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:
- 0:a16ad6f5c788
- Child:
- 1:8403da5975cb
diff -r 000000000000 -r a16ad6f5c788 SPI_MX25R.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SPI_MX25R.cpp Wed Jul 08 20:59:40 2015 +0000 @@ -0,0 +1,229 @@ +/* + * SPI_MX25R SPI-Flash Memory + * Macronix Low Power Serial Flash Memory + * Standard Pin-out + */ + +#include "SPI_MX25R.h" + +#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 + + +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_spi.write(CMD_WREN) ; + m_cs = 1 ; +} + +void SPI_MX25R::writeDisable(void) +{ + m_cs = 0 ; + m_spi.write(CMD_WRDI) ; + m_cs = 1 ; +} + +void SPI_MX25R::resetEnable(void) +{ + m_cs = 0 ; + m_spi.write(CMD_RSTEN) ; + m_cs = 1 ; +} + +void SPI_MX25R::reset(void) +{ + m_cs = 0 ; + m_spi.write(CMD_RST) ; + 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 + m_cs = 1 ; + return( data ) ; + } + +uint32_t SPI_MX25R::readConfig(void) +{ + 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_cs = 1 ; + return( config32 ) ; +} + +uint32_t SPI_MX25R::readID(void) +{ + 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_cs = 1 ; + return( data32 ) ; +} + +void SPI_MX25R::programPage(int addr, uint8_t *data, int numData) +{ + 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(data[i]) ; + } + m_cs = 1 ; + // poll in main +} + +void SPI_MX25R::hpmode(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(0x02) ; // CR2 = 02h, To set Config Reg 2 <1> = 1 to enter High Performance mode + 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) +{ + uint8_t data[3] ; + data[0] = (addr >> 16) & 0xFF ; + data[1] = (addr >> 8) & 0xFF ; + data[2] = (addr & 0xFF) ; + m_cs = 0 ; + m_spi.write(CMD_BE) ; + for (int i = 0 ; i < 3 ; i++ ) { + m_spi.write(data[i]) ; + } + m_cs = 1 ; + // poll in main +} + +void SPI_MX25R::blockErase32KB(int addr) +{ + uint8_t data[3] ; + data[0] = (addr >> 16) & 0xFF ; + data[1] = (addr >> 8) & 0xFF ; + data[2] = (addr & 0xFF) ; + m_cs = 0 ; + m_spi.write(CMD_32KBE) ; + for (int i = 0 ; i < 3 ; i++ ) { + m_spi.write(data[i]) ; + } + m_cs = 1 ; + // poll in main +} + +void SPI_MX25R::sectorErase(int addr) +{ + uint8_t data[3] ; + data[0] = (addr >> 16) & 0xFF ; + data[1] = (addr >> 8) & 0xFF ; + data[2] = (addr & 0xFF) ; + m_cs = 0 ; + m_spi.write(CMD_SE) ; + for (int i = 0 ; i < 3 ; i++ ) { + m_spi.write(data[i]) ; + } + m_cs = 1 ; + // poll in main +} +void SPI_MX25R::chipErase(void) +{ + m_cs = 0 ; + m_spi.write(CMD_CE) ; + m_cs = 1 ; + // poll in main +} + +uint8_t SPI_MX25R::read8(int addr) +{ + uint8_t data ; + m_cs = 0 ; + m_spi.write(CMD_READ) ; + 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 ; + return( data ) ; +} + +uint32_t SPI_MX25R::rd32(int addr) +{ + uint8_t data; + uint32_t data32 = 0 ; + 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_cs = 1 ; + return( data32 ) ; +}