pixelmatix / SmartMatrix

SmartMatrix Library for Teensy 3, Teensy 4, and ESP32
http://docs.pixelmatix.com/SmartMatrix
611 stars 161 forks source link

FM6126A chip support #78

Closed marcmerlin closed 3 years ago

marcmerlin commented 5 years ago

Newer panels are shipping with FM6126A, apparently because it's a chip offering faster refresh, which is necessary for bigger displays. But it indeed does not work with SmartMatrix https://community.pixelmatix.com/t/pxmatrix-seems-to-support-fm6126a-driver-chips-that-smartmatrix-doesnt-support/421 Discusses the details. The chip is already supported by http://github.com/2dom/PxMatrix/ but that's only supported on ESP8266

marcmerlin commented 5 years ago

https://github.com/marcmerlin/SmartMatrix/blob/FM6126A/examples/FM6126A_reset/FM6126A_reset.ino from bobdavis321 almost gets my panels working (based on this thread https://github.com/hzeller/rpi-rgb-led-matrix/issues/746#issuecomment-485404064 )

bobdavis321 commented 5 years ago

Here is the teensy code to reset the panels (It may work with other processors by changing pin assignments:)

// SMart Matrix Panel Reset Program
// For use with newer LED Panels
// Written 3/28/2019 by Bob Davis
int MaxLed = 128;

#define GPIO_PIN_CLK_TEENSY_PIN    14
#define GPIO_PIN_LATCH_TEENSY_PIN   3
#define GPIO_PIN_OE_TEENSY_PIN      4
#define GPIO_PIN_B0_TEENSY_PIN      6
#define GPIO_PIN_R0_TEENSY_PIN      2
#define GPIO_PIN_R1_TEENSY_PIN      21
#define GPIO_PIN_G0_TEENSY_PIN      5
#define GPIO_PIN_G1_TEENSY_PIN      7
#define GPIO_PIN_B1_TEENSY_PIN      20
#define ADDX_TEENSY_PIN_0   9
#define ADDX_TEENSY_PIN_1   10
#define ADDX_TEENSY_PIN_2   22
#define ADDX_TEENSY_PIN_3   23

