Shared Radio Support¶
The API for Sharing the radio between Mira and other protocols is split in two parts. The mira_radio_timeslots_ functions are used to schedule RF_SLOTS handlers, and the rf-slots API is used to define them.
Notes¶
Using another protocol concurrently with Mira will lower the performance of Mira. That leads to a lower PDR/more missing packets. The actual impact depends on the network rate and how often the other protocol's rf-slots usage.
The rf_slots_radio_mode_t
enum and rf_slots_radio_config_t.mode
will be replaced in future versions of rf-slots to allow other and
custom frame formats.
Functions¶
mira_radio_timeslot_schedule_at¶
void mira_radio_timeslot_schedule_at(rf_slots_slot_t *slot, miracore_timer_time_t start_time, miracore_timer_interval_t expected_duration, rf_slots_slot_handler_t handler, void *storage);
Schedule a rf_slots_slot_handler_t to start at a given time.
Parameters
Name | Description |
---|---|
slot | pointer to a rf_slots_slot_t that needs to be valid until the handler is done/aborted. |
start_time | when the radio is to be used. |
expected_duration | how long the radio is scheduled. |
handler | The handlar that is to be run. |
storage | A pointer passed on to the handler. |
mira_radio_timeslot_schedule_immediatly¶
void mira_radio_timeslot_schedule_immediatly(rf_slots_slot_t *slot, miracore_timer_interval_t latency, miracore_timer_interval_t expected_duration, rf_slots_slot_handler_t handler, void *storage);
Schedule a rf_slots_slot_handler_t to start at now + latency.
The slot is starting as soon as possible after a delay of latency
Parameters
Name | Description |
---|---|
slot | pointer to a rf_slots_slot_t that needs to be valid until the handler is done/aborted. |
latency | how long the start can wait and still be relevant. |
expected_duration | how long the radio is scheduled. |
handler | The handlar that is to be run. |
storage | A pointer passed on to the handler. |
Defines¶
RF_SLOTS_SUBPROCESS¶
#define RF_SLOTS_SUBPROCESS(_NAME, ...)
Define a RF_SLOTS subprocess handler.
RF_SLOTS_PROCESS¶
#define RF_SLOTS_PROCESS(_NAME, _STORAGE)
Define a RF_SLOTS process handler.
RF_SLOTS_SUBPROCESS_CALL¶
#define RF_SLOTS_SUBPROCESS_CALL(_NAME, ...)
Call a subprocess from a process.
Example
// Define subprocess:
RF_SLOTS_SUBPROCESS(my_tx_handler, uint8_t *packet, uint16_r packet_len);
// ...
RF_SLOTS_SUBPROCESS_CALL(my_tx_handler, current_packet, current_packet_len);
Note
Should only be used in a RF_SLOTS_(SUB)PROCESS
RF_SLOTS_PROCESS_BEGIN¶
#define RF_SLOTS_PROCESS_BEGIN()
Starts the rf-slots handler inside the C function declaring the rf-slots (sub)process.
Note
Should only be used in a RF_SLOTS_(SUB)PROCESS
RF_SLOTS_PROCESS_BEGIN_CLEANUP¶
#define RF_SLOTS_PROCESS_BEGIN_CLEANUP()
Ends the rf-slots handler inside the C function declaring the rf-slots (sub)process.
Note
Should only be used in a RF_SLOTS_(SUB)PROCESS
RF_SLOTS_PROCESS_END¶
#define RF_SLOTS_PROCESS_END()
Ends the rf-slots handler inside the C function declaring the rf-slots (sub)process.
Note
Should only be used in a RF_SLOTS_(SUB)PROCESS
RF_SLOTS_PROCESS_EXIT¶
#define RF_SLOTS_PROCESS_EXIT()
Exit the rf-slots handler.
Note
Should only be used in a RF_SLOTS_(SUB)PROCESS
RF_SLOTS_PROCESS_STATUS¶
#define RF_SLOTS_PROCESS_STATUS()
Get status from previous call
Note
Should only be used in a RF_SLOTS_(SUB)PROCESS
RF_SLOTS_PROCESS_EXTEND¶
#define RF_SLOTS_PROCESS_EXTEND(_TARGET_TIME)
Extend the requested time slot.
Note
Should only be used in a RF_SLOTS_(SUB)PROCESS
RF_SLOTS_PROCESS_SYNC¶
#define RF_SLOTS_PROCESS_SYNC()
Sync the rf-slots handler and the long term time source.
rf-slots uses a high resolution clock for scheduling slot events, but the clock does not have many bits so it wraps around after a short while.
That clock is synchronized with a low resolution clock at the start of a slot. For long running slots, the clock needs to be resynchronized once in a while before it wraps around. This function does that.
Note
Should only be used in a RF_SLOTS_(SUB)PROCESS
RF_SLOTS_PROCESS_DELAY¶
#define RF_SLOTS_PROCESS_DELAY(_TARGET_TIME)
Delay further code until _TARGET_TIME has happened.
Note
Should only be used in a RF_SLOTS_(SUB)PROCESS
RF_SLOTS_PROCESS_CALL¶
#define RF_SLOTS_PROCESS_CALL(_TARGET_TIME, _CALLBACK, _STORAGE)
Call a function on a lower irq level.
On NRF with SoftDevice the rf-slots handler runs from a SoftDevice callback which prevents calling sd_-functions. Code using sd_* functions must be run at a lower irq priority and that is done with this function.
Note
Should only be used in a RF_SLOTS_(SUB)PROCESS
RF_SLOTS_PROCESS_TX¶
#define RF_SLOTS_PROCESS_TX(_TARGET_TIME, _CONFIG)
Transmit the radio packet.
The packet should already have been placed in the buffer returned by rf_slots_get_packet_ptr() and rf_slots_set_packet_length() should have been called.
- _CONFIG is a rf_slots_radio_config_t struct.
Note
Should only be used in a RF_SLOTS_(SUB)PROCESS
RF_SLOTS_PROCESS_RX_WIN¶
#define RF_SLOTS_PROCESS_RX_WIN(_CENTER_TIME, _WINDOW_LENGTH, _CONFIG)
Tell the radio to listen for a packet during the time window.
If a packet is being received when the window ends, the listening window is extended to allow the reception of the whole packet.
- _CENTER_TIME when the packet is expected to be received.
- _WINDOW_LENGTH the receive window of the packet.
- _CONFIG is a rf_slots_radio_config_t struct.
Note
Should only be used in a RF_SLOTS_(SUB)PROCESS
RF_SLOTS_PROCESS_RX_IMM¶
#define RF_SLOTS_PROCESS_RX_IMM(_END_TIME, _CONFIG)
Tell the radio to listen for a packet, for at most _END_TIME.
- _CONFIG is a rf_slots_radio_config_t struct.
Note
Should only be used in a RF_SLOTS_(SUB)PROCESS
RF_SLOTS_PROCESS_RX_POWER¶
#define RF_SLOTS_PROCESS_RX_POWER(_DEST, _CONFIG)
Get channel RF power.
- _CONFIG is a rf_slots_radio_config_t struct.
Note
should only be used in a RF_SLOTS_(SUB)PROCESS
RF_SLOTS_RADIO_POWER_MAX¶
#define RF_SLOTS_RADIO_POWER_MAX
Maximum configurable radio power
This value is not the maximum output power, but the maximum value to put in the output power field
RF_SLOTS_RADIO_POWER_MIN¶
#define RF_SLOTS_RADIO_POWER_MIN
Maximum configurable radio power
This value is not the minimum output power, but the minimum value to put in the output power field
Types¶
rf_slots_radio_power_t¶
typedef int16_t rf_slots_radio_power_t;
Power in unit of cBm, which is 1/10 of dBm
rf_slots_radio_antenna_t¶
typedef uint8_t rf_slots_radio_antenna_t;
Antenna index
rf_slots_slot_t¶
typedef struct rf_slots_slot rf_slots_slot_t;
Storage for a scheduled slot
Enums¶
rf_slots_status_t¶
Status of previous operation within an rf slot. Return value of RF_SLOTS_PROCESS_STATUS()
Name | Description |
---|---|
RF_SLOTS_STATUS_SUCCESS |
|
RF_SLOTS_STATUS_FAIL |
|
RF_SLOTS_STATUS_ABORT |
rf_slots_radio_mode_t¶
The radio mode used to send/receive packets.
Used as mode in rf_slots_radio_config_t
Name | Description |
---|---|
RF_SLOTS_RADIO_MODE_BLE_1MBPS |
Structs¶
rf_slots_radio_config_t¶
Radio and packet format configuration
Note: To be compatible with future versions of Mira and allow more parameters to be added, make sure all non-used padding bytes in the struct is set to zero.
Recommended to call memset() before initializing the parameters, or changing mode:
memset(&config, 0, sizeof(rf_slots_radio_config_t));
Name | Type | Description |
---|---|---|
mode |
rf_slots_radio_mode_t |
|
access_address |
uint32_t |
|
frequency |
uint8_t |
|
white_iv |
uint8_t |
|
preamble_bits |
uint8_t |
|
length_bits |
uint8_t |
|
s0_bits |
uint8_t |
|
s1_bits |
uint8_t |
|
ble_1mbps |
struct rf_slots_radio_config_t::@4::@6 |
|
fmt |
union rf_slots_radio_config_t::@4 |
|
radio_power |
rf_slots_radio_power_t |
|
antenna |
rf_slots_radio_antenna_t |
|
low_power_mode |
bool |
|
rf |
struct rf_slots_radio_config_t::@5 |
rf_slots_slot¶
Storage for a scheduled slot
No parameters in this struct is intended to be directly accessed by the user.
Name | Type | Description |
---|---|---|
parameters_hidden |
int |
No parameters in this struct should be updated by user directly |
Functions¶
rf_slots_radio_config_is_valid¶
bool rf_slots_radio_config_is_valid(const rf_slots_radio_config_t *config);
Check if a radio packet configuration is valid.
Checks if a given radio packet configuration is valid and supported by the current radio hardware.
Note
This function is stateless, and can be executed both in IRQ and thread
rf_slots_get_packet_ptr¶
uint8_t* rf_slots_get_packet_ptr(void);
Get pointer to the packet buffer.
Note
Should only be used in a RF_SLOTS_(SUB)PROCESS
rf_slots_get_packet_header_ptr¶
uint8_t* rf_slots_get_packet_header_ptr(void);
Get pointer to storage for packet header.
For BLE 1Mbps packets, it's the s0 and s1 fields Both s0 and s1 fields are stored bytes aligned, and padded with 0 so each field fill a whole byte. Content of the field is stored in LSB for each field
Note
Should only be used in a RF_SLOTS_(SUB)PROCESS
rf_slots_get_packet_length¶
uint16_t rf_slots_get_packet_length(void);
Get length of last received packet.
Note
Should only be used in a RF_SLOTS_(SUB)PROCESS
rf_slots_set_packet_length¶
void rf_slots_set_packet_length(uint16_t length);
Set length of the packet buffer to send.
Note
Should only be used in a RF_SLOTS_(SUB)PROCESS
rf_slots_get_packet_rssi¶
rf_slots_radio_power_t rf_slots_get_packet_rssi(void);
Get RSSI of last received packet.
Note
Should only be used in a RF_SLOTS_(SUB)PROCESS
rf_slots_get_packet_time¶
miracore_timer_time_t rf_slots_get_packet_time(void);
Get the time the last packet was received.
Note
Should only be used in a RF_SLOTS_(SUB)PROCESS
rf_slots_get_time_now¶
miracore_timer_time_t rf_slots_get_time_now(void);
Get the current time in high precision.
Note
Should only be used in a RF_SLOTS_(SUB)PROCESS
rf_slots_get_actual_power¶
rf_slots_radio_power_t rf_slots_get_actual_power(const rf_slots_radio_config_t *config);
Get actual TX power given a radio configuration
This method is safe to run independent of rf-slot state.
If called from interrupt while rf_slots_set_frontend_config is running, the behaviour is undefined
rf_slots_get_max_power¶
rf_slots_radio_power_t rf_slots_get_max_power(const rf_slots_radio_config_t *config);
Get the maximum TX power given a radio configuration
This method is safe to run independent of rf-slot state.
If called from interrupt while rf_slots_set_frontend_config is running, the behaviour is undefined
rf_slots_timer_diff¶
miracore_timer_interval_t rf_slots_timer_diff(miracore_timer_time_t a, miracore_timer_time_t b);
Get the difference between two miracore_timer_time_t.