268 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Filename: cfag12864b-example.c4 * Version: 0.1.05 * Description: cfag12864b LCD userspace example program6 *7 * Author: Copyright (C) Miguel Ojeda <ojeda@kernel.org>8 * Date: 2006-10-319 */10 11/*12 * ------------------------13 * start of cfag12864b code14 * ------------------------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_DOCHECK33#ifdef CFAG12864B_DOCHECK34 #define CFAG12864B_CHECK(x, y) ((x) < CFAG12864B_WIDTH && \35 (y) < CFAG12864B_HEIGHT)36#else37 #define CFAG12864B_CHECK(x, y) (1)38#endif39 40int cfag12864b_fd;41unsigned char * cfag12864b_mem;42unsigned char cfag12864b_buffer[CFAG12864B_SIZE];43 44/*45 * init a cfag12864b framebuffer device46 *47 * No error: return = 048 * Unable to open: return = -149 * Unable to mmap: return = -250 */51static 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 device69 */70static void cfag12864b_exit(void)71{72 munmap(cfag12864b_mem, CFAG12864B_SIZE);73 close(cfag12864b_fd);74}75 76/*77 * set (x, y) pixel78 */79static 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) pixel88 */89static 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 = 0100 * Pixel on: return = 1101 */102static 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) pixel114 */115static void cfag12864b_not(unsigned char x, unsigned char y)116{117 if (cfag12864b_isset(x, y))118 cfag12864b_unset(x, y);119 else120 cfag12864b_set(x, y);121}122 123/*124 * fill (set all pixels)125 */126static 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 */137static 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] matrix147 *148 * Pixel off: src[i] = 0149 * Pixel on: src[i] > 0150 */151static 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 lcd170 */171static void cfag12864b_blit(void)172{173 memcpy(cfag12864b_mem, cfag12864b_buffer, CFAG12864B_SIZE);174}175 176/*177 * ----------------------178 * end of cfag12864b code179 * ----------------------180 */181 182#include <stdio.h>183 184#define EXAMPLES 6185 186static 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 242int 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