xmodem.c
来自「使用JTAG口对AT91R40008芯片进行FLASH编程的程序」· C语言 代码 · 共 485 行 · 第 1/2 页
C
485 行
//*----------------------------------------------------------------------------
//* ATMEL Microcontroller Software Support - ROUSSET -
//*----------------------------------------------------------------------------
//* The software is delivered "AS IS" without warranty or condition of any
//* kind, either express, implied or statutory. This includes without
//* limitation any warranty or condition with respect to merchantability or
//* fitness for any particular purpose, or against the infringements of
//* intellectual property rights of others.
//*----------------------------------------------------------------------------
//* File Name : xmodem.c
//* Object : xmodem receive utility with PDC
//*
//* 1.0 14/11/00 JPP : Creation
//* without PDC 256K AT->PC PC->RAM
//* 38400 1'26 s 1'52
//* 115200 0'56 s 1'
//* 1.1 05/01/11 : Com light modification
//*----------------------------------------------------------------------------
//* ------------------------------ include file -------------------------------
#include "xmodem.h"
#include "drivers/com/com.h" //* Communication driver
//* ---------------------------- extern function ----------------------------
//* --------------------------- extern global data --------------------------
extern ComDesc *Xmodem_COM;
//* ----------------------------- Local variable -----------------------------
static int wait_time;
static XmodemFrame input_buff[1];
static volatile u_char buffer_status;
static volatile u_char recv_error;
static volatile u_char timed_out;
static u_char packet_number;
static volatile u_char eot_flag;
static char buffer_send[XMODEM_DATA_SIZE];
//* ------------------------------- Functions -------------------------------
//*----------------------------------------------------------------------------
//* Function Name : time_out
//* Object : Compute the CRC
//* Input Parameters : Global wait_time
//* Output Parameters : Global timed_out = TRUE
//*----------------------------------------------------------------------------
static void time_out(void)
{
wait_time--;
if (wait_time <= 0)
{
wait_time = 0;
timed_out= TRUE;
}
}
//*----------------------------------------------------------------------------
//* Function Name : init_usart
//* Object : init_usart_with PDC
//* Input Parameters : Global time_out
//* Output Parameters : Global timed_out = TRUE
//*----------------------------------------------------------------------------
static void init_usart(void)
{
//* Store the address of the buffer
Xmodem_COM->usart->usart_base->US_RPR = (u_int) input_buff ;
//* Store the number of bytes to receive
Xmodem_COM->usart->usart_base->US_RCR = 0x85 ; //sizeof(input_buff);
}
//*----------------------------------------------------------------------------
//* Function Name : get_usart
//* Object : Get char in usart
//* Input Parameters : none
//* Output Parameters : none
//*----------------------------------------------------------------------------
static void get_usart (void)
{
// check for recv_errors before reading data register
// Framing, over run or parity error
if ( at91_usart_get_status(Xmodem_COM->usart) & (US_OVRE | US_FRAME| US_PARE) )
{
recv_error = TRUE;
//* Reset Status Bits
at91_usart_trig_cmd( Xmodem_COM->usart,US_RSTSTA);
}
else
{
//* check end of transmission
if (input_buff[0].Header != SOH)
{
buffer_status = FULL;
eot_flag = TRUE;
}
//* check end of frame
//* if the recivied size at XMODEM_FRAME_SIZE the [0] is full
else if ( Xmodem_COM->usart->usart_base->US_RCR == 0 )
{
init_usart();
buffer_status = FULL;
}
}
}
//*----------------------------------------------------------------------------
//* Function Name : calcrc
//* Object : Compute the CRC
//* Input Parameters : <ptr> char pointer
//* <count> nb of char
//* Output Parameters : crc value
//*----------------------------------------------------------------------------
static u_short calcrc(u_char *ptr, int count)
{
u_short crc, cmpt;
crc = 0;
//* For all char
while (--count >= 0)
{
crc = crc ^ (int) *ptr++ << 8;
//* For All bit
for (cmpt = 0; cmpt < 8; cmpt++)
{
if (crc & 0x8000)
crc = crc << 1 ^ CRC16POLY;
else
crc = crc << 1;
}//* end bit
}//* Frame end
return (crc & 0xFFFF);
}
//*----------------------------------------------------------------------------
//* Function Name : recv_wait_frame
//* Object : wait data or time out
//* Input Parameters : <time> Wait time
//* Output Parameters : none
//*----------------------------------------------------------------------------
static void recv_wait_frame(int time)
{
buffer_status = EMPTY;
timed_out = FALSE; // set in timer counter 0 overflow interrupt routine
recv_error = FALSE; // framing and over run detection
wait_time = time;
// wait for packet or error
while (!buffer_status && !recv_error && !timed_out)
{
get_usart();
time_out();
}
}
//*----------------------------------------------------------------------------
//* Function Name : purge
//* Object : wait 1 second for sender to EMPTY its transmit buffer
//* Input Parameters : none
//* Output Parameters : none
//*----------------------------------------------------------------------------
static void purge(void)
{
wait_time =WAIT_3S;
init_usart();
while (!timed_out) // read uart until done
{
time_out();
}
//* stop pdc reception
Xmodem_COM->usart->usart_base->US_RCR = 0;
//* clear error
at91_usart_trig_cmd( Xmodem_COM->usart,US_RSTSTA);
}
//*----------------------------------------------------------------------------
//* Function Name : respond
//* Object : Compute the CRC
//* Input Parameters : <responce type>: TRUE send ACK FALSE send NAK
//* Output Parameters : none
//*----------------------------------------------------------------------------
static void respond(u_char status)
{
if (status)
{
at91_send_byte(Xmodem_COM,ACK);
}
else
{ // tell sender error
at91_send_byte(Xmodem_COM,NAK);
}
}
//*----------------------------------------------------------------------------
//* Function Name : validate_packet
//* Object : check the data frame
//* SOH | nr | ns | < 128 data > | check|sum |
//* data size = XMODEM_FRAME_SIZE 133
//* Input Parameters : <check_buf> end address buffer address
//* Output Parameters : none
//*----------------------------------------------------------------------------
static u_char validate_packet(XmodemFrame *check_buf)
{
u_short crc;
u_char status = NOK;
if (buffer_status && !recv_error)
{ // no framing, over run, or time out errors
if (check_buf->Header == SOH)
{ // valid start
if (check_buf->packet == ((packet_number+1) & 0xff))
{ // sequential block number ?
if ((check_buf->packet + check_buf->packet_crc) == 0xff)
{ // block number and block number checksum are ok
// compute CRC and validate it
crc = calcrc((u_char*)check_buf->data,XMODEM_DATA_SIZE);
if ( (check_buf->crc_lsb == (unsigned char)(crc >> 8)) &&
(check_buf->crc_msb == (unsigned char)(crc))
)
{
packet_number++;
status = OK;
}// if end CRC
}// block Checksum
}// sequential block
}// valid start
// check for the end
else if (check_buf->Header == EOT)
{// no start
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?