2021-05-28 11:06:00 +02:00

75 lines
2.2 KiB
C++

#include "platform/stm32g0xx/Gpio.h"
#include "platform/stm32g0xx/Uart.h"
using namespace perinet::platform::stm32g0xx;
Uart::Uart(UartDevice device, uint32_t baud_rate)
{
uint32_t tx_pin = 2;
uint32_t rx_pin = 15;
Gpio::Port port = Gpio::Port::PORT_A;
Gpio::AlternateFunction alt_func = Gpio::AlternateFunction::ALTERNATE_FUNCTION_0;
switch(device) {
case UartDevice::UART_1:
uart = USART1;
RCC->APBENR2 |= RCC_APBENR2_USART1EN;
tx_pin = 6;
rx_pin = 7;
port = Gpio::Port::PORT_B;
break;
case UartDevice::UART_2:
uart = USART2;
RCC->APBENR1 |= RCC_APBENR1_USART2EN;
alt_func = Gpio::AlternateFunction::ALTERNATE_FUNCTION_1;
break;
}
Gpio tx_gpio(port, tx_pin, Gpio::Mode::MODE_AF_PP, Gpio::Pullup::PULLUP, alt_func);
Gpio rx_gpio(port, rx_pin, Gpio::Mode::MODE_AF_PP, Gpio::Pullup::PULLUP, alt_func);
// Disable UART
uart->CR1 &= ~USART_CR1_UE;
// USART CR1 Configuration
uint32_t tmp = uart->CR1;
tmp &= ~((USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8| USART_CR1_FIFOEN));
tmp |= (USART_CR1_TE | USART_CR1_RE); // RX and TX mode
uart->CR1 = tmp;
// USART CR2 Configuration
tmp = uart->CR2;
tmp &= ~(USART_CR2_STOP);
uart->CR2 = tmp;
// USART CR3 Configuration
// USART PRESC Configuration
// USART BRR Configuration
tmp = ((64000000 + (baud_rate / 2)) / baud_rate);
uart->BRR = tmp;
// In asynchronous mode, the following bits must be kept cleared:
// - LINEN and CLKEN bits in the USART_CR2 register,
// - SCEN, HDSEL and IREN bits in the USART_CR3 register.
uart->CR2 &= ~(USART_CR2_LINEN | USART_CR2_CLKEN);
uart->CR3 &= ~(USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN);
// Enable UART
uart->CR1 |= USART_CR1_UE;
}
void Uart::sync_send(const uint8_t *buffer, uint32_t len)
{
if (buffer == nullptr) {
return;
}
for (uint32_t i = 0; i < len; i++) {
// wait for tx not full
while ((uart->ISR & USART_ISR_TXE_TXFNF) == 0);
uart->TDR = buffer[i];
}
}