?lang_form?
?lang_select?
?lang_submit?
?lang_endform?
{HEADER END}
{FILE START}
library
?curdirlinks? - Rev 6
?prevdifflink? - Blame - ?getfile?
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>Procyon AVRlib: xmodem.c Source File</title>
<link href="dox.css" rel="stylesheet" type="text/css">
</head><body>
<!-- Generated by Doxygen 1.4.2 -->
<div class="qindex"><a class="qindex" href="main.html">Main Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data Structures</a> | <a class="qindex" href="dirs.html">Directories</a> | <a class="qindex" href="files.html">File List</a> | <a class="qindex" href="functions.html">Data Fields</a> | <a class="qindex" href="globals.html">Globals</a> | <a class="qindex" href="pages.html">Related Pages</a></div>
<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>
00002 <span class="comment">//*****************************************************************************</span>
00003 <span class="comment">//</span>
00004 <span class="comment">// File Name : 'xmodem.c'</span>
00005 <span class="comment">// Title : XModem Transmit/Receive Implementation with CRC and 1K support</span>
00006 <span class="comment">// Author : Pascal Stang - Copyright (C) 2006</span>
00007 <span class="comment">// Created : 4/22/2006</span>
00008 <span class="comment">// Revised : 7/22/2006</span>
00009 <span class="comment">// Version : 0.1</span>
00010 <span class="comment">// Target MCU : AVR processors</span>
00011 <span class="comment">// Editor Tabs : 4</span>
00012 <span class="comment">//</span>
00013 <span class="comment">// This code is distributed under the GNU Public License</span>
00014 <span class="comment">// which can be found at http://www.gnu.org/licenses/gpl.txt</span>
00015 <span class="comment">//</span>
00016 <span class="comment">//*****************************************************************************</span>
00017
00018 <span class="preprocessor">#include <string.h></span>
00019 <span class="preprocessor">#include "<a class="code" href="rprintf_8h.html">rprintf.h</a>"</span>
00020 <span class="preprocessor">#include "<a class="code" href="timer_8h.html">timer.h</a>"</span>
00021
00022 <span class="preprocessor">#include "<a class="code" href="xmodem_8h.html">xmodem.h</a>"</span>
00023
00024 <span class="comment">//#define XMODEM_BUFFER_SIZE 128</span>
00025 <span class="preprocessor">#define XMODEM_BUFFER_SIZE 1024</span>
00026 <span class="preprocessor"></span>
00027 <span class="comment">// pointers to stream I/O functions</span>
00028 <span class="keyword">static</span> void (*xmodemOut)(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> c);
00029 <span class="keyword">static</span> int (*xmodemIn)(void);
00030
<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>))
00032 {
00033 <span class="comment">// assign function pointers</span>
00034 xmodemOut = sendbyte_func;
00035 xmodemIn = getbyte_func;
00036 }
00037
<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) )
00039 {
00040 <span class="comment">// create xmodem buffer</span>
00041 <span class="comment">// 1024b for Xmodem 1K</span>
00042 <span class="comment">// 128 bytes for Xmodem std.</span>
00043 <span class="comment">// + 5b header/crc + NULL</span>
00044 <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> xmbuf[XMODEM_BUFFER_SIZE+6];
00045 <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> seqnum=1; <span class="comment">// xmodem sequence number starts at 1</span>
00046 <span class="keywordtype">unsigned</span> <span class="keywordtype">short</span> pktsize=128; <span class="comment">// default packet size is 128 bytes</span>
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>
00048 <span class="keywordtype">char</span> retry=XMODEM_RETRY_LIMIT;
00049 <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> crcflag=0;
00050 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> totalbytes=0;
00051 <span class="keywordtype">int</span> i,c;
00052
00053 <span class="keywordflow">while</span>(retry > 0)
00054 {
00055 <span class="comment">// solicit a connection/packet</span>
00056 xmodemOut(response);
00057 <span class="comment">// wait for start of packet</span>
00058 <span class="keywordflow">if</span>( (c = <a class="code" href="group__xmodem.html#ga4">xmodemInTime</a>(XMODEM_TIMEOUT_DELAY)) >= 0)
00059 {
00060 <span class="keywordflow">switch</span>(c)
00061 {
00062 <span class="keywordflow">case</span> SOH:
00063 pktsize = 128;
00064 <span class="keywordflow">break</span>;
00065 <span class="preprocessor"> #if(XMODEM_BUFFER_SIZE>=1024)</span>
00066 <span class="preprocessor"></span> <span class="keywordflow">case</span> STX:
00067 pktsize = 1024;
00068 <span class="keywordflow">break</span>;
00069 <span class="preprocessor"> #endif</span>
00070 <span class="preprocessor"></span> <span class="keywordflow">case</span> EOT:
00071 <a class="code" href="group__xmodem.html#ga5">xmodemInFlush</a>();
00072 xmodemOut(ACK);
00073 <span class="comment">// completed transmission normally</span>
00074 <span class="keywordflow">return</span> totalbytes;
00075 <span class="keywordflow">case</span> CAN:
00076 <span class="keywordflow">if</span>((c = <a class="code" href="group__xmodem.html#ga4">xmodemInTime</a>(XMODEM_TIMEOUT_DELAY)) == CAN)
00077 {
00078 <a class="code" href="group__xmodem.html#ga5">xmodemInFlush</a>();
00079 xmodemOut(ACK);
00080 <span class="comment">// transaction cancelled by remote node</span>
00081 <span class="keywordflow">return</span> XMODEM_ERROR_REMOTECANCEL;
00082 }
00083 <span class="keywordflow">default</span>:
00084 <span class="keywordflow">break</span>;
00085 }
00086 }
00087 <span class="keywordflow">else</span>
00088 {
00089 <span class="comment">// timed out, try again</span>
00090 <span class="comment">// no need to flush because receive buffer is already empty</span>
00091 retry--;
00092 <span class="comment">//response = NAK;</span>
00093 <span class="keywordflow">continue</span>;
00094 }
00095
00096 <span class="comment">// check if CRC mode was accepted</span>
00097 <span class="keywordflow">if</span>(response == <span class="charliteral">'C'</span>) crcflag = 1;
00098 <span class="comment">// got SOH/STX, add it to processing buffer</span>
00099 xmbuf[0] = c;
00100 <span class="comment">// try to get rest of packet</span>
00101 <span class="keywordflow">for</span>(i=0; i<(pktsize+crcflag+4-1); i++)
00102 {
00103 <span class="keywordflow">if</span>((c = <a class="code" href="group__xmodem.html#ga4">xmodemInTime</a>(XMODEM_TIMEOUT_DELAY)) >= 0)
00104 {
00105 xmbuf[1+i] = c;
00106 }
00107 <span class="keywordflow">else</span>
00108 {
00109 <span class="comment">// timed out, try again</span>
00110 retry--;
00111 <a class="code" href="group__xmodem.html#ga5">xmodemInFlush</a>();
00112 response = NAK;
00113 <span class="keywordflow">break</span>;
00114 }
00115 }
00116 <span class="comment">// packet was too small, retry</span>
00117 <span class="keywordflow">if</span>(i<(pktsize+crcflag+4-1))
00118 <span class="keywordflow">continue</span>;
00119
00120 <span class="comment">// got whole packet</span>
00121 <span class="comment">// check validity of packet</span>
00122 <span class="keywordflow">if</span>( (xmbuf[1] == (<span class="keywordtype">unsigned</span> char)(~xmbuf[2])) && <span class="comment">// sequence number was transmitted w/o error</span>
00123 <a class="code" href="group__xmodem.html#ga3">xmodemCrcCheck</a>(crcflag, &xmbuf[3], pktsize) ) <span class="comment">// packet is not corrupt</span>
00124 {
00125 <span class="comment">// is this the packet we were waiting for?</span>
00126 <span class="keywordflow">if</span>(xmbuf[1] == seqnum)
00127 {
00128 <span class="comment">// write/deliver data</span>
00129 write(&xmbuf[3], pktsize);
00130 <span class="comment">//spiflashWrite(flashaddr, pktsize, &xmbuf[3]);</span>
00131 totalbytes += pktsize;
00132 <span class="comment">// next sequence number</span>
00133 seqnum++;
00134 <span class="comment">// reset retries</span>
00135 retry = XMODEM_RETRY_LIMIT;
00136 <span class="comment">// reply with ACK</span>
00137 response = ACK;
00138 <span class="keywordflow">continue</span>;
00139 }
00140 <span class="keywordflow">else</span> <span class="keywordflow">if</span>(xmbuf[1] == (<span class="keywordtype">unsigned</span> char)(seqnum-1))
00141 {
00142 <span class="comment">// this is a retransmission of the last packet</span>
00143 <span class="comment">// ACK and move on</span>
00144 response = ACK;
00145 <span class="keywordflow">continue</span>;
00146 }
00147 <span class="keywordflow">else</span>
00148 {
00149 <span class="comment">// we are completely out of sync</span>
00150 <span class="comment">// cancel transmission</span>
00151 <a class="code" href="group__xmodem.html#ga5">xmodemInFlush</a>();
00152 xmodemOut(CAN);
00153 xmodemOut(CAN);
00154 xmodemOut(CAN);
00155 <span class="keywordflow">return</span> XMODEM_ERROR_OUTOFSYNC;
00156 }
00157 }
00158 <span class="keywordflow">else</span>
00159 {
00160 <span class="comment">// packet was corrupt</span>
00161 <span class="comment">// NAK it and try again</span>
00162 retry--;
00163 <a class="code" href="group__xmodem.html#ga5">xmodemInFlush</a>();
00164 response = NAK;
00165 <span class="keywordflow">continue</span>;
00166 }
00167 }
00168
00169 <span class="comment">// exceeded retry count</span>
00170 <a class="code" href="group__xmodem.html#ga5">xmodemInFlush</a>();
00171 xmodemOut(CAN);
00172 xmodemOut(CAN);
00173 xmodemOut(CAN);
00174 <span class="keywordflow">return</span> XMODEM_ERROR_RETRYEXCEED;
00175 }
00176
00177
<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) )
00179 {
00180 <span class="comment">// still to be written</span>
00181 <span class="keywordflow">return</span> 0;
00182 }
00183
00184 uint16_t crc_xmodem_update(uint16_t crc, uint8_t data)
00185 {
00186 <span class="keywordtype">int</span> i;
00187
00188 crc = crc ^ ((uint16_t)data << 8);
00189 <span class="keywordflow">for</span> (i=0; i<8; i++)
00190 {
00191 <span class="keywordflow">if</span>(crc & 0x8000)
00192 crc = (crc << 1) ^ 0x1021;
00193 <span class="keywordflow">else</span>
00194 crc <<= 1;
00195 }
00196
00197 <span class="keywordflow">return</span> crc;
00198 }
00199
<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)
00201 {
00202 <span class="comment">// crcflag=0 - do regular checksum</span>
00203 <span class="comment">// crcflag=1 - do CRC checksum</span>
00204
00205 <span class="keywordflow">if</span>(crcflag)
00206 {
00207 <span class="keywordtype">unsigned</span> <span class="keywordtype">short</span> crc=0;
00208 <span class="keywordtype">unsigned</span> <span class="keywordtype">short</span> pktcrc = (buffer[size]<<8)+buffer[size+1];
00209 <span class="comment">// do CRC checksum</span>
00210 <span class="keywordflow">while</span>(size--)
00211 crc = crc_xmodem_update(crc, *buffer++);
00212 <span class="comment">// check checksum against packet</span>
00213 <span class="keywordflow">if</span>(crc == pktcrc)
00214 <span class="keywordflow">return</span> 1;
00215 }
00216 <span class="keywordflow">else</span>
00217 {
00218 <span class="keywordtype">int</span> i;
00219 <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> cksum = 0;
00220 <span class="comment">// do regular checksum</span>
00221 <span class="keywordflow">for</span>(i=0; i<size; ++i)
00222 {
00223 cksum += buffer[i];
00224 }
00225 <span class="comment">// check checksum against packet</span>
00226 <span class="keywordflow">if</span>(cksum == buffer[size])
00227 <span class="keywordflow">return</span> 1;
00228 }
00229
00230 <span class="keywordflow">return</span> 0;
00231 }
00232
00233
<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)
00235 {
00236 <span class="keywordtype">int</span> c=-1;
00237
00238 <span class="keywordflow">while</span>( (timeout--) && ((c=xmodemIn()) < 0) )
00239 <a class="code" href="group__timer.html#ga10">timerPause</a>(1);
00240
00241 <span class="keywordflow">return</span> c;
00242 }
00243
<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>)
00245 {
00246 <span class="keywordflow">while</span>(<a class="code" href="group__xmodem.html#ga4">xmodemInTime</a>(XMODEM_TIMEOUT_DELAY) >= 0);
00247 }
</pre></div><hr size="1"><address style="align: right;"><small>Generated on Sun Oct 29 03:41:08 2006 for Procyon AVRlib by
<a href="http://www.doxygen.org/index.html">
<img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.2 </small></address>
</body>
</html>
|
{FILE END}
{FOOTER START}
Powered by WebSVN v2.8.3