Arduino / SPI通信_S25FL_1


Arduino

■ページ内リンク Link to internal page
1.概要 summary
1-1.ハードウェアセットアップ(hard ware set up)
1-2.タイミングチャート timing chart
1-3.ピン一覧 pin assigned table
1-4.ソースコード source code by arduino(prossecing)
1-5.シリアルモニタプロット displayed serial monitor prompt

1.概要(summary)

ArduinoからSPI I/Fによって記憶素子デバイスの制御を可能とする。
I will get possible to control the device which is NOR-FLASH bu using Arduino-NANO
主要デバイス(Main devices)
(1)Arduino Nano 16MHz 5V I/F
(2)FXMA108 レベル変換IC(変換できればなんでも可能)
  (any level-shifted devices available)
(3)S25FL032P0XNFI010 NOR-FLASH(SPI I/Fのものなら何でも可だがNORが良い)
  (any SPI-interfaced devices available ,but the type "NOR" is better)

1-1.ハードウェアセットアップ(hard ware set up)

下図のような構成を考える。
(I consider the following structure by putting it into practice.)

添付ファイルの画像


1-2.タイミングチャート

Please refer to the datasheet, "S25FL**".

#ref(): File not found: "ff.png" at page "Arduino/SPI通信_S25FL_1"


1-3.ピン一覧(pins assigned table)

AE-ATMEGA328-NANO<--(5V-3.3V変換)-->S25FL032P0XNF010 (WSON package 8pin)

ピンアサインは下記の通り。省略したが途中でレベル変換が必要。
CS:D10--->CS#:1pin
SCK:13pin--->SCK:6pin
MIS:12pin<---SO:2pin
MOS:11pin--->SI:5pin

1-4.ソースコード(source code)

 #include <SPI.h>       //to use SPI I/F
#define FLASH_CS 10    //set the pin to cs 
uint8_t data_id;      //ID data
uint8_t data_conf;    //CONFIGURATION data
uint8_t data_str;    
uint8_t data;
boolean exe_at_once = true;

//////////////////spi_initialize //////////////////
  void spi_init(){
  SPI.begin();
  pinMode(FLASH_CS, OUTPUT);
  spi_set_cs(0x1);
  }
//////////////////spi_set_cs //////////////////
  void spi_set_cs(uint8_t cs_high) {
  digitalWrite(FLASH_CS, cs_high & 0x1);
  }
 //////////////////watch Write In Progress(the subsequent cycle has to wait this flag"0") //////////////////
  uint8_t flash_is_wip(){
  spi_set_cs(0x0);
  data = SPI.transfer(0x05);  
  data |= (uint8_t)SPI.transfer(0x00);
  spi_set_cs(0x1);
  return(data & 0x1);
  }

  void setup() {
  spi_init();
  Serial.begin(9600);
  SPI.setBitOrder(MSBFIRST);           //send from MSB .Not LSB
  SPI.setClockDivider(SPI_CLOCK_DIV2); // DIV"2" means "2"/16 divided internal clock(16MHz).other: 4,8,16,...128
  SPI.setDataMode(SPI_MODE0); //MODE0  rising edge of the clock to capture data. 

//////////////////RDID //////////////////
  Serial.print("RDID(0x9f)_ReaD_Idtification_register\n");
  spi_set_cs(0x0);
//RDID(0x9f) are excuting 
  data_id= SPI.transfer(0x9f);  

 for(uint16_t i = 0 ; i <= 80; ++i){  //80d stands for 50h which is the end of ID register
  char cnt[80];                      //cnt array defined
  sprintf(cnt,"%2x",i);   //change Type to char to display (column gets to be the same vertical positon)  
  Serial.print(cnt);                
  Serial.print(" ");
  }
  Serial.print("\n");
  for(uint16_t i = 0 ; i <= 80; ++i){  //80d stands for 50h which is the end of ID register  
  data_id  = (uint8_t)SPI.transfer(0x00) ; //send dummy data to output clocks by 8 times (apply to 1byte)
  char data_cnt[80];                 //cnt array defined
  sprintf(data_cnt,"%2x",data_id);    
  Serial.print(data_cnt);
  Serial.print(" ");
  }
  Serial.print("\n");
// Set cs to High
  spi_set_cs(0x1);
//////////////////RCR //////////////////
  Serial.print("RCR(0x35)_Read_Configuration_Register\n");
  spi_set_cs(0x0);
 // RCR(0x35) are excuting 
  data_conf= SPI.transfer(0x35);

  for(uint16_t i = 0 ; i <= 1; ++i){
  char cnt[2];
  sprintf(cnt,"%2x",i);
  Serial.print(cnt);
  Serial.print(" ");
  }
  Serial.print("\n");
  for(uint16_t i = 0 ; i <= 1; ++i){    
  data_conf  = (uint8_t)SPI.transfer(0x00) ;
  char data_ccnt[2];
  sprintf(data_ccnt,"%2x",data_conf);
  Serial.print(data_ccnt);
  Serial.print(" ");
  }
  Serial.print("\n");
  spi_set_cs(0x1);
  
//WRITE STATUS RESISTER_check & initialize to "0x00"
  Serial.print("WEN(0x06)--->WRR(0x0100)_initialize to 0x00. All areas are Write Enabled\n");
  spi_set_cs(0x0);
  SPI.transfer(0x06); 
  spi_set_cs(0x1);
     
  spi_set_cs(0x0);
  SPI.transfer(0x01);
  SPI.transfer(0x00);
  spi_set_cs(0x1);
 
  Serial.print("Write_in_progress_check");
while(flash_is_wip()){//消去待ち
  Serial.print(".");}
  Serial.print(" Clear\n");
       
//READ STATUS RESISTER
  Serial.print("RDSR(0x05)_STATUS_REGISTER_check\n");
  spi_set_cs(0x0);
// CMD_RDSR(0x05) are excuting 
  data_str = SPI.transfer(0x05);  
  data_str |= (uint8_t)SPI.transfer(0x00);
  Serial.print(data_str,HEX);
  Serial.print("\n");
  spi_set_cs(0x1);
}

