Implement full FHSS TX/RX, real AES key, button read, slot sync
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:
@@ -10,18 +10,29 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
/** Dwell time per channel in milliseconds. */
|
||||
#define FHSS_DWELL_MS 2u
|
||||
|
||||
/** Number of channels in the hopping sequence. */
|
||||
#define FHSS_CHANNELS 40u
|
||||
|
||||
/** @brief Reset the slot counter to zero. */
|
||||
void fhss_init(void);
|
||||
|
||||
/**
|
||||
* @brief Return the next channel in the hopping sequence.
|
||||
*
|
||||
* Encrypts the current slot counter big-endian with AES-128-ECB, returns
|
||||
* @c block[0] % 40, and advances the slot counter.
|
||||
*
|
||||
* @brief Return the next channel in the hopping sequence and advance the slot.
|
||||
* @return Channel index in [0, 39].
|
||||
*/
|
||||
uint8_t fhss_next_channel(void);
|
||||
|
||||
/** @brief Advance the slot counter without transmitting (receiver side). */
|
||||
/** @brief Advance the slot counter by one (receiver side, no packet received). */
|
||||
void fhss_sync_tick(void);
|
||||
|
||||
/**
|
||||
* @brief Force the slot counter to a specific value for RX synchronisation.
|
||||
* @param s New slot value.
|
||||
*/
|
||||
void fhss_set_slot(uint32_t s);
|
||||
|
||||
/** @brief Return the current slot counter value. */
|
||||
uint32_t fhss_get_slot(void);
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
/**
|
||||
* @file power.h
|
||||
* @brief Power management: DC/DC regulator, GPIOTE wakeup, SYSTEM_ON sleep.
|
||||
* @brief Power management: DC/DC regulator, GPIOTE wakeup, WFI sleep.
|
||||
*/
|
||||
#pragma once
|
||||
#include <stdbool.h>
|
||||
|
||||
/** @brief Enable the DC/DC converter and configure GPIOTE wakeup on the PTT button. */
|
||||
/** @brief Enable the DC/DC converter, configure GPIO input and GPIOTE wakeup on the PTT button. */
|
||||
void power_init(void);
|
||||
|
||||
/**
|
||||
@@ -14,3 +15,9 @@ void power_init(void);
|
||||
* interrupt fires (button press) and resumes from here.
|
||||
*/
|
||||
void power_sleep_until_button(void);
|
||||
|
||||
/**
|
||||
* @brief Return the current state of the PTT button.
|
||||
* @return true when the button is pressed.
|
||||
*/
|
||||
bool power_button_pressed(void);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -153,3 +153,24 @@ typedef union {
|
||||
} bit;
|
||||
uint32_t reg;
|
||||
} radio_shorts_t;
|
||||
|
||||
/* GPIO */
|
||||
|
||||
/** @brief GPIO PIN_CNF[n]: pin configuration register. */
|
||||
typedef union {
|
||||
struct {
|
||||
uint32_t DIR : 1; /* [0] 0=Input 1=Output */
|
||||
uint32_t INPUT : 1; /* [1] 0=Connect 1=Disconnect */
|
||||
uint32_t PULL : 2; /* [3:2] 0=Disabled 1=Pulldown 3=Pullup */
|
||||
uint32_t : 4; /* [7:4] reserved */
|
||||
uint32_t DRIVE : 3; /* [10:8] 0=S0S1 standard drive */
|
||||
uint32_t : 5; /* [15:11] reserved */
|
||||
uint32_t SENSE : 2; /* [17:16] 0=Disabled 2=SenseHigh 3=SenseLow */
|
||||
uint32_t : 14; /* [31:18] reserved */
|
||||
} bit;
|
||||
uint32_t reg;
|
||||
} gpio_pin_cnf_t;
|
||||
|
||||
#define GPIO_PULL_DISABLED 0u
|
||||
#define GPIO_PULL_PULLDOWN 1u
|
||||
#define GPIO_PULL_PULLUP 3u
|
||||
|
||||
Reference in New Issue
Block a user