From 4d7f319ae26d06652999be2c6cde89f551379516 Mon Sep 17 00:00:00 2001 From: cfif Date: Tue, 19 May 2026 16:47:01 +0300 Subject: [PATCH] Init --- Inc/SerialPortArtery.h | 24 +--- Src/SerialPortArtery.c | 293 ----------------------------------------- 2 files changed, 1 insertion(+), 316 deletions(-) diff --git a/Inc/SerialPortArtery.h b/Inc/SerialPortArtery.h index ac8b0f0..de5268d 100644 --- a/Inc/SerialPortArtery.h +++ b/Inc/SerialPortArtery.h @@ -9,7 +9,6 @@ #include "at32f435_437.h" #include "cmsis_os2.h" #include "stdbool.h" -#include "LinIO.h" typedef struct { usart_type *uart; @@ -26,12 +25,6 @@ typedef struct { uint32_t rxDmaOffset; // osMutexId_t dmaAccess; - bool linFrameStarted; - uint8_t linByteCount; - uint8_t linBuffer[12]; - uint32_t linLastByteTime; - uint32_t linFrameTimeoutMs; - lin_frame_t rxFrame; osMessageQueueId_t txAccessQueue; @@ -211,25 +204,10 @@ tSerialPortIO vSerialPortGetSnifferIo(tSerialPortArtery *env); tSerialPortIO SerialPort_GetSnifferSecondIo(tSerialPortArtery *env); - uint16_t vSerialPortTransmit(tSerialPortArtery *env, uint8_t *data, uint16_t size, uint32_t timeout); +uint16_t vSerialPortTransmit(tSerialPortArtery *env, uint8_t *data, uint16_t size, uint32_t timeout); uint16_t vSerialPortBlindTransmit(tSerialPortArtery *env, uint8_t *data, uint16_t size, uint32_t timeout); void SerialPort_IrqProcessing_DmaTxBlind(tSerialPortArtery *env); -void vSerialPortLinInit( - tSerialPortArtery *env, - usart_type *uart, - bool swap, - uint32_t BoundRate, - IRQn_Type irq, - crm_periph_clock_type uartClock, - uint8_t irqPriority, - uint32_t rxBufferLength, - uint32_t rxSnifferLength -); - -void SerialPort_IrqProcessing_UartLin(tSerialPortArtery *env); -bool vSerialPortSendLinFrame(tSerialPortArtery *env, const lin_frame_t *pFrame, uint32_t timeout); - #endif //SERIALPORT_SERIALPORT_ARTERY_H diff --git a/Src/SerialPortArtery.c b/Src/SerialPortArtery.c index 830ec31..1d43867 100644 --- a/Src/SerialPortArtery.c +++ b/Src/SerialPortArtery.c @@ -47,61 +47,6 @@ void vSerialPortInit( env->uart = uart; } -void vSerialPortLinInit( - tSerialPortArtery *env, - usart_type *uart, - bool swap, - uint32_t BoundRate, - IRQn_Type irq, - crm_periph_clock_type uartClock, - uint8_t irqPriority, - uint32_t rxBufferLength, - uint32_t rxSnifferLength -) { - env->uart = uart; - - env->linLastByteTime = 20; - env->linFrameTimeoutMs = 20; - - usart_reset(uart); - - crm_periph_clock_enable(uartClock, TRUE); - - usart_init(uart, BoundRate, USART_DATA_8BITS, USART_STOP_1_BIT); - - // ВКЛЮЧАЕМ LIN РЕЖИМ!!! - usart_lin_mode_enable(uart, TRUE); - // Настраиваем длину break field (LIN требует 13 бит, выбираем 11) - usart_break_bit_num_set(uart, USART_BREAK_11BITS); - - usart_transmitter_enable(uart, TRUE); - usart_receiver_enable(uart, TRUE); - - if (swap) { - usart_transmit_receive_pin_swap(uart, TRUE); - } - - usart_enable(uart, TRUE); - - // Включаем прерывание по break frame - usart_interrupt_enable(uart, USART_BF_INT, TRUE); - usart_interrupt_enable(uart, USART_RDBF_INT, TRUE); -// usart_interrupt_enable(uart, USART_IDLE_INT, TRUE); - - NVIC_EnableIRQ(irq); - NVIC_SetPriority(irq, irqPriority); - - env->rxDataQueue = osMessageQueueNew(rxBufferLength, 12, NULL); - - if (rxSnifferLength) { - env->rxDataSnifferQueue = osMessageQueueNew(rxSnifferLength, sizeof(lin_frame_t), NULL); - } else { - env->rxDataSnifferQueue = 0; - } - -} - - void vSerialPortInitExt( tSerialPortArtery *env, usart_type *uart, @@ -816,244 +761,6 @@ uint16_t vSerialPortBlindTransmit(tSerialPortArtery *env, uint8_t *data, uint16_ return sent; } - - - - -static uint8_t LIN_DrvMakeCheckSum(uint8_t *pBuf, uint8_t u8Size, uint8_t u8Pid) { - uint16_t u16Checksum = 0U; - uint8_t u8Length = 0U; - - // For PID is 0x3C (ID 0x3C) or 0x7D (ID 0x3D) or 0xFE (ID 0x3E) or 0xBF (ID 0x3F) - if ((0x3CU == u8Pid) || (0x7DU == u8Pid) || (0xFEU == u8Pid) || (0xBFU == u8Pid)) - { - u8Pid = 0U; - } - - u16Checksum += u8Pid; - - for (u8Length = 0U; u8Length < u8Size; u8Length++) - { - u16Checksum += *pBuf; - pBuf++; - if (u16Checksum > 0xFFU) - { - u16Checksum -= 0xFFU; - } - } - - return ~(uint8_t)(u16Checksum); -} - -static uint8_t LIN_CalcParity(uint8_t id) { - uint8_t p0 = 0; - uint8_t p1 = 0; - - // P0 = ID0 ^ ID1 ^ ID2 ^ ID4 - p0 = ((id >> 0) & 0x01) ^ ((id >> 1) & 0x01) ^ - ((id >> 2) & 0x01) ^ ((id >> 4) & 0x01); - - // P1 = ^(ID1 ^ ID3 ^ ID4 ^ ID5) - p1 = 1 ^ ((id >> 1) & 0x01) ^ ((id >> 3) & 0x01) ^ - ((id >> 4) & 0x01) ^ ((id >> 5) & 0x01); - - return (p1 << 7) | (p0 << 6); -} - -// Измененный обработчик прерываний (без IDLE): -void SerialPort_IrqProcessing_UartLin(tSerialPortArtery *env) { - - // 1. Break frame detection - if (usart_flag_get(env->uart, USART_BFF_FLAG)) { - usart_flag_clear(env->uart, USART_BFF_FLAG); - usart_data_receive(env->uart); - - env->linFrameStarted = true; - env->linByteCount = 0; - env->linLastByteTime = SystemGetMs(); // Запоминаем время - env->rxFrame.event = LIN_RECV_BREAK_FIELD_OK; - return; - } - - // 2. Receive data (без IDLE) - if (usart_flag_get(env->uart, USART_RDBF_FLAG)) { - if (env->linFrameStarted && (env->linByteCount < sizeof(env->linBuffer))) { - uint8_t data = usart_data_receive(env->uart); - env->linBuffer[env->linByteCount] = data; - env->linByteCount++; - env->linLastByteTime = SystemGetMs(); // Обновляем время - } else { - usart_data_receive(env->uart); - if (env->linFrameStarted) { - env->rxFrame.event = LIN_RX_OVERRUN; - osMessageQueuePut(env->rxDataQueue, &env->rxFrame, 0, 0); - env->linFrameStarted = false; - } - } - } - - // 3. Error handling - if (usart_flag_get(env->uart, USART_FERR_FLAG)) { - usart_flag_clear(env->uart, USART_FERR_FLAG); - usart_data_receive(env->uart); - - if (env->linFrameStarted) { - env->rxFrame.event = LIN_FRAME_ERROR; - osMessageQueuePut(env->rxDataQueue, &env->rxFrame, 0, 0); - env->linFrameStarted = false; - } - } - - if (usart_flag_get(env->uart, USART_ROERR_FLAG)) { - usart_flag_clear(env->uart, USART_ROERR_FLAG); - usart_data_receive(env->uart); - - if (env->linFrameStarted) { - env->rxFrame.event = LIN_RX_OVERRUN; - osMessageQueuePut(env->rxDataQueue, &env->rxFrame, 0, 0); - env->linFrameStarted = false; - } - } -} - - -// Выделенная функция обработки кадра -static void LIN_ProcessReceivedFrame(tSerialPortArtery *env) { - // Проверка sync field - if (env->linBuffer[0] != 0x55) { - env->rxFrame.event = LIN_SYNC_ERROR; - osMessageQueuePut(env->rxDataQueue, &env->rxFrame, 0, 0); - return; - } - - // Проверка PID - uint8_t receivedPid = env->linBuffer[1]; - uint8_t id = receivedPid & 0x3F; - uint8_t expectedPid = id | LIN_CalcParity(id); - - if (receivedPid != expectedPid) { - env->rxFrame.event = LIN_PID_ERROR; - osMessageQueuePut(env->rxDataQueue, &env->rxFrame, 0, 0); - return; - } - - env->rxFrame.id = id; - env->rxFrame.dataLen = env->linByteCount - 3; - - if (env->rxFrame.dataLen > 8) { - env->rxFrame.event = LIN_FRAME_ERROR; - osMessageQueuePut(env->rxDataQueue, &env->rxFrame, 0, 0); - return; - } - - // Копируем данные - for (uint8_t i = 0; i < env->rxFrame.dataLen; i++) { - env->rxFrame.data[i] = env->linBuffer[2 + i]; - } - - // Проверка checksum - env->rxFrame.checksum = env->linBuffer[env->linByteCount - 1]; - uint8_t calculatedChecksum = LIN_DrvMakeCheckSum( - env->rxFrame.data, - env->rxFrame.dataLen, - receivedPid - ); - - if (env->rxFrame.checksum != calculatedChecksum) { - env->rxFrame.event = LIN_CHECKSUM_ERROR; - } else { - env->rxFrame.event = LIN_RX_COMPLETED; - } - - osMessageQueuePut(env->rxDataQueue, &env->rxFrame, 0, 0); -} - - -// Функция проверки таймаута (вызывать из таймера, например, каждые 1-5 мс) -void LIN_CheckTimeout(tSerialPortArtery *env) { - - if (!env->linFrameStarted) { - return; - } - - uint32_t now = SystemGetMs(); - uint32_t elapsed = now - env->linLastByteTime; - - if (elapsed >= env->linFrameTimeoutMs) { - // Таймаут - кадр должен быть завершен - if (env->linByteCount >= 3) { - // Пытаемся обработать полученные данные - LIN_ProcessReceivedFrame(env); - } else { - // Недостаточно данных - env->rxFrame.event = LIN_TIMEOUT; - osMessageQueuePut(env->rxDataQueue, &env->rxFrame, 0, 0); - } - - env->linFrameStarted = false; - } -} - - - - - - - - - - - -bool vSerialPortSendLinFrame(tSerialPortArtery *env, const lin_frame_t *pFrame, uint32_t timeout) { - uint8_t txBuffer[11]; // Максимальный размер LIN кадра (без break) - uint8_t idx = 0; - - if ((!env) || (!pFrame)) { - return false; - } - - // Проверка валидности данных - if (pFrame->dataLen > 8) { - return false; - } - - // 1. Формирование LIN кадра - // Sync field - txBuffer[idx++] = 0x55; - - // PID (ID + parity) - uint8_t pid = pFrame->id | LIN_CalcParity(pFrame->id); - txBuffer[idx++] = pid; - - // Data bytes - for (uint8_t i = 0; i < pFrame->dataLen; i++) { - txBuffer[idx++] = pFrame->data[i]; - } - - // Checksum - txBuffer[idx++] = pFrame->checksum; - - // 2. Отправка break field - usart_break_send(env->uart); - - // Ожидание завершения отправки break - uint32_t breakTimeout = SystemGetMs() + 10; // 10мс максимум на break - while (usart_flag_get(env->uart, USART_TDBE_FLAG) == RESET) { - if (SystemGetMs() > breakTimeout) { - return false; - } - } - - // 3. Отправка данных (возвращает количество отправленных байт) - uint16_t sent = vSerialPortTransmitOverCore(env, txBuffer, idx, timeout); - - return (sent == idx); // Успех, если все байты отправлены -} - - - - - static SerialPortIOTransaction vSerialPortTransmitterGet(tSerialPortArtery *env) { #ifdef UART_DMA_SEND