DeterministicESPAsyncWebServer v6.27.1
Zero-allocation, bounded-execution async HTTP server for ESP32
Loading...
Searching...
No Matches
nrf24.h
Go to the documentation of this file.
1// Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4/**
5 * @file nrf24.h
6 * @brief nRF24L01+ radio driver (DETWS_ENABLE_NRF24) - Nordic 2.4 GHz over SPI.
7 *
8 * A radio driver plugin for the gateway (DETWS_ENABLE_GATEWAY): cheap point-to-multipoint
9 * 2.4 GHz sensor links bridged to the web stack. Unlike the SX127x (plain register
10 * read/write), the nRF24L01+ speaks an **SPI command protocol** (each transaction is a
11 * command byte + data, and every command returns the STATUS register) and needs a separate
12 * **CE** pin to key RX/TX - so the driver runs over an @ref nrf_bus that carries a
13 * full-duplex SPI transfer plus a CE-set callback. That is the only board-specific code.
14 *
15 * The nRF24 does its own **hardware addressing** (5-byte pipe addresses), so a received
16 * frame's "source" is the pipe number it arrived on - there is no in-payload header and
17 * therefore no separate codec. It uses a **static payload width** (DETWS_NRF24_PAYLOAD):
18 * every frame is that many bytes (a short send is zero-padded). Bridge received payloads
19 * northbound with det_gw_uplink(port, pipe, payload, width, 0). The register/command
20 * protocol is host-testable against a mock; the RF link needs the module.
21 *
22 * @author Douglas Quigg (dstroy0)
23 * @date 2026
24 */
25
26#ifndef DETERMINISTICESPASYNCWEBSERVER_NRF24_H
27#define DETERMINISTICESPASYNCWEBSERVER_NRF24_H
28
29#include "ServerConfig.h"
30
31#if DETWS_ENABLE_NRF24
32
33#include <stddef.h>
34#include <stdint.h>
35
36/** @brief Full-duplex SPI transfer of @p len bytes (chip-select toggled by the callback). */
37typedef void (*nrf_spi_fn)(const uint8_t *tx, uint8_t *rx, uint8_t len, void *ctx);
38/** @brief Drive the CE pin (true = high). */
39typedef void (*nrf_ce_fn)(bool level, void *ctx);
40
41/** @brief The bus a driver call uses: your SPI transfer + CE control behind it. */
42struct nrf_bus
43{
44 nrf_spi_fn spi;
45 nrf_ce_fn ce;
46 void *ctx;
47};
48
49/** @brief Radio configuration applied by nrf24_init(). */
50struct nrf_config
51{
52 const uint8_t *address; ///< 5-byte pipe-0 / TX address (RX and TX share it here).
53 uint8_t channel; ///< RF channel 0..125 (2400 + channel MHz).
54 uint8_t data_rate; ///< 0 = 1 Mbps, 1 = 2 Mbps, 2 = 250 kbps.
55 uint8_t tx_power; ///< power level 0..3 (-18, -12, -6, 0 dBm).
56};
57
58/**
59 * @brief Configure the nRF24L01+ and power it up (standby).
60 * @return true; false if a written register does not read back - i.e. the bus is not
61 * talking to the chip.
62 */
63bool nrf24_init(const nrf_bus *bus, const nrf_config *cfg);
64
65/**
66 * @brief Transmit @p len bytes (zero-padded to DETWS_NRF24_PAYLOAD). Poll nrf24_tx_done().
67 * @return true; false if @p len exceeds DETWS_NRF24_PAYLOAD.
68 */
69bool nrf24_send(const nrf_bus *bus, const uint8_t *data, uint8_t len);
70
71/** @brief True once a transmit has finished (STATUS TX_DS); clears the flag. */
72bool nrf24_tx_done(const nrf_bus *bus);
73
74/** @brief Enter receive mode (PRX + CE high); then poll nrf24_recv(). */
75void nrf24_set_rx(const nrf_bus *bus);
76
77/**
78 * @brief If a frame is waiting, copy it into @p buf and report the pipe it arrived on.
79 * @param[out] pipe set to the receiving pipe number 0..5 (may be null).
80 * @return the payload width (DETWS_NRF24_PAYLOAD, capped at @p cap), or -1 if none.
81 */
82int nrf24_recv(const nrf_bus *bus, uint8_t *buf, uint8_t cap, uint8_t *pipe);
83
84#endif // DETWS_ENABLE_NRF24
85
86#endif // DETERMINISTICESPASYNCWEBSERVER_NRF24_H
User-facing configuration for DeterministicESPAsyncWebServer.