Simple GPIO Example - quandry

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Simple GPIO Example - quandry

90,844 Views
johncoleman
Contributor IV

I am trying to build a simple GPIO Toggle Example on the IMX6UL UltraLite Board.

I have had no success yet.

I have created a simple HelloWorld project.

But, I can not expand it to include GPIO Access.

I can Not figure out how to include files such as gpio.h

But all of these fail: <gpio.h>  <Linux/gpio.h>  "Linux/gpio.h"  etc..

#include <stdio.h>

#include <gpio.h>

typedef unsigned long  U32;

typedef unsigned short U16;

typedef unsigned char  U8;

#define MX6SL_PAD_EPDC_SDCLK__GPIO1_IO23 0x110 0x400 0x000 0x5 0x0

// IOMUXC_SW_MUX_CTL_PAD_GPIO_1_23 = 20E_0000h base + 0x010

#define  GPIO_1_23_MUX_CTL       ( 0x2000000 + 0x0110 )

// IOMUXC_SW_PAD_CTL_PAD_GPIO_1_23 = 20E_0000h base + 0x000

#define  GPIO_1_23_PAD_CTL       ( 0x2000000 + 0x0400 )

// IOMUXC_SW_PAD_INPUT_GPIO_1_23   = 20E_0000h base + 0x0000

#define  GPIO_1_23_INPUT         ( 0x2000000 + 0x0000 )

// IOMUXC_SW_MUX_DATA_GPIO_1_23    = 0x05

#define  GPIO_1_23_MUX_DATA        ( 0x05 )

// IOMUXC_SW_CTL_DATA_GPIO_1_23    = 1 << 0x00

#define  GPIO_1_23_CTL_DATA     ( 0x01 << 0x00 )

#define MX6SL_PAD_EPDC_SDLE__GPIO1_IO24  0x114 0x404 0x000 0x5 0x0

#define MX6SL_PAD_EPDC_SDOE__GPIO1_IO25  0x118 0x408 0x000 0x5 0x0

#define MX6SL_PAD_EPDC_SDSHR__GPIO1_IO26 0x11c 0x40c 0x000 0x5 0x0

 

int _t_;

#define  msleep(n)  for(_t_=1; _t_<10000; _t_++){_t_=_t_;}

#define  true  1

//#define IMX_GPIO_NR(port, index) ((((port)-1)*32)+((index)&31))

#define  IMX_GPIO_NR(b,p)  ( ((b - 1) * 32) + p )

int main(int argc, char **argv)

{

    printf("Hello World!\n");

    gpio_request(IMX_GPIO_NR(3, 11), "external_gpio_0");

    gpio_export(IMX_GPIO_NR(3, 11), true);

    gpio_request(IMX_GPIO_NR(3, 27), "external_gpio_1");

    gpio_export(IMX_GPIO_NR(3, 27), true);

 gpio_direction_output( IMX_GPIO_NR(1,0) ,   1 );

    msleep(300);

    gpio_direction_output( IMX_GPIO_NR(2,18) ,  1 );

    msleep(300);

    gpio_direction_output( IMX_GPIO_NR(2,19) ,  1 );

    msleep(300);

    gpio_direction_output( IMX_GPIO_NR(1,20) ,  0 );

    gpio_direction_output( UART2_TX_DATA ,      0 );

    gpio_direction_output( IMX_GPIO_NR(1,21) ,  0 );

    gpio_direction_output( UART2_RX_DATA ,      0 );

    gpio_set_value(IMX_GPIO_NR(1, 0)  , 1);

    gpio_set_value(IMX_GPIO_NR(2, 18) , 1);

    gpio_set_value(IMX_GPIO_NR(2, 19) , 1);

    gpio_direction_output( IMX_GPIO_NR(1,23) ,  1 );

    gpio_set_value(IMX_GPIO_NR(1, 23)  , 1);

    msleep(1000);

    gpio_set_value(IMX_GPIO_NR(1, 23)  , 0);

    msleep(1000);

    gpio_set_value(IMX_GPIO_NR(1, 23)  , 1);

    msleep(1000);

    gpio_export(IMX_GPIO_NR(1, 23), true);

    gpio_direction_output( IMX_GPIO_NR(1,23) ,  1 );

    gpio_set_value(IMX_GPIO_NR(1, 23)  , 1);

    return 0;

}

I have also tried direct register access, but just got segment faults:

#include <stdio.h>

int main(int argc, char **argv)

{

    printf("Hello World!\n");

 

//printf("\nset MUX\n");

//      *((long*)0x0209C000??) = (5);  // -set MUX

printf("\nset DIR\n");

      *((long*)0x0209C004) = (1 << 23);  // -set GPIO_1_23.Dir = 1

printf("\nset DATA 23\n");

      *((long*)0x0209C000) = (1 << 23);  // -set GPIO_1_23.Dat = 1

 

    return 0;

}

Also this segmentation fault :

#include <stdio.h>

#define AIPS1_ARB_BASE_ADDR     0x02000000

#define AIPS1_ARB_END_ADDR      0x020FFFFF

#define AIPS2_ARB_BASE_ADDR     0x02100000

#define AIPS2_ARB_END_ADDR      0x021FFFFF

#define AIPS_TZ1_BASE_ADDR AIPS1_ARB_BASE_ADDR

#define AIPS_TZ2_BASE_ADDR AIPS2_ARB_BASE_ADDR

#define AIPS1_ON_BASE_ADDR (AIPS_TZ1_BASE_ADDR+0x7C000)

#define AIPS1_OFF_BASE_ADDR (AIPS_TZ1_BASE_ADDR+0x80000)

#define GPIO1_BASE_ADDR (AIPS1_OFF_BASE_ADDR+0x1C000)

#define IOMUXC_BASE_ADDR (AIPS1_OFF_BASE_ADDR+0x60000)

#define CCM_BASE_ADDR (AIPS1_OFF_BASE_ADDR+0x44000)

#define reg_32_CSU_SA (*(volatile U32*)(0x021C0218))

#define NSA_CP15 1

 

#define R32   (volatile unsigned long *)

#define R16   (volatile unsigned short *)

#define R8    (volatile unsigned char *)

typedef unsigned long  U32;

typedef unsigned short U16;

typedef unsigned char  U8;

 

int _t_;

#define  msleep(n)  for(_t_=1; _t_<10000; _t_++){_t_=_t_;}

#define  true  1

 

int main(int argc, char **argv)

{

    printf("Hello World!\n");

      //Write to DIR register [DIR]

      *R32(GPIO1_BASE_ADDR+4) = 0x00000004;  // 1 : GPIO 1_2  - output

      *R32 (GPIO1_BASE_ADDR) = 0x00000004;  // 1 --> GPIO 1_2

      *R32 ( GPIO1_BASE_ADDR) = 0  ;  // 0 --> GPIO 1_2

    return 0;

}

//

I also tried adding these lines below in the  conf/bblayers.conf  file, but still with No Results :

FILESPATH_append = "~/yocto_3.14.38-6UL/build/tmp/work/cortexa7hf-vfp-neon-poky-linux-gnueabi/linux-libc-headers/3.14-r0/linux-3.14/include/linux:"
FILESPATH_append = "~/yocto_3.14.38-6UL/build/tmp/work/cortexa7hf-vfp-neon-poky-linux-gnueabi/linux-libc-headers/3.14-r0/linux-3.14/include:"

FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
FILESEXTRAPATHS_append = "~/yocto_3.14.38-6UL/build/tmp/work/cortexa7hf-vfp-neon-poky-linux-gnueabi/linux-libc-headers/3.14-r0/linux-3.14/include/linux:"
FILESEXTRAPATHS_append = "~/yocto_3.14.38-6UL/build/tmp/work/cortexa7hf-vfp-neon-poky-linux-gnueabi/linux-libc-headers/3.14-r0/linux-3.14/include:"

SRC_URI += "~/yocto_3.14.38-6UL/build/tmp/work/cortexa7hf-vfp-neon-poky-linux-gnueabi/linux-libc-headers/3.14-r0/linux-3.14/include/linux/gpio.h"

Labels (4)
Tags (2)
60 Replies

6,710 Views
BiyongSUN
NXP Employee
NXP Employee

You don't have to re-compile  kernel(zImage). Just compile the dts file.

This is just for remove the GPIO from usdhc1.

II use the GPIO19, just want to introduce more linux development concepts and  technologies here.

For test purpose, you can just use the memtool. And choose which one is not used as GPIO in current dts.

118559_118559.pngUntitled.png

root@imx6ulevk:~# /unit_tests/memtool IOMUXC.SW_MUX_CTL_PAD_SD1_DATA1.MUX_MODE=5
SOC: i.MX6UL
write 0x00000005 to Bit 0..3 of 0x020E01C8
root@imx6ulevk:~#
root@imx6ulevk:~# /unit_tests/memtool IOMUXC.SW_MUX_CTL_PAD_SD1_DATA1.SION=1
SOC: i.MX6UL
write 0x00000001 to Bit 4..4 of 0x020E01C8
root@imx6ulevk:~#
root@imx6ulevk:~#
root@imx6ulevk:~# echo 51 > /sys/class/gpio/export
root@imx6ulevk:~#
root@imx6ulevk:~# echo out  > /sys/class/gpio/gpio51/direction
root@imx6ulevk:~# cat /sys/kernel/debug/gpio
GPIOs 0-31, platform/209c000.gpio, 209c000.gpio:
gpio-3   (tsc_X-              ) in  hi   
gpio-9   (VSD_3V3             ) out lo   
gpio-19  (2190000.usdhc cd    ) in  hi

GPIOs 32-63, platform/20a0000.gpio, 20a0000.gpio:
gpio-51  (sysfs               ) out lo   

GPIOs 64-95, platform/20a4000.gpio, 20a4000.gpio:

GPIOs 96-127, platform/20a8000.gpio, 20a8000.gpio:
gpio-119 (?                   ) out lo

GPIOs 128-159, platform/20ac000.gpio, 20ac000.gpio:
gpio-131 (?                   ) out lo   
gpio-132 (headset detect      ) in  lo   
gpio-135 (spi32766.0          ) out lo   
gpio-136 (?                   ) out lo   
gpio-138 (spi4.14             ) out lo   
gpio-139 (spi4.14             ) out lo

GPIOs 248-255, spi/spi32766.0, 74hc595, can sleep:
root@imx6ulevk:~#
root@imx6ulevk:~# echo 1 > /sys/class/gpio/gpio51/value
root@imx6ulevk:~#
root@imx6ulevk:~# cat /sys/kernel/debug/gpio
GPIOs 0-31, platform/209c000.gpio, 209c000.gpio:
gpio-3   (tsc_X-              ) in  hi   
gpio-9   (VSD_3V3             ) out lo   
gpio-19  (2190000.usdhc cd    ) in  hi

GPIOs 32-63, platform/20a0000.gpio, 20a0000.gpio:
gpio-51  (sysfs               ) out hi   

GPIOs 64-95, platform/20a4000.gpio, 20a4000.gpio:

GPIOs 96-127, platform/20a8000.gpio, 20a8000.gpio:
gpio-119 (?                   ) out lo

GPIOs 128-159, platform/20ac000.gpio, 20ac000.gpio:
gpio-131 (?                   ) out lo   
gpio-132 (headset detect      ) in  lo   
gpio-135 (spi32766.0          ) out lo   
gpio-136 (?                   ) out lo   
gpio-138 (spi4.14             ) out lo   
gpio-139 (spi4.14             ) out lo

GPIOs 248-255, spi/spi32766.0, 74hc595, can sleep:
root@imx6ulevk:~#

118560_118560.pngUntitled.png

/unit_tests/memtool IOMUXC.SW_MUX_CTL_PAD_ENET2_TX_DATA1.MUX_M ODE=5
SOC: i.MX6UL
write 0x00000005 to Bit 0..3 of 0x020E00F4
root@imx6ulevk:~# /unit_tests/memtool IOMUXC.SW_MUX_CTL_PAD_ENET2_TX_DATA1.SION= 1
SOC: i.MX6UL
write 0x00000001 to Bit 4..4 of 0x020E00F4
root@imx6ulevk:~#
root@imx6ulevk:~#
root@imx6ulevk:~# echo 44 > /sys/class/gpio/export
root@imx6ulevk:~#
root@imx6ulevk:~# echo out  > /sys/class/gpio/gpio44/direction
root@imx6ulevk:~# cat /sys/kernel/debug/gpio
GPIOs 0-31, platform/209c000.gpio, 209c000.gpio:
gpio-3   (tsc_X-              ) in  hi   
gpio-9   (VSD_3V3             ) out lo   
gpio-19  (2190000.usdhc cd    ) in  hi

GPIOs 32-63, platform/20a0000.gpio, 20a0000.gpio:
gpio-44  (sysfs               ) out lo   

GPIOs 64-95, platform/20a4000.gpio, 20a4000.gpio:

GPIOs 96-127, platform/20a8000.gpio, 20a8000.gpio:
gpio-119 (?                   ) out lo

GPIOs 128-159, platform/20ac000.gpio, 20ac000.gpio:
gpio-131 (?                   ) out lo   
gpio-132 (headset detect      ) in  lo   
gpio-135 (spi32766.0          ) out lo   
gpio-136 (?                   ) out lo   
gpio-138 (spi4.14             ) out lo   
gpio-139 (spi4.14             ) out lo

GPIOs 248-255, spi/spi32766.0, 74hc595, can sleep:
root@imx6ulevk:~#
root@imx6ulevk:~# echo 1 > /sys/class/gpio/gpio44/value
root@imx6ulevk:~#
root@imx6ulevk:~# cat /sys/kernel/debug/gpio
GPIOs 0-31, platform/209c000.gpio, 209c000.gpio:
gpio-3   (tsc_X-              ) in  hi   
gpio-9   (VSD_3V3             ) out lo   
gpio-19  (2190000.usdhc cd    ) in  hi

GPIOs 32-63, platform/20a0000.gpio, 20a0000.gpio:
gpio-44  (sysfs               ) out hi   

GPIOs 64-95, platform/20a4000.gpio, 20a4000.gpio:

GPIOs 96-127, platform/20a8000.gpio, 20a8000.gpio:
gpio-119 (?                   ) out lo

GPIOs 128-159, platform/20ac000.gpio, 20ac000.gpio:
gpio-131 (?                   ) out lo   
gpio-132 (headset detect      ) in  lo   
gpio-135 (spi32766.0          ) out lo   
gpio-136 (?                   ) out lo   
gpio-138 (spi4.14             ) out lo   
gpio-139 (spi4.14             ) out lo

GPIOs 248-255, spi/spi32766.0, 74hc595, can sleep:
root@imx6ulevk:~#

6,712 Views
almarto
Contributor IV

Hi Biyong,

To follow with my device tree customization, I want to add pwm functionality to some pins. I have chosen sd1_nrst (gpio_9) and sd1_vselect (gpio_5). According to imx6ul-pinfunc.h they can be used as pwm2 and pwm4.

at imx6ul-14x14-evk.dts I have modified the following:

//backlight

&pwm1 {

    pinctrl-names = "default";

    pinctrl-0 = <&pinctrl_pwm1>;

    status = "okay";

};

//added by me

&pwm2 {

    pinctrl-names = "default";

    pinctrl-0 = <&pinctrl_pwm2>;

    status = "okay";

};

&pwm4 {

    pinctrl-names = "default";

    pinctrl-0 = <&pinctrl_pwm4>;

    status = "okay";

};

//end

I have redefined the functionality of GPIO1_IO05 and GPIO1_IO09 at iomuxc as it is done for pwm1 (backlight):

