📄 avrbootloader.cpp
字号:
/* Get range from HEX file */
start = data->getRangeStart();
end = data->getRangeEnd();
/* Need to read one odd byte first? */
address = start;
if( address & 1 )
{
setAddress( address >> 1 ); // Flash operations use word addresses.
/* Use only high word */
comm->sendByte( 'R' );
comm->flushTX();
data->setData( address, comm->getByte() ); // High byte.
comm->getByte(); // Low byte.
address++;
}
/* Need to read from middle to end of block first? */
if( (address % blocksize) > 0 ) // In the middle of a block?
{
bytecount = blocksize - (address % blocksize); // Bytes left in block.
if( (address+bytecount-1) > end ) // Is that past the read range?
{
bytecount = end-address+1; // Bytes left in read range.
bytecount &= ~0x01; // Adjust to word count.
}
if( bytecount > 0 )
{
setAddress( address >> 1 ); // Flash operations use word addresses.
/* Start Flash block read */
comm->sendByte( 'g' );
comm->sendByte( (bytecount>>8) & 0xff ); // Size, MSB first.
comm->sendByte( bytecount & 0xff );
comm->sendByte( 'F' ); // Flash memory.
while( bytecount > 0 )
{
data->setData( address, comm->getByte() );
address++;
bytecount--;
}
Util.progress( "#" ); // Advance progress indicator.
}
}
/* More complete blocks to read? */
while( (end-address+1) >= blocksize )
{
bytecount = blocksize;
setAddress( address >> 1 ); // Flash operations use word addresses.
/* Start Flash block read */
comm->sendByte( 'g' );
comm->sendByte( (bytecount>>8) & 0xff ); // Size, MSB first.
comm->sendByte( bytecount & 0xff );
comm->sendByte( 'F' ); // Flash memory.
while( bytecount > 0 )
{
data->setData( address, comm->getByte() );
address++;
bytecount--;
}
Util.progress( "#" ); // Advance progress indicator.
}
/* Any bytes left in last block */
if( (end-address+1) >= 1 )
{
bytecount = (end-address+1); // Get bytes left to read.
if( bytecount & 1 )
bytecount++; // Align to next word boundary.
setAddress( address >> 1 ); // Flash operations use word addresses.
/* Start Flash block read */
comm->sendByte( 'g' );
comm->sendByte( (bytecount>>8) & 0xff ); // Size, MSB first.
comm->sendByte( bytecount & 0xff );
comm->sendByte( 'F' ); // Flash memory.
while( bytecount > 0 )
{
if( address > end )
comm->getByte(); // Don't read outside write range.
else
data->setData( address, comm->getByte() );
address++;
bytecount--;
}
Util.progress( "#" ); // Advance progress indicator.
}
Util.progress( "\r\n" ); // Finish progress indicator.
return true; // Indicate supported command.
}
bool AVRBootloader::writeEEPROM( HEXFile * data )
{
long start, end; // Data address range.
bool autoincrement; // Bootloader supports address autoincrement?
long address;
/* Check block write support */
comm->sendByte( 'b' );
comm->flushTX();
if( comm->getByte() == 'Y' )
{
Util.log( "Using block mode...\r\n" );
return writeEEPROMBlock( data ); // Finished writing.
}
/* Get range from HEX file */
start = data->getRangeStart();
end = data->getRangeEnd();
/* Check autoincrement support */
comm->sendByte( 'a' );
comm->flushTX();
if( comm->getByte() == 'Y' )
autoincrement = true;
else
autoincrement = false;
/* Set initial address */
setAddress( start );
/* Send data */
address = start;
do
{
/* Need to set address again? */
if( !autoincrement )
setAddress( address );
/* Send byte */
comm->sendByte( 'D' );
comm->sendByte( data->getData( address ) );
comm->flushTX();
if( comm->getByte() != '\r' )
throw new ErrorMsg( "Writing byte to EEPROM failed! "
"Programmer did not return CR after 'D'-command." );
if( (address % MEM_PROGRESS_GRANULARITY) == 0 )
Util.progress( "#" ); // Advance progress indicator.
address++;
} while( address <= end );
Util.progress( "\r\n" ); // Finish progress indicator.
return true; // Indicate supported command.
}
bool AVRBootloader::writeEEPROMBlock( HEXFile * data )
{
long start, end; // Data address range.
long blocksize; // Bootloader block size.
long bytecount;
long address;
/* Get block size, assuming command 'b' just issued and 'Y' has been read */
blocksize = (comm->getByte() << 8) | comm->getByte();
/* Get range from HEX file */
start = data->getRangeStart();
end = data->getRangeEnd();
/* Send data */
address = start;
while( address <= end ) // More bytes to write?
{
bytecount = blocksize; // Try a full block.
if( (address+bytecount-1) > end ) // Is that past the write range?
{
bytecount = end-address+1; // Bytes left in write range.
}
setAddress( address );
/* Start EEPROM block write */
comm->sendByte( 'B' );
comm->sendByte( (bytecount>>8) & 0xff ); // Size, MSB first.
comm->sendByte( bytecount & 0xff );
comm->sendByte( 'E' ); // EEPROM memory.
while( bytecount > 0 )
{
comm->sendByte( data->getData( address ) );
comm->flushTX();
address++;
bytecount--;
}
if( comm->getByte() != '\r' )
throw new ErrorMsg( "Writing EEPROM block failed! "
"Programmer did not return CR after 'BxxE'-command." );
Util.progress( "#" ); // Advance progress indicator.
}
Util.progress( "\r\n" ); // Finish progress indicator.
return true; // Indicate supported command.
}
bool AVRBootloader::readEEPROM( HEXFile * data )
{
long start, end; // Data address range.
bool autoincrement; // Bootloader supports address autoincrement?
long address;
/* Check block write support */
comm->sendByte( 'b' );
comm->flushTX();
if( comm->getByte() == 'Y' )
{
Util.log( "Using block mode...\r\n" );
return readEEPROMBlock( data ); // Finished writing.
}
/* Get range from HEX file */
start = data->getRangeStart();
end = data->getRangeEnd();
/* Check autoincrement support */
comm->sendByte( 'a' );
comm->flushTX();
if( comm->getByte() == 'Y' )
autoincrement = true;
else
autoincrement = false;
/* Set initial address */
setAddress( start );
/* Read data */
address = start;
do
{
/* Need to set address again? */
if( !autoincrement )
setAddress( address );
/* Get byte */
comm->sendByte( 'd' );
comm->flushTX();
data->setData( address, comm->getByte() );
if( (address % MEM_PROGRESS_GRANULARITY) == 0 )
Util.progress( "#" ); // Advance progress indicator.
address++;
} while( address <= end );
Util.progress( "\r\n" ); // Finish progress indicator.
return true; // Indicate supported command.
}
bool AVRBootloader::readEEPROMBlock( HEXFile * data )
{
long start, end; // Data address range.
long blocksize; // Bootloader block size.
long bytecount;
long address;
/* Get block size, assuming command 'b' just issued and 'Y' has been read */
blocksize = (comm->getByte() << 8) | comm->getByte();
/* Get range from HEX file */
start = data->getRangeStart();
end = data->getRangeEnd();
/* Read data */
address = start;
while( address <= end ) // More bytes to read?
{
bytecount = blocksize; // Try a full block.
if( (address+bytecount-1) > end ) // Is that past the read range?
{
bytecount = end-address+1; // Bytes left in read range.
}
setAddress( address );
/* Start EEPROM block read */
comm->sendByte( 'g' );
comm->sendByte( (bytecount>>8) & 0xff ); // Size, MSB first.
comm->sendByte( bytecount & 0xff );
comm->sendByte( 'E' ); // EEPROM memory.
while( bytecount > 0 )
{
data->setData( address, comm->getByte() );
address++;
bytecount--;
}
Util.progress( "#" ); // Advance progress indicator.
}
Util.progress( "\r\n" ); // Finish progress indicator.
return true; // Indicate supported command.
}
bool AVRBootloader::writeLockBits( long bits )
{
/* Send command 'l' */
comm->sendByte( 'l' );
comm->sendByte( bits & 0xff );
comm->flushTX();
/* Should return CR */
if( comm->getByte() != '\r' )
throw new ErrorMsg( "Writing lock bits failed! "
"Programmer did not return CR after 'l'-command." );
return true; // Indicate supported command.
}
bool AVRBootloader::readLockBits( long * bits )
{
/* Send command 'r' */
comm->sendByte( 'r' );
comm->flushTX();
/* Get data */
*bits = comm->getByte();
return true; // Indicate supported command.
}
bool AVRBootloader::writeFuseBits( long bits )
{
return false; // Indicate unsupported command.
}
bool AVRBootloader::readFuseBits( long * bits )
{
long lowfuse, highfuse;
/* Send command 'N' */
comm->sendByte( 'N' );
comm->flushTX();
/* Get high fuse bits */
highfuse = comm->getByte();
/* Send command 'F' */
comm->sendByte( 'F' );
comm->flushTX();
/* Get low fuse bits */
lowfuse = comm->getByte();
*bits = (highfuse << 8) | lowfuse;
return true; // Indicate supported command.
}
bool AVRBootloader::writeExtendedFuseBits( long bits )
{
return false; // Indicate unsupported command.
}
bool AVRBootloader::readExtendedFuseBits( long * bits )
{
/* Send command 'Q' */
comm->sendByte( 'Q' );
comm->flushTX();
/* Get data */
*bits = comm->getByte();
return true; // Indicate supported command.
}
bool AVRBootloader::programmerSoftwareVersion( long * major, long * minor )
{
/* Send command 'V' to get software version */
comm->sendByte( 'V' );
comm->flushTX();
/* Get data */
*major = comm->getByte();
*minor = comm->getByte();
return true; // Indicate supported command.
}
bool AVRBootloader::programmerHardwareVersion( long * major, long * minor )
{
return false; // Indicate unsupported command.
}
void AVRBootloader::setAddress( long address )
{
/* Set current address */
if( address < 0x10000 ) {
comm->sendByte( 'A' );
comm->sendByte( (address >> 8) & 0xff );
comm->sendByte( address & 0xff );
comm->flushTX();
} else {
comm->sendByte( 'H' );
comm->sendByte( (address >> 16) & 0xff );
comm->sendByte( (address >> 8) & 0xff );
comm->sendByte( address & 0xff );
comm->flushTX();
}
/* Should return CR */
if( comm->getByte() != '\r' ) {
throw new ErrorMsg( "Setting address for programming operations failed! "
"Programmer did not return CR after 'A'-command." );
}
}
void AVRBootloader::writeFlashLowByte( long value )
{
comm->sendByte( 'c' );
comm->sendByte( value );
comm->flushTX();
if( comm->getByte() != '\r' )
throw new ErrorMsg( "Writing Flash low byte failed! "
"Programmer did not return CR after 'c'-command." );
}
void AVRBootloader::writeFlashHighByte( long value )
{
comm->sendByte( 'C' );
comm->sendByte( value );
comm->flushTX();
if( comm->getByte() != '\r' )
throw new ErrorMsg( "Writing Flash high byte failed! "
"Programmer did not return CR after 'C'-command." );
}
void AVRBootloader::writeFlashPage()
{
comm->sendByte( 'm' );
comm->flushTX();
if( comm->getByte() != '\r' )
throw new ErrorMsg( "Writing Flash page failed! "
"Programmer did not return CR after 'm'-command." );
}
/* end of file */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -