embox

Форк
0
198 строк · 5.9 Кб
1
/**
2
 * @file
3
 *
4
 * @date 13.03.10
5
 * @author Eldar Abusalimov
6
 */
7

8
#include <stdint.h>
9
#include <errno.h>
10

11
#include <drivers/common/memory.h>
12

13
#include <drivers/amba_pnp.h>
14
#include <hal/reg.h>
15
#include <hal/system.h>
16
#include <kernel/irq.h>
17

18
#include <drivers/diag.h>
19
#include <drivers/serial/uart_dev.h>
20
#include <drivers/serial/diag_serial.h>
21

22
#include <embox/unit.h>
23

24
#include <kernel/printk.h>
25

26
#define BAUD_RATE \
27
	OPTION_GET(NUMBER, baud_rate)
28

29
#define UART_SCALER_VAL \
30
	(((SYS_CLOCK * 10) / (BAUD_RATE * 8) - 5) / 10)
31

32
/* status register bit masks */
33
#define UART_STAT_DR (1u << 0) /**< Data is available for read in RX register*/
34
#define UART_STAT_TS (1u << 1) /**< TX shift register is empty */
35
#define UART_STAT_TE (1u << 2) /**< TX FIFO is empty */
36
#define UART_STAT_BR (1u << 3) /**< BREAK received */
37
#define UART_STAT_OV (1u << 4) /**< 1 or more bytes lossed over overflow */
38
#define UART_STAT_PE (1u << 5) /**< error in parity control */
39
#define UART_STAT_FE (1u << 6) /**< error in frame */
40
#define UART_STAT_TH (1u << 7) /**< TX FIFO is half-full */
41
#define UART_STAT_RH (1u << 8) /**< RX FIFO is half-full */
42
#define UART_STAT_TF (1u << 9) /**< TX FIFO is full */
43
#define UART_STAT_RF (1u << 10)/**< RX FIFO is full */
44

45
/* control register bit masks */
46
#define UART_CTRL_RE (1u << 0)  /**< receiver enable */
47
#define UART_CTRL_TE (1u << 1)  /**< transmitter enable */
48
#define UART_CTRL_RI (1u << 2)  /**< interrupt after receiving frame */
49
#define UART_CTRL_TI (1u << 3)  /**< interrupt after transmitting frame */
50
#define UART_CTRL_PS (1u << 4)  /**< parity check (0 - oddness, 1 - evenness) */
51
#define UART_CTRL_PE (1u << 5)  /**< parity control enable */
52
#define UART_CTRL_FL (1u << 6)  /**< flow control with CTS/RTS enable (don't use) */
53
#define UART_CTRL_LB (1u << 7)  /**< loopback enable */
54
#define UART_CTRL_EC (1u << 8)  /**< external clock enable */
55
#define UART_CTRL_TF (1u << 9)  /**< enable interrupt on FIFO transmitter layer */
56
#define UART_CTRL_RF (1u << 10) /**< enable interrupt on FIFO receiver layer */
57
#define UART_CTRL_DB (1u << 11) /**< debug mode enable (don't available) */
58
#define UART_CTRL_OE (1u << 12) /**< output transmitter enable */
59
#define UART_CTRL_FA (1u << 31) /**< set on when FIFO TX and RX are available */
60
#define UART_DISABLE_ALL 0
61

62
struct apbuart_regs {
63
	/*------+------+
64
	 | resv | data |
65
	 | 31-8 | 7-0  |
66
	 +------+------*/
67
	/* 0x0 */uint32_t data;
68
	/*-------+-------+-------+--+--+--+--+--+--+--+--+--+--+--+
69
	 | RCNT  | TCNT  | resrv |RF|TF|RH|TH|FE|PE|OV|BR|TE|TS|DR|
70
	 | 31-26 | 25-20 | 19-11 |10|9 |8 |7 |6 |5 |4 |3 |2 |1 |0 |
71
	 +-------+-------+-------+--+--+--+--+--+--+--+--+--+--+--*/
72
	/* 0x4 */uint32_t status;
73
	/*--+-------+--+--+--+--+--+--+--+--+--+--+--+--+--+
74
	 |FA| resrv |OE|DB|RF|TF|EC|LB|FL|PE|PS|TI|RI|TE|RE|
75
	 |31| 30-13 |12|11|10|9 |8 |7 |6 |5 |4 |3 |2 |1 |0 |
76
	 +--+-------+--+--+--+--+--+--+--+--+--+--+--+--+--*/
77
	/* 0x8 */uint32_t ctrl;
78
	/*-------+--------+
79
	 | resrv | scaler |
80
	 | 31-12 | 11-0   |
81
	 +-------+--------*/
82
	/* 0xC */uint32_t scaler;
83
};
84

85
static volatile struct apbuart_regs *dev_regs;
86

87
static int dev_regs_init(void);
88

89
EMBOX_UNIT_INIT(uart_init);
90

91
static int apbuart_setup(struct uart *dev, const struct uart_params *params) {
92
	int res;
93

94
	if (NULL == dev_regs && 0 != (res = dev_regs_init())) {
95
		return res;
96
	}
97

98
	assert(NULL != dev_regs);
99

100
	REG_STORE(&dev_regs->ctrl, UART_DISABLE_ALL);
101
	REG_STORE(&dev_regs->scaler, UART_SCALER_VAL);
102
	if (params->uart_param_flags & UART_PARAM_FLAGS_USE_IRQ) {
103
		REG_STORE(&dev_regs->ctrl, UART_CTRL_TE | UART_CTRL_RE | UART_CTRL_RI);
104
	} else {
105
		REG_STORE(&dev_regs->ctrl, UART_CTRL_TE | UART_CTRL_RE);
106
	}
107

108
	return 0;
109
}
110

111
static int apbuart_irq_en(struct uart *dev, const struct uart_params *params) {
112

113
	if (params->uart_param_flags & UART_PARAM_FLAGS_USE_IRQ) {
114
		REG_STORE(&dev_regs->ctrl, UART_CTRL_TE | UART_CTRL_RE | UART_CTRL_RI);
115
	}
116

117
	return 0;
118
}
119

120
static int apbuart_irq_dis(struct uart *dev, const struct uart_params *params) {
121
	if (params->uart_param_flags & UART_PARAM_FLAGS_USE_IRQ) {
122
		REG_STORE(&dev_regs->ctrl, UART_CTRL_TE | UART_CTRL_RE);
123
	}
124

125
	return 0;
126
}
127

128
static int apbuart_putc(struct uart *dev, int ch) {
129
	while (!(UART_STAT_TE & REG_LOAD(&dev_regs->status))) {
130
	}
131
	REG_STORE(&dev_regs->data, (uint32_t) ch);
132

133
	return 0;
134
}
135

136
static int apbuart_has_symbol(struct uart *dev) {
137
	return (UART_STAT_DR & REG_LOAD(&dev_regs->status));
138
}
139

140
static int apbuart_getc(struct uart *dev) {
141
	return REG_LOAD(&dev_regs->data);
142
}
143

144

145
#ifdef DRIVER_AMBAPP
146
static int dev_regs_init() {
147
	amba_dev_t amba_dev;
148
	if (-1 == capture_amba_dev(&amba_dev, AMBAPP_VENDOR_GAISLER,
149
					AMBAPP_DEVICE_GAISLER_APBUART, false, false)) {
150
		printk("can't capture apb dev venID=0x%X, devID=0x%X\n",
151
				AMBAPP_VENDOR_GAISLER, AMBAPP_DEVICE_GAISLER_APBUART);
152
		return -ENODEV;
153
	}
154
	dev_regs = (volatile struct apbuart_regs *) amba_dev.bar[0].start;
155
	return 0;
156
}
157
#elif OPTION_DEFINED(NUMBER,apbuart_base)
158

159
PERIPH_MEMORY_DEFINE(apbuart, OPTION_GET(NUMBER,apbuart_base), sizeof(struct apbuart_regs));
160

161
static int dev_regs_init() {
162
	dev_regs = (volatile struct apbuart_regs *) OPTION_GET(NUMBER,apbuart_base);
163
	return 0;
164
}
165
#else
166
# error "Either DRIVER_AMBAPP or apbuart_base option must be defined"
167
#endif /* DRIVER_AMBAPP */
168

169
static const struct uart_ops uart_ops = {
170
		.uart_getc = apbuart_getc,
171
		.uart_putc = apbuart_putc,
172
		.uart_hasrx = apbuart_has_symbol,
173
		.uart_setup = apbuart_setup,
174
		.uart_irq_en = apbuart_irq_en,
175
		.uart_irq_dis = apbuart_irq_dis,
176
};
177

178
static struct uart uart0 = {
179
		.irq_num = OPTION_GET(NUMBER,irq_num),
180
		.base_addr = OPTION_GET(NUMBER,apbuart_base),
181
		.uart_ops = &uart_ops,
182
};
183

184
static const struct uart_params uart_defparams = {
185
		.baud_rate = OPTION_GET(NUMBER,baud_rate),
186
		.uart_param_flags = UART_PARAM_FLAGS_8BIT_WORD | UART_PARAM_FLAGS_USE_IRQ,
187
};
188

189
static const struct uart_params uart_diag_params = {
190
		.baud_rate = OPTION_GET(NUMBER,baud_rate),
191
		.uart_param_flags = UART_PARAM_FLAGS_8BIT_WORD,
192
};
193

194
DIAG_SERIAL_DEF(&uart0, &uart_diag_params);
195

196
static int uart_init(void) {
197
	return uart_register(&uart0, &uart_defparams);
198
}
199

200

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

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

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

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