浏览代码

working code for adc read and dac write

namrota ghosh 8 月之前
父节点
当前提交
81029cf30f
共有 1 个文件被更改,包括 118 次插入0 次删除
  1. 118 0
      src/i2c_comm/mcu_slave.c

+ 118 - 0
src/i2c_comm/mcu_slave.c

@@ -0,0 +1,118 @@
+/*
+References: https://stackoverflow.com/questions/246127/why-is-volatile-needed-in-c
+
+*/
+
+#include "src/battery_data/battery.h"
+#include "src/peripherals/dac/dac.h"
+#include "src/interfaces/mcu_slave_interface.h"
+#include "ti/driverlib/dl_i2c.h"
+#include "ti_msp_dl_config.h"
+#include <stdio.h>
+#include <string.h>
+
+/*Function to Rx and Tx data from Target to Controller*/
+// The code has multiple i2c instances (multiple MCUs connected) from which we
+// need to select the right one, passing a pointer as an argument
+
+void mcu_i2c_handle(I2C_Regs *i2c) {
+  printf("MCU interrupt triggered\n");
+  uint8_t receivedCommand = DL_I2C_receiveTargetData(i2c);
+  printf("[SLAVE] Received Command: 0x%02X\n", receivedCommand);
+  uint8_t tx_buffer[10] = {0};
+  //changed to volatile variable, so that the compiler cannot optimize the variable out and is forced to do as told by the code
+  volatile uint8_t rx_buffer[10] = {0};
+  /*Handling GET commands with bitmasking*/
+  // GET command for ADC(Battery Measurement): Voltage, Current, Temperature
+  if ((receivedCommand & 0xF0) == 0x60) {
+    uint8_t slot = receivedCommand & 0x0F;
+    if (slot > NUM_SLOTS) {
+      DL_I2C_flushTargetTXFIFO(i2c);
+      return;
+    }
+    // Struct for voltage, current and temperature
+    BatteryMeasurementData battery_measure;
+    // Pointer pointing to the address of the requested battery slot:
+    Battery *battery = &batteries[slot];
+    // take the updated battery measurement from the battery struct and store it
+    // in the battery_measure struct
+    battery_measure.voltage = battery->voltage;
+    battery_measure.current = battery->current;
+    battery_measure.temperature = battery->temperature;
+    // Copying the memory block from battery_measure struct to tx_buffer:
+    memcpy(tx_buffer, &battery_measure, sizeof(battery_measure));
+    DL_I2C_fillTargetTXFIFO(i2c, tx_buffer, sizeof(BatteryMeasurementData));
+    printf("Battery Measurement Sent to MCU. \n");
+    DL_I2C_flushTargetTXFIFO(i2c);
+  }
+  // GET command for Battery Discharge State: 0x00, 0x01, 0x02, 0x03
+  else if ((receivedCommand & 0xF0) == 0x70) {
+    uint8_t slot = receivedCommand & 0x0F;
+    if (slot > NUM_SLOTS) {
+      DL_I2C_flushTargetTXFIFO(i2c);
+      return;
+    }
+    Battery *battery = &batteries[slot];
+    uint8_t discharge_state = battery->condition;
+    DL_I2C_fillTargetTXFIFO(i2c, &discharge_state, 1);
+    while (DL_I2C_transmitTargetDataCheck(i2c, 0x00) != false)
+      ;
+
+  } else{
+        switch(receivedCommand){
+            case CMD_SET_CURRENT:{
+                SetChargeDischargeCurrent set_current;
+                uint8_t rx_index= 0;
+                while(rx_index < sizeof(SetChargeDischargeCurrent)){
+                    if(!DL_I2C_isTargetRXFIFOEmpty(i2c)){
+                        rx_buffer[rx_index]= DL_I2C_receiveTargetData(i2c);
+                        rx_index++;
+                    }
+                }
+                if(rx_index != sizeof(SetChargeDischargeCurrent)){
+                    printf("[MCU target]: Set Charging Current: Incomplete Data.\n");
+                    DL_I2C_flushTargetRXFIFO(i2c);
+                    rx_index= 0;
+                    break;
+                }
+                memcpy(&set_current, (const uint8_t *)rx_buffer, sizeof(SetChargeDischargeCurrent));
+                if (set_current.slot_id < NUM_SLOTS) {
+                    Battery *battery = &batteries[set_current.slot_id];
+                    battery->charge_discharge_current = set_current.current;
+                    // printf("Charge Current:%u\n", battery->charge_discharge_current);
+                }
+                uint8_t slot = set_current.slot_id;
+                int16_t current = set_current.current;
+                printf("Slot id: %d, Current: %d\n", slot, current);
+                if (current > 0) {
+                    // Calibrate charge current for DAC, different slots will have different
+                    // channels, how to handle that?-> ans: with slot_id, since each slots
+                    // will be connected to each channels of the same DAC, address is same
+                    // channels change
+                    DL_GPIO_setPins(GPIO_Battery_Charging_PORT, GPIO_Battery_Charging_PIN_PB4_PIN);
+                    DAC_SingleWrite(current);
+                } else if (current < 0) {
+                    // Calibrate discharge current for PWM
+                    // TODO: PWM function develop
+                    printf("PWM Discharge");
+                } else {
+                    // do nothing, charge or discharge
+                    printf("state is idle");
+                }
+                break;
+            }
+            case CMD_SET_HOV_CLEAR:{
+                uint8_t slot = DL_I2C_receiveTargetDataBlocking(i2c);
+                /*if (slot >= NUM_SLOTS) {
+                }*/
+                Battery *battery = &batteries[slot];
+                // clear hov state flag to false:
+                battery->pwm_hov_state = false;
+                break;
+            }   
+        }
+    }
+} 
+    
+
+