11#if DETWS_ENABLE_CC1101
16const uint8_t READ = 0x80;
17const uint8_t BURST = 0x40;
20const uint8_t REG_CHANNR = 0x0A;
21const uint8_t STROBE_SRES = 0x30;
22const uint8_t STROBE_SRX = 0x34;
23const uint8_t STROBE_STX = 0x35;
24const uint8_t STROBE_SIDLE = 0x36;
25const uint8_t STROBE_SFRX = 0x3A;
26const uint8_t STROBE_SFTX = 0x3B;
27const uint8_t STAT_VERSION = 0x31;
28const uint8_t STAT_RXBYTES = 0x3B;
29const uint8_t FIFO = 0x3F;
32const uint8_t STATE_IDLE = 0;
34void write_reg(
const cc1101_bus *b, uint8_t addr, uint8_t val)
36 uint8_t tx[2] = {addr, val};
37 uint8_t rx[2] = {0, 0};
38 b->spi(tx, rx, 2, b->ctx);
41uint8_t read_reg(
const cc1101_bus *b, uint8_t addr,
bool status)
44 uint8_t hdr = (uint8_t)(addr | READ | (status ? BURST : 0));
45 uint8_t tx[2] = {hdr, 0};
46 uint8_t rx[2] = {0, 0};
47 b->spi(tx, rx, 2, b->ctx);
51void strobe(
const cc1101_bus *b, uint8_t cmd)
53 uint8_t tx[1] = {cmd};
55 b->spi(tx, rx, 1, b->ctx);
58uint8_t status_byte(
const cc1101_bus *b)
60 uint8_t tx[1] = {(uint8_t)(0x3D | READ | BURST)};
62 b->spi(tx, rx, 1, b->ctx);
67int16_t cc1101_rssi_dbm(uint8_t raw)
70 int16_t r = raw >= 128 ? (int16_t)raw - 256 : (int16_t)raw;
71 return (int16_t)(r / 2 - 74);
74bool cc1101_init(
const cc1101_bus *bus,
const cc1101_config *cfg)
76 if (!bus || !bus->spi || !cfg)
78 strobe(bus, STROBE_SRES);
79 for (
size_t i = 0; i < cfg->nregs && cfg->regs; i++)
80 write_reg(bus, cfg->regs[i].addr, cfg->regs[i].value);
81 write_reg(bus, REG_CHANNR, cfg->channel);
82 uint8_t ver = read_reg(bus, STAT_VERSION,
true);
83 return ver != 0x00 && ver != 0xFF;
86bool cc1101_send(
const cc1101_bus *bus,
const uint8_t *data, uint8_t len)
88 if (!bus || !bus->spi || !data || len == 0 || len > 63)
90 strobe(bus, STROBE_SIDLE);
91 strobe(bus, STROBE_SFTX);
95 tx[0] = (uint8_t)(FIFO | BURST);
97 for (uint8_t i = 0; i < len; i++)
99 bus->spi(tx, rx, (uint8_t)(2 + len), bus->ctx);
100 strobe(bus, STROBE_STX);
104bool cc1101_tx_done(
const cc1101_bus *bus)
106 if (!bus || !bus->spi)
108 uint8_t st = (uint8_t)((status_byte(bus) >> 4) & 0x07);
109 return st == STATE_IDLE;
112void cc1101_set_rx(
const cc1101_bus *bus)
114 if (!bus || !bus->spi)
116 strobe(bus, STROBE_SIDLE);
117 strobe(bus, STROBE_SFRX);
118 strobe(bus, STROBE_SRX);
121int cc1101_recv(
const cc1101_bus *bus, uint8_t *buf, uint8_t cap, int16_t *rssi_dbm)
123 if (!bus || !bus->spi || !buf)
125 uint8_t rxbytes = (uint8_t)(read_reg(bus, STAT_RXBYTES,
true) & 0x7F);
128 uint8_t len = read_reg(bus, FIFO,
false);
129 if (len == 0 || len > 63)
131 strobe(bus, STROBE_SFRX);
137 uint8_t n = (uint8_t)(len + 2);
138 tx[0] = (uint8_t)(FIFO | READ | BURST);
139 for (uint8_t i = 0; i < n; i++)
141 bus->spi(tx, rx, (uint8_t)(1 + n), bus->ctx);
143 *rssi_dbm = cc1101_rssi_dbm(rx[1 + len]);
144 uint8_t out = len < cap ? len : cap;
145 for (uint8_t i = 0; i < out; i++)
CC1101 sub-GHz radio driver (DETWS_ENABLE_CC1101) - TI 300-928 MHz over SPI.