bbb gpio - victronenergy/venus GitHub Wiki

Related documentation

  • TI gpio driver documentation is here
  • An easy to use website to retrieve the gpio pin numbers is available here
  • io access is implemented in the kernel as sysfs control: /sys/class/gpio
  • Pinmuxing / Sitara internal pullup & pulldown enable/disable is explained here, and full details are in the Sitara Technical Reference Manual.

Pinning:

Implementation in source code is here.

Name Cape Pin TI AM355x PIN Linux GPIO Remark
Relay 1 P8.8 GPIO 2_3 67
Relay 2 P8.9 GPIO 2_5 69
Dig. input 1 (rj12.1) P8.16 GPIO 1_14 46 Offset 0x838
Dig. input 2 (rj12.3) (4) P8.14 (3) GPIO 0_26 26 Offset 0x828
Dig. input 3 (rj12.4) P8.26 (3) GPIO 1_29 61 Offset 0x87C
Dig. input 4 (rj12.5) P8.18 GPIO 2_1 65 Offset 0x88C
Dig. input 5 (rj12.6) P8.12 (3) GPIO 1_12 44 Offset 0x830
MK3_RST P8.39 GPIO 2_12 76
VE.Bus Standby P8.41 (1) GPIO 2_10 74
S2 button (SD boot) P8.43 SYS_BOOT/LCDDATA2 72
Bi-color LED green P9.23 (2) GPIO 1_17 49 inverted
Bi-color LED red P9.27 (2) GPIO 3_19 115 inverted
  1. in pcb rev 0.3 and before, this was on pin P8.43
  2. in pcb rev 0.4, the led was on some other pins, but didn't work. All rev 4 sample capes have been reworked.
  3. in pcb rev 0.4, digital input 2, 3 and 5 were on GPIO1_5, GPIO1_1 and GPIO1_31. But those had conflicts.
  4. in pcb rev 0.6, the pins 2 and 3 of the RJ-12 socket will be swapped to be less conflicting with the BMV RJ-12 pinout: in the new situation, RJ-12 pin 2 will be digital input 2, and RJ-12 pin 3 will be ground.

Full hardware change log is here.

Making the digital inputs work

By default the internal pulldowns are enabled on those inputs. config byte is 0x27 = 100111.

basic dts config to disable the internal pulldowns on the digital inputs is:

+           0x38 (PIN_INPUT | MUX_MODE7)    /* GPIO1_14 = Digital input 1 */
+           0x28 (PIN_INPUT | MUX_MODE7)    /* GPIO0_26 = Digital input 2 */
+           0x7C (PIN_INPUT | MUX_MODE7)    /* GPIO1_29 = Digital input 3 */
+           0x8C (PIN_INPUT | MUX_MODE7)    /* GPIO2_1  = Digital input 4 */
+           0x30 (PIN_INPUT | MUX_MODE7)    /* GPIO1_12 = Digital input 5 */

which is verified to work:

~# devmem2 0x44e10828 b
/dev/mem opened.
Memory mapped at address 0xb6fbf000.
Read at address  0x44E10828 (0xb6fbf828): 0x2F

And 0x2F = 101111. The bit 4 being 1, meaning that pullup/down is disabled.

Rest of the page

Example of toggling relay 1 from the command line:

echo 67 > /sys/class/gpio/export
echo "out" > /sys/class/gpio/gpio67/direction
echo 1 > /sys/class/gpio/gpio67/value
echo 0 > /sys/class/gpio/gpio67/value

And finally unexport the gpio pin to release it back to driver control in case you'd want that:

echo 67 > /sys/class/gpio/unexport

Pulse counting with the digital inputs

The pulse inputs are not connected to actual pulse counters on the bbb / AM3558. They are connected to general GPIO pins, and need to be polled.

Here's the results from a simple C program accessing the gpio under sysfs. Going through a list of 10 gpio pins (P8.27 - P8.36), but it could be a list of any size. The results are reported per each gpio read.

Here it is with no delay between polls. As expected the load is high.

root@bbb:~/poll-gpio# ./poll-gpio

Elapsed   : 160.958 seconds
Poll Count: 1000000
Rate      : 6212.81 polls/sec

root@bbb:~/poll-gpio# uptime
 11:49:57 up 18 min,  2 users,  load average: 0.96, 0.48, 0.21

Here is the same loop with a 48 ms pause after each 10 reads (e.g. each time through the list).

root@bbb:~/poll-gpio# ./poll-gpio 48
^C
Elapsed   : 338.314 seconds
Poll Count: 68080
Rate      : 201.23 polls/sec

root@bbb:~/poll-gpio# uptime
 12:19:56 up 48 min,  2 users,  load average: 0.00, 0.04, 0.06

200 polls/sec with 10 pins gives the 20 Hz for each pin.

I didn't measure for time variations between individual reads, but I think there is enough slack that there wouldn't be anything to care about.

And a trivial kernel driver would still make this even more efficient if that's ever needed.