Subversion Repositories group.electronics

Rev

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

Rev Author Line No. Line
139 pfowler 1
using System;
2
using System.Collections.Generic;
3
using System.Linq;
4
using System.Text;
5
using System.Threading.Tasks;
155 pfowler 6
using System.Timers;
139 pfowler 7
 
155 pfowler 8
using Microsoft.FlightSimulator.SimConnect;
9
 
139 pfowler 10
using LibUsbDotNet;
11
using LibUsbDotNet.Main;
12
using LibUsbDotNet.DeviceNotify;
13
 
14
namespace NITNavComm {
15
    public class NITNavCommDevice : NITDevice  {
16
 
17
        enum UsbCommands : byte {
18
            CMD_LATCH_DISPLAY = 20,
153 pfowler 19
            CMD_SET_DISPLAY = 21,
139 pfowler 20
        };
21
 
22
        private byte[,] display { get; set; }
23
        private byte[] buttons {get; set; }
149 pfowler 24
        private sbyte[,] rotary;
155 pfowler 25
        private ushort[] points { get; set; }
139 pfowler 26
 
155 pfowler 27
        public int flipcomm { get; set; }
28
        public int flipnav { get; set; }
29
 
30
        public uint simStatus { get; set; }
31
 
32
 
33
 
34
        private const int TIMER_INTERVAL = 600;
35
        private const int TIMER_COUNT = 4;
36
        private const int TIMER_COMMSWAP = 0;
37
        private const int TIMER_COMMFLIP = 1;
38
        private const int TIMER_NAVSWAP = 2;
39
        private const int TIMER_NAVFLIP = 3;
40
        Timer[] timers = new Timer[TIMER_COUNT];
41
 
139 pfowler 42
        public NITNavCommDevice(NITDevice nitDevice) :
43
            base(nitDevice.usbRegistry, "NITNavComm", nitDevice.vid, nitDevice.pid) {
155 pfowler 44
            this.init();
139 pfowler 45
        }
46
 
47
        public NITNavCommDevice(UsbRegistry usbRegistry, string type, int vid, int pid) :
48
            base(usbRegistry, "NITNavComm", 0x20a0, 0x4236) {
155 pfowler 49
            this.init();
139 pfowler 50
        }
51
 
147 pfowler 52
        private void init()
53
        {
155 pfowler 54
            base.Open();
55
 
147 pfowler 56
            this.display = new byte[2, 10];
155 pfowler 57
            this.points = new ushort[2];
58
            this.blankDisplay();
59
 
147 pfowler 60
            this.buttons = new byte[2];
61
            this.buttons[0] = 0x00;
62
            this.buttons[1] = 0x00;
155 pfowler 63
 
149 pfowler 64
            this.rotary = new sbyte[2, 2];
147 pfowler 65
            this.rotary[0, 0] = 0x00;
66
            this.rotary[0, 1] = 0x00;
67
            this.rotary[1, 0] = 0x00;
68
            this.rotary[1, 1] = 0x00;
155 pfowler 69
 
70
            this.flipcomm = 0;
71
            this.flipnav = 0;
72
 
73
            this.simStatus = 0;
74
            this.assigned = 1;
75
 
76
            for (int i = 0; i < TIMER_COUNT; i++) {
77
                Timer timer = new Timer();
78
                timer.Enabled = false;
79
                timer.AutoReset = false;
80
                timer.Interval = TIMER_INTERVAL;
81
                timer.Elapsed += OnDebounceTimer;
82
                timers[i] = timer;
83
            }
84
 
147 pfowler 85
        }
86
 
155 pfowler 87
        private static void OnDebounceTimer(Object source, ElapsedEventArgs e) {
88
            Timer timer = (Timer)source;
89
            timer.Enabled = false;
90
        }
91
 
139 pfowler 92
        new public bool Close() {
155 pfowler 93
            this.blankDisplay();
94
            return base.Close();
95
        }
96
 
97
        public void powerDown() {
98
            this.blankDisplay();
99
            this.simStatus = 2;
100
        }
101
 
102
        public void powerUp() {
103
            this.simStatus = 0;
104
        }
105
 
106
        public void blankDisplay() {
139 pfowler 107
            byte[] blank = { 0x0a, 0x0a, 0x0a, 0x0a, 0x0a };
108
            for (byte i = 0; i < 4; i++)
109
                setFreq(i, ref blank);
155 pfowler 110
            this.points[0] = 0x0000
111
                ;
112
            this.points[1] = 0x0000;
153 pfowler 113
            this.UpdateDisplay();
139 pfowler 114
        }
115
 
116
        public byte[] getFreq(byte freq) {
117
            byte[] ret = new byte[5];
118
            switch (freq) {
119
                case 0:
120
                    for (byte i = 0; i < 5; i++)
121
                        ret[i] = display[0, i];
122
                    break;
123
                case 1:
124
                    for (byte i = 0; i < 5; i++)
125
                        ret[i] = display[0, i + 5];
126
                    break;
127
                case 2:
128
                    for (byte i = 0; i < 5; i++)
129
                        ret[i] = display[1, i];
130
                    break;
131
                case 3:
132
                    for (byte i = 0; i < 5; i++)
133
                        ret[i] = display[1, i + 5];
134
                    break;
135
            }
136
            return ret;
137
        }
138
 
139
        public void setFreq(byte freq, ref byte[] data) {
140
            switch (freq) {
141
                case 0:
142
                    for (byte i = 0; i < 5; i++)
143
                        display[0, i] = data[i];
144
                    break;
145
                case 1:
146
                    for (byte i = 0; i < 5; i++)
147
                        display[0, i+5] = data[i];
148
                    break;
149
                case 2:
150
                    for (byte i = 0; i < 5; i++)
151
                        display[1, i] = data[i];
152
                    break;
153
                case 3:
154
                    for (byte i = 0; i < 5; i++)
155
                        display[1, i + 5] = data[i];
156
                    break;
157
            }
158
        }
159
 
155 pfowler 160
        public void setNavComFreqs(FSXObject.NavCom_Data data) {
153 pfowler 161
            byte[] freq0 = this.charArrayToBytes(data.Freq0.ToString().ToCharArray());
162
            byte[] freq1 = this.charArrayToBytes(data.Freq1.ToString().ToCharArray());
163
            byte[] freq2 = this.charArrayToBytes(data.Freq2.ToString().ToCharArray());
164
            byte[] freq3 = this.charArrayToBytes(data.Freq3.ToString().ToCharArray());
165
 
166
            this.setFreq(0, ref freq0);
167
            this.setFreq(1, ref freq1);
168
            this.setFreq(2, ref freq2);
169
            this.setFreq(3, ref freq3);
170
 
171
            this.UpdateDisplay();
172
        }
173
 
174
        private byte[] charArrayToBytes(char[] digits) {
175
            byte[] bytes = new byte[5];
176
            for (byte i = 0; i < 5; i++) {
177
                bytes[i] = (byte)(digits[i] - '0');
178
            }
179
            return bytes;
180
        }
181
 
182
        public void setDisplay(byte dis, ref byte[] data) {
183
            for (byte i = 0; i < data.Length; i++) {
184
                display[dis, i] = data[i];
185
            }
186
        }
187
 
139 pfowler 188
        private void sendDigit(byte dis, byte dig, byte val, byte dp) {
189
            ushort wxValue = (ushort)(dis <<8);
190
            wxValue |= dig;
191
            ushort wxIndex = (ushort)(dp << 8);
192
            wxIndex |= val;
193
 
194
            base.SendCommand(21, (short)wxValue, (short)wxIndex);
195
        }
196
 
197
        private void sendLatch(byte dis) {
153 pfowler 198
            if (!this.isOpen())
199
                return;
200
 
139 pfowler 201
            base.SendCommand(20, (short)dis, 0);
202
        }
203
 
204
        public void updateInput() {
205
            byte[] data = new byte[8];
206
            int transferred;
149 pfowler 207
            base.SendCommand(30, 0, 0, data, out transferred);
208
            this.buttons[0] = data[0];
209
            this.rotary[0, 0] += (sbyte)data[1];
210
            this.buttons[1] = data[2];
211
            this.rotary[1, 0] += (sbyte)data[3];
139 pfowler 212
        }
213
 
214
        public bool isSwapSet(byte dis) {
215
            if ((this.buttons[dis] & 0x01)>0)
216
                return true;
217
            return false;
218
        }
219
 
220
        public bool isFlipSet(byte dis) {
221
            if ((this.buttons[dis] & 0x02) > 0)
222
                return true;
223
            return false;
224
        }
225
 
149 pfowler 226
        public sbyte getRotary(byte dis, byte rotary) {
139 pfowler 227
            return this.rotary[dis, rotary];
228
        }
229
 
149 pfowler 230
        public void resetRotary(byte display, byte rotary) {
231
            this.rotary[display, rotary] = 0x00;
232
        }
233
 
155 pfowler 234
        private void sendData(byte dis) {
235
            for (byte i = 0; i < 10; i++) {
236
                //this.sendDigit(dis, i, display[dis, i], this.GetBit(this.points[dis], i));
237
                this.sendDigit(dis, i, display[dis, i], 0);
238
            }            
239
        }
240
 
153 pfowler 241
        public void UpdateDisplay() {
242
            this.sendData(0);
243
            this.sendData(1);
244
            this.latchDisplay(0);
245
            this.latchDisplay(1);
139 pfowler 246
        }
247
 
153 pfowler 248
        public void UpdateDisplay(byte dis) {
249
            this.sendData(dis);
250
            this.latchDisplay(dis);
251
        }
252
 
155 pfowler 253
        private byte GetBit(ushort b, byte bitNumber) {
254
            if ((b & (1 << bitNumber)) != 0)
255
                return 1;
256
            return 0;
153 pfowler 257
        }
258
 
259
        private void latchDisplay(byte dis) {
139 pfowler 260
            this.sendLatch(dis);
261
        }
262
 
263
        public void swapFreq(byte display) {
264
            if (display == 0) {
265
                byte[] left = this.getFreq(0);
266
                byte[] right = this.getFreq(1);
267
                this.setFreq(0, ref right);
268
                this.setFreq(1, ref left);
269
            } else if (display == 1) {
270
                byte[] left = this.getFreq(2);
271
                byte[] right = this.getFreq(3);
272
                this.setFreq(2, ref right);
273
                this.setFreq(3, ref left);
274
            }
275
        }
155 pfowler 276
        // @TODO: Make this work with COMM1/COMM2
277
        public void simButtons(FSXObject fsx) {
278
 
279
            if (!timers[TIMER_COMMSWAP].Enabled && this.isSwapSet(0)) {
280
                if (this.assigned == 1)
281
                    fsx.Comm1SwapFreq();
282
                else
283
                    fsx.Comm2SwapFreq();
284
                timers[TIMER_COMMSWAP].Enabled = true;
285
            }
286
 
287
            if (!timers[TIMER_NAVSWAP].Enabled && this.isSwapSet(1)) {
288
                if (this.assigned == 1)
289
                    fsx.Nav1SwapFreq();
290
                else
291
                    fsx.Nav2SwapFreq();
292
 
293
                timers[TIMER_NAVSWAP].Enabled = true;
294
            }
295
 
296
            // Check if the MHz/KHz has been pressed
297
            if (!timers[TIMER_COMMFLIP].Enabled && this.isFlipSet(0)) {
298
                this.flipcomm = 1 - this.flipcomm;
299
                timers[TIMER_COMMFLIP].Enabled = true;
300
            }
301
 
302
            if (!timers[TIMER_NAVFLIP].Enabled && this.isFlipSet(1)) {
303
                this.flipnav = 1 - this.flipnav;
304
                timers[TIMER_NAVFLIP].Enabled = true;
305
            }
306
 
307
            // Process the rotary encoders COMM1
308
            sbyte delta = this.getRotary(0, 0);
309
            this.resetRotary(0, 0);
310
            if (delta != 0) {
311
                if (delta < 0) {
312
                    delta = (sbyte)-delta;
313
 
314
                    if (this.flipcomm == 1)
315
                        if (this.assigned == 1)
316
                            fsx.Comm1DecFract();
317
                        else
318
                            fsx.Comm2DecFract();
319
                    else
320
                        if (this.assigned == 1)
321
                            fsx.Comm1DecWhole();
322
                        else
323
                            fsx.Comm2DecWhole();
324
                } else {
325
 
326
                    if (this.flipcomm == 1)
327
                        if (this.assigned == 1)
328
                            fsx.Comm1IncFract();
329
                        else
330
                            fsx.Comm2IncFract();
331
                    else
332
                        if (this.assigned == 1)
333
                            fsx.Comm1IncWhole();
334
                        else
335
                            fsx.Comm2IncWhole();
336
                }
337
            }
338
 
339
            // Process the rotary encoders NAV1
340
            delta = this.getRotary(1, 0);
341
            this.resetRotary(1, 0);
342
            if (delta != 0) {
343
                if (delta < 0) {
344
                    delta = (sbyte)-delta;
345
 
346
                    if (this.flipnav == 1)
347
                        if (this.assigned == 1)
348
                            fsx.Nav1DecFract();
349
                        else
350
                            fsx.Nav2DecFract();
351
                    else
352
                        if (this.assigned == 1)
353
                            fsx.Nav1DecWhole();
354
                        else
355
                            fsx.Nav2DecWhole();
356
                } else {
357
 
358
                    if (this.flipcomm == 1)
359
                        if (this.assigned == 1)
360
                            fsx.Nav1IncFract();
361
                        else
362
                            fsx.Nav2IncFract();
363
                    else
364
                        if (this.assigned == 1)
365
                            fsx.Nav1IncWhole();
366
                        else
367
                            fsx.Nav2IncWhole();
368
                }
369
            }
370
 
371
        }
139 pfowler 372
    }
373
}