diff options
Diffstat (limited to 'FreeRTOS/Demo/Safe_Interrupts_M33F_NXP_LPC55S69_MCUXpresso/NXP_Code/component/uart/fsl_adapter_usart.c')
-rw-r--r-- | FreeRTOS/Demo/Safe_Interrupts_M33F_NXP_LPC55S69_MCUXpresso/NXP_Code/component/uart/fsl_adapter_usart.c | 1086 |
1 files changed, 1086 insertions, 0 deletions
diff --git a/FreeRTOS/Demo/Safe_Interrupts_M33F_NXP_LPC55S69_MCUXpresso/NXP_Code/component/uart/fsl_adapter_usart.c b/FreeRTOS/Demo/Safe_Interrupts_M33F_NXP_LPC55S69_MCUXpresso/NXP_Code/component/uart/fsl_adapter_usart.c new file mode 100644 index 000000000..4261752b8 --- /dev/null +++ b/FreeRTOS/Demo/Safe_Interrupts_M33F_NXP_LPC55S69_MCUXpresso/NXP_Code/component/uart/fsl_adapter_usart.c @@ -0,0 +1,1086 @@ +/* + * Copyright 2018 NXP + * All rights reserved. + * + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "fsl_common.h" +#include "fsl_usart.h" +#include "fsl_flexcomm.h" + +#include "fsl_adapter_uart.h" + +#if (defined(HAL_UART_DMA_ENABLE) && (HAL_UART_DMA_ENABLE > 0U)) +#include "fsl_component_timer_manager.h" +#include "fsl_usart_dma.h" +#endif /* HAL_UART_DMA_ENABLE */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#ifndef NDEBUG +#if (defined(DEBUG_CONSOLE_ASSERT_DISABLE) && (DEBUG_CONSOLE_ASSERT_DISABLE > 0U)) +#undef assert +#define assert(n) +#endif +#endif + +#if (defined(HAL_UART_DMA_ENABLE) && (HAL_UART_DMA_ENABLE > 0U)) +/*! @brief uart RX state structure. */ +typedef struct _hal_uart_dma_receive_state +{ + uint8_t *volatile buffer; + volatile uint32_t bufferLength; + volatile uint32_t bufferSofar; + volatile uint32_t timeout; + volatile bool receiveAll; +} hal_uart_dma_receive_state_t; + +/*! @brief uart TX state structure. */ +typedef struct _hal_uart_dma_send_state +{ + uint8_t *volatile buffer; + volatile uint32_t bufferLength; + volatile uint32_t bufferSofar; + volatile uint32_t timeout; +} hal_uart_dma_send_state_t; + +typedef struct _hal_uart_dma_state +{ + struct _hal_uart_dma_state *next; + uint8_t instance; /* USART instance */ + hal_uart_dma_transfer_callback_t dma_callback; + void *dma_callback_param; + usart_dma_handle_t dmaHandle; + dma_handle_t txDmaHandle; + dma_handle_t rxDmaHandle; + hal_uart_dma_receive_state_t dma_rx; + hal_uart_dma_send_state_t dma_tx; +} hal_uart_dma_state_t; + +typedef struct _uart_dma_list +{ + TIMER_MANAGER_HANDLE_DEFINE(timerManagerHandle); + hal_uart_dma_state_t *dma_list; + volatile int8_t activeCount; +} hal_uart_dma_list_t; + +static hal_uart_dma_list_t s_dmaHandleList; +#endif /* HAL_UART_DMA_ENABLE */ + +#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U)) +/*! @brief uart RX state structure. */ +typedef struct _hal_uart_receive_state +{ + volatile uint8_t *buffer; + volatile uint32_t bufferLength; + volatile uint32_t bufferSofar; +} hal_uart_receive_state_t; + +/*! @brief uart TX state structure. */ +typedef struct _hal_uart_send_state +{ + volatile uint8_t *buffer; + volatile uint32_t bufferLength; + volatile uint32_t bufferSofar; +} hal_uart_send_state_t; +#endif +/*! @brief uart state structure. */ +typedef struct _hal_uart_state +{ +#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U)) + hal_uart_transfer_callback_t callback; + void *callbackParam; +#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U)) + usart_handle_t hardwareHandle; +#endif + hal_uart_receive_state_t rx; + hal_uart_send_state_t tx; +#endif + uint8_t instance; +#if (defined(HAL_UART_DMA_ENABLE) && (HAL_UART_DMA_ENABLE > 0U)) + hal_uart_dma_state_t *dmaHandle; +#endif /* HAL_UART_DMA_ENABLE */ +} hal_uart_state_t; + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ +static USART_Type *const s_UsartAdapterBase[] = USART_BASE_PTRS; + +#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U)) + +#if !(defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U)) +/* Array of USART IRQ number. */ +static const IRQn_Type s_UsartIRQ[] = USART_IRQS; +#endif + +#endif + +/******************************************************************************* + * Code + ******************************************************************************/ + +#if ((defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U)) || \ + (defined(HAL_UART_DMA_ENABLE) && (HAL_UART_DMA_ENABLE > 0U))) +static hal_uart_status_t HAL_UartGetStatus(status_t status) +{ + hal_uart_status_t uartStatus = kStatus_HAL_UartError; + switch (status) + { + case kStatus_Success: + uartStatus = kStatus_HAL_UartSuccess; + break; + case kStatus_USART_TxBusy: + uartStatus = kStatus_HAL_UartTxBusy; + break; + case kStatus_USART_RxBusy: + uartStatus = kStatus_HAL_UartRxBusy; + break; + case kStatus_USART_TxIdle: + uartStatus = kStatus_HAL_UartTxIdle; + break; + case kStatus_USART_RxIdle: + uartStatus = kStatus_HAL_UartRxIdle; + break; + case kStatus_USART_BaudrateNotSupport: + uartStatus = kStatus_HAL_UartBaudrateNotSupport; + break; + case kStatus_USART_NoiseError: + case kStatus_USART_FramingError: + case kStatus_USART_ParityError: + uartStatus = kStatus_HAL_UartProtocolError; + break; + default: + /* This comments for MISRA C-2012 Rule 16.4 */ + break; + } + return uartStatus; +} +#else +static hal_uart_status_t HAL_UartGetStatus(status_t status) +{ + if (kStatus_Success == status) + { + return kStatus_HAL_UartSuccess; + } + else + { + return kStatus_HAL_UartError; + } +} +#endif + +#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U)) + +#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U)) +static void HAL_UartCallback(USART_Type *base, usart_handle_t *handle, status_t status, void *callbackParam) +{ + hal_uart_state_t *uartHandle; + hal_uart_status_t uartStatus = HAL_UartGetStatus(status); + assert(callbackParam); + + uartHandle = (hal_uart_state_t *)callbackParam; + + if (kStatus_HAL_UartProtocolError == uartStatus) + { + if (0U != uartHandle->hardwareHandle.rxDataSize) + { + uartStatus = kStatus_HAL_UartError; + } + } + + if (NULL != uartHandle->callback) + { + uartHandle->callback(uartHandle, uartStatus, uartHandle->callbackParam); + } +} + +#else +static void HAL_UartInterruptHandle(USART_Type *base, void *handle) +{ + hal_uart_state_t *uartHandle = (hal_uart_state_t *)handle; + uint32_t status; + uint8_t instance; + + if (NULL == uartHandle) + { + return; + } + instance = uartHandle->instance; + + status = USART_GetStatusFlags(s_UsartAdapterBase[instance]); + + /* Receive data register full */ + if ((0U != (USART_FIFOSTAT_RXNOTEMPTY_MASK & status)) && + (0U != (USART_GetEnabledInterrupts(s_UsartAdapterBase[instance]) & USART_FIFOINTENSET_RXLVL_MASK))) + { + if (NULL != uartHandle->rx.buffer) + { + uartHandle->rx.buffer[uartHandle->rx.bufferSofar++] = USART_ReadByte(s_UsartAdapterBase[instance]); + if (uartHandle->rx.bufferSofar >= uartHandle->rx.bufferLength) + { + USART_DisableInterrupts(s_UsartAdapterBase[instance], + USART_FIFOINTENCLR_RXLVL_MASK | USART_FIFOINTENCLR_RXERR_MASK); + uartHandle->rx.buffer = NULL; + if (NULL != uartHandle->callback) + { + uartHandle->callback(uartHandle, kStatus_HAL_UartRxIdle, uartHandle->callbackParam); + } + } + } + } + + /* Send data register empty and the interrupt is enabled. */ + if ((0U != (USART_FIFOSTAT_TXNOTFULL_MASK & status)) && + (0U != (USART_GetEnabledInterrupts(s_UsartAdapterBase[instance]) & USART_FIFOINTENSET_TXLVL_MASK))) + { + if (NULL != uartHandle->tx.buffer) + { + USART_WriteByte(s_UsartAdapterBase[instance], uartHandle->tx.buffer[uartHandle->tx.bufferSofar++]); + if (uartHandle->tx.bufferSofar >= uartHandle->tx.bufferLength) + { + USART_DisableInterrupts(s_UsartAdapterBase[instance], USART_FIFOINTENCLR_TXLVL_MASK); + uartHandle->tx.buffer = NULL; + if (NULL != uartHandle->callback) + { + uartHandle->callback(uartHandle, kStatus_HAL_UartTxIdle, uartHandle->callbackParam); + } + } + } + } + +#if 1 + USART_ClearStatusFlags(s_UsartAdapterBase[instance], status); +#endif +} + +static void HAL_UartInterruptHandle_Wapper(void *base, void *handle) +{ + HAL_UartInterruptHandle((USART_Type *)base, handle); +} +#endif + +#endif + +static hal_uart_status_t HAL_UartInitCommon(hal_uart_handle_t handle, const hal_uart_config_t *config) +{ + usart_config_t usartConfig; + status_t status; + + assert(handle); + assert(config); + assert(config->instance < (sizeof(s_UsartAdapterBase) / sizeof(USART_Type *))); + assert(s_UsartAdapterBase[config->instance]); + assert(HAL_UART_HANDLE_SIZE >= sizeof(hal_uart_state_t)); + + USART_GetDefaultConfig(&usartConfig); + usartConfig.baudRate_Bps = config->baudRate_Bps; + + if ((0U != config->enableRxRTS) || (0U != config->enableTxCTS)) + { + usartConfig.enableHardwareFlowControl = true; + } + + if (kHAL_UartParityEven == config->parityMode) + { + usartConfig.parityMode = kUSART_ParityEven; + } + else if (kHAL_UartParityOdd == config->parityMode) + { + usartConfig.parityMode = kUSART_ParityOdd; + } + else + { + usartConfig.parityMode = kUSART_ParityDisabled; + } + + if (kHAL_UartTwoStopBit == config->stopBitCount) + { + usartConfig.stopBitCount = kUSART_TwoStopBit; + } + else + { + usartConfig.stopBitCount = kUSART_OneStopBit; + } + usartConfig.enableRx = (bool)config->enableRx; + usartConfig.enableTx = (bool)config->enableTx; + usartConfig.txWatermark = kUSART_TxFifo0; + usartConfig.rxWatermark = kUSART_RxFifo1; + + status = USART_Init(s_UsartAdapterBase[config->instance], &usartConfig, config->srcClock_Hz); + + if (kStatus_Success != status) + { + return HAL_UartGetStatus(status); + } + + return kStatus_HAL_UartSuccess; +} + +hal_uart_status_t HAL_UartInit(hal_uart_handle_t handle, const hal_uart_config_t *config) +{ + hal_uart_state_t *uartHandle; + hal_uart_status_t status; + + /* Init serial port */ + status = HAL_UartInitCommon(handle, config); + if (kStatus_HAL_UartSuccess != status) + { + return status; + } + + uartHandle = (hal_uart_state_t *)handle; + uartHandle->instance = config->instance; +#if (defined(HAL_UART_DMA_ENABLE) && (HAL_UART_DMA_ENABLE > 0U)) + uartHandle->dmaHandle = NULL; +#endif /* HAL_UART_DMA_ENABLE */ + +#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U)) + +#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U)) + USART_TransferCreateHandle(s_UsartAdapterBase[config->instance], &uartHandle->hardwareHandle, + (usart_transfer_callback_t)HAL_UartCallback, handle); +#else + /* Enable interrupt in NVIC. */ + FLEXCOMM_SetIRQHandler(s_UsartAdapterBase[config->instance], HAL_UartInterruptHandle_Wapper, handle); + NVIC_SetPriority((IRQn_Type)s_UsartIRQ[config->instance], HAL_UART_ISR_PRIORITY); + (void)EnableIRQ(s_UsartIRQ[config->instance]); +#endif + +#endif + + return kStatus_HAL_UartSuccess; +} + +hal_uart_status_t HAL_UartDeinit(hal_uart_handle_t handle) +{ + hal_uart_state_t *uartHandle; + + assert(handle); + + uartHandle = (hal_uart_state_t *)handle; + + USART_Deinit(s_UsartAdapterBase[uartHandle->instance]); + + return kStatus_HAL_UartSuccess; +} + +hal_uart_status_t HAL_UartReceiveBlocking(hal_uart_handle_t handle, uint8_t *data, size_t length) +{ + hal_uart_state_t *uartHandle; + status_t status; + assert(handle); + assert(data); + assert(length); + + uartHandle = (hal_uart_state_t *)handle; + +#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U)) + if (NULL != uartHandle->rx.buffer) + { + return kStatus_HAL_UartRxBusy; + } +#endif + + status = USART_ReadBlocking(s_UsartAdapterBase[uartHandle->instance], data, length); + + return HAL_UartGetStatus(status); +} + +hal_uart_status_t HAL_UartSendBlocking(hal_uart_handle_t handle, const uint8_t *data, size_t length) +{ + hal_uart_state_t *uartHandle; + assert(handle); + assert(data); + assert(length); + + uartHandle = (hal_uart_state_t *)handle; + +#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U)) + if (NULL != uartHandle->tx.buffer) + { + return kStatus_HAL_UartTxBusy; + } +#endif + + (void)USART_WriteBlocking(s_UsartAdapterBase[uartHandle->instance], data, length); + + return kStatus_HAL_UartSuccess; +} + +hal_uart_status_t HAL_UartEnterLowpower(hal_uart_handle_t handle) +{ + assert(handle); + + return kStatus_HAL_UartSuccess; +} + +hal_uart_status_t HAL_UartExitLowpower(hal_uart_handle_t handle) +{ + assert(handle); + + return kStatus_HAL_UartSuccess; +} + +#if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U)) + +#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U)) + +hal_uart_status_t HAL_UartTransferInstallCallback(hal_uart_handle_t handle, + hal_uart_transfer_callback_t callback, + void *callbackParam) +{ + hal_uart_state_t *uartHandle; + + assert(handle); + assert(0U != HAL_UART_TRANSFER_MODE); + + uartHandle = (hal_uart_state_t *)handle; + + uartHandle->callbackParam = callbackParam; + uartHandle->callback = callback; + + return kStatus_HAL_UartSuccess; +} + +hal_uart_status_t HAL_UartTransferReceiveNonBlocking(hal_uart_handle_t handle, hal_uart_transfer_t *transfer) +{ + hal_uart_state_t *uartHandle; + status_t status; + assert(handle); + assert(transfer); + assert(0U != HAL_UART_TRANSFER_MODE); + + uartHandle = (hal_uart_state_t *)handle; + + status = USART_TransferReceiveNonBlocking(s_UsartAdapterBase[uartHandle->instance], &uartHandle->hardwareHandle, + (usart_transfer_t *)transfer, NULL); + + return HAL_UartGetStatus(status); +} + +hal_uart_status_t HAL_UartTransferSendNonBlocking(hal_uart_handle_t handle, hal_uart_transfer_t *transfer) +{ + hal_uart_state_t *uartHandle; + status_t status; + assert(handle); + assert(transfer); + assert(0U != HAL_UART_TRANSFER_MODE); + + uartHandle = (hal_uart_state_t *)handle; + + status = USART_TransferSendNonBlocking(s_UsartAdapterBase[uartHandle->instance], &uartHandle->hardwareHandle, + (usart_transfer_t *)transfer); + + return HAL_UartGetStatus(status); +} + +hal_uart_status_t HAL_UartTransferGetReceiveCount(hal_uart_handle_t handle, uint32_t *count) +{ + hal_uart_state_t *uartHandle; + status_t status; + assert(handle); + assert(count); + assert(0U != HAL_UART_TRANSFER_MODE); + + uartHandle = (hal_uart_state_t *)handle; + + status = + USART_TransferGetReceiveCount(s_UsartAdapterBase[uartHandle->instance], &uartHandle->hardwareHandle, count); + + return HAL_UartGetStatus(status); +} + +hal_uart_status_t HAL_UartTransferGetSendCount(hal_uart_handle_t handle, uint32_t *count) +{ + hal_uart_state_t *uartHandle; + status_t status; + assert(handle); + assert(count); + assert(0U != HAL_UART_TRANSFER_MODE); + + uartHandle = (hal_uart_state_t *)handle; + + status = USART_TransferGetSendCount(s_UsartAdapterBase[uartHandle->instance], &uartHandle->hardwareHandle, count); + + return HAL_UartGetStatus(status); +} + +hal_uart_status_t HAL_UartTransferAbortReceive(hal_uart_handle_t handle) +{ + hal_uart_state_t *uartHandle; + assert(handle); + assert(0U != HAL_UART_TRANSFER_MODE); + + uartHandle = (hal_uart_state_t *)handle; + + USART_TransferAbortReceive(s_UsartAdapterBase[uartHandle->instance], &uartHandle->hardwareHandle); + + return kStatus_HAL_UartSuccess; +} + +hal_uart_status_t HAL_UartTransferAbortSend(hal_uart_handle_t handle) +{ + hal_uart_state_t *uartHandle; + assert(handle); + assert(0U != HAL_UART_TRANSFER_MODE); + + uartHandle = (hal_uart_state_t *)handle; + + USART_TransferAbortSend(s_UsartAdapterBase[uartHandle->instance], &uartHandle->hardwareHandle); + + return kStatus_HAL_UartSuccess; +} + +#else + +/* None transactional API with non-blocking mode. */ +hal_uart_status_t HAL_UartInstallCallback(hal_uart_handle_t handle, + hal_uart_transfer_callback_t callback, + void *callbackParam) +{ + hal_uart_state_t *uartHandle; + + assert(handle); + assert(0U == HAL_UART_TRANSFER_MODE); + + uartHandle = (hal_uart_state_t *)handle; + + uartHandle->callbackParam = callbackParam; + uartHandle->callback = callback; + + return kStatus_HAL_UartSuccess; +} + +hal_uart_status_t HAL_UartReceiveNonBlocking(hal_uart_handle_t handle, uint8_t *data, size_t length) +{ + hal_uart_state_t *uartHandle; + assert(handle); + assert(data); + assert(length); + assert(0U == HAL_UART_TRANSFER_MODE); + + uartHandle = (hal_uart_state_t *)handle; + + if (NULL != uartHandle->rx.buffer) + { + return kStatus_HAL_UartRxBusy; + } + + uartHandle->rx.bufferLength = length; + uartHandle->rx.bufferSofar = 0; + uartHandle->rx.buffer = data; + USART_EnableInterrupts(s_UsartAdapterBase[uartHandle->instance], USART_FIFOINTENSET_RXLVL_MASK); + return kStatus_HAL_UartSuccess; +} + +hal_uart_status_t HAL_UartSendNonBlocking(hal_uart_handle_t handle, uint8_t *data, size_t length) +{ + hal_uart_state_t *uartHandle; + assert(handle); + assert(data); + assert(length); + assert(0U == HAL_UART_TRANSFER_MODE); + + uartHandle = (hal_uart_state_t *)handle; + + if (NULL != uartHandle->tx.buffer) + { + return kStatus_HAL_UartTxBusy; + } + uartHandle->tx.bufferLength = length; + uartHandle->tx.bufferSofar = 0; + uartHandle->tx.buffer = (volatile uint8_t *)data; + USART_EnableInterrupts(s_UsartAdapterBase[uartHandle->instance], USART_FIFOINTENSET_TXLVL_MASK); + return kStatus_HAL_UartSuccess; +} + +hal_uart_status_t HAL_UartGetReceiveCount(hal_uart_handle_t handle, uint32_t *reCount) +{ + hal_uart_state_t *uartHandle; + assert(handle); + assert(reCount); + assert(0U == HAL_UART_TRANSFER_MODE); + + uartHandle = (hal_uart_state_t *)handle; + + if (NULL != uartHandle->rx.buffer) + { + *reCount = uartHandle->rx.bufferSofar; + return kStatus_HAL_UartSuccess; + } + return kStatus_HAL_UartError; +} + +hal_uart_status_t HAL_UartGetSendCount(hal_uart_handle_t handle, uint32_t *seCount) +{ + hal_uart_state_t *uartHandle; + assert(handle); + assert(seCount); + assert(0U == HAL_UART_TRANSFER_MODE); + + uartHandle = (hal_uart_state_t *)handle; + + if (NULL != uartHandle->tx.buffer) + { + *seCount = uartHandle->tx.bufferSofar; + return kStatus_HAL_UartSuccess; + } + return kStatus_HAL_UartError; +} + +hal_uart_status_t HAL_UartAbortReceive(hal_uart_handle_t handle) +{ + hal_uart_state_t *uartHandle; + assert(handle); + assert(0U == HAL_UART_TRANSFER_MODE); + + uartHandle = (hal_uart_state_t *)handle; + + if (NULL != uartHandle->rx.buffer) + { + USART_DisableInterrupts(s_UsartAdapterBase[uartHandle->instance], + USART_FIFOINTENCLR_RXLVL_MASK | USART_FIFOINTENCLR_RXERR_MASK); + uartHandle->rx.buffer = NULL; + } + + return kStatus_HAL_UartSuccess; +} + +hal_uart_status_t HAL_UartAbortSend(hal_uart_handle_t handle) +{ + hal_uart_state_t *uartHandle; + assert(handle); + assert(0U == HAL_UART_TRANSFER_MODE); + + uartHandle = (hal_uart_state_t *)handle; + + if (NULL != uartHandle->tx.buffer) + { + USART_DisableInterrupts(s_UsartAdapterBase[uartHandle->instance], USART_FIFOINTENCLR_TXLVL_MASK); + uartHandle->tx.buffer = NULL; + } + + return kStatus_HAL_UartSuccess; +} + +#endif + +#if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U)) + +void HAL_UartIsrFunction(hal_uart_handle_t handle) +{ + hal_uart_state_t *uartHandle; + assert(handle); + assert(0U != HAL_UART_TRANSFER_MODE); + + uartHandle = (hal_uart_state_t *)handle; + +#if 0 + DisableIRQ(s_UsartIRQ[uartHandle->instance]); +#endif + USART_TransferHandleIRQ(s_UsartAdapterBase[uartHandle->instance], &uartHandle->hardwareHandle); +#if 0 + NVIC_SetPriority((IRQn_Type)s_UsartIRQ[uartHandle->instance], HAL_UART_ISR_PRIORITY); + EnableIRQ(s_UsartIRQ[uartHandle->instance]); +#endif +} + +#else + +void HAL_UartIsrFunction(hal_uart_handle_t handle) +{ + hal_uart_state_t *uartHandle; + assert(handle); + assert(0U == HAL_UART_TRANSFER_MODE); + + uartHandle = (hal_uart_state_t *)handle; + +#if 0 + DisableIRQ(s_UsartIRQ[uartHandle->instance]); +#endif + HAL_UartInterruptHandle(s_UsartAdapterBase[uartHandle->instance], (void *)uartHandle); +#if 0 + NVIC_SetPriority((IRQn_Type)s_UsartIRQ[uartHandle->instance], HAL_UART_ISR_PRIORITY); + EnableIRQ(s_UsartIRQ[uartHandle->instance]); +#endif +} + +#endif + +#endif + +#if (defined(HAL_UART_DMA_ENABLE) && (HAL_UART_DMA_ENABLE > 0U)) +static void USART_DMACallbacks(USART_Type *base, usart_dma_handle_t *handle, status_t status, void *userData) +{ + hal_uart_dma_state_t *uartDmaHandle; + hal_uart_status_t uartStatus = HAL_UartGetStatus(status); + hal_dma_callback_msg_t msg; + assert(handle); + + uartDmaHandle = (hal_uart_dma_state_t *)userData; + + if (NULL != uartDmaHandle->dma_callback) + { + if (kStatus_HAL_UartTxIdle == uartStatus) + { + msg.status = kStatus_HAL_UartDmaTxIdle; + msg.data = uartDmaHandle->dma_tx.buffer; + msg.dataSize = uartDmaHandle->dma_tx.bufferLength; + uartDmaHandle->dma_tx.buffer = NULL; + } + else if (kStatus_HAL_UartRxIdle == uartStatus) + { + msg.status = kStatus_HAL_UartDmaRxIdle; + msg.data = uartDmaHandle->dma_rx.buffer; + msg.dataSize = uartDmaHandle->dma_rx.bufferLength; + uartDmaHandle->dma_rx.buffer = NULL; + } + + uartDmaHandle->dma_callback(uartDmaHandle, &msg, uartDmaHandle->dma_callback_param); + } +} + +static void TimeoutTimer_Callbcak(void *param) +{ + hal_uart_dma_list_t *uartDmaHandleList; + hal_uart_dma_state_t *uartDmaHandle; + hal_dma_callback_msg_t msg; + uint32_t newReceived = 0U; + + uartDmaHandleList = &s_dmaHandleList; + uartDmaHandle = uartDmaHandleList->dma_list; + + while (NULL != uartDmaHandle) + { + if ((NULL != uartDmaHandle->dma_rx.buffer) && (false == uartDmaHandle->dma_rx.receiveAll)) + { + /* HAL_UartDMAGetReceiveCount(uartDmaHandle, &msg.dataSize); */ + USART_TransferGetReceiveCountDMA(s_UsartAdapterBase[uartDmaHandle->instance], &uartDmaHandle->dmaHandle, + &msg.dataSize); + newReceived = msg.dataSize - uartDmaHandle->dma_rx.bufferSofar; + uartDmaHandle->dma_rx.bufferSofar = msg.dataSize; + + /* 1, If it is in idle state. */ + if ((0U == newReceived) && (0U < uartDmaHandle->dma_rx.bufferSofar)) + { + uartDmaHandle->dma_rx.timeout++; + if (uartDmaHandle->dma_rx.timeout >= HAL_UART_DMA_IDLELINE_TIMEOUT) + { + /* HAL_UartDMAAbortReceive(uartDmaHandle); */ + USART_TransferAbortReceiveDMA(s_UsartAdapterBase[uartDmaHandle->instance], + &uartDmaHandle->dmaHandle); + msg.data = uartDmaHandle->dma_rx.buffer; + msg.status = kStatus_HAL_UartDmaIdleline; + uartDmaHandle->dma_rx.buffer = NULL; + uartDmaHandle->dma_callback(uartDmaHandle, &msg, uartDmaHandle->dma_callback_param); + } + } + /* 2, If got new data again. */ + if ((0U < newReceived) && (0U < uartDmaHandle->dma_rx.bufferSofar)) + { + uartDmaHandle->dma_rx.timeout = 0U; + } + } + + uartDmaHandle = uartDmaHandle->next; + } +} + +hal_uart_dma_status_t HAL_UartDMAInit(hal_uart_handle_t handle, + hal_uart_dma_handle_t dmaHandle, + hal_uart_dma_config_t *dmaConfig) +{ + hal_uart_state_t *uartHandle; + hal_uart_dma_state_t *uartDmaHandle; + + assert(handle); + assert(dmaHandle); + + /* DMA init process. */ + uartHandle = (hal_uart_state_t *)handle; + uartDmaHandle = (hal_uart_dma_state_t *)dmaHandle; + + uartHandle->dmaHandle = uartDmaHandle; + + uartDmaHandle->instance = dmaConfig->uart_instance; + + DMA_Type *dmaBases[] = DMA_BASE_PTRS; + DMA_EnableChannel(dmaBases[dmaConfig->dma_instance], dmaConfig->tx_channel); + DMA_EnableChannel(dmaBases[dmaConfig->dma_instance], dmaConfig->rx_channel); + + DMA_CreateHandle(&uartDmaHandle->txDmaHandle, dmaBases[dmaConfig->dma_instance], dmaConfig->tx_channel); + DMA_CreateHandle(&uartDmaHandle->rxDmaHandle, dmaBases[dmaConfig->dma_instance], dmaConfig->rx_channel); + + /* Timeout timer init. */ + if (0U == s_dmaHandleList.activeCount) + { + s_dmaHandleList.dma_list = uartDmaHandle; + uartDmaHandle->next = NULL; + s_dmaHandleList.activeCount++; + + timer_status_t timerStatus; + timerStatus = TM_Open((timer_handle_t)s_dmaHandleList.timerManagerHandle); + assert(kStatus_TimerSuccess == timerStatus); + + timerStatus = + TM_InstallCallback((timer_handle_t)s_dmaHandleList.timerManagerHandle, TimeoutTimer_Callbcak, NULL); + assert(kStatus_TimerSuccess == timerStatus); + + (void)TM_Start((timer_handle_t)s_dmaHandleList.timerManagerHandle, (uint8_t)kTimerModeIntervalTimer, 1); + + (void)timerStatus; + } + else + { + uartDmaHandle->next = s_dmaHandleList.dma_list; + s_dmaHandleList.dma_list = uartDmaHandle; + } + + return kStatus_HAL_UartDmaSuccess; +} + +hal_uart_dma_status_t HAL_UartDMADeinit(hal_uart_handle_t handle) +{ + hal_uart_state_t *uartHandle; + hal_uart_dma_state_t *uartDmaHandle; + hal_uart_dma_state_t *prev; + hal_uart_dma_state_t *curr; + + assert(handle); + + uartHandle = (hal_uart_state_t *)handle; + uartDmaHandle = uartHandle->dmaHandle; + + uartHandle->dmaHandle = NULL; + + assert(uartDmaHandle); + + /* Abort rx/tx */ + /* Here we should not abort before create transfer handle. */ + if (NULL != uartDmaHandle->dmaHandle.txDmaHandle) + { + USART_TransferAbortSendDMA(s_UsartAdapterBase[uartDmaHandle->instance], &uartDmaHandle->dmaHandle); + } + if (NULL != uartDmaHandle->dmaHandle.rxDmaHandle) + { + USART_TransferAbortReceiveDMA(s_UsartAdapterBase[uartDmaHandle->instance], &uartDmaHandle->dmaHandle); + } + + /* Disable rx/tx channels */ + /* Here we should not disable before create transfer handle. */ + if (NULL != uartDmaHandle->dmaHandle.txDmaHandle) + { + DMA_DisableChannel(uartDmaHandle->txDmaHandle.base, uartDmaHandle->txDmaHandle.channel); + } + if (NULL != uartDmaHandle->dmaHandle.rxDmaHandle) + { + DMA_DisableChannel(uartDmaHandle->rxDmaHandle.base, uartDmaHandle->rxDmaHandle.channel); + } + + /* Remove handle from list */ + prev = NULL; + curr = s_dmaHandleList.dma_list; + while (curr != NULL) + { + if (curr == uartDmaHandle) + { + /* 1, if it is the first one */ + if (prev == NULL) + { + s_dmaHandleList.dma_list = curr->next; + } + /* 2, if it is the last one */ + else if (curr->next == NULL) + { + prev->next = NULL; + } + /* 3, if it is in the middle */ + else + { + prev->next = curr->next; + } + break; + } + + prev = curr; + curr = curr->next; + } + + /* Reset all handle data. */ + (void)memset(uartDmaHandle, 0, sizeof(hal_uart_dma_state_t)); + + s_dmaHandleList.activeCount = (s_dmaHandleList.activeCount > 0) ? (s_dmaHandleList.activeCount - 1) : 0; + if (0 == s_dmaHandleList.activeCount) + { + (void)TM_Close((timer_handle_t)s_dmaHandleList.timerManagerHandle); + } + + return kStatus_HAL_UartDmaSuccess; +} + +hal_uart_dma_status_t HAL_UartDMATransferInstallCallback(hal_uart_handle_t handle, + hal_uart_dma_transfer_callback_t callback, + void *callbackParam) +{ + hal_uart_state_t *uartHandle; + hal_uart_dma_state_t *uartDmaHandle; + + assert(handle); + + uartHandle = (hal_uart_state_t *)handle; + uartDmaHandle = uartHandle->dmaHandle; + + assert(uartDmaHandle); + + uartDmaHandle->dma_callback = callback; + uartDmaHandle->dma_callback_param = callbackParam; + + USART_TransferCreateHandleDMA(s_UsartAdapterBase[uartDmaHandle->instance], &uartDmaHandle->dmaHandle, + USART_DMACallbacks, uartDmaHandle, &uartDmaHandle->txDmaHandle, + &uartDmaHandle->rxDmaHandle); + + return kStatus_HAL_UartDmaSuccess; +} + +hal_uart_dma_status_t HAL_UartDMATransferReceive(hal_uart_handle_t handle, + uint8_t *data, + size_t length, + bool receiveAll) +{ + hal_uart_state_t *uartHandle; + hal_uart_dma_state_t *uartDmaHandle; + usart_transfer_t xfer; + + assert(handle); + assert(data); + + uartHandle = (hal_uart_state_t *)handle; + uartDmaHandle = uartHandle->dmaHandle; + + assert(uartDmaHandle); + + if (NULL == uartDmaHandle->dma_rx.buffer) + { + uartDmaHandle->dma_rx.buffer = data; + uartDmaHandle->dma_rx.bufferLength = length; + uartDmaHandle->dma_rx.timeout = 0U; + uartDmaHandle->dma_rx.receiveAll = receiveAll; + } + else + { + /* Already in reading process. */ + return kStatus_HAL_UartDmaRxBusy; + } + + xfer.data = data; + xfer.dataSize = length; + + USART_TransferReceiveDMA(s_UsartAdapterBase[uartDmaHandle->instance], &uartDmaHandle->dmaHandle, &xfer); + + return kStatus_HAL_UartDmaSuccess; +} + +hal_uart_dma_status_t HAL_UartDMATransferSend(hal_uart_handle_t handle, uint8_t *data, size_t length) +{ + hal_uart_state_t *uartHandle; + hal_uart_dma_state_t *uartDmaHandle; + usart_transfer_t xfer; + + assert(handle); + assert(data); + + uartHandle = (hal_uart_state_t *)handle; + uartDmaHandle = uartHandle->dmaHandle; + + assert(uartDmaHandle); + + if (NULL == uartDmaHandle->dma_tx.buffer) + { + uartDmaHandle->dma_tx.buffer = data; + uartDmaHandle->dma_tx.bufferLength = length; + uartDmaHandle->dma_tx.bufferSofar = 0U; + uartDmaHandle->dma_tx.timeout = 0U; + } + else + { + /* Already in writing process. */ + return kStatus_HAL_UartDmaTxBusy; + } + + xfer.data = data; + xfer.dataSize = length; + + USART_TransferSendDMA(s_UsartAdapterBase[uartDmaHandle->instance], &uartDmaHandle->dmaHandle, &xfer); + + return kStatus_HAL_UartDmaSuccess; +} + +hal_uart_dma_status_t HAL_UartDMAGetReceiveCount(hal_uart_handle_t handle, uint32_t *reCount) +{ + hal_uart_state_t *uartHandle; + hal_uart_dma_state_t *uartDmaHandle; + + assert(handle); + + uartHandle = (hal_uart_state_t *)handle; + uartDmaHandle = uartHandle->dmaHandle; + + assert(uartDmaHandle); + + if (kStatus_Success != USART_TransferGetReceiveCountDMA(s_UsartAdapterBase[uartDmaHandle->instance], + &uartDmaHandle->dmaHandle, reCount)) + { + return kStatus_HAL_UartDmaError; + } + + return kStatus_HAL_UartDmaSuccess; +} + +hal_uart_dma_status_t HAL_UartDMAGetSendCount(hal_uart_handle_t handle, uint32_t *seCount) +{ + /* No get send count API */ + return kStatus_HAL_UartDmaError; +} + +hal_uart_dma_status_t HAL_UartDMAAbortReceive(hal_uart_handle_t handle) +{ + hal_uart_state_t *uartHandle; + hal_uart_dma_state_t *uartDmaHandle; + + assert(handle); + + uartHandle = (hal_uart_state_t *)handle; + uartDmaHandle = uartHandle->dmaHandle; + + assert(uartDmaHandle); + + USART_TransferAbortReceiveDMA(s_UsartAdapterBase[uartDmaHandle->instance], &uartDmaHandle->dmaHandle); + + return kStatus_HAL_UartDmaSuccess; +} + +hal_uart_dma_status_t HAL_UartDMAAbortSend(hal_uart_handle_t handle) +{ + hal_uart_state_t *uartHandle; + hal_uart_dma_state_t *uartDmaHandle; + + assert(handle); + + uartHandle = (hal_uart_state_t *)handle; + uartDmaHandle = uartHandle->dmaHandle; + + assert(uartDmaHandle); + + USART_TransferAbortSendDMA(s_UsartAdapterBase[uartDmaHandle->instance], &uartDmaHandle->dmaHandle); + + return kStatus_HAL_UartDmaSuccess; +} +#endif /* HAL_UART_DMA_ENABLE */ |