mirror of
https://github.com/elua/elua.git
synced 2025-01-25 01:02:54 +08:00
Added support for 1K xmodem
Preliminary support for 1K xmodem. Should make it configurable.
This commit is contained in:
parent
7a877e14cf
commit
d0a6375202
@ -7,8 +7,8 @@
|
|||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
|
|
||||||
// XMODEM constants
|
// XMODEM constants
|
||||||
#define XMODEM_INITIAL_BUFFER_SIZE 1024
|
#define XMODEM_INITIAL_BUFFER_SIZE 4096 // TH
|
||||||
#define XMODEM_INCREMENT_AMMOUNT 512
|
#define XMODEM_INCREMENT_AMMOUNT 4096 // TH
|
||||||
|
|
||||||
// xmodem timeout/retry parameters
|
// xmodem timeout/retry parameters
|
||||||
#define XMODEM_TIMEOUT 1000000
|
#define XMODEM_TIMEOUT 1000000
|
||||||
@ -19,6 +19,7 @@
|
|||||||
#define XMODEM_ERROR_OUTOFSYNC (-2)
|
#define XMODEM_ERROR_OUTOFSYNC (-2)
|
||||||
#define XMODEM_ERROR_RETRYEXCEED (-3)
|
#define XMODEM_ERROR_RETRYEXCEED (-3)
|
||||||
#define XMODEM_ERROR_OUTOFMEM (-4)
|
#define XMODEM_ERROR_OUTOFMEM (-4)
|
||||||
|
#define XMODEM_ERROR_INTERNAL (-5) // TH
|
||||||
|
|
||||||
typedef void ( *p_xm_send_func )( u8 );
|
typedef void ( *p_xm_send_func )( u8 );
|
||||||
typedef int ( *p_xm_recv_func )( timer_data_type );
|
typedef int ( *p_xm_recv_func )( timer_data_type );
|
||||||
|
66
src/xmodem.c
66
src/xmodem.c
@ -38,12 +38,15 @@
|
|||||||
#include "platform_conf.h"
|
#include "platform_conf.h"
|
||||||
#ifdef BUILD_XMODEM
|
#ifdef BUILD_XMODEM
|
||||||
|
|
||||||
#define PXM_ACKET_SIZE 128
|
|
||||||
|
|
||||||
|
//#define PXM_ACKET_SIZE 128 // TH: removed
|
||||||
static p_xm_send_func xmodem_out_func;
|
static p_xm_send_func xmodem_out_func;
|
||||||
static p_xm_recv_func xmodem_in_func;
|
static p_xm_recv_func xmodem_in_func;
|
||||||
|
|
||||||
// Line control codes
|
// Line control codes
|
||||||
#define XM_SOH 0x01
|
#define XM_SOH 0x01
|
||||||
|
#define XM_STX 0x02 // TH: Marker for 1K Blocks
|
||||||
#define XM_ACK 0x06
|
#define XM_ACK 0x06
|
||||||
#define XM_NAK 0x15
|
#define XM_NAK 0x15
|
||||||
#define XM_CAN 0x18
|
#define XM_CAN 0x18
|
||||||
@ -76,16 +79,24 @@ static void xmodem_flush( int how )
|
|||||||
|
|
||||||
// This private function receives a x-modem record to the pointer and
|
// This private function receives a x-modem record to the pointer and
|
||||||
// returns 1 on success and 0 on error
|
// returns 1 on success and 0 on error
|
||||||
static int xmodem_get_record( unsigned char blocknum, unsigned char *pbuf )
|
static int xmodem_get_record( unsigned char blocknum, unsigned char *pbuf,/*TH*/unsigned pack_sz /*TH*/ )
|
||||||
{
|
{
|
||||||
unsigned chk, j, size;
|
unsigned chk, j, size;
|
||||||
int ch;
|
int ch;
|
||||||
|
|
||||||
// Read packet
|
// Read packet
|
||||||
for( j = 0; j < PXM_ACKET_SIZE + 4; j ++ )
|
for( j = 0; j < (pack_sz + 4); j ++ )
|
||||||
{
|
{
|
||||||
if( ( ch = xmodem_in_func( XMODEM_TIMEOUT ) ) == -1 )
|
//TH : First read with zero timeout until the input fifo is empty
|
||||||
goto err;
|
// This should avoid FIFO overflows caused by the overhead of the eLua timers.
|
||||||
|
ch =xmodem_in_func( 0 );
|
||||||
|
if (ch== -1) {
|
||||||
|
// When no char available wait for XMODEM_TIMEOUT if a char arrives
|
||||||
|
ch = xmodem_in_func( XMODEM_TIMEOUT );
|
||||||
|
// If not we have a timout error
|
||||||
|
if( ch == -1 )
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
pbuf[ j ] = ( unsigned char )ch;
|
pbuf[ j ] = ( unsigned char )ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,7 +106,7 @@ static int xmodem_get_record( unsigned char blocknum, unsigned char *pbuf )
|
|||||||
if( *pbuf ++ != ( unsigned char )~blocknum )
|
if( *pbuf ++ != ( unsigned char )~blocknum )
|
||||||
goto err;
|
goto err;
|
||||||
// Check CRC
|
// Check CRC
|
||||||
for( size = chk = 0; size < PXM_ACKET_SIZE; size++, pbuf ++ )
|
for( size = chk = 0; size < pack_sz; size++, pbuf ++ )
|
||||||
{
|
{
|
||||||
chk = chk ^ *pbuf << 8;
|
chk = chk ^ *pbuf << 8;
|
||||||
for( j = 0; j < 8; j ++ )
|
for( j = 0; j < 8; j ++ )
|
||||||
@ -112,10 +123,11 @@ static int xmodem_get_record( unsigned char blocknum, unsigned char *pbuf )
|
|||||||
if( *pbuf ++ != ( chk & 0xFF ) )
|
if( *pbuf ++ != ( chk & 0xFF ) )
|
||||||
goto err;
|
goto err;
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
xmodem_out_func( XM_NAK );
|
xmodem_out_func( XM_NAK );
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This global function receives a x-modem transmission consisting of
|
// This global function receives a x-modem transmission consisting of
|
||||||
@ -124,42 +136,57 @@ err:
|
|||||||
long xmodem_receive( char **dest )
|
long xmodem_receive( char **dest )
|
||||||
{
|
{
|
||||||
int starting = 1, ch;
|
int starting = 1, ch;
|
||||||
unsigned char packnum = 1, buf[ PXM_ACKET_SIZE + 4 ];
|
unsigned char packnum = 1, buf[ 1024 + 4 ];
|
||||||
unsigned retries = XMODEM_RETRY_LIMIT;
|
unsigned retries = XMODEM_RETRY_LIMIT;
|
||||||
u32 limit = XMODEM_INITIAL_BUFFER_SIZE, size = 0;
|
u32 limit = XMODEM_INITIAL_BUFFER_SIZE, size = 0;
|
||||||
void *p;
|
void *p;
|
||||||
|
unsigned pack_sz; // TH
|
||||||
|
|
||||||
while( retries-- )
|
while( retries-- )
|
||||||
{
|
{
|
||||||
if( starting )
|
if( starting )
|
||||||
xmodem_out_func( 'C' );
|
xmodem_out_func( 'C' );
|
||||||
if( ( ( ch = xmodem_in_func( XMODEM_TIMEOUT ) ) == -1 ) || ( ch != XM_SOH && ch != XM_EOT && ch != XM_CAN ) )
|
if( ( ( ch = xmodem_in_func( XMODEM_TIMEOUT ) ) == -1 ) || ( ch != XM_SOH && /* TH */ ch != XM_STX && /*TH*/ ch != XM_EOT && ch != XM_CAN ) )
|
||||||
continue;
|
continue;
|
||||||
if( ch == XM_EOT )
|
|
||||||
{
|
switch(ch) { // TH
|
||||||
|
case XM_EOT:
|
||||||
|
//if( ch == XM_EOT )
|
||||||
|
//{
|
||||||
// End of transmission
|
// End of transmission
|
||||||
xmodem_out_func( XM_ACK );
|
xmodem_out_func( XM_ACK );
|
||||||
xmodem_flush( XMODEM_FLUSH_ONLY );
|
xmodem_flush( XMODEM_FLUSH_ONLY );
|
||||||
return size;
|
return size;
|
||||||
}
|
//}
|
||||||
else if( ch == XM_CAN )
|
case XM_CAN:
|
||||||
{
|
//else if( ch == XM_CAN )
|
||||||
|
//{
|
||||||
// The remote part ended the transmission
|
// The remote part ended the transmission
|
||||||
xmodem_out_func( XM_ACK );
|
xmodem_out_func( XM_ACK );
|
||||||
xmodem_flush( XMODEM_FLUSH_ONLY );
|
xmodem_flush( XMODEM_FLUSH_ONLY );
|
||||||
return XMODEM_ERROR_REMOTECANCEL;
|
return XMODEM_ERROR_REMOTECANCEL;
|
||||||
}
|
//}
|
||||||
|
case XM_SOH:
|
||||||
|
pack_sz=128;
|
||||||
|
break;
|
||||||
|
case XM_STX:
|
||||||
|
pack_sz=1024;
|
||||||
|
break;
|
||||||
|
default: // TH: Should never happen
|
||||||
|
return XMODEM_ERROR_INTERNAL;
|
||||||
|
}
|
||||||
starting = 0;
|
starting = 0;
|
||||||
|
|
||||||
|
|
||||||
// Get XMODEM packet
|
// Get XMODEM packet
|
||||||
if( !xmodem_get_record( packnum, buf ) )
|
if( !xmodem_get_record( packnum, buf,pack_sz ) )
|
||||||
continue; // allow for retransmission
|
continue; // allow for retransmission
|
||||||
xmodem_flush( XMODEM_FLUSH_ONLY );
|
xmodem_flush( XMODEM_FLUSH_ONLY );
|
||||||
retries = XMODEM_RETRY_LIMIT;
|
retries = XMODEM_RETRY_LIMIT;
|
||||||
packnum ++;
|
packnum ++;
|
||||||
|
|
||||||
// Got a valid packet
|
// Got a valid packet
|
||||||
if( size + PXM_ACKET_SIZE > limit )
|
if( size + pack_sz > limit )
|
||||||
{
|
{
|
||||||
limit += XMODEM_INCREMENT_AMMOUNT;
|
limit += XMODEM_INCREMENT_AMMOUNT;
|
||||||
if( ( p = realloc( *dest, limit ) ) == NULL )
|
if( ( p = realloc( *dest, limit ) ) == NULL )
|
||||||
@ -171,9 +198,10 @@ long xmodem_receive( char **dest )
|
|||||||
*dest = ( char* )p;
|
*dest = ( char* )p;
|
||||||
}
|
}
|
||||||
// Acknowledge and consume packet
|
// Acknowledge and consume packet
|
||||||
|
|
||||||
|
memcpy( *dest + size, buf + 2, pack_sz );
|
||||||
|
size += pack_sz;
|
||||||
xmodem_out_func( XM_ACK );
|
xmodem_out_func( XM_ACK );
|
||||||
memcpy( *dest + size, buf + 2, PXM_ACKET_SIZE );
|
|
||||||
size += PXM_ACKET_SIZE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exceeded retry count
|
// Exceeded retry count
|
||||||
|
Loading…
x
Reference in New Issue
Block a user