?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 stxetx.c \brief STX/ETX Packet Protocol Implementation Library. */
2 //*****************************************************************************
3 //
4 // File Name : 'stxetx.c'
5 // Title : STX/ETX Packet Protocol Implementation Library
6 // Author : Pascal Stang - Copyright (C) 2002
7 // Created : 10/9/2002
8 // Revised : 6/30/2003
9 // Version : 0.1
10 // Target MCU : any
11 // Editor Tabs : 4
12 //
13 // Description : This library provides a set of functions needed to send and
14 // receive STX/ETX packets. STX/ETX is a simple packet protocol that can
15 // be wrapped around user data for one or more of the following reasons:
16 //
17 // 1. packetization is needed
18 // - Using packets can be helpful if your data naturally forms
19 // little "bunches" or if different types of data must be sent
20 // over the same channel (a serial cable, for example). If your
21 // data forms "bunches", you can send user data inside STX/ETX
22 // packets with a predetermined structure, like an array of A/D
23 // conversion results. If you need a way to tell the receiver
24 // what kind of data you're sending, you can use the TYPE field
25 // in the STX/ETX packet.
26 // 2. error checking is needed
27 // - STX/ETX packets will add a checksum to your data. This
28 // allows the receiver to verify that data was received correctly
29 // and is error-free. Packets which are corrupted in transmission
30 // and fail the the checksum test are automatically discarded.
31 // Error checking is especially useful when the data transmission
32 // channel is unreliable or noisy (examples: radio, infrared, long
33 // cables, etc)
34 //
35 // STX/ETX packets have the following structure:
36 //
37 // [STX][status][type][length][user data...][checksum][ETX]
38 //
39 // All fields are 1 byte except for user data which may be 0-255 bytes.
40 // Uppercase fields are constant (STX=0x02, ETX=0x03), lowercase fields
41 // vary. The length field is the number of bytes in the user data area.
42 // The checksum is the 8-bit sum of all bytes between but not including
43 // STX/ETX.
44 //
45 // This code is distributed under the GNU Public License
46 // which can be found at http://www.gnu.org/licenses/gpl.txt
47 //
48 //*****************************************************************************
49  
50 #include "global.h"
51 #include "stxetx.h"
52 //#include "rprintf.h"
53  
54 // function pointer to data output routine
55 static void (*stxetxDataOut)(unsigned char data);
56  
57 // received packet data buffer
58 unsigned char stxetxRxPacket[STXETX_MAXRXPACKETSIZE];
59  
60 // functions
61  
62  
63 // Initialize STX/ETX packet protocol library
64 void stxetxInit(void (*dataout_func)(unsigned char data))
65 {
66 stxetxDataOut = dataout_func;
67 }
68  
69 // Send/Create STX/ETX packet
70 void stxetxSend(unsigned char status, unsigned char type, unsigned char datalength, unsigned char* dataptr)
71 {
72 unsigned char checksum = 0;
73 unsigned short i;
74  
75 // write packet header
76 stxetxDataOut(STX);
77 stxetxDataOut(status);
78 stxetxDataOut(type);
79 stxetxDataOut(datalength);
80 // update checksum
81 checksum += status + type + datalength;
82 // copy data into packet
83 for(i = 0; i < datalength; i++)
84 {
85 stxetxDataOut(*dataptr);
86 checksum += *dataptr;
87 dataptr++;
88 }
89 // write packet trailer
90 stxetxDataOut(checksum);
91 stxetxDataOut(ETX);
92 }
93  
94 // process buffer containing STX/ETX packets
95 unsigned char stxetxProcess(cBuffer* rxBuffer)
96 {
97 unsigned char foundpacket = FALSE;
98 unsigned short i;
99 unsigned char length, checksum;
100 //unsigned char type;
101  
102 // process the buffer
103 // go through buffer looking for packets
104 // the STX must be located at least STXETX_HEADERLENGTH+STXETX_TRAILERLENGTH from end
105 // otherwise we must not have a complete packet
106 while( rxBuffer->datalength >= ((u16)STXETX_HEADERLENGTH+(u16)STXETX_TRAILERLENGTH) )
107 {
108 // look for a potential start of packet
109 if(bufferGetAtIndex(rxBuffer, 0) == STX)
110 {
111 // if this is a start, then get the length
112 length = bufferGetAtIndex(rxBuffer, STXETX_LENGTHOFFSET);
113  
114 // now we must have at least STXETX_HEADERLENGTH+length+STXETX_TRAILERLENGTH in buffer to continue
115 if(rxBuffer->datalength >= ((u16)STXETX_HEADERLENGTH+length+(u16)STXETX_TRAILERLENGTH))
116 {
117 // check to see if ETX is in the right position
118 if(bufferGetAtIndex(rxBuffer, STXETX_HEADERLENGTH+length+STXETX_TRAILERLENGTH-1) == ETX)
119 {
120 // found potential packet
121 // test checksum
122 checksum = 0;
123 // sum data between STX and ETX, not including checksum itself
124 // (u16) casting needed to avoid unsigned/signed mismatch
125 for(i = 0; i<((u16)STXETX_HEADERLENGTH+length+(u16)STXETX_TRAILERLENGTH-(u16)STXETX_NOETXSTXCHECKSUM); i++)
126 {
127 checksum += bufferGetAtIndex(rxBuffer, i+STXETX_STATUSOFFSET);
128 }
129 // compare checksums
130 if(checksum == bufferGetAtIndex(rxBuffer, STXETX_CHECKSUMOFFSET+length))
131 {
132 //we have a packet!
133 foundpacket = TRUE;
134  
135 // copy data to buffer
136 // (don't copy STX, ETX, or CHECKSUM)
137 for(i = 0; i < ((u16)STXETX_HEADERLENGTH+length-1); i++)
138 {
139 stxetxRxPacket[i] = bufferGetAtIndex(rxBuffer, i+1);
140 }
141  
142 // debug
143 //rprintf("STXETX Received packet type: 0x%x\n", bufferGetAtIndex(rxBuffer, STXETX_TYPEOFFSET));
144  
145 // dump this packet from the
146 bufferDumpFromFront(rxBuffer, STXETX_HEADERLENGTH+length+STXETX_TRAILERLENGTH);
147  
148 // done with this processing session
149 break;
150 }
151 else
152 {
153 // checksum bad
154 //rprintf("STXETX Received packet with bad checksum\r\n");
155 // for now, we dump these
156 // dump this STX
157 bufferGetFromFront(rxBuffer);
158 }
159 }
160 else
161 {
162 // no ETX or ETX in wrong position
163 // dump this STX
164 bufferGetFromFront(rxBuffer);
165 }
166 }
167 else
168 {
169 // not enough data in buffer to decode pending packet
170 // wait until next time
171 break;
172 }
173 }
174 else
175 {
176 // this is not a start, dump it
177 bufferGetFromFront(rxBuffer);
178 }
179 }
180  
181 // check if receive buffer is full with no packets decoding
182 // (ie. deadlocked on garbage data or packet that exceeds buffer size)
183 if(!bufferIsNotFull(rxBuffer))
184 {
185 // dump receive buffer contents to relieve deadlock
186 bufferFlush(rxBuffer);
187 }
188  
189 return foundpacket;
190 }
191  
192 unsigned char stxetxGetRxPacketStatus(void)
193 {
194 // return the packet's status
195 // (subtract 1 from the offset because the STX has already been discarded)
196 return stxetxRxPacket[STXETX_STATUSOFFSET-1];
197 }
198  
199 unsigned char stxetxGetRxPacketType(void)
200 {
201 // return the packet's type
202 // (subtract 1 from the offset because the STX has already been discarded)
203 return stxetxRxPacket[STXETX_TYPEOFFSET-1];
204 }
205  
206 unsigned char stxetxGetRxPacketDatalength(void)
207 {
208 // return the packet's datalength
209 // (subtract 1 from the offset because the STX has already been discarded)
210 return stxetxRxPacket[STXETX_LENGTHOFFSET-1];
211 }
212  
213 unsigned char* stxetxGetRxPacketData(void)
214 {
215 // return a pointer to the packet's data payload
216 // (subtract 1 from the offset because the STX has already been discarded)
217 return stxetxRxPacket+STXETX_DATAOFFSET-1;
218 }
{BLAME END}
{FOOTER START}

Powered by WebSVN v2.8.3