Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:04

0001 /*
0002  *  console driver for RTL22xx UARTs
0003  *
0004  *  If you want the driver to be interrupt driven, you
0005  *  need to write the ISR, and in the ISR insert the
0006  *  chars into termios's queue.
0007  */
0008 
0009 /*
0010  *  Copyright (c) By ray <rayx.cn@gmail.com>
0011  *
0012  *  The license and distribution terms for this file may be
0013  *  found in the file LICENSE in this distribution or at
0014  *  http://www.rtems.org/license/LICENSE.
0015  */
0016 
0017 #include <bsp.h>                /* Must be before libio.h */
0018 #include <rtems/libio.h>
0019 #include <termios.h>
0020 #include <rtems/bspIo.h>
0021 
0022 /* Put the CPU (or UART) specific header file #include here */
0023 #include <lpc22xx.h>
0024 #include "lpc22xx_uart.h"
0025 
0026 #include <libchip/serial.h>
0027 #include <libchip/sersupp.h>
0028 
0029 /* How many serial ports? */
0030 #define NUM_DEVS       1
0031 
0032 int dbg_dly;
0033 
0034 /* static function prototypes */
0035 static int     uart_first_open(int major, int minor, void *arg);
0036 static int     uart_last_close(int major, int minor, void *arg);
0037 static int     uart_read(int minor);
0038 static ssize_t uart_write(int minor, const char *buf, size_t len);
0039 static void    uart_init(int minor);
0040 static void    uart_write_polled(int minor, char c);
0041 static int     uart_set_attributes(int minor, const struct termios *t);
0042 
0043 /* These are used by code in console.c */
0044 unsigned long Console_Configuration_Count = NUM_DEVS;
0045 
0046 /* Pointers to functions for handling the UART. */
0047 const console_fns uart_fns = {
0048   libchip_serial_default_probe,
0049   uart_first_open,
0050   uart_last_close,
0051   uart_read,
0052   uart_write,
0053   uart_init,
0054   uart_write_polled,   /* not used in this driver */
0055   uart_set_attributes,
0056   FALSE                /* TRUE if interrupt driven, FALSE if not. */
0057 };
0058 
0059 /*
0060  * There's one item in array for each UART.
0061  *
0062  * Some of these fields are marked "NOT USED". They are not used
0063  * by console.c, but may be used by drivers in libchip
0064  */
0065 console_tbl Console_Configuration_Ports[] = {
0066 {
0067     "/dev/com0",                      /* sDeviceName */
0068     SERIAL_CUSTOM,                    /* deviceType */
0069     &uart_fns,                        /* pDeviceFns */
0070     NULL,                             /* deviceProbe */
0071     NULL,                             /* pDeviceFlow */
0072     0,                                /* ulMargin - NOT USED */
0073     0,                                /* ulHysteresis - NOT USED */
0074     NULL,                             /* pDeviceParams */
0075     0,                                /* ulCtrlPort1  - NOT USED */
0076     0,                                /* ulCtrlPort2  - NOT USED */
0077     0,                                /* ulDataPort  - NOT USED */
0078     NULL,                             /* getRegister - NOT USED */
0079     NULL,                             /* setRegister - NOT USED */
0080     NULL,                             /* getData - NOT USED */
0081     NULL,                             /* setData - NOT USED */
0082     0,                                /* ulClock - NOT USED */
0083     0                                 /* ulIntVector - NOT USED */
0084 }
0085 #if 0
0086 {
0087     "/dev/com1",                      /* sDeviceName */
0088     SERIAL_CUSTOM,                    /* deviceType */
0089     &uart_fns,                        /* pDeviceFns */
0090     NULL,                             /* deviceProbe */
0091     NULL,                             /* pDeviceFlow */
0092     0,                                /* ulMargin - NOT USED */
0093     0,                                /* ulHysteresis - NOT USED */
0094     NULL,                             /* pDeviceParams */
0095     0,                                /* ulCtrlPort1  - NOT USED */
0096     0,                                /* ulCtrlPort2  - NOT USED */
0097     0,                                /* ulDataPort  - NOT USED */
0098     NULL,                             /* getRegister - NOT USED */
0099     NULL,                             /* setRegister - NOT USED */
0100     NULL,                             /* getData - NOT USED */
0101     NULL,                             /* setData - NOT USED */
0102     0,                                /* ulClock - NOT USED */
0103     0                                 /* ulIntVector - NOT USED */
0104 }
0105 #endif
0106 };
0107 
0108 /*
0109  * This is called the first time each device is opened. If the driver
0110  * is interrupt driven, you should enable interrupts here. Otherwise,
0111  * it's probably safe to do nothing.
0112  *
0113  * Since micromonitor already set up the UART, we do nothing.
0114  */
0115 static int uart_first_open(int major, int minor, void *arg)
0116 {
0117   return 0;
0118 }
0119 
0120 /*
0121  * This is called the last time each device is closed. If the driver
0122  * is interrupt driven, you should disable interrupts here. Otherwise,
0123  * it's probably safe to do nothing.
0124  */
0125 static int uart_last_close(int major, int minor, void *arg)
0126 {
0127   return 0;
0128 }
0129 
0130 /*
0131  * Read one character from UART.
0132  *
0133  * Return -1 if there's no data, otherwise return
0134  * the character in lowest 8 bits of returned int.
0135  */
0136 static int uart_read(int minor)
0137 {
0138   char c;
0139 
0140   switch (minor) {
0141     case 0:
0142       if (U0LSR & ULSR_RDR) {
0143         c = U0RBR;
0144         return c;
0145       }
0146       return -1;
0147     case 1:
0148       if (U1LSR & ULSR_RDR) {
0149         c = U1RBR;
0150         return c;
0151       }
0152       return -1;
0153     default:
0154       break;
0155   }
0156   printk("Unknown console minor number %d\n", minor);
0157   return -1;
0158 }
0159 
0160 /*
0161  * Write buffer to UART
0162  *
0163  * return 1 on success, -1 on error
0164  */
0165 static ssize_t uart_write(int minor, const char *buf, size_t len)
0166 {
0167   size_t i;
0168 
0169   switch (minor) {
0170     case 0:
0171       for (i = 0; i < len; i++) {
0172         while (!(U0LSR & ULSR_THRE))   /* wait for TX buffer to empty*/
0173           continue;                    /* also either WDOG() or swap()*/
0174         U0THR = (char) buf[i];
0175       }
0176       break;
0177     case 1:
0178       for (i = 0; i < len; i++) {
0179         while (!(U0LSR & ULSR_THRE))   /* wait for TX buffer to empty*/
0180           continue;                    /* also either WDOG() or swap()*/
0181         U0THR = (char) buf[i];
0182       }
0183       break;
0184     default:
0185       printk("Unknown console minor number %d\n", minor);
0186       return -1;
0187   }
0188 
0189   return len;
0190 }
0191 
0192 /* Set up the UART. */
0193 static void uart_init(int minor)
0194 {
0195 #if 0 //init will be done in bspstart.c
0196   int baud=6;
0197   int mode =0x03;
0198   if(minor==0){
0199     // set port pins for UART0
0200     PINSEL0 =  (PINSEL0 & ~U0_PINMASK) | U0_PINSEL;
0201 
0202     U0IER = 0x00;                         // disable all interrupts
0203 
0204     // set the baudrate
0205     U0LCR = 1<<7;             // select divisor latches
0206     U0DLL = (uint8_t)baud;                // set for baud low byte
0207     U0DLM = (uint8_t)(baud >> 8);         // set for baud high byte
0208 
0209     // set the number of characters and other
0210     // user specified operating parameters
0211     U0LCR = (mode & ~ULCR_DLAB_ENABLE);
0212     U0FCR = mode>>8; /*fifo mode*/
0213 
0214     // set port pins for UART1
0215     PINSEL0 = (PINSEL0 & ~U1_PINMASK) | U1_PINSEL;
0216 
0217     U1IER = 0x00;              // disable all interrupts
0218   }else if(minor==1){
0219     // set the baudrate
0220     U1LCR = ULCR_DLAB_ENABLE;        // select divisor latches
0221     U1DLL = (uint8_t)baud;          // set for baud low byte
0222     U1DLM = (uint8_t)(baud >> 8);      // set for baud high byte
0223 
0224     // set the number of characters and other
0225     // user specified operating parameters
0226     U1LCR = (mode & ~ULCR_DLAB_ENABLE);
0227     U1FCR = mode>>8;/*fifo mode*/
0228   }
0229 
0230 #endif
0231 }
0232 
0233 /* I'm not sure this is needed for the shared console driver. */
0234 static void uart_write_polled(int minor, char c)
0235 {
0236   uart_write(minor, &c, 1);
0237 }
0238 
0239 /* This is for setting baud rate, bits, etc. */
0240 static int uart_set_attributes(int minor, const struct termios *t)
0241 {
0242   return 0;
0243 }
0244 
0245 /*
0246  * Write a character to the console. This is used by printk() and
0247  * maybe other low level functions. It should not use interrupts or any
0248  * RTEMS system calls. It needs to be very simple
0249  */
0250 static void _BSP_put_char( char c )
0251 {
0252   uart_write_polled(0, c);
0253 }
0254 
0255 BSP_output_char_function_type BSP_output_char = _BSP_put_char;
0256 
0257 static int _BSP_get_char(void)
0258 {
0259   return uart_read(0);
0260 }
0261 
0262 BSP_polling_getchar_function_type BSP_poll_char = _BSP_get_char;
0263 
0264 /*
0265  * init USART 0: 8 bit, 1 Stop,No checkout, BPS115200
0266  */
0267 void UART0_Ini(void)
0268 {
0269   long Fdiv;
0270   int i;
0271 
0272   PINSEL0 = 0x00000005;        // I/O to UART0
0273   U0LCR = 0x83;                // DLAB = 1
0274   Fdiv = (Fpclk >>4) / UART_BPS;  // configure BPS
0275   U0DLM = Fdiv/256;
0276   U0DLL = Fdiv%256;
0277   U0LCR = 0x03;
0278 
0279   for(i=0;i<10;i++){
0280     U0THR = 67;    //send a C to see if is OK
0281     while ( (U0LSR&0x40)==0 );
0282   }
0283 }