1 | /* |
2 | * Copyright (C) 2009 Qi Hardware Inc., |
3 | * Author: Xiangfu Liu <xiangfu@qi-hardware.com> |
4 | * |
5 | * This program is free software; you can redistribute it and/or |
6 | * modify it under the terms of the GNU General Public License |
7 | * version 3 as published by the Free Software Foundation. |
8 | * |
9 | * This program is distributed in the hope that it will be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | * GNU General Public License for more details. |
13 | * |
14 | * You should have received a copy of the GNU General Public License |
15 | * along with this program; if not, write to the Free Software |
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, |
17 | * Boston, MA 02110-1301, USA |
18 | */ |
19 | #include "jz4750.h" |
20 | |
21 | volatile u32 UART_BASE; |
22 | #define CONFIG_BAUDRATE 57600 |
23 | #define CFG_EXTAL 12000000 /* EXTAL freq must=12 MHz !! */ |
24 | |
25 | void serial_setbrg (void) |
26 | { |
27 | volatile u8 *uart_lcr = (volatile u8 *)(UART_BASE + OFF_LCR); |
28 | volatile u8 *uart_dlhr = (volatile u8 *)(UART_BASE + OFF_DLHR); |
29 | volatile u8 *uart_dllr = (volatile u8 *)(UART_BASE + OFF_DLLR); |
30 | u32 baud_div, tmp; |
31 | |
32 | baud_div = CFG_EXTAL / 16 / CONFIG_BAUDRATE; |
33 | tmp = *uart_lcr; |
34 | tmp |= UART_LCR_DLAB; |
35 | *uart_lcr = tmp; |
36 | |
37 | *uart_dlhr = (baud_div >> 8) & 0xff; |
38 | *uart_dllr = baud_div & 0xff; |
39 | |
40 | tmp &= ~UART_LCR_DLAB; |
41 | *uart_lcr = tmp; |
42 | } |
43 | |
44 | void serial_putc (const char c) |
45 | { |
46 | volatile u8 *uart_lsr = (volatile u8 *)(UART_BASE + OFF_LSR); |
47 | volatile u8 *uart_tdr = (volatile u8 *)(UART_BASE + OFF_TDR); |
48 | |
49 | if (c == '\n') serial_putc ('\r'); |
50 | |
51 | /* Wait for fifo to shift out some bytes */ |
52 | while ( !((*uart_lsr & (UART_LSR_TDRQ | UART_LSR_TEMT)) == 0x60) ); |
53 | |
54 | *uart_tdr = (u8)c; |
55 | } |
56 | |
57 | void serial_puts (const char *s) |
58 | { |
59 | while (*s) { |
60 | serial_putc (*s++); |
61 | } |
62 | } |
63 | |
64 | void serial_init(void) |
65 | { |
66 | volatile u8 *uart_fcr = (volatile u8 *)(UART_BASE + OFF_FCR); |
67 | volatile u8 *uart_lcr = (volatile u8 *)(UART_BASE + OFF_LCR); |
68 | volatile u8 *uart_ier = (volatile u8 *)(UART_BASE + OFF_IER); |
69 | volatile u8 *uart_sircr = (volatile u8 *)(UART_BASE + OFF_SIRCR); |
70 | |
71 | /* Disable port interrupts while changing hardware */ |
72 | *uart_ier = 0; |
73 | |
74 | /* Disable UART unit function */ |
75 | *uart_fcr = ~UART_FCR_UUE; |
76 | |
77 | /* Set both receiver and transmitter in UART mode (not SIR) */ |
78 | *uart_sircr = ~(SIRCR_RSIRE | SIRCR_TSIRE); |
79 | |
80 | /* Set databits, stopbits and parity. (8-bit data, 1 stopbit, no parity) */ |
81 | *uart_lcr = UART_LCR_WLEN_8 | UART_LCR_STOP_1; |
82 | |
83 | /* Set baud rate */ |
84 | serial_setbrg(); |
85 | |
86 | /* Enable UART unit, enable and clear FIFO */ |
87 | *uart_fcr = UART_FCR_UUE | UART_FCR_FE | UART_FCR_TFLS | UART_FCR_RFLS; |
88 | } |
89 | |
90 | void serial_put_hex(unsigned int d) |
91 | { |
92 | unsigned char c[12]; |
93 | char i; |
94 | for(i = 0; i < 8;i++) |
95 | { |
96 | c[i] = (d >> ((7 - i) * 4)) & 0xf; |
97 | if(c[i] < 10) |
98 | c[i] += 0x30; |
99 | else |
100 | c[i] += (0x41 - 10); |
101 | } |
102 | c[8] = '\n'; |
103 | c[9] = 0; |
104 | serial_puts(c); |
105 | } |
106 | |