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

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.