#include "src/battery_data/battery.h" #include "ti/driverlib/dl_i2c.h" #include "ti_msp_dl_config.h" //#include "ti/driverlib/dl_i2c.h" #include #include "src/interfaces/i2c_target.h" #include "src/interfaces/i2c_controller.h" #include "src/config.h" int8_t handle_read_pending_slot = -1; void I2C_controller_INST_IRQHandler(void) { switch (DL_I2C_getPendingInterrupt(I2C_controller_INST)) { case DL_I2C_IIDX_CONTROLLER_START: controllerRxPackage.count = 0; DL_I2C_flushControllerTXFIFO(I2C_controller_INST); break; case DL_I2C_IIDX_CONTROLLER_RXFIFO_TRIGGER: /* Store bytes received from target in Rx Msg Buffer */ while (DL_I2C_isControllerRXFIFOEmpty(I2C_controller_INST) != true) { if (controllerRxPackage.count < controllerRxPackage.len) { controllerRxPackage.packet[controllerRxPackage.count] = DL_I2C_receiveControllerData(I2C_controller_INST); ; controllerRxPackage.count++; } else { /* Ignore and remove from FIFO if the buffer is full */ DL_I2C_receiveControllerData(I2C_controller_INST); } } if (controllerRxPackage.count >= controllerRxPackage.len) { controllerRxPackage.complete = true; DL_I2C_enableInterrupt(I2C_controller_INST, DL_I2C_INTERRUPT_CONTROLLER_STOP); } break; /*TRANSMIT data to ADC*/ case DL_I2C_IIDX_CONTROLLER_TXFIFO_TRIGGER: if (controllerTxPackage.count < controllerTxPackage.len) { DL_I2C_fillControllerTXFIFO(I2C_controller_INST, &controllerTxPackage.packet[controllerTxPackage.count], (controllerTxPackage.len - controllerTxPackage.count)); controllerTxPackage.count++; } else { /*Prevent overflow and just ignore data*/ DL_I2C_fillTargetTXFIFO(I2C_controller_INST, (uint8_t[]){0x00}, 1); controllerTxPackage.complete = true; } if(controllerTxPackage.count >= controllerTxPackage.len){ controllerTxPackage.complete= true; } break; /*STOP condition*/ case DL_I2C_IIDX_CONTROLLER_STOP: controllerTxPackage.complete = true; controllerRxPackage.complete = true; break; case DL_I2C_IIDX_CONTROLLER_ARBITRATION_LOST: break; case DL_I2C_IIDX_CONTROLLER_NACK: break; default: break; } } /**** Interrupt for Pi to MCU ****/ void I2C_target_INST_IRQHandler(void) { uint32_t status = DL_I2C_getPendingInterrupt(I2C_target_INST); switch (status) { case DL_I2C_IIDX_TARGET_START: break; case DL_I2C_IIDX_TARGET_STOP: break; case DL_I2C_IIDX_TARGET_RXFIFO_TRIGGER: // only use this function if we are async (filling buffers) - the rest is handled by the mainloop if (handle_read_pending_slot == -1) { handle_read_pending_slot = mcu_i2c_handle(I2C_target_INST); } break; case DL_I2C_IIDX_TARGET_TXFIFO_TRIGGER: break; case DL_I2C_IIDX_TARGET_ARBITRATION_LOST: break; case DL_I2C_IIDX_TIMEOUT_A: case DL_I2C_IIDX_TIMEOUT_B: DL_I2C_flushTargetRXFIFO(I2C_target_INST); DL_I2C_flushTargetTXFIFO(I2C_target_INST); default: break; } } int main(void) { SYSCFG_DL_init(); NVIC_EnableIRQ(I2C_controller_INST_INT_IRQN); NVIC_EnableIRQ(I2C_target_INST_INT_IRQN); battery_slotmgr.init(); initialize_target_address(); while (1) { for(uint8_t slot= 0; slot< NUM_SLOTS; slot++){ if (handle_read_pending_slot != -1) { mcu_i2c_handle_read(I2C_target_INST, handle_read_pending_slot); handle_read_pending_slot = -1; } // step 1: update the voltage readings battery_slotmgr.read_state(slot); // step 2: control loop to adjust the dac / adc values, // but only if no error happens // (0x80 is the error flag of the state) if ((*battery_slots[slot].state & 0x80) == 0) { battery_slotmgr.adjust_current(slot); } else { battery_slotmgr.disable(slot); } } delay_cycles(MAINLOOP_DELAY); } }