| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- /*
- * 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 <stdio.h>
- /*
- 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,
- };
|