Wireless Core API
The Wireless Core API is the set of public functions that applications can use to access the Wireless Core functionalities.
Applications must include swc_api.h to configure and access the Wireless Core and SPARK Radio features. The SPARK Radio PHY is used internally by the Wireless Core and is not exposed as a public application API.
Initialization
Before starting to use the Wireless Core, the user must first fully initialize it. The Wireless Core provides a lot of flexibility to accommodate a wide range of applications. Hence, many parameters are configurable.
The Wireless Core initialization steps are the same for every application. Only the configuration supplied at each step is different depending on specific application needs. Here is a flowchart of the whole initialization process.
Figure 96: Wireless Core initialization flowchart
Certain API calls are optional, such as connection callback setters, while some others can be called several times, like the one that adds RF channels to a connection. The configuration has been broken down into several API calls. Each API call takes care of configuring a specific level or component, such as a wireless connection or a wireless node.
Wireless Core Configuration
The Wireless Core configuration contains settings that have a global effect on the system. The configuration structure is as follows:
typedef struct swc_cfg { /*! Network schedule as an array of timeslot durations in microseconds. */ const uint32_t *timeslot_sequence; /*! Number of timeslots in the timeslot sequence. */ uint32_t timeslot_sequence_length; /*! RF channels as an array of channel numbers. */ const uint32_t *channel_sequence; /*! Number of channels in the channel sequence. */ uint32_t channel_sequence_length; /*! Concurrency mode. */ swc_concurrency_mode_t concurrency_mode; /*! Memory pool instance from which memory allocation is done. */ uint8_t *memory_pool; /*! Memory pool size in bytes. */ uint32_t memory_pool_size; /*! Chip rate. */ swc_chip_rate_t chip_rate; /*! Personal area network ID. */ uint16_t pan_id; } swc_cfg_t;
typedef struct swc_cfg { /*! Network schedule as an array of timeslot durations in microseconds. */ const uint32_t *timeslot_sequence; /*! Number of timeslots in the timeslot sequence. */ uint32_t timeslot_sequence_length; /*! RF channels as an array of channel numbers. */ const uint32_t *channel_sequence; /*! Number of channels in the channel sequence. */ uint32_t channel_sequence_length; /*! Concurrency mode. */ swc_concurrency_mode_t concurrency_mode; /*! Memory pool instance from which memory allocation is done. */ uint8_t *memory_pool; /*! Memory pool size in bytes. */ uint32_t memory_pool_size; /*! Personal area network ID. */ uint16_t pan_id; } swc_cfg_t;
timeslot_sequence
This is the sequence of timeslots, represented by their length in microseconds, that the Node will use to communicate over the SPARK network. This sequence is commonly called the TDMA schedule, or simply schedule. The Node will go through the timeslots in the schedule one by one until it reaches the end, at which point the schedule will repeat.
For example, for a repeating schedule of two timeslots of length 250 us and 750 us, the timeslot_sequence variable would be set like this:
uint32_t timeslot_sequence[] = {250, 750};
swc_cfg_t cfg = {0};
cfg.timeslot_sequence = timeslot_sequence;
timeslot_sequence_length
This is the length of the sequence of timeslots, or how many timeslots there are in the schedule. For example, if the timeslot sequence is
{250, 750}, the value would be 2.
channel_sequence
This is the sequence of channels, represented by their frequency in increments of 40.96 MHz, used for frequency switching.
For example, if the frequency switching pattern is to go from 6.676 GHz to 6.963 Ghz to 7.249 GHz, the channel_sequence would be set like this:
uint32_t channel_sequence[] = {163, 170, 177};
swc_cfg_t cfg = {0};
cfg.channel_sequence = channel_sequence;
The configured frequencies must be within the operating range of the transceiver in use.
channel_sequence_length
This is the number of channels in the channel sequence. For example, if the channel sequence is
{163, 170, 177}, the value would be 3.
concurrency_mode
The Spark Wireless Core API allow user to configure 2 pre-defined preset for the concurrency, low and high performance mode.
The low performance mode is targeted for low power MCU that are not fast enough to handle the high frequency of event coming from the radio. It will use Random Datarate Offset Protocol (RDO) as the main concurrency mechanism paired with a randomization of the channel sequence to allow minimal concurrency.
The high performance mode is targeted for higher speed MCU and uses the Distributed De-Synchronization Concurrency Algorithm (DDCM) paired with a randomization of the channel sequence to allow better concurrency.
Note that when using the SR1120, the MCU is not affected by the frequency of the radio event since the radio now handle the Clear Channel Assessment (CCA) event internally, which allow low power MCU to benefits from the high performance mode.
Valid values are SWC_CONCURRENCY_MODE_HIGH_PERFORMANCE and SWC_CONCURRENCY_MODE_LOW_PERFORMANCE.
Here is a table summarizing available concurrency mode
Table 76: SR1100 Concurrency mode High Performance
Low Performance
DDCM Enabled
DDCM Enabled
RDO Disabled
RDO Disabled
2 CCA try with Abort action
2 CCA try with Abort action
Delay between retry of 25us
Delay between retry of 25us
Note
Random channel sequence is always enabled.
Table 77: SR1000 Concurrency mode High Performance
Low Performance
DDCM Enabled
DDCM Disabled
RDO Disabled
RDO Enabled
2 CCA try with Abort action
1 CCA try with Abort action
Delay between retry of 25us
N/A
Note
Random channel sequence is always enabled.
memory_pool
This is the chunk of memory the Wireless Core uses when creating (or allocating) structures like the ones for the Node, connections and channels. It works much like the C Heap, and enables the Wireless Core to internally manage the memory.
For example, if a memory pool of 6000 bytes is needed, its declaration and configuration would look like this:
#define SWC_MEMORY_POOL_SIZE 6000
static uint8_t swc_memory_pool[SWC_MEMORY_POOL_SIZE];
swc_cfg_t cfg = {0};
cfg.memory_pool = swc_memory_pool;
cfg.memory_pool_size = SWC_MEMORY_POOL_SIZE;
If the memory pool is not large enough to accommodate every memory allocation needed by a particular configuration, the SWC_ERR_NOT_ENOUGH_MEMORY error code is returned by the faulty API call.
memory_pool_size
This is the size in bytes of the memory pool.
chip_rate
The CHIP rate field allow the user to change the default chip rate of the radio. See Over-The-Air Chip Rate for more informations.
This feature is not supported on the SR1000 Series.
pan_id
The Personal Area Network Identification (PAN ID) is a 15-bit value shared by all devices in a network. Nodes can only communicate with other nodes using the same PAN ID.
Wireless Node Configuration
The Wireless Node configuration contains Node settings. All devices on a network are considered to be Nodes. A Node can have a specific role on a network. The configuration structure is as follows:
typedef struct swc_node_cfg { /*! Network role. */ swc_role_t role; /*! Coordinator device's 8-bit address; Same as local_address if local device is the Coordinator. */ uint8_t coordinator_address; /*! Local device's 8-bit address. */ uint8_t local_address; /*! ISI mitigation level. */ swc_isi_mitig_t isi_mitig; /*! Dynamic phy mode enable flag. */ bool dynamic_phy_mode_enabled; } swc_node_cfg_t;
typedef struct swc_node_cfg { /*! Network role. */ swc_role_t role; /*! Coordinator device's 8-bit address; Same as local_address if local device is the Coordinator. */ uint8_t coordinator_address; /*! Local device's 8-bit address. */ uint8_t local_address; } swc_node_cfg_t;
role
There are two roles on the network. A Node can be a Coordinator (Coordinator role) or a simple Node (Node role). Synchronization is achieved when the Node receives frames from the Coordinator. The Coordinator must provide frames on a continuous basis or synchronization can be lost. Valid values are NETWORK_COORDINATOR and NETWORK_NODE.
coordinator_address
This is the 8-bit address of the Coordinator. If the Node being configured is the Coordinator Node, this address must be the same as the local address.
local_address
This is the 8-bit address of the device being configured
isi_mitig
The ISI mitigation field allow the user to change the mitigation level for the network. See Inter-Symbol Interference (ISI) mitigation for more informations.
This feature is not supported on the SR1000 Series.
dynamic_phy_mode_enabled
Enable or disable the dynamic PHY mode, which allow user to change the CHIP rate of the transceiver during normal operation. See Dynamic parameter change for more informations.
This feature is not supported on the SR1000 Series.
Concurrency Configuration
The Spark Wireless Core offers 3 differents algorithm for the concurrency mechanism: the Random Datarate Offset Protocol (RDO), the Distributed De-Synchronization Concurrency Algorithm (DDCM) and the randomization of channel sequence. Each offers their own respective advantage and are used when using the 2 differents concurrency mode.
For user wanting more control over these algorithm when configuring the concurrency, this API call can be used after the core has been initialized using swc_init
void swc_set_concurrency_cfg(swc_concurrency_cfg_t cfg, swc_error_t *const err);
This fonction configuration structure will allow user to enable or disable each of the available algorithm:
typedef struct swc_concurrency_cfg { /*! Enable random channel sequence concurrency mechanism. */ bool random_channel_sequence_enabled; /*! Enable the random datarate offset concurrency mechanism. */ bool rdo_enabled; /*! Enable the distributed desync concurrency mechanism. */ bool ddcm_enabled; } swc_concurrency_cfg_t;
random_channel_sequence_enabled
This enables or disables the random channel sequence feature. This is one of the features enabling concurrency operations. Other concurrency mechanisms must be enabled for optimal coexistence. See rdo_enabled (Core) as well as Concurrency Configuration. See Concurrency for more details.
rdo_enabled (Core)
This enables or disables the random data rate offset feature. This is one of the features enabling concurrency operations. Other concurrency mechanisms must be enabled for optimal coexistence. See random_channel_sequence_enabled in Wireless Core Configuration as well as as Concurrency Configuration. See Random Datarate Offset Protocol (RDO) and Concurrency for more details.
ddcm_enabled
This enables or disables the distributed de-synchronization concurrency mechanism. This is one of the features enabling concurrency operations. Other concurrency mechanisms must be enabled for optimal coexistence. See random_channel_sequence_enabled in Wireless Core Configuration as well as Concurrency Configuration. See Distributed De-Synchronization Concurrency Algorithm (DDCM) and Concurrency for more details.
Note
To be able to customize the Clear Channel Assessment (CCA) part of the concurrency, please refer to the section Configure Clear Channel Assessment
Wireless Radio Module Initialization
After initializing the Wireless Core Node, each radio module must be calibrated and initialized in two steps:
Calibrate with
swc_radio_module_calib()— powers up the radio, reads NVM, and runs spectral calibration. Returns an opaque handle.Initialize with
swc_radio_module_init()— binds calibration data to the SWC node and prepares the radio for operation.
The returned swc_radio_handle_t is a flat, self-contained structure (no pointers) protected by CRC8. It can be persisted to flash and reloaded on subsequent boots to skip recalibration.
Usage Scenarios
Fresh calibration (typical first boot):
swc_radio_handle_t *handle = swc_radio_module_calib(SWC_RADIO_ID_1, &err);
// Optionally save: memcpy(flash_buf, handle, swc_get_radio_handle_size());
swc_radio_module_init(handle, false, &err);
Restored calibration after power cycle:
size_t calib_data_size = swc_get_radio_handle_size();
uint8_t calib_data_buf[calib_data_size];
/* Read raw bytes from flash into a byte buffer. */
flash_read(calib_data_buf, calib_data_size);
/* Restore the byte buffer into the internal static radio handle. */
swc_radio_handle_t *radio_handle = swc_radio_module_load_calib_data(SWC_RADIO_ID_1, calib_data_buf, calib_data_size, &err);
ASSERT_SWC_STATUS(*err);
/* Use the restored handle to initialize the radio. */
swc_radio_module_init(radio_handle, true, &err);
ASSERT_SWC_STATUS(*err);
Restored calibration without power cycle (soft reset / re-init):
// Handle still valid in RAM from previous swc_radio_module_calib() call
swc_radio_module_init(handle, false, &err);
- Default Settings Applied
irq_polarity = IRQ_ACTIVE_HIGH;
SPI Mode = FAST SPI;
- PLL configuration:
PLL Enable
PLL clock source internal
Crystal oscillator source internal
- Parameters on swc_radio_module_calib:
radio_id: An enum value for specific transceiver index.SWC_RADIO_ID_1
SWC_RADIO_ID_2
err: Wireless Core error code.
- Parameters on swc_radio_module_init:
radio_handle: The calibrated radio instance with NVM and spectral data.pwr_cycle_saved_calib: Set to true when restoring previously saved calibration data after a power cycle.err: Wireless Core error code.
Calibration
Typically, a minimum wait of 1 second is required for the transceiver’s crystal frequency to stabilize upon power up. Once stabilized, calibration can be performed. The Wireless Core does this by initiating the calibration procedure 1 second after power up. It is assumed that the shutdown pin is set low at power up before the timer starts counting.
This means that calibration will start 1 second after startup regardless of the shutdown pin’s state. Shutdown pin control remains accessible, but the Wireless Core does not monitor its state.
The reason for this behavior is that using shutdown mode for power savings is marginally beneficial and may approach leakage current values. Thus, shutdown mode is generally avoided.
In cases where it is still desirable to use the shutdown mode, ensure that calibration starts 1 second after the pin is held low.
IRQ Polarity
/** @brief Set the state of the radio IRQ pin when asserted.
*
* @note Default SWC_IRQ_ACTIVE_HIGH is used if this function is not called.
*
* @note This function must be invoked after `swc_radio_module_init` to take affect.
*
* @param[in] radio_id Radio number.
* @param[in] irq_polarity Radio's IRQ polarity.
* @param[out] err Wireless Core error code.
*/
void swc_node_set_radio_irq_polarity(swc_radio_id_t radio_id, swc_irq_polarity_t irq_polarity, swc_error_t *const err);
Sets the IRQ polarity for a specified radio module within a node. This setting determines the active voltage level of the transceiver’s IRQ pin when an interrupt request is made.
- Parameters:
radio_id(swc_radio_id_t) - The identifier of the radio module whose IRQ polarity is to be set.irq_polarity(swc_irq_polarity_t) - The polarity of the IRQ pin. Valid values are:IRQ_ACTIVE_LOW - Sets the IRQ pin to be active at low voltage level.
IRQ_ACTIVE_HIGH - Sets the IRQ pin to be active at high voltage level.
err(swc_error_t*) - Pointer to a variable where any error code will be stored.
Default Behavior: If this function is not invoked, the default IRQ polarity is set to
IRQ_ACTIVE_HIGH.
Note
This function must be called after
swc_radio_module_init()to ensure that the polarity setting takes effect properly.It is essential to configure the IRQ polarity according to the microcontroller’s interrupt handling specifications to avoid improper IRQ handling.
SPI Mode
/** @brief Set the radio's SPI interface timing setting.
*
* @note Default SWC_SPI_STANDARD is used if this function is not called.
*
* @note This function must be invoked after `swc_radio_module_init` to take affect.
*
* @param[in] radio_id Radio number.
* @param[in] spi_mode Radio's SPI mode.
* @param[out] err Wireless Core error code.
*/
void swc_node_set_radio_spi_mode(swc_radio_id_t radio_id, swc_spi_mode_t spi_mode, swc_error_t *const err);
Configures the SPI communication mode for a specified radio module within a node. This setting adjusts the timing characteristics of the SPI interface to either adhere to standard SPI protocols or to optimize for high-speed data transfer.
- Parameters:
radio_id(swc_radio_id_t) - The identifier of the radio module whose SPI mode is to be configured.spi_mode(swc_spi_mode_t) - The SPI communication mode. Valid options are: - SPI_STANDARD - Follows the standard SPI protocol, suitable for most applications. - SPI_FAST - Implements a faster SPI communication by adjusting the timing for high capacitive loads. Useful in scenarios where the radio is distanced from the MCU or high throughput is necessary.err(swc_error_t*) - Pointer to a variable where any error code will be stored.
Default Behavior: If this function is not invoked, the default SPI mode is set to
FAST_SPI.
Note
This function should be called after
swc_radio_module_init()to ensure that the SPI mode setting is applied effectively.The
SPI_FASTmode adjusts the timing such that the MISO signal is latched on the falling edge of the SPI clock, allowing for reliable communication over longer distances or higher electronic noise environments without requiring modifications to the MCU’s SPI configuration.
Wireless Connection Configuration
The Wireless Connection configuration contains settings for a specific connection. See Connection for more details. The configuration structure is as follows:
typedef struct swc_connection_cfg { /*! Name of the connection as a character string. */ const char *name; /*! Address of the transmitting node. */ uint8_t source_address; /*! Address of the receiving node. */ uint8_t destination_address; /*! Maximum size in bytes the payload can ever be. */ uint8_t max_payload_size; /*! Queue size in number of frames. */ uint16_t queue_size; /*! ID of timeslots used by the connection. */ const int32_t *timeslot_id; /*! Number of timeslots used by the connection. */ uint32_t timeslot_count; } swc_connection_cfg_t;
typedef struct swc_connection_cfg { /*! Name of the connection as a character string. */ const char *name; /*! Address of the transmitting node. */ uint8_t source_address; /*! Address of the receiving node. */ uint8_t destination_address; /*! Maximum size in bytes the payload can ever be. */ uint8_t max_payload_size; /*! Queue size in number of frames. */ uint16_t queue_size; /*! ID of timeslots used by the connection. */ const int32_t *timeslot_id; /*! Number of timeslots used by the connection. */ uint32_t timeslot_count; } swc_connection_cfg_t;
name
This parameter specifies the name of the connection as a string of characters. It is mostly used when printing statistics and/or debugging.
source_address
This 8-bit address specifies the device that will be transmitting on the connection. If it is set to the Node’s own address (local_address), then the connection will be used to send frames (TX connection).
destination_address
This 8-bit address specifies the device that will be receiving on the connection. If it is set to the Node’s own address (local_address), then the connection will be used to receive frames (RX connection). If this field is set to the broadcast address (0xFF), then the destination becomes every Node on the Network (i.e. using the same PAN ID).
max_payload_size
This parameter specifies the maximum amount of application payload bytes that can be transmitted or received on this connection. The maximum supported value depends on the Wireless Core configuration, as some optional features require additional bytes appended to the header. Depending on the configuration, the maximum supported value can range from 118 to 124 bytes. See the Header Configuration section for more details.
queue_size
This parameter specifies the size (or length) of the queue managing the inbound and outbound data on a connection. It is specified in number of frames. When a Node transmits on a connection, the data goes into a transmit queue before being transmitted over-the-air. When a Node receives on a connection, it retrieves its data from a receive queue. Queue size values will depend on application requirements. The minimum value is 2.
timeslot_id
This represents which timeslots in the schedule are associated with the connection, each used either for transmitting or receiving. Since a connection represents a unidirectional link, all the timeslots it uses are either for transmitting or receiving, but not both. Aside from transmitting or receiving, the timeslots can be of two different types, main timeslots, or auto timeslots (payload in the auto-reply). This can be done by registering the timeslots with the use of the SWC_MAIN_TIMESLOT() and AUTO_TIMESLOT() macros. See Timeslot Events for more details.
For example, if the first timeslot and the third timeslot of a schedule are to be used by a connection for regular data transfers, the timeslot_id would be set like this:
int32_t timeslot_id[] = {SWC_MAIN_TIMESLOT(0), SWC_MAIN_TIMESLOT(2)};
swc_connection_cfg_t cfg = {0};
cfg.timeslot_id = timeslot_id;
Note that the timeslots ID starts at 0. That is why the first and third timeslot have ID 0 and 2 respectively.
timeslot_count
This is the number of timeslots the connection uses.
Wireless Beacon Connection Configuration
A helper function can be used to obtain a pre-configured beacon connection configuration (swc_connection_cfg_t). It can then be used to initialize a connection using the usual method.
swc_connection_cfg_t swc_get_beacon_connection_config(uint8_t source_address, const int32_t *const timeslot_id,
Wireless Channel Configuration
The recommended channel configuration flow is to initialize a channel pool once, then assign that pool to a connection. If different connections or different fallback modes require different channel configurations, multiple pools can be initialized and assigned accordingly. Make sure the settings for the channels are compatible with regulations in the region of operation.
Build a channel pool from an array of channel configurations, one element for each frequency.
swc_channel_t *swc_channel_list_init(const swc_channel_cfg_t *cfgs, uint8_t count, swc_error_t *const err);
Or, if all channels have the same configuration, build a channel pool from one base configuration plus an array of frequencies.
swc_channel_t *swc_channel_list_init_from_base(swc_channel_cfg_t base_cfg, const uint32_t *const freqs, uint8_t count,
Apply the pool to the connection.
void swc_connection_set_channels(swc_connection_t *const conn, swc_channel_t *channels, uint8_t count,
For fallback channels, apply a pre-initialized pool with the fallback index.
void swc_connection_set_fallback_channels(swc_connection_t *const conn, swc_channel_t *channels, uint8_t count,
Important
swc_connection_add_channel and swc_connection_add_fallback_channel are considered legacy APIs.
New applications should use swc_channel_list_init / swc_channel_list_init_from_base with
swc_connection_set_channels / swc_connection_set_fallback_channels.
The Wireless Channel configuration contains settings for a specific channel. A channel is a logical entity that corresponds to a RF band used for over-the-air transmissions. A connection can make use of several channels if frequency switching is desired. A connection requires at least one channel to operate. The configuration structure is as follows:
typedef struct swc_channel_cfg {
/*! Frequency of the channel in increments of 40.96 MHz (e.g., 183 for 7.5 GHz). */
uint8_t frequency;
/*! Pulses number of the transmitted frames, from 1 to 3. */
uint8_t tx_pulse_count;
/*! Pulses width of the transmitted frames, from 0 (narrow) to 7 (large). */
uint8_t tx_pulse_width;
/*! Pulses amplitude of the transmitted frames, from 0 (max gain: 0 dB) to 3 (min gain: -1.8 dB). */
uint8_t tx_pulse_gain;
/*! Pulses number of the received frames, from 1 to 3, corresponding to the tx_pulse_count of the incoming frames.
*/
uint8_t rx_pulse_count;
} swc_channel_cfg_t;
frequency
This is the center frequency of the transmitted pulses. This value is commonly called the channel frequency. The value is specified in increments of 40.96 MHz. For example, if a channel frequency of 6.5 GHz is desired, this value should be set to 159.
tx_pulse_count
This is the number of pulses used for transmission. The value ranges from 1 to 3. More pulses translate to higher output power. On an RX connection with ACK enabled, this setting controls the pulse count of the Auto-Replied ACK. This setting is not required on an RX connection with ack_enabled set to false.
tx_pulse_width
This is the width of the pulses. The width ranges from 0 (narrow) to 7 (wide). A wider pulse translates to higher output power. On an RX connection with ACK enabled, this setting controls the pulse width of the Auto-Replied ACK. This setting is not required on an RX connection with ack_enabled set to false.
tx_pulse_gain
This is the power amplifier gain. It is sometimes referred to as a backoff, as higher values result in lower output power. The gain values range from 0 (max gain: 0 dB) to 3 (min gain: -1.8 dB). On an RX connection with ACK enabled, this setting controls the power amplifier gain of the Auto-Replied ACK. This setting is not required on an RX connection with ack_enabled set to false.
rx_pulse_count
This is the number of pulses of the frames received on the connection, from 1 to 3. For a TX connection, the frames received will be auto-replies (if activated).
Enable Fast Synchronization
To enable the fast synchronization mechanism on all connections, simply use this API call after the core has been initialized using swc_init
void swc_set_fast_sync(bool enabled, swc_error_t *const err);
See Synchronization Methods for more details.
Enable Certification mode
When certification is enable, all connections will be used at maximum capacity automatically without application intervention needed. The power output will the maximum allowed by user connection’s configuration. In the case where multiple connections are assigned to a time slot, the first connection added the time slot will used for certification.
To enable this feature, simply use this API call after the core has been initialized using swc_init
void swc_set_certification_mode(bool enabled, swc_error_t *const err);
See Certification Mode for more details.
Configure Sleep Level
The sleep level denotes the depth of sleep the transceiver will enter when not actively transmitting or receiving. By default, the lightest sleep mode (idle) is configured. See Sleep Modes for more details.
The sleep level can be configured to another mode simply by using this API call after the node has been initialized using swc_init
void swc_node_set_sleep_level(swc_sleep_level_t sleep_level, swc_error_t *const err);
Alternativelly, if the SR1120 is used, the sleep level can be configured for each timeslot individually by using this API call after the node has been initialized using swc_init
void swc_set_time_slots_sleep_level(const swc_sleep_level_t *const sleep_level, swc_error_t *const err);
Configure FEC Ratio
The SPARK transceiver uses the forward error correction ratio (FEC) methods to recover from bit corruption which might occur during over-the-air transmissions.
The default FEC ratio configured is SWC_FEC_1_5_0_0 (1.5x).
The default FEC ratio configured is SWC_FEC_1_6_6 (1.66x).
The FEC ratio can be configured to another value simply by using this API call after the target connection has been initialized using swc_connection_init
void swc_connection_set_fec_ratio(const swc_connection_t *const conn, swc_fec_ratio_t ratio, swc_error_t *const err);Valid values are:
typedef enum swc_fec_ratio { /*! FEC ratio 1.00. */ SWC_FEC_1_0_0_0, /*! FEC ratio 1.25. */ SWC_FEC_1_2_5_0, /*! FEC ratio 1.375. */ SWC_FEC_1_3_7_5, /*! FEC ratio 1.50. */ SWC_FEC_1_5_0_0, /*! FEC ratio 1.625. */ SWC_FEC_1_6_2_5, /*! FEC ratio 1.75. */ SWC_FEC_1_7_5_0, /*! FEC ratio 1.875. */ SWC_FEC_1_8_7_5, /*! FEC ratio 2.00. */ SWC_FEC_2_0_0_0, } swc_fec_ratio_t;
typedef enum swc_fec_ratio { /*! FEC ratio 1.00. */ SWC_FEC_1_0_0, /*! FEC ratio 1.33. */ SWC_FEC_1_3_3, /*! FEC ratio 1.66. */ SWC_FEC_1_6_6, /*! FEC ratio 2.00. */ SWC_FEC_2_0_0, } swc_fec_ratio_t;
See the Forward Error Correction (FEC) Ratio section for more details.
Configure Modulation
The default connection’s encoding method is MODULATION_IOOK. The modulation can be configured to another method by simply using this API call after the target connection has been initialized using swc_connection_init
void swc_connection_set_modulation(const swc_connection_t *const conn, swc_modulation_t modulation,
Valid values are MODULATION_IOOK, MODULATION_OOK, MODULATION_PPM and MODULATION_2BITPPM. See Modulation for more details.
Valid values are MODULATION_IOOK and MODULATION_2BITPPM. See Modulation for more details.
Configure Auto Synchronization
If enabled, the Wireless Core will automatically transmit a short synchronization frame if the transmission queue is empty at the start of a transmission timeslot instead of keeping the transceiver asleep. This feature should be used when the Coordinator is not guaranteed to send at least one frame every 10 ms to each Node. See Auto-Sync for the concept description, including the power consumption and over-the-air usage trade-offs.
To enable this feature, simply use this API call after the target connection has been initialized using swc_connection_init
void swc_connection_set_auto_sync(const swc_connection_t *const conn, bool enabled, swc_error_t *const err);
Configure Latency Optimization
Enabling this parameter allows for latency optimization in the target connection. When activated, the Wireless Core introduces a delay to the wakeup event when there is an empty timeslot. This extra processing time extends the frame unqueuing process in the WPS, leading to a decrease in the minimum latency experienced.
To enable this feature, simply use this API call after the target connection has been initialized using swc_connection_init
void swc_connection_optimized_latency(const swc_connection_t *const conn, uint8_t auto_reply_payload_size,
Important
This feature only supports CCA fail action of SWC_CCA_ABORT_TX.
Important
Take extra care when using this feature with CCA enabled. Incorrectly adjusting the CCA while enabling this feature can cause synchronization issues between two transceivers.
Warning
This feature should only be enabled on a TX connection that is not an auto-reply. Incorrect usage of this feature could potentially disrupt synchronization and result in unpredictable behavior.
Configure Fragmentation
By default, when initializing a connection, the fragmentation capabilities of the Wireless Core are disabled. Once this is enabled, users will be able to send payloads larger than the provided maximum payload size during connection configuration when using the swc_connection_send method.
To enable this feature, simply use this API call after the target connection has been initialized using swc_connection_init
void swc_connection_set_fragmentation(const swc_connection_t *const conn, swc_error_t *const err);
Configure Credit Flow
By default, when initializing a connection, the credit flow control capabilities of the Wireless Core are disabled. The credit value will represent the number of packets that device can send during the connection. Each packet transmission consumes one credit. When the credit reaches zero, the receiver must grant more credits to allow more packets to be sent. This feature requires ACK frames, the ack_enabled setting must be set to true for this feature to work. Creating an auto-reply connection is optional. However, if it is created, the number of main connections assigned to the time slot must be equal to the number of auto-reply connections.
To enable this feature, simply use this API call after the target connection has been initialized using swc_connection_init
void swc_connection_set_credit_flow_ctrl(const swc_connection_t *const conn, bool enabled, swc_error_t *const err);
Configure Throttling
The data rate throttling support on a connection can be enabled simply by using this API call after the target connection has been initialized using swc_connection_init
void swc_connection_set_throttling_active_ratio(const swc_connection_t *const conn, uint8_t active_ratio,
swc_error_t *const err);
This feature allows the connection to disable timeslots to reduce power consumption. Once enabled, an application can call the following function to change the ratio of active timeslots.
void swc_connection_set_throttling_active_ratio(const swc_connection_t *const conn, uint8_t active_ratio,
swc_error_t *const err);
Enable Connection Priority
The following functions enable the Connection Priority feature on the connection. When enabled, the Wireless Core will include a connection ID in the MAC header field of every frame transmitted on this connection. The connection ID is an 8-bit value that is used by the Wireless Core to identify the connection on the receiver side. See Connection Priority for more details.
A lower priority number has higher priority. The value can range from 0 to 2. Only 3 connections can be added to a timeslot. If the same priority is used for multiple connections, the order in which the connections were added to the timeslot will be used.
The following function enables the Connection Priority feature on the connection with a single priority on all timeslots.
void swc_connection_set_connection_priority(swc_connection_t *const conn, uint8_t priority, swc_error_t *const err);
The following function enables the Connection Priority feature with priorities for the particular timeslots used by the connection. priority and slots_priority cannot be used in the same time. If used, it must specify a priority for each timeslot used by the connection. This meant that the size of the slots_priority table must be equal to the value of timeslot_count. This option may be useful when there is a necessity to establish varying connection priorities for specific timeslots, such as to mitigate the potential risk of a lower priority connection experiencing data transmission issues due to congestion.
void swc_connection_set_connection_slots_priority(swc_connection_t *const conn, const uint8_t *slots_priority,
Note
The priority will be ignored on a reception connection.
Important
These calls are optional and mutually exclusive - use either swc_connection_set_connection_priority() or swc_connection_set_connection_slots_priority() as the final configuration step. Subsequent API calls will fail.
Configure Acknowledgement
The SPARK wireless core allow the user to configure wheter or not there is acknowledgement on a target connection, which is enabled by default. This result in the transmitter expecting to receive an ACK frame in an Auto-Reply shortly after its transmission completes and the receiver will transmit an ACK frame in an Auto-Reply if the received frame destination address matches its local address or the broadcast address and the CRC checks.
Note that ACKs should be disabled on connections used for broadcasting: all receiving Nodes would transmit their respective ACK frame at the same time in the same timeslot. This is exactly the timeslot access contention the Wireless Core does not support (see Timeslot Ownership); the simultaneous ACKs from the different Nodes would collide, which is not desirable.
To configure the acknowledgement, use this API call after the target connection has been initialized using swc_connection_init
void swc_connection_set_acknowledgment(const swc_connection_t *const conn, bool enabled, swc_error_t *const err);
Configure Retransmissions
By default, when initializing a connection, the stop-and-wait automatic repeat request is considered to be in Guaranteed delivery mode, which mean that the Wireless Core will indefinitely try to retransmit frame that hasn’t been acknowledge.
The Wireless Core also allow user to configure a condition after which a frame is automatically dropped. The condition come in to form, a try conditions and/or a time conditions.
The try deadline parameters controls the maximum number of tries allowed before the frame is automatically dropped. For example, if try_count is set to 2, the Wireless Core, after the initial transmission fails, will attempt to retransmit the frame once (which is the second try) before the frame is discarded. If the try_count is set to 0, the frame will never be discarded.
The try deadline parameter controls the maximum amount of time (in increment of ticks) that a frame can sit in the transmission queue before it is dropped by the transmitting Node. The tick rate is set by the application depending of the tick rate of the swc_hal_t.get_tick function. For example, if time_deadline is set to 100, the Wireless Core will attempt to transmit the frame for 100 ticks before it is discarded. If the time_deadline is set to 0, the frame will never be discarded.
When both try_count and time_deadline are set to a non-zero value, the frame will be discarded when either limit is reached. See Stop and Wait for more details.
To configure that feature, use the following API call after the target connection has been initialized using swc_connection_init
void swc_connection_set_retransmission(const swc_connection_t *const conn, bool enabled, uint32_t try_deadline,
Configure Clear Channel Assessment
For advance user wanting to customize the Clear Channel Assessment (CCA) beyond the scope of the available concurrency mode, the following API call can be used after the connection has been initialized using swc_connection_init:
void swc_connection_set_concurrency_cfg(const swc_connection_t *const conn,
This fonction configuration structure will allow user to change a bunch of settings related to the CCA:
typedef struct swc_connection_concurrency_cfg { /*! Enable or disable the concurrency mechanism. */ bool enabled; /*! Number of energy readings to do before the fail action is executed. Disable the CCA if the value is set to 0. */ uint8_t try_count; /*! Amount of time between energy readings in increments of radio's PHY rate period (e.g. 48.8 ns at 20.48 MHz). * * Maximum value is 1024 cycles. */ uint16_t retry_time; /*! Action to execute when all CCA attempts fail (channel still busy). See swc_cca_fail_action_t. */ swc_cca_fail_action_t fail_action; } swc_connection_concurrency_cfg_t;
swc_connection_concurrency_cfg.enabled
This parameter is used to enable the clear channel assessment (CCA) feature. If enabled, the energy level on the channel is sensed before attempting a transmission. If the energy level is considered too high for a successful transmission, the transmission will be delayed for a certain amount of time before the next attempt. After a certain number of unsuccessful attempts, a final action is done. See Clear Channel Assessment (CCA) for more details. This is one of the features enabling concurrency operations. See Concurrency for more details.
swc_connection_concurrency_cfg.try_count
This parameter defines the maximum number of transmission attempts before the configured fail action is executed. For example, if this is set to 2, the transceiver will sense the channel up to 2 times before transmitting. If both CCA checks fail, the Wireless Core will execute the fail action.
swc_connection_concurrency_cfg.retry_time
This parameter defines the amount of time to wait between CCA attempts. The retry time is specified in increments of 48.8 ns. For example, if a 25 us delay is desired, the value 512 (25 us / 48.8 ns) needs to be used.
Note
On SR1120, retry_time is quantized to multiples of 32 PLL cycles at the register level
(truncated down to the nearest multiple; values below 32 become 0). Prefer a multiple of 32
so the configured value matches what the radio applies.
swc_connection_concurrency_cfg.fail_action
This parameter defines the action to execute when the last CCA check fails. The action can be either to transmit anyway (SWC_CCA_FORCE_TX) or to abort the transmission (SWC_CCA_ABORT_TX).
With SWC_CCA_FORCE_TX, when all CCA checks fail the frame is transmitted anyway: after the last failed reading, the Wireless Core waits one additional retry_time delay and then transmits directly, without performing a final CCA check. For example, with try_count set to 3, the three CCA readings occur in the first three windows and, if all of them fail, the frame is sent in a fourth window with no CCA reading. See the Clear Channel Assessment (CCA) section for a diagram comparing this behavior to SWC_CCA_ABORT_TX.
With SWC_CCA_ABORT_TX, when all CCA checks fail the frame transmission is aborted: nothing is emitted over the air during this timeslot and the frame is kept at the head of the connection’s TX queue. Because the frame was never transmitted, the Wireless Core simply reattempts it at the connection’s next timeslot.
A CCA abort is not the same as a failed transmission. On a connection with acknowledgements enabled, a frame that is actually transmitted but not acknowledged is handled by the retransmission (ARQ) mechanism (see Stop and Wait): it is retransmitted on the following timeslots and, once the configured try or time deadline is reached, it is dropped and the TX Dropped callback is triggered. A CCA abort emits no frame, so no acknowledgement is expected and it is not treated as a failed transmission; the frame is only deferred.
On a connection without acknowledgements, every transmitted frame is considered successful and removed from the queue, so there is no failed-transmission case. A CCA abort still behaves the same way in this configuration: since the frame is never transmitted, it stays queued and is retried on the next timeslot regardless of whether acknowledgements are enabled.
Note
The fail action does not change how many CCA readings are performed (always try_count), but on SR1120 it does change the maximum allowed try_count: up to 16 for the abort action versus 15 for the transmit-anyway action. See Clear Channel Assessment (CCA) for the explanation.
Configure Fallback
Fallback mode allows the Wireless Core to switch to an alternative output power and CCA try count configuration depending on the payload size provided by the application. See Fallback Mode for more details.
void swc_connection_set_fallback_cfg(const swc_connection_t *const conn, const swc_connection_fallback_cfg_t *const cfg,
The fallback settings are as follows:
typedef struct swc_connection_fallback_cfg {
/*! Enable or disable the fallback mechanism. */
bool enabled;
/*! Number of fallback modes. */
uint8_t fallback_mode_count;
/*! Array of payload size fallback threshold. in descending order. Array size must be equal to fallback_mode_count.
*/
const uint8_t *thresholds;
/*! Array of number of CCA tries. Array size must be equal to fallback_mode_count. */
const uint8_t *cca_try_count;
} swc_connection_fallback_cfg_t;
enable
This parameter enables or disables the fallback mode on the connection.
fallback_mode_count
This parameter defines the number of fallback modes available. The minimum value is 1.
threshold
This is an array of size of the payload in bytes that triggers the fallback mode. For example, if sets to 20, every application payload of size 20 bytes or less will use the fallback power settings, while every payload of size larger than 20 bytes will use the regular power settings. The array must be sorted in descending order.
cca_try_count
This parameter defines an array of alternate number of swc_connection_concurrency_cfg.try_count to use while in fallback mode. For example, if this is set to 3 and swc_connection_concurrency_cfg.try_count is set to 2, then once fallback is triggered the transceiver will be able to sense up to 3 times instead of 2 before transmitting. the array size must be equal to the number of fallback modes. The order of the array must match the order of the threshold array.
swc_connection_set_fallback_channels
When fallback mode is enabled, the Wireless Core can switch to an alternate channel configuration depending on payload size. The recommended approach is to prepare fallback channels in a pool and apply them with the following API (TX connections only):
void swc_connection_set_fallback_channels(swc_connection_t *const conn, swc_channel_t *channels, uint8_t count,
Legacy API (not recommended)
swc_connection_add_fallback_channel remains available for backward compatibility but is considered legacy. Use channel pools with swc_connection_set_fallback_channels for new code.
Change Remote Node Destination Address
The destination address of a remote node can be changed at runtime without requiring a full re-initialization of the Wireless Core. The address change is deferred via the request queue and applied between timeslots to avoid interfering with ongoing transmissions. All connections associated with the remote node will be affected by this change.
To change the destination address, use this API call while the Wireless Core is running:
void swc_set_remote_node_address(uint8_t current_address, uint8_t new_address, swc_error_t *const err);
Wireless Status
This helper function can be used to obtain the status of the Wireless Core.
swc_status_t swc_get_status(void);
Callbacks
Callbacks are user implemented functions that can be registered on a specific connection. Callbacks will be automatically called by the Wireless Core when certain events occur and are optional. Available callbacks are described below.
TX Success
This callback triggers when a frame has been successfully transmitted on the connection. If ACKs are enabled, it triggers when the ACK frame is received. If ACKs are disabled, it triggers every time the frame is sent. At this point, the frame has been automatically removed from the connection transmission queue.
It is registered on a connection with:
void swc_connection_set_tx_success_callback(swc_connection_t *const conn, void (*cb)(void *conn, void *arg), void *arg,
TX Fail
This callback triggers when a frame has not been successfully transmitted on the connection. If ACKs are enabled, it triggers if the ACK frame was expected and not received. If ACKs are disabled, it never triggers. The TX Fail callback is usually not used when ARQ is enabled as retransmissions are managed by the Wireless Core.
It is registered on a connection with:
void swc_connection_set_tx_fail_callback(swc_connection_t *const conn, void (*cb)(void *conn, void *arg), void *arg,
TX Dropped
This callback triggers when the frame is automatically discarded by the Wireless Core because the configured ARQ deadline (time or number of retries) has expired. If ARQ is disabled, it never triggers.
Note
If both a TX Dropped and a TX Fail callback are registered on a Connection, both will trigger when a frame is dropped due to the maximum number of retries being reached. This is because the absence of an ACK frame will trigger both callbacks.
It is registered on a connection with:
void swc_connection_set_tx_dropped_callback(swc_connection_t *const conn, void (*cb)(void *conn, void *arg), void *arg,
RX Success
This callback triggers when a frame has been successfully received. This means the destination address matches the Node local address or the broadcast address and the CRC checked. The frame is then ready to be retrieved by the application from the connection reception queue.
It is registered on a connection with:
void swc_connection_set_rx_success_callback(swc_connection_t *const conn, void (*cb)(void *conn, void *arg), void *arg,
Event Callback
A configurable event callback is triggered when events occur on a connection. The event details can be retreived with the swc_get_event function. It is registered on a connection with:
void swc_connection_set_event_callback(swc_connection_t *const conn, void (*cb)(void *conn, void *arg), void *arg,
Connect Event
Triggers when the link is successfully established between the sender and the receiver of the connection. Application data needs to be transferred for the connection to be considered connected.
Disconnect Event
Triggers when the link is lost between the sender and the receiver of the connection.
Error Event
Triggers when an error occurs on the connection.
Low Power Callback
This callback triggers when the Wireless Core is ready to enter a lower power mode. This means that when received, the MCU can go into low power mode to save energy.
Note
A deeper low power mode will increase the time it takes to start servicing interrupts from the transceiver IRQ pin. Please refer to the datasheet of the MCUs used for details.
It is registered on a node with:
void swc_node_set_low_power_callback(void (*cb)(void *node), swc_error_t *const err);
Sending Data
Once the Wireless Core is fully initialized, the user can start sending data on TX connections with:
void swc_connection_send(const swc_connection_t *const conn, const uint8_t *const payload_buffer, uint16_t size,
swc_error_t *const err);
A call to this function will enqueue the payload into the connection’s transmission queue. At the next TX timeslot, the oldest payload in the queue will be encapsulated by the Wireless Core and transferred to the transceiver’s internal transmission buffer through SPI, ready to be sent over-the-air. Once the transmission is completed, depending on the connection configuration, callback functions will trigger.
The payload can be allocated by the application or by the Wireless Core. The user can call swc_connection_get_payload_buffer or swc_connection_allocate_payload_buffer to get a pointer to a memory space from the connection’s queue. If the user wants to use its own payload buffer, the payload will be copied in the connection’s queue, so the application can reuse or free the payload buffer right after calling swc_connection_send() without worrying about data corruption.
For example, the following snippet of code shows that the application allocates memory for a 10-byte payload buffer. The buffer is then filled with data using a for loop and is finally sent through the tx_conn wireless connection.
#define PAYLOAD_SIZE 10
swc_error_t err = SWC_ERR_NONE;
uint8_t payload_buffer[PAYLOAD_SIZE] = {0};
for (uint8_t i = 0; i < PAYLOAD_SIZE; i++) {
payload_buffer[i] = i;
}
swc_connection_send(tx_conn, &payload_buffer, PAYLOAD_SIZE, &err);
Note that the content of the payload buffer should not be changed until the TX Success callback triggers, otherwise, data corruption could occur.
Now, if the user wants to use the Wireless Core allocated memory, a call to the following function must be done prior to calling the swc_connection_send() function in order to get a pointer to the payload memory allocated by the Wireless Core:
void swc_connection_allocate_payload_buffer(const swc_connection_t *const conn, uint8_t **const payload_buffer,
The size of the allocated space cannot be larger than the max_payload_size specified in the connection configuration.
The equivalent of the previous example in this case would look like this:
#define PAYLOAD_SIZE 10
swc_error_t err = SWC_ERR_NONE;
uint8_t *payload_buffer = NULL;
swc_connection_allocate_payload_buffer(tx_conn, &payload_buffer, PAYLOAD_SIZE, &err);
if (payload_buffer != NULL) {
for (uint8_t i = 0; i < PAYLOAD_SIZE; i++) {
payload_buffer[i] = i;
}
swc_connection_send(tx_conn, payload_buffer, PAYLOAD_SIZE, &err)
}
Note that in this example, payload_buffer is declared as a pointer and not an array, which means the application has not allocated memory for the payload content, but rather points to the memory allocated by the Wireless Core.
Receiving Data
Once the Wireless Core is fully initialized, the user can start receiving data on RX connections with:
uint16_t swc_connection_receive(const swc_connection_t *const conn, uint8_t **const payload_buffer,
This function takes a double pointer to a payload_buffer as argument as the content of the payload_buffer pointer must be changed for the address of the buffer that contains the received payload.
Once the application has made a copy of the payload or has finished using it, a call to:
void swc_connection_receive_complete(const swc_connection_t *const conn, swc_error_t *const err);
must be made in order the free the memory that the Wireless Core used to receive the payload. This function and swc_connection_receive_complete() are usually called in the RX Success callback as shown in the following example:
static uint8_t local_buffer[128];
void rx_success_callback(void *conn)
{
swc_error_t err = SWC_ERR_NONE;
swc_connection_t *rx_conn = conn;
uint8_t *payload = NULL;
uint8_t size = 0;
size = swc_connection_receive(rx_conn, &payload, &err);
memcpy(local_buffer, payload, size);
swc_connection_receive_complete(rx_conn, &err);
}
Additionally, it is possible to read the size of the received bytes before reading them using:
uint16_t swc_connection_receive_get_payload_size(const swc_connection_t *const conn, swc_error_t *const err);
Statistics
The Wireless Core provides connection-level statistics that the application can use to monitor the status of the payloads it sends and receives. The available statistics are as follows:
typedef struct swc_statistics {
/*! Increments when an acknowledge frame is received after sending a packet. */
uint32_t packet_sent_and_acked_count;
/*! Increments when an acknowledge frame is not received after sending a packet. */
uint32_t packet_sent_and_not_acked_count;
/*! Increments when there is nothing to send at the start of a TX timeslot. */
uint32_t no_packet_tranmission_count;
/*! Increments when a packet is dropped by the Wireless Core due to its timeout mechanism. */
uint32_t packet_dropped_count;
/*! Increments for every TX timeslot the connection goes through. */
uint32_t tx_timeslot_occurrence;
/*! Percentage of TX timeslots used for transmission over the total number of TX timeslots. */
float tx_used_capacity_pc;
/*! Increments when a packet is received and the CRC checks. */
uint32_t packet_successfully_received_count;
/*! Increment when nothing is received at the start of a RX timeslot. */
uint32_t no_packet_reception_count;
/*! Increments for every RX timeslot the connection goes through. */
uint32_t rx_timeslot_occurrence;
/*! Increments when a packet is received but is discarded because it is a duplicate of a previously received packet.
*/
uint32_t packet_duplicated_count;
/*! Increments when a packet is received but is discarded because the frame data size is invalid. */
uint32_t packet_invalid_data_size_count;
/*! Increments when a packet is received but is discarded because the frame header size is invalid. */
uint32_t packet_invalid_header_size_count;
/*! Increments when a packet is received but is discarded because the transceiver marked it as corrupted. */
uint32_t packet_rejected_count;
/*! Increments when a packet is received but is discarded because the Wireless Core reception queue is full. */
uint32_t packet_overrun_count;
/*! Increments when a ACK packet is received with data. */
uint32_t packet_ack_data_received_count;
/*! Increments when a ACK packet is sent with data. */
uint32_t packet_ack_data_send_count;
/*! Increments when a timeslot's Clear-Channel-Assessment passes and transmission occurs normally. */
uint32_t cca_pass_count;
/*! Increments when a timeslot's Clear-Channel-Assessment fails and aborts (or forces) transmission. */
uint32_t cca_fail_count;
/*! Increments when a single Clear-Channel-Assessment trial fails. */
uint32_t cca_try_fail_count;
/*! Average of all raw RSSI codes from the radio register. */
uint32_t rssi_avg_raw;
/*! Average of all raw RNSI codes from the radio register. */
uint32_t rnsi_avg_raw;
/*! Instantaneous RSSI value represented in tenths of dB. */
uint32_t rssi_inst;
/*! Instantaneous RNSI value represented in tenths of dB. */
uint32_t rnsi_inst;
/*! Average of all RSSI values in tenths of dB. */
uint32_t rssi_avg;
/*! Average of all RNSI values in tenths of dB. */
uint32_t rnsi_avg;
/*! Average of all Link Margin values in tenth of dB. */
uint32_t link_margin_avg;
/*! RSSI block average in tenths of dB. */
uint32_t rssi_block_avg_tenth_db;
/*! RNSI block average in tenths of dB. */
uint32_t rnsi_block_avg_tenth_db;
/*! Link Margin block average in tenths of dB. */
uint32_t link_margin_block_avg_tenth_db;
/*! Number of bytes sent. */
uint32_t bytes_sent;
/*! Number of bytes received. */
uint32_t bytes_received;
/*! TX datarate in bits per seconds. */
uint32_t tx_data_rate_bps;
/*! RX datarate in bits per seconds. */
uint32_t rx_data_rate_bps;
/*! Tick value on statistics reset. */
uint32_t tick_on_reset;
/*! Tick value since last statistics reset. */
uint32_t tick_since_reset;
} swc_statistics_t;
To refresh the statistics, the following function must be called:
swc_statistics_t *swc_connection_update_stats(swc_connection_t *const conn, swc_error_t *err);
This function also returns a pointer to the statistics for direct manipulation by the application. The following code snippet gives an example on how to access the packet_successfully_received_count counter:
uint32_t rx_good = 0;
swc_statistics_t *stats = NULL;
stats = swc_connection_update_stats(conn);
rx_good = stats->packet_successfully_received_count
To reset the statistics, the user can simply call:
void swc_connection_reset_stats(swc_connection_t *const conn, swc_error_t *err);
This will reset all the statistics counters to 0. Resetting the statistics just after the Node has finished synchronizing on the Coordinator is recommended as accumulated statistics prior to that point are mostly irrelevant.
Finally, a function that formats a string with all the available statistics is available:
int swc_connection_format_stats(const swc_connection_t *const conn, char *const buffer,
This function detects if the connection is used for receiving or transmitting and will format only the relevant statistics. It also adds the connection’s name to the string in order to separate the statistics by connection. This is particularly useful on systems using many connections. Before calling swc_connection_format_stats(), the statistics must be updated with swc_connection_update_stats() as shown in the following example:
char stats_string[500] = {};
swc_connection_update_stats(conn);
swc_connection_format_stats(conn, stats_string, sizeof(stats_string));
puts(stats_string);
Dynamic parameter change
Dynamically Change PHY mode (PHY rate and ISI mitigation)
Use swc_set_phy_mode to initiate a coordinated PHY mode switch request.
void swc_set_phy_mode(swc_phy_mode_t phy_mode, swc_error_t *const err);
The request will initiate a 15 frames exchange to ensure synchronized PHY mode switching under most useful PER conditions.
The PHY mode options are defined by the swc_phy_mode_t structure:
typedef enum swc_phy_mode {
/*! 20.48 MHz with ISI mitigation on preamble and payload (10.24 MHz effective). */
SWC_CHIP_RATE_20_48_ISI_2,
/*! 27.30 MHz ID without ISI mitigation on preamble and payload (14.15 MHz effective). */
SWC_CHIP_RATE_27_30_ISI_2,
/*! 20.48 MHz without ISI on preamble only (20.48 MHz effective). */
SWC_CHIP_RATE_20_48_ISI_1,
/*! 27.30 MHz with ISI on preamble only (27.30 MHz effective). */
SWC_CHIP_RATE_27_30_ISI_1,
/*! 40.96 MHz ID without ISI on preamble only (40.96 MHz effective). */
SWC_CHIP_RATE_40_96_ISI_1,
/*! Number of PHY modes. */
_SWC_CHIP_RATE_COUNT,
} swc_phy_mode_t;
The swc_get_current_phy_mode is also available to get the current used PHY mode.
swc_phy_mode_t swc_get_current_phy_mode(swc_error_t *const err);
Radio NVM
Each SPARK Radio contains manufacturing information stored in its non-volatile memory (NVM). Part of the information can be extracted such as the serial number, the radio model and the radio version.
In order to have access to the NVM content, all radios must be initialized. Following the initialization process of Figure 51, all swc_radio_module_init() calls should have been made.
Formatted Output
To get a formatted string of the NVM content, the swc_format_radio_nvm function can be used as shown in the following example:
swc_error_t err = SWC_ERR_NONE;
char string[128] = {};
swc_format_radio_nvm(string, sizeof(string), &err);
if (err == SWC_ERR_NONE) {
puts(string);
}
The same can be done with swc_format_radio2_nvm for a secondary radio.
Serial Number
To get the integer value of the radio’s serial number, the swc_node_get_radio_serial_number function can be used as shown in the following example:
swc_error_t err = SWC_ERR_NONE;
uint64_t serial_number = 0;
serial_number = swc_node_get_radio_serial_number(&err);
if (err != SWC_ERR_NONE) {
while (1);
}
The same can be done with swc_node_get_radio2_serial_number for a secondary radio.
Product Model
To get the integer value of the radio’s product model, the swc_node_get_radio_product_model function can be used as shown in the following example:
swc_error_t err = SWC_ERR_NONE;
uint8_t product_model = 0;
product_model = swc_node_get_radio_product_model(&err);
if (err != SWC_ERR_NONE) {
while (1);
}
The same can be done with swc_node_get_radio2_product_model for a secondary radio.
Product Version
To get the integer value of the radio’s product version, the swc_node_get_radio_product_version function can be used as shown in the following example:
swc_error_t err = SWC_ERR_NONE;
uint8_t product_version = 0;
product_version = swc_node_get_radio_product_version(&err);
if (err != SWC_ERR_NONE) {
while (1);
}
The same can be done with swc_node_get_radio2_product_version for a secondary radio.
Low Power Mode
The Wireless Core provides functionality to indicate that Low Power mode can be enabled by the MCU. To do this, the user needs to call:
void swc_node_set_low_power_callback(void (*cb)(void *node), swc_error_t *const err);
Additionally, user can check the current low power status of the Wireless Core using the function below:
void swc_node_set_low_power_callback(void (*cb)(void *node), swc_error_t *const err);
Function swc_node_is_low_power_allowed() can be used to enter low power mode from the main application loop. If the user application supports other interrupts, then it can be used to check whether low power mode can be re-enabled.
References
The following tree shows the Wireless Core public API layout in the SDK package.
sdk_spark_vx.y.z/
└── core/
└── wireless/
├── api/
| └── swc/
| ├── swc_utils.h
| ├── sr1000/
| | └── swc_def.h
| └── sr1100/
| └── swc_def.h
├── facade/
| └── swc_hal_facade.h
├── prebuilt/
| └── swc_api_<variant>_lib.a
├── swc_api.h
├── swc_error.h
└── swc_stats.h
File name |
Description |
|---|---|
swc_api.h |
Public Wireless Core API used by applications to configure and use the Wireless Core and SPARK Radio features. |
swc_def.h |
Public Wireless Core definitions for SR1000 applications, located in |
swc_def.h |
Public Wireless Core definitions for SR1100 applications, located in |
swc_utils.h |
Wireless Core public utility definitions, located in |
swc_error.h |
Wireless Core error handling definitions. |
swc_stats.h |
Wireless Core statistics definitions. |
swc_hal_facade.h |
Wireless Core facade interface used when porting the SDK to custom hardware, located in |
swc_api_<variant>_lib.a |
Prebuilt Wireless Core static library provided in the SDK release package, located in |