1
0
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:
Thomas Hornschuh 2017-03-20 01:17:23 +01:00
parent 7a877e14cf
commit d0a6375202
2 changed files with 50 additions and 21 deletions

View File

@ -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 );

View File

@ -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