|
|
@@ -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
|
|
|
+};
|
|
|
+
|