?lang_form? ?lang_select? ?lang_submit? ?lang_endform?
{HEADER END}
{BLAME START}

library

?curdirlinks? -

Blame information for rev 6

Line No. Rev Author Line
1 6 kaklik /*! \file xmodem.c \brief XModem Transmit/Receive Implementation with CRC and 1K support. */
2 //*****************************************************************************
3 //
4 // File Name : 'xmodem.c'
5 // Title : XModem Transmit/Receive Implementation with CRC and 1K support
6 // Author : Pascal Stang - Copyright (C) 2006
7 // Created : 4/22/2006
8 // Revised : 7/22/2006
9 // Version : 0.1
10 // Target MCU : AVR processors
11 // Editor Tabs : 4
12 //
13 // This code is distributed under the GNU Public License
14 // which can be found at http://www.gnu.org/licenses/gpl.txt
15 //
16 //*****************************************************************************
17  
18 #include <string.h>
19 #include "rprintf.h"
20 #include "timer.h"
21  
22 #include "xmodem.h"
23  
24 //#define XMODEM_BUFFER_SIZE 128
25 #define XMODEM_BUFFER_SIZE 1024
26  
27 // pointers to stream I/O functions
28 static void (*xmodemOut)(unsigned char c);
29 static int (*xmodemIn)(void);
30  
31 void xmodemInit(void (*sendbyte_func)(unsigned char c), int (*getbyte_func)(void))
32 {
33 // assign function pointers
34 xmodemOut = sendbyte_func;
35 xmodemIn = getbyte_func;
36 }
37  
38 long xmodemReceive( int (*write)(unsigned char* buffer, int size) )
39 {
40 // create xmodem buffer
41 // 1024b for Xmodem 1K
42 // 128 bytes for Xmodem std.
43 // + 5b header/crc + NULL
44 unsigned char xmbuf[XMODEM_BUFFER_SIZE+6];
45 unsigned char seqnum=1; // xmodem sequence number starts at 1
46 unsigned short pktsize=128; // default packet size is 128 bytes
47 unsigned char response='C'; // solicit a connection with CRC enabled
48 char retry=XMODEM_RETRY_LIMIT;
49 unsigned char crcflag=0;
50 unsigned long totalbytes=0;
51 int i,c;
52  
53 while(retry > 0)
54 {
55 // solicit a connection/packet
56 xmodemOut(response);
57 // wait for start of packet
58 if( (c = xmodemInTime(XMODEM_TIMEOUT_DELAY)) >= 0)
59 {
60 switch(c)
61 {
62 case SOH:
63 pktsize = 128;
64 break;
65 #if(XMODEM_BUFFER_SIZE>=1024)
66 case STX:
67 pktsize = 1024;
68 break;
69 #endif
70 case EOT:
71 xmodemInFlush();
72 xmodemOut(ACK);
73 // completed transmission normally
74 return totalbytes;
75 case CAN:
76 if((c = xmodemInTime(XMODEM_TIMEOUT_DELAY)) == CAN)
77 {
78 xmodemInFlush();
79 xmodemOut(ACK);
80 // transaction cancelled by remote node
81 return XMODEM_ERROR_REMOTECANCEL;
82 }
83 default:
84 break;
85 }
86 }
87 else
88 {
89 // timed out, try again
90 // no need to flush because receive buffer is already empty
91 retry--;
92 //response = NAK;
93 continue;
94 }
95  
96 // check if CRC mode was accepted
97 if(response == 'C') crcflag = 1;
98 // got SOH/STX, add it to processing buffer
99 xmbuf[0] = c;
100 // try to get rest of packet
101 for(i=0; i<(pktsize+crcflag+4-1); i++)
102 {
103 if((c = xmodemInTime(XMODEM_TIMEOUT_DELAY)) >= 0)
104 {
105 xmbuf[1+i] = c;
106 }
107 else
108 {
109 // timed out, try again
110 retry--;
111 xmodemInFlush();
112 response = NAK;
113 break;
114 }
115 }
116 // packet was too small, retry
117 if(i<(pktsize+crcflag+4-1))
118 continue;
119  
120 // got whole packet
121 // check validity of packet
122 if( (xmbuf[1] == (unsigned char)(~xmbuf[2])) && // sequence number was transmitted w/o error
123 xmodemCrcCheck(crcflag, &xmbuf[3], pktsize) ) // packet is not corrupt
124 {
125 // is this the packet we were waiting for?
126 if(xmbuf[1] == seqnum)
127 {
128 // write/deliver data
129 write(&xmbuf[3], pktsize);
130 //spiflashWrite(flashaddr, pktsize, &xmbuf[3]);
131 totalbytes += pktsize;
132 // next sequence number
133 seqnum++;
134 // reset retries
135 retry = XMODEM_RETRY_LIMIT;
136 // reply with ACK
137 response = ACK;
138 continue;
139 }
140 else if(xmbuf[1] == (unsigned char)(seqnum-1))
141 {
142 // this is a retransmission of the last packet
143 // ACK and move on
144 response = ACK;
145 continue;
146 }
147 else
148 {
149 // we are completely out of sync
150 // cancel transmission
151 xmodemInFlush();
152 xmodemOut(CAN);
153 xmodemOut(CAN);
154 xmodemOut(CAN);
155 return XMODEM_ERROR_OUTOFSYNC;
156 }
157 }
158 else
159 {
160 // packet was corrupt
161 // NAK it and try again
162 retry--;
163 xmodemInFlush();
164 response = NAK;
165 continue;
166 }
167 }
168  
169 // exceeded retry count
170 xmodemInFlush();
171 xmodemOut(CAN);
172 xmodemOut(CAN);
173 xmodemOut(CAN);
174 return XMODEM_ERROR_RETRYEXCEED;
175 }
176  
177  
178 long xmodemTransmit( int (*read)(unsigned char* buffer, int size) )
179 {
180 // still to be written
181 return 0;
182 }
183  
184 uint16_t crc_xmodem_update(uint16_t crc, uint8_t data)
185 {
186 int i;
187  
188 crc = crc ^ ((uint16_t)data << 8);
189 for (i=0; i<8; i++)
190 {
191 if(crc & 0x8000)
192 crc = (crc << 1) ^ 0x1021;
193 else
194 crc <<= 1;
195 }
196  
197 return crc;
198 }
199  
200 int xmodemCrcCheck(int crcflag, const unsigned char *buffer, int size)
201 {
202 // crcflag=0 - do regular checksum
203 // crcflag=1 - do CRC checksum
204  
205 if(crcflag)
206 {
207 unsigned short crc=0;
208 unsigned short pktcrc = (buffer[size]<<8)+buffer[size+1];
209 // do CRC checksum
210 while(size--)
211 crc = crc_xmodem_update(crc, *buffer++);
212 // check checksum against packet
213 if(crc == pktcrc)
214 return 1;
215 }
216 else
217 {
218 int i;
219 unsigned char cksum = 0;
220 // do regular checksum
221 for(i=0; i<size; ++i)
222 {
223 cksum += buffer[i];
224 }
225 // check checksum against packet
226 if(cksum == buffer[size])
227 return 1;
228 }
229  
230 return 0;
231 }
232  
233  
234 int xmodemInTime(unsigned short timeout)
235 {
236 int c=-1;
237  
238 while( (timeout--) && ((c=xmodemIn()) < 0) )
239 timerPause(1);
240  
241 return c;
242 }
243  
244 void xmodemInFlush(void)
245 {
246 while(xmodemInTime(XMODEM_TIMEOUT_DELAY) >= 0);
247 }
{BLAME END}
{FOOTER START}

Powered by WebSVN v2.8.3