Explorar o código

Control-Loop implementiert:
* BatterySlot-Klasse hat jetzt DAC und PWM-Werte sowie eine Timer-Instanz
* PWM startet jetzt direkt beim Programmstart
* Die main_target ruft automatisch das update und den Kontroll-Loop zum Strom nachführen auf

Heinrich Blatt hai 8 meses
pai
achega
6907789bf2

+ 7 - 6
main_target.c

@@ -3,8 +3,6 @@
 #include "ti_msp_dl_config.h"
 //#include "ti/driverlib/dl_i2c.h"
 #include <stdio.h>
-#include "src/peripherals/adc/adc.h"
-#include "src/peripherals/adc/adc_interface.h"
 #include "src/i2c_comm/mcu_slave_interface.h"
 #include "src/interfaces/i2c_controller_interface.h"
 
@@ -156,7 +154,7 @@ int main(void)
 
 {   
     SYSCFG_DL_init();
-    BatterySlots_Init();
+    battery_slotmgr.init();
     //I2C_scanBus(I2C_controller_INST);
     NVIC_EnableIRQ(I2C_controller_INST_INT_IRQN);
     NVIC_EnableIRQ(I2C_target_INST_INT_IRQN);
@@ -170,9 +168,12 @@ int main(void)
         }
         
         for(uint8_t slot= 0; slot< NUM_SLOTS; slot++){
-            for(uint8_t channel= 0; channel< 2; channel++){
-                updateADCReading_multichannel(slot, channel);
-            }
+
+            // step 1: update the voltage readings
+            battery_slotmgr.read_state(slot);
+
+            // step 2: control loop to adjust the dac / adc values
+            battery_slotmgr.adjust_current(slot);
         }
         
         delay_cycles(DELAY_CYCLE);

+ 1 - 0
main_target.syscfg

@@ -64,6 +64,7 @@ I2C2.sclPinConfig.enableConfig         = true;
 PWM1.$name                      = "PWM_0";
 PWM1.ccIndex                    = [0];
 PWM1.timerCount                 = 320;
+PWM1.timerStartTimer            = true;
 PWM1.peripheral.ccp0Pin.$assign = "PA26";
 PWM1.PWM_CHANNEL_0.$name        = "ti_driverlib_pwm_PWMTimerCC0";
 PWM1.PWM_CHANNEL_0.dutyCycle    = 10;

+ 120 - 1
src/battery_data/battery.c

@@ -1,6 +1,8 @@
 #include "battery.h"
 #include "ti/driverlib/dl_i2c.h"
 #include "ti_msp_dl_config.h"
+#include "src/peripherals/dac/dac.h"
+#include "src/peripherals/adc/adc.h"
 
 // Permissible charge temperature for LiIon battery is 0.0 degree Celsius to 45.0 degree Celsius
 // Correct temp_threshold yet to be analyzed
@@ -8,8 +10,20 @@
 //#define VOLTAGE_THRESHOLD ()
 // for extern -> variable definition
 BatterySlot battery_slots[NUM_SLOTS];
+
+static void set_dac(uint8_t slot, uint16_t value) {
+    battery_slots[slot].dac_value = value;
+    DAC_SingleWrite(slot, value);
+}
+static void set_pwm(uint8_t slot, uint16_t value) {
+    battery_slots[slot].pwm_value = value;
+    DL_TimerG_setCaptureCompareValue(battery_slots[0].timer, value, DL_TIMER_CC_0_INDEX);
+}
+
 /*Initialize battery array and default parameters*/
-void BatterySlots_Init() {
+static void batteryslots_init() {
+
+    battery_slots[0].timer = PWM_0_INST;
 
     for(uint8_t i=0; i< NUM_SLOTS; i++){
 
@@ -17,6 +31,111 @@ void BatterySlots_Init() {
         battery_slots[i].measurement.current = 0;
         battery_slots[i].measurement.temperature = 0;
         battery_slots[i].set_current = 0;
+
+        set_dac(i, 0);
+        set_pwm(i, 0);
+    }
+}
+static void batteryslots_read_state(uint8_t slot) {
+    /*
+     * Strategy:
+     * 1. updateADCReading calls the ADC function that does the control loop for getting the values
+     * 2. the updateADCReading also calls internally the HAL to send the i2c commands,
+     *    construct the configuration byte and calculate the values (voltage, current)
+     * 3. the adc updates the battery slot value directly
+     */
+ 
+     // step 1: read channel 0 (voltage reading of the cell)
+    updateADCReading(slot, 0);
+
+    // step 2: read channel 1 (current reading on charge)
+    updateADCReading(slot, 1);
+}
+
+static void batteryslots_adjust_current(uint8_t slot) {
+    if (battery_slots[slot].set_current > 0) {
+        // positive current -> charge (with DAC)
+
+        if (battery_slots[slot].pwm_value != 0) {
+            // seems like we switched from a charging before
+            // -> disable DAC before getting active
+            set_pwm(slot, 0);
+        }
+
+        if (battery_slots[slot].set_current + BATTERY_CURRENT_THRESHOLD > battery_slots[slot].measurement.current) {
+            // we are outside of the tolerance band
+            // exceeded to the upper limit
+            // -> update dac value, decrease the voltage
+            if (battery_slots[slot].dac_value-1 >= 0) {
+                set_dac(slot, --battery_slots[slot].dac_value);
+            }
+            else {
+                // error case to be implemented:
+                // we want to give more current, but we can't ?!
+                ;
+            }
+        } else if (battery_slots[slot].set_current - BATTERY_CURRENT_THRESHOLD < battery_slots[slot].measurement.current) {
+            // we are outside of the tolerance band
+            // exceeded to the upplowerer limit
+            // -> update dac value, increase the voltage
+            if (battery_slots[slot].dac_value+1 <= MAX_DAC_VALUE) {
+                set_dac(slot, ++battery_slots[slot].dac_value);
+            }
+            else {
+                // error case to be implemented:
+                // we want to give more current, but we can't ?!
+                ;
+            }
+        }
+        // no else statement here: we are ok, since we are in the tolerance measure
+    } else if (battery_slots[slot].set_current < 0) {
+        // negative current -> discharge (with PWM)
+        if (battery_slots[slot].dac_value != 0) {
+            // seems like we switched from a charging before
+            // -> disable DAC before getting active
+            set_dac(slot, 0);
+        }
+
+        if (battery_slots[slot].set_current + BATTERY_CURRENT_THRESHOLD > battery_slots[slot].measurement.current) {
+            // we are outside of the tolerance band
+            // exceeded to the upper limit
+            // -> update pwm value, decrease the voltage
+            
+            // @todo debugging & validation: ensure that this directive works
+            printf("timer count: %d\n", DL_Timer_getTimerCount(battery_slots[0].timer));
+
+            if (battery_slots[slot].pwm_value+1 >= DL_Timer_getTimerCount(battery_slots[0].timer)) {
+                // pwm is inverse to the DAC since dragging more current means more negative
+                set_pwm(slot, ++battery_slots[slot].pwm_value);
+            }
+            else {
+                // error case to be implemented:
+                // we want to give more current, but we can't ?!
+                ;
+            }
+        } else if (battery_slots[slot].set_current - BATTERY_CURRENT_THRESHOLD < battery_slots[slot].measurement.current) {
+            // we are outside of the tolerance band
+            // exceeded to the upplowerer limit
+            // -> update pwm value, increase the voltage
+            if (battery_slots[slot].pwm_value-1 >= 0) {
+                set_dac(slot, --battery_slots[slot].pwm_value);
+            }
+            else {
+                // error case to be implemented:
+                // we want to give more current, but we can't ?!
+                ;
+            }
+        }
+    } else {
+        // we have 0 -> stop charging and discharging
+        set_dac(slot, 0);
+        set_pwm(slot, 0);
     }
 }
 
+BatterySlotManager battery_slotmgr = {
+    .init = batteryslots_init,
+    .read_state = batteryslots_read_state,
+    .adjust_current = batteryslots_adjust_current
+};
+

+ 19 - 17
src/battery_data/battery.h

@@ -3,28 +3,22 @@
 
 #include <stdint.h>
 #include <stdbool.h>
+#include <stdio.h>
+#include "ti/driverlib/dl_timerg.h"
 //define macro to be used by multiple files in the program witout the variable being overwritten
 //for testing
 #define NUM_SLOTS (1)
+
+
 //Battery Tolerance
-#define BATTERY_THRESHOLD (50)
+// how much tolerance do we allow if we charge / discharge before we 
+// trigger the control loop to adjust the value
+#define BATTERY_CURRENT_THRESHOLD (5)
+
 // for i2c communication to know battery health
 #define BOOST_SOV_THRESHOLD_MV (4900)
 #define BOOST_HOV_THRESHOLD_MV (5400)
 #define TEMPERATURE_MAX_C (60)
-// Discharge hysterisis
-#define HYSTERISIS (50)
-
-//Battery states
-typedef enum{
-    STATE_EMPTY= 0x01,
-    STATE_BATTERY_DETECTED= 0x02,
-    STATE_WAITING_FOR_LIMITS= 0x03,
-    STATE_MEASUREMENT_IN_PROGRESS= 0x04,
-    STATE_MEASUREMENT_DONE= 0x04,
-    STATE_OVERHEATING= 0x05,
-
-} BatteryState;
 
 //Battery Discharge Safety Check
 typedef enum{
@@ -44,12 +38,20 @@ typedef struct {
     // for future extension of error states (overtemp etc): add here
     int16_t set_current;
     BatteryMeasurement measurement;
+    uint16_t dac_value;
+    uint16_t pwm_value;
+    GPTIMER_Regs *timer;
 } BatterySlot;
 
 //global battery array declaration: extending visiblity of the variable to multiple source files: variable declaration
 extern BatterySlot battery_slots[NUM_SLOTS];
 
-void BatterySlots_Init();
-void Battery_Discharge_SafetyCheck(uint8_t slot_id);
-void Battery_ReadState(uint8_t slot_id);
+typedef struct {
+    void (*init)();
+    void (*read_state)(uint8_t slot_id);
+    void (*adjust_current)(uint8_t slot_id);
+} BatterySlotManager;
+
+extern BatterySlotManager battery_slotmgr;
+
 #endif

+ 1 - 1
src/peripherals/adc/adc.c

@@ -10,7 +10,7 @@
 static ADC_MeasurementState adc_state = ADC_STATE_CONFIGURE;
 
 
-void updateADCReading_multichannel(uint8_t slot, uint8_t channel) {
+void updateADCReading(uint8_t slot, uint8_t channel) {
   //printf("Slot: %d, Channel: %d\n", slot, channel);
   ADC_Params adc_params= {0}; 
   while (adc_state != ADC_STATE_DONE) {

+ 1 - 1
src/peripherals/adc/adc.h

@@ -14,6 +14,6 @@ typedef enum{
 
 
 
-void updateADCReading_multichannel(uint8_t slot, uint8_t channel); //belongs to battery module
+void updateADCReading(uint8_t slot, uint8_t channel); //belongs to battery module
 
 #endif

+ 2 - 2
src/peripherals/dac/dac.c

@@ -29,8 +29,8 @@ void DAC_UpdateOutput() {
 
 
 bool DAC_SingleWrite(uint8_t slot, uint16_t channel_value) {
-  if(channel_value > 4095){
-    printf("DAC Error: channel_value out of range. Must be between 0 and 4095\n");
+  if(channel_value > MAX_DAC_VALUE){
+    printf("DAC Error: channel_value out of range. Must be between 0 and %d\n", MAX_DAC_VALUE);
     return false;
   }
   controllerTxPackage.len = 3;

+ 1 - 0
src/peripherals/dac/dac.h

@@ -5,6 +5,7 @@
 
 #define DAC_TARGET_ADDRESS (0x60)
 #define DAC_VREF_MV 2048
+#define MAX_DAC_VALUE 4095
 
 bool DAC_SingleWrite(uint8_t slot, uint16_t channel_value);