Help for Teensy 3.2 + F-RAM 4mbit 3 byte addressing

Status
Not open for further replies.

danixdj

Well-known member
Hi, i can't write and read on my new F-RAM chip 4mbit by mi Teensy 3.2

There isn't a specific library for this component and i can't write a working sketch..

Someone that have experience about F-RAM??

The problem is the 3 byte addressing and the specific system or read / write command i think..

The chip is: CY15B104Q 4-Mbit 512K X 8 Serial SPI F-RAM

Datasheet:
http://www.mouser.com/ds/2/100/001-94240_CY15B104Q_4-Mbit_512_K_8_Serial_SPI_F-RA-914618.pdf

write code
Code:
#define DATAOUT 7//MOSI
#define DATAIN  12//MISO 
#define SPICLOCK  14//sck
#define SLAVESELECT 6//ss

//opcodes
#define WREN  6
#define WRDI  4
#define RDSR  5
#define WRSR  1
#define READ  3
#define WRITE 2

byte eeprom_output_data;
byte eeprom_input_data=0;
byte clr;
unsigned int address=0;
byte daten=0; 

char spi_transfer(volatile char data)
{
  SPDR = data;                    // Start the transmission
  while (!(SPSR & (1<<SPIF)))     // Wait the end of the transmission
  {
  };
  return SPDR;                    // return the received byte
}

void setup()
{
  Serial.begin(9600);
  pinMode(DATAOUT, OUTPUT);
  pinMode(DATAIN, INPUT);
  pinMode(SPICLOCK,OUTPUT);
  pinMode(SLAVESELECT,OUTPUT);
  digitalWrite(SLAVESELECT,HIGH); //disable device

  SPCR = (1<<SPE)|(1<<MSTR);
  clr=SPSR;
  clr=SPDR;
  delay(10);    
  digitalWrite(SLAVESELECT,LOW);
  spi_transfer(WREN); //write enable
  digitalWrite(SLAVESELECT,HIGH);
  delay(10);  
  Serial.print("starttime: ");
  Serial.println(micros());
  digitalWrite(SLAVESELECT,LOW);      // write 32kByte in sequence
  spi_transfer(WRITE);                //write instruction
  address=0;
  spi_transfer((char)(address>>8));   //send MSByte address first
  spi_transfer((char)(address));      //send LSByte address
  // write 32KByte
  for (unsigned int I=0;I<524288;I++)
  {
    spi_transfer(I/256); //write data byte
  }  
  digitalWrite(SLAVESELECT,HIGH); //release chip  
  Serial.print("endtime: ");
  Serial.println(micros()); Serial.println();
  Serial.println("FRAM Write finish");
}

void loop()
{
  delay(5000); //pause for readability
}

Read code
Code:
#define DATAOUT 7//MOSI
#define DATAIN  12//MISO 
#define SPICLOCK  14//sck
#define SLAVESELECT 6//ss

//opcodes
#define WREN  6
#define WRDI  4
#define RDSR  5
#define WRSR  1
#define READ  3
#define WRITE 2

byte eeprom_output_data;
byte eeprom_input_data=0;
byte clr;
unsigned int address=0;

char spi_transfer(volatile char data)
{
  SPDR = data;                    // Start the transmission
  while (!(SPSR & (1<<SPIF)))     // Wait the end of the transmission
  {
  };
  return SPDR;                    // return the received byte
}

byte read_eeprom(int EEPROM_address)
{
  //READ EEPROM
  int data;
  digitalWrite(SLAVESELECT,LOW);
  spi_transfer(READ);                        //transmit read opcode
  spi_transfer((char)(EEPROM_address>>8));   //send MSByte address first
  spi_transfer((char)(EEPROM_address));      //send LSByte address
  data = spi_transfer(0xFF);                 //get data byte
  digitalWrite(SLAVESELECT,HIGH);            //release chip, signal end transfer
  return data;
}

void setup()
{
  Serial.begin(9600);
  pinMode(DATAOUT, OUTPUT);
  pinMode(DATAIN, INPUT);
  pinMode(SPICLOCK,OUTPUT);
  pinMode(SLAVESELECT,OUTPUT);
  digitalWrite(SLAVESELECT,HIGH);         //disable device
  SPCR = (1<<SPE)|(1<<MSTR);
  clr=SPSR;
  clr=SPDR;
  delay(10);  
}

void loop()
{
  Serial.print('\n',BYTE);
  for (unsigned int I=0;I<524288;I++)
  {
    eeprom_output_data = read_eeprom(I);
  Serial.print(eeprom_output_data,DEC);
  address++;
  if (address == 64)
  {Serial.print('\n',BYTE);
  address = 0;
  }
}  
delay(5000); //pause for readability
}
 
"The 4-Mbit serial F-RAM requires a 3-byte address for any read or write operation. Because the address is only 19 bits, the first five bits, which are fed in are ignored by the device. Although these five bits are ‘don’t care’, Cypress recommends that these bits be set to 0s to enable seamless transition to higher memory densities."
 
Assumed it was new effort ... That would be in the data sheet - another spi_transfer(...) byte needs to go out to cover those missing 3 bits. Not sure if it is packed before current MSB or after LSB?

Not sure if that helps ... others have used F-RAM.

Here is a link to perhaps similar code for 1Gbit FLASH: flashS25FL127_spi.cpp#L322

And this will only write at 0 - the line linked above shows 3 byte read address in use:
Code:
  [U][B]address=0;[/B][/U]
  spi_transfer((char)(address>>8));   //send MSByte address first
  spi_transfer((char)(address));      //send LSByte address
 
I can't make a good address :(

i think for this reason:
"Because the address is only 19 bits, the first five bits, which are fed in are ignored by the device. Although these five bits are ‘don’t care’, Cypress recommends that these bits be set to 0s to enable seamless transition to higher memory densities."

the real address is from 00000h to 7FFFFh (19 bit) but + 00000 (5bit zero needed) for 24bits total (2bytes) + 1 (byte dada) = 3 bytes ...


Schermata 2017-08-22 alle 13.08.41.jpg
 
I'm working on this now... but nothings...

Code:
#include <SPI.h>
 
//SRAM opcodes
#define WREN  0b00000110 //set write enable latch
#define WRDI  0b00000100 //write disable
#define RDSR  0b00000101 //read status register
#define WRSR  0b00000001 //write status register
#define READ  0b00000011 //read memory data
#define WRITE 0b00000010 //write memory data
  
uint8_t SpiRAMRead8(uint32_t address) {
  uint32_t read_byte;
  
  digitalWrite(6,LOW);              //CS
  SPI.transfer(READ);
  SPI.transfer((char)((address>>16)&0xFF));
  SPI.transfer((char)((address>>8)&0xFF));
  SPI.transfer((char)address);
  read_byte = SPI.transfer(0xFF);
  digitalWrite(6,HIGH);               //set CS high
  return read_byte;
}
  
void SpiRAMWrite8(uint32_t address, uint8_t data_byte) {
  digitalWrite(6,LOW);                //set CS low
  SPI.transfer(WREN);
  digitalWrite(6,HIGH);;               //set CS high
  digitalWrite(6,LOW);             //set CS low
  SPI.transfer(WRITE);
  SPI.transfer((char)((address>>16)&0xFF));
  SPI.transfer((char)((address>>8)&0xFF));
  SPI.transfer((char)address);
  SPI.transfer(data_byte);
  digitalWrite(6,HIGH);               //set CS high
}
  
void setup(void) {
  uint32_t addr;
  uint8_t i;
 
  Serial.begin(9600);
  pinMode(6, OUTPUT);                //CS
  SPI.begin();
  SPI.setMOSI(7);
  SPI.setMISO(12);
  SPI.setSCK(14);
  SPI.setDataMode(SPI_MODE0);
  SPI.setBitOrder(MSBFIRST);
  SPI.setClockDivider (SPI_CLOCK_DIV2);
  for (addr=0; addr<32; addr++) {
    SpiRAMWrite8(addr, (uint8_t)addr);
    Serial.print("Addr: ");
    Serial.print(addr);
    i = SpiRAMRead8(addr);
    Serial.print(" | Read: ");
    Serial.println((uint16_t)i);
  }
}
  
void loop() { }
 
F-RAM usage :: Somebody here noted recently they used F-RAM - maybe they'll see this and link their solution.

I found this with a quick search - and don't have time - or the hardware - to try it out.

Different manufacturer - but large and on Teensy:
https://github.com/christophepersoz/FRAM_MB85RS_SPI

Arduino notes and github:
http://hackscribble.github.io/hackscribble-ferro-library/

smaller AdaFruit shield:
https://github.com/adafruit/Adafruit_FRAM_SPI

all already tested... nothing! (or 2 byte addressing or different command in datasheet of the memory chip)

I'm writing to Cypress for help... i need a testing sketch, this memory have a specific "driver" code, witheout help from manufacture it's impossibile i think... for me maybe..
 
all already tested... nothing! (or 2 byte addressing or different command in datasheet of the memory chip)

I'm writing to Cypress for help... i need a testing sketch, this memory have a specific "driver" code, witheout help from manufacture it's impossibile i think... for me maybe..

The [first link ] one must use 3 bytes address - he tested on 1 Mbit - but says it works up to 4 Mbit - but not Cypress. The data sheet will have all the details you need. If that is beyond you then as noted - perhaps another user may have used your chip. Or you could switch to one of those tested chips.
 
I'm furious because the possibility of this memory type in teensy should be huge, easy and FAST .... can't wait to test it
 
The [first link ] one must use 3 bytes address - he tested on 1 Mbit - but says it works up to 4 Mbit - but not Cypress. The data sheet will have all the details you need. If that is beyond you then as noted - perhaps another user may have used your chip. Or you could switch to one of those tested chips.

Note : In the MB85RC64, input “000” as the upper 3 bits of the MSB

but for CY15B104Q are 5 bit set to zero... the address code is totally different...
 
I need more than 1 or 2 mbit... I'm waiting cypress support... they have a developers archive but the arduino sketch available is for 2mbit max (2 byte addressing)
 
Are you able to read the status register and/or the device id?
Why not start here as tvetter suggests? Divide and conquer. Verify the part is wired correctly. To read the device ID, you will not need to worry about the addressing. You will not need to worry about writing some data as the data already resides in the part. When successful you will have verified your wiring and the ability to send a command to the part, and the ability to read data out of the part.
 
Why not start here as tvetter suggests? Divide and conquer. Verify the part is wired correctly. To read the device ID, you will not need to worry about the addressing. You will not need to worry about writing some data as the data already resides in the part. When successful you will have verified your wiring and the ability to send a command to the part, and the ability to read data out of the part.

Sure I can do it but how?

I can't write a code that memory chip read fine.. (need addressing ecc ecc)

So if you can help me :)
 
Status
Not open for further replies.
Back
Top