source: rtems/c/src/lib/libbsp/arm/gp32/console/uart.c @ 1c0663b4

4.115
Last change on this file since 1c0663b4 was c499856, checked in by Chris Johns <chrisj@…>, on 03/20/14 at 21:10:47

Change all references of rtems.com to rtems.org.

  • Property mode set to 100644
File size: 6.5 KB
Line 
1/*
2 *  console driver for S3C2400 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 *
11 *  Copyright (c) 2004 Cogent Computer Systems
12 *  Written by Jay Monkman <jtm@lopingdog.com>
13 *
14 *  The license and distribution terms for this file may be
15 *  found in the file LICENSE in this distribution or at
16 *  http://www.rtems.org/license/LICENSE.
17*/
18#include <bsp.h>                /* Must be before libio.h */
19#include <rtems/libio.h>
20#include <termios.h>
21#include <rtems/bspIo.h>
22
23/* Put the CPU (or UART) specific header file #include here */
24#include <s3c24xx.h>
25#include <libchip/serial.h>
26#include <libchip/sersupp.h>
27
28/* How many serial ports? */
29#define NUM_DEVS       1
30
31int     uart_poll_read(int minor);
32
33int dbg_dly;
34
35/* static function prototypes */
36static int     uart_first_open(int major, int minor, void *arg);
37static int     uart_last_close(int major, int minor, void *arg);
38static int     uart_read(int minor);
39static ssize_t uart_write(int minor, const char *buf, size_t len);
40static void    uart_init(int minor);
41static void    uart_write_polled(int minor, char c);
42static int     uart_set_attributes(int minor, const struct termios *t);
43
44/* These are used by code in console.c */
45unsigned long Console_Configuration_Count = NUM_DEVS;
46
47/* Pointers to functions for handling the UART. */
48const console_fns uart_fns =
49{
50    libchip_serial_default_probe,
51    uart_first_open,
52    uart_last_close,
53    uart_read,
54    uart_write,
55    uart_init,
56    uart_write_polled,   /* not used in this driver */
57    uart_set_attributes,
58    FALSE      /* TRUE if interrupt driven, FALSE if not. */
59};
60
61/*
62 * There's one item in array for each UART.
63 *
64 * Some of these fields are marked "NOT USED". They are not used
65 * by console.c, but may be used by drivers in libchip
66 *
67 */
68console_tbl Console_Configuration_Ports[] = {
69    {
70        "/dev/com0",                      /* sDeviceName */
71        SERIAL_CUSTOM,                    /* deviceType */
72        &uart_fns,                        /* pDeviceFns */
73        NULL,                             /* deviceProbe */
74        NULL,                             /* pDeviceFlow */
75        0,                                /* ulMargin - NOT USED */
76        0,                                /* ulHysteresis - NOT USED */
77        NULL,                             /* pDeviceParams */
78        0,                                /* ulCtrlPort1  - NOT USED */
79        0,                                /* ulCtrlPort2  - NOT USED */
80        0,                                /* ulDataPort  - NOT USED */
81        NULL,                             /* getRegister - NOT USED */
82        NULL,                             /* setRegister - NOT USED */
83        NULL,                             /* getData - NOT USED */
84        NULL,                             /* setData - NOT USED */
85        0,                                /* ulClock - NOT USED */
86        0                                 /* ulIntVector - NOT USED */
87    }
88};
89
90/*********************************************************************/
91/* Functions called via termios callbacks (i.e. the ones in uart_fns */
92/*********************************************************************/
93
94/*
95 * This is called the first time each device is opened. If the driver
96 * is interrupt driven, you should enable interrupts here. Otherwise,
97 * it's probably safe to do nothing.
98 *
99 * Since micromonitor already set up the UART, we do nothing.
100 */
101static int uart_first_open(int major, int minor, void *arg)
102{
103    return 0;
104}
105
106
107/*
108 * This is called the last time each device is closed. If the driver
109 * is interrupt driven, you should disable interrupts here. Otherwise,
110 * it's probably safe to do nothing.
111 */
112static int uart_last_close(int major, int minor, void *arg)
113{
114    return 0;
115}
116
117
118/*
119 * Read one character from UART.
120 *
121 * Return -1 if there's no data, otherwise return
122 * the character in lowest 8 bits of returned int.
123 */
124static int uart_read(int minor)
125{
126    char c;
127
128    if (minor == 0) {
129        if (rUTRSTAT0 & 0x1) {
130            c = rURXH0 & 0xff;
131            return c;
132        } else {
133            return -1;
134        }
135    } else {
136        printk("Unknown console minor number: %d\n", minor);
137        return -1;
138    }
139
140}
141
142
143/*
144 * Write buffer to UART
145 *
146 * return 1 on success, -1 on error
147 */
148static ssize_t uart_write(int minor, const char *buf, size_t len)
149{
150    int i;
151
152    if (minor == 0) {
153        for (i = 0; i < len; i++) {
154            /* Wait for fifo to have room */
155            while(!(rUTRSTAT0 & 0x2)) {
156                continue;
157            }
158
159           rUTXH0 = (char) buf[i];
160        }
161    } else {
162        printk("Unknown console minor number: %d\n", minor);
163        return -1;
164    }
165
166    return 1;
167}
168
169
170/* Set up the UART. */
171static void uart_init(int minor)
172{
173        int i;
174        unsigned int reg = 0;
175
176        /* enable UART0 */
177        rCLKCON|=0x100;
178
179        /* value is calculated so : (int)(PCLK/16./baudrate) -1 */
180        reg = get_PCLK() / (16 * 115200) - 1;
181
182        /* FIFO enable, Tx/Rx FIFO clear */
183        rUFCON0 = 0x07;
184        rUMCON0 = 0x0;
185        /* Normal,No parity,1 stop,8 bit */
186        rULCON0 = 0x3;
187        /*
188         * tx=level,rx=edge,disable timeout int.,enable rx error int.,
189         * normal,interrupt or polling
190         */
191        rUCON0 = 0x245;
192        rUBRDIV0 = reg;
193
194        for (i = 0; i < 100; i++);
195
196}
197
198/* I'm not sure this is needed for the shared console driver. */
199static void    uart_write_polled(int minor, char c)
200{
201    uart_write(minor, &c, 1);
202}
203
204/* This is for setting baud rate, bits, etc. */
205static int     uart_set_attributes(int minor, const struct termios *t)
206{
207    return 0;
208}
209
210/***********************************************************************/
211/*
212 * The following functions are not used by TERMIOS, but other RTEMS
213 * functions use them instead.
214 */
215/***********************************************************************/
216/*
217 * Read from UART. This is used in the exit code, and can't
218 * rely on interrupts.
219*/
220int uart_poll_read(int minor)
221{
222    return uart_read(minor);
223}
224
225
226/*
227 * Write a character to the console. This is used by printk() and
228 * maybe other low level functions. It should not use interrupts or any
229 * RTEMS system calls. It needs to be very simple
230 */
231static void _BSP_put_char( char c ) {
232    uart_write_polled(0, c);
233    if (c == '\n') {
234        uart_write_polled(0, '\r');
235    }
236}
237
238BSP_output_char_function_type BSP_output_char = _BSP_put_char;
239
240static int _BSP_get_char(void)
241{
242  return uart_poll_read(0);
243}
244
245BSP_polling_getchar_function_type BSP_poll_char = _BSP_get_char;
Note: See TracBrowser for help on using the repository browser.