refactor: Improve CAN and UART handling, add documentation and checks

- Fixed UART speed inside handle and CAN speed inside handle for runtime configuration.
- Moved CAN filter setup inside the handle for more centralized control.
- Added documentation above functions for better readability.
- Included argument checks at function entry to ensure valid parameters.
- Added runtime checks to prevent memory corruption where values can change dynamically.
- Removed unnecessary `extern` declarations to improve code clarity.
- Fixed `vMCAL_MCAN_Tx()` to return success even if `if (sMcalTxFifoStatus_x.freeLvl)` fails.
- Removed unused functions to clean up the codebase.
- Fixed `xMCAL_VrefInit()` by calling vMCAL_SoftReset.
stable
Rakshita 2025-01-20 15:20:15 +05:30
parent 1c6fff8d24
commit b1fa1129af
11 changed files with 1184 additions and 463 deletions

View File

@ -3,6 +3,7 @@
#include "..\utils\utils.h" #include "..\utils\utils.h"
#include "ti_msp_dl_config.h" #include "ti_msp_dl_config.h"
#define ivMCAL_MAX_FILTERS 10
/* Enum for CAN ID Types */ /* Enum for CAN ID Types */
typedef enum { typedef enum {
@ -11,30 +12,47 @@ typedef enum {
IVEC_MCAL_CAN_ID_ERROR = 0x02 /* Error ID */ IVEC_MCAL_CAN_ID_ERROR = 0x02 /* Error ID */
} xMCAL_CanIdType_e; } xMCAL_CanIdType_e;
/* CAN Baud Rate Options */
typedef enum
{
IVEC_CAN_BAUD_500 = 500,
IVEC_CAN_BAUD_250 = 250,
IVEC_CAN_BAUD_150 = 150,
IVEC_CAN_BAUD_1000 = 1000,
IVEC_CAN_BAUD_125 = 125,
}xMCAL_CanBaud_e;
typedef struct
{
MCAN_Regs *pMCAN;
uint8_t __u8Init;
xMCAL_CanBaud_e u16Speed;
int32_t i32MaskCount;
int32_t i32FilterCount;
uint32_t u32MaskValues[ivMCAL_MAX_FILTERS];
uint32_t u32FilterValues[ivMCAL_MAX_FILTERS];
} xMcalCanHandle;
/* Function Prototypes for MCAN MCAL Layer */ /* Function Prototypes for MCAN MCAL Layer */
/* Initialize the MCAN module */ /* Initialize the MCAN module */
IVEC_McalStatus_e vMCAL_MCAN_Init(MCAN_Regs* pMCAN, IVEC_CanBaud_e eBaudRate); IVEC_McalStatus_e xMCAL_MCANInit(xMcalCanHandle* pxCanHandle);
/* Deinitialize the MCAN module */ /* Deinitialize the MCAN module */
IVEC_McalStatus_e vMCAL_MCAN_DeInit(MCAN_Regs* const pMCAN); IVEC_McalStatus_e xMCAL_MCANDeInit(xMcalCanHandle* pxCanHandle);
/* Transmit data via MCAN */ /* Transmit data via MCAN */
IVEC_McalStatus_e vMCAL_MCAN_Tx(MCAN_Regs* const pMCAN, uint32_t u32Id, uint16_t* pu16TxData, uint32_t u32BufNum, uint32_t u32Bytes); IVEC_McalStatus_e xMCAL_MCANTx(xMcalCanHandle* pxCanHandle, uint32_t u32Id, uint16_t* pu16TxData, uint32_t u32BufNum, uint32_t u32Bytes);
/* Transmit data via MCAN in blocking mode */
IVEC_McalStatus_e vMCAL_MCAN_TxBlocking(MCAN_Regs* const pMCAN, uint32_t u32Id, uint16_t* pu16TxData, uint32_t u32BufNum, int iBytes);
/* Receive data via MCAN */ /* Receive data via MCAN */
IVEC_McalStatus_e vMCAL_MCAN_Rx(MCAN_Regs* const pMCAN, uint32_t* pu32Id, uint8_t* pu8RxData, int iDLC); IVEC_McalStatus_e xMCAL_MCANRx(xMcalCanHandle* pxCanHandle, uint32_t* pu32Id, uint8_t* pu8RxData, int iDLC);
/* Get the error status of the MCAN module */ /* Get the error status of the MCAN module */
IVEC_McalStatus_e vMCAL_MCAN_GetErrorStatus(char* pcErrorStatus); IVEC_McalStatus_e xMCAL_MCANGetErrorStatus(xMcalCanHandle* pxCanHandle, char* pcErrorStatus);
/* Get interrupt status of MCAN Interrupt Line 1 */ /* Get interrupt status of MCAN Interrupt Line 1 */
IVEC_McalStatus_e vMCAL_MCAN_GetInterruptLine1Status(uint32_t* pu32InterruptStatus); IVEC_McalStatus_e xMCAL_MCANGetInterruptLine1Status(xMcalCanHandle* pxCanHandle, uint32_t* pu32InterruptStatus);
/* Reset the MCAN module */
IVEC_McalStatus_e vMCAL_MCAN_Reset(MCAN_Regs* const pMCAN, IVEC_CanBaud_e eBaudRate);
#endif /* CORE_INCLUDE_IVEc_MCAL_MCAN_H_ */ #endif /* CORE_INCLUDE_IVEc_MCAL_MCAN_H_ */

View File

@ -99,6 +99,5 @@ IVEC_McalCommonErr_e xMCAL_UartInit(xMcalUartHandle* pxUartHandle);
IVEC_McalCommonErr_e xMCAL_UartDeInit(xMcalUartHandle* pxUartHandle); IVEC_McalCommonErr_e xMCAL_UartDeInit(xMcalUartHandle* pxUartHandle);
IVEC_McalCommonErr_e xMCAL_UartRead(xMcalUartHandle* pxUartHandle, uint8_t* pu8Data, uint32_t u32DataLength); IVEC_McalCommonErr_e xMCAL_UartRead(xMcalUartHandle* pxUartHandle, uint8_t* pu8Data, uint32_t u32DataLength);
IVEC_McalCommonErr_e xMCAL_UartWrite(xMcalUartHandle* pxUartHandle, uint8_t* pu8Data, uint32_t u32DataLength); IVEC_McalCommonErr_e xMCAL_UartWrite(xMcalUartHandle* pxUartHandle, uint8_t* pu8Data, uint32_t u32DataLength);
IVEC_McalCommonErr_e _prvMCAL_UartPinInit(xMcalUartHandle* pxUartHandle);
#endif /* CORE_INCLUDE_IVEC_MCAL_UART_H_ */ #endif /* CORE_INCLUDE_IVEC_MCAL_UART_H_ */

View File

@ -11,19 +11,13 @@
#include <../Core/Include/ivec_mcal_mcan.h> #include <../Core/Include/ivec_mcal_mcan.h>
#include "string.h" #include "string.h"
/* MCAN Initialization Flag */
volatile bool bMCAL_MCAN_InitFlag = false;
/* MCAN Status Flag */ /* MCAN Status Flag */
volatile uint8_t u8MCAL_MCAN_StatusFlag = IVEC_MCAL_STATUS_ERROR; volatile uint8_t u8MCAL_MCAN_StatusFlag = IVEC_MCAL_STATUS_ERROR;
/* Service Interrupt Flag */
volatile bool bMCAL_ServiceInterrupt = true;
/* MCAN Protocol Status Header */ /* MCAN Protocol Status Header */
volatile DL_MCAN_ProtocolStatus xMCAL_HeaderStat; volatile DL_MCAN_ProtocolStatus xMCAL_HeaderStat;
extern IVEC_CanBaud_e g_eCanSpeed; extern xMCAL_CanBaud_e g_eCanSpeed;
/* MCAN Interrupt Line 1 Status */ /* MCAN Interrupt Line 1 Status */
volatile uint32_t u32MCAL_InterruptLine1Status; volatile uint32_t u32MCAL_InterruptLine1Status;
@ -33,15 +27,10 @@ volatile char cMCAL_ErrorInterruptStatus[50];
volatile uint32_t can_interrupt = 0; volatile uint32_t can_interrupt = 0;
#define ivMCAL_MAX_FILTERS 10
extern int32_t g_i32FilterCount;
extern int32_t g_i32MaskCount;
extern uint32_t g_u32MaskValues[ivMCAL_MAX_FILTERS];
extern uint32_t g_u32FilterValues[ivMCAL_MAX_FILTERS];
volatile DL_MCAN_RxBufElement xMCAL_TempRxMsgInFunction; volatile DL_MCAN_RxBufElement xMCAL_TempRxMsgInFunction;
__attribute__((weak)) void vMCU_FDCAN_RxFifo_Callback(uint32_t Identifier, uint8_t *data, uint16_t DataLength) __attribute__((weak)) void vMCU_FDCANRxFifoCallback(uint32_t Identifier, uint8_t *data, uint16_t DataLength)
{ {
} }
@ -193,18 +182,23 @@ volatile DL_MCAN_TxBufElement txMsg = {
/*============================================================================================================================================================================================= /*=============================================================================================================================================================================================
PRIVATE_DECLARATIONS PRIVATE_DECLARATIONS
==============================================================================================================================================================================================*/ ==============================================================================================================================================================================================*/
/** /**
* @brief Static Function to store RX data in a static buffer * @brief Processes CAN interrupt events.
* @retval void *
* Handles CAN RX FIFO events, reads messages from the RX FIFO, and invokes a callback
* for each received message. It also processes error conditions and manages the interrupt status.
*
* @param[in] u32InterruptStatus The interrupt status indicating which event triggered the interrupt.
*
* @details
* - If the interrupt is related to RX FIFO events (RF0F, RF0N, RF1F, RF1N):
* - Retrieves the FIFO status and reads messages from the corresponding RX FIFO.
* - Acknowledges the read message and processes the message ID and data payload.
* - Calls `vMCAL_CanReceiveFifoCallback` with the received message.
* - If the interrupt is related to errors (e.g., timeout, bus off, protocol errors):
* - The interrupt status is saved for further processing (currently no action is taken for errors).
*/ */
static void _prv_vMCAL_MCAN_StoreRxData(const DL_MCAN_RxBufElement* pRxMsg, uint32_t* pu32Id, uint8_t* pu8RxData, int iDLC)
{
/* Extract data from the RX message into the buffer */
for (int i = 0; i < iDLC; i++) {
pu8RxData[i] = (pRxMsg->data[i] & 0xFF);
}
}
void __prv_CANInterruptProcess(uint32_t u32InterruptStatus) void __prv_CANInterruptProcess(uint32_t u32InterruptStatus)
{ {
@ -236,7 +230,7 @@ void __prv_CANInterruptProcess(uint32_t u32InterruptStatus)
au8DataArr[i] = xMCAL_TempRxMsg.data[i] & 0xFF; au8DataArr[i] = xMCAL_TempRxMsg.data[i] & 0xFF;
} }
vMCAL_CanReceiveFifoCallback(xMCAL_TempRxMsg.id, &xMCAL_TempRxMsg.data[0], xMCAL_TempRxMsg.dlc); vMCAL_CanReceiveFifoCallback(xMCAL_TempRxMsg.id, &au8DataArr[0], xMCAL_TempRxMsg.dlc);
DL_MCAN_getRxFIFOStatus(CANFD0, &xMCAL_RxFIFOStatus); DL_MCAN_getRxFIFOStatus(CANFD0, &xMCAL_RxFIFOStatus);
} }
} }
@ -245,75 +239,6 @@ void __prv_CANInterruptProcess(uint32_t u32InterruptStatus)
} }
} }
//void vMCAL_MCAN_InterruptProcess(uint32_t u32InterruptStatus)
//{
// uint32_t u32IntrStatus = u32InterruptStatus;
//
//// /* Retrieve protocol status */
//// DL_MCAN_getProtocolStatus(CANFD0, &xMCAL_HeaderStat);
////
//// /* Handle Transmission Complete Interrupt */
//// if (u32IntrStatus & DL_MCAN_INTERRUPT_TC) {
//// bMCAL_ServiceInterrupt = true;
//// u8MCAL_MCAN_StatusFlag = IVEC_MCAL_STATUS_SUCCESS;
//// }
////
//// /* Handle Bus Off Interrupt */
//// if (u32IntrStatus & DL_MCAN_INTERRUPT_BO) {
//// DL_MCAN_setOpMode(CANFD0, DL_MCAN_OPERATION_MODE_NORMAL);
//// }
//
// /* Handle Receive FIFO New Message Interrupt */
// if (u32IntrStatus & (DL_MCAN_INTERRUPT_RF0N | DL_MCAN_INTERRUPT_RF1N)) {
// while (!bMCAL_ServiceInterrupt);
//
// bMCAL_ServiceInterrupt = false;
//
// /* MCAN RX FIFO Status */
// volatile DL_MCAN_RxFIFOStatus xMCAL_RxFIFOStatus;
//
// /* Determine which FIFO triggered the interrupt */
// xMCAL_RxFIFOStatus.fillLvl = 0;
// xMCAL_RxFIFOStatus.num = (u32IntrStatus & DL_MCAN_INTERRUPT_RF0N)
// ? DL_MCAN_RX_FIFO_NUM_0
// : DL_MCAN_RX_FIFO_NUM_1;
//
// /* Wait until the FIFO has data */
// while (xMCAL_RxFIFOStatus.fillLvl == 0) {
// DL_MCAN_getRxFIFOStatus(CANFD0, &xMCAL_RxFIFOStatus);
// }
//
// /* Read the message from the FIFO */
// DL_MCAN_readMsgRam(CANFD0, DL_MCAN_MEM_TYPE_FIFO, 0,
// xMCAL_RxFIFOStatus.num, &xMCAL_TempRxMsg);
//
// /* Acknowledge the message */
// DL_MCAN_writeRxFIFOAck(CANFD0, xMCAL_RxFIFOStatus.num,
// xMCAL_RxFIFOStatus.getIdx);
//
// bMCAL_ServiceInterrupt = true;
//
// /* Handle Bus Off Recovery */
// if (xMCAL_HeaderStat.busOffStatus == 1) {
// DL_MCAN_setOpMode(CANFD0, DL_MCAN_OPERATION_MODE_NORMAL);
// }
//
// /* Process Standard or Extended ID */
// if (!xMCAL_TempRxMsg.xtd) {
// xMCAL_TempRxMsg.id = (uint32_t)(xMCAL_TempRxMsg.id >> 18);
// }
//
// /* Extract data payload */
// uint8_t au8DataArr[8] = {0};
// for (int i = 0; i < 8; i++) {
// au8DataArr[i] = xMCAL_TempRxMsg.data[i] & 0xFF;
// }
//
// /* Call the RX FIFO callback function */
// vMCU_FDCAN_RxFifo_Callback(xMCAL_TempRxMsg.id, au8DataArr, xMCAL_TempRxMsg.dlc);
// }
//}
/** /**
* @brief Default Interrupt Handler for MCAN * @brief Default Interrupt Handler for MCAN
* *
@ -364,49 +289,63 @@ void CANFD0_IRQHandler(void)
==============================================================================================================================================================================================*/ ==============================================================================================================================================================================================*/
/** /**
* @brief Function to initialize MCAN Peripheral * @brief Initializes the MCAN module with specified configurations.
* @note Interrupts are enabled in this function itself *
* @param MCAN Pointer to the register overlay for the peripheral * This function configures the MCAN module with the following:
* @param BAUD Param to set Baud rate of MCAN * - Enables the module clock and sets the clock configuration.
* @retval IVEC_McalStatus_e * - Initializes the MCAN in software initialization mode and waits for completion.
* - Configures bit timings and message RAM.
* - Sets up the filter configurations for both extended and standard IDs based on the provided filter values and masks.
* - Enables necessary interrupts for CAN operation and sets interrupt priorities.
*
* @param[in] pxCanHandle Pointer to the CAN handle structure containing the configuration parameters.
*
* @return IVEC_MCAL_STATUS_SUCCESS if the initialization is successful, or an error status if failed.
*
* @details
* The function performs the following steps:
* 1. Validates the CAN instance and speed.
* 2. Initializes the MCAN module by enabling the module clock, configuring the clock, and setting the operation mode to software initialization.
* 3. Waits for memory initialization to complete, then sets the MCAN operation mode to normal.
* 4. Configures the MCAN module parameters, including bit timings and message RAM.
* 5. Sets up CAN filters for extended and standard IDs based on the provided filter and mask values.
* 6. Enables CAN interrupts and configures interrupt lines for CAN events.
* 7. Clears and enables interrupts in the NVIC for the CAN module.
*/ */
IVEC_McalStatus_e vMCAL_MCAN_Init(MCAN_Regs* pMCAN, IVEC_CanBaud_e eBaudRate) IVEC_McalStatus_e xMCAL_MCANInit(xMcalCanHandle* pxCanHandle)
{ {
assert(pMCAN == CANFD0); assert(pxCanHandle->pMCAN == CANFD0);
assert(eBaudRate == IVEC_CAN_BAUD_500 || eBaudRate == IVEC_CAN_BAUD_250); assert(pxCanHandle->u16Speed == IVEC_CAN_BAUD_500 || pxCanHandle->u16Speed == IVEC_CAN_BAUD_250);
assert(bMCAL_MCAN_InitFlag == 0);
// g_xEcuCanHandle.__xCanHandle.u16Speed = eMcalUartBaud115200;
DL_MCAN_RevisionId revid_MCAN0; DL_MCAN_RevisionId revid_MCAN0;
DL_MCAN_enableModuleClock(pMCAN); DL_MCAN_enableModuleClock(pxCanHandle->pMCAN);
DL_MCAN_setClockConfig(pMCAN, (DL_MCAN_ClockConfig *) &gMCAN0ClockConf); DL_MCAN_setClockConfig(pxCanHandle->pMCAN, (DL_MCAN_ClockConfig *) &gMCAN0ClockConf);
/* Get MCANSS Revision ID. */ /* Get MCANSS Revision ID. */
DL_MCAN_getRevisionId(pMCAN, &revid_MCAN0); DL_MCAN_getRevisionId(pxCanHandle->pMCAN, &revid_MCAN0);
/* Wait for Memory initialization to be completed. */ /* Wait for Memory initialization to be completed. */
while (false == DL_MCAN_isMemInitDone(pMCAN)); while (false == DL_MCAN_isMemInitDone(pxCanHandle->pMCAN));
/* Put MCAN in SW initialization mode. */ /* Put MCAN in SW initialization mode. */
DL_MCAN_setOpMode(pMCAN, DL_MCAN_OPERATION_MODE_SW_INIT); DL_MCAN_setOpMode(pxCanHandle->pMCAN, DL_MCAN_OPERATION_MODE_SW_INIT);
/* Wait till MCAN is not initialized. */ /* Wait till MCAN is not initialized. */
while (DL_MCAN_OPERATION_MODE_SW_INIT != DL_MCAN_getOpMode(pMCAN)); while (DL_MCAN_OPERATION_MODE_SW_INIT != DL_MCAN_getOpMode(pxCanHandle->pMCAN));
/* Initialize MCAN module. */ /* Initialize MCAN module. */
DL_MCAN_init(pMCAN, (DL_MCAN_InitParams*)&gMCAN0InitParams); DL_MCAN_init(pxCanHandle->pMCAN, (DL_MCAN_InitParams*)&gMCAN0InitParams);
gMCAN0ConfigParams.filterConfig.anfe = 0; gMCAN0ConfigParams.filterConfig.anfe = 0;
gMCAN0ConfigParams.filterConfig.anfs = 0; gMCAN0ConfigParams.filterConfig.anfs = 0;
// g_u32FilterValues[0]=1312;
// g_u32MaskValues[0]=2047;
// g_i32MaskCount=0;
// g_i32FilterCount=0;
for (int u32Index = 0; u32Index <= g_i32MaskCount; u32Index++) { for (int u32Index = 0; u32Index <= pxCanHandle->i32MaskCount; u32Index++) {
if ((g_u32FilterValues[u32Index] > 0x7FF) || (g_u32MaskValues[u32Index] > 0x7FF)) { if ((pxCanHandle->u32FilterValues[u32Index] > 0x7FF) || (pxCanHandle->u32MaskValues[u32Index] > 0x7FF)) {
gMCAN0ConfigParams.filterConfig.anfe = 3; gMCAN0ConfigParams.filterConfig.anfe = 3;
} }
else else
@ -415,62 +354,62 @@ IVEC_McalStatus_e vMCAL_MCAN_Init(MCAN_Regs* pMCAN, IVEC_CanBaud_e eBaudRate)
} }
} }
/* Configure MCAN module. */ /* Configure MCAN module. */
DL_MCAN_config(pMCAN, (DL_MCAN_ConfigParams*)&gMCAN0ConfigParams); DL_MCAN_config(pxCanHandle->pMCAN, (DL_MCAN_ConfigParams*)&gMCAN0ConfigParams);
/* Configure Bit timings. */ /* Configure Bit timings. */
if (eBaudRate == IVEC_CAN_BAUD_500) if (pxCanHandle->u16Speed == IVEC_CAN_BAUD_500)
{ {
DL_MCAN_setBitTime(pMCAN, (DL_MCAN_BitTimingParams*)&gMCAN0BitTimes_500); DL_MCAN_setBitTime(pxCanHandle->pMCAN, (DL_MCAN_BitTimingParams*)&gMCAN0BitTimes_500);
} }
else if (eBaudRate == IVEC_CAN_BAUD_250) else if (pxCanHandle->u16Speed == IVEC_CAN_BAUD_250)
{ {
DL_MCAN_setBitTime(pMCAN, (DL_MCAN_BitTimingParams*)&gMCAN0BitTimes_250); DL_MCAN_setBitTime(pxCanHandle->pMCAN, (DL_MCAN_BitTimingParams*)&gMCAN0BitTimes_250);
} }
else else
{ {
DL_MCAN_setBitTime(pMCAN, (DL_MCAN_BitTimingParams*)&gMCAN0BitTimes_500); DL_MCAN_setBitTime(pxCanHandle->pMCAN, (DL_MCAN_BitTimingParams*)&gMCAN0BitTimes_500);
} }
/* Configure Message RAM Sections */ /* Configure Message RAM Sections */
DL_MCAN_msgRAMConfig(pMCAN, (DL_MCAN_MsgRAMConfigParams*)&gMCAN0MsgRAMConfigParams); DL_MCAN_msgRAMConfig(pxCanHandle->pMCAN, (DL_MCAN_MsgRAMConfigParams*)&gMCAN0MsgRAMConfigParams);
uint8_t l_u8ExtendedFilterCount = 0; uint8_t l_u8ExtendedFilterCount = 0;
uint8_t l_u8StandardFilterCount = 0; uint8_t l_u8StandardFilterCount = 0;
for (int u32Index = 0; u32Index <= g_i32MaskCount; u32Index++) { for (int u32Index = 0; u32Index <= pxCanHandle->i32MaskCount; u32Index++) {
if ((g_u32FilterValues[u32Index] > 0x7FF) || (g_u32MaskValues[u32Index] > 0x7FF)) { if ((pxCanHandle->u32FilterValues[u32Index] > 0x7FF) || (pxCanHandle->u32MaskValues[u32Index] > 0x7FF)) {
// Extended ID filter // Extended ID filter
DL_MCAN_ExtMsgIDFilterElement extFilterElement; DL_MCAN_ExtMsgIDFilterElement extFilterElement;
extFilterElement.efid1 = g_u32FilterValues[u32Index]; extFilterElement.efid1 = pxCanHandle->u32FilterValues[u32Index];
extFilterElement.efid2 = g_u32MaskValues[u32Index]; extFilterElement.efid2 = pxCanHandle->u32MaskValues[u32Index];
extFilterElement.efec = 001; extFilterElement.efec = 001;
extFilterElement.eft = 2; extFilterElement.eft = 2;
DL_MCAN_addExtMsgIDFilter(pMCAN, l_u8ExtendedFilterCount, (DL_MCAN_StdMsgIDFilterElement*)&extFilterElement); DL_MCAN_addExtMsgIDFilter(pxCanHandle->pMCAN, l_u8ExtendedFilterCount, (DL_MCAN_StdMsgIDFilterElement*)&extFilterElement);
l_u8ExtendedFilterCount++; l_u8ExtendedFilterCount++;
} }
else { else {
// Standard ID filter // Standard ID filter
DL_MCAN_StdMsgIDFilterElement stdFilterElement; DL_MCAN_StdMsgIDFilterElement stdFilterElement;
stdFilterElement.sfid1 = g_u32FilterValues[u32Index]; stdFilterElement.sfid1 = pxCanHandle->u32FilterValues[u32Index];
stdFilterElement.sfid2 = g_u32MaskValues[u32Index]; stdFilterElement.sfid2 = pxCanHandle->u32MaskValues[u32Index];
stdFilterElement.sfec = 001; stdFilterElement.sfec = 001;
stdFilterElement.sft = 2; stdFilterElement.sft = 2;
DL_MCAN_addStdMsgIDFilter(pMCAN, l_u8StandardFilterCount, (DL_MCAN_StdMsgIDFilterElement*)&stdFilterElement); DL_MCAN_addStdMsgIDFilter(pxCanHandle->pMCAN, l_u8StandardFilterCount, (DL_MCAN_StdMsgIDFilterElement*)&stdFilterElement);
l_u8StandardFilterCount++; l_u8StandardFilterCount++;
} }
} }
DL_MCAN_setExtIDAndMask(pMCAN, (0x1FFFFFFFU)); DL_MCAN_setExtIDAndMask(pxCanHandle->pMCAN, (0x1FFFFFFFU));
/* Take MCAN out of the SW initialization mode */ /* Take MCAN out of the SW initialization mode */
DL_MCAN_setOpMode(pMCAN, DL_MCAN_OPERATION_MODE_NORMAL); DL_MCAN_setOpMode(pxCanHandle->pMCAN, DL_MCAN_OPERATION_MODE_NORMAL);
while (DL_MCAN_OPERATION_MODE_NORMAL != DL_MCAN_getOpMode(pMCAN)); while (DL_MCAN_OPERATION_MODE_NORMAL != DL_MCAN_getOpMode(pxCanHandle->pMCAN));
/* Enable MCAN mopdule Interrupts */ /* Enable MCAN mopdule Interrupts */
DL_MCAN_enableIntr(pMCAN, (MCAN_IR_RF0N_MASK | \ DL_MCAN_enableIntr(pxCanHandle->pMCAN, (MCAN_IR_RF0N_MASK | \
MCAN_IR_RF0F_MASK | \ MCAN_IR_RF0F_MASK | \
MCAN_IR_RF1N_MASK | \ MCAN_IR_RF1N_MASK | \
MCAN_IR_RF1F_MASK | \ MCAN_IR_RF1F_MASK | \
@ -487,17 +426,17 @@ IVEC_McalStatus_e vMCAL_MCAN_Init(MCAN_Regs* pMCAN, IVEC_CanBaud_e eBaudRate)
MCAN_IR_ARA_MASK), 1); MCAN_IR_ARA_MASK), 1);
DL_MCAN_selectIntrLine(pMCAN, DL_MCAN_INTR_MASK_ALL, DL_MCAN_INTR_LINE_NUM_0); DL_MCAN_selectIntrLine(pxCanHandle->pMCAN, DL_MCAN_INTR_MASK_ALL, DL_MCAN_INTR_LINE_NUM_0);
DL_MCAN_enableIntrLine(pMCAN, DL_MCAN_INTR_LINE_NUM_0, 1U); DL_MCAN_enableIntrLine(pxCanHandle->pMCAN, DL_MCAN_INTR_LINE_NUM_0, 1U);
/* Enable MSPM0 MCAN interrupt */ /* Enable MSPM0 MCAN interrupt */
DL_MCAN_clearInterruptStatus(pMCAN, (DL_MCAN_MSP_INTERRUPT_LINE0)); DL_MCAN_clearInterruptStatus(pxCanHandle->pMCAN, (DL_MCAN_MSP_INTERRUPT_LINE0));
DL_MCAN_enableInterrupt(pMCAN, (DL_MCAN_MSP_INTERRUPT_LINE0)); DL_MCAN_enableInterrupt(pxCanHandle->pMCAN, (DL_MCAN_MSP_INTERRUPT_LINE0));
NVIC_SetPriority(CANFD0_INT_IRQn, 1); NVIC_SetPriority(CANFD0_INT_IRQn, 1);
NVIC_ClearPendingIRQ(CANFD0_INT_IRQn); NVIC_ClearPendingIRQ(CANFD0_INT_IRQn);
NVIC_EnableIRQ(CANFD0_INT_IRQn); NVIC_EnableIRQ(CANFD0_INT_IRQn);
bMCAL_MCAN_InitFlag = 1; pxCanHandle->__u8Init = 1;
return IVEC_MCAL_STATUS_SUCCESS; return IVEC_MCAL_STATUS_SUCCESS;
} }
@ -509,23 +448,23 @@ IVEC_McalStatus_e vMCAL_MCAN_Init(MCAN_Regs* pMCAN, IVEC_CanBaud_e eBaudRate)
* @retval IVEC MCAL status * @retval IVEC MCAL status
*/ */
IVEC_McalStatus_e vMCAL_MCAN_DeInit(MCAN_Regs* const pMCAN) IVEC_McalStatus_e xMCAL_MCANDeInit(xMcalCanHandle* pxCanHandle)
{ {
/* Assert that the MCAN module pointer is valid */ /* Assert that the MCAN module pointer is valid */
assert(pMCAN == CANFD0); assert(pxCanHandle->pMCAN == CANFD0);
assert(bMCAL_MCAN_InitFlag != 0); /* Ensure the module was initialized before deinitializing. */ assert(pxCanHandle->__u8Init != 0); /* Ensure the module was initialized before deinitializing. */
/* Reset the CAN module to initialization mode */ /* Reset the CAN module to initialization mode */
DL_MCAN_setOpMode(pMCAN, DL_MCAN_OPERATION_MODE_SW_INIT); DL_MCAN_setOpMode(pxCanHandle->pMCAN, DL_MCAN_OPERATION_MODE_SW_INIT);
/* Wait until the operation mode is set to initialization mode */ /* Wait until the operation mode is set to initialization mode */
while (DL_MCAN_OPERATION_MODE_SW_INIT != DL_MCAN_getOpMode(pMCAN)); while (DL_MCAN_OPERATION_MODE_SW_INIT != DL_MCAN_getOpMode(pxCanHandle->pMCAN));
/* Disable the CAN interrupt */ /* Disable the CAN interrupt */
NVIC_DisableIRQ(CANFD0_INT_IRQn); NVIC_DisableIRQ(CANFD0_INT_IRQn);
/* Disable interrupts on CAN module */ /* Disable interrupts on CAN module */
DL_MCAN_enableIntr(pMCAN, (DL_MCAN_INTERRUPT_BEU | \ DL_MCAN_enableIntr(pxCanHandle->pMCAN, (DL_MCAN_INTERRUPT_BEU | \
DL_MCAN_INTERRUPT_BO | \ DL_MCAN_INTERRUPT_BO | \
DL_MCAN_INTERRUPT_ELO | \ DL_MCAN_INTERRUPT_ELO | \
DL_MCAN_INTERRUPT_EP | \ DL_MCAN_INTERRUPT_EP | \
@ -538,29 +477,29 @@ IVEC_McalStatus_e vMCAL_MCAN_DeInit(MCAN_Regs* const pMCAN)
DL_MCAN_INTERRUPT_TOO), false); DL_MCAN_INTERRUPT_TOO), false);
/* Disable interrupt lines */ /* Disable interrupt lines */
DL_MCAN_enableIntrLine(pMCAN, DL_MCAN_INTR_LINE_NUM_0, false); DL_MCAN_enableIntrLine(pxCanHandle->pMCAN, DL_MCAN_INTR_LINE_NUM_0, false);
DL_MCAN_enableIntrLine(pMCAN, DL_MCAN_INTR_LINE_NUM_1, false); DL_MCAN_enableIntrLine(pxCanHandle->pMCAN, DL_MCAN_INTR_LINE_NUM_1, false);
/* Clear interrupt statuses for lines 0 and 1 */ /* Clear interrupt statuses for lines 0 and 1 */
DL_MCAN_clearInterruptStatus(pMCAN, DL_MCAN_MSP_INTERRUPT_LINE0); DL_MCAN_clearInterruptStatus(pxCanHandle->pMCAN, DL_MCAN_MSP_INTERRUPT_LINE0);
DL_MCAN_disableInterrupt(pMCAN, DL_MCAN_MSP_INTERRUPT_LINE0); DL_MCAN_disableInterrupt(pxCanHandle->pMCAN, DL_MCAN_MSP_INTERRUPT_LINE0);
DL_MCAN_clearInterruptStatus(pMCAN, DL_MCAN_MSP_INTERRUPT_LINE1); DL_MCAN_clearInterruptStatus(pxCanHandle->pMCAN, DL_MCAN_MSP_INTERRUPT_LINE1);
DL_MCAN_disableInterrupt(pMCAN, DL_MCAN_MSP_INTERRUPT_LINE1); DL_MCAN_disableInterrupt(pxCanHandle->pMCAN, DL_MCAN_MSP_INTERRUPT_LINE1);
/* Set the operation mode back to normal */ /* Set the operation mode back to normal */
DL_MCAN_setOpMode(pMCAN, DL_MCAN_OPERATION_MODE_NORMAL); DL_MCAN_setOpMode(pxCanHandle->pMCAN, DL_MCAN_OPERATION_MODE_NORMAL);
/* Reset the initialization flag */ /* Reset the initialization flag */
bMCAL_MCAN_InitFlag = 0; pxCanHandle->__u8Init = 0;
/* Disable the CAN module's GPIO peripheral function */ /* Disable the CAN module's GPIO peripheral function */
DL_GPIO_initPeripheralOutputFunction(IOMUX_PINCM59, 0); DL_GPIO_initPeripheralOutputFunction(IOMUX_PINCM59, 0);
DL_GPIO_initPeripheralInputFunction(IOMUX_PINCM60, 0); DL_GPIO_initPeripheralInputFunction(IOMUX_PINCM60, 0);
/* Disable the module clock and power */ /* Disable the module clock and power */
DL_MCAN_disableModuleClock(pMCAN); DL_MCAN_disableModuleClock(pxCanHandle->pMCAN);
DL_MCAN_disablePower(pMCAN); DL_MCAN_disablePower(pxCanHandle->pMCAN);
/* Wait for power down to complete */ /* Wait for power down to complete */
delay_cycles(16); delay_cycles(16);
@ -569,23 +508,41 @@ IVEC_McalStatus_e vMCAL_MCAN_DeInit(MCAN_Regs* const pMCAN)
} }
/** /**
* @brief Function to Transmit CAN message * @brief Deinitializes the MCAN module and disables associated resources.
* @param MCAN Pointer to the register overlay for the peripheral *
* @param ID Message ID for TxMsg Object. * This function performs the necessary steps to safely deinitialize the MCAN module, including:
* @param TxData Array of Data to be transmitted * - Resetting the MCAN to initialization mode.
* @param BufNum Tx Buffer Number * - Disabling CAN interrupts and interrupt lines.
* @param Bytes Number of bytes to be transmitted * - Clearing interrupt statuses.
* @retval IVEC_McalStatus_e * - Setting the MCAN operation mode back to normal.
* - Disabling the CAN module clock and powering down the module.
* - Disabling the GPIO peripheral functions for CAN.
*
* @param[in] pxCanHandle Pointer to the CAN handle structure containing the configuration parameters.
*
* @return IVEC_MCAL_STATUS_SUCCESS if the deinitialization is successful, or an error status if failed.
*
* @details
* The function performs the following steps:
* 1. Validates the CAN module pointer and checks if the module was initialized.
* 2. Resets the CAN module to the software initialization mode and waits for completion.
* 3. Disables interrupts for the CAN module and the interrupt lines associated with CAN events.
* 4. Clears interrupt statuses for both interrupt lines and disables the interrupts in the NVIC.
* 5. Sets the CAN operation mode back to normal.
* 6. Resets the initialization flag and disables the GPIO peripheral functions for CAN pins.
* 7. Disables the CAN module's clock and power, waiting for the power down process to complete.
*/ */
IVEC_McalStatus_e vMCAL_MCAN_Tx(MCAN_Regs* const pMCAN, uint32_t u32Id,
IVEC_McalStatus_e xMCAL_MCANTx(xMcalCanHandle* pxCanHandle, uint32_t u32Id,
uint16_t* pu16TxData, uint32_t u32BufNum, uint16_t* pu16TxData, uint32_t u32BufNum,
uint32_t u32Bytes) uint32_t u32Bytes)
{ {
/* Ensure that the MCAN instance is CANFD0 */ /* Ensure that the MCAN instance is CANFD0 */
assert(pMCAN == CANFD0); assert(pxCanHandle->pMCAN == CANFD0);
assert(pxCanHandle->u16Speed == IVEC_CAN_BAUD_500 || pxCanHandle->u16Speed == IVEC_CAN_BAUD_250);
/* Ensure that the MCAN is initialized */ /* Ensure that the MCAN is initialized */
assert(bMCAL_MCAN_InitFlag != 0); assert(pxCanHandle->__u8Init != 0);
/* Validate the byte size */ /* Validate the byte size */
assert(u32Bytes <= 8); assert(u32Bytes <= 8);
@ -613,70 +570,70 @@ IVEC_McalStatus_e vMCAL_MCAN_Tx(MCAN_Regs* const pMCAN, uint32_t u32Id,
volatile DL_MCAN_TxFIFOStatus sMcalTxFifoStatus_x = { 0 }; // Structure variable prefixed with 's' for structure type and 'x' for typedef suffix volatile DL_MCAN_TxFIFOStatus sMcalTxFifoStatus_x = { 0 }; // Structure variable prefixed with 's' for structure type and 'x' for typedef suffix
DL_MCAN_getTxFIFOQueStatus(pMCAN, &sMcalTxFifoStatus_x); // Function name prefixed with layer (MCAL) and descriptive DL_MCAN_getTxFIFOQueStatus(pxCanHandle->pMCAN, &sMcalTxFifoStatus_x); // Get the FIFO status
if (sMcalTxFifoStatus_x.freeLvl) // Variable renamed for clarity and prefixed with 'u32' for uint32_t if (sMcalTxFifoStatus_x.freeLvl) // Check if there is space in the FIFO
{ {
DL_MCAN_writeMsgRam(pMCAN, DL_MCAN_MEM_TYPE_FIFO, u32BufNum, &txMsg); // Function and variable name updated DL_MCAN_writeMsgRam(pxCanHandle->pMCAN, DL_MCAN_MEM_TYPE_FIFO, u32BufNum, &txMsg); // Function and variable name updated
if (DL_MCAN_TXBufAddReq(pMCAN, sMcalTxFifoStatus_x.putIdx) == IVEC_MCAL_STATUS_ERROR) // Function return type 'x' if (DL_MCAN_TXBufAddReq(pxCanHandle->pMCAN, sMcalTxFifoStatus_x.putIdx) == IVEC_MCAL_STATUS_ERROR) // Function return type 'x'
{ {
return IVEC_MCAL_STATUS_ERROR; return IVEC_MCAL_STATUS_ERROR;
} }
} }
else
{
/* If no space in FIFO, return busy */
return IVEC_MCAL_STATUS_BUSY;
}
bMCAL_ServiceInterrupt = true;
return IVEC_MCAL_STATUS_SUCCESS; return IVEC_MCAL_STATUS_SUCCESS;
} }
/** /**
* @brief Function to Receive CAN message * @brief Receives a message from the CAN bus.
* @param MCAN Pointer to the register overlay for the peripheral *
* @param RxMsg Message Object. * Retrieves the received CAN message, including the message ID and data.
* @param FifoNum Fifo Number to be used * Handles bus-off recovery and copies the received data into the provided buffer.
* @param RxData Array where received data is to be stored *
* @param DLC length of received data * @param[in] pxCanHandle Pointer to the CAN handle.
* @retval IVEC_McalStatus_e * @param[out] pu32ID Pointer to store the received message ID.
* @param[out] pu8RxData Pointer to the buffer to store the received message data.
* @param[in] iDLC The Data Length Code (DLC), specifying the number of bytes in the data field.
*
* @return IVEC_MCAL_STATUS_SUCCESS on successful reception.
*/ */
IVEC_McalStatus_e vMCAL_MCAN_Rx(MCAN_Regs *pMCAN, uint32_t *pu32ID, uint8_t *pu8RxData, int iDLC)
IVEC_McalStatus_e xMCAL_MCANRx(xMcalCanHandle* pxCanHandle, uint32_t *pu32ID, uint8_t *pu8RxData, int iDLC)
{ {
/* Assert that the CAN module is CANFD0 and that the MCAL initialization flag is set */ /* Assert that the CAN module is CANFD0 and that the MCAL initialization flag is set */
assert(pMCAN == CANFD0); assert(pxCanHandle->pMCAN == CANFD0);
assert(bMCAL_MCAN_InitFlag != 0); assert(pxCanHandle->u16Speed == IVEC_CAN_BAUD_500 || pxCanHandle->u16Speed == IVEC_CAN_BAUD_250);
assert(pxCanHandle->__u8Init != 0);
/* If the bus-off status is set, change to normal operation mode */
if (xMCAL_HeaderStat.busOffStatus == 1)
{
DL_MCAN_setOpMode(CANFD0, DL_MCAN_OPERATION_MODE_NORMAL);
}
/* Temporary RX ID */
volatile uint32_t u32MCAL_TempRxID;
/* Store the received ID */ return IVEC_MCAL_STATUS_ERROR;
*pu32ID = u32MCAL_TempRxID;
/* Copy the received message data into the RxData buffer */
for (int i = 0; i < iDLC; i++)
{
pu8RxData[i] = xMCAL_TempRxMsgInFunction.data[i];
}
return IVEC_MCAL_STATUS_SUCCESS;
} }
/** /**
* @brief Function to check current Error Status of MCAN peripheral * @brief Retrieves the error status of the MCAN module.
* @param ErrorStatus Pointer to array where current status will be stored *
* @retval IVEC_McalStatus_e * Copies the current error interrupt status and protocol status into a buffer and returns
* an appropriate status based on error conditions.
*
* @param[in] pxCanHandle Pointer to the CAN handle.
* @param[out] pcErrorStatus Buffer to store the error status string.
*
* @return IVEC_MCAL_STATUS_SUCCESS if no errors, IVEC_MCAL_STATUS_ERROR if errors are detected.
*/ */
IVEC_McalStatus_e vMCAL_MCAN_GetErrorStatus(char *pcErrorStatus)
IVEC_McalStatus_e xMCAL_MCANGetErrorStatus(xMcalCanHandle* pxCanHandle, char *pcErrorStatus)
{ {
/* Assert that the MCAN initialization flag is set */ /* Assert that the MCAN initialization flag is set */
assert(bMCAL_MCAN_InitFlag != 0); assert(pxCanHandle->__u8Init != 0);;
/* Copy the error interrupt status to the provided buffer */ /* Copy the error interrupt status to the provided buffer */
strcpy(pcErrorStatus, cMCAL_ErrorInterruptStatus); strcpy(pcErrorStatus, cMCAL_ErrorInterruptStatus);
@ -695,29 +652,23 @@ IVEC_McalStatus_e vMCAL_MCAN_GetErrorStatus(char *pcErrorStatus)
/** /**
* @brief Function to check Interrupt Line1 Status of MCAN peripheral * @brief Retrieves the status of interrupt line 1 for the MCAN module.
* @param Interrupt_Status Pointer to variable where current status will be stored *
* @retval IVEC_McalStatus_e * Copies the current interrupt status for line 1 into the provided status buffer.
*
* @param[in] pxCanHandle Pointer to the CAN handle.
* @param[out] pu32InterruptStatus Pointer to store the interrupt status.
*
* @return IVEC_MCAL_STATUS_SUCCESS if successful.
*/ */
IVEC_McalStatus_e vMCAL_MCAN_GetInterruptLine1Status(uint32_t *pu32InterruptStatus)
IVEC_McalStatus_e xMCAL_MCANGetInterruptLine1Status(xMcalCanHandle* pxCanHandle, uint32_t *pu32InterruptStatus)
{ {
// Ensure CAN module is initialized (optional assertion, can be uncommented as needed) // Ensure CAN module is initialized (optional assertion, can be uncommented as needed)
// assert(b_MCAN_InitFlag != 0); assert(pxCanHandle->__u8Init != 0);;
*pu32InterruptStatus = u32MCAL_InterruptLine1Status; *pu32InterruptStatus = u32MCAL_InterruptLine1Status;
return IVEC_MCAL_STATUS_SUCCESS; return IVEC_MCAL_STATUS_SUCCESS;
} }
IVEC_McalStatus_e vMCAL_MCAN_Reset(MCAN_Regs* const pMCAN, IVEC_CanBaud_e eBaudRate)
{
// Ensure MCAN is initialized and that the pointer is valid
assert(bMCAL_MCAN_InitFlag != 0);
assert(pMCAN == CANFD0); // Or check for valid CAN register base address
// Reset the MCAN module and re-initialize it
vMCAL_MCAN_DeInit(pMCAN); // De-initialize CAN
vMCAL_MCAN_Init(pMCAN, eBaudRate); // Re-initialize CAN with the provided baud rate
return IVEC_MCAL_STATUS_SUCCESS;
}

View File

@ -18,6 +18,29 @@ static uint32_t prv_u32DataCount = 0; /* Data count for tracking received bytes
/* Static Function Prototypes */ /* Static Function Prototypes */
static eMcalUartPortNumber _prvMCAL_GetUartPort(UART_Regs* pxUartInstance); static eMcalUartPortNumber _prvMCAL_GetUartPort(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 `gpxMcalUartHandles` 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) void vMCAL_UartReadCallback(UART_Regs* pxUartInstance, uint8_t* pu8Buffer, bool bStatus)
{ {
if (bStatus) if (bStatus)
@ -39,6 +62,16 @@ void vMCAL_UartReadCallback(UART_Regs* pxUartInstance, uint8_t* pu8Buffer, bool
} }
} }
} }
/**
* @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) void prv_vRxCallback(UART_Regs* pxUartInstance, uint32_t u32Event)
{ {
@ -107,11 +140,14 @@ void UART2_IRQHandler()
} }
/** /**
* @brief Get the UART instance based on the enum. * @brief Retrieves the UART instance for the specified port number.
* *
* @param eUartPortNumber UART port number enumeration. * Maps a UART port number to its corresponding hardware instance.
* @return UART_Regs* Pointer to the UART registers. *
* @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* _prvMCAL_GetUartInstance(eMcalUartPortNumber eUartPortNumber) static UART_Regs* _prvMCAL_GetUartInstance(eMcalUartPortNumber eUartPortNumber)
{ {
switch (eUartPortNumber) switch (eUartPortNumber)
@ -123,16 +159,20 @@ static UART_Regs* _prvMCAL_GetUartInstance(eMcalUartPortNumber eUartPortNumber)
case eMcalUartPort3: case eMcalUartPort3:
return UART2; return UART2;
default: default:
return NULL; // Invalid UART port return eMcalUartPortMax; // Invalid UART port
} }
} }
/** /**
* @brief Get the UART port based on the instance. * @brief Maps UART instance to a corresponding port number.
* *
* @param pxUartInstance Pointer to the UART registers. * Returns the appropriate `eMcalUartPortNumber` based on the given UART
* @return eMcalUartPortNumber UART port number enumeration. * 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 eMcalUartPortNumber _prvMCAL_GetUartPort(UART_Regs* pxUartInstance) static eMcalUartPortNumber _prvMCAL_GetUartPort(UART_Regs* pxUartInstance)
{ {
switch ((uint32_t)pxUartInstance) switch ((uint32_t)pxUartInstance)
@ -149,11 +189,17 @@ static eMcalUartPortNumber _prvMCAL_GetUartPort(UART_Regs* pxUartInstance)
} }
/** /**
* @brief Private function to deinitialize UART instance. /**
* @brief Deinitializes a UART instance.
* *
* @param pxUartHandle Pointer to \link xMcalUartHandle \endlink. * Disables the specified UART instance, clears interrupt flags, and disables
* @return IVEC_CoreStatus_e Status of the UART deinitialization. * 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_CoreStatus_e _prvMCAL_UartDeInitInstance(xMcalUartHandle* pxUartHandle) static IVEC_CoreStatus_e _prvMCAL_UartDeInitInstance(xMcalUartHandle* pxUartHandle)
{ {
// Get the UART instance based on the port number in the handle // Get the UART instance based on the port number in the handle
@ -205,13 +251,25 @@ static IVEC_CoreStatus_e _prvMCAL_UartDeInitInstance(xMcalUartHandle* pxUartHand
} }
/** /**
* @brief Function to deinitialize the UART peripheral. * @brief Deinitializes the specified UART instance.
* *
* @param pxUartHandle Pointer to \link xMcalUartHandle \endlink. * This function validates the UART handle and port, then calls a private function
* @return IVEC_McalCommonErr_e Returns a status based on the success or failure of the UART deinitialization operation. * 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(xMcalUartHandle* pxUartHandle) IVEC_McalCommonErr_e xMCAL_UartDeInit(xMcalUartHandle* pxUartHandle)
{ {
if (pxUartHandle == NULL || pxUartHandle->eUartPortNumber >= IVEC_MCAL_UART_MAX_PORT)
{
return commonMCAL_INIT_FAIL;
}
IVEC_CoreStatus_e xRetStatus; IVEC_CoreStatus_e xRetStatus;
IVEC_MCAL_FUNC_ENTRY(LOG_STRING); IVEC_MCAL_FUNC_ENTRY(LOG_STRING);
IVEC_McalCommonErr_e eFuncStatus = commonMCAL_SUCCESS; IVEC_McalCommonErr_e eFuncStatus = commonMCAL_SUCCESS;
@ -243,11 +301,18 @@ exit:
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
/** /**
* @brief Internal function to read a single byte from UART. * @brief Reads a byte of data from the UART port.
* @param [in] pxUartHandle Pointer to \link McalUartHandle_t \endlink. *
* @param [out] pucData Pointer to store the received byte. * This function attempts to read a single byte of data from the specified UART
* @return \link CoreStatus_t \endlink Returns CORE_STATUS_SUCCESS on success or CORE_STATUS_ERROR on failure. * 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 prvIvecMcalUart_ReadByte(xMcalUartHandle* pxUartHandle, uint8_t* pucData) static IVEC_McalCommonErr_e prvIvecMcalUart_ReadByte(xMcalUartHandle* pxUartHandle, uint8_t* pucData)
{ {
/* Get the UART instance based on the port number in the handle */ /* Get the UART instance based on the port number in the handle */
@ -280,15 +345,25 @@ static IVEC_McalCommonErr_e prvIvecMcalUart_ReadByte(xMcalUartHandle* pxUartHan
} }
/** /**
* @brief Reads data from the UART port. * @brief Reads multiple bytes of data from the UART port.
* @pre UART should be initialized before calling this function. *
* @param [in] pxUartHandle Pointer to \link McalUartHandle_t \endlink. * This function validates the UART handle, attempts to read data from the UART port,
* @param [out] pucData Pointer to buffer for storing received data. * and returns the appropriate status. If the UART handle is invalid or the read
* @param [in] u32DataLength Length of the data to read. * operation fails, it returns an error status.
* @return \link IvecMcalCommonErr_t \endlink Returns the status of the UART read operation. *
* @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 xIvecMcalUart_Read(xMcalUartHandle* pxUartHandle, uint8_t* pucData, uint32_t u32DataLength) IVEC_McalCommonErr_e xIvecMcalUart_Read(xMcalUartHandle* pxUartHandle, uint8_t* pucData, uint32_t u32DataLength)
{ {
if (pxUartHandle == NULL || pxUartHandle->eUartPortNumber >= IVEC_MCAL_UART_MAX_PORT)
{
return commonMCAL_INIT_FAIL;
}
int32_t i32RetVal; int32_t i32RetVal;
IVEC_McalCommonErr_e eFuncStatus = commonMCAL_SUCCESS; IVEC_McalCommonErr_e eFuncStatus = commonMCAL_SUCCESS;
@ -324,11 +399,17 @@ exit:
//////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////
/** /**
* @brief Static function to transmit data over UART. * @brief Transmits data over the specified UART port.
* @param [in] pxUartHandle Pointer to UART handle structure. *
* @param [in] pu8TxData Pointer to the data buffer to transmit. * This function writes a specified number of bytes to the UART port, checking for
* @param [in] u32Size Number of bytes to transmit. * transmission timeout. If the transmission is successful, it returns a success
* @return xCoreStatus_t Status of the transmission (STATUS_SUCCESS or STATUS_ERROR). * 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_CoreStatus_e _prvMCAL_UartTransmit(xMcalUartHandle* pxUartHandle, uint8_t* pu8TxData, uint32_t u32Size) static IVEC_CoreStatus_e _prvMCAL_UartTransmit(xMcalUartHandle* pxUartHandle, uint8_t* pu8TxData, uint32_t u32Size)
{ {
@ -355,17 +436,27 @@ static IVEC_CoreStatus_e _prvMCAL_UartTransmit(xMcalUartHandle* pxUartHandle, ui
return IVEC_CORE_STATUS_SUCCESS; return IVEC_CORE_STATUS_SUCCESS;
} }
/** /**
* @brief Function to write data to the UART port. * @brief Writes data to the UART port.
* @pre UART must be initialized before calling this function. *
* @param [in] pxUartHandle Pointer to UART handle structure. * This function validates the UART handle, checks if the UART is initialized, and
* @param [in] pu8Data Pointer to the data buffer to send. * calls the static function to transmit data. It logs the status and handles errors
* @param [in] u32DataLength Length of the data to be sent. * related to the UART transmission.
* @return IVEC_McalCommonErr_e Status of the write operation. *
* @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(xMcalUartHandle* pxUartHandle, uint8_t* pu8Data, uint32_t u32DataLength) IVEC_McalCommonErr_e xMCAL_UartWrite(xMcalUartHandle* pxUartHandle, uint8_t* pu8Data, uint32_t u32DataLength)
{ {
if (pxUartHandle == NULL || pxUartHandle->eUartPortNumber >= IVEC_MCAL_UART_MAX_PORT)
{
return commonMCAL_INIT_FAIL;
}
IVEC_McalCommonErr_e eFuncStatus = commonMCAL_SUCCESS; IVEC_McalCommonErr_e eFuncStatus = commonMCAL_SUCCESS;
int32_t i32Ret; int32_t i32Ret;
@ -402,7 +493,27 @@ exit:
///////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
static IVEC_CoreStatus_e prvMCAL_UART_InitInstance(xMcalUartHandle* pxUartHandle, eMcalUartBaudRate xBaud) /**
* @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_CoreStatus_e prvMCAL_UARTInitInstance(xMcalUartHandle* pxUartHandle, eMcalUartBaudRate xBaud)
{ {
if (pxUartHandle->eUartPortNumber == eMcalUartPort2) if (pxUartHandle->eUartPortNumber == eMcalUartPort2)
{ {
@ -601,11 +712,16 @@ static IVEC_CoreStatus_e prvMCAL_UART_InitInstance(xMcalUartHandle* pxUartHandle
/** /**
* @brief Function to trigger the UART interrupt that is configured in the function pointer pvUartRecvCallback in \link McalUartHandle_s \endlink handle. * @brief UART receive callback function for notifying when data is received.
* @param [in] ind_type This is used as indication to the uart callback function. See \link IVEC_McalUartEvents_e \endlink *
* @param [in] port UART Port number. * This function is called when data is received on the specified UART port. It logs the
* @param [in] size Size of Data. * event type and calls the appropriate user-defined callback function if registered.
* @return nothing. * 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 #if 0
static void __prvMCAL_UartNotifyRecvCb(uint32 ind_type, ql_uart_port_number_e port, uint32 size) static void __prvMCAL_UartNotifyRecvCb(uint32 ind_type, ql_uart_port_number_e port, uint32 size)
@ -624,35 +740,49 @@ static void __prvMCAL_UartNotifyRecvCb(uint32 ind_type, ql_uart_port_number_e po
#endif #endif
/** /**
* @brief Function to register UART handle used for registering UART receive callback fucntion. * @brief Registers a UART handle for a specified UART port.
* @warning This is a private function. It should not be call outside the file \link ivec_mcal_uart.c \endlink. *
* @param pxUartHandle pointer to \link McalUartHandle_s \endlink * This function stores the given UART handle in the UART handles (`gpxMcalUartHandles`)
* @return Nothing * 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(xMcalUartHandle* pxUartHandle) static void prvMCAL_UartRegisterHandle(xMcalUartHandle* pxUartHandle)
{ {
gpxMcalUartHandles[pxUartHandle->eUartPortNumber] = pxUartHandle; gpxMcalUartHandles[pxUartHandle->eUartPortNumber] = pxUartHandle;
} }
/** /**
* @brief Function to Init UART peripheral * @brief Initializes the UART peripheral based on the provided configuration.
* @pre Need to configure UART configuration/properties in \link McalUartHandle_s \endlink *
* @param pxUartHandle pointer to \link McalUartHandle_s \endlink * This function initializes the UART instance by registering the handle,
* @return \link IVEC_McalCommonErr_e \endlink returns a status based on the success or failure of the UART Init operation. * configuring the UART instance with the settings specified in the
* `xMcalUartHandle`, 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(xMcalUartHandle* pxUartHandle) IVEC_McalCommonErr_e xMCAL_UartInit(xMcalUartHandle* pxUartHandle)
{ {
IVEC_MCAL_FUNC_ENTRY(LOG_STRING); IVEC_MCAL_FUNC_ENTRY(LOG_STRING);
IVEC_McalCommonErr_e l_xFuncStatus = commonMCAL_SUCCESS; IVEC_McalCommonErr_e l_xFuncStatus = commonMCAL_SUCCESS;
if (pxUartHandle == NULL) if (pxUartHandle == NULL || pxUartHandle->eUartPortNumber >= IVEC_MCAL_UART_MAX_PORT)
{ {
l_xFuncStatus = commonMCAL_INVALID_PARAM; return commonMCAL_INVALID_PARAM;
goto exit; goto exit;
} }
prvMCAL_UartRegisterHandle(pxUartHandle); prvMCAL_UartRegisterHandle(pxUartHandle);
int l_i32Ret = prvMCAL_UARTInitInstance(pxUartHandle, pxUartHandle->xUartConfig.eUartBaudrate);
int l_i32Ret = prvMCAL_UART_InitInstance(pxUartHandle, pxUartHandle->xUartConfig.eUartBaudrate);
if (l_i32Ret != IVEC_CORE_STATUS_SUCCESS) if (l_i32Ret != IVEC_CORE_STATUS_SUCCESS)
{ {
l_xFuncStatus = commonMCAL_INIT_FAIL; l_xFuncStatus = commonMCAL_INIT_FAIL;

View File

@ -9,6 +9,8 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#define ivECU_MAX_FILTERS ivMCAL_MAX_FILTERS
// Macro Definitions // Macro Definitions
#define IVEC_ECU_CAN_QUEUE(name, buff) \ #define IVEC_ECU_CAN_QUEUE(name, buff) \
volatile IVEC_ECU_CANQueue_s name = { \ volatile IVEC_ECU_CANQueue_s name = { \
@ -56,16 +58,39 @@ typedef struct {
IVEC_ECU_CANBuff_s *buffer; IVEC_ECU_CANBuff_s *buffer;
} IVEC_ECU_CANQueue_s; } IVEC_ECU_CANQueue_s;
// Function Prototypes typedef enum
void vMCU_FDCAN_RxFifo_Callback(uint32_t ulIdentifier, uint8_t *pucData, uint16_t usDataLength); {
uint8_t vMCAL_StoreMsgFromISRToQueue(uint32_t ulId, uint8_t *pucData, uint8_t ucLen); /* data */
IVEC_ECU_CAN_SPEED_125 = 125,
IVEC_ECU_CAN_SPEED_150 = 150,
IVEC_ECU_CAN_SPEED_250 = 250,
IVEC_ECU_CAN_SPEED_500 = 500,
IVEC_ECU_CAN_SPEED_1000 = 1000,
}IVEC_EcuCANSpeed_s;
IVEC_EcuCommonErr_e vECU_CAN_Init(MCAN_Regs *pMCAN, IVEC_CanBaud_e eBaud); typedef struct
IVEC_EcuCommonErr_e vECU_CAN_DeInit(MCAN_Regs *pMCAN); {
IVEC_EcuCommonErr_e vECU_WriteDataOverCAN(uint8_t *pucBuf, uint32_t ulId, int iRetCode, uint32_t ulBufNum); xMcalCanHandle __xCanHandle;
IVEC_EcuCommonErr_e vECU_CAN_GetData(IVEC_ECU_CANBuff_s *pxBuff); MCAN_Regs *pMCAN;
IVEC_EcuCommonErr_e vECU_CAN_ReInit(MCAN_Regs *pMCAN, uint16_t usSpeed); uint8_t __u8Init;
IVEC_EcuCommonErr_e vECU_CAN_GetStatus(MCAN_Regs *pMCAN, uint16_t usSpeed); IVEC_EcuCANSpeed_s u16Speed;
int32_t i32MaskCount;
int32_t i32FilterCount;
uint8_t __u8MaxFilter;
uint32_t u32MaskValues[ivECU_MAX_FILTERS];
uint32_t u32FilterValues[ivECU_MAX_FILTERS];
}IVEC_EcuCANHandle_s;
// Function Prototypes
void vMCU_FDCANRxFifoCallback(uint32_t ulIdentifier, uint8_t *pucData, uint16_t usDataLength);
uint8_t u8MCAL_StoreMsgFromISRToQueue(uint32_t ulId, uint8_t *pucData, uint8_t ucLen);
IVEC_EcuCommonErr_e xECU_CANInit(IVEC_EcuCANHandle_s *xCANhandle);
IVEC_EcuCommonErr_e xECU_CANDeInit(IVEC_EcuCANHandle_s *xCANhandle);
IVEC_EcuCommonErr_e xECU_WriteDataOverCAN(IVEC_EcuCANHandle_s *xCANhandle,uint8_t *pucBuf, uint32_t ulId, int iRetCode, uint32_t ulBufNum);
IVEC_EcuCommonErr_e xECU_CANGetData(IVEC_EcuCANHandle_s *xCANhandle, IVEC_ECU_CANBuff_s *pxBuff);
IVEC_EcuCommonErr_e xECU_CANReInit(IVEC_EcuCANHandle_s *xCANhandle);
IVEC_EcuCommonErr_e xECU_CANGetStatus(IVEC_EcuCANHandle_s *xCANhandle);
#endif /* IVEC_ECU_CAN_H_ */ #endif /* IVEC_ECU_CAN_H_ */
// //

