227 lines
6.3 KiB
C++
227 lines
6.3 KiB
C++
#include "stm32g4xx.h"
|
|
|
|
#include <string.h>
|
|
|
|
#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;
|
|
} 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, sizeof(UART3_BufferSend), UART3_BufferSend, 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, sizeof(UART2_BufferSend), UART2_BufferSend, 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, sizeof(UART1_BufferSend), UART1_BufferSend, 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.Recv.Size] = Uart.UART->RDR;
|
|
if (Uart.Recv.Head < Uart.Recv.Tail + Uart.Recv.Size) Uart.Recv.Head++;
|
|
}
|
|
if (isr & USART_ISR_TXE)
|
|
{
|
|
if (Uart.Send.Tail != Uart.Send.Head)
|
|
{
|
|
Uart.UART->TDR = Uart.Send.Buffer[Uart.Send.Tail % Uart.Send.Size];
|
|
Uart.Send.Tail++;
|
|
}
|
|
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.Head-Uart.Recv.Tail;
|
|
|
|
unsigned char* data=(unsigned char*)Data;
|
|
unsigned long size = 0;
|
|
|
|
while (size < Size)
|
|
{
|
|
if (Uart.Recv.Tail == Uart.Recv.Head) break;
|
|
data[size++] = Uart.Recv.Buffer[Uart.Recv.Tail % Uart.Recv.Size];
|
|
Uart.Recv.Tail++;
|
|
}
|
|
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.Head - Uart.Send.Tail >= Uart.Send.Size) break;
|
|
Uart.Send.Buffer[Uart.Send.Head % Uart.Send.Size] = data[size++];
|
|
Uart.Send.Head++;
|
|
}
|
|
|
|
Uart.UART->CR1 |= USART_CR1_TXEIE;
|
|
|
|
return size;
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
|
|
static inline void Flush(UART_Data& Uart)
|
|
{
|
|
Uart.Recv.Tail=Uart.Recv.Head;
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
|
|
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);
|
|
}
|
|
//------------------------------------------------------------------------------
|