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.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 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}/device}&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/lists}&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;${MCULIB}/&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.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.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 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.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"/>
@ -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.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.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.scriptdir.973298735" name="Script path" superClass="com.crt.advproject.link.scriptdir"/>
<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" 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.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"/>
@ -798,7 +796,9 @@
</storageModule>
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
<storageModule moduleId="refreshScope" versionNumber="2">
<configuration configurationName="Debug"/>
<configuration configurationName="Debug">
<resource resourceType="PROJECT" workspacePath="/ADIS_tinyK22_SplitFlap"/>
</configuration>
<configuration configurationName="Release">
<resource resourceType="PROJECT" workspacePath="/ADIS_tinyK22_Blinky"/>
</configuration>

@ -55,10 +55,6 @@ void App_Init(void){
static void App_Task(void* pv){
McuLog_info("Application Task starting");
while(1){
vTaskDelay(pdMS_TO_TICKS(100));
}
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");
@ -82,7 +78,7 @@ static void App_Task(void* pv){
/* MULTI SPLIT FLAP TESTING */
char sentence[] = "JONAS!";
//MultiSplitFlap_Display(sentence);
MultiSplitFlap_Display(sentence);
return;

@ -9,14 +9,20 @@
#include <stdbool.h>
#include "multi-splitflap.h"
#include "fsl_debug_console.h"
#include "splitflap.h"
/* vars */
static dict_t **flapDict;
static uint8_t addedFlaps = 0;
static const uint8_t BYTES_PER_KEY = 3;
static char* flapKeys[NUM_FLAPS]; // reserve memory
/* function declarations */
void initFlapKeys(uint8_t numberOfFlaps);
/**********************/
/* INIT / DEINIT */
/**********************/
void MultiSplitFlap_Init(){
addedFlaps = 0;
flapDict = dictAlloc();
@ -26,29 +32,14 @@ void MultiSplitFlap_Init(){
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){
dictDealoc(flapDict);
addedFlaps = 0;
}
uint8_t MultiSplitFlap_GetAmountOfAddedSplitFlaps(void){
return addedFlaps;
}
/**********************/
/* PUBLIC FUNCTIONS */
/**********************/
void MultiSplitFlap_AddFlap(SF_Handle_t splitflap){
PRINTF("Adding split flap to multi splitflap combination...\n");
addItem(flapDict, flapKeys[addedFlaps], (SF_Handle_t*)splitflap);
@ -59,8 +50,11 @@ void MultiSplitFlap_AddFlap(SF_Handle_t splitflap){
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_MoveToFlapAsync(sfHandle, (char*)(sentence[num]));
PRINTF("Moved multisplitflap: Flap nr. %i to letter '%c'.\n", num+1, sentence[num]);
char letter = 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
//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);
}
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 */
static dict_t **splitFlapDict;
/* 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",
"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 */
static bool OngoingMoveMutex_Lock(void);
static void OngoingMoveMutex_Unlock(void);
static bool OngoingMoveMutex_Lock(SF_Handle_t instance);
static void OngoingMoveMutex_Unlock(SF_Handle_t instance);
static void SF_MoveToNextFlap(void *pv);
/**********************/
/* INIT / DEINIT */
/**********************/
void SF_InitConfig(void){
splitFlapDict = dictAlloc();
((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->motor = McuULN2003_InitMotor(&instance->motorConfig);
splitflap->id = id;
splitflap->ongoingMoveMutex = xSemaphoreCreateRecursiveMutex(); // create mutex for ongoing move
splitflap->initialized = false;
splitflap->nextFlap = SF_Letters[0];
// create mutex for ongoing move
ongoingMoveMutex = xSemaphoreCreateRecursiveMutex();
// add mutex to registry
char text[50] = "Ongoing move SplitFlap ";
McuUtility_strcatNum16s((uint8_t*)text, sizeof(text)+20, id);
vQueueAddToRegistry(ongoingMoveMutex, text);
vQueueAddToRegistry(splitflap->ongoingMoveMutex, text);
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){
int numStepsMoved = 0;
if(OngoingMoveMutex_Lock()){
if(OngoingMoveMutex_Lock(instance)){
// move out of sensor
while(SF_GetMagSensorAtZeroPosition((SF_t*)instance) == true){
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_PowerOff(((SF_t*)instance)->motor);
OngoingMoveMutex_Unlock();
OngoingMoveMutex_Unlock(instance);
}
// 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){
if(initialized){
if(OngoingMoveMutex_Lock()){
if(((SF_t*)instance)->initialized){
if(OngoingMoveMutex_Lock(instance)){
// run move with acceleration & deceleration
McuULN2003_AccelerationStart(((SF_t*)instance)->motor);
while(steps>0){
@ -131,7 +143,7 @@ void SF_MoveSteps(SF_Handle_t instance, uint32_t steps){
// no re-init is required
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);
}
void SF_MoveToFlap(SF_Handle_t instance, char* flap){
if(OngoingMoveMutex_Lock()){
void SF_MoveToFlap(SF_Handle_t instance, Flap_t flap){
if(OngoingMoveMutex_Lock(instance)){
// get flap pos from dictonary
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);
}
OngoingMoveMutex_Unlock();
OngoingMoveMutex_Unlock(instance);
}
}
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()){
void SF_MoveToFlapAsync(SF_Handle_t instance, Flap_t flap){
if(OngoingMoveMutex_Lock(instance)){
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;
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_MoveToFlapWithParameter,
res = xTaskCreate( SF_MoveToNextFlap,
taskName,
500/sizeof(StackType_t),
&taskParameters,
instance, // no &, since otherwise pointing on parameter address! we want handle address!
tskIDLE_PRIORITY,
NULL);
@ -200,7 +197,7 @@ void SF_MoveToFlapAsync(SF_Handle_t instance, char* flap){
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);
}
void SF_Deinit(SF_Handle_t instance){
vSemaphoreDelete(ongoingMoveMutex);
McuULN2003_DeinitMotor(((SF_t*)instance)->motor);
McuGPIO_DeinitGPIO(((SF_t*)instance)->magSensor);
initialized = false;
/**********************/
/* INTERNAL FUNCTIONS */
/**********************/
/* voidpointer to instance of splitflap (SF_Handle_t) */
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 */
static bool OngoingMoveMutex_Lock(void){
/**********************/
static bool OngoingMoveMutex_Lock(SF_Handle_t instance){
/* 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 true;
}
static void OngoingMoveMutex_Unlock(void){
static void OngoingMoveMutex_Unlock(SF_Handle_t instance){
/* give back mutex */
if(xSemaphoreGiveRecursive(ongoingMoveMutex) != pdTRUE){
if(xSemaphoreGiveRecursive(((SF_t*)instance)->ongoingMoveMutex) != pdTRUE){
/* 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(;;);
}
}

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

Loading…
Cancel
Save