diff options
Diffstat (limited to 'arch/ppc/cpu/mpc5xx/serial.c')
-rw-r--r-- | arch/ppc/cpu/mpc5xx/serial.c | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/arch/ppc/cpu/mpc5xx/serial.c b/arch/ppc/cpu/mpc5xx/serial.c new file mode 100644 index 0000000000..88c6db81cb --- /dev/null +++ b/arch/ppc/cpu/mpc5xx/serial.c @@ -0,0 +1,170 @@ +/* + * (C) Copyright 2003 + * Martin Winistoerfer, martinwinistoerfer@gmx.ch. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, + */ + +/* + * File: serial.c + * + * Discription: Serial interface driver for SCI1 and SCI2. + * Since this code will be called from ROM use + * only non-static local variables. + * + */ + +#include <common.h> +#include <watchdog.h> +#include <command.h> +#include <mpc5xx.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* + * Local function prototypes + */ + +static int ready_to_send(void); + +/* + * Minimal global serial functions needed to use one of the SCI modules. + */ + +int serial_init (void) +{ + volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; + + serial_setbrg(); + +#if defined(CONFIG_5xx_CONS_SCI1) + /* 10-Bit, 1 start bit, 8 data bit, no parity, 1 stop bit */ + immr->im_qsmcm.qsmcm_scc1r1 = SCI_M_10; + immr->im_qsmcm.qsmcm_scc1r1 = SCI_TE | SCI_RE; +#else + immr->im_qsmcm.qsmcm_scc2r1 = SCI_M_10; + immr->im_qsmcm.qsmcm_scc2r1 = SCI_TE | SCI_RE; +#endif + return 0; +} + +void serial_putc(const char c) +{ + volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; + + /* Test for completition */ + if(ready_to_send()) { +#if defined(CONFIG_5xx_CONS_SCI1) + immr->im_qsmcm.qsmcm_sc1dr = (short)c; +#else + immr->im_qsmcm.qsmcm_sc2dr = (short)c; +#endif + if(c == '\n') { + if(ready_to_send()); +#if defined(CONFIG_5xx_CONS_SCI1) + immr->im_qsmcm.qsmcm_sc1dr = (short)'\r'; +#else + immr->im_qsmcm.qsmcm_sc2dr = (short)'\r'; +#endif + } + } +} + +int serial_getc(void) +{ + volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; + volatile short status; + unsigned char tmp; + + /* New data ? */ + do { +#if defined(CONFIG_5xx_CONS_SCI1) + status = immr->im_qsmcm.qsmcm_sc1sr; +#else + status = immr->im_qsmcm.qsmcm_sc2sr; +#endif + +#if defined(CONFIG_WATCHDOG) + reset_5xx_watchdog (immr); +#endif + } while ((status & SCI_RDRF) == 0); + + /* Read data */ +#if defined(CONFIG_5xx_CONS_SCI1) + tmp = (unsigned char)(immr->im_qsmcm.qsmcm_sc1dr & SCI_SCXDR_MK); +#else + tmp = (unsigned char)( immr->im_qsmcm.qsmcm_sc2dr & SCI_SCXDR_MK); +#endif + return tmp; +} + +int serial_tstc() +{ + volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; + short status; + + /* New data character ? */ +#if defined(CONFIG_5xx_CONS_SCI1) + status = immr->im_qsmcm.qsmcm_sc1sr; +#else + status = immr->im_qsmcm.qsmcm_sc2sr; +#endif + return (status & SCI_RDRF); +} + +void serial_setbrg (void) +{ + volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; + short scxbr; + + /* Set baudrate */ + scxbr = (gd->cpu_clk / (32 * gd->baudrate)); +#if defined(CONFIG_5xx_CONS_SCI1) + immr->im_qsmcm.qsmcm_scc1r0 = (scxbr & SCI_SCXBR_MK); +#else + immr->im_qsmcm.qsmcm_scc2r0 = (scxbr & SCI_SCXBR_MK); +#endif +} + +void serial_puts (const char *s) +{ + while (*s) { + serial_putc(*s); + ++s; + } +} + +int ready_to_send(void) +{ + volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR; + volatile short status; + + do { +#if defined(CONFIG_5xx_CONS_SCI1) + status = immr->im_qsmcm.qsmcm_sc1sr; +#else + status = immr->im_qsmcm.qsmcm_sc2sr; +#endif + +#if defined(CONFIG_WATCHDOG) + reset_5xx_watchdog (immr); +#endif + } while ((status & SCI_TDRE) == 0); + return 1; + +} |