Add usart.{h, c}

This commit is contained in:
Alexander Heldt
2025-01-01 12:30:57 +01:00
parent 3a69e75d9a
commit aecd073963
4 changed files with 123 additions and 0 deletions

66
src/usart.c Normal file
View File

@@ -0,0 +1,66 @@
#include "rcc.h"
#include "gpio.h"
#include "usart.h"
void usart2_init(void) {
// Enable clock for GPIOA as USART2 is on PORT A pins
RCC->AHB1ENR |= (1 << PORT('A'));
// Configure PA2 and PA3 (USART2 pins) to use alternative functions
uint16_t txPin = PIN('A', 2);
gpio_set_mode(txPin, GPIO_MODE_AF);
gpio_set_af(txPin, GPIO_AF_USART2_TX);
uint16_t rxPin = PIN('A', 3);
gpio_set_mode(rxPin, GPIO_MODE_AF);
gpio_set_af(rxPin, GPIO_AF_USART2_RX);
// Enable USART
RCC->APB1ENR |= RCC_APB1ENR_USART2EN_ENABLE;
// Clear control registers
USART2->CR1 = 0;
USART2->CR2 = 0;
USART2->CR3 = 0;
// Calculate Baud rate:
// baud = f_clck / (8 * (2 - OVER8) * USARTDIV) =>
// (8 * (2 - OVER8) * USARTDIV) = f_clock / baud =>
// baud * (8 * (2 - OVER8) * USARTDIV) = f_clock =>
// USARTDIV = (f_clock / (baud * (8 * (2 - OVER8)))
// Target Baud rate = 115200, f_clock = 48MHz, OVER8 = 0
// USARTDIV = 48E6 / (115200 * 8 * 2) = 26.0416666
// mantissa = 26 = 0x1A
// fraction = 0.041666 * 16 = 0.666656 ~= 1
// baud = 48E6 / (8 * 2 * 26) = 115384.61538461539
// error of 0.16% (115384.61538461539 / 115200 ) = 1.001602564102564
//
// skipping fractional part as error rate is good.
USART2->BRR &= ~(USART_BRR_MANTISSA_MASK << USART_BRR_MANTISSA_BIT);
USART2->BRR |= (0x1A << USART_BRR_MANTISSA_BIT);
USART2->BRR &= ~(USART_BRR_FRACTION_MASK << USART_BRR_FRACTION_BIT);
USART2->BRR |= (0x0 << USART_BRR_MANTISSA_BIT);
// Enable transmitter and receiver
USART2->CR1 |= USART_CR1_TE_ENABLE;
USART2->CR1 |= USART_CR1_RE_ENABLE;
}
void usart2_start(void) {
USART2->CR1 |= USART_CR1_UE_ENABLE;
}
void usart2_write_byte(uint8_t c) {
USART2->DR = c;
// Wait indefinitely for transmission to be ready for data
while (!(USART2->SR & USART_SR_TC_COMPLETED));
}
void usart2_write(char *buf) {
while (*buf) usart2_write_byte(*buf++);
}