瀏覽代碼

i2c get battery status

namrota ghosh 9 月之前
父節點
當前提交
2393c50707
共有 2 個文件被更改,包括 367 次插入309 次删除
  1. 0 7
      cc_cv_charging.c
  2. 367 302
      i2c_controller.c

+ 0 - 7
cc_cv_charging.c

@@ -1,10 +1,3 @@
-/*
-* MIN_VOLTAGE_MV, MAXIMUM_VOLTAGE will be replaced by the value a slot gets from Pi
-* Article referred: 
-* https://www.monolithicpower.com/learning/resources/battery-charger-fundamentals
-* https://www.instructables.com/Programming-a-Lithium-ion-Battery-Charger-Using-a-/
-*/
-
 #include "cc_cv_charging.h"
 #include "battery.h"
 #include "dac.h"

+ 367 - 302
i2c_controller.c

@@ -1,31 +1,28 @@
 /*
 Main Source File
 */
+#include "adc.h"
+#include "battery.h"
+#include "cc_cv_charging.h"
+#include "dac.h"
 #include "i2c_target.h"
+#include "multiplexer.h"
+#include "ti/comm_modules/i2c/controller/i2c_comm_controller.h"
 #include "ti/devices/msp/peripherals/hw_dac12.h"
 #include "ti/driverlib/dl_adc12.h"
 #include "ti/driverlib/dl_gpio.h"
 #include "ti/driverlib/dl_i2c.h"
 #include "ti/driverlib/m0p/dl_core.h"
 #include "ti_msp_dl_config.h"
-#include "ti/comm_modules/i2c/controller/i2c_comm_controller.h"
 #include <stdint.h>
 #include <stdio.h>
 #include <string.h>
-#include "multiplexer.h"
-#include "adc.h"
-#include "dac.h"
-#include "battery.h"
-#include "i2c_target.h"
-#include "cc_cv_charging.h"
 #include <ti/drivers/GPIO.h>
 
-
 I2C_Instance gI2C;
 I2C_ResponseInfo gResponse;
 BatteryData battery_data;
 
-
 /*Interrupt for MCU -> ADC
 * CASE: DL_I2C_IIDX_CONTROLLER_RX_DONE: ADC Reception Complete
     - ADC has finished sending data and it's fully received.
@@ -36,330 +33,398 @@ BatteryData battery_data;
     - gI2C.status = I2C_STATUS_RX_COMPLETE:
         - Marks reception is complete.
 * CASE: DL_I2C_IIDX_CONTROLLER_TX_DONE: Data Transmit to ADC complete
-    - DL_I2C_disableInterrupt(..): Disables the TXFIFO interrupt since data is now sent
+    - DL_I2C_disableInterrupt(..): Disables the TXFIFO interrupt since data is
+now sent
 * CASE: DL_I2C_IIDX_CONTROLLER_RXFIFO_TRIGGER: Receive Data in FIFO
     - The I2C Receive FIFO has data ready to be read.
-    - while (DL_I2C_isControllerRXFIFOEmpty(...) != true): Loops until the RX FIFOis empty (READ all available bytes)
+    - while (DL_I2C_isControllerRXFIFOEmpty(...) != true): Loops until the RX
+FIFOis empty (READ all available bytes)
     - Inside the while loop:
         - If buffer has SPACE, store the received byte
         - Prints each received byte in HEXADECIMAL format for debugging
         - IF BUFFER is FULL, avoids OVERFLOW by discarding extra byte.
 * CASE: DL_I2C_IIDX_CONTROLLER_TXFIFO_TRIGGER: Transmit Data in FIFO
         - If there is still data to send:
-        gI2C.txMsg.ptr += DL_I2C_fillControllerTXFIFO(I2C_controller_INST, &gI2C.txMsg.buffer[gI2C.txMsg.ptr], gI2C.txMsg.len - gI2C.txMsg.ptr);
+        gI2C.txMsg.ptr += DL_I2C_fillControllerTXFIFO(I2C_controller_INST,
+&gI2C.txMsg.buffer[gI2C.txMsg.ptr], gI2C.txMsg.len - gI2C.txMsg.ptr);
 
 */
