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/Modules/Thread | |
| 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/Modules/Thread')
6 files changed, 475 insertions, 0 deletions
diff --git a/Software/Embedded_SW/Embedded/Modules/Thread/Thread.h b/Software/Embedded_SW/Embedded/Modules/Thread/Thread.h new file mode 100644 index 000000000..475f63795 --- /dev/null +++ b/Software/Embedded_SW/Embedded/Modules/Thread/Thread.h @@ -0,0 +1,55 @@ +#include "PMR/common/MessageContainer.pb-c.h" +#include "PMR/Hardware/HardwareMotor.pb-c.h" +#include "PMR/Hardware/HardwareMotorType.pb-c.h" +#include "PMR/Hardware/HardwareDancer.pb-c.h" +#include "PMR/Hardware/HardwareDancerType.pb-c.h" +#include "PMR/Hardware/HardwareWinder.pb-c.h" +#include "PMR/Printing/JobSpool.pb-c.h" +#include "PMR/Printing/JobSpoolType.pb-c.h" + + +typedef struct +{ + HardwareMotorType id; + uint32_t minfreq; + uint32_t maxfreq; + uint32_t minmicrostep; + uint32_t maxmicrostep; + double linearratio; + uint32_t medianposition; + double correctiongain; + double ratio2dryerspeed; + double kp; + double ki; + double kd; + double changeslope; + double hightimeoutusec; +}MotorConfigStruc; +typedef struct +{ + uint32_t startoffsetpulses; + uint32_t spoolbackingrate; + uint32_t segmentoffsetpulses; + uint32_t milimetersperrotation; +}InternalWinderConfigStruc; + +typedef struct +{ + bool fixorgradual; + double k; + double x; + int32_t pulsepermmspring; + int id; //HardwareDancerType +}DancerConfigStruc; +#define MAX_THREAD_MOTORS_NUM HARDWARE_MOTOR_TYPE__WinderMotor +1 + + +extern MotorConfigStruc MotorsCfg[MAX_THREAD_MOTORS_NUM]; +extern InternalWinderConfigStruc InternalWinderCfg; + + +uint32_t InternalWinderConfigMessage(HardwareWinder* request); +uint32_t MotorsConfigMessage(HardwareMotor * request); +uint32_t InternalWindingConfigMessage(JobSpool* request); + +uint32_t DancerConfigMessage(HardwareDancer * request); diff --git a/Software/Embedded_SW/Embedded/Modules/Thread/Thread_BIT.c b/Software/Embedded_SW/Embedded/Modules/Thread/Thread_BIT.c new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/Software/Embedded_SW/Embedded/Modules/Thread/Thread_BIT.c diff --git a/Software/Embedded_SW/Embedded/Modules/Thread/Thread_ex.h b/Software/Embedded_SW/Embedded/Modules/Thread/Thread_ex.h new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/Software/Embedded_SW/Embedded/Modules/Thread/Thread_ex.h diff --git a/Software/Embedded_SW/Embedded/Modules/Thread/Thread_init.c b/Software/Embedded_SW/Embedded/Modules/Thread/Thread_init.c new file mode 100644 index 000000000..f32026ca8 --- /dev/null +++ b/Software/Embedded_SW/Embedded/Modules/Thread/Thread_init.c @@ -0,0 +1,94 @@ +/************************************************************************************************************************ + **************************************************************************************************************************/ + +#include "include.h" + +#include <Modules/Stubs_Handler/DataDef.h> +#include "PMR/Hardware/HardwareMotor.pb-c.h" +#include "PMR/Hardware/HardwareDancer.pb-c.h" +#include "PMR/Hardware/HardwareWinder.pb-c.h" +#include "PMR/Printing/JobSpool.pb-c.h" +#include "PMR/common/MessageContainer.pb-c.h" + +#include "thread.h" +#define MAX_SYSTEM_DANCERS HARDWARE_DANCER_TYPE__RightDancer+1 +MotorConfigStruc MotorsCfg[MAX_THREAD_MOTORS_NUM]; +InternalWinderConfigStruc InternalWinderCfg; +DancerConfigStruc DancersCfg[MAX_SYSTEM_DANCERS]; + + + +uint32_t InternalWinderConfigMessage(HardwareWinder* request) +{ + uint32_t status = PASSED; + + InternalWinderCfg.milimetersperrotation = request->millimeterperrotation; + + return status; +} +uint32_t InternalWindingConfigMessage(JobSpool* request) +{ + uint32_t status = PASSED; + + InternalWinderCfg.segmentoffsetpulses = request->segmentoffsetpulses; + InternalWinderCfg.spoolbackingrate = request->backingrate; + InternalWinderCfg.startoffsetpulses = request->startoffsetpulses; + + return status; +} + +//******************************************************************************************************************** +uint32_t MotorsConfigMessage(HardwareMotor * request) +{ + uint32_t status = PASSED; + int Motor_i; + + Motor_i = request->hardwaremotortype; + if ((Motor_i)&&(Motor_i< MAX_THREAD_MOTORS_NUM)) + { + MotorsCfg[Motor_i].id = request->hardwaremotortype; + MotorsCfg[Motor_i].minfreq = request->minfrequency; + MotorsCfg[Motor_i].maxfreq = request->maxfrequency; + MotorsCfg[Motor_i].minmicrostep = request->minmicrostep; + MotorsCfg[Motor_i].maxmicrostep = request->maxmicrostep; + MotorsCfg[Motor_i].linearratio = request->linearratio; + MotorsCfg[Motor_i].medianposition = request->medianposition; + MotorsCfg[Motor_i].correctiongain = request->correctiongain; + MotorsCfg[Motor_i].ratio2dryerspeed = request->ratiotodryerspeed; + MotorsCfg[Motor_i].kp = request->kp; + MotorsCfg[Motor_i].ki = request->ki; + MotorsCfg[Motor_i].kd = request->kd; + MotorsCfg[Motor_i].changeslope = request->changeslope; + MotorsCfg[Motor_i].hightimeoutusec = request->highlengthmicrosecond; + return status; + } + else return Motor_i; + +} +uint32_t DancerConfigMessage(HardwareDancer * request) +{ + uint32_t status = PASSED; + int Dancer_i; + + Dancer_i = request->hardwaredancertype; + if ((Dancer_i)&&(Dancer_i<MAX_SYSTEM_DANCERS )) + { + DancersCfg[Dancer_i].id = Dancer_i; + DancersCfg[Dancer_i].fixorgradual = request->gradual; + DancersCfg[Dancer_i].k = request->k; + DancersCfg[Dancer_i].x = request->x; + DancersCfg[Dancer_i].pulsepermmspring = request->pulsepermmspring; + return status; + } + else + return Dancer_i; + +} + +uint32_t thread_init(void) +{ + memset (MotorsCfg,0,sizeof(MotorsCfg)); + memset (&InternalWinderCfg,0,sizeof(InternalWinderConfigStruc)); + + return OK; +} diff --git a/Software/Embedded_SW/Embedded/Modules/Thread/Thread_maint.c b/Software/Embedded_SW/Embedded/Modules/Thread/Thread_maint.c new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/Software/Embedded_SW/Embedded/Modules/Thread/Thread_maint.c diff --git a/Software/Embedded_SW/Embedded/Modules/Thread/Thread_print.c b/Software/Embedded_SW/Embedded/Modules/Thread/Thread_print.c new file mode 100644 index 000000000..10baaed8e --- /dev/null +++ b/Software/Embedded_SW/Embedded/Modules/Thread/Thread_print.c @@ -0,0 +1,326 @@ +/************************************************************************************************************************ + * Thread_print.c + * 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 "thread.h" +#include "../control/control.h" +#include "../control/pidalgo.h" +#include "PMR/Hardware/HardwareMotor.pb-c.h" +#include "PMR/Hardware/HardwareMotorType.pb-c.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 +{ + Entry= 0, + Prepare, + PreSegment, + Segment, + End, + Exit +} PrintingState_t; + +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 EXIT_STATE Exit +#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 +};*/ +typedef struct +{ + bool m_isEnabled; + uint32_t m_SetParam; + uint32_t m_mesuredParam; + float m_preError; + float m_integral; + float m_calculatedError; + bool m_isReady; + PID_Config_Params m_params; +}MotorControlConfig_t; +/*typedef struct +{ + float epsilon; + float dt; + float MAX; + float MIN; + float Kp; + float Kd; + float Ki; +}PID_Config_Params; +#define epsilon 0.01 +#define dt 0.01 //100ms loop time +#define MAX 4 //For Current Saturation +#define MIN -4 +#define Kp 0.1 +#define Kd 0.01 +#define Ki 0.005 +*/ +MotorControlConfig_t MotorControlConfig[MAX_THREAD_MOTORS_NUM]; +uint32_t DeviceId2Motor[MAX_THREAD_MOTORS_NUM]; +////////////////////////Slow Motor State//////////////////////////////////// +static PrintingState_t gPrintingState; +//////////////////////////////////////////////////////////////////////////// + +uint32_t ThreadControlCBFunction(uint32_t deviceID, uint32_t ReadValue) +{ + int i,index=MAX_THREAD_MOTORS_NUM; + for (i=0;i<MAX_THREAD_MOTORS_NUM;i++) + if (DeviceId2Motor[i] == deviceID) + { + index = i; + break; + } + if (index==MAX_THREAD_MOTORS_NUM) + { + LOG_ERROR (deviceID, "No motor for device"); + return 0xFFFFFFFF; + } + if(MotorControlConfig[index].m_isEnabled && (MotorControlConfig[index].m_SetParam != 0)) + { + MotorControlConfig[index].m_mesuredParam = ReadValue; + MotorControlConfig[index].m_calculatedError = PIDAlgorithmCalculation(MotorControlConfig[index].m_SetParam , MotorControlConfig[index].m_mesuredParam, + &MotorControlConfig[index].m_params, &MotorControlConfig[index].m_preError, &MotorControlConfig[index].m_integral); + if (MotorControlConfig[index].m_calculatedError >= MotorControlConfig[index].m_params.MAX) + { + MotorControlConfig[index].m_calculatedError = MotorControlConfig[index].m_params.MAX; + } + if (MotorControlConfig[index].m_calculatedError < MotorControlConfig[index].m_params.MIN) + { + MotorControlConfig[index].m_calculatedError = MotorControlConfig[index].m_params.MIN; + } + + //SetMotorFreq (index, MotorControlConfig[index].m_calculatedError); + } + + 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 ReturnCode EntryState(void *JobDetails) +{ + return NextState; +} + +//******************************************************************************************************************** +static ReturnCode PrepareState(void *JobDetails) +{ + int Motor_i; + //start thread control for all motors + for (Motor_i = 0;Motor_i < MAX_THREAD_MOTORS_NUM;Motor_i++) + { + MotorControlConfig[Motor_i].m_params.MAX = MotorsCfg[Motor_i].maxfreq; + MotorControlConfig[Motor_i].m_params.MIN = MotorsCfg[Motor_i].minfreq; + MotorControlConfig[Motor_i].m_params.Kd = MotorsCfg[Motor_i].kd; + MotorControlConfig[Motor_i].m_params.Kp = MotorsCfg[Motor_i].kp; + MotorControlConfig[Motor_i].m_params.Ki = MotorsCfg[Motor_i].ki; + MotorControlConfig[Motor_i].m_params.dt = eOneMillisecond; + MotorControlConfig[Motor_i].m_calculatedError = 0; + MotorControlConfig[Motor_i].m_integral = 0; + MotorControlConfig[Motor_i].m_isEnabled = true; + MotorControlConfig[Motor_i].m_isReady = true; + MotorControlConfig[Motor_i].m_mesuredParam = 0; + MotorControlConfig[Motor_i].m_preError = 0; + MotorControlConfig[Motor_i].m_SetParam = 0;//need to update SetParams on presegment stage + AddControlCallback(DeviceId2Motor[Motor_i], ThreadControlCBFunction, eOneMillisecond); + } + //set 3 dancers to the profile positions + return NextState; +} + +//******************************************************************************************************************** +static ReturnCode PreSegmentState(void *JobDetails) +{ + + int Motor_i; + for (Motor_i = 0;Motor_i < MAX_THREAD_MOTORS_NUM;Motor_i++) + { + MotorControlConfig[Motor_i].m_SetParam = getMotorFreq(Motor_i);//need to update SetParams on presegment stage + } + // set the new speed in the dryer motor to the speed of the new segment + // activate control fr all motors + //set speed for both rocker motors + //wait for all motors to get to the required speed (set the target speed for the control to check) + //call the job state machine when the thread system is ready + 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 ThreadPrintingIterate(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[_motorId]]++; + 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[_motorId],returnCode); + cb_push_back (str, len); + //SendInterruptMessageToHost(10+gPrintingState[_motorId],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 ThreadPrintingsInit(void) +{ +// gPrintingState = Start; +} + +//******************************************************************************************************************** + +void ThreadStartPrinting(void) +{ + gPrintingState = ENTRY_STATE; + //PrintingIterate(); +} + +//******************************************************************************************************************** +//******************************************************************************************************************** + +void ThreadStopPrinting(void) +{ + gPrintingState = EXIT_STATE; + //PrintingIterate(); +} |
