From cec583d47e1963c8ebc8ad7b84b22b9c0c822429 Mon Sep 17 00:00:00 2001 From: cfif Date: Tue, 11 Mar 2025 12:05:57 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B5=D1=85=D0=BE=D0=B4=20?= =?UTF-8?q?=D0=B2=20=D0=BD=D0=BE=D0=B2=D1=83=D1=8E=20=D0=BE=D1=80=D0=B3?= =?UTF-8?q?=D0=B0=D0=BD=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Inc/SerialPortGiga.h | 41 ++++++++ Src/SerialPortGiga.c | 233 +++++++++++++++++++++++++++++++++++++++++++ modular.json | 22 ++++ 3 files changed, 296 insertions(+) create mode 100755 Inc/SerialPortGiga.h create mode 100755 Src/SerialPortGiga.c create mode 100755 modular.json diff --git a/Inc/SerialPortGiga.h b/Inc/SerialPortGiga.h new file mode 100755 index 0000000..80981d9 --- /dev/null +++ b/Inc/SerialPortGiga.h @@ -0,0 +1,41 @@ +// +// Created by cfif on 16.09.22. +// + +#ifndef SERIALPORT_SERIALPORT_GIGA_H +#define SERIALPORT_SERIALPORT_GIGA_H + +#include "SerialPort.h" +#include "gd32f4xx.h" +#include "cmsis_os2.h" +#include "stdbool.h" + + +typedef struct { + uint32_t uart; + dma_channel_enum dma_channel; + dma_single_data_parameter_struct dma_init_struct; + uint8_t* dma_buf; + uint32_t offset; + osMessageQueueId_t rxDataQueue; + osMessageQueueId_t rxDataSnifferQueue; +} tSerialPortGiga; + +void vSerialPortInit( + tSerialPortGiga *env, + uint32_t uart, + uint32_t rxBufferLength +); + +void vSerialPortIrqProcessing(tSerialPortGiga *env); +void vSerialPortIrqProcessingDMA(tSerialPortGiga *env); + +void vSerialPortIrqProcessingDMAloop(tSerialPortGiga *env, uint32_t len); + +tSerialPortIO vSerialPortGetIo(tSerialPortGiga *env); + +tSerialPortIO vSerialPortGetSnifferIo(tSerialPortGiga *env); + +uint16_t vSerialPortTransmit(tSerialPortGiga *env, uint8_t *data, uint16_t size, uint32_t timeout); + +#endif //SERIALPORT_SERIALPORT_GIGA_H diff --git a/Src/SerialPortGiga.c b/Src/SerialPortGiga.c new file mode 100755 index 0000000..b8b09b8 --- /dev/null +++ b/Src/SerialPortGiga.c @@ -0,0 +1,233 @@ +// +// Created by cfif on 16.09.22. +// +#include +#include "SerialPortGiga.h" + + +void vSerialPortInit( + tSerialPortGiga *env, + uint32_t uart, + uint32_t rxBufferLength +) { + + env->rxDataQueue = osMessageQueueNew(rxBufferLength, 1, NULL); + + env->uart = uart; +} + +/* +void vSerialPortInitDMA( + 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 FLEX_CHANNEL, + uint8_t DMA_FLEXIBLE_UART, + + uint8_t *DMA_BUF, + uint16_t DMA_BUF_LEN, + IRQn_Type DMA_Channel_IRQ, + + + 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_parity_selection_config(uart, USART_PARITY_NONE); + + usart_transmitter_enable(uart, TRUE); + usart_receiver_enable(uart, TRUE); + + usart_dma_receiver_enable(uart, TRUE); + + if (swap) { +// usart_transmit_receive_pin_swap(uart, TRUE); + } + + usart_enable(uart, TRUE); + + usart_interrupt_enable(uart, USART_IDLE_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; + + +// dma_init_type dma_init_struct; + + // enable dma1 clock + crm_periph_clock_enable(CRM_DMA1_PERIPH_CLOCK, TRUE); + +// dmamux_enable(DMA, TRUE); + + // dma channel for usart rx configuration + dma_reset(DMA_CHANNEL); + dma_default_para_init(&env->dma_init_struct); + env->dma_init_struct.buffer_size = DMA_BUF_LEN; + env->dma_init_struct.direction = DMA_DIR_PERIPHERAL_TO_MEMORY; + env->dma_init_struct.memory_base_addr = (uint32_t) DMA_BUF; + env->dma_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_BYTE; + env->dma_init_struct.memory_inc_enable = TRUE; + env->dma_init_struct.peripheral_base_addr = (uint32_t) &uart->dt; + env->dma_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_BYTE; + env->dma_init_struct.peripheral_inc_enable = FALSE; + env->dma_init_struct.priority = DMA_PRIORITY_MEDIUM; + env->dma_init_struct.loop_mode_enable = TRUE; + dma_init(DMA_CHANNEL, &env->dma_init_struct); + + // enable transfer full data intterrupt + dma_interrupt_enable(DMA_CHANNEL, DMA_FDT_INT, TRUE); + + // dma1 channel4 interrupt nvic init +// nvic_irq_enable(DMA1_Channel4_IRQn, 0, 0); + NVIC_EnableIRQ(DMA_Channel_IRQ); + NVIC_SetPriority(DMA_Channel_IRQ, irqPriority); + + + dma_flexible_config(DMA, FLEX_CHANNEL, DMA_FLEXIBLE_UART); +// dmamux_init(DMA_CHANNEL_MUX, DMAMUX_DMAREQ_ID); + + env->dma_channel = DMA_CHANNEL; + env->dma_buf = DMA_BUF; + env->offset = 0; + + dma_channel_enable(DMA_CHANNEL, TRUE); + + +} +*/ + +void vSerialPortIrqProcessingDMAloop(tSerialPortGiga *env, uint32_t len) { + + for (uint32_t i = env->offset; i < len; ++i) { + osMessageQueuePut(env->rxDataQueue, &env->dma_buf[i], 0x0, 0U); + if (env->rxDataSnifferQueue) { + osMessageQueuePut(env->rxDataSnifferQueue, &env->dma_buf[i], 0x0, 0U); + } + } + + env->offset = len; +} + + +void vSerialPortIrqProcessing(tSerialPortGiga *env) { + uint8_t data; + + while (usart_flag_get(env->uart, USART_FLAG_RBNE)) { + 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(tSerialPortGiga *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(tSerialPortGiga *env, uint8_t *data, uint16_t size, uint32_t timeout) { + return vSerialPortReceiveQueue(env, data, size, timeout, env->rxDataQueue); +} + +static uint16_t vSerialPortReceiveSniffer(tSerialPortGiga *env, uint8_t *data, uint16_t size, uint32_t timeout) { + + return env->rxDataSnifferQueue + ? vSerialPortReceiveQueue(env, data, size, timeout, env->rxDataSnifferQueue) + : 0; +} + +uint16_t vSerialPortTransmit(tSerialPortGiga *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_FLAG_TBE)) { + usart_data_transmit(env->uart, *data); + --size; + ++data; + ++sent; + } + + } + + while ((timeout == SystemWaitForever) || (endMs > SystemGetMs())) { + if (usart_flag_get(env->uart, USART_FLAG_TC)) + break; + } + + return sent; +} + +tSerialPortIO vSerialPortGetIo(tSerialPortGiga *env) { + tSerialPortIO io = { + .env = env, + .receive = (SerialPortIOTransaction) vSerialPortReceive, + .transmit = (SerialPortIOTransaction) vSerialPortTransmit + }; + return io; +} + +tSerialPortIO vSerialPortGetSnifferIo(tSerialPortGiga *env) { + tSerialPortIO io = { + .env = env, + .receive = (SerialPortIOTransaction) vSerialPortReceiveSniffer, + .transmit = (SerialPortIOTransaction) vSerialPortTransmit + }; + return io; +} diff --git a/modular.json b/modular.json new file mode 100755 index 0000000..4b69a96 --- /dev/null +++ b/modular.json @@ -0,0 +1,22 @@ +{ + "dep": [ + { + "type": "git", + "provider": "GONEC_BOOT_MODEM", + "repo": "SerialPort" + }, + { + "type": "git", + "provider": "GONEC_BOOT_MODEM", + "repo": "SystemDelayInterface" + } + ], + "cmake": { + "inc_dirs": [ + "Inc" + ], + "srcs": [ + "Src/**.c" + ] + } +} \ No newline at end of file