| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- /*
- References:
- https://stackoverflow.com/questions/246127/why-is-volatile-needed-in-c
- */
- #include "i2c_target.h"
- #include "src/battery_data/battery.h"
- #include "ti/driverlib/dl_i2c.h"
- #include <stdio.h>
- #include <string.h>
- #include "src/peripherals/dac/dac.h"
- #include <inttypes.h>
- #include "src/config.h"
- #include "ti_msp_dl_config.h"
- #include "src/peripherals/temp/tmp1075.h"
- /**
- * Dynamic addressing function
- * 1. set resistor to pullup
- * 2. measure gpio:
- * is it up, set the address +0, else set it +1
- * 3. disable the pullup again, so there is no current wasted
- */
- void initialize_target_address() {
- uint8_t add = 0;
- if (DL_GPIO_readPins(GPIOS_PORT, GPIOS_ADDR_PIN)) {
- add = 1;
- addr_offset = 4;
- }
- DL_I2C_setTargetOwnAddress(I2C_target_INST, I2C_TARGET_BASE_ADDRESS+add);
- DL_I2C_enableTargetOwnAddress(I2C_target_INST);
- }
- /*Function to Rx and Tx data from Target to Controller*/
- // The code has multiple i2c instances (multiple MCUs connected) from which we
- // need to select the right one, passing a pointer as an argument
- int8_t mcu_i2c_handle(I2C_Regs *i2c) {
- if (DL_I2C_isTargetRXFIFOEmpty(i2c)) {
- return -1;
- }
-
- uint8_t receivedByte = DL_I2C_receiveTargetData(i2c);
- uint8_t receivedCommand = (receivedByte & 0x0F);
- uint8_t slot = ((receivedByte & 0xF0) >> 4);
- if (receivedCommand == CMD_GET_MEASUREMENT) {
- DL_I2C_flushTargetTXFIFO(i2c);
- DL_I2C_fillTargetTXFIFO(i2c, (uint8_t *)&battery_slots[slot].measurement, 8);
- } else if (receivedCommand == CMD_SET_CURRENT) {
- return slot;
- } else if (receivedCommand == CMD_CLEAR_ERR) {
- if (slot > NUM_SLOTS) {
- DL_I2C_flushTargetTXFIFO(i2c);
- return -1;
- }
- *battery_slots[slot].state = SLOT_STATE_OK;
- }
- DL_I2C_flushTargetRXFIFO(i2c);
- return -1;
- }
- void mcu_i2c_handle_read(I2C_Regs *i2c, uint8_t slot) {
- // Read incoming bytes from the Controller:
- uint8_t rx_index = 0;
- uint8_t rx_buffer[2] = {0x00, 0x00};
- while (rx_index < 2) {
- // TODO: Need to have a workaround, currently the code is getting stuck on
- // the first trigger and provides result on the second trigger
- if (!DL_I2C_isTargetRXFIFOEmpty(i2c)) {
- rx_buffer[rx_index] = DL_I2C_receiveTargetData(i2c);
- rx_index++;
- }
- }
- if (rx_index != 2) {
- #ifdef DEBUG_TARGET
- printf("ERROR: Incomplete I2C Rx: received %d bytes\n", rx_index);
- #endif
- DL_I2C_flushTargetRXFIFO(i2c);
- rx_index = 0;
- return;
- }
- battery_slots[slot].set_current = *((int16_t*)(&rx_buffer[0]));
-
- #ifdef DEBUG_TARGET
- printf("Slot id: %d, Current: %d mA (Bytes 0x%02X 0x%02X)\n", slot, battery_slots[slot].set_current, rx_buffer[0], rx_buffer[1]);
- #endif
- /*
- // This code is for debugging:
- // you can shoot directly code to the DAC / PWM for debugging
- if (battery_slots[slot].set_current >= 0) {
- DAC_SingleWrite(slot, battery_slots[slot].set_current);
- } else if (battery_slots[slot].set_current < 0) {
- DL_TimerG_setCaptureCompareValue(PWM_0_INST, -1*battery_slots[slot].set_current, DL_TIMER_CC_1_INDEX);
- } else {
- // do nothing, charge or discharge
- #ifdef DEBUG_TARGET
- printf("state is idle");
- #else
- ;
- #endif
- } */
- }
|