Added some ack'ing of b interrupts, and do acks before handling
[comedi.git] / comedi / drivers / comedi_counter_unstable.h
1 /*
2     comedi_counter_unstable.h
3
4     This is for the development of comedi's counter API.  Any API
5     described here should be considered under development and
6     subject to change!  Eventually, this should get merged into
7     comedi.h when consensus is reached on a good API.
8
9     Copyright (C) 2003 Frank Mori Hess
10
11     This program is free software; you can redistribute it and/or modify
12     it under the terms of the GNU General Public License as published by
13     the Free Software Foundation; either version 2 of the License, or
14     (at your option) any later version.
15
16     This program is distributed in the hope that it will be useful,
17     but WITHOUT ANY WARRANTY; without even the implied warranty of
18     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19     GNU General Public License for more details.
20
21     You should have received a copy of the GNU General Public License
22     along with this program; if not, write to the Free Software
23     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24
25 ************************************************************************/
26
27 /* ALPHA counter stuff */
28 /*
29
30 ID=INSN_CONFIG_COUNTER_ALPHA: counter configuration
31
32   The subdevice has an accumulator which changes based on
33   triggers.
34
35   [0] - ID
36   [1] - trigger0 (comedi_counter_trigger_bits() is helpful)
37   [2] - action0 (action associated with trigger0, see comedi_counter_actions
38         for possibilities)
39   [3] - trigger1
40   [4] - action 1
41   ....
42
43   You can specify as many trigger/action pairs as you like.
44
45   Example Modes:
46     Up counter, counting falling edges on input 0
47
48         data[1] = comedi_counter_trigger_bits(0, CR_EDGE | CR_INVERT);
49         data[2] = COMEDI_INC_ACCUMULATOR;
50
51     Down counter, counting rising edges on input 0, and using input 1 as a gate
52     (input 1 must be high to count):
53
54         data[1] = comedi_counter_trigger_bits(0, CR_EDGE) | comedi_counter_trigger_bits(1, 0);
55         data[2] = COMEDI_DEC_ACCUMULATOR;
56
57     Quadrature x1 encoding:
58         data[1] = comedi_counter_trigger_bits(0, CR_EDGE) |
59                 comedi_counter_trigger_bits(1, CR_INVERT);
60         data[2] = COMEDI_INC_ACCUMULATOR;
61         data[3] = comedi_counter_trigger_bits(0, CR_EDGE | CR_INVERT) |
62                 comedi_counter_trigger_bits(1, CR_INVERT);
63         data[4] = COMEDI_DEC_ACCUMULATOR;
64
65   Notes:
66         Could add fields for specifying what inputs are connected to (input 0 connected
67         to external input pin, or internal oscillator?).
68
69         Could make triggers/actions more involved, for example "trigger on accumulator
70         reaches 0", or specify a value to reload the counter with for the
71         COMEDI_RESET_ACCUMULATOR action.  Could add an action that sets the counter's
72         output, like "pulse output when accumulator reaches 0".
73
74         Using this instruction is a bit of a pain.  On the user-end, the user has
75         to figure out exactly how to describe what her counter is doing in order to
76         program it, even if the counter only supports a few different modes of
77         operation.  This could be
78         eased by providing helper functions that fill out an insn with the
79         appropriate values for particular pieces of hardware.  On the driver end,
80         it might make things easier if we provided some functions for operations
81         on sets of trigger/action pairs.  For example, queries like "is A a subset
82         of B" where A and B are sets of trigger/action pairs.
83 */
84 #define INSN_CONFIG_COUNTER_ALPHA               0x1000
85
86 static inline int comedi_counter_trigger_bits(unsigned int input_num, int flags)
87 {
88         static const int low_bit = 0x1;
89         static const int edge_bit = 0x2;
90         static const int valid_bit = 0x4;
91         static const int bits_per_channel = 3;
92         int bits = valid_bit;
93
94         if(flags & CR_EDGE)
95                 bits |= edge_bit;
96         if(flags & CR_INVERT)
97                 bits |= low_bit;
98         return bits << (input_num * bits_per_channel);
99 }
100 enum comedi_counter_actions
101 {
102         COMEDI_INC_ACCUMULATOR,
103         COMEDI_DEC_ACCUMULATOR,
104         COMEDI_RESET_ACCUMULATOR,
105 };