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.

MSP430FR2353: No I2C Interrupts

Part Number: MSP430FR2353
Other Parts Discussed in Thread: MSP430FR2355, HDC2080, HDC2022,

I am trying to port the sample code in /msp430fr2355_demo_with_hdc2080/main.c to our hardware (FR2353, HDC2022). I'm using USCI_B1.

The I2C peripheral is not generating an interrupt (never hits the breakpoint I set on the first statement in the ISR).

First of all, am I using the correct keyword in the statement below:

#pragma vector = USCI_B1_VECTOR

How about this?

#pragma vector = EUSCI_B1_VECTOR

Do both point to the same interrupt vector?  Both Build with no errors.

Here are some of my code snippets that were modified to match my hardware.

void initGPIO()
{

......... skipped lines

// I2C pins (P4.7 is SCL, P4.6 is SDA)
P4SEL0 |= BIT6 | BIT7;
P4SEL1 &= ~(BIT6 | BIT7);

.......skipped lines

}

void initI2C()
{
UCB1CTLW0 = UCSWRST; // Enable SW reset
UCB1CTLW0 |= UCMODE_3 | UCMST | UCSSEL__SMCLK | UCSYNC; // I2C master mode, SMCLK
UCB1BRW = 160; // fSCL = SMCLK/160 = ~100kHz
UCB1I2CSA = SLAVE_ADDR; // Slave Address
UCB1CTLW0 &= ~UCSWRST; // Clear SW reset, resume operation
UCB1IE |= UCNACKIE;
}

//******************************************************************************
// I2C Interrupt ***************************************************************
//******************************************************************************

#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = USCI_B1_VECTOR
__interrupt void USCI_B1_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_B1_VECTOR))) USCI_B1_ISR (void)
#else
#error Compiler not supported!
#endif
{
//Must read from UCB1RXBUF
uint8_t rx_val = 0;
switch(__even_in_range(UCB1IV, USCI_I2C_UCBIT9IFG))       <<<<<<<<<<<Breakpoint set here.....
{

.......

......

}





I2C_Mode I2C_Master_WriteReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data, uint8_t count)
{
/* Initialize state machine */
MasterMode = TX_REG_ADDRESS_MODE;
TransmitRegAddr = reg_addr;

//Copy register data to TransmitBuffer
CopyArray(reg_data, TransmitBuffer, count);

TXByteCtr = count;
RXByteCtr = 0;
ReceiveIndex = 0;
TransmitIndex = 0;

/* Initialize slave address and interrupts */
UCB1I2CSA = dev_addr;
UCB1IFG &= ~(UCTXIFG + UCRXIFG); // Clear any pending interrupts
UCB1IE &= ~UCRXIE; // Disable RX interrupt
UCB1IE |= UCTXIE; // Enable TX interrupt

UCB1CTLW0 |= UCTR + UCTXSTT; // I2C TX, start condition
__bis_SR_register(LPM0_bits + GIE); // Enter LPM0 w/ interrupts   <<<<<<<<<<<< HANGS HERE...............

return MasterMode;
}

When I run the program, it hangs on the line:

__bis_SR_register(LPM0_bits + GIE); // Enter LPM0 w/ interrupts

The breakpoint is not hit.

This is the first attempt to use I2C to talk to the HDC2022).

  • Hello jing,

    When posting code to the forum, please utilize the Insert- </>Code option so the code is formatted for readability. I've edited your post to reflect this. 

    To your question, I encourage you to look into the following resources to help you debug your issue.

    Solutions to Common eUSCI and USCI Serial Communication Issues on MSP430 MCUs  Specifically section 2 and section 5. 

    Check out our standard I2C example for this part: https://dev.ti.com/tirex/explore/node?node=AJwbT2zPMZ72BhFoNsQCdA__IOGqZri__LATEST

    And our MSP Academy that can walk you through utilizing I2c on MSP430 - In particular task three which is similar to your situation: https://dev.ti.com/tirex/explore/node?node=ANn42uDC4eb.Ph7o71nKTg__IOGqZri__LATEST

  • The I2C hardware will generate a transmit interrupt after it generates a start condition on the line. So if you get no interrupt, then something prevented the MSP430 from winning arbitration. You can enable an interrupt for that.

    But if you don't get past a start condition then there is something wrong at the hardware level. A lack of pullup resistors on SDA and SCL being a popular failure. Also, most MSP430FR series parts lock the ports until LOCKLPM5 is cleared. You don't show where you did that in your code fragments.

    As for which symbol to use for the interrupt routine, check the device header file: msp430fr2553.h. I checked the GNU version and it has only the EUSCI symbol defined.

  • Thanks for your reply.

    I do have the  PM5CTL0 &= ~LOCKLPM5; statement in the initGPIO() function.

    The msp430fr2353.h file also has only EUSCI_B0_VECTOR.  However, the program also compiles without errors if I use USCI_B0_VECTOR.

    I'm getting another board tomorrow.  Will see if this is hardware issue.  The 4.7K resistors on SDA and SCL are present.

  • It is pretty simple to check the state of SDA and SCL, just read P4IN. If you get anything other than 1's when the port is idle, then you have a hardware problem.

    It is fairly common for some convenience definitions be provided just in case you use a symbol that made sense on older hardware. If you are really concerned then check the headers or look at the output from the C compiler to see what it did.

  • Thanks for the suggestions.

    I finally figured out what was causing the problem.  I examined the I2C registers while in debug and noticed there were some incorrect values.  I realized then that I had forgotten to call the initI2C() function in main!