فهرست منبع

main function to handle the target interrupts from MCU, handle Controller interrupts to read ADC values

namrota ghosh 11 ماه پیش
والد
کامیت
6370048b62
1فایلهای تغییر یافته به همراه181 افزوده شده و 0 حذف شده
  1. 181 0
      src/target_main.c

+ 181 - 0
src/target_main.c

@@ -0,0 +1,181 @@
+/*include configuration libraries*/
+#include "src/interfaces/mcu_slave_interface.h"
+#include "ti/driverlib/m0p/dl_core.h"
+#include "ti_msp_dl_config.h"
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <ti/drivers/GPIO.h>
+//adc peripheral
+#include "src/peripherals/adc/adc.h"
+#include "src/peripherals/adc/adc_interface.h"
+// mux peripheral
+#include "src/peripherals/mux/multiplexer.h"
+#define DELAY_CYCLE  (5000)
+//i2c:
+#include "ti/comm_modules/i2c/controller/i2c_comm_controller.h"
+//battery:
+#include "src/battery_data/battery.h"
+
+I2C_Instance gI2C;
+I2C_ResponseInfo gResponse;
+
+volatile bool mcuCommandPending= 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.
+    - 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)) { /*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 Main MCU to Target MCU ****/
+void I2C_target_INST_IRQHandler(void) {
+
+  uint32_t status = DL_I2C_getPendingInterrupt(I2C_target_INST);
+  //printf("status: %d\n", status);
+  switch (status) {
+  case DL_I2C_IIDX_TARGET_START:
+    DL_I2C_flushTargetTXFIFO(I2C_target_INST);
+    break;
+  case DL_I2C_IIDX_TARGET_STOP:
+    mcuCommandPending= true;
+    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");
+    if (DL_I2C_isTargetRXFIFOEmpty(I2C_target_INST)) {
+      return;
+    }
+    mcuCommandPending= true;
+    break;
+  case DL_I2C_IIDX_TARGET_TXFIFO_TRIGGER:
+    mcuCommandPending= true;
+    //printf("Tx interrupt triggered.\n");
+    break;
+  case DL_I2C_IIDX_TARGET_ARBITRATION_LOST:
+    break;
+  default:
+    break;
+  }
+}
+
+/***Main Function***/
+
+int main(void){
+    SYSCFG_DL_init();
+    Battery_Init();
+    // Reset_I2C_Bus();
+    NVIC_EnableIRQ(I2C_target_INST_INT_IRQN);
+    NVIC_EnableIRQ(I2C_controller_INST_INT_IRQN);
+    // Multiplexer
+    Multiplexer_SelectChannel(I2C_CHANNEL);
+    //I2C Scanning
+    I2C_scanBus();
+    I2C_init(&gI2C);
+
+    while(1){
+        if(mcuCommandPending){
+            mcu_i2c_handle(I2C_target_INST);
+            mcuCommandPending= false;
+            continue;
+        }
+        // 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++) {
+                updateADCReading_multichannel(slot_id, adc_channel);
+            }
+            delay_cycles(DELAY_CYCLE);
+        }
+    }
+}