summaryrefslogtreecommitdiff
path: root/src/hal/components/mux16.comp
blob: b0198ccf0b24da23435827a9c8e5106df948f3ef (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
component mux16 "Select from one of sixteen input values";
pin in bit use_graycode"""\
This signifies the input will use Gray code instead of binary.
Gray code is a good choice when using physical switches because
for each increment only one select input changes at a time.
""";
pin in bit suppress_no_input"""\
This suppresses changing the output if all select lines are false.
This stops unwanted jumps in output between transitions of input.
but make in00 unavaliable.
""";
pin in float debounce_time"""\
sets debouce time in seconds.  eg. .10 = a tenth of a second
input must be stable this long before outputs changes. This
helps to ignore 'noisy' switches.
""";
pin in bit sel#[4] """\
Together, these determine which \\fBin\\fIN\\fR value is copied to \\fBout\\fR.
""";
pin out float out_f;
pin out s32 out_s """\
Follows the value of one of the \\fBin\\fIN\\fR values according to the four \\fBsel\\fR values
and whether use-graycode is active.
The s32 value will be trunuated and limited to the max and min values of signed values. 
.RS
.TP
\\fBsel3=FALSE\\fR, \\fBsel2=FALSE\\fR, \\fBsel1=FALSE\\fR, \\fBsel0=FALSE\\fR
\\fBout\\fR follows \\fBin0\\fR
.TP
\\fBsel3=FALSE\\fR, \\fBsel2=FALSE\\fR, \\fBsel1=FALSE\\fR, \\fBsel0=TRUE\\fR
\\fBout\\fR follows \\fBin1\\fR
.TP
etc.
.RE
""";
param r float elapsed "Current value of the internal debounce timer\n for debugging.";
param r s32 selected "Current value of the internal selection variable after conversion\n for debugging";
pin in float in##[16] "array of selectable outputs";
variable double delaytime;
variable int lastnum;
variable int running;
function _;
license "GPL";
;;
FUNCTION(_) {
    int i,num = 0;
    int internal[4];

    if(suppress_no_input) {
        if (sel(0) + sel(1) + sel(2) + sel(3) == 0) {
            return;
        }
    }
    if (use_graycode) {
        internal[0] = sel(3);
        internal[1] = sel(2);
        internal[2] = sel(1);
        internal[3] = sel(0);
        for(i = 1; i < 4; i++){
            internal[i] = internal[i] ^ internal[i - 1];
        }
        selected = num = internal[3]+(internal[2]*2) + (internal[1]*4) + (internal[0]*8);
    }else{
        selected = num = (sel(0))+(sel(1)*2) + (sel(2)*4) + (sel(3)*8);
    }
    if(debounce_time) {
        if (num != lastnum) {
            if (!running) {
                running = 1;
                delaytime = 0;
            }
            if (delaytime < debounce_time) {
                delaytime += fperiod;
                elapsed = delaytime;
                return;
            }else{
            running = 0;
            lastnum = num;
            out_s = out_f = in(num);
            return;
            }
        }
    }
    /* select the output */
    out_s = out_f = in(num);

}