Procházet zdrojové kódy

MCU->Multiplexer->ADC and DAC Fast Write Mode in progress

namrota ghosh před 9 měsíci
rodič
revize
7c7d90859c

binární
charge_controller_v7/Debug/.clangd/.cache/clangd/index/i2c_comm_controller.c.203F8B33309E2B48.idx


binární
charge_controller_v7/Debug/.clangd/.cache/clangd/index/i2c_comm_controller.h.8DD4C36B9014EBE6.idx


binární
charge_controller_v7/Debug/.clangd/.cache/clangd/index/i2c_controller.c.D084D0AF1C0F98F4.idx


binární
charge_controller_v7/Debug/.clangd/.cache/clangd/index/ti_msp_dl_config.c.CD2F9AD1B4C264FA.idx


binární
charge_controller_v7/Debug/.clangd/.cache/clangd/index/ti_msp_dl_config.h.6C46FDF13D1C9C02.idx


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 526 - 375
charge_controller_v7/Debug/charge_controller_v7.map


binární
charge_controller_v7/Debug/charge_controller_v7.out


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 1263 - 678
charge_controller_v7/Debug/charge_controller_v7_linkInfo.xml


+ 4 - 4
charge_controller_v7/Debug/i2c_controller.d

@@ -1,6 +1,7 @@
 # FIXED
 
 i2c_controller.o: ../i2c_controller.c \
+ /home/ngosh/ti/mspm0_sdk_2_03_00_07/source/ti/devices/msp/peripherals/hw_dac12.h \
  /home/ngosh/ti/mspm0_sdk_2_03_00_07/source/ti/driverlib/dl_gpio.h \
  /home/ngosh/ti/mspm0_sdk_2_03_00_07/source/ti/devices/msp/msp.h \
  /home/ngosh/ti/mspm0_sdk_2_03_00_07/source/ti/devices/DeviceFamily.h \
@@ -10,7 +11,6 @@ i2c_controller.o: ../i2c_controller.c \
  /home/ngosh/ti/mspm0_sdk_2_03_00_07/source/ti/devices/msp/peripherals/hw_aes.h \
  /home/ngosh/ti/mspm0_sdk_2_03_00_07/source/ti/devices/msp/peripherals/hw_comp.h \
  /home/ngosh/ti/mspm0_sdk_2_03_00_07/source/ti/devices/msp/peripherals/hw_crc.h \
- /home/ngosh/ti/mspm0_sdk_2_03_00_07/source/ti/devices/msp/peripherals/hw_dac12.h \
  /home/ngosh/ti/mspm0_sdk_2_03_00_07/source/ti/devices/msp/peripherals/hw_dma.h \
  /home/ngosh/ti/mspm0_sdk_2_03_00_07/source/ti/devices/msp/peripherals/hw_flashctl.h \
  /home/ngosh/ti/mspm0_sdk_2_03_00_07/source/ti/devices/msp/peripherals/hw_gpio.h \
@@ -34,11 +34,11 @@ i2c_controller.o: ../i2c_controller.c \
  /home/ngosh/ti/mspm0_sdk_2_03_00_07/source/ti/devices/msp/peripherals/m0p/sysctl/hw_sysctl_mspm0g1x0x_g3x0x.h \
  /home/ngosh/ti/mspm0_sdk_2_03_00_07/source/ti/driverlib/dl_common.h \
  /home/ngosh/ti/mspm0_sdk_2_03_00_07/source/ti/driverlib/dl_i2c.h \
+ /home/ngosh/ti/mspm0_sdk_2_03_00_07/source/ti/driverlib/m0p/dl_core.h \
  ti_msp_dl_config.h \
  /home/ngosh/ti/mspm0_sdk_2_03_00_07/source/ti/driverlib/driverlib.h \
  /home/ngosh/ti/mspm0_sdk_2_03_00_07/source/ti/driverlib/dl_adc12.h \
  /home/ngosh/ti/mspm0_sdk_2_03_00_07/source/ti/driverlib/m0p/dl_factoryregion.h \
- /home/ngosh/ti/mspm0_sdk_2_03_00_07/source/ti/driverlib/m0p/dl_core.h \
  /home/ngosh/ti/mspm0_sdk_2_03_00_07/source/ti/driverlib/dl_aes.h \
  /home/ngosh/ti/mspm0_sdk_2_03_00_07/source/ti/driverlib/dl_aesadv.h \
  /home/ngosh/ti/mspm0_sdk_2_03_00_07/source/ti/driverlib/dl_comp.h \
@@ -76,6 +76,7 @@ i2c_controller.o: ../i2c_controller.c \
  /home/ngosh/ti/mspm0_sdk_2_03_00_07/source/ti/driverlib/m0p/dl_interrupt.h \
  /home/ngosh/ti/mspm0_sdk_2_03_00_07/source/ti/driverlib/m0p/dl_systick.h \
  ../ti/comm_modules/i2c/controller/i2c_comm_controller.h
+/home/ngosh/ti/mspm0_sdk_2_03_00_07/source/ti/devices/msp/peripherals/hw_dac12.h:
 /home/ngosh/ti/mspm0_sdk_2_03_00_07/source/ti/driverlib/dl_gpio.h:
 /home/ngosh/ti/mspm0_sdk_2_03_00_07/source/ti/devices/msp/msp.h:
 /home/ngosh/ti/mspm0_sdk_2_03_00_07/source/ti/devices/DeviceFamily.h:
@@ -85,7 +86,6 @@ i2c_controller.o: ../i2c_controller.c \
 /home/ngosh/ti/mspm0_sdk_2_03_00_07/source/ti/devices/msp/peripherals/hw_aes.h:
 /home/ngosh/ti/mspm0_sdk_2_03_00_07/source/ti/devices/msp/peripherals/hw_comp.h:
 /home/ngosh/ti/mspm0_sdk_2_03_00_07/source/ti/devices/msp/peripherals/hw_crc.h:
-/home/ngosh/ti/mspm0_sdk_2_03_00_07/source/ti/devices/msp/peripherals/hw_dac12.h:
 /home/ngosh/ti/mspm0_sdk_2_03_00_07/source/ti/devices/msp/peripherals/hw_dma.h:
 /home/ngosh/ti/mspm0_sdk_2_03_00_07/source/ti/devices/msp/peripherals/hw_flashctl.h:
 /home/ngosh/ti/mspm0_sdk_2_03_00_07/source/ti/devices/msp/peripherals/hw_gpio.h:
