/* * This file implements Hardware Abstraction Layer (HAL) to make the I2C * communication of MSPM0 SDK compatible with ADC (MCP3426/7/8) and DAC * (MCP34728) */ #include "src/interfaces/i2c_controller.h" #include "ti/driverlib/dl_i2c.h" #include "ti_msp_dl_config.h" #include /* static function is for implementing Data Hiding, access to the static function is restricted to the file where they are declared const keyword for 'i2c_addr' and 'Data_length' makes the variable immutable. const uint8_t * const Data: means the pointer to the variable and the value of Data is immutable */ I2CRxPackage controllerRxPackage; I2CTxPackage controllerTxPackage; static bool msp_i2c_write(uint8_t const i2c_addr) { // Flush any stale data in TX FIFO: DL_I2C_flushControllerTXFIFO(I2C_controller_INST); // **Check if the I2C bus is stuck before WRITE if (DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_ERROR) { #ifdef DEBUG_I2C_ERR printf("I2C Communication: Bus is stuck!\n"); #endif DL_I2C_resetControllerTransfer(I2C_controller_INST); return false; } // **Wait for I2C Bus to be Free** uint32_t n_cycles = 0; while ((DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS) && n_cycles++ < MAX_I2C_WAIT_RX) ; if (n_cycles == MAX_I2C_WAIT_RX) { printf("Error in reading from I2C Bus: Bus is not getting ready before transmit start\n"); DL_I2C_resetControllerTransfer(I2C_controller_INST); return false; } // **Start I2C Write Transaction** DL_I2C_startControllerTransfer(I2C_controller_INST, i2c_addr, DL_I2C_CONTROLLER_DIRECTION_TX, controllerTxPackage.len); // **Load Configuration Byte into TX FIFO** DL_I2C_fillControllerTXFIFO(I2C_controller_INST, controllerTxPackage.packet, controllerTxPackage.len); #ifdef DEBUG_I2C_TX for (uint8_t i = 0; i < controllerTxPackage.len; i++) { printf("Sending 0x%02X\n", controllerTxPackage.packet[i]); } #endif n_cycles = 0; while ((DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS) && n_cycles++ < MAX_I2C_WAIT_RX) ; if (n_cycles == MAX_I2C_WAIT_RX) { printf("Error in reading from I2C Bus: Bus is not getting ready after transmit data\n"); DL_I2C_resetControllerTransfer(I2C_controller_INST); return false; } // **Check if the target address is incorrect if (DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_ADDR_ACK) { #ifdef DEBUG_I2C_ERR printf("I2C Write Error: Target Address not acknowledged!\n"); #endif return false; } // **Check for any WRITE error if (DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_ERROR) { #ifdef DEBUG_I2C_ERR printf("I2C Write Error: Bus error after sending data.\n"); #endif return false; } return true; } static bool msp_i2c_read(uint8_t const i2c_addr) { // Flush any stale data in TX FIFO: DL_I2C_flushControllerRXFIFO(I2C_controller_INST); uint32_t n_cycles = 0; while ((DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS) && n_cycles++ < MAX_I2C_WAIT_RX) ; if (n_cycles == MAX_I2C_WAIT_RX) { printf("Error in reading from I2C Bus: Bus is not getting ready before transmit start\n"); } DL_I2C_startControllerTransfer(I2C_controller_INST, i2c_addr, DL_I2C_CONTROLLER_DIRECTION_RX, controllerRxPackage.len); n_cycles = 0; while ((DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS) && n_cycles++ < MAX_I2C_WAIT_RX) ; if (n_cycles == MAX_I2C_WAIT_RX) { printf("Error in reading from I2C Bus: Bus is not getting ready after transmit start\n"); } DL_I2C_enableInterrupt(I2C_controller_INST, DL_I2C_INTERRUPT_CONTROLLER_RXFIFO_TRIGGER); return true; } /** * this function discovers on the i2c bus the devices from the address * to ensure all relevant bus participants are present */ bool i2c_discover(uint8_t i2c_addr) { if (DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS) { DL_I2C_disableController(I2C_controller_INST); // Disable I2C DL_I2C_enableController(I2C_controller_INST); // Re-enable I2C } #ifdef DEBUG_I2C_TX printf("Scanning 0x%02X\n", i2c_addr); #endif DL_I2C_startControllerTransfer(I2C_controller_INST, i2c_addr, DL_I2C_CONTROLLER_DIRECTION_RX, 1); delay_cycles(5000); uint32_t i2c_status = DL_I2C_getControllerStatus(I2C_controller_INST); bool found = !(DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_ERROR); DL_I2C_disableController(I2C_controller_INST); DL_I2C_enableController(I2C_controller_INST); return found; } I2C_Interface i2c_hal = { .write = msp_i2c_write, .read = msp_i2c_read, };