GPIO Python or shell


(Frank W.) #36

tested with kernel 4.14:

some calculations and export:

[10:51] root@bpi-r2:~# GPIO_NO=$((232+200))
[10:53] root@bpi-r2:~# echo $GPIO_NO
432
[10:53] root@bpi-r2:~# echo $GPIO_NO > /sys/class/gpio/export

first try with LED, if GPIO is right:

[10:53] root@bpi-r2:~# echo out > /sys/class/gpio/gpio${GPIO_NO}/direction
[10:53] root@bpi-r2:~# echo 1 > /sys/class/gpio/gpio${GPIO_NO}/value
[10:54] root@bpi-r2:~# echo 0 > /sys/class/gpio/gpio${GPIO_NO}/value

LED goes on on “1” and off on “0”, so now try with high-active button-circuit on GPIO 200 (pin 40 between button and resistor, using pin 39 as GND [resistor] and pin 17 as 3v3-vcc)

[10:54] root@bpi-r2:~# echo in > /sys/class/gpio/gpio${GPIO_NO}/direction
[10:56] root@bpi-r2:~# cat /sys/class/gpio/gpio${GPIO_NO}/value
0 #button not pressed 
[10:56] root@bpi-r2:~# cat /sys/class/gpio/gpio${GPIO_NO}/value
1 #button pressed
[10:56] root@bpi-r2:~# cat /sys/class/gpio/gpio${GPIO_NO}/value
0 #button not pressed

as you see, it works :wink:


Gpio + uart (not the debug-port)
(Frank W.) #37

can you explain me why this:

root@bpi-r2:~# echo 3 >/sys/class/pwm/pwmchip0/export
root@bpi-r2:~# echo 200000 >/sys/class/pwm/pwmchip0/pwm3/period
root@bpi-r2:~# echo 100000 >/sys/class/pwm/pwmchip0/pwm3/duty_cycle
root@bpi-r2:~# echo 1 >/sys/class/pwm/pwmchip0/pwm3/enable

results in 1kHz-PWM? if period is full time (high+low) and in nanoseconds, it should be

200 000 ns = 200 µs = 0,2 ms = 0,0002 s => 1/0.0002 = 5000=5kHz

for 1 kHz period should be 1000000ns and dutycycle 500000ns, or am i’m wrong?


(dorabmon) #38

You should be right. I guessed it should be driver problems. I will try to have more analysis when I have free time.


(Frank W.) #39

that should be the relevant part (looks right so far):

static int mtk_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
			  int duty_ns, int period_ns)
{
	struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip);
	struct clk *clk = pc->clks[MTK_CLK_PWM1 + pwm->hwpwm];
	u32 resolution, clkdiv = 0;
	int ret;

	ret = mtk_pwm_clk_enable(chip, pwm);
	if (ret < 0)
		return ret;

	resolution = NSEC_PER_SEC / clk_get_rate(clk);

	while (period_ns / resolution > 8191) {
		resolution *= 2;
		clkdiv++;
	}

    mtk_pwm_writel(pc, pwm->hwpwm, PWMCON, BIT(15) | clkdiv);
    if (pwm->hwpwm > 2) { //for PWM4 and PWM5
        mtk_pwm_writel(pc, pwm->hwpwm, PWM45DWIDTH, period_ns / resolution);
        mtk_pwm_writel(pc, pwm->hwpwm, PWM45THRES, duty_ns / resolution);
    }else{
        mtk_pwm_writel(pc, pwm->hwpwm, PWMDWIDTH, period_ns / resolution);
        mtk_pwm_writel(pc, pwm->hwpwm, PWMTHRES, duty_ns / resolution);
    }
    mtk_pwm_clk_disable(chip, pwm);

i assume that there is a Problem in “resolution = NSEC_PER_SEC / clk_get_rate(clk);”

tried adding “resolution = resolution / 5;” after the while-loop, but now i’m getting 730 Hz

so i assume the problem in clkdiv-line “mtk_pwm_writel(pc, pwm->hwpwm, PWMCON, BIT(15) | clkdiv);”

added now 2 printk’s:

root@bpi-r2:~# echo 200000 >/sys/class/pwm/pwmchip0/pwm3/period
root@bpi-r2:~# echo 100000 >/sys/class/pwm/pwmchip0/pwm3/duty_cycle
[   42.063060] [mtk_pwm_config] period_ns: 200000, duty_ns: 100000
[   42.068179] [mtk_pwm_config] resolution: 48, clkdiv: 4

can you verify that is correct?


(Frank W.) #40

anything new about the wrong frequency and the missing PWM-Pins?


(dorabmon) #41

Hi, Frank

Could you help to test if the issue can be fixup after making the below changes which use clocks all from 26M instead of the old ones.

pwm: pwm@11006000 {
        compatible = "mediatek,mt7623-pwm";
        reg = <0 0x11006000 0 0x1000>;
        #pwm-cells = <2>;
        clocks = <&clk26m>,
                 <&clk26m,
                 <&clk26m>,
                 <&clk26m>,
                 <&clk26m>,
                 <&clk26m>,
                 <&clk26m>;
        clock-names = "top", "main", "pwm1", "pwm2",
                      "pwm3", "pwm4", "pwm5";
        status = "disabled";
};

(Frank W.) #42

currently it seems to do nothing, no output on pwm3 (pin 7+9)

root@bpi-r2:~# echo 3 >/sys/class/pwm/pwmchip0/export
root@bpi-r2:~# echo 200000 >/sys/class/pwm/pwmchip0/pwm3/period                 
[  130.864219] [mtk_pwm_config] period_ns: 200000, duty_ns: 0                   
root@bpi-r2:~# echo 100000 >/sys/class/pwm/pwmchip0/pwm3/duty_cycle             
[  130.864230] [mtk_pwm_config] resolution: 38, clkdiv: 0                       
[  140.144237] [mtk_pwm_config] period_ns: 200000, duty_ns: 100000              
root@bpi-r2:~# echo 1 >/sys/class/pwm/pwmchip0/pwm3/enable

btw. you have a typo in second clock-line (missing “>”)

reverted the change and i got the 1kHz (instead of 5kHz) again


(Frank W.) #43

anything new to PWM-frequency-bug?


(dorabmon) #44

Can you add more 4-times division into the equation and test again? I think it should be internal clock factor is missing in the clock driver for PWM.

as doing that

clock = clk_get_rate(clk) / 4;
resolution = NSEC_PER_SEC / clock;

and not to do as that

resolution = NSEC_PER_SEC / clk_get_rate(clk) / 4;

it would cause more precision is losing.


(Frank W.) #45

Using old clock,right? clk26m results in no output


(dorabmon) #46

please drop old patch with 26Mhz. and use original code as 4.14 kernel is using.


(Frank W.) #47

1kHz without /4 and with it again no output

[  780.909447] [mtk_pwm_config] period_ns: 200000, duty_ns: 0
[  780.909457] [mtk_pwm_config] resolution: 0, clkdiv: 0
[  784.029473] [mtk_pwm_config] period_ns: 200000, duty_ns: 100000

changed that “/ 4” in my main-branch codebase (not commited/pushed)


(dorabmon) #48

So weird. do you ensure you add more 4-times divisor based on the code you have done below testing?


(Frank W.) #49

Sorry, did it like in your second example…i try the first one tomorrow

Edit: its more near 5kHz :slight_smile:

How preceise should it be?

[   73.950379] [mtk_pwm_config] clock: 68250000, clockrate: 273000000           
[   73.950390] [mtk_pwm_config] period_ns: 200000, duty_ns: 0                   
[   73.950396] [mtk_pwm_config] resolution: 28, clkdiv: 1                       
[   76.910445] [mtk_pwm_config] clock: 68250000, clockrate: 273000000           
[   76.910455] [mtk_pwm_config] period_ns: 200000, duty_ns: 100000