@@ -109,11 +109,11 @@ i2c_controller.o: ../i2c_controller.c \
 /home/ngosh/ti/mspm0_sdk_2_03_00_07/source/ti/devices/msp/peripherals/m0p/sysctl/hw_sysctl_mspm0g1x0x_g3x0x.h:
 /home/ngosh/ti/mspm0_sdk_2_03_00_07/source/ti/driverlib/dl_common.h:
 /home/ngosh/ti/mspm0_sdk_2_03_00_07/source/ti/driverlib/dl_i2c.h:
+/home/ngosh/ti/mspm0_sdk_2_03_00_07/source/ti/driverlib/m0p/dl_core.h:
 ti_msp_dl_config.h:
 /home/ngosh/ti/mspm0_sdk_2_03_00_07/source/ti/driverlib/driverlib.h:
 /home/ngosh/ti/mspm0_sdk_2_03_00_07/source/ti/driverlib/dl_adc12.h:
 /home/ngosh/ti/mspm0_sdk_2_03_00_07/source/ti/driverlib/m0p/dl_factoryregion.h:
-/home/ngosh/ti/mspm0_sdk_2_03_00_07/source/ti/driverlib/m0p/dl_core.h:
 /home/ngosh/ti/mspm0_sdk_2_03_00_07/source/ti/driverlib/dl_aes.h:
 /home/ngosh/ti/mspm0_sdk_2_03_00_07/source/ti/driverlib/dl_aesadv.h:
 /home/ngosh/ti/mspm0_sdk_2_03_00_07/source/ti/driverlib/dl_comp.h:

binární
charge_controller_v7/Debug/i2c_controller.o


+ 2 - 1
charge_controller_v7/Debug/ti_msp_dl_config.c

@@ -175,7 +175,8 @@ SYSCONFIG_WEAK void SYSCFG_DL_I2C_target_init(void) {
     DL_I2C_enableInterrupt(I2C_target_INST,
                            DL_I2C_INTERRUPT_TARGET_RXFIFO_TRIGGER |
                            DL_I2C_INTERRUPT_TARGET_START |
-                           DL_I2C_INTERRUPT_TARGET_STOP);
+                           DL_I2C_INTERRUPT_TARGET_STOP |
+                           DL_I2C_INTERRUPT_TARGET_TXFIFO_TRIGGER);
 
 
     /* Enable module */

+ 8 - 8
charge_controller_v7/Debug/ti_msp_dl_config.h

