embox
253 строки · 6.1 Кб
1/**
2* @file
3* @brief
4*
5* @author Vadim Deryabkin
6* @date 07.02.2021
7*/
8
9#include <stdint.h>10#include <string.h>11
12#include <hal/reg.h>13
14#include <drivers/serial/diag_serial.h>15#include <drivers/serial/uart_dev.h>16#include <drivers/gpio/gpio.h>17
18#include "stm32_usart_conf_f0.h"19
20extern const uint32_t HSE_VALUE;21#define HSI_VALUE 800000022
23/*
24* RM0360, 23.4.4 "USART baud rate generation", 609.
25* Oversampling = 8.
26*/
27#define USART_BRR(USART_CLK,USART_BAUDRATE) (2 * USART_CLK / USART_BAUDRATE)28
29
30// Clock part.
31typedef struct {32volatile uint32_t CR;33volatile uint32_t CFGR;34volatile uint32_t CIR;35volatile uint32_t APB2RSTR;36volatile uint32_t APB1RSTR;37volatile uint32_t AHBENR;38volatile uint32_t APB2ENR;39volatile uint32_t APB1ENR;40volatile uint32_t BDCR;41volatile uint32_t CSR;42volatile uint32_t AHBRSTR;43volatile uint32_t CFGR2;44volatile uint32_t CFGR3;45volatile uint32_t CR2;46} rcc_struct;47
48#define RCC ((rcc_struct *) 0x40021000)49
50static uint32_t get_pll_clk () {51uint32_t src_clk;52
53if (RCC->CFGR & (1 << 16)) {54src_clk = HSE_VALUE / (RCC->CFGR2 + 1);55} else {56src_clk = HSI_VALUE / 2;57}58
59src_clk *= ((RCC->CFGR >> 18) & 0b1111) + 2;60return src_clk;61}
62
63static uint32_t HPRE_VALUE[8] = {2, 4, 8, 16, 64, 128, 256, 512};64static uint32_t PPRE_VALUE[8] = {2, 4, 8, 16};65
66static uint32_t get_usart_clk (usart_struct *USART) {67volatile uint32_t SW_SRC;68
69switch ((RCC->CFGR & (0b11 << 2)) >> 2) {70case 0b00:71SW_SRC = HSI_VALUE;72break;73
74case 0b01:75SW_SRC = HSE_VALUE;76break;77
78default:79SW_SRC = get_pll_clk();80break;81}82
83if (RCC->CFGR & (1 << 7)) {84SW_SRC /= HPRE_VALUE[((RCC->CFGR >> 4) & 0b111)];85}86
87if (RCC->CFGR & (1 << 10)) {88SW_SRC /= PPRE_VALUE[((RCC->CFGR >> 8) & 0b111)];89}90
91return SW_SRC;92}
93
94#define REG_RCC 0x40021000 // Doc: DS9773 Rev 4, 39/93.95#define REG_RCC_APB2ENR (REG_RCC + 0x18) // Doc: DocID025023 Rev 4, 125/779.96#define REG_RCC_APB1ENR (REG_RCC + 0x1C) // Doc: DocID025023 Rev 4, 125/779.97#define REG_RCC_AHBENR (REG_RCC + 0x14) // Doc: DocID025023 Rev 4, 125/779.98
99static void set_usart_pwr (usart_struct *USART) {100switch ((uint32_t)USART) {101case (uint32_t)USART1:102REG32_ORIN(REG_RCC_APB2ENR, (1 << 14)); // Doc: DocID025023 Rev 4, 113/779.103break;104
105case (uint32_t)USART2:106REG32_ORIN(REG_RCC_APB1ENR, (1 << 17)); // Doc: DocID025023 Rev 4, 115/779.107break;108
109case (uint32_t)USART3:110REG32_ORIN(REG_RCC_APB1ENR, (1 << 18)); // Doc: DocID025023 Rev 4, 115/779.111break;112
113case (uint32_t)USART4:114REG32_ORIN(REG_RCC_APB1ENR, (1 << 19)); // Doc: DocID025023 Rev 4, 115/779.115break;116
117case (uint32_t)USART5:118REG32_ORIN(REG_RCC_APB1ENR, (1 << 20)); // Doc: DocID025023 Rev 4, 115/779.119break;120
121case (uint32_t)USART6:122REG32_ORIN(REG_RCC_APB2ENR, (1 << 5)); // Doc: DocID025023 Rev 4, 114/779.123break;124
125default:126break;127}128}
129
130// GPIO part.
131static void set_gpio_pwr (uint32_t port) {132REG32_ORIN(REG_RCC_AHBENR, (1 << (port + 17))); // Doc: DocID025023 Rev 4, 111/779.133}
134
135static gpio_struct *get_gpio (unsigned char port) {136uint8_t *p = (uint8_t *)GPIOA;137p += 1024 * port;138return (gpio_struct *)p;139}
140
141static void set_gpio_af (uint32_t port, uint32_t pin, uint32_t func) {142gpio_struct* GPIO = get_gpio(port);143
144if (pin < PINS_NUMBER / 2) {145GPIO->AFRL &= ~L_AF_MSK(pin);146GPIO->AFRL |= L_AF(pin, func);147} else {148GPIO->AFRH &= ~H_AF_MSK(pin);149GPIO->AFRH |= H_AF(pin, func);150}151
152GPIO->MODER &= ~M_MSK(pin);153GPIO->MODER |= M_ALT(pin);154}
155
156static void set_gpio_high_spped (uint32_t port, uint32_t pin) {157gpio_struct* GPIO = get_gpio(port);158
159GPIO->OSPEEDR &= ~S_MSK(pin);160GPIO->OSPEEDR |= S_HS(pin);161}
162
163static void init_usart_gpio () {164set_gpio_pwr(OPTION_GET(NUMBER,port_tx));165set_gpio_pwr(OPTION_GET(NUMBER,port_rx));166
167set_gpio_af(OPTION_GET(NUMBER,port_tx), OPTION_GET(NUMBER,pin_tx), OPTION_GET(NUMBER,pin_tx_af));168set_gpio_af(OPTION_GET(NUMBER,port_rx), OPTION_GET(NUMBER,pin_rx), OPTION_GET(NUMBER,pin_rx_af));169
170set_gpio_high_spped(OPTION_GET(NUMBER,port_tx), OPTION_GET(NUMBER,pin_tx));171set_gpio_high_spped(OPTION_GET(NUMBER,port_rx), OPTION_GET(NUMBER,pin_rx));172}
173
174// USART part.
175static int stm32_uart_setup(struct uart *dev, const struct uart_params *params) {176init_usart_gpio();177
178usart_struct *USART = (usart_struct *)dev->base_addr;179volatile uint32_t usart_clk = get_usart_clk(USART);180
181set_usart_pwr(USART);182
183USART->BRR = (USART_BRR(usart_clk, dev->params.baud_rate) & 0xFFFFFFF0) |184((USART_BRR(usart_clk, dev->params.baud_rate) & 0xF) >> 1);185
186USART->CR1 = (1 << 15)|(1 << 3)|(1 << 2)|(1 << 0);187
188if (dev->params.uart_param_flags & UART_PARAM_FLAGS_USE_IRQ) {189USART->CR1 |= (1 << 5);190}191
192return 0;193}
194
195static int stm32_uart_putc(struct uart *dev, int ch) {196usart_struct *USART = (usart_struct *)dev->base_addr;197
198while ((USART->ISR & (1 << 7)) == 0);199USART->TDR = (char)ch;200
201return 0;202}
203
204static int stm32_uart_hasrx(struct uart *dev) {205usart_struct *USART = (usart_struct *)dev->base_addr;206return USART->ISR & (1 << 5);207}
208
209static int stm32_uart_getc(struct uart *dev) {210usart_struct *USART = (usart_struct *)dev->base_addr;211return USART->RDR & 0xFF;212}
213
214static int stm32_uart_irq_en(struct uart *dev, const struct uart_params *params) {215if (params->uart_param_flags & UART_PARAM_FLAGS_USE_IRQ) {216usart_struct *USART = (usart_struct *)dev->base_addr;217
218USART->CR1 |= (1 << 5);219}220return 0;221}
222
223static int stm32_uart_irq_dis(struct uart *dev, const struct uart_params *params) {224if (params->uart_param_flags & UART_PARAM_FLAGS_USE_IRQ) {225usart_struct *USART = (usart_struct *)dev->base_addr;226
227USART->CR1 &= ~(1 << 5);228}229return 0;230}
231
232// System part.
233const struct uart_ops stm32_uart_ops = {234.uart_getc = stm32_uart_getc,235.uart_putc = stm32_uart_putc,236.uart_hasrx = stm32_uart_hasrx,237.uart_setup = stm32_uart_setup,238.uart_irq_en = stm32_uart_irq_en,239.uart_irq_dis = stm32_uart_irq_dis,240};241
242static struct uart stm32_diag = {243.uart_ops = &stm32_uart_ops,244.irq_num = USARTx_IRQn,245.base_addr = (unsigned long)USARTx,246};247
248static const struct uart_params diag_defparams = {249.baud_rate = OPTION_GET(NUMBER,baud_rate),250.uart_param_flags = UART_PARAM_FLAGS_8BIT_WORD,251};252
253DIAG_SERIAL_DEF(&stm32_diag, &diag_defparams);254