-
Notifications
You must be signed in to change notification settings - Fork 41
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
FastLED breaking Ethernet using RMT (LAN8720) ? And wrong LED pattern using I2S #19
Comments
I am busy investigating led control while using the ESP32 an I stumbled on this. Reading bbulkow interesting readme I see that he on several occasions mention that I2S module works much better and is more stable. Have you tried the I2S module instead of the RMT. I am also going to use the olimex EVB....I hope I don't get the same problem 😳 |
Hi @NeliusNDL ! Thanks for your comment ! I confirm that this problem does not occur with I2S (when commenting / un-commenting lines in CMakeList.txt and FastLED.h). This means, pings are being replied to while LEDs are blinking.
I will dig more into this I2S issue in my examples. If anyone has ideas or links about any of those two issues, I would be glad to have it ! |
Hi @Pacheu . This sure sounds like the Olimex board is using a pin that you're trying to use. It looks like the EVB board is kinda tough because given the number of features it has, you have to find free pins. I see that all the pins you've tried are bootstrapping pins, I see on the Olimex support board lots of questions about which pins do what. It looks like the EMAC pins can be remapped through the gpio_matrix_* calls.... but I figure it's not doing any of that? Reading the schematic for the EVB, I see Ethernet using 19,22,21,25,26,23,18,27, which is a lot of pins. Looking at the Phy demo, I see the same pins. However, in the schematic, I see even more pins labeled as EMAC, such as GPIO0,1,4,5,12,13,14,15,16. I also see a bunch of statements in the forum about voltages, as if using the ethernet is simply pulling power that you don't have? This is a complicated board.... The fact that Olimex is not forthcoming about what pins you can use is quite unsettling - but how about this? I just looked at toggle_relay.c in their examples directory, and I see they're using gpio 32,33,34. The I2C example is using 16 and 13. watering is using 32, because it's where the relay is. GPIO2 is listed as SD_DATA0, GPIO4 is EMAC_TX_ER, GPIO5 is EMAC_RX_CLK, 12 is both SD_DATA2, and EMAC_TXD3... I'm getting that by eyeballing the schematic, checking out the ESP-WROOM-32 component, and reading carefully how they've labeled the pins. Its the only thing I can see on the Olimex site at all regarding what pins are safe.... this would seem a good question for the Olimex support forum? Ok, so how about pin 32? It's RELAY1, you can disable (and not init) any code using the relays, and use ethernet and FastLED? I also like the looks of 5 and 35, the canbus pins, because you're probably not using canbus --- just make sure you don't init or compile in CAN, and those pins are likely safe. If it's not a pin collision problem, and it's not a power problem, I'd turn on as much stack protection code as you can find. |
Hi @bbulkow ! Thank you for your time. After reading your comment I ran some more tests on Power supply, pins, etc ...
Also, what do you mean by turning " as much stack protection code as I can find " ? I used in IDF configs the Stack smashing protection mode with CONFIG_COMPILER_STACK_CHECK_MODE set to option Overall (COMPILER_STACK_CHECK_MODE_ALL) but nothing changed. I never had this Eth interference issue before. I used almost all GPIOs that was available according to this Pinout from RIOT OS with ADC, common GPIO with or without interrupts and I never broke anything from Eth driver or stack. That is why my guess was on RMT. EDIT : on my project real setup, with 4 stripes of 70+ LEDs (powered with 5V up to 3A), when using I2S with ESP-WROWER-KIT, there are some artifacts at the end of the number of LEDs I am using : for example, if I want to use 50 LEDs, the 51th one is sometime lit and the 4 after that are always red). But, using RMT with either WROWER KIT or Olimex EVB, every lit LED is expected. |
Thanks for all that testing, but tell me, where can we go next? The RMT driver is specifically built to only use that one pin and attaches the RMT driver to it. How else could it cause problems to the Ethernet driver and stack? My theory was pin conflict, but given your testing, I agree that seems impossible - although thank you for the pointer to RIOT OS documentation. It seems to also state, for example with GATEWAY, that there are few safe pins, but if you have the problem with just one LED string configured, and Just one 'addLeds' and only on the safest of pins, you've covered the bases. My other theory would be something is hurting the stack. For this there are several entries in menuconfig, such as "Compiler options -> stack smashing protection -> strong, and there's also the chance that there's heap corruption so Component config -> heap memory debugging -> heap corruption detection, which can be set to different levels. There are also controls for the amount of stack space used by interrupt handlers and similar, these are controlled under Component config -> Common ESP-Related. Since we are guessing at what even a cause would be, I can only suggest making these values bigger and see what happens. However, today, I can only think that it must be a timing issue related to the amount of CPU used by the RMT system or I2S. To test this, one could try lowering the priority of the RMT system and changing the core, to see if there is a difference. The core for RMT interrupts is controlled by the core where the initialization happens - in the main.cpp example code, you see there is an xTaskCreate.... that is on core 0, so the RMT interrupt will be on core 0 also. You can try changing this; I don't know which core the Ethernet system is using. In order to lower the priority ( which might cause pattern problems but at least give us a hint ), look for the line esp_intr_alloc() in clockless_rmt_esp32.cpp and change the values of ESP_INRT_FLAG_IRAM and ESP_INTR_FLAG_LEVEL3 as per the documentation for that function. LEVEL3 is the highest level allowed for C functions. Your measurement that adding a 4th "ring" creates disconnects could create this suspicion, but it's not a great theory. Disconnects might be caused by the ethernet driver not getting enough time, true but with 4 strings (and pins) there are still 4 in parallel, so I wouldn't expect the FastLED driver to take much more CPU, only a little. To tip over the edge into disconnects, that seems possible? If so lowering the interrupt level and changing the core should be an interesting test. Another test I can imagine is decrease the number of LEDs (again as a test). If the interrupt handler has to do a certain amount of work, and that's causing ethernet problems, then doing less work would be a way of sniffing out the cause. Since you are using "rings" I think you must not have too many LEDs, though? Is this a possible area of test? I see your real project is 70 so perhaps you are already using fewer, the "rings"? Going down to 1 LED might be an interesting test. I am also wondering if the Ethernet driver is conflicting with the RMT driver as well as the reverse. There is a define "FASTLED_ESP32_SHOWTIMINGS". This prints out, after every 'led show" call, the jitter at the interrupt level. I used it for determining the best MEM_BLOCK_NUM. Perhaps you can turn this on and see what the jitter is, compared to your WROVER? I have no Olimex systems to test, myself. I was thinking though, just a few days ago before I saw your post, of getting one of the POE systems, as they are small but mighty. It would be unfortunate if we couldn't get the olimex ethernet running with FastLED, because Ethernet really is the best way to synchronize and control LEDs like this. Since you have these boards, are there other differences that might give us a clue? For example, are they using Rev 0 chips, with more known errata? Are they using a different XTAL than the internal one, so might have major timing differences? The fact that the patterns "are not what you expect" with I2S is also interesting, no? What would be causing that? The usual reason would be that the timing generated is not correct. The interesting point of the RMT driver is it has "bail code", that it, it determines when there has been interrupt jitter and stops setting pixels. The I2S code doesn't have this, so if there is jitter and thus there is a > 50us pause, it will create very bad patterns - much worse than an extra pixel here or there. This is why I suggest turning on SHOWTIMINGS, it might determine if the ethernet driver is greedy. Regarding your test with I2S on a WROVER, I have seen a similar artifact. Interestingly, it happens only one some patterns, and when I wrote test patterns that were simpler, I was unable to reproduce it, so I started suspecting my pattern code and not the driver code. It also seemed to be just one LED too long sometimes, same as you say. If you have simple code to reproduce the "extra LED" on a more standard ESP32, I would love to see it, maybe I can track that down - if you can share that would be great. |
Hi ! First of all I'd like to thank you again for your time and your answers.
I will now dig more into Olimex's boards, if there is somewhere any clue on any Ethernet bug caused by FreeRTOS or any I/O. |
@Pacheu I had a think while I was sleeping, and want to confirm a fact. The I2S driver implementation DOES NOT impact the Ethernet use, it simply is wrong. If that's the case, since it uses the same amount of memory and mostly the same code paths until it actually manipulates drivers, then my new theory is the Ethernet driver is using the RMT hardware in some way. This can probably best be validated by reading the Ethernet source code (although looking at the driver state might work too). I don't love this theory, because when FastLED attempts to configure the RMT hardware, I would think we would get a failure and we do check for error codes now. The best thing I could do, if this is true, is to simply find the bug in the I2S code so it works. There are many reports of I2S being more stable so this would be a benefit to the driver -- perhaps you can look into the Ethernet driver, but especially do a quick search for whether it used RMT. I also think turning this over to the Olimex folks make sense. They have a forum where they reply, and they don't need hardware. One simply runs the test program, you don't need any particular hardware hooked up to the pins, and the ethernet stops functioning you say. They should be able to track that down. And, oh, my Olimex boards arrived yesterday. I got 4 of them: Two with isolation, one without ( the little POE boards ), and one big EVB board like you've got. I was planning on getting one anyway because Ethernet is the obvious choice for LED control so these boards and FastLED would be a great choice for several projects I'm working on. Thank you again for your effort on this --- we'll crack it! |
Hi ! @bbulkow Thank you a lot for your enthusiasm ! I confirm that the I2S does not impact anything else and that it is just wrong linke you said. Also, I am almost certain that Ethernet here does not use RMT module. I looked over the code, "rmt" does not appear anywhere in any file from esp_eth, and eth_phy + eth_phy_lan8720 files use driver/gpio or eth_phy special structures. Moreover, after initializing Ethernet with LAN8720, I used "rmt_driver_uninstall" on all possible channels and the log result said "No RMT for this channel", for all of them. I created a post in OLIMEX's forum and linked this GitHub issue to it. A moderator, replied and advise to use other boards than EVB. He also explain and answered on the XTAL and chip questions you asked. I just put the link here so you can check it ! Link to Olimex forum post. I also did some more test (and I found the source issue while doing my last test and writing this post):
What is really curious though is that Eth does not break until I do an actual show(), that is to say an actual rmt writing. But, before writing, the rmt_set_pin function is called and changes the pin. So we never write to GPIO 0, right ? That does not resolve the I2S problem, but at least, I can now use RMT driver to write my LEDs and have no issue anymore =D . |
Wow, great sleuthing! The intended reason for the metaphor of setting the pin to "0" and initializing I've never liked. It is intended to allow a very large number of pins to be used without constantly changing over the PIN structure. It would seem we could change the code to have a "default pin", that is, the pin that we're going to configure as the "first pin", so it could be something other than 0, and thus at least give an option of not messing with someone else's driver. But your research shows that there's likely to be even more issues, because by the time the 'show' is called, something must have remembered the PIN 0. If we're going to be strictly correct, then, we'd have to init the channel if it wasn't the old value before. Let me see if I can at least add a section to the README about the issue, and create a config #define for "default pin" to allow changing one simple #define and allowing boards like this to work for others. Thanks for the excellent sleuthing! I look forward to having my olimex boards work the first try :-) |
@Pacheu Hey! Thanks for the simple test code. It clearly shows the I2S fail. I'll follow up on the other incident when I have status. |
Hi @bbulkow ! Yeah I did quite a lot of testing to find this one ! But, thank you for the guidance ! I am glad it helps you strengthen this library code. I hope you will get through the I2S pb, and wish you the best with Olimex boards! |
Hi ! I am currently developing something on an ESP32 using ESP IDF and I was adding your library to my project to light up a Neopixel Ring (24 pixels).
I encountered some problems regarding the use of Wi-Fi and FastLED, which I believe I solved (I will describe it later), but now I am stuck with a new problem : On the first call to FastLED.show(), my Ethernet connectivity breaks ; I don't see any receives.
Details on my working environment :
main.zip
I'm also using the RMT driver, by commenting the (#define FASTLED_ESP32_I2S) line in FastLED.h and un-commenting ("platforms/esp/32/clockless_rmt_esp32.cpp") in CMakeLists.txt. Indeed, I am using the WS2812 LED chipset, and as I understood, this uses the RMT driver. Finally, I added a line inside IDF code, in "esp_eth_mac_esp32.c" in component esp_eth, to print transmits of the mac driver :
As my example is running on the Olimex, I am pinging it with my PC. After the initialization, I have no problem pinging it. But, on the first call to FastLED.show(), receives end, and the device is not responding to my pings. I can stop and restart the Ethernet handler, this won't change any thing. The only way is to destroy it (uninstall the driver), re-install it and restart it again. But once again, on the next show, this will stop working. If I don't restart it, receives don't happen, but also, after a while, I am starting to see that the line in "esp_eth_mac_esp32.c" :
MAC_CHECK(sent_len == length, "insufficient TX buffer size", err, ESP_ERR_INVALID_SIZE); // line227
is reporting an error .
At least, my LED are showing correctly =) .
There is also a Wi-Fi handler initialized, but removing it won't solve the problem.
I have no idea what is causing the PB : I have browsed everywhere, I cannot seem to find anything on that, except this :
espressif/esp-idf#2644
But the person's problem was on the RMT side with RX, not on the Ethernet side.
I don't know if the RMT here is messing with the SPI emac pins ( I don't know why it would do that).
I don't know either if it is interrupt - related ( I also cannot see why it would be because the RMT implementation is not using any I believe). EDIT : I may have been wrong, and I believe now that there are actually interrupts, because the RMT sends the signal in a devided way.
It might be my implementation somehow, but what is in the example is pretty basic (just esp_eth usage and one FastLED controller with not that many pins).
Do you think I have to write an issue on FastLED Github page or on ESP-IDF one's ? I mean if the issue is RMT related and not really FastLED-idf related, I can understand that solving this is not really in your interest.
Otherwise, do you have any idea what might be the issue here ? Ah, and here is a capture of the logging, where we can see during the blinking that no receives happen, until I destroy-restart the eth handler :
PS : The problem I had with the use of Wi-Fi and FastLED was due, I think, to the fact that Wi-Fi main task is pinned to core 0 and doing FastLED.show() in this core would result in wrong LED show, for example, 5 LEDs light up instead of 2. So, I'm now calling show() in a task pinned to core 1, and the problem disappeared. Have you ever seen this issue with Wi-Fi before ? Thank you for reading me !
The text was updated successfully, but these errors were encountered: