embox

Форк
0
131 строка · 4.0 Кб
1
/**
2
 * @file
3
 * @brief Raspberry Pi 16550-like Mini UART driver
4
 * Mini UART is the default console device on Raspberry Pi models with
5
 * Bluetooth and WiFi. But some registers are different. For example,
6
 * we need enable manually the mini UART by writting into base_address
7
 * + 0x04 Auxiliary Enable Register.
8
 * There are Extra Control Register and Extra Status Register as well,
9
 * in purpose to provide a more intelligent way to manage RX/TX. But
10
 * up to now, the driver adopts a full 16550-like solution.
11
 * There is a Baudrate Register as a shortcut to get and set Baudrate.
12
 *
13
 * @author  Weixuan XIAO
14
 * @date    09.11.2020
15
 */
16

17
#include <hal/reg.h>
18
#include <drivers/common/memory.h>
19
#include <drivers/diag.h>
20
#include <embox/unit.h>
21
#include <framework/mod/options.h>
22
#include <hal/mmu.h>
23
#include <mem/vmem.h>
24
#include <util/binalign.h>
25
#include <drivers/serial/uart_dev.h>
26
#include <drivers/serial/diag_serial.h>
27
#include <kernel/printk.h>
28

29
#define REG_WIDTH    OPTION_GET(NUMBER,reg_width)
30
#define COM0_IRQ_NUM OPTION_GET(NUMBER, irq_num)
31

32
#define AUX_ENABLE ((volatile unsigned int*)(OPTION_GET(NUMBER, base_addr) + 0x04))
33
#define AUX_MU_IO_OFFSET 0x40
34
#define COM_BASE (OPTION_GET(NUMBER, base_addr) + AUX_MU_IO_OFFSET)
35

36
#define MINI_UART_IER_RX_IRQ 0x01
37

38
#define UART_REG(x)													\
39
        unsigned char x;											\
40
        unsigned char postpad_##x[REG_WIDTH - 1];
41

42
struct com {
43
        UART_REG(io);          	/* Mini Uart I/O Data */
44
        UART_REG(ier);          /* Mini Uart Interrupt Enable */
45
        UART_REG(iir);          /* Mini Uart Interrupt Identify */
46
        UART_REG(lcr);          /* Mini Uart Line Control */
47
        UART_REG(mcr);          /* Mini Uart Modem Control */
48
        UART_REG(lsr);          /* Mini Uart Line Status */
49
        UART_REG(msr);          /* Mini Uart Modem Status */
50
        UART_REG(scr);          /* Mini Uart Scratch */
51
        UART_REG(cntl);         /* Mini Uart Extra Control */
52
        UART_REG(stat);         /* Mini Uart Extra Status */
53
        UART_REG(baud);         /* Mini Uart Baudrate */
54
};
55

56
#define COM3 ((volatile struct com *)COM_BASE)
57
#define COM3_LSR (COM3->lsr)
58
#define COM3_IER (COM3->ier)
59
#define COM3_IO (COM3->io)
60
#define COM3_CNTL (COM3->cntl)
61

62
EMBOX_UNIT_INIT(rpi_mini_uart_init);
63

64
static int rpi_mini_uart_setup(struct uart *dev, const struct uart_params *params) {
65
	*AUX_ENABLE |= 0x01;	/* enable mini uart */
66
	if (params->uart_param_flags & UART_PARAM_FLAGS_USE_IRQ) {
67
		COM3_IER |= MINI_UART_IER_RX_IRQ;
68
	}
69
	COM3_CNTL = 0x03;		/* enable tx and rx */
70
	return 0;
71
}
72

73
static int rpi_mini_uart_irq_en(struct uart *dev, const struct uart_params *params) {
74
	COM3_IER |= MINI_UART_IER_RX_IRQ;
75
	return 0;
76
}
77

78
static int rpi_mini_uart_irq_dis(struct uart *dev, const struct uart_params *params) {
79
	COM3_IER &= ~MINI_UART_IER_RX_IRQ;
80
	return 0;
81
}
82

83
static int rpi_mini_uart_putc(struct uart *dev, int ch) {
84
	while ((COM3_LSR & 0x20) == 0);	/* wait until we can send */
85

86
	COM3_IO = ch;
87

88
	return 0;
89
}
90

91
static int rpi_mini_uart_getc(struct uart *dev) {
92
	return COM3_IO;
93
}
94

95
static int rpi_mini_uart_has_symbol(struct uart *dev) {
96
	return COM3_LSR & 0x01;
97
}
98

99

100
static const struct uart_ops rpi_mini_uart_ops = {
101
		.uart_getc = rpi_mini_uart_getc,
102
		.uart_putc = rpi_mini_uart_putc,
103
		.uart_hasrx = rpi_mini_uart_has_symbol,
104
		.uart_setup = rpi_mini_uart_setup,
105
		.uart_irq_en = rpi_mini_uart_irq_en,
106
		.uart_irq_dis = rpi_mini_uart_irq_dis,
107
};
108

109
static struct uart uart0 = {
110
		.uart_ops = &rpi_mini_uart_ops,
111
		.irq_num = COM0_IRQ_NUM,
112
		.base_addr = COM_BASE,
113
};
114

115
static const struct uart_params uart_defparams = {
116
		.baud_rate = OPTION_GET(NUMBER,baud_rate),
117
		.uart_param_flags = UART_PARAM_FLAGS_8BIT_WORD | UART_PARAM_FLAGS_USE_IRQ,
118
};
119

120
static const struct uart_params uart_diag_params = {
121
		.baud_rate = OPTION_GET(NUMBER,baud_rate),
122
		.uart_param_flags = UART_PARAM_FLAGS_8BIT_WORD,
123
};
124

125
DIAG_SERIAL_DEF(&uart0, &uart_diag_params);
126

127
static int rpi_mini_uart_init(void) {
128
	return uart_register(&uart0, &uart_defparams);
129
}
130

131
PERIPH_MEMORY_DEFINE(rpi_mini_uart, COM_BASE, 0x1000);
132

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

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

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

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