Closed mhungerford closed 3 years ago
Meiyad says that they are using a new batch of ICs that exhibit this issue even with their own controller.
These panels are 32x32, there are 3 of them in series (32ROW_MOD8SCAN).
Try uncommenting this line:
https://github.com/pixelmatix/SmartMatrix/blob/master/src/SmartMatrix_Impl.h#L622
doh, that's already uncommented (I was going from memory from the years where it was just a debug option)
Change the value of that line from 0x02
to 0x03
, and it should stall the DMA engine for 8 cycles instead of 4, hopefully dropping the HUB75 CLK speed in half
That makes every pixel flicker white-ish, the original image is there the same as before, like extra data is being latched.
Here are the scope traces, first is the good panels, second is the bad panels where the data is skewed by the bad ICs (captured from clk and R2 pins out from 3rd panel). These were captured while we were running with F_CPU=192000000 (192MHz). In the good panels, clock and R2 transition at same time. In the bad panels, eventually it shifts so the R2 occurs just after the clock is transitioning again. Same for all other colors.
Here is the original asset:
Here is how it looks on the hardware, notice the corrupted data between panels 1-2 and 2-3.
And here is the panels using the TCD->CSR dma slowdown 0x3:
These panels have an odd internal order, which is why the bad data is from the next panel over, and upside down.
Here is a pic from the previous good batch of panels:
What happens if you use the stock SmartMatrix Library (without your F_CPU etc changes) and just change that value I mentioned from 0x02 to 0x03?
Same Problem. Looks identical to when F_CPU/F_BUS is modified.
Ah, I needed to increase the LATCH_TIMER_PULSE_WIDTH_NS, now I can use 0x03 for TCD->CSR. It helps, but still slightly off. Reduced the problem.
Glad you found that, I meant to tell you that this morning, but forgot before I got to my email later in the day
You probably also want to change PANEL_32_PIXELDATA_TRANSFER_MAXIMUM_NS
as that's related to the panel CLK speed. You may want to change this as well LATCH_TO_CLK_DELAY_NS
Here is that image:
Odd, DMA_UPDATES_PER_CLOCK is 2, but I cannot seem to make it 1 without it breaking. Otherwise this should also impact the rate, correct?
It needs to be 2, there are two updates, one to set the clock high, one to set the clock low.
So using 0x03 for TCD->CSR and lowering the CPU speed gets it pretty close. Is there anything else I can do to slow down the panel clock rate?
I'm surprised that the speed is based on the CPU and not the BUS speed, as I thought the DMA rate was the BUS rate.
Sorry, I'm out of ideas.
Doesn't lowering the CPU speed also lower the bus rate?
Is there a way to reduce the clock duty cycle?
not easily, it would involve writing code to insert more data (e.g. 2x CLK low cycles, 2x CLK high cycles) into the data buffer that's shifted out to GPIO, and it would multiple the amount of data used for refresh.
So the mk20dx128.c provides the configurations for F_CPU, and if coded to support it, can have the F_BUS as a lower (supported) multiple. Some already have a few options, I added a few for testing. The hope was to keep the processing power, while just reducing the bus, mainly used in this case for the Panel display. So things like GIF processing would still be ok.
Thanks for the help, the SmartMatrix code really is brilliant. Amazing to see the DMA controller leveraged this way, and the templated function and graphic buffers is a pretty clever optimization.
Will tweak out the CPU and timings with the CSR 0x03, see if its enough for these messy panels.
I wouldn't recommend using it as the project isn't released yet and I'm not actively working on it, but the SmartMatrix Library ESP32 port lets you select more arbitrary clock speeds because of the way the ESP32 DMA controller functions. It's a bit less of a hack than the Teensy, and more efficient:
https://community.pixelmatix.com/t/smartmatrix-library-esp32-port/272
Are you saying that port still works on the Teensy? I tried your teensylc branch, but it removed hooks I needed for re-arranging the incorrectly layed out sections...
In the SmartMatrix_Impl.h, I swap segments in the loadMatrixBuffers function:
if (optionFlags & SMARTMATRIX_OPTIONS_JUMBLE) {
int idx = 0;
int offset = 0;
int segment = i / 16;
// Horrible hack to re-arrange 16x32 segments from
// 0 4 2
// 3 1 5
//
// to
// 0 2 4
// 1 3 5
switch (segment) {
case 0:
idx = 0; // 12B
offset = idx * 16 + (i%16);
temp0red = tempRow1[offset].red;
temp0green = tempRow1[offset].green;
temp0blue = tempRow1[offset].blue;
idx = 6; // 11B
offset = idx * 16 + (i%16);
temp1red = tempRow1[offset].red;
temp1green = tempRow1[offset].green;
temp1blue = tempRow1[offset].blue;
break;
case 1:
idx = 1; // 12D
offset = idx * 16 + (i%16);
temp0red = tempRow1[offset].red;
temp0green = tempRow1[offset].green;
temp0blue = tempRow1[offset].blue;
idx = 7; // 11D
offset = idx * 16 + (i%16);
temp1red = tempRow1[offset].red;
temp1green = tempRow1[offset].green;
temp1blue = tempRow1[offset].blue;
break;
... through case 11
}
It should still work on the Teensy but code has been refactored a lot. It doesn't have any major Teensy-specific improvements, and won't help with your <5MHz CLK requirement. I was just mentioning that on the ESP32 the DMA clock rate (really I2S clock rate) can be set easily, and would be able to drop below 5MHz.
No luck, unfortunately. The DMA 0x03 trick helped, and changing the clock rate helps, but still can't get rid of all the artifacts. I would be interested in how to do the clk data delay, to decouple the data rate from the CPU speed some more. @embedded-creations - I sent you a PM.
I have some panels from Meiyad that in one batch worked, but in the new batch the image slowly gets worse from panel to panel. Meiyad reproduce the issue, and found a workaround was to slow the data clock to < 5MHz.
I have been tweaking the values in SmartMatrix_Impl.h and MatrixHardwareKit.h, as well as modifying the F_BUS and F_CPU speeds (by providing it both as a PLATFORMIO_BUILD_FLAG and platformio.ini board_f_cpu rate, the newest platformio overrides F_CPU using a default board_f_cpu value).
I have been able to reduce the CPU speed to reduce the distortion, but cannot get low enough to avoid the issue, as going too low breaks USB. I have been checking against the values in mk20dx128.c to use F_CPU and F_BUS rates that are supported.
Using an oscilloscope, it seems the clock value is based on the F_CPU rate and not the F_BUS rate, but is oddly F_CPU / 18. Not sure where the 18 comes from, but if I could increase that, I could leave the CPU rate alone and just slow the data clock to the panel.