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