Wireless Core API

The Wireless Core API is the set of public functions that applications can use to access the Wireless Core functionalities.

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 not found: Wireless Core initialization flowchart

Figure 52: 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 {
    uint32_t *timeslot_sequence;          /*!< Network schedule as an array of timeslot durations in microseconds */
    uint32_t timeslot_sequence_length;    /*!< Number of timeslots in the timeslot sequence */
    uint32_t *channel_sequence;           /*!< RF channels as an array of channel numbers */
    uint32_t channel_sequence_length;     /*!< Number of channels in the channel sequence */
    bool fast_sync_enabled;               /*!< Enable fast synchronization for low data rate links */
    bool random_channel_sequence_enabled; /*!< Enable random channel sequence concurrency mechanism */
    bool certification_mode_enabled;      /*!< Enable certification mode */
    bool rdo_enabled;                     /*!< Enable the random datarate offset concurrency mechanism */
    bool ddcm_enabled;                    /*!< Enable the distributed desync concurrency mechanism */
    uint8_t *memory_pool;                 /*!< Memory pool instance from which memory allocation is done */
    uint32_t memory_pool_size;            /*!< Memory pool size in bytes */
} 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;
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;
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.

fast_sync_enabled

This enables the fast synchronization mechanism on all connections. See Synchronization Methods for more details.

random_channel_sequence_enabled

This enables 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 in Wireless Core Configuration as well as cca_enabled and rdo_enabled in Wireless Connection Configuration. See Concurrency for more details.

certification_mode_enabled

This enables the certification mode on all connections. 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.

rdo_enabled (Core)

This enables 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 cca_enabled and rdo_enabled in Wireless Connection Configuration. See Random Datarate Offset Protocol (RDO) and Concurrency for more details.

ddcm_enabled

This enables 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 cca_enabled in Wireless Connection Configuration. See Distributed De-Synchronization algorithm and Concurrency for more details.

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

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 {
    swc_role_t role;               /*!< Network role */
    uint16_t pan_id;               /*!< Personal area network 12-bit ID */
    uint8_t coordinator_address;   /*!< Coordinator device's 8-bit address; Same as local_address if local device is the Coordinator */
    uint8_t local_address;         /*!< Local device's 8-bit address */
    swc_sleep_level_t sleep_level; /*!< Sleep depth the transceiver will put itself when not active */
} 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.

pan_id

The Personal Area Network Identification is a 12-bit number used to identify a specific Network. Nodes can only communicate with other Nodes using the same PAN ID.

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.

sleep_level

This is the sleep level that the transceiver will enter when not actively transmitting or receiving. See Sleep Modes for more details.

Wireless Radio Configuration

The Wireless Radio configuration contains settings for a specific radio. A Radio refers to a physical transceiver. A Node can make use of two transceivers (e.g. dual radio headset). For these cases, there will be two distinct configurations, one per radio. The configuration structure is as follows:

typedef struct swc_radio_cfg {
    swc_irq_polarity_t irq_polarity; /*!< State of the radio IRQ pin when asserted */
    swc_spi_mode_t spi_mode;         /*!< Radio SPI interface timing setting */
    bool no_reset;                   /*!< Whether or not the radio should be reset when doing initialization */
    bool no_calibration;             /*!< Whether or not the SWC should perform the calibration routine of the radio */
} swc_radio_cfg_t;

irq_polarity

This is the polarity of the transceiver’s interrupt request (IRQ) pin when active. If the polarity is set to active low, the voltage level on the IRQ pin will transition to low when the transceiver needs to be serviced by the MCU. Conversely, if the polarity is set to active high, the voltage level on the IRQ pin will transition to high when the transceiver needs to be serviced. Valid values are IRQ_ACTIVE_LOW and IRQ_ACTIVE_HIGH.

std_spi