-void I2C_controller_INST_IRQHandler(void)
-{   
-    //printf("I2C Interrupt Triggered to ADC!\n");
-    switch (DL_I2C_getPendingInterrupt(I2C_controller_INST)) 
-    {   /*START Condition*/
-        case DL_I2C_IIDX_CONTROLLER_START:
-            //gTxADCcount= 0;
-            gRxADCcount= 0;
-            DL_I2C_flushControllerTXFIFO(I2C_controller_INST);
-            break;
-
-        case DL_I2C_IIDX_CONTROLLER_RXFIFO_TRIGGER:
-            gI2C.status= I2C_STATUS_RX_INPROGRESS;
-            /* Store bytes received from target in Rx Msg Buffer */
-            while (DL_I2C_isControllerRXFIFOEmpty(I2C_controller_INST) != true) {
-                if (gRxADCcount< gRxADClen) {
-                        gRxPacket[gRxADCcount] = DL_I2C_receiveControllerData(I2C_controller_INST);
-                        printf("Received Byte[%d]: 0x%02X\n", gRxADCcount, gRxPacket[gRxADCcount]);  // Debug print
-                        gRxADCcount++;
-                                      
-                } else {
-                    //printf("ERROR: RX Buffer Overflow! ptr=%d MAX_BUFFER_SIZE=%d\n", gI2C.rxMsg.ptr, MAX_BUFFER_SIZE);
-                    /* Ignore and remove from FIFO if the buffer is full */
-                    DL_I2C_receiveControllerData(I2C_controller_INST);
-                }
-            }
-            if (gRxADCcount >= gRxADClen){
-                //printf("ADC Bytes Received!\n");
-                gRxComplete = true;
-                DL_I2C_enableInterrupt(I2C_controller_INST, DL_I2C_INTERRUPT_CONTROLLER_STOP);
-                
-            }
-            break;
-        /*TRANSMIT data to ADC*/
-        case DL_I2C_IIDX_CONTROLLER_TXFIFO_TRIGGER:
-            //printf("TX FIFO with data!\n"); 
-            gI2C.status= I2C_STATUS_TX_INPROGRESS;
-            if(gTxADCcount<gTxADClen){
-                gTxADCcount+= DL_I2C_fillControllerTXFIFO(I2C_controller_INST, &gTxPacket[gTxADCcount], (gTxADClen-gTxADCcount));
-            } else{
-                /*Prevent overflow and just ignore data*/
-                DL_I2C_fillTargetTXFIFO(I2C_controller_INST, (uint8_t[]){0x00}, 1);
-                gTxComplete= true;
-            }
-            //DL_I2C_flushControllerTXFIFO(I2C_controller_INST);
-            break;
-        /*STOP condition*/
-        case DL_I2C_IIDX_CONTROLLER_STOP:
-            gTxComplete= true;
-            gRxComplete = true;
-            //printf("I2C Stop Detected- RX Complete");
-            break;
-        case DL_I2C_IIDX_CONTROLLER_ARBITRATION_LOST:
-            //printf("Interrupt index for I2C controller Arbitration Lost!\n");
-            break;
-        case DL_I2C_IIDX_CONTROLLER_NACK:
-            //printf("I2C NACK Received\n");
-            if((gI2C.status== I2C_STATUS_RX_STARTED)|| (gI2C.status= I2C_STATUS_TX_STARTED)){
-                gI2C.status= I2C_STATUS_ERROR;
-            }
-            break;
-        default:
-            break;
+void I2C_controller_INST_IRQHandler(void) {
+  // printf("I2C Interrupt Triggered to ADC!\n");
+  switch (DL_I2C_getPendingInterrupt(I2C_controller_INST)) { /*START Condition*/
+  case DL_I2C_IIDX_CONTROLLER_START:
+    // gTxADCcount= 0;
+    gRxADCcount = 0;
+    DL_I2C_flushControllerTXFIFO(I2C_controller_INST);
+    break;
+
+  case DL_I2C_IIDX_CONTROLLER_RXFIFO_TRIGGER:
+    gI2C.status = I2C_STATUS_RX_INPROGRESS;
+    /* Store bytes received from target in Rx Msg Buffer */
+    while (DL_I2C_isControllerRXFIFOEmpty(I2C_controller_INST) != true) {
+      if (gRxADCcount < gRxADClen) {
+        gRxPacket[gRxADCcount] =
+            DL_I2C_receiveControllerData(I2C_controller_INST);
+        printf("Received Byte[%d]: 0x%02X\n", gRxADCcount,
+               gRxPacket[gRxADCcount]); // Debug print
+        gRxADCcount++;
+
+      } else {
+        // printf("ERROR: RX Buffer Overflow! ptr=%d MAX_BUFFER_SIZE=%d\n",
+        // gI2C.rxMsg.ptr, MAX_BUFFER_SIZE);
+        /* Ignore and remove from FIFO if the buffer is full */
+        DL_I2C_receiveControllerData(I2C_controller_INST);
+      }
+    }
+    if (gRxADCcount >= gRxADClen) {
+      // printf("ADC Bytes Received!\n");
+      gRxComplete = true;
+      DL_I2C_enableInterrupt(I2C_controller_INST,
+                             DL_I2C_INTERRUPT_CONTROLLER_STOP);
+    }
+    break;
+  /*TRANSMIT data to ADC*/
+  case DL_I2C_IIDX_CONTROLLER_TXFIFO_TRIGGER:
+    // printf("TX FIFO with data!\n");
+    gI2C.status = I2C_STATUS_TX_INPROGRESS;
+    if (gTxADCcount < gTxADClen) {
+      gTxADCcount += DL_I2C_fillControllerTXFIFO(I2C_controller_INST,
+                                                 &gTxPacket[gTxADCcount],
+                                                 (gTxADClen - gTxADCcount));
+    } else {
+      /*Prevent overflow and just ignore data*/
+      DL_I2C_fillTargetTXFIFO(I2C_controller_INST, (uint8_t[]){0x00}, 1);
+      gTxComplete = true;
     }
+    // DL_I2C_flushControllerTXFIFO(I2C_controller_INST);
+    break;
+  /*STOP condition*/
+  case DL_I2C_IIDX_CONTROLLER_STOP:
+    gTxComplete = true;
+    gRxComplete = true;
+    // printf("I2C Stop Detected- RX Complete");
+    break;
+  case DL_I2C_IIDX_CONTROLLER_ARBITRATION_LOST:
+    // printf("Interrupt index for I2C controller Arbitration Lost!\n");
+    break;
+  case DL_I2C_IIDX_CONTROLLER_NACK:
+    // printf("I2C NACK Received\n");
+    if ((gI2C.status == I2C_STATUS_RX_STARTED) ||
+        (gI2C.status = I2C_STATUS_TX_STARTED)) {
+      gI2C.status = I2C_STATUS_ERROR;
+    }
+    break;
+  default:
+    break;
+  }
 }
 
 /**** Interrupt for Pi to MCU ****/
 
 void I2C_target_INST_IRQHandler(void) {
 
-    //printf("I2C Interrupt Triggered to MCU (TARGET)!\n");
-    uint8_t receivedCommand= 0;
-    uint32_t status = DL_I2C_getPendingInterrupt(I2C_target_INST);
-    //ADC_PARAMS params;
-    switch (status) {
-
-        /* START condition detected */
-        case DL_I2C_IIDX_TARGET_START:
-            piTxCount= 0;
-            piRxCount= 0;
-            piTxComplete= false;
-            DL_I2C_flushTargetTXFIFO(I2C_target_INST);
-            break;
-
-        /* STOP condition detected */
-        case DL_I2C_IIDX_TARGET_STOP:
-            piTxComplete= true;
-            piRxComplete = true;
-            DL_I2C_flushTargetTXFIFO(I2C_target_INST);
-            break;
-
-        /* TX FIFO trigger (Pi is reading data from MCU) */
-        /* GET battery status is triggered when command is 0x01
-           - Pi on request of 0x01 will get a response of the battery status for all the slots
-           - Battery_StateUpdate function is called, which in turn calls the Battery_ReadState funtion to set the state of the batteries
-        -Pi on command of [0x02, slot_id] will GET the 'Battery Data' which is voltage, current and temperature for a given slot.
-            - MCU reads the slot_id from Pi using DL_I2C_receiveTargetData()
-            - piTxCount is set to 0
-            - piTxLen is the sizeof BatteryData struct which is 7 bytes
-            - If the requested slot is correct then:
-                - battery pointer variable points to the memory of the requested slot
-                - the values of voltage, current and temperature are then stored in battery_data struct
-            - Once the values are in BatteryData struct we wait for the bus to be free
-            - Next we send the BatteryData to Pi using DL_I2C_fillTargetRXFIFO()
-            - Reset the RX counter for the next data.
-        */
-        
-        case DL_I2C_IIDX_TARGET_TXFIFO_TRIGGER:
-            printf("Pi GET data from MCU!\n");
-            if(!DL_I2C_isTargetRXFIFOEmpty(I2C_target_INST)){
-                receivedCommand= DL_I2C_receiveTargetData(I2C_target_INST);
-                //printf("Received Command: 0x%02X\n", receivedCommand);
-
-                if (receivedCommand == CMD_GET_BATTERY_STATUS){
-                    printf("Battery status received.\n");
-                    //Battery_StateUpdate();
-                    piTxCount= 0;
-                    piTxLen= NUM_SLOTS;
-                    piTxComplete = false;
-                    // Prepare data to be sent to Pi:
-                    for(uint8_t slot= 0; slot < NUM_SLOTS; slot++){
-                        // Read the battery status for each slot
-                        Battery_ReadState(slot);
-                        piTxPacket[slot]= batteries[slot].state;
-                    }
-                    //Filling up the FIFO
-                    if(piTxCount < piTxLen){
-                        while (DL_I2C_getTargetStatus(I2C_target_INST) & DL_I2C_TARGET_STATUS_BUS_BUSY)
-                        ;
-                        piTxCount += DL_I2C_fillTargetTXFIFO(I2C_target_INST, &piTxPacket[piTxCount], (piTxLen-piTxCount));     
-                    }
-                    else {
-                    /*
-                    * Fill FIFO with 0x00 if more data is requested than expected piTxLen
-                    */
-                    while (
-                        DL_I2C_transmitTargetDataCheck(I2C_target_INST, 0x00) != false);
-                    }
-                    piTxComplete= true;
-                }
-                else if (receivedCommand == CMD_GET_BATTERY_DATA){
-
-                    uint8_t requestedSlot= DL_I2C_receiveTargetData(I2C_target_INST);
-                    while (DL_I2C_getTargetStatus(I2C_target_INST) & DL_I2C_TARGET_STATUS_BUS_BUSY)
-                    ;
-                    //printf("Battery Data Requested for Slot %d!\n", requestedSlot);
-                        piTxCount= 0;
-                        piTxLen= sizeof(BatteryData);
-                        BatteryData battery_data;
-                        if(requestedSlot < NUM_SLOTS){
-                            Battery *battery= &batteries[requestedSlot];
-                            battery_data.slot_id = battery-> slot_id;
-                            battery_data.voltage= battery-> voltage;
-                            battery_data.current= battery-> current;
-                            battery_data.temperature= battery-> temperature;
-
-                            while (DL_I2C_getTargetStatus(I2C_target_INST) & DL_I2C_TARGET_STATUS_BUS_BUSY);
-
-                            DL_I2C_fillTargetTXFIFO(I2C_target_INST, (uint8_t *)&battery_data, sizeof(BatteryData));
-
-                            //piTxCount += DL_I2C_fillTargetTXFIFO(I2C_target_INST, (uint8_t*)&battery_data, piTxLen);
-
-                            piTxComplete= true;
-
-                            while (DL_I2C_getTargetStatus(I2C_target_INST) & DL_I2C_TARGET_STATUS_BUS_BUSY);
-
-                            if(piTxCount >= piTxLen){
-                            piTxComplete= true;
-                            piTxCount=0;
-                            }
-
-                        } else{
-                            //printf("Invalid Slot ID: %d\n.", requestedSlot);
-                        }
-                    
-                }
+  // printf("I2C Interrupt Triggered to MCU (TARGET)!\n");
+  uint8_t receivedCommand = 0;
+  uint32_t status = DL_I2C_getPendingInterrupt(I2C_target_INST);
+  // ADC_PARAMS params;
+  switch (status) {
+
+  /* START condition detected */
+  case DL_I2C_IIDX_TARGET_START:
+    piTxCount = 0;
+    piRxCount = 0;
+    piTxComplete = false;
+    DL_I2C_flushTargetTXFIFO(I2C_target_INST);
+    break;
+
+  /* STOP condition detected */
+  case DL_I2C_IIDX_TARGET_STOP:
+    piTxComplete = true;
+    piRxComplete = true;
+    DL_I2C_flushTargetTXFIFO(I2C_target_INST);
+    break;
+
+    /* TX FIFO trigger (Pi is reading data from MCU) */
+    /* GET battery status is triggered when command is 0x01
+       - Pi on request of 0x01 will get a response of the battery status for all
+    the slots
+       - Battery_StateUpdate function is called, which in turn calls the
+    Battery_ReadState funtion to set the state of the batteries -Pi on command
+    of [0x02, slot_id] will GET the 'Battery Data' which is voltage, current and
+    temperature for a given slot.
+        - MCU reads the slot_id from Pi using DL_I2C_receiveTargetData()
+        - piTxCount is set to 0
+        - piTxLen is the sizeof BatteryData struct which is 7 bytes
+        - If the requested slot is correct then:
+            - battery pointer variable points to the memory of the requested
+    slot
+            - the values of voltage, current and temperature are then stored in
+    battery_data struct
+        - Once the values are in BatteryData struct we wait for the bus to be
+    free
+        - Next we send the BatteryData to Pi using DL_I2C_fillTargetRXFIFO()
+        - Reset the RX counter for the next data.
+    */
+
+  case DL_I2C_IIDX_TARGET_TXFIFO_TRIGGER:
+    break;
+    if (!DL_I2C_isTargetRXFIFOEmpty(I2C_target_INST)) {
+      receivedCommand = DL_I2C_receiveTargetData(I2C_target_INST);
+      // printf("Received Command: 0x%02X\n", receivedCommand);
+
+       else {
+          /*
+           * Fill FIFO with 0x00 if more data is requested than expected piTxLen
+           */
+          while (DL_I2C_transmitTargetDataCheck(I2C_target_INST, 0x00) != false)
+            ;
+        }
+        piTxComplete = true;
+      } else if (receivedCommand == CMD_GET_BATTERY_DATA) {
+
+        uint8_t requestedSlot = DL_I2C_receiveTargetData(I2C_target_INST);
+        while (DL_I2C_getTargetStatus(I2C_target_INST) &
+               DL_I2C_TARGET_STATUS_BUS_BUSY)
+          ;
+        // printf("Battery Data Requested for Slot %d!\n", requestedSlot);
+        piTxCount = 0;
+        piTxLen = sizeof(BatteryData);
+        BatteryData battery_data;
+        if (requestedSlot < NUM_SLOTS) {
+          Battery *battery = &batteries[requestedSlot];
+          battery_data.slot_id = battery->slot_id;
+          battery_data.voltage = battery->voltage;
+          battery_data.current = battery->current;
+          battery_data.temperature = battery->temperature;
+
+          while (DL_I2C_getTargetStatus(I2C_target_INST) &
+                 DL_I2C_TARGET_STATUS_BUS_BUSY)
+            ;
+
+          DL_I2C_fillTargetTXFIFO(I2C_target_INST, (uint8_t *)&battery_data,
+                                  sizeof(BatteryData));
+
+          // piTxCount += DL_I2C_fillTargetTXFIFO(I2C_target_INST,
+          // (uint8_t*)&battery_data, piTxLen);
+
+          piTxComplete = true;
+
+          while (DL_I2C_getTargetStatus(I2C_target_INST) &
+                 DL_I2C_TARGET_STATUS_BUS_BUSY)
+            ;
+
+          if (piTxCount >= piTxLen) {
+            piTxComplete = true;
+            piTxCount = 0;
+          }
+
+        } else {
+          // printf("Invalid Slot ID: %d\n.", requestedSlot);
         }
-            
-            break;
-
-         /* TARGET_Rx FIFO trigger (Pi is writing data to MCU) */
-         /*Pi SET battery data limits for each slot, where:
-         - RXFIFO buffer is filled if the command from Pi is 0x03
-         - Creating a temporary buffer named ´rxbuffer´
-         - sizeof(BatteryLimitMsg): 11 bytes (1 byte: slot_id, 2 bytes: min_voltage; max_voltage; cut_off_current; capacitance; charge_fraction)
-         - rx_buffer stores the data from Pi.
-         - if all the expected bytes are received from Pi then,
-            - memcpy() to copy the block of address from the temporary buffer to the BatteryLimitMsg structure
-            - Why?, A: It copies the specified number of bytes from one memory location to another regardless of the type of the data stored.
-            - verify if the received slot_id is less than NUM_SLOTS, where slot_id count starts from 0 then:
-                - create a pointer variable for 'Battery' 
-                - battery_limits.slot_id: index of the battery slot to be updated
-                - &batteries[battery_limits.slot_id]: gets the memory address of the battery in that slot
-                - Accessing the structure members of Battery using -> operator. This allows efficient access to the structure's members 
-                without directly using the structure variable.
-
-         */
-        case DL_I2C_IIDX_TARGET_RXFIFO_TRIGGER:
-            printf("Pi SET Battery limit to MCU.....\n");
-            if(!DL_I2C_isTargetRXFIFOEmpty(I2C_target_INST)){
-                receivedCommand= DL_I2C_receiveTargetData(I2C_target_INST);
-                //printf("Received Command: 0x%02X\n", receivedCommand);
-                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);
-                        //printf("Received Byte[%d]: 0x%02X\n", index, rx_buffer[index]); 
-                        index++;
-                        
-                    }
-                    else{
-                        DL_I2C_receiveTargetData(I2C_target_INST);
-                    }
-                }
-
-                //printf("Total Bytes Received: %d (Expected: %d)\n", index, sizeof(BatteryLimitMsg));
-
-                if(index == sizeof(BatteryLimitMsg)){
-                    //printf("Received Battery Limits.\n");
-                    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;
-                        /*printf("\n Received Battery Limits for slot %d: \n", battery_limits.slot_id);
-                        printf("  Min Voltage:      %d mV (0x%04X)\n", battery_limits.min_voltage, battery_limits.min_voltage);
-                        printf("  Max Voltage:      %d mV (0x%04X)\n", battery_limits.max_voltage, battery_limits.max_voltage);
-                        printf("  Cutoff Current:   %d mA (0x%04X)\n", battery_limits.cut_off_current, battery_limits.cut_off_current);
-                        printf("  Capacitance:      %d µF (0x%04X)\n", battery_limits.capacitance, battery_limits.capacitance);
-                        printf("  Charge Fraction:  %d%% (0x%02X)\n", battery_limits.charge_fraction, battery_limits.charge_fraction);*/
-                    }
-                }
-
-                }
-
-            }
-            
-            break;
-    
-        /* Arbitration lost or NACK */
-        case DL_I2C_IIDX_TARGET_ARBITRATION_LOST:
-            printf("Arbitration Lost.\n");
-            break;
-        default:
-            printf("Unknown Interrupt.\n");
-            break;
+      }
     }
