UART and USART Usage Scenarios#

The WiSeConnect SDK offers flexible APIs for both UART and USART on SiWx91x. Based on your performance and power needs, you can choose interrupt-driven, DMA-based, or low-power transfer modes.

Controller Features and Modes#

This section describes the capabilities of the available controllers. Each controller type supports features designed for different performance, power, and protocol requirements.

UART Controllers#

  • Multi-drop RS485 interface support

  • Character encoding: 5, 6, 7, and 8 bits with even, odd, or no parity

  • Stop bits: 1, 1.5 (with 5-bit encoding), and 2

  • Hardware auto flow control (RTS/CTS)

  • Programmable baud rate (up to 921,600 bps with 118 MHz input clock)

  • Standard baud rates: 300–921,600 bps

  • Programmable fractional baud rate with support up to 5 Mbps

  • Programmable FIFO thresholds, maximum FIFO depth 16, DMA support

  • Prioritized interrupt identification

Ultra-Low-Power (ULP) UART#

  • DMA support in PS2 state

  • Limitation: ULP UART doesn’t support RS485 or auto flow control

USART Controller#

  • Supports synchronous and asynchronous modes

  • Full-duplex and half-duplex (single-wire) communication

  • Character encoding: 5–8 bits

  • Baud rates up to 7.3 Mbps (UART mode) and up to 20 Mbps (USART mode)

  • Programmable FIFO thresholds, maximum FIFO depth 16, DMA support

  • Interrupt generation for multiple events

Typical Use Case 1: Non-DMA Based Transfers#

In interrupt-based mode, UART or USART signals the CPU when a transfer completes or when an error occurs. This approach is ideal for event-driven applications that require an immediate response. The driver invokes a callback function on each event, enabling the application to handle it efficiently.

Step-by-step Breakdown#

  1. Define a callback function for interrupt handling.

  2. Initialize the UART or USART driver.

  3. Register the callback for interrupt events.

  4. Prepare the data buffer.

  5. Send or receive data in non-blocking mode.

  6. Wait for the transfer to complete or for an error event.

  7. Validate results and handle errors.

Example#

#include "sl_si91x_usart.h"

static volatile bool transfer_complete = false;
static volatile bool transfer_error = false;

void uart_interrupt_callback(uint32_t event)
{
    if (event & SL_USART_EVENT_TX_COMPLETE) {
        transfer_complete = true;
    }
    if (event & SL_USART_EVENT_RX_OVERFLOW) {
        transfer_error = true;
        DEBUGOUT("Error: RX overflow during transfer\n");
    }
}

sl_usart_handle_t uart_handle;
sl_status_t status = sl_si91x_usart_init(UART_1, &uart_handle);
status = sl_si91x_usart_multiple_instance_register_event_callback(UART_1, uart_interrupt_callback);

uint8_t tx_buffer[256] = {0x01, 0x02, 0x03, /* ... */};
transfer_complete = false;
transfer_error = false;
status = sl_si91x_usart_send_data(uart_handle, tx_buffer, sizeof(tx_buffer));
while (!transfer_complete && !transfer_error) {}
if (!transfer_error) {
    DEBUGOUT("UART transfer completed successfully\n");
}

Performance notes#

  • Allows the CPU to perform other tasks during transfers.

  • Suitable for responsive, event-driven applications.

  • Lower CPU overhead compared to polling.

  • Transfer rates depend on the configured baud rate.

Typical Use Case 2: DMA-based Transfers#

DMA-enabled transfers offload data movement from the CPU to the Micro Direct Memory Access (UDMA) controller. This approach is recommended for high-throughput or power-sensitive applications because it reduces CPU load and enables efficient, hardware-accelerated transfers.

Step-by-step Breakdown#

  1. Enable DMA from the UART controller and configure DMA channels.

  2. Define a callback function for DMA completion and errors.

  3. Initialize and configure UART/USART with DMA.

  4. Prepare the data buffer.

  5. Start a non-blocking DMA transfer.

  6. Perform other tasks while the transfer is in progress.

  7. Process results after the transfer completes.

Example#

#include "sl_si91x_usart.h"

static volatile bool dma_transfer_complete = false;

void uart_dma_callback(uint32_t event)
{
    if (event & SL_USART_EVENT_TX_COMPLETE) {
        dma_transfer_complete = true;
    }
    if (event & SL_USART_EVENT_RX_OVERFLOW) {
        DEBUGOUT("Error: RX overflow during DMA transfer\n");
    }
}