This controls the activation of a special SPI feature. If the setting is set to standard, the transceiver’s SPI interface respects the de facto standard for SPI communications. This is the default setting that most applications should use. If the setting is set to fast, a slight timing change is applied to compensate for a higher capacitive load on the SPI communication lines. In this mode, the transceiver MISO signal is latched internally such that transitions occur on the falling edge of the SPI clock rather than on the rising edge. This non-standard mode can be useful when the transceiver is far from the MCU and the system needs to optimize SPI throughput. The fast mode does not require any configuration changes to the MCU’s SPI interface. Valid values are SPI_STANDARD and SPI_FAST.

no_reset

If set to true, the Wireless Core will not reset the radio registers to their default value when doing the initialization.

Warning

Not resetting the transceiver may lead to undefined behavior if not done properly. It is recommended to perform a radio reset at initial configuration. Reset can then be skipped (no_reset = true) for subsequent initialization (if radio is being re-initialized).

no_calibration

If set to true, the Wireless Core will not do a radio calibration while initializing the radio.

Warning

Calibration must be done at least once after powering up the transceiver. If not done properly, this will lead to improper RF performances.

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 {
    const char *name;             /*!< Name of the connection as a character string */
    uint8_t source_address;       /*!< Address of the transmitting node */
    uint8_t destination_address;  /*!< Address of the receiving node */
    uint8_t max_payload_size;     /*!< Maximum size in bytes the payload can ever be */
    uint32_t queue_size;          /*!< Queue size in number of frames */
    swc_modulation_t modulation;  /*!< Frame modulation */
    swc_fec_level_t fec;          /*!< Frame forward error correction level */
    int32_t *timeslot_id;         /*!< ID of timeslots used by the connection */
    uint32_t timeslot_count;      /*!< Number of timeslots used by the connection */
    bool fragmentation_enabled;   /*!< Whether or not frame fragmentation is managed by the connection (true) or the
                                   *   application (false) when using payloads bigger than max_payload_size
                                   */
    bool ack_enabled;             /*!< Whether or not ACK frames are sent (RX connection) or receive (TX connection) on the connection */
    bool arq_enabled;             /*!< Whether or not retransmissions are enabled (needs ACK enabled) */
    struct {
        uint32_t try_count;     /*!< Maximum number of tries (0 is infinite) before a frame is dropped (needs ARQ enabled) */
        uint32_t time_deadline; /*!< Maximum amount of time (0 is infinite) before a frame is
                                 * dropped (needs ARQ enabled). The time increment is in number of
                                 * tick from the get_tick() hal function.
                                 */
    } arq_settings;             /*!< Settings for the automatic repeat request feature (Set only if ARQ is enabled) */
    bool auto_sync_enabled;     /*!< Whether or not dummy frames are sent out by the Wireless Core if there is no
                                 *   application data in the queue
                                 */
    bool cca_enabled;           /*!< Whether or not energy is sensed on the channel before trying to transmit */
    struct {
        uint8_t threshold;             /*!< Energy level considered too high for a successful transmission, from 0 (extremely
                                        *   unsensitive, i.e. lots of energy sensed on the channel will still yield to a
                                        *   transmission) to 47 (extremely sensitive, i.e. little energy sensed on the channel will
                                        *   make the transmission abort)
                                        */
        uint8_t try_count;             /*!< Number of energy readings to do before the fail action is executed */
        uint16_t retry_time;           /*!< Amount of time between energy readings in increments of 48.8 ns (e.g. 10 is ~500 ns)
                                        */
        swc_cca_fail_action_t fail_action; /*!< Action to do when the energy level sensed is still too high after the last
                                            *   energy sensing try
                                            */
    } cca_settings;                    /*!< Settings for the clear channel assessment feature (Set only if CCA is enabled) */
    bool throttling_enabled;           /*!< Whether or not this connection supports throttling */
    bool rdo_enabled;                  /*!< Whether or not the random datarate offset value is sent on this connection */
    bool fallback_enabled;             /*!< Whether ot not this connection can dynamically change its power settings based on the
                                        *   sent payload size
                                        */
    bool ranging_enabled;              /*!< Whether or not headers contain phase data */
    struct {
        uint8_t sample_count;          /*!< The number of samples required for a distance measurement */
    } ranging_settings;                /*!< Settings for the ranging feature (Set only if ranging is enabled) */
    struct {
        uint8_t threshold;            /*!< Size of the payload in bytes that triggers the fallback mode */
        int8_t tx_pulse_count_offset; /*!< Offset on the pulse count to apply when going into fallback mode */
        int8_t tx_pulse_width_offset; /*!< Offset on the pulse width to apply when going into fallback mode */
        int8_t tx_pulse_gain_offset;  /*!< Offset on the pulse gain to apply when going into fallback mode */
        uint8_t cca_try_count;        /*!< CCA try count to use when in fallback mode (Set only if CCA is enabled) */
    } fallback_settings;              /*!< Settings for the fallback mode feature (Set only if fallback is enabled) */
    uint8_t rx_ack_payload_size;      /*!< ACK payload size, if any, for latency optimization purpose. */
    bool    latency_opt_enabled;      /*!< Whether or not the latency is optimize over the connection. */
    bool connection_id_enabled;       /*!< Whether or not the connection ID protocol is enabled. */
    uint8_t priority;                 /*!< Connection priority */
} 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) on that Node. If this field is set to the broadcast address (0xFF) on the transmitter (TX), then the destination becomes every Node on the Network (i.e. using the same PAN ID).

