■ページ内リンク 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
SpresenseからSPI I/Fによって記憶素子デバイスの制御を可能とする。
SpresenseとはSonyから発売されたIT向けの高性能エッジデバイスである。
Arduino互換SPI I/F(Supresense上はSPI4(D13:D10))を使う場合、拡張ボードが必須となる。
I will get possible to control the device which is NOR-FLASH using Supresense
Spresense is made by Sony, which is the highest performance "Edge device" which has ever seen before.
Spresense has SPI I/F with Arduino compatible, we can use it with both the main-board and the extended board.
主要デバイス(Main devices)
(1)Spresense Main-board CXD5602PWBMAIN1 CortexM4F x6cores 156 MHz
(2)Spresense Extended-board CXD5602PWBEXT1
(Arduino互換I/FのSPIの場合は40Mhzまでに制限されている。)
(3)S25FL032P0XNFI010 NOR-FLASH
(SPI I/Fのものなら何でも可だがNORが良い)
(1)Spresense Main-board CXD5602PWBMAIN1 CortexM4F x6cores 156 MHz
(2)Spresense Extended-board CXD5602PWBEXT1
(limited SPI I/F(Arduino compatible) is up to 40MHz)
(3)S25FL032P0XNFI010 NOR-FLASH
(Any SPI-interfaced devices available ,but the type "NOR" is better)
下図のような構成を考える。
(I consider the following structure by putting it into practice.)
Figure1.Spresense SPI diagram
Figure2.Spresense SPI diagram
Omitted.
Please reffer the datasheet "S25FL032P0XNFI010"
The Clock rate is 20MHz(DIV4).
(doesn't work at 40MHz)
The reason is unclear, I've not investigateing.
Spresense extended-board <---->S25FL032P0XNF010 (WSON package 8pin) CS:8pin*--->CS#:1pin SCK:13pin--->SCK:6pin MIS:12pin<---SO:2pin MOS:11pin--->SI:5pin *CS is assigned 8pin (not default 10pin),because the 10pin is executed by a byte. Read data is not limitted by only a byte. The possibility of 2 bytes and more exists.
#include <SPI.h> //to use SPI I/F #define FLASH_CS 8 //set the pin to cs spre 8 only using Supresense made by Sony uint8_t data_id; //ID data uint8_t data_conf; //CONFIGURATION data uint8_t data_str; //Status Register data uint8_t data_write; //Write data boolean exe_at_once = true; //////////////////spi_initialize ////////////////// void spi_init() { SPI.begin(); pinMode(FLASH_CS, OUTPUT); SPI.setBitOrder(MSBFIRST); //send from MSB .Not LSB SPI.setClockDivider(SPI_CLOCK_DIV4); //20MHz // DIV"2" means "2"/16 divided internal clock(worked by 40MHz) but the target device "25FL" works up to DIV4(20MHz) SPI.setDataMode(SPI_MODE0); //MODE0 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); SPI.transfer(0x05); data_str = (uint8_t)SPI.transfer(0x00); return (data_str & 0x1); spi_set_cs(0x1); } void setup() { spi_init(); Serial.begin(9600); //////////////////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 as character(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 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); SPI.endTransaction(); spi_init(); //////////////////RCR ////////////////// Serial.print("RCR(0x35)_Read_Configuration_Register\n"); spi_set_cs(0x0); // RCR(0x35) are excuting // data_conf = SPI.transfer(0x35); SPI.transfer(0x35); for (uint16_t i = 0 ; i <= 0; ++i) { char cnt[1]; sprintf(cnt, "%2x", i); Serial.print(cnt); Serial.print(" "); } Serial.print("\n"); for (uint16_t i = 0 ; i <= 0; ++i) { data_conf = (uint8_t)SPI.transfer(0x00) ; char data_ccnt[1]; sprintf(data_ccnt, "%2x", data_conf); Serial.print(data_ccnt); Serial.print(" "); } Serial.print("\n"); spi_set_cs(0x1); SPI.endTransaction(); spi_init(); //WRITE STATUS RESISTER_check & initialize to "0x00" Serial.print("WEN(0x06)--->WRR(0x01**)_Write Enabled & Write Status Register \n"); Serial.print("Initialized 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); delay(100); Serial.print("Write_in_progress_check"); while (flash_is_wip()) { //消去待ち Serial.print("."); } Serial.print(" Clear\n"); Serial.print(" \n"); SPI.endTransaction(); spi_init(); //READ STATUS RESISTER Serial.print("RDSR(0x05)_STATUS_REGISTER\n"); spi_set_cs(0x0); // CMD_RDSR(0x05) are excuting SPI.transfer(0x05); data_str = (uint8_t)SPI.transfer(0x00); Serial.print(data_str, HEX); Serial.print("\n"); spi_set_cs(0x1); SPI.endTransaction(); spi_init(); } /* //////////////////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) { SPI.endTransaction(); spi_init(); delay(200); Serial.print("---Loop is stating--- \n"); /////////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"); Serial.print(" \n"); SPI.endTransaction(); spi_init(); //////////////////READ ////////////////// Serial.print("READ(0x03)\n"); spi_set_cs(0x0); SPI.transfer(0x03); SPI.transfer(0x21); SPI.transfer(0x00); SPI.transfer(0x00); 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) { uint8_t data; data = (uint8_t)SPI.transfer(0x00) ; char data_cnt[16]; sprintf(data_cnt, "%2x", data); Serial.print(data_cnt); Serial.print(" "); } spi_set_cs(0x1); Serial.print("\n"); SPI.endTransaction(); spi_init(); //////////////////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) { char cnt[16]; sprintf(cnt, "%2x", i); Serial.print(cnt); Serial.print(" "); } Serial.print(" \n"); for (uint16_t i = 0 ; i <= 15; ++i) { //data_write = (uint8_t)SPI.transfer(i + 1 ) ; data_write = i + 1 ; SPI.transfer(i +1 ) ; char data_count[16]; sprintf(data_count,"%2x",data_write); Serial.print(data_count); Serial.print(" "); } Serial.print(" \n"); spi_set_cs(0x1); Serial.print("Write_in_progress_check"); while (flash_is_wip()) { //消去待ち Serial.print("."); } Serial.print(" Clear\n"); Serial.print(" \n"); SPI.endTransaction(); spi_init(); //////////////////READ ////////////////// Serial.print("READ(0x03)\n"); spi_set_cs(0x0); SPI.transfer(0x03); SPI.transfer(0x21); SPI.transfer(0x00); SPI.transfer(0x00); 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) { uint8_t data; data = (uint8_t)SPI.transfer(0x00) ; char data_cnt[16]; sprintf(data_cnt, "%2x", data); 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(0x01**)_Write Enabled & Write Status Register \n"); Serial.print("Changed data to 0x1C \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"); Serial.print(" \n"); SPI.endTransaction(); spi_init(); /////////READ STATUS RESISTER///////// Serial.print("RDSR(0x05)_STATUS_REGISTER\n"); spi_set_cs(0x0); // CMD_RDSR(0x05) are excuting 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"); SPI.endTransaction(); spi_init(); //////////////////READ CONFIGURATION REGISTER ////////////////// Serial.print("RCR(0x35)_Read_Configuration_Register\n"); spi_set_cs(0x0); // RCR(0x35) are excuting // data_conf = SPI.transfer(0x35); SPI.transfer(0x35); for (uint16_t i = 0 ; i <= 0; ++i) { char cnt[1]; sprintf(cnt, "%2x", i); Serial.print(cnt); Serial.print(" "); } Serial.print("\n"); for (uint16_t i = 0 ; i <= 0; ++i) { data_conf = (uint8_t)SPI.transfer(0x00) ; char data_ccnt[1]; sprintf(data_ccnt, "%2x", data_conf); Serial.print(data_ccnt); Serial.print(" "); } Serial.print("\n"); spi_set_cs(0x1); /////////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 0 WEN(0x06)--->WRR(0x01**)_Write Enabled & Write Status Register Initialized to 0x00. All areas are Write Enabled Write_in_progress_check Clear RDSR(0x05)_STATUS_REGISTER 0 ---Loop is stating--- 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(0x02) Terget to fixed address 0x210000 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 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(0x01**)_Write Enabled & Write Status Register Changed data to 0x1C Write_in_progress_check.................. Clear RDSR(0x05)_STATUS_REGISTER 1C WEN_COMMAND cycles are 3 times + 1 RCR(0x35)_Read_Configuration_Register 0 0