Hardware-PWM with RPi.GPIO-Odroid?

Post Reply
mattlovell
Posts: 38
Joined: Sat Sep 24, 2016 4:37 am
languages_spoken: english
ODROIDs: C2, C4
Location: Colorado
Has thanked: 9 times
Been thanked: 4 times
Contact:

Hardware-PWM with RPi.GPIO-Odroid?

Post by mattlovell »

Does RPi.GPIO-Odroid

https://wiki.odroid.com/odroid-xu4/appl ... o/rpi.gpio
https://github.com/awesometic/RPi.GPIO-Odroid

provide the ability to use the C4's hardware-based PWM at all, or is PWM still entirely software-controlled?

I ask since, experimenting with changes for kodi_panel.py, it is quite easy to end up with very noticeable flickering for the LCD panel's backlight.

Ideally, one could combine HW-based PWM (for precise control of the duty cycle) while still leaving Python scripts able to turn the GPIO on and off more generally (i.e., running or stopped). Is that combination possible?

Thanks,
Matt

User avatar
tobetter
Posts: 7118
Joined: Mon Feb 25, 2013 10:55 am
languages_spoken: Korean, English
ODROIDs: Many
Location: Paju, South Korea
Has thanked: 380 times
Been thanked: 1044 times
Contact:

Re: Hardware-PWM with RPi.GPIO-Odroid?

Post by tobetter »

It's H/W based PWM and we are sorting out the code to be managed by DTBO as well. But yes, you can try it out.

mattlovell
Posts: 38
Joined: Sat Sep 24, 2016 4:37 am
languages_spoken: english
ODROIDs: C2, C4
Location: Colorado
Has thanked: 9 times
Been thanked: 4 times
Contact:

Re: Hardware-PWM with RPi.GPIO-Odroid?

Post by mattlovell »

tobetter wrote:
Fri Oct 23, 2020 1:25 am
It's H/W based PWM and we are sorting out the code to be managed by DTBO as well. But yes, you can try it out.
Ok, so the current HEAD of awesometic/RPi.GPIO-Odroid on github makes use of the Odroid's HW PWM?

I'll give a try. Any recommended frequencies that are "easier" for HW to drive (i.e., some relationship to an existing hardware clock)?

mattlovell
Posts: 38
Joined: Sat Sep 24, 2016 4:37 am
languages_spoken: english
ODROIDs: C2, C4
Location: Colorado
Has thanked: 9 times
Been thanked: 4 times
Contact:

Re: Hardware-PWM with RPi.GPIO-Odroid?

Post by mattlovell »

Are you sure it's HW-based?

Setting up, via luma.lcd's PWMBacklight support, a frequency of 1 kHz and a duty cycle of 75%, there's definitely a visible flicker.

Thanks,
Matt

User avatar
tobetter
Posts: 7118
Joined: Mon Feb 25, 2013 10:55 am
languages_spoken: Korean, English
ODROIDs: Many
Location: Paju, South Korea
Has thanked: 380 times
Been thanked: 1044 times
Contact:

Re: Hardware-PWM with RPi.GPIO-Odroid?

Post by tobetter »

mattlovell wrote:
Fri Oct 23, 2020 1:47 am
Are you sure it's HW-based?

Setting up, via luma.lcd's PWMBacklight support, a frequency of 1 kHz and a duty cycle of 75%, there's definitely a visible flicker.

Thanks,
Matt
How did you set the PWM? And which pin?

mattlovell
Posts: 38
Joined: Sat Sep 24, 2016 4:37 am
languages_spoken: english
ODROIDs: C2, C4
Location: Colorado
Has thanked: 9 times
Been thanked: 4 times
Contact:

Re: Hardware-PWM with RPi.GPIO-Odroid?

Post by mattlovell »

tobetter wrote:
Fri Oct 23, 2020 1:50 am
How did you set the PWM? And which pin?
My script is using luma.lcd to drive the display. Here are the relevant constructor calls, as well as my comments describing the connectivity. The LED backlight signal is in the list:

Code: Select all

# Below is how I've connected the ILI9341, which is *close* to the
# recommended wiring in luma.lcd's online documentation.  Again,
# recall the distinction between RPi.GPIO pin naming and physical pin
# numbers.
#
# As you can provide RPi.GPIO numbers as arguments to the spi()
# constructor, you do have some flexibility.
#
#
#   LCD pin     |  RPi.GPIO name   |  Odroid C4 pin #
#   ------------|------------------|-----------------
#   VCC         |  3V3             |  1 or 17
#   GND         |  GND             |  9 or 25 or 39
#   CS          |  GPIO8           |  24
#   RST / RESET |  GPIO25          |  22
#   DC          |  GPIO24          |  18
#   MOSI        |  GPIO10 (MOSI)   |  19
#   SCLK / CLK  |  GPIO11 (SCLK)   |  23
#   LED         |  GPIO18          |  12 (a.k.a. PWM_E)
#   ------------|------------------|-----------------
#
# Originally, the constructor for ili9341 also included a
# framebuffer="full_frame" argument.  That proved unnecessary
# once non-zero reset hold and release times were specified
# for the device.
#
serial = spi(port=0, device=0, gpio_DC=24, gpio_RST=25,
             reset_hold_time=0.2, reset_release_time=0.2)

if USE_PWM:
    device = ili9341(serial, active_low=False, width=320, height=240,
                     bus_speed_hz=32000000,
                     gpio_LIGHT=18,
                     pwm_frequency=PWM_FREQ
    )
where PWM_FREQ was set to 1000. One can then activate the backlight with calls such as

Code: Select all

device.backlight(PWM_LEVEL)
where PWM_LEVEL is a Python float between 0 and 100. I tried 50.0 and 75.0.

The luma.lcd PWMBacklight class can be found in this file:

https://github.com/rm-hull/luma.lcd/blo ... /device.py

The object that code uses is one obtained from the GPIO package. In this case, that should be RPi.GPIO-Odroid:

Code: Select all

  self._pwm = self._gpio.PWM(pin, frequency)
  self._pwm.start(0.0)
The backlight() calls then end up here (device.py Lines 167-175):

