Add basic C++ Uart driver

This commit is contained in:
Thomas Klaehn 2021-01-08 10:20:09 +01:00
parent 4dd55be05c
commit f94f7f0d68
2 changed files with 109 additions and 0 deletions

View File

@ -0,0 +1,80 @@
#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 = 3;
Gpio::Port port = Gpio::Port::PORT_A;
switch(device) {
case UartDevice::UART_2:
this->uart = USART2;
RCC->APBENR1 |= RCC_APBENR1_USART2EN;
break;
case UartDevice::UART_3:
this->uart = USART3;
RCC->APBENR1 |= RCC_APBENR1_USART3EN;
// FIXME: Set pin confing accordingly
break;
case UartDevice::UART_4:
this->uart = USART4;
RCC->APBENR1 |= RCC_APBENR1_USART4EN;
// FIXME: Set pin confing accordingly
break;
}
Gpio tx_gpio(port, tx_pin, Gpio::Mode::MODE_AF_PP, Gpio::Pullup::PULLUP,
Gpio::AlternateFunction::ALTERNATE_FUNCTION_1);
Gpio rx_gpio(port, rx_pin, Gpio::Mode::MODE_AF_PP, Gpio::Pullup::PULLUP,
Gpio::AlternateFunction::ALTERNATE_FUNCTION_1);
// Disable UART
this->uart->CR1 &= ~USART_CR1_UE;
// USART CR1 Configuration
uint32_t tmp = this->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
this->uart->CR1 = tmp;
// USART CR2 Configuration
tmp = this->uart->CR2;
tmp &= ~(USART_CR2_STOP);
this->uart->CR2 = tmp;
// USART CR3 Configuration
// USART PRESC Configuration
// USART BRR Configuration
tmp = ((64000000 + (baud_rate / 2)) / baud_rate);
this->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.
this->uart->CR2 &= ~(USART_CR2_LINEN | USART_CR2_CLKEN);
this->uart->CR3 &= ~(USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN);
// Enable UART
this->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 ((this->uart->ISR & USART_ISR_TXE_TXFNF) == 0);
this->uart->TDR = buffer[i];
}
}

29
platform/stm32g0xx/Uart.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef __PLATFORM_STM32G0XX_UART_H__
#define __PLATFORM_STM32G0XX_UART_H__
#include <cstdint>
#include "stm32g0xx.h"
namespace perinet::platform::stm32g0xx {
class Uart
{
public:
enum class UartDevice
{
UART_2,
UART_3,
UART_4
};
Uart(UartDevice, uint32_t);
void sync_send(const uint8_t *, uint32_t);
private:
USART_TypeDef * uart;
};
}
#endif