commit f7ce19f94fb3b4fc7ec74db2cc054fcecf6f5516 Author: cfif Date: Fri Jan 24 13:22:32 2025 +0300 Перенос на новую организацию GONEC diff --git a/Inc/SerialPortArtery.h b/Inc/SerialPortArtery.h new file mode 100644 index 0000000..eef7a61 --- /dev/null +++ b/Inc/SerialPortArtery.h @@ -0,0 +1,210 @@ +// +// Created by cfif on 16.09.22. +// + +#ifndef SERIALPORT_SERIALPORT_ARTERY_H +#define SERIALPORT_SERIALPORT_ARTERY_H + +#include "SerialPort.h" +#include "at32f435_437.h" +#include "cmsis_os2.h" +#include "stdbool.h" + +typedef struct { + usart_type *uart; + dma_channel_type *rxDmaChannel; + + dma_init_type dma_rx_init_struct; + dma_init_type dma_tx_init_struct; + + uint32_t rxDmaFdtFlag;//full data transmit flag + uint32_t txDmaFdtFlag;//full data transmit flag + + dma_channel_type *txDmaChannel; + uint8_t *rxDmaBuf; + uint32_t rxDmaOffset; + +// osMutexId_t dmaAccess; + + osMessageQueueId_t txAccessQueue; + + osMessageQueueId_t rxDataQueue; + osMessageQueueId_t rxDataSnifferQueue; +} tSerialPortArtery; + +void vSerialPortInit( + 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 vSerialPortInitExt( + tSerialPortArtery *env, + usart_type *uart, + bool swap, + usart_hardware_flow_control_type flow_control_type, + uint32_t BoundRate, + IRQn_Type irq, + crm_periph_clock_type uartClock, + uint8_t irqPriority, + uint32_t rxBufferLength, + uint32_t rxSnifferLength +); + +void vSerialPortInitDMA( + tSerialPortArtery *env, + usart_type *uart, + + dma_type *DMA_RX, + dma_type *DMA_TX, + + dma_channel_type *RX_DMA_CHANNEL, + dmamux_channel_type *RX_DMA_CHANNEL_MUX, + dmamux_requst_id_sel_type RX_DMAMUX_DMAREQ_ID, + IRQn_Type RX_DMA_Channel_IRQ, + uint32_t RX_DMA_FDT_FLAG, + + uint8_t *DMA_BUF, + uint16_t DMA_BUF_LEN, + + + dma_channel_type *TX_DMA_CHANNEL, + dmamux_channel_type *TX_DMA_CHANNEL_MUX, + dmamux_requst_id_sel_type TX_DMAMUX_DMAREQ_ID, + IRQn_Type TX_DMA_Channel_IRQ, + uint32_t TX_DMA_FDT_FLAG, + + bool swap, + uint32_t BoundRate, + IRQn_Type irq, + crm_periph_clock_type uartClock, + uint8_t irqPriority, + uint32_t rxBufferLength, + uint32_t rxSnifferLength +); + +void vSerialPortInitDMAExt( + tSerialPortArtery *env, + usart_type *uart, + + dma_type *DMA_RX, + dma_type *DMA_TX, + + dma_channel_type *RX_DMA_CHANNEL, + dmamux_channel_type *RX_DMA_CHANNEL_MUX, + dmamux_requst_id_sel_type RX_DMAMUX_DMAREQ_ID, + IRQn_Type RX_DMA_Channel_IRQ, + uint32_t RX_DMA_FDT_FLAG, + + uint8_t *DMA_BUF, + uint16_t DMA_BUF_LEN, + + + dma_channel_type *TX_DMA_CHANNEL, + dmamux_channel_type *TX_DMA_CHANNEL_MUX, + dmamux_requst_id_sel_type TX_DMAMUX_DMAREQ_ID, + IRQn_Type TX_DMA_Channel_IRQ, + uint32_t TX_DMA_FDT_FLAG, + + bool swap, + usart_hardware_flow_control_type flow_control_type, + uint32_t BoundRate, + IRQn_Type irq, + crm_periph_clock_type uartClock, + uint8_t irqPriority, + uint32_t rxBufferLength, + uint32_t rxSnifferLength +); + +#define vSerialPortInitDMAName(ENV, NAME, DMA, RX_DMA_CHANNEL, RX_DMA_CHANNEL_MUX, RX_DMAMUX_DMAREQ_ID, RX_DMA_Channel_IRQ, RX_DMA_FDT_FLAG, DMA_BUF, DMA_BUF_LEN, TX_DMA_CHANNEL, TX_DMA_CHANNEL_MUX, TX_DMAMUX_DMAREQ_ID, TX_DMA_Channel_IRQ, TX_DMA_FDT_FLAG, SWAP, BOUND_RATE, PRIORITY, LEN) \ +vSerialPortInitDMA(ENV, NAME, DMA, RX_DMA_CHANNEL, RX_DMA_CHANNEL_MUX, RX_DMAMUX_DMAREQ_ID, RX_DMA_Channel_IRQ, RX_DMA_FDT_FLAG, DMA_BUF, DMA_BUF_LEN, TX_DMA_CHANNEL, TX_DMA_CHANNEL_MUX, TX_DMAMUX_DMAREQ_ID, TX_DMA_Channel_IRQ, TX_DMA_FDT_FLAG, SWAP, BOUND_RATE, NAME##_IRQn, CRM_##NAME##_PERIPH_CLOCK, PRIORITY, LEN, 0) + +#define vSerialPortInitDMANameWithSniffer(ENV, NAME, DMA, RX_DMA_CHANNEL, RX_DMA_CHANNEL_MUX, RX_DMAMUX_DMAREQ_ID, RX_DMA_Channel_IRQ, RX_DMA_FDT_FLAG, DMA_BUF, DMA_BUF_LEN, TX_DMA_CHANNEL, TX_DMA_CHANNEL_MUX, TX_DMAMUX_DMAREQ_ID, TX_DMA_Channel_IRQ, TX_DMA_FDT_FLAG, SWAP, BOUND_RATE, PRIORITY, LEN, SNIFFER_LEN) \ +vSerialPortInitDMA(ENV, NAME, DMA, RX_DMA_CHANNEL, RX_DMA_CHANNEL_MUX, RX_DMAMUX_DMAREQ_ID, RX_DMA_Channel_IRQ, RX_DMA_FDT_FLAG, DMA_BUF, DMA_BUF_LEN, TX_DMA_CHANNEL, TX_DMA_CHANNEL_MUX, TX_DMAMUX_DMAREQ_ID, TX_DMA_Channel_IRQ, TX_DMA_FDT_FLAG, SWAP, BOUND_RATE, NAME##_IRQn, CRM_##NAME##_PERIPH_CLOCK, PRIORITY, LEN, SNIFFER_LEN) + + +#define DMANONE_CHANNELNONE NULL +#define DMANONE NULL +#define DMANONEMUX_CHANNELNONE NULL +#define DMANONE_FDTNONE_FLAG (uint32_t)0 +#define DMANONE_ChannelNONE_IRQn (IRQn_Type)0 + +#define vSerialPortInitDmaWithNameAndSniffer(\ + ENV, NAME, BOUND_RATE, \ + RX_DMA, RX_CH, \ + TX_DMA, TX_CH, \ + SWAP, PRIORITY, \ + RX_DMA_BUF, RX_DMA_BUF_LEN, \ + QUEUE_LEN, SNIFFER_LEN \ +) \ +vSerialPortInitDMA(\ + ENV, NAME, DMA##RX_DMA, DMA##TX_DMA, \ + DMA##RX_DMA##_CHANNEL##RX_CH, DMA##RX_DMA##MUX_CHANNEL##RX_CH, DMAMUX_DMAREQ_ID_##NAME##_RX, DMA##RX_DMA##_Channel##RX_CH##_IRQn, DMA##RX_DMA##_FDT##RX_CH##_FLAG,\ + RX_DMA_BUF, RX_DMA_BUF_LEN, \ + DMA##TX_DMA##_CHANNEL##TX_CH, DMA##TX_DMA##MUX_CHANNEL##TX_CH, DMAMUX_DMAREQ_ID_##NAME##_TX, DMA##TX_DMA##_Channel##TX_CH##_IRQn, DMA##TX_DMA##_FDT##TX_CH##_FLAG,\ + SWAP, BOUND_RATE, NAME##_IRQn, CRM_##NAME##_PERIPH_CLOCK, \ + PRIORITY, QUEUE_LEN, SNIFFER_LEN\ +) + +#define vSerialPortInitDmaExtWithNameAndSniffer(\ + ENV, NAME, BOUND_RATE, \ + RX_DMA, RX_CH, \ + TX_DMA, TX_CH, \ + SWAP, FLOW, PRIORITY, \ + RX_DMA_BUF, RX_DMA_BUF_LEN, \ + QUEUE_LEN, SNIFFER_LEN \ +) \ +vSerialPortInitDMAExt(\ + ENV, NAME, DMA##RX_DMA, DMA##TX_DMA, \ + DMA##RX_DMA##_CHANNEL##RX_CH, DMA##RX_DMA##MUX_CHANNEL##RX_CH, DMAMUX_DMAREQ_ID_##NAME##_RX, DMA##RX_DMA##_Channel##RX_CH##_IRQn, DMA##RX_DMA##_FDT##RX_CH##_FLAG,\ + RX_DMA_BUF, RX_DMA_BUF_LEN, \ + DMA##TX_DMA##_CHANNEL##TX_CH, DMA##TX_DMA##MUX_CHANNEL##TX_CH, DMAMUX_DMAREQ_ID_##NAME##_TX, DMA##TX_DMA##_Channel##TX_CH##_IRQn, DMA##TX_DMA##_FDT##TX_CH##_FLAG,\ + SWAP, FLOW, BOUND_RATE, NAME##_IRQn, CRM_##NAME##_PERIPH_CLOCK, \ + PRIORITY, QUEUE_LEN, SNIFFER_LEN\ +) + + +#define vSerialPortInitName(ENV, NAME, SWAP, BOUND_RATE, PRIORITY, LEN) \ +vSerialPortInit(ENV, NAME, SWAP, BOUND_RATE, NAME##_IRQn, CRM_##NAME##_PERIPH_CLOCK, PRIORITY, LEN, 0) + +#define vSerialPortExtInitName(ENV, NAME, SWAP, FLOW, BOUND_RATE, PRIORITY, LEN) \ +vSerialPortInit(ENV, NAME, SWAP, FLOW, BOUND_RATE, NAME##_IRQn, CRM_##NAME##_PERIPH_CLOCK, PRIORITY, LEN, 0) + + +#define vSerialPortInitNameWithSniffer(ENV, NAME, SWAP, BOUND_RATE, PRIORITY, LEN, SNIFFER_LEN) \ +vSerialPortInit(ENV, NAME, SWAP, BOUND_RATE, NAME##_IRQn, CRM_##NAME##_PERIPH_CLOCK, PRIORITY, LEN, SNIFFER_LEN) + +#define vSerialPortExtInitNameWithSniffer(ENV, NAME, SWAP, FLOW, BOUND_RATE, PRIORITY, LEN, SNIFFER_LEN) \ +vSerialPortInit(ENV, NAME, SWAP, FLOW, BOUND_RATE, NAME##_IRQn, CRM_##NAME##_PERIPH_CLOCK, PRIORITY, LEN, SNIFFER_LEN) + + +void vSerialPortIrqProcessing(tSerialPortArtery *env); + +void vSerialPortIrqProcessingDMA(tSerialPortArtery *env); + +//void vSerialPortIrqProcessingDMAloop(tSerialPortArtery *env, uint32_t len); + +void SerialPort_IrqProcessing_UartIdle(tSerialPortArtery *env); +void SerialPort_IrqProcessing_DmaRxLoop(tSerialPortArtery *env); +void SerialPort_IrqProcessingFilter_UartIdle(tSerialPortArtery *env, tSerialPortIO *virtualPort, uint16_t *counterBufFilterStr, uint8_t *bufStrFilter, uint16_t maxBufStrFilter, const char *FilterStr[], uint8_t countFiler); +void SerialPort_IrqProcessingFilter_DmaRxLoop(tSerialPortArtery *env, tSerialPortIO *virtualPort, uint16_t *counterBufFilterStr, uint8_t *bufStrFilter, uint16_t maxBufStrFilter, const char *FilterStr[], uint8_t countFiler); + +void SerialPort_IrqProcessing_DmaTx(tSerialPortArtery *env); + +tSerialPortIO vSerialPortGetIo(tSerialPortArtery *env); + +tSerialPortIO vSerialPortGetSnifferIo(tSerialPortArtery *env); + +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); + +#endif //SERIALPORT_SERIALPORT_ARTERY_H diff --git a/Src/SerialPortArtery.c b/Src/SerialPortArtery.c new file mode 100644 index 0000000..a3890ea --- /dev/null +++ b/Src/SerialPortArtery.c @@ -0,0 +1,786 @@ +// +// Created by cfif on 16.09.22. +// +#include +#include "SerialPortArtery.h" +#include "string.h" + +void vSerialPortInit( + 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 +) { + usart_reset(uart); + + crm_periph_clock_enable(uartClock, TRUE); + + usart_init(uart, BoundRate, USART_DATA_8BITS, USART_STOP_1_BIT); + + usart_transmitter_enable(uart, TRUE); + usart_receiver_enable(uart, TRUE); + + if (swap) { + usart_transmit_receive_pin_swap(uart, TRUE); + } + + usart_enable(uart, TRUE); + + usart_interrupt_enable(uart, USART_RDBF_INT, TRUE); + + NVIC_EnableIRQ(irq); + NVIC_SetPriority(irq, irqPriority); + + env->rxDataQueue = osMessageQueueNew(rxBufferLength, 1, NULL); + + if (rxSnifferLength) { + env->rxDataSnifferQueue = osMessageQueueNew(rxSnifferLength, 1, NULL); + } else { + env->rxDataSnifferQueue = 0; + } + + env->uart = uart; +} + +void vSerialPortInitExt( + tSerialPortArtery *env, + usart_type *uart, + bool swap, + usart_hardware_flow_control_type flow_control_type, + uint32_t BoundRate, + IRQn_Type irq, + crm_periph_clock_type uartClock, + uint8_t irqPriority, + uint32_t rxBufferLength, + uint32_t rxSnifferLength +) { + usart_reset(uart); + + crm_periph_clock_enable(uartClock, TRUE); + + usart_init(uart, BoundRate, USART_DATA_8BITS, USART_STOP_1_BIT); + usart_hardware_flow_control_set(uart, flow_control_type); + + usart_transmitter_enable(uart, TRUE); + usart_receiver_enable(uart, TRUE); + + if (swap) { + usart_transmit_receive_pin_swap(uart, TRUE); + } + + usart_enable(uart, TRUE); + + usart_interrupt_enable(uart, USART_RDBF_INT, TRUE); + + NVIC_EnableIRQ(irq); + NVIC_SetPriority(irq, irqPriority); + + env->rxDataQueue = osMessageQueueNew(rxBufferLength, 1, NULL); + + if (rxSnifferLength) { + env->rxDataSnifferQueue = osMessageQueueNew(rxSnifferLength, 1, NULL); + } else { + env->rxDataSnifferQueue = 0; + } + + env->uart = uart; +} + +void vSerialPortInitDMA( + tSerialPortArtery *env, + usart_type *uart, + + dma_type *DMA_RX, + dma_type *DMA_TX, + + dma_channel_type *RX_DMA_CHANNEL, + dmamux_channel_type *RX_DMA_CHANNEL_MUX, + dmamux_requst_id_sel_type RX_DMAMUX_DMAREQ_ID, + IRQn_Type RX_DMA_Channel_IRQ, + uint32_t RX_DMA_FDT_FLAG, + + uint8_t *DMA_BUF, + uint16_t DMA_BUF_LEN, + + + dma_channel_type *TX_DMA_CHANNEL, + dmamux_channel_type *TX_DMA_CHANNEL_MUX, + dmamux_requst_id_sel_type TX_DMAMUX_DMAREQ_ID, + IRQn_Type TX_DMA_Channel_IRQ, + uint32_t TX_DMA_FDT_FLAG, + + bool swap, + uint32_t BoundRate, + IRQn_Type irq, + crm_periph_clock_type uartClock, + uint8_t irqPriority, + uint32_t rxBufferLength, + uint32_t rxSnifferLength +) { + + { + if (DMA_RX)NVIC_DisableIRQ(RX_DMA_Channel_IRQ); + if (DMA_TX)NVIC_DisableIRQ(TX_DMA_Channel_IRQ); + NVIC_DisableIRQ(irq); + } + + /*включаем тактирование uart и нужных DMA */{ + crm_periph_clock_enable(uartClock, TRUE); + + if (DMA_RX == DMA1 || DMA_TX == DMA1) { + crm_periph_clock_enable(CRM_DMA1_PERIPH_CLOCK, TRUE); + } + if (DMA_RX == DMA2 || DMA_TX == DMA2) { + crm_periph_clock_enable(CRM_DMA2_PERIPH_CLOCK, TRUE); + } + } + + /*заполняем параметры и создаем все очереди до начала работы порта (иначе при раннем сробатывании прервывания все упадет)*/{ + env->txAccessQueue = osMessageQueueNew(1, 1, NULL); + + env->rxDataQueue = osMessageQueueNew(rxBufferLength, 1, NULL); + + if (rxSnifferLength) { + env->rxDataSnifferQueue = osMessageQueueNew(rxSnifferLength, 1, NULL); + } else { + env->rxDataSnifferQueue = 0; + } + + + env->rxDmaFdtFlag = RX_DMA_FDT_FLAG; + env->txDmaFdtFlag = TX_DMA_FDT_FLAG; + + env->txDmaChannel = TX_DMA_CHANNEL; + env->rxDmaChannel = RX_DMA_CHANNEL; + + env->rxDmaBuf = DMA_BUF; + env->rxDmaOffset = 0; + } + + + /*инициализируем uart */{ + env->uart = uart; + + usart_reset(uart); + + usart_init(uart, BoundRate, USART_DATA_8BITS, USART_STOP_1_BIT); + + usart_transmitter_enable(uart, TRUE); + usart_receiver_enable(uart, TRUE); + + usart_dma_receiver_enable(uart, TRUE); + usart_dma_transmitter_enable(uart, TRUE); + + + if (swap) { + usart_transmit_receive_pin_swap(uart, TRUE); + } + } + + + /*инициализируем RX DMA в циклическом режиме*/if (DMA_RX) { + dmamux_enable(DMA_RX, TRUE); + + // dma channel for usart rx configuration + dma_reset(RX_DMA_CHANNEL); + dma_default_para_init(&env->dma_rx_init_struct); + env->dma_rx_init_struct.buffer_size = DMA_BUF_LEN; + env->dma_rx_init_struct.direction = DMA_DIR_PERIPHERAL_TO_MEMORY; + env->dma_rx_init_struct.memory_base_addr = (uint32_t) DMA_BUF; + env->dma_rx_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_BYTE; + env->dma_rx_init_struct.memory_inc_enable = TRUE; + env->dma_rx_init_struct.peripheral_base_addr = (uint32_t) &uart->dt; + env->dma_rx_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_BYTE; + env->dma_rx_init_struct.peripheral_inc_enable = FALSE; + env->dma_rx_init_struct.priority = DMA_PRIORITY_HIGH; + env->dma_rx_init_struct.loop_mode_enable = TRUE; + dma_init(RX_DMA_CHANNEL, &env->dma_rx_init_struct); + + + // config flexible dma for usart7 rx + dmamux_init(RX_DMA_CHANNEL_MUX, RX_DMAMUX_DMAREQ_ID); + } + + + /*инициализируем TX DMA*/if (DMA_TX) { + dmamux_enable(DMA_TX, TRUE); + + // dma channel for usart tx configuration + dma_reset(TX_DMA_CHANNEL); + dma_default_para_init(&env->dma_tx_init_struct); + env->dma_tx_init_struct.buffer_size = 0; + env->dma_tx_init_struct.direction = DMA_DIR_MEMORY_TO_PERIPHERAL; + env->dma_tx_init_struct.memory_base_addr = 0; + env->dma_tx_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_BYTE; + env->dma_tx_init_struct.memory_inc_enable = TRUE; + env->dma_tx_init_struct.peripheral_base_addr = (uint32_t) &uart->dt; + env->dma_tx_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_BYTE; + env->dma_tx_init_struct.peripheral_inc_enable = FALSE; + env->dma_tx_init_struct.priority = DMA_PRIORITY_HIGH; + env->dma_tx_init_struct.loop_mode_enable = FALSE; + dma_init(TX_DMA_CHANNEL, &env->dma_tx_init_struct); + + // config flexible dma for usart7 tx + dmamux_init(TX_DMA_CHANNEL_MUX, TX_DMAMUX_DMAREQ_ID); + } + + + /*включаем rx dma и прерывания на нем*/if (DMA_RX) { + dma_interrupt_enable(RX_DMA_CHANNEL, DMA_FDT_INT, TRUE); + + NVIC_EnableIRQ(RX_DMA_Channel_IRQ); + NVIC_SetPriority(RX_DMA_Channel_IRQ, irqPriority); + + dma_channel_enable(RX_DMA_CHANNEL, TRUE); // uart7 rx begin dma receiving + } + + /*включаем прерывания на tx dma*/if (DMA_TX) { + dma_interrupt_enable(TX_DMA_CHANNEL, DMA_FDT_INT, TRUE); + + NVIC_EnableIRQ(TX_DMA_Channel_IRQ); + NVIC_SetPriority(TX_DMA_Channel_IRQ, irqPriority); + + } + + /*включаем uart и прерывания на нем*/{ + usart_interrupt_enable(uart, USART_IDLE_INT, TRUE); +// usart_interrupt_enable(uart, USART_RDBF_INT, FALSE); + + NVIC_EnableIRQ(irq); + NVIC_SetPriority(irq, irqPriority); + + usart_enable(uart, TRUE); + } +} + +void vSerialPortInitDMAExt( + tSerialPortArtery *env, + usart_type *uart, + + dma_type *DMA_RX, + dma_type *DMA_TX, + + dma_channel_type *RX_DMA_CHANNEL, + dmamux_channel_type *RX_DMA_CHANNEL_MUX, + dmamux_requst_id_sel_type RX_DMAMUX_DMAREQ_ID, + IRQn_Type RX_DMA_Channel_IRQ, + uint32_t RX_DMA_FDT_FLAG, + + uint8_t *DMA_BUF, + uint16_t DMA_BUF_LEN, + + + dma_channel_type *TX_DMA_CHANNEL, + dmamux_channel_type *TX_DMA_CHANNEL_MUX, + dmamux_requst_id_sel_type TX_DMAMUX_DMAREQ_ID, + IRQn_Type TX_DMA_Channel_IRQ, + uint32_t TX_DMA_FDT_FLAG, + + bool swap, + usart_hardware_flow_control_type flow_control_type, + uint32_t BoundRate, + IRQn_Type irq, + crm_periph_clock_type uartClock, + uint8_t irqPriority, + uint32_t rxBufferLength, + uint32_t rxSnifferLength +) { + + /*включаем тактирование uart и нужных DMA */{ + crm_periph_clock_enable(uartClock, TRUE); + + if (DMA_RX == DMA1 || DMA_TX == DMA1) { + crm_periph_clock_enable(CRM_DMA1_PERIPH_CLOCK, TRUE); + } + if (DMA_RX == DMA2 || DMA_TX == DMA2) { + crm_periph_clock_enable(CRM_DMA2_PERIPH_CLOCK, TRUE); + } + } + + /*заполняем параметры и создаем все очереди до начала работы порта (иначе при раннем сробатывании прервывания все упадет)*/{ + env->txAccessQueue = osMessageQueueNew(1, 1, NULL); + + env->rxDataQueue = osMessageQueueNew(rxBufferLength, 1, NULL); + + if (rxSnifferLength) { + env->rxDataSnifferQueue = osMessageQueueNew(rxSnifferLength, 1, NULL); + } else { + env->rxDataSnifferQueue = 0; + } + + + env->rxDmaFdtFlag = RX_DMA_FDT_FLAG; + env->txDmaFdtFlag = TX_DMA_FDT_FLAG; + + env->txDmaChannel = TX_DMA_CHANNEL; + env->rxDmaChannel = RX_DMA_CHANNEL; + + env->rxDmaBuf = DMA_BUF; + env->rxDmaOffset = 0; + } + + + /*инициализируем uart */{ + env->uart = uart; + + usart_reset(uart); + + usart_init(uart, BoundRate, USART_DATA_8BITS, USART_STOP_1_BIT); + usart_hardware_flow_control_set(uart, flow_control_type); + + usart_transmitter_enable(uart, TRUE); + usart_receiver_enable(uart, TRUE); + + usart_dma_receiver_enable(uart, TRUE); + usart_dma_transmitter_enable(uart, TRUE); + + + if (swap) { + usart_transmit_receive_pin_swap(uart, TRUE); + } + } + + + /*инициализируем RX DMA в циклическом режиме*/if (DMA_RX) { + dmamux_enable(DMA_RX, TRUE); + + // dma channel for usart rx configuration + dma_reset(RX_DMA_CHANNEL); + dma_default_para_init(&env->dma_rx_init_struct); + env->dma_rx_init_struct.buffer_size = DMA_BUF_LEN; + env->dma_rx_init_struct.direction = DMA_DIR_PERIPHERAL_TO_MEMORY; + env->dma_rx_init_struct.memory_base_addr = (uint32_t) DMA_BUF; + env->dma_rx_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_BYTE; + env->dma_rx_init_struct.memory_inc_enable = TRUE; + env->dma_rx_init_struct.peripheral_base_addr = (uint32_t) &uart->dt; + env->dma_rx_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_BYTE; + env->dma_rx_init_struct.peripheral_inc_enable = FALSE; + env->dma_rx_init_struct.priority = DMA_PRIORITY_HIGH; + env->dma_rx_init_struct.loop_mode_enable = TRUE; + dma_init(RX_DMA_CHANNEL, &env->dma_rx_init_struct); + + + // config flexible dma for usart7 rx + dmamux_init(RX_DMA_CHANNEL_MUX, RX_DMAMUX_DMAREQ_ID); + } + + + /*инициализируем TX DMA*/if (DMA_TX) { + dmamux_enable(DMA_TX, TRUE); + + // dma channel for usart tx configuration + dma_reset(TX_DMA_CHANNEL); + dma_default_para_init(&env->dma_tx_init_struct); + env->dma_tx_init_struct.buffer_size = 0; + env->dma_tx_init_struct.direction = DMA_DIR_MEMORY_TO_PERIPHERAL; + env->dma_tx_init_struct.memory_base_addr = 0; + env->dma_tx_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_BYTE; + env->dma_tx_init_struct.memory_inc_enable = TRUE; + env->dma_tx_init_struct.peripheral_base_addr = (uint32_t) &uart->dt; + env->dma_tx_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_BYTE; + env->dma_tx_init_struct.peripheral_inc_enable = FALSE; + env->dma_tx_init_struct.priority = DMA_PRIORITY_HIGH; + env->dma_tx_init_struct.loop_mode_enable = FALSE; + dma_init(TX_DMA_CHANNEL, &env->dma_tx_init_struct); + + // config flexible dma for usart7 tx + dmamux_init(TX_DMA_CHANNEL_MUX, TX_DMAMUX_DMAREQ_ID); + } + + + /*включаем rx dma и прерывания на нем*/if (DMA_RX) { + dma_interrupt_enable(RX_DMA_CHANNEL, DMA_FDT_INT, TRUE); + + NVIC_EnableIRQ(RX_DMA_Channel_IRQ); + NVIC_SetPriority(RX_DMA_Channel_IRQ, irqPriority); + + dma_channel_enable(RX_DMA_CHANNEL, TRUE); // uart7 rx begin dma receiving + } + + /*включаем прерывания на tx dma*/if (DMA_TX) { + dma_interrupt_enable(TX_DMA_CHANNEL, DMA_FDT_INT, TRUE); + + NVIC_EnableIRQ(TX_DMA_Channel_IRQ); + NVIC_SetPriority(TX_DMA_Channel_IRQ, irqPriority); + + } + + /*включаем uart и прерывания на нем*/{ + usart_interrupt_enable(uart, USART_IDLE_INT, TRUE); +// usart_interrupt_enable(uart, USART_RDBF_INT, FALSE); + + NVIC_EnableIRQ(irq); + NVIC_SetPriority(irq, irqPriority); + + usart_enable(uart, TRUE); + } +} + + +void vSerialPortSendDMA( + tSerialPortArtery *env, + usart_type *uart, + + dma_type *DMA, + dma_channel_type *DMA_CHANNEL, + dmamux_channel_type *DMA_CHANNEL_MUX, + dmamux_requst_id_sel_type DMAMUX_DMAREQ_ID, + uint8_t *DMA_BUF, + uint16_t DMA_BUF_LEN + +) { + dma_channel_enable(DMA_CHANNEL, FALSE); + + // dma channel for usart tx configuration + dma_reset(DMA_CHANNEL); + dma_default_para_init(&env->dma_tx_init_struct); + env->dma_tx_init_struct.buffer_size = DMA_BUF_LEN; + env->dma_tx_init_struct.direction = DMA_DIR_MEMORY_TO_PERIPHERAL; + env->dma_tx_init_struct.memory_base_addr = (uint32_t) DMA_BUF; + env->dma_tx_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_BYTE; + env->dma_tx_init_struct.memory_inc_enable = TRUE; + env->dma_tx_init_struct.peripheral_base_addr = (uint32_t) &uart->dt; + env->dma_tx_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_BYTE; + env->dma_tx_init_struct.peripheral_inc_enable = FALSE; + env->dma_tx_init_struct.priority = DMA_PRIORITY_MEDIUM; + env->dma_tx_init_struct.loop_mode_enable = FALSE; + dma_init(DMA_CHANNEL, &env->dma_tx_init_struct); + + // config flexible dma for usart7 tx + dmamux_init(DMA_CHANNEL_MUX, DMAMUX_DMAREQ_ID); + + dma_channel_enable(DMA_CHANNEL, TRUE); + +} + + +/* +void vSerialPortIrqProcessingDMA(tSerialPortArtery *env) { + + dma_channel_enable(env->dma_channel, FALSE); + + uint32_t len = env->dma_init_struct.buffer_size - env->dma_channel->dtcnt; + env->offset = len; + + for (uint32_t i = 0; i < len; ++i) { + osMessageQueuePut(env->rxDataQueue, &env->dma_buf[i], 0x0, 0U); + if (env->rxDataSnifferQueue) { + osMessageQueuePut(env->rxDataSnifferQueue, &env->dma_buf[i], 0x0, 0U); + } + } + + dma_init(env->dma_channel, &env->dma_init_struct); + dma_channel_enable(env->dma_channel, TRUE); +} +*/ + + +void SerialPortFilter_RxDmaBufToQueue(tSerialPortArtery *env, uint32_t bufEnd, + tSerialPortIO *virtualPort, + uint16_t *counterBufFilterStr, uint8_t *bufStrFilter, uint16_t maxBufStrFilter, + const char *FilterStr[], uint8_t countFiler) { + + for (uint32_t i = env->rxDmaOffset; i < bufEnd; ++i) { + osMessageQueuePut(env->rxDataQueue, &env->rxDmaBuf[i], 0x0, 0U); + if (env->rxDataSnifferQueue) { + + if (*counterBufFilterStr < maxBufStrFilter) { + bufStrFilter[*counterBufFilterStr] = env->rxDmaBuf[i]; + ++*counterBufFilterStr; + } else { + *counterBufFilterStr = 0; + } + + bool isFilterFind = false; + if (env->rxDmaBuf[i] == '\n') { + + for (uint8_t j = 0; j < countFiler; ++j) { + if (memcmp(bufStrFilter, FilterStr[j], strlen(FilterStr[j])) == 0) { + + SerialPortTransmit(virtualPort, bufStrFilter, *counterBufFilterStr, 0); + + isFilterFind = true; + break; + } + } + + if (isFilterFind == false) { + for (uint16_t j = 0; j < *counterBufFilterStr; ++j) + osMessageQueuePut(env->rxDataSnifferQueue, &bufStrFilter[j], 0x0, 0U); + } + + *counterBufFilterStr = 0; + memset(bufStrFilter, 0, maxBufStrFilter); + } + + } + } + +} + +void SerialPort_RxDmaBufToQueue(tSerialPortArtery *env, uint32_t bufEnd) { + + for (uint32_t i = env->rxDmaOffset; i < bufEnd; ++i) { + osMessageQueuePut(env->rxDataQueue, &env->rxDmaBuf[i], 0x0, 0U); + if (env->rxDataSnifferQueue) { + osMessageQueuePut(env->rxDataSnifferQueue, &env->rxDmaBuf[i], 0x0, 0U); + } + } + +} + +void SerialPort_IrqProcessing_UartIdle(tSerialPortArtery *env) { + // Смотрим idle прерывание + if (usart_flag_get(env->uart, USART_IDLEF_FLAG)) { + // Сброс прерывания + usart_data_receive(env->uart); + usart_flag_clear(env->uart, USART_IDLEF_FLAG); + size_t bufEnd = env->dma_rx_init_struct.buffer_size - env->rxDmaChannel->dtcnt; + SerialPort_RxDmaBufToQueue(env, bufEnd); + env->rxDmaOffset = bufEnd; + } +} + +void SerialPort_IrqProcessing_DmaRxLoop(tSerialPortArtery *env) { + if (dma_flag_get(env->rxDmaFdtFlag)) { + SerialPort_RxDmaBufToQueue(env, env->dma_rx_init_struct.buffer_size); + env->rxDmaOffset = 0; + dma_flag_clear(env->rxDmaFdtFlag); + } +} + + +void +SerialPort_IrqProcessingFilter_UartIdle(tSerialPortArtery *env, + tSerialPortIO *virtualPort, + uint16_t *counterBufFilterStr, uint8_t *bufStrFilter, uint16_t maxBufStrFilter, + const char *FilterStr[], uint8_t countFiler) { + // Смотрим idle прерывание + if (usart_flag_get(env->uart, USART_IDLEF_FLAG)) { + // Сброс прерывания + usart_data_receive(env->uart); + usart_flag_clear(env->uart, USART_IDLEF_FLAG); + size_t bufEnd = env->dma_rx_init_struct.buffer_size - env->rxDmaChannel->dtcnt; + SerialPortFilter_RxDmaBufToQueue(env, bufEnd, virtualPort, counterBufFilterStr, bufStrFilter, maxBufStrFilter, + FilterStr, + countFiler); + env->rxDmaOffset = bufEnd; + } +} + +void +SerialPort_IrqProcessingFilter_DmaRxLoop(tSerialPortArtery *env, + tSerialPortIO *virtualPort, + uint16_t *counterBufFilterStr, uint8_t *bufStrFilter, uint16_t maxBufStrFilter, + const char *FilterStr[], uint8_t countFiler) { + if (dma_flag_get(env->rxDmaFdtFlag)) { + SerialPortFilter_RxDmaBufToQueue(env, env->dma_rx_init_struct.buffer_size, + virtualPort, + counterBufFilterStr, bufStrFilter, maxBufStrFilter, + FilterStr, countFiler); + env->rxDmaOffset = 0; + dma_flag_clear(env->rxDmaFdtFlag); + } +} + + +static const uint8_t DUMMY_BYTE = 0xFF; + +void SerialPort_IrqProcessing_DmaTx(tSerialPortArtery *env) { + if (dma_flag_get(env->txDmaFdtFlag)) { + dma_flag_clear(env->txDmaFdtFlag); + osMessageQueuePut(env->txAccessQueue, &DUMMY_BYTE, 0, 0); + } +} + +void SerialPort_IrqProcessing_DmaTxBlind(tSerialPortArtery *env) { + if (dma_flag_get(env->txDmaFdtFlag)) { + dma_flag_clear(env->txDmaFdtFlag); +// osMessageQueuePut(env->txAccessQueue, &DUMMY_BYTE, 0, 0); + } +} + + +void vSerialPortIrqProcessing(tSerialPortArtery *env) { + + uint8_t data; + while (usart_flag_get(env->uart, USART_RDBF_FLAG)) { + data = usart_data_receive(env->uart); + osMessageQueuePut(env->rxDataQueue, &data, 0x0, 0U); + if (env->rxDataSnifferQueue) { + osMessageQueuePut(env->rxDataSnifferQueue, &data, 0x0, 0U); + } + } +} + + +static uint16_t vSerialPortReceiveQueue(tSerialPortArtery *env, uint8_t *data, uint16_t size, uint32_t timeout, + osMessageQueueId_t queueId) { + uint16_t received = 0; + + + if (timeout) { + uint32_t endMs = SystemGetMs() + timeout; + uint32_t leftMs; + + while (size && ((timeout == SystemWaitForever) || (endMs > SystemGetMs()))) { + leftMs = endMs - SystemGetMs(); + if (osMessageQueueGet(queueId, data, NULL, leftMs) == osOK) { + --size; + ++received; + ++data; + } + } + + } else { + while (size) { + if (osMessageQueueGet(queueId, data, NULL, 0) == osOK) { + --size; + ++received; + ++data; + } else { + return received; + } + } + } + + return received; + +} + +static uint16_t vSerialPortReceive(tSerialPortArtery *env, uint8_t *data, uint16_t size, uint32_t timeout) { + return vSerialPortReceiveQueue(env, data, size, timeout, env->rxDataQueue); +} + +static uint16_t vSerialPortReceiveSniffer(tSerialPortArtery *env, uint8_t *data, uint16_t size, uint32_t timeout) { + + return env->rxDataSnifferQueue + ? vSerialPortReceiveQueue(env, data, size, timeout, env->rxDataSnifferQueue) + : 0; +} + + +static uint16_t vSerialPortTransmitOverDma(tSerialPortArtery *env, uint8_t *data, uint16_t size, uint32_t timeout) { + uint16_t sent = 0; + uint32_t endMs = SystemGetMs() + timeout; + + dma_channel_enable(env->txDmaChannel, FALSE); + env->dma_tx_init_struct.buffer_size = size; + env->dma_tx_init_struct.memory_base_addr = (uint32_t) data; + dma_init(env->txDmaChannel, &env->dma_tx_init_struct); + dma_channel_enable(env->txDmaChannel, TRUE); + + uint8_t res; + + sent = (osMessageQueueGet(env->txAccessQueue, &res, 0, timeout) == osOK) ? size : 0; + +// SystemDelayMs(10); +// +// while ((timeout == SystemWaitForever) || (endMs > SystemGetMs())) { +// if (dma_flag_get(env->txDmaFdtFlag) != RESET) +// break; +// SystemDelayMs(5); +// } + + while ((timeout == SystemWaitForever) || (endMs > SystemGetMs())) { + if (usart_flag_get(env->uart, USART_TDC_FLAG)) + break; + } + + dma_channel_enable(env->txDmaChannel, FALSE); + +// sent = size; + return sent; +} + +static uint16_t +vSerialPortTransmitOverCore(tSerialPortArtery *env, uint8_t *data, uint16_t size, uint32_t timeout) { + uint16_t sent = 0; + uint32_t endMs = SystemGetMs() + timeout; + + while (size && ((timeout == SystemWaitForever) || (endMs > SystemGetMs()))) { + + if (usart_flag_get(env->uart, USART_TDBE_FLAG)) { + usart_data_transmit(env->uart, *data); + --size; + ++data; + ++sent; + } + + } + + while ((timeout == SystemWaitForever) || (endMs > SystemGetMs())) { + if (usart_flag_get(env->uart, USART_TDC_FLAG)) + break; + } + + return sent; +} + + +uint16_t vSerialPortBlindTransmit(tSerialPortArtery *env, uint8_t *data, uint16_t size, uint32_t timeout) { + + uint16_t sent = 0; + uint32_t endMs = SystemGetMs() + timeout; + + + while ((timeout == SystemWaitForever) || (endMs > SystemGetMs())) { + if (usart_flag_get(env->uart, USART_TDC_FLAG)) + break; + else { + asm("nop"); + } + } + +// dma_channel_enable(env->txDmaChannel, FALSE); + + dma_channel_enable(env->txDmaChannel, FALSE); + env->dma_tx_init_struct.buffer_size = size; + env->dma_tx_init_struct.memory_base_addr = (uint32_t) data; + dma_init(env->txDmaChannel, &env->dma_tx_init_struct); + dma_channel_enable(env->txDmaChannel, TRUE); + +// uint8_t res; +// int32_t s = SystemGetMs(); +// sent = (osMessageQueueGet(env->txAccessQueue, &res, 0, timeout) == osOK) ? size : 0; +// int32_t s1 = SystemGetMs(); +// int32_t s3 = s1 - s; + + + return sent; +} + +static SerialPortIOTransaction vSerialPortTransmitterGet(tSerialPortArtery *env) { + +#ifdef UART_DMA_SEND + if (env->txDmaChannel) + return (SerialPortIOTransaction) vSerialPortTransmitOverDma; + else + return (SerialPortIOTransaction) vSerialPortTransmitOverCore; +#else + return (SerialPortIOTransaction) vSerialPortTransmitOverCore; +#endif +} + +tSerialPortIO vSerialPortGetIo(tSerialPortArtery *env) { + tSerialPortIO io = { + .env = env, + .receive = (SerialPortIOTransaction) vSerialPortReceive, + .transmit = vSerialPortTransmitterGet(env) + }; + return io; +} + +tSerialPortIO vSerialPortGetSnifferIo(tSerialPortArtery *env) { + tSerialPortIO io = { + .env = env, + .receive = (SerialPortIOTransaction) vSerialPortReceiveSniffer, + .transmit = vSerialPortTransmitterGet(env) + }; + return io; +} diff --git a/modular.json b/modular.json new file mode 100644 index 0000000..fb08e8c --- /dev/null +++ b/modular.json @@ -0,0 +1,22 @@ +{ + "dep": [ + { + "type": "git", + "provider": "GONEC", + "repo": "SerialPort" + }, + { + "type": "git", + "provider": "GONEC", + "repo": "SystemDelayInterface" + } + ], + "cmake": { + "inc_dirs": [ + "Inc" + ], + "srcs": [ + "Src/**.c" + ] + } +} \ No newline at end of file