diff options
Diffstat (limited to 'ldmicro/components/spdt.cpp')
-rw-r--r-- | ldmicro/components/spdt.cpp | 390 |
1 files changed, 390 insertions, 0 deletions
diff --git a/ldmicro/components/spdt.cpp b/ldmicro/components/spdt.cpp new file mode 100644 index 0000000..e30a732 --- /dev/null +++ b/ldmicro/components/spdt.cpp @@ -0,0 +1,390 @@ +/* SPDT component file +* Code version: 2.0 +* Version description: Adds latching functionality to component +* Version steability: +* GUI -> Stable +* Functionality -> No known bugs. +* Bugs: +* 1. - +* +*/ + +///Includes +#include <wincodec.h> +#include <stdio.h> +//#include <string.h> +#include <commctrl.h> +#include <Windowsx.h> + +#include "componentstructs.h" +#include "componentfunctions.h" +#include "componentimages.h" +#include "components.h" + +///Window handles +static HWND StateOut1; +static HWND StateOut2; +static HWND ModeLatched; +static HWND ModeTemp; +HWND* SettingsDialogSPDT; + +///Global variables +enum SPDT_Pins {in = 0, out1, out2}; + +///Function definitions +void SetSpdtIds(int* id, void* ComponentAddress) +{ + SpdtStruct* s = (SpdtStruct*)ComponentAddress; + s->PinId[in] = *id++; + s->PinId[out1] = *id++; + s->PinId[out2] = *id++; +} + +int InitSpdt(void * ComponentAddress) +{ + SpdtStruct* s = (SpdtStruct*)ComponentAddress; + s->image = SPDT_1; + s->latched = TRUE; + s->NO1 = TRUE; + s->Volt[in] = V_OPEN; + s->Volt[out1] = V_OPEN; + s->Volt[out2] = V_OPEN; + + return SPDT_1; +} + +void MakeSettingsDialogSPDT() +{ + ///Switch action mode + HWND InitLatched = CreateWindowEx(0, WC_BUTTON, ("Action mode"), + WS_CHILD | BS_GROUPBOX | WS_VISIBLE | WS_TABSTOP, + 7, 3, 120, 65, *SettingsDialogSPDT, NULL, NULL, NULL); + FontNice(InitLatched); + + ModeLatched = CreateWindowEx(0, WC_BUTTON, ("Latched"), + WS_CHILD | BS_AUTORADIOBUTTON | WS_TABSTOP | WS_VISIBLE | WS_GROUP, + 16, 21, 100, 20, *SettingsDialogSPDT, NULL, NULL, NULL); + FontNice(ModeLatched); + + ModeTemp = CreateWindowEx(0, WC_BUTTON, ("Temporary"), + WS_CHILD | BS_AUTORADIOBUTTON | WS_TABSTOP | WS_VISIBLE, + 16, 41, 100, 20, *SettingsDialogSPDT, NULL, NULL, NULL); + FontNice(ModeTemp); + + ///Switch initial status + HWND InitOut = CreateWindowEx(0, WC_BUTTON, ("Initial output"), + WS_CHILD | BS_GROUPBOX | WS_VISIBLE | WS_TABSTOP, + 140, 3, 120, 65, *SettingsDialogSPDT, NULL, NULL, NULL); + FontNice(InitOut); + + StateOut1 = CreateWindowEx(0, WC_BUTTON, ("Output 1"), + WS_CHILD | BS_AUTORADIOBUTTON | WS_TABSTOP | WS_VISIBLE | WS_GROUP, + 149, 21, 100, 20, *SettingsDialogSPDT, NULL, NULL, NULL); + FontNice(StateOut1); + + StateOut2 = CreateWindowEx(0, WC_BUTTON, ("Output 2"), + WS_CHILD | BS_AUTORADIOBUTTON | WS_TABSTOP | WS_VISIBLE, + 149, 41, 100, 20, *SettingsDialogSPDT, NULL, NULL, NULL); + FontNice(StateOut2); +} + +void LoadSettings(SpdtStruct* s) +{ + if (s->latched) + Button_SetCheck(ModeLatched, BST_CHECKED); + else + Button_SetCheck(ModeTemp, BST_CHECKED); + if (s->NO1) + Button_SetCheck(StateOut1, BST_CHECKED); + else + Button_SetCheck(StateOut2, BST_CHECKED); +} + +BOOL SaveSettings(SpdtStruct* s, void* ImageLocation) +{ + if (Button_GetState(ModeLatched) == BST_CHECKED) + s->latched = TRUE; + else if (Button_GetState(ModeTemp) == BST_CHECKED) + s->latched = FALSE; + else + { + MessageBox(*SettingsDialogSPDT, + ("Incomplete"), ("Warning"), MB_OK | MB_ICONWARNING); + return FALSE; + } + + if (Button_GetState(StateOut1) == BST_CHECKED) + s->NO1 = TRUE; + else if (Button_GetState(StateOut2) == BST_CHECKED) + s->NO1 = FALSE; + else + { + MessageBox(*SettingsDialogSPDT, + ("Incomplete"), ("Warning"), MB_OK | MB_ICONWARNING); + return FALSE; + } + + + if (s->NO1) + s->image = SPDT_1; + else + s->image = SPDT_2; + + SetImage(s->image, ImageLocation); + RefreshImages(); + + return TRUE; +} + +void SpdtSettingsDialog(void* ComponentAddress, void* ImageLocation) +{ + SpdtStruct* s = (SpdtStruct*)ComponentAddress; + BOOL exitStatus; + + //Create dialog window instance + SettingsDialogSPDT = CreateDialogWindow("SPDT Settings Dialog", 100, 100, 263, 145, STYLE_VERTICAL); + + //Make the settings dialog + MakeSettingsDialogSPDT(); + + //Load settings + LoadSettings(s); + + //Show dialog window + ShowDialogWindow(); + + exitStatus = ProcessDialogWindow(); + while (exitStatus == FALSE) + { + exitStatus = SaveSettings(s, ImageLocation); + if (exitStatus == TRUE) + break; + else + { + exitStatus = TRUE; + exitStatus = ProcessDialogWindow(); + } + } + + DestroyWindow(*SettingsDialogSPDT); + +} + +//Perform a static check and equalise the voltage on all pins that are connected to SPDT at runtime +void EqualiseStaticVoltageSPDT(void* ComponentAdderss) +{ + SpdtStruct* s = (SpdtStruct*)ComponentAdderss; + + ///Check if input and output 1 are connected + if (s->NO1) + { + ///If the input pin is connected to output 1 then output 2 will be open + s->Volt[out2] = VoltChange(s->PinId[out2], out2, ComponentAdderss, V_OPEN); + + ///Get voltages at the connected pins + double volt1 = VoltRequest(s->PinId[in], ComponentAdderss); + double volt2 = VoltRequest(s->PinId[out1], ComponentAdderss); + + ///If either pin is grounded then all pins are set to GND + if (volt1 == GND || volt2 == GND) + { + s->Volt[out1] = VoltChange(s->PinId[out1], out1, ComponentAdderss, GND); + s->Volt[in] = VoltChange(s->PinId[in], in, ComponentAdderss, GND); + } + ///If volt1 is set as open + else if (volt1 == V_OPEN) + s->Volt[in] = VoltChange(s->PinId[in], in, ComponentAdderss, volt2); + ///If volt2 is set as open + else if (volt2 == V_OPEN) + s->Volt[out1] = VoltChange(s->PinId[out1], out1, ComponentAdderss, volt1); + ///If no pin is grounded then all pins are set to the max voltage of the pins + else + { + s->Volt[out1] = VoltChange(s->PinId[out1], out1, ComponentAdderss, max(volt1, volt2)); + s->Volt[in] = VoltChange(s->PinId[in], in, ComponentAdderss, max(volt1, volt2)); + } + } + ///If input and output 2 are connected + else + { + ///If the input pin is connected to output 2 then output 1 will be open + s->Volt[out1] = VoltChange(s->PinId[out1], out1, ComponentAdderss, V_OPEN); + + ///Get voltages at the connected pins + double volt1 = VoltRequest(s->PinId[0], ComponentAdderss); + double volt2 = VoltRequest(s->PinId[out2], ComponentAdderss); + + ///If either pin is grounded then all pins are set to GND (Static event) + if (volt1 == GND || volt2 == GND) + { + s->Volt[out2] = VoltChange(s->PinId[out2], out2, ComponentAdderss, GND); + s->Volt[in] = VoltChange(s->PinId[in], in, ComponentAdderss, GND); + } + ///If volt1 is set as open + else if (volt1 == V_OPEN) + s->Volt[in] = VoltChange(s->PinId[in], in, ComponentAdderss, volt2); + ///If volt2 is set as open + else if (volt2 == V_OPEN) + s->Volt[out2] = VoltChange(s->PinId[out2], out2, ComponentAdderss, volt1); + ///If no pin is grounded then all pins are set to the max voltage of the pins (Dynamic event) + else + { + s->Volt[out2] = VoltChange(s->PinId[out2], out2, ComponentAdderss, max(volt1, volt2)); + s->Volt[in] = VoltChange(s->PinId[in], in, ComponentAdderss, max(volt1, volt2)); + } + } +} + +//Dynamically check and equalise the voltage on all pins that are connected to SPDT at runtime +double EqualiseRuntimeVoltageSPDT(void* ComponentAdderss, int index, double volt) +{ + SpdtStruct* s = (SpdtStruct*)ComponentAdderss; + + ///Check if input and output 1 are connected + if (s->NO1) + { + ///If the input pin is connected to output 1 then output 2 will be open + if (index == out2) + s->Volt[out2] = V_OPEN; + else + s->Volt[out2] = VoltChange(s->PinId[out2], out2, ComponentAdderss, V_OPEN); + + double volt1; + double volt2; + + ///Get voltages at the connected pins + if (index == in) + { + volt1 = volt; + volt2 = VoltRequest(s->PinId[out1], ComponentAdderss); + } + else if (index == out1) + { + volt1 = VoltRequest(s->PinId[in], ComponentAdderss); + volt2 = volt; + } + else + { + volt1 = VoltRequest(s->PinId[in], ComponentAdderss); + volt2 = VoltRequest(s->PinId[out1], ComponentAdderss); + } + + ///If either pin is grounded then all pins are set to GND + if (volt1 == GND || volt2 == GND) + { + s->Volt[out1] = VoltChange(s->PinId[out1], out1, ComponentAdderss, GND); + s->Volt[in] = VoltChange(s->PinId[in], in, ComponentAdderss, GND); + } + ///If volt1 is set as open + else if (volt1 == V_OPEN) + s->Volt[in] = VoltChange(s->PinId[in], in, ComponentAdderss, volt2); + ///If volt2 is set as open + else if (volt2 == V_OPEN) + s->Volt[out1] = VoltChange(s->PinId[out1], out1, ComponentAdderss, volt1); + ///If no pin is grounded then all pins are set to the max voltage of the pins + else + { + s->Volt[out1] = VoltChange(s->PinId[out1], out1, ComponentAdderss, max(volt1, volt2)); + s->Volt[in] = VoltChange(s->PinId[in], in, ComponentAdderss, max(volt1, volt2)); + } + } + ///If input and output 2 are connected + else + { + ///If the input pin is connected to output 2 then output 1 will be open + s->Volt[out1] = VoltChange(s->PinId[out1], out1, ComponentAdderss, V_OPEN); + + double volt1; + double volt2; + + ///Get voltages at the connected pins + if (index == in) + { + volt1 = volt; + volt2 = VoltRequest(s->PinId[out2], ComponentAdderss); + } + else if (index == out1) + { + volt1 = VoltRequest(s->PinId[in], ComponentAdderss); + volt2 = volt; + } + else + { + volt1 = VoltRequest(s->PinId[in], ComponentAdderss); + volt2 = VoltRequest(s->PinId[out2], ComponentAdderss); + } + + ///If either pin is grounded then all pins are set to GND (Static event) + if (volt1 == GND || volt2 == GND) + { + s->Volt[out2] = VoltChange(s->PinId[out2], out2, ComponentAdderss, GND); + s->Volt[in] = VoltChange(s->PinId[in], in, ComponentAdderss, GND); + } + ///If volt1 is set as open + else if (volt1 == V_OPEN) + s->Volt[in] = VoltChange(s->PinId[in], in, ComponentAdderss, volt2); + ///If volt2 is set as open + else if (volt2 == V_OPEN) + s->Volt[out2] = VoltChange(s->PinId[out2], out2, ComponentAdderss, volt1); + ///If no pin is grounded then all pins are set to the max voltage of the pins (Dynamic event) + else + { + s->Volt[out2] = VoltChange(s->PinId[out2], out2, ComponentAdderss, max(volt1, volt2)); + s->Volt[in] = VoltChange(s->PinId[in], in, ComponentAdderss, max(volt1, volt2)); + } + } + + return s->Volt[index]; +} + +double SpdtVoltChanged(void * ComponentAddress, BOOL SimulationStarted, int index, double Volt, int Source, void * ImageLocation) +{ + if (SimulationStarted) + return EqualiseRuntimeVoltageSPDT(ComponentAddress, index, Volt); + + return Volt; +} + +void ToggleState(SpdtStruct* s, void* ImageLocation) +{ + s->image = (s->image == SPDT_1) ? SPDT_2 : SPDT_1; + s->NO1 = (s->NO1 == TRUE) ? FALSE : TRUE; + SetImage(s->image, ImageLocation); + RefreshImages(); +} + +void HandleSpdtEvent(void * ComponentAddress, int Event, BOOL SimulationStarted, void * ImageLocation, UINT ImageId, HWND * h) +{ + SpdtStruct* s = (SpdtStruct*)ComponentAddress; + + if (SimulationStarted) + { + switch (Event) + { + case EVENT_MOUSE_DOWN: + ToggleState(s, ImageLocation); + EqualiseStaticVoltageSPDT(ComponentAddress); + break; + case EVENT_MOUSE_UP: + if (!s->latched) + { + ToggleState(s, ImageLocation); + EqualiseStaticVoltageSPDT(ComponentAddress); + } + break; + default: + break; + } + } + else + { + switch (Event) + { + case EVENT_MOUSE_DBLCLICK: + SpdtSettingsDialog(ComponentAddress, ImageLocation); + break; + default: + break; + } + } +}
\ No newline at end of file |