?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&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>
<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 &lt;string.h&gt;</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 &gt; 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)) &gt;= 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&gt;=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&lt;(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)) &gt;= 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&lt;(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])) &amp;&amp;     <span class="comment">// sequence number was transmitted w/o error</span>
00123             <a class="code" href="group__xmodem.html#ga3">xmodemCrcCheck</a>(crcflag, &amp;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(&amp;xmbuf[3], pktsize);
00130                 <span class="comment">//spiflashWrite(flashaddr, pktsize, &amp;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 &lt;&lt; 8);
00189     <span class="keywordflow">for</span> (i=0; i&lt;8; i++)
00190     {
00191         <span class="keywordflow">if</span>(crc &amp; 0x8000)
00192             crc = (crc &lt;&lt; 1) ^ 0x1021;
00193         <span class="keywordflow">else</span>
00194             crc &lt;&lt;= 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]&lt;&lt;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&lt;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--) &amp;&amp; ((c=xmodemIn()) &lt; 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) &gt;= 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&nbsp;
<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