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!
/*
* 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;
}
}