2 Copyright 2006 Arastra, Inc.
3 Copyright 2001, 2002 Georges Menie (www.menie.org)
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 extern void uart8250_tx_byte(unsigned, unsigned char);
24 extern int uart8250_can_rx_byte(unsigned);
25 extern unsigned char uart8250_rx_byte(unsigned);
27 static int _inbyte(int msec)
29 while (!uart8250_can_rx_byte(TTYS0_BASE)) {
34 return uart8250_rx_byte(TTYS0_BASE);
37 static void _outbyte(unsigned char c)
39 uart8250_tx_byte(TTYS0_BASE, c);
42 static unsigned short crc16_ccitt(const unsigned char *buf, int sz)
44 unsigned short crc = 0;
47 crc ^= (unsigned short) *buf++ << 8;
48 for (i = 0; i < 8; i++)
50 crc = crc << 1 ^ 0x1021;
68 static int check(int crc, const unsigned char *buf, int sz)
71 unsigned short crc = crc16_ccitt(buf, sz);
72 unsigned short tcrc = (buf[sz]<<8)+buf[sz+1];
78 unsigned char cks = 0;
79 for (i = 0; i < sz; ++i) {
89 static void flushinput(void)
91 while (_inbyte(((DLY_1S)*3)>>1) >= 0)
95 int xmodemReceive(unsigned char *dest, int destsz)
97 unsigned char xbuff[1030]; /* 1024 for XModem 1k + 3 head chars + 2 crc + nul */
100 unsigned char trychar = 'C';
101 unsigned char packetno = 1;
103 int retry, retrans = MAXRETRANS;
106 for( retry = 0; retry < 16; ++retry) {
107 if (trychar) _outbyte(trychar);
108 if ((c = _inbyte((DLY_1S)<<1)) >= 0) {
119 return len; /* normal end */
121 if ((c = _inbyte(DLY_1S)) == CAN) {
124 return -1; /* canceled by remote */
132 if (trychar == 'C') { trychar = NAK; continue; }
137 return -2; /* sync error */
140 if (trychar == 'C') crc = 1;
144 for (i = 0; i < (bufsz+(crc?1:0)+3); ++i) {
145 if ((c = _inbyte(DLY_1S)) < 0) goto reject;
149 if (xbuff[1] == (unsigned char)(~xbuff[2]) &&
150 (xbuff[1] == packetno || xbuff[1] == (unsigned char)packetno-1) &&
151 check(crc, &xbuff[3], bufsz)) {
152 if (xbuff[1] == packetno) {
153 register int count = destsz - len;
154 if (count > bufsz) count = bufsz;
156 memcpy (&dest[len], &xbuff[3], count);
160 retrans = MAXRETRANS+1;
162 if (--retrans <= 0) {
167 return -3; /* too many retry error */