diff 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
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/packages/devs/framebuf/synth/current/misc/example.c
@@ -0,0 +1,374 @@
+//==========================================================================
+//
+//      example.c
+//
+//      Demonstration of the synthetic target framebuffer capabilities
+//
+//==========================================================================
+//###ECOSGPLCOPYRIGHTBEGIN####
+//-------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2008 Free Software Foundation, Inc.
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//==========================================================================
+//###DESCRIPTIONBEGIN####
+//
+// Author(s):     bartv
+// Date:          2008-10-06
+//
+//###DESCRIPTIONEND####
+//========================================================================
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/diag.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/io/framebuf.h>
+#include <cyg/kernel/kapi.h>
+#include <string.h>
+#include <stdio.h>
+
+#define BLACK        colours[0x00]
+#define BLUE         colours[0x01]
+#define GREEN        colours[0x02]
+#define CYAN         colours[0x03]
+#define RED          colours[0x04]
+#define MAGENTA      colours[0x05]
+#define BROWN        colours[0x06]
+#define LIGHTGREY    colours[0x07]
+#define DARKGREY     colours[0x08]
+#define LIGHTBLUE    colours[0x09]
+#define LIGHTGREEN   colours[0x0A]
+#define LIGHTCYAN    colours[0x0B]
+#define LIGHTRED     colours[0x0C]
+#define LIGHTMAGENTA colours[0x0D]
+#define YELLOW       colours[0x0E]
+#define WHITE        colours[0x0F]
+
+// ----------------------------------------------------------------------------
+// FB0. 320x240 32bpp true 0888. Just draw a simple image as per the fb.c
+// example and return to main().
+
+static void
+fb0_thread(cyg_addrword_t arg)
+{
+#define FRAMEBUF cyg_synth_fb0    
+    static cyg_ucount32 colours[16];
+    cyg_ucount16 block_width;
+    int i;
+    
+    for (i = 0; i < 16; i++) {
+        colours[i]  = cyg_fb_make_colour(&FRAMEBUF,
+                                         cyg_fb_palette_vga[i + i + i], cyg_fb_palette_vga[i + i + i + 1],cyg_fb_palette_vga[i + i + i + 2]);
+    }
+
+    cyg_fb_on(&FRAMEBUF);
+    // A white background
+    cyg_fb_fill_block(&FRAMEBUF, 0, 0, FRAMEBUF.fb_width, FRAMEBUF.fb_height, WHITE);
+    // A black block in the middle, 25 pixels in.
+    cyg_fb_fill_block(&FRAMEBUF, 25, 25, FRAMEBUF.fb_width - 50, FRAMEBUF.fb_height - 50, BLACK);
+
+    // Four diagonal lines in the corners. Red in the top left, blue in the top right,
+    // green in the bottom left, and yellow in the bottom right.
+    for (i = 0; i < 25; i++) {
+        cyg_fb_write_pixel(&FRAMEBUF, i,                           i,                            RED);
+        cyg_fb_write_pixel(&FRAMEBUF, (FRAMEBUF.fb_width - 1) - i, i,                            BLUE);
+        cyg_fb_write_pixel(&FRAMEBUF, i,                           (FRAMEBUF.fb_height - 1) - i, GREEN);
+        cyg_fb_write_pixel(&FRAMEBUF, (FRAMEBUF.fb_width - 1) - i, (FRAMEBUF.fb_height - 1) - i, YELLOW);
+    }
+
+    // Horizontal and vertical lines. Cyan at the top, magenta on the bottom,
+    // brown on the left, lightgrey on the right.
+    cyg_fb_write_hline(&FRAMEBUF, 25, 12, FRAMEBUF.fb_width - 50, CYAN);
+    cyg_fb_write_hline(&FRAMEBUF, 25, FRAMEBUF.fb_height - 12, FRAMEBUF.fb_width - 50, MAGENTA);
+    cyg_fb_write_vline(&FRAMEBUF, 12, 25, FRAMEBUF.fb_height - 50, BROWN);
+    cyg_fb_write_vline(&FRAMEBUF, FRAMEBUF.fb_width - 12, 25, FRAMEBUF.fb_height - 50, LIGHTGREY);
+
+    // And 14 vertical stripes, from blue to yellow, in the centre of the box.
+    block_width     = (FRAMEBUF.fb_width - 100) / 14;
+    for (i = 1; i <= 14; i++) {
+        cyg_fb_fill_block(&FRAMEBUF, 50 + ((i - 1) * block_width), 50, block_width, FRAMEBUF.fb_height - 100, colours[i]);
+    }
+
+    cyg_fb_synch(&FRAMEBUF, CYG_FB_UPDATE_NOW);
+#undef FRAMEBUF    
+}
+
+// ----------------------------------------------------------------------------
+// FB1, 320x240 15bpp, true 555, two pages. Draw a set of horizontal lines
+// in one page, vertical lines in the other, and flip between them at
+// one second intervals.
+
+static void
+fb1_thread(cyg_addrword_t arg)
+{
+#define FRAMEBUF cyg_synth_fb1
+    static cyg_ucount32 colours[16];
+    struct cyg_fb_ioctl_page_flip page_flip;
+    size_t len;
+    int result;
+    int i;
+
+    cyg_fb_on(&FRAMEBUF);
+    for (i = 0; i < 16; i++) {
+        colours[i]  = cyg_fb_make_colour(&FRAMEBUF,
+                                         cyg_fb_palette_vga[i + i + i], cyg_fb_palette_vga[i + i + i + 1],cyg_fb_palette_vga[i + i + i + 2]);
+    }
+
+    // Draw the horizontal stripes on page 0.
+    page_flip.fbpf_visible_page     = 0;
+    page_flip.fbpf_drawable_page    = 1;
+    page_flip.fbpf_when             = CYG_FB_UPDATE_NOW;
+    len                             = sizeof(page_flip);
+    result = cyg_fb_ioctl(&FRAMEBUF, CYG_FB_IOCTL_PAGE_FLIPPING_SET_PAGES, &page_flip, &len);
+    if (result != 0) {
+        fprintf(stderr, "fb1_thread: initial page flip failed.\n");
+    }
+    // 16 colours, 240 rows -> 15 rows/colour
+    for (i = 0; i < 16; i++) {
+        cyg_fb_fill_block(&FRAMEBUF, 0, 15 * i, 320, 15, colours[i]);
+    }
+    
+    // Show the horizontal stripes and draw the vertical stripes on page 0.
+    page_flip.fbpf_visible_page     = 1;
+    page_flip.fbpf_drawable_page    = 0;
+    page_flip.fbpf_when             = CYG_FB_UPDATE_NOW;
+    len                             = sizeof(page_flip);
+    result = cyg_fb_ioctl(&FRAMEBUF, CYG_FB_IOCTL_PAGE_FLIPPING_SET_PAGES, &page_flip, &len);
+    if (result != 0) {
+        fprintf(stderr, "fb1_thread: second page flip failed.\n");
+    }
+    // 16 colours, 320 columns -> 20 columns/colour
+    for (i = 0; i < 16; i++) {
+        cyg_fb_fill_block(&FRAMEBUF, 20 * i, 0, 20, 240, colours[i]);
+    }
+    
+    for ( i = 0; ; i = 1 - i) {
+        page_flip.fbpf_visible_page     = i;
+        page_flip.fbpf_drawable_page    = 1 - i;
+        page_flip.fbpf_when             = CYG_FB_UPDATE_NOW;
+        len                             = sizeof(page_flip);
+        result = cyg_fb_ioctl(&FRAMEBUF, CYG_FB_IOCTL_PAGE_FLIPPING_SET_PAGES, &page_flip, &len);
+        if (result != 0) {
+            fprintf(stderr, "fb1_thread: ongoing page flip failed.\n");
+        }
+        cyg_thread_delay(100);
+    }
+#undef FRAMEBUF    
+}
+
+// ----------------------------------------------------------------------------
+// FB2, 320x240 15bpp, true 565, with a 160x120 viewport. Draw a simple image
+// as per the fbmacro.c example. Then move around within the viewport in a
+// clockwise direction at 110ms intervals.
+
+static void
+fb2_thread(cyg_addrword_t arg)
+{
+#define FRAMEBUF fb2
+#define WIDTH    320
+#define HEIGHT   240
+    
+    static cyg_ucount32 colours[16];
+    cyg_ucount16 block_width;
+    int i, j;
+    int x = 0, y = 0;
+    CYG_FB_PIXEL0_VAR(FRAMEBUF);
+    CYG_FB_PIXEL1_VAR(FRAMEBUF);
+    cyg_fb_ioctl_viewport viewport;
+    size_t len;
+
+    CYG_FB_ON(FRAMEBUF);
+    for (i = 0; i < 16; i++) {
+        colours[i]  = CYG_FB_MAKE_COLOUR(FRAMEBUF,
+                                         cyg_fb_palette_vga[i + i + i], cyg_fb_palette_vga[i + i + i + 1],cyg_fb_palette_vga[i + i + i + 2]);
+    }
+    // A white background
+    CYG_FB_FILL_BLOCK(FRAMEBUF, 0, 0, WIDTH, HEIGHT, WHITE);
+    // A black block in the middle, 25 pixels in.
+    CYG_FB_FILL_BLOCK(FRAMEBUF, 32, 32, WIDTH - 64, HEIGHT - 64, BLACK);
+
+    // Four diagonal lines in the corners. Red in the top left, blue in the top right,
+    // green in the bottom left, and yellow in the bottom right.
+    for (i = 0; i < 32; i++) {
+        CYG_FB_WRITE_PIXEL(FRAMEBUF, i,               i,                RED);
+        CYG_FB_WRITE_PIXEL(FRAMEBUF, (WIDTH - 1) - i, i,                BLUE);
+        CYG_FB_WRITE_PIXEL(FRAMEBUF, i,               (HEIGHT - 1) - i, GREEN);
+        CYG_FB_WRITE_PIXEL(FRAMEBUF, (WIDTH - 1) - i, (HEIGHT - 1) - i, YELLOW);
+    }
+
+    // Horizontal and vertical lines. Cyan at the top, magenta on the bottom,
+    // brown on the left, lightgrey on the right.
+    CYG_FB_WRITE_HLINE(FRAMEBUF, 32,         16,            WIDTH - 64, CYAN);
+    CYG_FB_WRITE_HLINE(FRAMEBUF, 32,         HEIGHT - 16,   WIDTH - 64, MAGENTA);
+    CYG_FB_WRITE_VLINE(FRAMEBUF, 16,         32,            HEIGHT - 64, BROWN);
+    CYG_FB_WRITE_VLINE(FRAMEBUF, WIDTH - 16, 32,            HEIGHT - 64, LIGHTGREY);
+
+    // Top left, diagonal lines away from 0,0 with increasing spacing horizontally
+    for (i = 0; i < 16; i++) {
+        CYG_FB_PIXEL0_SET(FRAMEBUF, i + 16, i);
+        for (j = 0; j < 16; j++) {
+            CYG_FB_PIXEL0_WRITE(FRAMEBUF, colours[i]);
+            CYG_FB_PIXEL0_ADDX(FRAMEBUF, j);
+        }
+    }
+
+    // Top right, diagonal lines away from the corner, with increasing spacing horizontally
+    for (i = 0; i < 16; i++) {
+        CYG_FB_PIXEL0_SET(FRAMEBUF, WIDTH - (i + 16), i);
+        for (j = 0; j < 16; j++) {
+            CYG_FB_PIXEL0_WRITE(FRAMEBUF, colours[i]);
+            CYG_FB_PIXEL0_ADDX(FRAMEBUF, -1 * j);
+        }
+    }
+
+    // Top left, diagonal lines away from the corner, with increasing spacing vertically
+    for (i = 0; i < 16; i++) {
+        CYG_FB_PIXEL0_SET(FRAMEBUF, i, i + 16);
+        for (j = 0; j < 16; j++) {
+            CYG_FB_PIXEL0_WRITE(FRAMEBUF, colours[i]);
+            CYG_FB_PIXEL0_ADDY(FRAMEBUF, j);
+        }
+    }
+    // Bottom left, diagonal lines away from the corner, with increasing spacing vertically
+    for (i = 0; i < 16; i++) {
+        CYG_FB_PIXEL0_SET(FRAMEBUF, i, HEIGHT - (i + 16));
+        for (j = 0; j < 16; j++) {
+            CYG_FB_PIXEL0_WRITE(FRAMEBUF, colours[i]);
+            CYG_FB_PIXEL0_ADDY(FRAMEBUF, -1 * j);
+        }
+    }
+
+    // Thin vertical bars in the top-middle of the screen, between the hline and the box.
+    // Starting in the center and moving out with increasing spacing.
+    for (j = 0; j < 8; j++) {
+        CYG_FB_PIXEL0_SET(FRAMEBUF, (WIDTH / 2) - 2, 20 + j);
+        CYG_FB_PIXEL0_GET(FRAMEBUF, x, y);
+        CYG_FB_PIXEL1_SET(FRAMEBUF, x + 3, y);
+        for (i = 0; i < 16; i++) {
+            CYG_FB_PIXEL0_ADDX(FRAMEBUF, -1 * i);
+            CYG_FB_PIXEL1_ADDX(FRAMEBUF, i);
+            CYG_FB_PIXEL0_WRITE(FRAMEBUF, colours[i]);
+            CYG_FB_PIXEL1_WRITE(FRAMEBUF, colours[i]);
+        }
+    }
+    
+    block_width     = (WIDTH - 100) / 14;
+    for (i = 1; i <= 14; i++) {
+        CYG_FB_FILL_BLOCK(FRAMEBUF, 50 + ((i - 1) * block_width), 50, block_width, HEIGHT - 100, colours[i]);
+    }
+    
+    
+    for ( ; ; ) {
+        for (x = 0; x <= 160; x += 5) {
+            viewport.fbvp_x     = x;
+            viewport.fbvp_y     = 0;
+            viewport.fbvp_when  = CYG_FB_UPDATE_NOW;
+            len                 = sizeof(viewport);
+            CYG_FB_IOCTL(FRAMEBUF, CYG_FB_IOCTL_VIEWPORT_SET_POSITION, &viewport, &len);
+            cyg_thread_delay(11);
+        }
+        for (y = 0; y < 120; y += 5) {
+            viewport.fbvp_x     = 160;
+            viewport.fbvp_y     = y;
+            viewport.fbvp_when  = CYG_FB_UPDATE_NOW;
+            len                 = sizeof(viewport);
+            CYG_FB_IOCTL(FRAMEBUF, CYG_FB_IOCTL_VIEWPORT_SET_POSITION, &viewport, &len);
+            cyg_thread_delay(11);
+        }
+        for (x = 160; x >= 0; x -= 5) {
+            viewport.fbvp_x     = x;
+            viewport.fbvp_y     = 120;
+            viewport.fbvp_when  = CYG_FB_UPDATE_NOW;
+            len                 = sizeof(viewport);
+            CYG_FB_IOCTL(FRAMEBUF, CYG_FB_IOCTL_VIEWPORT_SET_POSITION, &viewport, &len);
+            cyg_thread_delay(11);
+        }
+        for (y = 120; y >= 0; y -= 5) {
+            viewport.fbvp_x     = 0;
+            viewport.fbvp_y     = y;
+            viewport.fbvp_when  = CYG_FB_UPDATE_NOW;
+            len                 = sizeof(viewport);
+            CYG_FB_IOCTL(FRAMEBUF, CYG_FB_IOCTL_VIEWPORT_SET_POSITION, &viewport, &len);
+            cyg_thread_delay(11);
+        }
+    }
+#undef FRAMEBUF
+#undef WIDTH
+#undef HEIGHT
+}
+
+// ----------------------------------------------------------------------------
+// FB3, 320x240 8bpp, paletted 888. Draw a series of vertical stripes, 5 pixels
+// wide, and rotate through the palette at 210ms intervals.
+
+static void
+fb3_thread(cyg_addrword_t arg)
+{
+#define FRAMEBUF    fb3
+    static cyg_uint8 palette[(128 +16) * 3];
+    int i;
+
+    CYG_FB_ON(FRAMEBUF);
+
+    // Read in the first 128 palette entries, and copy the first 16
+    // entries to give a wrap-around. After 128 the palette gets less
+    // interesting.
+    CYG_FB_READ_PALETTE(FRAMEBUF, 0, 128, palette);
+    memcpy(&(palette[128 * 3]), palette, 16 * 3);
+    
+    for (i = 0; i < 32; i++) {
+        CYG_FB_FILL_BLOCK(FRAMEBUF, 10 * i, 0, 10, 240, i);
+    }
+    
+    for ( i = 0; ; i = (i + 1) % 128 ) {
+        cyg_thread_delay(21);
+        CYG_FB_WRITE_PALETTE(FRAMEBUF, 0, 64, &(palette[i * 3]), CYG_FB_UPDATE_NOW);
+    }
+#undef FRAMEBUF    
+}
+
+// ----------------------------------------------------------------------------
+// main(). Start up separate threads for FB1 and FB2, run the FB0 code since
+// it just does some drawing and finishes, then run the FB3 code.
+static cyg_thread       fb1_thread_data;
+static cyg_handle_t     fb1_thread_handle;
+static unsigned char    fb1_thread_stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
+static cyg_thread       fb2_thread_data;
+static cyg_handle_t     fb2_thread_handle;
+static unsigned char    fb2_thread_stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
+
+int
+main(int argc, char** argv)
+{
+    cyg_thread_create(10, &fb1_thread, 0, "fb1", fb1_thread_stack, CYGNUM_HAL_STACK_SIZE_TYPICAL, &fb1_thread_handle, &fb1_thread_data);
+    cyg_thread_create(10, &fb2_thread, 0, "fb2", fb2_thread_stack, CYGNUM_HAL_STACK_SIZE_TYPICAL, &fb2_thread_handle, &fb2_thread_data);
+    cyg_thread_resume(fb1_thread_handle);
+    cyg_thread_resume(fb2_thread_handle);
+    fb0_thread(0);
+    fb3_thread(0);
+    return 0;
+}
+