This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430FR5969 I2C driverlib issues

Other Parts Discussed in Thread: MSP430FR5969, CC3100

Hi all,

I recently purchased the MSP430FR5969 launchpad, and I'm trying to interface it with the SHT21 on the SensorHub boosterpack. However, I am having trouble with the MSP430 driverlib. First, let me post the relevant code:

Main code:

void main(void){
    WDT_A_hold(WDT_A_BASE);             // Stop watchdog
 
    // Set ACLK to extern crystal for TimerB use
    CS_clockSignalInit(CS_ACLK, CS_LFXTCLK_SELECT, CS_CLOCK_DIVIDER_1);
 
    // Configure pins as I2C
    GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1, GPIO_PIN6 + GPIO_PIN7, GPIO_SECONDARY_MODULE_FUNCTION);
 
    // Disable the GPIO power-on default high-impedance mode to activate previously configured port settings
    PMM_unlockLPM5();
 
    // Initialize master
    EUSCI_B_I2C_masterInit(EUSCI_B0_BASE,
                           EUSCI_B_I2C_CLOCKSOURCE_SMCLK,
                           CS_getSMCLK(),
                           EUSCI_B_I2C_SET_DATA_RATE_400KBPS,
                           1,
                           EUSCI_B_I2C_NO_AUTO_STOP
                           );
 
    tSHT2x ShtSensHub;
 
    while(1){
        // Read temperature
        SHT21ReadTemperature(&ShtSensHub);
 
        // Place breakpoint here
        __no_operation();
 
        // Delay
        __delay_cycles(500000);
    }
}

Read temperature function

// Used to read and convert temperature from SHT21
void SHT21ReadTemperature(tSHT2x *psInst){
    // Set SHT21 address
    EUSCI_B_I2C_setSlaveAddress(EUSCI_B0_BASE, SHT21_I2C_ADDRESS);
 
    //Set in transmit mode
    EUSCI_B_I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_MODE);
 
    //Enable I2C Module to start operations
    EUSCI_B_I2C_enable(EUSCI_B0_BASE);
 
    //Send single byte data.
    EUSCI_B_I2C_masterSendSingleByte(EUSCI_B0_BASE, SHT21_TEMP_NOBLOCK);
 
    //Delay until transmission completes
    while (EUSCI_B_I2C_isBusBusy(EUSCI_B0_BASE)) ;
 
    //Setup timer
    TIMER_B_clearTimerInterruptFlag(TIMER_B0_BASE);
    TIMER_B_configureUpMode(   TIMER_B0_BASE,
                               TIMER_B_CLOCKSOURCE_ACLK,
                               TIMER_B_CLOCKSOURCE_DIVIDER_1,
                               CS_getACLK()/11,
                               TIMER_B_TBIE_INTERRUPT_DISABLE,
                               TIMER_B_CAPTURECOMPARE_INTERRUPT_ENABLE,
                               TIMER_B_DO_CLEAR
                               );
 
    // Start timer
    TIMER_B_startCounter(
            TIMER_B0_BASE,
            TIMER_B_UP_MODE
            );
 
    //Enter LPM3, enable interrupts
    __bis_SR_register(LPM0_bits + GIE);
 
    // After interrupt has fired, set master to receive mode
    EUSCI_B_I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_MODE);
 
    // Send start
    EUSCI_B_I2C_masterReceiveStart(EUSCI_B0_BASE);
    while (EUSCI_B_I2C_isBusBusy(EUSCI_B0_BASE)) ;
 
    // Receive first byte
    psInst->i2cData[0] = EUSCI_B_I2C_masterMultiByteReceiveNext(EUSCI_B0_BASE);
    while (EUSCI_B_I2C_isBusBusy(EUSCI_B0_BASE)) ;
 
    // Receive second byte
    psInst->i2cData[1] = EUSCI_B_I2C_masterMultiByteReceiveNext(EUSCI_B0_BASE);
    while (EUSCI_B_I2C_isBusBusy(EUSCI_B0_BASE)) ;
 
    // Receive third (last) byte
    psInst->i2cData[2] = EUSCI_B_I2C_masterMultiByteReceiveFinish(EUSCI_B0_BASE);
    while (EUSCI_B_I2C_isBusBusy(EUSCI_B0_BASE)) ;
 
    // Disable I2C Module
    EUSCI_B_I2C_disable(EUSCI_B0_BASE);
 
    // Convert to temperature
    psInst->tempRaw = ((uint16_t)(psInst->i2cData[0]) << 8) | (uint16_t)(psInst->i2cData[1]);
    psInst->temp = (float)(psInst->tempRaw & 0xFFFC);
    psInst->temp = -46.85f + 175.72f * (psInst->temp/65536.0f);
}

The problem is this: when I upload the code, and I set a breakpoint at the no operation at the end of main, it never reaches it. When I pause the debugger, the code is not stopped specifically in my code, but in the function EUSCI_B_I2C_masterSendSingleByte, specifically on line 758: while (!(HWREG16(baseAddress + OFS_UCBxIFG) & UCTXIFG));  
I am not currently using I2C interrupts, and line 758 checks for an interrupt flags. Did I miss turning something on? Does anyone know what problem might be?

On a semi-related note, I found some errors in the documentation, and I would be happy to explain more if desired.

Thanks in advance!

  • During an ongoing transmission, the bus is busy all the time. That’s one of the criteria for ‘bus busy’. So while you’re waiting until the bus is no longer busy, you keep it busy yourself by not continuing and finishing the transfer.

    You only need to check whether the bus is busy before you start a transfer. Once the transfer is started, just keep going until done.

  • Hi Jens-Michael,

    Thank you very much, that makes sense, and it fixed the problem! I still haven't completely got it working yet, but that's for another time.

    Thanks again,
    Nipun

  • I understand why the while statements are in the wrong place, but I don't understand why this is his immediate problem that he mentions about in the first thread. The hangup occurred in masterSendSingleByte, but that comes before any while (EUSCI_B_I2C_isBusBusy(EUSCI_B0_BASE)) ; statements. I am having the same hangup. What's odd is that sometimes it gets stuck and sometimes it doesn't. The watchdog then takes over, resets the processor, and it may continue to work a few more times before hanging again. I'd start my own thread, but it seems related. I am also using the same launchpad with the CC3100 boosterpack so I have to switch between spi and i2c peripherals. Sometimes it works, sometimes it doesn't. There is never a problem on the spi bus. Only i2c.
  • I was reconfiguring the i2c bus for receive before the busy bit was cleared.

**Attention** This is a public forum