[ADC]TI am4378 ADC采样设置问题(am335x类似)

这段时间在调试AM4378的ADC问题,发现采样到的数据和真实输入波形有所出入,比如输入是1ms的周期,50%占空比的信号,但是采样的数据描点总是偏差较大,数据如下

iio device number being used is 0
scan_size:2
read_size:40
ADC value:1821 1820 1819 1820 1820 864 8 0 0 0 0 1823 0 0 0 1835 
1816 1818 1825 1817 
ADC AVG Value: 1823
read_size:40
ADC value:1817 24 0 2 0 0 1841 1818 1820 1818 1818 1820 0 0 0 0 
1823 1819 1819 1818 
ADC AVG Value: 1821
read_size:40
ADC value:1818 1821 0 0 0 0 0 1824 1830 1819 1820 1818 1820 1817 
1819 1821 1816 97 5 0 
ADC AVG Value: 1822
read_size:40
ADC value:10 0 1855 1824 1820 1817 1822 1820 233 0 0 0 1819 2 0 0 
0 0 1830 1820 
ADC AVG Value: 1825
read_size:40
ADC value:1817 1832 1817 1819 6 0 0 0 0 1844 1821 1820 0 0 1821 
1820 1818 1822 1819 619 
ADC AVG Value: 1825
read_size:40
ADC value:0 0 0 0 0 1823 1820 1818 1818 1824 1822 0 1819 1818 
1816 16 0 2 0 0 

而DTS的设置如下

status = "okay"
adc {
    ti, adc-channels = <5, 6, 7>;
    ti, chan-step-opendelay = <0x0 0x0 0x0>;
    ti, chan-step-sampledelay = <0xff 0xff 0xff>;
    ti, chan-step-avg = <1 1 1>;
};

采样目标:采样20次,2个周期,也就是2ms, 数据点均匀分布。

问题:在20次基本保持两个周期的情况下,opendelay+sampledelay+other cycles并不符合ADC 24MHz clock的情况,且20次采样并未均匀分布。经过在TI社区咨询发现存在如下问题:

  • 如果不打算做采样平均,那么chan-step-avg不应该设置为1,而是0
  • ADC计算频率并不是24MHz,而是3MHz

-------------------------------------------------------分界线----------------------------------------------------------------

首先, 从Documentation/devicetree/bindings/input/touchscreen/ti-tsc-adc.txt中可以查到如下信息

  • opendelay maximum为0x3FFFF cycles
  • sampledelay maximum为0xFF cycles

其次, 从TI的数据手册可以看到如下信息,最快的一次采样,在Sampledelay=1, opendelay=0的情况下,为15cycles

在者,从驱动文件driver/mfd/ti_am335x_tscadc.c中可以看到如下代码段

tscadc->clk_div = clock_rate / ADC_CLK;
ADC_CLK = 3000000

tscadc->clk_div会被写入ADC的DIV分频寄存器,也就是说,clock_rate = 24MHz并不是ADC的真实clock, ADC_CLK才是,也就是3MHz 。

基于以上信息,我们就有如下计算:

1/3MHz = 333.33ns ADC clock period --> 333.33ns * 15 ADC clocks = 5us sample period --> 1 / 5us = 200ksps sampling rate

 也就说,最快的ADC采样频率是200ksps,而且是所有通道。也就说1个通道,则采样频率为200ksps; 如果2个通道,则采样频率为100ksps, 以此类推.......

关于chan-step-avg变量

在driver/iio/adc/ti_am335x_adc.c中有如下代码段, 可知AVG默认是0,且当chan-step-avg=0时,寄存器数据为0。 (根据代码段,这里当chan-step-avg=1, 好像写到寄存器的值也是0,不知为什么最终效果确实像做了2个数的平均)

if(adc_dev->step_avg[i])
  stepconfig = STEPCONFIG_AVG(ffs(adc_dev->step_avg[i]) - 1) | STEPCONFIG_FIFO1;
else
  stepconfig = STEPCONFIG_FIFO1;

和如下的Datasheet

所以基于上面的采样目标,有如下设置即可, 因为只采用channel6,(0x11D + 15cycles)*333ns=100us. 也就是2ms内完成20次采样。333ns由上面的ADC clock得出。

status = "okay"
adc {
    ti, adc-channels = <6>;
    ti, chan-step-opendelay = <0x11D>;
    ti, chan-step-sampledelay = <0x1>;
    ti, chan-step-avg = <0>;
};

 打印结果如下, 可以看出来已经比较均匀了。

ADC value:1 0 3679 3667 3657 3666 3658 17 0 0 0 0 3678 3664 3659 3674 3662 0 0 3 
ADC AVG Value: 3673
read_size:40
ADC value:0 6 3663 3662 3660 3658 3673 0 3 0 0 0 3661 3662 3666 3671 210 0 7 0 
ADC AVG Value: 3666
read_size:40
ADC value:0 3710 3671 3664 3656 3660 154 2 0 0 0 3694 3662 3658 3659 3659 10 0 0 8 
ADC AVG Value: 3676
read_size:40
ADC value:0 3674 3668 3662 3658 3660 7 0 0 5 0 3670 3658 3659 3667 3659 7 3 0 0 
ADC AVG Value: 3668
read_size:40
ADC value:0 3664 3658 3658 3674 3658 0 0 0 0 0 3669 3662 3656 3660 222 0 0 3 0 
ADC AVG Value: 3665
read_size:40
ADC value:3706 3662 3664 3673 3654 168 0 0 5 0 3699 3665 3660 3659 3660 11 5 0 7 5 
ADC AVG Value: 3679
read_size:40
ADC value:3671 3660 3657 3658 3660 19 0 8 0 5 3674 3672 3661 3658 3662 0 0 0 0 3 
ADC AVG Value: 3668
read_size:40
ADC value:3664 3671 3662 3658 3658 0 0 0 0 0 3664 3662 3660 3672 260 0 3 0 0 3718 
ADC AVG Value: 3669
read_size:40
ADC value:3660 3656 3671 3667 180 0 0 3 0 3717 3659 3658 3662 3654 14 0 3 7 0 3686 
原文地址:https://www.cnblogs.com/aaronLinux/p/7999274.html