&iomuxc {

    pinctrl-names = "default";

    pinctrl-0 = <&pinctrl_hog_1>;

    imx6ul-evk {

        pinctrl_hog_1: hoggrp-1 {

            fsl,pins = <

                //MX6UL_PAD_GPIO1_IO05__USDHC1_VSELECT    0x17059 /* SD1 VSELECT */
                //MX6UL_PAD_GPIO1_IO09__GPIO1_IO09        0x17059 /* SD1 RESET */

            >;
        };

.....

        pinctrl_pwm1: pwm1grp {
            fsl,pins = <
                MX6UL_PAD_GPIO1_IO08__PWM1_OUT   0x110b0
            >;
        };

        pinctrl_pwm2: pwm2grp {
            fsl,pins = <
                MX6UL_PAD_GPIO1_IO09__PWM2_OUT   0x110b0
            >;
        };
        pinctrl_pwm4: pwm4grp {
            fsl,pins = <
                MX6UL_PAD_GPIO1_IO05__PWM4_OUT   0x110b0
            >;
        };

I have not replaced the kernel, as I understand the pwm support is already enabled at Device drivers > pwm support > i.MX pwm support.

I can modify brightness of the backlight and it works: echo 5 > /sys/class/backlight/backlight.8/brightness

However, when I try to configure pwm2 and pwm4 at command line, the operating system does not respond and I have to reboot.

to work with pwm2 (gpio_9, sd1_nreset), I do the following:

$echo 0 > /sys/class/pwm/pwmchip1/export

it creates pwm0 folder and I try to set the period (1sec)

$echo 1000000000 > /sys/class/pwm/pwmchip1/pwm0/period

The system crashes here.

It happens the same if instead of trying to set the period, I enable the output or try to do any other thing.

It also happens with pwm4 (gpio_5, sd1_vselect)

$echo 0 > /sys/class/pwm/pwmchip3/export

it creates pwm0 folder and I try to set the period (1sec)

$echo 1000000000 > /sys/class/pwm/pwmchip3/pwm0/period

The system crashes here.

I happens the same if instead of trying to set the period, I enable the output or try to do any other thing.

If I execute cat /sys/kernel/debug/pwm, I get:

platform/20fc000.pwm, 1 PWM device

pwm-0   ((null)              ):

platform/20f8000.pwm, 1 PWM device

pwm-0   ((null)              ):

platform/20f4000.pwm, 1 PWM device

pwm-0   ((null)              ):

platform/20f0000.pwm, 1 PWM device

pwm-0   ((null)              ):

platform/208c000.pwm, 1 PWM device

pwm-0   ((null)              ):

platform/2088000.pwm, 1 PWM device

pwm-0   ((null)              ):

platform/2084000.pwm, 1 PWM device

pwm-0   ((null)              ):

platform/2080000.pwm, 1 PWM device

pwm-0   (backlight           ): requested enabled

Can you give me any hints about what I am doing wrong??

Thank you in advance and happy new year!

BR

0 Kudos
Reply

6,715 Views
BiyongSUN
NXP Employee
NXP Employee

If it is another topic of pwm , please sumbit new ticket.

thanks.

6,715 Views
almarto
Contributor IV

You are right Biyong!

I have created a new thread here: PWM with iMX6UL

BR

0 Kudos
Reply

6,715 Views
almarto
Contributor IV

Hi Biyong,

I have finally been able to run a modified dts for gpio and spi on the imx6ulevk following your indications. I would like to thank you for all your indications and help.

BR

0 Kudos
Reply

6,715 Views
johncoleman
Contributor IV

Where do I find this memtool ?

0 Kudos
Reply

6,715 Views
BiyongSUN
NXP Employee
NXP Employee

The source is inside the Yocto build  directory  downloads/imx-test-3.14.28-1.0.0.tar.gz

you can run bibake command to build it:

bitbake imx-test

memtool is one of the imx test utilities.

And the binary is already built in the rootfs.

/unit_tests/memtool

0 Kudos
Reply

6,790 Views
BiyongSUN
NXP Employee
NXP Employee

Let's pick up usdhc1 cd pin on i.mx6ul evk for test.

Untitled.png

The MX6UL_PAD_UART1_RTS_B is configured as GPIO1_IO19  in device tree, which is used by usdhc1 as sd1 cd.

MX6UL_PAD_UART1_RTS_B__GPIO1_IO19      0x17059 /* SD1 CD */


imx6ul-14x14-evk.dts

314 &usdhc1 {
315        pinctrl-names = "default", "state_100mhz", "state_200mhz";
316        pinctrl-0 = <&pinctrl_usdhc1>;
317        pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
318        pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
319        cd-gpios = <&gpio1 19 0>;
320        keep-power-in-suspend;
321        enable-sdio-wakeup;
322        vmmc-supply = <&reg_sd1_vmmc>;
323        status = "okay";
324 };

407 &iomuxc {
408        pinctrl-names = "default";
409        pinctrl-0 = <&pinctrl_hog_1>;
410        imx6ul-evk {
411                pinctrl_hog_1: hoggrp-1 {
412                        fsl,pins = <
413                                MX6UL_PAD_LCD_RESET__WDOG1_WDOG_ANY    0x30b0
414                                MX6UL_PAD_UART1_RTS_B__GPIO1_IO19      0x17059 /* SD1 CD */
415                                MX6UL_PAD_GPIO1_IO05__USDHC1_VSELECT    0x17059 /* SD1 VSELECT */
416                                MX6UL_PAD_GPIO1_IO09__GPIO1_IO09        0x17059 /* SD1 RESET */
417                        >;

Debug fs give us chance to check the gpio status:

cat /sys/kernel/debug/gpio

sdcard plugout: gpio-19  (2190000.usdhc cd    ) in  hi                       

sdcard plugin  : gpio-19  (2190000.usdhc cd    ) in lo

sdcard plug out:

root@imx6ulevk:~# cat /sys/kernel/debug/gpio


GPIOs 0-31, platform/209c000.gpio, 209c000.gpio:
gpio-3   (tsc_X-              ) in  hi
gpio-9   (VSD_3V3             ) out lo
gpio-19  (2190000.usdhc cd    ) in  hi

GPIOs 32-63, platform/20a0000.gpio, 20a0000.gpio:

GPIOs 64-95, platform/20a4000.gpio, 20a4000.gpio:

GPIOs 96-127, platform/20a8000.gpio, 20a8000.gpio:
gpio-119 (?                   ) out lo

GPIOs 128-159, platform/20ac000.gpio, 20ac000.gpio:
gpio-131 (?                   ) out lo
gpio-132 (headset detect      ) in  lo
gpio-135 (spi32766.0          ) out lo
gpio-136 (?                   ) out lo
gpio-138 (spi4.14             ) out lo
gpio-139 (spi4.14             ) out lo

sdcard plugin:

root@imx6ulevk:~# cat /sys/kernel/debug/gpio


GPIOs 0-31, platform/209c000.gpio, 209c000.gpio:
gpio-3   (tsc_X-              ) in  hi
gpio-9   (VSD_3V3             ) out lo
gpio-19  (2190000.usdhc cd    ) in  lo

GPIOs 32-63, platform/20a0000.gpio, 20a0000.gpio:

GPIOs 64-95, platform/20a4000.gpio, 20a4000.gpio:

GPIOs 96-127, platform/20a8000.gpio, 20a8000.gpio:
gpio-119 (?                   ) out lo

GPIOs 128-159, platform/20ac000.gpio, 20ac000.gpio:
gpio-131 (?                   ) out lo
gpio-132 (headset detect      ) in  lo
gpio-135 (spi32766.0          ) out lo
gpio-136 (?                   ) out lo
gpio-138 (spi4.14             ) out lo
gpio-139 (spi4.14             ) out lo

                                                     

But we could not use it as an indenpendent  GPIO, because this GPIO is used by usdhc1 module.

You will get busy when you try to use it as an independent GPIO.

root@imx6ulevk:~#  echo 19 >  /sys/class/gpio/export

-sh: echo: write error: Device or resource busy

root@imx6ulevk:~#

Let's modify the device tree to make gpio-19 isolated from usdhc1:

314 &usdhc1 {

315         pinctrl-names = "default", "state_100mhz", "state_200mhz";

316         pinctrl-0 = <&pinctrl_usdhc1>;

317         pinctrl-1 = <&pinctrl_usdhc1_100mhz>;

318         pinctrl-2 = <&pinctrl_usdhc1_200mhz>;

319 //      cd-gpios = <&gpio1 19 0>;

320         keep-power-in-suspend;

321         enable-sdio-wakeup;

322         vmmc-supply = <&reg_sd1_vmmc>;

323         status = "okay";

324 };

recompile the dts and get the new dtb file. replace the old one and reboot the i.mx6ul evk

let's check by debug fs and sys class  we could not find the gpio-19.

root@imx6ulevk:~# cat /sys/kernel/debug/gpio
GPIOs 0-31, platform/209c000.gpio, 209c000.gpio:
gpio-3   (tsc_X-              ) in  hi
gpio-9   (VSD_3V3             ) out lo

GPIOs 32-63, platform/20a0000.gpio, 20a0000.gpio:

GPIOs 64-95, platform/20a4000.gpio, 20a4000.gpio:

GPIOs 96-127, platform/20a8000.gpio, 20a8000.gpio:
gpio-119 (?                   ) out lo

GPIOs 128-159, platform/20ac000.gpio, 20ac000.gpio:
gpio-131 (?                   ) out lo
gpio-132 (headset detect      ) in  lo
gpio-135 (spi32766.0          ) out lo
gpio-136 (?                   ) out lo
gpio-138 (spi4.14             ) out lo
gpio-139 (spi4.14             ) out lo

root@imx6ulevk:~# ls /sys/class/gpio/

export   gpiochip0    gpiochip248  gpiochip64  unexport

gpio132  gpiochip128  gpiochip32   gpiochip96

Let's export gpio19

root@imx6ulevk:~# echo 19 >  /sys/class/gpio/export

root@imx6ulevk:~# ls /sys/class/gpio/

export   gpio19     gpiochip128  gpiochip32  gpiochip96

gpio132  gpiochip0  gpiochip248  gpiochip64  unexport

check with debug fs if we can see it.

Yes. we see it.

root@imx6ulevk:~# cat /sys/kernel/debug/gpio
GPIOs 0-31, platform/209c000.gpio, 209c000.gpio:
gpio-3   (tsc_X-              ) in  hi
gpio-9   (VSD_3V3             ) out lo
gpio-19  (sysfs               ) in  hi

GPIOs 32-63, platform/20a0000.gpio, 20a0000.gpio:

GPIOs 64-95, platform/20a4000.gpio, 20a4000.gpio:

GPIOs 96-127, platform/20a8000.gpio, 20a8000.gpio:
gpio-119 (?                   ) out lo

GPIOs 128-159, platform/20ac000.gpio, 20ac000.gpio:
gpio-131 (?                   ) out lo
gpio-132 (headset detect      ) in  lo
gpio-135 (spi32766.0          ) out lo
gpio-136 (?                   ) out lo
gpio-138 (spi4.14             ) out lo
gpio-139 (spi4.14             ) out lo

check the gpio-19 value

sdcard plugout:

root@imx6ulevk:~# cat /sys/class/gpio/gpio19/value

524288

sdcard plugin:

root@imx6ulevk:~# cat /sys/class/gpio/gpio19/value

0

why it is not 0 and 1?  because it is raw data. any nonzero value is treated as high

The following is from linux document.

It may also provide a customvalue for ARCH_NR_GPIOS, so that it better reflects the number of GPIOs in
actual use on that platform, without
wasting static table space.  (It should count both built-in/SoC GPIOs and

also ones on GPIO expanders.

Sysfs Interface for Userspace (OPTIONAL) 
"value" ... reads as either 0 (low) or 1 (high).  If the GPIO

is configured as an output, this value may be written;
 

any nonzero value is treated as high.

let's check with debug fs.

sdcard plug out:

root@imx6ulevk:~# cat /sys/kernel/debug/gpio
GPIOs 0-31, platform/209c000.gpio, 209c000.gpio:
gpio-3   (tsc_X-              ) in  hi
gpio-9   (VSD_3V3             ) out lo
gpio-19  (sysfs               ) in  hi

GPIOs 32-63, platform/20a0000.gpio, 20a0000.gpio:

GPIOs 64-95, platform/20a4000.gpio, 20a4000.gpio:

GPIOs 96-127, platform/20a8000.gpio, 20a8000.gpio:
gpio-119 (?                   ) out lo

GPIOs 128-159, platform/20ac000.gpio, 20ac000.gpio:
gpio-131 (?                   ) out lo
gpio-132 (headset detect      ) in  lo
gpio-135 (spi32766.0          ) out lo
gpio-136 (?                   ) out lo
gpio-138 (spi4.14             ) out lo
gpio-139 (spi4.14             ) out lo

sdcard plugin:

root@imx6ulevk:~# cat /sys/kernel/debug/gpio
GPIOs 0-31, platform/209c000.gpio, 209c000.gpio:
gpio-3   (tsc_X-              ) in  hi
gpio-9   (VSD_3V3             ) out lo
gpio-19  (sysfs               ) in  lo

GPIOs 32-63, platform/20a0000.gpio, 20a0000.gpio:

GPIOs 64-95, platform/20a4000.gpio, 20a4000.gpio:

GPIOs 96-127, platform/20a8000.gpio, 20a8000.gpio:
gpio-119 (?                   ) out lo

GPIOs 128-159, platform/20ac000.gpio, 20ac000.gpio:
gpio-131 (?                   ) out lo
gpio-132 (headset detect      ) in  lo
gpio-135 (spi32766.0          ) out lo
gpio-136 (?                   ) out lo
gpio-138 (spi4.14             ) out lo
gpio-139 (spi4.14             ) out lo

Do you notice it is show hi and lo, not a value. (remember any nonzero value is treated as high. )

Verify with memtool:

root@imx6ulevk:~# /unit_tests/memtool  GPIO1.DR.DR

SOC: i.MX6UL

GPIO1    Addr:0x209c000

  GPIO1.DR Addr:0x0209C000 Value:0xF00C0118 - The 32-bit GPIO_DR register stores data that is ready to be driven to the output lines.

     GPIO1.DR.DR(0..31)         :0xf00c0118

root@imx6ulevk:~# /unit_tests/memtool  GPIO1.DR.DR

SOC: i.MX6UL

GPIO1    Addr:0x209c000

  GPIO1.DR Addr:0x0209C000 Value:0xF0040118 - The 32-bit GPIO_DR register stores data that is ready to be driven to the output lines.

     GPIO1.DR.DR(0..31)         :0xf0040118

             Data bits.

0xf00c0118 ->  0xf0040118

bit 19     1 -> 0 (hi->lo)

Could we use  the debug fs for accessing  gpio from use space.

No. Please don't do that.

a. It is for debug purpose.

b. it could not handle output.

What we need to do for an independent?

Only one thing: Correct IOMUX pinctrl in device tree.

In this example is:

MX6UL_PAD_UART1_RTS_B__GPIO1_IO19      0x17059 /* SD1 CD */

407 &iomuxc {

408        pinctrl-names = "default";

409        pinctrl-0 = <&pinctrl_hog_1>;

410        imx6ul-evk {

411                pinctrl_hog_1: hoggrp-1 {

412                        fsl,pins = <

413                                MX6UL_PAD_LCD_RESET__WDOG1_WDOG_ANY    0x30b0

414                                MX6UL_PAD_UART1_RTS_B__GPIO1_IO19      0x17059 /* SD1 CD */

415                                MX6UL_PAD_GPIO1_IO05__USDHC1_VSELECT    0x17059 /* SD1 VSELECT */

416                                MX6UL_PAD_GPIO1_IO09__GPIO1_IO09        0x17059 /* SD1 RESET */

417                        >;

Why we  know echo 19 >  /sys/class/gpio/export Not other number?

Please run the command

for i in /sys/class/gpio/* ; do cat $i/label; cat $i/base; echo; done

209c000.gpio
0

20ac000.gpio
128

74hc595
248

20a0000.gpio
32

20a4000.gpio
64

20a8000.gpio
96

imx6ul.dtsi

468                         gpio1: gpio@0209c000 {

469                                 compatible = "fsl,imx6ul-gpio", "fsl,imx35-gpio";

470                                 reg = <0x0209c000 0x4000>;

471                                 interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,

472                                              <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;

473                                 gpio-controller;

474                                 #gpio-cells = <2>;

475                                 interrupt-controller;

476                                 #interrupt-cells = <2>;

477                         };

209c000 is for gpio1 and the base is "0".

So, the bit 19 is 0 + 19.

What does this caculation refer to?

It is the linux document I mentoined before.

Let take another example for 20a8000.gpio base is 96.

501                         gpio4: gpio@020a8000 {

502                                 compatible = "fsl,imx6ul-gpio", "fsl,imx35-gpio";

503                                 reg = <0x020a8000 0x4000>;

504                                 interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,

505                                              <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;

506                                 gpio-controller;

507                                 #gpio-cells = <2>;

508                                 interrupt-controller;

509                                 #interrupt-cells = <2>;

510                         };

If we want to use gpio4-11, we should do is to echo 107 > /sys/class/gpio/export

107 = 96 + 11

6,715 Views
andreyreyes
Contributor II

Hello Biyong!

Thank you for your explanation! I was able to successfully follow your steps and control an GPIO output but now I would like to setup and configure it from the device tree, which I started to learn recently.

In other words, I would like to boot up the board and already have my GPIO listed under /sys/class/gpio/<my_gpio> like other devices that use GPIO in the device tree and have it setup as low by default.

I am using an IMX6Q SABRED SD. I have seen many examples but I get stuck with IMX6 because I don't seems to find a "fsl,imx6q-gpio" or similar and I wouldn't know what to populate in the register field.

References I have been using:

Pin settings app note:

http://cache.freescale.com/files/32bit/doc/app_note/AN5078.pdf 

Device tree app note:

http://www.nxp.com/assets/documents/data/en/application-notes/AN5125.pdf 

More on device tree:

Device Tree Customization 

Linux docs:

Documentation/devicetree/bindings/gpio/gpio.txt

-Andrey-

0 Kudos
Reply

6,790 Views
rooftree
Contributor II

hi, biyong:

I want to use your method. But I can't find /sys/kernel/debug/gpio, in my /sys/kernel/debug directory,there is no any file. Is something I should config?

0 Kudos
Reply

6,790 Views
BiyongSUN
NXP Employee
NXP Employee

In the 3.10 BSP release and above,  the debugfs is mounted as default.

You can manually mount it

mount -t debugfs none /sys/kernel/debug

0 Kudos
Reply

6,740 Views
rooftree
Contributor II

Thank you very much!

0 Kudos
Reply

6,790 Views
johncoleman
Contributor IV

I successfully Disabled the UART2, ENET2, SD1 using the DTS file modifications , on the Imx6ul-14x14 Board.

&uart2 {

pinctrl-names = "default";

pinctrl-0 = <&pinctrl_uart2>;

fsl,uart-has-rtscts;

/* for DTE mode, add below change */

/* fsl,dte-mode; */

/* pinctrl-0 = <&pinctrl_uart2dte>; */

// status = "okay";

  status = "disabled";

};

&usdhc1 {

pinctrl-names = "default", "state_100mhz", "state_200mhz";

pinctrl-0 = <&pinctrl_usdhc1>;

pinctrl-1 = <&pinctrl_usdhc1_100mhz>;

pinctrl-2 = <&pinctrl_usdhc1_200mhz>;

cd-gpios = <&gpio1 19 0>;

keep-power-in-suspend;

enable-sdio-wakeup;

vmmc-supply = <&reg_sd1_vmmc>;

// status = "okay";

  status = "disabled";

};

&fec2 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_enet2>;
phy-mode = "rmii";
phy-handle = <&ethphy1>;
// status = "okay";
  status = "disabled";

mdio {
  #address-cells = <1>;
  #size-cells = <0>;

  ethphy0: ethernet-phy@2 {
   compatible = "ethernet-phy-ieee802.3-c22";
   reg = <2>;
  };

  ethphy1: ethernet-phy@1 {
   compatible = "ethernet-phy-ieee802.3-c22";
   reg = <1>;
  };
};
};

The SD1.CD pin does not appear in the debug, cat /sys/kernel/debug/gpio

But, now I only read 0-voltages on All pins (no High pins except for pin38 from the UART2 fluctuates).

Do I need to Enable these as GPIO pins for Sysfs use ?

If so, how ?

0 Kudos
Reply

6,790 Views
christophertele
Contributor III

mux the pins as gpios in devicetree. just add the muxing line where the other gpios of your board are muxed. on my board its like:

pinctrl_hog: hoggrp {

     fsl,pins = <

          MX6QDL_PAD_XXX__GPIOX_IOX     0x130b0

     >;

};

0 Kudos
Reply

6,790 Views
johncoleman
Contributor IV

I still can Not assign HI Outputs on the Development Pins on the IMX6 UltraLite Eval Board.

(Same for the Inputs, the Inputs are not recognized, just All LO.)

I modified/added to the Device Tree for my Imx6ul-14x14 Board:

~/yocto_3.14.38-6UL/tmp/work-shared/imx6ulevk/kernel-source/arch/arm/boot/dts #

  xemacs imx6ul-14x14-evk.dts &

// . . .

&iomuxc {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_hog_1>;

imx6ul-evk {
  pinctrl_hog_1: hoggrp-1 {
   fsl,pins = <
    MX6UL_PAD_LCD_RESET__WDOG1_WDOG_ANY    0x30b0
    MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x17059 /* SD1 CD */
    MX6UL_PAD_GPIO1_IO05__USDHC1_VSELECT 0x17059 /* SD1 VSELECT */
    MX6UL_PAD_GPIO1_IO09__GPIO1_IO09        0x17059 /* SD1 RESET */

     // MY PINS: //

     // MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x17059 // SD1 CD //
     // cd-gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;

      // UART2:
    // MX6UL_PAD_UART2_TX_DATA__UART2_DCE_TX 0x1b0b1
     MX6UL_PAD_UART2_TX_DATA__GPIO1_IO20 0x1b0b1
     // MX6UL_PAD_UART2_RX_DATA__UART2_DCE_RX 0x1b0b1
      MX6UL_PAD_UART2_RX_DATA__GPIO1_IO21 0x1b0b1
    // MX6UL_PAD_UART2_RTS_B__FLEXCAN2_RX 0x1b020
     MX6UL_PAD_UART2_RTS_B__GPIO1_IO23 0x1b020
    // MX6UL_PAD_UART2_CTS_B__FLEXCAN2_TX 0x1b020
     MX6UL_PAD_UART2_CTS_B__GPIO1_IO22 0x1b020

      // uSDhc1:
    // MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x17059
     MX6UL_PAD_SD1_CMD__GPIO2_IO16      0x17059
    // MX6UL_PAD_SD1_CLK__USDHC1_CLK      0x10059
     MX6UL_PAD_SD1_CLK__GPIO2_IO17      0x10059
    // MX6UL_PAD_SD1_DATA0__USDHC1_DATA0  0x17059
     MX6UL_PAD_SD1_DATA0__GPIO2_IO18  0x17059
    // MX6UL_PAD_SD1_DATA1__USDHC1_DATA1  0x17059
     MX6UL_PAD_SD1_DATA1__GPIO2_IO19  0x17059
    // MX6UL_PAD_SD1_DATA2__USDHC1_DATA2  0x17059
     MX6UL_PAD_SD1_DATA2__GPIO2_IO20  0x17059
    // MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x17059
     MX6UL_PAD_SD1_DATA3__GPIO2_IO21 0x17059
    // MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x17059 // SD1 CD //
     MX6UL_PAD_UART1_RTS_B__GPIO1_IO19 0x17059 // SD1 CD //

     // ENET2:
     //// MX6UL_PAD_ENET2_RX_EN__ENET2_RX_EN 0x1b0b0
    // MX6UL_PAD_ENET2_RX_ER__ENET2_RX_ER  0x1b0b0
     MX6UL_PAD_ENET2_RX_ER__GPIO2_IO15  0x1b0b0
     //// MX6UL_PAD_ENET2_RX_DATA0__ENET2_RDATA00 0x1b0b0
     //// MX6UL_PAD_ENET2_RX_DATA1__ENET2_RDATA01 0x1b0b0
    // MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN  0x1b0b0
     MX6UL_PAD_ENET2_TX_EN__GPIO2_IO13  0x1b0b0
     //// MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00 0x1b0b0
    // MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01 0x1b0b0
     MX6UL_PAD_ENET2_TX_DATA1__GPIO2_IO12  0x1b0b0
    // MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2  0x4001b031
     MX6UL_PAD_ENET2_TX_CLK__GPIO2_IO14  0x4001b031

     //

   >;
  };

// . . .

-

Next compiled :

  bitbake linux-imx -c compile -f

  bitbake core-image-minimal

Then Flashed and Booted.

And executed commands after login :

~/yocto_3.14.38-6UL/tmp/work/imx6ulevk-poky-linux-gnueabi/linux-imx/3.14.38-r0/image/boot #

cat /sys/kernel/debug/gpio

GPIOs 0-31, platform/209c000.gpio, 209c000.gpio:

gpio-3   (tsc_X-              ) in  hi

gpio-9   (VSD_3V3             ) out lo

GPIOs 32-63, platform/20a0000.gpio, 20a0000.gpio:

GPIOs 64-95, platform/20a4000.gpio, 20a4000.gpio:

GPIOs 96-127, platform/20a8000.gpio, 20a8000.gpio:

gpio-119 (?                   ) out lo

GPIOs 128-159, platform/20ac000.gpio, 20ac000.gpio:

gpio-131 (?                   ) out lo

gpio-132 (headset detect      ) in  lo

gpio-135 (spi32766.0          ) out lo

gpio-136 (?                   ) out lo

gpio-138 (spi4.14             ) out lo

gpio-139 (spi4.14             ) out lo

GPIOs 248-255, spi/spi32766.0, 74hc595, can sleep:

echo 37 > /sys/class/gpio/export
echo "out" > /sys/class/gpio/gpio37/direction
echo 1 > /sys/class/gpio/gpio37/value
echo 38 > /sys/class/gpio/export
echo "out" > /sys/class/gpio/gpio38/direction
echo 1 > /sys/class/gpio/gpio38/value
echo 39 > /sys/class/gpio/export
echo "out" > /sys/class/gpio/gpio39/direction
echo 1 > /sys/class/gpio/gpio39/value
echo 40 > /sys/class/gpio/export
echo "out" > /sys/class/gpio/gpio40/direction
echo 1 > /sys/class/gpio/gpio40/value

echo 61 > /sys/class/gpio/export
echo "out" > /sys/class/gpio/gpio61/direction
echo 1 > /sys/class/gpio/gpio61/value
echo 62 > /sys/class/gpio/export
echo "out" > /sys/class/gpio/gpio62/direction
echo 1 > /sys/class/gpio/gpio62/value
echo 63 > /sys/class/gpio/export
echo "out" > /sys/class/gpio/gpio63/direction
echo 1 > /sys/class/gpio/gpio63/value
echo 64 > /sys/class/gpio/export
echo "out" > /sys/class/gpio/gpio64/direction
echo 1 > /sys/class/gpio/gpio64/value

cat /sys/kernel/debug/gpio                                         
GPIOs 0-31, platform/209c000.gpio, 209c000.gpio:
gpio-3   (tsc_X-              ) in  hi
gpio-9   (VSD_3V3             ) out lo
GPIOs 32-63, platform/20a0000.gpio, 20a0000.gpio:
gpio-37  (sysfs               ) out lo
gpio-38  (sysfs               ) out hi
gpio-39  (sysfs               ) out lo
gpio-40  (sysfs               ) out lo
gpio-61  (sysfs               ) out lo
gpio-62  (sysfs               ) out lo
gpio-63  (sysfs               ) out lo
GPIOs 64-95, platform/20a4000.gpio, 20a4000.gpio:
gpio-64  (sysfs               ) out lo
GPIOs 96-127, platform/20a8000.gpio, 20a8000.gpio:
gpio-111 (sysfs               ) out lo
gpio-112 (sysfs               ) out lo
gpio-113 (sysfs               ) out lo
gpio-114 (sysfs               ) out lo
gpio-115 (sysfs               ) out lo
gpio-116 (sysfs               ) out lo
gpio-119 (?                   ) out lo
GPIOs 128-159, platform/20ac000.gpio, 20ac000.gpio:
gpio-131 (?                   ) out lo
gpio-132 (headset detect      ) in  lo
gpio-135 (spi32766.0          ) out lo
gpio-136 (?                   ) out lo
gpio-138 (spi4.14             ) out lo
gpio-139 (spi4.14             ) out lo
GPIOs 248-255, spi/spi32766.0, 74hc595, can sleep:

Notice that the Cat Sys Debug still shows LOWs for ALL the Outputs ?

(while Gpio1.38 flickers between HI and LO)

-

What am I missing ?

0 Kudos
Reply

6,790 Views
johncoleman
Contributor IV

We are working with the iMx6sx/sl processors, testing on the imx6-UltraLite and imx6-Sabre-Solo Boards.

I have been compiling the Images under Yocto on.

But, I can not find the relevant DTS files:

~/yocto_3.14.38-6UL/build/tmp/work/cortexa7hf-vfp-neon-poky-linux-gnueabi/linux-libc-headers/3.14-r0/linux-3.14/arch/arm/boot/dts $

imx6sl-evk.dts

imx6sl-pinfunc.h

imx6sl-warp.dts

imx6sl.dtsi

imx6sx-pinfunc.h

imx6sx-sabreauto.dts

imx6sx-sdb-reva.dts

imx6sx-sdb.dts

imx6sx-sdb.dtsi

imx6sx.dtsi

Why are these files missing (but I can still compile the Images for the Board),

and how do I add them to the Yocto source ?

... I need to add GPIO access in the DTS via the DTS files.

0 Kudos
Reply

6,790 Views
BiyongSUN
NXP Employee
NXP Employee

The follow is the test on reference board. But it is pure linux topic, mentioned in 3.14.28  Documentation/gpio/gpio-legacy.txt, posted before.

This is just show you guys what is the correct method accessing gpio in linux, despite which kind of chip.

Suggest you guys again, read the linux document carefully.

christopher's solution is also a workaround.

The test use the sysfs, which mentioned in the linux documents. Then use memtool to verify the result.

memtool is using the same way as the christopher's code. christopher's code is just very small part of memtool. the christopher's code is to access the register directly as memtool does.

But again here, from the linux programming layer, it is a workround.

One important thing, you need to check the IOMUX you configured is correct for GPIO.

root@imx6qdlsolo:~# echo 115 > /sys/class/gpio/export
root@imx6qdlsolo:~# /unit_tests/memtool 0x20a8004 1
E
Reading 0x1 count starting at address 0x020A8004

0x020A8004:  0E050000

root@imx6qdlsolo:~# echo out > /sys/class/gpio/gpio115/direction
root@imx6qdlsolo:~# /unit_tests/memtool 0x20a8004 1
E
Reading 0x1 count starting at address 0x020A8004

0x020A8004:  0E0D0000

If you guys still don't believe, please google as following:

Untitled.png

0 Kudos
Reply

6,790 Views
BiyongSUN
NXP Employee
NXP Employee

From your code, we can know you have no any experience of the linux programming.

And the code you listed is for the linux kernel. Not user space.

From the user space, the GPIO should access from sys, which also have API in userspace.

Details please check the linux document file.

3.14.28

Documentation/gpio/gpio-legacy.txt

suggest you can start at the beginning of the linux program and build up a concept of linux.

Sysfs Interface for Userspace (OPTIONAL) ======================================== Platforms which use the "gpiolib" implementors framework may choose to configure a sysfs user interface to GPIOs.  This is different from the debugfs interface, since it provides control over GPIO direction and value instead of just showing a gpio state summary.  Plus, it could be present on production systems without debugging support.

Given appropriate hardware documentation for the system, userspace could know for example that GPIO #23 controls the write protect line used to protect boot loader segments in flash memory.  System upgrade procedures may need to temporarily remove that protection, first importing a GPIO, then changing its output state, then updating the code before re-enabling the write protection.  In normal use, GPIO #23 would never be touched, and the kernel would have no need to know about it.

Again depending on appropriate hardware documentation, on some systems userspace GPIO can be used to determine system configuration data that standard kernels won't know about.  And for some tasks, simple userspace GPIO drivers could be all that the system really needs.

Note that standard kernel drivers exist for common "LEDs and Buttons" GPIO tasks:  "leds-gpio" and "gpio_keys", respectively.  Use those instead of talking directly to the GPIOs; they integrate with kernel frameworks better than your userspace code could.

Paths in Sysfs

-------------- There are three kinds of entry in /sys/class/gpio:

   - Control interfaces used to get userspace control over GPIOs;

   - GPIOs themselves; and

   - GPIO controllers ("gpio_chip" instances).

That's in addition to standard files including the "device" symlink.

The control interfaces are write-only:

    /sys/class/gpio/

     "export" ... Userspace may ask the kernel to export control of a GPIO to userspace by writing its number to this file.

  Example:  "echo 19 > export" will create a "gpio19" node

  for GPIO #19, if that's not requested by kernel code.

     "unexport" ... Reverses the effect of exporting to userspace.

  Example:  "echo 19 > unexport" will remove a "gpio19"

  node exported using the "export" file.

GPIO signals have paths like /sys/class/gpio/gpio42/ (for GPIO #42) and have the following read/write attributes:

    /sys/class/gpio/gpioN/

"direction" ... reads as either "in" or "out".  This value may normally be written.  Writing as "out" defaults to

  initializing the value as low.  To ensure glitch free

  operation, values "low" and "high" may be written to

  configure the GPIO as an output with that initial value.

  Note that this attribute *will not exist* if the kernel

  doesn't support changing the direction of a GPIO, or

  it was exported by kernel code that didn't explicitly

  allow userspace to reconfigure this GPIO's direction.

"value" ... reads as either 0 (low) or 1 (high).  If the GPIO is configured as an output, this value may be written;

  any nonzero value is treated as high.

  If the pin can be configured as interrupt-generating interrupt

  and if it has been configured to generate interrupts (see the description of "edge"), you can poll(2) on that file and

  poll(2) will return whenever the interrupt was triggered. If

  you use poll(2), set the events POLLPRI and POLLERR. If you

  use select(2), set the file descriptor in exceptfds. After

  poll(2) returns, either lseek(2) to the beginning of the sysfs

  file and read the new value or close the file and re-open it

  to read the value.

"edge" ... reads as either "none", "rising", "falling", or "both". Write these strings to select the signal edge(s)

  that will make poll(2) on the "value" file return.

  This file exists only if the pin can be configured as an

  interrupt generating input pin.

"active_low" ... reads as either 0 (false) or 1 (true).  Write any nonzero value to invert the value attribute both

  for reading and writing.  Existing and subsequent

  poll(2) support configuration via the edge attribute

  for "rising" and "falling" edges will follow this

  setting.

GPIO controllers have paths like /sys/class/gpio/gpiochip42/ (for the controller implementing GPIOs starting at #42) and have the following read-only attributes:

    /sys/class/gpio/gpiochipN/

     "base" ... same as N, the first GPIO managed by this chip

     "label" ... provided for diagnostics (not always unique)

     "ngpio" ... how many GPIOs this manges (N to N + ngpio - 1)

Board documentation should in most cases cover what GPIOs are used for what purposes.  However, those numbers are not always stable; GPIOs on a daughtercard might be different depending on the base board being used, or other cards in the stack.  In such cases, you may need to use the gpiochip nodes (possibly in conjunction with schematics) to determine the correct GPIO number to use for a given signal.

Exporting from Kernel code

-------------------------- Kernel code can explicitly manage exports of GPIOs which have already been requested using gpio_request():

/* export the GPIO to userspace */

int gpio_export(unsigned gpio, bool direction_may_change);

/* reverse gpio_export() */

void gpio_unexport();

/* create a sysfs link to an exported GPIO node */

int gpio_export_link(struct device *dev, const char *name, unsigned gpio)

/* change the polarity of a GPIO node in sysfs */

int gpio_sysfs_set_active_low(unsigned gpio, int value);

After a kernel driver requests a GPIO, it may only be made available in the sysfs interface by gpio_export().  The driver can control whether the signal direction may change.  This helps drivers prevent userspace code from accidentally clobbering important system state.

This explicit exporting can help with debugging (by making some kinds of experiments easier), or can provide an always-there interface that's suitable for documenting as part of a board support package.

After the GPIO has been exported, gpio_export_link() allows creating symlinks from elsewhere in sysfs to the GPIO sysfs node.  Drivers can use this to provide the interface under their own device in sysfs with a descriptive name.

Drivers can use gpio_sysfs_set_active_low() to hide GPIO line polarity differences between boards from user space.  This only affects the sysfs interface.  Polarity change can be done both before and after gpio_export(), and previously enabled poll(2) support for either rising or falling edge will be reconfigured to follow this setting.

6,789 Views
johncoleman
Contributor IV

I am quite familiar with the explanations that you list - but still provides No output on the UL-Evk Board pins (with a Vmeter or scope).

- As you can see I already tried as you specified (clipped short to not Load the Blogs of course).

Actually, I am taking these from examples of howto code for Gpios here.

I can only Assume to Follow these examples - that I can find on freescale for their boards..

I am used to working on large Linux embedded client/server systems without worrying about gpios.

I would hope to see examples on freescale on howto work with its board gpios and io - to make any used of it.