diff --git a/.github/workflows/build-clang-doxy.yml b/.github/workflows/build-clang-doxy.yml index e0ea16fe4..2ff7f4256 100644 --- a/.github/workflows/build-clang-doxy.yml +++ b/.github/workflows/build-clang-doxy.yml @@ -45,7 +45,7 @@ jobs: run: bash ci/actions_install.sh - name: Install extra Arduino libraries run: | - git clone --quiet https://github.com/milesburton/Arduino-Temperature-Control-Library.git /home/runner/Arduino/libraries/Arduino-Temperature-Control-Library + git clone --quiet https://github.com/pstolarz/Arduino-Temperature-Control-Library.git /home/runner/Arduino/libraries/Arduino-Temperature-Control-Library git clone --quiet https://github.com/pstolarz/OneWireNg.git /home/runner/Arduino/libraries/OneWireNg git clone --quiet https://github.com/adafruit/Adafruit_HX8357_Library.git /home/runner/Arduino/libraries/Adafruit_HX8357_Library git clone --quiet https://github.com/adafruit/Adafruit_ILI9341.git /home/runner/Arduino/libraries/Adafruit_ILI9341 @@ -211,7 +211,7 @@ jobs: run: bash ci/actions_install.sh - name: Install extra Arduino libraries run: | - git clone --quiet https://github.com/milesburton/Arduino-Temperature-Control-Library.git /home/runner/Arduino/libraries/Arduino-Temperature-Control-Library + git clone --quiet https://github.com/pstolarz/Arduino-Temperature-Control-Library.git /home/runner/Arduino/libraries/Arduino-Temperature-Control-Library git clone --quiet https://github.com/pstolarz/OneWireNg.git /home/runner/Arduino/libraries/OneWireNg git clone --quiet https://github.com/adafruit/Adafruit_HX8357_Library.git /home/runner/Arduino/libraries/Adafruit_HX8357_Library git clone --quiet https://github.com/adafruit/Adafruit_ILI9341.git /home/runner/Arduino/libraries/Adafruit_ILI9341 @@ -319,7 +319,7 @@ jobs: run: bash ci/actions_install.sh - name: Install extra Arduino libraries run: | - git clone --quiet https://github.com/milesburton/Arduino-Temperature-Control-Library.git /home/runner/Arduino/libraries/Arduino-Temperature-Control-Library + git clone --quiet https://github.com/pstolarz/Arduino-Temperature-Control-Library.git /home/runner/Arduino/libraries/Arduino-Temperature-Control-Library git clone --quiet https://github.com/pstolarz/OneWireNg.git /home/runner/Arduino/libraries/OneWireNg - name: Download stable Nanopb id: download-nanopb @@ -446,8 +446,8 @@ jobs: - name: Install extra Arduino libraries run: | git clone --quiet https://github.com/adafruit/WiFiNINA.git /home/runner/Arduino/libraries/WiFiNINA - git clone --quiet https://github.com/milesburton/Arduino-Temperature-Control-Library.git /home/runner/Arduino/libraries/Arduino-Temperature-Control-Library - git clone --quiet https://github.com/PaulStoffregen/OneWire.git /home/runner/Arduino/libraries/OneWire + git clone --quiet https://github.com/pstolarz/OneWireNg.git /home/runner/Arduino/libraries/OneWireNg + git clone --quiet https://github.com/pstolarz/Arduino-Temperature-Control-Library.git /home/runner/Arduino/libraries/Arduino-Temperature-Control-Library git clone --quiet https://github.com/adafruit/Adafruit_TinyUSB_Arduino /home/runner/Arduino/libraries/Adafruit_TinyUSB_Arduino - name: Download stable Nanopb id: download-nanopb @@ -564,69 +564,6 @@ jobs: path: | wippersnapper.${{ matrix.arduino-platform }}.${{ env.WS_VERSION }}.uf2 - # NOTE: This does NOT release artifacts, it only builds - build-samd-non-fs: - name: 🏗️SAMD🚫⧾🔱 - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - arduino-platform: ["mkrwifi1010", "nano_33_iot"] - steps: - - uses: actions/setup-python@v5 - with: - python-version: "3.x" - - uses: actions/checkout@v4 - - name: Get WipperSnapper version - run: | - git fetch --prune --unshallow --tags - git describe --dirty --tags - echo >>$GITHUB_ENV WS_VERSION=$(git describe --dirty --tags) - - uses: actions/checkout@v4 - with: - repository: adafruit/ci-arduino - ref: ci-wippersnapper - path: ci - - name: Install CI-Arduino - run: bash ci/actions_install.sh - - name: Install extra Arduino libraries - run: | - git clone --quiet https://github.com/arduino-libraries/WiFiNINA.git /home/runner/Arduino/libraries/WiFiNINA - git clone --quiet https://github.com/arduino-libraries/Servo.git /home/runner/Arduino/libraries/Servo - git clone --quiet https://github.com/milesburton/Arduino-Temperature-Control-Library.git /home/runner/Arduino/libraries/Arduino-Temperature-Control-Library - git clone --quiet https://github.com/PaulStoffregen/OneWire.git /home/runner/Arduino/libraries/OneWire - - name: Download stable Nanopb - id: download-nanopb - continue-on-error: true - run: | - wget https://jpa.kapsi.fi/nanopb/download/nanopb-0.4.8.tar.gz - - if: ${{ failure() || steps.download-nanopb.outcome != 'success' }} - name: Restore cached nanopb - id: cache-nanopb-restore - uses: actions/cache/restore@v4 - env: - cache-name: cache-node-modules - with: - path: ./nanopb-0.4.8.tar.gz - key: nanopb-0.4.8.tar.gz - - if: ${{ steps.download-nanopb.outcome == 'success' }} - name: Save nanopb to cache - id: cache-nanopb-save - uses: actions/cache/save@v4 - env: - cache-name: cache-node-modules - with: - path: ./nanopb-0.4.8.tar.gz - key: nanopb-0.4.8.tar.gz - - name: Install stable Nanopb - run: | - tar -xf nanopb-0.4.8.tar.gz - # Copy files to WipperSnapper's src/nanopb directory - cp nanopb/pb_common.* nanopb/pb_encode.* nanopb/pb_decode.* src/nanopb - mv nanopb/pb.h src/nanopb/nanopb.pb.h - - name: build SAMD (no-FS) platforms - run: python3 ci/build_platform.py ${{ matrix.arduino-platform }} --build_timeout 48000 - build-esp8266: name: 🏗️ESP8266 runs-on: ubuntu-latest @@ -653,8 +590,8 @@ jobs: run: bash ci/actions_install.sh - name: Install extra Arduino library run: | - git clone --quiet https://github.com/milesburton/Arduino-Temperature-Control-Library.git /home/runner/Arduino/libraries/Arduino-Temperature-Control-Library - git clone --quiet https://github.com/PaulStoffregen/OneWire.git /home/runner/Arduino/libraries/OneWire + git clone --quiet https://github.com/pstolarz/OneWireNg.git /home/runner/Arduino/libraries/OneWireNg + git clone --quiet https://github.com/pstolarz/Arduino-Temperature-Control-Library.git /home/runner/Arduino/libraries/Arduino-Temperature-Control-Library - name: Download stable Nanopb id: download-nanopb continue-on-error: true @@ -741,7 +678,7 @@ jobs: run: bash ci/actions_install.sh - name: Install extra Arduino libraries run: | - git clone --quiet https://github.com/milesburton/Arduino-Temperature-Control-Library.git /home/runner/Arduino/libraries/Arduino-Temperature-Control-Library + git clone --quiet https://github.com/pstolarz/Arduino-Temperature-Control-Library.git /home/runner/Arduino/libraries/Arduino-Temperature-Control-Library git clone --quiet https://github.com/pstolarz/OneWireNg.git /home/runner/Arduino/libraries/OneWireNg git clone --quiet https://github.com/adafruit/Adafruit_HX8357_Library.git /home/runner/Arduino/libraries/Adafruit_HX8357_Library git clone --quiet https://github.com/adafruit/Adafruit_ILI9341.git /home/runner/Arduino/libraries/Adafruit_ILI9341 @@ -842,7 +779,7 @@ jobs: run: bash ci/actions_install.sh - name: Install extra Arduino libraries run: | - git clone --quiet https://github.com/milesburton/Arduino-Temperature-Control-Library.git /home/runner/Arduino/libraries/Arduino-Temperature-Control-Library + git clone --quiet https://github.com/pstolarz/Arduino-Temperature-Control-Library.git /home/runner/Arduino/libraries/Arduino-Temperature-Control-Library git clone --quiet https://github.com/pstolarz/OneWireNg.git /home/runner/Arduino/libraries/OneWireNg - name: Download stable Nanopb id: download-nanopb @@ -941,7 +878,7 @@ jobs: merge-job-build-files: name: Merge Artifacts for build-files runs-on: ubuntu-latest - needs: [build-esp32sx-esptool, build-esp32sx, build-esp32, build-esp8266, build-samd, build-rp2040, build-samd-non-fs] + needs: [build-esp32sx-esptool, build-esp32sx, build-esp32, build-esp8266, build-samd, build-rp2040] steps: - name: Merge Artifacts from Builds @@ -973,7 +910,6 @@ jobs: build-esp32, build-esp32sx, build-esp8266, - build-samd-non-fs, build-rp2040, ] steps: @@ -991,7 +927,7 @@ jobs: run: bash ci/actions_install.sh - name: clang - run: python3 ci/run-clang-format.py -r -e "ci/*" -e "bin/*" -e src/nanopb -e src/wippersnapper -e src/pb.h -e src/provisioning/tinyusb src/ + run: python3 ci/run-clang-format.py -r -e "ci/*" -e "bin/*" -e src/nanopb -e src/protos -e src/wippersnapper -e src/pb.h -e src/provisioning/tinyusb src/ - name: doxygen env: diff --git a/.gitignore b/.gitignore index b21993810..c8c95f2de 100644 --- a/.gitignore +++ b/.gitignore @@ -63,4 +63,6 @@ examples/Wippersnapper_demo_offline/build/ report.xml # VSCode settings -.vscode/settings.json \ No newline at end of file +.vscode/settings.json + +CLAUDE.md \ No newline at end of file diff --git a/CLAUDE.md b/CLAUDE.md deleted file mode 100644 index e82388b09..000000000 --- a/CLAUDE.md +++ /dev/null @@ -1,24 +0,0 @@ -# CLAUDE.md - -This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. - -## Build/Test Commands -- Build with PlatformIO: `pio run` -- Upload firmware: `python upload_no_build.py` -- Run tests: `cd tests && python test_offline.py` -- Run single test: `wokwi-cli --elf tests/bin/offline/firmware.elf --timeout 120000 --scenario tests/scenarios/offline/[test-file].scenario.yaml --diagram tests/diagrams/offline.json` - -## Code Style Guidelines -- Follow Adafruit library conventions -- Header guards: UPPERCASE_WITH_UNDERSCORES -- Classes: Model-View-Controller pattern (see components directory) -- Naming: camelCase for methods, snake_case for variables, UPPER_CASE for constants -- Imports: Group Arduino core, Adafruit libraries, then project-specific headers -- Documentation: Use Doxygen-style comments for classes and functions -- Error handling: Return error codes, use status LEDs for user feedback -- Follow existing code patterns for new components - -## Contributing -- Follow Code of Conduct in CODE_OF_CONDUCT.md -- For new components: https://learn.adafruit.com/how-to-add-a-new-component-to-adafruit-io-wippersnapper -- For new boards: https://learn.adafruit.com/how-to-add-a-new-board-to-wippersnapper \ No newline at end of file diff --git a/Doxyfile b/Doxyfile index 199b283ea..d56896e55 100644 --- a/Doxyfile +++ b/Doxyfile @@ -90,7 +90,7 @@ CREATE_SUBDIRS = NO # Minimum value: 0, maximum value: 8, default value: 8. # This tag requires that the tag CREATE_SUBDIRS is set to YES. -CREATE_SUBDIRS_LEVEL = 8 +# CREATE_SUBDIRS_LEVEL = 8 # Unsupported by current Doxygen version # If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII # characters to appear in the names of generated files. If set to NO, non-ASCII @@ -219,7 +219,7 @@ JAVADOC_AUTOBRIEF = NO # interpreted by doxygen. # The default value is: NO. -JAVADOC_BANNER = NO +# JAVADOC_BANNER = NO # Unsupported by current Doxygen version # If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first # line (until the first dot) of a Qt-style comment as the brief description. If @@ -247,7 +247,7 @@ MULTILINE_CPP_IS_BRIEF = NO # documentation blocks is shown as doxygen documentation. # The default value is: YES. -PYTHON_DOCSTRING = YES +# PYTHON_DOCSTRING = YES # Unsupported by current Doxygen version # If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the # documentation from any documented member that it re-implements. @@ -319,7 +319,7 @@ OPTIMIZE_OUTPUT_VHDL = NO # separated into more groups, etc. # The default value is: NO. -OPTIMIZE_OUTPUT_SLICE = NO +# OPTIMIZE_OUTPUT_SLICE = NO # Unsupported by current Doxygen version # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given @@ -372,7 +372,7 @@ TOC_INCLUDE_HEADINGS = 0 # The default value is: DOXYGEN. # This tag requires that the tag MARKDOWN_SUPPORT is set to YES. -MARKDOWN_ID_STYLE = DOXYGEN +# MARKDOWN_ID_STYLE = DOXYGEN # Unsupported by current Doxygen version # When enabled doxygen tries to link words that correspond to documented # classes, or namespaces to their corresponding documentation. Such a link can @@ -496,7 +496,7 @@ LOOKUP_CACHE_SIZE = 0 # DOT_NUM_THREADS setting. # Minimum value: 0, maximum value: 32, default value: 1. -NUM_PROC_THREADS = 1 +# NUM_PROC_THREADS = 1 # Unsupported by current Doxygen version # If the TIMESTAMP tag is set different from NO then each generated page will # contain the date or date and time when the page was generated. Setting this to @@ -504,7 +504,7 @@ NUM_PROC_THREADS = 1 # Possible values are: YES, NO, DATETIME and DATE. # The default value is: NO. -TIMESTAMP = NO +# TIMESTAMP = NO # Unsupported by current Doxygen version #--------------------------------------------------------------------------- # Build related configuration options @@ -530,7 +530,7 @@ EXTRACT_PRIVATE = NO # methods of a class will be included in the documentation. # The default value is: NO. -EXTRACT_PRIV_VIRTUAL = NO +# EXTRACT_PRIV_VIRTUAL = NO # Unsupported by current Doxygen version # If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal # scope will be included in the documentation. @@ -574,7 +574,7 @@ EXTRACT_ANON_NSPACES = NO # parameters remain unnamed in the output. # The default value is: YES. -RESOLVE_UNNAMED_PARAMS = YES +# RESOLVE_UNNAMED_PARAMS = YES # Unsupported by current Doxygen version # If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all # undocumented members inside documented classes or files. If set to NO these @@ -649,7 +649,7 @@ HIDE_COMPOUND_REFERENCE= NO # will show which file needs to be included to use the class. # The default value is: YES. -SHOW_HEADERFILE = YES +# SHOW_HEADERFILE = YES # Unsupported by current Doxygen version # If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of # the files that are included by a file in the documentation of that file. @@ -867,7 +867,7 @@ WARN_IF_DOC_ERROR = YES # parameters have no documentation without warning. # The default value is: YES. -WARN_IF_INCOMPLETE_DOC = YES +# WARN_IF_INCOMPLETE_DOC = YES # Unsupported by current Doxygen version # This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that # are documented, but have no documentation for their parameters or return @@ -885,7 +885,7 @@ WARN_NO_PARAMDOC = YES # will automatically be disabled. # The default value is: NO. -WARN_IF_UNDOC_ENUM_VAL = NO +# WARN_IF_UNDOC_ENUM_VAL = NO # Unsupported by current Doxygen version # If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when # a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS @@ -922,7 +922,7 @@ WARN_FORMAT = "$file:$line: $text" # See also: WARN_FORMAT # The default value is: at line $line of file $file. -WARN_LINE_FORMAT = "at line $line of file $file" +# WARN_LINE_FORMAT = "at line $line of file $file" # Unsupported by current Doxygen version # The WARN_LOGFILE tag can be used to specify a file to which warning and error # messages should be written. If left blank the output is written to standard @@ -963,7 +963,7 @@ INPUT_ENCODING = UTF-8 # form: pattern=encoding (like *.php=ISO-8859-1). See cfg_input_encoding # "INPUT_ENCODING" for further information on supported encodings. -INPUT_FILE_ENCODING = +# INPUT_FILE_ENCODING = # Unsupported by current Doxygen version # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and @@ -1134,7 +1134,7 @@ USE_MDFILE_AS_MAINPAGE = # be processed before the automatic comment starts. # Minimum value: 7, maximum value: 10000, default value: 72. -FORTRAN_COMMENT_AFTER = 72 +# FORTRAN_COMMENT_AFTER = 72 # Unsupported by current Doxygen version #--------------------------------------------------------------------------- # Configuration options related to source browsing @@ -1347,7 +1347,7 @@ HTML_EXTRA_FILES = # The default value is: AUTO_LIGHT. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_COLORSTYLE = AUTO_LIGHT +# HTML_COLORSTYLE = AUTO_LIGHT # Unsupported by current Doxygen version # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen # will adjust the colors in the style sheet and background images according to @@ -1388,7 +1388,7 @@ HTML_COLORSTYLE_GAMMA = 80 # The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_DYNAMIC_MENUS = YES +# HTML_DYNAMIC_MENUS = YES # Unsupported by current Doxygen version # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the @@ -1403,7 +1403,7 @@ HTML_DYNAMIC_SECTIONS = NO # The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_CODE_FOLDING = YES +# HTML_CODE_FOLDING = YES # Unsupported by current Doxygen version # With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries # shown in the various tree structured indices initially; the user can expand @@ -1446,7 +1446,7 @@ DOCSET_FEEDNAME = "Doxygen generated docs" # (such as a company or product suite) can be grouped. # This tag requires that the tag GENERATE_DOCSET is set to YES. -DOCSET_FEEDURL = +# DOCSET_FEEDURL = # Unsupported by current Doxygen version # This tag specifies a string that should uniquely identify the documentation # set bundle. This should be a reverse domain-name style string, e.g. @@ -1543,7 +1543,7 @@ TOC_EXPAND = NO # protocol see https://www.sitemaps.org # This tag requires that the tag GENERATE_HTML is set to YES. -SITEMAP_URL = +# SITEMAP_URL = # Unsupported by current Doxygen version # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that @@ -1667,7 +1667,7 @@ GENERATE_TREEVIEW = NO # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. -FULL_SIDEBAR = NO +# FULL_SIDEBAR = NO # Unsupported by current Doxygen version # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that # doxygen will group on one line in the generated HTML documentation. @@ -1698,7 +1698,7 @@ EXT_LINKS_IN_WINDOW = NO # The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. -OBFUSCATE_EMAILS = YES +# OBFUSCATE_EMAILS = YES # Unsupported by current Doxygen version # If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg # tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see @@ -1709,7 +1709,7 @@ OBFUSCATE_EMAILS = YES # The default value is: png. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_FORMULA_FORMAT = png +# HTML_FORMULA_FORMAT = png # Unsupported by current Doxygen version # Use this tag to change the font size of LaTeX formulas included as images in # the HTML documentation. When you change the font size after a successful @@ -1724,7 +1724,7 @@ FORMULA_FONTSIZE = 10 # to create new LaTeX commands to be used in formulas as building blocks. See # the section "Including formulas" for details. -FORMULA_MACROFILE = +# FORMULA_MACROFILE = # Unsupported by current Doxygen version # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see # https://www.mathjax.org) which uses client side JavaScript for the rendering @@ -1746,7 +1746,7 @@ USE_MATHJAX = NO # The default value is: MathJax_2. # This tag requires that the tag USE_MATHJAX is set to YES. -MATHJAX_VERSION = MathJax_2 +# MATHJAX_VERSION = MathJax_2 # Unsupported by current Doxygen version # When MathJax is enabled you can set the default output format to be used for # the MathJax output. For more details about the output format see MathJax @@ -1935,7 +1935,7 @@ MAKEINDEX_CMD_NAME = makeindex # The default value is: makeindex. # This tag requires that the tag GENERATE_LATEX is set to YES. -LATEX_MAKEINDEX_CMD = makeindex +# LATEX_MAKEINDEX_CMD = makeindex # Unsupported by current Doxygen version # If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX # documents. This may be useful for small projects and may help to save some @@ -2069,7 +2069,7 @@ LATEX_BIB_STYLE = plain # LATEX_OUTPUT directory will be used. # This tag requires that the tag GENERATE_LATEX is set to YES. -LATEX_EMOJI_DIRECTORY = +# LATEX_EMOJI_DIRECTORY = # Unsupported by current Doxygen version #--------------------------------------------------------------------------- # Configuration options related to the RTF output @@ -2203,7 +2203,7 @@ XML_PROGRAMLISTING = YES # The default value is: NO. # This tag requires that the tag GENERATE_XML is set to YES. -XML_NS_MEMB_FILE_SCOPE = NO +# XML_NS_MEMB_FILE_SCOPE = NO # Unsupported by current Doxygen version #--------------------------------------------------------------------------- # Configuration options related to the DOCBOOK output @@ -2243,7 +2243,7 @@ GENERATE_AUTOGEN_DEF = NO # database with symbols found by doxygen stored in tables. # The default value is: NO. -GENERATE_SQLITE3 = NO +# GENERATE_SQLITE3 = NO # Unsupported by current Doxygen version # The SQLITE3_OUTPUT tag is used to specify where the Sqlite3 database will be # put. If a relative path is entered the value of OUTPUT_DIRECTORY will be put @@ -2251,7 +2251,7 @@ GENERATE_SQLITE3 = NO # The default directory is: sqlite3. # This tag requires that the tag GENERATE_SQLITE3 is set to YES. -SQLITE3_OUTPUT = sqlite3 +# SQLITE3_OUTPUT = sqlite3 # Unsupported by current Doxygen version # The SQLITE3_OVERWRITE_DB tag is set to YES, the existing doxygen_sqlite3.db # database file will be recreated with each doxygen run. If set to NO, doxygen @@ -2259,7 +2259,7 @@ SQLITE3_OUTPUT = sqlite3 # The default value is: YES. # This tag requires that the tag GENERATE_SQLITE3 is set to YES. -SQLITE3_RECREATE_DB = YES +# SQLITE3_RECREATE_DB = YES # Unsupported by current Doxygen version #--------------------------------------------------------------------------- # Configuration options related to the Perl module output @@ -2466,7 +2466,7 @@ DOT_NUM_THREADS = 0 # The default value is: fontname=Helvetica,fontsize=10. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_COMMON_ATTR = "fontname=Helvetica,fontsize=10" +# DOT_COMMON_ATTR = "fontname=Helvetica,fontsize=10" # Unsupported by current Doxygen version # DOT_EDGE_ATTR is concatenated with DOT_COMMON_ATTR. For elegant style you can # add 'arrowhead=open, arrowtail=open, arrowsize=0.5'. -o . The external tool should support # output file formats "png", "eps", "svg", and "ismap". -MSCGEN_TOOL = +# MSCGEN_TOOL = # Unsupported by current Doxygen version # The MSCFILE_DIRS tag can be used to specify one or more directories that # contain msc files that are included in the documentation (see the \mscfile diff --git a/examples/Wippersnapper_demo/.pico_rp2350_tinyusb.test.skip b/examples/Wippersnapper_NoFS/.picow_rp2350_tinyusb.test.skip similarity index 100% rename from examples/Wippersnapper_demo/.pico_rp2350_tinyusb.test.skip rename to examples/Wippersnapper_NoFS/.picow_rp2350_tinyusb.test.skip diff --git a/examples/Wippersnapper_NoFS/.wippersnapper_feather_esp32c6.test.skip b/examples/Wippersnapper_NoFS/.wippersnapper_feather_esp32c6.test.skip new file mode 100644 index 000000000..e69de29bb diff --git a/examples/Wippersnapper_demo/.picow_rp2040_tinyusb.test.skip b/examples/Wippersnapper_NoFS/.wippersnapper_feather_esp32c6_debug.test.skip similarity index 100% rename from examples/Wippersnapper_demo/.picow_rp2040_tinyusb.test.skip rename to examples/Wippersnapper_NoFS/.wippersnapper_feather_esp32c6_debug.test.skip diff --git a/examples/Wippersnapper_demo/.qtpy_esp32.test.skip b/examples/Wippersnapper_NoFS/.wippersnapper_feather_esp32s3_reverse_tft_debug.test.skip similarity index 100% rename from examples/Wippersnapper_demo/.qtpy_esp32.test.skip rename to examples/Wippersnapper_NoFS/.wippersnapper_feather_esp32s3_reverse_tft_debug.test.skip diff --git a/examples/Wippersnapper_NoFS/picow_rp2350_tinyusb.test.skip b/examples/Wippersnapper_NoFS/picow_rp2350_tinyusb.test.skip new file mode 100644 index 000000000..e69de29bb diff --git a/examples/Wippersnapper_demo/.feather_esp32c6.generate b/examples/Wippersnapper_demo/.feather_esp32c6.generate new file mode 100644 index 000000000..e69de29bb diff --git a/examples/wippersnapper_debug/.feather_esp32s3_reverse_tft_dev.generate b/examples/Wippersnapper_demo/.pico_rp2350_tinyusb.generate similarity index 100% rename from examples/wippersnapper_debug/.feather_esp32s3_reverse_tft_dev.generate rename to examples/Wippersnapper_demo/.pico_rp2350_tinyusb.generate diff --git a/examples/Wippersnapper_demo/.picow_rp2040_tinyusb.generate b/examples/Wippersnapper_demo/.picow_rp2040_tinyusb.generate new file mode 100644 index 000000000..e69de29bb diff --git a/examples/Wippersnapper_demo/.picow_rp2350.generate b/examples/Wippersnapper_demo/.picow_rp2350.generate new file mode 100644 index 000000000..e69de29bb diff --git a/examples/Wippersnapper_demo/.picow_rp2350_tinyusb.generate b/examples/Wippersnapper_demo/.picow_rp2350_tinyusb.generate new file mode 100644 index 000000000..e69de29bb diff --git a/examples/Wippersnapper_demo/.qtpy_esp32.generate b/examples/Wippersnapper_demo/.qtpy_esp32.generate new file mode 100644 index 000000000..e69de29bb diff --git a/examples/Wippersnapper_demo/.wippersnapper_feather_esp32c6.generate b/examples/Wippersnapper_demo/.wippersnapper_feather_esp32c6.generate new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo/.wippersnapper_feather_esp32c6.generate @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo/.wippersnapper_feather_esp32c6_debug.test.skip b/examples/Wippersnapper_demo/.wippersnapper_feather_esp32c6_debug.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo/.wippersnapper_feather_esp32c6_debug.test.skip @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo/.wippersnapper_feather_esp32s3_reverse_tft_debug.test.skip b/examples/Wippersnapper_demo/.wippersnapper_feather_esp32s3_reverse_tft_debug.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo/.wippersnapper_feather_esp32s3_reverse_tft_debug.test.skip @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo/picow_rp2350_tinyusb.generate b/examples/Wippersnapper_demo/picow_rp2350_tinyusb.generate new file mode 100644 index 000000000..907c1f0d3 --- /dev/null +++ b/examples/Wippersnapper_demo/picow_rp2350_tinyusb.generate @@ -0,0 +1 @@ +picow_rp2350_tinyusb \ No newline at end of file diff --git a/examples/Wippersnapper_demo_offline/.picow_rp2350_tinyusb.test.skip b/examples/Wippersnapper_demo_offline/.picow_rp2350_tinyusb.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo_offline/.picow_rp2350_tinyusb.test.skip @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo_offline/.wippersnapper_feather_esp32c6.test.skip b/examples/Wippersnapper_demo_offline/.wippersnapper_feather_esp32c6.test.skip new file mode 100644 index 000000000..e69de29bb diff --git a/examples/Wippersnapper_demo_offline/.wippersnapper_feather_esp32c6_debug.test.skip b/examples/Wippersnapper_demo_offline/.wippersnapper_feather_esp32c6_debug.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo_offline/.wippersnapper_feather_esp32c6_debug.test.skip @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo_offline/.wippersnapper_feather_esp32s3_reverse_tft_debug.test.skip b/examples/Wippersnapper_demo_offline/.wippersnapper_feather_esp32s3_reverse_tft_debug.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/Wippersnapper_demo_offline/.wippersnapper_feather_esp32s3_reverse_tft_debug.test.skip @@ -0,0 +1 @@ + diff --git a/examples/Wippersnapper_demo_offline/picow_rp2350_tinyusb.test.skip b/examples/Wippersnapper_demo_offline/picow_rp2350_tinyusb.test.skip new file mode 100644 index 000000000..e69de29bb diff --git a/examples/wippersnapper_debug/.feather_esp32s3_reverse_tft_debug.generate b/examples/wippersnapper_debug/.feather_esp32s3_reverse_tft_debug.generate new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/wippersnapper_debug/.feather_esp32s3_reverse_tft_debug.generate @@ -0,0 +1 @@ + diff --git a/examples/wippersnapper_debug/.picow_rp2350_tinyusb.test.skip b/examples/wippersnapper_debug/.picow_rp2350_tinyusb.test.skip new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/wippersnapper_debug/.picow_rp2350_tinyusb.test.skip @@ -0,0 +1 @@ + diff --git a/examples/wippersnapper_debug/.wippersnapper_feather_esp32c6.test.skip b/examples/wippersnapper_debug/.wippersnapper_feather_esp32c6.test.skip new file mode 100644 index 000000000..e69de29bb diff --git a/examples/wippersnapper_debug/.wippersnapper_feather_esp32c6_debug.generate b/examples/wippersnapper_debug/.wippersnapper_feather_esp32c6_debug.generate new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/wippersnapper_debug/.wippersnapper_feather_esp32c6_debug.generate @@ -0,0 +1 @@ + diff --git a/examples/wippersnapper_debug/.wippersnapper_feather_esp32s3_reverse_tft_debug.generate b/examples/wippersnapper_debug/.wippersnapper_feather_esp32s3_reverse_tft_debug.generate new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/examples/wippersnapper_debug/.wippersnapper_feather_esp32s3_reverse_tft_debug.generate @@ -0,0 +1 @@ + diff --git a/examples/wippersnapper_debug/picow_rp2350_tinyusb.test.skip b/examples/wippersnapper_debug/picow_rp2350_tinyusb.test.skip new file mode 100644 index 000000000..e69de29bb diff --git a/platformio.ini b/platformio.ini index bc523e30e..ad5932606 100644 --- a/platformio.ini +++ b/platformio.ini @@ -17,6 +17,14 @@ monitor_speed = 115200 extra_scripts = upload_no_build.py lib_compat_mode = strict lib_deps = + ;;;;;;;;;;; FunHouse / LVGL Boards uncomment these ;;;;;;;;;;;;;; + ; https://github.com/adafruit/Adafruit_HX8357_Library.git + ; https://github.com/adafruit/Adafruit_ILI9341.git + ; https://github.com/adafruit/Adafruit_STMPE610.git + ; https://github.com/adafruit/Adafruit-ST7735-Library.git + ; https://github.com/adafruit/Adafruit_TouchScreen.git + ; https://github.com/brentru/lvgl.git#wippersnapper + ; https://github.com/brentru/Adafruit_LvGL_Glue.git#development adafruit/Adafruit TinyUSB Library adafruit/Adafruit Zero DMA Library adafruit/Adafruit SPIFlash diff --git a/src/Wippersnapper_Boards.h b/src/Wippersnapper_Boards.h index 01babf8a5..0c5aca7b8 100644 --- a/src/Wippersnapper_Boards.h +++ b/src/Wippersnapper_Boards.h @@ -191,7 +191,12 @@ #define BOARD_ID "rpi-pico-w" #define USE_TINYUSB #define USE_STATUS_LED -#define STATUS_LED_PIN 32 +#define STATUS_LED_PIN 64 +#elif defined(ARDUINO_RASPBERRY_PI_PICO_2W) +#define BOARD_ID "rpi-pico-2w" +#define USE_TINYUSB +#define USE_STATUS_LED +#define STATUS_LED_PIN 64 #elif defined(ARDUINO_RASPBERRY_PI_PICO) #define BOARD_ID "rpi-pico" #define USE_TINYUSB @@ -216,6 +221,12 @@ #define STATUS_NEOPIXEL_PIN PIN_NEOPIXEL #define STATUS_NEOPIXEL_NUM NUM_NEOPIXEL #define SD_USE_SPI_1 +#elif defined(ARDUINO_ADAFRUIT_FEATHER_ESP32C6) +#define BOARD_ID "feather-esp32c6" +#define USE_LITTLEFS +#define USE_STATUS_NEOPIXEL +#define STATUS_NEOPIXEL_PIN PIN_NEOPIXEL +#define STATUS_NEOPIXEL_NUM 1 #else #warning "Board type not identified within Wippersnapper_Boards.h!" #endif diff --git a/src/Wippersnapper_V2.cpp b/src/Wippersnapper_V2.cpp index e36377747..732405b23 100644 --- a/src/Wippersnapper_V2.cpp +++ b/src/Wippersnapper_V2.cpp @@ -108,21 +108,21 @@ void Wippersnapper_V2::provision() { // Initialize the display displayConfig config; WsV2._fileSystemV2->parseDisplayConfig(config); - WsV2._display = new ws_display_driver(config); + WsV2._displayV2 = new ws_display_driver(config); // Begin display - if (!WsV2._display->begin()) { + if (!WsV2._displayV2->begin()) { WS_DEBUG_PRINTLN("Unable to enable display driver and LVGL"); haltErrorV2("Unable to enable display driver, please check the json " "configuration!"); } - WsV2._display->enableLogging(); + WsV2._displayV2->enableLogging(); ReleaseStatusPixel(); // don't use status LED if we are using the display // UI Setup - WsV2._ui_helper = new ws_display_ui_helper(WsV2._display); - WsV2._ui_helper->set_bg_black(); - WsV2._ui_helper->show_scr_load(); - WsV2._ui_helper->set_label_status("Validating Credentials..."); + WsV2._ui_helperV2 = new ws_display_ui_helper(WsV2._displayV2); + WsV2._ui_helperV2->set_bg_black(); + WsV2._ui_helperV2->show_scr_load(); + WsV2._ui_helperV2->set_label_status("Validating Credentials..."); #endif #ifdef USE_TINYUSB @@ -139,8 +139,8 @@ void Wippersnapper_V2::provision() { set_ssid_pass(); #ifdef USE_DISPLAY - WsV2._ui_helper->set_label_status(""); - WsV2._ui_helper->set_load_bar_icon_complete(loadBarIconFile); + WsV2._ui_helperV2->set_label_status(""); + WsV2._ui_helperV2->set_load_bar_icon_complete(loadBarIconFile); #endif } @@ -515,7 +515,7 @@ void cbErrorTopicV2(char *errorData, uint16_t len) { } #ifdef USE_DISPLAY - WsV2._ui_helper->show_scr_error("IO Ban Error", errorData); + WsV2._ui_helperV2->show_scr_error("IO Ban Error", errorData); #endif // WDT reset @@ -554,7 +554,7 @@ void cbThrottleTopicV2(char *throttleData, uint16_t len) { buffer, 100, "[IO ERROR] Device is throttled for %d mS and blocking execution..\n.", throttleDuration); - WsV2._ui_helper->add_text_to_terminal(buffer); + WsV2._ui_helperV2->add_text_to_terminal(buffer); #endif // If throttle duration is less than the keepalive interval, delay for the @@ -574,7 +574,7 @@ void cbThrottleTopicV2(char *throttleData, uint16_t len) { } WS_DEBUG_PRINTLN("Device is un-throttled, resumed command execution"); #ifdef USE_DISPLAY - WsV2._ui_helper->add_text_to_terminal( + WsV2._ui_helperV2->add_text_to_terminal( "[IO] Device is un-throttled, resuming...\n"); #endif } @@ -784,8 +784,8 @@ void Wippersnapper_V2::runNetFSMV2() { if (networkStatus() == WS_NET_CONNECTED) { WS_DEBUG_PRINTLN("Connected to WiFi!"); #ifdef USE_DISPLAY - if (WsV2._ui_helper->getLoadingState()) - WsV2._ui_helper->set_load_bar_icon_complete(loadBarIconWifi); + if (WsV2._ui_helperV2->getLoadingState()) + WsV2._ui_helperV2->set_load_bar_icon_complete(loadBarIconWifi); #endif fsmNetwork = FSM_NET_ESTABLISH_MQTT; break; @@ -796,17 +796,17 @@ void Wippersnapper_V2::runNetFSMV2() { WS_DEBUG_PRINTLN("Establishing network connection..."); WS_PRINTER.flush(); #ifdef USE_DISPLAY - if (WsV2._ui_helper->getLoadingState()) - WsV2._ui_helper->set_label_status("Connecting to WiFi..."); + if (WsV2._ui_helperV2->getLoadingState()) + WsV2._ui_helperV2->set_label_status("Connecting to WiFi..."); #endif // Perform a WiFi scan and check if SSID within // secrets.json is within the scanned SSIDs WS_DEBUG_PRINT("Performing a WiFi scan for SSID..."); if (!check_valid_ssid()) { #ifdef USE_DISPLAY - WsV2._ui_helper->show_scr_error("ERROR", - "Unable to find WiFi network listed in " - "the secrets file. Rebooting soon..."); + WsV2._ui_helperV2->show_scr_error( + "ERROR", "Unable to find WiFi network listed in " + "the secrets file. Rebooting soon..."); #endif haltErrorV2("ERROR: Unable to find WiFi network, rebooting soon...", WS_LED_STATUS_WIFI_CONNECTING); @@ -834,7 +834,7 @@ void Wippersnapper_V2::runNetFSMV2() { if (networkStatus() != WS_NET_CONNECTED) { WS_DEBUG_PRINTLN("ERROR: Unable to connect to WiFi!"); #ifdef USE_DISPLAY - WsV2._ui_helper->show_scr_error( + WsV2._ui_helperV2->show_scr_error( "CONNECTION ERROR", "Unable to connect to WiFi Network. Please check that you entered " "the WiFi credentials correctly. Rebooting in 5 seconds..."); @@ -847,8 +847,8 @@ void Wippersnapper_V2::runNetFSMV2() { break; case FSM_NET_ESTABLISH_MQTT: #ifdef USE_DISPLAY - if (WsV2._ui_helper->getLoadingState()) - WsV2._ui_helper->set_label_status("Connecting to IO..."); + if (WsV2._ui_helperV2->getLoadingState()) + WsV2._ui_helperV2->set_label_status("Connecting to IO..."); #endif WsV2._mqttV2->setKeepAliveInterval(WS_KEEPALIVE_INTERVAL_MS / 1000); // Attempt to connect @@ -880,7 +880,7 @@ void Wippersnapper_V2::runNetFSMV2() { } if (fsmNetwork != FSM_NET_CHECK_MQTT) { #ifdef USE_DISPLAY - WsV2._ui_helper->show_scr_error( + WsV2._ui_helperV2->show_scr_error( "CONNECTION ERROR", "Unable to connect to Adafruit.io. If you are repeatedly having " "this issue, please check that your IO Username and IO Key are set " @@ -1126,12 +1126,12 @@ void Wippersnapper_V2::pingBrokerV2() { if (WsV2._mqttV2->ping()) { WS_DEBUG_PRINTLN("SUCCESS!"); #ifdef USE_DISPLAY - WsV2._ui_helper->add_text_to_terminal("[NET] Sent KeepAlive ping!\n"); + WsV2._ui_helperV2->add_text_to_terminal("[NET] Sent KeepAlive ping!\n"); #endif } else { WS_DEBUG_PRINTLN("FAILURE! Running network FSM..."); #ifdef USE_DISPLAY - WsV2._ui_helper->add_text_to_terminal( + WsV2._ui_helperV2->add_text_to_terminal( "[NET] EROR: Failed to send KeepAlive ping!\n"); #endif WsV2._mqttV2->disconnect(); @@ -1304,8 +1304,8 @@ void Wippersnapper_V2::connect() { WsV2.feedWDTV2(); #ifdef USE_DISPLAY - WsV2._ui_helper->set_load_bar_icon_complete(loadBarIconCloud); - WsV2._ui_helper->set_label_status("Sending device info..."); + WsV2._ui_helperV2->set_load_bar_icon_complete(loadBarIconCloud); + WsV2._ui_helperV2->set_label_status("Sending device info..."); #endif WS_DEBUG_PRINTLN("Performing checkin handshake..."); @@ -1325,9 +1325,9 @@ void Wippersnapper_V2::connect() { // switch to monitor screen #ifdef USE_DISPLAY WS_DEBUG_PRINTLN("Clearing loading screen..."); - WsV2._ui_helper->clear_scr_load(); + WsV2._ui_helperV2->clear_scr_load(); WS_DEBUG_PRINTLN("building monitor screen..."); - WsV2._ui_helper->build_scr_monitor(); + WsV2._ui_helperV2->build_scr_monitor(); #endif WS_DEBUG_PRINTLN("Running app loop..."); } @@ -1361,10 +1361,7 @@ ws_status_t Wippersnapper_V2::run() { // TODO: Process I2C sensor events WsV2._i2c_controller->update(); - - // Process Pixels events - // TODO: Add update() method to PixelsController if needed - + // TODO: Process UART sensor events return WS_NET_CONNECTED; // TODO: Make this funcn void! diff --git a/src/Wippersnapper_V2.h b/src/Wippersnapper_V2.h index 391b8f02e..c3fee0e51 100644 --- a/src/Wippersnapper_V2.h +++ b/src/Wippersnapper_V2.h @@ -62,7 +62,7 @@ while (millis() - start < timeout) { \ delay(10); \ yield(); \ - feedWDT(); \ + WsV2.feedWDTV2(); \ if (millis() < start) { \ start = millis(); \ } \ @@ -70,6 +70,7 @@ } // Cpp STD +#include #include #include #include @@ -129,7 +130,7 @@ #endif #define WS_VERSION \ - "1.0.0-offline-beta.1" ///< WipperSnapper app. version (semver-formatted) + "1.0.0-beta.1" ///< WipperSnapper app. version (semver-formatted) #define WS_WDT_TIMEOUT 60000 ///< WDT timeout #define WS_MAX_ALT_WIFI_NETWORKS 3 ///< Maximum number of alternative networks @@ -253,7 +254,8 @@ class Wippersnapper_V2 { DS18X20Controller *_ds18x20_controller = nullptr; ///< Instance of DS18X20 controller I2cController *_i2c_controller = nullptr; ///< Instance of I2C controller - PixelsController *_pixels_controller = nullptr; ///< Instance of Pixels controller + PixelsController *_pixels_controller = + nullptr; ///< Instance of Pixels controller // TODO: does this really need to be global? uint8_t _macAddrV2[6]; /*!< Unique network iface identifier */ diff --git a/src/adapters/wifi/ws_wifi_airlift.h b/src/adapters/wifi/ws_wifi_airlift.h index d9904c329..119211213 100644 --- a/src/adapters/wifi/ws_wifi_airlift.h +++ b/src/adapters/wifi/ws_wifi_airlift.h @@ -11,7 +11,7 @@ * please support Adafruit and open-source hardware by purchasing * products from Adafruit! * - * Copyright (c) Brent Rubell 2020-2021 for Adafruit Industries. + * Copyright (c) Brent Rubell 2020-2025 for Adafruit Industries. * * MIT license, all text here must be included in any redistribution. * @@ -20,27 +20,29 @@ #ifndef WS_WIFI_AIRLIFT_H #define WS_WIFI_AIRLIFT_H +#include "../../helpers/ws_helper_macros.h" #include "Adafruit_MQTT.h" #include "Adafruit_MQTT_Client.h" #include "Arduino.h" #include "SPI.h" #include "WiFiNINA.h" -#include "Wippersnapper.h" +#include "Wippersnapper_V2.h" #define NINAFWVER \ - "1.7.7" /*!< min. nina-fw version compatible with this library. */ + "2.0.0-rc.0+adafruit" /*!< min. nina-fw version compatible with this \ + library. */ #define AIRLIFT_CONNECT_TIMEOUT_MS 20000 /*!< Connection timeout (in ms) */ #define AIRLIFT_CONNECT_RETRY_DELAY_MS 200 /*!< delay time between retries. */ #define SPIWIFI SPI /*!< Instance of SPI interface used by an AirLift. */ -extern Wippersnapper WS; ///< Global Wippersnapper instance +extern Wippersnapper_V2 WsV2; ///< Wippersnapper client instance /****************************************************************************/ /*! @brief Class for using the AirLift Co-Processor network iface. */ /****************************************************************************/ -class ws_wifi_airlift : public Wippersnapper { +class ws_wifi_airlift : public Wippersnapper_V2 { public: /**************************************************************************/ @@ -48,7 +50,7 @@ class ws_wifi_airlift : public Wippersnapper { @brief Initializes the Adafruit IO class for AirLift devices. */ /**************************************************************************/ - ws_wifi_airlift() : Wippersnapper() { + ws_wifi_airlift() : Wippersnapper_V2() { _ssPin = SPIWIFI_SS; // 10; _ackPin = SPIWIFI_ACK; // 7; _rstPin = SPIWIFI_RESET; // 5; // should be 7 on PyPortals @@ -72,8 +74,8 @@ class ws_wifi_airlift : public Wippersnapper { */ /**************************************************************************/ ~ws_wifi_airlift() { - if (_mqtt) - delete _mqtt; + if (_mqttV2) + delete _mqttV2; } /**********************************************************/ @@ -97,8 +99,8 @@ class ws_wifi_airlift : public Wippersnapper { */ /**********************************************************/ void set_ssid_pass() { - _ssid = WS._config.network.ssid; - _pass = WS._config.network.pass; + _ssid = WsV2._configV2.network.ssid; + _pass = WsV2._configV2.network.pass; } /***********************************************************/ @@ -231,7 +233,7 @@ class ws_wifi_airlift : public Wippersnapper { void getMacAddr() { uint8_t mac[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; WiFi.macAddress(mac); - memcpy(WS._macAddr, mac, sizeof(mac)); + memcpy(WsV2._macAddrV2, mac, sizeof(mac)); } /********************************************************/ @@ -250,9 +252,9 @@ class ws_wifi_airlift : public Wippersnapper { */ /********************************************************/ void setupMQTTClient(const char *clientID) { - WS._mqtt = new Adafruit_MQTT_Client( - _mqtt_client, WS._config.aio_url, WS._config.io_port, clientID, - WS._config.aio_user, WS._config.aio_key); + WsV2._mqttV2 = new Adafruit_MQTT_Client( + _mqtt_client, WsV2._configV2.aio_url, WsV2._configV2.io_port, clientID, + WsV2._configV2.aio_user, WsV2._configV2.aio_key); } /********************************************************/ @@ -300,8 +302,8 @@ class ws_wifi_airlift : public Wippersnapper { /**************************************************************************/ void _connect() { if (strlen(_ssid) == 0) { - _status = WS_SSID_INVALID; // possibly unneccesary as already checking - // elsewhere + _statusV2 = WS_SSID_INVALID; // possibly unneccesary as already checking + // elsewhere } else { // disconnect from possible previous connection _disconnect(); @@ -310,16 +312,16 @@ class ws_wifi_airlift : public Wippersnapper { _wifi->end(); delay(100); _wifi->begin(); - feedWDT(); + WsV2.feedWDTV2(); // reset the esp32 if possible resetAirLift(); - feedWDT(); + WsV2.feedWDTV2(); WS_DEBUG_PRINT("ESP32 booted, version: "); WS_PRINTER.flush(); WS_DEBUG_PRINTLN(WiFi.firmwareVersion()); WS_PRINTER.flush(); - feedWDT(); + WsV2.feedWDTV2(); // validate co-processor's firmware version if (!firmwareCheck()) { @@ -330,26 +332,25 @@ class ws_wifi_airlift : public Wippersnapper { WS_DEBUG_PRINT("Connecting to "); WS_DEBUG_PRINTLN(_ssid); WS_PRINTER.flush(); - feedWDT(); + WsV2.feedWDTV2(); WiFi.begin(_ssid, _pass); - _status = WS_NET_DISCONNECTED; + _statusV2 = WS_NET_DISCONNECTED; // Use the macro to retry the status check until connected / timed out int lastResult = -1; RETRY_FUNCTION_UNTIL_TIMEOUT( []() -> int { return WiFi.status(); }, // Function call each cycle - int, // return type lastResult, // return variable [](int status) { return status == WL_CONNECTED; }, // check AIRLIFT_CONNECT_TIMEOUT_MS, // timeout interval (ms) AIRLIFT_CONNECT_RETRY_DELAY_MS); // interval between retries if (lastResult == WL_CONNECTED) { - _status = WS_NET_CONNECTED; + _statusV2 = WS_NET_CONNECTED; // wait 2seconds for connection to stabilize WS_DELAY_WITH_WDT(2000); } else { - _status = WS_NET_DISCONNECTED; // maybe connect failed instead? + _statusV2 = WS_NET_DISCONNECTED; // maybe connect failed instead? } } } diff --git a/src/adapters/wifi/ws_wifi_esp8266.h b/src/adapters/wifi/ws_wifi_esp8266.h index 73e25250d..14e56d8b3 100644 --- a/src/adapters/wifi/ws_wifi_esp8266.h +++ b/src/adapters/wifi/ws_wifi_esp8266.h @@ -8,7 +8,7 @@ * please support Adafruit and open-source hardware by purchasing * products from Adafruit! * - * Copyright (c) Brent Rubell 2020-2021 for Adafruit Industries. + * Copyright (c) Brent Rubell 2020-2025 for Adafruit Industries. * * MIT license, all text here must be included in any redistribution. * @@ -77,8 +77,8 @@ class ws_wifi_esp8266 : public Wippersnapper_V2 { ~ws_wifi_esp8266() { if (_wifi_client) delete _wifi_client; - if (_mqtt) - delete _mqtt; + if (_mqttV2) + delete _mqttV2; } /**********************************************************/ @@ -109,8 +109,8 @@ class ws_wifi_esp8266 : public Wippersnapper_V2 { */ /**********************************************************/ void set_ssid_pass() { - _ssid = WS._config.network.ssid; - _pass = WS._config.network.pass; + _ssid = WsV2._configV2.network.ssid; + _pass = WsV2._configV2.network.pass; } /***********************************************************/ @@ -142,7 +142,7 @@ class ws_wifi_esp8266 : public Wippersnapper_V2 { WS_DEBUG_PRINTLN(WiFi.RSSI(i)); return true; } - if (WS._isWiFiMultiV2) { + if (WsV2._isWiFiMultiV2) { // multi network mode for (int j = 0; j < WS_MAX_ALT_WIFI_NETWORKS; j++) { if (strcmp(WsV2._multiNetworksV2[j].ssid, WiFi.SSID(i).c_str()) == @@ -199,9 +199,10 @@ class ws_wifi_esp8266 : public Wippersnapper_V2 { /*******************************************************************/ void setupMQTTClient(const char *clientID) { // Uncomment the following lines to use MQTT/SSL. You will need to - // re-compile after. _wifi_client->setFingerprint(fingerprint); WS._mqtt = - // new Adafruit_MQTT_Client(_wifi_client, WS._config.aio_url, - // WS._config.io_port, clientID, WS._config.aio_user, WS._config.aio_key); + // re-compile after. _wifi_client->setFingerprint(fingerprint); WsV2._mqttV2 + // = new Adafruit_MQTT_Client(_wifi_client, WsV2._configV2.aio_url, + // WsV2._configV2.io_port, clientID, WsV2._configV2.aio_user, + // WsV2._configV2.aio_key); if (WsV2._configV2.io_port == 8883) WsV2._configV2.io_port = 1883; WsV2._mqttV2 = new Adafruit_MQTT_Client( @@ -247,7 +248,7 @@ class ws_wifi_esp8266 : public Wippersnapper_V2 { @brief Establishes a connection with the wireless network. */ /**************************************************************************/ - void _connect()() { + void _connect() { if (WiFi.status() == WL_CONNECTED) return; @@ -265,7 +266,7 @@ class ws_wifi_esp8266 : public Wippersnapper_V2 { _statusV2 = WS_NET_DISCONNECTED; delay(100); - if (WS._isWiFiMultiV2) { + if (WsV2._isWiFiMultiV2) { // multi network mode for (int i = 0; i < WS_MAX_ALT_WIFI_NETWORKS; i++) { if (strlen(WsV2._multiNetworksV2[i].ssid) > 0 && @@ -307,7 +308,7 @@ class ws_wifi_esp8266 : public Wippersnapper_V2 { _statusV2 = WS_NET_DISCONNECTED; } } - WsV2.feedWDT(); + WsV2.feedWDTV2(); } } diff --git a/src/adapters/wifi/ws_wifi_pico.h b/src/adapters/wifi/ws_wifi_pico.h index 07ba5066a..b30567ef3 100644 --- a/src/adapters/wifi/ws_wifi_pico.h +++ b/src/adapters/wifi/ws_wifi_pico.h @@ -17,7 +17,8 @@ #ifndef WS_WIFI_PICO_H #define WS_WIFI_PICO_H -#ifdef ARDUINO_RASPBERRY_PI_PICO_W +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) || \ + defined(ARDUINO_RASPBERRY_PI_PICO_2W) #define PICO_CONNECT_TIMEOUT_MS 20000 /*!< Connection timeout (in ms) */ #define PICO_CONNECT_RETRY_DELAY_MS 200 /*!< delay time between retries. */ diff --git a/src/components/analogIO/controller.cpp b/src/components/analogIO/controller.cpp index 7fae11b54..ce5260221 100644 --- a/src/components/analogIO/controller.cpp +++ b/src/components/analogIO/controller.cpp @@ -1,5 +1,5 @@ /*! - * @file controller.cpp + * @file src/components/analogIO/controller.cpp * * Controller for the analogio.proto API * diff --git a/src/components/analogIO/controller.h b/src/components/analogIO/controller.h index d046578c8..41aae6bbd 100644 --- a/src/components/analogIO/controller.h +++ b/src/components/analogIO/controller.h @@ -1,5 +1,5 @@ /*! - * @file controller.h + * @file src/components/analogIO/controller.h * * Controller for the AnalogIO API * diff --git a/src/components/analogIO/hardware.cpp b/src/components/analogIO/hardware.cpp index 038143fff..c5e3632ea 100644 --- a/src/components/analogIO/hardware.cpp +++ b/src/components/analogIO/hardware.cpp @@ -1,5 +1,5 @@ /*! - * @file hardware.cpp + * @file src/components/analogIO/hardware.cpp * * Hardware interface for the analogio.proto API * @@ -84,8 +84,10 @@ void AnalogIOHardware::SetNativeADCResolution() { #else _native_adc_resolution = 10; #endif +#ifndef ARDUINO_ARCH_ESP8266 // Set the resolution (in bits) of the hardware's ADC analogReadResolution(_native_adc_resolution); +#endif // ARDUINO_ARCH_ESP8266 } /*************************************************************************/ diff --git a/src/components/analogIO/hardware.h b/src/components/analogIO/hardware.h index 447495034..92eab469d 100644 --- a/src/components/analogIO/hardware.h +++ b/src/components/analogIO/hardware.h @@ -1,5 +1,5 @@ /*! - * @file model.h + * @file src/components/analogIO/hardware.h * * Hardware implementation for the analogio.proto message. * diff --git a/src/components/analogIO/model.cpp b/src/components/analogIO/model.cpp index b5c9f9854..c18c3da16 100644 --- a/src/components/analogIO/model.cpp +++ b/src/components/analogIO/model.cpp @@ -1,5 +1,5 @@ /*! - * @file model.cpp + * @file src/components/analogIO/model.cpp * * Interfaces for the analogio.proto API * @@ -20,7 +20,10 @@ */ /***********************************************************************/ AnalogIOModel::AnalogIOModel() { - _msg_AnalogioAdd = wippersnapper_analogio_AnalogIOAdd_init_default; + memset(&_msg_AnalogioAdd, 0, sizeof(_msg_AnalogioAdd)); + memset(&_msg_AnalogioRemove, 0, sizeof(_msg_AnalogioRemove)); + memset(&_msg_AnalogioEvent, 0, sizeof(_msg_AnalogioEvent)); + // no-op } /***********************************************************************/ @@ -28,7 +31,11 @@ AnalogIOModel::AnalogIOModel() { @brief AnalogIOModel destructor */ /***********************************************************************/ -AnalogIOModel::~AnalogIOModel() {} +AnalogIOModel::~AnalogIOModel() { + memset(&_msg_AnalogioAdd, 0, sizeof(_msg_AnalogioAdd)); + memset(&_msg_AnalogioRemove, 0, sizeof(_msg_AnalogioRemove)); + memset(&_msg_AnalogioEvent, 0, sizeof(_msg_AnalogioEvent)); +} /***********************************************************************/ /*! @@ -42,7 +49,7 @@ AnalogIOModel::~AnalogIOModel() {} bool AnalogIOModel::DecodeAnalogIOAdd(pb_istream_t *stream) { // Zero-out the AnalogIOAdd message struct. to ensure we don't have any old // data - _msg_AnalogioAdd = wippersnapper_analogio_AnalogIOAdd_init_default; + memset(&_msg_AnalogioAdd, 0, sizeof(_msg_AnalogioAdd)); // Decode the stream into a AnalogIOAdd message return pb_decode(stream, wippersnapper_analogio_AnalogIOAdd_fields, &_msg_AnalogioAdd); @@ -70,7 +77,7 @@ wippersnapper_analogio_AnalogIOAdd *AnalogIOModel::GetAnalogIOAddMsg() { bool AnalogIOModel::DecodeAnalogIORemove(pb_istream_t *stream) { // Zero-out the AnalogIORemove message struct. to ensure we don't have any old // data - _msg_AnalogioRemove = wippersnapper_analogio_AnalogIORemove_init_default; + memset(&_msg_AnalogioRemove, 0, sizeof(_msg_AnalogioRemove)); // Decode the stream into a AnalogIORemove message return pb_decode(stream, wippersnapper_analogio_AnalogIORemove_fields, &_msg_AnalogioRemove); @@ -112,7 +119,7 @@ bool AnalogIOModel::EncodeAnalogIOEvent( char *pin_name, float pin_value, wippersnapper_sensor_SensorType read_type) { // Initialize the AnalogIOEvent message to default values - _msg_AnalogioEvent = wippersnapper_analogio_AnalogIOEvent_init_zero; + memset(&_msg_AnalogioEvent, 0, sizeof(_msg_AnalogioEvent)); // Fill the AnalogIOEvent message's fields strncpy(_msg_AnalogioEvent.pin_name, pin_name, sizeof(_msg_AnalogioEvent.pin_name)); diff --git a/src/components/analogIO/model.h b/src/components/analogIO/model.h index f20fd4c46..64f6606e0 100644 --- a/src/components/analogIO/model.h +++ b/src/components/analogIO/model.h @@ -1,5 +1,5 @@ /*! - * @file model.h + * @file src/components/analogIO/model.h * * Model interface for the analogio.proto message. * diff --git a/src/components/checkin/model.cpp b/src/components/checkin/model.cpp index 3ddf0d38b..2c4d0e2d4 100644 --- a/src/components/checkin/model.cpp +++ b/src/components/checkin/model.cpp @@ -1,5 +1,5 @@ /*! - * @file model.cpp + * @file src/components/checkin/model.cpp * * Model for the Wippersnapper checkin proto API. * @@ -20,8 +20,9 @@ */ /***********************************************************************/ CheckinModel::CheckinModel() { - _CheckinRequest = wippersnapper_checkin_CheckinRequest_init_default; - _CheckinResponse = wippersnapper_checkin_CheckinResponse_init_default; + memset(&_CheckinRequest, 0, sizeof(_CheckinRequest)); + memset(&_CheckinResponse, 0, sizeof(_CheckinResponse)); + // no-op } /***********************************************************************/ @@ -30,8 +31,8 @@ CheckinModel::CheckinModel() { */ /***********************************************************************/ CheckinModel::~CheckinModel() { - _CheckinRequest = wippersnapper_checkin_CheckinRequest_init_default; - _CheckinResponse = wippersnapper_checkin_CheckinResponse_init_default; + memset(&_CheckinRequest, 0, sizeof(_CheckinRequest)); + memset(&_CheckinResponse, 0, sizeof(_CheckinResponse)); } /***********************************************************************/ @@ -83,6 +84,7 @@ bool CheckinModel::EncodeCheckinRequest() { */ /***********************************************************************/ bool CheckinModel::DecodeCheckinResponse(pb_istream_t *stream) { + memset(&_CheckinResponse, 0, sizeof(_CheckinResponse)); return pb_decode(stream, wippersnapper_checkin_CheckinResponse_fields, &_CheckinResponse); } diff --git a/src/components/checkin/model.h b/src/components/checkin/model.h index 280d62a6c..b5fae9d1b 100644 --- a/src/components/checkin/model.h +++ b/src/components/checkin/model.h @@ -1,5 +1,5 @@ /*! - * @file model.h + * @file src/components/checkin/model.h * * Model for the Wippersnapper checkin proto API. * diff --git a/src/components/digitalIO/controller.cpp b/src/components/digitalIO/controller.cpp index b32ee2569..2f3416411 100644 --- a/src/components/digitalIO/controller.cpp +++ b/src/components/digitalIO/controller.cpp @@ -1,5 +1,5 @@ /*! - * @file controller.cpp + * @file src/components/digitalIO/controller.cpp * * Controller for the digitalio.proto API * diff --git a/src/components/digitalIO/controller.h b/src/components/digitalIO/controller.h index e1de9666e..115829511 100644 --- a/src/components/digitalIO/controller.h +++ b/src/components/digitalIO/controller.h @@ -1,5 +1,5 @@ /*! - * @file controller.h + * @file src/components/digitalIO/controller.h * * Controller for the digitalio API * diff --git a/src/components/digitalIO/hardware.cpp b/src/components/digitalIO/hardware.cpp index f6503e1a8..bc8198a83 100644 --- a/src/components/digitalIO/hardware.cpp +++ b/src/components/digitalIO/hardware.cpp @@ -1,5 +1,5 @@ /*! - * @file hardware.cpp + * @file src/components/digitalIO/hardware.cpp * * Hardware driver for the digitalio.proto API * diff --git a/src/components/digitalIO/hardware.h b/src/components/digitalIO/hardware.h index e471c6b7d..8b9d43b4e 100644 --- a/src/components/digitalIO/hardware.h +++ b/src/components/digitalIO/hardware.h @@ -1,7 +1,7 @@ /*! - * @file model.h + * @file src/components/digitalIO/hardware.h * - * Model for the digitalio.proto message. + * Hardware for the digitalio.proto message. * * Adafruit invests time and resources providing this open source code, * please support Adafruit and open-source hardware by purchasing diff --git a/src/components/digitalIO/model.cpp b/src/components/digitalIO/model.cpp index 6643b1c49..18597027f 100644 --- a/src/components/digitalIO/model.cpp +++ b/src/components/digitalIO/model.cpp @@ -1,5 +1,5 @@ /*! - * @file model.cpp + * @file src/components/digitalIO/model.cpp * * Model for the digitalio.proto message. * @@ -20,10 +20,11 @@ */ /***********************************************************************/ DigitalIOModel::DigitalIOModel() { - _msg_dio_add = wippersnapper_digitalio_DigitalIOAdd_init_default; - _msg_dio_remove = wippersnapper_digitalio_DigitalIORemove_init_default; - _msg_dio_event = wippersnapper_digitalio_DigitalIOEvent_init_default; - _msg_dio_write = wippersnapper_digitalio_DigitalIOWrite_init_default; + memset(&_msg_dio_add, 0, sizeof(_msg_dio_add)); + memset(&_msg_dio_remove, 0, sizeof(_msg_dio_remove)); + memset(&_msg_dio_event, 0, sizeof(_msg_dio_event)); + memset(&_msg_dio_write, 0, sizeof(_msg_dio_write)); + // no-op } /***********************************************************************/ @@ -31,7 +32,12 @@ DigitalIOModel::DigitalIOModel() { @brief DigitalIOModel destructor */ /***********************************************************************/ -DigitalIOModel::~DigitalIOModel() {} +DigitalIOModel::~DigitalIOModel() { + memset(&_msg_dio_add, 0, sizeof(_msg_dio_add)); + memset(&_msg_dio_remove, 0, sizeof(_msg_dio_remove)); + memset(&_msg_dio_event, 0, sizeof(_msg_dio_event)); + memset(&_msg_dio_write, 0, sizeof(_msg_dio_write)); +} /***********************************************************************/ /*! @@ -54,7 +60,7 @@ wippersnapper_digitalio_DigitalIOAdd *DigitalIOModel::GetDigitalIOAddMsg() { bool DigitalIOModel::DecodeDigitalIORemove(pb_istream_t *stream) { // Zero-out the DigitalIORemove message struct. to ensure we don't have any // old data - _msg_dio_remove = wippersnapper_digitalio_DigitalIORemove_init_default; + memset(&_msg_dio_remove, 0, sizeof(_msg_dio_remove)); // Decode the stream into a DigitalIORemove message return pb_decode(stream, wippersnapper_digitalio_DigitalIORemove_fields, @@ -93,7 +99,7 @@ wippersnapper_digitalio_DigitalIOEvent *DigitalIOModel::GetDigitalIOEventMsg() { bool DigitalIOModel::DecodeDigitalIOAdd(pb_istream_t *stream) { // Zero-out the DigitalIOAdd message struct. to ensure we don't have any old // data - _msg_dio_add = wippersnapper_digitalio_DigitalIOAdd_init_default; + memset(&_msg_dio_add, 0, sizeof(_msg_dio_add)); // Decode the stream into a DigitalIOAdd message return pb_decode(stream, wippersnapper_digitalio_DigitalIOAdd_fields, @@ -112,7 +118,7 @@ bool DigitalIOModel::DecodeDigitalIOAdd(pb_istream_t *stream) { bool DigitalIOModel::DecodeDigitalIOWrite(pb_istream_t *stream) { // Zero-out the DigitalIOWrite message struct. to ensure we don't have any old // data - _msg_dio_write = wippersnapper_digitalio_DigitalIOWrite_init_default; + memset(&_msg_dio_write, 0, sizeof(_msg_dio_write)); // Decode the stream into a DigitalIOWrite message return pb_decode(stream, wippersnapper_digitalio_DigitalIOWrite_fields, &_msg_dio_write); @@ -132,7 +138,7 @@ bool DigitalIOModel::DecodeDigitalIOWrite(pb_istream_t *stream) { /***********************************************************************/ bool DigitalIOModel::EncodeDigitalIOEvent(char *pin_name, bool value) { // Initialize the DigitalIOEvent - _msg_dio_event = wippersnapper_digitalio_DigitalIOEvent_init_default; + memset(&_msg_dio_event, 0, sizeof(_msg_dio_event)); // Fill the DigitalIOEvent strncpy(_msg_dio_event.pin_name, pin_name, sizeof(_msg_dio_event.pin_name)); _msg_dio_event.has_value = true; diff --git a/src/components/digitalIO/model.h b/src/components/digitalIO/model.h index d0840efd0..2f90031c1 100644 --- a/src/components/digitalIO/model.h +++ b/src/components/digitalIO/model.h @@ -1,5 +1,5 @@ /*! - * @file model.h + * @file src/components/digitalIO/model.h * * Model for the digitalio.proto message. * diff --git a/src/components/ds18x20/controller.cpp b/src/components/ds18x20/controller.cpp index 06a4a3b2c..bc31d2266 100644 --- a/src/components/ds18x20/controller.cpp +++ b/src/components/ds18x20/controller.cpp @@ -1,5 +1,5 @@ /*! - * @file controller.cpp + * @file src/components/ds18x20/controller.cpp * * Controller for the ds18x20.proto API * @@ -64,9 +64,13 @@ bool DS18X20Controller::Handle_Ds18x20Add(pb_istream_t *stream) { // Extract the OneWire pin from the message uint8_t pin_name = atoi(_DS18X20_model->GetDS18x20AddMsg()->onewire_pin + 1); - // Initialize the DS18X20Hardware object +#ifdef ARDUINO_ARCH_SAMD + auto new_dsx_driver = new DS18X20Hardware(pin_name, _num_drivers); + std::unique_ptr unique_driver(new_dsx_driver); +#else auto new_dsx_driver = std::make_unique(pin_name, _num_drivers); +#endif // Attempt to get the sensor's ID on the OneWire bus to show it's been init'd bool is_initialized = new_dsx_driver->GetSensor(); @@ -103,7 +107,11 @@ bool DS18X20Controller::Handle_Ds18x20Add(pb_istream_t *stream) { // If the sensor was successfully initialized, add it to the controller if (is_initialized == true) { +#ifdef ARDUINO_ARCH_SAMD + _DS18X20_pins.push_back(std::move(unique_driver)); +#else _DS18X20_pins.push_back(std::move(new_dsx_driver)); +#endif _num_drivers++; } diff --git a/src/components/ds18x20/controller.h b/src/components/ds18x20/controller.h index 037e517b7..fcc3e8add 100644 --- a/src/components/ds18x20/controller.h +++ b/src/components/ds18x20/controller.h @@ -1,5 +1,5 @@ /*! - * @file controller.h + * @file src/components/ds18x20/controller.h * * Controller for the DS18X20 API * diff --git a/src/components/ds18x20/hardware.cpp b/src/components/ds18x20/hardware.cpp index beaf37aa0..5c0a74e84 100644 --- a/src/components/ds18x20/hardware.cpp +++ b/src/components/ds18x20/hardware.cpp @@ -1,5 +1,5 @@ /*! - * @file hardware.cpp + * @file src/components/ds18x20/hardware.cpp * * Hardware interface for the ds18x20.proto API * diff --git a/src/components/ds18x20/hardware.h b/src/components/ds18x20/hardware.h index 95e8b6663..bf59a6922 100644 --- a/src/components/ds18x20/hardware.h +++ b/src/components/ds18x20/hardware.h @@ -1,5 +1,5 @@ /*! - * @file model.h + * @file src/components/ds18x20/hardware.h * * Hardware implementation for the ds18x20.proto message. * diff --git a/src/components/ds18x20/model.cpp b/src/components/ds18x20/model.cpp index 17dd039c0..0cd8b078a 100644 --- a/src/components/ds18x20/model.cpp +++ b/src/components/ds18x20/model.cpp @@ -1,5 +1,5 @@ /*! - * @file model.cpp + * @file src/components/ds18x20/model.cpp * * Model for the ds18x20.proto message. * @@ -20,10 +20,11 @@ */ /***********************************************************************/ DS18X20Model::DS18X20Model() { - // Initialize the DS18X20 messages - _msg_DS18x20Add = wippersnapper_ds18x20_Ds18x20Add_init_zero; - _msg_DS18x20Added = wippersnapper_ds18x20_Ds18x20Added_init_zero; - _msg_DS18x20Remove = wippersnapper_ds18x20_Ds18x20Remove_init_zero; + memset(&_msg_DS18x20Add, 0, sizeof(_msg_DS18x20Add)); + memset(&_msg_DS18x20Added, 0, sizeof(_msg_DS18x20Added)); + memset(&_msg_DS18x20Remove, 0, sizeof(_msg_DS18x20Remove)); + memset(&_msg_DS18x20Event, 0, sizeof(_msg_DS18x20Event)); + // no-op } /***********************************************************************/ @@ -31,7 +32,12 @@ DS18X20Model::DS18X20Model() { @brief DS18X20Model destructor */ /***********************************************************************/ -DS18X20Model::~DS18X20Model() {} +DS18X20Model::~DS18X20Model() { + memset(&_msg_DS18x20Add, 0, sizeof(_msg_DS18x20Add)); + memset(&_msg_DS18x20Added, 0, sizeof(_msg_DS18x20Added)); + memset(&_msg_DS18x20Remove, 0, sizeof(_msg_DS18x20Remove)); + memset(&_msg_DS18x20Event, 0, sizeof(_msg_DS18x20Event)); +} /***********************************************************************/ /*! @@ -42,7 +48,7 @@ DS18X20Model::~DS18X20Model() {} */ /***********************************************************************/ bool DS18X20Model::DecodeDS18x20Add(pb_istream_t *stream) { - _msg_DS18x20Add = wippersnapper_ds18x20_Ds18x20Add_init_zero; + memset(&_msg_DS18x20Add, 0, sizeof(_msg_DS18x20Add)); // Attempt to decode the stream into a Ds18x20Add message return pb_decode(stream, wippersnapper_ds18x20_Ds18x20Add_fields, &_msg_DS18x20Add); @@ -82,7 +88,7 @@ wippersnapper_ds18x20_Ds18x20Added *DS18X20Model::GetDS18x20AddedMsg() { /***********************************************************************/ bool DS18X20Model::EncodeDS18x20Added(char *onewire_pin, bool is_init) { // Fill the Ds18x20Added message - _msg_DS18x20Added = wippersnapper_ds18x20_Ds18x20Added_init_zero; + memset(&_msg_DS18x20Added, 0, sizeof(_msg_DS18x20Added)); _msg_DS18x20Added.is_initialized = is_init; strcpy(_msg_DS18x20Added.onewire_pin, onewire_pin); @@ -107,7 +113,7 @@ bool DS18X20Model::EncodeDS18x20Added(char *onewire_pin, bool is_init) { */ /*************************************************************************/ bool DS18X20Model::DecodeDS18x20Remove(pb_istream_t *stream) { - _msg_DS18x20Remove = wippersnapper_ds18x20_Ds18x20Remove_init_zero; + memset(&_msg_DS18x20Remove, 0, sizeof(_msg_DS18x20Remove)); return pb_decode(stream, wippersnapper_ds18x20_Ds18x20Remove_fields, &_msg_DS18x20Remove); } @@ -159,7 +165,7 @@ bool DS18X20Model::EncodeDs18x20Event() { */ /*************************************************************************/ void DS18X20Model::InitDS18x20EventMsg(const char *ow_pin_name) { - _msg_DS18x20Event = wippersnapper_ds18x20_Ds18x20Event_init_zero; + memset(&_msg_DS18x20Event, 0, sizeof(_msg_DS18x20Event)); _msg_DS18x20Event.sensor_events_count = 0; strcpy(_msg_DS18x20Event.onewire_pin, ow_pin_name); } diff --git a/src/components/ds18x20/model.h b/src/components/ds18x20/model.h index c7efaac4b..26343fff8 100644 --- a/src/components/ds18x20/model.h +++ b/src/components/ds18x20/model.h @@ -1,5 +1,5 @@ /*! - * @file model.h + * @file src/components/ds18x20/model.h * * Model interface for the DS18X20.proto message. * diff --git a/src/components/i2c/controller.cpp b/src/components/i2c/controller.cpp index 56da34763..e14344d91 100644 --- a/src/components/i2c/controller.cpp +++ b/src/components/i2c/controller.cpp @@ -1,5 +1,5 @@ /*! - * @file controller.cpp + * @file src/components/i2c/controller.cpp * * Controller for the i2c.proto API * @@ -414,9 +414,11 @@ bool I2cController::RemoveDriver(uint32_t address) { if (driver->GetAddress() != address) continue; + auto it = std::find(_i2c_drivers.begin(), _i2c_drivers.end(), driver); + if (it != _i2c_drivers.end()) { + _i2c_drivers.erase(it); + } delete driver; - _i2c_drivers.erase( - std::find(_i2c_drivers.begin(), _i2c_drivers.end(), driver)); return true; } return false; @@ -488,7 +490,7 @@ bool I2cController::PublishI2cDeviceAddedorReplaced( bool I2cController::Handle_I2cDeviceRemove(pb_istream_t *stream) { // Attempt to decode an I2cDeviceRemove message WS_DEBUG_PRINTLN("[i2c] Decoding I2cDeviceRemove message..."); - if (! _i2c_model->DecodeI2cDeviceRemove(stream)) { + if (!_i2c_model->DecodeI2cDeviceRemove(stream)) { WS_DEBUG_PRINTLN("[i2c] ERROR: Unable to decode I2cDeviceRemove message!"); return false; } @@ -894,7 +896,7 @@ void I2cController::ConfigureMuxChannel(uint32_t mux_channel, bool is_alt_bus) { */ /***********************************************************************/ void I2cController::update() { - //WS_DEBUG_PRINTLN("[i2c] Updating I2C controller..."); + // WS_DEBUG_PRINTLN("[i2c] Updating I2C controller..."); if (_i2c_drivers.size() == 0) return; // bail out if no drivers exist diff --git a/src/components/i2c/controller.h b/src/components/i2c/controller.h index 5c515706d..cb2a9d2ab 100644 --- a/src/components/i2c/controller.h +++ b/src/components/i2c/controller.h @@ -1,5 +1,5 @@ /*! - * @file controller.h + * @file src/components/i2c/controller.h * * Routing controller for WipperSnapper's I2C component. * @@ -92,10 +92,11 @@ class I2cController { const wippersnapper_i2c_I2cDeviceDescriptor &device_descriptor, const wippersnapper_i2c_I2cDeviceStatus &device_status); // Helpers // - bool IsBusStatusOK(bool is_alt_bus=false); + bool IsBusStatusOK(bool is_alt_bus = false); bool InitMux(const char *name, uint32_t address, bool is_alt_bus); void ConfigureMuxChannel(uint32_t mux_channel, bool is_alt_bus); bool RemoveDriver(uint32_t address); + private: I2cModel *_i2c_model; ///< Pointer to an I2C model object I2cHardware *_i2c_bus_default; ///< Pointer to the default I2C bus diff --git a/src/components/i2c/hardware.cpp b/src/components/i2c/hardware.cpp index ddc631472..53fef36ca 100644 --- a/src/components/i2c/hardware.cpp +++ b/src/components/i2c/hardware.cpp @@ -1,3 +1,17 @@ +/*! + * @file src/components/i2c/hardware.cpp + * + * Hardware implementation for the i2c.proto API + * + * Adafruit invests time and resources providing this open source code, + * please support Adafruit and open-source hardware by purchasing + * products from Adafruit! + * + * Copyright (c) Brent Rubell 2025 for Adafruit Industries. + * + * BSD license, all text here must be included in any redistribution. + * + */ #include "hardware.h" /***********************************************************************/ @@ -145,7 +159,7 @@ void I2cHardware::InitBus(bool is_default, const char *sda, const char *scl) { _bus->setSDA(_bus_sda); _bus->setSCL(_bus_scl); _bus->begin(); -#elif defined(ARDUINO_ARCH_SAM) +#elif defined(ARDUINO_ARCH_SAMD) _bus = new TwoWire(&PERIPH_WIRE, _bus_sda, _bus_scl); _bus->begin(); #else @@ -216,7 +230,8 @@ bool I2cHardware::ScanBus(wippersnapper_i2c_I2cBusScanned *scan_results) { WS_DEBUG_PRINTLN("[i2c] Did not find device: NACK on transmit of data!"); continue; } else if (endTransmissionRC == 2) { - //WS_DEBUG_PRINTLN("[i2c] Did not find device: NACK on transmit of address!"); + // WS_DEBUG_PRINTLN("[i2c] Did not find device: NACK on transmit of + // address!"); continue; } else if (endTransmissionRC == 1) { WS_DEBUG_PRINTLN( @@ -229,19 +244,22 @@ bool I2cHardware::ScanBus(wippersnapper_i2c_I2cBusScanned *scan_results) { } else if (endTransmissionRC == 5) { WS_DEBUG_PRINTLN("[i2c] Did not find device: Bus timed out!"); continue; + } #endif // ARDUINO_ARCH_ESP32 - } else { + else { WS_DEBUG_PRINTLN( "[i2c] Did not find device: Unknown bus error has occured!"); continue; } } - /* #ifndef ARDUINO_ARCH_ESP32 + /* + #ifndef ARDUINO_ARCH_ESP32 // re-enable WipperSnapper SAMD WDT global timeout WS.enableWDT(WS_WDT_TIMEOUT); WS.feedWDT(); - #endif */ + #endif + */ return true; // TODO: Change this! } @@ -301,7 +319,7 @@ void I2cHardware::RemoveMux() { void I2cHardware::ClearMuxChannel() { if (!_has_mux) return; - _bus->beginTransmission(_mux_address_register); + _bus->beginTransmission((uint8_t)_mux_address_register); if (_mux_max_channels == 4) _bus->write(0b0000); else if (_mux_max_channels == 8) @@ -319,7 +337,7 @@ void I2cHardware::ClearMuxChannel() { void I2cHardware::SelectMuxChannel(uint32_t channel) { if (channel > _mux_max_channels - 1) return; - _bus->beginTransmission(_mux_address_register); + _bus->beginTransmission((uint8_t)_mux_address_register); _bus->write(1 << channel); _bus->endTransmission(); } diff --git a/src/components/i2c/hardware.h b/src/components/i2c/hardware.h index e6d0f8e88..19322dbd7 100644 --- a/src/components/i2c/hardware.h +++ b/src/components/i2c/hardware.h @@ -1,5 +1,5 @@ /*! - * @file hardware.cpp + * @file src/components/i2c/hardware.h * * Hardware driver for the i2c API * @@ -38,14 +38,15 @@ class I2cHardware { const char *scl = nullptr); TwoWire *GetBus(); wippersnapper_i2c_I2cBusStatus GetBusStatus(); - bool ScanBus(wippersnapper_i2c_I2cBusScanned* scan_results); + bool ScanBus(wippersnapper_i2c_I2cBusScanned *scan_results); // MUX bool AddMuxToBus(uint32_t address_register, const char *name); void RemoveMux(); bool HasMux(); void ClearMuxChannel(); void SelectMuxChannel(uint32_t channel); - bool ScanMux(wippersnapper_i2c_I2cBusScanned* scan_results); + bool ScanMux(wippersnapper_i2c_I2cBusScanned *scan_results); + private: void TogglePowerPin(); wippersnapper_i2c_I2cBusStatus _bus_status; ///< I2C bus status @@ -54,6 +55,6 @@ class I2cHardware { uint8_t _bus_scl; ///< SCL pin bool _has_mux; ///< Is a MUX present on the bus? uint32_t _mux_address_register; ///< I2C address for the MUX - int _mux_max_channels; ///< Maximum possible number of MUX channels + int _mux_max_channels; ///< Maximum possible number of MUX channels }; #endif // WS_I2C_HARDWARE_H \ No newline at end of file diff --git a/src/components/i2c/model.cpp b/src/components/i2c/model.cpp index 9a0d0ffc6..200148d38 100644 --- a/src/components/i2c/model.cpp +++ b/src/components/i2c/model.cpp @@ -1,5 +1,5 @@ /*! - * @file model.cpp + * @file src/components/i2c/model.cpp * * Model for the i2c.proto message. * @@ -20,15 +20,15 @@ */ /***********************************************************************/ I2cModel::I2cModel() { - _msg_i2c_bus_scan = wippersnapper_i2c_I2cBusScan_init_default; - _msg_i2c_bus_scanned = wippersnapper_i2c_I2cBusScanned_init_default; - _msg_i2c_device_add_replace = - wippersnapper_i2c_I2cDeviceAddOrReplace_init_default; - _msg_i2c_device_added_replaced = - wippersnapper_i2c_I2cDeviceAddedOrReplaced_init_default; - _msg_i2c_device_remove = wippersnapper_i2c_I2cDeviceRemove_init_default; - _msg_i2c_device_removed = wippersnapper_i2c_I2cDeviceRemoved_init_default; - _msg_i2c_device_event = wippersnapper_i2c_I2cDeviceEvent_init_default; + memset(&_msg_i2c_bus_scan, 0, sizeof(_msg_i2c_bus_scan)); + memset(&_msg_i2c_bus_scanned, 0, sizeof(_msg_i2c_bus_scanned)); + memset(&_msg_i2c_device_add_replace, 0, sizeof(_msg_i2c_device_add_replace)); + memset(&_msg_i2c_device_added_replaced, 0, + sizeof(_msg_i2c_device_added_replaced)); + memset(&_msg_i2c_device_remove, 0, sizeof(_msg_i2c_device_remove)); + memset(&_msg_i2c_device_removed, 0, sizeof(_msg_i2c_device_removed)); + memset(&_msg_i2c_device_event, 0, sizeof(_msg_i2c_device_event)); + // no-op } /***********************************************************************/ @@ -37,7 +37,14 @@ I2cModel::I2cModel() { */ /***********************************************************************/ I2cModel::~I2cModel() { - // nothing to add here! + memset(&_msg_i2c_bus_scan, 0, sizeof(_msg_i2c_bus_scan)); + memset(&_msg_i2c_bus_scanned, 0, sizeof(_msg_i2c_bus_scanned)); + memset(&_msg_i2c_device_add_replace, 0, sizeof(_msg_i2c_device_add_replace)); + memset(&_msg_i2c_device_added_replaced, 0, + sizeof(_msg_i2c_device_added_replaced)); + memset(&_msg_i2c_device_remove, 0, sizeof(_msg_i2c_device_remove)); + memset(&_msg_i2c_device_removed, 0, sizeof(_msg_i2c_device_removed)); + memset(&_msg_i2c_device_event, 0, sizeof(_msg_i2c_device_event)); } /***************************************************************************/ @@ -135,10 +142,12 @@ float GetValueFromSensorsEvent(wippersnapper_sensor_SensorType sensor_type, /****************************************************************************/ bool I2cModel::DecodeI2cDeviceRemove(pb_istream_t *stream) { WS_DEBUG_PRINTLN("[i2c] Set _msg_i2c_device_remove..."); - _msg_i2c_device_remove = wippersnapper_i2c_I2cDeviceRemove_init_default; + memset(&_msg_i2c_device_remove, 0, sizeof(_msg_i2c_device_remove)); bool is_success = false; - is_success = pb_decode(stream, wippersnapper_i2c_I2cDeviceRemove_fields, &_msg_i2c_device_remove); - WS_DEBUG_PRINT("is_success: "); WS_DEBUG_PRINTLN(is_success); + is_success = pb_decode(stream, wippersnapper_i2c_I2cDeviceRemove_fields, + &_msg_i2c_device_remove); + WS_DEBUG_PRINT("is_success: "); + WS_DEBUG_PRINTLN(is_success); return is_success; } @@ -162,7 +171,7 @@ wippersnapper_i2c_I2cDeviceRemove *I2cModel::GetI2cDeviceRemoveMsg() { */ /***************************************************************************/ bool I2cModel::DecodeI2cBusScan(pb_istream_t *stream) { - _msg_i2c_bus_scan = wippersnapper_i2c_I2cBusScan_init_default; + memset(&_msg_i2c_bus_scan, 0, sizeof(_msg_i2c_bus_scan)); return pb_decode(stream, wippersnapper_i2c_I2cBusScan_fields, &_msg_i2c_bus_scan); } @@ -193,7 +202,7 @@ wippersnapper_i2c_I2cBusScanned *I2cModel::GetI2cBusScannedMsg() { */ /**********************************************************************/ void I2cModel::ClearI2cBusScanned() { - _msg_i2c_bus_scanned = wippersnapper_i2c_I2cBusScanned_init_zero; + memset(&_msg_i2c_bus_scanned, 0, sizeof(_msg_i2c_bus_scanned)); _msg_i2c_bus_scanned.i2c_bus_found_devices_count = 0; // zero-out the count } @@ -247,8 +256,7 @@ bool I2cModel::AddDeviceToBusScan(const char *bus_scl, const char *bus_sda, */ /***************************************************************************/ bool I2cModel::DecodeI2cDeviceAddReplace(pb_istream_t *stream) { - _msg_i2c_device_add_replace = - wippersnapper_i2c_I2cDeviceAddOrReplace_init_default; + memset(&_msg_i2c_device_add_replace, 0, sizeof(_msg_i2c_device_add_replace)); return pb_decode(stream, wippersnapper_i2c_I2cDeviceAddOrReplace_fields, &_msg_i2c_device_add_replace); } @@ -283,8 +291,8 @@ bool I2cModel::encodeMsgI2cDeviceAddedorReplaced( size_t sz_msg; // Fill I2cDeviceAddedOrReplaced message - _msg_i2c_device_added_replaced = - wippersnapper_i2c_I2cDeviceAddedOrReplaced_init_zero; + memset(&_msg_i2c_device_added_replaced, 0, + sizeof(_msg_i2c_device_added_replaced)); _msg_i2c_device_added_replaced.has_i2c_device_description = true; _msg_i2c_device_added_replaced.i2c_device_description = device_descriptor; _msg_i2c_device_added_replaced.i2c_bus_status = bus_status; @@ -320,7 +328,7 @@ I2cModel::GetMsgI2cDeviceAddedOrReplaced() { */ /**********************************************************************/ void I2cModel::ClearI2cDeviceEvent() { - _msg_i2c_device_event = wippersnapper_i2c_I2cDeviceEvent_init_zero; + memset(&_msg_i2c_device_event, 0, sizeof(_msg_i2c_device_event)); _msg_i2c_device_event.i2c_device_events_count = 0; } diff --git a/src/components/i2c/model.h b/src/components/i2c/model.h index fedcf0c58..328783b7f 100644 --- a/src/components/i2c/model.h +++ b/src/components/i2c/model.h @@ -1,5 +1,5 @@ /*! - * @file model.h + * @file src/components/i2c/model.h * * Provides high-level interfaces for messages within i2c.proto. * diff --git a/src/components/pixels/controller.cpp b/src/components/pixels/controller.cpp index 1a1976c85..c8da27733 100644 --- a/src/components/pixels/controller.cpp +++ b/src/components/pixels/controller.cpp @@ -1,5 +1,5 @@ /*! - * @file controller.cpp + * @file src/components/pixels/controller.cpp * * Implementation for the pixels API controller. * @@ -60,8 +60,13 @@ bool PixelsController::Handle_Pixels_Add(pb_istream_t *stream) { msg_add->pixels_type, msg_add->pixels_ordering, msg_add->pixels_num, msg_add->pixels_brightness, msg_add->pixels_pin_data, msg_add->pixels_pin_dotstar_clock); - if (!did_init) + if (!did_init) { WS_DEBUG_PRINTLN("[pixels] Failed to create strand!"); + } else { + _num_strands++; + WS_DEBUG_PRINT("[pixels]: Added strand #"); + WS_DEBUG_PRINTLN(_num_strands); + } // Publish PixelsAdded message to the broker if (!_pixels_model->EncodePixelsAdded(msg_add->pixels_pin_data, did_init)) { @@ -74,13 +79,6 @@ bool PixelsController::Handle_Pixels_Add(pb_istream_t *stream) { return false; } - // Increment the strand counter if initialization was successful - if (did_init) { - _num_strands++; - WS_DEBUG_PRINT("[pixels]: Added strand #"); - WS_DEBUG_PRINTLN(_num_strands); - } - return true; } @@ -102,7 +100,7 @@ bool PixelsController::Handle_Pixels_Write(pb_istream_t *stream) { _pixels_model->GetPixelsWriteMsg(); uint16_t pin_data = atoi(msg_write->pixels_pin_data + 1); uint16_t idx = GetStrandIndex(pin_data); - if (idx == 0xFF) { + if (idx == STRAND_NOT_FOUND) { WS_DEBUG_PRINTLN("[pixels]: Failed to find strand index!"); return false; } @@ -132,7 +130,7 @@ bool PixelsController::Handle_Pixels_Remove(pb_istream_t *stream) { uint16_t pin_data = atoi(msg_remove->pixels_pin_data + 1); uint16_t idx = GetStrandIndex(pin_data); - if (idx == 0xFF) { + if (idx == STRAND_NOT_FOUND) { WS_DEBUG_PRINTLN("[pixels]: Failed to find strand index!"); return false; } @@ -147,7 +145,7 @@ bool PixelsController::Handle_Pixels_Remove(pb_istream_t *stream) { @brief Gets the index of a strand by its data pin @param pin_data The desired data pin - @returns Desired strand index, or 0xFF if not found. + @returns Desired strand index, or STRAND_NOT_FOUND if not found. */ /**************************************************************************/ uint16_t PixelsController::GetStrandIndex(uint16_t pin_data) { @@ -156,7 +154,5 @@ uint16_t PixelsController::GetStrandIndex(uint16_t pin_data) { return i; } } - WS_DEBUG_PRINT("[pixels]: No strand found on pin "); - WS_DEBUG_PRINTLN(pin_data); - return 0xFF; // Sentinel value indicating "not found" + return STRAND_NOT_FOUND; // Sentinel value indicating "not found" } \ No newline at end of file diff --git a/src/components/pixels/controller.h b/src/components/pixels/controller.h index 99bf84157..e4e487cc5 100644 --- a/src/components/pixels/controller.h +++ b/src/components/pixels/controller.h @@ -1,5 +1,5 @@ /*! - * @file controller.h + * @file src/components/pixels/controller.h * * Controller for the pixels API * @@ -18,11 +18,13 @@ #include "hardware.h" #include "model.h" -#define MAX_PIXEL_STRANDS 5 ///< Maximum number of pixel strands connected to a WipperSnapper device +#define MAX_PIXEL_STRANDS \ + 10 ///< Maximum number of pixel strands connected to a WipperSnapper device +#define STRAND_NOT_FOUND 0xFF ///< Strand not found in the array class Wippersnapper_V2; ///< Forward declaration -class PixelsModel; ///< Forward declaration -class PixelsHardware; ///< Forward declaration +class PixelsModel; ///< Forward declaration +class PixelsHardware; ///< Forward declaration /**************************************************************************/ /*! @@ -35,15 +37,16 @@ class PixelsController { public: PixelsController(); ~PixelsController(); - // Called by the cbDecodeBrokerToDevice router function bool Handle_Pixels_Add(pb_istream_t *stream); bool Handle_Pixels_Write(pb_istream_t *stream); bool Handle_Pixels_Remove(pb_istream_t *stream); + private: PixelsModel *_pixels_model = nullptr; ///< Pointer to the model class - PixelsHardware *_pixel_strands[MAX_PIXEL_STRANDS] = {nullptr}; ///< Pointer to the hardware class - uint8_t _num_strands; ///< Number of pixel strands + PixelsHardware *_pixel_strands[MAX_PIXEL_STRANDS] = { + nullptr}; ///< Pointer to the hardware class + uint8_t _num_strands; ///< Number of pixel strands uint16_t GetStrandIndex(uint16_t pin_data); // Returns 0xFF if not found }; -extern Wippersnapper_V2 WsV2; ///< Wippersnapper V2 instance -#endif // WS_PIXELS_CONTROLLER_H \ No newline at end of file +extern Wippersnapper_V2 WsV2; ///< Global V2 instance +#endif // WS_PIXELS_CONTROLLER_H \ No newline at end of file diff --git a/src/components/pixels/hardware.cpp b/src/components/pixels/hardware.cpp index 10bdc91ea..25a9d1b42 100644 --- a/src/components/pixels/hardware.cpp +++ b/src/components/pixels/hardware.cpp @@ -1,7 +1,7 @@ /*! - * @file hardware.cpp + * @file src/components/pixels/hardware.cpp * - * Hardware implementation for pixel strands. + * Hardware interface for NeoPixel/DotStar strands. * * Adafruit invests time and resources providing this open source code, * please support Adafruit and open-source hardware by purchasing @@ -165,13 +165,7 @@ bool PixelsHardware::AddStrand(wippersnapper_pixels_PixelsType type, /**************************************************************************/ void PixelsHardware::FillStrand(uint32_t color) { // Apply gamma correction to match IO Web - WS_DEBUG_PRINT("[pixels] Filling strand with color: "); - WS_DEBUG_PRINTLN(color); - - WS_DEBUG_PRINTLN("Applying gamma correction.."); uint32_t color_gamma = ApplyGammaCorrection(color); - WS_DEBUG_PRINT("[pixels] Filling strand with color_gamma: "); - WS_DEBUG_PRINT(color_gamma); if (_type == wippersnapper_pixels_PixelsType_PIXELS_TYPE_NEOPIXEL) { _neopixel->fill(color_gamma); _neopixel->show(); @@ -192,14 +186,7 @@ void PixelsHardware::FillStrand(uint32_t color) { */ /**************************************************************************/ uint32_t PixelsHardware::ApplyGammaCorrection(uint32_t color) { - WS_DEBUG_PRINT("Type: "); - WS_DEBUG_PRINTLN(_type); if (_type == wippersnapper_pixels_PixelsType_PIXELS_TYPE_NEOPIXEL) { - WS_DEBUG_PRINTLN("Applying gamma to neopixel..."); - if (_neopixel == nullptr) { - WS_DEBUG_PRINTLN("[pixels] No neopixel object found!"); - return color; - } return _neopixel->gamma32(color); } else if (_type == wippersnapper_pixels_PixelsType_PIXELS_TYPE_DOTSTAR) { return _dotstar->gamma32(color); @@ -217,21 +204,31 @@ uint32_t PixelsHardware::ApplyGammaCorrection(uint32_t color) { void PixelsHardware::RemoveStrand() { if (_type == wippersnapper_pixels_PixelsType_PIXELS_TYPE_NEOPIXEL) { if (_neopixel != nullptr) { + _neopixel->clear(); + _neopixel->show(); delete _neopixel; _neopixel = nullptr; } } else if (_type == wippersnapper_pixels_PixelsType_PIXELS_TYPE_DOTSTAR) { if (_dotstar != nullptr) { + _dotstar->clear(); + _dotstar->show(); delete _dotstar; _dotstar = nullptr; } } else { WS_DEBUG_PRINTLN("[pixels] Unknown pixel type!"); } - // Optionally re-init the status pixel for reuse by app. - if (getStatusNeoPixelPin() == _pin_data && !WsV2.lockStatusNeoPixelV2) + if (getStatusNeoPixelPin() == _pin_data && !WsV2.lockStatusNeoPixelV2) { + WS_DEBUG_PRINTLN("[pixels] Re-initializing status pixel"); initStatusLED(); + } + WS_DEBUG_PRINT("[pixels] Removed pixel strand from pin: "); + WS_DEBUG_PRINTLN(_pin_data); + + _pin_data = 0; // Reset the pin data + _type = wippersnapper_pixels_PixelsType_PIXELS_TYPE_UNSPECIFIED; } /**************************************************************************/ diff --git a/src/components/pixels/hardware.h b/src/components/pixels/hardware.h index efabf1c2d..a02e8ee22 100644 --- a/src/components/pixels/hardware.h +++ b/src/components/pixels/hardware.h @@ -1,7 +1,7 @@ /*! - * @file hardware.h + * @file src/components/pixels/hardware.h * - * Hardware interface for pixel strands. + * Hardware interface for NeoPixel/DotStar strands. * * Adafruit invests time and resources providing this open source code, * please support Adafruit and open-source hardware by purchasing @@ -16,23 +16,10 @@ #define WS_PIXELS_HARDWARE_H #include "Wippersnapper_V2.h" -// TODO: Do we need this? -/** - * @struct PixelStrand - * @brief This struct represents a NeoPixel or DotStar strand. - */ -struct PixelStrand { - uint8_t pin_data; ///< Data pin - uint8_t pin_clock; ///< Clock pin (for DotStar) - wippersnapper_pixels_PixelsType type; ///< Pixel type - wippersnapper_pixels_PixelsOrder order; ///< Color ordering - uint32_t num_pixels; ///< Number of pixels - uint32_t brightness; ///< Current brightness (0-255) -}; - /**************************************************************************/ /*! - @brief Interface for interacting with hardware's pixel strands. + @brief Interface for interacting with NeoPixel or Dotstar + pixel strands */ /**************************************************************************/ class PixelsHardware { @@ -48,10 +35,10 @@ class PixelsHardware { void RemoveStrand(); private: - Adafruit_NeoPixel *_neopixel = nullptr; ///< Used for NeoPixel pixel strands - Adafruit_DotStar *_dotstar = nullptr; ///< Used for DotStar pixel strands - wippersnapper_pixels_PixelsType _type; - uint16_t _pin_data; ///< Data pin for the pixel strand + Adafruit_NeoPixel *_neopixel = nullptr; ///< Used for NeoPixel strands + Adafruit_DotStar *_dotstar = nullptr; ///< Used for DotStar strands + wippersnapper_pixels_PixelsType _type; ///< Holds the type of strand + uint16_t _pin_data; ///< Data pin for the strand bool AddNeoPixel(uint16_t num_pixels, uint16_t pin_data, neoPixelType order, uint8_t brightness); bool AddDotStar(uint16_t num_pixels, uint16_t pin_data, uint16_t pin_clock, diff --git a/src/components/pixels/model.cpp b/src/components/pixels/model.cpp index ba2909dc2..2bf870f6f 100644 --- a/src/components/pixels/model.cpp +++ b/src/components/pixels/model.cpp @@ -1,5 +1,5 @@ /*! - * @file model.cpp + * @file src/components/pixels/model.cpp * * Implementation for the pixels.proto message model. * @@ -22,10 +22,11 @@ */ /**************************************************************************/ PixelsModel::PixelsModel() { - _msg_pixels_add = wippersnapper_pixels_PixelsAdd_init_zero; - _msg_pixels_remove = wippersnapper_pixels_PixelsRemove_init_zero; - _msg_pixels_write = wippersnapper_pixels_PixelsWrite_init_zero; - _msg_pixels_added = wippersnapper_pixels_PixelsAdded_init_zero; + memset(&_msg_pixels_add, 0, sizeof(_msg_pixels_add)); + memset(&_msg_pixels_remove, 0, sizeof(_msg_pixels_remove)); + memset(&_msg_pixels_write, 0, sizeof(_msg_pixels_write)); + memset(&_msg_pixels_added, 0, sizeof(_msg_pixels_added)); + // no-op } /**************************************************************************/ @@ -33,7 +34,12 @@ PixelsModel::PixelsModel() { @brief Destructs a PixelsModel object */ /**************************************************************************/ -PixelsModel::~PixelsModel() {} +PixelsModel::~PixelsModel() { + memset(&_msg_pixels_add, 0, sizeof(_msg_pixels_add)); + memset(&_msg_pixels_remove, 0, sizeof(_msg_pixels_remove)); + memset(&_msg_pixels_write, 0, sizeof(_msg_pixels_write)); + memset(&_msg_pixels_added, 0, sizeof(_msg_pixels_added)); +} /**************************************************************************/ /*! @@ -44,7 +50,7 @@ PixelsModel::~PixelsModel() {} */ /**************************************************************************/ bool PixelsModel::DecodePixelsAdd(pb_istream_t *stream) { - _msg_pixels_add = wippersnapper_pixels_PixelsAdd_init_zero; + memset(&_msg_pixels_add, 0, sizeof(_msg_pixels_add)); return pb_decode(stream, wippersnapper_pixels_PixelsAdd_fields, &_msg_pixels_add); } @@ -68,7 +74,7 @@ wippersnapper_pixels_PixelsAdd *PixelsModel::GetPixelsAddMsg() { */ /**************************************************************************/ bool PixelsModel::DecodePixelsRemove(pb_istream_t *stream) { - _msg_pixels_remove = wippersnapper_pixels_PixelsRemove_init_zero; + memset(&_msg_pixels_remove, 0, sizeof(_msg_pixels_remove)); return pb_decode(stream, wippersnapper_pixels_PixelsRemove_fields, &_msg_pixels_remove); } @@ -92,7 +98,7 @@ wippersnapper_pixels_PixelsRemove *PixelsModel::GetPixelsRemoveMsg() { */ /**************************************************************************/ bool PixelsModel::DecodePixelsWrite(pb_istream_t *stream) { - _msg_pixels_write = wippersnapper_pixels_PixelsWrite_init_zero; + memset(&_msg_pixels_write, 0, sizeof(_msg_pixels_write)); WS_DEBUG_PRINTLN("Decoding PixelsWrite message..."); return pb_decode(stream, wippersnapper_pixels_PixelsWrite_fields, &_msg_pixels_write); @@ -120,7 +126,7 @@ wippersnapper_pixels_PixelsWrite *PixelsModel::GetPixelsWriteMsg() { /**************************************************************************/ bool PixelsModel::EncodePixelsAdded(char *pin_data, bool success) { // Fill the message - _msg_pixels_added = wippersnapper_pixels_PixelsAdded_init_zero; + memset(&_msg_pixels_added, 0, sizeof(_msg_pixels_added)); _msg_pixels_added.is_success = success; strncpy(_msg_pixels_added.pixels_pin_data, pin_data, sizeof(_msg_pixels_added.pixels_pin_data)); diff --git a/src/components/pixels/model.h b/src/components/pixels/model.h index f95b5ab44..55cbf5e30 100644 --- a/src/components/pixels/model.h +++ b/src/components/pixels/model.h @@ -1,5 +1,5 @@ /*! - * @file model.h + * @file src/components/pixels/model.h * * Model for the pixels.proto message. * @@ -40,8 +40,7 @@ class PixelsModel { wippersnapper_pixels_PixelsAdded *GetPixelsAddedMsg(); private: - wippersnapper_pixels_PixelsAdd - _msg_pixels_add; ///< PixelsAdd message object + wippersnapper_pixels_PixelsAdd _msg_pixels_add; ///< PixelsAdd message object wippersnapper_pixels_PixelsRemove _msg_pixels_remove; ///< PixelsRemove message object wippersnapper_pixels_PixelsWrite diff --git a/src/components/sensor/model.cpp b/src/components/sensor/model.cpp index 85f1cb3d3..8cc2534b3 100644 --- a/src/components/sensor/model.cpp +++ b/src/components/sensor/model.cpp @@ -1,5 +1,5 @@ /*! - * @file model.cpp + * @file src/components/sensor/model.cpp * * Model for the sensor.proto message. * @@ -20,7 +20,8 @@ */ /***********************************************************************/ SensorModel::SensorModel() { - _msg_sensor_event = wippersnapper_sensor_SensorEvent_init_zero; + memset(&_msg_sensor_event, 0, sizeof(_msg_sensor_event)); + // no-op } /***********************************************************************/ @@ -30,5 +31,5 @@ SensorModel::SensorModel() { /***********************************************************************/ SensorModel::~SensorModel() { // Zero-out the SensorEvent message - _msg_sensor_event = wippersnapper_sensor_SensorEvent_init_zero; + memset(&_msg_sensor_event, 0, sizeof(_msg_sensor_event)); } \ No newline at end of file diff --git a/src/components/sensor/model.h b/src/components/sensor/model.h index aa014c48c..c9b9950a0 100644 --- a/src/components/sensor/model.h +++ b/src/components/sensor/model.h @@ -1,5 +1,5 @@ /*! - * @file model.h + * @file src/components/sensor/model.h * * Model for the sensor.proto message. * diff --git a/src/display/ws_display_driver.h b/src/display/ws_display_driver.h index 80f149df7..b0b8f483f 100644 --- a/src/display/ws_display_driver.h +++ b/src/display/ws_display_driver.h @@ -15,7 +15,7 @@ #ifndef WIPPERSNAPPER_DISPLAY_H #define WIPPERSNAPPER_DISPLAY_H -#include "Wippersnapper.h" +#include "Wippersnapper_V2.h" #include "provisioning/Config.h" #include // Always include this BEFORE lvgl.h! #include @@ -23,7 +23,7 @@ LV_FONT_DECLARE(errorTriangle); ///< Error triangle symbol/font -class Wippersnapper; // fwd decl +class Wippersnapper_V2; // fwd decl /***************************************************************************/ /*! @@ -51,6 +51,6 @@ class ws_display_driver { uint8_t _displayRotationMode; ///< Display rotation (mode, not number in degrees) }; -extern Wippersnapper WS; ///< Global Wippersnapper instance +extern Wippersnapper_V2 WsV2; ///< Global Wippersnapper instance #endif // WIPPERSNAPPER_DISPLAY_H \ No newline at end of file diff --git a/src/display/ws_display_ui_helper.cpp b/src/display/ws_display_ui_helper.cpp index bfc9fc11b..bd661e013 100644 --- a/src/display/ws_display_ui_helper.cpp +++ b/src/display/ws_display_ui_helper.cpp @@ -404,9 +404,9 @@ void ws_display_ui_helper::build_scr_monitor() { /**************************************************************************/ void ws_display_ui_helper::add_text_to_terminal(const char *text) { Serial.println("add_text_to_terminal"); - char txtBuffer[256]; // temporary text buffer for snprintf - snprintf(txtBuffer, 256, text); - addToTerminal(txtBuffer); + /* char txtBuffer[256]; // temporary text buffer for snprintf + snprintf(txtBuffer, 256, text); + addToTerminal(txtBuffer); */ } /**************************************************************************/ diff --git a/src/display/ws_display_ui_helper.h b/src/display/ws_display_ui_helper.h index 909d6c73a..a10a458a1 100644 --- a/src/display/ws_display_ui_helper.h +++ b/src/display/ws_display_ui_helper.h @@ -16,7 +16,7 @@ #ifndef WS_DISPLAY_UI_HELPER_H #define WS_DISPLAY_UI_HELPER_H -#include "Wippersnapper.h" +#include "Wippersnapper_V2.h" #include "ws_display_driver.h" #include "ws_display_tooltips.h" #include diff --git a/src/helpers/ws_helper_macros.h b/src/helpers/ws_helper_macros.h index e82393a28..10493766f 100644 --- a/src/helpers/ws_helper_macros.h +++ b/src/helpers/ws_helper_macros.h @@ -25,7 +25,7 @@ while (millis() - start < timeout) { \ delay(10); \ yield(); \ - feedWDT(); \ + WsV2.feedWDTV2(); \ if (millis() < start) { \ start = millis(); /* if rollover */ \ } \ @@ -51,12 +51,12 @@ The arguments to pass to the function. */ /**************************************************************************/ -#define RETRY_FUNCTION_UNTIL_TIMEOUT(func, result_type, result_var, condition, \ - timeout, interval, ...) \ +#define RETRY_FUNCTION_UNTIL_TIMEOUT(func, result_var, condition, timeout, \ + interval, ...) \ { \ unsigned long startTime = millis(); \ while (millis() - startTime < timeout) { \ - result_type result_var = func(__VA_ARGS__); \ + result_var = func(__VA_ARGS__); \ if (condition(result_var)) { \ break; \ } \ diff --git a/src/provisioning/littlefs/WipperSnapper_LittleFS.cpp b/src/provisioning/littlefs/WipperSnapper_LittleFS.cpp index 697614180..5ca54edb5 100644 --- a/src/provisioning/littlefs/WipperSnapper_LittleFS.cpp +++ b/src/provisioning/littlefs/WipperSnapper_LittleFS.cpp @@ -18,7 +18,7 @@ defined(ARDUINO_ADAFRUIT_FEATHER_ESP32_V2) || \ defined(ARDUINO_ADAFRUIT_QTPY_ESP32_PICO) || \ defined(ARDUINO_ADAFRUIT_QTPY_ESP32C3) || defined(ARDUINO_ESP32_DEV) || \ - defined(ESP32_DEV) + defined(ESP32_DEV) || defined(ARDUINO_ADAFRUIT_FEATHER_ESP32C6) #include "WipperSnapper_LittleFS.h" /**************************************************************************/ @@ -162,7 +162,11 @@ void WipperSnapper_LittleFS::fsHalt(String msg, ws_led_status_t status_state) { /**************************************************************************/ void WipperSnapper_LittleFS::GetSDCSPin() { // Attempt to open and deserialize the config.json file +#if defined(ARDUINO_ESP8266_ADAFRUIT_HUZZAH) + File file_cfg = LittleFS.open("/config.json", "r"); +#else File file_cfg = LittleFS.open("/config.json"); +#endif if (!file_cfg) WsV2.pin_sd_cs = 255; diff --git a/src/provisioning/sdcard/ws_sdcard.cpp b/src/provisioning/sdcard/ws_sdcard.cpp index 14b945a05..77ad66d62 100644 --- a/src/provisioning/sdcard/ws_sdcard.cpp +++ b/src/provisioning/sdcard/ws_sdcard.cpp @@ -90,11 +90,15 @@ void ws_sdcard::calculateFileLimits() { bool ws_sdcard::InitDS1307() { _rtc_ds1307 = new RTC_DS1307(); if (!_rtc_ds1307->begin()) { +#if !defined(ARDUINO_ARCH_ESP8266) && !defined(ARDUINO_ARCH_SAMD) && \ + !defined(ARDUINO_ADAFRUIT_FEATHER_ESP32C6) && \ + !defined(ARDUINO_ADAFRUIT_QTPY_ESP32C3) if (!_rtc_ds1307->begin(&Wire1)) { WS_DEBUG_PRINTLN("[SD] Runtime Error: Failed to initialize DS1307 RTC"); delete _rtc_ds1307; return false; } +#endif } if (!_rtc_ds1307->isrunning()) _rtc_ds1307->adjust(DateTime(F(__DATE__), F(__TIME__))); @@ -112,11 +116,15 @@ bool ws_sdcard::InitDS3231() { WS_DEBUG_PRINTLN("Begin DS3231 init"); _rtc_ds3231 = new RTC_DS3231(); if (!_rtc_ds3231->begin(&Wire)) { +#if !defined(ARDUINO_ARCH_ESP8266) && !defined(ARDUINO_ARCH_SAMD) && \ + !defined(ARDUINO_ADAFRUIT_FEATHER_ESP32C6) && \ + !defined(ARDUINO_ADAFRUIT_QTPY_ESP32C3) if (!_rtc_ds3231->begin(&Wire1)) { WS_DEBUG_PRINTLN("[SD] Runtime Error: Failed to initialize DS3231 RTC"); delete _rtc_ds3231; return false; } +#endif } if (_rtc_ds3231->lostPower()) _rtc_ds3231->adjust(DateTime(F(__DATE__), F(__TIME__))); @@ -135,12 +143,16 @@ bool ws_sdcard::InitPCF8523() { if (!_rtc_pcf8523->begin(&Wire)) { WS_DEBUG_PRINTLN( "[SD] Runtime Error: Failed to initialize PCF8523 RTC on WIRE"); +#if !defined(ARDUINO_ARCH_ESP8266) && !defined(ARDUINO_ARCH_SAMD) && \ + !defined(ARDUINO_ADAFRUIT_FEATHER_ESP32C6) && \ + !defined(ARDUINO_ADAFRUIT_QTPY_ESP32C3) if (!_rtc_pcf8523->begin(&Wire1)) { WS_DEBUG_PRINTLN( "[SD] Runtime Error: Failed to initialize PCF8523 RTC on WIRE1"); delete _rtc_pcf8523; return false; } +#endif } if (!_rtc_pcf8523->initialized() || _rtc_pcf8523->lostPower()) { _rtc_pcf8523->adjust(DateTime(F(__DATE__), F(__TIME__))); diff --git a/src/provisioning/tinyusb/Wippersnapper_FS.cpp b/src/provisioning/tinyusb/Wippersnapper_FS.cpp index 03bb68b90..6cd3dd39e 100644 --- a/src/provisioning/tinyusb/Wippersnapper_FS.cpp +++ b/src/provisioning/tinyusb/Wippersnapper_FS.cpp @@ -30,7 +30,8 @@ defined(ARDUINO_RASPBERRY_PI_PICO) || \ defined(ARDUINO_RASPBERRY_PI_PICO_2) || \ defined(ARDUINO_ADAFRUIT_FEATHER_RP2040_ADALOGGER) || \ - defined(ARDUINO_ADAFRUIT_METRO_RP2350) + defined(ARDUINO_ADAFRUIT_METRO_RP2350) || \ + defined(ARDUINO_RASPBERRY_PI_PICO_2W) #include "Wippersnapper_FS.h" // On-board external flash (QSPI or SPI) macros should already // defined in your board variant if supported @@ -148,7 +149,7 @@ Wippersnapper_FS::Wippersnapper_FS() { writeToBootOut( "Please edit the secrets.json file. Then, reset your board.\n"); #ifdef USE_DISPLAY - WsV2._ui_helper->show_scr_error( + WsV2._ui_helperV2->show_scr_error( "INVALID SETTINGS FILE", "The settings.json file on the WIPPER drive contains default values. " "Please edit it to reflect your Adafruit IO and network credentials. " @@ -472,7 +473,7 @@ void Wippersnapper_FS::parseSecrets() { "ERROR: Invalid IO credentials in secrets.json! TO FIX: Please change " "io_username and io_key to match your Adafruit IO credentials!\n"); #ifdef USE_DISPLAY - WsV2._ui_helper->show_scr_error( + WsV2._ui_helperV2->show_scr_error( "INVALID IO CREDS", "The \"io_username/io_key\" fields within secrets.json are invalid, " "please " @@ -489,7 +490,7 @@ void Wippersnapper_FS::parseSecrets() { "FIX: Please change network_ssid and network_password to " "match your Adafruit IO credentials!\n"); #ifdef USE_DISPLAY - WsV2._ui_helper->show_scr_error( + WsV2._ui_helperV2->show_scr_error( "INVALID NETWORK", "The \"network_ssid and network_password\" fields within secrets.json " "are invalid, please change it to match your WiFi credentials. Then, " diff --git a/src/ws_adapters.h b/src/ws_adapters.h index 72bba5072..6d8f899f6 100644 --- a/src/ws_adapters.h +++ b/src/ws_adapters.h @@ -33,7 +33,8 @@ typedef ws_wifi_esp8266 ws_adapter_wifi; #include "adapters/wifi/ws_wifi_esp32.h" typedef ws_wifi_esp32 ws_adapter_wifi; // Networking adapters for Raspberry Pi Pico W-series -#elif defined(ARDUINO_RASPBERRY_PI_PICO_W) +#elif defined(ARDUINO_RASPBERRY_PI_PICO_W) || \ + defined(ARDUINO_RASPBERRY_PI_PICO_2W) #include "adapters/wifi/ws_wifi_pico.h" typedef ws_wifi_pico ws_adapter_wifi; // Networking adapter for Arduino Nano 33 IoT and MKR WiFi 1010 diff --git a/tests/bin/offline/firmware.elf b/tests/bin/offline/firmware.elf index 21c458943..16e90150a 100755 Binary files a/tests/bin/offline/firmware.elf and b/tests/bin/offline/firmware.elf differ