Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Himpe V.I2C bus FAQ.Ver 1.6.1996

.txt
Скачиваний:
10
Добавлен:
22.08.2013
Размер:
120.84 Кб
Скачать
Newsgroups: SCI.ELECTRONICS,COMP.PROTOCOLS.MISC
Subject: I2c Bus FAQ Version 1.6
From: vincent.himpe@ping.be (Vincent Himpe)
Followup-To:POSTER

Archive-name: I2C-BUS-FAQ

This article is a collection of information sources on the i2c Bus

The following topics are addressed:

0) Preface

1) ABOUT THIS FAQ

1.1) Who put this FAQ together?
1.2) How can I contribute to this FAQ?
1.3) What newsgroups will this FAQ be posted to?
1.4) May I distribute this FAQ or post it somewhere else?
1.5) Other interesting FAQs

2) ABOUT I2C

2.1) Historical background
2.2) I2C Bus protocol
2.3) Hardware Layout
2.4) Events on the I2C Bus

2.4.1) Start and Stop condition
2.4.2) Putting something on the bus.
2.4.3) addressing a SLAVE chip.
2.4.4) What happens next ?
2.4.5) Writing one or more bytes to a SLAVE.
2.4.6) Reading one or more bytes from a SLAVE.
2.4.7) Determining the SLAVE acces mode
2.4.8) Combined data format

2.5) MultiMASTER operation
2.5.1) Bus synchronisation mechanism
2.6) Special addresses and exceptions
2.7) Electrical specs of the bus

3) Enhanced I2C (FAST mode)

4) Extended addressing (new I2C standard)

5) Q&A section

6) An I2C driver in Pseudocode

7) Debugging Tools

8) I2C interface system for IBM-PC

8.1) Hardware
8.1.1) Isolated Interface
8.2) Software
8.2.1) Quickbasic / PDs / PowerBasic Driver for I2C

9) Legal notes and Copyrights

A) ACCESS Bus

B) Address map

B.1) Overview of existing I2C components and their function

C) SOURCES OF INFORMATION ON I2C

C.1) FTP sites
C.2) Web pages about i2c
C.3) BBSs

D) I2C PRODUCTS

D.1) Free development tools
D.2) Commercially available products

E) I2C Documentation

E.1) Periodicals that have articles covering I2C
E.2) Books
E.3) Miscellaneous documentation

F) Troubleshooting



0) Preface


Hi and welcome to the Sixth edition of the I2C FAQ.

**** STILL HOT STILL HOT STILL HOT STILL HOT STILL HOT STILL HOT ****

Philips has an FTP site on the net with lots of I2C related
stuff.

FTP to ftp://ftp.inetbsystems.us.com/pub/Philips-MCU/bbs
This adress will change in the future.Check out .

For the Philips News letter subscribe to :
Philips-news@inetbsystems.us.com

Online Philips Datasheets in Acrobat format
http://server1.pa.hodes.com/ps/philips5.html ( this might be outdated )
http://www.semiconductors.philips.com/ps/philips5.html

General information
http://www.philips.com/products/

The Acrobat reader can be obtained from:
http://www.adobe.com/Software/Acrobat

**** HOT HOT HOT HOT HOT HOT HOT HOT HOT HOT HOT HOT HOT HOT ***

This release contains schematics and software listing to implement
I2C on you parallel port using Qbasic that comes with DOS.
Also some debugging tools are described in this FAQ.

On demand of Philips an entry on the copyrights and licences involved
with he use of the bus has been made to this FAQ.

Furthermore some bugs inside the Faq have been fixed .
Especially take care to read the sections on giving ACK and NACK again.
(this is for you who use the old faq (v1.5 and older))
This error was pointed out by Karl-Heinz Wietzke . Thanks Karl

This faq is archived on my Web Homepage.
When you log on select I2C

http://www.ping.be/~ping0751/I2C.HTM

The FAQ is archived.You can download it from :

FTP//fpt.uni.paderborn.de/elrad/020/


However the one on my homepage will be the most up to date version.

If you store the FAQ on a server or homepage please inform me.
That way i can add the server adresses to the list.

Hope its useful to you guys and girls out there.
Keep those reply's coming

Regards,

Vincent


As usual greetings go to :

Russ Hersh,Phil Wood,Philips PCALE Eindhoven,Stephen Phillips
Ian Willis,Kevin Gardner,Dave Heller,Karl-Heinz Wietzke,Sven Rymenants
and many others .

Special greetings go to:

Kevin Gardner 'The Copyright Section'
Tony Ayling for pointing out a bug in the PseudoCode driver.
Dave Heller ' The Philips FTP SIte
Karl-Heinz Wietzke for pointing out some error in the section 'Reading'
Sven Rymenants for the section about synchronisation


1) ABOUT THIS FAQ

1.1) Who put this FAQ together?

I put this FAQ together in response to my own frustration in searching
for information about I2C.I've been playing with the bus for some time
and , although i am not an expert on this matter, i think my , and
other people's, experiences with the I2C BUS can solve common problems.

1.2) How can I contribute to this FAQ?

If you have any suggestions or additions please inform me.

You can contact me :
By e-mail : Internet : Vincent.himpe@ping.be (preferred)
vi_himpe@mietec.be

By Snail-Mail : Vincent Himpe
A.De Taeyelaan 12
8792 Desselgem
Belgium


I hope that those of you who know of interesting items for this FAQ
will share with everyone by contributing to this list. A good amount
of stuff is turning up thanks to everyone's help.

If you are a manufacturer and have an anonymous ftp site or BBS
available that has information and/or tools for the I2C Bus please let
me know by EMail so that I can add it to this FAQ. Also, please feel
free to update me on new products.

1.3) What newsgroups will this FAQ be posted to?

This FAQ will be posted to the following newsgroups:
sci.electronics.design

These newsgroups often contain discussions, announcements, or
information about I2C. Check them out from time to time.

The schedule for posting will be once a month. I can't promise that
it will be on time, but I hope to post it by the end of each month.


1.4) May I distribute this FAq or post it somewhere else ?

I am putting no restrictions on the use of this FAQ except - It must
be distributed in its entirety with the copyright notice, and no
financial gain may be realized from it. After all, I have spent, and
continue to spend, a lot of time on this. The only thing that I
intend to gain from it is more information on I2C.

For this reason I have appended a copyright statement to the end of
this FAQ. I feel pretty silly doing this, but I just want to protect
myself. The copyright does not limit the use of this FAQ for
noncommercial purposes. I hereby give my permission to one and all
to pass this FAQ around and post it wherever you want - as long as
it is not for financial gain.

You are allowed to distribute portions of the FAQ as long as you
incorporate the following note.

: Taken from The I2C FAQ as posted in SCI.ELECTRONICS.

Thank you.


1.5) Other interesting FAQ's

Microcontroller FAQs

Subject: PIC microcontrollers
Newsgroups: comp.realtime
comp.robotics
sci.electronics
Maintainer: Tom Kellett
Tom@takdsign.demon.co.uk

Subject: 68hc11 microcontrollers
Newsgroups: comp.realtime
comp.robotics
sci.electronics
Archive: rtfm.mit.edu : <plus all mirror sites>
/pub/usenet/comp.answers/microcontroller-faq/68hc11
/pub/usenet/sci.answers/microcontroller-faq/68hc11
/pub/usenet/news.answers/microcontroller-faq/68hc11
Maintainer: Russ Hersch
Email: sibit@datasrv.co.il

Subject: Microcontroller primer and FAQ
Newsgroups: comp.sys.intel
comp.realtime
comp.robotics
sci.electronics
alt.comp.hardware.homebuilt
Archive: rtfm.mit.edu : <plus all mirror sites>
/pub/usenet/comp.answers/microcontroller-faq/primer
/pub/usenet/sci.answers/microcontroller-faq/primer
/pub/usenet/news.answers/microcontroller-faq/primer
Maintainer: Russ Hersch
Email: sibit@datasrv.co.il


Additional FAQs of interest

Subject: Robotics
Newsgroups: comp.robotics
Maintainer: Kevin Dowling
(412)268-8830
Email: nivek@ri.cmu.edu
Smail: Carnegie Mellon University
The Robotics Institute
Pittsburgh, PA 15213

Subject: Electronics
Newsgroups: sci.electronics
Comments: There are a number of FAQs available in this newsgroup
on various subjects. Among some of the subjects covered
are: LCDs, stepper motors, etc.

FAQ subject: Real-time
Newsgroups: comp.realtime, comp.answers, news.answers
Archive: rtfm.mit.edu : pub/usenet/comp.realtime
Maintainer: Mark Linimon
Lonesome Dove Computing Services
Roanoke, Virginia
Email: linimon@nominil.lonesome.com.

Subject: Motorola 68K microprocessor line
Newsgroups: comp.sys.m68k
Archive: bode.ee.ualberta.ca : pub/motorola/general
ftp.luth.se : /pub/misc/motorola/faq
file name of archive is m68kfaq?.zip (? is version)
Maintainer: Robert Boys - Ontario, Canada
Email: r.boys@genie.geis.com
or
fboys@uoguelph.ca

For more information on various microcontrollers and their features,
refer to the Microcontroller primer and FAQ listed above.


2) ABOUT THE I2C Bus


2.1) Historical background.

The I2C bus was developed in the early 1980's by Philips
semiconductors.It's purpose was to provide an easy way to connect a
CPU to peripherial chips in a TV-set.

Normal Computer systems use ByteWide buses to accomplish this task.
This results in lots of copper tracks on PCB's to route the Address
and datalines. Not to mention a bunch of address decoders and glue
logic to connect everything.In mass production items such as TV-sets,
VCR's and audio equipment this is not acceptable.Furthermore lots of
control lines implies that the systems is more susceptible to
disturbances by EMC and ESD.The research done by Philips Labs in
Eindhoven (The Netherlands) resulted in a 2 wire communication bus
called the I2C bus.

I2C is an acronym for Inter-IC bus.It's name literally explains it's
purpose: to provide a communication link between Integrated Circuits.

Nowadays the extent of the bus goes much further than Audio and Video
equipment.The bus is generally accepted in industry.Offsprings like
D2B and ACCESS bus find their ways into computer peripherals like
keyboards,mice,printers,monitors,etc... . The I2C BUs has been adopted
by several leading chip manufacturers like Xicor,SGS-Thomson,Siemens,
Intel,TI,Maxim,Atmel,Analog Devices.



