source: multiio/pcmmio/original/main_pcmmio_irq.c @ 2e9b49f

Last change on this file since 2e9b49f was 2e9b49f, checked in by Joel Sherrill <joel.sherrill@…>, on 12/11/09 at 20:41:36

2009-12-11 Joel Sherrill <joel.sherrill@…>

  • main_pcmmio_din.c, main_pcmmio_irq.c, pcmmio_shell.c: Report time between discrete in interrupts in microseconds.
  • Property mode set to 100644
File size: 6.1 KB
Line 
1/*
2 *  pcmmio_irq command
3 *
4 *  COPYRIGHT (c) 1989-2009.
5 *  On-Line Applications Research Corporation (OAR).
6 *
7 *  The license and distribution terms for this file may be
8 *  found in the file LICENSE in this distribution or at
9 *  http://www.rtems.com/license/LICENSE.
10 *
11 *  $Id$
12 */
13
14#include "pcmmio_commands.h"
15#include "mio_io.h"
16#include <rtems/stringto.h>
17#include <stdint.h>
18
19#define __need_getopt_newlib
20#include <getopt.h>
21
22char pcmmio_irq_usage[] =
23  "Usage: %s [-i iterations] [-p period] [-v] [-d|-D DAC|-a ADC]\n"
24  "Where: maximum iterations defaults to 1\n"
25  "       the period is in milliseconds and defaults to 1000\n";
26
27#define PRINT_USAGE() \
28   printf( pcmmio_irq_usage, argv[0] )
29
30/*
31 *  pc386 BSP provided variables.
32 */
33extern uint64_t pc586_tsc_per_tick;
34extern uint64_t pc586_nanoseconds_per_tick;
35
36/*
37 *  Compute the number of TSC clicks per microsecond.
38 */
39uint64_t tsc_per_microsecond()
40{
41  static uint64_t pcmmio_tsc_per_microsecond = 0;
42
43  if ( pcmmio_tsc_per_microsecond == 0 ) {
44    pcmmio_tsc_per_microsecond =
45      (pc586_tsc_per_tick * 1000) / pc586_nanoseconds_per_tick;
46  }
47
48  return pcmmio_tsc_per_microsecond;
49}
50
51/*
52 *  Subtract two timestamps from the PCMMIO driver and convert that to
53 *  microseconds.
54 */
55int din_timestamp_subtract(
56  uint64_t previousTimestamp,
57  uint64_t timestamp
58)
59{
60  uint64_t cycles;
61
62  if ( previousTimestamp == 0 )
63    return 0;
64
65  cycles = timestamp - previousTimestamp;
66  return (int) (cycles  / tsc_per_microsecond());
67}
68
69int main_pcmmio_irq(int argc, char **argv)
70{
71  int                 milliseconds;
72  int                 maximum;
73  int                 iterations;
74  int                 sc;
75  char                ch;
76  bool                verbose;
77  struct getopt_data  getopt_reent;
78  const  char        *s;
79  bool                do_dac = false;
80  bool                do_adc = false;
81  bool                do_din = false;
82  int                 dac = -1;
83  int                 adc = -1;
84  int                 selected;
85  const char         *irq = "";
86  int                 elapsed;
87  int                 interrupts;
88  uint64_t            previousTimestamp = 0;
89  uint64_t            timestamp;
90
91  /*
92   * Parse arguments here
93   */
94  milliseconds = 1000;
95  maximum = 1;
96  verbose = false;
97
98  memset(&getopt_reent, 0, sizeof(getopt_data));
99  while ((ch = getopt_r(argc, argv, "i:p:vdD:a:", &getopt_reent)) != -1) {
100    switch (ch) {
101      case 'i': /* maximum iterations */
102        s = getopt_reent.optarg;
103        if ( rtems_string_to_int( s, &maximum, NULL, 0 ) ) {
104          printf( "Maximum iterations (%s) is not a number\n", s );
105          PRINT_USAGE();
106          return -1;
107        }
108
109        break;
110      case 'p': /* sampling period */
111        s = getopt_reent.optarg;
112        if ( rtems_string_to_int( s, &milliseconds, NULL, 0 ) ) {
113          printf( "Sampling period (%s) is not a number\n", s );
114          PRINT_USAGE();
115          return -1;
116        }
117        if ( milliseconds == 0 ) {
118          printf( "Sampling period (%d) is 0\n", milliseconds );
119          PRINT_USAGE();
120          return -1;
121        }
122        break;
123      case 'd': /* DIN enable */
124        do_din = true;
125        break;
126      case 'D': /* DAC enable */
127        s = getopt_reent.optarg;
128        if ( rtems_string_to_int( s, &dac, NULL, 0 ) ) {
129          printf( "DAC (%s) is not a number\n", s );
130          PRINT_USAGE();
131          return -1;
132        }
133
134        if ( dac < 0 || dac > 7 ) {
135          puts( "DAC number must be 0-7" );
136          PRINT_USAGE();
137          return -1;
138        }
139
140        do_dac = true;
141        break;
142      case 'a': /* ADC enable */
143        s = getopt_reent.optarg;
144        if ( rtems_string_to_int( s, &adc, NULL, 0 ) ) {
145          printf( "ADC (%s) is not a number\n", s );
146          PRINT_USAGE();
147          return -1;
148        }
149
150        if ( adc < 0 || adc > 7 ) {
151          puts( "ADC number must be 0-7" );
152          PRINT_USAGE();
153          return -1;
154        }
155        do_adc = true;
156        break;
157      case 'v': /* verbose */
158        verbose = true;
159        break;
160      default:
161        printf( pcmmio_irq_usage, argv[0] );
162        return -1;
163    }
164  }
165
166  /*
167   *  Did they select one item and ONLY one item?
168   */
169  selected = 0;
170  if ( do_din == true ) selected++;
171  if ( do_dac == true ) selected++;
172  if ( do_adc == true ) selected++;
173
174  if ( selected == 0 ) {
175    puts( "No IRQ Sources selected" );
176    return -1;
177  }
178
179  if ( selected > 1 ) {
180    puts( "More than 1 IRQ Sources selected" );
181    return -1;
182  }
183
184  if ( do_din == true ) {
185    irq = "DIN";
186  } else if ( do_dac == true ) {
187    irq = "DAC";
188  } else if ( do_adc == true ) {
189    irq = "ADC";
190  }
191  if ( maximum != 1 )
192    printf(
193      "Polling for %s IRQ for %d iterations with %d msec period\n",
194      irq,
195      maximum,
196      milliseconds
197    );
198
199  /*
200   *  Now sample in the loop
201   */
202  elapsed    = 0;
203  iterations = 1;
204  interrupts = 0;
205
206  flush_buffered_ints();
207  while (1) {
208    sc = 0;
209   
210    if ( do_din == true ) {
211      sc = wait_dio_int_with_timestamp(milliseconds, &timestamp);
212    } else if ( do_dac == true ) {
213      sc = wait_dac_int_with_timeout(dac, milliseconds);
214    } else if ( do_adc == true ) {
215      sc = wait_dac_int_with_timeout(adc, milliseconds);
216    }
217
218    if ( sc != -1 ) {
219      interrupts++;
220      if ( do_din == true ) {
221        printf(
222          "%d %s irq pin %d @ %llx (%d usecs since last)\n",
223          elapsed,
224          irq,
225          sc - 1,
226          timestamp,
227          din_timestamp_subtract( previousTimestamp, timestamp )
228        );
229        previousTimestamp = timestamp;
230      } else {
231        printf( "%d %s irq\n", elapsed, irq );
232      }
233    }
234
235    elapsed += milliseconds;
236    if (iterations++ >= maximum )
237      break;
238  }
239  printf(
240    "%d total interrupts from %s in %d milliseconds\n",
241    interrupts,
242    irq,
243    elapsed
244  );
245  return 0;
246}
247
248rtems_shell_cmd_t Shell_PCMMIO_IRQ_Command = {
249  "pcmmio_irq",                                    /* name */
250  "Wait for PCMMIO Interrupts",                    /* usage */
251  "pcmmio",                                        /* topic */
252  main_pcmmio_irq,                                 /* command */
253  NULL,                                            /* alias */
254  NULL                                             /* next */
255};
Note: See TracBrowser for help on using the repository browser.