1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Filename: cfag12864b-example.c 4 * Version: 0.1.0 5 * Description: cfag12864b LCD userspace example program 6 * 7 * Author: Copyright (C) Miguel Ojeda Sandonis 8 * Date: 2006-10-31 9 */ 10 11 /* 12 * ------------------------ 13 * start of cfag12864b code 14 * ------------------------ 15 */ 16 17 #include <string.h> 18 #include <fcntl.h> 19 #include <unistd.h> 20 #include <sys/types.h> 21 #include <sys/stat.h> 22 #include <sys/mman.h> 23 24 #define CFAG12864B_WIDTH (128) 25 #define CFAG12864B_HEIGHT (64) 26 #define CFAG12864B_SIZE (128 * 64 / 8) 27 #define CFAG12864B_BPB (8) 28 #define CFAG12864B_ADDRESS(x, y) ((y) * CFAG12864B_WIDTH / \ 29 CFAG12864B_BPB + (x) / CFAG12864B_BPB) 30 #define CFAG12864B_BIT(n) (((unsigned char) 1) << (n)) 31 32 #undef CFAG12864B_DOCHECK 33 #ifdef CFAG12864B_DOCHECK 34 #define CFAG12864B_CHECK(x, y) ((x) < CFAG12864B_WIDTH && \ 35 (y) < CFAG12864B_HEIGHT) 36 #else 37 #define CFAG12864B_CHECK(x, y) (1) 38 #endif 39 40 int cfag12864b_fd; 41 unsigned char * cfag12864b_mem; 42 unsigned char cfag12864b_buffer[CFAG12864B_SIZE]; 43 44 /* 45 * init a cfag12864b framebuffer device 46 * 47 * No error: return = 0 48 * Unable to open: return = -1 49 * Unable to mmap: return = -2 50 */ 51 static int cfag12864b_init(char *path) 52 { 53 cfag12864b_fd = open(path, O_RDWR); 54 if (cfag12864b_fd == -1) 55 return -1; 56 57 cfag12864b_mem = mmap(0, CFAG12864B_SIZE, PROT_READ | PROT_WRITE, 58 MAP_SHARED, cfag12864b_fd, 0); 59 if (cfag12864b_mem == MAP_FAILED) { 60 close(cfag12864b_fd); 61 return -2; 62 } 63 64 return 0; 65 } 66 67 /* 68 * exit a cfag12864b framebuffer device 69 */ 70 static void cfag12864b_exit(void) 71 { 72 munmap(cfag12864b_mem, CFAG12864B_SIZE); 73 close(cfag12864b_fd); 74 } 75 76 /* 77 * set (x, y) pixel 78 */ 79 static void cfag12864b_set(unsigned char x, unsigned char y) 80 { 81 if (CFAG12864B_CHECK(x, y)) 82 cfag12864b_buffer[CFAG12864B_ADDRESS(x, y)] |= 83 CFAG12864B_BIT(x % CFAG12864B_BPB); 84 } 85 86 /* 87 * unset (x, y) pixel 88 */ 89 static void cfag12864b_unset(unsigned char x, unsigned char y) 90 { 91 if (CFAG12864B_CHECK(x, y)) 92 cfag12864b_buffer[CFAG12864B_ADDRESS(x, y)] &= 93 ~CFAG12864B_BIT(x % CFAG12864B_BPB); 94 } 95 96 /* 97 * is set (x, y) pixel? 98 * 99 * Pixel off: return = 0 100 * Pixel on: return = 1 101 */ 102 static unsigned char cfag12864b_isset(unsigned char x, unsigned char y) 103 { 104 if (CFAG12864B_CHECK(x, y)) 105 if (cfag12864b_buffer[CFAG12864B_ADDRESS(x, y)] & 106 CFAG12864B_BIT(x % CFAG12864B_BPB)) 107 return 1; 108 109 return 0; 110 } 111 112 /* 113 * not (x, y) pixel 114 */ 115 static void cfag12864b_not(unsigned char x, unsigned char y) 116 { 117 if (cfag12864b_isset(x, y)) 118 cfag12864b_unset(x, y); 119 else 120 cfag12864b_set(x, y); 121 } 122 123 /* 124 * fill (set all pixels) 125 */ 126 static void cfag12864b_fill(void) 127 { 128 unsigned short i; 129 130 for (i = 0; i < CFAG12864B_SIZE; i++) 131 cfag12864b_buffer[i] = 0xFF; 132 } 133 134 /* 135 * clear (unset all pixels) 136 */ 137 static void cfag12864b_clear(void) 138 { 139 unsigned short i; 140 141 for (i = 0; i < CFAG12864B_SIZE; i++) 142 cfag12864b_buffer[i] = 0; 143 } 144 145 /* 146 * format a [128*64] matrix 147 * 148 * Pixel off: src[i] = 0 149 * Pixel on: src[i] > 0 150 */ 151 static void cfag12864b_format(unsigned char * matrix) 152 { 153 unsigned char i, j, n; 154 155 for (i = 0; i < CFAG12864B_HEIGHT; i++) 156 for (j = 0; j < CFAG12864B_WIDTH / CFAG12864B_BPB; j++) { 157 cfag12864b_buffer[i * CFAG12864B_WIDTH / CFAG12864B_BPB + 158 j] = 0; 159 for (n = 0; n < CFAG12864B_BPB; n++) 160 if (matrix[i * CFAG12864B_WIDTH + 161 j * CFAG12864B_BPB + n]) 162 cfag12864b_buffer[i * CFAG12864B_WIDTH / 163 CFAG12864B_BPB + j] |= 164 CFAG12864B_BIT(n); 165 } 166 } 167 168 /* 169 * blit buffer to lcd 170 */ 171 static void cfag12864b_blit(void) 172 { 173 memcpy(cfag12864b_mem, cfag12864b_buffer, CFAG12864B_SIZE); 174 } 175 176 /* 177 * ---------------------- 178 * end of cfag12864b code 179 * ---------------------- 180 */ 181 182 #include <stdio.h> 183 184 #define EXAMPLES 6 185 186 static void example(unsigned char n) 187 { 188 unsigned short i, j; 189 unsigned char matrix[CFAG12864B_WIDTH * CFAG12864B_HEIGHT]; 190 191 if (n > EXAMPLES) 192 return; 193 194 printf("Example %i/%i - ", n, EXAMPLES); 195 196 switch (n) { 197 case 1: 198 printf("Draw points setting bits"); 199 cfag12864b_clear(); 200 for (i = 0; i < CFAG12864B_WIDTH; i += 2) 201 for (j = 0; j < CFAG12864B_HEIGHT; j += 2) 202 cfag12864b_set(i, j); 203 break; 204 205 case 2: 206 printf("Clear the LCD"); 207 cfag12864b_clear(); 208 break; 209 210 case 3: 211 printf("Draw rows formatting a [128*64] matrix"); 212 memset(matrix, 0, CFAG12864B_WIDTH * CFAG12864B_HEIGHT); 213 for (i = 0; i < CFAG12864B_WIDTH; i++) 214 for (j = 0; j < CFAG12864B_HEIGHT; j += 2) 215 matrix[j * CFAG12864B_WIDTH + i] = 1; 216 cfag12864b_format(matrix); 217 break; 218 219 case 4: 220 printf("Fill the lcd"); 221 cfag12864b_fill(); 222 break; 223 224 case 5: 225 printf("Draw columns unsetting bits"); 226 for (i = 0; i < CFAG12864B_WIDTH; i += 2) 227 for (j = 0; j < CFAG12864B_HEIGHT; j++) 228 cfag12864b_unset(i, j); 229 break; 230 231 case 6: 232 printf("Do negative not-ing all bits"); 233 for (i = 0; i < CFAG12864B_WIDTH; i++) 234 for (j = 0; j < CFAG12864B_HEIGHT; j ++) 235 cfag12864b_not(i, j); 236 break; 237 } 238 239 puts(" - [Press Enter]"); 240 } 241 242 int main(int argc, char *argv[]) 243 { 244 unsigned char n; 245 246 if (argc != 2) { 247 printf( 248 "Syntax: %s fbdev\n" 249 "Usually: /dev/fb0, /dev/fb1...\n", argv[0]); 250 return -1; 251 } 252 253 if (cfag12864b_init(argv[1])) { 254 printf("Can't init %s fbdev\n", argv[1]); 255 return -2; 256 } 257 258 for (n = 1; n <= EXAMPLES; n++) { 259 example(n); 260 cfag12864b_blit(); 261 while (getchar() != '\n'); 262 } 263 264 cfag12864b_exit(); 265 266 return 0; 267 } 268