diff --git a/src/shared/drivers/i2c/I2CDriver-f7.cpp b/src/shared/drivers/i2c/I2CDriver-f7.cpp
index 10c9eac8a7dc914c2a5d5f5cd63ea2263a07ebcf..080277ab4cb67a47c2b9c2d10cf666c030e0f6cd 100644
--- a/src/shared/drivers/i2c/I2CDriver-f7.cpp
+++ b/src/shared/drivers/i2c/I2CDriver-f7.cpp
@@ -63,15 +63,24 @@ static uint8_t SDADEL_FP;  ///< SDADEL for FAST PLUS speed
 /**
  * @brief Helper function for calculating the timing parameters for the
  * peripheral
+ *
+ * The formula for the clock is:
+ * t_SCL = [(SCLL + 1) + (SCLH + 1)] * (PRESC + 1) * t_I2CCLK + t_sync
+ * @param f Peripheral timer clock frequency in kHz
+ * @param fi2c I2C clock frequency in kHz
+ * @param presc pointer to the prescaler variable to set
+ * @param sclh pointer to the sclh variable to set
+ * @param scll pointer to the scll variable to set
+ * @param scldel pointer to the scldel variable to set
+ * @param sdadel pointer to the sdadel variable to set
  */
 void calculateTimings(uint32_t f, uint32_t fi2c, uint8_t *presc, uint8_t *sclh,
                       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.
+    // refined way (with SCLL and SCLH) the length of high and low phases. We
+    // "limit" SCLL and SCLH to 64 because like so we can have acceptable values
+    // for SCLDEL and SDADEL
     uint32_t temp_presc = f / (64 * fi2c);
 
     // presc is 4 bit long, so avoiding overflow
@@ -94,7 +103,8 @@ void calculateTimings(uint32_t f, uint32_t fi2c, uint8_t *presc, uint8_t *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
+    // subtracting 1. scldly and sdadly are calculated using values taken from
+    // the reference manual
     uint32_t scldly = 0, sdadly = 0;
     if (fi2c == 100)
     {
@@ -115,7 +125,7 @@ void calculateTimings(uint32_t f, uint32_t fi2c, uint8_t *presc, uint8_t *sclh,
     // max value of scldel is 15
     *scldel = ((scldly < 16) ? (scldly - 1) : 15);
 
-    // max value of sdadel is 15 m
+    // max value of sdadel is 15
     *sdadel = ((sdadly < 16) ? (sdadly - 1) : 15);
 }
 
@@ -410,21 +420,24 @@ void I2CDriver::init()
     uint32_t f =
         ClockUtils::getAPBPeripheralsClock(ClockUtils::APB::APB1) / 1000;
 
+    // Calculating for all the speed modes the clock parameters (so we won't
+    // have to calculate them again for every transaction)
+    // Standard mode (100 kHz)
     calculateTimings(f, 100, &I2CConsts::PRESC_STD, &I2CConsts::SCLH_STD,
                      &I2CConsts::SCLL_STD, &I2CConsts::SCLDEL_STD,
                      &I2CConsts::SDADEL_STD);
 
+    // Fast mode (400 kHz)
     calculateTimings(f, 400, &I2CConsts::PRESC_F, &I2CConsts::SCLH_F,
                      &I2CConsts::SCLL_F, &I2CConsts::SCLDEL_F,
                      &I2CConsts::SDADEL_F);
 
+    // Fast mode plus (1000 kHz)
     calculateTimings(f, 1000, &I2CConsts::PRESC_FP, &I2CConsts::SCLH_FP,
                      &I2CConsts::SCLL_FP, &I2CConsts::SCLDEL_FP,
                      &I2CConsts::SDADEL_FP);
 
-    // I2CCLK < (t_low - t_filters) / 4
-    // I2CCLK < t_high
-    // I2CCLK < 4/3 * t_SCL
+    // Enabling the peripheral after initialization
     i2c->CR1 |= I2C_CR1_PE;
 }
 
@@ -468,7 +481,7 @@ bool I2CDriver::write(const I2CSlaveConfig &slaveConfig, const void *buffer,
 
 bool I2CDriver::doOperation(const I2CSlaveConfig &slaveConfig)
 {
-    // Not yet supported
+    // 10-bit addressing not supported
     D(assert(slaveConfig.addressing == Addressing::BIT7 &&
              "Only 7-bit addressing supported!"));
 
@@ -504,7 +517,8 @@ bool I2CDriver::doOperation(const I2CSlaveConfig &slaveConfig)
     // Setting up transaction
     setupTransaction();
 
-    // Sending STOP condition and wake up thread
+    // Now proceeding as every other transaction (re-starting specific code
+    // already executed)
     reStarting = false;
 
     // clearing pending flags
@@ -518,10 +532,14 @@ bool I2CDriver::doOperation(const I2CSlaveConfig &slaveConfig)
         miosix::FastInterruptDisableLock dLock;
 
         // Sending the start condition
+        // [WARNING]: In F7 the START condition is not generated immediately
+        // when set the flag, but the peripheral waits that the bus is free for
+        // sending the START condition + slave address. This could be bad since
+        // the peripheral isn't deterministic in time.
         i2c->CR2 |= I2C_CR2_START;
 
-        // setting automatic stop generation if we have to generate STOP
-        // condition. This must be done after the START condition generation
+        // Setting automatic stop generation if we have to generate STOP
+        // condition. This MUST be done after the START condition generation
         // since, in case of a reStart, this would immediately end the previous
         // transaction before the start condition is generated.
         if (transaction.generateStop)
@@ -543,13 +561,13 @@ bool I2CDriver::doOperation(const I2CSlaveConfig &slaveConfig)
 
 void I2CDriver::setupPeripheral(const I2CSlaveConfig &slaveConfig)
 {
-    // Disabling the I2C peripheral before setting the registers
+    // Disabling the I2C peripheral before setting the registers.
+    // This will also perform a software reset, useful to restore the internal
+    // state machines and flags in order to start with a clear environment
     i2c->CR1 &= ~I2C_CR1_PE;
 
-    // setting the SCLH and SCLL bits in I2C_TIMINGR register to generate
-    // correct timings for each speed modes.
-    // SDADEL and SCLDEL are set to 1 just to provide a bit of margin but not
-    // too much (in order not to slow down communication)
+    // Setting PRESC, SCLH, SCLL, SCLDEL and SDADEL bits in I2C_TIMINGR register
+    // to generate correct timings for each speed mode
     if (slaveConfig.speed == Speed::STANDARD)
     {
         i2c->TIMINGR =
@@ -582,12 +600,13 @@ void I2CDriver::setupPeripheral(const I2CSlaveConfig &slaveConfig)
         D(assert(false && "speed not supported"));
     }
 
-    // setting addressing mode, read or write mode and slave address
+    // setting addressing mode and slave address (for 7-Bit addressing the 7
+    // bits have to be set on SADD[7:1])
     i2c->CR2 =
         (slaveConfig.addressing == Addressing::BIT10 ? I2C_CR2_ADD10 : 0) |
         (slaveConfig.slaveAddress << (I2C_CR2_SADD_Pos + 1));
 
-    // Finally enabling the peripheral
+    // Re-enabling the peripheral
     i2c->CR1 |= I2C_CR1_PE;
 }
 
@@ -609,6 +628,9 @@ void I2CDriver::setupTransaction()
 
 void I2CDriver::setupReload()
 {
+    // If we are left with a communication of less than 256 bytes, we can do it
+    // without reloading, otherwise we must perform the transaction with the
+    // first 255 bytes and then perform a reload operation
     if ((transaction.nBytes - transaction.nBytesDone) <= 0xffu)
     {
         i2c->CR2 =
@@ -626,7 +648,7 @@ void I2CDriver::setupReload()
 
 void I2CDriver::flushBus()
 {
-    // If there isn't any locked state return immediately
+    // If there isn't any locked state or bus error return immediately
     if (!((lastError & (Errors::BUS_LOCKED | Errors::BERR)) &&
           ((i2c->ISR & I2C_ISR_BUSY))))
     {
@@ -745,7 +767,7 @@ void I2CDriver::IRQhandleInterrupt()
     if (i2c->ISR & I2C_ISR_NACKF)
     {
         // "reserved" bit in the ISR register, so we don't collide with
-        // other fields
+        // other fields. Set to force an error
         error = 1 << 14;
         lastError |= Errors::AF;
         i2c->ICR |= I2C_ICR_NACKCF;