Post Go back to editing

AN9541-BATImpedance integration with other controllers (no ADICUP3029 CPU)

Category: Software
Product Number: EVAL-AD5941BATZ, AD5941, AD5941, AD5941
Software Version: 1

Hi Akila, and others in you team.
I am trying to integrate the BAT Impedance application code examples with my Linux based system (no ADICUP3029 CPU)
I have written working SPI drivers for the following functions and integrated (linking to my own hardware port driver) them into the ad5940.c and ad5940.h 
1. AD5940_RstClr(void);
2. 
AD5940_RstSet(void);
3. 
AD5940_HWReset(void);  ...modified existing ad5940.c function
4. 
AD5940_Initialize(void);  ... modified existing ad5940.c function
5. static void AD5940_SPIWriteReg(uint16_t RegAddr, uint32_t RegData); ... modified existing ad5940.c function (these appear to be the only truly needed SPI functions required) 
6. 
static uint32_t AD5940_SPIReadReg(uint16_t RegAddr); ... modified existing ad5940.c function  (these appear to be the only truly needed SPI functions required) 
7. 
uint32_t AD5940_ClrMCUIntFlag(void);   ... unsure if working 100% unable to confirm readback
8. 
uint32_t  AD5940_GetMCUIntFlag(void); ... unsure if working 100%

I cannot see the need/function for any of the defined functions below ..... please enlighten me?
1. 
static unsigned char AD5940_ReadWrite8B(unsigned char data);   .... does not support/conform to ad5941 data sheet requirements for SPI communications 
2. 
static uint16_t AD5940_ReadWrite16B(uint16_t data)  .... does not support/conform to ad5941 data sheet requirements for SPI communications 
3. 
static uint32_t AD5940_ReadWrite32B(uint32_t data)  .... does not support/conform to ad5941 data sheet requirements for SPI communications 
4. void AD5940_ReadWriteNBytes(unsigned char *pSendBuffer,unsigned char *pRecvBuff,unsigned long length);  ... same as above ..no conforming function.
5. Maybe the original code memory mapped the ad5940 registers etc .. but there is no information about these and how they work.


The original code examples (with ADICUP3029) use hardware controlled SPI_CS whereas my Linux code these are built-into the SPI transactions.
My SPI code can reliably read all the basic ad5940 registers including valid AD5940LIB Version: v0.2.1, ADIID: 0x4144 and CHIPID: 0x5502

1. Some functions like .. AD5940_Initialize(void); appear to work ... but for some reason I cannot seem to read-back was was written to the initialization registers, is this a common issue?
2. Running the ad5950Main.c is not retrieving and valid data as yet, not sure exactly why?
3. I have modified the BATImpedance function "static void PreCharge(unsigned char channel) " to work with my code but the EVAL-BATZ board, does not even have the jumpers JP8 or JMP9 so I wonder why this code will even work.
4. Can you please confirm all the necessary functions that are needed to make the EVAL_BATZ system work, unnecessary code and built-in connections with the ADI CPU (ADICUP3029) make it difficult to know precisely what code and functions are needed to make this work. 
5. Also the ad5940 data sheet is sadly lacking in details, do you have a detailed Map or table listing all the ad5941 registers and their functions, that also state which registers are defined as 32 or 16 bit registers, Why I cannot read the initialization registers etc.
6. The ad5940 only shows 10 x 16bit registers that need to be initialized after reset by the ADI code functions (for BATZ) show many more registers that include both 16bit and 32bit reigisters.
7. The ad5940 data sheet does not list any 32 bit registers .. so what's going on?
Any help would be much appreciated.
Thanks for you help on these matters.
Collin. 

Parents
  • Thanks Ivan,

    I have now been through the ad5940 datasheet in detail to extract as much information as possible. I repeat this is a poor example of a technical datasheet and has many short comings in particular the register definitions, addresses and their data widths. 

    1. I confirm that the ADI SDK's general rule below is correct because all analog front-end registers (ADC, DAC, TIA, etc.) reside in that 0x1000–0x3014 range and are 32-bit wide, the others are 16 bit. There are no real registers above 0x3014.
    YOUR CODE USES:
    if ((addr >= 0x1000) && (addr <= 0x3014))
    access_type = 32bit;
    else
    access_type = 16bit;

    This range is too broad — the Rev.D datasheet shows that the 32-bit registers exist in discontinuous regions:
    0x1000–0x1020 (High-level sequencer control)
    0x2000–0x3014 (AFE control blocks, sequencer SRAM, FIFO)

    Therefore I suggest to use:
    bool is_32bit_reg(uint16_t addr)
    {
    return ((addr >= 0x1000 && addr <= 0x1020) ||
    (addr >= 0x2000 && addr <= 0x3014));
    }


    2. 

    Range Meaning Width Valid for register access?
    0x0000–0x0FFF Control & Digital 16-bit
    0x1000–0x3014 Analog Front End (AFE) 32-bit
    0x4000–0x43FF Sequencer/FIFO memory 16-bit word memory Access only via memory commands

    • 0x3014 is indeed the last documented register (REG_AFE_ADCDAT).

    • Everything above that — e.g., 0x4000–0x43FF — is not normal register space, but maybe sequencer/FIFO memory accessed indirectly or through special SPI commands? -- If so can you explain how these work?

    3. The ADI SDK's are mixed and confusing in many parts, they don't properly segregate hardware specific control functions such as SPI and GPIO transactions. This leads to confusing ad5940.c and ad5940.h files containing a mix of hardware functions that could have been easily separated for the SDK's, making specific APP's difficult to work with, e.g. BATImpedence etc.

    4. I have now made separate files for ad5940.c, ad5940.h to work with  specific (hardware dependent) ad5940_port.c  and ad5940_port.h separating the much needed clarifications. 

    5.  I have re-written all the SPI functions and modified the necessary ad5940.c files as needed. When running the BATImpedance SDK the data being spurted out is incorrect .. eg when MRCAL is run I an getting inconsistant data like below.

    === Performing MRCAL  ===
    i: 1 Freq: 1.00 RcalVolt:(8.000000,-5.000000)
    i: 2 Freq: 1.25 RcalVolt:(5.000000,0.000000)
    i: 3 Freq: 1.56 RcalVolt:(4.000000,-3.000000)
    i: 4 Freq: 1.94 RcalVolt:(3.000000,-1.000000)
    i: 5 Freq: 2.42 RcalVolt:(1.000000,1.000000)
    i: 6 Freq: 3.02 RcalVolt:(1.000000,3.000000)
    i: 7 Freq: 3.76 RcalVolt:(-1.000000,2.000000)
    i: 8 Freq: 4.69 RcalVolt:(2.000000,-2.000000)
    i: 9 Freq: 5.85 RcalVolt:(-1.000000,-2.000000)
    i: 10 Freq: 7.30 RcalVolt:(1.000000,4.000000)
    i: 11 Freq: 9.10 RcalVolt:(0.000000,0.000000)
    i: 12 Freq: 11.35 RcalVolt:(-2.000000,-3.000000)
    i: 13 Freq: 14.15 RcalVolt:(-1.000000,1.000000)
    i: 14 Freq: 17.65 RcalVolt:(0.000000,0.000000)
    i: 15 Freq: 22.01 RcalVolt:(-1.000000,1.000000)
    i: 16 Freq: 27.44 RcalVolt:(1.000000,1.000000)

    As can be seen the data is all wrong, the measured data are effectively noise?
    This gets me back to my previous questions when I see the ADI code doing things like this?

        case BATCTRL_MRCAL:
        printf("=== Performing MRCAL 1 ===\n");
        if(AD5940_WakeUp(10) > 10)
            return AD5940ERR_WAKEUP;
        //Settle input RC filter.
        AD5940_WriteReg(REG_AFE_SWMUX, 0); //control ADG636 to measure rcal
        AD5940_WriteReg(REG_AFE_SYNCEXTDEVICE, 0x4);
        PreCharge(PRECHARGE_RCAL);
        PreCharge(PRECHARGE_AMP);
        AD5940_FIFOCtrlS(FIFOSRC_DFT, bFALSE);

    The BATImpedence code calls PRECHARGE functions even though the required hardware links for JP8 and JP9 are not installed, so how exactly is this supposed to work, it appears to be necessary, the code is implemented but links not installed on pcb nor any information on these matters provided by ADI.

    It seems that that the test excitation signal not being generated correctly in software, and or the DFT engine is not working due to my present coding issues with the sequencer setups, all these maybe SPI communication issues, I believe my coding meets the required SPI protocols outlined in the ad5940 datasheet.

     