@@ -84,14 +84,14 @@ extern "C" {
 #define I2C_controller_INST_IRQHandler                           I2C1_IRQHandler
 #define I2C_controller_INST_INT_IRQN                               I2C1_INT_IRQn
 #define I2C_controller_BUS_SPEED_HZ                                       100000
-#define GPIO_I2C_controller_SDA_PORT                                       GPIOB
-#define GPIO_I2C_controller_SDA_PIN                                DL_GPIO_PIN_3
-#define GPIO_I2C_controller_IOMUX_SDA                            (IOMUX_PINCM16)
-#define GPIO_I2C_controller_IOMUX_SDA_FUNC               IOMUX_PINCM16_PF_I2C1_SDA
-#define GPIO_I2C_controller_SCL_PORT                                       GPIOB
-#define GPIO_I2C_controller_SCL_PIN                                DL_GPIO_PIN_2
-#define GPIO_I2C_controller_IOMUX_SCL                            (IOMUX_PINCM15)
-#define GPIO_I2C_controller_IOMUX_SCL_FUNC               IOMUX_PINCM15_PF_I2C1_SCL
+#define GPIO_I2C_controller_SDA_PORT                                       GPIOA
+#define GPIO_I2C_controller_SDA_PIN                               DL_GPIO_PIN_16
+#define GPIO_I2C_controller_IOMUX_SDA                            (IOMUX_PINCM38)
+#define GPIO_I2C_controller_IOMUX_SDA_FUNC               IOMUX_PINCM38_PF_I2C1_SDA
+#define GPIO_I2C_controller_SCL_PORT                                       GPIOA
+#define GPIO_I2C_controller_SCL_PIN                               DL_GPIO_PIN_15
+#define GPIO_I2C_controller_IOMUX_SCL                            (IOMUX_PINCM37)
+#define GPIO_I2C_controller_IOMUX_SCL_FUNC               IOMUX_PINCM37_PF_I2C1_SCL
 
 /* Defines for I2C_target */
 #define I2C_target_INST                                                     I2C0

binární
charge_controller_v7/Debug/ti_msp_dl_config.o


+ 760 - 91
charge_controller_v7/i2c_controller.c

@@ -1,38 +1,31 @@
 /*
- * Copyright (c) 2024, Texas Instruments Incorporated
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * *  Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * *  Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * *  Neither the name of Texas Instruments Incorporated nor the names of
- *    its contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ 20.02.2025:
+ Flowchart of the code:
+ 1. MCU requests ADC data over I2C
+ 2. ADC is connected to the MULTIPLEXER.
+ 3. Interrupt triggers when data is available.
+ 4. Interrupt moves RECEIVED bytes into RXFIFO Buffer
+ 5. Interrupt marks reception complete RX_DONE
+ 6. Read ADC_Data and retrieve the final ADc value
+ 7. Convert ADC value to Voltage
+
+ 24.02.2025: 
+ Working Code for Reading Analog Signals from ADC to MCU through Multiplexer
+    - configured the registers with Channel, Resolution, Mode(Continuous or Single-mode) and Gain: Construct_Config_Byte()
+    - SET configuration registers to ADC: SetConfiguration()
+    - Read the Analog Output: Read_ADC_Data()
+    - Convert Analog output to voltage in Volts: Convert_ADC_To_Voltage()
+    - Commented out interrupts for the time being.
+    - Adding code for Pi to READ ADC voltages in mV.
+    - 
  */
 
 
+#include "ti/devices/msp/peripherals/hw_dac12.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>
@@ -40,27 +33,139 @@
 
 I2C_Instance gI2C;
 
+/*MULTIPLEXER SECTION:*/
+
 /*Multiplexer Address*/
 #define MULTIPLEXER_I2C_ADDR (0x70)
 
 /*Multiplexer channel*/
 #define ADC_I2C_CHANNEL (0x01)
 
+/*****************DAC*********************/
+
+/*Fast write command for DAC*/
+#define FAST_WRITE_COMMAND  0x00
+#define MULTI_WRITE         0x40
+#define SINGLE_WRITE        0x58
+#define SEQ_WRITE           0x50
+#define VREF_CMD            0x80
+#define GAIN_CMD            0xC0
+#define PWR_DWN_CMD         0xA0
+
+//DAC Channel Selection
+typedef enum{
+    DAC_A = 0,
+    DAC_B,
+    DAC_C,
+    DAC_D
+} DAC_CH;
+
+typedef enum{
+    VREF_VDD= 0,
+    VREF_INTERNAL= 1
+}VREF_SELECTION;
+
+typedef enum{
+    GAIN_X1= 0,
+    GAIN_X2= 1
+}GAIN_SELECTION;
+
+typedef enum{
+    PD_NORMAL=0,
+    PD_GND_1KOHM= 1,
+    PD_GND_100KOHM= 2,
+    PD_GND_500KOHM= 3
+}PWR_DOWN_SELECTION;
+
+// Structure to Hold DAC Register Data
+typedef struct {
+    VREF_SELECTION vref;
+    PWR_DOWN_SELECTION pd;
+    GAIN_SELECTION gain;
+    uint16_t data;
+} DACRegisterData;
+
+// Create Global Storage for DAC Values
+DACRegisterData read_reg_[4];  // Holds Active Register Values
+DACRegisterData read_eep_[4];  // Holds EEPROM Stored Values
+
+
+/***********************/
+
+/*
+
+ADC SETTINGS:
+
+Fixed Reference Voltage is 2.048V and PGA Gain setting default: x1
+
+Mode: can be 1: Continuous or 0: for One-Shot Conversion
+
+ADC_RESOLUTION: 16 bits -> A higher resolution means better precision but slower conversion time.
+
+Calculation for V(IN)= (ADC Value/2^ (Resolution-1))* V(REF)
+*/
+
+/*Voltage is calculated in ADC in milliVolts:
+- Reference voltage in milliVolts to be read from Pi
+- Register address where ADC result would be stored
+*/
+
+#define VREF 2.048 
+// address register for ADC Voltage Read:
+#define ADC_REGISTER 0x10
+/*Register for the MCU*/
+#define REGISTER_SIZE 256
+#define I2C_BUFFER_SIZE (16)
+//#define DAC12_REF_VOLTAGE_mV (2500)
+
+uint8_t registers[REGISTER_SIZE]= {1, 2, 3, 4, 5};
+
+/* Buffers for data exchange with Pi*/
+uint16_t gRxBuffer[I2C_BUFFER_SIZE]= {0};
+uint16_t gTxBuffer[I2C_BUFFER_SIZE]={0};
+
+/*Counter for data length and bytes*/
+uint32_t gTxLen, gTxCount;
+uint32_t gRxLen, gRxCount;
+
 volatile I2C_CommandInfo gCommand;
 
 I2C_ResponseInfo gResponse;
 
+
 volatile bool gSendCommand = true;
+volatile bool newMeasurementAvailable = false;
 
-/*Buffers to store ADC Data*/
 
-/* Data to send to target */
-uint8_t gTxData[MAX_DATA_SIZE] = {0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, \
-                                  0x00,0x11,0x22,0x33,0x44,0x55, \
-                                  0x66,0x77,0x88,0x99,0x12,0x23, \
-                                  0x34,0x45,0x56,0x67,0x78,0x89};
+uint8_t gTxData[MAX_DATA_SIZE] = {0} ;
 
+/*
+Scans all the addresses of the peripherals:
+*/
+void I2C_scanBus() {
+    printf("Scanning I2C Bus...\n");
 
+    // **Step 1: Reset I2C Controller if Busy**
+    if (DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS) {
+        printf("I2C Bus Busy! Resetting I2C Controller...\n");
+        DL_I2C_disableController(I2C_controller_INST);  // Disable I2C
+        delay_cycles(20000);
+        DL_I2C_enableController(I2C_controller_INST);   // Re-enable I2C
+        delay_cycles(20000);
+    }
+
+    // **Step 2: Scan I2C Bus**
+    for (uint8_t addr = 0x08; addr < 0x78; addr++) {  // Valid I2C Address Range
+        DL_I2C_startControllerTransfer(I2C_controller_INST, addr, DL_I2C_CONTROLLER_DIRECTION_RX, 1);
+        delay_cycles(5000);
+        
+        if (!(DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_ERROR)) {
+            printf("Device found at: 0x%02X\n", addr);
+        }
+    }
+
+    printf("I2C Scan Complete!\n");
+}
 
 /*
 Multiplexer TCA9548A:
@@ -88,99 +193,573 @@ there is only 1 register needed, and the controller merely writes the register d
 void Multiplexer_SelectChannel(uint8_t channel)
 {
     uint8_t data = channel;
-    printf("Scanning I2C Bus...\n");
+    printf("Selecting Multiplexer 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);
 
-    // Attempt to send START and the device address
+    // SEND Command to Multiplexer
     DL_I2C_startControllerTransfer(I2C_controller_INST, MULTIPLEXER_I2C_ADDR, DL_I2C_CONTROLLER_DIRECTION_TX, 1);
+    DL_I2C_fillControllerTXFIFO(I2C_controller_INST, &data, 1);
 
-    // Wait for a response from the multiplexer
+    // **Ensure STOP condition is sent**
     while (DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS);
 
-    // Send the channel selection byte
-    DL_I2C_fillControllerTXFIFO(I2C_controller_INST, &data, 1);
+    // **Slightly Increase Delay for Multiplexer to Process Command**
+    delay_cycles(30000); 
+
+    // Verify Multiplexer Response:
+    uint8_t response= 0x00;
+    DL_I2C_startControllerTransfer(I2C_controller_INST, MULTIPLEXER_I2C_ADDR, DL_I2C_CONTROLLER_DIRECTION_RX, 1);
+
+    // Wait for a response from the multiplexer
+    while (DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS);
+    response = DL_I2C_receiveControllerData(I2C_controller_INST);
 
+    // **Debug: Print Expected vs. Received Response**
+    printf("Multiplexer Response: 0x%02X (Expected: 0x%02X)\n", response, data);
+    
     // **CHECK FOR ADDRESS ACKNOWLEDGMENT**
-    if (!(DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_ERROR)) {
+    /*if (!(DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_ERROR)) {
         printf("Multiplexer detected at 0x70.\n");
         return;
     } else{
         printf("ERROR: Multiplexer (0x70) detected.\n");
-    }
+    }*/
 
     // Wait for transaction completion
+    //while (DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS);
+
+    if(response != data){
+        printf("ERROR: Multiplexer did not set the correct channel!\n");
+        // **Retry Mechanism: Attempt to Set the Channel Again**
+        delay_cycles(10000);
+        Multiplexer_SelectChannel(channel);
+    } else {
+        printf("Multiplexer Active Channel: 0x%X\n", data);
+    }
+}
+
+
+/*
+CONFIGURATION REGISTER:
+8-bit wide configuration register to select for: input channel, conversion mode, conversion rate, and PGA gain. 
+Device allows the user to changethe operating condition of the device:
+
+*/
+
+uint8_t Construct_Config_Byte(uint8_t channel, uint8_t resolution, bool continuous, uint8_t gain) {
+
+    uint8_t config = 0;
+
+    
+    config |= ((channel - 1) << 5);  // Channel Selection (Bits 6-5)
+
+    if (continuous) config |= (1 << 4);  // Continuous Mode (Bit 4)
+
+    switch (resolution) {
+        case 12: config |= (0b00 << 2); break;
+        case 14: config |= (0b01 << 2); break;       
+        case 16: config |= (0b10 << 2); break;
+        case 18: config |= (0b11 << 2); break;
+        default: printf("ERROR: Invalid Resolution!\n"); return 0;
+    }
+
+    switch (gain) {
+        case 1: config |= (0b00); break;
+        case 2: config |= (0b01); break;
+        case 4: config |= (0b10); break;
+        case 8: config |= (0b11); break;
+        default: printf("ERROR: Invalid Gain!\n"); return 0;
+    }
+
+    return config;
+}
+
+/* Tansmit Data from MCU to ADC:  Function to SET configuration to ADC over I2C*/
+
+void SetConfiguration(uint8_t channel, uint8_t resolution, bool mode, uint8_t gain) {
+    // **Step 1: Construct Configuration Byte**
+    uint8_t config_byte = Construct_Config_Byte(channel, resolution, mode, gain);
+
+    printf("Writing Config: 0x%02X to ADC (0x%X)...\n", config_byte, DEF_TARGET_ADDR_ADC);
+
+    // **Step 2: Wait for I2C Bus to be Free**
     while (DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS);
 
-    // Verify if the multiplexer accepted the command
-    printf("Checking the Multiplexer Configuration.\n");
+    // **Step 3: Start I2C Write Transaction**
+    DL_I2C_startControllerTransfer(I2C_controller_INST, DEF_TARGET_ADDR_ADC, DL_I2C_CONTROLLER_DIRECTION_TX, 1);
 
-    uint8_t response;
-    DL_I2C_startControllerTransfer(I2C_controller_INST, MULTIPLEXER_I2C_ADDR, DL_I2C_CONTROLLER_DIRECTION_RX, 1);
+    // **Step 4: Load Configuration Byte into TX FIFO**
+    DL_I2C_fillControllerTXFIFO(I2C_controller_INST, &config_byte, 1);
+
+    // **Step 5: Ensure STOP Condition is Sent**
+    while (DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS);
+    printf("Configuration Byte: 0x%02X\n", config_byte);
+    printf("Configuration Sent Successfully!\n");
+}
+
+/*Function to get the RDY bit from ADC*/
+
+bool Check_ADC_Ready()
+{
+    uint8_t config_byte = 0;
+
+    /*
+    READY BIT:
+    This bit is the data ready flag. In read mode, this bit indicates if the output register has been updated
+    with a latest conversion result. In One-Shot Conversion mode, writing this bit to “1” initiates a new
+    conversion.
+
+    1= Output Register has not been updated
+    0= Output Register has been updated
+
+    */
+
+    DL_I2C_startControllerTransfer(I2C_controller_INST, DEF_TARGET_ADDR_ADC, DL_I2C_CONTROLLER_DIRECTION_RX, 1);
+    config_byte = DL_I2C_receiveControllerData(I2C_controller_INST);
+    return (config_byte & 0x80) == 0;  // Check if RDY bit is cleared in bit 7
+
+}
+
+
+/*
+Function to read ADC DATA: This function simply retrieves the ADC raw digital output as 16-bit signed integer. 
+* The value returned is not yet converted to VOLTAGE.
+* adc_data[2]: Buffer with an array of size 2, to store two bytes of ADC data. 
+*             Since, the ADC output consists of two 8-bit bytes:
+*             - adc_data[0] (MSB)
+*             - adc_data[1] (LSB)
+* Next, we verify if the the I2C bus is busy using the function in the driverlib: DL_I2C_get ControllerStatus
+*       - Prevents collisions by ensuring no two I2C device is using the same bus before initializing.
+* BEGIN I2C READ operation to request 2 bytes from the ADC-> DL_I2C_startControllerTransfer()
+* Parameters:
+    - I2C_controller_INST: Refererence to the I2C instance bring used.
+    - DEF_TARGET_ADDR_ADC: Address of the ADC
+    - DL_I2C_CONTROLLER_DIRECTION_RX: Indicates that we want to receive the data from ADC
+    - 2: Specifies that we expect 2 bytes from the ADC
+* WAIT for the data to be received: (DL_I2C_getControllerStatus())
+    - Waits until the ADC sends the data over I2C.
+    - Ensures that the data transfer is complete before proceeding.
+* READ the two bytes of ADc Data:
+    - adc_data[0] : MSB
+    - adc_data[1] : LSB
+    - adc_data[2] : config_bytes
+    ADC sends its 16-bit value in two parts over 8-bit I2C data frames.
+* COMBINE the two bytes into 16-bit Integer:
+    - Shifts the MSB(first byte) left by 8 bits to make space for LSB.
+    - Performs a bitwise OR operation to combine MSB and LSB into a single 16-bit number.
+* PRINT HEXADEC and DECIMAL format for DEBUGGING.
+* Output code is in binary and is proportional to the Input Voltage and PGA settings.
+* From the datasheet: https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/22226a.pdf
+    - Equation 4.4 is being used to convert the output codes to input voltage
+*/
+
+int16_t Read_ADC_Data(uint8_t resolution)
+{
+    uint8_t adc_data[3] = {0};  // Buffer for ADC data (MSB, LSB, Config Byte)
+    int16_t raw_adc = 0;
+    
+    printf("Reading ADC Data from MCP3428...\n");
 
     while (DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS);
+
+    // Determine bytes to read
+    printf("Resolution for reading ADC is %d\n", resolution);
+
+    delay_cycles(10000);
+
+    // Request 3 Bytes from ADC**
+    DL_I2C_startControllerTransfer(I2C_controller_INST, DEF_TARGET_ADDR_ADC, DL_I2C_CONTROLLER_DIRECTION_RX, 3);
+
+    // Read Data into Buffer**
+    int i = 0;
+    while(i<3){
+        while (DL_I2C_isControllerRXFIFOEmpty(I2C_controller_INST));
+        printf("Loop no: %d\n",i);
+        while (DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS);
+        adc_data[i] = DL_I2C_receiveControllerData(I2C_controller_INST);
+        printf("Received Byte[%d]: 0x%02X\n", i, adc_data[i]);
+        i++;
+    }
+    newMeasurementAvailable = true;
+
+    /*Combining MSB and LSB for ADC output*/
+    raw_adc= adc_data[0] << 8 | adc_data[1];
+    printf("Raw ADC Value: 0x%0X (%d)\n", raw_adc, raw_adc);
+    //printf("Resolution: %d \n", resolution_bits );
+    return raw_adc;
    
-    response = DL_I2C_receiveControllerData(I2C_controller_INST);
+}
 
