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.

MSP432P401R: MSP432 I2C Repeat Start Example Code Hanging at Transmit Interrupt Poll

Part Number: MSP432P401R

Need a little help. I'm been trying to use the driverlib example I2C repeat start program to connect to a Si7051x temperature chip with very little luck. 

Problem 1: Only able to sample I2C on logic analyzer after pushing reset button. When capturing immediately after pushing the reset, this is what I get from analyzer.

 

 

 

 

 

The measure sequence for the Si7051 w/o clockstretching is on page 14 of this document.

http://www.silabs.com/documents/public/data-sheets/Si7050-1-3-4-5-A20.pdf

Problem 2: Stopping at following line when pausing debug. Looks as if nothing is going into the TXBUF 

//Poll for transmit interrupt flag.
while (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->rIFG.r, UCTXIFG_OFS))

The code I'm using is below: Thanks for the help.

#include "driverlib.h"

/* Standard Defines */

#include <stdint.h>

#include <stdbool.h>

#include <string.h>

#include <Si7051.h>

/* Slave Address for I2C Slave */

#define SLAVE_ADDRESS IC_ADDRESS_TMP7051_ADDRESS

#define NUM_OF_REC_BYTES 2

/* Variables */

//const uint8_t TXData[2] = 0;

static uint8_t RXData[NUM_OF_REC_BYTES];

static volatile uint32_t xferIndex;

static volatile bool stopSent;

/* 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

};

int main(void)

{

static volatile uint32_t ii;

/* Disabling the Watchdog */

MAP_WDT_A_holdTimer();

/* Select Port 1 for I2C - Set Pin 6, 7 to input Primary Module Function,

* (UCB0SIMO/UCB0SDA, UCB0SOMI/UCB0SCL).

*/

MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1,

GPIO_PIN6 + GPIO_PIN7, GPIO_PRIMARY_MODULE_FUNCTION);

//stopSent = false;

memset(RXData, 0x00, NUM_OF_REC_BYTES);

/* Initializing I2C Master to SMCLK at 100khz with no autostop */

MAP_I2C_initMaster(EUSCI_B0_BASE, &i2cConfig);

/* Specify slave address */

MAP_I2C_setSlaveAddress(EUSCI_B0_BASE, SLAVE_ADDRESS);

/* Set Master in transmit mode */

MAP_I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_MODE);

/* Enable I2C Module to start operations */

MAP_I2C_enableModule(EUSCI_B0_BASE);

/* Enable and clear the interrupt flag */

MAP_I2C_clearInterruptFlag(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT0);

MAP_I2C_clearInterruptFlag(EUSCI_B0_BASE, EUSCI_B_I2C_NAK_INTERRUPT);

MAP_I2C_clearInterruptFlag(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0);

//Enable master Transmit interrupt

MAP_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_NAK_INTERRUPT);

MAP_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT0);

MAP_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0);

MAP_Interrupt_enableSleepOnIsrExit();

MAP_Interrupt_enableInterrupt(INT_EUSCIB0);

while (1)

{

MAP_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0);

//MAP_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT0);

/* Making sure the last transaction has been completely sent out */

while (MAP_I2C_masterIsStopSent(EUSCI_B0_BASE) == EUSCI_B_I2C_SENDING_STOP);

/* Send start and the first byte of the transmit buffer. We have to send

* two bytes to clean out whatever is in the buffer from a previous

* send */

//MAP_I2C_masterSendSingleByte(EUSCI_B0_BASE, MEAS_TEMP_HOLD_REGISTER);

while (MAP_I2C_isBusBusy(EUSCI_B0_BASE) == EUSCI_B_I2C_BUS_BUSY);

// {

MAP_I2C_masterSendStart(EUSCI_B0_BASE);

MAP_I2C_masterSendMultiByteStart(EUSCI_B0_BASE, MEAS_TEMP_NOHOLD_REGISTER);

MAP_I2C_masterSendMultiByteNext(EUSCI_B0_BASE, MEAS_TEMP_NOHOLD_REGISTER);

/* Enabling transfer interrupt after stop has been sent */

MAP_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_RECEIVE_INTERRUPT0);

//MAP_Interrupt_enableSleepOnIsrExit();

//MAP_PCM_gotoLPM0InterruptSafe();

/* While the stop condition hasn't been sent out... */

// while(!stopSent)

//{

//MAP_PCM_gotoLPM0InterruptSafe();

//}

//stopSent = false;

/* Delay between Transmissions */

}

}

/*******************************************************************************

* eUSCIB0 ISR. The repeated start and transmit/receive operations happen

* within this ISR.

*******************************************************************************/

void EUSCIB0_IRQHandler(void)

