Changeset f787428f in rtems for c/src


Ignore:
Timestamp:
03/03/11 14:03:41 (13 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.11, 5, master
Children:
4c794c8
Parents:
8a5d6ac
Message:

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

PR 1750/bsps

  • console/erc32_console.c, make/custom/erc32.cfg: 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

    r8a5d6ac rf787428f  
     12011-03-03      Joel Sherrill <joel.sherrilL@OARcorp.com>
     2
     3        PR 1750/bsps
     4        * console/erc32_console.c, make/custom/erc32.cfg: The new console
     5        driver did not support polled mode. It also had a bug in which it
     6        could lose a transmitter interrupt.
     7
    182011-02-28      Joel Sherrill <joel.sherrill@oarcorp.com>
    29
  • c/src/lib/libbsp/sparc/erc32/console/erc32_console.c

    r8a5d6ac rf787428f  
    3737static uint8_t erc32_console_get_register(uint32_t addr, uint8_t i)
    3838{
    39     volatile uint32_t *reg = (volatile uint32_t *)addr;
    40     return (uint8_t) reg [i];
     39  volatile uint32_t *reg = (volatile uint32_t *)addr;
     40  return (uint8_t) reg [i];
    4141}
    4242
    4343static void erc32_console_set_register(uint32_t addr, uint8_t i, uint8_t val)
    4444{
    45     volatile uint32_t *reg = (volatile uint32_t *)addr;
    46     reg [i] = val;
     45  volatile uint32_t *reg = (volatile uint32_t *)addr;
     46  reg [i] = val;
    4747}
    4848
     
    5050
    5151#if (CONSOLE_USE_INTERRUPTS)
    52 static ssize_t erc32_console_write_support_int(
     52  static ssize_t erc32_console_write_support_int(
    5353    int minor, const char *buf, size_t len);
    5454#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);
     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);
    5858#endif
    5959static void erc32_console_initialize(int minor);
     
    8888
    8989console_tbl Console_Port_Tbl [] = {
    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     },
     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  },
    128128};
    129129
     
    137137static int erc32_console_first_open(int major, int minor, void *arg)
    138138{
    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;
     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;
    153153}
    154154
     
    156156static ssize_t erc32_console_write_support_int(int minor, const char *buf, size_t len)
    157157{
    158     console_data *cd = &Console_Port_Data[minor];
    159     int k = 0;
    160 
    161     if (minor == 0) { /* uart a */
    162         for (k = 0; k < len && (ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_THEA); k ++) {
    163             ERC32_MEC.UART_Channel_A = (unsigned char)buf[k];
    164         }
    165         ERC32_Force_interrupt(ERC32_INTERRUPT_UART_A_RX_TX);
    166     } else { /* uart b */
    167         for (k = 0; k < len && (ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_THEB); k ++) {
    168             ERC32_MEC.UART_Channel_B = (unsigned char)buf[k];
    169         }
    170         ERC32_Force_interrupt(ERC32_INTERRUPT_UART_B_RX_TX);
    171     }
    172    
    173     if (len > 0) {
    174         cd->pDeviceContext = (void *)k;
    175         cd->bActive = true;
    176     }
    177    
    178     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;
    179181}
    180182
    181183static void erc32_console_isr_a(
    182     rtems_vector_number vector
     184  rtems_vector_number vector
    183185)
    184186{
    185     console_data *cd = &Console_Port_Data[0];
    186 
    187     /* check for error */
    188     if (ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_ERRA) {
    189         ERC32_MEC.UART_Status = ERC32_MEC_UART_STATUS_CLRA;
    190         ERC32_MEC.Control = ERC32_MEC.Control;
    191     }
    192 
    193     do {
    194         int chars_to_dequeue = (int)cd->pDeviceContext;
    195         int rv = 0;
    196         int i = 0;
    197         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];
    198200       
    199         /* enqueue received chars */
    200         while (i < CONSOLE_BUF_SIZE) {
    201             if (ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_DRA) {
    202                 buf[i] = ERC32_MEC.UART_Channel_A;
    203                 ++i;
    204             } else {
    205                 break;
    206             }
    207         }
    208         rtems_termios_enqueue_raw_characters(cd->termios_data, buf, i);
    209 
    210         /* 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 ) {
    211216        cd->pDeviceContext = 0;
    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 ) {
    216             cd->bActive = false;
    217             ERC32_Clear_interrupt (ERC32_INTERRUPT_UART_A_RX_TX);
    218           }
    219         }
    220     } 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));
    221222}
    222223
    223224static void erc32_console_isr_b(
    224     rtems_vector_number vector
     225  rtems_vector_number vector
    225226)
    226227{
    227     console_data *cd = &Console_Port_Data[1];
    228 
    229     /* check for error */
    230     if (ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_ERRB) {
    231         ERC32_MEC.UART_Status = ERC32_MEC_UART_STATUS_CLRB;
    232         ERC32_MEC.Control = ERC32_MEC.Control;
    233     }
    234 
    235     do {
    236         int chars_to_dequeue = (int)cd->pDeviceContext;
    237         int rv = 0;
    238         int i = 0;
    239         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];
    240241       
    241         /* enqueue received chars */
    242         while (i < CONSOLE_BUF_SIZE) {
    243             if (ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_DRB) {
    244                 buf[i] = ERC32_MEC.UART_Channel_B;
    245                 ++i;
    246             } else {
    247                 break;
    248             }
    249         }
    250         rtems_termios_enqueue_raw_characters(cd->termios_data, buf, i);
    251 
    252         /* 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 ) {
    253257        cd->pDeviceContext = 0;
    254         if (ERC32_MEC.UART_Status & ERC32_MEC_UART_STATUS_THEB) {
    255           rv = rtems_termios_dequeue_characters(
    256              cd->termios_data, chars_to_dequeue);
    257           if ( !rv ) {
    258             cd->bActive = false;
    259             ERC32_Clear_interrupt (ERC32_INTERRUPT_UART_B_RX_TX);
    260           }
    261         }
    262     } while (ERC32_Is_interrupt_pending (ERC32_INTERRUPT_UART_B_RX_TX));
     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));
    263263}
    264264#else
     
    293293)
    294294{
    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)
     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)
    311311    set_vector(erc32_console_isr_a, CONSOLE_UART_A_TRAP, 1);
    312312    set_vector(erc32_console_isr_b, CONSOLE_UART_B_TRAP, 1);
    313 #endif
    314 }
     313  #endif
     314}
Note: See TracChangeset for help on using the changeset viewer.