-    if(response != channel){
-        printf("ERROR: Multiplexer did not set the correct channel!\n");
-    } else {
-        printf("Multiplexer Active Channel: 0x%X\n", channel);
+
+/* Function to Convert ADC Reading to Voltage */
+float Convert_ADC_To_Voltage(int16_t adc_value, uint8_t resolution, uint8_t gain) {
+    if (!newMeasurementAvailable) 
+    { return -1; }
+    float voltage= 0;
+    float LSB= 0;
+    uint32_t max_adc_value= 1;
+
+     switch (resolution) {
+        case 12:  // 12-bit
+            max_adc_value = 2048;
+            break;
+        case 14:  // 14-bit
+            max_adc_value = 8192;
+            break;
+        case 16:  // 16-bit
+            max_adc_value = 32768;
+            break;
+        case 18:  // 18-bit
+            max_adc_value = 131072;
+            break;
+        default:
+            printf("Error: Unknown ADC Resolution!\n");
+            return 0.0;
     }
+
+    /*Considering that MSB is always 0*/
+    printf("Max Resolution %d\n", max_adc_value);
+    LSB= ((VREF)/max_adc_value);
+    printf("LSB: %f\n", LSB);
+    float inputVoltage= ((float)adc_value*(LSB/gain));
+
+    
+    /*Formula for ADC to Voltage Conversion*/
+    /*voltage = ((float)adc_value / max_adc_value) * VREF;
+   
+    printf("Converted Voltage: %.2f V\n", voltage);*/
+
+    printf("Input Voltage Measured: %.2f V\n", inputVoltage);
+
+    /*To send the voltage to Pi in milliVolts*/
+    uint16_t voltage_mV= inputVoltage * 1000;
+
+    /*Storing ADC voltages in mVolts */
+    registers[ADC_REGISTER] = (voltage_mV>>8) & 0xFF; //Highest Byte
+    registers[ADC_REGISTER + 1] = (voltage_mV) & 0xFF; //Lowest Byte
+    newMeasurementAvailable = false;
+    printf("ADC Voltage Stored %d mV in MCU: MSB= 0x%02X, LSB= 0x%02X\n", voltage_mV, registers[ADC_REGISTER], registers[ADC_REGISTER + 1]);
+    return voltage;
 }
 
+/*
+DAC Configuration function: Tx to DAC channel
+DAC expects 3 bytes from the channel:
+Byte 0: write command + channel_selection
+Byte 1: configuration + high byte of DAC
+Byte 2: low byte of DAC
+*/
+/*bool SET_CHANNEL_VALUE(DAC_CH ch, uint16_t new_value, VREF_SELECTION new_vref, GAIN_SELECTION new_gain, PWR_DOWN_SELECTION new_pwr_dwn, bool udac){
+    uint8_t output_buffer[8];
+
+    //Build the setter header (Address) -> 01000 DAC0 DAC1 DAC2
+
+    uint8_t channel_write_cmd = FAST_WRITE_COMMAND; //0x00; FAST write mode
+    //channel_write_cmd |= (ch << 1); //SET DAC channel
+    //channel_write_cmd|= udac; // if udac is SET to 0; VOUT is updated after the 4th byte's ACK is issued
+
+    output_buffer[0]= channel_write_cmd;
+
+    // Construct the 12bit DAC value with the configuration settings
+    // For Fast write command it does not gives VREF:
+    // PD1 PD2 Gx D11 D10 D9 D8 [Byte 1]
+    // D7 D6 D5 D4 D3 D2 D1 D0 [Byte 2]
+
+    //new_value &= 0x0FFF; //Ensure only 12 bits are set
+    //new_value |= (new_vref << 15);
+    new_value |= (new_pwr_dwn << 13);
+    //new_value |= (new_gain << 12);
+    new_value |= new_value<< 9;
+    new_value |= new_value<< 8;
+
+    output_buffer[1]= new_value >> 8; //Upper Byte
+    output_buffer[2]= new_value & 0xFF; //Lower Byte
+
+    //Send the data via I2C:
+    if (DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS){
+        printf("I2C Bus is busy! Retry..\n");
+        return false;
+    }
+
+    //start I2C transmission:
+    DL_I2C_startControllerTransfer(I2C_controller_INST, DEF_TARGET_ADDR_DAC, DL_I2C_CONTROLLER_DIRECTION_TX, 3);
+    DL_I2C_fillControllerTXFIFO(I2C_controller_INST, output_buffer, 3);
+
+    while (DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS);
+
+    if (DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_ERROR) {
+        printf("I2C Write Error: Failed to write to DAC!\n");
+        return false;  // Return failure if there was an error
+    }
+
+    return true;
+}*/
+
+/**Function for FAST write command, sending values over I2c to every channel of DAC**/
+
+bool fastWrite(uint16_t channel_a_value){
+
+    /*DAC has a 12 bit resolution that ranges from 0 to 4095.
+    0x00: sets the Power Mode to NORMAL for Channel A
+    (channel_a_value >> 8): shifts the value to 8 places right and gives upper 4 bits
+    */
+
+    uint8_t output_buffer[8];
+
+    output_buffer[0]= (0x00)|(channel_a_value >> 8)&0x0F;
+    //output_buffer[0] = channel_a_value >> 8;
+    output_buffer[1]= channel_a_value & 0xFF;
+
+    output_buffer[2]= 0x40; // Power down for the other channels
+    output_buffer[3]= 0x00; 
+
+    output_buffer[4]= 0x40;
+    output_buffer[5]= 0x00;
+
+    output_buffer[6]= 0x40;
+    output_buffer[7]= 0x00;
+
+    if (DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_ERROR) {
+        printf("I2C Write Error: Failed to write to DAC channels for FAST write mode!\n");
+        return false;  // Return failure if there was an error
+    }
+
+    // **Wait for I2C Bus to be Free**
+    while (DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS);
+
+    // **Start I2C Write Transaction**
+    DL_I2C_startControllerTransfer(I2C_controller_INST, DEF_TARGET_ADDR_DAC, DL_I2C_CONTROLLER_DIRECTION_TX, 8);
+
+    // **Step 4: Load Configuration Byte into TX FIFO**
+    for (uint8_t i=0; i < 8; i++){
+        DL_I2C_fillControllerTXFIFO(I2C_controller_INST, &output_buffer[i], 1);
+
+    }
+
+    // **Ensure STOP Condition is Sent**
+    while (DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS);
+    printf("DAC Fast write Successful!\n");
+    return true;
+
+}
+
+/*void readRegisters(){
+
+    uint8_t data[24];
+    uint8_t channel;
+    bool isEeprom;
+
+    printf("Reading MCP4728 Registers...\n");
+
+    // ** Request 24 Bytes from MCP4728 over I2C **
+    DL_I2C_startControllerTransfer(I2C_controller_INST, DEF_TARGET_ADDR_DAC, DL_I2C_CONTROLLER_DIRECTION_RX, 24);
+
+    for (int i = 0; i < 24; i++) {
+        while (DL_I2C_isControllerRXFIFOEmpty(I2C_controller_INST));
+        data[i] = DL_I2C_receiveControllerData(I2C_controller_INST);
+    }
+
+    // ** Process the Received Data (8 Iterations for 4 Channels) **
+    for (uint8_t i = 0; i < 8; i++) {
+        isEeprom = i % 2; // Even indices: Register, Odd indices: EEPROM
+        //Extract channel:
+        uint8_t ch= (data[0] & 0x30)>>4;
+
+        if (isEeprom) {
+            read_eep_[ch].vref = (VREF_SELECTION) ((data[i * 3 + 1] & 0b10000000) >> 7);
+            read_eep_[ch].pd   = (PWR_DOWN_SELECTION) ((data[i * 3 + 1] & 0b01100000) >> 5);
+            read_eep_[ch].gain = (GAIN_SELECTION) ((data[i * 3 + 1] & 0b00010000) >> 4);
+            read_eep_[ch].data = (uint16_t) ((data[i * 3 + 1] & 0b00001111) << 8 | data[i * 3 + 2]);
+        } else {
+            read_reg_[ch].vref = (VREF_SELECTION) ((data[i * 3 + 1] & 0b10000000) >> 7);
+            read_reg_[ch].pd   = (PWR_DOWN_SELECTION) ((data[i * 3 + 1] & 0b01100000) >> 5);
+            read_reg_[ch].gain = (GAIN_SELECTION) ((data[i * 3 + 1] & 0b00010000) >> 4);
+            read_reg_[ch].data = (uint16_t) ((data[i * 3 + 1] & 0b00001111) << 8 | data[i * 3 + 2]);
+        }
+    }
+
+    printf("MCP4728 Registers Read Successfully!\n");
+}
+*/
+//The device updates all DAC analog output(vout) at the same time
+
+/*void update_DAC_Output() {
+    uint8_t general_call_command = 0x08;  // General Call Update Command
+
+    // Start I2C transaction
+    DL_I2C_startControllerTransfer(I2C_controller_INST, DEF_TARGET_ADDR_DAC, DL_I2C_CONTROLLER_DIRECTION_TX, 1);
+    DL_I2C_fillControllerTXFIFO(I2C_controller_INST, &general_call_command, 1);
+    
+    while (DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS);
+
+    printf("DAC Outputs Updated via General Call Software Update!\n");
+}*/
+
+/*
+DAC Function: 
+-12 bit Voltage Output DAC with Four Buffered outputs.
+-Using Internal VREF (2.048V):
+    - Output voltage range:
+    - 0.000V to 2.048V with Gain setting= 1
+    - 0.000V to 4.096V with Gain setting= 2
+- User can select internal reference or external voltage (VDD) for each channel
+- VOUTA: Buffered analog voltage of Channel A.
+- Channel Selection bits: 0x00 for Channel A
+*/
+
+
+/*int16_t read_DAC_Output()
+{
+    readRegisters(); //Read current register DAC values
+    uint16_t dac_a = read_reg_[DAC_A].data;
+    uint16_t dac_b = read_reg_[DAC_B].data;
+    uint16_t dac_c = read_reg_[DAC_C].data;
+    uint16_t dac_d = read_reg_[DAC_D].data;
+
+    printf("DAC Output Digital Values: A=%d, B=%d, C=%d, D=%d\n", 
+           dac_a, dac_b, dac_c, dac_d);
+    return dac_a;
+}
+
+float get_DAC_Output_Voltage(DAC_CH channel){
+    if(channel< DAC_A || channel> DAC_D){
+        printf("Error: Invalid DAC channel!\n");
+        return -1.0;
+    }
+    uint16_t dac_value = read_reg_[channel].data;
+    VREF_SELECTION vref = read_reg_[channel].vref;
+    GAIN_SELECTION gain = read_reg_[channel].gain;
+
+    //GET correct VREF value:
+    float vref_value= (vref==VREF_INTERNAL)? 2.048: 3.3;
+    uint8_t gain_factor= (gain==GAIN_X2)? 2: 1;
+
+    // Calculate Output Voltage
+    float vout = ((float)dac_value / 4095.0) * vref_value * gain_factor;
+
+    printf("DAC Channel %d - Digital Value: %d, VOUT: %.3fV\n", channel, dac_value, vout);
+    return vout;
+
+}*/
+
+/**Function to call DAC*/
+/*void get_Analog_Output(){
+    bool success= fastWrite(2048, 0, 0, 0);
+    if(!success){
+        printf("Error: DAC Fast Write Failed.\n");
+        return;
+    }
+
+    update_DAC_Output();
+    read_DAC_Output();
+
+    float vout_a= get_DAC_Output_Voltage(DAC_A);
+    float vout_b= get_DAC_Output_Voltage(DAC_B);
+    float vout_c= get_DAC_Output_Voltage(DAC_C);
+    float vout_d= get_DAC_Output_Voltage(DAC_D);
+
+    printf("\nMeasured DAC output Voltages:\n");
+    printf("Channel A: %.2f V\n", vout_a);
+    printf("Channel B: %.2f V\n", vout_b);
+    printf("Channel C: %.2f V\n", vout_c);
+    printf("Channel D: %.2f V\n", vout_d);
+}
+*/
+
+/*
+Function to initialize MCU as target: Pi communicates as the Controller and MCU as the Target
+*/
+
+void I2C_Target_Init(void) {
+    // Set the target address
+    DL_I2C_setTargetOwnAddress(I2C_target_INST, I2C_target_TARGET_OWN_ADDR);
+
+    // Enable target mode
+    DL_I2C_enableTarget(I2C_target_INST);
+
+
+    /* Enable relevant I2C interrupts */
+    DL_I2C_enableInterrupt(I2C_target_INST, DL_I2C_INTERRUPT_TARGET_START);
+    DL_I2C_enableInterrupt(I2C_target_INST, DL_I2C_INTERRUPT_TARGET_RXFIFO_TRIGGER);
+    DL_I2C_enableInterrupt(I2C_target_INST, DL_I2C_INTERRUPT_TARGET_TXFIFO_TRIGGER);                                        
+    DL_I2C_enableInterrupt(I2C_target_INST, DL_I2C_INTERRUPT_TARGET_STOP);
+    
+}
+
+
+/*
+MAIN function:
+*/
 
 int main(void)
 {
+    // **Step 1: Initialize System and I2C**
     SYSCFG_DL_init();
-
     printf("............System Configuration Enabled...............\n");
 
-    
-    /* Multiplexer Section */
-    printf("Selecting Multiplexer Channel...\n");
 
+    // **Step 2: Select ADC Channel via Multiplexer**
+    printf("Selecting Multiplexer Channel...\n");
     Multiplexer_SelectChannel(ADC_I2C_CHANNEL);
-    
-    NVIC_EnableIRQ(I2C_controller_INST_INT_IRQN);
-
+    I2C_scanBus();
+    // **Step 3: Enable I2C Interrupts**
+    //NVIC_EnableIRQ(I2C_controller_INST_INT_IRQN);
+    //NVIC_EnableIRQ(I2C_target_INST_INT_IRQN);
     I2C_init(&gI2C);
 
-    /* Default CommandInfo Object */
-    I2C_CommandInfo CommandInfo_Obj;
+    gTxCount = 0;
+    gTxLen   = REGISTER_SIZE;
+    gRxCount = 0;
+    gRxLen   = REGISTER_SIZE;
 
-    CommandInfo_Obj.targetAddr = DEF_TARGET_ADDR;
-    CommandInfo_Obj.commandType = READ_COMMAND;
-    CommandInfo_Obj.addr = 0x20207C00;
-    CommandInfo_Obj.dataArray = &gTxData[0];
-    CommandInfo_Obj.dataSize = 8;
-    CommandInfo_Obj.crcEnable = false;
+    // **Step 4: Configure ADC (Example: CH1, 16-bit, Continuous Mode, Gain x1)**
+    uint8_t channel= 4;
+    uint8_t resolution= 16;
+    bool continuous= 1;
+    uint8_t gain= 1;
+    printf("Configuring ADC...\n");
 
-    gCommand = CommandInfo_Obj;
+    //**Set Configuration Register for ADC**
+    SetConfiguration(channel, resolution, continuous, gain);  // CH1, 16-bit, Continuous mode, Gain x1
 
-    while(1)
+    while (1)
     {
-        if(gSendCommand == true)
-        {
-            //Add a delay to allow conversion time (~1ms)
-            delay_cycles(50000);  // Adjust if needed
-
-            //Frames a command packet and sends it to Target through I2C Write Command
-            I2C_sendCommand(&gI2C, (I2C_CommandInfo *) &gCommand);
-            printf("Requesting ADC Data from I2C address: 0x%X\n", gCommand.targetAddr);
-            gI2C.status = I2C_STATUS_RX_STARTED;
-            gI2C.rxMsg.ptr = 0;
-            gI2C.dataLen = gCommand.dataSize;
-            // Issues I2C Read Command to get the response from Target 
-            I2C_getResponse(&gI2C,gCommand.targetAddr);
-            gSendCommand = false;
-        }
-
+        // Read ADC Value and DAC values:
+        int16_t adc_value = Read_ADC_Data(resolution);
+        Convert_ADC_To_Voltage(adc_value, resolution, gain); 
+        delay_cycles(10000); 
+        fastWrite(3300);
+
+        //Add Delay for Next Conversion**
+        delay_cycles(100000);
     }
 }
 
-/*Interrupt for MCU -> ADC*/
+/*Interrupt for MCU -> ADC
+* CASE: DL_I2C_IIDX_CONTROLLER_RX_DONE: ADC Reception Complete
+    - ADC has finished sending data and it's fully received.
+    - gI2C.rxMsg.len = gI2C.rxMsg.ptr:
+        - Stores the received data length in the response buffer.
+    - I2C_decodeResponse():
+        - Decodes the received response.
+    - 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
+* 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)
+    - 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);
+
+*/
 void I2C_controller_INST_IRQHandler(void)
 {   printf("I2C Interrupt Triggered to ADC!\n");
     switch (DL_I2C_getPendingInterrupt(I2C_controller_INST)) 
@@ -207,11 +786,10 @@ void I2C_controller_INST_IRQHandler(void)
                     gI2C.rxMsg.buffer[gI2C.rxMsg.ptr++] =
                         DL_I2C_receiveControllerData(I2C_controller_INST);
                         if(gI2C.rxMsg.ptr>0){
-                            printf("Received Byte[%d]: 0x%02X\n", gI2C.rxMsg.ptr, gI2C.rxMsg.buffer[gI2C.rxMsg.ptr - 1]);
+                            //printf("Received Byte[%d]: 0x%02X\n", gI2C.rxMsg.ptr, gI2C.rxMsg.buffer[gI2C.rxMsg.ptr - 1]);
 
                         }
-                        
-                    
+                                      
                 } 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 */
@@ -232,13 +810,104 @@ void I2C_controller_INST_IRQHandler(void)
 
         case DL_I2C_IIDX_CONTROLLER_ARBITRATION_LOST:
             printf("Interrupt index for I2C controller Arbitration Lost!\n");
+            break;
         case DL_I2C_IIDX_CONTROLLER_NACK:
-            printf("Interrupt index for Address/Data NACK!\n");
-            gI2C.status = I2C_STATUS_ERROR;
-            break; 
+            printf("I2C NACK Received\n");
+            break;
         default:
             break;
     }
 }
 
