|
|
|
|
@ -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
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|