GPIO API general (Orange Pi ... H3)

Hello folks!

I successfully installed armv7 RELEASE 13.0 GENERIC on my Orange Pi Pc Plus (AllWinner H3 SoC sunxi8).
I set up LAN and DHCP so that I connect to the device via SSH.

As for the use of a 40 pin GPIO connector, I have some experience with STM32 NUCLEO boards, but I do not how GPIO is used via CLI or CMD from the operating system?
Where can I find instructions for this (or SPI) as well as the required packages and ports and commands?
 
Finding what pin is FreeBSD GPIO Pin to 40 pin header can be challenging.

I write small scripts trying setting output state on groups of pins and I hookup test LED.
This way is horrible because GPIO controls everything from ethernet to display.
Go and flip the state on your SD Card GPIO line. It will crash.

So Linux exports GPIO's to userland and we do not. So be careful.
One godsend is that most Arm boards follow a similar 40 pin layout.
UART console on same pins pretty reliably.

What I have started to do is look at labeling that U-Boot command prompt has for GPIO pins.
On my Rock64 u-boot does not use GPIO command but instead PINCTL.
So I don't know if this is different per architecture or what. Maybe its a new method they are switching too I dunno.

I suggest you learn how to get into u-boot command prompt and poke around GPIO/PINCTL
When you run help from u-boot command prompt it will show you which is used.
 
Thanks, man!
I'll inform you of the results when starting the journey...
To deal with u-boot at the start time I need to connect TTL to USB serial device (The HDMI for my device is not yet supported).
Before setting LAN, DHCP and SSH I had used it for the very first time ...

For now I find useful info for my device from file:
/usr/src/sys/arm/allwinner/h3/h3_padconf.c

C:
const static struct allwinner_pins h3_pins[] = {
    {"PA0",  0, 0,  {"gpio_in", "gpio_out", "uart2", "jtag", NULL, NULL, "pa_eint0", NULL}, 6, 0},
    {"PA1",  0, 1,  {"gpio_in", "gpio_out", "uart2", "jtag", NULL, NULL, "pa_eint1", NULL}, 6, 1},
    {"PA2",  0, 2,  {"gpio_in", "gpio_out", "uart2", "jtag", NULL, NULL, "pa_eint2", NULL}, 6, 2},
    {"PA3",  0, 3,  {"gpio_in", "gpio_out", "uart2", "jtag", NULL, NULL, "pa_eint3", NULL}, 6, 3},
    {"PA4",  0, 4,  {"gpio_in", "gpio_out", "uart0", NULL, NULL, NULL, "pa_eint4", NULL}, 6, 4},
    {"PA5",  0, 5,  {"gpio_in", "gpio_out", "uart0", "pwm0", NULL, NULL, "pa_eint5", NULL}, 6, 5},
    {"PA6",  0, 6,  {"gpio_in", "gpio_out", "sim", NULL, NULL, NULL, "pa_eint6", NULL}, 6, 6},
    {"PA7",  0, 7,  {"gpio_in", "gpio_out", "sim", NULL, NULL, NULL, "pa_eint7", NULL}, 6, 7},
    {"PA8",  0, 8,  {"gpio_in", "gpio_out", "sim", NULL, NULL, NULL, "pa_eint8", NULL}, 6, 8},
    {"PA9",  0, 9,  {"gpio_in", "gpio_out", "sim", NULL, NULL, NULL, "pa_eint9", NULL}, 6, 9},
    {"PA10", 0, 10, {"gpio_in", "gpio_out", "sim", NULL, NULL, NULL, "pa_eint10", NULL}, 6, 10},
    {"PA11", 0, 11, {"gpio_in", "gpio_out", "i2c0", "di", NULL, NULL, "pa_eint11", NULL}, 6, 11},
    {"PA12", 0, 12, {"gpio_in", "gpio_out", "i2c0", "di", NULL, NULL, "pa_eint12", NULL}, 6, 12},
    {"PA13", 0, 13, {"gpio_in", "gpio_out", "spi1", "uart3", NULL, NULL, "pa_eint13", NULL}, 6, 13},
    {"PA14", 0, 14, {"gpio_in", "gpio_out", "spi1", "uart3", NULL, NULL, "pa_eint14", NULL}, 6, 14},
    {"PA15", 0, 15, {"gpio_in", "gpio_out", "spi1", "uart3", NULL, NULL, "pa_eint15", NULL}, 6, 15},
    {"PA16", 0, 16, {"gpio_in", "gpio_out", "spi1", "uart3", NULL, NULL, "pa_eint16", NULL}, 6, 16},
    {"PA17", 0, 17, {"gpio_in", "gpio_out", "spdif", NULL, NULL, NULL, "pa_eint17", NULL}, 6, 17},
    {"PA18", 0, 18, {"gpio_in", "gpio_out", "i2s0", "i2c1", NULL, NULL, "pa_eint18", NULL}, 6, 18},
    {"PA19", 0, 19, {"gpio_in", "gpio_out", "i2s0", "i2c1", NULL, NULL, "pa_eint19", NULL}, 6, 19},
    {"PA20", 0, 20, {"gpio_in", "gpio_out", "i2s0", "sim", NULL, NULL, "pa_eint20", NULL}, 6, 20},
    {"PA21", 0, 21, {"gpio_in", "gpio_out", "i2s0", "sim", NULL, NULL, "pa_eint21", NULL}, 6, 21},

    {"PC0",  2, 0,  {"gpio_in", "gpio_out", "nand", "spi0", NULL, NULL, NULL, NULL}},
    {"PC1",  2, 1,  {"gpio_in", "gpio_out", "nand", "spi0", NULL, NULL, NULL, NULL}},
    {"PC2",  2, 2,  {"gpio_in", "gpio_out", "nand", "spi0", NULL, NULL, NULL, NULL}},
    {"PC3",  2, 3,  {"gpio_in", "gpio_out", "nand", "spi0", NULL, NULL, NULL, NULL}},
    {"PC4",  2, 4,  {"gpio_in", "gpio_out", "nand", NULL, NULL, NULL, NULL, NULL}},
    {"PC5",  2, 5,  {"gpio_in", "gpio_out", "nand", "mmc2", NULL, NULL, NULL, NULL}},
    {"PC6",  2, 6,  {"gpio_in", "gpio_out", "nand", "mmc2", NULL, NULL, NULL, NULL}},
    {"PC7",  2, 7,  {"gpio_in", "gpio_out", "nand", NULL, NULL, NULL, NULL, NULL}},
    {"PC8",  2, 8,  {"gpio_in", "gpio_out", "nand", "mmc2", NULL, NULL, NULL, NULL}},
    {"PC9",  2, 9,  {"gpio_in", "gpio_out", "nand", "mmc2", NULL, NULL, NULL, NULL}},
    {"PC10", 2, 10, {"gpio_in", "gpio_out", "nand", "mmc2", NULL, NULL, NULL, NULL}},
    {"PC11", 2, 11, {"gpio_in", "gpio_out", "nand", "mmc2", NULL, NULL, NULL, NULL}},
    {"PC12", 2, 12, {"gpio_in", "gpio_out", "nand", "mmc2", NULL, NULL, NULL, NULL}},
    {"PC13", 2, 13, {"gpio_in", "gpio_out", "nand", "mmc2", NULL, NULL, NULL, NULL}},
    {"PC14", 2, 14, {"gpio_in", "gpio_out", "nand", "mmc2", NULL, NULL, NULL, NULL}},
    {"PC15", 2, 15, {"gpio_in", "gpio_out", "nand", "mmc2", NULL, NULL, NULL, NULL}},
    {"PC16", 2, 16, {"gpio_in", "gpio_out", "nand", "mmc2", NULL, NULL, NULL, NULL}},

    {"PD0",  3, 0,  {"gpio_in", "gpio_out", "emac", NULL, NULL, NULL, NULL, NULL}},
    {"PD1",  3, 1,  {"gpio_in", "gpio_out", "emac", NULL, NULL, NULL, NULL, NULL}},
    {"PD2",  3, 2,  {"gpio_in", "gpio_out", "emac", NULL, NULL, NULL, NULL, NULL}},
    {"PD3",  3, 3,  {"gpio_in", "gpio_out", "emac", NULL, NULL, NULL, NULL, NULL}},
    {"PD4",  3, 4,  {"gpio_in", "gpio_out", "emac", NULL, NULL, NULL, NULL, NULL}},
    {"PD5",  3, 5,  {"gpio_in", "gpio_out", "emac", NULL, NULL, NULL, NULL, NULL}},
    {"PD6",  3, 6,  {"gpio_in", "gpio_out", "emac", NULL, NULL, NULL, NULL, NULL}},
    {"PD7",  3, 7,  {"gpio_in", "gpio_out", "emac", NULL, NULL, NULL, NULL, NULL}},
    {"PD8",  3, 8,  {"gpio_in", "gpio_out", "emac", NULL, NULL, NULL, NULL, NULL}},
    {"PD9",  3, 9,  {"gpio_in", "gpio_out", "emac", NULL, NULL, NULL, NULL, NULL}},
    {"PD10", 3, 10, {"gpio_in", "gpio_out", "emac", NULL, NULL, NULL, NULL, NULL}},
    {"PD11", 3, 11, {"gpio_in", "gpio_out", "emac", NULL, NULL, NULL, NULL, NULL}},
    {"PD12", 3, 12, {"gpio_in", "gpio_out", "emac", NULL, NULL, NULL, NULL, NULL}},
    {"PD13", 3, 13, {"gpio_in", "gpio_out", "emac", NULL, NULL, NULL, NULL, NULL}},
    {"PD14", 3, 14, {"gpio_in", "gpio_out", "emac", NULL, NULL, NULL, NULL, NULL}},
    {"PD15", 3, 15, {"gpio_in", "gpio_out", "emac", NULL, NULL, NULL, NULL, NULL}},
    {"PD16", 3, 16, {"gpio_in", "gpio_out", "emac", NULL, NULL, NULL, NULL, NULL}},
    {"PD17", 3, 17, {"gpio_in", "gpio_out", "emac", NULL, NULL, NULL, NULL, NULL}},

    {"PE0",  4, 0,  {"gpio_in", "gpio_out", "csi", "ts", NULL, NULL, NULL, NULL}},
    {"PE1",  4, 1,  {"gpio_in", "gpio_out", "csi", "ts", NULL, NULL, NULL, NULL}},
    {"PE2",  4, 2,  {"gpio_in", "gpio_out", "csi", "ts", NULL, NULL, NULL, NULL}},
    {"PE3",  4, 3,  {"gpio_in", "gpio_out", "csi", "ts", NULL, NULL, NULL, NULL}},
    {"PE4",  4, 4,  {"gpio_in", "gpio_out", "csi", "ts", NULL, NULL, NULL, NULL}},
    {"PE5",  4, 5,  {"gpio_in", "gpio_out", "csi", "ts", NULL, NULL, NULL, NULL}},
    {"PE6",  4, 6,  {"gpio_in", "gpio_out", "csi", "ts", NULL, NULL, NULL, NULL}},
    {"PE7",  4, 7,  {"gpio_in", "gpio_out", "csi", "ts", NULL, NULL, NULL, NULL}},
    {"PE8",  4, 8,  {"gpio_in", "gpio_out", "csi", "ts", NULL, NULL, NULL, NULL}},
    {"PE9",  4, 9,  {"gpio_in", "gpio_out", "csi", "ts", NULL, NULL, NULL, NULL}},
    {"PE10", 4, 10, {"gpio_in", "gpio_out", "csi", "ts", NULL, NULL, NULL, NULL}},
    {"PE11", 4, 11, {"gpio_in", "gpio_out", "csi", "ts", NULL, NULL, NULL, NULL}},
    {"PE12", 4, 12, {"gpio_in", "gpio_out", "csi", "i2c2", NULL, NULL, NULL, NULL}},
    {"PE13", 4, 13, {"gpio_in", "gpio_out", "csi", "i2c2", NULL, NULL, NULL, NULL}},
    {"PE14", 4, 14, {"gpio_in", "gpio_out", NULL, NULL, NULL, NULL, NULL, NULL}},
    {"PE15", 4, 15, {"gpio_in", "gpio_out", NULL, NULL, NULL, NULL, NULL, NULL}},

    {"PF0",  5, 0,  {"gpio_in", "gpio_out", "mmc0", "jtag", NULL, NULL, NULL, NULL}},
    {"PF1",  5, 1,  {"gpio_in", "gpio_out", "mmc0", "jtag", NULL, NULL, NULL, NULL}},
    {"PF2",  5, 2,  {"gpio_in", "gpio_out", "mmc0", "uart0", NULL, NULL, NULL, NULL}},
    {"PF3",  5, 3,  {"gpio_in", "gpio_out", "mmc0", "jtag", NULL, NULL, NULL, NULL}},
    {"PF4",  5, 4,  {"gpio_in", "gpio_out", "mmc0", "uart0", NULL, NULL, NULL, NULL}},
    {"PF5",  5, 5,  {"gpio_in", "gpio_out", "mmc0", "jtag", NULL, NULL, NULL, NULL}},
    {"PF6",  5, 6,  {"gpio_in", "gpio_out", NULL, NULL, NULL, NULL, NULL, NULL}},

    {"PG0",  6, 0,  {"gpio_in", "gpio_out", "mmc1", NULL, NULL, NULL, "pg_eint0", NULL}, 6, 0, 1},
    {"PG1",  6, 1,  {"gpio_in", "gpio_out", "mmc1", NULL, NULL, NULL, "pg_eint1", NULL}, 6, 1, 1},
    {"PG2",  6, 2,  {"gpio_in", "gpio_out", "mmc1", NULL, NULL, NULL, "pg_eint2", NULL}, 6, 2, 1},
    {"PG3",  6, 3,  {"gpio_in", "gpio_out", "mmc1", NULL, NULL, NULL, "pg_eint3", NULL}, 6, 3, 1},
    {"PG4",  6, 4,  {"gpio_in", "gpio_out", "mmc1", NULL, NULL, NULL, "pg_eint4", NULL}, 6, 4, 1},
    {"PG5",  6, 5,  {"gpio_in", "gpio_out", "mmc1", NULL, NULL, NULL, "pg_eint5", NULL}, 6, 5, 1},
    {"PG6",  6, 6,  {"gpio_in", "gpio_out", "uart1", NULL, NULL, NULL, "pg_eint6", NULL}, 6, 6, 1},
    {"PG7",  6, 7,  {"gpio_in", "gpio_out", "uart1", NULL, NULL, NULL, "pg_eint7", NULL}, 6, 7, 1},
    {"PG8",  6, 8,  {"gpio_in", "gpio_out", "uart1", NULL, NULL, NULL, "pg_eint8", NULL}, 6, 8, 1},
    {"PG9",  6, 9,  {"gpio_in", "gpio_out", "uart1", NULL, NULL, NULL, "pg_eint9", NULL}, 6, 9, 1},
    {"PG10", 6, 10, {"gpio_in", "gpio_out", "i2s1", NULL, NULL, NULL, "pg_eint10", NULL}, 6, 10, 1},
    {"PG11", 6, 11, {"gpio_in", "gpio_out", "i2s1", NULL, NULL, NULL, "pg_eint11", NULL}, 6, 11, 1},
    {"PG12", 6, 12, {"gpio_in", "gpio_out", "i2s1", NULL, NULL, NULL, "pg_eint12", NULL}, 6, 12, 1},
    {"PG13", 6, 13, {"gpio_in", "gpio_out", "i2s1", NULL, NULL, NULL, "pg_eint13", NULL}, 6, 13, 1},
};
 
Finding what pin is FreeBSD GPIO Pin to 40 pin header can be challenging.
A diagram like this plus output from gpioctl -l and you have everything you need:

lzt4s.png


So Linux exports GPIO's to userland and we do not.
Not sure what you mean.
 
Thanks, man!

I don't have much time for now so I just tried to turn on and off 2 LEDs via the CMD line:
Status red LED:
% sudo gpioctl -t PA15
Power green LED:
% sudo gpioctl -f /dev/gpioc1 -t PL10

Man it's works perfectly! ;)
I'm informing further progress ...?
 
Yes I know...

For now, this is the only way I did found to manage from the CMD line:

:~ # echo 0 > /dev/led/orangepi:green:pwr
:~ # echo 1 > /dev/led/orangepi:green:pwr
:~ # echo 0 > /dev/led/orangepi:red:status
:~ # echo 1 > /dev/led/orangepi:red:status
 
Not sure what you mean.
On Linux you have to export GPIO pins to sysfs to use them.
They only expose certain GPIO pins.
On FreeFBD gpioctl see's every GPIO line of the system and can alter state and change values crashing the board.

When I started with Arm on the Beaglebone with FreeBSD 10 they had the 4 board LED's available for raw manipulation with gpioctl. Now they fall under gpioled.
Nice that they have a device node. but it was fun and learning to manipulate the LEDs with gpioctl and scripts.
Plus no extra parts to buy and they had resistors built in properly.
I took the bonescript LED sample and made it work similarly on FreeBSD. They had a cool light sequence.

