embox

Форк
0
129 строк · 3.4 Кб
1
/**
2
 * @file
3
 * @brief PrimeCell UART (PL011)
4
 * http://infocenter.arm.com/help/topic/com.arm.doc.ddi0183g/DDI0183G_uart_pl011_r1p5_trm.pdf
5
 *
6
 * @date 04 aug 2015
7
 * @author: Anton Bondarev
8
 */
9
#include <stdint.h>
10

11
#include <drivers/serial/uart_dev.h>
12
#include <framework/mod/options.h>
13
#include <hal/reg.h>
14

15
#define UARTCLK         OPTION_GET(NUMBER, uartclk)
16
#define USE_BOARD_CONF  OPTION_GET(BOOLEAN, use_bconf)
17

18
/* UART Registers */
19
#define UART_DR(base)   (base + 0x00)
20
#define UART_RSR(base)  (base + 0x04)
21
#define UART_ECR(base)  (base + 0x04)
22
#define UART_FR(base)   (base + 0x18)
23
#define UART_IBRD(base) (base + 0x24)
24
#define UART_FBRD(base) (base + 0x28)
25
#define UART_LCRH(base) (base + 0x2c)
26
#define UART_CR(base)   (base + 0x30)
27
#define UART_IMSC(base) (base + 0x38)
28
#define UART_MIS(base)  (base + 0x40)
29
#define UART_ICR(base)  (base + 0x44)
30

31
#define UART_FEN        (1 << 4)
32
#define UART_UARTEN     (1 << 0)
33
#define UART_TXE        (1 << 8)
34
#define UART_RXE        (1 << 9)
35
#define UART_WLEN_8BIT  0x3
36
#define UART_WLEN_SHIFT 5
37

38
/* Flag register */
39
#define FR_RXFE         0x10 /* Receive FIFO empty */
40
#define FR_TXFF         0x20 /* Transmit FIFO full */
41

42
#define IMSC_RXIM       (0x1 << 4)
43

44
#if USE_BOARD_CONF
45
#include "uart_setup_hw_board_config.inc"
46
#else
47
static inline int uart_setup_hw(struct uart *dev) {
48
	return 0;
49
}
50
#endif /* USE_BOARD_CONF */
51

52
static void pl011_set_baudrate(struct uart *dev) {
53
	/* FIXME Init baud rate only if UARTCLK is really used.
54
	 * Currenly it is not so for the teplates which use pl011. */
55
#if UARTCLK != 0
56
	uint32_t baud_rate;
57
	int ibrd, fbrd;
58

59
	/* Baud Rate Divisor = UARTCLK/(16×Baud Rate) = BRDI + BRDF,
60
	 * See 2.4.3 UART operation.  */
61
	baud_rate = dev->params.baud_rate;
62
	ibrd = (UARTCLK / (16 * baud_rate));
63
	fbrd = ((UARTCLK % (16 * baud_rate)) * 64) / (16 * baud_rate);
64
	REG32_STORE(UART_IBRD(dev->base_addr), ibrd);
65
	REG32_STORE(UART_FBRD(dev->base_addr), fbrd);
66
#endif
67
}
68

69
static int pl011_irq_enable(struct uart *dev,
70
    const struct uart_params *params) {
71
	if (params->uart_param_flags & UART_PARAM_FLAGS_USE_IRQ) {
72
		REG32_STORE(UART_IMSC(dev->base_addr), IMSC_RXIM);
73
	}
74
	return 0;
75
}
76

77
static int pl011_irq_disable(struct uart *dev,
78
    const struct uart_params *params) {
79
	REG32_STORE(UART_IMSC(dev->base_addr), 0);
80

81
	return 0;
82
}
83

84
static int pl011_setup(struct uart *dev, const struct uart_params *params) {
85
	/* Disable uart. */
86
	REG32_STORE(UART_CR(dev->base_addr), 0);
87

88
	uart_setup_hw(dev);
89

90
	if (params->uart_param_flags & UART_PARAM_FLAGS_USE_IRQ) {
91
		REG32_STORE(UART_IMSC(dev->base_addr), IMSC_RXIM);
92
	}
93

94
	pl011_set_baudrate(dev);
95

96
	/* Word len 8 bit. */
97
	REG32_STORE(UART_LCRH(dev->base_addr), UART_WLEN_8BIT << UART_WLEN_SHIFT);
98

99
	/* Enable uart. */
100
	REG32_STORE(UART_CR(dev->base_addr), UART_UARTEN | UART_TXE | UART_RXE);
101

102
	return 0;
103
}
104

105
static int pl011_putc(struct uart *dev, int ch) {
106
	while (REG32_LOAD(UART_FR(dev->base_addr)) & FR_TXFF)
107
		;
108

109
	REG32_STORE(UART_DR(dev->base_addr), (uint32_t)ch);
110

111
	return 0;
112
}
113

114
static int pl011_getc(struct uart *dev) {
115
	return REG32_LOAD(UART_DR(dev->base_addr));
116
}
117

118
static int pl011_has_symbol(struct uart *dev) {
119
	return !(REG32_LOAD(UART_FR(dev->base_addr)) & FR_RXFE);
120
}
121

122
const struct uart_ops pl011_uart_ops = {
123
    .uart_getc = pl011_getc,
124
    .uart_putc = pl011_putc,
125
    .uart_hasrx = pl011_has_symbol,
126
    .uart_setup = pl011_setup,
127
    .uart_irq_en = pl011_irq_enable,
128
    .uart_irq_dis = pl011_irq_disable,
129
};
130

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

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

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

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