#include "stm32g4xx.h" #include #include "gpio.h" #include "uart.h" static const unsigned long UART_BuferSize=256; struct UART_Data { USART_TypeDef* UART; struct { unsigned long Size; unsigned char* Buffer; unsigned short Head; unsigned short Tail; unsigned short Push; unsigned short Pull; } Recv, Send; }; static unsigned char UART3_BufferRecv[UART_BuferSize], UART3_BufferSend[UART_BuferSize]; static UART_Data UART3_Data{ USART3, {sizeof(UART3_BufferRecv), UART3_BufferRecv, 0, 0, 0, 0}, {sizeof(UART3_BufferSend), UART3_BufferSend, 0, 0, 0, 0} }; static unsigned char UART2_BufferRecv[UART_BuferSize], UART2_BufferSend[UART_BuferSize]; static UART_Data UART2_Data{ USART2, {sizeof(UART2_BufferRecv), UART2_BufferRecv, 0, 0, 0, 0}, {sizeof(UART2_BufferSend), UART2_BufferSend, 0, 0, 0, 0} }; static unsigned char UART1_BufferRecv[UART_BuferSize], UART1_BufferSend[UART_BuferSize]; static UART_Data UART1_Data{ USART1, {sizeof(UART1_BufferRecv), UART1_BufferRecv, 0, 0, 0, 0}, {sizeof(UART1_BufferSend), UART1_BufferSend, 0, 0, 0, 0} }; static void IRQHandler(UART_Data& Uart) { unsigned long isr = Uart.UART->ISR; if(isr & USART_ISR_RXNE) { Uart.Recv.Buffer[Uart.Recv.Head] = Uart.UART->RDR; if(Uart.Recv.Push-Uart.Recv.Pull=Uart.Recv.Size) Uart.Recv.Head=0; } if(isr & USART_ISR_TXE) { if(Uart.Send.Push != Uart.Send.Pull) { Uart.UART->TDR = Uart.Send.Buffer[Uart.Send.Tail++]; if(Uart.Send.Tail>=Uart.Send.Size) Uart.Send.Tail=0; Uart.Send.Pull++; } else Uart.UART->CR1 &= ~USART_CR1_TXEIE; } } //------------------------------------------------------------------------------ extern "C" void USART3_IRQHandler() { IRQHandler(UART3_Data); } //------------------------------------------------------------------------------ extern "C" void USART2_IRQHandler() { IRQHandler(UART2_Data); } //------------------------------------------------------------------------------ extern "C" void USART1_IRQHandler() { IRQHandler(UART1_Data); } //------------------------------------------------------------------------------ static void Init(USART_TypeDef* USART, unsigned long Baud) { USART->CR1 = 0; USART->CR1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_RXNEIE; //USART->BRR = SystemCoreClock / 4 / Baud; USART->BRR = SystemCoreClock / Baud; USART->CR3 |= USART_CR3_OVRDIS; USART->CR1 |= USART_CR1_UE; } //------------------------------------------------------------------------------ void UART3_Init(unsigned long Baud) { if (RCC->APB1ENR1 & RCC_APB1ENR1_USART3EN) return; RCC->APB1ENR1 |= RCC_APB1ENR1_USART3EN; GPIO_InitPin(GPIO_PIN_10 | GPIO_PORT_B | GPIO_ALTER | GPIO_AF7 | GPIO_OSPEED_HIGH); GPIO_InitPin(GPIO_PIN_11 | GPIO_PORT_B | GPIO_ALTER | GPIO_AF7 | GPIO_OSPEED_HIGH); Init(USART3, Baud); NVIC_SetPriority(USART3_IRQn, 0); NVIC_EnableIRQ(USART3_IRQn); } //------------------------------------------------------------------------------ void UART2_Init(unsigned long Baud) { if (RCC->APB1ENR1 & RCC_APB1ENR1_USART2EN) return; RCC->APB1ENR1 |= RCC_APB1ENR1_USART2EN; GPIO_InitPin(GPIO_PIN_3 | GPIO_PORT_B | GPIO_ALTER | GPIO_AF7 | GPIO_OSPEED_HIGH); GPIO_InitPin(GPIO_PIN_4 | GPIO_PORT_B | GPIO_ALTER | GPIO_AF7 | GPIO_OSPEED_HIGH); Init(USART2, Baud); NVIC_SetPriority(USART2_IRQn, 0); NVIC_EnableIRQ(USART2_IRQn); } //------------------------------------------------------------------------------ void UART1_Init(unsigned long Baud) { if (RCC->APB2ENR & RCC_APB2ENR_USART1EN) return; RCC->APB2ENR |= RCC_APB2ENR_USART1EN; GPIO_InitPin(GPIO_PIN_6 | GPIO_PORT_B | GPIO_ALTER | GPIO_AF7 | GPIO_OSPEED_HIGH); GPIO_InitPin(GPIO_PIN_7 | GPIO_PORT_B | GPIO_ALTER | GPIO_AF7 | GPIO_OSPEED_HIGH); Init(USART1, Baud); NVIC_SetPriority(USART1_IRQn, 0); NVIC_EnableIRQ(USART1_IRQn); } //------------------------------------------------------------------------------ static unsigned long Recv(UART_Data& Uart, void* Data, unsigned long Size) { if(!Data) return Uart.Recv.Push-Uart.Recv.Pull; unsigned char* data=(unsigned char*)Data; unsigned long size = 0; while (size < Size) { if (Uart.Recv.Push == Uart.Recv.Pull) break; data[size++] = Uart.Recv.Buffer[Uart.Recv.Tail++]; if(Uart.Recv.Tail>=Uart.Recv.Size) Uart.Recv.Tail=0; Uart.Recv.Pull++; } return size; } //------------------------------------------------------------------------------ static unsigned long Send(UART_Data& Uart, const void* Data, unsigned long Size) { unsigned char* data=(unsigned char*)Data; unsigned long size = 0; while (size < Size) { if (Uart.Send.Push - Uart.Send.Pull >= Uart.Send.Size) break; Uart.Send.Buffer[Uart.Send.Head++] = data[size++]; if(Uart.Send.Head>=Uart.Send.Size) Uart.Send.Head=0; Uart.Send.Push++; } Uart.UART->CR1 |= USART_CR1_TXEIE; return size; } //------------------------------------------------------------------------------ static inline void Flush(UART_Data& Uart) { Uart.Recv.Tail=Uart.Recv.Head; Uart.Recv.Pull=Uart.Recv.Push; } //------------------------------------------------------------------------------ unsigned long UART3_Recv(void* Data, unsigned long Size) { return Recv(UART3_Data, Data, Size); } //------------------------------------------------------------------------------ void UART3_Flush() { Flush(UART3_Data); } //------------------------------------------------------------------------------ unsigned long UART3_Send(const void* Data, unsigned long Size) { return Send(UART3_Data, Data, Size); } //------------------------------------------------------------------------------ unsigned long UART2_Recv(void* Data, unsigned long Size) { return Recv(UART2_Data, Data, Size); } //------------------------------------------------------------------------------ void UART2_Flush() { Flush(UART2_Data); } //------------------------------------------------------------------------------ unsigned long UART2_Send(const void* Data, unsigned long Size) { return Send(UART2_Data, Data, Size); } //------------------------------------------------------------------------------ unsigned long UART1_Recv(void* Data, unsigned long Size) { return Recv(UART1_Data, Data, Size); } //------------------------------------------------------------------------------ void UART1_Flush() { Flush(UART1_Data); } //------------------------------------------------------------------------------ unsigned long UART1_Send(const void* Data, unsigned long Size) { return Send(UART1_Data, Data, Size); } //------------------------------------------------------------------------------