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.

AFE4490: Unable to read register from AFE4490

Part Number: AFE4490

hi,

       I am interfacing AFE4490 with Kinetis microcontroller.When i try to read back from regsiter i am getting the data as zero.I have seen the firmware source code and message communication protocol pdf.In that,they have mentioned to read regsiter using data packet.could anyone explain whether i have to send that data pcket to read from register through spi protocol or else i have to send that whole packet to read it back.I am facing the same problem in write to register .anyone say the procedure for that.

Thanks in advance.

  • Hi Kanimozhi,

    First lets get register write working .
    If you have your own microcontroller , you don't need to follow the message protocol.
    You just have to generate the SPI signals as mentioned in the datasheet for register read/write.

    Regards,
    Prabin
  • Hi prabin,
    I checked with code.my data is not getting written.i disabled spi_read and make changes to one register and enable spi_read,read back that register.This is the procedure i am following.i set the clock frq as4Mhz and mode 0 operation used .but still its not working .could you say the procedure for testing afe4490.Thank you.
  • Hi Kanimozhi,

    Can you please double check the supplies as well as AFE_PDN and RESET signal?
    Also can you please share the analog waveform for the SPI signals?

    Regards,
    PRabin
  •        Hi Prabin,

            I have attached spi waveform.First I didnt use adc_rdy ,pdn and reset,just i am trying to make spi to work it.interfacing afe with my controller and in code write 1 register with spi_read=0 and read it back with spi_read =1.This itself not working for me.I am using mode 0 and 4mhz.when i use 4mhz i could not see datas in logic analyzer so i have chnged clock.In datasheet they have mentioned you have to use 4mhz inorder read registers.So ,please clarify me about clock to use.The values what i try to write is not written to register.It would be great if its resolved.Thank you.

  • /*
    * File: hello_world.c
    * Purpose: Main process
    *
    */

    /*
    This project is intended to interface ADXL362 with K53n512 controller using SPI
    protocol
    k53 has 3 SPI protocols and we are using SPI0
    */

    #include "common.h"


    #define GPIO_PIN_MASK 0x1Fu
    #define GPIO_PIN(x) (((1)<<(x & GPIO_PIN_MASK)))
    #define CONTROL0 0x00
    #define LEDCNTRL 0x22
    #define TIAGAIN 0x20
    #define TIA_AMB_GAIN 0x21

    //#define TEST_LOW GPIOC_PDOR&=~GPIO_PDOR_PDO(GPIO_PIN(8)) //debug pin
    //#define TEST_HIGH GPIOC_PDOR|=GPIO_PDOR_PDO(GPIO_PIN(8)) //debug pin

    /* function prototypes */
    void spi_init();
    void spi_write(uint8,uint32);
    uint32 spi_read(uint8);
    void time_delay_ms(unsigned int count_val);
    uint8 SPI_byte_IO(uint32 data);

    void main (void)
    {
    printf("\n SPI Interface with afe \n");
    spi_init();
    while(1)
    {

    spi_write(0x00,0x000000);
    spi_write(0x20,0x000004);
    spi_write(0x00,0x000001);
    spi_read(0x20);
    }

    }

    /* SPI used here is SPI0 in master mode,spi clocks disable FIFO's,clear counter of FIFO's,frame siz 8,
    baud rate,clock phase on rising edge,inactive ststa high,use CTAR1 since in master mode,MSB first,
    doze mode disabled,continuous clock is activated
    */

    void spi_init() //spi initialization in master mode
    {
    SIM_SCGC6 |= SIM_SCGC6_DSPI0_MASK; // Enables clock to SPI0
    SIM_SCGC5 = (SIM_SCGC5_PORTA_MASK)|(SIM_SCGC5_PORTB_MASK); // Enables clock to PORTA

    PORTA_PCR14 |= PORT_PCR_MUX(2); //Setting the MUX value of 2 for SPI0 functionality(PCS0)
    //PORTA_PCR15 &= ~PORT_PCR_MUX_MASK;
    PORTA_PCR15 |= PORT_PCR_MUX(2); //Setting the MUX value of 2 for SPI0 functionality(SCK)
    //PORTA_PCR16 &= ~PORT_PCR_MUX_MASK;
    PORTA_PCR16 |= PORT_PCR_MUX(2); //Setting the MUX value of 2 for SPI0 functionality(SOUT)
    // PORTA_PCR17 &= ~PORT_PCR_MUX_MASK;
    PORTA_PCR17 |= PORT_PCR_MUX(2); //Setting the MUX value of 2 for SPI0 functionality(SIN)

    // MASTER MODE ,Continuous clock generation, peri chip select signal, when rx data overflow overwrite the shift register, all the chip select uses high signal for deactivating, doze mode is disabled, enalbe DSPI clocks always and is not controlled by external digital pins, tx and rx are enabled

    // SPI0_MCR = ((SPI_MCR_HALT_MASK) | (SPI_MCR_MDIS_MASK & 0x00));
    // SPI0_MCR = (SPI_MCR_DIS_TXF_MASK)|(SPI_MCR_MSTR_MASK )|(SPI_MCR_DIS_RXF_MASK)|(SPI_MCR_ROOE_MASK)|(SPI_MCR_DCONF(0x00))|SPI_MCR_CONT_SCKE_MASK|(SPI_MCR_PCSIS(1));
    // SPI0_CTAR0 = (SPI_CTAR_DBR_MASK&0x00) | (SPI_CTAR_FMSZ(0xF)) | (SPI_CTAR_PDT(0x00)) | (SPI_CTAR_BR(1)) | (SPI_CTAR_CPOL_MASK & 0x00) | (SPI_CTAR_CPHA_MASK&0x00) | (SPI_CTAR_PBR(1) | (SPI_CTAR_PCSSCK(0x02)) | (SPI_CTAR_PASC(0x00)) | (SPI_CTAR_CSSCK(0x06)) | (SPI_CTAR_ASC(0)) | (SPI_CTAR_PDT(0x00)) | (SPI_CTAR_DT(0))) ; // mode 0 operation
    SPI0_MCR = ((SPI_MCR_HALT_MASK) | (SPI_MCR_MDIS_MASK & 0x00));
    SPI0_MCR = (SPI_MCR_DIS_TXF_MASK)|(SPI_MCR_MSTR_MASK )|(SPI_MCR_DIS_RXF_MASK)|(SPI_MCR_ROOE_MASK)|(SPI_MCR_DCONF(0x00))|SPI_MCR_CONT_SCKE_MASK|(SPI_MCR_PCSIS(63));
    SPI0_CTAR0 = (SPI_CTAR_DBR_MASK & 0x00) | (SPI_CTAR_FMSZ(0x07)) | (SPI_CTAR_PDT(0x00)) | (SPI_CTAR_BR(0x07)) | (SPI_CTAR_CPOL_MASK & 0x00) | (SPI_CTAR_CPHA_MASK & 0x00) | (SPI_CTAR_PBR(0x02)) | (SPI_CTAR_PCSSCK(0x02) | (SPI_CTAR_PASC(0x00)) | (SPI_CTAR_CSSCK(0x06)) | (SPI_CTAR_ASC(0)) | (SPI_CTAR_PDT(0x00)) | (SPI_CTAR_DT(0))) ; // mode 0 operation

    }
    // SPI0_PUSHR |=(SPI_PUSHR_PCS(0<<0));
    // SPI0_MCR &= 0xfffffffe ; //start transfers again


    /* Function memory_write() to write data to memory one byte at a time*/

    /*void spi_write(uint8 address,uint32 data)
    {
    SIM_SCGC6 |=SIM_SCGC6_DSPI0_MASK;
    uint8 d1,d2,d3;
    uint8 du1,du2,du3,du4=0;

    d3=((data>>16)&(0x0000FF));
    d2=((data>>8)&(0x0000FF));
    d1=(data & 0x0000FF);

    //TEST_LOW;
    SPI0_PUSHR = ((SPI_PUSHR_CTAS(0x00))|(SPI_PUSHR_PCS(63)) | (SPI_PUSHR_CONT_MASK) | SPI_PUSHR_TXDATA(address));

    while(((SPI0_SR & SPI_SR_TCF_MASK) == 0));
    du1=SPI0_POPR;
    SPI0_SR |= SPI_SR_TCF_MASK;
    SPI0_SR |= SPI_SR_TFFF_MASK;
    printf("dummy when addrs sent:%x\n",du1);

    //data3
    SPI0_PUSHR = ((SPI_PUSHR_CTAS(0x00)) | (SPI_PUSHR_PCS(63))|(SPI_PUSHR_CONT_MASK)| SPI_PUSHR_TXDATA(d3));

    while(((SPI0_SR & SPI_SR_TCF_MASK) == 0));
    du2=SPI0_POPR;
    SPI0_SR |= SPI_SR_TCF_MASK;
    SPI0_SR |= SPI_SR_TFFF_MASK;
    printf("dummy when msb sent:%x\n",du2);

    //data2
    SPI0_PUSHR = ((SPI_PUSHR_CTAS(0x00)) | (SPI_PUSHR_PCS(63)) | (SPI_PUSHR_CONT_MASK) | SPI_PUSHR_TXDATA(d2));

    while(((SPI0_SR & SPI_SR_TCF_MASK) == 0));
    du3=SPI0_POPR;
    SPI0_SR |= SPI_SR_TCF_MASK;
    SPI0_SR |= SPI_SR_TFFF_MASK;
    printf("dummy when middle sent:%x\n",du3);

    //data1
    SPI0_PUSHR = (SPI_PUSHR_CTAS(0x00)) |(SPI_PUSHR_PCS(63))| (SPI_PUSHR_CONT_MASK&0x00)|(SPI_PUSHR_EOQ_MASK) |(SPI_PUSHR_TXDATA(d1));
    while(((SPI0_SR & SPI_SR_TCF_MASK) == 0));
    du4=SPI0_POPR;
    SPI0_SR |= SPI_SR_TCF_MASK;
    SPI0_SR |= SPI_SR_TFFF_MASK;
    printf("dummy when lsb sent:%x\n",du4);
    //TEST_HIGH;
    printf("the data write to addrs %x:%x\n",address,data);


    }*/

    /*Function memory_read() to read data from memory one byte at a time */

    /*uint32 spi_read(uint8 address)
    {
    uint8 rd1=0,rd2=0,rd3=0;
    unsigned long retVal=0;
    //TEST_LOW;
    //address
    SPI0_PUSHR = ((SPI_PUSHR_CTAS(0x00)) | (SPI_PUSHR_PCS(63)) | (SPI_PUSHR_CONT_MASK) | SPI_PUSHR_TXDATA(address));

    while(((SPI_SR_RFDF_MASK & SPI0_SR) == 0));
    SPI0_SR |= SPI_SR_RFDF_MASK;
    SPI0_SR |= SPI_SR_RFOF_MASK;

    //data3
    SPI0_PUSHR = ((SPI_PUSHR_CTAS(0x00)) | (SPI_PUSHR_PCS(63))| (SPI_PUSHR_CONT_MASK) |SPI_PUSHR_TXDATA(0x00));

    while(((SPI_SR_RFDF_MASK & SPI0_SR) == 0));
    rd1=SPI0_POPR;
    SPI0_SR |= SPI_SR_RFDF_MASK;
    SPI0_SR |= SPI_SR_RFOF_MASK;

    printf("data3:%x\n",rd1);

    SPI0_PUSHR = ((SPI_PUSHR_CTAS(0x00))| (SPI_PUSHR_PCS(63))| (SPI_PUSHR_CONT_MASK) |SPI_PUSHR_TXDATA(0x00));

    while(((SPI_SR_RFDF_MASK & SPI0_SR) == 0));
    rd2=SPI0_POPR;
    SPI0_SR |= SPI_SR_RFDF_MASK;
    SPI0_SR |= SPI_SR_RFOF_MASK;

    printf("data2:%x\n",rd2);

    SPI0_PUSHR = ((SPI_PUSHR_CTAS(0x00)) | (SPI_PUSHR_PCS(63))| (SPI_PUSHR_EOQ_MASK)| (SPI_PUSHR_CONT_MASK&0x00) | SPI_PUSHR_TXDATA(0x00));

    while(((SPI_SR_RFDF_MASK & SPI0_SR) == 0));
    rd3=SPI0_POPR;
    SPI0_SR |= SPI_SR_RFDF_MASK;
    SPI0_SR |= SPI_SR_RFOF_MASK;

    printf("data1:%x\n",rd3);
    //TEST_HIGH;
    retVal|= rd1;
    retVal = ((retVal << 8)|rd2);
    retVal = ((retVal << 8) |rd3);
    printf("data read from addrs:%x\n",retVal);
    return retVal;

    }*/

    /* Delay function using the LPTMR module */

    void time_delay_ms(unsigned int count_val)
    {
    SIM_SCGC5|=SIM_SCGC5_LPTIMER_MASK; //Turn on clock to LPTMR module
    LPTMR0_CMR = count_val; //Set compare value
    LPTMR0_PSR = LPTMR_PSR_PCS(1)|LPTMR_PSR_PBYP_MASK; //Use 1Khz LPO clock and bypass prescaler
    LPTMR0_CSR |= LPTMR_CSR_TEN_MASK; //Start counting

    while (!(LPTMR0_CSR & LPTMR_CSR_TCF_MASK)) {} //Wait for counter to reach compare value

    LPTMR0_CSR &= ~LPTMR_CSR_TEN_MASK; //Clear Timer Compare Flag
    return;
    }


    //Since you clearly don't care about time-efficiency, it would help to put the basic byte I/O in a small routine:

    /*uint8 SPI_byte_IO(uint32 data){
    uint8 retval;
    SPI0_PUSHR = data;
    // while(!(SPI0_SR & SPI_SR_TFFF_MASK)) {} //You DON'T need to spin on TX-empty
    //Because RX full will ALWAYS come 'one bit later'
    while (!(SPI0_SR & SPI_SR_RFDF_MASK)) {} //wait till RX fifo is not empty
    // while(!(SPI0_SR & SPI_SR_EOQF_MASK)) {} //pointless...
    retval = SPI0_POPR;
    // SPI0_SR = SPI_SR_EOQF_MASK; //clear EOQF flag
    SPI0_SR = SPI_SR_TFFF_MASK;
    SPI0_SR = SPI_SR_RFDF_MASK;
    return retval;
    }
    void spi_write(uint8 mstr_val,uint32 data){
    // SIM_SCGC6 |=SIM_SCGC6_DSPI0_MASK; //CANNOT be necessary by now!
    uint8 d1,d2,d3;
    uint8 dummy_rx=0;
    uint32 chk_data=0;
    d3=((data>>16)&(0x0000FF));
    d2=((data>>8)&(0x0000FF));
    d1=(data & 0x0000FF);
    dummy_rx = SPI_byte_IO ( ( SPI_PUSHR_TXDATA(mstr_val)) | SPI_PUSHR_CONT_MASK | SPI_PUSHR_PCS(0x01));
    dummy_rx = SPI_byte_IO ( ( SPI_PUSHR_TXDATA(d3)) | SPI_PUSHR_CONT_MASK | SPI_PUSHR_PCS(0x01));
    dummy_rx = SPI_byte_IO ( ( SPI_PUSHR_TXDATA(d2)) | SPI_PUSHR_CONT_MASK | SPI_PUSHR_PCS(0x01));
    dummy_rx = SPI_byte_IO (( SPI_PUSHR_TXDATA(d1))| (SPI_PUSHR_CONT_MASK&0x00) | SPI_PUSHR_PCS(0x01));
    chk_data=(d3<<16)|(d2<<8)|d1;
    printf("data written to addrs :%x\n",chk_data);
    }


    uint32 spi_read(uint8 address){
    // SIM_SCGC6 |=SIM_SCGC6_DSPI0_MASK; //CANNOT be necessary by now!
    uint8 d1,d2,d3;
    uint8 dummy_rx=0;
    uint32 chk_data=0;
    // d3=((data>>16)&(0x0000FF));
    // d2=((data>>8)&(0x0000FF));
    //d1=(data & 0x0000FF);
    dummy_rx = SPI_byte_IO ( ( SPI_PUSHR_TXDATA(address)) | SPI_PUSHR_CONT_MASK | SPI_PUSHR_PCS(0x01));
    d3= SPI_byte_IO ( ( SPI_PUSHR_TXDATA(0)) | SPI_PUSHR_CONT_MASK | SPI_PUSHR_PCS(0x01));
    d2 = SPI_byte_IO ( ( SPI_PUSHR_TXDATA(0)) | SPI_PUSHR_CONT_MASK | SPI_PUSHR_PCS(0x01));
    d1 = SPI_byte_IO (( SPI_PUSHR_TXDATA(0))| (SPI_PUSHR_CONT_MASK&0x00) | SPI_PUSHR_PCS(0x01));
    chk_data=((d3&0x3F)<<16)|(d2<<8)|d1;
    printf("data read from addrs :%x\n",chk_data);
    return chk_data;
    }*/


    void spi_write(uint8 address,uint32 data)
    {
    SIM_SCGC6 |=SIM_SCGC6_DSPI0_MASK;
    uint8 d1,d2,d3;
    uint8 du1,du2,du3,du4=0;

    d3=((data>>16)&(0x0000FF));
    d2=((data>>8)&(0x0000FF));
    d1=(data & 0x0000FF);

    SPI0_PUSHR = ((SPI_PUSHR_CTAS(0x00)) | (SPI_PUSHR_PCS(63)) | (SPI_PUSHR_CONT_MASK) | SPI_PUSHR_TXDATA(address));

    while(((SPI0_SR & SPI_SR_TCF_MASK) == 0));
    while(((SPI_SR_RFDF_MASK & SPI0_SR) == 0));

    SPI0_SR |= SPI_SR_RFDF_MASK;
    SPI0_SR |= SPI_SR_RFOF_MASK;

    SPI0_SR |= SPI_SR_TCF_MASK;
    SPI0_SR |= SPI_SR_TFFF_MASK;

    SPI0_PUSHR = ((SPI_PUSHR_CTAS(0x00)) | (SPI_PUSHR_PCS(63)) | (SPI_PUSHR_CONT_MASK) | SPI_PUSHR_TXDATA(d3));

    while(((SPI0_SR & SPI_SR_TCF_MASK) == 0));
    while(((SPI_SR_RFDF_MASK & SPI0_SR) == 0));

    SPI0_SR |= SPI_SR_RFDF_MASK;
    SPI0_SR |= SPI_SR_RFOF_MASK;

    SPI0_SR |= SPI_SR_TCF_MASK;
    SPI0_SR |= SPI_SR_TFFF_MASK;
    SPI0_PUSHR = ((SPI_PUSHR_CTAS(0x00)) | (SPI_PUSHR_PCS(63)) | (SPI_PUSHR_CONT_MASK) | SPI_PUSHR_TXDATA(d2));

    while(((SPI0_SR & SPI_SR_TCF_MASK) == 0));
    while(((SPI_SR_RFDF_MASK & SPI0_SR) == 0));

    SPI0_SR |= SPI_SR_RFDF_MASK;
    SPI0_SR |= SPI_SR_RFOF_MASK;

    SPI0_SR |= SPI_SR_TCF_MASK;
    SPI0_SR |= SPI_SR_TFFF_MASK;

    SPI0_PUSHR = ((SPI_PUSHR_CTAS(0x00)) | (SPI_PUSHR_PCS(0x00)) | (SPI_PUSHR_CONT_MASK & 0x00)| (SPI_PUSHR_EOQ_MASK) | SPI_PUSHR_TXDATA(d1));

    while(((SPI0_SR & SPI_SR_TCF_MASK) == 0));
    while(((SPI_SR_RFDF_MASK & SPI0_SR) == 0));

    SPI0_SR |= SPI_SR_RFDF_MASK;
    SPI0_SR |= SPI_SR_RFOF_MASK;

    SPI0_SR |= SPI_SR_TCF_MASK;
    SPI0_SR |= SPI_SR_TFFF_MASK;
    printf("the data write to addrs:%x\n",data);
    }

    /*Function memory_read() to read data from memory one byte at a time */

    uint32 spi_read(uint8 address)
    {
    SIM_SCGC6 |=SIM_SCGC6_DSPI0_MASK;
    uint8 rd1=0,rd2=0,rd3=0;
    unsigned long retVal=0;

    SPI0_PUSHR = ((SPI_PUSHR_CTAS(0x00)) | (SPI_PUSHR_PCS(63)) | (SPI_PUSHR_CONT_MASK) | SPI_PUSHR_TXDATA(address));

    while(((SPI0_SR & SPI_SR_TCF_MASK) == 0));

    while(((SPI_SR_RFDF_MASK & SPI0_SR) == 0));


    SPI0_SR |= SPI_SR_RFDF_MASK;
    SPI0_SR |= SPI_SR_RFOF_MASK;

    SPI0_SR |= SPI_SR_TCF_MASK;
    SPI0_SR |= SPI_SR_TFFF_MASK;
    printf("the data read frm msb:%x\n",rd3);
    SPI0_PUSHR = ((SPI_PUSHR_CTAS(0x00)) | (SPI_PUSHR_PCS(63)) | (SPI_PUSHR_CONT_MASK) | SPI_PUSHR_TXDATA(0x00));

    while(((SPI0_SR & SPI_SR_TCF_MASK) == 0));

    while(((SPI_SR_RFDF_MASK & SPI0_SR) == 0));
    rd3=SPI0_POPR;

    SPI0_SR|= SPI_SR_RFDF_MASK;
    SPI0_SR|= SPI_SR_RFOF_MASK;

    SPI0_SR|= SPI_SR_TCF_MASK;
    SPI0_SR|= SPI_SR_TFFF_MASK;
    printf("the data read frm middle:%x\n",rd2);
    SPI0_PUSHR = ((SPI_PUSHR_CTAS(0x00)) | (SPI_PUSHR_PCS(63)) | (SPI_PUSHR_CONT_MASK) | SPI_PUSHR_TXDATA(0x00));

    while(((SPI0_SR & SPI_SR_TCF_MASK) == 0));

    while(((SPI_SR_RFDF_MASK & SPI0_SR) == 0));
    rd2=SPI0_POPR;

    SPI0_SR |= SPI_SR_RFDF_MASK;
    SPI0_SR |= SPI_SR_RFOF_MASK;

    SPI0_SR |= SPI_SR_TCF_MASK;
    SPI0_SR |= SPI_SR_TFFF_MASK;
    printf("the data read frm lsb:%x\n",rd1);

    SPI0_PUSHR = ((SPI_PUSHR_CTAS(0x00)) | (SPI_PUSHR_PCS(0x00))| (SPI_PUSHR_EOQ_MASK) | (SPI_PUSHR_CONT_MASK & 0x00) | SPI_PUSHR_TXDATA(0x00));
    while(((SPI0_SR & SPI_SR_TCF_MASK) == 0));

    while(((SPI_SR_RFDF_MASK & SPI0_SR) == 0));
    rd1=SPI0_POPR;

    SPI0_SR |= SPI_SR_RFDF_MASK;
    SPI0_SR |= SPI_SR_RFOF_MASK;

    SPI0_SR |= SPI_SR_TCF_MASK;
    SPI0_SR |= SPI_SR_TFFF_MASK;


    retVal|= rd1;
    retVal = ((retVal << 8)|rd2);
    retVal = ((retVal << 8) |rd3);
    printf("data read from addrs:%x\n",retVal);
    return retVal;
    }

    register that i made changes and try to read 

  • Hi,

          Could you say me the clock frequency should used in afe4490?

    Thank you.

  • HI Kanimozhi,

    Looking at the waveform I have following comments.
    1) SPISTE line is pulled HIGH after the third byte, whereas it should be LOW for more than 4 bytes ( 1 register address, 3 data bytes). Refer to figure 1 and 2 in the datasheet for the SPI transactions.
    2) While reading the register you have to generate the SCLK for 4 bytes ( 1 register address, 3 data bytes). In your waveform you have SCLK for only one byte.

    Regards,
    Prabin