浏览代码

i2c communication interface for the MCU as Controller and Target

namrota ghosh 8 月之前
父节点
当前提交
d9bebc31b6
共有 3 个文件被更改,包括 153 次插入0 次删除
  1. 38 0
      src/interfaces/i2c_controller_interface.h
  2. 85 0
      src/interfaces/i2c_hal.c
  3. 30 0
      src/interfaces/mcu_slave_interface.h

+ 38 - 0
src/interfaces/i2c_controller_interface.h

@@ -0,0 +1,38 @@
+/*
+* This file is an interface file for I2C communication between MCU (Controller) and other peripherals (Target): i2c_hal.c
+* Context:
+* Our current functions in ADC and DAC are tightly coupled with I2C communication. 
+* Need a communication mechanism to isolate the flow of the ADC function from Asynchronous calls.
+* Decision:
+* i2c_controller_interface is a header file which defines what the I2C peripheral does:
+* - i2c READ
+* - i2c WRITE
+* - i2c start controller transfer
+* - i2c enable interrupt
+* - i2c bus wait
+* Consequences:
+* Cleaner platform independent file
+
+Reference:
+- https://www.embeddedrelated.com/showarticle/1596.php
+- https://www.beningo.com/5-tips-for-designing-an-interface-in-c/
+- https://iot.sites.arm.com/open-iot-sdk/libraries/mcu-driver-hal/mcu-driver-hal/pwmout__api_8h_source.html
+*/
+
+#ifndef I2C_INTERFACE_H_
+#define I2C_INTERFACE_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+
+/*
+* Since C does not allows to add functions in typedef struct, however a function pointer can be included in Structure in C. This interface provides a standard features of i2c_hal
+*/
+typedef struct{
+    bool (*write)(uint8_t const TARGET_ADDRESS, const uint8_t *const Data, uint8_t const Data_length);
+    bool (*read) (uint8_t const TARGET_ADDRESS, uint8_t const Data_length);
+} I2C_Interface;
+
+extern I2C_Interface i2c_hal;
+
+#endif

+ 85 - 0
src/interfaces/i2c_hal.c

@@ -0,0 +1,85 @@
+/*
+ * This file implements Hardware Abstraction Layer (HAL) to make the I2C
+ * communication of MSPM0 SDK compatible with ADC (MCP3426/7/8) and DAC
+ * (MCP34728)
+ */
+#include "src/interfaces/i2c_controller_interface.h"
+#include "ti/driverlib/dl_i2c.h"
+#include "ti_msp_dl_config.h"
+#include <stdio.h>
+
+/*
+static function is for implementing Data Hiding, access to the static function
+is restricted to the file where they are declared const keyword for
+'TARGET_ADDRESS' and 'Data_length' makes the variable immutable. const uint8_t *
+const Data: means the pointer to the variable and the value of Data is immutable
+*/
+static bool msp_i2c_write(uint8_t const TARGET_ADDRESS,
+                          const uint8_t *const Data,
+                          uint8_t const Data_length) {
+  // Flush any stale data in TX FIFO:
+  DL_I2C_flushControllerTXFIFO(I2C_controller_INST);
+
+  // **Check if the I2C bus is stuck before WRITE
+  if (DL_I2C_getControllerStatus(I2C_controller_INST) &
+      DL_I2C_CONTROLLER_STATUS_ERROR) {
+    printf("I2C Communication: Bus is stuck!\n");
+    DL_I2C_resetControllerTransfer(I2C_controller_INST); 
+    return false; 
+  }
+  
+  // **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, TARGET_ADDRESS,
+                                 DL_I2C_CONTROLLER_DIRECTION_TX, Data_length);
+
+  // **Load Configuration Byte into TX FIFO**
+  DL_I2C_fillControllerTXFIFO(I2C_controller_INST, (uint8_t *)Data,
+                              Data_length);
+
+  // ** Wait for the I2C Bus to be FREE **
+  while (DL_I2C_getControllerStatus(I2C_controller_INST) &
+         DL_I2C_CONTROLLER_STATUS_BUSY_BUS)
+    ;
+  
+  // **Check if the target address is incorrect
+  
+  if (DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_ADDR_ACK) {
+    printf("I2C Write Error: Target Address not acknowledged!\n");
+    return false;
+  }
+  
+  // Debug for I2C WRITE:
+  //printf("HAL Write: Address=0x%02X, Data Length=%d\n", TARGET_ADDRESS, Data_length);
+
+
+  // **Check for any WRITE error
+  if (DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_ERROR) {
+    printf("I2C Write Error: Bus error after sending data.\n");
+    return false;
+  }
+
+  return true;
+}
+
+static bool msp_i2c_read(uint8_t const TARGET_ADDRESS,
+                         uint8_t const Data_length) {
+
+  while (DL_I2C_getControllerStatus(I2C_controller_INST) &
+         DL_I2C_CONTROLLER_STATUS_BUSY_BUS)
+    ;
+  DL_I2C_startControllerTransfer(I2C_controller_INST, TARGET_ADDRESS,
+                                 DL_I2C_CONTROLLER_DIRECTION_RX, Data_length);
+  DL_I2C_enableInterrupt(I2C_controller_INST,
+                         DL_I2C_INTERRUPT_CONTROLLER_RXFIFO_TRIGGER);
+  return true;
+}
+
+I2C_Interface i2c_hal = {
+    .write = msp_i2c_write,
+    .read = msp_i2c_read,
+};

+ 30 - 0
src/interfaces/mcu_slave_interface.h

@@ -0,0 +1,30 @@
+//This file is an interface for I2C communication between MSPM0G3507 (Controller) and MSPM0L1304 (Target)
+
+#ifndef MCU_SLAVE_INTERACE_H_
+#include <stdint.h>
+#include "ti/driverlib/dl_i2c.h"
+#include "ti_msp_dl_config.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;
+
+void mcu_i2c_handle(I2C_Regs *i2c);
+#endif