AI-64 - PWM confusion

Hi Guys,

I’m trying to do something that I thought would be easy, using the sys interface to get a PWM signal.

The schematic has some pinout descriptions, the dts files also have setup for everything and I have looked at /sys/kernel/debug/pinctrl/4301c000.pinctrl-pinctrl-single/pinmux-pins.

Nothing seems to match up :slight_smile:

I’m guessing I need to use pinctrl to get this going?

Has anyone got any pointers?

Thanks

Andy

So I have enabled all the PWMs, I have probed every pin on the headers (great fun), I have looked into pinctrl and come to the conclusion that the only way that PWM can got to work on this board is via the dts stuff.

Is this correct?

Cheers

Andy

Ok, so after much messing around I have a way to get this going, I have no idea if this is the best way to go about things but it works, it should also help anyone looking at getting pin muxing going.

For this example I am using channel A of ehrpwm0, we can see it in /opt/source/dtb-5.10-ti-arm64/src/arm64/k3-j721e-beagleboneai64.dts:

ehrpwm0_pins_default: ehrpwm0_pins_default {
		pinctrl-single,pins = <
			J721E_IOPAD(0x164, PIN_OUTPUT, 6) /* (V29) RGMII5_TD2.EHRPWM0_A */
			J721E_IOPAD(0x168, PIN_OUTPUT, 6) /* (V27) RGMII5_TD1.EHRPWM0_B */
		>;
	};

The next task is trying to work out where that IOPAD is going, if we look in /opt/source/dtb-5.10-ti-arm64/include/dt-bindings/board/k3-j721e-bone-pins.h we can see the mapping of that IOPAD (0x164) to P8_19:

#define P8_19(mode, mux)  J721E_IOPAD(0x164, mode, mux)       /* V29 */

Now back to the dts we can see the various defines for this pin, these are expanded by the macros BONE_PIN() and P8_19().

BONE_PIN(P8_19, default,   P8_19(PIN_INPUT, 7))
BONE_PIN(P8_19, pwm,       P8_19(PIN_OUTPUT, 6))
BONE_PIN(P8_19, gpio,      P8_19(PIN_INPUT, 7))
BONE_PIN(P8_19, gpio_pu,   P8_19(PIN_INPUT_PULLUP, 7))
BONE_PIN(P8_19, gpio_pd,   P8_19(PIN_INPUT_PULLDOWN, 7))

So to enable the PWM we have to change cape_header: pinmux_dummy, pinmux_dummy is one of those words that google knows nothing about but It looks like this is what we want in order to change the muxing of the pins.

By default it setup to use the default pinmapping, so to use the PWM we change it to this:

/* Dummy driver to request setup for cape header pins */
	cape_header: pinmux_dummy {
		compatible = "gpio-leds";
		pinctrl-names = "default";
		pinctrl-0 = <
			&P8_03_default_pin
			&P8_04_default_pin
			&P8_05_default_pin
			&P8_06_default_pin
			&P8_07_default_pin
			&P8_08_default_pin
			&P8_09_default_pin
			&P8_10_default_pin
			&P8_11_default_pin
			&P8_12_default_pin
			&P8_13_default_pin
			&P8_14_default_pin
			&P8_15_default_pin
			&P8_16_default_pin
			&P8_17_default_pin
			&P8_18_default_pin
			&P8_19_pwm_pin
...

now build the dts and install it:

cd /opt/source/dtb-5.10-ti-arm64/

make

make install

Now reboot.

when it is up and running we need to setup ehrpwm0 channel A which is pwmchip0 (you can work this out from the address)

cd /sys/class/pwm/pwmchip0
echo 0 > export
cd pwm0
echo 1000 > period
echo 500 > duty_cycle 
echo 1 > enable 

Screenshot 2022-06-26 at 16.33.49

I have noticed something weird about all this!

If you don’t enable and set up PWM1 then the duty_cycle on PWM0 can not be set (well it can be set but it has no effect), very weird.

So to get PWM0 working properly you need:

cd /sys/class/pwm/pwmchip0
echo 1 > export
cd pwm1
echo 1000 > period
echo 500 > duty_cycle 
echo 1 > enable 
cd /sys/class/pwm/pwmchip0
echo 0 > export
cd pwm0
echo 1000 > period
echo 500 > duty_cycle 
echo 1 > enable 

Very strange