Skip to content

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

Parameter 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.

Return

void

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

Parameter 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.

Return

void

Defines

Name Value Description
RF_SLOTS_PROCESS(_NAME, _STATUS, _STORAGE) - Define a RF_SLOTS process handler.
RF_SLOTS_SUBPROCESS(_NAME, ...) - Define a RF_SLOTS subprocess handler.
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);

Should only be used in a RF_SLOTS_(SUB)PROCESS

RF_SLOTS_PROCESS_BEGIN() PT_BEGIN(_rf_slots_pt) Starts the rf-slots handler inside the C function declaring the rf-slots (sub)process.

Should only be used in a RF_SLOTS_(SUB)PROCESS

RF_SLOTS_PROCESS_END() PT_END(_rf_slots_pt) Ends the rf-slots handler inside the C function declaring the rf-slots (sub)process.

Should only be used in a RF_SLOTS_(SUB)PROCESS

RF_SLOTS_PROCESS_EXIT() PT_EXIT(_rf_slots_pt) Exit the rf-slots handler.

Should only be used in a RF_SLOTS_(SUB)PROCESS

RF_SLOTS_PROCESS_EXTEND(_TARGET_TIME) - Extend the requested time slot.

Should only be used in a RF_SLOTS_(SUB)PROCESS

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.

Should only be used in a RF_SLOTS_(SUB)PROCESS

RF_SLOTS_PROCESS_DELAY(_TARGET_TIME) - Delay further code until TARGET_TIME has happened.

Should only be used in a RF_SLOTS(SUB)PROCESS

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.

Should only be used in a RF_SLOTS_(SUB)PROCESS

RF_SLOTS_PROCESS_TX(_TARGET_TIME, _CONFIG) - Transmit the radio packet.

The packet should already have been placed in the buffer returned byrf_slots_get_packet_ptr()rf_slots_set_packet_length()

CONFIG is arf_slots_radio_config_t

Should only be used in a RF_SLOTS(SUB)PROCESS

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 arf_slots_radio_config_t

Should only be used in a RF_SLOTS(SUB)PROCESS

RF_SLOTS_PROCESS_RX_IMM(_END_TIME, _CONFIG) - Tell the radio to listen for a packet, for at most END_TIME.

_CONFIG is arf_slots_radio_config_t

Should only be used in a RF_SLOTS(SUB)PROCESS

RF_SLOTS_PROCESS_RX_POWER(_DEST, _CONFIG) - Get channel RF power.

CONFIG is arf_slots_radio_config_t

should only be used in a RF_SLOTS(SUB)PROCESS

RF_SLOTS_FE_NUM_PINS 4
RF_SLOTS_FE_MAX_ANTENNAS 4
RF_SLOTS_RADIO_POWER_MAX INT16_MAX
RF_SLOTS_RADIO_POWER_MIN INT16_MIN

Types

Name Type Description
rf_slots_radio_power_t int16_t

Power in unit of cBm, which is 1/10 of dBm

rf_slots_radio_antenna_t uint8_t

Antenna index

rf_slots_slot_t struct

Used by the RF-Slots implementation, not part of the public API.

Enums

rf_slots_status_t

Name Value Description
RF_SLOTS_STATUS_SUCCESS 0
RF_SLOTS_STATUS_FAIL
RF_SLOTS_STATUS_ABORT

rf_slots_action_num_t

Name Value Description
RF_SLOTS_ACTION_NUM_UNSET 0

Default, to see if isn't properly updated. Never set in the handler

RF_SLOTS_ACTION_NUM_EXIT
RF_SLOTS_ACTION_NUM_SYNC
RF_SLOTS_ACTION_NUM_EXTEND
RF_SLOTS_ACTION_NUM_DELAY
RF_SLOTS_ACTION_NUM_CALL
RF_SLOTS_ACTION_NUM_TX
RF_SLOTS_ACTION_NUM_RX
RF_SLOTS_ACTION_NUM_RX_POWER

rf_slots_radio_mode_t

Name Value Description
RF_SLOTS_RADIO_MODE_MIRA
RF_SLOTS_RADIO_MODE_BLE

rf_slots_timing_mode_t

Name Value Description
RF_SLOTS_TIMING_MODE_EARLIEST
RF_SLOTS_TIMING_MODE_TIME

Structs

rf_slots_frontend_config_t

Type Name Description
int16_t mode_tx_bypass_gain
int16_t mode_tx_active_gain
int16_t mode_rx_bypass_gain
int16_t mode_rx_active_gain
uint16_t mode_tx_bypass_pin_values
uint16_t mode_tx_active_pin_values
uint16_t mode_rx_bypass_pin_values
uint16_t mode_rx_active_pin_values
uint16_t mode_idle_pin_values
uint16_t antsel_idle_pin_values
uint16_t[RF_SLOTS_FE_MAX_ANTENNAS] antsel_pin_values
uint16_t[RF_SLOTS_FE_NUM_PINS] mode_gpios
uint16_t[RF_SLOTS_FE_NUM_PINS] antsel_gpios

Structs

rf_slots_radio_config_t

Type Name Description
rf_slots_radio_mode_t mode
uint32_t access_address
uint8_t frequency
rf_slots_radio_power_t radio_power
rf_slots_radio_antenna_t antenna
bool low_power_mode

Structs

rf_slots_action_t

Type Name Description
rf_slots_action_num_t num
miracore_timer_time_t target_time
struct rf_slots_action_t::@4::@5 extend
struct rf_slots_action_t::@4::@6 delay
void(*)(void *storage) callback
void * storage
struct rf_slots_action_t::@4::@7 call
rf_slots_radio_config_t config
struct rf_slots_action_t::@4::@8 tx
miracore_timer_interval_t window_length
struct rf_slots_action_t::@4::@9 rx
rf_slots_radio_power_t dest
struct rf_slots_action_t::@4::@10 rx_power
union rf_slots_action_t::@4 data

Structs

rf_slots_slot

Type Name Description
rf_slots_slot next
rf_slots_timing_mode_t timing_mode
miracore_timer_time_t start_time
miracore_timer_interval_t expected_duration
pt pt
rf_slots_slot_handler_t handler
bool running
void * storage

Functions

PT_THREAD

typedef PT_THREAD(
    (*rf_slots_slot_handler_t)(struct pt*  pt,
    rf_slots_slot_t*                       process,
    rf_slots_action_t*                     action,
    rf_slots_status_t                      status,
    void*                                  storage));

Note: Used by the RF-Slots implementation, not part of the public API.

Return

typedef

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

Return

uint8_t*

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

Return

uint16_t

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

Return

void

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

Return

miracore_timer_time_t

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

Return

miracore_timer_time_t

rf_slots_set_frontend_config

int rf_slots_set_frontend_config(
    const rf_slots_frontend_config_t*  frontend);

Set active frontend configuration

returns zero on success, non-zero on error

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.