I2C Library Address Question?

General discussion relating to the library modules supplied with the compiler

Moderators: David Barker, Jerry Messina

Post Reply
TonyR
Posts: 75
Joined: Fri Jan 14, 2011 11:49 pm
Location: Sydney
Contact:

I2C Library Address Question?

Post by TonyR » Thu Jan 08, 2015 7:53 pm

I've used SF I2C library from time to time with success connecting to various I2C peripheral chips, sometimes by empirical testing. This time nothing working.

A Freescale MMA7660 Accelerometer refuses to reply to reads from the I2C.bas library and also SI2C.bas library on an 18F87J50.

The waveforms on SDA SCL look right, but no output from MMA7660 after writing the "read address" and waiting. I think the I2C is hanging due to software.

My question is, does the I2C.bas library shift the bits in the byte entered as an I2C slave address to the right to match the "master" address of the IC2 peripheral. Does it set/reset the RD/WR bit automatically in read calls?

ie. The MMA7660 "slave address" is given as $4C in their documentation. But they then say the "master write address" is $98 and "master read address" is $99.

In SF do I use the $4C or $99, $98. Do I need to add 1 to the slave address to do a read (like in SF Help examples), or does the read function do that automatically?

I guess it shifts the bits to create the master addresses but doesn't add the one to do a read? Confused!

User avatar
Coccoliso
Posts: 152
Joined: Mon Feb 17, 2014 10:34 am

Re: I2C Library Address Question?

Post by Coccoliso » Thu Jan 08, 2015 8:48 pm

Hello,
I got the same question time ago for the PCF8574 and I solved so ..

Code: Select all

Public Function ReadPCFData() As Byte
    Start
    WriteByte(DevAddr + 1)
    result = ReadByte
    Stop
End Function

Code: Select all

Public Sub WritePCFData(CurrV As Byte) 
    Start
    WriteByte(DevAddr)
    WriteByte(CurrV)
    Stop        
End Sub
.. at this point I think that most of I2C devices have this peculiarity because even in the case of RTC (source DS1307.bas) the same thing happens.

Code: Select all

Sub RTCStartWrite(Address As Byte) 
   I2CStart
   I2CWriteByte(RTC_DEV_ADDR)
   I2CWriteByte(Address)        
End Sub

Code: Select all

Sub RTCStartRead(Address As Byte)
   RTCStartWrite(Address)
   I2CRestart
   I2CWriteByte(RTC_DEV_ADDR + 1)
End Sub

TonyR
Posts: 75
Joined: Fri Jan 14, 2011 11:49 pm
Location: Sydney
Contact:

Re: I2C Library Address Question?

Post by TonyR » Thu Jan 08, 2015 9:57 pm

Thanks Coccoliso I'll give your suggestions a try.

The last I2C device worked fine with the code below, but the MMA7660 refuses.

Code: Select all

Public Function ReadDeviceRegister(I2C_Address As Byte, Register As Byte) As Byte
'
' point to Register
'  
I2C.Start                          
I2C.WriteByte(I2C_Address) 
I2C.WriteByte(Register)  
I2C.Stop 
'
' Read Register 
'      
I2C.Restart                         
I2C.WriteByte(I2C_Address + 1) 
ReadDeviceRegister = I2C.ReadByte
I2C.Acknowledge(I2C_NOT_ACKNOWLEDGE)      ' doesn't make any difference in or out to running loop
I2C.Stop

End Function



Jerry Messina
Swordfish Developer
Posts: 1469
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Re: I2C Library Address Question?

Post by Jerry Messina » Thu Jan 08, 2015 10:05 pm

With that function, set I2C_Address = $98 to write, and $99 to read. WriteByte doesn't know if it's sending an addr or a data byte, so it doesn't shift or add anything.

Try removing the 'I2C.Stop' before you call I2C.Restart

Jerry Messina
Swordfish Developer
Posts: 1469
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Re: I2C Library Address Question?

Post by Jerry Messina » Fri Jan 09, 2015 12:27 am

I could have bit a bit clearer in that previous post... what I meant to say was that the address value needs to be $98 to write and $99 to read, so you would pass a value of I2C_Address=$98 to that function.

I think getting rid of the STOP call will fix things...
If a STOP condition is detected after just the register address is received, then MMA7660FC takes no action. See Figure 12. MA7660FC clears its internal register address pointer to register 0x00 when a STOP condition is detected, so a single byte write has no net effect because the register address given in this first and only byte is replaced by 0x00 at the STOP condition. The internal register address pointer is not , however, cleared on a repeated start condition.

TonyR
Posts: 75
Joined: Fri Jan 14, 2011 11:49 pm
Location: Sydney
Contact:

Re: I2C Library Address Question?

Post by TonyR » Fri Jan 09, 2015 1:47 am

I tried your suggestion Jerry and it works, thanks!

With $98 as write address and $99 as read address. This is with MMA7660 and 18F87J50.

What I don't understand is the last part I interfaced which was a 3 axis magnetometer HMC5883 to an 18F87J93. It worked fine using the so called "slave address", in its case $3C, just like in the SF help examples. But in this case I dont use the "slave address" but use the "master" address.

Im not complaining, Im thanking the Universe, and your suggestion.

My test loop that works is

Code: Select all


Const I2C_Address = $98

While true
 
I2C.Start
I2C.WriteByte(I2C_Address)
I2C.WriteByte(0)               
I2C.Restart                         

I2C.WriteByte(I2C_Address + 1)
X1 = I2C.ReadByte
I2C.Acknowledge(I2C_NOT_ACKNOWLEDGE)
I2C.Stop

USART2.Write ("Data ", DecToStr(X1), 13, 10)

Wend


Jerry Messina
Swordfish Developer
Posts: 1469
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Re: I2C Library Address Question?

Post by Jerry Messina » Fri Jan 09, 2015 10:49 am

Glad you got it working.
What I don't understand is the last part I interfaced which was a 3 axis magnetometer HMC5883 to an 18F87J93. It worked fine using the so called "slave address", in its case $3C, just like in the SF help examples. But in this case I dont use the "slave address" but use the "master" address.
I think that's because according to the datasheet on the HMC5883 the 7-bit I2C address of the device is actually $1E

From the datasheet:
These pointer locations are sent from the master to this slave device and succeed the 7-bit address (0x1E) plus 1 bit read/write identifier,i.e. 0x3D for read and 0x3C for write
Don't feel bad... this is always confusing to me too. I'm never sure which way around they're specifying the address byte. One hint is that if you ever see the LSB set to 1 then you know they're talking about a full 8-bit value since that bit is the R/W bit and not part of the address.

Post Reply