2.2) I2C Bus protocol

The BUS physically consists of 2 active wires and a ground connection.
The active wires ,SDA en SCL,are both bidirectional.
Where SDA is the Serial DAta line and SCL is the Serial CLock line.

Every component hooked up to the bus has its own unique address whether
it is a CPU,LCD driver,memory,or complex function chip.Each of these
chips can act as a receiver and/or transmitter depending on it's
functionality.Obviously an LCD driver is only a receiver ,while a
memory or I/O chip can both be transmitter and receiver.
Furthermore there may be one or more BUS MASTER's.

The BUS MASTER is the chip issuing the commands on the BUS.
In the I2C protocol specification it is stated that the IC that
initiates a data transfer on the bus is considered the BUS MASTER.
At that time all the others are regarded to as the BUS SLAVEs.

As mentioned before , the IC bus is a Multi-MASTER BUS. This means
that more than one IC capable of initiating data transfer can be
connected to it. As MASTERs are generally microcomputers let's take a
look at a general 'inter-IC chat' on the bus.

Lets consider the following setup :

-------- ------------
| CPU |-----------o--------| I/O port |
-------- | ------------
| ------------
+--------| Memory |
------------
Case : The CPU wants to talk to the I/O port.

The CPU will issue a START condition
(see further on for description of all these conditions)
This acts as an 'ATTENTION' signal to all of the connected
ic's.ALL IC's on the bus will listen to the bus for incoming
data.

Then the CPU sends the address of the device he wants to
address.This takes 8 clock pulses. At this moment in time all
IC's will compare this address with their own.If it doesn't
match they simply do nothing and wait until the bus is released
by the STOP condition.If the address matches however the chip
will produce a responce on the ACKNOWLEDGE signal of the CPU.

The ACKNOWLEDGE signal is issued by the CPU.When the chip which
address matches sees the ACKNOWLEDGE on the bus it Pulls the
data line LOW. This is an indication to the CPU that there is
a chip with the wanted address on the bus.

Now the CPU can start transmitting or receiving data
In our case the CPU will transmit data.When all is done the
CPU will issue a STOP condition. This is a signal that the bus
has been released and that the IC's may expect another
transmission to start any moment.

We have had several states on the BUS right now :
START, address ,ACKNOWLEDGE ,DATA ,STOP. These are all unique
conditions on the BUS.Before we take a closer look into these i will
talk about the hardware of the BUS.This is necessary to understand what
physically is going on.


2.3 Hardware layout of the I2C bus.

As stated before the BUS consists of 2 active signal lines and a ground
potential. Internally in the chip the bus looks like this :


/| | The bus interface is built around an input buffer
--o< |--- | and an open drain or open collector transistor.
\| | | When nothing happens the bus lines are in the
o----O logic HIGH state. Note here that an external
| | PULL-UP resistor is neccessary.This is an error
| | that most beginners make.
|-- | To put something on the BUS the chip drives its
------| | output transistor , thus pulling the BUS to a LOW
|-- | level.
| | When the bus is IDLE ( nothing going on ) both
--- | lines are HIGH . The HIGH state is defined as NOT
/// | LOW (obvious isn't it) . What i mean here is that
you cannot set a voltage on the HIGH Level.
It depends on the supply voltage of the connected IC's.However as this
is mostly 5 Volts you can say that HIGH is 5 volts and LOW 0 volt.

Nowadays there even exist 3.3 volt ic's. It's clear that in this case
the high level will be 3.3 volts.

2.4 Events on the BUS

We have already mentioned some things like START,STOP,ACKNOWLEDGE,
SLAVE,MASTER and so on. In this section these things get explained.
When reading this you must keep the following 2 things in mind.

- A MASTER is the device that initiates a message. Thus controls the
Clock line. The MASTER always generates the Clock pulses.

- The SDA and SCL lines can only be PULLED low. They cannot be DRIVEN
high. To make them high the device just releases the line.
The external pull-up resistor does the rest of the work.

2.4.1 Start And Stop condition.

A start condition looks like this:


SDA H ------\ The chip issuing the Start condition first
L \------- pulls the SDA (data) line low. And next
pulls the SCL (clock) line low.
SCL H ---------\
L \----


A Stop is just the mirror of the above.

SDA H /---- The Bus MASTER first releases the SCL and
L ---------/ then the SDA line

SCL H /-------
L ------/

The start condition acts as a signal to all connected IC's that
something is about to be transmitted on the BUS.The Stop condition
tells the connected chips that the message has been completed.

2.4.2 Putting something on the BUS

Putting a bit of any kind on the bus looks like this :

SDA H /----------\
L -----/\----------/\------- First the MASTER sets the data line
to the appropriate level by pulling
SCL H /----\ or not pulling the SDA line low.
L --------/ \---------- Then it releases the SCL line for
some time and pulls it low again
before changing the state of the
SDA line.

This is necessary because not all chips on the bus are EDGE driven.
The DATA must stay valid during the HIGH level of the CLOCK pulse.
The only time the DATA line is allowed to change during the HIGH
state of the clock is in a START or STOP condition.

Using the above information ,a transfer could look like this :



SDA H -\ /---\ /---\ /---\ /---\ /---
L \-----/ \---/ \--------/ \-------/ \----/

SCL H ----\ /-\ /-\ /-\ /-\ /-\ /-\ /------
L \---/ \-----/ \---/ \--/ \--/ \--/ \--/


! START ! 1 ! 1 ! 0 ! 1 ! 0 ! 1 ! STOP


As you can see in the above it is not necessary to have a clock with
a constant duty cycle.The BUS is very relaxed even in such a way that
you can stop the clock in the middle of a transaction and then
continue later on. This is very useful. Consider the following :
Your cpu is in the middle of a transaction and gets an interrupt.
It can process the interrupt first and continue its message later on
without any problem. (try doing that on RS232 !).

Since there is no minimum clock speed set you can have the
communication running at whatever speed you can handle.

2.4.3 addressing a SLAVE chip.


EVERY byte put on the BUS MUST be 8 bits long. (8 clock pulses)
A byte is always sent with the MSB first.

The number of bytes that can be transmitted in one data 'telegram' is
unrestricted. ('Data telegram' is everything going on on the bus
between a START and STOP condition).

However it is allowed to end a transmission any time by sending a STOP
condition. Even when you are only 4 bits far in your telegram.
Actually what happens is that the STOP condition resets the bus
control logic of all connected chips. They start looking for a START
condition again.


Waiting for ACKNOWLEDGE.

When a chip is being addressed or has received data it will issue an
ACKNOWLEDGE pulse. Therefore the MASTER must release the DATA line
(set it to high level) and then release the CLOCK line. Now it must check
if the SDA line is low.

The SDA line must be low before the master releases the SCL line !.
There was an error in the faq here !.

Philips I2C specification says:

During an ack (either from master to slave or slave to master )
the SDA line must be stable LOW before ! the SCL line gets raised.
It must also remain stable low during the time the SCL line is high .


When the SLAVE has pulled this line low the MASTER will take the CLOCK
line low and then the SLAVE will release the SDA (data) line.

Now that the MASTER knows that the SLAVE is actually there it can
continue. Generally the MASTERs (mainly CPU's running software) use a
timeout value. When no chip is responding after some time they issue a
STOP and then continue with their work.This prevents your software
from locking up if for some reason the addressed chip is not replying.

Concerning the SLAVE pulling low the SDA line it is so that generally
the addressed IC will already have pulled the SDA line low even before
the MASTER has set the clock HIGH.


This is how theoretically it should work


SDA H -\ /--------------------------------\ /--------
L \-/\--------------------------------/\------/\--------

SCL H ----\ |-| |-| |-| |-| |-| |-| |-| |-| |-| |-| |-| |
L \-| |-| |-| |-| |-| |-| |-| |-| |----| |---| |-| |-|


START ! ! !
! ! !
! ! !
addressed SLAVE pulls SDA LOW ---! ! !
CPU checks if SDA is LOW -------! !
addressed SLAVE releases SDA -------------


In the real life it is good practice to actually look during the high
level of the CLOCK if the SDA is being pulled LOW or is LOW.
Some chips need some time to process the address before they can
respond by pulling the SDA low. This can be the fact when the
addressed SLAVE is another CPU or an EEprom.

Suppose the following : You address a SLAVE CPU. But just before the
SLAVE CPU can pull the SDA low it has to process some interrupt
occuring.If the transfer issuing CPU would look to the SDA line
immediately it would see a HIGH level. Thus it would look like the
SLAVE is not responding.

The Same goes for EEproms. Since storing data to EEprom cells takes
some time the ACKNOWLEDGE is used to indicate that the programming has
been completed. So after the last bit has been transferred the EEprom
starts writing the received data into it's array.It leaves the SDA
line in the HIGH state until this action has been completed.

I have once spend a whole day figuering this one out !.The system once
in a while did not work like it should have because the addressed
device was not capable of generating an ACKNOWLEDGE in time.

The best way to do an ACKNOWLEDGE ,in my humble opinion,is like this:
Put the SCL high , wait some time (your TIMEOUT value) , then check if
SDA is LOW.
If it is LOW - > The chip is there. If it is HIGH -> The chip isn't
there.If you are writing to EEproms then take a bigger TIMEOUT value
in account.

2.4.4 What happens next ?

Now that the SLAVE has been addressed and responded to the ACKNOWLEDGE
the rest of the telegram (until we issue a STOP) depends solely on the
addressed chip. You can just send one or more bytes to the chip or
receive one or more bytes from the chip. It can even be that you first
write something and then read something from the chip.


2.4.5 Writing One or more byte's to a Slave.

After the Device has responded with an ACKNOWLEDGE (see above) you
just send another 8 bits on the bus. Now you have to wait again for
the SLAVE to ACKNOWLEDGE. If you are through you issue a STOP command
and then the bus is released again.
If you need to send more then you just send another 8 bits and wait
for an ACKNOWLEDGE. And so on and on and on.

I figuered out in real life that on the last transmitted byte you do
not have to wait for the ACKNOWLEDGE. You can directly issue a STOP
command.Apparently there are some chips that do not generate an
ACKNOWLEDGE here !.

Theoretically they should generate an ACKNOWLEDGE but for some reason
they don't. The best way is as follows : after you have transferred
your last byte just to set the SCL high , wait some time , take it low
and then issue a STOP command.There is an exception though. Devices
like serial EEproms use the ACKNOWLEDGE for storing the information in
the Memory array.They do not pull the SDA line low until the
programming has been completed.In that way the MASTER has a way to
know if the data has been written succesfully.Storing data in EEprom
memory is rather slow.So by monitoring the SDA line the CPU knows when
the chip has completed the WRITE to its memory array.

A byte write could look like this :

------------------------------------------
| S | SLAVE address | WA | DATA | WA | P |
------------------------------------------

A multi byte write looks like this:

----------------------------------------------------------------------
| S | SLAVE addr. | WA | DATA | WA | DATA | WA |.....| DATA | WA | P |
----------------------------------------------------------------------

Note : S = START
WA = WAIT FOR ACKNOWLEDGE
P = STOP

2.4.6 Reading one or more bytes from a slave.

Looks kind of the same as a byte write. The difference is the handling
of the SDA line and the ACKNOWLEDGE.

The MASTER generates a START , transmits the device address and waits
for an ACKNOWLEDGE. So far so good. Now the MASTER has to RELEASE the
SDA (data) line. The SLAVE will pull it low when needed. On every
clock pulse , that the MASTER generates ,the SDA line will be in the
state set by the SLAVE.When all 8 bits have been read the MASTER must
GIVE the ACKNOWLEDGE to the SLAVE .

Exception :!!!

This reading part is a bit tricky.There is a special condition.
It was pointed out to me by Karl-Heinz Wietzke (Thanks Karl).

On the Last byte read the Master must generate a NACK signal !.
This looks the same as a normal ACKnowledge except the SDA line remains
high now !

ACK :

/---------\
SDA -/ \-----
/-----\
SCL ---/ \-------

NACK :

/---------\
SDA -/ \-----
/-----\
SCL ---/ \-------

There are 2 different NACK signals.

1) The master transmits the slave adress and waits for the slave to
acknowledge this. if the acknowledge does not come we have a NACK.

2) When the master wants to end the read transaction it sends a NACK
instead of an ack just before the STOP condition.

The confusion comes from the fact that on a time diagram the looks
exactly the same. The real difference is that in case 1 it is the
slave that is not responding to the master where in the second case it
is the master that is sending a NACK to the slave.



A read sequence goes as follows:

----------------------------------------------------
| S | address SLAVE | WA | READ 8 BITS | NA | STOP |
----------------------------------------------------

GA = Give ACKNOWLEDGE.
NA = Give NOT-Acknowledge


What physically happens is the following


SDA H /-------------------------------\/--\ /-\ /--
L ----/\-------------------------------/ \-/\-/\--/

SCL H --\ |-| |-| |-| |-| |-| |-| |-| |-| /-\
L \--| |-| |-| |-| |-| |-| |-| |-| |-------/ \------



ACK | MASTER controls SCL | | |
BY | SLAVE controls SDA | *1 | *2 | *3
SLAVE| | | |


*1 : The SLAVE releases SDA (SDA goes HIGH)
*2 : Case of the master giving ACK to the slave
The MASTER first pulls SDA low then gives a CLOCK pulse
and releases SDA again.(SDA goes back high)
This acts as a signal to the SLAVE that the MASTER has received
all 8 bits.This is an ACK from master to slave
Case of the master giving a NACK to the slave
The master leaves SDA high and gives a puilse on SCL.
This acts as a signal to the slave that the transaction is done

*3 : Depending on what happens next. A stop condition could be issued
by the MASTER. If the *2 was an ACK then another byte could be read.
or a start issued. If *2 was a NACK then most a stop or (re)start
condition will appear on the bus.

Confused ? keep these rules in mind :

The chip controlling the CLOCK is the MASTER .
all others are SLAVES at that moment.

Now go and read the above again. (from Reading a BYTE on)


When you are reading another byte you just give another 8 clock
pulses and then generate an ACKNOWLEDGE again. (note that it is
the MASTER here that must generate the ACKNOWLEDGE ).
Remeber if this is the last byte you have read you must give a NACK
instead of an ACK !.

Reading one Byte

-----------------------------------------------
| S | SLAVE address | WA | READ BYTE | NA | P |
-----------------------------------------------

or

------------------------------------------
| S | SLAVE address | WA | READ BYTE | P |
------------------------------------------

Since STOP resets all SLAVEs why bother about giving an NACKnowledge ?.
This works fine in practical applications.
Although some IC's need thsi last NACK signal to reset some internal
circuitry. Check the datasheets before you do this.


Reading a sequence of bytes.

----------------------------------------------------------------------
| S | SLAVE address | WA | READ BYTE | GA |....| READ BYTE | NA | P |
----------------------------------------------------------------------

or

-----------------------------------------------------------------
| S | SLAVE address | WA | READ BYTE | GA |....| READ BYTE | P |
-----------------------------------------------------------------

Now what is the purpose of this NACK signal ?

Well lets consider this case :

We want to read 8 bits out of a chip in a multibyte read sequence
So the master accesses the chip in read mode and waits for ack from the
slave.Now the slave transmits a byte. The master ACK's this and the slave
sends another byte , and so on.
After x bytes read we want to end the transmission.
Now if we were to give an ACK then the slave would put the highest bit of
the next byte on the SDa line. Now if this bit is 1 then we can generate
a stop with no problem. But if this bit was 0 then we could not generate a
STOP condition. We can't raise the SDA line ! the slave is pulling it low.

By giving the NACK pulse we tell the slave that it must keep its hands
of the SDA line in the future until it detects either a START or STOP
condition.That way we ensure that we can give a STOP or START signal.



2.4.7 Determining the SLAVE Access mode

Now there is one thing i haven't told you yet. How does your SLAVE
know whether you want to read from or write to it ?

Thats an easy one. This is beeing determined by the SLAVE address.
Each byte consists of 8 bits. The 8th bit in the SLAVE address has a
special meaning. When it is set to 0 it means you want to write to
your SLAVE. When it is set to 1 it means that you you want to READ.
You could see this as follow. The Even addresses are WRITE addresses,
the ODD addresses are READ addresses. Each device has a consecutive
WRITE and READ address.

Example : a PCF8574 General purpose 8 BIT I/O port.
SLAVE address to WRITE is (01000000)b = 64d
SLAVE address to READ is (01000001)b = 65d


So you can have a theoretical maximum of 128 device on you BUS.
Practically this is not the case. There have been set up a couple of
addresses which you are not allowed to use.(more about this later on)

Still following ?

Now there is one more type of DATA telegram.

2.4.8 The Combined data format.

This is a format generally used by memory devices .

Suppose you have an 128 byte deep memory on the bus and you want to
read the 84th byte. Normally you would have to read the first 83 bytes
before getting what you want.This takes too much time and occupies the
bus. In this case there are two possibilities.
You first write to the SLAVE address a byte which tells it on which
location you want to read. Then you start a read operation.
That is one way of doing it.
A more elegant way to do this is using a combined mode telegram.

--------------------------------------------------------------------
| S | AS WRITE | WA | SEND BYTE | WA | S | AS READ | WA | READ | P |
--------------------------------------------------------------------

So you start out as a normal WRITE operation.

AS WRITE = Address Slave in WRITE mode (even address)

Wait for ACKNOWLEDGE and WRITE a byte . This byte is beeing treated
by the memory as the location pointer. (that is how i2C memories work)

Then you wait for an ACKNOWLEDGE by the SLAVE and you generate another
START condition. Now you send the SLAVEs READ address ( ODD address )
Wait for ACKNOWLEDGE and you receive the data byte. From now on
you are in standard READ mode. So you can now send a STOP or continue
reading from your SLAVE. All memory devices auto-increment their
location pointer.

Now you can even go one step further and generate another START and
then address the SLAVE as write. Send a new Data byte (which acts on
the location pointer), send another start, enter read mode etc ......

This combined mode is really a very flexible means of addressing
complex components.

You can easily do the following in one telegram.

START ,address SLAVE , set location pointer, read ,read ,
set location pointer ,read , set location pointer , write ,
set location pointer ,read , STOP.

This may look very messy . But it has its pro's and con's.

PRO : If you have 2 CPU's on your bus which could want to take the bus
this will assure you that you will be able to continue your
actions on the bus without interference from the other CPU.

Remember that when you have generated a START and have sent the
SLAVE address the other CPU too will be waiting until a STOP
appears on the bus. So he will not try to put something on the
bus.

There could be a risk involved using normal READ and WRITE
operations

Picture this situation :

CPU 1 accesses the MEMORY and sets the location pointer to 84

Now the BUS is FREE.

CPU 2 sees this and thinks : okay my turn.
he sets the location pointer to 92 because he wants to do
something at that location.

Now the bus is free again.

CPU 1 says : aha ! the bus is free. Time to write for me.
Now the data will land on location 92 and not on location 84
as it should have been.

So : If you are dealing with memories always use this last method.
It keeps you out of trouble.

CON:
If you have lots of operations to do you can create a bottleneck
situation. The other CPU could be waiting and waiting for a
chance to have his turn on the bus.


Still with me ?
Congratulations you have reached the EXPERT grade. :-)

2.5 MULTIMASTER communication.(collision detection)

As stated above you can have more than one CPU on the BUS.
When you have only one CPU there are no risks of having collisions on
the bus.

That situation changes with 2 CPU's.

When CPU 1 issues a START and sends an address the other one will back
off. Because of the fact that if the address does not match his own
address he has to wait until the bus is free. (STOP condition). So far
no problem.

But as Murphy is, as usual ,always around. It's when you least expect
it that it goes wrong.Fortunately the BUS setup helps us out here.

When you (as a MASTER ) change the state of a line, you MUST always
check that it has gone to the level you wanted.
If it hasn't : BACKOFF ! it's occupied !.

What could happen is that the TWO CPU's start communication on the
same moment in time.Since it is an open collector/drain bus they can
only PULL the line low. They cannot force it HIGH. (they can only
leave it HIGH by not turning on their output transistor).

So they start transmitting. And all goes well as long as they both are
asserting the same levels. (during START it's okay .They are doing the
same) Then they start asserting a SLAVE address. The first CPU wants
to access SLAVE address 84 and the second CPU wants SLAVE address 87
(for example).So all goes well until they arrive at the 7th bit in the
SLAVE address.

note : 84 = 01010100 (CPU 1)
87 = 01010111 (CPU 2)

