void JobInfo::doDeviceDependent( AVRProgrammer * prog, AVRDevice * avr ) { HEXFile * hex; HEXFile * hex_v; // Used for verifying memory contents. long pos; // Used when comparing data. long bits; // Used for lock and fuse bits. /* Set programmer pagesize */ prog->setPagesize( avr->getPageSize() ); /* Check if specified address limits are within device range */ if( flashEndAddress != -1 ) { if( flashEndAddress >= avr->getFlashSize() ) throw new ErrorMsg( "Specified Flash address range is outside device address space!" ); } else { flashStartAddress = 0; flashEndAddress = avr->getFlashSize() - 1; } if( eepromEndAddress != -1 ) { if( eepromEndAddress >= avr->getEEPROMSize() ) throw new ErrorMsg( "Specified EEPROM address range is outside device address space!" ); } else { eepromStartAddress = 0; eepromEndAddress = avr->getEEPROMSize() - 1; } /* Read out Flash contents? */ if( readFlash ) { /* Check that filename has been specified */ if( outputFileFlash.size() == 0 ) throw new ErrorMsg( "Cannot read Flash without output file specified!" ); /* Prepare the file */ hex = new HEXFile( avr->getFlashSize() ); hex->setUsedRange( flashStartAddress, flashEndAddress ); /* Read data and save file */ Util.log( "Reading Flash contents...\r\n" ); if( !prog->readFlash( hex ) ) throw new ErrorMsg( "Flash readout is not supported by this programmer!" ); Util.log( "Writing HEX output file...\r\n" ); hex->writeFile( outputFileFlash ); delete hex; } /* Read out EEPROM contents? */ if( readEEPROM ) { /* Check that filename has been specified */ if( outputFileEEPROM.size() == 0 ) throw new ErrorMsg( "Cannot read EEPROM without output file specified!" ); /* Prepare the file */ hex = new HEXFile( avr->getEEPROMSize() ); hex->setUsedRange( eepromStartAddress, eepromEndAddress ); /* Read data and save file */ Util.log( "Reading EEPROM contents...\r\n" ); if( !prog->readEEPROM( hex ) ) throw new ErrorMsg( "EEPROM readout is not supported by this programmer!" ); Util.log( "Writing HEX output file...\r\n" ); hex->writeFile( outputFileEEPROM ); delete hex; } /* Read lock bits? */ if( readLockBits ) { Util.log( "Reading lock bits...\r\n" ); if( !prog->readLockBits( &bits ) ) throw new ErrorMsg( "Lock bit readout is not supported by this programmer!" ); cout << "0x" << std::hex << setw(2) << bits << endl; } /* Read fuse bits (both ordinary and extended)? */ if( readFuseBits ) { if( !avr->getFuseStatus() ) throw new ErrorMsg( "Selected device has no fuse bits!" ); Util.log( "Reading fuse bits...\r\n" ); if( !prog->readFuseBits( &bits ) ) throw new ErrorMsg( "Fuse bit readout is not supported by this programmer!" ); cout << "0x" << std::hex << setw(4) << bits << endl; if( avr->getXFuseStatus() ) { if( !prog->readExtendedFuseBits( &bits ) ) throw new ErrorMsg( "Extended fuse bit readout is not supported by this programmer!" ); cout << "0x" << std::hex << setw(2) << bits << endl; } } /* Erase chip before programming anything? */ if( chipErase ) { Util.log( "Erasing chip contents...\r\n" ); if( !prog->chipErase() ) throw new ErrorMsg( "Chip erase is not supported by this programmer!" ); } /* Prepare input hex file for flash */ if( programFlash || verifyFlash ) { /* Check that filename has been specified */ if( inputFileFlash.size() == 0 ) throw new ErrorMsg( "Cannot program or verify Flash without input file specified!" ); /* Prepare the file */ hex = new HEXFile( avr->getFlashSize() ); /* Fill if wanted */ if( memoryFillPattern != -1 ) hex->clearAll( memoryFillPattern ); /* Read file */ Util.log( "Reading HEX input file for flash operations...\r\n" ); hex->readFile( inputFileFlash ); /* Check limits */ if( hex->getRangeStart() > flashEndAddress || hex->getRangeEnd() < flashStartAddress ) throw new ErrorMsg( "HEX file defines data outside specified range!" ); if( memoryFillPattern == -1 ) { if( hex->getRangeStart() > flashStartAddress ) flashStartAddress = hex->getRangeStart(); if( hex->getRangeEnd() < flashEndAddress ) flashEndAddress = hex->getRangeEnd(); } hex->setUsedRange( flashStartAddress, flashEndAddress ); } /* Program new Flash contents? */ if( programFlash ) { /* Program data */ Util.log( "Programming Flash contents...\r\n" ); if( !prog->writeFlash( hex ) ) throw new ErrorMsg( "Flash programming is not supported by this programmer!" ); } /* Verify Flash contents? */ if( verifyFlash ) { /* Prepare HEX file for comparision */ hex_v = new HEXFile( avr->getFlashSize() ); /* Compare to Flash */ Util.log( "Reading Flash contents...\r\n" ); hex_v->setUsedRange( hex->getRangeStart(), hex->getRangeEnd() ); if( !prog->readFlash( hex_v ) ) throw new ErrorMsg( "Flash readout is not supported by this programmer!" ); /* Compare data */ Util.log( "Comparing Flash data...\r\n" ); for( pos = hex->getRangeStart(); pos <= hex->getRangeEnd(); pos++ ) { if( hex->getData( pos ) != hex_v->getData( pos ) ) { cout << "Unequal at address 0x" << std::hex << pos << "!" << endl; break; } } if( pos > hex->getRangeEnd() ) // All equal? { cout << "Equal!" << endl; } delete hex_v; } if( programFlash || verifyFlash ) delete hex; /* Prepare input hex file for EEPROM */ if( programEEPROM || verifyEEPROM ) { /* Check that filename has been specified */ if( inputFileEEPROM.size() == 0 ) throw new ErrorMsg( "Cannot program or verify EEPROM without input file specified!" ); /* Prepare the file */ hex = new HEXFile( avr->getEEPROMSize() ); /* Fill if wanted */ if( memoryFillPattern != -1 ) hex->clearAll( memoryFillPattern ); /* Read file and program contents */ Util.log( "Reading HEX input file for EEPROM operations...\r\n" ); hex->readFile( inputFileEEPROM ); /* Check limits */ if( hex->getRangeStart() > eepromEndAddress || hex->getRangeEnd() < eepromStartAddress ) throw new ErrorMsg( "HEX file defines data outside specified range!" ); if( memoryFillPattern == -1 ) { if( hex->getRangeStart() > eepromStartAddress ) eepromStartAddress = hex->getRangeStart(); if( hex->getRangeEnd() < eepromEndAddress ) eepromEndAddress = hex->getRangeEnd(); } hex->setUsedRange( eepromStartAddress, eepromEndAddress ); } /* Program new EEPROM contents? */ if( programEEPROM ) { /* Program data */ Util.log( "Programming EEPROM contents...\r\n" ); if( !prog->writeEEPROM( hex ) ) throw new ErrorMsg( "EEPROM programming is not supported by this programmer!" ); } /* Verify EEPROM contents? */ if( verifyEEPROM ) { /* Prepare HEX file for comparision */ hex_v = new HEXFile( avr->getEEPROMSize() ); /* Compare to EEPROM */ Util.log( "Reading EEPROM contents...\r\n" ); hex_v->setUsedRange( hex->getRangeStart(), hex->getRangeEnd() ); if( !prog->readEEPROM( hex_v ) ) throw new ErrorMsg( "EEPROM readout is not supported by this programmer!" ); /* Compare data */ Util.log( "Comparing EEPROM data...\r\n" ); for( pos = hex->getRangeStart(); pos <= hex->getRangeEnd(); pos++ ) { if( hex->getData( pos ) != hex_v->getData( pos ) ) { cout << "Unequal at address 0x" << std::hex << pos << "!" << endl; break; } } if( pos > hex->getRangeEnd() ) // All equal? { cout << "Equal!" << endl; } delete hex_v; } if( programEEPROM || verifyEEPROM ) delete hex; /* Program lock bits */ if( programLockBits != -1 ) { Util.log( "Programming lock bits...\r\n" ); if( !prog->writeLockBits( programLockBits ) ) throw new ErrorMsg( "Lock bit programming is not supported by this programmer!" ); } /* Program fuse bits */ if( programFuseBits != -1 ) { if( !avr->getFuseStatus() ) throw new ErrorMsg( "Selected device has no fuse bits!" ); Util.log( "Programming fuse bits...\r\n" ); if( !prog->writeFuseBits( programFuseBits ) ) throw new ErrorMsg( "Fuse bit programming is not supported by this programmer!" ); } /* Program extended fuse bits */ if( programExtendedFuseBits != -1 ) { if( !avr->getXFuseStatus() ) throw new ErrorMsg( "Selected device has no extended fuse bits!" ); Util.log( "Programming extended fuse bits...\r\n" ); if( !prog->writeExtendedFuseBits( programExtendedFuseBits ) ) throw new ErrorMsg( "Extended fuse bit programming is not supported by this programmer!" ); } /* Verify lock bits */ if( verifyLockBits != -1 ) { Util.log( "Verifying lock bits...\r\n" ); if( !prog->readLockBits( &bits ) ) throw new ErrorMsg( "Lock bit readout is not supported by this programmer!" ); if( bits == verifyLockBits ) cout << "Equal!" << endl; else cout << "Unequal!" << endl; } /* Verify fuse bits */ if( verifyFuseBits != -1 ) { if( !avr->getFuseStatus() ) throw new ErrorMsg( "Selected device has no fuse bits!" ); Util.log( "Verifying fuse bits...\r\n" ); if( !prog->readFuseBits( &bits ) ) throw new ErrorMsg( "Fuse bit readout is not supported by this programmer!" ); if( bits == verifyFuseBits ) cout << "Equal!" << endl; else cout << "Unequal!" << endl; } /* Verify extended fuse bits */ if( verifyExtendedFuseBits != -1 ) { if( !avr->getXFuseStatus() ) throw new ErrorMsg( "Selected device has no extended fuse bits!" ); Util.log( "Verifying extended fuse bits...\r\n" ); if( !prog->readExtendedFuseBits( &bits ) ) throw new ErrorMsg( "Extended fuse bit readout is not supported by this programmer!" ); if( bits == verifyExtendedFuseBits ) cout << "Equal!" << endl; else cout << "Unequal!" << endl; } /* Read osccal value? */ if( OSCCAL_Parameter != -1 ) { /* Output to log if read from device */ if( readOSCCAL ) { Util.log( "Reading OSCCAL from device...\r\n" ); pos = OSCCAL_Parameter; if( !prog->readOSCCAL( pos, &OSCCAL_Parameter ) ) throw new ErrorMsg( "OSCCAL parameter readout is not supported by this programmer!" ); cout << "0x" << std::hex << setw(2) << OSCCAL_Parameter << endl; } } /* Write OSCCAL to Flash? */ if( OSCCAL_FlashAddress != -1 ) { if( OSCCAL_Parameter == -1 ) throw new ErrorMsg( "OSCCAL value not specified!" ); Util.log( "Programming OSCCAL value to Flash...\r\n" ); if( !prog->writeFlashByte( OSCCAL_FlashAddress, OSCCAL_Parameter ) ) throw new ErrorMsg( "Flash programming is not supported by this programmer!" ); } /* Write OSCCAL to EEPROM? */ if( OSCCAL_EEPROMAddress != -1 ) { if( OSCCAL_Parameter == -1 ) throw new ErrorMsg( "OSCCAL value not specified!" ); Util.log( "Programming OSCCAL value to EEPROM...\r\n" ); if( !prog->writeEEPROMByte( OSCCAL_EEPROMAddress, OSCCAL_Parameter ) ) throw new ErrorMsg( "EEPROM programming is not supported by this programmer!" ); } }
void TKN_NodeBox::hexUpload() { int page=0; int word=0; int byteCount=0; long start, end, addr; TKN_Data recData; BYTE sendData[TKN_DATA_SIZE]; BYTE byteForEmpty = 0xff; QString recString; HEXFile *h; try { h = new HEXFile(1024*1024, byteForEmpty); h->readFile(ui->lineEditHexFilePath->text().toStdString()); } catch(ErrorMsg *err) { emit consoleOut(QString::fromStdString(err->What())); return; } start = h->getRangeStart(); end = h->getRangeEnd(); for (addr=start; addr<= end; ) { /* Initiate a boot procedure */ memset(sendData, 0, TKN_DATA_SIZE); strcpy ((char*)sendData, "B:"); sendData[3] = addr/(PAGESIZE*2); /* Flush any data from receive queue */ flushRecDataQueue(); while (TKN_PushData ((TKN_Data *) sendData, NODE_ID)); /* Wait MCU */ do { if ( !dataDeque(&recData, 1500)) { emit consoleOut("MCU Busy, aborting."); return; } recString = QString(QByteArray((char*)&recData, sizeof(TKN_Data))); } while ( QString::compare(QString("-MCU-READY------"), recString)); emit consoleOut(QString("Sending Page: ") + QString ('0'+sendData[3])); /* Send a complete page */ do { /* Fill a TKN Packet */ for (int i=0; i<sizeof(TKN_Data); i++){ sendData[i] = addr<=end? ((BYTE) h->getData(addr)): byteForEmpty; byteCount++; addr++; } /* Send it to tha MCU */ while (TKN_PushData ((TKN_Data *) sendData, NODE_ID)); } while ((addr % (PAGESIZE*2)!=0) ); } QString msg = QString("Hex upload complete. Sent ") + QString::number(byteCount) + QString(" bytes."); emit consoleOut(msg); }