📄 avrprog.h
字号:
/*****************************************************************************
*
* Atmel Corporation
*
* File : AVRInSystemProg.hpp
* Compiler : Dev-C++ 4.9.8.0 - http://bloodshed.net/dev/
* Revision : $Revision: 3.0 $
* Date : $Date: Tuesday, January 17, 2006 18:33:56 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.
*
*
****************************************************************************/
#ifndef AVRPROG_HPP
#define AVRPROG_HPP
#include "CN_COM.h"
#include "AVRDEVICE.h"
#include "HEXparser.h"
class AVRProg
{
protected:
long pagesize; // Flash page size.
bool setAddress( long address )
{
if(!com.IsOpen())return false;
char c;
/* Set current address */
/* Send command 'A' */
c = 'A';
com.Write(&c,1);
c = (char)(address >> 8);
com.Write(&c,1);
c = (char)(address & 0xff);
com.Write(&c,1);
/* Should return CR */
if(!com.GetCharWait(&c))
{
AfxMessageBox( "超时!");
return false;
}
else if(c != '\r' )
{
AfxMessageBox( "不能设定地址(命令:A)!");
return false;
}
return true;
}
bool writeFlashLowByte( long value ) // Alwyas low byte first...
{
if(!com.IsOpen())return false;
char c;
/* Send command 'c' */
c = 'c';
com.Write(&c,1);
c = (char)(value);
com.Write(&c,1);
/* Should return CR */
if(!com.GetCharWait(&c))
{
AfxMessageBox( "超时!");
return false;
}
else if(c != '\r' )
{
AfxMessageBox( "不能FLASH写(命令:c)!");
return false;
}
return true;
}
bool writeFlashHighByte( long value ) // ...then high byte.
{
if(!com.IsOpen())return false;
char c;
/* Send command 'C' */
c = 'C';
com.Write(&c,1);
c = (char)(value);
com.Write(&c,1);
/* Should return CR */
if(!com.GetCharWait(&c))
{
AfxMessageBox( "超时!");
return false;
}
else if(c != '\r' )
{
AfxMessageBox( "不能FLASH写(命令:C)!");
return false;
}
return true;
}
bool writeFlashPage()
{
if(!com.IsOpen())return false;
char c;
/* Send command 'm' */
c = 'm';
com.Write(&c,1);
/* Should return CR */
if(!com.GetCharWait(&c))
{
AfxMessageBox( "超时!");
return false;
}
else if(c != '\r' )
{
AfxMessageBox( "不能FLASH页写(命令:m)!");
return false;
}
return true;
}
bool verifyIsOk(long address,long readc)
{
long mem;
if(address & 0x01)
{
mem=hexf.getData( address);
}
else
{
mem=hexf.getData( address);
if(address<hexf.getRangeEnd())mem|=hexf.getData( address+1)<<8;
}
if( mem != readc )
{
char mss[50];
sprintf(mss,"地址:%04X 读出:%04X 应该:%04X ! 继续?",address,readc,mem);
if(AfxMessageBox( mss,MB_YESNO)==IDYES)
return true ;
else return false;
}
else return true;
}
public:
cnComm com;
AVRDevice device;
HEXFile hexf;
unsigned char devicesupport[256];
long devicesupportNumber;
bool getDeviceSupportList()
{
int i = 0;
devicesupportNumber=0;
char c='t';
com.Write(&c,1);
do
{
if(com.GetCharWait(&c))
{
devicesupport[i]=c;
}
else devicesupport[i]=0;
if(devicesupport[i])
{
devicesupportNumber++;
}
}while (devicesupport[i++]);
return true;
}
/* 结构 */
AVRProg(){;}
/* 析构 */
~AVRProg() {;}
/* 方法 */
CString readProgrammerID( ) // Reads 7-character ID.
{
CString id( "1234567" ); // Reserve 7 characters.
if(!com.IsOpen())
{
AfxMessageBox( "NULL pointer provided for communication channel!" );
return id;
}
char c,s[16];
/* Synchonize with programmer */
c=27;
for( int i = 0; i < 10; i++ )
com.Write(&c,1); // Send ESC
com.ClearRecvBuff();
//读软件标识
c='S';
com.Write(&c,1);
if(com.GetStrWait(s,7)==7)
{
id = s;
}
else
{
//id="";
AfxMessageBox( "没有发现编程器!" );
}
getDeviceSupportList();
return id;
}
// 设页尺寸
void setPagesize( long _pagesize ) { pagesize = _pagesize; }
// 进入编程模式
bool enterProgrammingMode()
{
if(!com.IsOpen())return false;
char c;
/* Must select a device from the AVRISP device code table first */
c='T';
com.Write(&c,1);
c=device.getDeviceCode();
com.Write(&c,1);
/* Should return CR */
if(!com.GetCharWait(&c))
{
AfxMessageBox( "超时!");
return false;
}
else if(c != '\r' )
{
AfxMessageBox( "不能进入编程模式(命令:T)!");
return false;
}
long pgs = device.getPageSize();
//if( pgs == 0 ) pgs = -1;
setPagesize( pgs ) ;
/* Send command 'P' */
c='P';
com.Write(&c,1);
/* Should return CR */
if(!com.GetCharWait(&c))
{
AfxMessageBox( "超时!");
return false;
}
else if(c != '\r' )
{
AfxMessageBox( "不能进入编程模式(命令:P)!");
return false;
}
return true;
}
// 退出编程模式
bool leaveProgrammingMode()
{
if(!com.IsOpen())return false;
char c;
/* Send command 'L' */
c='L';
com.Write(&c,1);
/* 应该返回 CR */
if(!com.GetCharWait(&c))
{
AfxMessageBox( "超时!");
return false;
}
else if(c != '\r' )
{
AfxMessageBox( "不能退出编程模式(命令:L)!");
return false;
}
return true;
}
// 芯片擦除
bool chipErase()
{
if(!com.IsOpen())return false;
char c;
/* Send command 'e' */
c='e';
com.Write(&c,1);
/* 应该返回 CR */
if(!com.GetCharWait(&c))
{
AfxMessageBox( "超时!");
return false;
}
else if(c != '\r' )
{
AfxMessageBox( "不能擦除(命令:e)!");
return false;
}
return true;
}
bool readOSCCAL( long pos, long * value )
{
if(!com.IsOpen())return false;
char c;
/* Send command '.' */
c = '.';
com.Write(&c,1);
c = 0x38;
com.Write(&c,1);
c = 0x00;
com.Write(&c,1);
c = (char)pos;
com.Write(&c,1);
c = 0x00; // Dummy.
com.Write(&c,1);
if(com.GetCharWait(&c)) * value = c;
else {AfxMessageBox( "通用命令超时!");return false;}
/* 应该返回 CR */
if(!com.GetCharWait(&c))
{
AfxMessageBox( "超时!");
return false;
}
else if(c != '\r' )
{
AfxMessageBox( "不能校正时钟(命令:.)!");
return false;
}
return true;
}
// 读芯片签名
bool readSignature( long * sig0, long * sig1, long * sig2 )
{
if(!com.IsOpen())return false;
char c,s[4];
com.ClearRecvBuff();
/* Send command 's' */
c='s';
com.Write(&c,1);
if(com.GetStrWait(s,3)!=3)
{
AfxMessageBox( "未知签名(命令:s)!");
return false;
}
else
{
*sig2=s[0];
*sig1=s[1];
*sig0=s[2];
return true;
}
AfxMessageBox( "超时!");
return false;
}
bool 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 )
{
AfxMessageBox( "标识不匹配芯片!");
return false;
}
return true; // Indicate supported command.
}
bool equalSignature( long sig0, long sig1, long sig2 )
{
long sig[3];
/* Get signature */
device.getSignature( sig, sig+1, sig+2 );
/* Compare signature */
if( sig[0] != sig0 || sig[1] != sig1 || sig[2] != sig2 )
{
//AfxMessageBox( "标识不匹配芯片数据表!");
return false;
}
return true; // Indicate supported command.
}
bool isRightSignature(long * sig0, long * sig1, long * sig2)
{
long sig[3];
readSignature( sig, sig+1, sig+2 );
*sig2=sig[2];
*sig1=sig[1];
*sig0=sig[0];
return equalSignature( sig[0], sig[1],sig[2] );
}
bool isDeviceOK()
{
char ts[80];
bool r = true;
long sig[3];
readSignature( sig, sig+1, sig+2 );
long sig_get[3];
device.getSignature( sig_get, sig_get+1, sig_get+2 );
if( sig[0] != sig_get[0] || sig[1] != sig_get[1] || sig[2] != sig_get[2] )
{
sprintf(ts,"%s 标识不匹配:%02X %02X %02X 不等于 %02X %02X %02X ! 继续?",
device.getDeviceName(),
(unsigned char)sig[0],(unsigned char)sig[1],(unsigned char)sig[2],
(unsigned char)sig_get[0],(unsigned char)sig_get[1],(unsigned char)sig_get[2]);
if(AfxMessageBox( ts ,MB_YESNO) == IDNO) r= false;
}
return r;
}
bool writeFlashByte( long address, long value )
{
if(!com.IsOpen())return false;
if( address >= 0x20000 )
{
AfxMessageBox( "Flash addresses above 128k are currently not supported!");
return false;
}
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 && pagesize != 0)
{
setAddress( address >> 1 ); // The address could be autoincremented.
writeFlashPage();
}
return true; // Indicate supported command.
}
bool writeEEPROMByte( long address, long value )
{
if(!com.IsOpen())return false;
if( address >= 0x10000 )
{
AfxMessageBox( "EEPROM addresses above 64k are currently not supported!");
return false;
}
setAddress( address );
char c;
/* Send command 'l' */
c='D';
com.Write(&c,1);
c=(char)( value );
com.Write(&c,1);
/* 应该返回 CR */
if(!com.GetCharWait(&c))
{
AfxMessageBox( "超时!");
return false;
}
else if(c != '\r' )
{
AfxMessageBox( "不能写EEPROM BYTE(命令:D)!");
return false;
}
return true; // Indicate supported command.
}
bool writeFlash(CProgressCtrl *p)//( HEXFile * data )
{
long start, end; // Data address range.
bool autoincrement; // Bootloader supports address autoincrement?
long address;
/* Check that pagesize is set */
if( pagesize == -1 )
AfxMessageBox( "Programmer pagesize is not set!" );
/* Get range from HEX file */
start = hexf.getRangeStart();
end = hexf.getRangeEnd();
/* Check autoincrement support */
char c;
c='a';
com.Write(&c,1);
if(!com.GetCharWait(&c))
{
AfxMessageBox( "超时!");
return false;
}
else if( c == '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( hexf.getData( address ) );
address++;
/* Need to write page? */
if( pagesize != -1 && pagesize != 0)
{
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( hexf.getData( address ) );
writeFlashHighByte( hexf.getData( address+1 ) );
address += 2;
/* Need to write page? */
if( pagesize != -1 && pagesize != 0)
{
if( (address % pagesize) == 0 ) // Just passed a page boundary?
{
setAddress( (address-2) >> 1 ); // Set to an address inside the page.
writeFlashPage();
setAddress( address >> 1 );
}
}
p->SetPos(100*(address)/(end+1));
} while( address < end );
/* Need to write one even byte before finished? */
if( address == end )
{
/* Use only low byte */
writeFlashLowByte( hexf.getData( address ) );
writeFlashHighByte( 0xff ); // No-write in high byte.
}
/* Need to write page? */
if( pagesize != -1 && pagesize != 0)
{
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();
}
}
p->SetPos(0);
return true; // Indicate supported command.
}
bool readFlash(CProgressCtrl *p)//( HEXFile * data )
{
long start, end; // Data address range.
bool autoincrement; // Bootloader supports address autoincrement?
long address;
if( pagesize == -1 )
AfxMessageBox( "Programmer pagesize is not set!" );
/* Get range from HEX file */
start = hexf.getRangeStart();
end = hexf.getRangeEnd();
/* Check autoincrement support */
char c;
c='a';
com.Write(&c,1);
if(!com.GetCharWait(&c))
{
AfxMessageBox( "超时!");
return false;
}
else if( c == '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 */
c='R';
com.Write(&c,1);
if(!com.GetCharWait(&c))
{
AfxMessageBox( "超时!");
return false;
}
hexf.setData( address, c ); // High byte.
if(!com.GetCharWait(&c))
{
AfxMessageBox( "超时!");
return false;
} // Dont use low byte.
address++;
}
/* Get words */
do
{
/* Need to set address again? */
if( !autoincrement )
setAddress( address >> 1 );
/* Get words */
c='R';
com.Write(&c,1);
if(!com.GetCharWait(&c))
{
AfxMessageBox( "超时!");
return false;
}
hexf.setData( address+1, c ); // High byte.
if(!com.GetCharWait(&c))
{
AfxMessageBox( "超时!");
return false;
}
hexf.setData( address, c );// Dont use low byte.
address += 2;
p->SetPos(100*(address)/(end+1));
} while( address < end );
/* Need to read one even byte before finished? */
if( address == end )
{
/* Read both, but use only low byte */
c='R';
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -