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/>.
27 #if defined(USE_I2C) && !defined(SOFT_I2C)
29 #include "drivers/io.h"
30 #include "drivers/io_impl.h"
31 #include "drivers/nvic.h"
32 #include "drivers/time.h"
33 #include "drivers/rcc.h"
35 #include "drivers/bus_i2c.h"
36 #include "drivers/bus_i2c_impl.h"
38 #ifdef USE_I2C_DEVICE_1
39 void I2C1_ER_IRQHandler(void)
41 HAL_I2C_ER_IRQHandler(&i2cDevice
[I2CDEV_1
].handle
);
44 void I2C1_EV_IRQHandler(void)
46 HAL_I2C_EV_IRQHandler(&i2cDevice
[I2CDEV_1
].handle
);
50 #ifdef USE_I2C_DEVICE_2
51 void I2C2_ER_IRQHandler(void)
53 HAL_I2C_ER_IRQHandler(&i2cDevice
[I2CDEV_2
].handle
);
56 void I2C2_EV_IRQHandler(void)
58 HAL_I2C_EV_IRQHandler(&i2cDevice
[I2CDEV_2
].handle
);
62 #ifdef USE_I2C_DEVICE_3
63 void I2C3_ER_IRQHandler(void)
65 HAL_I2C_ER_IRQHandler(&i2cDevice
[I2CDEV_3
].handle
);
68 void I2C3_EV_IRQHandler(void)
70 HAL_I2C_EV_IRQHandler(&i2cDevice
[I2CDEV_3
].handle
);
74 #ifdef USE_I2C_DEVICE_4
75 void I2C4_ER_IRQHandler(void)
77 HAL_I2C_ER_IRQHandler(&i2cDevice
[I2CDEV_4
].handle
);
80 void I2C4_EV_IRQHandler(void)
82 HAL_I2C_EV_IRQHandler(&i2cDevice
[I2CDEV_4
].handle
);
86 static volatile uint16_t i2cErrorCount
= 0;
88 static bool i2cHandleHardwareFailure(I2CDevice device
)
92 // reinit peripheral + clock out garbage
97 uint16_t i2cGetErrorCounter(void)
103 bool i2cWrite(I2CDevice device
, uint8_t addr_
, uint8_t reg_
, uint8_t data
)
105 if (device
== I2CINVALID
|| device
>= I2CDEV_COUNT
) {
109 I2C_HandleTypeDef
*pHandle
= &i2cDevice
[device
].handle
;
111 if (!pHandle
->Instance
) {
115 HAL_StatusTypeDef status
;
118 status
= HAL_I2C_Master_Transmit(pHandle
,addr_
<< 1, &data
, 1, I2C_TIMEOUT_SYS_TICKS
);
120 status
= HAL_I2C_Mem_Write(pHandle
,addr_
<< 1, reg_
, I2C_MEMADD_SIZE_8BIT
, &data
, 1, I2C_TIMEOUT_SYS_TICKS
);
122 if (status
!= HAL_OK
)
123 return i2cHandleHardwareFailure(device
);
128 // Non-blocking write
129 bool i2cWriteBuffer(I2CDevice device
, uint8_t addr_
, uint8_t reg_
, uint8_t len_
, uint8_t *data
)
131 if (device
== I2CINVALID
|| device
>= I2CDEV_COUNT
) {
135 I2C_HandleTypeDef
*pHandle
= &i2cDevice
[device
].handle
;
137 if (!pHandle
->Instance
) {
141 HAL_StatusTypeDef status
;
143 status
= HAL_I2C_Mem_Write_IT(pHandle
,addr_
<< 1, reg_
, I2C_MEMADD_SIZE_8BIT
,data
, len_
);
145 if (status
== HAL_BUSY
) {
149 if (status
!= HAL_OK
)
151 return i2cHandleHardwareFailure(device
);
158 bool i2cRead(I2CDevice device
, uint8_t addr_
, uint8_t reg_
, uint8_t len
, uint8_t* buf
)
160 if (device
== I2CINVALID
|| device
>= I2CDEV_COUNT
) {
164 I2C_HandleTypeDef
*pHandle
= &i2cDevice
[device
].handle
;
166 if (!pHandle
->Instance
) {
170 HAL_StatusTypeDef status
;
173 status
= HAL_I2C_Master_Receive(pHandle
,addr_
<< 1, buf
, len
, I2C_TIMEOUT_SYS_TICKS
);
175 status
= HAL_I2C_Mem_Read(pHandle
, addr_
<< 1, reg_
, I2C_MEMADD_SIZE_8BIT
,buf
, len
, I2C_TIMEOUT_SYS_TICKS
);
177 if (status
!= HAL_OK
) {
178 return i2cHandleHardwareFailure(device
);
185 bool i2cReadBuffer(I2CDevice device
, uint8_t addr_
, uint8_t reg_
, uint8_t len
, uint8_t* buf
)
187 if (device
== I2CINVALID
|| device
>= I2CDEV_COUNT
) {
191 I2C_HandleTypeDef
*pHandle
= &i2cDevice
[device
].handle
;
193 if (!pHandle
->Instance
) {
197 HAL_StatusTypeDef status
;
199 status
= HAL_I2C_Mem_Read_IT(pHandle
, addr_
<< 1, reg_
, I2C_MEMADD_SIZE_8BIT
,buf
, len
);
201 if (status
== HAL_BUSY
) {
205 if (status
!= HAL_OK
) {
206 return i2cHandleHardwareFailure(device
);
212 bool i2cBusy(I2CDevice device
, bool *error
)
214 I2C_HandleTypeDef
*pHandle
= &i2cDevice
[device
].handle
;
217 *error
= pHandle
->ErrorCode
;
220 if (pHandle
->State
== HAL_I2C_STATE_READY
)
222 if (__HAL_I2C_GET_FLAG(pHandle
, I2C_FLAG_BUSY
) == SET
)