Release 1.01

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SPI_MX25R.cpp Source File

SPI_MX25R.cpp

Go to the documentation of this file.
00001 /**************************************************************************//**
00002  * @file     SPI_MX25R.cpp
00003  * @brief    Base class for wrapping the interface with the SPI NOR Flash.
00004  * @version: V1.0
00005  * @date:    9/17/2019
00006  *
00007  * @note
00008  * SPI_MX25R Series SPI-Flash Memory
00009  * Macronix Low Power Serial NOR Flash
00010  * (x2, and x4 I/O modes not implemented)
00011  *
00012  *
00013  * @note
00014  * Copyright (C) 2019 E3 Design. All rights reserved.
00015  *
00016  * @par
00017  * E3 Designers LLC is supplying this software for use with Cortex-M3 LPC1768
00018  * processor based microcontroller for the ESCM 2000 Monitor and Display.  
00019  *  *
00020  * @par
00021  * THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
00022  * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
00023  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
00024  * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
00025  * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
00026  *
00027  ******************************************************************************/
00028 
00029  
00030 #include "SPI_MX25R.h"
00031 
00032  
00033 SPI_MX25R::SPI_MX25R(PinName mosi, PinName miso, PinName sclk, PinName cs) :
00034         m_spi(mosi, miso, sclk), m_cs(cs) { }
00035  
00036 SPI_MX25R::~SPI_MX25R() { }
00037  
00038 void SPI_MX25R::writeEnable(void)
00039 {
00040     m_cs = CS_LOW ;
00041     m_spi.write(CMD_WREN) ;
00042     m_cs = CS_HIGH ;
00043 }
00044  
00045 void SPI_MX25R::writeDisable(void)
00046 {
00047     m_cs = CS_LOW ;
00048     m_spi.write(CMD_WRDI) ;
00049     m_cs = CS_HIGH ;
00050 }    
00051  
00052 void SPI_MX25R::resetEnable(void)
00053 {
00054     m_cs = CS_LOW ;
00055     m_spi.write(CMD_RSTEN) ;
00056     m_cs = CS_HIGH ;
00057 }  
00058  
00059 void SPI_MX25R::reset(void)
00060 {
00061     m_cs = CS_LOW ;
00062     m_spi.write(CMD_RST) ;
00063     m_cs = CS_HIGH ;
00064 } 
00065  
00066 void SPI_MX25R::pgmersSuspend(void)
00067 {
00068     m_cs = CS_LOW ;
00069     m_spi.write(CMD_PESUS) ;
00070     m_cs = CS_HIGH ;
00071 } 
00072  
00073 void SPI_MX25R::pgmersResume(void)
00074 {
00075     m_cs = CS_LOW ;
00076     m_spi.write(CMD_PERES) ;
00077     m_cs = CS_HIGH ;
00078 } 
00079  
00080 void SPI_MX25R::deepPowerdown(void)
00081 {
00082     m_cs = CS_LOW ;
00083     m_spi.write(CMD_DP) ;
00084     m_cs = CS_HIGH ;
00085 } 
00086  
00087 void SPI_MX25R::setBurstlength(void)
00088 {
00089     m_cs = CS_LOW ;
00090     m_spi.write(CMD_SBL) ;
00091     m_cs = CS_HIGH ;
00092 } 
00093  
00094 void SPI_MX25R::releaseReadenhaced(void)
00095 {
00096     m_cs = CS_LOW ;
00097     m_spi.write(CMD_RRE) ;
00098     m_cs = CS_HIGH ;
00099 } 
00100  
00101 void SPI_MX25R::noOperation(void)
00102 {
00103     m_cs = CS_LOW ;
00104     m_spi.write(CMD_NOP) ;
00105     m_cs = CS_HIGH ;
00106 } 
00107  
00108 void SPI_MX25R::enterSecureOTP(void)
00109 {
00110     m_cs = CS_LOW ;
00111     m_spi.write(CMD_ENSO) ;
00112     m_cs = CS_HIGH ;
00113 }
00114  
00115 void SPI_MX25R::exitSecureOTP(void)
00116 {
00117     m_cs = CS_LOW ;
00118     m_spi.write(CMD_EXSO) ;
00119     m_cs = CS_HIGH ;
00120 } 
00121  
00122 uint8_t SPI_MX25R::readStatus(void)
00123 {   
00124     uint8_t data ;
00125     m_cs = CS_LOW ;
00126     m_spi.write(CMD_RDSR) ;
00127     data = m_spi.write(DUMMY) ;                     // dummy
00128     m_cs = CS_HIGH ;
00129     return( data ) ;
00130 }
00131   
00132 uint32_t SPI_MX25R::readConfig(void)
00133 {   
00134     uint8_t data;
00135     uint32_t config32 = 0 ;
00136     m_cs = CS_LOW ;
00137     m_spi.write(CMD_RDCR) ;                         // send 15h
00138     data= m_spi.write(DUMMY)  ;                     // dumy to get 1st Byte out
00139     config32 = config32 | data ;                    // put in 32b reg
00140     data= m_spi.write(DUMMY) ;                      // dummy to get 2nd Byte out
00141     config32 = (config32 << 8) | data ;             // shift and put in reg
00142     m_cs = CS_HIGH ;
00143     return( config32 ) ;  
00144 }
00145 
00146 uint8_t SPI_MX25R::readSecurity(void)
00147 {   
00148     uint8_t data ;
00149     m_cs = CS_LOW ;
00150     m_spi.write(CMD_RDSCUR) ;                       // send 2Bh
00151     data = m_spi.write(DUMMY) ;                     // dummy
00152     m_cs = CS_HIGH ;
00153     return( data ) ;
00154 }
00155   
00156 uint32_t SPI_MX25R::readID(void)
00157 {   
00158     uint8_t data;
00159     uint32_t data32 = 0 ;
00160     m_cs = CS_LOW ;
00161     m_spi.write(CMD_RDID) ;                         // send 9Fh
00162     data= m_spi.write(DUMMY)  ;                     // dumy to get 1st Byte out
00163     data32 = data32 | data ;                        // put in 32b reg
00164     data= m_spi.write(DUMMY) ;                      // dummy to get 2nd Byte out
00165     data32 = (data32 << 8) | data ;                 // shift and put in reg
00166     data= m_spi.write(DUMMY)  ;                     // dummy to get 3rd Byte out
00167     data32 = (data32 << 8) | data ;                 // shift again and put in reg
00168     m_cs = CS_HIGH ;
00169     return( data32 ) ;  
00170 }
00171 
00172 uint32_t SPI_MX25R::readREMS(void)
00173 {   
00174     uint8_t data;
00175     uint32_t data32 = 0 ;
00176     m_cs = CS_LOW ;
00177     m_spi.write(CMD_REMS) ;                         // send 90h
00178     m_spi.write(DUMMY) ;                            // send DUMMY1
00179     m_spi.write(DUMMY) ;                            // send DUMMY2
00180     m_spi.write(0) ;                                // send address=0x00 to get Manu ID 1st.
00181     data= m_spi.write(DUMMY)  ;                     // dumy to get Manufacturer ID= C2h out
00182     data32 = data32 | data ;                        // put in 32b reg
00183     data= m_spi.write(DUMMY) ;                      // dummy to get 2nd Byte = Device ID out
00184     data32 = (data32 << 8) | data ;                 // shift and put in reg
00185     m_cs = CS_HIGH ;
00186     return( data32 ) ;  
00187 }
00188 
00189 uint8_t SPI_MX25R::readRES(void)
00190 {   
00191     uint8_t data;
00192     m_cs = CS_LOW ;
00193     m_spi.write(CMD_RES) ;                          // send ABh
00194     m_spi.write(DUMMY) ;                            // send DUMMY1
00195     m_spi.write(DUMMY) ;                            // send DUMMY2
00196     m_spi.write(DUMMY) ;                            // send DUMMY3
00197     data= m_spi.write(DUMMY)  ;                     // dumy to get Electronic Sig. out
00198     m_cs = CS_HIGH ;
00199     return( data ) ;  
00200 }
00201  
00202 void SPI_MX25R::programPage(int addr, uint8_t *data, int numData)
00203 {
00204     int i ;
00205     m_cs = CS_LOW ;
00206     m_spi.write(CMD_PP) ;                           // Program Page 02h
00207     m_spi.write((addr >> 16)&0xFF) ;                // adr 23:16
00208     m_spi.write((addr >>  8)&0xFF) ;                // adr 15:8
00209     m_spi.write(addr & 0xFF) ;                      // adr 7:0
00210     for (i = 0 ; i < numData ; i++ ) {              // data = 00, 01, 02, .. to FEh, FFh = all 256 Bytes in 1 page. 
00211         m_spi.write(data[i]) ;
00212     }
00213     m_cs = CS_HIGH ;
00214     // poll in main
00215 }
00216  
00217 void SPI_MX25R::writeStatusreg(int addr)            // Write SR cmd 01h + 3B data
00218 {   
00219     m_cs = CS_LOW ;
00220     m_spi.write(CMD_WRSR) ;                         // Write SR cmd 01h
00221     m_spi.write((addr >> 16)&0xFF) ;                // address
00222     m_spi.write((addr >>  8)&0xFF) ;
00223     m_spi.write(addr & 0xFF) ;
00224     m_cs = CS_HIGH ;
00225 }
00226 
00227 void SPI_MX25R::writeSecurityreg(int addr)          // WRSCUR cmd 2Fh + 1B data
00228 {   
00229     m_cs = CS_LOW ;
00230     m_spi.write(CMD_WRSCUR) ;                         // Write SR cmd 01h
00231     m_spi.write(addr & 0xFF) ;
00232     m_cs = CS_HIGH ;
00233 }
00234 
00235 void SPI_MX25R::blockErase(int addr)                // 64KB Block Erase
00236 {
00237     uint8_t data[3] ;
00238     data[0] = (addr >> 16) & 0xFF ;
00239     data[1] = (addr >> 8) & 0xFF ;
00240     data[2] = (addr & 0xFF) ;
00241     m_cs = CS_LOW ;
00242     m_spi.write(CMD_BE) ;
00243     for (int i = 0 ; i < 3 ; i++ ) {                // Address setting
00244         m_spi.write(data[i]) ;
00245     }
00246     m_cs = CS_HIGH ;
00247     // poll in main
00248 }
00249  
00250 void SPI_MX25R::blockErase32KB(int addr)            // 32KB Block Erase
00251 {
00252     uint8_t data[3] ;
00253     data[0] = (addr >> 16) & 0xFF ;
00254     data[1] = (addr >> 8) & 0xFF ;
00255     data[2] = (addr & 0xFF) ;
00256     m_cs = CS_LOW ;
00257     m_spi.write(CMD_32KBE) ;
00258     for (int i = 0 ; i < 3 ; i++ ) {                // Address Setting
00259         m_spi.write(data[i]) ;
00260     }
00261     m_cs = CS_HIGH ;
00262     // poll in main
00263 }
00264  
00265 void SPI_MX25R::sectorErase(int addr)               //  4KB Sector Erase
00266 {
00267     uint8_t data[3] ;
00268     data[0] = (addr >> 16) & 0xFF ;
00269     data[1] = (addr >> 8) & 0xFF ;
00270     data[2] = (addr & 0xFF) ;
00271     m_cs = CS_LOW ;
00272     m_spi.write(CMD_SE) ;
00273     for (int i = 0 ; i < 3 ; i++ ) {                // Address Setting
00274         m_spi.write(data[i]) ;
00275     }
00276     m_cs = CS_HIGH ;
00277     // poll in main
00278 }
00279  
00280 void SPI_MX25R::chipErase(void)                     // Chip Erase
00281 {
00282     m_cs = CS_LOW ;
00283     m_spi.write(CMD_CE) ;
00284     m_cs = CS_HIGH ;
00285     // poll in main
00286 }
00287  
00288 uint8_t SPI_MX25R::read8(int addr)                  // Single Byte Read
00289 {
00290     uint8_t data ;    
00291     m_cs = CS_LOW ;
00292     m_spi.write(CMD_READ) ;                         // send 03h
00293     m_spi.write((addr >> 16)&0xFF) ;
00294     m_spi.write((addr >>  8)&0xFF) ;
00295     m_spi.write(addr & 0xFF) ;
00296     data = m_spi.write(DUMMY) ;                     // write data is dummy 
00297     m_cs = CS_HIGH ;
00298     return( data ) ;                                // return 1 byte 
00299 }
00300  
00301 uint8_t SPI_MX25R::readSFDP(int addr)               // Read SFDP
00302 {
00303     uint8_t data ;    
00304     m_cs = CS_LOW ;
00305     m_spi.write(CMD_RDSFDP) ;                       // send cmd 5Ah
00306     m_spi.write((addr >> 16)&0xFF) ;                // address[23:16]
00307     m_spi.write((addr >>  8)&0xFF) ;                // address[15:8]
00308     m_spi.write(addr & 0xFF) ;                      // address[7:0]
00309     m_spi.write(DUMMY) ;                            // dummy cycle
00310     data = m_spi.write(DUMMY) ;                     // return 1 byte 
00311     m_cs = CS_HIGH ;
00312     return( data ) ;
00313 }
00314  
00315 uint8_t SPI_MX25R::readFREAD(int addr)              // x1 Fast Read Data Byte
00316 {
00317     uint8_t data ;    
00318     m_cs = CS_LOW ;
00319     m_spi.write(CMD_FREAD) ;                        // send cmd 0BH
00320     m_spi.write((addr >> 16)&0xFF) ;                // address[23:16]
00321     m_spi.write((addr >>  8)&0xFF) ;                // address[15:8]
00322     m_spi.write(addr & 0xFF) ;                      // address[7:0]
00323     m_spi.write(DUMMY) ;                            // dummy cycle
00324     data = m_spi.write(DUMMY) ;                     // return 1 byte 
00325     m_cs = CS_HIGH ;
00326     return( data ) ;
00327 }
00328