2 * This file is part of Cleanflight.
4 * Cleanflight is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * Cleanflight is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
23 #include "build/build_config.h"
25 #include "drivers/bus_i2c.h"
26 #include "drivers/time.h"
27 #include "drivers/io.h"
29 // Software I2C driver, using same pins as hardware I2C, with hw i2c module disabled.
30 // Can be configured for I2C2 pinout (SCL: PB10, SDA: PB11) or I2C1 pinout (SCL: PB6, SDA: PB7)
36 static volatile uint16_t i2cErrorCount
= 0;
38 #define SCL_H IOHi(scl)
39 #define SCL_L IOLo(scl)
41 #define SDA_H IOHi(sda)
42 #define SDA_L IOLo(sda)
44 #define SCL_read IORead(scl)
45 #define SDA_read IORead(sda)
47 #if !defined(SOFT_I2C_SCL) || !defined(SOFT_I2C_SDA)
48 #error "Must define the software i2c pins (SOFT_I2C_SCL and SOFT_I2C_SDA) in target.h"
51 static uint32_t delayTicks
= 90;
53 void i2cSetSpeed(uint8_t speed
)
56 case I2C_SPEED_100KHZ
:
57 delayTicks
= SystemCoreClock
/ 100000 / 2;
60 case I2C_SPEED_200KHZ
:
61 delayTicks
= SystemCoreClock
/ 200000 / 2;
64 case I2C_SPEED_400KHZ
:
65 delayTicks
= SystemCoreClock
/ 400000 / 2;
68 case I2C_SPEED_800KHZ
:
69 delayTicks
= SystemCoreClock
/ 800000 / 2;
74 static void I2C_delay(void)
76 uint32_t now
= ticks();
77 while ((ticks() - now
) < delayTicks
) {
82 static bool I2C_Start(void)
100 static void I2C_Stop(void)
112 static void I2C_Ack(void)
124 static void I2C_NoAck(void)
136 static bool I2C_WaitAck(void)
152 static void I2C_SendByte(uint8_t byte
)
172 static uint8_t I2C_ReceiveByte(void)
192 void i2cInit(I2CDevice device
)
196 scl
= IOGetByTag(IO_TAG(SOFT_I2C_SCL
));
197 sda
= IOGetByTag(IO_TAG(SOFT_I2C_SDA
));
199 IOConfigGPIOAF(scl
, IOCFG_OUT_OD
, 0);
200 IOConfigGPIOAF(sda
, IOCFG_OUT_OD
, 0);
203 bool i2cWriteBuffer(I2CDevice device
, uint8_t addr
, uint8_t reg
, uint8_t len
, const uint8_t * data
, bool allowRawAccess
)
212 I2C_SendByte(addr
<< 1 | I2C_Direction_Transmitter
);
213 if (!I2C_WaitAck()) {
217 if (!allowRawAccess
|| reg
!= 0xFF) {
221 for (i
= 0; i
< len
; i
++) {
222 I2C_SendByte(data
[i
]);
223 if (!I2C_WaitAck()) {
233 bool i2cWrite(I2CDevice device
, uint8_t addr
, uint8_t reg
, uint8_t data
, bool allowRawAccess
)
240 I2C_SendByte(addr
<< 1 | I2C_Direction_Transmitter
);
241 if (!I2C_WaitAck()) {
246 if (!allowRawAccess
|| reg
!= 0xFF) {
256 bool i2cRead(I2CDevice device
, uint8_t addr
, uint8_t reg
, uint8_t len
, uint8_t *buf
, bool allowRawAccess
)
264 if (!allowRawAccess
|| reg
!= 0xFF) {
265 I2C_SendByte(addr
<< 1 | I2C_Direction_Transmitter
);
266 if (!I2C_WaitAck()) {
276 I2C_SendByte(addr
<< 1 | I2C_Direction_Receiver
);
279 *buf
= I2C_ReceiveByte();
293 uint16_t i2cGetErrorCounter(void)
295 return i2cErrorCount
;