ESP32 timers - Page 1
Forum section: electronics / general

author: HwAoRrDk
author_rank: Super Contributor
timestamp: January 21, 2022, 09:03:17 am
content: Am I correct in thinking that the ESP32 timer peripheral has no integration with GPIO?As far as I can tell, when a timer counter match (or "alarm" in their terminology) occurs, it can only trigger an interrupt. So you can't, for example, have a GPIO pin toggled in hardware on counter match?One thing I am looking to do is to use a one-shot timer to implement an output pulse of a few hundred milliseconds on a GPIO pin with as little software involvement as possible. So far, as mentioned above, I don't think I can have a purely hardware-based solution. What are my alternatives?From my research, other potential solutions seem to be:Simple delay - undesirable as it's not asynchronousESP-IDF GPTimer APIESP-IDF High-Resolution Timer APIFrom reading the docs, it seems to me that the High-Resolution Timer API is basically an abstraction that allows multiple timers on top of a single hardware timer with a fixed 1 usec timebase. Whereas the GPTimer is more flexible, essentially a wrapper around the hardware timer peripheral.One thing I would particularly like to have is to ensure with as much certainty as possible that the output pulse will be turned off after the desired period. What guarantees do these APIs provide that the callback function will be run when the timer alarm is triggered?

author: lucazader
author_rank: Regular Contributor
timestamp: January 21, 2022, 10:09:53 am
content: If you are wanting to toggle a pin for pwm reasons. the ESP32 does have a separate PWM peripheral.See sections 4.1.15 and 4.1.16 of the data sheet. and also here for some examples:https://github.com/espressif/esp-idf/tree/master/examples/peripherals/mcpwm

author: HwAoRrDk
author_rank: Super Contributor
timestamp: January 21, 2022, 11:02:22 am
content: Oh, you can use the PWM peripheral for such a one-shot pulse output?Didn't think about that. Thanks, I will have to look into that.Does it allow you to use an arbitrary GPIO pin?

author: HwAoRrDk
author_rank: Super Contributor
timestamp: January 21, 2022, 02:42:45 pm
content: Hmm, I'm not seeing that there's any possible way of having a single-shot output pulse using the MCPWM peripheral (whether through ESP-IDF API or bare metal)...

author: florian-x
author_rank: Contributor
timestamp: January 21, 2022, 07:40:26 pm
content: The RMT peripheral should be able to produce a one-off pulse, I'd say...https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/rmt.html

author: HwAoRrDk
author_rank: Super Contributor
timestamp: January 22, 2022, 05:27:47 am
content: Interesting. While I think the RMT peripheral could do it, I don't think it would offer any advantage over using the HRT.It doesn't appear the clock can be divided down enough for single pulses of hundreds of milliseconds in length, so you'd have to make a pulse out of several 'items' (length + level pairs), which means the API driver will be using interrupts to copy all that data piece-by-piece out of a buffer into registers to be sent. Which basically makes the process not purely hardware driven.

author: florian-x
author_rank: Contributor
timestamp: January 22, 2022, 04:25:12 pm
content: I got the idea from the following project - a frequency counter:https://github.com/DavidAntliff/esp32-freqcount.It looks like one block of RMT data can encode a pulse of 0.1311 * 64 = 8.3 seconds long. And up to 8 blocks can be used. For longer periods you'd need to refill the RMT buffer on the fly.The frequency counter uses this to generate single pulses of, e.g., 1 second, for gating the signal that is being counted. I used it (I had to improve the implementation for counting with 64 bits, but otherwise the RMT worked fine).

author: HwAoRrDk
author_rank: Super Contributor
timestamp: January 22, 2022, 06:12:41 pm
content: 8.3 seconds? Are you sure?As far as I can see, RMT can be clocked only using the APB clock at 80 MHz, which can be divided at most by 256 to get 312.5 kHz. That means each RMT 'tick' is 3.2 us. A pulse duration is specified with 15 bits, for a maximum of 32,767 ticks, which gives a maximum pulse length of 104 ms. I suppose also that thermt_item32_tstruct contains two pairs of durations, so doubling gives 208 ms.

author: florian-x
author_rank: Contributor
timestamp: January 22, 2022, 07:16:22 pm
content: Well, at least at API level, one programs the RMT for sending a number of "blocks" of 64 items each, where an item is 32-bit and indicates two pairs duration + level. So you put a bunch of items at once, up to 64*8 items.The esp32 Technical Reference indicates: "The eight channels share a 512x32-bit RAM block which can be read and written by the processor cores over the APB bus, read by the transmitters, and written by the receivers."To me this looks like the RMT peripheral has this much RAM to hold the queued items. I would expect no interrupts to be needed, all blocks passed to the API should be copied to this memory upon API call, then used by the RMT with no intervention of the CPU.And by the way, it seems you can set it up so that data in the block is sent out continuously, starting each time from the beginning of the block. (RMT_REG_TX_CONTI_MODE).