Changeset 4106f7f in rtems


Ignore:
Timestamp:
Oct 23, 1997, 6:47:43 PM (23 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, 4.8, 4.9, 5, master
Children:
51961e4
Parents:
aa239a7
Message:

Update from Eric Norum.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/m68k/gen68360/console/console.c

    raa239a7 r4106f7f  
    11/*
    2  * Initialize SMC1 for console IO.
    3  *
    4  * Based on the `gen68302' board support package, and covered by the
    5  * original distribution terms.
    6  *
    7  * W. Eric Norum
    8  * Saskatchewan Accelerator Laboratory
    9  * University of Saskatchewan
    10  * Saskatoon, Saskatchewan, CANADA
    11  * eric@skatter.usask.ca
    12  *
    13  *  $Id$
    14  */
    15 
    16 /*
     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
    1715 *
    1816 *  COPYRIGHT (c) 1989-1997.
     
    2220 *  The license and distribution terms for this file may be
    2321 *  found in the file LICENSE in this distribution or at
     22 *
    2423 *  http://www.OARcorp.com/rtems/license.html.
    25  */
    26 
    27 #define GEN68360_INIT
    28 
     24 *
     25 *  $Id$
     26 */
     27
     28#include <termios.h>
    2929#include <bsp.h>
    3030#include <rtems/libio.h>
    3131#include "m68360.h"
    3232
    33 /*  console_initialize
    34  *
    35  *  This routine initializes the console IO driver.
    36  *
    37  *  Input parameters: NONE
    38  *
    39  *  Output parameters:  NONE
    40  *
    41  *  Return values:
    42  */
    43 
    44 /*
    45  * I/O buffers can be in ordindary RAM
    46  */
    47 static volatile char rxBuf, txBuf;
    48 static volatile m360BufferDescriptor_t *consoleRxBd, *consoleTxBd;
    49 
     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 */
    50195rtems_device_driver console_initialize(
    51196  rtems_device_major_number  major,
     
    57202
    58203        /*
    59          * Allocate buffer descriptors
    60          */
    61         consoleRxBd = M360AllocateBufferDescriptors (1);
    62         consoleTxBd = M360AllocateBufferDescriptors (1);
    63 
    64         /*
    65          * Configure port B pins to enable SMTXD1 and SMRXD1 pins
    66          */
    67         m360.pbpar |=  0xC0;
    68         m360.pbdir &= ~0xC0;
    69         m360.pbodr &= ~0xC0;
    70 
    71         /*
    72          * Set up BRG1 (9,600 baud)
    73          */
    74         m360.brgc1 = M360_BRG_RST;
    75         m360.brgc1 = M360_BRG_EN | M360_BRG_EXTC_BRGCLK | M360_BRG_9600;
    76 
    77         /*
    78          * Put SMC1 in NMSI mode, connect SMC1 to BRG1
    79          */
    80         m360.simode |= M360_SI_SMC1_BRG1;
    81          
    82         /*
    83          * Set up SMC1 parameter RAM common to all protocols
    84          */
    85         m360.smc1p.rbase = (char *)consoleRxBd - (char *)&m360;
    86         m360.smc1p.tbase = (char *)consoleTxBd - (char *)&m360;
    87         m360.smc1p.rfcr = M360_RFCR_MOT | M360_RFCR_DMA_SPACE;
    88         m360.smc1p.tfcr = M360_TFCR_MOT | M360_TFCR_DMA_SPACE;
    89         m360.smc1p.mrblr = 1;
    90          
    91         /*
    92          * Set up SMC1 parameter RAM UART-specific parameters
    93          */
    94         m360.smc1p.un.uart.max_idl = 0;
    95         m360.smc1p.un.uart.brklen = 0;
    96         m360.smc1p.un.uart.brkec = 0;
    97         m360.smc1p.un.uart.brkcr = 0;
    98          
    99         /*
    100          * Set up the Receive Buffer Descriptor
    101          */
    102         consoleRxBd->status = M360_BD_EMPTY | M360_BD_WRAP;
    103         consoleRxBd->length = 0;
    104         consoleRxBd->buffer = &rxBuf;
    105          
    106         /*
    107          * Setup the Transmit Buffer Descriptor
    108          */
    109         consoleTxBd->length = 1;
    110         consoleTxBd->status = M360_BD_WRAP;
    111         consoleTxBd->buffer = &txBuf;
    112          
    113         /*
    114          * Set up SMC1 general and protocol-specific mode registers
    115          */
    116         m360.smc1.smce = ~0;    /* Clear any pending events */
    117         m360.smc1.smcm = 0;     /* Mask all interrupt/event sources */
    118         m360.smc1.smcmr = M360_SMCMR_CLEN(9) | M360_SMCMR_SM_UART;
    119 
    120         /*
    121          * Send "Init parameters" command
    122          */
    123         M360ExecuteRISC (M360_CR_OP_INIT_RX_TX | M360_CR_CHAN_SMC1);
    124 
    125         /*
    126          * Enable receiver and transmitter
    127          */
    128         m360.smc1.smcmr |= M360_SMCMR_TEN | M360_SMCMR_REN;
    129 
    130         status = rtems_io_register_name(
    131                                 "/dev/console",
    132                                     major,
    133                                     (rtems_device_minor_number)0);
     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);
    134217        if (status != RTEMS_SUCCESSFUL)
    135                 rtems_fatal_error_occurred(status);
     218                rtems_fatal_error_occurred (status);
    136219        return RTEMS_SUCCESSFUL;
    137220}
    138221
    139 /*  is_character_ready
    140  *
    141  *  Check to see if a character is available on the console port.  If so,
    142  *  then return a TRUE (along with the character).  Otherwise return FALSE.
    143  *
    144  *  Input parameters:   pointer to location in which to return character
    145  *
    146  *  Output parameters:  character (if available)
    147  *
    148  *  Return values:      TRUE - character available
    149  *                      FALSE - no character available
    150  */
    151 
    152 rtems_boolean is_character_ready(
    153   char *ch                              /* -> character  */
    154 )
    155 {
    156         if (consoleRxBd->status & M360_BD_EMPTY)
    157                 return FALSE;
    158         *ch = rxBuf;
    159         consoleRxBd->status = M360_BD_EMPTY | M360_BD_WRAP;
    160         return TRUE;
    161 }
    162 
    163 
    164 /*  inbyte
    165  *
    166  *  Receive a character from the console port
    167  *
    168  *  Input parameters:   NONE
    169  *
    170  *  Output parameters:  NONE
    171  *
    172  *  Return values:      character read
    173  */
    174 
    175 char inbyte( void )
    176 {
    177     char ch;
    178 
    179     while (is_character_ready (&ch) == FALSE)
    180         continue;
    181     return ch;
    182 }
    183 
    184 
    185 /*  outbyte
    186  *
    187  *  Transmit a character to the console serial port
    188  *
    189  *  Input parameters:
    190  *    ch  - character to be transmitted
    191  *
    192  *  Output parameters:  NONE
    193  */
    194 
    195 void outbyte(
    196   char ch
    197 )
    198 {
    199         if (ch == '\n')
    200                 outbyte('\r');
    201         while (consoleTxBd->status & M360_BD_READY)
    202                 continue;
    203         txBuf = ch;
    204         consoleTxBd->status = M360_BD_READY | M360_BD_WRAP;
    205 }
    206 
    207 /*
    208  *  Open entry point
    209  */
    210 
     222/*
     223 * Open the device
     224 */
    211225rtems_device_driver console_open(
    212226  rtems_device_major_number major,
     
    215229)
    216230{
    217   return RTEMS_SUCCESSFUL;
     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;
    218250}
    219251 
    220252/*
    221  *  Close entry point
    222  */
    223 
     253 * Close the device
     254 */
    224255rtems_device_driver console_close(
    225256  rtems_device_major_number major,
     
    228259)
    229260{
    230   return RTEMS_SUCCESSFUL;
    231 }
    232 
    233 /*
    234  * read bytes from the serial port. We only have stdin.
    235  */
    236 
     261        return rtems_termios_close (arg);
     262}
     263
     264/*
     265 * Read from the device
     266 */
    237267rtems_device_driver console_read(
    238268  rtems_device_major_number major,
     
    241271)
    242272{
    243   rtems_libio_rw_args_t *rw_args;
    244   char *buffer;
    245   int maximum;
    246   int count = 0;
    247  
    248   rw_args = (rtems_libio_rw_args_t *) arg;
    249 
    250   buffer = rw_args->buffer;
    251   maximum = rw_args->count;
    252 
    253   for (count = 0; count < maximum; count++) {
    254     buffer[ count ] = inbyte();
    255     if (buffer[ count ] == '\n' || buffer[ count ] == '\r') {
    256       buffer[ count++ ]  = '\n';
    257       break;
    258     }
    259   }
    260 
    261   rw_args->bytes_moved = count;
    262   return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED;
    263 }
    264 
    265 /*
    266  * write bytes to the serial port. Stdout and stderr are the same.
    267  */
    268 
     273        return rtems_termios_read (arg);
     274}
     275
     276/*
     277 * Write to the device
     278 */
    269279rtems_device_driver console_write(
    270280  rtems_device_major_number major,
     
    273283)
    274284{
    275   int count;
    276   int maximum;
    277   rtems_libio_rw_args_t *rw_args;
    278   char *buffer;
    279 
    280   rw_args = (rtems_libio_rw_args_t *) arg;
    281 
    282   buffer = rw_args->buffer;
    283   maximum = rw_args->count;
    284 
    285   for (count = 0; count < maximum; count++) {
    286     if ( buffer[ count ] == '\n') {
    287       outbyte('\r');
    288     }
    289     outbyte( buffer[ count ] );
    290   }
    291 
    292   rw_args->bytes_moved = maximum;
    293   return 0;
    294 }
    295 
    296 /*
    297  *  IO Control entry point
    298  */
    299 
     285        return rtems_termios_write (arg);
     286}
     287
     288/*
     289 * Handle ioctl request.
     290 * Should set hardware line speed, bits/char, etc.
     291 */
    300292rtems_device_driver console_control(
    301293  rtems_device_major_number major,
     
    303295  void                    * arg
    304296)
    305 {
    306   return RTEMS_SUCCESSFUL;
    307 }
     297{ 
     298        return rtems_termios_ioctl (arg);
     299}
Note: See TracChangeset for help on using the changeset viewer.