||
---- these are different.

Now CPU 1 has pulled SDA LOW.
CPU leaves SDA open.

Since they are both running clean and good written code they are
testing what they have put on the BUS. CPU 1 sees that he has written
a 0 and says OKAY. CPU 2 on the other hand sees that the line is LOW
while he has left it HIGH :> COLLISION. BACK OFF !.

CPU 1 hasn't even seen this so he just continues whatever he was doing.

Now CPU2 has to check that the slave address beeing put on the bus is
not his own. If it is nit his own he has to wait for the STOP command to
appear on the bus before attempting to take control again.
On the other hand. If the address is his own address he must respond.In the
latter case CPU2 becomes the slave device on the bus.

This way all ends up well.

So from the above story we can conclude that is the one that has it's
line LOW that always wins.The One wich wanted the line to be HIGH when
it is beeing pulled low by the other looses the BUS .We call this a
loss of arbitration.

When a BACKOFF situation is generated it is good practice to have the
cpu ,that has to BACKOFF ,wait for a STOP condition to appear on the
bus.The other one is still busy transmitting .

Getting the hang of it ?.
You are ready to face the world of I2C. :-)


2.5.1 Bus synchronisation ( thanks to Sven Rymenants )

The i2c protocol also includes a synchronisation mechanism.
This can be used between masters. However to my knowledge there are
no chips that use this mechanism.
This must be implemented in software.

When a slower slave is attached to the bus then problems may rise.

Suppose the following : The master reads a byte from a slave.
Lets say an A/D convertor.
The slave needs some time to make a conversion.

The master adresses the slave in read mode

----------------------------------...
| S | READ_ADRESS | WACK |...........
----------------------------------...

In the Wait_for_ack module happens something worth looking at.


SDA(master) /-----\
-----/ \-----
/------
SDA(Slave) -----------/
/------
SDA -----------/
/-\
SCL ------/ \--------

This is the normal sequence.

Now lets suppose that the slave has detected his home adress.
It starts a conversion and waits until this conversion is done before
giving acknowledge.That way the master can read the result immediately
after the Acknowledge sequence. Of course the master would have timed out
and considered the slave not to be present on the bus.

Now the synchronisation meachanism can come in handy.

De Slave can pull the SCL low as long as needed.
The master is then not able of giving the ACK clockpulse because it cannot
raise the SCL line.Of course the master software must check this state.

This is the routine the master must execute for a synchronisation aware
Wait_for_ack sequence

initial state : SDA and SCL are low.

SDA=1 ' make SDa high so that slave can pull it low
SCL=1 ' Raise the SCL line
DO ' wait
UNTIL SCL=1 ' until SCL really gets raised
IF SDA=1 THEN DEVICE.IS.NOT.PRESENT ' no ack :the SDa is still high
SCL=0 ' complete clockpulse
...

In the DO..Until sequence the master waits for the slave to release the
SCL line before checking the state of the SDA line.


What happens is this : (in our theoretical model)

The master has sent the last bit of the slave adress on the bus.
The slave recognises it's adress and pulls the SDA line low.
( it wants to acknowledge because it has detected it's adress )
At the same time it starts the A to D conversion and pulls the SCL line
low.

The master now wants to start the Wait_for_ack sequence.
So it makes SDA high.( Never minding the Slave holding it low )

Now the master releases the SCL line.When testing the level of the
SCL line the master will see that it is still low.This is due to the
fact that the slave is holding the SCL low.So the master enters a loop
that runs until the SCL line effectively turns high.

The moment the slave has completed the conversion it releases the
SCL line.

The master detects that the SCL has become high and checks the SDa line.
Since the slave turned it low long ago it sees a valid acknowledge.
The master will now begin to read the result of the conversion.

While this is a very neat technique it is not beeing used.
It is enclosed in the I2C bus specification but to my knowledge no chip
uses this.There are a number of drawbacks involved when implementing this.
If the bus gets stuck due to an electrical failure of a circuit the master
can go into deadlock.Of course this can be handled by timeout counters.

Another drawback is speed.The BUS is locked at that moment. If you have
rather long delays (long conversion time in our example above) then this
penalizes the total bus speed a lot.

All A/D convertors use this technique :

Adress chip. Slave will ack and starts new conversion.
The master reads a byte and sends stop .
This byte is the result of the previous conversion.
The next time the master reads the chip it will read the value cycle above.
Between the 2 accesses the bus is free for the master or another master
to access a different slave.

When the A/D has not completed conversion it can also simply not ACK
The master Wait_for_ack will timeout and the master will continue.
It is the masters task to attempt a retry.

The Synchronisation mechanism is nothing else than a sort of handshaking.
In a multimaster environment there is the risk that , when the 2 masters
are talking to each other,using this handshake routine, they go into
deadlock.

Master 1 attemps to adress master 2. He succeeds.But during the ACK
sequence master 2 has to service an interrupt therefore he keeps SCL low.
Master 1 will now wait for the SCl line to come high.
Master 1 times out (because for some reason master 2 is still busy)
Master 1 completes transaction and starts a retry.
In the mean time master 2 came on line again and released the SCL line.
but is still pulling the SDa line low. Result Master 1 cannot start a
new transmission.Because it will get a backoff situation
( bus is not free ).Master 1 will get stuck in an endless retry routine.
While master 2 will be endlessly waiting for master 1 completing
the ACK. Result : System in complete deadlock.

When using the synchronisation mechanism you must take care to avoid all
possible causes of a deadlock.This makes the interface driver very complex.


2.6 Special addresses and exceptions.


During the above i have mentioned that there are some exceptions about
device addressing. Not all addresses can be used. There are some that
have been reserved by PHILIPS for special purposes.


address R/W

0000 000 0 : general call address
0000 000 1 : start byte

0000 001 x : CBUS address
0000 010 x : address reserved for different bus format.

0000 011 x !
0000 100 x !
0000 101 x !} to be defined
0000 110 x !
0000 111 x !


This implements that all addresses below 16 are reserved for special
purposes


The reason behind this is that there are other buses around. Using
this scheme you can connect device that uses a different bus
to the I2C bus !.
It is possible to put SPI,I2C,uWIRE and CBUS devices on the same I/O
pins of your CPU. Since all buses different to I2C use 3 lines you can
cut down on you CPU pin load using the following setup :

-------
| CPU |
| |------o--------o---------o--------o-----------------------
| | | | | |
| |------|-o------|-o-------|-o------|-o----------------------
| | | | | | | | | |
| |------|-|-o----|-|-------|-|------|-|-o---------------------
| | | | | | | | | | | |
| | | | | | | | | | | |
------- | | | | | | | | | |
------- ----- ----- -------
| SPI | |I2C| |I2C| |uWIRE|
------- ----- ----- -------

How this exactly works would lead us too far.Maybe in the future this
will be incorporated. If somebody out there has experience with these
other buses ? Could be interesting .

CBUS is the ancestor of I2C .It was also developed by Philips.
SPI is (c) Motorola
and uWIRE is (c) National Semiconductor


Some general notes about these reserved addresses.

- The general call address is received by all IC's on the bus.
If there is an IC out on the bus that can process this address it will
respond by generating an ACKNOWLEDGE.See Datasheets for info on which
IC use them and why.

You could use this to invoke some special command in a MultiMASTER
endvironment. (Like reboot all CPU's or whatever .Since all chips will
respond to it ,it can be used for this purpose. However take care not
to mess up anything else.)
There have been determined some actions on receipt of the General call
address.

When the second Byte in a telegram containing a general call is :

00000110 : This is a RESET condition. All IC's capable of handling a
general call message will reset and reload their SLAVE
address.There are I2C compatible IC that have part of
their address programmable.This allows you to have more
than one IC of a certain type on your BUS. Further about
this later on.
They also set all their internal registers to the power-up
state.

00000010 : The same as above except that you must provide the SLAVE
address.This does not RESET the registers to Power-up
state.

00000100 : Causes all IC's that define their address by hardware to
reload this value.This does noet reset internal register.

00000000 : PROHIBITED.

xxxxxxx1 : This is a HARDWARE general call.
You can look to this as a kind of INTERRUPT generated by
an I2C IC.
This can be used in the following condition.:
You have a keyboard controller. Each time a key is pressed
it transmits the following sequence :

----------------------------------------------------
| S | 0000 0000 | A | yyyy yyy1 | A | Databyte | P |
----------------------------------------------------

Where yyyy yyy is its own address.
What will happen is that the MASTER CPU will see the
General call address and see that the device with address
yyyy yyy has something to tell to the CPU.It will read the
next byte.In our case the CPU will know that keyboard
controller yyyyyyy has detected a key and that the
scancode of this key is contained in the received databyte.


All other codes have not been assigned. All I2c ic's are designed
to ignore them. So you are free to use them for whatever.
(I generally use them to debug MultiMASTER modes).

- NO IC is allowed to generated an ACKNOWLEDGE of the START byte.

- The start byte is used to syncronize Slow devices with fast devices.

- The CBUS address is used in this way :
After sending this address all IC's go into IDLE mode until they
receive a STOP condition. In the mean time you can transfer data using
a complete different protocol on your I2C bus.





2.7) Electrical spec's of the I2C Bus

As the chips designed for an I2C bus can function on different Supply
voltages the following levels have been set.

+--------+------+-----------------+-----------------+
| Symbol | Unit | Standard mode | FAST mode |
| | +--------+--------+--------+--------+
| | | Min | Max | Min | Max |
+-----------------+--------+------+--------+--------+--------+--------+
|Low level input | | | | | | |
| voltage | Vil | V | -0.5 | 1.5 | -0.5 | 1.5 |
| rel to VDD | | | -0.5 | 0.3Vdd | -0.5 | 0.3Vdd |
+-----------------+--------+------+--------+--------+--------+--------+
|HIGH level input | | | | | | |
| Volteg | Vih | V | 3.0 | *1 | 3.0 | *1 |
| rel to VDD | | | 0.7Vdd | *1 | 0.7Vdd | *1 |
+-----------------+--------+------+--------+--------+--------+--------+
|Hysteresis of | Vhys | V | - | - | 0.2 | - |
| Schmitttrig | | | | | | |
+-----------------+--------+------+--------+--------+--------+--------+
|Pulse width of | | | | | | |
|spikes that must | tSP | nS | - | - | 0 | 50 |
|be suppressed | | | | | | |
+-----------------+--------+------+--------+--------+--------+--------+
|Low level output | | | | | | |
| voltage | | | | | | |
| At 3mA | Vol1 | V | 0 | 0.4 | 0 | 0.4 |
| At 6mA | Vol2 | V | - | - | 0 | 0.6 |
+-----------------+--------+------+--------+--------+--------+--------+
|Input current of | | | | | | |
| BUS pins | Ii | uA | -10 | 10 | 10 | 10 |
+-----------------+--------+------+--------+--------+--------+--------+
|Capacitance of | | | | | | |
| each bus PIN | Ci | pF | - | 10 | - | 10 |
+-----------------+--------+------+--------+--------+--------+--------+


*1) Maximum Vih = VDD MAX + 0.5 V

The number of interfaces connected is limited to the number of
available addresses and the load capacitance on the bus.
This capacitance may not be bigger then 400pF. In the new standard
this is preferred to be less than 200pF.


3.0) Enhanced I2C (FAST mode)

Since the first I2C spec release (which dates back from 1982) a
couple of improvements have been made.In 1993 the new I2C spec was
released.This new spec conatains some additional sections covering
FAST mode and 10 -Bit addressing.
In this section the Fast mode will be covered , while in the next
section information about 10 bit addressing is given.

In the FAST mode the physical bus parameters are not altered.
The protocol,Bus levels,Capacitive load etc.. remain unchanged.
However the datarate has been increased to 400 Kbit/s.
To accomplisch this task a number of changes have been made to timing.

Since all CBUS activities have been canceled ,there is no
compatibility anymore with CBUS timing.The development of IC with CBUS
interface has been stopped. The existing CBUS ic's are being taken out
of production.

The input of the FAST mode devices all include Schmitt triggers to
suppress noise.The output buffers include slope control of the falling
edges of the SDA and SCL signals.If the power supply of a FAST mode
device is switched off the BUS pins must be floating so that they do
not obstruct the bus.

The pullup resitor must be adapted. For loads up to 200 pf a resistor
is sufficient.For loads between 200pf and 400pF a current source is
preferred.


4.0) Extended addressing (10 bit address mode)

Due to the increasing popularity of the I2C bus the address space is
nearly exhausted.This starts posing problems for people currently in
the phase of designing a new I2C compatible IC.
Therefore the I2C standard has been adapted.

A chip that conforms to the new standard receives 2 address bytes.
The first consists of 5 * a ONE ,the 2MSB's of the address and the
Read/Write bit. The second byte contains the LSB's of the address.

-----------------------------------------------------------------
|S| 1 1 1 1 1 A9 A8 R/W |WA| A7 A6 A5 A4 A3 A2 A1 A0 | WA | .....
-----------------------------------------------------------------

This scheme insures that the 0 bit addressing mode stays completely
transparent for the other devices on the bus.
Normally any new design should adept to this new addressing scheme.

5.0) Q&A section

Q - What is the maximum distance of the bus ?

A - This depends on the load of the bus and the speed you run it at.
In typical applications a few meters (3 to 4). Better: The maximum
capacitive load has been specified (electrical Spec's in this FAQ).

If you run at a lower clock frequency then you could go further.
If you are careful in routing your PCB's and cabling then you can
take it further.I once had an application that had a total of about
100 meter cable in it. The entire system was clocked on something
like 500 Hz.
I used twisted pair cable and twisted SCL with GND and SDA with VCC.
No problem.The systems is now up and running for over 2 years.

Q - I want to extend it ''by the book''. Is there something like a Buffer
for I2C ?

A - Yes indeed this exists. Philips manufactures a special chip to buffer
the bidirectional lines of the I2C bus. Typically this is a current
amplifier. What it does is force current into the wiring
(a couple of mA). That way you can overcome the capacitance of long
wiring.

Type : P82B715

Q - Can i isolate an I2C bus ? (using optocoupler or whatever)

A - This is possible. The circuit is rather complex due to the
bidirectional nature of the I2C BUS.

However : Here it comes (for once channel).

------------o----------+ +------o-------------------
VCC | | | | VCC
| | | | | 3K3 | 270
| | 270 | | 3K3 | | | |
| | | | | | | |
| | | | | |
+------o---+ | |C |
| | | | | / o------o----+
| | OL1--- | | --/ |/ OT1 | | |
1K8 | | \ / | | /--> B|\ | | |
| | --- | | | \E |C | |
| | | | | | / | | |
| |E | | o---B|/ NPN | | | 1K8
| | / | | | |\ | | |
_____o__B|/ | | | | \ | |
|\ | C | | |E | |
SDA | \ C | \ |B | | | |
or | | OT2 \| \-- | | OL2 --- |
SCL PNP | | /| <--\ | | \ / |
| C | E / | | | --- |
| \ |B | | | E| | SDA or
| \|____o | | \ | | SCL
| NPN /| | | | | PNP \|--o------
| / | | | | |1K | /|B
| E | | | 1K | | | / |
| | | | | | C|
| | | | | |
GND | | | | | | GND
-----------o----o------+ +------o------o------------

OT1 and OL1 are part of one optocoupler.
OT2 and OL2 are the other optocoupler.

A couple of remarks.
Since the speed of the I2C bus can be rather high it is reommended to
use a fast optocoupler. A 6N139 will do the job in all cases.
The 2 PNP and 2 NPN transistors can be any standard type.
Like 2N2219 and 2N2222 (USA) or BC547 and BC557 (EUROPE).

How does it work ?

The problem with bidirectional lines is that a buffer tends to get
stuck on a certain level. In the above schematic this has been dealth
with.
In the following explanation we assume that the left side is
transmitting and the right side is receiving.Since the circuit is
symmetrical you could do it the other way around too.

Suppose you send a logic 1 into the left side. The OL1 will stay dark.
Since OT1 does not receive any light it is not turned on. The next
transistor does not get driven and the line at the end is beeing pulled
hgih by the 270 ohm and 1K8 resistor. The PNP transitor will not get
driven. OL2 will not light. So OT2 does not get driven.So far so good.

Now lets look what will happen if we send a 0.
The first transistor will be turned on. Thus OL1 will start emitting
light.This results in the fact that OT1 will be turned on.
The transistor connected to the Emittor of OT1 will be tured on too.
The output line is now beeing pulled low via the 1K8 resistor.
This low level would turn on the PNP transistor . This would result in
OL2 to ligh, OT2 to turn on etc .. The circuit would go into a lockup.
But since the NPN transistor is pulling the Anode of the led to ground
this will not happen. In this way we have eliminated the deadlock.

Q - What if i don't want to emulate the bus by software or if i don't have
an I2C interface on my system ? Is there something like an I2C
controller ?

A - Yes indeed. There is a special chip to do the I2C interfacing.
The PCD8584 or PCF8584 incorporate a complete I2C interface.
These chips are designed in such way that they can interface to almost
any microcontroller or computer around.

Q - I am puzzled on how to generate a repeated start condition.
I make the SCK high and my device pulls SDA low to acknowledge.
So far no problem but how do i make a new start now ?.
The device is pulling SDA low.

A - First you have to complete you ACK cycle.
To do this you must make SCL low again.
The slave will release the dataline when it detects that SCL went
logic low.
Now you can issue a stop command. To do this you make the SCK
high again and then pull low the SDA line.
This is the confusing part of the procedure. Normally one would
suspect that by making the clock high again you will be clocking
in the first bit of a new byte. As a matter of fact that is the case.
But since the chip will detect a START condition this operation gets
cancelled.

Q - Is it okay to abort an on-going transmission any time.

A - According to the specification this !should! work.
It depends on the layout of the component. A real I2C compatible
ic will be able to handle this. You should test this before you
use it.

Normally when a START or STOP condition is detected the internal
logic of the chip is forced into a certain state.
Internally the part that detects START and STOP is differnet then
the logic that does all other processing.
The START together with the address register is to be considered as
a functional unit inside the chip.

When a START is detected all internal operations are cancelled and
the chip will compare the incoming data with it's own address.

When a STOP is detected ALL chip's on the bus will reset their
internal logic to IDLE mode.
This is also used to cut power consumption. When a STOP is detected
all logic is shut down except for the START detector.
When a start is issued on the bus the START detector will 'wake-up'
the rest of the internal logic.

Q - Do i need to give the ack in read mode on the last byte.
My chip starts sending data and occupies the bus ... .

A - This is a question that got me puzzled .Indeed this is a bit strange.
Normally if you have read the last byte in a chip and generate an ACK
the chip should do nothing anymore. So the bus is clear for you to
create a STOp condition.
Apparently there are some chips that start transmitting data again.

Digging in to to spec showed an error in my FAQ.
On the Last byte READ you must generate a NACK (NOT Acknowledge)
Check out the description of the READ mode

-- This is a BUG fIx !! --

Q - I read the SDA and SCL are bidirectional.Why does the clock line
need to be bidirectional ?

A - The clock line needs to be directional when using a MULTIMASTER
protocol and when using synchronisation protocol.
When you are using only one Master then this is not required
since the clock will always be generated by the Master and you only
have one on the BUS.
If you run Multimaster then this changes.The Master must be able
to receive data from the other master. At that time it must be able
to check the Clock line too.

For more information about bus synchronisation check out topic 2.5.1






6) An I2C driver in PseudoCode

This section covers a sample I2C driver. Currently Version 1.1

It is written in PseudoCode which is an imaginary programming language
that any programmer should be capable of porting to his/her favorite
language.

First we will define a set of basic interface routines.
All text between / / is considered as remark.

Following variables are used :

n,x = a general purpose BYTE
SIZE = a byte holding the maximum number of transferred data at a time
DATA(SIZE) = an array holding up to SIZE number of bytes.
This will contain the data we want to transmit
and will store the received data.
BUFFER = a byte value holding immediate received or transmit data.

Note. This is the improved Version 1.0.
It features startup code which is of use immediately after boot
of your system.

A number of adaptations have been made to kill some nasty beasties.

A Bug in the Start routine was fixed thanks to Tony Ayling.
Thanks Tony



/ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ /
/ **** I2C Driver V1.1 Written by V.Himpe. Released as Public Domain **** /
/ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ /

DECLARE N,SIZE,BUFFER,X Byte
DECLARE DATA() Array of SIZE elements

SUBroutine I2C_INIT / call this immediately after power-on /
SDA=1
SCK=0
FOR n = 0 to 3
CALL STOP
NEXT n
ENDsub

SUBroutine START
SCK=1 / BUGFIX !/
SDA=1 / Improvement /
SDA=0
SCK=0
SDA=1
ENDsub

SUBroutine STOP
SDA=0
SCK=1
SDA=1
ENDsub

SUBroutine PUTBYTE(BUFFER)
FOR n = 7 TO 0
SDA= BIT(n) of BUFFER
SCK=1
SCK=0
NEXT n
SDA=1
ENDsub

SUBroutine GETBYTE
FOR n = 7 to 0
SCK=1
BIT(n) OF BUFFER = SDA
SCK=0
NEXT n
SDA=1
ENDsub

SUBroutine GIVEACK
SDA=0
SCK=1
SCK=0
SDA=1
ENDsub

SUBroutine GETACK
SDA=1
SCK=1
WAITFOR SDA=0
SCK=0
ENDSUB

/ this concludes the low-level set of instructions for the I2C driver /
/ The next functions will handle the telegram formatting on a higher level /

SUBroutine READ(Device_address,Number_of_bytes)
Device_adress=Device_adress OR (0000.0001)b / This sets the READ FLAG /
CALL START
CALL PUTBYTE(Device_adress)
CALL GETACK
FOR x= 0 to Number_of_bytes)
CALL GETBYTE
DATA(x)=BUFFER / Copy the received BYTE in the DATA array /
IF X< Number_of_bytes THEN / Prevent giving an ack on the last /
CALL GIVEACK / byte read out of the chip.Otherways /
END IF / there is risk of bus hang-up /
NEXT x
CALL STOP
ENDsub

SUBroutine WRITE(Device_address,Number_of_bytes)
Device_adress=Device_adress AND (1111.1110)b / This clears READ flag /
CALL START
CALL PUTBYTE(Device_adress)
CALL GETACK
FOR x= 0 to Number_of_bytes
CALL PUTBYTE (DATA(x))
CALL GETACK
NEXT x
CALL STOP
ENDsub

SUBroutine RANDOMREAD(Device_adress,Start_adress,Number_of_bytes)
Device_adress=Device_adress AND (1111.1110)b / This clears READ flag /
CALL START
CALL PUTBYTE(Device_adress)
CALL GETACK
CALL PUTBYTE(Start_adress)
CALL GETACK
CALL START
Device_adress=Device_adress OR (0000.0001)b / This sets the READ FLAG /
CALL PUTBYTE(Device_adress)
CALL GETACK
FOR x= 0 to Number_of_bytes
CALL GETBYTE
DATA(x)=BUFFER
CALL GIVEACK
NEXT x
CALL STOP
ENDsub

SUBroutine RANDOMWRITE(Device_adress,Start_adress,Number_of_bytes)
Device_adress=Device_adress AND (1111.1110)b / This clears READ flag /
CALL START
CALL PUTBYTE(Device_adress)
CALL GETACK
CALL PUTBYTE(Start_adress)
CALL GETACK
FOR x= 0 to Number_of_bytes
CALL PUTBYTE (DATA(x))
CALL GETACK
NEXT x
CALL STOP
ENDsub

/ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ /
/ **** End of the I2C Driver . (c)95 V.Himpe . Public Domain release *** /
/ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ /

Some notes about the high level routines.

The READ and WRITE routine read/write one or more byte(s) from/to a
slave device. Generally this will be used only with Number_of_bytes
set to 1. An example

PCD8574=(0100.0000)b
CALL READ(PCD8574,1)
result = DATA(0)

/ will read the status of the 8 bit input port of a PCD8574. /

DATA(0)=(0110.01010)b
CALL WRITE(PCD8574,1)

/ will write 0110.0101 to the 8 bit port of the PCD8574 /

When do you need a multiread ?
Consider a PCF8582 EEPROM.
You want to read its contents in one time.

PCF8582=(1010.0000)b
CALL READ(PCF8582,255)

You can do the same with WRITe for the EEprom with the restriction
that Number_of_bytes is not larger than 4.

You will have to check the components datasheets.

The most usefull instructions are RANDOMREAD and RANDOMWRITE

Write 4 bytes of data to location 20h of the EEPROM

DATA(0)=(1010.0011)b
DATA(1)=(1110.0000)b
DATA(2)=(0000.1100)b
DATA(3)=(1111.0000)b
CALL RANDOMWRITE (PCF8582,(20)h,3)

The same goes for reading 16 bytes from the eeprom starting at adress 42h

CALL RANDOMREAD(PCF8582,(42)h,15)

The results are stored in DATA. All you have to do is read them out of
the array to process.
When you give the devices adress to these routines you don't have to care
about the R/W flag. It will be automatically set to the right state inside
the routines.



7) Debugging tools.

So you have an I2C bus and you want to monitor activity.
Using a regular scope this is rather tough.
When you are in control then you can easily generate a trigger for the scope.
If you are not in control ( in a TV set or other equipment ) then things
get more complicated.

The tools described in this section should provide some easy means to solve
these problems.

7.1) I2C trigger generator.

This simple circuit allows any scope to trigger on an I2C transmission.
each time a start condition is detected the output of the flipflop will
generate a pulse.


|------|
SDA ----|> Q|-----
| |
| -|
SCL ----|J Q|
|------|




8) I2C interfacing system for IBM-PC.

This section covers a complete I2C experimenting system for the IBM PC.
In this section i will set up an environment to experiment with I2C.

8.1 Hardware section.

The schematic is almost the same as the Schematic provided by Philips.
As a matter of fact it is the same.A little addition has been made.
However it is 100% compatible with the philips driver schematic.
This was done so you can use it both with tools like TV400 from Philips
and with my driver.

LS05 pin 14 (Vcc) o -------
| | |
+--+--+---------------------+--+--+--+----------+------+-o 1 |
| | | | | | | ===.1uF | +5V |
-------- [R][R][R] 3x10K 4x10K [R][R][R][R] LS05 | | |
| | | | | | | | | pin 7 o-+------+-o 2 |
| 12 o-+--+ | | 3|\ 4 | | | | (Gnd) | GND |
| 17 o-+-----|--|----| >o-------------+--|--|--|------------+ | |
| | | | |/ 8 /|9 | | | 10 /|11 +----+-o 3 |
| 15 o-+-----+--|--------------o< |------+--|--|----o< |----+ | SCL |
| | | 1|\ 2 \| | | \| | |
| 9 o-+--------|----| >o-------------------+--|------------+----+-o 4 |
| | | |/ | 6 /|5 | | SDA |
| 11 o-+--------+------------------------------|----o< |----+ | |
| | 13|\ 12 | \| | |
| 8 o-+-------------| >o----------------------+-----------------+-o 5 |
| | |/ | Trig|
| | -------
| |
| 10 o-+-+ 5-pin
| 13 o-+-+--oGND Connector
| 25 o-+-+ ------------------ Part List --------------------------
-------- | 1 - .01 uF capacitor | 6 - 10K 5% resistors |
25-pin male D | 1 - 4-pin connector | 1 - 25-pin male D connector |
connector to PC | 1 - 74LS05 open collector hex inverter |
printer port -------------------------------------------------------

SCL and SDA speak pretty much for themselves. The trig Output is an addition
i made to the original schematic. When used with the driver described below
it is able to trigger an oscilloscope. Each time a Start condition occurs
the trig output generates a pulse.This will make it easier to monitor bus
activity when experimenting wth the system.
You can write a loop that keeps doing the same over and over again.
When you connect SCL and SDa to channels X1 and X2 of the scope and the TRIG
to the Trigger input. You can see the transfer on the bus

Isolated schematic :

Don't you just hate it when another setup screws up the printerport of
your PC ?. Well here is an Optically isolated version of the interface.

