572 lines
22 KiB
C
572 lines
22 KiB
C
#include "../ivec_ECU/ivec_ecu_uart/inc/ivec_ecu_uart.h"
|
|
#include "ivec_cmplx_queue.h"
|
|
#include "../Core/Include/ivec_mcal_uart.h"
|
|
|
|
#define LOG_STRING "ivec-ecu-UART"
|
|
//#define NFC_UART_BUFFER_MAX_SIZE 256
|
|
#define DATA_PACKET_TIMEOUT_MS 300
|
|
|
|
volatile static CmplxFifoQueueHandle_s __gprv_xUartResponseQueue[IVEC_ECU_UART_PORT_MAX] = { 0 };
|
|
|
|
//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] pu8Buffer Pointer to the received data buffer.
|
|
* @param[in] u32Size Size of the received data buffer.
|
|
*/
|
|
|
|
static void __prv_EcuCanOverUartMsgCallback(IVEC_McalUartPort_e eUartPort, IVEC_ECU_UartEvent_e eEventType,int8_t* pu8Buffer, uint32_t u32Size)
|
|
{
|
|
switch (eUartPort)
|
|
{
|
|
case IVEC_MCAL_UART_PORT_2:
|
|
if (eEventType == IVEC_ECU_UART_EVENT_RX_ARRIVED) {
|
|
u8CMPLX_FifoEnqueue((CmplxFifoQueueHandle_s*)&__gprv_xUartResponseQueue[IVEC_ECU_UART_PORT2], pu8Buffer, u32Size);
|
|
}
|
|
break;
|
|
case IVEC_MCAL_UART_PORT_3:
|
|
if (eEventType == IVEC_ECU_UART_EVENT_RX_ARRIVED) {
|
|
u8CMPLX_FifoEnqueue((CmplxFifoQueueHandle_s*)&__gprv_xUartResponseQueue[IVEC_ECU_UART_PORT3], pu8Buffer, u32Size);
|
|
}
|
|
case IVEC_MCAL_UART_PORT_4:
|
|
if (eEventType == IVEC_ECU_UART_EVENT_RX_ARRIVED) {
|
|
u8CMPLX_FifoEnqueue((CmplxFifoQueueHandle_s*)&__gprv_xUartResponseQueue[IVEC_ECU_UART_PORT4], pu8Buffer, u32Size);
|
|
}
|
|
break;
|
|
default:
|
|
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 _prv_EcuCalculateChecksum(uint8_t* pkt, int i32Len, uint8_t* u8CheckSum) {
|
|
uint8_t l_u8CheckSumFirst = 0, l_u8CheckSumSecond = 0;
|
|
/* Incremented to ignore Sync data */
|
|
for (int u32Index = 2; u32Index < i32Len - 2; u32Index++) {
|
|
l_u8CheckSumFirst += pkt[u32Index];
|
|
l_u8CheckSumSecond += l_u8CheckSumFirst;
|
|
}
|
|
l_u8CheckSumFirst &= 0xFF;
|
|
l_u8CheckSumSecond &= 0xFF;
|
|
u8CheckSum[0] = l_u8CheckSumFirst;
|
|
u8CheckSum[1] = l_u8CheckSumSecond;
|
|
}
|
|
|
|
/**
|
|
* @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] pxUartHandle 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 `__prv_EcuCanOverUartMsgCallback`.
|
|
* - If the initialization of the FIFO queue or UART fails, the function returns
|
|
* `commonECU_INIT_FAIL`.
|
|
*/
|
|
|
|
IVEC_EcuCommonErr_e xECU_UartInit(IVEC_EcuUartHandle_s* pxUartHandle)
|
|
{
|
|
if (pxUartHandle->eUartPortNumber >= IVEC_ECU_UART_PORT_MAX)
|
|
{
|
|
return commonMCAL_INIT_FAIL;
|
|
}
|
|
|
|
IVEC_ECU_FUNC_ENTRY(LOG_STRING);
|
|
IVEC_EcuCommonErr_e l_eFuncStatus = commonECU_SUCCESS;
|
|
uint8_t l_i32Ret = 0;
|
|
|
|
IVEC_ECU_LOG(LOG_STRING, "UART Initializing Queue");
|
|
if (pxUartHandle->eUartPortNumber < IVEC_ECU_UART_PORT_MAX)
|
|
{
|
|
__gprv_xUartResponseQueue[pxUartHandle->eUartPortNumber].i32ElementSize = sizeof(uint8_t);
|
|
|
|
switch (pxUartHandle->eUartPortNumber)
|
|
{
|
|
case IVEC_ECU_UART_PORT2:
|
|
__gprv_xUartResponseQueue[pxUartHandle->eUartPortNumber].i32TotalElements = pxUartHandle->u16QbufSize;
|
|
__gprv_xUartResponseQueue[pxUartHandle->eUartPortNumber].pu8Buffer = pxUartHandle->u8Qbuffer;
|
|
break;
|
|
case IVEC_ECU_UART_PORT3:
|
|
__gprv_xUartResponseQueue[pxUartHandle->eUartPortNumber].i32TotalElements = pxUartHandle->u16QbufSize;
|
|
__gprv_xUartResponseQueue[pxUartHandle->eUartPortNumber].pu8Buffer = pxUartHandle->u8Qbuffer;
|
|
break;
|
|
case IVEC_ECU_UART_PORT4:
|
|
__gprv_xUartResponseQueue[pxUartHandle->eUartPortNumber].i32TotalElements = pxUartHandle->u16QbufSize;
|
|
__gprv_xUartResponseQueue[pxUartHandle->eUartPortNumber].pu8Buffer = pxUartHandle->u8Qbuffer;
|
|
break;
|
|
default:
|
|
__gprv_xUartResponseQueue[pxUartHandle->eUartPortNumber].pu8Buffer = NULL;
|
|
break;
|
|
}
|
|
|
|
__gprv_xUartResponseQueue[pxUartHandle->eUartPortNumber].i32QueueType = FIXED_ELEMENT_SIZE_QUEUE;
|
|
l_i32Ret = u8CMPLX_FifoQueueInit((CmplxFifoQueueHandle_s*)&__gprv_xUartResponseQueue[pxUartHandle->eUartPortNumber]);
|
|
}
|
|
|
|
if (l_i32Ret == 0)
|
|
{
|
|
l_eFuncStatus = commonECU_INIT_FAIL;
|
|
goto exit;
|
|
}
|
|
|
|
|
|
IVEC_ECU_LOG(LOG_STRING, "Initializing UART");
|
|
pxUartHandle->__xUartHandle.pvUartRecvCallback = __prv_EcuCanOverUartMsgCallback;
|
|
pxUartHandle->__xUartHandle.xUartConfig.eUartBaudrate = pxUartHandle->u32BaudRate;
|
|
pxUartHandle->__xUartHandle.eUartPortNumber = pxUartHandle->eUartPortNumber;
|
|
pxUartHandle->__xUartHandle.xUartConfig.eUartFlowCtrl = IVEC_MCAL_UART_FC_NONE;
|
|
pxUartHandle->__xUartHandle.xUartConfig.eUartDataBit = IVEC_MCAL_UART_DATA_BIT_8;
|
|
pxUartHandle->__xUartHandle.xUartConfig.eUartStopBit = IVEC_MCAL_UART_STOP_BIT_1;
|
|
pxUartHandle->__xUartHandle.xUartConfig.eUartParityBit = IVEC_MCAL_UART_PARITY_NONE;
|
|
l_i32Ret = xMCAL_UartInit(&pxUartHandle->__xUartHandle);
|
|
|
|
if (l_i32Ret != 0)
|
|
{
|
|
l_eFuncStatus = commonECU_INIT_FAIL;
|
|
goto exit;
|
|
}
|
|
|
|
exit:
|
|
IVEC_ECU_FUNC_EXIT(LOG_STRING, 0);
|
|
return l_eFuncStatus;
|
|
}
|
|
/**
|
|
* @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] pxUartHandle 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_EcuUartHandle_s* pxUartHandle)
|
|
{
|
|
if (pxUartHandle == NULL || pxUartHandle->eUartPortNumber >= IVEC_ECU_UART_PORT_MAX)
|
|
{
|
|
return commonECU_INIT_FAIL;
|
|
}
|
|
IVEC_ECU_FUNC_ENTRY(LOG_STRING);
|
|
uint8_t l_i32Ret;
|
|
IVEC_EcuCommonErr_e l_eFuncStatus = commonECU_SUCCESS;
|
|
|
|
if (pxUartHandle == NULL)
|
|
{
|
|
l_eFuncStatus = commonECU_ALREADY_DEINIT;
|
|
goto exit;
|
|
}
|
|
|
|
IVEC_ECU_LOG(LOG_STRING, "Deinitializing UART");
|
|
l_i32Ret = xMCAL_UartDeInit(&pxUartHandle->__xUartHandle);
|
|
if (l_i32Ret != IVEC_MCAL_STATUS_SUCCESS)
|
|
{
|
|
l_eFuncStatus = commonECU_DEINIT_FAIL;
|
|
goto exit;
|
|
}
|
|
|
|
if (pxUartHandle->eUartPortNumber < IVEC_ECU_UART_PORT_MAX)
|
|
{
|
|
vCMPLX_FifoQueueFlush((CmplxFifoQueueHandle_s*)&__gprv_xUartResponseQueue[pxUartHandle->eUartPortNumber]);
|
|
}
|
|
|
|
exit:
|
|
IVEC_ECU_FUNC_EXIT(LOG_STRING, 0);
|
|
return l_eFuncStatus;
|
|
}
|
|
void vECU_UartFlush(IVEC_EcuUartHandle_s* pxUartHandle)
|
|
{
|
|
if (pxUartHandle->eUartPortNumber < IVEC_ECU_UART_PORT_MAX)
|
|
{
|
|
vCMPLX_FifoQueueFlush((CmplxFifoQueueHandle_s*)&__gprv_xUartResponseQueue[pxUartHandle->eUartPortNumber]);
|
|
}
|
|
}
|
|
/**
|
|
* @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] pxUartHandle 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 xECU_UartReinit(IVEC_EcuUartHandle_s* pxUartHandle)
|
|
{
|
|
if (pxUartHandle == NULL || pxUartHandle->eUartPortNumber >= IVEC_ECU_UART_PORT_MAX)
|
|
{
|
|
return commonECU_INIT_FAIL;
|
|
}
|
|
IVEC_EcuCommonErr_e l_eFuncStatus = commonECU_SUCCESS;
|
|
uint8_t l_i32Ret;
|
|
|
|
// Deinitialize UART
|
|
l_i32Ret = xECU_UartDeinit(pxUartHandle);
|
|
if (l_i32Ret != IVEC_MCAL_STATUS_SUCCESS)
|
|
{
|
|
l_eFuncStatus = commonECU_DEINIT_FAIL;
|
|
goto exit;
|
|
}
|
|
|
|
// Reinitialize UART with the new speed
|
|
l_i32Ret = xECU_UartInit(pxUartHandle);
|
|
if (l_i32Ret != IVEC_MCAL_STATUS_SUCCESS)
|
|
{
|
|
l_eFuncStatus = commonECU_INIT_FAIL;
|
|
}
|
|
|
|
exit:
|
|
return l_eFuncStatus;
|
|
}
|
|
/**
|
|
* @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] pxUartHandle Pointer to the UART handle structure.
|
|
* @param[in] pu8Buffer 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 xECU_UartTransmit(IVEC_EcuUartHandle_s* pxUartHandle, uint8_t* pu8Buffer, uint16_t u16Len)
|
|
{
|
|
return commonECU_FAIL;
|
|
}
|
|
/**
|
|
* @brief Flushes the UART response queue.
|
|
*
|
|
* This function clears the response queue associated with the specified UART port.
|
|
*
|
|
* @param[in] pxUartHandle 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 xECU_UartFlush(IVEC_EcuUartHandle_s* pxUartHandle)
|
|
{
|
|
if (pxUartHandle == NULL || pxUartHandle->eUartPortNumber >= IVEC_ECU_UART_PORT_MAX)
|
|
{
|
|
return commonECU_FAIL;
|
|
}
|
|
vCMPLX_FifoQueueFlush((CmplxFifoQueueHandle_s*)&__gprv_xUartResponseQueue[pxUartHandle->eUartPortNumber]);
|
|
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] pxUartHandle Pointer to the UART handle structure.
|
|
* @param[out] pu8Buffer 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 xECU_UartGetData(IVEC_EcuUartHandle_s* pxUartHandle, uint8_t* pu8Buffer, uint16_t u16Len, uint16_t u16Timeout)
|
|
{
|
|
IVEC_ECU_FUNC_ENTRY(LOG_STRING);
|
|
|
|
IVEC_EcuCommonErr_e l_eFuncStatus = commonECU_SUCCESS;
|
|
|
|
if (pxUartHandle == NULL || pxUartHandle->eUartPortNumber >= IVEC_ECU_UART_PORT_MAX)
|
|
{
|
|
l_eFuncStatus = commonECU_INVALID_PARAM;
|
|
goto exit;
|
|
}
|
|
|
|
uint16_t l_u16Len = 0;
|
|
uint32_t u32CommTimestamp = i32MCAL_getTicks();
|
|
|
|
while(((i32MCAL_getTicks() - u32CommTimestamp) <= u16Timeout+1) && (l_u16Len < u16Len))
|
|
{
|
|
|
|
l_u16Len = i32CMPLX_FifoCounts((CmplxFifoQueueHandle_s*)&__gprv_xUartResponseQueue[pxUartHandle->eUartPortNumber]);
|
|
}
|
|
|
|
if (l_u16Len < u16Len)
|
|
{
|
|
l_eFuncStatus = commonECU_READ_FAIL;
|
|
goto exit;
|
|
}
|
|
else
|
|
{
|
|
int i32Len = 0;
|
|
__disable_irq();//disabling interrupt to avoid enqueing while dequeing
|
|
for(int u32Index=0;u32Index<u16Len;u32Index++)
|
|
{
|
|
u8CMPLX_FifoDequeue((CmplxFifoQueueHandle_s*)&__gprv_xUartResponseQueue[pxUartHandle->eUartPortNumber], &pu8Buffer[u32Index], &i32Len, 0);
|
|
|
|
}
|
|
__enable_irq();
|
|
}
|
|
|
|
exit:
|
|
IVEC_ECU_FUNC_EXIT(LOG_STRING, 0);
|
|
return l_eFuncStatus;
|
|
}
|
|
|
|
|
|
/**
|
|
* @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] pxUartHandle Pointer to the UART handle for communication.
|
|
* @param[out] pu8Buf Buffer to store the received data.
|
|
* @param[out] u32Id 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.
|
|
* - `ecuUART_PACKET_FAIL_i8` if the packet synchronization is lost.
|
|
*/
|
|
|
|
|
|
IVEC_ECU_UartPacketRetCode_e xECU_UartReadCANDataLenOverUART(IVEC_EcuUartHandle_s* pxUartHandle, uint8_t* pu8Buf, uint32_t* u32Id)
|
|
{
|
|
int PktLen = commonECU_READ_FAIL;
|
|
if ((xECU_UartGetData(pxUartHandle, (uint8_t*)&pu8Buf[0], 1, 0) == commonECU_SUCCESS))
|
|
{
|
|
if (pu8Buf[0] == 0xB5)
|
|
{
|
|
if (xECU_UartGetData(pxUartHandle, (uint8_t*)&pu8Buf[1], 1, 5) == commonECU_SUCCESS) {
|
|
if (pu8Buf[1] != 0x62) {
|
|
PktLen = commonECU_READ_FAIL;
|
|
goto EXIT; // 0x62 not found, OUT OF SYNC
|
|
}
|
|
}
|
|
else
|
|
{
|
|
PktLen = commonECU_READ_FAIL;
|
|
goto EXIT;
|
|
}
|
|
if (xECU_UartGetData(pxUartHandle, (uint8_t*)&pu8Buf[2], 5, DATA_PACKET_TIMEOUT_MS) != commonECU_SUCCESS) {
|
|
PktLen = commonECU_READ_FAIL;
|
|
goto EXIT;
|
|
}
|
|
|
|
*(u32Id) = (uint32_t)((pu8Buf[6] << 24) | (pu8Buf[5] << 16) | (pu8Buf[4] << 8) | (pu8Buf[3]));
|
|
uint8_t l_u8TempLen = pu8Buf[2];
|
|
PktLen = ecuUART_PKT_HEADER_FOOTER_u8 + l_u8TempLen;
|
|
if (xECU_UartGetData(pxUartHandle, (uint8_t*)&pu8Buf[ecuUART_PKT_HEADER_u8], (uint32_t)(PktLen - ecuUART_PKT_HEADER_u8), DATA_PACKET_TIMEOUT_MS) != commonECU_SUCCESS)
|
|
{
|
|
PktLen = commonECU_READ_FAIL;
|
|
goto EXIT;
|
|
}
|
|
uint8_t l_u8CheckSum[2];
|
|
_prv_EcuCalculateChecksum(pu8Buf, PktLen, l_u8CheckSum);
|
|
|
|
/* TODO: (Python Script) Sometimes fails due to bad checksum */
|
|
if ((l_u8CheckSum[0] == pu8Buf[PktLen - 2]) && (l_u8CheckSum[1] == pu8Buf[PktLen - 1])) {
|
|
PktLen -= ecuUART_PKT_HEADER_FOOTER_u8;
|
|
}
|
|
else
|
|
{
|
|
IVEC_ECU_LOG(LOG_STRING, "Packet Checksum Failed\n");
|
|
PktLen = commonECU_READ_FAIL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// COM_FlushBuffer();
|
|
PktLen = ecuUART_PACKET_FAIL_i8;
|
|
}
|
|
}
|
|
EXIT:
|
|
return PktLen;
|
|
}
|
|
/**
|
|
* @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] pxUartHandle Pointer to the UART handle for communication.
|
|
* @param[out] pu8Buf Buffer to store the received data.
|
|
* @param[out] u32Id Pointer to store the extracted CAN ID.
|
|
*
|
|
* @return The result of reading the CAN data over UART.
|
|
* - `ecuUART_PACKET_FAIL_i8` if the UART handle is invalid or the
|
|
* packet read fails.
|
|
*/
|
|
IVEC_ECU_UartPacketRetCode_e xECU_UartReadCANDataOverUART(IVEC_EcuUartHandle_s* pxUartHandle, uint8_t* pu8Buf, uint32_t* u32Id)
|
|
{
|
|
if (pxUartHandle == NULL || pxUartHandle->eUartPortNumber >= IVEC_ECU_UART_PORT_MAX)
|
|
{
|
|
return ecuUART_PACKET_FAIL_i8;
|
|
}
|
|
IVEC_ECU_UartPacketRetCode_e l_eRetCode = ecuUART_PACKET_FAIL_i8;
|
|
l_eRetCode = xECU_UartReadCANDataLenOverUART(pxUartHandle, pu8Buf, u32Id);
|
|
return l_eRetCode;
|
|
}
|
|
/**
|
|
* @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] pxUartHandle Pointer to the UART handle for communication.
|
|
* @param[in] pu8Buffer 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_ECUUartWrite(IVEC_EcuUartHandle_s* pxUartHandle, uint8_t* pu8Buffer, uint16_t len)
|
|
{
|
|
IVEC_EcuCommonErr_e l_eFuncStatus = commonECU_WRITE_FAIL;
|
|
uint8_t l_i32Ret;
|
|
if (pxUartHandle == NULL)
|
|
{
|
|
l_eFuncStatus = commonECU_INVALID_PARAM;
|
|
}
|
|
|
|
l_i32Ret = xMCAL_UartWrite(&pxUartHandle->__xUartHandle, pu8Buffer, len);
|
|
|
|
if (l_i32Ret == IVEC_CORE_STATUS_SUCCESS)
|
|
{
|
|
l_eFuncStatus = commonECU_SUCCESS;
|
|
}
|
|
|
|
return l_eFuncStatus;
|
|
}
|
|
/**
|
|
* @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] pxUartHandle 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] u32Id CAN ID to be included in the packet.
|
|
*
|
|
* @return Status of the packet formatting:
|
|
* - `IVEC_ECU_UART_PACKET_SUCCESS` if successful.
|
|
* - `ecuUART_PACKET_FAIL_i8` if the packet formatting or write fails.
|
|
*/
|
|
IVEC_ECU_UartPacketRetCode_e xECU_UartFormatPacket(IVEC_EcuUartHandle_s* pxUartHandle, uint8_t* pu8Data, uint8_t u8Dlc, uint32_t u32Id)
|
|
{
|
|
pu8Data[0] = 0xb5; // SYNC_CHAR[0]
|
|
pu8Data[1] = 0x62; // SYNC_CHAR[1]
|
|
pu8Data[2] = u8Dlc;
|
|
memcpy(&pu8Data[3], &u32Id, sizeof(uint32_t));
|
|
unsigned char l_u8CheckSum[2] = { 0 };
|
|
_prv_EcuCalculateChecksum(pu8Data, (u8Dlc + ecuUART_PKT_HEADER_FOOTER_u8), l_u8CheckSum);
|
|
pu8Data[(u8Dlc + ecuUART_PKT_HEADER_FOOTER_u8) - 2] = l_u8CheckSum[0];
|
|
pu8Data[(u8Dlc + ecuUART_PKT_HEADER_FOOTER_u8) - 1] = l_u8CheckSum[1];
|
|
if (IVEC_ECUUartWrite(pxUartHandle, pu8Data, (u8Dlc + ecuUART_PKT_HEADER_FOOTER_u8)) != commonECU_SUCCESS) {
|
|
return ecuUART_PACKET_FAIL_i8;
|
|
}
|
|
return ecuUART_PACKET_SUCCESS_u8;
|
|
}
|
|
/**
|
|
* @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] pxUartHandle 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_EcuUartHandle_s* pxUartHandle, uint32_t u32Id, uint8_t* pu8Data, uint8_t u8Len)
|
|
{
|
|
if (pxUartHandle == NULL || pxUartHandle->eUartPortNumber >= IVEC_ECU_UART_PORT_MAX)
|
|
{
|
|
return commonECU_INIT_FAIL;
|
|
}
|
|
uint8_t l_u8Buf[ecuUART_MAX_PACKET_LENGTH_u8] = {0};
|
|
memcpy(&l_u8Buf[ecuUART_PKT_HEADER_u8], pu8Data, u8Len);
|
|
return (xECU_UartFormatPacket(pxUartHandle, l_u8Buf, u8Len, u32Id) == ecuUART_PACKET_SUCCESS_u8) ? 0 : -1;
|
|
}
|
|
|
|
uint32_t xECU_data_length(IVEC_EcuUartHandle_s* pxUartHandle)
|
|
{
|
|
uint32_t length = i32CMPLX_FifoCounts((CmplxFifoQueueHandle_s*)&__gprv_xUartResponseQueue[pxUartHandle->eUartPortNumber]);
|
|
return(length);
|
|
}
|