i2c_bitbang.c
Go to the documentation of this file.00001
00039 #include "i2c.h"
00040 #include "cfg/cfg_i2c.h"
00041
00042 #define LOG_LEVEL I2C_LOG_LEVEL
00043 #define LOG_FORMAT I2C_LOG_FORMAT
00044
00045 #include <cfg/log.h>
00046 #include <cfg/macros.h>
00047 #include <cfg/module.h>
00048
00049 #include <drv/timer.h>
00050 #include <cpu/irq.h>
00051
00052 #include "hw/hw_i2c_bitbang.h"
00053
00054 INLINE bool i2c_bitbang_start(void)
00055 {
00056 SDA_HI;
00057 SCL_HI;
00058 I2C_HALFBIT_DELAY();
00059 SDA_LO;
00060 I2C_HALFBIT_DELAY();
00061 ASSERT(!SDA_IN);
00062 return !SDA_IN;
00063 }
00064
00065 void i2c_bitbang_stop(void)
00066 {
00067 SDA_LO;
00068 SCL_HI;
00069 I2C_HALFBIT_DELAY();
00070 SDA_HI;
00071 }
00072
00073 bool i2c_bitbang_put(uint8_t _data)
00074 {
00075
00076 uint16_t data = (_data << 1) | 1;
00077
00078 for (uint16_t i = 0x100; i != 0; i >>= 1)
00079 {
00080 SCL_LO;
00081 if (data & i)
00082 SDA_HI;
00083 else
00084 SDA_LO;
00085 I2C_HALFBIT_DELAY();
00086
00087 SCL_HI;
00088 I2C_HALFBIT_DELAY();
00089 }
00090
00091 bool ack = !SDA_IN;
00092 SCL_LO;
00093 I2C_HALFBIT_DELAY();
00094 return ack;
00095 }
00096
00097 bool i2c_bitbang_start_w(uint8_t id)
00098 {
00099 id &= ~I2C_READBIT;
00100
00101
00102
00103
00104
00105
00106 ticks_t start = timer_clock();
00107 while (i2c_bitbang_start())
00108 {
00109 if (i2c_bitbang_put(id))
00110 return true;
00111 else if (timer_clock() - start > ms_to_ticks(CONFIG_I2C_START_TIMEOUT))
00112 {
00113 LOG_ERR("Timeout on I2C start write\n");
00114 break;
00115 }
00116
00117 }
00118
00119 return false;
00120 }
00121
00122 bool i2c_bitbang_start_r(uint8_t id)
00123 {
00124 id |= I2C_READBIT;
00125 if (i2c_bitbang_start())
00126 {
00127 if (i2c_bitbang_put(id))
00128 return true;
00129
00130 LOG_ERR("NACK on I2c start read\n");
00131 }
00132
00133 return false;
00134 }
00135
00136 int i2c_bitbang_get(bool ack)
00137 {
00138 uint8_t data = 0;
00139 for (uint8_t i = 0x80; i != 0; i >>= 1)
00140 {
00141 SCL_LO;
00142 I2C_HALFBIT_DELAY();
00143 SCL_HI;
00144 if (SDA_IN)
00145 data |= i;
00146 else
00147 data &= ~i;
00148
00149 I2C_HALFBIT_DELAY();
00150 }
00151 SCL_LO;
00152
00153 if (ack)
00154 SDA_LO;
00155 else
00156 SDA_HI;
00157
00158 I2C_HALFBIT_DELAY();
00159 SCL_HI;
00160 I2C_HALFBIT_DELAY();
00161 SCL_LO;
00162 SDA_HI;
00163
00164 return (int)(uint8_t)data;
00165 }
00166
00167 MOD_DEFINE(i2c);
00168
00172 void i2c_bitbang_init(void)
00173 {
00174 MOD_CHECK(timer);
00175 I2C_BITBANG_HW_INIT;
00176 SDA_HI;
00177 SCL_HI;
00178 MOD_INIT(i2c);
00179 }
00180