/*************************************************************************** * Copyright (C) 2005-2007 Nicolas Hadacek * * Copyright (C) 2003-2004 Alain Gibaud * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #include "direct_config_widget.h" #include #include #include #include #include "progs/direct/base/direct_prog_config.h" #include "progs/direct/base/direct_prog.h" //----------------------------------------------------------------------------- ::Programmer::ConfigWidget *Direct::GroupUI::createConfigWidget(TQWidget *parent) const { return new ConfigWidget(static_cast(group()), parent); } //----------------------------------------------------------------------------- const char * const INV_PIN_LABEL = I18N_NOOP("Check this option if your hardware uses negative logic for this pin."); const char * const DELAY_LABEL = I18N_NOOP("Some programming cards need low clock rate:\nadding delay to clock pulses might help."); Direct::HConfigWidget::HConfigWidget(::Programmer::Base &base, TQWidget *parent, bool edit) : ::Hardware::HConfigWidget(base, parent, edit) { // pins assignment TQGroupBox *groupb = new TQGroupBox(1,TQt::Horizontal, i18n("Pin assignment"), this); _mainVBox->addWidget(groupb); TQWidget *w = new TQWidget(groupb); TQGridLayout *grid = new TQGridLayout(w, 1, 1, 0, 10); if (edit) grid->setColStretch(5, 1); for (uint i=0; iaddWidget(label, i, 0); _combos[i] = new TQComboBox(w); _combos[i]->setEnabled(edit); connect(_combos[i], TQT_SIGNAL(activated(int)), TQT_SLOT(slotPinChanged())); TQToolTip::add(_combos[i], PIN_DATA[i].comment); grid->addWidget(_combos[i], i, 1); _invcbs[i] = new TQCheckBox(i18n("Inverted"), w); _invcbs[i]->setEnabled(edit); TQToolTip::add(_invcbs[i], i18n(INV_PIN_LABEL)); grid->addWidget(_invcbs[i], i, 2); if (edit) { _testcbs[i] = new TQCheckBox(i18n("on"), w); TQToolTip::add(_testcbs[i], PIN_DATA[i].testComment); connect(_testcbs[i], TQT_SIGNAL(clicked()), TQT_SLOT(slotTestPin())); grid->addWidget(_testcbs[i], i, 3); _testLabels[i] = new TQLabel(w); TQToolTip::add(_testcbs[i], PIN_DATA[i].testComment); grid->addWidget(_testLabels[i], i, 4); updateTestStatus(PinType(i), false); } else { _testcbs[i] = 0; _testLabels[i] = 0; } } TQHBoxLayout *hbox = new TQHBoxLayout(_mainVBox); TQLabel *label = new TQLabel(i18n("Clock delay"), this); TQToolTip::add(label, i18n(DELAY_LABEL)); hbox->addWidget(label); _delay = new KIntNumInput(0,TQt::Horizontal, this); _delay->setRange(0, 50, 5); _delay->setEnabled(edit); TQToolTip::add(_delay, i18n(DELAY_LABEL)); hbox->addWidget(_delay); if (edit) { _sendBitsButton = new TQPushButton(i18n("Send 0xA55A"), this); _sendBitsButton->setToggleButton(true); connect(_sendBitsButton, TQT_SIGNAL(clicked()), TQT_SLOT(sendBits())); TQToolTip::add(_sendBitsButton, i18n("Continuously send 0xA55A on \"Data out\" pin.")); _editVBox->addWidget(_sendBitsButton); _editVBox->addStretch(1); } else _sendBitsButton = 0; // timer for sending bits _timerSendBits = new TQTimer(this); connect(_timerSendBits, TQT_SIGNAL(timeout()), TQT_SLOT(slotSendBits())); // timer for automatically polling DataOut pin _timerPollDataOut = new TQTimer(this); connect(_timerPollDataOut, TQT_SIGNAL(timeout()), TQT_SLOT(updateDataIn())); } void Direct::HConfigWidget::sendBits() { if ( _timerSendBits->isActive() ) { _sendBitsButton->setText(i18n("Send 0xA55A")); _timerSendBits->stop(); updateTestPin(DataOut); } else { _sendBitsButton->setText(i18n("Stop")); _timerSendBits->start(1); } } uint Direct::HConfigWidget::pin(PinType ptype) const { return static_cast(_hardware)->pinForIndex(PIN_DATA[ptype].dir, _combos[ptype]->currentItem()); } void Direct::HConfigWidget::slotPinChanged() { for (uint i = 0; iisGroundPin(pin(ptype)); _invcbs[ptype]->setEnabled(_edit); if (ground) _invcbs[ptype]->hide(); else _invcbs[ptype]->show(); if (_edit) { _testcbs[ptype]->setEnabled(PIN_DATA[ptype].dir==Port::Out && _connected); _testLabels[ptype]->setEnabled(_connected); if (ground) { _testcbs[ptype]->hide(); _testLabels[ptype]->hide(); } else { _testcbs[ptype]->show(); _testLabels[ptype]->show(); } } } void Direct::HConfigWidget::slotTestPin() { for (uint i = 0; iisChecked(); hardware()->setPin(ptype, on); updateTestStatus(ptype, on); if ( ptype==Vpp ) updateDataIn(); } void Direct::HConfigWidget::updateTestStatus(PinType ptype, bool on) { if (on) _testLabels[ptype]->setText(i18n(PIN_DATA[ptype].onLabel)); else _testLabels[ptype]->setText(i18n(PIN_DATA[ptype].offLabel)); } void Direct::HConfigWidget::updateDataIn() { bool on = hardware()->readBit(); updateTestStatus(DataIn, on); _testcbs[DataIn]->setChecked(on); } void Direct::HConfigWidget::sendBits(uint d, int nbb) { Q_ASSERT(_connected); hardware()->setWrite(); for (; nbb; --nbb) { hardware()->setPin(Clock, High); if ( d & 0x01 ) hardware()->setPin(DataOut, High); else hardware()->setPin(DataOut, Low); hardware()->setPin(Clock, Low); d >>= 1; // Move the data over 1 bit } hardware()->setPin(DataOut, Low); hardware()->setRead(); } void Direct::HConfigWidget::slotSendBits() { sendBits(0xA55A, 16); } bool Direct::HConfigWidget::set(const Port::Description &pd, const ::Hardware::Data &data) { // connect port _timerPollDataOut->stop(); if ( _timerSendBits->isActive() ) sendBits(); // stop delete _hardware; const HardwareData &hdata = static_cast(data); if ( pd.type==PortType::Serial ) _hardware = new SerialHardware(_base, pd.device, hdata); else _hardware = new ParallelHardware(_base, pd.device, hdata); bool ok = _hardware->connectHardware(); if ( !_edit) _hardware->disconnectHardware(); else _connected = ok; // update GUI if (_edit) { for (uint i=0; isetEnabled(_connected); updateTestStatus(PinType(i), false); } if ( _connected ) _timerPollDataOut->start(100); _sendBitsButton->setEnabled(_connected); } // update pins for (uint i=0; iclear(); Port::IODir dir = PIN_DATA[i].dir; for (uint k=0; knbPins(dir); k++) _combos[i]->insertItem(hardware()->pinLabelForIndex(dir, k)); if (PIN_DATA[i].canBeGround) _combos[i]->insertItem("GND"); _combos[i]->setCurrentItem(hardware()->indexForPin(dir, hdata.data.pins[i])); _invcbs[i]->setChecked(hdata.data.pins[i]<0); updatePin(PinType(i)); } _delay->setValue(hdata.data.clockDelay); return ok; } Hardware::Data *Direct::HConfigWidget::data() const { HardwareData *hdata = new HardwareData; hdata->portType = _hardware->portDescription().type; for (uint i=0; idata.pins[i] = pin(PinType(i)); if ( _invcbs[i]->isChecked() ) hdata->data.pins[i] = -hdata->data.pins[i]; } hdata->data.clockDelay = _delay->value(); return hdata; } //----------------------------------------------------------------------------- Direct::ConfigWidget::ConfigWidget(const ::Programmer::Group &group, TQWidget *parent) : ::Hardware::ConfigWidget(new ::Direct::PicBase(group, 0), new Config, parent) {} Hardware::HConfigWidget *Direct::ConfigWidget::createHardwareConfigWidget(TQWidget *parent, bool edit) const { return new HConfigWidget(*_base, parent, edit); }