#include "i2c_pi_target.h" #include "src/config.h" #include "ti/driverlib/dl_gpio.h" #include "ti/driverlib/dl_i2c.h" #include "src/battery_data/battery.h" #include "ti_msp_dl_config.h" #include #include #include // Global extern variable for buffers are defined in config.h and declared in i2c_hal.c: /* 05.05.25: Working on the Dynamic Addressing for I2C communication between MCU and Pi: 1. Base Address of 0x10 is set in the configuration of the MCU as a target 2. GPIO Pins are configured from Pin PA14 to Pin PA17 for Dynamic Addressing 3. If all the Pins are connected to GND then address is the BASE ADDRESS, if not then based on pull up the GPIO pins are set HIGH or LOW 4. Initialize GPIO pins 5. Read GPIO Pins for GND or Pull Up Resistor 6. Set the offset and the base address to the Target and enable */ void GPIO_Addr_Init(){ //Configure GPIO Pins as input: DL_GPIO_initDigitalInput(GPIO_ADDR_PINS_ADDR_0_IOMUX); DL_GPIO_initDigitalInput(GPIO_ADDR_PINS_ADDR_1_IOMUX); DL_GPIO_initDigitalInput(GPIO_ADDR_PINS_ADDR_2_IOMUX); DL_GPIO_initDigitalInput(GPIO_ADDR_PINS_ADDR_3_IOMUX); } //Dynamic Addressing pins for MCU: void dynamic_gpio_addressing(){ //Initialize the GPIO pins GPIO_Addr_Init(); // using ternary operators to verify if pin is high then 1 else 0 uint8_t offset= 0; offset|= ((DL_GPIO_readPins(GPIO_ADDR_PINS_PORT, GPIO_ADDR_PINS_ADDR_3_PIN) ? 1 : 0)<<3); offset|= ((DL_GPIO_readPins(GPIO_ADDR_PINS_PORT, GPIO_ADDR_PINS_ADDR_2_PIN) ? 1 : 0)<<2); offset|= ((DL_GPIO_readPins(GPIO_ADDR_PINS_PORT, GPIO_ADDR_PINS_ADDR_1_PIN) ? 1 : 0)<<1); offset|= ((DL_GPIO_readPins(GPIO_ADDR_PINS_PORT, GPIO_ADDR_PINS_ADDR_0_PIN) ? 1 : 0)<<0); // Target Address as configured in the syscfg file uint8_t i2c_dynamic_address= I2C_0_TARGET_OWN_ADDR + offset; //Configure as target with the dynamic address DL_I2C_setTargetAddress(I2C_0_INST, i2c_dynamic_address); //Enable Target Mode DL_I2C_enableTarget(I2C_0_INST); } void pi_i2c_mcu(){ //uint8_t rxBuffer_getLimits[12]; uint8_t receivedCommand= DL_I2C_receiveTargetData(I2C_0_INST); //printf("Received Command: 0x%02X\n", receivedCommand); if(receivedCommand == CMD_GET_BATTERY_STATUS){ //Example: i2cget -y 1 0x20 0x01 i 4 uint8_t status_buffer[NUM_SLOTS]; //GET battery state from battery.c file for(uint8_t slot=0; slot>4; //printf("Requested slot:%d\n", requestedSlot); BatteryData battery_measure; if(requestedSlot >= NUM_SLOTS){ DL_I2C_flushTargetRXFIFO(I2C_0_INST); return; } //Check for the requested slot and get the battery measurement data BatteryInfo *battery = &battery_data[requestedSlot]; battery_measure.voltage= battery->battery_measurement.voltage; battery_measure.current= battery->battery_measurement.current; battery_measure.temperature= battery->battery_measurement.temperature; battery_measure.cycle_number= battery->cycle_number; battery_measure.cycle_state= battery->battery_charging_state; DL_I2C_fillTargetTXFIFO(I2C_0_INST, (uint8_t *)&battery_measure, sizeof(BatteryData)); printf("Battery Measurement Sent. \n"); DL_I2C_flushTargetTXFIFO(I2C_0_INST); } else if((receivedCommand & 0x0F)== 0x03){ //slot_id is another element //Example i2ctools: i2cset -y 1 0x20 0x03 0x2C 0x01 0x68 0x10 0xFA 0xD0 0x07 0x19 0x00 i /* * min_voltage: 300 (2C 01) * max_voltage: 4200 (68 10) * cut off current: 250 (FA) * Capacitance: 2000 (D0 07) * charge fraction: 25 (19) */ uint8_t rx_index= 0; uint8_t requestedSlot= (receivedCommand & 0xF0)>>4; while(rx_index < (sizeof(BatteryLimitMsg))){ if(!DL_I2C_isTargetRXFIFOEmpty(I2C_0_INST)){ rxPacket.rxBuffer[rx_index]= DL_I2C_receiveTargetData(I2C_0_INST); rx_index++; } } //Check if all the data is received then store the battery limits in BatteryInfo struct: if(rx_index== (sizeof(BatteryLimitMsg))){ BatteryLimitMsg battery_limit_received; memcpy(&battery_limit_received, (const uint8_t*)rxPacket.rxBuffer, sizeof(BatteryLimitMsg)); if(requestedSlot < NUM_SLOTS){ BatteryInfo *battery = &battery_data[requestedSlot]; battery->min_voltage = battery_limit_received.min_voltage; battery->max_voltage = battery_limit_received.max_voltage; battery->cut_off_current = battery_limit_received.cut_off_current; battery->capacitance = battery_limit_received.capacitance; battery->charge_fraction = battery_limit_received.charge_fraction; // this is when WWDT resets the MCU during the charging cycle battery->cycle_number = battery_limit_received.previous_cycle_number; battery->batteryLimitReceived= true; } } rx_index= 0; DL_I2C_flushTargetRXFIFO(I2C_0_INST); } }