fl { NOR type Flash ROM 8Mbyte(W25Q64FV) 24bit address 0x00000 - 0x7FFFFF PropForth 5.5 2019/12/10 14:58:44 W25Q64FV Total memory 8388608byte Address 0x00000 - 0x7FFFFF Total block 128(64KB/block) 256(32KB/block) Total sector 2048 (4KB/sector) ---------- P0 ---- |/CS Vcc| --- 3V3 P1 ---- |/DO /HOLD| --- 3V3 3V3 --- |/WP CLK| --- P2 GND --- |/GND DI| --- P3 ---------- } \ ******************* \ Constants \ ******************* \ pin 0 wconstant cs 1 wconstant sdi 2 wconstant clk 3 wconstant sdo \ instruction 6 wconstant WRITE_ENABLE 4 wconstant WRITE_DISABLE 5 wconstant READ_STATUS_REG1 h35 wconstant READ_STATUS_REG2 2 wconstant PAGE_PROGRAM hD8 wconstant BLOCK_ERASE64KB h52 wconstant BLOCK_ERASE32KB h20 wconstant SECTOR_ERASE hC7 wconstant CHIP_ERASE hB9 wconstant POWER_DOWN hAB wconstant RELEASE_PDOWN_ID h90 wconstant MANUFACURER_ID h4B wconstant UNIQUE_ID h9F wconstant JEDEC_ID 3 wconstant READ_DATA hB wconstant FAST_READ 1 wconstant BUSY_MASK 2 wconstant WEN_MASK sdi >m constant mask_di \ ******************* \ Variables \ ******************* variable buffer d252 allot \ ******************* \ Main \ ******************* \ Initilize spi-port \ ( -- ) : spiInit cs pinout clk pinout sdo pinout cs pinhi ; : clkLo clk pinlo ; : clkHi clk pinhi ; \ Select chip \ ( -- ) : selectChip cs pinlo ; \ Deselect chip \ ( -- ) : deselectChip cs pinhi ; \ Output data to device's DI \ ( n1 -- ) n1:8bit data : spiOut h80 8 0 do clkLo 2dup and if sdo pinhi else sdo pinlo then clkHi 1 rshift loop 2drop ; \ Input data from device's DO \ ( -- n1 ) : spiIn 0 8 0 do 1 lshift clkLo ina COG@ mask_di and if 1 or then clkHi loop ; \ Read READ_STATUS_REG1 \ ( -- n1 ) n1:READ_STATUS_REG1 : getStatusReg1 selectChip READ_STATUS_REG1 spiOut spiIn deselectChip clkLo ; \ Read READ_STATUS_REG2 \ ( -- n1 ) n1:READ_STATUS_REG2 : getStatusReg2 selectChip READ_STATUS_REG2 spiOut spiIn deselectChip clkLo ; \ Get JEDEC ID(Manufacture ID, Memory Type,Capacity) \ ( -- n1 n2 n3 ) n1:ManufactureID n2:Memory Type n3:Capacity : getJEDEC selectChip JEDEC_ID spiOut spiIn spiIn spiIn deselectChip clkLo hex ." Capasity: " . cr ." Memory Type: " . cr ." Manufacture ID: " . cr decimal cr ; \ Get Unique ID \ ( -- n1 n2 ) n1:upper32bit serial number n1:lower32bit serial number : getUniqueID selectChip UNIQUE_ID spiOut 4 0 do 0 spiOut loop 2 0 do 4 0 do spiIn loop swap 8 lshift or swap d16 lshift or swap d24 lshift or loop deselectChip clkLo ." Serial number: " swap hex .long space .long cr cr cr decimal ; \ Check busy before writing \ ( -- n1 ) n1:true if busy : busy? selectChip READ_STATUS_REG1 spiOut spiIn deselectChip clkLo BUSY_MASK and ; \ Power down \ ( -- ) : powerDown selectChip POWER_DOWN spiOut deselectChip clkLo ; \ Release Power down/Device ID \ ( -- ) : releasePowerID selectChip RELEASE_PDOWN_ID spiOut 0 spiOut 0 spiOut 0 spiOut spiIn deselectChip clkLo ." DeviceID: " hex . decimal cr cr ; \ Read manufacture/Device ID \ ( -- ) : manufactureID selectChip MANUFACURER_ID spiOut 0 spiOut 0 spiOut 0 spiOut spiIn spiIn deselectChip clkLo hex ." DeviceID: " . cr ." Manufacture ID: " . cr cr decimal ; \ Enable writing \ ( -- ) : enableWrite selectChip WRITE_ENABLE spiOut deselectChip clkLo ; \ Inhibit writing \ ( -- ) : inhibitWrite selectChip WRITE_DISABLE spiOut deselectChip clkLo ; \ Send 23bit address \ ( n1 -- ) n1:address : sendAddres dup d16 rshift spiOut dup 8 rshift spiOut spiOut ; \ Read data \ ( n1 n2 n3 -- ) \ n1:buffer address n2:data number to read n3:address[0x00000 - 0x7FFF00] : readData selectChip READ_DATA spiOut sendAddres 0 do spiIn over i + C! loop deselectChip drop clkLo ; \ \ Read data fastly \ ( n1 n2 n3 -- ) \ n1:buffer address n2:data number to read n3::address[0x00000 - 0x7FFF00] : readDataFast selectChip FAST_READ spiOut sendAddres 0 spiOut \ Send dummy 0 do spiIn over i + C! loop deselectChip drop clkLo ; \ Check busy flag \ ( -- ) : checkBusy begin busy? 0= until ; \ Erace sector(4kByte) \ ( n1 -- ) n1:sector number[0-2047] : eraseSector enableWrite selectChip SECTOR_ERASE spiOut d12 lshift sendAddres deselectChip checkBusy clkLo ; \ Erase block(64kByte) \ ( n1 -- ) n1:block number[0-127] : eraseBlock64KB d16 lshift enableWrite selectChip BLOCK_ERASE64KB spiOut sendAddres clkLo deselectChip checkBusy ; \ Erase block(32kByte) \ ( n1 -- ) n1:block number[0-255] : eraseBlock32KB d15 lshift enableWrite selectChip BLOCK_ERASE32KB spiOut sendAddres clkLo deselectChip checkBusy ; \ Erase all \ ( -- ) : eraseAll enableWrite selectChip CHIP_ERASE spiOut clkLo deselectChip checkBusy ; \ Write page-data(256byte) \ ( n1 n2 n3 -- ) n1:buffer address n2:number n3:sector number[0-2047] : writeData d12 lshift enableWrite selectChip PAGE_PROGRAM spiOut sendAddres 0 do over i d256 * + d256 bounds do C@ spiOut loop loop deselectChip checkBusy drop clkLo ; \ test writing 256byte \ ( n1 n2 -- ) n1:address[0x00000 - 0x7FFF00] n2:start number : test spiInit enableWrite selectChip PAGE_PROGRAM spiOut over sendAddres d256 0 do dup i + spiOut loop drop clkLo deselectChip checkBusy buffer 256 rot readData buffer d256 dump ;