1.1.9.2 Using The Library

The USART driver builds on top of the USART or UART peripheral library (PLIB) and provides write, read APIs in blocking and non-blocking modes.

  • In asynchronous (non-blocking) mode, application can either register a callback to get notified once the data transfer is complete or can poll the status of the data transfer using the status APIs

  • In asynchronous mode, application can queue more than one transmit/receive requests without waiting for the previous request to be completed. The number of transmit/receive requests that can be queued depends on the depth of the transfer queue configured using the MHC

  • The asynchronous mode is supported in both bare-metal and RTOS environment

  • The synchronous (blocking) mode of the driver is supported only in an RTOS environment

  • The synchronous mode of the driver does not support callback or queuing multiple requests. This is because the implementation is blocking in nature

  • Supports DMA for Transfer/Receive in both asynchronous and synchronous mode

Example application to Read and Write from UART console in Asynchronous mode

#define APP_DATA_SIZE   1

APP_DATA appData;

static const char messageBuffer[] =
"*** USART Driver Echo Demo Application ***\r\n"
"*** Type a character and observe it echo back ***\r\n";

static void APP_USARTBufferEventHandler(
    DRV_USART_BUFFER_EVENT bufferEvent,
    DRV_USART_BUFFER_HANDLE bufferHandle,
    uintptr_t context
)
{
    switch(bufferEvent)
    {
        case DRV_USART_BUFFER_EVENT_COMPLETE:
        {
            appData.transferStatus = true;
            break;
        }

        case DRV_USART_BUFFER_EVENT_ERROR:
        {
            appData.state = APP_STATE_ERROR;
            break;
        }

        default:
        {
            break;
        }
    }
}

void APP_Initialize ( void )
{
    /* Place the App state machine in its initial state. */
    appData.state           = APP_STATE_INIT;
    appData.transferStatus  = false;
    appData.usartHandle     = DRV_HANDLE_INVALID;
    appData.bufferHandle    = DRV_USART_BUFFER_HANDLE_INVALID;
}

void APP_Tasks ( void )
{
    /* Check the application's current state. */
    switch ( appData.state )
    {
        /* Application's initial state. */
        case APP_STATE_INIT:
        {
            appData.usartHandle = DRV_USART_Open(DRV_USART_INDEX_0, DRV_IO_INTENT_READWRITE);

            if (appData.usartHandle != DRV_HANDLE_INVALID)
            {
                DRV_USART_BufferEventHandlerSet(appData.usartHandle, APP_USARTBufferEventHandler, 0);
                appData.state = APP_STATE_TRANSMIT_MESSAGE;
            }
            else
            {
                appData.state = APP_STATE_ERROR;
            }
            break;
        }

        case APP_STATE_TRANSMIT_MESSAGE:
        {
            DRV_USART_WriteBufferAdd(appData.usartHandle, (void*)messageBuffer, strlen(messageBuffer), &appData.bufferHandle);

            if (appData.bufferHandle != DRV_USART_BUFFER_HANDLE_INVALID)
            {
                appData.state = APP_STATE_WAIT_MESSAGE_TRANSFER_COMPLETE;
            }
            else
            {
                appData.state = APP_STATE_ERROR;
            }
            break;
        }

        case APP_STATE_WAIT_MESSAGE_TRANSFER_COMPLETE:
        {
            if(appData.transferStatus == true)
            {
                appData.transferStatus = false;
                appData.state = APP_STATE_RECEIVE_DATA;
            }
            break;
        }

        case APP_STATE_RECEIVE_DATA:
        {
            DRV_USART_ReadBufferAdd(appData.usartHandle, appData.readBuffer, APP_DATA_SIZE, &appData.bufferHandle);

            if (appData.bufferHandle != DRV_USART_BUFFER_HANDLE_INVALID)
            {
                appData.state = APP_STATE_WAIT_RECEIVE_COMPLETE;
            }
            else
            {
                appData.state = APP_STATE_ERROR;
            }
            break;
        }

        case APP_STATE_WAIT_RECEIVE_COMPLETE:
        {
            if(appData.transferStatus == true)
            {
                appData.transferStatus = false;
                appData.state = APP_STATE_TRANSMIT_DATA;
            }
            break;
        }

        case APP_STATE_TRANSMIT_DATA:
        {
            /* Echo the received data back on the terminal */
            DRV_USART_WriteBufferAdd(appData.usartHandle, appData.readBuffer, APP_DATA_SIZE, &appData.bufferHandle);

            if (appData.bufferHandle != DRV_USART_BUFFER_HANDLE_INVALID)
            {
                appData.state = APP_STATE_WAIT_TRANSMIT_COMPLETE;
            }
            else
            {
                appData.state = APP_STATE_ERROR;
            }
            break;
        }

        case APP_STATE_WAIT_TRANSMIT_COMPLETE:
        {
            if(appData.transferStatus == true)
            {
                appData.transferStatus = false;

                LED_TOGGLE();

                appData.state = APP_STATE_RECEIVE_DATA;
            }
            break;
        }

        case APP_STATE_ERROR:
        {
            LED_OFF();
            appData.state = APP_STATE_IDLE;
            break;
        }

        case APP_STATE_IDLE:
        default:
        {
            break;
        }
    }
}