Mercurial > ecos
comparison packages/devs/framebuf/synth/current/misc/example.c @ 2566:2063ee669faf
Contribute eCosCentric's synthetic target framebuffer device driver.
| author | bartv |
|---|---|
| date | Tue, 07 Oct 2008 21:10:17 +0000 |
| parents | |
| children | 74dbf4c3f2e1 |
comparison
equal
deleted
inserted
replaced
| 2565:f9d071633ee7 | 2566:2063ee669faf |
|---|---|
| 1 //========================================================================== | |
| 2 // | |
| 3 // example.c | |
| 4 // | |
| 5 // Demonstration of the synthetic target framebuffer capabilities | |
| 6 // | |
| 7 //========================================================================== | |
| 8 //###ECOSGPLCOPYRIGHTBEGIN#### | |
| 9 //------------------------------------------- | |
| 10 // This file is part of eCos, the Embedded Configurable Operating System. | |
| 11 // Copyright (C) 2008 Free Software Foundation, Inc. | |
| 12 // eCos is free software; you can redistribute it and/or modify it under | |
| 13 // the terms of the GNU General Public License as published by the Free | |
| 14 // Software Foundation; either version 2 or (at your option) any later version. | |
| 15 // | |
| 16 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY | |
| 17 // WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 18 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| 19 // for more details. | |
| 20 // | |
| 21 // You should have received a copy of the GNU General Public License along | |
| 22 // with eCos; if not, write to the Free Software Foundation, Inc., | |
| 23 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | |
| 24 // | |
| 25 // As a special exception, if other files instantiate templates or use macros | |
| 26 // or inline functions from this file, or you compile this file and link it | |
| 27 // with other works to produce a work based on this file, this file does not | |
| 28 // by itself cause the resulting work to be covered by the GNU General Public | |
| 29 // License. However the source code for this file must still be made available | |
| 30 // in accordance with section (3) of the GNU General Public License. | |
| 31 // | |
| 32 // This exception does not invalidate any other reasons why a work based on | |
| 33 // this file might be covered by the GNU General Public License. | |
| 34 // ------------------------------------------- | |
| 35 //####ECOSGPLCOPYRIGHTEND#### | |
| 36 //========================================================================== | |
| 37 //###DESCRIPTIONBEGIN#### | |
| 38 // | |
| 39 // Author(s): bartv | |
| 40 // Date: 2008-10-06 | |
| 41 // | |
| 42 //###DESCRIPTIONEND#### | |
| 43 //======================================================================== | |
| 44 | |
| 45 #include <cyg/infra/cyg_type.h> | |
| 46 #include <cyg/infra/diag.h> | |
| 47 #include <cyg/hal/hal_arch.h> | |
| 48 #include <cyg/io/framebuf.h> | |
| 49 #include <cyg/kernel/kapi.h> | |
| 50 #include <string.h> | |
| 51 #include <stdio.h> | |
| 52 | |
| 53 #define BLACK colours[0x00] | |
| 54 #define BLUE colours[0x01] | |
| 55 #define GREEN colours[0x02] | |
| 56 #define CYAN colours[0x03] | |
| 57 #define RED colours[0x04] | |
| 58 #define MAGENTA colours[0x05] | |
| 59 #define BROWN colours[0x06] | |
| 60 #define LIGHTGREY colours[0x07] | |
| 61 #define DARKGREY colours[0x08] | |
| 62 #define LIGHTBLUE colours[0x09] | |
| 63 #define LIGHTGREEN colours[0x0A] | |
| 64 #define LIGHTCYAN colours[0x0B] | |
| 65 #define LIGHTRED colours[0x0C] | |
| 66 #define LIGHTMAGENTA colours[0x0D] | |
| 67 #define YELLOW colours[0x0E] | |
| 68 #define WHITE colours[0x0F] | |
| 69 | |
| 70 // ---------------------------------------------------------------------------- | |
| 71 // FB0. 320x240 32bpp true 0888. Just draw a simple image as per the fb.c | |
| 72 // example and return to main(). | |
| 73 | |
| 74 static void | |
| 75 fb0_thread(cyg_addrword_t arg) | |
| 76 { | |
| 77 #define FRAMEBUF cyg_synth_fb0 | |
| 78 static cyg_ucount32 colours[16]; | |
| 79 cyg_ucount16 block_width; | |
| 80 int i; | |
| 81 | |
| 82 for (i = 0; i < 16; i++) { | |
| 83 colours[i] = cyg_fb_make_colour(&FRAMEBUF, | |
| 84 cyg_fb_palette_vga[i + i + i], cyg_fb_palette_vga[i + i + i + 1],cyg_fb_palette_vga[i + i + i + 2]); | |
| 85 } | |
| 86 | |
| 87 cyg_fb_on(&FRAMEBUF); | |
| 88 // A white background | |
| 89 cyg_fb_fill_block(&FRAMEBUF, 0, 0, FRAMEBUF.fb_width, FRAMEBUF.fb_height, WHITE); | |
| 90 // A black block in the middle, 25 pixels in. | |
| 91 cyg_fb_fill_block(&FRAMEBUF, 25, 25, FRAMEBUF.fb_width - 50, FRAMEBUF.fb_height - 50, BLACK); | |
| 92 | |
| 93 // Four diagonal lines in the corners. Red in the top left, blue in the top right, | |
| 94 // green in the bottom left, and yellow in the bottom right. | |
| 95 for (i = 0; i < 25; i++) { | |
| 96 cyg_fb_write_pixel(&FRAMEBUF, i, i, RED); | |
| 97 cyg_fb_write_pixel(&FRAMEBUF, (FRAMEBUF.fb_width - 1) - i, i, BLUE); | |
| 98 cyg_fb_write_pixel(&FRAMEBUF, i, (FRAMEBUF.fb_height - 1) - i, GREEN); | |
| 99 cyg_fb_write_pixel(&FRAMEBUF, (FRAMEBUF.fb_width - 1) - i, (FRAMEBUF.fb_height - 1) - i, YELLOW); | |
| 100 } | |
| 101 | |
| 102 // Horizontal and vertical lines. Cyan at the top, magenta on the bottom, | |
| 103 // brown on the left, lightgrey on the right. | |
| 104 cyg_fb_write_hline(&FRAMEBUF, 25, 12, FRAMEBUF.fb_width - 50, CYAN); | |
| 105 cyg_fb_write_hline(&FRAMEBUF, 25, FRAMEBUF.fb_height - 12, FRAMEBUF.fb_width - 50, MAGENTA); | |
| 106 cyg_fb_write_vline(&FRAMEBUF, 12, 25, FRAMEBUF.fb_height - 50, BROWN); | |
| 107 cyg_fb_write_vline(&FRAMEBUF, FRAMEBUF.fb_width - 12, 25, FRAMEBUF.fb_height - 50, LIGHTGREY); | |
| 108 | |
| 109 // And 14 vertical stripes, from blue to yellow, in the centre of the box. | |
| 110 block_width = (FRAMEBUF.fb_width - 100) / 14; | |
| 111 for (i = 1; i <= 14; i++) { | |
| 112 cyg_fb_fill_block(&FRAMEBUF, 50 + ((i - 1) * block_width), 50, block_width, FRAMEBUF.fb_height - 100, colours[i]); | |
| 113 } | |
| 114 | |
| 115 cyg_fb_synch(&FRAMEBUF, CYG_FB_UPDATE_NOW); | |
| 116 #undef FRAMEBUF | |
| 117 } | |
| 118 | |
| 119 // ---------------------------------------------------------------------------- | |
| 120 // FB1, 320x240 15bpp, true 555, two pages. Draw a set of horizontal lines | |
| 121 // in one page, vertical lines in the other, and flip between them at | |
| 122 // one second intervals. | |
| 123 | |
| 124 static void | |
| 125 fb1_thread(cyg_addrword_t arg) | |
| 126 { | |
| 127 #define FRAMEBUF cyg_synth_fb1 | |
| 128 static cyg_ucount32 colours[16]; | |
| 129 struct cyg_fb_ioctl_page_flip page_flip; | |
| 130 size_t len; | |
| 131 int result; | |
| 132 int i; | |
| 133 | |
| 134 cyg_fb_on(&FRAMEBUF); | |
| 135 for (i = 0; i < 16; i++) { | |
| 136 colours[i] = cyg_fb_make_colour(&FRAMEBUF, | |
| 137 cyg_fb_palette_vga[i + i + i], cyg_fb_palette_vga[i + i + i + 1],cyg_fb_palette_vga[i + i + i + 2]); | |
| 138 } | |
| 139 | |
| 140 // Draw the horizontal stripes on page 0. | |
| 141 page_flip.fbpf_visible_page = 0; | |
| 142 page_flip.fbpf_drawable_page = 1; | |
| 143 page_flip.fbpf_when = CYG_FB_UPDATE_NOW; | |
| 144 len = sizeof(page_flip); | |
| 145 result = cyg_fb_ioctl(&FRAMEBUF, CYG_FB_IOCTL_PAGE_FLIPPING_SET_PAGES, &page_flip, &len); | |
| 146 if (result != 0) { | |
| 147 fprintf(stderr, "fb1_thread: initial page flip failed.\n"); | |
| 148 } | |
| 149 // 16 colours, 240 rows -> 15 rows/colour | |
| 150 for (i = 0; i < 16; i++) { | |
| 151 cyg_fb_fill_block(&FRAMEBUF, 0, 15 * i, 320, 15, colours[i]); | |
| 152 } | |
| 153 | |
| 154 // Show the horizontal stripes and draw the vertical stripes on page 0. | |
| 155 page_flip.fbpf_visible_page = 1; | |
| 156 page_flip.fbpf_drawable_page = 0; | |
| 157 page_flip.fbpf_when = CYG_FB_UPDATE_NOW; | |
| 158 len = sizeof(page_flip); | |
| 159 result = cyg_fb_ioctl(&FRAMEBUF, CYG_FB_IOCTL_PAGE_FLIPPING_SET_PAGES, &page_flip, &len); | |
| 160 if (result != 0) { | |
| 161 fprintf(stderr, "fb1_thread: second page flip failed.\n"); | |
| 162 } | |
| 163 // 16 colours, 320 columns -> 20 columns/colour | |
| 164 for (i = 0; i < 16; i++) { | |
| 165 cyg_fb_fill_block(&FRAMEBUF, 20 * i, 0, 20, 240, colours[i]); | |
| 166 } | |
| 167 | |
| 168 for ( i = 0; ; i = 1 - i) { | |
| 169 page_flip.fbpf_visible_page = i; | |
| 170 page_flip.fbpf_drawable_page = 1 - i; | |
| 171 page_flip.fbpf_when = CYG_FB_UPDATE_NOW; | |
| 172 len = sizeof(page_flip); | |
| 173 result = cyg_fb_ioctl(&FRAMEBUF, CYG_FB_IOCTL_PAGE_FLIPPING_SET_PAGES, &page_flip, &len); | |
| 174 if (result != 0) { | |
| 175 fprintf(stderr, "fb1_thread: ongoing page flip failed.\n"); | |
| 176 } | |
| 177 cyg_thread_delay(100); | |
| 178 } | |
| 179 #undef FRAMEBUF | |
| 180 } | |
| 181 | |
| 182 // ---------------------------------------------------------------------------- | |
| 183 // FB2, 320x240 15bpp, true 565, with a 160x120 viewport. Draw a simple image | |
| 184 // as per the fbmacro.c example. Then move around within the viewport in a | |
| 185 // clockwise direction at 110ms intervals. | |
| 186 | |
| 187 static void | |
| 188 fb2_thread(cyg_addrword_t arg) | |
| 189 { | |
| 190 #define FRAMEBUF fb2 | |
| 191 #define WIDTH 320 | |
| 192 #define HEIGHT 240 | |
| 193 | |
| 194 static cyg_ucount32 colours[16]; | |
| 195 cyg_ucount16 block_width; | |
| 196 int i, j; | |
| 197 int x = 0, y = 0; | |
| 198 CYG_FB_PIXEL0_VAR(FRAMEBUF); | |
| 199 CYG_FB_PIXEL1_VAR(FRAMEBUF); | |
| 200 cyg_fb_ioctl_viewport viewport; | |
| 201 size_t len; | |
| 202 | |
| 203 CYG_FB_ON(FRAMEBUF); | |
| 204 for (i = 0; i < 16; i++) { | |
| 205 colours[i] = CYG_FB_MAKE_COLOUR(FRAMEBUF, | |
| 206 cyg_fb_palette_vga[i + i + i], cyg_fb_palette_vga[i + i + i + 1],cyg_fb_palette_vga[i + i + i + 2]); | |
| 207 } | |
| 208 // A white background | |
| 209 CYG_FB_FILL_BLOCK(FRAMEBUF, 0, 0, WIDTH, HEIGHT, WHITE); | |
| 210 // A black block in the middle, 25 pixels in. | |
| 211 CYG_FB_FILL_BLOCK(FRAMEBUF, 32, 32, WIDTH - 64, HEIGHT - 64, BLACK); | |
| 212 | |
| 213 // Four diagonal lines in the corners. Red in the top left, blue in the top right, | |
| 214 // green in the bottom left, and yellow in the bottom right. | |
| 215 for (i = 0; i < 32; i++) { | |
| 216 CYG_FB_WRITE_PIXEL(FRAMEBUF, i, i, RED); | |
| 217 CYG_FB_WRITE_PIXEL(FRAMEBUF, (WIDTH - 1) - i, i, BLUE); | |
| 218 CYG_FB_WRITE_PIXEL(FRAMEBUF, i, (HEIGHT - 1) - i, GREEN); | |
| 219 CYG_FB_WRITE_PIXEL(FRAMEBUF, (WIDTH - 1) - i, (HEIGHT - 1) - i, YELLOW); | |
| 220 } | |
| 221 | |
| 222 // Horizontal and vertical lines. Cyan at the top, magenta on the bottom, | |
| 223 // brown on the left, lightgrey on the right. | |
| 224 CYG_FB_WRITE_HLINE(FRAMEBUF, 32, 16, WIDTH - 64, CYAN); | |
| 225 CYG_FB_WRITE_HLINE(FRAMEBUF, 32, HEIGHT - 16, WIDTH - 64, MAGENTA); | |
| 226 CYG_FB_WRITE_VLINE(FRAMEBUF, 16, 32, HEIGHT - 64, BROWN); | |
| 227 CYG_FB_WRITE_VLINE(FRAMEBUF, WIDTH - 16, 32, HEIGHT - 64, LIGHTGREY); | |
| 228 | |
| 229 // Top left, diagonal lines away from 0,0 with increasing spacing horizontally | |
| 230 for (i = 0; i < 16; i++) { | |
| 231 CYG_FB_PIXEL0_SET(FRAMEBUF, i + 16, i); | |
| 232 for (j = 0; j < 16; j++) { | |
| 233 CYG_FB_PIXEL0_WRITE(FRAMEBUF, colours[i]); | |
| 234 CYG_FB_PIXEL0_ADDX(FRAMEBUF, j); | |
| 235 } | |
| 236 } | |
| 237 | |
| 238 // Top right, diagonal lines away from the corner, with increasing spacing horizontally | |
| 239 for (i = 0; i < 16; i++) { | |
| 240 CYG_FB_PIXEL0_SET(FRAMEBUF, WIDTH - (i + 16), i); | |
| 241 for (j = 0; j < 16; j++) { | |
| 242 CYG_FB_PIXEL0_WRITE(FRAMEBUF, colours[i]); | |
| 243 CYG_FB_PIXEL0_ADDX(FRAMEBUF, -1 * j); | |
| 244 } | |
| 245 } | |
| 246 | |
| 247 // Top left, diagonal lines away from the corner, with increasing spacing vertically | |
| 248 for (i = 0; i < 16; i++) { | |
| 249 CYG_FB_PIXEL0_SET(FRAMEBUF, i, i + 16); | |
| 250 for (j = 0; j < 16; j++) { | |
| 251 CYG_FB_PIXEL0_WRITE(FRAMEBUF, colours[i]); | |
| 252 CYG_FB_PIXEL0_ADDY(FRAMEBUF, j); | |
| 253 } | |
| 254 } | |
| 255 // Bottom left, diagonal lines away from the corner, with increasing spacing vertically | |
| 256 for (i = 0; i < 16; i++) { | |
| 257 CYG_FB_PIXEL0_SET(FRAMEBUF, i, HEIGHT - (i + 16)); | |
| 258 for (j = 0; j < 16; j++) { | |
| 259 CYG_FB_PIXEL0_WRITE(FRAMEBUF, colours[i]); | |
| 260 CYG_FB_PIXEL0_ADDY(FRAMEBUF, -1 * j); | |
| 261 } | |
| 262 } | |
| 263 | |
| 264 // Thin vertical bars in the top-middle of the screen, between the hline and the box. | |
| 265 // Starting in the center and moving out with increasing spacing. | |
| 266 for (j = 0; j < 8; j++) { | |
| 267 CYG_FB_PIXEL0_SET(FRAMEBUF, (WIDTH / 2) - 2, 20 + j); | |
| 268 CYG_FB_PIXEL0_GET(FRAMEBUF, x, y); | |
| 269 CYG_FB_PIXEL1_SET(FRAMEBUF, x + 3, y); | |
| 270 for (i = 0; i < 16; i++) { | |
| 271 CYG_FB_PIXEL0_ADDX(FRAMEBUF, -1 * i); | |
| 272 CYG_FB_PIXEL1_ADDX(FRAMEBUF, i); | |
| 273 CYG_FB_PIXEL0_WRITE(FRAMEBUF, colours[i]); | |
| 274 CYG_FB_PIXEL1_WRITE(FRAMEBUF, colours[i]); | |
| 275 } | |
| 276 } | |
| 277 | |
| 278 block_width = (WIDTH - 100) / 14; | |
| 279 for (i = 1; i <= 14; i++) { | |
| 280 CYG_FB_FILL_BLOCK(FRAMEBUF, 50 + ((i - 1) * block_width), 50, block_width, HEIGHT - 100, colours[i]); | |
| 281 } | |
| 282 | |
| 283 | |
| 284 for ( ; ; ) { | |
| 285 for (x = 0; x <= 160; x += 5) { | |
| 286 viewport.fbvp_x = x; | |
| 287 viewport.fbvp_y = 0; | |
| 288 viewport.fbvp_when = CYG_FB_UPDATE_NOW; | |
| 289 len = sizeof(viewport); | |
| 290 CYG_FB_IOCTL(FRAMEBUF, CYG_FB_IOCTL_VIEWPORT_SET_POSITION, &viewport, &len); | |
| 291 cyg_thread_delay(11); | |
| 292 } | |
| 293 for (y = 0; y < 120; y += 5) { | |
| 294 viewport.fbvp_x = 160; | |
| 295 viewport.fbvp_y = y; | |
| 296 viewport.fbvp_when = CYG_FB_UPDATE_NOW; | |
| 297 len = sizeof(viewport); | |
| 298 CYG_FB_IOCTL(FRAMEBUF, CYG_FB_IOCTL_VIEWPORT_SET_POSITION, &viewport, &len); | |
| 299 cyg_thread_delay(11); | |
| 300 } | |
| 301 for (x = 160; x >= 0; x -= 5) { | |
| 302 viewport.fbvp_x = x; | |
| 303 viewport.fbvp_y = 120; | |
| 304 viewport.fbvp_when = CYG_FB_UPDATE_NOW; | |
| 305 len = sizeof(viewport); | |
| 306 CYG_FB_IOCTL(FRAMEBUF, CYG_FB_IOCTL_VIEWPORT_SET_POSITION, &viewport, &len); | |
| 307 cyg_thread_delay(11); | |
| 308 } | |
| 309 for (y = 120; y >= 0; y -= 5) { | |
| 310 viewport.fbvp_x = 0; | |
| 311 viewport.fbvp_y = y; | |
| 312 viewport.fbvp_when = CYG_FB_UPDATE_NOW; | |
| 313 len = sizeof(viewport); | |
| 314 CYG_FB_IOCTL(FRAMEBUF, CYG_FB_IOCTL_VIEWPORT_SET_POSITION, &viewport, &len); | |
| 315 cyg_thread_delay(11); | |
| 316 } | |
| 317 } | |
| 318 #undef FRAMEBUF | |
| 319 #undef WIDTH | |
| 320 #undef HEIGHT | |
| 321 } | |
| 322 | |
| 323 // ---------------------------------------------------------------------------- | |
| 324 // FB3, 320x240 8bpp, paletted 888. Draw a series of vertical stripes, 5 pixels | |
| 325 // wide, and rotate through the palette at 210ms intervals. | |
| 326 | |
| 327 static void | |
| 328 fb3_thread(cyg_addrword_t arg) | |
| 329 { | |
| 330 #define FRAMEBUF fb3 | |
| 331 static cyg_uint8 palette[(128 +16) * 3]; | |
| 332 int i; | |
| 333 | |
| 334 CYG_FB_ON(FRAMEBUF); | |
| 335 | |
| 336 // Read in the first 128 palette entries, and copy the first 16 | |
| 337 // entries to give a wrap-around. After 128 the palette gets less | |
| 338 // interesting. | |
| 339 CYG_FB_READ_PALETTE(FRAMEBUF, 0, 128, palette); | |
| 340 memcpy(&(palette[128 * 3]), palette, 16 * 3); | |
| 341 | |
| 342 for (i = 0; i < 32; i++) { | |
| 343 CYG_FB_FILL_BLOCK(FRAMEBUF, 10 * i, 0, 10, 240, i); | |
| 344 } | |
| 345 | |
| 346 for ( i = 0; ; i = (i + 1) % 128 ) { | |
| 347 cyg_thread_delay(21); | |
| 348 CYG_FB_WRITE_PALETTE(FRAMEBUF, 0, 64, &(palette[i * 3]), CYG_FB_UPDATE_NOW); | |
| 349 } | |
| 350 #undef FRAMEBUF | |
| 351 } | |
| 352 | |
| 353 // ---------------------------------------------------------------------------- | |
| 354 // main(). Start up separate threads for FB1 and FB2, run the FB0 code since | |
| 355 // it just does some drawing and finishes, then run the FB3 code. | |
| 356 static cyg_thread fb1_thread_data; | |
| 357 static cyg_handle_t fb1_thread_handle; | |
| 358 static unsigned char fb1_thread_stack[CYGNUM_HAL_STACK_SIZE_TYPICAL]; | |
| 359 static cyg_thread fb2_thread_data; | |
| 360 static cyg_handle_t fb2_thread_handle; | |
| 361 static unsigned char fb2_thread_stack[CYGNUM_HAL_STACK_SIZE_TYPICAL]; | |
| 362 | |
| 363 int | |
| 364 main(int argc, char** argv) | |
| 365 { | |
| 366 cyg_thread_create(10, &fb1_thread, 0, "fb1", fb1_thread_stack, CYGNUM_HAL_STACK_SIZE_TYPICAL, &fb1_thread_handle, &fb1_thread_data); | |
| 367 cyg_thread_create(10, &fb2_thread, 0, "fb2", fb2_thread_stack, CYGNUM_HAL_STACK_SIZE_TYPICAL, &fb2_thread_handle, &fb2_thread_data); | |
| 368 cyg_thread_resume(fb1_thread_handle); | |
| 369 cyg_thread_resume(fb2_thread_handle); | |
| 370 fb0_thread(0); | |
| 371 fb3_thread(0); | |
| 372 return 0; | |
| 373 } | |
| 374 |
