embox

Форк
0
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

20
extern const uint32_t HSE_VALUE;
21
#define HSI_VALUE 8000000
22

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.
31
typedef struct {
32
    volatile uint32_t CR;
33
    volatile uint32_t CFGR;
34
    volatile uint32_t CIR;
35
    volatile uint32_t APB2RSTR;
36
    volatile uint32_t APB1RSTR;
37
    volatile uint32_t AHBENR;
38
    volatile uint32_t APB2ENR;
39
    volatile uint32_t APB1ENR;
40
    volatile uint32_t BDCR;
41
    volatile uint32_t CSR;
42
    volatile uint32_t AHBRSTR;
43
    volatile uint32_t CFGR2;
44
    volatile uint32_t CFGR3;
45
    volatile uint32_t CR2;
46
} rcc_struct;
47

48
#define RCC       ((rcc_struct *)          0x40021000)
49

50
static uint32_t get_pll_clk () {
51
	uint32_t src_clk;
52

53
	if (RCC->CFGR & (1 << 16)) {
54
		src_clk = HSE_VALUE / (RCC->CFGR2 + 1);
55
	} else {
56
		src_clk = HSI_VALUE / 2;
57
	}
58

59
	src_clk *= ((RCC->CFGR >> 18) & 0b1111) + 2;
60
	return src_clk;
61
}
62

63
static uint32_t HPRE_VALUE[8] = {2, 4, 8, 16, 64, 128, 256, 512};
64
static uint32_t PPRE_VALUE[8] = {2, 4, 8, 16};
65

