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