aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/Converters/BrushStopToOffsetLimitConverter.cs
blob: eb98fe7942e5e198fc71991876028c496a458049 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
using Tango.BL.Entities;

namespace Tango.MachineStudio.Developer.Converters
{
    public class BrushStopToOffsetLimitConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            try
            {
                BrushStop stop = values[0] as BrushStop;
                Segment segment = values[1] as Segment;
                String sign = parameter.ToString();

                if (stop != null && segment != null)
                {

                    if (stop.IsLast)
                    {
                        return 100d;
                    }
                    else if (stop.IsFirst)
                    {
                        return 0d;
                    }
                    else
                    {
                        return sign == "min" ? 0 : 100d;
                    }
                }
                else
                {
                    return 100d;
                }
            }
            catch
            {
                return 100d;
            }
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}
/************************************************************************************************************************
 * Ids_maint.c
 * Printing module is responsible for :
 * operating the dispensers according to predefined dispensing rate from the UI
 **************************************************************************************************************************/
#include "include.h"
#include "ids.h"
#include "ids_ex.h"
#include "../control/control.h"
#include "../control/pidalgo.h"
#include "../thread/thread.h"
#include "PMR/Hardware/Hardwaremotor.pb-c.h"
#include "PMR/Hardware/HardwareDispenser.pb-c.h"
#include "StateMachines/Printing/printingSTM.h"

#include "drivers/I2C_Communication/ADC_MUX/ADC_MUX.h"
#include "drivers/I2C_Communication/Dispenser_Card/IO_Ports/Dispenser_IO.h"

#include "drivers/FPGA/FPGA_GPIO/FPGA_GPIO.h"
#include "drivers/FPGA/FPGA_SPI_Comm.h"
#include "drivers/Motors/Motor.h"
#include "drivers/Valves/Valve.h"


FPGA_GPI_ENUM     Dispenser_Id_to_LS_Id[MAX_SYSTEM_DISPENSERS] = {
      GPI_LS_DISPENSER_DOWN_1, //MOTO_DISPENSER_1 = 6,
      GPI_LS_DISPENSER_DOWN_2, //MOTO_DISPENSER_2 = 7,
      GPI_LS_DISPENSER_DOWN_3, //MOTO_DISPENSER_3 = 8,
      GPI_LS_DISPENSER_DOWN_4, //MOTO_DISPENSER_4 = 9,
      GPI_LS_DISPENSER_DOWN_5, //MOTO_DISPENSER_5 = 10,
      GPI_LS_DISPENSER_DOWN_6, //MOTO_DISPENSER_6 = 11,
      GPI_LS_DISPENSER_DOWN_7, //MOTO_DISPENSER_7 = 12,
      GPI_LS_DISPENSER_DOWN_8, //MOTO_DISPENSER_8 = 13,
};
FPGA_GPI_ENUM     Dispenser_Id_to_LS_Empty_Id[MAX_SYSTEM_DISPENSERS] = {
      GPI_LS_DISPENSER_UP_1, //MOTO_DISPENSER_1 = 6,
      GPI_LS_DISPENSER_UP_2, //MOTO_DISPENSER_2 = 7,
      GPI_LS_DISPENSER_UP_3, //MOTO_DISPENSER_3 = 8,
      GPI_LS_DISPENSER_UP_4, //MOTO_DISPENSER_4 = 9,
      GPI_LS_DISPENSER_UP_5, //MOTO_DISPENSER_5 = 10,
      GPI_LS_DISPENSER_UP_6, //MOTO_DISPENSER_6 = 11,
      GPI_LS_DISPENSER_UP_7, //MOTO_DISPENSER_7 = 12,
      GPI_LS_DISPENSER_UP_8, //MOTO_DISPENSER_8 = 13,
};
FPGA_GPI_ENUM     Dispenser_Id_to_Alarm_LS_Id[MAX_SYSTEM_DISPENSERS*2] = {
      GPI_LS_DISPENSER_UP_1, //MOTO_DISPENSER_1 = 6,
      GPI_LS_DISPENSER_UP_2, //MOTO_DISPENSER_2 = 7,
      GPI_LS_DISPENSER_UP_3, //MOTO_DISPENSER_3 = 8,
      GPI_LS_DISPENSER_UP_4, //MOTO_DISPENSER_4 = 9,
      GPI_LS_DISPENSER_UP_5, //MOTO_DISPENSER_5 = 10,
      GPI_LS_DISPENSER_UP_6, //MOTO_DISPENSER_6 = 11,
      GPI_LS_DISPENSER_UP_7, //MOTO_DISPENSER_7 = 12,
      GPI_LS_DISPENSER_UP_8, //MOTO_DISPENSER_8 = 13,
      GPI_LS_DISPENSER_25_1, //MOTO_DISPENSER_1 = 6,
      GPI_LS_DISPENSER_25_2, //MOTO_DISPENSER_2 = 7,
      GPI_LS_DISPENSER_25_3, //MOTO_DISPENSER_3 = 8,
      GPI_LS_DISPENSER_25_4, //MOTO_DISPENSER_4 = 9,
      GPI_LS_DISPENSER_25_5, //MOTO_DISPENSER_5 = 10,
      GPI_LS_DISPENSER_25_6, //MOTO_DISPENSER_6 = 11,
      GPI_LS_DISPENSER_25_7, //MOTO_DISPENSER_7 = 12,
      GPI_LS_DISPENSER_25_8, //MOTO_DISPENSER_8 = 13,
};
callback_fptr HomingRequestCallback[MAX_SYSTEM_DISPENSERS]={0,0,0,0,0,0,0,0};
callback_fptr HomingBacklashCallback[MAX_SYSTEM_DISPENSERS]={0,0,0,0,0,0,0,0};
uint32_t HomingBacklashTimeout[MAX_SYSTEM_DISPENSERS];
uint32_t HomingBacklashTime[MAX_SYSTEM_DISPENSERS];

