david-res / ILI948x_t41_p

A basic display driver for ILI948X series on a Teensy 4.1
4 stars 1 forks source link

Fix for BUS_WIDTH = 16 #5

Open rjonkman opened 1 year ago

rjonkman commented 1 year ago

https://github.com/david-res/ILI948x_t41_p/blob/c32394e93f48281abef15915b0b2549ed413803a/ILI948x_t41_p.cpp#L875

I had to change this to:

   #if BUS_WIDTH == 16
    uint8_t beats = SHIFTNUM * BEATS_PER_SHIFTER / 2;
    #else
    uint8_t beats = SHIFTNUM * BEATS_PER_SHIFTER;
    #endif
rjonkman commented 1 year ago

This doesn't seem to be a complete fix. It does cause the correct pixel to be lit on the screen, but colors are not correct. They seem to be inverted perhaps? For example, a pixel that should be green is red.

Is this definition correct? I'm not entirely sure what it's used for, but If we are using a 16 bit bus mode, wouldn't it be sending two bytes per beat? #define BYTES_PER_BEAT (sizeof(uint8_t))

rjonkman commented 1 year ago

To get the colors right, a had to replace the 16bit bytes swap in flexIRQ_Callback() with a 32bit swap. I imagine this should be included even in your library for a 8bit interface.

 p->SHIFTBUFBYS[i] = ((((data) & 0xff000000) >> 24) |
                    (((data) & 0x00ff0000) >> 8) |
                    (((data) & 0x0000ff00) << 8) |
                    (((data) & 0x000000ff) << 24));
rjonkman commented 1 year ago

That last issue I'm having with your code is that the aync methods are running too fast , even as the lowest baud setting. Is there any way to slow everything down some more?

david-res commented 1 year ago

To get the colors right, a had to replace the 16bit bytes swap in flexIRQ_Callback() with a 32bit swap. I imagine this should be included even in your library for a 8bit interface.

 p->SHIFTBUFBYS[i] = ((((data) & 0xff000000) >> 24) |
                    (((data) & 0x00ff0000) >> 8) |
                    (((data) & 0x0000ff00) << 8) |
                    (((data) & 0x000000ff) << 24));

SHIFTBUFBYS does a byte swap Try changing to SHIFTBUF

That swaps the bytes around

You can find more info here on the various methods: https://community.nxp.com/t5/Kinetis-Microcontrollers/Understanding-FlexIO/ta-p/1115419

david-res commented 1 year ago

That last issue I'm having with your code is that the aync methods are running too fast , even as the lowest baud setting. Is there any way to slow everything down some more?

You can try to lower the FlexIO clock speed by dividing down the source clock in the FlexIO_init function IIRC it's running at 240Mhz at the moment. You can go down to 120/6030 etc by increasing the divider value

It's important to note that the baud rate of the bus is derived from the FlexIO clock speed, so if you were running at 20Mhz and you lower the FlexIO clock speed to 120 from 240, your new bus speed would be half of 20Mhz..

rjonkman commented 1 year ago

Hi,

Thanks, SHIFTBUF works perfectly on the RA9975 without any byte swapping. Unfortunately, as I go over the finer details of the code, if I'm already at the lowest baud setting, having the FlexIO clock is not going to help.

I can get it stable-ish by reducing the number of shifters and adding a microsecond delay inside the interupt callback, but I still end up with some pixels that don't get lit properly, and because I'm mirroring the the screen pixels in EXTMEM and only updating the ones that change, some of those pixels just never get drawn properly. So I'm stuck using the blocking methods to push pixels--such a shame. I pretty much only need the device to handle the display. I have a few other time sensitive things I need to do, but I should be able to put them into their own interrupt routines.

david-res commented 1 year ago

I have a possible solution Use a boolean to determine if the interrupt has triggered or not. In your main loop use a delay without delay loop to check if the bool is true - run the IRQ routine then set the bool back to false. You can set the time between checks at your desired intervals.

rjonkman commented 1 year ago

That's essentially the same thing I've done my putting a delay inside the internet. The problem is that shifters are sending out the bit too quickly. If I have 8 shifters, thats 16 pixels that are being sent at a time and I have to way to slow them down. I'll play around with overclocking the display. Maybe I can get it to run a bit faster and keep up.

On Sun., Oct. 1, 2023, 21:41 david-res, @.***> wrote:

I have a possible solution Use a boolean to determine if the interrupt has triggered or not. In your main loop use a delay without delay loop to check if the bool is true - run the IRQ routine then set the bool back to false. You can set the time between checks at your desired intervals.

— Reply to this email directly, view it on GitHub https://github.com/david-res/ILI948x_t41_p/issues/5#issuecomment-1742085661, or unsubscribe https://github.com/notifications/unsubscribe-auth/AEHBO6267PWOWHEQD4IU7KTX5FXG3ANCNFSM6AAAAAA5D7PVKY . You are receiving this because you authored the thread.Message ID: @.***>

rjonkman commented 1 year ago

Couldn't make any progress by overclocking. There must be some other limit to how fast the RA8875 can process pixels. I restored to progressively drawing to the screen line by line each time through the loop(). It works great and I can tend to other other small tasks while the screen is in the process of being drawn.