全志芯片如何提高GPIO触发中断精度?
-
问题背景
在使用 GPIO 中断处理外部信号,配置了上升沿和下降沿触发,发现gpio拉低拉高相差50us的时候,处理不过来,测试的情况看能处理的最小的精度在100us。此时需要提高触发中断的精度。
那么,在全志的芯片平台上,怎么样操作可以提高GPIO的触发中断精度呢?
- 存在问题
配置上升沿、下降沿触发,外部信号周期小于100us的,无法有效进入上升沿中断或下降沿中断。当外部信号周期提高,信号的上升沿和下降沿都能有效触发中断。
- 问题分析
关于这个中断无法及时响应的问题,主要是由于中断采样导致的。GPIO中断的信号检测有效时间为3个采样周期,默认GPIO采样频率为32K(1/32K * 3 = 94us),所以没有办法响应低于95us的一个中断信号。如果需要缩短采样时间间隔,可以将gpio的中断时钟从32k提高到24M。
- 根本原因
出现高频率中断(达到或超过10K频次)没有识别,可以确认GPIO的中断时钟是否配置为32k,可以将其配置为24M后再进行相应的中断测试。
- 解决办法
上面已经介绍到,通过将GPIO的中断时钟从32K切换到24M可提高中断采样的精度。
各平台补丁如下:diff --git a/arch/<arm/arm64>/boot/dts/sunxi/<sunXXiwYYp1>-pinctrl.dtsi b/arch/<arm/arm64>/boot/dts/sunxi/<sunXXiwYYp1>-pinctrl.dtsi index 0d0ab13552a8..b61dc4131092 100644 --- a/arch/<arm/arm64>/boot/dts/sunxi/<sunXXiwYYp1>-pinctrl.dtsi +++ b/arch/<arm/arm64>/boot/dts/sunxi/<sunXXiwYYp1>-pinctrl.dtsi @@ -16,7 +16,7 @@ #interrupt-cells = <3>; #size-cells = <0>; #gpio-cells = <6>; - input-debounce = <0>; + input-debounce = <100>; s_rsb0_pins_a: s_rsb0@0 { allwinner,pins = "PL0", "PL1";
通过在 dts 修改 input-debounce 参数影响 GPIO 中断采样时钟,它的含义如下:
/* * if debounce > 1, freq = (1000000 + (debounce/2)) / debounce * else freq = (1000000 - (debounce/2)) / debounce */ debounce_freq = DIV_ROUND_CLOSEST(USEC_PER_SEC, debounce);
上述 debounce 的值就是 input-debounce 的值,所以可以通过 dts 的 input-debounce 修改GPIO中断采样时钟频率。
中断采样时钟频率最高是24M,默认是 32k。当设置的采样时钟高于 24M 时,将会用最高24M时钟,内核启动log将会可以看到not support set rate %ld, use max rate24000000;
当设置的采样时钟处于32k与24M之间,内核启动log将会可以看到use hosc , set rate XXX;
当设置的采样时钟低于32k,内核启动log将会看到use default, set min rate 32000;
另外需要注意的是,上面的分频设置,不能无限的分频,寄存器中对24M的分频为2^N,N的取值只能3bit,也就是0-7,所有,最大的分频系数是128。
-
-
这个问题之前也遇到过。就普通的按键,有时候会失灵。修改采样时钟为24m就没问题了。配置的上升沿和下降沿触发,难道需要捕获到上升沿和下降沿才会触发中断吗?
-
此回复已被删除! -
@xiaowenge 在 全志芯片如何提高GPIO触发中断精度? 中说:
问题背景
在使用 GPIO 中断处理外部信号,配置了上升沿和下降沿触发,发现gpio拉低拉高相差50us的时候,处理不过来,测试的情况看能处理的最小的精度在100us。此时需要提高触发中断的精度。
那么,在全志的芯片平台上,怎么样操作可以提高GPIO的触发中断精度呢?
- 存在问题
配置上升沿、下降沿触发,外部信号周期小于100us的,无法有效进入上升沿中断或下降沿中断。当外部信号周期提高,信号的上升沿和下降沿都能有效触发中断。
- 问题分析
关于这个中断无法及时响应的问题,主要是由于中断采样导致的。GPIO中断的信号检测有效时间为3个采样周期,默认GPIO采样频率为32K(1/32K * 3 = 94us),所以没有办法响应低于95us的一个中断信号。如果需要缩短采样时间间隔,可以将gpio的中断时钟从32k提高到24M。
- 根本原因
出现高频率中断(达到或超过10K频次)没有识别,可以确认GPIO的中断时钟是否配置为32k,可以将其配置为24M后再进行相应的中断测试。
- 解决办法
上面已经介绍到,通过将GPIO的中断时钟从32K切换到24M可提高中断采样的精度。
各平台补丁如下:diff --git a/arch/<arm/arm64>/boot/dts/sunxi/<sunXXiwYYp1>-pinctrl.dtsi b/arch/<arm/arm64>/boot/dts/sunxi/<sunXXiwYYp1>-pinctrl.dtsi index 0d0ab13552a8..b61dc4131092 100644 --- a/arch/<arm/arm64>/boot/dts/sunxi/<sunXXiwYYp1>-pinctrl.dtsi +++ b/arch/<arm/arm64>/boot/dts/sunxi/<sunXXiwYYp1>-pinctrl.dtsi @@ -16,7 +16,7 @@ #interrupt-cells = <3>; #size-cells = <0>; #gpio-cells = <6>; - input-debounce = <0>; + input-debounce = <100>; s_rsb0_pins_a: s_rsb0@0 { allwinner,pins = "PL0", "PL1";
通过在 dts 修改 input-debounce 参数影响 GPIO 中断采样时钟,它的含义如下:
/* * if debounce > 1, freq = (1000000 + (debounce/2)) / debounce * else freq = (1000000 - (debounce/2)) / debounce */ debounce_freq = DIV_ROUND_CLOSEST(USEC_PER_SEC, debounce);
上述 debounce 的值就是 input-debounce 的值,所以可以通过 dts 的 input-debounce 修改GPIO中断采样时钟频率。
中断采样时钟频率最高是24M,默认是 32k。当设置的采样时钟高于 24M 时,将会用最高24M时钟,内核启动log将会可以看到not support set rate %ld, use max rate24000000;
当设置的采样时钟处于32k与24M之间,内核启动log将会可以看到use hosc , set rate XXX;
当设置的采样时钟低于32k,内核启动log将会看到use default, set min rate 32000;
另外需要注意的是,上面的分频设置,不能无限的分频,寄存器中对24M的分频为2^N,N的取值只能3bit,也就是0-7,所有,最大的分频系数是128。
大佬,没有sun8iw20p1-pinctrl.dtsi的话,得怎么修改采样时钟频率呀?
Copyright © 2024 深圳全志在线有限公司 粤ICP备2021084185号 粤公网安备44030502007680号