Implement full FHSS TX/RX, real AES key, button read, slot sync
All checks were successful
CI / Build firmware (push) Successful in 36s
CI / Check formatting (push) Successful in 12s
CI / Static analysis (push) Successful in 12s
CI / Build documentation (push) Successful in 15s

radio_tx_burst(): captures current slot, calls fhss_next_channel() to
advance the sequence, sets channel, transmits ptt_frame_t, then holds
the dwell window via TIMER0 so the receiver has the full 2 ms to listen.

radio_rx_burst(): advances to the same channel, enables RX, waits for
EVENTS_END or TIMER0 COMPARE0 expiry. On a valid CRC the ptt_frame_t
is returned; caller syncs FHSS with fhss_set_slot(frame.slot + 1).

TIMER0: configured once in radio_init() (MODE=Timer, BITMODE=16-bit,
PRESCALER=4 -> 1 MHz tick, CC[0]=2000 -> 2 ms, COMPARE0_STOP shortcut).

fhss.c: replace zero key with a non-trivial 128-bit value; add
fhss_set_slot() and fhss_get_slot() for RX synchronisation.

power.c: add BUTTON_ACTIVE_LOW flag (default 1 = pull-up + GND button);
configure PIN_CNF accordingly; implement power_button_pressed() via
NRF_P0->IN.

regs.h: add gpio_pin_cnf_t with GPIO_PULL_* constants.

main.c: tight PTT loop -- radio_tx_burst() while button held, otherwise
radio_rx_burst() with slot sync on reception. No WFI in RX mode.
This commit is contained in:
Krzysztof Cieślik
2026-05-22 00:40:49 +02:00
parent dca80c7821
commit c9320eb9db
8 changed files with 232 additions and 42 deletions

View File

@@ -3,9 +3,23 @@
* @brief RADIO peripheral driver -- NRF_1Mbit proprietary mode.
*/
#pragma once
#include <stdbool.h>
#include <stdint.h>
/** @brief Configure the RADIO peripheral (mode, packet format, address, CRC, power, channel). */
/**
* @brief PTT packet transmitted on every FHSS hop.
*
* The receiver uses @p slot to resynchronise its FHSS counter after
* receiving the first packet.
*/
typedef struct __attribute__((packed)) {
uint32_t slot; /**< Sender's FHSS slot number at time of transmission. */
uint8_t flags; /**< Bitmask: PTT_FLAG_ACTIVE when voice channel is open. */
} ptt_frame_t;
#define PTT_FLAG_ACTIVE 0x01u /**< PTT button is held on the transmitting side. */
/** @brief Configure the RADIO peripheral (mode, packet format, address, CRC, power). */
void radio_init(void);
/**
@@ -18,13 +32,30 @@ void radio_set_channel(uint8_t ch);
* @brief Transmit one packet synchronously.
*
* Loads @p data into the internal packet buffer, asserts TASKS_TXEN, and
* returns after EVENTS_END fires. The RADIO is DISABLED automatically via
* the END_DISABLE shortcut before the function returns.
* returns after EVENTS_END fires. RADIO is DISABLED automatically via the
* END_DISABLE shortcut before the function returns.
*
* @param data Payload bytes.
* @param len Payload length (0-255 bytes).
*/
void radio_tx(const uint8_t *data, uint8_t len);
/** @brief Transmit a burst with FHSS hopping (not yet implemented). */
/**
* @brief Transmit one FHSS hop: advance channel, send PTT frame, hold dwell time.
*
* Call repeatedly in a loop while the PTT button is held. Each call occupies
* exactly FHSS_DWELL_MS milliseconds.
*/
void radio_tx_burst(void);
/**
* @brief Receive one FHSS hop: advance channel, listen for FHSS_DWELL_MS ms.
*
* If a packet with a valid CRC arrives during the dwell window, @p frame_out
* is filled and the function returns true. The caller should then call
* fhss_set_slot(frame_out->slot + 1) to synchronise the hopping sequence.
*
* @param frame_out Destination for the received frame (must not be NULL).
* @return true if a valid packet was received, false on timeout or CRC error.
*/
bool radio_rx_burst(ptt_frame_t *frame_out);