stm32f4xx: pass through i2c error conditions to callback function

i2c callback function would always indicate success, even when an
error occured.

Fixed i2c drivers to store err value returned by the i2c calls

Bug: 31069187
Change-Id: I8fcada69600e4955219f7dc4750b108a85de415a
Signed-off-by: Ben Fennema <fennema@google.com>
diff --git a/firmware/src/drivers/ams_tmd2772/ams_tmd2772.c b/firmware/src/drivers/ams_tmd2772/ams_tmd2772.c
index 23df204..ddd1270 100644
--- a/firmware/src/drivers/ams_tmd2772/ams_tmd2772.c
+++ b/firmware/src/drivers/ams_tmd2772/ams_tmd2772.c
@@ -145,20 +145,24 @@
 
 struct I2cTransfer
 {
-  union {
-      uint8_t bytes[AMS_TMD2772_MAX_I2C_TRANSFER_SIZE];
-      struct {
-          uint8_t status;
-          uint16_t als[2];
-          uint16_t prox;
-      } __attribute__((packed)) sample;
-      struct {
-          uint16_t prox;
-      } calibration;
-  } txrxBuf;
+    size_t tx;
+    size_t rx;
+    int err;
 
-  uint8_t state;
-  bool inUse;
+    union {
+        uint8_t bytes[AMS_TMD2772_MAX_I2C_TRANSFER_SIZE];
+        struct {
+            uint8_t status;
+            uint16_t als[2];
+            uint16_t prox;
+        } __attribute__((packed)) sample;
+        struct {
+            uint16_t prox;
+        } calibration;
+    } txrxBuf;
+
+    uint8_t state;
+    bool inUse;
 };
 
 
@@ -212,10 +216,15 @@
 
 static void i2cCallback(void *cookie, size_t tx, size_t rx, int err)
 {
-    if (err == 0)
-        osEnqueuePrivateEvt(EVT_SENSOR_I2C, cookie, NULL, mData.tid);
-    else
-        osLog(LOG_INFO, DRIVER_NAME "i2c error (%d)\n", err);
+    struct I2cTransfer *xfer = cookie;
+
+    xfer->tx = tx;
+    xfer->rx = rx;
+    xfer->err = err;
+
+    osEnqueuePrivateEvt(EVT_SENSOR_I2C, cookie, NULL, mData.tid);
+    if (err != 0)
+        osLog(LOG_INFO, DRIVER_NAME "i2c error (tx: %d, rx: %d, err: %d)\n", tx, rx, err);
 }
 
 // Allocate a buffer and mark it as in use with the given state, or return NULL
@@ -305,7 +314,7 @@
         xfer->txrxBuf.bytes[2] = AMS_TMD2772_ATIME_SETTING;
         xfer->txrxBuf.bytes[3] = AMS_TMD2772_PTIME_SETTING;
         xfer->txrxBuf.bytes[4] = alsOn ? AMS_TMD2772_WTIME_SETTING_ALS_ON : AMS_TMD2772_WTIME_SETTING_ALS_OFF;
-        i2cMasterTx(I2C_BUS_ID, I2C_ADDR, xfer->txrxBuf.bytes, 5, &i2cCallback, xfer);
+        i2cMasterTx(I2C_BUS_ID, I2C_ADDR, xfer->txrxBuf.bytes, 5, i2cCallback, xfer);
     }
 }
 
@@ -484,7 +493,7 @@
         nextXfer = allocXfer(SENSOR_STATE_CALIBRATE_POLLING_STATUS);
         if (nextXfer != NULL) {
             nextXfer->txrxBuf.bytes[0] = AMS_TMD2772_REG_STATUS;
-            i2cMasterTxRx(I2C_BUS_ID, I2C_ADDR, nextXfer->txrxBuf.bytes, 1, nextXfer->txrxBuf.bytes, 1, &i2cCallback, nextXfer);
+            i2cMasterTxRx(I2C_BUS_ID, I2C_ADDR, nextXfer->txrxBuf.bytes, 1, nextXfer->txrxBuf.bytes, 1, i2cCallback, nextXfer);
         }
         break;
 
@@ -494,7 +503,7 @@
             nextXfer = allocXfer(SENSOR_STATE_CALIBRATE_AWAITING_SAMPLE);
             if (nextXfer != NULL) {
                 nextXfer->txrxBuf.bytes[0] = AMS_TMD2772_REG_PDATAL;
-                i2cMasterTxRx(I2C_BUS_ID, I2C_ADDR, nextXfer->txrxBuf.bytes, 1, nextXfer->txrxBuf.bytes, 2, &i2cCallback, nextXfer);
+                i2cMasterTxRx(I2C_BUS_ID, I2C_ADDR, nextXfer->txrxBuf.bytes, 1, nextXfer->txrxBuf.bytes, 2, i2cCallback, nextXfer);
             }
         } else {
             /* Poll again; go back to previous state */
@@ -538,7 +547,7 @@
     switch (xfer->state) {
     case SENSOR_STATE_VERIFY_ID:
         /* Check the sensor ID */
-        if (xfer->txrxBuf.bytes[0] != AMS_TMD2772_ID) {
+        if (xfer->err != 0 || xfer->txrxBuf.bytes[0] != AMS_TMD2772_ID) {
             osLog(LOG_INFO, DRIVER_NAME "not detected\n");
             sensorUnregister(mData.alsHandle);
             sensorUnregister(mData.proxHandle);
@@ -557,7 +566,7 @@
             nextXfer->txrxBuf.bytes[3] = AMS_TMD2772_PTIME_SETTING;
             /* WTIME */
             nextXfer->txrxBuf.bytes[4] = 0xFF;
-            i2cMasterTx(I2C_BUS_ID, I2C_ADDR, nextXfer->txrxBuf.bytes, 5, &i2cCallback, nextXfer);
+            i2cMasterTx(I2C_BUS_ID, I2C_ADDR, nextXfer->txrxBuf.bytes, 5, i2cCallback, nextXfer);
         }
         break;
 
@@ -574,7 +583,7 @@
             nextXfer->txrxBuf.bytes[3] = AMS_TMD2772_PPULSE_SETTING;
             /* CONTROL */
             nextXfer->txrxBuf.bytes[4] = 0x20;
-            i2cMasterTx(I2C_BUS_ID, I2C_ADDR, nextXfer->txrxBuf.bytes, 5, &i2cCallback, nextXfer);
+            i2cMasterTx(I2C_BUS_ID, I2C_ADDR, nextXfer->txrxBuf.bytes, 5, i2cCallback, nextXfer);
         }
         break;
 
@@ -704,7 +713,7 @@
         xfer = allocXfer(SENSOR_STATE_VERIFY_ID);
         if (xfer != NULL) {
             xfer->txrxBuf.bytes[0] = AMS_TMD2772_REG_ID;
-            i2cMasterTxRx(I2C_BUS_ID, I2C_ADDR, xfer->txrxBuf.bytes, 1, xfer->txrxBuf.bytes, 1, &i2cCallback, xfer);
+            i2cMasterTxRx(I2C_BUS_ID, I2C_ADDR, xfer->txrxBuf.bytes, 1, xfer->txrxBuf.bytes, 1, i2cCallback, xfer);
         }
         break;
 
@@ -719,7 +728,7 @@
             xfer = allocXfer(SENSOR_STATE_SAMPLING);
             if (xfer != NULL) {
                 xfer->txrxBuf.bytes[0] = AMS_TMD2772_REG_STATUS;
-                i2cMasterTxRx(I2C_BUS_ID, I2C_ADDR, xfer->txrxBuf.bytes, 1, xfer->txrxBuf.bytes, 7, &i2cCallback, xfer);
+                i2cMasterTxRx(I2C_BUS_ID, I2C_ADDR, xfer->txrxBuf.bytes, 1, xfer->txrxBuf.bytes, 7, i2cCallback, xfer);
             }
         }
 
diff --git a/firmware/src/drivers/ams_tmd4903/ams_tmd4903.c b/firmware/src/drivers/ams_tmd4903/ams_tmd4903.c
index f746ffe..a35ee98 100644
--- a/firmware/src/drivers/ams_tmd4903/ams_tmd4903.c
+++ b/firmware/src/drivers/ams_tmd4903/ams_tmd4903.c
@@ -213,6 +213,9 @@
 
 struct AlsProxTransfer
 {
+    size_t tx;
+    size_t rx;
+    int err;
     uint8_t txrxBuf[AMS_TMD4903_MAX_I2C_TRANSFER_SIZE];
     uint8_t state;
     bool inUse;
@@ -365,10 +368,15 @@
 
 static void i2cCallback(void *cookie, size_t tx, size_t rx, int err)
 {
-    if (err == 0)
-        osEnqueuePrivateEvt(EVT_SENSOR_I2C, cookie, NULL, mTask.tid);
-    else
-        INFO_PRINT("i2c error (%d)\n", err);
+    struct AlsProxTransfer *xfer = cookie;
+
+    xfer->tx = tx;
+    xfer->rx = rx;
+    xfer->err = err;
+
+    osEnqueuePrivateEvt(EVT_SENSOR_I2C, cookie, NULL, mTask.tid);
+    if (err != 0)
+        INFO_PRINT("i2c error (tx: %d, rx: %d, err: %d)\n", tx, rx, err);
 }
 
 static void alsTimerCallback(uint32_t timerId, void *cookie)
@@ -701,7 +709,7 @@
     DEBUG_PRINT("REVID = 0x%02x, ID = 0x%02x\n", xfer->txrxBuf[0], xfer->txrxBuf[1]);
 
     // Check the sensor ID
-    if (xfer->txrxBuf[1] != AMS_TMD4903_ID) {
+    if (xfer->err != 0 || xfer->txrxBuf[1] != AMS_TMD4903_ID) {
         INFO_PRINT("not detected\n");
         sensorUnregister(mTask.alsHandle);
         sensorUnregister(mTask.proxHandle);
diff --git a/firmware/src/drivers/bosch_bmp280/bosch_bmp280.c b/firmware/src/drivers/bosch_bmp280/bosch_bmp280.c
index feb621d..727c85e 100644
--- a/firmware/src/drivers/bosch_bmp280/bosch_bmp280.c
+++ b/firmware/src/drivers/bosch_bmp280/bosch_bmp280.c
@@ -46,7 +46,7 @@
 #define BOSCH_BMP280_REG_PRES_MSB       0xf7
 
 #define BOSCH_BMP280_MAX_PENDING_I2C_REQUESTS   4
-#define BOSCH_BMP280_MAX_I2C_TRANSFER_SIZE      24
+#define BOSCH_BMP280_MAX_I2C_TRANSFER_SIZE      6
 
 // temp: 2x oversampling, baro: 16x oversampling, power: normal
 #define CTRL_ON    ((2 << 5) | (5 << 2) | 3)
@@ -85,9 +85,12 @@
 
 struct I2cTransfer
 {
-  uint8_t txrxBuf[BOSCH_BMP280_MAX_I2C_TRANSFER_SIZE];
-  uint8_t state;
-  bool inUse;
+    size_t tx;
+    size_t rx;
+    int err;
+    uint8_t txrxBuf[BOSCH_BMP280_MAX_I2C_TRANSFER_SIZE];
+    uint8_t state;
+    bool inUse;
 };
 
 static struct BMP280Task
@@ -193,10 +196,15 @@
 
 static void i2cCallback(void *cookie, size_t tx, size_t rx, int err)
 {
-    if (err == 0)
-        osEnqueuePrivateEvt(EVT_SENSOR_I2C, cookie, NULL, mTask.id);
-    else
-        osLog(LOG_INFO, "[BMP280] i2c error (%d)\n", err);
+    struct I2cTransfer *xfer = cookie;
+
+    xfer->tx = tx;
+    xfer->rx = rx;
+    xfer->err = err;
+
+    osEnqueuePrivateEvt(EVT_SENSOR_I2C, cookie, NULL, mTask.id);
+    if (err != 0)
+        osLog(LOG_INFO, "[BMP280] i2c error (tx: %d, rx: %d, err: %d)\n", tx, rx, err);
 }
 
 static void baroTimerCallback(uint32_t timerId, void *cookie)
@@ -433,14 +441,14 @@
             newXfer = allocXfer(STATE_VERIFY_ID);
             if (newXfer != NULL) {
                 newXfer->txrxBuf[0] = BOSCH_BMP280_REG_ID;
-                i2cMasterTxRx(I2C_BUS_ID, I2C_ADDR, newXfer->txrxBuf, 1, newXfer->txrxBuf, 1, &i2cCallback, newXfer);
+                i2cMasterTxRx(I2C_BUS_ID, I2C_ADDR, newXfer->txrxBuf, 1, newXfer->txrxBuf, 1, i2cCallback, newXfer);
             }
             break;
         }
 
         case STATE_VERIFY_ID: {
             /* Check the sensor ID */
-            if (xfer->txrxBuf[0] != BOSCH_BMP280_ID) {
+            if (xfer->err != 0 || xfer->txrxBuf[0] != BOSCH_BMP280_ID) {
                 osLog(LOG_INFO, "[BMP280] not detected\n");
                 break;
             }
@@ -449,7 +457,7 @@
             newXfer = allocXfer(STATE_AWAITING_COMP_PARAMS);
             if (newXfer != NULL) {
                 newXfer->txrxBuf[0] = BOSCH_BMP280_REG_DIG_T1;
-                i2cMasterTxRx(I2C_BUS_ID, I2C_ADDR, newXfer->txrxBuf, 1, (uint8_t*)&mTask.comp, 24, &i2cCallback, newXfer);
+                i2cMasterTxRx(I2C_BUS_ID, I2C_ADDR, newXfer->txrxBuf, 1, (uint8_t*)&mTask.comp, 24, i2cCallback, newXfer);
             }
 
             break;
@@ -558,7 +566,7 @@
                 newXfer = allocXfer(STATE_SAMPLING);
                 if (newXfer != NULL) {
                     newXfer->txrxBuf[0] = BOSCH_BMP280_REG_PRES_MSB;
-                    i2cMasterTxRx(I2C_BUS_ID, I2C_ADDR, newXfer->txrxBuf, 1, newXfer->txrxBuf, 6, &i2cCallback, newXfer);
+                    i2cMasterTxRx(I2C_BUS_ID, I2C_ADDR, newXfer->txrxBuf, 1, newXfer->txrxBuf, 6, i2cCallback, newXfer);
                 }
             }
 
@@ -573,7 +581,7 @@
                 newXfer = allocXfer(STATE_SAMPLING);
                 if (newXfer != NULL) {
                     newXfer->txrxBuf[0] = BOSCH_BMP280_REG_PRES_MSB;
-                    i2cMasterTxRx(I2C_BUS_ID, I2C_ADDR, newXfer->txrxBuf, 1, newXfer->txrxBuf, 6, &i2cCallback, newXfer);
+                    i2cMasterTxRx(I2C_BUS_ID, I2C_ADDR, newXfer->txrxBuf, 1, newXfer->txrxBuf, 6, i2cCallback, newXfer);
                 }
             }
 
diff --git a/firmware/src/drivers/rohm_rpr0521/rohm_rpr0521.c b/firmware/src/drivers/rohm_rpr0521/rohm_rpr0521.c
index 30ffc5b..4e8d9d7 100644
--- a/firmware/src/drivers/rohm_rpr0521/rohm_rpr0521.c
+++ b/firmware/src/drivers/rohm_rpr0521/rohm_rpr0521.c
@@ -200,9 +200,12 @@
 
 struct I2cTransfer
 {
-  uint8_t txrxBuf[ROHM_RPR0521_MAX_I2C_TRANSFER_SIZE];
-  uint8_t state;
-  bool inUse;
+    size_t tx;
+    size_t rx;
+    int err;
+    uint8_t txrxBuf[ROHM_RPR0521_MAX_I2C_TRANSFER_SIZE];
+    uint8_t state;
+    bool inUse;
 };
 
 struct SensorData
@@ -283,10 +286,15 @@
 
 static void i2cCallback(void *cookie, size_t tx, size_t rx, int err)
 {
-    if (err == 0)
-        osEnqueuePrivateEvt(EVT_SENSOR_I2C, cookie, NULL, mTask.tid);
-    else
-        INFO_PRINT("i2c error (%d)\n", err);
+    struct I2cTransfer *xfer = cookie;
+
+    xfer->tx = tx;
+    xfer->rx = rx;
+    xfer->err = err;
+
+    osEnqueuePrivateEvt(EVT_SENSOR_I2C, cookie, NULL, mTask.tid);
+    if (err != 0)
+        INFO_PRINT("i2c error (tx: %d, rx: %d, err: %d)\n", tx, rx, err);
 }
 
 static void alsTimerCallback(uint32_t timerId, void *cookie)
@@ -474,7 +482,7 @@
         xfer->txrxBuf[0] = ROHM_RPR0521_REG_PS_OFFSET_LSB;
         xfer->txrxBuf[1] = offset & 0xFF;
         xfer->txrxBuf[2] = (offset >> 8) & 0x3;
-        i2cMasterTx(I2C_BUS_ID, I2C_ADDR, xfer->txrxBuf, 3, &i2cCallback, xfer);
+        i2cMasterTx(I2C_BUS_ID, I2C_ADDR, xfer->txrxBuf, 3, i2cCallback, xfer);
 
         return true;
     }
@@ -562,13 +570,13 @@
         newXfer = allocXfer(SENSOR_STATE_VERIFY_ID);
         if (newXfer != NULL) {
             newXfer->txrxBuf[0] = ROHM_RPR0521_REG_ID;
-            i2cMasterTxRx(I2C_BUS_ID, I2C_ADDR, newXfer->txrxBuf, 1, newXfer->txrxBuf, 1, &i2cCallback, newXfer);
+            i2cMasterTxRx(I2C_BUS_ID, I2C_ADDR, newXfer->txrxBuf, 1, newXfer->txrxBuf, 1, i2cCallback, newXfer);
         }
         break;
 
     case SENSOR_STATE_VERIFY_ID:
         /* Check the sensor ID */
-        if (xfer->txrxBuf[0] != ROHM_RPR0521_ID) {
+        if (xfer->err != 0 || xfer->txrxBuf[0] != ROHM_RPR0521_ID) {
             INFO_PRINT("not detected\n");
             sensorUnregister(mTask.alsHandle);
             sensorUnregister(mTask.proxHandle);
@@ -580,7 +588,7 @@
             newXfer->txrxBuf[0] = ROHM_RPR0521_REG_ALS_PS_CONTROL;
             newXfer->txrxBuf[1] = (ROHM_RPR0521_GAIN_ALS0 << 4) | (ROHM_RPR0521_GAIN_ALS1 << 2) | ROHM_RPR0521_LED_CURRENT;
             newXfer->txrxBuf[2] = (ROHM_RPR0521_GAIN_PS << 4) | PS_PERSISTENCE_ACTIVE_AT_EACH_MEASUREMENT_END;
-            i2cMasterTx(I2C_BUS_ID, I2C_ADDR, newXfer->txrxBuf, 3, &i2cCallback, newXfer);
+            i2cMasterTx(I2C_BUS_ID, I2C_ADDR, newXfer->txrxBuf, 3, i2cCallback, newXfer);
         }
         break;
 
@@ -591,7 +599,7 @@
             newXfer->txrxBuf[0] = ROHM_RPR0521_REG_PS_OFFSET_LSB;
             newXfer->txrxBuf[1] = 0;
             newXfer->txrxBuf[2] = 0;
-            i2cMasterTx(I2C_BUS_ID, I2C_ADDR, newXfer->txrxBuf, 3, &i2cCallback, newXfer);
+            i2cMasterTx(I2C_BUS_ID, I2C_ADDR, newXfer->txrxBuf, 3, i2cCallback, newXfer);
         }
         break;
 
@@ -604,7 +612,7 @@
             newXfer->txrxBuf[2] = (ROHM_RPR0521_THRESHOLD_ASSERT_NEAR & 0xFF00) >> 8;
             newXfer->txrxBuf[3] = (ROHM_RPR0521_THRESHOLD_DEASSERT_NEAR & 0xFF);
             newXfer->txrxBuf[4] = (ROHM_RPR0521_THRESHOLD_DEASSERT_NEAR & 0xFF00) >> 8;
-            i2cMasterTx(I2C_BUS_ID, I2C_ADDR, newXfer->txrxBuf, 5, &i2cCallback, newXfer);
+            i2cMasterTx(I2C_BUS_ID, I2C_ADDR, newXfer->txrxBuf, 5, i2cCallback, newXfer);
         }
         break;
 
@@ -755,7 +763,7 @@
         xfer = allocXfer(SENSOR_STATE_ALS_SAMPLING);
         if (xfer != NULL) {
             xfer->txrxBuf[0] = ROHM_RPR0521_REG_ALS_DATA0_LSB;
-            i2cMasterTxRx(I2C_BUS_ID, I2C_ADDR, xfer->txrxBuf, 1, xfer->txrxBuf, 4, &i2cCallback, xfer);
+            i2cMasterTxRx(I2C_BUS_ID, I2C_ADDR, xfer->txrxBuf, 1, xfer->txrxBuf, 4, i2cCallback, xfer);
         }
         break;
 
@@ -764,7 +772,7 @@
         xfer = allocXfer(SENSOR_STATE_PROX_SAMPLING);
         if (xfer != NULL) {
             xfer->txrxBuf[0] = ROHM_RPR0521_REG_PS_DATA_LSB;
-            i2cMasterTxRx(I2C_BUS_ID, I2C_ADDR, xfer->txrxBuf, 1, xfer->txrxBuf, 7, &i2cCallback, xfer);
+            i2cMasterTxRx(I2C_BUS_ID, I2C_ADDR, xfer->txrxBuf, 1, xfer->txrxBuf, 7, i2cCallback, xfer);
         }
         break;
 
diff --git a/firmware/src/drivers/synaptics_s3708/synaptics_s3708.c b/firmware/src/drivers/synaptics_s3708/synaptics_s3708.c
index 79b6a0f..3aec4d1 100644
--- a/firmware/src/drivers/synaptics_s3708/synaptics_s3708.c
+++ b/firmware/src/drivers/synaptics_s3708/synaptics_s3708.c
@@ -110,6 +110,9 @@
 
 struct I2cTransfer
 {
+    size_t tx;
+    size_t rx;
+    int err;
     uint8_t txrxBuf[MAX_I2C_TRANSFER_SIZE];
     uint8_t state;
     bool inUse;
@@ -155,11 +158,15 @@
 
 static void i2cCallback(void *cookie, size_t tx, size_t rx, int err)
 {
-    if (err == 0) {
-        osEnqueuePrivateEvt(EVT_SENSOR_I2C, cookie, NULL, mTask.id);
-    } else {
-        ERROR_PRINT("I2C error (%d)", err);
-    }
+    struct I2cTransfer *xfer = cookie;
+
+    xfer->tx = tx;
+    xfer->rx = rx;
+    xfer->err = err;
+
+    osEnqueuePrivateEvt(EVT_SENSOR_I2C, cookie, NULL, mTask.id);
+    if (err != 0)
+        ERROR_PRINT("i2c error (tx: %d, rx: %d, err: %d)\n", tx, rx, err);
 }
 
 static void retryTimerCallback(uint32_t timerId, void *cookie)
@@ -346,7 +353,7 @@
             // controller on the first few samples and then have communication
             // switched off. So, wait HACK_RETRY_SKIP_COUNT samples before we
             // consider the transaction.
-            if ((mTask.retryCnt < HACK_RETRY_SKIP_COUNT) || (xfer->txrxBuf[0] != S3708_ID)) {
+            if ((mTask.retryCnt < HACK_RETRY_SKIP_COUNT) || (xfer->err != 0) || (xfer->txrxBuf[0] != S3708_ID)) {
                 mTask.retryCnt++;
                 if (mTask.retryCnt < MAX_I2C_RETRY_COUNT) {
                     mTask.retryTimerHandle = timTimerSet(MAX_I2C_RETRY_DELAY, 0, 50, retryTimerCallback, NULL, true);
diff --git a/firmware/src/platform/stm32f4xx/i2c.c b/firmware/src/platform/stm32f4xx/i2c.c
index dd911c1..17d87dd 100644
--- a/firmware/src/platform/stm32f4xx/i2c.c
+++ b/firmware/src/platform/stm32f4xx/i2c.c
@@ -498,7 +498,7 @@
 
     state->tx.offset = 0;
     state->rx.offset = 0;
-    stmI2cInvokeTxCallback(state, txOffst, rxOffst, 0);
+    stmI2cInvokeTxCallback(state, txOffst, rxOffst, err);
 
     do {
         id = atomicAdd32bits(&pdev->next, 1);
@@ -648,16 +648,21 @@
     struct I2cStmState *state = &pdev->state;
     struct StmI2c *regs = pdev->cfg->regs;
     uint8_t masterState = atomicReadByte(&state->masterState);
+    int err = 0;
 
     if (masterState == STM_I2C_MASTER_TX_ADDR ||
-            masterState == STM_I2C_MASTER_TX_DATA ||
-            masterState == STM_I2C_MASTER_RX_ADDR ||
+            masterState == STM_I2C_MASTER_RX_ADDR) {
+        err = -ENXIO;
+    } else if (masterState == STM_I2C_MASTER_TX_DATA ||
             masterState == STM_I2C_MASTER_RX_DATA) {
         stmI2cMasterDmaCancel(pdev);
+        err = -EIO;
+    }
 
+    if (err) {
         regs->SR1 &= ~I2C_SR1_AF;
         stmI2cStopEnable(pdev);
-        stmI2cMasterTxRxDone(pdev, 0);
+        stmI2cMasterTxRxDone(pdev, err);
     }
 }