Jelajahi Sumber

Bugfix: I2C Kommunikation failsafe gemacht

Heinrich Blatt 7 bulan lalu
induk
melakukan
a17001f7dc
2 mengubah file dengan 46 tambahan dan 25 penghapusan
  1. 43 22
      src/interfaces/i2c_controller.c
  2. 3 3
      src/interfaces/i2c_target.c

+ 43 - 22
src/interfaces/i2c_controller.c

@@ -33,9 +33,15 @@ static bool msp_i2c_write(uint8_t const TARGET_ADDRESS) {
     }
     
     // **Wait for I2C Bus to be Free**
-    while (DL_I2C_getControllerStatus(I2C_controller_INST) &
-          DL_I2C_CONTROLLER_STATUS_BUSY_BUS)
-      ;
+    uint32_t n_cycles = 0;
+    while ((DL_I2C_getControllerStatus(I2C_controller_INST) &
+            DL_I2C_CONTROLLER_STATUS_BUSY_BUS) && n_cycles++ < MAX_I2C_WAIT_RX)
+        ;
+    if (n_cycles == MAX_I2C_WAIT_RX) {
+        printf("Error in reading from I2C Bus: Bus is not getting ready before transmit start\n");
+        DL_I2C_resetControllerTransfer(I2C_controller_INST); 
+        return false;
+    }
 
     // **Start I2C Write Transaction**
     DL_I2C_startControllerTransfer(I2C_controller_INST, TARGET_ADDRESS,
@@ -49,10 +55,15 @@ static bool msp_i2c_write(uint8_t const TARGET_ADDRESS) {
     }
 #endif
 
-    // ** Wait for the I2C Bus to be FREE **
-    while (DL_I2C_getControllerStatus(I2C_controller_INST) &
-          DL_I2C_CONTROLLER_STATUS_BUSY_BUS)
-      ;
+    n_cycles = 0;
+    while ((DL_I2C_getControllerStatus(I2C_controller_INST) &
+            DL_I2C_CONTROLLER_STATUS_BUSY_BUS) && n_cycles++ < MAX_I2C_WAIT_RX)
+        ;
+    if (n_cycles == MAX_I2C_WAIT_RX) {
+        printf("Error in reading from I2C Bus: Bus is not getting ready after transmit data\n");
+        DL_I2C_resetControllerTransfer(I2C_controller_INST); 
+        return false;
+    }
     
     // **Check if the target address is incorrect
     
@@ -77,23 +88,33 @@ static bool msp_i2c_write(uint8_t const TARGET_ADDRESS) {
 static bool msp_i2c_read(uint8_t const TARGET_ADDRESS) {
 
   
- // Flush any stale data in TX FIFO:
-  DL_I2C_flushControllerRXFIFO(I2C_controller_INST);
-  while (DL_I2C_getControllerStatus(I2C_controller_INST) &
-         DL_I2C_CONTROLLER_STATUS_BUSY_BUS)
-    ;
-  DL_I2C_startControllerTransfer(I2C_controller_INST, TARGET_ADDRESS,
-                                 DL_I2C_CONTROLLER_DIRECTION_RX, controllerRxPackage.len);
+    // Flush any stale data in TX FIFO:
+    DL_I2C_flushControllerRXFIFO(I2C_controller_INST);
+    
+    uint32_t n_cycles = 0;
+    while ((DL_I2C_getControllerStatus(I2C_controller_INST) &
+            DL_I2C_CONTROLLER_STATUS_BUSY_BUS) && n_cycles++ < MAX_I2C_WAIT_RX)
+        ;
+    if (n_cycles == MAX_I2C_WAIT_RX) {
+        printf("Error in reading from I2C Bus: Bus is not getting ready before transmit start\n");
+    }
+
+    DL_I2C_startControllerTransfer(I2C_controller_INST, TARGET_ADDRESS,
+                                    DL_I2C_CONTROLLER_DIRECTION_RX, controllerRxPackage.len);
 
-  while (DL_I2C_getControllerStatus(I2C_controller_INST) &
-         DL_I2C_CONTROLLER_STATUS_BUSY_BUS)
-    ;
+    n_cycles = 0;
+    while ((DL_I2C_getControllerStatus(I2C_controller_INST) &
+            DL_I2C_CONTROLLER_STATUS_BUSY_BUS) && n_cycles++ < MAX_I2C_WAIT_RX)
+        ;
+    if (n_cycles == MAX_I2C_WAIT_RX) {
+        printf("Error in reading from I2C Bus: Bus is not getting ready after transmit start\n");
+    }
+        
+    DL_I2C_enableInterrupt(I2C_controller_INST,
+                            DL_I2C_INTERRUPT_CONTROLLER_RXFIFO_TRIGGER);
     
-  DL_I2C_enableInterrupt(I2C_controller_INST,
-                         DL_I2C_INTERRUPT_CONTROLLER_RXFIFO_TRIGGER);
-  
-  
-  return true;
+    
+    return true;
 }
 
 /**

+ 3 - 3
src/interfaces/i2c_target.c

@@ -35,7 +35,7 @@ void initialize_target_address() {
 void mcu_i2c_handle(I2C_Regs *i2c) {
     uint8_t receivedByte = DL_I2C_receiveTargetData(i2c);
     uint8_t receivedCommand = (receivedByte & 0x0F);
-    uint8_t slot = (receivedByte & 0xF0);
+    uint8_t slot = ((receivedByte & 0xF0) >> 4);
 
 #ifdef DEBUG_TARGET
     printf("[SLAVE] Received Byte: 0x%02X\n", receivedByte);
@@ -52,13 +52,13 @@ void mcu_i2c_handle(I2C_Regs *i2c) {
             return;
         }
 
-        DL_I2C_fillTargetTXFIFO(i2c, &battery_slots[slot].measurement, sizeof(BatteryMeasurement));
+        DL_I2C_fillTargetTXFIFO(i2c, (uint8_t *)&battery_slots[slot].measurement, sizeof(BatteryMeasurement));
 
 #ifdef DEBUG_TARGET
         printf("Battery Measurement Sent to MCU. \n");
 #endif
         printf("");
-        DL_I2C_flushTargetTXFIFO(i2c);
+        //DL_I2C_flushTargetTXFIFO(i2c);
   
     } else if (receivedCommand == CMD_SET_CURRENT) {
         // Read incoming bytes from the Controller: