Changeset ec5d4505 in rtems


Ignore:
Timestamp:
Jul 17, 2009, 1:53:24 PM (10 years ago)
Author:
Thomas Doerfler <Thomas.Doerfler@…>
Branches:
4.10, 4.11, master
Children:
4016765
Parents:
7ae2775
Message:

code cleanup

Location:
c/src
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • c/src/ChangeLog

    r7ae2775 rec5d4505  
    55        now use the same macros.
    66        * aclocal/bsp-bspcleanup-options.m4: New file.
     7
     82009-07-15      Sebastian Huber <sebastian.huber@embedded-brains.de>
     9
     10        * libchip/serial/ns16550.c, libchip/serial/ns16550_p.h: Removed
     11        obsolete defines and declarations.  Set initial baud during device
     12        open.  Fixed interrupt mode.
    713
    8142009-06-12      Joel Sherrill <joel.sherrill@oarcorp.com>
  • c/src/libchip/serial/ns16550.c

    r7ae2775 rec5d4505  
    3131#include <rtems/ringbuf.h>
    3232#include <rtems/bspIo.h>
     33#include <rtems/termiostypes.h>
    3334
    3435#include <libchip/serial.h>
     
    165166
    166167NS16550_STATIC int ns16550_open(
    167   int      major,
    168   int      minor,
    169   void    * arg
     168  int major,
     169  int minor,
     170  void *arg
    170171)
    171172{
    172   /*
    173    * Assert DTR
    174    */
    175 
    176   if(Console_Port_Tbl[minor].pDeviceFlow != &ns16550_flow_DTRCTS) {
    177     ns16550_assert_DTR(minor);
    178   }
    179 
    180   return(RTEMS_SUCCESSFUL);
     173  rtems_libio_open_close_args_t *oc = (rtems_libio_open_close_args_t *) arg;
     174  struct rtems_termios_tty *tty = (struct rtems_termios_tty *) oc->iop->data1;
     175  console_tbl *c = &Console_Port_Tbl [minor];
     176
     177  /* Assert DTR */
     178  if (c->pDeviceFlow != &ns16550_flow_DTRCTS) {
     179    ns16550_assert_DTR( minor);
     180  }
     181
     182  /* Set initial baud */
     183  rtems_termios_set_initial_baud( tty, (int) c->pDeviceParams);
     184
     185  return RTEMS_SUCCESSFUL;
    181186}
    182187
     
    204209 * @brief Polled write for NS16550.
    205210 */
    206 NS16550_STATIC void ns16550_write_polled( int minor, char c)
    207 {
    208   uint32_t port = Console_Port_Tbl [minor].ulCtrlPort1;
    209   getRegister_f get = Console_Port_Tbl [minor].getRegister;
    210   setRegister_f set = Console_Port_Tbl [minor].setRegister;
    211   uint32_t status;
     211NS16550_STATIC void ns16550_write_polled( int minor, char out)
     212{
     213  console_tbl *c = &Console_Port_Tbl [minor];
     214  uint32_t port = c->ulCtrlPort1;
     215  getRegister_f get = c->getRegister;
     216  setRegister_f set = c->setRegister;
     217  uint32_t status = 0;
    212218  rtems_interrupt_level level;
    213219
    214   while (1) {
     220  /* Save port interrupt mask */
     221  uint32_t interrupt_mask = get( port, NS16550_INTERRUPT_ENABLE);
     222
     223  /* Disable port interrupts */
     224  ns16550_enable_interrupts( minor, NS16550_DISABLE_ALL_INTR);
     225
     226  while (true) {
    215227    /* Try to transmit the character in a critical section */
    216228    rtems_interrupt_disable( level);
     
    220232    if ((status & SP_LSR_THOLD) != 0) {
    221233      /* Transmit character */
    222       set( port, NS16550_TRANSMIT_BUFFER, c);
     234      set( port, NS16550_TRANSMIT_BUFFER, out);
    223235
    224236      /* Finished */
     
    234246    } while ((status & SP_LSR_THOLD) == 0);
    235247  }
     248
     249  /* Restore port interrupt mask */
     250  set( port, NS16550_INTERRUPT_ENABLE, interrupt_mask);
    236251}
    237252
     
    449464
    450465#if defined(BSP_FEATURE_IRQ_EXTENSION) || defined(BSP_FEATURE_IRQ_LEGACY)
    451 /*
    452  *  ns16550_process
    453  *
    454  *  This routine is the console interrupt handler for A port.
    455  */
    456 
    457 NS16550_STATIC void ns16550_process(int minor)
     466
     467/**
     468 * @brief Process interrupt.
     469 */
     470NS16550_STATIC void ns16550_process( int minor)
    458471{
    459472  console_tbl *c = &Console_Port_Tbl [minor];
    460473  console_data *d = &Console_Port_Data [minor];
    461 
    462   uint32_t                pNS16550;
    463   volatile uint8_t        ucLineStatus;
    464   volatile uint8_t        ucInterruptId;
    465   char                    cChar;
    466   getRegister_f           getReg;
    467   setRegister_f           setReg;
    468 
    469   pNS16550 = c->ulCtrlPort1;
    470   getReg   = c->getRegister;
    471   setReg   = c->setRegister;
    472 
     474  ns16550_context *ctx = d->pDeviceContext;
     475  uint32_t port = c->ulCtrlPort1;
     476  getRegister_f get = c->getRegister;
     477  setRegister_f set = c->setRegister;
     478  int i = 0;
     479  char buf [SP_FIFO_SIZE];
     480
     481  /* Iterate until no more interrupts are pending */
    473482  do {
    474     /*
    475      * Deal with any received characters
    476      */
    477     while (true) {
    478       ucLineStatus = (*getReg)(pNS16550, NS16550_LINE_STATUS);
    479       if (~ucLineStatus & SP_LSR_RDY) {
    480         break;
    481       }
    482       cChar = (*getReg)(pNS16550, NS16550_RECEIVE_BUFFER);
    483       rtems_termios_enqueue_raw_characters(
    484         d->termios_data,
    485         &cChar,
    486         1
    487       );
    488     }
    489 
    490     /*
    491      *  TX all the characters we can
    492      */
    493 
    494     while (true) {
    495       ucLineStatus = (*getReg)(pNS16550, NS16550_LINE_STATUS);
    496       if (~ucLineStatus & SP_LSR_THOLD) {
    497         /*
    498          * We'll get another interrupt when
    499          * the transmitter holding reg. becomes
    500          * free again
    501          */
    502         break;
    503       }
    504 
    505       if (rtems_termios_dequeue_characters( d->termios_data, 1) == 0) {
    506         if (c->pDeviceFlow != &ns16550_flow_RTSCTS) {
    507           ns16550_negate_RTS(minor);
    508         }
    509         d->bActive = false;
    510         ns16550_enable_interrupts(minor, NS16550_ENABLE_ALL_INTR_EXCEPT_TX);
     483    /* Fetch received characters */
     484    for (i = 0; i < SP_FIFO_SIZE; ++i) {
     485      if ((get( port, NS16550_LINE_STATUS) & SP_LSR_RDY) != 0) {
     486        buf [i] = (char) get(port, NS16550_RECEIVE_BUFFER);
     487      } else {
    511488        break;
    512489      }
    513490    }
    514491
    515     ucInterruptId = (*getReg)(pNS16550, NS16550_INTERRUPT_ID);
    516   } while((ucInterruptId&0xf)!=0x1);
     492    /* Enqueue fetched characters */
     493    rtems_termios_enqueue_raw_characters( d->termios_data, buf, i);
     494
     495    /* Check if we can dequeue transmitted characters */
     496    if (ctx->transmitFifoChars > 0
     497        && (get( port, NS16550_LINE_STATUS) & SP_LSR_THOLD) != 0) {
     498      unsigned chars = ctx->transmitFifoChars;
     499
     500      /*
     501       * We finished the transmission, so clear the number of characters in the
     502       * transmit FIFO.
     503       */
     504      ctx->transmitFifoChars = 0;
     505
     506      /* Dequeue transmitted characters */
     507      if (rtems_termios_dequeue_characters( d->termios_data, chars) == 0) {
     508        /* Nothing to do */
     509        d->bActive = false;
     510        ns16550_enable_interrupts( minor, NS16550_ENABLE_ALL_INTR_EXCEPT_TX);
     511      }
     512    }
     513  } while ((get( port, NS16550_INTERRUPT_ID) & SP_IID_0) == 0);
     514}
     515#endif
     516
     517/**
     518 * @brief Transmits up to @a len characters from @a buf.
     519 *
     520 * This routine is invoked either from task context with disabled interrupts to
     521 * start a new transmission process with exactly one character in case of an
     522 * idle output state or from the interrupt handler to refill the transmitter.
     523 *
     524 * Returns always zero.
     525 */
     526NS16550_STATIC int ns16550_write_support_int(
     527  int minor,
     528  const char *buf,
     529  int len
     530)
     531{
     532  console_tbl *c = &Console_Port_Tbl [minor];
     533  console_data *d = &Console_Port_Data [minor];
     534  ns16550_context *ctx = d->pDeviceContext;
     535  uint32_t port = c->ulCtrlPort1;
     536  setRegister_f set = c->setRegister;
     537  int i = 0;
     538  int out = len > SP_FIFO_SIZE ? SP_FIFO_SIZE : len;
     539
     540  for (i = 0; i < out; ++i) {
     541    set( port, NS16550_TRANSMIT_BUFFER, buf [i]);
     542  }
     543
     544  if (len > 0) {
     545    ctx->transmitFifoChars = out;
     546    d->bActive = true;
     547    ns16550_enable_interrupts( minor, NS16550_ENABLE_ALL_INTR);
     548  }
     549
     550  return 0;
    517551}
    518552
     
    522556 *  This routine initializes the port to have the specified interrupts masked.
    523557 */
    524 #endif
    525 
    526558NS16550_STATIC void ns16550_enable_interrupts(
    527559  int minor,
     
    623655
    624656/*
    625  *  ns16550_write_support_int
    626  *
    627  *  Console Termios output entry point.
    628  */
    629 
    630 NS16550_STATIC int ns16550_write_support_int(
    631   int   minor,
    632   const char *buf,
    633   int   len
    634 )
    635 {
    636   uint32_t       Irql;
    637   uint32_t       pNS16550;
    638   setRegister_f  setReg;
    639 
    640   setReg   = Console_Port_Tbl[minor].setRegister;
    641   pNS16550 = Console_Port_Tbl[minor].ulCtrlPort1;
    642 
    643   /*
    644    *  We are using interrupt driven output and termios only sends us
    645    *  one character at a time.
    646    */
    647 
    648   if ( !len )
    649     return 0;
    650 
    651   if(Console_Port_Tbl[minor].pDeviceFlow != &ns16550_flow_RTSCTS) {
    652     ns16550_assert_RTS(minor);
    653   }
    654 
    655   rtems_interrupt_disable(Irql);
    656     if ( Console_Port_Data[minor].bActive == false) {
    657       Console_Port_Data[minor].bActive = true;
    658       ns16550_enable_interrupts(minor, NS16550_ENABLE_ALL_INTR);
    659     }
    660     (*setReg)(pNS16550, NS16550_TRANSMIT_BUFFER, *buf);
    661   rtems_interrupt_enable(Irql);
    662 
    663   return 1;
    664 }
    665 
    666 /*
    667657 *  ns16550_write_support_polled
    668658 *
  • c/src/libchip/serial/ns16550_p.h

    r7ae2775 rec5d4505  
    3030#define NS16550_STATIC static
    3131
    32 /*
    33  * Define serial port read registers structure.
    34  */
    35 
    36 typedef volatile struct _SP_READ_REGISTERS {
    37     unsigned char ReceiveBuffer;
    38     unsigned char InterruptEnable;
    39     unsigned char InterruptId;
    40     unsigned char LineControl;
    41     unsigned char ModemControl;
    42     unsigned char LineStatus;
    43     unsigned char ModemStatus;
    44     unsigned char ScratchPad;
    45 } SP_READ_REGISTERS, *PSP_READ_REGISTERS;
    46 
    4732#define NS16550_RECEIVE_BUFFER   0
     33#define NS16550_TRANSMIT_BUFFER  0
    4834#define NS16550_INTERRUPT_ENABLE 1
    4935#define NS16550_INTERRUPT_ID     2
     36#define NS16550_FIFO_CONTROL     2
    5037#define NS16550_LINE_CONTROL     3
    5138#define NS16550_MODEM_CONTROL    4
     
    5542
    5643/*
    57  * Define serial port write registers structure.
    58  */
    59 
    60 typedef volatile struct _SP_WRITE_REGISTERS {
    61     unsigned char TransmitBuffer;
    62     unsigned char InterruptEnable;
    63     unsigned char FifoControl;
    64     unsigned char LineControl;
    65     unsigned char ModemControl;
    66     unsigned char Reserved1;
    67     unsigned char ModemStatus;
    68     unsigned char ScratchPad;
    69 } SP_WRITE_REGISTERS, *PSP_WRITE_REGISTERS;
    70 
    71 #define NS16550_TRANSMIT_BUFFER  0
    72 #define NS16550_FIFO_CONTROL     2
    73 
    74 /*
    7544 * Define serial port interrupt enable register structure.
    7645 */
     
    8655
    8756/*
    88  * Define serial port interrupt id register structure.
    89  */
    90 
    91 typedef struct _SP_INTERRUPT_ID {
    92     unsigned char InterruptPending : 1;
    93     unsigned char Identification : 3;
    94     unsigned char Reserved1 : 2;
    95     unsigned char FifoEnabled : 2;
    96 } SP_INTERRUPT_ID, *PSP_INTERRUPT_ID;
     57 * Define serial port interrupt ID register structure.
     58 */
     59
     60#define SP_IID_0 0x01
     61#define SP_IID_1 0x02
     62#define SP_IID_2 0x04
     63#define SP_IID_3 0x08
    9764
    9865/*
     
    10572#define SP_FIFO_DMA   0x08
    10673#define SP_FIFO_RXLEVEL 0xc0
     74
     75#define SP_FIFO_SIZE 16
    10776
    10877/*
     
    157126#define SP_LSR_EFIFO  0x80
    158127
    159 typedef struct _ns16550_context
    160 {
    161         uint8_t         ucModemCtrl;
     128typedef struct {
     129  uint8_t ucModemCtrl;
     130  int transmitFifoChars;
    162131} ns16550_context;
    163132
Note: See TracChangeset for help on using the changeset viewer.