Parcourir la source

added logic for inter-mcu i2c communication

namrota ghosh il y a 8 mois
Parent
commit
9bc15b3aa8
2 fichiers modifiés avec 109 ajouts et 0 suppressions
  1. 27 0
      src/interfaces/mcu_slave_interface.h
  2. 82 0
      src/mcu_slave_interface.c

+ 27 - 0
src/interfaces/mcu_slave_interface.h

@@ -0,0 +1,27 @@
+//This file is an interface for I2C communication between MSPM0G3507 (Controller) and MSPM0L1304 (Target)
+
+#ifndef MCU_SLAVE_INTERACE_H_
+#include <stdint.h>
+
+// Handles I2C command coming into Target MCU:
+
+typedef enum{
+    CMD_SET_CURRENT= 0x05,
+    CMD_GET_MEASUREMENT= 0x06,
+    CMD_GET_BATTERY_STATE= 0x07,
+    CMD_SET_HOV_CLEAR= 0x08
+}mcu_I2C_command;
+
+//Command structures:
+typedef struct{
+    uint8_t slot_id;
+    int16_t current;
+}SetChargeDischargeCurrent;
+
+typedef struct{
+    uint16_t voltage;
+    int16_t current;
+    uint16_t temperature;
+}BatteryMeasurementData;
+
+#endif

+ 82 - 0
src/mcu_slave_interface.c

@@ -0,0 +1,82 @@
+#include "src/interfaces/mcu_slave_interface.h"
+#include "battery.h"
+#include "dac.h"
+#include "ti/driverlib/dl_i2c.h"
+#include <stdio.h>
+#include <string.h>
+/*Function to Rx and Tx data from Target to Controller*/
+
+void mcu_i2c_handle(I2C_Regs *i2c) {
+  // At this point the code has multiple i2c instances from which we need to
+  // select the right one, passing a pointer as an argument
+  uint8_t receivedCommand = DL_I2C_receiveTargetDataBlocking(i2c);
+  uint8_t tx_buffer[10] = {0};
+  uint8_t rx_buffer[10] = {0};
+  /*Handling GET commands with bitmasking*/
+  // GET command for 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 volatge, current and temperature
+    BatteryMeasurementData battery_measure;
+    // Pointer pointing to the address of the requested battery slot:
+    Battery *battery = &batteries[slot];
+    battery_measure.voltage = battery->voltage;
+    battery_measure.current = battery->current;
+    battery_measure.temperature = battery->temperature;
+    DL_I2C_fillTargetTXFIFO(i2c, tx_buffer, sizeof(BatteryMeasurementData));
+  }
+  // GET command for Battery 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) {
+    // Set charge or discharge current, positive current is for DAC and negative
+    // current is for PWM
+    case CMD_SET_CURRENT: {
+      SetChargeDischargeCurrent set_current;
+      memcpy(&set_current, (const uint8_t *)rx_buffer,
+             sizeof(SetChargeDischargeCurrent));
+      uint8_t slot = set_current.slot_id;
+      int16_t current = set_current.current;
+      if (current > 0) {
+        // Calibrate charge current for DAC, different slots will have different
+        // channels, how to handle that?
+        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) {
+        break;
+      }
+      Battery *battery = &batteries[slot];
+      // clear hov state flag to false:
+      battery->pwm_hov_state = false;
+      break;
+    }
+    }
+  }
+}