📄 uart.c
字号:
/*
*********************************************************************************************************
* Atmega128
* UART
*
*
* File : UART.C
* Version : V0.01
* Data: March 20, 2007
*********************************************************************************************************
*/
#include "bootloader.h"
char Slip_inbuf[SLIP_BUFFER_SIZE];
char LedT;
/*
*********************************************************************************************************
* UART_putc
*
* Description :
* Arguments :
* Returned Values : none
* Note(s)/Warnings :
*********************************************************************************************************
*/
void UART_putc(BYTE c)
{
while ( !(UCSR0A & (1<<UDRE0)));
UDR0 = c;
}
/*
*********************************************************************************************************
* UART_getc
*
* Description :
* Arguments :
* Returned Values : none
* Note(s)/Warnings :
*********************************************************************************************************
*/
char UART_getc(void)
{
while(1){
if(UCSR0A & (1<<RXC0)) return 1; //if(UCSR0A & (1<<UDRE0)) return 1;
if(Wait && (TIMER_OVERFLOW)){
TIMER_CLEAR;
if(--Wait == 0) return 0;
}
}
}
/*
*********************************************************************************************************
* Slip_unpackage
*
* Description :
* Arguments :
* Returned Values :
* Note(s)/Warnings :
*********************************************************************************************************
*/
char Sumcheck(LENGTH_TYPE num)
{
char *p = Slip_inbuf;
char sum = 0;
while(num--)
sum += *p++;
return ~sum;
}
char Slip_unpackage(void)
{
int tmp;
char cmd;
char *p;
unsigned int addr;
LENGTH_TYPE num;
LENGTH_TYPE i;
LENGTH_TYPE length;
#ifdef EN_EXROM
char highaddr;
#endif
#ifdef EN_ERROR
char Err0;
char Err1;
#endif
Led(LedT = ~LedT);
length = 0;
p = Slip_inbuf;
while(1) {
if(UART_getc() == 0) return 0;
cmd = UDR0;
if(cmd == SLIP_END){
if(length) break;
else continue;
}else if(cmd == SLIP_ESC){
if(UART_getc() == 0) return 0;
cmd = UDR0;
if(cmd == SLIP_ESC_END) {cmd = SLIP_END;}
else if(cmd == SLIP_ESC_ESC){cmd = SLIP_ESC;}
else {return 0;}
}
if(length <= SLIP_BUFFER_SIZE) {
*p++ = cmd;
length++;
}else {
return 0;
}
}
if(Sumcheck(length)){
#ifdef EN_ERROR
Err0 = SLIP_ER_SUMCHECK;
#endif
goto Error;
}
p = Slip_inbuf + 1;
cmd = *p++;
addr = *p++;
addr += (*p++)<<8;
#ifdef EN_PAMPZ
RAMPZ = *p++;
#endif
num = *p++;
#if (FLASH_PAGE_WIDTH == 2)
num += (*p++)<<8;
#endif
#ifdef EN_EXROM
highaddr = (Slip_inbuf[SLIP_PKG_ADDR+1]>>4) + (Slip_inbuf[SLIP_PKG_ADDR+2] <<4);
Flash_Sector_Set(highaddr);
if(cmd == SLIP_W_EXROM){
addr &= 0x0fff;
Flash_Write_String(addr, p, num);
length = 2 + FLASH_ADDRESS_WIDTH + FLASH_PAGE_WIDTH + 1;
}else if(cmd == SLIP_R_EXROM){
addr &= 0x0fff;
Flash_Read_String(addr, p, num);
length += num;
}else if(cmd == SLIP_E_EXROM){
addr &= 0x0fff;
Flash_Erase_Sector(highaddr);
length = 2 + FLASH_ADDRESS_WIDTH + FLASH_PAGE_WIDTH + 1;
}else if(cmd == SLIP_R_EXROMID){
Flash_Read_ID(p);
length += num;
}else if(cmd == SLIP_START){
#else
if(cmd == SLIP_START){
#endif
Slip_inbuf[SLIP_PKG_CTRL0] = BOOT_CTRL0;
Slip_inbuf[SLIP_PKG_CTRL1] = BOOT_CTRL1;
#ifdef EN_EXPAND
Slip_inbuf[SLIP_PKG_EXCTRL0] = BOOT_EXCTRL0;
Slip_inbuf[SLIP_PKG_EXCTRL1] = BOOT_EXCTRL1;
length = 6+1;
#else
length = 4+1;
#endif
}else if(cmd == SLIP_FINISH){
Goto_app();
}else if(cmd == SLIP_BAUD){
length = 2+1;
}else if(cmd <= 0x03){ // write package
if(cmd == SLIP_W_FLASH){
Spm_page_erase(addr); // erase one page
for(i=0 ; i<num; i+=2){ // write data to flash buffer
tmp = *p++;
tmp += *p++ <<8;
Spm_page_fill(i, tmp);
}
Spm_page_write(addr); // write flash buffer to flash
#ifdef VERIFY_FLASH
while(i--){
if(Read_flash(addr + i) != *p--){
#ifdef ERROR_INFO
Err0 = SLIP_ER_VERIFY;
#endif
goto Error;
}
}
#endif
}else{
for(i=0; i<num; i++){
if(cmd == SLIP_W_EEPROM) { // write eeprom
#ifdef VERIFY_EEPROM //-------------------
EEPPUT(addr+i, *p);
if(EEPGET((addr+i) != *p++){
#ifdef EN_ERROR
Err0 = SLIP_ER_VERIFY;
#endif
goto Error;
}
#else //-------------------
EEPPUT(addr+i, *p++);
#endif
}else { // write fuse
Spm_fuse_write(i, *p++);
}
}
}
length = 2 + FLASH_ADDRESS_WIDTH + FLASH_PAGE_WIDTH + 1;
}else{ // read and unknow packages
for(i=0; i<num; i++){
if(cmd == SLIP_R_FLASH) *p++ = Read_flash(addr+i); // read flash
else if( cmd == SLIP_R_EEPROM) *p++ = EEPGET(addr+i); // read eeprom
else if (cmd == SLIP_R_FUSE) *p++ = Read_fuse(addr+i); // read fuse
else { // unknow package
#ifdef EN_ERROR
Err0 = SLIP_ER_UNKNOWPKG;
#endif
goto Error;
}
}
length += num;
}
#ifdef ALWAYS_CHECK_LINK
Wait = BOOT_WAIT;
#endif
if(length > (SPM_PAGESIZE+8 ))
goto Error; //?????
Slip_package(SLIP_ACK|cmd, length-1);
return 1;
Error:
#ifdef EN_ERROR
Slip_inbuf[SLIP_PKG_CTRL0] = Err0;
Slip_inbuf[SLIP_PKG_CTRL1] = Err1;
Slip_package(SLIP_ACK|SLIP_ERROR,4);
#else
Slip_package(SLIP_ACK|SLIP_ERROR,2);
#endif
return 0;
}
/*
*********************************************************************************************************
* Slip_package
*
* Description :
* Arguments :
* Returned Values :
* Note(s)/Warnings :
*********************************************************************************************************
*/
void Slip_package(char cmd, LENGTH_TYPE len)
{
char *p = Slip_inbuf;
Slip_inbuf[SLIP_PKG_CMD] = cmd;
Slip_inbuf[len] = Sumcheck(len);
len++;
UART_putc(SLIP_END);
while(len--) {
if(*p == SLIP_END){
UART_putc(SLIP_ESC);
UART_putc(SLIP_ESC_END);
}else if(*p == SLIP_ESC){
UART_putc(SLIP_ESC);
UART_putc(SLIP_ESC_ESC);
}else{
UART_putc(*p);
}
p++;
}
UART_putc(SLIP_END);
while ( !(UCSR0A & (1<<UDRE0)));
#ifdef EN_BAUD_CHANGE
if(cmd == (SLIP_ACK | SLIP_BAUD)){ // baud change
#ifdef USE_UBRR0H
UBRR0H = HIGH(BAUD_HIGH);
#endif
UBRR0L = LOW(BAUD_HIGH);
}
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -