SingingCat  0
application
ti1101.c
1 #include "main-header.h"
2 #include "ti1101-settings.h"
3 #include "led.h"
4 #include "ti1101-pinconfig.h"
5 #include "networkif.h"
6 #include "ti1101.h"
7 #include "irq_router.h"
8 #include "metrics/metrics.h"
9 
10 #define ENDMARK (0)
15 #define TI1101_BURST 0x40
16 #define TI1101_READ 0x80
17 
18 static long forwardto = 0;
19 static struct network_context *nctx;
20 static byte ti1101_enabled = 1;
21 static byte overflowed = 0;
22 static byte ti1101_failed = 0;
23 static byte need_reset;
24 static byte ti1101_isready = 0;
25 static byte laststatus;
26 static byte last_irq_error = 0;
27 static byte last_packet_rssi = 0;
28 volatile byte ti1101_in_read_loop = 0;
29 volatile byte ti1101_locked = 0;
30 
31 const char *decode_marcstate(int state);
32 static int ti1101_reset();
34 static void ti1101_select();
35 static void ti1101_deselect();
36 static int ti1101_read_register(byte offset);
37 static int ti1101_read_status_register(byte offset);
38 static void ti1101_config_init();
39 static byte ti1101_debug = 0;
40 
41 // see page 93 cc1101 reference manual
42 const char *statetable[] = {
43  "SLEEP",
44  "IDLE",
45  "XOFF",
46  "VCOON_MC",
47  "REGON_MC",
48  "MANCAL",
49  "VCOON",
50  "REGON",
51  "STARTCAL",
52  "BWBOOST",
53  "FS_LOCK",
54  "IFADCON",
55  "ENDCAL",
56  "RX",
57  "RX_END",
58  "RX_RST",
59  "TXRX_SWITCH",
60  "RXFIFO_OVERFLOW",
61  "FSTXON",
62  "TX",
63  "TX_END",
64  "RXTX_SWITCH",
65  "TXFIFO_UNDERFLOW",
66  NULL
67 };
68 
69 static int config_entries;
70 static byte current_config[102];
71 
72 #define CHECK_TI1101_FAILURE if (ti1101_failed) { ti1101_failure(); return; }
73 #define CHECK_TI1101_FAILURE_S if (ti1101_failed) { ti1101_failure(); printf("TI1101 failed\r\n"); return; }
74 #define CHECK_TI1101_FAILURE_V if (ti1101_failed) { ti1101_failure(); return 0; }
75 void ti1101_failure() {
76  ;
77 }
78 void ti1101_set_debug(byte b) {
79  ti1101_debug = b;
80  printf("TI1101: debug enabled\r\n");
81 }
82 static void lock_failure() {
83  printf("TI1101 lock() timeout!!\r\n");
84 }
85 
86 static byte tx = 0;
87 static int ti1101_write_and_read(int data) {
88  if (!ti1101_enabled) {
89  return 0;
90  }
91  tx = 1;
92  uint16_t res;
93 
94  mculib_spi_write_and_read(nctx->mculib_handle, ti1101_spiport(), data, &res); // ti1101-spi port
95  tx = 0;
96  return res;
97 }
98 static int spi_is_transmitting() {
99  return tx;
100 }
101 
102 static int ti1101_write(byte data) {
103  if (!ti1101_enabled) {
104  return 0;
105  }
106  tx = 1;
107  if (mculib_spi_write_only(nctx->mculib_handle, ti1101_spiport(), data) != 0) {
108  tx = 0;
109  return -1;
110  }
111  tx = 0;
112  return 0;
113 }
114 
115 
119 int ti1101_lock() {
120  long started = mculib_get_seconds_since_boot();
121 
122  while (ti1101_in_read_loop) {
123  if ((mculib_get_seconds_since_boot() - started) > 5) {
124  // more than 5 seconds passed when trying to lock it!
125  lock_failure();
126  return 0;
127  }
128  // wait
129  //mculib_pin_toggle(LED_YELLOW);
130  }
131  ti1101_locked = 1;
132  return 1;
133 }
134 void ti1101_unlock() {
135  ti1101_locked = 0;
136 }
137 
138 /*
139  * \brief high-level function to reset the ti1101
140  *
141  * configures all the registers.
142  * returns 0 if ok, otherwise an errorcode
143  */
144 int internal_ti1101_init(struct network_context *onctx) {
145  int r;
146 
147  nctx = onctx;
148  ti1101_config_init();
149  if ((r = mculib_spi_master_enable(nctx->mculib_handle, ti1101_spiport(), 1, SPI_DIR_RW))) {
150  printf("Could not enable spi: %i\r\n", r);
151  return 2;
152  }
153  if ((r = mculib_pin_out(nctx->mculib_handle, ti1101_cssns(), HAL_PIN_SLOWEST))) {
154  printf("Could not enable CSSNS pin: %i\r\n", r);
155  return 2;
156  }
157 
158 
159  int er = 0;
160 
161  mculib_pin_set(nctx->mculib_handle, ti1101_cssns(), 1);
162  ti1101_failed = 0;
163  need_reset = 1;
164  if (!ti1101_lock()) {
165  printf("Failed to lock ti1101 (init) - exit");
166  ti1101_failed = 1;
167  need_reset = 1;
168  return 12;
169  }
170  ti1101_in_read_loop = 0;
171  ti1101_isready = 0;
172  IPLOG("ti1101_on...");
173  ti1101_deselect(); // disable it (re-enable when reading/writing)
174  ti1101_on();
175  IPLOG("OK.");
176  //ti1101_compare_config();
177  er = ti1101_reset();
178  ti1101_unlock();
179  if ((er) || (ti1101_failed)) {
180  printf("ti1101 failed on spi %i, cssns pin %i\r\n", ti1101_spiport(), ti1101_cssns());
181  return 1;
182  }
183  return 0;
184 }
185 
186 // switch the CSn/NSS for the CC1101 off
187 void ti1101_select() {
188  mculib_pin_set(nctx->mculib_handle, ti1101_cssns(), 0);
189  /* see page29 of cc1101 reference manual:
190  * "When CSn is pulled low, the MCU must wait
191  * until CC1101 SO pin goes low before starting to
192  * transfer the header byte."
193  */
194  //Delay(10); // wait for S0 to go low. do i really need another pin for that???
195 }
196 
197 // switch the CSn/NSS for the CC1101 on
198 void ti1101_deselect() {
199  CHECK_TI1101_FAILURE
200 
201  // always wait for transmission to end before we deselect our chip
202  long secs = mculib_get_seconds_since_boot();
203 
204  while (spi_is_transmitting()) {
205  if ((mculib_get_seconds_since_boot() - secs) > 2) {
206  ti1101_failed = 1;
207  break;
208  }
209  }
210  mculib_pin_set(nctx->mculib_handle, ti1101_cssns(), 1);
211 }
212 
213 int ti1101_tx() {
214  CHECK_TI1101_FAILURE_V
215  return ti1101_write(0x35); // strobe STX
216 }
217 void ti1101_rx() {
218  CHECK_TI1101_FAILURE
219  ti1101_write(0x3a); // strobe flush RX
220  ti1101_write(0x36); // strobe SIDLE
221  ti1101_write(0x34); // strobe SRX
222 }
223 
224 /*
225  * \brief low-level function to reset the ti1101
226  *
227  * configures all the registers.
228  * Note that we check the configuration afterwards.
229  * if all registers are 0, we consider this an error,
230  * because usually it means there's nothing connected
231  * returns 0 if ok, otherwise an errorcode
232  */
233 static int ti1101_reset() {
234  if (config_get_ti1101disable()) {
235  return 0;
236  }
237  if (!ti1101_enabled) {
238  return 0;
239  }
240  ti1101_disable_irq(nctx);
241 
242  ti1101_failed = 0;
243  if (!ti1101_lock()) {
244  printf("Failed to lock ti1101 (reset)- exit");
245  ti1101_failed = 1;
246  return 12;
247  }
248 
249  need_reset = 1;
250  overflowed = 0;
251  IPLOG("Resetting ti1101...\r\n");
252  int i = 0;
253 
254  ti1101_select();
255  i = mculib_spi_write_only(nctx->mculib_handle, ti1101_spiport(), 0x30); // strobe reset
256  if (i != 0) {
257  printf("Failed to write to spi: %i\r\n", i);
258  ti1101_failed = 1;
259  return 16;
260  }
261  Delay(20);
262  mculib_pin_set(nctx->mculib_handle, ti1101_cssns(), 1);
263  printf("Strobe reset done\r\n");
264  // ti1101_deselect(); // hangs because it keeps transmitting?? weird.
265  Delay(10); // no ti select/deselect reset wait .1s
266  ti1101_select();
267  byte fail = 0;
268 
269  CNWDEBUG("ti1101 selected()");
270  i = 0;
271  for (;;) {
272  byte offset = current_config[i++];
273  byte value = current_config[i++];
274  if ((offset == ENDMARK) && (value == ENDMARK)) {
275  break;
276  }
277  //IPLOG("Register %x: %x\r\n", (int)offset, (int)value);
278  if (ti1101_write(offset) == -1) {
279  fail++;
280  }
281  if (ti1101_write(value) == -1) {
282  fail++;
283  }
284  if (fail > 10) {
285  ti1101_failed = 1;
286  break;
287  }
288  }
289 
290  ti1101_rx();
291  ti1101_deselect();
292 
293  CNWDEBUG("ti1101 deselected()");
294 
295  ti1101_isready = 1;
296 
297  if (ti1101_failed) {
298  ti1101_unlock();
299  printf("TI1101 failed to reset\r\n");
300  return 1;
301  }
302  int er = ti1101_compare_config();
303 
304  ti1101_unlock();
305  if (er) {
306  printf("TI1101 failed config check after reset\r\n");
307  return 2;
308  }
309  ti1101_enable_irq();
310  need_reset = 0;
311  printf("TI1101 was reset (%i)\r\n", ti1101_failed);
312 
313  return 0;
314 }
315 
316 
317 
318 // read all registers, print out those that do not match configuration
319 void ti1101_print_config() {
320  CHECK_TI1101_FAILURE_S
321  int i = 0;
322 
323  for (i = 0; i < 0x30; i++) {
324  int v = ti1101_read_register(i);
325  IPLOG("Register %x == %x\r\n", i, v);
326  v++; // in case iplog is a noop
327  }
328 }
336  CHECK_TI1101_FAILURE_V
337  int i = 0;
338 
339  IPLOG("Checking config...\r\n");
340  long start = mculib_get_seconds_since_boot();
341  int nonzero = 0;
342  int okvalues = 0;
343  int failvalues = 0;
344 
345  for (;;) {
346  if ((mculib_get_seconds_since_boot() - start) > 3) {
347  return 1;
348  }
349  byte offset = current_config[i++];
350  byte value = (int)current_config[i++];
351  if ((offset == ENDMARK) && (value == ENDMARK)) {
352  break;
353  }
354  //printf("Reading %i ",offset);
355  int v2 = (int)value;
356  int v = ti1101_read_register(offset);
357  //printf(" == %i\r\n",v);
358  if (v != 0) {
359  nonzero++;
360  }
361  if (v != v2) {
362  failvalues++;
363  // IPLOG("Register %x should be %x and is %x \r\n", (int)offset, v2, v);
364  } else {
365  okvalues++;
366  }
367  }
368  IPLOG("cc1101: Config check done (%i, ok=%i,fail=%i)\r\n", nonzero, okvalues, failvalues);
369  if (failvalues > okvalues) {
370  return 1;
371  }
372  if (nonzero) {
373  return 0;
374  }
375  return 1;
376 }
381 static int ti1101_send(int num_bytes, const byte *data) {
382  if ((!ti1101_enabled) || (config_get_ti1101disable())) {
383  IPLOG("Not sending via radio - radio is not enabled\r\n");
384  return 1;
385  }
386  CHECK_TI1101_FAILURE_V
387  if (need_reset) {
388  return 2;
389  }
390  if (num_bytes == 0) {
391  IPLOG("Reject request to send 0 bytes\r\n");
392  return 3;
393  }
394  if (!ti1101_lock()) {
395  printf("Failed to lock ti1101 (sending) - exit");
396  ti1101_failed = 1;
397  return 4;
398  }
399 
400  IPLOG("Sending %i bytes via cc1101\r\n", num_bytes);
401  ti1101_select();
402  ti1101_write(0x36); // strobe SIDLE
403  ti1101_write(0x3b); // strobe FLUSH TX FIFO
404  int i = 0;
405 
406  ti1101_write(TI1101_BURST | 0x3f);
407  ti1101_write((byte)num_bytes);
408  for (i = 0; i < num_bytes; i++) {
409  int r = ti1101_write(data[i]);
410  //IPLOG("i=%i,state=0x%x\r\n",i,r);
411  if ((r & 0x0F) < 4) {
412  break;
413  }
414  }
415  ti1101_deselect(); // end burst
416  ti1101_select(); // and start
417  ti1101_tx(); // transmission
418 
419  //are there more bytes to send? (than fit into txfifo)
420  for (i++; i < num_bytes; i++) {
421  ti1101_write(0x3f); // send the data (no burst though)
422  int r = ti1101_write(data[i]);
423  int txf;
424  // if less than 4 bytes reported by
425  // chip status byte, we force the readloop of the
426  // txbytes register until more bytes are available
427  txf = ((r & 0x0F) < 4) ? 70 : 50;
428 
429  while (txf > 60) {
430  // TODO: add timeout/error handling here
431  txf = ti1101_read_status_register(0x3A); // bytes in txfifo
432  //IPLOG("i=%i,txf=%i,state=0x%x\r\n",i,txf,r);
433  }
434  }
435 
436  int marcstate;
437 
438  reset_delay_counter(DELAY_TI1101);
439  while (
440  ((marcstate = ti1101_read_status_register(0x35)) != 0)
441  && (marcstate != 13)
442  && (marcstate != 1)
443  && (marcstate != 22)
444  ) {
445  if (get_delay_counter(DELAY_TI1101) > 500) {
446  IPLOG("Timeout in TX, marcstate= %s (%i) - ti1101 reset triggered\r\n", decode_marcstate(marcstate), marcstate);
447  need_reset = 1;
448  ti1101_select();
449  break;
450  }
451  // in this case we remain in this loop as long as the chip has not transitioned to an after-tx state
452  }
453 
454  ti1101_deselect(); // exit from burst or tx mode
455  Delay(1); // give it a chance to see it
456  ti1101_select();
457  ti1101_rx();
458  ti1101_deselect();
459  IPLOG("Sending done (marcstate=%s).\r\n", decode_marcstate(marcstate));
460  ti1101_unlock();
461  ti1101_print_status();
462  IncMetric_PKTS_RADIO_CTR_OUT;
463  return 0;
464 }
465 
466 
467 // read register, add burst-read, return value or -1 if error
468 int ti1101_read_status_register(byte offset) {
469  int i;
470 
471  if ((offset < 0x30) || (offset > 0x3F)) {
472  IPLOG("Warning! %x register is not a valid status register read\r\n", offset);
473  }
474  byte reg = TI1101_BURST | TI1101_READ | offset;
475 
476  laststatus = ti1101_write_and_read(reg);
477  i = ti1101_write_and_read(0);
478  return i;
479 }
480 
481 // read register, return value or -1 if error
482 int ti1101_read_register(byte offset) {
483  CHECK_TI1101_FAILURE_V
484  if (offset >= 0x30) {
485  IPLOG("Warning! register access to %x - it is a strobe/statusregister\r\n", offset);
486  }
487  ti1101_select();
488  byte reg = TI1101_READ | offset;
489  int i;
490 
491  ti1101_write_and_read(reg);
492  i = ti1101_write_and_read(0);
493  ti1101_deselect();
494  return i;
495 }
496 void ti1101_print_status() {
497  CHECK_TI1101_FAILURE_S
498  const char *ms;
499  const char *o = "";
500 
501  if (!ti1101_lock()) {
502  printf("Failed to lock ti1101 (print_status) - exit");
503  ti1101_failed = 1;
504  need_reset = 1;
505  }
506  ti1101_select();
507  int marcstate = ti1101_read_status_register(0x35);
508  int rxbytes = ti1101_read_status_register(0x3b);
509  int packetstate = ti1101_read_status_register(0x38);
510 
511  ti1101_deselect();
512  if (rxbytes & 0x80) {
513  o = "(OVERFLOW)";
514  rxbytes = rxbytes & 0x7F;
515  }
516  ms = decode_marcstate(marcstate);
517  IPLOG("[%i]RXbytes: %i%s, marcstate=0x%x (%s), laststatus=0x%x, packetstate=0x%x \r\n",
518  ti1101_isready, rxbytes, o,
519  marcstate, ms, laststatus, packetstate);
520  packetstate++; // in case iplog is a noop
521  ms++; // in case iplog is a noop
522  o++; // in case iplog is a noop
523  ti1101_unlock();
524 }
525 
526 // this gets called from the cc1101-gd0-IRQ
527 // printf should not be used in here since it might destroy
528 // a buffer which is initialised otherwise
529 // void ti1101_receive_loop() __attribute__ ((interrupt ("IRQ")));
530 void ti1101_receive_loop() {
531  //led_flash(LED_MACHINE, 0xFFFF00, 10);
532  if (!ti1101_enabled) {
533  return;
534  }
535  CHECK_TI1101_FAILURE
536  if (!ti1101_isready) {
537  //IPLOG("Warning: receive_loop called but ti1101 is not ready!\r\n");
538  return;
539  }
540  if (ti1101_locked) {
541  return; // sending? resetting?
542  }
543  if (ti1101_in_read_loop) {
544  return; // avoid double-IRQ (not a race-condition on single-core cpus)
545  }
546  ti1101_in_read_loop = 1;
547  if (ti1101_debug) {
548  printf("ti1101_loop()\r\n");
549  }
550  if (packet_isvalid(PACKETBUFFER_CC1101)) {
551  // error - cannot receive whilst packet is still being processed.
552  //IPLOG("CC1101 PACKET buffer not ready!\r\n");
553  ti1101_in_read_loop = 0;
554  return;
555  }
556 
557  int i;
558  int rxbytes;
559 
560  ti1101_select();
561 
562  int total_bytes = 0;
563 
564  //int marcstate = ti1101_read_status_register(0x35);
565  rxbytes = 1;
566  reset_delay_counter(DELAY_TI1101);
567  long started = mculib_get_seconds_since_boot();
568  byte needlen = 0;
569 
570  while (rxbytes) {
571  if ((mculib_get_seconds_since_boot() - started) > 3) {
572  need_reset = 1;
573  ti1101_isready = 0;
574  ti1101_failed = 1;
575  last_irq_error = 13;
576  // very broken!!
577  break;
578  }
579 
580  // the the number of byes currently in RXFIFO
581  rxbytes = ti1101_read_status_register(0x3b); // field RXBYTES (rxfifo_overflow & num_rxbytes)
582  if (rxbytes == 0) {
583  break;
584  }
585  // was there an rx overflow?
586  if (rxbytes & 0x80) {
587  overflowed = 1;
588  break;
589  }
590  total_bytes = total_bytes + rxbytes;
591  // get & print bytes
592  for (i = 0; i < rxbytes; i++) {
593  // tell chip we want a single byte from rxfifo
594  laststatus = ti1101_write_and_read(TI1101_READ | 0x3f); //3f==RXFIFO, TI1101_READ=="Single Byte"
595  // now read the byte
596  int v = ti1101_write_and_read(0);
597  if (packet_put_byte(PACKETBUFFER_CC1101, (byte)v) < 0) {
598  packet_getbuf(PACKETBUFFER_CC1101)[0] = 0;
599  break; // error adding byte, so there's nothing we can do anymore
600  }
601  }
602 
603  needlen = packet_getbuf(PACKETBUFFER_CC1101)[0];
604  needlen++; // including the length byte!
605  if (packet_getbytesinbuf(PACKETBUFFER_CC1101) >= needlen) {
606  packet_mark_valid(PACKETBUFFER_CC1101);
607  }
608  }
609  ti1101_in_read_loop = 0;
610 
611  // for the fun of it, get the RSSI of (presumably) most recent packet
612  int res = ti1101_read_status_register(0x34); //34==RSSI, TI1101_READ=="Single Byte"
613 
614  last_packet_rssi = (byte)(res & 0xFF);
615  //ti1101_rx();
616 
617  // ti1101_deselect();
618 }
619 
629 int ti1101_off() {
630  IPLOG("ti1101 off\r\n");
631  int res = ti1101_enabled ? 1 : 0;
632 
633  ti1101_enabled = 0;
634  return res;
635 }
636 /*
637  * \brief disable ti1101 (power it off)
638  */
639 void ti1101_disable() {
640  IPLOG("ti1101 disable\r\n");
641  ti1101_enabled = 0;
642  mculib_spi_write_only(nctx->mculib_handle, ti1101_spiport(), 0x39); // SLEEP when CSN is high
643  mculib_pin_set(nctx->mculib_handle, ti1101_cssns(), 1);
644 }
650 void ti1101_on() {
651  IPLOG("ti1101_enable\r\n");
652  ti1101_enabled = 1;
653  mculib_pin_set(nctx->mculib_handle, ti1101_cssns(), 0);
654  need_reset = 1;
655 }
656 int ti1101_is_enabled() {
657  return ti1101_enabled;
658 }
659 byte ti1101_read_byte() {
660  return 1;
661 }
662 
663 
664 
665 int ti1101_read_version() {
666  CHECK_TI1101_FAILURE_V
667  int v;
668 
669  ti1101_select();
670 
671  v = ti1101_read_status_register(0x31);
672  ti1101_deselect();
673  return v;
674 }
675 
676 const char *decode_marcstate(int state) {
677  int i = 0;
678  const char *tstate;
679 
680  while ((tstate = statetable[i]) != NULL) {
681  if (i == state) {
682  return tstate;
683  }
684  i++;
685  }
686  ;
687  return (const char *)"UNDEF";
688 }
689 
696  byte res = last_irq_error;
697 
698  last_irq_error = 0;
699  return res;
700 }
701 static void forwardPacketBuffer(byte *bs, int len) {
702  if (forwardto == 0) {
703  return;
704  }
705  send_command_one_arg(40, forwardto, bs, ((len >= MAX_SINGLE_ARG_SIZE) ? MAX_SINGLE_ARG_SIZE : len));
706 }
707 static void printPacketBuffer(byte *bs, int len) {
708  printf("Contents of TI1101 packetbuffer\r\n");
709  int i;
710  int j = 0;
711  int l;
712 
713  for (i = 0; i < len; i++) {
714  printf("%x ", bs[i]);
715  if (j > 10) {
716  for (l = 0; l < j; l++) {
717  byte b = bs[i - j + l];
718  if ((b == '\n') || (b == '\r')) {
719  printf(".");
720  } else {
721  printf("%c", b);
722  }
723  }
724  printf("\r\n");
725  j = 0;
726  }
727  j++;
728  }
729  printf("\r\nNote: command parsing starts at start+1!\r\n");
730  printf("END OF BUF LISTING\r\n");
731 }
732 
733 static void ti_got_new_packet(struct command *com) {
734  int sig_ind = last_packet_rssi;
735 
736  if (sig_ind >= 128) {
737  sig_ind = (sig_ind - 256) / 2 - 74;
738  } else {
739  sig_ind = sig_ind / 2 - 74;
740  }
741  sig_ind = sig_ind + 128;
742 
743  printf("TI packet at: %p from %N (RSSI=%i,sig_ind=%i)\r\n", com, com->sender, last_packet_rssi, sig_ind);
744  IncMetric_PKTS_RADIO_CTR_IN;
745 
746  got_new_packet(com, (uint8_t)(sig_ind & 0xFF));
747  printf("TI packet processed\r\n");
748 }
749 
750 void ti1101_event_loop_locked() {
751  /*
752  * here we check the input on the radio - perhaps
753  * there's a command in the ringbuffer
754  * if so, we execute it
755  */
756  struct command *com;
757  int i;
758 
759  byte b = ti1101_get_last_irq_error();
760 
761  if (b != 0) {
762  printf("TI1101 IRQ Error: %i\r\n", (int)b);
763  }
764  if (overflowed) {
765  printf("RXFIFO overflowed\r\n");
766  ti1101_reset();
767  }
768  if (need_reset) {
769  ti1101_reset();
770  }
771  com = NULL;
772  if (packet_isvalid(PACKETBUFFER_CC1101)) {
773  byte *bs = packet_getbuf(PACKETBUFFER_CC1101);
774  i = packet_getbytesinbuf(PACKETBUFFER_CC1101);
775  if (i > 0) {
776  if (ti1101_debug) {
777  printf("TI1101: %i bytes in buf\r\n", i);
778  }
779  com = command_parse(bs + 1, i - 1);
780  }
781  if (com == NULL) {
782  IncMetric_PKTS_RADIO_INVALID;
783  IPLOG("\r\n*** Invalid command from radio (bufsize=%i)***\r\n",
784  packet_getbytesinbuf(PACKETBUFFER_CC1101));
785  printPacketBuffer(bs, i);
786  forwardPacketBuffer(bs, i);
787  packet_buf_init(PACKETBUFFER_CC1101);
788  need_reset = 1;
789  IPLOG("Packet buf cleared\r\n");
790  } else {
791  com->sourcedev = SOURCE_RADIO;
792  //command_print(com);
793  ti_got_new_packet(com);
794  packet_buf_init(PACKETBUFFER_CC1101);
795  }
796  }
797 }
801 int ti1101_loop(struct network_context *ctx) {
802  if (!ti1101_enabled) {
803  return 1;
804  }
805  ti1101_lock();
806  ti1101_event_loop_locked();
807  ti1101_unlock();
808  return 0;
809 }
810 
811 
812 void ti1101_disable_irq(struct network_context *ctx) {
813  mculib_pin_release(ctx->mculib_handle, ti1101_irqpin());
814  int r = mculib_pin_out(ctx->mculib_handle, ti1101_irqpin(), HAL_PIN_SLOWEST);
815 
816  if (r != 0) {
817  printf("Failed to disable irq for ti1101 (%i)\r\n", r);
818  }
819 }
820 void ti1101_enable_irq() {
821  mculib_pin_release(nctx->mculib_handle, ti1101_irqpin());
822  int r = mculib_pin_in(nctx->mculib_handle, ti1101_irqpin(), HAL_PIN_SLOWEST, HAL_PUSHPULL_DOWN);
823 
824  if (r != 0) {
825  printf("Failed to enable irq for ti1101 (%i)\r\n", r);
826  }
827  if (register_softirq(nctx->mculib_handle, ti1101_irqpin(), &ti1101_receive_loop, NULL) != 0) {
828  printf("failed to register softirq for ti1101\r\n");
829  }
830 }
831 
832 /**************************************************
833 *** TI 1101 Configuration management
834 **************************************************/
838 static void ti1101_config_init() {
839  /* copy the config from flash to ram */
840  int i = 0;
841  int t = 0;
842 
843  config_entries = 0;
844  for (;;) {
845  int val = RFSETTINGS[i++];
846  int off = RFSETTINGS[i++];
847  current_config[t++] = val;
848  current_config[t++] = off;
849  config_entries++;
850  if ((val == ENDMARK) && (off == ENDMARK)) {
851  break;
852  }
853  }
854 }
855 
861  struct command *dcom;
862 
863  dcom = alloc_command();
864  if (dcom == NULL) {
865  return 1;
866  }
867  command_init(dcom);
868  dcom->target = com->sender;
869  dcom->connid = com->connid;
870  dcom->com = com->com;
871  dcom->flags = COMFLAGS_DATA | COMFLAGS_SUCCESS;
872  command_add_binary_arg(dcom, config_entries * 2, current_config);
873  deliver_command(dcom, NULL);
874  return 0;
875 }
879 static void set_reg_config(int reg, int value) {
880  int i;
881 
882  for (i = 0; i < config_entries; i++) {
883  if (current_config[i * 2] == reg) {
884  int oldv = current_config[i * 2 + 1];
885  if (oldv == value) {
886  return;
887  }
888  current_config[i * 2 + 1] = value;
889  printf("Changed TI1101 register %x from %x to %x\r\n", reg, oldv, value);
890  return;
891  }
892  }
893  current_config[config_entries * 2] = reg;
894  current_config[config_entries * 2 + 1] = value;
895  printf("Set TI1101 register %x to %x\r\n", reg, value);
896  config_entries++;
897  current_config[config_entries * 2] = ENDMARK;
898  current_config[config_entries * 2 + 1] = ENDMARK;
899 }
900 
906  const char *b;
907 
908  b = get_arg(com, 0);
909  int size = get_arg_size(com, 0);
910  int i = 0;
911 
912  for (;;) {
913  int reg = b[i++];
914  int val = b[i++];
915  set_reg_config(reg, val);
916  if (i >= size) {
917  break;
918  }
919  }
920  ti1101_reset();
921  return 0;
922 }
928 void ti1101_forward_radio(long node) {
929  printf("Forwarding all packets to %N\r\n", node);
930  forwardto = node;
931 }
932 
933 int ti1101_transmit(struct network_context *nctx, const byte *data, uint16_t num_bytes) {
934  return ti1101_send((int)num_bytes, data);
935 }
byte * packet_getbuf(const int num)
get pointer to the contents of the buffer
Definition: packetbuffer.c:143
int received_radio_set_config(struct command *com)
called when we received radio_set_config command modified the current radio config
Definition: ti1101.c:905
int deliver_command(struct command *com, pkt_callback)
deliver a command to a module
Definition: queue.c:649
void ti1101_forward_radio(long node)
forward all radio packets to this node mostly useful to debug and decode and sniff 3rd party protocol...
Definition: ti1101.c:928
struct command * alloc_command()
allocate a free command
Definition: queue.c:171
int ti1101_compare_config()
check the config against the values in flash
Definition: ti1101.c:335
int received_radio_get_config(struct command *com)
called when we received radio_get_config command sends back an answer with the current radio config
Definition: ti1101.c:860
int packet_put_byte(const int num, const byte b)
add a byte to a buffer
Definition: packetbuffer.c:78
void command_init(struct command *com)
initialize a command structure with default values
void ti1101_on()
enable processing of radio
Definition: ti1101.c:650
void packet_mark_valid(const int num)
mark this buffer as containing a valid packet
Definition: packetbuffer.c:108
byte got_new_packet(struct command *com, uint8_t signal_indicator)
stack received a new packet (signal indicator is a 0-255 byte value, interface specific)
Definition: routing.c:111
int packet_getbytesinbuf(const int num)
count bytes in the buffer
Definition: packetbuffer.c:158
int ti1101_loop(struct network_context *ctx)
this is called in the main thread periodically
Definition: ti1101.c:801
int send_command_one_arg(int command, long target, const byte *arg1, int arg1len)
helper function to quickly and easily send a command somewhere return 0 if ok, else errorcode
Definition: routing.c:567
const char * get_arg(const struct command *com, int index)
given an argument by index[0..n], will return a pointer to the bytearray (excluding the fieldtype) th...
byte ti1101_get_last_irq_error()
if we throw an error in the irq we cannot print it directly. save it and return it here....
Definition: ti1101.c:695
int command_add_binary_arg(struct command *com, const int len, const byte *srcbuf)
adds a binary parameter to command returns 0 if ok otherwise errorcode
int ti1101_lock()
lock, return 1 if ok, otherwise it is an error
Definition: ti1101.c:119
int get_arg_size(const struct command *com, int index)
given an argument by index [0..n], will returns the size of the value in bytes. for a string/array it...
int packet_isvalid(const int num)
initialize (reset, clear) a given buffer
Definition: packetbuffer.c:125
int ti1101_off()
diable processing of ti1101 commands
Definition: ti1101.c:629
void ti1101_set_debug(byte b)
set debug mode of ti1101
Definition: ti1101.c:78
void packet_buf_init(const int num)
initialize (reset, clear) a given buffer
Definition: packetbuffer.c:37
void start(int MCULIBHANDLE, struct sc_firmware_api *api)
this is called when the board powers up
Definition: userhooks.c:30
int com
Definition: command.h:22
long target
Definition: command.h:16
uint8_t connid
Definition: command.h:18
uint8_t flags
Definition: command.h:23
long sender
Definition: command.h:14