Contiki 2.5
i2c.c
1 /*
2  * Copyright (c) 2006, Swedish Institute of Computer Science
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the Institute nor the names of its contributors
14  * may be used to endorse or promote products derived from this software
15  * without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * @(#)$Id: i2c.c,v 1.2 2007/01/12 13:41:57 bg- Exp $
30  */
31 
32 /*
33  * Small and portable implementation of a bit-banging I2C bus master.
34  *
35  * The code should port really easily to platforms other than the
36  * msp430 but has some hardcoded constants in it.
37  *
38  * More info at:
39  * http://i2c-bus.org/
40  * http://www.esacademy.com/faq/i2c/
41  */
42 
43 #include <stdio.h>
44 #include <contiki.h>
45 #include <dev/spi.h>
46 #include <dev/leds.h>
47 
48 #include "dev/i2c.h"
49 
50 /*
51  * On the Tmote sky access to I2C/SPI/UART0 must always be exclusive.
52  */
53 
54 void i2c_enable(void);
55 void i2c_disable(void);
56 int i2c_start(void);
57 unsigned i2c_read(int send_ack);
58 int i2c_write(unsigned);
59 void i2c_stop(void);
60 
61 #define I2C_PxDIR P3DIR
62 #define I2C_PxIN P3IN
63 #define I2C_PxOUT P3OUT
64 #define I2C_PxSEL P3SEL
65 /*
66  * SDA == P3.1
67  * SCL == P3.3
68  */
69 #define SDA 1
70 #define SCL 3
71 
72 #define SDA_0() (I2C_PxDIR |= BV(SDA)) /* SDA Output */
73 #define SDA_1() (I2C_PxDIR &= ~BV(SDA)) /* SDA Input */
74 #define SDA_IS_1 (I2C_PxIN & BV(SDA))
75 
76 #define SCL_0() (I2C_PxDIR |= BV(SCL)) /* SCL Output */
77 #define SCL_1() (I2C_PxDIR &= ~BV(SCL)) /* SCL Input */
78 #define SCL_IS_1 (I2C_PxIN & BV(SCL))
79 
80 /*
81  * Should avoid infinite looping while waiting for SCL_IS_1. xxx/bg
82  */
83 #define SCL_WAIT_FOR_1() do{}while (!SCL_IS_1)
84 
85 #define delay_4_7us() do{ _NOP(); _NOP(); _NOP(); _NOP(); \
86  _NOP(); _NOP(); _NOP(); _NOP(); \
87  _NOP(); _NOP(); _NOP(); _NOP(); }while(0)
88 
89 #define delay_4us() do{ _NOP(); _NOP(); _NOP(); _NOP(); \
90  _NOP(); _NOP(); _NOP(); _NOP(); \
91  _NOP(); _NOP(); }while(0)
92 
93 static unsigned char old_pxsel, old_pxout, old_pxdir;
94 
95 /*
96  * Grab SDA and SCL pins for exclusive use but remember old
97  * configuration so that it may be restored when we are done.
98  */
99 void
100 i2c_enable(void)
101 {
102  unsigned char sda_scl = BV(SDA)|BV(SCL);
103 
104  old_pxsel = I2C_PxSEL & sda_scl;
105  old_pxout = I2C_PxOUT & sda_scl;
106  old_pxdir = I2C_PxDIR & sda_scl;
107 
108  spi_busy = 1;
109 
110  I2C_PxSEL &= ~sda_scl;
111 
112  I2C_PxOUT &= ~sda_scl;
113 
114  I2C_PxDIR |= BV(SCL); /* SCL Output */
115  I2C_PxDIR &= ~BV(SDA); /* SDA Input */
116 }
117 
118 /*
119  * Restore bus to what it was before i2c_enable.
120  *
121  */
122 void
123 i2c_disable(void)
124 {
125  unsigned char not_sda_scl = ~(BV(SDA)|BV(SCL));
126 
127  I2C_PxDIR = (I2C_PxDIR & not_sda_scl) | old_pxdir;
128  I2C_PxOUT = (I2C_PxOUT & not_sda_scl) | old_pxout;
129  I2C_PxSEL = (I2C_PxSEL & not_sda_scl) | old_pxsel;
130 
131  spi_busy = 0;
132 }
133 
134 int
135 i2c_start(void)
136 {
137  SDA_1();
138  SCL_1();
139 #if 1
140  SCL_WAIT_FOR_1();
141 #else
142  {
143  unsigned long n;
144  for (n = 0; n < 100000 && !SCL_IS_1; n++)
145  ;
146  if (!SCL_IS_1)
147  return -1;
148  }
149 #endif
150  delay_4_7us();
151  SDA_0();
152  delay_4us();
153  SCL_0();
154  return 0;
155 }
156 
157 void
158 i2c_stop(void)
159 {
160  SDA_0();
161  delay_4us();
162  SCL_1();
163  SCL_WAIT_FOR_1();
164  SDA_1();
165 }
166 
167 /*
168  * Return true if we received an ACK.
169  */
170 int
171 i2c_write(unsigned _c)
172 {
173  unsigned char c = _c;
174  unsigned long n;
175  int i;
176  int ret;
177 
178  for (i = 0; i < 8; i++, c <<= 1) {
179  if (c & 0x80)
180  SDA_1();
181  else
182  SDA_0();
183  SCL_1();
184  SCL_WAIT_FOR_1();
185  SCL_0();
186  }
187 
188  SDA_1();
189  SCL_1();
190  ret = 0; /* Loop waiting for an ACK to arrive. */
191  for (n = 0; n < 250000; n++) {
192  if (!SDA_IS_1) {
193  ret = 1;
194  break;
195  }
196  }
197  SCL_WAIT_FOR_1(); /* clock stretching? */
198  SCL_0();
199 
200  return ret;
201 }
202 
203 unsigned
204 i2c_read(int send_ack)
205 {
206  int i;
207  unsigned char c = 0x00;
208 
209  SDA_1();
210  for (i = 0; i < 8; i++) {
211  c <<= 1;
212  SCL_1();
213  SCL_WAIT_FOR_1();
214  if (SDA_IS_1)
215  c |= 0x1;
216  SCL_0();
217  }
218 
219  if (send_ack)
220  SDA_0();
221  SCL_1();
222  SCL_WAIT_FOR_1();
223  SCL_0();
224 
225  return c;
226 }