{

uint_fast16_t status;

status = MAP_I2C_getEnabledInterruptStatus(EUSCI_B0_BASE);

MAP_I2C_clearInterruptFlag(EUSCI_B0_BASE, status);

// if (status & EUSCI_B_I2C_NAK_INTERRUPT)

// {

//MAP_I2C_masterSendSingleByte(EUSCI_B0_BASE, MEAS_TEMP_NOHOLD_REGISTER);

// }

/* If we reached the transmit interrupt, it means we are at index 1 of

* the transmit buffer. When doing a repeated start, before we reach the

* last byte we will need to change the mode to receive mode, set the start

* condition send bit, and then load the final byte into the TXBUF.

*/

if (status & EUSCI_B_I2C_TRANSMIT_INTERRUPT0)

{

//MAP_I2C_masterSendSingleByte(EUSCI_B0_BASE, MEAS_TEMP_HOLD_REGISTER);

MAP_I2C_masterSendMultiByteNext(EUSCI_B0_BASE, MEAS_TEMP_NOHOLD_REGISTER);

MAP_I2C_disableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0);

MAP_I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_MODE);

xferIndex = 0;

MAP_I2C_masterReceiveStart(EUSCI_B0_BASE);

MAP_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT0);

//MAP_I2C_masterReceiveMultiByteNext(EUSCI_B0_BASE);

}

/* Receives bytes into the receive buffer. If we have received all bytes,

* send a STOP condition */

if (status & EUSCI_B_I2C_RECEIVE_INTERRUPT0)

{

if(xferIndex == NUM_OF_REC_BYTES - 2)

{

MAP_I2C_masterReceiveMultiByteStop(EUSCI_B0_BASE);

RXData[0] = MAP_I2C_masterReceiveMultiByteNext(EUSCI_B0_BASE);

xferIndex++;

}

else if(xferIndex == NUM_OF_REC_BYTES - 1)

{

RXData[1] = MAP_I2C_masterReceiveMultiByteNext(EUSCI_B0_BASE);

MAP_I2C_disableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT0);

MAP_I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_MODE);

xferIndex = 0;

//stopSent = true;

//MAP_Interrupt_disableSleepOnIsrExit();

}

else

{

RXData[xferIndex++] = MAP_I2C_masterReceiveMultiByteNext(EUSCI_B0_BASE);

}

}

}

  • The logic analyzer screenshot was cut. Here it is hopefully.

  • InvoBlue,

    Ill look into this for you. Please give me a little time to dive into it and I'll get back to you as soon as possible.
  • InovBlue,

    A few questions.

    For problem one)
    1) When you launch debug and flash, when you click run, you see nothing on the I2C lines?
    2) After resetting, do you see any data in the RxData array? Does it change any?

    For the second problem)
    1) When you hang on the line of code below, what I2C DriverLib function call does it stop on in the main program you are working out of?
    //Poll for transmit interrupt flag.
    while (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->rIFG.r, UCTXIFG_OFS))

    When you pause debug, is there anything in the RxData array?
  • Evan, thanks for the support.

    Answering your questions.

    1. When I connect to the device and click the debug button and run, the SCL line is pulled low and remains low during each capture. My thoughts on this issue is that since I'm not making it completely to the end of the while(1) loop, its getting hung at the while (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->rIFG.r, UCTXIFG_OFS)) in the 

    MAP_I2C_masterSendMultiByteStart(EUSCI_B0_BASE, MEAS_TEMP_NOHOLD_REGISTER) routine. 

    Also noticed that it doesn't enter into the EUSCIB0_IRQHandler unless I first power cycle(unplug/re-plug). The when I debug, I'm able to step through the code and make it completely through EUSCIB0_IRQHandler 

    1. It always hangs in the MAP_I2C_masterSendMultiByteStart routine when paused.

    2. RXData receives data in RxData[0] only when I step through the routine after a power up. 

  • InvoBlue,

    Can you remove the following line before the I2C_sendMultiByteStart() call?

    MAP_I2C_masterSendStart(EUSCI_B0_BASE);

    SendMultiByteStart() already sends a start command and I think this is hanging it up somehow as the Si device is only expecting one start command.
  • I'm going to close this thread due to innactivity. If you have another question unrelated to the topic above, please post another thread, if you have any more questions related to this, feel free to post here and thread will reopen.
  • InovBlue,

    There has been an update actually to the example that you were working with with regards to the master/slave repeated start I2C examples. Can you please review and retry? This was to help alleviate a bug that seems to be similar to what you were seeing. 
    dev.ti.com/.../

  • Evan,

    Thanks for following up and making me aware of this change. I took a look and the ISR is much clearer and follows the technical reference manual's repeat start sequence. Will test later. Thanks.

  • InnovBlue,

    I'm going to close this thread due to inactivity. Feel free to respond to reopen the thread if needed if you have another question on this topic.

**Attention** This is a public forum