Adc_DebugSop
REVISION HISTORY¶
Revision No. | Description |
Date |
---|---|---|
1.0 | 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采样不准确¶
-
检查引脚是否处于GPIO mode,详见
Gpio_DebugSop
中的"获取GPIO使能状态"部分 -
每次采样前操作GPIO,以此作为触发源,抓取adc采样时机,判断该采样点下输入电压的状态;ADC的采样间隔较短,需要等电压稳定后采样;另外输入电压应选用进LDO处理的输入源,如果是DCDC电源可能有较大纹波
-
输入电流偏低的时候,在多次采样时可能会出现较大的偏差值,应保证输入电流足够
-
Riscv debug port 用的是PAD_UART0_RX/TX,与5M ADC的2channel在同一个power domain,且layout上出ball与走线相邻,会干扰到ADC;在PCUPID平台Riscv 环境下,串口敲命令可能会看到ADCMP输入有毛刺,频率与敲命令的动作相同,此时需要换到ARM debug port避免干扰