Browse Source

* Discovery für ADC und DAC implementiert
* Bei fehlender Discovery wird Fehlerflag gesetzt
* Fehlerflag verhindert Ausführung, erlaubt aber noch Auslesen via I2C (Mainloop-condition)
* Bei einem Fehler werden automatisch DAC und PWM resetted (auch nützlich für Übertemperatur-Prüfung)

Heinrich Blatt 8 months ago
parent
commit
cff9c9979e

+ 10 - 53
main_target.c

@@ -11,56 +11,6 @@
 
 
 volatile bool mcu_CommandPending= false;
 volatile bool mcu_CommandPending= false;
 
 
-/*
-Scans all the addresses of the peripherals:
-*/
-/*void I2C_scanBus(I2C_Regs *i2c) {
-    printf("1");
-    // **Step 1: Reset I2C Controller if Busy**
-    if (DL_I2C_getControllerStatus(i2c) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS) {
-        printf("I2C Bus Busy! Resetting I2C Controller...\n");
-        DL_I2C_disableController(i2c);  // Disable I2C
-        delay_cycles(20000);
-        DL_I2C_enableController(i2c);   // Re-enable I2C
-        delay_cycles(20000);
-    }
-    uint32_t i2c_status;
-    // **Step 2: Scan I2C Bus**
-    for (uint8_t addr = 0x08; addr < 0x78; addr++) {  // Valid I2C Address Range
-        printf("Scanning 0x%02X\n", addr);
-        DL_I2C_startControllerTransfer(i2c, addr, DL_I2C_CONTROLLER_DIRECTION_RX, 1);
-        delay_cycles(5000);
-
-        if (addr != 0x60 && addr != 0x68) {
-            continue;
-        }
-
-        i2c_status = DL_I2C_getControllerStatus(i2c);
-        printf("DL_I2C_getControllerStatus(i2c): %d\n", i2c_status);
-        printf("busy?: %d\n", (i2c_status & DL_I2C_CONTROLLER_STATUS_BUSY));
-        printf("error?: %d\n", (i2c_status & DL_I2C_CONTROLLER_STATUS_ERROR));
-        printf("addr_ack?: %d\n", (i2c_status & DL_I2C_CONTROLLER_STATUS_ADDR_ACK));
-        printf("data_ack?: %d\n", (i2c_status & DL_I2C_CONTROLLER_STATUS_DATA_ACK));
-        printf("arb_lost?: %d\n", (i2c_status & DL_I2C_CONTROLLER_STATUS_ARBITRATION_LOST));
-        printf("idle?: %d\n", (i2c_status & DL_I2C_CONTROLLER_STATUS_IDLE));
-        printf("busy_bus?: %d\n", (i2c_status & DL_I2C_CONTROLLER_STATUS_BUSY_BUS));
-        
-        if (!(DL_I2C_getControllerStatus(i2c) & DL_I2C_CONTROLLER_STATUS_ERROR)) {
-            printf("Device found at: 0x%02X\n", addr);
-            DL_I2C_disableController(i2c);
-            DL_I2C_enableController(i2c);
-        }else {
-            // Clear the error by resetting the I2C controller
-            printf("Device not found...\n");
-            DL_I2C_disableController(i2c);
-            DL_I2C_enableController(i2c);
-        }
-    }
-
-    //printf("I2C Scan Complete!\n");
-}
-*/
-
 void I2C_controller_INST_IRQHandler(void) {
 void I2C_controller_INST_IRQHandler(void) {
   // printf("I2C Interrupt Triggered to ADC!\n");
   // printf("I2C Interrupt Triggered to ADC!\n");
   switch (DL_I2C_getPendingInterrupt(I2C_controller_INST)) { 
   switch (DL_I2C_getPendingInterrupt(I2C_controller_INST)) { 
@@ -155,7 +105,6 @@ int main(void)
 {   
 {   
     SYSCFG_DL_init();
     SYSCFG_DL_init();
     battery_slotmgr.init();
     battery_slotmgr.init();
-    //I2C_scanBus(I2C_controller_INST);
     NVIC_EnableIRQ(I2C_controller_INST_INT_IRQN);
     NVIC_EnableIRQ(I2C_controller_INST_INT_IRQN);
     NVIC_EnableIRQ(I2C_target_INST_INT_IRQN);
     NVIC_EnableIRQ(I2C_target_INST_INT_IRQN);
     
     
@@ -172,8 +121,16 @@ int main(void)
             // step 1: update the voltage readings
             // step 1: update the voltage readings
             battery_slotmgr.read_state(slot);
             battery_slotmgr.read_state(slot);
 
 
-            // step 2: control loop to adjust the dac / adc values
-            battery_slotmgr.adjust_current(slot);
+            // step 2: control loop to adjust the dac / adc values,
+            // but only if no error happens
+            // (0x80 is the error flag of the state)
+            if (*battery_slots[i].state & 0x80 == 0) {
+                battery_slotmgr.adjust_current(slot);
+            } else {
+                battery_slotmgr.disable(slot);
+            }
+
+            
         }
         }
         
         
         delay_cycles(DELAY_CYCLE);
         delay_cycles(DELAY_CYCLE);

+ 35 - 4
src/battery_data/battery.c

@@ -3,6 +3,10 @@
 #include "ti_msp_dl_config.h"
 #include "ti_msp_dl_config.h"
 #include "src/peripherals/dac/dac.h"
 #include "src/peripherals/dac/dac.h"
 #include "src/peripherals/adc/adc.h"
 #include "src/peripherals/adc/adc.h"
+#include "src/peripherals/i2c_controller_interface.h"
+// we need the itnerface for the ADC_TARGET_BASE_ADDRESS constant
+// refactor this somewhen to a general constants file
+#include "src/adc/adc_interface.h"
 
 
 // Permissible charge temperature for LiIon battery is 0.0 degree Celsius to 45.0 degree Celsius
 // Permissible charge temperature for LiIon battery is 0.0 degree Celsius to 45.0 degree Celsius
 // Correct temp_threshold yet to be analyzed
 // Correct temp_threshold yet to be analyzed
@@ -19,10 +23,19 @@ static void set_pwm(uint8_t slot, uint16_t value) {
     battery_slots[slot].pwm_value = value;
     battery_slots[slot].pwm_value = value;
     DL_TimerG_setCaptureCompareValue(battery_slots[0].timer, value, DL_TIMER_CC_0_INDEX);
     DL_TimerG_setCaptureCompareValue(battery_slots[0].timer, value, DL_TIMER_CC_0_INDEX);
 }
 }
+static void batteryslots_disable(uint8_t slot) {
+    if (battery_slots[slot].dac_value != 0) {
+        set_dac(slot, 0);
+    }
+    if (battery_slots[slot].pwm_value != 0) {
+        set_pwm(slot, 0);
+    }
+}
 
 
 /*Initialize battery array and default parameters*/
 /*Initialize battery array and default parameters*/
 static void batteryslots_init() {
 static void batteryslots_init() {
 
 
+    // initialize data structures
     battery_slots[0].timer = PWM_0_INST;
     battery_slots[0].timer = PWM_0_INST;
 
 
     for(uint8_t i=0; i< NUM_SLOTS; i++){
     for(uint8_t i=0; i< NUM_SLOTS; i++){
@@ -38,9 +51,27 @@ static void batteryslots_init() {
         battery_slots[i].measurement.temperature = 0;
         battery_slots[i].measurement.temperature = 0;
         battery_slots[i].set_current = 0;
         battery_slots[i].set_current = 0;
 
 
-        set_dac(i, 0);
         set_pwm(i, 0);
         set_pwm(i, 0);
     }
     }
+
+    if (!i2c_discover(DAC_TARGET_ADDRESS)) {
+        // there is only 1 DAC for all 4 slots
+        for(uint8_t i=0; i< NUM_SLOTS; i++) {
+            *battery_slots[i].state = SLOT_ERR_NO_DAC;
+        }
+        // Error state - no I2C on bus - we cannot continue.
+        return
+    }
+
+    for(uint8_t i=0; i< NUM_SLOTS; i++){
+
+        set_dac(i, 0);
+
+        if (!i2c_discover(ADC_TARGET_BASE_ADDRESS+i)) {
+            // this automatically translates to the other addresses
+            *battery_slots[i].state = SLOT_ERR_NO_ADC1+i;
+        }
+    }
 }
 }
 static void batteryslots_read_state(uint8_t slot) {
 static void batteryslots_read_state(uint8_t slot) {
     /*
     /*
@@ -130,14 +161,14 @@ static void batteryslots_adjust_current(uint8_t slot) {
         }
         }
     } else {
     } else {
         // we have 0 -> stop charging and discharging
         // we have 0 -> stop charging and discharging
-        set_dac(slot, 0);
-        set_pwm(slot, 0);
+        batteryslots_disable(slot);
     }
     }
 }
 }
 
 
 BatterySlotManager battery_slotmgr = {
 BatterySlotManager battery_slotmgr = {
     .init = batteryslots_init,
     .init = batteryslots_init,
     .read_state = batteryslots_read_state,
     .read_state = batteryslots_read_state,
-    .adjust_current = batteryslots_adjust_current
+    .adjust_current = batteryslots_adjust_current,
+    .disable = batteryslots_disable
 };
 };
 
 

+ 9 - 5
src/battery_data/battery.h

@@ -28,7 +28,7 @@ typedef enum{
     SLOT_STATE_HOV= 0x02,
     SLOT_STATE_HOV= 0x02,
 
 
     SLOT_WARN_OVERTEMPERATURE = 0x03,
     SLOT_WARN_OVERTEMPERATURE = 0x03,
-    SLOT_ERR_OVERTEMPERATURE= 0x04,
+    SLOT_ERR_OVERTEMPERATURE= (0x04 | 0x80), // first bit indicates complete error
 
 
     // Control error states
     // Control error states
     SLOT_WARN_LOWER_DAC_NOT_POSSIBLE=0x10,
     SLOT_WARN_LOWER_DAC_NOT_POSSIBLE=0x10,
@@ -38,10 +38,13 @@ typedef enum{
     SLOT_WARN_HIGHER_PWM_NOT_POSSIBLE=0x14,
     SLOT_WARN_HIGHER_PWM_NOT_POSSIBLE=0x14,
 
 
     // I2C Slave Error states
     // I2C Slave Error states
-    SLOT_ERR_NO_ADC = 0x20,
-    SLOT_ERR_NO_DAC = 0x21,
-    SLOT_ERR_CONFIGBYTE = 0x22,
-    SLOT_ERR_DAC_WRITE_FAILED=0x23,
+    SLOT_ERR_NO_DAC =  (0x20 | 0x80),
+    SLOT_ERR_NO_ADC1 = (0x21 | 0x80),
+    SLOT_ERR_NO_ADC2 = (0x22 | 0x80),
+    SLOT_ERR_NO_ADC3 = (0x23 | 0x80),
+    SLOT_ERR_NO_ADC4 = (0x24 | 0x80),
+    SLOT_ERR_CONFIGBYTE = (0x25 | 0x80),
+    SLOT_ERR_DAC_WRITE_FAILED= (0x26 | 0x80)
 } SlotState;
 } SlotState;
 
 
 typedef struct{
 typedef struct{
@@ -68,6 +71,7 @@ typedef struct {
     void (*init)();
     void (*init)();
     void (*read_state)(uint8_t slot_id);
     void (*read_state)(uint8_t slot_id);
     void (*adjust_current)(uint8_t slot_id);
     void (*adjust_current)(uint8_t slot_id);
+    void (*disable)(uint8_t slot_id);
 } BatterySlotManager;
 } BatterySlotManager;
 
 
 extern BatterySlotManager battery_slotmgr;
 extern BatterySlotManager battery_slotmgr;

+ 2 - 0
src/interfaces/i2c_controller_interface.h

@@ -46,6 +46,8 @@ typedef struct {
 } I2CTxPackage;
 } I2CTxPackage;
 extern I2CTxPackage controllerTxPackage;
 extern I2CTxPackage controllerTxPackage;
 
 
+bool i2c_discover(uint8_t i2c_addr);
+
 /*
 /*
 * Since C does not allows to add functions in typedef struct, however a function pointer can be included in Structure in C. This interface provides a standard features of i2c_hal
 * Since C does not allows to add functions in typedef struct, however a function pointer can be included in Structure in C. This interface provides a standard features of i2c_hal
 */
 */

+ 19 - 7
src/interfaces/i2c_hal.c

@@ -8,13 +8,6 @@
 #include "ti_msp_dl_config.h"
 #include "ti_msp_dl_config.h"
 #include <stdio.h>
 #include <stdio.h>
 
 
-volatile bool gRxComplete;
-volatile bool gTxComplete;
-uint8_t gTxPacket[I2C_TX_MAX_PACKET_SIZE];
-uint8_t gRxPacket[I2C_RX_MAX_PACKET_SIZE];
-uint8_t gTxADClen, gTxADCcount;
-uint8_t gRxADClen, gRxADCcount;
-
 /*
 /*
 static function is for implementing Data Hiding, access to the static function
 static function is for implementing Data Hiding, access to the static function
 is restricted to the file where they are declared const keyword for
 is restricted to the file where they are declared const keyword for
@@ -99,6 +92,25 @@ static bool msp_i2c_read(uint8_t const TARGET_ADDRESS) {
   return true;
   return true;
 }
 }
 
 
+/**
+ * this function discovers on the i2c bus the devices from the address
+ * to ensure all relevant bus participants are present
+ */
+ bool i2c_discover(uint8_t i2c_addr) {
+  if (DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS) {
+      DL_I2C_disableController(I2C_controller_INST);  // Disable I2C
+      DL_I2C_enableController(I2C_controller_INST);   // Re-enable I2C
+  }
+  printf("Scanning 0x%02X\n", i2c_addr);
+  DL_I2C_startControllerTransfer(I2C_controller_INST, i2c_addr, DL_I2C_CONTROLLER_DIRECTION_RX, 1);
+  delay_cycles(5000);
+  i2c_status = DL_I2C_getControllerStatus(I2C_controller_INST);
+  bool found = !(DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_ERROR);
+  DL_I2C_disableController(I2C_controller_INST);
+  DL_I2C_enableController(I2C_controller_INST);
+  return found
+}
+
 I2C_Interface i2c_hal = {
 I2C_Interface i2c_hal = {
     .write = msp_i2c_write,
     .write = msp_i2c_write,
     .read = msp_i2c_read,
     .read = msp_i2c_read,