23 static constexpr uint8_t CMD_R_REGISTER = 0x00;
24 static constexpr uint8_t CMD_W_REGISTER = 0x20;
25 static constexpr uint8_t CMD_R_RX_PAYLOAD = 0x61;
26 static constexpr uint8_t CMD_W_TX_PAYLOAD = 0xA0;
27 static constexpr uint8_t CMD_FLUSH_TX = 0xE1;
28 static constexpr uint8_t CMD_FLUSH_RX = 0xE2;
29 static constexpr uint8_t CMD_NOP = 0xFF;
35 static constexpr uint8_t REG_CONFIG = 0x00;
36 static constexpr uint8_t REG_EN_AA = 0x01;
37 static constexpr uint8_t REG_EN_RXADDR = 0x02;
38 static constexpr uint8_t REG_SETUP_AW = 0x03;
39 static constexpr uint8_t REG_SETUP_RETR = 0x04;
40 static constexpr uint8_t REG_RF_CH = 0x05;
41 static constexpr uint8_t REG_RF_SETUP = 0x06;
42 static constexpr uint8_t REG_STATUS = 0x07;
43 static constexpr uint8_t REG_RX_ADDR_P0 = 0x0A;
44 static constexpr uint8_t REG_TX_ADDR = 0x10;
45 static constexpr uint8_t REG_RX_PW_P0 = 0x11;
51 static constexpr uint8_t CFG_EN_CRC = 0x08;
52 static constexpr uint8_t CFG_CRCO = 0x04;
53 static constexpr uint8_t CFG_PWR_UP = 0x02;
54 static constexpr uint8_t CFG_PRIM_RX = 0x01;
60 static constexpr uint8_t ST_RX_DR = 0x40;
61 static constexpr uint8_t ST_TX_DS = 0x20;
62 static constexpr uint8_t ST_RX_P_NO = 0x0E;
65void reg_write(
const nrf_bus *b, uint8_t reg, uint8_t val)
67 uint8_t tx[2] = {(uint8_t)(Nrf24Cmd::CMD_W_REGISTER | reg), val};
69 b->spi(tx, rx, 2, b->ctx);
72uint8_t reg_read(
const nrf_bus *b, uint8_t reg)
74 uint8_t tx[2] = {(uint8_t)(Nrf24Cmd::CMD_R_REGISTER | reg), 0xFF};
76 b->spi(tx, rx, 2, b->ctx);
80void reg_write_buf(
const nrf_bus *b, uint8_t reg,
const uint8_t *buf, uint8_t n)
84 tx[0] = (uint8_t)(Nrf24Cmd::CMD_W_REGISTER | reg);
85 for (uint8_t i = 0; i < n; i++)
87 b->spi(tx, rx, (uint8_t)(n + 1), b->ctx);
90uint8_t status(
const nrf_bus *b)
92 uint8_t tx[1] = {Nrf24Cmd::CMD_NOP};
94 b->spi(tx, rx, 1, b->ctx);
98void cmd(
const nrf_bus *b, uint8_t c)
102 b->spi(tx, rx, 1, b->ctx);
106bool nrf24_init(
const nrf_bus *bus,
const nrf_config *cfg)
108 if (!bus || !bus->spi || !bus->ce || !cfg || !cfg->address)
110 bus->ce(
false, bus->ctx);
112 reg_write(bus, Nrf24Reg::REG_CONFIG, Nrf24Cfg::CFG_EN_CRC | Nrf24Cfg::CFG_CRCO);
113 reg_write(bus, Nrf24Reg::REG_RF_CH, cfg->channel);
114 if (reg_read(bus, Nrf24Reg::REG_RF_CH) != cfg->channel)
117 reg_write(bus, Nrf24Reg::REG_SETUP_AW, 0x03);
118 reg_write(bus, Nrf24Reg::REG_EN_RXADDR, 0x01);
119 reg_write(bus, Nrf24Reg::REG_EN_AA, 0x00);
120 reg_write(bus, Nrf24Reg::REG_SETUP_RETR, 0x00);
122 if (cfg->data_rate == 1)
124 else if (cfg->data_rate == 2)
126 reg_write(bus, Nrf24Reg::REG_RF_SETUP, (uint8_t)(dr | ((cfg->tx_power & 0x03) << 1)));
128 reg_write_buf(bus, Nrf24Reg::REG_RX_ADDR_P0, cfg->address, 5);
129 reg_write_buf(bus, Nrf24Reg::REG_TX_ADDR, cfg->address, 5);
131 cmd(bus, Nrf24Cmd::CMD_FLUSH_RX);
132 cmd(bus, Nrf24Cmd::CMD_FLUSH_TX);
133 reg_write(bus, Nrf24Reg::REG_STATUS, Nrf24Status::ST_RX_DR | Nrf24Status::ST_TX_DS | 0x10);
135 reg_write(bus, Nrf24Reg::REG_CONFIG,
136 Nrf24Cfg::CFG_EN_CRC | Nrf24Cfg::CFG_CRCO | Nrf24Cfg::CFG_PWR_UP);
140bool nrf24_send(
const nrf_bus *bus,
const uint8_t *data, uint8_t len)
144 bus->ce(
false, bus->ctx);
145 reg_write(bus, Nrf24Reg::REG_CONFIG,
146 Nrf24Cfg::CFG_EN_CRC | Nrf24Cfg::CFG_CRCO | Nrf24Cfg::CFG_PWR_UP);
150 tx[0] = Nrf24Cmd::CMD_W_TX_PAYLOAD;
152 tx[1 + i] = (i < len) ? data[i] : 0x00;
155 bus->ce(
true, bus->ctx);
159bool nrf24_tx_done(
const nrf_bus *bus)
163 if (status(bus) & Nrf24Status::ST_TX_DS)
165 reg_write(bus, Nrf24Reg::REG_STATUS, Nrf24Status::ST_TX_DS);
171void nrf24_set_rx(
const nrf_bus *bus)
175 reg_write(bus, Nrf24Reg::REG_CONFIG,
176 Nrf24Cfg::CFG_EN_CRC | Nrf24Cfg::CFG_CRCO | Nrf24Cfg::CFG_PWR_UP | Nrf24Cfg::CFG_PRIM_RX);
177 bus->ce(
true, bus->ctx);
180int nrf24_recv(
const nrf_bus *bus, uint8_t *buf, uint8_t cap, uint8_t *pipe)
184 uint8_t st = status(bus);
185 if (!(st & Nrf24Status::ST_RX_DR))
187 uint8_t p = (uint8_t)((st & Nrf24Status::ST_RX_P_NO) >> 1);
190 reg_write(bus, Nrf24Reg::REG_STATUS, Nrf24Status::ST_RX_DR);
195 tx[0] = Nrf24Cmd::CMD_R_RX_PAYLOAD;
201 for (uint8_t i = 0; i < n; i++)
205 reg_write(bus, Nrf24Reg::REG_STATUS, Nrf24Status::ST_RX_DR);
#define DETWS_NRF24_PAYLOAD
nRF24 fixed payload width in bytes (1..32; the chip's static payload size).
nRF24L01+ radio driver (DETWS_ENABLE_NRF24) - Nordic 2.4 GHz over SPI.