/* 
//////////////////COMMAND_TABLE //////////////////
RDID(ReaD Identification Data)   0x9F ---Correct response are 4D 15 02 01
RCR(Read Configuration Register) 0x35
SE(Sector Erase)                 0xD8
READ(READ)                       0x03
RDSR(ReaD Status Register)       0x05
WEN(Write Eanable)               0x06
WRR(WRite Register)              0x01** (**are 10,0C,08,04 etc)
*/

void loop() {
  if (exe_at_once) {
    exe_at_once = false;
    //  exe_at_once= true;
  for(uint16_t k = 0 ; k <=0 ; ++k){    //84 = 256 times all
 uint32_t rx_buf;
 uint32_t tx_buf;
 uint32_t addr = 0x0000;
 uint16_t length = 0x100;
      
//Sector Erase
  Serial.print("SE(0xD8)_Sector_Erase(only enable bit to change 0 to 1 1111...stands for 0xff)\n");
  spi_set_cs(0x0);
  SPI.transfer(0x06); 
  spi_set_cs(0x1);
  spi_set_cs(0x0);
  SPI.transfer(0xd8); 
  SPI.transfer(0x21);
  SPI.transfer(0x00);
  SPI.transfer(0x00);
  spi_set_cs(0x1);
  Serial.print("Write_in_progress_check");

while(flash_is_wip()){//消去待ち
  Serial.print(".");
  }
  Serial.print(" Clear\n");

//READ
  Serial.print("READ(0x03)\n");
  spi_set_cs(0x0);
  SPI.transfer(0x03);
  SPI.transfer(0x21);
  SPI.transfer(0x00);
  SPI.transfer(0x00);
//////////////////READ //////////////////
 for(uint16_t i = 0 ; i <= 15; ++i){
  char cnt[16];
  sprintf(cnt,"%2x",i);
  Serial.print(cnt);
  Serial.print(" ");
  }
  Serial.print("\n");
  for(uint16_t i = 0 ; i <= 15; ++i){    
  data_id  = (uint8_t)SPI.transfer(0x00) ;
  char data_cnt[16];
  sprintf(data_cnt,"%2x",data_id);
  Serial.print(data_cnt);
  Serial.print(" ");
  }
  Serial.print("\n");

  Serial.print("Write_in_progress_check");
while(flash_is_wip()){//消去待ち
  Serial.print(".");
 }
  Serial.print(" Clear\n");
     
//WRITE
  Serial.print("WRITE(0x02) Terget to fixed address 0x210000 \n");
  spi_set_cs(0x0);
  SPI.transfer(0x06); 
  spi_set_cs(0x1);
   
  spi_set_cs(0x0);
  SPI.transfer(0x02); 
  SPI.transfer(0x21);
  SPI.transfer(0x00);
  SPI.transfer(0x00);
  for(uint16_t i = 0 ; i <= 15; ++i){    
  data =(uint8_t)SPI.transfer(i +1 ) ;
  //char data_count[16];
  //sprintf(data_count,"%2x",data);
  //Serial.print(data_count);
  //Serial.print(" ");
      }
  spi_set_cs(0x1);

  Serial.print("Write_in_progress_check");
while(flash_is_wip()){//消去待ち
  Serial.print(".");
 }
  Serial.print(" Clear\n");
      
//READ
  Serial.print("READ(0x03)\n");
  spi_set_cs(0x0);
  SPI.transfer(0x03);
  SPI.transfer(0x21);
  SPI.transfer(0x00);
  SPI.transfer(0x00);
//////////////////READ //////////////////
  for(uint16_t i = 0 ; i <= 15; ++i){
    char cnt[16];
    sprintf(cnt,"%2x",i);
    Serial.print(cnt);
    Serial.print(" ");
  }
  Serial.print("\n");
  for(uint16_t i = 0 ; i <= 15; ++i){    
  data_id  = (uint8_t)SPI.transfer(0x00) ;
  char data_cnt[16];
  sprintf(data_cnt,"%2x",data_id);
  Serial.print(data_cnt);
  Serial.print(" ");
  }
  spi_set_cs(0x1);
  Serial.print("\n");
      
//WRITE STATUS RESISTER_check & chage the value to "0x1C" 
  Serial.print("WEN(0x06)--->WRR(0x0100)_change the value to 0x1C. All area are Write Disabled\n");
  spi_set_cs(0x0);
  SPI.transfer(0x06); 
  spi_set_cs(0x1);
     
  spi_set_cs(0x0);
  SPI.transfer(0x01);
  SPI.transfer(0x1C);
  spi_set_cs(0x1);

  Serial.print("Write_in_progress_check");
while(flash_is_wip()){//消去待ち
  Serial.print(".");}
  Serial.print(" Clear\n");
       
//READ STATUS RESISTER
  Serial.print("RDSR(0x05)_STATUS_REGISTER_check\n");
  spi_set_cs(0x0);
// CMD_RDSR(0x05) are excuting 
  data_str = SPI.transfer(0x05);  
  data_str |= (uint8_t)SPI.transfer(0x00);
  Serial.print(data_str,HEX);
  Serial.print("\n");
  spi_set_cs(0x1);
  Serial.print("WEN_COMMAND cycles are 3 times + 1\n");

// Ended up SPI transfer,and initialization
  SPI.endTransaction();
  }
}
}

