Transparent communication layer

The library provides a transparent communication layer that only supports UART at the moment but could be extended in the future to other communication protocols.

Configuring the communication layer

In order to establish a communication between the hardware and the host computer, the library communication layer must be correctly configured.

First, a whad_transport_cfg_t structure needs to be allocated and filled to provide the library with

  • the maximum number of bytes that can be sent over UART in a single transmission

  • a callback function the communication layer will use to send data through UART

  • a callback function for the communication layer to notify the reception of a WHAD message

The following code configures a communication layer with a maximum of 16 bytes per transmission and two callback functions implemented by the developer to handle UART transmission and WHAD message processing.

Note that the UART transmission callback calls whad_transport_data_sent() to notify the communication layer that the data has been successfully sent and it is ready to send more data.

struct whad_transport_cfg_t my_config;

void my_uart_tx(uint8_t *p_buffer, int size)
{
    /* Handle UART TX of p_buffer ... */

    /* Call whad_transport_data_sent() when data has been sent. */
    whad_transport_data_sent();
}

void my_message_cb(Message *p_message)
{
    /* Process incoming WHAD message. */
}

/* UART TX can only send a maximum of 16 bytes at a time. */
my_config.max_txbuf_size = 16;

/* Set up our UART TX callback. */
my_config.pfn_data_send_buffer = my_uart_tx;

/* And the incoming message callback. */
my_config.pfn_message_cb = my_message_cb;

/* Initialize our transport layer. */
whad_transport_init(&my_config);

Queuing a WHAD message for transmission

Once configured, the library is able to send WHAD messages through a call to whad_send_message(). This message will be queued for transmission and sent when the hardware is ready to transmit data over UART.

The following code shows how to send a WHAD message:

struct Message msg;

/* Create a simple WHAD message. */
whad_discovery_ready_resp(&msg);

/* Queue it for transmission. */
whad_send_message(&msg);

Sending pending messages

The hardware must regularly flush any pending transmission data in order to keep the transmission queue as small as possible to allow further messages to be sent.

A call to whad_transport_send_pending() causes the communication layer to transmit as many bytes as possible over the UART communication channel to the host, through a call to the configured transmission callback function.

Once the data transmitted, the firmware must call whad_transport_data_sent() to allow further transmissions.

Feeding the library with received data

The communication layer is able to send messages over UART but still needs to get notified when some data has been received. This is done through a call to whad_transport_data_received() in which the received bytes are provided to the communication layer:

Receiving WHAD messages

The communication layer is fed with incoming data from UART and will decode messages as they arrive. If a valid WHAD message has been received, a call to whad_get_message() will succeed and provide the raw NanoPb message.

Basic communication loop

The following code provides an example of a basic communication loop that checks for pending messages to be sent and process incoming WHAD messages as soon as they are received.

static struct Message *g_pending_message;
struct Message msg;

/* ... */

while (true)
{
    /* Check if we have a pending message to send. */
    if (g_pending_message != NULL)
    {
        if (whad_send_message(g_pending_message) == WHAD_SUCCESS)
        {
            /* Mark pending message as sent. */
            g_pending_message = NULL;
        }
    }

    /* Check if we have received a WHAD message. */
    if (whad_get_message(&msg) == WHAD_SUCCESS)
    {
        /* Process message through custom function. */
        dispatch_message(&msg);
    }

    /* Handle pending transmission data. */
    whad_transport_send_pending();
}

Transport API reference

Defines

WHAD_TRANSPORT_MSG_MAXSIZE

Typedefs

typedef void (*whad_transport_data_send_buffer_cb_t)(uint8_t *p_buffer, int size)
typedef void (*whad_transport_message_cb_t)(Message *p_msg)

Enums

enum whad_transport_state_t

Values:

enumerator WHAD_TRANSPORT_IDLE
enumerator WHAD_TRANSPORT_SENDING

Functions

void whad_transport_init(whad_transport_cfg_t *p_transport_cfg)

Initialize WHAD transport API.

Parameters:

p_transport_cfg – Pointer to a whad_transport_cfg_t structure holding the configuration to use

whad_result_t whad_transport_data_received(uint8_t *p_data, int size)

WHAD incoming data callback.

This callback must be called to notify WHAD that one or more bytes have been received.

Parameters:
  • p_data – Pointer to the received bytes

  • size – Size of the received bytes

Return values:
  • WHAD_SUCCESS – Success.

  • WHAD_RINGBUF_FULL – RX buffer is full.

whad_result_t whad_transport_transfer(void)
whad_result_t whad_transport_send_pending(void)

Send pending TX bytes.

Return values:
  • WHAD_SUCCESS – Pending TX data successfully sent

  • WHAD_RINGBUF_EMPTY – TX ring buffer is empty.

  • WHAD_ERROR – Error while sending pending data.

void whad_transport_data_sent(void)

WHAD transport data sent callback.

This function must be called whenever a transmit operation has ended in order for WHAD to continue sending pending data (if any).

whad_result_t whad_transport_send_byte(uint8_t data)

Add a data byte to WHAD transport TX buffer.

Parameters:

data – Byte to send

Returns:

WHAD_SUCCESS on success, WHAD_ERROR otherwise.

int whad_transport_send(uint8_t *p_data, int size)

Add a buffer to WHAD transport TX buffer.

Parameters:
  • p_data – Pointer to a buffer to send

  • size – Number of bytes to send

Returns:

WHAD_SUCCESS on success, WHAD_ERROR otherwise

whad_result_t whad_transport_get_message(uint8_t *p_buffer, int *p_size)

Retrieve a WHAD message from RX queue, if any.

This function must be called regularly to handle incoming WHAD messages.

Parameters:
  • p_buffer – Pointer to a buffer large enough to receive data

  • p_size – Pointer to an integer specifying the size of the destination buffer

Returns:

WHAD_SUCCESS on success, WHAD_ERROR otherwise.

whad_result_t whad_transport_send_message(uint8_t *p_message, int size)
int whad_transport_get_txbuf_size(void)
int whad_transport_get_rxbuf_size(void)
struct whad_transport_cfg_t
#include <transport.h>

WHAD Transport configuration structure.

Public Members

int max_txbuf_size

Maximum size of transmission buffer.

whad_transport_data_send_buffer_cb_t pfn_data_send_buffer

Pointer to a callback function that sends data over UART.

struct whad_transport_t
#include <transport.h>

WHAD transport state structure.

Public Members

Message msg
whad_transport_state_t state
whad_ringbuf_t rx_buf
whad_ringbuf_t tx_buf
whad_transport_cfg_t config