1351f683bSMiguel Ojeda // SPDX-License-Identifier: GPL-2.0 28fc07ebeSShuah Khan /* 38fc07ebeSShuah Khan * Filename: cfag12864b-example.c 48fc07ebeSShuah Khan * Version: 0.1.0 58fc07ebeSShuah Khan * Description: cfag12864b LCD userspace example program 68fc07ebeSShuah Khan * 7*c131bd0bSMiguel Ojeda * Author: Copyright (C) Miguel Ojeda <ojeda@kernel.org> 88fc07ebeSShuah Khan * Date: 2006-10-31 98fc07ebeSShuah Khan */ 108fc07ebeSShuah Khan 118fc07ebeSShuah Khan /* 128fc07ebeSShuah Khan * ------------------------ 138fc07ebeSShuah Khan * start of cfag12864b code 148fc07ebeSShuah Khan * ------------------------ 158fc07ebeSShuah Khan */ 168fc07ebeSShuah Khan 178fc07ebeSShuah Khan #include <string.h> 188fc07ebeSShuah Khan #include <fcntl.h> 198fc07ebeSShuah Khan #include <unistd.h> 208fc07ebeSShuah Khan #include <sys/types.h> 218fc07ebeSShuah Khan #include <sys/stat.h> 228fc07ebeSShuah Khan #include <sys/mman.h> 238fc07ebeSShuah Khan 248fc07ebeSShuah Khan #define CFAG12864B_WIDTH (128) 258fc07ebeSShuah Khan #define CFAG12864B_HEIGHT (64) 268fc07ebeSShuah Khan #define CFAG12864B_SIZE (128 * 64 / 8) 278fc07ebeSShuah Khan #define CFAG12864B_BPB (8) 288fc07ebeSShuah Khan #define CFAG12864B_ADDRESS(x, y) ((y) * CFAG12864B_WIDTH / \ 298fc07ebeSShuah Khan CFAG12864B_BPB + (x) / CFAG12864B_BPB) 308fc07ebeSShuah Khan #define CFAG12864B_BIT(n) (((unsigned char) 1) << (n)) 318fc07ebeSShuah Khan 328fc07ebeSShuah Khan #undef CFAG12864B_DOCHECK 338fc07ebeSShuah Khan #ifdef CFAG12864B_DOCHECK 348fc07ebeSShuah Khan #define CFAG12864B_CHECK(x, y) ((x) < CFAG12864B_WIDTH && \ 358fc07ebeSShuah Khan (y) < CFAG12864B_HEIGHT) 368fc07ebeSShuah Khan #else 378fc07ebeSShuah Khan #define CFAG12864B_CHECK(x, y) (1) 388fc07ebeSShuah Khan #endif 398fc07ebeSShuah Khan 408fc07ebeSShuah Khan int cfag12864b_fd; 418fc07ebeSShuah Khan unsigned char * cfag12864b_mem; 428fc07ebeSShuah Khan unsigned char cfag12864b_buffer[CFAG12864B_SIZE]; 438fc07ebeSShuah Khan 448fc07ebeSShuah Khan /* 458fc07ebeSShuah Khan * init a cfag12864b framebuffer device 468fc07ebeSShuah Khan * 478fc07ebeSShuah Khan * No error: return = 0 488fc07ebeSShuah Khan * Unable to open: return = -1 498fc07ebeSShuah Khan * Unable to mmap: return = -2 508fc07ebeSShuah Khan */ 518fc07ebeSShuah Khan static int cfag12864b_init(char *path) 528fc07ebeSShuah Khan { 538fc07ebeSShuah Khan cfag12864b_fd = open(path, O_RDWR); 548fc07ebeSShuah Khan if (cfag12864b_fd == -1) 558fc07ebeSShuah Khan return -1; 568fc07ebeSShuah Khan 578fc07ebeSShuah Khan cfag12864b_mem = mmap(0, CFAG12864B_SIZE, PROT_READ | PROT_WRITE, 588fc07ebeSShuah Khan MAP_SHARED, cfag12864b_fd, 0); 598fc07ebeSShuah Khan if (cfag12864b_mem == MAP_FAILED) { 608fc07ebeSShuah Khan close(cfag12864b_fd); 618fc07ebeSShuah Khan return -2; 628fc07ebeSShuah Khan } 638fc07ebeSShuah Khan 648fc07ebeSShuah Khan return 0; 658fc07ebeSShuah Khan } 668fc07ebeSShuah Khan 678fc07ebeSShuah Khan /* 688fc07ebeSShuah Khan * exit a cfag12864b framebuffer device 698fc07ebeSShuah Khan */ 708fc07ebeSShuah Khan static void cfag12864b_exit(void) 718fc07ebeSShuah Khan { 728fc07ebeSShuah Khan munmap(cfag12864b_mem, CFAG12864B_SIZE); 738fc07ebeSShuah Khan close(cfag12864b_fd); 748fc07ebeSShuah Khan } 758fc07ebeSShuah Khan 768fc07ebeSShuah Khan /* 778fc07ebeSShuah Khan * set (x, y) pixel 788fc07ebeSShuah Khan */ 798fc07ebeSShuah Khan static void cfag12864b_set(unsigned char x, unsigned char y) 808fc07ebeSShuah Khan { 818fc07ebeSShuah Khan if (CFAG12864B_CHECK(x, y)) 828fc07ebeSShuah Khan cfag12864b_buffer[CFAG12864B_ADDRESS(x, y)] |= 838fc07ebeSShuah Khan CFAG12864B_BIT(x % CFAG12864B_BPB); 848fc07ebeSShuah Khan } 858fc07ebeSShuah Khan 868fc07ebeSShuah Khan /* 878fc07ebeSShuah Khan * unset (x, y) pixel 888fc07ebeSShuah Khan */ 898fc07ebeSShuah Khan static void cfag12864b_unset(unsigned char x, unsigned char y) 908fc07ebeSShuah Khan { 918fc07ebeSShuah Khan if (CFAG12864B_CHECK(x, y)) 928fc07ebeSShuah Khan cfag12864b_buffer[CFAG12864B_ADDRESS(x, y)] &= 938fc07ebeSShuah Khan ~CFAG12864B_BIT(x % CFAG12864B_BPB); 948fc07ebeSShuah Khan } 958fc07ebeSShuah Khan 968fc07ebeSShuah Khan /* 978fc07ebeSShuah Khan * is set (x, y) pixel? 988fc07ebeSShuah Khan * 998fc07ebeSShuah Khan * Pixel off: return = 0 1008fc07ebeSShuah Khan * Pixel on: return = 1 1018fc07ebeSShuah Khan */ 1028fc07ebeSShuah Khan static unsigned char cfag12864b_isset(unsigned char x, unsigned char y) 1038fc07ebeSShuah Khan { 1048fc07ebeSShuah Khan if (CFAG12864B_CHECK(x, y)) 1058fc07ebeSShuah Khan if (cfag12864b_buffer[CFAG12864B_ADDRESS(x, y)] & 1068fc07ebeSShuah Khan CFAG12864B_BIT(x % CFAG12864B_BPB)) 1078fc07ebeSShuah Khan return 1; 1088fc07ebeSShuah Khan 1098fc07ebeSShuah Khan return 0; 1108fc07ebeSShuah Khan } 1118fc07ebeSShuah Khan 1128fc07ebeSShuah Khan /* 1138fc07ebeSShuah Khan * not (x, y) pixel 1148fc07ebeSShuah Khan */ 1158fc07ebeSShuah Khan static void cfag12864b_not(unsigned char x, unsigned char y) 1168fc07ebeSShuah Khan { 1178fc07ebeSShuah Khan if (cfag12864b_isset(x, y)) 1188fc07ebeSShuah Khan cfag12864b_unset(x, y); 1198fc07ebeSShuah Khan else 1208fc07ebeSShuah Khan cfag12864b_set(x, y); 1218fc07ebeSShuah Khan } 1228fc07ebeSShuah Khan 1238fc07ebeSShuah Khan /* 1248fc07ebeSShuah Khan * fill (set all pixels) 1258fc07ebeSShuah Khan */ 1268fc07ebeSShuah Khan static void cfag12864b_fill(void) 1278fc07ebeSShuah Khan { 1288fc07ebeSShuah Khan unsigned short i; 1298fc07ebeSShuah Khan 1308fc07ebeSShuah Khan for (i = 0; i < CFAG12864B_SIZE; i++) 1318fc07ebeSShuah Khan cfag12864b_buffer[i] = 0xFF; 1328fc07ebeSShuah Khan } 1338fc07ebeSShuah Khan 1348fc07ebeSShuah Khan /* 1358fc07ebeSShuah Khan * clear (unset all pixels) 1368fc07ebeSShuah Khan */ 1378fc07ebeSShuah Khan static void cfag12864b_clear(void) 1388fc07ebeSShuah Khan { 1398fc07ebeSShuah Khan unsigned short i; 1408fc07ebeSShuah Khan 1418fc07ebeSShuah Khan for (i = 0; i < CFAG12864B_SIZE; i++) 1428fc07ebeSShuah Khan cfag12864b_buffer[i] = 0; 1438fc07ebeSShuah Khan } 1448fc07ebeSShuah Khan 1458fc07ebeSShuah Khan /* 1468fc07ebeSShuah Khan * format a [128*64] matrix 1478fc07ebeSShuah Khan * 1488fc07ebeSShuah Khan * Pixel off: src[i] = 0 1498fc07ebeSShuah Khan * Pixel on: src[i] > 0 1508fc07ebeSShuah Khan */ 1518fc07ebeSShuah Khan static void cfag12864b_format(unsigned char * matrix) 1528fc07ebeSShuah Khan { 1538fc07ebeSShuah Khan unsigned char i, j, n; 1548fc07ebeSShuah Khan 1558fc07ebeSShuah Khan for (i = 0; i < CFAG12864B_HEIGHT; i++) 1568fc07ebeSShuah Khan for (j = 0; j < CFAG12864B_WIDTH / CFAG12864B_BPB; j++) { 1578fc07ebeSShuah Khan cfag12864b_buffer[i * CFAG12864B_WIDTH / CFAG12864B_BPB + 1588fc07ebeSShuah Khan j] = 0; 1598fc07ebeSShuah Khan for (n = 0; n < CFAG12864B_BPB; n++) 1608fc07ebeSShuah Khan if (matrix[i * CFAG12864B_WIDTH + 1618fc07ebeSShuah Khan j * CFAG12864B_BPB + n]) 1628fc07ebeSShuah Khan cfag12864b_buffer[i * CFAG12864B_WIDTH / 1638fc07ebeSShuah Khan CFAG12864B_BPB + j] |= 1648fc07ebeSShuah Khan CFAG12864B_BIT(n); 1658fc07ebeSShuah Khan } 1668fc07ebeSShuah Khan } 1678fc07ebeSShuah Khan 1688fc07ebeSShuah Khan /* 1698fc07ebeSShuah Khan * blit buffer to lcd 1708fc07ebeSShuah Khan */ 1718fc07ebeSShuah Khan static void cfag12864b_blit(void) 1728fc07ebeSShuah Khan { 1738fc07ebeSShuah Khan memcpy(cfag12864b_mem, cfag12864b_buffer, CFAG12864B_SIZE); 1748fc07ebeSShuah Khan } 1758fc07ebeSShuah Khan 1768fc07ebeSShuah Khan /* 1778fc07ebeSShuah Khan * ---------------------- 1788fc07ebeSShuah Khan * end of cfag12864b code 1798fc07ebeSShuah Khan * ---------------------- 1808fc07ebeSShuah Khan */ 1818fc07ebeSShuah Khan 1828fc07ebeSShuah Khan #include <stdio.h> 1838fc07ebeSShuah Khan 1848fc07ebeSShuah Khan #define EXAMPLES 6 1858fc07ebeSShuah Khan 1868fc07ebeSShuah Khan static void example(unsigned char n) 1878fc07ebeSShuah Khan { 1888fc07ebeSShuah Khan unsigned short i, j; 1898fc07ebeSShuah Khan unsigned char matrix[CFAG12864B_WIDTH * CFAG12864B_HEIGHT]; 1908fc07ebeSShuah Khan 1918fc07ebeSShuah Khan if (n > EXAMPLES) 1928fc07ebeSShuah Khan return; 1938fc07ebeSShuah Khan 1948fc07ebeSShuah Khan printf("Example %i/%i - ", n, EXAMPLES); 1958fc07ebeSShuah Khan 1968fc07ebeSShuah Khan switch (n) { 1978fc07ebeSShuah Khan case 1: 1988fc07ebeSShuah Khan printf("Draw points setting bits"); 1998fc07ebeSShuah Khan cfag12864b_clear(); 2008fc07ebeSShuah Khan for (i = 0; i < CFAG12864B_WIDTH; i += 2) 2018fc07ebeSShuah Khan for (j = 0; j < CFAG12864B_HEIGHT; j += 2) 2028fc07ebeSShuah Khan cfag12864b_set(i, j); 2038fc07ebeSShuah Khan break; 2048fc07ebeSShuah Khan 2058fc07ebeSShuah Khan case 2: 2068fc07ebeSShuah Khan printf("Clear the LCD"); 2078fc07ebeSShuah Khan cfag12864b_clear(); 2088fc07ebeSShuah Khan break; 2098fc07ebeSShuah Khan 2108fc07ebeSShuah Khan case 3: 2118fc07ebeSShuah Khan printf("Draw rows formatting a [128*64] matrix"); 2128fc07ebeSShuah Khan memset(matrix, 0, CFAG12864B_WIDTH * CFAG12864B_HEIGHT); 2138fc07ebeSShuah Khan for (i = 0; i < CFAG12864B_WIDTH; i++) 2148fc07ebeSShuah Khan for (j = 0; j < CFAG12864B_HEIGHT; j += 2) 2158fc07ebeSShuah Khan matrix[j * CFAG12864B_WIDTH + i] = 1; 2168fc07ebeSShuah Khan cfag12864b_format(matrix); 2178fc07ebeSShuah Khan break; 2188fc07ebeSShuah Khan 2198fc07ebeSShuah Khan case 4: 2208fc07ebeSShuah Khan printf("Fill the lcd"); 2218fc07ebeSShuah Khan cfag12864b_fill(); 2228fc07ebeSShuah Khan break; 2238fc07ebeSShuah Khan 2248fc07ebeSShuah Khan case 5: 2258fc07ebeSShuah Khan printf("Draw columns unsetting bits"); 2268fc07ebeSShuah Khan for (i = 0; i < CFAG12864B_WIDTH; i += 2) 2278fc07ebeSShuah Khan for (j = 0; j < CFAG12864B_HEIGHT; j++) 2288fc07ebeSShuah Khan cfag12864b_unset(i, j); 2298fc07ebeSShuah Khan break; 2308fc07ebeSShuah Khan 2318fc07ebeSShuah Khan case 6: 2328fc07ebeSShuah Khan printf("Do negative not-ing all bits"); 2338fc07ebeSShuah Khan for (i = 0; i < CFAG12864B_WIDTH; i++) 2348fc07ebeSShuah Khan for (j = 0; j < CFAG12864B_HEIGHT; j ++) 2358fc07ebeSShuah Khan cfag12864b_not(i, j); 2368fc07ebeSShuah Khan break; 2378fc07ebeSShuah Khan } 2388fc07ebeSShuah Khan 2398fc07ebeSShuah Khan puts(" - [Press Enter]"); 2408fc07ebeSShuah Khan } 2418fc07ebeSShuah Khan 2428fc07ebeSShuah Khan int main(int argc, char *argv[]) 2438fc07ebeSShuah Khan { 2448fc07ebeSShuah Khan unsigned char n; 2458fc07ebeSShuah Khan 2468fc07ebeSShuah Khan if (argc != 2) { 2478fc07ebeSShuah Khan printf( 2486c4d6bc5SMasanari Iida "Syntax: %s fbdev\n" 2498fc07ebeSShuah Khan "Usually: /dev/fb0, /dev/fb1...\n", argv[0]); 2508fc07ebeSShuah Khan return -1; 2518fc07ebeSShuah Khan } 2528fc07ebeSShuah Khan 2538fc07ebeSShuah Khan if (cfag12864b_init(argv[1])) { 2548fc07ebeSShuah Khan printf("Can't init %s fbdev\n", argv[1]); 2558fc07ebeSShuah Khan return -2; 2568fc07ebeSShuah Khan } 2578fc07ebeSShuah Khan 2588fc07ebeSShuah Khan for (n = 1; n <= EXAMPLES; n++) { 2598fc07ebeSShuah Khan example(n); 2608fc07ebeSShuah Khan cfag12864b_blit(); 2618fc07ebeSShuah Khan while (getchar() != '\n'); 2628fc07ebeSShuah Khan } 2638fc07ebeSShuah Khan 2648fc07ebeSShuah Khan cfag12864b_exit(); 2658fc07ebeSShuah Khan 2668fc07ebeSShuah Khan return 0; 2678fc07ebeSShuah Khan } 268