diff --git a/src/shared/drivers/i2c/I2CDriver-f7.cpp b/src/shared/drivers/i2c/I2CDriver-f7.cpp
index 27f9c32a2430baee304607ec268943f08f74f8e8..2ef687279bbbe89860c99ed77d2a2d19d493035f 100644
--- a/src/shared/drivers/i2c/I2CDriver-f7.cpp
+++ b/src/shared/drivers/i2c/I2CDriver-f7.cpp
@@ -41,17 +41,23 @@ static const int N_SCL_BITBANG =
 static const uint8_t I2C_PIN_ALTERNATE_FUNCTION =
     4;  ///< Alternate Function number of the I2C peripheral pins
 
-static uint8_t PRESC_STD;  ///< PRESC for STANDARD speed
-static uint8_t SCLH_STD;   ///< SCLH for STANDARD speed
-static uint8_t SCLL_STD;   ///< SCLL for STANDARD speed
-
-static uint8_t PRESC_F;  ///< PRESC for FAST speed
-static uint8_t SCLH_F;   ///< SCLH for FAST speed
-static uint8_t SCLL_F;   ///< SCLL for FAST speed
-
-static uint8_t PRESC_FP;  ///< PRESC for FAST PLUS speed
-static uint8_t SCLH_FP;   ///< SCLH for FAST PLUS speed
-static uint8_t SCLL_FP;   ///< SCLL for FAST PLUS speed
+static uint8_t PRESC_STD;   ///< PRESC for STANDARD speed
+static uint8_t SCLH_STD;    ///< SCLH for STANDARD speed
+static uint8_t SCLL_STD;    ///< SCLL for STANDARD speed
+static uint8_t SCLDEL_STD;  ///< SCLDEL for STANDARD speed
+static uint8_t SDADEL_STD;  ///< SDADEL for STANDARD speed
+
+static uint8_t PRESC_F;   ///< PRESC for FAST speed
+static uint8_t SCLH_F;    ///< SCLH for FAST speed
+static uint8_t SCLL_F;    ///< SCLL for FAST speed
+static uint8_t SCLDEL_F;  ///< SCLDEL for FAST speed
+static uint8_t SDADEL_F;  ///< SDADEL for FAST speed
+
+static uint8_t PRESC_FP;   ///< PRESC for FAST PLUS speed
+static uint8_t SCLH_FP;    ///< SCLH for FAST PLUS speed
+static uint8_t SCLL_FP;    ///< SCLL for FAST PLUS speed
+static uint8_t SCLDEL_FP;  ///< SCLDEL for FAST PLUS speed
+static uint8_t SDADEL_FP;  ///< SDADEL for FAST PLUS speed
 }  // namespace I2CConsts
 
 /**
@@ -59,14 +65,14 @@ static uint8_t SCLL_FP;   ///< SCLL for FAST PLUS speed
  * peripheral
  */
 void calculateTimings(uint32_t f, uint32_t fi2c, uint8_t *presc, uint8_t *sclh,
-                      uint8_t *scll)
+                      uint8_t *scll, uint8_t *scldel, uint8_t *sdadel)
 {
     // The formula for the clock is:
     // t_SCL = [(SCLL + 1) + (SCLH + 1)] * (PRESC + 1) * t_I2CCLK + t_sync;
 
     // calculating the "smallest" prescaler so that we can handle in a more
     // refined way (with SCLL and SCLH) the length of high and low phases.
-    uint32_t temp_presc = f / (256 * fi2c);
+    uint32_t temp_presc = f / (64 * fi2c);
 
     // presc is 4 bit long, so avoiding overflow
     if (temp_presc >= 16)
@@ -86,6 +92,31 @@ void calculateTimings(uint32_t f, uint32_t fi2c, uint8_t *presc, uint8_t *sclh,
     // correcting for the 250ns delay of the peripheral (250ns = 12 I2C clocks)
     // distributing the correction on SCLL and SCLH
     *sclh = *scll = (f / (fi2c * 2 * (*presc + 1)) - 1) - (7 / (*presc + 1));
+
+    // SCLDEL >= (t_r + t_su) / ((PRESC+1)*t_i2c) - 1 ; approximated without
+    // subtracting 1
+    uint32_t scldly = 0, sdadly = 0;
+    if (fi2c == 100)
+    {
+        scldly = 1250 * f / (*presc + 1) / 1000000;
+        sdadly = (3450 - 1000 - 260) * f / (*presc + 1) / 1000000;
+    }
+    else if (fi2c == 400)
+    {
+        scldly = 400 * f / (*presc + 1) / 1000000;
+        sdadly = (900 - 300 - 260) * f / (*presc + 1) / 1000000;
+    }
+    else if (fi2c == 1000)
+    {
+        scldly = 170 * f / (*presc + 1) / 1000000;
+        sdadly = (450 - 120 - 260) * f / (*presc + 1) / 1000000;
+    }
+
+    // max value of scldel is 15
+    *scldel = ((scldly < 16) ? (scldly - 1) : 15);
+
+    // max value of sdadel is 15 m
+    *sdadel = ((sdadly < 16) ? (sdadly - 1) : 15);
 }
 
 #ifdef I2C1
@@ -380,21 +411,25 @@ void I2CDriver::init()
         ClockUtils::getAPBPeripheralsClock(ClockUtils::APB::APB1) / 1000;
 
     calculateTimings(f, 100, &I2CConsts::PRESC_STD, &I2CConsts::SCLH_STD,
-                     &I2CConsts::SCLL_STD);
+                     &I2CConsts::SCLL_STD, &I2CConsts::SCLDEL_STD,
+                     &I2CConsts::SDADEL_STD);
 
     calculateTimings(f, 400, &I2CConsts::PRESC_F, &I2CConsts::SCLH_F,
-                     &I2CConsts::SCLL_F);
+                     &I2CConsts::SCLL_F, &I2CConsts::SCLDEL_F,
+                     &I2CConsts::SDADEL_F);
 
     calculateTimings(f, 1000, &I2CConsts::PRESC_FP, &I2CConsts::SCLH_FP,
-                     &I2CConsts::SCLL_FP);
+                     &I2CConsts::SCLL_FP, &I2CConsts::SCLDEL_FP,
+                     &I2CConsts::SDADEL_FP);
 
     // I2CCLK < (t_low - t_filters) / 4
     // I2CCLK < t_high
     // I2CCLK < 4/3 * t_SCL
