Generating an "I2C Restart" condition.

AllyCat

Senior Member
Hi,

I guess I should be able to "research" this myself, but I'm getting lazy in my old age. :)

I want to read I2C data from a VEML6075 into an 08M2 and the data sheet helpfully shows that the required format of bytes for reading data (words) is as follows:

Slave Address : Command : Slave Address : Low Data byte : High Data byte ; (where the bold is sent by the master and the "Command" is just a register number).

It seemed strange that the Slave Address is repeated, but the data sheet explains that this is an "I2C Restart Condition" (normally intended to prevent the master relinquishing the bus). The term "Restart" does not appear to occur in the PICaxe "I2C Tutorial" Manual. Is this format supported in (M2) PICaxe Basic, and if so how?

Thanks, Alan.
 

edmunds

Senior Member
I2C Restart Condition:
Pull the clock line low, then Release the data line.
Release the clock line. Pull the data line low for a restart.

PICaxe supports this, for 40X2 hardware it is data sheet page 225.


Cheers,

Edmunds
 

AllyCat

Senior Member
Hi,

Thanks. Yes, I was aware of the PIC data sheet, but I was trying to avoid having to bit-bang the I2C, or work out how to use SFR commands with the chip hardware.

Therefore, I finally did a little "research" and believe I've found a solution. The requirement is to send 3 bytes to the Slave before waiting for the (two) reply bytes. So I looked at the I2CWORD mode which sends 2 bytes to the "control" or register address, apparently High Byte first (e.g. for a 512k bit serial EEPROM). The trick is to send the register number as the "High Address" byte and then the (repeated) Slave Address (with the lsb set to 1 to initiate the Read) as the "Low Address" byte.

The following example instructions do receive the correct Device code (38 = $26) and the data values do increase through 256 (i.e. with the High byte) when higher illumination is applied. Also the "integration time" does appear to be changing with the configuration bits, but the relative channel sensitivies are rather "unexpected", so more testing is required.
Code:
hi2csetup I2CMASTER , $20 , I2CSLOW , I2CWORD           ; Master , Slaveaddr , Speed , Command_length
i2cread $C21 , (b24 , b25)                                ; Device Code = Register 12
i2cread $721 , (b14 , b15)                                ; UVA = Register 7
i2cread $921 , (b18 , b19)                                ; UVB = Register 9
etc.
Cheers, Alan.
 

hippy

Technical Support
Staff member
You do possibly seem to have found a solution though what you are sending is a little different to what the datasheet indicates should be sent.

What is expected -
Code:
          .-.-----.-----.-.-----.           .-.
Sending   |S| $20 | $0C |R| $21 |           |P|
          `-^-----^-----^-^-----+-----.-----+-'
Receiving                       | lsb | msb |
                                `-----^-----'
What I expect is happening, though I am not sure if I2CREAD sends a Start or a Repeated Start -
Code:
          .-.-----.-----.-----.-.-----.           .-.
Sending   |S| $20 | $0C | $21 |S| $21 |           |P|
          `-^-----^-----^-----^-^-----+-----.-----+-'
Receiving                             | lsb | msb |
                                      `-----^-----'
And I guess you are just being lucky that the $21 after $0C is being ignored. You should be able to get it closer to what the spec calls for by using I2CBYTE instead of I2CWORD addressing -
Code:
          .-.-----.-----.-.-----.           .-.
Sending   |S| $20 | $0C |S| $21 |           |P|
          `-^-----^-----^-^-----+-----.-----+-'
Receiving                       | lsb | msb |
                                `-----^-----'
 

AllyCat

Senior Member
Hi,

Thanks hippy. Yes, I have discovered this morning that it is not all working entirely "as expected". In particular, reading back the control register (0) always gives $21 (the slave address) rather than the written byte (typically $10), which I believe is being received correctly.

I can't look at this for some hours now, and I'm not sure how to use the I2CBYTE configuration to generate the format you show; maybe I'll have to get out my (Chinese) logic analyser (and see if it still works with Windows 10).

Cheers, Alan.
 

hippy

Technical Support
Staff member
I'm not sure how to use the I2CBYTE configuration to generate the format you show
Code:
hi2csetup I2CMASTER , $20 , I2CSLOW , I2CBYTE
HI2cIn $0C, ( b0, b1 )
SerTxd( #w0 )
Should hopefully show the 38 ($0026) from the ID register.

HI2CIN ( and I2CREAD ) should work because they are intended to work with I2C EEPROM which use a two-part process for reading; first an I2C write ($20) and the address ($0C), then an I2C read ($21) with data immediately received.

The only way to tell an I2C EEPROM where to read from is to do an initial write with the address but no data. Then do a read without any address.

The VEML6075 command code could be considered an address for an EEPROM type device. In fact the only difference between the VEML6075 and a byte addressed EEPROM seems to be that the VEML6075 insists it must be a Repeated Start and not a Stop, which precludes a normal Start because that would normally have a Stop preceding it -
Code:
     ____             _____             ____
SDA  . . |____   ____| . . |____   ____| . .
     _________   _______________   _________
SCL  . . . . .   . . . . . . . .   . . . . .

      Start      Stop then Start     Stop
Code:
                     _____
SDA              ___| . . |_____
                        ________
SCL              ______| . . . .

                 Repeated Start
As stated I don't know if the PICAXE generates a Start ( Stop then Start ) or a Repeated Start. In most cases it doesn't seem to matter, either works and they can be considered the same.

I'd be tempted to run this code and see if it generates any fail reports. If not I would say it's working -
Code:
HI2cSetup I2CMASTER, $20, I2CSLOW, I2CBYTE
Do
  For b2 = $00 To $0B
    HI2cIn b2, ( b0, b1 )
    If w0 <> 0 Then : SerTxd( "fail" ) : End If
  Next
  HI2cIn $0C, ( b0, b1 )
  If w0 <> $0026 Then : SerTxd( "FAIL" ) : End If
  SerTxd(".")
Loop
 
Last edited:

AllyCat

Senior Member
Hi,
HI2CIN ( and I2CREAD ) should work because they are intended to work with I2C EEPROM which use a two-part process for reading; first an I2C write ($20) and the address ($0C), then an I2C read ($21) with data immediately received.
Thanks hippy, that's a detail I couldn't find documented anywhere. The Repeated Start (Restart) is only required for multi-master systems, which I guess are quite rare.

The Device Code (38) proved relatively "easy" to read, with both I2CBYTE and I2CWORD; it's the "real" data that was more "suspicious", but perhaps the Configuration byte was wrong. It appears to be the only (documented) R/W register and with an address (and default value) of "0" there's a fair chance of it working (or not), as much by luck as by judgement. The data sheet also seems inconsistent as to whether the High byte should be "$00" or "$20" (I've only seen zero so far).

The data sheet also refers to "A Photodiode" and "UV Integration Time" whilst it actually has four independent channels (for different optical wavelengths, but only two are strictly "UV"). I don't know if the measurements are made consecutively or concurrently and when the data is "buffered" (latched); however, I do usually get a set of different values on the "first pass"of the program.

Thus, I've quite a lot of "configurations" to test, when I can next connect the hardware to my PC (some things just can't be done on the Simulator. ;) ).

Cheers, Alan.
 
Top