Wireless Core API

The Wireless Core API is the set of public functions the application 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 51: 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 */
    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.

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

This is how many channels there are in the sequence.

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 at the connection level for optimal coexistence. See cca_enable and rdo_enable in Wireless Connection Configuration. See Concurrency for more details.

memory_pool

This is the chunk of memory the Wireless Core will use 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 will be 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 settings affecting the Node. A Node can be viewed as the wireless device itself that is being configured. The parameters at this level also have a global effect. The configuration structure is as follows:

typedef struct swc_node_cfg {
    wps_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 */
    sleep_lvl_t sleep_level;     /*!< Sleep depth the transceiver will put itself when not active */
} swc_node_cfg_t;
role

This is the role the Node will have on the network. A Node can either be a Coordinator (Coordinator role) or have no special role (Node role). Nodes will synchronize on the Coordinator incoming frames.

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 go to when not actively transmitting or receiving. See Sleep Modes for more details.

Wireless Radio Configuration

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

typedef struct swc_radio_cfg {
    irq_polarity_t irq_polarity; /*!< State of the radio IRQ pin when asserted */
    std_spi_t std_spi;           /*!< Radio SPI interface timing setting */
} swc_radio_cfg_t;
irq_polarity

This is the polarity the transceiver’s interrupt request (IRQ) pin will go to when it needs to be serviced. If the polarity is set to active low, the IRQ pin polarity will drop from high to low when the transceiver needs to be serviced by the MCU. Conversely, if the polarity is set to active high, the IRQ pin polarity will rise from low to high.

std_spi

This controls the activation of a special SPI feature. If the setting is set to SPI_STANDARD, the transceiver’s SPI interface respects the de facto standard for SPI communications. This is the default setting that the vast majority of applications should stick to. If the setting is set to SPI_FAST, a slight timing change is applied in order to compensate for a higher capacitive load on the SPI communication lines. This is mostly useful when the transceiver is far from the MCU and the system needs to achieve high SPI throughput. The SPI_FAST does not require any configuration changes to the MCU’s SPI interface.

Wireless Connection Configuration

The Wireless Connection configuration contains settings affecting a specific connection. A connection is a logical entity that corresponds to a unidirectional communication link between the Node being configured and one or more other Nodes. A Node can make use of several connections if several communication links are needed, such as in a bidirectional point-to-point application. The configuration structure is as follows:

typedef struct swc_connection_cfg {
    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 */
    modulation_t modulation;      /*!< Frame modulation */
    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 allocate_payload_memory; /*!< Whether or not payload memory allocation is managed by the connection (true) or the application (false) */
    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 retry_count;     /*!< Maximum number of retries (0 is infinite) before a frame is dropped (needs ARQ enabled) */
        uint32_t time_deadline;   /*!< Maximum amount of time (0 is infinite) in increment of 250 us (e.g. 4 is 1 ms) a frame can sit in the queue before it is dropped (needs ARQ enabled) */
    } 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 sensings to do before the fail action is executed */
        uint16_t retry_time;            /*!< Amount of time between energy sensings in increments of 48.8 us (e.g. 10 is ~500 us) */
        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 data offset is used on this connection */
    bool fallback_enabled;              /*!< Whether ot not this connection can dynamically change its power settings based on the sent payload size */
    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 */
    } fallback_settings;                /*!< Settings for the fallback mode feature (Set only if fallback is enabled) */
} swc_connection_cfg_t;
name

This is the name of the connection as a string of characters. This is mostly useful when printing statistics and debugging.

source_address

This is the 8-bit address of the device transmitting on the connection. If this is set to the Node’s own address (local_address), the connection will be used to send frames (TX connection).

destination_address

This is the 8-bit address of the device receiving on the connection. If this is set to the Node’s own address (local_address), the connection will be used to receive frames (RX connection). If this is set to the broadcast address (0xFF), the destination becomes every Node in the Network (i.e. using the same PAN ID).

max_payload_size

This is the maximum number of bytes transmitted/received on this connection. The transmitted payload size must be lower or equal to this value. This size is used internally to allocate the right buffer size when allocate_payload_memory is set to true. The maximum size is 125 bytes.

queue_size

This is the size (or length) of the queue managing the inbound and outbound data on a connection. When a Node transmits on a connection, the data gets into the queue before being eventually transmitted over-the-air. When a Node receives on a connection, it gets its data from the queue. Setting the right queue size will depend on the application requirements. The minimum size is 2.

modulation

This the way a frame will be encoded when transmitted over-the-air using this connection. The SPARK transceiver supports a few different modulations, each having its pros and cons. See Modulation for more details.

fec

This is the forward error correction level. The SPARK transceiver uses this to recover some corrupted bits during over-the-air transmissions. The level at which the FEC should be configured will depend on application requirements. 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.

allocate_payload_memory

If set to true, the Wireless Core will allocate one buffer of the size of the biggest payload (maximum_payload_size) for each element of the queue (queue_size). This way, the application does not need to worry about allocating memory itself. Note that this must always be set to true for RX connections. If set to false, the application needs to manage its memory and can only pass a pointer to its payload when sending data. See Sending Data for an example of how it works.

ack_enabled

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

arq_enabled

This 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 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. If both try_count and time_deadline are set to a non-zero value, the frame will be discarded when any of these limits is reached first.

arq_settings.time_deadline

This control the maximum amount of time in increments of 250 us the frame can sit in the transmission queue before it is dropped by the transmitting Node. For example, if time_deadline is set to 12, the frame will be discarded if the Wireless Core could not transmit it successfully within 3 ms. If the time_deadline is set to 0, the frame will never be discarded. If both try_count and time_deadline are set to a non-zero value, the frame will be discarded when any of these limits is reached first.

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 is useful when the Coordinator does not regularly send frames for the Node to stay synchronized on the network.

cca_enabled

This enables the clear channel assessment 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 is 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 is 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 is the amount of time to wait between a failed attempt to transmit due to the energy level being too high on the channel and the next attempt. The retry time represents 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 is the action to execute when the last CCA check fails. This can be either to transmit anyway or to abort the transmission. If “transmit anyway” is selected as fail action and all CCA checks fail, the transmission will be forced after waiting an additional delay equals to the retry_time.

throttling_enabled

This enables data rate throttling support on the connection. This feature allows the connection to disable timeslots in order 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. This should only be enabled on TX connections.

rdo_enabled

This 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. This should only be enabled on the Coordinator for Beacon connections. 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 enables fallback mode support on the connection. This feature 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_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.

Wireless Channel Configuration

The Wireless Channel configuration contains settings affecting a specific channel. A channel is a logical entity that corresponds to a RF channel used for over-the-air transmissions. A connection can make use of several channels if frequency switching is required. A connection needs 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 represents increments of 40.96 MHz. For example, if a channel frequency of 6.5 GHz is desired, this setting should be set to 158.

tx_pulse_count

This is the number of pulses used for transmission. The number of pulses range from 1 to 3. More pulses translates to a higher output power. This setting is not required if the channel is added to an RX connection with ack_enabled set to false. On an RX connection with ACK enabled, this setting controls the pulse count of the Auto-Replied ACK.

tx_pulse_width

This is the width of the pulses. The width ranges from 0 (narrow) to 7 (wide). A wider pulse translates to a higher output power. This setting is not required if the channel is added to an RX connection with ack_enabled set to false. On an RX connection with ACK enabled, this setting controls the pulse width of the Auto-Replied ACK.

tx_pulse_gain

This is the power amplifier gain. The gain ranges from 0 (max gain: 0 dB) to 3 (min gain: -1.8 dB). More gain translates to a higher output power. This setting is not required if the channel is added to an RX connection with ack_enabled set to false. On an RX connection with ACK enabled, this setting controls the power amplifier gain of the Auto-Replied ACK.

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

Callbacks

Callbacks are functions implemented by the user that can be registered on a specific connection. Those functions will be automatically called by the Wireless Core when certain events happen. They are optional and must be set to NULL if not used.

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

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 a user usually does not need to know when a transmission fails since re-transmissions 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));

TX Dropped

This callback triggers when the frame is automatically discarded by the Wireless Core because the deadline configured for the ARQ (either in time or in number of retries) has been met. 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 if the drop is due to the maximum number of retries being reached. This is because the frame is dropped after not receiving an ACK which triggers the TX Fail callback.

It is registered on a connection with:

void swc_connection_set_tx_dropped_callback(swc_connection_t *conn, void (*cb)(void *conn));

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 picked up 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));

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, uint8_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 way to send data slightly differs. If allocate_payload_memory is set to false in the Wireless Connection configuration, the Wireless Core will not allocate room for the payload in the connection queue and it becomes the application responsibility to allocate the payload memory.

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. It would otherwise lead to potential data corruption issues.

Now, if the same connection had the setting allocate_payload_memory set to true, 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 but with allocate_payload_memory set to true 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:

uint8_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 done in order the free the memory the Wireless Core used to receive the payload. This function and swc_connection_receive_complete() are usually called in the RX Success callback like 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 what is happening with 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_overrun_count;      /*!< Increments when a packet is received but is discarded because the Wireless Core reception queue is full */
} swc_statistics_t;

Some statistics are relevant only to TX connections, while others only to RX connections.

To refresh the statistics, the following function has to 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 can be useful after the Node has finished synchronizing on the Coordinator as accumulated statistics before 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 only format the relevant statistics. It also adds the connection’s name to the string so it is easier to differentiate which statistics belong to which connection on systems using many connections. Before calling swc_connection_format_stats(), the statistics must be updated with swc_connection_update_stats() like 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

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.