Code: Select all

        :param value: Sets the value of the backlight.  Can provide a bool
        (True/False) to turn on/off or a float to set the backlight intensity in
        percentage (0 <= value <= 100.0).
        :type value: bool or float
        """
        if value in (True, False):
            value = 100.0 if value else 0.0
        assert 0.0 <= value <= 100.0
        self._pwm.ChangeDutyCycle(value)
That's what I think is happening anyway.

Any help you could offer is greatly appreciated!

Cheers,
Matt

User avatar
tobetter
Posts: 7118
Joined: Mon Feb 25, 2013 10:55 am
languages_spoken: Korean, English
ODROIDs: Many
Location: Paju, South Korea
Has thanked: 380 times
Been thanked: 1044 times
Contact:

Re: Hardware-PWM with RPi.GPIO-Odroid?

Post by tobetter »

I am not sure yet, since I also had use the Luma very recently for simple app. And I have seen that it's based on the Python for RPi GPIO library, so what I am guessing is that it might be not compatible. Let me discuss with my workmate who is more familiar with the python library for the ODROID GPIO support if we can do something with Luma.

Other than that, you could try to run PWM with WiringPi or DTB so that you can ensure if PWM is hardware based on software based. Since I do not have oscilloscope at the moment, maybe tomorrow myself or someone else can give you more detail.

mattlovell
Posts: 38
Joined: Sat Sep 24, 2016 4:37 am
languages_spoken: english
ODROIDs: C2, C4
Location: Colorado
Has thanked: 9 times
Been thanked: 4 times
Contact:

Re: Hardware-PWM with RPi.GPIO-Odroid?

Post by mattlovell »

tobetter wrote:
Fri Oct 23, 2020 2:05 am
Other than that, you could try to run PWM with WiringPi or DTB so that you can ensure if PWM is hardware based on software based. Since I do not have oscilloscope at the moment, maybe tomorrow myself or someone else can give you more detail.
I can try, but I should also mention that I'm running under CoreELEC (rather than a fuller Linux distribution like Debian or Ubuntu):

Code: Select all

Linux C4 4.9.113 #1 SMP PREEMPT Fri Aug 14 20:30:41 UTC 2020 aarch64 GNU/Linux
The /sys/class/pwm directory is populated. Running ls -l /sys/class/pwm yields:

Code: Select all

lrwxrwxrwx    1 root     root             0 Apr 11  2019 pwmchip0 -> ../../devices/platform/soc/ffd00000.cbus/ffd19000.pwm/pwm/pwmchip0
lrwxrwxrwx    1 root     root             0 Apr 11  2019 pwmchip4 -> ../../devices/platform/soc/ff800000.aobus/ff802000.pwm/pwm/pwmchip4
I installed the RPi.GPIO-Odroid package from source, after installing entware. (If you want to see the installation steps I followed to get RPi.GPIO-Odroid and luma running, they're documented in the readme on kodi_panel's github page.)

Thanks again,
Matt

mattlovell
Posts: 38
Joined: Sat Sep 24, 2016 4:37 am
languages_spoken: english
ODROIDs: C2, C4
Location: Colorado
Has thanked: 9 times
Been thanked: 4 times
Contact:

Re: Hardware-PWM with RPi.GPIO-Odroid?

Post by mattlovell »

It looks to me like RPi.GPIO-Odroid's PWM implementation resides here:

https://github.com/awesometic/RPi.GPIO- ... soft_pwm.c

Which is a pthreads-based implementation, with pwm_thread() being the main code of the thread that runs.

User avatar
tobetter
Posts: 7118
Joined: Mon Feb 25, 2013 10:55 am
languages_spoken: Korean, English
ODROIDs: Many
Location: Paju, South Korea
Has thanked: 380 times
Been thanked: 1044 times
Contact:

Re: Hardware-PWM with RPi.GPIO-Odroid?

Post by tobetter »

mattlovell wrote:
Fri Oct 23, 2020 2:20 am
It looks to me like RPi.GPIO-Odroid's PWM implementation resides here:

https://github.com/awesometic/RPi.GPIO- ... soft_pwm.c

Which is a pthreads-based implementation, with pwm_thread() being the main code of the thread that runs.
Ok, so...I guess awesometic, actually @joshua.yang here in this forum, will catch you this thread tomorrow or I will let him look into this.
These users thanked the author tobetter for the post:
mattlovell (Fri Oct 23, 2020 2:57 am)

mattlovell
Posts: 38
Joined: Sat Sep 24, 2016 4:37 am
languages_spoken: english
ODROIDs: C2, C4
Location: Colorado
Has thanked: 9 times
Been thanked: 4 times
Contact:

Re: Hardware-PWM with RPi.GPIO-Odroid?

Post by mattlovell »

The python-periphery project looks interesting. It is a pure Python library that offers GPIO, hardware-based PWM, and more.

The PWM support looks to be accomplished via use of the /sys/class/pwm/* sysfs files. Perhaps something similar could be done with RPi.GPIO-Odroid, rather than the existing soft_pwm.c approach.

https://github.com/vsergeev/python-peri ... ery/pwm.py

It would be great to take advantage of HW PWM while still allowing Python to control whether the signal is actively running or idle.

User avatar
tobetter
Posts: 7118
Joined: Mon Feb 25, 2013 10:55 am
languages_spoken: Korean, English
ODROIDs: Many
Location: Paju, South Korea
Has thanked: 380 times
Been thanked: 1044 times
Contact:

Re: Hardware-PWM with RPi.GPIO-Odroid?

Post by tobetter »

mattlovell wrote:
Fri Oct 23, 2020 11:18 am
The python-periphery project looks interesting. It is a pure Python library that offers GPIO, hardware-based PWM, and more.

The PWM support looks to be accomplished via use of the /sys/class/pwm/* sysfs files. Perhaps something similar could be done with RPi.GPIO-Odroid, rather than the existing soft_pwm.c approach.

https://github.com/vsergeev/python-peri ... ery/pwm.py

It would be great to take advantage of HW PWM while still allowing Python to control whether the signal is actively running or idle.
Wait, I've read your thread again and I realize that why you need the H/W PWM is to control LCD backlight? Then wouldn't it be better to create a backlight device in the kernel space and set the duty cycle or freq from the userspace? Wouldn't it make Python be more simple? Just a quick thought.

mattlovell
Posts: 38
Joined: Sat Sep 24, 2016 4:37 am
languages_spoken: english
ODROIDs: C2, C4
Location: Colorado
Has thanked: 9 times
Been thanked: 4 times
Contact:

Re: Hardware-PWM with RPi.GPIO-Odroid?

Post by mattlovell »

tobetter wrote:
Fri Oct 23, 2020 1:56 pm
Wait, I've read your thread again and I realize that why you need the H/W PWM is to control LCD backlight? Then wouldn't it be better to create a backlight device in the kernel space and set the duty cycle or freq from the userspace? Wouldn't it make Python be more simple? Just a quick thought.
It would still be nice to take advantage of luma.lcd's API. The luma.lcd module incorporates backlight control for several of the displays it supports.

My ideal scenario would be:
  • Python code is responsible for specifying the frequency and duty cycle of the backlight signal as well as whether the signal is active or not. (A duty cycle==0 would work, I suppose.)
  • Hardware is responsible for generating the PWM waveform, such that the display's brightness (when on) is entirely stable.
Right now, the pthread implementation in RPi.GPIO-Odroid (inherited from the original RPi version, I believe) cannot guarantee real-time scheduling. As a consequence, there is noticeable flicker in the backlight's brightness.

Poking around, it seems that even using sysfs for GPIO and PWM is falling out of favor (trying instead to consolidate onto libgpiod). At the moment, though, with CoreELEC using Linux 4.9.113, some sort of interaction with sysfs seems like the easiest "lift" for Python code.

Cheers,
Matt

joshua.yang
Posts: 475
Joined: Fri Sep 22, 2017 5:54 pm
languages_spoken: Korean, English
ODROIDs: XU4, XU4Q + Cloudshell2, H2, N2
Has thanked: 32 times
Been thanked: 130 times
Contact:

Re: Hardware-PWM with RPi.GPIO-Odroid?

Post by joshua.yang »

I checked the possibility of HW-based PWM working on CoreELEC. As a result, unfortunately, we cannot use the HW-based PWM in CoreELEC.

There're two exposed pwmchip nodes, which are pwmchip0 and pwmchip4, under the /sys/class/pwm directory. We can export PWM pins using the export file in there like echo 0 > pwmchip0/export, but it wouldn't work.
Here are my full steps to use the PWM pins.

Code: Select all

cd /sys/class/pwm
echo 0 > pwmchip0/export
echo 1000000 > pwmchip0/pwm0/period
echo 1000000 > pwmchip0/pwm0/duty_cycle
echo 1 > pwmchip0/pwm0/enable
As the results of these commands, physical pin #35 should turn on constantly. But, it does not work on CoreELEC while it does work on our Ubuntu image by using the same commands.

Besides, I noticed that the pwmchip nodes indicate the different addresses compared to our Ubuntu image.
Here're the results of ls -al in CoreELEC.

Code: Select all

lrwxrwxrwx  1 root   root       0 Apr 11 2019 pwmchip0 -> ../../devices/platform/soc/ffd00000.cbus/ffd19000.pwm/pwm/pwmchip0
lrwxrwxrwx  1 root   root       0 Apr 11 2019 pwmchip4 -> ../../devices/platform/soc/ff800000.aobus/ff802000.pwm/pwm/pwmchip4
And in Ubuntu.

Code: Select all

lrwxrwxrwx  1 root root 0 Jan 1 1970 pwmchip0 -> ../../devices/platform/soc/ffd00000.cbus/ffd1a000.pwm/pwm/pwmchip0/
lrwxrwxrwx  1 root root 0 Jan 1 1970 pwmchip4 -> ../../devices/platform/soc/ffd00000.cbus/ffd19000.pwm/pwm/pwmchip4/
lrwxrwxrwx  1 root root 0 Jan 1 1970 pwmchip8 -> ../../devices/platform/soc/ff800000.aobus/ff802000.pwm/pwm/pwmchip8/
You can see the differences. Even the address 0xffd1a000 is not referenced in CoreELEC.

So, making RPi.GPIO-Odroid uses HW-based PWM can be done but it will only affect our Ubuntu system.
I think in order to use the HW-based PWM on C4, this phenomenon should be reported to the CoreELEC team. :)
These users thanked the author joshua.yang for the post:
mattlovell (Wed Oct 28, 2020 1:13 am)

mattlovell
Posts: 38
Joined: Sat Sep 24, 2016 4:37 am
languages_spoken: english
ODROIDs: C2, C4
Location: Colorado
Has thanked: 9 times
Been thanked: 4 times
Contact:

Re: Hardware-PWM with RPi.GPIO-Odroid?

Post by mattlovell »

I think in order to use the HW-based PWM on C4, this phenomenon should be reported to the CoreELEC team. :)
I opened a new topic in the Development section of CE's forum for the above. Thanks for taking a look!

mattlovell
Posts: 38
Joined: Sat Sep 24, 2016 4:37 am
languages_spoken: english
ODROIDs: C2, C4
Location: Colorado
Has thanked: 9 times
Been thanked: 4 times
Contact:

Re: Hardware-PWM with RPi.GPIO-Odroid?

Post by mattlovell »

Returning to this topic, what does Hardkernel's device tree look like with regard to PWM?

The following is an excerpt from the CoreELEC installation's /flash/dtb.img file on my Odroid C4:

Code: Select all

                        pwm@1b000 {
                                compatible = "amlogic,g12a-ee-pwm";
                                reg = <0x00 0x1b000 0x00 0x20>;
                                #pwm-cells = <0x03>;
                                clocks = <0x16 0x16 0x16 0x16>;
                                clock-names = "clkin0\0clkin1\0clkin2\0clkin3";
                                status = "disabled";
                                phandle = <0x99>;
                        };

                        pwm@1a000 {
                                compatible = "amlogic,g12a-ee-pwm";
                                reg = <0x00 0x1a000 0x00 0x20>;
                                #pwm-cells = <0x03>;
                                clocks = <0x16 0x16 0x16 0x16>;
                                clock-names = "clkin0\0clkin1\0clkin2\0clkin3";
                                status = "disabled";
                                phandle = <0x9a>;
                        };

                        pwm@19000 {
                                compatible = "amlogic,g12a-ee-pwm";
                                reg = <0x00 0x19000 0x00 0x20>;
                                #pwm-cells = <0x03>;
                                clocks = <0x16 0x16 0x16 0x16>;
                                clock-names = "clkin0\0clkin1\0clkin2\0clkin3";
                                status = "okay";
                                phandle = <0x9b>;
                        };
Would it be possible get hardware PWM going (in this kernel 4.9.113 CoreELEC) just via updates to the device tree?

Thanks,
Matt

joshua.yang
Posts: 475
Joined: Fri Sep 22, 2017 5:54 pm
languages_spoken: Korean, English
ODROIDs: XU4, XU4Q + Cloudshell2, H2, N2
Has thanked: 32 times
Been thanked: 130 times
Contact:

Re: Hardware-PWM with RPi.GPIO-Odroid?

Post by joshua.yang »

Hi,

Here's the corresponding part of Odroid N2/C4 kernel.
https://github.com/hardkernel/linux/blo ... .dtsi#L540

I'm sorry but I'm not sure about replacing Armbian's PWM part with Hardkernel's since we don't know how Armbian's kernel, device tree configured.

BTW, I had worked on RPi.GPIO-Odroid to support HW-based PWM a few weeks ago. It is not released yet.
https://github.com/awesometic/RPi.GPIO-Odroid/tree/dev

This uses the PWM nodes on sysfs.
It seems working on our Ubuntu image but looks the system had a bug that invokes kernel panic when re-export a pin after un-export. So it is still in the testing stage.
We will look into this.

Post Reply

Return to “Hardware and peripherals”

Who is online

Users browsing this forum: No registered users and 1 guest