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
Revision 2:f72110475fec, committed 2015-07-23
- Comitter:
- alec1
- Date:
- Thu Jul 23 17:11:27 2015 +0000
- Parent:
- 1:8403da5975cb
- Commit message:
- added support for cmds REMS, RES, RDSCUR, WRSCUR
Changed in this revision
SPI_MX25R.cpp | Show annotated file Show diff for this revision Revisions of this file |
SPI_MX25R.h | Show annotated file Show diff for this revision Revisions of this file |
diff -r 8403da5975cb -r f72110475fec SPI_MX25R.cpp --- a/SPI_MX25R.cpp Mon Jul 20 20:45:33 2015 +0000 +++ b/SPI_MX25R.cpp Thu Jul 23 17:11:27 2015 +0000 @@ -1,178 +1,185 @@ /* - * SPI_MX25R SPI-Flash Memory + * SPI_MX25R Series SPI-Flash Memory * 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_WREN 0x06 // Write Enable -#define CMD_WRDI 0x04 // Write Disable -#define CMD_WRSR 0x01 // Write Status Register -#define CMD_RSTEN 0x66 // Reset Enable -#define CMD_RST 0x99 // Reset -#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) { } - + SPI_MX25R::~SPI_MX25R() { } - + void SPI_MX25R::writeEnable(void) { - m_cs = 0 ; + m_cs = CS_LOW ; m_spi.write(CMD_WREN) ; - m_cs = 1 ; + m_cs = CS_HIGH ; } - + void SPI_MX25R::writeDisable(void) { - m_cs = 0 ; + m_cs = CS_LOW ; m_spi.write(CMD_WRDI) ; - m_cs = 1 ; + m_cs = CS_HIGH ; } - + void SPI_MX25R::resetEnable(void) { - m_cs = 0 ; + m_cs = CS_LOW ; m_spi.write(CMD_RSTEN) ; - m_cs = 1 ; + m_cs = CS_HIGH ; } - + void SPI_MX25R::reset(void) { - m_cs = 0 ; + m_cs = CS_LOW ; m_spi.write(CMD_RST) ; - m_cs = 1 ; + m_cs = CS_HIGH ; } - + void SPI_MX25R::pgmersSuspend(void) { - m_cs = 0 ; + m_cs = CS_LOW ; m_spi.write(CMD_PESUS) ; - m_cs = 1 ; + m_cs = CS_HIGH ; } - + void SPI_MX25R::pgmersResume(void) { - m_cs = 0 ; + m_cs = CS_LOW ; m_spi.write(CMD_PERES) ; - m_cs = 1 ; + m_cs = CS_HIGH ; } - + void SPI_MX25R::deepPowerdown(void) { - m_cs = 0 ; + m_cs = CS_LOW ; m_spi.write(CMD_DP) ; - m_cs = 1 ; + m_cs = CS_HIGH ; } - + void SPI_MX25R::setBurstlength(void) { - m_cs = 0 ; + m_cs = CS_LOW ; m_spi.write(CMD_SBL) ; - m_cs = 1 ; + m_cs = CS_HIGH ; } - + void SPI_MX25R::releaseReadenhaced(void) { - m_cs = 0 ; + m_cs = CS_LOW ; m_spi.write(CMD_RRE) ; - m_cs = 1 ; + m_cs = CS_HIGH ; } - + void SPI_MX25R::noOperation(void) { - m_cs = 0 ; + m_cs = CS_LOW ; m_spi.write(CMD_NOP) ; - m_cs = 1 ; + m_cs = CS_HIGH ; } - + void SPI_MX25R::enterSecureOTP(void) { - m_cs = 0 ; + m_cs = CS_LOW ; m_spi.write(CMD_ENSO) ; - m_cs = 1 ; + m_cs = CS_HIGH ; } void SPI_MX25R::exitSecureOTP(void) { - m_cs = 0 ; + m_cs = CS_LOW ; m_spi.write(CMD_EXSO) ; - m_cs = 1 ; + m_cs = CS_HIGH ; } - + uint8_t SPI_MX25R::readStatus(void) { uint8_t data ; - m_cs = 0 ; + m_cs = CS_LOW ; m_spi.write(CMD_RDSR) ; - data = m_spi.write(CMD_RDSR) ; // dummy - m_spi.write(CMD_RDSR) ; - data = m_spi.write(CMD_RDSR) ; // dummy - m_cs = 1 ; + data = m_spi.write(DUMMY) ; // dummy + m_cs = CS_HIGH ; return( data ) ; - } +} uint32_t SPI_MX25R::readConfig(void) { uint8_t data; uint32_t config32 = 0 ; - m_cs = 0 ; + m_cs = CS_LOW ; 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 ) ; + data= m_spi.write(DUMMY) ; // dumy to get 1st Byte out + config32 = config32 | data ; // put in 32b reg + data= m_spi.write(DUMMY) ; // dummy to get 2nd Byte out + config32 = (config32 << 8) | data ; // shift and put in reg + m_cs = CS_HIGH ; + return( config32 ) ; +} + +uint8_t SPI_MX25R::readSecurity(void) +{ + uint8_t data ; + m_cs = CS_LOW ; + m_spi.write(CMD_RDSCUR) ; // send 2Bh + data = m_spi.write(DUMMY) ; // dummy + m_cs = CS_HIGH ; + return( data ) ; } uint32_t SPI_MX25R::readID(void) { uint8_t data; - uint32_t data32 = 0 ; - m_cs = 0 ; + uint32_t data32 = 0 ; + m_cs = CS_LOW ; 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 ) ; + data= m_spi.write(DUMMY) ; // dumy to get 1st Byte out + data32 = data32 | data ; // put in 32b reg + data= m_spi.write(DUMMY) ; // dummy to get 2nd Byte out + data32 = (data32 << 8) | data ; // shift and put in reg + data= m_spi.write(DUMMY) ; // dummy to get 3rd Byte out + data32 = (data32 << 8) | data ; // shift again and put in reg + m_cs = CS_HIGH ; + return( data32 ) ; } +uint32_t SPI_MX25R::readREMS(void) +{ + uint8_t data; + uint32_t data32 = 0 ; + m_cs = CS_LOW ; + m_spi.write(CMD_REMS) ; // send 90h + m_spi.write(DUMMY) ; // send DUMMY1 + m_spi.write(DUMMY) ; // send DUMMY2 + m_spi.write(0) ; // send address=0x00 to get Manu ID 1st. + data= m_spi.write(DUMMY) ; // dumy to get Manufacturer ID= C2h out + data32 = data32 | data ; // put in 32b reg + data= m_spi.write(DUMMY) ; // dummy to get 2nd Byte = Device ID out + data32 = (data32 << 8) | data ; // shift and put in reg + m_cs = CS_HIGH ; + return( data32 ) ; +} + +uint8_t SPI_MX25R::readRES(void) +{ + uint8_t data; + m_cs = CS_LOW ; + m_spi.write(CMD_RES) ; // send ABh + m_spi.write(DUMMY) ; // send DUMMY1 + m_spi.write(DUMMY) ; // send DUMMY2 + m_spi.write(DUMMY) ; // send DUMMY3 + data= m_spi.write(DUMMY) ; // dumy to get Electronic Sig. out + m_cs = CS_HIGH ; + return( data ) ; +} + void SPI_MX25R::programPage(int addr, uint8_t *data, int numData) { int i ; - m_cs = 0 ; + m_cs = CS_LOW ; 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 @@ -180,18 +187,26 @@ 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 ; + m_cs = CS_HIGH ; // poll in main } - + void SPI_MX25R::writeStatusreg(int addr) // Write SR cmd 01h + 3B data { - m_cs = 0 ; + m_cs = CS_LOW ; 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 ; + m_cs = CS_HIGH ; +} + +void SPI_MX25R::writeSecurityreg(int addr) // WRSCUR cmd 2Fh + 1B data +{ + m_cs = CS_LOW ; + m_spi.write(CMD_WRSCUR) ; // Write SR cmd 01h + m_spi.write(addr & 0xFF) ; + m_cs = CS_HIGH ; } void SPI_MX25R::blockErase(int addr) // 64KB Block Erase @@ -200,91 +215,91 @@ data[0] = (addr >> 16) & 0xFF ; data[1] = (addr >> 8) & 0xFF ; data[2] = (addr & 0xFF) ; - m_cs = 0 ; + m_cs = CS_LOW ; m_spi.write(CMD_BE) ; - for (int i = 0 ; i < 3 ; i++ ) { + for (int i = 0 ; i < 3 ; i++ ) { // Address setting m_spi.write(data[i]) ; } - m_cs = 1 ; + m_cs = CS_HIGH ; // poll in main } - + void SPI_MX25R::blockErase32KB(int addr) // 32KB Block Erase { uint8_t data[3] ; data[0] = (addr >> 16) & 0xFF ; data[1] = (addr >> 8) & 0xFF ; data[2] = (addr & 0xFF) ; - m_cs = 0 ; + m_cs = CS_LOW ; m_spi.write(CMD_32KBE) ; - for (int i = 0 ; i < 3 ; i++ ) { + for (int i = 0 ; i < 3 ; i++ ) { // Address Setting m_spi.write(data[i]) ; } - m_cs = 1 ; + m_cs = CS_HIGH ; // poll in main } - + void SPI_MX25R::sectorErase(int addr) // 4KB Sector Erase { uint8_t data[3] ; data[0] = (addr >> 16) & 0xFF ; data[1] = (addr >> 8) & 0xFF ; data[2] = (addr & 0xFF) ; - m_cs = 0 ; + m_cs = CS_LOW ; m_spi.write(CMD_SE) ; - for (int i = 0 ; i < 3 ; i++ ) { + for (int i = 0 ; i < 3 ; i++ ) { // Address Setting m_spi.write(data[i]) ; } - m_cs = 1 ; + m_cs = CS_HIGH ; // poll in main } - + void SPI_MX25R::chipErase(void) // Chip Erase { - m_cs = 0 ; + m_cs = CS_LOW ; m_spi.write(CMD_CE) ; - m_cs = 1 ; + m_cs = CS_HIGH ; // poll in main } - + uint8_t SPI_MX25R::read8(int addr) // Single Byte Read { uint8_t data ; - m_cs = 0 ; + m_cs = CS_LOW ; 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 - m_cs = 1 ; + data = m_spi.write(DUMMY) ; // write data is dummy + m_cs = CS_HIGH ; return( data ) ; // return 1 byte } - -uint8_t SPI_MX25R::readSFDP(int addr) // Single Byte Read + +uint8_t SPI_MX25R::readSFDP(int addr) // Read SFDP { uint8_t data ; - m_cs = 0 ; + m_cs = CS_LOW ; m_spi.write(CMD_RDSFDP) ; // send cmd 5Ah - m_spi.write((addr >> 16)&0xFF) ; // address[23:16] + 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 ; + m_spi.write(DUMMY) ; // dummy cycle + data = m_spi.write(DUMMY) ; // return 1 byte + m_cs = CS_HIGH ; + return( data ) ; +} + +uint8_t SPI_MX25R::readFREAD(int addr) // x1 Fast Read Data Byte +{ + uint8_t data ; + m_cs = CS_LOW ; + 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(DUMMY) ; // dummy cycle + data = m_spi.write(DUMMY) ; // return 1 byte + m_cs = CS_HIGH ; return( data ) ; } -uint8_t SPI_MX25R::readFREAD(int addr) // Single Byte Read -{ - uint8_t data ; - m_cs = 0 ; - 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( data ) ; -} -
diff -r 8403da5975cb -r f72110475fec SPI_MX25R.h --- a/SPI_MX25R.h Mon Jul 20 20:45:33 2015 +0000 +++ b/SPI_MX25R.h Thu Jul 23 17:11:27 2015 +0000 @@ -1,17 +1,58 @@ #ifndef _SPI_MX25R_H_ #define _SPI_MX25R_H_ - + #include "mbed.h" - + +/** + * Macronix Serial Flash Low Power Memories + * SPI_MX25R Series SPI-Flash Memory + */ +#define CS_LOW 0 // SPI CS# (Chip Select) Setting +#define CS_HIGH 1 // SPI CS# (Chip Select) Setting +#define DUMMY 0x00 // Dummy byte which can be changed to any value /** - * SPI_MX25R SPI-Flash Memory - * Macronix Serial Flash Low Power Memories + * MX25R Series Register Command Table. + * x2 and x4 commands not currently supported with FRDM K64F platform */ - +#define CMD_READ 0x03 // x1 Normal Read Data Byte +#define CMD_FREAD 0x0B // x1 Fast Read Data Byte +#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_PP 0x02 // Page Program +#define CMD_4PP 0x38 // x4 PP +#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_RDSFDP 0x5A // Read SFDP +#define CMD_WREN 0x06 // Write Enable +#define CMD_WRDI 0x04 // Write Disable +#define CMD_RDSR 0x05 // Read Status Register +#define CMD_RDCR 0x15 // Read Configuration Register +#define CMD_WRSR 0x01 // Write Status Register +#define CMD_PESUS 0xB0 // Program/Erase Suspend +#define CMD_PERES 0x30 // Program/Erase Resume +#define CMD_DP 0xB9 // Enter Deep Power Down +#define CMD_SBL 0xC0 // Set Burst Length +#define CMD_RDID 0x9F // Read Manufacturer and JDEC Device ID +#define CMD_REMS 0x90 // Read Electronic Manufacturer and Device ID +#define CMD_RES 0xAB // Read Electronic ID +#define CMD_ENSO 0xB1 // Enter Secure OTP +#define CMD_EXSO 0xC1 // Exit Secure OTP +#define CMD_RDSCUR 0x2B // Read Security Register +#define CMD_WRSCUR 0x2F // Write Security Register +#define CMD_NOP 0x00 // No Operation +#define CMD_RSTEN 0x66 // Reset Enable +#define CMD_RST 0x99 // Reset +#define CMD_RRE 0xFF // Release Read Enhanced Mode + + class SPI_MX25R { public: - /** +/** * Macronix MX25R Low Power and Wide Vcc SPI-Flash Memory Family * * @param SI/SIO0 SPI_MOSI pin @@ -22,7 +63,7 @@ SPI_MX25R(PinName mosi, PinName miso, PinName sclk, PinName cs) ; ~SPI_MX25R() ; - + SPI m_spi; DigitalOut m_cs ; int _mode ; @@ -38,37 +79,40 @@ /// Reset void reset(void) ; - + /// Program or Erase Suspend void pgmersSuspend(void) ; /// Program or Erase Resume void pgmersResume(void) ; - + /// Enter Deep Power Down void deepPowerdown(void) ; - + /// Set Burst Length void setBurstlength(void) ; - + /// Release from Read Enhanced Mode void releaseReadenhaced(void) ; - + /// No Operation void noOperation(void) ; - + /// Enter OTP Area void enterSecureOTP(void) ; /// Exit OTP Area void exitSecureOTP(void) ; - + /// Chip Erase void chipErase(void) ; /// Write Status and Configuration Reg 1 and 2 void writeStatusreg(int addr) ; +/// Write Security Reg + void writeSecurityreg(int addr) ; + /** Page Program * * @param int addr start address @@ -83,31 +127,49 @@ */ void sectorErase(int addr) ; - /** Block Erase +/** Block Erase * * @param int addr specify the sector to be erased */ void blockErase(int addr) ; - /** 32KB Block Erase +/** 32KB Block Erase * * @param int addr specify the sector to be erased */ void blockErase32KB(int addr) ; - /** Read Status Register +/** Read Status Register * * @returns uint8_t status register value */ uint8_t readStatus(void) ; - /** Read ID +/** Read Security Register + * + * @returns uint8_t security register value + */ + uint8_t readSecurity(void) ; + +/** Read Manufacturer and JEDEC Device ID * * @returns uint32_t Manufacturer ID, Mem Type, Device ID */ uint32_t readID(void) ; - /** Read Configuration Register +/** Read Electronic Manufacturer and Device ID + * + * @returns uint32_t Manufacturer ID, Device ID + */ + uint32_t readREMS(void) ; + +/** Read Electronic ID + * + * @returns uint8_t Device ID + */ + uint8_t readRES(void) ; + +/** Read Configuration Register * * @returns uint32_t configuration register value */ @@ -117,6 +179,6 @@ uint8_t read8(int addr) ; void write8(int addr, uint8_t data) ; private: - + } ; #endif // _SPI_MX25R_H_ \ No newline at end of file