I wonder if we ever see something similar with GPIO.
GPIO device nodes under each parent GPIO controller.
/dev/gpioc2/PA12
That's how Linux does it from my scant knowledge..
 
What about pin muxing? How do you use alternertive GPIO pin states?

For example on IMX6 PWM1 can be on 3 different pins. One is default and two are alternates states.

Beaglebone had a real nice body of work there. Robert Nelson made it so.
Easy to find the pin muxing without digging thru code by good documentation.

But this was pre-overlays and you just mashed the DT fragment in somewhere.

I see NXP has a Linux software program for programming IMX pin mux state. Real nice graphical format.
I dream of programs like this on FreeBSD.....

How do you mux pins on FreeBSD these days? Write an overlay?

Man this would be a good job for u-boot. Need to read some...
 
What about pin muxing? How do you use alternertive GPIO pin states?

How do you mux pins on FreeBSD these days? Write an overlay?
I haven't had a chance to try it yet.
I want to try the SPI0 interface for my small display so I will have to use mux 3 as seen in the above picture. But before that, I will test the LED on one of the available pins...
 
I wonder if we ever see something similar with GPIO.
GPIO device nodes under each parent GPIO controller.
/dev/gpioc2/PA12
That's how Linux does it from my scant knowledge..
Is that in any way superior to the gpioctl method?
 
