|
|
|
@ -6,16 +6,20 @@ |
|
|
|
* Author: jonas |
|
|
|
* Author: jonas |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "platform.h" |
|
|
|
#include <stdbool.h> |
|
|
|
#include <stdbool.h> |
|
|
|
#include "splitflap.h" |
|
|
|
#include "splitflap.h" |
|
|
|
#include "fsl_debug_console.h" |
|
|
|
#include "McuRTOS.h" |
|
|
|
#include "McuULN2003.h" |
|
|
|
#include "McuULN2003.h" |
|
|
|
#include <stdbool.h> |
|
|
|
#include <stdbool.h> |
|
|
|
#include "McuWait.h" |
|
|
|
#include "McuWait.h" |
|
|
|
#include "McuRTOS.h" |
|
|
|
#include "McuLog.h" |
|
|
|
#include "lib/dict.h" |
|
|
|
#include "lib/dict.h" |
|
|
|
#include "McuUtility.h" |
|
|
|
#include "McuUtility.h" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define FLAP_QUEUE_LENGTH (5) /* number of elements in queue */ |
|
|
|
|
|
|
|
#define FLAP_QUEUE_SELEM_SIZE (sizeof(Flap_t)) /* size of element */ |
|
|
|
|
|
|
|
|
|
|
|
/* dynamic dictionary for the letters of the dictionary */ |
|
|
|
/* dynamic dictionary for the letters of the dictionary */ |
|
|
|
static dict_t **splitFlapDict; |
|
|
|
static dict_t **splitFlapDict; |
|
|
|
/* all letters of the splitflap in the correct order */ |
|
|
|
/* all letters of the splitflap in the correct order */ |
|
|
|
@ -27,7 +31,7 @@ static Flap_t SF_Letters[] = { " ", "A", "B", "C", "D", "E", "F", "G", "H", "I", |
|
|
|
/* function declarations */ |
|
|
|
/* function declarations */ |
|
|
|
static bool OngoingMoveMutex_Lock(SF_Handle_t instance); |
|
|
|
static bool OngoingMoveMutex_Lock(SF_Handle_t instance); |
|
|
|
static void OngoingMoveMutex_Unlock(SF_Handle_t instance); |
|
|
|
static void OngoingMoveMutex_Unlock(SF_Handle_t instance); |
|
|
|
static void SF_MoveToNextFlap(void *pv); |
|
|
|
static void SF_Task(void *pv); |
|
|
|
|
|
|
|
|
|
|
|
/**********************/ |
|
|
|
/**********************/ |
|
|
|
/* INIT / DEINIT */ |
|
|
|
/* INIT / DEINIT */ |
|
|
|
@ -41,12 +45,12 @@ void SF_InitConfig(void){ |
|
|
|
|
|
|
|
|
|
|
|
// add all splitflap flaps to the dictionary, calculating the position automatically
|
|
|
|
// add all splitflap flaps to the dictionary, calculating the position automatically
|
|
|
|
// print out for debugging
|
|
|
|
// print out for debugging
|
|
|
|
PRINTF("Splitflap positioning data is automatically calculated:\n"); |
|
|
|
McuLog_info("Splitflap positioning data is automatically calculated:\n"); |
|
|
|
for(int i = 0; i < SPLITFLAP_AMOUNT_OF_SEGMENTS; i ++){ |
|
|
|
for(int i = 0; i < SPLITFLAP_AMOUNT_OF_SEGMENTS; i ++){ |
|
|
|
// + 0.5 so the rounding is done correctly
|
|
|
|
// + 0.5 so the rounding is done correctly
|
|
|
|
int32_t position = (stepsPerSegment * (float)i + 0.5); |
|
|
|
int32_t position = (stepsPerSegment * (float)i + 0.5); |
|
|
|
addItem(splitFlapDict, SF_Letters[i], (int32_t*)position); |
|
|
|
addItem(splitFlapDict, SF_Letters[i], (int32_t*)position); |
|
|
|
PRINTF("Letter '%s': Position %i\n", SF_Letters[i], (int)position); |
|
|
|
McuLog_info("Letter '%s': Position %i\n", SF_Letters[i], (int)position); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -65,15 +69,43 @@ SF_Handle_t SF_Init(SF_Config_t* instance, int id){ |
|
|
|
|
|
|
|
|
|
|
|
splitflap->magSensor = McuGPIO_InitGPIO(&instance->magSensorConfig); |
|
|
|
splitflap->magSensor = McuGPIO_InitGPIO(&instance->magSensorConfig); |
|
|
|
splitflap->motor = McuULN2003_InitMotor(&instance->motorConfig); |
|
|
|
splitflap->motor = McuULN2003_InitMotor(&instance->motorConfig); |
|
|
|
splitflap->id = id; |
|
|
|
|
|
|
|
splitflap->ongoingMoveMutex = xSemaphoreCreateRecursiveMutex(); // create mutex for ongoing move
|
|
|
|
splitflap->ongoingMoveMutex = xSemaphoreCreateRecursiveMutex(); // create mutex for ongoing move
|
|
|
|
|
|
|
|
splitflap->flapQueue = xQueueCreate(FLAP_QUEUE_LENGTH, FLAP_QUEUE_SELEM_SIZE); // create queue
|
|
|
|
|
|
|
|
splitflap->id = id; |
|
|
|
|
|
|
|
#ifndef APP_DEBUG // when not debugging => set to false
|
|
|
|
splitflap->initialized = false; |
|
|
|
splitflap->initialized = false; |
|
|
|
splitflap->nextFlap = SF_Letters[0]; |
|
|
|
#else // when debugging => set to true
|
|
|
|
|
|
|
|
splitflap->initialized = true; |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
// add mutex to registry
|
|
|
|
// check if queue was created
|
|
|
|
char text[50] = "Ongoing move SplitFlap "; |
|
|
|
if(splitflap->flapQueue == NULL){ |
|
|
|
McuUtility_strcatNum16s((uint8_t*)text, sizeof(text)+20, id); |
|
|
|
McuLog_error("Flap queue creation failed for Splitflap <%i>", id); |
|
|
|
vQueueAddToRegistry(splitflap->ongoingMoveMutex, text); |
|
|
|
for(;;){} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// if yes: add queue to registry
|
|
|
|
|
|
|
|
vQueueAddToRegistry(splitflap->flapQueue, "FlapQueue"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// check if queue was created
|
|
|
|
|
|
|
|
if(splitflap->ongoingMoveMutex == NULL){ |
|
|
|
|
|
|
|
McuLog_error("Ongoing Move mutex creation failed for Splitflap <%i>", id); |
|
|
|
|
|
|
|
for(;;){} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// if yes: add ongoing move mutex to registry
|
|
|
|
|
|
|
|
vQueueAddToRegistry(splitflap->ongoingMoveMutex, "OngoingMoveMutex"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// create Task for splitflap
|
|
|
|
|
|
|
|
BaseType_t res = xTaskCreate( SF_Task, |
|
|
|
|
|
|
|
"SF", |
|
|
|
|
|
|
|
800/sizeof(StackType_t), |
|
|
|
|
|
|
|
splitflap, // no &, since otherwise pointing on parameter address! we want handle address!
|
|
|
|
|
|
|
|
tskIDLE_PRIORITY, |
|
|
|
|
|
|
|
NULL); |
|
|
|
|
|
|
|
if(res != pdPASS) // task creation not successful?
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
McuLog_error("Creation of task for Splitflap <%i> failed", id); |
|
|
|
|
|
|
|
for(;;) {} // Endless loop
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return splitflap; |
|
|
|
return splitflap; |
|
|
|
} |
|
|
|
} |
|
|
|
@ -92,6 +124,11 @@ void SF_Deinit(SF_Handle_t instance){ |
|
|
|
bool SF_MoveMotorToZeroPosition(SF_Handle_t instance, uint16_t offsetSteps){ |
|
|
|
bool SF_MoveMotorToZeroPosition(SF_Handle_t instance, uint16_t offsetSteps){ |
|
|
|
int numStepsMoved = 0; |
|
|
|
int numStepsMoved = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(((SF_t*)instance)->initialized){ |
|
|
|
|
|
|
|
McuLog_warn("Tried to initialize motor of Splitflap <%i>, but already initialized => skipping", ((SF_t*)instance)->id); |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if(OngoingMoveMutex_Lock(instance)){ |
|
|
|
if(OngoingMoveMutex_Lock(instance)){ |
|
|
|
// move out of sensor
|
|
|
|
// move out of sensor
|
|
|
|
while(SF_GetMagSensorAtZeroPosition((SF_t*)instance) == true){ |
|
|
|
while(SF_GetMagSensorAtZeroPosition((SF_t*)instance) == true){ |
|
|
|
@ -145,6 +182,8 @@ void SF_MoveSteps(SF_Handle_t instance, uint32_t steps){ |
|
|
|
|
|
|
|
|
|
|
|
OngoingMoveMutex_Unlock(instance); |
|
|
|
OngoingMoveMutex_Unlock(instance); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} else{ |
|
|
|
|
|
|
|
McuLog_error("SF_MoveSteps could not be called for Splitflap <%i> because it is not initialized.", ((SF_t*)instance)->id); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -176,28 +215,8 @@ void SF_MoveToFlap(SF_Handle_t instance, Flap_t flap){ |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void SF_MoveToFlapAsync(SF_Handle_t instance, Flap_t flap){ |
|
|
|
void SF_MoveToFlapAsync(SF_Handle_t instance, Flap_t flap){ |
|
|
|
if(OngoingMoveMutex_Lock(instance)){ |
|
|
|
if(xQueueSendToBack(((SF_t*)instance)->flapQueue, &flap, pdMS_TO_TICKS(100)) != pdPASS){ |
|
|
|
BaseType_t res; |
|
|
|
McuLog_error("SF_MoveToFlapAsync: Failed to add flap to queue for Splitflap <%i>", ((SF_t*)instance)->id); |
|
|
|
|
|
|
|
|
|
|
|
char taskName[10] = "SF Mv "; |
|
|
|
|
|
|
|
McuUtility_strcatNum16s((uint8_t*)taskName, sizeof(taskName), ((SF_t*)instance)->id); |
|
|
|
|
|
|
|
// set next flap
|
|
|
|
|
|
|
|
((SF_t*)instance)->nextFlap = flap; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
res = xTaskCreate( SF_MoveToNextFlap, |
|
|
|
|
|
|
|
taskName, |
|
|
|
|
|
|
|
500/sizeof(StackType_t), |
|
|
|
|
|
|
|
instance, // no &, since otherwise pointing on parameter address! we want handle address!
|
|
|
|
|
|
|
|
tskIDLE_PRIORITY, |
|
|
|
|
|
|
|
NULL); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(res != pdPASS) // task creation not successful?
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
PRINTF("Creation of %s failed", taskName); |
|
|
|
|
|
|
|
for(;;) {} // Endless loop
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
OngoingMoveMutex_Unlock(instance); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -209,14 +228,48 @@ int32_t SF_GetMotorPosition(SF_Handle_t instance){ |
|
|
|
/* INTERNAL FUNCTIONS */ |
|
|
|
/* INTERNAL FUNCTIONS */ |
|
|
|
/**********************/ |
|
|
|
/**********************/ |
|
|
|
/* voidpointer to instance of splitflap (SF_Handle_t) */ |
|
|
|
/* voidpointer to instance of splitflap (SF_Handle_t) */ |
|
|
|
static void SF_MoveToNextFlap(void *pv){ |
|
|
|
static void SF_Task(void *pv){ |
|
|
|
// parse parameter
|
|
|
|
// parse parameter
|
|
|
|
SF_Handle_t instance = (SF_Handle_t)pv; |
|
|
|
SF_Handle_t instance = (SF_Handle_t)pv; |
|
|
|
PRINTF("Splitflap: Moving Flap nr. %i to letter '%c'.\n", ((SF_t*)instance)->id, (((SF_t*)instance)->nextFlap)[0]); |
|
|
|
SF_t* splitflap = (SF_t*)instance; |
|
|
|
// move to next flap
|
|
|
|
Flap_t nextFlap = " "; |
|
|
|
SF_MoveToFlap(instance, ((SF_t*)instance)->nextFlap); |
|
|
|
McuLog_info("Splitflap: Task for Splitflap <%i> started.\n", splitflap->id); |
|
|
|
// reset next flap
|
|
|
|
|
|
|
|
((SF_t*)instance)->nextFlap = SF_Letters[0]; |
|
|
|
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 iteam 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]); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
OngoingMoveMutex_Unlock(instance); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -235,7 +288,7 @@ static void OngoingMoveMutex_Unlock(SF_Handle_t instance){ |
|
|
|
/* give back mutex */ |
|
|
|
/* give back mutex */ |
|
|
|
if(xSemaphoreGiveRecursive(((SF_t*)instance)->ongoingMoveMutex) != pdTRUE){ |
|
|
|
if(xSemaphoreGiveRecursive(((SF_t*)instance)->ongoingMoveMutex) != pdTRUE){ |
|
|
|
/* issue */ |
|
|
|
/* issue */ |
|
|
|
PRINTF("Could not give back ongoing move mutex for splitflap %i", ((SF_t*)instance)->id); |
|
|
|
McuLog_error("Could not give back ongoing move mutex for splitflap %i", ((SF_t*)instance)->id); |
|
|
|
for(;;); |
|
|
|
for(;;); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|