Browse Source

Pi Logic decoupled from IRQ

namrota ghosh 8 months ago
parent
commit
26caf1e4b2
9 changed files with 381 additions and 263 deletions
  1. 9 9
      src/adc.c
  2. 221 123
      src/cc_cv_charging.c
  3. 2 1
      src/cc_cv_charging.h
  4. 9 8
      src/dac.c
  5. 1 1
      src/hal/i2c_hal.c
  6. 24 109
      src/i2c_controller.c
  7. 102 2
      src/i2c_target.c
  8. 11 8
      src/i2c_target.h
  9. 2 2
      src/multiplexer.c

+ 9 - 9
src/adc.c

@@ -114,7 +114,7 @@ bool ADC_CheckReadyBit(uint8_t slot_id, ADC_PARAMS params) {
   // Buffer for ADC data (MSB, LSB, Config Byte)
   uint8_t adc_data[3];
   uint8_t adc_address = ADC_TARGET_BASE_ADDRESS + slot_id;
-  printf("Reading ADC Data from MCP3428 for channel: %u\n", params.channel);
+  //printf("Reading ADC Data from MCP3428 for channel: %u\n", params.channel);
   gRxADClen = 3;
   gRxADCcount = 0;
   gRxComplete = false;
@@ -135,8 +135,8 @@ bool ADC_CheckReadyBit(uint8_t slot_id, ADC_PARAMS params) {
 
   // Ready bit is bit 7
   bool ready = (config_adc_byte & 0x80) == 0;
-  printf("Slot: %d | Config Byte: 0x%02X | READY Bit: %d\n", slot_id,
-         config_adc_byte, ready);
+  //printf("Slot: %d | Config Byte: 0x%02X | READY Bit: %d\n", slot_id,
+  //       config_adc_byte, ready);
   return ready;
 }
 
@@ -222,7 +222,7 @@ int16_t ADC_ReadData(uint8_t slot_id, ADC_PARAMS params) {
   uint8_t msb = gRxPacket[0];
   uint8_t lsb = gRxPacket[1];
   uint8_t config_adc_byte = gRxPacket[2];
-  printf("MSB: 0x%02X, LSB: 0x%02X\n", msb, lsb);
+  //printf("MSB: 0x%02X, LSB: 0x%02X\n", msb, lsb);
   uint8_t gain_setting = (config_adc_byte & 0x03);
   uint8_t gain_multiplier = (1 << gain_setting); // Gain values: 1, 2, 4, 8
 
@@ -239,7 +239,7 @@ int16_t ADC_ReadData(uint8_t slot_id, ADC_PARAMS params) {
     if (raw_adc > 2047)
       raw_adc -= 4096;
   }
-  printf("Raw ADC Value: 0x%0X (%d)\n", raw_adc, raw_adc);
+  //printf("Raw ADC Value: 0x%0X (%d)\n", raw_adc, raw_adc);
   return raw_adc;
 }
 
@@ -294,7 +294,7 @@ void Battery_UpdateADCReading(uint8_t slot, uint8_t channel) {
 
     case ADC_STATE_CONFIGURE:
       adc_params.channel = channel;
-      printf("Channel: %d\n", adc_params.channel);
+      //printf("Channel: %d\n", adc_params.channel);
       adc_params.resolution = 12;
       adc_params.continuous = 0;
       adc_params.gain = 1;
@@ -314,7 +314,7 @@ void Battery_UpdateADCReading(uint8_t slot, uint8_t channel) {
         int16_t raw_adc_voltage = ADC_ReadData(slot, adc_params);
         batteries[slot].voltage =
             ADC_ConvertToVoltage(raw_adc_voltage, adc_params); // Double check voltage dividers later on to get the right value (possibly instead of 2)
-        printf("Battery voltage for slot %d is %u mV.\n", slot,
+        printf("[ADC] Battery voltage for slot %d is %u mV.\n", slot,
                batteries[slot].voltage);
         adc_state = ADC_STATE_DONE;
 
@@ -323,7 +323,7 @@ void Battery_UpdateADCReading(uint8_t slot, uint8_t channel) {
         int16_t raw_adc_current = ADC_ReadData(slot, adc_params);
         batteries[slot].current =
             ADC_ConvertToCurrent(raw_adc_current, adc_params);
-        printf("Battery current for slot %d is %u mA.\n", slot,
+        printf("[ADC] Battery current for slot %d is %u mA.\n", slot,
                batteries[slot].current);
 
         adc_state = ADC_STATE_DONE;
@@ -350,7 +350,7 @@ void Battery_ReadState(uint8_t slot_id) {
     batteries[slot_id].state = STATE_EMPTY;
   } else if (voltage_mv >= 500 && voltage_mv < 3000) { //TODO: change the voltage_mv to min_voltage
     batteries[slot_id].state = STATE_BATTERY_DETECTED;
-  } else if (voltage_mv >= min_voltage && voltage_mv < max_voltage) {
+  } else if (voltage_mv >= 3000 && voltage_mv < 4200) {
     batteries[slot_id].state = STATE_MEASUREMENT_IN_PROGRESS;
   }
   // once MCU is done reading ADC:

+ 221 - 123
src/cc_cv_charging.c

@@ -1,162 +1,260 @@
 #include "cc_cv_charging.h"
+#include "adc.h"
 #include "battery.h"
 #include "dac.h"
-#include "adc.h"
 #include "ti/devices/msp/m0p/mspm0g350x.h"
 #include "ti/driverlib/dl_gpio.h"
+#include "ti_msp_dl_config.h"
 #include <stdio.h>
 
-//#define BATTERY_CAPACITY_MAH (2000)
+// #define BATTERY_CAPACITY_MAH (2000)
 #define MAX_VOLTAGE_MV (4200)
 #define MIN_VOLTAGE_MV (3000)
 #define CC_CURRENT_LIMIT_MA (500)
-#define CUTOFF_CURRENT_MA (50)
+// Cut off current has been set for CC-CV charging test simulation with DC Power
+// Supplies
+#define CUTOFF_CURRENT_MA (240)
 #define MAX_CYCLES (2)
 #define CONSTANT_VALUE (1)
 #define SHUNT_RESISTOR (0.1)
 
-//********** Not used **************************
-// if the battery is deeply discharged then 50mA of trickle charge is given for a set timer
-//#define TRICKLE_CHARGE_CURRENT_MA (50)
-//#define TRICKLE_CHARGE_VOLTAGE_MV (2100)
-//#define TRICKLE_CHARGE_TIMEOUT_MS (5000) //5 mseconds
+// Pre Charge
+#define PRE_CHARGE_CURRENT_MA (BATTERY_CAPACITY_MAH / 10)
+//static ChargingState charging_state = STATE_PRE_CHARGE;
+static ChargingState charging_state = STATE_IDLE;
+static uint16_t cycle_count = 0;
 
+// Functions for Charging and Discharging State
 
-//Pre Charge
+void CC_CV_UpdateChargingState(uint8_t slot_id) {
+  uint16_t batt_voltage = batteries[slot_id].voltage;
+  int16_t batt_current = batteries[slot_id].current;
+  // Flag for CV charging, the charging mode flips back to CC mode
+  static bool cv_charging_started = false;
 
-//#define PRE_CHARGE_CURRENT_MA (BATTERY_CAPACITY_MAH/ 10)
-static ChargingState charging_state= STATE_PRE_CHARGE;
-static uint16_t cycle_count= 0;
-static uint32_t pre_charge_start_time= 0;
+  // Handling condition for STATE_ERROR: When the battery voltage exceeds the
+  // MAXIMUM_VOLTAGE regardless of the current state
+  /*if (batt_voltage > MAX_VOLTAGE_MV) {
+    charging_state = STATE_ERROR;
+    return;
+  }*/
 
-//Functions for Charging and Discharging
+  if (batt_voltage > batteries[slot_id].max_voltage) {
+    charging_state = STATE_ERROR;
+  }
 
-void CC_CV_UpdateChargingState(uint8_t slot_id){
-    uint16_t batt_voltage= batteries[slot_id].voltage;
-    int16_t batt_current= batteries[slot_id].current;
-    if(batt_voltage < MIN_VOLTAGE_MV){
-        charging_state= STATE_PRE_CHARGE;
-    }
+  // if state is IDLE or ERROR then RETURN
+  if (charging_state == STATE_IDLE || charging_state == STATE_ERROR) {
+    return;
+  }
 
-    else if(batt_voltage >= MIN_VOLTAGE_MV && batt_voltage < MAX_VOLTAGE_MV - BATTERY_THRESHOLD){
-        charging_state= STATE_CC_CHARGING;
-    }
+  // 1. Deeply discharged: Pre-charge state
+  /*if ((batt_voltage < MIN_VOLTAGE_MV)) {
+    charging_state = STATE_PRE_CHARGE;
+    cv_charging_started = false;
+  }*/
+  if ((batt_voltage < batteries[slot_id].min_voltage)) {
+    charging_state = STATE_PRE_CHARGE;
+    cv_charging_started = false;
+  }
+  // 2. Fast Charging Condition: CC Charging: cv_charging_started condition
+  // added to avoid toggling back to CC after CV state is reached
+  /*else if (!cv_charging_started && (batt_voltage >= MIN_VOLTAGE_MV) &&
+           (batt_voltage < MAX_VOLTAGE_MV - BATTERY_THRESHOLD)) {
+    charging_state = STATE_CC_CHARGING;
+  }*/
 
-    else if(batt_voltage >= MAX_VOLTAGE_MV - BATTERY_THRESHOLD){
-        charging_state= STATE_CV_CHARGING;
-    }
+  else if (!cv_charging_started &&
+           (batt_voltage >= batteries[slot_id].min_voltage) &&
+           (batt_voltage <
+            batteries[slot_id].max_voltage - BATTERY_THRESHOLD)) {
+    charging_state = STATE_CC_CHARGING;
+  }
+  // 3. CV Charging condition: Changing the cv_charging_state to True, once the
+  // CV mode is reached
+  /*else if (batt_voltage >= MAX_VOLTAGE_MV - BATTERY_THRESHOLD) {
+    charging_state = STATE_CV_CHARGING;
+    cv_charging_started = true;
+  }*/
 
-    else if(charging_state == STATE_CV_CHARGING && batt_current <= CUTOFF_CURRENT_MA + BATTERY_THRESHOLD){
+  else if (batt_voltage >= batteries[slot_id].max_voltage - BATTERY_THRESHOLD) {
+    charging_state = STATE_CV_CHARGING;
+    cv_charging_started = true;
+  }
 
-        if(cycle_count < MAX_CYCLES){
-            charging_state= STATE_DISCHARGING;
-        }
-        else{
-            charging_state = STATE_FINAL_DISCHARGE;
-        }
-        
-    }
+  // 4. Cut-off check inside CV
+  /*else if ((charging_state == STATE_CV_CHARGING) &&
+           (batt_current <= CUTOFF_CURRENT_MA + BATTERY_THRESHOLD)) {
 
-    else if(charging_state == STATE_DISCHARGING && batt_voltage <= MIN_VOLTAGE_MV + BATTERY_THRESHOLD) {
-        charging_state= STATE_CC_CHARGING;      
+    if (cycle_count < MAX_CYCLES) {
+      charging_state = STATE_DISCHARGING;
+      cycle_count++;
+    } else {
+      charging_state = STATE_FINAL_DISCHARGE;
     }
-  
-    else{
-        charging_state= STATE_ERROR;
+  }*/
+
+  else if ((charging_state == STATE_CV_CHARGING) &&
+           (batt_current <=
+            batteries[slot_id].cut_off_current + BATTERY_THRESHOLD)) {
+    if (cycle_count < MAX_CYCLES) {
+      charging_state = STATE_DISCHARGING;
+      cycle_count++;
+    } else {
+      charging_state = STATE_FINAL_DISCHARGE;
     }
+  }
+
+  // 5. State Discharging condition
+  /*else if (charging_state == STATE_DISCHARGING &&
+           batt_voltage <= MIN_VOLTAGE_MV + BATTERY_THRESHOLD) {
+    charging_state = STATE_CC_CHARGING;
+    cv_charging_started = false;
+  }*/
+
+  else if (charging_state == STATE_DISCHARGING &&
+           batt_voltage <= batteries[slot_id].min_voltage + BATTERY_THRESHOLD) {
+    charging_state = STATE_CC_CHARGING;
+    cv_charging_started = false;
+  }
+
+  // 6. Hold previous state if none of the condition matches (Previously,
+  // CV_STATE was jumping directly to STATE_ERROR in else statement, to handle
+  // the condition better, else condition is being changed).
+  else {
+    printf("[CC-CV] Current state: Voltage= %d mV, Current= %d mA\n",
+           batt_voltage, batt_current);
+  }
 }
 
 /*
 Function for Battery Charging and Discharging:
-Trickle Charge: Only used when the battery voltage < ~2.1 V. 
-    - In this state, the batteries internal protection may have been previously disconnected.
-Pre Charge: Once the battery is in discharged state, pre-charging begins.
-    - Starts charging safely with a typically low current C/10
-Constant Current: Continues until the battery voltage has reached the "full" or floating voltage level
-Constant Voltage: CV volatge starts once the maximum voltage threshold is obtained
+** Pre Charge: Once the battery is in discharged state, pre-charging
+begins. Starts charging safely with a typically low current C/10
+** Constant Current: Continues until the battery voltage has reached the "full"
+or floating voltage level
+** Constant Voltage: CV voltage starts once the maximum
+voltage threshold is obtained.
 */
 
-void CC_CV_ControlCharging(uint8_t slot_id){
-    //Calling function to get all the conditional states
-    CC_CV_UpdateChargingState(slot_id);
-    uint16_t batt_voltage= batteries[slot_id].voltage;
-    int16_t batt_current= batteries[slot_id].current;
-    uint16_t batt_cutoff_current= batteries[slot_id].cut_off_current;
-    uint16_t charge_current_mA= (batteries[slot_id].capacitance * batteries[slot_id].charge_fraction)/100;
-    static uint16_t dac_channel_VoutA= 2000;
-
-    switch(charging_state){
-        case STATE_PRE_CHARGE:
-            DL_GPIO_setPins(GPIO_Battery_Charging_PORT, GPIO_Battery_Charging_PIN_PB4_PIN);
-            uint16_t pre_charge_current_limit_ma = charge_current_mA/10;
-            //DAC_fastWrite(pre_charge_current_limit_ma);
-            //DAC_fastWrite(dac_channel_VoutA);
-            DAC_SingleWrite(dac_channel_VoutA);
-            //DAC_UpdateOutput();
-            if(true){
-                printf("[CC-CV] Pre Charging: Slot %d at %d mA.\n", slot_id, dac_channel_VoutA);
-            }
-            
-            break;
-        
-        case STATE_CC_CHARGING:
-            DL_GPIO_setPins(GPIO_Battery_Charging_PORT, GPIO_Battery_Charging_PIN_PB4_PIN);
-            if(batt_voltage>= 3700) //3.7 Volts of Fast Charging
-            {
-                printf("[CC-CV] CC Charging Completed!\n");
-                break;
-            }
-            uint16_t target_current_mA= CC_CURRENT_LIMIT_MA;
-            //Convert to voltage using Shunt resistor
-            uint16_t voltage_mV= target_current_mA * SHUNT_RESISTOR * 1000;
-
-            DAC_SingleWrite(charge_current_mA);
-            printf("[CC-CV] CC Charging: Slot %d at %d mA.\n", slot_id, CC_CURRENT_LIMIT_MA);
-            break;
-        
-        case STATE_CV_CHARGING:
-            DL_GPIO_setPins(GPIO_Battery_Charging_PORT, GPIO_Battery_Charging_PIN_PB4_PIN);
-            if(batt_current >= batt_cutoff_current+BATTERY_THRESHOLD){
-                dac_channel_VoutA= (dac_channel_VoutA - 50);
-                printf("DAC Channel Value: %d, Battery Current:%d \n", dac_channel_VoutA, batt_current);
-            }
-            else{
-                dac_channel_VoutA= 0;
-                charging_state= STATE_FINAL_DISCHARGE;
-            }
-            DAC_SingleWrite(dac_channel_VoutA);
-            printf("[CC-CV] CV Charging: Slot %d at %d mA.\n", slot_id, dac_channel_VoutA);
-            break;
-        
-        case STATE_DISCHARGING:
-            DL_GPIO_clearPins(GPIO_Battery_Charging_PORT, GPIO_Battery_Charging_PIN_PB4_PIN);
-            DL_GPIO_setPins(GPIO_Battery_Discharging_PORT, GPIO_Battery_Discharging_PIN_PB12_PIN);
-            //still unsure about the value for channel VoutA:
-            DAC_SingleWrite(batt_voltage);
-            printf("[CC-CV] Discharging: Slot %d at %d mA.\n", slot_id, batt_voltage);
-            break;
-
-        case STATE_FINAL_DISCHARGE:
-            DL_GPIO_clearPins(GPIO_Battery_Charging_PORT, GPIO_Battery_Charging_PIN_PB4_PIN);
-            DL_GPIO_clearPins(GPIO_Battery_Discharging_PORT, GPIO_Battery_Discharging_PIN_PB12_PIN);
-            printf("[CC-CV] Final Discharge: Slot %d..\n", slot_id);
-            DAC_SingleWrite(0);
-            
-        
-        case STATE_ERROR:
-            DL_GPIO_clearPins(GPIO_Battery_Charging_PORT, GPIO_Battery_Charging_PIN_PB4_PIN);
-            DL_GPIO_clearPins(GPIO_Battery_Discharging_PORT, GPIO_Battery_Discharging_PIN_PB12_PIN);
-            printf("[CC-CV] Error: Slot %d.\n", slot_id);
-            
-
-        default:
-            break;
-        }
+void CC_CV_ControlCharging(uint8_t slot_id) {
+  // Calling function to get all the conditional states
+  CC_CV_UpdateChargingState(slot_id);
+  uint16_t batt_voltage = batteries[slot_id].voltage;
+  int16_t batt_current = batteries[slot_id].current;
+  uint16_t batt_cutoff_current = batteries[slot_id].cut_off_current;
+  uint16_t charge_current_mA =(batteries[slot_id].capacitance * batteries[slot_id].charge_fraction) / 100;
+  uint16_t charge_current_limit_ma = charge_current_mA / 10;
+
+  //  DAC channel value:
+  //static uint16_t dac_channel_VoutA = 1000;
+  // Adding a variable to check the stepness in the voltage drop in CV charging
+  // mode:
+  static uint16_t last_voltage = 0;
+
+  switch (charging_state) {
+
+  // PRE CHARGE STATE: Battery Voltage is lesser than 3000 mVolts
+  case STATE_PRE_CHARGE:
+    DL_GPIO_setPins(GPIO_Battery_Charging_PORT,
+                    GPIO_Battery_Charging_PIN_PB4_PIN);
     
-}
+    //DAC_SingleWrite(dac_channel_VoutA);
+    DAC_SingleWrite(charge_current_limit_ma);
+    if (true) {
+      //printf("PRE CHARGING: Slot %d at %d mA.\n", slot_id, );
+      printf("PRE CHARGING: Slot %d at %d mA.\n", slot_id, charge_current_limit_ma);
+    }
+    break;
 
+  // CC CHARGING STATE: Keeps on checking the condition until battery voltage
+  // reaches to (MAXIMUM_VOLTAGE-BATTERY_THRESHOLD)= 4150 mVolts
+  case STATE_CC_CHARGING:
+    DL_GPIO_setPins(GPIO_Battery_Charging_PORT,
+                    GPIO_Battery_Charging_PIN_PB4_PIN);
+    //DAC_SingleWrite(dac_channel_VoutA);
+    DAC_SingleWrite(charge_current_limit_ma);
+    printf("CC CHARGING: Slot %d, Current: %d mA, Voltage: %d mV.\n", slot_id,
+           batt_current, batt_voltage);
+    break;
 
+  // CV CHARGING STATE: Keeps on checking the condition until battery current
+  // decreases till it exceeds (CUTOFF_CURRENT_MA + BATTERY_THRESHOLD)= 290 mAs
+  case STATE_CV_CHARGING:
+    DL_GPIO_setPins(GPIO_Battery_Charging_PORT,
+                    GPIO_Battery_Charging_PIN_PB4_PIN);
+    // battery cut off current usually we get from Pi
+    //if (batt_current >= CUTOFF_CURRENT_MA + BATTERY_THRESHOLD) {
+    if(batt_current >= batteries[slot_id].cut_off_current + BATTERY_THRESHOLD){
+      // Detect steep voltage drop:
+      if (last_voltage != 0 && (last_voltage - batt_voltage) > 100) {
+        printf("!!! CV CHARGING: Voltage dropped too fast: %d -> %d mV. DAC "
+               "value: %d\n",
+               last_voltage, batt_voltage, charge_current_limit_ma);
+      }
+      // Clamping the DAC to avoid going too low too fast, causing the battery
+      // voltage to dip
+      //if (dac_channel_VoutA > 825) {
+      //  dac_channel_VoutA -= 25;
+      //} else {
+      //  dac_channel_VoutA = 825;
+      //}
 
+      printf("CV CHARGING: Slot: %d, DAC_Value: %d, Battery Voltage: %d, "
+             "Battery Current:%d \n",
+             slot_id, charge_current_limit_ma, batt_voltage, batt_current);
+    } else {
+      //dac_channel_VoutA = 0;
+      charging_state = STATE_FINAL_DISCHARGE;
+    }
+    last_voltage = batt_voltage;
+    //DAC_SingleWrite(dac_channel_VoutA);
+    DAC_SingleWrite(charge_current_limit_ma);
+    break;
+
+  case STATE_DISCHARGING:
+    DL_GPIO_clearPins(GPIO_Battery_Charging_PORT,
+                      GPIO_Battery_Charging_PIN_PB4_PIN);
+    DL_GPIO_setPins(GPIO_Battery_Discharging_PORT,
+                    GPIO_Battery_Discharging_PIN_PB12_PIN);
+    // TODO: DAC channel value need to recheck
+    DAC_SingleWrite(charge_current_limit_ma);
+    printf("DISCHARGING: Slot %d at %d mA.\n", slot_id, batt_voltage);
+    DL_GPIO_clearPins(GPIO_Battery_Discharging_PORT,
+                      GPIO_Battery_Discharging_PIN_PB12_PIN);
+    if (batt_voltage < MIN_VOLTAGE_MV) {
+      charging_state = STATE_PRE_CHARGE;
+    }
+    break;
 
+  case STATE_FINAL_DISCHARGE:
+    DL_GPIO_clearPins(GPIO_Battery_Charging_PORT,
+                      GPIO_Battery_Charging_PIN_PB4_PIN);
+    DL_GPIO_clearPins(GPIO_Battery_Discharging_PORT,
+                      GPIO_Battery_Discharging_PIN_PB12_PIN);
+    printf("FINAL DISCHARGE: Slot %d..\n", slot_id);
+    DAC_SingleWrite(0);
+    // Added a new state in the Final Discharge so that the state transition
+    // does not gets stuck in a loop.
+    charging_state = STATE_IDLE;
+    break;
 
+  case STATE_ERROR:
+    DL_GPIO_clearPins(GPIO_Battery_Charging_PORT,
+                      GPIO_Battery_Charging_PIN_PB4_PIN);
+    DL_GPIO_clearPins(GPIO_Battery_Discharging_PORT,
+                      GPIO_Battery_Discharging_PIN_PB12_PIN);
+    printf("ERROR: Slot %d.\n", slot_id);
+    break;
 
+  case STATE_IDLE:
+    DL_GPIO_clearPins(GPIO_Battery_Charging_PORT,
+                      GPIO_Battery_Charging_PIN_PB4_PIN);
+    DL_GPIO_clearPins(GPIO_Battery_Discharging_PORT,
+                      GPIO_Battery_Discharging_PIN_PB12_PIN);
+    break;
+
+  default:
+    break;
+  }
+}

+ 2 - 1
src/cc_cv_charging.h

@@ -11,7 +11,8 @@ typedef enum{
     STATE_CV_CHARGING,
     STATE_DISCHARGING,
     STATE_FINAL_DISCHARGE,
-    STATE_ERROR
+    STATE_ERROR,
+    STATE_IDLE,
 }ChargingState;
 
 

+ 9 - 8
src/dac.c

@@ -23,7 +23,7 @@ void DAC_UpdateOutput() {
 
   DL_I2C_fillControllerTXFIFO(I2C_controller_INST, &general_call_command, 1);
 
-  printf("DAC Outputs Updated via General Call Software Update!\n");
+  //printf("DAC Outputs Updated via General Call Software Update!\n");
 }
 
 /**Function for FAST write command, sending values over I2c to every channel of
@@ -59,9 +59,9 @@ bool DAC_fastWrite(uint16_t channel_a_value) {
   }
 
   i2c_hal.write(DAC_TARGET_BASE_ADDRESS, (uint8_t *)&output_buffer, 8);
-  printf("Output Buffer[2]: 0x%02X, Output Buffer[3]: 0x%02X\n",
-         output_buffer[2], output_buffer[3]);
-  printf("DAC Fast write Successful!\n");
+  //printf("Output Buffer[2]: 0x%02X, Output Buffer[3]: 0x%02X\n",
+  //      output_buffer[2], output_buffer[3]);
+  //printf("DAC Fast write Successful!\n");
   DAC_UpdateOutput();
   return true;
 }
@@ -113,7 +113,7 @@ uint8_t DAC_ReadCurrentAddress() {
   current_address = DL_I2C_receiveControllerData(I2C_controller_INST);
 
   // Debug
-  printf("Current DAC I2C Address: 0x%02X\n", current_address);
+  //printf("Current DAC I2C Address: 0x%02X\n", current_address);
   return current_address;
 }
 
@@ -142,10 +142,10 @@ bool DAC_SingleWrite(uint16_t channel_value) {
 
 
   // Log data being sent
-  printf("Sending to DAC: 0x%02X 0x%02X 0x%02X\n",
+  /*printf("Sending to DAC: 0x%02X 0x%02X 0x%02X\n",
            output_buffer_SingleWrite[0],
            output_buffer_SingleWrite[1],
-           output_buffer_SingleWrite[2]);
+           output_buffer_SingleWrite[2]);*/
 
   // Write data to DAC
   if (!i2c_hal.write(DAC_TARGET_BASE_ADDRESS, output_buffer_SingleWrite, data_length)) {
@@ -155,7 +155,8 @@ bool DAC_SingleWrite(uint16_t channel_value) {
 
   DAC_UpdateOutput();
 
-  printf("Output_Buffer_1: 0x%02X, Output_Buffer_2: 0x%02X\n", output_buffer_SingleWrite[1], output_buffer_SingleWrite[2]);
+  //printf("Output_Buffer_1: 0x%02X, Output_Buffer_2: 0x%02X\n", output_buffer_SingleWrite[1], output_buffer_SingleWrite[2]);
 
   return true;
+
 }

+ 1 - 1
src/hal/i2c_hal.c

@@ -54,7 +54,7 @@ static bool msp_i2c_write(uint8_t const TARGET_ADDRESS,
   }
   
   // Debug for I2C WRITE:
-  printf("HAL Write: Address=0x%02X, Data Length=%d\n", TARGET_ADDRESS, Data_length);
+  //printf("HAL Write: Address=0x%02X, Data Length=%d\n", TARGET_ADDRESS, Data_length);
 
 
   // **Check for any WRITE error

+ 24 - 109
src/i2c_controller.c

@@ -14,6 +14,7 @@ Main Source File
 #include "ti/driverlib/dl_i2c.h"
 #include "ti/driverlib/m0p/dl_core.h"
 #include "ti_msp_dl_config.h"
+#include <machine/_stdint.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <string.h>
@@ -23,6 +24,7 @@ I2C_Instance gI2C;
 I2C_ResponseInfo gResponse;
 BatteryData battery_data;
 
+volatile bool piCommandPending= false;
 /*Interrupt for MCU -> ADC
 * CASE: DL_I2C_IIDX_CONTROLLER_RX_DONE: ADC Reception Complete
     - ADC has finished sending data and it's fully received.
@@ -121,122 +123,26 @@ void I2C_controller_INST_IRQHandler(void) {
 
 /**** Interrupt for Pi to MCU ****/
 void I2C_target_INST_IRQHandler(void) {
-  uint8_t receivedCommand = 0;
-  uint8_t battery_state[8] = {0x00};
+
+  //uint8_t receivedCommand = 0;
+  //uint8_t battery_state[8] = {0x00};
   uint32_t status = DL_I2C_getPendingInterrupt(I2C_target_INST);
   //printf("status: %d\n", status);
   switch (status) {
   case DL_I2C_IIDX_TARGET_START:
-    /*Initialize Tx or RX after Start condition is recieved*/
-    piTxCount = 0;
-    piRxCount = 0;
-    piTxComplete = false;
     DL_I2C_flushTargetTXFIFO(I2C_target_INST);
     break;
   case DL_I2C_IIDX_TARGET_STOP:
-    piTxComplete = true;
-    piRxComplete = true;
+    piCommandPending= false;
     DL_I2C_flushTargetTXFIFO(I2C_target_INST);
     DL_I2C_flushTargetRXFIFO(I2C_target_INST);
     break;
   case DL_I2C_IIDX_TARGET_RXFIFO_TRIGGER:
-    printf("Rx Interrupt Triggered \n");
+    //printf("Rx Interrupt Triggered \n");
     if (DL_I2C_isTargetRXFIFOEmpty(I2C_target_INST)) {
       return;
     }
-    receivedCommand = DL_I2C_receiveTargetData(I2C_target_INST);
-    if (receivedCommand == CMD_GET_BATTERY_STATUS) {
-      // printf("Received Command: 0x%02X\n", receivedCommand);
-      for (uint8_t slot = 0; slot < NUM_SLOTS; slot++) {
-        battery_state[slot] = batteries[slot].state;
-      }
-
-      DL_I2C_fillTargetTXFIFO(I2C_target_INST, battery_state, 8);
-      while (DL_I2C_transmitTargetDataCheck(I2C_target_INST, 0x00) != false)
-        ;
-      printf("Sent Data\n");
-    }
-
-    /*
-    To receive the Battery Mesaurements from MCU, bit masking is applied
-    where:
-    - command type is upper 4 bits: 0010 (for CMD_GET_BATTERY_DATA)->
-    consistent
-    - slot_id is lower 3 bits, since NUM_SLOTS are 8 so it ranges from 000
-    till 111
-    - bit mask for command is 0xF0: 11110000
-    - bit mask for requested slot is 0x07: 00000111
-    receivedCommand now ranges from 0x20 till 0x27
-    */
-
-    else if ((receivedCommand & 0xF0) == 0x20) {
-
-      // printf("Received Command: 0x%02X\n", receivedCommand);
-      uint8_t requestedSlot = (receivedCommand & 0x07);
-      // printf("Requested slot:%d\n", requestedSlot);
-      //  piTxCount = 0;
-      piTxLen = sizeof(BatteryData);
-      BatteryData battery_data;
-
-      if (requestedSlot >= NUM_SLOTS) {
-        // printf("Requested Slot is not valid.\n");
-        DL_I2C_flushTargetTXFIFO(I2C_target_INST);
-        return;
-      }
-
-      Battery *battery = &batteries[requestedSlot];
-      battery_data.slot_id = battery->slot_id; // !TODO: recheck if necessary
-      battery_data.voltage = battery->voltage;
-      battery_data.current = battery->current;
-      battery_data.temperature = battery->temperature;
-      DL_I2C_fillTargetTXFIFO(I2C_target_INST, (uint8_t *)&battery_data,
-                              piTxLen);
-      DL_I2C_flushTargetTXFIFO(I2C_target_INST);
-      // printf("slot_id:%u\n", battery_data.slot_id);
-      // battery_data.slot_id= 0;
-      // battery_data.voltage= 61644;
-      // battery_data.current= 43605;
-      // battery_data.temperature= 13071;
-      // printf("voltage:%u\n", battery_data.voltage);
-      // printf("current:%u\n", battery_data.current);
-      // printf("temperature:%u\n", battery_data.temperature);
-      /*piTxComplete= true;
-      if(piTxCount >= piTxLen){
-          piTxComplete= true;
-          piTxCount= 0;
-      }*/
-      //printf("Battery Measurement Sent. \n");
-      
-
-    }
-
-    else if (receivedCommand == CMD_SET_BATTERY_LIMIT) {
-      uint8_t rx_buffer[sizeof(BatteryLimitMsg)];
-      uint8_t index = 0;
-
-      while (!DL_I2C_isTargetRXFIFOEmpty(I2C_target_INST)) {
-        if (index < sizeof(BatteryLimitMsg)) {
-          rx_buffer[index] = DL_I2C_receiveTargetData(I2C_target_INST);
-          index++;
-        } else {
-          DL_I2C_receiveTargetData(I2C_target_INST);
-        }
-      }
-
-      if (index == sizeof(BatteryLimitMsg)) {
-        BatteryLimitMsg battery_limits;
-        memcpy(&battery_limits, rx_buffer, sizeof(BatteryLimitMsg));
-        if (battery_limits.slot_id < NUM_SLOTS) {
-          Battery *battery = &batteries[battery_limits.slot_id];
-          battery->min_voltage = battery_limits.min_voltage;
-          battery->max_voltage = battery_limits.max_voltage;
-          battery->cut_off_current = battery_limits.cut_off_current;
-          battery->capacitance = battery_limits.capacitance;
-          battery->charge_fraction = battery_limits.charge_fraction;
-        }
-      }
-    }
-
+    piCommandPending= true;
     break;
   case DL_I2C_IIDX_TARGET_TXFIFO_TRIGGER:
     break;
@@ -264,22 +170,31 @@ int main(void) {
 
   // Multiplexer
   Multiplexer_SelectChannel(I2C_CHANNEL);
+  //I2C Scanning
   I2C_scanBus();
   I2C_init(&gI2C);
+  //int32_t cnt = 0;
   while (1) {
+    if(piCommandPending){
+        pi_i2c_mcu();
+        piCommandPending= false;
+        continue;
+
+    }
     // Looping through the ADC Channels
-    /*for (uint8_t slot_id = 0; slot_id < NUM_SLOTS; slot_id++) {
+    for (uint8_t slot_id = 0; slot_id < NUM_SLOTS; slot_id++) {
       for (uint8_t adc_channel = 0; adc_channel < ADC_CHANNEL_NUM;
            adc_channel++) {
         Battery_UpdateADCReading(slot_id, adc_channel);
-        delay_cycles(10000000);
+        
       }
+
       Battery_ReadState(slot_id);
+      printf("*** Battery Details: Slot: %u, Voltage:%u, Current: %u, State:%u ***\n",
+           batteries[0].slot_id, batteries[0].voltage, batteries[0].current, batteries[0].state);
       CC_CV_ControlCharging(slot_id);
-    }*/
-    //printf("Battery Details: Slot: %u, Voltage:%u, Current: %u \n, State:%u\n:",
-    //       batteries[0].slot_id, batteries[0].voltage, batteries[0].current,
-    //       batteries[0].state);
-    DAC_SingleWrite(2048);
+      delay_cycles(10000000);
+    }
+    
   }
 }

+ 102 - 2
src/i2c_target.c

@@ -3,9 +3,11 @@
 #include "adc.h"
 #include "battery.h"
 #include "ti/driverlib/dl_i2c.h"
+#include "ti/driverlib/m0p/dl_core.h"
 #include "ti_msp_dl_config.h"
 #include <stdint.h>
 #include <stdio.h>
+#include <string.h>
 
 // Global buffer for I2C
 
@@ -13,14 +15,17 @@ BatteryData battery_data;
 BatteryLimitMsg battery_limits;
 
 // Flag for Pi INTERRUPTS:
-volatile bool piRxComplete;
+/*volatile bool piRxComplete;
 volatile bool piTxComplete;
 
 uint8_t piTxPacket[I2C_TX_MAX_PACKET_SIZE_PI];
-uint8_t piRxPacket[I2C_RX_MAX_PACKET_SIZE_PI];
+uint8_t piRxPacket[I2C_RX_MAX_PACKET_SIZE_PI];*/
 
 uint32_t piTxLen, piTxCount;
 uint32_t piRxLen, piRxCount;
+
+volatile uint8_t rx_buffer[I2C_MAX_BYTES];
+
 /*
 - command: as defined in the Wiki for Pi 0x01, 0x02, 0x03, refer to i2c_target.h
 file
@@ -30,6 +35,101 @@ file
 
 */
 
+void pi_i2c_mcu() {
+  uint8_t receivedCommand = DL_I2C_receiveTargetData(I2C_target_INST);
+  // Storing battery state in a buffer
+  uint8_t battery_state[8] = {0x00};
+  // **Condition to GET Battery State
+  if (receivedCommand == CMD_GET_BATTERY_STATUS) {
+    // printf("Received Command: 0x%02X\n", receivedCommand);
+    for (uint8_t slot = 0; slot < NUM_SLOTS; slot++) {
+      battery_state[slot] = batteries[slot].state;
+    }
+
+    DL_I2C_fillTargetTXFIFO(I2C_target_INST, battery_state, 8);
+    while (DL_I2C_transmitTargetDataCheck(I2C_target_INST, 0x00) != false)
+      ;
+    printf("Sent Data\n");
+  }
+  // **Condition to GET Battery Measurement: Voltage, Current, Temperature
+  else if ((receivedCommand & 0xF0) == 0x20) {
+
+    // printf("Received Command: 0x%02X\n", receivedCommand);
+    uint8_t requestedSlot = (receivedCommand & 0x07);
+    //printf("Requested slot:%d\n", requestedSlot);
+    //  piTxCount = 0;
+    piTxLen = sizeof(BatteryData);
+    BatteryData battery_data;
+
+    if (requestedSlot >= NUM_SLOTS) {
+      // printf("Requested Slot is not valid.\n");
+      DL_I2C_flushTargetTXFIFO(I2C_target_INST);
+      return;
+    }
+    Battery *battery = &batteries[requestedSlot];
+    battery_data.slot_id = battery->slot_id; // !TODO: recheck if necessary
+    battery_data.voltage = battery->voltage;
+    battery_data.current = battery->current;
+    battery_data.temperature = battery->temperature;
+    DL_I2C_fillTargetTXFIFO(I2C_target_INST, (uint8_t *)&battery_data, piTxLen);
+    printf("Battery Measurement Sent. \n");
+    DL_I2C_flushTargetTXFIFO(I2C_target_INST);
+    // printf("slot_id:%u\n", battery_data.slot_id);
+    // battery_data.slot_id= 0;
+    // battery_data.voltage= 61644;
+    // battery_data.current= 43605;
+    // battery_data.temperature= 13071;
+    // printf("voltage:%u\n", battery_data.voltage);
+    // printf("current:%u\n", battery_data.current);
+    // printf("temperature:%u\n", battery_data.temperature);
+    /*piTxComplete= true;
+    if(piTxCount >= piTxLen){
+        piTxComplete= true;
+        piTxCount= 0;
+    }*/
+    // printf("Battery Measurement Sent. \n");
+
+  }
+  // **Condition to SET Battery Limits from Pi
+  else if (receivedCommand == CMD_SET_BATTERY_LIMIT) {
+    uint8_t rx_index= 0;
+    // Wait condition until all the bytes are received from Pi:
+
+    while(rx_index < sizeof(BatteryLimitMsg)){
+        if(!DL_I2C_isTargetRXFIFOEmpty(I2C_target_INST)){
+            rx_buffer[rx_index]= DL_I2C_receiveTargetData(I2C_target_INST);
+            //printf("Received Bytes[%d]: 0x%02X\n", rx_index, rx_buffer[rx_index]);
+            rx_index++;
+        }
+    }
+
+    
+    printf("index:%d\n", rx_index);
+    
 
+    if (rx_index == sizeof(BatteryLimitMsg)) {
+      BatteryLimitMsg battery_limits;
+      memcpy(&battery_limits, (const uint8_t*)rx_buffer, sizeof(BatteryLimitMsg));
+      if (battery_limits.slot_id < NUM_SLOTS) {
+        Battery *battery = &batteries[battery_limits.slot_id];
+        battery->min_voltage = battery_limits.min_voltage;
+        battery->max_voltage = battery_limits.max_voltage;
+        battery->cut_off_current = battery_limits.cut_off_current;
+        battery->capacitance = battery_limits.capacitance;
+        battery->charge_fraction = battery_limits.charge_fraction;
+      }
+    }
 
+    rx_index= 0;
+    DL_I2C_flushTargetRXFIFO(I2C_target_INST);
+    printf("*** Battery Limits: Slot: %u, Max Voltage:%u, Min Voltage:%u, "
+           "Cutoff Current: %u, Capacitance:%u, Charge Fraction:%u ***\n",
+           batteries[0].slot_id, batteries[0].max_voltage,
+           batteries[0].min_voltage, batteries[0].cut_off_current,
+           batteries[0].capacitance, batteries[0].charge_fraction);
+    
+    
+  }
 
+  
+}

+ 11 - 8
src/i2c_target.h

@@ -10,14 +10,15 @@
 #define CMD_SET_BATTERY_LIMIT         0x03       // SET min/max voltage, cutoff current limits
 
 //Maximum packet sizes
+#define I2C_MAX_BYTES (16)
 #define I2C_TX_MAX_PACKET_SIZE_PI (16)
 #define I2C_RX_MAX_PACKET_SIZE_PI (16)
 
 //Flag for READ and WRITE
-extern volatile bool piRxComplete;
+/*extern volatile bool piRxComplete;
 extern volatile bool piTxComplete;
 extern uint8_t piTxPacket[I2C_TX_MAX_PACKET_SIZE_PI];
-extern uint8_t piRxPacket[I2C_RX_MAX_PACKET_SIZE_PI];
+extern uint8_t piRxPacket[I2C_RX_MAX_PACKET_SIZE_PI];*/
 
 /*Counters for Tx and Rx length and bytes sent*/
 extern uint32_t piTxLen, piTxCount;
@@ -25,7 +26,7 @@ extern uint32_t piRxLen, piRxCount;
 
 //Structure for Battery Data Message (GET battery data)
 
-typedef struct{
+typedef struct __attribute__((packed)){
     uint8_t slot_id;
     uint16_t voltage;
     uint16_t current;
@@ -33,16 +34,18 @@ typedef struct{
 } BatteryData;
 
 //SET Battery Limit
-typedef struct{
+//TODO: Converting the datatype to correct size and taking care of the padding
+typedef struct __attribute__((packed)){
     uint8_t slot_id;
     uint16_t min_voltage;
     uint16_t max_voltage;
-    uint16_t cut_off_current;
+    uint8_t cut_off_current;
     uint16_t capacitance;
-    uint16_t charge_fraction;
+    uint8_t charge_fraction;
 } BatteryLimitMsg;
 
 //void I2C_Init();
-void Battery_ReadState(uint8_t slot_id);
-void I2C_target_communication();
+//void Battery_ReadState(uint8_t slot_id);
+//void I2C_target_communication();
+void pi_i2c_mcu();
 #endif

+ 2 - 2
src/multiplexer.c

@@ -54,7 +54,7 @@ void I2C_scanBus() {
         }
     }
 
-    printf("I2C Scan Complete!\n");
+    //printf("I2C Scan Complete!\n");
 }
 
 /*Function for Multiplexer*/
@@ -66,7 +66,7 @@ void Multiplexer_SelectChannel(uint8_t channel)
         return;
     }
     uint8_t data = (channel);
-    printf("Selecting Multiplexer I2C Channel: 0x%02X\n", data);
+    //printf("Selecting Multiplexer I2C Channel: 0x%02X\n", data);
 
     // Ensure bus is idle before starting communication
     while (DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS);