Main Page   Modules   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

/projects/cubeos/src_current/net/rsm.c

Go to the documentation of this file.
00001 /*  src_experimental/net/rsm.c
00002    CubeOS Version 0.4.90 experimental
00003    Copyright (C) 1999,2000 Holger Kenn
00004 
00005    CubeOS is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or any later version.
00009 
00010    CubeOS is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015  */
00016 // 
00017 // Radio State machine for CubeOS
00018 //
00019 
00024 #include <rsm.h>
00025 #include <rdio.h>
00026 #include <cubeos.h>
00027 //#include <conio.h>
00028 #include <stdio.h>
00029 #include <ttyio.h>
00030 
00031 //
00032 // A frame for the RSM looks like this:
00033 //
00034 // 00 ff 00 ff ... 00 ff SOH E1 E2 E1 E2 E1 E2 ... E1 E2 C1 C2
00035 //
00036 // There are exactly RMS_FRAMELEN E1/E2 pairs, each one encoding one byte
00037 // The C1/C2 bytes represent the encoded 8-bit checksum of the frame
00038 //
00039 // At the moment, no escaping of the SOH byte is done, so the protocol
00040 // may get stuck.
00041 //
00042 
00043 // States of the RSM
00044 
00045 #define RSM_OFF 0
00046 #define RSM_IDLE 1
00047 #define RSM_INFRAME1 2
00048 #define RSM_INFRAME2 3
00049 #define RSM_CHECKSUM1 4
00050 #define RSM_CHECKSUM2 5
00051 
00052 // Start of Header
00053 #define RSM_SOH 0xA5
00054 
00055 #define RSM_PREHEADER 6         //Number of 0x00 0xff in preheader
00056 
00057 //#define RSM_DEBUG
00058 
00059 // variables
00060 
00061 // buffers
00062 char _RSM_buffer0[RSM_FRAMELEN];
00063 char _RSM_buffer1[RSM_FRAMELEN];
00064 
00065 // internal
00066 unsigned char _RSM_state = 0;
00067 //unsigned char _RSM_enabled = 0;
00068 short _RSM_count;
00069 char RSM_new;
00070 char *_RSM_writebuf;
00071 char *RSM_getbuf;
00072 unsigned char _RSM_checksum;
00073 unsigned char _RSM_charcount;
00074 
00075 // statistics
00076 int RSM_good;
00077 int _RSM_bad;
00078 int _RSM_ugly;
00079 int _RSM_bytes;
00080 int _RSM_uglycount;
00081 
00082 // function prototypes: user interface
00083 
00084 int RSM_init_rx ();
00085 int RSM_init_tx ();
00086 int RSM_getframe (unsigned char *buffer);
00087 int RSM_send_frame (unsigned char *buffer);
00088 
00089 
00090 // function prototypes: for internal use only
00091 
00092 void _RSM_doutchar (unsigned char c);
00093 void _RSM_douthex (unsigned char c);
00094 void RSM_process (unsigned char c);
00095 void RSM_tty_rdioput_block (char byte);
00096 unsigned char *RSM_rxframe (unsigned char *frame);
00097 
00098 
00099 // function implementations
00100 
00105 int RSM_init_rx ()
00106 {
00107 #ifdef DUART_BASE
00108         _RSM_writebuf = _RSM_buffer0;
00109         RSM_getbuf = _RSM_buffer1;
00110         _RSM_state = RSM_IDLE;
00111         RSM_good = 0;
00112         _RSM_bad = 0;
00113         _RSM_ugly = 0;
00114         _RSM_bytes = 0;
00115         _RSM_uglycount = 0;
00116         RSM_new = 0;
00117         _RSM_charcount = 0;
00118 //      _RSM_enabled = 1;       /* redirect to RSM_process() */
00119         TTY_tty[1].char_process = RSM_process; /* enable char processor */
00120         clearRTXSEL ();         /* disable transmitter */
00121         setRRXSEL ();           /* enable receiver */
00122         RSM_rdio_enable_rx ();  /* Enable reception IRQ */
00123         return 0;
00124 #else
00125         return -1;
00126 #endif
00127 }
00128 
00129 
00134 int RSM_deinitrx ()
00135 {
00136 #ifdef DUART_BASE
00137         clearRRXSEL ();         /* disable receiver */
00138 //      _RSM_enabled = 0;       /* redirect to RSM_process() */
00139         TTY_tty[1].char_process = NULL; /* disable char processor */
00140         _RSM_state = RSM_IDLE;  /* back to idle state */
00141         RSM_rdio_disable_rx (); /* disable reception IRQ */
00142         return 0;
00143 #else
00144         return -1;
00145 #endif
00146 }
00147 
00152 int RSM_init_tx ()
00153 {
00154 #ifdef DUART_BASE
00155         clearRRXSEL ();         /* disable receiver */
00156         setRTXSEL ();           /* enable transmitter */
00157         RSM_rdio_disable_rx (); /* disable RX ISR */
00158 //      _RSM_enabled = 0;       /* and redirect to rdio queue */
00159         TTY_tty[1].char_process = NULL; /* disable char processor */
00160 
00161         return 0;
00162 #else
00163         return -1;
00164 #endif
00165 }
00166 
00171 int RSM_deinittx ()
00172 {
00173 #ifdef DUART_BASE
00174         RSM_rdio_flush ();
00175         clearRTXSEL ();         /* disable transmitter */
00176         return 0;
00177 #else
00178         return -1;
00179 #endif
00180 }
00181 
00182 #ifdef RSM_DEBUG
00183 
00188 void _RSM_doutchar (unsigned char c)
00189 {
00190         iTTY_outchar (c);
00191 }
00192 
00197 void _RSM_douthex (unsigned char c)
00198 {
00199         char l;
00200         char h;
00201 
00202         h = (c & 0xf0) >> 4;
00203         if (h < 10) {
00204                 _RSM_doutchar ('0' + h);
00205         } else {
00206                 _RSM_doutchar ('A' + h - 10);
00207         }
00208         l = (c & 0x0f);
00209         if (l < 10) {
00210                 _RSM_doutchar ('0' + l);
00211         } else {
00212                 _RSM_doutchar ('A' + l - 10);
00213         }
00214 }
00215 
00216 #else
00217 void _RSM_doutchar (unsigned char c)
00218 {
00219 }
00220 void _RSM_douthex (unsigned char c)
00221 {
00222 }
00223 
00224 #endif
00225 
00226 #ifdef DUART_BASE
00227 
00232 void RSM_process (unsigned char c)
00233 {                               /* this is called from the duart irq */
00234         static unsigned char save;
00235         unsigned char cx;
00236 
00237         _RSM_bytes++;           // byte statistics
00238 
00239         switch (_RSM_state) {
00240         case RSM_IDLE:
00241                 if (c == RSM_SOH) {
00242                         _RSM_state = RSM_INFRAME1;
00243                         _RSM_count = 0;
00244                         _RSM_checksum = 0;
00245                         _RSM_doutchar ('X');
00246                 }
00247                 break;
00248 
00249         case RSM_INFRAME1:
00250                 if ((c & 0xAA) != ((~((c << 1) | 0x55)) & 0xff)) {
00251                         _RSM_state = RSM_IDLE;
00252                         _RSM_uglycount = _RSM_count;
00253                         _RSM_ugly++;
00254                         _RSM_doutchar ('u');
00255                         break;
00256                 }
00257                 save = c;
00258                 _RSM_state = RSM_INFRAME2;
00259                 break;
00260 
00261         case RSM_INFRAME2:
00262                 if ((c & 0xAA) != ((~((c << 1) | 0x55)) & 0xff)) {
00263                         _RSM_state = RSM_IDLE;
00264                         _RSM_uglycount = _RSM_count;
00265                         _RSM_ugly++;
00266                         _RSM_doutchar ('U');
00267                         break;
00268                 }
00269                 cx = ((save & 0xAA) | (c & 0x55));
00270                 _RSM_writebuf[_RSM_count++] = cx;
00271                 _RSM_checksum += cx;
00272 
00273                 if (_RSM_count >= RSM_FRAMELEN) {
00274                         _RSM_state = RSM_CHECKSUM1;
00275                         break;
00276                 }
00277                 _RSM_state = RSM_INFRAME1;
00278                 break;
00279 
00280         case RSM_CHECKSUM1:
00281                 save = c;
00282                 _RSM_state = RSM_CHECKSUM2;
00283                 break;
00284 
00285         case RSM_CHECKSUM2:
00286                 if (
00287                       ((save & 0xAA) != ((~((save << 1) | 0x55)) & 0xff)) ||
00288                            ((c & 0xAA) != ((~((c << 1) | 0x55)) & 0xff))
00289                         ) {
00290                         _RSM_state = RSM_IDLE;
00291                         _RSM_uglycount = _RSM_count;
00292                         _RSM_ugly++;
00293                         _RSM_doutchar ('U');
00294                         _RSM_doutchar ('c');
00295                         break;
00296                 }
00297                 cx = ((save & 0xAA) | (c & 0x55));
00298                 if (cx == _RSM_checksum) {
00299                         _RSM_doutchar ('G');
00300                         _RSM_douthex (cx);
00301                         _RSM_doutchar ('\n');
00302                         RSM_good++;
00303 
00304 //                      bufsave = RSM_getbuf;
00305                         //                      RSM_getbuf = _RSM_writebuf;
00306                         //                      _RSM_writebuf = bufsave;
00307                         //                      RSM_new = 1;
00308                         _RSM_writebuf = RSM_rxframe (_RSM_writebuf);
00309                         if (_RSM_writebuf == NULL) {    /* we did not get a new buffer, so we 
00310                                                            disable the reception */
00311                                 RSM_rdio_disable_rx ();
00312                                 _RSM_doutchar ('N');
00313                         }
00314                 } else {
00315                         _RSM_bad++;
00316                         _RSM_doutchar ('B');
00317                         _RSM_douthex (cx);
00318                         _RSM_doutchar ('e');
00319                         _RSM_douthex (_RSM_checksum);
00320                         _RSM_doutchar ('\n');
00321                 }
00322                 _RSM_state = RSM_IDLE;
00323         }
00324 }
00325 
00326 
00327 // this implements a simple double buffer scheme. One gets written, the other 
00328 // can be read
00329 #endif
00330 
00331 
00336 unsigned char *RSM_rxframe (unsigned char *rxframebuf)
00337 {
00338         unsigned char *bufsave;
00339 
00340         bufsave = RSM_getbuf;
00341         RSM_getbuf = rxframebuf;        // this is the pointer to the frame just received
00342 
00343         RSM_new = 1;            // new frame available
00344 
00345         return (bufsave);       // we return the previous getbuf
00346 
00347 }
00348 
00353 int RSM_getframe (unsigned char *buffer)
00354 {
00355         int i;
00356 
00357         if (!RSM_new)
00358                 return (-1);
00359         disable ();
00360         for (i = 0; i < RSM_FRAMELEN; i++)
00361                 buffer[i] = RSM_getbuf[i];
00362         RSM_new = 0;
00363         enable ();
00364 
00365         return (0);
00366 
00367 }
00368 
00374 unsigned char *RSM_encode (unsigned char c)
00375 {
00376         static unsigned char buf[2];
00377 
00378         unsigned char t, hi, lo;
00379 
00380         t = (c & 0xaa);
00381         hi = t | ((~(t >> 1)) & 0x55);
00382         t = (c & 0x55);
00383         lo = t | ((~(t << 1)) & 0xaa);
00384         *buf = hi;
00385         *(buf + 1) = lo;
00386         return buf;
00387 
00388 }
00389 
00395 void RSM_tty_rdioput_block (char c)
00396 {
00397 #ifdef DUART_BASE
00398         int i;
00399         i = 0;
00400         while (TTY_rdioput (c)) {
00401                 i++;
00402                 if (i > 1000) {
00403                         //_RSM_doutchar('B');
00404                 }
00405         }
00406 #endif
00407 
00408 }
00409 
00414 int RSM_send_frame (unsigned char *buffer)
00415 {
00416 
00417         unsigned char *buf;
00418         int i;
00419         unsigned char checksum;
00420 
00421 
00422         for (i = 1; i < RSM_PREHEADER; i++);
00423         {
00424                 RSM_tty_rdioput_block (0x00);
00425                 RSM_tty_rdioput_block (0xff);
00426         }
00427 
00428         checksum = 0;
00429 
00430         RSM_tty_rdioput_block (RSM_SOH);
00431 
00432         for (i = 0; i < RSM_FRAMELEN; i++) {
00433                 buf = RSM_encode (buffer[i]);
00434                 RSM_tty_rdioput_block (buf[0]);
00435                 RSM_tty_rdioput_block (buf[1]);
00436                 checksum += buffer[i];
00437         }
00438 
00439         buf = RSM_encode (checksum);
00440 
00441         RSM_tty_rdioput_block (buf[0]);
00442         RSM_tty_rdioput_block (buf[1]);
00443         return (0);
00444 
00445 }

Generated on Thu Feb 20 15:38:46 2003 for cubeOS by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002