Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:48

0001 /*
0002  *  This file contains the MVME162 console IO package.
0003  */
0004 
0005 /*
0006  *  COPYRIGHT (c) 1989-2013.
0007  *  On-Line Applications Research Corporation (OAR).
0008  *
0009  *  The license and distribution terms for this file may be
0010  *  found in the file LICENSE in this distribution or at
0011  *  http://www.rtems.org/license/LICENSE.
0012  *
0013  *  Modifications of respective RTEMS file: COPYRIGHT (c) 1994.
0014  *  EISCAT Scientific Association. M.Savitski
0015  *
0016  *  This material is a part of the MVME162 Board Support Package
0017  *  for the RTEMS executive. Its licensing policies are those of the
0018  *  RTEMS above.
0019  */
0020 
0021 #define M162_INIT
0022 
0023 #include <rtems/bspIo.h>
0024 #include <rtems/console.h>
0025 #include <rtems/libio.h>
0026 #include <rtems/ringbuf.h>
0027 #include <bsp.h>
0028 
0029 Ring_buffer_t  Console_Buffer[2];
0030 
0031 /*
0032  *  Interrupt handler for receiver interrupts
0033  */
0034 static rtems_isr C_Receive_ISR(rtems_vector_number vector)
0035 {
0036   register int    ipend, port;
0037 
0038   ZWRITE0(1, 0x38);     /* reset highest IUS */
0039 
0040   ipend = ZREAD(1, 3);  /* read int pending from A side */
0041 
0042   if      (ipend == 0x04) port = 0;   /* channel B intr pending */
0043   else if (ipend == 0x20) port = 1;   /* channel A intr pending */
0044   else return;
0045 
0046   Ring_buffer_Add_character(&Console_Buffer[port], ZREADD(port));
0047 
0048   if (ZREAD(port, 1) & 0x70) {    /* check error stat */
0049     ZWRITE0(port, 0x30);          /* reset error */
0050   }
0051 }
0052 
0053 rtems_device_driver console_initialize(
0054   rtems_device_major_number  major,
0055   rtems_device_minor_number  minor,
0056   void                      *arg
0057 )
0058 {
0059   int     i;
0060   rtems_status_code status;
0061 
0062   /*
0063    * Initialise receiver interrupts on both ports
0064    */
0065   for (i = 0; i <= 1; i++) {
0066     Ring_buffer_Initialize( &Console_Buffer[i] );
0067     ZWRITE(i, 2, SCC_VECTOR);
0068     ZWRITE(i, 10, 0);
0069     ZWRITE(i, 1, 0x10);     /* int on all Rx chars or special condition */
0070     ZWRITE(i, 9, 8);        /* master interrupt enable */
0071   }
0072 
0073   set_vector(C_Receive_ISR, SCC_VECTOR, 1); /* install ISR for ports A and B */
0074 
0075   mcchip->vector_base = 0;
0076   mcchip->gen_control = 2;        /* MIEN */
0077   mcchip->SCC_int_ctl = 0x13;     /* SCC IEN, IPL3 */
0078 
0079   status = rtems_io_register_name(
0080     "/dev/console",
0081     major,
0082     (rtems_device_minor_number) 1
0083   );
0084 
0085   if (status != RTEMS_SUCCESSFUL)
0086     rtems_fatal_error_occurred(status);
0087 
0088   status = rtems_io_register_name(
0089     "/dev/tty00",
0090     major,
0091     (rtems_device_minor_number) 0
0092   );
0093 
0094   if (status != RTEMS_SUCCESSFUL)
0095     rtems_fatal_error_occurred(status);
0096 
0097   status = rtems_io_register_name(
0098     "/dev/tty01",
0099     major,
0100     (rtems_device_minor_number) 1
0101   );
0102 
0103   if (status != RTEMS_SUCCESSFUL)
0104     rtems_fatal_error_occurred(status);
0105 
0106   return RTEMS_SUCCESSFUL;
0107 }
0108 
0109 /*
0110  *   Non-blocking char input
0111  */
0112 bool char_ready(int port, char *ch)
0113 {
0114   if ( Ring_buffer_Is_empty( &Console_Buffer[port] ) )
0115     return false;
0116 
0117   Ring_buffer_Remove_character( &Console_Buffer[port], *ch );
0118 
0119   return true;
0120 }
0121 
0122 /*
0123  *   Block on char input
0124  */
0125 static char inbyte(int port)
0126 {
0127   char tmp_char;
0128 
0129   while ( !char_ready(port, &tmp_char) );
0130   return tmp_char;
0131 }
0132 
0133 /*
0134  *   This routine transmits a character out the SCC.  It no longer supports
0135  *   XON/XOFF flow control.
0136  */
0137 static void outbyte(char ch, int port)
0138 {
0139   while (1) {
0140     if (ZREAD0(port) & TX_BUFFER_EMPTY) break;
0141   }
0142   ZWRITED(port, ch);
0143 }
0144 
0145 /*
0146  *  Open entry point
0147  */
0148 rtems_device_driver console_open(
0149   rtems_device_major_number major,
0150   rtems_device_minor_number minor,
0151   void                    * arg
0152 )
0153 {
0154   return RTEMS_SUCCESSFUL;
0155 }
0156 
0157 /*
0158  *  Close entry point
0159  */
0160 rtems_device_driver console_close(
0161   rtems_device_major_number major,
0162   rtems_device_minor_number minor,
0163   void                    * arg
0164 )
0165 {
0166   return RTEMS_SUCCESSFUL;
0167 }
0168 
0169 /*
0170  * read bytes from the serial port. We only have stdin.
0171  */
0172 rtems_device_driver console_read(
0173   rtems_device_major_number major,
0174   rtems_device_minor_number minor,
0175   void                    * arg
0176 )
0177 {
0178   rtems_libio_rw_args_t *rw_args;
0179   char *buffer;
0180   int maximum;
0181   int count = 0;
0182 
0183   rw_args = (rtems_libio_rw_args_t *) arg;
0184 
0185   buffer = rw_args->buffer;
0186   maximum = rw_args->count;
0187 
0188   if ( minor > 1 )
0189     return RTEMS_INVALID_NUMBER;
0190 
0191   for (count = 0; count < maximum; count++) {
0192     buffer[ count ] = inbyte( minor );
0193     if (buffer[ count ] == '\n' || buffer[ count ] == '\r') {
0194       buffer[ count++ ]  = '\n';
0195       break;
0196     }
0197   }
0198 
0199   rw_args->bytes_moved = count;
0200   return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED;
0201 }
0202 
0203 /*
0204  * write bytes to the serial port. Stdout and stderr are the same.
0205  */
0206 rtems_device_driver console_write(
0207   rtems_device_major_number major,
0208   rtems_device_minor_number minor,
0209   void                    * arg
0210 )
0211 {
0212   int count;
0213   int maximum;
0214   rtems_libio_rw_args_t *rw_args;
0215   char *buffer;
0216 
0217   rw_args = (rtems_libio_rw_args_t *) arg;
0218 
0219   buffer = rw_args->buffer;
0220   maximum = rw_args->count;
0221 
0222   if ( minor > 1 )
0223     return RTEMS_INVALID_NUMBER;
0224 
0225   for (count = 0; count < maximum; count++) {
0226     if ( buffer[ count ] == '\n') {
0227       outbyte('\r', minor );
0228     }
0229     outbyte( buffer[ count ], minor  );
0230   }
0231 
0232   rw_args->bytes_moved = maximum;
0233   return 0;
0234 }
0235 
0236 /*
0237  *  IO Control entry point
0238  */
0239 rtems_device_driver console_control(
0240   rtems_device_major_number major,
0241   rtems_device_minor_number minor,
0242   void                    * arg
0243 )
0244 {
0245   return RTEMS_SUCCESSFUL;
0246 }
0247 
0248 /*
0249  *  _162Bug_output_char
0250  *
0251  *  Output a single character using the 162Bug functions.  The character
0252  *  will be written to the default output port.
0253  */
0254 static void _162Bug_output_char( char c )
0255 {
0256   asm volatile( "moveb  %0, -(%%sp)\n\t"   /* char to output */
0257                 "trap   #15\n\t"           /* Trap to 162Bug */
0258                 ".short 0x20"              /* Code for .OUTCHR */
0259     :: "d" (c) );
0260 }
0261 
0262 /*
0263  *  _BSP_output_char
0264  *
0265  *  printk() function prototyped in bspIo.h. Does not use termios.
0266  *
0267  *  If we have initialized the console device then use it, otherwise
0268  *  use the 162Bug routines to send it to the default output port.
0269  */
0270 static void _BSP_output_char(char c)
0271 {
0272   _162Bug_output_char(c);
0273 }
0274 
0275 /* Printk function */
0276 BSP_output_char_function_type           BSP_output_char = _BSP_output_char;
0277 BSP_polling_getchar_function_type       BSP_poll_char = NULL;