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