How to make LED-display driver – Beaglebone

I have been playing around with the beaglebone for a while, and the latest project was to make a driver for my 7SEG-LED display using the GPIO ports.
I’m trying to learn more about kernel programming so i made a kernel-module for this task. Its also possible to make a driver like this in userspace, using exported variables in sysfs.

So at first I tried to figure out how to manage the mux configuration from the kernel. Sins the functions in mux.h is’nt exported, i wrote my own routine to set the mux-registers. The function uses the pin_mux structure and set the mux-registers to mux-mode 7 (GPIO).

static int setup_pin_mux(void)
{
	void* adress;
	int i;
	if (request_mem_region(AM33XX_CONTROL_PADCONF_MUX_PBASE, AM33XX_CONTROL_PADCONF_MUX_SIZE,"MuxMem") == NULL)
			printk("Error requesting mem reqion MUX_PBASE\n");

	adress = (void *)ioremap (AM33XX_CONTROL_PADCONF_MUX_PBASE,AM33XX_CONTROL_PADCONF_MUX_SIZE);

	if (adress == NULL)
	{
		printk("Error ioremap: MUX_PBASE\n");
		return -1;
	}

	for (i = 0; pin_mux[i].reg_offset != OMAP_MUX_TERMINATOR; i++)
			iowrite16(pin_mux[i].value, adress+pin_mux[i].reg_offset);

	iounmap(adress);
	release_mem_region(AM33XX_CONTROL_PADCONF_MUX_PBASE,AM33XX_CONTROL_PADCONF_MUX_SIZE);

	return 0;
}

Im using the GPIO ports at the P8 Expansion header. The LEDs are configurated as follow:

  • 3 LED1_1 – GPIO1_6
  • 4 LED1_2 – GPIO1_7
  • 5 LED1_3 – GPIO1_2
  • 6 LED1_4 – GPIO1_3
  • 7 LED1_5 – GPIO2_2
  • 8 LED1_6 – GPIO2_3
  • 9 LED1_7 – GPIO2_5
  • 10 LED1_8 – GPIO2_4
  • 11 LED2_1 – GPIO1_13
  • 12 LED2_2 – GPIO1_12
  • 13 LED2_3 – GPIO0_23
  • 14 LED2_4 – GPIO0_26
  • 15 LED2_5 – GPIO1_15
  • 16 LED2_6 – GPIO1_14
  • 17 LED2_7 – GPIO0_27
  • 18 LED2_8 – GPIO2_1
  • 19 LED1_SWITCH – GPIO0_22 (anode)
  • 20 LED2_SWITCH – GPIO1_31 (anode)

At the LED-display anode, ive put resistors at 480 Ohm, to get safe currents cause maximum output current is 8mA and input 6mA, according to  Gerald Coley. To calculate the resistor of the circuit you can use the formula: voltage – LED-voltage / LED-current.

The function display_number() sets the ledmask according to each number. So for example to display number 2, we set LED 1,2,4,5,7 to zero and LED1_SWITCH to 1.

You can display numbers by using the char-device. Either by writing ioctl command:  ioctl(fd,DISPLAY_SET, &output) or by writing directly to the char-device like “echo 20 > /dev/LED_display”

Right now im using the display to show the CPU-usage and it works great 🙂

To install the driver you run the load-script LED_display_load, and remove with LED_display_unload.

Get the source-code @ gitub.org

Feel free to ask questions and make comments!