|
|
@@ -0,0 +1,181 @@
|
|
|
+/*include configuration libraries*/
|
|
|
+#include "src/interfaces/mcu_slave_interface.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>
|
|
|
+//adc peripheral
|
|
|
+#include "src/peripherals/adc/adc.h"
|
|
|
+#include "src/peripherals/adc/adc_interface.h"
|
|
|
+// mux peripheral
|
|
|
+#include "src/peripherals/mux/multiplexer.h"
|
|
|
+#define DELAY_CYCLE (5000)
|
|
|
+//i2c:
|
|
|
+#include "ti/comm_modules/i2c/controller/i2c_comm_controller.h"
|
|
|
+//battery:
|
|
|
+#include "src/battery_data/battery.h"
|
|
|
+
|
|
|
+I2C_Instance gI2C;
|
|
|
+I2C_ResponseInfo gResponse;
|
|
|
+
|
|
|
+volatile bool mcuCommandPending= false;
|
|
|
+
|
|
|
+/*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 Main MCU to Target MCU ****/
|
|
|
+void I2C_target_INST_IRQHandler(void) {
|
|
|
+
|
|
|
+ uint32_t status = DL_I2C_getPendingInterrupt(I2C_target_INST);
|
|
|
+ //printf("status: %d\n", status);
|
|
|
+ switch (status) {
|
|
|
+ case DL_I2C_IIDX_TARGET_START:
|
|
|
+ DL_I2C_flushTargetTXFIFO(I2C_target_INST);
|
|
|
+ break;
|
|
|
+ case DL_I2C_IIDX_TARGET_STOP:
|
|
|
+ mcuCommandPending= 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;
|
|
|
+ }
|
|
|
+ mcuCommandPending= true;
|
|
|
+ break;
|
|
|
+ case DL_I2C_IIDX_TARGET_TXFIFO_TRIGGER:
|
|
|
+ mcuCommandPending= true;
|
|
|
+ //printf("Tx interrupt triggered.\n");
|
|
|
+ break;
|
|
|
+ case DL_I2C_IIDX_TARGET_ARBITRATION_LOST:
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/***Main Function***/
|
|
|
+
|
|
|
+int main(void){
|
|
|
+ SYSCFG_DL_init();
|
|
|
+ Battery_Init();
|
|
|
+ // Reset_I2C_Bus();
|
|
|
+ NVIC_EnableIRQ(I2C_target_INST_INT_IRQN);
|
|
|
+ NVIC_EnableIRQ(I2C_controller_INST_INT_IRQN);
|
|
|
+ // Multiplexer
|
|
|
+ Multiplexer_SelectChannel(I2C_CHANNEL);
|
|
|
+ //I2C Scanning
|
|
|
+ I2C_scanBus();
|
|
|
+ I2C_init(&gI2C);
|
|
|
+
|
|
|
+ while(1){
|
|
|
+ if(mcuCommandPending){
|
|
|
+ mcu_i2c_handle(I2C_target_INST);
|
|
|
+ mcuCommandPending= false;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ // 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++) {
|
|
|
+ updateADCReading_multichannel(slot_id, adc_channel);
|
|
|
+ }
|
|
|
+ delay_cycles(DELAY_CYCLE);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|