aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/SideChains/ICSharpCode.AvalonEdit/Utils/Empty.cs
blob: 938f84fa216b3c808df13c7f9e52318974bc3d32 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)

using System;
using System.Collections.ObjectModel;

namespace ICSharpCode.AvalonEdit.Utils
{
	/// <summary>
	/// Provides immutable empty list instances.
	/// </summary>
	static class Empty<T>
	{
		public static readonly T[] Array = new T[0];
		//public static readonly ReadOnlyCollection<T> ReadOnlyCollection = new ReadOnlyCollection<T>(Array);
	}
}
/************************************************************************************************************************
 * Printing.c
 * High managment logical unit of slow motors in the system ( 6 dispensers and the screw motor)
 * profile run up begins from screw homing to begin position and only then from fast motors activation.
 * when every slow motor tuches the limit switch (no matter whether its screw or dispenser)
 * an interrupt occures in the system and as long as its pushing the limit switch all the system is prevented from operation.
 * because of that the work flow with interrupts must be :
     * design a function handle (what to do in the moment the interrupt arrives)
     * configure the wanted interrupt in the cfg file (according to the defined port and pin and its interrupt number and the handler)
     * enable interupt for predefined gpio in the application
     * when the interrupt arrives the handle will be automatically called
     * in case of the limit switches since the operation is continuess the interrupt must be disabled in order to continue the application running.
     * then the operation is not continues (like butten pushing) there is no need in disabling the interrupts

 * 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 "./printingSTM.h"
#include "modules/thread/thread_ex.h"
#include "modules/Heaters/Heaters_ex.h"
#include "modules/Diagnostics/Diagnostics.h"
#include "modules/ids/ids_ex.h"
#include "PMR/Hardware/UploadHardWareConfigurationRequest.pb-c.h"
#include "PMR/Hardware/HardwareMotorType.pb-c.h"
#include "modules/General/process.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
///////////////////////////////////////////////////////////////////////////////////////////

/********************************************************************************************
* functions describes motor operation flow and movement state during profile execution
* used to operate in runtime correct profileflow execution
*********************************************************************************************/
static uint32_t EntryState(void *JobDetails);
static uint32_t PrepareState(void *JobDetails);
static uint32_t PreSegmentState(void *JobDetails, int);
static uint32_t SegmentState(void *JobDetails, int);
uint32_t EndState(void *JobDetails, char *Message);
static uint32_t ExitState(void *JobDetails);

/**********************************************************************
* the array and enum of PrintingState_t below must be in sync order
***********************************************************************/
//static uint32_t (* state[])(void *JobDetails) = { EntryState, PrepareState, PreSegmentState,  SegmentState, EndState, ExitState};


typedef struct
{
    PrintingState_t m_sourceState;
    uint32_t          m_returnCode;
    PrintingState_t     m_destinationState;
} Transition_t;


////////////////////////Slow Motor State////////////////////////////////////
//static PrintingState_t gPrintingState;
////////////////////////////////////////////////////////////////////////////
ModuleStateEnum SegmentWaiting[MAX_SYSTEM_MODULES] =    {ModuleIdle,ModuleIdle,ModuleIdle,ModuleIdle,ModuleIdle};
ModuleStateEnum PreSegmentWaiting[MAX_SYSTEM_MODULES] = {ModuleIdle,ModuleIdle,ModuleIdle,ModuleIdle,ModuleIdle};
ModuleStateEnum DistanceToSpoolWaiting[MAX_SYSTEM_MODULES] = {ModuleIdle,ModuleIdle,ModuleIdle,ModuleIdle,ModuleIdle};
ModuleStateEnum PrintWaiting[MAX_SYSTEM_MODULES] =      {ModuleIdle,ModuleIdle,ModuleIdle,ModuleIdle,ModuleIdle};
ModuleStateEnum EndWaiting[MAX_SYSTEM_MODULES] =        {ModuleIdle,ModuleIdle,ModuleIdle,ModuleIdle,ModuleIdle};

bool Configured[MAX_SYSTEM_MODULES] = {false,false,false,false,false};

bool SuspendLargeMessages = false;

/********************************************************************************************************************
 * this function is for development initial stages. it analyses the hardware configuration to determine which modules are operational
 * according to the configuration map
 */

