- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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);
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Did you resolve your issue ?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes, applying the slight change in the previous message solved the issue I was seeing.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you for sharing Bob 🙂