Back to home page

LXR

 
 

    


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

0001 /*
0002  *  Console driver for Milkymist
0003  *
0004  *  The license and distribution terms for this file may be
0005  *  found in the file LICENSE in this distribution or at
0006  *  http://www.rtems.org/license/LICENSE.
0007  *
0008  *  COPYRIGHT (c) 2010 Sebastien Bourdeauducq
0009  */
0010 
0011 #include <unistd.h>
0012 #include <termios.h>
0013 
0014 #include <rtems.h>
0015 #include <rtems/bspIo.h>
0016 #include <rtems/libio.h>
0017 #include <rtems/console.h>
0018 #include <rtems/termiostypes.h>
0019 #include <bsp/irq-generic.h>
0020 
0021 #include "../include/system_conf.h"
0022 #include "uart.h"
0023 
0024 BSP_output_char_function_type BSP_output_char = BSP_uart_polled_write;
0025 BSP_polling_getchar_function_type BSP_poll_char = BSP_uart_polled_read;
0026 
0027 static struct rtems_termios_tty *tty;
0028 
0029 static int mmconsole_first_open(int major, int minor, void *arg)
0030 {
0031   tty = ((rtems_libio_open_close_args_t *) arg)->iop->data1;
0032   return rtems_termios_set_initial_baud(tty, UART_BAUD_RATE);
0033 }
0034 
0035 static int mmconsole_last_close(int major, int minor, void *arg)
0036 {
0037   return 0;
0038 }
0039 
0040 static int mmconsole_set_attributes(int minor, const struct termios *t)
0041 {
0042   int baud;
0043 
0044   switch (t->c_ospeed) {
0045     case B0:
0046       baud = 0;
0047       break;
0048     case B50:
0049       baud = 50;
0050       break;
0051     case B75:
0052       baud = 75;
0053       break;
0054     case B110:
0055       baud = 110;
0056       break;
0057     case B134:
0058       baud = 134;
0059       break;
0060     case B150:
0061       baud = 150;
0062       break;
0063     case B200:
0064       baud = 200;
0065       break;
0066     case B300:
0067       baud = 300;
0068       break;
0069     case B600:
0070       baud = 600;
0071       break;
0072     case B1200:
0073       baud = 1200;
0074       break;
0075     case B1800:
0076       baud = 1800;
0077       break;
0078     case B2400:
0079       baud = 2400;
0080       break;
0081     case B4800:
0082       baud = 4800;
0083       break;
0084     case B9600:
0085       baud = 9600;
0086       break;
0087     case B19200:
0088       baud = 19200;
0089       break;
0090     case B38400:
0091       baud = 38400;
0092       break;
0093     case B57600:
0094       baud = 57600;
0095       break;
0096     case B115200:
0097       baud = 115200;
0098       break;
0099     case B230400:
0100       baud = 230400;
0101       break;
0102     case B460800:
0103       baud = 460800;
0104       break;
0105     default:
0106       baud = -1;
0107       break;
0108   }
0109 
0110   if (baud > 0)
0111     MM_WRITE(MM_UART_DIV, MM_READ(MM_FREQUENCY)/baud/16);
0112 
0113   return 0;
0114 }
0115 
0116 static ssize_t mmconsole_write(int minor, const char *buf, size_t n)
0117 {
0118   if (n > 0) {
0119     MM_WRITE(MM_UART_RXTX, *buf);
0120   }
0121 
0122   return 0;
0123 }
0124 
0125 static rtems_isr mmconsole_interrupt(rtems_vector_number n)
0126 {
0127   char c;
0128   while (MM_READ(MM_UART_STAT) & UART_STAT_RX_EVT) {
0129     c = MM_READ(MM_UART_RXTX);
0130     MM_WRITE(MM_UART_STAT, UART_STAT_RX_EVT);
0131     rtems_termios_enqueue_raw_characters(tty, &c, 1);
0132   }
0133   if (MM_READ(MM_UART_STAT) & UART_STAT_TX_EVT) {
0134     MM_WRITE(MM_UART_STAT, UART_STAT_TX_EVT);
0135     rtems_termios_dequeue_characters(tty, 1);
0136   }
0137   lm32_interrupt_ack(1 << MM_IRQ_UART);
0138 }
0139 
0140 static const rtems_termios_callbacks mmconsole_callbacks = {
0141   .firstOpen = mmconsole_first_open,
0142   .lastClose = mmconsole_last_close,
0143   .pollRead = NULL,
0144   .write = mmconsole_write,
0145   .setAttributes = mmconsole_set_attributes,
0146   .stopRemoteTx = NULL,
0147   .startRemoteTx = NULL,
0148   .outputUsesInterrupts = TERMIOS_IRQ_DRIVEN
0149 };
0150 
0151 rtems_device_driver console_initialize(
0152   rtems_device_major_number major,
0153   rtems_device_minor_number minor,
0154   void *arg
0155 )
0156 {
0157   rtems_status_code status;
0158   rtems_isr_entry dummy;
0159 
0160   rtems_termios_initialize();
0161 
0162   status = rtems_io_register_name("/dev/console", major, 0);
0163   if (status != RTEMS_SUCCESSFUL)
0164     rtems_fatal_error_occurred(status);
0165 
0166   rtems_interrupt_catch(mmconsole_interrupt, MM_IRQ_UART, &dummy);
0167   bsp_interrupt_vector_enable(MM_IRQ_UART);
0168   MM_WRITE(MM_UART_CTRL, UART_CTRL_RX_INT|UART_CTRL_TX_INT);
0169 
0170   return RTEMS_SUCCESSFUL;
0171 }
0172 
0173 rtems_device_driver console_open(
0174   rtems_device_major_number major,
0175   rtems_device_minor_number minor,
0176   void  *arg
0177 )
0178 {
0179   return rtems_termios_open(major, minor, arg, &mmconsole_callbacks);
0180 }
0181 
0182 rtems_device_driver console_close(
0183   rtems_device_major_number major,
0184   rtems_device_minor_number minor,
0185   void *arg
0186 )
0187 {
0188   return rtems_termios_close(arg);
0189 }
0190 
0191 rtems_device_driver console_read(
0192   rtems_device_major_number major,
0193   rtems_device_minor_number minor,
0194   void *arg
0195 )
0196 {
0197   return rtems_termios_read(arg);
0198 }
0199 
0200 rtems_device_driver console_write(
0201   rtems_device_major_number major,
0202   rtems_device_minor_number minor,
0203   void *arg
0204 )
0205 {
0206   return rtems_termios_write(arg);
0207 }
0208 
0209 rtems_device_driver console_control(
0210   rtems_device_major_number major,
0211   rtems_device_minor_number minor,
0212   void *arg
0213 )
0214 {
0215   return rtems_termios_ioctl(arg);
0216 }