Commit f2841d377060cb2c3bedfcdfda6aab3066d6c4f1
Committed by
Markus Klotzbücher
1 parent
eeaab720f6
Exists in
master
and in
54 other branches
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
common/Makefile
common/cmd_load.c
... | ... | @@ -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" |
common/crc16.c
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 | +} |
common/xyzModem.c
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 |
include/crc.h
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_ |
include/xyzModem.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_ |