Changeset 5180f7c in rtems


Ignore:
Timestamp:
Mar 3, 2011, 2:03:48 PM (8 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10
Children:
631a092
Parents:
280f82d7
Message:

2011-03-03 Joel Sherrill <joel.sherrilL@…>

PR 1750/bsps

  • console/erc32_console.c: The new console driver did not support polled mode. It also had a bug in which it could lose a transmitter interrupt.
Location:
c/src/lib/libbsp/sparc/erc32
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/sparc/erc32/ChangeLog

    r280f82d7 r5180f7c  
     12011-03-03      Joel Sherrill <joel.sherrilL@OARcorp.com>
     2
     3        PR 1750/bsps
     4        * console/erc32_console.c: The new console driver did not support
     5        polled mode. It also had a bug in which it could lose a transmitter
     6        interrupt.
     7
    182011-02-02      Ralf Corsépius <ralf.corsepius@rtems.org>
    29
  • c/src/lib/libbsp/sparc/erc32/console/erc32_console.c

    r280f82d7 r5180f7c  
    2828
    2929#include <bsp.h>
     30#include <bspopts.h>
    3031
    3132#define CONSOLE_BUF_SIZE (16)
     
    3637static uint8_t erc32_console_get_register(uint32_t addr, uint8_t i)
    3738{
    38     volatile uint32_t *reg = (volatile uint32_t *)addr;
    39     return (uint8_t) reg [i];
     39  volatile uint32_t *reg = (volatile uint32_t *)addr;
     40  return (uint8_t) reg [i];
    4041}
    4142
    4243static void erc32_console_set_register(uint32_t addr, uint8_t i, uint8_t val)
    4344{
    44     volatile uint32_t *reg = (volatile uint32_t *)addr;
    45     reg [i] = val;
     45  volatile uint32_t *reg = (volatile uint32_t *)addr;
     46  reg [i] = val;
    4647}
    4748
    4849static int erc32_console_first_open(int major, int minor, void *arg);
    49 static ssize_t erc32_console_write_support_int(int minor, const char *buf, size_t len);
     50
     51#if (CONSOLE_USE_INTERRUPTS)
     52  static ssize_t erc32_console_write_support_int(
     53    int minor, const char *buf, size_t len);
     54#else
     55  int console_inbyte_nonblocking( int port );
     56  static ssize_t erc32_console_write_support_polled(
     57      int minor, const char *buf, size_t len);
     58#endif
    5059static void erc32_console_initialize(int minor);
    5160
    5261rtems_device_minor_number Console_Port_Minor = 0;
    5362
    54 console_fns erc32_fns = {
     63#if (CONSOLE_USE_INTERRUPTS)
     64  console_fns erc32_fns = {
    5565    libchip_serial_default_probe,           /* deviceProbe */
    5666    erc32_console_first_open,               /* deviceFirstOpen */
     
    6171    NULL,                                   /* deviceWritePolled */
    6272    NULL,                                   /* deviceSetAttributes */
    63     true                                    /* deviceOutputUsesInterrupts */
    64 };
     73    TERMIOS_IRQ_DRIVEN                      /* deviceOutputUsesInterrupts */
     74  };
     75#else
     76  console_fns erc32_fns = {
     77    libchip_serial_default_probe,           /* deviceProbe */
     78    erc32_console_first_open,               /* deviceFirstOpen */
     79    NULL,                                   /* deviceLastClose */
     80    console_inbyte_nonblocking,             /* deviceRead */
     81    erc32_console_write_support_polled,     /* deviceWrite */
     82    erc32_console_initialize,               /* deviceInitialize */
     83    NULL,                                   /* deviceWritePolled */
     84    NULL,                                   /* deviceSetAttributes */
     85    TERMIOS_POLLED                          /* deviceOutputUsesInterrupts */
     86  };
     87#endif
    6588
    6689console_tbl Console_Port_Tbl [] = {
    67     {
    68       .sDeviceName = "/dev/console",
    69       .deviceType = SERIAL_CUSTOM,
    70       .pDeviceFns = &erc32_fns,
    71       .deviceProbe = NULL,
    72       .pDeviceFlow = NULL,
    73       .ulMargin = 16,
    74       .ulHysteresis = 8,
    75       .pDeviceParams = (void *) 1,
    76       .ulCtrlPort1 = 0,
    77       .ulCtrlPort2 = 0,
    78       .ulDataPort = 0,
    79       .getRegister = erc32_console_get_register,
    80       .setRegister = erc32_console_set_register,
    81       .getData = NULL,
    82       .setData = NULL,
    83       .ulClock = 16,
    84       .ulIntVector = ERC32_INTERRUPT_UART_A_RX_TX
    85     },
    86     {
    87       .sDeviceName = "/dev/console_b",
    88       .deviceType = SERIAL_CUSTOM,
    89       .pDeviceFns = &erc32_fns,
    90       .deviceProbe = NULL,
    91       .pDeviceFlow = NULL,
    92       .ulMargin = 16,
    93       .ulHysteresis = 8,
    94       .pDeviceParams = (void *) 1,
    95       .ulCtrlPort1 = 0,
    96       .ulCtrlPort2 = 0,
    97       .ulDataPort = 0,
    98       .getRegister = erc32_console_get_register,
    99       .setRegister = erc32_console_set_register,
    100       .getData = NULL,
    101       .setData = NULL,
    102       .ulClock = 16,
    103       .ulIntVector = ERC32_INTERRUPT_UART_B_RX_TX
    104     },
     90  {
     91    .sDeviceName = "/dev/console_a",
     92    .deviceType = SERIAL_CUSTOM,
     93    .pDeviceFns = &erc32_fns,
     94    .deviceProbe = NULL,
     95    .pDeviceFlow = NULL,
     96    .ulMargin = 16,
     97    .ulHysteresis = 8,
     98    .pDeviceParams = (void *) -1,  /* could be baud rate */
     99    .ulCtrlPort1 = 0,
     100    .ulCtrlPort2 = 0,
     101    .ulDataPort = 0,
     102    .getRegister = erc32_console_get_register,
     103    .setRegister = erc32_console_set_register,
     104    .getData = NULL,
     105    .setData = NULL,
     106    .ulClock = 16,
     107    .ulIntVector = ERC32_INTERRUPT_UART_A_RX_TX
     108  },
     109  {
     110    .sDeviceName = "/dev/console_b",
     111    .deviceType = SERIAL_CUSTOM,
     112    .pDeviceFns = &erc32_fns,
     113    .deviceProbe = NULL,
     114    .pDeviceFlow = NULL,
     115    .ulMargin = 16,
     116    .ulHysteresis = 8,
     117    .pDeviceParams = (void *) -1,  /* could be baud rate */
     118    .ulCtrlPort1 = 0,
     119    .ulCtrlPort2 = 0,
     120    .ulDataPort = 0,
     121    .getRegister = erc32_console_get_register,
     122    .setRegister = erc32_console_set_register,
     123    .getData = NULL,
     124    .setData = NULL,
     125    .ulClock = 16,
     126    .ulIntVector = ERC32_INTERRUPT_UART_B_RX_TX
     127  },
    105128};
    106129
     
    114137static int erc32_console_first_open(int major, int minor, void *arg)
    115138{
    116     /* Check minor number */
    117     if (minor < 0 || minor > 1) {
    118         return -1;
    119     }
    120    
    121     rtems_libio_open_close_args_t *oca = arg;
    122     struct rtems_termios_tty *tty = oca->iop->data1;
    123     console_tbl *ct = &Console_Port_Tbl [minor];
    124     console_data *cd = &Console_Port_Data [minor];
    125    
    126     cd->termios_data = tty;
    127     rtems_termios_set_initial_baud(tty, (int32_t)ct->pDeviceParams);
    128    
    129     return 0;
    130 }
    131 
     139  /* Check minor number */
     140  if (minor < 0 || minor > 1) {
     141    return -1;
     142  }
     143 
     144  rtems_libio_open_close_args_t *oca = arg;
     145  struct rtems_termios_tty *tty = oca->iop->data1;
     146  console_tbl *ct = &Console_Port_Tbl [minor];
     147  console_data *cd = &Console_Port_Data [minor];
     148 
     149  cd->termios_data = tty;
     150  rtems_termios_set_initial_baud(tty, (int32_t)ct->pDeviceParams);
     151 
     152  return 0;
     153}
     154
     155#if (CONSOLE_USE_INTERRUPTS)
    132156static ssize_t erc32_console_write_support_int(int minor, const char *buf, size_t len)
    133157{
    134     console_data *cd = &Console_Port_Data[minor];
    135     int k = 0;
    136 
    137     if (minor == 0) { /* uart a */
    138         for (k = 0; k < len && (ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_THEA); k ++) {
    139             ERC32_MEC.UART_Channel_A = (unsigned char)buf[k];
    140         }
    141         ERC32_Force_interrupt(ERC32_INTERRUPT_UART_A_RX_TX);
    142     } else { /* uart b */
    143         for (k = 0; k < len && (ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_THEB); k ++) {
    144             ERC32_MEC.UART_Channel_B = (unsigned char)buf[k];
    145         }
    146         ERC32_Force_interrupt(ERC32_INTERRUPT_UART_B_RX_TX);
    147     }
    148    
    149     if (len > 0) {
    150         cd->pDeviceContext = (void *)k;
    151         cd->bActive = true;
    152     }
    153    
    154     return 0;
     158  console_data *cd = &Console_Port_Data[minor];
     159  int k = 0;
     160
     161  if (minor == 0) { /* uart a */
     162    for (k = 0;
     163         k < len && (ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_THEA); k ++) {
     164      ERC32_MEC.UART_Channel_A = (unsigned char)buf[k];
     165    }
     166    ERC32_Force_interrupt(ERC32_INTERRUPT_UART_A_RX_TX);
     167  } else { /* uart b */
     168    for (k = 0;
     169         k < len && (ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_THEB); k ++) {
     170      ERC32_MEC.UART_Channel_B = (unsigned char)buf[k];
     171    }
     172    ERC32_Force_interrupt(ERC32_INTERRUPT_UART_B_RX_TX);
     173  }
     174 
     175  if (len > 0) {
     176    cd->pDeviceContext = (void *)k;
     177    cd->bActive = true;
     178  }
     179 
     180  return 0;
    155181}
    156182
    157183static void erc32_console_isr_a(
    158     rtems_vector_number vector
     184  rtems_vector_number vector
    159185)
    160186{
    161     console_data *cd = &Console_Port_Data[0];
    162 
    163     /* check for error */
    164     if (ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_ERRA) {
    165         ERC32_MEC.UART_Status = ERC32_MEC_UART_STATUS_CLRA;
    166         ERC32_MEC.Control = ERC32_MEC.Control;
    167     }
    168 
    169     do {
    170         int chars_to_dequeue = (int)cd->pDeviceContext;
    171         int rv = 0;
    172         int i = 0;
    173         char buf[CONSOLE_BUF_SIZE];
     187  console_data *cd = &Console_Port_Data[0];
     188
     189  /* check for error */
     190  if (ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_ERRA) {
     191    ERC32_MEC.UART_Status = ERC32_MEC_UART_STATUS_CLRA;
     192    ERC32_MEC.Control = ERC32_MEC.Control;
     193  }
     194
     195  do {
     196    int chars_to_dequeue = (int)cd->pDeviceContext;
     197    int rv = 0;
     198    int i = 0;
     199    char buf[CONSOLE_BUF_SIZE];
    174200       
    175         /* enqueue received chars */
    176         while (i < CONSOLE_BUF_SIZE) {
    177             if (ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_DRA) {
    178                 buf[i] = ERC32_MEC.UART_Channel_A;
    179                 ++i;
    180             } else {
    181                 break;
    182             }
    183         }
    184         rtems_termios_enqueue_raw_characters(cd->termios_data, buf, i);
    185 
    186         /* dequeue transmitted chars */
     201    /* enqueue received chars */
     202    while (i < CONSOLE_BUF_SIZE) {
     203      if (!(ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_DRA))
     204        break;
     205      buf[i] = ERC32_MEC.UART_Channel_A;
     206      ++i;
     207    }
     208    if ( i )
     209      rtems_termios_enqueue_raw_characters(cd->termios_data, buf, i);
     210
     211    /* dequeue transmitted chars */
     212    if (ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_THEA) {
     213      rv = rtems_termios_dequeue_characters(
     214         cd->termios_data, chars_to_dequeue);
     215      if ( !rv ) {
    187216        cd->pDeviceContext = 0;
    188         rv = rtems_termios_dequeue_characters(cd->termios_data, chars_to_dequeue);
    189         if (rv == 0 && !(ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_DRA)) {
    190             cd->bActive = false;
    191             ERC32_Clear_interrupt (ERC32_INTERRUPT_UART_A_RX_TX);
    192         }
    193     } while (ERC32_Is_interrupt_pending (ERC32_INTERRUPT_UART_A_RX_TX));
     217        cd->bActive = false;
     218      }
     219      ERC32_Clear_interrupt (ERC32_INTERRUPT_UART_A_RX_TX);
     220    }
     221  } while (ERC32_Is_interrupt_pending (ERC32_INTERRUPT_UART_A_RX_TX));
    194222}
    195223
    196224static void erc32_console_isr_b(
    197     rtems_vector_number vector
     225  rtems_vector_number vector
    198226)
    199227{
    200     console_data *cd = &Console_Port_Data[1];
    201 
    202     /* check for error */
    203     if (ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_ERRB) {
    204         ERC32_MEC.UART_Status = ERC32_MEC_UART_STATUS_CLRB;
    205         ERC32_MEC.Control = ERC32_MEC.Control;
    206     }
    207 
    208     do {
    209         int chars_to_dequeue = (int)cd->pDeviceContext;
    210         int rv = 0;
    211         int i = 0;
    212         char buf[CONSOLE_BUF_SIZE];
     228  console_data *cd = &Console_Port_Data[1];
     229
     230  /* check for error */
     231  if (ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_ERRB) {
     232      ERC32_MEC.UART_Status = ERC32_MEC_UART_STATUS_CLRB;
     233      ERC32_MEC.Control = ERC32_MEC.Control;
     234  }
     235
     236  do {
     237    int chars_to_dequeue = (int)cd->pDeviceContext;
     238    int rv = 0;
     239    int i = 0;
     240    char buf[CONSOLE_BUF_SIZE];
    213241       
    214         /* enqueue received chars */
    215         while (i < CONSOLE_BUF_SIZE) {
    216             if (ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_DRB) {
    217                 buf[i] = ERC32_MEC.UART_Channel_B;
    218                 ++i;
    219             } else {
    220                 break;
    221             }
    222         }
    223         rtems_termios_enqueue_raw_characters(cd->termios_data, buf, i);
    224 
    225         /* dequeue transmitted chars */
     242    /* enqueue received chars */
     243    while (i < CONSOLE_BUF_SIZE) {
     244      if (!(ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_DRB))
     245        break;
     246      buf[i] = ERC32_MEC.UART_Channel_B;
     247      ++i;
     248    }
     249    if ( i )
     250      rtems_termios_enqueue_raw_characters(cd->termios_data, buf, i);
     251
     252    /* dequeue transmitted chars */
     253    if (ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_THEB) {
     254      rv = rtems_termios_dequeue_characters(
     255         cd->termios_data, chars_to_dequeue);
     256      if ( !rv ) {
    226257        cd->pDeviceContext = 0;
    227         rv = rtems_termios_dequeue_characters(cd->termios_data, chars_to_dequeue);
    228         if (rv == 0 && !(ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_DRB)) {
    229             cd->bActive = false;
    230             ERC32_Clear_interrupt (ERC32_INTERRUPT_UART_B_RX_TX);
    231         }
    232     } while (ERC32_Is_interrupt_pending (ERC32_INTERRUPT_UART_B_RX_TX));
    233 }
     258        cd->bActive = false;
     259      }
     260      ERC32_Clear_interrupt (ERC32_INTERRUPT_UART_B_RX_TX);
     261    }
     262  } while (ERC32_Is_interrupt_pending (ERC32_INTERRUPT_UART_B_RX_TX));
     263}
     264#else
     265
     266extern void console_outbyte_polled( int  port, unsigned char ch );
     267
     268static ssize_t erc32_console_write_support_polled(
     269  int         minor,
     270  const char *buf,
     271  size_t      len
     272)
     273{
     274  int nwrite = 0;
     275
     276  while (nwrite < len) {
     277    console_outbyte_polled( minor, *buf++ );
     278    nwrite++;
     279  }
     280  return nwrite;
     281}
     282
     283#endif
    234284
    235285
     
    243293)
    244294{
    245     console_data *cd = &Console_Port_Data [minor];
    246 
    247     cd->bActive = false;
    248     cd->pDeviceContext = 0;
    249 
    250    /*
    251     * Initialize the Termios infrastructure.  If Termios has already
    252     * been initialized by another device driver, then this call will
    253     * have no effect.
    254     */
    255     rtems_termios_initialize();
    256 
    257    /*
    258     *  Initialize Hardware
    259     */
     295  console_data *cd = &Console_Port_Data [minor];
     296
     297  cd->bActive = false;
     298  cd->pDeviceContext = 0;
     299
     300 /*
     301  * Initialize the Termios infrastructure.  If Termios has already
     302  * been initialized by another device driver, then this call will
     303  * have no effect.
     304  */
     305  rtems_termios_initialize();
     306
     307 /*
     308  *  Initialize Hardware
     309  */
     310  #if (CONSOLE_USE_INTERRUPTS)
    260311    set_vector(erc32_console_isr_a, CONSOLE_UART_A_TRAP, 1);
    261312    set_vector(erc32_console_isr_b, CONSOLE_UART_B_TRAP, 1);
    262 }
     313  #endif
     314}
Note: See TracChangeset for help on using the changeset viewer.