66
static uint32_t get_usart_clk (usart_struct *USART) {
67
	volatile uint32_t SW_SRC;
68

69
	switch ((RCC->CFGR & (0b11 << 2)) >> 2) {
70
	case 0b00:
71
		SW_SRC = HSI_VALUE;
72
		break;
73

74
	case 0b01:
75
		SW_SRC = HSE_VALUE;
76
		break;
77

78
	default:
79
		SW_SRC = get_pll_clk();
80
		break;
81
	}
82

83
	if (RCC->CFGR & (1 << 7)) {
84
		SW_SRC /= HPRE_VALUE[((RCC->CFGR >> 4) & 0b111)];
85
	}
86

87
	if (RCC->CFGR & (1 << 10)) {
88
		SW_SRC /= PPRE_VALUE[((RCC->CFGR >> 8) & 0b111)];
89
	}
90

91
	return 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

99
static void set_usart_pwr (usart_struct *USART) {
100
	switch ((uint32_t)USART) {
101
	case (uint32_t)USART1:
102
			REG32_ORIN(REG_RCC_APB2ENR, (1 << 14)); // Doc: DocID025023 Rev 4, 113/779.
103
			break;
104

105
	case (uint32_t)USART2:
106
			REG32_ORIN(REG_RCC_APB1ENR, (1 << 17)); // Doc: DocID025023 Rev 4, 115/779.
107
			break;
108

109
	case (uint32_t)USART3:
110
			REG32_ORIN(REG_RCC_APB1ENR, (1 << 18)); // Doc: DocID025023 Rev 4, 115/779.
111
			break;
112

113
	case (uint32_t)USART4:
114
			REG32_ORIN(REG_RCC_APB1ENR, (1 << 19)); // Doc: DocID025023 Rev 4, 115/779.
115
			break;
116

117
	case (uint32_t)USART5:
118
			REG32_ORIN(REG_RCC_APB1ENR, (1 << 20)); // Doc: DocID025023 Rev 4, 115/779.
119
			break;
120

121
	case (uint32_t)USART6:
122
			REG32_ORIN(REG_RCC_APB2ENR, (1 << 5)); // Doc: DocID025023 Rev 4, 114/779.
123
			break;
124

125
	default:
126
		break;
127
	}
128
}
129

130
// GPIO part.
131
static void set_gpio_pwr (uint32_t port) {
132
	REG32_ORIN(REG_RCC_AHBENR, (1 << (port + 17))); // Doc: DocID025023 Rev 4, 111/779.
133
}
134

135
static gpio_struct *get_gpio (unsigned char port) {
136
	uint8_t *p = (uint8_t *)GPIOA;
137
	p += 1024 * port;
138
	return (gpio_struct *)p;
139
}
140

141
static void set_gpio_af (uint32_t port, uint32_t pin, uint32_t func) {
142
	gpio_struct* GPIO = get_gpio(port);
143

144
	if (pin < PINS_NUMBER / 2) {
145
		GPIO->AFRL &= ~L_AF_MSK(pin);
146
		GPIO->AFRL |= L_AF(pin, func);
147
	} else {
148
		GPIO->AFRH &= ~H_AF_MSK(pin);
149
		GPIO->AFRH |= H_AF(pin, func);
150
	}
151

152
	GPIO->MODER &= ~M_MSK(pin);
153
	GPIO->MODER |=  M_ALT(pin);
154
}
155

156
static void set_gpio_high_spped (uint32_t port, uint32_t pin) {
157
	gpio_struct* GPIO = get_gpio(port);
158

159
	GPIO->OSPEEDR &= ~S_MSK(pin);
160
	GPIO->OSPEEDR |= S_HS(pin);
161
}
162

163
static void init_usart_gpio () {
164
	set_gpio_pwr(OPTION_GET(NUMBER,port_tx));
165
	set_gpio_pwr(OPTION_GET(NUMBER,port_rx));
166

167
	set_gpio_af(OPTION_GET(NUMBER,port_tx), OPTION_GET(NUMBER,pin_tx), OPTION_GET(NUMBER,pin_tx_af));
168
	set_gpio_af(OPTION_GET(NUMBER,port_rx), OPTION_GET(NUMBER,pin_rx), OPTION_GET(NUMBER,pin_rx_af));
169

170
	set_gpio_high_spped(OPTION_GET(NUMBER,port_tx), OPTION_GET(NUMBER,pin_tx));
171
	set_gpio_high_spped(OPTION_GET(NUMBER,port_rx), OPTION_GET(NUMBER,pin_rx));
172
}
173

174
// USART part.
175
static int stm32_uart_setup(struct uart *dev, const struct uart_params *params) {
176
	init_usart_gpio();
177

178
	usart_struct *USART = (usart_struct *)dev->base_addr;
179
	volatile uint32_t usart_clk = get_usart_clk(USART);
180

181
	set_usart_pwr(USART);
182

183
	USART->BRR = (USART_BRR(usart_clk, dev->params.baud_rate) & 0xFFFFFFF0) |
184
			     ((USART_BRR(usart_clk, dev->params.baud_rate) & 0xF) >> 1);
185

186
	USART->CR1 = (1 << 15)|(1 << 3)|(1 << 2)|(1 << 0);
187

188
	if (dev->params.uart_param_flags & UART_PARAM_FLAGS_USE_IRQ) {
189
		USART->CR1 |= (1 << 5);
190
	}
191

192
	return 0;
193
}
194

195
static int stm32_uart_putc(struct uart *dev, int ch) {
196
	usart_struct *USART = (usart_struct *)dev->base_addr;
197

198
	while ((USART->ISR & (1 << 7)) == 0);
199
	USART->TDR = (char)ch;
200

201
	return 0;
202
}
203

204
static int stm32_uart_hasrx(struct uart *dev) {
205
	usart_struct *USART = (usart_struct *)dev->base_addr;
206
	return USART->ISR & (1 << 5);
207
}
208

209
static int stm32_uart_getc(struct uart *dev) {
210
	usart_struct *USART = (usart_struct *)dev->base_addr;
211
	return USART->RDR & 0xFF;
212
}
213

214
static int stm32_uart_irq_en(struct uart *dev, const struct uart_params *params) {
215
	if (params->uart_param_flags & UART_PARAM_FLAGS_USE_IRQ) {
216
		usart_struct *USART = (usart_struct *)dev->base_addr;
217

218
		USART->CR1 |= (1 << 5);
219
	}
220
	return 0;
221
}
222

223
static int stm32_uart_irq_dis(struct uart *dev, const struct uart_params *params) {
224
	if (params->uart_param_flags & UART_PARAM_FLAGS_USE_IRQ) {
225
		usart_struct *USART = (usart_struct *)dev->base_addr;
226

227
		USART->CR1 &= ~(1 << 5);
228
	}
229
	return 0;
230
}
231

232
// System part.
233
const 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

242
static struct uart stm32_diag = {
243
		.uart_ops = &stm32_uart_ops,
244
		.irq_num = USARTx_IRQn,
245
		.base_addr = (unsigned long)USARTx,
246
};
247

248
static 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

253
DIAG_SERIAL_DEF(&stm32_diag, &diag_defparams);
254

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.