Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed EEPROM USBDevice
RawNAND.cpp
- Committer:
- muraguchi
- Date:
- 2021-09-15
- Revision:
- 4:2e8b78a74493
- Parent:
- 3:28ceea26c918
File content as of revision 4:2e8b78a74493:
#include "RawNAND.h"
// TODO: Replace wait_us(int) to wait_ns
RawNAND::RawNAND(PinName ceb0,PinName ceb1, 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)
: _ceb0(ceb0,1),_ceb1(ceb1,1),_cle(cle,1),
_ale(ale,1),_web(web,1),
_reb(reb,1),_wpb(wpb,1),
_rbb(rbb,PullUp),
_io(io1,io2,io3,io4,io5,io6,io7,io8) {
_io.mode(PullNone);
_io.input();
}
void RawNAND::reset(uint8_t cs) {
// wait ready
while(_rbb==0){
__NOP();
}
// RESET COMMAND (0xff)
if(cs==0) {
_ceb0 = 0;
} else if (cs==1) {
_ceb1 = 1;
}
_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();
}
if(cs==0) {
_ceb0 = 1;
} else if (cs==1) {
_ceb1 = 1;
}
}
void RawNAND::idRead(uint8_t cs, uint8_t * readData) {
// ID READ COMMAND (0x90)
if(cs==0) {
_ceb0 = 0;
} else if (cs==1) {
_ceb1 = 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
if(cs==0) {
_ceb0 = 1;
} else if (cs==1) {
_ceb1 = 1;
}
wait_us(tCHZ_US);
}
uint8_t RawNAND::statusRead(uint8_t cs) {
uint8_t status;
// wait ready
while(_rbb==0){
__NOP();
}
// STATUS READ COMMAND (0x70)
if(cs==0) {
_ceb0 = 0;
} else if (cs==1) {
_ceb1 = 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);
if(cs==0) {
_ceb0 = 1;
} else if (cs==1) {
_ceb1 = 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 cs, 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)
if(cs==0) {
_ceb0 = 0;
} else if (cs==1) {
_ceb1 = 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);
}
if(cs==0) {
_ceb0 = 1;
} else if (cs==1) {
_ceb1 = 1;
}
// wait io hiz
wait_us(tCHZ_US);
}
uint8_t RawNAND::erase(uint8_t cs, uint16_t blockAddress){
// wait ready
while(_rbb==0){
__NOP();
}
// 1ST ERASE COMMAND (0x60)
if(cs==0) {
_ceb0 = 0;
} else if (cs==1) {
_ceb1 = 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(cs);
}
uint8_t RawNAND::pageProgram(uint8_t cs, 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)
if(cs==0) {
_ceb0 = 0;
} else if (cs==1) {
_ceb1 = 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(cs);
}