uint32_t PrintingHWConfiguration(void *Configuration)
{
    /*
     *     Module_Thread,
    Module_Winder,
    Module_IDS,
    Module_Heaters,
    Module_Waste,
     *
     */
    uint32_t i;
    HardwareConfiguration *request = Configuration;
    if (request->n_winders == 1)
        Configured[Module_Winder] = true;

    if (request->n_motors < HARDWARE_MOTOR_TYPE__MOTO_RDRIVING)
    {
        for (i = 0; i < request->n_motors ; i++)
        {
            if ((request->motors[i]->hardwaremotortype == HARDWARE_MOTOR_TYPE__MOTO_LDRIVING)||
                (request->motors[i]->hardwaremotortype == HARDWARE_MOTOR_TYPE__MOTO_RDRIVING)||
                (request->motors[i]->hardwaremotortype == HARDWARE_MOTOR_TYPE__MOTO_DRYER_DRIVING))
            {
                Configured[Module_Thread] = true;
                //break;
            }
            if ((request->motors[i]->hardwaremotortype == HARDWARE_MOTOR_TYPE__MOTO_DISPENSER_1)||
                (request->motors[i]->hardwaremotortype == HARDWARE_MOTOR_TYPE__MOTO_DISPENSER_2)||
                (request->motors[i]->hardwaremotortype == HARDWARE_MOTOR_TYPE__MOTO_DISPENSER_3)||
                (request->motors[i]->hardwaremotortype == HARDWARE_MOTOR_TYPE__MOTO_DISPENSER_4)||
                (request->motors[i]->hardwaremotortype == HARDWARE_MOTOR_TYPE__MOTO_DISPENSER_5)||
                (request->motors[i]->hardwaremotortype == HARDWARE_MOTOR_TYPE__MOTO_DISPENSER_6)||
                (request->motors[i]->hardwaremotortype == HARDWARE_MOTOR_TYPE__MOTO_DISPENSER_7)||
                (request->motors[i]->hardwaremotortype == HARDWARE_MOTOR_TYPE__MOTO_DISPENSER_8))
            {
                Configured[Module_IDS] = true;
                //break;
            }
        }
    }
    if (request->n_pidcontrols <= HARDWARE_PID_CONTROL_TYPE__Dispenser8)
    {
        for (i = 0; i < request->n_pidcontrols ; i++)
        {
            if (request->pidcontrols[i]->hardwarepidcontroltype <= HARDWARE_PID_CONTROL_TYPE__MixerHeater)
            {
                Configured[Module_Heaters] = true;
                break;
            }
        }
    }
    /*if (request->n_dispensers <= MAX_SYSTEM_DISPENSERS)
    {
        for (i = 0; i < request->n_dispensers ; i++)
        {
            if(request->dispensers[i]->index)
            {
                Configured[Module_IDS] = true;
                break;
            }
        }
    }*/


    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 uint32_t EntryState(void *JobDetails)
{
    return OK;
}

uint32_t PreSegmentReady(int ModuleId, ModuleStateEnum result)
{
    int i;
    bool ready = true;
    uint32_t status = OK;

    JobMessageStruc Message;
    PrintMessageStruc *PrtMessage = (PrintMessageStruc *)Message.messageData;

    assert (ModuleId<MAX_SYSTEM_MODULES);
    assert (result<=ModuleFail);

    if (PreSegmentWaiting[ModuleId] != ModuleWaiting)
    {
        LOG_ERROR (ModuleId, "Message from unrelated module!!");
    }

    PreSegmentWaiting[ModuleId] = result;
    if (result == ModuleFail) status = ERROR;
    for (i=0;i<MAX_SYSTEM_MODULES ;i++)
    {
        if (PreSegmentWaiting[i] == ModuleWaiting)
            ready = false;
    }
    if ((ready == false)&&(status == OK)) return OK;
    else
    {
        Message.messageId = PrintMessage;
        if (status == OK)
            {
                SendJobProgress(0.0, 0, false, "PreSegment Ready");
                PrtMessage->messageId = PreSegmentResultsOk;
            }
        else
            {
                PrtMessage->messageId = PreSegmentResultsFail;
                SendJobProgress(0.0, 0, false, "PreSegment Failed");
            }
        //memcpy(Message.messageData,JobDetails,MAX_MSG_LEN);
        Message.msglen = 10;
        if (JobmsgQ != NULL)
            Mailbox_post(JobmsgQ , &Message, BIOS_NO_WAIT);
    }
    return 0;

}

//********************************************************************************************************************
static uint32_t PreSegmentState(void *JobDetails, int SegmentId)
{
    SendJobProgress(0.0, SegmentId, false, "PreSegment Start");
    if (Configured[Module_Thread])
    {
        PreSegmentWaiting[Module_Thread] = ModuleWaiting;
    }
    if (Configured[Module_Winder])
    {
        PreSegmentWaiting[Module_Winder] = ModuleWaiting;
    }
    if (Configured[Module_IDS])
    {
        PreSegmentWaiting[Module_IDS] = ModuleWaiting;
    }
    if (Configured[Module_Thread])
    {
        ThreadPreSegmentState(JobDetails);
    }
    if (Configured[Module_Winder])
    {
        Winder_Presegment(JobDetails,SegmentId);  //must be after ThreadPreSegmentState
    }
    if (Configured[Module_IDS])
    {
        IDSPreSegmentState(JobDetails,SegmentId);
    }
    return OK;
}
//********************************************************************************************************************
uint32_t SegmentReady(int ModuleId, ModuleStateEnum result)
{
    int i;
    bool ready = true;
    uint32_t status = OK;

    JobMessageStruc Message;
    PrintMessageStruc *PrtMessage = (PrintMessageStruc *)Message.messageData;

    assert (ModuleId<MAX_SYSTEM_MODULES);
    assert (result<=ModuleFail);
    LOG_ERROR (ModuleId, "SegmentReady");

    if (SegmentWaiting[ModuleId] != ModuleWaiting)
    {
        LOG_ERROR (ModuleId, "Message from unrelated module!!");
    }

    SegmentWaiting[ModuleId] = result;
    if (result == ModuleFail) status = ERROR;
    for (i=0;i<MAX_SYSTEM_MODULES ;i++)
    {
        if (SegmentWaiting[i] == ModuleWaiting)
            ready = false;
    }
    if ((ready == false)&&(status == OK)) return OK;
    else
    {
        Message.messageId = PrintMessage;
        if (status == OK)
            {
                PrtMessage->messageId = SegmentResultsOk;
                SendJobProgress(0.0, 0, false, "Segment Done");
            }
        else
            {
                PrtMessage->messageId = SegmentResultsFail;
                SendJobProgress(0.0, 0, false, "Segment Fail");
            }
        //memcpy(Message.messageData,JobDetails,MAX_MSG_LEN);
        Message.msglen = 10;
        if (JobmsgQ != NULL)
            Mailbox_post(JobmsgQ , &Message, BIOS_NO_WAIT);
    }
    return 0;

}

//********************************************************************************************************************
static uint32_t SegmentState(void *JobDetails, int SegmentId)
{
    SendJobProgress(0.0, SegmentId, false, "Segment Start");
    if (Configured[Module_IDS])
    {
        //SegmentWaiting[Module_IDS] = ModuleWaiting;
        IDSSegmentState(JobDetails,SegmentId);
    }
    if (Configured[Module_Thread])
    {
        SegmentWaiting[Module_Thread] = ModuleWaiting;
        ThreadSegmentState(JobDetails,SegmentId);
    }
    if (Configured[Module_Winder])
    {
        //SegmentWaiting[Module_Winder] = ModuleWaiting;
        //Winder_Segment(JobDetails);
    }
    return OK;
}
//********************************************************************************************************************
uint32_t DistanceToSpoolReady(int ModuleId, ModuleStateEnum result)
{
    int i;
    bool ready = true;
    uint32_t status = OK;

    JobMessageStruc Message;
    PrintMessageStruc *PrtMessage = (PrintMessageStruc *)Message.messageData;

    assert (ModuleId<MAX_SYSTEM_MODULES);
    assert (result<=ModuleFail);

    if (DistanceToSpoolWaiting[ModuleId] != ModuleWaiting)
    {
        LOG_ERROR (ModuleId, "Message from unrelated module!!");
    }

    DistanceToSpoolWaiting[ModuleId] = result;
    if (result == ModuleFail) status = ERROR;
    for (i=0;i<MAX_SYSTEM_MODULES ;i++)
    {
        if (DistanceToSpoolWaiting[i] == ModuleWaiting)
            ready = false;
    }
    if ((ready == false)&&(status == OK)) return OK;
    else
    {
        Message.messageId = PrintMessage;
        if (status == OK)
            {
                PrtMessage->messageId = FinishResultsOk;
                SendJobProgress(0.0, 0, false, "DistanceToSpool Done");
            }
        else
            {
                PrtMessage->messageId = FinishResultsFail;
                SendJobProgress(0.0, 0, false, "DistanceToSpool Fail");
            }
        //memcpy(Message.messageData,JobDetails,MAX_MSG_LEN);
        Message.msglen = 10;
        if (JobmsgQ != NULL)
            Mailbox_post(JobmsgQ , &Message, BIOS_NO_WAIT);
    }
    return 0;

}

//********************************************************************************************************************
static uint32_t DistanceToSpoolState(void *JobDetails)
{
    SendJobProgress(0.0, 0, false, "DistanceToSpool Start");
    if (Configured[Module_IDS])
    {
        DistanceToSpoolWaiting[Module_IDS] = ModuleWaiting;
        IDSDistanceToSpoolState();
    }
    if (Configured[Module_Thread])
    {
        DistanceToSpoolWaiting[Module_Thread] = ModuleWaiting;
        ThreadDistanceToSpoolState();
    }
    if (Configured[Module_Winder])
    {
        //DistanceToSpoolWaiting[Module_Winder] = ModuleWaiting;
        //Winder_DistanceToSpool(JobDetails);
    }
    return OK;
}

//********************************************************************************************************************

uint32_t EndState(void *JobDetails, char *Message)
{
    //ROM_IntMasterDisable();
    SuspendLargeMessages = true;
    if (Configured[Module_Winder])
    {
        PrepareWaiting[Module_Winder] = ModuleIdle;
        SegmentWaiting[Module_Winder] = ModuleIdle;
        PreSegmentWaiting[Module_Winder] = ModuleIdle;
        DistanceToSpoolWaiting[Module_Winder] = ModuleIdle;
        //    EndWaiting[Module_Winder] = ModuleWaiting;
        Winder_End();
    }
    if (Configured[Module_IDS])
    {
        PrepareWaiting[Module_IDS] = ModuleIdle;
        SegmentWaiting[Module_IDS] = ModuleIdle;
        PreSegmentWaiting[Module_IDS] = ModuleIdle;
        DistanceToSpoolWaiting[Module_IDS] = ModuleIdle;
        //EndWaiting[Module_IDS] = ModuleWaiting;
        IDSEndState(JobDetails);
    }
    /*if (Configured[Module_Heaters])
    {
        //EndWaiting[Module_Heaters] = ModuleWaiting;
        //heaters preparation starts on process parameters handling
        // do not call HeatersEnd(); because the heaters should stay ready for coming jobs
    }*/
    if (Configured[Module_Thread])
    {
        PrepareWaiting[Module_Thread] = ModuleIdle;
        SegmentWaiting[Module_Thread] = ModuleIdle;
        PreSegmentWaiting[Module_Thread] = ModuleIdle;
        DistanceToSpoolWaiting[Module_Thread] = ModuleIdle;
        //EndWaiting[Module_Thread] = ModuleWaiting;
        ThreadEndState(CurrentJob);
    }
    //ROM_IntMasterEnable();
    SendJobProgress(0.0,0,true,Message);

    JobMessageStruc JobMessage;

    JobMessage.messageId = PrintingResultsOk;
    JobMessage.msglen = MAX_MSG_LEN;
    if (JobmsgQ != NULL)
        Mailbox_post(JobmsgQ , &JobMessage, BIOS_NO_WAIT);

    return OK;
}
//********************************************************************************************************************
static uint32_t ExitState(void *JobDetails)
{
    return OK;
}

//********************************************************************************************************************

/*void PrintingsInit(void)
{
}
*/
//********************************************************************************************************************

void StartPrinting(void)
{
}

//********************************************************************************************************************
//********************************************************************************************************************

void StopPrinting(void)
{
}
void PrintSTMMsgHandler(void * msg)
{
    JobMessageStruc *Message = msg;
    PrintMessageStruc *PrtMessage = (PrintMessageStruc *)Message->messageData;

    Report("PrintSTMMsgHandler",__FILE__,__LINE__, RpMessage,0x1000,Message->messageId,PrtMessage->messageId);

    if ((Message->messageId != PrintMessage)&&(Message->messageId != Abort))
    {
        //REPORT_ERR ...
        return;
    }
    static int SegmentId = 0;
    switch(PrtMessage->messageId)
    {
        case PrintRequest:
            SegmentId = 0;
            PreSegmentState(CurrentJob,SegmentId);
            break;
        case PreSegmentResultsOk:
            SegmentState(CurrentJob,SegmentId);
            break;
        case PreSegmentResultsFail:
            ExitState(Message->messageData);
            break;
        case SegmentResultsOk:
            SegmentId++;
            if (SegmentId >= CurrentJob->n_segments)
                {
                  if (dryerbufferlength == 0)
                    EndState(CurrentJob, "Job Ended");
                  else
                      DistanceToSpoolState(CurrentJob);
                }
            else
            {
                PreSegmentState(CurrentJob,SegmentId);
            }
            break;
        case SegmentResultsFail:
            EndState(CurrentJob, "Segment Failed");
            break;
        case FinishResultsOk:
            EndState(CurrentJob, "Job Ended");
            break;
        case FinishResultsFail:
            EndState(CurrentJob, "Job Distance t Spool Failed");
            break;
        case PrintSystemFailure:
            EndState(CurrentJob, Message->messageData);
            break;
        default:
            break;
    }



}