Jump to content
43oh

Help with SD Card module on TM4C123GXL


Recommended Posts

Hello,

 

I have a question regarding communication between my Tiva C EK-TM4C123GXL lauchpad and a generic SD Card breakout board.

 

Using:

  • Energia 0101E0013
  • Windows 8.1
  • SD Library (SD_TM4C)
  • 4 GB FujiFilm SD card

I CAN get the ReadWrite demo program in the SD library to work sucessfully by wiring everything up according to the 1-page pinout diagram that came with my board for the SPI bus.

 

Hardware wiring (SD breakout --> Launchpad):

 

SDCS  --> J2.9  /  PA3  /  12

MOSI  -->  J2.6  /  PB7  /  15

SCK    -->  J1.7  /  PB4  /  7

MISO  -->  J2.7  /  PB6  /  14

 

And then I change the ReadWrite code so that it looks like this:

void setup()
{
...
...
...
  pinMode(12, OUTPUT);
  pinMode(12, LOW);

  if (!SD.begin(12)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");
...
...
...
}

...and everything works just fine.

 

 

Here's where the problem comes in. I need to change the pins I'm using for the SD card because I'm going to use the Sensor Hub BoosterPack which uses (at least) J2.6 - J2.7 for I2C communication with the sensors. As far as my understanding goes, that means I need to find a different SPI bus for the SD card because I can't switch modes or devices easily.

 

I have tried wiring up to pins J3.3 - J3.6 and changing my code to this...

void setup()
{
...
...
...
  pinMode(24, OUTPUT);
  pinMode(24, LOW);

  if (!SD.begin(24, SPI_HALF_SPEED, 3)) {

    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");
...
...
...
}

... but the SD card never initializes correctly. I'm obviously missing something and/or not understanding this SP_TM4C library correctly.

 

Any help would be amazing.

 

Thank you!

Link to post
Share on other sites

As long as you don't have the sensor hub boosterpack or something else connected to J2.6-J2.7 (pins 15,14) don't know why it wouldn't work.

 

Why did you pick port SSI3?  Won't that make it conflict even more with the sensorhub boosterpack, since SSI3 shares actual pins with I2C port 3 (23 and 24).  (To get the I2C port 3 function on pins 15,14 on the boosterpack there are jumpers from pins 23 and 24.)

Link to post
Share on other sites

Thanks for the reply.

 

And, yes, the whole first half of my post was explaining that the SD card does work perfectly without the BoosterPack. When I add the sensor hub and use some code (which I've already verified that it works on its own) to get a pressure reading via I2C, both the sensor and the SD card initialize, but then there's always an error getting a reading from the sensor, which I attribute to both SD card and sensor being on the same physical pins. Since I need the sensor hub, I'm trying to move the SD card pins.

 

I was going off of page 4 of the Sensor Hub BoosterPack guide where it shows which pins it uses on the BoosterPack connecter. That table shows that J3.3 - J3.7 (23 - 26) are basically open. [used for buttons and sensor board LED, but I didn't think it would interfere with SPI3]. So I wired it up according to naming shown here for all the ____ (3) pins, but that didn't work.

 

I could try to use J4.1, J4.2, J4.9, and J4.10 (40, 39, 32, 31) because they look open on the BoosterPack connector, but I dont think those pins have SPI....

 

All I'm trying to do is use the Sensor Hub and the SD card together. It should be possible, right?

 

Is there something I'm not understanding with this whole SSI/SPI bus stuff?

Link to post
Share on other sites

Not sure if my previous post was clear - the point is that on the Tiva launchpad, pins 23 and 14 are shorted together (i.e. they are electrically identical).

Likewise for pins 24 and 15.  (See the note in lower left part of the wiring diagram).

 

So, unless you remove those 0 ohm shunts, connecting pin 23 is the same as connecting to pin 14.

 

Note that the I2C port 3 is pins 23 and 24.

You could remove the 0 ohm shunts, and redirect the wiring so that I2C port 3 is connected to the SensorHub, and use SSI port 2 for the SD card.

 

You could redo wiring and use I2C port 0, or 2 for the sensorHub (using SSI2 or SSI3 for the SD card).

Could try using SSI0 for the SD card (but with a different CS line than the default, so that it could coexist with SensorHub).

Link to post
Share on other sites
  • 4 weeks later...

Could use 40, 39, 17 and 30 (i.e. SSI 1).  Though has the onboard LEDs on some of those lines.

 

You are awesome!

 

I took a break from this project over winter break since I've been trying to figure out this issue for over a month and just got plain tired of it. Came back at it and took a look at what you had suggested. I found those shunts you were talking about. I did not see that at all in the datasheet.

 

Today, I hooked up both the Sensor Board and the SD card (using SSI 1). I had to fiddle with my code for a few minutes, but I got it to work! After months of researching and experimenting with the wiring, it finally works.

 

Thank you so much, @@igor. You saved this project. :)

 

Yeah, it does light up the RGB led, but I don't mind. It makes for a nice visualization when data is being written.

 

 

For anyone else who might come across this, I have posted my code below for Energia. Besides adding more sensors to the log, I want to modify this code so that when you press one of the user buttons, it will stop logging and make sure the file is closed. Wasn't important for now.

 

I hope this helps somebody else.

#include <SFE_BMP180.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>

File myFile;

// You will need to create an SFE_BMP180 object, here called "pressure":
SFE_BMP180 pressure;

#define ALTITUDE 1655.0 // Altitude of SparkFun's HQ in Boulder, CO. in meters

const int SD1_CS = 24;
const int SPI_PORT = 1;
const int LOG_DELAY = 2000; // Wait before retrieving and storing new value(s)

boolean LogData( int value );
void errorLoop();

void setup()
{ 
  Serial.begin(9600);
  Serial.println("REBOOT");
  
  Serial.print("Initializing SD Card: ");
  pinMode(SD1_CS, OUTPUT);
  digitalWrite(SD1_CS, LOW);
 
  if (!SD.begin(SD1_CS, SPI_HALF_SPEED, SPI_PORT)) 
  {
    Serial.println("FAILED");
    errorLoop();
  }
  digitalWrite(SD1_CS, HIGH);
  Serial.println("DONE");


  // Initialize the sensor (it is important to get calibration values stored on the device).

  if (pressure.begin())
    Serial.println("BMP180 init success");
  else
  {
    // Oops, something went wrong, this is usually a connection problem,
    // see the comments at the top of this sketch for the proper connections.

    Serial.println("BMP180 init fail\n\n");
    errorLoop();
  } 
}

void loop()
{
  char status;
  double T,P,p0,a;

  // Loop here getting pressure readings every 10 seconds.

  // If you want sea-level-compensated pressure, as used in weather reports,
  // you will need to know the altitude at which your measurements are taken.
  // We're using a constant called ALTITUDE in this sketch:
  
  Serial.println();
  Serial.print("provided altitude: ");
  Serial.print(ALTITUDE,0);
  Serial.print(" meters, ");
  Serial.print(ALTITUDE*3.28084,0);
  Serial.println(" feet");
  
  // If you want to measure altitude, and not pressure, you will instead need
  // to provide a known baseline pressure. This is shown at the end of the sketch.

  // You must first get a temperature measurement to perform a pressure reading.
  
  // Start a temperature measurement:
  // If request is successful, the number of ms to wait is returned.
  // If request is unsuccessful, 0 is returned.

  Serial.print("Getting temp...");
  status = pressure.startTemperature();
  if (status != 0)
  {
    //digitalWrite(led1, HIGH);
    // Wait for the measurement to complete:
    Serial.print("...waiting for sensor...");
    delay(status);

    // Retrieve the completed temperature measurement:
    // Note that the measurement is stored in the variable T.
    // Function returns 1 if successful, 0 if failure.

    status = pressure.getTemperature(T);
 
    if (status != 0)
    {
      // Print out the measurement:
      Serial.print("temperature: ");
      Serial.print(T,2);
      Serial.print(" deg C, ");
      Serial.print((9.0/5.0)*T+32.0,2);
      Serial.println(" deg F");
      
      // Start a pressure measurement:
      // The parameter is the oversampling setting, from 0 to 3 (highest res, longest wait).
      // If request is successful, the number of ms to wait is returned.
      // If request is unsuccessful, 0 is returned.

      status = pressure.startPressure(3);
      if (status != 0)
      {
        //digitalWrite(led2, HIGH);
        // Wait for the measurement to complete:
        delay(status);

        // Retrieve the completed pressure measurement:
        // Note that the measurement is stored in the variable P.
        // Note also that the function requires the previous temperature measurement (T).
        // (If temperature is stable, you can do one temperature measurement for a number of pressure measurements.)
        // Function returns 1 if successful, 0 if failure.

        status = pressure.getPressure(P,T);
        if (status != 0)
        {
          // Print out the measurement:
          Serial.print("absolute pressure: ");
          Serial.print(P,2);
          Serial.print(" mb, ");
          Serial.print(P*0.0295333727,2);
          Serial.println(" inHg");
          
          delay(100);

          // The pressure sensor returns abolute pressure, which varies with altitude.
          // To remove the effects of altitude, use the sealevel function and your current altitude.
          // This number is commonly used in weather reports.
          // Parameters: P = absolute pressure in mb, ALTITUDE = current altitude in m.
          // Result: p0 = sea-level compensated pressure in mb

          p0 = pressure.sealevel(P,ALTITUDE); // we're at 1655 meters (Boulder, CO)
          Serial.print("relative (sea-level) pressure: ");
          Serial.print(p0,2);
          Serial.print(" mb, ");
          Serial.print(p0*0.0295333727,2);
          Serial.println(" inHg");

          // On the other hand, if you want to determine your altitude from the pressure reading,
          // use the altitude function along with a baseline pressure (sea-level or other).
          // Parameters: P = absolute pressure in mb, p0 = baseline pressure in mb.
          // Result: a = altitude in m.

          a = pressure.altitude(P,p0);
          Serial.print("computed altitude: ");
          Serial.print(a,0);
          Serial.print(" meters, ");
          Serial.print(a*3.28084,0);
          Serial.println(" feet");
          
          LogData( (int)a );

          delay(100);
          //digitalWrite(led3, LOW);
        }
        else Serial.println("error retrieving pressure measurement\n");
      }
      else Serial.println("error starting pressure measurement\n");
    }
    else Serial.println("error retrieving temperature measurement\n");
  }
  else Serial.println("error starting temperature measurement\n");

  delay(LOG_DELAY);  // Pause
}

boolean LogData( int value )
{
  digitalWrite(SD1_CS, LOW);
  myFile = SD.open("log.dat", FILE_WRITE);
  
  if (myFile) {
    Serial.print("Storing: ");
    myFile.println( value );
    // close the file:
    myFile.close();
    Serial.println("DONE");
    digitalWrite(SD1_CS, HIGH);
    return(true);
  } else {
    // if the file didn't open, print an error:
    Serial.println("ERROR");
    digitalWrite(SD1_CS, HIGH);
    return(false);
  }

}

void errorLoop()
{
     while(1)
    {
      delay(1000);
    } 
}
Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...