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.

CCS/MSP430FR2311: Software I²C is leading to ISR trap

Part Number: MSP430FR2311
Other Parts Discussed in Thread: MSP430FR2111

Tool/software: Code Composer Studio

Hi there folks,

I'm having a problem with the Software I²C that is found in this guide http://www.ti.com/lit/an/slaa703/slaa703.pdf . When I'm executing on my MSP430FR2311, it enters an ISR trap after calling TIMER_ITERATION() (sometimes it loops and calls this function more than once before entering trap).

I've changed the timers to use the Timer B (since MSP430FR2311 doesn't have the Timer A), and I left the pins untouched (the software I²C uses exactly the pins I need).

My main.c is as below:

#include <stdint.h>
#include <stdbool.h>
#include <msp430.h>
#include "msp430_swi2c_master.h"

void main(void)
{
    WDTCTL = WDTPW | WDTHOLD;                          // Stop watchdog timer

    PM5CTL0 &= ~LOCKLPM5;                              // Disable the GPIO power-on default high-impedance mode
    // to activate previously configured port settings

    // Configure one FRAM waitstate as required by the device datasheet for MCLK
    // operation beyond 8MHz _before_ configuring the clock system.
    FRCTL0 = FRCTLPW | NWAITS_1;

    __bis_SR_register(SCG0);                           // disable FLL
    CSCTL3 |= SELREF__REFOCLK;                         // Set REFO as FLL reference source
    CSCTL0 = 0;                                        // clear DCO and MOD registers
    CSCTL1 &= ~(DCORSEL_7);                            // Clear DCO frequency select bits first
    CSCTL1 |= DCORSEL_5;                               // Set DCO = 16MHz
    CSCTL2 = FLLD_0 + 487;                             // DCOCLKDIV = 16MHz
    __delay_cycles(3);
    __bic_SR_register(SCG0);                           // enable FLL
    while(CSCTL7 & (FLLUNLOCK0 | FLLUNLOCK1));         // FLL locked

    CSCTL4 = SELMS__DCOCLKDIV | SELA__REFOCLK;        // set default REFO(~32768Hz) as ACLK source, ACLK = 32768Hz
    // default DCOCLKDIV as MCLK and SMCLK source

    SWI2C_I2CTransaction myTransaction;
    uint8_t myBuffer[1] = {0xFF};

    /* Initializing the master */
    SWI2C_initI2C();

    /* Setting up the transaction */
    myTransaction.address = 0x38;
    myTransaction.writeBuffer = myBuffer;
    myTransaction.numWriteBytes = 1;

    if(!SWI2C_performI2CTransaction(&myTransaction))
    {
        /* Handle Error Code Here */
    }

    while(1);
}

The part that the code hangs is located in msp430_swi2c_master.c.

        /* Loop to read until all bits have been read */
        do
        {
            /* Priming our temporary variable and sending a clock pulse */
            temp = (temp << 1);
            SWI2C_SCL_HIGH;
            TIMER_ITERATION();
            
            /* If the data line is high, recording that */
            if (SWI2C_PxIN & SWI2C_SDA) 
            {
              temp += 1;
            }
            
            /* Send out another clock cycle and decrement our counter */
            bits = (bits - 1);
            SWI2C_SCL_LOW;
            TIMER_ITERATION();
        }

I've tried increasing stack size up to 1000kB (almost the entire RAM), but no success. Also, I've tried to modify the source code for the MSP430FR2111 (found on this guide http://www.ti.com/lit/an/slaa714/slaa714.pdfd) and the result is the same. Is there an additional configuration I'm missing?

  • Since I don't see any interrupts being enabled anywhere, my first guess is an NMI. What do SYSSNIV and SYSUNIV say?
  • Not sure what to expect from these registers, never dealt with them before...

    UPDATE: From what I've read, there's an Oscillator Fault IFG and a Vacant Memory Acess IFG. So I changed the clock two times, one without configuring at all (so the default values would kick in), and one using the software trim example. Neither of them worked. As for the VMAIFG, I've no idea what I could do.

  • I'm not quite sure how VMAIFG appears in SYSSNIV, since (by convention at least) the xxxIV registers only contain Enabled IFGs, and I don't see VMAIE being set anywhere.

    That said: What I find more disturbing is the number of uninitialized fields being looked at by the SWI2C library -- even when using the SLAA703 example main() program. That code fragment where the failure occurred is in SWI2C_readData, but you didn't ask it to read anything, suggesting that numReadBytes was (accidentally) non-0. That function stores bytes using the readBuffer pointer, which hasn't been initialized (hmm, sounds like a recipe for a VMAIFG).

    Does anything change if you make myTransaction a global? Just skimming, it looks like 0s will be OK for the otherwise-unused fields.
  • Bruce McKenney47378 said:
    Does anything change if you make myTransaction a global? Just skimming, it looks like 0s will be OK for the otherwise-unused fields.

    For some reason, the code works this way - putting 0 in numReadBytes or making myTransaction global - (thanks btw)!

    Edit: figured out that globals are initialized to 0. Unfortunately, the example code provided in slaa703.pdf doesn't work without these modifications.

  • Yes, simple_example.c is incorrect (I figured that's where you got it). I suppose it "works" if you run it out of powerup, before anything dirties the stack, but it seems it could have used a bit more exercise..

**Attention** This is a public forum