Friday, 7 June 2013

Pinmuxing

If you want to use the Black as anything more than just a very small computer (and you should), pinmuxing is going to be very important. Essentially, every pin on the GPIO headers on the Black do multiple things, depending on what mode you have them set to. Therefore, if you want to use a pin as an output, you need to set it to the correct mode. Using the Linux 3.8 kernel means interfacing with the new device tree. In general, this is a good thing. It standardises hardware initialisation across any embedded Linux system, meaning that you only write drivers once, and then use them forever more. Even better, all the required drivers are already written, we just need to know how to play with them. So, some steps and discussion.
First, we introduce some shorthand to save typing:

export SLOTS=/sys/devices/bone_capemgr.8/slots
export PINS=/sys/kernel/debug/pinctrl/44e10800.pinmux/pins

Now, let's say we want to make pins 11 and 12 of the P8 header, also known as GPIO_45 and GPIO_44, into mode 7 output pins. We need to know the kernel pin numbers, which are conveniently located on a diagram here. It can be clearly seen that we need pin numbers 12 and 13.

Next, run cat $PINS, and find pins 12 and 13. We see that they have hex addresses of 44e10830 and 44e10834, and are currently set to 0x27. 0x27 = 0b100111, and by consulting the following table, we see that the pins are in mode 7, input and acting as pull-down resistors.

Table of mux options:
Bit 0 \
Bit 1 |- Mode
Bit 2 /
Bit 3: 1 - Pull disabled, 0 - Pull enabled
Bit 4: 1 - Pull up, 0 - Pull down
Bit 5: 1 - Input, 0 – Output


The only thing we want to change is to make these into output pins, which means setting the pins to 0x07.

Next, we need a device tree source file. We'll call it pinctrl_test_0.dts, and it should look like this:
/*
* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
/dts-v1/;
/plugin/;
/ { compatible = "ti,beaglebone", "ti,beaglebone-black";
/* identification */
part-number = "pinctrl-test-0";
fragment@0 {
target = <&am33xx_pinmux>;
__overlay__ {
pinctrl_test: pinctrl_test_0_pins {
pinctrl-single,pins = <;
0x030 0x07 /* P8_12 OUTPUT | MODE7 */
0x034 0x07 /* P8_11 OUTPUT | MODE7 */
>;
};
};
};

fragment@1 {
target = <&ocp>;
__overlay__ {
test_helper: helper {
compatible = "bone-pinmux-helper";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_test>;
status = "okay";
};
};
};
};
Compile the dts file using dtc (this is installed on the Black):
dtc -O dtb -o pinctrl-test-0-00A0.dtbo -b 0 -@ pinctrl-test-0.dts

Copy this new file to /lib/firmware, echo pinctrl-test-0 > $SLOTS and you're done.


This was all written by using Jason Kridner's test-capemgr project, found here.