+void I2C_target_INST_IRQHandler(void) {
+
+    static bool DataRx= false;
+    static uint16_t registerAddress=0;
+
+    printf("I2C Interrupt Triggered to MCU (TARGET)!\n");
+
+    uint32_t status = DL_I2C_getPendingInterrupt(I2C_target_INST);
+    switch (status) {
+
+        /* START condition detected */
+        case DL_I2C_IIDX_TARGET_START:
+            printf("START condition detected.\n");
+            gTxCount= 0;
+            gRxCount= 0;
+            DataRx= false;
+            DL_I2C_flushTargetTXFIFO(I2C_target_INST);
+            break;
+
+        /* STOP condition detected */
+        case DL_I2C_IIDX_TARGET_STOP:
+            printf("STOP condition detected.\n");
+            if (DataRx == true){
+                printf("Data received from Pi: ");
+                for (uint8_t i = 0; i < gRxCount; i++) {
+                    printf("0x%02X ", gRxBuffer[i]);
+
+                }
+                printf("\n");
+                DataRx= false;
+            }
+            DL_I2C_flushTargetTXFIFO(I2C_target_INST);
+            break;
+
+        /* RX FIFO trigger (Pi is writing data to MCU) */
+        case DL_I2C_IIDX_TARGET_RXFIFO_TRIGGER:
+            printf("receiving data from Pi.\n");
+            DataRx= true;
+            while (!DL_I2C_isTargetRXFIFOEmpty(I2C_target_INST)) {
+                if (gRxCount == 0) {
+                    // First byte received is the register address
+                    registerAddress = DL_I2C_receiveTargetData(I2C_target_INST);
+                    printf("Register Address Set: 0x%02X\n", registerAddress);
+                } 
+                else if (registerAddress < REGISTER_SIZE) {
+                    //Storing the received data from the controller correctly
+                    registers[registerAddress] = DL_I2C_receiveTargetData(I2C_target_INST);
+                    printf("Stored 0x%02X in Register 0x%02X\n", registers[registerAddress], registerAddress);
+                    //gRxBuffer[gRxCount++] = DL_I2C_receiveTargetData(I2C_0_INST);
+
+                } 
+                else {
+                    printf("ERROR: RX Buffer Overflow!\n");
+                    break;
+                }
+                gRxCount++;
+            }
+            break;
+
+         /* TX FIFO trigger (Pi is reading data from MCU) */
+        case DL_I2C_IIDX_TARGET_TXFIFO_TRIGGER:
+            printf("transmitting data to Pi...\n");
+            if (!DL_I2C_isTargetTXFIFOFull(I2C_target_INST)) {
+
+                if (registerAddress < REGISTER_SIZE) {
+                    //DL_I2C_fillTargetTXFIFO(I2C_0_INST, &gTxBuffer[gTxCount], 1);
+                    // Retrieve stored value from the correct register
+                    uint8_t value = registers[registerAddress];
+                    uint8_t value_test[2] = { 0x01, 0x03 };
+                    DL_I2C_fillTargetTXFIFO(I2C_target_INST, &value_test[0], 2);
+                    printf("Sending to 0x%02X: 0x%02X\n", registerAddress, value);  // Debugging
+                } else {
+                    // **Fix: Avoid infinite while loop**
+                    printf("WARNING: TX Buffer Underflow! Sending default value.\n");
+                    DL_I2C_fillTargetTXFIFO(I2C_target_INST, (uint8_t[]){0x00}, 1);
+                    break;
+                }
+            }
+            break;
+
+        /* Arbitration lost or NACK */
+        case DL_I2C_IIDX_TARGET_ARBITRATION_LOST:
+        default:
+            printf("Unknown Interrupt.\n");
+            break;
+    }
+}
+
+
+
+
 

