|
|
@@ -1,10 +1,11 @@
|
|
|
#include "src/controller/controller.h"
|
|
|
-#include "src/i2c_comm/i2c_hal.h"
|
|
|
-#include "src/pi/i2c_pi_target.h"
|
|
|
+//#include "src/i2c_comm/i2c_hal.h"
|
|
|
#include "ti/driverlib/dl_i2c.h"
|
|
|
+#include "ti/driverlib/m0p/dl_core.h"
|
|
|
#include "ti_msp_dl_config.h"
|
|
|
#include <stdio.h>
|
|
|
-#include <string.h>
|
|
|
+//#include <string.h>
|
|
|
+
|
|
|
|
|
|
/*
|
|
|
* Generic Function to send data to the target controller using I2C:
|
|
|
@@ -13,23 +14,26 @@ Format: command + ((slot_id) + data (optional))
|
|
|
//Send command to set charge and discharge current to the target
|
|
|
void controller_SetCurrent(uint8_t const TARGET_ADDRESS, uint8_t slot_id, int16_t current_mA){
|
|
|
//Bitmasked: Slot id + Command
|
|
|
- tx_packet.txBuffer[0]= (slot_id<<4) | (CMD_SET_CURRENT & 0x0F);
|
|
|
+
|
|
|
+ txPacket.txBuffer[0]= (slot_id<<4) | (CMD_SET_CURRENT & 0x0F);
|
|
|
//Filling the buffer with current value
|
|
|
- *((int16_t*)(&tx_packet.txBuffer[1])) = current_mA;
|
|
|
+ *((int16_t*)(&txPacket.txBuffer[1])) = current_mA;
|
|
|
|
|
|
/*I2C Communication for transmitting Charging/Discharging current for the slots*/
|
|
|
//Length is calculated as 1 byte for the bitmasked slot and command+ 2 bytes of current + 1 byte of padding
|
|
|
- tx_packet.txLen= 4;
|
|
|
+ txPacket.txLen= 4;
|
|
|
+
|
|
|
DL_I2C_enableInterrupt(I2C_1_INST, DL_I2C_INTERRUPT_CONTROLLER_TXFIFO_TRIGGER);
|
|
|
- DL_I2C_startControllerTransfer(I2C_1_INST, TARGET_ADDRESS, DL_I2C_CONTROLLER_DIRECTION_TX, tx_packet.txLen);
|
|
|
- /*printf("Packet Sent:: 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X \n", TARGET_ADDRESS, tx_packet.txBuffer[0], tx_packet.txBuffer[1],tx_packet.txBuffer[2], tx_packet.txBuffer[3]);
|
|
|
- DL_I2C_fillControllerTXFIFO(I2C_1_INST, tx_packet.txBuffer, tx_packet.txLen);*/
|
|
|
+ DL_I2C_startControllerTransfer(I2C_1_INST, TARGET_ADDRESS, DL_I2C_CONTROLLER_DIRECTION_TX, txPacket.txLen);
|
|
|
+ printf("Packet Sent:: 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X \n", TARGET_ADDRESS, txPacket.txBuffer[0], txPacket.txBuffer[1],txPacket.txBuffer[2], txPacket.txBuffer[3]);
|
|
|
+ DL_I2C_fillControllerTXFIFO(I2C_1_INST, txPacket.txBuffer, txPacket.txLen);
|
|
|
|
|
|
// Wait for the bus to become not busy WITH a timeout
|
|
|
- uint32_t timeout = 100000;
|
|
|
+ uint32_t timeout = 10000;
|
|
|
while ((DL_I2C_getControllerStatus(I2C_1_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS) && timeout > 0) {
|
|
|
timeout--;
|
|
|
}
|
|
|
+
|
|
|
printf("STATUS ***SetCurrent successful for slot %d with current %d mA***\n", slot_id, current_mA);
|
|
|
// Clean up and exit
|
|
|
DL_I2C_flushControllerTXFIFO(I2C_1_INST);
|
|
|
@@ -38,89 +42,115 @@ void controller_SetCurrent(uint8_t const TARGET_ADDRESS, uint8_t slot_id, int16_
|
|
|
|
|
|
|
|
|
//Get battery measurement: Voltage, Current, Temperature including slot state:
|
|
|
-bool controller_GetBatteryMeasurement(uint8_t const TARGET_ADDRESS, uint8_t slot_id){
|
|
|
+bool controller_GetBatteryMeasurement(uint8_t slot_id){
|
|
|
|
|
|
+ uint8_t target_address= TARGET_BASE_ADDRESS + ((slot_id & 0b00000100) >> 2);
|
|
|
+ printf("Target Address 0x%02X \n", target_address);
|
|
|
//Initializing BatteryMeasurement structure from battery.h of size 8
|
|
|
BatteryMeasurement measurement;
|
|
|
- uint8_t rx_index=0;
|
|
|
|
|
|
//Flush the TX FIFO and make the buffer ready to transmit data:
|
|
|
DL_I2C_flushControllerTXFIFO(I2C_1_INST);
|
|
|
+ DL_I2C_flushControllerRXFIFO(I2C_1_INST);
|
|
|
|
|
|
//Write Command to the target
|
|
|
- //Set the command in the tx buffer in bit masked format to the target: Upper Nibble-> Slot and Lower Nibbel -> Command
|
|
|
- tx_packet.txBuffer[0]= (slot_id << 4)|(CMD_GET_MEASUREMENT & 0x0F); //shift slot_id to the left by 4 bits
|
|
|
-
|
|
|
- //Send command bytes to the target
|
|
|
- DL_I2C_enableInterrupt(I2C_1_INST, DL_I2C_INTERRUPT_CONTROLLER_TXFIFO_TRIGGER);
|
|
|
- DL_I2C_startControllerTransfer(I2C_1_INST, TARGET_ADDRESS, DL_I2C_CONTROLLER_DIRECTION_TX, 1);
|
|
|
- printf("[I2C] TX Packet Sent:: 0x%02X\n", tx_packet.txBuffer[0]);
|
|
|
- DL_I2C_fillControllerTXFIFO(I2C_1_INST, tx_packet.txBuffer, 1);
|
|
|
-
|
|
|
- // Wait for the write transaction to complete
|
|
|
- uint32_t tx_timeout = 100000;
|
|
|
- while (!(DL_I2C_getControllerStatus(I2C_1_INST) & DL_I2C_CONTROLLER_STATUS_IDLE) && tx_timeout > 0) {
|
|
|
- tx_timeout--;
|
|
|
+ //Set the command in the tx buffer in bit masked format to the target: Upper Nibble-> Slot and Lower Nibble -> Command
|
|
|
+ txPacket.txBuffer[0]= (slot_id << 4)|(CMD_GET_MEASUREMENT & 0x0F); //shift slot_id to the left by 4 bits
|
|
|
+ txPacket.txLen= 1;
|
|
|
+ txPacket.txCount= 0;
|
|
|
+ txPacket.txComplete= false;
|
|
|
+ DL_I2C_fillControllerTXFIFO(I2C_1_INST, &txPacket.txBuffer[0], txPacket.txLen);
|
|
|
+
|
|
|
+ // Wait for the bus to be idle
|
|
|
+ uint32_t timeout = 10000;
|
|
|
+ while (!(DL_I2C_getControllerStatus(I2C_1_INST) & DL_I2C_CONTROLLER_STATUS_IDLE) && timeout--);
|
|
|
+ if(timeout == 0){
|
|
|
+ printf("Error in reading from I2C Bus: Bus is not getting ready before transmit start\n");
|
|
|
+ DL_I2C_resetControllerTransfer(I2C_1_INST);
|
|
|
+ return false;
|
|
|
}
|
|
|
+
|
|
|
+ //Send command bytes to the target
|
|
|
+
|
|
|
+ DL_I2C_startControllerTransferAdvanced(I2C_1_INST, target_address, DL_I2C_CONTROLLER_DIRECTION_TX, txPacket.txLen, DL_I2C_CONTROLLER_START_ENABLE, DL_I2C_CONTROLLER_STOP_DISABLE, DL_I2C_CONTROLLER_ACK_ENABLE);
|
|
|
+ printf("[I2C] TX Packet Sent:: 0x%02X\n", txPacket.txBuffer[0]);
|
|
|
+
|
|
|
+
|
|
|
//If I2C Bus is stuck then reset the controller:
|
|
|
- if(DL_I2C_getControllerStatus(I2C_1_INST)& (DL_I2C_CONTROLLER_STATUS_ERROR)){
|
|
|
+ if(DL_I2C_getControllerStatus(I2C_1_INST)&(DL_I2C_CONTROLLER_STATUS_ERROR)){
|
|
|
printf("ERROR ***I2C Write Error: Bus is stuck***\n");
|
|
|
DL_I2C_resetControllerTransfer(I2C_1_INST);
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- //Clear RX FIFO for any stale data and prepare for receiving data
|
|
|
- DL_I2C_flushControllerRXFIFO(I2C_1_INST);
|
|
|
|
|
|
- //Adding a while wait loop
|
|
|
- uint32_t rx_timeout = 20000;
|
|
|
- while (!(DL_I2C_getControllerStatus(I2C_1_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS) && rx_timeout > 0) {
|
|
|
- rx_timeout--;
|
|
|
+ // Wait until TX FIFO is empty (TX complete)
|
|
|
+ timeout = 10000;
|
|
|
+ while ((DL_I2C_getControllerStatus(I2C_1_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS) && timeout--);
|
|
|
+ if (timeout == 0) {
|
|
|
+ printf("Bus stuck during TX.\n");
|
|
|
+ DL_I2C_resetControllerTransfer(I2C_1_INST);
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
- //BatteryMeasurement size is 12 similar to the target side
|
|
|
- DL_I2C_startControllerTransfer(I2C_1_INST, TARGET_ADDRESS, DL_I2C_CONTROLLER_DIRECTION_RX, sizeof(BatteryMeasurement));
|
|
|
+ //delay_cycles(1000);
|
|
|
|
|
|
- while(rx_index < sizeof(BatteryMeasurement)){
|
|
|
- if(!DL_I2C_isControllerRXFIFOEmpty(I2C_1_INST)){
|
|
|
- //Get byte from the I2C RX FIFO of the target
|
|
|
- rx_packet.rxBuffer[rx_index]= DL_I2C_receiveControllerData(I2C_1_INST);
|
|
|
- printf("Received Bytes[%d]: 0x%02X\n", rx_index, rx_packet.rxBuffer[rx_index]);
|
|
|
- rx_index++;
|
|
|
- }
|
|
|
+ //Re-initializing te timeout value for Rx:
|
|
|
+ timeout= 10000;
|
|
|
+ rxPacket.rxLen= sizeof(BatteryMeasurement);
|
|
|
+ rxPacket.rxCount= 0;
|
|
|
+ rxPacket.rxComplete= false;
|
|
|
+
|
|
|
+ DL_I2C_enableInterrupt(I2C_1_INST, DL_I2C_INTERRUPT_CONTROLLER_RXFIFO_TRIGGER);
|
|
|
+ //BatteryMeasurement size is 8 similar to the target side
|
|
|
+ //DL_I2C_startControllerTransferAdvanced(I2C_1_INST, TARGET_ADDRESS, DL_I2C_CONTROLLER_DIRECTION_RX, rxPacket.rxLen, DL_I2C_CONTROLLER_START_ENABLE, DL_I2C_CONTROLLER_STOP_ENABLE, DL_I2C_CONTROLLER_ACK_DISABLE);
|
|
|
+ DL_I2C_startControllerTransfer(I2C_1_INST, target_address, DL_I2C_CONTROLLER_DIRECTION_RX, rxPacket.rxLen);
|
|
|
+
|
|
|
+
|
|
|
+ while((DL_I2C_getControllerStatus(I2C_1_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS) && timeout--);
|
|
|
+
|
|
|
+ if(timeout == 0 || (DL_I2C_getSCLStatus(I2C_1_INST)== DL_I2C_CONTROLLER_SCL_LOW)){
|
|
|
+ printf("Bus stuck during Rx transmit or SCL held LOW.\n");
|
|
|
+ DL_I2C_resetControllerTransfer(I2C_1_INST);
|
|
|
+ return false;
|
|
|
}
|
|
|
+
|
|
|
//DEBUG
|
|
|
- printf("RX Index: %d\n", rx_index);
|
|
|
+ //printf("Rx Count: %d\n", rxPacket.rxCount);
|
|
|
+ printf("Total Received Bytes out of total length of [0x%02X]: 0x%02X\n", rxPacket.rxLen, sizeof(rxPacket.rxBuffer[rxPacket.rxCount]));
|
|
|
+ printf("Rx Complete: %d\n", rxPacket.rxComplete);
|
|
|
//Check if all the data is received then store the battery limits in BatteryInfo struct:
|
|
|
- if(rx_index== (sizeof(BatteryMeasurement))){
|
|
|
- measurement.voltage= rx_packet.rxBuffer[0] | (rx_packet.rxBuffer[1] << 8);
|
|
|
- measurement.current= rx_packet.rxBuffer[2]|(rx_packet.rxBuffer[3] << 8);
|
|
|
- measurement.temperature = rx_packet.rxBuffer[4] | (rx_packet.rxBuffer[5] << 8);
|
|
|
- measurement.slot_state = (SlotState)(rx_packet.rxBuffer[6]);
|
|
|
+ if(rxPacket.rxCount== (sizeof(BatteryMeasurement))){
|
|
|
+ measurement.voltage= rxPacket.rxBuffer[0] | (rxPacket.rxBuffer[1] << 8);
|
|
|
+ measurement.current= rxPacket.rxBuffer[2]|(rxPacket.rxBuffer[3] << 8);
|
|
|
+ measurement.temperature = rxPacket.rxBuffer[4] | (rxPacket.rxBuffer[5] << 8);
|
|
|
+ measurement.slot_state = (SlotState)(rxPacket.rxBuffer[6]);
|
|
|
+
|
|
|
battery_data[slot_id].battery_measurement= measurement;
|
|
|
//DEBUG
|
|
|
- printf("[I2C] Successfully read %d bytes from target 0x%02X\n", sizeof(BatteryMeasurement), TARGET_ADDRESS);
|
|
|
+ printf("[I2C] Successfully read %d bytes from target 0x%02X\n", rxPacket.rxCount, target_address);
|
|
|
+ printf("Voltage: %u\n", battery_data[slot_id].battery_measurement.voltage);
|
|
|
+ printf("Current: %d\n", battery_data[slot_id].battery_measurement.current);
|
|
|
+ printf("Temp: %u\n", battery_data[slot_id].battery_measurement.temperature);
|
|
|
+ printf("Slot state: %u\n", battery_data[slot_id].battery_measurement.slot_state);
|
|
|
+ return true;
|
|
|
}
|
|
|
- DL_I2C_flushTargetRXFIFO(I2C_1_INST);
|
|
|
- //DEBUG
|
|
|
- printf("Voltage: %u\n", battery_data[slot_id].battery_measurement.voltage);
|
|
|
- printf("Current: %d\n", battery_data[slot_id].battery_measurement.current);
|
|
|
- printf("Temp: %u\n", battery_data[slot_id].battery_measurement.temperature);
|
|
|
- printf("Slot state: %u\n", battery_data[slot_id].battery_measurement.slot_state);
|
|
|
- return true;
|
|
|
+
|
|
|
+
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
-//Clear error flag to the target
|
|
|
+//Clear error flag to the target to change it back to SLOT_STATE_OK
|
|
|
//Format: command + ((slot_id) + data (optional))
|
|
|
void controller_ClearError(uint8_t const TARGET_ADDRESS, uint8_t slot_id){
|
|
|
uint8_t command= CMD_CLEAR_ERR| (slot_id<<4); //shift slot_id to the left by 4 bits
|
|
|
printf("[MCU] Clear Error Bitmasked Command:: 0x%02X\n", command);
|
|
|
- tx_packet.txBuffer[0]= command;
|
|
|
- tx_packet.txBuffer[1]= slot_id;
|
|
|
- tx_packet.txLen= sizeof(tx_packet.txBuffer);
|
|
|
+ txPacket.txBuffer[0]= command;
|
|
|
+ txPacket.txBuffer[1]= slot_id;
|
|
|
+ txPacket.txLen= sizeof(txPacket.txBuffer);
|
|
|
while (DL_I2C_getControllerStatus(I2C_1_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS);
|
|
|
- DL_I2C_startControllerTransfer(I2C_1_INST, TARGET_ADDRESS, DL_I2C_CONTROLLER_DIRECTION_TX, tx_packet.txLen);
|
|
|
- DL_I2C_fillControllerTXFIFO(I2C_1_INST, tx_packet.txBuffer, tx_packet.txLen);
|
|
|
+ DL_I2C_startControllerTransfer(I2C_1_INST, TARGET_ADDRESS, DL_I2C_CONTROLLER_DIRECTION_TX, txPacket.txLen);
|
|
|
+ DL_I2C_fillControllerTXFIFO(I2C_1_INST, txPacket.txBuffer, txPacket.txLen);
|
|
|
while (DL_I2C_getControllerStatus(I2C_1_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS);
|
|
|
DL_I2C_flushControllerTXFIFO(I2C_1_INST);
|
|
|
}
|