Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add GPIO Support to CustomReset (ESPTOOL-974) #1042

Closed
Rio6 opened this issue Dec 16, 2024 · 5 comments
Closed

Add GPIO Support to CustomReset (ESPTOOL-974) #1042

Rio6 opened this issue Dec 16, 2024 · 5 comments

Comments

@Rio6
Copy link

Rio6 commented Dec 16, 2024

Is your feature request related to a problem?

I currently have a ESP32 board using FT260 for USB communication. With driver from https://github.com/MichaelZaidman/hid-ft260, I am able to flash the chip by manual reset. However the driver does not implement ioctl calls that sets/clears DTR and RTS, and it will require some hacks to get it to work (see MichaelZaidman/hid-ft260#27). The driver does provide a gpio interface, which can be used instead of DTR/RTS hack for automatic reset to work.

Describe the solution you'd like

Extend CustomReset interface to support toggling reset lines with gpiod. This makes it easy to connect any gpio lines to ESP32 bootstrap pins without relying on the RTS/DTR behavriour of the kernel/driver. On top of enabling automatic reset via FT260, it can be potentially used by other embedded Linux platform with GPIO.

Currently I have this wrapper for esptool to replace ioctl calls with gpiod, and I'm able to get automatic reset to work with it

#!/usr/bin/env python3
# Workaround for https://github.com/MichaelZaidman/hid-ft260/issues/27
import os.path
import sys
import gpiod
sys.path.append(os.path.join(sys.argv.pop(1), 'tool-esptoolpy'))
import esptool

esptool.reset.ResetStrategy.gpiopath = '/dev/gpiochip0'
esptool.reset.ResetStrategy.RTS = 7
esptool.reset.ResetStrategy.DTR = 11

def setDTR(self, state):
    import gpiod
    with gpiod.request_lines(self.gpiopath, { self.DTR: self.line_settings }) as req:
        req.set_value(self.DTR, gpiod.line.Value(state))

def setRTS(self, state):
    import gpiod
    with gpiod.request_lines(self.gpiopath, { self.RTS: self.line_settings }) as req:
        req.set_value(self.RTS, gpiod.line.Value(state))

def setDTRandRTS(self, dtr=False, rts=False):
    import gpiod
    with gpiod.request_lines(self.gpiopath, {
        self.DTR: self.line_settings,
        self.RTS: self.line_settings,
    }) as req:
        req.set_values({
            self.DTR: gpiod.line.Value(dtr),
            self.RTS: gpiod.line.Value(rts),
        })

esptool.reset.ResetStrategy.line_settings          = gpiod.LineSettings(direction=gpiod.line.Direction.OUTPUT, active_low=True)
esptool.reset.ResetStrategy._setDTR.__code__       = setDTR.__code__
esptool.reset.ResetStrategy._setRTS.__code__       = setRTS.__code__
esptool.reset.ResetStrategy._setDTRandRTS.__code__ = setDTRandRTS.__code__

esptool._main()

Describe alternatives you've considered

Alternative is to implement RTS/DTR ioctl calls in the driver MichaelZaidman/hid-ft260#27. But since the hardware does not have support for setting the pins directly without switching flow control mode, it can make the firmware hacky and messy. Since it was a hack to abuse DTR and RTS in the first place for esptool, it may as well support a more straight forward GPIO interface.

Additional context

No response

@github-actions github-actions bot changed the title Add GPIO Support to CustomReset Add GPIO Support to CustomReset (ESPTOOL-974) Dec 16, 2024
@radimkarnis
Copy link
Collaborator

Hi @Rio6,

Thank you for the detailed feature request! It’s definitely an interesting idea worth considering. I wanted to follow up with your thoughts, though:

It was a hack to abuse DTR and RTS in the first place for esptool.

You’re right—it could be seen as a hack. However, it’s also the cheapest and simplest solution, requiring no additional hardware (since most USB bridges already have the necessary flow control lines). While it has its challenges (e.g., timing constraints or edge cases like the one you mentioned), it still works effectively in 99% of scenarios.

Esptool aims to support the widest variety of hardware configurations—essentially that 99%. However, we do have to balance that against complexity. I’m not sure if reworking the reset strategies would justify the added maintenance overhead for what seems to be a very niche use case.

For edge cases like these, implementing a wrapper or customizing the code (as you’ve done) is often the quicker, more practical solution.

Reset strategies are already quite complex to maintain—handling different timings for USB and UART modes, addressing OS/driver-specific quirks, and supporting various USB-OTG and USB-Serial/JTAG scenarios. Adding another layer of complexity risks overbloating esptool.

Do you believe this feature could benefit a broader audience beyond a small group of developers with niche requirements?

Thanks!

@Rio6
Copy link
Author

Rio6 commented Dec 16, 2024

I agree with you that this is a niche use case for the extra maintanance. I was hoping to leverage the existing code in CustomReset to minimize the code change. This way reset sequence can be used like G0,7,1|W0.5|G0,7,0 to toggle /dev/gpiochip0 line 7. And we can see from the wrapper above it doesn't take that much code to add gpiod support.

But it seems like I am the only one with this use case, and I already got a solution using wrapper. So as of now there really isn't a strong push for this feature. We can see if in the future there'll be more people with this need.

@radimkarnis
Copy link
Collaborator

If more similar feature requests come in, we will reconsider this. In the meantime, I will close this ticket.

Thanks for understanding and for your time!

@dhruvampWork
Copy link

Hello @Rio6, thank you for providing such a solution.
I am working on a similar project. We have FT260 connected to ESP32 on UART bus, and working to convert it from HID to USB-UART to program ESP32. Here is the snapshot of the circuit schematic.

Image

Could you please guide me on how can I apply your solution if that works for the attached schematic?
Any help will be appreciated.

@Rio6
Copy link
Author

Rio6 commented Feb 27, 2025

Hello @Rio6, thank you for providing such a solution. I am working on a similar project. We have FT260 connected to ESP32 on UART bus, and working to convert it from HID to USB-UART to program ESP32. Here is the snapshot of the circuit schematic.

Image

Could you please guide me on how can I apply your solution if that works for the attached schematic? Any help will be appreciated.

I'm using this driver https://github.com/MichaelZaidman/hid-ft260, which you'll have to build yourself. Assuming you follow the same connection as this reference design (looks like it is, although your C27 might be too small), then you should be able to run my wrapper the same way you would use esptool.py.

For me using that driver, the FT-260 appears as /dev/ttyFT0 and /dev/gpiochip0, just update the script if it is something else for you.

Hope this helps

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants