world leader in high performance signal processing
Trace: » animated

ADSP-BF548 EZ-KIT Quick Start: Peripheral Demos: animated

www.analog.com_static_imported-files_images_product_descriptions_680755565image1a.jpg

What is animated

An application that uses SDL_gfx to draw a black box that bounces around on the screen. It demonstrates some very basic primitive drawing using SDL_gfx.

Download animated

The demo comes with the customised Ubuntu ISO and can be found in the folder /home/Blackfin/demos. Alternatively it is already installed on the demo uClinux image (demo-uclinux.img) that you can get on ADSP-BF548 EZ-KIT Quick Start: Booting uClinux.

If you just want to download the demos on their own and get their source code you can download the compressed archive (demos-R1.tar.gz) here bf548-quick-start .

How to run the animated program

  • Change directory to /demos/lcd

    root:/> cd /demos/lcd
  • Make sure SDL knows that there is no mouse available otherwise it won't run

    root:/> export SDL_NOMOUSE=1

    Note: You only need to do this once per uClinux boot. If you want your program to make use of the touch screen, do not run this environment variable and instead run the commands found in the touchscreen demos.

  • Run animated

    root:/> ./animated
    Loading... 
    Done!
    Drawing shapes... 
    Displayed. Interrupt to exit.
  • Exit (Ctrl + C)

How the animated demo works

Required header files

#include <stdio.h>
#include <stdlib.h>

// Necessary Drawing Libraries
#include <SDL_gfxPrimitives.h>

As you can see, this program only grabs SDL_gfxPrimitives.h really for the low level drawing API. It doesn't explicitly grab SDL.h as that will be done by SDL_gfxPrimitives.

Main function

