i2c_bitbang.c
Go to the documentation of this file.00001
00039 #include "hw/hw_i2c_bitbang.h"
00040
00041 #include "cfg/cfg_i2c.h"
00042
00043 #define LOG_LEVEL I2C_LOG_LEVEL
00044 #define LOG_FORMAT I2C_LOG_FORMAT
00045
00046 #include <cfg/log.h>
00047 #include <cfg/macros.h>
00048 #include <cfg/module.h>
00049
00050 #include <drv/timer.h>
00051 #include <drv/i2c.h>
00052
00053 #include <cpu/irq.h>
00054
00055 #include <cpu/attr.h>
00056
00057 #if !CONFIG_I2C_DISABLE_OLD_API
00058
00059 INLINE bool i2c_bitbang_start(void)
00060 {
00061 SDA_HI;
00062 SCL_HI;
00063 I2C_HALFBIT_DELAY();
00064 SDA_LO;
00065 I2C_HALFBIT_DELAY();
00066
00067 return !SDA_IN;
00068 }
00069
00070 void i2c_bitbang_stop(void)
00071 {
00072 SDA_LO;
00073 SCL_HI;
00074 I2C_HALFBIT_DELAY();
00075 SDA_HI;
00076 }
00077
00078 bool i2c_bitbang_put(uint8_t _data)
00079 {
00080
00081 uint16_t data = (_data << 1) | 1;
00082
00083 for (uint16_t i = 0x100; i != 0; i >>= 1)
00084 {
00085 SCL_LO;
00086 if (data & i)
00087 SDA_HI;
00088 else
00089 SDA_LO;
00090 I2C_HALFBIT_DELAY();
00091
00092 SCL_HI;
00093 I2C_HALFBIT_DELAY();
00094 }
00095
00096 bool ack = !SDA_IN;
00097 SCL_LO;
00098 I2C_HALFBIT_DELAY();
00099 return ack;
00100 }
00101
00102 bool i2c_bitbang_start_w(uint8_t id)
00103 {
00104 id &= ~I2C_READBIT;
00105
00106
00107
00108
00109
00110
00111 ticks_t start = timer_clock();
00112 while (i2c_bitbang_start())
00113 {
00114 if (i2c_bitbang_put(id))
00115 return true;
00116 else if (timer_clock() - start > ms_to_ticks(CONFIG_I2C_START_TIMEOUT))
00117 {
00118 LOG_ERR("Timeout on I2C start write\n");
00119 break;
00120 }
00121
00122 }
00123
00124 return false;
00125 }
00126
00127 bool i2c_bitbang_start_r(uint8_t id)
00128 {
00129 id |= I2C_READBIT;
00130 if (i2c_bitbang_start())
00131 {
00132 if (i2c_bitbang_put(id))
00133 return true;
00134
00135 LOG_ERR("NACK on I2c start read\n");
00136 }
00137
00138 return false;
00139 }
00140
00141 int i2c_bitbang_get(bool ack)
00142 {
00143 uint8_t data = 0;
00144 for (uint8_t i = 0x80; i != 0; i >>= 1)
00145 {
00146 SCL_LO;
00147 I2C_HALFBIT_DELAY();
00148 SCL_HI;
00149 if (SDA_IN)
00150 data |= i;
00151 else
00152 data &= ~i;
00153
00154 I2C_HALFBIT_DELAY();
00155 }
00156 SCL_LO;
00157
00158 if (ack)
00159 SDA_LO;
00160 else
00161 SDA_HI;
00162
00163 I2C_HALFBIT_DELAY();
00164 SCL_HI;
00165 I2C_HALFBIT_DELAY();
00166 SCL_LO;
00167 SDA_HI;
00168
00169 return (int)(uint8_t)data;
00170 }
00171
00172 #endif
00173
00174
00175
00176
00177 static bool old_api = false;
00178 #define I2C_DEV(i2c) ((int)((i2c)->hw))
00179
00180 static void i2c_bitbang_stop_1(struct I2c *i2c)
00181 {
00182 if (old_api)
00183 {
00184 SDA_LO;
00185 SCL_HI;
00186 I2C_HALFBIT_DELAY();
00187 SDA_HI;
00188 }
00189 else
00190 {
00191 i2c_sdaLo(I2C_DEV(i2c));
00192 i2c_sclHi(I2C_DEV(i2c));
00193 i2c_halfbitDelay(I2C_DEV(i2c));
00194 i2c_sdaHi(I2C_DEV(i2c));
00195 }
00196 }
00197
00198 INLINE bool i2c_bitbang_start_1(struct I2c *i2c)
00199 {
00200 bool ret;
00201
00202 i2c->errors &= ~(I2C_NO_ACK | I2C_ARB_LOST);
00203
00204 if (old_api)
00205 {
00206 SDA_HI;
00207 SCL_HI;
00208 I2C_HALFBIT_DELAY();
00209 SDA_LO;
00210 I2C_HALFBIT_DELAY();
00211
00212 ret = !SDA_IN;
00213 }
00214 else
00215 {
00216 i2c_sdaHi(I2C_DEV(i2c));
00217 i2c_sclHi(I2C_DEV(i2c));
00218 i2c_halfbitDelay(I2C_DEV(i2c));
00219 i2c_sdaLo(I2C_DEV(i2c));
00220 i2c_halfbitDelay(I2C_DEV(i2c));
00221
00222 ret = !i2c_sdaIn(I2C_DEV(i2c));
00223 }
00224
00225 return ret;
00226 }
00227
00228
00229 static uint8_t i2c_bitbang_getc(struct I2c *i2c)
00230 {
00231 uint8_t data = 0;
00232 if (old_api)
00233 {
00234 for (uint8_t i = 0x80; i != 0; i >>= 1)
00235 {
00236 SCL_LO;
00237 I2C_HALFBIT_DELAY();
00238 SCL_HI;
00239 if (SDA_IN)
00240 data |= i;
00241 else
00242 data &= ~i;
00243
00244 I2C_HALFBIT_DELAY();
00245 }
00246 SCL_LO;
00247
00248
00249 if (i2c->xfer_size > 1)
00250 SDA_LO;
00251 else
00252 SDA_HI;
00253
00254 I2C_HALFBIT_DELAY();
00255 SCL_HI;
00256 I2C_HALFBIT_DELAY();
00257 SCL_LO;
00258 SDA_HI;
00259 }
00260 else
00261 {
00262 for (uint8_t i = 0x80; i != 0; i >>= 1)
00263 {
00264 i2c_sclLo(I2C_DEV(i2c));
00265 i2c_halfbitDelay(I2C_DEV(i2c));
00266 i2c_sclHi(I2C_DEV(i2c));
00267 if (i2c_sdaIn(I2C_DEV(i2c)))
00268 data |= i;
00269 else
00270 data &= ~i;
00271
00272 i2c_halfbitDelay(I2C_DEV(i2c));
00273 }
00274 i2c_sclLo(I2C_DEV(i2c));
00275
00276
00277 if (i2c->xfer_size > 1)
00278 i2c_sdaLo(I2C_DEV(i2c));
00279 else
00280 i2c_sdaHi(I2C_DEV(i2c));
00281
00282 i2c_halfbitDelay(I2C_DEV(i2c));
00283 i2c_sclHi(I2C_DEV(i2c));
00284 i2c_halfbitDelay(I2C_DEV(i2c));
00285 i2c_sclLo(I2C_DEV(i2c));
00286 i2c_sdaHi(I2C_DEV(i2c));
00287 }
00288
00289
00290 if ((i2c->xfer_size == 1) && (i2c->flags & I2C_STOP))
00291 i2c_bitbang_stop_1(i2c);
00292
00293 return data;
00294 }
00295
00296 INLINE void i2c_bitbang_putcStop(struct I2c *i2c, uint8_t _data, bool stop)
00297 {
00298
00299 uint16_t data = (_data << 1) | 1;
00300 bool ack;
00301
00302 if (old_api)
00303 {
00304 for (uint16_t i = 0x100; i != 0; i >>= 1)
00305 {
00306 SCL_LO;
00307 if (data & i)
00308 SDA_HI;
00309 else
00310 SDA_LO;
00311 I2C_HALFBIT_DELAY();
00312
00313 SCL_HI;
00314 I2C_HALFBIT_DELAY();
00315 }
00316
00317 ack = !SDA_IN;
00318 SCL_LO;
00319 I2C_HALFBIT_DELAY();
00320 }
00321 else
00322 {
00323 for (uint16_t i = 0x100; i != 0; i >>= 1)
00324 {
00325 i2c_sclLo(I2C_DEV(i2c));
00326 if (data & i)
00327 i2c_sdaHi(I2C_DEV(i2c));
00328 else
00329 i2c_sdaLo(I2C_DEV(i2c));
00330 i2c_halfbitDelay(I2C_DEV(i2c));
00331
00332 i2c_sclHi(I2C_DEV(i2c));
00333 i2c_halfbitDelay(I2C_DEV(i2c));
00334 }
00335 ack = !i2c_sdaIn(I2C_DEV(i2c));
00336
00337 i2c_sclLo(I2C_DEV(i2c));
00338 i2c_halfbitDelay(I2C_DEV(i2c));
00339 }
00340
00341 if (!ack)
00342 i2c->errors |= I2C_NO_ACK;
00343
00344
00345 if (stop || i2c->errors)
00346 i2c_bitbang_stop_1(i2c);
00347 }
00348
00349 static void i2c_bitbang_putc(struct I2c *i2c, uint8_t data)
00350 {
00351 i2c_bitbang_putcStop(i2c, data,
00352 (i2c->xfer_size == 1) && (i2c->flags & I2C_STOP));
00353 }
00354
00355 static void i2c_bitbang_start_2(struct I2c *i2c, uint16_t slave_addr)
00356 {
00357 if (i2c->flags & I2C_START_R)
00358 slave_addr |= I2C_READBIT;
00359 else
00360 slave_addr &= ~I2C_READBIT;
00361
00362
00363
00364
00365
00366
00367
00368 ticks_t start = timer_clock();
00369 while (i2c_bitbang_start_1(i2c))
00370 {
00371 i2c_bitbang_putcStop(i2c, slave_addr, false);
00372
00373 if (!(i2c->errors & I2C_NO_ACK))
00374 return;
00375 else if (timer_clock() - start > ms_to_ticks(CONFIG_I2C_START_TIMEOUT))
00376 {
00377 LOG_ERR("Timeout on I2C start\n");
00378 i2c->errors |= I2C_START_TIMEOUT;
00379 i2c_bitbang_stop_1(i2c);
00380 return;
00381 }
00382 }
00383
00384 LOG_ERR("START arbitration lost\n");
00385 i2c->errors |= I2C_ARB_LOST;
00386 i2c_bitbang_stop_1(i2c);
00387 return;
00388 }
00389
00390
00391 static const I2cVT i2c_bitbang_vt =
00392 {
00393 .start = i2c_bitbang_start_2,
00394 .getc = i2c_bitbang_getc,
00395 .putc = i2c_bitbang_putc,
00396 .write = i2c_genericWrite,
00397 .read = i2c_genericRead,
00398 };
00399
00400
00404 void i2c_hw_bitbangInit(I2c *i2c, int dev)
00405 {
00406 MOD_CHECK(timer);
00407 if (dev == I2C_BITBANG_OLD)
00408 old_api = true;
00409 else
00410 i2c->hw = (struct I2cHardware *)(dev - I2C_BITBANG0);
00411
00412 i2c->vt = &i2c_bitbang_vt;
00413
00414 if (old_api)
00415 {
00416 I2C_BITBANG_HW_INIT;
00417 SDA_HI;
00418 SCL_HI;
00419 }
00420 else
00421 {
00422 i2c_bitbangInit(I2C_DEV(i2c));
00423 i2c_sdaHi(I2C_DEV(i2c));
00424 i2c_sclHi(I2C_DEV(i2c));
00425 }
00426 }
00427