// SPDX-License-Identifier: Apache-2.0 // Copyright (c) 2012-2024 Scott Penrose and WII5 Buoy contributors // // This file is part of WII5 Buoy firmware. // See LICENSE for full terms. /** * @file WII5Power.cpp * @brief Base class for power-managed peripherals (powerOn/powerOff state). */ /* WII5Power - Power PIN version of base class - can also be used stand alone TODO * (low) pulse - How do we have a loop function or simiar to turn off the pin after a period. * (medium) two pin - one one on, one off * (medium) shared pin - sharing a single pin (could this be done better/together) * (low) deug - approve upon the macro that is here. */ #include #include #include /* POWER PIN Debuggig This can produce an overwhelming amount of serial output Uses safeLog to prevent output on alternative serial / SD Card. Add a _PIN versio to allow logging of a single pin NOTE: This should be generalised across all the modules (different selectors) */ // #define POWERDEBUG // #define POWERDEBUG_PIN POWER_GPS_PIN #ifdef POWERDEBUG #if defined(POWERDEBUG_PIN) #define DODEBUG(...) if(powerData_Pin == POWERDEBUG_PIN) console.safeLog(LOG_DEBUG, __VA_ARGS__) #else #define DODEBUG(...) console.safeLog(LOG_DEBUG, __VA_ARGS__) #endif #else #define DODEBUG(...) (void)0 #endif // powerOn void WII5Power::powerOn(bool force) { // FATAL ERROR (can we afford to Serial print here?) if (powerData_Pin < 2) return; DODEBUG(F("Power (ON): ON request %d=%s, status=%d, force=%d"), powerData_Pin, wii5Strings.strPinWII5Name(powerData_Pin), powerData_On, force); if (powerData_Input || !powerData_On || force) { powerData_Input = false; // Shared pin if (powerData_Shared) { DODEBUG(F("Power(ON): shared requested")); powerData_Shared->powerOn(); } // Pin Modes DODEBUG(F("Power(ON): pinMode OUTPUT")); pinMode(powerData_Pin, OUTPUT); if (powerData_PinOff > 0) pinMode(powerData_PinOff, OUTPUT); DODEBUG(F("Power(ON): digitalWrite %d"), powerData_OnIsHigh ? HIGH : LOW); digitalWrite(powerData_Pin, powerData_OnIsHigh ? HIGH : LOW); if (powerData_PinOff > 0) { DODEBUG(F("Power(ON): WARNING - Untested PinOff Code")); digitalWrite(powerData_PinOff, powerData_OnIsHigh ? LOW : HIGH); } // Variables powerData_Elapsed = 0; powerData_Last = now(); powerData_On = true; // Status // setStatus(WII5STATUS_ON); } DODEBUG(F("Power(ON) : Actual=%d OnIs=%d"), digitalRead(powerData_Pin), powerData_OnIsHigh); } // powerInput - Turn this pin back into an input - either for safety or sleep void WII5Power::powerInput() { powerData_Input = true; pinMode(powerData_Pin, INPUT); } // powerOff void WII5Power::powerOff(bool force) { if (powerData_Pin < 2) return; DODEBUG(F("Power (OFF): OFF request %d=%s, status=%d, force=%d"), powerData_Pin, wii5Strings.strPinWII5Name(powerData_Pin), powerData_On, force); if (powerData_Input || powerData_On || force) { powerData_Input = false; // Shared pin if (powerData_Shared) powerData_Shared->powerOff(); // Local pin DODEBUG(F("Power(OFF): pinMode OUTPUT")); pinMode(powerData_Pin, OUTPUT); if (powerData_PinOff > 0) pinMode(powerData_PinOff, OUTPUT); // Output DODEBUG(F("Power(OFF): digitalWrite %d"), powerData_OnIsHigh ? HIGH : LOW); digitalWrite(powerData_Pin, powerData_OnIsHigh ? LOW : HIGH); if (powerData_PinOff > 0) digitalWrite(powerData_PinOff, powerData_OnIsHigh ? HIGH : LOW); // Variables (caclulate totals) powerData_LastTotal = int(powerData_Elapsed / 1000); powerData_Elapsed = 0; powerData_Last = now(); powerData_On = false; // Status // setStatus(WII5STATUS_OFF); } DODEBUG(F("Power(OFF) : Actual=%d OnIs=%d"), digitalRead(powerData_Pin), powerData_OnIsHigh); } void WII5Power::powerSetPin(uint8_t p, bool onHigh, uint8_t pOff, uint8_t pulse) { powerData_Pin = p; powerData_OnIsHigh = onHigh; powerData_PinOff = pOff; powerData_Pulse = pulse; powerData_Input = true; powerData_On = false; powerData_Elapsed = 0; powerData_Last = 0; powerData_LastTotal = 0; powerData_Shared = NULL; } void WII5Power::powerSetShared(WII5Power *s) { powerData_Shared = s; } // Status and output bool WII5Power::powerStatus() { // NOTE: This is not accurate if the pin as still an INPUT return powerData_On; } uint32_t WII5Power::powerLast() { return powerData_Last; } uint32_t WII5Power::powerElapsed() { return powerData_Elapsed; } uint32_t WII5Power::powerLastTotal() { return powerData_LastTotal; }