1#include "main-header.h"
2#include "ti1101-settings.h"
4#include "ti1101-pinconfig.h"
8#include "metrics/metrics.h"
15#define TI1101_BURST 0x40
16#define TI1101_READ 0x80
18static long forwardto = 0;
20static byte ti1101_enabled = 1;
21static byte overflowed = 0;
22static byte ti1101_failed = 0;
23static byte need_reset;
24static byte ti1101_isready = 0;
25static byte laststatus;
26static byte last_irq_error = 0;
27static byte last_packet_rssi = 0;
28volatile byte ti1101_in_read_loop = 0;
29volatile byte ti1101_locked = 0;
31const char *decode_marcstate(
int state);
32static int ti1101_reset();
34static void ti1101_select();
35static void ti1101_deselect();
36static int ti1101_read_register(
byte offset);
37static int ti1101_read_status_register(
byte offset);
38static void ti1101_config_init();
39static byte ti1101_debug = 0;
42const char *statetable[] = {
69static int config_entries;
70static byte current_config[102];
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; }
75void ti1101_failure() {
80 printf(
"TI1101: debug enabled\r\n");
82static void lock_failure() {
83 printf(
"TI1101 lock() timeout!!\r\n");
87static int ti1101_write_and_read(
int data) {
88 if (!ti1101_enabled) {
94 mculib_spi_write_and_read(nctx->mculib_handle, ti1101_spiport(), data, &res);
98static int spi_is_transmitting() {
102static int ti1101_write(
byte data) {
103 if (!ti1101_enabled) {
107 if (mculib_spi_write_only(nctx->mculib_handle, ti1101_spiport(), data) != 0) {
120 long started = mculib_get_seconds_since_boot();
122 while (ti1101_in_read_loop) {
123 if ((mculib_get_seconds_since_boot() - started) > 5) {
134void ti1101_unlock() {
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);
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);
161 mculib_pin_set(nctx->mculib_handle, ti1101_cssns(), 1);
165 printf(
"Failed to lock ti1101 (init) - exit");
170 ti1101_in_read_loop = 0;
172 IPLOG(
"ti1101_on...");
179 if ((er) || (ti1101_failed)) {
180 printf(
"ti1101 failed on spi %i, cssns pin %i\r\n", ti1101_spiport(), ti1101_cssns());
187void ti1101_select() {
188 mculib_pin_set(nctx->mculib_handle, ti1101_cssns(), 0);
198void ti1101_deselect() {
202 long secs = mculib_get_seconds_since_boot();
204 while (spi_is_transmitting()) {
205 if ((mculib_get_seconds_since_boot() - secs) > 2) {
210 mculib_pin_set(nctx->mculib_handle, ti1101_cssns(), 1);
214 CHECK_TI1101_FAILURE_V
215 return ti1101_write(0x35);
233static int ti1101_reset() {
234 if (config_get_ti1101disable()) {
237 if (!ti1101_enabled) {
240 ti1101_disable_irq(nctx);
244 printf(
"Failed to lock ti1101 (reset)- exit");
251 IPLOG(
"Resetting ti1101...\r\n");
255 i = mculib_spi_write_only(nctx->mculib_handle, ti1101_spiport(), 0x30);
257 printf(
"Failed to write to spi: %i\r\n", i);
262 mculib_pin_set(nctx->mculib_handle, ti1101_cssns(), 1);
263 printf(
"Strobe reset done\r\n");
269 CNWDEBUG(
"ti1101 selected()");
272 byte offset = current_config[i++];
273 byte value = current_config[i++];
274 if ((offset == ENDMARK) && (value == ENDMARK)) {
278 if (ti1101_write(offset) == -1) {
281 if (ti1101_write(value) == -1) {
293 CNWDEBUG(
"ti1101 deselected()");
299 printf(
"TI1101 failed to reset\r\n");
306 printf(
"TI1101 failed config check after reset\r\n");
311 printf(
"TI1101 was reset (%i)\r\n", ti1101_failed);
319void ti1101_print_config() {
320 CHECK_TI1101_FAILURE_S
323 for (i = 0; i < 0x30; i++) {
324 int v = ti1101_read_register(i);
325 IPLOG(
"Register %x == %x\r\n", i, v);
336 CHECK_TI1101_FAILURE_V
339 IPLOG(
"Checking config...\r\n");
340 long start = mculib_get_seconds_since_boot();
346 if ((mculib_get_seconds_since_boot() -
start) > 3) {
349 byte offset = current_config[i++];
350 byte value = (int)current_config[i++];
351 if ((offset == ENDMARK) && (value == ENDMARK)) {
356 int v = ti1101_read_register(offset);
368 IPLOG(
"cc1101: Config check done (%i, ok=%i,fail=%i)\r\n", nonzero, okvalues, failvalues);
369 if (failvalues > okvalues) {
381static 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");
386 CHECK_TI1101_FAILURE_V
390 if (num_bytes == 0) {
391 IPLOG(
"Reject request to send 0 bytes\r\n");
395 printf(
"Failed to lock ti1101 (sending) - exit");
400 IPLOG(
"Sending %i bytes via cc1101\r\n", num_bytes);
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]);
411 if ((r & 0x0F) < 4) {
420 for (i++; i < num_bytes; i++) {
422 int r = ti1101_write(data[i]);
427 txf = ((r & 0x0F) < 4) ? 70 : 50;
431 txf = ti1101_read_status_register(0x3A);
438 reset_delay_counter(DELAY_TI1101);
440 ((marcstate = ti1101_read_status_register(0x35)) != 0)
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);
459 IPLOG(
"Sending done (marcstate=%s).\r\n", decode_marcstate(marcstate));
461 ti1101_print_status();
462 IncMetric_PKTS_RADIO_CTR_OUT;
468int ti1101_read_status_register(
byte offset) {
471 if ((offset < 0x30) || (offset > 0x3F)) {
472 IPLOG(
"Warning! %x register is not a valid status register read\r\n", offset);
474 byte reg = TI1101_BURST | TI1101_READ | offset;
476 laststatus = ti1101_write_and_read(reg);
477 i = ti1101_write_and_read(0);
482int 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);
488 byte reg = TI1101_READ | offset;
491 ti1101_write_and_read(reg);
492 i = ti1101_write_and_read(0);
496void ti1101_print_status() {
497 CHECK_TI1101_FAILURE_S
502 printf(
"Failed to lock ti1101 (print_status) - exit");
507 int marcstate = ti1101_read_status_register(0x35);
508 int rxbytes = ti1101_read_status_register(0x3b);
509 int packetstate = ti1101_read_status_register(0x38);
512 if (rxbytes & 0x80) {
514 rxbytes = rxbytes & 0x7F;
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);
530void ti1101_receive_loop() {
532 if (!ti1101_enabled) {
536 if (!ti1101_isready) {
543 if (ti1101_in_read_loop) {
546 ti1101_in_read_loop = 1;
548 printf(
"ti1101_loop()\r\n");
553 ti1101_in_read_loop = 0;
566 reset_delay_counter(DELAY_TI1101);
567 long started = mculib_get_seconds_since_boot();
571 if ((mculib_get_seconds_since_boot() - started) > 3) {
581 rxbytes = ti1101_read_status_register(0x3b);
586 if (rxbytes & 0x80) {
590 total_bytes = total_bytes + rxbytes;
592 for (i = 0; i < rxbytes; i++) {
594 laststatus = ti1101_write_and_read(TI1101_READ | 0x3f);
596 int v = ti1101_write_and_read(0);
609 ti1101_in_read_loop = 0;
612 int res = ti1101_read_status_register(0x34);
614 last_packet_rssi = (byte)(res & 0xFF);
630 IPLOG(
"ti1101 off\r\n");
631 int res = ti1101_enabled ? 1 : 0;
639void ti1101_disable() {
640 IPLOG(
"ti1101 disable\r\n");
642 mculib_spi_write_only(nctx->mculib_handle, ti1101_spiport(), 0x39);
643 mculib_pin_set(nctx->mculib_handle, ti1101_cssns(), 1);
651 IPLOG(
"ti1101_enable\r\n");
653 mculib_pin_set(nctx->mculib_handle, ti1101_cssns(), 0);
656int ti1101_is_enabled() {
657 return ti1101_enabled;
659byte ti1101_read_byte() {
665int ti1101_read_version() {
666 CHECK_TI1101_FAILURE_V
671 v = ti1101_read_status_register(0x31);
676const char *decode_marcstate(
int state) {
680 while ((tstate = statetable[i]) != NULL) {
687 return (
const char *)
"UNDEF";
696 byte res = last_irq_error;
701static void forwardPacketBuffer(
byte *bs,
int len) {
702 if (forwardto == 0) {
705 send_command_one_arg(40, forwardto, bs, ((len >= MAX_SINGLE_ARG_SIZE) ? MAX_SINGLE_ARG_SIZE : len));
707static void printPacketBuffer(
byte *bs,
int len) {
708 printf(
"Contents of TI1101 packetbuffer\r\n");
713 for (i = 0; i < len; i++) {
714 printf(
"%x ", bs[i]);
716 for (l = 0; l < j; l++) {
717 byte b = bs[i - j + l];
718 if ((b ==
'\n') || (b ==
'\r')) {
729 printf(
"\r\nNote: command parsing starts at start+1!\r\n");
730 printf(
"END OF BUF LISTING\r\n");
733static void ti_got_new_packet(
struct command *com) {
734 int sig_ind = last_packet_rssi;
736 if (sig_ind >= 128) {
737 sig_ind = (sig_ind - 256) / 2 - 74;
739 sig_ind = sig_ind / 2 - 74;
741 sig_ind = sig_ind + 128;
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;
747 printf(
"TI packet processed\r\n");
750void ti1101_event_loop_locked() {
762 printf(
"TI1101 IRQ Error: %i\r\n", (
int)b);
765 printf(
"RXFIFO overflowed\r\n");
777 printf(
"TI1101: %i bytes in buf\r\n", i);
779 com = command_parse(bs + 1, i - 1);
782 IncMetric_PKTS_RADIO_INVALID;
783 IPLOG(
"\r\n*** Invalid command from radio (bufsize=%i)***\r\n",
785 printPacketBuffer(bs, i);
786 forwardPacketBuffer(bs, i);
789 IPLOG(
"Packet buf cleared\r\n");
791 com->sourcedev = SOURCE_RADIO;
793 ti_got_new_packet(
com);
802 if (!ti1101_enabled) {
806 ti1101_event_loop_locked();
813 mculib_pin_release(ctx->mculib_handle, ti1101_irqpin());
814 int r = mculib_pin_out(ctx->mculib_handle, ti1101_irqpin(), HAL_PIN_SLOWEST);
817 printf(
"Failed to disable irq for ti1101 (%i)\r\n", r);
820void 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);
825 printf(
"Failed to enable irq for ti1101 (%i)\r\n", r);
827 if (register_softirq(nctx->mculib_handle, ti1101_irqpin(), &ti1101_receive_loop, NULL) != 0) {
828 printf(
"failed to register softirq for ti1101\r\n");
838static void ti1101_config_init() {
845 int val = RFSETTINGS[i++];
846 int off = RFSETTINGS[i++];
847 current_config[t++] = val;
848 current_config[t++] = off;
850 if ((val == ENDMARK) && (off == ENDMARK)) {
871 dcom->
flags = COMFLAGS_DATA | COMFLAGS_SUCCESS;
879static void set_reg_config(
int reg,
int value) {
882 for (i = 0; i < config_entries; i++) {
883 if (current_config[i * 2] == reg) {
884 int oldv = current_config[i * 2 + 1];
888 current_config[i * 2 + 1] = value;
889 printf(
"Changed TI1101 register %x from %x to %x\r\n", reg, oldv, value);
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);
897 current_config[config_entries * 2] = ENDMARK;
898 current_config[config_entries * 2 + 1] = ENDMARK;
915 set_reg_config(reg, val);
929 printf(
"Forwarding all packets to %N\r\n", node);
933int ti1101_transmit(
struct network_context *nctx,
const byte *data, uint16_t num_bytes) {
934 return ti1101_send((
int)num_bytes, data);
int received_radio_set_config(struct command *com)
called when we received radio_set_config command modified the current radio config
int deliver_command(struct command *com, pkt_callback)
deliver a command to a module
void ti1101_forward_radio(long node)
forward all radio packets to this node mostly useful to debug and decode and sniff 3rd party protocol...
int start(int MCULIBHANDLE, struct sc_firmware_api *api)
this is called when the board powers up
int ti1101_compare_config()
check the config against the values in flash
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
int packet_put_byte(const int num, const byte b)
add a byte to a buffer
void command_init(struct command *com)
initialize a command structure with default values
void ti1101_on()
enable processing of radio
void packet_mark_valid(const int num)
mark this buffer as containing a valid packet
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)
int packet_getbytesinbuf(const int num)
count bytes in the buffer
int ti1101_loop(struct network_context *ctx)
this is called in the main thread periodically
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
struct command * alloc_command()
allocate a free command
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....
byte * packet_getbuf(const int num)
get pointer to the contents of the buffer
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
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...
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
int ti1101_off()
diable processing of ti1101 commands
void ti1101_set_debug(byte b)
set debug mode of ti1101
void packet_buf_init(const int num)
initialize (reset, clear) a given buffer