/*************************************************************************** * Copyright (C) 2006 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 "pickit2.h" #include "common/global/global.h" #include "devices/list/device_list.h" #include "common/port/port.h" //----------------------------------------------------------------------------- void Pickit2::USBPort::fillCommand(Pickit::Array &cmd, uchar command, uint nbBytes, uint address, uint i, bool longAddress) const { cmd[i] = command; cmd[i+1] = nbBytes; cmd[i+2] = address & 0xFF; cmd[i+3] = (address >> 8) & 0xFF; if (longAddress) cmd[i+4] = (address >> 16) & 0xFF; } Pickit::Array Pickit2::USBPort::createCommand(uchar c, uint nbBytes, uint address, bool longAddress) const { Array cmd; fillCommand(cmd, c, nbBytes, address, 0, longAddress); return cmd; } bool Pickit2::USBPort::readFirmwareCodeMemory(Device::Array &data, const Device::Array *vdata, ProgressMonitor &monitor) { const Pic::Data *device = static_cast(Device::lister().data("18F2455")); log(Log::DebugLevel::Normal, " Read pickit2 firmware"); for (uint i=0; istart; end--) if ( data[i + end].isInitialized() ) break; uint nb = end - start + 1; Pickit::Array cmd = createCommand(1, 2*nb, 2*i); if ( !command(cmd) ) return false; QValueVector read; if ( !receiveWords(1, 1, read) ) return false; for (uint k=0; k=0x1000 && index<0x3FF0 && data[index]!=(*vdata)[index] ) { log(Log::LineType::Error, i18n("Firmware memory does not match hex file (at address 0x%2: reading 0x%3 and expecting 0x%4).") .arg(QString(toHex(index/2, device->nbCharsAddress()))) .arg(QString(toHex(data[index], device->nbCharsWord(Pic::MemoryRangeType::Code)))) .arg(QString(toHex((*vdata)[index], device->nbCharsWord(Pic::MemoryRangeType::Code))))); return false; } } } monitor.addTaskProgress(data.count()); return true; } bool Pickit2::USBPort::eraseFirmwareCodeMemory() { log(Log::DebugLevel::Normal, " Erase pickit2 firmware"); Pickit::Array cmd = createCommand(3, 0xC0, 0x2000); if ( !command(cmd) ) return false; // erase 0x2000-0x4FFF Port::usleep(1000000); cmd = createCommand(3, 0xC0, 0x5000); if ( !command(cmd) ) return false; // erase 0x5000-0x7FFF Port::usleep(1000000); return true; } bool Pickit2::USBPort::writeFirmwareCodeMemory(const Device::Array &data, ProgressMonitor &monitor) { log(Log::DebugLevel::Normal, " Write pickit2 firmware"); for (uint i=0x1000; istart; end--) if ( data[i + end].isInitialized() ) break; uint nb = end - start + 1; Pickit::Array cmd = createCommand(2, 2*nb, 2*i); for (uint k=0; k> 8; uint cvpp = uint(18.61 * vpp); cmd[3] = 0x40; cmd[4] = cvpp; cmd[5] = uchar(4.5 * (cvdd >> 8)); // linit to 75% of vdd cmd[6] = uchar(0.75 * cvpp); // linit to 75% of vpp if ( !port().command(cmd) ) return false; // wait until vpp is stabilized for (uint i=0; i<30; i++) { Port::usleep(50000); VoltagesData voltages; if ( !readVoltages(voltages) ) return false; if ( voltages[Pic::TargetVpp].value<(vpp+0.5) ) break; } return true; } //----------------------------------------------------------------------------- bool Pickit2::Baseline::init() { Array cmd; cmd[0] = 'c'; cmd[1] = 0x00; // Load Configuration cmd[2] = 0x02; // Load Program latches cmd[3] = 0x03; // Load Data latches cmd[4] = 0x04; // Read Program memory cmd[5] = 0x05; // Read Data latches cmd[6] = 0x06; // Increment Address cmd[7] = 0x08; // Begin programming internally timed cmd[8] = 0x08; // Begin Programming externally timed cmd[9] = 0x0E; // End externally time programming cycle cmd[10] = 0x09; // Bulk Erase program memory cmd[11] = 0x0B; // Bulk Erase Data memory cmd[12] = 0xFF; // Read Program memory cmd[13] = 0xFF; // Read Data latches cmd[14] = 0xFF; // Increment Address cmd[15] = 0xFF; // Begin programming internally timed return hardware().port().command(cmd); } //----------------------------------------------------------------------------- bool Pickit2::P16F::init() { Array cmd; cmd[0] = 'c'; cmd[1] = 0x00; // Load Configuration cmd[2] = 0x02; // Load Program latches cmd[3] = 0x03; // Load Data latches cmd[4] = 0x04; // Read Program memory cmd[5] = 0x05; // Read Data latches cmd[6] = 0x06; // Increment Address cmd[7] = 0x08; // Begin programming internally timed cmd[8] = 0x18; // Begin Programming externally timed cmd[9] = 0x0A; // End externally time programming cycle cmd[10] = 0x09; // Bulk Erase program memory cmd[11] = 0x0B; // Bulk Erase Data memory cmd[12] = 0xFF; // Read Program memory cmd[13] = 0xFF; // Read Data latches cmd[14] = 0xFF; // Increment Address cmd[15] = 0xFF; // Begin programming internally timed return hardware().port().command(cmd); } //----------------------------------------------------------------------------- bool Pickit2::P16F87XA::init() { Array cmd; cmd[0] = 'c'; cmd[1] = 0x00; // Load Configuration cmd[2] = 0x02; // Load Program latches cmd[3] = 0x03; // Load Data latches cmd[4] = 0x04; // Read Program memory cmd[5] = 0x05; // Read Data latches cmd[6] = 0x06; // Increment Address cmd[7] = 0x08; // Begin programming internally timed cmd[8] = 0x18; // Begin Programming externally timed cmd[9] = 0x17; // End externally time programming cycle cmd[10] = 0x1F; // Bulk Erase program memory cmd[11] = 0x1F; // Bulk Erase Data memory cmd[12] = 0xFF; // Read Program memory cmd[13] = 0xFF; // Read Data latches cmd[14] = 0xFF; // Increment Address cmd[15] = 0xFF; // Begin programming internally timed return hardware().port().command(cmd); } //----------------------------------------------------------------------------- bool Pickit2::P16F7X::init() { Array cmd; cmd[0] = 'c'; cmd[1] = 0x00; // Load Configuration cmd[2] = 0x02; // Load Program latches cmd[3] = 0x03; // Load Data latches cmd[4] = 0x04; // Read Program memory cmd[5] = 0x05; // Read Data latches cmd[6] = 0x06; // Increment Address cmd[7] = 0x08; // Begin programming internally timed cmd[8] = 0x08; // Begin Programming externally timed cmd[9] = 0x0E; // End externally time programming cycle cmd[10] = 0x09; // Bulk Erase program memory cmd[11] = 0x0B; // Bulk Erase Data memory cmd[12] = 0xFF; // Read Program memory cmd[13] = 0xFF; // Read Data latches cmd[14] = 0xFF; // Increment Address cmd[15] = 0xFF; // Begin programming internally timed return hardware().port().command(cmd); } bool Pickit2::P16F716::init() { Array cmd; cmd[0] = 'c'; cmd[1] = 0x00; // Load Configuration cmd[2] = 0x02; // Load Program latches cmd[3] = 0x03; // Load Data latches cmd[4] = 0x04; // Read Program memory cmd[5] = 0x05; // Read Data latches cmd[6] = 0x06; // Increment Address cmd[7] = 0x08; // Begin programming internally timed cmd[8] = 0x18; // Begin Programming externally timed cmd[9] = 0x0E; // End externally time programming cycle cmd[10] = 0x09; // Bulk Erase program memory cmd[11] = 0x0B; // Bulk Erase Data memory cmd[12] = 0xFF; // Read Program memory cmd[13] = 0xFF; // Read Data latches cmd[14] = 0xFF; // Increment Address cmd[15] = 0xFF; // Begin programming internally timed return hardware().port().command(cmd); } //----------------------------------------------------------------------------- bool Pickit2::P18F::init() { Array cmd; cmd[0] = 'c'; cmd[1] = 0x00; // Load Configuration cmd[2] = 0x02; // Load Program latches cmd[3] = 0x03; // Load Data latches cmd[4] = 0x04; // Read Program memory cmd[5] = 0x05; // Read Data latches cmd[6] = 0x06; // Increment Address cmd[7] = 0x08; // Begin programming internally timed cmd[8] = 0x18; // Begin Programming externally timed cmd[9] = 0x0A; // End externally time programming cycle cmd[10] = 0x09; // Bulk Erase program memory cmd[11] = 0x0B; // Bulk Erase Data memory cmd[12] = 0xFF; // Read Program memory cmd[13] = 0xFF; // Read Data latches cmd[14] = 0xFF; // Increment Address cmd[15] = 0xFF; // Begin programming internally timed return hardware().port().command(cmd); } bool Pickit2::P18F::doEraseCommand(uint cmd1, uint cmd2) { Array cmd; cmd[0] = 0x85; cmd[1] = cmd1; cmd[2] = cmd2; return hardware().port().command(cmd); } bool Pickit2::P18F::doEraseRange(Pic::MemoryRangeType type) { if ( type==Pic::MemoryRangeType::Eeprom ) return doEraseCommand(0x84, 0x00); Q_ASSERT( type==Pic::MemoryRangeType::Code ); if ( !doEraseCommand(0x81, 0x00) ) return false; // boot for (uint i=0; i(hardware().port()); data.resize(device().nbWords(type)); QValueVector words; switch (type.type()) { case Pic::MemoryRangeType::DeviceId: case Pic::MemoryRangeType::UserId: case Pic::MemoryRangeType::Config: { Pickit::Array cmd = port.createCommand(0x80, data.count(), device().range(type).start.toUInt()); if ( !port.command(cmd) ) return false; if ( !hardware().port().receiveWords(1, 1, words) ) return false; for (uint k=0; k(hardware().port()); switch (type.type()) { case Pic::MemoryRangeType::UserId: { Pickit::Array cmd = port.createCommand(0x82, data.count() / 2, device().range(type).start.toUInt()); for (uint i=0; i