embox

Форк
0
/
stm_usart_l0x0.c 
248 строк · 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
#include <kernel/irq.h>
14

15
#include <drivers/serial/diag_serial.h>
16
#include <drivers/serial/uart_dev.h>
17

18
#include "stm32_usart_conf_l0x0.h"
19

20
// Doc: DocID031151 Rev 1, RM0451, 620/774.
21
#define USART_BRR(USART_CLK,USART_BAUDRATE)             (2 * USART_CLK / USART_BAUDRATE)
22

23
// Clock part.
24
static const uint32_t HSI_VALUE = 16000000;
25
extern const uint32_t HSE_VALUE;
26

27
typedef struct {
28
    volatile uint32_t CR;        // 0x00
29
    volatile uint32_t ICSCR;     // 0x04
30
    volatile uint32_t RES_1;     // 0x08
31
    volatile uint32_t CFGR;      // 0x0C
32
    volatile uint32_t CIER;      // 0x10
33
    volatile uint32_t CIFR;      // 0x14
34
    volatile uint32_t CICR;      // 0x18
35
    volatile uint32_t IOPRSTR;   // 0x1C
36
    volatile uint32_t AHBRSTR;   // 0x20
37
    volatile uint32_t APB2RSTR;  // 0x24
38
    volatile uint32_t APB1RSTR;  // 0x28
39
    volatile uint32_t IOPENR;    // 0x2C
40
    volatile uint32_t AHBENR;    // 0x30
41
    volatile uint32_t APB2ENR;   // 0x34
42
    volatile uint32_t APB1ENR;   // 0x38
43
    volatile uint32_t IOPSMEN;   // 0x3C
44
    volatile uint32_t AHBSMENR;  // 0x40
45
    volatile uint32_t APB2SMENR; // 0x44
46
    volatile uint32_t APB1SMENR; // 0x48
47
    volatile uint32_t CCIPR;     // 0x4C
48
    volatile uint32_t CSR;       // 0x50
49
} rcc_struct; // Doc: DocID031151 Rev 1, RM0451, 185/774.
50

51
// Doc: DocID031151 Rev 1, RM0451, 39/774.
52
#define RCC       ((rcc_struct *)          0X40021000)
53

54
static uint32_t get_hsi_clk () {
55
	if (RCC->CR & (1 << 4)) {
56
		return HSI_VALUE / 4;
57
	} else {
58
		return HSI_VALUE;
59
	}
60
}
61

62
static uint32_t PLLMUL_VALUE[9] = {3, 4, 6, 8, 12, 16, 24, 32, 48};
63

64
static uint32_t get_pll_clk () {
65
	uint32_t src_clk;
66

67
	if (RCC->CFGR & (1 << 16)) {
68
		src_clk = HSE_VALUE;
69
	} else {
70
		src_clk = get_hsi_clk();
71
	}
72

73
	src_clk *= PLLMUL_VALUE[(RCC->CFGR >> 18) & 0b1111];
74
	src_clk /= ((RCC->CFGR >> 22) & 0b11) + 1;
75
	return src_clk;
76
}
77

78
static uint32_t HPRE_VALUE[8] = {2, 4, 8, 16, 64, 128, 256, 512};
79
static uint32_t PPRE_VALUE[8] = {2, 4, 8, 16};
80

81
static uint32_t MSI_CLI_TABLE[8] = {
82
		65536, 131072, 262144, 524288, 1048000, 2097000, 4194000, 0
83
};
84

85
static uint32_t get_msi_clk () {
86
	return MSI_CLI_TABLE[(RCC->ICSCR & (0b111 << 13)) >> 13];
87
}
88

89
static uint32_t get_usart_clk () {
90
	volatile uint32_t SW_SRC;
91

92
	switch ((RCC->CFGR & (0b11 << 2)) >> 2) {
93
	case 0b00:
94
		SW_SRC = get_msi_clk();
95
		break;
96

97
	case 0b01:
98
		SW_SRC = get_hsi_clk();
99
		break;
100

101
	case 0b10:
102
		SW_SRC = HSE_VALUE;
103
		break;
104

105
	case 0b11:
106
		SW_SRC = get_pll_clk();
107
		break;
108
	}
109

110
	if (RCC->CFGR & (1 << 7)) {
111
		SW_SRC /= HPRE_VALUE[((RCC->CFGR >> 4) & 0b111)];
112
	}
113

114
	if (RCC->CFGR & (1 << 10)) {
115
		SW_SRC /= PPRE_VALUE[((RCC->CFGR >> 8) & 0b111)];
116
	}
117

118
	return SW_SRC;
119
}
120

121
static void set_usart_pwr () {
122
	RCC->APB1ENR |= 1 << 17; // On USART2.
123
}
124

125
// GPIO part.
126
static void set_gpio_pwr (uint32_t port) {
127
	RCC->IOPENR |= (1 << port); // Doc: DocID031151 Rev 1, RM0451, 169/774.
128
}
129

130
static gpio_struct *get_gpio (unsigned char port) {
131
	uint8_t *p = (uint8_t *)GPIOA;
132
	p += 1024 * port;
133
	return (gpio_struct *)p;
134
}
135

