Commit f2841d377060cb2c3bedfcdfda6aab3066d6c4f1

Authored by Markus Klotzbuecher
Committed by Markus Klotzbücher
1 parent eeaab720f6

Add support for ymodem protocol (loady command).

Patch by Stefano Babic, 29 Mar 2006

Showing 6 changed files with 1151 additions and 14 deletions Side-by-side Diff

... ... @@ -51,7 +51,7 @@
51 51 memsize.o miiphybb.o miiphyutil.o \
52 52 s_record.o serial.o soft_i2c.o soft_spi.o spartan2.o spartan3.o \
53 53 usb.o usb_kbd.o usb_storage.o \
54   - virtex2.o xilinx.o
  54 + virtex2.o xilinx.o crc16.o xyzModem.o
55 55  
56 56 OBJS = $(AOBJS) $(COBJS)
57 57  
... ... @@ -29,10 +29,11 @@
29 29 #include <s_record.h>
30 30 #include <net.h>
31 31 #include <exports.h>
  32 +#include <xyzModem.h>
32 33  
33   -
34 34 #if (CONFIG_COMMANDS & CFG_CMD_LOADS)
35 35 static ulong load_serial (ulong offset);
  36 +static ulong load_serial_ymodem (ulong offset);
36 37 static int read_record (char *buf, ulong len);
37 38 # if (CONFIG_COMMANDS & CFG_CMD_SAVES)
38 39 static int save_serial (ulong offset, ulong size);
39 40  
40 41  
41 42  
... ... @@ -475,21 +476,31 @@
475 476 }
476 477 }
477 478  
478   - printf ("## Ready for binary (kermit) download "
479   - "to 0x%08lX at %d bps...\n",
480   - offset,
481   - load_baudrate);
482   - addr = load_serial_bin (offset);
  479 + if (strcmp(argv[0],"loady")==0) {
  480 + printf ("## Ready for binary (ymodem) download "
  481 + "to 0x%08lX at %d bps...\n",
  482 + offset,
  483 + load_baudrate);
483 484  
484   - if (addr == ~0) {
485   - load_addr = 0;
486   - printf ("## Binary (kermit) download aborted\n");
487   - rcode = 1;
  485 + addr = load_serial_ymodem (offset);
  486 +
488 487 } else {
489   - printf ("## Start Addr = 0x%08lX\n", addr);
490   - load_addr = addr;
491   - }
492 488  
  489 + printf ("## Ready for binary (kermit) download "
  490 + "to 0x%08lX at %d bps...\n",
  491 + offset,
  492 + load_baudrate);
  493 + addr = load_serial_bin (offset);
  494 +
  495 + if (addr == ~0) {
  496 + load_addr = 0;
  497 + printf ("## Binary (kermit) download aborted\n");
  498 + rcode = 1;
  499 + } else {
  500 + printf ("## Start Addr = 0x%08lX\n", addr);
  501 + load_addr = addr;
  502 + }
  503 + }
493 504 if (load_baudrate != current_baudrate) {
494 505 printf ("## Switch baudrate to %d bps and press ESC ...\n",
495 506 current_baudrate);
... ... @@ -963,6 +974,66 @@
963 974 }
964 975 return ((ulong) os_data_addr - (ulong) bin_start_address);
965 976 }
  977 +
  978 +static int getcxmodem(void) {
  979 + if (tstc())
  980 + return (getc());
  981 + return -1;
  982 +}
  983 +static ulong load_serial_ymodem (ulong offset)
  984 +{
  985 + int size;
  986 + char buf[32];
  987 + int err;
  988 + int res;
  989 + connection_info_t info;
  990 + char ymodemBuf[1024];
  991 + ulong store_addr = ~0;
  992 + ulong addr = 0;
  993 +
  994 + size=0;
  995 + info.mode=xyzModem_ymodem;
  996 + res=xyzModem_stream_open(&info, &err);
  997 + if (!res) {
  998 +
  999 + while ((res=xyzModem_stream_read(ymodemBuf, 1024, &err)) > 0 ){
  1000 + store_addr = addr + offset;
  1001 + size+=res;
  1002 + addr+=res;
  1003 +#ifndef CFG_NO_FLASH
  1004 + if (addr2info(store_addr)) {
  1005 + int rc;
  1006 +
  1007 + rc = flash_write((char *)ymodemBuf,store_addr,res);
  1008 + if (rc != 0) {
  1009 + flash_perror (rc);
  1010 + return (~0);
  1011 + }
  1012 + } else
  1013 +#endif
  1014 + {
  1015 + memcpy ((char *)(store_addr), ymodemBuf, res);
  1016 + }
  1017 +
  1018 + }
  1019 + }
  1020 + else {
  1021 + printf ("%s\n",xyzModem_error(err));
  1022 + }
  1023 +
  1024 + xyzModem_stream_close(&err);
  1025 + xyzModem_stream_terminate(false,&getcxmodem);
  1026 +
  1027 +
  1028 + flush_cache (offset, size);
  1029 +
  1030 + printf("## Total Size = 0x%08x = %d Bytes\n", size, size);
  1031 + sprintf(buf, "%X", size);
  1032 + setenv("filesize", buf);
  1033 +
  1034 + return offset;
  1035 +}
  1036 +
966 1037 #endif /* CFG_CMD_LOADB */
967 1038  
968 1039 /* -------------------------------------------------------------------- */
... ... @@ -1017,6 +1088,14 @@
1017 1088 U_BOOT_CMD(
1018 1089 loadb, 3, 0, do_load_serial_bin,
1019 1090 "loadb - load binary file over serial line (kermit mode)\n",
  1091 + "[ off ] [ baud ]\n"
  1092 + " - load binary file over serial line"
  1093 + " with offset 'off' and baudrate 'baud'\n"
  1094 +);
  1095 +
  1096 +U_BOOT_CMD(
  1097 + loady, 3, 0, do_load_serial_bin,
  1098 + "loady - load binary file over serial line (ymodem mode)\n",
1020 1099 "[ off ] [ baud ]\n"
1021 1100 " - load binary file over serial line"
1022 1101 " with offset 'off' and baudrate 'baud'\n"
  1 +//==========================================================================
  2 +//
  3 +// crc16.c
  4 +//
  5 +// 16 bit CRC with polynomial x^16+x^12+x^5+1
  6 +//
  7 +//==========================================================================
  8 +//####ECOSGPLCOPYRIGHTBEGIN####
  9 +// -------------------------------------------
  10 +// This file is part of eCos, the Embedded Configurable Operating System.
  11 +// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
  12 +// Copyright (C) 2002 Gary Thomas
  13 +//
  14 +// eCos is free software; you can redistribute it and/or modify it under
  15 +// the terms of the GNU General Public License as published by the Free
  16 +// Software Foundation; either version 2 or (at your option) any later version.
  17 +//
  18 +// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
  19 +// WARRANTY; without even the implied warranty of MERCHANTABILITY or
  20 +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  21 +// for more details.
  22 +//
  23 +// You should have received a copy of the GNU General Public License along
  24 +// with eCos; if not, write to the Free Software Foundation, Inc.,
  25 +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  26 +//
  27 +// As a special exception, if other files instantiate templates or use macros
  28 +// or inline functions from this file, or you compile this file and link it
  29 +// with other works to produce a work based on this file, this file does not
  30 +// by itself cause the resulting work to be covered by the GNU General Public
  31 +// License. However the source code for this file must still be made available
  32 +// in accordance with section (3) of the GNU General Public License.
  33 +//
  34 +// This exception does not invalidate any other reasons why a work based on
  35 +// this file might be covered by the GNU General Public License.
  36 +//
  37 +// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
  38 +// at http://sources.redhat.com/ecos/ecos-license/
  39 +// -------------------------------------------
  40 +//####ECOSGPLCOPYRIGHTEND####
  41 +//==========================================================================
  42 +//#####DESCRIPTIONBEGIN####
  43 +//
  44 +// Author(s): gthomas
  45 +// Contributors: gthomas,asl
  46 +// Date: 2001-01-31
  47 +// Purpose:
  48 +// Description:
  49 +//
  50 +// This code is part of eCos (tm).
  51 +//
  52 +//####DESCRIPTIONEND####
  53 +//
  54 +//==========================================================================
  55 +
  56 +#include "crc.h"
  57 +
  58 +// Table of CRC constants - implements x^16+x^12+x^5+1
  59 +static const uint16_t crc16_tab[] = {
  60 + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
  61 + 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
  62 + 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
  63 + 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
  64 + 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
  65 + 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
  66 + 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
  67 + 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
  68 + 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
  69 + 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
  70 + 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
  71 + 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
  72 + 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
  73 + 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
  74 + 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
  75 + 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
  76 + 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
  77 + 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
  78 + 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
  79 + 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
  80 + 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
  81 + 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
  82 + 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
  83 + 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
  84 + 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
  85 + 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
  86 + 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
  87 + 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
  88 + 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
  89 + 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
  90 + 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
  91 + 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0,
  92 +};
  93 +
  94 +uint16_t
  95 +cyg_crc16(unsigned char *buf, int len)
  96 +{
  97 + int i;
  98 + uint16_t cksum;
  99 +
  100 + cksum = 0;
  101 + for (i = 0; i < len; i++) {
  102 + cksum = crc16_tab[((cksum>>8) ^ *buf++) & 0xFF] ^ (cksum << 8);
  103 + }
  104 + return cksum;
  105 +}
  1 +//==========================================================================
  2 +//
  3 +// xyzModem.c
  4 +//
  5 +// RedBoot stream handler for xyzModem protocol
  6 +//
  7 +//==========================================================================
  8 +//####ECOSGPLCOPYRIGHTBEGIN####
  9 +// -------------------------------------------
  10 +// This file is part of eCos, the Embedded Configurable Operating System.
  11 +// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
  12 +// Copyright (C) 2002 Gary Thomas
  13 +//
  14 +// eCos is free software; you can redistribute it and/or modify it under
  15 +// the terms of the GNU General Public License as published by the Free
  16 +// Software Foundation; either version 2 or (at your option) any later version.
  17 +//
  18 +// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
  19 +// WARRANTY; without even the implied warranty of MERCHANTABILITY or
  20 +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  21 +// for more details.
  22 +//
  23 +// You should have received a copy of the GNU General Public License along
  24 +// with eCos; if not, write to the Free Software Foundation, Inc.,
  25 +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  26 +//
  27 +// As a special exception, if other files instantiate templates or use macros
  28 +// or inline functions from this file, or you compile this file and link it
  29 +// with other works to produce a work based on this file, this file does not
  30 +// by itself cause the resulting work to be covered by the GNU General Public
  31 +// License. However the source code for this file must still be made available
  32 +// in accordance with section (3) of the GNU General Public License.
  33 +//
  34 +// This exception does not invalidate any other reasons why a work based on
  35 +// this file might be covered by the GNU General Public License.
  36 +//
  37 +// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
  38 +// at http://sources.redhat.com/ecos/ecos-license/
  39 +// -------------------------------------------
  40 +//####ECOSGPLCOPYRIGHTEND####
  41 +//==========================================================================
  42 +//#####DESCRIPTIONBEGIN####
  43 +//
  44 +// Author(s): gthomas
  45 +// Contributors: gthomas, tsmith, Yoshinori Sato
  46 +// Date: 2000-07-14
  47 +// Purpose:
  48 +// Description:
  49 +//
  50 +// This code is part of RedBoot (tm).
  51 +//
  52 +//####DESCRIPTIONEND####
  53 +//
  54 +//==========================================================================
  55 +#include <common.h>
  56 +#include <xyzModem.h>
  57 +#include <stdarg.h>
  58 +#include <crc.h>
  59 +
  60 +// Assumption - run xyzModem protocol over the console port
  61 +
  62 +// Values magic to the protocol
  63 +#define SOH 0x01
  64 +#define STX 0x02
  65 +#define EOT 0x04
  66 +#define ACK 0x06
  67 +#define BSP 0x08
  68 +#define NAK 0x15
  69 +#define CAN 0x18
  70 +#define EOF 0x1A // ^Z for DOS officionados
  71 +
  72 +#define USE_YMODEM_LENGTH
  73 +
  74 +// Data & state local to the protocol
  75 +static struct {
  76 +#ifdef REDBOOT
  77 + hal_virtual_comm_table_t* __chan;
  78 +#else
  79 + int *__chan;
  80 +#endif
  81 + unsigned char pkt[1024], *bufp;
  82 + unsigned char blk,cblk,crc1,crc2;
  83 + unsigned char next_blk; // Expected block
  84 + int len, mode, total_retries;
  85 + int total_SOH, total_STX, total_CAN;
  86 + bool crc_mode, at_eof, tx_ack;
  87 +#ifdef USE_YMODEM_LENGTH
  88 + unsigned long file_length, read_length;
  89 +#endif
  90 +} xyz;
  91 +
  92 +#define xyzModem_CHAR_TIMEOUT 2000 // 2 seconds
  93 +#define xyzModem_MAX_RETRIES 20
  94 +#define xyzModem_MAX_RETRIES_WITH_CRC 10
  95 +#define xyzModem_CAN_COUNT 3 // Wait for 3 CAN before quitting
  96 +
  97 +
  98 +#ifndef REDBOOT //SB
  99 +typedef int cyg_int32;
  100 +int CYGACC_COMM_IF_GETC_TIMEOUT (char chan,char *c) {
  101 +#define DELAY 20
  102 + unsigned long counter=0;
  103 + while (!tstc() && (counter < xyzModem_CHAR_TIMEOUT*1000/DELAY)) {
  104 + udelay(DELAY);
  105 + counter++;
  106 + }
  107 + if (tstc()) {
  108 + *c=getc();
  109 + return 1;
  110 + }
  111 + return 0;
  112 +}
  113 +
  114 +void CYGACC_COMM_IF_PUTC(char x,char y) {
  115 + putc(y);
  116 +}
  117 +
  118 +// Validate a hex character
  119 +__inline__ static bool
  120 +_is_hex(char c)
  121 +{
  122 + return (((c >= '0') && (c <= '9')) ||
  123 + ((c >= 'A') && (c <= 'F')) ||
  124 + ((c >= 'a') && (c <= 'f')));
  125 +}
  126 +
  127 +// Convert a single hex nibble
  128 +__inline__ static int
  129 +_from_hex(char c)
  130 +{
  131 + int ret = 0;
  132 +
  133 + if ((c >= '0') && (c <= '9')) {
  134 + ret = (c - '0');
  135 + } else if ((c >= 'a') && (c <= 'f')) {
  136 + ret = (c - 'a' + 0x0a);
  137 + } else if ((c >= 'A') && (c <= 'F')) {
  138 + ret = (c - 'A' + 0x0A);
  139 + }
  140 + return ret;
  141 +}
  142 +
  143 +// Convert a character to lower case
  144 +__inline__ static char
  145 +_tolower(char c)
  146 +{
  147 + if ((c >= 'A') && (c <= 'Z')) {
  148 + c = (c - 'A') + 'a';
  149 + }
  150 + return c;
  151 +}
  152 +
  153 +
  154 +
  155 +//
  156 +// Parse (scan) a number
  157 +//
  158 +bool
  159 +parse_num(char *s, unsigned long *val, char **es, char *delim)
  160 +{
  161 + bool first = true;
  162 + int radix = 10;
  163 + char c;
  164 + unsigned long result = 0;
  165 + int digit;
  166 +
  167 + while (*s == ' ') s++;
  168 + while (*s) {
  169 + if (first && (s[0] == '0') && (_tolower(s[1]) == 'x')) {
  170 + radix = 16;
  171 + s += 2;
  172 + }
  173 + first = false;
  174 + c = *s++;
  175 + if (_is_hex(c) && ((digit = _from_hex(c)) < radix)) {
  176 + // Valid digit
  177 +#ifdef CYGPKG_HAL_MIPS
  178 + // FIXME: tx49 compiler generates 0x2539018 for MUL which
  179 + // isn't any good.
  180 + if (16 == radix)
  181 + result = result << 4;
  182 + else
  183 + result = 10 * result;
  184 + result += digit;
  185 +#else
  186 + result = (result * radix) + digit;
  187 +#endif
  188 + } else {
  189 + if (delim != (char *)0) {
  190 + // See if this character is one of the delimiters
  191 + char *dp = delim;
  192 + while (*dp && (c != *dp)) dp++;
  193 + if (*dp) break; // Found a good delimiter
  194 + }
  195 + return false; // Malformatted number
  196 + }
  197 + }
  198 + *val = result;
  199 + if (es != (char **)0) {
  200 + *es = s;
  201 + }
  202 + return true;
  203 +}
  204 +
  205 +#endif
  206 +
  207 +#define USE_SPRINTF
  208 +#ifdef DEBUG
  209 +#ifndef USE_SPRINTF
  210 +//
  211 +// Note: this debug setup only works if the target platform has two serial ports
  212 +// available so that the other one (currently only port 1) can be used for debug
  213 +// messages.
  214 +//
  215 +static int
  216 +zm_dprintf(char *fmt, ...)
  217 +{
  218 + int cur_console;
  219 + va_list args;
  220 +
  221 + va_start(args, fmt);
  222 +#ifdef REDBOOT
  223 + cur_console = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
  224 + CYGACC_CALL_IF_SET_CONSOLE_COMM(1);
  225 +#endif
  226 + diag_vprintf(fmt, args);
  227 +#ifdef REDBOOT
  228 + CYGACC_CALL_IF_SET_CONSOLE_COMM(cur_console);
  229 +#endif
  230 +}
  231 +
  232 +static void
  233 +zm_flush(void)
  234 +{
  235 +}
  236 +
  237 +#else
  238 +//
  239 +// Note: this debug setup works by storing the strings in a fixed buffer
  240 +//
  241 +#define FINAL
  242 +#ifdef FINAL
  243 +static char *zm_out = (char *)0x00380000;
  244 +static char *zm_out_start = (char *)0x00380000;
  245 +#else
  246 +static char zm_buf[8192];
  247 +static char *zm_out=zm_buf;
  248 +static char *zm_out_start = zm_buf;
  249 +
  250 +#endif
  251 +static int
  252 +zm_dprintf(char *fmt, ...)
  253 +{
  254 + int len;
  255 + va_list args;
  256 +
  257 + va_start(args, fmt);
  258 + len = diag_vsprintf(zm_out, fmt, args);
  259 + zm_out += len;
  260 + return len;
  261 +}
  262 +
  263 +static void
  264 +zm_flush(void)
  265 +{
  266 + char *p = zm_out_start;
  267 +#ifdef REDBOOT
  268 + while (*p) mon_write_char(*p++);
  269 +#endif
  270 + zm_out = zm_out_start;
  271 +}
  272 +#endif
  273 +
  274 +static void
  275 +zm_dump_buf(void *buf, int len)
  276 +{
  277 +#ifdef REDBOOT
  278 + diag_vdump_buf_with_offset(zm_dprintf, buf, len, 0);
  279 +#else
  280 +
  281 +#endif
  282 +}
  283 +
  284 +static unsigned char zm_buf[2048];
  285 +static unsigned char *zm_bp;
  286 +
  287 +static void
  288 +zm_new(void)
  289 +{
  290 + zm_bp = zm_buf;
  291 +}
  292 +
  293 +static void
  294 +zm_save(unsigned char c)
  295 +{
  296 + *zm_bp++ = c;
  297 +}
  298 +
  299 +static void
  300 +zm_dump(int line)
  301 +{
  302 + zm_dprintf("Packet at line: %d\n", line);
  303 + zm_dump_buf(zm_buf, zm_bp-zm_buf);
  304 +}
  305 +
  306 +#define ZM_DEBUG(x) x
  307 +#else
  308 +#define ZM_DEBUG(x)
  309 +#endif
  310 +
  311 +// Wait for the line to go idle
  312 +static void
  313 +xyzModem_flush(void)
  314 +{
  315 + int res;
  316 + char c;
  317 + while (true) {
  318 + res = CYGACC_COMM_IF_GETC_TIMEOUT(*xyz.__chan, &c);
  319 + if (!res) return;
  320 + }
  321 +}
  322 +
  323 +static int
  324 +xyzModem_get_hdr(void)
  325 +{
  326 + char c;
  327 + int res;
  328 + bool hdr_found = false;
  329 + int i, can_total, hdr_chars;
  330 + unsigned short cksum;
  331 +
  332 + ZM_DEBUG(zm_new());
  333 + // Find the start of a header
  334 + can_total = 0;
  335 + hdr_chars = 0;
  336 +
  337 + if (xyz.tx_ack) {
  338 + CYGACC_COMM_IF_PUTC(*xyz.__chan, ACK);
  339 + xyz.tx_ack = false;
  340 + }
  341 + while (!hdr_found) {
  342 + res = CYGACC_COMM_IF_GETC_TIMEOUT(*xyz.__chan, &c);
  343 + ZM_DEBUG(zm_save(c));
  344 + if (res) {
  345 + hdr_chars++;
  346 + switch (c) {
  347 + case SOH:
  348 + xyz.total_SOH++;
  349 + case STX:
  350 + if (c == STX) xyz.total_STX++;
  351 + hdr_found = true;
  352 + break;
  353 + case CAN:
  354 + xyz.total_CAN++;
  355 + ZM_DEBUG(zm_dump(__LINE__));
  356 + if (++can_total == xyzModem_CAN_COUNT) {
  357 + return xyzModem_cancel;
  358 + } else {
  359 + // Wait for multiple CAN to avoid early quits
  360 + break;
  361 + }
  362 + case EOT:
  363 + // EOT only supported if no noise
  364 + if (hdr_chars == 1) {
  365 + CYGACC_COMM_IF_PUTC(*xyz.__chan, ACK);
  366 + ZM_DEBUG(zm_dprintf("ACK on EOT #%d\n", __LINE__));
  367 + ZM_DEBUG(zm_dump(__LINE__));
  368 + return xyzModem_eof;
  369 + }
  370 + default:
  371 + // Ignore, waiting for start of header
  372 + ;
  373 + }
  374 + } else {
  375 + // Data stream timed out
  376 + xyzModem_flush(); // Toss any current input
  377 + ZM_DEBUG(zm_dump(__LINE__));
  378 + CYGACC_CALL_IF_DELAY_US((cyg_int32)250000);
  379 + return xyzModem_timeout;
  380 + }
  381 + }
  382 +
  383 + // Header found, now read the data
  384 + res = CYGACC_COMM_IF_GETC_TIMEOUT(*xyz.__chan, &xyz.blk);
  385 + ZM_DEBUG(zm_save(xyz.blk));
  386 + if (!res) {
  387 + ZM_DEBUG(zm_dump(__LINE__));
  388 + return xyzModem_timeout;
  389 + }
  390 + res = CYGACC_COMM_IF_GETC_TIMEOUT(*xyz.__chan, &xyz.cblk);
  391 + ZM_DEBUG(zm_save(xyz.cblk));
  392 + if (!res) {
  393 + ZM_DEBUG(zm_dump(__LINE__));
  394 + return xyzModem_timeout;
  395 + }
  396 + xyz.len = (c == SOH) ? 128 : 1024;
  397 + xyz.bufp = xyz.pkt;
  398 + for (i = 0; i < xyz.len; i++) {
  399 + res = CYGACC_COMM_IF_GETC_TIMEOUT(*xyz.__chan, &c);
  400 + ZM_DEBUG(zm_save(c));
  401 + if (res) {
  402 + xyz.pkt[i] = c;
  403 + } else {
  404 + ZM_DEBUG(zm_dump(__LINE__));
  405 + return xyzModem_timeout;
  406 + }
  407 + }
  408 + res = CYGACC_COMM_IF_GETC_TIMEOUT(*xyz.__chan, &xyz.crc1);
  409 + ZM_DEBUG(zm_save(xyz.crc1));
  410 + if (!res) {
  411 + ZM_DEBUG(zm_dump(__LINE__));
  412 + return xyzModem_timeout;
  413 + }
  414 + if (xyz.crc_mode) {
  415 + res = CYGACC_COMM_IF_GETC_TIMEOUT(*xyz.__chan, &xyz.crc2);
  416 + ZM_DEBUG(zm_save(xyz.crc2));
  417 + if (!res) {
  418 + ZM_DEBUG(zm_dump(__LINE__));
  419 + return xyzModem_timeout;
  420 + }
  421 + }
  422 + ZM_DEBUG(zm_dump(__LINE__));
  423 + // Validate the message
  424 + if ((xyz.blk ^ xyz.cblk) != (unsigned char)0xFF) {
  425 + ZM_DEBUG(zm_dprintf("Framing error - blk: %x/%x/%x\n", xyz.blk, xyz.cblk, (xyz.blk ^ xyz.cblk)));
  426 + ZM_DEBUG(zm_dump_buf(xyz.pkt, xyz.len));
  427 + xyzModem_flush();
  428 + return xyzModem_frame;
  429 + }
  430 + // Verify checksum/CRC
  431 + if (xyz.crc_mode) {
  432 + cksum = cyg_crc16(xyz.pkt, xyz.len);
  433 + if (cksum != ((xyz.crc1 << 8) | xyz.crc2)) {
  434 + ZM_DEBUG(zm_dprintf("CRC error - recvd: %02x%02x, computed: %x\n",
  435 + xyz.crc1, xyz.crc2, cksum & 0xFFFF));
  436 + return xyzModem_cksum;
  437 + }
  438 + } else {
  439 + cksum = 0;
  440 + for (i = 0; i < xyz.len; i++) {
  441 + cksum += xyz.pkt[i];
  442 + }
  443 + if (xyz.crc1 != (cksum & 0xFF)) {
  444 + ZM_DEBUG(zm_dprintf("Checksum error - recvd: %x, computed: %x\n", xyz.crc1, cksum & 0xFF));
  445 + return xyzModem_cksum;
  446 + }
  447 + }
  448 + // If we get here, the message passes [structural] muster
  449 + return 0;
  450 +}
  451 +
  452 +int
  453 +xyzModem_stream_open(connection_info_t *info, int *err)
  454 +{
  455 + int console_chan, stat=0;
  456 + int retries = xyzModem_MAX_RETRIES;
  457 + int crc_retries = xyzModem_MAX_RETRIES_WITH_CRC;
  458 +
  459 +// ZM_DEBUG(zm_out = zm_out_start);
  460 +#ifdef xyzModem_zmodem
  461 + if (info->mode == xyzModem_zmodem) {
  462 + *err = xyzModem_noZmodem;
  463 + return -1;
  464 + }
  465 +#endif
  466 +
  467 +#ifdef REDBOOT
  468 + // Set up the I/O channel. Note: this allows for using a different port in the future
  469 + console_chan = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
  470 + if (info->chan >= 0) {
  471 + CYGACC_CALL_IF_SET_CONSOLE_COMM(info->chan);
  472 + } else {
  473 + CYGACC_CALL_IF_SET_CONSOLE_COMM(console_chan);
  474 + }
  475 + xyz.__chan = CYGACC_CALL_IF_CONSOLE_PROCS();
  476 +
  477 + CYGACC_CALL_IF_SET_CONSOLE_COMM(console_chan);
  478 + CYGACC_COMM_IF_CONTROL(*xyz.__chan, __COMMCTL_SET_TIMEOUT, xyzModem_CHAR_TIMEOUT);
  479 +#else
  480 +// TODO: CHECK !
  481 + int dummy;
  482 + xyz.__chan=&dummy;
  483 +#endif
  484 + xyz.len = 0;
  485 + xyz.crc_mode = true;
  486 + xyz.at_eof = false;
  487 + xyz.tx_ack = false;
  488 + xyz.mode = info->mode;
  489 + xyz.total_retries = 0;
  490 + xyz.total_SOH = 0;
  491 + xyz.total_STX = 0;
  492 + xyz.total_CAN = 0;
  493 +#ifdef USE_YMODEM_LENGTH
  494 + xyz.read_length = 0;
  495 + xyz.file_length = 0;
  496 +#endif
  497 +
  498 + CYGACC_COMM_IF_PUTC(*xyz.__chan, (xyz.crc_mode ? 'C' : NAK));
  499 +
  500 + if (xyz.mode == xyzModem_xmodem) {
  501 + // X-modem doesn't have an information header - exit here
  502 + xyz.next_blk = 1;
  503 + return 0;
  504 + }
  505 +
  506 + while (retries-- > 0) {
  507 + stat = xyzModem_get_hdr();
  508 + if (stat == 0) {
  509 + // Y-modem file information header
  510 + if (xyz.blk == 0) {
  511 +#ifdef USE_YMODEM_LENGTH
  512 + // skip filename
  513 + while (*xyz.bufp++);
  514 + // get the length
  515 + parse_num(xyz.bufp, &xyz.file_length, NULL, " ");
  516 +#endif
  517 + // The rest of the file name data block quietly discarded
  518 + xyz.tx_ack = true;
  519 + }
  520 + xyz.next_blk = 1;
  521 + xyz.len = 0;
  522 + return 0;
  523 + } else
  524 + if (stat == xyzModem_timeout) {
  525 + if (--crc_retries <= 0) xyz.crc_mode = false;
  526 + CYGACC_CALL_IF_DELAY_US(5*100000); // Extra delay for startup
  527 + CYGACC_COMM_IF_PUTC(*xyz.__chan, (xyz.crc_mode ? 'C' : NAK));
  528 + xyz.total_retries++;
  529 + ZM_DEBUG(zm_dprintf("NAK (%d)\n", __LINE__));
  530 + }
  531 + if (stat == xyzModem_cancel) {
  532 + break;
  533 + }
  534 + }
  535 + *err = stat;
  536 + ZM_DEBUG(zm_flush());
  537 + return -1;
  538 +}
  539 +
  540 +int
  541 +xyzModem_stream_read(char *buf, int size, int *err)
  542 +{
  543 + int stat, total, len;
  544 + int retries;
  545 +
  546 + total = 0;
  547 + stat = xyzModem_cancel;
  548 + // Try and get 'size' bytes into the buffer
  549 + while (!xyz.at_eof && (size > 0)) {
  550 + if (xyz.len == 0) {
  551 + retries = xyzModem_MAX_RETRIES;
  552 + while (retries-- > 0) {
  553 + stat = xyzModem_get_hdr();
  554 + if (stat == 0) {
  555 + if (xyz.blk == xyz.next_blk) {
  556 + xyz.tx_ack = true;
  557 + ZM_DEBUG(zm_dprintf("ACK block %d (%d)\n", xyz.blk, __LINE__));
  558 + xyz.next_blk = (xyz.next_blk + 1) & 0xFF;
  559 +
  560 +#if defined(xyzModem_zmodem) || defined(USE_YMODEM_LENGTH)
  561 + if (xyz.mode == xyzModem_xmodem || xyz.file_length == 0) {
  562 +#else
  563 + if (1) {
  564 +#endif
  565 + // Data blocks can be padded with ^Z (EOF) characters
  566 + // This code tries to detect and remove them
  567 + if ((xyz.bufp[xyz.len-1] == EOF) &&
  568 + (xyz.bufp[xyz.len-2] == EOF) &&
  569 + (xyz.bufp[xyz.len-3] == EOF)) {
  570 + while (xyz.len && (xyz.bufp[xyz.len-1] == EOF)) {
  571 + xyz.len--;
  572 + }
  573 + }
  574 + }
  575 +
  576 +#ifdef USE_YMODEM_LENGTH
  577 + // See if accumulated length exceeds that of the file.
  578 + // If so, reduce size (i.e., cut out pad bytes)
  579 + // Only do this for Y-modem (and Z-modem should it ever
  580 + // be supported since it can fall back to Y-modem mode).
  581 + if (xyz.mode != xyzModem_xmodem && 0 != xyz.file_length) {
  582 + xyz.read_length += xyz.len;
  583 + if (xyz.read_length > xyz.file_length) {
  584 + xyz.len -= (xyz.read_length - xyz.file_length);
  585 + }
  586 + }
  587 +#endif
  588 + break;
  589 + } else if (xyz.blk == ((xyz.next_blk - 1) & 0xFF)) {
  590 + // Just re-ACK this so sender will get on with it
  591 + CYGACC_COMM_IF_PUTC(*xyz.__chan, ACK);
  592 + continue; // Need new header
  593 + } else {
  594 + stat = xyzModem_sequence;
  595 + }
  596 + }
  597 + if (stat == xyzModem_cancel) {
  598 + break;
  599 + }
  600 + if (stat == xyzModem_eof) {
  601 + CYGACC_COMM_IF_PUTC(*xyz.__chan, ACK);
  602 + ZM_DEBUG(zm_dprintf("ACK (%d)\n", __LINE__));
  603 + if (xyz.mode == xyzModem_ymodem) {
  604 + CYGACC_COMM_IF_PUTC(*xyz.__chan, (xyz.crc_mode ? 'C' : NAK));
  605 + xyz.total_retries++;
  606 + ZM_DEBUG(zm_dprintf("Reading Final Header\n"));
  607 + stat = xyzModem_get_hdr();
  608 + CYGACC_COMM_IF_PUTC(*xyz.__chan, ACK);
  609 + ZM_DEBUG(zm_dprintf("FINAL ACK (%d)\n", __LINE__));
  610 + }
  611 + xyz.at_eof = true;
  612 + break;
  613 + }
  614 + CYGACC_COMM_IF_PUTC(*xyz.__chan, (xyz.crc_mode ? 'C' : NAK));
  615 + xyz.total_retries++;
  616 + ZM_DEBUG(zm_dprintf("NAK (%d)\n", __LINE__));
  617 + }
  618 + if (stat < 0) {
  619 + *err = stat;
  620 + xyz.len = -1;
  621 + return total;
  622 + }
  623 + }
  624 + // Don't "read" data from the EOF protocol package
  625 + if (!xyz.at_eof) {
  626 + len = xyz.len;
  627 + if (size < len) len = size;
  628 + memcpy(buf, xyz.bufp, len);
  629 + size -= len;
  630 + buf += len;
  631 + total += len;
  632 + xyz.len -= len;
  633 + xyz.bufp += len;
  634 + }
  635 + }
  636 + return total;
  637 +}
  638 +
  639 +void
  640 +xyzModem_stream_close(int *err)
  641 +{
  642 + diag_printf("xyzModem - %s mode, %d(SOH)/%d(STX)/%d(CAN) packets, %d retries\n",
  643 + xyz.crc_mode ? "CRC" : "Cksum",
  644 + xyz.total_SOH, xyz.total_STX, xyz.total_CAN,
  645 + xyz.total_retries);
  646 + ZM_DEBUG(zm_flush());
  647 +}
  648 +
  649 +// Need to be able to clean out the input buffer, so have to take the
  650 +// getc
  651 +void xyzModem_stream_terminate(bool abort, int (*getc)(void))
  652 +{
  653 + int c;
  654 +
  655 + if (abort) {
  656 + ZM_DEBUG(zm_dprintf("!!!! TRANSFER ABORT !!!!\n"));
  657 + switch (xyz.mode) {
  658 + case xyzModem_xmodem:
  659 + case xyzModem_ymodem:
  660 + // The X/YMODEM Spec seems to suggest that multiple CAN followed by an equal
  661 + // number of Backspaces is a friendly way to get the other end to abort.
  662 + CYGACC_COMM_IF_PUTC(*xyz.__chan,CAN);
  663 + CYGACC_COMM_IF_PUTC(*xyz.__chan,CAN);
  664 + CYGACC_COMM_IF_PUTC(*xyz.__chan,CAN);
  665 + CYGACC_COMM_IF_PUTC(*xyz.__chan,CAN);
  666 + CYGACC_COMM_IF_PUTC(*xyz.__chan,BSP);
  667 + CYGACC_COMM_IF_PUTC(*xyz.__chan,BSP);
  668 + CYGACC_COMM_IF_PUTC(*xyz.__chan,BSP);
  669 + CYGACC_COMM_IF_PUTC(*xyz.__chan,BSP);
  670 + // Now consume the rest of what's waiting on the line.
  671 + ZM_DEBUG(zm_dprintf("Flushing serial line.\n"));
  672 + xyzModem_flush();
  673 + xyz.at_eof = true;
  674 + break;
  675 +#ifdef xyzModem_zmodem
  676 + case xyzModem_zmodem:
  677 + // Might support it some day I suppose.
  678 +#endif
  679 + break;
  680 + }
  681 + } else {
  682 + ZM_DEBUG(zm_dprintf("Engaging cleanup mode...\n"));
  683 + // Consume any trailing crap left in the inbuffer from
  684 + // previous recieved blocks. Since very few files are an exact multiple
  685 + // of the transfer block size, there will almost always be some gunk here.
  686 + // If we don't eat it now, RedBoot will think the user typed it.
  687 + ZM_DEBUG(zm_dprintf("Trailing gunk:\n"));
  688 + while ((c = (*getc)()) > -1) ;
  689 + ZM_DEBUG(zm_dprintf("\n"));
  690 + // Make a small delay to give terminal programs like minicom
  691 + // time to get control again after their file transfer program
  692 + // exits.
  693 + CYGACC_CALL_IF_DELAY_US((cyg_int32)250000);
  694 + }
  695 +}
  696 +
  697 +char *
  698 +xyzModem_error(int err)
  699 +{
  700 + switch (err) {
  701 + case xyzModem_access:
  702 + return "Can't access file";
  703 + break;
  704 + case xyzModem_noZmodem:
  705 + return "Sorry, zModem not available yet";
  706 + break;
  707 + case xyzModem_timeout:
  708 + return "Timed out";
  709 + break;
  710 + case xyzModem_eof:
  711 + return "End of file";
  712 + break;
  713 + case xyzModem_cancel:
  714 + return "Cancelled";
  715 + break;
  716 + case xyzModem_frame:
  717 + return "Invalid framing";
  718 + break;
  719 + case xyzModem_cksum:
  720 + return "CRC/checksum error";
  721 + break;
  722 + case xyzModem_sequence:
  723 + return "Block sequence error";
  724 + break;
  725 + default:
  726 + return "Unknown error";
  727 + break;
  728 + }
  729 +}
  730 +
  731 +//
  732 +// RedBoot interface
  733 +//
  734 +#if 0 // SB
  735 +GETC_IO_FUNCS(xyzModem_io, xyzModem_stream_open, xyzModem_stream_close,
  736 + xyzModem_stream_terminate, xyzModem_stream_read, xyzModem_error);
  737 +RedBoot_load(xmodem, xyzModem_io, false, false, xyzModem_xmodem);
  738 +RedBoot_load(ymodem, xyzModem_io, false, false, xyzModem_ymodem);
  739 +#endif
  1 +//==========================================================================
  2 +//
  3 +// crc.h
  4 +//
  5 +// Interface for the CRC algorithms.
  6 +//
  7 +//==========================================================================
  8 +//####ECOSGPLCOPYRIGHTBEGIN####
  9 +// -------------------------------------------
  10 +// This file is part of eCos, the Embedded Configurable Operating System.
  11 +// Copyright (C) 2002 Andrew Lunn
  12 +//
  13 +// eCos is free software; you can redistribute it and/or modify it under
  14 +// the terms of the GNU General Public License as published by the Free
  15 +// Software Foundation; either version 2 or (at your option) any later version.
  16 +//
  17 +// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
  18 +// WARRANTY; without even the implied warranty of MERCHANTABILITY or
  19 +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  20 +// for more details.
  21 +//
  22 +// You should have received a copy of the GNU General Public License along
  23 +// with eCos; if not, write to the Free Software Foundation, Inc.,
  24 +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  25 +//
  26 +// As a special exception, if other files instantiate templates or use macros
  27 +// or inline functions from this file, or you compile this file and link it
  28 +// with other works to produce a work based on this file, this file does not
  29 +// by itself cause the resulting work to be covered by the GNU General Public
  30 +// License. However the source code for this file must still be made available
  31 +// in accordance with section (3) of the GNU General Public License.
  32 +//
  33 +// This exception does not invalidate any other reasons why a work based on
  34 +// this file might be covered by the GNU General Public License.
  35 +//
  36 +// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
  37 +// at http://sources.redhat.com/ecos/ecos-license/
  38 +// -------------------------------------------
  39 +//####ECOSGPLCOPYRIGHTEND####
  40 +//==========================================================================
  41 +//#####DESCRIPTIONBEGIN####
  42 +//
  43 +// Author(s): Andrew Lunn
  44 +// Contributors: Andrew Lunn
  45 +// Date: 2002-08-06
  46 +// Purpose:
  47 +// Description:
  48 +//
  49 +// This code is part of eCos (tm).
  50 +//
  51 +//####DESCRIPTIONEND####
  52 +//
  53 +//==========================================================================
  54 +
  55 +#ifndef _SERVICES_CRC_CRC_H_
  56 +#define _SERVICES_CRC_CRC_H_
  57 +
  58 +#include <linux/types.h>
  59 +
  60 +#ifndef __externC
  61 +# ifdef __cplusplus
  62 +# define __externC extern "C"
  63 +# else
  64 +# define __externC extern
  65 +# endif
  66 +#endif
  67 +
  68 +// Compute a CRC, using the POSIX 1003 definition
  69 +extern uint32_t
  70 +cyg_posix_crc32(unsigned char *s, int len);
  71 +
  72 +// Gary S. Brown's 32 bit CRC
  73 +
  74 +extern uint32_t
  75 +cyg_crc32(unsigned char *s, int len);
  76 +
  77 +// Gary S. Brown's 32 bit CRC, but accumulate the result from a
  78 +// previous CRC calculation
  79 +
  80 +extern uint32_t
  81 +cyg_crc32_accumulate(uint32_t crc, unsigned char *s, int len);
  82 +
  83 +// Ethernet FCS Algorithm
  84 +
  85 +extern uint32_t
  86 +cyg_ether_crc32(unsigned char *s, int len);
  87 +
  88 +// Ethernet FCS algorithm, but accumulate the result from a previous
  89 +// CRC calculation.
  90 +
  91 +extern uint32_t
  92 +cyg_ether_crc32_accumulate(uint32_t crc, unsigned char *s, int len);
  93 +
  94 +// 16 bit CRC with polynomial x^16+x^12+x^5+1
  95 +
  96 +extern uint16_t cyg_crc16(unsigned char *s, int len);
  97 +
  98 +#endif // _SERVICES_CRC_CRC_H_
  1 +//==========================================================================
  2 +//
  3 +// xyzModem.h
  4 +//
  5 +// RedBoot stream handler for xyzModem protocol
  6 +//
  7 +//==========================================================================
  8 +//####ECOSGPLCOPYRIGHTBEGIN####
  9 +// -------------------------------------------
  10 +// This file is part of eCos, the Embedded Configurable Operating System.
  11 +// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
  12 +// Copyright (C) 2002 Gary Thomas
  13 +//
  14 +// eCos is free software; you can redistribute it and/or modify it under
  15 +// the terms of the GNU General Public License as published by the Free
  16 +// Software Foundation; either version 2 or (at your option) any later version.
  17 +//
  18 +// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
  19 +// WARRANTY; without even the implied warranty of MERCHANTABILITY or
  20 +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  21 +// for more details.
  22 +//
  23 +// You should have received a copy of the GNU General Public License along
  24 +// with eCos; if not, write to the Free Software Foundation, Inc.,
  25 +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  26 +//
  27 +// As a special exception, if other files instantiate templates or use macros
  28 +// or inline functions from this file, or you compile this file and link it
  29 +// with other works to produce a work based on this file, this file does not
  30 +// by itself cause the resulting work to be covered by the GNU General Public
  31 +// License. However the source code for this file must still be made available
  32 +// in accordance with section (3) of the GNU General Public License.
  33 +//
  34 +// This exception does not invalidate any other reasons why a work based on
  35 +// this file might be covered by the GNU General Public License.
  36 +//
  37 +// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
  38 +// at http://sources.redhat.com/ecos/ecos-license/
  39 +// -------------------------------------------
  40 +//####ECOSGPLCOPYRIGHTEND####
  41 +//==========================================================================
  42 +//#####DESCRIPTIONBEGIN####
  43 +//
  44 +// Author(s): gthomas
  45 +// Contributors: gthomas
  46 +// Date: 2000-07-14
  47 +// Purpose:
  48 +// Description:
  49 +//
  50 +// This code is part of RedBoot (tm).
  51 +//
  52 +//####DESCRIPTIONEND####
  53 +//
  54 +//==========================================================================
  55 +
  56 +#ifndef _XYZMODEM_H_
  57 +#define _XYZMODEM_H_
  58 +
  59 +#define xyzModem_xmodem 1
  60 +#define xyzModem_ymodem 2
  61 +// Don't define this until the protocol support is in place
  62 +//#define xyzModem_zmodem 3
  63 +
  64 +#define xyzModem_access -1
  65 +#define xyzModem_noZmodem -2
  66 +#define xyzModem_timeout -3
  67 +#define xyzModem_eof -4
  68 +#define xyzModem_cancel -5
  69 +#define xyzModem_frame -6
  70 +#define xyzModem_cksum -7
  71 +#define xyzModem_sequence -8
  72 +
  73 +#define xyzModem_close 1
  74 +#define xyzModem_abort 2
  75 +
  76 +
  77 +#ifdef REDBOOT
  78 +extern getc_io_funcs_t xyzModem_io;
  79 +#else
  80 +#define CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT
  81 +#define CYGACC_CALL_IF_SET_CONSOLE_COMM(x)
  82 +
  83 +#define diag_vprintf vprintf
  84 +#define diag_printf printf
  85 +#define diag_vsprintf vsprintf
  86 +
  87 +#define CYGACC_CALL_IF_DELAY_US(x) udelay(x)
  88 +
  89 +typedef struct {
  90 + char *filename;
  91 + int mode;
  92 + int chan;
  93 +#ifdef CYGPKG_REDBOOT_NETWORKING
  94 + struct sockaddr_in *server;
  95 +#endif
  96 +} connection_info_t;
  97 +
  98 +typedef unsigned int bool;
  99 +
  100 +#define false 0
  101 +#define true 1
  102 +
  103 +#endif
  104 +
  105 +
  106 +int xyzModem_stream_open(connection_info_t *info, int *err);
  107 +void xyzModem_stream_close(int *err);
  108 +void xyzModem_stream_terminate(bool method, int (*getc)(void));
  109 +int xyzModem_stream_read(char *buf, int size, int *err);
  110 +char *xyzModem_error(int err);
  111 +
  112 +#endif // _XYZMODEM_H_