int C12[16] = {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
int C13[16] = {0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0};

void setup() {
  // put your setup code here, to run once:
    pinMode(GPIO_PIN_CLK_TEENSY_PIN, OUTPUT);
    pinMode(GPIO_PIN_LATCH_TEENSY_PIN, OUTPUT);
    pinMode(GPIO_PIN_OE_TEENSY_PIN, OUTPUT);
    pinMode(GPIO_PIN_B0_TEENSY_PIN, OUTPUT);
    pinMode(GPIO_PIN_R0_TEENSY_PIN, OUTPUT);
    pinMode(GPIO_PIN_R1_TEENSY_PIN, OUTPUT);
    pinMode(GPIO_PIN_G0_TEENSY_PIN, OUTPUT);
    pinMode(GPIO_PIN_G1_TEENSY_PIN, OUTPUT);
    pinMode(GPIO_PIN_B1_TEENSY_PIN, OUTPUT);
    pinMode(ADDX_TEENSY_PIN_0, OUTPUT);
    pinMode(ADDX_TEENSY_PIN_1, OUTPUT);
    pinMode(ADDX_TEENSY_PIN_2, OUTPUT);
    pinMode(ADDX_TEENSY_PIN_3, OUTPUT);
}

void loop() {
    // put your main code here, to run repeatedly:
    // Send Data to control register 11
    digitalWrite (GPIO_PIN_OE_TEENSY_PIN, HIGH); // Display reset
    digitalWrite (GPIO_PIN_LATCH_TEENSY_PIN, LOW);
    digitalWrite (GPIO_PIN_CLK_TEENSY_PIN, LOW);
    for (int l=0; l<MaxLed; l++){
      int y=l%16;
      digitalWrite (GPIO_PIN_R0_TEENSY_PIN,LOW);
      digitalWrite (GPIO_PIN_G0_TEENSY_PIN,LOW);
      digitalWrite (GPIO_PIN_B0_TEENSY_PIN,LOW);
      digitalWrite (GPIO_PIN_R1_TEENSY_PIN,LOW);
      digitalWrite (GPIO_PIN_G1_TEENSY_PIN,LOW);
      digitalWrite (GPIO_PIN_B1_TEENSY_PIN,LOW);
      if (C12[y]==1){
          digitalWrite (GPIO_PIN_R0_TEENSY_PIN,HIGH);
          digitalWrite (GPIO_PIN_G0_TEENSY_PIN,HIGH);
          digitalWrite (GPIO_PIN_B0_TEENSY_PIN,HIGH);
          digitalWrite (GPIO_PIN_R1_TEENSY_PIN,HIGH);
          digitalWrite (GPIO_PIN_G1_TEENSY_PIN,HIGH);
          digitalWrite (GPIO_PIN_B1_TEENSY_PIN,HIGH);
      }
      if (l>MaxLed-12){digitalWrite(GPIO_PIN_LATCH_TEENSY_PIN, HIGH);}
          else{digitalWrite(GPIO_PIN_LATCH_TEENSY_PIN, LOW);}
      digitalWrite(GPIO_PIN_CLK_TEENSY_PIN, HIGH);  
      digitalWrite(GPIO_PIN_CLK_TEENSY_PIN, LOW);  
    }
  digitalWrite (GPIO_PIN_LATCH_TEENSY_PIN, LOW);
  digitalWrite (GPIO_PIN_CLK_TEENSY_PIN, LOW);
  // Send Data to control register 12 
    for (int l=0; l<MaxLed; l++){
      int y=l%16;
      digitalWrite (GPIO_PIN_R0_TEENSY_PIN,LOW);
      digitalWrite (GPIO_PIN_G0_TEENSY_PIN,LOW);
      digitalWrite (GPIO_PIN_B0_TEENSY_PIN,LOW);
      digitalWrite (GPIO_PIN_R1_TEENSY_PIN,LOW);
      digitalWrite (GPIO_PIN_G1_TEENSY_PIN,LOW);
      digitalWrite (GPIO_PIN_B1_TEENSY_PIN,LOW);
      if (C13[y]==1){
          digitalWrite (GPIO_PIN_R0_TEENSY_PIN,HIGH);
          digitalWrite (GPIO_PIN_G0_TEENSY_PIN,HIGH);
          digitalWrite (GPIO_PIN_B0_TEENSY_PIN,HIGH);
          digitalWrite (GPIO_PIN_R1_TEENSY_PIN,HIGH);
          digitalWrite (GPIO_PIN_G1_TEENSY_PIN,HIGH);
          digitalWrite (GPIO_PIN_B1_TEENSY_PIN,HIGH);
      }    
      if (l>MaxLed-13){digitalWrite(GPIO_PIN_LATCH_TEENSY_PIN, HIGH);}
          else{digitalWrite(GPIO_PIN_LATCH_TEENSY_PIN, LOW);}
      digitalWrite(GPIO_PIN_CLK_TEENSY_PIN, HIGH);  
      digitalWrite(GPIO_PIN_CLK_TEENSY_PIN, LOW);  
    }
  digitalWrite (GPIO_PIN_LATCH_TEENSY_PIN, LOW);
  digitalWrite (GPIO_PIN_CLK_TEENSY_PIN, LOW);
}

.

marcmerlin commented 5 years ago

Thanks @bobdavis321. Diffs work better, but I compared what you pasted with what I was able to get from your webpage:

     // Send Data to control register 11
-    digitalWrite (GPIO_PIN_OE_TEENSY_PIN, LOW); // Display reset
+   digitalWrite (GPIO_PIN_OE_TEENSY_PIN, HIGH); // Display reset

The problem was not with MaxLed but the version I got from your webpage that had this small bug. Thanks for the updated version

https://github.com/marcmerlin/SmartMatrix/blob/FM6126A/examples/FM6126A_reset/FM6126A_reset.ino updated.

marcmerlin commented 5 years ago

Also sent to @embedded-creations via https://github.com/pixelmatix/SmartMatrix/pull/79 Obviously it's not where it belongs long term, but if he can't test it, it's better there than nowhere for now

marcmerlin commented 5 years ago

@bobdavis321 ok, my upload has your corrected code now. However, I'm not too clear about a couple of things:

1) I read that the reset code had to be run once before running normal code. This is what I do with rPi, all I have to run is https://github.com/hzeller/rpi-rgb-led-matrix/files/3100669/resetmatrix_adafruit.py.txt and then normal code and it works. With your teensy version, you put that in loop() instead of setup() I moved it to setup() because it didn't feel like it needed to be in loop(), but the corrected version you gave me still does this in loop() (and doesn't fully work, see 2) below) Can you please download and test https://github.com/marcmerlin/SmartMatrix/blob/FM6126A/examples/FM6126A_reset/FM6126A_reset.ino ?

