| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292 |
- /*
- Main Source File
- */
- #include "adc.h"
- #include "battery.h"
- #include "cc_cv_charging.h"
- #include "dac.h"
- #include "i2c_target.h"
- #include "multiplexer.h"
- #include "ti/comm_modules/i2c/controller/i2c_comm_controller.h"
- #include "ti/devices/msp/peripherals/hw_dac12.h"
- #include "ti/driverlib/dl_adc12.h"
- #include "ti/driverlib/dl_gpio.h"
- #include "ti/driverlib/dl_i2c.h"
- #include "ti/driverlib/m0p/dl_core.h"
- #include "ti_msp_dl_config.h"
- #include <stdint.h>
- #include <stdio.h>
- #include <string.h>
- #include <ti/drivers/GPIO.h>
- I2C_Instance gI2C;
- I2C_ResponseInfo gResponse;
- BatteryData battery_data;
- /*Interrupt for MCU -> ADC
- * CASE: DL_I2C_IIDX_CONTROLLER_RX_DONE: ADC Reception Complete
- - ADC has finished sending data and it's fully received.
- - gI2C.rxMsg.len = gI2C.rxMsg.ptr:
- - Stores the received data length in the response buffer.
- - I2C_decodeResponse():
- - Decodes the received response.
- - gI2C.status = I2C_STATUS_RX_COMPLETE:
- - Marks reception is complete.
- * CASE: DL_I2C_IIDX_CONTROLLER_TX_DONE: Data Transmit to ADC complete
- - DL_I2C_disableInterrupt(..): Disables the TXFIFO interrupt since data is
- now sent
- * CASE: DL_I2C_IIDX_CONTROLLER_RXFIFO_TRIGGER: Receive Data in FIFO
- - The I2C Receive FIFO has data ready to be read.
- - while (DL_I2C_isControllerRXFIFOEmpty(...) != true): Loops until the RX
- FIFOis empty (READ all available bytes)
- - Inside the while loop:
- - If buffer has SPACE, store the received byte
- - Prints each received byte in HEXADECIMAL format for debugging
- - IF BUFFER is FULL, avoids OVERFLOW by discarding extra byte.
- * CASE: DL_I2C_IIDX_CONTROLLER_TXFIFO_TRIGGER: Transmit Data in FIFO
- - If there is still data to send:
- gI2C.txMsg.ptr += DL_I2C_fillControllerTXFIFO(I2C_controller_INST,
- &gI2C.txMsg.buffer[gI2C.txMsg.ptr], gI2C.txMsg.len - gI2C.txMsg.ptr);
- */
- void I2C_controller_INST_IRQHandler(void) {
- // printf("I2C Interrupt Triggered to ADC!\n");
- switch (DL_I2C_getPendingInterrupt(I2C_controller_INST)) { /*START Condition*/
- case DL_I2C_IIDX_CONTROLLER_START:
- // gTxADCcount= 0;
- gRxADCcount = 0;
- DL_I2C_flushControllerTXFIFO(I2C_controller_INST);
- break;
- case DL_I2C_IIDX_CONTROLLER_RXFIFO_TRIGGER:
- gI2C.status = I2C_STATUS_RX_INPROGRESS;
- /* Store bytes received from target in Rx Msg Buffer */
- while (DL_I2C_isControllerRXFIFOEmpty(I2C_controller_INST) != true) {
- if (gRxADCcount < gRxADClen) {
- gRxPacket[gRxADCcount] =
- DL_I2C_receiveControllerData(I2C_controller_INST);
- printf("Received Byte[%d]: 0x%02X\n", gRxADCcount,
- gRxPacket[gRxADCcount]); // Debug print
- gRxADCcount++;
- } else {
- // printf("ERROR: RX Buffer Overflow! ptr=%d MAX_BUFFER_SIZE=%d\n",
- // gI2C.rxMsg.ptr, MAX_BUFFER_SIZE);
- /* Ignore and remove from FIFO if the buffer is full */
- DL_I2C_receiveControllerData(I2C_controller_INST);
- }
- }
- if (gRxADCcount >= gRxADClen) {
- // printf("ADC Bytes Received!\n");
- gRxComplete = true;
- DL_I2C_enableInterrupt(I2C_controller_INST,
- DL_I2C_INTERRUPT_CONTROLLER_STOP);
- }
- break;
- /*TRANSMIT data to ADC*/
- case DL_I2C_IIDX_CONTROLLER_TXFIFO_TRIGGER:
- // printf("TX FIFO with data!\n");
- gI2C.status = I2C_STATUS_TX_INPROGRESS;
- if (gTxADCcount < gTxADClen) {
- gTxADCcount += DL_I2C_fillControllerTXFIFO(I2C_controller_INST,
- &gTxPacket[gTxADCcount],
- (gTxADClen - gTxADCcount));
- } else {
- /*Prevent overflow and just ignore data*/
- DL_I2C_fillTargetTXFIFO(I2C_controller_INST, (uint8_t[]){0x00}, 1);
- gTxComplete = true;
- }
- // DL_I2C_flushControllerTXFIFO(I2C_controller_INST);
- break;
- /*STOP condition*/
- case DL_I2C_IIDX_CONTROLLER_STOP:
- gTxComplete = true;
- gRxComplete = true;
- // printf("I2C Stop Detected- RX Complete");
- break;
- case DL_I2C_IIDX_CONTROLLER_ARBITRATION_LOST:
- // printf("Interrupt index for I2C controller Arbitration Lost!\n");
- break;
- case DL_I2C_IIDX_CONTROLLER_NACK:
- // printf("I2C NACK Received\n");
- if ((gI2C.status == I2C_STATUS_RX_STARTED) ||
- (gI2C.status = I2C_STATUS_TX_STARTED)) {
- gI2C.status = I2C_STATUS_ERROR;
- }
- break;
- default:
- break;
- }
- }
- /**** Interrupt for Pi to MCU ****/
- void I2C_target_INST_IRQHandler(void) {
- uint8_t receivedCommand = 0;
- uint8_t battery_state[8] = {0x00};
- uint32_t status = DL_I2C_getPendingInterrupt(I2C_target_INST);
- printf("status: %d\n", status);
- switch (status) {
- case DL_I2C_IIDX_TARGET_START:
- /*Initialize Tx or RX after Start condition is recieved*/
- piTxCount = 0;
- piRxCount = 0;
- piTxComplete = false;
- DL_I2C_flushTargetTXFIFO(I2C_target_INST);
- break;
- case DL_I2C_IIDX_TARGET_STOP:
- piTxComplete = true;
- piRxComplete = true;
- DL_I2C_flushTargetTXFIFO(I2C_target_INST);
- DL_I2C_flushTargetRXFIFO(I2C_target_INST);
- break;
- case DL_I2C_IIDX_TARGET_RXFIFO_TRIGGER:
- printf("Rx Interrupt Triggered \n");
- if (DL_I2C_isTargetRXFIFOEmpty(I2C_target_INST)) {
- return;
- }
- receivedCommand = DL_I2C_receiveTargetData(I2C_target_INST);
- if (receivedCommand == CMD_GET_BATTERY_STATUS) {
- printf("Received Command: 0x%02X\n", receivedCommand);
- for (uint8_t slot = 0; slot < NUM_SLOTS; slot++) {
- battery_state[slot] = batteries[slot].state;
- }
- DL_I2C_fillTargetTXFIFO(I2C_target_INST, battery_state, 8);
- while (DL_I2C_transmitTargetDataCheck(I2C_target_INST, 0x00) != false)
- ;
- printf("Sent Data\n");
- }
- /*
- To receive the Battery Mesaurements from MCU, bit masking is applied
- where:
- - command type is upper 4 bits: 0010 (for CMD_GET_BATTERY_DATA)->
- consistent
- - slot_id is lower 3 bits, since NUM_SLOTS are 8 so it ranges from 000
- till 111
- - bit mask for command is 0xF0: 11110000
- - bit mask for requested slot is 0x07: 00000111
- receivedCommand now ranges from 0x20 till 0x27
- */
- else if ((receivedCommand & 0xF0) == 0x20) {
- //printf("Received Command: 0x%02X\n", receivedCommand);
- uint8_t requestedSlot = (receivedCommand & 0x07);
- //printf("Requested slot:%d\n", requestedSlot);
- // piTxCount = 0;
- piTxLen = sizeof(BatteryData);
- BatteryData battery_data;
- if (requestedSlot >= NUM_SLOTS) {
- //printf("Requested Slot is not valid.\n");
- DL_I2C_flushTargetTXFIFO(I2C_target_INST);
- return;
- }
- Battery *battery = &batteries[requestedSlot];
- battery_data.slot_id = battery->slot_id; // !TODO: recheck if necessary
- //printf("slot_id:%u\n", battery_data.slot_id);
- battery_data.voltage = battery->voltage;
- //printf("voltage:%u\n", battery_data.voltage);
- battery_data.current = battery->current;
- //printf("current:%u\n", battery_data.current);
- battery_data.temperature = battery->temperature;
- //printf("temperature:%u\n", battery_data.temperature);
- DL_I2C_fillTargetTXFIFO(I2C_target_INST, (uint8_t *)&battery_data,
- piTxLen);
- /*piTxComplete= true;
- if(piTxCount >= piTxLen){
- piTxComplete= true;
- piTxCount= 0;
- }*/
- printf("Battery Measurement Sent. \n");
- DL_I2C_flushTargetTXFIFO(I2C_target_INST);
- }
- else if (receivedCommand == CMD_SET_BATTERY_LIMIT) {
- uint8_t rx_buffer[sizeof(BatteryLimitMsg)];
- uint8_t index = 0;
- while (!DL_I2C_isTargetRXFIFOEmpty(I2C_target_INST)) {
- if (index < sizeof(BatteryLimitMsg)) {
- rx_buffer[index] = DL_I2C_receiveTargetData(I2C_target_INST);
- index++;
- } else {
- DL_I2C_receiveTargetData(I2C_target_INST);
- }
- }
- if (index == sizeof(BatteryLimitMsg)) {
- BatteryLimitMsg battery_limits;
- memcpy(&battery_limits, rx_buffer, sizeof(BatteryLimitMsg));
- if (battery_limits.slot_id < NUM_SLOTS) {
- Battery *battery = &batteries[battery_limits.slot_id];
- battery->min_voltage = battery_limits.min_voltage;
- battery->max_voltage = battery_limits.max_voltage;
- battery->cut_off_current = battery_limits.cut_off_current;
- battery->capacitance = battery_limits.capacitance;
- battery->charge_fraction = battery_limits.charge_fraction;
- }
- }
- }
- break;
- case DL_I2C_IIDX_TARGET_TXFIFO_TRIGGER:
- break;
- case DL_I2C_IIDX_TARGET_ARBITRATION_LOST:
- break;
- default:
- break;
- }
- }
- /********MAIN function*************/
- int main(void) {
- // Initialize System and I2C
- SYSCFG_DL_init();
- // Initialize battery array and default params
- Battery_Init();
- // Reset_I2C_Bus();
- NVIC_EnableIRQ(I2C_target_INST_INT_IRQN);
- NVIC_EnableIRQ(I2C_controller_INST_INT_IRQN);
- printf("............System Configuration Enabled...............\n");
- // Multiplexer
- Multiplexer_SelectChannel(I2C_CHANNEL);
- // I2C_scanBus();
- I2C_init(&gI2C);
- // ADC_SetConfigurationBytes(adc_voltage_params);
- // delay_cycles(50000);
- // ADC_SetConfigurationBytes(adc_current_params);
- // delay_cycles(50000);
- // DAC_ReadCurrentAddress();
- while (1) {
- // Looping through the ADC Channels
- for (uint8_t slot_id = 0; slot_id < NUM_SLOTS; slot_id++) {
- for (uint8_t adc_channel = 0; adc_channel < ADC_CHANNEL_NUM;
- adc_channel++) {
- Battery_UpdateADCReading(slot_id, adc_channel);
- }
- Battery_ReadState(slot_id);
- }
- printf("Battery Details: Slot: %u, Voltage:%u, Current: %u \n, State:%u\n:",
- batteries[0].slot_id, batteries[0].voltage, batteries[0].current,
- batteries[0].state);
- // CC-CV Cycle: maximum cycles is not yet implemented
- // for(uint8_t slot_id= 0; slot_id < NUM_SLOTS; slot_id++){
- // CC_CV_ControlCharging(slot_id);
- // }
- // DAC_fastWrite(CHANNEL_A_VALUE);
- }
- }
|