i2c flow control

Has anyone seen any simple flow control techniques for i2C?

I have a picaxe 20x2 acting as an i2c LCD. The 20x2 is in slave mode and simply receives and passes on to the LCD command and text streams sent by the i2cMaster, but it takes the Slave and LCD a little while to execute the display requests.

Flow control is achieved for now by the Slave device setting a busy/not busy flag in it's scratchpad memory where the Master can read it. The problem is that at the Master end I need a function allowing the Master to hang about for a bit if the slave is busy but not allowing the Master to get itself locked up. In my case the Master is also picaxe and it has plenty of other time related tasks to get on with.

A way round this is of course to use a cyclic/ring buffer.

Would appreciate any views, experience or shortcut ideas.
 

BeanieBots

Moderator
How about Xon/Xoff signals?
When the receiver sends an Xoff, go off and 'do something else' and then start sending again even if Xon is not received.
Of course, that assumes that the receiver can receive a certain amount before loosing data.
 

Buzby

Senior Member
Hi Hundred,

There is nothing at all wrong with your method of having a 'busy' flag in the Slave, it's the way I always do it.
Your challenge is what the Master should do while the Slave is busy.

One method is to buffer the requests in the Master, and only send when the Slave is not busy.
This is quite easy if your PICAXE can multi-task. It's a bit trickier if you can only single-task.

If you post your Master code we can get a better idea of how to advise.

Cheers,

Buzby
 

oracacle

Senior Member
i have some kicking around for a project that will be restarted shortly now that cash flow issue are resolving themselve, heres a snipet, i a single sub procedure, it will change for error coding as well as busy signal but may give you an idea

Code:
check:
'##################################################################################################################
'###this sub will check and hold until ready flag is given. doesnt currently show any error, may need to updated###
'##################################################################################################################
	hi2cin 0,(b23)								'check for ready flag
	if b23 = 1  then check							'if not ready then loop
	return									'return if ready
you dont have to use b23 for storing the flag, nor do you need to use 1,
 
Thanks for the comments. Since my post I thought more about the problem. Also I found this earlier post http://www.picaxeforum.co.uk/entry.php?102-20x2-for-Picaxe-OLED-Driver-Hardware-Serial-I-o-Circular-buffer-Line-mapping.

My first implementation test example where I was just exploring using i2c for the LCD just looked a mess. It can be tidied up but it is never going to look good when the code keeps having to drop into a test-and-wait loop structure each time. Eg:

Code:
'send lcd setup protocol
hi2cout comm_type_field, (command_type,$28,$0C,$01,eot)

waitforready:
hi2cin 0,(b1)
if b1 <> $FF then goto waitforready

hi2cout comm_type_field, (display_type,"Help is",eot)

waitforready1:
hi2cin 0,(b1)
if b1 <> $FF then goto waitforready1

hi2cout comm_type_field, (command_type,$c0,eot) 'switch to line 2

waitforready2:
hi2cin 0,(b1)
if b1 <> $FF then goto waitforready2

hi2cout comm_type_field, (display_type,"Coming",eot)
The problem with a flag based protocol is that it essentally passes the problem back up the line - somewhere you just have to say "no more data". This can be aleviated by keeping a buffer of data waiting to be transmitted and then sending it when the flag indicates clear. Managing this buffer is itself comparable with the management of a circular buffer so why not just go straight to the latter as a solution.

It seems to me that i2c going from Master to Slave is ideal for this because it naturally uses the Slave Scratchpad as the buffer area. The slight downside is that the 20x2 only has 128 bytes of scratchpad and anything larger needs word addressing. So I am proceeding by implementing a circular buffer between the Master and Slave. I will post an update.
 

inglewoodpete

Senior Member
I built a high-speed serial and i2c interface to Rev-Ed's Winstar OLED display. It used a 20x2 @ 64MHz as the dedicated driver, running as an i2c slave. It also has a memory-mapped routine for i2c that allows you to (virtually) write directly to any location on the screen from the master.

You mention that your setup runs a bit slow. The master does not spend much time waiting for this slave!

Master and slave code can be found here: http://www.picaxeforum.co.uk/showthread.php?23847-OLED-interface-with-High-Speed-Serial-i2c-and-Mapped-i2c
 
Inglewood and everyone - thanks for the input. I have been head down getting my circular buffer code to work and think I am almost there, apart that is from an i2c transfer reliability issue in my prototype setup which I know I am going to crack soon. I have made the code as simple as I can so that it is useful for purposes other than driving displays. It is a while since I last implemented a circular buffer and I had forgotten how compact the code ends up.

Debugging has proven interesting as two picaxes are involved and debug statements do not directly allow inspection of the scratchpad memory.

I will look carefully at Inglewood's code as I am especially interested in the memory mapping features. What I have now is the ability to send to the slave an escape character that put's the lcd into command mode in readiness for the next byte (ie the command byte). Otherwise all bytes are normally passed straight onto the lcd as text characters. Very simple.

Just to comment on the overall problem I am dealing with:

The application in my i2c Master is very busy reading switches, taking input from an RFID reader and communicating with a KNX building control bus to control alarms. When I want a message displayed locally (inside my unit) I want it sent simply and quickly - no hanging about testing readiness or anything, just assemble message and send - zap! However these messages do not happen often and the overall rate is well inside what an lcd controller can handle, so the Slave can take it's time just as long as the buffer is long enough to deal with the peaks.

Code to follow - once cracked!
 
Top