简体   繁体   中英

Can't access gpio line with gpiod_line_request_output() on Adafruit FT232H

I am using an Adafruit Ft232H breakout to add GPIO ports to my Linux pc. Although I had some success to flash a led with libftdi and bitbang mode, I don't have the same luck with libgpiod because gpiod_line_request_output is failing.

Some gpio information of my system:

sudo gpiodetect
gpiochip0 [ftdi-cbus] (4 lines)

sudo gpioinfo
gpiochip0 - 4 lines:
        line   0:      unnamed       unused   input  active-high 
        line   1:      unnamed       unused   input  active-high 
        line   2:      unnamed       unused   input  active-high 
        line   3:      unnamed       unused   input  active-high

This is the C program which tries to access the line 0.

#include <stdio.h>
#include <stdlib.h>

#include <gpiod.h>

#define LINE_NUM 0

void gpio_fatal(struct gpiod_chip* chip, const char msg[20]);

int main(int argc, char** argv)
{
    struct gpiod_chip*  chip;
    struct gpiod_line*  line;
    const char path[] = "/dev/gpiochip0";

    chip = gpiod_chip_open(path);
    if(!chip)
    {
        fprintf(stderr, "Error opening path\n");
        return EXIT_FAILURE;
    }

    line = gpiod_chip_get_line(chip, LINE_NUM);
    if(!line)
    {
        fprintf(stderr, "error getting this line\n");
        return EXIT_FAILURE;
    }

    int ret = gpiod_line_request_output(line,
                        "ftdi-cbus",
                        1);
    if(ret != 0)
        gpio_fatal(chip, "Request output failed");

    for(;;)
    {
        gpiod_line_set_value(line, 1);
        printf("On\n");
        sleep(1);
        gpiod_line_set_value(line, 0);
        printf("Off\n");
        sleep(1);
    }

    gpiod_line_release(line);
    gpiod_chip_close(chip);

    return EXIT_SUCCESS;
}

void gpio_fatal(struct gpiod_chip* chip, const char* msg)
{
    fprintf(stderr, "%s\n", msg);
    gpiod_chip_close(chip);
    exit(EXIT_FAILURE);
}

Running the executable with sudo gives me:

sudo g_gpiod/build/g_gpiod 
Password: 
Request output failed

gpiod.h states for the failing function the following:

/**
 * @brief Reserve a single line, set the direction to output.
 * @param line GPIO line object.
 * @param consumer Name of the consumer.
 * @param default_val Initial line value.
 * @return 0 if the line was properly reserved, -1 on failure.
 */
int gpiod_line_request_output(struct gpiod_line *line,
                  const char *consumer, int default_val) GPIOD_API;

The parameters seem to be correct, for what reason could this be failing? Other examples using libftdi or CircuitPython can access the ports and work correctly.

You need to flash the EEPROM to set the function of pin C5, eg using the ftdi_eeprom command from libftdi. First, unload the ftdi_sio module and save the original EEPROM:

$ sudo rmmod ftdi_sio
$ sudo ftdi_eeprom --verbose --device i:0x0403:0x6014 ft232h-orig.conf

FTDI eeprom generator v0.17
(c) Intra2net AG and the libftdi developers <opensource@intra2net.com>
FTDI read eeprom: 0
EEPROM size: 256
VID:     0x0403
PID:     0x6014
Release: 0x0900
Bus Powered: 100 mA
Manufacturer: ÿÿÿÿÿÿÿÿ
Product:      ÿÿÿÿÿÿ
Serial:       ÿÿÿÿÿÿÿÿ
Checksum      : ffff
PNP: 1
Channel A has Mode UART
FT1284 Mode Clock is idle LOW, MSB first, No Flow Control
ACBUS has 4 mA drive
ADBUS has 4 mA drive
C0 Function: TRISTATE
C1 Function: TRISTATE
C2 Function: TRISTATE
C3 Function: TRISTATE
C4 Function: TRISTATE
C5 Function: TRISTATE
C6 Function: TRISTATE
C7 Function: TRISTATE
C8 Function: DRIVE_1
C9 Function: DRIVE_0
FTDI close: 0

The file ft232h-orig.conf contains just a single line filename="ft232h-orig.bin" .

You can control 4 GPIO pins of the FT232H using the ftdi_sio module:

| line | pin | remarks   |
==========================
| 0    | C5  | -         |
| 1    | C6  | -         | 
| 2    | C8  | red led   |
| 3    | C9  | green led |

The Adafruit board has the cathodes of two LEDs (red and green) connected to pins C8 and C9. The default EEPROM has C9 set to DRIVE_0 so that the green LED is "on" when the board is powered up.

Here is my config file for ftdi_eeprom:

$ cat ft232h-libgpiod.conf
vendor_id="0x0403"
product_id="0x6014"
manufacturer="Adafruit"
product="FT232H Breakout"

# whatever
serial="20211223"
use_serial=true

max_power=100
self_powered=false
remote_wakeup=false

cha_type=UART
cha_vcp=false

cbush5=IOMODE
cbush6=IOMODE

# red led
cbush8=IOMODE

# green led
cbush9=DRIVE_0 # power-on indicator
#cbush9=IOMODE

$ sudo ftdi_eeprom --verbose --device i:0x0403:0x6014 --flash-eeprom ft232h-libgpiod.conf

Your program now works fine with line 0 on pin C5. As a bonus, you can now control the red LED with the libgpiod commands:

# turn red LED on (low active)
sudo gpioset gpiochip0 2=0

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM