1 /*
2 * serialGT.c
3 *
4 * BRIEF MODULE DESCRIPTION
5 * Low Level Serial Port control for use
6 * with the Galileo EVB64120A MIPS eval board and
7 * its on board two channel 16552 Uart.
8 *
9 * Copyright (C) 2000 RidgeRun, Inc.
10 * Author: RidgeRun, Inc.
11 * glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version.
17 *
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
19 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
21 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
24 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * You should have received a copy of the GNU General Public License along
30 * with this program; if not, write to the Free Software Foundation, Inc.,
31 * 675 Mass Ave, Cambridge, MA 02139, USA.
32 *
33 */
34
35 // Note:
36 // Serial CHANNELS - 0 is the bottom connector of evb64120A.
37 // (The one that maps to the "B" channel of the
38 // board's uart)
39 // 1 is the top connector of evb64120A.
40 // (The one that maps to the "A" channel of the
41 // board's uart)
42 int DEBUG_CHANNEL = 0; // See Note Above
43 int CONSOLE_CHANNEL = 1; // See Note Above
44
45 #define DUART 0xBD000000 /* Base address of Uart. */
46 #define CHANNELOFFSET 0x20 /* DUART+CHANNELOFFSET gets you to the ChanA
47 register set of the 16552 Uart device.
48 DUART+0 gets you to the ChanB register set.
49 */
50 #define DUART_DELTA 0x4
51 #define FIFO_ENABLE 0x07
52 #define INT_ENABLE 0x04 /* default interrupt mask */
53
54 #define RBR 0x00
55 #define THR 0x00
56 #define DLL 0x00
57 #define IER 0x01
58 #define DLM 0x01
59 #define IIR 0x02
60 #define FCR 0x02
61 #define LCR 0x03
62 #define MCR 0x04
63 #define LSR 0x05
64 #define MSR 0x06
65 #define SCR 0x07
66
67 #define LCR_DLAB 0x80
68 #define XTAL 1843200
69 #define LSR_THRE 0x20
70 #define LSR_BI 0x10
71 #define LSR_DR 0x01
72 #define MCR_LOOP 0x10
73 #define ACCESS_DELAY 0x10000
74
75 /******************************
76 Routine:
77 Description:
78 ******************************/
inreg(int channel,int reg)79 int inreg(int channel, int reg)
80 {
81 int val;
82 val =
83 *((volatile unsigned char *) DUART +
84 (channel * CHANNELOFFSET) + (reg * DUART_DELTA));
85 return val;
86 }
87
88 /******************************
89 Routine:
90 Description:
91 ******************************/
outreg(int channel,int reg,unsigned char val)92 void outreg(int channel, int reg, unsigned char val)
93 {
94 *((volatile unsigned char *) DUART + (channel * CHANNELOFFSET)
95 + (reg * DUART_DELTA)) = val;
96 }
97
98 /******************************
99 Routine:
100 Description:
101 Initialize the device driver.
102 ******************************/
serial_init(int channel)103 void serial_init(int channel)
104 {
105 /*
106 * Configure active port, (CHANNELOFFSET already set.)
107 *
108 * Set 8 bits, 1 stop bit, no parity.
109 *
110 * LCR<7> 0 divisor latch access bit
111 * LCR<6> 0 break control (1=send break)
112 * LCR<5> 0 stick parity (0=space, 1=mark)
113 * LCR<4> 0 parity even (0=odd, 1=even)
114 * LCR<3> 0 parity enable (1=enabled)
115 * LCR<2> 0 # stop bits (0=1, 1=1.5)
116 * LCR<1:0> 11 bits per character(00=5, 01=6, 10=7, 11=8)
117 */
118 outreg(channel, LCR, 0x3);
119
120 outreg(channel, FCR, FIFO_ENABLE); /* Enable the FIFO */
121
122 outreg(channel, IER, INT_ENABLE); /* Enable appropriate interrupts */
123 }
124
125 /******************************
126 Routine:
127 Description:
128 Set the baud rate.
129 ******************************/
serial_set(int channel,unsigned long baud)130 void serial_set(int channel, unsigned long baud)
131 {
132 unsigned char sav_lcr;
133
134 /*
135 * Enable access to the divisor latches by setting DLAB in LCR.
136 *
137 */
138 sav_lcr = inreg(channel, LCR);
139
140 #if 0
141 /*
142 * Set baud rate
143 */
144 outreg(channel, LCR, LCR_DLAB | sav_lcr);
145 // outreg(DLL,(XTAL/(16*2*(baud))-2));
146 outreg(channel, DLL, XTAL / (16 * baud));
147 // outreg(DLM,(XTAL/(16*2*(baud))-2)>>8);
148 outreg(channel, DLM, (XTAL / (16 * baud)) >> 8);
149 #else
150 /*
151 * Note: Set baud rate, hardcoded here for rate of 115200
152 * since became unsure of above "buad rate" algorithm (??).
153 */
154 outreg(channel, LCR, 0x83);
155 outreg(channel, DLM, 0x00); // See note above
156 outreg(channel, DLL, 0x02); // See note above.
157 outreg(channel, LCR, 0x03);
158 #endif
159
160 /*
161 * Restore line control register
162 */
163 outreg(channel, LCR, sav_lcr);
164 }
165
166
167 /******************************
168 Routine:
169 Description:
170 Transmit a character.
171 ******************************/
serial_putc(int channel,int c)172 void serial_putc(int channel, int c)
173 {
174 while ((inreg(channel, LSR) & LSR_THRE) == 0);
175 outreg(channel, THR, c);
176 }
177
178 /******************************
179 Routine:
180 Description:
181 Read a received character if one is
182 available. Return -1 otherwise.
183 ******************************/
serial_getc(int channel)184 int serial_getc(int channel)
185 {
186 if (inreg(channel, LSR) & LSR_DR) {
187 return inreg(channel, RBR);
188 }
189 return -1;
190 }
191
192 /******************************
193 Routine:
194 Description:
195 Used by embedded gdb client. (example; gdb-stub.c)
196 ******************************/
getDebugChar()197 char getDebugChar()
198 {
199 int val;
200 while ((val = serial_getc(DEBUG_CHANNEL)) == -1); // loop until we get a character in.
201 return (char) val;
202 }
203
204 /******************************
205 Routine:
206 Description:
207 Used by embedded gdb target. (example; gdb-stub.c)
208 ******************************/
putDebugChar(char c)209 void putDebugChar(char c)
210 {
211 serial_putc(DEBUG_CHANNEL, (int) c);
212 }
213