int main(int argc, char* argv[])
{
  int screen_width = 480;
  int screen_height = 272;
  int screen_bitdepth = 24;

  SDL_Surface *screen;
  SDL_Event input_event;

  int running = 0;

  int vertical_direction = 1;
  int horizontal_direction = 1;

  int box_x = 0;
  int box_y = 0;
  int box_width = 25;
  int box_height = 25;

  printf("Loading... \n");

This section highlights how the programs run are just like normal C programs on your desktop machine. You have your normal main function, and some variable declarations at the top of the function. The screen dimensions provided match up with the LCD on the BF548 EZ-KIT.

Initializing the video subsystem

if (SDL_Init(SDL_INIT_VIDEO) < 0)
{
  fprintf(stderr, "Error: Unable to init SDL: %s\n", SDL_GetError());
  exit(1);
}
atexit(SDL_Quit);

screen = SDL_SetVideoMode(width, height, depth, SDL_DOUBLEBUF);
if (screen == NULL)
{
  fprintf(stderr, "Error: Unable to grab screen\n");
  SDL_Quit();
  exit(1);
}

This section of code will initialise the video subsystem of SDL so that SDL knows it will have a graphics buffer to write to. If it fails, it will abort the program. The atexit call is added so that when the program closes, SDL will clean itself up.

It also grabs the screen to write to by making a call to SDL_SetVideoMode and provides the screen details, note that width, height and depth are provided at the start of this program and are set to the LCD screens actual dimensions so this creates a full screen window. If this fails, the program will abort.

This section will be quite common for any SDL program using the LCD and the SDL_Init call might have to OR other subsystems as well if you're using things like audio.

Drawing Shapes

printf("Drawing shapes... \n");
// Draw white background
SDL_Rect rect0 = {0, 0, screen_width, screen_height};
SDL_FillRect(screen, &rect0, 0xFFFFFF);

// Draw a black rectangle
boxColor(screen, box_x, box_y, box_x + box_width, box_y + box_height, 0x000000FF);

// display surface on LCD
SDL_Flip(screen);
printf("Displayed. Interrupt to exit.\n");

This section merely draws a white rectangle to the screen, then draws a box on top of it. The boxColor call draws a box onto the screen surface, and as you can see the colour provided is in the form of 0x000000FF. This is the black colour in the form of RGBA. The last FF indicates a 255 alpha value (not transparent). The other variables in the function call dictate which surface to draw on, and the coordinates and dimensions (as provided at the top of the program).

SDL_gfx has many low level drawing functions and you can learn more about them on the official SDL_gfx documentation at http://www.ferzkopp.net/Software/SDL_gfx-2.0/Docs/html/_s_d_l__gfx_primitives_8c.html and http://www.ferzkopp.net/Software/SDL_gfx-2.0/Docs/html/index.html .

Input handling & animation loop

memset(&input_event, 0, sizeof(input_event));
while (running == 0)
{
  box_y += vertical_direction;
  box_x += horizontal_direction;
  if ((box_x + box_width) >= screen_width)
  {
    horizontal_direction = -1;
  }
  if (box_x <= 0)
  {
    horizontal_direction = 1;
  }
  if ((box_y + box_height) >= screen_height)
  {
    vertical_direction = -1;
  }
  if (box_y <= 0)
  {
    vertical_direction = 1;
  }

  // Draw white background
  SDL_Rect rect0 = {0, 0, screen_width, screen_height};
  SDL_FillRect(screen, &rect0, 0xFFFFFF);

  // Draw a black rectangle
  boxColor(screen, box_x, box_y, box_x + box_width, box_y + box_height, 0x000000FF);

  // display surface on LCD
  SDL_Flip(screen);

  if (SDL_PollEvent(&input_event))
  {
    if (input_event.type == SDL_QUIT)
    {
      running = 1;
    }
  }

  SDL_Delay(10);
}

This main loop performs the animation of the box on the screen. The program will shift the box coordinates in a certain direction and perform a edge collision check with the LCD screen dimensions. If it detects it, it'll set the box to bounce the opposite way. This is just a basic animation example, common in many example graphics programs. When it finishes updating the box coordinates, it will redraw the entire screen (white rectangle, followed by box).

This section also performs the common input loop that will continuously check for any program input. This one is looking for an SDL_Quit call (from program termination) to perform an exit.

The SDL_Delay(10); call just delays SDL for 10ms so it doesn't consume all of the processor.

Exiting

SDL_Quit();
return 0;

This section just does some basic clean up and exits the program.

Compiling animated

First make sure that your kernel has the libraries libSDL, SDL_gfx and tslib enabled.

Secondly, make sure your vendor staging install is complete (ADSP-BF548 EZ-KIT Quick Start: Compiling uClinux).

root:/> make vendor_staging_install

Run the following compile command in the same directory as the source code:

root:/> bfin-linux-uclibc-gcc -O2 \
$(~/Blackfin/blackfin-linux-dist/staging/usr/bin/sdl-config --cflags) \
$(~/Blackfin/blackfin-linux-dist/staging/usr/bin/sdl-config --libs) \ 
-lSDL_gfx \ 
animated.c -o animated

What this compile command is doing is it is calling the uclibc cross compiler that is set up from the Blackfin toolchains to compile our application.

The calls to sdl-config are a special case for SDL because SDL places its header & library files in non-root locations so this will load them properly.

The parameters prefixed with -l are to indicate we need to load that library, so in this case the library SDL_gfx is loaded. Without this library, our program would not have access to the required functions.

The final parameters match up to standard gcc compiling, “animated.c” is the source file while ”-o animated” indicates the output file is “animated”.

A standard make file is accompanies this demo and you can run that by simply calling

root:/> make animated

Further Reading

SDL_gfx

SDL_gfx is a popular SDL primitives drawing api, and its documentation is located at http://www.ferzkopp.net/joomla/content/view/19/14/

It contains many SDL support functions and in this case was used for its interpolating rotozoomer functions to resize the SDL surface displaying the jpeg. The components of SDL_gfx you can use include

  • Graphic Primitives (SDL_gfxPrimitves.h)
  • Rotozoomer (SDL_rotozoom.h)
  • Framerate control (SDL_framerate.h)
  • MMX image filters (SDL_imageFilter.h)
  • Custom Blit functions (SDL_gfxBlitFunc.h)

LCD Notes

The LCD on the BF548 EZ-KIT is a 24bit lcd (8bit blue, 8bit green, 8bit red). This means some programs hard coded for the frame buffer do not work, for example pngview. If you run pngview and it appears wonky on the BF548 that is because it was made for the BF537 and a 16bit LCD. Since it does not write enough data to fill a pixel and will encode for rgb and not bgr, it will be interpreted wrongly, so be aware of this when working with programs that write directly to the frame buffer.

If the colour on the LCD screen appears wonky, this may be due to the LCD screen settings defined by SW17. These switches can set the bitrate of the LCD and if set differently than to what the program expecs will lead to a bit of mayham. Check the development environment page of this guide to make sure it is set to the default 24bit.

Information on the LCD driver for the BF548 EZ-KIT can be found here Linux framebuffer driver for ADSP-BF54x