+ 4 - 4
charge_controller_v7/i2c_controller.syscfg

@@ -28,8 +28,8 @@ I2C1.advAnalogGlitchFilter             = "DISABLED";
 I2C1.intController                     = ["ARBITRATION_LOST","NACK","RXFIFO_TRIGGER","RX_DONE","TX_DONE"];
 I2C1.$name                             = "I2C_controller";
 I2C1.basicTargetAddress                = 0x48;
-I2C1.peripheral.sdaPin.$assign         = "PB3";
-I2C1.peripheral.sclPin.$assign         = "PB2";
+I2C1.peripheral.sdaPin.$assign         = "PA16";
+I2C1.peripheral.sclPin.$assign         = "PA15";
 I2C1.sdaPinConfig.$name                = "ti_driverlib_gpio_GPIOPinGeneric0";
 I2C1.sdaPinConfig.hideOutputInversion  = scripting.forceWrite(false);
 I2C1.sdaPinConfig.onlyInternalResistor = scripting.forceWrite(false);
@@ -45,10 +45,10 @@ I2C1.sclPinConfig.internalResistor     = "PULL_UP";
 
 I2C2.$name                             = "I2C_target";
 I2C2.basicEnableTarget                 = true;
-I2C2.basicTargetAddress                = 0x48;
 I2C2.enableDMAEvent1                   = false;
 I2C2.enableDMAEvent2                   = false;
