xmodem协议 文件接收发送

 作业:PC机发送file1到板子的内存,然后发回该文件到PC机的file2,查看两文件是否相同。
*/

#include "at91rm9200.h"
//
#define XMODEM_SOH 0x01
#define XMODEM_STX 0x02
#define XMODEM_EOT 0x04
#define XMODEM_ACK 0x06
#define XMODEM_NAK 0x15
#define XMODEM_ESC 0x1b
#define XMODEM_CAN 0x18
#define XMODEM_CRC 'C'
//
unsigned char filebuf[ 4 * 8 * 128 ];         //Max size of file, 4KB
unsigned char *fileEnd = filebuf;
static const unsigned short CRC16TAB[ 256 ] =
{
0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7,
0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef,
0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6,
0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de,
0x2462,0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485,
0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d,
0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4,
0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc,
0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823,
0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92b,
0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12,
0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a,
0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41,
0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49,
0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70,
0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78,
0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f,
0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067,
0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e,
0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256,
0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50d,
0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405,
0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c,
0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634,
0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9ab,
0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3,
0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a,
0x4a75,0x5a54,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92,
0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9,
0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1,
0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8,
0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0
};

//
void init_DMA_DBGU( void )
{
    /*Using peripheral DBGU*/
    AT91C_BASE_SYS -> PIOA_PDR = 0xc0000000;
    AT91C_BASE_SYS -> PIOA_ASR = 0xc0000000;
    AT91C_BASE_SYS -> DBGU_BRGR = 0x78;       //9600 at 32.768KHz
    AT91C_BASE_SYS -> DBGU_MR = 0x800;        //No parity
    AT91C_BASE_SYS -> DBGU_CR = 0x10c;        //RSTSTA | RSTTX | RSTRX
    AT91C_BASE_SYS -> DBGU_CR = 0x050;        //TXEN | RXEN
    AT91C_BASE_SYS -> DBGU_PTCR = 0x101;      //TXTEN | RXTEN
}

void sentByte( unsigned char byte )
{
    while( ( AT91C_BASE_SYS -> DBGU_CSR & 0x02 ) == 0 );
    AT91C_BASE_SYS -> DBGU_THR = byte;
}

unsigned short get_CRC16( unsigned char *xbuff, int len )
{
    register int i;
    register unsigned short CRC = 0x00;
    for( i = 0; i < len; i++ )
    {
        CRC = ( CRC << 8 ) ^ CRC16TAB[( ( CRC >> 8 ) ^ *xbuff++ ) & 0xff ];
    }
    return CRC;
}

int xmodem_recv( void )
{   
    int i;
    int error;
    int timeCounter;
    unsigned short tCRC;
    unsigned char recv;
    unsigned char expectnum;
    unsigned char XMODEM_FRAME[ 132 ];
    fileEnd = filebuf;
   
    timeCounter = 0;
    while( ( AT91C_BASE_SYS -> DBGU_CSR & 0x01 ) == 0 )
    {
        timeCounter++;
        if( timeCounter > 500000 )
        {
            timeCounter = 0;
            sentByte( XMODEM_CRC );
        }
    }
   
    for( expectnum = 1; ; expectnum++ )
    {
        while( ( AT91C_BASE_SYS -> DBGU_CSR & 0x01 ) == 0 );
        recv = AT91C_BASE_SYS -> DBGU_RHR;
        if( recv == XMODEM_EOT )
        {
            sentByte( XMODEM_ACK );
            return 0;
        }
       
        AT91C_BASE_SYS -> DBGU_RPR = (unsigned int)XMODEM_FRAME;
        AT91C_BASE_SYS -> DBGU_RCR = 132;
       
        timeCounter = 0;
        while( ( AT91C_BASE_SYS -> DBGU_CSR & 0x08 ) == 0 )
        {
            timeCounter++;
            if( timeCounter > 500000 )
            {
                sentByte( XMODEM_CAN );
                return 1;
            }
        }
       
        if( (XMODEM_FRAME[ 0 ] ^ XMODEM_FRAME[ 1 ]) != 0xff )
        {
            expectnum--;
            sentByte( XMODEM_NAK );
        }
        else
        {
            if( XMODEM_FRAME[ 0 ] != expectnum )
            {
                sentByte( XMODEM_CAN );
                return 1;
            }
            //check the CRC
            tCRC = ( XMODEM_FRAME[ 130 ] << 8 ) + XMODEM_FRAME[ 131 ];
            error = ( tCRC != get_CRC16( &XMODEM_FRAME[ 2 ], 128 ) );
            if( error )
            {
                expectnum--;
                sentByte( XMODEM_NAK );
            }
            else
            {
                for( i = 2; i < 130; i++ )
                {
                    *fileEnd++ = XMODEM_FRAME[ i ];
                }
            }
            sentByte( XMODEM_ACK );
        }
    }
    return 0;
}

int xmodem_sent( void )
{
    int i;
    int valid;
    unsigned char packetnum;
    unsigned char recv;
    unsigned char XMODEM_FRAME[ 133 ];
    unsigned char *fp = filebuf;
    unsigned short CRC;

    while( 1 )
    {
        do
        {
            valid = 1;
            while( ( AT91C_BASE_SYS -> DBGU_CSR & 0x01 ) == 0 );
            recv = AT91C_BASE_SYS -> DBGU_RHR;
            switch( recv )
            {
            case XMODEM_ACK: packetnum++; break;
            case XMODEM_NAK: fp = fp - 128; break;
            case XMODEM_CAN: return 1;
            case XMODEM_CRC: packetnum = 1; break;
            default: valid = 0;
            }
        }while( !valid );
       
        if( fp == fileEnd )
        {
            sentByte( XMODEM_EOT );
            return 0;
        }
        else
        {
            XMODEM_FRAME[ 0 ] = XMODEM_SOH;
            XMODEM_FRAME[ 1 ] = packetnum;
            XMODEM_FRAME[ 2 ] = 0xff - packetnum;
            for( i = 3; i < 131; i++ )
            {
                if( fp != fileEnd ) XMODEM_FRAME[ i ] = *fp++;
                else
                {
                    XMODEM_FRAME[ i ] = '\0';
                }
            }
            CRC = get_CRC16( &XMODEM_FRAME[ 3 ], 128 );
            XMODEM_FRAME[ 131 ] = CRC >> 8;
            XMODEM_FRAME[ 132 ] = CRC & 0xff;
            AT91C_BASE_SYS -> DBGU_TPR = (unsigned int)XMODEM_FRAME;
            AT91C_BASE_SYS -> DBGU_TCR = 133;
            while( ( AT91C_BASE_SYS -> DBGU_CSR & 0x10 ) == 0 );
        }
    }
    return 0;
}

int main( void )
{
    int error;
    init_DMA_DBGU( );
    error = xmodem_recv( );
    error = xmodem_sent( );

    while( 1 ){}
    return 0;
}

你可能感兴趣的:(xmodem协议 文件接收发送)