source: rtems/c/src/lib/libbsp/arm/rtl22xx/console/uart.c @ e890774

4.104.114.84.95
Last change on this file since e890774 was e890774, checked in by Joel Sherrill <joel.sherrill@…>, on 05/01/07 at 19:15:38

2007-05-01 Ray Xu <xr@…>

  • README, times, console/lpc22xx_uart.h, console/uart.c, include/bsp.h, start/start.S, startup/bspstart.c, startup/exit.c, startup/linkcmds: Update BSP to address changes between 4.7 and CVS head as well as to address comments from Ralf and Joel.
  • Property mode set to 100644
File size: 10.4 KB
RevLine 
[f4392b88]1/*
2 *  console driver for RTL22xx UARTs
3 *
4 *  This driver uses the shared console driver in
5 *  ...../libbsp/shared/console.c
6 *
7 *  If you want the driver to be interrupt driven, you
8 *  need to write the ISR, and in the ISR insert the
9 *  chars into termios's queue.
[e890774]10 *  Copyright (c) By ray <rayx.cn@gmail.com>
[f4392b88]11 *
12 *  The license and distribution terms for this file may be
13 *  found in the file LICENSE in this distribution or at
14 *
[6f1247b]15 *  http://www.rtems.com/license/LICENSE.
[f4392b88]16 *
17 *
18*/
19#include <bsp.h>                /* Must be before libio.h */
20#include <rtems/libio.h>
21#include <termios.h>
22#include <rtems/bspIo.h>
23
24/* Put the CPU (or UART) specific header file #include here */
25#include <lpc22xx.h>
26#include "lpc22xx_uart.h"
27
28#include <libchip/serial.h>
29#include <libchip/sersupp.h>
30
31/* How many serial ports? */
32#define NUM_DEVS       1
33
34int     uart_poll_read(int minor);
35
36int dbg_dly;
37
38/* static function prototypes */
39static int     uart_first_open(int major, int minor, void *arg);
40static int     uart_last_close(int major, int minor, void *arg);
41static int     uart_read(int minor);
42static int     uart_write(int minor, const char *buf, int len);
43static void    uart_init(int minor);
44static void    uart_write_polled(int minor, char c);
45static int     uart_set_attributes(int minor, const struct termios *t);
46
47/* These are used by code in console.c */
48unsigned long Console_Port_Count = NUM_DEVS;
49console_data  Console_Port_Data[NUM_DEVS];
50
51/* rtems console uses the following minor number */
52rtems_device_minor_number  Console_Port_Minor = 0;
53
54/* Pointers to functions for handling the UART. */
55console_fns uart_fns =
56{
57    libchip_serial_default_probe,
58    uart_first_open,
59    uart_last_close,
60    uart_read,
61    uart_write,
62    uart_init,
63    uart_write_polled,   /* not used in this driver */
64    uart_set_attributes,
65    FALSE      /* TRUE if interrupt driven, FALSE if not. */
66};
67
68/*
69 * There's one item in array for each UART.
70 *
71 * Some of these fields are marked "NOT USED". They are not used
72 * by console.c, but may be used by drivers in libchip
73 *
74 */
75console_tbl Console_Port_Tbl[] = {
76    {
77        "/dev/console",                   /* sDeviceName */
78        SERIAL_CUSTOM,                    /* deviceType */
79        &uart_fns,                        /* pDeviceFns */
80        NULL,                             /* deviceProbe */
81        NULL,                             /* pDeviceFlow */
82        0,                                /* ulMargin - NOT USED */
83        0,                                /* ulHysteresis - NOT USED */
84        NULL,                             /* pDeviceParams */
85        0,                                /* ulCtrlPort1  - NOT USED */
86        0,                                /* ulCtrlPort2  - NOT USED */
87        0,                                /* ulDataPort  - NOT USED */
88        NULL,                             /* getRegister - NOT USED */
89        NULL,                             /* setRegister - NOT USED */
90        NULL,                             /* getData - NOT USED */
91        NULL,                             /* setData - NOT USED */
92        0,                                /* ulClock - NOT USED */
93        0                                 /* ulIntVector - NOT USED */
94    }
95    #if 0
96    {
97        "/dev/com1",                      /* sDeviceName */
98        SERIAL_CUSTOM,                    /* deviceType */
99        &uart_fns,                        /* pDeviceFns */
100        NULL,                             /* deviceProbe */
101        NULL,                             /* pDeviceFlow */
102        0,                                /* ulMargin - NOT USED */
103        0,                                /* ulHysteresis - NOT USED */
104        NULL,                             /* pDeviceParams */
105        0,                                /* ulCtrlPort1  - NOT USED */
106        0,                                /* ulCtrlPort2  - NOT USED */
107        0,                                /* ulDataPort  - NOT USED */
108        NULL,                             /* getRegister - NOT USED */
109        NULL,                             /* setRegister - NOT USED */
110        NULL,                             /* getData - NOT USED */
111        NULL,                             /* setData - NOT USED */
112        0,                                /* ulClock - NOT USED */
113        0                                 /* ulIntVector - NOT USED */
114    }
115    #endif
116};
117
118/*********************************************************************/
119/* Functions called via termios callbacks (i.e. the ones in uart_fns */
120/*********************************************************************/
121
122/*
123 * This is called the first time each device is opened. If the driver
124 * is interrupt driven, you should enable interrupts here. Otherwise,
125 * it's probably safe to do nothing.
126 *
127 * Since micromonitor already set up the UART, we do nothing.
128 */
129static int uart_first_open(int major, int minor, void *arg)
130{
131    return 0;
132}
133
134
135/*
136 * This is called the last time each device is closed. If the driver
137 * is interrupt driven, you should disable interrupts here. Otherwise,
138 * it's probably safe to do nothing.
139 */
140static int uart_last_close(int major, int minor, void *arg)
141{
142    return 0;
143}
144
145
146/*
147 * Read one character from UART.
148 *
149 * Return -1 if there's no data, otherwise return
150 * the character in lowest 8 bits of returned int.
151 */
152static int uart_read(int minor)
153{
154    char c;
155
156    if (minor == 0) {
157        if(U0LSR & ULSR_RDR) {
158            c = U0RBR;
159            return c;
160        } else {
161            return -1;
162        }
163    } else if (minor == 1) {
164        if (U1LSR & ULSR_RDR) {
165            c = U1RBR;
166            return c;
167        } else {
168            return -1;
169        }
170    } else {
[e890774]171        debug_printk("Unknown console minor number");
172        printi(minor);
[f4392b88]173        return -1;
174    }
175
176}
177
178
179/*
180 * Write buffer to UART
181 *
182 * return 1 on success, -1 on error
183 */
184static int uart_write(int minor, const char *buf, int len)
185{
186    int i;
187
188    if (minor == 0) {
189        for (i = 0; i < len; i++) {
190            while(!(U0LSR & ULSR_THRE))         /* wait for TX buffer to empty*/
191                  continue;                                             /* also either WDOG() or swap()*/
192            U0THR = (char) buf[i];
193        }
194    } else if (minor == 1) {
195            for (i = 0; i < len; i++) {
196                while(!(U0LSR & ULSR_THRE))     /* wait for TX buffer to empty*/
197                      continue;                                         /* also either WDOG() or swap()*/
198                U0THR = (char) buf[i];
199            }
200        }else {
[e890774]201        debug_printk("Unknown console minor number");
202        printi(minor);
[f4392b88]203        return -1;
204    }
205   
206    return 1;
207}
208
209
210/* Set up the UART. */
211static void uart_init(int minor)
212{
213#if 0 //init will be done in bspstart.c
214        int baud=6;
215        int mode =0x03;
216        if(minor==0){
217                // set port pins for UART0
218                PINSEL0 =  (PINSEL0 & ~U0_PINMASK) | U0_PINSEL;
219
220                U0IER = 0x00;                         // disable all interrupts
221
222                // set the baudrate
223                U0LCR = 1<<7;             // select divisor latches
224                U0DLL = (uint8_t)baud;                // set for baud low byte
225                U0DLM = (uint8_t)(baud >> 8);         // set for baud high byte
226
227                // set the number of characters and other
228                // user specified operating parameters
229                U0LCR = (mode & ~ULCR_DLAB_ENABLE);
230                U0FCR = mode>>8; /*fifo mode*/
231               
232                // set port pins for UART1
233                PINSEL0 = (PINSEL0 & ~U1_PINMASK) | U1_PINSEL;
234               
235                U1IER = 0x00;                                             // disable all interrupts
236        }else if(minor==1){
237                // set the baudrate
238                U1LCR = ULCR_DLAB_ENABLE;                         // select divisor latches
239                U1DLL = (uint8_t)baud;                            // set for baud low byte
240                U1DLM = (uint8_t)(baud >> 8);             // set for baud high byte
241               
242                // set the number of characters and other
243                // user specified operating parameters
244                U1LCR = (mode & ~ULCR_DLAB_ENABLE);
245                U1FCR = mode>>8;/*fifo mode*/
246        }
247               
248#endif
249}
250
251/* I'm not sure this is needed for the shared console driver. */
252static void    uart_write_polled(int minor, char c)
253{
254    uart_write(minor, &c, 1);
255}
256
257/* This is for setting baud rate, bits, etc. */
258static int     uart_set_attributes(int minor, const struct termios *t)
259{
260    return 0;
261}
262
263/***********************************************************************/
264/*
265 * The following functions are not used by TERMIOS, but other RTEMS
266 * functions use them instead.
267 */
268/***********************************************************************/
269/*
270 * Read from UART. This is used in the exit code, and can't
271 * rely on interrupts.
272*/
273int uart_poll_read(int minor)
274{
275    return uart_read(minor);
276}
277
278
279/*
280 * Write a character to the console. This is used by printk() and
281 * maybe other low level functions. It should not use interrupts or any
282 * RTEMS system calls. It needs to be very simple
283 */
284static void _BSP_put_char( char c ) {
285    uart_write_polled(0, c);
286    if (c == '\n') {
287        uart_write_polled(0, '\r');
288    }
289}
290
291BSP_output_char_function_type BSP_output_char = _BSP_put_char;
292
293
294
295
296/****************************************************************************
297* init USART 0¡£8 bit, 1 Stop,No checkout, BPS115200
298****************************************************************************/
299void  UART0_Ini(void)
300{
301   long Fdiv;
302   int i;
303   PINSEL0 = 0x00000005;                    // I/O to UART0
304   U0LCR = 0x83;                            // DLAB = 1
305   Fdiv = (Fpclk >>4) / UART_BPS;  // configure BPS
306   U0DLM = Fdiv/256;                                                   
307   U0DLL = Fdiv%256;                                           
308   U0LCR = 0x03;
309
310   for(i=0;i<10;i++){
311     U0THR = 67;                //send a C to see if is OK
312     while( (U0LSR&0x40)==0 );
313   } 
314}
315                               
316
317/****************************************************************************
318*Send a Byte
319****************************************************************************/
320void  UART0_SendByte(char data)
321
322    U0THR = data;       
323
324    while( (U0LSR&0x40)==0 );
325}
326
327
328/****************************************************************************
329*Send a string
330****************************************************************************/
331void  UART0_SendStr(char const *str)
332{  while(1)
333   {  if( *str == '\0' ) break;
334      UART0_SendByte(*str++);       // Send the char
335   }
336}
337
338debug_printk(char *dg_str)
339{
340  UART0_SendStr(dg_str);
341  UART0_SendStr("\r\n");
342}
343
344void printi(unsigned long value)
345{
346  static char istring[9]={0,0,0,0,0,0,0,0,0};
347  static char tmp[9]={0,0,0,0,0,0,0,0,0};
348  char *sp;
349  char *tp = tmp;
350
351  long i;
352  unsigned long v = value;
353  int index;
354
355  for(index=0;index<9;index++)
356        istring[index]=tmp[index]=0x0;
357
358  while (v || tp == tmp)
359  {
360    i = v % 16;
361    v = v / 16;
362    if (i < 10)
363      *tp++ = i+'0';
364    else
365      *tp++ = i + 'a' - 10;
366  }
367
368  sp = istring;
369  while (tp > tmp)
370    *sp++ = *--tp;
371
372  tp=tmp;
373  sp=istring;
374  debug_printk(istring);
375
376}
Note: See TracBrowser for help on using the repository browser.