229 lines
7.2 KiB
C
Executable File
229 lines
7.2 KiB
C
Executable File
//
|
||
// Created by cfif on 15.11.22.
|
||
//
|
||
#include "SerialPorts.h"
|
||
#include "gd32f4xx.h"
|
||
|
||
tSerialPorts SERIAL_PORTS;
|
||
|
||
uint8_t buf_UART0_DMA[2048];
|
||
|
||
void USART0_IRQHandler() {
|
||
|
||
// Смотрим idle прерывание
|
||
if (usart_flag_get(SERIAL_PORTS.GONEC0.uart, USART_FLAG_IDLE)) {
|
||
// Сброс прерывания
|
||
usart_data_receive(SERIAL_PORTS.GONEC0.uart);
|
||
|
||
vSerialPortIrqProcessingDMAloop(&SERIAL_PORTS.GONEC0, SERIAL_PORTS.GONEC0.dma_init_struct.number -
|
||
dma_transfer_number_get(DMA1, DMA_CH2));
|
||
|
||
}
|
||
|
||
}
|
||
|
||
|
||
void DMA1_Channel2_IRQHandler(void) {
|
||
if (dma_flag_get(DMA1,DMA_CH2,DMA_FLAG_FTF)) {
|
||
|
||
vSerialPortIrqProcessingDMAloop(&SERIAL_PORTS.GONEC0,
|
||
SERIAL_PORTS.GONEC0.dma_init_struct.number);
|
||
SERIAL_PORTS.GONEC0.offset = 0;
|
||
dma_flag_clear(DMA1, DMA_CH2, DMA_FLAG_FTF);
|
||
}
|
||
}
|
||
|
||
#define USART0_RDATA_ADDRESS ((uint32_t)&USART_DATA(USART0))
|
||
|
||
// Настройка порта
|
||
static void vSerialPort_InitUSART0(tSerialPortGiga *env) {
|
||
|
||
env->dma_buf = buf_UART0_DMA;
|
||
|
||
rcu_periph_clock_enable(RCU_DMA1);
|
||
|
||
env->dma_channel = DMA_CH2;
|
||
|
||
dma_deinit(DMA1, DMA_CH2);
|
||
env->dma_init_struct.direction = DMA_PERIPH_TO_MEMORY;
|
||
env->dma_init_struct.memory0_addr = (uint32_t)buf_UART0_DMA;
|
||
env->dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
|
||
env->dma_init_struct.number = sizeof(buf_UART0_DMA);
|
||
env->dma_init_struct.periph_addr = USART0_RDATA_ADDRESS;
|
||
env->dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
|
||
env->dma_init_struct.periph_memory_width = DMA_PERIPH_WIDTH_8BIT;
|
||
env->dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
|
||
// env->dma_init_struct.circular_mode = DMA_CIRCULAR_MODE_ENABLE;
|
||
dma_single_data_mode_init(DMA1, DMA_CH2, &env->dma_init_struct);
|
||
|
||
/* configure DMA mode */
|
||
dma_circulation_enable(DMA1, DMA_CH2);
|
||
dma_channel_subperipheral_select(DMA1, DMA_CH2, DMA_SUBPERI4);
|
||
/* enable DMA1 channel7 transfer complete interrupt */
|
||
dma_interrupt_enable(DMA1, DMA_CH2, DMA_CHXCTL_FTFIE);
|
||
/* enable DMA1 channel2 */
|
||
dma_channel_enable(DMA1, DMA_CH2);
|
||
|
||
|
||
|
||
/* enable GPIO clock */
|
||
rcu_periph_clock_enable(RCU_GPIOA);
|
||
|
||
/* enable USART clock */
|
||
rcu_periph_clock_enable(RCU_USART0);
|
||
|
||
/* connect port to USARTx_Tx */
|
||
gpio_af_set(GPIOA, GPIO_AF_7, GPIO_PIN_9);
|
||
|
||
/* connect port to USARTx_Rx */
|
||
gpio_af_set(GPIOA, GPIO_AF_7, GPIO_PIN_10);
|
||
|
||
/* configure USART Tx as alternate function push-pull */
|
||
gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_9);
|
||
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);
|
||
|
||
/* configure USART Rx as alternate function push-pull */
|
||
gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_10);
|
||
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_10);
|
||
|
||
/* configure USART */
|
||
usart_deinit(USART0);
|
||
usart_baudrate_set(USART0, 921600);
|
||
// usart_halfduplex_enable(USART1);
|
||
|
||
usart_receive_config(USART0, USART_RECEIVE_ENABLE);
|
||
usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);
|
||
usart_dma_receive_config(USART0, USART_RECEIVE_DMA_ENABLE);
|
||
usart_enable(USART0);
|
||
|
||
/* clear the USART1 data register */
|
||
usart_data_receive(USART0);
|
||
|
||
usart_interrupt_enable(USART0, USART_INT_IDLE);
|
||
|
||
NVIC_EnableIRQ(USART0_IRQn);
|
||
NVIC_SetPriority(USART0_IRQn, 0xFF);
|
||
|
||
NVIC_EnableIRQ(DMA1_Channel2_IRQn);
|
||
NVIC_SetPriority(DMA1_Channel2_IRQn, 0xFF);
|
||
|
||
vSerialPortInit(env, USART0, 3200);
|
||
|
||
}
|
||
|
||
uint8_t buf_UART1_DMA[2048];
|
||
|
||
void USART1_IRQHandler() {
|
||
// Смотрим idle прерывание
|
||
if (usart_flag_get(SERIAL_PORTS.GONEC1.uart, USART_FLAG_IDLE)) {
|
||
// Сброс прерывания
|
||
usart_data_receive(SERIAL_PORTS.GONEC1.uart);
|
||
|
||
vSerialPortIrqProcessingDMAloop(&SERIAL_PORTS.GONEC1, SERIAL_PORTS.GONEC1.dma_init_struct.number -
|
||
dma_transfer_number_get(DMA0, DMA_CH5));
|
||
|
||
}
|
||
|
||
}
|
||
|
||
|
||
void DMA0_Channel5_IRQHandler(void) {
|
||
if (dma_flag_get(DMA0,DMA_CH5,DMA_FLAG_FTF)) {
|
||
|
||
vSerialPortIrqProcessingDMAloop(&SERIAL_PORTS.GONEC1,
|
||
SERIAL_PORTS.GONEC1.dma_init_struct.number);
|
||
SERIAL_PORTS.GONEC1.offset = 0;
|
||
dma_flag_clear(DMA0, DMA_CH5, DMA_FLAG_FTF);
|
||
}
|
||
}
|
||
|
||
|
||
#define USART1_RDATA_ADDRESS ((uint32_t)&USART_DATA(USART1))
|
||
|
||
// Настройка порта
|
||
static void vSerialPort_InitUSART1(tSerialPortGiga *env) {
|
||
|
||
env->dma_buf = buf_UART1_DMA;
|
||
|
||
rcu_periph_clock_enable(RCU_DMA0);
|
||
|
||
env->dma_channel = DMA_CH5;
|
||
|
||
dma_deinit(DMA0, DMA_CH5);
|
||
env->dma_init_struct.direction = DMA_PERIPH_TO_MEMORY;
|
||
env->dma_init_struct.memory0_addr = (uint32_t)buf_UART1_DMA;
|
||
env->dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
|
||
env->dma_init_struct.number = sizeof(buf_UART1_DMA);
|
||
env->dma_init_struct.periph_addr = USART1_RDATA_ADDRESS;
|
||
env->dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
|
||
env->dma_init_struct.periph_memory_width = DMA_PERIPH_WIDTH_8BIT;
|
||
env->dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
|
||
// env->dma_init_struct.circular_mode = DMA_CIRCULAR_MODE_ENABLE;
|
||
dma_single_data_mode_init(DMA0, DMA_CH5, &env->dma_init_struct);
|
||
|
||
/* configure DMA mode */
|
||
dma_circulation_enable(DMA0, DMA_CH5);
|
||
dma_channel_subperipheral_select(DMA0, DMA_CH5, DMA_SUBPERI4);
|
||
/* enable DMA1 channel7 transfer complete interrupt */
|
||
dma_interrupt_enable(DMA0, DMA_CH5, DMA_CHXCTL_FTFIE);
|
||
/* enable DMA1 channel2 */
|
||
dma_channel_enable(DMA0, DMA_CH5);
|
||
|
||
|
||
|
||
/* enable GPIO clock */
|
||
rcu_periph_clock_enable(RCU_GPIOD);
|
||
|
||
/* enable USART clock */
|
||
rcu_periph_clock_enable(RCU_USART1);
|
||
|
||
/* connect port to USARTx_Tx */
|
||
gpio_af_set(GPIOD, GPIO_AF_7, GPIO_PIN_5);
|
||
|
||
/* connect port to USARTx_Rx */
|
||
gpio_af_set(GPIOD, GPIO_AF_7, GPIO_PIN_6);
|
||
|
||
/* configure USART Tx as alternate function push-pull */
|
||
gpio_mode_set(GPIOD, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_5);
|
||
gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_5);
|
||
|
||
/* configure USART Rx as alternate function push-pull */
|
||
gpio_mode_set(GPIOD, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_6);
|
||
gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6);
|
||
|
||
/* configure USART */
|
||
usart_deinit(USART1);
|
||
usart_baudrate_set(USART1, 921600);
|
||
// usart_halfduplex_enable(USART1);
|
||
|
||
usart_receive_config(USART1, USART_RECEIVE_ENABLE);
|
||
usart_transmit_config(USART1, USART_TRANSMIT_ENABLE);
|
||
usart_dma_receive_config(USART1, USART_RECEIVE_DMA_ENABLE);
|
||
usart_enable(USART1);
|
||
|
||
/* clear the USART1 data register */
|
||
usart_data_receive(USART1);
|
||
|
||
usart_interrupt_enable(USART1, USART_INT_IDLE);
|
||
|
||
NVIC_EnableIRQ(USART1_IRQn);
|
||
NVIC_SetPriority(USART1_IRQn, 0xFF);
|
||
|
||
NVIC_EnableIRQ(DMA0_Channel5_IRQn);
|
||
NVIC_SetPriority(DMA0_Channel5_IRQn, 0xFF);
|
||
|
||
vSerialPortInit(env, USART1, 3200);
|
||
|
||
}
|
||
|
||
void SerialPorts_Init() {
|
||
tSerialPorts *env = &SERIAL_PORTS;
|
||
|
||
vSerialPort_InitUSART0(&env->GONEC0);
|
||
SERIAL_PORTS.GONEC0IO = vSerialPortGetIo(&SERIAL_PORTS.GONEC0);
|
||
|
||
vSerialPort_InitUSART1(&env->GONEC1);
|
||
SERIAL_PORTS.GONEC1IO = vSerialPortGetIo(&SERIAL_PORTS.GONEC1);
|
||
|
||
}
|