View File

@ -8,25 +8,40 @@ static IVEC_ECU_CANBuff_s g_xCanBuffer[1024] = {0}; /* All the CAN ID, length,
/* Queue for CAN messages */ /* Queue for CAN messages */
IVEC_ECU_CAN_QUEUE(g_xCanQueue_x, g_xCanBuffer); IVEC_ECU_CAN_QUEUE(g_xCanQueue_x, g_xCanBuffer);
/**
* @brief Callback function for receiving CAN messages and storing them in a queue.
*
* This function is called when a CAN message is received. It checks if the CAN
* queue is full and stores the message in the queue if there is space available.
*
* @param[in] u32Identifier CAN ID of the received message.
* @param[in] pu8Data Pointer to the data of the received CAN message.
* @param[in] u16DataLength Length of the received CAN message data.
*/
/* CAN Receive FIFO Callback function */ /* CAN Receive FIFO Callback function */
void vMCAL_CanReceiveFifoCallback(uint32_t u32Identifier, uint8_t* pu8Data, uint16_t u16DataLength) void vMCAL_CanReceiveFifoCallback(uint32_t u32Identifier, uint8_t* pu8Data, uint16_t u16DataLength)
{ {
/* Check if the CAN queue is full */ /* Check if the CAN queue is full */
if (!IVEC_ECU_CAN_IS_FULL(g_xCanQueue_x)) { if (!IVEC_ECU_CAN_IS_FULL(g_xCanQueue_x)) {
/* Store the received message in the queue from the interrupt */ /* Store the received message in the queue from the interrupt */
vMCAL_StoreMsgFromISRToQueue(u32Identifier, pu8Data, u16DataLength); u8MCAL_StoreMsgFromISRToQueue(u32Identifier, pu8Data, u16DataLength);
} }
} }
/** /**
* @brief Stores a CAN message from ISR to a queue. * @brief Stores a CAN message from an interrupt service routine (ISR) to a queue.
* *
* @param ulId CAN ID of the message. * This function stores a CAN message with the specified ID and data length into
* @param pucData Pointer to the CAN data. * the CAN queue.
* @param ucLen Length of the CAN data. *
* @param[in] ulId CAN ID of the message.
* @param[in] pucData Pointer to the CAN message data.
* @param[in] ucLen Length of the CAN message data.
* @return uint8_t Status (0 for success, non-zero for failure). * @return uint8_t Status (0 for success, non-zero for failure).
*/ */
uint8_t vMCAL_StoreMsgFromISRToQueue(uint32_t ulId, uint8_t* pucData, uint8_t ucLen)
uint8_t u8MCAL_StoreMsgFromISRToQueue(uint32_t ulId, uint8_t* pucData, uint8_t ucLen)
{ {
IVEC_ECU_CANBuff_s xBuff = {0}; IVEC_ECU_CANBuff_s xBuff = {0};
xBuff.ulId = ulId; xBuff.ulId = ulId;
@ -37,18 +52,30 @@ uint8_t vMCAL_StoreMsgFromISRToQueue(uint32_t ulId, uint8_t* pucData, uint8_t uc
} }
/** /**
* @brief Sends data over CAN. * @brief Writes data over CAN.
* *
* @param pucBuf Pointer to the data buffer. * This function writes a data buffer to the CAN bus using the provided CAN
* @param ulId CAN ID to send the data. * handle and ID. It processes the buffer, applies a transformation (XOR with 0x0000),
* @param iRetCode Number of bytes to transmit. * and attempts to send the data using `xMCAL_MCANTx`.
* @param ulBufNum CAN buffer number. *
* @return IVEC_EcuCommonErr_e Status of the transmission. * @param[in] xCANhandle Pointer to the CAN handle structure.
* @param[in] pucBuf Pointer to the buffer containing data to be sent.
* @param[in] u32Id CAN ID for the message.
* @param[in] iRetCode Number of bytes to be written.
* @param[in] u32BufNum Buffer number to be used for transmission.
* @return IVEC_EcuCommonErr_e Status of the operation (`commonECU_SUCCESS` or `commonECU_WRITE_FAIL`).
*/ */
// Function to write data over CAN
IVEC_EcuCommonErr_e vECU_WriteDataOverCAN(uint8_t* pucBuf, uint32_t u32Id, int iRetCode, uint32_t u32BufNum) IVEC_EcuCommonErr_e xECU_WriteDataOverCAN(IVEC_EcuCANHandle_s *xCANhandle, uint8_t* pucBuf, uint32_t u32Id, int iRetCode, uint32_t u32BufNum)
{ {
IVEC_EcuCommonErr_e eFuncStatus = commonECU_WRITE_FAIL; IVEC_EcuCommonErr_e l_xFuncStatus = commonECU_WRITE_FAIL;
/* Ensure that the MCAN instance is CANFD0 */
if (xCANhandle->__xCanHandle.__u8Init == 0)
{
l_xFuncStatus = commonMCAL_FAIL;
return l_xFuncStatus;
}
uint8_t u8RetCode; uint8_t u8RetCode;
uint16_t au16TxData[8] = {0}; // Define a buffer for the CAN payload data. uint16_t au16TxData[8] = {0}; // Define a buffer for the CAN payload data.
@ -57,43 +84,82 @@ IVEC_EcuCommonErr_e vECU_WriteDataOverCAN(uint8_t* pucBuf, uint32_t u32Id, int i
} }
int iBytes = iRetCode; int iBytes = iRetCode;
u8RetCode = vMCAL_MCAN_Tx(CANFD0, u32Id, au16TxData, u32BufNum, iBytes); u8RetCode = xMCAL_MCANTx(&xCANhandle->__xCanHandle, u32Id, au16TxData, u32BufNum, iBytes);
if (u8RetCode == IVEC_MCAL_STATUS_SUCCESS) { if (u8RetCode == IVEC_MCAL_STATUS_SUCCESS) {
eFuncStatus = commonECU_SUCCESS; l_xFuncStatus = commonECU_SUCCESS;
} }
return eFuncStatus; return l_xFuncStatus;
} }
// Function to get data from the CAN buffer queue /**
IVEC_EcuCommonErr_e vECU_CAN_GetData(IVEC_ECU_CANBuff_s *pxBuff) * @brief Retrieves data from the CAN buffer queue.
*
* This function checks if the CAN queue is not empty and, if so, retrieves
* the next CAN message from the queue and copies it into the provided buffer.
*
* @param[in] xCANhandle Pointer to the CAN handle structure.
* @param[out] pxBuff Pointer to the buffer to store the retrieved CAN message.
* @return IVEC_EcuCommonErr_e Status of the operation (`commonECU_SUCCESS` or `commonECU_FAIL`).
*/
IVEC_EcuCommonErr_e xECU_CANGetData(IVEC_EcuCANHandle_s *xCANhandle, IVEC_ECU_CANBuff_s *pxBuff)
{ {
IVEC_EcuCommonErr_e eFuncStatus = commonECU_FAIL; IVEC_EcuCommonErr_e l_xFuncStatus = commonECU_FAIL;
/* Ensure that the MCAN instance is CANFD0 */
if (xCANhandle->__xCanHandle.__u8Init == 0)
{
l_xFuncStatus = commonMCAL_FAIL;
return l_xFuncStatus;
}
if (!IVEC_ECU_CAN_IS_EMPTY(g_xCanQueue_x)) { if (!IVEC_ECU_CAN_IS_EMPTY(g_xCanQueue_x)) {
IVEC_ECU_CANBuff_s xBuff = { 0x00 }; IVEC_ECU_CANBuff_s xBuff = { 0x00 };
IVEC_ECU_CAN_DEQUEUE(g_xCanQueue_x, xBuff); IVEC_ECU_CAN_DEQUEUE(g_xCanQueue_x, xBuff);
memcpy(pxBuff, &xBuff, sizeof(IVEC_ECU_CANBuff_s)); memcpy(pxBuff, &xBuff, sizeof(IVEC_ECU_CANBuff_s));
eFuncStatus = commonECU_SUCCESS; l_xFuncStatus = commonECU_SUCCESS;
} }
return eFuncStatus; return l_xFuncStatus;
} }
/* Function to reinitialize the CAN module */ /**
IVEC_EcuCommonErr_e vECU_CAN_ReInit(MCAN_Regs* pMCAN, uint16_t u16Speed) * @brief Reinitializes the CAN module.
*
* This function attempts to deinitialize and then reinitialize the CAN module,
* ensuring the correct configuration of power, GPIO, and CAN settings. It handles
* errors in the initialization and deinitialization process.
*
* @param[in] xCANhandle Pointer to the CAN handle structure.
* @return IVEC_EcuCommonErr_e Status of the operation (`commonECU_SUCCESS`, `commonECU_ALREADY_DEINIT`,
* `commonECU_DEINIT_FAIL`, or `commonECU_INIT_FAIL`).
*/
IVEC_EcuCommonErr_e xECU_CANReInit(IVEC_EcuCANHandle_s *xCANhandle)
{ {
IVEC_EcuCommonErr_e l_eFuncStatus = commonECU_SUCCESS; IVEC_EcuCommonErr_e l_xFuncStatus = commonECU_SUCCESS;
/* Ensure that the MCAN instance is CANFD0 */
assert(xCANhandle->pMCAN == CANFD0);
assert(xCANhandle->u16Speed == IVEC_ECU_CAN_SPEED_250 || xCANhandle->u16Speed == IVEC_ECU_CAN_SPEED_500);
if (xCANhandle->__xCanHandle.__u8Init == 0)
{
l_xFuncStatus = commonECU_ALREADY_DEINIT;
return l_xFuncStatus;
}
IVEC_McalStatus_e l_xMCALStatus; IVEC_McalStatus_e l_xMCALStatus;
/* Deinitialize the MCAN module */ /* Deinitialize the MCAN module */
l_xMCALStatus = vMCAL_MCAN_DeInit(pMCAN); l_xMCALStatus = xMCAL_MCANDeInit(&xCANhandle->__xCanHandle);
if (l_xMCALStatus != IVEC_MCAL_STATUS_SUCCESS) { if (l_xMCALStatus != IVEC_MCAL_STATUS_SUCCESS) {
l_eFuncStatus = commonECU_DEINIT_FAIL; l_xFuncStatus = commonECU_DEINIT_FAIL;
return l_eFuncStatus; return l_xFuncStatus;
} }
/* Enable power to the MCAN module */ /* Enable power to the MCAN module */
DL_MCAN_enablePower(pMCAN); DL_MCAN_enablePower(xCANhandle->pMCAN);
delay_cycles(POWER_STARTUP_DELAY); delay_cycles(POWER_STARTUP_DELAY);
/* Configure GPIO for CAN TX and RX */ /* Configure GPIO for CAN TX and RX */
@ -101,61 +167,122 @@ IVEC_EcuCommonErr_e vECU_CAN_ReInit(MCAN_Regs* pMCAN, uint16_t u16Speed)
DL_GPIO_initPeripheralInputFunction(GPIO_MCAN0_IOMUX_CAN_RX, GPIO_MCAN0_IOMUX_CAN_RX_FUNC); DL_GPIO_initPeripheralInputFunction(GPIO_MCAN0_IOMUX_CAN_RX, GPIO_MCAN0_IOMUX_CAN_RX_FUNC);
/* Reinitialize the MCAN module */ /* Reinitialize the MCAN module */
l_xMCALStatus = vMCAL_MCAN_Init(pMCAN, u16Speed); l_xMCALStatus = xMCAL_MCANInit(&xCANhandle->__xCanHandle);
/* Check if reinitialization was successful */ /* Check if reinitialization was successful */
if (l_xMCALStatus != IVEC_MCAL_STATUS_SUCCESS) { if (l_xMCALStatus != IVEC_MCAL_STATUS_SUCCESS) {
l_eFuncStatus = commonECU_INIT_FAIL; l_xFuncStatus = commonECU_INIT_FAIL;
} }
return l_eFuncStatus; return l_xFuncStatus;
} }
/* Function to initialize the CAN module */ /**
IVEC_EcuCommonErr_e vECU_CAN_Init(MCAN_Regs *pMCAN, IVEC_CanBaud_e eBaud) * @brief Initializes the CAN module.
*
* This function initializes the CAN module with the provided handle and settings.
* It ensures the correct speed configuration and performs the necessary hardware
* initializations.
*
* @param[in] xCANhandle Pointer to the CAN handle structure.
* @return IVEC_EcuCommonErr_e Status of the operation (`commonECU_SUCCESS` or `commonECU_INIT_FAIL`).
*/
IVEC_EcuCommonErr_e xECU_CANInit(IVEC_EcuCANHandle_s *xCANhandle)
{ {
IVEC_EcuCommonErr_e l_eFuncStatus = commonECU_SUCCESS;
IVEC_EcuCommonErr_e l_xFuncStatus = commonECU_SUCCESS;
/* Ensure that the MCAN instance is CANFD0 */
assert(xCANhandle->pMCAN == CANFD0);
assert(xCANhandle->u16Speed == IVEC_ECU_CAN_SPEED_250 || xCANhandle->u16Speed == IVEC_ECU_CAN_SPEED_500);
if (xCANhandle->__xCanHandle.__u8Init == 1)
{
l_xFuncStatus = commonECU_ALREADY_INIT;
return l_xFuncStatus;
}
xCANhandle->__xCanHandle.pMCAN = xCANhandle->pMCAN;
xCANhandle->__xCanHandle.u16Speed = xCANhandle->u16Speed;
IVEC_McalStatus_e eMcalStatus; IVEC_McalStatus_e eMcalStatus;
/* Call MCAL initialization function */ /* Call MCAL initialization function */
eMcalStatus = vMCAL_MCAN_Init(pMCAN, eBaud); eMcalStatus = xMCAL_MCANInit(&xCANhandle->__xCanHandle);
/* Check if initialization was successful */ /* Check if initialization was successful */
if (eMcalStatus != IVEC_MCAL_STATUS_SUCCESS) if (eMcalStatus != IVEC_MCAL_STATUS_SUCCESS)
{ {
l_eFuncStatus = commonECU_INIT_FAIL; l_xFuncStatus = commonECU_INIT_FAIL;
} }
return l_eFuncStatus; return l_xFuncStatus;
} }
/* Function to deinitialize the CAN module */ /**
IVEC_EcuCommonErr_e vECU_CAN_DeInit(MCAN_Regs *pMCAN) * @brief Deinitializes the CAN module.
*
* This function deinitializes the CAN module if it has been initialized.
* It ensures that the CAN module is properly deinitialized by calling the
* MCAL deinitialization function and checks for errors during the process.
*
* @param[in] xCANhandle Pointer to the CAN handle structure.
* @return IVEC_EcuCommonErr_e Status of the operation (`commonECU_SUCCESS`, `commonECU_ALREADY_DEINIT`,
* or `commonECU_INIT_FAIL`).
*/
IVEC_EcuCommonErr_e xECU_CANDeInit(IVEC_EcuCANHandle_s *xCANhandle)
{ {
IVEC_EcuCommonErr_e l_eFuncStatus = commonECU_SUCCESS; /* Assert that the MCAN module pointer is valid */
assert(xCANhandle->pMCAN == CANFD0);
IVEC_EcuCommonErr_e l_xFuncStatus = commonECU_SUCCESS;
if (xCANhandle->__xCanHandle.__u8Init == 0)
{
l_xFuncStatus = commonECU_ALREADY_DEINIT;
return l_xFuncStatus;
}
IVEC_McalStatus_e eMcalStatus; IVEC_McalStatus_e eMcalStatus;
/* Call MCAL deinitialization function */ /* Call MCAL deinitialization function */
eMcalStatus = vMCAL_MCAN_DeInit(pMCAN); eMcalStatus = xMCAL_MCANDeInit(&xCANhandle->__xCanHandle);
/* Check if deinitialization was successful */ /* Check if deinitialization was successful */
if (eMcalStatus != IVEC_MCAL_STATUS_SUCCESS) if (eMcalStatus != IVEC_MCAL_STATUS_SUCCESS)
{ {
l_eFuncStatus = commonECU_INIT_FAIL; l_xFuncStatus = commonECU_INIT_FAIL;
} }
return l_eFuncStatus; return l_xFuncStatus;
} }
/* Function to get the status of the CAN module */ /**
IVEC_EcuCommonErr_e vECU_CAN_GetStatus(MCAN_Regs* const pMCAN, uint16_t u16Speed) * @brief Retrieves the status of the CAN module.
*
* This function checks the current status of the CAN module. If the module is
* initialized, it retrieves the error status. If an error is detected, it attempts
* to reinitialize the CAN module.
*
* @param[in] xCANhandle Pointer to the CAN handle structure.
* @return IVEC_EcuCommonErr_e Status of the operation (`commonECU_SUCCESS`, `commonMCAL_FAIL`).
*/
IVEC_EcuCommonErr_e xECU_CANGetStatus(IVEC_EcuCANHandle_s *xCANhandle)
{ {
IVEC_EcuCommonErr_e l_eFuncStatus = commonECU_SUCCESS; /* Ensure that the MCAN instance is CANFD0 */
assert(xCANhandle->pMCAN == CANFD0);
assert(xCANhandle->u16Speed == IVEC_ECU_CAN_SPEED_250 || xCANhandle->u16Speed == IVEC_ECU_CAN_SPEED_500);
IVEC_EcuCommonErr_e l_xFuncStatus = commonECU_SUCCESS;
if (xCANhandle->__xCanHandle.__u8Init == 0)
{
l_xFuncStatus = commonMCAL_FAIL;
return l_xFuncStatus;
}
char cErrorString[32] = {0}; char cErrorString[32] = {0};
/* Retrieve the MCAN error status */ /* Retrieve the MCAN error status */
if (vMCAL_MCAN_GetErrorStatus(cErrorString) == IVEC_MCAL_STATUS_ERROR) if (xMCAL_MCANGetErrorStatus(&xCANhandle->__xCanHandle, cErrorString) == IVEC_MCAL_STATUS_ERROR)
{ {
/* Reinitialize CAN if an error is detected */ /* Reinitialize CAN if an error is detected */
l_eFuncStatus = vECU_CAN_ReInit(pMCAN, u16Speed); l_xFuncStatus = xECU_CANReInit(xCANhandle);
} }
return l_eFuncStatus; return l_xFuncStatus;
} }

