|
@@ -1,23 +1,27 @@
|
|
|
/*
|
|
/*
|
|
|
-References: https://stackoverflow.com/questions/246127/why-is-volatile-needed-in-c
|
|
|
|
|
|
|
+References:
|
|
|
|
|
+https://stackoverflow.com/questions/246127/why-is-volatile-needed-in-c
|
|
|
|
|
|
|
|
*/
|
|
*/
|
|
|
|
|
|
|
|
-#include "src/battery_data/battery.h"
|
|
|
|
|
#include "mcu_slave_interface.h"
|
|
#include "mcu_slave_interface.h"
|
|
|
|
|
+#include "src/battery_data/battery.h"
|
|
|
#include "ti/driverlib/dl_i2c.h"
|
|
#include "ti/driverlib/dl_i2c.h"
|
|
|
#include <stdio.h>
|
|
#include <stdio.h>
|
|
|
#include <string.h>
|
|
#include <string.h>
|
|
|
|
|
+#include "src/peripherals/dac/dac.h"
|
|
|
|
|
+
|
|
|
/*Function to Rx and Tx data from Target to Controller*/
|
|
/*Function to Rx and Tx data from Target to Controller*/
|
|
|
// The code has multiple i2c instances (multiple MCUs connected) from which we
|
|
// The code has multiple i2c instances (multiple MCUs connected) from which we
|
|
|
// need to select the right one, passing a pointer as an argument
|
|
// need to select the right one, passing a pointer as an argument
|
|
|
|
|
|
|
|
void mcu_i2c_handle(I2C_Regs *i2c) {
|
|
void mcu_i2c_handle(I2C_Regs *i2c) {
|
|
|
- //printf("MCU interrupt triggered\n");
|
|
|
|
|
|
|
+ printf("MCU interrupt triggered\n");
|
|
|
uint8_t receivedCommand = DL_I2C_receiveTargetData(i2c);
|
|
uint8_t receivedCommand = DL_I2C_receiveTargetData(i2c);
|
|
|
- //printf("[SLAVE] Received Command: 0x%02X\n", receivedCommand);
|
|
|
|
|
|
|
+ printf("[SLAVE] Received Command: 0x%02X\n", receivedCommand);
|
|
|
uint8_t tx_buffer[8] = {0};
|
|
uint8_t tx_buffer[8] = {0};
|
|
|
- //changed to volatile variable, so that the compiler cannot optimize the variable out and is forced to do as told by the code
|
|
|
|
|
|
|
+ // 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[8] = {0};
|
|
volatile uint8_t rx_buffer[8] = {0};
|
|
|
/*Handling GET commands with bitmasking*/
|
|
/*Handling GET commands with bitmasking*/
|
|
|
// GET command for ADC(Battery Measurement): Voltage, Current, Temperature
|
|
// GET command for ADC(Battery Measurement): Voltage, Current, Temperature
|
|
@@ -29,9 +33,9 @@ void mcu_i2c_handle(I2C_Regs *i2c) {
|
|
|
}
|
|
}
|
|
|
// Struct for voltage, current and temperature
|
|
// Struct for voltage, current and temperature
|
|
|
BatteryMeasurementData battery_measure;
|
|
BatteryMeasurementData battery_measure;
|
|
|
- //Battery *battery= &batteries[slot];
|
|
|
|
|
- // take the updated battery measurement from the battery struct and store it
|
|
|
|
|
- // in the battery_measure struct
|
|
|
|
|
|
|
+ // Battery *battery= &batteries[slot];
|
|
|
|
|
+ // take the updated battery measurement from the battery struct and store
|
|
|
|
|
+ // it in the battery_measure struct
|
|
|
battery_measure.voltage = batteries[slot].voltage;
|
|
battery_measure.voltage = batteries[slot].voltage;
|
|
|
battery_measure.current = batteries[slot].current;
|
|
battery_measure.current = batteries[slot].current;
|
|
|
battery_measure.temperature = batteries[slot].temperature;
|
|
battery_measure.temperature = batteries[slot].temperature;
|
|
@@ -40,6 +44,46 @@ void mcu_i2c_handle(I2C_Regs *i2c) {
|
|
|
DL_I2C_fillTargetTXFIFO(i2c, tx_buffer, sizeof(BatteryMeasurementData));
|
|
DL_I2C_fillTargetTXFIFO(i2c, tx_buffer, sizeof(BatteryMeasurementData));
|
|
|
printf("Battery Measurement Sent to MCU. \n");
|
|
printf("Battery Measurement Sent to MCU. \n");
|
|
|
DL_I2C_flushTargetTXFIFO(i2c);
|
|
DL_I2C_flushTargetTXFIFO(i2c);
|
|
|
|
|
+ } else if (receivedCommand == CMD_SET_CURRENT) {
|
|
|
|
|
+ SetChargeDischargeCurrent set_current;
|
|
|
|
|
+ // Read incoming bytes from the Controller:
|
|
|
|
|
+ uint8_t rx_index = 0;
|
|
|
|
|
+ while (rx_index < sizeof(SetChargeDischargeCurrent)) {
|
|
|
|
|
+ // TODO: Need to have a workaround, currently the code is getting stuck on
|
|
|
|
|
+ // the first trigger and provides result on the second trigger
|
|
|
|
|
+ if (!DL_I2C_isTargetRXFIFOEmpty(i2c)) {
|
|
|
|
|
+ rx_buffer[rx_index] = DL_I2C_receiveTargetData(i2c);
|
|
|
|
|
+ rx_index++;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ printf("index:%d\n", rx_index);
|
|
|
|
|
+ // Byte array received from the Controller will be typecasted to (const
|
|
|
|
|
+ // uint8_t *), treats the rx_buffer as an array of READ ONLY bytes because
|
|
|
|
|
+ // of the const
|
|
|
|
|
+ if (rx_index != sizeof(SetChargeDischargeCurrent)) {
|
|
|
|
|
+ printf("ERROR: Incomplete I2C Rx: received %d%zu bytes\n", rx_index,
|
|
|
|
|
+ sizeof(SetChargeDischargeCurrent));
|
|
|
|
|
+ DL_I2C_flushTargetRXFIFO(i2c);
|
|
|
|
|
+ rx_index = 0;
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ memcpy(&set_current, (const uint8_t *)rx_buffer,
|
|
|
|
|
+ sizeof(SetChargeDischargeCurrent));
|
|
|
|
|
+ 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) {
|
|
|
|
|
+ DAC_SingleWrite(current);
|
|
|
|
|
+ } else if (current < 0) {
|
|
|
|
|
+
|
|
|
|
|
+ DL_TimerG_startCounter(PWM_0_INST);
|
|
|
|
|
+ DL_TimerG_setCaptureCompareValue(PWM_0_INST, -1*current, DL_TIMER_CC_0_INDEX); // update ccr0 value
|
|
|
|
|
+ //DL_TimerG_setCaptureCompareValue(PWM_0_INST, 1000, DL_TIMER_CC_1_INDEX);
|
|
|
|
|
+
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // do nothing, charge or discharge
|
|
|
|
|
+ printf("state is idle");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
}
|
|
}
|