diff --git a/os/hal/include/hal_ee24xx.h b/os/hal/include/hal_ee24xx.h index 2c9b3fc42f..475ba61387 100644 --- a/os/hal/include/hal_ee24xx.h +++ b/os/hal/include/hal_ee24xx.h @@ -26,6 +26,11 @@ typedef struct { * Address of IC on I2C bus. */ i2caddr_t addr; + /** + * I2C bus frequency in Hz. Used to compute transaction timeouts. + * If zero, a conservative default will be used by the driver. + */ + uint32_t bus_hz; /** * Pointer to write buffer. The safest size is (pagesize + 2) * Declare with CC_SECTION(".nocache") ... if using I2C with DMA to avoid diff --git a/os/hal/src/hal_ee24xx.c b/os/hal/src/hal_ee24xx.c index ef4b9357f6..41de28c79e 100644 --- a/os/hal/src/hal_ee24xx.c +++ b/os/hal/src/hal_ee24xx.c @@ -59,7 +59,8 @@ Write cycle time (byte or page) - 5 ms #define EEPROM_I2C_CLOCK (i2cp->config->clock_speed) #endif */ -#define EEPROM_I2C_CLOCK 400000 +/* Fallback frequency if not provided via config and not detectable */ +#define EEPROM_I2C_CLOCK_DEFAULT 400000U /* ****************************************************************************** @@ -98,12 +99,13 @@ Write cycle time (byte or page) - 5 ms /** * @brief Calculates requred timeout. */ -static systime_t calc_timeout(I2CDriver *i2cp, size_t txbytes, size_t rxbytes) { +static systime_t calc_timeout(I2CDriver *i2cp, size_t txbytes, size_t rxbytes, uint32_t bus_hz) { (void)i2cp; const uint32_t bitsinbyte = 10; uint32_t tmo; + uint32_t freq = bus_hz ? bus_hz : EEPROM_I2C_CLOCK_DEFAULT; tmo = ((txbytes + rxbytes + 1) * bitsinbyte * 1000); - tmo /= EEPROM_I2C_CLOCK; + tmo /= freq; tmo += 10; /* some additional milliseconds to be safer */ return TIME_MS2I(tmo); } @@ -126,7 +128,7 @@ static msg_t eeprom_read(const I2CEepromFileConfig *eepcfg, const bool one_byte_addr = (eepcfg->size <= 2048U); const uint32_t eff_off = offset + eepcfg->barrier_low; const size_t addr_bytes = one_byte_addr ? 1U : 2U; - systime_t tmo = calc_timeout(eepcfg->i2cp, addr_bytes, len); + systime_t tmo = calc_timeout(eepcfg->i2cp, addr_bytes, len, eepcfg->bus_hz); osalDbgAssert(((len <= eepcfg->size) && ((offset + len) <= eepcfg->size)), "out of device bounds"); @@ -175,7 +177,7 @@ static msg_t eeprom_write(const I2CEepromFileConfig *eepcfg, uint32_t offset, const bool one_byte_addr = (eepcfg->size <= 2048U); const uint32_t eff_off = offset + eepcfg->barrier_low; const size_t addr_bytes = one_byte_addr ? 1U : 2U; - systime_t tmo = calc_timeout(eepcfg->i2cp, (len + addr_bytes), 0); + systime_t tmo = calc_timeout(eepcfg->i2cp, (len + addr_bytes), 0, eepcfg->bus_hz); osalDbgAssert(((len <= eepcfg->size) && ((offset + len) <= eepcfg->size)), "out of device bounds");