📄 avrinsystemprog.cpp
字号:
/*****************************************************************************
*
* Atmel Corporation
*
* File : AVRInSystemProg.cpp
* Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/
* Revision : $Revision: 3.0 $
* Date : $Date: Tuesday, January 17, 2006 18:33:48 UTC $
* Updated by : $Author: raapeland $
*
* Support mail : avr@atmel.com
*
* Target platform : Win32
*
* AppNote : AVR911 - AVR Open-source Programmer
*
* Description : A class providing an interface to the AVR ISP described
* in Application Note AVR910. This class is derived from AVRPRogrammer.
*
*
****************************************************************************/
#include "AVRInSystemProg.hpp"
#include <sstream>
#include <iomanip>
#define MEM_PROGRESS_GRANULARITY 256 // For use with progress indicator.
/* Constructor */
AVRInSystemProg::AVRInSystemProg( CommChannel * _comm ) :
AVRProgrammer::AVRProgrammer( _comm )
{
/* No code here */
}
/* Destructor */
AVRInSystemProg::~AVRInSystemProg()
{
/* No code here */
}
bool AVRInSystemProg::enterProgrammingMode()
{
/* Must select a device from the AVRISP device code table first */
comm->sendByte( 'T' );
comm->sendByte( 0x64 ); // Select ATmega163, any device in the table will do.
comm->flushTX();
/* Should return CR */
if( comm->getByte() != '\r' )
throw new ErrorMsg( "Entering programming mode failed! "
"Programmer did not return CR after 'T'-command." );
/* Send command 'P' */
comm->sendByte( 'P' );
comm->flushTX();
/* Should return CR */
if( comm->getByte() != '\r' )
throw new ErrorMsg( "Entering programming mode failed! "
"Programmer did not return CR after 'P'-command." );
return true; // Indicate supported command.
}
bool AVRInSystemProg::leaveProgrammingMode()
{
/* Send command 'L' */
comm->sendByte( 'L' );
comm->flushTX();
/* Should return CR */
if( comm->getByte() != '\r' )
throw new ErrorMsg( "Leaving programming mode failed! "
"Programmer did not return CR after 'L'-command." );
return true; // Indicate supported command.
}
bool AVRInSystemProg::chipErase()
{
/* Send command 'e' */
comm->sendByte( 'e' );
comm->flushTX();
if( comm->getByte() != '\r' )
throw new ErrorMsg( "Chip erase failed! "
"Programmer did not return CR after 'e'-command." );
return true; // Indicate supported command.
}
bool AVRInSystemProg::readOSCCAL( long pos, long * value )
{
/* Use AVRISP's 4-byte universal command */
comm->sendByte( '.' );
comm->sendByte( 0x38 );
comm->sendByte( 0x00 );
comm->sendByte( pos );
comm->sendByte( 0x00 ); // Dummy.
comm->flushTX();
*value = comm->getByte();
if( comm->getByte() != '\r' ) // Check return code from command.
throw new ErrorMsg( "OSCCAL value readout failed! "
"Programmer did not return CR after '.'-command." );
return true; // Indicate supported command.
}
bool AVRInSystemProg::readSignature( long * sig0, long * sig1, long * sig2 )
{
/* Send command 's' */
comm->sendByte( 's' );
comm->flushTX();
/* Get actual signature */
*sig2 = comm->getByte();
*sig1 = comm->getByte();
*sig0 = comm->getByte();
}
bool AVRInSystemProg::checkSignature( long sig0, long sig1, long sig2 )
{
long sig[3];
/* Get signature */
readSignature( sig, sig+1, sig+2 );
/* Compare signature */
if( sig[0] != sig0 || sig[1] != sig1 || sig[2] != sig2 )
{
ostringstream msg;
msg << "Signature does not match selected device! ";
msg << "Actual signature: (" << hex
<< "0x" << setw(2) << sig[0] << " "
<< "0x" << setw(2) << sig[1] << " "
<< "0x" << setw(2) << sig[2] << ") "
<< "Signature from XML-file: (" << hex
<< "0x" << setw(2) << sig0 << " "
<< "0x" << setw(2) << sig1 << " "
<< "0x" << setw(2) << sig2 << ").";
throw new ErrorMsg( msg.str() );
}
return true; // Indicate supported command.
}
bool AVRInSystemProg::writeFlashByte( long address, long value )
{
if( address >= 0x20000 )
throw new ErrorMsg( "Flash addresses above 128k are currently not supported!" );
setAddress( address >> 1 ); // Flash operations use word addresses.
/* Move data if at odd address */
if( address & 0x01 ) // Odd address?
value = (value << 8) | 0x00ff; // Move to high byte of one flash word.
else
value |= 0xff00; // Ensure no-write for high byte.
/* Send low and high byte */
writeFlashLowByte( value & 0xff );
writeFlashHighByte( value >> 8 );
/* Issue page write if required */
if( pagesize != -1 )
{
setAddress( address >> 1 ); // The address could be autoincremented.
writeFlashPage();
}
return true; // Indicate supported command.
}
bool AVRInSystemProg::writeEEPROMByte( long address, long value )
{
if( address >= 0x10000 )
throw new ErrorMsg( "EEPROM addresses above 64k are currently not supported!" );
setAddress( address );
/* Send data */
comm->sendByte( 'D' );
comm->sendByte( value );
comm->flushTX();
/* Should return CR */
if( comm->getByte() != '\r' )
throw new ErrorMsg( "Writing byte to EEPROM failed! "
"Programmer did not return CR after 'D'-command." );
return true; // Indicate supported command.
}
bool AVRInSystemProg::writeFlash( HEXFile * data )
{
long start, end; // Data address range.
bool autoincrement; // Bootloader supports address autoincrement?
long address;
/* Check that pagesize is set */
if( pagesize == -1 )
throw new ErrorMsg( "Programmer pagesize is not set!" );
/* 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 >> 1 ); // Flash operations use word addresses.
/* Need to write one odd byte first? */
address = start;
if( address & 1 )
{
/* Use only high byte */
writeFlashLowByte( 0xff ); // No-write in low byte.
writeFlashHighByte( data->getData( address ) );
address++;
/* Need to write page? */
if( pagesize != -1 )
{
if( !(address % pagesize) ) // Just passed page limit?
{
setAddress( (address-1) >> 1 ); // Set to an address inside the page.
writeFlashPage();
setAddress( address >> 1 );
}
}
}
/* Write words */
do
{
/* Need to set address again? */
if( !autoincrement )
setAddress( address >> 1 );
/* Write words */
writeFlashLowByte( data->getData( address ) );
writeFlashHighByte( data->getData( address+1 ) );
address += 2;
if( (address % MEM_PROGRESS_GRANULARITY) == 0 )
Util.progress( "#" ); // Advance progress indicator.
/* Need to write page? */
if( pagesize != -1 )
{
if( (address % pagesize) == 0 ) // Just passed a page boundary?
{
setAddress( (address-2) >> 1 ); // Set to an address inside the page.
writeFlashPage();
setAddress( address >> 1 );
}
}
} while( address < end );
/* Need to write one even byte before finished? */
if( address == end )
{
/* Use only low byte */
writeFlashLowByte( data->getData( address ) );
writeFlashHighByte( 0xff ); // No-write in high byte.
}
/* Need to write page? */
if( pagesize != -1 )
{
if( address == end || // One extra byte written...
(end+1)%pagesize != 0 ) // ...or end is not on page boundary.
{
setAddress( (address-2) >> 1 ); // Set to an address inside the page.
writeFlashPage();
}
}
Util.progress( "\r\n" ); // Finish progress indicator.
return true; // Indicate supported command.
}
bool AVRInSystemProg::readFlash( HEXFile * data )
{
long start, end; // Data address range.
bool autoincrement; // Bootloader supports address autoincrement?
long address;
if( pagesize == -1 )
throw new ErrorMsg( "Programmer pagesize is not set!" );
/* 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 >> 1 ); // Flash operations use word addresses.
/* Need to read one odd byte first? */
address = start;
if( address & 1 )
{
/* Read both, but use only high byte */
comm->sendByte( 'R' );
comm->flushTX();
data->setData( address, comm->getByte() ); // High byte.
comm->getByte(); // Dont use low byte.
address++;
}
/* Get words */
do
{
/* Need to set address again? */
if( !autoincrement )
setAddress( address >> 1 );
/* Get words */
comm->sendByte( 'R' );
comm->flushTX();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -