500KB USB mass storage
Dependencies: mbed EEPROM USBDevice
RawNAND.cpp
- Committer:
- muraguchi
- Date:
- 2021-02-09
- Revision:
- 1:49963e1662d6
- Parent:
- 0:1472308ded03
File content as of revision 1:49963e1662d6:
#include "RawNAND.h" // CEB // CLE // ALE // WEB // REB // RBB // WPB // IO1 // IO2 // IO3 // IO4 // IO5 // IO6 // IO7 // IO8 RawNAND::RawNAND(PinName ceb, PinName cle, PinName ale, PinName web, PinName reb, PinName wpb, PinName rbb, PinName io1, PinName io2, PinName io3, PinName io4, PinName io5, PinName io6, PinName io7, PinName io8) : _ceb(ceb,1),_cle(cle,1), _ale(ale,1),_web(web,1), _reb(reb,1),_wpb(wpb,1), _rbb(rbb,PullNone), _io(io1,io2,io3,io4,io5,io6,io7,io8) { _io.mode(PullNone); _io.input(); } void RawNAND::reset() { // wait ready while(_rbb==0){ __NOP(); } // RESET COMMAND (0xff) _ceb = 0; _cle = 1; _ale = 0; _web = 0; _io=0xff; _io.output(); // wait setup time : max(tCS,tCLS,tALS,tDS,tWP) wait_us(tCS_US); _web = 1; // wait hold time : max(tCLH,tALH,tDH,tWH,tWB,tCH) wait_us(tWB_US); // check tRBB; while (_rbb==0){ __NOP(); } _ceb = 1; } void RawNAND::idRead(uint8_t * readData) { // ID READ COMMAND (0x90) _ceb = 0; _cle = 1; _ale = 0; _web = 0; _io=0x90; _io.output(); // wait setup time : max(tCS,tCLS,tALS,tDS,tWP) wait_us(tCS_US); _web = 1; // wait hold time : max(tCLH,tALH,tDH,tWH) wait_us(tWH_US); // IO READ ADDRESS (0x00) _cle=0; _ale=1; _web=0; _io=0x00; // wait setup time : max(tCLS,tALS,tDS,tWP) wait_us(tCLS_US); _web=1; // wait hold time : max(tCLH,tALH,tDH,tWH) wait_us(tWH_US); // ALE low and IO input _ale=0; _io.input(); // ALE low to tREB low : tAR wait_us(tAR_US); // IO READ read data for (int l=0;l<5;l++) { _reb = 0; // wait max(tREA,tRP) wait_us(tREA_US); *(readData+l)=_io; _reb = 1; // wait tREH wait_us(tREH_US); } // wait io hiz _ceb = 1; wait_us(tCHZ_US); } uint8_t RawNAND::statusRead() { uint8_t status; // wait ready while(_rbb==0){ __NOP(); } // STATUS READ COMMAND (0x70) _ceb = 0; _cle = 1; _ale = 0; _web = 0; _io=0x70; _io.output(); // wait setup time : max(tCS,tCLS,tALS,tDS,tWP) wait_us(tCS_US); _web = 1; // wait hold time : max(tCLH,tDH,tWH) wait_us(tWH_US); _cle = 0; _io.input(); // wait max(tWHR-tWH,tCLR-tWH) wait_us(tWHR_US-tWH_US); _reb = 0; // wait max(tREA,tRP) wait_us(tREA_US); status = _io; _reb = 1; // wait tREH wait_us(tREH_US); _ceb = 1; wait_us(tCHZ_US); // wait io hiz return status; } void RawNAND::setWriteProtect(uint8_t writeProtect){ _wpb = writeProtect; // wait tWW wait_us(tWW_US); } void RawNAND::pageRead(uint8_t * readData,uint16_t blockAddress,uint8_t pageAddress,uint16_t columnAddress,uint16_t beats){ // wait ready while(_rbb==0){ __NOP(); } // 1ST READ COMMAND (0x00) _ceb = 0; _cle = 1; _ale = 0; _web = 0; _io=0x00; _io.output(); // wait setup time : max(tCS,tCLS,tALS,tDS,tWP) wait_us(tCS_US); _web = 1; // wait hold time : max(tCLH,tDH,tWH) wait_us(tWH_US); // 1st address column [7:0] _cle = 0; _ale = 1; _web = 0; _io = columnAddress & 0xff; // wait setup time : max(tALS,tCLS,tDS,tWP) wait_us(tWP_US); _web = 1; // wait hold time : max(tCLH,tDH,tWH) wait_us(tWH_US); // 2nd address column [11:8] _web = 0; _io = (columnAddress>>8) & 0x0f; // wait setup time : max(tALS,tCLS,tDS,tWP) wait_us(tWP_US); _web = 1; // wait hold time : max(tCLH,tDH,tWH) wait_us(tWH_US); // 3rd address {blockAddress[1:0],pageAddress[5:0]} _web = 0; _io = ((blockAddress<<6) | pageAddress) ; // wait setup time : max(tALS,tDS,tWP) wait_us(tWP_US); _web = 1; // wait hold time : max(tALH,tDH,tWH) wait_us(tWH_US); // 4th address blockAddress[9:2] _web = 0; _io = (blockAddress>>2) ; // wait setup time : max(tALS,tDS,tWP) wait_us(tWP_US); _web = 1; // wait hold time : max(tALH,tDH,tWH) wait_us(tWH_US); // 2ND READ COMMAND (0x30) _cle = 1; _ale = 0; _web = 0; _io = 0x30; // wait setup time : max(tALS,tCLS,tDS,tWP) wait_us(tWP_US); _web = 1; // wait hold time : max(tALH,tDH,tWH,tWB) wait_us(tWB_US); _cle = 0; _io.input(); // wait ready while(_rbb==0){ __NOP(); } // wait tRR ( RBB to REB Low ) wait_us(tRR_US); // read sequence for (int b=0;b<beats;b++){ _reb = 0; // wait max(tREA,tRP) wait_us(tREA_US); *(readData + b)= _io; _reb = 1; // wait tREH wait_us(tREH_US); } _ceb = 1; // wait io hiz wait_us(tCHZ_US); } uint8_t RawNAND::erase(uint16_t blockAddress){ // wait ready while(_rbb==0){ __NOP(); } // 1ST READ COMMAND (0x60) _ceb = 0; _cle = 1; _ale = 0; _web = 0; _io=0x60; _io.output(); // wait setup time : max(tCS,tCLS,tALS,tDS,tWP) wait_us(tCS_US); _web = 1; // wait hold time : max(tCLH,tDH,tWH) wait_us(tWH_US); // 1st page address {blockAddress[1:0],pageAddress[5:0]} _cle = 0; _ale = 1; _web = 0; _io = (blockAddress<<6) ; // wait setup time : max(tALS,tDS,tWP) wait_us(tWP_US); _web = 1; // wait hold time : max(tALH,tDH,tWH) wait_us(tWH_US); // 2nd page address blockAddress[9:2] _web = 0; _io = (blockAddress>>2) ; // wait setup time : max(tALS,tDS,tWP) wait_us(tWP_US); _web = 1; // wait hold time : max(tALH,tDH,tWH) wait_us(tWH_US); // 2ND READ COMMAND (0xD0) _cle = 1; _ale = 0; _web = 0; _io = 0xD0; // wait setup time : max(tALS,tCLS,tDS,tWP) wait_us(tWP_US); _web = 1; // wait hold time : max(tALH,tDH,tWH,tWB) wait_us(tWB_US); _cle = 0; _io.input(); // wait ready while(_rbb==0){ __NOP(); } return statusRead(); } uint8_t RawNAND::pageProgram(const uint8_t * writeData,uint16_t blockAddress,uint8_t pageAddress,uint16_t columnAddress,uint16_t beats){ // wait ready while(_rbb==0){ __NOP(); } // 1ST PROGRAM COMMAND (0x80) _ceb = 0; _cle = 1; _ale = 0; _web = 0; _io = 0x80; _io.output(); // wait setup time : max(tCS,tCLS,tALS,tDS,tWP) wait_us(tCS_US); _web = 1; // wait hold time : max(tCLH,tDH,tWH) wait_us(tWH_US); // 1st address column [7:0] _cle = 0; _ale = 1; _web = 0; _io = columnAddress & 0xff; // wait setup time : max(tALS,tCLS,tDS,tWP) wait_us(tWP_US); _web = 1; // wait hold time : max(tCLH,tDH,tWH) wait_us(tWH_US); // 2nd address column [11:8] _web = 0; _io = (columnAddress>>8) & 0x0f; // wait setup time : max(tALS,tCLS,tDS,tWP) wait_us(tWP_US); _web = 1; // wait hold time : max(tCLH,tDH,tWH) wait_us(tWH_US); // 3rd address {blockAddress[1:0],pageAddress[5:0]} _web = 0; _io = ((blockAddress<<6) | pageAddress) ; // wait setup time : max(tALS,tDS,tWP) wait_us(tWP_US); _web = 1; // wait hold time : max(tALH,tDH,tWH) wait_us(tWH_US); // 4th address blockAddress[9:2] _web = 0; _io = (blockAddress>>2) ; // wait setup time : max(tALS,tDS,tWP) wait_us(tWP_US); _web = 1; // wait hold time : max(tALH,tDH,tWH) wait_us(tWH_US); // datain _ale = 0; for (int b=0;b<beats;b++) { _io = *(writeData+b); _web = 0; // setup // wait setup time : max(tALS,tCLS,tDS,tWP) wait_us(tWP_US); _web = 1; // hold // wait hold time : max(tALH,tDH,tWH) wait_us(tWH_US); } // 2ND PROGRAM COMMAND (0x10) _cle = 1; _ale = 0; _io = 0x10; _web = 0; // wait setup time : max(tALS,tCLS,tDS,tWP) wait_us(tWP_US); _web = 1; // wait hold time : max(tCLH,tDH,tWH,tWB) wait_us(tWB_US); _cle = 0; _io.input(); // wait ready while(_rbb==0){ __NOP(); } return statusRead(); }