?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 edp.c \brief Emerald Data Protocol System. */
2 //*****************************************************************************
3 //
4 // File Name : 'edp.c'
5 // Title : Emerald Data Protocol System
6 // Author : Pascal Stang - Copyright (C) 2003
7 // Created : 2003.07.01
8 // Revised : 2003.07.21
9 // Version : 0.1
10 // Target MCU : Atmel AVR series
11 // Editor Tabs : 4
12 //
13 // This code is distributed under the GNU Public License
14 // which can be found at http://www.gnu.org/licenses/gpl.txt
15 //
16 //*****************************************************************************
17  
18 //----- Include Files ---------------------------------------------------------
19 #include <avr/io.h> // include I/O definitions (port names, pin names, etc)
20 #include <avr/interrupt.h> // include interrupt support
21 #include <avr/pgmspace.h> // include program-space support
22  
23 #include "global.h" // include our global settings
24 #include "i2c.h" // include I2C support
25 #include "rprintf.h" // include printf function library
26  
27 #include "edp.h"
28  
29 // globals
30 // EDP master/command: response code and reply buffer
31 u08 EdpCommandResponseCode;
32 //u08 EdpCommandReplyLength;
33 u08 EdpCommandReplyBuffer[EDP_REPLY_BUFFER_SIZE];
34 u08 EdpCommandReplyChecksum;
35 // EDP slave: response code and reply buffer
36 u08 EdpSlaveResponseCode;
37 u08 EdpSlaveReplyLength;
38 u08 EdpSlaveReplyBuffer[EDP_REPLY_BUFFER_SIZE];
39 // EDP slave request handler function pointer
40 EdpSlaveHandlerFuncType edpSlaveHandlerFunc;
41  
42 // functions
43 void edpInit(void)
44 {
45 // initialize i2c interface and function library
46 i2cInit();
47 // set i2c bit rate to 30KHz
48 i2cSetBitrate(30);
49 // set the Slave Receive Handler function
50 // (this function will run whenever a master somewhere else on the bus
51 // writes data to us as a slave)
52 i2cSetSlaveReceiveHandler( edpSlaveReceiveService );
53 // set the Slave Transmit Handler function
54 // (this function will run whenever a master somewhere else on the bus
55 // attempts to read data from us as a slave)
56 i2cSetSlaveTransmitHandler( edpSlaveTransmitService );
57 }
58  
59 void edpSetSlaveHandler(EdpSlaveHandlerFuncType edpSlaveHandlerFunction)
60 {
61 edpSlaveHandlerFunc = edpSlaveHandlerFunction;
62 }
63  
64 // ************ EDP Master operations ************
65 u08 edpSendCommand(u08 deviceAddr, u08 cmdLength, EdpCommand* edpCommand)
66 {
67 EdpReply* edpCommandReply = (EdpReply*)EdpCommandReplyBuffer;
68 u08* sendData;
69 u08* replyData;
70 u08 replyLength;
71 u08 checksum;
72  
73 // initialize response variables
74 edpCommandReply->Length = 0;
75 EdpCommandReplyChecksum = 0;
76  
77 #ifdef EDP_DEBUG
78 rprintf("\r\nBegin EdpSendCommand, TWSR:0x%x\r\n",inb(TWSR));
79 #endif
80  
81 // disable TWI interrupt
82 cbi(TWCR, TWIE);
83  
84 // clear TWI interface
85 //outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK));
86  
87 // send start condition
88 i2cSendStart();
89 i2cWaitForComplete();
90 #ifdef EDP_DEBUG
91 rprintf("Sent Start, TWSR:0x%x\r\n",inb(TWSR));
92 #endif
93  
94 // send device address with write
95 i2cSendByte( (deviceAddr&0xFE) );
96 i2cWaitForComplete();
97 #ifdef EDP_DEBUG
98 rprintf("Sent Device Address+Write, TWSR:0x%x\r\n",inb(TWSR));
99 #endif
100  
101 // check if device is present and live
102 if( i2cGetStatus() != TW_MT_SLA_ACK)
103 {
104 // device did not ACK it's address, command will not continue
105 // transmit stop condition
106 // leave with TWEA on for slave receiving
107 i2cSendStop();
108 while( !(inb(TWCR) & BV(TWSTO)) );
109 #ifdef EDP_DEBUG
110 rprintf("No Device!, Sent Stop, TWSR:0x%x\r\n",inb(TWSR));
111 #endif
112 // enable TWI interrupt
113 sbi(TWCR, TWIE);
114 // return error
115 return EDP_COMMAND_NODEV;
116 }
117  
118 // send data
119 sendData = (u08*)edpCommand;
120 checksum = 0;
121 while(cmdLength)
122 {
123 i2cSendByte( *sendData );
124 i2cWaitForComplete();
125 #ifdef EDP_DEBUG
126 rprintf("Sent Data, TWSR:0x%x\r\n",inb(TWSR));
127 #endif
128 checksum += *sendData++;
129 cmdLength--;
130 }
131  
132 // send the checksum
133 i2cSendByte( ~checksum );
134 i2cWaitForComplete();
135 #ifdef EDP_DEBUG
136 rprintf("Sent Checksum, TWSR:0x%x\r\n",inb(TWSR));
137 #endif
138  
139 // send repeated start condition
140 i2cSendStart();
141 i2cWaitForComplete();
142 #ifdef EDP_DEBUG
143 rprintf("Sent Repeated Start, TWSR:0x%x\r\n",inb(TWSR));
144 #endif
145  
146 // send device address with read
147 i2cSendByte( deviceAddr|0x01 );
148 i2cWaitForComplete();
149 #ifdef EDP_DEBUG
150 rprintf("Sent Device Address+Read, TWSR:0x%x\r\n",inb(TWSR));
151 #endif
152  
153 // read response code, return NACK
154 i2cReceiveByte(FALSE);
155 i2cWaitForComplete();
156 #ifdef EDP_DEBUG
157 rprintf("Read Data, TWSR:0x%x\r\n",inb(TWSR));
158 #endif
159 EdpCommandResponseCode = i2cGetReceivedByte();
160  
161 if(EdpCommandResponseCode==EDP_RESP_DATA_REPLY)
162 {
163 // a data reply is being sent
164  
165 // send repeated start condition
166 i2cSendStart();
167 i2cWaitForComplete();
168  
169 // send device address with read
170 i2cSendByte( deviceAddr|0x01 );
171 i2cWaitForComplete();
172  
173 // get length, return ACK
174 i2cReceiveByte(TRUE);
175 i2cWaitForComplete();
176 edpCommandReply->Length = i2cGetReceivedByte();
177 // set temp variables
178 replyLength = edpCommandReply->Length;
179 replyData = edpCommandReply->Data;
180  
181 // get data, return ACKs
182 // preset checksum with the datalength byte
183 checksum = replyLength;
184 while(replyLength > 1)
185 {
186 i2cReceiveByte(TRUE); // receive data byte and return ACK
187 i2cWaitForComplete();
188 *replyData = i2cGetReceivedByte();
189 checksum += *replyData++;
190 replyLength--;
191 }
192  
193 // get last data (actually the checksum), return NACK (last-byte signal)
194 i2cReceiveByte(FALSE);
195 i2cWaitForComplete();
196 *replyData = i2cGetReceivedByte();
197 // add received checksum+1 to our checksum, the result should be zero
198 checksum += (*replyData) + 1;
199 // save the reply checksum
200 EdpCommandReplyChecksum = checksum;
201 }
202  
203 // transmit stop condition
204 // leave with TWEA on for slave receiving
205 i2cSendStop();
206 while( !(inb(TWCR) & BV(TWSTO)) );
207 #ifdef EDP_DEBUG
208 rprintf("Sent Stop, TWSR:0x%x\r\n",inb(TWSR));
209 #endif
210  
211 // enable TWI interrupt
212 sbi(TWCR, TWIE);
213  
214 return EDP_COMMAND_OK;
215 }
216  
217 // get the response code and reply from last command
218 u08 edpGetCommandReply(u08* responseCode, EdpReply** edpReply)
219 {
220 u08 retval=EDP_REPLY_OK;
221  
222 // get the response code from last command
223 *responseCode = EdpCommandResponseCode;
224 // get the reply from last command
225 *edpReply = (EdpReply*)EdpCommandReplyBuffer;
226  
227 // check response code
228 if(EdpCommandResponseCode == EDP_RESP_DATA_REPLY)
229 {
230 // there was a reply, check the checksum
231 // if it's non-zero, data corruption is present
232 if(EdpCommandReplyChecksum)
233 retval = EDP_REPLY_BADCHKSUM;
234 }
235 return retval;
236 }
237  
238 /*
239 u08 edpSendCommand(u08 deviceAddr, u08 sendLength, u08* sendData)
240 {
241 u08* replyData = EdpCommandReplyBuffer;
242 u08 replyLength;
243 u08 checksum;
244  
245 // initialize response variables
246 EdpCommandReplyLength = 0;
247 EdpCommandReplyChecksum = 0;
248  
249 #ifdef EDP_DEBUG
250 rprintf("\r\nBegin EdpSendCommand, TWSR:0x%x\r\n",inb(TWSR));
251 #endif
252  
253 // disable TWI interrupt
254 cbi(TWCR, TWIE);
255  
256 // clear TWI interface
257 //outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK));
258  
259 // send start condition
260 i2cSendStart();
261 i2cWaitForComplete();
262 #ifdef EDP_DEBUG
263 rprintf("Sent Start, TWSR:0x%x\r\n",inb(TWSR));
264 #endif
265  
266 // send device address with write
267 i2cSendByte( (deviceAddr&0xFE) );
268 i2cWaitForComplete();
269 #ifdef EDP_DEBUG
270 rprintf("Sent Device Address+Write, TWSR:0x%x\r\n",inb(TWSR));
271 #endif
272  
273 // check if device is present and live
274 if( i2cGetStatus() != TW_MT_SLA_ACK)
275 {
276 // device did not ACK it's address, command will not continue
277 // transmit stop condition
278 // leave with TWEA on for slave receiving
279 i2cSendStop();
280 while( !(inb(TWCR) & BV(TWSTO)) );
281 #ifdef EDP_DEBUG
282 rprintf("No Device!, Sent Stop, TWSR:0x%x\r\n",inb(TWSR));
283 #endif
284 // enable TWI interrupt
285 sbi(TWCR, TWIE);
286 // return error
287 return EDP_COMMAND_NODEV;
288 }
289  
290 // send data
291 checksum = 0;
292 while(sendLength)
293 {
294 i2cSendByte( *sendData );
295 i2cWaitForComplete();
296 #ifdef EDP_DEBUG
297 rprintf("Sent Data, TWSR:0x%x\r\n",inb(TWSR));
298 #endif
299 checksum += *sendData++;
300 sendLength--;
301 }
302  
303 // send the checksum
304 i2cSendByte( ~checksum );
305 i2cWaitForComplete();
306 #ifdef EDP_DEBUG
307 rprintf("Sent Checksum, TWSR:0x%x\r\n",inb(TWSR));
308 #endif
309  
310 // send repeated start condition
311 i2cSendStart();
312 i2cWaitForComplete();
313 #ifdef EDP_DEBUG
314 rprintf("Sent Repeated Start, TWSR:0x%x\r\n",inb(TWSR));
315 #endif
316  
317 // send device address with read
318 i2cSendByte( deviceAddr|0x01 );
319 i2cWaitForComplete();
320 #ifdef EDP_DEBUG
321 rprintf("Sent Device Address+Read, TWSR:0x%x\r\n",inb(TWSR));
322 #endif
323  
324 // read response code, return NACK
325 i2cReceiveByte(FALSE);
326 i2cWaitForComplete();
327 #ifdef EDP_DEBUG
328 rprintf("Read Data, TWSR:0x%x\r\n",inb(TWSR));
329 #endif
330 EdpCommandResponseCode = i2cGetReceivedByte();
331  
332 if(EdpCommandResponseCode==EDP_RESP_DATA_REPLY)
333 {
334 // a data reply is being sent
335  
336 // send repeated start condition
337 i2cSendStart();
338 i2cWaitForComplete();
339  
340 // send device address with read
341 i2cSendByte( deviceAddr|0x01 );
342 i2cWaitForComplete();
343  
344 // get length, return ACK
345 i2cReceiveByte(TRUE);
346 i2cWaitForComplete();
347 replyLength = i2cGetReceivedByte();
348 EdpCommandReplyLength = replyLength;
349  
350 // get data, return ACKs
351 // preset checksum with the datalength byte
352 checksum = replyLength;
353 while(replyLength > 1)
354 {
355 i2cReceiveByte(TRUE); // receive data byte and return ACK
356 i2cWaitForComplete();
357 *replyData = i2cGetReceivedByte();
358 checksum += *replyData++;
359 replyLength--;
360 }
361  
362 // get last data (actually the checksum), return NACK (last-byte signal)
363 i2cReceiveByte(FALSE);
364 i2cWaitForComplete();
365 *replyData = i2cGetReceivedByte();
366 // add received checksum+1 to our checksum, the result should be zero
367 checksum += (*replyData) + 1;
368 // save the reply checksum
369 EdpCommandReplyChecksum = checksum;
370 }
371  
372 // transmit stop condition
373 // leave with TWEA on for slave receiving
374 i2cSendStop();
375 while( !(inb(TWCR) & BV(TWSTO)) );
376 #ifdef EDP_DEBUG
377 rprintf("Sent Stop, TWSR:0x%x\r\n",inb(TWSR));
378 #endif
379  
380 // enable TWI interrupt
381 sbi(TWCR, TWIE);
382  
383 return EDP_COMMAND_OK;
384 }
385  
386 u08 edpGetCommandReply(u08* responseCode, u08* replyLength, u08** replyData)
387 {
388 u08 retval=EDP_REPLY_OK;
389  
390 // get the response code and reply data from last command
391 *responseCode = EdpCommandResponseCode;
392 // get the reply length from last command
393 *replyLength = EdpCommandReplyLength;
394 // get the reply data from last command
395 *replyData = EdpCommandReplyBuffer;
396  
397 // check response code
398 if(EdpCommandResponseCode == EDP_RESP_DATA_REPLY)
399 {
400 // there was a reply, check the checksum
401 // if it's non-zero, data corruption is present
402 if(EdpCommandReplyChecksum)
403 retval = EDP_REPLY_BADCHKSUM;
404 }
405 return retval;
406 }
407 */
408  
409 // ************ EDP Slave operations ************
410  
411 // this function will run when a master somewhere else on the bus
412 // addresses us and wishes to write data to us
413 void edpSlaveReceiveService(u08 receiveDataLength, u08* receiveData)
414 {
415 u08 i,checksum;
416  
417 // initialize the reply length from this command
418 EdpSlaveReplyLength = 0;
419 // verify the checksum
420 // initialize the checksum with 1
421 checksum = 0x01;
422 // sum all the data in the packet and the data's checksum
423 for(i=0; i<receiveDataLength; i++)
424 {
425 checksum += receiveData[i];
426 }
427 // if the checksum is non-zero, then the data is corrupt
428 if(checksum)
429 {
430 // set reply code
431 // [FIX] which should it be?
432 EdpSlaveResponseCode = EDP_RESP_DATA_CHK_ERROR;
433 //EdpSlaveResponseCode = EDP_RESP_CMD_CHK_ERROR;
434 return;
435 }
436  
437 // make an EDP command pointer to the received I2C data
438 EdpCommand* edpCommand = (EdpCommand*)receiveData;
439  
440 // if a slave handler is defined
441 if(edpSlaveHandlerFunc)
442 {
443 // then use it
444 EdpSlaveResponseCode = edpSlaveHandlerFunc(
445 receiveDataLength, edpCommand,
446 EDP_REPLY_BUFFER_SIZE, (EdpReply*)EdpSlaveReplyBuffer);
447 }
448 else
449 {
450 // otherwise reply with unknown command
451 EdpSlaveResponseCode = EDP_RESP_UNKWN_CMD;
452 }
453 }
454  
455 // this function will run when a master somewhere else on the bus
456 // addresses us and wishes to read data from us
457 u08 edpSlaveTransmitService(u08 transmitDataLengthMax, u08* transmitData)
458 {
459 u08 i;
460 u08 checksum;
461 u08 transmitDataLength = 0;
462  
463 EdpReply* edpReply = (EdpReply*)EdpSlaveReplyBuffer;
464  
465 if(EdpSlaveResponseCode)
466 {
467 // reply code is non-zero, we must send it
468 *transmitData = EdpSlaveResponseCode;
469 transmitDataLength = 1;
470 // reset the reply code to flag that we've sent it
471 EdpSlaveResponseCode = 0;
472 }
473 else
474 {
475 // reply code already sent, now send data (if any)
476 // copy length of reply to transmit buffer (+1 for checksum)
477 *transmitData++ = edpReply->Length+1;
478 // initialize checksum
479 checksum = edpReply->Length+1;
480 // copy reply buffer to the transmit buffer
481 for(i=0; i<edpReply->Length; i++)
482 {
483 *transmitData++ = edpReply->Data[i];
484 checksum += edpReply->Data[i];
485 }
486 // copy checksum to transmit buffer
487 *transmitData++ = ~checksum;
488 // set number of bytes to transmit
489 transmitDataLength = edpReply->Length+2;
490 }
491  
492 // return number of bytes written to transmit buffer
493 return transmitDataLength;
494 }
{BLAME END}
{FOOTER START}

Powered by WebSVN v2.8.3