i2c.c

00001 /*
00002  * Copyright (c) 2006, Swedish Institute of Computer Science
00003  * All rights reserved. 
00004  *
00005  * Redistribution and use in source and binary forms, with or without 
00006  * modification, are permitted provided that the following conditions 
00007  * are met: 
00008  * 1. Redistributions of source code must retain the above copyright 
00009  *    notice, this list of conditions and the following disclaimer. 
00010  * 2. Redistributions in binary form must reproduce the above copyright 
00011  *    notice, this list of conditions and the following disclaimer in the 
00012  *    documentation and/or other materials provided with the distribution. 
00013  * 3. Neither the name of the Institute nor the names of its contributors 
00014  *    may be used to endorse or promote products derived from this software 
00015  *    without specific prior written permission. 
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
00018  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
00021  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
00023  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
00024  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
00025  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
00026  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
00027  * SUCH DAMAGE. 
00028  *
00029  * @(#)$Id: i2c.c,v 1.2 2007/01/12 13:41:57 bg- Exp $
00030  */
00031 
00032 /*
00033  * Small and portable implementation of a bit-banging I2C bus master.
00034  *
00035  * The code should port really easily to platforms other than the
00036  * msp430 but has some hardcoded constants in it.
00037  *
00038  * More info at:
00039  *   http://i2c-bus.org/
00040  *   http://www.esacademy.com/faq/i2c/
00041  */
00042 
00043 #include <stdio.h>
00044 
00045 #include <io.h>
00046 
00047 #include <contiki.h>
00048 #include <dev/spi.h>
00049 #include <dev/leds.h>
00050 
00051 #include "dev/i2c.h"
00052 
00053 /*
00054  * On the Tmote sky access to I2C/SPI/UART0 must always be exclusive.
00055  */
00056 
00057 void     i2c_enable(void);
00058 void     i2c_disable(void);
00059 int      i2c_start(void);
00060 unsigned i2c_read(int send_ack);
00061 int      i2c_write(unsigned);
00062 void     i2c_stop(void);
00063 
00064 #define I2C_PxDIR   P3DIR
00065 #define I2C_PxIN    P3IN
00066 #define I2C_PxOUT   P3OUT
00067 #define I2C_PxSEL   P3SEL
00068 /*
00069  * SDA == P3.1
00070  * SCL == P3.3
00071  */
00072 #define SDA       1
00073 #define SCL       3
00074 
00075 #define SDA_0()   (I2C_PxDIR |=  BV(SDA))               /* SDA Output */
00076 #define SDA_1()   (I2C_PxDIR &= ~BV(SDA))               /* SDA Input */
00077 #define SDA_IS_1  (I2C_PxIN & BV(SDA))
00078 
00079 #define SCL_0()   (I2C_PxDIR |=  BV(SCL))               /* SCL Output */
00080 #define SCL_1()   (I2C_PxDIR &= ~BV(SCL))               /* SCL Input */
00081 #define SCL_IS_1  (I2C_PxIN & BV(SCL))
00082 
00083 /*
00084  * Should avoid infinite looping while waiting for SCL_IS_1. xxx/bg
00085  */
00086 #define SCL_WAIT_FOR_1() do{}while (!SCL_IS_1)
00087 
00088 #define delay_4_7us() do{ _NOP(); _NOP(); _NOP(); _NOP(); \
00089                           _NOP(); _NOP(); _NOP(); _NOP(); \
00090                           _NOP(); _NOP(); _NOP(); _NOP(); }while(0)
00091 
00092 #define delay_4us()   do{ _NOP(); _NOP(); _NOP(); _NOP(); \
00093                           _NOP(); _NOP(); _NOP(); _NOP(); \
00094                           _NOP(); _NOP(); }while(0)
00095 
00096 static unsigned char old_pxsel, old_pxout, old_pxdir;
00097 
00098 /*
00099  * Grab SDA and SCL pins for exclusive use but remember old
00100  * configuration so that it may be restored when we are done.
00101  */
00102 void
00103 i2c_enable(void)
00104 {
00105   unsigned char sda_scl = BV(SDA)|BV(SCL);
00106 
00107   old_pxsel = I2C_PxSEL & sda_scl;
00108   old_pxout = I2C_PxOUT & sda_scl;
00109   old_pxdir = I2C_PxDIR & sda_scl;
00110 
00111   spi_busy = 1;
00112 
00113   I2C_PxSEL &= ~sda_scl;
00114 
00115   I2C_PxOUT &= ~sda_scl;
00116 
00117   I2C_PxDIR |=  BV(SCL);                /* SCL Output */
00118   I2C_PxDIR &= ~BV(SDA);                /* SDA Input */
00119 }
00120 
00121 /*
00122  * Restore bus to what it was before i2c_enable.
00123  *
00124  */
00125 void
00126 i2c_disable(void)
00127 {
00128   unsigned char not_sda_scl = ~(BV(SDA)|BV(SCL));
00129 
00130   I2C_PxDIR = (I2C_PxDIR & not_sda_scl) | old_pxdir;
00131   I2C_PxOUT = (I2C_PxOUT & not_sda_scl) | old_pxout;
00132   I2C_PxSEL = (I2C_PxSEL & not_sda_scl) | old_pxsel;
00133 
00134   spi_busy = 0;
00135 }
00136 
00137 int
00138 i2c_start(void)
00139 {
00140   SDA_1();
00141   SCL_1();
00142 #if 1
00143   SCL_WAIT_FOR_1();
00144 #else
00145   {
00146     unsigned long n;
00147     for (n = 0; n < 100000 && !SCL_IS_1; n++)
00148       ;
00149     if (!SCL_IS_1)
00150       return -1;
00151   }
00152 #endif
00153   delay_4_7us();
00154   SDA_0();
00155   delay_4us();
00156   SCL_0();
00157   return 0;
00158 }
00159 
00160 void
00161 i2c_stop(void)
00162 {
00163   SDA_0();
00164   delay_4us();
00165   SCL_1();
00166   SCL_WAIT_FOR_1();
00167   SDA_1();
00168 }
00169 
00170 /*
00171  * Return true if we received an ACK.
00172  */
00173 int
00174 i2c_write(unsigned _c)
00175 {
00176   unsigned char c = _c;
00177   unsigned long n;
00178   int i;
00179   int ret;
00180 
00181   for (i = 0; i < 8; i++, c <<= 1) {
00182     if (c & 0x80)
00183       SDA_1();
00184     else
00185       SDA_0();
00186     SCL_1();
00187     SCL_WAIT_FOR_1();
00188     SCL_0();
00189   }
00190 
00191   SDA_1();
00192   SCL_1();
00193   ret = 0;                 /* Loop waiting for an ACK to arrive. */
00194   for (n = 0; n < 250000; n++) {
00195     if (!SDA_IS_1) {
00196       ret = 1;
00197       break;
00198     }
00199   }
00200   SCL_WAIT_FOR_1();             /* clock stretching? */
00201   SCL_0();
00202 
00203   return ret;
00204 }
00205 
00206 unsigned
00207 i2c_read(int send_ack)
00208 {
00209   int i;
00210   unsigned char c = 0x00;
00211 
00212   SDA_1();
00213   for (i = 0; i < 8; i++) {
00214     c <<= 1;
00215     SCL_1();
00216     SCL_WAIT_FOR_1();
00217     if (SDA_IS_1)
00218       c |= 0x1;
00219     SCL_0();
00220   }
00221 
00222   if (send_ack)
00223     SDA_0();
00224   SCL_1();
00225   SCL_WAIT_FOR_1();
00226   SCL_0();
00227 
00228   return c;
00229 }

Generated on Mon Apr 11 14:23:45 2011 for Contiki 2.5 by  doxygen 1.6.1