I2C Master Read

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

 Hi guys, 

                       

I have a peculiar problem, which is driving me insane!     

 

   

I have created a function that is able to read back I2C which includes a 16 bit subaddress.     

 

   

In my case I need to read back 4 bytes of the subaddress where the value of the 4th byte will be a value of 0, 1 or 2.     

 

   

 

   

if(sleep_counter > 50){     

 

   

sleep_counter = 0;     

 

   

      readData = I2C_1_DSP_MASTER_READ(DEVICE_ADDR_IC_1, MOD_AUDIO_DETECT_DETECT_REG_READBACKALGSIGMA2001_ADDR, 4);     

 

   

                                  

 

   

      if(readData == 2 ){     

 

   

      //Do something    }     

 

   

      else if(readData == 1 ){     

 

   

      //Do something    }     

 

   

      else if(readData == 0){     

 

   

      //Do something        

 

   

}     

 

   

}     

 

 

   

Where the read function is as follows:     

 

   

uint8 I2C_1_DSP_MASTER_READ(uint8 slavechip, uint16 regAddress, uint8 cnt ){     

 

   

uint16 msb = (regAddress >> 8);     

 

   

uint16 lsb = regAddress;     

 

              

 

   

uint8 i;     

 

   

volatile uint8 status;     

 

   

uint8 rdData[4];

   

     

 

   

status = DSP_I2CMasterSendStart(slavechip, DSP_I2C_WRITE_XFER_MODE);     

 

   

if(status == DSP_I2C_MSTR_NO_ERROR) /* Check if transfer completed without errors */     

 

   

{     

 

   

      // Send register address     

 

   

      status = DSP_I2CMasterWriteByte(msb);     

 

   

      while(status != DSP_I2C_MSTR_NO_ERROR);// break;     

 

                      

 

   

      status = DSP_I2CMasterWriteByte(lsb);     

 

   

      while(status != DSP_I2C_MSTR_NO_ERROR);                   

 

   

}     

 

   

status = DSP_I2CMasterSendRestart(slavechip, DSP_I2C_READ_XFER_MODE);     

 

 

   

if(status == DSP_I2C_MSTR_NO_ERROR) {     

 

   

/* Read array of cnt bytes */     

 

   

      for(i=0; i<cnt; i++)     

 

   

      {     

 

   

      if(i < (cnt))rdData=DSP_I2CMasterReadByte(DSP_I2C_ACK_DATA);     

 

   

      else rdData = DSP_I2CMasterReadByte(DSP_I2C_NAK_DATA);       

 

   

      }     

 

   

}     

 

   

DSP_I2CMasterSendStop(); /* Send Stop */     

 

   

DSP_I2CMasterClearReadBuf();     

 

       

 

   

return rdData[3];     

 

   

}     

 

   

 

   

Every time I read back from the register I get the expected four bytes, verified by using a logic analyzer.  However, there are two strange things that happen.     

 

   

 

   

1) Even when the 4th byte of the array stays the same, hence return rdData[3] should always return the same value, this is not the case. First time I2C_1_DSP_MASTER_READ()is called the correct value is returned, every time after that it returns 0     

 

   

 

   

2) The first time I2C_1_DSP_MASTER_READ  is called the logic analyzer shows the four bytes returned with ACK, in addition a 5 byte of 0x00 and NACK is seen. Everytime after that 4 bytes only are returned, but the 4 byte is now accompanied by a NACK. Please see attachment. (please note that even if I increase cnt to 5 so that the four bytes are always acknowledged, the return value is still wrong after the first read.     

 

   

 

   

Any help would be very much appreciated!     

 

   

 

   

All the Best,     

 

   

Katrine     

 

   

 

   

 

0 Likes
5 Replies
Anonymous
Not applicable

 Alright - resorted by this slight alteration:

   

/* Read array of cnt bytes */

   

for(i=0; i<cnt; i++)

   

{

   

if(i < (cnt-1))rdData = DSP_I2CMasterReadByte(DSP_I2C_ACK_DATA);

   

else rdData = DSP_I2CMasterReadByte(DSP_I2C_NAK_DATA);

   

 

   

}

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

Did you resolve your issue ?

0 Likes
Anonymous
Not applicable

 Yes, applying the slight change in the previous message solved the issue I was seeing.

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

I frequently use

   

/* Read array of cnt bytes */

   

for(i=0; i<cnt; i++)

   

{

   

rdData = DSP_I2CMasterReadByte(i < (cnt-1))?DSP_I2C_ACK_DATA:DSP_I2C_NAK_DATA;

   

}

   

 

   

although I do not like the "?" operator, but here it is my favorite.

   

 

   

 

   

Hoping that forumSW doesn't clobber the lines

   

Bob

0 Likes
Anonymous
Not applicable

 Thank you for sharing Bob 🙂

0 Likes