Open zyxtia opened 1 year ago
Hi @zyxtia , the issue is that, in your code, you didn't call the rmt_driver_install
to install the driver object, leading to the p_rmt_obj[channel]
being a NULL
pointer when you call rmt_rx_start
.
BTW, if what you need is to get notified when RMT RX is done, then you can consider trying the new RMT driver, where you can call rmt_rx_register_event_callbacks to hook your callback function. Note, the new driver only exists on esp-idf 5.x
rmt_driver_install
Hi @suda-morris , thank you for the reply. The documentation states that if using a custom ISR handler (which I am), then I can't use rmt_driver_install
. I tried it anyway (rmt_driver_install(rmt_channel.channel,0,0);
), and while it allows rmt_rx_start
to pass, the program won't actually work because the default handler is installed, instead of my custom routine. Now that you've pointed me in the right direction, it seems that I am not the first person or the second to have trouble with this, but I haven't been able to find a resolution.
Also worth noting that the code works fine on ESP32 (with some basic edits within the ISR handler), but not on ESP32S3, so that's why I'm really stumped. I think the documentation isn't quite clear on
Any help would be greatly appreciated.
BTW, if what you need is to get notified when RMT RX is done, then you can consider trying the new RMT driver, where you can call rmt_rx_register_event_callbacks to hook your callback function. Note, the new driver only exists on esp-idf 5.x
I'm using Arduino-ESP32 Core (currently 2.0.9), so I'll have to wait until Arduino-ESP32 Core 3.0 comes out :)
@zyxtia I'm afraid there's no easy fix for it. I can explain the difference you've observed between esp32 and esp32s3. Why rmt_rx_start
can work on ESP32 but can't on ESP32S3? Because on ESP32, this SOC_RMT_SUPPORT_RX_PINGPONG
is false, in the rmt_rx_start
function, there's no code that will read the p_rmt_obj[channel]
. So it's safe for esp32. But on esp32s3, the driver needs to reset some of the internal states, especially for a ping-pong receive.
@zyxtia I'm afraid there's no easy fix for it. I can explain the difference you've observed between esp32 and esp32s3. Why
rmt_rx_start
can work on ESP32 but can't on ESP32S3? Because on ESP32, thisSOC_RMT_SUPPORT_RX_PINGPONG
is false, in thermt_rx_start
function, there's no code that will read thep_rmt_obj[channel]
. So it's safe for esp32. But on esp32s3, the driver needs to reset some of the internal states, especially for a ping-pong receive.
Hi @suda-morris , thanks for the reply. A few follow up questions:
1) you say that there is no "easy" way. Would it be possible to modify my local configuration, even if it means my build isn't distributable? I imagine that I could modify the default ISR to suit my needs. This would be a stopgap until ESP-IDF v5 is released for Arduino ESP32 Core (and assuming that it includes functionality that I can have a custom interrupt). I'm currently pursuing that option (modifying a local copy of rmt.c), with limited success, but I'll figure it out hopefully.
2) question/suggestion: the v4.4 documentation states that "It’s not recommended for users to register an interrupt handler in their applications". Based on what youve said, I would suggest that the documentation is wrong and should be updated to read "custom ISR is not supported in v4.4.4", or some clarification therein. The documentation is misleading in that it explains methods to attach a custom ISR, even though they don't work. Is there any chance v4.4.4 documentation would be updated, or is that frozen and the point is therefore moot because v5 works totally differently?
3) (off topic to this bug request, but relevant to my use case) my use case is to read 50hz servo PWM, but I need to minimize impact to the main processor. If the RMT can no longer support this on ESP32S3, is there a way to use the MCPWM peripheral as an input-only device? That might be another option for my use case, but I can't find documentation or examples that can help. Or maybe there is another suggestion you have. I really don't want to have manual timing of PWM signals in my main code (for various valid reasons).
Thank you! -zyxtia-
Following up, in case anyone stumbles across this and wants an answer:
a) I ended up downloading the v4.4 "rmt.c" file (https://github.com/espressif/esp-idf/blob/release/v4.4/components/driver/rmt.c), and modified the "rmt_driver_isr_default" section to make it do what I wanted my custom ISR to do. It's less than ideal (i have to keep my custom "rmt.c" file in the directory of my Sketch, and can't give it a different name), but it's working as intended.
b) I maintain that the documentation for ESP-IDF 4.4 is incorrect. As stated above, it says that "it’s not recommended for users to register an interrupt handler in their applications", but it should state that this functionality simply does not work. As such, i've updated the subject of this submission accordingly, and am leaving this issue open for now, hoping someone can make the documentation correction (i don't know how to update documentation, so I can't do it myself)
Answers checklist.
IDF version.
v4.4.4 (through Arduino IDE)
Operating System used.
Linux
How did you build your project?
Other (please specify in More Information)
If you are using Windows, please specify command line type.
None
Development Kit.
M5Atom-S3 Lite, (also same on StampS3)
Power Supply used.
USB
What is the expected behavior?
The RMT was changed from the ESP32 to the ESP32-S3, where channels 0-3 are TX only, and 4-7 are RX only. Choosing an RX only channel, mapping it to a GPIO, and configuring it (in much the same way as would be done on ESP32), would then end with calling "rmt_rx_start" to get the channel listening. The ESP_ERROR_CHECK passes when choosing a valid RX channel (4-7), so there shouldn't be a reason for rmt_rx_start() to fail (that I can think of). If there is something wrong with the channel config, then ESP_ERROR_CHECK should flag it, and that should be explained in the API reference. (FYI: program is intended to measure the period of a simple RC car/plane 20Hz servo motor. Those motors generally have a period of 1ms to 2ms)
What is the actual behavior?
While configuring RMT (see below, "rmt_init()" function), when calling "_rmt_rx_start(rmtchannel.channel, true)", error is thrown and system reboots. Note that the backtrace calls out file "rmt_ll.h", line 132. The contents of line 132 (for me) are:
static inline uint32_t rmt_ll_rx_get_mem_blocks(rmt_dev_t *dev, uint32_t channel) { return dev->chmconf[channel].conf0.mem_size_m; }
Steps to reproduce.
Debug Logs.
More Information.
You can see in my code that it's based off the work of others. I've modified the code and it's worked great with ESP32. I further modified it based on documentation to work with ESP32S3, but I think there might be a problem with the driver for RX-only applications.