Files
MAX_CARLINK_A270S/A27-STEPLDR/Src/uart.c

762 lines
19 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <string.h>
#include "amt630h.h"
#include "typedef.h"
#include "uart.h"
#include "aic.h"
#include "update.h"
#include "spi.h"
#include "crc32.h"
#include "sysinfo.h"
#include "board.h"
#include "sysctl.h"
#include "sdmmc.h"
#define UART_CLK CLK_24MHZ
#define UART_ISR_PASS_LIMIT 1
static unsigned int ulUartBase[UART_NUM] = {REGS_UART0_BASE, REGS_UART1_BASE, REGS_UART2_BASE, REGS_UART3_BASE};
void InitUart(unsigned int baud)
{
unsigned int Baud_Rate_Divisor;
unsigned int val;
//select pad
val = rSYS_PAD_CTRL02;
val &= ~(0xF<<12);
val |=(0x1<<14)|(0x1<<12);
rSYS_PAD_CTRL02 = val;
Baud_Rate_Divisor = ((CLK_24MHZ<<3) + baud)/(baud<<1);
rUART_IBRD = Baud_Rate_Divisor >> 6;
rUART_FBRD = Baud_Rate_Divisor & 0x3f;
rUART_LCR_H = 0x70;//data len:8 bit,parity checking disable
rUART_IFLS = 0x19;
rUART_CR = 0x301;
}
static char HexToChar(unsigned char value)
{
value &= 0x0f;
if ( value < 10 )
return(0x30 + value);
else
return(0x60 + value - 9);
}
static void ShortToStr(unsigned short value, char *str)
{
str[0] = HexToChar(value >> 12);
str[1] = HexToChar((value >> 8) & 0x0f);
str[2] = HexToChar((value >> 4) & 0x0f);
str[3] = HexToChar(value & 0x0f);
str[4] = 0;
}
void IntToStr(unsigned int value, char *str)
{
ShortToStr(value >> 16, str);
ShortToStr(value & 0xffff, str + 4);
str[8] = 0;
}
void SendUartString(char * buf)
{
int i = 0;
while ( buf[i] != 0)
{
while ( !(rUART_FR & 0x20) )
{
rUART_DR = buf[i++];
if ( buf[i] == 0 )
return;
}
while ( (rUART_FR & 0x20));
}
}
void SendUartChar(char ch)
{
while ( (rUART_FR & 0x20) );
rUART_DR = ch;
}
void PrintVariableValueHex(char * variable, unsigned int value)
{
char buf[10];
SendUartString(variable);
SendUartString(": 0x");
IntToStr(value, buf);
SendUartString(buf);
SendUartString("\r\n");
}
void SendUartWord(unsigned int data)
{
char buf[10];
SendUartString("0x");
IntToStr(data, buf);
SendUartString(buf);
SendUartString("\r\n");
}
void uart_puts(const UINT8*buf)
{
INT32 i = 0;
while ( buf[i] != 0)
{
while( !(rUART_FR & 0x20) )
{
if ( buf[i] == '\n' )
{
rUART_DR = '\r';
while( (rUART_FR & 0x20) );
}
rUART_DR = buf[i++];
if ( buf[i] == 0 )
return;
}
while( (rUART_FR & 0x20) );
}
}
/* retarget printf function */
int putchar(int ch)
{
while (readl(REGS_UART0_BASE + UART_FR) & UART_FR_TXFF);
writel(ch, REGS_UART0_BASE + UART_DR);
return ch;
}
typedef enum {
UART_FRAME_START,
UART_FRAME_FILEINFO,
UART_FRAME_FILEXFER,
UART_FRAME_FINISH,
} eUartFrameType;
#define UUP_STATE_IDLE 0
#define UUP_STATE_START 1
#define UUP_STATE_END 2
#define UUP_ACK_OK 1
#define UUP_ACK_FAIL 0
#define UUP_MAX_FILE_SIZE 0x1000000
#define UUP_BUF_SIZE (BYTESPERPAGE * PAGESPERSECTORS)
#define UUP_PACKET_SIZE 128
#define UUP_MAX_FRAME_LEN (UUP_PACKET_SIZE + 16)
#define UUP_RX_FRAME_NUM 16
#define UUP_MAX_LOADER_SIZE STEPLDR_MAX_SIZE//0x10000
typedef struct {
int type;
unsigned char *buf;
unsigned int len;
int ack;
} UartFrame;
#pragma data_alignment=16
static unsigned char uup_rx_buf[UUP_RX_FRAME_NUM][UUP_MAX_FRAME_LEN];
static unsigned char *uup_rx_ptr;
static int uup_rx_rev_len = 0;
static int uup_rx_head = 0;
static int uup_rx_tail = 0;
static int uup_rx_state = 0;
static int uup_rx_data_len = 0;
static int uup_status = UUP_STATE_IDLE;
static int uup_file_type = 0;
static unsigned int uup_file_offset;
static int uup_file_size = 0;
static int uup_packet_num = 0;
static int uup_rev_packet = 0;
static int uup_rev_len = 0;
#pragma data_alignment=16
static unsigned char uup_buf[UUP_MAX_LOADER_SIZE];
static unsigned int uup_buf_len = 0;
static void uart_select_pad(int id)
{
switch (id) {
case UART_ID0:
vSysctlConfigure(SYS_PAD_CTRL02, 12, 0xf, 0x5);
break;
case UART_ID1:
vSysctlConfigure(SYS_PAD_CTRL02, 16, 0xf, 0x5);
break;
case UART_ID2:
vSysctlConfigure(SYS_PAD_CTRL02, 20, 0xf, 0x5);
break;
case UART_ID3:
vSysctlConfigure(SYS_PAD_CTRL02, 24, 0xf, 0x5);
break;
}
}
void uart_init(int id, unsigned int baud, unsigned int flags)
{
unsigned int lcr_h, quot, cr;
unsigned int regbase;
int count = 0;
//uart_select_pad(id);
regbase = ulUartBase[id];
if (id == UART_ID0 || id == UART_ID2) {
if (baud > UART_CLK / 16)
quot = (UART_CLK * 8 + baud / 2) / baud;
else
quot = (UART_CLK * 4 + baud / 2) / baud;
switch (flags & CSIZE) {
case CS5:
lcr_h = UART_LCRH_WLEN_5;
break;
case CS6:
lcr_h = UART_LCRH_WLEN_6;
break;
case CS7:
lcr_h = UART_LCRH_WLEN_7;
break;
default: // CS8
lcr_h = UART_LCRH_WLEN_8;
break;
}
if (flags & CSTOPB)
lcr_h |= UART_LCRH_STP2;
if (flags & PARENB) {
lcr_h |= UART_LCRH_PEN;
if (!(flags & PARODD))
lcr_h |= UART_LCRH_EPS;
if (flags & CMSPAR)
lcr_h |= UART_LCRH_SPS;
}
lcr_h |= UART_LCRH_FEN;
/* Provoke TX FIFO interrupt into asserting */
cr = UART_CR_UARTEN | UART_CR_TXE | UART_CR_LBE;
reconfig:
writel(cr, regbase + UART_CR);
writel(0, regbase + UART_FBRD);
writel(1, regbase + UART_IBRD);
writel(0, regbase + UART_LCRH);
writel(0, regbase + UART_DR);
while (readl(regbase + UART_FR) & UART_FR_BUSY);
if (count++ < 10 && !(readl(regbase + UART_RIS) & UART_TXIS)) {
SendUartString("ERROR! Uart status wrong.\n");
goto reconfig;
}
/* first, disable everything */
writel(0, regbase + UART_CR);
cr = UART_CR_RXE | UART_CR_TXE;
if (flags & CRTSCTS)
cr |= UART_CR_CTSEN | UART_CR_RTSEN;
/* Set baud rate */
writel(quot & 0x3f, regbase + UART_FBRD);
writel(quot >> 6, regbase + UART_IBRD);
writel(UART_RTIM | UART_RXIM, regbase + UART_IMSC);
writel(UART_IFLS_RX4_8 | UART_IFLS_TX4_8, regbase + UART_IFLS);
writel(lcr_h, regbase + UART_LCRH);
writel(cr | UART_CR_UARTEN, regbase + UART_CR);
} else {
//set modem
writel(0, regbase + UART485_MCR);
// baud = clk/(16*U_DLL)
//set baud rate
writel(readl(regbase + UART485_LCR) | (1 << 7), regbase + UART485_LCR);
writel(UART_CLK / (16 * baud), regbase + UART485_DLL);
writel(0, regbase + UART485_DLH);
//Set fractional baud rate
//Fractional baud divisor = ((uart_clk%(16*baud))/(16*baud)) * 16 = (uart_clk%(16*baud)) * 16 / (16*baud);
writel((UART_CLK % (16*baud)) * 16 / (16*baud), regbase + UART485_DLF);
writel(readl(regbase + UART485_LCR) & ~(1 << 7), regbase + UART485_LCR);
cr = readl(regbase + UART485_LCR);
//校验
cr &= ~(7 << 3);
if (flags & PARENB) {
cr |= (1 << 3);
if (!(flags & PARODD))
cr |= (1 << 4);
if (flags & CMSPAR)
cr |= (1 << 5);
}
//停止位
if (flags & CSTOPB)
cr |= (1 << 2);
else
cr &= ~(1 << 2);
//数据位
cr &= ~(3 << 0);
switch (flags & CSIZE) {
case CS5:
break;
case CS6:
cr |= 1;
break;
case CS7:
cr |= 2;
break;
default: // CS8
cr |= 3;
break;
}
writel(cr, regbase + UART485_LCR);
//set fifo
writel((2 << 6) | (3 << 4) | 7, regbase + UART485_FCR);
//enable rx and err interrupt
writel((1 << 4) | 1, regbase + UART485_IER);
//设置通信模式全双工还是半双工
//485mode disable
writel(0, regbase + UART485_TCR);
}
uart_select_pad(id);
}
static int uart_rx_chars(int id)
{
unsigned int regbase = ulUartBase[id];
unsigned int status;
unsigned int ch, max_count = 256;
int fifotaken = 0;
while (max_count--) {
if (id == UART_ID0 || id == UART_ID2) {
status = readl(regbase + UART_FR);
if (status & UART_FR_RXFE)
break;
/* Take chars from the FIFO and update status */
ch = readl(regbase + UART_DR);
} else {
status = readl(regbase + UART485_LSR);
if (!(status & UART485_LSR_DR))
break;
/* Take chars from the FIFO and update status */
ch = readl(regbase + UART485_RBR);
}
fifotaken++;
switch (uup_rx_state) {
case 0:
if (ch == 0x55) {
uup_rx_state++;
uup_rx_rev_len = 0;
uup_rx_ptr = &uup_rx_buf[uup_rx_head][0];
}
break;
case 1:
if (ch == 0x81)
uup_rx_state++;
else
uup_rx_state = 0;
*uup_rx_ptr++ = ch;
break;
case 2:
if (ch == 0xc6)
uup_rx_state++;
else
uup_rx_state = 0;
*uup_rx_ptr++ = ch;
break;
case 3:
uup_rx_data_len = ch;
if (uup_rx_data_len <= 0 || uup_rx_data_len > UUP_PACKET_SIZE + 2) {
SendUartString("Invalid uart frame len.\n");
uup_rx_state = 0;
} else {
uup_rx_state++;
*uup_rx_ptr++ = ch;
}
break;
case 4:
*uup_rx_ptr++ = ch;
if (++uup_rx_rev_len == uup_rx_data_len)
uup_rx_state++;
break;
case 5:
*uup_rx_ptr++ = ch;
uup_rx_head = (uup_rx_head + 1) % UUP_RX_FRAME_NUM;
uup_rx_state = 0;
break;
}
/* discard when rx buf is full */
}
return fifotaken;
}
void uart_tx_chars(int id, unsigned char *buf, int len)
{
unsigned int regbase = ulUartBase[id];
int i;
for (i = 0; i < len; i++) {
if (id == UART_ID0 || id == UART_ID2) {
while (readl(regbase + UART_FR) & UART_FR_TXFF);
writel(buf[i], regbase + UART_DR);
} else {
while (!(readl(regbase + UART485_LSR) & UART485_LSR_TEMT));
writel(buf[i], regbase + UART485_THR);
}
}
}
void uart_update_int_handler(void *param)
{
int id = (int)param;
unsigned int regbase = ulUartBase[id];
unsigned int status;
unsigned int imsc;
uint32_t pass_counter = UART_ISR_PASS_LIMIT;
imsc = readl(regbase + UART_IMSC);
status = readl(regbase + UART_RIS) & imsc;
if (status) {
do {
writel(status & ~(/*UART_TXIS | */UART_RTIS | UART_RXIS),
regbase + UART_ICR);
if (status & (UART_RTIS | UART_RXIS)) {
uart_rx_chars(id);
}
/* if (status & UART_TXIS)
xUartTxChars(uap, pdTRUE); */
if (pass_counter-- == 0)
break;
status = readl(regbase + UART_RIS) & imsc;
} while (status != 0);
}
}
void uart485_update_int_handler(void *param)
{
int id = (int)param;
unsigned int regbase = ulUartBase[id];
uint32_t iir;
iir = readl(regbase + UART485_IIR);
switch (iir & UART485_IIR_IID_MASK) {
case UART485_IIR_IID_REV_DATA_AVAIL:
case UART485_IIR_IID_REV_LINE_STATUS:
case UART485_IIR_IID_CHAR_TIMEOUT:
uart_rx_chars(id);
}
}
static void uart_send_ack(int type, int ret)
{
unsigned char buf[7] = {0x55, 0x80, 0xc5, 0x02, 0x00, 0x00, 0x00};
int i;
buf[4] = type;
buf[5] = ret;
for (i = 1; i < 6; i++)
buf[6] ^= buf[i];
uart_tx_chars(UART_MCU_PORT, buf, 7);
}
static int uart_rev_frame(UartFrame *frame)
{
unsigned char *buf;
int len;
unsigned char checksum = 0;
int i;
if (uup_rx_tail == uup_rx_head) {
return 0;
}
buf = &uup_rx_buf[uup_rx_tail][0];
uup_rx_tail = (uup_rx_tail + 1) % UUP_RX_FRAME_NUM;
len = buf[2];
for (i = 0; i < len + 3; i++)
checksum ^= buf[i];
if (checksum == buf[len + 3]) {
frame->buf = &buf[4];
frame->len = len - 1;
frame->type = buf[3];
} else {
SendUartString("rev frame checksum err.\n");
/* for (int i = 0; i < len + 4; i++) {
if (i && i % 16 == 0)
printf("\n");
printf("%.2x, ", buf[i]);
}
printf("\n0x%x, 0x%x.\n", checksum, buf[len + 3]); */
uart_send_ack(buf[3], UUP_ACK_FAIL);
return 0;
}
return 1;
}
void updateFromUart(int id)
{
UartFrame rx_frame;
unsigned char *buf;
unsigned int checksum = 0, calc_checksum = 0xffffffff;
unsigned int framelen;
unsigned int packetnum;
SysInfo *sysinfo = GetSysInfo();
uart_init(id, 115200, 0);
if (id == UART_ID0 || id == UART_ID2)
request_irq(UART0_IRQn + id, 0, uart_update_int_handler, (void*)id);
else
request_irq(UART0_IRQn + id, 0, uart485_update_int_handler, (void*)id);
do {
if (!uart_rev_frame(&rx_frame))
continue;
switch (rx_frame.type) {
case UART_FRAME_START:
uart_send_ack(rx_frame.type, UUP_ACK_OK);
uup_status = UUP_STATE_START;
update_logo_init();
break;
case UART_FRAME_FILEINFO:
if (uup_status != UUP_STATE_START)
break;
buf = rx_frame.buf;
uup_file_type = buf[0];
if (uup_file_type > UPFILE_TYPE_STEPLDR) {
PrintVariableValueHex("Rev wrong file type", uup_file_type);
uart_send_ack(rx_frame.type, UUP_ACK_FAIL);
break;
}
#if DEVICE_TYPE_SELECT != EMMC_FLASH
uup_file_offset = SpiGetUpfileOffset(uup_file_type);
#else
uup_file_offset = EmmcGetUpfileOffset(uup_file_type);
#endif
if (uup_file_offset == 0xffffffff) {
uart_send_ack(rx_frame.type, UUP_ACK_FAIL);
break;
}
uup_packet_num = (buf[1] << 16) | (buf[2] << 8) | buf[3];
uup_file_size = UUP_PACKET_SIZE * uup_packet_num;
if (uup_file_size > UUP_MAX_FILE_SIZE - uup_file_offset) {
SendUartString("Rev wrong file size.\n");
uart_send_ack(rx_frame.type, UUP_ACK_FAIL);
break;
}
uart_send_ack(rx_frame.type, UUP_ACK_OK);
break;
case UART_FRAME_FILEXFER:
if (uup_status != UUP_STATE_START)
break;
buf = rx_frame.buf;
packetnum = buf[0];
PrintVariableValueHex("uup_rev_packet", uup_rev_packet);
if ((uup_rev_packet & 0xff) != packetnum) {
SendUartString("Wrong packet number.\n");
uart_send_ack(rx_frame.type, UUP_ACK_FAIL);
break;
}
if (uup_rev_packet == 0) {
if (uup_file_type == UPFILE_TYPE_WHOLE) {
UpFileHeader *header = (UpFileHeader *)&buf[1];
if (header->magic != MKTAG('U', 'P', 'D', 'F')) {
SendUartString("Wrong whole file magic.\n");
uart_send_ack(rx_frame.type, UUP_ACK_FAIL);
break;
}
checksum = header->checksum;
sysinfo->app_size = header->files[0].size;
PrintVariableValueHex("sysinfo->appsize ", sysinfo->app_size);
} else if (uup_file_type == UPFILE_TYPE_RESOURCE) {
RomHeader *header = (RomHeader *)&buf[1];
if (header->magic != MKTAG('R', 'O', 'M', 'A')) {
SendUartString("Wrong resource file magic.\n");
uart_send_ack(rx_frame.type, UUP_ACK_FAIL);
break;
}
checksum = header->checksum;
} else if (uup_file_type == UPFILE_TYPE_ANIMATION) {
BANIHEADER *header = (BANIHEADER *)&buf[1];
if (header->magic != MKTAG('B', 'A', 'N', 'I')) {
SendUartString("Wrong animation file magic.\n");
uart_send_ack(rx_frame.type, UUP_ACK_FAIL);
break;
}
checksum = header->checksum;
} else if (uup_file_type == UPFILE_TYPE_APP) {
unsigned int magic = buf[1] | (buf[2] << 8) | (buf[3] << 16) | (buf[4] << 24);
if (magic != UPFILE_APP_MAGIC) {
SendUartString("Wrong app file magic.\n");
uart_send_ack(rx_frame.type, UUP_ACK_FAIL);
break;
}
unsigned char *tmp = buf + 1 + APPLDR_CHECKSUM_OFFSET;
checksum = tmp[0] | (tmp[1] <<8) | (tmp[2] << 16) | (tmp[3] << 24);
}
}
framelen = rx_frame.len - 1;
/* only last frame size is less than UUP_PACKET_SIZE */
if (framelen > UUP_PACKET_SIZE ||
(framelen < UUP_PACKET_SIZE && uup_rev_packet != uup_packet_num - 1)) {
SendUartString("Wrong packet len.\n");
uart_send_ack(rx_frame.type, UUP_ACK_FAIL);
break;
}
memcpy(uup_buf + uup_buf_len, buf + 1, framelen);
uup_buf_len += framelen;
if (uup_buf_len > UUP_MAX_LOADER_SIZE) {
SendUartString("loader file is too large.\n");
uart_send_ack(rx_frame.type, UUP_ACK_FAIL);
break;
}
uup_rev_packet++;
//loader程序如果升级错误会导致系统起不来并且不能再继续升级因此需要
//等数据校验成功后再烧录(loader程序通常并不需要升级)
if (uup_file_type < UPFILE_TYPE_FIRSTLDR && uup_buf_len == UUP_BUF_SIZE) {
#if DEVICE_TYPE_SELECT != EMMC_FLASH
if(!FlashBurn(uup_buf, uup_file_offset, UUP_BUF_SIZE, 0))
#else
if(!EmmcBurn(uup_buf, uup_file_offset, UUP_BUF_SIZE, 0))
#endif
{
uart_send_ack(rx_frame.type, UUP_ACK_OK);
} else {
SendUartString("Burn failed.\n");
uart_send_ack(rx_frame.type, UUP_ACK_FAIL);
break;
}
//文件起始部分需要先将头信息里的checksum清0来计算checksum
if (uup_rev_packet == UUP_BUF_SIZE / UUP_PACKET_SIZE) {
if (uup_file_type == UPFILE_TYPE_WHOLE) {
UpFileHeader *pheader = (UpFileHeader *)uup_buf;
pheader->checksum = 0;
} else if (uup_file_type == UPFILE_TYPE_RESOURCE) {
RomHeader *pheader = (RomHeader *)uup_buf;
pheader->checksum = 0;
} else if (uup_file_type == UPFILE_TYPE_ANIMATION) {
BANIHEADER *pheader = (BANIHEADER *)uup_buf;
pheader->checksum = 0;
} else if (uup_file_type == UPFILE_TYPE_APP) {
unsigned int *tmp = (unsigned int *)(uup_buf + APPLDR_CHECKSUM_OFFSET);
*tmp = 0;
}
}
calc_checksum = xcrc32(uup_buf, UUP_BUF_SIZE, calc_checksum);
uup_buf_len = 0;
uup_file_offset += UUP_BUF_SIZE;
uup_rev_len += UUP_BUF_SIZE;
update_progress_set(uup_rev_len * 100 / uup_file_size);
} else {
uart_send_ack(rx_frame.type, UUP_ACK_OK);
}
break;
case UART_FRAME_FINISH:
buf = rx_frame.buf;
if (!buf[0]) {
SendUartString("update end with error!\n");
uart_send_ack(rx_frame.type, UUP_ACK_FAIL);
uup_status = UUP_STATE_END;
break;
}
if (uup_file_type < UPFILE_TYPE_FIRSTLDR) {
if (uup_buf_len) {
#if DEVICE_TYPE_SELECT != EMMC_FLASH
if(FlashBurn(uup_buf, uup_file_offset, uup_buf_len, 0))
#else
if(EmmcBurn(uup_buf, uup_file_offset, uup_buf_len, 0))
#endif
{
SendUartString("update fail with burn failed.!\n");
calc_checksum = 0xFFFFFFFF;
} else {
//如果升级文件小于UUP_BUF_SIZE此时收到的是文件起始部分
if (uup_rev_packet < UUP_BUF_SIZE / UUP_PACKET_SIZE) {
if (uup_file_type == UPFILE_TYPE_WHOLE) {
UpFileHeader *pheader = (UpFileHeader *)uup_buf;
pheader->checksum = 0;
} else if (uup_file_type == UPFILE_TYPE_RESOURCE) {
RomHeader *pheader = (RomHeader *)uup_buf;
pheader->checksum = 0;
} else if (uup_file_type == UPFILE_TYPE_ANIMATION) {
BANIHEADER *pheader = (BANIHEADER *)uup_buf;
pheader->checksum = 0;
} else if (uup_file_type == UPFILE_TYPE_APP) {
unsigned int *checksum = (unsigned int *)(uup_buf + APPLDR_CHECKSUM_OFFSET);
*checksum = 0;
}
}
calc_checksum = xcrc32(uup_buf, uup_buf_len, calc_checksum);
}
}
if (calc_checksum == checksum) {
SendUartString("update finish!\n");
update_progress_set(100);
if (uup_file_type == UPFILE_TYPE_APP)
sysinfo->app_size = uup_file_size;
sysinfo->update_status = UPDATE_STATUS_END;
SaveSysInfo(sysinfo);
uart_send_ack(rx_frame.type, UUP_ACK_OK);
} else {
SendUartString("update checksum fail!\n");
uart_send_ack(rx_frame.type, UUP_ACK_FAIL);
}
} else {
unsigned int *tmp = (unsigned int *)(uup_buf + APPLDR_CHECKSUM_OFFSET);
checksum = *tmp;
*tmp = 0;
calc_checksum = xcrc32(uup_buf, uup_buf_len, calc_checksum);
if (calc_checksum == checksum) {
#if DEVICE_TYPE_SELECT != EMMC_FLASH
if (!FlashBurn(uup_buf, uup_file_offset, uup_buf_len, 1))
#else
if (!EmmcBurn(uup_buf, uup_file_offset, uup_buf_len, 1))
#endif
{
if (uup_file_type == UPFILE_TYPE_STEPLDR)
sysinfo->stepldr_size = uup_buf_len;
sysinfo->update_status = UPDATE_STATUS_END;
SaveSysInfo(sysinfo);
uart_send_ack(rx_frame.type, UUP_ACK_OK);
} else {
SendUartString("burn loader fail!\n");
uart_send_ack(rx_frame.type, UUP_ACK_FAIL);
}
} else {
SendUartString("update checksum fail!\n");
uart_send_ack(rx_frame.type, UUP_ACK_FAIL);
}
}
uup_status = UUP_STATE_END;
break;
}
} while (uup_status != UUP_STATE_END);
}