- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello, I'm working on an small I2C program that will interface with a temperature sensor. The sensor has 8 registers that I need to read. Here is what I have so far:
TempI2C_Start(); // start the I2C Master Module
TempI2C_MasterClearStatus();
MStatus = TempI2C_MasterSendStart(TEMP_I2C_SLAVE_ADDR, TempI2C_READ_XFER_MODE);
if(TempI2C_MSTR_NO_ERROR == MStatus) // check for error
{
TempI2C_MasterWriteByte(MANUF_ID); // address: manufacturers ID from device
TempI2C_MasterSendRestart(TEMP_I2C_SLAVE_ADDR, TempI2C_READ_XFER_MODE);
TempRd_Buffer[0] = TempI2C_MasterReadByte(TempI2C_ACK_DATA); // read manufacturers ID from device
TempI2C_MasterSendStop();
}
The problem I have is after function:
MStatus = TempI2C_MasterSendStart(TEMP_I2C_SLAVE_ADDR, TempI2C_READ_XFER_MODE);
MStatus is 3 which means the last byte was NAK.
Since MStatus is a 3 the rest of the code doesn't execute. I don't understand why and hope someone can give me some help. I've uploaded my project. The function is located in the TempSensor.cpp file.
Thank you very much,
Joe
Solved! Go to Solution.
- Labels:
-
PSoC 5LP
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I got things working!
Thank you very much for everyone giving me help along the way and not giving up on me.
I have attached my design for those looking for an example on SPI and I2C.
I2C Temperature Sensor MAX6581
SPI GPIO Expander XRA1403
Again, thanks to all who helped me.
Joe
- 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
Well I'm making progress, I found out that my I2C Slave address was incorrect. Now I'm getting ACK instead of NAK which I think is better.
Quick question, on my MasterReadByte do I need to send a NAK or an ACK back? I see in the I2C Master/Multi-Master/Slave page 38 top of the page they have NAK on the last read. Do I need to do the same with a single read?
Thanks,
Joe
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
As described in the "Figure 2. SMBus Protocols" the MASTER device should respond to the READ byte with "NOT ACKNOWLEDGED"
Regards,
Noriaki
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
As I was writing sample, I'm a little bit slow.
(I used CY8CKIT-059)
I think that at first you need to send "WRITE" for register address, then restart and read.
I modified your function as follows
======================
int myI2C_ReadByte(uint8_t reg_addr)
{
uint8_t MStatus ;
// TempI2C_Start(); // start the I2C Master Module
TempI2C_MasterClearStatus();
// MStatus = TempI2C_MasterSendStart(TEMP_I2C_SLAVE_ADDR, TempI2C_READ_XFER_MODE);
MStatus = TempI2C_MasterSendStart(TEMP_I2C_SLAVE_ADDR, TempI2C_WRITE_XFER_MODE) ;
if (TempI2C_MSTR_NO_ERROR == MStatus) {
TempI2C_MasterWriteByte(reg_addr); /* was MANUF_ID */ // address: manufacturers ID from device
MStatus = TempI2C_MasterSendRestart(TEMP_I2C_SLAVE_ADDR, TempI2C_READ_XFER_MODE);
}
if (TempI2C_MSTR_NO_ERROR == MStatus) {
TempRd_Buffer[0] = TempI2C_MasterReadByte(TempI2C_ACK_DATA); // read manufacturers ID from device
}
TempI2C_MasterSendStop();
return(TempRd_Buffer[0]) ;
}
======================
Then connected LM75B for test, the Tera Term Output was
I touched the sensor in the middle.
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi, thanks for helping me with my problem. I'm making progress but don't understand some things. On page 24 of the Max6581 datasheet it lists the Slave Address
1001 100 R/W
So that we be x9B for Read and 0x9A for Write.
Is that correct?
Which would be:
MStatus = TempI2C_MasterSendStart( 0x9B, TempI2C_WRITE_XFER_MODE) ;
But when I do this it gives a NAK and the MStatus is 3.
But if I use 0x4E as the Slave address things work and MStatus is 0.
Can you help clear things up for me?
Thank you very much,
Joe
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear Joe-san,
I think that this is very confusing part of I2C specification.
When they say 7bit address it means 100 1100
and the bus uses another bit to identify if it's read or write.
Therefore the "address" gets shifted 1bit left with the R/W as the LSB,
so on the bus we see 1001 1001 (read) 1001 1000 (write).
In the "mbed" world they use this 8bit address for slave address,
but most of other world we use only the 7bit as the address.
So if the address is 0x4E and read, we will write
TempI2C_MasterSendStart(0x4E, (1)) ; // read
which will send 0x9C (1001 100(1)) to the bus (SDA).
And if we wirte
TempI2C_MasterSendStart(0x4E, (0)) ; // write
I2C module will send 0x9B (1001 100 (0)) to the bus (SDA)
I wonder if I could explain right, but this the way
we have to deal with the I2C bus.
Best Regards,
18-Jul-2019
Motoo Tanaka
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Oops, I didn't look closely on page 1 of the datasheet. I am using the MAX6581TG9C which has a slave address of 0x9C. I will have to look into this more tomorrow. Thank you very much for your comments and suggestions. I am getting close.
Joe
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear Joe-san,
I've just read the first part of MAX6581 Datasheet.
They show "8bit" address of the devices.
So in your case, MAX6581TG9C+'s slave address is 0x9C (1001 110(0)) .
this include the R/W bit as LSB.
On the other hand, PSoC's API takes "7bit" address,
so you need to call
TempI2C_MasterSendStart((0x9C >> 1), READ_OR_WRITE_BIT) ;
For read
TempI2C_MasterSendStart((0x9C >> 1), 1) ;
which is same with
TempI2C_MasterSendStart(0x4E, 1) ;
For write
TempI2C_MasterSendStart((0x9C >> 1), 0) ;
which is same with
TempI2C_MasterSendStart(0x4E, 0) ;
Best Regards,
18-Jul-2019
Motoo Tanaka
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I got things working!
Thank you very much for everyone giving me help along the way and not giving up on me.
I have attached my design for those looking for an example on SPI and I2C.
I2C Temperature Sensor MAX6581
SPI GPIO Expander XRA1403
Again, thanks to all who helped me.
Joe
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
When the function TempI2C_MasterSendStart() is called the slave address is specified as an 8-bit address TEMP_I2C_SLAVE_ADDR=0x9Eu. But the function accepts a 7-bit slave address as described in the I2C datasheet.
So the I2C master sends 0x1E (the LSB 7-bits of 0x9Eu) and no slave devices respond.
The TEMP_I2C_SLAVE_ADDR should be set to (0x9Eu >> 1)
Please ensure the device part number which your are going to use. the MAX6581 has four part numbers with different slave address.
Regards,
Noriaki