Bad interaction between SDFileSystem and FXOS8700Q libraries

24 Jul 2016

Hello,

I am using mbed to develop a small data logger, based on the NXP RD-KL25-AGMP01 platform:

http://www.nxp.com/products/sensors/gyroscopes/10-axis-sensor-data-logger-reference-design:RD-KL25-AGMP01

This hardware is based on the Kinetis KL25 microcontroller, and it has an OpenSDA debug interface, so I can make mbed code using the FRDM-KL25 platform as the base for it. I want to make a small acceleration logger, using the onboard microSD card connector and the FXOS8700CQ accelerometer/magnetometer combo, so I imported both SDFileSystem abd FXOS8700Q libraries.

My code has a calibration phase, where it collects the accelerations for 5 seconds and then calculates its average as an offset. Then, it opens a file in the SD card to save this offset and then start logging. However, the recorded accelerations were with their values all wrong. Also, I am using the green LED to blink after a certain number of samples, and it looks like the blinking period is dilated, which suggests a timeout in the accel readings. If I comment out all lines that control the SD card (sending data through serial to check it out), everything works fine. If I add just an fopen command, readings are wrong again. All readings before the fopen command are right.

So I believe there is some strange interaction between SPI and I2C interfaces when using mbed, and I have no idea on how to fix it.

The code is below. I am using the mbed-dev library, modified to change function of RESET pin, but I have also tried using the normal mbed library (just logging data without any command button), and the result is the same.

Here is the code

/* THIS PROGRAM USES A MODIFIED MBED-DEV LIBRARY!
   THE RESET BUTTON IS USED AAS A COMMAND PUSH BUTTON, FOR THIS THE STARTUP FILE WAS CHANGED
   SO THE FOPT REGISTER STARTS WITH THE 0xF7 VALUE (RESET DISABLED
*/

#include "mbed.h"
#include "FXOS8700Q.h"
#include "SDFileSystem.h"

FXOS8700Q_acc acc(PTC2, PTC1, FXOS8700CQ_SLAVE_ADDR0); // Proper Ports and I2C Address for RD board
// RGB LED
DigitalOut LEDR(PTB0);
DigitalOut LEDG(PTB1);
DigitalOut LEDB(PTD6);
DigitalIn detect(PTD4); // SD card inserted detection; logic level H if inserted
DigitalIn SW(PTA20); // Using RESET button as a command push button
SDFileSystem sd(PTC7, PTC6, PTC5, PTC4, "sd"); // Filesystem for SD card

char mainaxis = 0; // indicates axis at vertical: 1 for X, 2 for Y, 3 for Z
bool osc = false; // flag to indicate oscillation
FILE *fp; // File pointer
int16_t raX, raY, raZ; // Raw acc data
int32_t sx, sy, sz; // sum of samples for average during callibration
int16_t mx, my, mz; // averages for callibration

int main() {
    char k = 0;
    
    LEDR = 1;
    LEDG = 1;
    LEDB = 1;
    while(SW); // wait for button press
    
    acc.enable();
    LEDB = 0;
    sx = 0;
    sy = 0;
    sz = 0;
    
    for(k = 0; k < 125; k++) { // 125 samples, 40ms between them, total 5 seconds
        acc.getX(&raX);
        acc.getY(&raY);
        acc.getZ(&raZ);
        sx = sx + raX; // adding all samples
        sy = sy + raY;
        sz = sz + raZ;
        printf("%d, %d, %d\r\n", raX, raY, raZ);
        wait_ms(40);
    }
    mx = sx / 125; // average
    my = sy / 125;
    mz = sz / 125;
    
    // Defining the gravity axis
    mainaxis = 1;
    if(abs(my) > abs(mx)) mainaxis = 2;
    if(abs(mz) > abs(my) && abs(mz) > abs(mx)) mainaxis = 3;
    
    k = 0;
    if (detect) {
        //fp = fopen("/sd/osclog.txt", "w"); // open file if there is sd card
        //fprintf(fp, "OSCILLATION LOG\r\n");
        //fprintf(fp, "MEDIAS: %d, %d, %d\r\n", mx, my, mz);
        //fprintf(fp, "Main Axis: %d\r\n", mainaxis);
        //fprintf(fp, "--------------------------------------------------\r\n");
    }
    
    LEDB = 1;
    while(SW); //  wait for button press to start logging
    wait(0.1);
    while(!SW);
    wait(0.1);
    LEDG = 0;
    while (SW) {
        acc.getX(&raX);
        acc.getY(&raY);
        acc.getZ(&raZ);
        s = false;
        raX = raX - mx;
        raY = raY - my;
        raZ = raZ - mz;
        printf("%d, %d, %d\r\n", raX, raY, raZ);
        if (detect) { // record sample if there is SD card
            //fprintf(fp, "%d, %d, %d\r\n", raX, raY, raZ);
        }
        k++; // toggles green LED every 1 second
        if(k > 24) {
            k = 0;
            LEDG = !LEDG;
        }
        wait_ms(40);
    }
    LEDG = 1;
    if (detect) {
        //fclose(fp); // close file
    }
}