View File

@ -24,6 +24,30 @@
/*Private Variables*/ /*Private Variables*/
typedef int IVEC_ECU_UartPacketRetCode_e;/*SERVICE_SUCESS or SERVICE_FAIL*/ typedef int IVEC_ECU_UartPacketRetCode_e;/*SERVICE_SUCESS or SERVICE_FAIL*/
typedef enum
{
eEcuUartBaudAuto = 0,
eEcuUartBaud2400 = 2400,
eEcuUartBaud4800 = 4800,
eEcuUartBaud9600 = 9600,
eEcuUartBaud14400 = 14400,
eEcuUartBaud19200 = 19200,
eEcuUartBaud28800 = 28800,
eEcuUartBaud33600 = 33600,
eEcuUartBaud38400 = 38400,
eEcuUartBaud57600 = 57600,
eEcuUartBaud115200 = 115200,
eEcuUartBaud230400 = 230400,
eEcuUartBaud460800 = 460800,
eEcuUartBaud921600 = 921600,
eEcuUartBaud1000000 = 1000000,
eEcuUartBaud1843200 = 1843200,
eEcuUartBaud2000000 = 2000000,
eEcuUartBaud2100000 = 2100000,
eEcuUartBaud3686400 = 3686400,
eEcuUartBaud4000000 = 4000000,
eEcuUartBaud4468750 = 4468750
} eEcuUartBaudRate;
typedef enum typedef enum
@ -48,6 +72,7 @@ typedef struct
volatile uint8_t* u8Qbuffer; volatile uint8_t* u8Qbuffer;
uint16_t u16QbufSize; uint16_t u16QbufSize;
uint16_t u16len; uint16_t u16len;
eEcuUartBaudRate u32BaudRate;
void (*pvUartRecvCallback)(IVEC_ECU_UartPortNumber_e, IVEC_ECU_UartEvent_e , char *, uint32_t); void (*pvUartRecvCallback)(IVEC_ECU_UartPortNumber_e, IVEC_ECU_UartEvent_e , char *, uint32_t);
} IVEC_ECU_UartHandle_s; } IVEC_ECU_UartHandle_s;
@ -55,14 +80,13 @@ typedef struct
* Functions declaration * Functions declaration
===========================================================================*/ ===========================================================================*/
IVEC_EcuCommonErr_e xECU_UartInit(IVEC_ECU_UartHandle_s* uartHandle);
IVEC_EcuCommonErr_e xECU_UartDeinit(IVEC_ECU_UartHandle_s *uartHandle);
IVEC_EcuCommonErr_e xECU_UartReinit(IVEC_ECU_UartHandle_s *uartHandle);
IVEC_EcuCommonErr_e xECU_UartTransmit(IVEC_ECU_UartHandle_s *uartHandle, uint8_t* buffer, uint16_t len);
IVEC_EcuCommonErr_e xECU_UartGetData(IVEC_ECU_UartHandle_s *uartHandle, uint8_t* buffer, uint16_t len, uint16_t timeout);
IVEC_EcuCommonErr_e IVEC_ECU_Uart_Init(IVEC_ECU_UartHandle_s* uartHandle, uint32_t speed); IVEC_ECU_UartPacketRetCode_e xECU_UartFormatPacket(IVEC_ECU_UartHandle_s *uartHandle, uint8_t* data, uint8_t dlc, uint32_t id);
IVEC_EcuCommonErr_e IVEC_ECU_Uart_Deinit(IVEC_ECU_UartHandle_s *uartHandle); IVEC_ECU_UartPacketRetCode_e xECU_UartReadCANDataLenOverUART(IVEC_ECU_UartHandle_s *uartHandle, uint8_t* buffer, uint32_t *id);
IVEC_EcuCommonErr_e IVEC_ECU_Uart_Reinit(IVEC_ECU_UartHandle_s *uartHandle, uint32_t speed); IVEC_ECU_UartPacketRetCode_e xECU_UartReadCANDataOverUART(IVEC_ECU_UartHandle_s* uartHandle, uint8_t* buffer, uint32_t *id);
IVEC_EcuCommonErr_e IVEC_ECU_Uart_Transmit(IVEC_ECU_UartHandle_s *uartHandle, uint8_t* buffer, uint16_t len); int32_t iECU_UartInitiateTransmit(IVEC_ECU_UartHandle_s* uartHandle, uint32_t id, uint8_t *data, uint8_t len);
IVEC_EcuCommonErr_e IVEC_ECU_Uart_GetData(IVEC_ECU_UartHandle_s *uartHandle, uint8_t* buffer, uint16_t len, uint16_t timeout);
IVEC_ECU_UartPacketRetCode_e IVEC_ECU_Uart_FormatPacket(IVEC_ECU_UartHandle_s *uartHandle, uint8_t* data, uint8_t dlc, uint32_t id);
IVEC_ECU_UartPacketRetCode_e IVEC_ECU_Uart_ReadCANDataLenOverUART(IVEC_ECU_UartHandle_s *uartHandle, uint8_t* buffer, uint32_t *id);
IVEC_ECU_UartPacketRetCode_e IVEC_ECU_Uart_ReadCANDataOverUART(IVEC_ECU_UartHandle_s* uartHandle, uint8_t* buffer, uint32_t *id);
int IVEC_ECU_Uart_InitiateTransmit(IVEC_ECU_UartHandle_s* uartHandle, uint32_t id, uint8_t *data, uint8_t len);

