[SOLVED] How to access mp_obj_framebuf_t from screen's show()

C programming, build, interpreter/VM.
Target audience: MicroPython Developers.
Post Reply
User avatar
shazz
Posts: 46
Joined: Tue Apr 30, 2019 6:35 pm
Contact:

[SOLVED] How to access mp_obj_framebuf_t from screen's show()

Post by shazz » Mon May 06, 2019 1:16 am

Hi,

Within the screen driver function exposed as pyb.SCREEN.show(fb)

Code: Select all

STATIC mp_obj_t pyb_screen_show(size_t n_args, const mp_obj_t *args)
I'd like to retrieve the width, height and format of the framebuffer.

To get access to the bytearray I saw that I can do:

Code: Select all

mp_buffer_info_t bufinfo;
mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_READ);
byte *p = bufinfo.buf;
But when I try to do:

Code: Select all

mp_obj_framebuf_t *fb = MP_OBJ_TO_PTR(args[1]);
uint8_t format = fb->format; 
It doesn't compile as mp_obj_framebuf_t and FRAMEBUF_* are defined in extmod/modframebuf.c and so not public.

What the clean way to do ?

Thanks!
Last edited by shazz on Mon May 20, 2019 11:48 am, edited 1 time in total.
8bits should be enough...

User avatar
jimmo
Posts: 2754
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: How to access mp_obj_framebuf_t from screen's show()

Post by jimmo » Mon May 06, 2019 2:21 am

I assume you're talking about https://github.com/KittenBot/micropytho ... 2/screen.c which looks like meowbit's copy of the built-in pyb.LCD class.

Unless you've already made significant modifications, it doesn't look like this class interacts with framebuf at all? i.e. it's not written specifically with the mp_obj_framebuf_t type in mind.

It looks like the API is actually that you pass a buffer object (e.g. bytearray or a framebuf) to show. So there is no "width and height of the framebuffer" as such, it's literally just the bytes. So if you're prepared to make it only work with framebuf.FrameBuffer, then the way to do this is to add extmod/modframebuf.h and move the definition of the mp_obj_framebuf_t struct there.

FYI: For questions like this it's good to include the relevant context (this is for a meowbit, the repo is at URL, i've made these changes, etc) just in case people haven't seen your other threads.

User avatar
shazz
Posts: 46
Joined: Tue Apr 30, 2019 6:35 pm
Contact:

Re: How to access mp_obj_framebuf_t from screen's show()

Post by shazz » Mon May 06, 2019 12:51 pm

Sorry, I tried to be generic but it did not help :)

So, let's explain what I try do do. In the coming sentences, I will probably write a lot of nonsense, feel free to fix me.

Board: Meowbit (with TFT screen), but may be applicable to any board with a screen.

Constraints:
- Most of their boards are relatively powerful (CPU/Bus... around 50-100MHz) but most of them have very little RAM (arounf 100K).
- Contrary to computers, everything is I/O, no memory map, no VBL/HBL/interrupts, no blitter... so LCD controller framebuffer cannot be easily used by the MCU.

Assumption, the framebuf.FrameBuffer MicroPython class is multiple things:
- a software framebuffer (as the real one cannot be used as is) to be used by program and which will eventually be sent to replace the real framebuffer.
- a helper to provide some high level operations (pixels, lines, rect, scroll...).
- a way to save RAM by implementing in software low level resolution compared to the TFT.
- more or less decoupled from LCD specs, the driver will convert the Framebuffer to the supported modes (resolution, pixel encoding, pixel organization...).

Consequences:
- if your goal is blitting speed and not RAM, use a framebuf as similar as the real framebuffer specs.
- if your goal is to save memory, use an smaller framebuf (grayscale, palette-indexed,...) and the driver will do the job (at a CPU cost).

So to achieve this goal, I modified the framebuf C implementation (https://github.com/KittenBot/micropytho ... framebuf.c) to support 2 new modes:
- PAL16 (4bit per pixel, 16 colors available, multiple hardcoded palettes selectable (C64, Spectrum,...))
- PAL256 (8bit per pixel, 256 colors available, multiple hardcoded palettes selectable (MSX,...))
In this case , the bytearray attached to the Framebuf is smaller than the TFT 160x128x16bits real framebuffer size (Meowbit init mode for the ST)

Then I modified the screen.c (https://github.com/KittenBot/micropytho ... 2/screen.c) file which implements the driver for the ST used by the Meowbit:
When calling pyb.SCREEN.show(fb), the code has to:
- check the fb widtrh, height, format and accordingly will process the bytearray to tranfer the equivalent of a 160x128x2 array.

1. if the Framebuffer is 160x128 in RGB565 mode, nothing to do, DMA powered SPI transfer.
2. if not, pixel per pixel, the byterarray will be converted to a RGB565 pixel and transfered thru the SPI interface.

Now the implementation:
- the format, width, height are stored in the mp_obj_framebuf_t struct and I need them in show(fb) to know what the bytearray is (ref: http://meowbit-doc.kittenbot.cn/#/micro ... E%E7%A4%BA)
- the current code uses this snippet to get the bytearray:

Code: Select all

mp_buffer_info_t bufinfo;
mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_READ);
byte *p = bufinfo.buf;
- as the struct mp_obj_framebuf_t and FRAMEBUF_* are defined in modframebuf.c, there are not public so this code does not compile:

Code: Select all

mp_obj_framebuf_t *fb = MP_OBJ_TO_PTR(args[1]);
uint8_t format = fb->format; 
As a result my questions are:
- are my assumptions right or wrong ?
- is there a better way to do ?
- if not, why mp_obj_framebuf_t and defines are not exposed in a .h file ? Is there a good reason ? Else I will create it as you suggested.
8bits should be enough...

Post Reply