TN215

Using the I2C Bus with a Rabbit Microprocessor

This document describes how to use the library, I2C.LIB, to enable the Rabbit 2000 microproccessor to communicate with I2C peripheral devices. The library covers the basic I2C protocol.

The term I2C comes from IIC, an acronym for Inter IC. The I2C bus is a popular way for a processor to communicate with peripheral chips on a board. Its simple and flexible nature make it a good choice for low-speed peripherals. There are a number of these that can be used by the Rabbit, including serial EEPROM chips, ADCs, and even more exotic types such as video switches and USB controllers.

Physical Properties of the I2C Bus

I2C is a synchronous serial bus that can be shared by several peripheral devices. The physical connection is made up of two wires (SCL and SDA) pulled up to a logic high level by resistors. All nodes on the bus use open-collector style drivers when controlling SCL or SDA. This prevents the possibility of contention between nodes.

I2C Protocol

The master (i.e. the Rabbit) normally controls the clock line (SCL) and determines when a data transfer will occur. Peripherals are not able to interrupt the master. A data bit on the SDA line is normally latched before the clock goes into a high state. The master can signal a start (S) or stop (P) condition by violating this and creating a transition while the clock is high. A falling edge indicates a start, while a rising edge indicates a stop. This is followed by bits being clocked out normally, with the most significant bit first. At the end of each byte, the master generates an extra clock pulse, and the receiver of the byte (slave or master) generates an acknowledge bit (ACK). The ACK is a low state on SDA while SCL is high.

Since SDA is pulled up, an ACK will only be generated if the receiver intentionally pulls the line low.

Which Parallel Port to Use

There are 5 parallel ports on the Rabbit 2000. The I2C library uses port D because it has open drain capabilities, which makes clock stretching easy to detect. Clock stretching is when a slave device needs more time to prepare to send a byte of data and so pulls SCL low to indicate that it is not yet ready.

Port D is hardcoded in i2c.lib with #ifndef directives. To use a different parallel port you must #define a few things in your application code, as well as change the function i2c_init(). Refer to i2c.lib, and specifically the comment "Define these to change basic bit handling," to see what needs to be done.

I2C Library API

The functions in I2C.LIB handle the generic aspects of an I2C interface. Drivers for specific I2C peripheral devices can easily be built with these functions. The basic operations for a Rabbit I2C master are:

These actions are combined in driver functions to communicate with a specific I2C device. For additional information on this API, refer to the Dynamic C User's Manual or use the "Function Lookup/Insert" feature on Dynamic C's Help menu.

Device Specific Functions

To write a set of functions for a given device, you will need to consult it's datasheet and write functions for each of the operations you wish to perform. This is simple, since the master's tasks breaks down into a series of byte writes and byte reads. Examples of higher-level API functions written for specific devices are in I2C_DEVICES.LIB. This library contains implementations for a 24LC16 EEPROM and a MAX518 DAC.

After writing a byte, the master usually listens for an acknowledgement bit and and acts appropriately depending on if one is received or not. Not receiving an ACK from the slave does not always indicate an error. Several types of I2C devices stop acknowledging while they are busy to indicate that they are not ready. EEPROMs doing a write operation and ADCs performing a conversion are good examples of this.

If the I2C device only receives commands, then it is a simple matter sending it a Start, writing the command bytes to it, listening for an ACK after each one, and finally ending with a Stop. If the device sends data back to the master, the operation is more complex.

In this case, the master starts the transfer by sending a Start followed by one or more bytes. The slave should ACK each of these. At some point the master will begin reading bytes from the device and sending an ACK bit after each one. The master usually ends the transfer by not acknowledging the last byte and then sending a Stop condition.

Note that even while reading, the master still controls the clock (SCL), but the device is controlling SDA

Sample Programs

Sample programs are available in the directory where Dynamic C was installed, in the folder Samples\I2C. The program, i2c_test.c, writes a string to the beginning of the memory space of a Microchip 24LC16 serial EEPORM, and then reads it back. The program, i2c_dac_sample.c, tests the connection of the Rabbit to a MAX517/518/519 chip This sample will cycle through DAC values zero through 255, creating a sawtooth output.

Summary

Communicating with devices over an I2C bus requires a tailored implementation for each device type. After reading this document and looking at the sample programs, you should be able to create an implementation for whatever device you will be using. The best resource for further informaion is the datasheet for the chip you are interfacing to the Rabbit. The better datasheets include an overview of I2C in addition to specifics about communicating with the chip. The I2C specification was developed by Philips Semiconductor and is available on their website:

www.semiconductors.philips.com.

022-0061 Rev. A
Z-World
http://www.zworld.com
Voice: (530) 757-3737
FAX: (530) 757-3792
sales@zworld.com
Rabbit Semiconductor
http://www.rabbitsemiconductor.com
Voice: (530) 757-8400
FAX: (530) 757-8402
sales@rabbitsemiconductor.com