2) your teensy version even after your fix you just gave me, still doesn't seem to fully work. The top half of the screen and bottom half (top 16 vs bottom 16 lines) don't look the same. Are you not having this issue? Again, can you try the link above and verify if you are seeing this, or not when doing a) run the code above b) run featuredemo from smartmatrix examples.

Thanks, Marc

bobdavis321 commented 5 years ago

The reset code was in Setup() because the Loop() had code for displaying text (That is not needed to run the demos). I do not have the Teensy setup at this time because I am working on some different projects. I fixed the code on my blog so it should cut and paste just fine (Blogspot trashes code with < or > in it). I will set up a Teensy code page on my github account soon. (Hopefully) -Bob

On Thu, Apr 25, 2019 at 1:39 AM Marc MERLIN notifications@github.com wrote:

@bobdavis321 https://github.com/bobdavis321 ok, my upload has your correct code now. However, I'm not too clear about a couple of things:

1.

I read that the reset code had to be run once before running normal code. This is what I do with rPi, all I have to run is https://github.com/hzeller/rpi-rgb-led-matrix/files/3100669/resetmatrix_adafruit.py.txt and then normal code and it works. With your teensy version, you put that in loop() instead of setup() I moved it to setup() because it didn't feel like it needed to be in loop(), but the corrected version you gave me still does this in loop() (and doesn't fully work, see 2) below) Can you please download and test https://github.com/marcmerlin/SmartMatrix/blob/FM6126A/examples/FM6126A_reset/FM6126A_reset.ino ? 2.

your teensy version even after your fix you just gave me, still doesn't seem to fully work. The top half of the screen and bottom half (top 16 vs bottom 16 lines) don't look the same. Are you not having this issue? Again, can you try the link above and verify if you are seeing this, or not when doing a) run the code above b) run featuredemo from smartmatrix examples.

Thanks, Marc

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/pixelmatix/SmartMatrix/issues/78#issuecomment-486526644, or mute the thread https://github.com/notifications/unsubscribe-auth/AI4VLATNBV6PRMODFMJYL3TPSE7XPANCNFSM4HGQXOEQ .

embedded-creations commented 5 years ago

Where'd you guys get these panels? I'd like to order some so I can test compatibility

marcmerlin commented 5 years ago

https://www.amazon.com/panels-digital-module-display-P3-19296mm/dp/B079JSKF21

embedded-creations commented 5 years ago

@marcmerlin How would you like this to be integrated into SmartMatrix Library? Ideas:

marcmerlin commented 5 years ago

I was thinking about this too... I'm not sure how slow the sequence is, but it may have a bit of a time penalty and it's hard to know it can't cause problems to any other panel. Given that, making it an init option seems more desirable and safer. In other words, SMARTMATRIX_OPTIONS_FM6126A would be given to setup as an optional argument that defaults to 0

MotivDev commented 5 years ago

@marcmerlin @embedded-creations Will this fix be applied to the ESP32 branch as well or are there other changes needed to make it work on the ESP32 chip? If so, any ETA? I just looked at my 64x64 panels late yesterday and 2 of the 3 on the bench have this newer FM6126 chip....

-Rich

marcmerlin commented 5 years ago

@MotivDev if/when this gets integrated in the SM source code, I'm sure it would, but currently, it is not. You can take the script I posted and modify the pin numbers to match your ESP32 wiring.

embedded-creations commented 5 years ago

@bobdavis321 Can you send me a link to the eBay panels you bought? I ordered a panel from Aliexpress, same listing that someone else got FM6126A chipset, and I got ICN2037. The Amazon listing Marc posted is now unavailable. I'm unable to easily source a panel to test.

