// // Created by cfif on 16.09.22. // #include #include "SerialPortArtery.h" #include "string.h" void vSerialPortInit( tSerialPortArtery *env, usart_type *uart, bool swap, uint32_t BoundRate, IRQn_Type irq, crm_periph_clock_type uartClock, uint8_t irqPriority, uint32_t rxBufferLength, uint32_t rxSnifferLength ) { usart_reset(uart); crm_periph_clock_enable(uartClock, TRUE); usart_init(uart, BoundRate, USART_DATA_8BITS, USART_STOP_1_BIT); usart_transmitter_enable(uart, TRUE); usart_receiver_enable(uart, TRUE); if (swap) { usart_transmit_receive_pin_swap(uart, TRUE); } usart_enable(uart, TRUE); usart_interrupt_enable(uart, USART_RDBF_INT, TRUE); NVIC_EnableIRQ(irq); NVIC_SetPriority(irq, irqPriority); env->rxDataQueue = osMessageQueueNew(rxBufferLength, 1, NULL); if (rxSnifferLength) { env->rxDataSnifferQueue = osMessageQueueNew(rxSnifferLength, 1, NULL); } else { env->rxDataSnifferQueue = 0; } env->uart = uart; } void vSerialPortInitExt( tSerialPortArtery *env, usart_type *uart, bool swap, usart_hardware_flow_control_type flow_control_type, uint32_t BoundRate, IRQn_Type irq, crm_periph_clock_type uartClock, uint8_t irqPriority, uint32_t rxBufferLength, uint32_t rxSnifferLength ) { usart_reset(uart); crm_periph_clock_enable(uartClock, TRUE); usart_init(uart, BoundRate, USART_DATA_8BITS, USART_STOP_1_BIT); usart_hardware_flow_control_set(uart, flow_control_type); usart_transmitter_enable(uart, TRUE); usart_receiver_enable(uart, TRUE); if (swap) { usart_transmit_receive_pin_swap(uart, TRUE); } usart_enable(uart, TRUE); usart_interrupt_enable(uart, USART_RDBF_INT, TRUE); NVIC_EnableIRQ(irq); NVIC_SetPriority(irq, irqPriority); env->rxDataQueue = osMessageQueueNew(rxBufferLength, 1, NULL); if (rxSnifferLength) { env->rxDataSnifferQueue = osMessageQueueNew(rxSnifferLength, 1, NULL); } else { env->rxDataSnifferQueue = 0; } env->uart = uart; } void vSerialPortInitDMA( tSerialPortArtery *env, usart_type *uart, dma_type *DMA_RX, dma_type *DMA_TX, dma_channel_type *RX_DMA_CHANNEL, dmamux_channel_type *RX_DMA_CHANNEL_MUX, dmamux_requst_id_sel_type RX_DMAMUX_DMAREQ_ID, IRQn_Type RX_DMA_Channel_IRQ, uint32_t RX_DMA_FDT_FLAG, uint8_t *DMA_BUF, uint16_t DMA_BUF_LEN, dma_channel_type *TX_DMA_CHANNEL, dmamux_channel_type *TX_DMA_CHANNEL_MUX, dmamux_requst_id_sel_type TX_DMAMUX_DMAREQ_ID, IRQn_Type TX_DMA_Channel_IRQ, uint32_t TX_DMA_FDT_FLAG, bool swap, uint32_t BoundRate, IRQn_Type irq, crm_periph_clock_type uartClock, uint8_t irqPriority, uint32_t rxBufferLength, uint32_t rxSnifferLength ) { { if (DMA_RX)NVIC_DisableIRQ(RX_DMA_Channel_IRQ); if (DMA_TX)NVIC_DisableIRQ(TX_DMA_Channel_IRQ); NVIC_DisableIRQ(irq); } /*включаем тактирование uart и нужных DMA */{ crm_periph_clock_enable(uartClock, TRUE); if (DMA_RX == DMA1 || DMA_TX == DMA1) { crm_periph_clock_enable(CRM_DMA1_PERIPH_CLOCK, TRUE); } if (DMA_RX == DMA2 || DMA_TX == DMA2) { crm_periph_clock_enable(CRM_DMA2_PERIPH_CLOCK, TRUE); } } /*заполняем параметры и создаем все очереди до начала работы порта (иначе при раннем сробатывании прервывания все упадет)*/{ env->txAccessQueue = osMessageQueueNew(1, 1, NULL); env->rxDataQueue = osMessageQueueNew(rxBufferLength, 1, NULL); if (rxSnifferLength) { env->rxDataSnifferQueue = osMessageQueueNew(rxSnifferLength, 1, NULL); } else { env->rxDataSnifferQueue = 0; } env->rxDmaFdtFlag = RX_DMA_FDT_FLAG; env->txDmaFdtFlag = TX_DMA_FDT_FLAG; env->txDmaChannel = TX_DMA_CHANNEL; env->rxDmaChannel = RX_DMA_CHANNEL; env->rxDmaBuf = DMA_BUF; env->rxDmaOffset = 0; } /*инициализируем uart */{ env->uart = uart; usart_reset(uart); usart_init(uart, BoundRate, USART_DATA_8BITS, USART_STOP_1_BIT); usart_transmitter_enable(uart, TRUE); usart_receiver_enable(uart, TRUE); usart_dma_receiver_enable(uart, TRUE); usart_dma_transmitter_enable(uart, TRUE); if (swap) { usart_transmit_receive_pin_swap(uart, TRUE); } } /*инициализируем RX DMA в циклическом режиме*/if (DMA_RX) { dmamux_enable(DMA_RX, TRUE); // dma channel for usart rx configuration dma_reset(RX_DMA_CHANNEL); dma_default_para_init(&env->dma_rx_init_struct); env->dma_rx_init_struct.buffer_size = DMA_BUF_LEN; env->dma_rx_init_struct.direction = DMA_DIR_PERIPHERAL_TO_MEMORY; env->dma_rx_init_struct.memory_base_addr = (uint32_t) DMA_BUF; env->dma_rx_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_BYTE; env->dma_rx_init_struct.memory_inc_enable = TRUE; env->dma_rx_init_struct.peripheral_base_addr = (uint32_t) &uart->dt; env->dma_rx_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_BYTE; env->dma_rx_init_struct.peripheral_inc_enable = FALSE; env->dma_rx_init_struct.priority = DMA_PRIORITY_HIGH; env->dma_rx_init_struct.loop_mode_enable = TRUE; dma_init(RX_DMA_CHANNEL, &env->dma_rx_init_struct); // config flexible dma for usart7 rx dmamux_init(RX_DMA_CHANNEL_MUX, RX_DMAMUX_DMAREQ_ID); } /*инициализируем TX DMA*/if (DMA_TX) { dmamux_enable(DMA_TX, TRUE); // dma channel for usart tx configuration dma_reset(TX_DMA_CHANNEL); dma_default_para_init(&env->dma_tx_init_struct); env->dma_tx_init_struct.buffer_size = 0; env->dma_tx_init_struct.direction = DMA_DIR_MEMORY_TO_PERIPHERAL; env->dma_tx_init_struct.memory_base_addr = 0; env->dma_tx_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_BYTE; env->dma_tx_init_struct.memory_inc_enable = TRUE; env->dma_tx_init_struct.peripheral_base_addr = (uint32_t) &uart->dt; env->dma_tx_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_BYTE; env->dma_tx_init_struct.peripheral_inc_enable = FALSE; env->dma_tx_init_struct.priority = DMA_PRIORITY_HIGH; env->dma_tx_init_struct.loop_mode_enable = FALSE; dma_init(TX_DMA_CHANNEL, &env->dma_tx_init_struct); // config flexible dma for usart7 tx dmamux_init(TX_DMA_CHANNEL_MUX, TX_DMAMUX_DMAREQ_ID); } /*включаем rx dma и прерывания на нем*/if (DMA_RX) { dma_interrupt_enable(RX_DMA_CHANNEL, DMA_FDT_INT, TRUE); NVIC_EnableIRQ(RX_DMA_Channel_IRQ); NVIC_SetPriority(RX_DMA_Channel_IRQ, irqPriority); dma_channel_enable(RX_DMA_CHANNEL, TRUE); // uart7 rx begin dma receiving } /*включаем прерывания на tx dma*/if (DMA_TX) { dma_interrupt_enable(TX_DMA_CHANNEL, DMA_FDT_INT, TRUE); NVIC_EnableIRQ(TX_DMA_Channel_IRQ); NVIC_SetPriority(TX_DMA_Channel_IRQ, irqPriority); } /*включаем uart и прерывания на нем*/{ usart_interrupt_enable(uart, USART_IDLE_INT, TRUE); // usart_interrupt_enable(uart, USART_RDBF_INT, FALSE); NVIC_EnableIRQ(irq); NVIC_SetPriority(irq, irqPriority); usart_enable(uart, TRUE); } } void vSerialPortInitDMAExt( tSerialPortArtery *env, usart_type *uart, dma_type *DMA_RX, dma_type *DMA_TX, dma_channel_type *RX_DMA_CHANNEL, dmamux_channel_type *RX_DMA_CHANNEL_MUX, dmamux_requst_id_sel_type RX_DMAMUX_DMAREQ_ID, IRQn_Type RX_DMA_Channel_IRQ, uint32_t RX_DMA_FDT_FLAG, uint8_t *DMA_BUF, uint16_t DMA_BUF_LEN, dma_channel_type *TX_DMA_CHANNEL, dmamux_channel_type *TX_DMA_CHANNEL_MUX, dmamux_requst_id_sel_type TX_DMAMUX_DMAREQ_ID, IRQn_Type TX_DMA_Channel_IRQ, uint32_t TX_DMA_FDT_FLAG, bool swap, usart_hardware_flow_control_type flow_control_type, uint32_t BoundRate, IRQn_Type irq, crm_periph_clock_type uartClock, uint8_t irqPriority, uint32_t rxBufferLength, uint32_t rxSnifferLength ) { /*включаем тактирование uart и нужных DMA */{ crm_periph_clock_enable(uartClock, TRUE); if (DMA_RX == DMA1 || DMA_TX == DMA1) { crm_periph_clock_enable(CRM_DMA1_PERIPH_CLOCK, TRUE); } if (DMA_RX == DMA2 || DMA_TX == DMA2) { crm_periph_clock_enable(CRM_DMA2_PERIPH_CLOCK, TRUE); } } /*заполняем параметры и создаем все очереди до начала работы порта (иначе при раннем сробатывании прервывания все упадет)*/{ env->txAccessQueue = osMessageQueueNew(1, 1, NULL); env->rxDataQueue = osMessageQueueNew(rxBufferLength, 1, NULL); if (rxSnifferLength) { env->rxDataSnifferQueue = osMessageQueueNew(rxSnifferLength, 1, NULL); } else { env->rxDataSnifferQueue = 0; } env->rxDmaFdtFlag = RX_DMA_FDT_FLAG; env->txDmaFdtFlag = TX_DMA_FDT_FLAG; env->txDmaChannel = TX_DMA_CHANNEL; env->rxDmaChannel = RX_DMA_CHANNEL; env->rxDmaBuf = DMA_BUF; env->rxDmaOffset = 0; } /*инициализируем uart */{ env->uart = uart; usart_reset(uart); usart_init(uart, BoundRate, USART_DATA_8BITS, USART_STOP_1_BIT); usart_hardware_flow_control_set(uart, flow_control_type); usart_transmitter_enable(uart, TRUE); usart_receiver_enable(uart, TRUE); usart_dma_receiver_enable(uart, TRUE); usart_dma_transmitter_enable(uart, TRUE); if (swap) { usart_transmit_receive_pin_swap(uart, TRUE); } } /*инициализируем RX DMA в циклическом режиме*/if (DMA_RX) { dmamux_enable(DMA_RX, TRUE); // dma channel for usart rx configuration dma_reset(RX_DMA_CHANNEL); dma_default_para_init(&env->dma_rx_init_struct); env->dma_rx_init_struct.buffer_size = DMA_BUF_LEN; env->dma_rx_init_struct.direction = DMA_DIR_PERIPHERAL_TO_MEMORY; env->dma_rx_init_struct.memory_base_addr = (uint32_t) DMA_BUF; env->dma_rx_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_BYTE; env->dma_rx_init_struct.memory_inc_enable = TRUE; env->dma_rx_init_struct.peripheral_base_addr = (uint32_t) &uart->dt; env->dma_rx_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_BYTE; env->dma_rx_init_struct.peripheral_inc_enable = FALSE; env->dma_rx_init_struct.priority = DMA_PRIORITY_HIGH; env->dma_rx_init_struct.loop_mode_enable = TRUE; dma_init(RX_DMA_CHANNEL, &env->dma_rx_init_struct); // config flexible dma for usart7 rx dmamux_init(RX_DMA_CHANNEL_MUX, RX_DMAMUX_DMAREQ_ID); } /*инициализируем TX DMA*/if (DMA_TX) { dmamux_enable(DMA_TX, TRUE); // dma channel for usart tx configuration dma_reset(TX_DMA_CHANNEL); dma_default_para_init(&env->dma_tx_init_struct); env->dma_tx_init_struct.buffer_size = 0; env->dma_tx_init_struct.direction = DMA_DIR_MEMORY_TO_PERIPHERAL; env->dma_tx_init_struct.memory_base_addr = 0; env->dma_tx_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_BYTE; env->dma_tx_init_struct.memory_inc_enable = TRUE; env->dma_tx_init_struct.peripheral_base_addr = (uint32_t) &uart->dt; env->dma_tx_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_BYTE; env->dma_tx_init_struct.peripheral_inc_enable = FALSE; env->dma_tx_init_struct.priority = DMA_PRIORITY_HIGH; env->dma_tx_init_struct.loop_mode_enable = FALSE; dma_init(TX_DMA_CHANNEL, &env->dma_tx_init_struct); // config flexible dma for usart7 tx dmamux_init(TX_DMA_CHANNEL_MUX, TX_DMAMUX_DMAREQ_ID); } /*включаем rx dma и прерывания на нем*/if (DMA_RX) { dma_interrupt_enable(RX_DMA_CHANNEL, DMA_FDT_INT, TRUE); NVIC_EnableIRQ(RX_DMA_Channel_IRQ); NVIC_SetPriority(RX_DMA_Channel_IRQ, irqPriority); dma_channel_enable(RX_DMA_CHANNEL, TRUE); // uart7 rx begin dma receiving } /*включаем прерывания на tx dma*/if (DMA_TX) { dma_interrupt_enable(TX_DMA_CHANNEL, DMA_FDT_INT, TRUE); NVIC_EnableIRQ(TX_DMA_Channel_IRQ); NVIC_SetPriority(TX_DMA_Channel_IRQ, irqPriority); } /*включаем uart и прерывания на нем*/{ usart_interrupt_enable(uart, USART_IDLE_INT, TRUE); // usart_interrupt_enable(uart, USART_RDBF_INT, FALSE); NVIC_EnableIRQ(irq); NVIC_SetPriority(irq, irqPriority); usart_enable(uart, TRUE); } } void vSerialPortSendDMA( tSerialPortArtery *env, usart_type *uart, dma_type *DMA, dma_channel_type *DMA_CHANNEL, dmamux_channel_type *DMA_CHANNEL_MUX, dmamux_requst_id_sel_type DMAMUX_DMAREQ_ID, uint8_t *DMA_BUF, uint16_t DMA_BUF_LEN ) { dma_channel_enable(DMA_CHANNEL, FALSE); // dma channel for usart tx configuration dma_reset(DMA_CHANNEL); dma_default_para_init(&env->dma_tx_init_struct); env->dma_tx_init_struct.buffer_size = DMA_BUF_LEN; env->dma_tx_init_struct.direction = DMA_DIR_MEMORY_TO_PERIPHERAL; env->dma_tx_init_struct.memory_base_addr = (uint32_t) DMA_BUF; env->dma_tx_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_BYTE; env->dma_tx_init_struct.memory_inc_enable = TRUE; env->dma_tx_init_struct.peripheral_base_addr = (uint32_t) &uart->dt; env->dma_tx_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_BYTE; env->dma_tx_init_struct.peripheral_inc_enable = FALSE; env->dma_tx_init_struct.priority = DMA_PRIORITY_MEDIUM; env->dma_tx_init_struct.loop_mode_enable = FALSE; dma_init(DMA_CHANNEL, &env->dma_tx_init_struct); // config flexible dma for usart7 tx dmamux_init(DMA_CHANNEL_MUX, DMAMUX_DMAREQ_ID); dma_channel_enable(DMA_CHANNEL, TRUE); } /* void vSerialPortIrqProcessingDMA(tSerialPortArtery *env) { dma_channel_enable(env->dma_channel, FALSE); uint32_t len = env->dma_init_struct.buffer_size - env->dma_channel->dtcnt; env->offset = len; for (uint32_t i = 0; i < len; ++i) { osMessageQueuePut(env->rxDataQueue, &env->dma_buf[i], 0x0, 0U); if (env->rxDataSnifferQueue) { osMessageQueuePut(env->rxDataSnifferQueue, &env->dma_buf[i], 0x0, 0U); } } dma_init(env->dma_channel, &env->dma_init_struct); dma_channel_enable(env->dma_channel, TRUE); } */ void SerialPortFilter_RxDmaBufToQueue(tSerialPortArtery *env, uint32_t bufEnd, tSerialPortIO *virtualPort, uint16_t *counterBufFilterStr, uint8_t *bufStrFilter, uint16_t maxBufStrFilter, const char *FilterStr[], uint8_t countFiler) { for (uint32_t i = env->rxDmaOffset; i < bufEnd; ++i) { osMessageQueuePut(env->rxDataQueue, &env->rxDmaBuf[i], 0x0, 0U); if (env->rxDataSnifferQueue) { if (*counterBufFilterStr < maxBufStrFilter) { bufStrFilter[*counterBufFilterStr] = env->rxDmaBuf[i]; ++*counterBufFilterStr; } else { *counterBufFilterStr = 0; } bool isFilterFind = false; if (env->rxDmaBuf[i] == '\n') { for (uint8_t j = 0; j < countFiler; ++j) { if (memcmp(bufStrFilter, FilterStr[j], strlen(FilterStr[j])) == 0) { SerialPortTransmit(virtualPort, bufStrFilter, *counterBufFilterStr, 0); isFilterFind = true; break; } } if (isFilterFind == false) { for (uint16_t j = 0; j < *counterBufFilterStr; ++j) osMessageQueuePut(env->rxDataSnifferQueue, &bufStrFilter[j], 0x0, 0U); } *counterBufFilterStr = 0; memset(bufStrFilter, 0, maxBufStrFilter); } } } } void SerialPort_RxDmaBufToQueue(tSerialPortArtery *env, uint32_t bufEnd) { 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; }