xmodem.c

来自「使用JTAG口对AT91R40008芯片进行FLASH编程的程序」· C语言 代码 · 共 485 行 · 第 1/2 页

C
485
字号
            eot_flag = TRUE;
            status = OK;
        }
    }// recieved with error
    return (status);
}

//*----------------------------------------------------------------------------
//* Function Name       : xmodem_receive
//* Object              : Received all frame
//* Input Parameters    : address of write function (flash,or ram, ...
//* Output Parameters   : Status
//* Functions called    : validate_packet       static function
//*                       respond               static function
//*----------------------------------------------------------------------------
int xmodem_receive(int (*write_function)(u_char *ptr_data,int size))
{

    u_char packet;
    int status;
    // init static data
    packet_number = 0x00;
    eot_flag = FALSE;
    buffer_status = EMPTY;

    //* init the header
    input_buff[0].Header = SOH;
    init_usart();
    status = TRUE;
    // send 'C' character until we get a packet from the sender
    while (!buffer_status)
    {
        at91_send_byte(Xmodem_COM,CRCCHR);
        recv_wait_frame(WAIT_1S);
    }

    //* validate 1st packet
    packet = validate_packet(input_buff);
    if ( packet)
    { // if Ok write data
        //* external function for write data
       if (!(*write_function)((u_char *) input_buff[0].data,XMODEM_DATA_SIZE))
       {
           eot_flag = TRUE ;
           status = FALSE;
       }
    }

    //* ack or nak
    respond(packet);

    // get remainder of file
    while (!eot_flag)
    {
        // wait for error or buffer FULL
        recv_wait_frame(WAIT_2S);
        // validate the packet
        packet = validate_packet(input_buff);
        if (packet && (eot_flag == FALSE))
        { // if Ok write data
        	if ( packet_number ==5)
        	{
				status = TRUE;
                eot_flag = FALSE ;
			}
            if (!(*write_function)((u_char *) input_buff[0].data,XMODEM_DATA_SIZE))
            {
                eot_flag = TRUE ;
                status = FALSE;
            }
        }
        // ack or nak
        respond(packet);

    } // end of 1st file transmission

    //* Send ACK
    respond(0==0);
    purge();
    return  (status);
}

//*----------------------------------------------------------------------------
//* Function Name       : recv_char_wait
//* Object              : wait data
//* Input Parameters    : <data> char to read
//* Output Parameters   : if Recievied char retrun this char
//*----------------------------------------------------------------------------
static u_char recv_char_wait(u_char data)
{
    int  read;
    buffer_status    = EMPTY;
    recv_error       = FALSE; // framing and over run detection

    timed_out = FALSE; // set in timer counter 0 overflow interrupt routine
    wait_time = WAIT_3S;

    // wait for packet or error
    while (!buffer_status && !recv_error && !timed_out)
    {
        if ( at91_usart_get_status(Xmodem_COM->usart) & (US_OVRE | US_PARE) )
        {
            recv_error = TRUE;
            //* Reset Status Bits
            at91_usart_trig_cmd( Xmodem_COM->usart,US_RSTSTA);
        }
        else if (!at91_getch(Xmodem_COM,&read))
        {
            // determine if read char is ok buffer FULL
            if ((u_char)read == data )
                    buffer_status = FULL;
        }
        // Time out
        time_out();
    }
    return( (u_char) read);
}

//*----------------------------------------------------------------------------
//* Function Name       : xmodem_transmit
//* Object              : transmit data area
//* Input Parameters    : <bufptr> start data address
//*                       <size>   lenght
//* Output Parameters   : none
//* Functions called    : at91_send_byte        define in com.c driver
//*                       at91_print_frame      define in com.c driver
//*                       calcrc                static function
//*----------------------------------------------------------------------------
int xmodem_transmit(u_char *bufptr,u_int len)
{
    u_int   count;
    int status = TRUE;
    u_short crc;
    u_char sent_packet = 0x01;
    //* wait the received
    while ( recv_char_wait(CRCCHR) != CRCCHR );

    for (count =0 ; count <len ;sent_packet++)
    {
        // send header
        at91_send_byte(Xmodem_COM,SOH);
        at91_send_byte(Xmodem_COM,sent_packet);
        at91_send_byte(Xmodem_COM,0xFF - sent_packet);
        // send data frame
        at91_print_frame (Xmodem_COM, (char*) bufptr , XMODEM_DATA_SIZE);
        count+= XMODEM_DATA_SIZE;
        bufptr+=XMODEM_DATA_SIZE;


        // determine CRC in background
        crc = calcrc((bufptr-XMODEM_DATA_SIZE),XMODEM_DATA_SIZE);
        // send CRC
        at91_send_byte(Xmodem_COM,(u_char)(crc >> 8));
        at91_send_byte(Xmodem_COM,(u_char)(crc));
        // wait ACK
        switch ( recv_char_wait(ACK))
        {
            case NAK: //* retransmit the last frame
                bufptr -=XMODEM_DATA_SIZE;
                count -=XMODEM_DATA_SIZE;
                sent_packet--;
                status =FALSE;
            break;
            case ACK://* Continue
            break;
            default: // Stop the transmission
                // send NACK
                respond(0!=0);
                count = len;
            break;
        }// switch End
    }// for end
    // send end of file
    at91_send_byte(Xmodem_COM,EOT);
    purge();
    return (status);
}

//*----------------------------------------------------------------------------
//* Function Name       : xmodem_transmit_func
//* Object              : Received all frame
//* Input Parameters    : address of read function (I2C,, ...
//* Output Parameters   : Status
//* Functions called    : validate_packet       static function
//*                       respond               static function
//*----------------------------------------------------------------------------
int xmodem_transmit_function(void (*read_function)(int address,char *ptr_data,int size),u_int len)
{
    u_int   count;
    int add;
    int status = TRUE;
    u_short crc;
    u_char sent_packet = 0x01;
    add=0;
    //* wait the received
    while ( recv_char_wait(CRCCHR) != CRCCHR );

    for (count =0 ; count <len ;sent_packet++)
    {
        // send header
        at91_send_byte(Xmodem_COM,SOH);
        at91_send_byte(Xmodem_COM,sent_packet);
        at91_send_byte(Xmodem_COM,0xFF - sent_packet);
        //* read data
       (*read_function)(add,buffer_send,XMODEM_DATA_SIZE);

        // send data frame
        at91_print_frame (Xmodem_COM,buffer_send, XMODEM_DATA_SIZE);
        count+= XMODEM_DATA_SIZE;
        add+=XMODEM_DATA_SIZE;

        //* determine CRC in background
        crc = calcrc((u_char *)buffer_send,XMODEM_DATA_SIZE);
        // send CRC
        at91_send_byte(Xmodem_COM,(u_char)(crc >> 8));
        at91_send_byte(Xmodem_COM,(u_char)(crc));
        // wait ACK
        switch ( recv_char_wait(ACK))
        {
            case NAK: //* retransmit the la st frame
            	add -=XMODEM_DATA_SIZE;
                count -=XMODEM_DATA_SIZE;
                sent_packet--;
                status =FALSE;
            break;
            case ACK://* Continue
            break;
            default: // Stop the transmission
                // send NACK
                respond(0!=0);
                count = len;
            break;
        }// switch End
    }// for end
    // send end of file
    at91_send_byte(Xmodem_COM,EOT);
    purge();

    return (status);
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?