-}
 
-/********MAIN function*************/
+    break;
+
+    /* TARGET_Rx FIFO trigger (Pi is writing data to MCU) */
+    /*Pi SET battery data limits for each slot, where:
+    - RXFIFO buffer is filled if the command from Pi is 0x03
+    - Creating a temporary buffer named ´rxbuffer´
+    - sizeof(BatteryLimitMsg): 11 bytes (1 byte: slot_id, 2 bytes: min_voltage;
+    max_voltage; cut_off_current; capacitance; charge_fraction)
+    - rx_buffer stores the data from Pi.
+    - if all the expected bytes are received from Pi then,
+       - memcpy() to copy the block of address from the temporary buffer to the
+    BatteryLimitMsg structure
+       - Why?, A: It copies the specified number of bytes from one memory
+    location to another regardless of the type of the data stored.
+       - verify if the received slot_id is less than NUM_SLOTS, where slot_id
+    count starts from 0 then:
+           - create a pointer variable for 'Battery'
+           - battery_limits.slot_id: index of the battery slot to be updated
+           - &batteries[battery_limits.slot_id]: gets the memory address of the
+    battery in that slot
+           - Accessing the structure members of Battery using -> operator. This
+    allows efficient access to the structure's members without directly using
+    the structure variable.
+
+    */
+  case DL_I2C_IIDX_TARGET_RXFIFO_TRIGGER:
+    if (!DL_I2C_isTargetRXFIFOEmpty(I2C_target_INST)) {
+
+      receivedCommand = DL_I2C_receiveTargetData(I2C_target_INST);
+
+      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);
+            // printf("Received Byte[%d]: 0x%02X\n", index, rx_buffer[index]);
+            index++;
+
+          } else {
+            DL_I2C_receiveTargetData(I2C_target_INST);
+          }
+        }
 
-int main(void)
-{
-    // Initialize System and I2C
-    SYSCFG_DL_init();
-
-    // Initialize battery array and default params
-    Battery_Init();
-    
-    //Reset_I2C_Bus();
-    NVIC_EnableIRQ(I2C_target_INST_INT_IRQN);
-    NVIC_EnableIRQ(I2C_controller_INST_INT_IRQN);
-
-    printf("............System Configuration Enabled...............\n");
-    
-    //Multiplexer
-    Multiplexer_SelectChannel(I2C_CHANNEL);
-    //I2C_scanBus();
-    I2C_init(&gI2C);
-    
-    //ADC_SetConfigurationBytes(adc_voltage_params); 
-    //delay_cycles(50000);
-    //ADC_SetConfigurationBytes(adc_current_params);
-    //delay_cycles(50000);
-    //DAC_ReadCurrentAddress();
-
-    while (1)
-    {   //Looping through the ADC Channels
-        /*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++){
-                batteries[slot_id].channel= adc_channel;
-                Battery_UpdateADCReading(slot_id, batteries[slot_id].channel);
-            
-            }
-            
+        // printf("Total Bytes Received: %d (Expected: %d)\n", index,
+        // sizeof(BatteryLimitMsg));
+
+        if (index == sizeof(BatteryLimitMsg)) {
+          // printf("Received Battery Limits.\n");
+          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;
+            /*printf("\n Received Battery Limits for slot %d: \n",
+            battery_limits.slot_id); printf("  Min Voltage:      %d mV
+            (0x%04X)\n", battery_limits.min_voltage,
+            battery_limits.min_voltage); printf("  Max Voltage:      %d mV
+            (0x%04X)\n", battery_limits.max_voltage,
+            battery_limits.max_voltage); printf("  Cutoff Current:   %d mA
+            (0x%04X)\n", battery_limits.cut_off_current,
+            battery_limits.cut_off_current); printf("  Capacitance:      %d µF
+            (0x%04X)\n", battery_limits.capacitance,
+            battery_limits.capacitance); printf("  Charge Fraction:  %d%%
+            (0x%02X)\n", battery_limits.charge_fraction,
+            battery_limits.charge_fraction);*/
+          }
+        }
+      } else if (receivedCommand == CMD_GET_BATTERY_STATUS) {
+        uint8_t test[8] = {0x00};
+        // for testing:
+        Battery batteries[NUM_SLOTS] = {
+            {0, STATE_BATTERY_DETECTED, 3700, 500, 25, 3000, 4200, 2000, 10000, 80}
+        };
+        //Battery_StateUpdate();
+
+        // Prepare data to be sent to Pi:
+        for (uint8_t slot = 0; slot < NUM_SLOTS; slot++) {
+          // Read the battery status for each slot
+          //Battery_ReadState(slot);
+          test[slot] = batteries[slot].state;
+        }
+        // Filling up the FIFO
+        DL_I2C_fillTargetTXFIFO(I2C_target_INST, &test, 8);
+        while (DL_I2C_transmitTargetDataCheck(I2C_target_INST, 0x00) != false)
+            ;
+                printf("Sent Data\n");
+
+
+
+        /*if (piTxCount < piTxLen) {
+          while (DL_I2C_getTargetStatus(I2C_target_INST) &
+                 DL_I2C_TARGET_STATUS_BUS_BUSY)
+            ;
+          piTxCount += DL_I2C_fillTargetTXFIFO(
+              I2C_target_INST, &piTxPacket[piTxCount], (piTxLen - piTxCount));
+        } else {
+          /*
+           * Fill FIFO with 0x00 if more data is requested than expected piTxLen
+           */
+          /*while (DL_I2C_transmitTargetDataCheck(I2C_target_INST, 0x00) != false)
+            ;
         }*/
+      } else if (receivedCommand == CMD_GET_BATTERY_DATA) {
+
+        uint8_t requestedSlot = DL_I2C_receiveTargetData(I2C_target_INST);
+        while (DL_I2C_getTargetStatus(I2C_target_INST) &
+               DL_I2C_TARGET_STATUS_BUS_BUSY)
+          ;
+        // printf("Battery Data Requested for Slot %d!\n", requestedSlot);
+        piTxCount = 0;
+        piTxLen = sizeof(BatteryData);
+        BatteryData battery_data;
+        if (requestedSlot < NUM_SLOTS) {
+          Battery *battery = &batteries[requestedSlot];
+          battery_data.slot_id = battery->slot_id;
+          battery_data.voltage = battery->voltage;
+          battery_data.current = battery->current;
+          battery_data.temperature = battery->temperature;
+
+          while (DL_I2C_getTargetStatus(I2C_target_INST) &
+                 DL_I2C_TARGET_STATUS_BUS_BUSY)
+            ;
+
+          DL_I2C_fillTargetTXFIFO(I2C_target_INST, (uint8_t *)&battery_data,
+                                  sizeof(BatteryData));
+
+          // piTxCount += DL_I2C_fillTargetTXFIFO(I2C_target_INST,
+          // (uint8_t*)&battery_data, piTxLen);
+
+          piTxComplete = true;
+
+          while (DL_I2C_getTargetStatus(I2C_target_INST) &
+                 DL_I2C_TARGET_STATUS_BUS_BUSY)
+            ;
+
+          if (piTxCount >= piTxLen) {
+            piTxComplete = true;
+            piTxCount = 0;
+          }
 
-        //CC-CV Cycle: maximum cycles is not yet implemented
-        //for(uint8_t slot_id= 0; slot_id < NUM_SLOTS; slot_id++){
-        //    CC_CV_ControlCharging(slot_id);
-        //}  
-
-        //DAC_fastWrite(CHANNEL_A_VALUE);   
+        }
 
-    }   
+    break;
 
