Maintain power on RAK boards 3V3_S rail for displays and WisBlock add-ons#2215
Maintain power on RAK boards 3V3_S rail for displays and WisBlock add-ons#2215benders wants to merge 3 commits intomeshcore-dev:devfrom
Conversation
The 3V3_S switched peripheral rail (controlled by WB_IO2 / pin 34) was being disabled after board.begin() set it HIGH, by two code paths: - ArduinoSerialInterface::begin() called pinMode(WB_IO2, OUTPUT) without a following digitalWrite(HIGH), resetting the pin to LOW on nRF52. - EnvironmentSensorManager::rakGPSInit() probed WB_IO2 for GPS and left the pin as INPUT on failure, killing the rail and preventing subsequent GPS probes on other sockets (WB_IO4/WB_IO5) from succeeding since those modules are also powered by 3V3_S. Changes: - Enable 3V3_S rail in RAK4631Board::begin() before I2C peripheral probing - Remove misplaced WB_IO2 pinMode from ArduinoSerialInterface (commit 27aa7a7) - Restore WB_IO2 OUTPUT/HIGH after GPS probe in rakGPSInit() Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Two issues caused the SSD1306 to go blank: - RAK4631Board::begin() enabled 3V3_S after Wire.begin(), so after a hard reset the I2C bus initialized without pull-ups (powered by 3V3_S), leaving SDA stuck low. Move 3V3_S enable before Wire.begin() with a short stabilization delay. - The GPS probe in rakGPSInit() power-cycles 3V3_S via WB_IO2, wiping the SSD1306 register state. Re-init the display after sensors.begin() before starting the UI task. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
FYI, I have found a similar issue with the RAK12035 sensor. I've recently submitted a PR with a new sensor driver. If I unplugged the sensor, it would boot but if the sensor was plugged in it would hang (very similar to your issue). I verified that the MeshCore firmware was running by turning on the Blue and Green LEDs in initVariant(), they did turn on, so I knew it was getting that far but the MeshCore firmware was then going to the bootloader for some reason (I haven't tracked down where that is happening yet, it's difficult to debug with no debug statements, serial hasn't been turned on yet). I turned on the 3v3_S here and it worked much better, but it still hung but only with a cold power on. If I booted the board without the sensor and then plugged in the sensor it worked (I suspect that this would also work for you). I tracked this down to the MeshCore firmware which does not "directly" initialize the 3v3_S supply for the sensor boards anywhere. I looked at the Meshtastic code and it turns on 3v3_S early in the boot process. As, I mentioned I also added code to initVariant() to turn on 3v3_S and it worked much better. The issue was ultimately traced to the gps_Is_Awake() routine which turned on the power (via pinMode(ioPin,OUTPUT); and digitalWrite(ioPin,HIGH);) for the different GPS sensors (via IO2, IO4 & IO5), however if the GPS was not found, it changed the pin to an INPUT from an OUTPUT which will tristate the driver and leaves the pin floating (not driven). I also found that subsequent digitalWrite(), digitalToggle() do not work since it is no longer and OUTPUT (as expected, duh), but for some reason the signal does remain at the last written state before it is changed to an INPUT. I am still debugging this, but I believe the charge on the gate of the FET is still leaving the 3v3_S on (I need to figure out how to put a pulldown on IO2 to verify that it is not being driven correctly and will not keep the power on, could you test this?). So, the detection of the various GPS sensors "inadvertently" was turning on the power for all the sensor add-in boards in MeshCore (not a good design). I agree that turning this on early is the proper thing to do. However, any fix should also consider the other RAK boards (RAK19007/10, RAK19003/9 and RAK19001/11, I've only looked at the 19007 schematics). For my sensor on the RAK19007, IO4 is *reset signal for the sensor, so it requires IO4 to be set HIGH (not be in reset) and remain an OUTPUT. So, I believe that all three supplies should be explicitly turned on. I believe a delay of ??mS might be needed to allow the power rail to stabilize (the GPS code used 500mS which seems way too long). With the supplies now being on, the code in gpsIsAwake() that turns the power off for 500mS, turns it on and waits 500mS is not needed (this is the inadvertent power turn on) and the code that changes it to an INPUT should also be removed. The GPS will always be powered and can be directly accesses to determine its presence and gather the location data. But there is a bigger issue: I do believe that turning power on early is the proper thing to do and then the coordination mechansim can be added later. (for my sensor code I already have a routine to put the sensor to sleep and to reset it when it comes back up, so I'm ready for whatever future power management looks like. I would recommend that you close your PR and open a Discussion or Issue to determine the full fix and then submit a PR. I would be happy to participate in the discussion and provide whatever new information I gather (I'm right in the middle of this with my scope and test code, I toggle IO4 to "mark" the code on the scope). |
|
Howdy @KPrivitt . Happy to close this and move discussion to an Issue. Opened #2222 As a note, I did check the other schematics and confirm that IO2 also controls the 3V3_S rail on the 19001 and 19003. And I also ran into the issue that I suspected of being related to something (like a FET) hanging on when testing the physical RST button. In an earlier version I had put a 5ms delay after bringing the pin up before starting the probe that seemed to fix it. But I ditched that when updating the code to as closely as possible match the RAK3401 variant. But that version might just be racing the clock and getting lucky.... |
|
I also just verified that all three boards used IO2 to control the 3v3_S and the IO4 and IO5 are the *reset signal pin for those particular boards (and IO4 is the *reset on my sensor). My feeling is that initVariant() should be modified to add setting IO2, IO4 and IO5 as an output then driving then all HIGH then a 10mS delay. The 3v3_S voltage will stabilize sub-millisecond, but sensors may need a start-up delay before they are accessed (which is what the 10mS is for, my sensor only needs 2000nS). Then EnvironmentSensorManager.cpp needs to be updated to remove the GPS power sequencing (3v3_S will already on, from above, and stable and the *reset will have been deactivated. This allows the GPS to start up early on. But most important is to NOT turn IO2, IO4 and IO5 off (do not make them an INPUT). I looked at the ZOE-M8Q datasheet and could not find a spec on how long it takes to initialize, but I did find a reset minimum of 10mS to detect the reset. The current code is delaying the startup of MeshCore by 3 seconds for really no reason (the three sets if 500mS LOW, the HIGH and a 500mS delay). For my particular issue the cold power on lockup, I suspect that having the extra sensor load (plugging it in) is causing a droop in the main power voltage after is the first applied. 3v3_S is initially 0V, and when it is first turned on with the extra load it causes VDD to droop and that is detected as a "almost dead" battery so, it powers down, which is a recent addition at 1.14.0, I think... I see you created Issue #2222 to discuss this bug (it truly is a bug) to discuss the above proposed fix, but to also plan for a future sensor power manager. Does your OLED display need initialization? I believe it does |
Howdy all,
This is a fix to the OLED issue on the RAK 4631 reported in #1874 . It attempts to follow the solution used on the RAK3401, and to clean-up what appear to be some scattered previous attempts. Without the fix, the board would hang when it attempted to probe the unpowered OLED module over I2C.
The root hardware issue is that RAK re-uses the WB_IO2 pin both as an odd GPIO pin and as the control for the 3V3_S power rail for WisBlock modules. So unless that pin is set as OUTPUT and HIGH, modules are unpowered. This was an issue both at initial startup, and after GNSS probing, because that pin is toggled during probing for GNSS on SLOT_A or SLOT_B.
This proposed fix is relatively minimal: Power up that rail early (during
initVariant()), make sure it gets put back HIGH duringrakGPSInit(), and re-initialize the display (if present) during display setup, since it will have been killed by therakGPSInit()process.A bigger fix around how the GPS/GNSS probing is done might be cleaner. As well as rationalizing the differences between RAK4631 and RAK3401. But I was going for minimal in this pass and I don't have that other hardware to test with (yet...).
Caveats: