]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - cpu/mpc5xx/serial.c
* Patch by Martin Winistoerfer, 23 Mar 2003
[karo-tx-uboot.git] / cpu / mpc5xx / serial.c
1 /*
2  * (C) Copyright 2003
3  * Martin Winistoerfer, martinwinistoerfer@gmx.ch.
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, 
21  */
22
23 /*
24  * File:                serial.c
25  * 
26  * Discription:         Serial interface driver for SCI1 and SCI2. 
27  *                      Since this code will be called from ROM use
28  *                      only non-static local variables.
29  *
30  */
31
32 #include <common.h>
33 #include <watchdog.h>
34 #include <command.h>
35 #include <mpc5xx.h>
36
37
38 /*
39  * Local function prototypes 
40  */
41
42 static int ready_to_send(void);
43
44 /*
45  * Minimal global serial functions needed to use one of the SCI modules.
46  */
47
48 int serial_init (void)
49 {
50         volatile immap_t *immr = (immap_t *)CFG_IMMR;
51
52         serial_setbrg();
53
54 #if defined(CONFIG_5xx_CONS_SCI1)
55         /* 10-Bit, 1 start bit, 8 data bit, no parity, 1 stop bit */
56         immr->im_qsmcm.qsmcm_scc1r1 = SCI_M_10;
57         immr->im_qsmcm.qsmcm_scc1r1 = SCI_TE | SCI_RE; 
58 #else
59         immr->im_qsmcm.qsmcm_scc2r1 = SCI_M_10; 
60         immr->im_qsmcm.qsmcm_scc2r1 = SCI_TE | SCI_RE;
61 #endif
62         return 0;
63 }
64
65 void serial_putc(const char c)
66 {        
67         volatile immap_t *immr = (immap_t *)CFG_IMMR;
68         
69         /* Test for completition */
70         if(ready_to_send()) {
71 #if defined(CONFIG_5xx_CONS_SCI1)
72                 immr->im_qsmcm.qsmcm_sc1dr = (short)c; 
73 #else
74                 immr->im_qsmcm.qsmcm_sc2dr = (short)c;
75 #endif          
76                 if(c == '\n') {
77                         if(ready_to_send());
78 #if defined(CONFIG_5xx_CONS_SCI1)
79                         immr->im_qsmcm.qsmcm_sc1dr = (short)'\r';
80 #else
81                         immr->im_qsmcm.qsmcm_sc2dr = (short)'\r';
82 #endif
83                 }
84         }
85 }
86
87 int serial_getc(void)
88 {       
89         volatile immap_t *immr = (immap_t *)CFG_IMMR;
90         volatile short status;
91         unsigned char tmp;
92     
93         /* New data ? */
94         do {
95 #if defined(CONFIG_5xx_CONS_SCI1)
96                 status = immr->im_qsmcm.qsmcm_sc1sr; 
97 #else
98                 status = immr->im_qsmcm.qsmcm_sc2sr;
99 #endif
100
101 #if defined(CONFIG_WATCHDOG)
102                 reset_5xx_watchdog (immr);      
103 #endif
104         } while ((status & SCI_RDRF) == 0);
105                 
106         /* Read data */
107 #if defined(CONFIG_5xx_CONS_SCI1)
108         tmp = (unsigned char)(immr->im_qsmcm.qsmcm_sc1dr & SCI_SCXDR_MK); 
109 #else
110         tmp = (unsigned char)( immr->im_qsmcm.qsmcm_sc2dr & SCI_SCXDR_MK);
111 #endif
112         return  tmp;
113 }
114
115 int serial_tstc()
116 {
117         volatile immap_t *immr = (immap_t *)CFG_IMMR;
118         short status;
119
120         /* New data character ? */
121 #if defined(CONFIG_5xx_CONS_SCI1)
122         status = immr->im_qsmcm.qsmcm_sc1sr; 
123 #else
124         status = immr->im_qsmcm.qsmcm_sc2sr;
125 #endif
126         return (status & SCI_RDRF); 
127 }
128
129 void serial_setbrg (void)
130 {
131         DECLARE_GLOBAL_DATA_PTR;
132         volatile immap_t *immr = (immap_t *)CFG_IMMR;
133         short scxbr;
134
135         /* Set baudrate */
136         scxbr = (gd->cpu_clk / (32 * gd->baudrate));
137 #if defined(CONFIG_5xx_CONS_SCI1)
138         immr->im_qsmcm.qsmcm_scc1r0 = (scxbr & SCI_SCXBR_MK); 
139 #else
140         immr->im_qsmcm.qsmcm_scc2r0 = (scxbr & SCI_SCXBR_MK);
141 #endif
142 }
143
144 void serial_puts (const char *s)
145 {
146         while (*s) {
147                 serial_putc(*s);
148                 ++s;
149         }
150 }
151
152 int ready_to_send(void)
153 {
154         volatile immap_t *immr = (immap_t *)CFG_IMMR;
155         volatile short status;
156
157         do {
158 #if defined(CONFIG_5xx_CONS_SCI1)
159                 status = immr->im_qsmcm.qsmcm_sc1sr; 
160 #else
161                 status = immr->im_qsmcm.qsmcm_sc2sr;
162 #endif
163
164 #if defined(CONFIG_WATCHDOG)
165                 reset_5xx_watchdog (immr);      
166 #endif
167         } while ((status & SCI_TDRE) == 0);
168         return 1; 
169
170 }
171