world leader in high performance signal processing
Trace: » blink

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

www.analog.com_static_imported-files_images_product_descriptions_680755565image1a.jpg

What is blink

This demo program will use simply blink the User LEDs on and off every second. The program will operate until it is terminated (Ctrl + C).

This is only a simple demo, just to show you that the user leds can be used as a program output.

Note that the kernel option '/sys/class/gpio/… (sysfs interface)' must be enabled for this to work.

Device Drivers -> 
  GPIO Support -> 
    [X] /sys/class/gpio/... (sysfs interface)

Download blink

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 blink program

  • Change directory to /demos/leds

    root:/> cd /demos/leds
  • Run blink

    root:/> ./blink
  • Exit (Ctrl + C)

Note that User LEDs 3, 4 and 5 do not work unless you disable the spi driver which will correlate with the touch screen being disabled. If you need all 6 LEDs and do not need the touch screen you can disable the SPI driver in the kernel configuration (Device Drivers > SPI > SPI controller driver for ADI Blackfin5xx).

How the blink demo works

Required header files

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "gpio.h"

This program makes use of a GPIO user space helpers class written by Michael Hennerich. You can find more about this at GPIO sysfs Interface. Essentially all the functions provided just wrap system calls to make it inline with your C code.

Main function

int main (int argc, char **argv)
{
  int i;
  int running = 0;
  int all_leds = 1;

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.

Request / Release GPIO

// Export gpio for all LEDs
for (i = LED1; i <= LED6; i++)
{
  if (gpio_export(i) != 0)
  {
    fprintf(stderr, "error: couldn't export gpio for port %d!\n",       i);
    continue;
  }
}

// Set up exit handler
atexit(unexport_leds);
// Called on exiting
void unexport_leds(void)
{
  int i;

  // Unexport gpio
  for (i = LED1; i <= LED6; i++)
  {
    if (gpio_unexport(i) != 0)
    {
      fprintf(stderr, "error: couldn't unexport gpio for port         %d!\n", i);
      continue;
    }
  }

  // Exit
  printf("done.\n");
}

To use a gpio port you must first export it into the sysfs system. This exposes it for system calls. At the end of the program, you should unexport it to clean up after yourself. This code section shows the usage of the gpio helper class to do that exact thing.

Set GPIO Direction

// Set direction to out
for (i = LED1; i <= LED6; i++)
{
  if (gpio_dir_out(i) != 0)
  {
    fprintf(stderr, "error: couldn't set gpio direction for port       %d!\n", i);
    all_leds = 0;
    continue;
  }
}

You should also set the direction that the gpio is, whether it is input or output. This is a section of code that uses the gpio sys helper class to set the gpio to outwards as it is an output.

Blinking Loop

// Blink LEDs
while (running == 0)
{
  // Write low
  for (i = LED1; i <= LED6; i++)
  {
    // If 3,4 and 5 are already reserved, just skip
    if ((i == LED3 || i == LED4 || i == LED5) && all_leds == 0)
    {
      continue;
    }
    if (gpio_value(i, 0) != 0)
    {
      fprintf(stderr, "error: couldn't write gpio value for port         %d!\n", i);
      continue;
    }
  }

  // Wait one second
  sleep(1);

  // Write high
  for (i = LED1; i <= LED6; i++)
  {
    // If 3,4 and 5 are already reserved, just skip
    if ((i == LED3 || i == LED4 || i == LED5) && all_leds == 0)
    {
      continue;
    }
    if (gpio_value(i, 1) != 0)
    {
      fprintf(stderr, "error: couldn't write gpio value for port         %d!\n", i);
      continue;
    }
  }

  // Wait one second
  sleep(1);
}

This section of code is just a loop that turns the ports from low to high to back to low repeatedly with a second pause in between. This is using the gpio sys helper class to set the gpio port value. You can also use the gpio sys helper class to read in gpio values if the gpio is an input.

Note that this demo is coded for the BF548 EZ-KIT and the check for LED3, LED4 and LED5 is because these ports are in use by the spi as well and may already be reserved by the spi driver and out of use. Disabling the spi driver can enable these ports to be used.

Compiling blink

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 blink.c gpio.c -o blink

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 final parameters match up to standard gcc compiling; “blink.c” is the source file, “gpio.c” has the blink functions source code and ”-o blink” indicates the output file is blink.

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

root:/> make blink

Further Reading

The gpio sys fs page on the wiki is located at GPIO sysfs Interface. You can actually do all these gpio settings via the terminal prompt as shown on that page. That is a good way to debug gpio.

The page Interrupts shows a mapping of ports to their aliases.