Solved libgpio and pin pullup

I am having trouble doing the tutorial for switches and libgpio.

Manually, I am using a toggle switch and need to set the input via gpioctl in one line.
gpioctl -c 31 IN
gpioctl -c 31 PU
Does not work, Must be one line like so:
gpioctl -c 31 IN PU

No problem at all. Now I am coming to learn C library libgpio and I am trying to do the same.
Set the toggle button pin 31 to both IN and PU.

My problem is the tutorial only sets the pin with libgpio function input:
gpio_pin_input(handle, button_pin);
I can trigger the LED with one toggle of the switch, beyond that it does not detect any input(due to missing PU resistor)

When I add the following for pullup it seems the entire input fails according to gpioctl -l where the IN mode never gets set or PU.
gpio 31 is blank. It is not set to either IN or OUT. Prior to running my app it is set to Pin31 IN PU by default.
Code:
gpio_pin_input(handle, button_pin);
gpio_pin_pullup(handle, button_pin);/*My ADDED line*/
gpio_pin_output(handle, led_pin);
gpio_pin_low(handle, led_pin);
gpio_pin_low(handle, button_pin);
So how do I combine these two functions? gpio_pin_input and gpio_pin_pullup
It seems there is something I missed. This should be common.

The same for the output side. How to set OUT PU with libgpio?

If I manually adjust the pins from another shell with my program running then the switch and LED works fine.
gpioctl -c 31 IN PU
 
Last edited:
According to gpio(3) you can use gpio_pin_set_flags() function to set all flags at once (i.e. direction, pull up/down etc).
The flags are defined in /usr/include/sys/gpio.h, you can OR them. That function accepts the pin number and flags as a structure gpio_config_t (here is its definition).
 
That is exactly what I am working with now. I wrote a small program similar to the gpio handbook example.
Code:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <libgpio.h>

    int main(int argc, char **argv)
    {
        gpio_handle_t handle;
        handle = gpio_open(0);
        gpio_config_t cfg;
        cfg.g_pin=31;
        gpio_pin_config(handle, &cfg);
        printf("Pin %d: \"%u\"\n", cfg.g_pin, cfg.g_flags);
};

I wanted to see what it was expecting for g_flags. I was suprised what it showed:

Code:
root@beaglebone:/gpio # gpioctl -c 31 IN PU
root@beaglebone:/gpio # ./get.app
Pin 31: "33"
root@beaglebone:/gpio # gpioctl -c 31 IN
root@beaglebone:/gpio # ./get.app
Pin 31: "1"
root@beaglebone:/gpio # gpioctl -c 31 OUT
root@beaglebone:/gpio # ./get.app
Pin 31: "2"
root@beaglebone:/gpio # gpioctl -c 31 OUT PU
root@beaglebone:/gpio # ./get.app
Pin 31: "34"
 
So is that g_flags value a hex number like the overlays use ? Maybe I got a wrong data type?
 
Using the gpio.c gpio_pin_set_flag() function as a guide. I tried this for set_flags.c
Code:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <libgpio.h>
#include <strings.h>

    int main(int argc, char **argv)
    {
        gpio_handle_t handle;
        handle = gpio_open(0);
        gpio_config_t cfg;
        bzero(&cfg, sizeof(cfg));
        cfg.g_pin=31;
        if (gpio_pin_config(handle, &cfg) < 0)return (-1);
        cfg.g_flags = 33;
        gpio_pin_config(handle, &cfg);
        printf("Pin %d: \"%u\"\n", cfg.g_pin, cfg.g_flags);
};

I tried using the g_flags value I extracted as the setting. Am I anywhere close to being in the ballpark???
 
So here is my program that works for writing libgpio pin flags: set_flags.c
Code:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <libgpio.h>
#include <strings.h>

    int main(int argc, char **argv)
    {
        gpio_handle_t handle;
        handle = gpio_open(0);
        gpio_config_t cfg;
        bzero(&cfg, sizeof(cfg));
        cfg.g_pin=31;
        if (gpio_pin_config(handle, &cfg) < 0)return (-1);
        cfg.g_flags = 33;
        return (gpio_pin_set_flags(handle, &cfg));
        gpio_pin_config(handle, &cfg);
};
Here is my g_flags legend for the BBB Pin Modes:
1=IN
2=OUT
33=IN,PU
34=OUT,PU
65=IN,PD
 
How cool is it to build your own tools from libraries.
I got tired of Arm and started working on PC Engines APU with its GPIO driver -nctgpio.

The APU1 uses different pin flag types so my trusty get.app compiled great on amd64 and it fed me some new numbers:
APU1D GPIO Pin flags:

IN=1
OUT=2
IN OD=5
OUT OD=6
OUT PP=10

To light a LED it required OUT PP and that was showing 2.5v on my multimeter as the high.
 
In case your wonder why I am using a number value instead of the function name it is because I need 2 flags and passing them in plain text does not work. Passing one flag in plain text does work.

For Example:
cfg.g_flags = 33; works
cfg.g_flags = GPIO_PIN_INPUT, GPIO_PIN_PULLUP; does not work
 
Back
Top