| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- #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 <stdint.h>
- #include <stdio.h>
- #include <string.h>
- // 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<NUM_SLOTS; slot++){
- status_buffer[slot] = battery_data[slot].battery_state;
- }
- DL_I2C_fillTargetTXFIFO(I2C_0_INST, status_buffer, NUM_SLOTS);
- while(DL_I2C_transmitTargetDataCheck(I2C_0_INST, 0x00)!= false);
- }
- //bitmasked GET command:
- else if((receivedCommand & 0x0F)== 0x02){
- //I2Ctools command: i2cget -y 1 0x20 0xn2 i 8
- //Get Battery Measurement data for slot_id: Voltage, Current, Temperture, Cycle Number and Cycle State
- // on two of the testings have received:
- //0x00 0xff 0xff 0xff 0xff 0xff 0xff 0xff
- //0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
- uint8_t requestedSlot = (receivedCommand & 0xF0)>>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);
-
- }
- }
|