+  /* Arbitration lost or NACK */
+  case DL_I2C_IIDX_TARGET_ARBITRATION_LOST:
+    printf("Arbitration Lost.\n");
+    break;
+  default:
+    printf("Unknown Interrupt.\n");
+    break;
+  }
 }
-        
-        
 
+/********MAIN function*************/
+
+int main(void) {
+  // Initialize System and I2C
+  SYSCFG_DL_init();
+
+  // Initialize battery array and default params
+  Battery_Init();
 
+  // Reset_I2C_Bus();
+  NVIC_EnableIRQ(I2C_target_INST_INT_IRQN);
+  NVIC_EnableIRQ(I2C_controller_INST_INT_IRQN);
 
+  printf("............System Configuration Enabled...............\n");
 
+  // Multiplexer
+  Multiplexer_SelectChannel(I2C_CHANNEL);
+  // I2C_scanBus();
+  I2C_init(&gI2C);
 
+  // ADC_SetConfigurationBytes(adc_voltage_params);
+  // delay_cycles(50000);
+  // ADC_SetConfigurationBytes(adc_current_params);
+  // delay_cycles(50000);
+  // DAC_ReadCurrentAddress();
 
+  while (1) { // Looping through the ADC Channels
+    /*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++){
+            batteries[slot_id].channel= adc_channel;
+            Battery_UpdateADCReading(slot_id, batteries[slot_id].channel);
 
+        }
+
+    }*/
 
+    // CC-CV Cycle: maximum cycles is not yet implemented
+    // for(uint8_t slot_id= 0; slot_id < NUM_SLOTS; slot_id++){
+    //     CC_CV_ControlCharging(slot_id);
+    // }
+
+    // DAC_fastWrite(CHANNEL_A_VALUE);
+  }
+}