This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AFE4960EVM: Issue with the decimation factor affecting timing

Part Number: AFE4960EVM

Tool/software:

Hi,

I'm encountering an issue with the decimation factor in my system. When the decimation factor is set to zero (which corresponds to a value of 2), the FIFO interrupt triggers correctly at 500 ms.

However, when I change the decimation factor to 1 (which corresponds to a value of 4), instead of firing at 1000 ms , the interrupt occurs at around 680 ms.  I've attached the RAC calculations and timing details for  reference. 

Is there any additional configuration required to ensure the correct timing with different decimation settings? Any insights would be greatly appreciated.

Thanks,

FIFO_CAL.pdf

  • Hi Dhivin,

    Please excuse the delay. Can you share export and share the register configuration you are using for the EVM?

    Regards,

    Ryan

  • Hi Ryan,

    Please find the attached files with the dual channel configuration functions.

    afe4960_drv.c
    #include "zephyr/kernel.h"
    #include "zephyr/drivers/gpio.h"
    #include "afe4960_drv.h"
    #include "ecg_test.h"
    
    uint32_t CONFIG_ECG1_MIX1_value = 0;
    uint32_t CONFIG_BIA_SW_MATRIX_STATIC_MIX1_value = 0;
    uint32_t CONFIG_PRPCT_MIX1_value = 0;
    uint32_t CONFIG_NUM_TS_MIX1_value = 0;
    uint32_t CONFIG_TS_1TO8_MIX1_value = 0;
    uint32_t CONFIG_TS_9TO16_MIX1_value =0;
    uint32_t CONFIG_CLK_CKT_MIX1_value = 0;
    uint32_t CONFIG_CLK_DIV_MIX1_value = 0;
    uint32_t CONFIG_ECG2_MIX1_value = 0;
    uint32_t CONFIG_ECG_CH2_value = 0;
    uint32_t CONFIG_MODE_SEL_value = 0;
    uint32_t ACT_CTRL_value = 0;
    uint32_t CTRL_PDN_value = 0;
    uint32_t CONTROL10_value = 0;
    uint32_t CONTROL4_value = 0;
    uint32_t RAC_CONTROL_value = 0;
    uint32_t CONTROL0_value = 0;
    uint32_t CONTROL9_value = 0;
    uint32_t CONFIG_BIA_RX_MIX1_value = 0;
    uint32_t CONTROL7_value = 0;
    uint32_t MASK_INT_REG_value = 0;
    uint32_t CONFIG_ELECTRODE_BIAS1_MIX1_value = 0;
    uint32_t CONFIG_ELECTRODE_BIAS2_MIX1_value = 0;
    uint32_t CONFIG_COMP_ANA_MIX1_value = 0;
    uint32_t CONFIG_PACE_DETECT_value = 0;
    uint32_t CONFIG_PACE_DIG_REG2_value = 0;
    uint32_t CONFIG_PACE_DIG_REG3_value = 0;
    uint32_t CONTROL19_value = 0;
    uint32_t CONFIG_PACE_DIG_REG1_value = 0;
    uint32_t CONFIG_BIA_PROC_MIX1_value = 0;
    uint32_t CONTROL25_value = 0;
    uint32_t CONTROL20_value = 0;
    
    /*For Selecting the single channel mode*/
    void AFE_single_channel(void) // TODO: singe changed
    {
        /*---Lead construction---*/
        CONFIG_ECG1_MIX1_value |= SW_ECG_INP_ECG | SW_ECG_INM_ECG << 4 | SW_RLD << 8;
        AFE_SetRegisterValue(CONFIG_ECG1_MIX1, CONFIG_ECG1_MIX1_value);
        CONFIG_BIA_SW_MATRIX_STATIC_MIX1_value |= SW_BIOZ_TXP << 3 | SW_BIOZ_TXM << 7 | SW_BIOZ_RXP_SINGLE << 8 | SW_BIOZ_RXM << 12;
        AFE_SetRegisterValue(CONFIG_BIA_SW_MATRIX_STATIC_MIX1, CONFIG_BIA_SW_MATRIX_STATIC_MIX1_value);
    
        /*---Signal Acquisition configuration---*/
    
        CONFIG_PRPCT_MIX1_value |= COUNT_RAC_SINGLE; // TODO:check last addition
        AFE_SetRegisterValue(CONFIG_PRPCT_MIX1, CONFIG_PRPCT_MIX1_value);
        CONFIG_NUM_TS_MIX1_value |= REG_NUM_TS_SINGLE << 3 | REG_NUM_ESAW << 9 | REG_NUM_BSAW << 15;
        AFE_SetRegisterValue(CONFIG_NUM_TS_MIX1, CONFIG_NUM_TS_MIX1_value);
        CONFIG_TS_1TO8_MIX1_value |= CONFIG_TS0; // check
        AFE_SetRegisterValue(CONFIG_TS_1TO8_MIX1, CONFIG_TS_1TO8_MIX1_value);
    
        /*---Clocking configuration---*/
        CONFIG_CLK_CKT_MIX1_value |= SEL2_CLK_TE << 1 | OSCL_DIS << 2 | EN_OSCL_SYNC << 4 | DIS_DYN_PDN_OSCH << 7 |
                                     SEL1_CLK_BIOZ << 8 | SEL2_CLK_BIOZ << 9 | EN_PLL << 10 | SEL2_CLK_RAC << 13 | DIV_TE_RAC_OUT_EN << 16;
        AFE_SetRegisterValue(CONFIG_CLK_CKT_MIX1, CONFIG_CLK_CKT_MIX1_value);
        CONFIG_CLK_DIV_MIX1_value |= DIV_OUT_BIOZ << 17;
        AFE_SetRegisterValue(CONFIG_CLK_DIV_MIX1, CONFIG_CLK_DIV_MIX1_value);
    
        /*---Signal chain configuration---*/
        CONFIG_ECG1_MIX1_value |= ECG_INA_GAIN << 17 | DIS_CHOP_INA1 << 21;
        AFE_SetRegisterValue(CONFIG_ECG1_MIX1, CONFIG_ECG1_MIX1_value);
        CONFIG_ECG2_MIX1_value |= EN_DEC_ECG << 9 | ECG_DEC_FACTOR << 10;
        AFE_SetRegisterValue(CONFIG_ECG2_MIX1, CONFIG_ECG2_MIX1_value);
        CONFIG_ECG_CH2_value |= EN_ECG2_SINGLE << 0 | SEL_IN_BIOZ_RX_SINGLE << 1 | EN_RLD_LOOP_ECG2 << 2 | RECONFIGURE_BIOZ_LPF_SINGLE << 3 | DIS_CHOP_INA2 << 4;
        AFE_SetRegisterValue(CONFIG_ECG_CH2, CONFIG_ECG_CH2_value);
        CONFIG_MODE_SEL_value |= ACQ_MODE_SEL | EN_BIOZ_TX << 18 | EN_BIOZ_RX << 20 | EN_ECG_RX << 23;
        AFE_SetRegisterValue(CONFIG_MODE_SEL, CONFIG_MODE_SEL_value);
        ACT_CTRL_value |= PDN_ECG_INA << 14 | PDN_ECG_RLD << 16 | PDN_ADC << 10 | PDN_OSCH << 8;
        AFE_SetRegisterValue(ACT_CTRL, ACT_CTRL_value);
        CTRL_PDN_value |= PDN_ILEAD << 0 | DIS_ACTIVE_BIOZ_TX << 4 | DIS_PD_REFSYS << 16 | DIS_PD_VCM << 19 | PDN_BG_IN_DEEP_SLEEP << 21;
        AFE_SetRegisterValue(CTRL_PDN, CTRL_PDN_value);
        CONTROL10_value |= DIS_BUF_PDN_ON_ADC << 8;
        AFE_SetRegisterValue(CONTROL10, CONTROL10_value);
        CONTROL4_value |= PDNAFE << 0;
        AFE_SetRegisterValue(CONTROL4, CONTROL4_value);
        CONTROL0_value |= FIFO_EN << 6;
        AFE_SetRegisterValue(CONTROL0, CONTROL0_value);
        CONTROL9_value |= REG_WM_FIFO << 6; // changed
        AFE_SetRegisterValue(CONTROL9, CONTROL9_value);
        CONFIG_BIA_RX_MIX1_value |= SEL_RHPF1_BIOZ_SINGLE << 3;
        AFE_SetRegisterValue(CONFIG_BIA_RX_MIX1, CONFIG_BIA_RX_MIX1_value);
    }
    /*---DC Lead Detection Configuration ---*/
    void AFE_DC_Lead_Config(void)
    {
        CONFIG_ELECTRODE_BIAS1_MIX1_value |= SW_RBIAS1_ECGP << 0 | SW_RBIAS1_LEAD_BIAS << 3 | POL_RBIAS1_LEAD_BIAS << 4 | SW_RBIAS2_ECGM << 5 | SW_RBIAS2_LEAD_BIAS << 8 | POL_RBIAS2_LEAD_BIAS << 9 | SW_RBIAS3_ECG1 << 10 | SW_RBIAS3_LEAD_BIAS << 13 | POL_RBIAS3_LEAD_BIAS << 14 | SW_RBIAS4_ECG2 << 15 | SW_RBIAS4_LEAD_BIAS << 18 | POL_RBIAS4_LEAD_BIAS << 19;
        AFE_SetRegisterValue(CONFIG_ELECTRODE_BIAS1_MIX1, CONFIG_ELECTRODE_BIAS1_MIX1_value);
        CONFIG_ELECTRODE_BIAS2_MIX1_value |= SEL_RBIAS_CH1 << 3 | SEL_RBIAS_CH2 << 7;
        AFE_SetRegisterValue(CONFIG_ELECTRODE_BIAS2_MIX1, CONFIG_ELECTRODE_BIAS2_MIX1_value);
        CONFIG_COMP_ANA_MIX1_value |= EN_COMP_ANA << 0 | LEAD_DET_THR_L << 2 | LEAD_DET_THR_H << 6 | LEAD_DET_MODULE_CLK_EN << 22 | LEAD_DET_WIDTH << 14;
        AFE_SetRegisterValue(CONFIG_COMP_ANA_MIX1, CONFIG_COMP_ANA_MIX1_value);
    }
    
    void AFE_int_config(void)
    {
        CONTROL9_value |= INT_MUX_ADC_RDY_1 << 4 | INT_MUX_GPIO2_2 << 19 | INT_MUX_ADC_RDY_2 << 16; // changed
        AFE_SetRegisterValue(CONTROL9, CONTROL9_value);
        CONTROL7_value |= EN_GPIO2_OUT << 19;
        AFE_SetRegisterValue(CONTROL7, CONTROL7_value);
        MASK_INT_REG_value |= MASK_DC_LEAD_DET << 0 | MASK_AC_LEAD_ON << 1 | MASK_AC_LEAD_OFF << 2 | MASK_ADC_FIFO_RDY << 3 | MASK_PACE_VALID_INT << 6 | MASK_DISABLE1 << 4 | MASK_DISABLE2 << 5; ////changed
        AFE_SetRegisterValue(MASK_INT_REG, MASK_INT_REG_value);
    }
    /*--- RAC configuration---*/
    void AFE_RAC_config(void)
    {
        /*Configure at last step of the initialization */
        RAC_CONTROL_value |= TIMER_ENABLE << 23 | RAC_COUNTER_ENABLE << 22;
        AFE_SetRegisterValue(RAC_CONTROL, RAC_CONTROL_value);
    }
    /* Initializes the communication with AFE and checks if the device is present.*/
    bool AFE_Init(void)
    {
        AFE_software_reset();
        AFE_dual_channel();
       // AFE_single_channel();
        AFE_DC_Lead_Config();
        AFE_int_config();
        AFE_RAC_config();
        return 0;
    }
    /*For Selecting the dual channel mode*/
    void AFE_dual_channel(void)
    {
        /*---Lead construction---*/
        CONFIG_ECG1_MIX1_value |= SW_ECG_INP_ECG | SW_ECG_INM_ECG << 4 | SW_RLD << 8 | ECG_INA_GAIN << 17 | DIS_CHOP_INA1 << 21;
        AFE_SetRegisterValue(CONFIG_ECG1_MIX1, CONFIG_ECG1_MIX1_value);
        CONFIG_BIA_SW_MATRIX_STATIC_MIX1_value |= SW_BIOZ_TXP << 3 | SW_BIOZ_TXM << 7 | SW_BIOZ_RXP_DUAL << 8 | SW_BIOZ_RXM << 12;
        AFE_SetRegisterValue(CONFIG_BIA_SW_MATRIX_STATIC_MIX1, CONFIG_BIA_SW_MATRIX_STATIC_MIX1_value);
    
        /*---Signal Acquisition configuration---*/
        CONFIG_PRPCT_MIX1_value |= COUNT_RAC_DUAL; // check
        AFE_SetRegisterValue(CONFIG_PRPCT_MIX1, CONFIG_PRPCT_MIX1_value);
        CONFIG_NUM_TS_MIX1_value |= REG_NUM_TS_DUAL | REG_NUM_ESAW << 9 | REG_NUM_BSAW << 15;
        AFE_SetRegisterValue(CONFIG_NUM_TS_MIX1, CONFIG_NUM_TS_MIX1_value);
        CONFIG_TS_1TO8_MIX1_value |= CONFIG_TS0 | CONFIG_TS1 << 3 | CONFIG_TS2 << 6 | CONFIG_TS3 << 9 ;
       // CONFIG_TS_1TO8_MIX1_value|=CONFIG_TS0|CONFIG_TS1_DUAL <<3;
        AFE_SetRegisterValue(CONFIG_TS_1TO8_MIX1, CONFIG_TS_1TO8_MIX1_value);
        // CONFIG_TS_9TO16_MIX1_value |= CONFIG_TS4 ;
        // AFE_SetRegisterValue(CONFIG_TS_9TO16_MIX1, CONFIG_TS_9TO16_MIX1_value);
        //*---Clocking configuration---*/
        CONFIG_CLK_CKT_MIX1_value |= SEL2_CLK_TE << 1 | OSCL_DIS << 2 | EN_OSCL_SYNC << 4 | DIS_DYN_PDN_OSCH << 7 |
                                     SEL1_CLK_BIOZ << 8 | SEL2_CLK_BIOZ << 9 | EN_PLL << 10 | SEL2_CLK_RAC << 13 | DIV_TE_RAC_OUT_EN << 16;
        AFE_SetRegisterValue(CONFIG_CLK_CKT_MIX1, CONFIG_CLK_CKT_MIX1_value);
        // DIV_OUT_BIOZ			= 0;CONFIG_CLK_DIV_MIX1_value|=DIV_OUT_BIOZ<<17;
        AFE_SetRegisterValue(CONFIG_CLK_DIV_MIX1, CONFIG_CLK_DIV_MIX1_value);
        CONFIG_ECG2_MIX1_value |= EN_DEC_ECG << 9 | ECG_DEC_FACTOR << 10;
        AFE_SetRegisterValue(CONFIG_ECG2_MIX1, CONFIG_ECG2_MIX1_value);
        CONFIG_ECG_CH2_value |= EN_ECG2_DUAL << 0 | SEL_IN_BIOZ_RX_DUAL << 1 | EN_RLD_LOOP_ECG2 << 2 | RECONFIGURE_BIOZ_LPF_DUAL << 3 | DIS_CHOP_INA2 << 4;
        AFE_SetRegisterValue(CONFIG_ECG_CH2, CONFIG_ECG_CH2_value);
        CONFIG_MODE_SEL_value |= ACQ_MODE_SEL | EN_BIOZ_TX << 18 | EN_BIOZ_RX << 20 | EN_ECG_RX << 23;
        AFE_SetRegisterValue(CONFIG_MODE_SEL, CONFIG_MODE_SEL_value);
        ACT_CTRL_value |= PDN_ECG_INA << 14 | PDN_ECG_RLD << 16 | PDN_ADC << 10 | PDN_OSCH << 8;
        AFE_SetRegisterValue(ACT_CTRL, ACT_CTRL_value);
        CTRL_PDN_value |= PDN_ILEAD << 0 | DIS_ACTIVE_BIOZ_TX << 4 | DIS_PD_REFSYS << 16 | DIS_PD_VCM << 19 | PDN_BG_IN_DEEP_SLEEP << 21;
        AFE_SetRegisterValue(CTRL_PDN, CTRL_PDN_value);
        CONTROL10_value |= DIS_BUF_PDN_ON_ADC << 8;
        AFE_SetRegisterValue(CONTROL10, CONTROL10_value);
        CONTROL4_value |= PDNAFE << 0;
        AFE_SetRegisterValue(CONTROL4, CONTROL4_value);
        CONTROL0_value |= FIFO_EN << 6;
        AFE_SetRegisterValue(CONTROL0, CONTROL0_value);
        CONTROL9_value |= REG_WM_FIFO << 6; // changed
        AFE_SetRegisterValue(CONTROL9, CONTROL9_value);
        CONFIG_BIA_RX_MIX1_value |= SEL_CHPF1_BIOZ_DUAL << 1 | SEL_RHPF1_BIOZ_DUAL << 3 | BIOZ_INA_GAIN_DUAL << 9 | BIOZ_LPF_BW_DUAL << 11;
        AFE_SetRegisterValue(CONFIG_BIA_RX_MIX1, CONFIG_BIA_RX_MIX1_value);
        CONFIG_BIA_PROC_MIX1_value |= PROCESS_BSAW_DUAL << 2 | EN_DEC_BIOZ_DUAL << 4 | BIOZ_DEC_FACTOR_DUAL << 7;
        AFE_SetRegisterValue(CONFIG_BIA_PROC_MIX1, CONFIG_BIA_PROC_MIX1_value);
        // Not added
        // CONTROL20_value|=MODE_EN_FRAME_SYNC_ON<<6;
    }
    /*---Pace pulse detect configuration---*/
    void AFE_pacs_config(void)
    {
        CONFIG_PACE_DETECT_value |= EN_PACE << 0;
        AFE_SetRegisterValue(CONFIG_PACE_DETECT, CONFIG_PACE_DETECT_value);
        CONFIG_PACE_DIG_REG2_value |= PACE_CONFIG_REG1;
        AFE_SetRegisterValue(CONFIG_PACE_DIG_REG2, CONFIG_PACE_DIG_REG2_value);
        CONFIG_PACE_DIG_REG3_value |= PACE_CONFIG_REG2;
        AFE_SetRegisterValue(CONFIG_PACE_DIG_REG3, CONFIG_PACE_DIG_REG3_value);
        CONTROL19_value |= PACE_DIS_RESP_REJECT << 19;
        AFE_SetRegisterValue(CONTROL19, CONTROL19_value);
        CONFIG_PACE_DIG_REG1_value |= SEL_CLK_PACE << 17 | WIDTH_PACE_MIN | WIDTH_PACE_MAX << 6 | PACE_OBS_EXTEND << 14 | PACE_VALID_COMPLETE << 18;
        AFE_SetRegisterValue(CONFIG_PACE_DIG_REG1, CONFIG_PACE_DIG_REG1_value);
        CONFIG_PACE_DETECT_value |= PACE_REF1_H << 3 | PACE_REF1_L << 9;
        AFE_SetRegisterValue(CONFIG_PACE_DETECT, CONFIG_PACE_DETECT_value);
        CONTROL25_value |= PACE_FIFO_DATA_CTRL << 7 | EN_PACE_VALID_TAG << 2 | EN_PACE_OVERLAP_TAG << 3 | USE_PACE_OVERLAP_TAG << 4 | USE_BOTH_PACE_TAGS << 5 | EN_PACE_TAG_ECG_CH1 << 0 | EN_PACE_TAG_ECG_CH2 << 1; // changed
        AFE_SetRegisterValue(CONTROL25, CONTROL25_value);
        CONTROL9_value |= EN_PACE_WINDOW_ADC_RDY << 15 | EN_PACE_WINDOW_GPIO2 << 14;
        AFE_SetRegisterValue(CONTROL9, CONTROL9_value);
    }
    
    void fifo_disable()
    {
        CONTROL0_value |= 0 << 6;
        AFE_SetRegisterValue(CONTROL0, CONTROL0_value);
    }
    

    afe4960_drv.h

  • Hello Dhivin,

    I'm still looking into this. 

    Are you completely reading the data from the FIFO after the interrupt is generated, or is the interrupt coming while the FIFO remains full? Can you confirm that the data ready interrupt remains constant at 256 Hz (= PRF cycle period).

    Regards,

    Ryan

  • Hi Ryan,

    We only read the data after an interrupt is triggered when the FIFO becomes full.

    The data-ready interrupt occurs at a rate of 256Hz.