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