Post Go back to editing

Using the AD4130-8 chip, the read conversion result is abnormal and the CRC check fails

Category: Software
Product Number: AD4130-8
Software Version: V1.0

Hi:

When using AD4130-8 chip, software code reference: no-OS/drivers/afe/ad413x;


1. At present, the device ID can be read correctly through SPI, and other values can be written into other registers, and then the read out matches the written value, but the read ADC conversion value is abnormal.


2. After CRC verification is enabled, the if (buf[data_size]! = crc) In the judgment statement, the CRC value does not match the 0x07 register, and the check fails.

/***************************************************************************//**
 * GD32F303芯片AD413X初始化.
*******************************************************************************/
static int32_t ad413x_arg_init(struct ad413x_preset* preset, struct ad413x_channel* ch)
{
    int32_t ret, i;
    uint32_t reg_data;

    no_os_crc8_populate_msb(ad413x_crc8, AD413X_CRC8_POLY);
    
    // Device Settings
    ret = ad413x_spi_do_soft_reset();
    if (ret)
    {
        goto err_spi;
    }

    // Reset POR([4]) flag
    ret = ad413x_reg_read(AD413X_REG_STATUS, &reg_data);
    if (ret)
    {
        goto err_spi;
    }
#ifdef _MYDEBUG
    printf("ad413x_arg_init: POR Flag Reg = 0x%x\r\n", reg_data & 0x10);
#endif
    
    // Change SPI to 4 wire
    ret = ad413x_reg_write_msk(AD413X_REG_ADC_CTRL, AD413X_ADC_CSB_EN, AD413X_ADC_CSB_EN);      // ADC Control Register[9]
    if (ret)
    {
        goto err_spi;
    }
    
#ifdef _MYDEBUG
    ret = ad413x_reg_write_msk(AD413X_REG_ADC_CTRL, AD413X_ADC_DATA_STATUS, AD413X_ADC_DATA_STATUS);    
#endif
    
    // Read Device ID
    ret = ad413x_reg_read(AD413X_REG_ID, &reg_data);
    if (ret)
    {
        printf("Device Communication Exception!\r\n");
        goto err_spi;
    }
    
    if (reg_data != AD4130_8)
    {
        printf("Get AD413x  Device ID failure!\r\n");
        goto err_spi;
    }
    else
    {
        printf("Get AD413x  Device ID Successfully!  ");
        printf("Device ID = 0x%02x\r\n", reg_data);
    }
    
    // set adc mode
    ret = ad413x_set_adc_mode(AD413X_SINGLE_CONV_MODE);
    if (ret)
    {
        goto err_spi;
    }
    // 设置AD413X CRC错误寄存器
    if (ad413x_spi_crc_en)
    {   
        // Error Enable Register[2]
        ret = ad413x_reg_write_msk(AD413X_REG_ERROR_EN, AD413X_SPI_CRC_ERR_EN, AD413X_SPI_CRC_ERR_EN);
        if (ret)
        {
            goto err_spi;
        }
    }
    
    // 预先配置并保存在dev中
    for (i = 0; i < 8; i++)
    {
        ret = ad413x_preset_store(preset[i], (enum ad413x_preset_nb)i);// 需要修正
        if (ret)
        {
            goto err_spi;
        }
    }
    
    // Channel setup
    for (i = 0; i < 16; i++) 
    {
        ret = ad413x_set_ch_preset(i, ch[i].preset);
        if (ret)
            goto err_spi;
        
        ret = ad413x_reg_write_msk(AD413X_REG_CHN(i), AD413X_AINP_M(ch[i].ain_p), AD413X_AINP_M(0xFF));
        if (ret)
            goto err_spi;
        // 
        ret = ad413x_reg_write_msk(AD413X_REG_CHN(i), AD413X_AINM_M(ch[i].ain_m), AD413X_AINM_M(0xFF));
        if (ret)
            goto err_spi;
        // 通道m的励磁电流 [0:1] 选择
        ret = ad413x_ch_exc_input(i, ch[i].iout0_exc_input, ch[i].iout1_exc_input);
        if (ret)
            goto err_spi;

        ret = ad413x_pdsw_en(i, ch[i].pdsw_en);
        if (ret)
            goto err_spi;

        ret = ad413x_ch_en(i, ch[i].enable);
        if (ret)
            goto err_spi;
    }
    
    ret = ad413x_set_int_ref(AD413X_INTREF_2_5V);   //不使能内部引用
    if (ret)
        goto err_spi;

    ret = ad413x_adc_bipolar(0);        // 直接单极编码输出,不输出负电压的
    if (ret)
        goto err_spi;

    ret = ad413x_set_v_bias(0x0000);    // 全部不使能VBIAS输入/输出
    if (ret)
        goto err_spi;

    ret = ad413x_set_standby_ctrl();    // 在待机模式下的配置,全部禁用
    if (ret)
        goto err_spi;

    ret = ad413x_set_mclk(AD413X_INT_76_8_KHZ_OUT_OFF);
    if (ret)
        goto err_spi;

    ret = ad413x_data_stat_en(ad413x_data_stat);        // 禁用DATA_STATUS字段
    if (ret)
        goto err_spi;

    printf("AD413X Successfully initialized\r\n");
    return 0;

err_spi:
    printf("AD413X initialization ERROR (%d)\n", ret);
    return ret;
}
/***************************************************************************//**
 * 外部API接口.
*******************************************************************************/
void AD413X_Start_Init(void)
{
    int x;
    struct ad413x_preset preset[8];
    struct ad413x_channel ch[16];
    
    for (x = 0; x < 8; x++)
    {
        preset[x].gain = AD413X_GAIN_1;                 // 不使用增益
        preset[x].ref_sel = AD413X_REFIN1;              // 
        preset[x].ref_buf.ref_buf_p_en = 1;
        preset[x].ref_buf.ref_buf_m_en = 1;
        preset[x].s_time = AD413X_32_MCLK;              // 使用默认最小值
        preset[x].iout0_exc_current = AD413X_EXC_OFF;   //不使用励磁电流
        preset[x].iout1_exc_current = AD413X_EXC_OFF;
        preset[x].filter = AD413X_SYNC3_STANDALONE;     // 使用AD413X_SYNC3_STANDALONE
    }
   
    ch[0].preset = AD413X_PRESET_0;
    ch[0].ain_p = AD413X_AIN0;
    ch[0].ain_m = AD413X_DGND;
    ch[0].iout0_exc_input = AD413X_AIN0;        // 励磁电流0的输入选择,这里默认到AIN0
    ch[0].iout1_exc_input = AD413X_AIN0;        // 励磁电流1的输入选择,这里默认到AIN0
    ch[0].pdsw_en = 0;                          // 不使用pdsw短接接AVSS引脚
    ch[0].enable = 1;                           // 通道m的使能位。
    
    ch[1].preset = AD413X_PRESET_0;
    ch[1].ain_p = AD413X_AIN1;
    ch[1].ain_m = AD413X_DGND;
    ch[1].iout0_exc_input = AD413X_AIN1;    // 励磁电流0的输入选择,这里默认到AIN0
    ch[1].iout1_exc_input = AD413X_AIN1;    // 励磁电流1的输入选择,这里默认到AIN0
    ch[1].pdsw_en = 0;                      // 不使用psw短接接AVSS引脚
    ch[1].enable = 1;                       // 通道m的使能位。

    ch[2].preset = AD413X_PRESET_0;
    ch[2].ain_p = AD413X_AIN2;
    ch[2].ain_m = AD413X_DGND;
    ch[2].iout0_exc_input = AD413X_AIN2;    // 励磁电流0的输入选择,这里默认到AIN0
    ch[2].iout1_exc_input = AD413X_AIN2;    // 励磁电流1的输入选择,这里默认到AIN0
    ch[2].pdsw_en = 0;                      // 不使用psw短接接AVSS引脚
    ch[2].enable = 1;                       // 通道m的使能位。
    
    ch[3].preset = AD413X_PRESET_0;
    ch[3].ain_p = AD413X_AIN3;
    ch[3].ain_m = AD413X_DGND;
    ch[3].iout0_exc_input = AD413X_AIN3;    // 励磁电流0的输入选择,这里默认到AIN0
    ch[3].iout1_exc_input = AD413X_AIN3;    // 励磁电流1的输入选择,这里默认到AIN0
    ch[3].pdsw_en = 0;                      // 不使用psw短接接AVSS引脚
    ch[3].enable = 1;                       // 通道m的使能位。
    
    ad413x_spi_crc_en = 1;
    ad413x_data_stat = 0;
    ad413x_arg_init(preset, ch);
}

Thread Notes