bobdavis321 commented 5 years ago

This is where I purchaed my LED arrays: https://www.ebay.com/itm/LED-Matrix-P3-RGB-pixel-panel-HD-video-display-64x32-LED-Screen-module-2121SMD/253691968968?ssPageName=STRK%3AMEBIDX%3AIT&_trksid=p2060353.m2749.l2649

On Fri, May 10, 2019 at 8:55 AM Louis Beaudoin notifications@github.com wrote:

@bobdavis321 https://github.com/bobdavis321 Can you send me a link to the eBay panels you bought? I ordered a panel from Aliexpress, same listing that someone else got FM6126A chipset, and I got ICN2037. The Amazon listing Marc posted is now unavailable. I'm unable to easily source a panel to test.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/pixelmatix/SmartMatrix/issues/78#issuecomment-491278932, or mute the thread https://github.com/notifications/unsubscribe-auth/AI4VLAXYN3GEUTYNK6QKI33PUVWFTANCNFSM4HGQXOEQ .

marcmerlin commented 5 years ago

@embedded-creations damn, sorry to hear that you got the wrong one again, but see below @bobdavis321 the ebay one you listed looks identical to the one I got from amazon . By the way, the amazon panel is likely still available directly from the seller if you'd like me to put you in touch with him (been working with him directly via FB chat) If you send him a chat request I'm sure he'll send you the correct panel directly, bypassing ebay/amazon: https://www.facebook.com/su.hongren.9 I think he removed the amazon panel because he was getting too many returns. Azerone, I'm sure would be happy to get you setup with exactly the panels you want, checking the chips before mailing. Tell him I sent you and that you maintain the best driver for the arduino environment :) I've done enough work with him that I just send him money by paypal, say via FB chat what I wanted, and he's sent me what we agreed on, including replaced some panels that were defective (i.e. good customer support and work ethics).

embedded-creations commented 5 years ago

Thanks @bobdavis321 and @marcmerlin. I contacted the eBay seller and confirmed that they would ship me a panel with the right chipset. We'll see what I actually get in a few weeks. :-)

embedded-creations commented 5 years ago

I'm now the proud owner of two panels with FM6126A chips. One is a P3 64x32 from Bob's eBay seller, which I haven't tested yet. The other is a flexible P2.5 128x64 panel, which just happened to have FM6126A chips installed.

I used Bob's sketch with some minor modifications and got the panel working from a Teensy 3.6 in a SmartLED Shield V4:

marcmerlin commented 5 years ago

Glad you were finally able to get some, when many of us were getting some without trying to :)

MotivDev commented 5 years ago

Just an ESP32 update.... I have 4 - 64x64 panels on the bench, all from different batches/vendors and both FM6124A & ICN2037BP panels work correctly. The panel with FM6126A does not work and I have not tried implementing the reset that marcmerlin has provided. I also have seen a ICN2038/S chip referenced on other site forum postings.... I am thinking the FM6126A & ICN2038/S must be very similar and solving the reset issue on one might just fix the reset/setup for the other. Similar to the 6124A & 2037BP parts.

I had an ESP32 SMARTLED shield fabricated and built and I am using this for my driver for these panels. So easy to use!! Thanks for releasing that design Louis!

I hope this helps someone else that comes across these driver numbers and using an ESP32. --Rich

marcmerlin commented 5 years ago

@MotivDev FM6126A is known not to work unless you send the reset sequence. Please try it. Actually it's not clear if @embedded-creations has integrated the reset into a local branch, or not, but I guess he probably will soon and keep us up to date

embedded-creations commented 5 years ago

@MotivDev

I had an ESP32 SMARTLED shield fabricated and built

Which version? SMT or THT? Did you notice any issues? I haven't assembled the SMT version myself yet

I haven't even had a chance to seriously think about how I want to add FM6126A reset support. Let me think about it briefly now:

I think if the timing works I want to add an option where the reset sequence will be loaded up into the data buffer to be sent out to the panel like a normal frame. I don't see any delays in Bob's code so hopefully sending the reset sequence works at the same rate as sending data for refreshing the panels. The library would have a flag you could set that replaces the next frame with a reset sequence (and probably blank pixels for anything else that needs to be shifted out for that frame). I don't see any harm in sending out a blank frame for any panel, so this flag could be automatically set on power up, and also controlled with a method so the user can choose if and when to send a reset sequence after powerup (to handle the case where power to the panel is cycled while the micro is not, for example).

MotivDev commented 5 years ago

@embedded-creations

I apologize for not getting back with you sooner!

Which version? SMT or THT? Did you notice any issues? I haven't assembled the SMT version myself yet

I have been using the SMT version. Have not populated the SD card interface, but everything else seems to be working great. No issues and I've been able to run @marcmerlin SmartMatrix_GFX library.

I haven't even had a chance to seriously think about how I want to add FM6126A reset support.

I have been trying to avoid the 6126 issue... I have read on other forums that the vendors are moving away from this chip so I've been working with a vendor to attempt to get 6124 panels to satisfy my needs for the next couple of months.

I like the approach you have outlined for reseting the panel. I am using a command line interface and having the ability to send a reset command to the panel would be great. This is much better than a compile flag that would force the panel controller into a special panel reset mode. What might also work would be the ability to set the driver type: ie 6124/2037, 6126, ... then a call to the reset method could call the correct driver reset method. I'm just thinking that they will probably change the chip again and when they do, we will probably need another special reset routine.

Thanks for all the great work on SmartMatrix!

jdot3333 commented 4 years ago

Hi there! Was there any further work/fix update on this? I have been playing with the reset code on my p3 Fm6126A polluted led board and the best I get is half a screen that works and exactly half a screen that is bright green (bottom). I saw Louis said he got it to work quite simply but for me that did not happen. I have parsed through the other forums and have read all the issues with the chip. When I run gifs or the Feature Demo, you can see some of the animation play through the green, but the color is off significantly. Any extra help would be great! Thanks

marcmerlin commented 4 years ago

@jdot3333 while this sucks, try sending the reset code multiple times. It usually addresses what you describe

jdot3333 commented 4 years ago

FIGURED it out..... So @marcmerlin, you and @bobdavis321 have defined pin GPIO_PIN_G1_TEENSY_PIN 7 :

https://github.com/marcmerlin/SmartMatrix/blob/2519651d6df22621990e4ee413cf06369e806bef/examples/FM6126A_reset/FM6126A_reset.ino#L20

but in the current master of MatrixHardware_KitV4.h at:

https://github.com/pixelmatix/SmartMatrix/blob/c76d3efb417e802f0508740c2779e44463059bec/src/MatrixHardware_KitV4.h#L69

it is defined as GPIO_PIN_G1_TEENSY_PIN 8 and obviously the hardware of the SmartMatrixV4 ties to the Teensy Pin 8... No more green lines and the reset works on one shot.

Perhaps the older SmartMatrix that Bob shows on his blog used Pin 7? I am not sure if your code marc was meant for the SmartMatrixV4 or not but if it was give that change a try and it should work flawlessly. Thanks a lot for the hard work you guys did looking into this before I jumped in and @embedded-creations for the awesome library!

FYI and anybody else who may stumble across this post troubleshooting, I purchased super cheap from here on 2019-07-04 and it took 2.5 weeks to Canada:

https://www.aliexpress.com/snapshot/null.html?spm=a2g0s.issue_f040t.0.0.199a4c4d6NKiKu&orderId=103467005517597

marcmerlin commented 4 years ago

Thanks for that @jdot3333 https://github.com/marcmerlin/SmartMatrix/blob/FM6126A/examples/FM6126A_reset/FM6126A_reset.ino updated with the correct pin. @bobdavis321 is that fix relevant to you too?

atc1441 commented 4 years ago

Hi. In the manual of the FM6126A it says the last thre clock cycles the latch pin needs to be set high.

Is this allready implemented in the current SmartMatrix library?

Using an esp32

embedded-creations commented 4 years ago

No, this isn't implemented in SmartMatrix Library. You can try using the example code from Bob and Marc in your sketch. I haven't tried that code with an ESP32, but have with a Teensy and it worked for my panel.

If you're using the ESP32 shield with the latch chip, don't expect it to work, as the CLK signal is blocked while the Latch signal is high. I'm going to have to modify the circuit to handle this.

atc1441 commented 4 years ago

Thank you for the answer.

