Subversion Repositories group.electronics

Rev

Blame | Last modification | View Log | RSS feed

using MCP2221;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using WindowsInput;
using WindowsInput.Native;

namespace nitdcscore{    
    class NITAHFSDevice  {
        
        DcsBios _bios;
        Bridge_mcp2221 _mcp;

        InputSimulator sendkey = new InputSimulator();

        private readonly uint pot_threshold = 5;
        private readonly Object _lockObject = new object();
        private Boolean dev_init = false;

        uint _prev_inputs = 0;
        public uint inputs { get; set; }

        ushort _prev_adc { get; set; }
        public ushort adc { get; set; }

        public NITAHFSDevice(ref DcsBios bios, Bridge_mcp2221 mcp) {
            _bios = bios;
            _mcp = mcp;

        }

        public void refresh(object sender, ElapsedEventArgs e) {
            this.GetInputs();

            if (_prev_inputs != inputs) {
                Console.WriteLine("AHFS Input: " + (inputs).ToString("X"));

                // Train - Safe - Arm
                Switch3Pos(8, 9, "AHCP_MASTER_ARM");

                // Gunarm - Safe - Arm
                Switch3Pos(10, 11, "AHCP_GUNPAC");

                // Train - Safe - Arm
                Switch3Pos(12, 13, "AHCP_LASER_ARM");
                
                // Off - On
                Switch2Pos(14, "AHCP_TGP");

                // Radar  - Delta - Baro
                Switch3Pos(0, 1, "AHCP_ALT_SCE");

                // Night - Day
                Switch2Pos(2, "AHCP_HUD_DAYNIGHT");

                //Stby - Norm
                Switch2Pos(15, "AHCP_HUD_MODE");

                // Off - On
                Switch2Pos(3, "AHCP_CICU");

                // Off - On
                Switch2Pos(4, "AHCP_JTRS");

                //Off - Test - On
                Switch3Pos(6, 5, "AHCP_IFFCC");

                //
                Switch2Pos(7, "HARS_FAST_ERECT");

                // Fuel System

                // 
                Switch2Pos(16, "FSCP_AMPL");
                // 
                Switch2Pos(24, "FSCP_BOOST_MAIN_L");
                // 
                Switch2Pos(25, "FSCP_BOOST_MAIN_R");
                // 
                Switch2Pos(26, "FSCP_BOOST_WING_L");
                // 
                Switch2Pos(27, "FSCP_BOOST_WING_R");
                // 
                Switch2Pos(28, "FSCP_CROSSFEED");
                // 
                Switch2Pos(30, "FSCP_EXT_TANKS_FUS");
                // 
                Switch2Pos(31, "FSCP_EXT_TANKS_WING");
                // 
                Switch2Pos(20, "FSCP_FD_MAIN_L", true);
                // 
                Switch2Pos(21, "FSCP_FD_MAIN_R", true);
                // 
                Switch2Pos(18, "FSCP_FD_WING_L", true);
                // 
                Switch2Pos(19, "FSCP_FD_WING_R", true);
                // 
                Switch2Pos(17, "FSCP_LINE_CHECK");
                // 
                Switch2Pos(23, "FSCP_RCVR_LEVER"); // Technically a 3pos, but 3rd not needed
                // 
                Switch2Pos(29, "FSCP_TK_GATE");


                _prev_inputs = inputs;
            }

            // Do the Refueling light adc
            ushort lowerval = 0;
            if (_prev_adc >= 5)
                lowerval = (ushort)(_prev_adc - pot_threshold);

            ushort upperval = 1023;
            if (_prev_adc <= 1018)
                upperval = (ushort)(_prev_adc + pot_threshold);

            if ((adc <= lowerval) || (adc >= upperval)) {
                _prev_adc = adc;
                //Console.WriteLine("ADC Input: " + (adc).ToString());
                ushort refuellight = map_ushort(adc, 0, 930, 0, 0xffff);
                _bios.SendData("ALCP_RCVR_LTS " + refuellight.ToString() + "\n");
            }
        }

        public uint Switch2Pos(int pin, String cmd, Boolean invert = false) {
            uint chg = (uint)(this._prev_inputs >> pin) & 0x01;
            uint norm = (uint)(this.inputs >> pin) & 0x01;
            uint value = 0;

            if ((uint)(norm) == 1) {
                value = (uint)(invert ? 0 : 1);
            }

            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, Boolean invert = false) {
            uint value = 1;
            uint chg0 = (uint)(this._prev_inputs >> pin0) & 0x01;
            uint chg1 = (uint)(this._prev_inputs >> pin1) & 0x01;
            uint nrm0 = (uint)(this.inputs >> pin0) & 0x01;
            uint nrm1 = (uint)(this.inputs >> 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 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);
        }

        public int init() {
            // Select our CDU power module
            int rslt = _mcp.SelectDevice("AHCP/FSCP Panel");
            if (rslt != 0) {
                return rslt;
            }

            // Get the initial ADC value
            this._prev_adc = this.adc = _mcp.ReadADC(1);
            

            // Enable the mcp23017
            _mcp.WriteGpio(3, 1);

            // Set io dir, pullups and rev polarity
            byte[] 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 & polarity
            _mcp.WriteI2cData(0x40, data, 5);
            data = new byte[] { 0x0c, 0xff, 0xff }; // All pullups = on
            _mcp.WriteI2cData(0x40, data, 3);

            data = new byte[] { 0x00, 0xff, 0xff, 0xff, 0xff }; // All inputs & polarity
            _mcp.WriteI2cData(0x42, data, 5);
            data = new byte[] { 0x0c, 0xff, 0xff }; // All pullups = on
            _mcp.WriteI2cData(0x42, data, 3);

            this.GetInputs();
            this._prev_inputs = this.inputs;

            this.dev_init = true;
            return 0;
        }

        public void Enable() {
            if (!this.dev_init)
                this.init();

        }
        public void Disable() {

        }

        public void GetInputs() {         
            
            lock (_lockObject) {
                this.adc = _mcp.ReadADC(1);
            }

            byte[] data;
            data = new byte[] { 0x12 }; // Select GPIOA register
            _mcp.WriteI2cData(0x40, data, 1);

            data = new byte[] { 0x00, 0x00 }; // Read two bytes
            int rslt = _mcp.ReadI2CData(0x41, ref data, 2);
            
            this.inputs = (uint)data[0] << 24;
            this.inputs |= (uint)data[1] << 16;

            data = new byte[] { 0x12 }; // Select GPIOA register
            _mcp.WriteI2cData(0x42, data, 1);

            data = new byte[] { 0x00, 0x00 }; // Read two bytes
            rslt = _mcp.ReadI2CData(0x43, ref data, 2);

            this.inputs += (uint)data[0] << 8;
            this.inputs |= (uint)data[1];


        }
    }
}