Conflict between accelerometer and ramdisk

The accelerometer outputs data correctly before the function setupRAM is called. After setupRAM is called the accelerometer outputs data as if the accelerometer was not correctly initialized. In other words, I can get the accelerometer to read correctly when setupRAM call is commented out.

//Add the SPI library so we can communicate with the ADXL345 sensor + SD Card + File time stamp
#include <SPI.h>
#include <SdFat.h>
#include <SdFatUtil.h>
#include <M23LCV1024.h>
#include <RamDisk.h>
#include <RTClib.h>
#include <Wire.h>

// Multiple SRAM chips so use CS pin list.
uint8_t csPins[] = {9, 8};
const uint8_t CHIP_COUNT = 2;
M23LCV1024 ram;

const uint8_t SD_CS_PIN = SS;

SdFat sd;
SdBaseFile sdFile;
RamVolume vol;
RamFile ramFile;
char buf[40];

/*  ADXL Connections
SCL => pin 13
SDA => pin 11
SDO => pin 12
CS => pin 5
*/

const int AccCS=5;               // Assign ADXL to pin 5     
const int inputPin = 2;          // input pin for the on/off switch.  The other side of switch goes to gnd
int count;
static boolean firstFlag = false;  // Flag to correct first read interval error

char FILENAME[15];
int fileNum = 0;                  // part of file name

// some of the registers available on the ADXL345.

char BW_RATE = 0x2C;     //Bandwidth Register
char POWER_CTL = 0x2D;	 //Power Control Register
char DATA_FORMAT = 0x31;  // g range setting 
char DATAX0 = 0x32;	//X-Axis Data 0
char DATAX1 = 0x33;	//X-Axis Data 1
char DATAY0 = 0x34;	//Y-Axis Data 0
char DATAY1 = 0x35;	//Y-Axis Data 1
char DATAZ0 = 0x36;	//Z-Axis Data 0
char DATAZ1 = 0x37;	//Z-Axis Data 1

char data[50];       // x,y,z data to be stored into SD Card
char values[10];    //This buffer will hold values read from the ADXL345 registers.

int x,y,z;         //These variables will be used to hold the x,y and z axis accelerometer values.

RTC_DS1307 RTC;   // define the Real Time Clock object 

//------------------------------------------------------------------------------
void setup(){  
 
  Serial.begin(115200);

  SPI.begin();                     //Initiate an SPI communication instance.
  SPI.setDataMode(SPI_MODE3);      //Configure the SPI connection for the ADXL345.  
  
  
  pinMode(AccCS, OUTPUT);                //Set up the Chip Select pin to be an output from the Arduino.  
  digitalWrite(AccCS, HIGH);             //Set Chip Select pin to high.
  writeRegister(DATA_FORMAT, 0x01);   //Put the ADXL345 into +/- 4G range by writing the value 0x01 to the DATA_FORMAT register.
  writeRegister(POWER_CTL, 0x08);     //Put the ADXL345 into Measure Mode by writing 0x08 to the POWER_CTL register.  
  writeRegister(BW_RATE, 0x0D);        //Set bandwidth to: E= 800 Hz, D=400, C=200, B=100, A=50
  pinMode(inputPin, INPUT);           // Switch input
  digitalWrite(inputPin, HIGH);       // turn on internal pull-up for on/off switch

  setupRAM();
}
//----------------------------------------------------------------------------  
void loop(){
   int val = digitalRead(inputPin);    // read on/off switch
  if (val == LOW)                      // if switch is LOW, take measurements
  {  
   readAcc();
  }
  else
  {
    if (firstFlag == true)
    {
        saveToSD();                     // save ram to SD
        fileNum++;                      //`increase file name by 1
        setupRAM();                     // get ready for the next measurement & format ram
    }
    count = 0;                        // count number of measurements
    firstFlag = false;                // reset first count interval flag
  }
}
//-------------------------------------------------------------------------------  
void setupRAM(){ 
   
  ram.begin(csPins, CHIP_COUNT);

  if (!sd.begin(SD_CS_PIN)) sd.errorHalt();
 

    if (!vol.format(&ram)) {
      Serial.println(F("format fail"));
      return;
    }
  if (!vol.init(&ram)) {
    Serial.println(F("init fail"));
    return;
  }
  Wire.begin();                            // add time stamp
  if (!RTC.begin()) {
    Serial.println("RTC failed");
    while(1);
  }
 
  SdFile::dateTimeCallback(dateTime);             // set date time callback function
  sprintf(FILENAME, "run_%d.CSV", fileNum);
  vol.remove(FILENAME);                           //format
   if (!ramFile.open(FILENAME, O_CREAT | O_RDWR)) {
    Serial.println(F("open fail"));
    return;
  }
  Serial.println(F("Ready to write ramFile"));
}
//-------------------------------------------------------------------
void saveToSD()
{
    // like closing and opening file (need to update dir for ls).
  ramFile.sync();
  ramFile.rewind();
  
//  vol.ls(&Serial, LS_DATE | LS_SIZE);

  if (!sdFile.open(FILENAME, O_CREAT | O_RDWR | O_TRUNC)) {
    Serial.println(F("sdFile.open failed"));
    return;
  }
  Serial.println(F("Copying ramFile to sdFile"));
  int n;
  while ((n = ramFile.read(buf, sizeof(buf))) > 0) {
   
    if (sdFile.write(buf, n) != n) {
      Serial.println(F("sdFile.write failed"));
      return;
    }
  }
  ramFile.close();
  sdFile.close();
  sd.ls(&Serial, LS_DATE | LS_SIZE);

  Serial.println(F("Done"));
}
//------------------------------------------------------------------------------  
void readAcc()  
{
  static const unsigned long READ_INTERVAL = 5;        // duration between Accelerometer reads in ms
  static unsigned long lastReadTime = millis();        // define for first loop
  static unsigned long MeasurementTime;                // determine time to do one measurement
  
//  static unsigned long MeasurementError;

  
  if(millis() - lastReadTime >= READ_INTERVAL)
  {

    lastReadTime = millis();
    SPI.setDataMode(SPI_MODE3);      //Configure the SPI connection for the ADXL345.
    //Reading 6 bytes of data starting at register DATAX0 will retrieve the x,y and z acceleration values from the ADXL345.
    //The results of the read operation will get stored to the values[] buffer.
    readRegister(DATAX0, 6, values);

    //The ADXL345 gives 10-bit acceleration values, but they are stored as bytes (8-bits). To get the full value, two bytes must be combined for each axis.
    //The X value is stored in values[0] and values[1].
    x = ((int)values[1]<<8)|(int)values[0];
    //The Y value is stored in values[2] and values[3].
    y = ((int)values[3]<<8)|(int)values[2];
    //The Z value is stored in values[4] and values[5].
    z = ((int)values[5]<<8)|(int)values[4];
  
    if (firstFlag) 
      {      
      //Print the results to the terminal.
  
     sprintf(data, "%d,%d,%d,%d",count,x,y,z);

    
      Serial.println(data);

      ramFile.println(data);

      count++;
      
      MeasurementTime = millis() - lastReadTime;
    }
    else
    {
      firstFlag = true;              // flag OK to get measurements
    }
  }

}
//----------------------------------------------------------------
//This function will write a value to a register on the ADXL345.
//Parameters:
//  char registerAddress - The register to write a value to
//  char value - The value to be written to the specified register.

void writeRegister(char registerAddress, char value){
  //Set Chip Select pin low to signal the beginning of an SPI packet.
  
//  Serial.println(registerAddress);
//  Serial.println(value);
  
  digitalWrite(AccCS, LOW);
  //Transfer the register address over SPI.
  SPI.transfer(registerAddress);
  //Transfer the desired register value over SPI.
  SPI.transfer(value);
  //Set the Chip Select pin high to signal the end of an SPI packet.
  digitalWrite(AccCS, HIGH);
}
//--------------------------------------------------------------------------------------
//This function will read a certain number of registers starting from a specified address and store their values in a buffer.
//Parameters:
//  char registerAddress - The register addresse to start the read sequence from.
//  int numBytes - The number of registers that should be read.
//  char * values - A pointer to a buffer where the results of the operation should be stored.
void readRegister(char registerAddress, int numBytes, char * values){
  //Since we're performing a read operation, the most significant bit of the register address should be set.
  char address = 0x80 | registerAddress;
  //If we're doing a multi-byte read, bit 6 needs to be set as well.
  if(numBytes > 1)address = address | 0x40;
  
  //Set the Chip select pin low to start an SPI packet.
  digitalWrite(AccCS, LOW);
  //Transfer the starting register address that needs to be read.
  SPI.transfer(address);
  //Continue to read registers until we've read the number specified, storing the results to the input buffer.
  for(int i=0; i<numBytes; i++){
    values[i] = SPI.transfer(0x00);
  }
  
  digitalWrite(AccCS, HIGH);   //Set the Chips Select pin high to end the SPI packet.
}
//--------------------------------------------------------------------------------
// call back for file timestamps
void dateTime(uint16_t* date, uint16_t* time) {
  DateTime now = RTC.now();

  // return date using FAT_DATE macro to format fields
  *date = FAT_DATE(now.year(), now.month(), now.day());

  // return time using FAT_TIME macro to format fields
  *time = FAT_TIME(now.hour(), now.minute(), now.second());
}

Thanks,
Gerry

I think the ADXL345 has a maximum SPI clock speed of 5 MHz.

RamDisk sets the SPI speed to 8 MHz each time it is called.

Try setting both the mode and speed like this:

  SPI.setDataMode(SPI_MODE3); 
  SPI.setClockDivider(SPI_CLOCK_DIV4);

I think the default SPI speed is 4 MHz.

Thanks, that works.
I placed:
SPI.setDataMode(SPI_MODE3);
SPI.setClockDivider(SPI_CLOCK_DIV4);

within the readAcc function.

Gerry