/* * hal.cpp * * Created on: Aug 3, 2016 * Author: Philipp Hinz */ #include #include #include #include #include #include "hal.h" #include "global.h" #include "logger.h" #include "timer.h" int flowcnt = 0; int Int0Time; int Int1Time; bool flagIgnoreRlsInt0; bool flagIgnoreRlsInt1; timer Int0Timer(&halInt0TimerHandler); timer Int1Timer(&halInt1TimerHandler); /** * Initializes HAL */ void halInit(void) { if (optPower) { halMachineOn(); } else { halMachineOff(); } pinMode(RELAIS_HEAT, OUTPUT); pinMode(RELAIS_PUMP, OUTPUT); pinMode(RELAIS_POWER, OUTPUT); pinMode(PIN_PRESSURE_CTRL, INPUT); pinMode(PIN_PROXIMITY_SENSOR, INPUT); pinMode(PIN_INT0, INPUT); pinMode(PIN_INT1, INPUT); pinMode(PIN_FLOW, INPUT); Int0Timer.setDivider(4); //200ms Int1Timer.setDivider(4); Int0Time = 0; Int1Time = 0; flagIgnoreRlsInt0 = false; flagIgnoreRlsInt1 = false; if (wiringPiISR(PIN_INT0, INT_EDGE_BOTH, &halInt0) < 0) { logger_error("Unable to setup ISR0: %s\n", strerror(errno)); return; } if (wiringPiISR(PIN_INT1, INT_EDGE_BOTH, &halInt1) < 0) { logger_error("Unable to setup ISR1: %s\n", strerror(errno)); return; } if (wiringPiISR(PIN_FLOW, INT_EDGE_FALLING, &halIntFlow) < 0) { logger_error("Unable to setup ISRFLOW: %s\n", strerror(errno)); return; } if (wiringPiISR(PIN_PRESSURE_CTRL, INT_EDGE_BOTH, &halIntPressure) < 0) { logger_error("Unable to setup ISRPressure: %s\n", strerror(errno)); return; } if (wiringPiISR(PIN_PROXIMITY_SENSOR, INT_EDGE_BOTH, &halIntProximity) < 0) { logger_error("Unable to setup ISRProximity: %s\n", strerror(errno)); return; } } /** * Switches relais on * @param relais Relais ID */ void halRelaisOn(int relais) { halRelaisSet(relais, LOW); } /** * Switches relais off * @param relais Relais ID */ void halRelaisOff(int relais) { halRelaisSet(relais, HIGH); } /** * Switches relais to state * @param relais Relais ID * @param state LOW(0) or HIGH(1) */ void halRelaisSet(int relais, int state) { if (state != HIGH && state != LOW) return; switch (relais) { case RELAIS_POWER: case RELAIS_HEAT: case RELAIS_PUMP: digitalWrite(relais, state); break; } } /** * Returns the state of the relais relais * Returns HIGH when Relais is ON * @param relais Relais ID */ int halGetRelaisState(int relais) { switch (relais) { case RELAIS_POWER: case RELAIS_HEAT: case RELAIS_PUMP: return !digitalRead(relais); break; } return -1; } /** * Interrupt routine for Int0 (Top button) */ void halInt0(void) { logger(V_HAL, "Int0 triggered\n"); if (halGetInt0()) { if (flagIgnoreRlsInt0) { flagIgnoreRlsInt0 = false; } else { halSendSignal(SigInt0Rls); } } else { halSendSignal(SigInt0Psh); Int0Time = 0; Int0Timer.start(); } } /** * */ void halInt0TimerHandler(void) { Int0Time += 200; if (Int0Time >= (TIME_BUTTONLONGPRESS * 1000)) { halSendSignal(SigInt0RlsLong); flagIgnoreRlsInt0 = true; Int0Time = 0; Int0Timer.stop(); } } /** * Interrupt routine for Int1 (Bottom button) */ void halInt1(void) { logger(V_HAL, "Int1 triggered\n"); if (halGetInt1()) { if (flagIgnoreRlsInt1) { flagIgnoreRlsInt1 = false; } else { halSendSignal(SigInt1Rls); } } else { halSendSignal(SigInt1Psh); Int1Time = 0; Int1Timer.start(); } } /* * */ void halInt1TimerHandler(void) { Int1Time += 200; if (Int1Time >= TIME_BUTTONLONGPRESS) { halSendSignal(SigInt1RlsLong); flagIgnoreRlsInt1 = true; Int1Time = 0; Int1Timer.stop(); } } /** * Interrupt routine for the flow sensor * It counts the edgdes and stores the value in flowcnt */ void halIntFlow(void) { //halRelaisOff(RELAIS_POWER); logger(V_HAL, "IntFlow triggered #%d total: %.2fml\n", flowcnt, halGetFlow()); if (flowcnt == 99) { halRelaisOff(RELAIS_PUMP); } flowcnt++; } /** * Interrupt routine for the pressure control */ void halIntPressure(void) { logger(V_HAL, "IntPressure Control triggered\n"); if (halIsHeating()) { halSendSignal(SigPressCls); } else { halSendSignal(SigPressOpn); } } /** * Method to handle toggle of the proximity sensor */ void halIntProximity(void) { logger(V_HAL, "IntProximity triggered\n"); if (halProxSensorCovered()) { halSendSignal(SigProxCvrd); } else { halSendSignal(SigProxOpn); } } /** * Returns total flow trough sensor in ml */ float halGetFlow(void) { return flowcnt * FLOW_ML_PULSE; } /** * Resets the Flow counter */ void halResetFlow(void) { flowcnt = 0; } /** * Reads the status of the Pressure Control * @return 0 for closed Pressure Control(heating) and 1 for open */ bool halIsHeating(void) { if (digitalRead(PIN_PRESSURE_CTRL) == 0) { return true; } else { return false; } } /** * Returns status of the proximity switch * @return 1 if the proximity switch is covered and 0 if uncovered */ bool halProxSensorCovered(void) { //for legacy till sensor is installed /*if(digitalRead(PROXIMITY_SENSOR) == 0){ return false; } else { return true; }*/ return true; } /** * Returns the value of the top button Int0 (low active) * @return LOW or HIGH */ int halGetInt0(void) { return digitalRead(PIN_INT0); } /** * Returns the value of the bottom button Int1 (low active) * @return LOW or HIGH */ int halGetInt1(void) { return digitalRead(PIN_INT1); } /** * send Signal to coffee thread * @param val Integer value assigned to signal */ void halSendSignal(int val) { sigval value = { 0 }; value.sival_int = (int) val; if (pthread_sigqueue(thread[THREAD_COFFEE], SIGUSR2, value)) { logger_error("Failed to queue signal %d %s", val, strerror(errno)); //No Signals reach the state machine anymore... exit(EXIT_FAILURE); } } /** * Turn machine on */ void halMachineOn(void) { halRelaisOn(RELAIS_HEAT); halRelaisOff(RELAIS_PUMP); halRelaisOn(RELAIS_POWER); logger(V_HAL, "Turning machine on\n"); } /** * Turn machine off */ void halMachineOff(void) { halRelaisOff(RELAIS_HEAT); halRelaisOff(RELAIS_PUMP); halRelaisOff(RELAIS_POWER); logger(V_HAL, "Turning machine off\n"); }