//=========================================================================// // // // PonyProg - Serial Device Programmer // // // // Copyright (C) 1997-2019 Claudio Lanconelli // // // // http://ponyprog.sourceforge.net // // // //-------------------------------------------------------------------------// // // // 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 version2 of // // the License, or (at your option) any later version. // // // // This program is distributed in the hope that it will be useful, // // but WITHOUT ANY WARRANTY; without even the implied warranty of // // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // // General Public License for more details. // // // // You should have received a copy of the GNU General Public License // // along with this program (see LICENSE); if not, write to the // // Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // // // //=========================================================================// #include "types.h" #include "pic125xx.h" // Header file #include "errcode.h" #include "eeptypes.h" #include #include "e2awinfo.h" #define CONFIG_SIZE ( 8 * sizeof(uint16_t) ) Pic125xx::Pic125xx(e2AppWinInfo *wininfo, BusIO *busp) : Device(wininfo, busp, 1 /*BANK_SIZE*/) { config_word = 0xffff; } Pic125xx::~Pic125xx() { } int Pic125xx::CodeProtectAdjust(uint16_t &config, int read) { config = ~config & 0x0fff; return OK; } int Pic125xx::SecurityRead(uint32_t &bits) { int rv = GetBus()->ReadConfig(config_word); if (rv == OK) { uint16_t config = config_word; CodeProtectAdjust(config, 1); bits = config; } return rv; } int Pic125xx::SecurityWrite(uint32_t bits) { uint16_t config = (uint16_t)bits; CodeProtectAdjust(config, 0); config_word = config; return GetBus()->WriteConfig(config_word); } int Pic125xx::Probe(int probe_size) { return 1; } int Pic125xx::Read(int probe, int type) { int rv = Probe(probe || GetNoOfBank() == 0); if (rv > 0) { if (type & CONFIG_TYPE) { // read the config locations // this must be the FIRST operation (just after reset) uint32_t f; SecurityRead(f); GetAWInfo()->SetLockBits(f); } else { //Skip configuration word GetBus()->IncAddress(1); } if (type & PROG_TYPE) { rv = ReadProg(); } } return rv; } int Pic125xx::Write(int probe, int type) { int rv = Probe(probe || GetNoOfBank() == 0); if (rv > 0) { if (type & PROG_TYPE) { //Skip configuration word GetBus()->IncAddress(1); rv = WriteProg(); } if (rv > 0 && (type & CONFIG_TYPE)) { // write the config locations // this must be the FIRST operation (just after reset) uint32_t f; GetBus()->Reset(); f = GetAWInfo()->GetLockBits(); SecurityWrite(f); } } else if (rv == 0) { rv = E2ERR_WRITEFAILED; } return rv; } int Pic125xx::Verify(int type) { GetBus()->Reset(); if (GetNoOfBank() == 0) { return BADPARAM; } int rval = -1; if (GetSize() >= GetSplitted()) { unsigned char *localbuf = new unsigned char[GetSize()]; int v_prog = OK, v_config = OK; if (type & CONFIG_TYPE) { uint32_t f; SecurityRead(f); qDebug() << "Pic125xx::Verify() ** " << f << " <-> " << (unsigned long)GetAWInfo()->GetLockBits(); if (GetAWInfo()->GetLockBits() == f) { v_config = OK; } else { v_config = 1; } } else { //Skip configuration word GetBus()->IncAddress(1); } if (type & PROG_TYPE) { v_prog = VerifyProg(localbuf); } rval = (v_prog == OK && v_config == OK) ? 1 : 0; delete[] localbuf; } return rval; } int Pic125xx::VerifyProg(unsigned char *localbuf) { int rval = -1; int size = GetSplitted(); int base = 0; //Verify only programmed bytes (to save time in big devices) // long v_len = size - 2; //Don't verify RC Calibration location long v_len = size; if (GetBus()->GetLastProgrammedAddress() > 0 && GetBus()->GetLastProgrammedAddress() < size - 1) { v_len = GetBus()->GetLastProgrammedAddress() + 2; GetBus()->ClearLastProgrammedAddress(); //reset last_programmed_addr, so next verify not preceeded by write verify all the flash } //Set blank locations to default 0xFF (erased) memset(localbuf, 0xFF, size); // read the current flash content and store it in localbuf rval = GetBus()->Read(0, localbuf, v_len); if (rval != v_len) { if (rval > 0) { rval = OP_ABORTED; } } else { rval = GetBus()->CompareMultiWord(GetBufPtr() + base, localbuf + base, v_len, 0) == 0 ? OK : 1; } return rval; } /** //Write Flash program memory (don't program RC calibration value) int Pic125xx::WriteProg() { int rv; int size = GetSplitted()-2; //Don't program last location (RC calibration value) int base = 0; rv = GetBus()->Write(0, GetBufPtr()+base, size); if ( rv != size ) { if (rv > 0) rv = OP_ABORTED; } return rv; } **/