No. I was just musing. There is no wrong way.
Why did they use a device node for gpioled if it is un-superior?
That is the musings of a machinist. Not a programmer.
 
I have a problem with SPI, I can't find the any spi at /dev/spi...
At dmesg no info about SPI
I try:
:~ # kldstat
Id Refs Address Size Name
1 6 0xc0000000 cbe97c kernel
2 1 0xc0cc0000 23f84 umodem.ko
3 2 0xc0ce4000 26fe0 ucom.ko

After that:
:~ # kldload spibus
kldload: can't load spibus: module already loaded or in kernel
:~ # kldload spigen
kldload: can't load spigen: module already loaded or in kernel
:~ # kldload gpiospi
kldload: can't load gpiospi: module already loaded or in kernel
:~ # dmesg
KLD gpiospi.ko: depends on gpiospi - not available or version mismatch
module_register: cannot register spibus/spigen from spigen.ko; already loaded from kernel
Module spibus/spigen failed to register: 17
KLD gpiospi.ko: depends on gpiospi - not available or version mismatch

The result is same:
:~ # kldstat
Id Refs Address Size Name
1 6 0xc0000000 cbe97c kernel
2 1 0xc0cc0000 23f84 umodem.ko
3 2 0xc0ce4000 26fe0 ucom.ko

I try to add lines at rc.conf:
Code:
kld_list="spibus.ko"
kld_list="spigen.ko"
kld_list="gpiospi.ko"
and line at end of /boot/defaults/loader.conf:
Code:
sun8i-h3-orangepi-pc-plus.dtb_load="YES"
After rebooting, I didn't get any better results.
Any solution?
 
Code:
/dts-v1/;
/plugin/;

/ {
    compatible = "allwinner,sun8i-h3";

    fragment@0 {
        target = <&spi0>;
        __overlay__ {
            status = "okay";
        };
    };

    fragment@1 {
        target = <&spi1>;
         __overlay__ {
            status = "okay";
        };
    };

};
compile it with dtc -O dtb -I dts x.dts >/boot/dtb/overlays/spi-sunxi.dtbo
fdt_overlays="spi-sunxi.dtbo"
 
fdt_overlays="spi-sunxi.dtbo"
Where I must put this line?
at /etc/rc.conf or /boot/defaults/loader.conf ?
 
Back
Top