162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Filename: cfag12864b-example.c 462306a36Sopenharmony_ci * Version: 0.1.0 562306a36Sopenharmony_ci * Description: cfag12864b LCD userspace example program 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Author: Copyright (C) Miguel Ojeda <ojeda@kernel.org> 862306a36Sopenharmony_ci * Date: 2006-10-31 962306a36Sopenharmony_ci */ 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci/* 1262306a36Sopenharmony_ci * ------------------------ 1362306a36Sopenharmony_ci * start of cfag12864b code 1462306a36Sopenharmony_ci * ------------------------ 1562306a36Sopenharmony_ci */ 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci#include <string.h> 1862306a36Sopenharmony_ci#include <fcntl.h> 1962306a36Sopenharmony_ci#include <unistd.h> 2062306a36Sopenharmony_ci#include <sys/types.h> 2162306a36Sopenharmony_ci#include <sys/stat.h> 2262306a36Sopenharmony_ci#include <sys/mman.h> 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci#define CFAG12864B_WIDTH (128) 2562306a36Sopenharmony_ci#define CFAG12864B_HEIGHT (64) 2662306a36Sopenharmony_ci#define CFAG12864B_SIZE (128 * 64 / 8) 2762306a36Sopenharmony_ci#define CFAG12864B_BPB (8) 2862306a36Sopenharmony_ci#define CFAG12864B_ADDRESS(x, y) ((y) * CFAG12864B_WIDTH / \ 2962306a36Sopenharmony_ci CFAG12864B_BPB + (x) / CFAG12864B_BPB) 3062306a36Sopenharmony_ci#define CFAG12864B_BIT(n) (((unsigned char) 1) << (n)) 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci#undef CFAG12864B_DOCHECK 3362306a36Sopenharmony_ci#ifdef CFAG12864B_DOCHECK 3462306a36Sopenharmony_ci #define CFAG12864B_CHECK(x, y) ((x) < CFAG12864B_WIDTH && \ 3562306a36Sopenharmony_ci (y) < CFAG12864B_HEIGHT) 3662306a36Sopenharmony_ci#else 3762306a36Sopenharmony_ci #define CFAG12864B_CHECK(x, y) (1) 3862306a36Sopenharmony_ci#endif 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ciint cfag12864b_fd; 4162306a36Sopenharmony_ciunsigned char * cfag12864b_mem; 4262306a36Sopenharmony_ciunsigned char cfag12864b_buffer[CFAG12864B_SIZE]; 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci/* 4562306a36Sopenharmony_ci * init a cfag12864b framebuffer device 4662306a36Sopenharmony_ci * 4762306a36Sopenharmony_ci * No error: return = 0 4862306a36Sopenharmony_ci * Unable to open: return = -1 4962306a36Sopenharmony_ci * Unable to mmap: return = -2 5062306a36Sopenharmony_ci */ 5162306a36Sopenharmony_cistatic int cfag12864b_init(char *path) 5262306a36Sopenharmony_ci{ 5362306a36Sopenharmony_ci cfag12864b_fd = open(path, O_RDWR); 5462306a36Sopenharmony_ci if (cfag12864b_fd == -1) 5562306a36Sopenharmony_ci return -1; 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci cfag12864b_mem = mmap(0, CFAG12864B_SIZE, PROT_READ | PROT_WRITE, 5862306a36Sopenharmony_ci MAP_SHARED, cfag12864b_fd, 0); 5962306a36Sopenharmony_ci if (cfag12864b_mem == MAP_FAILED) { 6062306a36Sopenharmony_ci close(cfag12864b_fd); 6162306a36Sopenharmony_ci return -2; 6262306a36Sopenharmony_ci } 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci return 0; 6562306a36Sopenharmony_ci} 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci/* 6862306a36Sopenharmony_ci * exit a cfag12864b framebuffer device 6962306a36Sopenharmony_ci */ 7062306a36Sopenharmony_cistatic void cfag12864b_exit(void) 7162306a36Sopenharmony_ci{ 7262306a36Sopenharmony_ci munmap(cfag12864b_mem, CFAG12864B_SIZE); 7362306a36Sopenharmony_ci close(cfag12864b_fd); 7462306a36Sopenharmony_ci} 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci/* 7762306a36Sopenharmony_ci * set (x, y) pixel 7862306a36Sopenharmony_ci */ 7962306a36Sopenharmony_cistatic void cfag12864b_set(unsigned char x, unsigned char y) 8062306a36Sopenharmony_ci{ 8162306a36Sopenharmony_ci if (CFAG12864B_CHECK(x, y)) 8262306a36Sopenharmony_ci cfag12864b_buffer[CFAG12864B_ADDRESS(x, y)] |= 8362306a36Sopenharmony_ci CFAG12864B_BIT(x % CFAG12864B_BPB); 8462306a36Sopenharmony_ci} 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci/* 8762306a36Sopenharmony_ci * unset (x, y) pixel 8862306a36Sopenharmony_ci */ 8962306a36Sopenharmony_cistatic void cfag12864b_unset(unsigned char x, unsigned char y) 9062306a36Sopenharmony_ci{ 9162306a36Sopenharmony_ci if (CFAG12864B_CHECK(x, y)) 9262306a36Sopenharmony_ci cfag12864b_buffer[CFAG12864B_ADDRESS(x, y)] &= 9362306a36Sopenharmony_ci ~CFAG12864B_BIT(x % CFAG12864B_BPB); 9462306a36Sopenharmony_ci} 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci/* 9762306a36Sopenharmony_ci * is set (x, y) pixel? 9862306a36Sopenharmony_ci * 9962306a36Sopenharmony_ci * Pixel off: return = 0 10062306a36Sopenharmony_ci * Pixel on: return = 1 10162306a36Sopenharmony_ci */ 10262306a36Sopenharmony_cistatic unsigned char cfag12864b_isset(unsigned char x, unsigned char y) 10362306a36Sopenharmony_ci{ 10462306a36Sopenharmony_ci if (CFAG12864B_CHECK(x, y)) 10562306a36Sopenharmony_ci if (cfag12864b_buffer[CFAG12864B_ADDRESS(x, y)] & 10662306a36Sopenharmony_ci CFAG12864B_BIT(x % CFAG12864B_BPB)) 10762306a36Sopenharmony_ci return 1; 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci return 0; 11062306a36Sopenharmony_ci} 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci/* 11362306a36Sopenharmony_ci * not (x, y) pixel 11462306a36Sopenharmony_ci */ 11562306a36Sopenharmony_cistatic void cfag12864b_not(unsigned char x, unsigned char y) 11662306a36Sopenharmony_ci{ 11762306a36Sopenharmony_ci if (cfag12864b_isset(x, y)) 11862306a36Sopenharmony_ci cfag12864b_unset(x, y); 11962306a36Sopenharmony_ci else 12062306a36Sopenharmony_ci cfag12864b_set(x, y); 12162306a36Sopenharmony_ci} 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci/* 12462306a36Sopenharmony_ci * fill (set all pixels) 12562306a36Sopenharmony_ci */ 12662306a36Sopenharmony_cistatic void cfag12864b_fill(void) 12762306a36Sopenharmony_ci{ 12862306a36Sopenharmony_ci unsigned short i; 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci for (i = 0; i < CFAG12864B_SIZE; i++) 13162306a36Sopenharmony_ci cfag12864b_buffer[i] = 0xFF; 13262306a36Sopenharmony_ci} 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci/* 13562306a36Sopenharmony_ci * clear (unset all pixels) 13662306a36Sopenharmony_ci */ 13762306a36Sopenharmony_cistatic void cfag12864b_clear(void) 13862306a36Sopenharmony_ci{ 13962306a36Sopenharmony_ci unsigned short i; 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci for (i = 0; i < CFAG12864B_SIZE; i++) 14262306a36Sopenharmony_ci cfag12864b_buffer[i] = 0; 14362306a36Sopenharmony_ci} 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ci/* 14662306a36Sopenharmony_ci * format a [128*64] matrix 14762306a36Sopenharmony_ci * 14862306a36Sopenharmony_ci * Pixel off: src[i] = 0 14962306a36Sopenharmony_ci * Pixel on: src[i] > 0 15062306a36Sopenharmony_ci */ 15162306a36Sopenharmony_cistatic void cfag12864b_format(unsigned char * matrix) 15262306a36Sopenharmony_ci{ 15362306a36Sopenharmony_ci unsigned char i, j, n; 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ci for (i = 0; i < CFAG12864B_HEIGHT; i++) 15662306a36Sopenharmony_ci for (j = 0; j < CFAG12864B_WIDTH / CFAG12864B_BPB; j++) { 15762306a36Sopenharmony_ci cfag12864b_buffer[i * CFAG12864B_WIDTH / CFAG12864B_BPB + 15862306a36Sopenharmony_ci j] = 0; 15962306a36Sopenharmony_ci for (n = 0; n < CFAG12864B_BPB; n++) 16062306a36Sopenharmony_ci if (matrix[i * CFAG12864B_WIDTH + 16162306a36Sopenharmony_ci j * CFAG12864B_BPB + n]) 16262306a36Sopenharmony_ci cfag12864b_buffer[i * CFAG12864B_WIDTH / 16362306a36Sopenharmony_ci CFAG12864B_BPB + j] |= 16462306a36Sopenharmony_ci CFAG12864B_BIT(n); 16562306a36Sopenharmony_ci } 16662306a36Sopenharmony_ci} 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci/* 16962306a36Sopenharmony_ci * blit buffer to lcd 17062306a36Sopenharmony_ci */ 17162306a36Sopenharmony_cistatic void cfag12864b_blit(void) 17262306a36Sopenharmony_ci{ 17362306a36Sopenharmony_ci memcpy(cfag12864b_mem, cfag12864b_buffer, CFAG12864B_SIZE); 17462306a36Sopenharmony_ci} 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci/* 17762306a36Sopenharmony_ci * ---------------------- 17862306a36Sopenharmony_ci * end of cfag12864b code 17962306a36Sopenharmony_ci * ---------------------- 18062306a36Sopenharmony_ci */ 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ci#include <stdio.h> 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ci#define EXAMPLES 6 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_cistatic void example(unsigned char n) 18762306a36Sopenharmony_ci{ 18862306a36Sopenharmony_ci unsigned short i, j; 18962306a36Sopenharmony_ci unsigned char matrix[CFAG12864B_WIDTH * CFAG12864B_HEIGHT]; 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci if (n > EXAMPLES) 19262306a36Sopenharmony_ci return; 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_ci printf("Example %i/%i - ", n, EXAMPLES); 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_ci switch (n) { 19762306a36Sopenharmony_ci case 1: 19862306a36Sopenharmony_ci printf("Draw points setting bits"); 19962306a36Sopenharmony_ci cfag12864b_clear(); 20062306a36Sopenharmony_ci for (i = 0; i < CFAG12864B_WIDTH; i += 2) 20162306a36Sopenharmony_ci for (j = 0; j < CFAG12864B_HEIGHT; j += 2) 20262306a36Sopenharmony_ci cfag12864b_set(i, j); 20362306a36Sopenharmony_ci break; 20462306a36Sopenharmony_ci 20562306a36Sopenharmony_ci case 2: 20662306a36Sopenharmony_ci printf("Clear the LCD"); 20762306a36Sopenharmony_ci cfag12864b_clear(); 20862306a36Sopenharmony_ci break; 20962306a36Sopenharmony_ci 21062306a36Sopenharmony_ci case 3: 21162306a36Sopenharmony_ci printf("Draw rows formatting a [128*64] matrix"); 21262306a36Sopenharmony_ci memset(matrix, 0, CFAG12864B_WIDTH * CFAG12864B_HEIGHT); 21362306a36Sopenharmony_ci for (i = 0; i < CFAG12864B_WIDTH; i++) 21462306a36Sopenharmony_ci for (j = 0; j < CFAG12864B_HEIGHT; j += 2) 21562306a36Sopenharmony_ci matrix[j * CFAG12864B_WIDTH + i] = 1; 21662306a36Sopenharmony_ci cfag12864b_format(matrix); 21762306a36Sopenharmony_ci break; 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_ci case 4: 22062306a36Sopenharmony_ci printf("Fill the lcd"); 22162306a36Sopenharmony_ci cfag12864b_fill(); 22262306a36Sopenharmony_ci break; 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_ci case 5: 22562306a36Sopenharmony_ci printf("Draw columns unsetting bits"); 22662306a36Sopenharmony_ci for (i = 0; i < CFAG12864B_WIDTH; i += 2) 22762306a36Sopenharmony_ci for (j = 0; j < CFAG12864B_HEIGHT; j++) 22862306a36Sopenharmony_ci cfag12864b_unset(i, j); 22962306a36Sopenharmony_ci break; 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_ci case 6: 23262306a36Sopenharmony_ci printf("Do negative not-ing all bits"); 23362306a36Sopenharmony_ci for (i = 0; i < CFAG12864B_WIDTH; i++) 23462306a36Sopenharmony_ci for (j = 0; j < CFAG12864B_HEIGHT; j ++) 23562306a36Sopenharmony_ci cfag12864b_not(i, j); 23662306a36Sopenharmony_ci break; 23762306a36Sopenharmony_ci } 23862306a36Sopenharmony_ci 23962306a36Sopenharmony_ci puts(" - [Press Enter]"); 24062306a36Sopenharmony_ci} 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_ciint main(int argc, char *argv[]) 24362306a36Sopenharmony_ci{ 24462306a36Sopenharmony_ci unsigned char n; 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ci if (argc != 2) { 24762306a36Sopenharmony_ci printf( 24862306a36Sopenharmony_ci "Syntax: %s fbdev\n" 24962306a36Sopenharmony_ci "Usually: /dev/fb0, /dev/fb1...\n", argv[0]); 25062306a36Sopenharmony_ci return -1; 25162306a36Sopenharmony_ci } 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_ci if (cfag12864b_init(argv[1])) { 25462306a36Sopenharmony_ci printf("Can't init %s fbdev\n", argv[1]); 25562306a36Sopenharmony_ci return -2; 25662306a36Sopenharmony_ci } 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_ci for (n = 1; n <= EXAMPLES; n++) { 25962306a36Sopenharmony_ci example(n); 26062306a36Sopenharmony_ci cfag12864b_blit(); 26162306a36Sopenharmony_ci while (getchar() != '\n'); 26262306a36Sopenharmony_ci } 26362306a36Sopenharmony_ci 26462306a36Sopenharmony_ci cfag12864b_exit(); 26562306a36Sopenharmony_ci 26662306a36Sopenharmony_ci return 0; 26762306a36Sopenharmony_ci} 268