1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
#include <nds32_intrinsic.h>
#define DEFAULT_BAUDRATE 115200 /* 8n1 */
#define IN8(reg) (uint8_t)((*(volatile unsigned long *)(reg)) & 0x000000FF)
#define READ_CLR(reg) (*(volatile unsigned long *)(reg))
int drv_uart_set_baudrate(int baudrate)
{
unsigned long baud_div; /* baud rate divisor */
unsigned long temp_word;
baud_div = (MB_UCLK / (16 * baudrate));
/* Save LCR temporary */
temp_word = IN8(STUARTC_BASE + UARTC_LCR_OFFSET);
/* Setup dlab bit for baud rate setting */
OUT8(STUARTC_BASE + UARTC_LCR_OFFSET, (temp_word | UARTC_LCR_DLAB));
/* Apply baud rate */
OUT8(STUARTC_BASE + UARTC_DLM_OFFSET, (unsigned char)(baud_div >> 8));
OUT8(STUARTC_BASE + UARTC_DLL_OFFSET, (unsigned char)baud_div);
OUT8(STUARTC_BASE + UARTC_PSR_OFFSET, (unsigned char)1);
/* Restore LCR */
OUT8(STUARTC_BASE + UARTC_LCR_OFFSET, temp_word);
return 0;
}
int drv_uart_is_kbd_hit(void)
{
return IN8(STUARTC_BASE + UARTC_LSR_OFFSET) & UARTC_LSR_RDR;
}
int drv_uart_get_char(void)
{
while (!(IN8(STUARTC_BASE + UARTC_LSR_OFFSET) & UARTC_LSR_RDR))
;
return IN8(STUARTC_BASE + UARTC_RBR_OFFSET);
}
void drv_uart_put_char(int ch)
{
while (!(IN8(STUARTC_BASE + UARTC_LSR_OFFSET) & UARTC_LSR_THRE))
;
OUT8(STUARTC_BASE + UARTC_THR_OFFSET, ch);
}
int drv_uart_init(void)
{
/* Clear everything */
OUT8(STUARTC_BASE + UARTC_IER_OFFSET, 0x0);
OUT8(STUARTC_BASE + UARTC_LCR_OFFSET, 0x0);
/* Setup baud rate */
drv_uart_set_baudrate(DEFAULT_BAUDRATE);
/* Setup parity, data bits, and stop bits */
OUT8(STUARTC_BASE + UARTC_LCR_OFFSET, \
(UARTC_LCR_PARITY_NONE | UARTC_LCR_BITS8 | UARTC_LCR_STOP1));
return 0;
}
/**********************************************
*
* Archer Chang
*
* driver API with reg base
*
***********************************************/
int __drv_uart_set_baudrate(unsigned int regbase, int baudrate)
{
unsigned long baud_div; /* baud rate divisor */
unsigned long temp_word;
baud_div = (MB_UCLK / (16 * baudrate));
/* Save LCR temporary */
temp_word = IN8(regbase + UARTC_LCR_OFFSET);
/* Setup dlab bit for baud rate setting */
OUT8(regbase + UARTC_LCR_OFFSET, (temp_word | UARTC_LCR_DLAB));
/* Apply baud rate */
OUT8(regbase + UARTC_DLM_OFFSET, (unsigned char)(baud_div >> 8));
OUT8(regbase + UARTC_DLL_OFFSET, (unsigned char)baud_div);
OUT8(regbase + UARTC_PSR_OFFSET, (unsigned char)1);
/* Restore LCR */
OUT8(regbase + UARTC_LCR_OFFSET, temp_word);
return 0;
}
int __drv_uart_is_kbd_hit(unsigned int regbase)
{
return IN8(regbase + UARTC_LSR_OFFSET) & UARTC_LSR_RDR;
}
int __drv_uart_get_char(unsigned int regbase)
{
while (!(IN8(regbase + UARTC_LSR_OFFSET) & UARTC_LSR_RDR))
;
return IN8(regbase + UARTC_RBR_OFFSET);
}
void __drv_uart_put_char(unsigned int regbase, int ch)
{
while (!(IN8(regbase + UARTC_LSR_OFFSET) & UARTC_LSR_THRE))
;
OUT8(regbase + UARTC_THR_OFFSET, ch);
}
int __drv_uart_put_char_nowait(unsigned int regbase, int ch)
{
OUT8(regbase + UARTC_THR_OFFSET, ch);
return 1;
}
int __drv_uart_init(unsigned int regbase, int baudrate)
{
/* Clear everything */
OUT8(regbase + UARTC_IER_OFFSET, 0x0);
OUT8(regbase + UARTC_LCR_OFFSET, 0x0);
/* Setup baud rate */
__drv_uart_set_baudrate(regbase, baudrate);
/* Setup parity, data bits, and stop bits */
OUT8(regbase + UARTC_LCR_OFFSET, \
(UARTC_LCR_PARITY_NONE | UARTC_LCR_BITS8 | UARTC_LCR_STOP1));
return 0;
}
|