/* * ivec_mcal_uart.c * * Created on: 28-Oct-2024 * Author: altam */ #include "../Core/Include/ivec_mcal_uart.h" #include "string.h" #include "../../utils/utils.h" #define LOG_STRING "ivec-mcal-uart" /* Global UART Handles Array */ static IVEC_McalUartHandle_s* __gprv_pIVEC_McalUartHandle_ss[IVEC_MCAL_UART_PORT_MAX] = { 0 }; /* Static Variables */ static uint32_t __gprv_u32DataCount = 0; /* Data count for tracking received bytes */ /* Static Function Prototypes */ static IVEC_McalUartPort_e __prv_McalGetUartPort(UART_Regs* pxUartInstance); /** * @brief UART read callback function. * * This function is triggered upon receiving data via UART. It increments a data * counter, logs the reception event, and invokes the appropriate user-defined * callback for handling the received data. * * @param[in] pxUartInstance Pointer to the UART instance triggering the callback. * @param[in] pu8Buffer Pointer to the buffer containing the received data. * @param[in] bStatus Boolean indicating the success of the receive operation: * - `true`: Data received successfully. * - `false`: Data reception failed. * * @details * - If `bStatus` is true: * 1. Increments the `prv_u32DataCount` variable to track received data events. * 2. Logs the data count using the `IVEC_MCAL_LOG` macro. * 3. Iterates through `gpIVEC_McalUartHandle_ss` to find a valid UART handle. * 4. If a valid user-defined receive callback (`pvUartRecvCallback`) is found, * it is invoked with the received data. * - If `bStatus` is false, the function performs no additional operations. */ void vMCAL_UartReadCallback(UART_Regs* pxUartInstance, uint8_t* pu8Buffer, bool bStatus) { if (bStatus) { __gprv_u32DataCount++; IVEC_MCAL_LOG(LOG_STRING, "UART Receive Callback: %d", prv_u32DataCount); for (uint32_t i = 0; i < IVEC_MCAL_UART_PORT_MAX; i++) { if (__gprv_pIVEC_McalUartHandle_ss[i] != NULL) { if (__gprv_pIVEC_McalUartHandle_ss[i]->pvUartRecvCallback != NULL) { __gprv_pIVEC_McalUartHandle_ss[i]->pvUartRecvCallback(__prv_McalGetUartPort(pxUartInstance),IVEC_MCAL_UART_EVENT_RX_ARRIVED,(char*)pu8Buffer,1); } break; } } } } /** * @brief Handles UART RX events and errors. * * Processes received data, clears interrupt flags, and handles specific * error conditions such as overrun, framing, and parity errors. * * @param[in] pxUartInstance Pointer to the UART instance triggering the callback. * @param[in] u32Event Event type indicating the RX or error condition. */ void prv_vRxCallback(UART_Regs* pxUartInstance, uint32_t u32Event) { switch (u32Event) { case DL_UART_MAIN_IIDX_RX: { uint8_t u8RxBuffer[64] = { 0 }; // Adjust size as needed uint32_t u32BytesRead = 0; // Drain the RX FIFO and store the data in buffer u32BytesRead = DL_UART_drainRXFIFO(pxUartInstance, u8RxBuffer, sizeof(u8RxBuffer)); // Clear the RX interrupt flag DL_UART_clearInterruptStatus(pxUartInstance, DL_UART_MAIN_IIDX_RX); // Process each byte of received data for (uint32_t u32Index = 0; u32Index < u32BytesRead; u32Index++) { vMCAL_UartReadCallback(pxUartInstance, &u8RxBuffer[u32Index], true); } break; } case DL_UART_MAIN_IIDX_OVERRUN_ERROR: DL_UART_clearInterruptStatus(pxUartInstance, DL_UART_MAIN_IIDX_OVERRUN_ERROR); __asm("nop"); break; case DL_UART_MAIN_IIDX_BREAK_ERROR: DL_UART_clearInterruptStatus(pxUartInstance, DL_UART_MAIN_IIDX_BREAK_ERROR); __asm("nop"); break; case DL_UART_MAIN_IIDX_PARITY_ERROR: DL_UART_clearInterruptStatus(pxUartInstance, DL_UART_MAIN_IIDX_PARITY_ERROR); __asm("nop"); break; case DL_UART_MAIN_IIDX_FRAMING_ERROR: DL_UART_clearInterruptStatus(pxUartInstance, DL_UART_MAIN_IIDX_FRAMING_ERROR); __asm("nop"); break; case DL_UART_MAIN_IIDX_RX_TIMEOUT_ERROR: DL_UART_clearInterruptStatus(pxUartInstance, DL_UART_MAIN_IIDX_RX_TIMEOUT_ERROR); __asm("nop"); break; case DL_UART_MAIN_IIDX_NOISE_ERROR: DL_UART_clearInterruptStatus(pxUartInstance, DL_UART_MAIN_IIDX_NOISE_ERROR); __asm("nop"); break; default: break; } } void UART0_IRQHandler() { prv_vRxCallback(UART0, DL_UART_Main_getPendingInterrupt(UART0)); } void UART1_IRQHandler() { prv_vRxCallback(UART1, DL_UART_Main_getPendingInterrupt(UART1)); } void UART2_IRQHandler() { prv_vRxCallback(UART2, DL_UART_Main_getPendingInterrupt(UART2)); } /** * @brief Retrieves the UART instance for the specified port number. * * Maps a UART port number to its corresponding hardware instance. * * @param[in] eUartPortNumber UART port number to retrieve the instance for. * @return Pointer to the UART instance, or `eMcalUartPortMax` for invalid input. */ static UART_Regs* __prv_McalGetUartInstance(IVEC_McalUartPort_e eUartPortNumber) { switch (eUartPortNumber) { case IVEC_MCAL_UART_PORT_1: return UART0; case IVEC_MCAL_UART_PORT_2: return UART1; case IVEC_MCAL_UART_PORT_3: return UART2; default: return NULL; // Invalid UART port } } /** * @brief Maps UART instance to a corresponding port number. * * Returns the appropriate `eMcalUartPortNumber` based on the given UART * instance. If the instance is not recognized, returns `eMcalUartPortMax`. * * @param[in] pxUartInstance Pointer to the UART instance. * @return Corresponding `eMcalUartPortNumber` or `eMcalUartPortMax` if invalid. */ static IVEC_McalUartPort_e __prv_McalGetUartPort(UART_Regs* pxUartInstance) { switch ((uint32_t)pxUartInstance) { case (uint32_t)UART0: return IVEC_MCAL_UART_PORT_1; case (uint32_t)UART1: return IVEC_MCAL_UART_PORT_2; case (uint32_t)UART2: return IVEC_MCAL_UART_PORT_3; default: return IVEC_MCAL_UART_PORT_MAX; // Invalid UART port } } /** * @brief Deinitializes a UART instance. * * Disables the specified UART instance, clears interrupt flags, and disables * interrupt requests. Optionally resets the UART clock configuration. * * @param[in] pxUartHandle Pointer to the UART handle containing the port number. * @return `IVEC_CORE_STATUS_SUCCESS` if deinitialization is successful, * `IVEC_CORE_STATUS_ERROR` if the UART instance is invalid. */ static IVEC_McalCommonErr_e _prvMCAL_UartDeInitInstance(IVEC_McalUartHandle_s* pxUartHandle) { // Get the UART instance based on the port number in the handle UART_Regs* pxUartInstance = __prv_McalGetUartInstance(pxUartHandle->eUartPortNumber); // Check if the UART instance is valid if (pxUartInstance == NULL) { return commonMCAL_INVALID_PARAM; } // Disable UART instance DL_UART_Main_disable(pxUartInstance ); // Disable interrupts for the UART instance DL_UART_Main_disableInterrupt(pxUartInstance , DL_UART_MAIN_INTERRUPT_BREAK_ERROR | DL_UART_MAIN_INTERRUPT_FRAMING_ERROR | DL_UART_MAIN_INTERRUPT_NOISE_ERROR | DL_UART_MAIN_INTERRUPT_OVERRUN_ERROR | DL_UART_MAIN_INTERRUPT_PARITY_ERROR | DL_UART_MAIN_INTERRUPT_RX | DL_UART_MAIN_INTERRUPT_RX_TIMEOUT_ERROR); // Clear and disable NVIC interrupt requests based on UART instance if (pxUartInstance == UART0) { NVIC_DisableIRQ(UART0_INT_IRQn); NVIC_ClearPendingIRQ(UART0_INT_IRQn); // Reset the UART0 init flag if needed (b_UART0_init_flag = 0) } else if (pxUartInstance == UART1) { NVIC_DisableIRQ(UART1_INT_IRQn); NVIC_ClearPendingIRQ(UART1_INT_IRQn); // Reset the UART1 init flag if needed (b_UART1_init_flag = 0) } else if (pxUartInstance == UART2) { NVIC_DisableIRQ(UART2_INT_IRQn); NVIC_ClearPendingIRQ(UART2_INT_IRQn); // Reset the UART2 init flag if needed (b_UART2_init_flag = 0) } // Optionally, reset the UART clock configuration if needed DL_UART_Main_setClockConfig(pxUartInstance, NULL); return commonMCAL_SUCCESS; } /** * @brief Deinitializes the specified UART instance. * * This function validates the UART handle and port, then calls a private function * to deinitialize the UART instance. It logs the status and returns an error code * if the deinitialization fails. * * @param[in] pxUartHandle Pointer to the UART handle containing the port number. * @return `commonMCAL_SUCCESS` if deinitialization is successful, * `commonMCAL_INVALID_PARAM` if the input parameters are invalid, * `commonMCAL_DEINIT_FAIL` if deinitialization fails. */ IVEC_McalCommonErr_e xMCAL_UartDeInit(IVEC_McalUartHandle_s* pxUartHandle) { if (pxUartHandle == NULL || pxUartHandle->eUartPortNumber >= IVEC_MCAL_UART_PORT_MAX) { return commonMCAL_INIT_FAIL; } IVEC_McalCommonErr_e xRetStatus; IVEC_MCAL_FUNC_ENTRY(LOG_STRING); IVEC_McalCommonErr_e eFuncStatus = commonMCAL_SUCCESS; // Check for null pointer if (pxUartHandle == NULL) { eFuncStatus = commonMCAL_INVALID_PARAM; goto exit; } // Call the private deinit function xRetStatus = _prvMCAL_UartDeInitInstance(pxUartHandle); IVEC_MCAL_LOG(LOG_STRING, "Deinitializing UART status: %d", xRetStatus); // Check the return status if (xRetStatus != commonMCAL_SUCCESS) { eFuncStatus = commonMCAL_DEINIT_FAIL; goto exit; } exit: IVEC_MCAL_FUNC_EXIT(LOG_STRING); return eFuncStatus; } /////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// /** * @brief Reads a byte of data from the UART port. * * This function attempts to read a single byte of data from the specified UART * instance. It waits until data is received or a timeout occurs. If no data is * received within the timeout, it returns an error. * * @param[in] pxUartHandle Pointer to the UART handle containing the port number. * @param[out] pucData Pointer to the buffer where the received data will be stored. * @return `commonMCAL_SUCCESS` if the data is read successfully, * `commonMCAL_FAIL` if no data was received or an error occurred. */ static IVEC_McalCommonErr_e __prv_McalUartReadByte(IVEC_McalUartHandle_s* pxUartHandle, uint8_t* pucData) { /* Get the UART instance based on the port number in the handle */ UART_Regs* pUartInstance = __prv_McalGetUartInstance(pxUartHandle->eUartPortNumber); /* Check if the UART instance is valid */ if (pUartInstance == NULL) { return commonMCAL_FAIL; } bool bDataReceived = false; uint32_t u32StartTick = i32MCAL_getTicks(); /* Wait until data is received or timeout occurs */ while (!DL_UART_isTXFIFOEmpty(pUartInstance) && ((i32MCAL_getTicks() - u32StartTick) < 50)) { *pucData = DL_UART_Main_receiveData(pUartInstance); bDataReceived = true; } /* Return error if no data was received */ if (!bDataReceived) { return commonMCAL_FAIL; } return commonMCAL_SUCCESS; } /** * @brief Reads multiple bytes of data from the UART port. * * This function validates the UART handle, attempts to read data from the UART port, * and returns the appropriate status. If the UART handle is invalid or the read * operation fails, it returns an error status. * * @param[in] pxUartHandle Pointer to the UART handle containing the port number. * @param[out] pucData Pointer to the buffer where the received data will be stored. * @param[in] u32DataLength The length of data to read. * @return `commonMCAL_INIT_FAIL` if the UART handle is invalid, * `commonMCAL_INVALID_PARAM` if input parameters are incorrect, * `commonMCAL_FAIL` if the read operation fails. */ IVEC_McalCommonErr_e xMCAL_UartRead(IVEC_McalUartHandle_s* pxUartHandle, uint8_t* pucData, uint32_t u32DataLength) { if (pxUartHandle == NULL || pxUartHandle->eUartPortNumber >= IVEC_MCAL_UART_PORT_MAX) { return commonMCAL_INIT_FAIL; } int32_t i32RetVal; IVEC_McalCommonErr_e eFuncStatus = commonMCAL_SUCCESS; IVEC_MCAL_FUNC_ENTRY(LOG_STRING); /* Validate the UART handle */ if (pxUartHandle == NULL) { eFuncStatus = commonMCAL_INVALID_PARAM; goto exit; } /* Attempt to read a single byte from UART */ i32RetVal = __prv_McalUartReadByte(pxUartHandle, pucData); /* Log the read operation status */ IVEC_MCAL_LOG(LOG_STRING, "UART read status: %d", i32RetVal); /* Check if the read operation failed */ if (i32RetVal == commonMCAL_SUCCESS) { eFuncStatus = commonMCAL_FAIL; goto exit; } exit: IVEC_MCAL_FUNC_EXIT(LOG_STRING); return eFuncStatus; } /////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////// /** * @brief Transmits data over the specified UART port. * * This function writes a specified number of bytes to the UART port, checking for * transmission timeout. If the transmission is successful, it returns a success * status, otherwise, it returns an error. * * @param[in] pxUartHandle Pointer to the UART handle containing the port number. * @param[in] pu8TxData Pointer to the buffer containing the data to transmit. * @param[in] u32Size Number of bytes to transmit. * @return `IVEC_CORE_STATUS_SUCCESS` if data is transmitted successfully, * `IVEC_CORE_STATUS_ERROR` if an error occurs. */ static IVEC_McalCommonErr_e __prv_McalUartTransmit(IVEC_McalUartHandle_s* pxUartHandle, uint8_t* pu8TxData, uint32_t u32Size) { /* Retrieve UART instance based on the port number */ UART_Regs* pxUartInstance = __prv_McalGetUartInstance(pxUartHandle->eUartPortNumber); /* Validate the UART instance and data size */ if (pxUartInstance == NULL || u32Size == 0) { return commonMCAL_INVALID_PARAM; } /* Track transmission timeout */ uint32_t u32TickStart = i32MCAL_getTicks(); for (uint32_t u32Index = 0; u32Index < u32Size; u32Index++) { /* Transmit data byte */ DL_UART_transmitData(pxUartInstance, pu8TxData[u32Index]); /* Wait for TX FIFO to become available, with timeout */ while (DL_UART_isTXFIFOFull(pxUartInstance) && ((i32MCAL_getTicks() - u32TickStart) < 100)); } return commonMCAL_SUCCESS; } /** * @brief Writes data to the UART port. * * This function validates the UART handle, checks if the UART is initialized, and * calls the static function to transmit data. It logs the status and handles errors * related to the UART transmission. * * @param[in] pxUartHandle Pointer to the UART handle structure. * @param[in] pu8Data Pointer to the data buffer to send. * @param[in] u32DataLength Length of the data to be sent. * @return `commonMCAL_INIT_FAIL` if the UART handle is invalid, * `commonMCAL_INVALID_PARAM` if input parameters are invalid, * `commonMCAL_WRITE_FAIL` if the write operation fails. */ IVEC_McalCommonErr_e xMCAL_UartWrite(IVEC_McalUartHandle_s* pxUartHandle, uint8_t* pu8Data, uint32_t u32DataLength) { if (pxUartHandle == NULL || pxUartHandle->eUartPortNumber >= IVEC_MCAL_UART_PORT_MAX) { return commonMCAL_INIT_FAIL; } IVEC_McalCommonErr_e eFuncStatus = commonMCAL_SUCCESS; int32_t i32Ret; /* Log function entry */ IVEC_MCAL_FUNC_ENTRY(LOG_STRING); /* Validate input parameters */ if (pxUartHandle == NULL) { eFuncStatus = commonMCAL_INVALID_PARAM; goto exit; } /* Call static transmit function */ i32Ret = __prv_McalUartTransmit(pxUartHandle, pu8Data, u32DataLength); /* Log transmit status */ IVEC_MCAL_LOG(LOG_STRING, "UART write status: %d", i32Ret); /* Handle transmit errors */ if (i32Ret != IVEC_CORE_STATUS_SUCCESS) { eFuncStatus = commonMCAL_WRITE_FAIL; goto exit; } exit: /* Log function exit */ IVEC_MCAL_FUNC_EXIT(LOG_STRING); return eFuncStatus; } ///////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////// /** * @brief Initializes a UART instance based on the given configuration. * * This function configures the specified UART port by initializing the * required GPIO pins for TX and RX, configuring the UART settings such * as baud rate, word length, stop bits, parity, and clock settings. * It also enables interrupts for error handling and sets FIFO thresholds * for efficient data transmission and reception. * * @param [in] pxUartHandle Pointer to a structure that holds the UART * configuration parameters. * @param [in] xBaud The desired baud rate for the UART communication. * Supported values include various baud rates like * 115200, 9600, 2400, etc. * * @return IVEC_CoreStatus_e Returns `commonMCAL_SUCCESS` if initialization * was successful, otherwise returns `commonMCAL_FAIL` in case of errors. */ static IVEC_McalCommonErr_e __prv_McalUartInitInstance(IVEC_McalUartHandle_s* pxUartHandle, IVEC_McalUartBaudRate_e xBaud) { if (pxUartHandle->eUartPortNumber == IVEC_MCAL_UART_PORT_2) { DL_UART_Main_reset(UART1); DL_UART_Main_enablePower(UART1); DL_GPIO_initPeripheralOutputFunction(IOMUX_PINCM19, IOMUX_PINCM19_PF_UART1_TX); DL_GPIO_initPeripheralInputFunction(IOMUX_PINCM20, IOMUX_PINCM20_PF_UART1_RX); } else if (pxUartHandle->eUartPortNumber == IVEC_MCAL_UART_PORT_3) { DL_UART_Main_reset(UART2); DL_UART_Main_enablePower(UART2); DL_GPIO_initPeripheralOutputFunction(IOMUX_PINCM32, IOMUX_PINCM32_PF_UART2_TX); DL_GPIO_initPeripheralInputFunction(IOMUX_PINCM33, IOMUX_PINCM33_PF_UART2_RX); } UART_Regs* pxUartInstance = __prv_McalGetUartInstance(pxUartHandle->eUartPortNumber); if (pxUartInstance == NULL) { return commonMCAL_FAIL; } DL_UART_Config xUartConfig = { 0 }; xUartConfig.direction = DL_UART_MAIN_DIRECTION_TX_RX; xUartConfig.mode = DL_UART_MAIN_MODE_NORMAL; uint8_t u8DataLength = pxUartHandle->xUartConfig.eUartDataBit; if (u8DataLength == IVEC_MCAL_UART_DATA_BIT_7) { xUartConfig.wordLength = DL_UART_WORD_LENGTH_7_BITS; } else if (u8DataLength == IVEC_MCAL_UART_DATA_BIT_8) { xUartConfig.wordLength = DL_UART_WORD_LENGTH_8_BITS; } uint8_t u8StopBit = pxUartHandle->xUartConfig.eUartStopBit; if (u8StopBit == IVEC_MCAL_UART_STOP_BIT_1) { xUartConfig.stopBits = DL_UART_STOP_BITS_ONE; } else if (u8StopBit == IVEC_MCAL_UART_STOP_BIT_2) { xUartConfig.stopBits = DL_UART_STOP_BITS_TWO; } uint8_t u8ParityBit = pxUartHandle->xUartConfig.eUartParityBit; if (u8ParityBit == IVEC_MCAL_UART_PARITY_NONE) { xUartConfig.parity = DL_UART_PARITY_NONE; } else if (u8ParityBit == IVEC_MCAL_UART_PARITY_ODD) { xUartConfig.parity = DL_UART_PARITY_ODD; } else if (u8ParityBit == IVEC_MCAL_UART_PARITY_EVEN) { xUartConfig.parity = DL_UART_PARITY_EVEN; } xUartConfig.flowControl = DL_UART_FLOW_CONTROL_NONE; DL_UART_ClockConfig xUartClockConfig = { 0 }; xUartClockConfig.clockSel = DL_UART_CLOCK_BUSCLK; xUartClockConfig.divideRatio = DL_UART_MAIN_CLOCK_DIVIDE_RATIO_1; DL_UART_Main_setClockConfig(pxUartInstance, (DL_UART_Main_ClockConfig*) &xUartClockConfig); DL_UART_Main_init(pxUartInstance, (DL_UART_Main_Config*) &xUartConfig); DL_UART_Main_setOversampling(pxUartInstance, DL_UART_OVERSAMPLING_RATE_16X); if (xBaud == IVEC_MCAL_UART_BAUD_115200) { DL_UART_Main_setBaudRateDivisor(pxUartInstance, 19, 34); } else if (xBaud == IVEC_MCAL_UART_BAUD_9600) { DL_UART_Main_setBaudRateDivisor(pxUartInstance, 234, 24); } else if (xBaud == IVEC_MCAL_UART_BAUD_2400) { DL_UART_Main_setBaudRateDivisor(pxUartInstance, 937, 32); } else if (xBaud == IVEC_MCAL_UART_BAUD_4800) { DL_UART_Main_setBaudRateDivisor(pxUartInstance, 468, 48); } else if (xBaud == IVEC_MCAL_UART_BAUD_14400) { DL_UART_Main_setBaudRateDivisor(pxUartInstance, 156, 16); } else if (xBaud == IVEC_MCAL_UART_BAUD_19200) { DL_UART_Main_setBaudRateDivisor(pxUartInstance, 117, 12); } else if (xBaud == IVEC_MCAL_UART_BAUD_28800) { DL_UART_Main_setBaudRateDivisor(pxUartInstance, 78, 8); } else if (xBaud == IVEC_MCAL_UART_BAUD_33600) { DL_UART_Main_setBaudRateDivisor(pxUartInstance, 66, 62); } else if (xBaud == IVEC_MCAL_UART_BAUD_38400) { DL_UART_Main_setBaudRateDivisor(pxUartInstance, 58, 38); } else if (xBaud == IVEC_MCAL_UART_BAUD_57600) { DL_UART_Main_setBaudRateDivisor(pxUartInstance, 39, 4); } else if (xBaud == IVEC_MCAL_UART_BAUD_230400) { DL_UART_Main_setBaudRateDivisor(pxUartInstance, 9, 49); } else if (xBaud == IVEC_MCAL_UART_BAUD_460800) { DL_UART_Main_setBaudRateDivisor(pxUartInstance, 4, 57); } else if (xBaud == IVEC_MCAL_UART_BAUD_921600) { DL_UART_Main_setBaudRateDivisor(pxUartInstance, 2, 28); } else if (xBaud == IVEC_MCAL_UART_BAUD_1000000) { DL_UART_Main_setBaudRateDivisor(pxUartInstance, 2, 16); } else { DL_UART_Main_setBaudRateDivisor(pxUartInstance, 13, 1); } if (pxUartInstance == UART0) { DL_UART_Main_enableInterrupt(pxUartInstance, DL_UART_MAIN_INTERRUPT_BREAK_ERROR | DL_UART_MAIN_INTERRUPT_FRAMING_ERROR | DL_UART_MAIN_INTERRUPT_NOISE_ERROR | DL_UART_MAIN_INTERRUPT_OVERRUN_ERROR | DL_UART_MAIN_INTERRUPT_PARITY_ERROR | DL_UART_MAIN_INTERRUPT_RX | DL_UART_MAIN_INTERRUPT_RX_TIMEOUT_ERROR); DL_UART_Main_enableFIFOs(UART0); DL_UART_Main_setRXFIFOThreshold(UART0, DL_UART_RX_FIFO_LEVEL_ONE_ENTRY); DL_UART_Main_setTXFIFOThreshold(UART0, DL_UART_TX_FIFO_LEVEL_1_2_EMPTY); DL_UART_Main_enable(pxUartInstance); NVIC_ClearPendingIRQ(UART0_INT_IRQn); NVIC_EnableIRQ(UART0_INT_IRQn); } else if (pxUartInstance == UART1) { DL_UART_Main_enableInterrupt(pxUartInstance, DL_UART_MAIN_INTERRUPT_BREAK_ERROR | DL_UART_MAIN_INTERRUPT_FRAMING_ERROR | DL_UART_MAIN_INTERRUPT_NOISE_ERROR | DL_UART_MAIN_INTERRUPT_OVERRUN_ERROR | DL_UART_MAIN_INTERRUPT_PARITY_ERROR | DL_UART_MAIN_INTERRUPT_RX | DL_UART_MAIN_INTERRUPT_RX_TIMEOUT_ERROR); DL_UART_Main_enableFIFOs(UART1); DL_UART_Main_setRXFIFOThreshold(UART1, DL_UART_RX_FIFO_LEVEL_ONE_ENTRY); DL_UART_Main_setTXFIFOThreshold(UART1, DL_UART_TX_FIFO_LEVEL_1_2_EMPTY); DL_UART_Main_enable(pxUartInstance); NVIC_ClearPendingIRQ(UART1_INT_IRQn); NVIC_EnableIRQ(UART1_INT_IRQn); } else if (pxUartInstance == UART2) { DL_UART_Main_enableInterrupt(pxUartInstance, DL_UART_MAIN_INTERRUPT_BREAK_ERROR | DL_UART_MAIN_INTERRUPT_FRAMING_ERROR | DL_UART_MAIN_INTERRUPT_NOISE_ERROR | DL_UART_MAIN_INTERRUPT_OVERRUN_ERROR | DL_UART_MAIN_INTERRUPT_PARITY_ERROR | DL_UART_MAIN_INTERRUPT_RX | DL_UART_MAIN_INTERRUPT_RX_TIMEOUT_ERROR); DL_UART_Main_enableFIFOs(UART2); DL_UART_Main_setRXFIFOThreshold(UART2, DL_UART_RX_FIFO_LEVEL_ONE_ENTRY); DL_UART_Main_setTXFIFOThreshold(UART2, DL_UART_TX_FIFO_LEVEL_1_2_EMPTY); DL_UART_Main_enable(pxUartInstance); NVIC_ClearPendingIRQ(UART2_INT_IRQn); NVIC_EnableIRQ(UART2_INT_IRQn); } return commonMCAL_SUCCESS; } /** * @brief UART receive callback function for notifying when data is received. * * This function is called when data is received on the specified UART port. It logs the * event type and calls the appropriate user-defined callback function if registered. * The callback is invoked with the event type, a NULL pointer for data (as no data is * passed here), and the size of the received data. * * @param [in] ind_type The type of interrupt or event that occurred (e.g., data received). * @param [in] port The UART port number on which the receive event occurred. * @param [in] size The size of the data that was received on the UART port. */ #if 0 static void __prvMCAL_UartNotifyRecvCb(uint32 ind_type, ql_uart_port_number_e port, uint32 size) { IVEC_MCAL_LOG(LOG_STRING, "Uart Recv Callback:%d", ind_type); for (int i = 0;i < IVEC_MCAL_UART_MAX_PORT; i++) { if (g_pxUartHandles[i] != NULL && port == (ql_uart_port_number_e)g_pxUartHandles[i]->eUartPortNumber) { if (g_pxUartHandles[i]->pvUartRecvCallback != NULL) g_pxUartHandles[i]->pvUartRecvCallback((IVEC_McalUartEvents_e)ind_type & 0xffff, NULL, size); break; } } } #endif /** * @brief Registers a UART handle for a specified UART port. * * This function stores the given UART handle in the UART handles (`gpIVEC_McalUartHandle_ss`) * at the index corresponding to the specified UART port number. It ensures that the handle can be accessed * later for operations like configuring or handling UART events. * * @param [in] pxUartHandle Pointer to the UART handle to be registered. The handle should contain * valid configuration and state information for the corresponding UART port. */ static void prvMCAL_UartRegisterHandle(IVEC_McalUartHandle_s* pxUartHandle) { __gprv_pIVEC_McalUartHandle_ss[pxUartHandle->eUartPortNumber] = pxUartHandle; } /** * @brief Initializes the UART peripheral based on the provided configuration. * * This function initializes the UART instance by registering the handle, * configuring the UART instance with the settings specified in the * `IVEC_McalUartHandle_s`, and setting the UART's baud rate. If the provided handle * is invalid or if initialization fails, an appropriate error code is returned. * * @param [in] pxUartHandle Pointer to the UART handle, containing the port number and configuration * (such as baud rate, data bits, stop bits, etc.) for the UART instance. * * @return IVEC_McalCommonErr_e Returns the status of the UART initialization: * - `commonMCAL_SUCCESS` if the initialization is successful. * - `commonMCAL_INVALID_PARAM` if the provided handle is invalid (NULL or incorrect port number). * - `commonMCAL_INIT_FAIL` if initialization of the UART instance fails. */ IVEC_McalCommonErr_e xMCAL_UartInit(IVEC_McalUartHandle_s* pxUartHandle) { IVEC_MCAL_FUNC_ENTRY(LOG_STRING); IVEC_McalCommonErr_e l_xFuncStatus = commonMCAL_SUCCESS; if (pxUartHandle == NULL || pxUartHandle->eUartPortNumber >= IVEC_MCAL_UART_PORT_MAX) { return commonMCAL_INVALID_PARAM; goto exit; } prvMCAL_UartRegisterHandle(pxUartHandle); int l_i32Ret = __prv_McalUartInitInstance(pxUartHandle, pxUartHandle->xUartConfig.eUartBaudrate); if (l_i32Ret != IVEC_CORE_STATUS_SUCCESS) { l_xFuncStatus = commonMCAL_INIT_FAIL; goto exit; } exit: IVEC_MCAL_FUNC_EXIT(LOG_STRING); return l_xFuncStatus; }