Macronix Low Power Serial NOR Flash in SPI mode.
Dependents: MX25Rxx35F_Serial_NOR_Flash_Testbench MX25Rxx35F_Serial_NOR_Flash_Testbench Coragem_all_sensors 1_Test_Flash_ADC_RTT
Diff: SPI_MX25R.cpp
- Revision:
- 1:8403da5975cb
- Parent:
- 0:a16ad6f5c788
- Child:
- 2:f72110475fec
--- a/SPI_MX25R.cpp Wed Jul 08 20:59:40 2015 +0000 +++ b/SPI_MX25R.cpp Mon Jul 20 20:45:33 2015 +0000 @@ -1,35 +1,42 @@ /* * SPI_MX25R SPI-Flash Memory - * Macronix Low Power Serial Flash Memory - * Standard Pin-out + * Macronix Low Power Serial NOR Flash + * (x2, and x4 I/O modes not implemented) */ #include "SPI_MX25R.h" +#define CMD_READ 0x03 // x1 Normal Read Data Byte +#define CMD_FREAD 0x0B // x1 Fast Read Data Byte +#define CMD_PP 0x02 // Page Program +#define CMD_SE 0x20 // 4KB Sector Erase +#define CMD_32KBE 0x52 // 32KB Block Erase +#define CMD_BE 0xD8 // 64KB Block Erase +#define CMD_CE 0xC7 // Chip Erase +#define CMD_RDID 0x9F // Read Identification +#define CMD_RDSFDP 0x5A // Read SFDP #define CMD_RDSR 0x05 // Read Status Register #define CMD_RDCR 0x15 // Read Configuration Register -#define CMD_RDID 0x9F // Read Identification #define CMD_WREN 0x06 // Write Enable #define CMD_WRDI 0x04 // Write Disable #define CMD_WRSR 0x01 // Write Status Register -#define CMD_READ 0x03 // Read Data Byte -#define CMD_PP 0x02 // Page Program -#define CMD_BE 0xD8 // 64KB Block Erase -#define CMD_32KBE 0x52 // 32KB Block Erase -#define CMD_SE 0x20 // 4KB Sector Erase -#define CMD_CE 0xC7 // Chip Erase #define CMD_RSTEN 0x66 // Reset Enable #define CMD_RST 0x99 // Reset -#define CMD_RDSFDP 0x5A // Read SFDP -#define CMD_FREAD 0x0B // x1 FREAD -#define CMD_2READ 0xBB // x2 2READ -#define CMD_DREAD 0x3B // x2 DREAD -#define CMD_4READ 0xEB // x4 4READ -#define CMD_QREAD 0x6B // x4 QREAD #define CMD_PESUS 0xB0 // x4 Program/Erase Suspend #define CMD_PERES 0x30 // x4 Program/Erase Resume #define CMD_DP 0xB9 // Enter Deep Power Down - +#define CMD_SBL 0xC0 // Set Burst Length +#define CMD_RRE 0xFF // Release Read Enhanced Mode +#define CMD_NOP 0x00 // No Operation +#define CMD_ENSO 0xB1 // Enter Secure OTP +#define CMD_EXSO 0xC1 // Exit Secure OTP +// x2 and x4 commands not currently supported with FRDM K64F platform +//#define CMD_2READ 0xBB // x2 2READ +//#define CMD_DREAD 0x3B // x2 DREAD +//#define CMD_4READ 0xEB // x4 4READ +//#define CMD_QREAD 0x6B // x4 QREAD +//#define CMD_4PP 0x38 // x4 PP + SPI_MX25R::SPI_MX25R(PinName mosi, PinName miso, PinName sclk, PinName cs) : m_spi(mosi, miso, sclk), m_cs(cs) { } @@ -63,14 +70,71 @@ m_spi.write(CMD_RST) ; m_cs = 1 ; } + +void SPI_MX25R::pgmersSuspend(void) +{ + m_cs = 0 ; + m_spi.write(CMD_PESUS) ; + m_cs = 1 ; +} + +void SPI_MX25R::pgmersResume(void) +{ + m_cs = 0 ; + m_spi.write(CMD_PERES) ; + m_cs = 1 ; +} + +void SPI_MX25R::deepPowerdown(void) +{ + m_cs = 0 ; + m_spi.write(CMD_DP) ; + m_cs = 1 ; +} + +void SPI_MX25R::setBurstlength(void) +{ + m_cs = 0 ; + m_spi.write(CMD_SBL) ; + m_cs = 1 ; +} + +void SPI_MX25R::releaseReadenhaced(void) +{ + m_cs = 0 ; + m_spi.write(CMD_RRE) ; + m_cs = 1 ; +} + +void SPI_MX25R::noOperation(void) +{ + m_cs = 0 ; + m_spi.write(CMD_NOP) ; + m_cs = 1 ; +} + +void SPI_MX25R::enterSecureOTP(void) +{ + m_cs = 0 ; + m_spi.write(CMD_ENSO) ; + m_cs = 1 ; +} + +void SPI_MX25R::exitSecureOTP(void) +{ + m_cs = 0 ; + m_spi.write(CMD_EXSO) ; + m_cs = 1 ; +} + uint8_t SPI_MX25R::readStatus(void) { uint8_t data ; m_cs = 0 ; m_spi.write(CMD_RDSR) ; - data = m_spi.write(CMD_RDSR) ; // dummy - m_spi.write(CMD_RDSR) ; - data = m_spi.write(CMD_RDSR) ; // dummy + data = m_spi.write(CMD_RDSR) ; // dummy + m_spi.write(CMD_RDSR) ; + data = m_spi.write(CMD_RDSR) ; // dummy m_cs = 1 ; return( data ) ; } @@ -80,11 +144,11 @@ uint8_t data; uint32_t config32 = 0 ; m_cs = 0 ; - m_spi.write(CMD_RDCR) ; // send 15h - data= m_spi.write(0x55) ; // dumy to get 1st Byte out - config32 = config32 | data ; // put in 32b reg - data= m_spi.write(0x55) ; //dummy to get 2nd Byte out - config32 = (config32 << 8) | data ; // shift and put in reg + m_spi.write(CMD_RDCR) ; // send 15h + data= m_spi.write(0x55) ; // dumy to get 1st Byte out + config32 = config32 | data ; // put in 32b reg + data= m_spi.write(0x55) ; // dummy to get 2nd Byte out + config32 = (config32 << 8) | data ; // shift and put in reg m_cs = 1 ; return( config32 ) ; } @@ -94,13 +158,13 @@ uint8_t data; uint32_t data32 = 0 ; m_cs = 0 ; - m_spi.write(CMD_RDID) ; // send 9Fh - data= m_spi.write(0x55) ; // dumy to get 1st Byte out - data32 = data32 | data ; // put in 32b reg - data= m_spi.write(CMD_RDID) ; //dummy to get 2nd Byte out - data32 = (data32 << 8) | data ; // shift and put in reg - data= m_spi.write(0x55) ; //dummy to get 3rd Byte out - data32 = (data32 << 8) | data ; // shift again and put in reg + m_spi.write(CMD_RDID) ; // send 9Fh + data= m_spi.write(0x55) ; // dumy to get 1st Byte out + data32 = data32 | data ; // put in 32b reg + data= m_spi.write(CMD_RDID) ; // dummy to get 2nd Byte out + data32 = (data32 << 8) | data ; // shift and put in reg + data= m_spi.write(0x55) ; // dummy to get 3rd Byte out + data32 = (data32 << 8) | data ; // shift again and put in reg m_cs = 1 ; return( data32 ) ; } @@ -109,38 +173,28 @@ { int i ; m_cs = 0 ; - m_spi.write(CMD_PP) ; // Program Page 02h - m_spi.write((addr >> 16)&0xFF) ; // adr 23:16 - m_spi.write((addr >> 8)&0xFF) ; // adr 15:8 - m_spi.write(addr & 0xFF) ; // adr 7:0 - for (i = 0 ; i < numData ; i++ ) { // data = 00, 01, 02, .. to FEh, FFh = all 256 Bytes in 1 page. + m_spi.write(CMD_PP) ; // Program Page 02h + m_spi.write((addr >> 16)&0xFF) ; // adr 23:16 + m_spi.write((addr >> 8)&0xFF) ; // adr 15:8 + m_spi.write(addr & 0xFF) ; // adr 7:0 + for (i = 0 ; i < numData ; i++ ) { // data = 00, 01, 02, .. to FEh, FFh = all 256 Bytes in 1 page. m_spi.write(data[i]) ; } m_cs = 1 ; // poll in main } -void SPI_MX25R::hpmode(void) -{ +void SPI_MX25R::writeStatusreg(int addr) // Write SR cmd 01h + 3B data +{ m_cs = 0 ; - m_spi.write(CMD_WRSR) ; // Write SR cmd 01h - m_spi.write(0x00) ; // SR = 00h - m_spi.write(0x00) ; // CR1 = 00h - m_spi.write(0x02) ; // CR2 = 02h, To set Config Reg 2 <1> = 1 to enter High Performance mode + m_spi.write(CMD_WRSR) ; // Write SR cmd 01h + m_spi.write((addr >> 16)&0xFF) ; // address + m_spi.write((addr >> 8)&0xFF) ; + m_spi.write(addr & 0xFF) ; m_cs = 1 ; } -void SPI_MX25R::lpmode(void) -{ - m_cs = 0 ; - m_spi.write(CMD_WRSR) ; // Write SR cmd 01h - m_spi.write(0x00) ; // SR = 00h - m_spi.write(0x00) ; // CR1 = 00h - m_spi.write(0x00) ; // CR2 = 00h, To set Config Reg 2 <1> = 0 to enter Low Power mode - m_cs = 1 ; -} - -void SPI_MX25R::blockErase(int addr) +void SPI_MX25R::blockErase(int addr) // 64KB Block Erase { uint8_t data[3] ; data[0] = (addr >> 16) & 0xFF ; @@ -155,7 +209,7 @@ // poll in main } -void SPI_MX25R::blockErase32KB(int addr) +void SPI_MX25R::blockErase32KB(int addr) // 32KB Block Erase { uint8_t data[3] ; data[0] = (addr >> 16) & 0xFF ; @@ -170,7 +224,7 @@ // poll in main } -void SPI_MX25R::sectorErase(int addr) +void SPI_MX25R::sectorErase(int addr) // 4KB Sector Erase { uint8_t data[3] ; data[0] = (addr >> 16) & 0xFF ; @@ -184,7 +238,8 @@ m_cs = 1 ; // poll in main } -void SPI_MX25R::chipErase(void) + +void SPI_MX25R::chipErase(void) // Chip Erase { m_cs = 0 ; m_spi.write(CMD_CE) ; @@ -192,38 +247,44 @@ // poll in main } -uint8_t SPI_MX25R::read8(int addr) +uint8_t SPI_MX25R::read8(int addr) // Single Byte Read { uint8_t data ; m_cs = 0 ; - m_spi.write(CMD_READ) ; + m_spi.write(CMD_READ) ; // send 03h m_spi.write((addr >> 16)&0xFF) ; m_spi.write((addr >> 8)&0xFF) ; m_spi.write(addr & 0xFF) ; - data = m_spi.write(addr & 0xFF) ; // write data is dummy + data = m_spi.write(addr & 0xFF) ; // write data is dummy + m_cs = 1 ; + return( data ) ; // return 1 byte +} + +uint8_t SPI_MX25R::readSFDP(int addr) // Single Byte Read +{ + uint8_t data ; + m_cs = 0 ; + m_spi.write(CMD_RDSFDP) ; // send cmd 5Ah + m_spi.write((addr >> 16)&0xFF) ; // address[23:16] + m_spi.write((addr >> 8)&0xFF) ; // address[15:8] + m_spi.write(addr & 0xFF) ; // address[7:0] + m_spi.write(0x00 & 0xFF) ; // dummy cycle + data = m_spi.write(addr & 0xFF) ; // return 1 byte m_cs = 1 ; return( data ) ; } -uint32_t SPI_MX25R::rd32(int addr) -{ - uint8_t data; - uint32_t data32 = 0 ; +uint8_t SPI_MX25R::readFREAD(int addr) // Single Byte Read +{ + uint8_t data ; m_cs = 0 ; - m_spi.write(CMD_READ) ; // send 03h - - m_spi.write((addr >> 16)&0xFF) ; // address - m_spi.write((addr >> 8)&0xFF) ; - m_spi.write(addr & 0xFF) ; - - data= m_spi.write(0xFF) ; // dumy to get 1st Byte out - data32 = data32 | data ; // put in 32b reg - data= m_spi.write(0xFF) ; //dummy to get 2nd Byte out - data32 = (data32 << 8) | data ; // shift and put in reg - data= m_spi.write(0xFF) ; //dummy to get 3rd Byte out - data32 = (data32 << 8) | data ; // shift again and put in reg - data= m_spi.write(0xFF) ; //dummy to get 4th Byte out - data32 = (data32 << 8) | data ; // shift again and put in reg + m_spi.write(CMD_FREAD) ; // send cmd 0Bh + m_spi.write((addr >> 16)&0xFF) ; // address[23:16] + m_spi.write((addr >> 8)&0xFF) ; // address[15:8] + m_spi.write(addr & 0xFF) ; // address[7:0] + m_spi.write(0x00 & 0xFF) ; // dummy cycle + data = m_spi.write(addr & 0xFF) ; // return 1 byte m_cs = 1 ; - return( data32 ) ; + return( data ) ; } +