diff --git a/ADIS_tinyK22_SplitFlap/source/application.c b/ADIS_tinyK22_SplitFlap/source/application.c index 8824902..06f475a 100644 --- a/ADIS_tinyK22_SplitFlap/source/application.c +++ b/ADIS_tinyK22_SplitFlap/source/application.c @@ -51,8 +51,8 @@ void App_Init(void){ /* App Task */ static void App_Task(void* pv){ -PRINTF("Initializing split flap motors.\n"); - bool successfulInit0 = SF_MoveMotorToZeroPosition(splitflap0, 12); + PRINTF("Initializing split flap motors.\n"); + bool successfulInit0 = SF_MoveMotorToZeroPosition(splitflap0, 20); PRINTF("Init of motor 0 done. Success = %s\n\n", successfulInit0 ? "true" : "false"); #ifndef APP_DEBUG @@ -62,7 +62,7 @@ PRINTF("Initializing split flap motors.\n"); } #endif - bool successfulInit1 = SF_MoveMotorToZeroPosition(splitflap1, 12); + bool successfulInit1 = SF_MoveMotorToZeroPosition(splitflap1, 25); PRINTF("Init of motor 1 done. Success = %s\n\n", successfulInit1 ? "true" : "false"); #ifndef APP_DEBUG @@ -73,7 +73,7 @@ PRINTF("Initializing split flap motors.\n"); #endif /* MULTI SPLIT FLAP TESTING */ - char* sentence[] = {"JONAS!"}; + char sentence[] = "JONAS!"; MultiSplitFlap_Display(sentence); return; @@ -109,7 +109,7 @@ void App_Run(void){ &appTaskHandle); if(res != pdPASS) // task creation not successful? - { // TODO error handling + { PRINTF("Task creation of app task failed"); for(;;) {} // Endless loop } diff --git a/ADIS_tinyK22_SplitFlap/source/multi-splitflap.c b/ADIS_tinyK22_SplitFlap/source/multi-splitflap.c index 53b71e6..7e29a65 100644 --- a/ADIS_tinyK22_SplitFlap/source/multi-splitflap.c +++ b/ADIS_tinyK22_SplitFlap/source/multi-splitflap.c @@ -56,11 +56,11 @@ void MultiSplitFlap_AddFlap(SF_Handle_t splitflap){ addedFlaps++; } -void MultiSplitFlap_Display(char* sentence[]){ +void MultiSplitFlap_Display(char sentence[]){ for (uint8_t num = 0; num < NUM_FLAPS; ++num) { SF_Handle_t sfHandle = (SF_Handle_t)(getItem(*flapDict, flapKeys[num])); - SF_MoveToFlap(sfHandle, sentence[num]); - PRINTF("Moved multisplitflap: Flap nr. %i to letter '%c'.\n", num+1, (*sentence)[num]); + SF_MoveToFlapAsync(sfHandle, (char*)(sentence[num])); + PRINTF("Moved multisplitflap: Flap nr. %i to letter '%c'.\n", num+1, sentence[num]); } // for testing purposes only //SF_t* sf0 = (SF_t*)(SF_Handle_t)(getItem(*flapDict, flapKeys[0])); diff --git a/ADIS_tinyK22_SplitFlap/source/multi-splitflap.h b/ADIS_tinyK22_SplitFlap/source/multi-splitflap.h index 6435f79..bded770 100644 --- a/ADIS_tinyK22_SplitFlap/source/multi-splitflap.h +++ b/ADIS_tinyK22_SplitFlap/source/multi-splitflap.h @@ -24,7 +24,7 @@ void MultiSplitFlap_AddFlap(SF_Handle_t splitflap); /* display a sentence on the splitflap combination * splitflaps must be initialized to be able to display something!*/ -void MultiSplitFlap_Display(char* sentence[]); +void MultiSplitFlap_Display(char sentence[]); /* returns the amount of registered split flap displays in the combination */ uint8_t MultiSplitFlap_GetAmountOfAddedSplitFlaps(void); diff --git a/ADIS_tinyK22_SplitFlap/source/splitflap.c b/ADIS_tinyK22_SplitFlap/source/splitflap.c index 2d101d6..23fdbee 100644 --- a/ADIS_tinyK22_SplitFlap/source/splitflap.c +++ b/ADIS_tinyK22_SplitFlap/source/splitflap.c @@ -6,12 +6,15 @@ * Author: jonas */ +#include #include "splitflap.h" #include "fsl_debug_console.h" #include "McuULN2003.h" #include #include "McuWait.h" +#include "McuRTOS.h" #include "lib/dict.h" +#include "McuUtility.h" /* dynamic dictionary for the letters of the dictionary */ static dict_t **splitFlapDict; @@ -22,6 +25,12 @@ static char* SF_Letters[] = { " ", "A", "B", "C", "D", "E", "F", "G", "H", "I", "!", "?", ":"}; /* flag if this module is initialized (physically) */ static bool initialized = false; +/* mutex for if the module is currently being moved */ +static SemaphoreHandle_t ongoingMoveMutex = NULL; + +/* function declarations */ +static bool OngoingMoveMutex_Lock(void); +static void OngoingMoveMutex_Unlock(void); void SF_InitConfig(void){ splitFlapDict = dictAlloc(); @@ -58,34 +67,44 @@ SF_Handle_t SF_Init(SF_Config_t* instance, int id){ splitflap->motor = McuULN2003_InitMotor(&instance->motorConfig); splitflap->id = id; + // create mutex for ongoing move + ongoingMoveMutex = xSemaphoreCreateRecursiveMutex(); + char text[50] = "Ongoing move SplitFlap "; + McuUtility_strcatNum16s((uint8_t*)text, sizeof(text)+20, id); + vQueueAddToRegistry(ongoingMoveMutex, text); + return splitflap; } bool SF_MoveMotorToZeroPosition(SF_Handle_t instance, uint16_t offsetSteps){ int numStepsMoved = 0; - // move out of sensor - while(SF_GetMagSensorAtZeroPosition((SF_t*)instance) == true){ - McuULN2003_IncStep(((SF_t*)instance)->motor); - McuWait_Waitms(20); - } - - // turn until sensor is on and not reached one full rotation already (timeout) - while(SF_GetMagSensorAtZeroPosition((SF_t*)instance) == false && numStepsMoved < SPLITFLAP_STEPS_ONE_ROUND ){ - McuULN2003_IncStep(((SF_t*)instance)->motor); - McuWait_Waitms(20); - numStepsMoved++; - } + if(OngoingMoveMutex_Lock()){ + // move out of sensor + while(SF_GetMagSensorAtZeroPosition((SF_t*)instance) == true){ + McuULN2003_IncStep(((SF_t*)instance)->motor); + McuWait_Waitms(20); + } - // offset after init - if(numStepsMoved < SPLITFLAP_STEPS_ONE_ROUND){ - for(int i=0; i < offsetSteps; i++){ + // turn until sensor is on and not reached one full rotation already (timeout) + while(SF_GetMagSensorAtZeroPosition((SF_t*)instance) == false && numStepsMoved < SPLITFLAP_STEPS_ONE_ROUND ){ McuULN2003_IncStep(((SF_t*)instance)->motor); McuWait_Waitms(20); + numStepsMoved++; } + + // offset after init + if(numStepsMoved < SPLITFLAP_STEPS_ONE_ROUND){ + for(int i=0; i < offsetSteps; i++){ + McuULN2003_IncStep(((SF_t*)instance)->motor); + McuWait_Waitms(20); + } + } + McuULN2003_SetPos(((SF_t*)instance)->motor, 0); + McuULN2003_PowerOff(((SF_t*)instance)->motor); + + OngoingMoveMutex_Unlock(); } - McuULN2003_SetPos(((SF_t*)instance)->motor, 0); - McuULN2003_PowerOff(((SF_t*)instance)->motor); // success if less than one rotation initialized = (numStepsMoved < SPLITFLAP_STEPS_ONE_ROUND); @@ -95,20 +114,25 @@ bool SF_MoveMotorToZeroPosition(SF_Handle_t instance, uint16_t offsetSteps){ void SF_MoveSteps(SF_Handle_t instance, uint32_t steps){ if(initialized){ - // run move with acceleration & deceleration - McuULN2003_AccelerationStart(((SF_t*)instance)->motor); - while(steps>0){ - if(McuULN2003_StepCallback(((SF_t*)instance)->motor, true)){ - steps--; + + if(OngoingMoveMutex_Lock()){ + // run move with acceleration & deceleration + McuULN2003_AccelerationStart(((SF_t*)instance)->motor); + while(steps>0){ + if(McuULN2003_StepCallback(((SF_t*)instance)->motor, true)){ + steps--; + } + McuWait_Waitms(1); } - McuWait_Waitms(1); - } - McuULN2003_AccelerationEnd(((SF_t*)instance)->motor); + McuULN2003_AccelerationEnd(((SF_t*)instance)->motor); - // Power off disables all outputs of the ULN, - // required since it is possible that one is still active, which would result in the motor getting hot - // no re-init is required - McuULN2003_PowerOff(((SF_t*)instance)->motor); + // Power off disables all outputs of the ULN, + // required since it is possible that one is still active, which would result in the motor getting hot + // no re-init is required + McuULN2003_PowerOff(((SF_t*)instance)->motor); + + OngoingMoveMutex_Unlock(); + } } } @@ -117,20 +141,66 @@ bool SF_GetMagSensorAtZeroPosition(SF_Handle_t instance){ } void SF_MoveToFlap(SF_Handle_t instance, char* flap){ - // get flap pos from dictonary - int32_t flapPos = (int32_t)getItem(*splitFlapDict, flap); - // get current motor pos - int32_t currentPos = SF_GetMotorPosition(instance) % SPLITFLAP_STEPS_ONE_ROUND; - // calc steps to move - int32_t stepsToReachFlap = 0; - // not already there - if(flapPos != currentPos){ - if(flapPos < currentPos){ - stepsToReachFlap = SPLITFLAP_STEPS_ONE_ROUND-currentPos+flapPos; - }else if(flapPos > currentPos){ - stepsToReachFlap = flapPos - currentPos; + if(OngoingMoveMutex_Lock()){ + + // get flap pos from dictonary + int32_t flapPos = (int32_t)getItem(*splitFlapDict, flap); + // get current motor pos + int32_t currentPos = SF_GetMotorPosition(instance) % SPLITFLAP_STEPS_ONE_ROUND; + // calc steps to move + int32_t stepsToReachFlap = 0; + // not already there + if(flapPos != currentPos){ + if(flapPos < currentPos){ + stepsToReachFlap = SPLITFLAP_STEPS_ONE_ROUND-currentPos+flapPos; + }else if(flapPos > currentPos){ + stepsToReachFlap = flapPos - currentPos; + } + SF_MoveSteps(instance, stepsToReachFlap); + } + + OngoingMoveMutex_Unlock(); + } +} + +typedef struct{ + SF_Handle_t instance; + char* flap; +} MoveToFlap_Param_t; + + +/* pointer to MoveToFlap_Param_t */ +static void SF_MoveToFlapWithParameter(void *pv){ + + MoveToFlap_Param_t param = *(MoveToFlap_Param_t*)pv; + SF_MoveToFlap(param.instance, param.flap); +} + +MoveToFlap_Param_t taskParameters; + +void SF_MoveToFlapAsync(SF_Handle_t instance, char* flap){ + if(OngoingMoveMutex_Lock()){ + BaseType_t res; + + char taskName[50] = "SF Mv "; + McuUtility_strcatNum16s((uint8_t*)taskName, sizeof(taskName)+20, ((SF_t*)instance)->id); + taskParameters.instance = instance; + taskParameters.flap = flap; + + res = xTaskCreate( SF_MoveToFlapWithParameter, + taskName, + 500/sizeof(StackType_t), + &taskParameters, + tskIDLE_PRIORITY, + NULL); + + if(res != pdPASS) // task creation not successful? + { + PRINTF("Creation of %s failed", taskName); + for(;;) {} // Endless loop } - SF_MoveSteps(instance, stepsToReachFlap); + + OngoingMoveMutex_Unlock(); } } @@ -139,7 +209,27 @@ int32_t SF_GetMotorPosition(SF_Handle_t instance){ } void SF_Deinit(SF_Handle_t instance){ + vSemaphoreDelete(ongoingMoveMutex); McuULN2003_DeinitMotor(((SF_t*)instance)->motor); McuGPIO_DeinitGPIO(((SF_t*)instance)->magSensor); initialized = false; } + + +/* HELPERS */ +static bool OngoingMoveMutex_Lock(void){ + /* aquire mutex */ + if(xSemaphoreTakeRecursive(ongoingMoveMutex, pdMS_TO_TICKS(20)) != pdTRUE){ + return false; /* timeout? */ + } + return true; +} + +static void OngoingMoveMutex_Unlock(void){ + /* give back mutex */ + if(xSemaphoreGiveRecursive(ongoingMoveMutex) != pdTRUE){ + /* issue */ + PRINTF("Could not give back ongoing move mutex for splitflap"); + for(;;); + } +} diff --git a/ADIS_tinyK22_SplitFlap/source/splitflap.h b/ADIS_tinyK22_SplitFlap/source/splitflap.h index 7132b85..5748b64 100644 --- a/ADIS_tinyK22_SplitFlap/source/splitflap.h +++ b/ADIS_tinyK22_SplitFlap/source/splitflap.h @@ -65,6 +65,9 @@ bool SF_GetMagSensorAtZeroPosition(SF_Handle_t instance); /* move to specific flap */ void SF_MoveToFlap(SF_Handle_t instance, char* flap); +/* move to specific flap asynchronously (RTOS task) */ +void SF_MoveToFlapAsync(SF_Handle_t instance, char* flap); + /* get current position of motor */ int32_t SF_GetMotorPosition(SF_Handle_t instance);