mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-15 04:15:44 +03:00
Merge pull request #10631 from klutvott123/fix-i2c-timeout
Fix I2C timeout
This commit is contained in:
commit
828fed5103
4 changed files with 50 additions and 43 deletions
|
@ -115,9 +115,9 @@ bool i2cWrite(I2CDevice device, uint8_t addr_, uint8_t reg_, uint8_t data)
|
|||
HAL_StatusTypeDef status;
|
||||
|
||||
if (reg_ == 0xFF)
|
||||
status = HAL_I2C_Master_Transmit(pHandle ,addr_ << 1, &data, 1, I2C_DEFAULT_TIMEOUT);
|
||||
status = HAL_I2C_Master_Transmit(pHandle ,addr_ << 1, &data, 1, I2C_TIMEOUT_SYS_TICKS);
|
||||
else
|
||||
status = HAL_I2C_Mem_Write(pHandle ,addr_ << 1, reg_, I2C_MEMADD_SIZE_8BIT, &data, 1, I2C_DEFAULT_TIMEOUT);
|
||||
status = HAL_I2C_Mem_Write(pHandle ,addr_ << 1, reg_, I2C_MEMADD_SIZE_8BIT, &data, 1, I2C_TIMEOUT_SYS_TICKS);
|
||||
|
||||
if (status != HAL_OK)
|
||||
return i2cHandleHardwareFailure(device);
|
||||
|
@ -170,9 +170,9 @@ bool i2cRead(I2CDevice device, uint8_t addr_, uint8_t reg_, uint8_t len, uint8_t
|
|||
HAL_StatusTypeDef status;
|
||||
|
||||
if (reg_ == 0xFF)
|
||||
status = HAL_I2C_Master_Receive(pHandle ,addr_ << 1, buf, len, I2C_DEFAULT_TIMEOUT);
|
||||
status = HAL_I2C_Master_Receive(pHandle ,addr_ << 1, buf, len, I2C_TIMEOUT_SYS_TICKS);
|
||||
else
|
||||
status = HAL_I2C_Mem_Read(pHandle, addr_ << 1, reg_, I2C_MEMADD_SIZE_8BIT,buf, len, I2C_DEFAULT_TIMEOUT);
|
||||
status = HAL_I2C_Mem_Read(pHandle, addr_ << 1, reg_, I2C_MEMADD_SIZE_8BIT,buf, len, I2C_TIMEOUT_SYS_TICKS);
|
||||
|
||||
if (status != HAL_OK) {
|
||||
return i2cHandleHardwareFailure(device);
|
||||
|
|
|
@ -25,9 +25,8 @@
|
|||
#include "drivers/io_types.h"
|
||||
#include "drivers/rcc_types.h"
|
||||
|
||||
#define I2C_SHORT_TIMEOUT ((uint32_t)0x1000)
|
||||
#define I2C_LONG_TIMEOUT ((uint32_t)(10 * I2C_SHORT_TIMEOUT))
|
||||
#define I2C_DEFAULT_TIMEOUT I2C_SHORT_TIMEOUT
|
||||
#define I2C_TIMEOUT_US 10000
|
||||
#define I2C_TIMEOUT_SYS_TICKS (I2C_TIMEOUT_US / 1000)
|
||||
|
||||
#define I2C_PIN_SEL_MAX 4
|
||||
|
||||
|
|
|
@ -182,7 +182,7 @@ bool i2cWriteBuffer(I2CDevice device, uint8_t addr_, uint8_t reg_, uint8_t len_,
|
|||
return false;
|
||||
}
|
||||
|
||||
uint32_t timeout = I2C_DEFAULT_TIMEOUT;
|
||||
timeUs_t timeoutStartUs = microsISR();
|
||||
|
||||
state->addr = addr_ << 1;
|
||||
state->reg = reg_;
|
||||
|
@ -196,9 +196,11 @@ bool i2cWriteBuffer(I2CDevice device, uint8_t addr_, uint8_t reg_, uint8_t len_,
|
|||
|
||||
if (!(I2Cx->CR2 & I2C_IT_EVT)) { // if we are restarting the driver
|
||||
if (!(I2Cx->CR1 & I2C_CR1_START)) { // ensure sending a start
|
||||
while (I2Cx->CR1 & I2C_CR1_STOP && --timeout > 0) {; } // wait for any stop to finish sending
|
||||
if (timeout == 0)
|
||||
return i2cHandleHardwareFailure(device);
|
||||
while (I2Cx->CR1 & I2C_CR1_STOP) { // wait for any stop to finish sending
|
||||
if (cmpTimeUs(microsISR(), timeoutStartUs) >= I2C_TIMEOUT_US) {
|
||||
return i2cHandleHardwareFailure(device);
|
||||
}
|
||||
}
|
||||
I2C_GenerateSTART(I2Cx, ENABLE); // send the start for the new job
|
||||
}
|
||||
I2C_ITConfig(I2Cx, I2C_IT_EVT | I2C_IT_ERR, ENABLE); // allow the interrupts to fire off again
|
||||
|
@ -220,11 +222,13 @@ bool i2cBusy(I2CDevice device, bool *error)
|
|||
bool i2cWait(I2CDevice device)
|
||||
{
|
||||
i2cState_t *state = &i2cDevice[device].state;
|
||||
uint32_t timeout = I2C_DEFAULT_TIMEOUT;
|
||||
timeUs_t timeoutStartUs = microsISR();
|
||||
|
||||
while (state->busy && --timeout > 0) {; }
|
||||
if (timeout == 0)
|
||||
return i2cHandleHardwareFailure(device) && i2cWait(device);
|
||||
while (state->busy) {
|
||||
if (cmpTimeUs(microsISR(), timeoutStartUs) >= I2C_TIMEOUT_US) {
|
||||
return i2cHandleHardwareFailure(device) && i2cWait(device);
|
||||
}
|
||||
}
|
||||
|
||||
return !(state->error);
|
||||
}
|
||||
|
@ -250,7 +254,7 @@ bool i2cReadBuffer(I2CDevice device, uint8_t addr_, uint8_t reg_, uint8_t len, u
|
|||
return false;
|
||||
}
|
||||
|
||||
uint32_t timeout = I2C_DEFAULT_TIMEOUT;
|
||||
timeUs_t timeoutStartUs = microsISR();
|
||||
|
||||
state->addr = addr_ << 1;
|
||||
state->reg = reg_;
|
||||
|
@ -264,9 +268,11 @@ bool i2cReadBuffer(I2CDevice device, uint8_t addr_, uint8_t reg_, uint8_t len, u
|
|||
|
||||
if (!(I2Cx->CR2 & I2C_IT_EVT)) { // if we are restarting the driver
|
||||
if (!(I2Cx->CR1 & I2C_CR1_START)) { // ensure sending a start
|
||||
while (I2Cx->CR1 & I2C_CR1_STOP && --timeout > 0) {; } // wait for any stop to finish sending
|
||||
if (timeout == 0)
|
||||
return i2cHandleHardwareFailure(device);
|
||||
while (I2Cx->CR1 & I2C_CR1_STOP) { // wait for any stop to finish sending
|
||||
if (cmpTimeUs(microsISR(), timeoutStartUs) >= I2C_TIMEOUT_US) {
|
||||
return i2cHandleHardwareFailure(device);
|
||||
}
|
||||
}
|
||||
I2C_GenerateSTART(I2Cx, ENABLE); // send the start for the new job
|
||||
}
|
||||
I2C_ITConfig(I2Cx, I2C_IT_EVT | I2C_IT_ERR, ENABLE); // allow the interrupts to fire off again
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "drivers/io.h"
|
||||
#include "drivers/io_impl.h"
|
||||
#include "drivers/rcc.h"
|
||||
#include "drivers/time.h"
|
||||
|
||||
#include "drivers/bus_i2c.h"
|
||||
#include "drivers/bus_i2c_impl.h"
|
||||
|
@ -44,8 +45,6 @@
|
|||
|
||||
#define I2C_GPIO_AF GPIO_AF_4
|
||||
|
||||
static uint32_t i2cTimeout;
|
||||
|
||||
static volatile uint16_t i2cErrorCount = 0;
|
||||
|
||||
const i2cHardware_t i2cHardware[I2CDEV_COUNT] = {
|
||||
|
@ -144,10 +143,12 @@ bool i2cWrite(I2CDevice device, uint8_t addr_, uint8_t reg, uint8_t data)
|
|||
|
||||
addr_ <<= 1;
|
||||
|
||||
timeUs_t timeoutStartUs;
|
||||
|
||||
/* Test on BUSY Flag */
|
||||
i2cTimeout = I2C_LONG_TIMEOUT;
|
||||
timeoutStartUs = microsISR();
|
||||
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_BUSY) != RESET) {
|
||||
if ((i2cTimeout--) == 0) {
|
||||
if (cmpTimeUs(microsISR(), timeoutStartUs) >= I2C_TIMEOUT_US) {
|
||||
return i2cTimeoutUserCallback();
|
||||
}
|
||||
}
|
||||
|
@ -156,9 +157,9 @@ bool i2cWrite(I2CDevice device, uint8_t addr_, uint8_t reg, uint8_t data)
|
|||
I2C_TransferHandling(I2Cx, addr_, 1, I2C_Reload_Mode, I2C_Generate_Start_Write);
|
||||
|
||||
/* Wait until TXIS flag is set */
|
||||
i2cTimeout = I2C_LONG_TIMEOUT;
|
||||
timeoutStartUs = microsISR();
|
||||
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_TXIS) == RESET) {
|
||||
if ((i2cTimeout--) == 0) {
|
||||
if (cmpTimeUs(microsISR(), timeoutStartUs) >= I2C_TIMEOUT_US) {
|
||||
return i2cTimeoutUserCallback();
|
||||
}
|
||||
}
|
||||
|
@ -167,10 +168,9 @@ bool i2cWrite(I2CDevice device, uint8_t addr_, uint8_t reg, uint8_t data)
|
|||
I2C_SendData(I2Cx, (uint8_t) reg);
|
||||
|
||||
/* Wait until TCR flag is set */
|
||||
i2cTimeout = I2C_LONG_TIMEOUT;
|
||||
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_TCR) == RESET)
|
||||
{
|
||||
if ((i2cTimeout--) == 0) {
|
||||
timeoutStartUs = microsISR();
|
||||
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_TCR) == RESET) {
|
||||
if (cmpTimeUs(microsISR(), timeoutStartUs) >= I2C_TIMEOUT_US) {
|
||||
return i2cTimeoutUserCallback();
|
||||
}
|
||||
}
|
||||
|
@ -179,9 +179,9 @@ bool i2cWrite(I2CDevice device, uint8_t addr_, uint8_t reg, uint8_t data)
|
|||
I2C_TransferHandling(I2Cx, addr_, 1, I2C_AutoEnd_Mode, I2C_No_StartStop);
|
||||
|
||||
/* Wait until TXIS flag is set */
|
||||
i2cTimeout = I2C_LONG_TIMEOUT;
|
||||
timeoutStartUs = microsISR();
|
||||
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_TXIS) == RESET) {
|
||||
if ((i2cTimeout--) == 0) {
|
||||
if (cmpTimeUs(microsISR(), timeoutStartUs) >= I2C_TIMEOUT_US) {
|
||||
return i2cTimeoutUserCallback();
|
||||
}
|
||||
}
|
||||
|
@ -190,9 +190,9 @@ bool i2cWrite(I2CDevice device, uint8_t addr_, uint8_t reg, uint8_t data)
|
|||
I2C_SendData(I2Cx, data);
|
||||
|
||||
/* Wait until STOPF flag is set */
|
||||
i2cTimeout = I2C_LONG_TIMEOUT;
|
||||
timeoutStartUs = microsISR();
|
||||
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_STOPF) == RESET) {
|
||||
if ((i2cTimeout--) == 0) {
|
||||
if (cmpTimeUs(microsISR(), timeoutStartUs) >= I2C_TIMEOUT_US) {
|
||||
return i2cTimeoutUserCallback();
|
||||
}
|
||||
}
|
||||
|
@ -217,10 +217,12 @@ bool i2cRead(I2CDevice device, uint8_t addr_, uint8_t reg, uint8_t len, uint8_t*
|
|||
|
||||
addr_ <<= 1;
|
||||
|
||||
timeUs_t timeoutStartUs;
|
||||
|
||||
/* Test on BUSY Flag */
|
||||
i2cTimeout = I2C_LONG_TIMEOUT;
|
||||
timeoutStartUs = microsISR();
|
||||
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_BUSY) != RESET) {
|
||||
if ((i2cTimeout--) == 0) {
|
||||
if (cmpTimeUs(microsISR(), timeoutStartUs) >= I2C_TIMEOUT_US) {
|
||||
return i2cTimeoutUserCallback();
|
||||
}
|
||||
}
|
||||
|
@ -229,9 +231,9 @@ bool i2cRead(I2CDevice device, uint8_t addr_, uint8_t reg, uint8_t len, uint8_t*
|
|||
I2C_TransferHandling(I2Cx, addr_, 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Write);
|
||||
|
||||
/* Wait until TXIS flag is set */
|
||||
i2cTimeout = I2C_LONG_TIMEOUT;
|
||||
timeoutStartUs = microsISR();
|
||||
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_TXIS) == RESET) {
|
||||
if ((i2cTimeout--) == 0) {
|
||||
if (cmpTimeUs(microsISR(), timeoutStartUs) >= I2C_TIMEOUT_US) {
|
||||
return i2cTimeoutUserCallback();
|
||||
}
|
||||
}
|
||||
|
@ -240,9 +242,9 @@ bool i2cRead(I2CDevice device, uint8_t addr_, uint8_t reg, uint8_t len, uint8_t*
|
|||
I2C_SendData(I2Cx, (uint8_t) reg);
|
||||
|
||||
/* Wait until TC flag is set */
|
||||
i2cTimeout = I2C_LONG_TIMEOUT;
|
||||
timeoutStartUs = microsISR();
|
||||
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_TC) == RESET) {
|
||||
if ((i2cTimeout--) == 0) {
|
||||
if (cmpTimeUs(microsISR(), timeoutStartUs) >= I2C_TIMEOUT_US) {
|
||||
return i2cTimeoutUserCallback();
|
||||
}
|
||||
}
|
||||
|
@ -253,9 +255,9 @@ bool i2cRead(I2CDevice device, uint8_t addr_, uint8_t reg, uint8_t len, uint8_t*
|
|||
/* Wait until all data are received */
|
||||
while (len) {
|
||||
/* Wait until RXNE flag is set */
|
||||
i2cTimeout = I2C_LONG_TIMEOUT;
|
||||
timeoutStartUs = microsISR();
|
||||
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_RXNE) == RESET) {
|
||||
if ((i2cTimeout--) == 0) {
|
||||
if (cmpTimeUs(microsISR(), timeoutStartUs) >= I2C_TIMEOUT_US) {
|
||||
return i2cTimeoutUserCallback();
|
||||
}
|
||||
}
|
||||
|
@ -270,9 +272,9 @@ bool i2cRead(I2CDevice device, uint8_t addr_, uint8_t reg, uint8_t len, uint8_t*
|
|||
}
|
||||
|
||||
/* Wait until STOPF flag is set */
|
||||
i2cTimeout = I2C_LONG_TIMEOUT;
|
||||
timeoutStartUs = microsISR();
|
||||
while (I2C_GetFlagStatus(I2Cx, I2C_ISR_STOPF) == RESET) {
|
||||
if ((i2cTimeout--) == 0) {
|
||||
if (cmpTimeUs(microsISR(), timeoutStartUs) >= I2C_TIMEOUT_US) {
|
||||
return i2cTimeoutUserCallback();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue