⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 avrprog.h

📁 上位机软件 for avricp 根据功能设定熔丝
💻 H
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************
*
* 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 + -