Пример #1
0
void ns16550_init(int minor)
{
  uintptr_t               pNS16550;
  uint8_t                 ucDataByte;
  uint32_t                ulBaudDivisor;
  NS16550Context        *pns16550Context;
  setRegister_f           setReg;
  getRegister_f           getReg;
  console_tbl             *c = Console_Port_Tbl [minor];

  pns16550Context=(NS16550Context *)malloc(sizeof(NS16550Context));

  if (pns16550Context == NULL) {
    printk( "%s: Error: Not enough memory\n", __func__);
    rtems_fatal_error_occurred( 0xdeadbeef);
  }

  Console_Port_Data[minor].pDeviceContext=(void *)pns16550Context;
  pns16550Context->ucModemCtrl=SP_MODEM_IRQ;

  pNS16550 = c->ulCtrlPort1;
  setReg   = c->setRegister;
  getReg   = c->getRegister;

  /* Clear the divisor latch, clear all interrupt enables,
   * and reset and
   * disable the FIFO's.
   */

  (*setReg)(pNS16550, NS16550_LINE_CONTROL, 0x0);
  ns16550_enable_interrupts( c, NS16550_DISABLE_ALL_INTR );

  /* Set the divisor latch and set the baud rate. */

  ulBaudDivisor = NS16550_GetBaudDivisor(c, (uintptr_t) c->pDeviceParams);
  ucDataByte = SP_LINE_DLAB;
  (*setReg)(pNS16550, NS16550_LINE_CONTROL, ucDataByte);

  /* XXX */
  (*setReg)(pNS16550,NS16550_TRANSMIT_BUFFER,(uint8_t)(ulBaudDivisor & 0xffU));
  (*setReg)(
    pNS16550,NS16550_INTERRUPT_ENABLE,
    (uint8_t)(( ulBaudDivisor >> 8 ) & 0xffU )
  );

  /* Clear the divisor latch and set the character size to eight bits */
  /* with one stop bit and no parity checking. */
  ucDataByte = EIGHT_BITS;
  (*setReg)(pNS16550, NS16550_LINE_CONTROL, ucDataByte);

  /* Enable and reset transmit and receive FIFOs. TJA     */
  ucDataByte = SP_FIFO_ENABLE;
  (*setReg)(pNS16550, NS16550_FIFO_CONTROL, ucDataByte);

  ucDataByte = SP_FIFO_ENABLE | SP_FIFO_RXRST | SP_FIFO_TXRST;
  (*setReg)(pNS16550, NS16550_FIFO_CONTROL, ucDataByte);

  ns16550_enable_interrupts(c, NS16550_DISABLE_ALL_INTR);

  /* Set data terminal ready. */
  /* And open interrupt tristate line */
  (*setReg)(pNS16550, NS16550_MODEM_CONTROL,pns16550Context->ucModemCtrl);

  (*getReg)(pNS16550, NS16550_LINE_STATUS );
  (*getReg)(pNS16550, NS16550_RECEIVE_BUFFER );
}
Пример #2
0
int ns16550_set_attributes(
  int                   minor,
  const struct termios *t
)
{
  uint32_t                pNS16550;
  uint32_t                ulBaudDivisor;
  uint8_t                 ucLineControl;
  uint32_t                baud_requested;
  setRegister_f           setReg;
  rtems_interrupt_lock_context lock_context;
  const console_tbl      *c = Console_Port_Tbl [minor];

  pNS16550 = c->ulCtrlPort1;
  setReg   = c->setRegister;

  /*
   *  Calculate the baud rate divisor
   *
   *  Assert ensures there is no division by 0.
   */

  baud_requested = rtems_termios_baud_to_number(t->c_cflag);
  _Assert( baud_requested != 0 );
  ulBaudDivisor = NS16550_GetBaudDivisor(c, baud_requested);

  ucLineControl = 0;

  /*
   *  Parity
   */

  if (t->c_cflag & PARENB) {
    ucLineControl |= SP_LINE_PAR;
    if (!(t->c_cflag & PARODD))
      ucLineControl |= SP_LINE_ODD;
  }

  /*
   *  Character Size
   */

  if (t->c_cflag & CSIZE) {
    switch (t->c_cflag & CSIZE) {
      case CS5:  ucLineControl |= FIVE_BITS;  break;
      case CS6:  ucLineControl |= SIX_BITS;   break;
      case CS7:  ucLineControl |= SEVEN_BITS; break;
      case CS8:  ucLineControl |= EIGHT_BITS; break;
    }
  } else {
    ucLineControl |= EIGHT_BITS;               /* default to 9600,8,N,1 */
  }

  /*
   *  Stop Bits
   */

  if (t->c_cflag & CSTOPB) {
    ucLineControl |= SP_LINE_STOP;              /* 2 stop bits */
  } else {
    ;                                           /* 1 stop bit */
  }

  /*
   *  Now actually set the chip
   */

  rtems_interrupt_lock_acquire(&ns16550_lock, &lock_context);

    /*
     *  Set the baud rate
     *
     *  NOTE: When the Divisor Latch Access Bit (DLAB) is set to 1,
     *        the transmit buffer and interrupt enable registers
     *        turn into the LSB and MSB divisor latch registers.
     */

    (*setReg)(pNS16550, NS16550_LINE_CONTROL, SP_LINE_DLAB);
    (*setReg)(pNS16550, NS16550_TRANSMIT_BUFFER, ulBaudDivisor&0xff);
    (*setReg)(pNS16550, NS16550_INTERRUPT_ENABLE, (ulBaudDivisor>>8)&0xff);

    /*
     *  Now write the line control
     */
    (*setReg)(pNS16550, NS16550_LINE_CONTROL, ucLineControl );

  rtems_interrupt_lock_release(&ns16550_lock, &lock_context);

  return 0;
}
Пример #3
0
int ns16550_set_attributes(
  int                   minor,
  const struct termios *t
)
{
  uint32_t                pNS16550;
  uint32_t                ulBaudDivisor;
  uint8_t                 ucLineControl;
  uint32_t                baud_requested;
  setRegister_f           setReg;
  uint32_t                Irql;
  const console_tbl      *c = Console_Port_Tbl [minor];

  pNS16550 = c->ulCtrlPort1;
  setReg   = c->setRegister;

  /*
   *  Calculate the baud rate divisor
   */

  baud_requested = rtems_termios_baud_to_number(t->c_cflag);
  ulBaudDivisor = NS16550_GetBaudDivisor(c, baud_requested);

  ucLineControl = 0;

  /*
   *  Parity
   */

  if (t->c_cflag & PARENB) {
    ucLineControl |= SP_LINE_PAR;
    if (!(t->c_cflag & PARODD))
      ucLineControl |= SP_LINE_ODD;
  }

  /*
   *  Character Size
   */

  if (t->c_cflag & CSIZE) {
    switch (t->c_cflag & CSIZE) {
      case CS5:  ucLineControl |= FIVE_BITS;  break;
      case CS6:  ucLineControl |= SIX_BITS;   break;
      case CS7:  ucLineControl |= SEVEN_BITS; break;
      case CS8:  ucLineControl |= EIGHT_BITS; break;
    }
  } else {
    ucLineControl |= EIGHT_BITS;               /* default to 9600,8,N,1 */
  }

  /*
   *  Stop Bits
   */

  if (t->c_cflag & CSTOPB) {
    ucLineControl |= SP_LINE_STOP;              /* 2 stop bits */
  } else {
    ;                                           /* 1 stop bit */
  }

  /*
   *  Now actually set the chip
   */

  rtems_interrupt_disable(Irql);

    /*
     *  Set the baud rate
     */

    (*setReg)(pNS16550, NS16550_LINE_CONTROL, SP_LINE_DLAB);
    /* XXX are these registers right? */
    (*setReg)(pNS16550, NS16550_TRANSMIT_BUFFER, ulBaudDivisor&0xff);
    (*setReg)(pNS16550, NS16550_INTERRUPT_ENABLE, (ulBaudDivisor>>8)&0xff);

    /*
     *  Now write the line control
     */
    (*setReg)(pNS16550, NS16550_LINE_CONTROL, ucLineControl );

  rtems_interrupt_enable(Irql);

  return 0;
}