I don't use any shield, i soldered on a perf board. See here: https://twitter.com/atc1441/status/1174019294826500096 There i only used bitbanging and also the Reset code is working there but not with the library. When I connect a "normal" shift Matrix panel this library is working with i2s and esp32.

The Reset code is not working correctly for me, it seems like it is driving the panels and not setting like it should as some LEDs light up if I sent the reset code.

After my message yesterday here i tested further and my problem is indeed the Reset and not the latch. Even if it's may needed in the future.

I will look further into it and try a few more things.

atc1441 commented 4 years ago

Just as info on how i got it working so far,

with SmartMatrix i could not get it to work, but with the resetcode(https://github.com/marcmerlin/SmartMatrix/blob/FM6126A/examples/FM6126A_reset/FM6126A_reset.ino) first and then this library: https://github.com/mrfaptastic/ESP32-RGB64x32MatrixPanel-I2S-DMA it is working fine dont know why until now, but i think i will stay at that library as it is nice small. So the early latch if defenetely not needed.

Thanks for the help.

embedded-creations commented 4 years ago

I posted this question in the SmartMatrix Community, but the GitHub Issue is probably being followed by more people so I think it's worth reposting here:

I'm working on integrating FM6126A Reset into SmartMatrix Library. I'm operating under the assumption that this reset sequence can be sent at the beginning before matrix.begin() is called (or during matrix.begin()), and doesn't need to be sent any any point later in the sketch. Do you agree?

I only see two exceptions to this:

If I implement the FM6126A reset only at the beginning, the only solution to these exceptions happening is to reset the microcontroller, starting the sketch over at the beginning where the reset sequence is sent. Is that acceptable?

jdot3333 commented 4 years ago

For my project, the code needed to end with a soft reboot otherwise it would just hang on a black screen. So for me i set up a button that runs the code and soft reboots the teensy. Kind of a hacky way but for me, my project is a clock and knowing that if the display doesn't work means you push the reset button to fix things isnt a dealbreaker.

That being said, from my experience throwing it into the .begin()/setup method didn't work for me because it would hang so it would always need the reboot. Doing it the way I did works flawlessly tho.

J

embedded-creations commented 4 years ago

@jdot3333 Thanks for the feedback.

Let me make sure I understand your scenario:

Do you ever need to press the button to fix the display, after the display has been running for some time?

jdot3333 commented 4 years ago
  • Your sketch runs matrix.begin() inside setup() without any FM6126A reset code

correct

  • When you power on the clock, it has a blank display because no FM6126A reset code has been run Yes or sometimes the colors are all weird and i have random lines or squares of weird color

  • You then press a button, which runs the FM6126A reset code, and then soft reboots the Teensy, and after that, the display is working properly

correct because when i run the reset code, the display basically flashes and stays black and the soft reset makes it work.

Do you ever need to press the button to fix the display, after the display has been running for some time?

Yes that has happened but not very often and I don't know what circumstance would have caused the display to require being reset again but when it has happened a couple of times and I simply hit my reset button again and it went back to normal functionality. Could have been a bad power connection or cable connection and i haven't run the clock for real long periods of time so I am unable to say if it is a consistent issue, just that for sure it has happened.

marcmerlin commented 4 years ago

@embedded-creations , you said "If I implement the FM6126A reset only at the beginning, the only solution to these exceptions happening is to reset the microcontroller, starting the sketch over at the beginning where the reset sequence is sent. Is that acceptable?" It's probably good enough for most people (including my own use), but isn't a reset just sending a sequence over the data pins while the interrupt handler isn't sending frame data? Would it be hard to have some reset method that 1) turns off ISR if it's on 2) sends reset sequence 3) turns ISR back on That way, if the panel is disconnected or powered off (maybe for power saving as controlled by the CPU via relay, and then turns back on as needed), and then powered back on, you can send the reset sequence.

I realize you can send black frames, but if you're looking at power saving, turning off power via relay saves additional power.

embedded-creations commented 4 years ago

@marcmerlin good idea, I hadn't considered the power saving scenario.