int32_t KeepMicrostep[MAX_SYSTEM_DISPENSERS];

bool HomingActive[MAX_SYSTEM_DISPENSERS] = {false,false,false,false,false,false,false,false};
bool PrimingActive[MAX_SYSTEM_DISPENSERS] = {false,false,false,false,false,false,false,false};
uint32_t DispenserHomingControlId[MAX_SYSTEM_DISPENSERS] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
uint32_t DispenserBacklashControlId[MAX_SYSTEM_DISPENSERS] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
uint32_t DispenserHomingTime[MAX_SYSTEM_DISPENSERS] = {0,0,0,0,0,0,0,0};
#define INITIAL_DISPENSER_PRESSURE 2.10
#define INITIAL_DISPENSER_TIMEOUT_LIMIT 60000
#define INITIAL_DISPENSER_TIMEOUT 100
#define INITIAL_DISPENSER_SPEED 1000

double   InitialDispenserPressure = INITIAL_DISPENSER_PRESSURE;
uint32_t InitialDispenserTimeout = INITIAL_DISPENSER_TIMEOUT_LIMIT;
uint32_t InitialDispenserTimeLag = INITIAL_DISPENSER_TIMEOUT;
uint32_t InitialDispenserSpeed = INITIAL_DISPENSER_SPEED;

uint32_t IDS_StopHomeDispenserBuildPressure (uint32_t deviceID);

AutoHoming_Config_enum AutoHoming_Config = AutoHoming_off;
void IDS_Dispenser_SetAutoHoming_Config(AutoHoming_Config_enum Config)
{
    Report("IDS_Dispenser_SetAutoHoming_Config ",__FILE__,__LINE__,Config,RpWarning,AutoHoming_Config,0);
    AutoHoming_Config = Config;
}

