Pwm on allwinner h3


5 5

Recommended Posts

Donate and support the project!

There is a python library to access the GPIO based on WiringPI/WiringOP around, but I didn't use the PWM feature.


I successfully used this WiringOP fork (but this is only C) with software PWM:

You may give a try to wrap using ctypes python module to gain access to the C library from python.


I didn't try the hardware PWM, Orange PI H3 devices have just one hardware PWM exposed via GPIO, and it has to be activated via script.bin

Link to post
Share on other sites

Thank you, Very much appreciated!

There are many examples for their matrix code. which appear to be just shims around the kernel driver userland stuff here

I will try and test some ASAP.

Link to post
Share on other sites

how so?

Last documentation H3 says that PA06 no pwm.

It's a lie?


I don't know. Neither interested in PWM nor Audio but I can remember that FriendlyARM fiddled around PA06 for reasons unknown to me. Just wanted people looking into it save some time but can't answer any detail questions.

Link to post
Share on other sites


There are the results?

I tried last night.

First i tried on FA's Lichee.

I could get that running without errors . I didn't actuall hook up a LED to ensure the PWM was getting to the pin  yet.

But I can see driver load and test program thinks all is well.


However for a fresh build that included the patch I see the driver loading but the library FAHW-Lib complains that it failed to set pwm.

dmesg shows nothing more of use.


I need to dig deep and gain a better understanding of driver installation.

Link to post
Share on other sites

Not much to add. Looking at the source it appears that the PWM initialized ok but the attempt to do ioctrol failed.

One thing I noted is the pwm demo file is opened with read only which seems odd as it will be writing the PWM pin, duty cycle and period.

if ((devFD = openHW("/dev/pwm", O_RDONLY)) == -1) { setLastError("Fail to open pwm device"); return -1; }   if (ioctl(devFD, PWM_IOCTL_SET_FREQ, arg) == -1) { setLastError("Fail to set pwm"); // This is the message I see. closeHW(devFD); return -1;


I checked the fex file and there is entries there. I don't know how to check them...

Next thing up will be to recompile Armbian with RW.

Also going to put an LED on PIN 6 to see some flashing.

Also read the data sheet section on the PWM for the H3. Straightforward with not very many options if compared to a PIC

Slow going as I am cutting my teeth on Linux Device Driver development.


Will keep you posted.


Also noted from the code the H3 is compiled the same for M1 and Neo.

2 PWM channels. Channel 1 is the on one on PA06/GPIO6.

The other channel is on a pin used by UART0 RX so not possible to use console IO at the same time.

Might try putting some printk statements in to see what the PWM driver shows.

It also has a debug setting if I can figure out how to turn it on.

Link to post
Share on other sites

The manual states there is only one PWM so, any idea how a PWM1 is supposed to work?


I tried to add pin stuff on the DTS and changed some lines in pwm-sun4i.c without success. I was able to export pwm1 and change duty and so on but it didn't change the LED.


However exporting the GPIO and writing the value changed the LED state.

Link to post
Share on other sites

So I managed to get back to this but am still unable to get the pwm working on the 3.4 kernel legacy build.

I am trying pwm1 (H3 supports 0 and 1) on linux GPI0 5 and 6 respectively.

PWM0 GPIO 5 is multiplexed with UART0_RX which is the uart for the serial console and therefore not available on the neo.

the code loads the driver fine using modprob matrix-pwm and /dev/pwm  is available.


This file can be opened and the failure is on the ioctl call to set the frequency.

Actually it is writing the pwm pin (linux 6), pwm index (1), frequency(period) and duty cycle

All seems to work well until it hits the pwm_request call in the driver which fails.

dmesg shows me "request pwm1 failed"


which is coming from the driver.

At this point I am stuck.

I also  loaded the FA lichee build to  see if the pwm demo actually works on that.

The program runs but I don't think it is actually making it to the pin as I can't get the LED to light. I can get the GPIO to output (neo 12) so not a pin numbering issue.

Any suggestions appreciated.



 File /home/allan/armbianneo4.7.6/lib/patch/kernel/sun8i-default/matrix-support-Matrix-starter-kit.patch

static int matrix_pwm_hw_init(int index, int pin)
+    int ret=0;
+#if 0
+    ret = gpio_request(pin, DEVICE_NAME);
+    if (ret) {
+        printk("request gpio %d for pwm failed\n", pin);
+        return ret;
+    }
+    gpio_direction_output(pin, 0);
+    matrix_pwm[index] = pwm_request(index, DEVICE_NAME);
+    if (IS_ERR(matrix_pwm[index])) {
+        printk("request pwm%d failed\n", index);
+#if 0
+        gpio_free(pin);
+        return -ENODEV;
+    }

Link to post
Share on other sites

How to improve handling of PWM:


My tutorial to drive WS2812 with an Orange Pi zero:


Both links contain clues which may be usefull for those who are playing with the PWM, even if you are not driving LEDs.

Link to post
Share on other sites

This topic is now closed to further replies.

5 5