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

Open
Rio6 opened this issue Dec 16, 2024 · 2 comments
Open

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

Rio6 opened this issue Dec 16, 2024 · 2 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.

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

2 participants