gobot.io/x/gobot/v2@v2.1.0/system/GPIO.md (about)

     1  # GPIOs
     2  
     3  This document describes some basics for developers. This is useful to understand programming in gobot's [digital pin driver](digital_pin.go).
     4  
     5  ## GPIOs with sysfs
     6  
     7  > Kernel SYSFS ABI is deprecated since Linux 4.8, see <https://www.kernel.org/doc/html/latest/admin-guide/gpio/sysfs.html>.
     8  > For GPIO's we still use the Kernel SYSFS ABI.
     9  
    10  ## GPIOs with character devices
    11  
    12  This document provides some test possibilities by using the new character device feature since Kernel 4.8. Please check
    13  your Kernel version before using this. Install of "gpiod" is mandatory for the tests.
    14  
    15  ```sh
    16  uname -a
    17  Linux raspi 5.15.61+ #1579 Fri Aug 26 11:08:59 BST 2022 armv6l GNU/Linux
    18  
    19  sudo apt install gpiod
    20  ```
    21  
    22  > For work on character device user space drivers, please refer to our [issue #775](https://github.com/hybridgroup/gobot/issues/775).
    23  
    24  ## Check available GPIO banks
    25  
    26  Example for Tinkerboard (RK3288) with TinkerOS:
    27  
    28  ```sh
    29  ls -la /sys/class/gpio/
    30  total 0
    31  drwxr-xr-x  2 root root    0 Nov 12 06:53 .
    32  drwxr-xr-x 66 root root    0 Feb 14  2019 ..
    33  --w-------  1 root root 4096 Feb 14  2019 export
    34  lrwxrwxrwx  1 root root    0 Feb 14  2019 gpiochip0 -> ../../devices/platform/pinctrl/gpio/gpiochip0
    35  lrwxrwxrwx  1 root root    0 Feb 14  2019 gpiochip120 -> ../../devices/platform/pinctrl/gpio/gpiochip120
    36  lrwxrwxrwx  1 root root    0 Feb 14  2019 gpiochip152 -> ../../devices/platform/pinctrl/gpio/gpiochip152
    37  lrwxrwxrwx  1 root root    0 Feb 14  2019 gpiochip184 -> ../../devices/platform/pinctrl/gpio/gpiochip184
    38  lrwxrwxrwx  1 root root    0 Feb 14  2019 gpiochip216 -> ../../devices/platform/pinctrl/gpio/gpiochip216
    39  lrwxrwxrwx  1 root root    0 Feb 14  2019 gpiochip24 -> ../../devices/platform/pinctrl/gpio/gpiochip24
    40  lrwxrwxrwx  1 root root    0 Feb 14  2019 gpiochip248 -> ../../devices/platform/pinctrl/gpio/gpiochip248
    41  lrwxrwxrwx  1 root root    0 Feb 14  2019 gpiochip56 -> ../../devices/platform/pinctrl/gpio/gpiochip56
    42  lrwxrwxrwx  1 root root    0 Feb 14  2019 gpiochip88 -> ../../devices/platform/pinctrl/gpio/gpiochip88
    43  ```
    44  
    45  Example for "Raspberry Pi Model B Rev 2" with "Raspbian GNU/Linux 11 (bullseye)" (26 pin header):
    46  
    47  ```sh
    48  ls -la /sys/class/gpio/
    49  total 0
    50  drwxrwxr-x  2 root gpio    0 Nov 13 09:33 .
    51  drwxr-xr-x 58 root root    0 Sep 13 02:58 ..
    52  --w--w----  1 root gpio 4096 Nov 13 09:33 export
    53  lrwxrwxrwx  1 root gpio    0 Nov 13 09:33 gpiochip0 -> ../../devices/platform/soc/20200000.gpio/gpio/gpiochip0
    54  --w--w----  1 root gpio 4096 Nov 13 09:33 unexport
    55  
    56  gpiodetect
    57  gpiochip0 [pinctrl-bcm2835] (54 lines)
    58  
    59  gpioinfo 
    60  gpiochip0 - 54 lines:
    61    gpiochip0 - 54 lines:
    62    ...
    63    line   2:       "SDA1"       unused   input  active-high 
    64    line   3:       "SCL1"       unused   input  active-high 
    65    line   4:  "GPIO_GCLK"       unused   input  active-high 
    66    ...
    67    line   7:  "SPI_CE1_N"       unused   input  active-high 
    68    line   8:  "SPI_CE0_N"       unused   input  active-high 
    69    line   9:   "SPI_MISO"       unused   input  active-high 
    70    line  10:   "SPI_MOSI"       unused   input  active-high 
    71    line  11:   "SPI_SCLK"       unused   input  active-high 
    72    ...
    73    line  14:       "TXD0"       unused   input  active-high 
    74    line  15:       "RXD0"       unused   input  active-high 
    75    ...
    76    line  17:     "GPIO17"       unused   input  active-high 
    77    line  18:     "GPIO18"       unused   input  active-high 
    78    ...
    79    line  22:     "GPIO22"       unused   input  active-high 
    80    line  23:     "GPIO23"       unused   input  active-high 
    81    line  24:     "GPIO24"       unused   input  active-high 
    82    line  25:     "GPIO25"       unused   input  active-high 
    83    ...
    84  ```
    85  
    86  ## General GPIO tests
    87  
    88  For Tinkerboard and in general for all other boards:
    89  
    90  * the name on system level differ from the header name (normally pin1..pin40)
    91  * the mapping is done in gobot by a file named something like [pin_map.go](../platforms/tinkerboard/pin_map.go)
    92  * for the next tests the system level name is needed
    93  
    94  Connect an oscilloscope or at least a meter to the pin (used header pin26 for example). For the output tests a LED with
    95  a sufficient resistor to 3.3.V (e.g. 290 Ohm) can be used to detect the output state.  
    96  
    97  > On Tinkerboard the pin26 relates to gpio251. For raspi it relates to gpio7.
    98  
    99  ### Creating gpio251 (sysfs Tinkerboard)
   100  
   101  > Needs to be "root" for this to work. Switch to root user by "su -".
   102  
   103  ```sh
   104  echo "251" > /sys/class/gpio/export
   105  ```
   106  
   107  investigate result:
   108  
   109  ```sh
   110  # cat /sys/class/gpio/gpio251/active_low 
   111  0
   112  
   113  # cat /sys/class/gpio/gpio251/direction 
   114  in
   115  
   116  # cat /sys/class/gpio/gpio251/edge 
   117  none
   118  
   119  # cat /sys/class/gpio/gpio251/value 
   120  1
   121  ```
   122  
   123  > The value can float to "1", if the input is open.
   124  
   125  ### Test input behavior of gpio251 (sysfs Tinkerboard)
   126  
   127  > Be careful with connecting the input to GND or 3.3V directly, instead use an resistor with minimum 300 Ohm.
   128  
   129  Connect the input header pin26 to GND.
   130  
   131  ```sh
   132  # cat /sys/class/gpio/gpio251/direction 
   133  in
   134  # cat /sys/class/gpio/gpio251/value 
   135  0
   136  ```
   137  
   138  Connect the input header pin26 to +3.3V with an resistor (e.g. 1kOhm).
   139  
   140  ```sh
   141  # cat /sys/class/gpio/gpio251/value 
   142  1
   143  ```
   144  
   145  ### Test output behavior of gpio251 (sysfs Tinkerboard)
   146  
   147  Connect the output header pin26 to +3.3V with an resistor (e.g. 1kOhm leads to ~0.3mA, 300Ohm leads to ~10mA).
   148  
   149  ```sh
   150  # echo "out" > /sys/class/gpio/gpio251/direction
   151  # cat /sys/class/gpio/gpio251/direction
   152  out
   153  # cat /sys/class/gpio/gpio251/value
   154  0
   155  
   156  # echo "1" > /sys/class/gpio/gpio251/value
   157  # cat /sys/class/gpio/gpio251/value
   158  1
   159  
   160  # echo "0" > /sys/class/gpio/gpio251/value
   161  # cat /sys/class/gpio/gpio251/value
   162  0
   163  ```
   164  
   165  The meter should show "0V" for values of "0" and "3.3V", when the value was set to "1".
   166  
   167  > For armbian and Tinkerboard the value remains to "1", although it was set to "0". In this case the pin is not usable
   168  > as output.
   169  
   170  ### Test inverse output behavior of gpio251 (sysfs Tinkerboard)
   171  
   172  ```sh
   173  # cat /sys/class/gpio/gpio251/value
   174  0
   175  # cat /sys/class/gpio/gpio251/active_low
   176  0
   177  
   178  # echo "1" > /sys/class/gpio/gpio251/active_low
   179  # cat /sys/class/gpio/gpio251/value
   180  1
   181  
   182  # echo "0" > /sys/class/gpio/gpio251/value
   183  # cat /sys/class/gpio/gpio251/value
   184  0
   185  ```
   186  
   187  The meter should show "0V" for values of "1" and "3.3V", when the value was set to "0".
   188  
   189  ### Test input behavior of gpio7 (cdev Raspi)
   190  
   191  > Use --help to get some information of the command usage and options, e.g. "gpioget --help". Be careful with connecting
   192  > the input to GND or 3.3V directly, instead use an resistor with minimum 300Ohm. Prefer to use the pull-up or pull-down
   193  > feature, if working.
   194  
   195  ```sh
   196  sudo gpioget 0 7
   197  1
   198  gpioinfo | grep 'line   7'
   199    line   7:  "SPI_CE1_N"       unused   input  active-high
   200  
   201  sudo gpioget --bias=pull-down 0 7
   202  0
   203  ```
   204  
   205  >The value can float to "1", if the input is open. Most likely the raspi device has an internal pull-up resistor.
   206  >Setting the bias is not possible for sysfs usage. This is one of the advantages of the new character device Kernel feature.
   207  
   208  ### Test output behavior of gpio7 (cdev Raspi)
   209  
   210  ```sh
   211  sudo gpioset 0 7=0
   212  gpioinfo | grep 'line   7'
   213    line   7:  "SPI_CE1_N"       unused  output  active-high
   214  
   215  sudo gpioset 0 7=1
   216  gpioinfo | grep 'line   7'
   217    line   7:  "SPI_CE1_N"       unused  output  active-high
   218  ```
   219  
   220  The meter should show "0V" for values of "0" and "3.3V", when the value was set to "1".  
   221  A connected LED with pull-up resistor lights up for setting to "0" (inverse).
   222  
   223  ### Test inverse output behavior of gpio7 (cdev Raspi)
   224  
   225  ```sh
   226  sudo gpioset -l 0 7=0
   227  sudo gpioset -l 0 7=1
   228  ```
   229  
   230  The meter should show "0V" for values of "1" and "3.3V", when the value was set to "0" (inverse logic).  
   231  A connected LED with pull-up resistor lights up for setting to "1" (inverse reversed).
   232  
   233  > The gpioinfo seems to do not recognize the "active-low" set.
   234  
   235  ## Links
   236  
   237  * <https://www.kernel.org/doc/html/latest/admin-guide/gpio/sysfs.html>
   238  * <https://embeddedbits.org/linux-kernel-gpio-user-space-interface>