#include "api_uart.h" #include "api_rt_uart.h" #include "api_rt_dbg.h" #include "board_config.h" #include "gd32f30x.h" ApiRtUart_Handle Uarts[1]; uint8_t rxBuffer[UART_BUFFER_LENGTH]; uint8_t txBuffer[UART_BUFFER_LENGTH]; void iRtUart_Init() { Uarts[0].UartBase = UART3; Uarts[0].DmaBase = DMA1; Uarts[0].DmaChannelBase = DMA_CH4; // Uarts[0].TxDmaChannelBase = DMA1_Channel2; Uarts[0].Status = ApiUart_Idle; Uarts[0].RxBuffer = rxBuffer; Uarts[0].TxBuffer = txBuffer; Uarts[0].RxBufferHead = 0; Uarts[0].RxBufferTail = 0; Uarts[0].TxBufferCount = 0; Uarts[0].AsyncWriteCompleteCallback = 0; Uarts[0].AsyncReadCompleteCallback = 0; Uarts[0].AsyncWriteErrorCallback = 0; Uarts[0].AsyncReadErrorCallback = 0; Uarts[0].AsyncReadCount = 0; Uarts[0].AsyncReadAddr = 0; /*======================================================================= DMA1 Ch2 for UART3 receive =======================================================================*/ dma_deinit(DMA1, DMA_CH2); dma_parameter_struct dma_init_struct; dma_init_struct.periph_addr = (uint32_t)(&USART_DATA(UART3)); dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE; dma_init_struct.memory_addr = (uint32_t)(rxBuffer); dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE; dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT; dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT; dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY; dma_init_struct.number = 22; dma_init_struct.priority = DMA_PRIORITY_HIGH; dma_init(DMA1, DMA_CH2, &dma_init_struct); dma_circulation_disable(DMA1, DMA_CH2); /* enable DMA1 channel2 */ dma_channel_enable(DMA1, DMA_CH2); } void iUart_Open(uint8_t devIndex, uint32_t baudrate) { USART_BAUD(Uarts[devIndex].UartBase)=(HW_MCU_CLOCK_HZ / baudrate); USART_CTL0(Uarts[devIndex].UartBase) |= 0x00000001; // Uarts[devIndex].UartBase->BRR = (HW_MCU_CLOCK_HZ / baudrate); // Uarts[devIndex].UartBase->CR1 |= 0x00000001; } void iUart_Close(uint8_t devIndex) { USART_CTL0(Uarts[devIndex].UartBase) &= ~(0x00000001UL); // Uarts[devIndex].UartBase->CR1 &= ~(0x00000001UL); } ApiUart_Status iUart_GetStatus(uint8_t devIndex) { return ApiUart_Idle; } int16_t iUart_Available(uint8_t devIndex) { return (Uarts[devIndex].RxBufferTail + UART_BUFFER_LENGTH - Uarts[devIndex].RxBufferHead) % UART_BUFFER_LENGTH; } int16_t iUart_GetWriteBufferSpace(uint8_t devIndex) { return UART_BUFFER_LENGTH; } int16_t iUart_Read(uint8_t devIndex, uint8_t *data, int16_t count) { int16_t readCount = 0; // data[readCount] = Uarts[devIndex].RxBuffer[Uarts[devIndex].RxBufferHead]; if ((Uarts[devIndex].Status & ApiUart_ReadBusy) == 0) { while (Uarts[devIndex].RxBufferHead != Uarts[devIndex].RxBufferTail && readCount < count) { data[readCount] = Uarts[devIndex].RxBuffer[Uarts[devIndex].RxBufferHead]; Uarts[devIndex].RxBufferHead += 1; Uarts[devIndex].RxBufferHead %= UART_BUFFER_LENGTH; readCount++; } } return readCount; } int16_t iUart_Write(uint8_t devIndex, uint8_t *data, int16_t count) { int16_t writeCount = 0; if ((Uarts[devIndex].Status & ApiUart_WriteBusy) == 0) { while (writeCount < count) { USART_DATA(Uarts[devIndex].UartBase) = data[writeCount]; while ((USART_STAT0(Uarts[devIndex].UartBase) & 0x80) == 0) { ; } // Uarts[devIndex].UartBase->TDR = data[writeCount]; // while ((Uarts[devIndex].UartBase->ISR & 0x80) == 0) // { // ; // } } } return writeCount; } void iUart_ReadAsync(uint8_t devIndex, uint8_t *data, uint8_t count, void (*cplt)(uint8_t *data, int16_t count), void (*error)()) { if ((Uarts[devIndex].Status & ApiUart_ReadBusy) == 0) { Uarts[devIndex].Status |= ApiUart_ReadBusy; Uarts[devIndex].AsyncReadCount = count; Uarts[devIndex].AsyncReadAddr = data; Uarts[devIndex].AsyncReadCompleteCallback = cplt; Uarts[devIndex].AsyncReadErrorCallback = error; } } void iUart_WriteAsync(uint8_t devIndex, uint8_t *data, uint8_t count, void (*cplt)(), void (*error)()) { if ((Uarts[devIndex].Status & ApiUart_WriteBusy) == 0) { Uarts[devIndex].Status |= ApiUart_WriteBusy; Uarts[devIndex].AsyncWriteCompleteCallback = cplt; Uarts[devIndex].AsyncWriteErrorCallback = error; DMA_CHMADDR(Uarts[devIndex].DmaBase,Uarts[devIndex].DmaChannelBase)= (uint32_t)data; DMA_CHCNT(Uarts[devIndex].DmaBase,Uarts[devIndex].DmaChannelBase)= count; USART_STAT0(Uarts[devIndex].UartBase) &= ~ USART_STAT0_TC; DMA_CHCTL(Uarts[devIndex].DmaBase,Uarts[devIndex].DmaChannelBase)|= 0x00000001; // Uarts[devIndex].TxDmaChannelBase->CMAR = (uint32_t)data; // Uarts[devIndex].TxDmaChannelBase->CNDTR = count; // Uarts[devIndex].UartBase->ICR = UART_CLEAR_TCF; // Uarts[devIndex].TxDmaChannelBase->CCR |= 0x00000001; } } void iRtUart_RxIsr(uint8_t devIndex) { static uint16_t uwTempCount = 0; if (dma_flag_get(DMA1, DMA_CH2, DMA_INT_FLAG_FTF) != 0) { Uarts[0].RxBufferTail = 22; Uarts[0].RxBufferHead = 0; DMA_CH2CTL(DMA1) &= ~DMA_CHXCTL_CHEN; //dma_flag_clear(DMA1, DMA_CH2, DMA_INT_FLAG_FTF); DMA_INTC(DMA1) |= DMA_FLAG_ADD(DMA_INT_FLAG_FTF, DMA_CH2); uwTempCount = 22 - DMA_CH2CNT(DMA1); DMA_CH2CNT(DMA1) = uwTempCount; DMA_CH2CTL(DMA1) |= DMA_CHXCTL_CHEN; } /* RX error */ if (dma_flag_get(DMA1, DMA_CH2, DMA_FLAG_ERR) != 0) { DMA_CH2CTL(DMA1) &= ~DMA_CHXCTL_CHEN; //dma_flag_clear(DMA1, DMA_CH2, DMA_FLAG_ERR); DMA_INTC(DMA1) |= DMA_FLAG_ADD(DMA_FLAG_ERR, DMA_CH2); DMA_CH2CNT(DMA1) = 22; DMA_CH2CTL(DMA1) |= DMA_CHXCTL_CHEN; } if (Uarts[0].AsyncReadCount > 0 && iUart_Available(0) >= Uarts[0].AsyncReadCount) { iUart_Read(0, Uarts[0].AsyncReadAddr, Uarts[0].AsyncReadCount); if (Uarts[0].AsyncReadCompleteCallback != 0) { Uarts[0].AsyncReadCompleteCallback(Uarts[0].AsyncReadAddr, Uarts[0].AsyncReadCount); } Uarts[0].AsyncReadCount = 0; Uarts[0].Status &= ~ApiUart_ReadBusy; } } void iRtUart_AsyncWriteCompleteIsr(uint8_t devIndex) { DMA_CHCTL(Uarts[devIndex].DmaBase,Uarts[devIndex].DmaChannelBase)&= ~0x00000001; USART_STAT0(Uarts[devIndex].UartBase) &= ~ USART_STAT0_TC; // Uarts[0].TxDmaChannelBase->CCR &= (uint16_t)(~DMA_CCR_EN); // Uarts[0].UartBase->ICR = UART_CLEAR_TCF; Uarts[devIndex].Status &= ~ApiUart_WriteBusy; if (Uarts[devIndex].AsyncWriteCompleteCallback != 0) { Uarts[devIndex].AsyncWriteCompleteCallback(); } } void iRtUart_AsyncWriteErrorIsr(uint8_t devIndex) { DMA_CHCTL(Uarts[devIndex].DmaBase,Uarts[devIndex].DmaChannelBase)&= ~0x00000001; USART_STAT0(Uarts[devIndex].UartBase) &= ~ USART_STAT0_TC; // Uarts[0].TxDmaChannelBase->CCR &= (uint16_t)(~DMA_CCR_EN); // Uarts[0].UartBase->ICR = UART_CLEAR_TCF; Uarts[devIndex].Status &= ~ApiUart_WriteBusy; if (Uarts[devIndex].AsyncWriteErrorCallback != 0) { Uarts[devIndex].AsyncWriteErrorCallback(); } }