Pages: [1]   Go Down
Author Topic: Arduino GTFT problem if used with SD card + SRAM  (Read 1288 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 11
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi everybody,

I bought some days ago an 1.8" TFT from arduino store (http://arduino.cc/en/Main/GTFT), it has a built in micro SD card reader and all is working fine. I can use the TFT and the SD at the same time without problem. Now I'm trying to attach to the same SPI also an SRAM (23K256) but something is going wrong...

If the MISO is connected to the pin of the LCD shield the SRAM stop working... If I detach the MISO pin from the TFT (needed by the shield only for the SD card) the SRAM will work correctly but the SD is unusable... The MISO is connected directly to the PIN 2 of the SRAM.

Another strange thing is that when the SRAM is working the TFT seem to be slower...

For the SRAM I used the attached schema (taken from the forum).

Any idea?

Thank you in advance.

inode

Code:
#include <TFT.h>  // Arduino LCD library
#include <SPI.h>
#include <SD.h>
#include "SRAM2.h"

SRAM2class SRAM2;
Sd2Card card;
SdVolume volume;
SdFile root;
const int chipSelect = 6;

// pin definition for the Uno
#define cs   7
#define dc   9
#define rst  8

// pin definition for the Leonardo
// #define cs   7
// #define dc   0
// #define rst  1

// create an instance of the library
TFT TFTscreen = TFT(cs, dc, rst);

// char array to print to the screen
char sensorPrintout[4];

void setup() {

  // Put this line at the beginning of every sketch that uses the GLCD:
  TFTscreen.begin();

  Serial.begin(115200);

  // clear the screen with a black background
  TFTscreen.background(0, 0, 0);

  // write the static text to the screen
  // set the font color to white
  TFTscreen.stroke(255, 255, 255);
  // set the font size
  TFTscreen.setTextSize(2);
  // write the text to the top left corner of the screen
  TFTscreen.text("Sensor Value :\n ", 0, 0);
  // ste the font size very large for the loop
  TFTscreen.setTextSize(5);


  if (!card.init(SPI_HALF_SPEED, chipSelect)) {
    Serial.println("initialization failed. Things to check:");
    Serial.println("* is a card is inserted?");
    Serial.println("* Is your wiring correct?");
    Serial.println("* did you change the chipSelect pin to match your shield or module?");
    } else {
      Serial.println("Wiring is correct and a card is present.");
    }

  // print the type of card
  Serial.print("\nCard type: ");
  switch (card.type()) {
    case SD_CARD_TYPE_SD1:
    Serial.println("SD1");
    break;
    case SD_CARD_TYPE_SD2:
    Serial.println("SD2");
    break;
    case SD_CARD_TYPE_SDHC:
    Serial.println("SDHC");
    break;
    default:
    Serial.println("Unknown");
  }

  // Now we will try to open the 'volume'/'partition' - it should be FAT16 or FAT32
  if (!volume.init(card)) {
    Serial.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card");
  }

  else {
  // print the type and size of the first FAT-type volume
  uint32_t volumesize;
  Serial.print("\nVolume type is FAT");
  Serial.println(volume.fatType(), DEC);
  Serial.println();

  volumesize = volume.blocksPerCluster();    // clusters are collections of blocks
  volumesize *= volume.clusterCount();       // we'll have a lot of clusters
  volumesize *= 512;                            // SD card blocks are always 512 bytes
  Serial.print("Volume size (bytes): ");
  Serial.println(volumesize);
  Serial.print("Volume size (Kbytes): ");
  volumesize /= 1024;
  Serial.println(volumesize);
  Serial.print("Volume size (Mbytes): ");
  volumesize /= 1024;
  Serial.println(volumesize);

}


Serial.println("Init SRAM test");

SRAM2.writestream1(0);  // write to SRAM 1
  unsigned long stopwatch = millis(); //start stopwatch
  for (unsigned int i = 0; i < 32768; i++)
    SRAM2.RWdata(0x55); //write to every SRAM 1 address
    Serial.print(millis() - stopwatch);
    Serial.println("   ms to write full SRAM 1");
    Serial.println(32768*8/(millis() - stopwatch));
    Serial.println("   bit x seconds");
  SRAM2.readstream1(0);   // start address from 0
  for (unsigned int i = 0; i < 32768; i++) {
    if (SRAM2.RWdata(0xFF) != 0x55)  //check every address in the SRAM1
    {
      Serial.print("error in SRAM 1 at location  ");
      Serial.println(i);
      break;
    }  //end of print error
    if (i == 32767)
    Serial.println("no errors for SRAM 1 in its 32768 bytes");
  }  //end of get byte
  Serial.println(" ");


}

void loop() {

  // Read the value of the sensor on A0
  String sensorVal = String(analogRead(A0));

  // convert the reading to a char array
  sensorVal.toCharArray(sensorPrintout, 4);

  // set the font color
  TFTscreen.stroke(255, 255, 255);
  // print the sensor value
  TFTscreen.text(sensorPrintout, 0, 20);
  // wait for a moment
  delay(250);
  // erase the text you just wrote
  TFTscreen.stroke(0, 0, 0);
  TFTscreen.text(sensorPrintout, 0, 20);
}
 

SRAM2.cpp code (it's like SRAM9)
Code:
#include "SRAM2.h"

SRAM2class::SRAM2class()  //constructor
{
setupDDRB;
setupSPI;

//SPCR &= ~_BV(SPIE);

deselectSS1;  //deselect if selected

selectSS1; //setup SRAM1
RWdata(0x05); //read status register
int Sreg = RWdata(0xff); //get status value
deselectSS1;



if (Sreg != 0x41) //are we in sequential mode
{
selectSS1;
RWdata(0x01); //write to status reg
RWdata(0x41);  //set sequencial  mode
deselectSS1;
}  //end of set sequential mode for SRAM1

}  //end of constructor

void SRAM2class::writestream1(int address) {
deselectSS1;  //deselect if still selected
selectSS1; //select now
RWdata(0x02); //write to address
RWdata(address >> 8); //msb address
RWdata(address); //lsb address
} //end of write stream SRAM 1


void SRAM2class::readstream1(int address) {
deselectSS1;  //deselect if still selected
selectSS1; //select now
RWdata(0x03); //read from address
RWdata(address >> 8); //read from address
RWdata(address);
} //end of read stream SRAM1


void SRAM2class::closeRWstream(void) {
deselectSS1;  //deselect
}  //end of close RW stream

byte SRAM2class::RWdata(byte data) {
SPDR = data;
while (!(SPSR & _BV(SPIF)))
;
return SPDR ;
}  //end of RWdata



* SCHEME.jpg (542.24 KB, 2048x1216 - viewed 82 times.)
Logged

Offline Offline
Faraday Member
**
Karma: 101
Posts: 6206
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

How many SPI devices do you have and how many chip select pins do you have setup for them
on your controller ?
Logged

Arduino UNOs, Pro-Minis, ATMega328, ATtiny85, LCDs, MCP4162, keypads,
DS18B20s,74c922,nRF24L01, RS232, SD card, RC fixed wing, quadcopter

Offline Offline
Newbie
*
Karma: 0
Posts: 11
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

How many SPI devices do you have and how many chip select pins do you have setup for them
on your controller ?

Currently I have only the arduino GTFT and the SRAM, they are 3 devices (the SD card slot is included into the GTFT).

- LCD (SS pin 7)
- SD (SS pin 6)
- SRAM (SS pin 10)

inode
Logged

Offline Offline
Faraday Member
**
Karma: 101
Posts: 6206
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Currently I have only the arduino GTFT and the SRAM, they are 3 devices (the SD card slot is included into the GTFT).

- LCD (SS pin 7)
- SD (SS pin 6)
- SRAM (SS pin 10   


 
Code:
SRAM2class SRAM2;
Sd2Card card;
SdVolume volume;
SdFile root;
const int chipSelect = 6;

// pin definition for the Uno
#define cs   7
#define dc   9
#define rst  8

I see the SD & LCD chip select definitions but am not seeing any definition(declaration) for the SRAM chipselect on pin 10
in the code you posted. Is it there ?
Please show me where you declare pin-10 as an SRAM chip select.
Logged

Arduino UNOs, Pro-Minis, ATMega328, ATtiny85, LCDs, MCP4162, keypads,
DS18B20s,74c922,nRF24L01, RS232, SD card, RC fixed wing, quadcopter

Offline Offline
Faraday Member
**
Karma: 101
Posts: 6206
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Read this:
http://ucexperiment.wordpress.com/2013/02/23/interfacing-microchip-23k256-32kb-sram-spi-memory-to-the-arduino/ 
Logged

Arduino UNOs, Pro-Minis, ATMega328, ATtiny85, LCDs, MCP4162, keypads,
DS18B20s,74c922,nRF24L01, RS232, SD card, RC fixed wing, quadcopter

Offline Offline
Newbie
*
Karma: 0
Posts: 11
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I see the SD & LCD chip select definitions but am not seeing any definition(declaration) for the SRAM chipselect on pin 10
in the code you posted. Is it there ?
Please show me where you declare pin-10 as an SRAM chip select.

The pin 10 is defined into SRAM2.h (selectSS1).

Code:
#define selectSS1 PORTB &= ~0x04  //set the SS to 0 to select SRAM 1

Regards,

inode
Logged

Offline Offline
Faraday Member
**
Karma: 101
Posts: 6206
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Please forgive my ignorance but I don't have a lot of programming experience.
Can you explain how the following:
Code:
  #define selectSS1 PORTB &= ~0x04  //set the SS to 0 to select SRAM 1

equates to Arduino pin-10 as a chip select ?
Obviously I am missing something. . 
PORTB &= ~0x04 => PORTB & 0x04 ?  (PORTB AND 0x04)
What does the "~" mean in front of the 0x04 ?
I am not seeing how ANDing PORTB with 0x04 = "10" (which would be 0x0A hex right?)
Appreciate you help understanding this.
Robert
Logged

Arduino UNOs, Pro-Minis, ATMega328, ATtiny85, LCDs, MCP4162, keypads,
DS18B20s,74c922,nRF24L01, RS232, SD card, RC fixed wing, quadcopter

Offline Offline
Newbie
*
Karma: 0
Posts: 11
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Please forgive my ignorance but I don't have a lot of programming experience.
Can you explain how the following:
Code:
  #define selectSS1 PORTB &= ~0x04  //set the SS to 0 to select SRAM 1

equates to Arduino pin-10 as a chip select ?
Obviously I am missing something. . 
PORTB &= ~0x04 => PORTB & 0x04 ?  (PORTB AND 0x04)
What does the "~" mean in front of the 0x04 ?
I am not seeing how ANDing PORTB with 0x04 = "10" (which would be 0x0A hex right?)
Appreciate you help understanding this.
Robert

Hi Robert,
I didn't wrote the SRAM code you are reading, but this way to access to digital ports should be correct (see http://arduino.cc/en/Reference/PortManipulation for more info). The "~" operator is a NOT bitwise, you are working with port bits so you will bever see value "10". PORTB start from port 8, so 0x4 should be the PIN 10. I'm not a powerful user of arduino, but I think others people can confirm that.

Regards,

inode
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 11
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


I just implemented the code based on the link, but no changes. The SRAM will work correctly if the MISO is not attached and will be faulty if the MISO is connected to the TFT shield.

inode

Code:
#include <TFT.h>  // Arduino LCD library
#include <SPI.h>
#include <SD.h>

Sd2Card card;
SdVolume volume;
SdFile root;
const int chipSelect = 6;

// pin definition for the Uno
#define cs   7
#define dc   9
#define rst  8



#define RDSR 5
#define WRSR 1
#define READ 3
#define WRITE 2

uint8_t SpiRAMRead8(uint16_t address) {
  uint8_t read_byte;

  PORTB &= ~(1<<PORTB2); //set SPI_SS low
  SPI.transfer(READ);
  SPI.transfer((char)(address >> 8));
  SPI.transfer((char)address);
  read_byte = SPI.transfer(0xFF);
  PORTB |= (1<<PORTB2); //set SPI_SS high
  return read_byte;
}

void SpiRAMWrite8(uint16_t address, uint8_t data_byte) {
  PORTB &= ~(1<<PORTB2); //set SPI_SS low
  SPI.transfer(WRITE);
  SPI.transfer((char)(address >> 8));
  SPI.transfer((char)address);
  SPI.transfer(data_byte);
  PORTB |= (1<<PORTB2); //set SPI_SS high
}


// create an instance of the library
TFT TFTscreen = TFT(cs, dc, rst);

// char array to print to the screen
char sensorPrintout[4];

void setup() {

  TFTscreen.begin();

  Serial.begin(115200);

  TFTscreen.background(0, 0, 0);
  TFTscreen.stroke(255, 255, 255);
  TFTscreen.setTextSize(2);
  TFTscreen.text("Sensor Value :\n ", 0, 0);
  TFTscreen.setTextSize(5);


  if (!card.init(SPI_HALF_SPEED, chipSelect)) {
    Serial.println("initialization failed. Things to check:");
    Serial.println("* is a card is inserted?");
    Serial.println("* Is your wiring correct?");
    Serial.println("* did you change the chipSelect pin to match your shield or module?");
    } else {
      Serial.println("Wiring is correct and a card is present.");
    }

    if (!volume.init(card)) {
      Serial.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card");
    }

    else {
      // print the type and size of the first FAT-type volume
      uint32_t volumesize;
      Serial.print("\nVolume type is FAT");
      Serial.println(volume.fatType(), DEC);
      Serial.println();

      volumesize = volume.blocksPerCluster();    // clusters are collections of blocks
      volumesize *= volume.clusterCount();       // we'll have a lot of clusters
      volumesize *= 512;                            // SD card blocks are always 512 bytes
      Serial.print("Volume size (bytes): ");
      Serial.println(volumesize);
      Serial.print("Volume size (Kbytes): ");
      volumesize /= 1024;
      Serial.println(volumesize);
      Serial.print("Volume size (Mbytes): ");
      volumesize /= 1024;
      Serial.println(volumesize);

  }


  Serial.println("* Init SRAM test *");

  unsigned long stopwatch = millis(); //start stopwatch
  for (unsigned int i = 0; i < 32768; i++)

  SpiRAMWrite8(i,0x55);
  Serial.print(millis() - stopwatch);
  Serial.println("   ms to write full SRAM 1");
  Serial.print(32768*8/(millis() - stopwatch));
  Serial.println("   bit x seconds");

  for (unsigned int i = 0; i < 32768; i++) {
    if (SpiRAMRead8(i) != 0x55)  //check every address in the SRAM1
    {
      Serial.print("error in SRAM 1 at location  ");
      Serial.println(i);
      break;
    }  //end of print error
    if (i == 32767)
    Serial.println("no errors for SRAM 1 in its 32768 bytes");
  }  //end of get byte
  Serial.println(" ");


}

void loop() {
  String sensorVal = String(analogRead(A0));
  sensorVal.toCharArray(sensorPrintout, 4);
  TFTscreen.stroke(255, 255, 255);
  TFTscreen.text(sensorPrintout, 0, 20);
  delay(250);
  TFTscreen.stroke(0, 0, 0);
  TFTscreen.text(sensorPrintout, 0, 20);
}

Logged

Offline Offline
Faraday Member
**
Karma: 101
Posts: 6206
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
PORTB start from port 8, so 0x4 should be the PIN 10 
Got it.
You meant to say "PORTB start from PIN- 8"  (PB0 - PB5)
                                         pinout diagram, pin-10 is PORTB, bit 02 (MSB=>76543210<=LSB
                           SO:                                       PORTB &= ~0x04   =    0X04 Hex = B0000100 = 4 (DEC)

Thanks for the clarification !
Learning is one piece of info after another. Every little piece helps fill in the blanks.
Logged

Arduino UNOs, Pro-Minis, ATMega328, ATtiny85, LCDs, MCP4162, keypads,
DS18B20s,74c922,nRF24L01, RS232, SD card, RC fixed wing, quadcopter

Norfolk UK
Offline Offline
Faraday Member
**
Karma: 71
Posts: 2614
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Maybe something on the TFT shield does not allow tri-state for the MISO pin and it is being held high/low and preventing you from reading the SRAM MISO line. If this is the case then not sure if you can overcome it with a counteracting pullup/pulldown resistor.
Logged


Offline Offline
Newbie
*
Karma: 1
Posts: 5
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I have exactly the same problem with the Arduino TFT& a TinyFlash W25Q80BV on Arduino due.

I have tried all the possibile funky stuff & patch, starting from manually deselecting SD_CS & LCD_CS and ending to rewrite SD lib, TFT lib & the TinyFlash lib to support out of the box the extended SPI protocol on the Arduino Due. Nothing worked.

TFT works alone and also with the Flash wired and initialized but the Flash RAM fail if the MISO is attached to the TFT display. This happen also if you do not initialize the TFT at all.

I really think the problem is on the TFT side that do not release the MISO as needed. Or as stated by Riva, do not allow tri-state for the MISO.

Stefano.
Logged

Norfolk UK
Offline Offline
Faraday Member
**
Karma: 71
Posts: 2614
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have exactly the same problem with the Arduino TFT& a TinyFlash W25Q80BV on Arduino due.

I really think the problem is on the TFT side that do not release the MISO as needed. Or as stated by Riva, do not allow tri-state for the MISO.
A quick look at the Arduino TFT schematic and it looks to be using a 74LVC1G125 tri-state buffer on the MISO line but it's output enable is tied to ground.
Maybe using a CD4053 to switch MISO or a software SPI library.
Logged


Pages: [1]   Go Up
Jump to: