Post Go back to editing

Reading data from FIFO

Hi Analog Team,

We are interfacing ADPD4100 with nRF52840 MCU.

We have set dcfg Register Basic Configuration as:-

  {0x00B4, 0x0010},
// {0x0009, 0x0094}, // 72 frequency adj
// {0x000B, 0x02EA}, //02CA 1mhz freq adj
{0x0100, 0x0100}, // 40DA
{0x000D, 0x03EB}, // setting the sampling rate // 2710 C350 20HZ C8=5khz ,
{0x000f, 0x0006}, // (1Mhz internal low freq osc)
//{0x0020, 0x0002}, // INP sleep in1 is connected to vc1
{0x0022, 0x0003}, // gpio config pin output invert
{0x0023, 0x0002}, // gpio 0 is int x
{0x0014, 0x8000}, // interrupt enable th_fifi
{0x0021, 0x0000}, // in1 connected to the single ended
{0x0006, 0x003B}, // setting the size of fifo thrshoul
{0x0101, 0x40DA}, // setting the analog path
{0x0102, 0x0001}, // IN1 connected to channel1
{0x0103, 0x5002}, // precondition with TIAVref and vc1 sel tia +215mv
{0x0104, 0x03C0}, // 13C2// AFE trim Vref 1,265 &madulatevref1.265 ,channel1 200k
{0x0105, 0x0F0F}, //
//{0x0106, 0x1919}, //
{0x0107, 0x0108}, // number of 4 pulses
{0x0108, 0x0000}, // mode selection
{0x0109, 0x0210}, // led pulse 2micro width, offset 16microsec
{0x010A, 0x0003}, // integrator clock width 3 microsec
{0x010B, 0x0206}, // int offset 16us and led width 2us 0210
{0x010C, 0x0201},
{0x010D, 0x0099}, // CHOPE MODE 99
{0x010E, 0x0000},
{0x0110, 0x0004}, // 3 bytesom
{0x0010, 0x0000}, // time slot A enable * 

Note : We are following the Driver provided on this link : adpd-drivers/adpd40xx at master · analogdevicesinc/adpd-drivers (

After doing basic configuration the led's on the adpd4100 module are glowing. Now we are trying to extract Data from the FIFO. Some random data is coming and also not refreshing. We are not able to understand the main cause.

We followed this link main.cpp firmware for FIFO reading :- adpd-drivers/main.cpp at master · analogdevicesinc/adpd-drivers (

We tried reading status of fifo using FIFO_ STATUS register, we are receiving 2200(hex) value.

Questions :- 

1.) Please suggest what wrong i may be doing from the Firmware side ?

2.) Pls share something on how to read data from the FIFO ?

Thank You 

