source: rtems/c/src/lib/libcpu/arm/at91rm9200/usart/usart.c @ c8bd3cd

4.115
Last change on this file since c8bd3cd was c8bd3cd, checked in by Sebastian Huber <sebastian.huber@…>, on 02/08/13 at 12:39:59

libchip/serial: Add const qualifier

  • Property mode set to 100644
File size: 6.1 KB
Line 
1/*
2 *  Driver for AT91RM9200 USART ports
3 *
4 * COPYRIGHT (c) 2006-2009.
5 * NCB - Sistemas Embarcados Ltda. (Brazil)
6 * Fernando Nicodemos <fgnicodemos@terra.com.br>
7 *
8 * and
9 *
10 * COPYRIGHT (c) 1989-2009.
11 * On-Line Applications Research Corporation (OAR).
12 *
13 *  The license and distribution terms for this file may be
14 *  found in the file LICENSE in this distribution or at
15 *  http://www.rtems.com/license/LICENSE.
16*/
17
18#include <bsp.h>
19#include <rtems/libio.h>
20#include <termios.h>
21
22#include <at91rm9200.h>
23#include <at91rm9200_usart.h>
24#include <at91rm9200_pmc.h>
25#include <rtems/bspIo.h>
26#include <libchip/serial.h>
27#include <libchip/sersupp.h>
28
29/* static function prototypes */
30static int     usart_first_open(int major, int minor, void *arg);
31static int     usart_last_close(int major, int minor, void *arg);
32static int     usart_read_polled(int minor);
33static ssize_t usart_write_polled_support(int minor, const char *buf, size_t len);
34static void    usart_init(int minor);
35static void    usart_write_polled(int minor, char c);
36static int     usart_set_attributes(int minor, const struct termios *t);
37at91rm9200_usart_regs_t *usart_get_base(int minor);
38
39/* Pointers to functions for handling the UART polled. */
40const console_fns usart_polling_fns = {
41  libchip_serial_default_probe,       /* deviceProbe */
42  usart_first_open,                   /* deviceFirstOpen */
43  usart_last_close,                   /* deviceLastClose */
44  usart_read_polled,                  /* deviceRead */
45  usart_write_polled_support,         /* deviceWrite */
46  usart_init,                         /* deviceInitialize */
47  usart_write_polled,                 /* deviceWritePolled */
48  usart_set_attributes,               /* deviceSetAttributes */
49  FALSE                 /* TRUE if interrupt driven, FALSE if not. */
50};
51
52at91rm9200_usart_regs_t *usart_get_base(int minor)
53{
54  console_tbl *console_entry;
55  at91rm9200_usart_regs_t *port;
56
57  console_entry = BSP_get_uart_from_minor(minor);
58
59  if (console_entry == NULL)
60    return 0;
61
62  port = (at91rm9200_usart_regs_t *) console_entry->ulCtrlPort1;
63  //printk( "minor=%d entry=%p port=%p\n", minor, console_entry, port );
64
65  return port;
66}
67
68/*
69 * Functions called via callbacks (i.e. the ones in uart_fns
70 */
71
72/*
73 * This is called the first time each device is opened. Since
74 * the driver is polled, we don't have to do anything. If the driver
75 * were interrupt driven, we'd enable interrupts here.
76 */
77static int usart_first_open(int major, int minor, void *arg)
78{
79  at91rm9200_usart_regs_t *usart;
80
81  usart = usart_get_base(minor);
82  if ( !usart )
83    return -1;
84
85  /* XXX port isn't being initialized or enabled */
86
87  /* XXX I hope this is enough */
88  usart->cr = (US_CR_RXEN | US_CR_TXEN);
89  return 0;
90}
91
92/*
93 * This is called the last time each device is closed.  Since
94 * the driver is polled, we don't have to do anything. If the driver
95 * were interrupt driven, we'd disable interrupts here.
96 */
97static int usart_last_close(int major, int minor, void *arg)
98{
99  at91rm9200_usart_regs_t *usart;
100
101  usart = usart_get_base(minor);
102  if ( !usart )
103    return -1;
104
105  return 0;
106}
107
108/*
109 * Read one character from UART.
110 *
111 * return -1 if there's no data, otherwise return
112 * the character in lowest 8 bits of returned int.
113 */
114static int usart_read_polled(int minor)
115{
116  at91rm9200_usart_regs_t *usart;
117
118  usart = usart_get_base(minor);
119  if ( !usart )
120    return -1;
121
122  /* if nothing ready return -1 */
123  if ( (usart->sr & US_IER_RXRDY) == 0 )
124    return -1;
125
126  return usart->rhr;
127}
128
129
130/*
131 *  Write character out
132 */
133static void usart_write_polled(int minor, char c)
134{
135  at91rm9200_usart_regs_t *usart;
136
137  usart = usart_get_base(minor);
138  if ( !usart )
139    return;
140
141  /* delay until TX empty */
142  while ( (usart->sr & US_IER_TXEMPTY) == 0 )
143    ;
144
145  usart->thr = c;
146}
147
148/*
149 * Write buffer to UART
150 *
151 * return 1 on success, -1 on error
152 */
153static ssize_t usart_write_polled_support(int minor, const char *buf, size_t len)
154{
155  at91rm9200_usart_regs_t *usart;
156  int nwrite=0;
157
158  /*
159   *  Verify the minor number
160   */
161  usart = usart_get_base(minor);
162  if ( !usart )
163    return -1;
164
165  /*
166   * poll each byte in the string out of the port.
167   */
168  while (nwrite < len) {
169    usart_write_polled(minor, *buf++);
170    nwrite++;
171  }
172
173  /*
174   * return the number of bytes written.
175   */
176  return nwrite;
177
178  return 1;
179}
180
181
182/* Set up the UART. */
183static void usart_init(int minor)
184{
185  at91rm9200_usart_regs_t *usart;
186
187  usart = usart_get_base(minor);
188  if ( !usart )
189    return;
190
191}
192
193
194/* This is for setting baud rate, bits, etc. */
195static int usart_set_attributes(int minor, const struct termios *t)
196{
197  uint32_t      brgr;
198  uint32_t      mode, baud, baud_requested;
199  at91rm9200_usart_regs_t *usart;
200
201  usart = usart_get_base(minor);
202  if ( !usart )
203    return -1;
204
205  /* Get current mode register */
206  mode = usart->mr & ~(US_MR_USMODE | US_MR_USCLKS | US_MR_CHRL
207                        | US_MR_PAR | US_MR_NBSTOP);
208
209  /* Byte size */
210  switch (t->c_cflag & CSIZE){
211  case CS5:
212    mode |= US_MR_CHRL_5;
213    break;
214  case CS6:
215    mode |= US_MR_CHRL_6;
216    break;
217  case CS7:
218    mode |= US_MR_CHRL_7;
219    break;
220  default:
221    mode |= US_MR_CHRL_8;
222    break;
223  }
224
225  /* Stop bits */
226  if (t->c_cflag & CSTOPB){
227        mode |= US_MR_NBSTOP_2; /* 2 stop bits */
228  } else
229    mode |= US_MR_NBSTOP_1;     /* 1 stop bits */
230
231  /* Parity */
232  if (t->c_cflag & PARENB){
233      /* Mark or Space parity */
234      if (t->c_cflag & PARODD){
235        mode |= US_MR_PAR_ODD;
236      } else
237        mode |= US_MR_PAR_EVEN;
238   } else
239        mode |= US_MR_PAR_NONE;
240
241  baud_requested = t->c_cflag & CBAUD;
242
243  /* If not, set the dbgu console baud as USART baud default */
244  if (!baud_requested)
245    baud_requested = BSP_get_baud();
246
247  baud = rtems_termios_baud_to_number(baud_requested);
248
249  brgr = (at91rm9200_get_mck() / 16) / baud;
250
251        if (brgr > 65535){    /* BRGR is 16-bit, so switch to slower clock */
252                brgr /= 8;
253                mode |= US_MR_USCLKS_MCK_DIV8;
254        }
255
256  usart->mr = mode;
257  usart->brgr = brgr;
258  return 0;
259}
260
261/*
262 * The following functions are not used by TERMIOS, but other RTEMS
263 * functions use them instead.
264 */
265
266/*
267 * Read from UART. This is used in the exit code, and can't
268 * rely on interrupts.
269 */
270int usart_poll_read(int minor)
271{
272  return usart_read_polled(minor);
273}
Note: See TracBrowser for help on using the repository browser.