Contiki 2.6

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 #include <contiki.h>
00045 #include <dev/spi.h>
00046 #include <dev/leds.h>
00047 
00048 #include "dev/i2c.h"
00049 
00050 /*
00051  * On the Tmote sky access to I2C/SPI/UART0 must always be exclusive.
00052  */
00053 
00054 void     i2c_enable(void);
00055 void     i2c_disable(void);
00056 int      i2c_start(void);
00057 unsigned i2c_read(int send_ack);
00058 int      i2c_write(unsigned);
00059 void     i2c_stop(void);
00060 
00061 #define I2C_PxDIR   P3DIR
00062 #define I2C_PxIN    P3IN
00063 #define I2C_PxOUT   P3OUT
00064 #define I2C_PxSEL   P3SEL
00065 /*
00066  * SDA == P3.1
00067  * SCL == P3.3
00068  */
00069 #define SDA       1
00070 #define SCL       3
00071 
00072 #define SDA_0()   (I2C_PxDIR |=  BV(SDA))               /* SDA Output */
00073 #define SDA_1()   (I2C_PxDIR &= ~BV(SDA))               /* SDA Input */
00074 #define SDA_IS_1  (I2C_PxIN & BV(SDA))
00075 
00076 #define SCL_0()   (I2C_PxDIR |=  BV(SCL))               /* SCL Output */
00077 #define SCL_1()   (I2C_PxDIR &= ~BV(SCL))               /* SCL Input */
00078 #define SCL_IS_1  (I2C_PxIN & BV(SCL))
00079 
00080 /*
00081  * Should avoid infinite looping while waiting for SCL_IS_1. xxx/bg
00082  */
00083 #define SCL_WAIT_FOR_1() do{}while (!SCL_IS_1)
00084 
00085 #define delay_4_7us() do{ _NOP(); _NOP(); _NOP(); _NOP(); \
00086                           _NOP(); _NOP(); _NOP(); _NOP(); \
00087                           _NOP(); _NOP(); _NOP(); _NOP(); }while(0)
00088 
00089 #define delay_4us()   do{ _NOP(); _NOP(); _NOP(); _NOP(); \
00090                           _NOP(); _NOP(); _NOP(); _NOP(); \
00091                           _NOP(); _NOP(); }while(0)
00092 
00093 static unsigned char old_pxsel, old_pxout, old_pxdir;
00094 
00095 /*
00096  * Grab SDA and SCL pins for exclusive use but remember old
00097  * configuration so that it may be restored when we are done.
00098  */
00099 void
00100 i2c_enable(void)
00101 {
00102   unsigned char sda_scl = BV(SDA)|BV(SCL);
00103 
00104   old_pxsel = I2C_PxSEL & sda_scl;
00105   old_pxout = I2C_PxOUT & sda_scl;
00106   old_pxdir = I2C_PxDIR & sda_scl;
00107 
00108   spi_busy = 1;
00109 
00110   I2C_PxSEL &= ~sda_scl;
00111 
00112   I2C_PxOUT &= ~sda_scl;
00113 
00114   I2C_PxDIR |=  BV(SCL);                /* SCL Output */
00115   I2C_PxDIR &= ~BV(SDA);                /* SDA Input */
00116 }
00117 
00118 /*
00119  * Restore bus to what it was before i2c_enable.
00120  *
00121  */
00122 void
00123 i2c_disable(void)
00124 {
00125   unsigned char not_sda_scl = ~(BV(SDA)|BV(SCL));
00126 
00127   I2C_PxDIR = (I2C_PxDIR & not_sda_scl) | old_pxdir;
00128   I2C_PxOUT = (I2C_PxOUT & not_sda_scl) | old_pxout;
00129   I2C_PxSEL = (I2C_PxSEL & not_sda_scl) | old_pxsel;
00130 
00131   spi_busy = 0;
00132 }
00133 
00134 int
00135 i2c_start(void)
00136 {
00137   SDA_1();
00138   SCL_1();
00139 #if 1
00140   SCL_WAIT_FOR_1();
00141 #else
00142   {
00143     unsigned long n;
00144     for (n = 0; n < 100000 && !SCL_IS_1; n++)
00145       ;
00146     if (!SCL_IS_1)
00147       return -1;
00148   }
00149 #endif
00150   delay_4_7us();
00151   SDA_0();
00152   delay_4us();
00153   SCL_0();
00154   return 0;
00155 }
00156 
00157 void
00158 i2c_stop(void)
00159 {
00160   SDA_0();
00161   delay_4us();
00162   SCL_1();
00163   SCL_WAIT_FOR_1();
00164   SDA_1();
00165 }
00166 
00167 /*
00168  * Return true if we received an ACK.
00169  */
00170 int
00171 i2c_write(unsigned _c)
00172 {
00173   unsigned char c = _c;
00174   unsigned long n;
00175   int i;
00176   int ret;
00177 
00178   for (i = 0; i < 8; i++, c <<= 1) {
00179     if (c & 0x80)
00180       SDA_1();
00181     else
00182       SDA_0();
00183     SCL_1();
00184     SCL_WAIT_FOR_1();
00185     SCL_0();
00186   }
00187 
00188   SDA_1();
00189   SCL_1();
00190   ret = 0;                 /* Loop waiting for an ACK to arrive. */
00191   for (n = 0; n < 250000; n++) {
00192     if (!SDA_IS_1) {
00193       ret = 1;
00194       break;
00195     }
00196   }
00197   SCL_WAIT_FOR_1();             /* clock stretching? */
00198   SCL_0();
00199 
00200   return ret;
00201 }
00202 
00203 unsigned
00204 i2c_read(int send_ack)
00205 {
00206   int i;
00207   unsigned char c = 0x00;
00208 
00209   SDA_1();
00210   for (i = 0; i < 8; i++) {
00211     c <<= 1;
00212     SCL_1();
00213     SCL_WAIT_FOR_1();
00214     if (SDA_IS_1)
00215       c |= 0x1;
00216     SCL_0();
00217   }
00218 
00219   if (send_ack)
00220     SDA_0();
00221   SCL_1();
00222   SCL_WAIT_FOR_1();
00223   SCL_0();
00224 
00225   return c;
00226 }