blob: 48687829e5aaa067e21115f84914c51bd6992c7a [file] [log] [blame]
wdenk0db5bca2003-03-31 17:27:09 +00001/*
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
wdenk8bde7f72003-06-27 21:31:46 +000020 * Foundation,
wdenk0db5bca2003-03-31 17:27:09 +000021 */
22
23/*
24 * File: serial.c
wdenk8bde7f72003-06-27 21:31:46 +000025 *
26 * Discription: Serial interface driver for SCI1 and SCI2.
wdenk0db5bca2003-03-31 17:27:09 +000027 * 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/*
wdenk8bde7f72003-06-27 21:31:46 +000039 * Local function prototypes
wdenk0db5bca2003-03-31 17:27:09 +000040 */
41
42static int ready_to_send(void);
43
44/*
45 * Minimal global serial functions needed to use one of the SCI modules.
46 */
47
48int 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;
wdenk8bde7f72003-06-27 21:31:46 +000057 immr->im_qsmcm.qsmcm_scc1r1 = SCI_TE | SCI_RE;
wdenk0db5bca2003-03-31 17:27:09 +000058#else
wdenk8bde7f72003-06-27 21:31:46 +000059 immr->im_qsmcm.qsmcm_scc2r1 = SCI_M_10;
wdenk0db5bca2003-03-31 17:27:09 +000060 immr->im_qsmcm.qsmcm_scc2r1 = SCI_TE | SCI_RE;
61#endif
62 return 0;
63}
64
65void serial_putc(const char c)
wdenk8bde7f72003-06-27 21:31:46 +000066{
wdenk0db5bca2003-03-31 17:27:09 +000067 volatile immap_t *immr = (immap_t *)CFG_IMMR;
wdenk8bde7f72003-06-27 21:31:46 +000068
wdenk0db5bca2003-03-31 17:27:09 +000069 /* Test for completition */
70 if(ready_to_send()) {
71#if defined(CONFIG_5xx_CONS_SCI1)
wdenk8bde7f72003-06-27 21:31:46 +000072 immr->im_qsmcm.qsmcm_sc1dr = (short)c;
wdenk0db5bca2003-03-31 17:27:09 +000073#else
74 immr->im_qsmcm.qsmcm_sc2dr = (short)c;
wdenk8bde7f72003-06-27 21:31:46 +000075#endif
wdenk0db5bca2003-03-31 17:27:09 +000076 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
87int serial_getc(void)
wdenk8bde7f72003-06-27 21:31:46 +000088{
wdenk0db5bca2003-03-31 17:27:09 +000089 volatile immap_t *immr = (immap_t *)CFG_IMMR;
90 volatile short status;
91 unsigned char tmp;
wdenk8bde7f72003-06-27 21:31:46 +000092
wdenk0db5bca2003-03-31 17:27:09 +000093 /* New data ? */
94 do {
95#if defined(CONFIG_5xx_CONS_SCI1)
wdenk8bde7f72003-06-27 21:31:46 +000096 status = immr->im_qsmcm.qsmcm_sc1sr;
wdenk0db5bca2003-03-31 17:27:09 +000097#else
98 status = immr->im_qsmcm.qsmcm_sc2sr;
99#endif
100
101#if defined(CONFIG_WATCHDOG)
wdenk8bde7f72003-06-27 21:31:46 +0000102 reset_5xx_watchdog (immr);
wdenk0db5bca2003-03-31 17:27:09 +0000103#endif
wdenk8bde7f72003-06-27 21:31:46 +0000104 } while ((status & SCI_RDRF) == 0);
105
wdenk0db5bca2003-03-31 17:27:09 +0000106 /* Read data */
107#if defined(CONFIG_5xx_CONS_SCI1)
wdenk8bde7f72003-06-27 21:31:46 +0000108 tmp = (unsigned char)(immr->im_qsmcm.qsmcm_sc1dr & SCI_SCXDR_MK);
wdenk0db5bca2003-03-31 17:27:09 +0000109#else
110 tmp = (unsigned char)( immr->im_qsmcm.qsmcm_sc2dr & SCI_SCXDR_MK);
111#endif
112 return tmp;
113}
114
115int serial_tstc()
116{
117 volatile immap_t *immr = (immap_t *)CFG_IMMR;
wdenk8bde7f72003-06-27 21:31:46 +0000118 short status;
wdenk0db5bca2003-03-31 17:27:09 +0000119
120 /* New data character ? */
121#if defined(CONFIG_5xx_CONS_SCI1)
wdenk8bde7f72003-06-27 21:31:46 +0000122 status = immr->im_qsmcm.qsmcm_sc1sr;
wdenk0db5bca2003-03-31 17:27:09 +0000123#else
124 status = immr->im_qsmcm.qsmcm_sc2sr;
125#endif
wdenk8bde7f72003-06-27 21:31:46 +0000126 return (status & SCI_RDRF);
wdenk0db5bca2003-03-31 17:27:09 +0000127}
128
129void serial_setbrg (void)
130{
131 DECLARE_GLOBAL_DATA_PTR;
wdenk8bde7f72003-06-27 21:31:46 +0000132 volatile immap_t *immr = (immap_t *)CFG_IMMR;
wdenk0db5bca2003-03-31 17:27:09 +0000133 short scxbr;
134
135 /* Set baudrate */
136 scxbr = (gd->cpu_clk / (32 * gd->baudrate));
137#if defined(CONFIG_5xx_CONS_SCI1)
wdenk8bde7f72003-06-27 21:31:46 +0000138 immr->im_qsmcm.qsmcm_scc1r0 = (scxbr & SCI_SCXBR_MK);
wdenk0db5bca2003-03-31 17:27:09 +0000139#else
140 immr->im_qsmcm.qsmcm_scc2r0 = (scxbr & SCI_SCXBR_MK);
141#endif
142}
143
144void serial_puts (const char *s)
145{
146 while (*s) {
147 serial_putc(*s);
148 ++s;
149 }
150}
151
152int ready_to_send(void)
153{
154 volatile immap_t *immr = (immap_t *)CFG_IMMR;
155 volatile short status;
156
wdenk8bde7f72003-06-27 21:31:46 +0000157 do {
wdenk0db5bca2003-03-31 17:27:09 +0000158#if defined(CONFIG_5xx_CONS_SCI1)
wdenk8bde7f72003-06-27 21:31:46 +0000159 status = immr->im_qsmcm.qsmcm_sc1sr;
wdenk0db5bca2003-03-31 17:27:09 +0000160#else
161 status = immr->im_qsmcm.qsmcm_sc2sr;
162#endif
163
164#if defined(CONFIG_WATCHDOG)
wdenk8bde7f72003-06-27 21:31:46 +0000165 reset_5xx_watchdog (immr);
wdenk0db5bca2003-03-31 17:27:09 +0000166#endif
wdenk8bde7f72003-06-27 21:31:46 +0000167 } while ((status & SCI_TDRE) == 0);
168 return 1;
wdenk0db5bca2003-03-31 17:27:09 +0000169
170}