Release 1.01
Embed:
(wiki syntax)
Show/hide line numbers
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
Generated on Wed Jul 20 2022 06:07:03 by 1.7.2