Xiao ESP32S3 Plus boot issue

I’m still working on my copy stand motor drive project. For various reasons I’ve upgraded from the original -C6 to an -S3 and now to the -S3 Plus. In the end I needed more GPIO pins than either the -C6 or -S3 offered, so -S3 Plus it is. My system uses a stepper motor to drive the copy stand traveler (that holds the camera) via an acme screw. I’m using a TMC2209 stepper driver chip which has stall detection that can be used for limit-switch-less homing.

The -S3 Plus can be powered by any of the following:

  1. USB-C

  2. 5V pin (Pin 14) via Schottky diode (anode to external 5V source, cathode to 5V pin)

  3. Battery pads on the underside of the board

For this project I’m using #1 for code development, while #2 is to be used for the final device. The 5V source for this is a 24V - 5V buck converter. (The motor power is 24VDC.)

While I’m still fine tuning the code, basically everything works…as long as I power first the -S3 Plus and then the 24VDC. The net of this is that the board is running on USB-C sourced power, not the buck converter. This allows me to do development of the code and have the serial interface for testing purposes. (Once the project is done, there will be no UI other than various buttons to control the motor operation.)

The issue I’m experiencing is when attempting to only power the device from 24V. In this case, the buck converter supplies 5V to the -S3 Plus board, the red charging LED on the board light up for about 45 seconds, and then nothing else happens. Unlike when I power the board via USB-C, when powered solely by 24V (with the -S3 Plus board powered via the buck converter), device doesn’t respond to any button presses. (There is nothing in my code that should cause this to happen.)

Interestingly however, if I power the device initially with USB-C, then add the 24V power, start using the device, and then remove USB-C, the device continues to work as expected! This leads me to think that the issue may be a boot problem. Two possibilities come to mind. a) there is something funky happening with the board boot up sequence that doesn’t like being powered by 5V (I experienced a similar issue with an Arduino Nano Matter board last year, but that was a community preview board that was being sold as full production - a long an frustrating story, the fault of which lies almost entirely with Arduino). Or b) the strapping pins are being mucked with such that the board is booting in a different mode. I have my sights primarily on b) because it seems more likely (with a caveat), and honestly it is more in my control (I know wanting something to be doesn’t make it so!).

From Espressif ESP32-S3 Series Datasheet

Table 2-11. Chip Boot Mode Control

Boot Mode GPIO0 GPIO46
Default Configuration 1 (Pull-up) 0 (Pull-down)
SPI Boot (default) 1 Any Value
Download Boot 0 0
Invalid combination* 0 1

*This combination triggers unexpected behavior and should be avoided.

The caveat is that nowhere have I found anywhere that GPIO0 and/or GPIO46 are exposed on the -S3 Plus board! This seems very odd to me because Seeed goes through the trouble of including a section about the strapping pins in their Getting Started wiki page. (Why do that if these pins aren’t exposed?)

I am using D0 (which is marked as GPIO1 on the same wiki page) as an output to the DIR pin on The TMC2209, which in turn has an internal pull-down resistor. So if GPIO0 is actually D0, then I might have my smoking gun that could explain the issue I’m seeing. But I’d prefer to not have to modify my board on the long shot that the Seeed wiki is wrong about which GPIO D0 actually is. (FWIW, Seeed’s KiCAD library part for the board also shows D0 as being GPIO1, and GPIO0 is not shown at all.)

Seeed also lists GPIO3 as a strapping pin, in this case for JTAG signal source. I have that pin connected to the Enable (ENN) pin of the TMC2209. Trinamic says this about this pin: “Enable not input. The power stage becomes switched off (all motor outputs floating) when this pin becomes driven to a high level.” Not sure if/how that might result in erroneously triggering the JTAG interface, but …?

If I figure out where to upload my schematic for review, I will, but as of now I’ve not found a way to do that.

I’ll have a look at this today as I have a similar project, viz 24V->5V buck into 5V pin…

1 Like

Have you made any headway with this? (I’ve been focused on other parts of my project, so haven’t looked at this for awhile now…)

