Subversion Repositories group.electronics

Rev

Rev 187 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
161 pfowler 1
using System;
2
using System.Collections.Generic;
3
using System.Linq;
4
using System.Text;
5
using System.Threading.Tasks;
6
 
7
namespace nitdcscore {
171 pfowler 8
 
9
    public class jsaxis {
10
        public UInt16 prev { get; set; }        // The previous ADC value
11
        public UInt16 value { get; set; }       // The current ADC value
12
        public UInt16 thres { get; set; }       // Threshold to report a new position
13
        public UInt16 max { get; set; }              // The maximum value we've seen
14
        public UInt16 mapsize { get; set; }     // The mapping maximum
15
 
16
        public jsaxis() {
17
 
18
        }
19
 
20
        public bool getPosition(ref UInt16 position) {
21
            if (this.value > this.max)
22
                this.max = this.value;
23
 
24
            UInt16 lowerval = 0;
25
            if (this.prev >= this.thres)
26
                lowerval = (UInt16)(this.prev - this.thres);
27
 
28
            ushort upperval = this.max;
29
            if (this.prev <= upperval - this.thres)
30
                upperval = (ushort)(this.prev + this.thres);
31
 
32
            if ((this.value < lowerval) || (this.value > upperval)) {
33
                // Cover our min/max ranges within threshold
34
                if (this.value < this.thres)
35
                    this.value = 0;
36
                if (this.value > this.max - this.thres)
37
                    this.value = this.max;
38
 
189 pfowler 39
                // Only update the prev value once we've moved out of the
40
                //  threshold and triggered an update
171 pfowler 41
                this.prev = this.value;
42
 
43
                position = Globals.map_uint16(this.value, 0, this.max, 0, this.mapsize);
44
 
45
                return true;
46
            }
47
 
48
            return false;
49
        }
50
    }
51
 
52
    public class jsdata {
53
        public bool changed { get; set; }
54
        public UInt64 buttons { get; set; }
55
        public UInt64 prev { get; set; }
56
 
57
        public jsaxis[] axis = new jsaxis[6];
58
 
59
        public jsdata() {
60
            changed = false;
61
            prev = buttons = 0;
62
 
63
            for (int i = 0; i < 6; i++) {
64
                axis[i] = new jsaxis();
65
                axis[i].thres = Globals.ADC_THRESHOLD;
66
                axis[i].max = Globals.ADC_DEFMAX;
67
                axis[i].prev = axis[i].value = 0;
68
                axis[i].mapsize = 0xffff;
69
            }
70
        }
71
    }
72
 
73
    public class Led {
172 pfowler 74
        public int bank { get; set; }
75
        public int pin { get; set; }
76
        public UInt16 address { get; set; }
77
        public UInt16 mask { get; set; }
78
        public int shift { get; set; }
171 pfowler 79
        public uint value { get; set; }
175 pfowler 80
        private UInt16 prevdata;
171 pfowler 81
 
172 pfowler 82
        public Led(int bank, int pin, UInt16 address, UInt16 mask, int shift) {
171 pfowler 83
            this.pin = pin;
84
            this.address = address;
85
            this.mask = mask;
86
            this.shift = shift;
87
            this.value = 0;
88
 
172 pfowler 89
            UInt16 data;
90
            if (!Globals.BiosOutput.TryGetValue(this.address, out data)) {
91
                Globals.BiosOutput.Add(this.address, 0x0000);
92
            }
93
 
171 pfowler 94
        }
95
 
172 pfowler 96
        public bool Tick(ref byte shadow) {
173 pfowler 97
 
172 pfowler 98
            UInt16 data;
99
            byte tmpshadow = shadow;
100
            if (Globals.BiosOutput.TryGetValue(this.address, out data)) {
175 pfowler 101
                // Only continue if the data parm has changed
102
                if (data == this.prevdata)
103
                    return false;
104
                this.prevdata = data;
173 pfowler 105
 
172 pfowler 106
                this.value = (UInt16)((data & mask) >> shift);
171 pfowler 107
 
172 pfowler 108
                if (this.value == 1)
173 pfowler 109
                    Globals.setBit(ref shadow, this.pin);
172 pfowler 110
                else
173 pfowler 111
                    Globals.clearBit(ref shadow, this.pin);
171 pfowler 112
            }
113
 
175 pfowler 114
            // Only update the led if the led value has changed
172 pfowler 115
            if (tmpshadow == shadow)
116
                return false;
117
 
175 pfowler 118
            // Return true to signal the panel to update the led
171 pfowler 119
            return true;
120
        }
121
 
181 pfowler 122
        public bool Tick(ref UInt16 shadow) {
123
 
124
            UInt16 data;
125
            UInt16 tmpshadow = shadow;
126
            if (Globals.BiosOutput.TryGetValue(this.address, out data)) {
127
                // Only continue if the data parm has changed
128
                if (data == this.prevdata)
129
                    return false;
130
                this.prevdata = data;
131
 
132
                this.value = (UInt16)((data & mask) >> shift);
133
 
134
                if (this.value == 1) {
135
                    Globals.setBit(ref shadow, this.pin);
136
                } else {
137
                    Globals.clearBit(ref shadow, this.pin);
138
                }
139
            }
140
 
141
            // Only update the led if the led value has changed
142
            if (tmpshadow == shadow)
143
                return false;
144
 
145
            // Return true to signal the panel to update the led
146
            return true;
147
        }
148
 
171 pfowler 149
    }
150
 
151
 
161 pfowler 152
    public abstract class Control {
166 pfowler 153
        public UInt64 value { get; set; }
162 pfowler 154
 
161 pfowler 155
        public Control(Command command) {
156
            commands.Add(command);
157
        }
158
 
159
        public List<Command> commands = new List<Command>();
167 pfowler 160
        public jsdata data { get; set; }
161 pfowler 161
        public Boolean updated { get; set; }
162
 
163
        public abstract void Tick();
164
    }
165
 
166
    public class Switch2Pos : Control {
167
        public int pin { get; set; }
162 pfowler 168
 
161 pfowler 169
        public Boolean invert { get; set; }
170
 
171
        public Switch2Pos(Command command, int pin, Boolean invert = false) : base(command) {
172
            this.invert = invert;
173
            this.pin = pin;
174
        }
175
 
176
        public override void Tick() {
166 pfowler 177
            UInt64 chg = (UInt64)(data.prev >> pin) & 0x01;
167 pfowler 178
            UInt64 norm = (UInt64)(data.buttons >> pin) & 0x01;
161 pfowler 179
            this.value = 0;
166 pfowler 180
 
181
            if ((UInt64)(norm) == 1) {
182
                value = (UInt64)(invert ? 0 : 1);
161 pfowler 183
            } else {
166 pfowler 184
                value = (UInt64)(invert ? 1 : 0);
161 pfowler 185
            }
186
 
162 pfowler 187
            if (this.commands != null && norm != chg) {
161 pfowler 188
                foreach (Command cmd in this.commands) {
162 pfowler 189
                    cmd.data = this.data;
164 pfowler 190
                    if (cmd.Send(this.value) == 0)
191
                        Console.Write(cmd.ToString());
161 pfowler 192
                }
193
            }
194
        }
195
    }
196
 
197
    public class Switch3Pos : Control {
198
        public int pin0 { get; set; }
199
        public int pin1 { get; set; }
162 pfowler 200
 
161 pfowler 201
        public Boolean invert { get; set; }
202
 
203
        public Switch3Pos(Command command, int pin0, int pin1, Boolean invert = false) : base(command) {
204
            this.pin0 = pin0;
205
            this.pin1 = pin1;
206
            this.invert = invert;
207
 
208
        }
209
 
210
        public override void Tick() {
166 pfowler 211
            UInt64 chg0 = (UInt64)(data.prev >> pin0) & 0x01;
212
            UInt64 chg1 = (UInt64)(data.prev >> pin1) & 0x01;
167 pfowler 213
            UInt64 nrm0 = (UInt64)(data.buttons >> pin0) & 0x01;
214
            UInt64 nrm1 = (UInt64)(data.buttons >> pin1) & 0x01;
161 pfowler 215
            this.value = 1;
166 pfowler 216
 
217
            if ((UInt64)nrm0 == 1)
218
                this.value = (UInt64)(invert ? 2 : 0);
161 pfowler 219
            else if ((uint)nrm1 == 1)
166 pfowler 220
                this.value = (UInt64)(invert ? 0 : 2);
162 pfowler 221
 
222
            if (this.commands != null &&  ((nrm0 != chg0) || (nrm1 != chg1))) {
161 pfowler 223
                foreach (Command cmd in this.commands) {
162 pfowler 224
                    cmd.data = this.data;
164 pfowler 225
                    if (cmd.Send(this.value) == 0)
226
                        Console.Write(cmd.ToString());
161 pfowler 227
                }
228
            }
229
        }
230
    }
231
 
167 pfowler 232
    public class Potentiometer : Control {
233
        public int channel { get; set; }
234
 
235
        public Boolean invert { get; set; }
236
 
237
        public Potentiometer(Command command, int channel) : base(command) {
238
            this.channel = channel;
239
        }
240
 
241
        public override void Tick() {
242
            UInt16 tmpval = 0;
168 pfowler 243
            bool changed = data.axis[channel].getPosition(ref tmpval);
180 pfowler 244
 
168 pfowler 245
            if (changed) {
187 pfowler 246
                this.value = tmpval;
167 pfowler 247
                foreach (Command cmd in this.commands) {
248
                    cmd.data = this.data;
249
                    if (cmd.Send(this.value) == 0)
250
                        Console.Write(cmd.ToString());
251
                }
252
            }
253
        }
254
    }
255
 
161 pfowler 256
    public class Selector : Control {
257
        int[] pins;
258
 
162 pfowler 259
 
161 pfowler 260
        public Selector(Command command, int[] pins) : base(command) {
261
            this.pins = pins;
262
            this.value = 0;
263
        }
264
 
265
        public override void Tick() {
162 pfowler 266
            // This is a rather complicated way  to check what the previous select
267
            //  was, and was the current selection is. Not really needed, but hoping it 
268
            //  might come in handy for something else down the line.
166 pfowler 269
            UInt64 chg = 0;
270
            UInt64 norm = 0;
271
            UInt64 mask = 0;
162 pfowler 272
            for (int i = 0; i < pins.Length; i++) // Create a mask of how many selection points there are
166 pfowler 273
                mask |= (UInt64)1 << i;
161 pfowler 274
 
275
            for (int i = 0; i < pins.Length; i++) {
166 pfowler 276
                chg |= (UInt64)(data.prev >> (pins[i] - i)); // Narrow down to the previsouly selected bit
167 pfowler 277
                norm |= (UInt64)(data.buttons >> (pins[i] - i)); // Narrow down to the currently selected bit
161 pfowler 278
 
167 pfowler 279
                if ((UInt64)((data.buttons >> pins[i]) & 0x01) == 1) { // Decode the value we need to use
166 pfowler 280
                    value = (UInt64)i;
161 pfowler 281
                }
282
            }
162 pfowler 283
 
284
            norm &= mask; // Remove any bits from above
161 pfowler 285
            chg &= mask;
162 pfowler 286
 
287
            if (norm == 0) // Can sometimes be in the inbetween selector switch, ignore
161 pfowler 288
                return;
289
 
162 pfowler 290
            if (norm != chg) { // Send the update if needed
161 pfowler 291
                foreach (Command cmd in this.commands) {
162 pfowler 292
                    cmd.data = this.data;
164 pfowler 293
                    if (cmd.Send(this.value) == 0)
294
                        Console.Write(cmd.ToString());
161 pfowler 295
                }
296
            }
297
        }
162 pfowler 298
 
161 pfowler 299
    }
300
}