From 5c7ff1ff94c01e261e41332381a857c6244b1438 Mon Sep 17 00:00:00 2001
From: Hans Christian Olaussen <41271048+klutvott123@users.noreply.github.com>
Date: Tue, 30 Mar 2021 23:01:01 +0200
Subject: [PATCH] I2C configurable clockspeed
---
make/mcu/STM32F3.mk | 1 +
make/mcu/STM32F7.mk | 1 +
make/mcu/STM32G4.mk | 1 +
make/mcu/STM32H7.mk | 1 +
make/source.mk | 1 +
src/main/cli/settings.c | 8 +-
src/main/drivers/bus_i2c_config.c | 2 +-
src/main/drivers/bus_i2c_hal_init.c | 96 +-----------------
src/main/drivers/bus_i2c_impl.h | 2 +-
src/main/drivers/bus_i2c_stm32f10x.c | 9 +-
src/main/drivers/bus_i2c_stm32f30x.c | 6 +-
src/main/drivers/bus_i2c_timing.c | 112 +++++++++++++++++++++
.../{pg/bus_i2c.h => drivers/bus_i2c_timing.h} | 15 +--
src/main/pg/bus_i2c.c | 14 +--
src/main/pg/bus_i2c.h | 5 +-
src/main/target/common_defaults_post.h | 16 +--
src/main/target/common_pre.h | 10 --
17 files changed, 148 insertions(+), 152 deletions(-)
create mode 100644 src/main/drivers/bus_i2c_timing.c
copy src/main/{pg/bus_i2c.h => drivers/bus_i2c_timing.h} (72%)
diff --git a/make/mcu/STM32F3.mk b/make/mcu/STM32F3.mk
index d5504be62..e1a66cb8f 100644
--- a/make/mcu/STM32F3.mk
+++ b/make/mcu/STM32F3.mk
@@ -80,6 +80,7 @@ MCU_COMMON_SRC = \
startup/system_stm32f30x.c \
drivers/adc_stm32f30x.c \
drivers/bus_i2c_stm32f30x.c \
+ drivers/bus_i2c_timing.c \
drivers/bus_spi_stdperiph.c \
drivers/dma.c \
drivers/light_ws2811strip_stdperiph.c \
diff --git a/make/mcu/STM32F7.mk b/make/mcu/STM32F7.mk
index e1129df55..8d2b22bbb 100644
--- a/make/mcu/STM32F7.mk
+++ b/make/mcu/STM32F7.mk
@@ -175,6 +175,7 @@ MCU_COMMON_SRC = \
drivers/audio_stm32f7xx.c \
drivers/bus_i2c_hal.c \
drivers/bus_i2c_hal_init.c \
+ drivers/bus_i2c_timing.c \
drivers/dma_stm32f7xx.c \
drivers/light_ws2811strip_hal.c \
drivers/transponder_ir_io_hal.c \
diff --git a/make/mcu/STM32G4.mk b/make/mcu/STM32G4.mk
index 2a0b708b8..b7a5fbeb9 100644
--- a/make/mcu/STM32G4.mk
+++ b/make/mcu/STM32G4.mk
@@ -160,6 +160,7 @@ MCU_COMMON_SRC = \
drivers/adc_stm32g4xx.c \
drivers/bus_i2c_hal.c \
drivers/bus_i2c_hal_init.c \
+ drivers/bus_i2c_timing.c \
drivers/bus_spi_hal.c \
drivers/dma_stm32g4xx.c \
drivers/dshot_bitbang.c \
diff --git a/make/mcu/STM32H7.mk b/make/mcu/STM32H7.mk
index 806977c75..00eca8fe7 100644
--- a/make/mcu/STM32H7.mk
+++ b/make/mcu/STM32H7.mk
@@ -291,6 +291,7 @@ MCU_COMMON_SRC = \
drivers/adc_stm32h7xx.c \
drivers/bus_i2c_hal.c \
drivers/bus_i2c_hal_init.c \
+ drivers/bus_i2c_timing.c \
drivers/pwm_output_dshot_hal.c \
drivers/pwm_output_dshot_shared.c \
drivers/persistent.c \
diff --git a/make/source.mk b/make/source.mk
index d678d1ec2..5dd4bd0bc 100644
--- a/make/source.mk
+++ b/make/source.mk
@@ -294,6 +294,7 @@ SIZE_OPTIMISED_SRC := $(SIZE_OPTIMISED_SRC) \
drivers/barometer/barometer_lps.c \
drivers/barometer/barometer_qmp6988.c \
drivers/bus_i2c_config.c \
+ drivers/bus_i2c_timing.c \
drivers/bus_spi_config.c \
drivers/bus_spi_pinconfig.c \
drivers/compass/compass_ak8963.c \
diff --git a/src/main/cli/settings.c b/src/main/cli/settings.c
index a76d7ebfe..5d4bb90db 100644
--- a/src/main/cli/settings.c
+++ b/src/main/cli/settings.c
@@ -1631,19 +1631,19 @@ const clivalue_t valueTable[] = {
#ifdef I2C_FULL_RECONFIGURABILITY
#ifdef USE_I2C_DEVICE_1
{ "i2c1_pullup", VAR_UINT8 | HARDWARE_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_I2C_CONFIG, PG_ARRAY_ELEMENT_OFFSET(i2cConfig_t, 0, pullUp) },
- { "i2c1_overclock", VAR_UINT8 | HARDWARE_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_I2C_CONFIG, PG_ARRAY_ELEMENT_OFFSET(i2cConfig_t, 0, overClock) },
+ { "i2c1_clockspeed_khz", VAR_UINT16 | HARDWARE_VALUE, .config.minmax = { I2C_CLOCKSPEED_MIN_KHZ, I2C_CLOCKSPEED_MAX_KHZ }, PG_I2C_CONFIG, PG_ARRAY_ELEMENT_OFFSET(i2cConfig_t, 0, clockSpeed) },
#endif
#ifdef USE_I2C_DEVICE_2
{ "i2c2_pullup", VAR_UINT8 | HARDWARE_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_I2C_CONFIG, PG_ARRAY_ELEMENT_OFFSET(i2cConfig_t, 1, pullUp) },
- { "i2c2_overclock", VAR_UINT8 | HARDWARE_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_I2C_CONFIG, PG_ARRAY_ELEMENT_OFFSET(i2cConfig_t, 1, overClock) },
+ { "i2c2_clockspeed_khz", VAR_UINT16 | HARDWARE_VALUE, .config.minmax = { I2C_CLOCKSPEED_MIN_KHZ, I2C_CLOCKSPEED_MAX_KHZ }, PG_I2C_CONFIG, PG_ARRAY_ELEMENT_OFFSET(i2cConfig_t, 1, clockSpeed) },
#endif
#ifdef USE_I2C_DEVICE_3
{ "i2c3_pullup", VAR_UINT8 | HARDWARE_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_I2C_CONFIG, PG_ARRAY_ELEMENT_OFFSET(i2cConfig_t, 2, pullUp) },
- { "i2c3_overclock", VAR_UINT8 | HARDWARE_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_I2C_CONFIG, PG_ARRAY_ELEMENT_OFFSET(i2cConfig_t, 2, overClock) },
+ { "i2c3_clockspeed_khz", VAR_UINT16 | HARDWARE_VALUE, .config.minmax = { I2C_CLOCKSPEED_MIN_KHZ, I2C_CLOCKSPEED_MAX_KHZ }, PG_I2C_CONFIG, PG_ARRAY_ELEMENT_OFFSET(i2cConfig_t, 2, clockSpeed) },
#endif
#ifdef USE_I2C_DEVICE_4
{ "i2c4_pullup", VAR_UINT8 | HARDWARE_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_I2C_CONFIG, PG_ARRAY_ELEMENT_OFFSET(i2cConfig_t, 3, pullUp) },
- { "i2c4_overclock", VAR_UINT8 | HARDWARE_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_I2C_CONFIG, PG_ARRAY_ELEMENT_OFFSET(i2cConfig_t, 3, overClock) },
+ { "i2c4_clockspeed_khz", VAR_UINT16 | HARDWARE_VALUE, .config.minmax = { I2C_CLOCKSPEED_MIN_KHZ, I2C_CLOCKSPEED_MAX_KHZ }, PG_I2C_CONFIG, PG_ARRAY_ELEMENT_OFFSET(i2cConfig_t, 3, clockSpeed) },
#endif
#endif
#ifdef USE_MCO
diff --git a/src/main/drivers/bus_i2c_config.c b/src/main/drivers/bus_i2c_config.c
index 32d35b08d..8cf3e9293 100644
--- a/src/main/drivers/bus_i2c_config.c
+++ b/src/main/drivers/bus_i2c_config.c
@@ -71,8 +71,8 @@ void i2cHardwareConfigure(const i2cConfig_t *i2cConfig)
if (pDev->scl && pDev->sda) {
pDev->hardware = hardware;
pDev->reg = hardware->reg;
- pDev->overClock = i2cConfig[device].overClock;
pDev->pullUp = i2cConfig[device].pullUp;
+ pDev->clockSpeed = i2cConfig[device].clockSpeed;
}
}
}
diff --git a/src/main/drivers/bus_i2c_hal_init.c b/src/main/drivers/bus_i2c_hal_init.c
index 4b66b5714..3f00b9b5f 100644
--- a/src/main/drivers/bus_i2c_hal_init.c
+++ b/src/main/drivers/bus_i2c_hal_init.c
@@ -34,6 +34,7 @@
#include "drivers/bus_i2c.h"
#include "drivers/bus_i2c_impl.h"
+#include "drivers/bus_i2c_timing.h"
// Number of bits in I2C protocol phase
#define LEN_ADDR 7
@@ -202,99 +203,6 @@ const i2cHardware_t i2cHardware[I2CDEV_COUNT] = {
i2cDevice_t i2cDevice[I2CDEV_COUNT];
-// Values from I2C-SMBus specification
-static uint16_t trmax; // Rise time (max)
-static uint16_t tfmax; // Fall time (max)
-static uint8_t tsuDATmin; // SDA setup time (min)
-static uint8_t thdDATmin; // SDA hold time (min)
-static uint16_t tHIGHmin; // High period of SCL clock (min)
-static uint16_t tLOWmin; // Low period of SCL clock (min)
-
-// Silicon specific values, from datasheet
-static uint8_t tAFmin; // Analog filter delay (min)
-static uint16_t tAFmax; // Analog filter delay (max)
-
-// Actual (estimated) values
-static uint16_t tr = 100; // Rise time
-static uint16_t tf = 10; // Fall time
-
-/*
- * Compute SCLDEL, SDADEL, SCLH and SCLL for TIMINGR register according to reference manuals.
- */
-static void i2cClockComputeRaw(uint32_t pclkFreq, int i2cFreqKhz, int presc, int dfcoeff,
- uint8_t *scldel, uint8_t *sdadel, uint16_t *sclh, uint16_t *scll)
-{
- if (i2cFreqKhz > 400) {
- // Fm+ (Fast mode plus)
- trmax = 120;
- tfmax = 120;
- tsuDATmin = 50;
- thdDATmin = 0;
- tHIGHmin = 260;
- tLOWmin = 500;
- } else {
- // Fm (Fast mode)
- trmax = 300;
- tfmax = 300;
- tsuDATmin = 100;
- thdDATmin = 0;
- tHIGHmin = 600;
- tLOWmin = 1300;
- }
- tAFmin = 50;
- tAFmax = 90;
-
- // Convert pclkFreq into nsec
- float tI2cclk = 1000000000.0f / pclkFreq;
-
- // Convert target i2cFreq into cycle time (nsec)
- float tSCL = 1000000.0f / i2cFreqKhz;
-
- uint32_t SCLDELmin = (trmax + tsuDATmin)/((presc + 1) * tI2cclk) - 1;
-
- uint32_t SDADELmin = (tfmax + thdDATmin - tAFmin - ((dfcoeff + 3) * tI2cclk)) / ((presc + 1) * tI2cclk);
-
- float tsync1 = tf + tAFmin + dfcoeff * tI2cclk + 2 * tI2cclk;
- float tsync2 = tr + tAFmin + dfcoeff * tI2cclk + 2 * tI2cclk;
-
- float tSCLH = tHIGHmin * tSCL / (tHIGHmin + tLOWmin) - tsync2;
- float tSCLL = tSCL - tSCLH - tsync1 - tsync2;
-
- uint32_t SCLH = tSCLH / ((presc + 1) * tI2cclk) - 1;
- uint32_t SCLL = tSCLL / ((presc + 1) * tI2cclk) - 1;
-
- while (tsync1 + tsync2 + ((SCLH + 1) + (SCLL + 1)) * ((presc + 1) * tI2cclk) < tSCL) {
- SCLH++;
- }
-
- *scldel = SCLDELmin;
- *sdadel = SDADELmin;
- *sclh = SCLH;
- *scll = SCLL;
-}
-
-static uint32_t i2cClockTIMINGR(uint32_t pclkFreq, int i2cFreqKhz, int dfcoeff)
-{
-#define TIMINGR(presc, scldel, sdadel, sclh, scll) \
- ((presc << 28)|(scldel << 20)|(sdadel << 16)|(sclh << 8)|(scll << 0))
-
- uint8_t scldel;
- uint8_t sdadel;
- uint16_t sclh;
- uint16_t scll;
-
- for (int presc = 0; presc < 15; presc++) {
- i2cClockComputeRaw(pclkFreq, i2cFreqKhz, presc, dfcoeff, &scldel, &sdadel, &sclh, &scll);
-
- // If all fields are not overflowing, return TIMINGR.
- // Otherwise, increase prescaler and try again.
- if ((scldel < 16) && (sdadel < 16) && (sclh < 256) && (scll < 256)) {
- return TIMINGR(presc, scldel, sdadel, sclh, scll);
- }
- }
- return 0; // Shouldn't reach here
-}
-
void i2cInit(I2CDevice device)
{
if (device == I2CINVALID) {
@@ -358,7 +266,7 @@ void i2cInit(I2CDevice device)
#error Unknown MCU type
#endif
- pHandle->Init.Timing = i2cClockTIMINGR(i2cPclk, pDev->overClock ? 800 : 400, 0);
+ pHandle->Init.Timing = i2cClockTIMINGR(i2cPclk, pDev->clockSpeed, 0);
pHandle->Init.OwnAddress1 = 0x0;
pHandle->Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
diff --git a/src/main/drivers/bus_i2c_impl.h b/src/main/drivers/bus_i2c_impl.h
index 318f5e724..57a303ebd 100644
--- a/src/main/drivers/bus_i2c_impl.h
+++ b/src/main/drivers/bus_i2c_impl.h
@@ -82,8 +82,8 @@ typedef struct i2cDevice_s {
uint8_t sclAF;
uint8_t sdaAF;
#endif
- bool overClock;
bool pullUp;
+ uint16_t clockSpeed;
// MCU/Driver dependent member follows
#if defined(STM32F1) || defined(STM32F4)
diff --git a/src/main/drivers/bus_i2c_stm32f10x.c b/src/main/drivers/bus_i2c_stm32f10x.c
index 6c6653639..743e88c53 100644
--- a/src/main/drivers/bus_i2c_stm32f10x.c
+++ b/src/main/drivers/bus_i2c_stm32f10x.c
@@ -35,8 +35,6 @@
#include "drivers/bus_i2c.h"
#include "drivers/bus_i2c_impl.h"
-#define CLOCKSPEED 800000 // i2c clockspeed 400kHz default (conform specs), 800kHz and 1200kHz (Betaflight default)
-
// Number of bits in I2C protocol phase
#define LEN_ADDR 7
#define LEN_RW 1
@@ -483,12 +481,7 @@ void i2cInit(I2CDevice device)
i2cInit.I2C_OwnAddress1 = 0;
i2cInit.I2C_Ack = I2C_Ack_Enable;
i2cInit.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
-
- if (pDev->overClock) {
- i2cInit.I2C_ClockSpeed = 800000; // 800khz Maximum speed tested on various boards without issues
- } else {
- i2cInit.I2C_ClockSpeed = 400000; // 400khz Operation according specs
- }
+ i2cInit.I2C_ClockSpeed = pDev->clockSpeed * 1000;
I2C_Cmd(I2Cx, ENABLE);
I2C_Init(I2Cx, &i2cInit);
diff --git a/src/main/drivers/bus_i2c_stm32f30x.c b/src/main/drivers/bus_i2c_stm32f30x.c
index b3f68cd78..54184179b 100644
--- a/src/main/drivers/bus_i2c_stm32f30x.c
+++ b/src/main/drivers/bus_i2c_stm32f30x.c
@@ -36,13 +36,11 @@
#include "drivers/bus_i2c.h"
#include "drivers/bus_i2c_impl.h"
+#include "drivers/bus_i2c_timing.h"
#define IOCFG_I2C_PU IO_CONFIG(GPIO_Mode_AF, GPIO_Speed_50MHz, GPIO_OType_OD, GPIO_PuPd_UP)
#define IOCFG_I2C IO_CONFIG(GPIO_Mode_AF, GPIO_Speed_50MHz, GPIO_OType_OD, GPIO_PuPd_NOPULL)
-#define I2C_HIGHSPEED_TIMING 0x00500E30 // 1000 Khz, 72Mhz Clock, Analog Filter Delay ON, Setup 40, Hold 4.
-#define I2C_STANDARD_TIMING 0x00E0257A // 400 Khz, 72Mhz Clock, Analog Filter Delay ON, Rise 100, Fall 10.
-
#define I2C_GPIO_AF GPIO_AF_4
static volatile uint16_t i2cErrorCount = 0;
@@ -114,7 +112,7 @@ void i2cInit(I2CDevice device)
.I2C_OwnAddress1 = 0x00,
.I2C_Ack = I2C_Ack_Enable,
.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit,
- .I2C_Timing = (pDev->overClock ? I2C_HIGHSPEED_TIMING : I2C_STANDARD_TIMING)
+ .I2C_Timing = i2cClockTIMINGR(SystemCoreClock, pDev->clockSpeed, 0)
};
I2C_Init(I2Cx, &i2cInit);
diff --git a/src/main/drivers/bus_i2c_timing.c b/src/main/drivers/bus_i2c_timing.c
new file mode 100644
index 000000000..ed3b959ca
--- /dev/null
+++ b/src/main/drivers/bus_i2c_timing.c
@@ -0,0 +1,112 @@
+/*
+ * This file is part of Cleanflight and Betaflight.
+ *
+ * Cleanflight and Betaflight are free software. You can redistribute
+ * this software and/or modify this software under the terms of the
+ * GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option)
+ * any later version.
+ *
+ * Cleanflight and Betaflight are distributed in the hope that they
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this software.
+ *
+ * If not, see .
+ */
+
+#include
+
+#include "platform.h"
+
+/*
+ * Compute SCLDEL, SDADEL, SCLH and SCLL for TIMINGR register according to reference manuals.
+ */
+static void i2cClockComputeRaw(uint32_t pclkFreq, int i2cFreqKhz, int presc, int dfcoeff,
+ uint8_t *scldel, uint8_t *sdadel, uint16_t *sclh, uint16_t *scll)
+{
+ // Values from I2C-SMBus specification
+ uint16_t trmax; // Rise time (max)
+ uint16_t tfmax; // Fall time (max)
+ uint8_t tsuDATmin; // SDA setup time (min)
+ uint8_t thdDATmin; // SDA hold time (min)
+ uint16_t tHIGHmin; // High period of SCL clock (min)
+ uint16_t tLOWmin; // Low period of SCL clock (min)
+
+ // Silicon specific values, from datasheet
+ uint8_t tAFmin = 50; // Analog filter delay (min)
+
+ // Actual (estimated) values
+ uint8_t tr = 100; // Rise time
+ uint8_t tf = 10; // Fall time
+
+ if (i2cFreqKhz > 400) {
+ // Fm+ (Fast mode plus)
+ trmax = 120;
+ tfmax = 120;
+ tsuDATmin = 50;
+ thdDATmin = 0;
+ tHIGHmin = 260;
+ tLOWmin = 500;
+ } else {
+ // Fm (Fast mode)
+ trmax = 300;
+ tfmax = 300;
+ tsuDATmin = 100;
+ thdDATmin = 0;
+ tHIGHmin = 600;
+ tLOWmin = 1300;
+ }
+
+ // Convert pclkFreq into nsec
+ float tI2cclk = 1000000000.0f / pclkFreq;
+
+ // Convert target i2cFreq into cycle time (nsec)
+ float tSCL = 1000000.0f / i2cFreqKhz;
+
+ uint32_t SCLDELmin = (trmax + tsuDATmin) / ((presc + 1) * tI2cclk) - 1;
+ uint32_t SDADELmin = (tfmax + thdDATmin - tAFmin - ((dfcoeff + 3) * tI2cclk)) / ((presc + 1) * tI2cclk);
+
+ float tsync1 = tf + tAFmin + dfcoeff * tI2cclk + 2 * tI2cclk;
+ float tsync2 = tr + tAFmin + dfcoeff * tI2cclk + 2 * tI2cclk;
+
+ float tSCLH = tHIGHmin * tSCL / (tHIGHmin + tLOWmin) - tsync2;
+ float tSCLL = tSCL - tSCLH - tsync1 - tsync2;
+
+ uint32_t SCLH = tSCLH / ((presc + 1) * tI2cclk) - 1;
+ uint32_t SCLL = tSCLL / ((presc + 1) * tI2cclk) - 1;
+
+ while (tsync1 + tsync2 + ((SCLH + 1) + (SCLL + 1)) * ((presc + 1) * tI2cclk) < tSCL) {
+ SCLH++;
+ }
+
+ *scldel = SCLDELmin;
+ *sdadel = SDADELmin;
+ *sclh = SCLH;
+ *scll = SCLL;
+}
+
+uint32_t i2cClockTIMINGR(uint32_t pclkFreq, int i2cFreqKhz, int dfcoeff)
+{
+#define TIMINGR(presc, scldel, sdadel, sclh, scll) \
+ ((presc << 28)|(scldel << 20)|(sdadel << 16)|(sclh << 8)|(scll << 0))
+
+ uint8_t scldel;
+ uint8_t sdadel;
+ uint16_t sclh;
+ uint16_t scll;
+
+ for (int presc = 0; presc < 15; presc++) {
+ i2cClockComputeRaw(pclkFreq, i2cFreqKhz, presc, dfcoeff, &scldel, &sdadel, &sclh, &scll);
+
+ // If all fields are not overflowing, return TIMINGR.
+ // Otherwise, increase prescaler and try again.
+ if ((scldel < 16) && (sdadel < 16) && (sclh < 256) && (scll < 256)) {
+ return TIMINGR(presc, scldel, sdadel, sclh, scll);
+ }
+ }
+ return 0; // Shouldn't reach here
+}
diff --git a/src/main/pg/bus_i2c.h b/src/main/drivers/bus_i2c_timing.h
similarity index 72%
copy from src/main/pg/bus_i2c.h
copy to src/main/drivers/bus_i2c_timing.h
index 28cd88b6b..c07058df4 100644
--- a/src/main/pg/bus_i2c.h
+++ b/src/main/drivers/bus_i2c_timing.h
@@ -20,17 +20,4 @@
#pragma once
-#include "drivers/bus_i2c.h"
-#include "drivers/io_types.h"
-#include "drivers/rcc_types.h"
-
-#include "pg/pg.h"
-
-typedef struct i2cConfig_s {
- ioTag_t ioTagScl;
- ioTag_t ioTagSda;
- bool overClock;
- bool pullUp;
-} i2cConfig_t;
-
-PG_DECLARE_ARRAY(i2cConfig_t, I2CDEV_COUNT, i2cConfig);
+uint32_t i2cClockTIMINGR(uint32_t pclkFreq, int i2cFreqKhz, int dfcoeff);
diff --git a/src/main/pg/bus_i2c.c b/src/main/pg/bus_i2c.c
index 846db887c..37c4eb058 100644
--- a/src/main/pg/bus_i2c.c
+++ b/src/main/pg/bus_i2c.c
@@ -42,22 +42,22 @@
typedef struct i2cDefaultConfig_s {
I2CDevice device;
ioTag_t ioTagScl, ioTagSda;
- bool overClock;
bool pullUp;
+ uint16_t clockSpeed;
} i2cDefaultConfig_t;
static const i2cDefaultConfig_t i2cDefaultConfig[] = {
#ifdef USE_I2C_DEVICE_1
- { I2CDEV_1, IO_TAG(I2C1_SCL), IO_TAG(I2C1_SDA), I2C1_OVERCLOCK, I2C1_PULLUP },
+ { I2CDEV_1, IO_TAG(I2C1_SCL), IO_TAG(I2C1_SDA), I2C1_PULLUP, I2C1_CLOCKSPEED },
#endif
#ifdef USE_I2C_DEVICE_2
- { I2CDEV_2, IO_TAG(I2C2_SCL), IO_TAG(I2C2_SDA), I2C2_OVERCLOCK, I2C2_PULLUP },
+ { I2CDEV_2, IO_TAG(I2C2_SCL), IO_TAG(I2C2_SDA), I2C2_PULLUP, I2C2_CLOCKSPEED },
#endif
#ifdef USE_I2C_DEVICE_3
- { I2CDEV_3, IO_TAG(I2C3_SCL), IO_TAG(I2C3_SDA), I2C3_OVERCLOCK, I2C3_PULLUP },
+ { I2CDEV_3, IO_TAG(I2C3_SCL), IO_TAG(I2C3_SDA), I2C3_PULLUP, I2C3_CLOCKSPEED },
#endif
#ifdef USE_I2C_DEVICE_4
- { I2CDEV_4, IO_TAG(I2C4_SCL), IO_TAG(I2C4_SDA), I2C4_OVERCLOCK, I2C4_PULLUP },
+ { I2CDEV_4, IO_TAG(I2C4_SCL), IO_TAG(I2C4_SDA), I2C4_PULLUP, I2C4_CLOCKSPEED },
#endif
};
@@ -70,11 +70,11 @@ void pgResetFn_i2cConfig(i2cConfig_t *i2cConfig)
int device = defconf->device;
i2cConfig[device].ioTagScl = defconf->ioTagScl;
i2cConfig[device].ioTagSda = defconf->ioTagSda;
- i2cConfig[device].overClock = defconf->overClock;
i2cConfig[device].pullUp = defconf->pullUp;
+ i2cConfig[device].clockSpeed = defconf->clockSpeed;
}
}
-PG_REGISTER_ARRAY_WITH_RESET_FN(i2cConfig_t, I2CDEV_COUNT, i2cConfig, PG_I2C_CONFIG, 0);
+PG_REGISTER_ARRAY_WITH_RESET_FN(i2cConfig_t, I2CDEV_COUNT, i2cConfig, PG_I2C_CONFIG, 1);
#endif // defined(USE_I2C) && !defined(USE_SOFT_I2C)
diff --git a/src/main/pg/bus_i2c.h b/src/main/pg/bus_i2c.h
index 28cd88b6b..f460c48aa 100644
--- a/src/main/pg/bus_i2c.h
+++ b/src/main/pg/bus_i2c.h
@@ -26,11 +26,14 @@
#include "pg/pg.h"
+#define I2C_CLOCKSPEED_MIN_KHZ 100
+#define I2C_CLOCKSPEED_MAX_KHZ 1300
+
typedef struct i2cConfig_s {
ioTag_t ioTagScl;
ioTag_t ioTagSda;
- bool overClock;
bool pullUp;
+ uint16_t clockSpeed;
} i2cConfig_t;
PG_DECLARE_ARRAY(i2cConfig_t, I2CDEV_COUNT, i2cConfig);
diff --git a/src/main/target/common_defaults_post.h b/src/main/target/common_defaults_post.h
index 04e6d3577..7324c629b 100644
--- a/src/main/target/common_defaults_post.h
+++ b/src/main/target/common_defaults_post.h
@@ -169,17 +169,17 @@
#endif // I2C_FULL_RECONFIGURABILITY
-#ifndef I2C1_OVERCLOCK
-#define I2C1_OVERCLOCK false
+#ifndef I2C1_CLOCKSPEED
+#define I2C1_CLOCKSPEED 800
#endif
-#ifndef I2C2_OVERCLOCK
-#define I2C2_OVERCLOCK false
+#ifndef I2C2_CLOCKSPEED
+#define I2C2_CLOCKSPEED 800
#endif
-#ifndef I2C3_OVERCLOCK
-#define I2C3_OVERCLOCK false
+#ifndef I2C3_CLOCKSPEED
+#define I2C3_CLOCKSPEED 800
#endif
-#ifndef I2C4_OVERCLOCK
-#define I2C4_OVERCLOCK false
+#ifndef I2C4_CLOCKSPEED
+#define I2C4_CLOCKSPEED 800
#endif
// Default values for internal pullup
diff --git a/src/main/target/common_pre.h b/src/main/target/common_pre.h
index 2d7f25e7e..0f3c448b0 100644
--- a/src/main/target/common_pre.h
+++ b/src/main/target/common_pre.h
@@ -30,9 +30,6 @@
//#define SCHEDULER_DEBUG // define this to use scheduler debug[] values. Undefined by default for performance reasons
-#define I2C1_OVERCLOCK true
-#define I2C2_OVERCLOCK true
-
#ifdef STM32F1
#define MINIMAL_CLI
// Using RX DMA disables the use of receive callbacks
@@ -57,7 +54,6 @@
#define USE_DSHOT_TELEMETRY_STATS
#define USE_RPM_FILTER
#define USE_DYN_IDLE
-#define I2C3_OVERCLOCK true
#define USE_GYRO_DATA_ANALYSE
#define USE_ADC
#define USE_ADC_INTERNAL
@@ -86,8 +82,6 @@
#define USE_DSHOT_TELEMETRY_STATS
#define USE_RPM_FILTER
#define USE_DYN_IDLE
-#define I2C3_OVERCLOCK true
-#define I2C4_OVERCLOCK true
#define USE_GYRO_DATA_ANALYSE
#define USE_OVERCLOCK
#define USE_ADC_INTERNAL
@@ -111,8 +105,6 @@
#define USE_DSHOT_TELEMETRY_STATS
#define USE_RPM_FILTER
#define USE_DYN_IDLE
-#define I2C3_OVERCLOCK true
-#define I2C4_OVERCLOCK true
#define USE_GYRO_DATA_ANALYSE
#define USE_ADC_INTERNAL
#define USE_USB_CDC_HID
@@ -135,8 +127,6 @@
#define USE_DSHOT_TELEMETRY_STATS
#define USE_RPM_FILTER
#define USE_DYN_IDLE
-#define I2C3_OVERCLOCK true
-#define I2C4_OVERCLOCK true
#define USE_OVERCLOCK
#define USE_GYRO_DATA_ANALYSE
#define USE_ADC_INTERNAL
--
2.11.4.GIT