using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace Fusion_Control_Centre_UberMDX { public partial class MainMDX : Form { #region FusionUSB DLL Calls public static class FusionUSB { [System.Runtime.InteropServices.DllImport("FusionUSB.dll")] public static extern bool FUSB_Initialize(ref UInt32 pFusionUSB, String deviceID, UInt32 instanceNumber); [System.Runtime.InteropServices.DllImport("FusionUSB.dll")] public static extern bool FUSB_Receive(UInt32 pFusionUSB, byte[] buffer); [System.Runtime.InteropServices.DllImport("FusionUSB.dll")] public static extern bool FUSB_Send(UInt32 pFusionUSB, byte[] buffer); [System.Runtime.InteropServices.DllImport("FusionUSB.dll")] public static extern UInt32 FUSB_Free(ref UInt32 pFusionUSB); [System.Runtime.InteropServices.DllImport("FusionUSB.dll")] public static extern bool FUSB_printf(UInt32 pFusionUSB); [System.Runtime.InteropServices.DllImport("FusionUSB.dll")] public static extern UInt32 FUSB_GetWinUSBerror(UInt32 pFusionUSB); [System.Runtime.InteropServices.DllImport("FusionUSB.dll")] public static extern UInt32 FUSB_GetFUSBstatus(UInt32 pFusionUSB); [System.Runtime.InteropServices.DllImport("FusionUSB.dll")] public static extern String FUSB_GetDeviceInstanceID(UInt32 pFusionUSB); } #endregion #region USB Global Constants and Variables UInt32 instanceNumber = 0; const UInt32 INVALID_HANDLE_VALUE = 0xFFFFFFFF; const UInt32 NULL = 0; UInt32 pFusionUSB = NULL; byte[] ReadBuffer = new byte[64]; byte[] WriteBuffer = new byte[64]; const UInt32 FUSB_OK = 0; const UInt32 FUSB_DEVICE_NOT_FOUND = 13; const UInt32 MAX_DEVICES = 100; string deviceID = @"USB\VID_04D8&PID_000C\"; bool flip_et_flop = true; #endregion #region Output Byte Stream public bool WriteTheStream(byte[] DataToSend) { if (pFusionUSB != NULL) { bool suc = FusionUSB.FUSB_Send(pFusionUSB, DataToSend); return suc; } else { pFusionUSB = NULL; return false; } } #endregion #region Input Byte Stream public byte[] ReadTheStream() { if (pFusionUSB != NULL) { if (FusionUSB.FUSB_Receive(pFusionUSB, ReadBuffer)) { return ReadBuffer; } else { pFusionUSB = NULL; return null; } } else { return null; } } #endregion #region Free USB Handle public UInt32 FreeTheDevice() { UInt32 sucUINT; sucUINT = FusionUSB.FUSB_Free(ref pFusionUSB); if (sucUINT == 0) { return sucUINT; } return sucUINT; } #endregion #region Initialize USB Handle public bool InitializeTheDevice() { try { return FusionUSB.FUSB_Initialize(ref pFusionUSB, deviceID, instanceNumber); } catch (Exception e) { return false; } } #endregion #region Change the USB Device public bool ChangeTheDevice(string newDeviceID, string newHumanName) { bool _isVirtual = VirtualBrainStruct.isAVirtualBrain(newHumanName); try { if (deviceID.ToLower().Equals(newDeviceID.ToLower()) && pFusionUSB != NULL) { //Already Initialized, so keep it open return true; } if (pFusionUSB != NULL) { //There is already something connected so free it first if (FreeTheDevice() != 0) { return _isVirtual || false; } } deviceID = newDeviceID; if (InitializeTheDevice()) { //if it all checks out return true; } uint errorUINT = FreeTheDevice(); return false || _isVirtual; } catch (ArgumentException) { } return _isVirtual || false; ; } #endregion #region Get Output Stream Ready to be Exported public void USB_OutputSteps() { USB_OutputSteps(false); } public void USB_OutputSteps(bool DontUpdateParts) { flip_et_flop = !flip_et_flop; //Keep the PIC alive foreach (BrainID CurrentBrain in AllBrains) { if (ChangeTheDevice(CurrentBrain.instanceID, CurrentBrain.humanName.ToLower())) { WriteBuffer = new byte[64]; WriteBuffer[61] = (byte)255; //Initialize PIC bit foreach (DigitalOutputChannel DOC in AllDigitalOutputs) { string tempoutstring = ""; #region Check it is the Correct BrainID if (DOC.BrainID != CurrentBrain.humanName) { continue; } #endregion #region Output Timer Shutoff tempoutstring = DecimalToBase(DOC.TimerValue, 2); tempoutstring = tempoutstring.PadLeft(6, '0'); tempoutstring = tempoutstring.Substring(tempoutstring.Length - 6); #endregion #region Keep PIC Alive if (flip_et_flop) { tempoutstring += "1"; } else { tempoutstring += "0"; } #endregion if (!DontUpdateParts) { #region Tally the Votes int[] myVote = { 0, 0, 0 }; DOC.PreviousState = DOC.CurrentState; foreach (LogicalVote individualVote in DOC.ShouldIChangeState) { myVote[Vote_Priority_To_Integer(individualVote.MyLogicalPriority)] += Vote_Opinion_To_Integer(individualVote.MyLogicalOpinion); } DOC.ShouldIChangeState.Clear(); if (myVote[2] != 0) { if (myVote[2] > 0) { DOC.CurrentState = true; } else { DOC.CurrentState = false; } } else if (myVote[1] != 0) { if (myVote[1] > 0) { DOC.CurrentState = true; } else { DOC.CurrentState = false; } } else if (myVote[0] != 0) { if (myVote[0] > 0) { DOC.CurrentState = true; } else { DOC.CurrentState = false; } } #endregion } #region On or Off if (DOC.CurrentState) { tempoutstring += "1"; } else { tempoutstring += "0"; } #endregion byte OutputByte = (byte)BaseToDecimal(tempoutstring, 2); WriteBuffer[DOC.Port] = OutputByte; } #region If Transmit Error if (pFusionUSB != NULL) { if (!WriteTheStream(WriteBuffer)) { //Error Writing to the Brain } } #endregion } } if (DoneChangingOutputState != null) { DoneChangingOutputState(); } } #endregion #region Retrieve and Interpret Input Stream public void USB_InputSteps() { foreach (BrainID CurrentBrain in AllBrains) { if (ChangeTheDevice(CurrentBrain.instanceID, CurrentBrain.humanName.ToLower())) { if (pFusionUSB != NULL) { ReadBuffer = ReadTheStream(); } #region Error Reading Byte Stream if (ReadBuffer == null) { return; } if (VirtualBrainStruct.isAVirtualBrain(CurrentBrain.humanName)) { bool skipUpdating = false; VirtualBrainStruct _daBrain = new VirtualBrainStruct(); foreach (VirtualBrainStruct _vbs in DEBUG_VirtualBrainList) { if (_vbs._human.ToLower() == CurrentBrain.humanName.ToLower()) { if (_vbs._Form._OverrideAnalogues) { skipUpdating = true; _daBrain = _vbs; break; } } } if (skipUpdating && _daBrain._Form != null) { foreach (AnalogueInputChannel _aic in AllAnalogueInputs) { if (_aic.BrainID.ToLower() != CurrentBrain.humanName.ToLower()) { continue; } double _theDoubleOfDoom = 0.0; if (double.TryParse(_daBrain._Form._AnalogueOverrideTextboxes[_aic.Port].Text, out _theDoubleOfDoom)) { _aic.HistoryValues.Add(_theDoubleOfDoom); if (_aic.HistoryValues.Count > _aic.maximumHistory) { _aic.HistoryValues.RemoveAt(0); } _aic.CurrentValue = 0; if (_aic.autoAverage && _aic.HistoryValues.Count > 0) { foreach (double history_value_dbl in _aic.HistoryValues) { _aic.CurrentValue += history_value_dbl; } _aic.CurrentValue /= _aic.HistoryValues.Count; } else { _aic.CurrentValue = _theDoubleOfDoom; } } } continue; } } #endregion #region Where the Analogue and Digital Input Portions of the Stream Exist const int AIBeginIndex = 12; const int DIBeginIndex = 32; #endregion #region Input Buffers double[] AnalogueInputBuffer = new double[10]; bool[] DigitalInputBuffer = new bool[4]; #endregion #region Parse Analogue Input Values to Buffer for (int i = AIBeginIndex; i < AIBeginIndex + (10 * 2); i += 2) { int InputBinary1 = (int)ReadBuffer[i]; int InputBinary2 = (int)ReadBuffer[i + 1]; string InputStringBinary1 = DecimalToBase(InputBinary1, 2); string InputStringBinary2 = DecimalToBase(InputBinary2, 2); InputStringBinary1 = InputStringBinary1.PadLeft(8, '0'); InputStringBinary2 = InputStringBinary2.PadLeft(8, '0'); InputStringBinary2 = InputStringBinary2.Substring(0, 2); string InputStringBinaryCombined = InputStringBinary1 + InputStringBinary2; double AnalogueVoltageInputDouble = (double)BaseToDecimal(InputStringBinaryCombined, 2); AnalogueVoltageInputDouble = (AnalogueVoltageInputDouble / 1023) * 5; AnalogueInputBuffer[(i - AIBeginIndex) / 2] = AnalogueVoltageInputDouble; } #endregion #region Update Each Analogue Input's Value foreach (AnalogueInputChannel AIC in AllAnalogueInputs) { if (AIC.BrainID != CurrentBrain.humanName) { continue; } if (AIC.Port < 0 || AIC.Port > 10) { continue; } AIC.HistoryValues.Add(AnalogueInputBuffer[AIC.Port]); if (AIC.HistoryValues.Count > AIC.maximumHistory) { AIC.HistoryValues.RemoveAt(0); } AIC.CurrentValue = 0; if (AIC.autoAverage && AIC.HistoryValues.Count > 0) { foreach (double history_value_dbl in AIC.HistoryValues) { AIC.CurrentValue += history_value_dbl; } AIC.CurrentValue /= AIC.HistoryValues.Count; } else { AIC.CurrentValue = AnalogueInputBuffer[AIC.Port]; } } #endregion #region Get the Individual Bits for Each Digital Input string DigitalInputString = DecimalToBase((int)ReadBuffer[DIBeginIndex], 2); DigitalInputString = DigitalInputString.PadLeft(8, '0'); char[] DigitalInputCharacterArray = DigitalInputString.ToCharArray(); int[] DigitalInputBitPositions = { 1, 2, 3, 4 }; #endregion #region Parse Each Digital Input's Value for (int i = 0; i < 4; i++) { if (DigitalInputCharacterArray[DigitalInputBitPositions[i]].Equals('1')) { //The Digital Input is On DigitalInputBuffer[i] = true; } else { //The Digital Input is Off DigitalInputBuffer[i] = false; } } #endregion #region Update Each Digital Input's Value foreach (DigitalInputChannel DIC in AllDigitalInputs) { if (DIC.BrainID != CurrentBrain.humanName) { continue; } if (DIC.Port < 0 || DIC.Port > 4) { continue; } DIC.PreviousState = DIC.CurrentState; DIC.CurrentState = DigitalInputBuffer[DIC.Port]; } #endregion } else { //Error Connecting to the Device } } } #endregion #region Base Conversion Constants const int base10 = 10; char[] cHexa = new char[] { 'A', 'B', 'C', 'D', 'E', 'F' }; int[] iHexaNumeric = new int[] { 10, 11, 12, 13, 14, 15 }; int[] iHexaIndices = new int[] { 0, 1, 2, 3, 4, 5 }; const int asciiDiff = 48; #endregion #region Convert Decimal to Binary or Hexadecimal public string DecimalToBase(int iDec, int numbase) { string strBin = ""; int[] result = new int[32]; int MaxBit = 32; for (; iDec > 0; iDec /= numbase) { int rem = iDec % numbase; result[--MaxBit] = rem; } for (int i = 0; i < result.Length; i++) if ((int)result.GetValue(i) >= base10) strBin += cHexa[(int)result.GetValue(i) % base10]; else strBin += result.GetValue(i); strBin = strBin.TrimStart(new char[] { '0' }); return strBin; } #endregion #region Convert Binary or Hexadecimal to Decimal public int BaseToDecimal(string sBase, int numbase) { int dec = 0; int b; int iProduct = 1; string sHexa = ""; if (numbase > base10) for (int i = 0; i < cHexa.Length; i++) sHexa += cHexa.GetValue(i).ToString(); for (int i = sBase.Length - 1; i >= 0; i--, iProduct *= numbase) { string sValue = sBase[i].ToString(); if (sValue.IndexOfAny(cHexa) >= 0) b = iHexaNumeric[sHexa.IndexOf(sBase[i])]; else b = (int)sBase[i] - asciiDiff; dec += (b * iProduct); } return dec; } #endregion } }