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

4.104.114.84.9
Last change on this file since 6f1247b was 6f1247b, checked in by Ralf Corsepius <ralf.corsepius@…>, on Apr 25, 2007 at 12:52:48 PM

Use current OAR license file URL.

  • Property mode set to 100644
File size: 10.4 KB
Line 
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.
10 *  Copyright (c) By ray
11 *
12 *  The license and distribution terms for this file may be
13 *  found in the file LICENSE in this distribution or at
14 *
15 *  http://www.rtems.com/license/LICENSE.
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 {
171        printk("Unknown console minor number: %d\n", minor);
172        return -1;
173    }
174
175}
176
177
178/*
179 * Write buffer to UART
180 *
181 * return 1 on success, -1 on error
182 */
183static int uart_write(int minor, const char *buf, int len)
184{
185    int i;
186
187    if (minor == 0) {
188        for (i = 0; i < len; i++) {
189            while(!(U0LSR & ULSR_THRE))         /* wait for TX buffer to empty*/
190                  continue;                                             /* also either WDOG() or swap()*/
191            U0THR = (char) buf[i];
192        }
193    } else if (minor == 1) {
194            for (i = 0; i < len; i++) {
195                while(!(U0LSR & ULSR_THRE))     /* wait for TX buffer to empty*/
196                      continue;                                         /* also either WDOG() or swap()*/
197                U0THR = (char) buf[i];
198            }
199        }else {
200        printk("Unknown console minor number: %d\n", minor);
201        return -1;
202    }
203   
204    return 1;
205}
206
207
208/* Set up the UART. */
209static void uart_init(int minor)
210{
211#if 0 //init will be done in bspstart.c
212        int baud=6;
213        int mode =0x03;
214        if(minor==0){
215                // set port pins for UART0
216                PINSEL0 =  (PINSEL0 & ~U0_PINMASK) | U0_PINSEL;
217
218                U0IER = 0x00;                         // disable all interrupts
219
220                // set the baudrate
221                U0LCR = 1<<7;             // select divisor latches
222                U0DLL = (uint8_t)baud;                // set for baud low byte
223                U0DLM = (uint8_t)(baud >> 8);         // set for baud high byte
224
225                // set the number of characters and other
226                // user specified operating parameters
227                U0LCR = (mode & ~ULCR_DLAB_ENABLE);
228                U0FCR = mode>>8; /*fifo mode*/
229               
230                // set port pins for UART1
231                PINSEL0 = (PINSEL0 & ~U1_PINMASK) | U1_PINSEL;
232               
233                U1IER = 0x00;                                             // disable all interrupts
234        }else if(minor==1){
235                // set the baudrate
236                U1LCR = ULCR_DLAB_ENABLE;                         // select divisor latches
237                U1DLL = (uint8_t)baud;                            // set for baud low byte
238                U1DLM = (uint8_t)(baud >> 8);             // set for baud high byte
239               
240                // set the number of characters and other
241                // user specified operating parameters
242                U1LCR = (mode & ~ULCR_DLAB_ENABLE);
243                U1FCR = mode>>8;/*fifo mode*/
244        }
245               
246#endif
247}
248
249/* I'm not sure this is needed for the shared console driver. */
250static void    uart_write_polled(int minor, char c)
251{
252    uart_write(minor, &c, 1);
253}
254
255/* This is for setting baud rate, bits, etc. */
256static int     uart_set_attributes(int minor, const struct termios *t) 
257{
258    return 0;
259}
260
261/***********************************************************************/
262/*
263 * The following functions are not used by TERMIOS, but other RTEMS
264 * functions use them instead.
265 */
266/***********************************************************************/
267/*
268 * Read from UART. This is used in the exit code, and can't
269 * rely on interrupts.
270*/
271int uart_poll_read(int minor)
272{
273    return uart_read(minor);
274}
275
276
277/*
278 * Write a character to the console. This is used by printk() and
279 * maybe other low level functions. It should not use interrupts or any
280 * RTEMS system calls. It needs to be very simple
281 */
282static void _BSP_put_char( char c ) {
283    uart_write_polled(0, c);
284    if (c == '\n') {
285        uart_write_polled(0, '\r');
286    }
287}
288
289BSP_output_char_function_type BSP_output_char = _BSP_put_char;
290
291
292
293
294/****************************************************************************
295* init USART 0¡£8 bit, 1 Stop,No checkout, BPS115200
296****************************************************************************/
297void  UART0_Ini(void)
298{ 
299   long Fdiv;
300   int i;
301   PINSEL0 = 0x00000005;                    // I/O to UART0
302   U0LCR = 0x83;                            // DLAB = 1
303   Fdiv = (Fpclk >>4) / UART_BPS;  // configure BPS
304   U0DLM = Fdiv/256;                                                   
305   U0DLL = Fdiv%256;                                           
306   U0LCR = 0x03;
307
308   for(i=0;i<10;i++){
309     U0THR = 67;                //send a C to see if is OK
310     while( (U0LSR&0x40)==0 );
311   } 
312}
313                               
314
315/****************************************************************************
316*Send a Byte
317****************************************************************************/
318void  UART0_SendByte(char data)
319{ 
320    U0THR = data;       
321
322    while( (U0LSR&0x40)==0 );
323}
324
325
326/****************************************************************************
327*Send a string
328****************************************************************************/
329void  UART0_SendStr(char const *str)
330{  while(1)
331   {  if( *str == '\0' ) break;
332      UART0_SendByte(*str++);       // Send the char
333   }
334}
335
336debug_printk(char *dg_str)
337{
338  UART0_SendStr(dg_str);
339  UART0_SendStr("\r\n");
340}
341
342void printi(unsigned long value)
343{
344  static char istring[9]={0,0,0,0,0,0,0,0,0};
345  static char tmp[9]={0,0,0,0,0,0,0,0,0};
346  char *sp;
347  char *tp = tmp;
348
349  long i;
350  unsigned long v = value;
351  int index;
352
353  for(index=0;index<9;index++)
354        istring[index]=tmp[index]=0x0;
355
356  while (v || tp == tmp)
357  {
358    i = v % 16;
359    v = v / 16;
360    if (i < 10)
361      *tp++ = i+'0';
362    else
363      *tp++ = i + 'a' - 10;
364  }
365
366  sp = istring;
367  while (tp > tmp)
368    *sp++ = *--tp;
369
370  tp=tmp;
371  sp=istring;
372  debug_printk(istring);
373
374}
Note: See TracBrowser for help on using the repository browser.