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

4.104.115
Last change on this file since 336d67a was 336d67a, checked in by Sebastian Huber <sebastian.huber@…>, on 04/30/10 at 14:24:03

2010-04-30 Sebastian Huber <sebastian.huber@…>

  • Makefile.am, preinstall.am: Added generic interrupt support modules.
  • include/bsp.h: Define BSP_FEATURE_IRQ_EXTENSION.
  • startup/bspstart.c, network/network.c: Interrupt support changes.
  • console/uart.c: Fixed warnings.
  • Property mode set to 100644
File size: 9.9 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 <rayx.cn@gmail.com>
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 ssize_t uart_write(int minor, const char *buf, size_t 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 ssize_t uart_write(int minor, const char *buf, size_t len)
184{
185    size_t 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
291static int _BSP_get_char(void)
292{
293  return uart_poll_read(0);
294}
295
296BSP_polling_getchar_function_type BSP_poll_char = _BSP_get_char;
297
298
299/****************************************************************************
300* init USART 0¡£8 bit, 1 Stop,No checkout, BPS115200
301****************************************************************************/
302void  UART0_Ini(void)
303{
304   long Fdiv;
305   int i;
306   PINSEL0 = 0x00000005;                    // I/O to UART0
307   U0LCR = 0x83;                            // DLAB = 1
308   Fdiv = (Fpclk >>4) / UART_BPS;  // configure BPS
309   U0DLM = Fdiv/256;
310   U0DLL = Fdiv%256;
311   U0LCR = 0x03;
312
313   for(i=0;i<10;i++){
314     U0THR = 67;                //send a C to see if is OK
315     while( (U0LSR&0x40)==0 );
316   }
317}
318
319
320/****************************************************************************
321*Send a Byte
322****************************************************************************/
323void  UART0_SendByte(char data)
324{
325    U0THR = data;
326
327    while( (U0LSR&0x40)==0 );
328}
329
330
331/****************************************************************************
332*Send a string
333****************************************************************************/
334void  UART0_SendStr(char const *str)
335{  while(1)
336   {  if( *str == '\0' ) break;
337      UART0_SendByte(*str++);       // Send the char
338   }
339}
Note: See TracBrowser for help on using the repository browser.