787 lines
25 KiB
C
787 lines
25 KiB
C
//
|
||
// Created by cfif on 16.09.22.
|
||
//
|
||
#include <SystemDelayInterface.h>
|
||
#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;
|
||
}
|