#include <SPI.h>
#define SPICONFIG SPISettings(35000000, MSBFIRST, SPI_MODE0)
// address masks
#define ADDR_MSB_MASK (uint32_t)0x00FF0000
#define ADDR_ISB_MASK (uint32_t)0x0000FF00
#define ADDR_LSB_MASK (uint32_t)0x000000FF
#define MSB_ADDR_BYTE(addr) ((uint8_t)((addr & ADDR_MSB_MASK)>>16))
#define ISB_ADDR_BYTE(addr) ((uint8_t)((addr & ADDR_ISB_MASK)>>8))
#define LSB_ADDR_BYTE(addr) ((uint8_t)(addr & ADDR_LSB_MASK))
#define NULL_PTR ((uint8_t*) 0u)
//#define THREEBYTEADDRESS 0 //Disable 3-byte address access in SPI F-RAMs
#define THREEBYTEADDRESS 1 //Enable 3-byte address in 1Mb and above densities SPI F-RAMs
// Data buffer size
#define BUFFER_SIZE (32u)
uint8_t pin = 10;
uint8_t xData[BUFFER_SIZE], buffer[BUFFER_SIZE];
void setup() {
pinMode(pin, OUTPUT);
digitalWrite(pin, HIGH);
Serial.begin(115000);
delay(3000);
SPI.begin();
delay(2000);
GetJedecID();
readStatusRegister(0x05, false);
uint32_t address = 0;
memset(buffer, 0xff, BUFFER_SIZE);
readBytes(address, buffer, BUFFER_SIZE);
Serial.println();
for (uint16_t j = 0; j < 2; j++) {
for (uint16_t i = 0; i < 16; i++) {
Serial.printf("0x%02x, ", buffer[j * 16 + i]);
} Serial.println();
}
//check42(false);
//writeEnable(true);
bool status = readStatusRegister(0x05, true);
Serial.println("Write Enabled");
delay(2);
//memset(buffer, 0xff, BUFFER_SIZE);
for (uint16_t i = 0; i < BUFFER_SIZE; i++) buffer[i] = i+1;
writeBytes(address, buffer, BUFFER_SIZE);
delay(200);
//writeEnable(false);
memset(buffer, 0xff, BUFFER_SIZE);
readBytes(address, buffer, BUFFER_SIZE);
Serial.println();
for (uint16_t j = 0; j < 2; j++) {
for (uint16_t i = 0; i < 16; i++) {
Serial.printf("0x%02x, ", buffer[j * 16 + i]);
} Serial.println();
}
check42(true);
}
void loop() {
// put your main code here, to run repeatedly:
}
uint8_t valERAM;
uint16_t arraySize = 2048;
uint8_t x42[2048];
uint32_t errCnt = 0;
elapsedMicros my_us;
const uint32_t sizeofNAND = 1048576;
void check42( bool doWrite ) {
uint32_t test = sizeofNAND / arraySize;
byte value;
uint32_t ii;
uint32_t jj = 0, kk = 0;
if ( doWrite) {
Serial.print("\n NAND ========== memory map ====== ====== check42() : WRITE !!!!\n");
Serial.printf("\t\tNAND length 0x%X element size of %d\n", sizeofNAND, sizeof(valERAM));
my_us = 0;
for ( ii = 0; ii < test; ii++ ) { //write pages
//Serial.println("Loading data");
memset(x42, 42, arraySize);
writeBytes(ii * 2048, x42, arraySize);
}
Serial.printf( "\t took %lu elapsed us\n", (uint32_t)my_us );
} //end doWrite
Serial.print(" NAND ============================ check42() : COMPARE !!!!\n");
my_us = 0;
for ( ii = 0; ii < test; ii++ ) {
memset(x42, 0, arraySize);
readBytes(ii * arraySize, x42, arraySize);
// Serial.println();
// for (uint16_t j = 0; j < 12; j++) {
// for (uint16_t i = 0; i < 16; i++) {
// Serial.printf("0x%02x, ", x42[j * 16 + i]);
// } Serial.println();
// }
for (uint16_t ik = 0; ik < arraySize; ik++) {
if ( 42 != x42[ik] ) {
if ( ik != 0 ) {
Serial.printf( "\t+++ NOT 42 Good Run of %u {bad @ %u}\n", ik, ii );
ik = 0;
return;
}
if ( jj < 100 ) Serial.printf( "%3u=%8u\n", ik, x42[ik] );
jj++;
}
else kk++;
}
}
Serial.printf( "\t took %lu elapsed us\n", (uint32_t)my_us );
if ( 0 == jj )
Serial.printf( "Good, " );
else
Serial.printf( "Failed to find 42 in NAND %d Times", jj );
errCnt += jj;
Serial.printf( "\tFound 42 in NAND 0x%X Times\n", sizeofNAND - jj );
}
//////////////////////////////////////////////////////////////////
// JEDEC ID is available even if chip is busy, so no need to stall
void GetJedecID(void) {
uint8_t data[9];
SPI.beginTransaction(SPICONFIG);
digitalWrite(pin, LOW);
delayNanoseconds(250);
SPI.transfer(0x9f); //0x9f - JEDEC register
for(uint8_t i = 0; i<9; i++)
data[i] = SPI.transfer(0);
delayNanoseconds(250);
digitalWrite(pin, HIGH); // Chip deselect
SPI.endTransaction();
//for(uint8_t i = 0; i<3; i++) Serial.println(data[i], HEX);
Serial.printf("JEDEC: 0x%02X, 0x%02X, 0x%02X\n", data[0], data[1], data[2]);
}
bool writeEnable(bool enable) {
uint8_t status;
if(enable == true) {
SPI.beginTransaction(SPICONFIG);
digitalWrite(pin, LOW);
delayNanoseconds(250);
SPI.transfer(0x06);
delayNanoseconds(250);
digitalWrite(pin, HIGH); // Chip deselect
SPI.endTransaction();
} else {
SPI.beginTransaction(SPICONFIG);
digitalWrite(pin, LOW);
delayNanoseconds(250);
SPI.transfer(0x04);
delayNanoseconds(250);
digitalWrite(pin, HIGH); // Chip deselect
SPI.endTransaction();
}
status = readStatusRegister(0x05, true);
//Serial.print("Status WEL: "); Serial.println(status, BIN);
//Serial.print("Wel Bit Enabled: "); Serial.println(status & (1<<1));
if(status & (1<<1) != 2) return false;
return status & (0x02);
}
uint8_t readStatusRegister(uint16_t reg, bool dump)
{
uint8_t val;
SPI.beginTransaction(SPICONFIG);
digitalWrite(pin, LOW);
delayNanoseconds(250);
SPI.transfer(0x05); //0x05 - read status register
SPI.transfer(reg);
val = SPI.transfer(0x00);
delayNanoseconds(250);
digitalWrite(pin, HIGH); // Chip deselect
//SPI.endTransaction();
if(dump) {
Serial.printf("Status of reg 0x%x: \n", reg);
Serial.printf("(HEX: ) 0x%02X, (Binary: )", val);
Serial.println(val, BIN);
Serial.println();
}
return val;
}
void writeBytes(uint32_t address, uint8_t * FRAM_wr_data_ptr, uint32_t length)
{
//Serial.println("Writing Data");
uint32_t i;
// If write pointer is NULL, return
if(FRAM_wr_data_ptr == NULL_PTR){
Serial.println("NULL POINTER");
return;
}
SPI.beginTransaction(SPICONFIG);
// F-RAM WRITE ENABLE COMMAND
digitalWrite(pin,LOW); //chip select
delayNanoseconds(250);
SPI.transfer(0x06); //transmit write enable opcode
digitalWrite(pin,HIGH); //release chip, signal end transfer
// F-RAM WRITE OPERATION
digitalWrite(pin,LOW); //chip select
SPI.transfer(0x02); //transmit write opcode
#if (THREEBYTEADDRESS == 1)
SPI.transfer(MSB_ADDR_BYTE(address)); //send MSByte address in three byte address
#endif
SPI.transfer(ISB_ADDR_BYTE(address)); //send ISByte address in three byte address (MSByte address in two byte address)
SPI.transfer(LSB_ADDR_BYTE(address)); //send LSByte address
// Data byte transmission
for(i=0;i<length;i++)
SPI.transfer((uint8_t)(FRAM_wr_data_ptr[i])); //send 1 byte data at a time
delayNanoseconds(250);
digitalWrite(pin,HIGH); //release chip, signal end of transfer
SPI.endTransaction();
}
bool readBytes(uint32_t address, uint8_t * FRAM_rd_data_ptr, uint32_t length)
{
uint32_t i;
// If read pointer is NULL, return
if(FRAM_rd_data_ptr == NULL_PTR) {
Serial.println("NULL POINTER");
return;
}
//FRAM READ OPERATION
SPI.beginTransaction(SPICONFIG);
digitalWrite(pin,LOW); //chip select
delayNanoseconds(250);
SPI.transfer(0x03); //transmit read opcode
#if (THREEBYTEADDRESS == 1)
SPI.transfer(MSB_ADDR_BYTE(address)); //send MSByte address in three byte address
#endif
SPI.transfer(ISB_ADDR_BYTE(address)); //send ISByte address in three byte address (MSByte address in two byte address)
SPI.transfer(LSB_ADDR_BYTE(address)); //send LSByte address
for(i=0;i<length;i++)
FRAM_rd_data_ptr[i] = SPI.transfer(0); //get all the data bytes from F-RAM
delayNanoseconds(250);
digitalWrite(pin,HIGH); //release chip, signal end of transfer
SPI.endTransaction();
}