/* #include * splitflap.c * * Created on: 29.09.2022 * Author: jonas */ #include "splitflap.h" #include "McuULN2003.h" #include #include "McuWait.h" #include "lib/dict.h" #include "splitflap_flaps.h" dict_t **splitFlapDict; void SF_InitConfig(void){ splitFlapDict = dictAlloc(); ((dict_t*)splitFlapDict)->key=NULL; ((dict_t*)splitFlapDict)->value=NULL; ((dict_t*)splitFlapDict)->next=NULL; addItem(splitFlapDict, SF_A, 0); addItem(splitFlapDict, SF_B, 0); addItem(splitFlapDict, SF_C, 0); addItem(splitFlapDict, SF_D, 0); addItem(splitFlapDict, SF_E, 0); addItem(splitFlapDict, SF_F, 0); addItem(splitFlapDict, SF_G, 0); addItem(splitFlapDict, SF_H, 0); addItem(splitFlapDict, SF_J, 0); addItem(splitFlapDict, SF_K, 0); addItem(splitFlapDict, SF_L, 0); addItem(splitFlapDict, SF_M, 0); addItem(splitFlapDict, SF_N, 0); addItem(splitFlapDict, SF_O, 0); addItem(splitFlapDict, SF_P, 0); addItem(splitFlapDict, SF_Q, 0); addItem(splitFlapDict, SF_R, 0); addItem(splitFlapDict, SF_S, 0); addItem(splitFlapDict, SF_T, 0); addItem(splitFlapDict, SF_U, 0); addItem(splitFlapDict, SF_V, 0); addItem(splitFlapDict, SF_W, 0); addItem(splitFlapDict, SF_X, 0); addItem(splitFlapDict, SF_Y, 0); addItem(splitFlapDict, SF_Z, 0); addItem(splitFlapDict, SF_0, 0); addItem(splitFlapDict, SF_1, 0); addItem(splitFlapDict, SF_2, 0); addItem(splitFlapDict, SF_3, 0); addItem(splitFlapDict, SF_4, 0); addItem(splitFlapDict, SF_5, 0); addItem(splitFlapDict, SF_6, 0); addItem(splitFlapDict, SF_7, 0); addItem(splitFlapDict, SF_8, 0); addItem(splitFlapDict, SF_9, 0); addItem(splitFlapDict, SF_EXCLAMATION, 0); addItem(splitFlapDict, SF_QUESTION, 0); addItem(splitFlapDict, SF_COLON, 0); addItem(splitFlapDict, SF_SPACE, 0); } void SF_DeInitConfig(void){ dictDealoc(splitFlapDict); } SF_Handle_t SF_Init(SF_Config_t* instance, int id){ SF_t* splitflap; #if SPLITFLAP_CONFIG_USE_FREERTOS_HEAP splitflap = (SF_t*)pvPortMalloc(sizeof(SF_t)); /* get a new device descriptor */ #else splitflap = (SF_t*)malloc(sizeof(SF_t)); /* get a new device descriptor */ #endif splitflap->magSensor = McuGPIO_InitGPIO(&instance->magSensorConfig); splitflap->motor = McuULN2003_InitMotor(&instance->motorConfig); splitflap->id = id; /* TODO IMPLEMENT ACTUAL INITIALIZATION of Motor */ return splitflap; } bool SF_MoveMotorToZeroPosition(SF_Handle_t instance){ 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 while(SF_GetMagSensorAtZeroPosition((SF_t*)instance) == false && numStepsMoved < SPLITFLAP_STEPS_ONE_ROUND ){ McuULN2003_IncStep(((SF_t*)instance)->motor); McuWait_Waitms(20); numStepsMoved++; } // one more segment if not already one round if(numStepsMoved < SPLITFLAP_STEPS_ONE_ROUND){ for(int i=0; imotor); McuWait_Waitms(20); numStepsMoved++; } } McuULN2003_SetPos(((SF_t*)instance)->motor, 0); McuULN2003_PowerOff(((SF_t*)instance)->motor); // success if less than one rotation return numStepsMoved < SPLITFLAP_STEPS_ONE_ROUND; } void SF_MoveSteps(SF_Handle_t instance, int32_t steps){ // run move with acceleration & deceleration McuULN2003_AccelerationStart(((SF_t*)instance)->motor); while(steps>0){ if(McuULN2003_StepCallback(((SF_t*)instance)->motor, true) == true){ steps--; } McuWait_Waitms(1); } 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); } bool SF_GetMagSensorAtZeroPosition(SF_Handle_t instance){ return McuGPIO_IsLow(((SF_t*)instance)->magSensor); } 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 = McuULN2003_GetPos(((SF_t*)instance)->motor); // calc steps to move int32_t stepsToReachFlap = 0; if(flapPos == currentPos){ if(flapPos < currentPos){ stepsToReachFlap = SPLITFLAP_STEPS_ONE_ROUND-currentPos+flapPos; }else if(flapPos > currentPos){ stepsToReachFlap = flapPos - currentPos; } SF_MoveSteps(((SF_t*)instance)->motor, stepsToReachFlap); } } void SF_Deinit(SF_Handle_t instance){ McuULN2003_DeinitMotor(((SF_t*)instance)->motor); McuGPIO_DeinitGPIO(((SF_t*)instance)->magSensor); }