source: rtems/c/src/lib/libbsp/m68k/gen68360/console/console.c @ 4106f7f

4.104.114.84.95
Last change on this file since 4106f7f was 4106f7f, checked in by Joel Sherrill <joel.sherrill@…>, on Oct 23, 1997 at 6:47:43 PM

Update from Eric Norum.

  • Property mode set to 100644
File size: 6.0 KB
Line 
1/*
2 *  SMC1 raw console serial I/O.
3 *
4 *  This driver is an example of `POLLING' or `INTERRUPT' input.
5 *
6 *  To compile with interrupt-driven input, define M360_SMC1_INTERRUPT
7 *  in the make customization file for this bsp (gen68360.cfg).
8 *
9 *  Author:
10 *    W. Eric Norum
11 *    Saskatchewan Accelerator Laboratory
12 *    University of Saskatchewan
13 *    Saskatoon, Saskatchewan, CANADA
14 *    eric@skatter.usask.ca
15 *
16 *  COPYRIGHT (c) 1989-1997.
17 *  On-Line Applications Research Corporation (OAR).
18 *  Copyright assigned to U.S. Government, 1994.
19 *
20 *  The license and distribution terms for this file may be
21 *  found in the file LICENSE in this distribution or at
22 *
23 *  http://www.OARcorp.com/rtems/license.html.
24 *
25 *  $Id$
26 */
27
28#include <termios.h>
29#include <bsp.h>
30#include <rtems/libio.h>
31#include "m68360.h"
32
33#if (defined (M360_SMC1_INTERRUPT))
34# define RXBUFSIZE      16
35static void *smc1ttyp;
36#else
37# define RXBUFSIZE      1
38#endif
39
40/*
41 * I/O buffers and pointers to buffer descriptors
42 */
43static volatile char rxBuf[RXBUFSIZE], txBuf;
44static volatile m360BufferDescriptor_t *smcRxBd, *smcTxBd;
45
46/*
47 * Device-specific routines
48 */
49#if (defined (M360_SMC1_INTERRUPT))
50static rtems_isr
51smc1InterruptHandler (rtems_vector_number v)
52{
53        /*
54         * Buffer received?
55         */
56        if (m360.smc1.smce & 0x1) {
57                m360.smc1.smce = 0x1;
58                while ((smcRxBd->status & M360_BD_EMPTY) == 0) {
59                        rtems_termios_enqueue_raw_characters (smc1ttyp,
60                                                        (char *)smcRxBd->buffer,
61                                                        smcRxBd->length);
62                        smcRxBd->status = M360_BD_EMPTY | M360_BD_WRAP | M360_BD_INTERRUPT;
63                }
64        }
65        m360.cisr = 1UL << 4;   /* Clear SMC1 interrupt-in-service bit */
66}
67
68#endif
69
70static void
71smc1Initialize (void)
72{
73        /*
74         * Allocate buffer descriptors
75         */
76        smcRxBd = M360AllocateBufferDescriptors (1);
77        smcTxBd = M360AllocateBufferDescriptors (1);
78
79        /*
80         * Configure port B pins to enable SMTXD1 and SMRXD1 pins
81         */
82        m360.pbpar |=  0xC0;
83        m360.pbdir &= ~0xC0;
84        m360.pbodr &= ~0xC0;
85
86        /*
87         * Set up BRG1 (9,600 baud)
88         */
89        m360.brgc1 = M360_BRG_RST;
90        m360.brgc1 = M360_BRG_EN | M360_BRG_EXTC_BRGCLK | M360_BRG_9600;
91
92        /*
93         * Put SMC1 in NMSI mode, connect SMC1 to BRG1
94         */
95        m360.simode |= M360_SI_SMC1_BRG1;
96         
97        /*
98         * Set up SMC1 parameter RAM common to all protocols
99         */
100        m360.smc1p.rbase = (char *)smcRxBd - (char *)&m360;
101        m360.smc1p.tbase = (char *)smcTxBd - (char *)&m360;
102        m360.smc1p.rfcr = M360_RFCR_MOT | M360_RFCR_DMA_SPACE;
103        m360.smc1p.tfcr = M360_TFCR_MOT | M360_TFCR_DMA_SPACE;
104        m360.smc1p.mrblr = RXBUFSIZE;
105         
106        /*
107         * Set up SMC1 parameter RAM UART-specific parameters
108         */
109        m360.smc1p.un.uart.max_idl = 10;
110        m360.smc1p.un.uart.brklen = 0;
111        m360.smc1p.un.uart.brkec = 0;
112        m360.smc1p.un.uart.brkcr = 0;
113         
114        /*
115         * Set up the Receive Buffer Descriptor
116         */
117        smcRxBd->status = M360_BD_EMPTY | M360_BD_WRAP | M360_BD_INTERRUPT;
118        smcRxBd->length = 0;
119        smcRxBd->buffer = rxBuf;
120         
121        /*
122         * Setup the Transmit Buffer Descriptor
123         */
124        smcTxBd->status = M360_BD_WRAP;
125        smcTxBd->length = 1;
126        smcTxBd->buffer = &txBuf;
127         
128        /*
129         * Set up SMC1 general and protocol-specific mode registers
130         */
131        m360.smc1.smce = ~0;    /* Clear any pending events */
132        m360.smc1.smcm = 0;     /* Mask all interrupt/event sources */
133        m360.smc1.smcmr = M360_SMCMR_CLEN(9) | M360_SMCMR_SM_UART;
134
135        /*
136         * Send "Init parameters" command
137         */
138        M360ExecuteRISC (M360_CR_OP_INIT_RX_TX | M360_CR_CHAN_SMC1);
139
140        /*
141         * Enable receiver and transmitter
142         */
143        m360.smc1.smcmr |= M360_SMCMR_TEN | M360_SMCMR_REN;
144
145#if (defined (M360_SMC1_INTERRUPT))
146        {
147        rtems_isr_entry old_handler;
148        rtems_status_code sc;
149
150        sc = rtems_interrupt_catch (smc1InterruptHandler,
151                                                (m360.cicr & 0xE0) | 0x04,
152                                                &old_handler);
153        m360.smc1.smcm = 1;     /* Enable SMC1 receiver interrupt */
154        m360.cimr |= 1UL << 4;  /* Enable SMC1 interrupts */
155        }
156#endif
157}
158
159static int
160smc1Read (int minor)
161{
162        unsigned char c;
163
164        if (smcRxBd->status & M360_BD_EMPTY)
165                return -1;
166        c = rxBuf[0];
167        smcRxBd->status = M360_BD_EMPTY | M360_BD_WRAP;
168        return c;
169}
170
171static int
172smc1Write (int minor, char *buf, int len)
173{
174        int nwrite = 0;
175
176        while (nwrite < len) {
177                while (smcTxBd->status & M360_BD_READY)
178                        continue;
179                txBuf = *buf++;
180                smcTxBd->status = M360_BD_READY | M360_BD_WRAP;
181                nwrite++;
182        }
183        return nwrite;
184}
185
186/*
187 ***************
188 * BOILERPLATE *
189 ***************
190 */
191
192/*
193 * Initialize and register the device
194 */
195rtems_device_driver console_initialize(
196  rtems_device_major_number  major,
197  rtems_device_minor_number  minor,
198  void                      *arg
199)
200{
201        rtems_status_code status;
202
203        /*
204         * Set up TERMIOS
205         */
206        rtems_termios_initialize ();
207
208        /*
209         * Do device-specific initialization
210         */
211        smc1Initialize ();
212
213        /*
214         * Register the device
215         */
216        status = rtems_io_register_name ("/dev/console", major, 0);
217        if (status != RTEMS_SUCCESSFUL)
218                rtems_fatal_error_occurred (status);
219        return RTEMS_SUCCESSFUL;
220}
221
222/*
223 * Open the device
224 */
225rtems_device_driver console_open(
226  rtems_device_major_number major,
227  rtems_device_minor_number minor,
228  void                    * arg
229)
230{
231        rtems_status_code sc;
232
233#if (defined (M360_SMC1_INTERRUPT))
234        rtems_libio_open_close_args_t *args = arg;
235
236        sc = rtems_termios_open (major, minor, arg,
237                        NULL,
238                        NULL,
239                        NULL,
240                        smc1Write);
241        smc1ttyp = args->iop->data1;
242#else
243        sc = rtems_termios_open (major, minor, arg,
244                        NULL,
245                        NULL,
246                        smc1Read,
247                        smc1Write);
248#endif
249        return sc;
250}
251 
252/*
253 * Close the device
254 */
255rtems_device_driver console_close(
256  rtems_device_major_number major,
257  rtems_device_minor_number minor,
258  void                    * arg
259)
260{
261        return rtems_termios_close (arg);
262}
263
264/*
265 * Read from the device
266 */
267rtems_device_driver console_read(
268  rtems_device_major_number major,
269  rtems_device_minor_number minor,
270  void                    * arg
271)
272{
273        return rtems_termios_read (arg);
274}
275
276/*
277 * Write to the device
278 */
279rtems_device_driver console_write(
280  rtems_device_major_number major,
281  rtems_device_minor_number minor,
282  void                    * arg
283)
284{
285        return rtems_termios_write (arg);
286}
287
288/*
289 * Handle ioctl request.
290 * Should set hardware line speed, bits/char, etc.
291 */
292rtems_device_driver console_control(
293  rtems_device_major_number major,
294  rtems_device_minor_number minor,
295  void                    * arg
296)
297{ 
298        return rtems_termios_ioctl (arg);
299}
Note: See TracBrowser for help on using the repository browser.