Structure that parameterizes SL_RAIL_RX_CHANNEL_HOPPING_MODE_MULTI_SENSE.

Every sl_rail_rx_channel_hopping_config_entry_t or sl_rail_rx_duty_cycle_config_t that uses SL_RAIL_RX_CHANNEL_HOPPING_MODE_MULTI_SENSE must allocate one of these structures in global read-write memory to provide the settings for this mode and for RAIL to use during hopping or duty cycling. A pointer to this structure, cast appropriately, is what is passed in the corresponding sl_rail_rx_channel_hopping_config_entry_t::parameter or sl_rail_rx_duty_cycle_config_t::parameter.

The contents of this structure must be initialized prior to each sl_rail_config_rx_channel_hopping() or sl_rail_config_rx_duty_cycle() call and must not be touched thereafter until the next such call. RAIL may change these contents during configuration or operation.

This mode of operation functions algorithmically like this pseudocode:

extern bool channel_hopping; // true if channel hopping, false if duty cycling
extern sl_rail_rx_channel_hopping_config_entry_t *hop_config_entry; // current channel

static sl_rail_rx_channel_hopping_config_multi_mode_t *multi_params;
static sl_rail_time_t rx_start_time;
static bool preamble_sensed;

static void hop_or_suspend_rx(uint32_t delay)
{
  disable_demod_events();
  disable_timer_events();
  stop_timer();
  if (channel_hopping) {
    hop_to_next_channel(delay, &hop_config_entry); // updates hop_config_entry
  } else {
    suspend_rx(delay);
  }
  on_start_rx(); // resume receive after delay (on new channel if hopping)
}

void on_start_rx(void) // called upon entry to receive
{
  rx_start_time = sl_rail_get_time(SL_RAIL_EFR32_HANDLE);
  multi_params = (sl_rail_rx_channel_hopping_config_multi_mode_t *)
                 (void *)hop_config_entry->parameter;
  start_timer(rx_start_time + multi_params->timing_sense);
  preamble_sensed = false;
  enable_timer_events(); // timer will trigger on_timer_event() handler
  enable_demod_events(); // demod will trigger on_demod_event() handler
}

void on_timer_event(void) // called when timer expires
{
  hop_or_suspend_rx(hop_config_entry->delay);
}

void on_demod_event(void) // called when demodulator state changes
{
  if (DEMOD_TIMING_SENSED) {
    stop_timer();
    start_timer(rx_start_time + multi_params->sync_detect);
  }
  if (DEMOD_TIMING_LOST) {
    stop_timer();
    uint32_t new_timeout = sl_rail_get_time(SL_RAIL_EFR32_HANDLE) + multi_params->timing_re_sense;
    uint32_t limit_timeout;
    if (preamble_sensed) {
      limit_timeout = rx_start_time + multi_params->sync_detect;
    } else {
      limit_timeout = rx_start_time + multi_params->preamble_sense;
    }
    if (new_timeout > limit_timeout) {
      new_timeout = limit_timeout;
    }
    if (new_timeout > sl_rail_get_time(SL_RAIL_EFR32_HANDLE)) {
      start_timer(new_timeout);
    } else {
      hop_or_suspend_rx(hop_config_entry->delay);
    }
  }
  if (DEMOD_PREAMBLE_SENSED) {
    preamble_sensed = true;
  }
  if (DEMOD_PREAMBLE_LOST) {
    preamble_sensed = false;
  }
  if (DEMOD_SYNC_DETECTED) {
    disable_demod_events();
    disable_timer_events();
    stop_timer();
    receive_packet(); // stay on channel to receive frame
    hop_or_suspend_rx(0); // continue RX per state transitions with no delay
  }
}

Public Attributes#

uint32_t

Switch to the next channel if sync is not detected before this time, in microseconds, measured from entry to Rx.

uint32_t

Switch to the next channel if timing was sensed but then lost after this time, in microseconds, measured from entry to Rx – unless preamble had been sensed in which case any switching is deferred to timing_re_sense and, if timing is regained, to sync_detect.

uint32_t

Switch to the next channel if timing is not sensed before this time, in microseconds, measured from entry to Rx.

uint32_t

Switch to the next channel if timing was sensed but then lost and not regained before this time, in microseconds, measured from when timing was lost.

uint32_t

Set this to 0.

Public Attribute Documentation#

sync_detect_us#

uint32_t sl_rail_rx_channel_hopping_config_multi_mode_t::sync_detect_us

Switch to the next channel if sync is not detected before this time, in microseconds, measured from entry to Rx.

This must be greater than preamble_sense and less than SL_RAIL_RX_CHANNEL_HOPPING_MAX_SENSE_TIME_US.


preamble_sense_us#

uint32_t sl_rail_rx_channel_hopping_config_multi_mode_t::preamble_sense_us

Switch to the next channel if timing was sensed but then lost after this time, in microseconds, measured from entry to Rx – unless preamble had been sensed in which case any switching is deferred to timing_re_sense and, if timing is regained, to sync_detect.

This must be greater than timing_sense and less than SL_RAIL_RX_CHANNEL_HOPPING_MAX_SENSE_TIME_US.


timing_sense_us#

uint32_t sl_rail_rx_channel_hopping_config_multi_mode_t::timing_sense_us

Switch to the next channel if timing is not sensed before this time, in microseconds, measured from entry to Rx.

This must be greater than 2 and less than SL_RAIL_RX_CHANNEL_HOPPING_MAX_SENSE_TIME_US.


timing_re_sense_us#

uint32_t sl_rail_rx_channel_hopping_config_multi_mode_t::timing_re_sense_us

Switch to the next channel if timing was sensed but then lost and not regained before this time, in microseconds, measured from when timing was lost.

This must be less than SL_RAIL_RX_CHANNEL_HOPPING_MAX_SENSE_TIME_US.


status#

uint32_t sl_rail_rx_channel_hopping_config_multi_mode_t::status

Set this to 0.

This field, along with the others, may be used internally by RAIL during configuration or operation.