/*****************************************************
This program was produced by the
CodeWizardAVR V2.03.9 Standard
Automatic Program Generator
?Copyright 1998-2008 Pavel Haiduc, HP InfoTech s.r.l.
Project : AVR_BootLoader
Version : V1.00
Date : 2014-7-19
Author : Sui Hongwei
Company : SCICALA
Comments:
Chip type : ATmega64L
Program type : Boot Loader - Size:1024words
AVR Core Clock frequency: 16.000000 MHz
Memory model : Small
External RAM size : 0
Data Stack size : 1024
*****************************************************/
#include "AVR_boot.h" // 頭文件包含
//--------------------------------------------------//
//同步密碼長度
#define CONNECTCNT 7
//同步密碼
uchar KEY_Data[10] = {"SCICALA"};
// Declare your global variables here
//--------------------------------------------------//
// 全局變量定義
uchar RX_buff[BUFSIZE]; // 數據拉收緩存
uchar Frame_State,SOH_Wait_cnt; // 幀狀態,幀頭等待計數
uint Time_cnt,Error_cnt; // 超時計數,連續幀錯誤計數
uint buffptr,buffptr_old,buffptr_New; // 數據緩存指針必須大於1024
ulong FlashAddr; // Flash地址
uchar UpdatedSta; // 升級標志
//-----------------------------------------------//
//擦除(code=0x03)和寫入(code=0x05)一個Flash頁
void boot_page_ew(ulong p_address,char code)
{
#asm
ldd r26,y+1 ; R26 LSB
ldd r27,y+2 ; R27 MSB
#endasm
SPM_REG = code; // 寄存器SPMCSR中爲操作碼
#asm
mov r30,r26
mov r31,r27
#endasm
#ifdef ATMEGA128
RAMPZ=(p_address>>16); // RAMPZ0 = 1: ELPM/SPM 可以訪問程序存儲器地址$8000 - $FFFF ( 高64K 字節)
#endif
#asm("spm"); // 對指定Flash頁進行擦操作
}
//填充Flash緩衝頁中的一個字
void boot_page_fill(uint A_address,uint data)
{
#asm
LDD R30,Y+2 ; R30 LSB
LDD R31,Y+3 ; R31 MSB
LD R26,Y
LDD R27,Y+1
MOV R0,R26
MOV R1,R27
MOV R26,R30
MOV R27,R31
#endasm
SPM_REG =0x01; //寄存器SPMCSR中爲操作碼
#asm
mov r30,r26
mov r31,r27
#endasm
#asm("spm"); //對指定Flash頁進行擦操作
}
//等待一個Flash頁的寫完成
void wait_page_rw_ok(void)
{
while(SPM_REG & 0x40)
{
while(SPM_REG & 0x01);
SPM_REG = 0x11;
#asm("spm");
while(SPM_REG & 0x01);
}
}
//-----------------------------------------------//
//更新一個Flash頁的完整處理
void write_one_page(uchar data[])
{
uint i;
boot_page_ew(FlashAddr,0x03); //擦除一個Flash頁
wait_page_rw_ok(); //等待擦除完成
for(i=0;i<SPM_PAGESIZE;i+=2) //將數據填入Flash緩衝頁中 按字填充
{
boot_page_fill(i,(uint)data[i]+(data[i+1]<<8));
wait_page_rw_ok();
}
boot_page_ew(FlashAddr,0x05); //將緩衝頁數據寫入一個Flash頁
wait_page_rw_ok(); //等待寫入完成
}
//--------------------------------------------------//
//等待串口數據1S超時自動轉爲應答
unsigned char Wait1S_UART()
{
uchar i=0;
do
{
#if WDGEn
Watchdog_Reset(); // 喂狗
#endif
if(TIFR&0x10) // OCF1A: T/C1 輸出比較 A 匹配標志位
{
TIFR|=0x10; // 清除Time1定時器比較匹配標志
i++;
if(i>=4) // 等待1S 250ms*4=1S
{ Frame_State=0x06; break; } // 幀數據超時轉爲應答請求重發數據幀
}
if(UCSRAREG(COMPORTNo) & 0x80)
{
UCSRAREG(COMPORTNo)|=0x80; // 清除接收完成狀態
#if Run_LEDEn
Run_LED; // 運行LED閃爍
#endif
i=100;
return UDRREG(COMPORTNo); // 讀取UDR0
}
}
while(100!=i); // 等待數據||超時退出
}
//***************************************************//
//===================================================//
void main(void)
{
uchar packNO,packNO_old; // 包號、包號留存
uint crc16; // 接收CRC緩存
uint li; // 幀計數
uchar ch, cl; // 包號
PORT_Init(); // 端口初始化
UART_Init(); // 串口初始化
Time1_Init(); // 定時器初始化 250ms
#if WDGEn
WatchDog_Enable(); // 打開看門狗(2S)
#else
WatchDog_Disenable(); // 禁止看門狗
#endif
#if Wait_BootTime
Time_cnt=EEPROM_Read(EE_TimeAddr); // 讀取boot運行時間
#endif
#if SafeUpdated_En
UpdatedSta=EEPROM_Read(EE_SafeAddr);// 讀取升級成功標志
#endif
#asm("cli") // 關總中斷
#if Delay_En // 是否延時
for(li=0;li<5000;li++)
{ #asm("nop") }
#endif
//-----------------------------------------------//
//等待"握手",否則退出Bootloader程序,從0x0000處執行應用程序
Time_cnt += WiteTimeCnt;
cl = 0;
while(1)
{
if(TIFR&0x10) // OCF1A: T/C1 輸出比較 A 匹配標志位
{
TIFR|=0x10; // 清除Time1定時器比較匹配標志
#if Run_LEDEn
Run_LED; // 運行LED閃爍
#endif
Time_cnt--;
if(Time_cnt==0) // 等待握手超時
{
#if SafeUpdated_En
if(UpdatedSta) // 上次升級失敗
{ while(1); } // 復位boot
else
#endif
{ quit_boot(); } // 跳轉到用戶程序
}
if(UCSRAREG(COMPORTNo) & 0x80)
{
ch=Wait_UART();
if(ch== KEY_Data[cl])
{ cl++; }
else
{ cl = 0; }
//WriteCom(ch); // 密碼回傳
}
if(cl == CONNECTCNT)break;
}
#if WDGEn
Watchdog_Reset(); // 喂狗
#endif
}
//-----------------------------------------------//
//啓動Xmodex CRC傳數據=字符“C”,等待控制字〈soh〉
Time_cnt = TimeOutCntC;
while(1)
{
if(TIFR&0x10) // OCF1A: T/C1 輸出比較 A 匹配標志位
{
TIFR|=0x10; // 清除Time1定時器比較匹配標志
#if Run_LEDEn
Run_LED; // 運行LED閃爍
#endif
Send_UART(XMODEM_RWC) ; //發送 "C"
Time_cnt--;
if(Time_cnt == 0) // 等待文件超時
{
#if SafeUpdated_En
if(UpdatedSta) // 上次升級失敗
{ while(1); } // 復位boot
else
#endif
{ quit_boot(); } // 跳轉到用戶程序
} // 跳轉到用戶程序
}
if(UCSRAREG(COMPORTNo) & 0x80) // 串口有數據
{
#ifdef Xmodem
if( Wait_UART()== XMODEM_SOH) //XMODEM命令開始 0x01
#else // Xmodem_1K
if( Wait_UART()== XMODEM_STX) //XMODEM命令開始 0x02
#endif
break;
}
#if WDGEn
Watchdog_Reset(); // 喂狗
#endif
}
//-----------------------------------------------//
// 開始接收數據進入Xmodem協議接收文件
// 幀的兩個時間很重要:連續出錯10次*最大幀請求間隔6S
// 累計請求間隔10*6S=1min
packNO = 1; // Xmodem 起始爲 0x01
packNO_old=0;
buffptr = 0;
buffptr_old=0;
Error_cnt = 0;
FlashAddr = 0;
Frame_State=0x01; // 第一幀不判斷幀頭
while(1)
{
switch (Frame_State) // 幀狀態
{
case 0x00: // 接受狀態 幀頭與停止信號判斷
{
ch=XMODEM_NUL; // 清除
if(UCSRAREG(COMPORTNo) & 0x80) // 串口有數據
{ ch=Wait_UART(); } // 讀取幀頭或停止信號
if(TIFR&0x10) // OCF1A: T/C1 輸出比較 A 匹配標志位
{
TIFR|=0x10; // 清除Time1定時器比較匹配標志
SOH_Wait_cnt++; // 等待計時 250ms
if(SOH_Wait_cnt>=24) // 等待幀超時請求數據(6S*10=1min)
{
Frame_State=0x06; // 要求重發數據塊
SOH_Wait_cnt=0; // 幀請求計時
#if Run_LEDEn
Run_LED; // 運行LED閃爍
#endif
}
}
//------------------------------
if(ch== XMODEM_EOT) // 發送結束
{
for(li=(buffptr_New-128);li<buffptr_New;) // 判斷上一幀數據尾16個正確性以決定是否重傳
{
if((RX_buff[li++])!=0xff)break; // 填充幀判斷爭強EOT抗幹擾能力 FF CF
{
if((RX_buff[li++])!=0xcf)break; // 填充幀判斷爭強EOT抗幹擾能力 FF CF
}
}
if(li==buffptr_New)
{ Send_UART(XMODEM_ACK); // 最後一幀應答完成
Frame_State=0x0ff; // 轉爲退出boot
}
else
{
Frame_State=0x06; // 要求重發數據塊
SOH_Wait_cnt=0; // 幀請求計時
}
}
#ifdef Xmodem
if(ch== XMODEM_SOH) // Xmodem幀頭判斷
#else // Xmodem_1K
if(ch== XMODEM_STX) // Xmodem_1K幀頭判斷
#endif
{
Frame_State=0x01; // 轉爲包號檢查
SOH_Wait_cnt=0; // 清除幀頭等待計時
}
}
break;
case 0x01: //包序號校驗
{
ch = Wait1S_UART(); // 獲取包序號
cl = ~Wait1S_UART();
if(ch == cl) // 包號對比
{ Frame_State=0x02;
packNO=ch; // 正確保留包號
}
else
{ Frame_State=0x06; } // 重發應答ANK
}
break;
case 0x02: // 進入二級CRC校驗
{
for(li = 0; li < BUFFER_SIZE; li++) // 接收完整一幀數據 (128字節)
{
RX_buff[buffptr++] = Wait1S_UART(); // 接收數據
// 幀數據接收超時1S退出for詢環,再接收2個數據或超時1S+2S轉爲應答
if(Frame_State==0x06)break;
}
crc16 = Wait1S_UART();
crc16=crc16<<8;
crc16 += Wait1S_UART(); // 接收2個字節的CRC效驗字
if(CRC16_Word(&RX_buff[buffptr - BUFFER_SIZE],BUFFER_SIZE)==crc16) // CRC校驗驗證
{
if(packNO==packNO_old) // 接收相同包不寫flash
{ Frame_State=0x05; // 正常應答ACK
buffptr=buffptr_old;
}
else
{ Frame_State=0x03; // 正確應答
buffptr_New=buffptr; // 記錄當前數據指針
}
}
else
{ Frame_State=0x06; // 應答NAK
buffptr=buffptr_old; // 去掉錯誤數據的指針
}
}
break;
case 0x03: // 校驗通過,執行寫入
{
if(FlashAddr < BootStart) //避免寫入Boot區
{
#if BUFFER_SIZE < SPM_PAGESIZE // ---
if(buffptr >= SPM_PAGESIZE) //緩衝區滿,寫入數據;否則繼續接收
{ //接收多個幀,寫入一頁
write_one_page(&RX_buff[0]); //寫入緩衝區內容到Flash中
FlashAddr += SPM_PAGESIZE; //修改Flash頁地址
buffptr = 0;
}
#else //----------------------
while(buffptr > 0) //接收一幀,寫入多個頁面
{
write_one_page(&RX_buff[BUFSIZE - buffptr]);
FlashAddr += SPM_PAGESIZE; //修改Flash頁地址
buffptr -= SPM_PAGESIZE;
}
#endif //-----------------------
}
else //超過BootStart,忽略寫操作
{ buffptr = 0; } //重置接收指針
Frame_State=0x04;
}
break;
case 0x04: //讀取寫入的Flash內容並和下載的緩衝區比較
{
Frame_State=0x05; // 轉爲應答狀態
buffptr_old=buffptr; // 寫入正常才記錄數據指針
}
break;
case 0x05: // 正確應答ACK
{
packNO_old=packNO; // 接收完整一幀保留本次包號
Send_UART(XMODEM_ACK); // 認可應答
//WriteCom(packNO); // 測試
//WriteCom(FlashAddr); // 測試
//WriteCom(FlashAddr>>8); // 測試
Error_cnt = 0; // 清除連續錯誤計數
Frame_State=0x00; // 轉爲幀接收(請求)狀態
}
break;
case 0x06: // 錯誤=重發應答ANK
{
Send_UART(XMODEM_NAK); // 要求重發數據塊
Error_cnt++; // 連續錯誤計數
Frame_State=0x00; // 轉爲接收狀態
}
break;
default: // 升級完成退出處理
{
#if SafeUpdated_En
EEPROM_Write(EE_SafeAddr,0);// 寫升級成功標志 0
#endif
quit_boot(); //退出Bootloader
}
break;
} // switch End
if(Error_cnt>10) // 連續出錯10次退出升級(復位)
{
Send_UART(XMODEM_CAN); // 撤銷傳送(無條件停止)
#if SafeUpdated_En
EEPROM_Write(EE_SafeAddr,1);// 寫升級失敗標志 1
#endif
while(1); // 沒有升級完成重新開始
}
#if WDGEn
Watchdog_Reset(); // 喂狗
#endif
} // while end
//-------------------------------------------------//
} // main end
//-----------------------------------------------//
#include "AVR_boot.h" // 頭文件包含
//-----------------------------------------------//
//----------初始化-------------------------------//
// 輸出端口初始化
void PORT_Init()
{
// 上電默認全爲輸入口
// 輸出口設置
#if Run_LEDEn
DDRREG(LEDPORT)|=(1 << LEDPORTNo); // 指示燈
#endif
}
//-----------------------------------------------//
// 串口初始化
void UART_Init()
{
#if RS485_En
DDRREG(RS485PORT)|=(1 << RS485TXEn); // 設置(PC5)RS485方向控制引腳爲輸出
RX485DE_RX; // 默認爲接收
#endif
UCSRAREG(COMPORTNo) = 0x00;
UCSRBREG(COMPORTNo) = 0x18; // Enable Receiver and Transmitter
UCSRCREG(COMPORTNo) = 0x0E; // Set frame. format: 8data, 2stop bit
// 通信速率
UBRRHREG(COMPORTNo) = BAUD_H; // 0X00
UBRRLREG(COMPORTNo) = BAUD_L; // Set baud rate 16M 9600 0x0067
}
// 250ms定時器設置Time1
//-----------------------------------------------//
//使用定時器1:1024分頻,CTC模式4,產生以毫秒爲單位的時間
void Time1_Init()
{
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 16MHz
TCCR1A=0x00; // CTC4
TCCR1B=0x08; // CTC4
TCCR1B|=0x03; // clkI/O/64 ( 來自預分頻器) 16M=4us
OCR1A=T1_TCNT; // 250MS
}
//-----------------------------------------------//
// 看門狗初始化函數 2s
void WatchDog_Enable(void)
{
// Watchdog Timer initialization
// Watchdog Timer Prescaler: OSC/2048k
MCUCSR=0x00; // 控制與狀態寄存器
WDTCR=0x1F; // 看門狗使能 500ms(D)1.0S(E) 2.0S(F)
WDTCR=0x0F;
}
// 禁止看門狗
void WatchDog_Disenable(void) // 禁止看門狗
{
MCUCSR=0x00; // 控制與狀態寄存器
WDTCR=0b00011111; // 看門狗 使能位修改 使能(B4=1) 2.0S(F)
WDTCR=0b00000111; // 禁止看門狗 2.0S(7)
}
// 喂狗
void Watchdog_Reset(void)
{ #asm("wdr") } // 喂狗
//-----------------------------------------------//
//-------------子函數----------------------------//
//寫入數據到串口
void Send_UART(unsigned char dat)
{
uchar i;
#if RS485_En
RX485DE_TX; // 使能RS485發送
#endif
UDRREG(COMPORTNo) = dat; // UDR0
//等待數據發送完成
while(!(UCSRAREG(COMPORTNo) & 0x40)); // 等待數據發送完成 Bit 6 – TXC: USART 發送結束
UCSRAREG(COMPORTNo)|=0x40; // 清除發送完成狀態
#if RS485_En
RX485DE_RX; // 使能RS485接收
#endif
}
//-----------------------------------------------//
//等待串口數據(注意是”死等“)
unsigned char Wait_UART()
{
while(!(UCSRAREG(COMPORTNo) & 0x80)); // 等等數據到來 Bit 7 – RXC: USART 接收結束
UCSRAREG(COMPORTNo)|=0x80; // 清除接收完成狀態
#if Run_LEDEn
Run_LED; // 運行LED閃爍
#endif
return UDRREG(COMPORTNo);
}
//-----------------------------------------------//
//計算CRC
int CRC16_Word(char *ptr, int count)
{
int crc = 0;
char i;
while (--count >= 0)
{
crc = crc ^ (int) *ptr++ << 8;
i = 8;
do
{
if (crc & 0x8000)
crc = crc << 1 ^ 0x1021;
else
crc = crc << 1;
} while(--i);
}
return (crc);
}
//-----------------------------------------------//
//退出Bootloader程序,從0x0000處執行應用程序
void quit_boot(void)
{
MCUCR = 0x00; //當IVSEL 爲"0“ 時,中斷向量位於Flash 存儲器的起始地址;
#ifdef ATMEGA128
RAMPZ = 0x00; //0: ELPM/SPM 可以訪問程序存儲器地址$0000 - $7FFF ( 低64K 字節)
#endif
#asm("jmp 0x0000") //跳轉到Flash的0x0000處,執行用戶的應用程序
}
//-----------------------------------------------//
// 讀EEPROM一個字節
uchar EEPROM_Read(uint Addr) // EEPROM讀1個字節操作 0
{
while(EECR & 0x02); // 等待上一次寫操作結束
EEAR = Addr; // 設置地址寄存器
EECR |= 0x01; // 設置EERE 以啓動讀操作 b0
return(EEDR); // 自數據寄存器返回數據
}
// 寫EEPROM一個字節
void EEPROM_Write(uint Addr,char Data) // EEPROM 寫1個字節操作
{
EEAR = Addr; // 設置地址寄存器
EEDR = Data; // 設置數據寄存器
// #asm("cli") // EEMPE置1,EEPE1,這兩步操作中間不能超過4個時鍾周期
EECR |= 0x04; // 置位EEMWE b2
EECR |= 0x02; // 置位EEWE以啓動寫操作 b1
//#asm("sei")
}
//-----------------------------------------------//
//-------------------------------------------------------//
#ifndef _AVR_BOOT_H_
#define _AVR_BOOT_H_ 1
// 配置文件包含
#include "Config.h"
//------------------------------------------------------//
#ifdef ATMEGA32
#include <mega32.h>
#endif
#ifdef ATMEGA64
#include <mega64.h>
#endif
#ifdef ATMEGA128
#include <mega128.h>
#endif
//---------------------------------------------------//
typedef signed char schar;
typedef signed int sint;
typedef signed long slong;
typedef unsigned char uchar;
typedef unsigned int uint;
typedef unsigned long ulong;
//--------------------------------------------------//
// 函數申明
void UART_Init();
void PORT_Init();
void Time1_Init();
void Send_UART(unsigned char dat);
unsigned char Wait_UART();
unsigned char Wait1S_UART();
void WatchDog_Disenable(void);
void quit_boot(void);
int CRC16_Word(char *ptr, int count);
void write_one_page(uchar data[]);
void WatchDog_Enable(void);
void Watchdog_Reset(void);
uchar EEPROM_Read(uint Addr);
void EEPROM_Write(uint Addr,char Data);
//--------------------------------------------------//
//內部使用的宏定義
#define CONCAT(a, b) a ## b
#define CONCAT3(a, b, c) a ## b ## c
//端口以及位定義
#define PORTREG(No) CONCAT(PORT, No)
#define PINREG(No) CONCAT(PIN, No)
#define DDRREG(No) CONCAT(DDR, No)
#define UDRREG(No) CONCAT(UDR, No)
//串口初始化需要寄存器
#define UCSRAREG(No) CONCAT3(UCSR, No, A)
#define UCSRBREG(No) CONCAT3(UCSR, No, B)
#define UCSRCREG(No) CONCAT3(UCSR, No, C)
#define UBRRHREG(No) CONCAT3(UBRR, No, H)
#define UBRRLREG(No) CONCAT3(UBRR, No, L)
//---------------------------------------------------//
// 端口定義
#define RX485DE_RX PORTREG(RS485PORT)&=~(1 << RS485TXEn); // SCI接收使能
#define RX485DE_TX PORTREG(RS485PORT)|=(1 << RS485TXEn); // SCI發送使能
#define Run_LED PORTREG(LEDPORT)^= (1 << LEDPORTNo); // boot運行LED
//---------------------------------------------------//
//定義Xmoden控制字符
#define XMODEM_NUL 0x00 // null
#define XMODEM_SOH 0x01 // Xmodem數據頭
#define XMODEM_STX 0x02 // Xmodem_1K數據頭
#define XMODEM_EOT 0x04 // 發送結束
#define XMODEM_ACK 0x06 // 認可響應
#define XMODEM_NAK 0x15 // 不認可響應
#define XMODEM_CAN 0x18 // 撤銷傳送
#define XMODEM_EOF 0x1A // 填充數據包
#define XMODEM_RWC 'C' // CRC16-128
//-------------------------------------------------------//
#ifdef Xmodem_1K
#define BUFFER_SIZE 1024
#else // Xmodem
#define BUFFER_SIZE 128
#endif
//-----------------------------------------------------//
#ifdef ATMEGA32
#define SPM_PAGESIZE 128 // SPM 頁大小
#define BootStart 0x3C00*2 // 按字節
#define SPM_REG SPMCR // SPM寄存器
#endif
#ifdef ATMEGA64
#define SPM_PAGESIZE 256 // SPM 頁大小
#define BootStart 0x7C00*2 // 按字節
#define SPM_REG SPMCSR // SPM寄存器
#endif
#ifdef ATMEGA128
#define SPM_PAGESIZE 256 // SPM 頁大小
#define BootStart 0xFC00*2 // 按字節
#define SPM_REG SPMCSR // SPM寄存器
#endif
//接收緩衝區大小不能小於 SPM_PAGESIZE
#if BUFFER_SIZE < SPM_PAGESIZE
#define BUFSIZE SPM_PAGESIZE // UART數據緩存
#else
#define BUFSIZE BUFFER_SIZE // UART數據緩存
#endif
//計算和定義波特率設置參數
#define BAUD_SETTING (unsigned char)((unsigned long)CRYSTAL/(16*(unsigned long)BAUDRATE)-1)
#define BAUD_H ((unsigned char)(BAUD_SETTING>>8))
#define BAUD_L (unsigned char)BAUD_SETTING
//計算T1定時器設置參數
#define T1_TCNT (unsigned int)((unsigned long)CRYSTAL*250/(64 * 1000));
//--------------------------------------------------------//
#endif // _AVR_BOOT_H_
#ifndef _CONFIG_H_
#define _CONFIG_H_ 1
//*********************************************************//
// 關於上海霜蟬-AVR_bootV1.00
// 1、軟件版本V1.00 編譯環境CodeWizardAVR V2.03.9 Standard;
// 2、支持本公司常用的三種AVR芯片;
// 3、支持標準Xmodem和擴展Xmodem_1K協議;
// 4、聯機握手密碼爲"00",握手成功手的等待文件超時爲1分鍾;
// 5、默認復位等待3S退出boot到用戶程序或循環運行boot;
// 6、支持1分鍾以內的斷網續傳;
// 7、支持連續10幀以內數據錯誤的重傳;
// 8、支持下載過程中的取消超作;
// 9、支持當收到包時,接收過程中每個字符的超時間隔爲 1 秒;
// 10、支持所有的超時及錯誤事件至少重試 10 次;
// 11、支持數等待超時6S的請求;
// 12、Boot Loader - Size:1024words;
// 13、支持傳輸速度:38.400KB/S~2.400KB/S;
// 14、支持上海霜蟬常用最多的三個型號ATMEGA32,64,128。
// 15、支持開門狗自定義開關,自定義時鍾頻率
//*********************************************************//
// 注意:修改編譯器配置 (char to int;char is unsigned)
// 注意:填充數據必須大於兩包(>=256)
// 定義芯片型號
// 芯片型號選擇
//#define ATMEGA32
#define ATMEGA64 // 已測試Atmgea64L
//#define ATMEGA128
// 協議類型選擇:Xmodem或Xmodem_1K
#define Xmodem // Xmodex 128(CRC16)
//#define Xmodem_1K // Xmodem 1024(CRC16)
//-----------------------------------------------//
// 系統時鍾MHz
#ifndef CRYSTAL
#define CRYSTAL 16000000 // 16M
#endif
// 波特率 38400~2400
#define BAUDRATE 9600
// 等待密碼的超時時間 = WiteTimeCnt * 250ms
// 超時次數
#define WiteTimeCnt 10 // 10=2.5s
// 用戶設置boot駐留等待握手時間(1=250ms)+2.5S(WiteTimeCnt)
#define Wait_BootTime 40 // (1=250ms)+2.5S
// 等待文件的超時時間 = TimeOutCntC * 250ms
// 發送'C'的最大次數
#define TimeOutCntC 40 // 40=1min
// 串口號(ATMEA32 串口號爲空)
#define COMPORTNo 0 // UART0
// 看門狗使能
#define WDGEn 1 // 使用看門狗
// 使用485模式
#define RS485_En 1 // 使用485使能腳
// 485控制端口和引腳
#define RS485PORT E // PORTE
#define RS485TXEn 2 // PORTE2
// 使用LED指示狀態
#define Run_LEDEn 1 // 使能boot運行LED指示
// LED控制端口和引腳
#define LEDPORT B // PORTB
#define LEDPORTNo 6 // PORTB6
// 延時用於解決串口數據出錯
#define Delay_En 0
// 用戶設置boot駐留等待握手時間(1=250ms)+2.5S(WiteTimeCnt)
// 使此功能需要設置EEPROM
#define Wait_BootTime 40 // (40*250ms)+2.5S
#define EE_TimeAddr 0 // 使用EEPROM 佔用1個字節
// 安全升級(升級不成功不進入用戶區)
// 使此功能需要設置EEPROM
#define SafeUpdated_En 1
#define EE_SafeAddr 1 // 使用EEPROM 佔用1個字節
//-----------------------------------------------//
#endif // _CONFIG_H_
//End of file: bootcfg.h