Part Number: MSP432P401R
I am using Driverlib to program my MSP432 as an I2C master to interact with a sensor. To be configured correctly the sensor requires a few registers to be set. When attempting to start sending bytes with the I2C_masterSendMultiByteStart function, it gets stuck in the loop that "Poll[s] for transmit interrupt flag and start condition flag." Relevant portions of my code are below.
The I2C_MasterConfig Struct:
/* I2C Master Configuration Parameter */ const eUSCI_I2C_MasterConfig i2cConfig = { EUSCI_B_I2C_CLOCKSOURCE_SMCLK, // SMCLK Clock Source 3000000, // SMCLK = 3MHz EUSCI_B_I2C_SET_DATA_RATE_100KBPS, // Desired I2C Clock of 100khz 0, // No byte counter threshold EUSCI_B_I2C_NO_AUTO_STOP // No Autostop };
main begins setting clock frequencies, GPIOs, and configuring I2C on eUSCIB0. BME280_setup() is entered, and is there the trouble is.
int main(void) { /* Disabling the Watchdog */ MAP_WDT_A_holdTimer(); CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_12); // DCO to 12MHz MAP_CS_initClockSignal(CS_SMCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_4); // HSMCLK to 3 MHz MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1, // P1.6 and P1.7 in I2C GPIO_PIN6 + GPIO_PIN7 + GPIO_PIN2 + GPIO_PIN3, // P1.2 and P1.3 in UART GPIO_PRIMARY_MODULE_FUNCTION); memset(BME280_RXTrimmingData, 0x00, TRIMMING_PARAM_BYTES); memset(BME820_RXData, 0x00, BME280_REC_BYTES); /* I2C Setup */ MAP_I2C_initMaster(EUSCI_B0_BASE, &i2cConfig); // init I2C B0 MAP_I2C_setSlaveAddress(EUSCI_B0_BASE, BME280_I2C_ADDRESS); // set BME slave address MAP_I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_MODE); // set transmit mode to initially set sensor register values MAP_I2C_enableModule(EUSCI_B0_BASE); // enable I2C to start operations MAP_Interrupt_enableInterrupt(INT_EUSCIB0); // enable I2C interrupt BME280_setup();
Here is void BME280_setup():
void BME280_setup() { // set slave address and set to transmit mode MAP_I2C_setSlaveAddress(EUSCI_B0_BASE, BME280_I2C_ADDRESS); // BME280_I2C_ADDRESS defined as ((uint_fast16_t)0x77), consistent with the sensor's datasheet. MAP_I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_MODE); // set CONFIG - Disable IIR filtering MAP_I2C_masterSendMultiByteStart(EUSCI_B0_BASE, BME280_CONFIG_ADDR); // BME280_CONFIG_ADDR defined as ((uint8_t)0xF5), consistent with the sensor's datasheet MAP_I2C_masterSendMultiByteNext(EUSCI_B0_BASE, BME280_CONFIG_FILTER_OFF); // set CTL_MEAS - Pressure, Temperature 1 x oversample, Forced Mode MAP_I2C_masterSendMultiByteNext(EUSCI_B0_BASE, BME280_CTL_MEAS_ADDR); MAP_I2C_masterSendMultiByteNext(EUSCI_B0_BASE, BME280_CTL_MEAS_FORCED); // set CTL_HUM - Humidity 1 x oversample MAP_I2C_masterSendMultiByteNext(EUSCI_B0_BASE, BME280_CTL_HUM_ADDR); MAP_I2C_masterSendMultiByteFinish(EUSCI_B0_BASE, BME280_HUM_OS_1); /* Making sure the last transaction has been completely sent out */ while (MAP_I2C_masterIsStopSent(EUSCI_B0_BASE)); // get trimming parameters BME280_read_trimming_parameters(); }
MAP_I2C_masterSendMultiByteStart() is the driverlib function from i2c.c:
void I2C_masterSendMultiByteStart(uint32_t moduleInstance, uint8_t txData) { //Store current transmit interrupt enable uint16_t txieStatus = EUSCI_B_CMSIS(moduleInstance)->IE & EUSCI_B_IE_TXIE0; //Disable transmit interrupt enable BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IE, EUSCI_B_IE_TXIE0_OFS) = 0; //Send start condition. EUSCI_B_CMSIS(moduleInstance)->CTLW0 |= EUSCI_B_CTLW0_TR + EUSCI_B_CTLW0_TXSTT; //Poll for transmit interrupt flag and start condition flag. while (BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->CTLW0, EUSCI_B_CTLW0_TXSTT_OFS) || !BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->IFG, EUSCI_B_IFG_TXIFG0_OFS)); //Send single byte data. EUSCI_B_CMSIS(moduleInstance)->TXBUF = txData; //Reinstate transmit interrupt enable EUSCI_B_CMSIS(moduleInstance)->IE |= txieStatus; }
That while loop is where it is getting stuck. But if it is waiting for a tx interrupt flag, two statements ago the tx IE was disabled. So how is that consistent with expecting the flag to be raised? Either way, the while loop should also terminate when the start condition flag is raised. The previous statement supposedly sends the start condition, but somehow that is not raising the start condition flag? It seems like there is something wrong in my configuration of eUSCIB0, but I'm not seeing where it differs from what is described in the docs.
Thanks in advance!