aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/StubRealTimeUsage.h
blob: 7c0fee8ed8546997deff5a87bfa9d84d3ad3f2d4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
 * StubRealTimeUsage.h
 *
 *  Created on: 15 ���� 2018
 *      Author: shlomo
 */

#ifndef MODULES_STUBS_HANDLER_STUBREALTIMEUSAGE_H_
#define MODULES_STUBS_HANDLER_STUBREALTIMEUSAGE_H_


void Stub_RealTimeUsageRequest(MessageContainer* requestContainer);


#endif /* MODULES_STUBS_HANDLER_STUBREALTIMEUSAGE_H_ */
/************************************************************************************************************************
 * 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 "PMR/Hardware/HardwarePidControl.pb-c.h"
#include "PMR/Hardware/HardwarePidControlType.pb-c.h"
#include "PMR/common/MessageContainer.pb-c.h"
#include "PMR/Stubs/StubHeatingTestRequest.pb-c.h"
#include "PMR/Stubs/StubHeatingTestResponse.pb-c.h"
#include "PMR/Stubs/StubHeatingTestPollRequest.pb-c.h"
#include "PMR/Stubs/StubHeatingTestPollResponse.pb-c.h"

#include "../control/control.h"
#include "../control/pidalgo.h"
#include "include.h"
#include <driverlib/timer.h>
#include <DataDef.h>
#include "heaters_ex.h"
#include "heaters.h"
#include "Drivers/Heater/Heater.h"
#include "Drivers/Heater/TemperatureSensor.h"
#include "Drivers/I2C_Communication/Head_Card/PT100/Head_PT100_ADC.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[HEATER_TYPE_MAX_HEATERS] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
bool AcHeaterConfigured[MAX_AC_HEATERS] = {0,0,0};

int      NumberOFSlicesInUse = 0;
uint32_t MillisecondsPerChange = 0;

bool FastHeating = 1;
/******************** CODE  ********************************************/
/*
 * HeatersInit
 * called by: General Hardware Init
 * initialized all global data
 */
uint32_t Heaters_Init(void)
{
    int i;
    //ROM_TimerDisable(Heater_timerBase, TIMER_A);

    FPGA_SensorInitConfig();

    memset(HeaterControl,0,sizeof(HeaterControl));
    for (i = 0;i<HEATER_TYPE_MAX_HEATERS; i++)
        DeActivateHeater(i);
    initializeArrays();

    BlowerCfg.enabled = true;
    BlowerCfg.voltage = 3000;
    BlowerCfg.heatingvoltage = 3000;
    if (WHS_Type == WHS_TYPE_UNKNOWN)
        BlowerCfg.hardwareblowertype = HARDWARE_BLOWER_TYPE__DefaultBlower;
    else
        BlowerCfg.hardwareblowertype = HARDWARE_BLOWER_TYPE__WHSBlower2;

    return OK;
}




