worked on multi splitflap

main
Jonas Arnold 4 years ago
parent 9d1bbd2009
commit 0332771fe9
  1. 16
      ADIS_tinyK22_SplitFlap/.cproject
  2. 6
      ADIS_tinyK22_SplitFlap/source/application.c
  3. 53
      ADIS_tinyK22_SplitFlap/source/multi-splitflap.c
  4. 116
      ADIS_tinyK22_SplitFlap/source/splitflap.c
  5. 13
      ADIS_tinyK22_SplitFlap/source/splitflap.h

@ -202,7 +202,7 @@
<option id="com.crt.advproject.gas.thumb.24888127" name="Thumb mode" superClass="com.crt.advproject.gas.thumb" value="true" valueType="boolean"/> <option id="com.crt.advproject.gas.thumb.24888127" name="Thumb mode" superClass="com.crt.advproject.gas.thumb" value="true" valueType="boolean"/>
<option id="com.crt.advproject.gas.arch.59322756" name="Architecture" superClass="com.crt.advproject.gas.arch" value="com.crt.advproject.gas.target.cm4" valueType="enumerated"/> <option id="com.crt.advproject.gas.arch.59322756" name="Architecture" superClass="com.crt.advproject.gas.arch" value="com.crt.advproject.gas.target.cm4" valueType="enumerated"/>
<option id="gnu.both.asm.option.flags.crt.538274977" name="Assembler flags" superClass="gnu.both.asm.option.flags.crt" value="-c -x assembler-with-cpp -D__NEWLIB__" valueType="string"/> <option id="gnu.both.asm.option.flags.crt.538274977" name="Assembler flags" superClass="gnu.both.asm.option.flags.crt" value="-c -x assembler-with-cpp -D__NEWLIB__" valueType="string"/>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.both.asm.option.include.paths.1038992328" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths" valueType="includePath"> <option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.both.asm.option.include.paths.1038992328" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/drivers}&quot;"/> <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/drivers}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/device}&quot;"/> <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/device}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/CMSIS}&quot;"/> <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/CMSIS}&quot;"/>
@ -211,8 +211,6 @@
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/component/uart}&quot;"/> <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/component/uart}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/component/lists}&quot;"/> <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/component/lists}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/board}&quot;"/> <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/board}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/freertos/freertos_kernel/include}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/freertos/freertos_kernel/portable/GCC/ARM_CM4F}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/source}&quot;"/> <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/source}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${MCULIB}/&quot;"/> <listOptionValue builtIn="false" value="&quot;${MCULIB}/&quot;"/>
<listOptionValue builtIn="false" value="&quot;${MCULIB}/config&quot;"/> <listOptionValue builtIn="false" value="&quot;${MCULIB}/config&quot;"/>
@ -295,10 +293,10 @@
<option id="com.crt.advproject.link.gcc.hdrlib.1729811092" name="Library" superClass="com.crt.advproject.link.gcc.hdrlib" value="com.crt.advproject.gcc.link.hdrlib.newlibnano.semihost" valueType="enumerated"/> <option id="com.crt.advproject.link.gcc.hdrlib.1729811092" name="Library" superClass="com.crt.advproject.link.gcc.hdrlib" value="com.crt.advproject.gcc.link.hdrlib.newlibnano.semihost" valueType="enumerated"/>
<option id="com.crt.advproject.link.fpu.965634186" name="Floating point" superClass="com.crt.advproject.link.fpu" value="com.crt.advproject.link.fpu.fpv4.hard" valueType="enumerated"/> <option id="com.crt.advproject.link.fpu.965634186" name="Floating point" superClass="com.crt.advproject.link.fpu" value="com.crt.advproject.link.fpu.fpv4.hard" valueType="enumerated"/>
<option id="com.crt.advproject.link.thumb.939936813" name="Thumb mode" superClass="com.crt.advproject.link.thumb" value="true" valueType="boolean"/> <option id="com.crt.advproject.link.thumb.939936813" name="Thumb mode" superClass="com.crt.advproject.link.thumb" value="true" valueType="boolean"/>
<option id="com.crt.advproject.link.memory.load.image.1141884635" name="Plain load image" superClass="com.crt.advproject.link.memory.load.image" useByScannerDiscovery="false" value="" valueType="string"/> <option id="com.crt.advproject.link.memory.load.image.1141884635" name="Plain load image" superClass="com.crt.advproject.link.memory.load.image" useByScannerDiscovery="false" value="false;" valueType="string"/>
<option defaultValue="com.crt.advproject.heapAndStack.mcuXpressoStyle" id="com.crt.advproject.link.memory.heapAndStack.style.214008281" name="Heap and Stack placement" superClass="com.crt.advproject.link.memory.heapAndStack.style" useByScannerDiscovery="false" valueType="enumerated"/> <option defaultValue="com.crt.advproject.heapAndStack.mcuXpressoStyle" id="com.crt.advproject.link.memory.heapAndStack.style.214008281" name="Heap and Stack placement" superClass="com.crt.advproject.link.memory.heapAndStack.style" useByScannerDiscovery="false" valueType="enumerated"/>
<option id="com.crt.advproject.link.memory.heapAndStack.581254503" name="Heap and Stack options" superClass="com.crt.advproject.link.memory.heapAndStack" value="&amp;Heap:Default;Post Data;Default&amp;Stack:Default;End;Default" valueType="string"/> <option id="com.crt.advproject.link.memory.heapAndStack.581254503" name="Heap and Stack options" superClass="com.crt.advproject.link.memory.heapAndStack" value="&amp;Heap:Default;Post Data;Default&amp;Stack:Default;End;Default" valueType="string"/>
<option id="com.crt.advproject.link.memory.data.1422954448" name="Global data placement" superClass="com.crt.advproject.link.memory.data" useByScannerDiscovery="false" value="" valueType="string"/> <option id="com.crt.advproject.link.memory.data.1422954448" name="Global data placement" superClass="com.crt.advproject.link.memory.data" useByScannerDiscovery="false" value="Default" valueType="string"/>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="true" id="com.crt.advproject.link.memory.sections.3963713" name="Extra linker script input sections" superClass="com.crt.advproject.link.memory.sections" useByScannerDiscovery="false" valueType="stringList"/> <option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="true" id="com.crt.advproject.link.memory.sections.3963713" name="Extra linker script input sections" superClass="com.crt.advproject.link.memory.sections" useByScannerDiscovery="false" valueType="stringList"/>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="true" id="com.crt.advproject.link.gcc.multicore.master.userobjs.2124723269" name="Slave Objects (not visible)" superClass="com.crt.advproject.link.gcc.multicore.master.userobjs" useByScannerDiscovery="false" valueType="userObjs"/> <option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="true" id="com.crt.advproject.link.gcc.multicore.master.userobjs.2124723269" name="Slave Objects (not visible)" superClass="com.crt.advproject.link.gcc.multicore.master.userobjs" useByScannerDiscovery="false" valueType="userObjs"/>
<option id="com.crt.advproject.link.gcc.multicore.slave.1241419045" name="Multicore configuration" superClass="com.crt.advproject.link.gcc.multicore.slave"/> <option id="com.crt.advproject.link.gcc.multicore.slave.1241419045" name="Multicore configuration" superClass="com.crt.advproject.link.gcc.multicore.slave"/>
@ -329,8 +327,8 @@
<option id="com.crt.advproject.link.gcc.lto.2006844944" name="Enable Link-time optimization (-flto)" superClass="com.crt.advproject.link.gcc.lto"/> <option id="com.crt.advproject.link.gcc.lto.2006844944" name="Enable Link-time optimization (-flto)" superClass="com.crt.advproject.link.gcc.lto"/>
<option id="com.crt.advproject.link.gcc.lto.optmization.level.1416309801" name="Link-time optimization level" superClass="com.crt.advproject.link.gcc.lto.optmization.level"/> <option id="com.crt.advproject.link.gcc.lto.optmization.level.1416309801" name="Link-time optimization level" superClass="com.crt.advproject.link.gcc.lto.optmization.level"/>
<option id="com.crt.advproject.link.manage.2050229701" name="Manage linker script" superClass="com.crt.advproject.link.manage" value="true" valueType="boolean"/> <option id="com.crt.advproject.link.manage.2050229701" name="Manage linker script" superClass="com.crt.advproject.link.manage" value="true" valueType="boolean"/>
<option id="com.crt.advproject.link.script.788371422" name="Linker script" superClass="com.crt.advproject.link.script" value="ADIS_tinyK22_Blinky_Debug.ld" valueType="string"/> <option id="com.crt.advproject.link.script.788371422" name="Linker script" superClass="com.crt.advproject.link.script" useByScannerDiscovery="false" value="ADIS_tinyK22_SplitFlap_Debug.ld" valueType="string"/>
<option id="com.crt.advproject.link.scriptdir.973298735" name="Script path" superClass="com.crt.advproject.link.scriptdir"/> <option id="com.crt.advproject.link.scriptdir.973298735" name="Script path" superClass="com.crt.advproject.link.scriptdir" useByScannerDiscovery="false" value="" valueType="string"/>
<option id="com.crt.advproject.link.crpenable.827328657" name="Enable automatic placement of Code Read Protection field in image" superClass="com.crt.advproject.link.crpenable"/> <option id="com.crt.advproject.link.crpenable.827328657" name="Enable automatic placement of Code Read Protection field in image" superClass="com.crt.advproject.link.crpenable"/>
<option id="com.crt.advproject.link.flashconfigenable.1185095849" name="Enable automatic placement of Flash Configuration field in image" superClass="com.crt.advproject.link.flashconfigenable" value="true" valueType="boolean"/> <option id="com.crt.advproject.link.flashconfigenable.1185095849" name="Enable automatic placement of Flash Configuration field in image" superClass="com.crt.advproject.link.flashconfigenable" value="true" valueType="boolean"/>
<option id="com.crt.advproject.link.ecrp.335964278" name="Enhanced CRP" superClass="com.crt.advproject.link.ecrp"/> <option id="com.crt.advproject.link.ecrp.335964278" name="Enhanced CRP" superClass="com.crt.advproject.link.ecrp"/>
@ -798,7 +796,9 @@
</storageModule> </storageModule>
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/> <storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
<storageModule moduleId="refreshScope" versionNumber="2"> <storageModule moduleId="refreshScope" versionNumber="2">
<configuration configurationName="Debug"/> <configuration configurationName="Debug">
<resource resourceType="PROJECT" workspacePath="/ADIS_tinyK22_SplitFlap"/>
</configuration>
<configuration configurationName="Release"> <configuration configurationName="Release">
<resource resourceType="PROJECT" workspacePath="/ADIS_tinyK22_Blinky"/> <resource resourceType="PROJECT" workspacePath="/ADIS_tinyK22_Blinky"/>
</configuration> </configuration>

