mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-04-14 10:07:39 +08:00
HOTFIX: disable interrupt-driven I2C mode, configure pessimistic I2C timeout, correct handling of the NAK generation for I2C master reads.
This looks like it addresses the recent I2C lockup issue, unfortunately it also increases CPU consumption by ~5% for the I2C sensor bus.
This commit is contained in:
parent
7d7c352fb4
commit
bc35bb23dd
@ -163,6 +163,8 @@ static ssize_t at24c_bwrite(FAR struct mtd_dev_s *dev, off_t startblock,
|
||||
size_t nblocks, FAR const uint8_t *buf);
|
||||
static int at24c_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg);
|
||||
|
||||
void at24c_test(void);
|
||||
|
||||
/************************************************************************************
|
||||
* Private Data
|
||||
************************************************************************************/
|
||||
@ -218,6 +220,31 @@ static int at24c_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nbloc
|
||||
return (int)nblocks;
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
* Name: at24c_test
|
||||
************************************************************************************/
|
||||
|
||||
void at24c_test(void)
|
||||
{
|
||||
uint8_t buf[CONFIG_AT24XX_MTD_BLOCKSIZE];
|
||||
unsigned count = 0;
|
||||
unsigned errors = 0;
|
||||
|
||||
for (count = 0; count < 10000; count++) {
|
||||
ssize_t result = at24c_bread(&g_at24c.mtd, 0, 1, buf);
|
||||
if (result == ERROR) {
|
||||
if (errors++ > 2) {
|
||||
vdbg("too many errors\n");
|
||||
return;
|
||||
}
|
||||
} else if (result != 1) {
|
||||
vdbg("unexpected %u\n", result);
|
||||
}
|
||||
if ((count % 100) == 0)
|
||||
vdbg("test %u errors %u\n", count, errors);
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
* Name: at24c_bread
|
||||
************************************************************************************/
|
||||
|
||||
@ -73,6 +73,7 @@ static void eeprom_erase(void);
|
||||
static void eeprom_ioctl(unsigned operation);
|
||||
static void eeprom_save(const char *name);
|
||||
static void eeprom_load(const char *name);
|
||||
static void eeprom_test(void);
|
||||
|
||||
static bool attached = false;
|
||||
static bool started = false;
|
||||
@ -93,6 +94,9 @@ int eeprom_main(int argc, char *argv[])
|
||||
if (!strcmp(argv[1], "erase"))
|
||||
eeprom_erase();
|
||||
|
||||
if (!strcmp(argv[1], "test"))
|
||||
eeprom_test();
|
||||
|
||||
if (0) { /* these actually require a file on the filesystem... */
|
||||
|
||||
if (!strcmp(argv[1], "reformat"))
|
||||
@ -250,3 +254,12 @@ eeprom_load(const char *name)
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
extern void at24c_test(void);
|
||||
|
||||
static void
|
||||
eeprom_test(void)
|
||||
{
|
||||
at24c_test();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
@ -1245,11 +1245,11 @@ static int stm32_i2c_isr(struct stm32_i2c_priv_s *priv)
|
||||
|
||||
/* Disable acknowledge when last byte is to be received */
|
||||
|
||||
priv->dcnt--;
|
||||
if (priv->dcnt == 1)
|
||||
{
|
||||
stm32_i2c_modifyreg(priv, STM32_I2C_CR1_OFFSET, I2C_CR1_ACK, 0);
|
||||
}
|
||||
priv->dcnt--;
|
||||
|
||||
#ifdef CONFIG_I2C_POLLED
|
||||
irqrestore(state);
|
||||
@ -1985,7 +1985,6 @@ int up_i2creset(FAR struct i2c_dev_s * dev)
|
||||
uint32_t scl_gpio;
|
||||
uint32_t sda_gpio;
|
||||
int ret = ERROR;
|
||||
irqstate_t state;
|
||||
|
||||
ASSERT(dev);
|
||||
|
||||
@ -2010,6 +2009,9 @@ int up_i2creset(FAR struct i2c_dev_s * dev)
|
||||
scl_gpio = MKI2C_OUTPUT(priv->config->scl_pin);
|
||||
sda_gpio = MKI2C_OUTPUT(priv->config->sda_pin);
|
||||
|
||||
/* Let SDA go high */
|
||||
stm32_gpiowrite(sda_gpio, 1);
|
||||
|
||||
/* Clock the bus until any slaves currently driving it let it go. */
|
||||
|
||||
clock_count = 0;
|
||||
@ -2017,7 +2019,7 @@ int up_i2creset(FAR struct i2c_dev_s * dev)
|
||||
{
|
||||
/* Give up if we have tried too hard */
|
||||
|
||||
if (clock_count++ > 1000)
|
||||
if (clock_count++ > 10)
|
||||
{
|
||||
goto out;
|
||||
}
|
||||
@ -2032,7 +2034,7 @@ int up_i2creset(FAR struct i2c_dev_s * dev)
|
||||
{
|
||||
/* Give up if we have tried too hard */
|
||||
|
||||
if (stretch_count++ > 1000)
|
||||
if (stretch_count++ > 10)
|
||||
{
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -352,17 +352,19 @@ CONFIG_CAN2_BAUD=700000
|
||||
# I2C configuration
|
||||
#
|
||||
CONFIG_I2C=y
|
||||
#CONFIG_I2C_POLLED=y
|
||||
CONFIG_I2C_POLLED=y
|
||||
CONFIG_I2C_TRANSFER=y
|
||||
CONFIG_I2C_TRACE=n
|
||||
CONFIG_I2C_RESET=y
|
||||
# Allow 180 us per byte, a wide margin for the 400 KHz clock we're using
|
||||
# e.g. 9.6 ms for an EEPROM page write, 0.9 ms for a MAG update
|
||||
CONFIG_STM32_I2CTIMEOUS_PER_BYTE=200
|
||||
# Constant overhead for generating I2C start / stop conditions
|
||||
CONFIG_STM32_I2CTIMEOUS_START_STOP=700
|
||||
# XXX this is bad and we want it gone
|
||||
CONFIG_I2C_WRITEREAD=y
|
||||
|
||||
# Dynamic timeout
|
||||
#CONFIG_STM32_I2C_DYNTIMEO=y
|
||||
#CONFIG_STM32_I2C_DYNTIMEO_STARTSTOP=500
|
||||
#CONFIG_STM32_I2C_DYNTIMEO_USECPERBYTE=200
|
||||
|
||||
# Fixed per-transaction timeout
|
||||
CONFIG_STM32_I2CTIMEOSEC=0
|
||||
CONFIG_STM32_I2CTIMEOMS=10
|
||||
|
||||
#
|
||||
# General build options
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user