printer port
+---+
| |
|12 o-o---o---o--> ** +------------o----o-----------o-------o +5V
| | | | | | | | |
| |[R5] | [R1] [R2] [R6] [R4] |
| | | | | | (3)|\ (4) | | |
| | | | | +-----| }o---|----o--[R3]---o-|--------o SCL
| | | | |(2) |(6) |/ | | |
| | | | +-o------------o-+ | | |
| | | | | + C | | | |
| | | | |LED NPN| | | |
| | | | | - E |4N33 | | |
| | | | +-o------------o-+ | | |
| | | | |(3) |(5) | | |
|17 o-|---|---+ === | | |
| | | | | | |
| | | | +------------+ | |
|15 o-o---|---+ | | |
| | | |(6) |(2) | |
| | | +-o------------o-+ R1, R6 = 220 | |
| | | | C + | R2, R3, R4, R5 = 4K7 | |
| | | |NPN LED| | |
| | | | E - |4N33 | |
| | | +-o------------o-+ | |
| | | |(5) (7) |(3) (8) /|(9) | |
| | | === +------o{ |-----------------+ |
| | | \| |
| | | |
| | +---o---+ +------------o----o-----------+
| | | | | | |
| |[R5] [R1] [R2] [R6] [R4]
| | | | | (1)|\ (2) | |
| | | | o-----| }o---|----o--[R3]---o----------o SDA
| | | |(2) |(6) |/ | |
| | | +-o------------o-+ | |
| | | | + C | | |
| | | |LED NPN| | |
| | | | - E |4N33 | |
| | | +-o------------o-+ | |
| | | |(3) |(5) | |
|9 o-|-------+ === | |
| | | | |
| | | +------------+ |
|11 o-o-------+ | |
| | |(6) |(2) |
| | +-o------------o-+ R1, R6 = 220 |
| | | C + | R2, R3, R4, R5 = 4K7 |
| | |NPN LED| |
| | | E - |4N33 |
| | +-o------------o-+ |
| | |(5) (7) |(3) (6) /|(6) |
| | === +------o{ |-----------------+
| | \|
+---+ Schematic based on an original from SVEN Rymenants


In stead of the 4n33 you can use a TIL111 or 4.32 or 6n136 or any regular
optocoupler. The suggested types are Fast optocouplers and low LED current
optocouplers.

** : this means you must apply 5 volts here. Now how can this be made.?
The driver must leave all unused pins in the HIGH state.
You must connect 9 diodes to this point.

1 o--|>|--+ The output pins that are left open will
2 o--|>|--+ supply sufficiently power to the capacitor
3 o--|>|--+ to charge it to 4..5 volts.
4 o--|>|--+ This is then used as suply for the leds
5 o--|>|--+ in the optocouplers.
6 o--|>|--+
7 o--|>|--+ You can also use digital optocouplers
8 o--|>|--+---> ** (5 volts) These are optocouplers with a built in
| driver and smitttrigger.
---
47 uF 16volts.
/-\
|
===

8.2 Software

This module can be used with the programs developed by philips and available
from their FTP site.

Programs are TV400.ZIP and RAD216.ZIP
These contain a complete bus control terminal. You can monitor bus activity
and also actively control lots of standard chips.It comes with libraries
for nearly all Philips IC's available. You can also control Non-Philips
ic by using the universal bus interface.


8.2.1 Quickbasic / PDS / POWERBasic Driver

' -------------- (CUT here) ------------------------------------------------

DECLARE SUB I2Cmultiread (adr%, count%)
DECLARE SUB I2Cwrite (adr%, dta%)
DECLARE SUB I2Cinit (timeout!)
DECLARE SUB I2Cdebugon ()
DECLARE SUB I2Csettimeout (tme!)
DECLARE SUB I2Cwwsend (adr%, sbadr%, dta%)
DECLARE SUB I2Cdebugoff ()
DECLARE FUNCTION I2Cread! (adr%)
DECLARE SUB holdsystem ()
DECLARE SUB delay (count)
DECLARE SUB hold.system ()
DECLARE SUB I2Copen (port%, debug%)
DECLARE SUB I2Cpob ()
DECLARE SUB messg (dta$)
DECLARE SUB holdsystem ()
DECLARE SUB I2Cgenstart ()
DECLARE SUB delay (count!)
DECLARE SUB I2Cgenstop ()
DECLARE SUB I2Cgiveack ()
DECLARE SUB I2Ctransmit (byte%)
DECLARE SUB I2Cwaitforack ()
DECLARE SUB I2Creceive ()
DECLARE FUNCTION I2Cread! (adr%)
DECLARE FUNCTION I2Cwwread! (adr%, sbadr%)

' **************************************************************************
' * I2CDRIVE I2C Bus Driver Version 1.42 *
' * (c) 1995-1996 Vincent Himpe All Rights Reserved *
' * Features ICee Debugger *
' * Released as PUBLIC DOMAIN. Use as you please *
' * *
' * This driver can be used in Quickbasic ,PDS and PowerBasic *
' * PowerBasic users must kill the 'Sub DELAY' since powerbasic has this *
' * feature. *
' **************************************************************************
' * ICee Debugger. *
' * *
' * If during run of the program the computer beeps this means that an *
' * adressed chip is not responding. Turn on the debugger by issuing the *
' * I2CDebugOn command immediately after opening the bus and rerun the *
' * program. You will get detailed error information *
' **************************************************************************

DIM ICdta(10)
COMMON SHARED I2CLoPort, I2Cmidport, I2CHiPort, I2C.savedstatus, scl, SDA
COMMON SHARED I2Cdebug, I2Ctimeout, I2Cdevadr%, I2Cresult%, ICdta(), hold
' powerbasic users must replace COMMON SHARED by PUBLIC


hold = .001 ' do not adapt this value. Adapt the value in the sub DELAY


' $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
' $ Sample program using the driver $
' $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

I2Copen 0, 1 ' open port &h378 (LPT1) with ICee enabled
I2Cinit 10 ' set a timeoutvalue

' the above is always needed on top of any program using the I2C driver

CLS

I2Cwrite 192, 12 ' write '12' to device with adress 192
a = I2Cread(193) ' read a byte from the same device

I2Cwwsend 200, 1, 7 ' write '7' to register '1' of device at adress 200
a = I2Cwwread(201, 1) ' read register 2 of device at 200

I2Cmultiread 200, 3 ' read first 4 registers (0..3) of the slave at 200
FOR a = 0 TO 3
PRINT ICdta(a)
NEXT a

END

SUB delay (count)

' Notice about this routine.
' When using powerbasic you must delete this routine in its entirity.
' this routine is needed for Qbasic only. Since it lacks the feature of
' a microtimer.

FOR a = 0 TO (count * 1000) ' adapt this value according to the speed
NEXT a
END SUB

SUB holdsystem ' Freezes the system so you can read ICee debugger messages
CALL messg(" Press any key to continue ... ")
DO
a$ = INKEY$
LOOP UNTIL a$ <> ""
END SUB

SUB I2Cclose ' Closes the I2C driver. This resets the parallel port
OUT I2CHiPort, I2C.savedstatus
OUT I2CLoPort, 127 ' set sda hi all others high (VCC for opto)
END SUB

SUB I2Cdebugoff ' Turns off the I2C debugger
CALL messg("ICee debugger DISABLED ")
I2Cdebug = 0
END SUB

SUB I2Cdebugon ' Turns the debugger on
CALL messg("ICee Debugger ENABLED ")
I2Cdebug = 1
END SUB

SUB I2Cgenstart ' transmits a start condition
IF I2Cdebug = 1 THEN
CALL messg("ICee MSG001: Generating START on bus ")
END IF
' start of transmission
OUT I2CLoPort, 127 ' sda high
delay hold
OUT I2CHiPort, 8 ' scl high
delay hold
OUT I2CLoPort, 255 ' sda lo
delay hold
OUT I2CLoPort, 255 ' sda lo
delay hold
OUT I2CHiPort, 0 ' scl lo
delay hold
END SUB


SUB I2Cgenstop ' transmits a stop on the bus
IF I2Cdebug = 1 THEN
CALL messg("ICee MSG002: Generating STOP on bus ")
END IF
OUT I2CLoPort, 255 ' sda lo
delay hold
OUT I2CLoPort, 255 ' sda lo
delay hold
OUT I2CHiPort, 8 ' scl hi
delay hold
OUT I2CHiPort, 8 ' scl hi
delay hold
OUT I2CLoPort, 127 ' sda hi
delay hold
' // end of stransmission
END SUB

SUB I2Cgiveack ' Gives an ACK to a slave
OUT I2CHiPort, 0 ' scl low
delay hold
OUT I2CLoPort, 255 ' sda low
delay hold
OUT I2CHiPort, 8 ' scl hi
delay hold
OUT I2CHiPort, 0 ' scl low
delay hold
OUT I2CLoPort, 127 ' sda high
delay hold
END SUB

SUB I2Cinit (timeout) ' aborts transmission and clears bus
FOR I2Ca% = 0 TO 5
OUT I2CLoPort, 255 ' set SDA low
delay hold
OUT I2CHiPort, 8 ' set SCL HI
delay hold
OUT I2CLoPort, 127 ' bring SDA HIGH
delay hold
OUT I2CHiPort, 0 ' bring SCL Low
delay hold
NEXT I2Ca%
I2Ctimeout = timeout
OUT I2CHiPort, 8
delay hold
END SUB

SUB I2Cmultiread (adr%, count%) ' performs a multiread from a slave
adr% = (adr% OR 1)'make shure adress is odd
I2Cdevadr% = adr%
CALL I2Cgenstart
CALL I2Ctransmit(adr%)
CALL I2Cwaitforack
I2Cdevadr% = 0
FOR internalloop% = 0 TO count%
CALL I2Creceive
IF internalloop% < count% THEN ' prevent giving ack on last byte
CALL I2Cgiveack
END IF
ICdta(internalloop%) = I2Cresult%
NEXT internalloop%
CALL I2Cgenstop
END SUB

SUB I2Copen (port%, dbug%) ' Always call this before any other routines !
SELECT CASE port%
CASE 0
I2CLoPort = &H378
I2Cmidport = &H379
I2CHiPort = &H37A
CASE 1
I2CLoPort = &H3BC
I2Cmidport = &H3BD
I2CHiPort = &H3BE
END SELECT
I2C.savedstatus = INP(I2CHiPort)
IF dbug% = 1 THEN
I2Cdebug = 1
ELSE
I2Cdebug = 0
END IF
END SUB

SUB I2Cpob ' puts bits on the bus
IF SDA = 1 THEN
OUT I2CLoPort, 127
delay hold
ELSE
OUT I2CLoPort, 255
delay hold
END IF
IF scl = 1 THEN
OUT I2CHiPort, 8
delay hold
ELSE
OUT I2CHiPort, 0
delay hold
END IF
IF I2Cdebug = 1 THEN
END IF
END SUB

FUNCTION I2Cread (adr%) ' reads a byte out of a slave
adr% = (adr% OR 1)' make shure adress is odd
I2Cdevadr% = adr%
CALL I2Cgenstart
CALL I2Ctransmit(adr%)
CALL I2Cwaitforack
I2Cdevadr% = 0
CALL I2Creceive
CALL I2Cgiveack
CALL I2Cgenstop
I2Cread = I2Cresult%
END FUNCTION

SUB I2Creceive ' receives a byte from a slave
IF I2Cdebug = 1 THEN
CALL messg("ICee MSG005: Receiving data from slave :")
END IF
I2Cresult% = 0
OUT I2CLoPort, 127 ' release sda
delay hold
FOR I2Ca% = 7 TO 0 STEP -1
I2Cb% = 2 ^ I2Ca%
OUT I2CHiPort, 8
delay hold
I2Cin% = (INP(I2Cmidport) AND 128)
OUT I2CHiPort, 0
delay hold
IF I2Cin% = 128 THEN
I2Cresult% = I2Cresult% + I2Cb%
PRINT "1";
ELSE
PRINT "0";
END IF
IF I2Ca% = 4 THEN PRINT " ";
NEXT I2Ca%
PRINT
END SUB

SUB I2Csettimeout (tme) ' assigns a timeout value
I2Ctimeout = tme
END SUB

SUB I2Ctransmit (byte%) ' transmits a byte on the bus
IF I2Cdebug = 1 THEN
CALL messg("ICee MSG004: Transmitting data byte on bus ")
END IF
I2Ca% = 0
FOR I2Ca% = 7 TO 0 STEP -1
I2Cb% = 2 ^ I2Ca%
IF (byte% AND I2Cb%) = I2Cb% THEN
OUT I2CLoPort, 127
delay hold
ELSE
OUT I2CLoPort, 255
delay hold
END IF
OUT I2CHiPort, 8
delay hold
OUT I2CHiPort, 0
delay hold
NEXT I2Ca%
OUT I2CLoPort, 127 ' release sda
delay hold
END SUB

SUB I2Cwaitforack ' waits for slave acknowledge
IF I2Cdebug = 1 THEN
CALL messg("ICee MSG003: Waiting for ACKNOWLEDGE ")
END IF
OUT I2CLoPort, 127 ' maak SDa hi
OUT I2CLoPort, 127
delay hold
OUT I2CHiPort, 8 ' maak scl hi
OUT I2CHiPort, 8
delay hold
acknowledge = 0
acktimer = 0
WHILE acknowledge = 0
acktimer = acktimer + 1
I2C.mon = (INP(I2Cmidport) AND 128)
IF I2C.mon <> 128 THEN
acknowledge = 1
END IF
IF acktimer = I2Ctimeout THEN
acknowledge = 1
IF I2Cdevadr% <> 0 THEN
IF I2Cdebug = 1 THEN
CALL messg("ICee ERR001: Device is not responding ")
CALL holdsystem
ELSE
BEEP
END IF
ELSE
IF I2Cdebug = 1 THEN
CALL messg("ICee ERR002: No ACK received")
CALL holdsystem
ELSE
BEEP
END IF
END IF
END IF
WEND
OUT I2CLoPort, 127 ' maak SDa hi
OUT I2CLoPort, 127
delay hold
OUT I2CHiPort, 0 ' maak scl LO
OUT I2CHiPort, 0
delay hold
END SUB

SUB I2Cwrite (adr%, dta%) ' writes a byte to a slave
adr% = (adr% AND 254)'make shure adress is even
I2Cdevadr% = adr%
CALL I2Cgenstart
CALL I2Ctransmit(adr%)
CALL I2Cwaitforack
I2Cdevadr% = 0
CALL I2Ctransmit(dta%)
CALL I2Cwaitforack
CALL I2Cgenstop
END SUB

FUNCTION I2Cwwread (adr%, sbadr%) ' reads with subadress
adr% = (adr% OR 1)' make shure adr is odd
I2Cdevadr% = adr%
CALL I2Cgenstart
CALL I2Ctransmit(adr%)
CALL I2Cwaitforack
I2Cdevadr% = 0
CALL I2Ctransmit(sbadr%)
CALL I2Cwaitforack
CALL I2Cgenstart
adr% = adr% + 1
CALL I2Ctransmit(adr%)
CALL I2Creceive
CALL I2Cgenstop
I2Cwwread = I2Cresult%
END FUNCTION

SUB I2Cwwsend (adr%, sbadr%, dta%) ' writes with subadress
adr% = (adr% AND 254)' make shure addr is even
I2Cdevadr% = adr%
CALL I2Cgenstart
CALL I2Ctransmit(adr%)
CALL I2Cwaitforack
I2Cdevadr% = 0
CALL I2Ctransmit(sbadr%)
CALL I2Cwaitforack
CALL I2Ctransmit(dta%)
CALL I2Cwaitforack
CALL I2Cgenstop
END SUB

SUB messg (dta$) ' shows the ICee messages on the screen
' adapt this routine for your screenhandler

PRINT dta$
END SUB

'--------------------- ( cut here ) ----------------------------------------

Note :
A Windows DLL will be made available that can use this board.
So Visual basic programmers or other Windows programmers can have
I2C control too.


9) Legal Notes and Copyrights.

