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.

Tricky SD Card Bug. Maybe a stack problem?

Other Parts Discussed in Thread: MSP430FR5969

Hi All,

I am currently building a datalogger with an MSP430FR5969, and I have run into a bug that has completely stumped me. I will try to explain the problem clearly. The main code I am referring to can be found on Github here.

My datalogging code follows a specific flow. After the MSP430 is turned on and the watchdog timer is turned off, the uC will wait for the user to press a button, signifying the logging period. The data logger will then read the time from a real time clock, and then set the RTC alarm for the next even 10 second value (10, 20, 30, etc.) and go to sleep. When the 10 second value arrives, the RTC wakes the uC from sleep, the uC takes some readings, sets the RTC alarm to fire at 10 seconds from now, and goes back to sleep. This process repeats until the user tells it to stop. I wrote all of this before adding any code for the SD card so I can make sure the general flow of the program is correct. The code snippet below, shows the very first iteration of this process.

	  MLX90615Sleep();						// Put MLX to sleep
	  DS3231GetCurrentTime();					// Get current time
	  DS3231ClearAlarm1Bits();					// Clear alarm bits
	  DS3231SetAlarm1Round10Sec();				        // Set alarm for nearest 10 second value-ish
	  DS3231TurnAlarm1On();						// Turn on alarm
	  i2cSetReset();					        // Reset I2C so LPM is achieved
	  __bis_SR_register(LPM0_bits);				        // Enter LPM0
	  P4OUT |= BIT6;	        // Red LED debug
	  DS3231GetCurrentTime();					// Get current time. Should meet (seconds % 10 == 0) cond. at this point
	  DS3231SetAlarm1Plus10Sec();				        // Set alarm for +10 sec
	  P1OUT &= ~BIT0;						// Turn off green light
	  P4OUT &= ~BIT6;	        // Red LED debug
	  P1IES |= BIT1;						// Enable interrupts for P1.1 Button
	  P1IE |= BIT1;
	  i2cSetReset();						// Reset I2C so LPM is achieved

The code above works just fine when the SD card code isn't added. However, as soon as I add the SD Card initialization code (see here), the uC will get stuck in whatever line comes right after __bis_SR_register(LPM0_bits) line above. I have tried several different lines after that line, and it will always get stuck there which makes me think that the microcontroller cannot exit low power mode.

Here is my thought process when debugging:

  • My first thought is that the RTC is failing to wake the microcontroller from sleep. I have the uC to wake up on a falling edge, and the RTC drives the line low when the alarm fires so I thought that there might be a communication problem. Here is a screenshot of when the program is working, and here is a screenshot of when the program is not working. As you can see, in the working code the RTC drives the line low at once at the beginning and again at regular intervals, while in the not working code the line gets driven low but never comes up again. This makes me believe that the program is hanging in the interrupt, because I tell the RTC to bring the line back up after I exit LPM. It also shows that the signal that would wake the uC up (high to low transition) does happen.
  • I don't think this is a hardware problem because the thing that causes the bug is simply adding a few lines of code.
  • The SD card is using the eUSCIA module, while all the I2C sensors are on the eUSCIB module - I would think it's unlikely that my SD card code messes up the sensor communication. In addition, I have tried my real time clock alongside my SD card in other code and it seems to work fine.
  • The I2C communication is identical before the uC goes into sleep mode (other than the times read from the RTC of course). The comparison from logic analyzer can be seen here if you are curious.
  • The other thing I thought could be the problem is a stack overflow. I increased the stack size in CCS but that didn't change anything. I don't know how to change the stack size from the linker file, especially for a FRAM product. Is it possible that this is due to the stack size? If so, what can I do to increase the stack size? The MSP430FR5969 has a lot of room in FRAM and 2kB in SRAM.
  • The SD card and the sensors I'm currently using all work independently of each other.

I apologize for the wall of text but I'm at a loss and I wanted to provide as much detail as possible. I'd be happy to provide more code or detail, or answer any questions that people have if I can.

Thanks in advance for any help!

- NG 

  • Merging codes is always hard, I would guess the added code messes with lpm modes, GIE and/or aclk/smlk sources.
    As you never know what lpm mode the programmer wanted as the default and it's IRQ may use bis_exit_lmp3 etc

    Just add little of the code at a time and let us know when it stops working.

    P.S when inserting SD cards, they do sometime cause a brownout due to the power-inrush.
    Putting a 10ohm resistor on sdcards Vcc helps or protect the msp430 Vcc with 47ohm and a 10uA cap.

  • Hi Tony,

    Thank you for your quick reply. I am using FatFS and the only platform specific code in it is the diskio.c file. As far as I can tell, the code doesn't use any interrupts (is it possible to use interrupts without a handler?) but it does turn them on and off (see here). However, since it restores it to the same state, would that really affect anything? As for the interrupt handler I use to wake the processor up, it is the following:

    // Port 1 interrupt service routine
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=PORT1_VECTOR
    __interrupt void Port_1(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(PORT1_VECTOR))) Port_1 (void)
    #else
    #error Compiler not supported!
    #endif
    {
    	  flag = P1IV;
    	  P1IFG &= ~(BIT1 | BIT3);                  // Clear P1.1, 1.3 IFG
    	  __bic_SR_register_on_exit(LPM0_bits);     // Exit LPM0
    }

    I try to make sure the exit command uses the same low power mode that I set it as. Thank you for the tip about the resistors. I have pull-ups on the SD card but I don't think I have a capacitor.

    - NG 

  • Tony was correct, the added code was messing with GIE. For people reading this thread in the future, I found the exact cause of the problem. In the SD code I was using, I was turning the interrupts off, but I forgot to turn them on again. When I added the code to turn them on again, this problem disappeared. Hopefully this helps!

**Attention** This is a public forum