?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 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2 <html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
3 <title>Procyon AVRlib: xmodem.c Source File</title>
4 <link href="dox.css" rel="stylesheet" type="text/css">
5 </head><body>
6 <!-- Generated by Doxygen 1.4.2 -->
7 <div class="qindex"><a class="qindex" href="main.html">Main&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="dirs.html">Directories</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="globals.html">Globals</a> | <a class="qindex" href="pages.html">Related&nbsp;Pages</a></div>
8 <h1>xmodem.c</h1><a href="xmodem_8c.html">Go to the documentation of this file.</a><div class="fragment"><pre class="fragment">00001 <span class="comment">/*! \file xmodem.c \brief XModem Transmit/Receive Implementation with CRC and 1K support. */</span>
9 00002 <span class="comment">//*****************************************************************************</span>
10 00003 <span class="comment">//</span>
11 00004 <span class="comment">// File Name : 'xmodem.c'</span>
12 00005 <span class="comment">// Title : XModem Transmit/Receive Implementation with CRC and 1K support</span>
13 00006 <span class="comment">// Author : Pascal Stang - Copyright (C) 2006</span>
14 00007 <span class="comment">// Created : 4/22/2006</span>
15 00008 <span class="comment">// Revised : 7/22/2006</span>
16 00009 <span class="comment">// Version : 0.1</span>
17 00010 <span class="comment">// Target MCU : AVR processors</span>
18 00011 <span class="comment">// Editor Tabs : 4</span>
19 00012 <span class="comment">//</span>
20 00013 <span class="comment">// This code is distributed under the GNU Public License</span>
21 00014 <span class="comment">// which can be found at http://www.gnu.org/licenses/gpl.txt</span>
22 00015 <span class="comment">//</span>
23 00016 <span class="comment">//*****************************************************************************</span>
24 00017
25 00018 <span class="preprocessor">#include &lt;string.h&gt;</span>
26 00019 <span class="preprocessor">#include "<a class="code" href="rprintf_8h.html">rprintf.h</a>"</span>
27 00020 <span class="preprocessor">#include "<a class="code" href="timer_8h.html">timer.h</a>"</span>
28 00021
29 00022 <span class="preprocessor">#include "<a class="code" href="xmodem_8h.html">xmodem.h</a>"</span>
30 00023
31 00024 <span class="comment">//#define XMODEM_BUFFER_SIZE 128</span>
32 00025 <span class="preprocessor">#define XMODEM_BUFFER_SIZE 1024</span>
33 00026 <span class="preprocessor"></span>
34 00027 <span class="comment">// pointers to stream I/O functions</span>
35 00028 <span class="keyword">static</span> void (*xmodemOut)(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> c);
36 00029 <span class="keyword">static</span> int (*xmodemIn)(void);
37 00030
38 <a name="l00031"></a><a class="code" href="group__xmodem.html#ga0">00031</a> <span class="keywordtype">void</span> <a class="code" href="group__xmodem.html#ga0">xmodemInit</a>(<span class="keywordtype">void</span> (*sendbyte_func)(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> c), <span class="keywordtype">int</span> (*getbyte_func)(<span class="keywordtype">void</span>))
39 00032 {
40 00033 <span class="comment">// assign function pointers</span>
41 00034 xmodemOut = sendbyte_func;
42 00035 xmodemIn = getbyte_func;
43 00036 }
44 00037
45 <a name="l00038"></a><a class="code" href="group__xmodem.html#ga1">00038</a> <span class="keywordtype">long</span> <a class="code" href="group__xmodem.html#ga1">xmodemReceive</a>( <span class="keywordtype">int</span> (*write)(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span>* buffer, <span class="keywordtype">int</span> size) )
46 00039 {
47 00040 <span class="comment">// create xmodem buffer</span>
48 00041 <span class="comment">// 1024b for Xmodem 1K</span>
49 00042 <span class="comment">// 128 bytes for Xmodem std.</span>
50 00043 <span class="comment">// + 5b header/crc + NULL</span>
51 00044 <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> xmbuf[XMODEM_BUFFER_SIZE+6];
52 00045 <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> seqnum=1; <span class="comment">// xmodem sequence number starts at 1</span>
53 00046 <span class="keywordtype">unsigned</span> <span class="keywordtype">short</span> pktsize=128; <span class="comment">// default packet size is 128 bytes</span>
54 00047 <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> response=<span class="charliteral">'C'</span>; <span class="comment">// solicit a connection with CRC enabled</span>
55 00048 <span class="keywordtype">char</span> retry=XMODEM_RETRY_LIMIT;
56 00049 <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> crcflag=0;
57 00050 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> totalbytes=0;
58 00051 <span class="keywordtype">int</span> i,c;
59 00052
60 00053 <span class="keywordflow">while</span>(retry &gt; 0)
61 00054 {
62 00055 <span class="comment">// solicit a connection/packet</span>
63 00056 xmodemOut(response);
64 00057 <span class="comment">// wait for start of packet</span>
65 00058 <span class="keywordflow">if</span>( (c = <a class="code" href="group__xmodem.html#ga4">xmodemInTime</a>(XMODEM_TIMEOUT_DELAY)) &gt;= 0)
66 00059 {
67 00060 <span class="keywordflow">switch</span>(c)
68 00061 {
69 00062 <span class="keywordflow">case</span> SOH:
70 00063 pktsize = 128;
71 00064 <span class="keywordflow">break</span>;
72 00065 <span class="preprocessor"> #if(XMODEM_BUFFER_SIZE&gt;=1024)</span>
73 00066 <span class="preprocessor"></span> <span class="keywordflow">case</span> STX:
74 00067 pktsize = 1024;
75 00068 <span class="keywordflow">break</span>;
76 00069 <span class="preprocessor"> #endif</span>
77 00070 <span class="preprocessor"></span> <span class="keywordflow">case</span> EOT:
78 00071 <a class="code" href="group__xmodem.html#ga5">xmodemInFlush</a>();
79 00072 xmodemOut(ACK);
80 00073 <span class="comment">// completed transmission normally</span>
81 00074 <span class="keywordflow">return</span> totalbytes;
82 00075 <span class="keywordflow">case</span> CAN:
83 00076 <span class="keywordflow">if</span>((c = <a class="code" href="group__xmodem.html#ga4">xmodemInTime</a>(XMODEM_TIMEOUT_DELAY)) == CAN)
84 00077 {
85 00078 <a class="code" href="group__xmodem.html#ga5">xmodemInFlush</a>();
86 00079 xmodemOut(ACK);
87 00080 <span class="comment">// transaction cancelled by remote node</span>
88 00081 <span class="keywordflow">return</span> XMODEM_ERROR_REMOTECANCEL;
89 00082 }
90 00083 <span class="keywordflow">default</span>:
91 00084 <span class="keywordflow">break</span>;
92 00085 }
93 00086 }
94 00087 <span class="keywordflow">else</span>
95 00088 {
96 00089 <span class="comment">// timed out, try again</span>
97 00090 <span class="comment">// no need to flush because receive buffer is already empty</span>
98 00091 retry--;
99 00092 <span class="comment">//response = NAK;</span>
100 00093 <span class="keywordflow">continue</span>;
101 00094 }
102 00095
103 00096 <span class="comment">// check if CRC mode was accepted</span>
104 00097 <span class="keywordflow">if</span>(response == <span class="charliteral">'C'</span>) crcflag = 1;
105 00098 <span class="comment">// got SOH/STX, add it to processing buffer</span>
106 00099 xmbuf[0] = c;
107 00100 <span class="comment">// try to get rest of packet</span>
108 00101 <span class="keywordflow">for</span>(i=0; i&lt;(pktsize+crcflag+4-1); i++)
109 00102 {
110 00103 <span class="keywordflow">if</span>((c = <a class="code" href="group__xmodem.html#ga4">xmodemInTime</a>(XMODEM_TIMEOUT_DELAY)) &gt;= 0)
111 00104 {
112 00105 xmbuf[1+i] = c;
113 00106 }
114 00107 <span class="keywordflow">else</span>
115 00108 {
116 00109 <span class="comment">// timed out, try again</span>
117 00110 retry--;
118 00111 <a class="code" href="group__xmodem.html#ga5">xmodemInFlush</a>();
119 00112 response = NAK;
120 00113 <span class="keywordflow">break</span>;
121 00114 }
122 00115 }
123 00116 <span class="comment">// packet was too small, retry</span>
124 00117 <span class="keywordflow">if</span>(i&lt;(pktsize+crcflag+4-1))
125 00118 <span class="keywordflow">continue</span>;
126 00119
127 00120 <span class="comment">// got whole packet</span>
128 00121 <span class="comment">// check validity of packet</span>
129 00122 <span class="keywordflow">if</span>( (xmbuf[1] == (<span class="keywordtype">unsigned</span> char)(~xmbuf[2])) &amp;&amp; <span class="comment">// sequence number was transmitted w/o error</span>
130 00123 <a class="code" href="group__xmodem.html#ga3">xmodemCrcCheck</a>(crcflag, &amp;xmbuf[3], pktsize) ) <span class="comment">// packet is not corrupt</span>
131 00124 {
132 00125 <span class="comment">// is this the packet we were waiting for?</span>
133 00126 <span class="keywordflow">if</span>(xmbuf[1] == seqnum)
134 00127 {
135 00128 <span class="comment">// write/deliver data</span>
136 00129 write(&amp;xmbuf[3], pktsize);
137 00130 <span class="comment">//spiflashWrite(flashaddr, pktsize, &amp;xmbuf[3]);</span>
138 00131 totalbytes += pktsize;
139 00132 <span class="comment">// next sequence number</span>
140 00133 seqnum++;
141 00134 <span class="comment">// reset retries</span>
142 00135 retry = XMODEM_RETRY_LIMIT;
143 00136 <span class="comment">// reply with ACK</span>
144 00137 response = ACK;
145 00138 <span class="keywordflow">continue</span>;
146 00139 }
147 00140 <span class="keywordflow">else</span> <span class="keywordflow">if</span>(xmbuf[1] == (<span class="keywordtype">unsigned</span> char)(seqnum-1))
148 00141 {
149 00142 <span class="comment">// this is a retransmission of the last packet</span>
150 00143 <span class="comment">// ACK and move on</span>
151 00144 response = ACK;
152 00145 <span class="keywordflow">continue</span>;
153 00146 }
154 00147 <span class="keywordflow">else</span>
155 00148 {
156 00149 <span class="comment">// we are completely out of sync</span>
157 00150 <span class="comment">// cancel transmission</span>
158 00151 <a class="code" href="group__xmodem.html#ga5">xmodemInFlush</a>();
159 00152 xmodemOut(CAN);
160 00153 xmodemOut(CAN);
161 00154 xmodemOut(CAN);
162 00155 <span class="keywordflow">return</span> XMODEM_ERROR_OUTOFSYNC;
163 00156 }
164 00157 }
165 00158 <span class="keywordflow">else</span>
166 00159 {
167 00160 <span class="comment">// packet was corrupt</span>
168 00161 <span class="comment">// NAK it and try again</span>
169 00162 retry--;
170 00163 <a class="code" href="group__xmodem.html#ga5">xmodemInFlush</a>();
171 00164 response = NAK;
172 00165 <span class="keywordflow">continue</span>;
173 00166 }
174 00167 }
175 00168
176 00169 <span class="comment">// exceeded retry count</span>
177 00170 <a class="code" href="group__xmodem.html#ga5">xmodemInFlush</a>();
178 00171 xmodemOut(CAN);
179 00172 xmodemOut(CAN);
180 00173 xmodemOut(CAN);
181 00174 <span class="keywordflow">return</span> XMODEM_ERROR_RETRYEXCEED;
182 00175 }
183 00176
184 00177
185 <a name="l00178"></a><a class="code" href="group__xmodem.html#ga2">00178</a> <span class="keywordtype">long</span> <a class="code" href="group__xmodem.html#ga2">xmodemTransmit</a>( <span class="keywordtype">int</span> (*read)(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span>* buffer, <span class="keywordtype">int</span> size) )
186 00179 {
187 00180 <span class="comment">// still to be written</span>
188 00181 <span class="keywordflow">return</span> 0;
189 00182 }
190 00183
191 00184 uint16_t crc_xmodem_update(uint16_t crc, uint8_t data)
192 00185 {
193 00186 <span class="keywordtype">int</span> i;
194 00187
195 00188 crc = crc ^ ((uint16_t)data &lt;&lt; 8);
196 00189 <span class="keywordflow">for</span> (i=0; i&lt;8; i++)
197 00190 {
198 00191 <span class="keywordflow">if</span>(crc &amp; 0x8000)
199 00192 crc = (crc &lt;&lt; 1) ^ 0x1021;
200 00193 <span class="keywordflow">else</span>
201 00194 crc &lt;&lt;= 1;
202 00195 }
203 00196
204 00197 <span class="keywordflow">return</span> crc;
205 00198 }
206 00199
207 <a name="l00200"></a><a class="code" href="group__xmodem.html#ga3">00200</a> <span class="keywordtype">int</span> <a class="code" href="group__xmodem.html#ga3">xmodemCrcCheck</a>(<span class="keywordtype">int</span> crcflag, <span class="keyword">const</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *buffer, <span class="keywordtype">int</span> size)
208 00201 {
209 00202 <span class="comment">// crcflag=0 - do regular checksum</span>
210 00203 <span class="comment">// crcflag=1 - do CRC checksum</span>
211 00204
212 00205 <span class="keywordflow">if</span>(crcflag)
213 00206 {
214 00207 <span class="keywordtype">unsigned</span> <span class="keywordtype">short</span> crc=0;
215 00208 <span class="keywordtype">unsigned</span> <span class="keywordtype">short</span> pktcrc = (buffer[size]&lt;&lt;8)+buffer[size+1];
216 00209 <span class="comment">// do CRC checksum</span>
217 00210 <span class="keywordflow">while</span>(size--)
218 00211 crc = crc_xmodem_update(crc, *buffer++);
219 00212 <span class="comment">// check checksum against packet</span>
220 00213 <span class="keywordflow">if</span>(crc == pktcrc)
221 00214 <span class="keywordflow">return</span> 1;
222 00215 }
223 00216 <span class="keywordflow">else</span>
224 00217 {
225 00218 <span class="keywordtype">int</span> i;
226 00219 <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> cksum = 0;
227 00220 <span class="comment">// do regular checksum</span>
228 00221 <span class="keywordflow">for</span>(i=0; i&lt;size; ++i)
229 00222 {
230 00223 cksum += buffer[i];
231 00224 }
232 00225 <span class="comment">// check checksum against packet</span>
233 00226 <span class="keywordflow">if</span>(cksum == buffer[size])
234 00227 <span class="keywordflow">return</span> 1;
235 00228 }
236 00229
237 00230 <span class="keywordflow">return</span> 0;
238 00231 }
239 00232
240 00233
241 <a name="l00234"></a><a class="code" href="group__xmodem.html#ga4">00234</a> <span class="keywordtype">int</span> <a class="code" href="group__xmodem.html#ga4">xmodemInTime</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">short</span> timeout)
242 00235 {
243 00236 <span class="keywordtype">int</span> c=-1;
244 00237
245 00238 <span class="keywordflow">while</span>( (timeout--) &amp;&amp; ((c=xmodemIn()) &lt; 0) )
246 00239 <a class="code" href="group__timer.html#ga10">timerPause</a>(1);
247 00240
248 00241 <span class="keywordflow">return</span> c;
249 00242 }
250 00243
251 <a name="l00244"></a><a class="code" href="group__xmodem.html#ga5">00244</a> <span class="keywordtype">void</span> <a class="code" href="group__xmodem.html#ga5">xmodemInFlush</a>(<span class="keywordtype">void</span>)
252 00245 {
253 00246 <span class="keywordflow">while</span>(<a class="code" href="group__xmodem.html#ga4">xmodemInTime</a>(XMODEM_TIMEOUT_DELAY) &gt;= 0);
254 00247 }
255 </pre></div><hr size="1"><address style="align: right;"><small>Generated on Sun Oct 29 03:41:08 2006 for Procyon AVRlib by&nbsp;
256 <a href="http://www.doxygen.org/index.html">
257 <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.2 </small></address>
258 </body>
259 </html>
{BLAME END}
{FOOTER START}

Powered by WebSVN v2.8.3