Selaa lähdekoodia

dynamic addressing logic added

namrota ghosh 7 kuukautta sitten
vanhempi
commit
ef5229bdd8
3 muutettua tiedostoa jossa 133 lisäystä ja 84 poistoa
  1. 40 22
      main.c
  2. 91 61
      src/controller/controller.c
  3. 2 1
      src/controller/controller.h

+ 40 - 22
main.c

@@ -1,4 +1,4 @@
-#include "ti/driverlib/dl_wwdt.h"
+//#include "ti/driverlib/dl_wwdt.h"
 #include "ti/driverlib/m0p/dl_core.h"
 #include "ti_msp_dl_config.h"
 #include "src/pi/i2c_pi_target.h"
@@ -23,24 +23,36 @@ void I2C_1_INST_IRQHandler(void)
     switch (DL_I2C_getPendingInterrupt(I2C_1_INST)) 
     {   
         case DL_I2C_IIDX_CONTROLLER_START:
-            DL_I2C_flushControllerRXFIFO(I2C_1_INST);
-            DL_I2C_flushControllerTXFIFO(I2C_1_INST);
             break;
 
         case DL_I2C_IIDX_CONTROLLER_RXFIFO_TRIGGER:
-            if (DL_I2C_isTargetRXFIFOEmpty(I2C_1_INST)) {
-                return;
-            }
             mcuSendCommand= true;
+            while(DL_I2C_isControllerRXFIFOEmpty(I2C_1_INST) != true) {
+                if(rxPacket.rxCount < rxPacket.rxLen){
+                     //Get byte from the I2C RX FIFO of the target
+                    rxPacket.rxBuffer[rxPacket.rxCount]= DL_I2C_receiveControllerData(I2C_1_INST);
+                    rxPacket.rxCount++;
+                }else{
+                    DL_I2C_receiveControllerData(I2C_1_INST);
+                }
+            }
+            if(rxPacket.rxCount >= rxPacket.rxLen){
+                rxPacket.rxComplete= true;
+            }
+            
             break;
-
+            
         case DL_I2C_IIDX_CONTROLLER_TXFIFO_TRIGGER:
             /* Fill TX FIFO with bytes to send */
             mcuSendCommand = true;
-            
+            txPacket.txComplete= true;
             break;
+
         case DL_I2C_IIDX_CONTROLLER_STOP:
             mcuSendCommand = true;
+            rxPacket.rxComplete= true;
+            break;
+
         case DL_I2C_IIDX_CONTROLLER_ARBITRATION_LOST:
         case DL_I2C_IIDX_CONTROLLER_NACK:
             break; 
@@ -82,7 +94,7 @@ void I2C_0_INST_IRQHandler(void)
 }
 
 //interrupt added for Windows Watchdog Timer:
-void GROUP0_IRQHandler(void)
+/*void GROUP0_IRQHandler(void)
 {
     switch (DL_Interrupt_getPendingGroup(DL_INTERRUPT_GROUP_0)) {
         case DL_INTERRUPT_GROUP0_IIDX_WWDT0:
@@ -98,7 +110,7 @@ void GROUP0_IRQHandler(void)
         default:
             break;
     }
-}
+}*/
 
 int main(void)
 {  
@@ -107,25 +119,27 @@ int main(void)
     //dynamic addressing function call for Pi
     dynamic_gpio_addressing();
     /* Enable WWDT interrupts on device */
-    NVIC_EnableIRQ(WWDT0_INT_IRQN);
+    //NVIC_EnableIRQ(WWDT0_INT_IRQN);
     //Interrupt routine for Pi
     NVIC_EnableIRQ(I2C_0_INST_INT_IRQN);
     //Interrupt for target mcu
     NVIC_EnableIRQ(I2C_1_INST_INT_IRQN);
     //DL_GPIO_setPins(GPIO_Battery_Discharging_PORT, GPIO_Battery_Discharging_PIN_PB7_PIN);
+
+
+    bool was_true = false;
+
     while(1)
     {   
-        if(watchdog_triggered){
+        /*if(watchdog_triggered){
             printf("ERROR: ***WATCHDOG TRIGGERED***\n");
             //Resetting the flags to its original state
             picommandPending= false;
             mcuSendCommand= false;
             watchdog_triggered= false;
             //Reinitialize the system
-            
-
 
-        }
+        }*/
 
         if(picommandPending)
         {   printf("Pi Interrupt Triggered.\n");
@@ -134,22 +148,26 @@ int main(void)
         }
         if(mcuSendCommand){   
             printf("MCU Interrupt Triggered.\n");
-            for(uint8_t i=0; i<NUM_SLOTS; i++){
-                controller_GetBatteryMeasurement(TARGET_MCU_ADDRESS, i);
-            }
             mcuSendCommand = false;
             
         }
         
         for(uint8_t slot_id= 0; slot_id< NUM_SLOTS; slot_id++){
+            //Reading the battery measurement:
+            printf("mainloop slot?\n");
+            if (!was_true) {
+                printf("executing?\n");
+                was_true = controller_GetBatteryMeasurement(slot_id);
+                printf("true? %d\n", was_true);
+            }
             //Reading battery state:
             Battery_ReadState(slot_id);
-            printf("STATUS ***Reading Battery Measurement for Slot ID %u:: Battery State: %u, Voltage: %u, Current: %u, Temperature: %u, Slot state: %u***\n", slot_id, battery_data[slot_id].battery_state, battery_data[slot_id].battery_measurement.voltage,
-            battery_data[slot_id].battery_measurement.current, battery_data[slot_id].battery_measurement.temperature, battery_data[slot_id].battery_measurement.slot_state);
+            //printf("STATUS ***Reading Battery Measurement for Slot ID %u:: Battery State: %u, Voltage: %u, Current: %u, Temperature: %u, Slot state: %u***\n", slot_id, battery_data[slot_id].battery_state, battery_data[slot_id].battery_measurement.voltage,
+            //battery_data[slot_id].battery_measurement.current, battery_data[slot_id].battery_measurement.temperature, battery_data[slot_id].battery_measurement.slot_state);
             //If target received battery limits from Pi then start charging:       
             if(battery_data[slot_id].batteryLimitReceived){
-                printf("STATUS ***Battery Limits: Slot: %d, Max Voltage:%u, Min Voltage:%u, "
-                "Cutoff Current: %u, Capacitance:%u, Charge Fraction:%u***\n", slot_id, battery_data[slot_id].max_voltage,
+                printf("Battery Limits: Slot: %d, Max Voltage:%u, Min Voltage:%u, "
+                "Cutoff Current: %u, Capacitance:%u, Charge Fraction:%u\n", slot_id, battery_data[slot_id].max_voltage,
                 battery_data[slot_id].min_voltage, battery_data[slot_id].cut_off_current,
                 battery_data[slot_id].capacitance, battery_data[slot_id].charge_fraction);
                 CC_CV_ControlCharging(slot_id, 50);

+ 91 - 61
src/controller/controller.c

@@ -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);
 }

+ 2 - 1
src/controller/controller.h

@@ -17,7 +17,8 @@ typedef enum{
     CMD_CLEAR_ERR= 0x08
 }mcu_I2C_command;
 
+uint8_t detect_target_address();
 void controller_SetCurrent(uint8_t const TARGET_ADDRESS, uint8_t slot_id, int16_t current_mA);
-bool controller_GetBatteryMeasurement(uint8_t const TARGET_ADDRESS, uint8_t slot_id);
+bool controller_GetBatteryMeasurement(uint8_t slot_id);
 void controller_EvaluateBatterySlotState(uint8_t slot_id, BatteryMeasurement *measurement);
 #endif