uint32_t HeaterConfigRequestMessage(HardwarePidControl* request)
{
    //uint32_t status = OK;
    HardwarePidControlType HeaterId;

    HeaterId = getHeaterId(request->hardwarepidcontroltype);
    //int ValidationError = 0;

    if (HeaterId< HEATER_TYPE_MAX_HEATERS)
    {
        HeaterControl[HeaterId].configured = true;
        HeaterControl[HeaterId].id = HeaterId;
        HeaterControl[HeaterId].outputproportionalpowerlimit = request->outputproportionalpowerlimit;
        HeaterControl[HeaterId].outputproportionalband = request->outputproportionalband;
        HeaterControl[HeaterId].IntegralErrorMultiplier = request->setpointramprateorsoftstartramp;
        HeaterControl[HeaterId].ProportionalErrorMultiplier = request->outputonoffhysteresisvalue;
        if (HeaterId == HARDWARE_PID_CONTROL_TYPE__DryerAirTemperature)
        {
            HeaterControl[HEATER_TYPE__DryerMainHeater].sensormaxvalue = request->sensormaxvalue*100;
            HeaterControl[HEATER_TYPE__DryerMainHeater].sensorminvalue = request->sensorminvalue*100;
            HeaterControl[HEATER_TYPE__DryerSecondaryHeater].sensormaxvalue = request->sensormaxvalue*100;
            HeaterControl[HEATER_TYPE__DryerSecondaryHeater].sensorminvalue = request->sensorminvalue*100;
        }
        HeaterControl[HeaterId].sensormaxvalue = 0;
        HeaterControl[HeaterId].sensorminvalue = 0;
        HeaterControl[HeaterId].kp = request->proportionalgain;
        HeaterControl[HeaterId].ki = request->integraltime;
        HeaterControl[HeaterId].kd = request->derivativetime;
        HeaterControl[HeaterId].dt = request->controloutputtype;
        HeaterControl[HeaterId].epsilon = request->epsilon;
        HeaterControl[HeaterId].pidactive = request->pidactive;
        //HeaterControl[HeaterId].sensorcorrectionadjustment = request->sensorcorrectionadjustment;
        //sensorminvalue,sensormaxvalue are used for the dryer heater as internal heater control
        //HeaterControl[HeaterId].sensortypeandsetpointlimits = request->sensortypeandsetpointlimits;
        //HeaterControl[HeaterId].setpointramprateorsoftstartramp = request->setpointramprateorsoftstartramp;
        //HeaterControl[HeaterId].setpointcontroloutputrate = request->setpointcontroloutputrate;
        //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;

        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)
   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[HEATER_TYPE__DryerMainHeater].outputproportionalpowerlimit * NumberOFSlicesInUse / 100;
   Heater200aSlices = HeaterControl[HEATER_TYPE__DryerSecondaryHeater].outputproportionalpowerlimit * NumberOFSlicesInUse / 100;

   if ((Heater1000Slices + Heater200aSlices +2)>NumberOFSlicesInUse)
   {
       LOG_ERROR (NumberOFSlicesInUse, "proportional time slices too high too high");
       return ERROR;//NumberOFSlicesInUse = MAX_TIMESLICES;
   }

   //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] = HEATER_TYPE__DryerMainHeater;
   for (Slice_i = Heater1000Slices+1; Slice_i <= Heater1000Slices+Heater200aSlices;Slice_i++ ) TimeSliceAllocation[Slice_i] = HEATER_TYPE__DryerSecondaryHeater;

   return OK;

}
/*
 * HeaterRecalculateSharedHeatersParams -
 *
 * parameters - the cycle time for the coordinated operation, the size (in MCU cycles) of a single step.
 */
uint32_t stub_heating_limit = 100;
uint32_t HeaterRecalculateSharedHeatersParams(uint32_t deviceId, uint32_t new_outputproportionalpowerlimit)
{
   int Slice_i;
   int Heater1000Slices,Heater200aSlices /*,Heater200bSlices Currently both 200W heaters will work together*/;
   uint32_t stub_outputproportionalpowerlimit = new_outputproportionalpowerlimit;

   if (NumberOFSlicesInUse > MAX_TIMESLICES )
   {
       LOG_ERROR (NumberOFSlicesInUse, "NumberOFSlicesInUse too high");
       return ERROR;//NumberOFSlicesInUse = MAX_TIMESLICES;
   }

   if (stub_outputproportionalpowerlimit > stub_heating_limit)
       stub_outputproportionalpowerlimit = stub_heating_limit;
   // all numbers are rounded down. better to have carefully calculated numbers
   HeaterControl[deviceId].outputproportionalpowerlimit = stub_outputproportionalpowerlimit;///100;
   Heater1000Slices = HeaterControl[HEATER_TYPE__DryerMainHeater].outputproportionalpowerlimit * NumberOFSlicesInUse / 100;
   Heater200aSlices = HeaterControl[HEATER_TYPE__DryerSecondaryHeater].outputproportionalpowerlimit * NumberOFSlicesInUse / 100;

//#warning temporary disable time slice control as we are working with one heater in run time
/*   if ((Heater1000Slices + Heater200aSlices +2)>NumberOFSlicesInUse)
   {
       LOG_ERROR (NumberOFSlicesInUse, "proportional time slices too high too high");
       return ERROR;//NumberOFSlicesInUse = MAX_TIMESLICES;
   }
*/
   //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] = HEATER_TYPE__DryerMainHeater;
   for (Slice_i = Heater1000Slices+1; Slice_i <= Heater1000Slices+Heater200aSlices;Slice_i++ ) TimeSliceAllocation[Slice_i] = HEATER_TYPE__DryerSecondaryHeater;

   return OK;

}

/*
 * HeaterRecalculateHeaterParams - prepare the time slices for D/C heaters 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 HeaterRecalculateHeaterParams(uint32_t deviceId, uint32_t new_outputproportionalpowerlimit)
{
   // 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
   if (new_outputproportionalpowerlimit > HeaterControl[deviceId].outputproportionalpowerlimit)
       new_outputproportionalpowerlimit = HeaterControl[deviceId].outputproportionalpowerlimit;

   //mark the time slices  for heaters operation as empty / Heater1000 / Heater 200
   DCTimeSliceAllocation[deviceId] = (new_outputproportionalpowerlimit/*/100*/ * NumberOFSlicesInUse) / 100;



   return OK;

}