How to draw on a small TFT screen, after the end of the linux boot, (on a rPI)

70 views Asked by At

I managed to have a TFT screen (160*128) working on my PI (via SPI)

When the system boots, I can see the end of the boot and at the very end, the "login:"

I would like to have a program (text terminal, or graphical program, not sure yet) to start à the very end of the boot process, and use the tft screen as its STD output. I don't have X running.

(/dev/fb0 is created, when I plug in a screen it becomes /dev/fb1, but I managed to hav a /dev/fbTFT)

1/ should I disable the gettys ? (how ?) 2/ how can I have a python (or C) program start at the end of the boot and use the console as STDout ? (I don't have a keyboard) 3 should I use libcurses (text mode) ?

I can display a picture using fbi -d /dev/fbTFT -T 1 -noverbose -a cat.jpg (shows a cat)

1

There are 1 answers

0
Aruna Jayasena On

For this, you can directly dump pixel values to the direct memory corresponding to the frame buffer. Following code is an example code that I have created for this use case based on the answer from here,

import os
import sys  # for exit
import mmap # shared memory

frame_buffer_number = 'fb0'   # device created by the device driver

# get width and height
f = open(f"/sys/class/graphics/{frame_buffer_number}/virtual_size", "r")
width_and_height = f.read()
width_string, height_string = width_and_height.split(',')
width = int(width_string) # width
height = int(height_string) # height
f.close


# get bits per pixel
f = open(f"/sys/class/graphics/{frame_buffer_number}/bits_per_pixel", "r")
bpp = int(f.read())
if not bpp in (16, 32):
    print("Unsupported bpp")
    sys.exit()
f.close()

print(f"width: {width}, height: {height}, bpp: {bpp}")

# open framebuffer and map it onto a python bytearray
frame_buffer_device = open(f"/dev/{frame_buffer_number}", mode='r+b') # open R/W
frame_buffer_memory_map = mmap.mmap(frame_buffer_device.fileno(), width * height * bpp//8, mmap.MAP_SHARED, mmap.PROT_WRITE | mmap.PROT_READ)


# Copy the image pixel data to the framebuffer
for y in range(height):
    for x in range(width):
        r, g, b = 120, 120, 200
        
        # Calculate the offset in framebuffer memory
        offset = (y * width + x) * 2

        # Convert RGB values to 16-bit code
        code = ((r & 0x1F) << 11) | ((g & 0x3F) << 5) | (b & 0x1F)

        # Write the 16-bit code to the framebuffer mmap
        frame_buffer_memory_map[offset] = code & 0xFF
        frame_buffer_memory_map[offset + 1] = (code >> 8) & 0xFF

        

#Close the framebuffer device and mmap
frame_buffer_memory_map.close()
frame_buffer_device.close()

Once the code is changed according to your requirements, put it in the /etc/rc.local as follows,

python3 path/to/your/code &
exit0

This will write directly to the memory of the framebuffer and draw stuff over it.