Skip to content

JC4827W543 + Touch 911 #312

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

Open
straga opened this issue Mar 9, 2025 · 3 comments
Open

JC4827W543 + Touch 911 #312

straga opened this issue Mar 9, 2025 · 3 comments

Comments

@straga
Copy link

straga commented Mar 9, 2025

LCD: NV3041A QSPI
TOUCH: GT911 I2C

LCD Back View

continue from: #251

  • need inverter mode
  • turn on swap
  • send tx_color data by chuck

Now, the right color and rotation only work 0 and 180.
Probably not real NV3041A.
Config:
https://github.com/straga/micropython_lcd/blob/master/device/JC4827W543/lv_config.py

@kdschlosser
Copy link
Collaborator

The only place I see there being a potential problem with the driver is here...

def _flush_ready_cb(self, *_):
        # since there are 2 transfers that take place we need to
        # make sure that flush ready is only called after the second part
        # of the buffer has sent.
        self.__flush_ready_count += 1
        if self.__flush_ready_count == 2:
            self._disp_drv.flush_ready()
            self.__flush_ready_count = 0

    def _flush_cb(self, _, area, color_p):

        x1 = area.x1 + self._offset_x
        x2 = area.x2 + self._offset_x

        y1 = area.y1 + self._offset_y
        y2 = area.y2 + self._offset_y

        self._set_memory_location(x1, y1, x2, y2)

        width = x2 - x1 + 1
        height = y2 - y1 + 1
        size = width * height * lv.color_format_get_size(self._color_space)

        data_view = color_p.__dereference__(size)

        chunk_size = 1024 * 10
        for i in range(0, size, chunk_size):
            chunk = data_view[i:i + chunk_size]
            if i == 0:
                self._data_bus.tx_color(self.__ramwr, chunk, x1, y1, x2, y2, self._rotation, False)
            else:
                self._data_bus.tx_color(self.__ramwrc, chunk, x1, y1, x2, y2,  self._rotation, self._disp_drv.flush_is_last())

If the flush function ends up transmitting more than 2 chunks the buffers will go out of sync and if an odd number of chunks gets transmitted the code will end up locking up and doing nothing. This problem will only be apparent if double buffering is used.

This is where the problem will stem from.

def _flush_ready_cb(self, *_):
        # since there are 2 transfers that take place we need to
        # make sure that flush ready is only called after the second part
        # of the buffer has sent.
        self.__flush_ready_count += 1
        if self.__flush_ready_count == 2:
            self._disp_drv.flush_ready()
            self.__flush_ready_count = 0

I am guessing the display has a maximum data size that it is able to transfer in a single go. We know the frame buffer must match the display size.

the code above needs to change to..

def _flush_ready_cb(self, *_):
        self.__flush_ready_count += 1
        if self.__flush_ready_count == self.__num_chunks:
            self._disp_drv.flush_ready()
            self.__flush_ready_count = 0

and this code needs to be added to the __init__ method at the end of it.

    size = self.display_width * self.display_height * lv.color_format_get_size(self._color_space)
    self.__num_chunks = int(round(size / (1024 * 10)))

we should be able to combine the RGB driver into the same class as the SPI driver as well.

@straga
Copy link
Author

straga commented Mar 10, 2025

Thanks a lot for the feedback. I am upgrade driver.
(https://github.com/straga/micropython_lcd/blob/master/device/JC4827W543/nv3041aG.py)

This change:

Uses integer division () with ceiling instead of [round()]

The formula (size + chunk_size - 1) // chunk_size ensures:
If size is exactly divisible by chunk_size, you get the exact number of chunks
If there's a remainder, you get one extra chunk to handle the remaining data
For example:
If size is 30KB and chunk_size is 10KB: (30000 + 9999) // 10000 = 3 chunks
If size is 25KB and chunk_size is 10KB: (25000 + 9999) // 10000 = 3 chunks (2 full chunks + 1 partial)

@kdschlosser
Copy link
Collaborator

That looks a lot better. That will make sure that LVGL is only being told that the flush is ready a single time for each buffer.
Now you should be able to use DMA memory and use double buffering. That will greatly speed things up that's for sure.

I have been working on a way to be able to use partial buffers with display IC's that flush full buffers like this. This is currently done for RGB displays. It would speed things up that's for sure because LVGL doesn't need to render the entire displays worth of data that way and the copying of the partial to the full buffer takes place on the second CPU core so LVGL is able to render to the second partial buffer while the first partial buffer is being copied to the full buffer. When the update run from LVGL has finished is when that full buffer will get written to the display.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants