SZS ez430-RF2480 1.0

ZigBee Sensor Network with synchronized time and time-stamped measurements.
uart.c
Go to the documentation of this file.
1 /*
2  * uart.c
3  *
4  * Created on: 14/10/2013
5  * Author: Fernando
6  */
7 
16 /*
17  * ======== Includes ========
18  */
19 
20 #include "uart.h"
21 #include "msp430f2274.h"
22 #include "spi.h"
23 #include "nwk.h"
24 #include "clock.h"
25 #include "cc2480ai.h"
26 #include "im.h"
27 
28 /*
29  * ======== Constants ========
30  */
31 
32 /*
33  * ======== Macros ========
34  */
35 
36 /*
37  * ======== Types ========
38  */
39 
40 /*
41  * ======== Global Variables ========
42  */
43 
44 /*
45  * ======== Local Variables ========
46  */
47 
52 
57 
63 
69 
75 
81 
86 
87 /*
88  * ======== Local Functions ========
89  */
90 
91 void uart_proccessCmd();
92 UInt8 uart_txBufFreeReal();
93 
94 /*
95  * ================
96  */
97 
105 void uart_init() {
106  uart_rxBufRead = 0;
107  uart_rxBufWrite = 0;
108  uart_txBufRead = 0;
109  uart_txBufWrite = 0;
110  uart_currentFCS = 0;
111 }
112 
122 UInt16 uart_proccess() {
124  return 500;
125 }
126 
140 UInt8 uart_startFrame(UInt8 len, UInt8 cmd0, UInt8 cmd1) {
141  char frameHeader[3];
142  if (len > uart_txBufFree()) {
143  return 0;
144  }
146  frameHeader[0] = len;
147  frameHeader[1] = cmd0;
148  frameHeader[2] = cmd1;
149  uart_snd(1, "\xFE"); // SOF = 0xFE = 254
150  uart_currentFCS = 0;
151  uart_snd(3, frameHeader);
152  return 1;
153 }
154 
167 }
168 
181 UInt8 uart_snd(UInt8 len, void *pBuf) {
182  UInt8 i;
183  char *pcBuf;
184 
185  // check if there is enough room to the requested size;
186  if ((len) > uart_txBufFreeReal()) {
187  IE2 |= UCA0TXIE; // activate TX interrupt, this must trigger ISR if TX is not busy.
188  return 0;
189  }
190  pcBuf = pBuf;
191  for (i = len; i != 0; i--) {
192  uart_txBuf[uart_txBufWrite] = *pcBuf;
193  uart_txBufWrite++;
195  uart_txBufWrite = 0;
196  }
197  uart_currentFCS ^= *pcBuf++;
198  }
199  IE2 |= UCA0TXIE; // activate TX interrupt, this must trigger ISR if TX is not busy.
200  return 1;
201 }
202 
204 // *
205 // * @brief This function receive up to size characters from the uart_rxBuf.
206 // *
207 // * @param[in] size Amount of data to read from the uart_rxBuf.
208 // * @param[out] Pointer to the buffer where the data will be written.
209 // *
210 // * @return Amount of bytes received
211 // *
212 // */
213 //UInt8 uart_rcv(UInt8 size, void *pBuf) {
214 // UInt8 i = 0;
215 // char *pcBuf;
216 //
217 // pcBuf = pBuf;
218 // while (size && (uart_rxBufRead != uart_rxBufWrite)) {
219 // *pcBuf++ = uart_rxBuf[uart_rxBufRead];
220 // uart_rxBufRead++;
221 // if (uart_rxBufRead == UART_RX_BUF_SIZE) {
222 // uart_rxBufRead = 0;
223 // }
224 // i++;
225 // size--;
226 // }
227 // return i;
228 //}
229 
237 void USCIA0RX_ISR() {
238  // Device enters ISR when character received in RX Buffer
239  if ((uart_rxBufRead != uart_rxBufWrite + 1)
240  && !((uart_rxBufWrite == (UART_RX_BUF_SIZE - 1))
241  && (uart_rxBufRead == 0))) {
242  uart_rxBuf[uart_rxBufWrite] = UCA0RXBUF;
243  uart_rxBufWrite++;
245  uart_rxBufWrite = 0;
246  }
247  } else {
248  UCA0RXBUF; // Buffer is full, discard it - Must be done to clear IFG
249  }
250 }
251 
259 void USCIA0TX_ISR() {
261 }
262 
272  if (IFG2 & UCA0TXIFG) { // if TX not busy
273  UCA0TXBUF = uart_txBuf[uart_txBufRead];
274  uart_txBufRead++;
276  uart_txBufRead = 0;
277  }
278  }
279  } else if (uart_txBufRead == uart_txBufWrite) {
280  IE2 &= ~UCA0TXIE;
281  }
282 }
283 
293 UInt8 uart_txBufFree() {
294  UInt8 free;
295 
296  free = uart_txBufFreeReal();
297  if (free < 7)
298  free = 0;
299  else
300  free -= 6;
301  return free;
302 }
303 
316  return UART_TX_BUF_SIZE - 1;
317  } else if (uart_txBufWrite < uart_txBufRead) {
318  return uart_txBufRead - (uart_txBufWrite + 1);
319  } else {
321  }
322 }
323 
335 UInt8 uart_sndInt64(int64_t *p) {
336  return uart_snd(8, p);
337 }
338 
350 UInt8 uart_sndUInt64(uint64_t *p) {
351  return uart_snd(8, p);
352 }
353 
365 UInt8 uart_sndUInt48(uint64_t *p) {
366  return uart_snd(6, p);
367 }
368 
380 UInt8 uart_sndUInt32(UInt32 *p) {
381  return uart_snd(4, p);
382 }
383 
395 UInt8 uart_sndUInt16(UInt16 v) {
396  return uart_snd(2, &v);
397 }
398 
410 UInt8 uart_sndUInt8(UInt8 v) {
411  return uart_snd(1, &v);
412 }
413 
422  UInt8 i;
423  UInt8 len;
424  UInt8 fcs;
425  UInt16 cmd;
426  clock_timeStamp time;
427  UInt32 newTickSize;
428  int64_t timeAdjust;
429  char *dumpPos;
430  UInt8 dumpLen;
431 
432  // search SOF, using packet format of swra175a.pdf - 5.2.2 Frame Format
433  while ((uart_rxBufRead != uart_rxBufWrite)
434  && (uart_rxBuf[uart_rxBufRead] != 254)) {
435  uart_rxBufRead++;
437  uart_rxBufRead = 0;
438  }
439  // Check empty buffer
441  return;
442  // char 254 found check length of the buffer
443  i = uart_rxBufRead + 1;
444  if (i == UART_RX_BUF_SIZE)
445  i = 0;
446  if (i == uart_rxBufWrite) // No data received
447  return;
448  len = uart_rxBuf[i];
449  if (len >= (UART_RX_BUF_SIZE - 6)) { // Packet invalid or larger than buffer, can't be read
450  uart_rxBufRead = i; // discard it, next call will search next SOF
451  return;
452  }
453  // check for complete packet
455  if ((len + 5) > (UART_RX_BUF_SIZE - uart_rxBufRead + uart_rxBufWrite))
456  return;
457  } else {
458  if ((len + 5) > (uart_rxBufWrite - uart_rxBufRead))
459  return;
460  }
461  // Frame-check sequence.
462  fcs = uart_rxBuf[i]; // len
463  i++;
464  if (i == UART_RX_BUF_SIZE)
465  i = 0;
466  fcs ^= uart_rxBuf[i]; // cmd0
467  i++;
468  if (i == UART_RX_BUF_SIZE)
469  i = 0;
470  fcs ^= uart_rxBuf[i]; // cmd1
471  i++;
472  if (i == UART_RX_BUF_SIZE)
473  i = 0;
474  while (len) { // data
475  len--;
476  fcs ^= uart_rxBuf[i];
477  i++;
478  if (i == UART_RX_BUF_SIZE)
479  i = 0;
480  }
481  if (fcs != uart_rxBuf[i]) {
482  uart_rxBufRead++; // Invalid packet. Discard it, next call will search next SOF
484  uart_rxBufRead = 0;
485  return;
486  }
487  // The packet is complete and FCS is valid
488  uart_rxBufRead++; //pointer position from SOF to len
490  uart_rxBufRead = 0;
491  // Now, if packet is invalid, just exit with return and next call will search for next SOF
492  i = uart_rxBufRead;
493  len = uart_rxBuf[i];
494  i++;
495  if (i == UART_RX_BUF_SIZE)
496  i = 0;
497  cmd = uart_rxBuf[i];
498  i++;
499  if (i == UART_RX_BUF_SIZE)
500  i = 0;
501  cmd <<= 8;
502  cmd |= uart_rxBuf[i];
503  i++;
504  if (i == UART_RX_BUF_SIZE)
505  i = 0;
506  switch (cmd) {
507  case 0xE110: // select device type
508  if (len != 1) {
509  // invalid length
510  return;// Discard it, next call will search next SOF
511  }
512  switch (uart_rxBuf[i]) {
513  case 0:
515  break;
516  case 1:
518  break;
519  case 2:
521  break;
522  default:
523  // invalid value
524  return; // Discard it, next call will search next SOF
525  }
526  i++;
527  if (i == UART_RX_BUF_SIZE)
528  i = 0;
529  break;
530  case 0xE111: // Select data sink on/off (bind)
531  if (len != 1) {
532  // invalid length
533  return;// Discard it, next call will search next SOF
534  }
536  i++;
537  if (i == UART_RX_BUF_SIZE)
538  i = 0;
539  break;
540  case 0xE120: // Set clock time
541  if (len != 10) {
542  // invalid length
543  return;// Discard it, next call will search next SOF
544  }
545  ((char *) &(time.seconds.secondsLow))[0] = uart_rxBuf[i];
546  i++;
547  if (i == UART_RX_BUF_SIZE)
548  i = 0;
549  ((char *) &(time.seconds.secondsLow))[1] = uart_rxBuf[i];
550  i++;
551  if (i == UART_RX_BUF_SIZE)
552  i = 0;
553  ((char *) &(time.seconds.secondsLow))[2] = uart_rxBuf[i];
554  i++;
555  if (i == UART_RX_BUF_SIZE)
556  i = 0;
557  ((char *) &(time.seconds.secondsLow))[3] = uart_rxBuf[i];
558  i++;
559  if (i == UART_RX_BUF_SIZE)
560  i = 0;
561  ((char *) &(time.seconds.secondsHigh))[0] = uart_rxBuf[i];
562  i++;
563  if (i == UART_RX_BUF_SIZE)
564  i = 0;
565  ((char *) &(time.seconds.secondsHigh))[1] = uart_rxBuf[i];
566  i++;
567  if (i == UART_RX_BUF_SIZE)
568  i = 0;
569  ((char *) &(time.nanoSeconds))[0] = uart_rxBuf[i];
570  i++;
571  if (i == UART_RX_BUF_SIZE)
572  i = 0;
573  ((char *) &(time.nanoSeconds))[1] = uart_rxBuf[i];
574  i++;
575  if (i == UART_RX_BUF_SIZE)
576  i = 0;
577  ((char *) &(time.nanoSeconds))[2] = uart_rxBuf[i];
578  i++;
579  if (i == UART_RX_BUF_SIZE)
580  i = 0;
581  ((char *) &(time.nanoSeconds))[3] = uart_rxBuf[i];
582  i++;
583  if (i == UART_RX_BUF_SIZE)
584  i = 0;
585  clock_setTime(&time);
586 
587  break;
588  case 0xE121: // Adjust clock tick
589  if (len != 4) {
590  // invalid length
591  return;// Discard it, next call will search next SOF
592  }
593  ((char *) &(newTickSize))[0] = uart_rxBuf[i];
594  i++;
595  if (i == UART_RX_BUF_SIZE)
596  i = 0;
597  ((char *) &(newTickSize))[1] = uart_rxBuf[i];
598  i++;
599  if (i == UART_RX_BUF_SIZE)
600  i = 0;
601  ((char *) &(newTickSize))[2] = uart_rxBuf[i];
602  i++;
603  if (i == UART_RX_BUF_SIZE)
604  i = 0;
605  ((char *) &(newTickSize))[3] = uart_rxBuf[i];
606  i++;
607  if (i == UART_RX_BUF_SIZE)
608  i = 0;
609  clock_tickSize = newTickSize;
610  break;
611  case 0xE122: // Adjust clock time
612  if (len != 8) {
613  // invalid length
614  return;// Discard it, next call will search next SOF
615  }
616  ((char *) &(timeAdjust))[0] = uart_rxBuf[i];
617  i++;
618  if (i == UART_RX_BUF_SIZE)
619  i = 0;
620  ((char *) &(timeAdjust))[1] = uart_rxBuf[i];
621  i++;
622  if (i == UART_RX_BUF_SIZE)
623  i = 0;
624  ((char *) &(timeAdjust))[2] = uart_rxBuf[i];
625  i++;
626  if (i == UART_RX_BUF_SIZE)
627  i = 0;
628  ((char *) &(timeAdjust))[3] = uart_rxBuf[i];
629  i++;
630  if (i == UART_RX_BUF_SIZE)
631  i = 0;
632  ((char *) &(timeAdjust))[4] = uart_rxBuf[i];
633  i++;
634  if (i == UART_RX_BUF_SIZE)
635  i = 0;
636  ((char *) &(timeAdjust))[5] = uart_rxBuf[i];
637  i++;
638  if (i == UART_RX_BUF_SIZE)
639  i = 0;
640  ((char *) &(timeAdjust))[6] = uart_rxBuf[i];
641  i++;
642  if (i == UART_RX_BUF_SIZE)
643  i = 0;
644  ((char *) &(timeAdjust))[7] = uart_rxBuf[i];
645  i++;
646  if (i == UART_RX_BUF_SIZE)
647  i = 0;
648  clock_adjTime(&timeAdjust);
649  break;
650  case 0xE1FD: // Memory data dump to serial
651  /*
652  * Packet Received:
653  * ----------+--------
654  * Bytes | 2 | 1 |
655  * +----------+--------+
656  * Desc | position | Length |
657  * ----------+--------
658  * Offset | 0 | 2 | - not counting header
659  *
660  * Packet to send:
661  * -----------------+------
662  * Bytes | 1 | 0-64 |
663  * +-----------------+------+
664  * Desc | Status & Length | Data |
665  * -----------------+------
666  * Offset | 0 | 1 |
667  *
668  * Status is first 2 bits and Length is last 6 bits
669  *
670  */
671  dumpPos = (char *) (uart_rxBuf[i] | (uart_rxBuf[i + 1u] << 8));
672  i++;
673  if (i == UART_RX_BUF_SIZE)
674  i = 0;
675  i++;
676  if (i == UART_RX_BUF_SIZE)
677  i = 0;
678  dumpLen = uart_rxBuf[i];
679  i++;
680  if (i == UART_RX_BUF_SIZE)
681  i = 0;
682  if (dumpLen > 63)
683  dumpLen = 63;
684 
685  if (uart_startFrame(dumpLen + 1, 0xE1, 0x03)) {
686  // status is 0, no need to insert it as there is a 00 already
687  uart_sndUInt8(dumpLen);
688  uart_snd(dumpLen, dumpPos);
689  uart_endFrame();
690  } else {
691  dumpLen = uart_txBufFree();
692  if (dumpLen) {
693  if (uart_startFrame(dumpLen, 0xE1, 0x03)) {
694  // status is 1, incomplete dump due to no space on buffer
695  uart_sndUInt8((dumpLen - 1u) | (0x01 << 6));
696  uart_snd(dumpLen - 1, dumpPos);
697  uart_endFrame();
698  }
699  }
700  }
701 
702  case 0xE1FE: // Reset CC2480
703  if (len != 0) {
704  // invalid length
705  return;// Discard it, next call will search next SOF
706  }
707  nwk_init();
708  spi_init();
709  ccai_resetFull();
710  break;
711  case 0xE1FF: // reset the MSP430
712  if (len != 0) {
713  // invalid length
714  return;// Discard it, next call will search next SOF
715  }
716  // Reset by writing an invalid value to watch dog control
717  WDTCTL = 0;
718  break;
719  default:
720  // unknown command
721  return; // Discard it, next call will search next SOF
722  }
723  // Command processed, 'i' is pointing FCS, point to byte after packet.
724  i++;
725  if (i == UART_RX_BUF_SIZE)
726  i = 0;
727  // set read pointer
728  uart_rxBufRead = i;
729 }
730 
740 UInt8 uart_forwardCmd(char *pBuf) {
741  // Forward report to UART
742  if (uart_startFrame(pBuf[0], pBuf[1], pBuf[2])) {
743  uart_snd(pBuf[0], &pBuf[3]);
744  uart_endFrame();
745  return 1;
746  }
747  return 0;
748 }
749 
Coordinator.
Definition: nwk.h:217
Network functions interface.
UART interface.
#define UART_TX_BUF_SIZE
UART TX buffer size.
Definition: uart.h:49
void USCIA0TX_ISR()
USCIA0 TX ISR.
Definition: uart.c:259
UInt8 uart_sndUInt8(UInt8 v)
Send UInt8.
Definition: uart.c:410
Interruption management (enable/disable) interface.
UInt8 uart_txBufFree()
TX buffer free.
Definition: uart.c:293
void nwk_setSink(UInt8 sink)
Set sink.
Definition: nwk.c:1195
Router.
Definition: nwk.h:218
UInt16 uart_proccess()
UART process.
Definition: uart.c:122
UInt8 uart_rxBufWrite
RX buffer write pointer, if + 1 = uart_rxBufRead, full buffer, must roll to zero at at UART_RX_BUF_SI...
Definition: uart.c:68
UInt32 clock_tickSize
Tick size (ns)
Definition: clock.c:102
Time stamp.
Definition: clock.h:75
Clock interface.
void im_disable_interrupt()
Disable interrupt.
Definition: im.c:162
void ccai_resetFull()
Full reset.
Definition: cc2480ai.c:616
SPI interface.
UInt8 uart_startFrame(UInt8 len, UInt8 cmd0, UInt8 cmd1)
Start frame.
Definition: uart.c:140
void im_enable_interrupt()
Enable interrupt.
Definition: im.c:222
UInt8 uart_txBufRead
TX buffer read pointer, if = uart_txBufWrite, no chars to send, must roll to zero at at UART_TX_BUF_S...
Definition: uart.c:74
UInt8 uart_sndUInt16(UInt16 v)
Send UInt16.
Definition: uart.c:395
void nwk_setDeviceType(nwk_devType newType)
Set device type.
Definition: nwk.c:516
void USCIA0RX_ISR()
USCIA0 RX ISR.
Definition: uart.c:237
UInt8 uart_sndUInt32(UInt32 *p)
Send UInt32.
Definition: uart.c:380
void nwk_init()
Network initialization.
Definition: nwk.c:276
UInt8 uart_rxBufRead
RX buffer read pointer, if = uart_rxBufWrite, no chars to send, must roll to zero at at UART_RX_BUF_S...
Definition: uart.c:62
UInt8 uart_forwardCmd(char *pBuf)
Forward command.
Definition: uart.c:740
char uart_currentFCS
Frame-check sequence.
Definition: uart.c:85
UInt8 uart_sndInt64(int64_t *p)
Send Int64.
Definition: uart.c:335
UInt8 uart_snd(UInt8 len, void *pBuf)
Send.
Definition: uart.c:181
char uart_rxBuf[UART_RX_BUF_SIZE]
UART RX buffer.
Definition: uart.c:51
CC2480 interface.
UInt8 uart_txBufWrite
TX buffer write pointer, if + 1 = uart_txBufRead, full buffer, must roll to zero at at UART_TX_BUF_SI...
Definition: uart.c:80
End device.
Definition: nwk.h:219
UInt8 uart_txBufFreeReal()
TX buffer real free.
Definition: uart.c:314
#define UART_RX_BUF_SIZE
UART RX buffer size.
Definition: uart.h:45
void uart_proccessCmd()
Process command.
Definition: uart.c:421
void uart_init()
UART initialization.
Definition: uart.c:105
void uart_endFrame()
End frame.
Definition: uart.c:164
void uart_sndnextchar()
Send next char.
Definition: uart.c:270
UInt8 uart_sndUInt48(uint64_t *p)
Send UInt48.
Definition: uart.c:365
void spi_init()
SPI initialization.
Definition: spi.c:287
char uart_txBuf[UART_TX_BUF_SIZE]
UART TX buffer.
Definition: uart.c:56
void clock_setTime(clock_timeStamp *sourceTime)
Set time.
Definition: clock.c:237
void clock_adjTime(int64_t *adjValue)
Adjust time.
Definition: clock.c:256
UInt8 uart_sndUInt64(uint64_t *p)
Send UInt64.
Definition: uart.c:350