GPIO Python or shell

Please refer to below script and then run commands source mt_gpio.sh

mt_gpio_mode 200 0
mt_gpio_dir 200 in
mt_gpio_value 200 | echo $?

mt_gpio.sh

SYS_FILE=/sys/devices/platform/1000b000.pinctrl/mt_gpio

mt_gpio_mode()
{
   pin=$1
   mode=$2
  
   if [ ! -f ${SYS_FILE} ]; then
       exit 1
   fi

   echo "mode $pin $mode" > ${SYS_FILE}

   return 0   
}

mt_gpio_dir()
{
   pin=$1
   dir=$2
 
   if [ "x${dir}" == "xout" ]; then
       dir_val=1
   else
       dir_val=0
   fi
 
   if [ ! -f ${SYS_FILE} ]; then
       exit 1
   fi

   echo "dir $pin $dir_val" > ${SYS_FILE}

   return 0   
}

mt_gpio_out()
{
   pin=$1
   out=$2
 
   if [ ! -f ${SYS_FILE} ]; then
       exit 1
   fi

   echo "out $pin $out" > ${SYS_FILE}

   return 0   
}

mt_gpio_in()
{
   pin=$1
 
   if [ ! -f ${SYS_FILE} ]; then
       exit 1
   fi

   echo "start $1" > ${SYS_FILE}
   result=`cat ${SYS_FILE} | grep "$1"`

   if [ "x${result}" == "x" ]; then
       echo "can't get $pin status"
       exit 2
   fi
   echo ${result}
   pin_val=`echo ${result} | awk -F ' |-' '{print $5}'`
   if [ ${pin_val} == "0" ] ; then
       return 0
   else
       return 1
   fi
  
   return 0

}

I’ve checked the driver of PWM module, it will NOT work for PWM 4 and PWM5 controller, PWM 1/2/3 should be working fine.

I think you want to use PWM4, so the following patch is required.

1 Like

CON1-P40 GPIO49 or GPIO200?

./mt_gpio.sh mt_gpio_value 49 | echo $?
0
./mt_gpio.sh mt_gpio_value 200 | echo $?
0

But button pressed.

How looks your circuit (high active vs. Low active)?

what do you mean high active vs low active?

these are the common circuits for GPIO (out/in)

bpi-r2 this my scheme

you have no defined state if buttons is not pressed and a near-ground if pressed, please correct it for having clear 0 and 1 levels, see my posting

i assume you will do low-active (gnd on gpio if button is pressed), so use the 3rd image in the picture above (gpio between resistor [can be 1k, connected to 3v3]) and button (connected to gnd)

included PWM with the patch for 4+5 in my 4.14 github, now the question: how to define pwm-signal (4.4.x and 4.14.x)?

Hi Ace Space,

Looks like the ciruit is incorrect. Below is my suggesstion.

image

Also, there is internal pullup and pulldown resister internally for a few pins, you may need them, please use command “pullsel 0/1” to enable it.

Pullup needed if active low- circuit without vcc connected. There is no need for that.

Back to pwm…i’ve found only pwm2+3…where are the others (40pin gpio header)?

Can you explain (via picture) whats the difference between duty-cycle and period. I had assumed that 1khz was a period of 1000…duty cycle i thought is the behaviour between high and low parts inside the period (by default 50:50 in rectangular signal)

a figure explains concept for duty cycle

image

so 50%:100% :wink:

so 1kHz should be period of 1000 (if defined 1/Hz) and duty cycle is 0.5 (if high/low is 50:50)

that why i don’t understand the values above (200000 as period and 100000 as duty_cycle)…there duty cycle seems to be not the relationship (it’s the absolute value)…and the values are not 1/Hz

how to do it with 4.14 (debugfs)? and where are pwm 1,4 and 5?

4.14 has to follow official document as you can see in the followin link https://www.kernel.org/doc/Documentation/pwm.txt

and about duty_cycle, period you’re confused about also being defined here, they all are absolute value

period The total period of the PWM signal (read/write). Value is in nanoseconds and is the sum of the active and inactive time of the PWM.

duty_cycle The active time of the PWM signal (read/write). Value is in nanoseconds and must be less than the period.

the pwm kernel exports always in starting at 1. but schematic always starts at 0. you must be aware more about this.

pwm3 is then pwm#4 (if starting at 1) regarding to garys table there are pwm0-pwm4 where pwm3 is gpio 206 (pin 7)

So i’m searching pwm0-1 and pwm4…

pwm2 is gpio205/pin15

Thanks, it works on GPIO 126 or any other than GPIO 200 (PIN 40)

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:

3 Likes

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? pwm-5khz-1khz

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

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?

1 Like

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