|
esp-sdr-zephyr
Raw I/Q receive and transmit on the ESP32-S3/C6 Wi-Fi radio, for Zephyr
|
The gapless ring through three dump banks, ESP32-S3 (esp_sdr_ring.h). More...
Topics | |
| Bursts inside a run | |
Data Structures | |
| struct | esp_sdr_ring_cfg |
| struct | esp_sdr_ring_stats |
| struct | esp_sdr_ring_bench_result |
Macros | |
| #define | ESP_SDR_RING_RATE_HZ 16000000U |
| #define | ESP_SDR_RING_DECIM_MIN 64U |
| #define | ESP_SDR_RING_FULL_SCALE 16384 |
| #define | ESP_SDR_RING_DECIM_BOX4 4U |
| #define | ESP_SDR_RING_DECIM_RAW 1U |
| #define | ESP_SDR_RING_UNIT_DEFAULT 12288U |
| #define | ESP_SDR_RING_UNIT_MIN 1024U |
Typedefs | |
| typedef void(* | esp_sdr_ring_sink_t) (void *user, const int16_t *i, const int16_t *q, size_t n, uint64_t index) |
Enumerations | |
| enum | esp_sdr_ring_status { } |
Functions | |
| int | esp_sdr_ring_run (const struct esp_sdr_ring_cfg *cfg, struct esp_sdr_ring_stats *stats) |
| Stream until esp_sdr_ring_stop() or a ring failure. | |
| bool | esp_sdr_ring_wmac_hold (void) |
| Hold off the Wi-Fi MAC interrupt on the calling CPU. | |
| void | esp_sdr_ring_wmac_release (bool was_enabled) |
| Undo esp_sdr_ring_wmac_hold() on the same CPU. | |
| int | esp_sdr_ring_bench (const struct esp_sdr_ring_cfg *cfg, unsigned int units, struct esp_sdr_ring_bench_result *res) |
| Time the filter on synthetic data in bank 0, the engine idle. | |
| void | esp_sdr_ring_stop (void) |
| Ask a running esp_sdr_ring_run() to return; safe from any thread or ISR. | |
| bool | esp_sdr_ring_active (void) |
| bool | esp_sdr_ring_now (uint64_t *pair) |
| The running ring's position, from any CPU. | |
The gapless ring through three dump banks, ESP32-S3 (esp_sdr_ring.h).
| #define ESP_SDR_RING_DECIM_BOX4 4U |
Decimation by 4 (4 MS/s) for signals about 2 MHz wide, such as IEEE 802.15.4: the optional -fs/4 mix and a boxcar of 4 instead of the FIR chain, which cannot keep up at this rate. Aliasing is only suppressed by the boxcar's nulls (about 13 dB at +-1 MHz from them); full scale ESP_SDR_RING_BOX4_FULL_SCALE. Needs CONFIG_ESP_SDR_RING_BOX4 (else esp_sdr_ring_run() returns -EINVAL for it).
| #define ESP_SDR_RING_DECIM_MIN 64U |
Decimation limits (powers of two).
| #define ESP_SDR_RING_DECIM_RAW 1U |
No decimation: the sink gets the whole 16 MS/s stream, unpacked to int16 (the raw 10-bit words times 64, full scale ESP_SDR_RING_RAW_FULL_SCALE) in chunks of up to 512 pairs, the optional -fs/4 mix applied; the index is the pair index. The unpack costs about 3 of the 15 cycles per pair (4.6 with the mix): the sink has the rest, so it copies and counts, and leaves the processing to the other CPU. Needs CONFIG_ESP_SDR_RING_RAW.
The ESP_SDR_RING_RAW_HISTORY pairs before i[0] and q[0] are readable too: the stream's previous pairs (stale after a gap or at the start of a run), for a sink that filters in place. i and q are 16-byte aligned, and n and the index are multiples of 8.
| #define ESP_SDR_RING_FULL_SCALE 16384 |
Output full scale: the raw 10-bit full scale times 32.
| #define ESP_SDR_RING_RATE_HZ 16000000U |
Ring sample rate; outputs come at this rate divided by the decimation.
| #define ESP_SDR_RING_UNIT_DEFAULT 12288U |
Default unit length: 768 us at 16 MS/s.
| #define ESP_SDR_RING_UNIT_MIN 1024U |
Shortest unit: 64 us.
| typedef void(* esp_sdr_ring_sink_t) (void *user, const int16_t *i, const int16_t *q, size_t n, uint64_t index) |
Output callback, called from the ring loop with interrupts masked on its CPU: copy the samples and return quickly, never block. index is the output sample index of i[0] and q[0] since esp_sdr_ring_run() started; a jump from the previous call's index + n is a gap (lost input).
| enum esp_sdr_ring_status |
Why a run ended early.
| bool esp_sdr_ring_active | ( | void | ) |
| int esp_sdr_ring_bench | ( | const struct esp_sdr_ring_cfg * | cfg, |
| unsigned int | units, | ||
| struct esp_sdr_ring_bench_result * | res ) |
Time the filter on synthetic data in bank 0, the engine idle.
Runs units ring units (12288 pairs each) through the filter and cfg's sink with interrupts masked on the calling CPU. Not while a run is active.
| bool esp_sdr_ring_now | ( | uint64_t * | pair | ) |
The running ring's position, from any CPU.
| pair | The index of the pair the engine writes now, counted from the run's first pair (output sample k of a decimating run is pair k times the decimation). |
| int esp_sdr_ring_run | ( | const struct esp_sdr_ring_cfg * | cfg, |
| struct esp_sdr_ring_stats * | stats ) |
Stream until esp_sdr_ring_stop() or a ring failure.
Runs on the calling thread with interrupts masked on its CPU, except for short windows between polls in which pending interrupts run (the kernel timer may be armed on this CPU, and IPIs; the Wi-Fi MAC interrupt waits until the run ends), and holds the radio for the whole run: call it from a thread pinned to a CPU that nothing else needs meanwhile (cooperative, or a higher-priority thread made ready by such an interrupt preempts the run, which then ends late), and change frequency or gain between runs. A flash write on the other CPU parks this one (the loop answers the stall request) and usually ends the run with ESP_SDR_RING_LATE.
| 0 | after esp_sdr_ring_stop(). |
| -EINVAL | for a bad configuration. |
| -EAGAIN | if esp_sdr_init() has not run. |
| -EIO | if the ring failed (stats says why). |
| void esp_sdr_ring_stop | ( | void | ) |
Ask a running esp_sdr_ring_run() to return; safe from any thread or ISR.
A request made while no run is active is discarded when the next run starts. A caller that must not lose one (a settings change racing the start of a run) repeats it, or calls it again from the sink once it sees the change.
| bool esp_sdr_ring_wmac_hold | ( | void | ) |
Hold off the Wi-Fi MAC interrupt on the calling CPU.
The ring does this on its own CPU for a run. Its handler runs for hundreds of microseconds per packet the receiver decodes, and the HAL allocates it on the CPU that started Wi-Fi: a consumer of the ring's output on that other CPU calls this from a thread pinned there, for as long as the run lasts (the MAC needs no serving while the ring owns the radio).