Because of the holidays, TI E2E™ design support forum responses will be delayed from Dec. 25 through Jan. 2. Thank you for your patience.

This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Blinking LED using BeagleBone Black by GPIO

Hi, I am using BeagleBone Black to blink LED through GPIO programming. QNX is installed on BBB. Now I can control ON/OFF states of USER1 by this command line:

#beaglebone_gpio -m 2 -p 22 -d write -c set

#beaglebone_gpio -m 2 -p 22 -d write -c reset

But it cannot control my LED on bread board, which uses Pin12 on P9 header driven by a transistor. When run the following command, LED will not blink. LED always lights on. (Shown as the picture)

#beaglebone_gpio -m 2 -p 28 -d write -c set

#beaglebone_gpio -m 2 -p 28 -d write -c reset

While read the status of GPIO1[28], the value is correct.

#beaglebone_gpio -m 2 -p 28 -d write -c read

0x1 (set) or 0x0 (reset)

The source code file is attached here, please give me some advice to solve the problem.

Thanks in advance!

3348.beaglebone_gpio.c
/*
 * This program enables the user to fiddle with GPIO pins.
 */

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <hw/inout.h>
#include <sys/neutrino.h>
#include <sys/mman.h>
#include <errno.h>
#include <string.h>

// See page 4640 of SPRUF73I (AM335X) October 2011
// Base address of GPIO0
#define AM335X_GPIO0_BASE		    0x44E07000
// Base address of GPIO1
#define AM335X_GPIO1_BASE		    0x4804C000
// Base address of GPIO2
#define AM335X_GPIO2_BASE		    0x481AC000
// Base address of GPIO3
#define AM335X_GPIO3_BASE		    0x481AE000
// GPIO register size
#define AM335X_GPIO_SIZE		    0x1000
// This register is used to enable the pins output capabilities.
#define AM335X_GPIO_OE		    	0x134
//This register is used to register the data that is read from the GPIO pins.
#define AM335X_GPIO_DATAIN			0x138
//This register is used for setting the value of the GPIO output pins
#define AM335X_GPIO_DATAOUT			0x13C
//This register is used to register the data that is read from the GPIO pins.
#define AM335X_GPIO_SETDATAOUT		0x190
//This register is used for setting the value of the GPIO output pins
#define AM335X_GPIO_CLEARDATAOUT	0x194

uint64_t gpio_base[] = {
	AM335X_GPIO0_BASE,
	AM335X_GPIO1_BASE,
	AM335X_GPIO2_BASE,
	AM335X_GPIO3_BASE,
	NULL
};

volatile void *gpio_addr = NULL;
volatile unsigned int *gpio_oe_addr = NULL;
volatile unsigned int *gpio_dataout_addr = NULL;
volatile unsigned int *gpio_datain_addr = NULL;
volatile unsigned int *gpio_setdataout_addr = NULL;
volatile unsigned int *gpio_cleardataout_addr = NULL;

void gpio_set(int pin)
{
	unsigned int reg;
	gpio_dataout_addr = gpio_addr + AM335X_GPIO_DATAOUT;
	reg = *gpio_dataout_addr;
	reg = reg | (1 << pin);
	*gpio_dataout_addr = reg;
}

void gpio_reset(int pin)
{
	unsigned int reg;
	gpio_dataout_addr = gpio_addr + AM335X_GPIO_DATAOUT;
	reg = *gpio_dataout_addr;
	reg = reg & ~(1 << pin);
	*gpio_dataout_addr = reg;
}

int gpio_read(int direction, int pin)
{
	int pin_value = 0;
	unsigned int reg;
	if (direction == 0) {
		gpio_dataout_addr = gpio_addr + AM335X_GPIO_DATAOUT;
		reg = *gpio_dataout_addr;
		if (reg & (1 << pin)) {
			pin_value = 1;
		}
	}
	else if (direction == 1) {
		gpio_datain_addr = gpio_addr + AM335X_GPIO_DATAIN;
		reg = *gpio_datain_addr;
		if (reg & (1 << pin)) {
			pin_value = 1;
		}
	}
	else{
		pin_value = -1;
	}
	return pin_value;
}

void gpio_set_direction(int direction, int pin)
{
	unsigned int reg;
	gpio_oe_addr = gpio_addr + AM335X_GPIO_OE;
	reg = *gpio_oe_addr;
	if (direction == 0) {
		reg = reg & ~(1 << pin);
		*gpio_oe_addr = reg;
	} else {
		reg = reg | (1 << pin);
		*gpio_oe_addr = reg;
	}
}

int main (int argc, char *argv[])
{
	int opt = 0, verbose = 0, pin = -1, direction = -1, gpio_module = -1;
	int cmd = -1;
	extern char *optarg;

	// Handle commandline arguments
	// -m gpio_module  The GPIO module. Can be a value from 1 to 6
	// -p pin          The GPIO pin you want to set
	// -d direction    The direction of the GPIO pin. Can be: 0 (=write) | 1(=read)
	// -c command      Action to perform. Can be: set | reset | read
	while ((opt = getopt(argc, argv, "m:p:d:c:v")) != -1) {
		switch (opt) {
		case 'm':
			gpio_module = strtol(optarg, NULL, 10);
			if (errno != 0) gpio_module = -1;
			break;
		case 'p':
			pin = strtol(optarg, NULL, 10);
			if (errno != 0) pin = -1;
			break;
		case 'd':
			direction = strtol(optarg, NULL, 10);
			if (errno != 0 || direction > 1) direction = -1;

			if (strcmp(optarg, "write") == 0) direction = 0;
			else if (strcmp(optarg, "read")  == 0) direction = 1;
			else direction = -1;
		case 'c':
			if (strcmp(optarg, "set")   == 0) cmd = 0;
			else if (strcmp(optarg, "reset") == 0) cmd = 1;
			else if (strcmp(optarg, "read")  == 0) cmd = 2;
			else cmd = -1;
			break;
		case 'v':
			verbose++;
			break;
		default:
			break;
		}
	}

	if (gpio_module != -1 && pin != -1 && direction != -1 && cmd != -1) {

		/* enable this thread to execute i/o functions... */
	   	ThreadCtl(_NTO_TCTL_IO, 0);

	   	gpio_addr = mmap_device_memory(0, AM335X_GPIO_SIZE, PROT_READ | PROT_WRITE | PROT_NOCACHE, 0, gpio_base[gpio_module - 1]);
	   	if (gpio_addr == MAP_FAILED) {
	   	    perror("mmap_device_memory for physical address failed");
	   	    exit( EXIT_FAILURE );
	   	}

	   	gpio_set_direction(pin, direction);

	   	if (cmd == 0) gpio_set(pin);
	   	if (cmd == 1) gpio_reset(pin);
	   	if (cmd == 2) printf("0x%x\n", gpio_read(direction, pin));

	   	munmap_device_memory((void *)gpio_addr, AM335X_GPIO_SIZE);
		return 0;
	} else {
		printf("Illegal command line options provided\n");
		return -1;
	}
}