+    i2c->CR1 |= I2C_CR1_PE;
 }
 
 bool I2CDriver::read(const I2CSlaveConfig &slaveConfig, void *buffer,
-                     size_t nBytes)
+                     const size_t &nBytes)
 {
     // Setting up the read transaction
     transaction.operation    = Operation::READ;
@@ -413,7 +448,7 @@ bool I2CDriver::read(const I2CSlaveConfig &slaveConfig, void *buffer,
 };
 
 bool I2CDriver::write(const I2CSlaveConfig &slaveConfig, const void *buffer,
-                      size_t nBytes, bool generateStop)
+                      const size_t &nBytes, bool generateStop)
 {
     // Setting up the write transaction
     transaction.operation    = Operation::WRITE;
@@ -518,28 +553,29 @@ void I2CDriver::setupPeripheral(const I2CSlaveConfig &slaveConfig)
     if (slaveConfig.speed == Speed::STANDARD)
     {
         i2c->TIMINGR =
-            (I2CConsts::PRESC_STD << I2C_TIMINGR_PRESC_Pos) |  // PRESC
-            (I2CConsts::SCLL_STD << I2C_TIMINGR_SCLL_Pos) |    // SCLL
-            (I2CConsts::SCLH_STD << I2C_TIMINGR_SCLH_Pos) |    // SCLH
-            (0x1 << I2C_TIMINGR_SDADEL_Pos) |                  // SDADEL
-            (0x1 << I2C_TIMINGR_SCLDEL_Pos);                   // SCLDEL
+            (I2CConsts::PRESC_STD << I2C_TIMINGR_PRESC_Pos) |    // PRESC
+            (I2CConsts::SCLL_STD << I2C_TIMINGR_SCLL_Pos) |      // SCLL
+            (I2CConsts::SCLH_STD << I2C_TIMINGR_SCLH_Pos) |      // SCLH
+            (I2CConsts::SCLDEL_STD << I2C_TIMINGR_SCLDEL_Pos) |  // SCLDEL
+            (I2CConsts::SDADEL_STD << I2C_TIMINGR_SDADEL_Pos);   // SDADEL
     }
     else if (slaveConfig.speed == Speed::FAST)
     {
-        i2c->TIMINGR = (I2CConsts::PRESC_F << I2C_TIMINGR_PRESC_Pos) |  // PRESC
-                       (I2CConsts::SCLL_F << I2C_TIMINGR_SCLL_Pos) |    // SCLL
-                       (I2CConsts::SCLH_F << I2C_TIMINGR_SCLH_Pos) |    // SCLH
-                       (0x1 << I2C_TIMINGR_SDADEL_Pos) |  // SDADEL
-                       (0x1 << I2C_TIMINGR_SCLDEL_Pos);   // SCLDEL
+        i2c->TIMINGR =
+            (I2CConsts::PRESC_F << I2C_TIMINGR_PRESC_Pos) |    // PRESC
+            (I2CConsts::SCLL_F << I2C_TIMINGR_SCLL_Pos) |      // SCLL
+            (I2CConsts::SCLH_F << I2C_TIMINGR_SCLH_Pos) |      // SCLH
+            (I2CConsts::SCLDEL_F << I2C_TIMINGR_SCLDEL_Pos) |  // SCLDEL
+            (I2CConsts::SDADEL_F << I2C_TIMINGR_SDADEL_Pos);   // SDADEL
     }
     else if (slaveConfig.speed == Speed::FAST_PLUS)
     {
         i2c->TIMINGR =
-            (I2CConsts::PRESC_FP << I2C_TIMINGR_PRESC_Pos) |  // PRESC
-            (I2CConsts::SCLL_FP << I2C_TIMINGR_SCLL_Pos) |    // SCLL
-            (I2CConsts::SCLH_FP << I2C_TIMINGR_SCLH_Pos) |    // SCLH
-            (0x1 << I2C_TIMINGR_SDADEL_Pos) |                 // SDADEL
-            (0x1 << I2C_TIMINGR_SCLDEL_Pos);                  // SCLDEL
+            (I2CConsts::PRESC_FP << I2C_TIMINGR_PRESC_Pos) |    // PRESC
+            (I2CConsts::SCLL_FP << I2C_TIMINGR_SCLL_Pos) |      // SCLL
+            (I2CConsts::SCLH_FP << I2C_TIMINGR_SCLH_Pos) |      // SCLH
+            (I2CConsts::SCLDEL_FP << I2C_TIMINGR_SCLDEL_Pos) |  // SCLDEL
+            (I2CConsts::SDADEL_FP << I2C_TIMINGR_SDADEL_Pos);   // SDADEL
     }
     else
     {
@@ -575,15 +611,16 @@ void I2CDriver::setupReload()
 {
     if ((transaction.nBytes - transaction.nBytesDone) <= 0xffu)
     {
-        i2c->CR2 &= ~I2C_CR2_RELOAD;
-        i2c->CR2 |= ((transaction.nBytes - transaction.nBytesDone)
-                     << I2C_CR2_NBYTES_Pos);
+        i2c->CR2 =
+            (i2c->CR2 & ~(I2C_CR2_NBYTES_Msk |
+                          I2C_CR2_RELOAD)) |  // clearing NBYTES and RELOAD
+            ((transaction.nBytes - transaction.nBytesDone)
+             << I2C_CR2_NBYTES_Pos);  // Reloading right number of bytes
     }
     else
     {
-        i2c->CR2 |=
-            (I2C_CR2_RELOAD |                // There must be a reload
-             (0xff << I2C_CR2_NBYTES_Pos));  // maximum bytes that can be sent
+        i2c->CR2 |= (I2C_CR2_RELOAD |      // There must be a reload
+                     I2C_CR2_NBYTES_Msk);  // maximum bytes that can be sent
     }
 }
 
@@ -716,6 +753,12 @@ void I2CDriver::IRQhandleInterrupt()
         return;
     }
 
+    // Transfer complete reload: setting registers for the remaining bytes
+    if (i2c->ISR & I2C_ISR_TCR)
+    {
+        setupReload();
+    }
+
     if (transaction.nBytesDone < transaction.nBytes)
     {
         // Performing the read/write
@@ -733,12 +776,6 @@ void I2CDriver::IRQhandleInterrupt()
         }
     }
 