sl_usart_handle_t uart_handle;
sl_status_t status = sl_si91x_usart_init(UART_1, &uart_handle);
status = sl_si91x_usart_multiple_instance_register_event_callback(UART_1, uart_dma_callback);

uint8_t tx_buffer[1024] = {/* large data set */};
dma_transfer_complete = false;
status = sl_si91x_usart_send_data(uart_handle, tx_buffer, sizeof(tx_buffer));
while (!dma_transfer_complete) {}
DEBUGOUT("DMA transfer completed successfully\n");

Performance Benefits#

  • Offloads work from the CPU, enabling concurrent processing.

  • Delivers the highest throughput for large transfers.

  • Improves power efficiency, as the CPU can enter low-power modes.

  • Ideal for continuous or high-frequency data streaming.

Typical Use Case 3: Ultra-low-power UART Operation (ULP mode)#

ULP mode enables energy-efficient communication for battery-powered or long-life applications. Devices such as Internet of Things (IoT) sensors and wearables benefit from reduced current consumption during UART transactions.

Step-by-step Breakdown#

  1. Configure power domains and RAM retention for ULP operation.

  2. Initialize the UART driver with ULP settings in interrupt mode.

  3. Perform UART transactions in both high-power and ultra-low-power states.

  4. Validate data integrity and compare power consumption.

  5. Optimize settings for battery life and report metrics.

  6. Deinitialize the driver and release power requirements when finished.

Example#

sl_si91x_power_manager_add_ps_requirement(SL_SI91X_POWER_MANAGER_PS2); // Enter PS2

sl_usart_control_config_t ulp_uart_config = {
    .baudrate = 9600,
    .mode = SL_USART_MODE_ASYNCHRONOUS,
    .parity = SL_USART_NO_PARITY,
    .stopbits = SL_USART_STOP_BITS_1,
    .hwflowcontrol = SL_USART_FLOW_CONTROL_NONE,
    .databits = SL_USART_DATA_BITS_8,
    .misc_control = SL_USART_MISC_CONTROL_NONE
};

sl_usart_handle_t uart_handle;
sl_status_t status = sl_si91x_usart_init(UART_1, &ulp_uart_config);

uint8_t ulp_tx_buffer[32] = {0x01, 0x02, 0x03, /* ... */};
uint8_t ulp_rx_buffer[32];

// Send data in ULP mode
status = sl_si91x_usart_send_data_blocking(uart_handle, ulp_tx_buffer, sizeof(ulp_tx_buffer));
// Receive data in ULP mode
status = sl_si91x_usart_receive_data_blocking(uart_handle, ulp_rx_buffer, sizeof(ulp_rx_buffer));

// Validate received data
bool data_valid = true;
for (int i = 0; i < sizeof(ulp_tx_buffer); i++) {
    if (ulp_rx_buffer[i] != ulp_tx_buffer[i]) {
        data_valid = false;
        break;
    }
}
if (data_valid) {
    DEBUGOUT("ULP UART data validation PASSED\n");
} else {
    DEBUGOUT("ULP UART data validation FAILED\n");
}

sl_si91x_usart_deinit(UART_1);

Application Areas#

  • Battery-powered IoT devices

  • Sensor networks with duty cycling

  • Energy-harvesting systems

  • Long-term deployment scenarios

Advanced Features and Transfer Modes#

The WiSeConnect SDK also supports advanced features for UART and USART, enabling more robust communication in complex scenarios.

Full-duplex Communication Example#

// Transmit and receive simultaneously
status = sl_si91x_usart_send_data(uart_handle, tx_buffer, tx_length);
status = sl_si91x_usart_receive_data(uart_handle, rx_buffer, rx_length);

Hardware Flow Control Example#

sl_si91x_usart_control_config_t uart_config = {
    .baudrate = 115200,
    .mode = SL_USART_MODE_ASYNCHRONOUS,
    .parity = SL_USART_NO_PARITY,
    .stopbits = SL_USART_STOP_BITS_1,
    .hwflowcontrol = SL_USART_FLOW_CONTROL_RTS_CTS,
    .databits = SL_USART_DATA_BITS_8,
    .misc_control = SL_USART_MISC_CONTROL_NONE
};

Related Example Projects#

Explore the following projects for practical implementations:

  • WiSeConnect SDK UART peripheral examples

    • SL Si91x – UART example

    • SL Si91x – UART RS485 example

    • SL Si91x – USART asynchronous example

    • SL Si91x – USART synchronous master example

    • SL Si91x – USART synchronous slave example

    • SL Si91x – ULP UART example