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. Attached are two screenshots from my logic analyzer of the interrupt signal when it is working and 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 (which happens in the interrupt). 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 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?
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.
Slightly unrelated, but people are free to use my sensor code for the FR5969 if they want. I've gotten the BMP180, SHT21, DS3231, and the MLX90615 working. It can be found here.
Thanks in advance for any help!