aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Embedded_SW/Embedded/Modules
diff options
context:
space:
mode:
authorShlomo Hecht <shlomo@twine-s.com>2018-03-06 12:09:02 +0200
committerShlomo Hecht <shlomo@twine-s.com>2018-03-06 12:09:02 +0200
commitfb2d080fbbcea3a91e598b4ea8837a230de6a319 (patch)
tree6b3ce09a252d2ebab8189a92b3326ffbba6dbe4b /Software/Embedded_SW/Embedded/Modules
parentd734bb5cf08ba2433b74fc86a8858d2437d1a237 (diff)
downloadTango-fb2d080fbbcea3a91e598b4ea8837a230de6a319.tar.gz
Tango-fb2d080fbbcea3a91e598b4ea8837a230de6a319.zip
A new forlder for embedded software in our common structure
Diffstat (limited to 'Software/Embedded_SW/Embedded/Modules')
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Control/PIDAlgo.c39
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Control/PIDAlgo.h18
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Control/control.c333
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Control/control.h30
-rw-r--r--Software/Embedded_SW/Embedded/Modules/General/GeneralHardware.c348
-rw-r--r--Software/Embedded_SW/Embedded/Modules/General/GeneralHardware.h313
-rw-r--r--Software/Embedded_SW/Embedded/Modules/General/process.c121
-rw-r--r--Software/Embedded_SW/Embedded/Modules/General/process.h16
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Heaters/Heaters.h62
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_bit.c0
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_ex.h9
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_init.c154
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_maint.c0
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_print.c247
-rw-r--r--Software/Embedded_SW/Embedded/Modules/IDS/IDS.h25
-rw-r--r--Software/Embedded_SW/Embedded/Modules/IDS/IDS_BIT.c0
-rw-r--r--Software/Embedded_SW/Embedded/Modules/IDS/IDS_ex.h0
-rw-r--r--Software/Embedded_SW/Embedded/Modules/IDS/IDS_init.c46
-rw-r--r--Software/Embedded_SW/Embedded/Modules/IDS/IDS_maint.c0
-rw-r--r--Software/Embedded_SW/Embedded/Modules/IDS/IDS_print.c43
-rw-r--r--Software/Embedded_SW/Embedded/Modules/IDS/MixerHandler.c37
-rw-r--r--Software/Embedded_SW/Embedded/Modules/IDS/MixerHandler.h17
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Calculate.c39
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Calculate.h8
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Container.c125
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Container.h7
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Stubs_Handler/DataDef.h71
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Progress.c48
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Progress.h7
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_Cartridge.c128
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_Cartridge.h9
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_Dispenser.c72
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_Dispenser.h9
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_ExtFlash.c160
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_ExtFlash.h8
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_GPIO.c947
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_GPIO.h12
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_Heater.c74
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_Heater.h6
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_MotorEncoder.c84
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_MotorEncoder.h6
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_OptLimitSwitch.c70
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_OptLimitSwitch.h6
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_Status.c58
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_Status.h3
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_SteperMotor.c79
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_SteperMotor.h7
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_Valve.c60
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_Valve.h6
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Stubs_Handler/User_Leds.c68
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Stubs_Handler/User_Leds.h23
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Thread/Thread.h55
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Thread/Thread_BIT.c0
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Thread/Thread_ex.h0
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Thread/Thread_init.c94
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Thread/Thread_maint.c0
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Thread/Thread_print.c326
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Waste/Waste.h0
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Waste/Waste_BIT.c0
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Waste/Waste_ex.h0
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Waste/Waste_init.c0
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Waste/Waste_maint.c0
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Waste/Waste_print.c0
63 files changed, 4533 insertions, 0 deletions
diff --git a/Software/Embedded_SW/Embedded/Modules/Control/PIDAlgo.c b/Software/Embedded_SW/Embedded/Modules/Control/PIDAlgo.c
new file mode 100644
index 000000000..fbea57f7d
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Control/PIDAlgo.c
@@ -0,0 +1,39 @@
+
+#include "PIDAlgo.h"
+
+float PIDAlgorithmCalculation(uint32_t _setPoint,uint32_t _mesuredParam , PID_Config_Params *params, float *_pre_error, float *_integral)
+{
+ float error;
+ float derivative;
+ float output;
+
+ //Calculate P,I,D
+ error = _setPoint - _mesuredParam;
+
+ //In case of error too small then stop integration
+ if(abs(error) > params->epsilon)
+ {
+ *_integral = *_integral + error*params->dt;
+ }
+
+ derivative = (error - *_pre_error)/params->dt;
+
+ output = params->Kp*error + params->Ki**_integral + params->Kd*derivative;
+
+ //Saturation Filter
+ if(output > params->MAX)
+ {
+ output = params->MAX;
+ }
+ else if(output < params->MIN)
+ {
+ output = params->MIN;
+ }
+
+ //Update error
+ *_pre_error = error;
+
+ return output;
+}
+
+
diff --git a/Software/Embedded_SW/Embedded/Modules/Control/PIDAlgo.h b/Software/Embedded_SW/Embedded/Modules/Control/PIDAlgo.h
new file mode 100644
index 000000000..5f8f4dfe6
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Control/PIDAlgo.h
@@ -0,0 +1,18 @@
+
+#ifndef MODULES_PIDALGO_H_
+#define MODULES_PIDALGO_H_
+#include <stdint.h>
+
+typedef struct
+{
+ float epsilon;
+ float dt;
+ float MAX;
+ float MIN;
+ float Kp;
+ float Kd;
+ float Ki;
+}PID_Config_Params;
+float PIDAlgorithmCalculation(uint32_t _setPoint,uint32_t _mesuredParam , PID_Config_Params *params, float *_pre_error, float *_integral);
+
+#endif /* MODULES_PIDALGO_H_ */
diff --git a/Software/Embedded_SW/Embedded/Modules/Control/control.c b/Software/Embedded_SW/Embedded/Modules/Control/control.c
new file mode 100644
index 000000000..8f389855e
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Control/control.c
@@ -0,0 +1,333 @@
+/************************************************************************************************************************
+ * control.c
+ * Control module
+ *
+ * The control module is hardware agnostic, not related to a specific hardware module, to enable it to deal with hardware and system changes easily.
+ * The control module contains a high priority task that connects the hardware drivers
+ * below to the control algorithms of the high level system modules above.
+ *
+ * The control task is invoked by a message from a 1 millisecond timer interrupt.
+ * The module is based on system components registered in the control module, supplying callback hooks for information gathering and distribution.
+ * All control clients (drivers and modules) will not perform long procedures that will block the control task.
+ *
+ * Control interfaces:
+ * System Devices list:
+ *
+ * All control system input devices will be listed in a system-shared enumareted list, to create a common language between the modules and the drivers.
+ * (The list will include all hardware devices, but for this module only control input devices are valid)
+ * Drivers:
+ * Device registration: a driver that initializes a control input device will call the ControlDeviceRegister function with the deviceId,
+ * and a control callback hook. This callback is called with a deviceId as the parameter, and returns an unsigned 32bit integer
+ * as a read value and a call status. The callback will be a non-blocking call, and will indicate in the status value if the data is valid.
+ *
+ * It is the responsibility of the device driver to update the control information according to the module hardware requirements.
+ * If the polling of the information is immediate, it can be collected at the callback call (e.g. local GPI).
+ *
+ * Module registration – control: a module is registering to receive the value of the input from a specific device.
+ * The module indicates what will be the desired frequency of the device polling (in milliseconds).
+ * It supplies a callback routine that will receive the deviceId, the control value status and the control value.
+ * The callback will be a non-blocking call.
+ * The polling frequency is one of a specific list of frequencies: 1/10/100/1000 Hz. (others - TBD)
+ *
+ *
+ * Registering a request for control information from a device that is not registered will be rejected.
+ * The device registration process must be performed before module registration process.
+ *
+ * Unregistering: when control information is not needed, the module will unregister the device polling request from the control module.
+ * There is a separate call for control hooks and for report hooks.
+ * The unregistering command contains the callback function pointer, to enable distribution of control
+ * information of the same device to more than one destination.
+ *
+ **************************************************************************************************************************/
+
+////////////////////////////////State machine operation////////////////////////////////////
+//the state machine operation is used to operate in runtime correct profile flow execution
+//by recieved esign flow of the user from the UI
+///////////////////////////////////////////////////////////////////////////////////////////
+#include "include.h"
+#include "Modules/General/GeneralHardware.h"
+
+#include <driverlib/timer.h>
+#include <inc/hw_ints.h>
+
+#include "drivers/adc_sampling/adc.h"
+#include "control.h"
+/******************** Definitions ********************************************/
+#define INVALID_MSG_ID 0xFFFF
+#define MAX_TANGO_CONTROL_DEVICES 200
+/******************** STRUCTURES AND ENUMs ********************************************/
+typedef struct
+{
+ uint32_t PartId; // the identity of the inspected/controlled part in the Devices enum.
+ DeviceDataFunction Callback;
+ uint32_t lastStatus;
+}DriverDeviceStruc;
+DriverDeviceStruc DevicesArray[MAX_PORT_ENUM];
+
+
+typedef struct
+{
+ uint32_t PartId; // the identity of the inspected/controlled part in the Devices enum.
+ bool ControlActive;
+ uint32_t Parameter;
+ DataReadCBFunction ControlDataReadPtr;
+ ControlCBFunction ControlCallbackPtr;
+ CTRL_TIMING_ENUM ControlTiming;
+}ControlDeviceStruc;
+
+typedef enum
+{
+ OneMillisec,
+}controlMessages;
+
+typedef struct ControlMessage{
+ uint16_t messageId;
+ uint16_t msglen;
+ uint32_t tick;
+ uint8_t messageData[20];
+}ControlMessageStruc;
+/******************** GLOBAL PARAMETERS ********************************************/
+Mailbox_Handle ControlMsgQ = NULL;
+bool ControlRestart;
+static GateMutex_Handle gateControlDB;
+
+ControlDeviceStruc ControlArray[MAX_TANGO_CONTROL_DEVICES];
+uint32_t ControlDatalog[MAX_TANGO_CONTROL_DEVICES];
+uint32_t Control_timerBase = TIMER0_BASE; //Timer handle
+/******************** Functions ********************************************/
+void OneMilliSecondFunction(UArg arg0);
+
+//**********************************************************************
+/******************** CODE ********************************************/
+//**********************************************************************
+
+void ControlInit(void)
+{
+ int Device_i;
+ Error_Block eb;
+
+ ControlMsgQ = Mailbox_create(sizeof(ControlMessageStruc), 20, NULL,NULL);
+
+ ControlRestart = false;
+
+ memset(ControlDatalog,0,sizeof(uint32_t)*MAX_TANGO_CONTROL_DEVICES);
+
+ for (Device_i = 0; Device_i < MAX_TANGO_CONTROL_DEVICES; Device_i++)
+ {
+ DevicesArray[Device_i].Callback = NULL;
+ DevicesArray[Device_i].lastStatus = ERROR;
+ }
+
+ for (Device_i = 0; Device_i < MAX_TANGO_CONTROL_DEVICES; Device_i++)
+ {
+ ControlArray[Device_i].ControlActive = false;
+ ControlArray[Device_i].ControlCallbackPtr = NULL;
+ ControlArray[Device_i].ControlDataReadPtr = NULL;
+ ControlArray[Device_i].ControlTiming = eNoControl;
+ }
+ gateControlDB = GateMutex_create(NULL, &eb);
+ if (gateControlDB == NULL)
+ {
+ System_abort("Could not create USB Wait gate");
+ }
+
+ ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
+ ROM_TimerConfigure(Control_timerBase, TIMER_CFG_PERIODIC); // 32 bits Timer
+ //TimerIntRegister(Control_timerBase, TIMER_A, Timer0Isr); // Registering isr
+ ROM_TimerEnable(Control_timerBase, TIMER_A);
+ ROM_IntEnable(INT_TIMER0A);
+ ROM_TimerIntEnable(Control_timerBase, TIMER_TIMA_TIMEOUT);
+
+ ADCAcquireInit();
+
+ return;
+}
+void ControlStop(void)
+{
+ ControlRestart = false;
+ ADCAcquireStop();
+}
+
+void ControlStart(void)
+{
+ ControlRestart = true;
+ ROM_TimerLoadSet(Control_timerBase, TIMER_BOTH,120000/*one millisecond*/);
+ ADCAcquireStart(0,1);
+}
+
+/************************************************************************************************************************************************
+ * the control task reads the data from the devices every millisecond.
+ * (the data might be old data, if it is polled in a slower rate)
+ * for every polled device, there is a need to add a Data read callback, with a device id. the read value is always 32bits unsigned integer
+ * if there is a need to run a control function based on the read data, then the hardware module will add a control function, specifying the control calling rate
+ * both these callbacks can be removed. if a new call is arriving, it invalidates the previous one (no dual control or data)
+ *
+ ***************************************************************************************************************************************************/
+int AddControlCallback(uint32_t deviceId, ControlCBFunction Callback, CTRL_TIMING_ENUM CtrlFrequency )
+{
+ assert(deviceId < MAX_TANGO_CONTROL_DEVICES);
+ assert(Callback);
+ unsigned int key;
+
+ if(ControlArray[deviceId].ControlDataReadPtr == NULL)
+ {
+ LOG_ERROR (deviceId, "No dataread function for device");
+ return ERROR;
+ }
+
+ key = GateMutex_enter(gateControlDB);
+ ControlArray[deviceId].ControlTiming = CtrlFrequency;
+ ControlArray[deviceId].ControlCallbackPtr = Callback;
+ ControlArray[deviceId].ControlActive = true;
+ GateMutex_leave(gateControlDB, key);
+
+ return OK;
+
+}
+int RemoveControlCallback(uint32_t deviceId , ControlCBFunction Callback)
+{
+ assert(deviceId < MAX_TANGO_CONTROL_DEVICES);
+ unsigned int key;
+
+ if (Callback == ControlArray[deviceId].ControlCallbackPtr)
+ {
+ key = GateMutex_enter(gateControlDB);
+ ControlArray[deviceId].ControlTiming = eNoControl;
+ ControlArray[deviceId].ControlCallbackPtr = NULL;
+ ControlArray[deviceId].ControlActive = false;
+ GateMutex_leave(gateControlDB, key);
+ return OK;
+ }
+ else
+ return ERROR;
+
+}
+
+int RegisterDevice(uint32_t deviceId, DataReadCBFunction Callback, uint32_t Parameter)
+{
+ assert(deviceId < MAX_TANGO_CONTROL_DEVICES);
+ assert(Callback);
+ unsigned int key;
+ key = GateMutex_enter(gateControlDB);
+ ControlArray[deviceId].Parameter = Parameter;
+ ControlArray[deviceId].ControlDataReadPtr = Callback;
+ GateMutex_leave(gateControlDB, key);
+ return OK;
+
+}
+int UnRegisterDevice(uint32_t deviceId, DataReadCBFunction Callback )
+{
+ assert(deviceId < MAX_TANGO_CONTROL_DEVICES);
+ unsigned int key;
+ if (Callback == ControlArray[deviceId].ControlDataReadPtr)
+ {
+ key = GateMutex_enter(gateControlDB);
+ ControlArray[deviceId].Parameter = 0;
+ ControlArray[deviceId].ControlDataReadPtr = NULL;
+ ControlDatalog[deviceId] = 0;
+ GateMutex_leave(gateControlDB, key);
+ return OK;
+ }
+ else
+ return ERROR;
+
+}
+
+void OneMilliSecondControlInterrupt(UArg arg0)
+{
+ ControlMessageStruc Message;
+ bool retcode = false;
+ ROM_IntMasterDisable();
+
+ //trigger the ADC collection - check and set priorities to make sure handling timing is correct.
+ //we might want to call it from the task, afetr execution of other taks!!!
+ ADC_TriggerCollection();
+ //send message to the control task
+ Message.messageId = OneMillisec;
+ Message.tick = UsersysTickGet();
+ Message.msglen = sizeof(ControlMessageStruc);
+ if (ControlMsgQ != NULL)
+ retcode = Mailbox_post(ControlMsgQ , &Message, BIOS_NO_WAIT);
+ if (ControlRestart == true)
+ {
+ ROM_TimerLoadSet(Control_timerBase, TIMER_BOTH,120000/*one millisecond*/);
+ }
+
+ ROM_TimerIntClear(Control_timerBase, TIMER_TIMA_TIMEOUT); // Clear the timer interrupt
+ //
+ // Enable all interrupts.
+ //
+ ROM_IntMasterEnable();
+ return ;
+}
+
+uint32_t ControlLoop(uint32_t tick)
+{
+ //call all modules control functions
+ //test dancers and speed encoders
+ //check all callback units (state machine waiting for completion of a change)
+ uint32_t Device_i;
+ bool Ten_msTick, Hundred_msTick, Onesecond_Tick;
+ Ten_msTick = (tick%eTenMilliSecond == 0) ?true:false;
+ Hundred_msTick = (tick%eHunderdMillisecond == 0) ?true:false;
+ Onesecond_Tick = (tick%eOneSecond == 0) ?true:false;
+
+ for (Device_i = 0; Device_i < MAX_TANGO_CONTROL_DEVICES;Device_i++)
+ {
+ if (ControlArray[Device_i].ControlDataReadPtr)
+ ControlDatalog[Device_i] = ControlArray[Device_i].ControlDataReadPtr(Device_i, ControlArray[Device_i].Parameter);
+ if (ControlArray[Device_i].ControlActive)
+ {
+ switch (ControlArray[Device_i].ControlTiming)
+ {
+ case eOneMillisecond:
+ ControlArray[Device_i].ControlCallbackPtr(Device_i, ControlDatalog[Device_i]);
+ break;
+ case eTenMilliSecond:
+ if (Ten_msTick)
+ ControlArray[Device_i].ControlCallbackPtr(Device_i, ControlDatalog[Device_i]);
+ break;
+ case eHunderdMillisecond:
+ if (Hundred_msTick)
+ ControlArray[Device_i].ControlCallbackPtr(Device_i, ControlDatalog[Device_i]);
+ break;
+ case eOneSecond:
+ if (Onesecond_Tick)
+ ControlArray[Device_i].ControlCallbackPtr(Device_i, ControlDatalog[Device_i]);
+ break;
+ default:
+ LOG_ERROR (ControlArray[Device_i].ControlTiming, "Invalid control timing value");
+ break;
+ }
+ }
+ }
+
+ return OK;
+}
+/******************************************************************************
+ * ======== messageTsk ========
+ * Task for this function is created statically. See the project's .cfg file.
+ * this message task is created statically in system initialization,
+ ******************************************************************************/
+void controlTask(UArg arg0, UArg arg1)
+{
+ ControlMessageStruc Message;
+ //char str[60];
+ //uint16_t length;
+ //Clock_setTimeout(HostKAClock, 1000);
+ //Clock_start(HostKAClock);
+
+
+ while(1)
+ {
+ Mailbox_pend(ControlMsgQ , &Message, BIOS_WAIT_FOREVER);
+ switch (Message.messageId)
+ {
+ case OneMillisec:
+ ControlLoop(Message.tick);
+ break;
+ default:
+ break;
+ }
+ }
+}
diff --git a/Software/Embedded_SW/Embedded/Modules/Control/control.h b/Software/Embedded_SW/Embedded/Modules/Control/control.h
new file mode 100644
index 000000000..ab259993a
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Control/control.h
@@ -0,0 +1,30 @@
+/************************************************************************************************************************
+ * control.c
+ **************************************************************************************************************************/
+
+////////////////////////////////State machine operation////////////////////////////////////
+//the state machine operation is used to operate in runtime correct profile flow execution
+//by recieved esign flow of the user from the UI
+///////////////////////////////////////////////////////////////////////////////////////////
+#include "include.h"
+
+typedef uint32_t (* DeviceDataFunction)(uint32_t deviceID, uint32_t *Value);
+typedef uint32_t (* ControlCBFunction)(uint32_t deviceID, uint32_t ReadValue);
+typedef uint32_t (* DataReadCBFunction)(uint32_t deviceID, uint32_t Parameter);
+typedef enum {
+ eNoControl = 0,
+ eOneMillisecond = 1,
+ eTenMilliSecond = 10,
+ eHunderdMillisecond = 100,
+ eOneSecond = 1000
+}CTRL_TIMING_ENUM;
+
+
+void ControlInit(void);
+void ControlStop(void);
+void ControlStart(void);
+int AddControlCallback(uint32_t deviceID, ControlCBFunction Callback, CTRL_TIMING_ENUM CtrlFrequency );
+int RemoveControlCallback(uint32_t deviceID, ControlCBFunction Callback );
+int RegisterDevice(uint32_t deviceID, DataReadCBFunction Callback, uint32_t Parameter);
+int UnRegisterDevice(uint32_t deviceID, DataReadCBFunction Callback );
+
diff --git a/Software/Embedded_SW/Embedded/Modules/General/GeneralHardware.c b/Software/Embedded_SW/Embedded/Modules/General/GeneralHardware.c
new file mode 100644
index 000000000..1f5e3aa84
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/General/GeneralHardware.c
@@ -0,0 +1,348 @@
+/************************************************************************************************************************
+ * control.c
+ * Control module
+ *
+************************************************************************************************************************/
+#include "include.h"
+#include "GeneralHardware.h"
+#include "thread/thread.h"
+#include "ids/ids.h"
+#include "control/control.h"
+#include "heaters/heaters_ex.h"
+#include <Modules/Stubs_Handler/DataDef.h>
+#include "PMR/common/MessageContainer.pb-c.h"
+#include "Modules/Stubs_Handler/Container.h"
+#include "PMR/Hardware/UploadHardWareConfigurationRequest.pb-c.h"
+#include "PMR/Hardware/UploadHardWareConfigurationResponse.pb-c.h"
+
+PortInfoStruct PortInfoTable[MAX_PORT_ENUM] = {
+ {ANALOG_MIXCHIP_TEMP,"ANALOG_MIXCHIP_TEMP"},
+ {AN_DYEINGH_CURSEN_1,"AN_DYEINGH_CURSEN_1"},
+ {AN_DYEINGH_CURSEN_2,"AN_DYEINGH_CURSEN_2"},
+ {AN_DYEINGH_CURSEN_3,"AN_DYEINGH_CURSEN_3"},
+ {AN_DYEINGH_CURSEN_4,"AN_DYEINGH_CURSEN_4"},
+ {AN_DYEINGH_CURSEN_5,"AN_DYEINGH_CURSEN_5"},
+ {ANALOG_DYEINGH_TEMP1,"ANALOG_DYEINGH_TEMP1"},
+ {ANALOG_DYEINGH_TEMP2,"ANALOG_DYEINGH_TEMP2"},
+ {ANALOG_DYEINGH_TEMP3,"ANALOG_DYEINGH_TEMP3"},
+ {ANALOG_DYEINGH_TEMP4,"ANALOG_DYEINGH_TEMP4"},
+ {ANALOG_DYEINGH_TEMP5,"ANALOG_DYEINGH_TEMP5"},
+ {AN_DRYER_CURSEN1,"AN_DRYER_CURSEN1"},
+ {AN_DRYER_CURSEN2,"AN_DRYER_CURSEN2"},
+ {AN_DRYER_CURSEN3,"AN_DRYER_CURSEN3"},
+ {ANALOG_DRYER_TEMP1,"ANALOG_DRYER_TEMP1"},
+ {ANALOG_DRYER_TEMP2,"ANALOG_DRYER_TEMP2"},
+ {ANALOG_DRYER_TEMP3,"ANALOG_DRYER_TEMP3"},
+ {AN_ENCLOSURETEMP1,"AN_ENCLOSURETEMP1"},
+ {AN_ENCLOSURETEMP2,"AN_ENCLOSURETEMP2"},
+ {AN_ENCLOSURETEMP3,"AN_ENCLOSURETEMP3"},
+ {AN_IDS_PRESSENS_1,"AN_IDS_PRESSENS_1"},
+ {AN_IDS_PRESSENS_2,"AN_IDS_PRESSENS_2"},
+ {AN_IDS_PRESSENS_3,"AN_IDS_PRESSENS_3"},
+ {AN_IDS_PRESSENS_4,"AN_IDS_PRESSENS_4"},
+ {AN_IDS_PRESSENS_5,"AN_IDS_PRESSENS_5"},
+ {AN_IDS_PRESSENS_6,"AN_IDS_PRESSENS_6"},
+ {AN_IDS_PRESSENS_7,"AN_IDS_PRESSENS_7"},
+ {AN_IDS_PRESSENS_8,"AN_IDS_PRESSENS_8"},
+ {AN_MIDTANK_PRESSENS1,"AN_MIDTANK_PRESSENS1"},
+ {AN_MIDTANK_PRESSENS2,"AN_MIDTANK_PRESSENS2"},
+ {AN_MIDTANK_PRESSENS3,"AN_MIDTANK_PRESSENS3"},
+ {AN_MIDTANK_PRESSENS4,"AN_MIDTANK_PRESSENS4"},
+ {AN_MIDTANK_PRESSENS5,"AN_MIDTANK_PRESSENS5"},
+ {AN_MIDTANK_PRESSENS6,"AN_MIDTANK_PRESSENS6"},
+ {AN_MIDTANK_PRESSENS7,"AN_MIDTANK_PRESSENS7"},
+ {AN_MIXCHIP_CURSENn,"AN_MIXCHIP_CURSENn"},
+ {AN5V_LDANCER1,"AN5V_LDANCER1"},
+ {AN5V_LDANCER2,"AN5V_LDANCER2"},
+ {AN5V_RDANCER,"AN5V_RDANCER"},
+ {AN10V_SPARE1,"AN10V_SPARE1"},
+ {AN10V_SPARE2,"AN10V_SPARE2"},
+ {AN_AIRPRESS_1,"AN_AIRPRESS_1"},
+ {AN_AIRPRESS_2,"AN_AIRPRESS_2"},
+ {AN_VOCSENS,"AN_VOCSENS"},
+ {AN_BLOWERCTRL,"AN_BLOWERCTRL"},
+ {LS_DH_LID_CLEANING,"LS_DH_LID_CLEANING"},
+ {LS_DH_LID_CLOSED,"LS_DH_LID_CLOSED"},
+ {LS_DH_CLEAN_UP,"LS_DH_CLEAN_UP"},
+ {LS_DH_CLEAN_RIGHT,"LS_DH_CLEAN_RIGHT"},
+ {LS_DH_SPARE1,"LS_DH_SPARE1"},
+ {LS_DH_LID_OPEN,"LS_DH_LID_OPEN"},
+ {LS_DH_CLEAN_DOWN,"LS_DH_CLEAN_DOWN"},
+ {LS_DH_CLEAN_LEFT,"LS_DH_CLEAN_LEFT"},
+ {LS_DRYER_LID_OPEN,"LS_DRYER_LID_OPEN"},
+ {LS_DRYER_SPARE3,"LS_DRYER_SPARE3"},
+ {LS_DRYER_LID_CLOSED,"LS_DRYER_LID_CLOSED"},
+ {LS_DRYER_SPARE4,"LS_DRYER_SPARE4"},
+ {LS_DRYER_SPARE1,"LS_DRYER_SPARE1"},
+ {LS_LOADARM_RIGHT,"LS_LOADARM_RIGHT"},
+ {LS_DRYER_SPARE2,"LS_DRYER_SPARE2"},
+ {LS_LOADARM_LEFT,"LS_LOADARM_LEFT"},
+ {GPI_PS1_DC_OK,"GPI_PS1_DC_OK"},
+ {GPI_PANSW2,"GPI_PANSW2"},
+ {GPI_PANSW4,"GPI_PANSW4"},
+ {GPI_PANSW1,"GPI_PANSW1"},
+ {GPI_PANSW3,"GPI_PANSW3"},
+ {GPI_PANSW5,"GPI_PANSW5"},
+ {GPI_PANSW6,"GPI_PANSW6"},
+ {GPI_TACTSW1,"GPI_TACTSW1"},
+ {GPI_TACTSW3,"GPI_TACTSW3"},
+ {GPI_PWRBUTTON,"GPI_PWRBUTTON"},
+ {GPI_TACTSW2,"GPI_TACTSW2"},
+ {GPI_TACTSW4,"GPI_TACTSW4"},
+ {GPI_EXTWINDER_1,"GPI_EXTWINDER_1"},
+ {GPI_EXTWINDER_2,"GPI_EXTWINDER_2"},
+ {GPI_EXTWINDER_3,"GPI_EXTWINDER_3"},
+ {GPI_EXTWINDER_1_rtn,"GPI_EXTWINDER_1_rtn"},
+ {GPI_EXTWINDER_2_rtn,"GPI_EXTWINDER_2_rtn"},
+ {GPI_EXTWINDER_3_rtn,"GPI_EXTWINDER_3_rtn"},
+ {LS_DISPENSER_UP_1,"LS_DISPENSER_UP_1"},
+ {LS_DISPENSER_25_1,"LS_DISPENSER_25_1"},
+ {LS_DISPENSER_75_1,"LS_DISPENSER_75_1"},
+ {LS_DISPENSER_UP_3,"LS_DISPENSER_UP_3"},
+ {LS_DISPENSER_25_3,"LS_DISPENSER_25_3"},
+ {LS_DISPENSER_75_3,"LS_DISPENSER_75_3"},
+ {LS_DISPENSER_UP_5,"LS_DISPENSER_UP_5"},
+ {LS_DISPENSER_25_5,"LS_DISPENSER_25_5"},
+ {LS_DISPENSER_75_5,"LS_DISPENSER_75_5"},
+ {LS_DISPENSER_UP_7,"LS_DISPENSER_UP_7"},
+ {LS_DISPENSER_25_7,"LS_DISPENSER_25_7"},
+ {LS_DISPENSER_75_7,"LS_DISPENSER_75_7"},
+ {LS_DISPENSER_DOWN_1,"LS_DISPENSER_DOWN_1"},
+ {LS_DISPENSER_50_1,"LS_DISPENSER_50_1"},
+ {LS_DISPENSER_SPARE_1,"LS_DISPENSER_SPARE_1"},
+ {LS_DISPENSER_DOWN_3,"LS_DISPENSER_DOWN_3"},
+ {LS_DISPENSER_50_3,"LS_DISPENSER_50_3"},
+ {LS_DISPENSER_SPARE_3,"LS_DISPENSER_SPARE_3"},
+ {LS_DISPENSER_DOWN_5,"LS_DISPENSER_DOWN_5"},
+ {LS_DISPENSER_50_5,"LS_DISPENSER_50_5"},
+ {LS_DISPENSER_SPARE_5,"LS_DISPENSER_SPARE_5"},
+ {LS_DISPENSER_DOWN_7,"LS_DISPENSER_DOWN_7"},
+ {LS_DISPENSER_50_7,"LS_DISPENSER_50_7"},
+ {LS_DISPENSER_SPARE_7,"LS_DISPENSER_SPARE_7"},
+ {LS_DISPENSER_UP_2,"LS_DISPENSER_UP_2"},
+ {LS_DISPENSER_25_2,"LS_DISPENSER_25_2"},
+ {LS_DISPENSER_75_2,"LS_DISPENSER_75_2"},
+ {LS_DISPENSER_UP_4,"LS_DISPENSER_UP_4"},
+ {LS_DISPENSER_25_4,"LS_DISPENSER_25_4"},
+ {LS_DISPENSER_75_4,"LS_DISPENSER_75_4"},
+ {LS_DISPENSER_UP_6,"LS_DISPENSER_UP_6"},
+ {LS_DISPENSER_25_6,"LS_DISPENSER_25_6"},
+ {LS_DISPENSER_75_6,"LS_DISPENSER_75_6"},
+ {LS_DISPENSER_UP_8,"LS_DISPENSER_UP_8"},
+ {LS_DISPENSER_25_8,"LS_DISPENSER_25_8"},
+ {LS_DISPENSER_75_8,"LS_DISPENSER_75_8"},
+ {LS_RLOADMOTOR_UP,"LS_RLOADMOTOR_UP"},
+ {LS_DISPENSER_DOWN_2,"LS_DISPENSER_DOWN_2"},
+ {LS_DISPENSER_50_2,"LS_DISPENSER_50_2"},
+ {LS_DISPENSER_SPARE_2,"LS_DISPENSER_SPARE_2"},
+ {LS_DISPENSER_DOWN_4,"LS_DISPENSER_DOWN_4"},
+ {LS_DISPENSER_50_4,"LS_DISPENSER_50_4"},
+ {LS_DISPENSER_SPARE_4,"LS_DISPENSER_SPARE_4"},
+ {LS_DISPENSER_DOWN_6,"LS_DISPENSER_DOWN_6"},
+ {LS_DISPENSER_50_6,"LS_DISPENSER_50_6"},
+ {LS_DISPENSER_SPARE_6,"LS_DISPENSER_SPARE_6"},
+ {LS_DISPENSER_DOWN_8,"LS_DISPENSER_DOWN_8"},
+ {LS_DISPENSER_50_8,"LS_DISPENSER_50_8"},
+ {LS_DISPENSER_SPARE_8,"LS_DISPENSER_SPARE_8"},
+ {LS_SCREW_LEFT,"LS_SCREW_LEFT"},
+ {SW_SPOOL_EXISTS,"SW_SPOOL_EXISTS"},
+ {LS_SCREW_RIGHT,"LS_SCREW_RIGHT"},
+ {SW_SPARE,"SW_SPARE"},
+ {LS_LDANCER1_DOWN,"LS_LDANCER1_DOWN"},
+ {LS_LDANCER2_DOWN,"LS_LDANCER2_DOWN"},
+ {LS_LPIVOT_DOWN,"LS_LPIVOT_DOWN"},
+ {LS_PIVOT_SPARE1,"LS_PIVOT_SPARE1"},
+ {LS_LDANCER1_UP,"LS_LDANCER1_UP"},
+ {LS_LDANCER2_UP,"LS_LDANCER2_UP"},
+ {LS_LPIVOT_UP,"LS_LPIVOT_UP"},
+ {LS_PIVOT_SPARE2,"LS_PIVOT_SPARE2"},
+ {LS_LLOADMOTOR_DOWN,"LS_LLOADMOTOR_DOWN"},
+ {LS_LSPARE1,"LS_LSPARE1"},
+ {LS_LLOADMOTOR_UP,"LS_LLOADMOTOR_UP"},
+ {LS_LSPARE2,"LS_LSPARE2"},
+ {LS_RDANCER_DOWN,"LS_RDANCER_DOWN"},
+ {LS_RLOADRAM_DOWN,"LS_RLOADRAM_DOWN"},
+ {LS_RDANCER_UP,"LS_RDANCER_UP"},
+ {LS_RLOADRAM_UP,"LS_RLOADRAM_UP"},
+ {LS_RLOADMOTOR_DOWN,"LS_RLOADMOTOR_DOWN"},
+ {GPI_TFEED_BREAK_1,"GPI_TFEED_BREAK_1"},
+ {GPI_TFEED_BREAK_2,"GPI_TFEED_BREAK_2"},
+ {LS_RSPARE1,"LS_RSPARE1"},
+ {LS_SPARE2_1,"LS_SPARE2_1"},
+ {LS_SPARE2_3,"LS_SPARE2_3"},
+ {LS_SPARE1_1,"LS_SPARE1_1"},
+ {LS_SPARE1_3,"LS_SPARE1_3"},
+ {LS_RSPARE2,"LS_RSPARE2"},
+ {LS_SPARE2_2,"LS_SPARE2_2"},
+ {LS_SPARE2_4,"LS_SPARE2_4"},
+ {LS_SPARE1_2,"LS_SPARE1_2"},
+ {LS_SPARE1_4,"LS_SPARE1_4"},
+ {GPI_WCONTAINER_WARN,"GPI_WCONTAINER_WARN"},
+ {GPI_SW_WCONTAINER_PRES,"GPI_SW_WCONTAINER_PRES"},
+ {GPI_CHILLER_FAULT,"GPI_CHILLER_FAULT"},
+ {GPI_CHILLER_STAT1,"GPI_CHILLER_STAT1"},
+ {GPI_BLOWER_TACH,"GPI_BLOWER_TACH"},
+ {GPI_WCONTAINER_FULL,"GPI_WCONTAINER_FULL"},
+ {GPI_AIRFLOW_FLAP,"GPI_AIRFLOW_FLAP"},
+ {GPO_MIXCHIP_SSR4_CTRL,"GPO_MIXCHIP_SSR4_CTRL"},
+ {GPO_DYEINGH_SSR7_CTRL,"GPO_DYEINGH_SSR7_CTRL"},
+ {GPO_DYEINGH_SSR8_CTRL,"GPO_DYEINGH_SSR8_CTRL"},
+ {GPO_DYEINGH_SSR5_CTRL,"GPO_DYEINGH_SSR5_CTRL"},
+ {GPO_DYEINGH_SSR6_CTRL,"GPO_DYEINGH_SSR6_CTRL"},
+ {GPO_DRYER_SSR3_CTRL,"GPO_DRYER_SSR3_CTRL"},
+ {GPO_DRYER_SSR1_CTRL,"GPO_DRYER_SSR1_CTRL"},
+ {GPO_DRYER_SSR2_CTRL,"GPO_DRYER_SSR2_CTRL"},
+ {GPO_SPARE_SSR12_CTRL,"GPO_SPARE_SSR12_CTRL"},
+ {GPO_SPARE_SSR13_CTRL,"GPO_SPARE_SSR13_CTRL"},
+ {GPO_PDOWN_RL1_CTRL,"GPO_PDOWN_RL1_CTRL"},
+ {GPO_LED1,"GPO_LED1"},
+ {GPO_LED3,"GPO_LED3"},
+ {GPO_LED2,"GPO_LED2"},
+ {GPO_LED4,"GPO_LED4"},
+ {GPO_BUZZER,"GPO_BUZZER"},
+ {GPO_EXTWINDER_SSR11_CTRL,"GPO_EXTWINDER_SSR11_CTRL"},
+ {GPO_EXTWINDER_1,"GPO_EXTWINDER_1"},
+ {GPO_EXTWINDER_2,"GPO_EXTWINDER_2"},
+ {GPO_EXTWINDER_3,"GPO_EXTWINDER_3"},
+ {GPO_DILUTORPUMP_SSR10_CTRL,"GPO_DILUTORPUMP_SSR10_CTRL"},
+ {GPO_WASTECH_PUMP1,"GPO_WASTECH_PUMP1"},
+ {GPO_WASTECH_PUMP2,"GPO_WASTECH_PUMP2"},
+ {GPO_TFEED_BREAK_1,"GPO_TFEED_BREAK_1"},
+ {GPO_TFEED_BREAK_2,"GPO_TFEED_BREAK_2"},
+ {GPO_SPARE1_1,"GPO_SPARE1_1"},
+ {GPO_SPARE2_1,"GPO_SPARE2_1"},
+ {GPO_SPARE1_2,"GPO_SPARE1_2"},
+ {GPO_SPARE2_2,"GPO_SPARE2_2"},
+ {GPO_BLOWER_PWM,"GPO_BLOWER_PWM"},
+ {GPO_WHS_WTANKPUMP2,"GPO_WHS_WTANKPUMP2"},
+ {GPO_CHILLER_SSR9_CTRL,"GPO_CHILLER_SSR9_CTRL"},
+ {DH2,"DH2"},
+ {DH1,"DH1"},
+ {DRYER2,"DRYER2"},
+ {DRYER1,"DRYER1"},
+ {ELECTRICALENC,"ELECTRICALENC"},
+ {USERPANEL,"USERPANEL"},
+ {EXTWINDINGUNIT,"EXTWINDINGUNIT"},
+ {DISPENSER_1,"DISPENSER_1"},
+ {DISPENSER_3,"DISPENSER_3"},
+ {DISPENSER_5,"DISPENSER_5"},
+ {DISPENSER_7,"DISPENSER_7"},
+ {MIDTANK3_1,"MIDTANK3_1"},
+ {DISPENSER_2,"DISPENSER_2"},
+ {DISPENSER_4,"DISPENSER_4"},
+ {DISPENSER_6,"DISPENSER_6"},
+ {DISPENSER_8,"DISPENSER_8"},
+ {CART3,"CART3"},
+ {CART1,"CART1"},
+ {CART2,"CART2"},
+ {CART4,"CART4"},
+ {CART7,"CART7"},
+ {CART5,"CART5"},
+ {CART6,"CART6"},
+ {CART8,"CART8"},
+ {INTWINDINGUNIT,"INTWINDINGUNIT"},
+ {LTFEEDUNIT2,"LTFEEDUNIT2"},
+ {LTFEEDUNIT1,"LTFEEDUNIT1"},
+ {RTFEEDUNIT2,"RTFEEDUNIT2"},
+ {RTFEEDUNIT1,"RTFEEDUNIT1"},
+ {SPARE2,"SPARE2"},
+ {SPARE1,"SPARE1"},
+ {WHS,"WHS"},
+ {MIDTANK3_2,"MIDTANK3_2"},
+ {MOTO_DH_CLEANHEAD,"MOTO_DH_CLEANHEAD"},
+ {MOTO_DH_CLEANMECH,"MOTO_DH_CLEANMECH"},
+ {MOTO_DH_LID,"MOTO_DH_LID"},
+ {MOTO_DRYER_DRIVING,"MOTO_DRYER_DRIVING"},
+ {MOTO_DRYER_LID,"MOTO_DRYER_LID"},
+ {MOTO_DRYER_LOADARM,"MOTO_DRYER_LOADARM"},
+ {MOTO_DISPENSER_1,"MOTO_DISPENSER_1"},
+ {MOTO_DISPENSER_2,"MOTO_DISPENSER_2"},
+ {MOTO_DISPENSER_3,"MOTO_DISPENSER_3"},
+ {MOTO_DISPENSER_4,"MOTO_DISPENSER_4"},
+ {MOTO_DISPENSER_5,"MOTO_DISPENSER_5"},
+ {MOTO_DISPENSER_6,"MOTO_DISPENSER_6"},
+ {MOTO_DISPENSER_7,"MOTO_DISPENSER_7"},
+ {MOTO_DISPENSER_8,"MOTO_DISPENSER_8"},
+ {MOTO_SCREW,"MOTO_SCREW"},
+ {MOTO_WINDER,"MOTO_WINDER"},
+ {MOTO_LDANCER1,"MOTO_LDANCER1"},
+ {MOTO_LDANCER2,"MOTO_LDANCER2"},
+ {MOTO_LDRIVING,"MOTO_LDRIVING"},
+ {MOTO_LLOADING,"MOTO_LLOADING"},
+ {MOTO_LPIVOT1,"MOTO_LPIVOT1"},
+ {MOTO_RDANCER,"MOTO_RDANCER"},
+ {MOTO_RDRIVING,"MOTO_RDRIVING"},
+ {MOTO_RLOADARM,"MOTO_RLOADARM"},
+ {MOTO_RLOADING,"MOTO_RLOADING"},
+ {MOTO_SPARE1_1,"MOTO_SPARE1_1"},
+ {MOTO_SPARE1_2,"MOTO_SPARE1_2"},
+ {MOTO_SPARE2_1,"MOTO_SPARE2_1"},
+ {MOTO_SPARE2_2,"MOTO_SPARE2_2"},
+ {DRYER_LOADARM_ROTENC,"DRYER_LOADARM_ROTENC"},
+ {DISPENSER_ROTENC1,"DISPENSER_ROTENC1"},
+ {DISPENSER_ROTENC2,"DISPENSER_ROTENC2"},
+ {DISPENSER_ROTENC3,"DISPENSER_ROTENC3"},
+ {DISPENSER_ROTENC4,"DISPENSER_ROTENC4"},
+ {DISPENSER_ROTENC5,"DISPENSER_ROTENC5"},
+ {DISPENSER_ROTENC6,"DISPENSER_ROTENC6"},
+ {DISPENSER_ROTENC7,"DISPENSER_ROTENC7"},
+ {DISPENSER_ROTENC8,"DISPENSER_ROTENC8"},
+ {SCREW_ROTENC,"SCREW_ROTENC"},
+ {LDANCER1_ROTENC2,"LDANCER1_ROTENC2"},
+ {LDANCER2_ROTENC2,"LDANCER2_ROTENC2"},
+ {LSPARE_ROTENC,"LSPARE_ROTENC"},
+ {LSPARE_ROTENCn,"LSPARE_ROTENCn"},
+ {LSPARE1_ROTENC,"LSPARE1_ROTENC"},
+ {LSPARE2_ROTENC,"LSPARE2_ROTENC"},
+ {RDANCER_ROTENC2,"RDANCER_ROTENC2"},
+ {RSPARE_ROTENC,"RSPARE_ROTENC"},
+ {RSPEEDSENS_ROTENC,"RSPEEDSENS_ROTENC"},
+ {SPARE1_ROTENC,"SPARE1_ROTENC"},
+ {SPARE2_ROTENC,"SPARE2_ROTENC"},
+ {FAN_TACHO1,"FAN_TACHO1"},
+ {FAN_TACHO3,"FAN_TACHO3"},
+ {FAN_TACHO2,"FAN_TACHO2"},
+ {FAN1_TACH,"FAN1_TACH"},
+ {FAN2_TACH,"FAN2_TACH"},
+ {FAN5_TACH,"FAN5_TACH"},
+ {FAN3_TACH,"FAN3_TACH"},
+ {FAN4_TACH,"FAN4_TACH"},
+};
+
+
+
+uint32_t HWConfigurationFunc(MessageContainer* requestContainer)
+{
+ uint32_t status = 0;
+ int Motor_i, Dancer_i, Dispenser_i,PID_i;
+ MessageContainer responseContainer;
+ UploadHardwareConfigurationResponse response = UPLOAD_HARDWARE_CONFIGURATION_RESPONSE__INIT;
+
+ UploadHardwareConfigurationRequest* UploadRequest = upload_hardware_configuration_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data);
+ HardwareConfiguration *request = UploadRequest->hardwareconfiguration;
+ status += InternalWinderConfigMessage(request->winders);
+ for (Motor_i = 0; Motor_i < request->n_motors ; Motor_i++)
+ status += MotorsConfigMessage(request->motors[Motor_i]);
+ for (Dancer_i = 0; Dancer_i < request->n_dancers ; Dancer_i++)
+ status += DancerConfigMessage(request->dancers[Dancer_i]);
+ for (PID_i = 0; PID_i < request->n_pidcontrols ; PID_i++)
+ status += HeaterConfigRequestMessage(request->pidcontrols[PID_i]);
+ for (Dispenser_i = 0; Dispenser_i < request->n_dispensers ; Dispenser_i++)
+ status += DispenserConfigMessage(request->dispensers[Dispenser_i]);
+ //status += HeaterConfigSetSharedHeatersParams (request->outputproportionalcycletime, request->outputproportionalsinglestep);
+
+
+
+
+ responseContainer = createContainer(MESSAGE_TYPE__UploadHardwareConfigurationResponse, requestContainer->token, true, &response, &upload_hardware_configuration_response__pack, &upload_hardware_configuration_response__get_packed_size);
+ uint8_t* container_buffer = malloc(message_container__get_packed_size(&responseContainer));
+ size_t container_size = message_container__pack(&responseContainer, container_buffer);
+ SendChars((char*)container_buffer, container_size);
+ free(container_buffer);
+ free(requestContainer);
+
+ return OK;
+
+
+
+}
diff --git a/Software/Embedded_SW/Embedded/Modules/General/GeneralHardware.h b/Software/Embedded_SW/Embedded/Modules/General/GeneralHardware.h
new file mode 100644
index 000000000..ab55c3e57
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/General/GeneralHardware.h
@@ -0,0 +1,313 @@
+#ifndef GENERALHARDWARE_H
+#define GENERALHARDWARE_H
+
+#include "include.h"
+#include <Modules/Stubs_Handler/DataDef.h>
+#include "PMR/common/MessageContainer.pb-c.h"
+#include "Modules/Stubs_Handler/Container.h"
+
+typedef enum
+{
+ ANALOG_MIXCHIP_TEMP,
+ AN_DYEINGH_CURSEN_1,
+ AN_DYEINGH_CURSEN_2,
+ AN_DYEINGH_CURSEN_3,
+ AN_DYEINGH_CURSEN_4,
+ AN_DYEINGH_CURSEN_5,
+ ANALOG_DYEINGH_TEMP1,
+ ANALOG_DYEINGH_TEMP2,
+ ANALOG_DYEINGH_TEMP3,
+ ANALOG_DYEINGH_TEMP4,
+ ANALOG_DYEINGH_TEMP5,
+ AN_DRYER_CURSEN1,
+ AN_DRYER_CURSEN2,
+ AN_DRYER_CURSEN3,
+ ANALOG_DRYER_TEMP1,
+ ANALOG_DRYER_TEMP2,
+ ANALOG_DRYER_TEMP3,
+ AN_ENCLOSURETEMP1,
+ AN_ENCLOSURETEMP2,
+ AN_ENCLOSURETEMP3,
+ AN_IDS_PRESSENS_1,
+ AN_IDS_PRESSENS_2,
+ AN_IDS_PRESSENS_3,
+ AN_IDS_PRESSENS_4,
+ AN_IDS_PRESSENS_5,
+ AN_IDS_PRESSENS_6,
+ AN_IDS_PRESSENS_7,
+ AN_IDS_PRESSENS_8,
+ AN_MIDTANK_PRESSENS1,
+ AN_MIDTANK_PRESSENS2,
+ AN_MIDTANK_PRESSENS3,
+ AN_MIDTANK_PRESSENS4,
+ AN_MIDTANK_PRESSENS5,
+ AN_MIDTANK_PRESSENS6,
+ AN_MIDTANK_PRESSENS7,
+ AN_MIXCHIP_CURSENn,
+ AN5V_LDANCER1,
+ AN5V_LDANCER2,
+ AN5V_RDANCER,
+ AN10V_SPARE1,
+ AN10V_SPARE2,
+ AN_AIRPRESS_1,
+ AN_AIRPRESS_2,
+ AN_VOCSENS,
+ AN_BLOWERCTRL,
+ LS_DH_LID_CLEANING,
+ LS_DH_LID_CLOSED,
+ LS_DH_CLEAN_UP,
+ LS_DH_CLEAN_RIGHT,
+ LS_DH_SPARE1,
+ LS_DH_LID_OPEN,
+ LS_DH_CLEAN_DOWN,
+ LS_DH_CLEAN_LEFT,
+ LS_DRYER_LID_OPEN,
+ LS_DRYER_SPARE3,
+ LS_DRYER_LID_CLOSED,
+ LS_DRYER_SPARE4,
+ LS_DRYER_SPARE1,
+ LS_LOADARM_RIGHT,
+ LS_DRYER_SPARE2,
+ LS_LOADARM_LEFT,
+ GPI_PS1_DC_OK,
+ GPI_PANSW2,
+ GPI_PANSW4,
+ GPI_PANSW1,
+ GPI_PANSW3,
+ GPI_PANSW5,
+ GPI_PANSW6,
+ GPI_TACTSW1,
+ GPI_TACTSW3,
+ GPI_PWRBUTTON,
+ GPI_TACTSW2,
+ GPI_TACTSW4,
+ GPI_EXTWINDER_1,
+ GPI_EXTWINDER_2,
+ GPI_EXTWINDER_3,
+ GPI_EXTWINDER_1_rtn,
+ GPI_EXTWINDER_2_rtn,
+ GPI_EXTWINDER_3_rtn,
+ LS_DISPENSER_UP_1,
+ LS_DISPENSER_25_1,
+ LS_DISPENSER_75_1,
+ LS_DISPENSER_UP_3,
+ LS_DISPENSER_25_3,
+ LS_DISPENSER_75_3,
+ LS_DISPENSER_UP_5,
+ LS_DISPENSER_25_5,
+ LS_DISPENSER_75_5,
+ LS_DISPENSER_UP_7,
+ LS_DISPENSER_25_7,
+ LS_DISPENSER_75_7,
+ LS_DISPENSER_DOWN_1,
+ LS_DISPENSER_50_1,
+ LS_DISPENSER_SPARE_1,
+ LS_DISPENSER_DOWN_3,
+ LS_DISPENSER_50_3,
+ LS_DISPENSER_SPARE_3,
+ LS_DISPENSER_DOWN_5,
+ LS_DISPENSER_50_5,
+ LS_DISPENSER_SPARE_5,
+ LS_DISPENSER_DOWN_7,
+ LS_DISPENSER_50_7,
+ LS_DISPENSER_SPARE_7,
+ LS_DISPENSER_UP_2,
+ LS_DISPENSER_25_2,
+ LS_DISPENSER_75_2,
+ LS_DISPENSER_UP_4,
+ LS_DISPENSER_25_4,
+ LS_DISPENSER_75_4,
+ LS_DISPENSER_UP_6,
+ LS_DISPENSER_25_6,
+ LS_DISPENSER_75_6,
+ LS_DISPENSER_UP_8,
+ LS_DISPENSER_25_8,
+ LS_DISPENSER_75_8,
+ LS_RLOADMOTOR_UP,
+ LS_DISPENSER_DOWN_2,
+ LS_DISPENSER_50_2,
+ LS_DISPENSER_SPARE_2,
+ LS_DISPENSER_DOWN_4,
+ LS_DISPENSER_50_4,
+ LS_DISPENSER_SPARE_4,
+ LS_DISPENSER_DOWN_6,
+ LS_DISPENSER_50_6,
+ LS_DISPENSER_SPARE_6,
+ LS_DISPENSER_DOWN_8,
+ LS_DISPENSER_50_8,
+ LS_DISPENSER_SPARE_8,
+ LS_SCREW_LEFT,
+ SW_SPOOL_EXISTS,
+ LS_SCREW_RIGHT,
+ SW_SPARE,
+ LS_LDANCER1_DOWN,
+ LS_LDANCER2_DOWN,
+ LS_LPIVOT_DOWN,
+ LS_PIVOT_SPARE1,
+ LS_LDANCER1_UP,
+ LS_LDANCER2_UP,
+ LS_LPIVOT_UP,
+ LS_PIVOT_SPARE2,
+ LS_LLOADMOTOR_DOWN,
+ LS_LSPARE1,
+ LS_LLOADMOTOR_UP,
+ LS_LSPARE2,
+ LS_RDANCER_DOWN,
+ LS_RLOADRAM_DOWN,
+ LS_RDANCER_UP,
+ LS_RLOADRAM_UP,
+ LS_RLOADMOTOR_DOWN,
+ GPI_TFEED_BREAK_1,
+ GPI_TFEED_BREAK_2,
+ LS_RSPARE1,
+ LS_SPARE2_1,
+ LS_SPARE2_3,
+ LS_SPARE1_1,
+ LS_SPARE1_3,
+ LS_RSPARE2,
+ LS_SPARE2_2,
+ LS_SPARE2_4,
+ LS_SPARE1_2,
+ LS_SPARE1_4,
+ GPI_WCONTAINER_WARN,
+ GPI_SW_WCONTAINER_PRES,
+ GPI_CHILLER_FAULT,
+ GPI_CHILLER_STAT1,
+ GPI_BLOWER_TACH,
+ GPI_WCONTAINER_FULL,
+ GPI_AIRFLOW_FLAP,
+ GPO_MIXCHIP_SSR4_CTRL,
+ GPO_DYEINGH_SSR7_CTRL,
+ GPO_DYEINGH_SSR8_CTRL,
+ GPO_DYEINGH_SSR5_CTRL,
+ GPO_DYEINGH_SSR6_CTRL,
+ GPO_DRYER_SSR3_CTRL,
+ GPO_DRYER_SSR1_CTRL,
+ GPO_DRYER_SSR2_CTRL,
+ GPO_SPARE_SSR12_CTRL,
+ GPO_SPARE_SSR13_CTRL,
+ GPO_PDOWN_RL1_CTRL,
+ GPO_LED1,
+ GPO_LED3,
+ GPO_LED2,
+ GPO_LED4,
+ GPO_BUZZER,
+ GPO_EXTWINDER_SSR11_CTRL,
+ GPO_EXTWINDER_1,
+ GPO_EXTWINDER_2,
+ GPO_EXTWINDER_3,
+ GPO_DILUTORPUMP_SSR10_CTRL,
+ GPO_WASTECH_PUMP1,
+ GPO_WASTECH_PUMP2,
+ GPO_TFEED_BREAK_1,
+ GPO_TFEED_BREAK_2,
+ GPO_SPARE1_1,
+ GPO_SPARE2_1,
+ GPO_SPARE1_2,
+ GPO_SPARE2_2,
+ GPO_BLOWER_PWM,
+ GPO_WHS_WTANKPUMP2,
+ GPO_CHILLER_SSR9_CTRL,
+ DH2,
+ DH1,
+ DRYER2,
+ DRYER1,
+ ELECTRICALENC,
+ USERPANEL,
+ EXTWINDINGUNIT,
+ DISPENSER_1,
+ DISPENSER_3,
+ DISPENSER_5,
+ DISPENSER_7,
+ MIDTANK3_1,
+ DISPENSER_2,
+ DISPENSER_4,
+ DISPENSER_6,
+ DISPENSER_8,
+ CART3,
+ CART1,
+ CART2,
+ CART4,
+ CART7,
+ CART5,
+ CART6,
+ CART8,
+ INTWINDINGUNIT,
+ LTFEEDUNIT2,
+ LTFEEDUNIT1,
+ RTFEEDUNIT2,
+ RTFEEDUNIT1,
+ SPARE2,
+ SPARE1,
+ WHS,
+ MIDTANK3_2,
+ MOTO_DH_CLEANHEAD,
+ MOTO_DH_CLEANMECH,
+ MOTO_DH_LID,
+ MOTO_DRYER_DRIVING,
+ MOTO_DRYER_LID,
+ MOTO_DRYER_LOADARM,
+ MOTO_DISPENSER_1,
+ MOTO_DISPENSER_2,
+ MOTO_DISPENSER_3,
+ MOTO_DISPENSER_4,
+ MOTO_DISPENSER_5,
+ MOTO_DISPENSER_6,
+ MOTO_DISPENSER_7,
+ MOTO_DISPENSER_8,
+ MOTO_SCREW,
+ MOTO_WINDER,
+ MOTO_LDANCER1,
+ MOTO_LDANCER2,
+ MOTO_LDRIVING,
+ MOTO_LLOADING,
+ MOTO_LPIVOT1,
+ MOTO_RDANCER,
+ MOTO_RDRIVING,
+ MOTO_RLOADARM,
+ MOTO_RLOADING,
+ MOTO_SPARE1_1,
+ MOTO_SPARE1_2,
+ MOTO_SPARE2_1,
+ MOTO_SPARE2_2,
+ DRYER_LOADARM_ROTENC,
+ DISPENSER_ROTENC1,
+ DISPENSER_ROTENC2,
+ DISPENSER_ROTENC3,
+ DISPENSER_ROTENC4,
+ DISPENSER_ROTENC5,
+ DISPENSER_ROTENC6,
+ DISPENSER_ROTENC7,
+ DISPENSER_ROTENC8,
+ SCREW_ROTENC,
+ LDANCER1_ROTENC2,
+ LDANCER2_ROTENC2,
+ LSPARE_ROTENC,
+ LSPARE_ROTENCn,
+ LSPARE1_ROTENC,
+ LSPARE2_ROTENC,
+ RDANCER_ROTENC2,
+ RSPARE_ROTENC,
+ RSPEEDSENS_ROTENC,
+ SPARE1_ROTENC,
+ SPARE2_ROTENC,
+ FAN_TACHO1,
+ FAN_TACHO3,
+ FAN_TACHO2,
+ FAN1_TACH,
+ FAN2_TACH,
+ FAN5_TACH,
+ FAN3_TACH,
+ FAN4_TACH,
+ MAX_PORT_ENUM
+}SYSTEM_PORTS_ENUM;
+typedef struct
+{
+ SYSTEM_PORTS_ENUM PortId;
+ char PortName[30];
+}PortInfoStruct;
+
+extern PortInfoStruct PortInfoTable[MAX_PORT_ENUM];
+extern uint32_t HWConfigurationFunc(MessageContainer* requestContainer);
+
+#endif
diff --git a/Software/Embedded_SW/Embedded/Modules/General/process.c b/Software/Embedded_SW/Embedded/Modules/General/process.c
new file mode 100644
index 000000000..f15c65f22
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/General/process.c
@@ -0,0 +1,121 @@
+/*
+ * process.c
+ *
+ * Created on: 4 áîøõ 2018
+ * Author: shlomo
+ */
+//********************************************************************************************************************
+#include "include.h"
+#include "process.h"
+
+#include <Modules/Stubs_Handler/DataDef.h>
+#include "heaters/heaters_ex.h"
+#include "PMR/Printing/UploadProcessParametersRequest.pb-c.h"
+#include "PMR/Printing/UploadProcessParametersResponse.pb-c.h"
+#include "PMR/Hardware/HardwarePidControlType.pb-c.h"
+#include "PMR/common/MessageContainer.pb-c.h"
+
+void ProcessRequestFunc(MessageContainer* requestContainer)
+{
+ MessageContainer responseContainer;
+ uint8_t* container_buffer;
+ uint32_t status = 0;
+
+ UploadProcessParametersRequest* request = upload_process_parameters_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data);
+ ProcessParameters* ProcessParams = request->processparameters;
+
+
+ UploadProcessParametersResponse response = UPLOAD_PROCESS_PARAMETERS_RESPONSE__INIT;
+
+ responseContainer = createContainer(MESSAGE_TYPE__UploadProcessParametersResponse, requestContainer->token, true, &response, &upload_process_parameters_request__pack, &upload_process_parameters_request__get_packed_size);
+ container_buffer = malloc(message_container__get_packed_size(&responseContainer));
+
+
+ /*
+ *
+ * uint32_t HeaterCommandRequestMessage(int HeaterId, bool OnOff, int Temperature)
+ *
+ struct _ProcessParameters
+{
+ protobuf_c_boolean has_dyeingspeed;
+ double dyeingspeed;
+ protobuf_c_boolean has_dryerbufferlength;
+ double dryerbufferlength;
+ protobuf_c_boolean has_mininkuptake;
+ double mininkuptake;
+ protobuf_c_boolean has_feedertension;
+ double feedertension;
+ protobuf_c_boolean has_pullertension;
+ double pullertension;
+ protobuf_c_boolean has_windertension;
+ double windertension;
+ protobuf_c_boolean has_headairflow;
+ double headairflow;
+ protobuf_c_boolean has_dryerairflow;
+ double dryerairflow;
+ protobuf_c_boolean has_tableindex;
+ int32_t tableindex;
+};
+
+
+ */
+ if (ProcessParams->has_mixertemp)
+ {
+ if(ProcessParams->mixertemp)
+ status |= HeaterCommandRequestMessage(HARDWARE_PID_CONTROL_TYPE__MixerHeater, true, ProcessParams->mixertemp);
+ else
+ status |= HeaterCommandRequestMessage(HARDWARE_PID_CONTROL_TYPE__MixerHeater, false, ProcessParams->mixertemp);
+ }
+ if (ProcessParams->has_headzone1temp)
+ {
+ if(ProcessParams->headzone1temp)
+ status |= HeaterCommandRequestMessage(HARDWARE_PID_CONTROL_TYPE__HeadHeaterZ1, true, ProcessParams->headzone1temp);
+ else
+ status |= HeaterCommandRequestMessage(HARDWARE_PID_CONTROL_TYPE__HeadHeaterZ1, false, ProcessParams->headzone1temp);
+ }
+ if (ProcessParams->has_headzone2temp)
+ {
+ if(ProcessParams->headzone2temp)
+ status |= HeaterCommandRequestMessage(HARDWARE_PID_CONTROL_TYPE__HeadHeaterZ2, true, ProcessParams->headzone2temp);
+ else
+ status |= HeaterCommandRequestMessage(HARDWARE_PID_CONTROL_TYPE__HeadHeaterZ2, false, ProcessParams->headzone2temp);
+ }
+ if (ProcessParams->has_headzone3temp)
+ {
+ if(ProcessParams->headzone3temp)
+ status |= HeaterCommandRequestMessage(HARDWARE_PID_CONTROL_TYPE__HeadHeaterZ3, true, ProcessParams->headzone3temp);
+ else
+ status |= HeaterCommandRequestMessage(HARDWARE_PID_CONTROL_TYPE__HeadHeaterZ3, false, ProcessParams->headzone3temp);
+ }
+ if (ProcessParams->has_dryerzone1temp)
+ {
+ if(ProcessParams->dryerzone1temp)
+ status |= HeaterCommandRequestMessage(HARDWARE_PID_CONTROL_TYPE__DryerHeater1000w, true, ProcessParams->dryerzone1temp);
+ else
+ status |= HeaterCommandRequestMessage(HARDWARE_PID_CONTROL_TYPE__DryerHeater1000w, false, ProcessParams->dryerzone1temp);
+ }
+ if (ProcessParams->has_dryerzone2temp)
+ {
+ if(ProcessParams->dryerzone2temp)
+ status |= HeaterCommandRequestMessage(HARDWARE_PID_CONTROL_TYPE__DryerHeater200w1, true, ProcessParams->dryerzone2temp);
+ else
+ status |= HeaterCommandRequestMessage(HARDWARE_PID_CONTROL_TYPE__DryerHeater200w1, false, ProcessParams->dryerzone2temp);
+ }
+ if (ProcessParams->has_dryerzone3temp)
+ {
+ if(ProcessParams->dryerzone3temp)
+ status |= HeaterCommandRequestMessage(HARDWARE_PID_CONTROL_TYPE__DryerHeater200w2, true, ProcessParams->dryerzone3temp);
+ else
+ status |= HeaterCommandRequestMessage(HARDWARE_PID_CONTROL_TYPE__DryerHeater200w2, false, ProcessParams->dryerzone3temp);
+ }
+
+ if (status)
+ {
+ responseContainer.has_error = true;
+ responseContainer.error = (ErrorCode)status;
+ }
+ size_t container_size = message_container__pack(&responseContainer, container_buffer);
+ SendChars((char*)container_buffer, container_size);
+ free(container_buffer);
+ free(requestContainer);
+}
diff --git a/Software/Embedded_SW/Embedded/Modules/General/process.h b/Software/Embedded_SW/Embedded/Modules/General/process.h
new file mode 100644
index 000000000..aa7b157a2
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/General/process.h
@@ -0,0 +1,16 @@
+/*
+ * process.h
+ *
+ * Created on: 4 áîøõ 2018
+ * Author: shlomo
+ */
+
+#ifndef MODULES_GENERAL_PROCESS_H_
+#define MODULES_GENERAL_PROCESS_H_
+
+
+void ProcessRequestFunc(MessageContainer* requestContainer);
+
+
+
+#endif /* MODULES_GENERAL_PROCESS_H_ */
diff --git a/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters.h b/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters.h
new file mode 100644
index 000000000..beaf32b2a
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters.h
@@ -0,0 +1,62 @@
+#include "PMR/Hardware/HardwarePidControl.pb-c.h"
+#include "PMR/Hardware/HardwarePidControlType.pb-c.h"
+/******************** DEFINITIONS ********************************************/
+#define MAX_AC_HEATERS HARDWARE_PID_CONTROL_TYPE__DryerHeater200w2+1
+#define MAX_TIMESLICES 200
+#define MAX_HEATERS_NUM HARDWARE_PID_CONTROL_TYPE__MixerHeater+1
+#define MAX_HEATERS_TEMPERATURE 300
+
+extern uint32_t OutputProportionalSingleStep; //A/C Heaters step size from one decision point to another - in cpu clocks. 120000 = 1 millisecod
+extern uint32_t OutputProportionalCycleTime; //A/C Heaters Cycle time in milliseconds - one for all heaters
+//extern uint32_t Heater_timerBase; //Timer handle
+extern char TimeSliceAllocation[MAX_TIMESLICES];
+extern int NumberOFSlicesInUse;
+
+
+typedef struct HeaterPIDControlConfigstruc
+{
+ int id; //HardwarePidControlType
+ char name[20];
+ int32_t outputproportionalpowerlimit;
+ int32_t outputproportionalband;
+ int32_t integraltime;
+ int32_t derivativetime;
+ int32_t sensorcorrectionadjustment;
+ int32_t sensortypeandsetpointlimits;
+ int32_t setpointramprateorsoftstartramp;
+ int32_t setpointcontroloutputrate;
+ int32_t controloutputtype;
+ int32_t ssrcontroloutputtype;
+ int32_t outputonoffhysteresisvalues;
+ int32_t processvariablesamplingrate;
+ int32_t pvinputfilterfactormode;
+ double kp;
+ double ki;
+ double kd;
+}HeaterPIDControlConfig;
+
+typedef struct HeaterCommandstruc
+{
+ int heaterid; //HardwarePidControlType
+ bool command;
+ uint32_t targettemperatue;
+}HeaterCommand;
+
+typedef struct
+{
+ bool m_isEnabled;
+ uint32_t m_SetParam;
+ uint32_t m_mesuredParam;
+ float m_preError;
+ float m_integral;
+ float m_calculatedError;
+ bool m_isReady;
+ PID_Config_Params m_params;
+}HeaterControlConfig_t;
+
+extern HeaterPIDControlConfig HeaterControl[MAX_HEATERS_NUM];
+extern HeaterControlConfig_t HeaterPIDConfig[MAX_HEATERS_NUM];
+extern HeaterCommand HeaterCmd[MAX_HEATERS_NUM];
+extern uint32_t DeviceId2Heater[MAX_HEATERS_NUM];
+
+
diff --git a/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_bit.c b/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_bit.c
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_bit.c
diff --git a/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_ex.h b/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_ex.h
new file mode 100644
index 000000000..b5249d302
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_ex.h
@@ -0,0 +1,9 @@
+#include "PMR/common/MessageContainer.pb-c.h"
+#include "PMR/Hardware/HardwarePidControl.pb-c.h"
+
+//uint32_t HeaterCommandRequestMessage(MessageContainer* requestContainer);
+uint32_t HeaterConfigRequestMessage(HardwarePidControl* request);
+uint32_t HeaterConfigSetSharedHeatersParams (uint32_t outputproportionalcycletime, uint32_t outputproportionalsinglestep);
+
+uint32_t HeaterCommandRequestMessage(int HeaterId, bool OnOff, int Temperature);
+
diff --git a/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_init.c b/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_init.c
new file mode 100644
index 000000000..55da2ecfa
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_init.c
@@ -0,0 +1,154 @@
+/************************************************************************************************************************
+ * Heaters_init.c
+ **************************************************************************************************************************/
+
+////////////////////////////////State machine operation////////////////////////////////////
+//the state machine operation is used to operate in runtime correct profile flow execution
+//by recieved esign flow of the user from the UI
+///////////////////////////////////////////////////////////////////////////////////////////
+#include "include.h"
+
+#include <Modules/Stubs_Handler/DataDef.h>
+//#include "PMR/Hardware/PIDControlConfig.pb-c.h"
+//#include "PMR/Hardware/PIDCluster.pb-c.h"
+//#include "PMR/Hardware/HeaterControl.pb-c.h"
+//#include "PMR/Hardware/HeaterCommandRequest.pb-c.h"
+//#include "PMR/Hardware/HeaterCommandRequest.pb-c.h"
+#include "PMR/Hardware/HardwarePidControl.pb-c.h"
+#include "PMR/Hardware/HardwarePidControlType.pb-c.h"
+#include "PMR/common/MessageContainer.pb-c.h"
+
+#include "../control/control.h"
+#include "../control/pidalgo.h"
+#include "include.h"
+#include <driverlib/timer.h>
+
+#include "heaters.h"
+#include "Drivers/Heater/Heater.h"
+
+
+
+/******************** STRUCTURES AND ENUMs ********************************************/
+typedef enum {
+ HeatersInitialState,
+ HeatersInit,
+ HeatersControlledOp,
+ HeatersShutdown,
+ HeatersTest,
+ MaxHeatersStates
+}HEATERS_STATES_ENUM;
+typedef enum {
+ HeatersCold,
+ HeatersAtPIDStrip,
+ HeatersOverHeat,
+ HeatersOnTest
+}HEATERS_EVENTS_ENUM;
+
+/******************** GLOBAL PARAMETERS ********************************************/
+HeaterPIDControlConfig HeaterControl[MAX_HEATERS_NUM] = {0};
+HeaterControlConfig_t HeaterPIDConfig[MAX_HEATERS_NUM] = {0};
+uint32_t DeviceId2Heater[MAX_HEATERS_NUM] = {0};
+bool AcHeaterConfigured[MAX_AC_HEATERS] = {0};
+
+/******************** CODE ********************************************/
+/*
+ * HeatersInit
+ * called by: General Hardware Init
+ * initialized all global data
+ */
+uint32_t Heaters_Init(void)
+{
+ return OK;
+}
+
+
+uint32_t HeaterConfigRequestMessage(HardwarePidControl* request)
+{
+ //uint32_t status = OK;
+ HardwarePidControlType HeaterId;
+
+ HeaterId = request->hardwarepidcontroltype;
+ int ValidationError = 0;
+
+ if ((HeaterId)&&(HeaterId< MAX_HEATERS_NUM))
+ {
+ HeaterControl[HeaterId].id = HeaterId;
+ //strncpy (HeaterControl[HeaterId].name, request->name, 20);
+ HeaterControl[HeaterId].outputproportionalpowerlimit = request->outputproportionalpowerlimit;
+ HeaterControl[HeaterId].outputproportionalband = request->outputproportionalband;
+ HeaterControl[HeaterId].integraltime = request->integraltime;
+ HeaterControl[HeaterId].derivativetime = request->derivativetime;
+ HeaterControl[HeaterId].sensorcorrectionadjustment = request->sensorcorrectionadjustment;
+ //HeaterControl[HeaterId].sensortypeandsetpointlimits = request->sensortypeandsetpointlimits;
+ HeaterControl[HeaterId].setpointramprateorsoftstartramp = request->setpointramprateorsoftstartramp;
+ HeaterControl[HeaterId].setpointcontroloutputrate = request->setpointcontroloutputrate;
+ HeaterControl[HeaterId].controloutputtype = request->controloutputtype;
+ HeaterControl[HeaterId].ssrcontroloutputtype = request->ssrcontroloutputtype;
+ HeaterControl[HeaterId].outputonoffhysteresisvalues = request->outputonoffhysteresisvalue;
+ HeaterControl[HeaterId].processvariablesamplingrate = request->processvariablesamplingrate;
+ HeaterControl[HeaterId].pvinputfilterfactormode = request->pvinputfilterfactormode;
+
+ if (HeaterId < MAX_AC_HEATERS)
+ AcHeaterConfigured[HeaterId] = true;
+
+ //check if all A/C heaters are defined. if they are - validate the configuration
+ if (HeaterControl[HARDWARE_PID_CONTROL_TYPE__DryerHeater1000w].id
+ &&HeaterControl[HARDWARE_PID_CONTROL_TYPE__DryerHeater200w1].id
+ &&HeaterControl[HARDWARE_PID_CONTROL_TYPE__DryerHeater200w2].id)
+ {
+ if (HeaterControl[HARDWARE_PID_CONTROL_TYPE__DryerHeater1000w].outputproportionalpowerlimit
+ + HeaterControl[HARDWARE_PID_CONTROL_TYPE__DryerHeater200w1].outputproportionalpowerlimit
+ + HeaterControl[HARDWARE_PID_CONTROL_TYPE__DryerHeater200w2].outputproportionalpowerlimit> 100)
+ ValidationError += 2;
+ if (ValidationError)
+ {
+ LOG_ERROR (ValidationError, "Validation Error in Heaters Control");
+ return ERROR;
+ }
+ }
+ return OK;
+ }
+ return ERROR;
+
+}
+
+/*
+ * HeaterConfigSetSharedHeatersParams - prepare the time slices for A/C heaters co-ordinated operation
+ * called by the general hardware HWConfigurationFunc
+ * parameters - the cycle time for the coordinated operation, the size (in MCU cycles) of a single step.
+ */
+uint32_t HeaterConfigSetSharedHeatersParams(uint32_t outputproportionalcycletime, uint32_t outputproportionalsinglestep)
+{
+ int Slice_i;
+ int Heater1000Slices,Heater200aSlices /*,Heater200bSlices Currently both 200W heaters will work together*/;
+
+ //A/C Heaters Cycle time in milliseconds - one for all heaters
+ OutputProportionalCycleTime = outputproportionalcycletime;
+
+ //A/C Heaters step size from one decision point to another - in cpu clocks. 120000 = 1 millisecod
+ OutputProportionalSingleStep = outputproportionalsinglestep;
+
+ // calculate how many milliseconds is in each operating cycle (should be an integer number)
+ uint32_t MillisecondsPerChange = OutputProportionalSingleStep/120000;
+
+ // calculate how many time slices are used. the total cycle time / the length of one operating cycle. (one added to put a time gap??? TBD)
+ NumberOFSlicesInUse = (OutputProportionalCycleTime/MillisecondsPerChange);
+
+ if (NumberOFSlicesInUse > MAX_TIMESLICES )
+ {
+ LOG_ERROR (NumberOFSlicesInUse, "NumberOFSlicesInUse too high");
+ return ERROR;//NumberOFSlicesInUse = MAX_TIMESLICES;
+ }
+
+ // all numbers are rounded down. better to have carefully calculated numbers
+ Heater1000Slices = HeaterControl[HARDWARE_PID_CONTROL_TYPE__DryerHeater1000w].outputproportionalpowerlimit * NumberOFSlicesInUse / 100;
+ Heater200aSlices = HeaterControl[HARDWARE_PID_CONTROL_TYPE__DryerHeater200w1].outputproportionalpowerlimit * NumberOFSlicesInUse / 100;
+
+ //mark the time slices for heaters operation as empty / Heater1000 / Heater 200
+ memset (TimeSliceAllocation,0xFF,sizeof(TimeSliceAllocation));
+ for (Slice_i = 0; Slice_i < Heater1000Slices;Slice_i++ ) TimeSliceAllocation[Slice_i] = HARDWARE_PID_CONTROL_TYPE__DryerHeater1000w;
+ for (Slice_i = Heater1000Slices; Slice_i < Heater1000Slices+Heater200aSlices;Slice_i++ ) TimeSliceAllocation[Slice_i] = HARDWARE_PID_CONTROL_TYPE__DryerHeater200w1;
+
+ return OK;
+
+}
diff --git a/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_maint.c b/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_maint.c
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_maint.c
diff --git a/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_print.c b/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_print.c
new file mode 100644
index 000000000..3eeff9ec3
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_print.c
@@ -0,0 +1,247 @@
+/************************************************************************************************************************
+ * Heaters_print.c
+ **************************************************************************************************************************/
+
+////////////////////////////////State machine operation////////////////////////////////////
+//the state machine operation is used to operate in runtime correct profile flow execution
+//by recieved esign flow of the user from the UI
+///////////////////////////////////////////////////////////////////////////////////////////
+#include "include.h"
+
+#include <Modules/Stubs_Handler/DataDef.h>
+//#include "PMR/Hardware/PIDCluster.pb-c.h"
+#include "PMR/Hardware/HardwarePidControlType.pb-c.h"
+#include "PMR/Hardware/HardwarePidControl.pb-c.h"
+#include "PMR/common/MessageContainer.pb-c.h"
+
+#include "../control/control.h"
+#include "../control/pidalgo.h"
+#include "include.h"
+#include <driverlib/timer.h>
+
+#include "heaters.h"
+#include "Drivers/Heater/Heater.h"
+
+
+/******************** GLOBAL PARAMETERS ********************************************/
+HeaterCommand HeaterCmd[MAX_HEATERS_NUM] = {};
+int NumberOFSlicesInUse = 0;
+bool HeatersRestart = false;
+
+uint32_t OutputProportionalSingleStep = 0; //A/C Heaters step size from one decision point to another - in cpu clocks. 120000 = 1 millisecod
+uint32_t Heater_timerBase = TIMER2_BASE; //Timer handle
+uint32_t OutputProportionalCycleTime = 0; //A/C Heaters Cycle time in milliseconds - one for all heaters
+char TimeSliceAllocation[MAX_TIMESLICES] = {0};
+
+bool InitialHeatingState = false;
+/******************** FUNCTIONS ********************************************/
+uint32_t HeaterControlCBFunction(uint32_t deviceID, uint32_t ReadValue);
+uint32_t PrepareHeater(int HeaterId, uint32_t SetTemperatue);
+
+/*
+ * HeaterCommandRequestMessage
+ * called by: Communication from host
+ * initialized all global data
+ */
+uint32_t HeaterCommandRequestMessage(int HeaterId, bool OnOff, int Temperature)
+{
+ //uint32_t status = NOT_SUPPORTED;
+ //MessageContainer responseContainer;
+ if ((HeaterId)&&(HeaterId< MAX_HEATERS_NUM))
+ {
+ if (HeaterControl[HeaterId].id != HeaterId) // heater configuration missing
+ {
+ LOG_ERROR (HeaterId, "Heater is not yet configured");
+ return ERROR;
+ }
+ HeaterCmd[HeaterId].heaterid = HeaterId;
+ HeaterCmd[HeaterId].command = OnOff;
+ HeaterCmd[HeaterId].targettemperatue = Temperature;
+ }
+ bool HeaterState = GetHeaterState(HeaterId);
+
+ if ((HeaterState == HEATER_OFF)&& (OnOff == HEATER_ON)) //start heating
+ {
+ //set the heater control parameters
+ //set the target operation temperature
+ //start the control
+ PrepareHeater(HeaterId,Temperature); //prepare the heaters control info
+ //set the power balance handler (if not set yet)
+ ROM_TimerConfigure(Heater_timerBase, TIMER_CFG_PERIODIC); // 32 bits Timer
+ ROM_IntEnable(INT_TIMER2B);
+ ROM_TimerIntEnable(Heater_timerBase, TIMER_TIMA_TIMEOUT);
+ // if the heater is off (?) start it.
+ ActivateHeater(HeaterId);
+ //set the heater operation mode to fast heating - depended on the current temperature
+ // timers are prepared but not started yet!!! only when the system is hot.
+
+ }
+ else if ((HeaterState == HEATER_ON)&& (OnOff == HEATER_ON)) //set temperature
+ {
+ HeaterPIDConfig[HeaterId].m_SetParam = Temperature;
+ // if the heater is not on return (?).
+ //set the target operation temperature
+ //set the heater operation mode to fast heating - depended on the current temperature
+ }
+ else if ((HeaterState == HEATER_ON)&& (OnOff == HEATER_OFF)) //stop heating
+ {
+ //turn off the heater
+ //stop the control
+ HeaterPIDConfig[HeaterId].m_SetParam = HeaterId;
+ }
+ else
+ {
+ LOG_ERROR (OnOff, "unsupported command id");
+ return ERROR;
+ }
+
+ return OK;
+}
+/*
+ * PrepareHeater
+ * called by: Communication from host
+ * initialized all global data
+ */
+uint32_t PrepareHeater(int HeaterId, uint32_t SetTemperatue)
+{
+ assert(HeaterId < MAX_HEATERS_NUM);
+ assert(SetTemperatue < MAX_HEATERS_TEMPERATURE);
+
+ //start thread control for all motors
+ HeaterPIDConfig[HeaterId].m_params.MAX = HeaterControl[HeaterId].outputproportionalpowerlimit;
+ HeaterPIDConfig[HeaterId].m_params.MIN = .0;
+ HeaterPIDConfig[HeaterId].m_params.Kd = HeaterControl[HeaterId].kd;
+ HeaterPIDConfig[HeaterId].m_params.Kp = HeaterControl[HeaterId].kp;
+ HeaterPIDConfig[HeaterId].m_params.Ki = HeaterControl[HeaterId].ki;
+ HeaterPIDConfig[HeaterId].m_params.dt = eHunderdMillisecond;
+ HeaterPIDConfig[HeaterId].m_calculatedError = 0;
+ HeaterPIDConfig[HeaterId].m_integral = 0;
+ HeaterPIDConfig[HeaterId].m_isEnabled = true;
+ HeaterPIDConfig[HeaterId].m_isReady = true;
+ HeaterPIDConfig[HeaterId].m_mesuredParam = 0;
+ HeaterPIDConfig[HeaterId].m_preError = 0;
+ HeaterPIDConfig[HeaterId].m_SetParam = SetTemperatue;//need to update SetParams on presegment stage
+ AddControlCallback(DeviceId2Heater[HeaterId], HeaterControlCBFunction, eHunderdMillisecond);
+
+ return OK;
+}
+
+/*
+ * HeaterControlCBFunction
+ * called by: Communication from host
+ * initialized all global data
+ */
+
+uint32_t HeaterControlCBFunction(uint32_t deviceID, uint32_t ReadValue)
+{
+ int i,index=MAX_HEATERS_NUM;
+ char str[100];
+ uint8_t len = 0;
+
+ for (i=0;i<MAX_HEATERS_NUM;i++)
+ if (DeviceId2Heater[i] == deviceID)
+ {
+ index = i;
+ break;
+ }
+ if (index==MAX_HEATERS_NUM)
+ {
+ LOG_ERROR (deviceID, "No heater for device");
+ return 0xFFFFFFFF;
+ }
+ // check if the read value is within the proportional band
+ if (ReadValue > (HeaterCmd[index].targettemperatue * (1+HeaterControl[index].outputproportionalband)))
+ {
+ //Heaters OFF until coming into the proportional band
+ len = usnprintf(str, 100, "\r\n HeaterControlCBFunction devId %d temp %d over proportional band %d of set temp %d "
+ ,index, ReadValue,HeaterControl[index].outputproportionalband,HeaterCmd[index].targettemperatue);
+ Report(str, __FILE__,__LINE__,0, RpMessage, index, deviceID);
+ return OK;
+ }
+ if (ReadValue < (HeaterCmd[index].targettemperatue * (1-HeaterControl[index].outputproportionalband)))
+ {
+ len = usnprintf(str, 100, "\r\n HeaterControlCBFunction devId %d temp %d below proportional band %d of set temp %d "
+ ,index, ReadValue,HeaterControl[index].outputproportionalband,HeaterCmd[index].targettemperatue);
+ Report(str, __FILE__,__LINE__,0, RpMessage, index, deviceID);
+ //Heaters ON until coming into the proportional band
+ return OK;
+ }
+
+ if(HeaterPIDConfig[index].m_isEnabled && (HeaterPIDConfig[index].m_SetParam != 0))
+ {
+ HeaterPIDConfig[index].m_mesuredParam = ReadValue;
+ HeaterPIDConfig[index].m_calculatedError = PIDAlgorithmCalculation(HeaterPIDConfig[index].m_SetParam , HeaterPIDConfig[index].m_mesuredParam,
+ &HeaterPIDConfig[index].m_params, &HeaterPIDConfig[index].m_preError, &HeaterPIDConfig[index].m_integral);
+ if (HeaterPIDConfig[index].m_calculatedError >= HeaterPIDConfig[index].m_params.MAX)
+ {
+ HeaterPIDConfig[index].m_calculatedError = HeaterPIDConfig[index].m_params.MAX;
+ }
+ if (HeaterPIDConfig[index].m_calculatedError < HeaterPIDConfig[index].m_params.MIN)
+ {
+ HeaterPIDConfig[index].m_calculatedError = HeaterPIDConfig[index].m_params.MIN;
+ }
+
+ //SetMotorFreq (index, HeaterControl[index].m_calculatedError);
+ }
+
+ return OK;
+}
+
+/*
+ * EightMilliSecondHeatersInterrupt - a timer based interrupt, that will handle the time sharing between the A/C heaters
+ * There is a need to prevent the system from activating all A/C heaters at the same time, due to electrical current problems
+ */
+int SliceCounter = 0;
+void EightMilliSecondHeatersInterrupt(UArg arg0)
+{
+ char str[100];
+ uint8_t len = 0;
+
+ len = usnprintf(str, 100, "\r\n EightMilliSecondHeatersInterrupt SliceCounter %d Owner %d H1000 %d H2000 %d"
+ ,SliceCounter,TimeSliceAllocation[SliceCounter],HeatersRestart,NumberOFSlicesInUse);
+ Report(str, __FILE__,__LINE__,0, RpMessage, SliceCounter, TimeSliceAllocation[SliceCounter]);
+ ROM_IntMasterDisable();
+
+ if (TimeSliceAllocation[SliceCounter] == HARDWARE_PID_CONTROL_TYPE__DryerHeater1000w)
+ {
+ //If HARDWARE_PID_CONTROL_TYPE__DryerHeater1000w should be active
+ //Activate HARDWARE_PID_CONTROL_TYPE__DryerHeater1000w
+ ActivateHeater (HARDWARE_PID_CONTROL_TYPE__DryerHeater1000w);
+ //DeActivate HARDWARE_PID_CONTROL_TYPE__DryerHeater200w1
+ DeActivateHeater (HARDWARE_PID_CONTROL_TYPE__DryerHeater200w1);
+ DeActivateHeater (HARDWARE_PID_CONTROL_TYPE__DryerHeater200w2);
+ }
+ else if (TimeSliceAllocation[SliceCounter] == HARDWARE_PID_CONTROL_TYPE__DryerHeater200w1)
+ {
+ //DeActivate HARDWARE_PID_CONTROL_TYPE__DryerHeater1000w
+ DeActivateHeater (HARDWARE_PID_CONTROL_TYPE__DryerHeater1000w);
+ //If HARDWARE_PID_CONTROL_TYPE__DryerHeater200w1 should be active
+ //Activate HARDWARE_PID_CONTROL_TYPE__DryerHeater200w1
+ ActivateHeater (HARDWARE_PID_CONTROL_TYPE__DryerHeater200w1);
+ ActivateHeater (HARDWARE_PID_CONTROL_TYPE__DryerHeater200w2);
+ }
+ else
+ {
+ //DeActivate HARDWARE_PID_CONTROL_TYPE__DryerHeater1000w
+ DeActivateHeater (HARDWARE_PID_CONTROL_TYPE__DryerHeater1000w);
+ //DeActivate HARDWARE_PID_CONTROL_TYPE__DryerHeater200w1
+ DeActivateHeater (HARDWARE_PID_CONTROL_TYPE__DryerHeater200w1);
+ DeActivateHeater (HARDWARE_PID_CONTROL_TYPE__DryerHeater200w2);
+ }
+ //handle the time sharing module
+ SliceCounter++;
+ if (SliceCounter >= NumberOFSlicesInUse)
+ SliceCounter = 0;
+
+ if (HeatersRestart == true)
+ {
+ ROM_TimerLoadSet(Heater_timerBase, TIMER_BOTH,OutputProportionalSingleStep/*twelve millisecond???*/);
+ }
+
+ ROM_TimerIntClear(Heater_timerBase, TIMER_TIMA_TIMEOUT); // Clear the timer interrupt
+ //
+ // Enable all interrupts.
+ //
+ ROM_IntMasterEnable();
+ return ;
+}
diff --git a/Software/Embedded_SW/Embedded/Modules/IDS/IDS.h b/Software/Embedded_SW/Embedded/Modules/IDS/IDS.h
new file mode 100644
index 000000000..1c9fee547
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/IDS/IDS.h
@@ -0,0 +1,25 @@
+#include "PMR/common/MessageContainer.pb-c.h"
+#include "PMR/Hardware/HardwareDispenser.pb-c.h"
+
+#define MAX_SYSTEM_DISPENSERS 8
+typedef struct
+{
+ int32_t dispensercapacity; //milliliters
+ int32_t midtankcapacity;//milliliters
+ double nlperpulse; //nanoliter per step , uStep = 1
+ uint32_t minfrequency;
+ uint32_t maxfrequency;
+ uint32_t minmicrostep;
+ uint32_t maxmicrostep;
+ double correctiongain;
+ double ratiotodryerspeed;
+ double kp;
+ double ki;
+ double kd;
+ double changeslope;
+ double highlengthmicrosecond;
+ int32_t controltiming; //10-100-1000 milliseconds
+ int32_t id;
+}DispenserConfigStruc;
+
+uint32_t DispenserConfigMessage(HardwareDispenser * request);
diff --git a/Software/Embedded_SW/Embedded/Modules/IDS/IDS_BIT.c b/Software/Embedded_SW/Embedded/Modules/IDS/IDS_BIT.c
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/IDS/IDS_BIT.c
diff --git a/Software/Embedded_SW/Embedded/Modules/IDS/IDS_ex.h b/Software/Embedded_SW/Embedded/Modules/IDS/IDS_ex.h
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/IDS/IDS_ex.h
diff --git a/Software/Embedded_SW/Embedded/Modules/IDS/IDS_init.c b/Software/Embedded_SW/Embedded/Modules/IDS/IDS_init.c
new file mode 100644
index 000000000..0294615b6
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/IDS/IDS_init.c
@@ -0,0 +1,46 @@
+/************************************************************************************************************************
+ **************************************************************************************************************************/
+
+#include "include.h"
+
+#include <Modules/Stubs_Handler/DataDef.h>
+
+#include "ids.h"
+#include "PMR/common/MessageContainer.pb-c.h"
+#include "PMR/Hardware/HardwareDispenser.pb-c.h"
+
+
+DispenserConfigStruc DispensersCfg[ MAX_SYSTEM_DISPENSERS];
+
+
+
+uint32_t DispenserConfigMessage(HardwareDispenser * request)
+{
+ uint32_t status = PASSED;
+ int Dispenser_i;
+
+ Dispenser_i = request->hardwaredispensertype;
+ if ((Dispenser_i)&&(Dispenser_i< MAX_SYSTEM_DISPENSERS))
+ {
+
+ DispensersCfg[Dispenser_i].id = request->hardwaredispensertype;
+ DispensersCfg[Dispenser_i].minfrequency = request->minfrequency;
+ DispensersCfg[Dispenser_i].maxfrequency = request->maxfrequency;
+ DispensersCfg[Dispenser_i].minmicrostep = request->minmicrostep;
+ DispensersCfg[Dispenser_i].maxmicrostep = request->maxmicrostep;
+ DispensersCfg[Dispenser_i].correctiongain = request->correctiongain;
+ DispensersCfg[Dispenser_i].ratiotodryerspeed = request->ratiotodryerspeed;
+ DispensersCfg[Dispenser_i].kp = request->kp;
+ DispensersCfg[Dispenser_i].ki = request->ki;
+ DispensersCfg[Dispenser_i].kd = request->kd;
+ DispensersCfg[Dispenser_i].changeslope = request->changeslope;
+ DispensersCfg[Dispenser_i].highlengthmicrosecond = request->highlengthmicrosecond;
+ DispensersCfg[Dispenser_i].dispensercapacity= request->capacity;
+// DispensersCfg[Dispenser_i].midtankcapacity = request->midtankcapacity;
+ DispensersCfg[Dispenser_i].nlperpulse = request->nlperpulse;
+ DispensersCfg[Dispenser_i].controltiming = request->controltiming;
+ return status;
+ }
+ else return Dispenser_i;
+
+}
diff --git a/Software/Embedded_SW/Embedded/Modules/IDS/IDS_maint.c b/Software/Embedded_SW/Embedded/Modules/IDS/IDS_maint.c
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/IDS/IDS_maint.c
diff --git a/Software/Embedded_SW/Embedded/Modules/IDS/IDS_print.c b/Software/Embedded_SW/Embedded/Modules/IDS/IDS_print.c
new file mode 100644
index 000000000..32b147569
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/IDS/IDS_print.c
@@ -0,0 +1,43 @@
+/************************************************************************************************************************
+ * Ids_print.c
+ * Printing module is responsible for :
+ * operating diffrent winding algorithms with predefined parameters from the UI
+ * operating the dispensers according to predefined dispensing rate from the UI
+ **************************************************************************************************************************/
+#include "include.h"
+#include "ids.h"
+#include "../control/control.h"
+#include "../control/pidalgo.h"
+#include "PMR/Hardware/Hardwaremotor.pb-c.h"
+#include "PMR/Hardware/HardwareDispenser.pb-c.h"
+#include "StateMachines/Printing/printingSTM.h"
+
+
+
+/******************** STRUCTURES AND ENUMs ********************************************/
+/******************** GLOBAL PARAMETERS ********************************************/
+
+
+/*
+ * IDS Printing support
+ * Prepare: build pressure in all participating dispensers
+ * Print - dispense ink to the printing head
+ * stop - stop dispensing
+ *
+ * control processes:
+ * on prepare stage - each 10msec against the pressure sensors
+ * on print stage - every 10/100 msec against the speed sensor
+ *
+ * */
+//Dispenser Pressure control
+//callback - calls printing stm with the result
+
+// registration - 10 msec, dispenser pressure sensor
+// AddControlCallback(DeviceId2Heater[HeaterId], HeaterControlCBFunction, eHunderdMillisecond);
+// start the dispenser pressure building - move up in a TBD speed, valve closed
+//Dispenser Speed control
+//callback - handles speed
+// registration - 10msec, dispenser speed senseo
+// start the dispensing - move up according to the segment defined speed and microstepping, valve opened
+//
+
diff --git a/Software/Embedded_SW/Embedded/Modules/IDS/MixerHandler.c b/Software/Embedded_SW/Embedded/Modules/IDS/MixerHandler.c
new file mode 100644
index 000000000..ce423ab72
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/IDS/MixerHandler.c
@@ -0,0 +1,37 @@
+/*
+ * MixerHandle.c
+ *
+ * Created on: 26 áôáø× 2018
+ * Author: shlomo
+ */
+
+#ifndef MODULES_IDS_MIXERHANDLER_C_
+#define MODULES_IDS_MIXERHANDLER_C_
+#include "include.h"
+#include "MixerHandler.h"
+typedef enum
+{
+ MixerStateNone,
+ MixerStateHead,
+ MixerStateWaste
+}MIXER_STATE_ENUM;
+
+MIXER_STATE_ENUM MixerState = MixerStateNone;
+
+uint32_t MixerHandlerSwitchToWaste(void)
+{
+ return OK;
+
+}
+uint32_t MixerHandlerSwitchToHead(void)
+{
+ return OK;
+}
+uint32_t MixerHandlerGetState(void)
+{
+ return MixerState;
+}
+
+
+
+#endif /* MODULES_IDS_MIXERHANDLER_C_ */
diff --git a/Software/Embedded_SW/Embedded/Modules/IDS/MixerHandler.h b/Software/Embedded_SW/Embedded/Modules/IDS/MixerHandler.h
new file mode 100644
index 000000000..51093e1b7
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/IDS/MixerHandler.h
@@ -0,0 +1,17 @@
+/*
+ * MixerHandle.h
+ *
+ * Created on: 26 áôáø× 2018
+ * Author: shlomo
+ */
+
+#ifndef MODULES_IDS_MIXERHANDLER_H_
+#define MODULES_IDS_MIXERHANDLER_H_
+
+extern uint32_t MixerHandlerSwitchToWaste(void);
+extern uint32_t MixerHandlerSwitchToHead(void);
+extern uint32_t MixerHandlerGetState(void);
+
+
+
+#endif /* MODULES_IDS_MIXERHANDLER_H_ */
diff --git a/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Calculate.c b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Calculate.c
new file mode 100644
index 000000000..f12b92adc
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Calculate.c
@@ -0,0 +1,39 @@
+
+#include <PMR/Common/MessageContainer.pb-c.h>
+#include <PMR/Stubs/CalculateRequest.pb-c.h>
+#include <PMR/Stubs/CalculateResponse.pb-c.h>
+#include "include.h"
+#include "driverlib/gpio.h"
+
+#include "drivers/twine_usblib/usb_serial_adapter.h"
+#include "drivers/twine_graphicslib/graphics_adapter.h"
+#include "Container.h"
+
+void Stub_CalculateRequest(MessageContainer* requestContainer)
+{
+ MessageContainer responseContainer;
+
+ CalculateRequest* request = calculate_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data);
+
+ writeLine("Calculate Request: ");
+ writeFloat(request->a);
+ writeString(" + ");
+ writeFloat(request->b);
+
+ CalculateResponse response = CALCULATE_RESPONSE__INIT;
+ response.sum = request->a + request->b;
+ response.has_sum = true;
+
+ responseContainer = createContainer(MESSAGE_TYPE__CalculateResponse, requestContainer->token, true, &response, &calculate_response__pack, &calculate_response__get_packed_size);
+
+ writeLine("Sending Response: ");
+ writeFloat(response.sum);
+
+ free(request);
+
+ uint8_t* container_buffer = malloc(message_container__get_packed_size(&responseContainer));
+ size_t container_size = message_container__pack(&responseContainer, container_buffer);
+ SendChars((char*)container_buffer, container_size);
+ free(container_buffer);
+ free(requestContainer);
+}
diff --git a/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Calculate.h b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Calculate.h
new file mode 100644
index 000000000..0623435f0
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Calculate.h
@@ -0,0 +1,8 @@
+#ifndef STUB_CALCULATE_H
+#define STUB_CALCULATE_H
+
+#include "PMR/Common/MessageContainer.pb-c.h"
+void Stub_CalculateRequest(MessageContainer* requestContainer);
+
+#endif //STUB_CALCULATE_H
+
diff --git a/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Container.c b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Container.c
new file mode 100644
index 000000000..b9c3ffbd0
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Container.c
@@ -0,0 +1,125 @@
+#include <PMR/Common/MessageContainer.pb-c.h>
+#include "include.h"
+#include "driverlib/gpio.h"
+
+//#include "usb_serial_adapter.h"
+//#include "graphics_adapter.h"
+#include "Calculate.h"
+#include "Progress.h"
+#include "Stub_Cartridge.h"
+#include "Stub_Dispenser.h"
+#include "Stub_GPIO.h"
+#include "Stub_Heater.h"
+#include "Stub_MotorEncoder.h"
+#include "Stub_OptLimitSwitch.h"
+#include "Stub_SteperMotor.h"
+#include "Stub_Valve.h"
+#include "Stub_ExtFlash.h"
+#include "General/GeneralHardware.h"
+#include "heaters/heaters_ex.h"
+#include "StateMachines/Printing/PrintingSTM.h"
+#include "Modules/General/process.h"
+#include "Common/report/report.h"
+
+
+MessageContainer createContainer(MessageType type, char* token, protobuf_c_boolean completed, void* response, size_t (*packPtr)(void*, uint8_t*), size_t (*sizePtr)(void*))
+{
+ MessageContainer container = MESSAGE_CONTAINER__INIT;
+ container.completed = completed;
+ container.token = token;
+ container.has_completed = true;
+ container.has_data = true;
+ container.has_type = true;
+ container.type = type;
+
+
+
+ uint8_t* response_buffer = malloc((*sizePtr)(response));
+ size_t response_size = (*packPtr)(response, response_buffer);
+ container.data.data = response_buffer;
+ container.data.len = response_size;
+
+ free(response);
+ return container;
+}
+
+void receive_callback(char* buffer, size_t length)
+{
+ //SendChars(buffer,length);
+ //draw_string(buffer, length);
+ //draw_image((uint8_t *)buffer);
+
+ //writeLine("Received ");
+ //writeFloat(length);
+ //writeString(" bytes");
+ //writeLine("Parsing message...");
+
+ MessageContainer* requestContainer = message_container__unpack(NULL, length, (uint8_t*)buffer);
+
+ switch(requestContainer->type)
+ {
+ case MESSAGE_TYPE__CalculateRequest:
+ Stub_CalculateRequest(requestContainer);
+ break;
+ case MESSAGE_TYPE__ProgressRequest:
+ Stub_ProgressRequest(requestContainer);
+ break;
+ case MESSAGE_TYPE__StubCartridgeReadRequest:
+ Stub_CartridgeReadRequest(requestContainer);
+ break;
+ case MESSAGE_TYPE__StubCartridgeWriteRequest:
+ Stub_CartridgeWriteRequest(requestContainer);
+ break;
+ case MESSAGE_TYPE__StubDispenserRequest:
+ Stub_DispenserRequest(requestContainer);
+ break;
+ case MESSAGE_TYPE__StubGPIOInputSetupRequest:
+ Stub_GPIOInputSetupRequest(requestContainer);
+ break;
+ case MESSAGE_TYPE__StubGPIOReadBitRequest:
+ Stub_GPIOReadBitRequest(requestContainer);
+ break;
+ case MESSAGE_TYPE__StubGPIOReadByteRequest:
+ Stub_GPIOReadByteRequest(requestContainer);
+ break;
+ case MESSAGE_TYPE__StubGPIOWriteBitRequest:
+ Stub_GPIOWriteBitRequest(requestContainer);
+ break;
+ case MESSAGE_TYPE__StubGPIOWriteByteRequest:
+ Stub_GPIOWriteByteRequest(requestContainer);
+ break;
+ case MESSAGE_TYPE__StubHeaterRequest:
+ Stub_HeaterRequest(requestContainer);
+ break;
+ case MESSAGE_TYPE__StubMotorEncoderRequest:
+ Stub_MotorEncoderRequest(requestContainer);
+ break;
+ case MESSAGE_TYPE__StubOptLimitSwitchRequest:
+ Stub_OptLimitSwitchRequest(requestContainer);
+ break;
+ case MESSAGE_TYPE__StubSteperMotorRequest:
+ Stub_SteperMotorRequest(requestContainer);
+ break;
+ case MESSAGE_TYPE__StubValveRequest:
+ Stub_ValveRequest(requestContainer);
+ break;
+ case MESSAGE_TYPE__StubExtFlashReadRequest:
+ Stub_ExtFlashReadRequest(requestContainer);
+ break;
+ case MESSAGE_TYPE__StubExtFlashWriteRequest:
+ Stub_ExtFlashWriteRequest(requestContainer);
+ break;
+ case MESSAGE_TYPE__DebugLogRequest:
+ ReportInitMessage(requestContainer);
+ break;
+ case MESSAGE_TYPE__JobRequest:
+ JobRequestFunc(requestContainer);
+ break;
+ case MESSAGE_TYPE__UploadProcessParametersRequest:
+ ProcessRequestFunc(requestContainer);
+ break;
+ default:
+ //unsupported message type !!
+ break;
+ }
+}
diff --git a/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Container.h b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Container.h
new file mode 100644
index 000000000..2c5d9fa60
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Container.h
@@ -0,0 +1,7 @@
+#ifndef CONTAINER_H
+#define CONTAINER_H
+
+MessageContainer createContainer(MessageType type, char* token, protobuf_c_boolean completed, void* response, size_t (*packPtr)(void*, uint8_t*), size_t (*sizePtr)(void*));
+void receive_callback(char* buffer, size_t length);
+
+#endif //CONTAINER_H
diff --git a/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/DataDef.h b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/DataDef.h
new file mode 100644
index 000000000..08da87c09
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/DataDef.h
@@ -0,0 +1,71 @@
+#ifndef DATADEF_H
+#define DATADEF_H
+
+#define EVALUATION_BOARD // to use the LCD only when using the evaluation board
+#define USE_HIGH_SPEED_GPIO // to use AHB GPIO (A..J) ports A-J APB or AHB, ports K-Q on AHB only
+
+#define ON 1
+#define OFF 0
+
+enum
+{
+ PASSED = 0,
+ FAILED = 1,
+ NOT_SUPPORTED = 254,
+ VERIFIED = 255
+};
+
+
+#define OK 0
+#define ERROR 1
+
+#define ENABLE 0
+#define DISABLE 1
+
+#define NEW 0
+#define USED 1
+
+#define START 1
+#define STOP 0
+
+// motor direction
+#define CW 1 // clockwise
+#define CCW 0 // counter clockwise
+
+#define TRUE 1
+#define FALSE 0
+
+#define INPUT 1
+#define OUTPUT 0
+
+#define PULLDOWN 0
+#define PULLUP 1
+
+#define TX 0
+#define RX 1
+#define TXRX 2
+
+//---------------------------------------------------------------------
+#pragma diag_suppress 169 /* Avoid warnings on VOID * conversions (protobuf issue)
+The warning:
+#169-D argument of type "size_t (*)(const CalculateResponse *, uint8_t *)" is incompatible with parameter of type "size_t (*)(void *, uint8_t *)" Calculate.c /twine_usblib_demo/PMR/Stubs line 53 C/C++ Problem
+
+
+//#pragma diag_suppress 190 // Avoid the warning - #190-D enumerated type mixed with another type protobuf-c.c
+ *
+or in the environment add command line:
+
+Project -> properties ->
+
+Add the warning number in
+Supports diagnostic <id> (--diag_suppress, - pds)
+169
+190
+*/
+
+//Project Properties->Build->Compiler->Include Options
+//There may be paths there relative to a build variable, rather than hard-coded paths, that may be triggering the error.
+
+
+
+#endif /* DATADEF_H */
diff --git a/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Progress.c b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Progress.c
new file mode 100644
index 000000000..c44df4ef7
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Progress.c
@@ -0,0 +1,48 @@
+
+#include <PMR/Common/MessageContainer.pb-c.h>
+#include <PMR/Stubs/ProgressRequest.pb-c.h>
+#include <PMR/Stubs/ProgressResponse.pb-c.h>
+#include "include.h"
+#include "driverlib/gpio.h"
+
+#include "drivers/twine_usblib/usb_serial_adapter.h"
+//#include "graphics_adapter.h"
+#include "Container.h"
+
+void Stub_ProgressRequest(MessageContainer* requestContainer)
+{
+ MessageContainer responseContainer;
+
+ ProgressRequest* request = progress_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data);
+
+ //writeLine("Progress Request...");
+
+ ProgressResponse response = PROGRESS_RESPONSE__INIT;
+ response.has_progress = true;
+
+ int i = 0;
+ for (i = 0; i < request->amount; i++)
+ {
+ response.progress = i;
+ responseContainer = createContainer(MESSAGE_TYPE__ProgressResponse, requestContainer->token, false, &response, &progress_response__pack, &progress_response__get_packed_size);
+ uint8_t* container_buffer = malloc(message_container__get_packed_size(&responseContainer));
+ size_t container_size = message_container__pack(&responseContainer, container_buffer);
+ //writeLine("Sending Progress: ");
+ //writeFloat(response.progress);
+ SendChars((char*)container_buffer, container_size);
+
+ int co = 0;
+ for (co = 0; co < request->delay; co++)
+ {
+ __delay_cycles(1000000);
+ }
+ }
+
+ responseContainer = createContainer(MESSAGE_TYPE__ProgressResponse, requestContainer->token, true, &response, &progress_response__pack, &progress_response__get_packed_size);
+ uint8_t* container_buffer = malloc(message_container__get_packed_size(&responseContainer));
+ size_t container_size = message_container__pack(&responseContainer, container_buffer);
+ //writeLine("Progress Completed!");
+ SendChars((char*)container_buffer, container_size);
+ return;
+
+}
diff --git a/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Progress.h b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Progress.h
new file mode 100644
index 000000000..a0595e4b9
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Progress.h
@@ -0,0 +1,7 @@
+#ifndef PROGRESS_H
+#define PROGRESS_H
+
+#include "PMR/Common/MessageContainer.pb-c.h"
+void Stub_ProgressRequest(MessageContainer* requestContainer);
+
+#endif //PROGRESS_H
diff --git a/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_Cartridge.c b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_Cartridge.c
new file mode 100644
index 000000000..166cf9e7a
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_Cartridge.c
@@ -0,0 +1,128 @@
+
+
+#include <PMR/Common/MessageContainer.pb-c.h>
+#include <PMR/Stubs/StubCartridgeReadRequest.pb-c.h>
+#include <PMR/Stubs/StubCartridgeReadResponse.pb-c.h>
+#include <PMR/Stubs/StubCartridgeWriteRequest.pb-c.h>
+#include <PMR/Stubs/StubCartridgeWriteResponse.pb-c.h>
+#include "include.h"
+#include "inc/hw_uart.h"
+#include "driverlib/gpio.h"
+
+#include "drivers/twine_usblib/usb_serial_adapter.h"
+#include "drivers/twine_graphicslib/graphics_adapter.h"
+
+#include "Container.h"
+#include "Stub_Status.h"
+
+void Stub_CartridgeReadRequest(MessageContainer* requestContainer)
+{
+ uint32_t status = NOT_SUPPORTED;
+ MessageContainer responseContainer;
+
+ StubCartridgeReadRequest* request = stub_cartridge_read_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data);
+
+ //request->cartridgeid
+
+ writeLine("cartridge Request: ");
+
+ writeFloat(request->cartridgeid);
+
+ StubCartridgeReadResponse response = STUB_CARTRIDGE_READ_RESPONSE__INIT;
+
+ response.cartridgeid = request->cartridgeid;
+ response.has_cartridgeid = true;
+
+ //response.cartridgecolor
+ response.has_cartridgecolor = false;
+
+ //response.cartridgeversion
+ response.has_cartridgeversion = false;
+
+ //response.cartridgedata
+ response.has_cartridgedata = false;
+
+ //response.cartridgeused
+ response.has_cartridgeused = false;
+
+ status_response(status,&response.status, &response.statusword ,&response.has_statusword);
+
+ writeLine("Sending Response: ");
+
+ writeFloat(response.cartridgeid);
+ writeString(", ");
+ writeFloat(response.cartridgecolor);
+ writeString(", ");
+ writeFloat(response.cartridgeversion);
+ writeString(", ");
+ writeFloat(response.cartridgedata);
+ writeString(", ");
+ writeFloat(response.cartridgeused);
+ writeString(", ");
+
+ Write_status_response(status);
+
+ responseContainer = createContainer(MESSAGE_TYPE__StubCartridgeReadResponse, requestContainer->token, true, &response, &stub_cartridge_read_response__pack, &stub_cartridge_read_response__get_packed_size);
+
+ //-------------------------------------------------------------------------------------------
+ uint8_t* container_buffer = malloc(message_container__get_packed_size(&responseContainer));
+ size_t container_size = message_container__pack(&responseContainer, container_buffer);
+ SendChars((char*)container_buffer, container_size);
+ free(container_buffer);
+ free(requestContainer);
+}
+
+void Stub_CartridgeWriteRequest(MessageContainer* requestContainer)
+{
+ uint32_t status = NOT_SUPPORTED;
+ MessageContainer responseContainer;
+
+ StubCartridgeWriteRequest* request = stub_cartridge_write_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data);
+
+ //request->cartridgeid
+ //request->cartridgecolor
+ //request->cartridgeversion
+ //request->cartridgedata
+ //request->cartridgeused
+
+ writeLine("Cartridge Request: ");
+
+ writeFloat(request->cartridgeid);
+ writeString(", ");
+ writeFloat(request->cartridgecolor);
+ writeString(", ");
+ writeFloat(request->cartridgeversion);
+ writeString(", ");
+ writeFloat(request->cartridgedata);
+ writeString(", ");
+ writeFloat(request->cartridgeused);
+
+ StubCartridgeWriteResponse response = STUB_CARTRIDGE_WRITE_RESPONSE__INIT;
+
+ response.cartridgeid = request->cartridgeid;
+ response.has_cartridgeid = true;
+
+// char temp[7] = "PASSED";
+// response.status = temp;
+// response.statusword = OK;
+// response.has_statusword = true;
+ status_response(status,&response.status, &response.statusword ,&response.has_statusword);
+
+ writeLine("Sending Response: ");
+
+ writeFloat(response.cartridgeid);
+ writeString(", ");
+// writeFloat(response.statusword);
+// WRITELINESTATUS;
+ Write_status_response(status);
+
+ responseContainer = createContainer(MESSAGE_TYPE__StubCartridgeWriteResponse, requestContainer->token, true, &response, &stub_cartridge_write_response__pack, &stub_cartridge_write_response__get_packed_size);
+
+ //-------------------------------------------------------------------------------------------
+ uint8_t* container_buffer = malloc(message_container__get_packed_size(&responseContainer));
+ size_t container_size = message_container__pack(&responseContainer, container_buffer);
+ SendChars((char*)container_buffer, container_size);
+ free(container_buffer);
+ free(requestContainer);
+}
+
diff --git a/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_Cartridge.h b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_Cartridge.h
new file mode 100644
index 000000000..38c71c233
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_Cartridge.h
@@ -0,0 +1,9 @@
+#ifndef STUB_CARTRIDGE_H
+#define STUB_CARTRIDGE_H
+
+#include "PMR/Common/MessageContainer.pb-c.h"
+
+void Stub_CartridgeReadRequest(MessageContainer* requestContainer);
+void Stub_CartridgeWriteRequest(MessageContainer* requestContainer);
+
+#endif //STUB_CARTRIDGE_H
diff --git a/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_Dispenser.c b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_Dispenser.c
new file mode 100644
index 000000000..384133e7e
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_Dispenser.c
@@ -0,0 +1,72 @@
+
+
+#include <PMR/Common/MessageContainer.pb-c.h>
+#include <PMR/Stubs/StubDispenserRequest.pb-c.h>
+#include <PMR/Stubs/StubDispenserResponse.pb-c.h>
+#include "include.h"
+#include "driverlib/gpio.h"
+
+#include "drivers/twine_usblib/usb_serial_adapter.h"
+#include "drivers/twine_graphicslib/graphics_adapter.h"
+
+#include "Container.h"
+#include "Stub_Status.h"
+
+void Stub_DispenserRequest(MessageContainer* requestContainer)
+{
+ uint32_t status = NOT_SUPPORTED;
+ MessageContainer responseContainer;
+
+ StubDispenserRequest* request = stub_dispenser_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data);
+
+ //request->dispenserid
+ //request->start
+ //request->setdirection
+ //request->setmicrostepdivision
+ //request->setspeed
+
+ writeLine("Dispenser Request: ");
+
+ writeFloat(request->dispenserid);
+ writeString(", ");
+ writeFloat(request->start);
+ writeString(", ");
+ writeFloat(request->setdirection);
+ writeString(", ");
+ writeFloat(request->setmicrostepdivision);
+ writeString(", ");
+ writeFloat(request->setspeed);
+
+ StubDispenserResponse response = STUB_DISPENSER_RESPONSE__INIT;
+
+ response.dispenserid = request->dispenserid;
+ response.has_dispenserid = true;
+
+ //response.dispenserposition
+ response.has_dispenserposition = false;
+
+ //response.inkworninglevel
+ response.has_inkworninglevel = false;
+
+ status_response(status,&response.status, &response.statusword ,&response.has_statusword);
+
+ writeLine("Sending Response: ");
+
+ writeFloat(response.dispenserid);
+ writeString(", ");
+ writeFloat(response.dispenserposition);
+ writeString(", ");
+ writeFloat(response.inkworninglevel);
+ writeString(", ");
+
+ Write_status_response(status);
+
+ responseContainer = createContainer(MESSAGE_TYPE__StubDispenserResponse, requestContainer->token, true, &response, &stub_dispenser_response__pack, &stub_dispenser_response__get_packed_size);
+
+ //-------------------------------------------------------------------------------------------
+ uint8_t* container_buffer = malloc(message_container__get_packed_size(&responseContainer));
+ size_t container_size = message_container__pack(&responseContainer, container_buffer);
+ SendChars((char*)container_buffer, container_size);
+ free(container_buffer);
+ free(requestContainer);
+}
diff --git a/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_Dispenser.h b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_Dispenser.h
new file mode 100644
index 000000000..f2f163e99
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_Dispenser.h
@@ -0,0 +1,9 @@
+
+#ifndef STUB_DISPENSER_H
+#define STUB_DISPENSER_H
+
+#include "PMR/Common/MessageContainer.pb-c.h"
+
+void Stub_DispenserRequest(MessageContainer* requestContainer);
+
+#endif //STUB_DISPENSER_H
diff --git a/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_ExtFlash.c b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_ExtFlash.c
new file mode 100644
index 000000000..5b7577dfe
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_ExtFlash.c
@@ -0,0 +1,160 @@
+
+#include <PMR/Common/MessageContainer.pb-c.h>
+#include <PMR/Stubs/StubExtFlashReadRequest.pb-c.h>
+#include <PMR/Stubs/StubExtFlashReadResponse.pb-c.h>
+#include <PMR/Stubs/StubExtFlashWriteRequest.pb-c.h>
+#include <PMR/Stubs/StubExtFlashWriteResponse.pb-c.h>
+#include <drivers/Flash_Memory/Flash_Memory.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <Modules/Stubs_Handler/DataDef.h>
+#include "inc/hw_memmap.h"
+#include "inc/hw_types.h"
+#include "inc/hw_uart.h"
+#include "driverlib/gpio.h"
+
+#include "drivers/twine_usblib/usb_serial_adapter.h"
+#include "drivers/twine_graphicslib/graphics_adapter.h"
+
+#include "Container.h"
+#include "Stub_Status.h"
+
+
+#define Max_words 5
+
+
+void Stub_ExtFlashWriteRequest(MessageContainer* requestContainer)
+{
+
+ uint32_t WriteBuf[5];
+ uint32_t status = PASSED;
+
+ MessageContainer responseContainer;
+
+ StubExtFlashWriteRequest* request = stub_ext_flash_write_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data);
+
+
+ WriteBuf[0] = request->wordtowrite1;
+ WriteBuf[1] = request->wordtowrite2;
+ WriteBuf[2] = request->wordtowrite3;
+ WriteBuf[3] = request->wordtowrite4;
+ WriteBuf[4] = request->wordtowrite5;
+
+ writeLine("ExtFlash Request: ");
+ writeFloat(request->wordtowrite1);
+ writeString(", ");
+ writeFloat(request->wordtowrite2);
+ writeString(", ");
+ writeFloat(request->wordtowrite3);
+ writeString(", ");
+ writeFloat(request->wordtowrite4);
+ writeString(", ");
+ writeFloat(request->wordtowrite5);
+
+ Ext_Flash_Operation(TX, Max_words, WriteBuf, NULL );
+
+ StubExtFlashWriteResponse response = STUB_EXT_FLASH_WRITE_RESPONSE__INIT;
+
+ status_response(status,&response.status, &response.statusword ,&response.has_statusword);
+
+ responseContainer = createContainer(MESSAGE_TYPE__StubExtFlashWriteResponse, requestContainer->token, true, &response, &stub_ext_flash_write_response__pack, &stub_ext_flash_write_response__get_packed_size);
+
+ writeLine("Sending Response: ");
+
+ Write_status_response(status);
+
+ free(request);
+ //-------------------------------------------------------------------------------------------
+ uint8_t* container_buffer = malloc(message_container__get_packed_size(&responseContainer));
+ size_t container_size = message_container__pack(&responseContainer, container_buffer);
+ SendChars((char*)container_buffer, container_size);
+ free(container_buffer);
+ free(requestContainer);
+
+}
+
+void Stub_ExtFlashReadRequest(MessageContainer* requestContainer)
+{
+ uint32_t status = PASSED;
+ MessageContainer responseContainer;
+
+ StubExtFlashReadRequest* request = stub_ext_flash_read_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data);
+
+ uint32_t No_Words;
+ uint32_t ReadBuf[Max_words];
+
+ if(request->number_of_words>Max_words)
+ {
+ No_Words = Max_words;
+ }
+ else
+ {
+ No_Words = request->number_of_words;
+ }
+
+ Ext_Flash_Operation(RX, No_Words, NULL, ReadBuf );
+
+ writeLine("ExtFlash Request: ");
+ writeFloat(request->number_of_words);
+
+
+ StubExtFlashReadResponse response = STUB_EXT_FLASH_READ_RESPONSE__INIT;
+
+ status_response(status,&response.status, &response.statusword ,&response.has_statusword);
+
+ response.has_readword_5 = false;
+ response.has_readword_4 = false;
+ response.has_readword_3 = false;
+ response.has_readword_2 = false;
+ response.has_readword_1 = false;
+
+ switch(No_Words)
+ {
+ case 5:
+ response.readword_5 = ReadBuf[4];
+ response.has_readword_5 = true;
+ case 4:
+ response.readword_4 = ReadBuf[3];
+ response.has_readword_4 = true;
+ case 3:
+ response.readword_3 = ReadBuf[2];
+ response.has_readword_3 = true;
+ case 2:
+ response.readword_2 = ReadBuf[1];
+ response.has_readword_2 = true;
+ case 1:
+ response.readword_1 = ReadBuf[0];
+ response.has_readword_1 = true;
+ break;
+ default:
+ break;
+ }
+
+ responseContainer = createContainer(MESSAGE_TYPE__StubExtFlashReadResponse, requestContainer->token, true, &response, &stub_ext_flash_read_response__pack, &stub_ext_flash_read_response__get_packed_size);
+ //clear();
+ writeLine("Sending Response: ");
+
+ Write_status_response(status);
+ writeString(", ");
+ writeFloat(response.readword_1);
+ writeString(", ");
+ writeFloat(response.readword_2);
+ writeString(", ");
+ writeFloat(response.readword_3);
+ writeString(", ");
+ writeFloat(response.readword_4);
+ writeString(", ");
+ writeFloat(response.readword_5);
+
+ free(request);
+ //-------------------------------------------------------------------------------------------
+ uint8_t* container_buffer = malloc(message_container__get_packed_size(&responseContainer));
+ size_t container_size = message_container__pack(&responseContainer, container_buffer);
+ SendChars((char*)container_buffer, container_size);
+ free(container_buffer);
+ free(requestContainer);
+}
+
diff --git a/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_ExtFlash.h b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_ExtFlash.h
new file mode 100644
index 000000000..35fc78f85
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_ExtFlash.h
@@ -0,0 +1,8 @@
+#ifndef STUB_EXTFLASH_H
+#define STUB_EXTFLASH_H
+
+void Stub_ExtFlashWriteRequest(MessageContainer* requestContainer);
+void Stub_ExtFlashReadRequest(MessageContainer* requestContainer);
+
+#endif //STUB_EXTFLASH_H
+
diff --git a/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_GPIO.c b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_GPIO.c
new file mode 100644
index 000000000..07ef4a360
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_GPIO.c
@@ -0,0 +1,947 @@
+#include "include.h"
+
+#include <PMR/Common/MessageContainer.pb-c.h>
+#include <PMR/Stubs/StubGPIOInputSetupRequest.pb-c.h>
+#include <PMR/Stubs/StubGPIOInputSetupResponse.pb-c.h>
+#include <PMR/Stubs/StubGPIOReadBitRequest.pb-c.h>
+#include <PMR/Stubs/StubGPIOReadBitResponse.pb-c.h>
+#include <PMR/Stubs/StubGPIOReadByteRequest.pb-c.h>
+#include <PMR/Stubs/StubGPIOReadByteResponse.pb-c.h>
+#include <PMR/Stubs/StubGPIOWriteBitRequest.pb-c.h>
+#include <PMR/Stubs/StubGPIOWriteBitResponse.pb-c.h>
+#include <PMR/Stubs/StubGPIOWriteByteRequest.pb-c.h>
+#include <PMR/Stubs/StubGPIOWriteByteResponse.pb-c.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <Modules/Stubs_Handler/DataDef.h>
+
+#include "inc/hw_memmap.h"
+#include "inc/hw_types.h"
+#include "inc/hw_uart.h"
+#include "driverlib/gpio.h"
+
+#include "drivers/twine_usblib/usb_serial_adapter.h"
+#include "drivers/twine_graphicslib/graphics_adapter.h"
+
+#include "Container.h"
+#include <Modules/Stubs_Handler/User_Leds.h>
+
+#include "Stub_Status.h"
+
+void Stub_GPIOWriteBitRequest(MessageContainer* requestContainer)
+{
+ uint32_t status = FAILED;
+ MessageContainer responseContainer;
+
+ StubGPIOWriteBitRequest* request = stub_gpiowrite_bit_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data);
+
+ writeLine("GPIO Request: ");
+
+ writeString(request->portid);
+ writeString(", ");
+ writeFloat(request->pinid);
+ writeString(", ");
+ writeFloat(request->bittowrite);
+
+
+ uint8_t PinId = 0;
+ uint32_t PortId = 0;
+
+ switch(request->pinid)
+ {
+ case 0:
+ PinId = GPIO_PIN_0;
+ break;
+ case 1:
+ PinId = GPIO_PIN_1;
+ break;
+ case 2:
+ PinId = GPIO_PIN_2;
+ break;
+ case 3:
+ PinId = GPIO_PIN_3;
+ break;
+ case 4:
+ PinId = GPIO_PIN_4;
+ break;
+ case 5:
+ PinId = GPIO_PIN_5;
+ break;
+ case 6:
+ PinId = GPIO_PIN_6;
+ break;
+ case 7:
+ PinId = GPIO_PIN_7;
+ break;
+ default:
+ break;
+ }
+
+ char Port = request->portid[0];
+ switch(Port)
+ {
+ #ifdef USE_HIGH_SPEED_GPIO
+ case 'A':
+ PortId = GPIO_PORTA_AHB_BASE;
+ break;
+ case 'B':
+ PortId = GPIO_PORTB_AHB_BASE;
+ break;
+ case 'C':
+ PortId = GPIO_PORTC_AHB_BASE;
+ break;
+ case 'D':
+ PortId = GPIO_PORTD_AHB_BASE;
+ break;
+ case 'E':
+ PortId = GPIO_PORTE_AHB_BASE;
+ break;
+ case 'F':
+ PortId = GPIO_PORTF_AHB_BASE;
+ break;
+ case 'G':
+ PortId = GPIO_PORTG_AHB_BASE;
+ break;
+ case 'H':
+ PortId = GPIO_PORTH_AHB_BASE;
+ break;
+ case 'J':
+ PortId = GPIO_PORTJ_AHB_BASE;
+ break;
+ #else
+ case 'A':
+ PortId = GPIO_PORTA_BASE;
+ break;
+ case 'B':
+ PortId = GPIO_PORTB_BASE;
+ break;
+ case 'C':
+ PortId = GPIO_PORTC_BASE;
+ break;
+ case 'D':
+ PortId = GPIO_PORTD_BASE;
+ break;
+ case 'E':
+ PortId = GPIO_PORTE_BASE;
+ break;
+ case 'F':
+ PortId = GPIO_PORTF_BASE;
+ break;
+ case 'G':
+ PortId = GPIO_PORTG_BASE;
+ break;
+ case 'H':
+ PortId = GPIO_PORTH_BASE;
+ break;
+ case 'J':
+ PortId = GPIO_PORTJ_BASE;
+ break;
+ #endif
+ case 'K':
+ PortId = GPIO_PORTK_BASE;
+ break;
+ case 'L':
+ PortId = GPIO_PORTL_BASE;
+ break;
+ case 'M':
+ PortId = GPIO_PORTM_BASE;
+ break;
+ case 'N':
+ PortId = GPIO_PORTN_BASE;
+ break;
+ case 'P':
+ PortId = GPIO_PORTP_BASE;
+ break;
+ case 'Q':
+ PortId = GPIO_PORTQ_BASE;
+ break;
+ case 'R':
+ PortId = GPIO_PORTR_BASE;
+ break;
+ case 'S':
+ PortId = GPIO_PORTS_BASE;
+ break;
+ case 'T':
+ PortId = GPIO_PORTT_BASE;
+ break;
+
+ default:
+ writeLine("Unsupported Port ID: ");
+ writeString(request->portid);
+ break;
+ }
+
+ ROM_GPIOPinTypeGPIOOutput(PortId, PinId); // set the requested GPIO to output
+ SysCtlDelay(10000);
+
+ if(request->bittowrite)
+ ROM_GPIOPinWrite(PortId, PinId, ROM_GPIOPinRead(PortId, GPIO_BYTE) | PinId); //Turn ON the requested GPIO
+ else
+ ROM_GPIOPinWrite(PortId, PinId, ROM_GPIOPinRead(PortId, GPIO_BYTE) & ~PinId); //Turn OFF the requested GPIO
+
+ //GPIOPinWrite(PortId, PinId, PinId*request->bittowrite);//
+
+ StubGPIOWriteBitResponse response = STUB_GPIOWRITE_BIT_RESPONSE__INIT;
+
+ response.portid = request->portid;
+
+ response.pinid = request->pinid;
+ response.has_pinid = true;
+
+ //Verify Writing
+ if(request->bittowrite)
+ {
+ if(ROM_GPIOPinRead(PortId, PinId) == PinId)
+ status = VERIFIED;
+ }
+ else
+ {
+ if(ROM_GPIOPinRead(PortId, PinId) == 0)
+ status = VERIFIED;
+ }
+
+ status_response(status,&response.status, &response.statusword ,&response.has_statusword);
+
+ writeLine("Sending Response: ");
+
+ writeString(response.portid);
+ writeString(", ");
+ writeFloat(response.pinid);
+ writeString(", ");
+
+ Write_status_response(status);
+
+
+ responseContainer = createContainer(MESSAGE_TYPE__StubGPIOWriteBitResponse, requestContainer->token, true, &response, &stub_gpiowrite_bit_response__pack, &stub_gpiowrite_bit_response__get_packed_size);
+
+ //-------------------------------------------------------------------------------------------
+ uint8_t* container_buffer = malloc(message_container__get_packed_size(&responseContainer));
+ size_t container_size = message_container__pack(&responseContainer, container_buffer);
+ SendChars((char*)container_buffer, container_size);
+ free(container_buffer);
+ free(requestContainer);
+}
+
+//
+void Stub_GPIOReadByteRequest(MessageContainer* requestContainer)
+{
+ uint32_t status = PASSED;
+ MessageContainer responseContainer;
+
+ StubGPIOReadByteRequest* request = stub_gpioread_byte_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data);
+
+ writeLine("GPIO Request: ");
+
+ writeString(request->portid);
+
+ char Port = request->portid[0];
+ uint32_t PortId = 0;
+
+ switch(Port)
+ {
+ #ifdef USE_HIGH_SPEED_GPIO
+ case 'A':
+ PortId = GPIO_PORTA_AHB_BASE;
+ break;
+ case 'B':
+ PortId = GPIO_PORTB_AHB_BASE;
+ break;
+ case 'C':
+ PortId = GPIO_PORTC_AHB_BASE;
+ break;
+ case 'D':
+ PortId = GPIO_PORTD_AHB_BASE;
+ break;
+ case 'E':
+ PortId = GPIO_PORTE_AHB_BASE;
+ break;
+ case 'F':
+ PortId = GPIO_PORTF_AHB_BASE;
+ break;
+ case 'G':
+ PortId = GPIO_PORTG_AHB_BASE;
+ break;
+ case 'H':
+ PortId = GPIO_PORTH_AHB_BASE;
+ break;
+ case 'J':
+ PortId = GPIO_PORTJ_AHB_BASE;
+ break;
+ #else
+ case 'A':
+ PortId = GPIO_PORTA_BASE;
+ break;
+ case 'B':
+ PortId = GPIO_PORTB_BASE;
+ break;
+ case 'C':
+ PortId = GPIO_PORTC_BASE;
+ break;
+ case 'D':
+ PortId = GPIO_PORTD_BASE;
+ break;
+ case 'E':
+ PortId = GPIO_PORTE_BASE;
+ break;
+ case 'F':
+ PortId = GPIO_PORTF_BASE;
+ break;
+ case 'G':
+ PortId = GPIO_PORTG_BASE;
+ break;
+ case 'H':
+ PortId = GPIO_PORTH_BASE;
+ break;
+ case 'J':
+ PortId = GPIO_PORTJ_BASE;
+ break;
+ #endif
+ case 'K':
+ PortId = GPIO_PORTK_BASE;
+ break;
+ case 'L':
+ PortId = GPIO_PORTL_BASE;
+ break;
+ case 'M':
+ PortId = GPIO_PORTM_BASE;
+ break;
+ case 'N':
+ PortId = GPIO_PORTN_BASE;
+ break;
+ case 'P':
+ PortId = GPIO_PORTP_BASE;
+ break;
+ case 'Q':
+ PortId = GPIO_PORTQ_BASE;
+ break;
+ case 'R':
+ PortId = GPIO_PORTR_BASE;
+ break;
+ case 'S':
+ PortId = GPIO_PORTS_BASE;
+ break;
+ case 'T':
+ PortId = GPIO_PORTT_BASE;
+ break;
+
+ default:
+ writeLine("Unsupported Port ID: ");
+ writeString(request->portid);
+ break;
+ }
+
+ StubGPIOReadByteResponse response = STUB_GPIOREAD_BYTE_RESPONSE__INIT;
+
+ response.portid = request->portid;
+
+ char temp = ROM_GPIOPinRead(PortId, GPIO_BYTE);
+ response.bytevalue = temp;
+ response.has_bytevalue = true;
+
+ status_response(status,&response.status, &response.statusword ,&response.has_statusword);
+
+ writeLine("Sending Response: ");
+
+ writeString(response.portid);
+ writeString(", ");
+ writeFloat(response.bytevalue);
+ writeString(", ");
+
+ Write_status_response(status);
+
+ responseContainer = createContainer(MESSAGE_TYPE__StubGPIOReadByteResponse, requestContainer->token, true, &response, &stub_gpioread_byte_response__pack, &stub_gpioread_byte_response__get_packed_size);
+
+ //-------------------------------------------------------------------------------------------
+ uint8_t* container_buffer = malloc(message_container__get_packed_size(&responseContainer));
+ size_t container_size = message_container__pack(&responseContainer, container_buffer);
+ SendChars((char*)container_buffer, container_size);
+ free(container_buffer);
+ free(requestContainer);
+}
+
+
+void Stub_GPIOReadBitRequest(MessageContainer* requestContainer)
+{
+ uint32_t status = PASSED;
+ MessageContainer responseContainer;
+
+ StubGPIOReadBitRequest* request = stub_gpioread_bit_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data);
+
+ writeLine("GPIO Request: ");
+
+ writeString(request->portid);
+ writeString(", ");
+ writeFloat(request->pinid);
+
+ uint8_t PinId = 0;
+ uint32_t PortId = 0;
+
+ switch(request->pinid)
+ {
+ case 0:
+ PinId = GPIO_PIN_0;
+ break;
+ case 1:
+ PinId = GPIO_PIN_1;
+ break;
+ case 2:
+ PinId = GPIO_PIN_2;
+ break;
+ case 3:
+ PinId = GPIO_PIN_3;
+ break;
+ case 4:
+ PinId = GPIO_PIN_4;
+ break;
+ case 5:
+ PinId = GPIO_PIN_5;
+ break;
+ case 6:
+ PinId = GPIO_PIN_6;
+ break;
+ case 7:
+ PinId = GPIO_PIN_7;
+ break;
+ default:
+ break;
+ }
+
+ char Port = request->portid[0];
+ switch(Port)
+ {
+ #ifdef USE_HIGH_SPEED_GPIO
+ case 'A':
+ PortId = GPIO_PORTA_AHB_BASE;
+ break;
+ case 'B':
+ PortId = GPIO_PORTB_AHB_BASE;
+ break;
+ case 'C':
+ PortId = GPIO_PORTC_AHB_BASE;
+ break;
+ case 'D':
+ PortId = GPIO_PORTD_AHB_BASE;
+ break;
+ case 'E':
+ PortId = GPIO_PORTE_AHB_BASE;
+ break;
+ case 'F':
+ PortId = GPIO_PORTF_AHB_BASE;
+ break;
+ case 'G':
+ PortId = GPIO_PORTG_AHB_BASE;
+ break;
+ case 'H':
+ PortId = GPIO_PORTH_AHB_BASE;
+ break;
+ case 'J':
+ PortId = GPIO_PORTJ_AHB_BASE;
+ break;
+ #else
+ case 'A':
+ PortId = GPIO_PORTA_BASE;
+ break;
+ case 'B':
+ PortId = GPIO_PORTB_BASE;
+ break;
+ case 'C':
+ PortId = GPIO_PORTC_BASE;
+ break;
+ case 'D':
+ PortId = GPIO_PORTD_BASE;
+ break;
+ case 'E':
+ PortId = GPIO_PORTE_BASE;
+ break;
+ case 'F':
+ PortId = GPIO_PORTF_BASE;
+ break;
+ case 'G':
+ PortId = GPIO_PORTG_BASE;
+ break;
+ case 'H':
+ PortId = GPIO_PORTH_BASE;
+ break;
+ case 'J':
+ PortId = GPIO_PORTJ_BASE;
+ break;
+ #endif
+ case 'K':
+ PortId = GPIO_PORTK_BASE;
+ break;
+ case 'L':
+ PortId = GPIO_PORTL_BASE;
+ break;
+ case 'M':
+ PortId = GPIO_PORTM_BASE;
+ break;
+ case 'N':
+ PortId = GPIO_PORTN_BASE;
+ break;
+ case 'P':
+ PortId = GPIO_PORTP_BASE;
+ break;
+ case 'Q':
+ PortId = GPIO_PORTQ_BASE;
+ break;
+ case 'R':
+ PortId = GPIO_PORTR_BASE;
+ break;
+ case 'S':
+ PortId = GPIO_PORTS_BASE;
+ break;
+ case 'T':
+ PortId = GPIO_PORTT_BASE;
+ break;
+
+ default:
+ writeLine("Unsupported Port ID: ");
+ writeString(request->portid);
+ break;
+ }
+
+///////////////////////////////////////////-----------------------------------------------------------------------------
+ char temp;
+ uint8_t expvalue;
+ uint32_t timeout = 10000;
+
+ if(request->pollexpvalue)
+ expvalue = PinId;
+
+ //Polling
+ if(request->polling)
+ {
+ do
+ {
+ timeout--;
+ SysCtlDelay(10000);
+ temp = ROM_GPIOPinRead(PortId, PinId);
+ } while(( temp != expvalue) && (timeout));
+
+ }
+ else
+ {
+ temp = ROM_GPIOPinRead(PortId, PinId);
+ }
+
+ StubGPIOReadBitResponse response = STUB_GPIOREAD_BIT_RESPONSE__INIT;
+
+ response.portid = request->portid;
+
+ response.pinid = request->pinid;
+ response.has_pinid = true;
+
+ response.bitvalue = temp;
+ response.has_bitvalue = true;
+
+ status_response(status,&response.status, &response.statusword ,&response.has_statusword);
+
+ writeLine("Sending Response: ");
+
+ writeString(response.portid);
+ writeString(", ");
+ writeFloat(response.pinid);
+ writeString(", ");
+ writeFloat(response.bitvalue);
+ writeString(", ");
+
+ Write_status_response(status);
+
+ responseContainer = createContainer(MESSAGE_TYPE__StubGPIOReadBitResponse, requestContainer->token, true, &response, &stub_gpioread_bit_response__pack, &stub_gpioread_bit_response__get_packed_size);
+
+///////////////////////////////////////////-----------------------------------------------------------------------------
+/*
+// if( (PortId == GPIO_PORTS_BASE) && (PinId == GPIO_PIN_3))
+// {
+// MAP_GPIOPinTypeGPIOInput(GPIO_PORTS_BASE, GPIO_PIN_3); // Enable pin PS3 for GPIOInput
+// GPIOPadConfigSet(GPIO_PORTS_BASE,GPIO_PIN_3,GPIO_STRENGTH_2MA,GPIO_PIN_TYPE_STD_WPU);//Configure GPIO pull up resistors. NOTE: does not work if ROM_GPIOPinTypeGPIOInput() isnt called before.
+// //GPIOPadConfigSet(GPIO_PORTS_BASE,GPIO_PIN_3,GPIO_STRENGTH_2MA,GPIO_PIN_TYPE_STD_WPD );//Configure GPIO pull down resistors. NOTE: does not work if ROM_GPIOPinTypeGPIOInput() isnt called before.
+// }
+
+ //ROM_GPIOPinTypeGPIOInput(PortId, PinId); // set the requested GPIO to Input
+ //SysCtlDelay(10000);
+
+ StubGPIOReadBitResponse response = STUB_GPIOREAD_BIT_RESPONSE__INIT;
+
+ response.portid = request->portid;
+
+ response.pinid = request->pinid;
+ response.has_pinid = true;
+
+ char temp = ROM_GPIOPinRead(PortId, PinId);
+
+ //char temp2 = ROM_GPIOPinRead(GPIO_PORTQ_BASE, GPIO_BYTE);
+
+ //GPIOPinTypeGPIOInput(GPIO_PORTS_BASE, GPIO_PIN_3); // set the requested GPIO to Input
+ //SysCtlDelay(10000);
+ //char temp3 = GPIOPinRead(GPIO_PORTS_BASE, GPIO_PIN_3);
+ //char temp4 = GPIOPinRead(GPIO_PORTS_BASE, GPIO_BYTE);
+
+ response.bitvalue = temp;
+ response.has_bitvalue = true;
+
+ response.status = OK;
+ response.has_status = true;
+
+ writeLine("Sending Response: ");
+
+ writeString(response.portid);
+ writeString(", ");
+ writeFloat(response.pinid);
+ writeString(", ");
+ writeFloat(response.bitvalue);
+ writeString(", ");
+ writeFloat(response.status);
+ WRITELINESTATUS;
+
+ responseContainer = createContainer(MESSAGE_TYPE__StubGPIOReadBitResponse, requestContainer->token, true, &response, &stub_gpioread_bit_response__pack, &stub_gpioread_bit_response__get_packed_size);
+*/
+ //-------------------------------------------------------------------------------------------
+ uint8_t* container_buffer = malloc(message_container__get_packed_size(&responseContainer));
+ size_t container_size = message_container__pack(&responseContainer, container_buffer);
+ SendChars((char*)container_buffer, container_size);
+ free(container_buffer);
+ free(requestContainer);
+}
+
+
+
+void Stub_GPIOWriteByteRequest(MessageContainer* requestContainer)
+{
+ uint32_t status = FAILED;
+ MessageContainer responseContainer;
+
+ StubGPIOWriteByteRequest* request = stub_gpiowrite_byte_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data);
+
+ writeLine("GPIO Request: ");
+
+ writeString(request->portid);
+ writeString(", ");
+ writeFloat(request->datatowrite);
+
+ uint32_t PortId = 0;
+
+ char Port = request->portid[0];
+ switch(Port)
+ {
+ #ifdef USE_HIGH_SPEED_GPIO
+ case 'A':
+ PortId = GPIO_PORTA_AHB_BASE;
+ break;
+ case 'B':
+ PortId = GPIO_PORTB_AHB_BASE;
+ break;
+ case 'C':
+ PortId = GPIO_PORTC_AHB_BASE;
+ break;
+ case 'D':
+ PortId = GPIO_PORTD_AHB_BASE;
+ break;
+ case 'E':
+ PortId = GPIO_PORTE_AHB_BASE;
+ break;
+ case 'F':
+ PortId = GPIO_PORTF_AHB_BASE;
+ break;
+ case 'G':
+ PortId = GPIO_PORTG_AHB_BASE;
+ break;
+ case 'H':
+ PortId = GPIO_PORTH_AHB_BASE;
+ break;
+ case 'J':
+ PortId = GPIO_PORTJ_AHB_BASE;
+ break;
+ #else
+ case 'A':
+ PortId = GPIO_PORTA_BASE;
+ break;
+ case 'B':
+ PortId = GPIO_PORTB_BASE;
+ break;
+ case 'C':
+ PortId = GPIO_PORTC_BASE;
+ break;
+ case 'D':
+ PortId = GPIO_PORTD_BASE;
+ break;
+ case 'E':
+ PortId = GPIO_PORTE_BASE;
+ break;
+ case 'F':
+ PortId = GPIO_PORTF_BASE;
+ break;
+ case 'G':
+ PortId = GPIO_PORTG_BASE;
+ break;
+ case 'H':
+ PortId = GPIO_PORTH_BASE;
+ break;
+ case 'J':
+ PortId = GPIO_PORTJ_BASE;
+ break;
+ #endif
+ case 'K':
+ PortId = GPIO_PORTK_BASE;
+ break;
+ case 'L':
+ PortId = GPIO_PORTL_BASE;
+ break;
+ case 'M':
+ PortId = GPIO_PORTM_BASE;
+ break;
+ case 'N':
+ PortId = GPIO_PORTN_BASE;
+ break;
+ case 'P':
+ PortId = GPIO_PORTP_BASE;
+ break;
+ case 'Q':
+ PortId = GPIO_PORTQ_BASE;
+ break;
+ case 'R':
+ PortId = GPIO_PORTR_BASE;
+ break;
+ case 'S':
+ PortId = GPIO_PORTS_BASE;
+ break;
+ case 'T':
+ PortId = GPIO_PORTS_BASE;
+ break;
+
+ default:
+ writeLine("Unsupported Port ID: ");
+ writeString(request->portid);
+ break;
+ }
+
+ ROM_GPIOPinTypeGPIOOutput(PortId, GPIO_BYTE); // set the requested GPIO to output
+ SysCtlDelay(10000);
+
+ ROM_GPIOPinWrite(PortId, GPIO_BYTE, request->datatowrite); //Turn ON the requested GPIOs BYTE
+
+ StubGPIOWriteByteResponse response = STUB_GPIOWRITE_BYTE_RESPONSE__INIT;
+
+ response.portid = request->portid;
+
+ //Verify writing
+ if(ROM_GPIOPinRead(PortId, GPIO_BYTE) == request->datatowrite)
+ {
+ status = VERIFIED;
+ }
+ status_response(status,&response.status, &response.statusword ,&response.has_statusword);
+
+ writeLine("Sending Response: ");
+
+ writeString(response.portid);
+ writeString(", ");
+
+ Write_status_response(status);
+
+ responseContainer = createContainer(MESSAGE_TYPE__StubGPIOWriteByteResponse, requestContainer->token, true, &response, &stub_gpiowrite_byte_response__pack, &stub_gpiowrite_byte_response__get_packed_size);
+
+ //-------------------------------------------------------------------------------------------
+ uint8_t* container_buffer = malloc(message_container__get_packed_size(&responseContainer));
+ size_t container_size = message_container__pack(&responseContainer, container_buffer);
+ SendChars((char*)container_buffer, container_size);
+ free(container_buffer);
+ free(requestContainer);
+}
+
+
+
+void Stub_GPIOInputSetupRequest(MessageContainer* requestContainer)
+{
+ uint32_t status = PASSED;
+ MessageContainer responseContainer;
+
+ StubGPIOInputSetupRequest* request = stub_gpioinput_setup_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data);
+
+ writeLine("GPIO Request: ");
+
+ writeString(request->portid);
+ writeString(", ");
+ writeFloat(request->pinid);
+ writeString(", ");
+ writeFloat(request->setinput);
+ writeString(", ");
+ writeFloat(request->setpullup);
+
+
+ uint8_t PinId = 0;
+ uint32_t PortId = 0;
+
+ switch(request->pinid)
+ {
+ case 0:
+ PinId = GPIO_PIN_0;
+ break;
+ case 1:
+ PinId = GPIO_PIN_1;
+ break;
+ case 2:
+ PinId = GPIO_PIN_2;
+ break;
+ case 3:
+ PinId = GPIO_PIN_3;
+ break;
+ case 4:
+ PinId = GPIO_PIN_4;
+ break;
+ case 5:
+ PinId = GPIO_PIN_5;
+ break;
+ case 6:
+ PinId = GPIO_PIN_6;
+ break;
+ case 7:
+ PinId = GPIO_PIN_7;
+ break;
+ default:
+ break;
+ }
+
+ char Port = request->portid[0];
+ switch(Port)
+ {
+ #ifdef USE_HIGH_SPEED_GPIO
+ case 'A':
+ PortId = GPIO_PORTA_AHB_BASE;
+ break;
+ case 'B':
+ PortId = GPIO_PORTB_AHB_BASE;
+ break;
+ case 'C':
+ PortId = GPIO_PORTC_AHB_BASE;
+ break;
+ case 'D':
+ PortId = GPIO_PORTD_AHB_BASE;
+ break;
+ case 'E':
+ PortId = GPIO_PORTE_AHB_BASE;
+ break;
+ case 'F':
+ PortId = GPIO_PORTF_AHB_BASE;
+ break;
+ case 'G':
+ PortId = GPIO_PORTG_AHB_BASE;
+ break;
+ case 'H':
+ PortId = GPIO_PORTH_AHB_BASE;
+ break;
+ case 'J':
+ PortId = GPIO_PORTJ_AHB_BASE;
+ break;
+ #else
+ case 'A':
+ PortId = GPIO_PORTA_BASE;
+ break;
+ case 'B':
+ PortId = GPIO_PORTB_BASE;
+ break;
+ case 'C':
+ PortId = GPIO_PORTC_BASE;
+ break;
+ case 'D':
+ PortId = GPIO_PORTD_BASE;
+ break;
+ case 'E':
+ PortId = GPIO_PORTE_BASE;
+ break;
+ case 'F':
+ PortId = GPIO_PORTF_BASE;
+ break;
+ case 'G':
+ PortId = GPIO_PORTG_BASE;
+ break;
+ case 'H':
+ PortId = GPIO_PORTH_BASE;
+ break;
+ case 'J':
+ PortId = GPIO_PORTJ_BASE;
+ break;
+ #endif
+ case 'K':
+ PortId = GPIO_PORTK_BASE;
+ break;
+ case 'L':
+ PortId = GPIO_PORTL_BASE;
+ break;
+ case 'M':
+ PortId = GPIO_PORTM_BASE;
+ break;
+ case 'N':
+ PortId = GPIO_PORTN_BASE;
+ break;
+ case 'P':
+ PortId = GPIO_PORTP_BASE;
+ break;
+ case 'Q':
+ PortId = GPIO_PORTQ_BASE;
+ break;
+ case 'R':
+ PortId = GPIO_PORTR_BASE;
+ break;
+ case 'S':
+ PortId = GPIO_PORTS_BASE;
+ break;
+ case 'T':
+ PortId = GPIO_PORTT_BASE;
+ break;
+
+ default:
+ writeLine("Unsupported Port ID: ");
+ writeString(request->portid);
+ break;
+ }
+
+ if(request->setinput == INPUT)
+ {
+ MAP_GPIOPinTypeGPIOInput(PortId, PinId); // Enable pin for GPIOInput
+
+ if(request->setpullup == PULLUP)
+ {
+ GPIOPadConfigSet(PortId,PinId,GPIO_STRENGTH_2MA,GPIO_PIN_TYPE_STD_WPU);//Configure GPIO pull up resistors. NOTE: does not work if ROM_GPIOPinTypeGPIOInput() isnt called before.
+ }
+ else //set pulldown:
+ {
+ GPIOPadConfigSet(GPIO_PORTS_BASE,GPIO_PIN_3,GPIO_STRENGTH_2MA,GPIO_PIN_TYPE_STD_WPD );//Configure GPIO pull down resistors. NOTE: does not work if ROM_GPIOPinTypeGPIOInput() isnt called before.
+ }
+ }
+ else
+ {
+ ROM_GPIOPinTypeGPIOOutput(PortId, PinId); // set the requested GPIO to output
+ }
+
+ SysCtlDelay(10000);
+
+ StubGPIOInputSetupResponse response = STUB_GPIOINPUT_SETUP_RESPONSE__INIT;
+
+ response.portid = request->portid;
+
+ response.pinid = request->pinid;
+ response.has_pinid = true;
+
+ status_response(status,&response.status, &response.statusword ,&response.has_statusword);
+
+ writeLine("Sending Response: ");
+
+ writeString(response.portid);
+ writeString(", ");
+ writeFloat(response.pinid);
+ writeString(", ");
+
+ Write_status_response(status);
+
+ responseContainer = createContainer(MESSAGE_TYPE__StubGPIOInputSetupResponse, requestContainer->token, true, &response, &stub_gpioinput_setup_response__pack, &stub_gpioinput_setup_response__get_packed_size);
+
+ //-------------------------------------------------------------------------------------------
+ uint8_t* container_buffer = malloc(message_container__get_packed_size(&responseContainer));
+ size_t container_size = message_container__pack(&responseContainer, container_buffer);
+ SendChars((char*)container_buffer, container_size);
+ free(container_buffer);
+ free(requestContainer);
+}
diff --git a/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_GPIO.h b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_GPIO.h
new file mode 100644
index 000000000..3830ba54f
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_GPIO.h
@@ -0,0 +1,12 @@
+#ifndef STUB_GPIO_H
+#define STUB_GPIO_H
+
+#include "PMR/Common/MessageContainer.pb-c.h"
+
+void Stub_GPIOWriteBitRequest(MessageContainer* requestContainer);
+void Stub_GPIOReadByteRequest(MessageContainer* requestContainer);
+void Stub_GPIOReadBitRequest(MessageContainer* requestContainer);
+void Stub_GPIOWriteByteRequest(MessageContainer* requestContainer);
+void Stub_GPIOInputSetupRequest(MessageContainer* requestContainer);
+
+#endif //STUB_GPIO_H
diff --git a/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_Heater.c b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_Heater.c
new file mode 100644
index 000000000..ff2f2ce1c
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_Heater.c
@@ -0,0 +1,74 @@
+
+
+#include <PMR/Common/MessageContainer.pb-c.h>
+#include <PMR/Stubs/StubHeaterRequest.pb-c.h>
+#include <PMR/Stubs/StubHeaterResponse.pb-c.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <Modules/Stubs_Handler/DataDef.h>
+
+#include "inc/hw_memmap.h"
+#include "inc/hw_types.h"
+#include "inc/hw_uart.h"
+#include "driverlib/gpio.h"
+
+#include "drivers/twine_usblib/usb_serial_adapter.h"
+#include "drivers/twine_graphicslib/graphics_adapter.h"
+
+#include "Container.h"
+#include "Stub_Status.h"
+#include "Drivers/Heater/Heater.h"
+
+void Stub_HeaterRequest(MessageContainer* requestContainer)
+{
+ uint32_t status = NOT_SUPPORTED;
+ MessageContainer responseContainer;
+
+ StubHeaterRequest* request = stub_heater_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data);
+
+ /*
+ request->heaterid
+ request->heatergroupon
+ */
+
+ writeLine("Heater Request: ");
+
+ writeFloat(request->heatergroupid);
+ writeString(", ");
+ writeFloat(request->heatergroupon);
+
+ if (request->heatergroupon )
+ status = ActivateHeater(request->heatergroupid);
+ else
+ status = DeActivateHeater(request->heatergroupid);
+ StubHeaterResponse response = STUB_HEATER_RESPONSE__INIT;
+
+ response.heatergroupid = request->heatergroupid;
+ response.has_heatergroupid = true;
+
+ //response.heatertemperaturesensor
+ response.has_heatertemperaturesensor = false;
+
+ status_response(status,&response.status, &response.statusword ,&response.has_statusword);
+
+ writeLine("Sending Response: ");
+
+ writeFloat(response.heatergroupid);
+ writeString(", ");
+ writeFloat(response.heatertemperaturesensor);
+ writeString(", ");
+
+ Write_status_response(status);
+
+ responseContainer = createContainer(MESSAGE_TYPE__StubHeaterResponse, requestContainer->token, true, &response, &stub_heater_response__pack, &stub_heater_response__get_packed_size);
+
+ //-------------------------------------------------------------------------------------------
+ uint8_t* container_buffer = malloc(message_container__get_packed_size(&responseContainer));
+ size_t container_size = message_container__pack(&responseContainer, container_buffer);
+ SendChars((char*)container_buffer, container_size);
+ free(container_buffer);
+ free(requestContainer);
+}
diff --git a/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_Heater.h b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_Heater.h
new file mode 100644
index 000000000..14c2dad3c
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_Heater.h
@@ -0,0 +1,6 @@
+#ifndef STUB_HEATER_H
+#define STUB_HEATER_H
+
+void Stub_HeaterRequest(MessageContainer* requestContainer);
+
+#endif //STUB_HEATER_H
diff --git a/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_MotorEncoder.c b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_MotorEncoder.c
new file mode 100644
index 000000000..346b595e2
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_MotorEncoder.c
@@ -0,0 +1,84 @@
+
+#include <PMR/Common/MessageContainer.pb-c.h>
+#include <PMR/Stubs/StubMotorEncoderRequest.pb-c.h>
+#include <PMR/Stubs/StubMotorEncoderResponse.pb-c.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <Modules/Stubs_Handler/DataDef.h>
+
+#include "inc/hw_memmap.h"
+#include "inc/hw_types.h"
+#include "inc/hw_uart.h"
+#include "driverlib/gpio.h"
+
+#include "drivers/twine_usblib/usb_serial_adapter.h"
+#include "drivers/twine_graphicslib/graphics_adapter.h"
+
+#include "Container.h"
+#include "Stub_Status.h"
+
+void Stub_MotorEncoderRequest(MessageContainer* requestContainer)
+{
+ uint32_t status = NOT_SUPPORTED;
+ MessageContainer responseContainer;
+
+ StubMotorEncoderRequest* request = stub_motor_encoder_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data);
+
+ /*
+ request->motorid
+ request->readencspeed
+ request->readdirection
+ request->motion_control
+ */
+
+ writeLine("Encoder Request: ");
+
+ writeFloat(request->motorid);
+ writeString(", ");
+ writeFloat(request->readencspeed);
+ writeString(", ");
+ writeFloat(request->readdirection);
+ writeString(", ");
+ writeFloat(request->motion_control);
+
+ StubMotorEncoderResponse response = STUB_MOTOR_ENCODER_RESPONSE__INIT;
+
+ response.encoderid = request->motorid;
+ response.has_encoderid = true;
+
+ response.encoderversion = 456;
+ response.has_encoderversion = true;
+
+ //response.motorspeed
+ response.has_motorspeed = false;
+
+ response.motordirection = CW;
+ response.has_motordirection = true;
+
+ status_response(status,&response.status, &response.statusword ,&response.has_statusword);
+
+ writeLine("Sending Response: ");
+
+ writeFloat(response.encoderid);
+ writeString(", ");
+ writeFloat(response.encoderversion);
+ writeString(", ");
+ writeFloat(response.motorspeed);
+ writeString(", ");
+ writeFloat(response.motordirection);
+ writeString(", ");
+
+ Write_status_response(status);
+
+ responseContainer = createContainer(MESSAGE_TYPE__StubMotorEncoderResponse, requestContainer->token, true, &response, &stub_motor_encoder_response__pack, &stub_motor_encoder_response__get_packed_size);
+
+ //-------------------------------------------------------------------------------------------
+ uint8_t* container_buffer = malloc(message_container__get_packed_size(&responseContainer));
+ size_t container_size = message_container__pack(&responseContainer, container_buffer);
+ SendChars((char*)container_buffer, container_size);
+ free(container_buffer);
+ free(requestContainer);
+}
diff --git a/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_MotorEncoder.h b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_MotorEncoder.h
new file mode 100644
index 000000000..0e0a1c41e
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_MotorEncoder.h
@@ -0,0 +1,6 @@
+#ifndef STUB_MOTORENCODER_H
+#define STUB_MOTORENCODER_H
+
+void Stub_MotorEncoderRequest(MessageContainer* requestContainer);
+
+#endif //STUB_STUB_MOTORENCODER_H
diff --git a/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_OptLimitSwitch.c b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_OptLimitSwitch.c
new file mode 100644
index 000000000..5da89ab10
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_OptLimitSwitch.c
@@ -0,0 +1,70 @@
+
+
+#include <PMR/Common/MessageContainer.pb-c.h>
+#include <PMR/Stubs/StubOptLimitSwitchRequest.pb-c.h>
+#include <PMR/Stubs/StubOptLimitSwitchResponse.pb-c.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <Modules/Stubs_Handler/DataDef.h>
+
+#include "inc/hw_memmap.h"
+#include "inc/hw_types.h"
+#include "inc/hw_uart.h"
+#include "driverlib/gpio.h"
+
+#include "drivers/twine_usblib/usb_serial_adapter.h"
+#include "drivers/twine_graphicslib/graphics_adapter.h"
+
+#include "Container.h"
+#include "Stub_Status.h"
+
+void Stub_OptLimitSwitchRequest(MessageContainer* requestContainer)
+{
+ uint32_t status = NOT_SUPPORTED;
+
+ MessageContainer responseContainer;
+
+ StubOptLimitSwitchRequest* request = stub_opt_limit_switch_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data);
+
+ /*
+ request->limitswitchrid
+ request->limitswitchrdisable
+ */
+
+ writeLine("OptLimit Switch Request: ");
+
+ writeFloat(request->limitswitchrid);
+ writeString(", ");
+ writeFloat(request->limitswitchrdisable);
+
+ StubOptLimitSwitchResponse response = STUB_OPT_LIMIT_SWITCH_RESPONSE__INIT;
+
+ response.limitswitchrid = request->limitswitchrid;
+ response.has_limitswitchrid = true;
+
+ //response.limitswitchditection = 2;
+ response.has_limitswitchditection = false;
+
+ status_response(status,&response.status, &response.statusword ,&response.has_statusword);
+
+ writeLine("Sending Response: ");
+
+ writeFloat(response.limitswitchrid);
+ writeString(", ");
+ writeFloat(response.limitswitchditection);
+ writeString(", ");
+
+ Write_status_response(status);
+
+ responseContainer = createContainer(MESSAGE_TYPE__StubOptLimitSwitchResponse, requestContainer->token, true, &response, &stub_opt_limit_switch_response__pack, &stub_opt_limit_switch_response__get_packed_size);
+
+ //-------------------------------------------------------------------------------------------
+ uint8_t* container_buffer = malloc(message_container__get_packed_size(&responseContainer));
+ size_t container_size = message_container__pack(&responseContainer, container_buffer);
+ SendChars((char*)container_buffer, container_size);
+ free(container_buffer);
+ free(requestContainer);
+}
diff --git a/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_OptLimitSwitch.h b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_OptLimitSwitch.h
new file mode 100644
index 000000000..dbd064a1d
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_OptLimitSwitch.h
@@ -0,0 +1,6 @@
+#ifndef STUB_OPTLIMITSWITCH_H
+#define STUB_OPTLIMITSWITCH_H
+
+void Stub_OptLimitSwitchRequest(MessageContainer* requestContainer);
+
+#endif //STUB_OPTLIMITSWITCH_H
diff --git a/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_Status.c b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_Status.c
new file mode 100644
index 000000000..00299c74c
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_Status.c
@@ -0,0 +1,58 @@
+
+#include "include.h"
+/*#include <graphics_adapter.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include "Stub_Status.h"
+#include <Stubs_Handler/DataDef.h>*/
+#include "drivers/twine_graphicslib/graphics_adapter.h"
+
+int status_response(uint32_t Rstatus,char *status[20],uint32_t *statusword ,protobuf_c_boolean *has_statusword)
+{
+ if(Rstatus==PASSED)
+ {
+ *status = "PASSED";
+ *has_statusword = false;
+ }
+ else if(Rstatus==VERIFIED)
+ {
+ *status = "PASSED (VERIFIED)";
+ *has_statusword = false;
+ }
+ else if(Rstatus==NOT_SUPPORTED)
+ {
+ *status = "NOT_SUPPORTED";
+ *statusword = Rstatus;
+ *has_statusword = false;
+ }
+ else
+ {
+ *status = "FAILED";
+ *statusword = Rstatus;
+ *has_statusword = true;
+ }
+ return 0;
+}
+
+int Write_status_response(uint32_t Rstatus)
+{
+ writeFloat(Rstatus);
+
+ if(Rstatus==PASSED)
+ {
+ writeLine("PASSED");
+ }
+ else if(Rstatus==VERIFIED)
+ {
+ writeLine("PASSED (VERIFIED)");
+ }
+ else if(Rstatus==NOT_SUPPORTED)
+ {
+ writeLine("NOT_SUPPORTED");
+ }
+ else
+ {
+ writeLine("FAILED");
+ }
+ return 0;
+}
diff --git a/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_Status.h b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_Status.h
new file mode 100644
index 000000000..c2ff1b7e5
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_Status.h
@@ -0,0 +1,3 @@
+
+int status_response(uint32_t Rstatus,char *status[8],uint32_t *statusword ,protobuf_c_boolean *has_statusword);
+int Write_status_response(uint32_t Rstatus);
diff --git a/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_SteperMotor.c b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_SteperMotor.c
new file mode 100644
index 000000000..03807934b
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_SteperMotor.c
@@ -0,0 +1,79 @@
+
+
+#include <PMR/Common/MessageContainer.pb-c.h>
+#include <PMR/Stubs/StubSteperMotorRequest.pb-c.h>
+#include <PMR/Stubs/StubSteperMotorResponse.pb-c.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <Modules/Stubs_Handler/DataDef.h>
+
+#include "inc/hw_memmap.h"
+#include "inc/hw_types.h"
+#include "inc/hw_uart.h"
+#include "driverlib/gpio.h"
+
+#include "drivers/twine_usblib/usb_serial_adapter.h"
+#include "drivers/twine_graphicslib/graphics_adapter.h"
+
+#include "Container.h"
+#include "Stub_Status.h"
+
+void Stub_SteperMotorRequest(MessageContainer* requestContainer)
+{
+ uint32_t status = NOT_SUPPORTED;
+ MessageContainer responseContainer;
+
+ StubSteperMotorRequest* request = stub_steper_motor_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data);
+
+
+ writeLine("Steper Motor Request: ");
+
+ writeFloat(request->motorid);
+ writeString(", ");
+ writeFloat(request->start);
+ writeString(", ");
+ writeFloat(request->setdirection);
+ writeString(", ");
+ writeFloat(request->setmicrostepdivision);
+ writeString(", ");
+ writeFloat(request->setspeed);
+ /*
+ request->motorid
+ request->start
+ request->setdirection
+ request->setmicrostepdivision
+ request->setspeed
+ */
+
+ StubSteperMotorResponse response = STUB_STEPER_MOTOR_RESPONSE__INIT;
+
+ response.motorid = request->motorid;
+ response.has_motorid = true;
+
+ response.motorversion = 123;
+ response.has_motorversion = true;
+
+ status_response(status,&response.status, &response.statusword ,&response.has_statusword);
+
+ writeLine("Sending Response: ");
+
+ writeFloat(response.motorid);
+ writeString(", ");
+ writeFloat(response.motorversion);
+ writeString(", ");
+
+ Write_status_response(status);
+
+
+ responseContainer = createContainer(MESSAGE_TYPE__StubSteperMotorResponse, requestContainer->token, true, &response, &stub_steper_motor_response__pack, &stub_steper_motor_response__get_packed_size);
+
+ //-------------------------------------------------------------------------------------------
+ uint8_t* container_buffer = malloc(message_container__get_packed_size(&responseContainer));
+ size_t container_size = message_container__pack(&responseContainer, container_buffer);
+ SendChars((char*)container_buffer, container_size);
+ free(container_buffer);
+ free(requestContainer);
+}
diff --git a/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_SteperMotor.h b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_SteperMotor.h
new file mode 100644
index 000000000..b19aa0cc0
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_SteperMotor.h
@@ -0,0 +1,7 @@
+
+#ifndef STUB_STEPERMOTOR_H
+#define STUB_STEPERMOTOR_H
+
+void Stub_SteperMotorRequest(MessageContainer* requestContainer);
+
+#endif //STUB_STEPERMOTOR_H
diff --git a/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_Valve.c b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_Valve.c
new file mode 100644
index 000000000..ef38bb496
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_Valve.c
@@ -0,0 +1,60 @@
+
+#include <PMR/Common/MessageContainer.pb-c.h>
+#include <PMR/Stubs/StubValveRequest.pb-c.h>
+#include <PMR/Stubs/StubValveResponse.pb-c.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <Modules/Stubs_Handler/DataDef.h>
+
+#include "inc/hw_memmap.h"
+#include "inc/hw_types.h"
+#include "inc/hw_uart.h"
+#include "driverlib/gpio.h"
+
+#include "drivers/twine_usblib/usb_serial_adapter.h"
+#include "drivers/twine_graphicslib/graphics_adapter.h"
+
+#include "Container.h"
+
+#include "Stub_Status.h"
+
+void Stub_ValveRequest(MessageContainer* requestContainer)
+{
+ MessageContainer responseContainer;
+ uint32_t status = NOT_SUPPORTED;
+
+ StubValveRequest* request = stub_valve_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data);
+
+ /*
+ request->valveid
+ request->inkflow
+ request->valveon
+ */
+ writeLine("Valve Request: ");
+ writeFloat(request->valveid);
+ writeString(", ");
+ writeFloat(request->inkflow);
+ writeString(", ");
+ writeFloat(request->valveon);
+
+ StubValveResponse response = STUB_VALVE_RESPONSE__INIT;
+
+ status_response(status,&response.status, &response.statusword ,&response.has_statusword);
+
+ responseContainer = createContainer(MESSAGE_TYPE__StubValveResponse, requestContainer->token, true, &response, &stub_valve_response__pack, &stub_valve_response__get_packed_size);
+
+ writeLine("Sending Response: ");
+
+ Write_status_response(status);
+
+ free(request);
+ //-------------------------------------------------------------------------------------------
+ uint8_t* container_buffer = malloc(message_container__get_packed_size(&responseContainer));
+ size_t container_size = message_container__pack(&responseContainer, container_buffer);
+ SendChars((char*)container_buffer, container_size);
+ free(container_buffer);
+ free(requestContainer);
+}
diff --git a/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_Valve.h b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_Valve.h
new file mode 100644
index 000000000..1948fa37b
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_Valve.h
@@ -0,0 +1,6 @@
+#ifndef STUB_VALVE_H
+#define STUB_VALVE_H
+void Stub_ValveRequest(MessageContainer* requestContainer);
+
+#endif //STUB_VALVE_H
+
diff --git a/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/User_Leds.c b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/User_Leds.c
new file mode 100644
index 000000000..d06b3aeef
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/User_Leds.c
@@ -0,0 +1,68 @@
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "inc/hw_memmap.h"
+
+#include "driverlib/rom.h"
+#include "driverlib/gpio.h"
+#include "driverlib/sysctl.h"
+
+#include <Modules/Stubs_Handler/DataDef.h>
+#include <Modules/Stubs_Handler/User_Leds.h>
+
+void Turn_Green_Led_On()
+{
+ INIT_GPIO_GREEN_LED
+ GREEN_LED_ON
+ LED_SET_DELAY
+}
+
+void Turn_Green_Led_Off()
+{
+ GREEN_LED_OFF
+}
+
+void Turn_Blue_Led_On()
+{
+ INIT_GPIO_BLUE_LED
+ BLUE_LED_ON
+ LED_SET_DELAY
+}
+
+void Turn_Blue_Led_Off()
+{
+ BLUE_LED_OFF
+}
+
+void Turn_Red_Led_On()
+{
+ INIT_GPIO_RED_LED
+ RED_LED_ON
+ LED_SET_DELAY
+}
+
+void Turn_Red_Led_Off()
+{
+ RED_LED_OFF
+}
+
+
+void Test_3_Color_Led()
+{
+ char i;
+
+ for (i=0;i<5000;i++)
+ {
+ Turn_Green_Led_On();
+ Turn_Green_Led_Off();
+
+ Turn_Blue_Led_On();
+ Turn_Blue_Led_Off();
+
+ Turn_Red_Led_On();
+ Turn_Red_Led_Off();
+ }
+}
diff --git a/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/User_Leds.h b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/User_Leds.h
new file mode 100644
index 000000000..5f0016bda
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/User_Leds.h
@@ -0,0 +1,23 @@
+#ifndef USER_LEDS_H
+#define USER_LEDS_H
+
+#define GPIO_BYTE (GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7)
+
+#define INIT_GPIO_GREEN_LED ROM_GPIOPinTypeGPIOOutput(GPIO_PORTQ_BASE, GPIO_PIN_7); // set PQ7 to output (Green LED)
+#define INIT_GPIO_BLUE_LED ROM_GPIOPinTypeGPIOOutput(GPIO_PORTQ_BASE, GPIO_PIN_4); // set PQ4 to output (Blue LED)
+#define INIT_GPIO_RED_LED ROM_GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_5); // set PN5 to output (RED LED)
+
+#define GREEN_LED_ON ROM_GPIOPinWrite(GPIO_PORTQ_BASE, GPIO_PIN_7, ROM_GPIOPinRead(GPIO_PORTQ_BASE, GPIO_BYTE) | GPIO_PIN_7); //Turn the GREEN led on
+#define GREEN_LED_OFF ROM_GPIOPinWrite(GPIO_PORTQ_BASE, GPIO_PIN_7, ROM_GPIOPinRead(GPIO_PORTQ_BASE, GPIO_BYTE) & ~ GPIO_PIN_7); //Turn the GREEN led off
+
+#define BLUE_LED_ON ROM_GPIOPinWrite(GPIO_PORTQ_BASE, GPIO_PIN_4, ROM_GPIOPinRead(GPIO_PORTQ_BASE, GPIO_BYTE) | GPIO_PIN_4); //Turn the BLUE led on
+#define BLUE_LED_OFF ROM_GPIOPinWrite(GPIO_PORTQ_BASE, GPIO_PIN_4, ROM_GPIOPinRead(GPIO_PORTQ_BASE, GPIO_BYTE) & ~ GPIO_PIN_4); //Turn the BLUE led off
+
+#define RED_LED_ON ROM_GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_5, ROM_GPIOPinRead(GPIO_PORTN_BASE, GPIO_BYTE) | GPIO_PIN_5); //Turn the RED led on
+#define RED_LED_OFF ROM_GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_5, ROM_GPIOPinRead(GPIO_PORTN_BASE, GPIO_BYTE) & ~ GPIO_PIN_5); //Turn the RED led off
+
+#define LED_SET_DELAY SysCtlDelay(10000000); // need #include "driverlib/sysctl.h"
+
+void Test_3_Color_Led();
+
+#endif //USER_LEDS_H
diff --git a/Software/Embedded_SW/Embedded/Modules/Thread/Thread.h b/Software/Embedded_SW/Embedded/Modules/Thread/Thread.h
new file mode 100644
index 000000000..475f63795
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Thread/Thread.h
@@ -0,0 +1,55 @@
+#include "PMR/common/MessageContainer.pb-c.h"
+#include "PMR/Hardware/HardwareMotor.pb-c.h"
+#include "PMR/Hardware/HardwareMotorType.pb-c.h"
+#include "PMR/Hardware/HardwareDancer.pb-c.h"
+#include "PMR/Hardware/HardwareDancerType.pb-c.h"
+#include "PMR/Hardware/HardwareWinder.pb-c.h"
+#include "PMR/Printing/JobSpool.pb-c.h"
+#include "PMR/Printing/JobSpoolType.pb-c.h"
+
+
+typedef struct
+{
+ HardwareMotorType id;
+ uint32_t minfreq;
+ uint32_t maxfreq;
+ uint32_t minmicrostep;
+ uint32_t maxmicrostep;
+ double linearratio;
+ uint32_t medianposition;
+ double correctiongain;
+ double ratio2dryerspeed;
+ double kp;
+ double ki;
+ double kd;
+ double changeslope;
+ double hightimeoutusec;
+}MotorConfigStruc;
+typedef struct
+{
+ uint32_t startoffsetpulses;
+ uint32_t spoolbackingrate;
+ uint32_t segmentoffsetpulses;
+ uint32_t milimetersperrotation;
+}InternalWinderConfigStruc;
+
+typedef struct
+{
+ bool fixorgradual;
+ double k;
+ double x;
+ int32_t pulsepermmspring;
+ int id; //HardwareDancerType
+}DancerConfigStruc;
+#define MAX_THREAD_MOTORS_NUM HARDWARE_MOTOR_TYPE__WinderMotor +1
+
+
+extern MotorConfigStruc MotorsCfg[MAX_THREAD_MOTORS_NUM];
+extern InternalWinderConfigStruc InternalWinderCfg;
+
+
+uint32_t InternalWinderConfigMessage(HardwareWinder* request);
+uint32_t MotorsConfigMessage(HardwareMotor * request);
+uint32_t InternalWindingConfigMessage(JobSpool* request);
+
+uint32_t DancerConfigMessage(HardwareDancer * request);
diff --git a/Software/Embedded_SW/Embedded/Modules/Thread/Thread_BIT.c b/Software/Embedded_SW/Embedded/Modules/Thread/Thread_BIT.c
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Thread/Thread_BIT.c
diff --git a/Software/Embedded_SW/Embedded/Modules/Thread/Thread_ex.h b/Software/Embedded_SW/Embedded/Modules/Thread/Thread_ex.h
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Thread/Thread_ex.h
diff --git a/Software/Embedded_SW/Embedded/Modules/Thread/Thread_init.c b/Software/Embedded_SW/Embedded/Modules/Thread/Thread_init.c
new file mode 100644
index 000000000..f32026ca8
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Thread/Thread_init.c
@@ -0,0 +1,94 @@
+/************************************************************************************************************************
+ **************************************************************************************************************************/
+
+#include "include.h"
+
+#include <Modules/Stubs_Handler/DataDef.h>
+#include "PMR/Hardware/HardwareMotor.pb-c.h"
+#include "PMR/Hardware/HardwareDancer.pb-c.h"
+#include "PMR/Hardware/HardwareWinder.pb-c.h"
+#include "PMR/Printing/JobSpool.pb-c.h"
+#include "PMR/common/MessageContainer.pb-c.h"
+
+#include "thread.h"
+#define MAX_SYSTEM_DANCERS HARDWARE_DANCER_TYPE__RightDancer+1
+MotorConfigStruc MotorsCfg[MAX_THREAD_MOTORS_NUM];
+InternalWinderConfigStruc InternalWinderCfg;
+DancerConfigStruc DancersCfg[MAX_SYSTEM_DANCERS];
+
+
+
+uint32_t InternalWinderConfigMessage(HardwareWinder* request)
+{
+ uint32_t status = PASSED;
+
+ InternalWinderCfg.milimetersperrotation = request->millimeterperrotation;
+
+ return status;
+}
+uint32_t InternalWindingConfigMessage(JobSpool* request)
+{
+ uint32_t status = PASSED;
+
+ InternalWinderCfg.segmentoffsetpulses = request->segmentoffsetpulses;
+ InternalWinderCfg.spoolbackingrate = request->backingrate;
+ InternalWinderCfg.startoffsetpulses = request->startoffsetpulses;
+
+ return status;
+}
+
+//********************************************************************************************************************
+uint32_t MotorsConfigMessage(HardwareMotor * request)
+{
+ uint32_t status = PASSED;
+ int Motor_i;
+
+ Motor_i = request->hardwaremotortype;
+ if ((Motor_i)&&(Motor_i< MAX_THREAD_MOTORS_NUM))
+ {
+ MotorsCfg[Motor_i].id = request->hardwaremotortype;
+ MotorsCfg[Motor_i].minfreq = request->minfrequency;
+ MotorsCfg[Motor_i].maxfreq = request->maxfrequency;
+ MotorsCfg[Motor_i].minmicrostep = request->minmicrostep;
+ MotorsCfg[Motor_i].maxmicrostep = request->maxmicrostep;
+ MotorsCfg[Motor_i].linearratio = request->linearratio;
+ MotorsCfg[Motor_i].medianposition = request->medianposition;
+ MotorsCfg[Motor_i].correctiongain = request->correctiongain;
+ MotorsCfg[Motor_i].ratio2dryerspeed = request->ratiotodryerspeed;
+ MotorsCfg[Motor_i].kp = request->kp;
+ MotorsCfg[Motor_i].ki = request->ki;
+ MotorsCfg[Motor_i].kd = request->kd;
+ MotorsCfg[Motor_i].changeslope = request->changeslope;
+ MotorsCfg[Motor_i].hightimeoutusec = request->highlengthmicrosecond;
+ return status;
+ }
+ else return Motor_i;
+
+}
+uint32_t DancerConfigMessage(HardwareDancer * request)
+{
+ uint32_t status = PASSED;
+ int Dancer_i;
+
+ Dancer_i = request->hardwaredancertype;
+ if ((Dancer_i)&&(Dancer_i<MAX_SYSTEM_DANCERS ))
+ {
+ DancersCfg[Dancer_i].id = Dancer_i;
+ DancersCfg[Dancer_i].fixorgradual = request->gradual;
+ DancersCfg[Dancer_i].k = request->k;
+ DancersCfg[Dancer_i].x = request->x;
+ DancersCfg[Dancer_i].pulsepermmspring = request->pulsepermmspring;
+ return status;
+ }
+ else
+ return Dancer_i;
+
+}
+
+uint32_t thread_init(void)
+{
+ memset (MotorsCfg,0,sizeof(MotorsCfg));
+ memset (&InternalWinderCfg,0,sizeof(InternalWinderConfigStruc));
+
+ return OK;
+}
diff --git a/Software/Embedded_SW/Embedded/Modules/Thread/Thread_maint.c b/Software/Embedded_SW/Embedded/Modules/Thread/Thread_maint.c
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Thread/Thread_maint.c
diff --git a/Software/Embedded_SW/Embedded/Modules/Thread/Thread_print.c b/Software/Embedded_SW/Embedded/Modules/Thread/Thread_print.c
new file mode 100644
index 000000000..10baaed8e
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Thread/Thread_print.c
@@ -0,0 +1,326 @@
+/************************************************************************************************************************
+ * Thread_print.c
+ * Printing module is responsible for :
+ * operating diffrent winding algorithms with predefined parameters from the UI
+ * operating the dispensers according to predefined dispensing rate from the UI
+ **************************************************************************************************************************/
+#include "include.h"
+#include "thread.h"
+#include "../control/control.h"
+#include "../control/pidalgo.h"
+#include "PMR/Hardware/HardwareMotor.pb-c.h"
+#include "PMR/Hardware/HardwareMotorType.pb-c.h"
+////////////////////////////////State machine operation////////////////////////////////////
+//the state machine operation is used to operate in runtime correct profile flow execution
+//by recieved esign flow of the user from the UI
+///////////////////////////////////////////////////////////////////////////////////////////
+typedef enum
+{
+ NextState = 0,
+ Repeat,
+ Inter,
+ Home,
+ Stop
+} ReturnCode;
+
+/********************************************************************************************
+* functions describes motor operation flow and movement state during profile execution
+* used to operate in runtime correct profileflow execution
+*********************************************************************************************/
+static ReturnCode EntryState(void *JobDetails);
+static ReturnCode PrepareState(void *JobDetails);
+static ReturnCode PreSegmentState(void *JobDetails);
+static ReturnCode SegmentState(void *JobDetails);
+static ReturnCode EndState(void *JobDetails);
+static ReturnCode ExitState(void *JobDetails);
+;
+
+/**********************************************************************
+* the array and enum of PrintingState_t below must be in sync order
+***********************************************************************/
+static ReturnCode (* state[])(void *JobDetails) = { EntryState, PrepareState, PreSegmentState, SegmentState, EndState, ExitState};
+
+typedef enum
+{
+ Entry= 0,
+ Prepare,
+ PreSegment,
+ Segment,
+ End,
+ Exit
+} PrintingState_t;
+
+typedef struct
+{
+ PrintingState_t m_sourceState;
+ ReturnCode m_returnCode;
+ PrintingState_t m_destinationState;
+} Transition_t;
+
+//*************************************************************
+/* transitions from end state aren't needed */
+//*************************************************************
+#define NUM_OF_TRANSITION 17
+#define EXIT_STATE Exit
+#define ENTRY_STATE Entry
+/*************************************************************
+ * table which describes fast motors transitions states
+ * during p_profile / segments execution
+ *************************************************************/
+static Transition_t stateTransitionTable[NUM_OF_TRANSITION] =
+{};
+/* {Entry, NextState, HomingStart},
+ {Entry, Repeat, Entry}, //for homing of dispensers
+ {HomingStart, NextState, Start},
+ {HomingStart, Repeat, HomingStart},
+ {Start, NextState, Segment},
+ {Start, Repeat, Start},
+ {Segment, Inter, Intersegment},
+ {Segment, Repeat, Segment},
+ {Segment, Home, HomingEnd},
+ {Intersegment, NextState, Segment},
+ {Intersegment, Repeat, Intersegment},
+ {Intersegment, Home, HomingEnd},
+ {HomingEnd, NextState, End},
+ {HomingEnd, Repeat, HomingEnd},
+ {End, NextState, Entry},
+ {End, Repeat, Entry},
+ {Exit, Stop, Exit} //for stoping the machine iteration in case of error
+};*/
+typedef struct
+{
+ bool m_isEnabled;
+ uint32_t m_SetParam;
+ uint32_t m_mesuredParam;
+ float m_preError;
+ float m_integral;
+ float m_calculatedError;
+ bool m_isReady;
+ PID_Config_Params m_params;
+}MotorControlConfig_t;
+/*typedef struct
+{
+ float epsilon;
+ float dt;
+ float MAX;
+ float MIN;
+ float Kp;
+ float Kd;
+ float Ki;
+}PID_Config_Params;
+#define epsilon 0.01
+#define dt 0.01 //100ms loop time
+#define MAX 4 //For Current Saturation
+#define MIN -4
+#define Kp 0.1
+#define Kd 0.01
+#define Ki 0.005
+*/
+MotorControlConfig_t MotorControlConfig[MAX_THREAD_MOTORS_NUM];
+uint32_t DeviceId2Motor[MAX_THREAD_MOTORS_NUM];
+////////////////////////Slow Motor State////////////////////////////////////
+static PrintingState_t gPrintingState;
+////////////////////////////////////////////////////////////////////////////
+
+uint32_t ThreadControlCBFunction(uint32_t deviceID, uint32_t ReadValue)
+{
+ int i,index=MAX_THREAD_MOTORS_NUM;
+ for (i=0;i<MAX_THREAD_MOTORS_NUM;i++)
+ if (DeviceId2Motor[i] == deviceID)
+ {
+ index = i;
+ break;
+ }
+ if (index==MAX_THREAD_MOTORS_NUM)
+ {
+ LOG_ERROR (deviceID, "No motor for device");
+ return 0xFFFFFFFF;
+ }
+ if(MotorControlConfig[index].m_isEnabled && (MotorControlConfig[index].m_SetParam != 0))
+ {
+ MotorControlConfig[index].m_mesuredParam = ReadValue;
+ MotorControlConfig[index].m_calculatedError = PIDAlgorithmCalculation(MotorControlConfig[index].m_SetParam , MotorControlConfig[index].m_mesuredParam,
+ &MotorControlConfig[index].m_params, &MotorControlConfig[index].m_preError, &MotorControlConfig[index].m_integral);
+ if (MotorControlConfig[index].m_calculatedError >= MotorControlConfig[index].m_params.MAX)
+ {
+ MotorControlConfig[index].m_calculatedError = MotorControlConfig[index].m_params.MAX;
+ }
+ if (MotorControlConfig[index].m_calculatedError < MotorControlConfig[index].m_params.MIN)
+ {
+ MotorControlConfig[index].m_calculatedError = MotorControlConfig[index].m_params.MIN;
+ }
+
+ //SetMotorFreq (index, MotorControlConfig[index].m_calculatedError);
+ }
+
+ return OK;
+}
+
+//********************************************************************************************************************
+/********************************************************************************************************************
+*function describes entry point of motor in profile execution - accelerate from stop position
+*function described above used to operate motor operation flow and movement state during profile execution
+*********************************************************************************************************************/
+static ReturnCode EntryState(void *JobDetails)
+{
+ return NextState;
+}
+
+//********************************************************************************************************************
+static ReturnCode PrepareState(void *JobDetails)
+{
+ int Motor_i;
+ //start thread control for all motors
+ for (Motor_i = 0;Motor_i < MAX_THREAD_MOTORS_NUM;Motor_i++)
+ {
+ MotorControlConfig[Motor_i].m_params.MAX = MotorsCfg[Motor_i].maxfreq;
+ MotorControlConfig[Motor_i].m_params.MIN = MotorsCfg[Motor_i].minfreq;
+ MotorControlConfig[Motor_i].m_params.Kd = MotorsCfg[Motor_i].kd;
+ MotorControlConfig[Motor_i].m_params.Kp = MotorsCfg[Motor_i].kp;
+ MotorControlConfig[Motor_i].m_params.Ki = MotorsCfg[Motor_i].ki;
+ MotorControlConfig[Motor_i].m_params.dt = eOneMillisecond;
+ MotorControlConfig[Motor_i].m_calculatedError = 0;
+ MotorControlConfig[Motor_i].m_integral = 0;
+ MotorControlConfig[Motor_i].m_isEnabled = true;
+ MotorControlConfig[Motor_i].m_isReady = true;
+ MotorControlConfig[Motor_i].m_mesuredParam = 0;
+ MotorControlConfig[Motor_i].m_preError = 0;
+ MotorControlConfig[Motor_i].m_SetParam = 0;//need to update SetParams on presegment stage
+ AddControlCallback(DeviceId2Motor[Motor_i], ThreadControlCBFunction, eOneMillisecond);
+ }
+ //set 3 dancers to the profile positions
+ return NextState;
+}
+
+//********************************************************************************************************************
+static ReturnCode PreSegmentState(void *JobDetails)
+{
+
+ int Motor_i;
+ for (Motor_i = 0;Motor_i < MAX_THREAD_MOTORS_NUM;Motor_i++)
+ {
+ MotorControlConfig[Motor_i].m_SetParam = getMotorFreq(Motor_i);//need to update SetParams on presegment stage
+ }
+ // set the new speed in the dryer motor to the speed of the new segment
+ // activate control fr all motors
+ //set speed for both rocker motors
+ //wait for all motors to get to the required speed (set the target speed for the control to check)
+ //call the job state machine when the thread system is ready
+ return NextState;
+}
+
+//********************************************************************************************************************
+static ReturnCode SegmentState(void *JobDetails)
+{
+ return Repeat;
+}
+
+//********************************************************************************************************************
+static ReturnCode EndState(void *JobDetails)
+{
+ return NextState;
+}
+//********************************************************************************************************************
+static ReturnCode ExitState(void *JobDetails)
+{
+ return Stop;
+}
+
+
+//***********************************************************************************************************************
+//this function is responsible for operating and transitioning between the diffrent motor state executions of the profile
+//the lower managment level
+//***********************************************************************************************************************
+static PrintingState_t LookupTransitions(PrintingState_t state,ReturnCode returnCode)
+{
+ char str[80];
+ uint8_t len = 0;
+ uint8_t indexInTransitionTable;
+ for (indexInTransitionTable = 0; indexInTransitionTable < NUM_OF_TRANSITION; ++indexInTransitionTable)
+ {
+ if ((stateTransitionTable[indexInTransitionTable].m_sourceState == state) && (stateTransitionTable[indexInTransitionTable].m_returnCode == returnCode))
+ {
+ //len = usnprintf(str, 60, "\r\n tick %d state %d return code %d",tick,state, returnCode );
+ //cb_push_back (str, len);
+
+ //in normal execution flow function should not arrive here
+ //in case it did the meaning is that the entery point was wrong and a bug should be corrected
+ return stateTransitionTable[indexInTransitionTable].m_destinationState;
+ }
+ }
+ //int tick = UsersysTickGet();
+ //len = usnprintf(str, 60, "\r\n tick %d state %d return code %d",tick,state, returnCode );
+ //cb_push_back (str, len);
+
+ //in normal execution flow function should not arrive here
+ //in case it did the meaning is that the entery point was wrong and a bug should be corrected
+ len = usnprintf(str, 80, "Internal: invalid slow motor transition state %d return code %d",state, returnCode );
+
+ return EXIT_STATE;
+}
+//********************************************************************************
+//this function is used to manage and operate the motor managmant state mashine
+//the highest managment level
+//********************************************************************************
+bool ThreadPrintingIterate(void *JobDetails)
+{
+ uint32_t tick = 0;
+ char str[60];
+ uint8_t len = 0;
+ PrintingState_t keepstate = gPrintingState;
+ //
+ // Disable all interrupts.
+ //
+ ROM_IntMasterDisable();
+
+ ReturnCode (* state_fun)(void *JobDetails) = state[gPrintingState];
+ //if (_motorId == SCREW_MOTOR)
+ // screw_movement[gPrintingState[_motorId]]++;
+ ReturnCode returnCode = state_fun(JobDetails);
+
+ /*if ((_motorId == SCREW_MOTOR)&&(pause_active))
+ {
+ tick = UsersysTickGet();
+ len = usnprintf(str, 60, "\r\n PrintingIterate tick %d state %d retcode %d ",tick, gPrintingState[_motorId],returnCode);
+ cb_push_back (str, len);
+ //SendInterruptMessageToHost(10+gPrintingState[_motorId],returnCode);
+ }*/
+ gPrintingState = LookupTransitions(gPrintingState, returnCode);
+ if (keepstate != gPrintingState){
+ tick = UsersysTickGet();
+ len = usnprintf(str, 60, "\r\n changed state tick %d state %d retcode %d ", tick, gPrintingState,returnCode);
+ cb_push_back (str, len);
+
+ }
+
+ //
+ // Enable all interrupts.
+ //
+ ROM_IntMasterEnable();
+ return (gPrintingState != EXIT_STATE);
+}
+
+
+//********************************************************************************************************************
+
+void ThreadPrintingsInit(void)
+{
+// gPrintingState = Start;
+}
+
+//********************************************************************************************************************
+
+void ThreadStartPrinting(void)
+{
+ gPrintingState = ENTRY_STATE;
+ //PrintingIterate();
+}
+
+//********************************************************************************************************************
+//********************************************************************************************************************
+
+void ThreadStopPrinting(void)
+{
+ gPrintingState = EXIT_STATE;
+ //PrintingIterate();
+}
diff --git a/Software/Embedded_SW/Embedded/Modules/Waste/Waste.h b/Software/Embedded_SW/Embedded/Modules/Waste/Waste.h
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Waste/Waste.h
diff --git a/Software/Embedded_SW/Embedded/Modules/Waste/Waste_BIT.c b/Software/Embedded_SW/Embedded/Modules/Waste/Waste_BIT.c
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Waste/Waste_BIT.c
diff --git a/Software/Embedded_SW/Embedded/Modules/Waste/Waste_ex.h b/Software/Embedded_SW/Embedded/Modules/Waste/Waste_ex.h
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Waste/Waste_ex.h
diff --git a/Software/Embedded_SW/Embedded/Modules/Waste/Waste_init.c b/Software/Embedded_SW/Embedded/Modules/Waste/Waste_init.c
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Waste/Waste_init.c
diff --git a/Software/Embedded_SW/Embedded/Modules/Waste/Waste_maint.c b/Software/Embedded_SW/Embedded/Modules/Waste/Waste_maint.c
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Waste/Waste_maint.c
diff --git a/Software/Embedded_SW/Embedded/Modules/Waste/Waste_print.c b/Software/Embedded_SW/Embedded/Modules/Waste/Waste_print.c
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Modules/Waste/Waste_print.c