[Bug 1829] LEON3_UART_Regs_Map struct incomplete

bugzilla-daemon at rtems.org bugzilla-daemon at rtems.org
Fri Jul 8 06:49:59 UTC 2011


https://www.rtems.org/bugzilla/show_bug.cgi?id=1829

Daniel Hellstrom <daniel at gaisler.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |daniel at gaisler.com

--- Comment #2 from Daniel Hellstrom <daniel at gaisler.com> 2011-07-08 01:49:58 CDT ---
Hello, 

It does not hurt to add it. The register is used to control the UART baud rate,
however the console.c APBUART driver does not support setting the baud rate so
the register is never used.

In the Gaisler RTEMS-4.10 sources we have added support for setting the baud
rate as below, even though the frequency detection isn't 100% correct and the
frequency detection should be located in a separate C-file under leon3/startup/
for example it works in 95% of the cases and is a better solution than the old
code. Also, it adds support for flowcontrol/stopbit/parity settings. The code
below will not work without modifications.

Regards,
Daniel

unsigned int console_get_sys_freq(void)
{
  unsigned int freq_hz;
  struct ambapp_apb_info gptimer;
  LEON3_Timer_Regs_Map *tregs;

  /* LEON3: find timer address via AMBA Plug&Play info */
  if ( ambapp_find_apbslv(&ambapp_plb, VENDOR_GAISLER, GAISLER_GPTIMER,
&gptimer
) == 1 ){
    tregs = (LEON3_Timer_Regs_Map *)gptimer.start;
    freq_hz = (tregs->scaler_reload+1)*1000*1000;
  } else {
    freq_hz = 40000000; /* Default to 40MHz */
    printk("CONSOLE: Failed to detect system frequency\n\r");
  }

  return freq_hz;
}

int console_set_attributes(int minor, const struct termios *t)
{
  unsigned int core_clk_hz;
  unsigned int scaler;
  unsigned int ctrl;
  int baud;
  struct apbuart_priv *uart;

  switch(t->c_cflag & CSIZE) {
    default:
    case CS5:
    case CS6:
    case CS7:
      /* Hardware doesn't support other than CS8 */
      return -1;
    case CS8:
      break;
  }

  minor += LEON3_Cpu_Index;

  if ( minor >= uarts )
    return -1;

  uart = &apbuarts[minor];

  /* Read out current value */
  ctrl = uart->regs->ctrl;

  switch(t->c_cflag & (PARENB|PARODD)){
    case (PARENB|PARODD):
      /* Odd parity */
      ctrl |= LEON_REG_UART_CTRL_PE|LEON_REG_UART_CTRL_PS;
      break;

    case PARENB:
      /* Even parity */
      ctrl &= ~LEON_REG_UART_CTRL_PS;
      ctrl |= LEON_REG_UART_CTRL_PE;
      break;

    default:
    case 0:
    case PARODD:
      /* No Parity */
      ctrl &= ~(LEON_REG_UART_CTRL_PS|LEON_REG_UART_CTRL_PE);
  }

  if ( !(t->c_cflag & CLOCAL) ){
    ctrl |= LEON_REG_UART_CTRL_FL;
  }else{
    ctrl &= ~LEON_REG_UART_CTRL_FL;
  }

  /* Update new settings */
  uart->regs->ctrl = ctrl;

  /* Baud rate */
  switch(t->c_cflag & CBAUD){
    default:      baud = -1;      break;
    case B50:     baud = 50;      break;
    case B75:     baud = 75;      break;
    case B110:    baud = 110;     break;
    case B134:    baud = 134;     break;
    case B150:    baud = 150;     break;
    case B200:    baud = 200;     break;
    case B300:    baud = 300;     break;
    case B600:    baud = 600;     break;
    case B1200:   baud = 1200;    break;
    case B1800:   baud = 1800;    break;
    case B2400:   baud = 2400;    break;
    case B4800:   baud = 4800;    break;
    case B9600:   baud = 9600;    break;
    case B19200:  baud = 19200;   break;
    case B38400:  baud = 38400;   break;
    case B57600:  baud = 57600;   break;
    case B115200: baud = 115200;  break;
    case B230400: baud = 230400;  break;
    case B460800: baud = 460800;  break;
  }

  if ( baud > 0 ){
    /* Get APBUART core frequency, it is assumed that it is the same
     * as system frequency 
     */
    core_clk_hz = console_get_sys_freq();

    /* Calculate Baud rate generator "scaler" number */
    scaler = (((core_clk_hz*10)/(baud*8))-5)/10;

    /* Set new baud rate by setting scaler */
    uart->regs->scaler = scaler;
  }

  return 0;
}



  static const rtems_termios_callbacks pollCallbacks = {
    NULL,                        /* firstOpen */
    NULL,                        /* lastClose */
    console_inbyte_nonblocking,  /* pollRead */
    console_write_support,       /* write */
-    NULL,                        /* setAttributes */
+    console_set_attributes,      /* setAttributes */
    NULL,                        /* stopRemoteTx */
    NULL,                        /* startRemoteTx */
    0                            /* outputUsesInterrupts */
  };

-- 
Configure bugmail: https://www.rtems.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are watching all bug changes.



More information about the bugs mailing list