📄 m128bls.c
字号:
/****************************************************
Project : Mega128 Bootloader
Version : 1.00
Date : 2005-12-23
Author : lq
Company : HX GCT
Comments: This program is from M128bls2 based on CVAVR.
Chip type : ATmega128L
Program type : Boot Loader - Size:4096words
Clock frequency : defined in "config.h"
Memory model : Small
External SRAM size : 0
Data Stack size : 1024
*****************************************************/
#include "config.h"
// data buffer
uint8_t gui8_data[DATA_BUFFER_SIZE];
uint8_t pw0[PWLENTH+1]="3452";
uint8_t pw1[PWLENTH+1]="2093";
/*****************************************************************************************
Function: getpassword
Description: 进入bootload必须检查密码
Calls: 无
Called By: main
Globel RD: rx_counter
Globel WR: 无
Input: 无
Output: 无
Return: 0-地址0,1-地址可选
Others: 无
Auther: Liu.Qian
Time: 2005-7-8
*****************************************************************************************/
uint8_t getpassword(void)
{
uint8_t i;
uint8_t pw[PWLENTH];
while(1)
{
putstrf("\r\nInput password:");
flush();
while(rx_counter)
{
Ugetchar();
}
for( i = 0 ; i < PWLENTH ; i++)
{
pw[i]=Ugetchar();
Uputchar('*');
}
for( i = 0 ; i < PWLENTH ; i++)
{
if(pw[i]!=pw0[i])
{
break;
}
}
putstrf("\r\n");
if(i==PWLENTH)
{
return(0);
}
for( i = 0 ; i < PWLENTH ; i++)
{
if(pw[i]!=pw1[i])
{
break;
}
}
if(i==PWLENTH)
{
return(1);
}
DelayMs(2000);
putstrf("!!!Invalid password!!!\r\n");
}
}
/*****************************************************************************************
Function: getpageadd
Description: 数据写入的起始页地址
Calls: 无
Called By: program
Globel RD: 无
Globel WR: 无
Input: 无
Output: 无
Return: 无
Others: 无
Auther: Liu.Qian
Time: 2005-12-15
*****************************************************************************************/
uint32_t getpageadd(void)
{
uint32_t addr=0;
uint8_t in;
uint8_t data;
uint8_t addrhex[5];
for(;;)
{
putstrf("\r\nInput start address(in HEX,default is 0x00000):0x");
in=0;
while(in<5)
{
data=Ugetchar();
if (data==KB_ENT)
{
break;
}
if ((data>='0')&&(data<='9'))//0-9
{
Uputchar(data);
data = data - '0';
}
else
{
if ((data>='a')&&(data<='f'))//a-f
{
data = data - 'a' + 10;
}
else
{
if ((data>='A')&&(data<='F'))//A-F
{
data = data - 'A' + 10;
}
else
{
continue;
}
}
Uputchar(data+'A'-10);
}
addrhex[in]=data;
in++;
} //end of while(in<5)
if(in==0)
{
putstrf("00000");
addr=0;
}
else
{
data=0;
for (;in>0;in--)
{
addr<<=4;
addr|=addrhex[data];
data++;
}
if((uint8_t)addr||(addr>=APP_SIZE))
{
putstrf("\r\nBad address");
continue;
}
}
Uputchar('\r');
Uputchar('\n');
return(addr);
} // end of for(;;)
}
/*****************************************************************************************
Function: cancel
Description: 发送CAN
Calls: 无
Called By: 无
Globel RD: 无
Globel WR: 无
Input: 无
Output: 无
Return: 无
Others: 无
Auther: Liu.Qian
Time: 2005-12-15
*****************************************************************************************/
void cancel(void)
{
uint8_t times;
for(times=0;times<16;times++)
{
Uputchar(XMODEM_CAN);
}
}
/*****************************************************************************************
Function: boot_program_page
Description: 页编程
Calls: 无
Called By: 无
Globel RD: 无
Globel WR: 无
Input: 无
Output: 无
Return: uint8_t
Others: 无
Auther: Liu.Qian
Time: 2005-12-15
*****************************************************************************************/
uint8_t boot_program_page (uint32_t page)
{
uint16_t i;
uint8_t sreg;
uint8_t retry;
uint16_t w;
uint16_t *buf;
for(retry=0; retry<3; retry++)
{
// Disable interrupts.
sreg = SREG;
cli();
eeprom_busy_wait ();
boot_page_erase (page);
boot_spm_busy_wait (); // Wait until the memory is erased.
buf = (uint16_t *)gui8_data;
for(i=0; i<SPM_PAGESIZE; i+=2)
{
// Set up little-endian word.
w = *buf++;
boot_page_fill (page + i, w);
}
boot_page_write (page); // Store buffer in flash page.
boot_spm_busy_wait(); // Wait until the memory is written.
// Reenable RWW-section again. We need this if we want to jump back
// to the application after bootloading.
boot_rww_enable ();
// Re-enable interrupts (if they were ever enabled).
SREG = sreg;
// verify
buf = (uint16_t *)gui8_data;
for(i=0; i<SPM_PAGESIZE; i+=2)
{
if(pgm_read_word_far(page + i)!=*buf++)
{
break;
}
}
if(i==SPM_PAGESIZE)
{
return(0);
}
}
return(1);
}
/*****************************************************************************************
Function: program
Description: program
Calls: 无
Called By: 无
Globel RD: 无
Globel WR: 无
Input: 无
Output: 无
Return: 无
Others: 无
Auther: Liu.Qian
Time: 2005-12-15
*****************************************************************************************/
void program(void)
{
uint32_t pageadd;
uint8_t i;
uint8_t addf;
uint8_t pack_no;
if(getpassword())
{
pageadd = getpageadd();
}
else
{
pageadd = 0;
}
wait_soh();
pack_no = 1;
addf = 0;
while(1)
{
i=get_pack(gui8_data+addf,pack_no);
if (addf)
{
if (pageadd >= APP_SIZE)
{
while(1)
{
cancel();
putstrf("\r\nApplication Flash Section(0x00000-0x1DFFF) is full!");
DelayMs(2000);
}
}
if(boot_program_page(pageadd))
{
while(1);
{
cancel();
putstrf("\r\nFlash write error!");
DelayMs(2000);
}
} // end of if(ProgramPage(pageadd)==0)
else
{
if(i==0)
{
return;
}
pageadd += SPM_PAGESIZE;
addf = 0;
} // end of if(ProgramPage(pageadd)==0)else
} // end of if(addf)
else
{
if (i==0)
{
return;
}
addf = 128;
}
Uputchar(XMODEM_ACK);
pack_no++;
} // end of while(1)
}
/*****************************************************************************************
Function: quit
Description: 退出Bootloader程序,从0x00000处执行应用程序
Calls: 无
Called By: 无
Globel RD: 无
Globel WR: 无
Input: 无
Output: 无
Return: 无
Others: 无
Auther: Liu.Qian
Time: 2005-7-8
*****************************************************************************************/
void quit(void)
{
putstrf("\r\nGo! 0x00000\r\n");
flush();
cli();
MCUCR = 0x01;
MCUCR = 0x00; //将中断向量表迁移到应用程序区头部
RAMPZ = 0x00; //RAMPZ清零初始化
asm volatile ("jmp 0"::); //跳转到Flash的0x00000处,执行用户的应用程序
}
/*****************************************************************************************
Function: cpuinit
Description: cpu初始化
Calls: main
Called By: 无
Globel RD: 无
Globel WR: 无
Input: 无
Output: 无
Return: 无
Others: 无
Auther: Liu.Qian
Time: 2005-7-8
*****************************************************************************************/
void cpuinit(void)
{
// Input/Output Ports initialization
PORTA=0x00;
DDRA=0x00;
PORTB=0x00;
DDRB=0x00;
PORTC=0x00;
DDRC=0x00;
PORTD=0x00;
DDRD=0x00;
PORTE=0x00;
DDRE=0x00;
PORTF=0x00;
DDRF=0x00;
PORTG=0x00;
DDRG=0x00;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=FFh
// OC0 output: Disconnected
ASSR=0x00;
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;
// Timer/Counter 3 initialization
// Clock source: System Clock
// Clock value: Timer 3 Stopped
// Mode: Normal top=FFFFh
// Noise Canceler: Off
// Input Capture on Falling Edge
// OC3A output: Discon.
// OC3B output: Discon.
// OC3C output: Discon.
// Timer 3 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
// Compare C Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
OCR1CH=0x00;
OCR1CL=0x00;
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
// Timer/Counter 3 initialization
// Clock source: System Clock
// Clock value: Timer 3 Stopped
// Mode: Normal top=FFFFh
// Noise Canceler: Off
// Input Capture on Falling Edge
// OC3A output: Discon.
// OC3B output: Discon.
// OC3C output: Discon.
// Timer 3 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
// Compare C Match Interrupt: Off
TCCR3A=0x00;
TCCR3B=0x00;
TCNT3H=0x00;
TCNT3L=0x00;
ICR3H=0x00;
ICR3L=0x00;
OCR3AH=0x00;
OCR3AL=0x00;
OCR3BH=0x00;
OCR3BL=0x00;
OCR3CH=0x00;
OCR3CL=0x00;
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
// INT3: Off
// INT4: Off
// INT5: Off
// INT6: Off
// INT7: Off
EICRA=0x00;
EICRB=0x00;
EIMSK=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;
ETIMSK=0x00;
#if defined UART0
UBRR0L = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);
UBRR0H = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1) >> 8;
UCSR0A = 0x00;
UCSR0C = 0x06;
UCSR0B = _BV(RXCIE)|_BV(TXCIE)|_BV(TXEN)|_BV(RXEN);
UBRR1L = 0;
UBRR1H = 0;
UCSR1A = 0;
UCSR1C = 0;
UCSR1B = 0;
#else
UBRR0L = 0;
UBRR0H = 0;
UCSR0A = 0;
UCSR0C = 0;
UCSR0B = 0;
UBRR1L = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);
UBRR1H = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1) >> 8;
UCSR1A = 0x00;
UCSR1C = 0x06;
UCSR1B = _BV(RXCIE)|_BV(TXCIE)|_BV(TXEN)|_BV(RXEN);
#endif
// SPI initialization
// SPI Type: Disable
SPCR=0x00;
SPSR=0x00;
// 2 Wire Bus initialization
// TWI disable
TWSR=0x00;
TWBR=0x00;
TWAR=0x00;
TWCR=0x00;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
// ADC initialization
// ADC disable
ADMUX=0;
ADCSRA=0;
}
/*****************************************************************************************
Function: main
Description: main
Auther: Liu.Qian
Time: 2005-7-8
*****************************************************************************************/
int16_t main(void)
{
uint8_t temp;
uint8_t esc_ct;
cpuinit();
MCUCR = 0x01;
MCUCR = 0x02; //将中断向量表迁移到Boot区头部
sei();
// boot
putstrf("\r\nMega128 bootloader 1.00. Built at ");
putstrf(__DATE__);
putstrf(", by WINAVR 20050214.");
putstrf("\r\n(c)Copyright 2001-2005 HX GCT Co., Ltd. All Rights Reserved.");
putstrf("\r\nAutoboot in 2 seconds. Triple <Esc> to abort...");
flush();
esc_ct=0;
for(temp=0;temp<20;temp++)
{
if(rx_counter)
{
if(Ugetchar()==KB_ESC)
{
esc_ct++;
if (esc_ct==3)
{
program();
putstrf("\r\nOver. Go to application after 3 seconds.");
DelayMs(3000);
break;
}
}
else
{
esc_ct=0;
}
}
DelayMs(100);
};
quit();
return(0);
}
// end of file
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -