embox

Форк
0
108 строк · 2.6 Кб
1
/**
2
 * @file
3
 * @brief Serial driver for x86 (compatible with 16550)
4
 *
5
 * @date 12.04.10
6
 * @author Nikolay Korotky
7
 */
8

9
#include <stdint.h>
10

11
#include <asm/io.h>
12

13
#include <drivers/serial/uart_dev.h>
14

15
#include "i8250.h"
16

17
static uint8_t calc_line_stat(const struct uart_params *params) {
18
	uint8_t line_stat;
19
	uint32_t flags;
20

21
	line_stat = 0;
22
	flags = params->uart_param_flags;
23

24
	if((flags & UART_PARAM_FLAGS_PARITY_NONE)) {
25
		line_stat |= UART_NO_PARITY;
26
	}
27
	if(flags & UART_PARAM_FLAGS_8BIT_WORD) {
28
		line_stat |= UART_8BITS_WORD;
29
	}
30
	if((flags & UART_PARAM_FLAGS_2_STOP)) {
31
		line_stat |= UART_2_STOP_BIT;
32
	} else {
33
		line_stat |= UART_1_STOP_BIT;
34
	}
35
	return line_stat;
36
}
37

38
static int i8250_setup(struct uart *dev, const struct uart_params *params) {
39
	uint8_t line_stat;
40

41
	line_stat = calc_line_stat(params);
42

43
	line_stat = UART_NO_PARITY | UART_8BITS_WORD | UART_1_STOP_BIT;
44

45
	/* Turn off the interrupt */
46
	out8(0x0, dev->base_addr + UART_IER);
47
	/* Set DLAB */
48
	out8(UART_DLAB, dev->base_addr + UART_LCR);
49
	/* Set the baud rate */
50
	out8(DIVISOR(params->baud_rate) & 0xFF, dev->base_addr + UART_DLL);
51
	out8((DIVISOR(params->baud_rate) >> 8) & 0xFF, dev->base_addr + UART_DLH);
52
	/* Set the line status */
53
	out8(line_stat, dev->base_addr + UART_LCR);
54
	/* Uart enable FIFO */
55
	out8(UART_ENABLE_FIFO, dev->base_addr + UART_FCR);
56
	/* Uart enable modem (turn on DTR, RTS, and OUT2) */
57
	out8(UART_ENABLE_MODEM, dev->base_addr + UART_MCR);
58

59
	/*enable rx interrupt*/
60
	if (params->uart_param_flags & UART_PARAM_FLAGS_USE_IRQ) {
61
		/*enable rx interrupt*/
62
		out8(UART_IER_RX_ENABLE, dev->base_addr + UART_IER);
63
	}
64

65
	return 0;
66
}
67

68
static int i8250_irq_en(struct uart *dev, const struct uart_params *params) {
69
	/*enable rx interrupt*/
70
	if (params->uart_param_flags & UART_PARAM_FLAGS_USE_IRQ) {
71
		/*enable rx interrupt*/
72
		out8(UART_IER_RX_ENABLE, dev->base_addr + UART_IER);
73
	}
74

75
	return 0;
76
}
77

78
static int i8250_irq_dis(struct uart *dev, const struct uart_params *params) {
79
	if (params->uart_param_flags & UART_PARAM_FLAGS_USE_IRQ) {
80
		/*disable rx interrupt*/
81
		out8(0, dev->base_addr + UART_IER);
82
	}
83

84
	return 0;
85
}
86

87
static int i8250_putc(struct uart *dev, int ch) {
88
	while (!(in8(dev->base_addr + UART_LSR) & UART_EMPTY_TX));
89
	out8((uint8_t) ch, dev->base_addr + UART_TX);
90
	return 0;
91
}
92

93
static int i8250_has_symbol(struct uart *dev) {
94
	return in8(dev->base_addr + UART_LSR) & UART_DATA_READY;
95
}
96

97
static int i8250_getc(struct uart *dev) {
98
	return in8(dev->base_addr + UART_RX);
99
}
100

101
const struct uart_ops i8250_uart_ops = {
102
		.uart_getc = i8250_getc,
103
		.uart_putc = i8250_putc,
104
		.uart_hasrx = i8250_has_symbol,
105
		.uart_setup = i8250_setup,
106
		.uart_irq_en = i8250_irq_en,
107
		.uart_irq_dis = i8250_irq_dis,
108
};
109

110

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

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

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

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