1MB version

Dependencies:   mbed EEPROM USBDevice

RawNAND.cpp

Committer:
muraguchi
Date:
2021-02-10
Revision:
3:28ceea26c918
Parent:
0:1472308ded03

File content as of revision 3:28ceea26c918:

#include "RawNAND.h"

// TODO: Replace wait_us(int) to wait_ns 

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 ERASE 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 ERASE 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();
}