From 48a0254f1342b13d0e49dd0f9bf1441a373f60cf Mon Sep 17 00:00:00 2001 From: Ray Jones Date: Wed, 7 Aug 2019 22:04:20 +1000 Subject: [PATCH] Can now define the operation mode for each GPIO line individually. Need to test actual functionality, GUI OK. --- src/Afterburner.cpp | 45 +++++--- src/OLED/GPIOScreen.cpp | 187 ++++++++++++++++++++++----------- src/OLED/VersionInfoScreen.cpp | 10 -- src/Utility/BTC_GPIO.cpp | 121 +++++++++++++++------ src/Utility/BTC_GPIO.h | 89 +++++++++++----- src/Utility/BTC_JSON.cpp | 6 +- src/Utility/NVStorage.cpp | 43 +++++++- src/Utility/NVStorage.h | 18 ++-- 8 files changed, 363 insertions(+), 156 deletions(-) diff --git a/src/Afterburner.cpp b/src/Afterburner.cpp index 563a6b1..70b75a8 100644 --- a/src/Afterburner.cpp +++ b/src/Afterburner.cpp @@ -1373,12 +1373,12 @@ void setupGPIO() // V2.0+ PCBs use an input transistor buffer. Active state into ESP32 is HIGH (inverted). int activePinState = (BoardRevision == 10) ? LOW : HIGH; int Input1 = BoardRevision == 20 ? GPIOin1_pinV20 : GPIOin1_pinV21V10; - GPIOin.begin(Input1, GPIOin2_pin, NVstore.getUserSettings().GPIO.inMode, activePinState); + GPIOin.begin(Input1, GPIOin2_pin, NVstore.getUserSettings().GPIO.in1Mode, NVstore.getUserSettings().GPIO.in2Mode, activePinState); // GPIO out is always active high from ESP32 // V1.0 PCBs only expose the bare pins // V2.0+ PCBs provide an open collector output that conducts when active - GPIOout.begin(GPIOout1_pin, GPIOout2_pin, NVstore.getUserSettings().GPIO.outMode); + GPIOout.begin(GPIOout1_pin, GPIOout2_pin, NVstore.getUserSettings().GPIO.out1Mode, NVstore.getUserSettings().GPIO.out2Mode); // ### MAJOR ISSUE WITH ADC INPUTS ### // @@ -1407,27 +1407,44 @@ void setupGPIO() pinMode(GPIOin1_pinV20, INPUT_PULLUP); pinMode(GPIOout1_pin, INPUT_PULLUP); pinMode(GPIOout2_pin, INPUT_PULLUP); - GPIOin.begin(0, 0, GPIOinNone, LOW); // ensure modes disabled (should already be by constructors) - GPIOout.begin(0, 0, GPIOoutNone); + GPIOin.begin(0, 0, GPIOin1None, GPIOin2None, LOW); // ensure modes disabled (should already be by constructors) + GPIOout.begin(0, 0, GPIOout1None, GPIOout2None); GPIOalg.begin(ADC1_CHANNEL_5, GPIOalgNone); } } bool toggleGPIOout(int channel) { - if(NVstore.getUserSettings().GPIO.outMode == GPIOoutUser) { - setGPIOout(channel, !getGPIOout(channel)); // toggle selected GPIO output - return true; + if(channel == 0) { + if(NVstore.getUserSettings().GPIO.out1Mode == GPIOout1User) { + setGPIOout(channel, !getGPIOout(channel)); // toggle selected GPIO output + return true; + } + } + else if(channel == 1) { + if(NVstore.getUserSettings().GPIO.out2Mode == GPIOout2User) { + setGPIOout(channel, !getGPIOout(channel)); // toggle selected GPIO output + return true; + } } return false; } bool setGPIOout(int channel, bool state) { - if(GPIOout.getMode() != GPIOoutNone) { - DebugPort.printf("setGPIO: Output #%d = %d\r\n", channel+1, state); - GPIOout.setState(channel, state); - return true; + if(channel == 0) { + if(GPIOout.getMode1() != GPIOout1None) { + DebugPort.printf("setGPIO: Output #%d = %d\r\n", channel+1, state); + GPIOout.setState(channel, state); + return true; + } + } + else if(channel == 1) { + if(GPIOout.getMode2() != GPIOout2None) { + DebugPort.printf("setGPIO: Output #%d = %d\r\n", channel+1, state); + GPIOout.setState(channel, state); + return true; + } } return false; } @@ -1526,8 +1543,10 @@ void getGPIOinfo(sGPIO& info) info.outState[0] = GPIOout.getState(0); info.outState[1] = GPIOout.getState(1); info.algVal = GPIOalg.getValue(); - info.inMode = GPIOin.getMode(); - info.outMode = GPIOout.getMode(); + info.in1Mode = GPIOin.getMode1(); + info.in2Mode = GPIOin.getMode2(); + info.out1Mode = GPIOout.getMode1(); + info.out2Mode = GPIOout.getMode2(); info.algMode = GPIOalg.getMode(); } diff --git a/src/OLED/GPIOScreen.cpp b/src/OLED/GPIOScreen.cpp index 7e23498..c48c297 100644 --- a/src/OLED/GPIOScreen.cpp +++ b/src/OLED/GPIOScreen.cpp @@ -42,14 +42,16 @@ extern CGPIOalg GPIOalg; static const int Line3 = 14; static const int Line2 = 27; static const int Line1 = 40; -//static const int Column = 58; -static const int Column = 38; +static const int Column1 = 26; +static const int Column2 = 85; CGPIOScreen::CGPIOScreen(C128x64_OLED& display, CScreenManager& mgr) : CPasswordScreen(display, mgr) { _initUI(); - _GPIOparams.inMode = GPIOinNone; - _GPIOparams.outMode = GPIOoutNone; + _GPIOparams.in1Mode = GPIOin1None; + _GPIOparams.in2Mode = GPIOin2None; + _GPIOparams.out1Mode = GPIOout1None; + _GPIOparams.out2Mode = GPIOout2None; _GPIOparams.algMode = GPIOalgNone; } @@ -73,36 +75,57 @@ CGPIOScreen::show() { _display.clearDisplay(); + static bool animated = false; + animated = !animated; + if(!CPasswordScreen::show()) { // for showing "saving settings" - if(_rowSel == 4) { + if(_rowSel == 10) { _showConfirmMessage(); } else { _showTitle("GPIO Settings"); - _drawBitmap(10, 14, (getBoardRevision() != BRD_V2_GPIO_NOALG) ? GPIOIconInfo : GPIOIconNoAlgInfo); + _drawBitmap(0, 14, (getBoardRevision() != BRD_V2_GPIO_NOALG) ? GPIOIconInfo : GPIOIconNoAlgInfo); { const char* msgText = NULL; - switch(_GPIOparams.inMode) { - case GPIOinNone: msgText = "Disabled"; break; - case GPIOinOn1Off2: msgText = "1:On 2:Off"; break; - case GPIOinOnHold1: msgText = "1:On 2:\352T"; break; - case GPIOinOn1Off1: msgText = "1:On/Off"; break; - case GPIOinExtThermostat2: msgText = "2:\352T"; break; + switch(_GPIOparams.in1Mode) { + case GPIOin1None: msgText = "1: --- "; break; + case GPIOin1On: msgText = "1:Start"; break; + case GPIOin1Hold: msgText = "1: Run "; break; + case GPIOin1OnOff: msgText = animated ? "1:Start" : "1: Stop"; break; } if(msgText) - _printMenuText(Column, Line3, msgText, _rowSel == 3); + _printMenuText(Column1, Line3, msgText, _rowSel == 4); + } + { + const char* msgText = NULL; + switch(_GPIOparams.in2Mode) { + case GPIOin2None: msgText = "2: ---"; break; + case GPIOin2Off: msgText = "2:Stop"; break; + case GPIOin2ExtThermostat: msgText = "2: \352T "; break; + } + if(msgText) + _printMenuText(Column2, Line3, msgText, _rowSel == 5); } { const char* msgText = NULL; - switch(_GPIOparams.outMode) { - case GPIOoutNone: msgText = "Disabled"; break; - case GPIOoutStatus: msgText = "1: Status LED"; break; - case GPIOoutUser: msgText = "1&2 User"; break; + switch(_GPIOparams.out1Mode) { + case GPIOout1None: msgText = "1: --- "; break; + case GPIOout1Status: msgText = "1:Status"; break; + case GPIOout1User: msgText = "1: User "; break; } if(msgText) - _printMenuText(Column, Line2, msgText, _rowSel == 2); + _printMenuText(Column1, Line2, msgText, _rowSel == 2); + } + { + const char* msgText = NULL; + switch(_GPIOparams.out2Mode) { + case GPIOout2None: msgText = "2: ---"; break; + case GPIOout2User: msgText = "2:User"; break; + } + if(msgText) + _printMenuText(Column2, Line2, msgText, _rowSel == 3); } if(getBoardRevision() != BRD_V2_GPIO_NOALG) { // Not No Analog support @@ -112,7 +135,7 @@ CGPIOScreen::show() case GPIOalgHeatDemand: msgText = "Ip1 allows"; break; } if(msgText) - _printMenuText(Column, Line1, msgText, _rowSel == 1); + _printMenuText(Column1, Line1, msgText, _rowSel == 1); } } } @@ -126,7 +149,7 @@ CGPIOScreen::animate() CPasswordScreen::animate(); if(!CPasswordScreen::_busy()) { - if(_rowSel != 4) { + if(_rowSel != 10) { int yPos = 53; int xPos = _display.xCentre(); const char* pMsg = NULL; @@ -146,23 +169,41 @@ CGPIOScreen::animate() case 2: _display.drawFastHLine(0, 52, 128, WHITE); - switch(_GPIOparams.outMode) { - case GPIOoutNone: pMsg = " Digital outputs are disabled. "; break; - case GPIOoutStatus: pMsg = " Output1: LED status indicator. "; break; - case GPIOoutUser: pMsg = " Output 1&2: User controlled. "; break; + switch(_GPIOparams.out1Mode) { + case GPIOout1None: pMsg = " Output 1: DISABLED. "; break; + case GPIOout1Status: pMsg = " Output 1: LED status indicator. "; break; + case GPIOout1User: pMsg = " Output 1: User controlled. "; break; + } + if(pMsg) + _scrollMessage(56, pMsg, _scrollChar); + break; + case 3: + _display.drawFastHLine(0, 52, 128, WHITE); + switch(_GPIOparams.out2Mode) { + case GPIOout2None: pMsg = " Output 2: DISABLED. "; break; + case GPIOout2User: pMsg = " Output 2: User controlled. "; break; } if(pMsg) _scrollMessage(56, pMsg, _scrollChar); break; - case 3: + case 4: _display.drawFastHLine(0, 52, 128, WHITE); - switch(_GPIOparams.inMode) { - case GPIOinNone: pMsg = " Digital inputs are disabled. "; break; - case GPIOinOn1Off2: pMsg = " Input 1: Starts upon closure. Input 2: Stops upon closure. "; break; - case GPIOinOnHold1: pMsg = " Input 1: Starts when held closed, stops when opened. Input2: Max fuel when closed, min fuel when open. "; break; - case GPIOinOn1Off1: pMsg = " Input 1: Starts or Stops upon closure. "; break; - case GPIOinExtThermostat2: pMsg = " Input 1: not used. Input 2: Max fuel when closed, min fuel when open. "; break; + switch(_GPIOparams.in1Mode) { + case GPIOin1None: pMsg = " Input 1: DISABLED. "; break; + case GPIOin1On: pMsg = " Input 1: Starts heater upon closure. "; break; + case GPIOin1Hold: pMsg = " Input 1: Starts heater when held closed, stops when opened. "; break; + case GPIOin1OnOff: pMsg = " Input 1: Starts or Stops heater upon closure. "; break; + } + if(pMsg) + _scrollMessage(56, pMsg, _scrollChar); + break; + case 5: + _display.drawFastHLine(0, 52, 128, WHITE); + switch(_GPIOparams.in2Mode) { + case GPIOin2None: pMsg = " Input 2: DISABLED. "; break; + case GPIOin2Off: pMsg = " Input 2: Stops heater upon closure. "; break; + case GPIOin2ExtThermostat: pMsg = " Input 2: External thermostat. Max fuel when closed, min fuel when open. "; break; } if(pMsg) _scrollMessage(56, pMsg, _scrollChar); @@ -188,10 +229,12 @@ CGPIOScreen::keyHandler(uint8_t event) case 1: case 2: case 3: + case 4: + case 5: _scrollChar = 0; _adjust(-1); break; - case 4: + case 10: _rowSel = 0; // abort save break; } @@ -205,10 +248,12 @@ CGPIOScreen::keyHandler(uint8_t event) case 1: case 2: case 3: + case 4: + case 5: _scrollChar = 0; _adjust(+1); break; - case 4: + case 10: _rowSel = 0; // abort save break; } @@ -229,11 +274,13 @@ CGPIOScreen::keyHandler(uint8_t event) case 1: case 2: case 3: + case 4: + case 5: _scrollChar = 0; _rowSel++; - UPPERLIMIT(_rowSel, 3); + UPPERLIMIT(_rowSel, 5); break; - case 4: // confirmed save + case 10: // confirmed save _enableStoringMessage(); us = NVstore.getUserSettings(); us.GPIO = _GPIOparams; @@ -256,7 +303,9 @@ CGPIOScreen::keyHandler(uint8_t event) case 1: case 2: case 3: - _rowSel = 4; + case 4: + case 5: + _rowSel = 10; break; } } @@ -278,16 +327,28 @@ CGPIOScreen::_adjust(int dir) _GPIOparams.algMode = (GPIOalgModes)tVal; break; case 2: // outputs mode - tVal = _GPIOparams.outMode; + tVal = _GPIOparams.out1Mode; tVal += dir; WRAPLIMITS(tVal, 0, 2); - _GPIOparams.outMode = (GPIOoutModes)tVal; + _GPIOparams.out1Mode = (GPIOout1Modes)tVal; break; - case 3: - tVal = _GPIOparams.inMode; + case 3: // outputs mode + tVal = _GPIOparams.out2Mode; tVal += dir; - WRAPLIMITS(tVal, 0, 4); - _GPIOparams.inMode = (GPIOinModes)tVal; + WRAPLIMITS(tVal, 0, 1); + _GPIOparams.out2Mode = (GPIOout2Modes)tVal; + break; + case 4: + tVal = _GPIOparams.in1Mode; + tVal += dir; + WRAPLIMITS(tVal, 0, 3); + _GPIOparams.in1Mode = (GPIOin1Modes)tVal; + break; + case 5: + tVal = _GPIOparams.in2Mode; + tVal += dir; + WRAPLIMITS(tVal, 0, 2); + _GPIOparams.in2Mode = (GPIOin2Modes)tVal; break; } } @@ -319,39 +380,45 @@ CGPIOInfoScreen::show() _printMenuText(91, 20, "1", false, eCentreJustify); _printMenuText(118, 20, "2", false, eCentreJustify); - _printMenuText(55, Line1, "Analogue:", false, eRightJustify); + if(getBoardRevision() == BRD_V2_FULLGPIO || getBoardRevision() == BRD_V1_FULLGPIO) + _printMenuText(55, Line1, "Analogue:", false, eRightJustify); - if(NVstore.getUserSettings().GPIO.inMode == GPIOinNone) { + if(NVstore.getUserSettings().GPIO.in1Mode == GPIOin1None) { _drawBitmap(7, 28, CrossLgIconInfo); - _drawBitmap(30, 28, CrossLgIconInfo); } else { _drawBitmap(4, 29, GPIOin.getState(0) ? CloseIconInfo : OpenIconInfo); - if(NVstore.getUserSettings().GPIO.inMode == GPIOinOn1Off1) - _drawBitmap(30, 28, CrossLgIconInfo); - else - _drawBitmap(27, 29, GPIOin.getState(1) ? CloseIconInfo : OpenIconInfo); + } + if(NVstore.getUserSettings().GPIO.in2Mode == GPIOin2None) { + _drawBitmap(30, 28, CrossLgIconInfo); + } + else { + _drawBitmap(27, 29, GPIOin.getState(1) ? CloseIconInfo : OpenIconInfo); } - if(NVstore.getUserSettings().GPIO.outMode == GPIOoutNone) { + if(NVstore.getUserSettings().GPIO.out1Mode == GPIOout1None) { _drawBitmap(87, 28, CrossLgIconInfo); - _drawBitmap(114, 28, CrossLgIconInfo); } else { _drawBitmap(86, 29, GPIOout.getState(0) ? BulbOnIconInfo : BulbOffIconInfo); - if(NVstore.getUserSettings().GPIO.outMode == GPIOoutStatus) - _drawBitmap(114, 28, CrossLgIconInfo); - else - _drawBitmap(113, 29, GPIOout.getState(1) ? BulbOnIconInfo : BulbOffIconInfo); } - - if(NVstore.getUserSettings().GPIO.algMode == GPIOalgNone) { - _drawBitmap(58, Line1, CrossLgIconInfo); + if(NVstore.getUserSettings().GPIO.out2Mode == GPIOout2None) { + _drawBitmap(114, 28, CrossLgIconInfo); } else { - sprintf(msg, "%d%%", GPIOalg.getValue() * 100 / 4096); - _printMenuText(58, Line1, msg); + _drawBitmap(113, 29, GPIOout.getState(1) ? BulbOnIconInfo : BulbOffIconInfo); + } + + + if(getBoardRevision() == BRD_V2_FULLGPIO || getBoardRevision() == BRD_V1_FULLGPIO) { + if(NVstore.getUserSettings().GPIO.algMode == GPIOalgNone) { + _drawBitmap(58, Line1, CrossLgIconInfo); + } + else { + sprintf(msg, "%d%%", GPIOalg.getValue() * 100 / 4096); + _printMenuText(58, Line1, msg); + } } _printMenuText(_display.xCentre(), 53, " \021 \020 ", true, eCentreJustify); diff --git a/src/OLED/VersionInfoScreen.cpp b/src/OLED/VersionInfoScreen.cpp index eaab75b..3fe90a8 100644 --- a/src/OLED/VersionInfoScreen.cpp +++ b/src/OLED/VersionInfoScreen.cpp @@ -71,8 +71,6 @@ CVersionInfoScreen::_initUI() bool CVersionInfoScreen::show() { - char msg[16]; - _display.clearDisplay(); if(!CPasswordScreen::show()) { // for showing "saving settings" @@ -86,14 +84,6 @@ CVersionInfoScreen::show() _printMenuText(41, 15, getVersionStr()); _printMenuText(41, 26, getVersionDate()); int newVer = isUpdateAvailable(); - // if(newVer) { - // char msg[32]; - // int major = (int)(newVer * 0.01); - // int minor = newVer - major*100; - // float prtMajor = major * 0.1; - // sprintf(msg, "V%.1f.%d", prtMajor, minor); - // _printMenuText(128, 15, msg, false, eRightJustify); - // } _drawBitmap(18, 34, HardwareIconInfo); int PCB = getBoardRevision(); _printMenuText(41, 38, getBoardRevisionString(PCB)); diff --git a/src/Utility/BTC_GPIO.cpp b/src/Utility/BTC_GPIO.cpp index 8455770..709663d 100644 --- a/src/Utility/BTC_GPIO.cpp +++ b/src/Utility/BTC_GPIO.cpp @@ -30,19 +30,41 @@ const int FADEAMOUNT = 3; const int FLASHPERIOD = 2000; const int ONFLASHINTERVAL = 50; -const char* GPIOinNames[] = { +// const char* GPIOinNames[] = { +// "Disabled", +// "On1Off2", +// "Hold1", +// "On1Off1", +// "ExtThermostat" +// }; + +const char* GPIOin1Names[] = { "Disabled", - "On1Off2", - "Hold1", - "On1Off1", - "ExtThermostat" + "Mom On", + "Hold On", + "Mom On/Off" +}; +const char* GPIOin2Names[] = { + "Disabled", + "Mom Off", + "Ext \352T" }; -const char* GPIOoutNames[] = { + +// const char* GPIOoutNames[] = { +// "Disabled", +// "Status", +// "User" +// }; +const char* GPIOout1Names[] = { "Disabled", "Status", "User" }; +const char* GPIOout2Names[] = { + "Disabled", + "User" +}; const char* GPIOalgNames[] = { "Disabled", @@ -52,18 +74,19 @@ const char* GPIOalgNames[] = { CGPIOin::CGPIOin() { - _Mode = GPIOinNone; + _Mode1 = GPIOin1None; + _Mode2 = GPIOin2None; _lastKey = 0; } void -CGPIOin::begin(int pin1, int pin2, GPIOinModes mode, int activeState) +CGPIOin::begin(int pin1, int pin2, GPIOin1Modes mode1, GPIOin2Modes mode2, int activeState) { _Debounce.addPin(pin1); _Debounce.addPin(pin2); _Debounce.setActiveState(activeState); - setMode(mode); + setMode(mode1, mode2); } uint8_t @@ -89,9 +112,14 @@ CGPIOin::getState(int channel) return retval; } -GPIOinModes CGPIOin::getMode() const +GPIOin1Modes CGPIOin::getMode1() const { - return _Mode; + return _Mode1; +}; + +GPIOin2Modes CGPIOin::getMode2() const +{ + return _Mode2; }; void @@ -116,29 +144,41 @@ CGPIOin::manage() void CGPIOin::simulateKey(uint8_t newKey) { - switch (_Mode) { - case GPIOinNone: + switch (_Mode1) { + case GPIOin1None: break; - case GPIOinOn1Off2: - _doOn1Off2(newKey); + case GPIOin1On: + _doOn1(newKey); break; - case GPIOinOnHold1: + case GPIOin1Hold: _doOnHold1(newKey); break; - case GPIOinOn1Off1: + case GPIOin1OnOff: _doOn1Off1(newKey); break; - case GPIOinExtThermostat2: + } + switch (_Mode2) { + case GPIOin2None: + break; + case GPIOin2Off: + _doOff2(newKey); + break; + case GPIOin2ExtThermostat: break; // handling actually performed at Tx Manage for setting the fuel rate } } void -CGPIOin::_doOn1Off2(uint8_t newKey) +CGPIOin::_doOn1(uint8_t newKey) { if(newKey & 0x01) { requestOn(); } +} + +void +CGPIOin::_doOff2(uint8_t newKey) +{ if(newKey & 0x02) { requestOff(); } @@ -174,7 +214,8 @@ CGPIOin::_doOn1Off1(uint8_t newKey) CGPIOout::CGPIOout() { - _Mode = GPIOoutNone; + _Mode1 = GPIOout1None; + _Mode2 = GPIOout2None; _pins[0] = 0; _pins[1] = 0; _breatheDelay = 0; @@ -185,7 +226,7 @@ CGPIOout::CGPIOout() } void -CGPIOout::begin(int pin1, int pin2, GPIOoutModes mode) +CGPIOout::begin(int pin1, int pin2, GPIOout1Modes mode1, GPIOout2Modes mode2) { _pins[0] = pin1; _pins[1] = pin2; @@ -200,30 +241,40 @@ CGPIOout::begin(int pin1, int pin2, GPIOoutModes mode) ledcSetup(1, 500, 8); // create PWM channel for GPIO2: 500Hz, 8 bits } - setMode(mode); + setMode(mode1, mode2); } void -CGPIOout::setMode(GPIOoutModes mode) +CGPIOout::setMode(GPIOout1Modes mode1, GPIOout2Modes mode2) { - _Mode = mode; + _Mode1 = mode1; + _Mode2 = mode2; _prevState = -1; ledcDetachPin(_pins[0]); // ensure PWM detached from IO line ledcDetachPin(_pins[1]); // ensure PWM detached from IO line }; -GPIOoutModes CGPIOout::getMode() const +GPIOout1Modes CGPIOout::getMode1() const { - return _Mode; + return _Mode1; +}; + +GPIOout2Modes CGPIOout::getMode2() const +{ + return _Mode2; }; void CGPIOout::manage() { - switch (_Mode) { - case GPIOoutNone: break; - case GPIOoutStatus: _doStatus(); break; - case GPIOoutUser: _doUser(); break; + switch (_Mode1) { + case GPIOout1None: break; + case GPIOout1Status: _doStatus(); break; + case GPIOout1User: _doUser1(); break; + } + switch (_Mode2) { + case GPIOout2None: break; + case GPIOout2User: _doUser2(); break; } } @@ -304,12 +355,18 @@ CGPIOout::_doStatus() } void -CGPIOout::_doUser() +CGPIOout::_doUser1() { -// DebugPort.println("GPIOout::_doUser()"); +// DebugPort.println("GPIOout::_doUser1()"); if(_pins[0]) { digitalWrite(_pins[0], (_userState & 0x01) ? HIGH : LOW); } +} + +void +CGPIOout::_doUser2() +{ +// DebugPort.println("GPIOout::_doUser2()"); if(_pins[1]) { digitalWrite(_pins[1], (_userState & 0x02) ? HIGH : LOW); } diff --git a/src/Utility/BTC_GPIO.h b/src/Utility/BTC_GPIO.h index 37ad359..d866361 100644 --- a/src/Utility/BTC_GPIO.h +++ b/src/Utility/BTC_GPIO.h @@ -27,23 +27,33 @@ #include "Debounce.h" #include -extern const char* GPIOinNames[]; -extern const char* GPIOoutNames[]; +extern const char* GPIOin1Names[]; +extern const char* GPIOin2Names[]; +extern const char* GPIOout1Names[]; +extern const char* GPIOout2Names[]; extern const char* GPIOalgNames[]; -enum GPIOinModes { - GPIOinNone, - GPIOinOn1Off2, // input 1 closure, heater starts; input2 closure, heater stops - GPIOinOnHold1, // hold input 1 closure, heater runs; input 1 open, heater stops - GPIOinOn1Off1, // alternate input 1 closures start or stop the heater - GPIOinExtThermostat2 // input 2 used to max/min heater if closed/open +enum GPIOin1Modes { + GPIOin1None, + GPIOin1On, // input 1 closure, heater starts; input2 closure, heater stops + GPIOin1Hold, // hold input 1 closure, heater runs; input 1 open, heater stops + GPIOin1OnOff // alternate input 1 closures start or stop the heater +}; +enum GPIOin2Modes { + GPIOin2None, + GPIOin2Off, // input 2 closure stops heater + GPIOin2ExtThermostat // input 2 used to max/min heater if closed/open }; -enum GPIOoutModes { - GPIOoutNone, - GPIOoutStatus, - GPIOoutUser +enum GPIOout1Modes { + GPIOout1None, + GPIOout1Status, + GPIOout1User +}; +enum GPIOout2Modes { + GPIOout2None, + GPIOout2User }; @@ -54,37 +64,48 @@ enum GPIOalgModes { struct sGPIOparams { - GPIOinModes inMode; - GPIOoutModes outMode; + GPIOin1Modes in1Mode; + GPIOin2Modes in2Mode; + GPIOout1Modes out1Mode; + GPIOout2Modes out2Mode; GPIOalgModes algMode; }; class CGPIOin { - GPIOinModes _Mode; + GPIOin1Modes _Mode1; + GPIOin2Modes _Mode2; CDebounce _Debounce; uint8_t _lastKey; std::list _eventList[2]; - void _doOn1Off2(uint8_t newKey); + void _doOn1(uint8_t newKey); + void _doOff2(uint8_t newKey); void _doOnHold1(uint8_t newKey); void _doOn1Off1(uint8_t newKey); public: CGPIOin(); - void setMode(GPIOinModes mode) { _Mode = mode; }; - void begin(int pin1, int pin2, GPIOinModes mode, int activeState); + // void setMode(GPIOinModes mode) { _Mode = mode; }; + // void begin(int pin1, int pin2, GPIOinModes mode, int activeState); + void setMode(GPIOin1Modes mode1, GPIOin2Modes mode2) { _Mode1 = mode1; _Mode2 = mode2; }; + void begin(int pin1, int pin2, GPIOin1Modes mode1, GPIOin2Modes mode2, int activeState); void manage(); uint8_t getState(int channel); - GPIOinModes getMode() const; + GPIOin1Modes getMode1() const; + GPIOin2Modes getMode2() const; void simulateKey(uint8_t newKey); bool usesExternalThermostat() const { - return (_Mode == GPIOinOnHold1) || (_Mode == GPIOinExtThermostat2); +// return (_Mode == GPIOinOnHold1) || (_Mode == GPIOinExtThermostat2); + return (_Mode2 == GPIOin2ExtThermostat); }; }; class CGPIOout { - GPIOoutModes _Mode; +// GPIOoutModes _Mode; + GPIOout1Modes _Mode1; + GPIOout2Modes _Mode2; void _doStatus(); - void _doUser(); + void _doUser1(); + void _doUser2(); int _pins[2]; int _prevState; int _statusState; @@ -96,12 +117,16 @@ class CGPIOout { void _doSuspendMode(); public: CGPIOout(); - void setMode(GPIOoutModes mode); - void begin(int pin1, int pin2, GPIOoutModes mode); +// void setMode(GPIOoutModes mode); +// void begin(int pin1, int pin2, GPIOoutModes mode); + void setMode(GPIOout1Modes mode1, GPIOout2Modes mode2); + void begin(int pin1, int pin2, GPIOout1Modes mode1, GPIOout2Modes mode2); void manage(); void setState(int channel, bool state); bool getState(int channel); - GPIOoutModes getMode() const; +// GPIOoutModes getMode() const; + GPIOout1Modes getMode1() const; + GPIOout2Modes getMode2() const; }; class CGPIOalg { @@ -120,8 +145,12 @@ struct sGPIO { bool outState[2]; bool inState[2]; int algVal; - GPIOoutModes outMode; - GPIOinModes inMode; +// GPIOoutModes outMode; +// GPIOinModes inMode; + GPIOout1Modes out1Mode; + GPIOout2Modes out2Mode; + GPIOin1Modes in1Mode; + GPIOin2Modes in2Mode; GPIOalgModes algMode; sGPIO& operator=(const sGPIO& rhs) { outState[0] = rhs.outState[0]; @@ -129,8 +158,10 @@ struct sGPIO { inState[0] = rhs.inState[0]; inState[1] = rhs.inState[1]; algVal = rhs.algVal; - outMode = rhs.outMode; - inMode = rhs.inMode; + out1Mode = rhs.out1Mode; + out2Mode = rhs.out2Mode; + in1Mode = rhs.in1Mode; + in2Mode = rhs.in2Mode; algMode = rhs.algMode; return *this; } diff --git a/src/Utility/BTC_JSON.cpp b/src/Utility/BTC_JSON.cpp index d89904e..34a592a 100644 --- a/src/Utility/BTC_JSON.cpp +++ b/src/Utility/BTC_JSON.cpp @@ -428,8 +428,10 @@ bool makeJSONStringGPIO(CModerator& moderator, char* opStr, int len) bSend |= moderator.addJson("GPout1", info.outState[0], root); bSend |= moderator.addJson("GPout2", info.outState[1], root); bSend |= moderator.addJson("GPanlg", info.algVal * 100 / 4096, root); - bSend |= moderator.addJson("GPmodeIn", GPIOinNames[info.inMode], root); - bSend |= moderator.addJson("GPmodeOut", GPIOoutNames[info.outMode], root); + bSend |= moderator.addJson("GPmodeIn1", GPIOin1Names[info.in1Mode], root); + bSend |= moderator.addJson("GPmodeIn2", GPIOin2Names[info.in2Mode], root); + bSend |= moderator.addJson("GPmodeOut1", GPIOout1Names[info.out1Mode], root); + bSend |= moderator.addJson("GPmodeOut2", GPIOout2Names[info.out2Mode], root); bSend |= moderator.addJson("GPmodeAnlg", GPIOalgNames[info.algMode], root); if(bSend) { diff --git a/src/Utility/NVStorage.cpp b/src/Utility/NVStorage.cpp index 3f09068..521069b 100644 --- a/src/Utility/NVStorage.cpp +++ b/src/Utility/NVStorage.cpp @@ -345,8 +345,41 @@ sUserSettings::load() validatedLoad("cyclicStop", cyclic.Stop, 0, s8inBounds, 0, 10); validatedLoad("cyclicStart", cyclic.Start, -1, s8inBounds, -20, 0); uint8_t tVal; - validatedLoad("GPIOinMode", tVal, 0, u8inBounds, 0, 4); GPIO.inMode = (GPIOinModes)tVal; - validatedLoad("GPIOoutMode", tVal, 0, u8inBounds, 0, 2); GPIO.outMode = (GPIOoutModes)tVal; +// validatedLoad("GPIOinMode", tVal, 0, u8inBounds, 0, 4); GPIO.inMode = (GPIOinModes)tVal; + validatedLoad("GPIOinMode", tVal, 0, u8inBounds, 0, 255); + if(tVal <= 4) { + // migrate old GPIO input mode + GPIO.in1Mode = GPIOin1None; + GPIO.in2Mode = GPIOin2None; + switch(tVal) { + case 1: GPIO.in1Mode = GPIOin1On; GPIO.in2Mode = GPIOin2Off; break; + case 2: GPIO.in1Mode = GPIOin1Hold; GPIO.in2Mode = GPIOin2ExtThermostat; break; + case 3: GPIO.in1Mode = GPIOin1OnOff; break; + case 4: GPIO.in2Mode = GPIOin2ExtThermostat; break; + } + preferences.putUChar("GPIOinMode", 0xff); // cancel old + preferences.putUChar("GPIOin1Mode", GPIO.in1Mode); // set new + preferences.putUChar("GPIOin2Mode", GPIO.in2Mode); // set new + } + validatedLoad("GPIOin1Mode", tVal, 0, u8inBounds, 0, 3); GPIO.in1Mode = (GPIOin1Modes)tVal; + validatedLoad("GPIOin2Mode", tVal, 0, u8inBounds, 0, 2); GPIO.in2Mode = (GPIOin2Modes)tVal; +// validatedLoad("GPIOoutMode", tVal, 0, u8inBounds, 0, 2); GPIO.outMode = (GPIOoutModes)tVal; + validatedLoad("GPIOoutMode", tVal, 0, u8inBounds, 0, 255); + if(tVal <= 2) { + // migrate old GPIO output mode + GPIO.out1Mode = GPIOout1None; + GPIO.out2Mode = GPIOout2None; + switch(tVal) { + case 0: GPIO.out1Mode = GPIOout1None; GPIO.out2Mode = GPIOout2None; break; + case 1: GPIO.out1Mode = GPIOout1Status; GPIO.out2Mode = GPIOout2None; break; + case 2: GPIO.out1Mode = GPIOout1User; GPIO.out2Mode = GPIOout2User; break; + } + preferences.putUChar("GPIOoutMode", 0xff); // cancel old + preferences.putUChar("GPIOout1Mode", GPIO.out1Mode); // set new + preferences.putUChar("GPIOout2Mode", GPIO.out2Mode); // set new + } + validatedLoad("GPIOout1Mode", tVal, 0, u8inBounds, 0, 2); GPIO.out1Mode = (GPIOout1Modes)tVal; + validatedLoad("GPIOout2Mode", tVal, 0, u8inBounds, 0, 1); GPIO.out2Mode = (GPIOout2Modes)tVal; validatedLoad("GPIOalgMode", tVal, 0, u8inBounds, 0, 2); GPIO.algMode = (GPIOalgModes)tVal; validatedLoad("MenuOnTimeout", HomeMenu.onTimeout, 0, u8inBounds, 0, 3); validatedLoad("MenuonStart", HomeMenu.onStart, 0, u8inBounds, 0, 3); @@ -373,8 +406,10 @@ sUserSettings::save() preferences.putUChar("enableOTA", enableOTA); preferences.putChar("cyclicStop", cyclic.Stop); preferences.putChar("cyclicStart",cyclic.Start); - preferences.putUChar("GPIOinMode", GPIO.inMode); - preferences.putUChar("GPIOoutMode", GPIO.outMode); + preferences.putUChar("GPIOin1Mode", GPIO.in1Mode); + preferences.putUChar("GPIOin2Mode", GPIO.in2Mode); + preferences.putUChar("GPIOout1Mode", GPIO.out1Mode); + preferences.putUChar("GPIOout2Mode", GPIO.out2Mode); preferences.putUChar("GPIOalgMode", GPIO.algMode); preferences.putUChar("MenuOnTimeout", HomeMenu.onTimeout); preferences.putUChar("MenuonStart", HomeMenu.onStart); diff --git a/src/Utility/NVStorage.h b/src/Utility/NVStorage.h index 039169c..ed22739 100644 --- a/src/Utility/NVStorage.h +++ b/src/Utility/NVStorage.h @@ -267,8 +267,10 @@ struct sUserSettings : public CESP32_NVStorage { retval &= useThermostat < 2; retval &= (enableWifi == 0) || (enableWifi == 1); retval &= (enableOTA == 0) || (enableOTA == 1); - retval &= GPIO.inMode < 4; - retval &= GPIO.outMode < 3; + retval &= GPIO.in1Mode < 4; + retval &= GPIO.in2Mode < 3; + retval &= GPIO.out1Mode < 3; + retval &= GPIO.out2Mode < 2; retval &= INBOUNDS(FrameRate, 300, 1500); retval &= cyclic.valid(); retval &= HomeMenu.valid(); @@ -284,8 +286,10 @@ struct sUserSettings : public CESP32_NVStorage { useThermostat = 1; enableWifi = 1; enableOTA = 1; - GPIO.inMode = GPIOinNone; - GPIO.outMode = GPIOoutNone; + GPIO.in1Mode = GPIOin1None; + GPIO.in2Mode = GPIOin2None; + GPIO.out1Mode = GPIOout1None; + GPIO.out2Mode = GPIOout2None; GPIO.algMode = GPIOalgNone; FrameRate = 1000; cyclic.init(); @@ -303,8 +307,10 @@ struct sUserSettings : public CESP32_NVStorage { useThermostat = rhs.useThermostat; enableWifi = rhs.enableWifi; enableOTA = rhs.enableOTA; - GPIO.inMode = rhs.GPIO.inMode; - GPIO.outMode = rhs.GPIO.outMode; + GPIO.in1Mode = rhs.GPIO.in1Mode; + GPIO.in2Mode = rhs.GPIO.in2Mode; + GPIO.out1Mode = rhs.GPIO.out1Mode; + GPIO.out2Mode = rhs.GPIO.out2Mode; GPIO.algMode = rhs.GPIO.algMode; FrameRate = rhs.FrameRate; cyclic = rhs.cyclic;