aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_init.c
blob: 169ae463e73f9dbdb07720d03b83ccc27d531404 (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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Tango.SharedUI;

namespace Tango.MachineStudio.RML.Contracts
{
    public enum RmlNavigationView
    {
        RmlsView,
        RmlView,
    }

    public interface IMainView : IView
    {
        void NavigateTo(RmlNavigationView view);
    }
}
n269'>269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297
/************************************************************************************************************************
 * 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"



/******************** 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,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)
{
    //ROM_TimerDisable(Heater_timerBase, TIMER_A);
    FPGA_SensorInitConfig();
    return OK;
}

void HeatingTestRequest(MessageContainer* requestContainer)
{
//#ifdef DEBUG_TEST_FUNCTIONS
    MessageContainer responseContainer;
    uint8_t* container_buffer;
    uint32_t status = 0;

    StubHeatingTestRequest* request = stub_heating_test_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data);
    StubHeatingTestResponse response = STUB_HEATING_TEST_RESPONSE__INIT;

    responseContainer = createContainer(MESSAGE_TYPE__StubHeatingTestResponse, requestContainer->token, false, &response, &stub_heating_test_response__pack, &stub_heating_test_response__get_packed_size);
    container_buffer = my_malloc(message_container__get_packed_size(&responseContainer));



    //if (status)
    {
        responseContainer.has_error = true;
        responseContainer.error = ERROR_CODE__JOB_UNSPECIFIED_ERROR;
    }
    size_t container_size = message_container__pack(&responseContainer, container_buffer);
    my_free(responseContainer.data.data);
    //USBCDCD_sendData(container_buffer, container_size,10);
    SendChars(container_buffer, container_size);
    stub_heating_test_request__free_unpacked(request,NULL);

//#else
//    LOG_ERROR (-1, "Heating Control not on debug");
//    return ERROR;
//#endif
}
void HeatingTestPollRequest(MessageContainer* requestContainer)
{
    uint8_t* container_buffer;

    StubHeatingTestPollRequest* request = stub_heating_test_poll_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data);

    StubHeatingTestPollResponse response = STUB_HEATING_TEST_POLL_RESPONSE__INIT;
    MessageContainer responseContainer;


    responseContainer = createContainer(MESSAGE_TYPE__StubHeatingTestPollResponse, requestContainer->token, false, &response, &stub_heating_test_poll_response__pack, &stub_heating_test_poll_response__get_packed_size);
    container_buffer = my_malloc(message_container__get_packed_size(&responseContainer));



    {
        responseContainer.has_error = true;
        responseContainer.error = ERROR_CODE__JOB_UNSPECIFIED_ERROR;
    }
    size_t container_size = message_container__pack(&responseContainer, container_buffer);
    my_free(responseContainer.data.data);
    SendChars(container_buffer, container_size);
    stub_heating_test_poll_request__free_unpacked(request,NULL);
}



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

    HeaterId = request->hardwarepidcontroltype;
    int ValidationError = 0;

    if (HeaterId< MAX_HEATERS_NUM)
    {
        HeaterControl[HeaterId].configured = true;
        HeaterControl[HeaterId].id = HeaterId;
        HeaterControl[HeaterId].outputproportionalpowerlimit = request->outputproportionalpowerlimit;
        HeaterControl[HeaterId].outputproportionalband = request->outputproportionalband;
        if (HeaterId == HARDWARE_PID_CONTROL_TYPE__DryerAirTemperature)
        {
            HeaterControl[HARDWARE_PID_CONTROL_TYPE__DryerHeaterMain].sensormaxvalue = request->sensormaxvalue;
            HeaterControl[HARDWARE_PID_CONTROL_TYPE__DryerHeaterMain].sensorminvalue = request->sensorminvalue;
            HeaterControl[HARDWARE_PID_CONTROL_TYPE__DryerHeaterSecondary].sensormaxvalue = request->sensormaxvalue;
            HeaterControl[HARDWARE_PID_CONTROL_TYPE__DryerHeaterSecondary].sensorminvalue = request->sensorminvalue;
        }
        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;

        //check if all A/C heaters are defined. if they are - validate the configuration
        /*if (((HeaterId == HARDWARE_PID_CONTROL_TYPE__DryerHeaterMain)||(HeaterId == HARDWARE_PID_CONTROL_TYPE__DryerHeaterSecondary))
                &&HeaterControl[HARDWARE_PID_CONTROL_TYPE__DryerHeaterMain].configured
                &&HeaterControl[HARDWARE_PID_CONTROL_TYPE__DryerHeaterSecondary].configured)
        {
            if (HeaterControl[HARDWARE_PID_CONTROL_TYPE__DryerHeaterMain].outputproportionalpowerlimit
                    + HeaterControl[HARDWARE_PID_CONTROL_TYPE__DryerHeaterSecondary].outputproportionalpowerlimit > 100)
                    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)
   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__DryerHeaterMain].outputproportionalpowerlimit * NumberOFSlicesInUse / 100;
   Heater200aSlices = HeaterControl[HARDWARE_PID_CONTROL_TYPE__DryerHeaterSecondary].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] = HARDWARE_PID_CONTROL_TYPE__DryerHeaterMain;
   for (Slice_i = Heater1000Slices+1; Slice_i <= Heater1000Slices+Heater200aSlices;Slice_i++ ) TimeSliceAllocation[Slice_i] = HARDWARE_PID_CONTROL_TYPE__DryerHeaterSecondary;

   return OK;

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


   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
   HeaterControl[deviceId].outputproportionalpowerlimit = new_outputproportionalpowerlimit;///100;
   Heater1000Slices = HeaterControl[HARDWARE_PID_CONTROL_TYPE__DryerHeaterMain].outputproportionalpowerlimit * NumberOFSlicesInUse / 100;
   Heater200aSlices = HeaterControl[HARDWARE_PID_CONTROL_TYPE__DryerHeaterSecondary].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] = HARDWARE_PID_CONTROL_TYPE__DryerHeaterMain;
   for (Slice_i = Heater1000Slices+1; Slice_i <= Heater1000Slices+Heater200aSlices;Slice_i++ ) TimeSliceAllocation[Slice_i] = HARDWARE_PID_CONTROL_TYPE__DryerHeaterSecondary;

   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;

}