2 * This file is part of Cleanflight and Betaflight.
4 * Cleanflight and Betaflight are free software. You can redistribute
5 * this software and/or modify this software under the terms of the
6 * GNU General Public License as published by the Free Software
7 * Foundation, either version 3 of the License, or (at your option)
10 * Cleanflight and Betaflight are distributed in the hope that they
11 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this software.
18 * If not, see <http://www.gnu.org/licenses/>.
28 #include "build/build_config.h"
30 #include "drivers/bus_i2c.h"
31 #include "drivers/io.h"
33 // Software I2C driver, using same pins as hardware I2C, with hw i2c module disabled.
34 // Can be configured for I2C2 pinout (SCL: PB10, SDA: PB11) or I2C1 pinout (SCL: PB6, SDA: PB7)
38 static volatile uint16_t i2cErrorCount
= 0;
40 #define SCL_H IOHi(scl)
41 #define SCL_L IOLo(scl)
43 #define SDA_H IOHi(sda)
44 #define SDA_L IOLo(sda)
46 #define SCL_read IORead(scl)
47 #define SDA_read IORead(sda)
49 #if !defined(SOFT_I2C_SCL) || !defined(SOFT_I2C_SDA)
50 #error "Must define the software i2c pins (SOFT_I2C_SCL and SOFT_I2C_SDA) in target.h"
53 static void I2C_delay(void)
61 static bool I2C_Start(void)
79 static void I2C_Stop(void)
91 static void I2C_Ack(void)
103 static void I2C_NoAck(void)
115 static bool I2C_WaitAck(void)
131 static void I2C_SendByte(uint8_t byte
)
151 static uint8_t I2C_ReceiveByte(void)
171 void i2cInit(I2CDevice device
)
175 scl
= IOGetByTag(IO_TAG(SOFT_I2C_SCL
));
176 sda
= IOGetByTag(IO_TAG(SOFT_I2C_SDA
));
178 IOConfigGPIO(scl
, IOCFG_OUT_OD
);
179 IOConfigGPIO(sda
, IOCFG_OUT_OD
);
182 bool i2cWriteBuffer(I2CDevice device
, uint8_t addr
, uint8_t reg
, uint8_t len
, uint8_t * data
)
191 I2C_SendByte(addr
<< 1 | I2C_Direction_Transmitter
);
192 if (!I2C_WaitAck()) {
198 for (i
= 0; i
< len
; i
++) {
199 I2C_SendByte(data
[i
]);
200 if (!I2C_WaitAck()) {
210 bool i2cWrite(I2CDevice device
, uint8_t addr
, uint8_t reg
, uint8_t data
)
217 I2C_SendByte(addr
<< 1 | I2C_Direction_Transmitter
);
218 if (!I2C_WaitAck()) {
231 bool i2cRead(I2CDevice device
, uint8_t addr
, uint8_t reg
, uint8_t len
, uint8_t *buf
)
238 I2C_SendByte(addr
<< 1 | I2C_Direction_Transmitter
);
239 if (!I2C_WaitAck()) {
247 I2C_SendByte(addr
<< 1 | I2C_Direction_Receiver
);
250 *buf
= I2C_ReceiveByte();
264 uint16_t i2cGetErrorCounter(void)
266 return i2cErrorCount
;