Mirror of espurna firmware for wireless switches and more
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

990 lines
29 KiB

Rework settings (#2282) * wip based on early draft. todo benchmarking * fixup eraser, assume keys are unique * fix cursor copy, test removal at random * small benchmark via permutations. todo lambdas and novirtual * fix empty condition / reset * overwrite optimizations, fix move offsets overflows * ...erase using 0xff instead of 0 * test the theory with code, different length kv were bugged * try to check for out-of-bounds writes / reads * style * trying to fix mover again * clarify length, defend against reading len on edge * fix uncommited rewind change * prove space assumptions * more concise traces, fix move condition (agrh!!!) * slightly more internal knowledge (estimates API?) * make sure cursor is only valid within the range * ensure 0 does not blow things * go back up * cursor comments * comments * rewrite writes through cursor * in del too * estimate kv storage requirements, return available size * move raw erase / move into a method, allow ::set to avoid scanning storage twice * refactor naming, use in code * amend storage slicing test * fix crash handler offsets, cleanup configuration * start -> begin * eeprom readiness * dependencies * unused * SPI_FLASH constants for older Core * vtables -> templates * less include dependencies * gcov help, move estimate outside of the class * writer position can never match, use begin + offset * tweak save_crash to trigger only once in a serious crash * doh, header function should be inline * foreach api, tweak structs for public api * use test helper class * when not using foreach, move cursor reset closer to the loop using read_kv * coverage comments, fix typo in tests decltype * ensure set() does not break with offset * make codacy happy again
3 years ago
providers: relays, lights and buttons refactoring (#2414) - gpio module now tracks the known providers (right now, hardware and mcp expander) - refactored relay struct to use 'Provider' implementing setup,notify,change,boot instead of just BasePin actions - refactored button module to use gpio provider instead of referencing types itself - removed dual & stm code from buttons, migrate both to relay module - added status notify and change callbacks for relayStatus (i.e. 'notify' when relay status was called, but not changed. and 'changed' when it did) - relays runtime configuration keys - relay command now shows configured relays and current & target statuses - refactor the code using relayStatus(0, blah) under LIGHT_PROVIDER check to use lightState instead - remove rfbridge code form relay module. implement through a basic state listener in the rfbridge module, depend on RELAY_SUPPORT - allow to bind rf codes to real relays - drop tuya-specific lights provider, remove tuya code from relays and lights modules - integrate tuya via relay listeners and providers, use lights custom provider - implement channel transitions for tuya. disabled by default, and transition time and step are overridden to 2000 + 100. needs to be set to some value below the total time (i.e. `total transition time / step time == number of steps`, we need to figure out a correct time that serial comms could handle) - lights custom provider (global, not per-pin) and state listeners - remove lights code from relay module. implement through providers & listeners in the lights module, depend on RELAY_SUPPORT - lights per-channel relay provider (unused atm), depend on RELAY_SUPPORT - refactored channel transition - calculate step only once, make sure time + step values are sane, generate quick transitions with very small delay (10ms hardcoded) for transitions during OFF state i.e. we no longer waste 500ms (or whatever transition time is set to) on boot doing nothing - transition time + step parameter for the lightUpdate - report mask parameter for the lightUpdate - minor fixes across the board resolve #2222
3 years ago
webui: remove jquery dependencies and clean-up websocket API Refactor WebUI: - remove jquery dependency from the base custom.js and use vanilla JS - remove jquery + jquery-datatables dependency from the RFM69 module - replace jquery-datatables handlers with pure-css table + some basic cell filtering (may be incomplete, but tbh it is not worth additional 50Kb to the .bin size) - introduce a common way to notify about the app errors, show small text notification at the top of the page instead of relying on user to find out about errors by using the Web Developer Tools - replace <span name=...> with <span data-settings-key=...> - replace <div> templates with <template>, disallowing modification without an explicit DOM clone - run `eslint` on html/custom.js and `html-validate` on html/index.html, and fix issues detected by both tools Streamline settings group handling in custom.js & index.html - drop module-specific button-add-... in favour of button-add-settings-group - only enforce data-settings-max requirement when the property actually exists - re-create label for=... and input id=... when settings group is modified, so checkboxes refer to the correct element - introduce additional data-... properties to generalize settings group additions - introduce Enumerable object to track some common list elements for <select>, allow to re-create <option> list when messages come in different order Minor fixes that also came with this: - fix relay code incorrectly parsing the payload, causing no relay names to be displayed in the SWITCHES panel - fix scheduler code accidentally combining keys b/c of the way C parses string literals on separate lines, without any commas in-between - thermostat should not reference tmpUnit directly in the webui, replace with module-specific thermostatUnit that is handled on the device itself - fix index.html initial setup invalid adminPass ids - fix index.html layout when removing specific schedules
2 years ago
webui: remove jquery dependencies and clean-up websocket API Refactor WebUI: - remove jquery dependency from the base custom.js and use vanilla JS - remove jquery + jquery-datatables dependency from the RFM69 module - replace jquery-datatables handlers with pure-css table + some basic cell filtering (may be incomplete, but tbh it is not worth additional 50Kb to the .bin size) - introduce a common way to notify about the app errors, show small text notification at the top of the page instead of relying on user to find out about errors by using the Web Developer Tools - replace <span name=...> with <span data-settings-key=...> - replace <div> templates with <template>, disallowing modification without an explicit DOM clone - run `eslint` on html/custom.js and `html-validate` on html/index.html, and fix issues detected by both tools Streamline settings group handling in custom.js & index.html - drop module-specific button-add-... in favour of button-add-settings-group - only enforce data-settings-max requirement when the property actually exists - re-create label for=... and input id=... when settings group is modified, so checkboxes refer to the correct element - introduce additional data-... properties to generalize settings group additions - introduce Enumerable object to track some common list elements for <select>, allow to re-create <option> list when messages come in different order Minor fixes that also came with this: - fix relay code incorrectly parsing the payload, causing no relay names to be displayed in the SWITCHES panel - fix scheduler code accidentally combining keys b/c of the way C parses string literals on separate lines, without any commas in-between - thermostat should not reference tmpUnit directly in the webui, replace with module-specific thermostatUnit that is handled on the device itself - fix index.html initial setup invalid adminPass ids - fix index.html layout when removing specific schedules
2 years ago
providers: relays, lights and buttons refactoring (#2414) - gpio module now tracks the known providers (right now, hardware and mcp expander) - refactored relay struct to use 'Provider' implementing setup,notify,change,boot instead of just BasePin actions - refactored button module to use gpio provider instead of referencing types itself - removed dual & stm code from buttons, migrate both to relay module - added status notify and change callbacks for relayStatus (i.e. 'notify' when relay status was called, but not changed. and 'changed' when it did) - relays runtime configuration keys - relay command now shows configured relays and current & target statuses - refactor the code using relayStatus(0, blah) under LIGHT_PROVIDER check to use lightState instead - remove rfbridge code form relay module. implement through a basic state listener in the rfbridge module, depend on RELAY_SUPPORT - allow to bind rf codes to real relays - drop tuya-specific lights provider, remove tuya code from relays and lights modules - integrate tuya via relay listeners and providers, use lights custom provider - implement channel transitions for tuya. disabled by default, and transition time and step are overridden to 2000 + 100. needs to be set to some value below the total time (i.e. `total transition time / step time == number of steps`, we need to figure out a correct time that serial comms could handle) - lights custom provider (global, not per-pin) and state listeners - remove lights code from relay module. implement through providers & listeners in the lights module, depend on RELAY_SUPPORT - lights per-channel relay provider (unused atm), depend on RELAY_SUPPORT - refactored channel transition - calculate step only once, make sure time + step values are sane, generate quick transitions with very small delay (10ms hardcoded) for transitions during OFF state i.e. we no longer waste 500ms (or whatever transition time is set to) on boot doing nothing - transition time + step parameter for the lightUpdate - report mask parameter for the lightUpdate - minor fixes across the board resolve #2222
3 years ago
providers: relays, lights and buttons refactoring (#2414) - gpio module now tracks the known providers (right now, hardware and mcp expander) - refactored relay struct to use 'Provider' implementing setup,notify,change,boot instead of just BasePin actions - refactored button module to use gpio provider instead of referencing types itself - removed dual & stm code from buttons, migrate both to relay module - added status notify and change callbacks for relayStatus (i.e. 'notify' when relay status was called, but not changed. and 'changed' when it did) - relays runtime configuration keys - relay command now shows configured relays and current & target statuses - refactor the code using relayStatus(0, blah) under LIGHT_PROVIDER check to use lightState instead - remove rfbridge code form relay module. implement through a basic state listener in the rfbridge module, depend on RELAY_SUPPORT - allow to bind rf codes to real relays - drop tuya-specific lights provider, remove tuya code from relays and lights modules - integrate tuya via relay listeners and providers, use lights custom provider - implement channel transitions for tuya. disabled by default, and transition time and step are overridden to 2000 + 100. needs to be set to some value below the total time (i.e. `total transition time / step time == number of steps`, we need to figure out a correct time that serial comms could handle) - lights custom provider (global, not per-pin) and state listeners - remove lights code from relay module. implement through providers & listeners in the lights module, depend on RELAY_SUPPORT - lights per-channel relay provider (unused atm), depend on RELAY_SUPPORT - refactored channel transition - calculate step only once, make sure time + step values are sane, generate quick transitions with very small delay (10ms hardcoded) for transitions during OFF state i.e. we no longer waste 500ms (or whatever transition time is set to) on boot doing nothing - transition time + step parameter for the lightUpdate - report mask parameter for the lightUpdate - minor fixes across the board resolve #2222
3 years ago
providers: relays, lights and buttons refactoring (#2414) - gpio module now tracks the known providers (right now, hardware and mcp expander) - refactored relay struct to use 'Provider' implementing setup,notify,change,boot instead of just BasePin actions - refactored button module to use gpio provider instead of referencing types itself - removed dual & stm code from buttons, migrate both to relay module - added status notify and change callbacks for relayStatus (i.e. 'notify' when relay status was called, but not changed. and 'changed' when it did) - relays runtime configuration keys - relay command now shows configured relays and current & target statuses - refactor the code using relayStatus(0, blah) under LIGHT_PROVIDER check to use lightState instead - remove rfbridge code form relay module. implement through a basic state listener in the rfbridge module, depend on RELAY_SUPPORT - allow to bind rf codes to real relays - drop tuya-specific lights provider, remove tuya code from relays and lights modules - integrate tuya via relay listeners and providers, use lights custom provider - implement channel transitions for tuya. disabled by default, and transition time and step are overridden to 2000 + 100. needs to be set to some value below the total time (i.e. `total transition time / step time == number of steps`, we need to figure out a correct time that serial comms could handle) - lights custom provider (global, not per-pin) and state listeners - remove lights code from relay module. implement through providers & listeners in the lights module, depend on RELAY_SUPPORT - lights per-channel relay provider (unused atm), depend on RELAY_SUPPORT - refactored channel transition - calculate step only once, make sure time + step values are sane, generate quick transitions with very small delay (10ms hardcoded) for transitions during OFF state i.e. we no longer waste 500ms (or whatever transition time is set to) on boot doing nothing - transition time + step parameter for the lightUpdate - report mask parameter for the lightUpdate - minor fixes across the board resolve #2222
3 years ago
providers: relays, lights and buttons refactoring (#2414) - gpio module now tracks the known providers (right now, hardware and mcp expander) - refactored relay struct to use 'Provider' implementing setup,notify,change,boot instead of just BasePin actions - refactored button module to use gpio provider instead of referencing types itself - removed dual & stm code from buttons, migrate both to relay module - added status notify and change callbacks for relayStatus (i.e. 'notify' when relay status was called, but not changed. and 'changed' when it did) - relays runtime configuration keys - relay command now shows configured relays and current & target statuses - refactor the code using relayStatus(0, blah) under LIGHT_PROVIDER check to use lightState instead - remove rfbridge code form relay module. implement through a basic state listener in the rfbridge module, depend on RELAY_SUPPORT - allow to bind rf codes to real relays - drop tuya-specific lights provider, remove tuya code from relays and lights modules - integrate tuya via relay listeners and providers, use lights custom provider - implement channel transitions for tuya. disabled by default, and transition time and step are overridden to 2000 + 100. needs to be set to some value below the total time (i.e. `total transition time / step time == number of steps`, we need to figure out a correct time that serial comms could handle) - lights custom provider (global, not per-pin) and state listeners - remove lights code from relay module. implement through providers & listeners in the lights module, depend on RELAY_SUPPORT - lights per-channel relay provider (unused atm), depend on RELAY_SUPPORT - refactored channel transition - calculate step only once, make sure time + step values are sane, generate quick transitions with very small delay (10ms hardcoded) for transitions during OFF state i.e. we no longer waste 500ms (or whatever transition time is set to) on boot doing nothing - transition time + step parameter for the lightUpdate - report mask parameter for the lightUpdate - minor fixes across the board resolve #2222
3 years ago
providers: relays, lights and buttons refactoring (#2414) - gpio module now tracks the known providers (right now, hardware and mcp expander) - refactored relay struct to use 'Provider' implementing setup,notify,change,boot instead of just BasePin actions - refactored button module to use gpio provider instead of referencing types itself - removed dual & stm code from buttons, migrate both to relay module - added status notify and change callbacks for relayStatus (i.e. 'notify' when relay status was called, but not changed. and 'changed' when it did) - relays runtime configuration keys - relay command now shows configured relays and current & target statuses - refactor the code using relayStatus(0, blah) under LIGHT_PROVIDER check to use lightState instead - remove rfbridge code form relay module. implement through a basic state listener in the rfbridge module, depend on RELAY_SUPPORT - allow to bind rf codes to real relays - drop tuya-specific lights provider, remove tuya code from relays and lights modules - integrate tuya via relay listeners and providers, use lights custom provider - implement channel transitions for tuya. disabled by default, and transition time and step are overridden to 2000 + 100. needs to be set to some value below the total time (i.e. `total transition time / step time == number of steps`, we need to figure out a correct time that serial comms could handle) - lights custom provider (global, not per-pin) and state listeners - remove lights code from relay module. implement through providers & listeners in the lights module, depend on RELAY_SUPPORT - lights per-channel relay provider (unused atm), depend on RELAY_SUPPORT - refactored channel transition - calculate step only once, make sure time + step values are sane, generate quick transitions with very small delay (10ms hardcoded) for transitions during OFF state i.e. we no longer waste 500ms (or whatever transition time is set to) on boot doing nothing - transition time + step parameter for the lightUpdate - report mask parameter for the lightUpdate - minor fixes across the board resolve #2222
3 years ago
providers: relays, lights and buttons refactoring (#2414) - gpio module now tracks the known providers (right now, hardware and mcp expander) - refactored relay struct to use 'Provider' implementing setup,notify,change,boot instead of just BasePin actions - refactored button module to use gpio provider instead of referencing types itself - removed dual & stm code from buttons, migrate both to relay module - added status notify and change callbacks for relayStatus (i.e. 'notify' when relay status was called, but not changed. and 'changed' when it did) - relays runtime configuration keys - relay command now shows configured relays and current & target statuses - refactor the code using relayStatus(0, blah) under LIGHT_PROVIDER check to use lightState instead - remove rfbridge code form relay module. implement through a basic state listener in the rfbridge module, depend on RELAY_SUPPORT - allow to bind rf codes to real relays - drop tuya-specific lights provider, remove tuya code from relays and lights modules - integrate tuya via relay listeners and providers, use lights custom provider - implement channel transitions for tuya. disabled by default, and transition time and step are overridden to 2000 + 100. needs to be set to some value below the total time (i.e. `total transition time / step time == number of steps`, we need to figure out a correct time that serial comms could handle) - lights custom provider (global, not per-pin) and state listeners - remove lights code from relay module. implement through providers & listeners in the lights module, depend on RELAY_SUPPORT - lights per-channel relay provider (unused atm), depend on RELAY_SUPPORT - refactored channel transition - calculate step only once, make sure time + step values are sane, generate quick transitions with very small delay (10ms hardcoded) for transitions during OFF state i.e. we no longer waste 500ms (or whatever transition time is set to) on boot doing nothing - transition time + step parameter for the lightUpdate - report mask parameter for the lightUpdate - minor fixes across the board resolve #2222
3 years ago
providers: relays, lights and buttons refactoring (#2414) - gpio module now tracks the known providers (right now, hardware and mcp expander) - refactored relay struct to use 'Provider' implementing setup,notify,change,boot instead of just BasePin actions - refactored button module to use gpio provider instead of referencing types itself - removed dual & stm code from buttons, migrate both to relay module - added status notify and change callbacks for relayStatus (i.e. 'notify' when relay status was called, but not changed. and 'changed' when it did) - relays runtime configuration keys - relay command now shows configured relays and current & target statuses - refactor the code using relayStatus(0, blah) under LIGHT_PROVIDER check to use lightState instead - remove rfbridge code form relay module. implement through a basic state listener in the rfbridge module, depend on RELAY_SUPPORT - allow to bind rf codes to real relays - drop tuya-specific lights provider, remove tuya code from relays and lights modules - integrate tuya via relay listeners and providers, use lights custom provider - implement channel transitions for tuya. disabled by default, and transition time and step are overridden to 2000 + 100. needs to be set to some value below the total time (i.e. `total transition time / step time == number of steps`, we need to figure out a correct time that serial comms could handle) - lights custom provider (global, not per-pin) and state listeners - remove lights code from relay module. implement through providers & listeners in the lights module, depend on RELAY_SUPPORT - lights per-channel relay provider (unused atm), depend on RELAY_SUPPORT - refactored channel transition - calculate step only once, make sure time + step values are sane, generate quick transitions with very small delay (10ms hardcoded) for transitions during OFF state i.e. we no longer waste 500ms (or whatever transition time is set to) on boot doing nothing - transition time + step parameter for the lightUpdate - report mask parameter for the lightUpdate - minor fixes across the board resolve #2222
3 years ago
providers: relays, lights and buttons refactoring (#2414) - gpio module now tracks the known providers (right now, hardware and mcp expander) - refactored relay struct to use 'Provider' implementing setup,notify,change,boot instead of just BasePin actions - refactored button module to use gpio provider instead of referencing types itself - removed dual & stm code from buttons, migrate both to relay module - added status notify and change callbacks for relayStatus (i.e. 'notify' when relay status was called, but not changed. and 'changed' when it did) - relays runtime configuration keys - relay command now shows configured relays and current & target statuses - refactor the code using relayStatus(0, blah) under LIGHT_PROVIDER check to use lightState instead - remove rfbridge code form relay module. implement through a basic state listener in the rfbridge module, depend on RELAY_SUPPORT - allow to bind rf codes to real relays - drop tuya-specific lights provider, remove tuya code from relays and lights modules - integrate tuya via relay listeners and providers, use lights custom provider - implement channel transitions for tuya. disabled by default, and transition time and step are overridden to 2000 + 100. needs to be set to some value below the total time (i.e. `total transition time / step time == number of steps`, we need to figure out a correct time that serial comms could handle) - lights custom provider (global, not per-pin) and state listeners - remove lights code from relay module. implement through providers & listeners in the lights module, depend on RELAY_SUPPORT - lights per-channel relay provider (unused atm), depend on RELAY_SUPPORT - refactored channel transition - calculate step only once, make sure time + step values are sane, generate quick transitions with very small delay (10ms hardcoded) for transitions during OFF state i.e. we no longer waste 500ms (or whatever transition time is set to) on boot doing nothing - transition time + step parameter for the lightUpdate - report mask parameter for the lightUpdate - minor fixes across the board resolve #2222
3 years ago
providers: relays, lights and buttons refactoring (#2414) - gpio module now tracks the known providers (right now, hardware and mcp expander) - refactored relay struct to use 'Provider' implementing setup,notify,change,boot instead of just BasePin actions - refactored button module to use gpio provider instead of referencing types itself - removed dual & stm code from buttons, migrate both to relay module - added status notify and change callbacks for relayStatus (i.e. 'notify' when relay status was called, but not changed. and 'changed' when it did) - relays runtime configuration keys - relay command now shows configured relays and current & target statuses - refactor the code using relayStatus(0, blah) under LIGHT_PROVIDER check to use lightState instead - remove rfbridge code form relay module. implement through a basic state listener in the rfbridge module, depend on RELAY_SUPPORT - allow to bind rf codes to real relays - drop tuya-specific lights provider, remove tuya code from relays and lights modules - integrate tuya via relay listeners and providers, use lights custom provider - implement channel transitions for tuya. disabled by default, and transition time and step are overridden to 2000 + 100. needs to be set to some value below the total time (i.e. `total transition time / step time == number of steps`, we need to figure out a correct time that serial comms could handle) - lights custom provider (global, not per-pin) and state listeners - remove lights code from relay module. implement through providers & listeners in the lights module, depend on RELAY_SUPPORT - lights per-channel relay provider (unused atm), depend on RELAY_SUPPORT - refactored channel transition - calculate step only once, make sure time + step values are sane, generate quick transitions with very small delay (10ms hardcoded) for transitions during OFF state i.e. we no longer waste 500ms (or whatever transition time is set to) on boot doing nothing - transition time + step parameter for the lightUpdate - report mask parameter for the lightUpdate - minor fixes across the board resolve #2222
3 years ago
providers: relays, lights and buttons refactoring (#2414) - gpio module now tracks the known providers (right now, hardware and mcp expander) - refactored relay struct to use 'Provider' implementing setup,notify,change,boot instead of just BasePin actions - refactored button module to use gpio provider instead of referencing types itself - removed dual & stm code from buttons, migrate both to relay module - added status notify and change callbacks for relayStatus (i.e. 'notify' when relay status was called, but not changed. and 'changed' when it did) - relays runtime configuration keys - relay command now shows configured relays and current & target statuses - refactor the code using relayStatus(0, blah) under LIGHT_PROVIDER check to use lightState instead - remove rfbridge code form relay module. implement through a basic state listener in the rfbridge module, depend on RELAY_SUPPORT - allow to bind rf codes to real relays - drop tuya-specific lights provider, remove tuya code from relays and lights modules - integrate tuya via relay listeners and providers, use lights custom provider - implement channel transitions for tuya. disabled by default, and transition time and step are overridden to 2000 + 100. needs to be set to some value below the total time (i.e. `total transition time / step time == number of steps`, we need to figure out a correct time that serial comms could handle) - lights custom provider (global, not per-pin) and state listeners - remove lights code from relay module. implement through providers & listeners in the lights module, depend on RELAY_SUPPORT - lights per-channel relay provider (unused atm), depend on RELAY_SUPPORT - refactored channel transition - calculate step only once, make sure time + step values are sane, generate quick transitions with very small delay (10ms hardcoded) for transitions during OFF state i.e. we no longer waste 500ms (or whatever transition time is set to) on boot doing nothing - transition time + step parameter for the lightUpdate - report mask parameter for the lightUpdate - minor fixes across the board resolve #2222
3 years ago
providers: relays, lights and buttons refactoring (#2414) - gpio module now tracks the known providers (right now, hardware and mcp expander) - refactored relay struct to use 'Provider' implementing setup,notify,change,boot instead of just BasePin actions - refactored button module to use gpio provider instead of referencing types itself - removed dual & stm code from buttons, migrate both to relay module - added status notify and change callbacks for relayStatus (i.e. 'notify' when relay status was called, but not changed. and 'changed' when it did) - relays runtime configuration keys - relay command now shows configured relays and current & target statuses - refactor the code using relayStatus(0, blah) under LIGHT_PROVIDER check to use lightState instead - remove rfbridge code form relay module. implement through a basic state listener in the rfbridge module, depend on RELAY_SUPPORT - allow to bind rf codes to real relays - drop tuya-specific lights provider, remove tuya code from relays and lights modules - integrate tuya via relay listeners and providers, use lights custom provider - implement channel transitions for tuya. disabled by default, and transition time and step are overridden to 2000 + 100. needs to be set to some value below the total time (i.e. `total transition time / step time == number of steps`, we need to figure out a correct time that serial comms could handle) - lights custom provider (global, not per-pin) and state listeners - remove lights code from relay module. implement through providers & listeners in the lights module, depend on RELAY_SUPPORT - lights per-channel relay provider (unused atm), depend on RELAY_SUPPORT - refactored channel transition - calculate step only once, make sure time + step values are sane, generate quick transitions with very small delay (10ms hardcoded) for transitions during OFF state i.e. we no longer waste 500ms (or whatever transition time is set to) on boot doing nothing - transition time + step parameter for the lightUpdate - report mask parameter for the lightUpdate - minor fixes across the board resolve #2222
3 years ago
providers: relays, lights and buttons refactoring (#2414) - gpio module now tracks the known providers (right now, hardware and mcp expander) - refactored relay struct to use 'Provider' implementing setup,notify,change,boot instead of just BasePin actions - refactored button module to use gpio provider instead of referencing types itself - removed dual & stm code from buttons, migrate both to relay module - added status notify and change callbacks for relayStatus (i.e. 'notify' when relay status was called, but not changed. and 'changed' when it did) - relays runtime configuration keys - relay command now shows configured relays and current & target statuses - refactor the code using relayStatus(0, blah) under LIGHT_PROVIDER check to use lightState instead - remove rfbridge code form relay module. implement through a basic state listener in the rfbridge module, depend on RELAY_SUPPORT - allow to bind rf codes to real relays - drop tuya-specific lights provider, remove tuya code from relays and lights modules - integrate tuya via relay listeners and providers, use lights custom provider - implement channel transitions for tuya. disabled by default, and transition time and step are overridden to 2000 + 100. needs to be set to some value below the total time (i.e. `total transition time / step time == number of steps`, we need to figure out a correct time that serial comms could handle) - lights custom provider (global, not per-pin) and state listeners - remove lights code from relay module. implement through providers & listeners in the lights module, depend on RELAY_SUPPORT - lights per-channel relay provider (unused atm), depend on RELAY_SUPPORT - refactored channel transition - calculate step only once, make sure time + step values are sane, generate quick transitions with very small delay (10ms hardcoded) for transitions during OFF state i.e. we no longer waste 500ms (or whatever transition time is set to) on boot doing nothing - transition time + step parameter for the lightUpdate - report mask parameter for the lightUpdate - minor fixes across the board resolve #2222
3 years ago
providers: relays, lights and buttons refactoring (#2414) - gpio module now tracks the known providers (right now, hardware and mcp expander) - refactored relay struct to use 'Provider' implementing setup,notify,change,boot instead of just BasePin actions - refactored button module to use gpio provider instead of referencing types itself - removed dual & stm code from buttons, migrate both to relay module - added status notify and change callbacks for relayStatus (i.e. 'notify' when relay status was called, but not changed. and 'changed' when it did) - relays runtime configuration keys - relay command now shows configured relays and current & target statuses - refactor the code using relayStatus(0, blah) under LIGHT_PROVIDER check to use lightState instead - remove rfbridge code form relay module. implement through a basic state listener in the rfbridge module, depend on RELAY_SUPPORT - allow to bind rf codes to real relays - drop tuya-specific lights provider, remove tuya code from relays and lights modules - integrate tuya via relay listeners and providers, use lights custom provider - implement channel transitions for tuya. disabled by default, and transition time and step are overridden to 2000 + 100. needs to be set to some value below the total time (i.e. `total transition time / step time == number of steps`, we need to figure out a correct time that serial comms could handle) - lights custom provider (global, not per-pin) and state listeners - remove lights code from relay module. implement through providers & listeners in the lights module, depend on RELAY_SUPPORT - lights per-channel relay provider (unused atm), depend on RELAY_SUPPORT - refactored channel transition - calculate step only once, make sure time + step values are sane, generate quick transitions with very small delay (10ms hardcoded) for transitions during OFF state i.e. we no longer waste 500ms (or whatever transition time is set to) on boot doing nothing - transition time + step parameter for the lightUpdate - report mask parameter for the lightUpdate - minor fixes across the board resolve #2222
3 years ago
providers: relays, lights and buttons refactoring (#2414) - gpio module now tracks the known providers (right now, hardware and mcp expander) - refactored relay struct to use 'Provider' implementing setup,notify,change,boot instead of just BasePin actions - refactored button module to use gpio provider instead of referencing types itself - removed dual & stm code from buttons, migrate both to relay module - added status notify and change callbacks for relayStatus (i.e. 'notify' when relay status was called, but not changed. and 'changed' when it did) - relays runtime configuration keys - relay command now shows configured relays and current & target statuses - refactor the code using relayStatus(0, blah) under LIGHT_PROVIDER check to use lightState instead - remove rfbridge code form relay module. implement through a basic state listener in the rfbridge module, depend on RELAY_SUPPORT - allow to bind rf codes to real relays - drop tuya-specific lights provider, remove tuya code from relays and lights modules - integrate tuya via relay listeners and providers, use lights custom provider - implement channel transitions for tuya. disabled by default, and transition time and step are overridden to 2000 + 100. needs to be set to some value below the total time (i.e. `total transition time / step time == number of steps`, we need to figure out a correct time that serial comms could handle) - lights custom provider (global, not per-pin) and state listeners - remove lights code from relay module. implement through providers & listeners in the lights module, depend on RELAY_SUPPORT - lights per-channel relay provider (unused atm), depend on RELAY_SUPPORT - refactored channel transition - calculate step only once, make sure time + step values are sane, generate quick transitions with very small delay (10ms hardcoded) for transitions during OFF state i.e. we no longer waste 500ms (or whatever transition time is set to) on boot doing nothing - transition time + step parameter for the lightUpdate - report mask parameter for the lightUpdate - minor fixes across the board resolve #2222
3 years ago
providers: relays, lights and buttons refactoring (#2414) - gpio module now tracks the known providers (right now, hardware and mcp expander) - refactored relay struct to use 'Provider' implementing setup,notify,change,boot instead of just BasePin actions - refactored button module to use gpio provider instead of referencing types itself - removed dual & stm code from buttons, migrate both to relay module - added status notify and change callbacks for relayStatus (i.e. 'notify' when relay status was called, but not changed. and 'changed' when it did) - relays runtime configuration keys - relay command now shows configured relays and current & target statuses - refactor the code using relayStatus(0, blah) under LIGHT_PROVIDER check to use lightState instead - remove rfbridge code form relay module. implement through a basic state listener in the rfbridge module, depend on RELAY_SUPPORT - allow to bind rf codes to real relays - drop tuya-specific lights provider, remove tuya code from relays and lights modules - integrate tuya via relay listeners and providers, use lights custom provider - implement channel transitions for tuya. disabled by default, and transition time and step are overridden to 2000 + 100. needs to be set to some value below the total time (i.e. `total transition time / step time == number of steps`, we need to figure out a correct time that serial comms could handle) - lights custom provider (global, not per-pin) and state listeners - remove lights code from relay module. implement through providers & listeners in the lights module, depend on RELAY_SUPPORT - lights per-channel relay provider (unused atm), depend on RELAY_SUPPORT - refactored channel transition - calculate step only once, make sure time + step values are sane, generate quick transitions with very small delay (10ms hardcoded) for transitions during OFF state i.e. we no longer waste 500ms (or whatever transition time is set to) on boot doing nothing - transition time + step parameter for the lightUpdate - report mask parameter for the lightUpdate - minor fixes across the board resolve #2222
3 years ago
providers: relays, lights and buttons refactoring (#2414) - gpio module now tracks the known providers (right now, hardware and mcp expander) - refactored relay struct to use 'Provider' implementing setup,notify,change,boot instead of just BasePin actions - refactored button module to use gpio provider instead of referencing types itself - removed dual & stm code from buttons, migrate both to relay module - added status notify and change callbacks for relayStatus (i.e. 'notify' when relay status was called, but not changed. and 'changed' when it did) - relays runtime configuration keys - relay command now shows configured relays and current & target statuses - refactor the code using relayStatus(0, blah) under LIGHT_PROVIDER check to use lightState instead - remove rfbridge code form relay module. implement through a basic state listener in the rfbridge module, depend on RELAY_SUPPORT - allow to bind rf codes to real relays - drop tuya-specific lights provider, remove tuya code from relays and lights modules - integrate tuya via relay listeners and providers, use lights custom provider - implement channel transitions for tuya. disabled by default, and transition time and step are overridden to 2000 + 100. needs to be set to some value below the total time (i.e. `total transition time / step time == number of steps`, we need to figure out a correct time that serial comms could handle) - lights custom provider (global, not per-pin) and state listeners - remove lights code from relay module. implement through providers & listeners in the lights module, depend on RELAY_SUPPORT - lights per-channel relay provider (unused atm), depend on RELAY_SUPPORT - refactored channel transition - calculate step only once, make sure time + step values are sane, generate quick transitions with very small delay (10ms hardcoded) for transitions during OFF state i.e. we no longer waste 500ms (or whatever transition time is set to) on boot doing nothing - transition time + step parameter for the lightUpdate - report mask parameter for the lightUpdate - minor fixes across the board resolve #2222
3 years ago
providers: relays, lights and buttons refactoring (#2414) - gpio module now tracks the known providers (right now, hardware and mcp expander) - refactored relay struct to use 'Provider' implementing setup,notify,change,boot instead of just BasePin actions - refactored button module to use gpio provider instead of referencing types itself - removed dual & stm code from buttons, migrate both to relay module - added status notify and change callbacks for relayStatus (i.e. 'notify' when relay status was called, but not changed. and 'changed' when it did) - relays runtime configuration keys - relay command now shows configured relays and current & target statuses - refactor the code using relayStatus(0, blah) under LIGHT_PROVIDER check to use lightState instead - remove rfbridge code form relay module. implement through a basic state listener in the rfbridge module, depend on RELAY_SUPPORT - allow to bind rf codes to real relays - drop tuya-specific lights provider, remove tuya code from relays and lights modules - integrate tuya via relay listeners and providers, use lights custom provider - implement channel transitions for tuya. disabled by default, and transition time and step are overridden to 2000 + 100. needs to be set to some value below the total time (i.e. `total transition time / step time == number of steps`, we need to figure out a correct time that serial comms could handle) - lights custom provider (global, not per-pin) and state listeners - remove lights code from relay module. implement through providers & listeners in the lights module, depend on RELAY_SUPPORT - lights per-channel relay provider (unused atm), depend on RELAY_SUPPORT - refactored channel transition - calculate step only once, make sure time + step values are sane, generate quick transitions with very small delay (10ms hardcoded) for transitions during OFF state i.e. we no longer waste 500ms (or whatever transition time is set to) on boot doing nothing - transition time + step parameter for the lightUpdate - report mask parameter for the lightUpdate - minor fixes across the board resolve #2222
3 years ago
providers: relays, lights and buttons refactoring (#2414) - gpio module now tracks the known providers (right now, hardware and mcp expander) - refactored relay struct to use 'Provider' implementing setup,notify,change,boot instead of just BasePin actions - refactored button module to use gpio provider instead of referencing types itself - removed dual & stm code from buttons, migrate both to relay module - added status notify and change callbacks for relayStatus (i.e. 'notify' when relay status was called, but not changed. and 'changed' when it did) - relays runtime configuration keys - relay command now shows configured relays and current & target statuses - refactor the code using relayStatus(0, blah) under LIGHT_PROVIDER check to use lightState instead - remove rfbridge code form relay module. implement through a basic state listener in the rfbridge module, depend on RELAY_SUPPORT - allow to bind rf codes to real relays - drop tuya-specific lights provider, remove tuya code from relays and lights modules - integrate tuya via relay listeners and providers, use lights custom provider - implement channel transitions for tuya. disabled by default, and transition time and step are overridden to 2000 + 100. needs to be set to some value below the total time (i.e. `total transition time / step time == number of steps`, we need to figure out a correct time that serial comms could handle) - lights custom provider (global, not per-pin) and state listeners - remove lights code from relay module. implement through providers & listeners in the lights module, depend on RELAY_SUPPORT - lights per-channel relay provider (unused atm), depend on RELAY_SUPPORT - refactored channel transition - calculate step only once, make sure time + step values are sane, generate quick transitions with very small delay (10ms hardcoded) for transitions during OFF state i.e. we no longer waste 500ms (or whatever transition time is set to) on boot doing nothing - transition time + step parameter for the lightUpdate - report mask parameter for the lightUpdate - minor fixes across the board resolve #2222
3 years ago
providers: relays, lights and buttons refactoring (#2414) - gpio module now tracks the known providers (right now, hardware and mcp expander) - refactored relay struct to use 'Provider' implementing setup,notify,change,boot instead of just BasePin actions - refactored button module to use gpio provider instead of referencing types itself - removed dual & stm code from buttons, migrate both to relay module - added status notify and change callbacks for relayStatus (i.e. 'notify' when relay status was called, but not changed. and 'changed' when it did) - relays runtime configuration keys - relay command now shows configured relays and current & target statuses - refactor the code using relayStatus(0, blah) under LIGHT_PROVIDER check to use lightState instead - remove rfbridge code form relay module. implement through a basic state listener in the rfbridge module, depend on RELAY_SUPPORT - allow to bind rf codes to real relays - drop tuya-specific lights provider, remove tuya code from relays and lights modules - integrate tuya via relay listeners and providers, use lights custom provider - implement channel transitions for tuya. disabled by default, and transition time and step are overridden to 2000 + 100. needs to be set to some value below the total time (i.e. `total transition time / step time == number of steps`, we need to figure out a correct time that serial comms could handle) - lights custom provider (global, not per-pin) and state listeners - remove lights code from relay module. implement through providers & listeners in the lights module, depend on RELAY_SUPPORT - lights per-channel relay provider (unused atm), depend on RELAY_SUPPORT - refactored channel transition - calculate step only once, make sure time + step values are sane, generate quick transitions with very small delay (10ms hardcoded) for transitions during OFF state i.e. we no longer waste 500ms (or whatever transition time is set to) on boot doing nothing - transition time + step parameter for the lightUpdate - report mask parameter for the lightUpdate - minor fixes across the board resolve #2222
3 years ago
providers: relays, lights and buttons refactoring (#2414) - gpio module now tracks the known providers (right now, hardware and mcp expander) - refactored relay struct to use 'Provider' implementing setup,notify,change,boot instead of just BasePin actions - refactored button module to use gpio provider instead of referencing types itself - removed dual & stm code from buttons, migrate both to relay module - added status notify and change callbacks for relayStatus (i.e. 'notify' when relay status was called, but not changed. and 'changed' when it did) - relays runtime configuration keys - relay command now shows configured relays and current & target statuses - refactor the code using relayStatus(0, blah) under LIGHT_PROVIDER check to use lightState instead - remove rfbridge code form relay module. implement through a basic state listener in the rfbridge module, depend on RELAY_SUPPORT - allow to bind rf codes to real relays - drop tuya-specific lights provider, remove tuya code from relays and lights modules - integrate tuya via relay listeners and providers, use lights custom provider - implement channel transitions for tuya. disabled by default, and transition time and step are overridden to 2000 + 100. needs to be set to some value below the total time (i.e. `total transition time / step time == number of steps`, we need to figure out a correct time that serial comms could handle) - lights custom provider (global, not per-pin) and state listeners - remove lights code from relay module. implement through providers & listeners in the lights module, depend on RELAY_SUPPORT - lights per-channel relay provider (unused atm), depend on RELAY_SUPPORT - refactored channel transition - calculate step only once, make sure time + step values are sane, generate quick transitions with very small delay (10ms hardcoded) for transitions during OFF state i.e. we no longer waste 500ms (or whatever transition time is set to) on boot doing nothing - transition time + step parameter for the lightUpdate - report mask parameter for the lightUpdate - minor fixes across the board resolve #2222
3 years ago
providers: relays, lights and buttons refactoring (#2414) - gpio module now tracks the known providers (right now, hardware and mcp expander) - refactored relay struct to use 'Provider' implementing setup,notify,change,boot instead of just BasePin actions - refactored button module to use gpio provider instead of referencing types itself - removed dual & stm code from buttons, migrate both to relay module - added status notify and change callbacks for relayStatus (i.e. 'notify' when relay status was called, but not changed. and 'changed' when it did) - relays runtime configuration keys - relay command now shows configured relays and current & target statuses - refactor the code using relayStatus(0, blah) under LIGHT_PROVIDER check to use lightState instead - remove rfbridge code form relay module. implement through a basic state listener in the rfbridge module, depend on RELAY_SUPPORT - allow to bind rf codes to real relays - drop tuya-specific lights provider, remove tuya code from relays and lights modules - integrate tuya via relay listeners and providers, use lights custom provider - implement channel transitions for tuya. disabled by default, and transition time and step are overridden to 2000 + 100. needs to be set to some value below the total time (i.e. `total transition time / step time == number of steps`, we need to figure out a correct time that serial comms could handle) - lights custom provider (global, not per-pin) and state listeners - remove lights code from relay module. implement through providers & listeners in the lights module, depend on RELAY_SUPPORT - lights per-channel relay provider (unused atm), depend on RELAY_SUPPORT - refactored channel transition - calculate step only once, make sure time + step values are sane, generate quick transitions with very small delay (10ms hardcoded) for transitions during OFF state i.e. we no longer waste 500ms (or whatever transition time is set to) on boot doing nothing - transition time + step parameter for the lightUpdate - report mask parameter for the lightUpdate - minor fixes across the board resolve #2222
3 years ago
providers: relays, lights and buttons refactoring (#2414) - gpio module now tracks the known providers (right now, hardware and mcp expander) - refactored relay struct to use 'Provider' implementing setup,notify,change,boot instead of just BasePin actions - refactored button module to use gpio provider instead of referencing types itself - removed dual & stm code from buttons, migrate both to relay module - added status notify and change callbacks for relayStatus (i.e. 'notify' when relay status was called, but not changed. and 'changed' when it did) - relays runtime configuration keys - relay command now shows configured relays and current & target statuses - refactor the code using relayStatus(0, blah) under LIGHT_PROVIDER check to use lightState instead - remove rfbridge code form relay module. implement through a basic state listener in the rfbridge module, depend on RELAY_SUPPORT - allow to bind rf codes to real relays - drop tuya-specific lights provider, remove tuya code from relays and lights modules - integrate tuya via relay listeners and providers, use lights custom provider - implement channel transitions for tuya. disabled by default, and transition time and step are overridden to 2000 + 100. needs to be set to some value below the total time (i.e. `total transition time / step time == number of steps`, we need to figure out a correct time that serial comms could handle) - lights custom provider (global, not per-pin) and state listeners - remove lights code from relay module. implement through providers & listeners in the lights module, depend on RELAY_SUPPORT - lights per-channel relay provider (unused atm), depend on RELAY_SUPPORT - refactored channel transition - calculate step only once, make sure time + step values are sane, generate quick transitions with very small delay (10ms hardcoded) for transitions during OFF state i.e. we no longer waste 500ms (or whatever transition time is set to) on boot doing nothing - transition time + step parameter for the lightUpdate - report mask parameter for the lightUpdate - minor fixes across the board resolve #2222
3 years ago
providers: relays, lights and buttons refactoring (#2414) - gpio module now tracks the known providers (right now, hardware and mcp expander) - refactored relay struct to use 'Provider' implementing setup,notify,change,boot instead of just BasePin actions - refactored button module to use gpio provider instead of referencing types itself - removed dual & stm code from buttons, migrate both to relay module - added status notify and change callbacks for relayStatus (i.e. 'notify' when relay status was called, but not changed. and 'changed' when it did) - relays runtime configuration keys - relay command now shows configured relays and current & target statuses - refactor the code using relayStatus(0, blah) under LIGHT_PROVIDER check to use lightState instead - remove rfbridge code form relay module. implement through a basic state listener in the rfbridge module, depend on RELAY_SUPPORT - allow to bind rf codes to real relays - drop tuya-specific lights provider, remove tuya code from relays and lights modules - integrate tuya via relay listeners and providers, use lights custom provider - implement channel transitions for tuya. disabled by default, and transition time and step are overridden to 2000 + 100. needs to be set to some value below the total time (i.e. `total transition time / step time == number of steps`, we need to figure out a correct time that serial comms could handle) - lights custom provider (global, not per-pin) and state listeners - remove lights code from relay module. implement through providers & listeners in the lights module, depend on RELAY_SUPPORT - lights per-channel relay provider (unused atm), depend on RELAY_SUPPORT - refactored channel transition - calculate step only once, make sure time + step values are sane, generate quick transitions with very small delay (10ms hardcoded) for transitions during OFF state i.e. we no longer waste 500ms (or whatever transition time is set to) on boot doing nothing - transition time + step parameter for the lightUpdate - report mask parameter for the lightUpdate - minor fixes across the board resolve #2222
3 years ago
providers: relays, lights and buttons refactoring (#2414) - gpio module now tracks the known providers (right now, hardware and mcp expander) - refactored relay struct to use 'Provider' implementing setup,notify,change,boot instead of just BasePin actions - refactored button module to use gpio provider instead of referencing types itself - removed dual & stm code from buttons, migrate both to relay module - added status notify and change callbacks for relayStatus (i.e. 'notify' when relay status was called, but not changed. and 'changed' when it did) - relays runtime configuration keys - relay command now shows configured relays and current & target statuses - refactor the code using relayStatus(0, blah) under LIGHT_PROVIDER check to use lightState instead - remove rfbridge code form relay module. implement through a basic state listener in the rfbridge module, depend on RELAY_SUPPORT - allow to bind rf codes to real relays - drop tuya-specific lights provider, remove tuya code from relays and lights modules - integrate tuya via relay listeners and providers, use lights custom provider - implement channel transitions for tuya. disabled by default, and transition time and step are overridden to 2000 + 100. needs to be set to some value below the total time (i.e. `total transition time / step time == number of steps`, we need to figure out a correct time that serial comms could handle) - lights custom provider (global, not per-pin) and state listeners - remove lights code from relay module. implement through providers & listeners in the lights module, depend on RELAY_SUPPORT - lights per-channel relay provider (unused atm), depend on RELAY_SUPPORT - refactored channel transition - calculate step only once, make sure time + step values are sane, generate quick transitions with very small delay (10ms hardcoded) for transitions during OFF state i.e. we no longer waste 500ms (or whatever transition time is set to) on boot doing nothing - transition time + step parameter for the lightUpdate - report mask parameter for the lightUpdate - minor fixes across the board resolve #2222
3 years ago
providers: relays, lights and buttons refactoring (#2414) - gpio module now tracks the known providers (right now, hardware and mcp expander) - refactored relay struct to use 'Provider' implementing setup,notify,change,boot instead of just BasePin actions - refactored button module to use gpio provider instead of referencing types itself - removed dual & stm code from buttons, migrate both to relay module - added status notify and change callbacks for relayStatus (i.e. 'notify' when relay status was called, but not changed. and 'changed' when it did) - relays runtime configuration keys - relay command now shows configured relays and current & target statuses - refactor the code using relayStatus(0, blah) under LIGHT_PROVIDER check to use lightState instead - remove rfbridge code form relay module. implement through a basic state listener in the rfbridge module, depend on RELAY_SUPPORT - allow to bind rf codes to real relays - drop tuya-specific lights provider, remove tuya code from relays and lights modules - integrate tuya via relay listeners and providers, use lights custom provider - implement channel transitions for tuya. disabled by default, and transition time and step are overridden to 2000 + 100. needs to be set to some value below the total time (i.e. `total transition time / step time == number of steps`, we need to figure out a correct time that serial comms could handle) - lights custom provider (global, not per-pin) and state listeners - remove lights code from relay module. implement through providers & listeners in the lights module, depend on RELAY_SUPPORT - lights per-channel relay provider (unused atm), depend on RELAY_SUPPORT - refactored channel transition - calculate step only once, make sure time + step values are sane, generate quick transitions with very small delay (10ms hardcoded) for transitions during OFF state i.e. we no longer waste 500ms (or whatever transition time is set to) on boot doing nothing - transition time + step parameter for the lightUpdate - report mask parameter for the lightUpdate - minor fixes across the board resolve #2222
3 years ago
providers: relays, lights and buttons refactoring (#2414) - gpio module now tracks the known providers (right now, hardware and mcp expander) - refactored relay struct to use 'Provider' implementing setup,notify,change,boot instead of just BasePin actions - refactored button module to use gpio provider instead of referencing types itself - removed dual & stm code from buttons, migrate both to relay module - added status notify and change callbacks for relayStatus (i.e. 'notify' when relay status was called, but not changed. and 'changed' when it did) - relays runtime configuration keys - relay command now shows configured relays and current & target statuses - refactor the code using relayStatus(0, blah) under LIGHT_PROVIDER check to use lightState instead - remove rfbridge code form relay module. implement through a basic state listener in the rfbridge module, depend on RELAY_SUPPORT - allow to bind rf codes to real relays - drop tuya-specific lights provider, remove tuya code from relays and lights modules - integrate tuya via relay listeners and providers, use lights custom provider - implement channel transitions for tuya. disabled by default, and transition time and step are overridden to 2000 + 100. needs to be set to some value below the total time (i.e. `total transition time / step time == number of steps`, we need to figure out a correct time that serial comms could handle) - lights custom provider (global, not per-pin) and state listeners - remove lights code from relay module. implement through providers & listeners in the lights module, depend on RELAY_SUPPORT - lights per-channel relay provider (unused atm), depend on RELAY_SUPPORT - refactored channel transition - calculate step only once, make sure time + step values are sane, generate quick transitions with very small delay (10ms hardcoded) for transitions during OFF state i.e. we no longer waste 500ms (or whatever transition time is set to) on boot doing nothing - transition time + step parameter for the lightUpdate - report mask parameter for the lightUpdate - minor fixes across the board resolve #2222
3 years ago
webui: remove jquery dependencies and clean-up websocket API Refactor WebUI: - remove jquery dependency from the base custom.js and use vanilla JS - remove jquery + jquery-datatables dependency from the RFM69 module - replace jquery-datatables handlers with pure-css table + some basic cell filtering (may be incomplete, but tbh it is not worth additional 50Kb to the .bin size) - introduce a common way to notify about the app errors, show small text notification at the top of the page instead of relying on user to find out about errors by using the Web Developer Tools - replace <span name=...> with <span data-settings-key=...> - replace <div> templates with <template>, disallowing modification without an explicit DOM clone - run `eslint` on html/custom.js and `html-validate` on html/index.html, and fix issues detected by both tools Streamline settings group handling in custom.js & index.html - drop module-specific button-add-... in favour of button-add-settings-group - only enforce data-settings-max requirement when the property actually exists - re-create label for=... and input id=... when settings group is modified, so checkboxes refer to the correct element - introduce additional data-... properties to generalize settings group additions - introduce Enumerable object to track some common list elements for <select>, allow to re-create <option> list when messages come in different order Minor fixes that also came with this: - fix relay code incorrectly parsing the payload, causing no relay names to be displayed in the SWITCHES panel - fix scheduler code accidentally combining keys b/c of the way C parses string literals on separate lines, without any commas in-between - thermostat should not reference tmpUnit directly in the webui, replace with module-specific thermostatUnit that is handled on the device itself - fix index.html initial setup invalid adminPass ids - fix index.html layout when removing specific schedules
2 years ago
webui: remove jquery dependencies and clean-up websocket API Refactor WebUI: - remove jquery dependency from the base custom.js and use vanilla JS - remove jquery + jquery-datatables dependency from the RFM69 module - replace jquery-datatables handlers with pure-css table + some basic cell filtering (may be incomplete, but tbh it is not worth additional 50Kb to the .bin size) - introduce a common way to notify about the app errors, show small text notification at the top of the page instead of relying on user to find out about errors by using the Web Developer Tools - replace <span name=...> with <span data-settings-key=...> - replace <div> templates with <template>, disallowing modification without an explicit DOM clone - run `eslint` on html/custom.js and `html-validate` on html/index.html, and fix issues detected by both tools Streamline settings group handling in custom.js & index.html - drop module-specific button-add-... in favour of button-add-settings-group - only enforce data-settings-max requirement when the property actually exists - re-create label for=... and input id=... when settings group is modified, so checkboxes refer to the correct element - introduce additional data-... properties to generalize settings group additions - introduce Enumerable object to track some common list elements for <select>, allow to re-create <option> list when messages come in different order Minor fixes that also came with this: - fix relay code incorrectly parsing the payload, causing no relay names to be displayed in the SWITCHES panel - fix scheduler code accidentally combining keys b/c of the way C parses string literals on separate lines, without any commas in-between - thermostat should not reference tmpUnit directly in the webui, replace with module-specific thermostatUnit that is handled on the device itself - fix index.html initial setup invalid adminPass ids - fix index.html layout when removing specific schedules
2 years ago
webui: remove jquery dependencies and clean-up websocket API Refactor WebUI: - remove jquery dependency from the base custom.js and use vanilla JS - remove jquery + jquery-datatables dependency from the RFM69 module - replace jquery-datatables handlers with pure-css table + some basic cell filtering (may be incomplete, but tbh it is not worth additional 50Kb to the .bin size) - introduce a common way to notify about the app errors, show small text notification at the top of the page instead of relying on user to find out about errors by using the Web Developer Tools - replace <span name=...> with <span data-settings-key=...> - replace <div> templates with <template>, disallowing modification without an explicit DOM clone - run `eslint` on html/custom.js and `html-validate` on html/index.html, and fix issues detected by both tools Streamline settings group handling in custom.js & index.html - drop module-specific button-add-... in favour of button-add-settings-group - only enforce data-settings-max requirement when the property actually exists - re-create label for=... and input id=... when settings group is modified, so checkboxes refer to the correct element - introduce additional data-... properties to generalize settings group additions - introduce Enumerable object to track some common list elements for <select>, allow to re-create <option> list when messages come in different order Minor fixes that also came with this: - fix relay code incorrectly parsing the payload, causing no relay names to be displayed in the SWITCHES panel - fix scheduler code accidentally combining keys b/c of the way C parses string literals on separate lines, without any commas in-between - thermostat should not reference tmpUnit directly in the webui, replace with module-specific thermostatUnit that is handled on the device itself - fix index.html initial setup invalid adminPass ids - fix index.html layout when removing specific schedules
2 years ago
webui: remove jquery dependencies and clean-up websocket API Refactor WebUI: - remove jquery dependency from the base custom.js and use vanilla JS - remove jquery + jquery-datatables dependency from the RFM69 module - replace jquery-datatables handlers with pure-css table + some basic cell filtering (may be incomplete, but tbh it is not worth additional 50Kb to the .bin size) - introduce a common way to notify about the app errors, show small text notification at the top of the page instead of relying on user to find out about errors by using the Web Developer Tools - replace <span name=...> with <span data-settings-key=...> - replace <div> templates with <template>, disallowing modification without an explicit DOM clone - run `eslint` on html/custom.js and `html-validate` on html/index.html, and fix issues detected by both tools Streamline settings group handling in custom.js & index.html - drop module-specific button-add-... in favour of button-add-settings-group - only enforce data-settings-max requirement when the property actually exists - re-create label for=... and input id=... when settings group is modified, so checkboxes refer to the correct element - introduce additional data-... properties to generalize settings group additions - introduce Enumerable object to track some common list elements for <select>, allow to re-create <option> list when messages come in different order Minor fixes that also came with this: - fix relay code incorrectly parsing the payload, causing no relay names to be displayed in the SWITCHES panel - fix scheduler code accidentally combining keys b/c of the way C parses string literals on separate lines, without any commas in-between - thermostat should not reference tmpUnit directly in the webui, replace with module-specific thermostatUnit that is handled on the device itself - fix index.html initial setup invalid adminPass ids - fix index.html layout when removing specific schedules
2 years ago
webui: remove jquery dependencies and clean-up websocket API Refactor WebUI: - remove jquery dependency from the base custom.js and use vanilla JS - remove jquery + jquery-datatables dependency from the RFM69 module - replace jquery-datatables handlers with pure-css table + some basic cell filtering (may be incomplete, but tbh it is not worth additional 50Kb to the .bin size) - introduce a common way to notify about the app errors, show small text notification at the top of the page instead of relying on user to find out about errors by using the Web Developer Tools - replace <span name=...> with <span data-settings-key=...> - replace <div> templates with <template>, disallowing modification without an explicit DOM clone - run `eslint` on html/custom.js and `html-validate` on html/index.html, and fix issues detected by both tools Streamline settings group handling in custom.js & index.html - drop module-specific button-add-... in favour of button-add-settings-group - only enforce data-settings-max requirement when the property actually exists - re-create label for=... and input id=... when settings group is modified, so checkboxes refer to the correct element - introduce additional data-... properties to generalize settings group additions - introduce Enumerable object to track some common list elements for <select>, allow to re-create <option> list when messages come in different order Minor fixes that also came with this: - fix relay code incorrectly parsing the payload, causing no relay names to be displayed in the SWITCHES panel - fix scheduler code accidentally combining keys b/c of the way C parses string literals on separate lines, without any commas in-between - thermostat should not reference tmpUnit directly in the webui, replace with module-specific thermostatUnit that is handled on the device itself - fix index.html initial setup invalid adminPass ids - fix index.html layout when removing specific schedules
2 years ago
webui: remove jquery dependencies and clean-up websocket API Refactor WebUI: - remove jquery dependency from the base custom.js and use vanilla JS - remove jquery + jquery-datatables dependency from the RFM69 module - replace jquery-datatables handlers with pure-css table + some basic cell filtering (may be incomplete, but tbh it is not worth additional 50Kb to the .bin size) - introduce a common way to notify about the app errors, show small text notification at the top of the page instead of relying on user to find out about errors by using the Web Developer Tools - replace <span name=...> with <span data-settings-key=...> - replace <div> templates with <template>, disallowing modification without an explicit DOM clone - run `eslint` on html/custom.js and `html-validate` on html/index.html, and fix issues detected by both tools Streamline settings group handling in custom.js & index.html - drop module-specific button-add-... in favour of button-add-settings-group - only enforce data-settings-max requirement when the property actually exists - re-create label for=... and input id=... when settings group is modified, so checkboxes refer to the correct element - introduce additional data-... properties to generalize settings group additions - introduce Enumerable object to track some common list elements for <select>, allow to re-create <option> list when messages come in different order Minor fixes that also came with this: - fix relay code incorrectly parsing the payload, causing no relay names to be displayed in the SWITCHES panel - fix scheduler code accidentally combining keys b/c of the way C parses string literals on separate lines, without any commas in-between - thermostat should not reference tmpUnit directly in the webui, replace with module-specific thermostatUnit that is handled on the device itself - fix index.html initial setup invalid adminPass ids - fix index.html layout when removing specific schedules
2 years ago
webui: remove jquery dependencies and clean-up websocket API Refactor WebUI: - remove jquery dependency from the base custom.js and use vanilla JS - remove jquery + jquery-datatables dependency from the RFM69 module - replace jquery-datatables handlers with pure-css table + some basic cell filtering (may be incomplete, but tbh it is not worth additional 50Kb to the .bin size) - introduce a common way to notify about the app errors, show small text notification at the top of the page instead of relying on user to find out about errors by using the Web Developer Tools - replace <span name=...> with <span data-settings-key=...> - replace <div> templates with <template>, disallowing modification without an explicit DOM clone - run `eslint` on html/custom.js and `html-validate` on html/index.html, and fix issues detected by both tools Streamline settings group handling in custom.js & index.html - drop module-specific button-add-... in favour of button-add-settings-group - only enforce data-settings-max requirement when the property actually exists - re-create label for=... and input id=... when settings group is modified, so checkboxes refer to the correct element - introduce additional data-... properties to generalize settings group additions - introduce Enumerable object to track some common list elements for <select>, allow to re-create <option> list when messages come in different order Minor fixes that also came with this: - fix relay code incorrectly parsing the payload, causing no relay names to be displayed in the SWITCHES panel - fix scheduler code accidentally combining keys b/c of the way C parses string literals on separate lines, without any commas in-between - thermostat should not reference tmpUnit directly in the webui, replace with module-specific thermostatUnit that is handled on the device itself - fix index.html initial setup invalid adminPass ids - fix index.html layout when removing specific schedules
2 years ago
  1. /*
  2. GPIO MODULE
  3. Copyright (C) 2017-2019 by Xose Pérez <xose dot perez at gmail dot com>
  4. */
  5. #include "espurna.h"
  6. // --------------------------------------------------------------------------
  7. #include <bitset>
  8. #include <utility>
  9. #include "mcp23s08_pin.h"
  10. #include "rtcmem.h"
  11. #include "terminal.h"
  12. #if WEB_SUPPORT
  13. #include "ws.h"
  14. #endif
  15. namespace espurna {
  16. namespace peripherals {
  17. namespace {
  18. // TODO: `struct Register { ... }` with additional size params?
  19. // e.g. GPIO IN / OUT register is techically u16, and we don't detect writing past the allowed 'mask'
  20. // something with direct field access may be useful, too; like handling function-select for io mux
  21. // but, *something other than bitfields*, since we can't really guarantee compiler won't optimize reads / writes
  22. // (and since we are not bound by the SDK requirement of writing in C, and could just write C++ code)
  23. inline uint32_t reg_read(uintptr_t) __attribute__((always_inline));
  24. uint32_t reg_read(uintptr_t address) {
  25. return *reinterpret_cast<volatile uint32_t*>(address);
  26. }
  27. inline void reg_write(uintptr_t, uint32_t) __attribute__((always_inline));
  28. void reg_write(uintptr_t address, uint32_t value) {
  29. *reinterpret_cast<volatile uint32_t*>(address) = value;
  30. }
  31. template <typename T>
  32. inline void reg_apply(uintptr_t, T&&) __attribute__((always_inline));
  33. template <typename T>
  34. void reg_apply(uintptr_t address, T&& func) {
  35. static_assert(!std::is_integral<T>::value, "");
  36. reg_write(address, func(reg_read(address)));
  37. }
  38. // At the time of writing this...
  39. // Current version of Arduino Core uses NONOS, plus a set of "AVR-Style" macros
  40. // - https://github.com/esp8266/Arduino/blob/3.0.2/cores/esp8266/esp8266_peri.h
  41. //
  42. // NONOS does not really have a very good register reference
  43. // - https://github.com/espressif/ESP8266_NONOS_SDK/blob/release/v3.0.5/include/eagle_soc.h
  44. // (base addresses, register get / set macros, etc.)
  45. // - https://github.com/espressif/ESP8266_NONOS_SDK/blob/release/v3.0.5/driver_lib/include/driver/slc_register.h
  46. // - https://github.com/espressif/ESP8266_NONOS_SDK/blob/release/v3.0.5/driver_lib/include/driver/spi_register.h
  47. // - https://github.com/espressif/ESP8266_NONOS_SDK/blob/release/v3.0.5/driver_lib/include/driver/uart_register.h
  48. // (note that Core still uses v2.2, but it is not available through github)
  49. //
  50. // While the more recent RTOS SDK (based on esp-idf v3.4) has even more *_register.h headers
  51. // Plus, especially helpful are the newly introduced *_struct.h headers, where structs are mapped
  52. // on register memory addresses and specific bits or range of bits are declared through bitfields.
  53. // - https://github.com/espressif/ESP8266_RTOS_SDK/blob/release/v3.4/components/esp8266/include/esp8266/eagle_soc.h
  54. // - https://github.com/espressif/ESP8266_RTOS_SDK/blob/release/v3.4/components/esp8266/include/esp8266/efuse_register.h
  55. // - https://github.com/espressif/ESP8266_RTOS_SDK/blob/release/v3.4/components/esp8266/include/esp8266/pin_mux_register.h
  56. // - https://github.com/espressif/ESP8266_RTOS_SDK/blob/release/v3.4/components/esp8266/include/esp8266/rtc_register.h
  57. // - https://github.com/espressif/ESP8266_RTOS_SDK/blob/release/v3.4/components/esp8266/include/esp8266/slc_register.h
  58. // - https://github.com/espressif/ESP8266_RTOS_SDK/blob/release/v3.4/components/esp8266/include/esp8266/spi_register.h
  59. // - https://github.com/espressif/ESP8266_RTOS_SDK/blob/release/v3.4/components/esp8266/include/esp8266/timer_register.h
  60. // - https://github.com/espressif/ESP8266_RTOS_SDK/blob/release/v3.4/components/esp8266/include/esp8266/uart_register.h
  61. //
  62. // Current ESP32 boards have CMSIS-SVD (.svd) that may be used for code generation
  63. // - https://github.com/espressif/svd/
  64. // But, there does not seem to be anything up-to-date for ESP8266.
  65. //
  66. // Rust-based esp-pacs project provides one
  67. // - https://github.com/esp-rs/esp-pacs/blob/main/esp8266/svd/esp8266.base.svd
  68. // Be aware that it suffers the same problem as RTOS implementation, though,
  69. // sometimes mixing in ESP32 terms that don't really apply to ESP8266
  70. //
  71. // Here we opt into the RTOS-style approach, but have it private to this file.
  72. static constexpr uintptr_t AddressBase { 0x60000000 };
  73. namespace efuse {
  74. static constexpr uintptr_t AddressBase { 0x3ff00050 };
  75. static constexpr uintptr_t Data0 { AddressBase };
  76. static constexpr uintptr_t Data1 { AddressBase + 0x4 };
  77. static constexpr uintptr_t Data2 { AddressBase + 0x8 };
  78. static constexpr uintptr_t Data3 { AddressBase + 0xc };
  79. using Data = std::array<uint32_t, 4>;
  80. inline Data data() {
  81. return {{
  82. reg_read(Data0),
  83. reg_read(Data1),
  84. reg_read(Data2),
  85. reg_read(Data3),
  86. }};
  87. }
  88. } // namespace efuse
  89. namespace rtc {
  90. static constexpr uintptr_t AddressBase { peripherals::AddressBase + 0x700 };
  91. static constexpr uintptr_t PadXpdDcdcConf { AddressBase + 0xA0 };
  92. static constexpr uintptr_t GpioOutput { AddressBase + 0x68 };
  93. static constexpr uintptr_t GpioEnable { AddressBase + 0x74 };
  94. static constexpr uintptr_t GpioInput { AddressBase + 0x8C };
  95. static constexpr uintptr_t GpioConf { AddressBase + 0x90 };
  96. // 2 low bits, 1 high; same as iomux register
  97. static constexpr uint32_t FunctionSelectMask { (1 << 6) | (1 << 1) | 1 };
  98. // no other pin allows pulldown
  99. static constexpr uint32_t Pulldown { (1 << 3) };
  100. inline bool gpio16_get() __attribute__((always_inline));
  101. bool gpio16_get() {
  102. return reg_read(GpioInput) & 0b1;
  103. }
  104. inline void gpio16_set(bool) __attribute__((always_inline));
  105. void gpio16_set(bool status) {
  106. reg_apply(
  107. GpioOutput,
  108. [=](uint32_t value) {
  109. return status ? (value | 0b1) : (value & ~0b1);
  110. });
  111. }
  112. void gpio16_mode(int8_t mode) {
  113. reg_apply(
  114. PadXpdDcdcConf,
  115. [=](uint32_t value) {
  116. // Like RTOS attempts to preserve existing function-select,
  117. // first masking with the full mask and then setting the 1st bit
  118. // (neither RTOS or NONOS really explain it... so, :shrug:)
  119. value &= ~FunctionSelectMask;
  120. value |= 0b1;
  121. // ESP8266 does not have INPUT_PULLDOWN definition, and instead
  122. // has a GPIO16-specific INPUT_PULLDOWN_16:
  123. // - https://github.com/esp8266/Arduino/issues/478
  124. // - https://github.com/esp8266/Arduino/commit/1b3581d55ebf0f8c91e081f9af4cf7433d492ec9
  125. // Only RTOS SDK includes GPIO definitions, so we include our own unused flag for compatibility
  126. // (and continue to hope it does not collide with FUNCTION... mask checks)
  127. value &= ~Pulldown;
  128. if ((mode == INPUT_PULLDOWN) || (mode == INPUT_PULLDOWN_16)) {
  129. value |= Pulldown;
  130. }
  131. return value;
  132. });
  133. // Arduino always erased this, RTOS applies mask. just to be safe
  134. reg_apply(
  135. GpioConf,
  136. [=](uint32_t value) {
  137. return value & ~0b1;
  138. });
  139. // Same as above, 1st bit controls the direction
  140. reg_apply(
  141. GpioEnable,
  142. [=](uint32_t value) {
  143. value &= ~0b1;
  144. if (mode == OUTPUT) {
  145. value |= 0b1;
  146. }
  147. return value;
  148. });
  149. }
  150. } // namespace rtc
  151. namespace pin {
  152. static constexpr uintptr_t AddressBase { peripherals::AddressBase + 0x300 };
  153. static constexpr uintptr_t GpioOutput { AddressBase };
  154. static constexpr uintptr_t GpioOutputSet { AddressBase + 0x4 };
  155. static constexpr uintptr_t GpioOutputClear { AddressBase + 0x8 };
  156. static constexpr uintptr_t GpioEnable { AddressBase + 0xC };
  157. static constexpr uintptr_t GpioEnableSet { AddressBase + 0x10 };
  158. static constexpr uintptr_t GpioEnableClear { AddressBase + 0x14 };
  159. static constexpr uintptr_t GpioInput { AddressBase + 0x18 };
  160. static constexpr uintptr_t GpioInterupt { AddressBase + 0x1C };
  161. static constexpr uintptr_t GpioInteruptSet { AddressBase + 0x20 };
  162. static constexpr uintptr_t GpioInteruptClear { AddressBase + 0x24 };
  163. static constexpr uintptr_t GpioControlBase { peripherals::AddressBase + 0x328 };
  164. static constexpr uintptr_t IoMuxBase { peripherals::AddressBase + 0x800 };
  165. // IO Mux values
  166. // the actual 'function' is described purely through the token name
  167. // we see in pin_mux_register.h, it may not be the same for two
  168. // different pins. plus, gpio16 has a completely different register layout
  169. // (see rtc namespace)
  170. static constexpr uint32_t FunctionLowBit1 { (1 << 4) };
  171. static constexpr uint32_t FunctionLowBit2 { (1 << 5) };
  172. static constexpr uint32_t FunctionHighBit { (1 << 8) };
  173. static constexpr uint32_t PullupMask { (1 << 7) };
  174. static constexpr uint32_t FunctionSelectMask { FunctionHighBit | FunctionLowBit2 | FunctionLowBit1 };
  175. static constexpr uint32_t IoMuxMask { PullupMask | FunctionSelectMask };
  176. // Control values
  177. static constexpr uint32_t Source { 1 };
  178. static constexpr uint32_t Driver { (1 << 2) };
  179. // normal interrupt types
  180. static constexpr uint32_t InterruptRising { (1 << 7) }; // aka positive edge
  181. static constexpr uint32_t InterruptFalling { (1 << 8) }; // aka negative edge
  182. static constexpr uint32_t InterruptChange { (1 << 8) | (1 << 7) }; // aka any edge
  183. // special wake-up interrupts
  184. static constexpr uint32_t InterruptLow { (1 << 9) }; // aka low level trigger
  185. static constexpr uint32_t InterruptHigh { (1 << 9) | (1 << 7) }; // aka high level trigger
  186. static constexpr uint32_t WakeupEnabled { (1 << 10) }; // ^ should set this bit as well when low or high are set
  187. static constexpr uint32_t InterruptMask { (1 << 9) | (1 << 8) | (1 << 7) };
  188. static constexpr uint32_t ControlMask { WakeupEnabled | InterruptMask | Driver | Source };
  189. // ref. PERIPHS_IO_MUX_...
  190. constexpr uintptr_t ioMuxOffset(uint8_t pin) {
  191. return (pin == 0) ? 0x34 :
  192. (pin == 1) ? 0x18 :
  193. (pin == 2) ? 0x38 :
  194. (pin == 3) ? 0x14 :
  195. (pin == 4) ? 0x3C :
  196. (pin == 5) ? 0x40 :
  197. (pin == 6) ? 0x1C :
  198. (pin == 7) ? 0x20 :
  199. (pin == 8) ? 0x24 :
  200. (pin == 9) ? 0x28 :
  201. (pin == 10) ? 0x2C :
  202. (pin == 11) ? 0x30 :
  203. (pin == 12) ? 0x04 :
  204. (pin == 13) ? 0x08 :
  205. (pin == 14) ? 0x0C :
  206. (pin == 15) ? 0x10 : 0;
  207. }
  208. constexpr uintptr_t ioMuxAddress(uint8_t pin) {
  209. return IoMuxBase + ioMuxOffset(pin);
  210. }
  211. constexpr uintptr_t controlOffset(uint8_t pin) {
  212. return (pin & 0xf) * 4;
  213. }
  214. constexpr uintptr_t controlAddress(uint8_t pin) {
  215. return GpioControlBase + controlOffset(pin);
  216. }
  217. inline void set(uint8_t, bool) __attribute__((always_inline));
  218. void set(uint8_t pin, bool status) {
  219. reg_write(status ? GpioOutputSet : GpioOutputClear, (1 << pin));
  220. }
  221. inline bool get(uint8_t) __attribute__((always_inline));
  222. bool get(uint8_t pin) {
  223. return reg_read(GpioInput) & (1 << pin);
  224. }
  225. // ref. function numbers (FUNC_...) used in the header and techical reference
  226. // with the exception of 4 pins, everything sets it to 3 (0b11)
  227. // ──────────────────────────────────────────────────────────────────────────
  228. // #define GPFFS_GPIO(p)
  229. // (((p) == 0 || (p) == 2 || (p) == 4 || (p) == 5) ? 0
  230. // : ((p) == 16) ? 1
  231. // : 3)
  232. constexpr uint32_t function_select_gpio(uint8_t pin) {
  233. return ((pin == 0) || (pin == 2) || (pin == 4) || (pin == 5))
  234. ? 0 : (FunctionLowBit2 | FunctionLowBit1);
  235. }
  236. // NONOS SDK `GPFFS_BUS`, with 'bus' function bits for certain pins (like SPI, UART, I2S, etc.)
  237. // ────────────────────────────────────────────────────────────────────────────────────────────
  238. // #define GPFFS_BUS(p)
  239. // (((p) == 1 || (p) == 3) ? 0
  240. // : ((p) == 2 || (p) == 12 || (p) == 13 || (p) == 14 || (p) == 15) ? 2
  241. // : ((p) == 0) ? 4
  242. // : 1)
  243. constexpr uint32_t function_select_arduino_special(uint8_t pin) {
  244. return ((pin == 1) || (pin == 3))
  245. ? 0 :
  246. ((pin == 2) || (pin == 12)
  247. || (pin == 13) || (pin == 14)
  248. || (pin == 15))
  249. ? FunctionLowBit2 :
  250. (pin == 0)
  251. ? FunctionHighBit
  252. : FunctionLowBit1;
  253. }
  254. // Arduino, like SDK, encodes function select in a 3bit mask that is later 'unpacked'
  255. // into a real mask. Simple if-else, since the original involves unnecessary optional shifts.
  256. constexpr uint32_t function_select_arduino_mask(uint8_t mode) {
  257. return (mode == FUNCTION_1) ? FunctionLowBit1 :
  258. (mode == FUNCTION_2) ? FunctionLowBit2 :
  259. (mode == FUNCTION_3) ? (FunctionLowBit2 | FunctionLowBit1) :
  260. (mode == FUNCTION_4) ? FunctionHighBit : 0;
  261. }
  262. // For some reason, PULLUP was not encoded in the mode directly, so UART
  263. // should be configured by us as well to avoid these exceptional cases
  264. constexpr uint32_t pullup_arduino_mask(uint8_t pin, uint8_t mode) {
  265. return (((pin == 13) && (mode == FUNCTION_4))
  266. || ((pin == 3) && (mode == SPECIAL))) ? PullupMask : 0;
  267. }
  268. // Will be exposed as `pinMode(pin, mode)`, must maintain Arduino compatibility with mode selection
  269. void mode(uint8_t pin, uint8_t mode) {
  270. reg_apply(
  271. ioMuxAddress(pin),
  272. [=](uint32_t value) {
  273. value &= ~PullupMask;
  274. if (mode == INPUT_PULLUP) {
  275. value |= PullupMask;
  276. }
  277. // b/c Arduino core only has `pinMode` and does not
  278. // have something like `pinPullup` or `pinFunction`,
  279. // we are forced into handling these special cases
  280. value |= pullup_arduino_mask(pin, mode);
  281. value &= ~FunctionSelectMask;
  282. if (mode == SPECIAL) {
  283. value |= function_select_arduino_special(pin);
  284. } else if (mode & FUNCTION_0) {
  285. value |= function_select_arduino_mask(mode);
  286. } else {
  287. value |= function_select_gpio(pin);
  288. }
  289. return value;
  290. });
  291. // Notice that Core also implements WAKEUP_PULL{UP,DOWN}, that attempt to wrap around
  292. // the LOW and HIGH wakeup triggers (respectively). The issue is, pull{up,down} means
  293. // internal bit setting as well, since only the UP bits works for GPIO0...15
  294. // Simply ignoring those modes
  295. switch (mode) {
  296. case INPUT:
  297. case INPUT_PULLUP:
  298. case SPECIAL:
  299. case FUNCTION_1:
  300. case FUNCTION_2:
  301. case FUNCTION_3:
  302. case FUNCTION_4:
  303. reg_apply(
  304. GpioEnableClear,
  305. [=](uint32_t value) {
  306. return value | (1 << pin);
  307. });
  308. break;
  309. }
  310. // notice that we preserve interrupt mask, but it is not yet clear
  311. // whether it is the right approach.
  312. reg_apply(
  313. controlAddress(pin),
  314. [=](uint32_t value) {
  315. value &= (WakeupEnabled | InterruptMask);
  316. if ((mode == INPUT) || (mode == OUTPUT_OPEN_DRAIN)) {
  317. value |= Driver;
  318. }
  319. return value;
  320. });
  321. // FUNCTION_0 special case for TX pin. Does not really seem to matter in hardware,
  322. // but useful for debug code checking whether it's INPUT or OUTPUT
  323. if ((mode == OUTPUT) || (mode == OUTPUT_OPEN_DRAIN) || (mode == FUNCTION_0)) {
  324. reg_apply(
  325. GpioEnableSet,
  326. [=](uint32_t value) {
  327. return value | (1 << pin);
  328. });
  329. }
  330. }
  331. } // namespace pin
  332. } // namespace
  333. } // namespace peripherals
  334. namespace gpio {
  335. namespace {
  336. struct PinInfo {
  337. int8_t mode;
  338. bool reading;
  339. };
  340. struct Info {
  341. uint32_t outputs;
  342. uint32_t readings;
  343. bool gpio16_output;
  344. bool gpio16_reading;
  345. bool gpio16_pulldown;
  346. };
  347. Info info() {
  348. using peripherals::reg_read;
  349. using namespace peripherals;
  350. return Info{
  351. .outputs = reg_read(pin::GpioEnable),
  352. .readings = reg_read(pin::GpioInput),
  353. .gpio16_output = (reg_read(rtc::GpioEnable) & 0b1) != 0,
  354. .gpio16_reading = (reg_read(rtc::GpioInput) & 0b1) != 0,
  355. .gpio16_pulldown = (reg_read(rtc::PadXpdDcdcConf) & rtc::Pulldown) != 0,
  356. };
  357. }
  358. struct Reading {
  359. bool value;
  360. };
  361. Reading pin_reading(uint8_t pin, Info info) {
  362. Reading out;
  363. if (pin == 16) {
  364. out.value = info.gpio16_reading;
  365. } else {
  366. out.value = (info.readings & (1 << pin)) != 0;
  367. }
  368. return out;
  369. }
  370. Mode pin_mode(uint8_t pin, Info info) {
  371. Mode out;
  372. out.value = OUTPUT;
  373. if (((pin == 16) && info.gpio16_output)
  374. || ((info.outputs & (pin << pin)) != 0))
  375. {
  376. return out;
  377. }
  378. if ((pin == 16) && (info.gpio16_pulldown)) {
  379. out.value = INPUT_PULLDOWN;
  380. return out;
  381. }
  382. using namespace peripherals;
  383. const auto iomux = reg_read(pin::ioMuxAddress(pin));
  384. if ((iomux & pin::PullupMask) != 0) {
  385. out.value = INPUT_PULLUP;
  386. } else {
  387. out.value = INPUT;
  388. }
  389. return out;
  390. }
  391. namespace settings {
  392. namespace options {
  393. using espurna::settings::options::Enumeration;
  394. PROGMEM_STRING(None, "none");
  395. PROGMEM_STRING(Hardware, "hardware");
  396. #if MCP23S08_SUPPORT
  397. PROGMEM_STRING(Mcp23s08, "mcp23s08");
  398. #endif
  399. static constexpr Enumeration<GpioType> GpioTypeOptions[] PROGMEM {
  400. {GpioType::Hardware, Hardware},
  401. #if MCP23S08_SUPPORT
  402. {GpioType::Mcp23s08, Mcp23s08},
  403. #endif
  404. {GpioType::None, None},
  405. };
  406. } // namespace options
  407. } // namespace settings
  408. // TODO(?)
  409. // will probably stay cached, but... note that both vtable and method are in flash
  410. // may not be safe from within ISR (50/50), and our sensor code still uses Core methods
  411. // possibly, declare and define in header as previous version for forcibly inline?
  412. class Gpio16Pin final : public BasePin {
  413. private:
  414. static constexpr unsigned char Pin { 16 };
  415. public:
  416. Gpio16Pin() = default;
  417. void pinMode(int8_t mode) override {
  418. peripherals::rtc::gpio16_mode(mode);
  419. }
  420. void digitalWrite(int8_t val) override {
  421. peripherals::rtc::gpio16_set(val == 1);
  422. }
  423. int digitalRead() override {
  424. return peripherals::rtc::gpio16_get();
  425. }
  426. unsigned char pin() const override {
  427. return Pin;
  428. }
  429. const char* id() const override {
  430. return "Gpio16Pin";
  431. }
  432. };
  433. class GpioPin final : public BasePin {
  434. public:
  435. GpioPin() = delete;
  436. explicit GpioPin(unsigned char pin) :
  437. _pin(pin)
  438. {}
  439. void pinMode(int8_t mode) override {
  440. peripherals::pin::mode(_pin, mode);
  441. }
  442. void digitalWrite(int8_t val) override {
  443. peripherals::pin::set(_pin, (val == 1));
  444. }
  445. int digitalRead() override {
  446. return peripherals::pin::get(_pin);
  447. }
  448. unsigned char pin() const override {
  449. return _pin;
  450. }
  451. const char* id() const override {
  452. return "GpioPin";
  453. }
  454. private:
  455. unsigned char _pin;
  456. };
  457. class Hardware : public GpioBase {
  458. public:
  459. static constexpr size_t Pins { 17 };
  460. Hardware() {
  461. // https://github.com/espressif/esptool/blob/f04d34bcab29ace798d2d3800ba87020cccbbfdd/esptool.py#L1060-L1070
  462. // "One or the other efuse bit is set for ESP8285"
  463. // https://github.com/espressif/ESP8266_RTOS_SDK/blob/3c055779e9793e5f082afff63a011d6615e73639/components/esp8266/include/esp8266/efuse_register.h#L20-L21
  464. // "define EFUSE_IS_ESP8285 (1 << 4)"
  465. const auto data = peripherals::efuse::data();
  466. _esp8285 = (data[0] & (1 << 4))
  467. || (data[2] & (1 << 16));
  468. }
  469. const char* id() const override {
  470. return "hardware";
  471. }
  472. size_t pins() const override {
  473. return Pins;
  474. }
  475. bool lock(unsigned char index) const override {
  476. return _mask[index];
  477. }
  478. void lock(unsigned char index, bool value) override {
  479. _mask.set(index, value);
  480. }
  481. bool valid(unsigned char index) const override {
  482. switch (index) {
  483. case 0 ... 5:
  484. return true;
  485. case 9:
  486. case 10:
  487. return _esp8285;
  488. case 12 ... 16:
  489. return true;
  490. }
  491. return false;
  492. }
  493. BasePinPtr pin(unsigned char pin) override {
  494. if (pin == 16) {
  495. return std::make_unique<Gpio16Pin>();
  496. }
  497. return std::make_unique<GpioPin>(pin);
  498. }
  499. private:
  500. using Mask = std::bitset<Pins>;
  501. bool _esp8285 { false };
  502. Mask _mask;
  503. };
  504. namespace origin {
  505. namespace internal {
  506. std::forward_list<Origin> origins;
  507. } // namespace internal
  508. void add(Origin origin) {
  509. internal::origins.emplace_front(origin);
  510. }
  511. } // namespace origin
  512. #if WEB_SUPPORT
  513. namespace web {
  514. void onVisible(JsonObject& root) {
  515. JsonObject& config = root.createNestedObject(F("gpioConfig"));
  516. constexpr GpioType known_types[] {
  517. GpioType::Hardware,
  518. #if MCP23S08_SUPPORT
  519. GpioType::Mcp23s08,
  520. #endif
  521. };
  522. JsonArray& types = config.createNestedArray(F("types"));
  523. for (auto& type : known_types) {
  524. auto* base = gpioBase(type);
  525. if (base) {
  526. JsonArray& entry = types.createNestedArray();
  527. entry.add(base->id());
  528. entry.add(static_cast<int>(type));
  529. JsonArray& pins = config.createNestedArray(base->id());
  530. for (size_t pin = 0; pin < base->pins(); ++pin) {
  531. if (base->valid(pin)) {
  532. pins.add(pin);
  533. }
  534. }
  535. }
  536. }
  537. JsonObject& info = root.createNestedObject(F("gpioInfo"));
  538. JsonArray& locks = info.createNestedArray(F("failed-locks"));
  539. for (auto& origin : origin::internal::origins) {
  540. if (!origin.result) {
  541. JsonArray& entry = locks.createNestedArray();
  542. entry.add(origin.pin);
  543. entry.add(origin.location.file);
  544. entry.add(origin.location.func);
  545. entry.add(origin.location.line);
  546. }
  547. }
  548. }
  549. void setup() {
  550. wsRegister()
  551. .onVisible(onVisible);
  552. }
  553. } // namespace web
  554. #endif
  555. #if TERMINAL_SUPPORT
  556. namespace terminal {
  557. PROGMEM_STRING(GpioLocks, "GPIO.LOCKS");
  558. void gpio_list_origins(::terminal::CommandContext&& ctx) {
  559. for (const auto& origin : origin::internal::origins) {
  560. ctx.output.printf_P(PSTR("%c %c %s GPIO%hhu\t%d:%s:%s\n"),
  561. origin.result ? ' ' : '!',
  562. origin.lock ? '*' : ' ',
  563. origin.base, origin.pin,
  564. origin.location.line,
  565. origin.location.file,
  566. origin.location.func);
  567. }
  568. }
  569. PROGMEM_STRING(Gpio, "GPIO");
  570. void gpio_read_write(::terminal::CommandContext&& ctx) {
  571. const int pin = (ctx.argv.size() >= 2)
  572. ? espurna::settings::internal::convert<int>(ctx.argv[1])
  573. : -1;
  574. if ((pin >= 0) && !gpioValid(pin)) {
  575. terminalError(ctx, F("Invalid pin number"));
  576. return;
  577. }
  578. int start = 0;
  579. int end = gpioPins();
  580. const auto gpio_info = info();
  581. switch (ctx.argv.size()) {
  582. case 3:
  583. {
  584. // even in INPUT mode, we are still techically allowed to set output register
  585. // (like it is used in software I2C implementation with INPUT_PULLUP)
  586. const bool status = espurna::settings::internal::convert<bool>(ctx.argv[2]);
  587. if (pin == 16) {
  588. peripherals::rtc::gpio16_set(status);
  589. } else {
  590. peripherals::pin::set(pin, status);
  591. }
  592. break;
  593. }
  594. case 2:
  595. start = pin;
  596. end = pin + 1;
  597. // fallthrough!
  598. case 1:
  599. for (auto current = start; current < end; ++current) {
  600. if (!gpioValid(current)) {
  601. continue;
  602. }
  603. const auto mode = pin_mode(current, gpio_info);
  604. ctx.output.printf_P(
  605. PSTR("%c %6s @ GPIO%02d%s\n"),
  606. gpioLocked(current) ? '*' : ' ',
  607. (mode.value == OUTPUT)
  608. ? PSTR("OUTPUT")
  609. : PSTR("INPUT"),
  610. current,
  611. (mode.value == OUTPUT)
  612. ? ""
  613. : pin_reading(current, gpio_info).value
  614. ? PSTR(" (HIGH)")
  615. : PSTR(" (LOW)"));
  616. }
  617. break;
  618. }
  619. terminalOK(ctx);
  620. }
  621. PROGMEM_STRING(RegRead, "REG.READ");
  622. void reg_read(::terminal::CommandContext&& ctx) {
  623. if (ctx.argv.size() == 2) {
  624. const auto convert = espurna::settings::internal::convert<uint32_t>;
  625. const auto address = convert(ctx.argv[1]);
  626. ctx.output.printf_P(PSTR("0x%08X -> 0x%08X\n"),
  627. address, peripherals::reg_read(address));
  628. terminalOK(ctx);
  629. return;
  630. }
  631. terminalError(ctx, F("REG.READ <ADDRESS>"));
  632. }
  633. PROGMEM_STRING(RegWrite, "REG.WRITE");
  634. void reg_write(::terminal::CommandContext&& ctx) {
  635. if (ctx.argv.size() == 3) {
  636. const auto convert = espurna::settings::internal::convert<uint32_t>;
  637. const auto address = convert(ctx.argv[1]);
  638. const auto value = convert(ctx.argv[2]);
  639. ctx.output.printf_P(PSTR("0x%08X -> 0x%08X\n"), address, value);
  640. peripherals::reg_write(address, value);
  641. terminalOK(ctx);
  642. return;
  643. }
  644. terminalError(ctx, F("REG.WRITE <ADDRESS> <VALUE>"));
  645. }
  646. static constexpr espurna::terminal::Command Commands[] PROGMEM {
  647. {GpioLocks, gpio_list_origins},
  648. {Gpio, gpio_read_write},
  649. {RegRead, reg_read},
  650. {RegWrite, reg_write},
  651. };
  652. void setup() {
  653. espurna::terminal::add(Commands);
  654. }
  655. } // namespace terminal
  656. #endif
  657. } // namespace
  658. Mode pin_mode(uint8_t pin) {
  659. return pin_mode(pin, info());
  660. }
  661. } // namespace gpio
  662. namespace settings {
  663. namespace internal {
  664. namespace {
  665. using gpio::settings::options::GpioTypeOptions;
  666. } // namespace
  667. template <>
  668. GpioType convert(const String& value) {
  669. return convert(GpioTypeOptions, value, GpioType::None);
  670. }
  671. String serialize(GpioType value) {
  672. return serialize(GpioTypeOptions, value);
  673. }
  674. } // namespace internal
  675. } // namespace settings
  676. } // namespace espurna
  677. // --------------------------------------------------------------------------
  678. // Per https://llvm.org/docs/CodingStandards.html#provide-a-virtual-method-anchor-for-classes-in-headers
  679. // > If a class is defined in a header file and has a vtable (either it has virtual methods or it derives from classes with virtual methods),
  680. // > it must always have at least one out-of-line virtual method in the class. Without this, the compiler will copy the vtable and RTTI into
  681. // > every .o file that #includes the header, bloating .o file sizes and increasing link times.
  682. // - http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1263r0.pdf
  683. // > This technique is unfortunate as it relies on detailed knowledge of how common toolchains work, and it may also require creating
  684. // > a dummy virtual function.
  685. //
  686. // `~BasePin() = default;` is technically inlined, so leaving that in the header.
  687. // Thus, ::description() implementation here becomes that anchor for the BasePin.
  688. String BasePin::description() const {
  689. char buffer[64];
  690. snprintf_P(buffer, sizeof(buffer),
  691. PSTR("%s @ GPIO%02hhu"), id(), pin());
  692. return buffer;
  693. }
  694. GpioBase& hardwareGpio() {
  695. static espurna::gpio::Hardware gpio;
  696. return gpio;
  697. }
  698. GpioBase* gpioBase(GpioType type) {
  699. GpioBase* ptr { nullptr };
  700. switch (type) {
  701. case GpioType::Hardware:
  702. ptr = &hardwareGpio();
  703. break;
  704. case GpioType::Mcp23s08:
  705. #if MCP23S08_SUPPORT
  706. ptr = &mcp23s08Gpio();
  707. #endif
  708. break;
  709. case GpioType::None:
  710. break;
  711. }
  712. return ptr;
  713. }
  714. BasePinPtr gpioRegister(GpioBase& base, unsigned char gpio,
  715. espurna::SourceLocation source_location)
  716. {
  717. BasePinPtr result;
  718. if (gpioLock(base, gpio, source_location)) {
  719. result = base.pin(gpio);
  720. }
  721. return result;
  722. }
  723. BasePinPtr gpioRegister(unsigned char gpio, espurna::SourceLocation source_location) {
  724. return gpioRegister(hardwareGpio(), gpio, source_location);
  725. }
  726. void gpioSetup() {
  727. #if WEB_SUPPORT
  728. espurna::gpio::web::setup();
  729. #endif
  730. #if TERMINAL_SUPPORT
  731. espurna::gpio::terminal::setup();
  732. #endif
  733. }
  734. void hardwareGpioIgnore(unsigned char gpio) {
  735. const auto value = Rtcmem->gpio_ignore;
  736. Rtcmem->gpio_ignore = value | (1 << gpio);
  737. }
  738. void gpioLockOrigin(espurna::gpio::Origin origin) {
  739. espurna::gpio::origin::add(origin);
  740. }
  741. extern "C" {
  742. // All of these have __attribute__((weak)) in the Core files. While the original intent
  743. // seems to be for internal use to override things throuhg 'variant' files, we (so far)
  744. // never used anything but the base ESP8266 implementations.
  745. // Which ones get picked up the linker depends on the build system used, and order
  746. // of the files in the resulting build command.
  747. // *Must* be in IRAM by default, ISR almost certainly include these calls
  748. int IRAM_ATTR digitalRead(uint8_t);
  749. int digitalRead(uint8_t pin) {
  750. using namespace espurna::peripherals;
  751. return (pin == 16)
  752. ? rtc::gpio16_get()
  753. : pin::get(pin);
  754. }
  755. // *Must* be in IRAM by default, ISR almost certainly include these calls
  756. void IRAM_ATTR digitalWrite(uint8_t, uint8_t);
  757. void digitalWrite(uint8_t pin, uint8_t val) {
  758. using namespace espurna::peripherals;
  759. if (pin == 16) {
  760. rtc::gpio16_set(val == 1);
  761. } else {
  762. pin::set(pin, val == 1);
  763. }
  764. }
  765. void pinMode(uint8_t pin, uint8_t mode) {
  766. using namespace espurna::peripherals;
  767. if (pin == 16) {
  768. rtc::gpio16_mode(mode);
  769. } else {
  770. pin::mode(pin, mode);
  771. }
  772. }
  773. // Special override for Core, allows us to skip init for certain pins when needed
  774. void resetPins() {
  775. const auto& hardware = hardwareGpio();
  776. const auto ignore = Rtcmem->gpio_ignore;
  777. for (size_t pin = 0; pin < espurna::gpio::Hardware::Pins; ++pin) {
  778. if (!hardware.valid(pin)) {
  779. continue;
  780. }
  781. if ((ignore & (1 << pin)) > 0) {
  782. continue;
  783. }
  784. #if DEBUG_SERIAL_SUPPORT
  785. // TODO: actually check which pin is set as TX via function select
  786. if (pin == 1) {
  787. continue;
  788. }
  789. #endif
  790. pinMode(pin, INPUT);
  791. }
  792. }
  793. } // extern "C"