[4.4.2] Remove 15 m/s limit on estimated vario (#12788)
[betaflight.git] / src / main / drivers / bus_i2c_stm32f4xx.c
blobb45ac7f0991c49234d53931f8ed7b46784200447
1 /*
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)
8 * any later version.
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/>.
21 #include <stdbool.h>
22 #include <stdint.h>
23 #include <stdlib.h>
24 #include <string.h>
26 #include "platform.h"
28 #if defined(USE_I2C) && !defined(SOFT_I2C)
30 #include "drivers/io.h"
31 #include "drivers/time.h"
32 #include "drivers/nvic.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
39 #define LEN_ADDR 7
40 #define LEN_RW 1
41 #define LEN_ACK 1
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 i2c_er_handler(I2CDevice device);
50 static void i2c_ev_handler(I2CDevice device);
51 static void i2cUnstick(IO_t scl, IO_t sda);
53 #ifdef STM32F4
54 #define IOCFG_I2C_PU IO_CONFIG(GPIO_Mode_AF, 0, GPIO_OType_OD, GPIO_PuPd_UP)
55 #define IOCFG_I2C IO_CONFIG(GPIO_Mode_AF, 0, GPIO_OType_OD, GPIO_PuPd_NOPULL)
56 #else // STM32F4
57 #define IOCFG_I2C IO_CONFIG(GPIO_Mode_AF_OD, GPIO_Speed_50MHz)
58 #endif
60 const i2cHardware_t i2cHardware[I2CDEV_COUNT] = {
61 #ifdef USE_I2C_DEVICE_1
63 .device = I2CDEV_1,
64 .reg = I2C1,
65 .sclPins = {
66 I2CPINDEF(PB6, GPIO_AF_I2C1),
67 I2CPINDEF(PB8, GPIO_AF_I2C1),
69 .sdaPins = {
70 I2CPINDEF(PB7, GPIO_AF_I2C1),
71 I2CPINDEF(PB9, GPIO_AF_I2C1),
73 .rcc = RCC_APB1(I2C1),
74 .ev_irq = I2C1_EV_IRQn,
75 .er_irq = I2C1_ER_IRQn,
77 #endif
78 #ifdef USE_I2C_DEVICE_2
80 .device = I2CDEV_2,
81 .reg = I2C2,
82 .sclPins = {
83 I2CPINDEF(PB10, GPIO_AF_I2C2),
84 I2CPINDEF(PF1, GPIO_AF_I2C2),
86 .sdaPins = {
87 #if defined(STM32F446xx)
88 I2CPINDEF(PC12, GPIO_AF_I2C2),
89 #else
90 I2CPINDEF(PB11, GPIO_AF_I2C2),
91 #endif
92 I2CPINDEF(PF0, GPIO_AF_I2C2),
94 #if defined(STM32F40_41xxx) || defined (STM32F411xE)
95 // STM32F401xx/STM32F410xx/STM32F411xE/STM32F412xG
96 I2CPINDEF(PB3, GPIO_AF9_I2C2),
97 I2CPINDEF(PB9, GPIO_AF9_I2C2),
98 #endif
100 .rcc = RCC_APB1(I2C2),
101 .ev_irq = I2C2_EV_IRQn,
102 .er_irq = I2C2_ER_IRQn,
104 #endif
105 #ifdef USE_I2C_DEVICE_3
107 .device = I2CDEV_3,
108 .reg = I2C3,
109 .sclPins = {
110 I2CPINDEF(PA8, GPIO_AF_I2C3),
112 .sdaPins = {
113 I2CPINDEF(PC9, GPIO_AF_I2C3),
115 #if defined(STM32F40_41xxx) || defined (STM32F411xE)
116 // STM32F401xx/STM32F410xx/STM32F411xE/STM32F412xG
117 I2CPINDEF(PB4, GPIO_AF9_I2C3),
118 I2CPINDEF(PB8, GPIO_AF9_I2C3),
119 #endif
121 .rcc = RCC_APB1(I2C3),
122 .ev_irq = I2C3_EV_IRQn,
123 .er_irq = I2C3_ER_IRQn,
125 #endif
128 i2cDevice_t i2cDevice[I2CDEV_COUNT];
130 static volatile uint16_t i2cErrorCount = 0;
132 void I2C1_ER_IRQHandler(void)
134 i2c_er_handler(I2CDEV_1);
137 void I2C1_EV_IRQHandler(void)
139 i2c_ev_handler(I2CDEV_1);
142 void I2C2_ER_IRQHandler(void)
144 i2c_er_handler(I2CDEV_2);
147 void I2C2_EV_IRQHandler(void)
149 i2c_ev_handler(I2CDEV_2);
152 #ifdef STM32F4
153 void I2C3_ER_IRQHandler(void)
155 i2c_er_handler(I2CDEV_3);
158 void I2C3_EV_IRQHandler(void)
160 i2c_ev_handler(I2CDEV_3);
162 #endif
164 static bool i2cHandleHardwareFailure(I2CDevice device)
166 i2cErrorCount++;
167 // reinit peripheral + clock out garbage
168 i2cInit(device);
169 return false;
172 bool i2cWriteBuffer(I2CDevice device, uint8_t addr_, uint8_t reg_, uint8_t len_, uint8_t *data)
174 if (device == I2CINVALID || device >= I2CDEV_COUNT) {
175 return false;
178 I2C_TypeDef *I2Cx = i2cDevice[device].reg;
180 if (!I2Cx) {
181 return false;
184 i2cState_t *state = &i2cDevice[device].state;
185 if (state->busy) {
186 return false;
189 timeUs_t timeoutStartUs = microsISR();
191 state->addr = addr_ << 1;
192 state->reg = reg_;
193 state->writing = 1;
194 state->reading = 0;
195 state->write_p = data;
196 state->read_p = data;
197 state->bytes = len_;
198 state->busy = 1;
199 state->error = false;
201 if (!(I2Cx->CR2 & I2C_IT_EVT)) { // if we are restarting the driver
202 if (!(I2Cx->CR1 & I2C_CR1_START)) { // ensure sending a start
203 while (I2Cx->CR1 & I2C_CR1_STOP) { // wait for any stop to finish sending
204 if (cmpTimeUs(microsISR(), timeoutStartUs) >= I2C_TIMEOUT_US) {
205 return i2cHandleHardwareFailure(device);
208 I2C_GenerateSTART(I2Cx, ENABLE); // send the start for the new job
210 I2C_ITConfig(I2Cx, I2C_IT_EVT | I2C_IT_ERR, ENABLE); // allow the interrupts to fire off again
213 return true;
216 bool i2cBusy(I2CDevice device, bool *error)
218 i2cState_t *state = &i2cDevice[device].state;
220 if (error) {
221 *error = state->error;
223 return state->busy;
226 bool i2cWait(I2CDevice device)
228 i2cState_t *state = &i2cDevice[device].state;
229 timeUs_t timeoutStartUs = microsISR();
231 while (state->busy) {
232 if (cmpTimeUs(microsISR(), timeoutStartUs) >= I2C_TIMEOUT_US) {
233 return i2cHandleHardwareFailure(device) && i2cWait(device);
237 return !(state->error);
240 bool i2cWrite(I2CDevice device, uint8_t addr_, uint8_t reg_, uint8_t data)
242 return i2cWriteBuffer(device, addr_, reg_, 1, &data) && i2cWait(device);
245 bool i2cReadBuffer(I2CDevice device, uint8_t addr_, uint8_t reg_, uint8_t len, uint8_t* buf)
247 if (device == I2CINVALID || device >= I2CDEV_COUNT) {
248 return false;
251 I2C_TypeDef *I2Cx = i2cDevice[device].reg;
252 if (!I2Cx) {
253 return false;
256 i2cState_t *state = &i2cDevice[device].state;
257 if (state->busy) {
258 return false;
261 timeUs_t timeoutStartUs = microsISR();
263 state->addr = addr_ << 1;
264 state->reg = reg_;
265 state->writing = 0;
266 state->reading = 1;
267 state->read_p = buf;
268 state->write_p = buf;
269 state->bytes = len;
270 state->busy = 1;
271 state->error = false;
273 if (!(I2Cx->CR2 & I2C_IT_EVT)) { // if we are restarting the driver
274 if (!(I2Cx->CR1 & I2C_CR1_START)) { // ensure sending a start
275 while (I2Cx->CR1 & I2C_CR1_STOP) { // wait for any stop to finish sending
276 if (cmpTimeUs(microsISR(), timeoutStartUs) >= I2C_TIMEOUT_US) {
277 return i2cHandleHardwareFailure(device);
280 I2C_GenerateSTART(I2Cx, ENABLE); // send the start for the new job
282 I2C_ITConfig(I2Cx, I2C_IT_EVT | I2C_IT_ERR, ENABLE); // allow the interrupts to fire off again
285 return true;
288 bool i2cRead(I2CDevice device, uint8_t addr_, uint8_t reg_, uint8_t len, uint8_t* buf)
290 return i2cReadBuffer(device, addr_, reg_, len, buf) && i2cWait(device);
293 static void i2c_er_handler(I2CDevice device)
295 I2C_TypeDef *I2Cx = i2cDevice[device].hardware->reg;
297 i2cState_t *state = &i2cDevice[device].state;
299 // Read the I2C1 status register
300 volatile uint32_t SR1Register = I2Cx->SR1;
302 if (SR1Register & (I2C_SR1_BERR | I2C_SR1_ARLO | I2C_SR1_AF | I2C_SR1_OVR)) // an error
303 state->error = true;
305 // If AF, BERR or ARLO, abandon the current job and commence new if there are jobs
306 if (SR1Register & (I2C_SR1_BERR | I2C_SR1_ARLO | I2C_SR1_AF)) {
307 (void)I2Cx->SR2; // read second status register to clear ADDR if it is set (note that BTF will not be set after a NACK)
308 I2C_ITConfig(I2Cx, I2C_IT_BUF, DISABLE); // disable the RXNE/TXE interrupt - prevent the ISR tailchaining onto the ER (hopefully)
309 if (!(SR1Register & I2C_SR1_ARLO) && !(I2Cx->CR1 & I2C_CR1_STOP)) { // if we dont have an ARLO error, ensure sending of a stop
310 if (I2Cx->CR1 & I2C_CR1_START) { // We are currently trying to send a start, this is very bad as start, stop will hang the peripheral
311 while (I2Cx->CR1 & I2C_CR1_START) {; } // wait for any start to finish sending
312 I2C_GenerateSTOP(I2Cx, ENABLE); // send stop to finalise bus transaction
313 while (I2Cx->CR1 & I2C_CR1_STOP) {; } // wait for stop to finish sending
314 i2cInit(device); // reset and configure the hardware
316 else {
317 I2C_GenerateSTOP(I2Cx, ENABLE); // stop to free up the bus
318 I2C_ITConfig(I2Cx, I2C_IT_EVT | I2C_IT_ERR, DISABLE); // Disable EVT and ERR interrupts while bus inactive
322 I2Cx->SR1 &= ~(I2C_SR1_BERR | I2C_SR1_ARLO | I2C_SR1_AF | I2C_SR1_OVR); // reset all the error bits to clear the interrupt
323 state->busy = 0;
326 void i2c_ev_handler(I2CDevice device)
328 I2C_TypeDef *I2Cx = i2cDevice[device].hardware->reg;
330 i2cState_t *state = &i2cDevice[device].state;
332 static uint8_t subaddress_sent, final_stop; // flag to indicate if subaddess sent, flag to indicate final bus condition
333 static int8_t index; // index is signed -1 == send the subaddress
334 uint8_t SReg_1 = I2Cx->SR1; // read the status register here
336 if (SReg_1 & I2C_SR1_SB) { // we just sent a start - EV5 in ref manual
337 I2Cx->CR1 &= ~I2C_CR1_POS; // reset the POS bit so ACK/NACK applied to the current byte
338 I2C_AcknowledgeConfig(I2Cx, ENABLE); // make sure ACK is on
339 index = 0; // reset the index
340 if (state->reading && (subaddress_sent || 0xFF == state->reg)) { // we have sent the subaddr
341 subaddress_sent = 1; // make sure this is set in case of no subaddress, so following code runs correctly
342 if (state->bytes == 2)
343 I2Cx->CR1 |= I2C_CR1_POS; // set the POS bit so NACK applied to the final byte in the two byte read
344 I2C_Send7bitAddress(I2Cx, state->addr, I2C_Direction_Receiver); // send the address and set hardware mode
346 else { // direction is Tx, or we havent sent the sub and rep start
347 I2C_Send7bitAddress(I2Cx, state->addr, I2C_Direction_Transmitter); // send the address and set hardware mode
348 if (state->reg != 0xFF) // 0xFF as subaddress means it will be ignored, in Tx or Rx mode
349 index = -1; // send a subaddress
352 else if (SReg_1 & I2C_SR1_ADDR) { // we just sent the address - EV6 in ref manual
353 // Read SR1,2 to clear ADDR
354 __DMB(); // memory fence to control hardware
355 if (state->bytes == 1 && state->reading && subaddress_sent) { // we are receiving 1 byte - EV6_3
356 I2C_AcknowledgeConfig(I2Cx, DISABLE); // turn off ACK
357 __DMB();
358 (void)I2Cx->SR2; // clear ADDR after ACK is turned off
359 I2C_GenerateSTOP(I2Cx, ENABLE); // program the stop
360 final_stop = 1;
361 I2C_ITConfig(I2Cx, I2C_IT_BUF, ENABLE); // allow us to have an EV7
363 else { // EV6 and EV6_1
364 (void)I2Cx->SR2; // clear the ADDR here
365 __DMB();
366 if (state->bytes == 2 && state->reading && subaddress_sent) { // rx 2 bytes - EV6_1
367 I2C_AcknowledgeConfig(I2Cx, DISABLE); // turn off ACK
368 I2C_ITConfig(I2Cx, I2C_IT_BUF, DISABLE); // disable TXE to allow the buffer to fill
370 else if (state->bytes == 3 && state->reading && subaddress_sent) // rx 3 bytes
371 I2C_ITConfig(I2Cx, I2C_IT_BUF, DISABLE); // make sure RXNE disabled so we get a BTF in two bytes time
372 else // receiving greater than three bytes, sending subaddress, or transmitting
373 I2C_ITConfig(I2Cx, I2C_IT_BUF, ENABLE);
376 else if (SReg_1 & I2C_SR1_BTF) { // Byte transfer finished - EV7_2, EV7_3 or EV8_2
377 final_stop = 1;
378 if (state->reading && subaddress_sent) { // EV7_2, EV7_3
379 if (state->bytes > 2) { // EV7_2
380 I2C_AcknowledgeConfig(I2Cx, DISABLE); // turn off ACK
381 state->read_p[index++] = (uint8_t)I2Cx->DR; // read data N-2
382 I2C_GenerateSTOP(I2Cx, ENABLE); // program the Stop
383 final_stop = 1; // required to fix hardware
384 state->read_p[index++] = (uint8_t)I2Cx->DR; // read data N - 1
385 I2C_ITConfig(I2Cx, I2C_IT_BUF, ENABLE); // enable TXE to allow the final EV7
387 else { // EV7_3
388 if (final_stop)
389 I2C_GenerateSTOP(I2Cx, ENABLE); // program the Stop
390 else
391 I2C_GenerateSTART(I2Cx, ENABLE); // program a rep start
392 state->read_p[index++] = (uint8_t)I2Cx->DR; // read data N - 1
393 state->read_p[index++] = (uint8_t)I2Cx->DR; // read data N
394 index++; // to show job completed
397 else { // EV8_2, which may be due to a subaddress sent or a write completion
398 if (subaddress_sent || (state->writing)) {
399 if (final_stop)
400 I2C_GenerateSTOP(I2Cx, ENABLE); // program the Stop
401 else
402 I2C_GenerateSTART(I2Cx, ENABLE); // program a rep start
403 index++; // to show that the job is complete
405 else { // We need to send a subaddress
406 I2C_GenerateSTART(I2Cx, ENABLE); // program the repeated Start
407 subaddress_sent = 1; // this is set back to zero upon completion of the current task
410 // we must wait for the start to clear, otherwise we get constant BTF
411 while (I2Cx->CR1 & I2C_CR1_START) {; }
413 else if (SReg_1 & I2C_SR1_RXNE) { // Byte received - EV7
414 state->read_p[index++] = (uint8_t)I2Cx->DR;
415 if (state->bytes == (index + 3))
416 I2C_ITConfig(I2Cx, I2C_IT_BUF, DISABLE); // disable TXE to allow the buffer to flush so we can get an EV7_2
417 if (state->bytes == index) // We have completed a final EV7
418 index++; // to show job is complete
420 else if (SReg_1 & I2C_SR1_TXE) { // Byte transmitted EV8 / EV8_1
421 if (index != -1) { // we dont have a subaddress to send
422 I2Cx->DR = state->write_p[index++];
423 if (state->bytes == index) // we have sent all the data
424 I2C_ITConfig(I2Cx, I2C_IT_BUF, DISABLE); // disable TXE to allow the buffer to flush
426 else {
427 index++;
428 I2Cx->DR = state->reg; // send the subaddress
429 if (state->reading || !(state->bytes)) // if receiving or sending 0 bytes, flush now
430 I2C_ITConfig(I2Cx, I2C_IT_BUF, DISABLE); // disable TXE to allow the buffer to flush
433 if (index == state->bytes + 1) { // we have completed the current job
434 subaddress_sent = 0; // reset this here
435 if (final_stop) // If there is a final stop and no more jobs, bus is inactive, disable interrupts to prevent BTF
436 I2C_ITConfig(I2Cx, I2C_IT_EVT | I2C_IT_ERR, DISABLE); // Disable EVT and ERR interrupts while bus inactive
437 state->busy = 0;
441 void i2cInit(I2CDevice device)
443 if (device == I2CINVALID)
444 return;
446 i2cDevice_t *pDev = &i2cDevice[device];
447 const i2cHardware_t *hw = pDev->hardware;
448 const IO_t scl = pDev->scl;
449 const IO_t sda = pDev->sda;
451 if (!hw || IOGetOwner(scl) || IOGetOwner(sda)) {
452 return;
455 I2C_TypeDef *I2Cx = hw->reg;
457 memset(&pDev->state, 0, sizeof(pDev->state));
459 NVIC_InitTypeDef nvic;
460 I2C_InitTypeDef i2cInit;
462 IOInit(scl, OWNER_I2C_SCL, RESOURCE_INDEX(device));
463 IOInit(sda, OWNER_I2C_SDA, RESOURCE_INDEX(device));
465 // Enable RCC
466 RCC_ClockCmd(hw->rcc, ENABLE);
468 I2C_ITConfig(I2Cx, I2C_IT_EVT | I2C_IT_ERR, DISABLE);
470 i2cUnstick(scl, sda);
472 // Init pins
473 #ifdef STM32F4
474 IOConfigGPIOAF(scl, pDev->pullUp ? IOCFG_I2C_PU : IOCFG_I2C, pDev->sclAF);
475 IOConfigGPIOAF(sda, pDev->pullUp ? IOCFG_I2C_PU : IOCFG_I2C, pDev->sdaAF);
476 #else
477 IOConfigGPIO(scl, IOCFG_I2C);
478 IOConfigGPIO(sda, IOCFG_I2C);
479 #endif
481 I2C_DeInit(I2Cx);
482 I2C_StructInit(&i2cInit);
484 I2C_ITConfig(I2Cx, I2C_IT_EVT | I2C_IT_ERR, DISABLE); // Disable EVT and ERR interrupts - they are enabled by the first request
485 i2cInit.I2C_Mode = I2C_Mode_I2C;
486 i2cInit.I2C_DutyCycle = I2C_DutyCycle_2;
487 i2cInit.I2C_OwnAddress1 = 0;
488 i2cInit.I2C_Ack = I2C_Ack_Enable;
489 i2cInit.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
490 i2cInit.I2C_ClockSpeed = pDev->clockSpeed * 1000;
492 I2C_Cmd(I2Cx, ENABLE);
493 I2C_Init(I2Cx, &i2cInit);
495 I2C_StretchClockCmd(I2Cx, ENABLE);
497 // I2C ER Interrupt
498 nvic.NVIC_IRQChannel = hw->er_irq;
499 nvic.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_I2C_ER);
500 nvic.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_I2C_ER);
501 nvic.NVIC_IRQChannelCmd = ENABLE;
502 NVIC_Init(&nvic);
504 // I2C EV Interrupt
505 nvic.NVIC_IRQChannel = hw->ev_irq;
506 nvic.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_I2C_EV);
507 nvic.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_I2C_EV);
508 NVIC_Init(&nvic);
511 uint16_t i2cGetErrorCounter(void)
513 return i2cErrorCount;
516 static void i2cUnstick(IO_t scl, IO_t sda)
518 int i;
520 IOHi(scl);
521 IOHi(sda);
523 IOConfigGPIO(scl, IOCFG_OUT_OD);
524 IOConfigGPIO(sda, IOCFG_OUT_OD);
526 // Clock out, with SDA high:
527 // 7 data bits
528 // 1 READ bit
529 // 1 cycle for the ACK
530 for (i = 0; i < (LEN_ADDR + LEN_RW + LEN_ACK); i++) {
531 // Wait for any clock stretching to finish
532 int timeout = UNSTICK_CLK_STRETCH;
533 while (!IORead(scl) && timeout) {
534 delayMicroseconds(UNSTICK_CLK_US);
535 timeout--;
538 // Pull low
539 IOLo(scl); // Set bus low
540 delayMicroseconds(UNSTICK_CLK_US/2);
541 IOHi(scl); // Set bus high
542 delayMicroseconds(UNSTICK_CLK_US/2);
545 // Generate a stop condition in case there was none
546 IOLo(scl);
547 delayMicroseconds(UNSTICK_CLK_US/2);
548 IOLo(sda);
549 delayMicroseconds(UNSTICK_CLK_US/2);
551 IOHi(scl); // Set bus scl high
552 delayMicroseconds(UNSTICK_CLK_US/2);
553 IOHi(sda); // Set bus sda high
556 #endif