Standard Philips Copyright notice :

' Purchase of Philips I2c components conveys a licence under the Philips
I2C patent to use the components in the I2C system provided the system
conforms to the I2C specifications defined by Philips '


A) ACCESS bus.

A recent offspring of the I2C BUS is the ACCESS Bus. This bus was
codeveloped by Philips,Signetics,Digital and Intel.The goal was to
create a bus that could help us getting rid of all cabling involved
with computer peripherals. You would have 1 bus connector where you
could hook up your keyboard,mouse,digitizer,scanner,printer,monitor
etc.

Then by using sotware you could issue commands to your monitor or
printer.Things like selecting fonts or programming brightness and
picture size could be done from within software on the host platform.

Things like Hotplugging are included in the standard.There has been
a chip developed that could replace the standard 8042 (which is the
keyboard controller in an ibm PC) by an access bus controller.
Digital is using the bus in its Alpha based machines. Sony and some
other manufacturers have monitors that support the remote programming
features.Microsoft will support the bus fully .
(probably already in Windows 95).

Basically the hardware layer of the access bus is an I2C bus.
All that has been done is implementing a software protocol to
provide additional functionality to the system.


You can contact Sharon Baker at Signetics (408) 991-3518.
for further information

A company called Computer Access technology provides
plug in boards for IBM-PC that give your system ACCESS bus features.

Note that the address has changed since the FIRST FAQ issue.

Computer Access Technology ( CATC )
3375 Scott Blvd.
Suite #410
Santa Clara CA 95054

Phone +1-408-727-6600
Fax +1-408-727-6622

e-mail catc@netcom.com


B) address Map of existing I2C components.

+----+------------------------------------------------------------------------+
|Low | 000x 001x 010x 011x 100x 101x 110x 111x |
+----+------------------------------------------------------------------------+
|High| |
| | |
|0000| |
|0001| |
+----+------------------------------------------------------------------------+
|0010| SAA5240 SAA5240 SAA5240 SAF1134 SAA5252 SAA9020 SAA9020 SAA9020 |
| | SAA4700 SAA5241 SAB9070 SAF1135 SAA9020 |
| | SAF1134 SAA5243 SAF1134 |
| | SAF1135 SAA5244 SAF1135 |
| | SAA5245 |
| | SAA5246 |
| | SAA9041 |
| | SAA4700 |
| | SAF1134 |
| | SAF1135 |
+----+------------------------------------------------------------------------+
|0011| SAA7250 SAA7250 SAA1136 PCF1810 PCF1810 PCF1810 |
| | PCB5020 PCB5020 PCF1810 SAA1770 SAA1770 |
| | PCB5021 PCB5021 |
| | PCB5032 PCB5032 |
+----+------------------------------------------------------------------------+
|0100| SAA1137 SAA1137 PCA1070 PCA1070 PCD3311 PCD3311 SAB3028 PCD5002 |
| | PCD4430 PCD4430 PCD3312 PCD3312 |
| | SAA7194 SAA7194 |
| | PCF8574 PCF8574 PCF8574 PCF8574 PCF8574 PCF8574 PCF8574 PCF8574 |
| | TDA8444 TDA8444 TDA8444 TDA8444 TDA8444 TDA8444 TDA8444 TDA8444 |
+----+------------------------------------------------------------------------+
|0101| |
|0110| |
|0111| PCF8576 PCF8576 PCF8577 PCF8577A PCF8578 PCF8578 PCF8566 PCF8566 |
| | SAA1064 SAA1064 SAA1064 SAA1064 PCF8579 PCF8579 |
| | PCF8574A PCF8574A PCF8574A PCF8574A PCF8574A PCF8574A PCF8574A PCF8574A|
+----+------------------------------------------------------------------------+
|1000| TEA6320 TDA8424 TDA8405 |
| | TEA6330 TDA8425 TDA8415 |
| | TDA8526 TDA8416 |
| | TDA8420 TDA8420 TDA9840 |
| | TDA8421 TDA8421 TDA8940T |
| | TDA9860 TDA9860 TDA8417 |
| | NE5751 NE5751 TDA6360 TDA6360 |
| | TDA8480 TDA8480 |
+----+------------------------------------------------------------------------+
|1001| TDA8440 TDA8440 TDA8440 TDA8440 TDA8440 TDA8440 TDA8440 TDA8440 |
| | TDA8540 TDA8540 TDA8540 TDA8540 TDA8540 TDA8540 TDA8540 TDA8540 |
| | PCF8591 PCF8591 PCF8591 PCF8591 PCF8591 PCF8591 PCF8591 PCF8591 |
+----+------------------------------------------------------------------------+
|1010| PCF8570 PCF8570 PCF8570 PCF8570 PCF8570 PCF8570 PCF8570 PCF8570 |
| | PCF8571 PCF8571 PCF8571 PCF8571 PCF8571 PCF8571 PCF8571 PCF8571 |
| | PCF8580 PCF8580 PCF8580 PCF8580 PCF8580 PCF8580 PCF8580 PCF8580 |
| | PCF8582 PCF8582 PCF8582 PCF8582 PCF8582 PCF8582 PCF8582 PCF8582 |
| | PCF8581 PCF8581 PCF8581 PCF8581 PCF8581 PCF8581 PCF8581 PCF8581 |
| | PCF8582 PCF8582 PCF8582 PCF8582 PCF8582 PCF8582 PCF8582 PCF8582 |
| | PCF8583 PCF8583 |
+----+------------------------------------------------------------------------+
|1011| SAA7199 SAA7191 TDA8416 TDA2518 PCA8510 SAA7186 SAA9065 |
| | SAA7152 SAA7186 PCA8516 |
| | PCF8570C PCF8570C PCF8570C PCF8570C PCF8570C PCF8570C PCF8570C PCF8570C|
+----+------------------------------------------------------------------------+
|1100| |
| | TSA5510 TSA5510 TSA5510 TSA5510 TSA5510 TSA5510 TSA5510 TSA5510 |
| | TSA5511 TSA5511 TSA5511 TSA5511 TSA5511 TSA5511 TSA5511 TSA5511 |
| | TSA5512 TSA5512 TSA5512 TSA5512 TSA5512 TSA5512 TSA5512 TSA5512 |
| | TSA5514 TSA5514 TSA5514 TSA5514 TSA5514 TSA5514 TSA5514 TSA5514 |
| | TSA5519 TSA5519 TSA5519 TSA5519 TSA5519 TSA5519 TSA5519 TSA5519 |
| | SAB3035 SAB3035 SAB3035 SAB3035 SAB3035 SAB3035 SAB3035 SAB3035 |
| | SAB3036 SAB3036 SAB3036 SAB3036 SAB3036 SAB3036 SAB3036 SAB3036 |
| | SAB3037 SAB3037 SAB3037 SAB3037 SAB3037 SAB3037 SAB3037 SAB3037 |
| | UMA1010 UMA1010 UMA1010 UMA1010 UMA1010 UMA1010 UMA1010 UMA1010 |
| | UMA1009 UMA1009 UMA1009 UMA1009 UMA1009 UMA1009 UMA1009 UMA1009 |
| | TEA6000 TSA6057 TSA6057 |
| | TEA6100 PCA8516 PCA
Соседние файлы в предмете Проектирование электроприборов