Added details
[edited by: SloneShrub at 1:26 PM (GMT -5) on 15 Dec 2021]
Parents Reply Children
  • Hi SloneShrub,

    The integration offset timing need to change.

    {0x0100,0x0000}, // 40DA
    {0x000D,0x03EB}, // setting the sampling rate // 2710 C350 20HZ C8=5khz ,
    {0x000f,0x0006}, // (1Mhz internal low freq osc)
    {0x0022,0x0003}, // gpio config pin output invert
    {0x0023,0x0002}, // gpio 0 is int x
    {0x0014,0x8000}, // interrupt enable th_fifi
    {0x0021,0x0000}, // in1 connected to the single ended
    {0x0006,0x003B}, // setting the size of fifo thrshoul
    {0x0101,0x40DA}, // setting the analog path
    {0x0102,0x0001}, // IN1 connected to channel1
    {0x0103,0x5002}, // precondition with TIAVref and vc1 sel tia +215mv
    {0x0104,0x03C0}, // 13C2// AFE trim Vref 1,265 &madulatevref1.265 ,channel1 200k
    {0x0105,0x0F0F}, //
    {0x0107,0x0108}, // number of 4 pulses
    {0x0108,0x0000}, // mode selection
    {0x0109,0x0210}, // led pulse 2micro width, offset 16microsec
    {0x010A,0x0003}, // integrator clock width 3 microsec
    {0x010B,0x01F5}, // int offset 16us and led width 2us 0210
    {0x010D,0x0099}, // CHOPE MODE 99
    {0x0110,0x0004}, // 4 bytesom
    {0x0010,0x0000}, // time slot A enable *

    Can use the above configuration for your checking.


    Optical Support Team

  • Hi Sathishkumar,

    I verified with above configuration, but no luck.

    We again checked the status of fifo using FIFO_ STATUS register, we are receiving 2200(hex) value.

    Questions :- 

    1.) Please suggest what wrong i may be doing from the Firmware side ?

    2.) Pls share something on how to read data from the FIFO ?

    Note :- Below is the read function, we are using for reading REGISTER Values.

    uint16_t adi_adpddrv_RegRead(uint16_t nAddr, uint16_t *pnData)
    /* Declare variable to track the status of routine */
    uint16_t nRetCode = ADI_ADPD_DRV_SUCCESS;
    /* Declare variable to store number of byte to be transmit */
    uint16_t nTxSize = 0U;
    /* Declare variable to store register address */
    uint16_t nTmpAddr = 0U;
    /* Declare variable to store value from receive buffer */
    uint8_t anRxData[4] = {0U, 0U,0U,0U};
    /* Declare variable to prepare transmit buffer */
    uint8_t anTxData[4] = {0U,0U,0U,0U};
    /* Check the communication type and proceed with selected peripheral */
    /* To set the last bit low for read operation */
    nTmpAddr = ((nAddr << 1U) & ADPD400x_SPI_READ);
    /* Prepare the transmit buffer with register address */
    anTxData[nTxSize++] = (uint8_t)(nTmpAddr >> 8U);
    anTxData[nTxSize++] = (uint8_t)(nTmpAddr);
    anTxData[nTxSize++] = 0U;
    anTxData[nTxSize++] = 0U;
    The first argument to the function is the register address of the
    ADPD4x device from where the data is to be read.
    The 2nd argument is the pointer to the buffer of received data.
    The size of this buffer should be equal to the number of data requested.
    The 3rd argument is the size of transmit data in bytes.
    The 4th argument is the size of requested data in bytes.
    Adpd4x_SPI_Receive() should be implemented in such a way that it transmits
    the register address from the first argument and receives the data
    specified by the address in the second argument. The received data will
    be of size specified by 3rd argument.
    APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi,&anTxData,nTxSize,&anRxData, 4U));
    // printf("transfer complete flag");
    /* Copy the register value from receive buffer to output parameter with byte order [15:0]*/
    // NRF_LOG_INFO("delay.");
    // NRF_LOG_INFO("delay200.");
    *pnData = (((uint16_t)anRxData[2]) << (8U)) + (anRxData[3]);

    NRF_LOG_INFO("receive data %x" ,anRxData[2] );
    NRF_LOG_INFO("receive data %x" ,anRxData[3] );
    /* Return routine status to caller function */
    return nRetCode;

    //* Above line of code is from this link : *//

    Thank you

  • Hi,

    Looks like the FIFO overflow error happening, This error can occur when we are not reading the data from FIFO after getting interrupt.

    Can you share your main code to verify the ISR handing for FIFO interrupt?


    Optical Support Team

  • Below is main() function code. :- 

    int main(void)
    uint16_t read_data =0;
    uint16_t nAdpdFifoLevelSize;
    uint32_t nRetValue = 0U;
    uint16_t nbytes =1;
    uint16_t regaddr =0x002F;
    uint32_t adpd_ch1 = 0U;
    uint16_t loop = 0U;
    static uint32_t tick = 0U;


    nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
    spi_config.ss_pin = SPI_SS_PIN;
    spi_config.miso_pin = SPI_MISO_PIN;
    spi_config.mosi_pin = SPI_MOSI_PIN;
    spi_config.sck_pin = SPI_SCK_PIN;
    spi_config.frequency =NRF_SPI_FREQ_1M;
    spi_config.mode = NRF_DRV_SPI_MODE_3;

    APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler, NULL));


    NRF_LOG_INFO("SPI example started.");
    spi_xfer_done = false;

    if(adi_adpddrv_OpenDriver() != ADI_ADPD_DRV_SUCCESS) // 0
    NRF_LOG_INFO("Device ID is not reading.");

    // Load default configuration parameters
    if(adi_adpdssm_loadDcfg(dcfg_ADPD4000, 0xFFU) != ADI_ADPD_SSM_SUCCESS)
    NRF_LOG_INFO("Error: Cannot configure ADPD400x.\r\n");

    NRF_LOG_INFO("press button two for go mode");

    NRF_LOG_INFO("led bytes count %x",read_data);


    NRF_LOG_INFO("fifo bytes count %x",read_data);

    while (1)

    //Clearing the FIFO_TH Bit

    // read size of the of the fifo data availablke in the fifo


    /* Read the fifo data available in the FIFO */
    nRetValue = adi_adpddrv_ReadFifoData(nAdpdFifoLevelSize, &aFifoDataBuf[0]);

    if(nAdpdFifoLevelSize== 0)
    NRF_LOG_INFO("no fifo data");
    loop = 0U;
    adpd_ch1 = 0U;
    /* Read the data from the FIFO and print them */
    while (nAdpdFifoLevelSize != 0u) {
    /* Byte swapping is needed to print ADPD data in proper format */
    adpd_ch1 = ((aFifoDataBuf[loop] << 8) +
    (aFifoDataBuf[loop + 1]) +
    (aFifoDataBuf[loop + 2] << 24) +
    (aFifoDataBuf[loop + 3] << 16));

    NRF_LOG_INFO("%d tich ADPD_CH1 %x",tick,adpd_ch1);

    nAdpdFifoLevelSize -= 4;
    tick += 1;


    Note :- In while loop i am clearing the Interrupt Bit.

    I am not sure if it is the correct way, Please suggest how to properly handle interrupt bit ?

    Thank You !

  • Hi,

    Code looks fine. Loop variable incrementing alone missing on data printing section. That's why you are getting same value for each iteration.

    Regarding FIFO read method, you can refer the "adi_adpddrv_ReadFifoData" API in driver file.


    Optical Support Team.

  • Hi,

    Can use the "adi_adpdssm_setOperationMode" API to set the Sensor GO Mode. I think currently you are using own written code to set the Sensor Go Mode.

    If you are wish to use your own code please refer "adpd-drivers/adi_adpd_slotops_helper.c at master · analogdevicesinc/adpd-drivers · GitHub" file to create your code for Sensor Go Mode API. The code comments itself guide you through to make your own code.


    Optical Support Team.

  • Hi Sathishkumar,

    I tried using "adi_adpdssm_setOperationMode" API to set the Sensor GO Mode.

    Inside "adi_adpdssm_getMaxSamplSz" API the firmware is getting stuck in do{}While() Loop.

    Below is the Loop Firmware code :-

    /* Form a loop to run until it reaches LCM value, do the condition check with count and sample size flag */
    for (uint32_t nLcm = 1U; ((nLcm <= goAdiAdpdSSmInst->oAdpdSlotInst.nLcmValue) && (nMaximumSizeFlag == 0U)); nLcm++)
    _adi_adpdssm_CalculateMaxSamplSz(nTotalSampleSize, nLcm, &nMaximumSizeFlag, &nSampleSize);
    /* Check the calculated size and total sample size is not exceeding fifo buffer size */
    if((nTotalSampleSize + nSampleSize) < MAX_SAMPLES_IN_FIFO)
    /* Add the calculated size to total sample size variable */
    nTotalSampleSize = nTotalSampleSize + nSampleSize;
    /* Set the sample size value to '0' to calculate sample size for next sequence */
    nSampleSize = 0U;
    /* Update the sample count variable with successful size calculation*/
    nSampleCount = nSampleCount + 1U;
    /* Check the sample count variable to update last faliure routine */
    if(nSampleCount > 1U)
    /* Decrement '1' total sample count value, because last run on sample
    count loop value need to be decrement to match successful calculation alone */
    nSampleCount = nSampleCount - 1U;
    }while(nMaximumSizeFlag == 0U);

    Note : nTotalSampleSize, nMaximumSizeFlag and nSampleSize all values are coming 0.

    and nLcm value is starting from 0 to 865 and then again resetting.

    Questions :-

    1.) Please suggest What might be the reason ?

    2.) How to resolve this ?

    Thankyou & regards


  • Hi,

    Please do call the "adi_adpdssm_slotinit(&oAdiAppInst)" API as like in example code before calling "adi_adpdssm_setOperationMode" API.

    ADPD Instance is not initialized in above main code. Due to this do while{} will run continuously until reaching desired values based on device configuration.


    Optical Support Team.

  • Hi,

    The firmware is running perfectly, But we are not sure whether go mode is set or not properly. (I am using adi_adpdssm_setOperationMode Api only didn't made any changes.

    The Led's are not glowing now. Some random data came for a particular duration and stopped.

    I am not able to understand the problem, please suggest something to resolve this .

    Thank you

  • Hi,

    In the device configuration IR is selected that's why the LED glow is not able observe over sensor.

    Please change the "0x105" register value as "008F" to select the Green LED.

    Your current configuration is 1000Hz sampling rate. Can you reduce sample rate and check whether you are able to get the data continuously.

    To set 50Hz sample rate use the below register values.

    000B 02B2 # 1MHz trim - trim your own clock
    000C 0012 # 32kHz trim - trim your own clock
    000D 4E20 # 50 Hz
    000F 0006 # enable 1MHz osc


    Optical Support Team.