diff (added alternative calculation without additional variable) :

diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c
index 1cc2f68..5aa6c4f 100644
--- a/drivers/pwm/pwm-mediatek.c
+++ b/drivers/pwm/pwm-mediatek.c
@@ -121,13 +121,18 @@ static int mtk_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
        struct mtk_pwm_chip *pc = to_mtk_pwm_chip(chip);
        struct clk *clk = pc->clks[MTK_CLK_PWM1 + pwm->hwpwm];
        u32 resolution, clkdiv = 0;
+       ulong clock;
        int ret;
 
        ret = mtk_pwm_clk_enable(chip, pwm);
        if (ret < 0)
                return ret;
 
-       resolution = NSEC_PER_SEC / clk_get_rate(clk);
+       clock=clk_get_rate(clk) / 4;
+       printk(KERN_NOTICE "[mtk_pwm_config] clock: %lu, clockrate: %lu",clock,clk_get_rate(clk));
+
+       //resolution = NSEC_PER_SEC / ( clk_get_rate(clk) / 4 );
+       resolution = NSEC_PER_SEC / clock;
 
        while (period_ns / resolution > 8191) {
                resolution *= 2;

[20:43] root@bpi-r2:~# echo 100000 >/sys/class/pwm/pwmchip0/pwm3/period
[20:45] root@bpi-r2:~# echo 50000 >/sys/class/pwm/pwmchip0/pwm3/duty_cycle

is 9.55kHz

[20:45] root@bpi-r2:~# echo 1000000 >/sys/class/pwm/pwmchip0/pwm3/period
[20:46] root@bpi-r2:~# echo 500000 >/sys/class/pwm/pwmchip0/pwm3/duty_cycle

is 955 Hz

[20:47] root@bpi-r2:~# echo 10000000 >/sys/class/pwm/pwmchip0/pwm3/period
[20:50] root@bpi-r2:~# echo 5000000 >/sys/class/pwm/pwmchip0/pwm3/duty_cycle

95.5 Hz

so the clock(-divider) is a bit inaccurately…can you confirm, that these values are correct depending on Hardware-spec:

clock: 68250000, clockrate: 273000000

(Frank W.) #50

Seems this is related: https://patchwork.kernel.org/patch/10250319/ + https://patchwork.kernel.org/patch/10250321/


(dorabmon) #51

4-times problem seems it is being solved

~5% inaccuracy you said I thought that is another problem


(Frank W.) #52

reverted my patch and applied the official from sean wang and can confirm it works the same way as my test:

echo 3 >/sys/class/pwm/pwmchip0/export
echo 200000 >/sys/class/pwm/pwmchip0/pwm3/period
echo 100000 >/sys/class/pwm/pwmchip0/pwm3/duty_cycle 
echo 1 >/sys/class/pwm/pwmchip0/pwm3/enable 

4,78kHz on Oscilloscope

added Info also to my wiki


(dorabmon) #53

good news. sean wang already posted another patch for the inaccuracy problem similar to this one.

https://patchwork.kernel.org/patch/10253633/


(Frank W.) #54

ok, for this patch i need a bit more time because this patch (and depending) is not compatible with my codebase. maybe it’s done for 4.16

tried to merge the new changes into my version of pwm-mediatek.c (other pwm45-fix than refererred by sean): pwm_fwu.patch (2,0 KB)

for pwm3 it works, frequency is exactly 5kHz…where are the pwm 1, 4 and 5 on the bpi-r2?


(dorabmon) #55

The solution should be workable for all PWMs.

pwm4 can be found on gpio header.

pwm1 is routed to lcm display

and for pwm5, it seems to be used to control FAN (cn12).

I think it is easier to test pwm4 at first than test1 and pwm5.