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 // Number of bits in I2C protocol phase
43 // Clock period in us during unstick transfer
44 #define UNSTICK_CLK_US 10
46 // Allow 500us for clock strech to complete during unstick
47 #define UNSTICK_CLK_STRETCH (500/UNSTICK_CLK_US)
49 static void i2cUnstick(IO_t scl
, IO_t sda
);
51 #define IOCFG_I2C_PU IO_CONFIG(GPIO_MODE_AF_OD, GPIO_SPEED_FREQ_VERY_HIGH, GPIO_PULLUP)
52 #define IOCFG_I2C IO_CONFIG(GPIO_MODE_AF_OD, GPIO_SPEED_FREQ_VERY_HIGH, GPIO_NOPULL)
54 #define GPIO_AF4_I2C GPIO_AF4_I2C1
56 const i2cHardware_t i2cHardware
[I2CDEV_COUNT
] = {
58 #ifdef USE_I2C_DEVICE_1
62 .sclPins
= { I2CPINDEF(PB6
), I2CPINDEF(PB8
) },
63 .sdaPins
= { I2CPINDEF(PB7
), I2CPINDEF(PB9
) },
64 .rcc
= RCC_APB1(I2C1
),
65 .ev_irq
= I2C1_EV_IRQn
,
66 .er_irq
= I2C1_ER_IRQn
,
69 #ifdef USE_I2C_DEVICE_2
73 .sclPins
= { I2CPINDEF(PB10
), I2CPINDEF(PF1
) },
74 .sdaPins
= { I2CPINDEF(PB11
), I2CPINDEF(PF0
) },
75 .rcc
= RCC_APB1(I2C2
),
76 .ev_irq
= I2C2_EV_IRQn
,
77 .er_irq
= I2C2_ER_IRQn
,
80 #ifdef USE_I2C_DEVICE_3
84 .sclPins
= { I2CPINDEF(PA8
) },
85 .sdaPins
= { I2CPINDEF(PC9
) },
86 .rcc
= RCC_APB1(I2C3
),
87 .ev_irq
= I2C3_EV_IRQn
,
88 .er_irq
= I2C3_ER_IRQn
,
91 #ifdef USE_I2C_DEVICE_4
95 .sclPins
= { I2CPINDEF(PD12
), I2CPINDEF(PF14
) },
96 .sdaPins
= { I2CPINDEF(PD13
), I2CPINDEF(PF15
) },
97 .rcc
= RCC_APB1(I2C4
),
98 .ev_irq
= I2C4_EV_IRQn
,
99 .er_irq
= I2C4_ER_IRQn
,
102 #elif defined(STM32H7)
103 #ifdef USE_I2C_DEVICE_1
107 .sclPins
= { I2CPINDEF(PB6
, GPIO_AF4_I2C1
), I2CPINDEF(PB8
, GPIO_AF4_I2C1
) },
108 .sdaPins
= { I2CPINDEF(PB7
, GPIO_AF4_I2C1
), I2CPINDEF(PB9
, GPIO_AF4_I2C1
) },
109 .rcc
= RCC_APB1L(I2C1
),
110 .ev_irq
= I2C1_EV_IRQn
,
111 .er_irq
= I2C1_ER_IRQn
,
114 #ifdef USE_I2C_DEVICE_2
118 .sclPins
= { I2CPINDEF(PB10
, GPIO_AF4_I2C2
), I2CPINDEF(PF1
, GPIO_AF4_I2C2
) },
119 .sdaPins
= { I2CPINDEF(PB11
, GPIO_AF4_I2C2
), I2CPINDEF(PF0
, GPIO_AF4_I2C2
) },
120 .rcc
= RCC_APB1L(I2C2
),
121 .ev_irq
= I2C2_EV_IRQn
,
122 .er_irq
= I2C2_ER_IRQn
,
125 #ifdef USE_I2C_DEVICE_3
129 .sclPins
= { I2CPINDEF(PA8
, GPIO_AF4_I2C3
) },
130 .sdaPins
= { I2CPINDEF(PC9
, GPIO_AF4_I2C3
) },
131 .rcc
= RCC_APB1L(I2C3
),
132 .ev_irq
= I2C3_EV_IRQn
,
133 .er_irq
= I2C3_ER_IRQn
,
136 #ifdef USE_I2C_DEVICE_4
140 .sclPins
= { I2CPINDEF(PD12
, GPIO_AF4_I2C4
), I2CPINDEF(PF14
, GPIO_AF4_I2C4
), I2CPINDEF(PB6
, GPIO_AF6_I2C4
), I2CPINDEF(PB8
, GPIO_AF6_I2C4
) },
141 .sdaPins
= { I2CPINDEF(PD13
, GPIO_AF4_I2C4
), I2CPINDEF(PF15
, GPIO_AF4_I2C4
), I2CPINDEF(PB7
, GPIO_AF6_I2C4
), I2CPINDEF(PB9
, GPIO_AF6_I2C4
) },
142 .rcc
= RCC_APB4(I2C4
),
143 .ev_irq
= I2C4_EV_IRQn
,
144 .er_irq
= I2C4_ER_IRQn
,
147 #elif defined(STM32G4)
148 #ifdef USE_I2C_DEVICE_1
153 // Some boards are overloading SWD pins with I2C1 for maximum pin utilization on 48-pin CE(U) packages.
154 // Be carefull when using SWD on these boards if I2C1 pins are defined by default.
156 .sclPins
= { I2CPINDEF(PA13
, GPIO_AF4_I2C1
), I2CPINDEF(PA15
, GPIO_AF4_I2C1
), I2CPINDEF(PB6
, GPIO_AF4_I2C1
), I2CPINDEF(PB8
, GPIO_AF4_I2C1
), },
157 .sdaPins
= { I2CPINDEF(PA14
, GPIO_AF4_I2C1
), I2CPINDEF(PB7
, GPIO_AF4_I2C1
), I2CPINDEF(PB9
, GPIO_AF4_I2C1
), },
158 .rcc
= RCC_APB11(I2C1
),
159 .ev_irq
= I2C1_EV_IRQn
,
160 .er_irq
= I2C1_ER_IRQn
,
163 #ifdef USE_I2C_DEVICE_2
167 .sclPins
= { I2CPINDEF(PA9
, GPIO_AF4_I2C2
), },
168 .sdaPins
= { I2CPINDEF(PA10
, GPIO_AF4_I2C2
), },
169 .rcc
= RCC_APB11(I2C2
),
170 .ev_irq
= I2C2_EV_IRQn
,
171 .er_irq
= I2C2_ER_IRQn
,
174 #ifdef USE_I2C_DEVICE_3
178 .sclPins
= { I2CPINDEF(PA10
, GPIO_AF2_I2C3
), I2CPINDEF(PC8
, GPIO_AF8_I2C3
), },
179 .sdaPins
= { I2CPINDEF(PB5
, GPIO_AF8_I2C3
), I2CPINDEF(PC9
, GPIO_AF8_I2C3
), I2CPINDEF(PC11
, GPIO_AF8_I2C3
), },
180 .rcc
= RCC_APB11(I2C3
),
181 .ev_irq
= I2C3_EV_IRQn
,
182 .er_irq
= I2C3_ER_IRQn
,
185 #ifdef USE_I2C_DEVICE_4
190 // Here, SWDIO(PA13) is overloaded with I2C4_SCL, too.
191 // See comment in the I2C1 section above.
193 .sclPins
= { I2CPINDEF(PA13
, GPIO_AF3_I2C4
), I2CPINDEF(PB6
, GPIO_AF3_I2C4
), I2CPINDEF(PC6
, GPIO_AF8_I2C4
), },
194 .sdaPins
= { I2CPINDEF(PB7
, GPIO_AF4_I2C4
), I2CPINDEF(PC7
, GPIO_AF8_I2C4
), },
195 .rcc
= RCC_APB12(I2C4
),
196 .ev_irq
= I2C4_EV_IRQn
,
197 .er_irq
= I2C4_ER_IRQn
,
203 i2cDevice_t i2cDevice
[I2CDEV_COUNT
];
205 // Values from I2C-SMBus specification
206 static uint16_t trmax
; // Rise time (max)
207 static uint16_t tfmax
; // Fall time (max)
208 static uint8_t tsuDATmin
; // SDA setup time (min)
209 static uint8_t thdDATmin
; // SDA hold time (min)
210 static uint16_t tHIGHmin
; // High period of SCL clock (min)
211 static uint16_t tLOWmin
; // Low period of SCL clock (min)
213 // Silicon specific values, from datasheet
214 static uint8_t tAFmin
; // Analog filter delay (min)
215 static uint16_t tAFmax
; // Analog filter delay (max)
217 // Actual (estimated) values
218 static uint16_t tr
= 100; // Rise time
219 static uint16_t tf
= 10; // Fall time
222 * Compute SCLDEL, SDADEL, SCLH and SCLL for TIMINGR register according to reference manuals.
224 static void i2cClockComputeRaw(uint32_t pclkFreq
, int i2cFreqKhz
, int presc
, int dfcoeff
,
225 uint8_t *scldel
, uint8_t *sdadel
, uint16_t *sclh
, uint16_t *scll
)
227 if (i2cFreqKhz
> 400) {
228 // Fm+ (Fast mode plus)
247 // Convert pclkFreq into nsec
248 float tI2cclk
= 1000000000.0f
/ pclkFreq
;
250 // Convert target i2cFreq into cycle time (nsec)
251 float tSCL
= 1000000.0f
/ i2cFreqKhz
;
253 uint32_t SCLDELmin
= (trmax
+ tsuDATmin
)/((presc
+ 1) * tI2cclk
) - 1;
255 uint32_t SDADELmin
= (tfmax
+ thdDATmin
- tAFmin
- ((dfcoeff
+ 3) * tI2cclk
)) / ((presc
+ 1) * tI2cclk
);
257 float tsync1
= tf
+ tAFmin
+ dfcoeff
* tI2cclk
+ 2 * tI2cclk
;
258 float tsync2
= tr
+ tAFmin
+ dfcoeff
* tI2cclk
+ 2 * tI2cclk
;
260 float tSCLH
= tHIGHmin
* tSCL
/ (tHIGHmin
+ tLOWmin
) - tsync2
;
261 float tSCLL
= tSCL
- tSCLH
- tsync1
- tsync2
;
263 uint32_t SCLH
= tSCLH
/ ((presc
+ 1) * tI2cclk
) - 1;
264 uint32_t SCLL
= tSCLL
/ ((presc
+ 1) * tI2cclk
) - 1;
266 while (tsync1
+ tsync2
+ ((SCLH
+ 1) + (SCLL
+ 1)) * ((presc
+ 1) * tI2cclk
) < tSCL
) {
276 static uint32_t i2cClockTIMINGR(uint32_t pclkFreq
, int i2cFreqKhz
, int dfcoeff
)
278 #define TIMINGR(presc, scldel, sdadel, sclh, scll) \
279 ((presc << 28)|(scldel << 20)|(sdadel << 16)|(sclh << 8)|(scll << 0))
286 for (int presc
= 0; presc
< 15; presc
++) {
287 i2cClockComputeRaw(pclkFreq
, i2cFreqKhz
, presc
, dfcoeff
, &scldel
, &sdadel
, &sclh
, &scll
);
289 // If all fields are not overflowing, return TIMINGR.
290 // Otherwise, increase prescaler and try again.
291 if ((scldel
< 16) && (sdadel
< 16) && (sclh
< 256) && (scll
< 256)) {
292 return TIMINGR(presc
, scldel
, sdadel
, sclh
, scll
);
295 return 0; // Shouldn't reach here
298 void i2cInit(I2CDevice device
)
300 if (device
== I2CINVALID
) {
304 i2cDevice_t
*pDev
= &i2cDevice
[device
];
306 const i2cHardware_t
*hardware
= pDev
->hardware
;
307 const IO_t scl
= pDev
->scl
;
308 const IO_t sda
= pDev
->sda
;
310 if (!hardware
|| IOGetOwner(scl
) || IOGetOwner(sda
)) {
314 IOInit(scl
, OWNER_I2C_SCL
, RESOURCE_INDEX(device
));
315 IOInit(sda
, OWNER_I2C_SDA
, RESOURCE_INDEX(device
));
318 RCC_ClockCmd(hardware
->rcc
, ENABLE
);
320 i2cUnstick(scl
, sda
);
324 IOConfigGPIOAF(scl
, pDev
->pullUp
? IOCFG_I2C_PU
: IOCFG_I2C
, GPIO_AF4_I2C
);
325 IOConfigGPIOAF(sda
, pDev
->pullUp
? IOCFG_I2C_PU
: IOCFG_I2C
, GPIO_AF4_I2C
);
326 #elif defined(STM32H7) || defined(STM32G4)
327 IOConfigGPIOAF(scl
, pDev
->pullUp
? IOCFG_I2C_PU
: IOCFG_I2C
, pDev
->sclAF
);
328 IOConfigGPIOAF(sda
, pDev
->pullUp
? IOCFG_I2C_PU
: IOCFG_I2C
, pDev
->sdaAF
);
330 IOConfigGPIO(scl
, IOCFG_AF_OD
);
331 IOConfigGPIO(sda
, IOCFG_AF_OD
);
334 // Init I2C peripheral
336 I2C_HandleTypeDef
*pHandle
= &pDev
->handle
;
338 memset(pHandle
, 0, sizeof(*pHandle
));
340 pHandle
->Instance
= pDev
->hardware
->reg
;
342 // Compute TIMINGR value based on peripheral clock for this device instance
346 #if defined(STM32F7) || defined(STM32G4)
347 // F7 Clock source configured in startup/system_stm32f7xx.c as:
349 // G4 Clock source configured in startup/system_stm32g4xx.c as:
351 i2cPclk
= HAL_RCC_GetPCLK1Freq();
352 #elif defined(STM32H7)
353 // Clock sources configured in startup/system_stm32h7xx.c as:
354 // I2C123 : D2PCLK1 (rcc_pclk1 for APB1)
355 // I2C4 : D3PCLK1 (rcc_pclk4 for APB4)
356 i2cPclk
= (pHandle
->Instance
== I2C4
) ? HAL_RCCEx_GetD3PCLK1Freq() : HAL_RCC_GetPCLK1Freq();
358 #error Unknown MCU type
361 pHandle
->Init
.Timing
= i2cClockTIMINGR(i2cPclk
, pDev
->overClock
? 800 : 400, 0);
363 pHandle
->Init
.OwnAddress1
= 0x0;
364 pHandle
->Init
.AddressingMode
= I2C_ADDRESSINGMODE_7BIT
;
365 pHandle
->Init
.DualAddressMode
= I2C_DUALADDRESS_DISABLE
;
366 pHandle
->Init
.OwnAddress2
= 0x0;
367 pHandle
->Init
.GeneralCallMode
= I2C_GENERALCALL_DISABLE
;
368 pHandle
->Init
.NoStretchMode
= I2C_NOSTRETCH_DISABLE
;
370 HAL_I2C_Init(pHandle
);
372 // Enable the Analog I2C Filter
373 HAL_I2CEx_ConfigAnalogFilter(pHandle
, I2C_ANALOGFILTER_ENABLE
);
375 // Setup interrupt handlers
376 HAL_NVIC_SetPriority(hardware
->er_irq
, NVIC_PRIORITY_BASE(NVIC_PRIO_I2C_ER
), NVIC_PRIORITY_SUB(NVIC_PRIO_I2C_ER
));
377 HAL_NVIC_EnableIRQ(hardware
->er_irq
);
378 HAL_NVIC_SetPriority(hardware
->ev_irq
, NVIC_PRIORITY_BASE(NVIC_PRIO_I2C_EV
), NVIC_PRIORITY_SUB(NVIC_PRIO_I2C_EV
));
379 HAL_NVIC_EnableIRQ(hardware
->ev_irq
);
382 static void i2cUnstick(IO_t scl
, IO_t sda
)
389 IOConfigGPIO(scl
, IOCFG_OUT_OD
);
390 IOConfigGPIO(sda
, IOCFG_OUT_OD
);
392 // Clock out, with SDA high:
395 // 1 cycle for the ACK
396 for (i
= 0; i
< (LEN_ADDR
+ LEN_RW
+ LEN_ACK
); i
++) {
397 // Wait for any clock stretching to finish
398 int timeout
= UNSTICK_CLK_STRETCH
;
399 while (!IORead(scl
) && timeout
) {
400 delayMicroseconds(UNSTICK_CLK_US
);
405 IOLo(scl
); // Set bus low
406 delayMicroseconds(UNSTICK_CLK_US
/2);
407 IOHi(scl
); // Set bus high
408 delayMicroseconds(UNSTICK_CLK_US
/2);
411 // Generate a stop condition in case there was none
413 delayMicroseconds(UNSTICK_CLK_US
/2);
415 delayMicroseconds(UNSTICK_CLK_US
/2);
417 IOHi(scl
); // Set bus scl high
418 delayMicroseconds(UNSTICK_CLK_US
/2);
419 IOHi(sda
); // Set bus sda high