#include "uart.h"
#include "registers.h"
#include "stm32f401xe.h"
void usart_init(uart_t *uart, USART_TypeDef *peripheral, uint8_t idx) {
uart->periph = peripheral;
uart->idx = idx;
}
void usart_configure_speed(uart_t *uart, uint32_t clock_freq,
uint32_t baud) {
// 12 000 000 / 9600 / 16 = 78.125
uint32_t temp = clock_freq / baud;
uint32_t mantissa = temp / 16;
uint32_t fraction = temp % 16;
if (fraction == 15 && ((temp + 8) % 16) == 0) {
mantissa++;
fraction = 0;
}
uart->periph->BRR = (mantissa << USART_BRR_DIV_Mantissa_Pos) | (fraction << USART_BRR_DIV_Fraction_Pos);
}
void usart_configure_uart(uart_t *uart,
bool enable,
usart_word_length_t length,
bool parity_control, usart_parity_t parity,
usart_stop_bits_t stop_bits) {
reg_write_bits(&uart->periph->CR1, (enable << USART_CR1_UE_Pos) |
(parity << USART_CR1_PS_Pos) |
(parity_control << USART_CR1_PCE_Pos) | (length << USART_CR1_M_Pos),
USART_CR1_UE_Msk | USART_CR1_PS_Msk | USART_CR1_PCE_Msk | USART_CR1_M_Msk);
reg_write_bits(&uart->periph->CR2, (stop_bits << USART_CR2_STOP_Pos), USART_CR2_STOP_Msk);
}
void usart_configure_receiver(uart_t *uart, bool enable) {
reg_write_bits(&uart->periph->CR1, enable << USART_CR1_RE_Pos, USART_CR1_RE_Msk);
}
uint16_t usart_receive(uart_t* uart, char *buffer, uint16_t max_size, char separator) {
char received = '\0';
uint16_t size = 0;
while (received != separator && size < max_size - 1) {
// NOTE: this can be stuck here forever, if, for example,
// the uart got disabled. There should be some kind of a timeout I suppose.
if (!(uart->periph->SR & USART_SR_RXNE)) {
continue;
}
*(buffer++) = received = (char)(uart->periph->DR & USART_DR_DR_Msk);
size++;
}
*(buffer - 1) = '\0';
return size - 1;
}