Restore GPIO46 after board detection on boards that expose it to the application - #345
Merged
Merged
Conversation
…application begin() drives GPIO46 high as the power hold pin before the board is known (Capsule / Dial / DinMeter power off otherwise) and left it as an output on every board. On CoreS3 GPIO46 is the camera VSYNC, so an esp_camera_init() done before M5.begin() stopped delivering frames (frame timeout while the sensor stayed readable over I2C). Back up the pad before asserting and restore it once the board is positively identified as one that exposes GPIO46 to the application: CoreS3 / CoreS3SE / StackChan (camera VSYNC), AtomS3R Cam (camera data), AtomS3R Ext / StampS3 / StampS3Bat (header pin). Every other case keeps the previous behaviour on purpose: the power hold boards must stay asserted, StopWatch / ChainCaptain / PaperS3 / PaperDIY have Display.init() configure GPIO46 as a display bus pin after the backup was taken (an unconditional restore would undo that), and a board resolved through cfg.fallback_board is not restored because the physical board may still be one that needs the hold. Cardputer / PaperMono use GPIO46 as the mic data line, which M5Unified itself reconfigures, so they are left as is. The pin is still driven high for the duration of board detection; the change makes the interference finite instead of permanent, it does not remove it. Verified on CoreS3 (ESP-IDF 5.5.1, esp32-camera 2.1.7): camera first then M5.begin() and M5.begin() first then camera (sccb_i2c_port = In_I2C port) both stream frames while the PMIC is read over the shared bus.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
On ESP32-S3,
M5.begin()drives GPIO46 high as an output before the board is known, because Capsule / Dial / DinMeter use it as the power hold pin and would power off otherwise. The pin was left as an output on every board afterwards.On CoreS3 GPIO46 is the camera VSYNC. When
esp_camera_init()is called beforeM5.begin()(a legitimate order now that the I2C bus is shared with an already openedi2c_masterbus), the camera stops delivering frames afterM5.begin():cam_hal: Failed to get frame: timeout, while the sensor stays readable over I2C. Returning GPIO46 to an input makes frames flow again, which pins the cause to the driven output.Change
Back up the pad state before asserting the hold, and restore it once the board is positively identified as one that exposes GPIO46 to the application:
Every other case keeps the previous behaviour on purpose:
Display.init()configure GPIO46 as a display bus pin after the backup was taken, so an unconditional restore would undo that;cfg.fallback_boardis not restored, because the physical board may still be one that needs the hold;The pin is still driven high for the duration of board detection; this makes the interference finite instead of permanent, it does not remove it.
Verification
CoreS3 (GC0308), ESP-IDF 5.5.1, esp32-camera 2.1.7, QVGA RGB565 in DRAM:
esp_camera_init()(own bus on GPIO12/11) →M5.begin(): before the change frames time out afterM5.begin(); after the change frames keep streaming, and reading the PMIC throughM5.In_I2Con the bus opened by esp32-camera works.M5.begin()→esp_camera_init()withpin_sccb_sda = -1andsccb_i2c_port = M5.In_I2C.getPort(): unchanged, frames stream and the PMIC is read on the shared bus.Related: #163.