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

4.104.114.84.95
Last change on this file since d2632274 was d24ceb3, checked in by Joel Sherrill <joel.sherrill@…>, on 11/15/97 at 18:15:36

interrupt driven change from Eric Norum

  • Property mode set to 100644
File size: 6.8 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];
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
66        /*
67         * Buffer transmitted?
68         */
69        if (m360.smc1.smce & 0x2) {
70                m360.smc1.smce = 0x2;
71                if ((smcTxBd->status & M360_BD_READY) == 0)
72                        rtems_termios_dequeue_characters (smc1ttyp, smcTxBd->length);
73        }
74        m360.cisr = 1UL << 4;   /* Clear SMC1 interrupt-in-service bit */
75}
76
77#endif
78
79static void
80smc1Initialize (void)
81{
82        /*
83         * Allocate buffer descriptors
84         */
85        smcRxBd = M360AllocateBufferDescriptors (1);
86        smcTxBd = M360AllocateBufferDescriptors (1);
87
88        /*
89         * Configure port B pins to enable SMTXD1 and SMRXD1 pins
90         */
91        m360.pbpar |=  0xC0;
92        m360.pbdir &= ~0xC0;
93        m360.pbodr &= ~0xC0;
94
95        /*
96         * Set up BRG1 (9,600 baud)
97         */
98        m360.brgc1 = M360_BRG_RST;
99        m360.brgc1 = M360_BRG_EN | M360_BRG_EXTC_BRGCLK | M360_BRG_9600;
100
101        /*
102         * Put SMC1 in NMSI mode, connect SMC1 to BRG1
103         */
104        m360.simode |= M360_SI_SMC1_BRG1;
105         
106        /*
107         * Set up SMC1 parameter RAM common to all protocols
108         */
109        m360.smc1p.rbase = (char *)smcRxBd - (char *)&m360;
110        m360.smc1p.tbase = (char *)smcTxBd - (char *)&m360;
111        m360.smc1p.rfcr = M360_RFCR_MOT | M360_RFCR_DMA_SPACE;
112        m360.smc1p.tfcr = M360_TFCR_MOT | M360_TFCR_DMA_SPACE;
113        m360.smc1p.mrblr = RXBUFSIZE;
114         
115        /*
116         * Set up SMC1 parameter RAM UART-specific parameters
117         */
118        m360.smc1p.un.uart.max_idl = 10;
119        m360.smc1p.un.uart.brklen = 0;
120        m360.smc1p.un.uart.brkec = 0;
121        m360.smc1p.un.uart.brkcr = 0;
122         
123        /*
124         * Set up the Receive Buffer Descriptor
125         */
126        smcRxBd->status = M360_BD_EMPTY | M360_BD_WRAP | M360_BD_INTERRUPT;
127        smcRxBd->length = 0;
128        smcRxBd->buffer = rxBuf;
129         
130        /*
131         * Setup the Transmit Buffer Descriptor
132         */
133        smcTxBd->status = M360_BD_WRAP;
134         
135        /*
136         * Set up SMC1 general and protocol-specific mode registers
137         */
138        m360.smc1.smce = ~0;    /* Clear any pending events */
139        m360.smc1.smcm = 0;     /* Mask all interrupt/event sources */
140        m360.smc1.smcmr = M360_SMCMR_CLEN(9) | M360_SMCMR_SM_UART;
141
142        /*
143         * Send "Init parameters" command
144         */
145        M360ExecuteRISC (M360_CR_OP_INIT_RX_TX | M360_CR_CHAN_SMC1);
146
147        /*
148         * Enable receiver and transmitter
149         */
150        m360.smc1.smcmr |= M360_SMCMR_TEN | M360_SMCMR_REN;
151
152#if (defined (M360_SMC1_INTERRUPT))
153        {
154        rtems_isr_entry old_handler;
155        rtems_status_code sc;
156
157        sc = rtems_interrupt_catch (smc1InterruptHandler,
158                                                (m360.cicr & 0xE0) | 0x04,
159                                                &old_handler);
160        m360.smc1.smcm = 3;     /* Enable SMC1 TX and RX interrupts */
161        m360.cimr |= 1UL << 4;  /* Enable SMC1 interrupts */
162        }
163#endif
164}
165
166static int
167smc1Read (int minor)
168{
169        unsigned char c;
170
171        if (smcRxBd->status & M360_BD_EMPTY)
172                return -1;
173        c = rxBuf[0];
174        smcRxBd->status = M360_BD_EMPTY | M360_BD_WRAP;
175        return c;
176}
177
178/*
179 * Device-dependent write routine
180 * Interrupt-driven devices:
181 *      Begin transmission of as many characters as possible (minimum is 1).
182 * Polling devices:
183 *      Transmit all characters.
184 */
185static int
186smc1Write (int minor, char *buf, int len)
187{
188#if (defined (M360_SMC1_INTERRUPT))
189        smcTxBd->buffer = buf;
190        smcTxBd->length = len;
191        smcTxBd->status = M360_BD_READY | M360_BD_WRAP | M360_BD_INTERRUPT;
192#else
193        while (len--) {
194                static char txBuf;
195                while (smcTxBd->status & M360_BD_READY)
196                        continue;
197                txBuf = *buf++;
198                smcTxBd->buffer = &txBuf;
199                smcTxBd->length = 1;
200                smcTxBd->status = M360_BD_READY | M360_BD_WRAP;
201        }
202#endif
203        return 0;
204}
205
206/*
207 ***************
208 * BOILERPLATE *
209 ***************
210 */
211
212/*
213 * Reserve resources consumed by this driver
214 */
215void console_reserve_resources(
216  rtems_configuration_table *configuration
217)
218{
219        rtems_termios_reserve_resources (configuration, 1);
220}
221
222/*
223 * Initialize and register the device
224 */
225rtems_device_driver console_initialize(
226  rtems_device_major_number  major,
227  rtems_device_minor_number  minor,
228  void                      *arg
229)
230{
231        rtems_status_code status;
232
233        /*
234         * Set up TERMIOS
235         */
236        rtems_termios_initialize ();
237
238        /*
239         * Do device-specific initialization
240         */
241        smc1Initialize ();
242
243        /*
244         * Register the device
245         */
246        status = rtems_io_register_name ("/dev/console", major, 0);
247        if (status != RTEMS_SUCCESSFUL)
248                rtems_fatal_error_occurred (status);
249        return RTEMS_SUCCESSFUL;
250}
251
252/*
253 * Open the device
254 */
255rtems_device_driver console_open(
256  rtems_device_major_number major,
257  rtems_device_minor_number minor,
258  void                    * arg
259)
260{
261        rtems_status_code sc;
262
263#if (defined (M360_SMC1_INTERRUPT))
264        rtems_libio_open_close_args_t *args = arg;
265
266        sc = rtems_termios_open (major, minor, arg,
267                        NULL,
268                        NULL,
269                        NULL,
270                        smc1Write,
271                        1);
272        smc1ttyp = args->iop->data1;
273#else
274        sc = rtems_termios_open (major, minor, arg,
275                        NULL,
276                        NULL,
277                        smc1Read,
278                        smc1Write,
279                        0);
280#endif
281        return sc;
282}
283 
284/*
285 * Close the device
286 */
287rtems_device_driver console_close(
288  rtems_device_major_number major,
289  rtems_device_minor_number minor,
290  void                    * arg
291)
292{
293        return rtems_termios_close (arg);
294}
295
296/*
297 * Read from the device
298 */
299rtems_device_driver console_read(
300  rtems_device_major_number major,
301  rtems_device_minor_number minor,
302  void                    * arg
303)
304{
305        return rtems_termios_read (arg);
306}
307
308/*
309 * Write to the device
310 */
311rtems_device_driver console_write(
312  rtems_device_major_number major,
313  rtems_device_minor_number minor,
314  void                    * arg
315)
316{
317        return rtems_termios_write (arg);
318}
319
320/*
321 * Handle ioctl request.
322 * Should set hardware line speed, bits/char, etc.
323 */
324rtems_device_driver console_control(
325  rtems_device_major_number major,
326  rtems_device_minor_number minor,
327  void                    * arg
328)
329{
330        return rtems_termios_ioctl (arg);
331}
Note: See TracBrowser for help on using the repository browser.