i2c.c
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
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
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
00070
00071
00072 #define SDA 1
00073 #define SCL 3
00074
00075 #define SDA_0() (I2C_PxDIR |= BV(SDA))
00076 #define SDA_1() (I2C_PxDIR &= ~BV(SDA))
00077 #define SDA_IS_1 (I2C_PxIN & BV(SDA))
00078
00079 #define SCL_0() (I2C_PxDIR |= BV(SCL))
00080 #define SCL_1() (I2C_PxDIR &= ~BV(SCL))
00081 #define SCL_IS_1 (I2C_PxIN & BV(SCL))
00082
00083
00084
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
00100
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);
00118 I2C_PxDIR &= ~BV(SDA);
00119 }
00120
00121
00122
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
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;
00194 for (n = 0; n < 250000; n++) {
00195 if (!SDA_IS_1) {
00196 ret = 1;
00197 break;
00198 }
00199 }
00200 SCL_WAIT_FOR_1();
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 }