linux/samples/auxdisplay/cfag12864b-example.c
<<
>>
Prefs
   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 <ojeda@kernel.org>
   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
  40int cfag12864b_fd;
  41unsigned char * cfag12864b_mem;
  42unsigned 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 */
  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 device
  69 */
  70static void cfag12864b_exit(void)
  71{
  72        munmap(cfag12864b_mem, CFAG12864B_SIZE);
  73        close(cfag12864b_fd);
  74}
  75
  76/*
  77 * set (x, y) pixel
  78 */
  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) pixel
  88 */
  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 = 0
 100 * Pixel on:  return = 1
 101 */
 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) pixel
 114 */
 115static 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 */
 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] matrix
 147 *
 148 * Pixel off: src[i] = 0
 149 * Pixel on:  src[i] > 0
 150 */
 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 lcd
 170 */
 171static 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
 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