Начало
This commit is contained in:
commit
c72b2179f5
|
|
@ -0,0 +1,213 @@
|
||||||
|
//
|
||||||
|
// 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;
|
||||||
|
osMessageQueueId_t rxDataSnifferSecondQueue;
|
||||||
|
} 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);
|
||||||
|
|
||||||
|
tSerialPortIO SerialPort_GetSnifferSecondIo(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
|
||||||
|
|
@ -0,0 +1,801 @@
|
||||||
|
//
|
||||||
|
// 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) {
|
||||||
|
osStatus_t res;
|
||||||
|
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 vSerialPortReceiveSnifferSecond(tSerialPortArtery *env, uint8_t *data, uint16_t size, uint32_t timeout) {
|
||||||
|
|
||||||
|
return env->rxDataSnifferSecondQueue
|
||||||
|
? vSerialPortReceiveQueue(env, data, size, timeout, env->rxDataSnifferSecondQueue)
|
||||||
|
: 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
tSerialPortIO SerialPort_GetSnifferSecondIo(tSerialPortArtery *env) {
|
||||||
|
tSerialPortIO io = {
|
||||||
|
.env = env,
|
||||||
|
.receive = (SerialPortIOTransaction) vSerialPortReceiveSnifferSecond,
|
||||||
|
.transmit = vSerialPortTransmitterGet(env)
|
||||||
|
};
|
||||||
|
return io;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
{
|
||||||
|
"dep": [
|
||||||
|
{
|
||||||
|
"type": "git",
|
||||||
|
"provider": "HVAC_DEV",
|
||||||
|
"repo": "SerialPort"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "git",
|
||||||
|
"provider": "HVAC_DEV",
|
||||||
|
"repo": "SystemDelayInterface"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"cmake": {
|
||||||
|
"inc_dirs": [
|
||||||
|
"Inc"
|
||||||
|
],
|
||||||
|
"srcs": [
|
||||||
|
"Src/**.c"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue