blob: 14739aab26ba0dee8258b52b9664eea0d356bc74 [file] [log] [blame]
/*
* Copyright (c) 2013-2022 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "Driver_USART.h"
#include "RTE_Device.h"
#include "cmsis_driver_config.h"
#ifndef ARG_UNUSED
#define ARG_UNUSED(arg) (void) arg
#endif
/* Driver version */
#define ARM_USART_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(2, 2)
/* Driver Version */
static const ARM_DRIVER_VERSION DriverVersion = { ARM_USART_API_VERSION, ARM_USART_DRV_VERSION };
/* Driver Capabilities */
static const ARM_USART_CAPABILITIES DriverCapabilities = {
1, /* supports UART (Asynchronous) mode */
0, /* supports Synchronous Master mode */
0, /* supports Synchronous Slave mode */
0, /* supports UART Single-wire mode */
0, /* supports UART IrDA mode */
0, /* supports UART Smart Card mode */
0, /* Smart Card Clock generator available */
0, /* RTS Flow Control available */
0, /* CTS Flow Control available */
0, /* Transmit completed event: \ref ARM_USARTx_EVENT_TX_COMPLETE */
0, /* Signal receive character timeout event: \ref ARM_USARTx_EVENT_RX_TIMEOUT */
0, /* RTS Line: 0=not available, 1=available */
0, /* CTS Line: 0=not available, 1=available */
0, /* DTR Line: 0=not available, 1=available */
0, /* DSR Line: 0=not available, 1=available */
0, /* DCD Line: 0=not available, 1=available */
0, /* RI Line: 0=not available, 1=available */
0, /* Signal CTS change event: \ref ARM_USARTx_EVENT_CTS */
0, /* Signal DSR change event: \ref ARM_USARTx_EVENT_DSR */
0, /* Signal DCD change event: \ref ARM_USARTx_EVENT_DCD */
0, /* Signal RI change event: \ref ARM_USARTx_EVENT_RI */
0 /* Reserved */
};
static ARM_DRIVER_VERSION ARM_USART_GetVersion(void)
{
return DriverVersion;
}
static ARM_USART_CAPABILITIES ARM_USART_GetCapabilities(void)
{
return DriverCapabilities;
}
typedef struct
{
struct uart_cmsdk_dev_t * dev; /* UART device structure */
uint32_t tx_nbr_bytes; /* Number of bytes transferred */
uint32_t rx_nbr_bytes; /* Number of bytes recevied */
ARM_USART_SignalEvent_t cb_event; /* Callback function for events */
} UARTx_Resources;
static int32_t ARM_USARTx_Initialize(UARTx_Resources * uart_dev)
{
/* Initializes generic UART driver */
uart_cmsdk_init(uart_dev->dev, PeripheralClock);
return ARM_DRIVER_OK;
}
static int32_t ARM_USARTx_PowerControl(UARTx_Resources * uart_dev, ARM_POWER_STATE state)
{
ARG_UNUSED(uart_dev);
switch (state)
{
case ARM_POWER_OFF:
case ARM_POWER_LOW:
return ARM_DRIVER_ERROR_UNSUPPORTED;
case ARM_POWER_FULL:
/* Nothing to be done */
return ARM_DRIVER_OK;
/* default: The default is not defined intentionally to force the
* compiler to check that all the enumeration values are
* covered in the switch.*/
}
}
static int32_t ARM_USARTx_Send(UARTx_Resources * uart_dev, const void * data, uint32_t num)
{
const uint8_t * p_data = (const uint8_t *) data;
if ((data == NULL) || (num == 0U))
{
/* Invalid parameters */
return ARM_DRIVER_ERROR_PARAMETER;
}
/* Resets previous TX counter */
uart_dev->tx_nbr_bytes = 0;
while (uart_dev->tx_nbr_bytes != num)
{
/* Waits until UART is ready to transmit */
while (!uart_cmsdk_tx_ready(uart_dev->dev))
{
};
/* As UART is ready to transmit at this point, the write function can
* not return any transmit error */
(void) uart_cmsdk_write(uart_dev->dev, *p_data);
uart_dev->tx_nbr_bytes++;
p_data++;
}
if (uart_dev->cb_event != NULL)
{
uart_dev->cb_event(ARM_USART_EVENT_SEND_COMPLETE);
}
/* Waits until character is transmitted */
while (!uart_cmsdk_tx_ready(uart_dev->dev))
{
};
return ARM_DRIVER_OK;
}
static int32_t ARM_USARTx_Receive(UARTx_Resources * uart_dev, void * data, uint32_t num)
{
uint8_t * p_data = (uint8_t *) data;
if ((data == NULL) || (num == 0U))
{
// Invalid parameters
return ARM_DRIVER_ERROR_PARAMETER;
}
/* Resets previous RX counter */
uart_dev->rx_nbr_bytes = 0;
while (uart_dev->rx_nbr_bytes != num)
{
/* Waits until one character is received */
while (!uart_cmsdk_rx_ready(uart_dev->dev))
{
};
/* As UART has received one byte, the read can not
* return any receive error at this point */
(void) uart_cmsdk_read(uart_dev->dev, p_data);
uart_dev->rx_nbr_bytes++;
p_data++;
}
if (uart_dev->cb_event != NULL)
{
uart_dev->cb_event(ARM_USART_EVENT_RECEIVE_COMPLETE);
}
return ARM_DRIVER_OK;
}
static uint32_t ARM_USARTx_GetTxCount(UARTx_Resources * uart_dev)
{
return uart_dev->tx_nbr_bytes;
}
static uint32_t ARM_USARTx_GetRxCount(UARTx_Resources * uart_dev)
{
return uart_dev->rx_nbr_bytes;
}
static int32_t ARM_USARTx_Control(UARTx_Resources * uart_dev, uint32_t control, uint32_t arg)
{
switch (control & ARM_USART_CONTROL_Msk)
{
#ifdef UART_TX_RX_CONTROL_ENABLED
case ARM_USART_CONTROL_TX:
if (arg == 0)
{
uart_cmsdk_tx_disable(uart_dev->dev);
}
else if (arg == 1)
{
if (uart_cmsdk_tx_enable(uart_dev->dev) != UART_CMSDK_ERR_NONE)
{
return ARM_DRIVER_ERROR;
}
}
else
{
return ARM_DRIVER_ERROR_PARAMETER;
}
break;
case ARM_USART_CONTROL_RX:
if (arg == 0)
{
uart_cmsdk_rx_disable(uart_dev->dev);
}
else if (arg == 1)
{
if (uart_cmsdk_rx_enable(uart_dev->dev) != UART_CMSDK_ERR_NONE)
{
return ARM_DRIVER_ERROR;
}
}
else
{
return ARM_DRIVER_ERROR_PARAMETER;
}
break;
#endif
case ARM_USART_MODE_ASYNCHRONOUS:
if (uart_cmsdk_set_baudrate(uart_dev->dev, arg) != UART_CMSDK_ERR_NONE)
{
return ARM_USART_ERROR_BAUDRATE;
}
break;
/* Unsupported command */
default:
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
/* UART Data bits */
if (control & ARM_USART_DATA_BITS_Msk)
{
/* Data bit is not configurable */
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
/* UART Parity */
if (control & ARM_USART_PARITY_Msk)
{
/* Parity is not configurable */
return ARM_USART_ERROR_PARITY;
}
/* USART Stop bits */
if (control & ARM_USART_STOP_BITS_Msk)
{
/* Stop bit is not configurable */
return ARM_USART_ERROR_STOP_BITS;
}
return ARM_DRIVER_OK;
}
#if (RTE_USART0)
/* USART0 Driver wrapper functions */
static UARTx_Resources USART0_DEV = {
.dev = &UART0_CMSDK_DEV,
.tx_nbr_bytes = 0,
.rx_nbr_bytes = 0,
.cb_event = NULL,
};
static int32_t ARM_USART0_Initialize(ARM_USART_SignalEvent_t cb_event)
{
USART0_DEV.cb_event = cb_event;
return ARM_USARTx_Initialize(&USART0_DEV);
}
static int32_t ARM_USART0_Uninitialize(void)
{
/* Nothing to be done */
return ARM_DRIVER_OK;
}
static int32_t ARM_USART0_PowerControl(ARM_POWER_STATE state)
{
return ARM_USARTx_PowerControl(&USART0_DEV, state);
}
static int32_t ARM_USART0_Send(const void * data, uint32_t num)
{
return ARM_USARTx_Send(&USART0_DEV, data, num);
}
static int32_t ARM_USART0_Receive(void * data, uint32_t num)
{
return ARM_USARTx_Receive(&USART0_DEV, data, num);
}
static int32_t ARM_USART0_Transfer(const void * data_out, void * data_in, uint32_t num)
{
ARG_UNUSED(data_out);
ARG_UNUSED(data_in);
ARG_UNUSED(num);
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
static uint32_t ARM_USART0_GetTxCount(void)
{
return ARM_USARTx_GetTxCount(&USART0_DEV);
}
static uint32_t ARM_USART0_GetRxCount(void)
{
return ARM_USARTx_GetRxCount(&USART0_DEV);
}
static int32_t ARM_USART0_Control(uint32_t control, uint32_t arg)
{
return ARM_USARTx_Control(&USART0_DEV, control, arg);
}
static ARM_USART_STATUS ARM_USART0_GetStatus(void)
{
ARM_USART_STATUS status = { 0, 0, 0, 0, 0, 0, 0, 0 };
return status;
}
static int32_t ARM_USART0_SetModemControl(ARM_USART_MODEM_CONTROL control)
{
ARG_UNUSED(control);
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
static ARM_USART_MODEM_STATUS ARM_USART0_GetModemStatus(void)
{
ARM_USART_MODEM_STATUS modem_status = { 0, 0, 0, 0, 0 };
return modem_status;
}
extern ARM_DRIVER_USART Driver_USART0;
ARM_DRIVER_USART Driver_USART0 = { ARM_USART_GetVersion, ARM_USART_GetCapabilities, ARM_USART0_Initialize,
ARM_USART0_Uninitialize, ARM_USART0_PowerControl, ARM_USART0_Send,
ARM_USART0_Receive, ARM_USART0_Transfer, ARM_USART0_GetTxCount,
ARM_USART0_GetRxCount, ARM_USART0_Control, ARM_USART0_GetStatus,
ARM_USART0_SetModemControl, ARM_USART0_GetModemStatus };
#endif /* RTE_USART0 */
#if (RTE_USART1)
/* USART1 Driver wrapper functions */
static UARTx_Resources USART1_DEV = {
.dev = &UART1_CMSDK_DEV,
.tx_nbr_bytes = 0,
.rx_nbr_bytes = 0,
.cb_event = NULL,
};
static int32_t ARM_USART1_Initialize(ARM_USART_SignalEvent_t cb_event)
{
USART1_DEV.cb_event = cb_event;
return ARM_USARTx_Initialize(&USART1_DEV);
}
static int32_t ARM_USART1_Uninitialize(void)
{
/* Nothing to be done */
return ARM_DRIVER_OK;
}
static int32_t ARM_USART1_PowerControl(ARM_POWER_STATE state)
{
return ARM_USARTx_PowerControl(&USART1_DEV, state);
}
static int32_t ARM_USART1_Send(const void * data, uint32_t num)
{
return ARM_USARTx_Send(&USART1_DEV, data, num);
}
static int32_t ARM_USART1_Receive(void * data, uint32_t num)
{
return ARM_USARTx_Receive(&USART1_DEV, data, num);
}
static int32_t ARM_USART1_Transfer(const void * data_out, void * data_in, uint32_t num)
{
ARG_UNUSED(data_out);
ARG_UNUSED(data_in);
ARG_UNUSED(num);
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
static uint32_t ARM_USART1_GetTxCount(void)
{
return ARM_USARTx_GetTxCount(&USART1_DEV);
}
static uint32_t ARM_USART1_GetRxCount(void)
{
return ARM_USARTx_GetRxCount(&USART1_DEV);
}
static int32_t ARM_USART1_Control(uint32_t control, uint32_t arg)
{
return ARM_USARTx_Control(&USART1_DEV, control, arg);
}
static ARM_USART_STATUS ARM_USART1_GetStatus(void)
{
ARM_USART_STATUS status = { 0, 0, 0, 0, 0, 0, 0, 0 };
return status;
}
static int32_t ARM_USART1_SetModemControl(ARM_USART_MODEM_CONTROL control)
{
ARG_UNUSED(control);
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
static ARM_USART_MODEM_STATUS ARM_USART1_GetModemStatus(void)
{
ARM_USART_MODEM_STATUS modem_status = { 0, 0, 0, 0, 0 };
return modem_status;
}
extern ARM_DRIVER_USART Driver_USART1;
ARM_DRIVER_USART Driver_USART1 = { ARM_USART_GetVersion, ARM_USART_GetCapabilities, ARM_USART1_Initialize,
ARM_USART1_Uninitialize, ARM_USART1_PowerControl, ARM_USART1_Send,
ARM_USART1_Receive, ARM_USART1_Transfer, ARM_USART1_GetTxCount,
ARM_USART1_GetRxCount, ARM_USART1_Control, ARM_USART1_GetStatus,
ARM_USART1_SetModemControl, ARM_USART1_GetModemStatus };
#endif /* RTE_USART1 */
#if (RTE_USART2)
/* USART2 Driver wrapper functions */
static UARTx_Resources USART2_DEV = {
.dev = &UART2_CMSDK_DEV,
.tx_nbr_bytes = 0,
.rx_nbr_bytes = 0,
.cb_event = NULL,
};
static int32_t ARM_USART2_Initialize(ARM_USART_SignalEvent_t cb_event)
{
USART2_DEV.cb_event = cb_event;
return ARM_USARTx_Initialize(&USART2_DEV);
}
static int32_t ARM_USART2_Uninitialize(void)
{
/* Nothing to be done */
return ARM_DRIVER_OK;
}
static int32_t ARM_USART2_PowerControl(ARM_POWER_STATE state)
{
return ARM_USARTx_PowerControl(&USART2_DEV, state);
}
static int32_t ARM_USART2_Send(const void * data, uint32_t num)
{
return ARM_USARTx_Send(&USART2_DEV, data, num);
}
static int32_t ARM_USART2_Receive(void * data, uint32_t num)
{
return ARM_USARTx_Receive(&USART2_DEV, data, num);
}
static int32_t ARM_USART2_Transfer(const void * data_out, void * data_in, uint32_t num)
{
ARG_UNUSED(data_out);
ARG_UNUSED(data_in);
ARG_UNUSED(num);
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
static uint32_t ARM_USART2_GetTxCount(void)
{
return ARM_USARTx_GetTxCount(&USART2_DEV);
}
static uint32_t ARM_USART2_GetRxCount(void)
{
return ARM_USARTx_GetRxCount(&USART2_DEV);
}
static int32_t ARM_USART2_Control(uint32_t control, uint32_t arg)
{
return ARM_USARTx_Control(&USART2_DEV, control, arg);
}
static ARM_USART_STATUS ARM_USART2_GetStatus(void)
{
ARM_USART_STATUS status = { 0, 0, 0, 0, 0, 0, 0, 0 };
return status;
}
static int32_t ARM_USART2_SetModemControl(ARM_USART_MODEM_CONTROL control)
{
ARG_UNUSED(control);
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
static ARM_USART_MODEM_STATUS ARM_USART2_GetModemStatus(void)
{
ARM_USART_MODEM_STATUS modem_status = { 0, 0, 0, 0, 0 };
return modem_status;
}
extern ARM_DRIVER_USART Driver_USART2;
ARM_DRIVER_USART Driver_USART2 = { ARM_USART_GetVersion, ARM_USART_GetCapabilities, ARM_USART2_Initialize,
ARM_USART2_Uninitialize, ARM_USART2_PowerControl, ARM_USART2_Send,
ARM_USART2_Receive, ARM_USART2_Transfer, ARM_USART2_GetTxCount,
ARM_USART2_GetRxCount, ARM_USART2_Control, ARM_USART2_GetStatus,
ARM_USART2_SetModemControl, ARM_USART2_GetModemStatus };
#endif /* RTE_USART2 */
#if (RTE_USART3)
/* USART3 Driver wrapper functions */
static UARTx_Resources USART3_DEV = {
.dev = &UART3_CMSDK_DEV,
.tx_nbr_bytes = 0,
.rx_nbr_bytes = 0,
.cb_event = NULL,
};
static int32_t ARM_USART3_Initialize(ARM_USART_SignalEvent_t cb_event)
{
USART3_DEV.cb_event = cb_event;
return ARM_USARTx_Initialize(&USART3_DEV);
}
static int32_t ARM_USART3_Uninitialize(void)
{
/* Nothing to be done */
return ARM_DRIVER_OK;
}
static int32_t ARM_USART3_PowerControl(ARM_POWER_STATE state)
{
return ARM_USARTx_PowerControl(&USART3_DEV, state);
}
static int32_t ARM_USART3_Send(const void * data, uint32_t num)
{
return ARM_USARTx_Send(&USART3_DEV, data, num);
}
static int32_t ARM_USART3_Receive(void * data, uint32_t num)
{
return ARM_USARTx_Receive(&USART3_DEV, data, num);
}
static int32_t ARM_USART3_Transfer(const void * data_out, void * data_in, uint32_t num)
{
ARG_UNUSED(data_out);
ARG_UNUSED(data_in);
ARG_UNUSED(num);
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
static uint32_t ARM_USART3_GetTxCount(void)
{
return ARM_USARTx_GetTxCount(&USART3_DEV);
}
static uint32_t ARM_USART3_GetRxCount(void)
{
return ARM_USARTx_GetRxCount(&USART3_DEV);
}
static int32_t ARM_USART3_Control(uint32_t control, uint32_t arg)
{
return ARM_USARTx_Control(&USART3_DEV, control, arg);
}
static ARM_USART_STATUS ARM_USART3_GetStatus(void)
{
ARM_USART_STATUS status = { 0, 0, 0, 0, 0, 0, 0, 0 };
return status;
}
static int32_t ARM_USART3_SetModemControl(ARM_USART_MODEM_CONTROL control)
{
ARG_UNUSED(control);
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
static ARM_USART_MODEM_STATUS ARM_USART3_GetModemStatus(void)
{
ARM_USART_MODEM_STATUS modem_status = { 0, 0, 0, 0, 0 };
return modem_status;
}
extern ARM_DRIVER_USART Driver_USART3;
ARM_DRIVER_USART Driver_USART3 = { ARM_USART_GetVersion, ARM_USART_GetCapabilities, ARM_USART3_Initialize,
ARM_USART3_Uninitialize, ARM_USART3_PowerControl, ARM_USART3_Send,
ARM_USART3_Receive, ARM_USART3_Transfer, ARM_USART3_GetTxCount,
ARM_USART3_GetRxCount, ARM_USART3_Control, ARM_USART3_GetStatus,
ARM_USART3_SetModemControl, ARM_USART3_GetModemStatus };
#endif /* RTE_USART3 */
#if (RTE_USART4)
/* USART4 Driver wrapper functions */
static UARTx_Resources USART4_DEV = {
.dev = &UART4_CMSDK_DEV,
.tx_nbr_bytes = 0,
.rx_nbr_bytes = 0,
.cb_event = NULL,
};
static int32_t ARM_USART4_Initialize(ARM_USART_SignalEvent_t cb_event)
{
USART4_DEV.cb_event = cb_event;
return ARM_USARTx_Initialize(&USART4_DEV);
}
static int32_t ARM_USART4_Uninitialize(void)
{
/* Nothing to be done */
return ARM_DRIVER_OK;
}
static int32_t ARM_USART4_PowerControl(ARM_POWER_STATE state)
{
return ARM_USARTx_PowerControl(&USART4_DEV, state);
}
static int32_t ARM_USART4_Send(const void * data, uint32_t num)
{
return ARM_USARTx_Send(&USART4_DEV, data, num);
}
static int32_t ARM_USART4_Receive(void * data, uint32_t num)
{
return ARM_USARTx_Receive(&USART4_DEV, data, num);
}
static int32_t ARM_USART4_Transfer(const void * data_out, void * data_in, uint32_t num)
{
ARG_UNUSED(data_out);
ARG_UNUSED(data_in);
ARG_UNUSED(num);
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
static uint32_t ARM_USART4_GetTxCount(void)
{
return ARM_USARTx_GetTxCount(&USART4_DEV);
}
static uint32_t ARM_USART4_GetRxCount(void)
{
return ARM_USARTx_GetRxCount(&USART4_DEV);
}
static int32_t ARM_USART4_Control(uint32_t control, uint32_t arg)
{
return ARM_USARTx_Control(&USART4_DEV, control, arg);
}
static ARM_USART_STATUS ARM_USART4_GetStatus(void)
{
ARM_USART_STATUS status = { 0, 0, 0, 0, 0, 0, 0, 0 };
return status;
}
static int32_t ARM_USART4_SetModemControl(ARM_USART_MODEM_CONTROL control)
{
ARG_UNUSED(control);
return ARM_DRIVER_ERROR_UNSUPPORTED;
}
static ARM_USART_MODEM_STATUS ARM_USART4_GetModemStatus(void)
{
ARM_USART_MODEM_STATUS modem_status = { 0, 0, 0, 0, 0 };
return modem_status;
}
extern ARM_DRIVER_USART Driver_USART4;
ARM_DRIVER_USART Driver_USART4 = { ARM_USART_GetVersion, ARM_USART_GetCapabilities, ARM_USART4_Initialize,
ARM_USART4_Uninitialize, ARM_USART4_PowerControl, ARM_USART4_Send,
ARM_USART4_Receive, ARM_USART4_Transfer, ARM_USART4_GetTxCount,
ARM_USART4_GetRxCount, ARM_USART4_Control, ARM_USART4_GetStatus,
ARM_USART4_SetModemControl, ARM_USART4_GetModemStatus };
#endif /* RTE_USART4 */