1-5.シリアルモニタプロット(serial monitor prompt displayed)

RDID(0x9f)_ReaD_Idtification_register
0 1 2 3 4 5 6 7 8 9 a b c d e f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50
1 2 15 4d 0 0 0 ff ff ff ff ff ff ff ff ff 51 52 59 2 0 40 0 0 0 0 0 27 36 0 0 b b 9 f 1 1 2 1 16 5 5 8 0 2 1f 0 10 0 3d 0 0 1 0 0 0 0 0 0 0 0 ff ff ff 50 52 49 31 33 15 0 1 0 5 0 1 3 85 95 7 0
RCR(0x35)_Read_Configuration_Register
0 1
c c
WEN(0x06)--->WRR(0x0100)_initialize to 0x00. All areas are Write Enabled
Write_in_progress_check............... Clear
RDSR(0x05)_STATUS_REGISTER_check
0
SE(0xD8)_Sector_Erase(only enable bit to change 0 to 1 1111...stands for 0xff)
Write_in_progress_check...................................................................................................................................................................................................................... Clear
READ(0x03)
0 1 2 3 4 5 6 7 8 9 a b c d e f
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
Write_in_progress_check.. Clear
WRITE(0x02) Terget to fixed address 0x210000
Write_in_progress_check Clear
READ(0x03)
0 1 2 3 4 5 6 7 8 9 a b c d e f
1 2 3 4 5 6 7 8 9 a b c d e f 10
WEN(0x06)--->WRR(0x0100)_change the value to 0x1C. All area are Write Disabled
Write_in_progress_check............... Clear
RDSR(0x05)_STATUS_REGISTER_check
1C
WEN_COMMAND cycles are 3 times + 1