10 Replies Latest reply on Jul 18, 2019 7:37 AM by joli_601446

    I2C Master Read

    joli_601446

      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

       

       

        • 1. Re: I2C Master Read
          joli_601446

          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

          • 2. Re: I2C Master Read
            joli_601446

            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

            • 3. Re: I2C Master Read
              NoriakiT_91

              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

              • 4. Re: I2C Master Read
                NoriakiT_91

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

                 

                Regards,

                Noriaki

                • 5. Re: I2C Master Read
                  MoTa_728816

                  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

                  • 6. Re: I2C Master Read
                    joli_601446

                    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

                    • 7. Re: I2C Master Read
                      MoTa_728816

                      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

                      • 8. Re: I2C Master Read
                        joli_601446

                        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

                        • 9. Re: I2C Master Read
                          MoTa_728816

                          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

                          • 10. Re: I2C Master Read
                            joli_601446

                            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