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.
joli_601446
Level 5
Level 5
10 likes given 10 sign-ins 5 sign-ins

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.

I2C_View.jpg

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

0 Likes
1 Solution
lock attach
Attachments are accessible only for community members.

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

View solution in original post

10 Replies
lock attach
Attachments are accessible only for community members.
joli_601446
Level 5
Level 5
10 likes given 10 sign-ins 5 sign-ins

Here is the I2C Protocol for the MAX6581 Temperature Sensor:

MAX6581_I2C_Link.gif

I'm trying to determine if what I'm doing in the PSOC that may be incompatible with the device but I don't see what I'm doing wrong.

Thank you for helping me,

Joe

0 Likes

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.

I2C_Linkview.jpg

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

0 Likes

As described in the "Figure 2. SMBus Protocols" the MASTER device should respond to the READ byte with "NOT ACKNOWLEDGED"

Regards,

Noriaki

0 Likes
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

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

000-TeraTerm.JPG

I touched the sensor in the middle.

moto

0 Likes

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

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

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

0 Likes

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

MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

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

0 Likes
lock attach
Attachments are accessible only for community members.

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

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.

GS004340.png

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

0 Likes