diff --git a/ADIS_tinyK22_SplitFlap/source/application.c b/ADIS_tinyK22_SplitFlap/source/application.c index 684fd2b..174a3e2 100644 --- a/ADIS_tinyK22_SplitFlap/source/application.c +++ b/ADIS_tinyK22_SplitFlap/source/application.c @@ -54,32 +54,39 @@ static void App_Task(void* pv){ McuLog_info("Application Task starting"); McuLog_info("Initializing split flap motors."); - bool successfulInit0 = SF_MoveMotorToZeroPosition(splitflap0); - McuLog_info("Init of motor 0 done. Success = %s\n\n", successfulInit0 ? "true" : "false"); - -#ifndef APP_DEBUG - // if init failed => stop - if(successfulInit0 == false){ - return; + SF_MoveMotorToZeroPositionAsync(splitflap0); + SF_MoveMotorToZeroPositionAsync(splitflap1); + + // timeout of 35sec + bool initSuccess = false; + for (int i = 0; i < 700; ++i) { + vTaskDelay(pdMS_TO_TICKS(50)); + if(SF_IS_RDY_TO_MOVE((SF_t*)splitflap0) && SF_IS_RDY_TO_MOVE((SF_t*)splitflap1)){ + initSuccess = true; + break; // end loop + } } -#endif - bool successfulInit1 = SF_MoveMotorToZeroPosition(splitflap1); - McuLog_info("Init of motor 1 done. Success = %s\n\n", successfulInit1 ? "true" : "false"); + McuLog_info("Init of splitflaps done. success=%s\n\n", initSuccess ? "true" : "false"); #ifndef APP_DEBUG - // if init failed => stop - if(successfulInit1 == false){ - return; + if(initSuccess == false) + { + // end here + for(;;) {} } +#else + // fake set to ready + ((SF_t*)splitflap0)->state = SF_STATE_READY; + ((SF_t*)splitflap1)->state = SF_STATE_READY; #endif /* MULTI SPLIT FLAP TESTING */ char sentence[] = "JONAS!"; MultiSplitFlap_Display(sentence); - for(;;) - {} + // endless loop (no return! this would produce an bkpt0) + for(;;) {} /* SINGLE SPLIT FLAP TESTING */ diff --git a/ADIS_tinyK22_SplitFlap/source/splitflap.c b/ADIS_tinyK22_SplitFlap/source/splitflap.c index 23261a0..2ffb17b 100644 --- a/ADIS_tinyK22_SplitFlap/source/splitflap.c +++ b/ADIS_tinyK22_SplitFlap/source/splitflap.c @@ -46,7 +46,7 @@ void SF_InitConfig(void){ // + 0.5 so the rounding is done correctly int32_t position = (stepsPerSegment * (float)i + 0.5); addItem(splitFlapDict, SF_Letters[i], (int32_t*)position); - McuLog_info("Letter '%s': Position %i", SF_Letters[i], (int)position); + // TODO FIX LOGGING McuLog_info("Letter '%s': Position %i", SF_Letters[i], (int)position); } } @@ -71,9 +71,9 @@ SF_Handle_t SF_Init(SF_Config_t* config){ splitflap->id = config->setupIdentifier; // copy setup identifier splitflap->hwId = config->hardwareIdentifier; // copy hardware identifier #ifndef APP_DEBUG // when not debugging => set to "not initialized" - splitflap->initialized = false; + splitflap->state = SF_STATE_NOT_READY; #else // when debugging => set to "initialized" - splitflap->initialized = true; + splitflap->state = SF_STATE_READY; #endif // check if queue was created @@ -112,7 +112,7 @@ void SF_Deinit(SF_Handle_t instance){ McuLog_warn("Deinitializing Splitflap <%i>", ((SF_t*)instance)->id); vSemaphoreDelete(((SF_t*)instance)->ongoingMoveMutex); vQueueDelete(((SF_t*)instance)->flapQueue); - ((SF_t*)instance)->initialized = false; + ((SF_t*)instance)->state = SF_STATE_NOT_READY; McuULN2003_DeinitMotor(((SF_t*)instance)->motor); McuGPIO_DeinitGPIO(((SF_t*)instance)->magSensor); #if SPLITFLAP_CONFIG_USE_FREERTOS_HEAP @@ -138,12 +138,19 @@ bool SF_MoveMotorToZeroPosition(SF_Handle_t instance){ } } - if(((SF_t*)instance)->initialized){ + if(SF_IS_RDY_TO_MOVE((SF_t*)instance)){ McuLog_warn("Tried to initialize motor of Splitflap <%i>, but already initialized => skipping", ((SF_t*)instance)->id); return true; } + else if(SF_IS_MOVING((SF_t*)instance)){ + McuLog_warn("Tried to initialize motor of Splitflap <%i>, but it is currently moving => skipping", ((SF_t*)instance)->id); + return false; + } if(OngoingMoveMutex_Lock(instance)){ + // set state + ((SF_t*)instance)->state = SF_STATE_INITIALIZATION; + // move out of sensor while(SF_GetMagSensorAtZeroPosition((SF_t*)instance) == true){ McuULN2003_IncStep(((SF_t*)instance)->motor); @@ -168,23 +175,31 @@ bool SF_MoveMotorToZeroPosition(SF_Handle_t instance){ McuULN2003_PowerOff(((SF_t*)instance)->motor); OngoingMoveMutex_Unlock(instance); + } else{ + // set state + ((SF_t*)instance)->state = SF_STATE_NOT_READY; + McuLog_error("SF_MoveMotorToZeroPosition failed for Splitflap <%i>, could not aquire ongoing move mutex.", ((SF_t*)instance)->id); + return false; } // success if less than one rotation - ((SF_t*)instance)->initialized = (numStepsMoved < SPLITFLAP_STEPS_ONE_ROUND); - McuLog_info("SF_MoveMotorToZeroPosition finished for Splitflap <%i>, success=%s", ((SF_t*)instance)->id, ((SF_t*)instance)->initialized ? "true" : "false"); + ((SF_t*)instance)->state = (numStepsMoved < SPLITFLAP_STEPS_ONE_ROUND) ? SF_STATE_READY : SF_STATE_NOT_READY; + McuLog_info("SF_MoveMotorToZeroPosition finished for Splitflap <%i>, success=%s", ((SF_t*)instance)->id, SF_IS_RDY_TO_MOVE(((SF_t*)instance)) ? "true" : "false"); - return ((SF_t*)instance)->initialized; + return SF_IS_RDY_TO_MOVE(((SF_t*)instance)); } void SF_MoveMotorToZeroPositionAsync(SF_Handle_t instance){ - // TODO TO IMPLEMENT - + // set to state INITIALIZATION => is trigger for the task to start init + ((SF_t*)instance)->state = SF_STATE_INITIALIZATION; } void SF_MoveSteps(SF_Handle_t instance, uint32_t steps){ - if(((SF_t*)instance)->initialized){ + if(SF_IS_RDY_TO_MOVE((SF_t*)instance)){ if(OngoingMoveMutex_Lock(instance)){ + // set state + ((SF_t*)instance)->state = SF_STATE_MOVING; + // run move with acceleration & deceleration McuULN2003_AccelerationStart(((SF_t*)instance)->motor); while(steps>0){ @@ -200,7 +215,12 @@ void SF_MoveSteps(SF_Handle_t instance, uint32_t steps){ // no re-init is required McuULN2003_PowerOff(((SF_t*)instance)->motor); + // set new state + ((SF_t*)instance)->state = SF_STATE_READY; + OngoingMoveMutex_Unlock(instance); + } else{ + McuLog_error("SF_MoveSteps failed for Splitflap <%i>, could not aquire ongoing move mutex.", ((SF_t*)instance)->id); } } else{ McuLog_error("SF_MoveSteps could not be called for Splitflap <%i> because it is not initialized.", ((SF_t*)instance)->id); @@ -253,42 +273,61 @@ static void SF_Task(void *pv){ SF_Handle_t instance = (SF_Handle_t)pv; SF_t* splitflap = (SF_t*)instance; Flap_t nextFlap = " "; + bool initSuccess = false; McuLog_info("Splitflap: Task for Splitflap <%i> started.", splitflap->id); for(;;){ // delay task vTaskDelay(pdMS_TO_TICKS(50)); - // if not initialized => Skip everything - if(splitflap->initialized == false){ - continue; - } - - // check if anything is in queue once (poll once, don't get item) - if(xQueuePeek(splitflap->flapQueue, &nextFlap, 0) != pdPASS){ - /* failed to receive => queue empty */ - continue; - } - McuLog_info("Splitflap <%i> recognized new flap '%c' in queue to move to.", splitflap->id, nextFlap[0]); - - // new flap to move to is available - // check if ongoing move - if(OngoingMoveMutex_Lock(instance)){ - // now get the queue item - if(xQueueReceive(splitflap->flapQueue, &nextFlap, 0) != pdPASS){ - /* failed to receive => queue empty but previously an item was there? error */ - McuLog_error("Failed to receive Queue item of Splitflap <%i>.", splitflap->id); - OngoingMoveMutex_Unlock(instance); - continue; // ignore & proceed - } - - //=> execute move - McuLog_info("Splitflap <%i> moving to flap '%c'.", splitflap->id, nextFlap[0]); - SF_MoveToFlap(instance, nextFlap); - McuLog_info("Splitflap <%i> move done to flap '%c'.", splitflap->id, nextFlap[0]); - vTaskDelay(pdMS_TO_TICKS(100)); // wait for logger to finish + // check state + switch (splitflap->state) { + // no action to be made + case SF_STATE_NOT_READY: + break; // = restart for loop + + // action: start initialization + case SF_STATE_INITIALIZATION: + McuLog_info("Splitflap <%i> recognized to be in state initialization => starting zero move.", splitflap->id); + initSuccess = SF_MoveMotorToZeroPosition(instance); + McuLog_info("Splitflap <%i> finished initialization. success=%s", splitflap->id, initSuccess ? "true" : "false"); + + break; // = go on in the current loop + + // action: check if any moves need to be made + case SF_STATE_READY: + // check if anything is in queue once (poll once, don't get item) + if(xQueuePeek(splitflap->flapQueue, &nextFlap, 0) != pdPASS){ + /* failed to receive => queue empty */ + continue; + } + McuLog_info("Splitflap <%i> recognized new flap '%c' in queue to move to.", splitflap->id, nextFlap[0]); + + // new flap to move to is available + // check if ongoing move + if(OngoingMoveMutex_Lock(instance)){ + // now get the queue item + if(xQueueReceive(splitflap->flapQueue, &nextFlap, 0) != pdPASS){ + /* failed to receive => queue empty but previously an item was there? error */ + McuLog_error("Failed to receive Queue item of Splitflap <%i>.", splitflap->id); + OngoingMoveMutex_Unlock(instance); + continue; // ignore & proceed + } + + //=> execute move + McuLog_info("Splitflap <%i> moving to flap '%c'.", splitflap->id, nextFlap[0]); + SF_MoveToFlap(instance, nextFlap); + McuLog_info("Splitflap <%i> move done to flap '%c'.", splitflap->id, nextFlap[0]); + vTaskDelay(pdMS_TO_TICKS(100)); // wait for logger to finish + + OngoingMoveMutex_Unlock(instance); + } + break; - OngoingMoveMutex_Unlock(instance); + // wrong state + default: + McuLog_warn("Not implemented state in SF_Task!"); + break; // = restart for loop } } } diff --git a/ADIS_tinyK22_SplitFlap/source/splitflap.h b/ADIS_tinyK22_SplitFlap/source/splitflap.h index f589a90..7dfbbaa 100644 --- a/ADIS_tinyK22_SplitFlap/source/splitflap.h +++ b/ADIS_tinyK22_SplitFlap/source/splitflap.h @@ -35,6 +35,18 @@ typedef uint8_t HardwareIdentifier_t; /* descriptor to identify the instance in the setup */ typedef uint8_t SetupIdentifier_t; +/* state of the splitflap instance */ +typedef enum{ + /* splitflap is in initial state, after creation, not initialized */ + SF_STATE_NOT_READY, + /* splitflap is waiting to be or currently being initialized */ + SF_STATE_INITIALIZATION, + /* splitflap is ready to move to another flap */ + SF_STATE_READY, + /* splitflap is currently moving to another flap */ + SF_STATE_MOVING +} SF_State; + typedef struct { SetupIdentifier_t id; HardwareIdentifier_t hwId; @@ -42,7 +54,7 @@ typedef struct { McuGPIO_Handle_t magSensor; SemaphoreHandle_t ongoingMoveMutex; QueueHandle_t flapQueue; - bool initialized; + SF_State state; } SF_t; typedef struct { @@ -52,6 +64,11 @@ typedef struct { SetupIdentifier_t setupIdentifier; } SF_Config_t; +/****** HELPER MACROS **/ +#define SF_IS_RDY_TO_MOVE(sf) ((sf)->state == SF_STATE_READY) +#define SF_IS_MOVING(sf) ((sf)->state == SF_STATE_MOVING) +#define SF_IS_INITIALIZING(sf) ((sf)->state == SF_STATE_INITIALIZATION) + /****** FUNCTIONS ******/ /* initializes dictonary with splitflap flaps position */ void SF_InitConfig(void);