/* * Copyright 2018 NXP * All rights reserved. * * * SPDX-License-Identifier: BSD-3-Clause */ #include "fsl_common.h" #include "fsl_uart.h" #include "fsl_adapter_uart.h" /******************************************************************************* * Definitions ******************************************************************************/ #ifndef NDEBUG #if (defined(DEBUG_CONSOLE_ASSERT_DISABLE) && (DEBUG_CONSOLE_ASSERT_DISABLE > 0U)) #undef assert #define assert(n) #endif #endif #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)) uart_handle_t hardwareHandle; #endif hal_uart_receive_state_t rx; hal_uart_send_state_t tx; #endif uint8_t instance; } hal_uart_state_t; /******************************************************************************* * Prototypes ******************************************************************************/ /******************************************************************************* * Variables ******************************************************************************/ static UART_Type *const s_UartAdapterBase[] = UART_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 UART IRQ number. */ static const IRQn_Type s_UartIRQ[] = UART_IRQS; static hal_uart_state_t *s_UartState[sizeof(s_UartAdapterBase) / sizeof(UART_Type *)]; #endif #endif /******************************************************************************* * Code ******************************************************************************/ #if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 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_UART_TxBusy: uartStatus = kStatus_HAL_UartTxBusy; break; case kStatus_UART_RxBusy: uartStatus = kStatus_HAL_UartRxBusy; break; case kStatus_UART_TxIdle: uartStatus = kStatus_HAL_UartTxIdle; break; case kStatus_UART_RxIdle: uartStatus = kStatus_HAL_UartRxIdle; break; case kStatus_UART_BaudrateNotSupport: uartStatus = kStatus_HAL_UartBaudrateNotSupport; break; case kStatus_UART_NoiseError: case kStatus_UART_FramingError: case kStatus_UART_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(UART_Type *base, uart_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 (uartHandle->hardwareHandle.rxDataSize) { uartStatus = kStatus_HAL_UartError; } } if (uartHandle->callback) { uartHandle->callback(uartHandle, uartStatus, uartHandle->callbackParam); } } #else static void HAL_UartInterruptHandle(uint8_t instance) { hal_uart_state_t *uartHandle = s_UartState[instance]; if (NULL == uartHandle) { return; } /* Receive data register full */ if (UART_GetStatusFlag(s_UartAdapterBase[instance], kUART_RxReadyFlag)) { UART_ClearStatusFlag(s_UartAdapterBase[instance], kUART_RxReadyFlag); if (UART_GetEnabledInterrupts(s_UartAdapterBase[instance]) & kUART_RxReadyEnable) { if (uartHandle->rx.buffer) { uartHandle->rx.buffer[uartHandle->rx.bufferSofar++] = UART_ReadByte(s_UartAdapterBase[instance]); if (uartHandle->rx.bufferSofar >= uartHandle->rx.bufferLength) { /* Disable RX interrupt/overrun interrupt/framing error interrupt */ UART_DisableInterrupts(s_UartAdapterBase[instance], kUART_RxReadyEnable | kUART_AgingTimerEnable | kUART_RxOverrunEnable | kUART_ParityErrorEnable | kUART_FrameErrorEnable); uartHandle->rx.buffer = NULL; if (uartHandle->callback) { uartHandle->callback(uartHandle, kStatus_HAL_UartRxIdle, uartHandle->callbackParam); } } } } } /* Send data register empty and the interrupt is enabled. */ if (UART_GetStatusFlag(s_UartAdapterBase[instance], kUART_TxEmptyFlag)) { UART_ClearStatusFlag(s_UartAdapterBase[instance], kUART_TxEmptyFlag); if (UART_GetEnabledInterrupts(s_UartAdapterBase[instance]) & kUART_TxReadyEnable) { if (uartHandle->tx.buffer) { UART_WriteByte(s_UartAdapterBase[instance], uartHandle->tx.buffer[uartHandle->tx.bufferSofar++]); if (uartHandle->tx.bufferSofar >= uartHandle->tx.bufferLength) { UART_DisableInterrupts(s_UartAdapterBase[uartHandle->instance], kUART_TxReadyEnable); uartHandle->tx.buffer = NULL; if (uartHandle->callback) { uartHandle->callback(uartHandle, kStatus_HAL_UartTxIdle, uartHandle->callbackParam); } } } } } } #endif #endif hal_uart_status_t HAL_UartInit(hal_uart_handle_t handle, const hal_uart_config_t *uart_config) { hal_uart_state_t *uartHandle; uart_config_t uartConfig; status_t status; assert(handle); assert(uart_config); assert(uart_config->instance < (sizeof(s_UartAdapterBase) / sizeof(UART_Type *))); assert(s_UartAdapterBase[uart_config->instance]); assert(HAL_UART_HANDLE_SIZE >= sizeof(hal_uart_state_t)); UART_GetDefaultConfig(&uartConfig); uartConfig.baudRate_Bps = uart_config->baudRate_Bps; if (kHAL_UartParityEven == uart_config->parityMode) { uartConfig.parityMode = kUART_ParityEven; } else if (kHAL_UartParityOdd == uart_config->parityMode) { uartConfig.parityMode = kUART_ParityOdd; } else { uartConfig.parityMode = kUART_ParityDisabled; } if (kHAL_UartTwoStopBit == uart_config->stopBitCount) { uartConfig.stopBitCount = kUART_TwoStopBit; } else { uartConfig.stopBitCount = kUART_OneStopBit; } uartConfig.enableRx = (bool)uart_config->enableRx; uartConfig.enableTx = (bool)uart_config->enableTx; status = UART_Init(s_UartAdapterBase[uart_config->instance], &uartConfig, uart_config->srcClock_Hz); if (kStatus_Success != status) { return HAL_UartGetStatus(status); } uartHandle = (hal_uart_state_t *)handle; uartHandle->instance = uart_config->instance; #if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U)) #if (defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U)) UART_TransferCreateHandle(s_UartAdapterBase[uart_config->instance], &uartHandle->hardwareHandle, (uart_transfer_callback_t)HAL_UartCallback, handle); #else s_UartState[uartHandle->instance] = uartHandle; /* Enable interrupt in NVIC. */ NVIC_SetPriority((IRQn_Type)s_UartIRQ[uart_config->instance], HAL_UART_ISR_PRIORITY); EnableIRQ(s_UartIRQ[uart_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; UART_Deinit(s_UartAdapterBase[uartHandle->instance]); #if (defined(UART_ADAPTER_NON_BLOCKING_MODE) && (UART_ADAPTER_NON_BLOCKING_MODE > 0U)) #if !(defined(HAL_UART_TRANSFER_MODE) && (HAL_UART_TRANSFER_MODE > 0U)) s_UartState[uartHandle->instance] = NULL; #endif #endif 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 (uartHandle->rx.buffer) { return kStatus_HAL_UartRxBusy; } #endif status = UART_ReadBlocking(s_UartAdapterBase[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 (uartHandle->tx.buffer) { return kStatus_HAL_UartTxBusy; } #endif (void)UART_WriteBlocking(s_UartAdapterBase[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(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(HAL_UART_TRANSFER_MODE); uartHandle = (hal_uart_state_t *)handle; status = UART_TransferReceiveNonBlocking(s_UartAdapterBase[uartHandle->instance], &uartHandle->hardwareHandle, (uart_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(HAL_UART_TRANSFER_MODE); uartHandle = (hal_uart_state_t *)handle; status = UART_TransferSendNonBlocking(s_UartAdapterBase[uartHandle->instance], &uartHandle->hardwareHandle, (uart_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(HAL_UART_TRANSFER_MODE); uartHandle = (hal_uart_state_t *)handle; status = UART_TransferGetReceiveCount(s_UartAdapterBase[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(HAL_UART_TRANSFER_MODE); uartHandle = (hal_uart_state_t *)handle; status = UART_TransferGetSendCount(s_UartAdapterBase[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(HAL_UART_TRANSFER_MODE); uartHandle = (hal_uart_state_t *)handle; UART_TransferAbortReceive(s_UartAdapterBase[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(HAL_UART_TRANSFER_MODE); uartHandle = (hal_uart_state_t *)handle; UART_TransferAbortSend(s_UartAdapterBase[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(!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(!HAL_UART_TRANSFER_MODE); uartHandle = (hal_uart_state_t *)handle; if (uartHandle->rx.buffer) { return kStatus_HAL_UartRxBusy; } uartHandle->rx.bufferLength = length; uartHandle->rx.bufferSofar = 0; uartHandle->rx.buffer = data; /* Enable RX/Rx overrun/framing error interrupt. */ UART_EnableInterrupts(s_UartAdapterBase[uartHandle->instance], kUART_RxReadyEnable | kUART_AgingTimerEnable | kUART_RxOverrunEnable); 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(!HAL_UART_TRANSFER_MODE); uartHandle = (hal_uart_state_t *)handle; if (uartHandle->tx.buffer) { return kStatus_HAL_UartTxBusy; } uartHandle->tx.bufferLength = length; uartHandle->tx.bufferSofar = 0; uartHandle->tx.buffer = (volatile uint8_t *)data; UART_EnableInterrupts(s_UartAdapterBase[uartHandle->instance], kUART_TxReadyEnable); 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(!HAL_UART_TRANSFER_MODE); uartHandle = (hal_uart_state_t *)handle; if (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(!HAL_UART_TRANSFER_MODE); uartHandle = (hal_uart_state_t *)handle; if (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(!HAL_UART_TRANSFER_MODE); uartHandle = (hal_uart_state_t *)handle; if (uartHandle->rx.buffer) { /* Disable RX interrupt/overrun interrupt/framing error interrupt */ UART_DisableInterrupts(s_UartAdapterBase[uartHandle->instance], kUART_RxReadyEnable | kUART_AgingTimerEnable | kUART_RxOverrunEnable | kUART_ParityErrorEnable | kUART_FrameErrorEnable); 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(!HAL_UART_TRANSFER_MODE); uartHandle = (hal_uart_state_t *)handle; if (uartHandle->tx.buffer) { UART_DisableInterrupts(s_UartAdapterBase[uartHandle->instance], kUART_TxReadyEnable); 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(HAL_UART_TRANSFER_MODE); uartHandle = (hal_uart_state_t *)handle; #if 0 DisableIRQ(s_UartIRQ[uartHandle->instance]); #endif UART_TransferHandleIRQ(s_UartAdapterBase[uartHandle->instance], &uartHandle->hardwareHandle); #if 0 NVIC_SetPriority((IRQn_Type)s_UartIRQ[uartHandle->instance], HAL_UART_ISR_PRIORITY); EnableIRQ(s_UartIRQ[uartHandle->instance]); #endif } #else void HAL_UartIsrFunction(hal_uart_handle_t handle) { hal_uart_state_t *uartHandle; assert(handle); assert(!HAL_UART_TRANSFER_MODE); uartHandle = (hal_uart_state_t *)handle; #if 0 DisableIRQ(s_UartIRQ[uartHandle->instance]); #endif HAL_UartInterruptHandle(uartHandle->instance); #if 0 NVIC_SetPriority((IRQn_Type)s_UartIRQ[uartHandle->instance], HAL_UART_ISR_PRIORITY); EnableIRQ(s_UartIRQ[uartHandle->instance]); #endif } #if defined(UART1) void UART1_IRQHandler(void) { HAL_UartInterruptHandle(1); SDK_ISR_EXIT_BARRIER; } #endif #if defined(UART2) void UART2_IRQHandler(void) { HAL_UartInterruptHandle(2); SDK_ISR_EXIT_BARRIER; } #endif #if defined(UART3) void UART3_IRQHandler(void) { HAL_UartInterruptHandle(3); SDK_ISR_EXIT_BARRIER; } #endif #if defined(UART4) void UART4_IRQHandler(void) { HAL_UartInterruptHandle(4); SDK_ISR_EXIT_BARRIER; } #endif #if defined(UART5) void UART5_IRQHandler(void) { HAL_UartInterruptHandle(5); SDK_ISR_EXIT_BARRIER; } #endif #if defined(UART6) void UART6_IRQHandler(void) { HAL_UartInterruptHandle(6); SDK_ISR_EXIT_BARRIER; } #endif #if defined(UART7) void UART7_IRQHandler(void) { HAL_UartInterruptHandle(7); SDK_ISR_EXIT_BARRIER; } #endif #if defined(UART8) void UART8_IRQHandler(void) { HAL_UartInterruptHandle(8); SDK_ISR_EXIT_BARRIER; } #endif #endif #endif