Adc_DebugSop

REVISION HISTORY

Revision No.
Description
Date
1.0
  • Initial release
  • 12/13/2024

    问题一:ADC采样值错误

    1. ADC采样值错误的Debug流程图

    2. ADC采样值错误的Debug流程说明

    2.1 硬件问题

    检查到adc采样值错误时,可操作寄存器或使用GPIO指令将对应PIN脚设为GPIO并拉高拉低(请注意某些PIN脚GPIO功能优先级并不是最高的,此时需要先清除更高优先级),如果实际输出电平没有变化,则可判断为硬件问题,可按照如下顺序排查:

    2.1.1 HW-A 检查电阻

    查看原理图的对应PIN脚是否有电阻漏焊,漏焊则需要补焊电阻,否则PIN脚不通

    2.1.2 HW-B 检查焊接情况

    如果更换Board后,GPIO是可以拉高拉低的,那么可能是芯片虚焊,需要rework

    2.1.3 HW-C 请求协助

    联系硬件同事协助排查并重焊芯片

    2.1.4 HW-D 问题上报

    如果更换Board后,GPIO仍然无法拉高拉低,请联系FAE上报问题

    2.2 软件问题

    2.2.1 步骤SW-A 检查ADC初始化情况和使用方法

    Linux端检查sysfs下SAR ADCLP和ADCMP的接口是否存在(详见ADCLP使用参考和ADCMP使用参考的7.4.1节),若不存在,说明ip没有正常初始化

    如若未完成初始化,自然无法获取数据,请检查config及DTS配置是否有加载相应adc驱动

    Linux config:

    Device Drivers --->
        SStar SoC platform drivers --->
            <*> Sstar ADCMP driver
            <*> Sstar ADCLP driver
    

    Linux DTS:

    adclp0: adclp0@1f002800 {
        compatible = "sstar,adclp";
        reg = <0x0 0x1F002800 0x0 0x200>;
        ......
        status = "ok";    //ok:初始化adclp
    };
    .....
    adcmp0: adcmp@1f00ac00 {
        compatible = "sstar,adcmp";
        reg = <0x0 0x1F00AC00 0x0 0x200>, <0x0 0x1F00AE00 0x0 0x200>, <0x0 0x1F003C00 0x0 0x200>,
                <0x0 0x1F204600 0x0 0x200>, <0x0 0x1F203E00 0x0 0x200>;
        ......
        status = "ok";    //ok:初始化adcmp
    };
    

    Riscv端请检查pcupid-default.sys中ADC配置是否正确(详见RISCV_ADCLP使用参考和RISCV_ADCMP使用参考的6.3节),注意ADCMP使能dma功能时需要同时把dma_en_u8和interrupts_en_u8配置为1

    <adclp4>
        [reg_u32] 0x2002800;
        [interrupts_u32] INT_PM_IRQ_SAR_KP;
        [camclk_u16] CAMCLK_sar;
        [interrupts_en_u8] 1;
        [ref_vol_u32] 1800;
        [upper_bound_u16] 0x3FF;
        [lower_bound_u16] 0;
        [status_u8] 1; /*1, 使能ADCLP channel4*/
    
    <adcmp0>
        [reg_u32] 0x200AC00, 0x200AE00, 0x2003C00, 0x2204600, 0x2203E00;
        [interrupts_u32] INT_PM_FIQ_ADCMP;
        [camclk_u16] CAMCLK_pm_pwm_adc;
        [interrupts_en_u8] 0;
        [dma_en_u8] 0;
        [dma_count_u32] 50;
        [clk_level_u8] 0;
        [ref_vol_u32] 1800;
        [regular_method_u8] 0;
        [inject_method_u8] 0;
        [regular_ch_u8] 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11;
        [inject_ch_u8] 12, 13, 14, 15, 16, 17, 18, 19, 20, 21;
        [upper_bound_u16] 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
                        0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF;
        [lower_bound_u16] 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
        [status_u8] 1; /*1, 使能ADCMP group0*/
    
    <adcmp1>
        [reg_u32] 0x2203600, 0x2203A00, 0x2200E00, 0x2204600, 0x2203E00;
        [interrupts_u32] INT_FIQ_ADCMP;
        [camclk_u16] CAMCLK_pwm_adc;
        [interrupts_en_u8] 0;
        [dma_en_u8] 0;
        [dma_count_u32] 50;
        [clk_level_u8] 3;
        [ref_vol_u32] 1800;
        [regular_method_u8] 0;
        [inject_method_u8] 0;
        [regular_ch_u8] 0, 1;
        [upper_bound_u16] 0xFFFF, 0xFFFF;
        [lower_bound_u16] 0, 0;
        [status_u8] 1; /*1, 使能ADCMP group1*/
    

    检查同一组ADCMP或者同一通道ADCLP是否同时在LINUX和RISCV端配置,如果同时配置需要在不用的那端拿掉配置

    检查ADC使用方法是否正确,比较常见的问题是触发方式问题。

    ADCMP设置触发方法为pwm触发(0~11)时,没有事先设定对应pwm的pwm dead time,就不会触发导致没有数据;

    LINUX端ADC的具体使用方法详见使用文档 ADCLP使用参考和ADCMP使用参考,RISCV端ADC的具体使用方法详见使用文档 RISCV_ADCLP使用参考和RISCV_ADCMP使用参考

    2.2.2 步骤SW-B 检查PADMUX

    检查PADMUX是否存在冲突,详见 Gpio_DebugSop中的PADMUX冲突检查内容,如果有同时使用ARM和RISCV,需要两端一起检查

    2.2.3 步骤SW-C 检查CLK配置

    检查ADC CLK是否正常开启,各ADC clock检查寄存器如下表,读取指令/customer/riu_r 0x1038 0x38,对应bit为0表示clock正常开启,为1表示clock关闭

    ADC BANK OFFSET BIT
    ADCMP channel0-17 1038 38 bit0
    ADCMP channel18-19 E 24 bit0
    ADCLP E 22 bit5

    clock被关需要检查pcupid-clks.dtsi的时钟配置,配置auto_enable = <1>表示系统起来之后clock常开,RISCV和LINUX需要同时使用同一组ADCMP时需要如此配置;ignore = <1>表示clock由模块自行开关,当只有RISCV使用ADC时把LINUX端配置拿掉按如此配置

    2.2.4 步骤SW-D 检查基准电压

    检查ADC输入的外部电压和设置的基准电压是否匹配,不匹配需要让外部电压在基准电压范围内

    2.2.5 步骤SW-E 请求协助

    上述步骤均检查OK,请 <font color=blue>提供ADC相关LOG以及ADC配置信息 </font>,联系FAE协助debug

    3. 常见问题说明

    3.1 ADCMP采样元件电压变化较慢导致采样值不对

    常见于红外测距元件,这些元件的电平下降时间可能长于adcmp的采样时间,需要调整采样时间点,可以尝试以下两种方案:

    • 将PWM设为极性1,将下降沿较慢的器件通道加入inject mode,而其余无特殊要求的加入regular mode,可保证准确采样(注意inject使用single触发,如果用continue会导致regular的通道无法采样)。

    • 将PWM设为极性0,将下降沿较慢的器件通道加入inject mode,同时设定inject delay count (delay时长=pwm source clock * count),将采样时机延后。

    3.2 ADCMP采样结果以256的倍数变化

    当某一ADC通道对应的PIN脚输入电压大于参考电压时,前一个通道的采样会受到干扰,采样结果只能是256的倍数

    adcmp0: adcmp@1f00ac00 {
        compatible = "sstar,adcmp";
        reg = <0x0 0x1F00AC00 0x0 0x200>, <0x0 0x1F00AE00 0x0 0x200>, <0x0 0x1F003C00 0x0 0x200>, <0x0 0x1F204600 0x0 0x200>, <0x0 0x1F203E00 0x0 0x200>;
        clocks = <&CLK_pm_pwm_adc>;
        interrupt-parent = <&sstar_pm_main_intc>;
        interrupts = <INT_PMSLEEP_FIQ_ADC>;
        interrupts-enable;
        group = <0>;
        //dma-enable;
        //dma-count = <50>;
        ref-voltage = <1800>;//1.5V 1.8V
        //0:24M 1:12M
        clk-select = <0>;
        regular-method = <0>;
        inject-method = <0>;
        regular-ch = <0 1 2 8 3 9 4 5 6 7 10 11 12 13 14 15 16 17 18 19 20 21>;
        upper-bound = <0xFFFF 0xFFFF 0xFFFF 0xFFFF 0xFFFF 0xFFFF 0xFFFF 0xFFFF 0xFFFF 0xFFFF 0xFFFF 0xFFFF 0xFFFF 0xFFFF 0xFFFF 0xFFFF 0xFFFF 0xFFFF 0xFFFF 0xFFFF 0xFFFF 0xFFFF>;
        lower-bound = <0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0>;
        status = "okay";
    };
    

    例如上述配置中,ref-voltage为1.8V,若通道8、通道9的输入电压大于1.8V,则通道2、通道3的采样结果会受到干扰,且只能是256的倍数。

    3.3 ADCMP采样不准确

    1. 检查引脚是否处于GPIO mode,详见 Gpio_DebugSop中的"获取GPIO使能状态"部分

    2. 每次采样前操作GPIO,以此作为触发源,抓取adc采样时机,判断该采样点下输入电压的状态;ADC的采样间隔较短,需要等电压稳定后采样;另外输入电压应选用进LDO处理的输入源,如果是DCDC电源可能有较大纹波

    3. 输入电流偏低的时候,在多次采样时可能会出现较大的偏差值,应保证输入电流足够

    4. Riscv debug port 用的是PAD_UART0_RX/TX,与5M ADC的2channel在同一个power domain,且layout上出ball与走线相邻,会干扰到ADC;在PCUPID平台Riscv 环境下,串口敲命令可能会看到ADCMP输入有毛刺,频率与敲命令的动作相同,此时需要换到ARM debug port避免干扰