diff options
| author | Shlomo Hecht <shlomo@twine-s.com> | 2018-03-06 12:09:02 +0200 |
|---|---|---|
| committer | Shlomo Hecht <shlomo@twine-s.com> | 2018-03-06 12:09:02 +0200 |
| commit | fb2d080fbbcea3a91e598b4ea8837a230de6a319 (patch) | |
| tree | 6b3ce09a252d2ebab8189a92b3326ffbba6dbe4b /Software/Embedded_SW/Embedded/StateMachines | |
| parent | d734bb5cf08ba2433b74fc86a8858d2437d1a237 (diff) | |
| download | Tango-fb2d080fbbcea3a91e598b4ea8837a230de6a319.tar.gz Tango-fb2d080fbbcea3a91e598b4ea8837a230de6a319.zip | |
A new forlder for embedded software in our common structure
Diffstat (limited to 'Software/Embedded_SW/Embedded/StateMachines')
3 files changed, 712 insertions, 0 deletions
diff --git a/Software/Embedded_SW/Embedded/StateMachines/Printing/JobSTM.c b/Software/Embedded_SW/Embedded/StateMachines/Printing/JobSTM.c new file mode 100644 index 000000000..b62f538e8 --- /dev/null +++ b/Software/Embedded_SW/Embedded/StateMachines/Printing/JobSTM.c @@ -0,0 +1,341 @@ +/************************************************************************************************************************ + * 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 "include.h" +#include <ti/sysbios/knl/mailbox.h> +#include <ti/sysbios/knl/Clock.h> +#include <ti/sysbios/knl/task.h> + +#include <Modules/Stubs_Handler/DataDef.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/Stubs_Handler/Container.h" + +#include "./printingSTM.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; + + + +typedef enum +{ + JobSuccess = 0, + JobFail, + JobStop +} ReturnCode; + +/******************************************************************************************** +* 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; + + +//************************************************************* +/* transitions from end state aren't needed */ +//************************************************************* +#define NUM_OF_TRANSITION 11 +#define ENTRY_STATE Idle +/************************************************************* + * table which describes fast motors transitions states + * during p_profile / segments execution + *************************************************************/ +static Transition_t stateTransitionTable[NUM_OF_TRANSITION] = +{ + {Idle, JobSuccess, Validate}, + {Validate, JobSuccess, PrepareJob}, + {PrepareJob,JobSuccess, Print}, + {Print, JobSuccess, Clean}, + {Clean, JobSuccess, Idle}, + {Idle, JobFail, Idle}, + {Validate, JobFail, Idle}, + {PrepareJob,JobFail, Idle}, + {Print, JobFail, Clean}, + {Clean, JobFail, Idle}, + {ExitJob, JobStop, ExitJob} //for stoping the machine iteration in case of error +}; + +////////////////////////Slow Motor State//////////////////////////////////// +static JobState_t gJobState_t; +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; + + 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) +{ + gJobState_t = Idle; + 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; + 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); + SendChars((char*)container_buffer, container_size); + 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; + } + } +} + diff --git a/Software/Embedded_SW/Embedded/StateMachines/Printing/PrintingSTM.c b/Software/Embedded_SW/Embedded/StateMachines/Printing/PrintingSTM.c new file mode 100644 index 000000000..76b7b2a69 --- /dev/null +++ b/Software/Embedded_SW/Embedded/StateMachines/Printing/PrintingSTM.c @@ -0,0 +1,274 @@ +/************************************************************************************************************************ + * 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" + +////////////////////////////////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 +/////////////////////////////////////////////////////////////////////////////////////////// +typedef enum +{ + NextState = 0, + Repeat, + Inter, + Home, + Stop +} ReturnCode; + +/******************************************************************************************** +* functions describes motor operation flow and movement state during profile execution +* used to operate in runtime correct profileflow execution +*********************************************************************************************/ +static ReturnCode EntryState(void *JobDetails); +static ReturnCode PrepareState(void *JobDetails); +static ReturnCode PreSegmentState(void *JobDetails); +static ReturnCode SegmentState(void *JobDetails); +static ReturnCode EndState(void *JobDetails); +static ReturnCode ExitState(void *JobDetails); + +/********************************************************************** +* the array and enum of PrintingState_t below must be in sync order +***********************************************************************/ +static ReturnCode (* state[])(void *JobDetails) = { EntryState, PrepareState, PreSegmentState, SegmentState, EndState, ExitState}; + + +typedef enum +{ + PrintRequest, + PreSegmentResultsOk, + PreSegmentResultsFail, + SegmentResultsOk, + SegmentResultsFail, + FinishResultsOk, + FinishResultsFail, + PrintSystemFailure +}PrintSTMEventsEnum; + +typedef struct +{ + PrintingState_t m_sourceState; + ReturnCode m_returnCode; + PrintingState_t m_destinationState; +} Transition_t; + +//************************************************************* +/* transitions from end state aren't needed */ +//************************************************************* +#define NUM_OF_TRANSITION 17 +#define ENTRY_STATE Entry +/************************************************************* + * table which describes fast motors transitions states + * during p_profile / segments execution + *************************************************************/ +static Transition_t stateTransitionTable[NUM_OF_TRANSITION] = {}; +/*{ + {Entry, NextState, HomingStart}, + {Entry, Repeat, Entry}, //for homing of dispensers + {HomingStart, NextState, Start}, + {HomingStart, Repeat, HomingStart}, + {Start, NextState, Segment}, + {Start, Repeat, Start}, + {Segment, Inter, Intersegment}, + {Segment, Repeat, Segment}, + {Segment, Home, HomingEnd}, + {Intersegment, NextState, Segment}, + {Intersegment, Repeat, Intersegment}, + {Intersegment, Home, HomingEnd}, + {HomingEnd, NextState, End}, + {HomingEnd, Repeat, HomingEnd}, + {End, NextState, Entry}, + {End, Repeat, Entry}, + {Exit, Stop, Exit} //for stoping the machine iteration in case of error +};*/ + +////////////////////////Slow Motor State//////////////////////////////////// +static PrintingState_t gPrintingState; +//////////////////////////////////////////////////////////////////////////// + + +//******************************************************************************************************************** +/******************************************************************************************************************** +*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 EntryState(void *JobDetails) +{ + return NextState; +} + +//******************************************************************************************************************** +static ReturnCode PrepareState(void *JobDetails) +{ + return NextState; +} + +//******************************************************************************************************************** +static ReturnCode PreSegmentState(void *JobDetails) +{ + + return NextState; +} + +//******************************************************************************************************************** +static ReturnCode SegmentState(void *JobDetails) +{ + return Repeat; +} + +//******************************************************************************************************************** +static ReturnCode EndState(void *JobDetails) +{ + return NextState; +} +//******************************************************************************************************************** +static ReturnCode ExitState(void *JobDetails) +{ + return Stop; +} + +//*********************************************************************************************************************** +//this function is responsible for operating and transitioning between the diffrent motor state executions of the profile +//the lower managment level +//*********************************************************************************************************************** +static PrintingState_t LookupTransitions(PrintingState_t state,ReturnCode returnCode) +{ + char str[80]; + uint8_t len = 0; + uint8_t indexInTransitionTable; + for (indexInTransitionTable = 0; indexInTransitionTable < NUM_OF_TRANSITION; ++indexInTransitionTable) + { + if ((stateTransitionTable[indexInTransitionTable].m_sourceState == state) && (stateTransitionTable[indexInTransitionTable].m_returnCode == returnCode)) + { + //len = usnprintf(str, 60, "\r\n tick %d state %d return code %d",tick,state, returnCode ); + //cb_push_back (str, len); + + //in normal execution flow function should not arrive here + //in case it did the meaning is that the entery point was wrong and a bug should be corrected + return stateTransitionTable[indexInTransitionTable].m_destinationState; + } + } + //int tick = UsersysTickGet(); + //len = usnprintf(str, 60, "\r\n tick %d state %d return code %d",tick,state, returnCode ); + //cb_push_back (str, len); + + //in normal execution flow function should not arrive here + //in case it did the meaning is that the entery point was wrong and a bug should be corrected + len = usnprintf(str, 80, "Internal: invalid slow motor transition state %d return code %d",state, returnCode ); + + return EXIT_STATE; +} +//******************************************************************************** +//this function is used to manage and operate the motor managmant state mashine +//the highest managment level +//******************************************************************************** +bool PrintingIterate(void *JobDetails) +{ + uint32_t tick = 0; + char str[60]; + uint8_t len = 0; + PrintingState_t keepstate = gPrintingState; + // + // Disable all interrupts. + // + ROM_IntMasterDisable(); + + ReturnCode (* state_fun)(void *JobDetails) = state[gPrintingState]; + //if (_motorId == SCREW_MOTOR) + // screw_movement[gPrintingState]++; + ReturnCode returnCode = state_fun(JobDetails); + + /*if ((_motorId == SCREW_MOTOR)&&(pause_active)) + { + tick = UsersysTickGet(); + len = usnprintf(str, 60, "\r\n PrintingIterate tick %d state %d retcode %d ",tick, gPrintingState,returnCode); + cb_push_back (str, len); + //SendInterruptMessageToHost(10+gPrintingState,returnCode); + }*/ + gPrintingState = LookupTransitions(gPrintingState, returnCode); + if (keepstate != gPrintingState){ + tick = UsersysTickGet(); + len = usnprintf(str, 60, "\r\n changed state tick %d state %d retcode %d ", tick, gPrintingState,returnCode); + cb_push_back (str, len); + + } + + // + // Enable all interrupts. + // + ROM_IntMasterEnable(); + return (gPrintingState != EXIT_STATE); +} + + +//******************************************************************************************************************** + +void PrintingsInit(void) +{ +} + +//******************************************************************************************************************** + +void StartPrinting(void) +{ +} + +//******************************************************************************************************************** +//******************************************************************************************************************** + +void StopPrinting(void) +{ +} +void PrintSTMMsgHandler(void * msg) +{ + JobMessageStruc *Message = msg; + PrintMessageStruc *PrtMessage = (PrintMessageStruc *)Message->messageData; + + Report(REPORT_LINE("PrintSTMMsgHandler"),__FILE__,__LINE__, RpMessage,0x1000,Message->messageId,PrtMessage->messageId); + + if (Message->messageId != PrintMessage) + { + //REPORT_ERR ... + return; + } + switch(PrtMessage->messageId) + { + case PrintRequest: + break; + case PreSegmentResultsOk: + break; + case PreSegmentResultsFail: + break; + case SegmentResultsOk: + break; + case SegmentResultsFail: + break; + case FinishResultsOk: + break; + case FinishResultsFail: + break; + case PrintSystemFailure: + break; + default: + break; + } + + + +} diff --git a/Software/Embedded_SW/Embedded/StateMachines/Printing/PrintingSTM.h b/Software/Embedded_SW/Embedded/StateMachines/Printing/PrintingSTM.h new file mode 100644 index 000000000..e9aa4cffd --- /dev/null +++ b/Software/Embedded_SW/Embedded/StateMachines/Printing/PrintingSTM.h @@ -0,0 +1,97 @@ +/************************************************************************************************************************ + * PrintSTM.c + * High managment logical unit of slow motors in the system ( 6 dispensers and the screw) + * profile run up begins from screw homing to begin position and only then from fast motors activation. + * SlowMotor 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 + **************************************************************************************************************************/ + +#ifndef STATEMACHINES_PRINTSTM_H_ +#define STATEMACHINES_PRINTSTM_H_ + +//#include "include.h" +#include "PMR/common/MessageContainer.pb-c.h" +#include "PMR/Hardware/HardwareDispenser.pb-c.h" +#include "PMR/Printing/JobSegment.pb-c.h" +#include "PMR/Printing/JobRequest.pb-c.h" +#include "PMR/Printing/JobTicket.pb-c.h" +#include "PMR/Printing/JobResponse.pb-c.h" + +#define MAX_MSG_LEN 100 +typedef enum +{ + Entry= 0, + Prepare, + PreSegment, + PrintSegment, + End, + ExitPrint +} PrintingState_t; +#define EXIT_STATE ExitPrint + +typedef enum +{ + JobRequestMsg, + ValidationResultsOk, + ValidationResultsFail, + PreparationResultsOk, + PreparationResultsFail, + PrintMessage, + PrintingResultsOk, + PrintingResultsFail, + CleaningResultsOk, + CleaningResultsFail, + SystemFailure +}JobSTMEventsEnum; +#define MAX_JOB_NAME_LEN 40 +#define MAX_SEGMENT_NUM 30 +#define MAX_GRADIENT_STAGES_PER_SEGMENT_NUM 50 +#define MAX_DISPENSER_NUM 8 + +typedef struct +{ + int32_t prevstepmiliseconds; + double nlflow; +}GradientFlowStruc; +typedef struct +{ + size_t n_gradients; + GradientFlowStruc gradient[MAX_GRADIENT_STAGES_PER_SEGMENT_NUM]; +}SegmentGradientStruc; + +typedef struct +{ + int32_t id; + double startflow; +}DispenserStruc; + +typedef struct +{ + char Segmentname[MAX_JOB_NAME_LEN]; + int32_t length; + //RGB *color; + size_t n_dispensers; + DispenserStruc dispenser[MAX_DISPENSER_NUM]; +}SegmentStruc; + + + +typedef struct JobMessage{ + uint16_t messageId; + uint16_t msglen; + uint8_t messageData[MAX_MSG_LEN]; +}JobMessageStruc; +typedef struct PrintMessage{ + uint16_t messageId; + uint16_t msglen; + uint8_t messageData[MAX_MSG_LEN]; +}PrintMessageStruc; + +void PrintSTMMsgHandler(void * msg); +void JobInit(void); +void PrintingsInit(void); + +void JobRequestFunc(MessageContainer* requestContainer); + +#endif /* STATEMACHINES_PRINTSTM_H_ */ |
