Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:22:49

0001 /*
0002  *  Console driver for AT91RM9200 DBGU port
0003  *
0004  *  This driver uses the shared console driver in
0005  *  ...../libbsp/shared/console.c
0006  *
0007  *  Copyright (c) 2003 by Cogent Computer Systems
0008  *  Written by Mike Kelly <mike@cogcomp.com>
0009  *        and Jay Monkman <jtm@lopingdog.com>
0010  *
0011  *  The license and distribution terms for this file may be
0012  *  found in the file LICENSE in this distribution or at
0013  *  http://www.rtems.org/license/LICENSE.
0014  */
0015 #include <bsp.h>
0016 #include <rtems/libio.h>
0017 #include <termios.h>
0018 
0019 #include <at91rm9200.h>
0020 #include <at91rm9200_dbgu.h>
0021 #include <at91rm9200_pmc.h>
0022 #include <rtems/bspIo.h>
0023 #include <libchip/serial.h>
0024 #include <libchip/sersupp.h>
0025 
0026 volatile int dbg_dly;
0027 
0028 /* static function prototypes */
0029 static int     dbgu_first_open(int major, int minor, void *arg);
0030 static int     dbgu_last_close(int major, int minor, void *arg);
0031 static int     dbgu_read(int minor);
0032 static ssize_t dbgu_write(int minor, const char *buf, size_t len);
0033 static void    dbgu_init(int minor);
0034 static void    dbgu_write_polled(int minor, char c);
0035 static int     dbgu_set_attributes(int minor, const struct termios *t);
0036 
0037 /* Pointers to functions for handling the UART. */
0038 const console_fns dbgu_fns =
0039 {
0040     libchip_serial_default_probe,
0041     dbgu_first_open,
0042     dbgu_last_close,
0043     dbgu_read,
0044     dbgu_write,
0045     dbgu_init,
0046     dbgu_write_polled,   /* not used in this driver */
0047     dbgu_set_attributes,
0048     FALSE      /* TRUE if interrupt driven, FALSE if not. */
0049 };
0050 /*********************************************************************/
0051 /* Functions called via callbacks (i.e. the ones in uart_fns */
0052 /*********************************************************************/
0053 
0054 /*
0055  * This is called the first time each device is opened. Since
0056  * the driver is polled, we don't have to do anything. If the driver
0057  * were interrupt driven, we'd enable interrupts here.
0058  */
0059 static int dbgu_first_open(int major, int minor, void *arg)
0060 {
0061     return 0;
0062 }
0063 
0064 
0065 /*
0066  * This is called the last time each device is closed.  Since
0067  * the driver is polled, we don't have to do anything. If the driver
0068  * were interrupt driven, we'd disable interrupts here.
0069  */
0070 static int dbgu_last_close(int major, int minor, void *arg)
0071 {
0072     return 0;
0073 }
0074 
0075 
0076 /*
0077  * Read one character from UART.
0078  *
0079  * return -1 if there's no data, otherwise return
0080  * the character in lowest 8 bits of returned int.
0081  */
0082 static int dbgu_read(int minor)
0083 {
0084     char c;
0085     console_tbl *console_entry;
0086     at91rm9200_dbgu_regs_t *dbgu;
0087 
0088     console_entry = BSP_get_uart_from_minor(minor);
0089 
0090     if (console_entry == NULL) {
0091         return -1;
0092     }
0093 
0094     dbgu = (at91rm9200_dbgu_regs_t *)console_entry->ulCtrlPort1;
0095 
0096     if (!(dbgu->sr & DBGU_INT_RXRDY)) {
0097         return -1;
0098     }
0099 
0100     c  = dbgu->rhr & 0xff;
0101 
0102     return c;
0103 }
0104 
0105 
0106 /*
0107  * Write buffer to UART
0108  *
0109  * return 1 on success, -1 on error
0110  */
0111 static ssize_t dbgu_write(int minor, const char *buf, size_t len)
0112 {
0113     int i, x;
0114     char c;
0115     console_tbl *console_entry;
0116     at91rm9200_dbgu_regs_t *dbgu;
0117 
0118     console_entry = BSP_get_uart_from_minor(minor);
0119 
0120     if (console_entry == NULL) {
0121         return -1;
0122     }
0123 
0124     dbgu = (at91rm9200_dbgu_regs_t *)console_entry->ulCtrlPort1;
0125 
0126     for (i = 0; i < len; i++) {
0127         /* Wait for fifo to have room */
0128         while(1) {
0129             if (dbgu->sr & DBGU_INT_TXRDY) {
0130                 break;
0131             }
0132         }
0133 
0134         c = (char) buf[i];
0135         dbgu->thr = c;
0136 
0137         /* the TXRDY flag does not seem to update right away (is this true?) */
0138         /* so we wait a bit before continuing */
0139         for (x = 0; x < 100; x++) {
0140             dbg_dly++; /* using a global so this doesn't get optimized out */
0141         }
0142     }
0143 
0144     return 1;
0145 }
0146 
0147 
0148 /* Set up the UART. */
0149 static void dbgu_init(int minor)
0150 {
0151     console_tbl *console_entry;
0152     at91rm9200_dbgu_regs_t *dbgu;
0153 
0154     console_entry = BSP_get_uart_from_minor(minor);
0155 
0156     if (console_entry == NULL) {
0157         return;
0158     }
0159 
0160     dbgu = (at91rm9200_dbgu_regs_t *)console_entry->ulCtrlPort1;
0161 
0162     /* Clear error bits, and reset */
0163     dbgu->cr = (DBGU_CR_RSTSTA | DBGU_CR_RSTTX | DBGU_CR_RSTRX);
0164 
0165     /* Clear pending interrupts */
0166     dbgu->idr = DBGU_INT_ALL;
0167     dbgu->imr = 0;
0168 
0169     /* Set port to no parity, no loopback */
0170     dbgu->mr = DBGU_MR_PAR_NONE | DBGU_MR_CHMODE_NORM;
0171 
0172     /* Set the baud rate */
0173     dbgu->brgr = (at91rm9200_get_mck() / 16) / BSP_get_baud();
0174 
0175     /* Enable the DBGU */
0176     dbgu->cr = (DBGU_CR_TXEN | DBGU_CR_RXEN);
0177 }
0178 
0179 /* This is used for getchark support */
0180 static void dbgu_write_polled(int minor, char c)
0181 {
0182     dbgu_write(minor, &c, 1);
0183 }
0184 
0185 /* This is for setting baud rate, bits, etc. */
0186 static int dbgu_set_attributes(int minor, const struct termios *t)
0187 {
0188     return 0;
0189 }
0190 
0191 /***********************************************************************/
0192 /*
0193  * The following functions are not used by TERMIOS, but other RTEMS
0194  * functions use them instead.
0195  */
0196 /***********************************************************************/
0197 /*
0198  * Read from UART. This is used in the exit code, and can't
0199  * rely on interrupts.
0200  */
0201 static int dbgu_poll_read(int minor)
0202 {
0203     return dbgu_read(minor);
0204 }
0205 
0206 
0207 /*
0208  * Write a character to the console. This is used by printk() and
0209  * maybe other low level functions. It should not use interrupts or any
0210  * RTEMS system calls. It needs to be very simple
0211  */
0212 static void _BSP_put_char( char c ) {
0213   dbgu_write_polled(0, c);
0214 }
0215 
0216 BSP_output_char_function_type     BSP_output_char = _BSP_put_char;
0217 
0218 static int _BSP_poll_char(void)
0219 {
0220   return dbgu_poll_read(0);
0221 }
0222 
0223 BSP_polling_getchar_function_type BSP_poll_char = _BSP_poll_char;