Reply
  • Thanks Ivan,

    I have now been through the ad5940 datasheet in detail to extract as much information as possible. I repeat this is a poor example of a technical datasheet and has many short comings in particular the register definitions, addresses and their data widths. 

    1. I confirm that the ADI SDK's general rule below is correct because all analog front-end registers (ADC, DAC, TIA, etc.) reside in that 0x1000–0x3014 range and are 32-bit wide, the others are 16 bit. There are no real registers above 0x3014.
    YOUR CODE USES:
    if ((addr >= 0x1000) && (addr <= 0x3014))
    access_type = 32bit;
    else
    access_type = 16bit;

    This range is too broad — the Rev.D datasheet shows that the 32-bit registers exist in discontinuous regions:
    0x1000–0x1020 (High-level sequencer control)
    0x2000–0x3014 (AFE control blocks, sequencer SRAM, FIFO)

    Therefore I suggest to use:
    bool is_32bit_reg(uint16_t addr)
    {
    return ((addr >= 0x1000 && addr <= 0x1020) ||
    (addr >= 0x2000 && addr <= 0x3014));
    }


    2. 

    Range Meaning Width Valid for register access?
    0x0000–0x0FFF Control & Digital 16-bit
    0x1000–0x3014 Analog Front End (AFE) 32-bit
    0x4000–0x43FF Sequencer/FIFO memory 16-bit word memory Access only via memory commands

    • 0x3014 is indeed the last documented register (REG_AFE_ADCDAT).

    • Everything above that — e.g., 0x4000–0x43FF — is not normal register space, but maybe sequencer/FIFO memory accessed indirectly or through special SPI commands? -- If so can you explain how these work?

    3. The ADI SDK's are mixed and confusing in many parts, they don't properly segregate hardware specific control functions such as SPI and GPIO transactions. This leads to confusing ad5940.c and ad5940.h files containing a mix of hardware functions that could have been easily separated for the SDK's, making specific APP's difficult to work with, e.g. BATImpedence etc.

    4. I have now made separate files for ad5940.c, ad5940.h to work with  specific (hardware dependent) ad5940_port.c  and ad5940_port.h separating the much needed clarifications. 

    5.  I have re-written all the SPI functions and modified the necessary ad5940.c files as needed. When running the BATImpedance SDK the data being spurted out is incorrect .. eg when MRCAL is run I an getting inconsistant data like below.

    === Performing MRCAL  ===
    i: 1 Freq: 1.00 RcalVolt:(8.000000,-5.000000)
    i: 2 Freq: 1.25 RcalVolt:(5.000000,0.000000)
    i: 3 Freq: 1.56 RcalVolt:(4.000000,-3.000000)
    i: 4 Freq: 1.94 RcalVolt:(3.000000,-1.000000)
    i: 5 Freq: 2.42 RcalVolt:(1.000000,1.000000)
    i: 6 Freq: 3.02 RcalVolt:(1.000000,3.000000)
    i: 7 Freq: 3.76 RcalVolt:(-1.000000,2.000000)
    i: 8 Freq: 4.69 RcalVolt:(2.000000,-2.000000)
    i: 9 Freq: 5.85 RcalVolt:(-1.000000,-2.000000)
    i: 10 Freq: 7.30 RcalVolt:(1.000000,4.000000)
    i: 11 Freq: 9.10 RcalVolt:(0.000000,0.000000)
    i: 12 Freq: 11.35 RcalVolt:(-2.000000,-3.000000)
    i: 13 Freq: 14.15 RcalVolt:(-1.000000,1.000000)
    i: 14 Freq: 17.65 RcalVolt:(0.000000,0.000000)
    i: 15 Freq: 22.01 RcalVolt:(-1.000000,1.000000)
    i: 16 Freq: 27.44 RcalVolt:(1.000000,1.000000)

    As can be seen the data is all wrong, the measured data are effectively noise?
    This gets me back to my previous questions when I see the ADI code doing things like this?

        case BATCTRL_MRCAL:
        printf("=== Performing MRCAL 1 ===\n");
        if(AD5940_WakeUp(10) > 10)
            return AD5940ERR_WAKEUP;
        //Settle input RC filter.
        AD5940_WriteReg(REG_AFE_SWMUX, 0); //control ADG636 to measure rcal
        AD5940_WriteReg(REG_AFE_SYNCEXTDEVICE, 0x4);
        PreCharge(PRECHARGE_RCAL);
        PreCharge(PRECHARGE_AMP);
        AD5940_FIFOCtrlS(FIFOSRC_DFT, bFALSE);

    The BATImpedence code calls PRECHARGE functions even though the required hardware links for JP8 and JP9 are not installed, so how exactly is this supposed to work, it appears to be necessary, the code is implemented but links not installed on pcb nor any information on these matters provided by ADI.

    It seems that that the test excitation signal not being generated correctly in software, and or the DFT engine is not working due to my present coding issues with the sequencer setups, all these maybe SPI communication issues, I believe my coding meets the required SPI protocols outlined in the ad5940 datasheet.

     

Children
No Data