X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=mware%2Fxmodem.c;h=d6653a49d6c37d635a87af142685063599e20e23;hb=HEAD;hp=ba38810b935cf7adf943bec7f20bbadf948e5ae7;hpb=ed046ec2e30d22f13729f02739a5aa80806d72ec;p=bertos.git diff --git a/mware/xmodem.c b/mware/xmodem.c deleted file mode 100755 index ba38810b..00000000 --- a/mware/xmodem.c +++ /dev/null @@ -1,430 +0,0 @@ -/*! - * \file - * - * \brief X-Modem serial transmission protocol (implementation) - * - * Suppots the CRC-16 and 1K-blocks variants of the standard. - * \see ymodem.txt for the protocol description. - * - * \version $Id$ - * \author Bernardo Innocenti - */ - -/* - * $Log$ - * Revision 1.1 2004/08/11 19:54:22 bernie - * Import XModem protocol into DevLib. - * - */ - -#include "xmodem.h" - -#include -#include -#include -#include -#include - - -/*! - * \name Protocol control codes - * \{ - */ -#define XM_SOH 0x01 /*!< Start Of Header (128-byte block) */ -#define XM_STX 0x02 /*!< Start Of Header (1024-byte block) */ -#define XM_EOT 0x04 /*!< End Of Transmission */ -#define XM_ACK 0x06 /*!< Acknowledge block */ -#define XM_NAK 0x15 /*!< Negative Acknowledge */ -#define XM_C 0x43 /*!< Request CRC-16 transmission */ -#define XM_CAN 0x18 /*!< CANcel transmission */ -/*\}*/ - -#define XM_MAXRETRIES 15 /*!< Max retries before giving up */ -#define XM_MAXCRCRETRIES 7 /*!< Max retries before switching to BCC */ -#define XM_BUFSIZE 1024 /*!< Size of block buffer */ - - -#if (ARCH & ARCH_BOOT) - #include "kbdhw.h" - #if (ARCH & ARCH_SLIM) - #define CHECK_ABORT KEYPRESSED_STOP - #elif (ARCH & ARCH_SARF) - #define CHECK_ABORT KEYPRESSED_ESC - #endif -#else - #include "kbd.h" - #if (ARCH & ARCH_SLIM) - #define CHECK_ABORT (kbd_getchar() == K_STOP) - #elif (ARCH & ARCH_SARF) - #define CHECK_ABORT (kbd_getchar() == K_ESC) - #endif -#endif /* ARCH_BOOT */ - - -/*! Buffer to hold a block of data */ -static char block_buffer[XM_BUFSIZE]; - - -/*! - * Decode serial driver errors and print - * them on the display. - */ -static void SerialError(int retries) -{ - serstatus_t err, status; - - /* Get serial error code and reset it */ - status = ser_getstatus(); - ser_setstatus(0); - - /* Mostra tutti gli errori in sequenza */ - for (err = 0; status != 0; status >>= 1, err++) - { - /* Se il bit dell'errore e' settato */ - if (status & 1) - { - lcd_printf(0, 3, LCD_FILL, "%s %d", serial_errors[err], retries); - buz_beep(200); - timer_delay(500); - } - } -} - - -/*! - * Reset previous serial errors and flush the receive buffer - * (set a short timeout to speed up purge) - */ -static void FlushSerial(void) -{ - ser_setstatus(0); - ser_settimeouts(200, SER_DEFTXTIMEOUT); - while (ser_getchar() != EOF) {} - ser_settimeouts(SER_DEFRXTIMEOUT, SER_DEFTXTIMEOUT); - ser_setstatus(0); -} - - -bool xmodem_recv(KFile *fd) -{ - int c, i, blocksize; - int blocknr = 0, last_block_done = 0, retries = 0; - char *buf; - uint8_t checksum; - uint16_t crc; - bool purge = false; - bool usecrc = true; - - - lcd_printf(0, 2, LCD_FILL, "Starting Transfer..."); - lcd_clear(); - purge = true; - ser_settimeouts(SER_DEFRXTIMEOUT, SER_DEFTXTIMEOUT); - ser_setstatus(0); - - /* Send initial NAK to start transmission */ - for(;;) - { - if (CHECK_ABORT) - { - ser_putchar(XM_CAN); - ser_putchar(XM_CAN); - lcd_printf(0, 2, LCD_FILL, "Transfer aborted"); - return false; - } - - /* - * Discard incoming input until a timeout occurs, then send - * a NAK to the transmitter. - */ - if (purge) - { - purge = false; - - if (ser_getstatus()) - SerialError(retries); - - FlushSerial(); - retries++; - - if (retries >= XM_MAXRETRIES) - { - ser_putchar(XM_CAN); - ser_putchar(XM_CAN); - lcd_printf(0, 2, LCD_FILL, "Transfer aborted"); - return false; - } - - /* Transmission start? */ - if (blocknr == 0) - { - if (retries < XM_MAXCRCRETRIES) - { - lcd_printf(0, 2, LCD_FILL, "Request Tx (CRC)"); - ser_putchar(XM_C); - } - else - { - /* Give up with CRC and fall back to checksum */ - usecrc = false; - lcd_printf(0, 2, LCD_FILL, "Request Tx (BCC)"); - ser_putchar(XM_NAK); - } - } - else - ser_putchar(XM_NAK); - } - - switch (ser_getchar()) - { - case XM_STX: /* Start of header (1024-byte block) */ - blocksize = 1024; - goto getblock; - - case XM_SOH: /* Start of header (128-byte block) */ - blocksize = 128; - - getblock: - /* Get block number */ - c = ser_getchar(); - - /* Check complemented block number */ - if ((~c & 0xff) != ser_getchar()) - { - lcd_printf(0, 3, LCD_FILL, "Bad blk (%d)", c); - purge = true; - break; - } - - /* Determine which block is being sent */ - if (c == (blocknr & 0xff)) - /* Last block repeated */ - lcd_printf(0, 2, LCD_FILL, "Repeat blk %d", blocknr); - else if (c == ((blocknr + 1) & 0xff)) - /* Next block */ - lcd_printf(0, 2, LCD_FILL, "Recv blk %d", ++blocknr); - else - { - /* Sync lost */ - lcd_printf(0, 3, LCD_FILL, "Sync lost (%d/%d)", c, blocknr); - purge = true; - break; - } - - buf = block_buffer; /* Reset pointer to start of buffer */ - checksum = 0; - crc = 0; - for (i = 0; i < blocksize; i++) - { - if ((c = ser_getchar()) == EOF) - { - purge = true; - break; - } - - /* Store in buffer */ - *buf++ = (char)c; - - /* Calculate block checksum or CRC */ - if (usecrc) - crc = UPDCRC(c, crc); - else - checksum += (char)c; - } - - if (purge) - break; - - /* Get the checksum byte or the CRC-16 MSB */ - if ((c = ser_getchar()) == EOF) - { - purge = true; - break; - } - - if (usecrc) - { - crc = UPDCRC(c, crc); - - /* Get CRC-16 LSB */ - if ((c = ser_getchar()) == EOF) - { - purge = true; - break; - } - - crc = UPDCRC(c, crc); - - if (crc) - { - lcd_printf(0, 3, LCD_FILL, "Bad CRC: %04x", crc); - purge = true; - break; - } - } - /* Compare the checksum */ - else if (c != checksum) - { - lcd_printf(0, 3, LCD_FILL, "Bad sum: %04x/%04x", checksum, c); - purge = true; - break; - } - - /* - * Avoid flushing the same block twice. - * This could happen when the sender does not receive our - * acknowledge and resends the same block. - */ - if (last_block_done < blocknr) - { - /* Call user function to flush the buffer */ - if (fd->write(fd, block_buffer, blocksize)) - { - /* Acknowledge block and clear error counter */ - ser_putchar(XM_ACK); - retries = 0; - last_block_done = blocknr; - } - else - { - /* User callback failed: abort transfer immediately */ - retries = XM_MAXRETRIES; - purge = true; - } - } - break; - - case XM_EOT: /* End of transmission */ - ser_putchar(XM_ACK); - lcd_printf(0, 2, LCD_FILL, "Transfer completed"); - return true; - - case EOF: /* Timeout or serial error */ - purge = true; - break; - - default: - lcd_printf(0, 3, LCD_FILL, "Skipping garbage"); - purge = true; - break; - } - } /* End forever */ -} - - -bool xmodem_send(KFile *fd) -{ - size_t size = -1; - int blocknr = 1, retries = 0, c, i; - bool proceed, usecrc = false; - uint16_t crc; - uint8_t sum; - - - ser_settimeouts(SER_DEFRXTIMEOUT, SER_DEFTXTIMEOUT); - ser_setstatus(0); - FlushSerial(); - lcd_printf(0, 2, LCD_FILL, "Wait remote host"); - - for(;;) - { - proceed = false; - do - { - if (CHECK_ABORT) - return false; - - switch (c = ser_getchar()) - { - case XM_NAK: - case XM_C: - if (blocknr == 1) - { - if (c == XM_C) - { - lcd_printf(0, 2, LCD_FILL, "Tx start (CRC)"); - usecrc = true; - } - else - lcd_printf(0, 2, LCD_FILL, "Tx start (BCC)"); - - /* Call user function to read in one block */ - size = fd->read(fd, block_buffer, XM_BUFSIZE); - } - else - lcd_printf(0, 2, LCD_FILL, "Resend blk %d", blocknr); - proceed = true; - break; - - case XM_ACK: - /* End of transfer? */ - if (!size) - return true; - - /* Call user function to read in one block */ - size = fd->read(fd, block_buffer, XM_BUFSIZE); - blocknr++; - retries = 0; - proceed = true; - lcd_printf(0, 2, LCD_FILL, "Send blk %d", blocknr); - break; - - case EOF: - retries++; - SerialError(retries); - if (retries <= XM_MAXRETRIES) - break; - /* falling through! */ - - case XM_CAN: - lcd_printf(0, 2, LCD_FILL, "Transfer aborted"); - return false; - - default: - lcd_printf(0, 3, LCD_FILL, "Skipping garbage"); - break; - } - } - while (!proceed); - - if (!size) - ser_putchar(XM_EOT); - else - { - /* Pad block with 0xFF if it's partially full */ - if (size < XM_BUFSIZE) - for (i = size; i < XM_BUFSIZE; i++) - block_buffer[i] = (char)0xFF; - - /* Send block header (STX, blocknr, ~blocknr) */ - ser_putchar(XM_STX); - ser_putchar(blocknr & 0xFF); - ser_putchar(~blocknr & 0xFF); - - /* Send block and compute its CRC/checksum */ - sum = 0; - crc = 0; - for (i = 0; i < XM_BUFSIZE; i++) - { - ser_putchar(block_buffer[i]); - crc = UPDCRC(block_buffer[i], crc); - sum += block_buffer[i]; - } - - /* Send CRC/Checksum */ - if (usecrc) - { - crc = UPDCRC(0, crc); - crc = UPDCRC(0, crc); - ser_putchar(crc >> 8); - ser_putchar(crc & 0xFF); - } - else - ser_putchar(sum); - } - } -}