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; } }