// // 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); }