Back to home page

LXR

 
 

    


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

0001 /*
0002  * Console driver for pxa255 full function port by Yang Xi <hiyangxi@gmail.com>
0003  * Copyright (c) 2004 by Jay Monkman <jtm@lopingdog.com>
0004  *
0005  *  The license and distribution terms for this file may be
0006  *  found in the file LICENSE in this distribution or at
0007  *  http://www.rtems.org/license/LICENSE.
0008  */
0009 
0010 #include <bsp.h>
0011 #include <rtems/libio.h>
0012 #include <termios.h>
0013 
0014 #include <pxa255.h>
0015 #include <ffuart.h>
0016 #include <rtems/bspIo.h>
0017 #include <libchip/serial.h>
0018 #include <libchip/sersupp.h>
0019 
0020 volatile int dbg_dly;
0021 
0022 /* static function prototypes */
0023 static int     ffuart_first_open(int major, int minor, void *arg);
0024 static int     ffuart_last_close(int major, int minor, void *arg);
0025 static int     ffuart_read(int minor);
0026 static ssize_t ffuart_write(int minor, const char *buf, size_t len);
0027 static void    ffuart_init(int minor);
0028 static void    ffuart_write_polled(int minor, char c);
0029 static int     ffuart_set_attributes(int minor, const struct termios *t);
0030 
0031 /* Pointers to functions for handling the UART. */
0032 const console_fns ffuart_fns =
0033 {
0034     libchip_serial_default_probe,
0035     ffuart_first_open,
0036     ffuart_last_close,
0037     ffuart_read,
0038     ffuart_write,
0039     ffuart_init,
0040     ffuart_write_polled,   /* not used in this driver */
0041     ffuart_set_attributes,
0042     FALSE      /* TRUE if interrupt driven, FALSE if not. */
0043 };
0044 
0045 
0046 /*
0047  * This is called the first time each device is opened. Since
0048  * the driver is polled, we don't have to do anything. If the driver
0049  * were interrupt driven, we'd enable interrupts here.
0050  */
0051 static int ffuart_first_open(int major, int minor, void *arg)
0052 {
0053     return 0;
0054 }
0055 
0056 
0057 /*
0058  * This is called the last time each device is closed.  Since
0059  * the driver is polled, we don't have to do anything. If the driver
0060  * were interrupt driven, we'd disable interrupts here.
0061  */
0062 static int ffuart_last_close(int major, int minor, void *arg)
0063 {
0064     return 0;
0065 }
0066 
0067 
0068 /*
0069  * Read one character from UART.
0070  *
0071  * return -1 if there's no data, otherwise return
0072  * the character in lowest 8 bits of returned int.
0073  */
0074 static int ffuart_read(int minor)
0075 {
0076     char c;
0077     console_tbl *console_entry;
0078     ffuart_reg_t *ffuart;
0079 
0080     console_entry = BSP_get_uart_from_minor(minor);
0081 
0082     if (console_entry == NULL) {
0083         return -1;
0084     }
0085 
0086     ffuart = (ffuart_reg_t *)console_entry->ulCtrlPort1;
0087 
0088     if (!(ffuart->lsr & FULL_RECEIVE)) {
0089         return -1;
0090     }
0091 
0092     c  = ffuart->rbr & 0xff;
0093 
0094     return c;
0095 }
0096 
0097 
0098 /*
0099  * Write buffer to UART
0100  *
0101  * return 1 on success, -1 on error
0102  */
0103 static ssize_t ffuart_write(int minor, const char *buf, size_t len)
0104 {
0105     size_t i, x;
0106     char c;
0107     console_tbl *console_entry;
0108     ffuart_reg_t *ffuart;
0109 
0110     console_entry = BSP_get_uart_from_minor(minor);
0111 
0112     if (console_entry == NULL) {
0113         return -1;
0114     }
0115 
0116     ffuart = (ffuart_reg_t *)console_entry->ulCtrlPort1;
0117 
0118     for (i = 0; i < len; i++) {
0119 
0120         while(1) {
0121             if (ffuart->lsr & SEND_EMPTY) {
0122                 break;
0123             }
0124         }
0125 
0126         c = (char) buf[i];
0127 #if ON_SKYEYE != 1
0128     if(c=='\n'){
0129       ffuart->rbr = '\r';
0130       for (x = 0; x < 100; x++) {
0131             dbg_dly++; /* using a global so this doesn't get optimized out */
0132       }
0133       while(1){
0134         if(ffuart->lsr & SEND_EMPTY){
0135           break;
0136         }
0137       }
0138     }
0139 #endif
0140         ffuart->rbr = c;
0141 
0142         /* the TXRDY flag does not seem to update right away (is this true?) */
0143         /* so we wait a bit before continuing */
0144         for (x = 0; x < 100; x++) {
0145             dbg_dly++; /* using a global so this doesn't get optimized out */
0146         }
0147     }
0148 
0149     return 1;
0150 }
0151 
0152 
0153 static void ffuart_init(int minor)
0154 {
0155 
0156 
0157     console_tbl *console_entry;
0158     ffuart_reg_t  *ffuart;
0159     unsigned int divisor;
0160 
0161     console_entry = BSP_get_uart_from_minor(minor);
0162 
0163 
0164 
0165     if (console_entry == NULL) {
0166         return;
0167     }
0168 
0169     ffuart = (ffuart_reg_t *)console_entry->ulCtrlPort1;
0170     ffuart->lcr |= DLAB;
0171     /*Set the Bound*/
0172     ffuart->lcr |= DLAB;
0173     divisor = FREQUENCY_UART / (115200*16);
0174     ffuart->rbr = divisor & 0xff;
0175     ffuart->ier = (divisor >> 8)&0xff;
0176     /*Disable FIFO*/
0177     ffuart->iir = 0;
0178     ffuart->lcr &=~DLAB;
0179     /*Enable UART*/
0180     ffuart->ier = 0x40;
0181     ffuart->lcr = EIGHT_BITS_NOPARITY_1STOPBIT;
0182 
0183 }
0184 
0185 /* I'm not sure this is needed for the shared console driver. */
0186 static void ffuart_write_polled(int minor, char c)
0187 {
0188     ffuart_write(minor, &c, 1);
0189 }
0190 
0191 /* This is for setting baud rate, bits, etc. */
0192 static int ffuart_set_attributes(int minor, const struct termios *t)
0193 {
0194     return 0;
0195 }
0196 
0197 /***********************************************************************/
0198 /*
0199  * The following functions are not used by TERMIOS, but other RTEMS
0200  * functions use them instead.
0201  */
0202 /***********************************************************************/
0203 /*
0204  * Read from UART. This is used in the exit code, and can't
0205  * rely on interrupts.
0206  */
0207 static int ffuart_poll_read(int minor)
0208 {
0209     return ffuart_read(minor);
0210 }
0211 
0212 
0213 /*
0214  * Write a character to the console. This is used by printk() and
0215  * maybe other low level functions. It should not use interrupts or any
0216  * RTEMS system calls. It needs to be very simple
0217  */
0218 static void _BSP_put_char( char c ) {
0219     ffuart_write_polled(0, c);
0220 }
0221 
0222 static int _BSP_poll_char(void) {
0223   return ffuart_poll_read(0);
0224 }
0225 
0226 BSP_output_char_function_type     BSP_output_char = _BSP_put_char;
0227 BSP_polling_getchar_function_type BSP_poll_char = _BSP_poll_char;