The Software for Minimal I2C
The Software for Minimal I2C
Are you an I2C noob? If so, check out this article before trying to port the source code.
Before we actually get into the software, these diagrams show how the bus is hooked up to the CPU.
C - language Source code for Minimal I2C
The following source code is an example of a minimal I2C implementation. It was actually translated from FORTH, so this may contain some small mistakes.
CPU-Dependent Primitives
The following bits are implementation-dependent code, which will vary depending on which CPU is being used.
#define SCLOUT( val ) set_p0_state( val ) /* CPU Dependent function to set p0 to low-state val=0, or float val=1 */
#define SDAOUT( val ) set_p1_state( val )
#define SCL_IN get_p0_state() /* Returns 1 if p0 is high, or 0 if p0 is low. */
#define SDA_IN get_p1_state()
#define MSEC_DELAY(usec) cpu_dependent_delay(usec) /* Waste time for some microseconds (not milliseconds) */
typedef unsigned char BYTE
Initialization
The first software step is to initialize the io ports to be open collector outputs, and then put the bus into an idle state. An idle state is where both lines are high. It may also be a good idea to generate aSTOP condition on the bus before putting it idle.
void i2c_setup()
{
set_p0_open_collector(); /* Implementation dependent - must be made to match your CPU */
set_p1_open_collector();
SCLOUT(0); /* Generate a STOP condition */
SDAOUT(0);
SCLOUT(1); /* SCL is high */
MSEC_DELAY(10); /* Wait */
SDAOUT(1); /* Now cause a low-to-high transistion on SDA */
}
I2C Start and Stop Conditions
The following code implements the I2C Start and Stop conditions using the primitives defined above.
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
\\ void i2c_do_stop(void) \\ puts data low, then clock low, \\ then clock high, then data high. \\ This should cause a stop, which \\ should idle the bus, I.E. both clk and data are high. \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ void i2c_do_stop(void) { SCLOUT(0); MSEC_DELAY(10); SDAOUT(0); MSEC_DELAY(10); SCLOUT(1); MSEC_DELAY(10); SDAOUT(1); } \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\ void i2c_do_start(void) \\ Sets clock high, then data high. This will do a stop if data was low. \\ Then sets data low, which should be a start condition. \\ After executing, data is left low, while clock is left high \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ void i2c_do_start(void) { SCLOUT(1); SDAOUT(1); MSEC_DELAY(10); SDAOUT(0); MSEC_DELAY(10); \\ waste time }
Next - More I2c Source Code
|
Last Updated on Sunday, 17 May 2009 13:52 |