Einfaches Snippet das einen im Binärfile hinterlegten BMP Font(RGB565) im Framebuffer scrollt. Jeder Buchstabe hat in der Datei seinen Startblock Ascii-Code*Width*Heigth und jede Fontgröße wiederum ihren Startblock. (Gepackt mit einem kleinen Tool für Grafiken in SPI-Flashes)
Als Grundlage installiert man rpi-update mit integriertem fbtft und aktiviert SPI.
Dann kann man zB. für das kleine HY28B display folgend Treiber laden:
modprobe dma fbtft
modprobe fbtft_device name=hy28b fbtft_device.speed=10000000 fbtft_device.rotate=90 fbtft_device.mode=3
//#include "font.h" #include <stdlib.h> #include <unistd.h> #include <stdio.h> #include <fcntl.h> #include <linux/fb.h> #include <sys/mman.h> #include <sys/ioctl.h> #include <string.h> #include <fstream> using namespace std; unsigned int BinToNum(char* b, int bytes) { unsigned int tmpx = 0; unsigned int pw = 1; for (int i = 0; i < bytes; i++) { tmpx += ((unsigned char)b[i] * pw); pw = pw * 256; } return tmpx; } int width = 320; int height = 240; int ColorBits = 16; int size = 0; unsigned short int* matrix; char* fbp = 0; int x = 0, y = 0; long int location = 0; int fbfd = 0; struct fb_var_screeninfo vinfo; struct fb_fix_screeninfo finfo; long int screensize = 0; // Liest MultiImageDatei in Array ein, Buchstaben in verschiedenen Groessen // jeweils nach Ascii-Code sortiert. int Open(const char* path) { int pad = 0; unsigned int sof = 0; unsigned int tx = 0; char tmp[4] = { 0, 0, 0, 0 }; fstream file; file.open(path, ios::in); if (file.fail()) { width = height = ColorBits = size = 0; return -1; } else { printf("The Filesizen"); file.seekg(0, file.end); size = file.tellg(); // Initialize Matrix// printf("The Filematrixn"); matrix = new (unsigned short int[size / 2]); sof = 0; int counter = 0; while (sof < size) { file.seekg(sof, ios::beg); file.read(tmp, (int)(ColorBits / 8)); tx = BinToNum(tmp, (int)(ColorBits / 8)); matrix[counter] = tx; sof += (int)(ColorBits / 8); counter++; } file.close(); return 1; } } // Framebuffer Ausschnitte auf Framebuffer selbst kopieren(Scrolling Ansatz) int blockcpfb(int source_x, int source_y, int width, int height, int dest_x, int dest_y) { for (int y = 0; y < height; y++) for (int x = 0; x < width; x++) { location = (source_x + x) * (vinfo.bits_per_pixel / 8) + (source_y + y) * 640; unsigned short int t = *((unsigned short int*)(fbp + location)); location = (dest_x + x) * (vinfo.bits_per_pixel / 8) + (dest_y + y) * 640; *((unsigned short int*)(fbp + location)) = t; } } // Kopiert Image/Buchstabe ueber Startblock aus Tabelle von array in // Framebuffer int blockcp(int start, int width, int height, int dest_x, int dest_y) { for (int y = 0; y < height; y++) for (int x = 0; x < width; x++) { location = (dest_x + x) * (vinfo.bits_per_pixel / 8) + (dest_y + y) * 640; unsigned short int t = matrix[(y * width) + start + x]; *((unsigned short int*)(fbp + location)) = t; } } // schneidet aus dem angegebenem Bildsource aus dem Array einen Bereich aus. int blockcpclipping(int start, int width, int height, int dest_x, int dest_y, int clipx, int clipy, int clipwidth, int clipheight) { for (int y = 0; y < height; y++) for (int x = 0; x < width; x++) { if (x > clipx && y > clipy && x < clipx + clipwidth && y < clipy + clipheight) { location = (dest_x + x) * (vinfo.bits_per_pixel / 8) + (dest_y + y) * 640; unsigned short int t = matrix[(y * width) + start + x]; *((unsigned short int*)(fbp + location)) = t; } } } // munmap(fbp, screensize); int main() { // Open the file for reading and writing fbfd = open("/dev/fb1", O_RDWR); if (fbfd == -1) { perror("Error: cannot open framebuffer device"); exit(1); } printf("The framebuffer device was opened successfully.n"); // Get fixed screen information if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo) == -1) { perror("Error reading fixed information"); exit(2); } // Get variable screen information if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo) == -1) { perror("Error reading variable information"); exit(3); } printf("%dx%d, %dbppn", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel); // Figure out the size of the screen in bytes screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8; // Map the device to memory fbp = (char*)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0); if ((int)fbp == -1) { perror("Error: failed to map framebuffer device to memory"); exit(4); } printf("The framebuffer device was mapped to memory successfully.n"); x = 320; y = 240; // Where we are going to put the pixel // Figure out where in memory to put the pixel if (Open("font.bin") == 1) { } string s = " Guns n Roses "; int z = 0; for (int c = 0; c <= ((int)s.length() - 4); c++) { string tmp = s.substr(c, 4); string::iterator i; for (i = tmp.begin(); i != tmp.end(); i++) { // berechnet Startblock aus Ascii Code und kopiert Buchstaben. blockcp((8330 * (((int)*i) - 32)), 70, 119, 40 + z * 70, 0); z++; } } int charspalte = 1; int mychar = 0; z = 70; char tmp = s.at(mychar); while (1) { blockcpfb(1, 0, 319, 119, 0, 0); //Einzelne Linien dem Scroll folgend einkopieren(Neuer Buchstabe erscheint komplett) // blockcpclipping( (8330*(((int)tmp)-32)),70, 119,320, // 0,charspalte,0,1,119); if (z == 70) { char tmp = s.at(mychar); blockcp((8330 * (((int)tmp) - 32)), 70, 119, 320 - 70, 0); z = 0; mychar++; charspalte = 1; if (mychar == s.length()) { mychar = 0; } } else { charspalte++; z++; } } close(fbfd); return 0; }