Warning

Setting the destination_address as broadcast address (0xFF) must only be done on the transmitter (TX) side. Setting the receiver’s (RX) destination_address to 0xFF will generate an error. For a Node to receive a broadcast, set the connection’s code:destination_address equal to its local_address, as you would normally do to receive from a unicast connection.

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.

modulation (encoding)

This parameter specifies the connection’s encoding method. Valid values are MODULATION_IOOK and MODULATION_2BITPPM. See Modulation for more details.

fec

This parameter specifies the forward error correction level. The SPARK transceiver uses FEC methods to recover from bit corruption which might occur during over-the-air transmissions. The level at which the FEC should be configured will depend on application requirements. Valid values are FEC_LVL_0, FEC_LVL_1, FEC_LVL_2 and FEC_LVL_3. See the Forward Error Correction (FEC) Level section for more details.

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 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[] = {MAIN_TIMESLOT(0), MAIN_TIMESLOT(2)};
swc_connection_cfg_t cfg;
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.

ack_enabled

This parameter enables acknowledgements on the connection. If set to true on a TX connection, the transmitter will expect to receive an ACK frame in an Auto-Reply shortly after its transmission completes. If set to true on an RX connection, 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 not be enabled on connections used for broadcasting since all receiving Nodes would transmit their respective ACK frame at the same time, and that would cause contention which is not desirable.

arq_enabled

This parameter enables the stop-and-wait automatic repeat request protocol where a sender continuously retransmits the same frame until it receives an ACK frame. Since this feature requires ACK frames, the ack_enabled setting must be set to true for this feature to work. See Stop and Wait for more details.

arq_settings.try_count

This parameter 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

arq_settings.time_deadline

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

auto_sync_enabled

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.

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

cca_settings.threshold

This parameter defines the energy level considered too high for a successful transmission, from 0 (extremely unsensitive, i.e. lots of energy sensed on the channel will still yield to a transmission) to 47 (extremely sensitive, i.e. little energy sensed on the channel will make the transmission abort).

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

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

cca_settings.fail_action

This parameter defines the action to execute when the last CCA check fails. The action can be either to transmit anyway or to abort the transmission. If “transmit anyway” is selected and all CCA checks fail, the transmission will be forced after waiting an additional delay equal to the retry_time. Valid values are CCA_FAIL_ACTION_TX and CCA_FAIL_ACTION_ABORT_TX.

throttling_enabled

This parameter enables data rate throttling support on the connection. This feature allows the connection to disable timeslots to reduce power consumption. Once enabled, an application can call:

void swc_connection_set_throttling_active_ratio(swc_connection_t *conn, uint8_t active_ratio, swc_error_t *err);

to change the ratio of active timeslots.

rdo_enabled (connection)

This parameter enables random data rate offset on the connection. If enabled, the Wireless Core will add a special timing information in the header of frames transmitted on this connection and decode it on the connection receiving those frames. This should be enabled on the TX and RX connection of the system’s highest data rate link. See Random Datarate Offset Protocol (RDO) for more details. This is one of the features enabling concurrency operations. See Concurrency for more details.

fallback_enabled

This parameter enables fallback mode support on the connection. Fallback mode allows the Wireless Core to switch to an alternative output power configuration depending on the payload size provided by the application. See Fallback Mode for more details.

Fallback should only be enabled on the transmitter. On the receiver side, the cca_settings.try_count needs to account for the highest CCA try count of the transmitter. For example, if the transmitter’s fallback_settings.cca_try_count is greater than its cca_settings.try_count, the receiver’s cca_settings.try_count needs to match the transmitter’s fallback_settings.cca_try_count.

ranging_enabled

This parameter enables ranging mode on the connection. If enabled, the Wireless Core will include fine-grained packet reception timing information in the MAC header field needed for precise time-of-flight ranging and set a target application callback when enough ranging data sets are available for distance processing. For more details, visit Ranging Mode.

ranging_settings.sample_count

This parameter controls the number of required ranging data sets to gather before adding the distance processing application callback to the callback queue.

fallback_settings.threshold

This is the 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.

fallback_settings.tx_pulse_count_offset

This is the offset to apply to the pulse count (tx_pulse_count) of all the wireless channels added to the connection when going into fallback mode.

fallback_settings.tx_pulse_width_offset

This is the offset to apply to the pulse width (tx_pulse_width) of all the wireless channels added to the connection when going into fallback mode.

fallback_settings.tx_pulse_gain_offset

This is the offset to apply to the pulse gain (tx_pulse_gain) of all the wireless channels added to the connection when going into fallback mode.

fallback_settings.cca_try_count

This parameter defines the alternate number of cca_settings.try_count to use while in fallback mode. For example, if this is set to 3 and cca_settings.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.

rx_ack_payload_size

If necessary, the size of the ACK payload can be adjusted when implementing latency optimization.

(experimental) latency_opt_enabled

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.

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.

connection_id_enabled

This parameter enables 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.

priority

Connection priority number. A lower 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.

Note

This parameter will be ignored on a reception connection.

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(swc_node_t *node, uint8_t source_address, int32_t *timeslot_id, uint8_t timeslot_count);

Wireless Channel Configuration

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 {
    uint8_t frequency;      /*!< Frequency of the channel in increments of 40.96 MHz (e.g., 183 for 7.5 GHz) */
    uint8_t tx_pulse_count; /*!< Pulses number of the transmitted frames, from 1 to 3 */
    uint8_t tx_pulse_width; /*!< Pulses width of the transmitted frames, from 0 (narrow) to 7 (large) */
    uint8_t tx_pulse_gain;  /*!< Pulses amplitude of the transmitted frames, from 0 (max gain: 0 dB) to 3 (min gain: -1.8 dB) */
    uint8_t rx_pulse_count; /*!< Pulses number of the received frames, from 1 to 3, corresponding to the tx_pulse_count
                             *   of the incoming frames
                             */
} 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).

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 *conn, void (*cb)(void *conn), swc_error_t *err);

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 *conn, void (*cb)(void *conn), swc_error_t *err);

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 *conn, void (*cb)(void *conn), swc_error_t *err);

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 *conn, void (*cb)(void *conn), swc_error_t *err);

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 *conn, void (*cb)(void *conn), swc_error_t *err);

Connect Event

Triggers when the link is successfully established between the sender and the receiver of the connection.

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.

Ranging Data Ready Callback

The function is used to set a callback function that will be triggered when the ranging data becomes available for a specific SWC connection. This callback function provides users with the flexibility to define custom application-specific function to process the received ranging data. It is invoked once the required number of ranging data samples is collected.

void swc_connection_set_ranging_data_ready_callback(swc_connection_t *conn, void (*cb)(void *conn), swc_error_t *err);

Sending Data

Once the Wireless Core is fully initialized, the user can start sending data on TX connections with:

