■ページ内リンク 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
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)
下図のような構成を考える。
(I consider the following structure by putting it into practice.)
Please refer to the datasheet, "S25FL**".
#ref(): File not found: "ff.png" at page "Arduino/SPI通信_S25FL_1"
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
#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(); } } }
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 |