Files
bacnet_stack/ports/bdk-atxx4-mstp/external/avrosp/JobInfo.cpp
T
Kari Argillander 599033b7b0 Move some external files to external/ folder (#744)
It is lot easier to work with automatic formatters if we have external
files in different folder. For some tools we can example just exclude
external all together.

Co-authored-by: Kari Argillander <kari.argillander@fidelix.com>
2024-08-28 16:24:48 -05:00

1297 lines
34 KiB
C++

/*****************************************************************************
*
* Atmel Corporation
*
* File : JobInfo.cpp
* Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/
* Revision : $Revision: 1163 $
* Date : $Date: 2006-08-02 15:38:16 +0200 (on, 02 aug 2006) $
* Updated by : $Author: ohlia $
*
* Support mail : avr@atmel.com
*
* Target platform : Win32
*
* AppNote : AVR911 - AVR Open-source Programmer
*
* Description : A class holding information on what the AVR Open-Source Programmer
* should do. The information is derived from the command-line.
*
*
****************************************************************************/
#include "JobInfo.hpp"
#include <conio.h>
#define VERSIONSTRING "$Revision: 1163 $" // For use in later text output.
#define TIMEOUT 5
#define TIMEOUTSTRING "5"
JobInfo::JobInfo()
{
/* Initialize variables */
showHelp = false;
silentMode = false;
noProgressIndicator = false;
readSignature = false;
chipErase = false;
getHWrevision = false;
getSWrevision = false;
programFlash = false;
programEEPROM = false;
readFlash = false;
readEEPROM = false;
verifyFlash = false;
verifyEEPROM = false;
readLockBits = false;
readFuseBits = false;
readOSCCAL = false;
deviceName.erase();
inputFileFlash.erase();
inputFileEEPROM.erase();
outputFileFlash.erase();
outputFileEEPROM.erase();
OSCCAL_Parameter = -1;
OSCCAL_FlashAddress = -1;
OSCCAL_EEPROMAddress = -1;
programLockBits = -1;
verifyLockBits = -1;
programFuseBits = -1;
programExtendedFuseBits = -1;
verifyFuseBits = -1;
verifyExtendedFuseBits = -1;
memoryFillPattern = -1;
flashStartAddress = -1;
flashEndAddress = -1;
eepromStartAddress = -1;
eepromEndAddress = -1;
comPort = -1;
}
void JobInfo::parseCommandline( int argc, char *argv[] )
{
char * param; // Temp string ptr for holding current parsed parameter.
int comma; // Temp position for comma separator in address ranges.
/* Get application directory */
string ownpath = argv[0];
int slash_pos = ownpath.find_last_of( "\\/" ); // Search for last og / or \.
if( slash_pos == string::npos ) // Not found?
{
ownpath.assign( "." ); // The current directory is the AVROSP EXE path also.
} else
{
ownpath.erase( slash_pos ); // Remove from and including the last slash separator.
}
searchpath.push_back( "." ); // Add current directory also.
searchpath.push_back( ownpath ); // Save for later.
if( argc <= 1 )
{
showHelp = true;
return;
}
/* Iterate through cmdline parameters */
for( int i = 1; i < argc; i++ )
{
param = argv[i];
/* Allow parameters to start with '-' */
if( param[0] != '-' )
throw new ErrorMsg( "All parameters must start with '-'!" );
if( strlen( param ) <= 1 )
throw new ErrorMsg( "Parameters cannot be just the minus without any characters!" );
/* Now for the parsing... */
switch( param[1] )
{
case 'a' : // Address range specified.
if( strlen( param ) <= 2 )
throw new ErrorMsg( "Cannot use -a without memory type!" );
if( strlen( param ) <= 5 )
throw new ErrorMsg( "Cannot use -a without start and end address!" );
/* Find comma position and set it to '0' to help hex conversion */
comma = 2;
while( (param[comma] != 0) && (param[comma] != ',') )
comma++;
if( comma == strlen( param ) ) // No comma found?
throw new ErrorMsg( "No comma separator found in -a parameter!" );
param[comma] = 0; // It is now two separate strings for hex conversion.
/* Convert limits */
switch( param[2] )
{
case 'f' : // Flash address range.
try
{
flashStartAddress = convertHex( param + 3 );
}
catch( ErrorMsg * e )
{
delete e;
throw new ErrorMsg( "Number format error in start limit for -af parameter!" );
}
try
{
flashEndAddress = convertHex( param + comma + 1 );
}
catch( ErrorMsg * e )
{
delete e;
throw new ErrorMsg( "Number format error in end limit for -af parameter!" );
}
if( flashEndAddress < flashStartAddress )
throw new ErrorMsg( "Cannot have Flash end limit less than start limit!" );
break;
case 'e' : // EEPROM address range.
try
{
eepromStartAddress = convertHex( param + 3 );
}
catch( ErrorMsg * e )
{
delete e;
throw new ErrorMsg( "Number format error in start limit for -ae parameter!" );
}
try
{
eepromEndAddress = convertHex( param + comma + 1 );
}
catch( ErrorMsg * e )
{
delete e;
throw new ErrorMsg( "Number format error in end limit for -ae parameter!" );
}
if( eepromEndAddress < eepromStartAddress )
throw new ErrorMsg( "Cannot have EEPROM end limit less than start limit!" );
break;
default:
throw new ErrorMsg( "Unknown choice for -a, use -af or -ae!" );
}
break;
case 'b' : // Get revision.
if( strlen( param ) != 3 )
throw new ErrorMsg( "Specify SW og HW revision, not just -b!" );
switch( param[2] )
{
case 'h' : // Hardware revision.
getHWrevision = true;
break;
case 's' : // Software revision.
getSWrevision = true;
break;
default:
throw new ErrorMsg( "Unknown choice for -b, use -bs or -bh!" );
}
break;
case 'c' : // Specify COM port.
if (( strlen( param ) < 6 ) || (strlen( param ) > 7) ||
(param[2] != 'C' || param[3] != 'O' || param[4] != 'M' ) ||
(param[5] < '1' || param[5] > '9')) {
throw new ErrorMsg( "COM port parameter syntax is -cCOM1 to -cCOM99" );
}
comPort = param[5] - '0'; // Convert COM port digit to number.
if (param[6] != 0) {
comPort = (comPort * 10) + param[6] - '0';
}
break;
case 'd' : // Device name specified.
if( strlen( param ) <= 2 )
throw new ErrorMsg( "Cannot use -d without the device name!" );
/* Copy device name string to class variable */
deviceName.assign( param + 2 );
break;
case 'e' : // Chip erase before programming.
if( strlen( param ) != 2 )
throw new ErrorMsg( "Parameter -e needs no extra arguments!" );
chipErase = true;
break;
case 'E' : // Set extended fuse bits.
if( strlen( param ) != 4 )
throw new ErrorMsg( "Use two hex digits for the -E parameter!" );
try
{
programExtendedFuseBits = convertHex( param + 2 );
}
catch( ErrorMsg * e )
{
delete e;
throw new ErrorMsg( "Hex number format error for -E parameter!" );
}
break;
case 'f' : // Set fuse bits.
if( strlen( param ) != 6 )
throw new ErrorMsg( "Use four hex digits for the -f parameter!" );
try
{
programFuseBits = convertHex( param + 2 );
}
catch( ErrorMsg * e )
{
delete e;
throw new ErrorMsg( "Hex number format error for -f parameter!" );
}
break;
case 'F' : // Verify fuse bits.
if( strlen( param ) != 6 )
throw new ErrorMsg( "Use four hex digits for the -F parameter!" );
try
{
verifyFuseBits = convertHex( param + 2 );
}
catch( ErrorMsg * e )
{
delete e;
throw new ErrorMsg( "Hex number format error for -F parameter!" );
}
break;
case 'g' : // Silent operation.
if( strlen( param ) != 2 )
throw new ErrorMsg( "Parameter -g needs no extra arguments!" );
silentMode = true;
break;
case 'G' : // Verify extended fuse bits.
if( strlen( param ) != 4 )
throw new ErrorMsg( "Use two hex digits for the -G parameter!" );
try
{
verifyExtendedFuseBits = convertHex( param + 2 );
}
catch( ErrorMsg * e )
{
delete e;
throw new ErrorMsg( "Hex number format error for -G parameter!" );
}
break;
case 'h' : // Help screen.
case '?' : // Help screen.
if( strlen( param ) != 2 )
throw new ErrorMsg( "Parameter -h and -? needs no extra arguments!" );
showHelp = true;
break;
case 'i' : // Input file specified.
if( strlen( param ) <= 2 )
throw new ErrorMsg( "Cannot use -i without memory type!" );
if( strlen( param ) <= 3 )
throw new ErrorMsg( "Cannot use -i without file name!" );
/* Copy file name string to correct class variable */
switch( param[2] )
{
case 'f' : // Flash input file.
inputFileFlash.assign( param + 3 );
break;
case 'e' : // EEPROM input file.
inputFileEEPROM.assign( param + 3 );
break;
default:
throw new ErrorMsg( "Unknown choice for -i, use -if or -ie!" );
}
break;
case 'l' : // Set lock bits.
if( strlen( param ) != 4 )
throw new ErrorMsg( "Use two hex digits for the -l parameter!" );
try
{
programLockBits = convertHex( param + 2 );
}
catch( ErrorMsg * e )
{
delete e;
throw new ErrorMsg( "Hex number format error for -l parameter!" );
}
break;
case 'L' : // Verify lock bits.
if( strlen( param ) != 4 )
throw new ErrorMsg( "Use two hex digits for the -l parameter!" );
try
{
verifyLockBits = convertHex( param + 2 );
}
catch( ErrorMsg * e )
{
delete e;
throw new ErrorMsg( "Hex number format error for -L parameter!" );
}
break;
case 'o' : // Output file specified.
if( strlen( param ) <= 2 )
throw new ErrorMsg( "Cannot use -o without memory type!" );
if( strlen( param ) <= 3 )
throw new ErrorMsg( "Cannot use -o without file name!" );
/* Copy file name string to correct class variable */
switch( param[2] )
{
case 'f' : // Flash output file.
outputFileFlash.assign( param + 3 );
break;
case 'e' : // EEPROM output file.
outputFileEEPROM.assign( param + 3 );
break;
default:
throw new ErrorMsg( "Unknown choice for -o, use -of or -oe!" );
}
break;
case 'O' : // Read OSCCAL byte.
switch( strlen( param ) )
{
case 2 : // No value specified, use first OSCCAL byte.
readOSCCAL = true;
OSCCAL_Parameter = 0; // First OSCCAL byte.
break;
case 3 : // Byte index specified.
case 4 :
readOSCCAL = true;
try
{
OSCCAL_Parameter = convertHex( param + 2 );
}
catch( ErrorMsg * e )
{
delete e;
throw new ErrorMsg( "Hex number format error for -O parameter!" );
}
break;
case 5 : // Direct value specified.
if( param[2] != '#' )
throw new ErrorMsg( "Use one or two hex digits for -O and two for -O#!" );
readOSCCAL = false;
try
{
OSCCAL_Parameter = convertHex( param + 3 );
}
catch( ErrorMsg * e )
{
delete e;
throw new ErrorMsg( "Hex number format error for -O# parameter!" );
}
break;
default:
throw new ErrorMsg( "Invalid use of -O or -O# parameter!" );
}
break;
case 'p' : // Program data.
if( strlen( param ) != 3 )
throw new ErrorMsg( "Specify memory type, not just -p!" );
switch( param[2] )
{
case 'f' : // Program Flash memory.
programFlash = true;
break;
case 'e' : // Program EEPROM memory.
programEEPROM = true;
break;
case 'b' : // Both.
programFlash = true;
programEEPROM = true;
break;
default:
throw new ErrorMsg( "Unknown choice for -p, use -pf, -pe or -pb!" );
}
break;
case 'q' : // Read all fuse bits.
if( strlen( param ) != 2 )
throw new ErrorMsg( "Parameter -q needs no extra arguments!" );
readFuseBits = true;
break;
case 'r' : // Read data.
if( strlen( param ) != 3 )
throw new ErrorMsg( "Specify memory type, not just -r!" );
switch( param[2] )
{
case 'f' : // Read Flash memory.
readFlash = true;
break;
case 'e' : // Read EEPROM memory.
readEEPROM = true;
break;
case 'b' : // Both.
readFlash = true;
readEEPROM = true;
break;
default:
throw new ErrorMsg( "Unknown choice for -r, use -rf, -re or -rb!" );
}
break;
case 's' : // Read signature byte.
if( strlen( param ) != 2 )
throw new ErrorMsg( "Parameter -s needs no extra arguments!" );
readSignature = true;
break;
case 'S' : // Write OSCCAL byte to memory.
if( strlen( param ) <= 2 )
throw new ErrorMsg( "Cannot use -S without memory type!" );
if( strlen( param ) <= 3 )
throw new ErrorMsg( "Cannot use -S without byte address!" );
switch( param[2] )
{
case 'f' : // Write to Flash address.
try
{
OSCCAL_FlashAddress = convertHex( param + 3 );
}
catch( ErrorMsg * e )
{
delete e;
throw new ErrorMsg( "Cannot convert hex number for -Sf parameter!" );
}
break;
case 'e' : // Write to EEPROM address.
try
{
OSCCAL_EEPROMAddress = convertHex( param + 3 );
}
catch( ErrorMsg * e )
{
delete e;
throw new ErrorMsg( "Cannot convert hex number for -Se parameter!" );
}
break;
default:
throw new ErrorMsg( "Unknown choice for -S, use -Sf or -Se!" );
}
break;
case 'v' : // Verify data.
if( strlen( param ) != 3 )
throw new ErrorMsg( "Specify memory type, not just -v!" );
switch( param[2] )
{
case 'f' : // Verify Flash memory.
verifyFlash = true;
break;
case 'e' : // Verify EEPROM memory.
verifyEEPROM = true;
break;
case 'b' : // Both.
verifyFlash = true;
verifyEEPROM = true;
break;
default:
throw new ErrorMsg( "Unknown choice for -v, use -vf, -ve or -vb!" );
}
break;
case 'x' : // Fill unspecified memory.
if( strlen( param ) != 4 )
throw new ErrorMsg( "Use two hex digits for the -x parameter!" );
try
{
memoryFillPattern = convertHex( param + 2 );
}
catch( ErrorMsg * e )
{
delete e;
throw new ErrorMsg( "Hex number format error for -x parameter!" );
}
break;
case 'y' : // Read lock bits.
if( strlen( param ) != 2 )
throw new ErrorMsg( "Parameter -y needs no extra arguments!" );
readLockBits = true;
break;
case 'z' : // No progress indicator?
if( strlen( param ) != 2 )
throw new ErrorMsg( "Parameter -z needs no extra arguments!" );
noProgressIndicator = true;
break;
default:
throw new ErrorMsg( "Unknow parameter!" );
}
}
}
void JobInfo::help()
{
cout
<< "Command Line Switches:" << endl
<< " [-d device name] [-if infile] [-ie infile] [-of outfile] [-oe outfile]" << endl
<< " [-s] [-O index] [-O#value] [-Sf addr] [-Se addr] [-e] [-p f|e|b]" << endl
<< " [-r f|e|b] [-v f|e|b] [-l value] [-L value] [-y] [-f value] [-E value]" << endl
<< " [-F value] [-G value] [-q] [-x value] [-af start,stop] [-ae start,stop]" << endl
<< " [-c port] [-b h|s] [-g] [-z] [-h|?]" << endl
<< endl
<< "Parameters:" << endl
<< "d Device name. Must be applied when programming the device." << endl
<< "if Name of FLASH input file. Required for programming or verification" << endl
<< " of the FLASH memory. The file format is Intel Extended HEX." << endl
<< "ie Name of EEPROM input file. Required for programming or verification" << endl
<< " of the EEPROM memory. The file format is Intel Extended HEX." << endl
<< "of Name of FLASH output file. Required for readout of the FLASH memory." << endl
<< " The file format is Intel Extended HEX." << endl
<< "oe Name of EEPROM output file. Required for readout of the EEPROM" << endl
<< " memory. The file format is Intel Extended HEX." << endl
<< "s Read signature bytes." << endl;
getch();
cout
<< "O Read oscillator calibration byte. 'index' is optional." << endl
<< "O# User-defined oscillator calibration value." << endl
<< "Sf Write oscillator cal. byte to FLASH memory. 'addr' is byte address." << endl
<< "Se Write oscillator cal. byte to EEPROM memory. 'addr' is byte address." << endl
<< "e Erase device. If applied with another programming parameter, the" << endl
<< " device will be erased before any other programming takes place." << endl
<< "p Program device; FLASH (f), EEPROM (e) or both (b). Corresponding" << endl
<< " input files are required." << endl
<< "r Read out device; FLASH (f), EEPROM (e) or both (b). Corresponding" << endl
<< " output files are required" << endl
<< "v Verify device; FLASH (f), EEPROM (e) or both (b). Can be used with" << endl
<< " -p or alone. Corresponding input files are required." << endl
<< "l Set lock byte. 'value' is an 8-bit hex. value." << endl
<< "L Verify lock byte. 'value' is an 8-bit hex. value to verify against." << endl
<< "y Read back lock byte." << endl
<< "f Set fuse bytes. 'value' is a 16-bit hex. value describing the" << endl
<< " settings for the upper and lower fuse bytes." << endl
<< "E Set extended fuse byte. 'value' is an 8-bit hex. value describing the" << endl
<< " extend fuse settings." << endl
<< "F Verify fuse bytes. 'value' is a 16-bit hex. value to verify against." << endl;
getch();
cout
<< "G Verify extended fuse byte. 'value' is an 8-bit hex. value to" << endl
<< " verify against." << endl
<< "q Read back fuse bytes." << endl
<< "x Fill unspecified locations with a value (00-ff). The default is" << endl
<< " to not program locations not specified in the input files." << endl
<< "af FLASH address range. Specifies the address range of operations. The" << endl
<< " default is the entire FLASH. Byte addresses in hex." << endl
<< "ae EEPROM address range. Specifies the address range of operations." << endl
<< " The default is the entire EEPROM. Byte addresses in hex." << endl
<< "c Select communication port; 'COM1' to 'COM99'. If this parameter is" << endl
<< " omitted the program will scan the COM ports for a programmer." << endl
<< "b Get revisions; hardware revision (h) and software revision (s)." << endl
<< "g Silent operation." << endl
<< "z No progress indicator. E.g. if piping to a file for log purposes, use" << endl
<< " this option to avoid the characters used for the indicator." << endl
<< "h|? Help information (overrides all other settings)." << endl
<< endl
<< "Example:" << endl
<< " AVROSP -dATmega128 -ifmyapp.hex -pf" << endl;
}
long JobInfo::convertHex( char * txt )
{
string t( txt );
return Util.convertHex( t );
}
void JobInfo::doJob()
{
long scanCOM;
SerialPort * com;
AVRProgrammer * prog;
AVRDevice * avr;
string programmerID;
long sig0, sig1, sig2; // Signature bytes.
/* Set correct silent and progress indicator status */
if( silentMode )
{
Util.muteLog();
Util.muteProgress(); // Silent also includes progress indicator.
}
if( noProgressIndicator )
Util.muteProgress();
/* Application header text */
Util.log( "AVR Open-source Programmer " VERSIONSTRING " (C) 2004 Atmel Corp.\n\r\n\r" );
/* Show help screen? */
if( showHelp )
{
help();
return;
}
Util.log( "Serial port timeout set to " TIMEOUTSTRING " sec.\r\n" );
/* Need to scan for COM port? */
if( comPort == -1 )
{
Util.log( "Scanning COM ports for supported programmer...\n\r" );
for( scanCOM = 1; scanCOM <= 99; scanCOM++ )
{
Util.progress( "COM" + Util.convertLong( scanCOM ) + "...\r\n" );
try
{
/* Try to communicate */
com = NULL;
com = new SerialPort( scanCOM, TIMEOUT );
com->openChannel();
programmerID = AVRProgrammer::readProgrammerID( com );
/* Contact! Check ID... Add custom handler signatures here */
if( programmerID == "AVRBOOT" || programmerID == "AVR ISP" )
{
break;
}
delete com;
Util.progress( programmerID + " found - not supported!\r\n" );
}
catch( ErrorMsg * e )
{
/* No contact on COM port, skip to next */
if( com != NULL ) delete com;
delete e;
}
}
/* Exit if no supported programmers found */
if( scanCOM > 99 )
{
Util.log( "No supported programmers found!\r\n" );
return;
}
comPort = scanCOM;
} else // ... COM port is specified
{
/* Try to communicate, errors will propagate to caller */
com = new SerialPort( comPort, TIMEOUT );
com->openChannel();
programmerID = AVRProgrammer::readProgrammerID( com );
/* Contact! Check ID */
if( programmerID != "AVRBOOT" && programmerID != "AVR ISP" )
throw new ErrorMsg( "Programmer not supported!" );
}
Util.log( "Found " + programmerID + " on COM" + Util.convertLong( comPort ) + "!\r\n" );
/* Create programmer interface object, add custom handlers here */
if( programmerID == "AVRBOOT" )
{
prog = new AVRBootloader( com );
}
if( programmerID == "AVR ISP" )
{
prog = new AVRInSystemProg( com );
}
Util.log( "Entering programming mode...\r\n" );
prog->enterProgrammingMode(); // Ignore return code.
/* Do device independent operations */
doDeviceIndependent( prog );
/* Finished if no device name is specified */
if( deviceName.size() == 0 )
{
Util.log( "Device name not specified!\r\n" );
return;
}
/* Parse XML part description file */
avr = new AVRDevice( deviceName );
Util.log( "Parsing XML file for device parameters...\r\n" );
Util.parsePath( searchpath );
avr->readParametersFromAVRStudio( searchpath );
/* Verify that the device signature matches the signature from the XML file */
avr->getSignature( &sig0, &sig1, &sig2 );
if( prog->checkSignature( sig0, sig1, sig2 ) )
Util.log( "Signature matches device!\r\n" );
/* Do device dependent operations */
doDeviceDependent( prog, avr );
/* Clean up */
Util.log( "Leaving programming mode...\r\n" );
prog->leaveProgrammingMode(); // Ignore return code.
delete avr;
delete prog;
delete com;
}
void JobInfo::doDeviceIndependent( AVRProgrammer * prog )
{
long sig0, sig1, sig2; // Signature bytes.
long minor, major; // Minor and major programmer revision.
/* Read signature? */
if( readSignature )
{
Util.log( "Reading signature bytes: " );
if( !prog->readSignature( &sig0, &sig1, &sig2 ) )
throw new ErrorMsg( "Signature readout is not supported by this programmer!" );
/* No pass through Util, since user wants the info */
cout.fill( '0' );
cout << hex
<< "0x" << setw(2) << sig0 << " "
<< "0x" << setw(2) << sig1 << " "
<< "0x" << setw(2) << sig2 << endl;
}
/* Get software version? */
if( getSWrevision )
{
Util.log( "Reading programmer software revision: " );
if( !prog->programmerSoftwareVersion( &major, &minor ) )
throw new ErrorMsg( "Software revision readout is not supported by this programmer!" );
/* No pass through Util, since user wants the info */
cout << (char) (major & 0xff) << "." << (char) (minor & 0xff) << endl;
}
/* Get software version? */
if( getHWrevision )
{
Util.log( "Reading programmer hardware revision: " );
if( !prog->programmerHardwareVersion( &major, &minor ) )
throw new ErrorMsg( "Hardware revision readout is not supported by this programmer!" );
/* No pass through Util, since user wants the info */
cout << (char) (major & 0xff) << "." << (char) (minor & 0xff) << endl;
}
}
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!" );
}
}
/* end of file */