136
static void set_gpio_af (uint32_t port, uint32_t pin, uint32_t func) {
137
	gpio_struct* GPIO = get_gpio(port);
138

139
	if (pin < PINS_NUMBER / 2) {
140
		GPIO->AFRL &= ~L_AF_MSK(pin);
141
		GPIO->AFRL |= L_AF(pin, func);
142
	} else {
143
		GPIO->AFRH &= ~H_AF_MSK(pin);
144
		GPIO->AFRH |= H_AF(pin, func);
145
	}
146

147
	GPIO->MODER &= ~M_MSK(pin);
148
	GPIO->MODER |=  M_ALT(pin);
149
}
150

151
static void set_gpio_high_spped (uint32_t port, uint32_t pin) {
152
	gpio_struct* GPIO = get_gpio(port);
153

154
	GPIO->OSPEEDR &= ~S_MSK(pin);
155
	GPIO->OSPEEDR |= S_HS(pin);
156
}
157

158
static void init_usart_gpio () {
159
	set_gpio_pwr(OPTION_GET(NUMBER,port_tx));
160
	set_gpio_pwr(OPTION_GET(NUMBER,port_rx));
161

162
	set_gpio_af(OPTION_GET(NUMBER,port_tx), OPTION_GET(NUMBER,pin_tx), OPTION_GET(NUMBER,pin_tx_af));
163
	set_gpio_af(OPTION_GET(NUMBER,port_rx), OPTION_GET(NUMBER,pin_rx), OPTION_GET(NUMBER,pin_rx_af));
164

165
	set_gpio_high_spped(OPTION_GET(NUMBER,port_tx), OPTION_GET(NUMBER,pin_tx));
166
	set_gpio_high_spped(OPTION_GET(NUMBER,port_rx), OPTION_GET(NUMBER,pin_rx));
167
}
168

169
// USART part.
170
static int stm32_uart_setup(struct uart *dev, const struct uart_params *params) {
171
	init_usart_gpio();
172

173
	usart_struct *USART = (usart_struct *)dev->base_addr;
174
	volatile uint32_t usart_clk = get_usart_clk();
175

176
	set_usart_pwr();
177

178
	USART->BRR = (USART_BRR(usart_clk, dev->params.baud_rate) & 0xFFFFFFF0) |
179
			     ((USART_BRR(usart_clk, dev->params.baud_rate) & 0xF) >> 1);
180

181
	USART->CR1 = (1 << 15)|(1 << 3)|(1 << 2)|(1 << 0);
182

183
	if (dev->params.uart_param_flags & UART_PARAM_FLAGS_USE_IRQ) {
184
		USART->CR1 |= (1 << 5);
185
	}
186

187
	return 0;
188
}
189

190
static int stm32_uart_putc(struct uart *dev, int ch) {
191
	usart_struct *USART = (usart_struct *)dev->base_addr;
192

193
	while ((USART->ISR & (1 << 7)) == 0);
194
	USART->TDR = (char)ch;
195

196
	return 0;
197
}
198

199
static int stm32_uart_hasrx(struct uart *dev) {
200
	usart_struct *USART = (usart_struct *)dev->base_addr;
201
	return USART->ISR & (1 << 5);
202
}
203

204
static int stm32_uart_getc(struct uart *dev) {
205
	usart_struct *USART = (usart_struct *)dev->base_addr;
206
	return USART->RDR & 0xFF;
207
}
208

209
static int stm32_uart_irq_en(struct uart *dev, const struct uart_params *params) {
210
	if (params->uart_param_flags & UART_PARAM_FLAGS_USE_IRQ) {
211
		usart_struct *USART = (usart_struct *)dev->base_addr;
212

213
		USART->CR1 |= (1 << 5);
214
	}
215
	return 0;
216
}
217

218
static int stm32_uart_irq_dis(struct uart *dev, const struct uart_params *params) {
219
	if (params->uart_param_flags & UART_PARAM_FLAGS_USE_IRQ) {
220
		usart_struct *USART = (usart_struct *)dev->base_addr;
221

222
		USART->CR1 &= ~(1 << 5);
223
	}
224
	return 0;
225
}
226

227
// System part.
228
const struct uart_ops stm32_uart_ops = {
229
		.uart_getc = stm32_uart_getc,
230
		.uart_putc = stm32_uart_putc,
231
		.uart_hasrx = stm32_uart_hasrx,
232
		.uart_setup = stm32_uart_setup,
233
		.uart_irq_en = stm32_uart_irq_en,
234
		.uart_irq_dis = stm32_uart_irq_dis,
235
};
236

237
static struct uart stm32_diag = {
238
		.uart_ops = &stm32_uart_ops,
239
		.irq_num = USARTx_IRQn,
240
		.base_addr = (unsigned long)USARTx,
241
};
242

243
static const struct uart_params diag_defparams = {
244
		.baud_rate = OPTION_GET(NUMBER,baud_rate),
245
		.uart_param_flags = UART_PARAM_FLAGS_8BIT_WORD,
246
};
247

248
DIAG_SERIAL_DEF(&stm32_diag, &diag_defparams);
249

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

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

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

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