BeagleBone Black, FreeBSD and GPIOs

The LEDs of a BeagleBone Black running FreeBSD are lighten up. The FreeBSD logo

Introduction

The BeagleBone black, using its AM335X CPU, provides a number of GPIOs. Let's try to make them work.

Trying to find the device

dmesg indicates that the kernel found a GPIO device.

gpio0: <TI General Purpose I/O (GPIO)> mem 0x44e07000-0x44e07fff,0x4804c000-0x4804cfff,0x481ac000-0x481acfff,0x481ae000-0x481aefff irq 96,97,98,99,32,33,62,63 on simplebus0
gpioc0: <GPIO controller> on gpio0
gpiobus0: <GPIO bus> on gpio0

devinfo and ofwdump confirm that the corresponding nodes exist.

# devinfo
nexus0
  fdtbus0
    simplebus0
      aintc0
      ti_scm0
      am335x_prcm0
      am335x_dmtimer0
      gpio0
        gpioc0
        gpiobus0
      uart0
      ti_edma30
      sdhci_ti0
        mmc0
          mmcsd0
      sdhci_ti1
        mmc1
          mmcsd1
      cpsw0
        miibus0
          smscphy0
      iichb0
        iicbus0
          iic0
          am335x_pmic0
      am335x_pwm0
      am335x_pwm1
      am335x_pwm2
      musbotg0
        usbus0
          uhub0
            ustorage_fs0
        usbus1
          uhub1


# ofwdump -a
Node 0x38:
  Node 0xc4: am335x
    Node 0x124: interrupt-controller@48200000
    Node 0x1b4: scm@44e10000
    Node 0xb24: prcm@44E00000
    Node 0xb88: dmtimers@44E05000
    Node 0xc6c: gpio
    Node 0xd14: serial@44E09000
    Node 0xda8: serial@48022000
    Node 0xe54: serial@48024000
    Node 0xf00: serial@481a6000
    Node 0xfac: serial@481a8000
    Node 0x1058: serial@481aa000
    Node 0x1104: edma3@49000000
    Node 0x1188: mmchs0@48060000
    Node 0x120c: mmchs1@481D8000
    Node 0x12a4: ethernet@4A100000
      Node 0x1340: mdio@0
        Node 0x1388: ethernet-phy@0
    Node 0x13c8: i2c@44e0b000
      Node 0x1454: pmic@24
    Node 0x1494: pwm@48300000
    Node 0x1548: pwm@48302000
    Node 0x15fc: pwm@48304000
    Node 0x16b0: lcd@4830e000
    Node 0x1738: usb@47400000
    Node 0x1808: mbox0@480C8000
    Node 0x1874: spinlock0@480CA000
    Node 0x18c0: pruss@4A300000
  Node 0x1944: aliases
  Node 0x198c: memory
  Node 0x19c4: chosen

# ofwdump -p /am335x/gpio
Node 0xc6c: gpio
  #gpio-cells:
    00 00 00 03
  compatible:
    74 69 2c 67 70 69 6f 00
    'ti,gpio'
  gpio-controller:
  reg:
    44 e0 70 00 00 00 10 00 48 04 c0 00 00 00 10 00 48 1a c0 00
    00 00 10 00 48 1a e0 00 00 00 10 00
  interrupts:
    00 00 00 60 00 00 00 61 00 00 00 62 00 00 00 63 00 00 00 20
    00 00 00 21 00 00 00 3e 00 00 00 3f
  interrupt-parent:
    00 00 00 01

Using the device

Reading the kernel source code indicates that the GPIOs are used with a tool called gpioctl.

Listing the available IOs shows that some of them are already configured.

# gpioctl -f /dev/gpioc0 -l
pin 00: 0       gpio_0<>
pin 01: 0       gpio_1<>
pin 02: 0       gpio_2<>
pin 03: 0       gpio_3<>
pin 04: 0       gpio_4<>
pin 05: 0       gpio_5<>
pin 06: 0       gpio_6<>
pin 07: 0       gpio_7<IN,PD>
pin 08: 0       gpio_8<IN>
pin 09: 0       gpio_9<IN>
pin 10: 0       gpio_10<IN>
pin 11: 0       gpio_11<IN>
pin 12: 0       gpio_12<IN,PU>
pin 13: 0       gpio_13<IN,PU>
pin 14: 0       gpio_14<IN,PU>
pin 15: 0       gpio_15<IN,PU>
pin 16: 0       gpio_16<>
pin 17: 0       gpio_17<>
pin 18: 0       gpio_18<>
pin 19: 0       gpio_19<>
pin 20: 0       gpio_20<IN,PD>
pin 21: 0       gpio_21<>
pin 22: 0       gpio_22<>
pin 23: 0       gpio_23<>
pin 24: 0       gpio_24<>
pin 25: 0       gpio_25<>
pin 26: 0       gpio_26<IN,PD>
pin 27: 0       gpio_27<IN,PD>
pin 28: 0       gpio_28<>
pin 29: 0       gpio_29<IN,PD>
pin 30: 0       gpio_30<IN,PU>
pin 31: 0       gpio_31<IN,PU>
pin 32: 0       gpio_32<>
pin 33: 0       gpio_33<>
pin 34: 0       gpio_34<>
pin 35: 0       gpio_35<>
pin 36: 0       gpio_36<>
pin 37: 0       gpio_37<>
pin 38: 0       gpio_38<>
pin 39: 0       gpio_39<>
pin 40: 0       gpio_40<IN,PU>
pin 41: 0       gpio_41<IN,PU>
pin 42: 0       gpio_42<>
pin 43: 0       gpio_43<>
pin 44: 0       gpio_44<IN,PD>
pin 45: 0       gpio_45<IN,PD>
pin 46: 0       gpio_46<IN,PD>
pin 47: 0       gpio_47<IN,PD>
pin 48: 0       gpio_48<IN,PD>
pin 49: 0       gpio_49<IN,PD>
pin 50: 0       gpio_50<>
pin 51: 0       gpio_51<>
pin 52: 0       gpio_52<IN,PD>
pin 53: 0       gpio_53<OUT>
pin 54: 0       gpio_54<OUT>
pin 55: 0       gpio_55<OUT>
pin 56: 0       gpio_56<OUT>
pin 57: 0       gpio_57<IN,PD>
pin 58: 0       gpio_58<IN,PD>
pin 59: 0       gpio_59<IN,PD>
pin 60: 0       gpio_60<IN,PD>
pin 61: 0       gpio_61<IN,PD>
pin 62: 0       gpio_62<>
pin 63: 0       gpio_63<>
pin 64: 0       gpio_64<OUT,PU>
pin 65: 0       gpio_65<IN,PD>
pin 66: 0       gpio_66<>
pin 67: 0       gpio_67<>
pin 68: 0       gpio_68<>
pin 69: 0       gpio_69<IN,PD>
pin 70: 0       gpio_70<IN,PD>
pin 71: 0       gpio_71<IN,PD>
pin 72: 0       gpio_72<IN,PD>
pin 73: 0       gpio_73<IN,PD>
pin 74: 0       gpio_74<IN,PD>
pin 75: 0       gpio_75<IN,PD>
pin 76: 0       gpio_76<IN>
pin 77: 0       gpio_77<IN>
pin 78: 0       gpio_78<IN>
pin 79: 0       gpio_79<>
pin 80: 0       gpio_80<>
pin 81: 0       gpio_81<>
pin 82: 0       gpio_82<>
pin 83: 0       gpio_83<>
pin 84: 0       gpio_84<>
pin 85: 0       gpio_85<>
pin 86: 0       gpio_86<IN,PD>
pin 87: 0       gpio_87<IN,PD>
pin 88: 0       gpio_88<IN,PD>
pin 89: 0       gpio_89<IN,PD>
pin 90: 0       gpio_90<>
pin 91: 0       gpio_91<>
pin 92: 0       gpio_92<>
pin 93: 0       gpio_93<>
pin 94: 0       gpio_94<>
pin 95: 0       gpio_95<>
pin 96: 0       gpio_96<IN,PD>
pin 97: 0       gpio_97<IN,PD>
pin 98: 0       gpio_98<>
pin 99: 0       gpio_99<>
pin 100:        0       gpio_100<>
pin 101:        0       gpio_101<>
pin 102:        0       gpio_102<>
pin 103:        0       gpio_103<>
pin 104:        0       gpio_104<IN,PU>
pin 105:        0       gpio_105<>
pin 106:        0       gpio_106<>
pin 107:        0       gpio_107<>
pin 108:        0       gpio_108<>
pin 109:        0       gpio_109<>
pin 110:        0       gpio_110<IN,PD>
pin 111:        0       gpio_111<IN,PD>
pin 112:        0       gpio_112<IN,PD>
pin 113:        0       gpio_113<IN,PD>
pin 114:        0       gpio_114<>
pin 115:        0       gpio_115<IN,PD>
pin 116:        0       gpio_116<IN,PD>
pin 117:        0       gpio_117<IN,PD>
pin 118:        0       gpio_118<>
pin 119:        0       gpio_119<>
pin 120:        0       gpio_120<>
pin 121:        0       gpio_121<>
pin 122:        0       gpio_122<>
pin 123:        0       gpio_123<>
pin 124:        0       gpio_124<>
pin 125:        0       gpio_125<>
pin 126:        0       gpio_126<>
pin 127:        0       gpio_127<>

Let's try to play with the board's 4 builtin LEDs.

# gpioctl -f /dev/gpioc0 -t 53
# gpioctl -f /dev/gpioc0 -t 54
# gpioctl -f /dev/gpioc0 -t 55
# gpioctl -f /dev/gpioc0 -t 56

Yep, they work.

Let's try configure another random IO.

# gpioctl -f /dev/gpioc0 -c 49 OUT OD
0/OUT
1/OD

GPIO1_17 (P9.23) should be configured as an open-drain output pin. Let's try to change its value.

root@beaglebone:~ # while 1
while? gpioctl -f /dev/gpioc0 -t 49
while? sleep 1
while? end
^C

We created a very slow bit-banged PWM.

Reference and relevant information