~ruther/uni-mam-arm

ref: 009a105e762919ce95daabb7343085c9b93f0efe uni-mam-arm/arm07/src/uart.c -rw-r--r-- 2.0 KiB
009a105e — Rutherther feat: implement large part of arm07 3 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#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);
}

void usart_configure_transmitter(uart_t* uart, bool enable) {
  reg_write_bits(&uart->periph->CR1, (enable == true) << USART_CR1_TE_Pos, USART_CR1_TE_Msk);
}

uint16_t usart_transmit(uart_t *uart, char *data, uint16_t size) {
  for (int16_t i = 0; i < size; i++) {
    char byte = *(data++);

    while (!(uart->periph->SR & USART_SR_TXE));
    uart->periph->DR = byte;
  }

  return size;
}

uint16_t usart_receive(uart_t* uart, char *buffer, uint16_t max_size) {
  uint16_t size = 0;

  while (size < max_size - 1 && (uart->periph->SR & USART_SR_RXNE)) {
    *(buffer + (size++)) = (char)(uart->periph->DR & USART_DR_DR_Msk);
  }

  return size;
}
Do not follow this link