Post Go back to editing

AD5941 Impedance Frequency Sweep without the Sequencer and Interrupts

Category: Software
Product Number: AD5941

 Hello,

I am working on a 2-wire impedance project with the AD5941. I am trying to get rid of the sequencer controlling the frequency sweep. I would prefer to do all of it through SPI if possible. I have referenced this example: https://ez.analog.com/data_converters/precision_adcs/f/q-a/560706/is-there-way-to-use-ad5940-without-interrupt-or-gpio-interrupt-pin

The only issue here is I am not sure where the data is being written to, as when trying to print it out the values are 0. Any pointers?

  • Hi  ,

    We will look into this. I will contact the product owner and get back to you.

    Regards,

    JC

  • Hi,

    You will have to add 

    AppIMPDataProcess((int32_t*)pBuff,&FifoCnt); 

    function inside AD5940_Main() before 

    ImpedanceShowResult(AppBuffImpedance, temp,++counter); function.

    /* Depending on the data type, do appropriate data pre-process before return back to controller */
    int32_t AppIMPDataProcess(int32_t * const pData, uint32_t *pDataCount)
    {
      uint32_t DataCount = *pDataCount;
      uint32_t ImpResCount = DataCount/4;
    
      fImpPol_Type * const pOut = (fImpPol_Type*)pData;
      iImpCar_Type * pSrcData = (iImpCar_Type*)pData;
    
      *pDataCount = 0;
    
      DataCount = (DataCount/4)*4;/* We expect RCAL data together with Rz data. One DFT result has two data in FIFO, real part and imaginary part.  */
    
      /* Convert DFT result to int32_t type */
      for(uint32_t i=0; i<DataCount; i++)
      {
        pData[i] &= 0x3ffff; /* @todo option to check ECC */
        if(pData[i]&(1L<<17)) /* Bit17 is sign bit */
        {
          pData[i] |= 0xfffc0000; /* Data is 18bit in two's complement, bit17 is the sign bit */
        }
      }
      for(uint32_t i=0; i<ImpResCount; i++)
      {
        iImpCar_Type *pDftRcal, *pDftRz;
    
        pDftRcal = pSrcData++;
        pDftRz = pSrcData++;
        float RzMag,RzPhase;
        float RcalMag, RcalPhase;
        
        RcalMag = sqrt((float)pDftRcal->Real*pDftRcal->Real+(float)pDftRcal->Image*pDftRcal->Image);
        RcalPhase = atan2(-pDftRcal->Image,pDftRcal->Real);
        RzMag = sqrt((float)pDftRz->Real*pDftRz->Real+(float)pDftRz->Image*pDftRz->Image);
        RzPhase = atan2(-pDftRz->Image,pDftRz->Real);
    
        RzMag = RcalMag/RzMag*AppIMPCfg.RcalVal;
        RzPhase = RcalPhase - RzPhase;
        //printf("V:%d,%d,I:%d,%d ",pDftRcal->Real,pDftRcal->Image, pDftRz->Real, pDftRz->Image);
        
        pOut[i].Magnitude = RzMag;
        pOut[i].Phase = RzPhase;
      }
      *pDataCount = ImpResCount; 
      AppIMPCfg.FreqofData = AppIMPCfg.SweepCurrFreq;
      /* Calculate next frequency point */
      if(AppIMPCfg.SweepCfg.SweepEn == bTRUE)
      {
        AppIMPCfg.FreqofData = AppIMPCfg.SweepCurrFreq;
        AppIMPCfg.SweepCurrFreq = AppIMPCfg.SweepNextFreq;
        AD5940_SweepNext(&AppIMPCfg.SweepCfg, &AppIMPCfg.SweepNextFreq);
      }
    
      return 0;
    }

    Output data is stored in pOut[].

  • Hi  thanks for the response. This makes sense, thanks. 

    When you call AppIMPDataProcess((int32_t*)pBuff,&FifoCnt); in the AD5940_main, where is the &FifoCnt coming from? If I am correct, the pBuff is a pointer to the AppBuffImpedance declared earlier in the C file(see below).

    #define APPBUFF_SIZE_IMPEDANCE 512
    uint32_t AppBuffImpedance[APPBUFF_SIZE_IMPEDANCE];
    uint64_t counter = 0;
    

  • FifoCnt = (AD5940_FIFOGetCnt()/4)*4;

    Yes. (int32_t*)pBuff is

    #define APPBUFF_SIZE 512
    uint32_t AppBuff[APPBUFF_SIZE];