Начало
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