void IDS_Dispenser_SetBackLashValues(double   initialdispenserpressure,   uint32_t initialdispensertimeout,   uint32_t initialdispensertimelag,   uint32_t initialdispenserspeed)
{
    InitialDispenserPressure = initialdispenserpressure;
    InitialDispenserTimeout = initialdispensertimeout;
    InitialDispenserTimeLag = initialdispensertimelag;
    InitialDispenserSpeed = INITIAL_DISPENSER_SPEED;

    Report("IDS_Dispenser_SetBackLashValues ",__FILE__,InitialDispenserPressure*100,InitialDispenserTimeout,RpWarning,(int)InitialDispenserTimeLag,0);
}
uint32_t IDS_HomeDispenserWaitForHomingEndCallback(uint32_t DispenserId, uint32_t ReadValue)
{
    HomingBacklashTime[DispenserId]+=eOneSecond;
    if (( HomingActive[DispenserId]== false) ||((HomingBacklashTime[DispenserId]>=HomingBacklashTimeout[DispenserId])&&(HomingBacklashTimeout[DispenserId]>0)))
       {
           //stop this control loop
           SafeRemoveControlCallback(DispenserBacklashControlId[DispenserId], IDS_HomeDispenserWaitForHomingEndCallback );
           DispenserBacklashControlId[DispenserId] = 0xFF;

           if (HomingBacklashCallback[DispenserId])
           {
               if ( HomingActive[DispenserId]== false)
                   HomingBacklashCallback[DispenserId](DispenserId,OK);
               else
                   HomingBacklashCallback[DispenserId](DispenserId,ERROR);
           }
           HomingBacklashCallback[DispenserId] = 0;
       }
    return OK;
}
uint32_t IDS_HomeDispenserWaitForHomingEnd(uint32_t DispenserId,  uint32_t timeout , callback_fptr callback)
{
    assert(DispenserId < MAX_SYSTEM_DISPENSERS);

    if (HomingBacklashCallback[DispenserId]!=NULL)
        return ERROR;
    HomingBacklashCallback[DispenserId] = callback;
    HomingBacklashTimeout[DispenserId] = timeout;
    HomingBacklashTime[DispenserId] = 0;

    if (DispenserBacklashControlId[DispenserId] != 0xFF)
    {
        RemoveControlCallback(DispenserBacklashControlId[DispenserId], IDS_HomeDispenserWaitForHomingEndCallback );
        DispenserBacklashControlId[DispenserId] = 0xFF;
        //return ERROR;
    }
    DispenserBacklashControlId[DispenserId] = AddControlCallback("Wait for Homing", IDS_HomeDispenserWaitForHomingEnd,eOneSecond , TemplateDataReadCBFunction,DispenserId,0, 0 );
    if ( DispenserBacklashControlId[DispenserId] == 0xFF)
        return ERROR;

    return OK;
}

uint32_t IDS_HomeDispenserBackMoveCallback(uint32_t motorId, uint32_t ReadValue)
{
    uint8_t DispenserId = motorId-HARDWARE_MOTOR_TYPE__MOTO_DISPENSER_1;
    if ((GetDispenserPressure(DispenserId)>=InitialDispenserPressure)||(DispenserHomingTime[DispenserId]>InitialDispenserTimeout)||(JobStartStopBackLash[DispenserId] == true))
    {
        MotorStop(motorId,Hard_Hiz);
        CurrentDispenserSpeed[DispenserId] = 0;
        if (Extended_Motor_Param == true)
            Power_Step_01_Dispenser_Mode(DispenserId,Voltage);
        MotorSetMicroStep(motorId, KeepMicrostep[DispenserId]);
        HomingActive[DispenserId]= false;
        PrimingActive[DispenserId]= false;
        Control_TCA9534ByPass(DispenserId,DISABLE);// use ENABLE or DISABLE

        //close dry air valve in the dispenser
        Valve_Set(IDS_Id_to_AirValve[DispenserId], Atm_MidTank_OFF);
        Disable_MidTank_Pressure_Reading(DispenserId);

        if (JobStartStopBackLash[DispenserId] == true)
            JobStartStopBackLash[DispenserId] = false;
        Report("End backlash",__FILE__,millisecondCounter,(int)DispenserId,RpWarning,(int)DispenserHomingTime[DispenserId],0);
        if (SafeRemoveControlCallback(DispenserHomingControlId[DispenserId], IDS_HomeDispenserBackMoveCallback )==OK)
            DispenserHomingControlId[DispenserId] = 0xFF;
        else
            Report("Remove control callback failed",__FILE__,__LINE__,(int)DispenserId,RpWarning,(int)DispenserHomingControlId[DispenserId],0);
        DispenserHomingTime[DispenserId]=0;
    }
    else
    {
        DispenserHomingTime[DispenserId]+=InitialDispenserTimeLag;
    }
    return OK;
}
uint32_t IDS_HomeDispenserCallback(uint32_t motorId, uint32_t ReadValue)
{
    uint8_t DispenserId = motorId-HARDWARE_MOTOR_TYPE__MOTO_DISPENSER_1;

    MotorStop(motorId,Hard_Hiz);
    CurrentDispenserSpeed[DispenserId] = 0;
    if (Extended_Motor_Param == true)
        Power_Step_01_Dispenser_Mode(DispenserId,Voltage);
    Read_MidTank_Pressure_Sensor(DispenserId);
    //close dry air valve in the dispenser
    Valve_Set(IDS_Id_to_AirValve[DispenserId], Atm_MidTank_OFF);
    Disable_MidTank_Pressure_Reading(DispenserId);
    MotorSetMicroStep(motorId, KeepMicrostep[DispenserId]);
    HomingActive[DispenserId]= false;
    PrimingActive[DispenserId]= false;
    Control_TCA9534ByPass(DispenserId,DISABLE);// use ENABLE or DISABLE
    if (HomingRequestCallback[DispenserId])
    {
        HomingRequestCallback[DispenserId](DispenserId,0);
        HomingRequestCallback[DispenserId] = NULL;
    }
//    HomingActive[DispenserId]= false;
    IDS_Dispenser_RefillEnded ( DispenserId, MotorsCfg[motorId].microstep);
    Report("End homing no backlash backlash",__FILE__,millisecondCounter,(int)DispenserId,RpWarning,(int)DispenserHomingTime[DispenserId],0);
    /*Report("Start backlash",__FILE__,millisecondCounter,(int)DispenserId,RpWarning,(int)DispenserHomingTime[DispenserId],0);
    DispenserHomingControlId[DispenserId] = AddControlCallback( IDS_HomeDispenserBackMoveCallback, InitialDispenserTimeLag, GetDispenserPressure,motorId, motorId, 0 );
    MotorSetDirection(motorId,MotorsCfg[motorId].directionthreadwize);
    Task_sleep(10);
    MotorSetSpeed(motorId, InitialDispenserSpeed);
    CurrentDispenserSpeed[DispenserId] = InitialDispenserSpeed;*/
    return OK;
}

uint32_t IDS_HomeDispenser (uint32_t DispenserId, uint32_t speed , callback_fptr callback)
{
    assert(DispenserId < MAX_SYSTEM_DISPENSERS);
    //if (DispensersAlarmState[DispenserId] == true)
    //    return ERROR;

    double midTankContent = 0.0;
    if (FPGA_Read_limit_Switches(Dispenser_Id_to_LS_Id[DispenserId]) == LIMIT)
    {
        Report("IDS_HomeDispenser - Disp is full",__FILE__,Dispenser_Id_to_LS_Id[DispenserId],(int)DispenserId,RpWarning,LIMIT,0);
        return OK;
    }
    if (Get_MidTank_Pressure_Sensor(DispenserId)<0.2)
    {
        Report("IDS_HomeDispenser - Midtank is empty",__FILE__,Get_MidTank_Int1000_Sensor(DispenserId),(int)DispenserId,RpWarning,LIMIT,0);
        return ERROR;
    }
    //if Safety is active
        //if safety is upper position or
    if ((HomingActive[DispenserId] == true)||(PrimingActive[DispenserId] == true))
    {
        Report("IDS_HomeDispenser - Homing/priming already active",__FILE__,HomingActive[DispenserId],(int)DispenserId,RpWarning,PrimingActive[DispenserId],0);
        return ERROR;
    }
    else
        HomingActive[DispenserId] = true;

    if (Check_Disp_Safety_Stop_Indication(DispenserId) == true)
    {
        if ((Get_Notification_Disp_UP(DispenserId) == false)||(Get_Notification_Over_Press(DispenserId) == false))
        {
            Report("IDS_HomeDispenser - Bypassing safety",__FILE__,HomingActive[DispenserId],(int)DispenserId,RpWarning,PrimingActive[DispenserId],0);
            Control_TCA9534ByPass(DispenserId,ENABLE);// use ENABLE or DISABLE
        }
    }
    HomingRequestCallback[DispenserId] = callback;

    TimerMotors_t MotorId = HARDWARE_MOTOR_TYPE__MOTO_DISPENSER_1 + DispenserId;
    if ( Dispenser_Id_to_LS_Id[DispenserId] != MAX_GPI)
    {
        //open dispenser valve dispenser to midtank direction
        Control3WayValvesWithCallback ((Valves_t)DispenserId, MidTank_Dispenser, NULL); //direction: MidTank_Dispenser or Dispenser_Mixer
        KeepMicrostep[DispenserId] = MotorsCfg[MotorId].microstep;
        if (Extended_Motor_Param == true)
            Power_Step_01_Dispenser_Mode(DispenserId,Current);
        MotorSetMicroStep(MotorId, 1);
        SysCtlDelay(180000);
        //open dry air valve in the dispenser
        Valve_Set(IDS_Id_to_AirValve[DispenserId], Atm_MidTank_ON);
        Enable_MidTank_Pressure_Reading(DispenserId);
        SysCtlDelay(1200000);
        midTankContent = Read_MidTank_Pressure_Sensor(DispenserId);
        if (midTankContent < 0.2) //midtank is empty - abort!!!!
        {
            Report("IDS_HomeDispenser - Mid Tank Empty!!! ",__FILE__,__LINE__,(int)(midTankContent * 1000),RpWarning,DispenserId,0);
            Valve_Set(IDS_Id_to_AirValve[DispenserId], Atm_MidTank_OFF);
            STATUS_GREEN_LED_OFF;
            STATUS_RED_LED_ON;

            return ERROR;
        }

        IDS_Dispenser_RefillStarted(DispenserId,1);
        MotorMovetoLimitSwitch (MotorId,1-MotorsCfg[MotorId].directionthreadwize, speed,  Dispenser_Id_to_LS_Id[DispenserId], IDS_HomeDispenserCallback,0);
        CurrentDispenserSpeed[DispenserId] = speed;
        CurrentDispenserSpeed[DispenserId] = (-1*CurrentDispenserSpeed[DispenserId]);
        Report("IDS_HomeDispenser ",__FILE__,__LINE__,(int)DispenserId,RpWarning,speed,0);
        return OK;
    }
    return ERROR;
}
uint32_t IDS_Dispenser_Alarm_On (uint8_t DispenserId)
{
    uint32_t status = OK;
    Report("IDS_Dispenser_Alarm_On",__FILE__,millisecondCounter,(int)DispenserId,RpWarning,0,0);
    DispensersAlarmState[DispenserId] = true;
    TimerMotors_t MotorId = HARDWARE_MOTOR_TYPE__MOTO_DISPENSER_1 + DispenserId;
    status |= MotorAbortMovetoLimitSwitch(MotorId);
    Valve_Set(IDS_Id_to_AirValve[DispenserId], Atm_MidTank_OFF);
    Enable_MidTank_Pressure_Reading(DispenserId);
    if (Extended_Motor_Param == true)
        Power_Step_01_Dispenser_Mode(DispenserId,Voltage);
    status |= MotorSetMicroStep(MotorId, KeepMicrostep[DispenserId]);
    status |= MotorStop(DispenserId, Hard_Hiz);
    CurrentDispenserSpeed[DispenserId] = 0;
    JobEndReason = JOB_OUT_OF_DYE;
    return status;
}
uint32_t IDS_Dispenser_Alarm_Off (uint8_t DispenserId)
{
    uint32_t status = OK;
    DispensersAlarmState[DispenserId] = false;
    Report("IDS_Dispenser_Alarm_Off",__FILE__,millisecondCounter,(int)DispenserId,RpWarning,0,0);
    return status;
}

uint32_t IDS_StopHomeDispenser (uint32_t DispenserId)
{
    assert(DispenserId < MAX_SYSTEM_DISPENSERS);

    Report("IDS_StopHomeDispenser",__FILE__,millisecondCounter,(int)DispenserId,RpWarning,(int)HomingActive[DispenserId],0);
    if ((HomingActive[DispenserId] == false)&&( PrimingActive[DispenserId] == false))
    {
        LOG_ERROR (DispenserId,"Homing not active");
        return OK;
    }

    TimerMotors_t MotorId = (DispenserId)+HARDWARE_MOTOR_TYPE__MOTO_DISPENSER_1;
    MotorAbortMovetoLimitSwitch(MotorId);
    //close dry air valve in the dispenser
    Disable_MidTank_Pressure_Reading(DispenserId);
    Valve_Set(IDS_Id_to_AirValve[DispenserId], Atm_MidTank_OFF);
    Control3WayValvesWithCallback ((Valves_t)DispenserId, MidTank_Dispenser, NULL); //direction: MidTank_Dispenser or Dispenser_Mixer

    if (HomingActive[DispenserId] == true)
    {
        IDS_StopHomeDispenserBuildPressure(DispenserId);
    }
    if (PrimingActive[DispenserId] == true)
    {
        if (DispenserId == LUBRICANT_DISPENSER)
        {
            Lubricant_2Way_Valve (STOP);
        }
        PrimingActive[DispenserId] = false;
        Control_TCA9534ByPass(DispenserId,DISABLE);// use ENABLE or DISABLE
        if (Extended_Motor_Param == true)
            Power_Step_01_Dispenser_Mode(DispenserId,Voltage);
        MotorSetMicroStep(MotorId, KeepMicrostep[DispenserId]);
        CurrentDispenserSpeed[DispenserId] = 0;
        CurrentDispenserSpeed[DispenserId] = 0;
    }
    return OK;
}
uint32_t IDS_StopHomeDispenserBuildPressure (uint32_t DispenserId)
{
    assert(DispenserId < MAX_SYSTEM_DISPENSERS);

    Report("IDS_StopHomeDispenser and build pressure",__FILE__,millisecondCounter,(int)DispenserId,RpWarning,(int)HomingActive[DispenserId],0);
    if (HomingActive[DispenserId] != true)
    {
        LOG_ERROR (DispenserId,"Homing not active");
        return ERROR;
    }
    else
        HomingActive[DispenserId] = false;
    Control_TCA9534ByPass(DispenserId,DISABLE);// use ENABLE or DISABLE

    TimerMotors_t motorId = (DispenserId)+HARDWARE_MOTOR_TYPE__MOTO_DISPENSER_1;
    MotorAbortMovetoLimitSwitch(motorId);
    //close dry air valve in the dispenser
//////////////////////////////////////////////////
    Read_MidTank_Pressure_Sensor(DispenserId);
    //close dry air valve in the dispenser
    Valve_Set(IDS_Id_to_AirValve[DispenserId], Atm_MidTank_OFF);
    Disable_MidTank_Pressure_Reading(DispenserId);
    CurrentDispenserSpeed[DispenserId] = 0;
    if (Extended_Motor_Param == true)
        Power_Step_01_Dispenser_Mode(DispenserId,Voltage);
    MotorSetMicroStep(motorId, KeepMicrostep[DispenserId]);

    if (HomingRequestCallback[DispenserId])
    {
        HomingRequestCallback[DispenserId](DispenserId,0);
        HomingRequestCallback[DispenserId] = NULL;
    }
//    HomingActive[DispenserId]= false;
    JobStartStopBackLash[DispenserId] = false;
    Report("End homing no backlash",__FILE__,millisecondCounter,(int)DispenserId,RpWarning,(int)DispenserHomingTime[DispenserId],0);
    /*if (JobStartStopBackLash[DispenserId] == true)
    {
            JobStartStopBackLash[DispenserId] = false;
            Report("End homing for job start",__FILE__,millisecondCounter,(int)DispenserId,RpWarning,(int)DispenserHomingTime[DispenserId],0);
    }
    else
    {
        Report("homing aborted,start backlash",__FILE__,millisecondCounter,(int)DispenserId,RpWarning,(int)DispenserHomingTime[DispenserId],0);
        DispenserHomingControlId[DispenserId] = AddControlCallback( IDS_HomeDispenserBackMoveCallback, InitialDispenserTimeLag, GetDispenserPressure,motorId, motorId, 0 );
        Task_sleep(10);
        MotorSetDirection(motorId,MotorsCfg[motorId].directionthreadwize);
        Task_sleep(10);
        MotorSetSpeed(motorId, 1000);
        CurrentDispenserSpeed[DispenserId] = 1000;
    }*/
    IDS_Dispenser_RefillEnded ( DispenserId, MotorsCfg[motorId].microstep);

    return OK;
}

uint32_t IDS_CheckDispenserLimitSwitch (LimitSwitchAlarms LS_Id)
{
    int DispenserId;
    if (LS_Id <= LimitSwitchAlarmEmpty_8)
    {
        DispenserId = LS_Id;
    }
    else
    {
        DispenserId = LS_Id-LimitSwitchAlarmEmpty_8;
    }
    if (isMotorConfigured(DispenserId + HARDWARE_MOTOR_TYPE__MOTO_DISPENSER_1)==false)
        return true;  //false is the alarm value
    else
        return FPGA_Read_limit_Switches(Dispenser_Id_to_Alarm_LS_Id[LS_Id]);
}
uint32_t IDS_EmptyDispenserCallback(uint32_t motorId, uint32_t ReadValue)
{
    uint8_t DispenserId = motorId-HARDWARE_MOTOR_TYPE__MOTO_DISPENSER_1;

    Read_MidTank_Pressure_Sensor(DispenserId);
    //close dry air valve in the dispenser
    Valve_Set(IDS_Id_to_AirValve[DispenserId], Atm_MidTank_OFF);
    Disable_MidTank_Pressure_Reading(DispenserId);

    MotorStop(motorId,Hard_Hiz);
    CurrentDispenserSpeed[DispenserId] = 0;
    if (Extended_Motor_Param == true)
        Power_Step_01_Dispenser_Mode(DispenserId,Voltage);
    MotorSetMicroStep(motorId, KeepMicrostep[DispenserId]);
    PrimingActive[DispenserId]= false;
    Control_TCA9534ByPass(DispenserId,DISABLE);// use ENABLE or DISABLE
    if (DispenserId == LUBRICANT_DISPENSER)
    {
        Lubricant_2Way_Valve (STOP);
    }
    Report("End Priming",__FILE__,millisecondCounter,(int)DispenserId,RpWarning,(int)DispenserHomingTime[DispenserId],0);
    //    MotorSetMicroStep(motorId, KeepMicrostep[DispenserId]);
    if (HomingRequestCallback[DispenserId])
    {
        HomingRequestCallback[DispenserId](DispenserId,0);
        HomingRequestCallback[DispenserId] = NULL;
    }
    return OK;
}

uint32_t IDS_EmptyDispenser (uint32_t DispenserId, uint32_t speed , callback_fptr callback)
{
    assert(DispenserId < MAX_SYSTEM_DISPENSERS);

    //if (DispensersAlarmState[DispenserId] == true)
    //    return ERROR;
    if ((HomingActive[DispenserId] == true)||(PrimingActive[DispenserId] == true))
        return ERROR;
    else
        PrimingActive[DispenserId] = true;
    HomingRequestCallback[DispenserId] = callback;
    if (Check_Disp_Safety_Stop_Indication(DispenserId) == true)
    {
        if ((Get_Notification_Disp_Down(DispenserId) == false)||(Get_Notification_Over_Press(DispenserId) == false))
        {
            Report("IDS_EmptyDispenser - Bypassing safety",__FILE__,HomingActive[DispenserId],(int)DispenserId,RpWarning,PrimingActive[DispenserId],0);
            Control_TCA9534ByPass(DispenserId,ENABLE);// use ENABLE or DISABLE
        }
    }
    TimerMotors_t MotorId = HARDWARE_MOTOR_TYPE__MOTO_DISPENSER_1 + DispenserId;
    if ( Dispenser_Id_to_LS_Empty_Id[DispenserId] != MAX_GPI)
    {
        //open dispenser valve dispenser to midtank direction
        Control3WayValvesWithCallback ((Valves_t)DispenserId, Dispenser_Mixer, NULL); //direction: MidTank_Dispenser or Dispenser_Mixer
        if (Extended_Motor_Param == true)
            Power_Step_01_Dispenser_Mode(DispenserId,Current);
        //Valve_Set((Valves_t) request->index, Dispenser_Mixer);
        KeepMicrostep[DispenserId] = MotorsCfg[MotorId].microstep;
        MotorSetMicroStep(MotorId, 1);
        Task_sleep(100);
        //open dry air valve in the dispenser
        //Valve_Set(IDS_Id_to_AirValve[DispenserId], Atm_MidTank_ON);
        if (DispenserId == LUBRICANT_DISPENSER)
        {
            Lubricant_2Way_Valve (START);
        }
        MotorMovetoLimitSwitch (MotorId,MotorsCfg[MotorId].directionthreadwize, speed,  Dispenser_Id_to_LS_Empty_Id[DispenserId], IDS_EmptyDispenserCallback,0);
        CurrentDispenserSpeed[DispenserId] = speed;
        return OK;
    }
    return ERROR;
}