void swc_connection_send(swc_connection_t *conn, uint8_t *payload_buffer, uint16_t size, swc_error_t *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.

Depending on what manages the payload memory (application vs Wireless Core), the method of sending data differs slightly. If the application wants to manage the memory allocation itself, it is suggested to set the connection’s queue_size to 1 to avoid unnecessary memory consumption by the Wireless Core.

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;
uint8_t payload_buffer[PAYLOAD_SIZE];

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_get_payload_buffer(swc_connection_t *conn, uint8_t **payload_buffer, swc_error_t *err);

The equivalent of the previous example in this case would look like this:

#define PAYLOAD_SIZE 10

swc_error_t err;
uint8_t *payload_buffer;

swc_connection_get_payload_buffer(tx_conn, &payload_buffer, &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(swc_connection_t *conn, uint8_t **payload_buffer, swc_error_t *err);

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(swc_connection_t *conn, swc_error_t *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_connection_t *rx_conn = conn;
   uint8_t *payload = NULL;
   uint8_t size;

   size = swc_connection_receive(rx_conn, &payload, &err);
   memcpy(local_buffer, payload, size);

   swc_connection_receive_complete(rx_conn, &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 {
    uint32_t packet_sent_and_acked_count;        /*!< Increments when an acknowledge frame is received after sending a packet */
    uint32_t packet_sent_and_not_acked_count;    /*!< Increments when an acknowledge frame is not received after sending a packet */
    uint32_t no_packet_tranmission_count;        /*!< Increments when there is nothing to send at the start of a TX timeslot */
    uint32_t packet_dropped_count;               /*!< Increments when a packet is dropped by the Wireless Core due to its timeout
                                                  *   mechanism
                                                  */
    uint32_t tx_timeslot_occurrence;             /*!< Increments for every TX timeslot the connection goes through */
    float tx_used_capacity_pc;                   /*!< Percentage of TX timeslots used for transmission over the total number of TX
                                                  *   timeslots
                                                  */
    uint32_t packet_successfully_received_count; /*!< Increments when a packet is received and the CRC checks */
    uint32_t no_packet_reception_count;          /*!< Increment when nothing is received at the start of a RX timeslot */
    uint32_t rx_timeslot_occurrence;             /*!< Increments for every RX timeslot the connection goes through */
    uint32_t packet_duplicated_count;            /*!< Increments when a packet is received but is discarded because it is a
                                                  *   duplicate of a previously received packet
                                                  */
    uint32_t packet_rejected_count;              /*!< Increments when a packet is received but is discarded because the transceiver
                                                  *   marked it as corrupted.
                                                  */
    uint32_t packet_overrun_count;               /*!< Increments when a packet is received but is discarded because the Wireless Core
                                                  *   reception queue is full
                                                  */
    uint32_t cca_pass_count;                     /*!< Increments when a timeslot's Clear-Channel-Assessment passes and transmission occurs
                                                  *   normally.
                                                  */
    uint32_t cca_fail_count;                     /*!< Increments when a timeslot's Clear-Channel-Assessment fails and aborts (or forces)
                                                  *   transmission.
                                                  */
    uint32_t cca_try_fail_count;                 /*!< Increments when a single Clear-Channel-Assessment trial fails.
                                                  */
} swc_statistics_t;

To refresh the statistics, the following function must be called:

swc_statistics_t *swc_connection_update_stats(swc_connection_t *conn);

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;
swc_statistics_t *stats;

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 *conn);

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(swc_connection_t *conn, swc_node_t *node, char *buffer, uint16_t size);

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, node, stats_string, sizeof(stats_string));
puts(stats_string);

References

sdk_spark_vx.y.z/
└── core/
    └── wireless/
        └── api/
            ├── swc_api.h
            ├── swc_error.h
            ├── swc_stats.h
            └── swc_utils.h

File name

Description

swc_api.h

The API itself. This header file must be included in the user’s application in order to use the Wireless Core.

swc_error.h

Wireless Core error codes.

swc_stats.h

Wireless Core statistics module.

swc_utils.h

Wireless Core utilities.