Changeset 03aa739 in multiio


Ignore:
Timestamp:
Oct 5, 2011, 6:07:48 PM (8 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
master
Children:
d35032f
Parents:
396c143
Message:

2011-10-05 Joel Sherrill <joel.sherrill@…>

  • mio_io_rtems.c, multiio_pcmmio.c: Rework interrupt handler to reduce overhead per pin change.
Location:
pcmmio
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • pcmmio/ChangeLog

    r396c143 r03aa739  
     12011-10-05      Joel Sherrill <joel.sherrill@oarcorp.com>
     2
     3        * mio_io_rtems.c, multiio_pcmmio.c: Rework interrupt handler to reduce
     4        overhead per pin change.
     5
    162011-10-05      Cindy Cicalese <cicalese@mitre.org>
    27
  • pcmmio/mio_io_rtems.c

    r396c143 r03aa739  
    3232/* Function prototypes for local functions */
    3333static int get_buffered_int(
    34   unsigned long long *timestamp
     34  struct timespec *timestamp
    3535);
    3636static void init_io(unsigned short io_address);
    3737static void clr_int(int bit_number);
    3838static int get_int(void);
     39
     40int report_dio_ints(void);
    3941
    4042/* RTEMS Ids for Wait Queues */
     
    5355///////////////////////////////////////////////////////////////////////////////
    5456typedef struct {
    55   unsigned long long timestamp;
    56   int                pin;
     57  struct timespec timestamp;
     58  int             pin;
    5759} din_message_t;
    5860
     
    340342
    341343int dio_get_int_with_timestamp(
    342   unsigned long long *timestamp
     344  struct timespec *timestamp
    343345)
    344346{
     
    405407
    406408int wait_dio_int_with_timestamp(
    407   int                 milliseconds,
    408   unsigned long long *timestamp
     409  int              milliseconds,
     410  struct timespec *timestamp
    409411)
    410412{
     
    426428  );
    427429  if ( rc == RTEMS_UNSATISFIED ) {
     430    mio_error_code = MIO_READ_DATA_FAILURE;
     431    return -1;
     432  }
     433
     434  if ( rc == RTEMS_TIMEOUT ) {
    428435    mio_error_code = MIO_TIMEOUT_ERROR;
    429     return -1;
    430   }
    431 
    432   if ( rc == RTEMS_TIMEOUT ) {
    433     mio_error_code = MIO_READ_DATA_FAILURE;
    434436    return -1;
    435437  }
     
    536538  if ( rc == RTEMS_SUCCESSFUL )
    537539    return 0;
     540
     541  mio_error_code = MIO_TIMEOUT_ERROR;
    538542  return -1;
    539543}
     
    543547)
    544548{
    545   rtems_status_code rc;
    546   uint32_t          unblocked;
    547 
    548   rc = rtems_barrier_release(*id, &unblocked);
     549  uint32_t  unblocked;
     550
     551  (void) rtems_barrier_release(*id, &unblocked);
    549552}
    550553
     
    636639  if ( base_port && irq ) {
    637640    int status = 0;
     641
     642    /*
     643     *  Process any pending interrupts
     644     */
     645
     646    common_handler();
     647
    638648    pcmmio_irq.name = irq;
    639649    #if defined(BSP_SHARED_HANDLER_SUPPORT)
     
    650660}
    651661
    652 #include <libcpu/cpuModel.h> /* for rdtsc */
    653 
    654662/*
    655663 *  From this point down, we should be able to share easily with the Linux
     
    668676{
    669677  unsigned char status;
     678#if 0
    670679  unsigned char int_num;
     680#endif
    671681
    672682  /* Read the interrupt ID register from ADC2 */
    673 
    674683  adc2_port_image = adc2_port_image | 0x20;
    675684  outb(adc2_port_image,base_port + 0x0f);
    676685
    677686  status = inb(base_port + 0x0f);
     687#if !defined(PCMMIO_DISABLE_ADC_IRQ)
    678688  if (status & 1) {
    679689    /* Clear ADC1 interrupt */
     
    699709    wake_up_interruptible(&wq_dac_1);
    700710  }
     711#endif
    701712
    702713  if (status & 8) {
    703714
     715#if 1
     716    report_dio_ints();
     717#else
    704718    /* DIO interrupt. Find out which bit */
    705     while ((int_num = get_int()) != 0) {
     719    int_num = get_int();
     720    if (int_num) {
    706721      rtems_status_code  rc;
    707722      din_message_t      din;
    708723
    709       din.timestamp = rdtsc();
    710       din.pin       = int_num;
     724      rtems_clock_get_uptime( &din.timestamp );
     725      din.pin = int_num;
    711726
    712727      rc = rtems_message_queue_send( wq_dio, &din, sizeof(din_message_t) );
     
    724739      clr_int(int_num);
    725740    }
     741#endif
    726742  }
    727743
     
    846862}
    847863
     864void report_dio_interrupt(
     865  din_message_t   *din,
     866  int              pin
     867)
     868{
     869  rtems_status_code  rc;
     870
     871  din->pin = pin;
     872
     873  rc = rtems_message_queue_send( wq_dio, &din, sizeof(din_message_t) );
     874  if ( rc != RTEMS_SUCCESSFUL ) {
     875    pcmmio_dio_missed_interrupts++;
     876    #ifdef DEBUG
     877      printk("<1>Missed DIO interrupt\n" );
     878    #endif
     879 }
     880 #ifdef DEBUG
     881   printk("<1>Buffering DIO interrupt on bit %d\n",int_num);
     882 #endif
     883
     884  /* Clear the interrupt */
     885  clr_int(pin);
     886}
     887
     888int report_dio_ints(void)
     889{
     890  int                temp;
     891  int                x;
     892  unsigned short     dio_port;
     893  din_message_t      din;
     894  bool               found = false;
     895
     896  rtems_clock_get_uptime( &din.timestamp );
     897  /* din.pin set in report_dio_interrupts() */
     898
     899  dio_port = base_port + 0x10;
     900
     901  /* Read the master interrupt pending register,
     902           mask off undefined bits */
     903  temp = inb(dio_port+6) & 0x07;
     904
     905  /* If there are no pending interrupts, return 0 */
     906  if ((temp & 7) == 0)
     907    return 0;
     908
     909  /* There is something pending, now we need to identify it */
     910
     911  /* Set access to page 3 for interrupt id register */
     912  outb(0xc0, dio_port + 7);
     913
     914  /* Read the interrupt ID register for port 0 */
     915  temp = inb(dio_port+8);
     916
     917  /* See if any bit set, if so return the bit number */
     918  for (x=0; temp && x<=7; x++) {
     919    if (temp & (1 << x)) {
     920      outb(0,dio_port+7);
     921      report_dio_interrupt( &din, x+1 );
     922      found = true;
     923      temp &= ~(1 << x);
     924    }
     925  }
     926
     927  /* Now check port 0, read port 1 interrupt ID register */
     928  temp = inb(dio_port+9);
     929
     930  /* See if any bit set, if so return the bit number */
     931  for (x=0; temp && x<=7; x++) {
     932    if (temp & (1 << x)) {
     933      outb(0,dio_port+7);
     934      report_dio_interrupt( &din, x+9 );
     935      found = true;
     936      temp &= ~(1 << x);
     937    }
     938  }
     939
     940  /* Now read the status of port 2 interrupt ID register */
     941  temp = inb(dio_port+0x0a);
     942
     943  /* If any pending, return the appropriate bit number */
     944  for (x=0; temp && x<=7; x++) {
     945    if (temp & (1 << x)) {
     946      outb(0,dio_port+7);
     947      report_dio_interrupt( &din, x+17 );
     948      temp &= ~(1 << x);
     949      found = true;
     950    }
     951  }
     952
     953  /* We should never get here unless the hardware is seriously
     954     misbehaving, but just to be sure, we'll turn the page access
     955     back to 0 and return a 0 for no interrupt found
     956  */
     957  if ( !found )
     958    outb(0,dio_port+7);
     959  return 0;
     960}
     961
    848962void flush_buffered_ints(void)
    849963{
     
    859973
    860974int get_buffered_int(
    861   unsigned long long *timestamp
     975  struct timespec *timestamp
    862976)
    863977{
     
    881995    0
    882996  );
    883   if ( rc == RTEMS_UNSATISFIED )
     997  if ( rc == RTEMS_UNSATISFIED ) {
     998    mio_error_code = MIO_READ_DATA_FAILURE;
    884999    return 0;
     1000  }
    8851001
    8861002  if ( rc != RTEMS_SUCCESSFUL ) {
  • pcmmio/multiio_pcmmio.c

    r396c143 r03aa739  
    112112)
    113113{
    114   rtems_status_code sc;
    115 
    116   sc = wait_dio_int_with_timestamp(milliseconds, timestamp);
     114  (void) wait_dio_int_with_timestamp(milliseconds, timestamp);
    117115  return 0;
    118116}
Note: See TracChangeset for help on using the changeset viewer.