It's more complicated than just software changes in the ESP32, because the circuit I have blocks the clock from being sent when latch is high (otherwise you end up shifting garbage pixels in when you're just trying to latch good pixels). I have to come up with a circuit that blocks clocks during latch, unless you're sending a reset sequence. Ideally I'd like to do that without dedicating a new GPIO pin for the task.

marcmerlin commented 4 years ago

Got it, I use 14 pin wiring without latch, so didn't need to worry about that :)

embedded-creations commented 4 years ago

@marcmerlin I'm actually working on this now! I have it working for my latest ESP32-based boards with external latch, etc, sending the reset sequence when calling matrix.begin() at the start of a sketch. I wired up the ESP32 Forum Pinout, and it's not working, and I'm not sure why.

Do you have an ESP32 sketch that sends the FM6126A reset sequence successfully that you can share? I tried changing the pins on your FM6126A_reset example sketch to the ESP32 pins, and that didn't work.

embedded-creations commented 4 years ago

@marcmerlin Nevermind, I think it's a level shifting issue. I don't actually have an ESP32 wired up with level shifters but not a latch, so I can't test this circuit very well. Guess I need to wire one up on a breadboard, not tonight though...

marcmerlin commented 4 years ago

I think I got it to work on teensy at the time, but then I moved to rPi given that said panels were too big to reasonably run on ESP32

embedded-creations commented 4 years ago

Well, I wired up the level shifters, and there was no improvement. Trying to think through the differences between my circuit with the latch and the direct/level-shifter-only wiring, I think I found the issue. It's not with the FM6126A reset code, it must be after.

With the latch, and the new MANUAL_CLK signal, I can precisely control the number of CLK pulses sent while LAT is high. With the direct/level-shifter-only wiring, CLK is pulsed once while LAT is high every time, as the I2S circuit must toggle the CLK signal as part of sending new I2S data. This must be changing some setting on the panel. The datasheet says that >1 CLK pulses sent with LAT high is a soft reset command. Maybe 1 CLK pulse during LAT is enough to do the soft reset.

The datasheet says 3 pulses is the "Data Latch" command, which may be an option as the direct/level-shifter-only wiring can support keeping LAT high for a specific number of CLK pulses, just not 0 CLK pulses. This is more work than I want to put into supporting the FM6126A for now.

embedded-creations commented 4 years ago

I added Bob's FM6126A init routine inside matrix.begin() if the SMARTMATRIX_OPTIONS_FM6126A_RESET_AT_START option flag is set, e.g.:

const uint8_t kMatrixOptions = (SMARTMATRIX_OPTIONS_FM6126A_RESET_AT_START);

I don't see a problem with enabling this code by default, but as I only have one panel to test with, I'm being conservative for now.

This works on the Teensy platform (SmartLED Shield V4, and earlier shields) in the master and teensylc branches. It works on the ESP32 only in my new un-released board that is able to manually toggle the CLK signal while LAT is high. I'll publish the circuit for this new board eventually, but if anyone is dying to get this working, and has a 74AHCT157 (or another 2:1) MUX and the usual 74AHCT373 Latch chips handy, let me know and I'll share that part of the circuit.

I experimented using the ESP32 without latch which seems to be resetting fine at the beginning, but then not displaying anything after. As suspected, the number of clocks during the latch pulse is important:

This makes some sense as the FM6126A datasheet says >1 clocks (maybe this should actually read > 0 && < 3 clocks) during latch is the "RESET_OEN" command, 4-10 is reserved, while 3 clocks is the "DATA_LATCH" command.

I made the SMARTMATRIX_OPTIONS_FM6126A_RESET_AT_START option make the LAT pulse 3x clocks wide. You'll have to set ESP32_I2S_CLOCK_SPEED manually. I'd appreciate some feedback on how this is working, as I only have one panel to test. I didn't test with a bare ESP32 without level shifters.

marcmerlin commented 4 years ago

@embedded-creations sorry if I didn't follow everything. I set const uint8_t kMatrixOptions = (SMARTMATRIX_OPTIONS_FM6126A_RESET_AT_START);
and basically things don't work, unless I init my panels with the rPi and don't power cycle them (if I do that, everything displays fine). This is on ESP32 with #define GPIOPINOUT 8

