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

4.104.114.84.95
Last change on this file since 96c73ab was 96c73ab, checked in by Joel Sherrill <joel.sherrill@…>, on 02/19/98 at 23:02:16

Patch from Eric Norum:

While trying to work through this problem I decided that the
build-time selection of the console I/O operation (polling or
interrupt) was too clumsy. Here's a patch that allows run-time
(actually init-time) selection of the console I/O mode.

It also shows the need for another flags' or options' field in
the rtems_driver_address_table structure...

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