/*************************************************************************** * 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 "pickit.h" #include "devices/base/device_group.h" #include "progs/base/prog_group.h" //----------------------------------------------------------------------------- Pickit::Array::Array(uint length, uchar fillChar, PrintMode mode) : _fillChar(fillChar), _mode(mode), _data(length) { _data.fill(fillChar); } QString Pickit::Array::pretty() const { int end = _data.count() - 1; for (; end>=0; end--) if ( _data[end]!=_fillChar ) break; QString s; for (int i=0; i<=end; i++) s += toPrintable(_data[i], _mode); return s; } //----------------------------------------------------------------------------- Pickit::USBPort::USBPort(uint deviceId, Log::Base &log) : Port::USB(log, Microchip::VENDOR_ID, deviceId, CONFIG_VENDOR, 0) {} bool Pickit::USBPort::command(uchar c) { Array a = array(); a._data[0] = c; return command(a); } bool Pickit::USBPort::command(const char *s) { Array a = array(); if (s) { Q_ASSERT( strlen(s)<=a.length() ); for (uint i=0; i &words, uint offset) { log(Log::DebugLevel::Max, QString("receive words nbBytesWord=%1 nbRead=%2 offset=%3").arg(nbBytesWord).arg(nbRead).arg(offset)); Array a = array(); QMemArray data(nbRead*a.length()); uint l = 0; for (uint i=0; i=data.count() ) break; } return port().command(cmd); } bool Pickit::Hardware::regenerateOsccal(BitValue &newValue) { if ( !setTargetPower(Osc2_5kHz) ) return false; if ( !setTargetPower(PowerOn + Osc2_5kHz) ) return false; Port::usleep(400000); // 400 ms if ( !setTargetPower(PowerOff) ) return false; Pickit::Array cmd = port().array(); cmd[0] = 'P'; cmd[1] = 'I'; cmd[2] = 120; cmd[3] = 0; cmd[4] = 'r'; cmd[5] = 'p'; if ( !port().command(cmd) ) return false; QValueVector words; if ( !port().receiveWords(1, 1, words) ) return false; newValue = words[7] | 0x3400; return true; } //---------------------------------------------------------------------------- bool Pickit::DeviceSpecific::setPowerOn() { return hardware().port().command(entryMode()); } bool Pickit::DeviceSpecific::setPowerOff() { return hardware().port().command('p'); } bool Pickit::DeviceSpecific::setTargetPowerOn(bool on) { return hardware().setTargetPower(on ? PowerOn : PowerOff); } //---------------------------------------------------------------------------- bool Pickit::BMDeviceSpecific::doRead(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata) { data.resize(device().nbWords(type)); gotoMemory(type); QValueVector words; switch (type.type()) { case Pic::MemoryRangeType::Config: case Pic::MemoryRangeType::Code: case Pic::MemoryRangeType::Cal: case Pic::MemoryRangeType::CalBackup: case Pic::MemoryRangeType::UserId: case Pic::MemoryRangeType::DeviceId: for (uint i=0; i=data.count() ) break; } } break; case Pic::MemoryRangeType::Eeprom: for (uint i=0; i=data.count() ) break; } } break; case Pic::MemoryRangeType::DebugVector: case Pic::MemoryRangeType::HardwareStack: case Pic::MemoryRangeType::ProgramExecutive: case Pic::MemoryRangeType::Nb_Types: Q_ASSERT(false); return false; } if ( type==Pic::MemoryRangeType::Code || type==Pic::MemoryRangeType::Eeprom ) _base.progressMonitor().addTaskProgress(data.count()); return true; } bool Pickit::BMDeviceSpecific::incrementPC(uint nb) { Pickit::Array cmd = hardware().port().array(); cmd[0] = 'I'; cmd[1] = nb & 0xFF; cmd[2] = (nb >> 8) & 0xFF; return hardware().port().command(cmd); } bool Pickit::BMDeviceSpecific::doEraseRange(Pic::MemoryRangeType type) { Q_ASSERT( type==Pic::MemoryRangeType::Code ); return hardware().port().command('E'); } bool Pickit::BMDeviceSpecific::doWrite(Pic::MemoryRangeType type, const Device::Array &data, bool force) { // #### TODO: speed optimize... Q_UNUSED(force); gotoMemory(type); uint nb = nbWrites(type); switch (type.type()) { case Pic::MemoryRangeType::Config: case Pic::MemoryRangeType::Code: case Pic::MemoryRangeType::Cal: case Pic::MemoryRangeType::UserId: for (uint i=0; i