/************************************************************************************************************************ * Printing.c * High management 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 touches the limit switch (no matter whether its screw or dispenser) * an interrupt occurred 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 interrupt 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 different 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 received design flow of the user from the UI /////////////////////////////////////////////////////////////////////////////////////////// #include #include #include "include.h" //#include //#include //#include #include "Common/report/report.h" #include "PMR/Printing/JobSegment.pb-c.h" #include "PMR/Printing/JobRequest.pb-c.h" #include "PMR/Printing/JobResponse.pb-c.h" #include "PMR/Printing/CurrentJobRequest.pb-c.h" #include "PMR/Printing/CurrentJobResponse.pb-c.h" #include "PMR/Printing/ResumeCurrentJobRequest.pb-c.h" #include "PMR/Printing/ResumeCurrentJobResponse.pb-c.h" #include "PMR/Printing/StartHeadCleaningRequest.pb-c.h" #include "PMR/Printing/StartHeadCleaningResponse.pb-c.h" #include "PMR/Printing/AbortHeadCleaningRequest.pb-c.h" #include "PMR/Printing/AbortHeadCleaningResponse.pb-c.h" #include "PMR/Printing/JobUploadStrategy.pb-c.h" #include "PMR/Printing/JobStatus.pb-c.h" #include "PMR/Printing/AbortJobRequest.pb-c.h" #include "PMR/Printing/AbortJobResponse.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 "PMR/Diagnostics/EventType.pb-c.h" #include "PMR/MachineStatus/MachineStatus.pb-c.h" #include "Modules/General/MachineStatus.h" #include "Modules/General/process.h" #include "modules/Diagnostics/Diagnostics.h" #include "modules/waste/waste_ex.h" #include "PMR/Stubs/StubJobRequest.pb-c.h" #include "PMR/Stubs/StubJobResponse.pb-c.h" #include "PMR/Stubs/StubAbortJobRequest.pb-c.h" #include "PMR/Stubs/StubAbortJobResponse.pb-c.h" #include "PMR/Diagnostics/ThreadJoggingRequest.pb-c.h" #include "PMR/Diagnostics/ThreadJoggingResponse.pb-c.h" #include "PMR/Diagnostics/ThreadAbortJoggingRequest.pb-c.h" #include "PMR/Diagnostics/ThreadAbortJoggingResponse.pb-c.h" #include "StateMachines/Initialization/PowerIdle.h" #include "StateMachines/Initialization/InitSequence.h" #include "drivers/Motors/Motor.h" #include #include "drivers/FPGA/Full_Vme/FPGA_Programming_Up.h" #include "drivers/Heater/TemperatureSensor.h" #include "./printingSTM.h" #include "modules/thread/thread_ex.h" #include "modules/AlarmHandling/AlarmHandling.h" #include "modules/ids/ids_ex.h" #include "Modules/heaters/heaters_ex.h" #include "Modules/control/control.h" #include "drivers/Flash_ram/MCU_E2Prom.h" #define MAX_TICKET_SIZE 10000 Mailbox_Handle JobmsgQ = NULL; JobEndReasonEnum JobEndReason = JOB_OK; ErrorCode JobError_to_ErrorCode[JOB_ERRORS_MAX+1] = {ERROR_CODE__NONE,ERROR_CODE__JOB_UNSPECIFIED_ERROR,ERROR_CODE__JOB_THREAD_BREAK,ERROR_CODE__JOB_WINDER_DANCER_FAIL, ERROR_CODE__JOB_POOLER_DANCER_FAIL,ERROR_CODE__JOB_FEEDER_DANCER_FAIL,ERROR_CODE__JOB_OUT_OF_DYE,ERROR_CODE__JOB_OTHER_ALARM, ERROR_CODE__JOB_TEMPERATURE_ALARM,ERROR_CODE__JOB_LS_ALARM,ERROR_CODE__JOB_PRESSURE_ALARM,ERROR_CODE__JOB_CURRENT_ALARM, ERROR_CODE__JOB_MOTOR_ALARM,ERROR_CODE__JOB_LIDS_OPEN,ERROR_CODE__JOB_LIDS_OPEN,ERROR_CODE__JOB_ABORTED_BY_USER,ERROR_CODE__JOB_SAFETY_ALARM, ERROR_CODE__JOB_NO_ALARM_FILE, ERROR_CODE__JOB_FILE_PROBLEM,ERROR_CODE__JOB_WASTE_HANDLING_PROBLEM}; JobTicket *CurrentJob = NULL; JobRequest *CurrentRequest = NULL; double previousJobLength; uint32_t StubControlId = 0xFF; double StubLengthCounter = 0,StubLength = 0,StubSpeed=0; JobTicket Ticket; JobSegment *TSegment; JobBrushStop *TbrushStop; JobDispenser *Tdispenser; JobSpool *Tspool; HeadCleaningParameters *CleaningParameters = NULL; BTSRParameters *BtsrPrameters = NULL; bool CopyConfigured[MAX_SYSTEM_MODULES]; bool CleaningJobActive = false, JoggingJobActive = false; char ErrorMsg[100]; uint32_t JobEndTimeMillisec = 0; ModuleStateEnum PrepareWaiting[MAX_SYSTEM_MODULES] = {ModuleIdle,ModuleIdle,ModuleIdle,ModuleIdle,ModuleIdle}; double job_length = 0.0; char infomsg[190]; bool prepare_state = false; /******************************************************************************************** * 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}; void AbortJob(char *Msg); void HandleJobEnd(JobEndReasonEnum JobEndReason); 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//////////////////////////////////// bool JobActive = false; bool JobResumed = false; char JobToken[36+1]={0}; bool JobAbortedByUser = false; ThreadParameters SavedThreadParameters; //////////////////////////////////////////////////////////////////////////// void StartJob(void *JobDetails); //******************************************************************************************************************** bool JobIsActive(void) { return JobActive; } /******************************************************************************************************************** *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; }*/ ErrorCode getJobError_to_ErrorCode(JobEndReasonEnum JobError) { if (JobErrormessageId = PrintRequest; Message.msglen = 10; if (JobmsgQ != NULL) Mailbox_post(JobmsgQ , &Message, BIOS_NO_WAIT); 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) { Clock_Params_init(&jobclkParams); jobclkParams.period = 0; jobclkParams.startFlag = FALSE; JobClock = Clock_create(JobClockHandle, 0, &jobclkParams, NULL); return ; }*/ //******************************************************************************************************************** void JobAbortFunc(MessageContainer* requestContainer) { MessageContainer responseContainer; uint8_t* container_buffer; AbortJobRequest* request = abort_job_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data); //AbortJob(); AbortJobResponse response = ABORT_JOB_RESPONSE__INIT; responseContainer = createContainer(MESSAGE_TYPE__AbortJobResponse, requestContainer->token, false, &response, &abort_job_response__pack, &abort_job_response__get_packed_size); container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); size_t container_size = message_container__pack(&responseContainer, container_buffer); my_free(responseContainer.data.data); SendChars((char*)container_buffer, container_size); abort_job_request__free_unpacked(request,NULL); JobEndReason = JOB_ABORTED_BY_USER; JobAbortedByUser = true; AbortJob("Job Aborted by user"); //We keep the job request until it is done } //******************************************************************************************************************** uint32_t ThreadJoggingFunc(int speed) { ProcessParameters ProcessParametersCopy; uint32_t status = OK; // JobEndTimeMillisec = msec_millisecondCounter; if (JobIsActive() == true) { Report("cannot jog while JobIsActive", __FILE__, __LINE__, JobIsActive(), RpWarning, JoggingJobActive, 0); return ERROR; } if (JoggingJobActive == true) { Report("cannot jog while JoggingJobActive", __FILE__, __LINE__, JoggingJobActive, RpWarning, JoggingJobActive, 0); return ERROR; } if (MachineReadyForHeating == false) { Report("cannot jog while Machine not ReadyForHeating", __FILE__, __LINE__, MachineReadyForHeating, RpWarning, JoggingJobActive, 0); return ERROR; } if (FPGABurningActive==true) { Report("cannot jog while FPGABurningActive", __FILE__, __LINE__, FPGABurningActive, RpWarning, JoggingJobActive, 0); return ERROR; } if ((msec_millisecondCounter - JobEndTimeMillisec) <2000) { Report("cannot jog while Job Is ending", __FILE__, __LINE__, msec_millisecondCounter, RpWarning, JobEndTimeMillisec, 0); return ERROR; } //memcpy(&CopyConfigured,&Configured,sizeof(CopyConfigured)); //usnprintf(ErrorMsg, 80,"Copy Configured T %d W %d I %d H %d W %d",CopyConfigured[Module_Thread],CopyConfigured[Module_Winder],CopyConfigured[Module_IDS],CopyConfigured[Module_Heaters],CopyConfigured[Module_Waste]); //Report(ErrorMsg, __FILE__, __LINE__, 0, RpWarning, 0, 0); //set the job handler to ignore heaters, ids and waste in the state machine Configured[Module_Thread] = true; Configured[Module_Winder] = true; Configured[Module_IDS] = false; Configured[Module_Heaters] = false; Configured[Module_Waste] = false; //set the requested speed without changing other process parameters memcpy (&ProcessParametersCopy,&ProcessParametersKeep,sizeof(ProcessParameters)); if(speed) ProcessParametersCopy.dyeingspeed = speed; else ProcessParametersCopy.dyeingspeed = 40; if (HandleProcessParameters(&ProcessParametersCopy,false)!= OK) { Report("Process parameters handling failed", __FILE__, __LINE__, 0, RpWarning, 0, 0); status = FAILED; } else { //load essential job prameters to enable thread running Ticket.n_segments = 1; n_segments = 1; Ticket.segments = my_malloc(sizeof(Ticket.segments)); TSegment = my_malloc(sizeof(JobSegment)); Tspool = my_malloc(sizeof(JobSpool)); TSegment->length = 200.0; TSegment->n_brushstops = 0; Ticket.segments[0] = TSegment; if (InternalWinderCfg.spoolbackingrate) Tspool->backingrate = InternalWinderCfg.spoolbackingrate; else Tspool->backingrate = 32; if (InternalWinderCfg.SpoolBottomBackingRate) Tspool->bottombackingrate = InternalWinderCfg.SpoolBottomBackingRate; else Tspool->bottombackingrate = 32; if (InternalWinderCfg.segmentoffsetpulses) Tspool->segmentoffsetpulses = InternalWinderCfg.segmentoffsetpulses; else Tspool->segmentoffsetpulses = 1000; if (InternalWinderCfg.startoffsetpulses) Tspool->startoffsetpulses = InternalWinderCfg.startoffsetpulses; else Tspool->startoffsetpulses = 220; if (InternalWinderCfg.NumberOfRotationPerPassage) Tspool->rotationsperpassage = InternalWinderCfg.NumberOfRotationPerPassage; else Tspool->rotationsperpassage = 3.1415926*3; Tspool->has_limitswitchstartpointoffset = false; Ticket.spool = Tspool; Ticket.threadparameters = &SavedThreadParameters; #ifdef UFEEDER_BTSR BtsrReadParamsFromEeprom(Ticket.btsrparameters); #endif CurrentJob = &Ticket; InternalWindingConfigMessage(Tspool); JoggingJobActive = true; StartJob(&Ticket); } return status; } //******************************************************************************************************************** uint32_t ThreadCleaningJobFunc(MessageContainer* requestContainer) { MessageContainer responseContainer; uint8_t* container_buffer; uint32_t status = OK; StartHeadCleaningRequest *request = start_head_cleaning_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data); if (request) { if (JobIsActive() == true) { status = ERROR; LOG_ERROR(JobIsActive(),"Jog JobIsActive"); } else { if (dyeingspeed<10) status = ERROR; else { status = ThreadCleaningJob(dyeingspeed); if (status == OK) { ustrncpy (JobToken, requestContainer->token,36); previousJobLength = 0.0; } } } } StartHeadCleaningResponse response = START_HEAD_CLEANING_RESPONSE__INIT; if (status == PASSED) { usnprintf(ErrorMsg, 100, "Cleaning Job Accepted"); responseContainer = createContainer(MESSAGE_TYPE__StartHeadCleaningResponse, JobToken, false, &response, &start_head_cleaning_response__pack, &start_head_cleaning_response__get_packed_size); responseContainer.has_continuous = true; responseContainer.continuous = true; container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); } else { usnprintf(ErrorMsg, 100, "Cleaning Job Failed"); responseContainer = createContainer(MESSAGE_TYPE__StartHeadCleaningResponse, JobToken, true, &response, &start_head_cleaning_response__pack, &start_head_cleaning_response__get_packed_size); responseContainer.has_error = true; responseContainer.error = ERROR_CODE__INVALID_PARAMETER; container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); } response.status = ErrorMsg; response.has_progress = true; response.progress = 0.0; response.has_total = true; response.total = job_length; container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); start_head_cleaning_request__free_unpacked(request,NULL); if (container_buffer) { size_t container_size = message_container__pack(&responseContainer, container_buffer); my_free(responseContainer.data.data); SendChars((char*)container_buffer, container_size); //We keep the job request until it is done // job_request__free_unpacked(request,NULL); } return status; } uint32_t ThreadCleaningAbortJobFunc(MessageContainer* requestContainer) { MessageContainer responseContainer; uint8_t* container_buffer; AbortHeadCleaningResponse response = ABORT_HEAD_CLEANING_RESPONSE__INIT; responseContainer = createContainer(MESSAGE_TYPE__AbortHeadCleaningResponse, requestContainer->token, false, &response, &abort_head_cleaning_response__pack, &abort_head_cleaning_response__get_packed_size); container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); size_t container_size = message_container__pack(&responseContainer, container_buffer); my_free(responseContainer.data.data); SendChars((char*)container_buffer, container_size); JobEndReason = JOB_ABORTED_BY_USER; JobAbortedByUser = true; AbortJob("Job Aborted by user"); //We keep the job request until it is done return OK; } uint32_t ThreadCleaningJob(int speed) { ProcessParameters ProcessParametersCopy; JobEndReasonEnum JobAlarmReason = JOB_OK; uint32_t status = OK; if (JobIsActive() == true) { status = ERROR; LOG_ERROR(JobIsActive(),"Jog JobIsActive"); } else { if (isMotorConfigured(CLEANER_DISPENSER + HARDWARE_MOTOR_TYPE__MOTO_DISPENSER_1)==false) { status = ERROR; LOG_ERROR(JobIsActive(),"Jog No cleaner dispenser"); } else if ((ProcessParametersKeep.dryerzone1temp == 0)||((ProcessParametersKeep.headzone1temp == 0)&&(ProcessParametersKeep.headzone2temp == 0)&&(ProcessParametersKeep.headzone3temp == 0))) { status = ERROR; usnprintf(ErrorMsg, 80,"Cleaning job Heaters are off D %d H1 %d H2 %d H3 %d M %d", (int)ProcessParametersKeep.dryerzone1temp,(int)ProcessParametersKeep.headzone1temp,(int)ProcessParametersKeep.headzone2temp, (int)ProcessParametersKeep.headzone3temp,(int)ProcessParametersKeep.mixertemp); Report(ErrorMsg, __FILE__, __LINE__, 0, RpWarning, 0, 0); } else { //memcpy(&CopyConfigured,&Configured,sizeof(CopyConfigured)); //usnprintf(ErrorMsg, 80,"Copy Configured T %d W %d I %d H %d W %d",CopyConfigured[Module_Thread],CopyConfigured[Module_Winder],CopyConfigured[Module_IDS],CopyConfigured[Module_Heaters],CopyConfigured[Module_Waste]); //Report(ErrorMsg, __FILE__, __LINE__, 0, RpWarning, 0, 0); //set the job handler to ignore heaters, ids and waste in the state machine Configured[Module_Thread] = true; Configured[Module_Winder] = true; Configured[Module_IDS] = true; Configured[Module_Heaters] = true; Configured[Module_Waste] = true; //set the requested speed without changing other process parameters memcpy (&ProcessParametersCopy,&ProcessParametersKeep,sizeof(ProcessParameters)); if(speed) ProcessParametersCopy.dyeingspeed = speed; else ProcessParametersCopy.dyeingspeed = 40; if (HandleProcessParameters(&ProcessParametersCopy,false)!= OK) { LOG_ERROR(FAILED,"Jog HandleProcessParameters"); status = FAILED; } else { //load essential job prameters to enable thread running Ticket.uploadstrategy = JOB_UPLOAD_STRATEGY__Default; Ticket.n_segments = 1; Ticket.enableintersegment = true; Ticket.intersegmentlength = 100; Ticket.length += Ticket.intersegmentlength; n_segments = 2; Ticket.segments = my_malloc(sizeof(Ticket.segments)*2); TSegment = my_malloc(sizeof(JobSegment)); Tspool = my_malloc(sizeof(JobSpool)); TbrushStop = my_malloc(sizeof(JobBrushStop)); Ticket.headcleaningparameters = CleaningParameters; if (Ticket.headcleaningparameters) Report("Clean job cleaning parameters", __FILE__, __LINE__, Ticket.headcleaningparameters->cleanerflow, RpWarning, Ticket.headcleaningparameters->archeadcleaningmotorspeed, 0); TSegment->length = 10.0; Ticket.length += (TSegment->length*n_segments); TSegment->n_brushstops = 1; TSegment->brushstops = my_malloc(sizeof(TSegment->brushstops)); TSegment->brushstops[0] = TbrushStop; Tdispenser = my_malloc(sizeof(JobDispenser)); TbrushStop->has_index =true; TbrushStop->index = 0; TbrushStop->n_dispensers = 1; TbrushStop->dispensers = my_malloc(sizeof(TbrushStop->dispensers)); TbrushStop->dispensers[0] = Tdispenser; Tdispenser->nanolitterpersecond = 10000; Tdispenser->nanoliterperpulse = 2.34; Tdispenser->dispenserstepdivision = DISPENSER_STEP_DIVISION__Auto; Tdispenser->index = 4; //TI dispenser Ticket.segments[0] = TSegment; Ticket.segments[1] = TSegment; if (InternalWinderCfg.spoolbackingrate) Tspool->backingrate = InternalWinderCfg.spoolbackingrate; else Tspool->backingrate = 32; if (InternalWinderCfg.SpoolBottomBackingRate) Tspool->bottombackingrate = InternalWinderCfg.SpoolBottomBackingRate; else Tspool->bottombackingrate = 32; if (InternalWinderCfg.segmentoffsetpulses) Tspool->segmentoffsetpulses = InternalWinderCfg.segmentoffsetpulses; else Tspool->segmentoffsetpulses = 1000; if (InternalWinderCfg.startoffsetpulses) Tspool->startoffsetpulses = InternalWinderCfg.startoffsetpulses; else Tspool->startoffsetpulses = 220; if (InternalWinderCfg.NumberOfRotationPerPassage) Tspool->rotationsperpassage = InternalWinderCfg.NumberOfRotationPerPassage; else Tspool->rotationsperpassage = 3.1415926*3; Tspool->has_limitswitchstartpointoffset = false; Tspool->has_limitswitchstartpointoffset = false; Ticket.spool = Tspool; Ticket.threadparameters = &SavedThreadParameters; #ifdef UFEEDER_BTSR BtsrReadParamsFromEeprom(Ticket.btsrparameters); #endif CurrentJob = &Ticket; job_length = CurrentJob->length + dryerbufferMeters; JobAlarmReason = JOB_OK; JobAlarmReason = AlarmHandlingPrepareJob(CurrentJob); if (JobAlarmReason !=JOB_OK) { LOG_ERROR(JobAlarmReason,"Jog JobAlarmReason"); return ERROR; } InternalWindingConfigMessage(Tspool); CleaningJobActive = true; StartJob(&Ticket); } } } return status; } void FreeCleaningJobData(void *JobDetails) { JobTicket* JobTicket = JobDetails; //if (JobTicket->headcleaningparameters) // free (JobTicket->headcleaningparameters); if (JobTicket->spool) { free (JobTicket->spool); } if (JobTicket->segments[0]->brushstops[0]->n_dispensers) { if (JobTicket->segments[0]->brushstops[0]->dispensers[0]); free (JobTicket->segments[0]->brushstops[0]->dispensers[0]); if (JobTicket->segments[0]->brushstops[0]->dispensers); free (JobTicket->segments[0]->brushstops[0]->dispensers); } if (JobTicket->segments[0]->n_brushstops) { if (JobTicket->segments[0]->brushstops[0]); free (JobTicket->segments[0]->brushstops[0]); if (JobTicket->segments[0]->brushstops); free (JobTicket->segments[0]->brushstops); } if (JobTicket->segments[0]) free (JobTicket->segments[0]); if (JobTicket->segments) free (JobTicket->segments); } void ThreadJoggingRequestFunc(MessageContainer* requestContainer) { uint32_t status = OK; MessageContainer responseContainer; ThreadJoggingRequest* request = thread_jogging_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data); ThreadJoggingResponse response = THREAD_JOGGING_RESPONSE__INIT; status = ThreadJoggingFunc(request->speed); responseContainer = createContainer(MESSAGE_TYPE__ThreadJoggingResponse, requestContainer->token, true, &response, &thread_jogging_response__pack, &thread_jogging_response__get_packed_size); if (status!= OK) { responseContainer.has_error = true; responseContainer.error = ERROR_CODE__INVALID_PARAMETER; responseContainer.errormessage = "JOb Active or incorrect parameters"; } // responseContainer.continuous = false; uint8_t* container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); size_t container_size = message_container__pack(&responseContainer, container_buffer); SendChars(container_buffer, container_size); my_free(responseContainer.data.data); return ; } void ThreadAbortJoggingFunc(void) { if (JobIsActive() == true) { AbortJob(0); //set the job handler to handle heaters, ids and waste in the state machine Task_sleep(100); //let the job end procedure role before returning the configuration to normal. //usnprintf(ErrorMsg, 80,"Copy Configured T %d W %d I %d H %d W %d",CopyConfigured[Module_Thread],CopyConfigured[Module_Winder],CopyConfigured[Module_IDS],CopyConfigured[Module_Heaters],CopyConfigured[Module_Waste]); //Report(ErrorMsg, __FILE__, __LINE__, 0, RpWarning, 0, 0); my_free(Ticket.segments); my_free(TSegment); my_free(Tspool); } } void ThreadAbortJoggingRequestFunc(MessageContainer* requestContainer) { //uint32_t status = OK; MessageContainer responseContainer; ThreadAbortJoggingRequest* request = thread_abort_jogging_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data); ThreadAbortJoggingResponse response = THREAD_ABORT_JOGGING_RESPONSE__INIT; ThreadAbortJoggingFunc(); responseContainer = createContainer(MESSAGE_TYPE__ThreadAbortJoggingResponse, requestContainer->token, false, &response, &thread_abort_jogging_response__pack, &thread_abort_jogging_response__get_packed_size); responseContainer.continuous = false; uint8_t* container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); if (container_buffer) { size_t container_size = message_container__pack(&responseContainer, container_buffer); SendChars(container_buffer, container_size); } if (responseContainer.data.data) my_free(responseContainer.data.data); return ; } //******************************************************************************************************************** uint32_t SendStubJobProgress(uint32_t IfIndex, uint32_t readValue) { MessageContainer responseContainer; uint8_t* container_buffer; bool done = false; // //REPORT_MSG(msdid++,logmsg); Report("Stub Job",__FILE__,__LINE__,StubLengthCounter,RpWarning,StubLength, StubSpeed); if (JobToken[0] == 0) return OK; StubJobResponse response = STUB_JOB_RESPONSE__INIT; JobStatus jobStatus = JOB_STATUS__INIT; jobStatus.has_progress = true; jobStatus.progress = StubLengthCounter/100; StubLengthCounter += StubSpeed; if (StubLengthCounter>=StubLength) { done = true; RemoveControlCallback(StubControlId, SendStubJobProgress); } jobStatus.has_currentsegmentindex = true; jobStatus.currentsegmentindex = 0; response.status = &jobStatus; responseContainer = createContainer(MESSAGE_TYPE__StubJobResponse, JobToken, done, &response, &stub_job_response__pack, &stub_job_response__get_packed_size); container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); if (container_buffer) { size_t container_size = message_container__pack(&responseContainer, container_buffer); SendChars(container_buffer, container_size); } if (responseContainer.data.data) my_free(responseContainer.data.data); return OK; } void Stub_JobRequest(MessageContainer* requestContainer) { uint32_t status = OK; MessageContainer responseContainer; StubJobRequest* request = stub_job_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data); JobTicket *Ticket = request->jobticket; StubJobResponse response = STUB_JOB_RESPONSE__INIT; JobStatus jobStatus = JOB_STATUS__INIT; StubSpeed = Ticket->processparameters->dyeingspeed; StubLength = Ticket->length*100; StubLengthCounter = 0; ustrncpy (JobToken, requestContainer->token,36); StubControlId = AddControlCallback(NULL, SendStubJobProgress, eOneSecond,TemplateDataReadCBFunction,0,0,0); jobStatus.has_progress = true; jobStatus.progress = 0.0; jobStatus.has_currentsegmentindex = false; response.status = &jobStatus; responseContainer = createContainer(MESSAGE_TYPE__StubJobResponse, JobToken, false, &response, &stub_job_response__pack, &stub_job_response__get_packed_size); if (status!= OK) { responseContainer.has_error = true; responseContainer.error = ERROR_CODE__INVALID_PROCESS_ID; responseContainer.errormessage = "JOb Active or incorrect parameters"; } // responseContainer.continuous = false; uint8_t* container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); if (container_buffer) { size_t container_size = message_container__pack(&responseContainer, container_buffer); SendChars(container_buffer, container_size); } if (responseContainer.data.data) my_free(responseContainer.data.data); return ; } void Stub_AbortJobRequest(MessageContainer* requestContainer) { //uint32_t status = OK; MessageContainer responseContainer; StubAbortJobRequest* request = stub_abort_job_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data); StubAbortJobResponse response = STUB_ABORT_JOB_RESPONSE__INIT; //RemoveControlCallback(StubControlId, SendStubJobProgress); StubLength = 0; StubLengthCounter = 10; //trigger job end message; responseContainer = createContainer(MESSAGE_TYPE__StubAbortJobResponse, requestContainer->token, false, &response, &stub_abort_job_response__pack, &stub_abort_job_response__get_packed_size); responseContainer.continuous = false; uint8_t* container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); if (container_buffer) { size_t container_size = message_container__pack(&responseContainer, container_buffer); SendChars(container_buffer, container_size); } if (responseContainer.data.data) my_free(responseContainer.data.data); return ; } //******************************************************************************************************************** void JobRequestFunc(MessageContainer* requestContainer) { uint32_t rc, status = NOT_SUPPORTED; MessageContainer responseContainer; uint8_t* container_buffer; ErrorCode error = ERROR_CODE__NONE; JobEndReasonEnum JobAlarmReason = JOB_OK; if (JobActive == true) { LOG_ERROR(JobActive, "Job started while active"); status = FAILED; error = ERROR_CODE__NO_JOB_IN_PROGRESS; } else { JobRequest* request = job_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data); if (request != NULL) { ustrncpy (JobToken, requestContainer->token,36); previousJobLength = 0.0; 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; error = ERROR_CODE__BAD_CRC; usnprintf(ErrorMsg, 100, "job ticket message too long"); } else { //memcpy(CurrentJob, Ticket,TicketSize); CurrentJob = Ticket; // if (CurrentRequest!= NULL) // job_request__free_unpacked(CurrentRequest,NULL); CurrentRequest = request; n_segments = 0; if (CurrentJob->uploadstrategy == JOB_UPLOAD_STRATEGY__JobDescriptionFile) { LOG_ERROR(JobActive, "Job upload strategy file"); } else { n_segments = CurrentJob->n_segments; } JobResumed = false; status = PASSED; JobEndReason = JOB_OK; TotalProcessedLength = 0.0; PoolerTotalProcessedLength = 0.0; JobAlarmReason = JOB_OK; JobAlarmReason = AlarmHandlingPrepareJob(CurrentJob); if (JobAlarmReason ==OK) { n_unit_segments = n_segments; n_units = 1; if ((Ticket->has_numberofunits)&&(Ticket->numberofunits > 1)) { n_units = Ticket->numberofunits; } if (n_units>1) { n_segments = n_segments*n_units; } //#warning Process parameters in job request are not handled. push separately for now if (Ticket->processparameters) { if (HandleProcessParameters(Ticket->processparameters,true)!= OK) { status = FAILED; error = ERROR_CODE__INVALID_PARAMETER; usnprintf(ErrorMsg, 100, "Hardware Parameters Not Set"); if (GetMachineState()length + dryerbufferMeters; Report("job length ",__FILE__,job_length,(int)CurrentJob->length,RpWarning,(int)dryerbufferCentimeters, 0); if (Ticket->name) Report(Ticket->name,__FILE__,__LINE__,(int)Ticket->length,RpWarning,(int)Ticket->numberofunits, 0); if (Ticket->spool) { if (InternalWindingConfigMessage(Ticket->spool)!= OK) { status = FAILED; error = ERROR_CODE__INVALID_PARAMETER; usnprintf(ErrorMsg, 100, "spool parameters error"); } } if (Ticket->headcleaningparameters) { ///store last updated cleaning parameters if (CleaningParameters == NULL) CleaningParameters = my_malloc(sizeof(CleaningParameters)); CleaningParameters->has_cleanerflow = Ticket->headcleaningparameters->has_cleanerflow; CleaningParameters->cleanerflow = Ticket->headcleaningparameters->cleanerflow; CleaningParameters->has_archeadcleaningmotorspeed = Ticket->headcleaningparameters->has_archeadcleaningmotorspeed; CleaningParameters->archeadcleaningmotorspeed = Ticket->headcleaningparameters->archeadcleaningmotorspeed; Report("Save job cleaning parameters", __FILE__, __LINE__, CleaningParameters->cleanerflow, RpWarning, CleaningParameters->archeadcleaningmotorspeed, 0); } if (Ticket->btsrparameters) { ///store last updated BTSR parameters if (BtsrPrameters == NULL) BtsrPrameters = my_malloc(sizeof(BTSRParameters)); memcpy(BtsrPrameters, Ticket->btsrparameters, sizeof(BTSRParameters)); rc = BtsrSaveParamsToEeprom(BtsrPrameters); Report("Save job BTSR parameters", __FILE__, __LINE__, BtsrPrameters->feedingtension, RpWarning, rc, 0); } } else { status = FAILED; error = JobError_to_ErrorCode[JobAlarmReason]; if (strlen(AlarmReasonStr)) strncpy(ErrorMsg,AlarmReasonStr,100); } } if (status == PASSED) { Report("Job Request ",__FILE__,__LINE__,Ticket->processparameters->dyeingspeed,RpWarning,n_segments, Ticket->intersegmentlength); memcpy(&Configured,&JobConfigured,sizeof(JobConfigured)); if (Ticket->threadparameters) memcpy(&SavedThreadParameters,Ticket->threadparameters,sizeof(SavedThreadParameters)); else Report("Job Request empty thread parameters ",__FILE__,__LINE__,Ticket->processparameters->dyeingspeed,RpWarning,n_segments, Ticket->intersegmentlength); StartJob(CurrentJob); } } else { status = FAILED; error = ERROR_CODE__BAD_CRC; usnprintf(ErrorMsg, 100, "job ticket missing"); } } JobResponse response = JOB_RESPONSE__INIT; JobStatus jobStatus = JOB_STATUS__INIT; if (status == PASSED) { JobResumed = false; usnprintf(ErrorMsg, 100, "Job Accepted"); jobStatus.message =ErrorMsg; jobStatus.has_progress = true; jobStatus.progress = 0.0; jobStatus.has_currentsegmentindex = false; response.status = &jobStatus; response.has_canceled = false; responseContainer.has_continuous = true; responseContainer.continuous = true; responseContainer = createContainer(MESSAGE_TYPE__JobResponse, JobToken, false, &response, &job_response__pack, &job_response__get_packed_size); container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); } else { jobStatus.message = ErrorMsg; jobStatus.has_progress = true; jobStatus.progress = 0.0; jobStatus.has_currentsegmentindex = false; response.status = &jobStatus; response.has_canceled = true; response.canceled = true; responseContainer = createContainer(MESSAGE_TYPE__JobResponse, JobToken, true, &response, &job_response__pack, &job_response__get_packed_size); responseContainer.has_error = true; responseContainer.error = error; if (strlen(ErrorMsg)) responseContainer.errormessage = ErrorMsg; container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); } if (container_buffer) { size_t container_size = message_container__pack(&responseContainer, container_buffer); ErrorMsg[0] = 0; my_free(responseContainer.data.data); SendChars((char*)container_buffer, container_size); //We keep the job request until it is done // job_request__free_unpacked(request,NULL); } } //******************************************************************************************************************** uint8_t JobStatusBuffer[400]; ResumeCurrentJobResponse resumeresponse = RESUME_CURRENT_JOB_RESPONSE__INIT; JobResponse JobResponseMsg = JOB_RESPONSE__INIT; JobStatus jobStatus = JOB_STATUS__INIT; void SendCleaningJobProgress(double ProcessedLength, int SegmentId, bool done, char *Message) { StartHeadCleaningResponse response = START_HEAD_CLEANING_RESPONSE__INIT; MessageContainer responseContainer; uint8_t* container_buffer; double totlen = ProcessedLength; if (ProcessedLength>job_length) totlen = job_length; response.has_progress = true; response.progress = totlen; response.has_total = true; response.total = job_length; responseContainer = createContainer(MESSAGE_TYPE__StartHeadCleaningResponse, JobToken, done, &response, &start_head_cleaning_response__pack, &start_head_cleaning_response__get_packed_size); responseContainer.has_continuous = true; responseContainer.continuous = true; if (done == true) { if(JobEndReason != JOB_OK) { responseContainer.has_error = true; responseContainer.error = JobError_to_ErrorCode[JobEndReason]; responseContainer.errormessage = Message; if (Message) //moved - bug #3867 { response.status = Message; } } if (JobAbortedByUser == true) { JobAbortedByUser = false; responseContainer.has_error = true; responseContainer.error = ERROR_CODE__CONTINUOUS_RESPONSE_ABORTED; } } container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); if (container_buffer) { size_t container_size = message_container__pack(&responseContainer, container_buffer); my_free(responseContainer.data.data); SendChars((char*)container_buffer, container_size); } } double heaterRatio = 1.00; double dispenserRatio = 1.00 ; float wfcf_count = 0; double prepare_progress = 0.0; void SendJobProgress(double ProcessedLength, int SegmentId, bool done, char *Message) { MessageContainer responseContainer; uint8_t* container_buffer; //int len; //static msdid = 0; //int length = (int)(ProcessedLength*100); //len = usnprintf(logmsg, 254, "MSG: Job Progress Length %d, Seg %d Done %d ",length, SegmentId, done); //REPORT_MSG(msdid++,logmsg); //Report(logmsg,__FILE__,__LINE__,SegmentId,RpWarning,SegmentId, done); /*if (Message) { strcpy (infomsg,Message); Report(infomsg,__FILE__,__LINE__,55,RpWarning,33, 44); }*/ //UInt Key = Task_disable(); if (prepare_state == true) { heaterRatio = HeatersPrepareProgress(); dispenserRatio = IdsPrepareProgress(); if ((heaterRatio>0.99)&&(dispenserRatio>0.99)) { wfcf_count+=1.00; //Report("prepare_progress wfcf" ,__FILE__,(int)(wfcf_count),(int)(heaterRatio*100),RpWarning,(int)(dispenserRatio*100),0); } prepare_progress = (0.9*heaterRatio)+(0.08*dispenserRatio) + (0.02*wfcf_count/25.0); //Report("prepare_progress" ,__FILE__,(int)(prepare_progress*1000),(int)(heaterRatio*1000),RpWarning,(int)(dispenserRatio*1000),0); } else wfcf_count = 0; double totlength = 0; if (JobToken[0] != 0) { if (CleaningJobActive == true) { SendCleaningJobProgress( ProcessedLength, SegmentId, done, Message); } else { if (Message) { jobStatus.message = Message; } //previousJobLength = ProcessedLength; jobStatus.has_progress = true; #ifdef FEEDER_LENGTH_CALCULATION totlength = TotalProcessedLength; if (TotalProcessedLength > job_length) { Report("job length bigger than assigned",__FILE__,__LINE__,TotalProcessedLength,RpWarning,job_length, done); //TotalProcessedLength = job_length; totlength = job_length; } #else totlength = PoolerTotalProcessedLength; if (PoolerTotalProcessedLength > job_length) { Report("job length bigger than assigned",__FILE__,__LINE__,(int)(PoolerTotalProcessedLength*100),RpWarning,(int)(job_length*100), done); //TotalProcessedLength = job_length; totlength = job_length; } #endif jobStatus.progress = totlength; jobStatus.has_currentsegmentindex = true; jobStatus.currentsegmentindex = SegmentId; if (JobResumed == true) { resumeresponse.status = &jobStatus; //responseContainer = createContainer(MESSAGE_TYPE__ResumeCurrentJobResponse, JobToken, done, &resumeresponse, &resume_current_job_response__pack, &resume_current_job_response__get_packed_size); responseContainer = createAllocatedContainer(MESSAGE_TYPE__ResumeCurrentJobResponse, JobToken, done, &resumeresponse, &resume_current_job_response__pack, &resume_current_job_response__get_packed_size,&JobStatusBuffer); } else { JobResponseMsg.status = &jobStatus; //responseContainer = createContainer(MESSAGE_TYPE__JobResponse, JobToken, done, &JobResponseMsg, &job_response__pack, &job_response__get_packed_size); responseContainer = createAllocatedContainer(MESSAGE_TYPE__JobResponse, JobToken, done, &JobResponseMsg, &job_response__pack, &job_response__get_packed_size,&JobStatusBuffer); } responseContainer.has_continuous = true; responseContainer.continuous = true; if (done == true) { if(JobEndReason != JOB_OK) { switch (JobEndReason) { case JOB_THREAD_BREAK: //AlarmHandlingSetAlarm(EVENT_TYPE__THREAD_BREAK,true); break; case JOB_POOLER_DANCER_FAIL: AlarmHandlingSetAlarm(EVENT_TYPE__THREAD_TENSION_CONTROL_FAILURE_PULLER_DANCER,true); break; case JOB_FEEDER_DANCER_FAIL: AlarmHandlingSetAlarm(EVENT_TYPE__THREAD_TENSION_CONTROL_FAILURE_FEEDER_DANCER,true); break; case JOB_WINDER_DANCER_FAIL: AlarmHandlingSetAlarm(EVENT_TYPE__THREAD_TENSION_CONTROL_FAILURE_WINDER_DANCER,true); break; default: break; } if (strlen(AlarmReasonStr)) strncpy(ErrorMsg,AlarmReasonStr,100); responseContainer.has_error = true; responseContainer.error = JobError_to_ErrorCode[JobEndReason]; if (strlen(ErrorMsg)) responseContainer.errormessage = ErrorMsg; } if (JobAbortedByUser == true) { JobAbortedByUser = false; responseContainer.has_error = true; responseContainer.error = ERROR_CODE__CONTINUOUS_RESPONSE_ABORTED; } } container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); if (container_buffer) { size_t container_size = message_container__pack(&responseContainer, container_buffer); // if (SendChars(container_buffer, container_size) == false) //comm tx mailbox full ErrorMsg[0] = 0; if (SendCharsWithType(container_buffer, container_size,MESSAGE_TYPE__JobResponse) == false) //comm tx mailbox full { //AlarmHandlingToken[0] = 0; my_free(container_buffer); } } } } if (done == true) { if (CurrentRequest!= NULL) { // job_request__free_unpacked(CurrentRequest,NULL); CurrentRequest = NULL; } JobStopReporting(); prepare_state = false; HandleJobEnd(JobEndReason); } // if (responseContainer.data.data) // my_free(responseContainer.data.data); //Task_restore(Key); } void JobStopReporting(void) { LOG_ERROR(0,"JobStopReporting"); JobToken[0] = 0; } void AbortJob(char *Msg) { //ReturnCode retcode; //retcode = JobSuccess; JobMessageStruc Message; PrintMessageStruc *PrtMessage = (PrintMessageStruc *)Message.messageData; Message.messageId = Abort; PrtMessage->messageId = PrintSystemFailure; strncpy(PrtMessage->messageData,Msg,99); //PrtMessage->messageData[99] = NULL; Message.msglen = 10; if (JobmsgQ != NULL) Mailbox_post(JobmsgQ , &Message, BIOS_NO_WAIT); } uint32_t CurrentJobRequestFunc(MessageContainer* requestContainer) { uint32_t status = OK; MessageContainer responseContainer; CurrentJobRequest* request = current_job_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data); CurrentJobResponse response = CURRENT_JOB_RESPONSE__INIT; if (JobActive == true) { response.has_isjobinprogress = true; response.isjobinprogress = true; response.jobticket = CurrentJob; } else { response.has_isjobinprogress = true; response.isjobinprogress = false; response.jobticket = NULL; } responseContainer = createContainer(MESSAGE_TYPE__CurrentJobResponse, requestContainer->token, false, &response, ¤t_job_response__pack, ¤t_job_response__get_packed_size); if (status!= OK) { responseContainer.has_error = true; responseContainer.error = ERROR_CODE__INVALID_PROCESS_ID; responseContainer.errormessage = "JOb Active or incorrect parameters"; } responseContainer.continuous = false; uint8_t* container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); if (container_buffer) { size_t container_size = message_container__pack(&responseContainer, container_buffer); SendChars(container_buffer, container_size); } if (responseContainer.data.data) my_free(responseContainer.data.data); return OK; } uint32_t ResumeCurrentJobRequestFunc(MessageContainer* requestContainer) { uint32_t status = OK; MessageContainer responseContainer; ResumeCurrentJobRequest* request = resume_current_job_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data); ResumeCurrentJobResponse response = RESUME_CURRENT_JOB_RESPONSE__INIT; JobStatus jobStatus = JOB_STATUS__INIT; if (JobActive == true) { ustrncpy (JobToken, requestContainer->token,36); JobResumed = true; usnprintf(ErrorMsg, 100, "Job Resumed"); Report("Job resumed",__FILE__,__LINE__, JobActive,RpMessage,JobResumed,0); jobStatus.message =ErrorMsg; jobStatus.has_progress = true; jobStatus.progress = 0.0; jobStatus.has_currentsegmentindex = false; response.status = &jobStatus; response.has_canceled = false; } else { usnprintf(ErrorMsg, 100, "Job not Resumed"); Report("Job not resumed",__FILE__,__LINE__, JobActive,RpMessage,JobResumed,0); jobStatus.message =ErrorMsg; jobStatus.has_progress = true; jobStatus.progress = 0.0; jobStatus.has_currentsegmentindex = false; response.status = &jobStatus; response.has_canceled = true; response.canceled = true; } responseContainer = createContainer(MESSAGE_TYPE__ResumeCurrentJobResponse, JobToken, false, &response, &resume_current_job_response__pack, &resume_current_job_response__get_packed_size); if (status!= OK) { responseContainer.has_error = true; responseContainer.error = ERROR_CODE__INVALID_PROCESS_ID; responseContainer.errormessage = "JOb Active or incorrect parameters"; } responseContainer.continuous = false; uint8_t* container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); if (container_buffer) { size_t container_size = message_container__pack(&responseContainer, container_buffer); SendChars(container_buffer, container_size); } if (responseContainer.data.data) my_free(responseContainer.data.data); return OK; } void StartJob(void *JobDetails) { JobMessageStruc Message; Message.messageId = JobRequestMsg; Message.msglen = MAX_MSG_LEN; if (JobmsgQ != NULL) Mailbox_post(JobmsgQ , &Message, BIOS_NO_WAIT); } void HandleJobEnd(JobEndReasonEnum JobEndReason) { JobActive = false; JobResumed = false; setmachineActive(false); SetMachineStatus(MACHINE_STATE__Ready); IDS_Dispenser_Store_Data(); resetIdleCounter(); CurrentJob = NULL; if (IFS_Clearing_SuctionWaiting == true) WHS_Set_IFS_Clearing_Suction(NUM_OF_MIDTANKS); SuspendLargeMessages = false; Report("Job Ended ", __FILE__, __LINE__, JobEndReason, RpMessage, 0, 0); ExitState(NULL); } /****************************************************************************** * ======== 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); memset(&SavedThreadParameters,0,sizeof(SavedThreadParameters)); JobmsgQ = Mailbox_create(MAX_MSG_LEN, 20, NULL,NULL); while(1) { Mailbox_pend(JobmsgQ , &Message, BIOS_WAIT_FOREVER); switch (Message.messageId) { case JobRequestMsg: JobEndReason = JOB_OK; Report("JobRequestMsg",__FILE__,__LINE__, JobActive,RpMessage,JobResumed,0); JobActive = true; PowerIdleOutOfIdleState(); SetMachineStatus(MACHINE_STATE__PreparingJob); JobResumed = false; OpenJobFile(); setmachineActive(true); PrepareState (CurrentJob); break; case ValidationResultsFail: //send message data as a validation error message to host ExitState(Message.messageData); break; case PreparationResultsOk: Report("PreparationResultsOk",__FILE__,__LINE__, 5,RpMessage,0,0); PrintState(CurrentJob); break; case PreparationResultsFail: //send message data as a validation error message to host Report("Job Ended PreparationResultsFail",__FILE__,__LINE__, 5,RpMessage,0,0); EndState(CurrentJob, "Prepare Failed"); //ExitState(Message.messageData); break; case PrintMessage: //send message data as a validation error message to host PrintSTMMsgHandler(&Message); break; case PrintingResultsOk: case PrintingResultsFail: 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; case Abort: PrintSTMMsgHandler(&Message); break; default: break; } } }