target_main.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /*include configuration libraries*/
  2. #include "src/interfaces/mcu_slave_interface.h"
  3. #include "ti/driverlib/m0p/dl_core.h"
  4. #include "ti_msp_dl_config.h"
  5. #include <stdint.h>
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <ti/drivers/GPIO.h>
  9. //adc peripheral
  10. #include "src/peripherals/adc/adc.h"
  11. #include "src/peripherals/adc/adc_interface.h"
  12. #define DELAY_CYCLE (1000000)
  13. //i2c:
  14. #include "ti/comm_modules/i2c/controller/i2c_comm_controller.h"
  15. //battery:
  16. #include "src/battery_data/battery.h"
  17. #include "src/interfaces/i2c_peripherals_scan.h"
  18. I2C_Instance gI2C;
  19. I2C_ResponseInfo gResponse;
  20. volatile bool mcuCommandPending= false;
  21. /*Interrupt for MCU -> ADC
  22. * CASE: DL_I2C_IIDX_CONTROLLER_RX_DONE: ADC Reception Complete
  23. - ADC has finished sending data and it's fully received.
  24. - gI2C.rxMsg.len = gI2C.rxMsg.ptr:
  25. - Stores the received data length in the response buffer.
  26. - I2C_decodeResponse():
  27. - Decodes the received response.
  28. - gI2C.status = I2C_STATUS_RX_COMPLETE:
  29. - Marks reception is complete.
  30. * CASE: DL_I2C_IIDX_CONTROLLER_TX_DONE: Data Transmit to ADC complete
  31. - DL_I2C_disableInterrupt(..): Disables the TXFIFO interrupt since data is
  32. now sent
  33. * CASE: DL_I2C_IIDX_CONTROLLER_RXFIFO_TRIGGER: Receive Data in FIFO
  34. - The I2C Receive FIFO has data ready to be read.
  35. - while (DL_I2C_isControllerRXFIFOEmpty(...) != true): Loops until the RX
  36. FIFOis empty (READ all available bytes)
  37. - Inside the while loop:
  38. - If buffer has SPACE, store the received byte
  39. - Prints each received byte in HEXADECIMAL format for debugging
  40. - IF BUFFER is FULL, avoids OVERFLOW by discarding extra byte.
  41. * CASE: DL_I2C_IIDX_CONTROLLER_TXFIFO_TRIGGER: Transmit Data in FIFO
  42. - If there is still data to send:
  43. gI2C.txMsg.ptr += DL_I2C_fillControllerTXFIFO(I2C_controller_INST,
  44. &gI2C.txMsg.buffer[gI2C.txMsg.ptr], gI2C.txMsg.len - gI2C.txMsg.ptr);
  45. */
  46. void I2C_controller_INST_IRQHandler(void) {
  47. // printf("I2C Interrupt Triggered to ADC!\n");
  48. switch (DL_I2C_getPendingInterrupt(I2C_controller_INST)) { /*START Condition*/
  49. case DL_I2C_IIDX_CONTROLLER_START:
  50. // gTxADCcount= 0;
  51. gRxADCcount = 0;
  52. DL_I2C_flushControllerTXFIFO(I2C_controller_INST);
  53. break;
  54. case DL_I2C_IIDX_CONTROLLER_RXFIFO_TRIGGER:
  55. gI2C.status = I2C_STATUS_RX_INPROGRESS;
  56. /* Store bytes received from target in Rx Msg Buffer */
  57. while (DL_I2C_isControllerRXFIFOEmpty(I2C_controller_INST) != true) {
  58. if (gRxADCcount < gRxADClen) {
  59. gRxPacket[gRxADCcount] =
  60. DL_I2C_receiveControllerData(I2C_controller_INST);
  61. //printf("Received Byte[%d]: 0x%02X\n", gRxADCcount,
  62. // gRxPacket[gRxADCcount]); // Debug print
  63. gRxADCcount++;
  64. } else {
  65. // printf("ERROR: RX Buffer Overflow! ptr=%d MAX_BUFFER_SIZE=%d\n",
  66. // gI2C.rxMsg.ptr, MAX_BUFFER_SIZE);
  67. /* Ignore and remove from FIFO if the buffer is full */
  68. DL_I2C_receiveControllerData(I2C_controller_INST);
  69. }
  70. }
  71. if (gRxADCcount >= gRxADClen) {
  72. // printf("ADC Bytes Received!\n");
  73. gRxComplete = true;
  74. DL_I2C_enableInterrupt(I2C_controller_INST,
  75. DL_I2C_INTERRUPT_CONTROLLER_STOP);
  76. }
  77. break;
  78. /*TRANSMIT data to ADC*/
  79. case DL_I2C_IIDX_CONTROLLER_TXFIFO_TRIGGER:
  80. // printf("TX FIFO with data!\n");
  81. gI2C.status = I2C_STATUS_TX_INPROGRESS;
  82. if (gTxADCcount < gTxADClen) {
  83. gTxADCcount += DL_I2C_fillControllerTXFIFO(I2C_controller_INST,
  84. &gTxPacket[gTxADCcount],
  85. (gTxADClen - gTxADCcount));
  86. } else {
  87. /*Prevent overflow and just ignore data*/
  88. DL_I2C_fillTargetTXFIFO(I2C_controller_INST, (uint8_t[]){0x00}, 1);
  89. gTxComplete = true;
  90. }
  91. // DL_I2C_flushControllerTXFIFO(I2C_controller_INST);
  92. break;
  93. /*STOP condition*/
  94. case DL_I2C_IIDX_CONTROLLER_STOP:
  95. gTxComplete = true;
  96. gRxComplete = true;
  97. // printf("I2C Stop Detected- RX Complete");
  98. break;
  99. case DL_I2C_IIDX_CONTROLLER_ARBITRATION_LOST:
  100. // printf("Interrupt index for I2C controller Arbitration Lost!\n");
  101. break;
  102. case DL_I2C_IIDX_CONTROLLER_NACK:
  103. // printf("I2C NACK Received\n");
  104. if ((gI2C.status == I2C_STATUS_RX_STARTED) ||
  105. (gI2C.status = I2C_STATUS_TX_STARTED)) {
  106. gI2C.status = I2C_STATUS_ERROR;
  107. }
  108. break;
  109. default:
  110. break;
  111. }
  112. }
  113. /**** Interrupt for Main MCU to Target MCU ****/
  114. void I2C_target_INST_IRQHandler(void) {
  115. uint32_t status = DL_I2C_getPendingInterrupt(I2C_target_INST);
  116. //printf("status: %d\n", status);
  117. switch (status) {
  118. case DL_I2C_IIDX_TARGET_START:
  119. DL_I2C_flushTargetTXFIFO(I2C_target_INST);
  120. break;
  121. case DL_I2C_IIDX_TARGET_STOP:
  122. mcuCommandPending= true;
  123. DL_I2C_flushTargetTXFIFO(I2C_target_INST);
  124. DL_I2C_flushTargetRXFIFO(I2C_target_INST);
  125. break;
  126. case DL_I2C_IIDX_TARGET_RXFIFO_TRIGGER:
  127. //printf("Rx Interrupt Triggered \n");
  128. if (DL_I2C_isTargetRXFIFOEmpty(I2C_target_INST)) {
  129. return;
  130. }
  131. mcuCommandPending= true;
  132. break;
  133. case DL_I2C_IIDX_TARGET_TXFIFO_TRIGGER:
  134. mcuCommandPending= true;
  135. //printf("Tx interrupt triggered.\n");
  136. break;
  137. case DL_I2C_IIDX_TARGET_ARBITRATION_LOST:
  138. break;
  139. default:
  140. break;
  141. }
  142. }
  143. /***Main Function***/
  144. int main(void){
  145. SYSCFG_DL_init();
  146. Battery_Init();
  147. // Reset_I2C_Bus();
  148. NVIC_EnableIRQ(I2C_target_INST_INT_IRQN);
  149. NVIC_EnableIRQ(I2C_controller_INST_INT_IRQN);
  150. printf("*******Scanning the peripherals********\n");
  151. //I2C Scanning
  152. I2C_scanBus(I2C_controller_INST);
  153. I2C_init(&gI2C);
  154. while(1){
  155. if(mcuCommandPending){
  156. mcu_i2c_handle(I2C_target_INST);
  157. mcuCommandPending= false;
  158. continue;
  159. }
  160. // Looping through the ADC Channels
  161. for (uint8_t slot_id = 0; slot_id < NUM_SLOTS; slot_id++) {
  162. for (uint8_t adc_channel = 0; adc_channel < ADC_CHANNEL_NUM; adc_channel++) {
  163. updateADCReading_multichannel(slot_id, adc_channel);
  164. }
  165. }
  166. delay_cycles(DELAY_CYCLE);
  167. }
  168. }