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 |
- in pcb rev 0.3 and before, this was on pin P8.43
- in pcb rev 0.4, the led was on some other pins, but didn't work. All rev 4 sample capes have been reworked.
- in pcb rev 0.4, digital input 2, 3 and 5 were on GPIO1_5, GPIO1_1 and GPIO1_31. But those had conflicts.
- 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.