-I2C2.intTarget                         = ["RXFIFO_TRIGGER","START","STOP"];
+I2C2.basicTargetAddress                = 0x48;
+I2C2.intTarget                         = ["RXFIFO_TRIGGER","START","STOP","TXFIFO_TRIGGER"];
 I2C2.peripheral.$assign                = "I2C0";
 I2C2.peripheral.sdaPin.$assign         = "PA0";
 I2C2.peripheral.sclPin.$assign         = "PA1";

+ 4 - 0
charge_controller_v7/ti/comm_modules/i2c/controller/i2c_comm_controller.c

@@ -375,3 +375,7 @@ void I2C_decodeResponse(I2C_Instance *I2C_handle,I2C_ResponseInfo *response)
         response->frame.crc = u16(&I2C_handle->rxMsg.buffer[I2C_handle->rxMsg.len - CRC_SIZE]);
     }
 }
+
+
+
+

+ 2 - 2
charge_controller_v7/ti/comm_modules/i2c/controller/i2c_comm_controller.h

@@ -104,8 +104,8 @@ extern "C" {
 
 /*! I2C Target Addr configured in the example */
 /*! @brief Default Target Address */
-#define DEF_TARGET_ADDR             (0x68)
-
+#define DEF_TARGET_ADDR_ADC             (0x68)
+#define DEF_TARGET_ADDR_DAC             (0x60)
 
 
 

Některé soubory nejsou zobrazeny, neboť je v těchto rozdílových datech změněno mnoho souborů