Arkadi Rafalovich / SPI_MX25R

Dependents:   Demo_MX25Rxx35F_Serial_NOR_Flash_Testbench mbed-lorawan-pulga mbed-lorawan-pulga-serial_rx mbed-lorawan-pulga-gps-added_shared

Fork of SPI_MX25R by alec cohen

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SPI_MX25R.cpp Source File

SPI_MX25R.cpp

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