View File

@ -1,4 +1,4 @@
#include "../ivec_ECU/ivec_ecu_uart/inc/ivec_ecu_uart.h" #include "../ivec_ECU/ivec_ecu_uart/inc/ivec_ecu_uart.h"
#include "ivec_cmplx_queue.h" #include "ivec_cmplx_queue.h"
#include "../Core/Include/ivec_mcal_uart.h" #include "../Core/Include/ivec_mcal_uart.h"
@ -9,9 +9,19 @@
volatile static CmplxFifoQueueHandle_s __gprv_EcuUartResponseQueue[IVEC_MCAL_UART_MAX_PORT] = { 0 }; volatile static CmplxFifoQueueHandle_s __gprv_EcuUartResponseQueue[IVEC_MCAL_UART_MAX_PORT] = { 0 };
//static uint8_t __gprv_u8NFCUartDataBuffer[NFC_UART_BUFFER_MAX_SIZE]; //static uint8_t __gprv_u8NFCUartDataBuffer[NFC_UART_BUFFER_MAX_SIZE];
/**
* @brief UART receive callback for processing received data.
*
* This function is invoked when data is received over UART on different UART ports.
* The received data is enqueued into the appropriate FIFO queue based on the UART port.
*
* @param[in] uartPort The UART port number where the data was received.
* @param[in] eventType The event type indicating the status of the UART reception.
* @param[in] pucBuffer Pointer to the received data buffer.
* @param[in] u32Size Size of the received data buffer.
*/
static void __prvEcu_CANOverUartMsgCallback(eMcalUartPortNumber uartPort, IVEC_ECU_UartEvent_e eventType, char* pucBuffer, uint32_t u32Size)
static void __prv_vEcu_CANOverUartMsgCallback(eMcalUartPortNumber uartPort, IVEC_ECU_UartEvent_e eventType, char* pucBuffer, uint32_t u32Size)
{ {
switch (uartPort) switch (uartPort)
{ {
@ -29,8 +39,20 @@ static void __prv_vEcu_CANOverUartMsgCallback(eMcalUartPortNumber uartPort, IVEC
break; break;
} }
} }
/**
* @brief Calculates the checksum for the given packet.
*
* This function computes a two-byte checksum for the provided data packet. The
* checksum is calculated by summing the bytes of the packet (excluding the sync data),
* with each byte of the checksum being constrained to 8 bits.
*
* @param[in] pkt Pointer to the packet data for which the checksum is to be calculated.
* @param[in] len Length of the packet data.
* @param[out] checksum Pointer to a buffer where the calculated checksum will be stored.
* The checksum consists of two bytes.
*/
static void IVEC_ECU_CalculateChecksum(uint8_t* pkt, int len, uint8_t* checksum) { static void _prvECU_CalculateChecksum(uint8_t* pkt, int len, uint8_t* checksum) {
uint8_t checksum_a = 0, checksum_b = 0; uint8_t checksum_a = 0, checksum_b = 0;
/* Incremented to ignore Sync data */ /* Incremented to ignore Sync data */
for (int i = 2; i < len - 2; i++) { for (int i = 2; i < len - 2; i++) {
@ -43,10 +65,38 @@ static void IVEC_ECU_CalculateChecksum(uint8_t* pkt, int len, uint8_t* checksum)
checksum[1] = checksum_b; checksum[1] = checksum_b;
} }
//IVEC_EcuCommonErr_e /**
* @brief Initializes UART with specified configurations and a FIFO queue.
*
* This function initializes the UART interface by configuring the UART port,
* setting up the receive callback, and initializing the FIFO queue for the
* specified UART port. It also sets the UART parameters such as baud rate,
* flow control, data bits, stop bits, and parity bits.
*
* @param[in] prvUartHandle Pointer to the UART handle structure containing
* UART port configuration and queue settings.
*
* @return IVEC_EcuCommonErr_e Status of the initialization process:
* - `commonECU_SUCCESS`: Initialization was successful.
* - `commonECU_INIT_FAIL`: Initialization failed.
*
* @details
* - The function validates the UART port number and configures the appropriate
* FIFO queue for receiving data.
* - Initializes the UART configuration with provided parameters (baud rate, flow control,
* data bits, stop bits, and parity).
* - Sets the UART receive callback to `__prvEcu_CANOverUartMsgCallback`.
* - If the initialization of the FIFO queue or UART fails, the function returns
* `commonECU_INIT_FAIL`.
*/
IVEC_EcuCommonErr_e IVEC_ECU_Uart_Init(IVEC_ECU_UartHandle_s* prvUartHandle, uint32_t speed) IVEC_EcuCommonErr_e xECU_UartInit(IVEC_ECU_UartHandle_s* prvUartHandle)
{ {
if (prvUartHandle->eUartPortNumber >= IVEC_MCAL_UART_MAX_PORT)
{
return commonMCAL_INIT_FAIL;
}
IVEC_ECU_FUNC_ENTRY(LOG_STRING); IVEC_ECU_FUNC_ENTRY(LOG_STRING);
IVEC_EcuCommonErr_e l_xFuncStatus = commonECU_SUCCESS; IVEC_EcuCommonErr_e l_xFuncStatus = commonECU_SUCCESS;
uint8_t l_i32Ret = 0; uint8_t l_i32Ret = 0;
@ -83,9 +133,8 @@ IVEC_EcuCommonErr_e IVEC_ECU_Uart_Init(IVEC_ECU_UartHandle_s* prvUartHandle, uin
IVEC_ECU_LOG(LOG_STRING, "Initializing UART"); IVEC_ECU_LOG(LOG_STRING, "Initializing UART");
prvUartHandle->__xUartHandle.pvUartRecvCallback = __prv_vEcu_CANOverUartMsgCallback; prvUartHandle->__xUartHandle.pvUartRecvCallback = __prvEcu_CANOverUartMsgCallback;
prvUartHandle->__xUartHandle.xUartConfig.eUartBaudrate = prvUartHandle->u32BaudRate;
prvUartHandle->__xUartHandle.xUartConfig.eUartBaudrate = speed;
prvUartHandle->__xUartHandle.eUartPortNumber = prvUartHandle->eUartPortNumber; prvUartHandle->__xUartHandle.eUartPortNumber = prvUartHandle->eUartPortNumber;
prvUartHandle->__xUartHandle.xUartConfig.eUartFlowCtrl = eMcalUartFcNone; prvUartHandle->__xUartHandle.xUartConfig.eUartFlowCtrl = eMcalUartFcNone;
prvUartHandle->__xUartHandle.xUartConfig.eUartDataBit = eMcalUartDataBit8; prvUartHandle->__xUartHandle.xUartConfig.eUartDataBit = eMcalUartDataBit8;
@ -103,11 +152,34 @@ exit:
IVEC_ECU_FUNC_EXIT(LOG_STRING, 0); IVEC_ECU_FUNC_EXIT(LOG_STRING, 0);
return l_xFuncStatus; return l_xFuncStatus;
} }
/**
* @brief Deinitializes the UART interface.
*
* This function deinitializes the UART interface by flushing the associated FIFO
* queue and calling the `xMCAL_UartDeInit` function. If the UART port number is invalid
* or the UART handle is NULL, it returns an initialization failure status.
*
* @param[in] prvUartHandle Pointer to the UART handle structure to be deinitialized.
*
* @return IVEC_EcuCommonErr_e Status of the deinitialization:
* - `commonECU_SUCCESS`: Deinitialization was successful.
* - `commonECU_INIT_FAIL`: UART port is invalid or initialization failed.
* - `commonECU_DEINIT_FAIL`: UART deinitialization failed.
* - `commonECU_ALREADY_DEINIT`: UART handle is NULL, indicating it's already deinitialized.
*
* @details
* - The function first validates the UART handle and port number.
* - It then calls `xMCAL_UartDeInit` to deinitialize the UART hardware.
* - If the deinitialization fails, it returns `commonECU_DEINIT_FAIL`.
* - If successful, it flushes the UART response queue.
*/
IVEC_EcuCommonErr_e xECU_UartDeinit(IVEC_ECU_UartHandle_s* prvUartHandle)
IVEC_EcuCommonErr_e IVEC_ECU_Uart_Deinit(IVEC_ECU_UartHandle_s* prvUartHandle)
{ {
if (prvUartHandle == NULL || prvUartHandle->eUartPortNumber >= IVEC_MCAL_UART_MAX_PORT)
{
return commonECU_INIT_FAIL;
}
IVEC_ECU_FUNC_ENTRY(LOG_STRING); IVEC_ECU_FUNC_ENTRY(LOG_STRING);
uint8_t l_i32Ret; uint8_t l_i32Ret;
IVEC_EcuCommonErr_e l_xFuncStatus = commonECU_SUCCESS; IVEC_EcuCommonErr_e l_xFuncStatus = commonECU_SUCCESS;
@ -122,7 +194,7 @@ IVEC_EcuCommonErr_e IVEC_ECU_Uart_Deinit(IVEC_ECU_UartHandle_s* prvUartHandle)
l_i32Ret = xMCAL_UartDeInit(&prvUartHandle->__xUartHandle); l_i32Ret = xMCAL_UartDeInit(&prvUartHandle->__xUartHandle);
if (l_i32Ret != IVEC_MCAL_STATUS_SUCCESS) if (l_i32Ret != IVEC_MCAL_STATUS_SUCCESS)
{ {
l_xFuncStatus = commonECU_INIT_FAIL; l_xFuncStatus = commonECU_DEINIT_FAIL;
goto exit; goto exit;
} }
@ -135,14 +207,36 @@ exit:
IVEC_ECU_FUNC_EXIT(LOG_STRING, 0); IVEC_ECU_FUNC_EXIT(LOG_STRING, 0);
return l_xFuncStatus; return l_xFuncStatus;
} }
/**
* @brief Reinitializes the UART interface.
*
* This function first deinitializes the UART interface using `xECU_UartDeinit`,
* and then reinitializes it with the new configuration using `xECU_UartInit`.
*
* @param[in] prvUartHandle Pointer to the UART handle structure to be reinitialized.
*
* @return IVEC_EcuCommonErr_e Status of the reinitialization:
* - `commonECU_SUCCESS`: Reinitialization was successful.
* - `commonECU_INIT_FAIL`: UART initialization failed.
* - `commonECU_DEINIT_FAIL`: UART deinitialization failed.
*
* @details
* - The function first deinitializes the UART by calling `xECU_UartDeinit`.
* - If the deinitialization is successful, it then calls `xECU_UartInit` to reinitialize the UART.
* - If any step fails, the function returns an appropriate error status.
*/
IVEC_EcuCommonErr_e IVEC_ECU_Uart_Reinit(IVEC_ECU_UartHandle_s* prvUartHandle, uint32_t speed) IVEC_EcuCommonErr_e xECU_UartReinit(IVEC_ECU_UartHandle_s* prvUartHandle)
{ {
if (prvUartHandle == NULL || prvUartHandle->eUartPortNumber >= IVEC_MCAL_UART_MAX_PORT)
{
return commonECU_INIT_FAIL;
}
IVEC_EcuCommonErr_e l_xFuncStatus = commonECU_SUCCESS; IVEC_EcuCommonErr_e l_xFuncStatus = commonECU_SUCCESS;
uint8_t l_i32Ret; uint8_t l_i32Ret;
// Deinitialize UART // Deinitialize UART
l_i32Ret = IVEC_ECU_Uart_Deinit(prvUartHandle); l_i32Ret = xECU_UartDeinit(prvUartHandle);
if (l_i32Ret != IVEC_MCAL_STATUS_SUCCESS) if (l_i32Ret != IVEC_MCAL_STATUS_SUCCESS)
{ {
l_xFuncStatus = commonECU_DEINIT_FAIL; l_xFuncStatus = commonECU_DEINIT_FAIL;
@ -150,7 +244,7 @@ IVEC_EcuCommonErr_e IVEC_ECU_Uart_Reinit(IVEC_ECU_UartHandle_s* prvUartHandle, u
} }
// Reinitialize UART with the new speed // Reinitialize UART with the new speed
l_i32Ret = IVEC_ECU_Uart_Init(prvUartHandle, speed); l_i32Ret = xECU_UartInit(prvUartHandle);
if (l_i32Ret != IVEC_MCAL_STATUS_SUCCESS) if (l_i32Ret != IVEC_MCAL_STATUS_SUCCESS)
{ {
l_xFuncStatus = commonECU_INIT_FAIL; l_xFuncStatus = commonECU_INIT_FAIL;
@ -159,69 +253,182 @@ IVEC_EcuCommonErr_e IVEC_ECU_Uart_Reinit(IVEC_ECU_UartHandle_s* prvUartHandle, u
exit: exit:
return l_xFuncStatus; return l_xFuncStatus;
} }
/**
* @brief Transmits data over UART.
*
* This function is a placeholder and currently does not transmit data.
* It returns a failure status as the implementation is not provided.
*
* @param[in] prvUartHandle Pointer to the UART handle structure.
* @param[in] pucBuffer Pointer to the data buffer to be transmitted.
* @param[in] len Length of the data to be transmitted.
*
* @return IVEC_EcuCommonErr_e Status of the transmission:
* - `commonECU_FAIL`: Transmission is not implemented.
*/
IVEC_EcuCommonErr_e IVEC_ECU_Uart_Transmit(IVEC_ECU_UartHandle_s* prvUartHandle, uint8_t* pucBuffer, uint16_t len) IVEC_EcuCommonErr_e xECU_UartTransmit(IVEC_ECU_UartHandle_s* prvUartHandle, uint8_t* pucBuffer, uint16_t len)
{ {
return commonECU_SUCCESS; return commonECU_FAIL;
} }
/**
* @brief Flushes the UART response queue.
*
* This function clears the response queue associated with the specified UART port.
*
* @param[in] prvUartHandle Pointer to the UART handle structure.
*
* @return IVEC_EcuCommonErr_e Status of the flush operation:
* - `commonECU_SUCCESS`: Queue was flushed successfully.
* - `commonECU_FAIL`: The UART handle is invalid or the port number is out of range.
*
* @details
* - The function checks if the UART handle is valid and if the port number is within the allowed range.
* - It then flushes the FIFO queue associated with the UART response queue for the specified port.
*/
IVEC_EcuCommonErr_e IVEC_ECU_UART_Flush(IVEC_ECU_UartHandle_s* prvUartHandle)
IVEC_EcuCommonErr_e xECU_UartFlush(IVEC_ECU_UartHandle_s* prvUartHandle)
{ {
if (prvUartHandle == NULL || prvUartHandle->eUartPortNumber >= IVEC_MCAL_UART_MAX_PORT) if (prvUartHandle == NULL || prvUartHandle->eUartPortNumber >= IVEC_MCAL_UART_MAX_PORT)
{ {
vCMPLX_FifoQueueFlush((CmplxFifoQueueHandle_s*)&__gprv_EcuUartResponseQueue[prvUartHandle->eUartPortNumber]); return commonECU_FAIL;
} }
vCMPLX_FifoQueueFlush((CmplxFifoQueueHandle_s*)&__gprv_EcuUartResponseQueue[prvUartHandle->eUartPortNumber]);
return commonECU_SUCCESS; return commonECU_SUCCESS;
} }
/**
* @brief Retrieves data from the UART response queue.
*
* This function retrieves data from the UART response queue within a specified timeout period.
* If the data is available, it copies the data into the provided buffer. If data is not available
* within the timeout, it returns an error.
*
* @param[in] prvUartHandle Pointer to the UART handle structure.
* @param[out] pucBuffer Pointer to the buffer where the received data will be stored.
* @param[in] len Length of the data to be received.
* @param[in] timeout Timeout period in milliseconds.
*
* @return IVEC_EcuCommonErr_e Status of the data retrieval:
* - `commonECU_SUCCESS`: Data was retrieved successfully.
* - `commonECU_INVALID_PARAM`: Invalid UART handle or port number.
* - `commonECU_READ_FAIL`: Data could not be read within the timeout.
*
* @details
* - The function validates the UART handle and port number.
* - It checks the FIFO queue for available data and retrieves it into the provided buffer.
* - If data is not available within the timeout period, it returns `commonECU_READ_FAIL`.
* - Interrupts are disabled during the dequeue operation to ensure data integrity.
*/
IVEC_EcuCommonErr_e IVEC_ECU_Uart_GetData(IVEC_ECU_UartHandle_s* prvUartHandle, uint8_t* pucBuffer, uint16_t len, uint16_t timeout) IVEC_EcuCommonErr_e xECU_UartGetData(IVEC_ECU_UartHandle_s* prvUartHandle, uint8_t* pucBuffer, uint16_t len, uint16_t timeout)
{ {
IVEC_ECU_FUNC_ENTRY(LOG_STRING); IVEC_ECU_FUNC_ENTRY(LOG_STRING);
IVEC_EcuCommonErr_e l_xFuncStatus = commonECU_SUCCESS; IVEC_EcuCommonErr_e l_xFuncStatus = commonECU_SUCCESS;
// Validate parameters
if (prvUartHandle == NULL || prvUartHandle->eUartPortNumber >= IVEC_MCAL_UART_MAX_PORT) if (prvUartHandle == NULL || prvUartHandle->eUartPortNumber >= IVEC_MCAL_UART_MAX_PORT)
{ {
l_xFuncStatus = commonECU_INVALID_PARAM; l_xFuncStatus = commonECU_INVALID_PARAM;
goto exit; goto exit;
} }
uint8_t ijk = 0; uint16_t l_u16Len = 0;
int l_u32Len = 0;
uint32_t u32CommTimestamp = i32MCAL_GetTicks(); uint32_t u32CommTimestamp = i32MCAL_GetTicks();
// Loop until timeout or buffer is filled while(((i32MCAL_GetTicks() - u32CommTimestamp) <= timeout+1) && (l_u16Len < len))
while (((i32MCAL_GetTicks() - u32CommTimestamp) <= timeout + 1) && (ijk < len))
{ {
if (!u8CMPLX_FifoQueueEmpty((CmplxFifoQueueHandle_s*)&__gprv_EcuUartResponseQueue[prvUartHandle->eUartPortNumber]))
{ l_u16Len = i32CMPLX_FifoCounts((CmplxFifoQueueHandle_s*)&__gprv_EcuUartResponseQueue[prvUartHandle->eUartPortNumber]);
if (u8CMPLX_FifoDequeue((CmplxFifoQueueHandle_s*)&__gprv_EcuUartResponseQueue[prvUartHandle->eUartPortNumber], &pucBuffer[ijk], &l_u32Len, 0) == 1)
ijk++;
}
} }
// Check if all requested data was received if (l_u16Len < len)
if (ijk != len)
{ {
l_xFuncStatus = commonECU_READ_FAIL; l_xFuncStatus = commonECU_READ_FAIL;
goto exit; goto exit;
} }
else
{
int i32Len = 0;
__disable_irq();//disabling interrupt to avoid enqueing while dequeing
for(int i=0;i<len;i++)
{
u8CMPLX_FifoDequeue((CmplxFifoQueueHandle_s*)&__gprv_EcuUartResponseQueue[prvUartHandle->eUartPortNumber], &pucBuffer[i], &i32Len, 0);
exit: }
__enable_irq();
}
exit:
IVEC_ECU_FUNC_EXIT(LOG_STRING, 0); IVEC_ECU_FUNC_EXIT(LOG_STRING, 0);
return l_xFuncStatus; return l_xFuncStatus;
} }
//IVEC_EcuCommonErr_e xECU_UartGetData(IVEC_ECU_UartHandle_s* prvUartHandle, uint8_t* pucBuffer, uint16_t len, uint16_t timeout)
//{
// IVEC_ECU_FUNC_ENTRY(LOG_STRING);
//
// IVEC_EcuCommonErr_e l_xFuncStatus = commonECU_SUCCESS;
//
// // Validate parameters
// if (prvUartHandle == NULL || prvUartHandle->eUartPortNumber >= IVEC_MCAL_UART_MAX_PORT)
// {
// l_xFuncStatus = commonECU_INVALID_PARAM;
// goto exit;
// }
//
// uint8_t ijk = 0;
// int l_u32Len = 0;
// uint32_t u32CommTimestamp = i32MCAL_GetTicks();
//
// // Loop until timeout or buffer is filled
// while (((i32MCAL_GetTicks() - u32CommTimestamp) <= timeout + 1) && (ijk < len))
// {
// if (!u8CMPLX_FifoQueueEmpty((CmplxFifoQueueHandle_s*)&__gprv_EcuUartResponseQueue[prvUartHandle->eUartPortNumber]))
// {
// if (u8CMPLX_FifoDequeue((CmplxFifoQueueHandle_s*)&__gprv_EcuUartResponseQueue[prvUartHandle->eUartPortNumber], &pucBuffer[ijk], &l_u32Len, 0) == 1)
// ijk++;
// }
// }
//
// // Check if all requested data was received
// if (ijk != len)
// {
// l_xFuncStatus = commonECU_READ_FAIL;
// goto exit;
// }
//
//exit:
// IVEC_ECU_FUNC_EXIT(LOG_STRING, 0);
// return l_xFuncStatus;
//}
IVEC_ECU_UartPacketRetCode_e IVEC_ECU_Uart_ReadCANDataLenOverUART(IVEC_ECU_UartHandle_s* prvUartHandle, uint8_t* pucBuf, uint32_t* ulId)
/**
* @brief Reads and validates CAN data length over UART.
*
* This function reads data from the UART, checks packet synchronization, calculates
* the packet length, and verifies the checksum. It handles various conditions and
* returns the packet length or failure code.
*
* @param[in] prvUartHandle Pointer to the UART handle for communication.
* @param[out] pucBuf Buffer to store the received data.
* @param[out] ulId Pointer to store the extracted CAN ID.
*
* @return The packet length on success, or a failure code:
* - `commonECU_READ_FAIL` if the read operation or checksum validation fails.
* - `IVEC_ECU_UART_PACKET_FAIL` if the packet synchronization is lost.
*/
IVEC_ECU_UartPacketRetCode_e xECU_UartReadCANDataLenOverUART(IVEC_ECU_UartHandle_s* prvUartHandle, uint8_t* pucBuf, uint32_t* ulId)
{ {
int PktLen = commonECU_READ_FAIL; int PktLen = commonECU_READ_FAIL;
if ((IVEC_ECU_Uart_GetData(prvUartHandle, (uint8_t*)&pucBuf[0], 1, 0) == commonECU_SUCCESS)) if ((xECU_UartGetData(prvUartHandle, (uint8_t*)&pucBuf[0], 1, 0) == commonECU_SUCCESS))
{ {
if (pucBuf[0] == 0xB5) if (pucBuf[0] == 0xB5)
{ {
if (IVEC_ECU_Uart_GetData(prvUartHandle, (uint8_t*)&pucBuf[1], 1, 5) == commonECU_SUCCESS) { if (xECU_UartGetData(prvUartHandle, (uint8_t*)&pucBuf[1], 1, 5) == commonECU_SUCCESS) {
if (pucBuf[1] != 0x62) { if (pucBuf[1] != 0x62) {
PktLen = commonECU_READ_FAIL; PktLen = commonECU_READ_FAIL;
goto EXIT; // 0x62 not found, OUT OF SYNC goto EXIT; // 0x62 not found, OUT OF SYNC
@ -232,7 +439,7 @@ IVEC_ECU_UartPacketRetCode_e IVEC_ECU_Uart_ReadCANDataLenOverUART(IVEC_ECU_UartH
PktLen = commonECU_READ_FAIL; PktLen = commonECU_READ_FAIL;
goto EXIT; goto EXIT;
} }
if (IVEC_ECU_Uart_GetData(prvUartHandle, (uint8_t*)&pucBuf[2], 5, DATA_PACKET_TIMEOUT_MS) != commonECU_SUCCESS) { if (xECU_UartGetData(prvUartHandle, (uint8_t*)&pucBuf[2], 5, DATA_PACKET_TIMEOUT_MS) != commonECU_SUCCESS) {
PktLen = commonECU_READ_FAIL; PktLen = commonECU_READ_FAIL;
goto EXIT; goto EXIT;
} }
@ -240,13 +447,13 @@ IVEC_ECU_UartPacketRetCode_e IVEC_ECU_Uart_ReadCANDataLenOverUART(IVEC_ECU_UartH
*(ulId) = (uint32_t)((pucBuf[6] << 24) | (pucBuf[5] << 16) | (pucBuf[4] << 8) | (pucBuf[3])); *(ulId) = (uint32_t)((pucBuf[6] << 24) | (pucBuf[5] << 16) | (pucBuf[4] << 8) | (pucBuf[3]));
uint8_t l_ucTempLen = pucBuf[2]; uint8_t l_ucTempLen = pucBuf[2];
PktLen = IVEC_ECU_UART_PKT_HEADER_FOOTER + l_ucTempLen; PktLen = IVEC_ECU_UART_PKT_HEADER_FOOTER + l_ucTempLen;
if (IVEC_ECU_Uart_GetData(prvUartHandle, (uint8_t*)&pucBuf[IVEC_ECU_UART_PKT_HEADER], (uint32_t)(PktLen - IVEC_ECU_UART_PKT_HEADER), DATA_PACKET_TIMEOUT_MS) != commonECU_SUCCESS) if (xECU_UartGetData(prvUartHandle, (uint8_t*)&pucBuf[IVEC_ECU_UART_PKT_HEADER], (uint32_t)(PktLen - IVEC_ECU_UART_PKT_HEADER), DATA_PACKET_TIMEOUT_MS) != commonECU_SUCCESS)
{ {
PktLen = commonECU_READ_FAIL; PktLen = commonECU_READ_FAIL;
goto EXIT; goto EXIT;
} }
uint8_t checksum[2]; uint8_t checksum[2];
IVEC_ECU_CalculateChecksum(pucBuf, PktLen, checksum); _prvECU_CalculateChecksum(pucBuf, PktLen, checksum);
/* TODO: (Python Script) Sometimes fails due to bad checksum */ /* TODO: (Python Script) Sometimes fails due to bad checksum */
if ((checksum[0] == pucBuf[PktLen - 2]) && (checksum[1] == pucBuf[PktLen - 1])) { if ((checksum[0] == pucBuf[PktLen - 2]) && (checksum[1] == pucBuf[PktLen - 1])) {
@ -267,14 +474,46 @@ IVEC_ECU_UartPacketRetCode_e IVEC_ECU_Uart_ReadCANDataLenOverUART(IVEC_ECU_UartH
EXIT: EXIT:
return PktLen; return PktLen;
} }
/**
IVEC_ECU_UartPacketRetCode_e IVEC_ECU_Uart_ReadCANDataOverUART(IVEC_ECU_UartHandle_s* prvUartHandle, uint8_t* pucBuf, uint32_t* ulId) * @brief Reads CAN data over UART and returns the packet length.
*
* This function first validates the UART handle and checks the packet
* length over UART by calling `xECU_UartReadCANDataLenOverUART`.
* It returns the result based on the outcome of that function.
*
* @param[in] prvUartHandle Pointer to the UART handle for communication.
* @param[out] pucBuf Buffer to store the received data.
* @param[out] ulId Pointer to store the extracted CAN ID.
*
* @return The result of reading the CAN data over UART.
* - `IVEC_ECU_UART_PACKET_FAIL` if the UART handle is invalid or the
* packet read fails.
*/
IVEC_ECU_UartPacketRetCode_e xECU_UartReadCANDataOverUART(IVEC_ECU_UartHandle_s* prvUartHandle, uint8_t* pucBuf, uint32_t* ulId)
{ {
if (prvUartHandle == NULL || prvUartHandle->eUartPortNumber >= IVEC_MCAL_UART_MAX_PORT)
{
return IVEC_ECU_UART_PACKET_FAIL;
}
IVEC_ECU_UartPacketRetCode_e retCode = IVEC_ECU_UART_PACKET_FAIL; IVEC_ECU_UartPacketRetCode_e retCode = IVEC_ECU_UART_PACKET_FAIL;
retCode = IVEC_ECU_Uart_ReadCANDataLenOverUART(prvUartHandle, pucBuf, ulId); retCode = xECU_UartReadCANDataLenOverUART(prvUartHandle, pucBuf, ulId);
return retCode; return retCode;
} }
/**
* @brief Writes data to UART.
*
* This function writes a buffer of data to the UART, returning a success
* or failure status based on the outcome of the write operation.
*
* @param[in] prvUartHandle Pointer to the UART handle for communication.
* @param[in] pucBuffer Pointer to the buffer containing the data to send.
* @param[in] len Length of the data to send.
*
* @return Status of the write operation:
* - `commonECU_SUCCESS` if successful.
* - `commonECU_INVALID_PARAM` if the UART handle is invalid.
* - `commonECU_WRITE_FAIL` if the write operation fails.
*/
IVEC_EcuCommonErr_e IVEC_ECU_Uart_Write(IVEC_ECU_UartHandle_s* prvUartHandle, uint8_t* pucBuffer, uint16_t len) IVEC_EcuCommonErr_e IVEC_ECU_Uart_Write(IVEC_ECU_UartHandle_s* prvUartHandle, uint8_t* pucBuffer, uint16_t len)
{ {
IVEC_EcuCommonErr_e l_xFuncStatus = commonECU_WRITE_FAIL; IVEC_EcuCommonErr_e l_xFuncStatus = commonECU_WRITE_FAIL;
@ -293,15 +532,29 @@ IVEC_EcuCommonErr_e IVEC_ECU_Uart_Write(IVEC_ECU_UartHandle_s* prvUartHandle, ui
return l_xFuncStatus; return l_xFuncStatus;
} }
/**
IVEC_ECU_UartPacketRetCode_e IVEC_ECU_Uart_FormatPacket(IVEC_ECU_UartHandle_s* prvUartHandle, uint8_t* pucData, uint8_t ucDlc, uint32_t ulId) * @brief Formats and prepares a UART packet for transmission.
*
* This function formats a packet with a sync character, data length, CAN ID,
* and checksum, and then sends it via UART using `IVEC_ECU_Uart_Write`.
*
* @param[in] prvUartHandle Pointer to the UART handle for communication.
* @param[in] pucData Pointer to the data buffer to format.
* @param[in] ucDlc Data length code (DLC) for the packet.
* @param[in] ulId CAN ID to be included in the packet.
*
* @return Status of the packet formatting:
* - `IVEC_ECU_UART_PACKET_SUCCESS` if successful.
* - `IVEC_ECU_UART_PACKET_FAIL` if the packet formatting or write fails.
*/
IVEC_ECU_UartPacketRetCode_e xECU_UartFormatPacket(IVEC_ECU_UartHandle_s* prvUartHandle, uint8_t* pucData, uint8_t ucDlc, uint32_t ulId)
{ {
pucData[0] = 0xb5; // SYNC_CHAR[0] pucData[0] = 0xb5; // SYNC_CHAR[0]
pucData[1] = 0x62; // SYNC_CHAR[1] pucData[1] = 0x62; // SYNC_CHAR[1]
pucData[2] = ucDlc; pucData[2] = ucDlc;
memcpy(&pucData[3], &ulId, sizeof(uint32_t)); memcpy(&pucData[3], &ulId, sizeof(uint32_t));
unsigned char checksum[2] = { 0 }; unsigned char checksum[2] = { 0 };
IVEC_ECU_CalculateChecksum(pucData, (ucDlc + IVEC_ECU_UART_PKT_HEADER_FOOTER), checksum); _prvECU_CalculateChecksum(pucData, (ucDlc + IVEC_ECU_UART_PKT_HEADER_FOOTER), checksum);
pucData[(ucDlc + IVEC_ECU_UART_PKT_HEADER_FOOTER) - 2] = checksum[0]; pucData[(ucDlc + IVEC_ECU_UART_PKT_HEADER_FOOTER) - 2] = checksum[0];
pucData[(ucDlc + IVEC_ECU_UART_PKT_HEADER_FOOTER) - 1] = checksum[1]; pucData[(ucDlc + IVEC_ECU_UART_PKT_HEADER_FOOTER) - 1] = checksum[1];
if (IVEC_ECU_Uart_Write(prvUartHandle, pucData, (ucDlc + IVEC_ECU_UART_PKT_HEADER_FOOTER)) != commonECU_SUCCESS) { if (IVEC_ECU_Uart_Write(prvUartHandle, pucData, (ucDlc + IVEC_ECU_UART_PKT_HEADER_FOOTER)) != commonECU_SUCCESS) {
@ -309,10 +562,28 @@ IVEC_ECU_UartPacketRetCode_e IVEC_ECU_Uart_FormatPacket(IVEC_ECU_UartHandle_s* p
} }
return IVEC_ECU_UART_PACKET_SUCCESS; return IVEC_ECU_UART_PACKET_SUCCESS;
} }
/**
int IVEC_ECU_Uart_InitiateTransmit(IVEC_ECU_UartHandle_s* prvUartHandle, uint32_t id, uint8_t* pucData, uint8_t ucLen) * @brief Initiates UART data transmission.
*
* This function prepares a data packet with the given CAN ID and data,
* formats the packet, and sends it via UART.
*
* @param[in] prvUartHandle Pointer to the UART handle for communication.
* @param[in] id CAN ID for the packet.
* @param[in] pucData Pointer to the data to send.
* @param[in] ucLen Length of the data to send.
*
* @return Status of the transmission:
* - `0` on success.
* - `-1` on failure.
*/
int32_t iECU_UartInitiateTransmit(IVEC_ECU_UartHandle_s* prvUartHandle, uint32_t id, uint8_t* pucData, uint8_t ucLen)
{ {
if (prvUartHandle == NULL || prvUartHandle->eUartPortNumber >= IVEC_MCAL_UART_MAX_PORT)
{
return commonECU_INIT_FAIL;
}
uint8_t pucBuf[IVEC_ECU_UART_MAX_PACKET_LENGTH] = { 0 }; uint8_t pucBuf[IVEC_ECU_UART_MAX_PACKET_LENGTH] = { 0 };
memcpy(&pucBuf[IVEC_ECU_UART_PKT_HEADER], pucData, ucLen); memcpy(&pucBuf[IVEC_ECU_UART_PKT_HEADER], pucData, ucLen);
return (IVEC_ECU_Uart_FormatPacket(prvUartHandle, pucBuf, ucLen, id) == IVEC_ECU_UART_PACKET_SUCCESS) ? 0 : -1; return (xECU_UartFormatPacket(prvUartHandle, pucBuf, ucLen, id) == IVEC_ECU_UART_PACKET_SUCCESS) ? 0 : -1;
} }

View File

@ -19,6 +19,7 @@
// UART Handles // UART Handles
IVEC_ECU_UartHandle_s g_xEcuUartHandle; IVEC_ECU_UartHandle_s g_xEcuUartHandle;
IVEC_ECU_UartHandle_s g_xEcuUart2Handle; IVEC_ECU_UartHandle_s g_xEcuUart2Handle;
IVEC_EcuCANHandle_s g_xEcuCanHandle;
// Configuration Macros // Configuration Macros
#define ivECU_CONFIG_BASIL_BATTERY_SMART 1 #define ivECU_CONFIG_BASIL_BATTERY_SMART 1
@ -28,8 +29,7 @@ IVEC_ECU_UartHandle_s g_xEcuUart2Handle;
#define ivECU_UART_PIN_SELECTION ivECU_CONFIG_BASIL_BATTERY_SMART #define ivECU_UART_PIN_SELECTION ivECU_CONFIG_BASIL_BATTERY_SMART
// Global Variables // Global Variables
uint32_t g_u32UartSpeed = 0; xMCAL_CanBaud_e g_eCanSpeed = 0;
IVEC_CanBaud_e g_eCanSpeed = 0;
uint8_t g_pu8UartBuffer[IVEC_ECU_UART_MAX_PACKET_LENGTH] = {0}; uint8_t g_pu8UartBuffer[IVEC_ECU_UART_MAX_PACKET_LENGTH] = {0};
volatile uint32_t g_u32CanId = 0x1FFFFFFF; volatile uint32_t g_u32CanId = 0x1FFFFFFF;
@ -38,14 +38,8 @@ volatile uint32_t g_u32CanId = 0x1FFFFFFF;
volatile uint8_t g_prvU8CanUartDataBuffer[ivECU_CAN_UART_BUFFER_MAX_SIZE]; volatile uint8_t g_prvU8CanUartDataBuffer[ivECU_CAN_UART_BUFFER_MAX_SIZE];
// CAN Filters // CAN Filters
#define ivECU_MAX_FILTERS 10
uint32_t g_u32MaskValues[ivECU_MAX_FILTERS];
uint32_t g_u32FilterValues[ivECU_MAX_FILTERS];
bool g_bIsExtendedId[ivECU_MAX_FILTERS]; bool g_bIsExtendedId[ivECU_MAX_FILTERS];
// Filter Counters
int32_t g_i32MaskCount = -1;
int32_t g_i32FilterCount = -1;
// Filter Information // Filter Information
uint16_t g_u16ExtendedFilter = 0; uint16_t g_u16ExtendedFilter = 0;
@ -63,12 +57,15 @@ extern volatile bool g_bMcalMcanInitFlag; /*!< CAN initialization flag */
#define ivECU_MCAN_FILTER_SIZE 0U #define ivECU_MCAN_FILTER_SIZE 0U
/** /**
* @brief Function to use SDA pin of TM1650 * @brief Sets the state of the MCU temperature data pin (SDA) for TM1650.
* *
* @param state the value to write on SDA pin (0 or 1) * @param[in] u8State The state to set on the SDA pin (0 for low, 1 for high).
* @returns none *
* @note This function controls the SDA pin of the TM1650 by setting it to
* either low or high based on the input state.
*/ */
void vRTE_SetMcuTempDataPin(uint8_t u8State) void vRTE_SetMcuTempDataPin(uint8_t u8State)
{ {
if(u8State == 0){ if(u8State == 0){
@ -80,11 +77,14 @@ void vRTE_SetMcuTempDataPin(uint8_t u8State)
} }
/** /**
* @brief Function to use SCL pin of TM1650 * @brief Sets the state of the MCU temperature clock pin (SCL) for TM1650.
* *
* @param state the value to write on SDA pin (0 or 1) * @param[in] u8State The state to set on the SCL pin (0 for low, 1 for high).
* @returns none *
* @note This function controls the SCL pin of the TM1650 by setting it to
* either low or high based on the input state.
*/ */
void vRTE_McuSetTempClkPin(uint8_t u8State) void vRTE_McuSetTempClkPin(uint8_t u8State)
{ {
if(u8State == 0){ if(u8State == 0){
@ -96,12 +96,17 @@ void vRTE_McuSetTempClkPin(uint8_t u8State)
} }
/** /**
* @brief Function to read SDA pin of TM1650 * @brief Reads the state of the MCU temperature data pin (SDA) for TM1650.
* *
* @param none * This function configures the SDA pin as an input, reads the pin state,
* @returns Value of GPIO (0 or 1) * and then restores the pin's direction to output.
*
* @returns The state of the SDA pin (0 for low, 1 for high).
*
* @note The pin direction is temporarily set to input to read the pin state.
*/ */
static uint8_t _prvRteReadMcuTempPin(void) {
static uint8_t _prvRTE_ReadMcuTempPin(void) {
uint8_t l_u8ReadBuffer = 0; uint8_t l_u8ReadBuffer = 0;
vMCAL_set_gpioDirection(TM1650_SDA_PIN_IOMUX,false); vMCAL_set_gpioDirection(TM1650_SDA_PIN_IOMUX,false);
l_u8ReadBuffer = u32MCAL_gpioRead(TM1650_PORT, TM1650_SDA_PIN_PIN); l_u8ReadBuffer = u32MCAL_gpioRead(TM1650_PORT, TM1650_SDA_PIN_PIN);
@ -109,11 +114,25 @@ static uint8_t _prvRteReadMcuTempPin(void) {
return l_u8ReadBuffer; return l_u8ReadBuffer;
} }
/**
* @brief Initializes the MATLAB interface for MCU and TM1650.
*
* This function performs the following initialization steps:
* - Initializes GPIO pins for communication.
* - Initializes the TM1650 display with the specified parameters.
* - Turns off the TM1650 screen, waits for a short delay, and then hides the
* decimal points on the digits.
* - Initializes the touch display for user interaction.
*
* @returns None
*
* @note The function uses `vMCAL_DelayTicks` for a delay after turning off the display.
*/
void vRTE_MatlabInit(void) void vRTE_MatlabInit(void)
{ {
u8MCAL_gpioInit(); u8MCAL_gpioInit();
tm1650_Init(TM_1650_BRIGHT_8, TM_1650_Segment_8, TM_1650_Normal_Mode, TM_1650_Screen_ON, TM_1650_DIG_3, (void*)&vRTE_SetMcuTempDataPin , (void*)&vRTE_McuSetTempClkPin , &_prvRteReadMcuTempPin); tm1650_Init(TM_1650_BRIGHT_8, TM_1650_Segment_8, TM_1650_Normal_Mode, TM_1650_Screen_ON, TM_1650_DIG_3, (void*)&vRTE_SetMcuTempDataPin , (void*)&vRTE_McuSetTempClkPin , &_prvRTE_ReadMcuTempPin);
tm1650_displaySwitch(TM_1650_Screen_OFF); tm1650_displaySwitch(TM_1650_Screen_OFF);
vMCAL_DelayTicks(500); vMCAL_DelayTicks(500);
tm1650_showDot(TM_1650_DIG_1,false); tm1650_showDot(TM_1650_DIG_1,false);
@ -121,6 +140,20 @@ void vRTE_MatlabInit(void)
tm1650_showDot(TM_1650_DIG_3,false); tm1650_showDot(TM_1650_DIG_3,false);
socTouchDisplay_initialize(); socTouchDisplay_initialize();
} }
/**
* @brief Runs the MATLAB interface for MCU and TM1650 during operation.
*
* This function performs several actions:
* - Detects if a touch input is active and sets display and touch durations.
* - Executes the display update step with `socTouchDisplay_step()`.
* - Clears and resets the CAN message buffer.
* - Based on the display and error statuses, it updates the TM1650 display:
* - If display status is active, it shows the appropriate digits or alphabet.
* - If an error is detected, it displays an error message on the TM1650.
* - If neither status is active, it turns off the display.
*
* @returns None
*/
void vRTE_MatlabRun(void) void vRTE_MatlabRun(void)
{ {
@ -177,6 +210,15 @@ void vRTE_MatlabRun(void)
tm1650_displaySwitch(TM_1650_Screen_OFF); tm1650_displaySwitch(TM_1650_Screen_OFF);
} }
} }
/**
* @brief Initializes the application run processes.
*
* This function processes UART and CAN data to perform necessary tasks during
* the application runtime.
*
* @returns None
*/
void vRTE_AppInit(void) void vRTE_AppInit(void)
{ {
@ -186,32 +228,64 @@ void vRTE_AppInit(void)
vRTE_InitUartCanEcho(); vRTE_InitUartCanEcho();
} }
/**
* @brief Callback function for timer interrupt.
*
* This function is triggered by a timer interrupt and performs the following actions:
* - Calls the `vRTE_MatlabRun()` function if the battery smart configuration is enabled.
* - Clears the interrupt flag for Timer 1.
*
* @returns None
*/
void vRTE_InitUartCanEcho(void) void vRTE_InitUartCanEcho(void)
{ {
g_u32UartSpeed = eMcalUartBaud115200;
g_eCanSpeed = IVEC_CAN_BAUD_500; g_eCanSpeed = IVEC_CAN_BAUD_500;
g_xEcuUartHandle.u8Qbuffer = g_prvU8CanUartDataBuffer; g_xEcuUartHandle.u8Qbuffer = g_prvU8CanUartDataBuffer;
g_xEcuUartHandle.u16QbufSize = ivECU_CAN_UART_BUFFER_MAX_SIZE; g_xEcuUartHandle.u16QbufSize = ivECU_CAN_UART_BUFFER_MAX_SIZE;
#if (ivECU_UART_PIN_SELECTION == 1) #if (ivECU_UART_PIN_SELECTION == 1)
g_xEcuUartHandle.eUartPortNumber = IVEC_ECU_UART_PORT3; g_xEcuUartHandle.eUartPortNumber = IVEC_ECU_UART_PORT3;
#elif (ivECU_UART_PIN_SELECTION == 2) g_xEcuUartHandle.u32BaudRate = eEcuUartBaud115200;
g_xEcuUartHandle.eUartPortNumber = IVEC_ECU_UART_PORT2; #elif (ivECU_UART_PIN_SELECTION == 2)
#endif g_xEcuUartHandle.eUartPortNumber = IVEC_ECU_UART_PORT2;
g_xEcuUartHandle.u32BaudRate = eEcuUartBaud115200;
#endif
IVEC_ECU_Uart_Init(&g_xEcuUartHandle, g_u32UartSpeed); xECU_UartInit(&g_xEcuUartHandle);
vECU_CAN_Init(CANFD0,g_eCanSpeed); g_xEcuCanHandle.u16Speed = IVEC_ECU_CAN_SPEED_500;
g_xEcuCanHandle.pMCAN = CANFD0;
g_xEcuCanHandle.i32MaskCount = -1;
g_xEcuCanHandle.i32FilterCount = -1;
xECU_CANInit(&g_xEcuCanHandle);
} }
/**
* @brief Initializes the application run processes.
*
* This function processes UART and CAN data to perform necessary tasks during
* the application runtime.
*
* @returns None
*/
void vRTE_AppRunInit(void) void vRTE_AppRunInit(void)
{ {
vRTE_ProcessUartData(); vRTE_ProcessUartData();
vRTE_ProcessCanData(); vRTE_ProcessCanData();
} }
/**
* @brief Callback function for timer interrupt.
*
* This function is triggered by a timer interrupt and performs the following actions:
* - Calls the `vRTE_MatlabRun()` function if the battery smart configuration is enabled.
* - Clears the interrupt flag for Timer 1.
*
* @returns None
*/
void vMCAL_TimerCallback(void) void vMCAL_TimerCallback(void)
{ {
@ -221,25 +295,61 @@ void vMCAL_TimerCallback(void)
DL_TimerA_clearInterruptStatus(TIMER_1_INST, GPTIMER_CPU_INT_IMASK_Z_SET); DL_TimerA_clearInterruptStatus(TIMER_1_INST, GPTIMER_CPU_INT_IMASK_Z_SET);
} }
/**
* @brief Saves the CAN filter mask value.
*
* This function saves the mask value at the specified index in the CAN handle,
* allowing for the configuration of the CAN filters based on the given
* extended ID and mask value.
*
* @param[in] u8Idx The index where the mask value is saved.
* @param[in] u32Mask The mask value to be stored.
* @param[in] bIsExtended Flag indicating whether the mask applies to extended IDs.
*
* @returns None
*/
void vRTE_CanFilterMaskSaveVal(uint8_t u8Idx, uint32_t u32Mask, bool bIsExtended) void vRTE_CanFilterMaskSaveVal(uint8_t u8Idx, uint32_t u32Mask, bool bIsExtended)
{ {
g_i32MaskCount = u8Idx; g_xEcuCanHandle.i32MaskCount = u8Idx;
g_u32MaskValues[g_i32MaskCount] = u32Mask; g_xEcuCanHandle.u32MaskValues[g_xEcuCanHandle.i32MaskCount] = u32Mask;
} }
/**
* @brief Saves the CAN filter value.
*
* This function saves the CAN filter value at the specified index in the CAN handle,
* allowing for dynamic configuration of the CAN filters at runtime.
*
* @param[in] u8Idx The index where the filter value is stored.
* @param[in] u32Filter The filter value to be stored.
* @param[in] bIsExtended Flag indicating whether the filter applies to extended IDs.
*
* @returns None
*/
void vRTE_CanFilterSaveVal(uint8_t u8Idx, uint32_t u32Filter, bool bIsExtended) void vRTE_CanFilterSaveVal(uint8_t u8Idx, uint32_t u32Filter, bool bIsExtended)
{ {
g_i32FilterCount = u8Idx; g_xEcuCanHandle.i32FilterCount = u8Idx;
// Store filter value // Store filter value
g_u32FilterValues[g_i32FilterCount] = u32Filter; g_xEcuCanHandle.u32FilterValues[g_xEcuCanHandle.i32FilterCount] = u32Filter;
} }
/**
* @brief Processes UART data to manage CAN and UART communication.
*
* This function reads data from UART, interprets the data to determine the mode,
* and performs appropriate actions like adjusting UART or CAN baud rates, saving
* filter and mask values, or reinitializing CAN with new configurations.
* It handles different modes (0, 1, 2, 3, and 100) for runtime configurations.
*
* @returns None
*/
void vRTE_ProcessUartData(void) void vRTE_ProcessUartData(void)
{ {
IVEC_ECU_UartPacketRetCode_e eRetCode = IVEC_ECU_UART_PACKET_FAIL; IVEC_ECU_UartPacketRetCode_e eRetCode = IVEC_ECU_UART_PACKET_FAIL;
uint32_t l_u32Id = 0x1fffffff; uint32_t l_u32Id = 0x1fffffff;
eRetCode= IVEC_ECU_Uart_ReadCANDataOverUART(&g_xEcuUartHandle,g_pu8UartBuffer,&l_u32Id); eRetCode= xECU_UartReadCANDataOverUART(&g_xEcuUartHandle,g_pu8UartBuffer,&l_u32Id);
l_u32Id &= 0x1fffffff; l_u32Id &= 0x1fffffff;
if(eRetCode > -1) if(eRetCode > -1)
{ {
@ -248,16 +358,16 @@ void vRTE_ProcessUartData(void)
uint32_t l_u32Baudrate = 0; uint32_t l_u32Baudrate = 0;
uint8_t l_u8Mode = g_pu8UartBuffer[IVEC_ECU_UART_PKT_HEADER]; uint8_t l_u8Mode = g_pu8UartBuffer[IVEC_ECU_UART_PKT_HEADER];
memcpy(&l_u32Baudrate, &g_pu8UartBuffer[IVEC_ECU_UART_PKT_HEADER+1], (uint32_t)eRetCode); memcpy(&l_u32Baudrate, &g_pu8UartBuffer[IVEC_ECU_UART_PKT_HEADER+1], (uint32_t)eRetCode);
IVEC_ECU_Uart_InitiateTransmit(&g_xEcuUartHandle, 0x01, g_pu8UartBuffer, 0); iECU_UartInitiateTransmit(&g_xEcuUartHandle, 0x01, g_pu8UartBuffer, 0);
if( l_u8Mode == 0 ) if( l_u8Mode == 0 )
{ {
g_u32UartSpeed = l_u32Baudrate; g_xEcuUartHandle.u32BaudRate = l_u32Baudrate;
IVEC_ECU_Uart_Reinit(&g_xEcuUartHandle, g_u32UartSpeed); xECU_UartReinit(&g_xEcuUartHandle);
} }
else if( l_u8Mode == 1 ) else if( l_u8Mode == 1 )
{ {
g_eCanSpeed = (uint16_t)l_u32Baudrate; g_xEcuCanHandle.u16Speed = (uint16_t)l_u32Baudrate;;
vECU_CAN_ReInit(CANFD0, g_eCanSpeed); xECU_CANReInit(&g_xEcuCanHandle);
} }
else if( l_u8Mode == 2 ) else if( l_u8Mode == 2 )
{ {
@ -270,13 +380,13 @@ void vRTE_ProcessUartData(void)
vRTE_CanFilterSaveVal((g_pu8UartBuffer[IVEC_ECU_UART_PKT_HEADER+1] - 1), filterId, isExtended); vRTE_CanFilterSaveVal((g_pu8UartBuffer[IVEC_ECU_UART_PKT_HEADER+1] - 1), filterId, isExtended);
if( g_pu8UartBuffer[IVEC_ECU_UART_PKT_HEADER+2] )//All filter received. Trigger Filter Settings if( g_pu8UartBuffer[IVEC_ECU_UART_PKT_HEADER+2] )//All filter received. Trigger Filter Settings
{ {
vECU_CAN_ReInit(CANFD0,g_eCanSpeed); xECU_CANReInit(&g_xEcuCanHandle);
} }
else else
return; return;
} }
else{ else{
vECU_CAN_ReInit(CANFD0,g_eCanSpeed); xECU_CANReInit(&g_xEcuCanHandle);
} }
} }
else if ( l_u8Mode == 3 ) else if ( l_u8Mode == 3 )
@ -296,32 +406,43 @@ void vRTE_ProcessUartData(void)
} }
vMCAL_DelayTicks(100); vMCAL_DelayTicks(100);
IVEC_ECU_Uart_InitiateTransmit(&g_xEcuUartHandle, 0x01, g_pu8UartBuffer, 0); iECU_UartInitiateTransmit(&g_xEcuUartHandle, 0x01, g_pu8UartBuffer, 0);
} }
if ( eRetCode == 0 && l_u32Id == 0){ if ( eRetCode == 0 && l_u32Id == 0){
IVEC_ECU_Uart_InitiateTransmit(&g_xEcuUartHandle, 0x0, g_pu8UartBuffer, 0); //interface okay response iECU_UartInitiateTransmit(&g_xEcuUartHandle, 0x0, g_pu8UartBuffer, 0); //interface okay response
} }
if ( eRetCode >= 0 && (l_u32Id > 0x00 && l_u32Id < 0xffffffff) ) if ( eRetCode >= 0 && (l_u32Id > 0x00 && l_u32Id < 0xffffffff) )
{ {
//_prvU8Buffer = (_prvU8Buffer + 1) % 2; //_prvU8Buffer = (_prvU8Buffer + 1) % 2;
vECU_WriteDataOverCAN(&g_pu8UartBuffer[IVEC_ECU_UART_PKT_HEADER], l_u32Id, eRetCode, 0); xECU_WriteDataOverCAN(&g_xEcuCanHandle, &g_pu8UartBuffer[IVEC_ECU_UART_PKT_HEADER], l_u32Id, eRetCode, 0);
} }
} }
} }
/**
* @brief Processes CAN data and handles CAN communication.
*
* This function reads incoming CAN data, checks the data for specific conditions (e.g.,
* the CAN ID `0x16` and specific data values `V`, `E`, and `C`), and takes actions accordingly,
* such as initiating a soft reset. If the data matches the conditions, it is transmitted over UART.
* The function also stores received CAN messages in a buffer and tracks the number of messages sent in bursts.
* Once the burst limit is reached, it stops processing additional messages.
*
* @returns None
*/
void vRTE_ProcessCanData(void) void vRTE_ProcessCanData(void)
{ {
IVEC_ECU_CANBuff_s l_xCanBuff = { 0x00 }; IVEC_ECU_CANBuff_s l_xCanBuff = { 0x00 };
volatile uint8_t l_u8TxBurstMessages = 0; volatile uint8_t l_u8TxBurstMessages = 0;
while( vECU_CAN_GetData(&l_xCanBuff) == commonECU_SUCCESS ) while( xECU_CANGetData(&g_xEcuCanHandle, &l_xCanBuff) == commonECU_SUCCESS )
{ {
if( (l_xCanBuff.ulId == 0x16) && (l_xCanBuff.ucData[0] = 'V') && \ if( (l_xCanBuff.ulId == 0x16) && (l_xCanBuff.ucData[0] = 'V') && \
(l_xCanBuff.ucData[1] == 'E') && (l_xCanBuff.ucData[2] == 'C')) (l_xCanBuff.ucData[1] == 'E') && (l_xCanBuff.ucData[2] == 'C'))
{ {
xMCAL_VrefInit(); vMCAL_SoftReset();
} }
IVEC_ECU_Uart_InitiateTransmit(&g_xEcuUartHandle, (uint32_t)l_xCanBuff.ulId, (uint8_t*)&l_xCanBuff.ucData[0], (uint8_t)l_xCanBuff.ucLength); iECU_UartInitiateTransmit(&g_xEcuUartHandle, (uint32_t)l_xCanBuff.ulId, (uint8_t*)&l_xCanBuff.ucData[0], (uint8_t)l_xCanBuff.ucLength);
socTouchDisplay_U.Input[_prvU8Index].ID = l_xCanBuff.ulId; socTouchDisplay_U.Input[_prvU8Index].ID = l_xCanBuff.ulId;
socTouchDisplay_U.Input[_prvU8Index].Length = l_xCanBuff.ucLength; socTouchDisplay_U.Input[_prvU8Index].Length = l_xCanBuff.ucLength;
memcpy(&socTouchDisplay_U.Input[_prvU8Index].Data[0], &l_xCanBuff.ucData[0], 8); memcpy(&socTouchDisplay_U.Input[_prvU8Index].Data[0], &l_xCanBuff.ucData[0], 8);
@ -331,6 +452,6 @@ void vRTE_ProcessCanData(void)
else else
break; break;
} }
vECU_CAN_GetStatus(CANFD0, g_eCanSpeed); xECU_CANGetStatus(&g_xEcuCanHandle);
} }

View File

@ -23,7 +23,16 @@ static const DL_VREF_ClockConfig g_dlVrefClockConfig = {
.divideRatio = DL_VREF_CLOCK_DIVIDE_1, .divideRatio = DL_VREF_CLOCK_DIVIDE_1,
}; };
/* Systick Initialization */ /**
* @brief Initializes the SysTick timer.
*
* Configures the SysTick timer with the specified period and sets the interrupt priority.
*
* @param[in] eTick The period for the SysTick timer.
*
* @return IVEC_CORE_STATUS_SUCCESS if initialization is successful.
*/
IVEC_CoreStatus_e xMCAL_SystickInit(IVEC_SystickPeriod_e eTick) IVEC_CoreStatus_e xMCAL_SystickInit(IVEC_SystickPeriod_e eTick)
{ {
SysTick_Config(eTick); SysTick_Config(eTick);
@ -47,8 +56,19 @@ static const DL_SYSCTL_SYSPLLConfig g_dlSysPllConfig = {
.qDiv = 5, .qDiv = 5,
.pDiv = DL_SYSCTL_SYSPLL_PDIV_1, .pDiv = DL_SYSCTL_SYSPLL_PDIV_1,
}; };
/**
* @brief Initializes the system control settings, including clock source and low power mode.
*
* Configures the power policy, BOR threshold, and flash wait state based on the specified
* low power mode and clock source. It also sets up system PLL and HFCLK parameters accordingly.
*
* @param[in] u8ClkSrc The clock source to use (e.g., HFXT or SYSOSC).
* @param[in] u8LowPowerMode The low power mode to configure (e.g., STANDBY0 or SLEEP0).
*
* @return IVEC_CORE_STATUS_SUCCESS if initialization is successful,
* IVEC_CORE_STATUS_INIT_FAIL if invalid parameters are provided.
*/
/* System Control Initialization */
IVEC_CoreStatus_e xMCAL_SysctlInit(uint8_t u8ClkSrc, uint8_t u8LowPowerMode) IVEC_CoreStatus_e xMCAL_SysctlInit(uint8_t u8ClkSrc, uint8_t u8LowPowerMode)
{ {
if ((u8LowPowerMode != IVEC_STANDBY0) && (u8LowPowerMode != IVEC_SLEEP0)) if ((u8LowPowerMode != IVEC_STANDBY0) && (u8LowPowerMode != IVEC_SLEEP0))
@ -96,16 +116,33 @@ IVEC_CoreStatus_e xMCAL_SysctlInit(uint8_t u8ClkSrc, uint8_t u8LowPowerMode)
return IVEC_CORE_STATUS_SUCCESS; return IVEC_CORE_STATUS_SUCCESS;
} }
/**
* @brief SysTick interrupt handler.
*
* Increments the global tick counter (`g_i32TickCnt`) each time the SysTick interrupt occurs.
*/
void SysTick_Handler(void) void SysTick_Handler(void)
{ {
g_i32TickCnt++; g_i32TickCnt++;
} }
/**
* @brief Retrieves the current tick count.
*
* @return The current tick count stored in `g_i32TickCnt`.
*/
int32_t i32MCAL_GetTicks() int32_t i32MCAL_GetTicks()
{ {
return g_i32TickCnt; return g_i32TickCnt;
} }
/**
* @brief Delays execution for a specified number of milliseconds based on tick count.
*
* Waits until the number of ticks has passed corresponding to the input delay (in milliseconds).
*
* @param[in] i32DelayMs The delay in milliseconds to wait.
*/
void vMCAL_DelayTicks(int32_t i32DelayMs) void vMCAL_DelayTicks(int32_t i32DelayMs)
{ {
@ -116,17 +153,38 @@ void vMCAL_DelayTicks(int32_t i32DelayMs)
/* Wait */ /* Wait */
} }
} }
/**
* @brief Initializes the MCU by configuring power and GPIO settings.
*
* Calls the necessary functions to initialize power and GPIO configurations for the MCU.
*/
void vMCAL_McuInit(void) void vMCAL_McuInit(void)
{ {
SYSCFG_DL_initPower(); SYSCFG_DL_initPower();
SYSCFG_DL_GPIO_init(); SYSCFG_DL_GPIO_init();
} }
/**
* @brief Delays execution for a specified number of microseconds.
*
* Uses a cycle-based delay function to wait for the specified duration in microseconds.
*
* @param[in] u32Us The delay duration in microseconds.
*/
void vMCAL_DelayUs(uint32_t u32Us) void vMCAL_DelayUs(uint32_t u32Us)
{ {
delay_cycles(32 * u32Us); delay_cycles(32 * u32Us);
} }
/**
* @brief Initializes the voltage reference (VREF) system.
*
* Configures the clock and reference settings for the VREF system. If already initialized,
* it returns a failure status.
*
* @return IVEC_MCAL_STATUS_SUCCESS if initialization is successful,
* IVEC_MCAL_STATUS_INIT_FAIL if VREF is already initialized.
*/
IVEC_McalStatus_e xMCAL_VrefInit(void) IVEC_McalStatus_e xMCAL_VrefInit(void)
{ {
@ -143,6 +201,11 @@ IVEC_McalStatus_e xMCAL_VrefInit(void)
return IVEC_MCAL_STATUS_INIT_FAIL; return IVEC_MCAL_STATUS_INIT_FAIL;
} }
} }
/**
* @brief Performs a soft reset on the MCU.
*
* Resets the MCU's CPU by calling the appropriate system control function.
*/
void vMCAL_SoftReset(void) void vMCAL_SoftReset(void)
{ {

View File

@ -51,15 +51,7 @@ typedef enum
IVEC_UART_BAUD_9600 = 1, IVEC_UART_BAUD_9600 = 1,
} IVEC_UartBaud_e; } IVEC_UartBaud_e;
/* CAN Baud Rate Options */
typedef enum
{
IVEC_CAN_BAUD_500 = 500,
IVEC_CAN_BAUD_250 = 250,
IVEC_CAN_BAUD_150 = 150,
IVEC_CAN_BAUD_1000 = 1000,
IVEC_CAN_BAUD_125 = 125,
} IVEC_CanBaud_e;
/* SPI Clock Speed Options */ /* SPI Clock Speed Options */
typedef enum typedef enum