@ -55,10 +55,6 @@ void App_Init(void){
static void App_Task(void* pv){ static void App_Task(void* pv){
McuLog_info("Application Task starting"); McuLog_info("Application Task starting");
while(1){
vTaskDelay(pdMS_TO_TICKS(100));
}
PRINTF("Initializing split flap motors.\n"); PRINTF("Initializing split flap motors.\n");
bool successfulInit0 = SF_MoveMotorToZeroPosition(splitflap0, 20); bool successfulInit0 = SF_MoveMotorToZeroPosition(splitflap0, 20);
PRINTF("Init of motor 0 done. Success = %s\n\n", successfulInit0 ? "true" : "false"); PRINTF("Init of motor 0 done. Success = %s\n\n", successfulInit0 ? "true" : "false");
@ -82,7 +78,7 @@ static void App_Task(void* pv){
/* MULTI SPLIT FLAP TESTING */ /* MULTI SPLIT FLAP TESTING */
char sentence[] = "JONAS!"; char sentence[] = "JONAS!";
//MultiSplitFlap_Display(sentence); MultiSplitFlap_Display(sentence);
return; return;

@ -9,14 +9,20 @@
#include <stdbool.h> #include <stdbool.h>
#include "multi-splitflap.h" #include "multi-splitflap.h"
#include "fsl_debug_console.h" #include "fsl_debug_console.h"
#include "splitflap.h"
/* vars */
static dict_t **flapDict; static dict_t **flapDict;
static uint8_t addedFlaps = 0; static uint8_t addedFlaps = 0;
static const uint8_t BYTES_PER_KEY = 3; static const uint8_t BYTES_PER_KEY = 3;
static char* flapKeys[NUM_FLAPS]; // reserve memory static char* flapKeys[NUM_FLAPS]; // reserve memory
/* function declarations */
void initFlapKeys(uint8_t numberOfFlaps); void initFlapKeys(uint8_t numberOfFlaps);
/**********************/
/* INIT / DEINIT */
/**********************/
void MultiSplitFlap_Init(){ void MultiSplitFlap_Init(){
addedFlaps = 0; addedFlaps = 0;
flapDict = dictAlloc(); flapDict = dictAlloc();
@ -26,29 +32,14 @@ void MultiSplitFlap_Init(){
initFlapKeys(NUM_FLAPS); initFlapKeys(NUM_FLAPS);
} }
void initFlapKeys(uint8_t numberOfFlaps){
for (uint8_t i = 0; i < numberOfFlaps; ++i) {
/* get a memory place for the key */
#if SPLITFLAP_CONFIG_USE_FREERTOS_HEAP
flapKeys[i] = pvPortMalloc(sizeof(BYTES_PER_KEY));
#else
if((flapKeys[i] = malloc(BYTES_PER_KEY)) == NULL){
PRINTF("Reserving memory for flap num. %i failed!:\n", i);
}
sprintf(flapKeys[i], "%i", i);
#endif
}
}
void MultiSplitFlap_Deinit(void){ void MultiSplitFlap_Deinit(void){
dictDealoc(flapDict); dictDealoc(flapDict);
addedFlaps = 0; addedFlaps = 0;
} }
uint8_t MultiSplitFlap_GetAmountOfAddedSplitFlaps(void){ /**********************/
return addedFlaps; /* PUBLIC FUNCTIONS */
} /**********************/
void MultiSplitFlap_AddFlap(SF_Handle_t splitflap){ void MultiSplitFlap_AddFlap(SF_Handle_t splitflap){
PRINTF("Adding split flap to multi splitflap combination...\n"); PRINTF("Adding split flap to multi splitflap combination...\n");
addItem(flapDict, flapKeys[addedFlaps], (SF_Handle_t*)splitflap); addItem(flapDict, flapKeys[addedFlaps], (SF_Handle_t*)splitflap);
@ -59,8 +50,11 @@ void MultiSplitFlap_AddFlap(SF_Handle_t splitflap){
void MultiSplitFlap_Display(char sentence[]){ void MultiSplitFlap_Display(char sentence[]){
for (uint8_t num = 0; num < NUM_FLAPS; ++num) { for (uint8_t num = 0; num < NUM_FLAPS; ++num) {
SF_Handle_t sfHandle = (SF_Handle_t)(getItem(*flapDict, flapKeys[num])); SF_Handle_t sfHandle = (SF_Handle_t)(getItem(*flapDict, flapKeys[num]));
SF_MoveToFlapAsync(sfHandle, (char*)(sentence[num])); char letter = sentence[num];
PRINTF("Moved multisplitflap: Flap nr. %i to letter '%c'.\n", num+1, sentence[num]); char letter_move[] = " ";
letter_move[0] = letter;
SF_MoveToFlapAsync(sfHandle, letter_move);
PRINTF("Multi splitflap: Commanded Flap nr. %i to letter '%c'.\n", num+1, letter);
} }
// for testing purposes only // for testing purposes only
//SF_t* sf0 = (SF_t*)(SF_Handle_t)(getItem(*flapDict, flapKeys[0])); //SF_t* sf0 = (SF_t*)(SF_Handle_t)(getItem(*flapDict, flapKeys[0]));
@ -68,4 +62,23 @@ void MultiSplitFlap_Display(char sentence[]){
//int32_t test = McuULN2003_GetPos(sf1->motor); //int32_t test = McuULN2003_GetPos(sf1->motor);
} }
uint8_t MultiSplitFlap_GetAmountOfAddedSplitFlaps(void){
return addedFlaps;
}
/**********************/
/* INTERNAL FUNCTIONS */
/**********************/
void initFlapKeys(uint8_t numberOfFlaps){
for (uint8_t i = 0; i < numberOfFlaps; ++i) {
/* get a memory place for the key */
#if SPLITFLAP_CONFIG_USE_FREERTOS_HEAP
flapKeys[i] = pvPortMalloc(sizeof(BYTES_PER_KEY));
#else
if((flapKeys[i] = malloc(BYTES_PER_KEY)) == NULL){
PRINTF("Reserving memory for flap num. %i failed!:\n", i);
}
sprintf(flapKeys[i], "%i", i);
#endif
}
}

@ -19,19 +19,19 @@
/* 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 */
static char* SF_Letters[] = { " ", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", static Flap_t SF_Letters[] = { " ", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K",
"L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
"!", "?", ":"}; "!", "?", ":"};
/* 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 */ /* function declarations */
static bool OngoingMoveMutex_Lock(void); static bool OngoingMoveMutex_Lock(SF_Handle_t instance);
static void OngoingMoveMutex_Unlock(void); static void OngoingMoveMutex_Unlock(SF_Handle_t instance);
static void SF_MoveToNextFlap(void *pv);
/**********************/
/* INIT / DEINIT */
/**********************/
void SF_InitConfig(void){ void SF_InitConfig(void){
splitFlapDict = dictAlloc(); splitFlapDict = dictAlloc();
((dict_t*)splitFlapDict)->key=NULL; ((dict_t*)splitFlapDict)->key=NULL;
@ -66,20 +66,33 @@ 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->id = id;
splitflap->ongoingMoveMutex = xSemaphoreCreateRecursiveMutex(); // create mutex for ongoing move
splitflap->initialized = false;
splitflap->nextFlap = SF_Letters[0];
// create mutex for ongoing move // add mutex to registry
ongoingMoveMutex = xSemaphoreCreateRecursiveMutex();
char text[50] = "Ongoing move SplitFlap "; char text[50] = "Ongoing move SplitFlap ";
McuUtility_strcatNum16s((uint8_t*)text, sizeof(text)+20, id); McuUtility_strcatNum16s((uint8_t*)text, sizeof(text)+20, id);
vQueueAddToRegistry(ongoingMoveMutex, text); vQueueAddToRegistry(splitflap->ongoingMoveMutex, text);
return splitflap; return splitflap;
} }
void SF_Deinit(SF_Handle_t instance){
vSemaphoreDelete(((SF_t*)instance)->ongoingMoveMutex);
((SF_t*)instance)->initialized = false;
McuULN2003_DeinitMotor(((SF_t*)instance)->motor);
McuGPIO_DeinitGPIO(((SF_t*)instance)->magSensor);
}
/**********************/
/* PUBLIC FUNCTIONS */
/**********************/
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(OngoingMoveMutex_Lock()){ 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){
McuULN2003_IncStep(((SF_t*)instance)->motor); McuULN2003_IncStep(((SF_t*)instance)->motor);
@ -103,19 +116,18 @@ bool SF_MoveMotorToZeroPosition(SF_Handle_t instance, uint16_t offsetSteps){
McuULN2003_SetPos(((SF_t*)instance)->motor, 0); McuULN2003_SetPos(((SF_t*)instance)->motor, 0);
McuULN2003_PowerOff(((SF_t*)instance)->motor); McuULN2003_PowerOff(((SF_t*)instance)->motor);
OngoingMoveMutex_Unlock(); OngoingMoveMutex_Unlock(instance);
} }
// success if less than one rotation // success if less than one rotation
initialized = (numStepsMoved < SPLITFLAP_STEPS_ONE_ROUND); ((SF_t*)instance)->initialized = (numStepsMoved < SPLITFLAP_STEPS_ONE_ROUND);
return initialized; return ((SF_t*)instance)->initialized;
} }
void SF_MoveSteps(SF_Handle_t instance, uint32_t steps){ void SF_MoveSteps(SF_Handle_t instance, uint32_t steps){
if(initialized){ if(((SF_t*)instance)->initialized){
if(OngoingMoveMutex_Lock(instance)){
if(OngoingMoveMutex_Lock()){
// run move with acceleration & deceleration // run move with acceleration & deceleration
McuULN2003_AccelerationStart(((SF_t*)instance)->motor); McuULN2003_AccelerationStart(((SF_t*)instance)->motor);
while(steps>0){ while(steps>0){
@ -131,7 +143,7 @@ void SF_MoveSteps(SF_Handle_t instance, uint32_t steps){
// no re-init is required // no re-init is required
McuULN2003_PowerOff(((SF_t*)instance)->motor); McuULN2003_PowerOff(((SF_t*)instance)->motor);
OngoingMoveMutex_Unlock(); OngoingMoveMutex_Unlock(instance);
} }
} }
} }
@ -140,8 +152,8 @@ bool SF_GetMagSensorAtZeroPosition(SF_Handle_t instance){
return McuGPIO_IsLow(((SF_t*)instance)->magSensor); return McuGPIO_IsLow(((SF_t*)instance)->magSensor);
} }
void SF_MoveToFlap(SF_Handle_t instance, char* flap){ void SF_MoveToFlap(SF_Handle_t instance, Flap_t flap){
if(OngoingMoveMutex_Lock()){ if(OngoingMoveMutex_Lock(instance)){
// get flap pos from dictonary // get flap pos from dictonary
int32_t flapPos = (int32_t)getItem(*splitFlapDict, flap); int32_t flapPos = (int32_t)getItem(*splitFlapDict, flap);
@ -159,38 +171,23 @@ void SF_MoveToFlap(SF_Handle_t instance, char* flap){
SF_MoveSteps(instance, stepsToReachFlap); SF_MoveSteps(instance, stepsToReachFlap);
} }
OngoingMoveMutex_Unlock(); OngoingMoveMutex_Unlock(instance);
} }
} }
typedef struct{ void SF_MoveToFlapAsync(SF_Handle_t instance, Flap_t flap){
SF_Handle_t instance; if(OngoingMoveMutex_Lock(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; BaseType_t res;
char taskName[50] = "SF Mv "; char taskName[10] = "SF Mv ";
McuUtility_strcatNum16s((uint8_t*)taskName, sizeof(taskName)+20, ((SF_t*)instance)->id); McuUtility_strcatNum16s((uint8_t*)taskName, sizeof(taskName), ((SF_t*)instance)->id);
taskParameters.instance = instance; // set next flap
taskParameters.flap = flap; ((SF_t*)instance)->nextFlap = flap;
res = xTaskCreate( SF_MoveToFlapWithParameter, res = xTaskCreate( SF_MoveToNextFlap,
taskName, taskName,
500/sizeof(StackType_t), 500/sizeof(StackType_t),
&taskParameters, instance, // no &, since otherwise pointing on parameter address! we want handle address!
tskIDLE_PRIORITY, tskIDLE_PRIORITY,
NULL); NULL);
@ -200,7 +197,7 @@ void SF_MoveToFlapAsync(SF_Handle_t instance, char* flap){
for(;;) {} // Endless loop for(;;) {} // Endless loop
} }
OngoingMoveMutex_Unlock(); OngoingMoveMutex_Unlock(instance);
} }
} }
@ -208,28 +205,37 @@ int32_t SF_GetMotorPosition(SF_Handle_t instance){
return McuULN2003_GetPos(((SF_t*)instance)->motor); return McuULN2003_GetPos(((SF_t*)instance)->motor);
} }
void SF_Deinit(SF_Handle_t instance){ /**********************/
vSemaphoreDelete(ongoingMoveMutex); /* INTERNAL FUNCTIONS */
McuULN2003_DeinitMotor(((SF_t*)instance)->motor); /**********************/
McuGPIO_DeinitGPIO(((SF_t*)instance)->magSensor); /* voidpointer to instance of splitflap (SF_Handle_t) */
initialized = false; static void SF_MoveToNextFlap(void *pv){
// parse parameter
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]);
// move to next flap
SF_MoveToFlap(instance, ((SF_t*)instance)->nextFlap);
// reset next flap
((SF_t*)instance)->nextFlap = SF_Letters[0];
} }
/**********************/
/* HELPERS */ /* HELPERS */
static bool OngoingMoveMutex_Lock(void){ /**********************/
static bool OngoingMoveMutex_Lock(SF_Handle_t instance){
/* aquire mutex */ /* aquire mutex */
if(xSemaphoreTakeRecursive(ongoingMoveMutex, pdMS_TO_TICKS(20)) != pdTRUE){ if(xSemaphoreTakeRecursive(((SF_t*)instance)->ongoingMoveMutex, pdMS_TO_TICKS(20)) != pdTRUE){
return false; /* timeout? */ return false; /* timeout? */
} }
return true; return true;
} }
static void OngoingMoveMutex_Unlock(void){ static void OngoingMoveMutex_Unlock(SF_Handle_t instance){
/* give back mutex */ /* give back mutex */
if(xSemaphoreGiveRecursive(ongoingMoveMutex) != pdTRUE){ if(xSemaphoreGiveRecursive(((SF_t*)instance)->ongoingMoveMutex) != pdTRUE){
/* issue */ /* issue */
PRINTF("Could not give back ongoing move mutex for splitflap"); PRINTF("Could not give back ongoing move mutex for splitflap %i", ((SF_t*)instance)->id);
for(;;); for(;;);
} }
} }

@ -11,6 +11,7 @@
#include <stdbool.h> #include <stdbool.h>
#include "McuULN2003.h" #include "McuULN2003.h"
#include "McuGPIO.h" #include "McuGPIO.h"
#include "McuRTOS.h"
#include "lib/dict.h" #include "lib/dict.h"
#include <string.h> #include <string.h>
@ -26,10 +27,16 @@
/* define splitflap handle type. SF_Handle_t points to SF_t */ /* define splitflap handle type. SF_Handle_t points to SF_t */
typedef void* SF_Handle_t; typedef void* SF_Handle_t;
/* descriptor to identify the flap */
typedef char* Flap_t;
typedef struct { typedef struct {
int id;
McuULN2003_Handle_t motor; McuULN2003_Handle_t motor;
McuGPIO_Handle_t magSensor; McuGPIO_Handle_t magSensor;
int id; SemaphoreHandle_t ongoingMoveMutex;
bool initialized;
Flap_t nextFlap;
} SF_t; } SF_t;
typedef struct { typedef struct {
@ -63,10 +70,10 @@ void SF_MoveSteps(SF_Handle_t instance, uint32_t steps);
bool SF_GetMagSensorAtZeroPosition(SF_Handle_t instance); bool SF_GetMagSensorAtZeroPosition(SF_Handle_t instance);
/* move to specific flap */ /* move to specific flap */
void SF_MoveToFlap(SF_Handle_t instance, char* flap); void SF_MoveToFlap(SF_Handle_t instance, Flap_t flap);
/* move to specific flap asynchronously (RTOS task) */ /* move to specific flap asynchronously (RTOS task) */
void SF_MoveToFlapAsync(SF_Handle_t instance, char* flap); void SF_MoveToFlapAsync(SF_Handle_t instance, Flap_t flap);
/* get current position of motor */ /* get current position of motor */
int32_t SF_GetMotorPosition(SF_Handle_t instance); int32_t SF_GetMotorPosition(SF_Handle_t instance);

Loading…
Cancel
Save