/* * ivec_rte.c * * Created on: 28-Oct-2024 * Author: altam */ #include "ivec_rte.h" #include "ivec_cmplx_queue.h" #include "ivec_cmplx_vFrame.h" #include "../ivec_ECU/ivec_ecu_uart/inc/ivec_ecu_uart.h" #include "../ivec_ECU/ivec_ecu_can/inc/ivec_ecu_can.h" #include "../../Core/Include/ivec_mcal_gpio.h" #include "socTouchDisplay.h" #include "../../TM1650_SDK/inc/ivec_TM1650.h" #include"ivec_bsw_nfc.h" #include "ivec_rte.h" // UART Handles IVEC_EcuUartHandle_s g_xUartHandle = {0}; IVEC_EcuUartHandle_s __gprv_UartCcHandle = {0}; IVEC_EcuCANHandle_s g_xCanHandle = {0}; // Configuration Macros #define rteCONFIG_BASIL_BATTERY_SMART_u8 1 #define rteCONFIG_BASIL_u8 2 #define rteCONFIG_MOTHER_BOARD_u8 3 // UART Configuration #define rteUART_PIN_SELECTION_u8 rteCONFIG_BASIL_BATTERY_SMART_u8 uint8_t g_pu8UartBuffer[ecuUART_MAX_PACKET_LENGTH_u8] = {0}; volatile uint32_t g_u32CanId = 0x1FFFFFFF; // CAN UART Buffer #define eteCAN_UART_BUFFER_MAX_SIZE_u32 4096 volatile uint8_t g_prvU8CanUartDataBuffer[eteCAN_UART_BUFFER_MAX_SIZE_u32]; // CAN Filters bool g_bl_bIsExtendedId[ecuMAX_FILTERS_u8]; // Filter Information uint16_t g_u16ExtendedFilter = 0; uint16_t g_u16StandardFilter = 0; // Private Static Variables static uint8_t __gprv_U8Index = 0; // External Variables extern ExtU_socTouchDisplay_T socTouchDisplay_U; extern ExtY_socTouchDisplay_T socTouchDisplay_Y; #define CAN_UART_BUFFER_MAX_SIZE 300 uint8_t g_prv_u8CANUartDataBuffer[CAN_UART_BUFFER_MAX_SIZE]; uint32_t g_prv_u32CanUartDataAvailable = 0; // CAN UART Buffer #define eteCAN_UART_Cc_BUFFER_MAX_SIZE_u32 4096 volatile uint8_t __gprv_u8CcUartDataBuffer[eteCAN_UART_Cc_BUFFER_MAX_SIZE_u32]; uint8_t g_u8SmdReceived = 0; IVEC_EcuCommonCanFrame_s g_xSmdCanMsg = {0}; int32_t g_u32LastSendTick = 0; // Last time we sent over CAN/UART /** * @brief Sets the state of the MCU temperature data pin (SDA) for TM1650. * * @param[in] u8State The state to set on the SDA pin (0 for low, 1 for high). * * @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) { if(u8State == 0){ vMCAL_gpioWrite(TM1650_PORT, TM1650_SDA_PIN_PIN, 0); } else if(u8State == 1){ vMCAL_gpioWrite(TM1650_PORT, TM1650_SDA_PIN_PIN, 1); } } /** * @brief Sets the state of the MCU temperature clock pin (SCL) for TM1650. * * @param[in] u8State The state to set on the SCL pin (0 for low, 1 for high). * * @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) { if(u8State == 0){ vMCAL_gpioWrite(TM1650_PORT, TM1650_SCL_PIN_PIN, 0); } else if(u8State == 1){ vMCAL_gpioWrite(TM1650_PORT, TM1650_SCL_PIN_PIN, 1); } } /** * @brief Reads the state of the MCU temperature data pin (SDA) for TM1650. * * This function configures the SDA pin as an input, reads the pin state, * 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 _prv_RteReadMcuTempPin(void) { uint8_t l_u8ReadBuffer = 0; vMCAL_setGpioDirection(TM1650_SDA_PIN_IOMUX,false); l_u8ReadBuffer = u32MCAL_gpioRead(TM1650_PORT, TM1650_SDA_PIN_PIN); vMCAL_setGpioDirection(TM1650_SDA_PIN_IOMUX,true); 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) { 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 , &_prv_RteReadMcuTempPin); tm1650_displaySwitch(TM_1650_Screen_OFF); vMCAL_delayTicks(500); tm1650_showDot(TM_1650_DIG_1,false); tm1650_showDot(TM_1650_DIG_2,false); tm1650_showDot(TM_1650_DIG_3,false); socTouchDisplay_initialize(); } void vRTE_InitUartCc(void) { __gprv_UartCcHandle.u8Qbuffer = __gprv_u8CcUartDataBuffer; __gprv_UartCcHandle.u16QbufSize = eteCAN_UART_Cc_BUFFER_MAX_SIZE_u32; __gprv_UartCcHandle.eUartPortNumber = IVEC_ECU_UART_PORT4; __gprv_UartCcHandle.u32BaudRate = IVEC_ECU_UART_BAUD_230400; xECU_UartInit(&__gprv_UartCcHandle); } /** * @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) { socTouchDisplay_U.in_bTouchDetected = (u32MCAL_gpioRead(GPIOB, DL_GPIO_PIN_17) == DL_GPIO_PIN_17) ? 1 : 0; socTouchDisplay_U.ip_u32DisplayDuration_msec = 10000; socTouchDisplay_U.ip_u32TouchDuration_msec = 100; socTouchDisplay_U.ip_u32canId = g_u32CanId; socTouchDisplay_step(); memset(&socTouchDisplay_U.Input[0], 0, sizeof(CAN_MESSAGE_BUS)*MAX_CAN_MESSAGE_INSTANCE); __gprv_U8Index = 0; if( socTouchDisplay_Y.op_bDisplayStatus ) { tm1650_displaySwitch(TM_1650_Screen_ON); tm1650_showDot(TM_1650_DIG_1,false); tm1650_showDot(TM_1650_DIG_2,false); tm1650_showDot(TM_1650_DIG_3,false); if( socTouchDisplay_Y.op_u8HundredsPlace == 1 && \ socTouchDisplay_Y.op_u8TensPlace == 0 && \ socTouchDisplay_Y.op_u8OnesPlace == 0) { char l_cData = 'F'; tm1650_showAlphabet(TM_1650_DIG_2, (char*)&l_cData); l_cData = 'C'; tm1650_showAlphabet(TM_1650_DIG_3, (char*)&l_cData); } else { tm1650_showNum(TM_1650_DIG_3, socTouchDisplay_Y.op_u8OnesPlace); tm1650_showNum(TM_1650_DIG_2, socTouchDisplay_Y.op_u8TensPlace); } // tm1650_showNum(TM_1650_DIG_1, socTouchDisplay_Y.op_u8HundredsPlace); } if( socTouchDisplay_Y.op_bErrorStatus ) { tm1650_displaySwitch(TM_1650_Screen_ON); tm1650_showDot(TM_1650_DIG_1,false); tm1650_showDot(TM_1650_DIG_2,false); tm1650_showDot(TM_1650_DIG_3,false); char l_cData = 'R'; l_cData = 'C'; tm1650_showAlphabet(TM_1650_DIG_2, (char*)&l_cData); l_cData = 'E'; tm1650_showAlphabet(TM_1650_DIG_3, (char*)&l_cData); } if( !socTouchDisplay_Y.op_bDisplayStatus && !socTouchDisplay_Y.op_bErrorStatus ) { 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) { #if rteUART_PIN_SELECTION_u8 == 1 vRTE_MatlabInit(); vRTE_InitUartCc(); #endif vRTE_InitUartCanEcho(); // Uncomment for UART-to-CAN transmission, if required // iECU_UartInitiateTransmit(&g_xUartHandle, 0x6, NULL, 0); // xECU_WriteDataOverCAN(&g_xCanHandle, NULL , 0x6, 1, 0); #if rteUART_PIN_SELECTION_u8 == 3 vRTE_NfcInit(); #endif } /** * @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) { g_xUartHandle.u8Qbuffer = g_prvU8CanUartDataBuffer; g_xUartHandle.u16QbufSize = eteCAN_UART_BUFFER_MAX_SIZE_u32; #if (rteUART_PIN_SELECTION_u8 == 1) g_xUartHandle.eUartPortNumber = IVEC_ECU_UART_PORT3; g_xUartHandle.u32BaudRate = IVEC_ECU_UART_BAUD_115200; #elif (rteUART_PIN_SELECTION_u8 == 2) g_xUartHandle.eUartPortNumber = IVEC_ECU_UART_PORT2; g_xUartHandle.u32BaudRate = IVEC_ECU_UART_BAUD_115200; #elif (rteUART_PIN_SELECTION_u8 == 3) g_xUartHandle.eUartPortNumber = IVEC_ECU_UART_PORT2; g_xUartHandle.u32BaudRate = IVEC_ECU_UART_BAUD_115200; #endif xECU_UartInit(&g_xUartHandle); g_xCanHandle.u16Speed = IVEC_ECU_CAN_SPEED_500; g_xCanHandle.pMCAN = CANFD0; g_xCanHandle.i32MaskCount = -1; g_xCanHandle.i32FilterCount = -1; for (int i = 0; i < ecuMAX_FILTERS_u8; ++i) { g_xCanHandle.u32MaskValues[i] = 0; g_xCanHandle.u32FilterValues[i] = 0; } xECU_CANInit(&g_xCanHandle); } void vRTE_NfcInit(void) { bBSW_NfcInit(); } /** * @brief Initializes the application run processes. * * This function processes UART and CAN data to perform necessary tasks during * the application runtime. * * @returns None */ volatile bool g_bConfigured = false; extern uint8_t u8MCAL_StoreMsgFromISRToQueue(uint32_t u32UlId, uint8_t* pu8Data, uint8_t u8Len); void vRTE_UartNfcProcess(void) { static uint32_t a = 0; if (i32MCAL_getTicks() - a > 2000 || g_bConfigured == false) // if(g_bConfigured==false) { a = i32MCAL_getTicks(); if (bBSW_NfcTest()) { if (g_bConfigured == false) { bBSW_NfcConfigure();//todo: make it one time call g_bConfigured = true; } i328BSW_NfcAutoPollMIFARE(); } else { g_bConfigured = false; } } else { uint8_t l_pu8Uid[16] = { 0 }; int l_UidLen = i328BSW_NfcScanMIFARE(l_pu8Uid); if (l_UidLen > 0) { a = i32MCAL_getTicks(); uint8_t l_pu8Keyb[] = { 0xff,0xff,0xff,0xff,0xff,0xff }; uint8_t l_pu8NfcData[32] = { 0 }; IVEC_RTE_LOG("Found MIFARE card with UID: %02x %02x %02x %02x ", l_pu8Uid[0], l_pu8Uid[1], l_pu8Uid[2], l_pu8Uid[3]); if (bBSW_NfcMifareClassicDataRead(l_pu8Uid, l_UidLen, 8, l_pu8Keyb, IVEC_BSW_NFC_MIFRAE_AUTH_B, l_pu8NfcData)) { IVEC_RTE_LOG("Nfc Read 8"); for (int i = 0;i < 16;i++) { IVEC_RTE_LOG("Block 8[%d]->0x%02x", i, l_pu8NfcData[i]); } } if (bBSW_NfcMifareClassicDataRead(l_pu8Uid, l_UidLen, 9, l_pu8Keyb, IVEC_BSW_NFC_MIFRAE_AUTH_B, &l_pu8NfcData[16])) { // g_bConfigured = false; IVEC_RTE_LOG("Nfc Read 9"); for (int i = 0;i < 16;i++) { IVEC_RTE_LOG("Block 9[%d]->0x%02x", i, l_pu8NfcData[i]); } } //1->4bytesuid //2-4->block8 //5-7->block9 uint8_t l_u8NfcCanData[8] = { 0 }; l_u8NfcCanData[0] = 1; for (int i = 0;i < 4;i++) l_u8NfcCanData[i + 1] = l_pu8Uid[i]; u8MCAL_StoreMsgFromISRToQueue(0x76969, l_u8NfcCanData, 8); l_u8NfcCanData[0] = 2; for (int i = 0;i < 7;i++) l_u8NfcCanData[i + 1] = l_pu8NfcData[i]; u8MCAL_StoreMsgFromISRToQueue(0x76969, l_u8NfcCanData, 8); l_u8NfcCanData[0] = 3; for (int i = 0;i < 7;i++) l_u8NfcCanData[i + 1] = l_pu8NfcData[7 + i]; u8MCAL_StoreMsgFromISRToQueue(0x76969, l_u8NfcCanData, 8); memset(l_u8NfcCanData,0,8); l_u8NfcCanData[0] = 4; for (int i = 0;i < 2;i++) l_u8NfcCanData[i + 1] = l_pu8NfcData[14 + i]; u8MCAL_StoreMsgFromISRToQueue(0x76969, l_u8NfcCanData, 8); l_u8NfcCanData[0] = 5; for (int i = 0;i < 7;i++) l_u8NfcCanData[i + 1] = l_pu8NfcData[16 + i]; u8MCAL_StoreMsgFromISRToQueue(0x76969, l_u8NfcCanData, 8); l_u8NfcCanData[0] = 6; for (int i = 0;i < 7;i++) l_u8NfcCanData[i + 1] = l_pu8NfcData[23 + i]; u8MCAL_StoreMsgFromISRToQueue(0x76969, l_u8NfcCanData, 8); memset(l_u8NfcCanData,0,8); l_u8NfcCanData[0] = 7; for (int i = 0;i < 2;i++) l_u8NfcCanData[i + 1] = l_pu8NfcData[30 + i]; u8MCAL_StoreMsgFromISRToQueue(0x76969, l_u8NfcCanData, 8); } } } void vRTE_AppRun(void) { vRTE_ProcessUartData(); vRTE_ProcessCanData(); #if rteUART_PIN_SELECTION_u8 == 1 vRTE_CcUartRxProcess(); #endif #if rteUART_PIN_SELECTION_u8 == 3 vRTE_UartNfcProcess(); #endif } /** * @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) { #if rteUART_PIN_SELECTION_u8 == 1 vRTE_MatlabRun(); #endif 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] bl_bIsExtended Flag indicating whether the mask applies to extended IDs. * * @returns None */ void vRTE_CanFilterMaskSaveVal(uint8_t u8Idx, uint32_t u32Mask, bool bl_bIsExtended) { g_xCanHandle.i32MaskCount = u8Idx; g_xCanHandle.u32MaskValues[g_xCanHandle.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] bl_bIsExtended Flag indicating whether the filter applies to extended IDs. * * @returns None */ void vRTE_CanFilterSaveVal(uint8_t u8Idx, uint32_t u32Filter, bool bl_bIsExtended) { g_xCanHandle.i32FilterCount = u8Idx; // Store filter value g_xCanHandle.u32FilterValues[g_xCanHandle.i32FilterCount] = u32Filter; } //IVEC_EcuCommonCanFrame_s g_xSmdCanMsg = {0}; // Global message buffer //uint8_t g_u8SmdReceived = 0; uint32_t g_u32LastSmdTick = 0; void vCcUartRxToCanTx(IVEC_EcuCommonCanFrame_s* pxCanMsg) { if( (pxCanMsg->u32CanId == 0x16) && (pxCanMsg->pucCanData[0] == 'V') && \ (pxCanMsg->pucCanData[1] == 'E') && (pxCanMsg->pucCanData[2] == 'C') && \ (pxCanMsg->pucCanData[3] == 'I') && (pxCanMsg->pucCanData[4]== 'O') && \ (pxCanMsg->pucCanData[5] == 'T')) { uint32_t l_u32Id = 0x36; // ID to pass uint8_t pu8Data[1] = {0x79}; // Data array containing 0x79 uint8_t u8Len = sizeof(pu8Data); // Length of data array int l_i32RetSize = 0; uint8_t l_u8UartBuffer[30] = { 0 }; int l_i32Status = -1; l_i32RetSize = u16CMPLX_vFrameEncode((uint32_t)l_u32Id, (uint8_t*)&pu8Data[1], u8Len, l_u8UartBuffer, 30); l_i32Status = IVEC_ECUUartWrite(&__gprv_UartCcHandle, l_u8UartBuffer, l_i32RetSize); vMCAL_softReset(); } if(pxCanMsg->ucCanDlc > 0 && pxCanMsg->u32CanId == 0x00) { uint32_t l_u32Baudrate = 0; uint8_t l_u8Mode = pxCanMsg->pucCanData[0];//g_pu8UartBuffer[ecuUART_PKT_HEADER_u8]; memcpy(&l_u32Baudrate, &pxCanMsg->pucCanData[1], (uint32_t)pxCanMsg->ucCanDlc); iECU_UartInitiateTransmit(&g_xUartHandle, 0x01,(uint8_t*)&pxCanMsg->pucCanData[0],0); if( l_u8Mode == 0 ) { __gprv_UartCcHandle.u32BaudRate = l_u32Baudrate; xECU_UartReinit(&__gprv_UartCcHandle); } else if( l_u8Mode == 1 ) { g_xCanHandle.u16Speed = (uint16_t)l_u32Baudrate; xECU_CANReInit(&g_xCanHandle); } else if( l_u8Mode == 2 ) { if( pxCanMsg->pucCanData[1] != 0 ){//22(20+2) rx filter available send each id in a frame uint32_t l_U32FilterId = 0; memcpy(&l_U32FilterId, &pxCanMsg->pucCanData[3], sizeof(uint32_t)); bool l_bIsExtended = 0; l_bIsExtended = (l_U32FilterId > 0x7FF); // Standard IDs are <= 0x7FF vRTE_CanFilterSaveVal((pxCanMsg->pucCanData[1] - 1), l_U32FilterId, l_bIsExtended); if( pxCanMsg->pucCanData[2])//All filter received. Trigger Filter Settings { xECU_CANReInit(&g_xCanHandle); } else return; } else{ xECU_CANReInit(&g_xCanHandle); } } else if ( l_u8Mode == 3 ) { if( (pxCanMsg->pucCanData[1] < 1) || (pxCanMsg->pucCanData[1] > 8) )//0-7 maximum received pkts return; uint32_t l_u32u32MaskId = 0; memcpy(&l_u32u32MaskId, &pxCanMsg->pucCanData[3], sizeof(uint32_t)); bool l_bIsExtended = 0; l_bIsExtended = (l_u32u32MaskId > 0x7FF); // Standard IDs are <= 0x7FF vRTE_CanFilterMaskSaveVal((pxCanMsg->pucCanData[1] - 1), l_u32u32MaskId, l_bIsExtended); } else if (l_u8Mode == 100) { g_u32CanId = l_u32Baudrate; return; } vMCAL_delayTicks(100); iECU_UartInitiateTransmit(&g_xUartHandle, 0x01,(uint8_t*)&pxCanMsg->pucCanData[0],0); } if(pxCanMsg->u32CanId != 0x00) { if (pxCanMsg->u32CanId == 0x1cea6969) { iECU_UartInitiateTransmit(&g_xUartHandle, (uint32_t)pxCanMsg->u32CanId,(uint8_t*)&pxCanMsg->pucCanData[0],(uint8_t)pxCanMsg->ucCanDlc); } else { if(pxCanMsg->u32CanId == 0xabcdef) { pxCanMsg->u32CanId = g_u32CanId; } if (pxCanMsg->u32CanId == 0x696972) { g_xSmdCanMsg = *pxCanMsg; // Store the latest data g_u8SmdReceived = 1; // Flag to indicate data is fresh // Add touch info uint32_t l_u32TouchDetect = DL_GPIO_readPins(GPIOB, GPIO_GRP_0_soc_PIN); if (g_xSmdCanMsg.pucCanData[0] == 0) { g_xSmdCanMsg.pucCanData[0] = 0x2; } g_xSmdCanMsg.pucCanData[1] = (uint8_t)((l_u32TouchDetect >> 17) & 0x1); } // if(pxCanMsg->u32CanId == 0x696972) // { // g_u8SmdReceived = 1; // IVEC_EcuCommonCanFrame_s xMyCanMsg; // // g_u32LastSmdTick = i32MCAL_getTicks(); // Store time of last valid message // //// // Copy entire struct in one line //// g_xSmdCanMsg = *pxCanMsg; // // uint32_t l_u32TouchDetect = DL_GPIO_readPins(GPIOB, GPIO_GRP_0_soc_PIN); // if(pxCanMsg->pucCanData[0] == 0) // { // pxCanMsg->pucCanData[0] = 0x2; // } // // pxCanMsg->pucCanData[1] = (uint8_t)((l_u32TouchDetect >> 17) & 0x1); // // // Send immediately // iECU_UartInitiateTransmit(&g_xUartHandle, (uint32_t)pxCanMsg->u32CanId,(uint8_t*)&pxCanMsg->pucCanData[0],(uint8_t)pxCanMsg->ucCanDlc); // } if(pxCanMsg->u32CanId != 0x696972) xECU_WriteDataOverCAN(&g_xCanHandle, &pxCanMsg->pucCanData[0], pxCanMsg->u32CanId, pxCanMsg->ucCanDlc, 0); } } } void vRTE_CcUartRxProcess(void) { static int __prv_i32BfrIdx = 0; g_prv_u32CanUartDataAvailable = xECU_data_length(&__gprv_UartCcHandle); // // uint32_t u32CurrentTick = i32MCAL_getTicks(); // // // If no message in last 5 sec // if ((u32CurrentTick - g_u32LastSmdTick) >= 5000) // { // uint32_t l_u32TouchDetect = DL_GPIO_readPins(GPIOB, GPIO_GRP_0_soc_PIN); // // IVEC_EcuCommonCanFrame_s g_xSmdCanMsg = {0}; // g_xSmdCanMsg.u32CanId = 0x696972; // g_xSmdCanMsg.ucCanDlc = 8; // g_xSmdCanMsg.pucCanData[0] = 0; // g_xSmdCanMsg.pucCanData[1] = (uint8_t)((l_u32TouchDetect >> 17) & 0x1); // iECU_UartInitiateTransmit(&g_xUartHandle, (uint32_t)g_xSmdCanMsg.u32CanId,(uint8_t*)&g_xSmdCanMsg.pucCanData[0],(uint8_t)g_xSmdCanMsg.ucCanDlc); // xECU_WriteDataOverCAN(&g_xCanHandle, &g_xSmdCanMsg.pucCanData[0], g_xSmdCanMsg.u32CanId, g_xSmdCanMsg.ucCanDlc, 0); // // g_u32LastSmdTick = u32CurrentTick; // } uint32_t u32CurrentTick = i32MCAL_getTicks(); if ((u32CurrentTick - g_u32LastSendTick) >= 5000) { IVEC_EcuCommonCanFrame_s xMsgToSend = {0}; if (g_u8SmdReceived == 1) { xMsgToSend = g_xSmdCanMsg; g_u8SmdReceived = 0; // Reset flag after sending } else { xMsgToSend.u32CanId = 0x696972; xMsgToSend.ucCanDlc = 8; xMsgToSend.pucCanData[0] = 0; uint32_t l_u32TouchDetect = DL_GPIO_readPins(GPIOB, GPIO_GRP_0_soc_PIN); xMsgToSend.pucCanData[1] = (uint8_t)((l_u32TouchDetect >> 17) & 0x1); } iECU_UartInitiateTransmit(&g_xUartHandle, xMsgToSend.u32CanId, xMsgToSend.pucCanData, xMsgToSend.ucCanDlc); xECU_WriteDataOverCAN(&g_xCanHandle, xMsgToSend.pucCanData, xMsgToSend.u32CanId, xMsgToSend.ucCanDlc, 0); g_u32LastSendTick = u32CurrentTick; // Update last send time } int l_u32AvailableData = g_prv_u32CanUartDataAvailable > (CAN_UART_BUFFER_MAX_SIZE - __prv_i32BfrIdx) ? (CAN_UART_BUFFER_MAX_SIZE - __prv_i32BfrIdx) : g_prv_u32CanUartDataAvailable; if ((l_u32AvailableData <= 10 && g_prv_u32CanUartDataAvailable > 10)|| (__prv_i32BfrIdx+l_u32AvailableData)>=CAN_UART_BUFFER_MAX_SIZE) { // printf("Data Overflow detected:%d-%d\n", g_prv_u32CanUartDataAvailable, __prv_i32BfrIdx); __prv_i32BfrIdx = 0; l_u32AvailableData = 0; } if (1) { //record uart recv uint8_t l_u8Goon=0; if (l_u32AvailableData && xECU_UartGetData(&__gprv_UartCcHandle, &g_prv_u8CANUartDataBuffer[__prv_i32BfrIdx], l_u32AvailableData, 3000) == commonECU_SUCCESS) l_u8Goon=1; if(l_u32AvailableData<=0 && __prv_i32BfrIdx>0) l_u8Goon=1; if(l_u8Goon) { // g_prv_u32CanUartDataAvailable -= l_u32AvailableData; __prv_i32BfrIdx += l_u32AvailableData; uint8_t* l_ucStart = g_prv_u8CANUartDataBuffer; uint8_t* l_ucFrameStart = NULL; uint8_t* l_ucFrameEnd = NULL; IVEC_ECU_LOG(LOG_STRING, "New Data:%d-%d", l_u32AvailableData, __prv_i32BfrIdx); while (1) { // IVEC_ECU_LOG(LOG_STRING, "Current Idx:%d", __prv_i32BfrIdx); int l_i32Len = __prv_i32BfrIdx; if (u16CMPLX_vFrameFind(l_ucStart, l_i32Len, &l_ucFrameStart, &l_ucFrameEnd) == 2)//cksum error { // xCANhandle->xMyMetrics.u32CANCommFrameErrors++; } if (l_ucFrameStart == NULL) { __prv_i32BfrIdx = 0; break; } if (l_ucFrameEnd == NULL) { if (memmove(g_prv_u8CANUartDataBuffer, l_ucFrameStart, __prv_i32BfrIdx) != g_prv_u8CANUartDataBuffer) { __prv_i32BfrIdx = 0; IVEC_ECU_LOG(LOG_STRING, "Never Print"); } __prv_i32BfrIdx-=(l_ucFrameStart-g_prv_u8CANUartDataBuffer); if(__prv_i32BfrIdx<0) __prv_i32BfrIdx=0; break; } IVEC_EcuCommonCanFrame_s l_xCanFrame = { 0 }; uint8_t l_u8UartFrameLen = l_ucFrameEnd - l_ucFrameStart + 1; int l_CanDlc=0; u16CMPLX_vFrameDecode(l_ucFrameStart, l_u8UartFrameLen, &l_xCanFrame.pucCanData,8,&l_CanDlc,&l_xCanFrame.u32CanId); l_xCanFrame.ucCanDlc = l_CanDlc; vCcUartRxToCanTx(&l_xCanFrame); memset(l_ucFrameStart, 0, l_u8UartFrameLen); l_ucStart = ++l_ucFrameEnd; __prv_i32BfrIdx -= l_u8UartFrameLen; if (__prv_i32BfrIdx < 0) __prv_i32BfrIdx = 0; } // printf( "Out Current Idx:%d\n", __prv_i32BfrIdx); } } } /** * @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) { IVEC_ECU_UartPacketRetCode_e l_eRetCode = ecuUART_PACKET_FAIL_i8; uint32_t l_u32Id = 0x1fffffff; l_eRetCode= xECU_UartReadCANDataOverUART(&g_xUartHandle,g_pu8UartBuffer,&l_u32Id); l_u32Id &= 0x1fffffff; uint16_t l_u16Len = 0; if(l_eRetCode > -1) { if( (l_u32Id == 0x16) && (g_pu8UartBuffer[ecuUART_PKT_HEADER_u8] == 'V') && \ (g_pu8UartBuffer[ecuUART_PKT_HEADER_u8 + 1] == 'E') &&(g_pu8UartBuffer[ecuUART_PKT_HEADER_u8 + 2] == 'C') && \ (g_pu8UartBuffer[ecuUART_PKT_HEADER_u8 + 3] == 'I') && (g_pu8UartBuffer[ecuUART_PKT_HEADER_u8 + 4] == 'O') && \ (g_pu8UartBuffer[ecuUART_PKT_HEADER_u8 + 5] == 'T')) { uint32_t u32Id = 0x36; // ID to pass uint8_t pu8Data[1] = {0x79}; // Data array containing 0x79 uint8_t u8Len = sizeof(pu8Data); // Length of data array iECU_UartInitiateTransmit(&g_xUartHandle, u32Id, pu8Data, u8Len); iECU_UartInitiateTransmit(&g_xUartHandle, 0x8, NULL, 0); vMCAL_softReset(); } if(l_eRetCode > 0 && l_u32Id == 0x00) { uint32_t l_u32Baudrate = 0; uint8_t l_u8Mode = g_pu8UartBuffer[ecuUART_PKT_HEADER_u8]; memcpy(&l_u32Baudrate, &g_pu8UartBuffer[ecuUART_PKT_HEADER_u8+1], (uint32_t)l_eRetCode); iECU_UartInitiateTransmit(&g_xUartHandle, 0x01, g_pu8UartBuffer, 0); if( l_u8Mode == 0 ) { g_xUartHandle.u32BaudRate = l_u32Baudrate; xECU_UartReinit(&g_xUartHandle); } else if( l_u8Mode == 1 ) { g_xCanHandle.u16Speed = (uint16_t)l_u32Baudrate;; xECU_CANReInit(&g_xCanHandle); } else if( l_u8Mode == 2 ) { if( g_pu8UartBuffer[ecuUART_PKT_HEADER_u8+1] != 0 ){//22(20+2) rx filter available send each id in a frame uint32_t l_U32FilterId = 0; memcpy(&l_U32FilterId, &g_pu8UartBuffer[ecuUART_PKT_HEADER_u8+3], sizeof(uint32_t)); bool l_bIsExtended = 0; l_bIsExtended = (l_U32FilterId > 0x7FF); // Standard IDs are <= 0x7FF vRTE_CanFilterSaveVal((g_pu8UartBuffer[ecuUART_PKT_HEADER_u8+1] - 1), l_U32FilterId, l_bIsExtended); if( g_pu8UartBuffer[ecuUART_PKT_HEADER_u8+2] )//All filter received. Trigger Filter Settings { xECU_CANReInit(&g_xCanHandle); } else return; } else{ xECU_CANReInit(&g_xCanHandle); } } else if ( l_u8Mode == 3 ) { if( (g_pu8UartBuffer[ecuUART_PKT_HEADER_u8+1] < 1) || (g_pu8UartBuffer[ecuUART_PKT_HEADER_u8+1] > 8) )//0-7 maximum received pkts return; uint32_t l_u32u32MaskId = 0; memcpy(&l_u32u32MaskId, &g_pu8UartBuffer[ecuUART_PKT_HEADER_u8+3], sizeof(uint32_t)); bool l_bIsExtended = 0; l_bIsExtended = (l_u32u32MaskId > 0x7FF); // Standard IDs are <= 0x7FF vRTE_CanFilterMaskSaveVal((g_pu8UartBuffer[ecuUART_PKT_HEADER_u8+1] - 1), l_u32u32MaskId, l_bIsExtended); } else if (l_u8Mode == 100) { g_u32CanId = l_u32Baudrate; return; } vMCAL_delayTicks(100); iECU_UartInitiateTransmit(&g_xUartHandle, 0x01, g_pu8UartBuffer, 0); } if ( l_eRetCode == 0 && l_u32Id == 0){ iECU_UartInitiateTransmit(&g_xUartHandle, 0x0, g_pu8UartBuffer, 0); //interface okay response } if ( l_eRetCode >= 0 && (l_u32Id > 0x00 && l_u32Id < 0xffffffff) ) { //_prvU8Buffer = (_prvU8Buffer + 1) % 2; if(l_u32Id == 0x1cecff69) { int l_i32RetSize = 0; uint8_t l_u8UartBuffer[30] = { 0 }; int l_i32Status = -1; l_i32RetSize = u16CMPLX_vFrameEncode((uint32_t)l_u32Id, (uint8_t*)&g_pu8UartBuffer[ecuUART_PKT_HEADER_u8], (int32_t)l_eRetCode, l_u8UartBuffer, 30); l_i32Status = IVEC_ECUUartWrite(&__gprv_UartCcHandle, l_u8UartBuffer, l_i32RetSize); } xECU_WriteDataOverCAN(&g_xCanHandle, &g_pu8UartBuffer[ecuUART_PKT_HEADER_u8], l_u32Id, l_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) { IVEC_ECU_CANBuff_s l_xCanBuff = { 0x00 }; volatile uint8_t l_u8TxBurstMessages = 0; while( xECU_CANGetData(&g_xCanHandle, &l_xCanBuff) == commonECU_SUCCESS ) { if( (l_xCanBuff.u32UlId == 0x16) && (l_xCanBuff.u8Data[0] = 'V') && \ (l_xCanBuff.u8Data[1] == 'E') && (l_xCanBuff.u8Data[2] == 'C') && \ (l_xCanBuff.u8Data[3] == 'I') && (l_xCanBuff.u8Data[4] == 'O') && \ (l_xCanBuff.u8Data[5] == 'T')) { vMCAL_softReset(); } #if rteUART_PIN_SELECTION_u8 == 1 int l_i32RetSize = 0; uint8_t l_u8UartBuffer[30] = { 0 }; int l_i32Status = -1; l_i32RetSize = u16CMPLX_vFrameEncode((uint32_t)l_xCanBuff.u32UlId, (uint8_t*)&l_xCanBuff.u8Data[0], (int32_t)l_xCanBuff.u8Length, l_u8UartBuffer, 30); if(l_xCanBuff.u32UlId == g_u32CanId) { l_i32RetSize = u16CMPLX_vFrameEncode((uint32_t)0xabcdef, (uint8_t*)&l_xCanBuff.u8Data[0], (int32_t)l_xCanBuff.u8Length, l_u8UartBuffer, 30); } l_i32Status = IVEC_ECUUartWrite(&__gprv_UartCcHandle, l_u8UartBuffer, l_i32RetSize); #endif iECU_UartInitiateTransmit(&g_xUartHandle, (uint32_t)l_xCanBuff.u32UlId, (uint8_t*)&l_xCanBuff.u8Data[0], (uint8_t)l_xCanBuff.u8Length); socTouchDisplay_U.Input[__gprv_U8Index].ID = l_xCanBuff.u32UlId; socTouchDisplay_U.Input[__gprv_U8Index].Length = l_xCanBuff.u8Length; memcpy(&socTouchDisplay_U.Input[__gprv_U8Index].Data[0], &l_xCanBuff.u8Data[0], 8); __gprv_U8Index = (__gprv_U8Index + 1) % MAX_CAN_MESSAGE_INSTANCE; if(l_u8TxBurstMessages < 16) l_u8TxBurstMessages++; else break; } xECU_CANGetStatus(&g_xCanHandle); }