aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/PPC/Tango.PPC.Common/Notifications/ItemBase.cs
blob: 41bfb8e4d5c9e4fc7745c6505a7b613ce6320eea (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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Tango.Core;
using Tango.Core.Commands;

namespace Tango.PPC.Common.Notifications
{
    /// <summary>
    /// Represents a base notification item class.
    /// </summary>
    /// <seealso cref="Tango.Core.ExtendedObject" />
    /// <seealso cref="System.IDisposable" />
    public abstract class ItemBase : ExtendedObject, IDisposable
    {
        /// <summary>
        /// Occurs when the item has been closed.
        /// </summary>
        public event EventHandler Closed;

        /// <summary>
        /// Occurs when the item has been pressed.
        /// </summary>
        public event EventHandler Pressed;

        /// <summary>
        /// Gets or sets the remove action.
        /// </summary>
        internal Action RemoveAction { get; set; }

        /// <summary>
        /// Gets or sets the view type.
        /// </summary>
        public abstract Type ViewType { get; }

        /// <summary>
        /// Gets or sets the close command.
        /// </summary>
        public RelayCommand CloseCommand { get; set; }

        /// <summary>
        /// Gets or sets the pressed command.
        /// </summary
        public RelayCommand PressedCommand { get; set; }

        /// <summary>
        /// Initializes a new instance of the <see cref="ItemBase"/> class.
        /// </summary>
        public ItemBase()
        {
            CloseCommand = new RelayCommand(Close);
            PressedCommand = new RelayCommand(OnPreesed);
        }

        /// <summary>
        /// Called when the item has been pressed.
        /// </summary>
        protected virtual void OnPreesed()
        {
            Pressed?.Invoke(this, new EventArgs());
        }

        /// <summary>
        /// Called after the close command has been raised.
        /// </summary>
        public virtual void Close()
        {
            RemoveAction?.Invoke();
            Closed?.Invoke(this, new EventArgs());
        }

        /// <summary>
        /// Disposes the item.
        /// </summary>
        public void Dispose()
        {
            Close();
        }
    }
}
lor: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
/************************************************************************************************************************
 * 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
 **************************************************************************************************************************/

////////////////////////////////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 <Container.h>
#include <DataDef.h>
#include "include.h"
#include <ti/sysbios/knl/mailbox.h>
#include <ti/sysbios/knl/Clock.h>
#include <ti/sysbios/knl/task.h>

#include "PMR/Printing/JobSegment.pb-c.h"
#include "PMR/Printing/JobRequest.pb-c.h"
#include "PMR/Hardware/Hardwaremotor.pb-c.h"
#include "PMR/Hardware/HardwareWinder.pb-c.h"
#include "PMR/common/MessageContainer.pb-c.h"
#include "Modules/General/process.h"

#include "./printingSTM.h"
#include "modules/thread/thread_ex.h"
#include "modules/ids/ids_ex.h"


#define INVALID_MSG_ID    0xFFFF

Mailbox_Handle JobmsgQ = NULL;

static Clock_Handle JobClock;
static Clock_Params jobclkParams;

char JobDetails[MAX_MSG_LEN];

#define MAX_TICKET_SIZE  10000
SegmentGradientStruc SegmentGradient;
char CurrentJobBuffer[MAX_TICKET_SIZE];
JobTicket *CurrentJob = (JobTicket *)CurrentJobBuffer;
char PreviousJobBuffer[MAX_TICKET_SIZE];
JobTicket *PreviousJob = (JobTicket *)PreviousJobBuffer;




ModuleStateEnum PrepareWaiting[MAX_SYSTEM_MODULES] = {ModuleIdle};

/********************************************************************************************
* functions describes motor operation flow and movement state during profile execution
* used to operate in runtime correct profileflow execution
*********************************************************************************************/
static ReturnCode IdleState(void *JobDetails);
static ReturnCode ValidateState(void *JobDetails);
static ReturnCode PrepareState(void *JobDetails);
static ReturnCode PrintState(void *JobDetails);
static ReturnCode CleanState(void *JobDetails);
static ReturnCode ExitState(void *JobDetails);
/**********************************************************************
* the array and enum of JobState_t below must be in sync order
***********************************************************************/
//static ReturnCode (* state[])(void *JobDetails) = { IdleState, ValidateState, PrepareState,  PrintState, CleanState};


typedef enum
{
    Idle= 0,
	Validate,
	PrepareJob,
	Print,
	Clean,
	ExitJob
} JobState_t;

typedef struct
{
    JobState_t	m_sourceState;
    ReturnCode   		m_returnCode;
    JobState_t 	m_destinationState;
} Transition_t;


////////////////////////Slow Motor State////////////////////////////////////
char JobToken[36];

////////////////////////////////////////////////////////////////////////////
void StartJob(void *JobDetails);


//********************************************************************************************************************
/********************************************************************************************************************
*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 IdleState(void *JobDetails)
{
    ReturnCode retcode;
    retcode = JobSuccess;

    return retcode;
}
//********************************************************************************************************************
static ReturnCode ValidateState(void *JobDetails)
{
    ReturnCode retcode;
    retcode = JobSuccess;

    return retcode;
}

//********************************************************************************************************************
static ReturnCode PrepareState(void *JobDetails)
{
    ReturnCode retcode;
    retcode = JobSuccess;
    //start (fast??) heating
    //wait for fast heating to end
    //start other peripheral systems: chiller, waist handling
    //check thread type
    //prepare winder
    PrepareWaiting[Module_Heaters] = ModuleWaiting;
    PrepareWaiting[Module_Winder] = ModuleWaiting;
    PrepareWaiting[Module_Thread] = ModuleWaiting;
    ThreadPrepareState(&CurrentJob);
    PrepareWaiting[Module_IDS] = ModuleWaiting;
    IDSPrepareState(JobDetails);

/*
 * typedef enum
{
    ModuleIdle = 0,
    ModuleWaiting,
    ModuleDone,
    ModuleFail
} ModuleStateEnum;

ModuleStateEnum PrepareWaiting[MAX_SYSTEM_MODULES] = {ModuleIdle};
 * typedef enum
{
    Module_Thread,
    Module_Winder,
    Module_IDS,
    Module_Heaters,
    Module_Waste,
    MAX_SYSTEM_MODULES
}SYSTEM_MODULE_ID_ENUM;
 *
 */
	return retcode;
}
//********************************************************************************************************************
uint32_t PrepareReady(int ModuleId, ModuleStateEnum result)
{
    int i;
    bool ready = true;
    uint32_t retcode = 0,status = OK;

    JobMessageStruc Message;

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


    PrepareWaiting[ModuleId] = result;
    if (result == ModuleFail) status = ERROR;
    for (i=0;i<MAX_SYSTEM_MODULES ;i++)
    {
        if (PrepareWaiting[i] == ModuleWaiting)
            ready = false;
    }
    if (ready == false) return OK;
    else
    {
        if (status == OK)    Message.messageId = PreparationResultsOk;
        else Message.messageId = PreparationResultsFail;
        //memcpy(Message.messageData,JobDetails,MAX_MSG_LEN);
        Message.msglen = 10;
        if (JobmsgQ != NULL)
            retcode = Mailbox_post(JobmsgQ , &Message, BIOS_NO_WAIT);
    }
/*
 * typedef enum
{
    ModuleIdle = 0,
    ModuleWaiting,
    ModuleDone,
    ModuleFail
} ModuleStateEnum;

ModuleStateEnum PrepareWaiting[MAX_SYSTEM_MODULES] = {ModuleIdle};
 * typedef enum
{
    Module_Thread,
    Module_Winder,
    Module_IDS,
    Module_Heaters,
    Module_Waste,
    MAX_SYSTEM_MODULES
}SYSTEM_MODULE_ID_ENUM;
 *
 */
    return retcode;
}

