I2C Slave Interesting Results

dellarb

New Member
Hi all

I have ventured into the world of ram sharing using the hi2csetup in slave mode on some of my X2 parts. Generally it worked really well but I have noticed some odd behaviour from the slave chip. If I ask the slave chip to perform any tasks like receive serial data it seems to shut down the I2C slave function completely and not restore it. The master then just gets 255 as a result for any request for data from the slave.

Just curious if someone in the know can confirm which commands will affect the I2C slave mode. The manual suggests it will work all the time regardless of other tasks the slave is performing but my experimentation doesn't back that up.

Thanks in advance :)
 

hippy

Ex-Staff (retired)
Manual 2 page 222 lists potentially conflicting commands and includes I2C Slave operation, but I expect we will reconsider the phrasing on page 60.

Unfortunately it's simply not possible on a single core processor to do two things at once. It's a akin to having gone shopping when a courier arrives to collect a parcel to be sent; you simply cannot be there to answer the door at the same time.

Basically any time sensitive commands where the PICAXE has to dedicate itself to the instructed task could inhibit I2C Slave during that time.

It should be possible to re-establish I2C comms after a failure and this could be a case of, as per previous example, the courier always turning up when you are out shopping, When you go shopping or when the courier turns up has to alter or there won't be a time when collection is possible.

It would be useful to indicate which PICAXE types are used as master and slave, and to post your complete code for each, so that the isuue can be looked at in more detail.
 

dellarb

New Member
Ah good to see it wasn't me doing something wrong. I guessed it might be the case that other tasks could affect it. It's fair enough some tasks can affect it, thought it seemed a bit too good to be true in the manual. :)

I'm using a 28X2 as the master and 20X2 as the slave. One easy-ish way of getting around the problem I'm trying out is to have the Master check a byte in the slave memory that is never =255. If it sees it as 255 then it knows I2C is not enabled and don't input the data. This code which now works is below, hopefully it might help someone. Seems to work ok will have to see how it scales in a larger program that is using the data.

Master Code
Code:
setfreq em32
hi2csetup i2cmaster, %10100100,i2cfast_32,i2cbyte		'20X2 Code

do
gosub loadgps
loop

loadgps:
	hi2cin 0,(b55)
	if b55 = 255 then	
		return	'Checks if 20X2 is in I2c Mode (If not then 255 will be returned)
	endif
	ptr = 0
	hi2cin 0,(@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc)
	gosub downlinkgps ' This is just code to send the data to the terminal not relevant to the discussion
return
Slave Code
Code:
setfreq m64
hi2csetup i2cslave, %10100100

do
       gosub getgps
loop

getgps:

	
	ptr = 78		' get 50 bytes
	serin [1000,nogps],b.6,T38400_64,("RMC,"),@ptrinc,@ptrinc,@ptrinc, ' This continues for 50 bytes but if I put them all here it makes the forums way too wide


'The rest of the code in this subroutine is just normal maths that turns the GPS data into easier to store variables

return
 

hippy

Ex-Staff (retired)
Thanks for the code. The trick of reading a slave location which should be non-255 and seeing if it is 255, and if so treating it as I2C unavailable, is a good one.

I think the main issue may be that the slave is spending most of its time waiting for GPS data in SERIN and while doing that is not able to handle I2C requests. I2C data can only then be taken from the slave in the periods it is not executing the SERIN.

A solution would be to read the GPS data, set the slave scratchpad ready for transfer then mark a location in scratchpad that data has been received, is ready and waiting, say by writing a 1 value ( initialised to 0 to indicate no data yet ).

The master can read that location, if 255, it knows there is an issue and cannot obtain the data, when it is 0 knows there is no data, when it is a 1 it can then read the data and set the flag to 0.

The slave waits for the scratchpad byte previously set to 1 to be reset back to 0 by the master, then gets the next GPS data with SERIN.

This 'software handshaking' would also avoid any situation where the master starts to fetch I2C data from the slave just as the I2C slave enters SERIN. In that case it may be possible that while the initial check for I2C availability and earliest data bytes are returned correctly, later data bytes may become inaccessible and return as 255.

Similar handshaking can be used when writing to a slave, and where a slave is both producing and consuming I2C-passed data. Basically it's establishing and protecting I2C communications when they occur to not be interfered with by commands which could disrupt that communication until it completes.

The only issue to watch for - which should normally only apply when both reading and writing to a slave - is 'deadlock' which can occur if one is waiting for acknowledgement or permission for one thing while the other is waiting for acknowledgement or permission of another, and neither will ever get either. This can usually be avoided by appropriate program design.
 

dellarb

New Member
Thanks for that Hippy. Excellent advice as always. Have not got that style code working where the two chips operate in lock step. Will see how it scales once each is running more complex code
 
Top