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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 static int _inbyte(int msec)
26 while (!uart8250_can_rx_byte(CONFIG_TTYS0_BASE)) {
31 return uart8250_rx_byte(CONFIG_TTYS0_BASE);
34 static void _outbyte(unsigned char c)
36 uart8250_tx_byte(CONFIG_TTYS0_BASE, c);
39 static unsigned short crc16_ccitt(const unsigned char *buf, int sz)
41 unsigned short crc = 0;
44 crc ^= (unsigned short) *buf++ << 8;
45 for (i = 0; i < 8; i++)
47 crc = crc << 1 ^ 0x1021;
65 static int check(int crc, const unsigned char *buf, int sz)
68 unsigned short crc = crc16_ccitt(buf, sz);
69 unsigned short tcrc = (buf[sz]<<8)+buf[sz+1];
75 unsigned char cks = 0;
76 for (i = 0; i < sz; ++i) {
86 static void flushinput(void)
88 while (_inbyte(((DLY_1S)*3)>>1) >= 0)
92 int xmodemReceive(unsigned char *dest, int destsz)
94 unsigned char xbuff[1030]; /* 1024 for XModem 1k + 3 head chars + 2 crc + nul */
97 unsigned char trychar = 'C';
98 unsigned char packetno = 1;
100 int retry, retrans = MAXRETRANS;
103 for( retry = 0; retry < 16; ++retry) {
104 if (trychar) _outbyte(trychar);
105 if ((c = _inbyte((DLY_1S)<<1)) >= 0) {
116 return len; /* normal end */
118 if ((c = _inbyte(DLY_1S)) == CAN) {
121 return -1; /* canceled by remote */
129 if (trychar == 'C') { trychar = NAK; continue; }
134 return -2; /* sync error */
137 if (trychar == 'C') crc = 1;
141 for (i = 0; i < (bufsz+(crc?1:0)+3); ++i) {
142 if ((c = _inbyte(DLY_1S)) < 0) goto reject;
146 if (xbuff[1] == (unsigned char)(~xbuff[2]) &&
147 (xbuff[1] == packetno || xbuff[1] == (unsigned char)packetno-1) &&
148 check(crc, &xbuff[3], bufsz)) {
149 if (xbuff[1] == packetno) {
150 register int count = destsz - len;
151 if (count > bufsz) count = bufsz;
153 memcpy (&dest[len], &xbuff[3], count);
157 retrans = MAXRETRANS+1;
159 if (--retrans <= 0) {
164 return -3; /* too many retry error */