//********************************************************************************************************************
static ReturnCode PrintState(void *JobDetails)
{
    ReturnCode retcode;
    retcode = JobSuccess;

    return retcode;
}

//********************************************************************************************************************
static ReturnCode CleanState(void *JobDetails)
{
    ReturnCode retcode;
    retcode = JobSuccess;

    return retcode;
}
//********************************************************************************************************************
static ReturnCode ExitState(void *JobDetails)
{
    ReturnCode retcode;
    retcode = JobStop;

    return retcode;
}

static void JobClockHandle(UArg arg0)
{
    //Clock_setTimeout(JobClock, 1000);
    //Clock_start(JobClock);

}

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

void JobInit(void)
{
    JobmsgQ = Mailbox_create(MAX_MSG_LEN, 20, NULL,NULL);
    Clock_Params_init(&jobclkParams);
    jobclkParams.period = 0;
    jobclkParams.startFlag = FALSE;
    JobClock = Clock_create(JobClockHandle, 0, &jobclkParams, NULL);
    return ;
}
//********************************************************************************************************************
//********************************************************************************************************************
void JobRequestFunc(MessageContainer* requestContainer)
{
    uint32_t status = NOT_SUPPORTED;
    MessageContainer responseContainer;
    uint8_t* container_buffer;


    JobRequest* request = job_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data);

    strcpy (JobToken, requestContainer->token);
    JobTicket *Ticket = request->jobticket;
    int TicketSize = job_ticket__get_packed_size(Ticket);
    if (TicketSize >= MAX_TICKET_SIZE)
    {
        LOG_ERROR (TicketSize, "job ticket message too long");
        status = FAILED;
    }
    else
    {
        memcpy(CurrentJob, Ticket,TicketSize);
        status  = PASSED;
        status += HandleProcessParameters(Ticket->processparameters);
        PrepareWaiting[Module_Heaters] = ModuleWaiting;
    }
    if (status == PASSED)
    {
        StartJob(&CurrentJob);
    }

    JobResponse response = JOB_RESPONSE__INIT;
    if (status == PASSED)
    {

        responseContainer = createContainer(MESSAGE_TYPE__JobResponse, JobToken, false, &response, &job_response__pack, &job_response__get_packed_size);
        container_buffer = malloc(message_container__get_packed_size(&responseContainer));

        strcpy (response.status->message,"Job Accepted");
        response.status->has_progress = true;
        response.status->progress = 0.0;
        response.status->has_currentsegmentindex = false;
    }
    else
    {

        responseContainer = createContainer(MESSAGE_TYPE__JobResponse, JobToken, true, &response, &job_response__pack, &job_response__get_packed_size);
        container_buffer = malloc(message_container__get_packed_size(&responseContainer));
        responseContainer.has_error = true;
        responseContainer.error = ERROR_CODE__BAD_CRC;

        strcpy (response.status->message,"Job message too large");
        response.status->has_progress = true;
        response.status->progress = 0.0;
        response.status->has_currentsegmentindex = false;
    }

    size_t container_size = message_container__pack(&responseContainer, container_buffer);
    free(responseContainer.data.data);
    SendChars((char*)container_buffer, container_size);
    job_request__free_unpacked(request,NULL);

    //free(container_buffer);
    //free(requestContainer);
}

