/*************************************************************************** * Copyright (C) 2005 Lorenz M�senlechner & Matthias Kranz * * * * Copyright (C) 2005 Nicolas Hadacek * * * * 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 "icd2_usb.h" #include "microchip.h" #include "common/common/misc.h" //------------------------------------------------------------------------------ const Icd2::USBPort::SequenceData Icd2::USBPort::SEQUENCE_DATA[Nb_SequenceTypes] = { { 0x00 }, // receive { 0x01 }, // send { 0x02 }, // connect { 0x00 } // poll }; Icd2::USBPort::USBPort(uint deviceId, Log::Base &log) : Port::USB(log, Microchip::VENDOR_ID, deviceId, 1, 0), _dataSend(false) {} bool Icd2::USBPort::doSequence(SequenceType type, char *data, uint size) { TQByteArray tx(0x12); for (uint i=0; i> 8) & 0xFF; tx[0x0A] = _ctype & 0xFF; tx[0x0B] = (_ctype >> 8) & 0xFF; if ( !write(0x01, tx.data(), tx.size()) ) return false; switch (type) { case Connect: break; case Receive: if ( !read(0x82, data, size, 0) ) return false; break; case Poll: if ( !read(0x82, data, size, &_poll) ) return false; break; case Send: if ( !write(0x01, data, size) ) return false; break; case Nb_SequenceTypes: Q_ASSERT(false); break; } TQByteArray rx(0x08); if ( !read(0x81, rx.data(), rx.size(), 0) ) return false; //Q_ASSERT( rx[0]==tx[1] ); _seqnum++; if ( _seqnum==0xFF ) _seqnum = 0xC0; return true; } bool Icd2::USBPort::connectDevice(const TQString &mode) { _seqnum = 0xC1; // preset seqnum _ctype = 0x00; if ( !doSequence(Connect, 0, 0) ) return false; if ( !send("Z", 1) ) return false; TQString s; if ( !receive(4, s) ) return false; _ctype = 0x00; if ( !doSequence(Connect, 0, 0) ) return false; for (uint i=0; true; i++) { if ( i==10 ) { log(Log::LineType::Error, i18n("Problem connecting ICD2: please try again after unplug-replug.")); return false; } _ctype = 0x02; TQByteArray a = toAscii(mode); if ( !doSequence(Send, a.data(), a.count()) ) return false; char c; _ctype = 0x02; if ( !doSequence(Receive, &c, 1) ) return false; if ( c==mode.lower()[0] ) break; } return true; } bool Icd2::USBPort::internalReceive(uint size, char *data, uint) { if (_dataSend) { //_ctype = qMin(0x65, tqRound(4.8 * size)); // timing ?? (1.6 for my ICD2) _ctype = 0xC9; } else _ctype = 0xC9; bool ok = doSequence(Receive, data, size); if (_dataSend) _dataSend = false; return ok; } bool Icd2::USBPort::internalSend(const char *data, uint size, uint) { if (_dataSend) { //_ctype = qMin(0x65, tqRound(4.8 * size)); // timing ?? (1.6 for my ICD2) _ctype = 0xC9; } else _ctype = 0xC9; bool ok = doSequence(Send, (char *)data, size); if (_dataSend) _dataSend = false; return ok; } bool Icd2::USBPort::poll(uint size, TQString &s) { TQMemArray a; if ( !poll(size, a) ) return false; s.fill(0, size); for (uint i=0; i &a) { a.resize(size); for (;;) { _ctype = 0x65;//0x01; if ( !doSequence(Poll, (char *)a.data(), size) ) return false; if (_poll) break; } //log(Log::DebugLevel::Max, TQString("Receiced: \"%1\"").tqarg(toPrintable((const char *)a.data(), size))); return true; } bool Icd2::USBPort::dataSend(const char *data, uint size) { _dataSend = true; return Port::USB::send(data, size); } bool Icd2::USBPort::dataReceive(uint size, TQString &s) { _dataSend = true; return Port::USB::receive(size, s); } //------------------------------------------------------------------------------ Icd2::USBHardware::USBHardware(::Programmer::Base &base) : Hardware(base, new USBPort(ID_CLIENT, base)) {} bool Icd2::USBHardware::internalConnect(const TQString &mode) { // load control messages for USB device if needed log(Log::DebugLevel::Extra, TQString("need firmware ? %1").tqarg(USBPort::findDevice(Microchip::VENDOR_ID, ID_FIRMWARE)!=0)); if ( Port::USB::findDevice(Microchip::VENDOR_ID, ID_FIRMWARE) ) { USBPort port(ID_FIRMWARE, *this); if ( !port.open() ) return false; uint i = 0; while ( CONTROL_MESSAGE_DATA[i].bytes!=0 ) { if ( !port.sendControlMessage(CONTROL_MESSAGE_DATA[i]) ) return false; i++; } port.close(); for (uint i=0; i<10; i++) { log(Log::DebugLevel::Extra, TQString("client here ? %1").tqarg(USBPort::findDevice(Microchip::VENDOR_ID, ID_CLIENT)!=0)); if ( Port::USB::findDevice(Microchip::VENDOR_ID, ID_CLIENT) ) break; Port::msleep(1000); } } if ( !_port->open() ) return false; return static_cast(_port)->connectDevice(mode); }