Rev 159 | Rev 161 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
using MCP2221;using System;using System.Collections.Generic;using System.Linq;using System.Reflection;using System.Text;using System.Threading.Tasks;using System.Timers;using WindowsInput;using WindowsInput.Native;namespace nitdcscore {public struct devdata {public uint prev_input;public uint cur_input;public ushort cur_adc;public ushort prev_adc;public ushort max_adc;public ushort adc_thres;public int id;public string name;public string function;}public class mcp2221 {DcsBios bios = new DcsBios();public MchpUsbI2c usbi2c = new MchpUsbI2c();public Boolean hasAHFS { get; set; }public Boolean hasAAP { get; set; }int idx { get; set; }int devcount { get; set; }public uint speed { get; set; }Timer refresh = new Timer();Timer delay = new Timer();InputSimulator sendkey = new InputSimulator();private readonly Object lockobject = new object();public devdata[] devices = new devdata[5];public mcp2221() {speed = 400000;idx = 0;refresh.Interval = 70;refresh.AutoReset = true;refresh.Elapsed += refresh_Elapsed;refresh.Enabled = false;bios.InitUDP();usbi2c.Settings.GetConnectionStatus();devcount = usbi2c.Management.GetDevCount();Console.WriteLine(devcount.ToString() + " devices found");for (int i = 0; i < devcount; i++) {int rslt = usbi2c.Management.SelectDev(i);usbi2c.Settings.GetConnectionStatus();string usbDescriptor = this.usbi2c.Settings.GetUsbStringDescriptor();if (usbDescriptor == "AHCP/FSCP Panel") {this.hasAHFS = true;devices[i].cur_input = 0;devices[i].prev_input = 0;devices[i].cur_adc = 0;devices[i].max_adc = 930;devices[i].adc_thres = 15;devices[i].id = i;devices[i].name = "AHCP/FSCP Panel";devices[i].function = "refresh_ahfs";init_ahfs(i);} else if (usbDescriptor == "AAP Panel") {this.hasAAP = true;devices[i].cur_input = 0;devices[i].prev_input = 0;devices[i].prev_adc = 0;devices[i].id = i;devices[i].name = "AAP Panel";devices[i].function = "refresh_aap";init_aap(i);}}}private Boolean enabled;public Boolean Enabled {get {return enabled;}set {if (this.devcount == 0)return;this.enabled = true;refresh.Enabled = true;}}void refresh_Elapsed(object sender, ElapsedEventArgs e) {if (!Enabled)return;devdata dev = devices[idx];usbi2c.Management.SelectDev(dev.id);usbi2c.Settings.GetConnectionStatus();Type type = this.GetType();MethodInfo callfunc = type.GetMethod(dev.function);ParameterInfo[] parameters = callfunc.GetParameters();object[] parms = { idx };callfunc.Invoke(this, parms);idx++;if (idx >= devcount)idx = 0;}public void init_aap(int devid) {// Enable the mcp23017WriteGpio(3, 0);Utils.delayms(500);this.WriteGpio(3, 1);Utils.delayms();// Set io dir, pullups and rev polaritybyte[] data;data = new byte[] { 0x00, 0xff, 0xff, 0xff, 0xff }; // All inputs & polarityWriteI2cData(0x40, data, 5);data = new byte[] { 0x0c, 0xff, 0xff }; // All pullups = onWriteI2cData(0x40, data, 3);refresh_aap(devid);devices[devid].prev_input = devices[devid].cur_input;}public void refresh_aap(int devid) {refresh.Enabled = false;lock (lockobject) {byte[] data;data = new byte[] { 0x12 }; // Select GPIOA registerWriteI2cData(0x40, data, 1);data = new byte[] { 0x00, 0x00 }; // Read two bytesint rslt = ReadI2CData(0x41, ref data, 2);// Join all our buttons into a single inputsuint gpio = (uint)((1 - ReadGpio(0)) | ((1 - ReadGpio(1)) << 1));devices[devid].cur_input = (uint)gpio << 16;devices[devid].cur_input |= (uint)data[0] << 8;devices[devid].cur_input |= (uint)data[1];if (devices[devid].cur_input != devices[devid].prev_input) {this.input_aap(devid);devices[devid].prev_input = devices[devid].cur_input;}}refresh.Enabled = enabled;}public void input_aap(int devid) {//Switch2Pos(11, "AAP_CDUPWR", devid);//Switch2Pos(10, "AAP_EGIPWR", devid);//Switch3Pos(9, 8, "AAP_STEER", devid);//Selector(new int[] { 6, 5, 4 }, "AAP_STEERPT", devid);//Selector(new int[] {0,1,2,3}, "AAP_PAGE", devid);}public void init_ahfs(int devid) {WriteGpio(3, 0);Utils.delayms(500);// Enable the mcp23017WriteGpio(3, 1);Utils.delayms();// Set io dir, pullups and rev polaritybyte[] data;// Soldered a couple of inputs wrong, the f0 is to reverse them (fuel boost switches)data = new byte[] { 0x00, 0xff, 0xff, 0xf0, 0xff }; // All inputs & polarityWriteI2cData(0x40, data, 5);data = new byte[] { 0x0c, 0xff, 0xff }; // All pullups = onWriteI2cData(0x40, data, 3);data = new byte[] { 0x00, 0xff, 0xff, 0xff, 0xff }; // All inputs & polarityWriteI2cData(0x42, data, 5);data = new byte[] { 0x0c, 0xff, 0xff }; // All pullups = onWriteI2cData(0x42, data, 3);// Get the initial ADC valuedevices[devid].prev_adc = devices[devid].cur_adc = ReadADC(1);refresh_ahfs(devid);devices[devid].prev_input = devices[devid].cur_input;}public void refresh_ahfs(int devid) {refresh.Enabled = false;lock (lockobject) {byte[] data;data = new byte[] { 0x12 }; // Select GPIOA registerWriteI2cData(0x40, data, 1);data = new byte[] { 0x00, 0x00 }; // Read two bytesint rslt = ReadI2CData(0x41, ref data, 2);devices[devid].cur_input = (uint)data[0] << 24;devices[devid].cur_input |= (uint)data[1] << 16;data = new byte[] { 0x12 }; // Select GPIOA registerWriteI2cData(0x42, data, 1);data = new byte[] { 0x00, 0x00 }; // Read two bytesrslt = ReadI2CData(0x43, ref data, 2);devices[devid].cur_input |= (uint)data[0] << 8;devices[devid].cur_input |= (uint)data[1];if (devices[devid].cur_input != devices[devid].prev_input) {this.input_ahfs(devid);devices[devid].prev_input = devices[devid].cur_input;}// Do the Refueling light adcdevices[devid].cur_adc = ReadADC(1);if (devices[devid].cur_adc > devices[devid].max_adc)devices[devid].max_adc = devices[devid].cur_adc;ushort lowerval = 0;if (devices[devid].prev_adc >= devices[devid].adc_thres)lowerval = (ushort)(devices[devid].prev_adc - devices[devid].adc_thres);ushort upperval = devices[devid].max_adc;if (devices[devid].prev_adc <= upperval - devices[devid].adc_thres)upperval = (ushort)(devices[devid].prev_adc + devices[devid].adc_thres);//Console.WriteLine("ADC: " + devices[devid].cur_adc + " Max: " + devices[devid].max_adc + " Low: " + lowerval + " High: " + upperval);if ((devices[devid].cur_adc < lowerval) || (devices[devid].cur_adc >= upperval)) {// Cover our min/max ranges within thresholdif (devices[devid].cur_adc < devices[devid].adc_thres)devices[devid].cur_adc = 0;if (devices[devid].cur_adc > devices[devid].max_adc - devices[devid].adc_thres)devices[devid].cur_adc = devices[devid].max_adc;devices[devid].prev_adc = devices[devid].cur_adc;ushort refuellight = map_ushort(devices[devid].cur_adc, 0, devices[devid].max_adc, 0, 0xffff);bios.SendData("ALCP_RCVR_LTS " + refuellight.ToString() + "\n");Console.WriteLine("ALCP_RCVR_LTS " + ":" + refuellight.ToString() + "(" + devices[devid].cur_adc + ")");}}refresh.Enabled = enabled;}public void input_ahfs(int devid) {// AHCP// Train - Safe - ArmSwitch3Pos(8, 9, "AHCP_MASTER_ARM", devid);// Gunarm - Safe - ArmSwitch3Pos(10, 11, "AHCP_GUNPAC", devid);// Train - Safe - ArmSwitch3Pos(12, 13, "AHCP_LASER_ARM", devid);// Off - OnSwitch2Pos(14, "AHCP_TGP", devid);// Radar - Delta - BaroSwitch3Pos(0, 1, "AHCP_ALT_SCE", devid);// Night - DaySwitch2Pos(2, "AHCP_HUD_DAYNIGHT", devid);//Stby - NormSwitch2Pos(15, "AHCP_HUD_MODE", devid);// Off - OnSwitch2Pos(3, "AHCP_CICU", devid);// Off - OnSwitch2Pos(4, "AHCP_JTRS", devid);//Off - Test - OnSwitch3Pos(6, 5, "AHCP_IFFCC", devid);//Switch2Pos(7, "HARS_FAST_ERECT", devid);// Fuel System//Switch2Pos(16, "FSCP_AMPL", devid);//Switch2Pos(24, "FSCP_BOOST_MAIN_L", devid);//Switch2Pos(25, "FSCP_BOOST_MAIN_R", devid);//Switch2Pos(26, "FSCP_BOOST_WING_L", devid);//Switch2Pos(27, "FSCP_BOOST_WING_R", devid);//Switch2Pos(28, "FSCP_CROSSFEED", devid);//Switch2Pos(30, "FSCP_EXT_TANKS_FUS", devid);//Switch2Pos(31, "FSCP_EXT_TANKS_WING", devid);//Switch2Pos(20, "FSCP_FD_MAIN_L",devid, true);//Switch2Pos(21, "FSCP_FD_MAIN_R", devid, true);//Switch2Pos(18, "FSCP_FD_WING_L", devid, true);//Switch2Pos(19, "FSCP_FD_WING_R", devid, true);//Switch2Pos(17, "FSCP_LINE_CHECK", devid);//Switch2Pos(23, "FSCP_RCVR_LEVER", devid); // Technically a 3pos, but 3rd not needed//Switch2Pos(29, "FSCP_TK_GATE", devid);}public byte ReadGpio(byte pinNum) {return Convert.ToByte(usbi2c.Functions.ReadGpioPinValue(pinNum));}public ushort ReadADC(byte pinNum) {ushort[] adcData = { 0, 0, 0, 0, 0, 0 };int rslt = usbi2c.Functions.GetAdcData(adcData);return adcData[pinNum];}public void WriteGpio(byte pinNum, byte value) {this.usbi2c.Functions.WriteGpioPinValue(pinNum, value);}public int WriteI2cData(byte address, byte[] data, uint count) {int rslt = this.usbi2c.Functions.WriteI2cData(address, data, count, this.speed);return rslt;}public int ReadI2CData(byte address, ref byte[] data, uint count) {int rslt = this.usbi2c.Functions.ReadI2cData(address, data, count, this.speed);return rslt;}public uint Switch2Pos(int pin, String cmd, int devid, Boolean invert = false) {uint chg = (uint)(devices[devid].prev_input >> pin) & 0x01;uint norm = (uint)(devices[devid].cur_input >> pin) & 0x01;uint value = 0;if ((uint)(norm) == 1) {value = (uint)(invert ? 0 : 1);} else {value = (uint)(invert ? 1 : 0);}if (norm != chg) {bios.SendData(cmd + " " + value.ToString() + "\n");Console.WriteLine(cmd + ":" + value.ToString());}return value;}public uint Switch3Pos(int pin0, int pin1, String cmd, int devid, Boolean invert = false) {uint value = 1;uint chg0 = (uint)(devices[devid].prev_input >> pin0) & 0x01;uint chg1 = (uint)(devices[devid].prev_input >> pin1) & 0x01;uint nrm0 = (uint)(devices[devid].cur_input >> pin0) & 0x01;uint nrm1 = (uint)(devices[devid].cur_input >> pin1) & 0x01;if ((uint)nrm0 == 1)value = (uint)(invert ? 2 : 0);else if ((uint)nrm1 == 1)value = (uint)(invert ? 0 : 2);if ((nrm0 != chg0) || (nrm1 != chg1)) {bios.SendData(cmd + " " + value.ToString() + "\n");Console.WriteLine(cmd + ":" + value.ToString());}return value;}public uint Selector(int[] pins, String cmd, int devid) {uint value = 0;uint chg = 0;uint norm = 0;uint mask = 0;for (int i = 0; i < pins.Length; i++)mask |= (uint)1 << i;for (int i = 0; i < pins.Length; i++) {chg |= (uint)(devices[devid].prev_input >> (pins[i] - i)) & mask;norm |= (uint)(devices[devid].cur_input >> (pins[i] - i)) & mask;if ((uint)((devices[devid].cur_input >> pins[i]) & 0x01) == 1) {value = (uint)i;}}// This happens when between positions of the selectorif (norm == 0)return 0;if (norm != chg) {bios.SendData(cmd + " " + value.ToString() + "\n");Console.WriteLine(cmd + ":" + value.ToString());}return value;}public void send_trackir(VirtualKeyCode key) {sendkey.Keyboard.KeyDown(VirtualKeyCode.CONTROL);System.Threading.Thread.Sleep(10);sendkey.Keyboard.KeyPress(key);sendkey.Keyboard.KeyUp(VirtualKeyCode.CONTROL);}public ushort map_ushort(ushort x, ushort in_min, ushort in_max, ushort out_min, ushort out_max) {return (ushort)((x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min);}}}