I have noticed some similar traits with my “self powered” dev system here (I don’t use 5V input? on Pin 14).

When running on battery, the USB (Serial/JTAG) interface doesn’t automatically “recover” when USB is reattached.

I’m trying to determine the cause of the issue.

I’ve found that too. Since USB-C can be used to send power or receive power, there is logic to figure out what needs to be done. If you plug in the (powered) USB-C connector first, it knows to receive power. However if the device is already receiving power (from the battery input or from the 5V input), then it will no longer look for power on the USB-C connector. It seems when that happens, it also decides that it shouldn’t talk on that connector either. It’s annoying, but in my application not a big deal. I can just unplug the 24V power, plug in USB-C, and then plug in the 24V again.

The issue I’m having is the inability to get the XIAO to function at all when only powered by 24V (though it works fine if USB-C was used to get it going, and subsequently removed. I could do this, and it would work, but it’s definitely not what I want.

@PJ_Glasso, might you have any ideas for us? (You were very helpful with the previous issues I was experiencing…)

I don’t really have that issue. My device works normally but in some cases the USB isn’t recognised (Windows) if plugged in while the system is powered by battery.

1 Like

Hi there,

I would suspect in the code Setup do you have the “while Serial!”
statement? comment that out and try the tests again, even better use the code tags above “</>” and paste it in there. the setup portion only if it is proprietary, we can have a look.

HTH
GL :slight_smile: PJ :v:

You’re close you’ll get it sorted. :+1:

2 Likes

Close indeed… You were (of course) right! That was the issue. Duh. I was stuck on possible hardware causes. :confused: :persevere:

I’ll edit the original post and (if possible) add RESOLVED to the title.

Thank you!

1 Like

Awesome… :+1:

Good description helped figure it out , so we got you.
Its good stuff man so keep it rolling. :v:

1 Like

Thanks. Now I just need to figure out how to be able to read the DIAG bit in the TMC2209 so I don’t need to use up a precious GPIO to read it in hardware… The TMC2209 library for some odd reason doesn’t expose that bit even though the code exists (privately) in the code base. :confused:

Hi there,

Yea, that is a PITA in LIBs i see it now and then, Look for an near alternative, even a sparkfun or Adafruit or a manufactures competitor, also the versions sometimes older BSP have the hook and then the new ones drop it because it wasn’t used often… Yea looking under the hood for stuff now… LOL :grin: :+1:

You want to poll it for some error or status? Stepper driver ,
You read the uart instead of an INT pin.
I asked the AI too.

What actually works (no extra pin)

  • Read IOIN.DIAG over UART.
    The IOIN register mirrors the current logic level of the DIAG pin internally. Poll it on a timer and you’ve effectively “read DIAG” without wiring it to the MCU.
  • (Better) Read the detailed status bits over UART.
    Use DRV_STATUS (and friends like GSTAT, SG_RESULT) to check for the exact conditions you care about (stall, OT/OTPW, short, standstill, etc.). Many people wire DIAG only to catch “something’s wrong”; reading DRV_STATUS tells you what and avoids false positives.

Hmm, ??

HTH
GL :slight_smile: PJ :v:

I want to use it to access the stallguard status (i.e., is the motor stalled). It’s a feature of the TMC2209 that allows for limit-switch-less homing. There’s a s/w version of the stallguard result, but it is…odd. Anyway, I’m hoping to avoid recreating the s/w stack needed to access the UART since I literally have everything else coded and more or less done (refinement aside). I may just throw in the towel and hook up the hardware (I do have the extra pins, but I’m into the funky half pins that are a PITA to solder to (I’m using pin headers so as to allow microcontroller replacement if needed), and things are getting tight inside my housing!)

Imma gonna experiment with creating a library branch - just to test, of course :wink:

The code branch was trivial, but the test suggests why DIAG isn’t exposed: it seems that the register value is not latched when triggered and the pulse is too fast to reliably be captured in s/w. Oh well. Guess I’m opening up the enclosure tomorrow. :grimacing:

1 Like