- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
I have some trouble in I2C. My I2C_I2CMasterSendStart() returns I2C_I2C_MSTR_ERR_LB_NAK. According to the description of the datasheet, this constant indicates "Last byte was NAKed". I don't know how to solve this problem. Can you help me?
My I2C master is PSoC 4 BLE and slave is MAX30100(here is datasheet link, https://www.maximintegrated.com/en/products/analog/sensors-and-sensor-interface/MAX30100.html)
Here is code that I try to read temperature value:
static uint16 temp1,temp2;
static double temp = 30;
// Mode Configuration
I2C_I2CMasterSendStart(0xae,I2C_I2C_WRITE_XFER_MODE); // MAX30100 WRITE ADDRESS is 0xae
I2C_I2CMasterWriteByte(0x06); //Mode Configuration's register address is 0x06
I2C_I2CMasterWriteByte(0x0a); // the value I write
I2C_I2CMasterSendStop();
// wait a momment
CyDelay(20);
// read integer value of temperature
I2C_I2CMasterSendStart(0xae,I2C_I2C_WRITE_XFER_MODE);
I2C_I2CMasterWriteByte(0x16); //Integer Value's reg_addr is 0x16
I2C_I2CMasterSendRestart(0xaf,I2C_I2C_READ_XFER_MODE); //MAX30100 READ ADDRESS is 0xaf
temp1 = I2C_I2CMasterReadByte(I2C_I2C_NAK_DATA); // read integer value
I2C_I2CMasterSendStop();
// read fraction value of temperature
I2C_I2CMasterSendStart(0xae,I2C_I2C_WRITE_XFER_MODE);
I2C_I2CMasterWriteByte(0x17); //Fraction Value's reg_addr is 0x17
I2C_I2CMasterSendRestart(0xaf,I2C_I2C_READ_XFER_MODE);
temp2 = I2C_I2CMasterReadByte(I2C_I2C_NAK_DATA);
I2C_I2CMasterSendStop();
temp = temp1 + (temp2 / 100);
CyDelay(100);
Any guidance would be greatly appreciated! Thank you.
Solved! Go to Solution.
- Labels:
-
BLE
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Welcome in the forum.
Your slave address is wrong. I2C uses 7-bit addresses and an additional bit indicating read or write access. This bit is inserted automatically.
So your address should read 0x57
Keep in mind that most of the APIs (except those for reading a byte) return a status byte which, when non-zero indicate an error condition. I always suggest to check those values at least while debugging.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Welcome in the forum.
Your slave address is wrong. I2C uses 7-bit addresses and an additional bit indicating read or write access. This bit is inserted automatically.
So your address should read 0x57
Keep in mind that most of the APIs (except those for reading a byte) return a status byte which, when non-zero indicate an error condition. I always suggest to check those values at least while debugging.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,Bob
Thanks for your advice, my master device could read temperature value.
Wang
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You are always welcome, Wang.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Can you please post your complete project, so that we all can have a look at all of your settings. To do so, use
Creator->File->Create Workspace Bundle (minimal)
and attach the resulting file.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
All I2C functions except I2CMasterReadByte() deliver a status that indicates an error when non-zero. I strongly suggest to check for that at least until the project runs correctly.
Easiest will be to put your writes and reads into functions.
Provide a function void I2CError(void) and change all your I2C functions except I2CMasterReadByte() to
if(I2CMasterfunction(..) != 0) I2CError();
Now you can set a breakpoint in I2CError and check with the call stack window where the error happened.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Welcome in the forum, Wang Sen.
I do not have got your temp-measure device, so I can only have a look.
Every I2C_I2CMasterxxx() API returns a status byte which when non-zero indicates an error . so you can see when debugging which of your calls hang.
I would suggest some more changes:
Set UART to byte mode and increase read and write buffers to 80.
The line
temp = temp1 + (temp2 / 100);
will not work as expected: Temp is a float and thmp1 and temp2 are 16 bit integers. Change them to int8 and
temp = (double)temp1 + ((double)temp2 * 0.0625); // See datasheet page 23
Datasheet shows that registers for temperature are 0x1f and 0x20, am I wrong with that?
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Congratulations!
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hey, can you suggest us what could be the possible changes in the above project for SpO2 implementation using the same sensor i.e MAX30100?