-    // Transfer complete reload: setting registers for the remaining bytes
-    if (i2c->ISR & I2C_ISR_TCR)
-    {
-        setupReload();
-    }
-
     // when stop detected on the bus
     if (i2c->ISR & I2C_ISR_STOPF)
     {
diff --git a/src/tests/drivers/i2c/test-i2c-driver.cpp b/src/tests/drivers/i2c/test-i2c-driver.cpp
index ce9d8ceebe2d091c282167427e8e191441e02bab..0b40f814e233ea2f727dfdf913cc0160c6b41992 100644
--- a/src/tests/drivers/i2c/test-i2c-driver.cpp
+++ b/src/tests/drivers/i2c/test-i2c-driver.cpp
@@ -89,20 +89,15 @@ I2CDriver::I2CSlaveConfig BME280Config{BME280.addressSensor,
                                        I2CDriver::Addressing::BIT7,
                                        I2CDriver::Speed::STANDARD};
 
-I2CDriver::I2CSlaveConfig OLEDConfig_F{
-    OLED.addressSensor, I2CDriver::Addressing::BIT7, I2CDriver::Speed::FAST};
-
-#ifdef _ARCH_CORTEXM7_STM32F7
-I2CDriver::I2CSlaveConfig OLEDConfig_FP{OLED.addressSensor,
-                                        I2CDriver::Addressing::BIT7,
-                                        I2CDriver::Speed::FAST_PLUS};
-#endif  // _ARCH_CORTEXM7_STM32F7
+I2CDriver::I2CSlaveConfig OLEDConfig{OLED.addressSensor,
+                                     I2CDriver::Addressing::BIT7,
+                                     I2CDriver::Speed::STANDARD};
 
 bool i2cDriver(I2CDriver &i2c, I2CSensor sensor,
                I2CDriver::I2CSlaveConfig sensorConfig)
 {
-    uint8_t buffer[10]  = {0};
-    const uint8_t nRead = 1;
+    const size_t nRead    = 300;
+    uint8_t buffer[nRead] = {0};
 
     i2c.flushBus();
 
@@ -132,31 +127,41 @@ bool i2cDriver(I2CDriver &i2c, I2CSensor sensor,
 
 int main()
 {
-    int nRepeat = 50;
+    int nRepeat = 10;
 
-    // thread that uses 100% CPU
-    std::thread t(
-        []()
-        {
-            while (1)
-                ;
-        });
+    // // thread that uses 100% CPU
+    // std::thread t(
+    //     []()
+    //     {
+    //         while (1)
+    //             ;
+    //     });
+
+    I2CDriver i2c(I2C1, i1scl2::getPin(), i1sda2::getPin());
 
     for (;;)
     {
-        I2CDriver i2c(I2C1, i1scl2::getPin(), i1sda2::getPin());
-
         // resetting status of read sensors
         bool statusOLED = true;
         bool statusBMP  = true;
 
         for (int i = 0; i < nRepeat; i++)
         {
-            statusBMP &= i2cDriver(i2c, BMP180, BMP180Config);
-            statusOLED &= i2cDriver(i2c, OLED, OLEDConfig_F);
+            for (I2CDriver::Speed speed :
+                 {I2CDriver::Speed::STANDARD, I2CDriver::Speed::FAST
 #ifdef _ARCH_CORTEXM7_STM32F7
-            statusOLED &= i2cDriver(i2c, OLED, OLEDConfig_FP);
+                  ,
+                  I2CDriver::Speed::FAST_PLUS
 #endif  // _ARCH_CORTEXM7_STM32F7
+                 })
+            {
+                statusBMP &= i2cDriver(
+                    i2c, BMP180,
+                    {BMP180.addressSensor, I2CDriver::Addressing::BIT7, speed});
+                statusOLED &= i2cDriver(
+                    i2c, OLED,
+                    {OLED.addressSensor, I2CDriver::Addressing::BIT7, speed});
+            }
         }
 
         printf("OLED:%d\tBMP:%d\n", statusOLED, statusBMP);
diff --git a/src/tests/drivers/i2c/test-i2c.cpp b/src/tests/drivers/i2c/test-i2c.cpp
index ac292392e681fbcf4b81a18f4f81553544240805..caa0dde6af61b53f6ec7064d24fe0141c7b7fb36 100644
--- a/src/tests/drivers/i2c/test-i2c.cpp
+++ b/src/tests/drivers/i2c/test-i2c.cpp
@@ -24,7 +24,6 @@
 
 #include "drivers/i2c/I2C.h"
 #include "miosix.h"
-#include "scheduler/TaskScheduler.h"
 #include "string"
 #include "string.h"
 #include "thread"
@@ -67,6 +66,8 @@ typedef miosix::Gpio<GPIOH_BASE, 8> i3scl2;
  * one sensor (in order to provoke a locked state).
  */
 
+uint8_t buffer = 0;
+
 typedef struct
 {
     // cppcheck-suppress unusedStructMember
@@ -88,21 +89,14 @@ I2CDriver::I2CSlaveConfig BME280Config{BME280.addressSensor,
                                        I2CDriver::Addressing::BIT7,
                                        I2CDriver::Speed::STANDARD};
 
-I2CDriver::I2CSlaveConfig OLEDConfig_F{
-    OLED.addressSensor, I2CDriver::Addressing::BIT7, I2CDriver::Speed::FAST};
-
-#ifdef _ARCH_CORTEXM7_STM32F7
-I2CDriver::I2CSlaveConfig OLEDConfig_FP{OLED.addressSensor,
-                                        I2CDriver::Addressing::BIT7,
-                                        I2CDriver::Speed::FAST_PLUS};
-#endif  // _ARCH_CORTEXM7_STM32F7
+I2CDriver::I2CSlaveConfig OLEDConfig{OLED.addressSensor,
+                                     I2CDriver::Addressing::BIT7,
+                                     I2CDriver::Speed::STANDARD};
 
 bool i2cDriver(I2C &i2c, I2CSensor sensor,
                I2CDriver::I2CSlaveConfig sensorConfig)
 {
-    uint8_t whoamiContent = 0;
-    const size_t nRead    = 300;
-    uint8_t buffer[nRead] = {0};
+    buffer = 48;
 
     // reset the sensor and then read the whoami
     if (!(i2c.probe(sensorConfig) &&
@@ -132,29 +126,39 @@ int main()
 {
     int nRepeat = 10;
 
-    // thread that uses 100% CPU
-    std::thread t(
-        []()
-        {
-            while (1)
-                ;
-        });
+    // // thread that uses 100% CPU
+    // std::thread t(
+    //     []()
+    //     {
+    //         while (1)
+    //             ;
+    //     });
+
+    SyncedI2C i2c(I2C1, i1scl2::getPin(), i1sda2::getPin());
 
     for (;;)
     {
-        SyncedI2C i2c(I2C1, i1scl2::getPin(), i1sda2::getPin());
-
         // resetting status of read sensors
         bool statusOLED = true;
         bool statusBMP  = true;
 
         for (int i = 0; i < nRepeat; i++)
         {
-            statusBMP &= i2cDriver(i2c, BMP180, BMP180Config);
-            statusOLED &= i2cDriver(i2c, OLED, OLEDConfig_F);
+            for (I2CDriver::Speed speed :
+                 {I2CDriver::Speed::STANDARD, I2CDriver::Speed::FAST
 #ifdef _ARCH_CORTEXM7_STM32F7
-            statusOLED &= i2cDriver(i2c, OLED, OLEDConfig_FP);
+                  ,
+                  I2CDriver::Speed::FAST_PLUS
 #endif  // _ARCH_CORTEXM7_STM32F7
+                 })
+            {
+                statusBMP &= i2cDriver(
+                    i2c, BMP180,
+                    {BMP180.addressSensor, I2CDriver::Addressing::BIT7, speed});
+                statusOLED &= i2cDriver(
+                    i2c, OLED,
+                    {OLED.addressSensor, I2CDriver::Addressing::BIT7, speed});
+            }
         }
 
         printf("OLED:%d\tBMP:%d\n", statusOLED, statusBMP);