void StartJob(void *JobDetails)
{
    JobMessageStruc Message;
    bool retcode = false;

    Message.messageId = JobRequestMsg;
    memcpy(Message.messageData,JobDetails,MAX_MSG_LEN);
    Message.msglen = MAX_MSG_LEN;
    if (JobmsgQ != NULL)
        retcode = Mailbox_post(JobmsgQ , &Message, BIOS_NO_WAIT);
}

/******************************************************************************
 *  ======== messageTsk ========
 *  Task for this function is created statically. See the project's .cfg file.
 *  this message task is created statically in system initialization,
 ******************************************************************************/
Void jobTask(UArg arg0, UArg arg1)
{
    JobMessageStruc Message;
    //char str[60];
    //uint16_t length;
    //Clock_setTimeout(HostKAClock, 1000);
    //Clock_start(HostKAClock);


    while(1)
    {
        Mailbox_pend(JobmsgQ , &Message, BIOS_WAIT_FOREVER);
        switch (Message.messageId)
        {
            case JobRequestMsg:
                memcpy(JobDetails,Message.messageData, Message.msglen);
                /*ValidateState (&JobDetails);
                break;
            case ValidationResultsOk:*/
                PrepareState (&JobDetails);
                break;
            case ValidationResultsFail:
                //send message data as a validation error message to host
                ExitState(Message.messageData);
                break;
            case PreparationResultsOk:
                PrintState(&JobDetails);
                break;
            case PreparationResultsFail:
                //send message data as a validation error message to host
                ExitState(Message.messageData);
                break;
            case PrintMessage:
                //send message data as a validation error message to host
                PrintSTMMsgHandler(&Message);
                break;
            case PrintingResultsOk:
                CleanState(&JobDetails);
                break;
            case PrintingResultsFail:
                //send message data as a validation error message to host
                ExitState(Message.messageData);
                break;
            case CleaningResultsOk:
                //send message data as a validation error message to host
                ExitState(Message.messageData);
                break;
            case CleaningResultsFail:
                //send message data as a validation error message to host
                ExitState(Message.messageData);
                break;
            case SystemFailure:
                //send message data as a validation error message to host
                ExitState(Message.messageData);
                break;
            default:
                break;
        }
    }
}