Is ESP32_I2S_CLOCK_SPEED set incorrectly in the code and it needs to be changed for things to work with direct wiring, or it's just not expected to work? ./src/SmartMatrixMultiplexedRefreshEsp32_Impl.h: int psPerClock = 1000000000000UL/ESP32_I2S_CLOCK_SPEED;

IMG_20200517_163138

marcmerlin commented 4 years ago

As a side note @embedded-creations the reset does do something. If I take my working panel, plug the ESP32 in while code is running, things work. Then if I reboot the ESP32, it sends an init that breaks the panel, and shows the display above (the offset in the lines is because every other panel is upside down)

embedded-creations commented 4 years ago

@marcmerlin I get similar results to you when I switched over to a direct wiring setup (ESP32_FORUM_PINOUT) instead of using level shifters, and when I leave ESP32_I2S_CLOCK_SPEED at the default of 20000000UL. If I switch to 15000000UL it works, though I do notice a row with some faint green lights lit below the bitmaps (I'm using the Bitmaps sketch).

Is ESP32_I2S_CLOCK_SPEED set incorrectly in the code and it needs to be changed for things to work with direct wiring, or it's just not expected to work? ./src/SmartMatrixMultiplexedRefreshEsp32_Impl.h: int psPerClock = 1000000000000UL/ESP32_I2S_CLOCK_SPEED;

#define ESP32_I2S_CLOCK_SPEED (20000000UL) hasn't been an issue for me, but I'm using level shifters 99% of the time. I can see needing to lower the clock rate if using direct wiring, I'll add that to the README

My results (trying to solve this a different way without necessarily lowering clock speed):

  1. Only change is kMatrixOptions = (SMARTMATRIX_OPTIONS_FM6126A_RESET_AT_START); IMG_8650

  2. Added a bunch of delays into the init sequence (you helped me find this by saying that the RPi init sequence followed by ESP32 refresh was working for you) IMG_6989

  3. Lowered ESP32_I2S_CLOCK_SPEED to 15MHz to reduce tearing IMG_2179

I narrowed down the delays needed to just a single delay at the end of init. If this doesn't work for you, can you sprinkle delays into the init code (especially before/after CLK and LAT transitions), and see if you can find the minimum number of delays that make your panel init?

I just committed the delay at the end and some notes on setting I2S clock speed. Fingers crossed it works for you as is (with just the SMARTMATRIX_OPTIONS_FM6126A_RESET_AT_START flag change needed in your test sketch)

Thanks again for testing this!

embedded-creations commented 4 years ago

Also, I get a clean image with ESP32_I2S_CLOCK_SPEED 20MHz on a different panel with direct wiring. So in my case, only one panel that I've tested with direct wiring requires lowering the I2S clock speed, the others all seemed to work fine at 20MHz.

marcmerlin commented 4 years ago

woohoo, it works now at 20Mhz, well almost, there is a dimming issue I can confirm that fixes it, a mere delay(1) :) Also, just to be clear, I am using level shifters (using Jason Coon's shield with a single trace re-routed). I'll attach some screenshots

marcmerlin commented 4 years ago

upper right corner where the pixels first get pushed is the wrong brightness and sometimes wrong colors: IMG_20200518_153350

Interesting thing is that I have 5 panels chained but only 3 configured in SmartMatrix (as you may remember, in one setup, I use bits shifted out from the virst panel to the other one). To be honest, I don't expect any panel past #3 to work, but #4 actually has blue background which is almost invisible on the first 3 panels because it's too dark, and while panel #5 has weird squares: IMG_20200518_153021

Changing the speed to 15Mhz didn't change anything I could see.

embedded-creations commented 4 years ago

@marcmerlin Thanks for the testing and photos! I'm out of time today, but want to do some more testing on my panel which I thought "worked" but maybe there are some more issues that I didn't see. I'll do my best to get back to you tomorrow with updated code

embedded-creations commented 4 years ago

I just pushed a change that hopefully helps. Before, it was sending the reset sequence out to 256 LEDs, regardless of how many you have configured in your sketch. Now it should send the right amount.

https://github.com/pixelmatix/SmartMatrix/commit/4c297be7d42131abe93f32853b990da4e84cf00c

I tried the sketch again on an ESP32 with no level shifters, and another with level shifters, no latch. Both had bad images at 20MHz, worked at 15MHz.