Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-os-test by
S25FS512.cpp
00001 /******************************************************************************* 00002 * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. 00003 * 00004 * Permission is hereby granted, free of charge, to any person obtaining a 00005 * copy of this software and associated documentation files (the "Software"), 00006 * to deal in the Software without restriction, including without limitation 00007 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00008 * and/or sell copies of the Software, and to permit persons to whom the 00009 * Software is furnished to do so, subject to the following conditions: 00010 * 00011 * The above copyright notice and this permission notice shall be included 00012 * in all copies or substantial portions of the Software. 00013 * 00014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00015 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00016 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 00017 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES 00018 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 00019 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 00020 * OTHER DEALINGS IN THE SOFTWARE. 00021 * 00022 * Except as contained in this notice, the name of Maxim Integrated 00023 * Products, Inc. shall not be used except as stated in the Maxim Integrated 00024 * Products, Inc. Branding Policy. 00025 * 00026 * The mere transfer of this software does not imply any licenses 00027 * of trade secrets, proprietary technology, copyrights, patents, 00028 * trademarks, maskwork rights, or any other form of intellectual 00029 * property whatsoever. Maxim Integrated Products, Inc. retains all 00030 * ownership rights. 00031 ******************************************************************************* 00032 */ 00033 00034 // 00035 // Flash Non-Volatile Memory 00036 // U27 S25FS512 00037 // Nimitz SPIM1 00038 // 00039 00040 #include "mbed.h" 00041 #include "S25FS512.h" 00042 #include "QuadSpiInterface.h" 00043 00044 #define IOMUX_IO_ENABLE 1 00045 00046 #define S25FS512_SPI_PORT 1 00047 #define S25FS512_CS_PIN 0 00048 #define S25FS512_CS_POLARITY 0 00049 #define S25FS512_CS_ACTIVITY_DELAY 0 00050 #define S25FS512_CS_INACTIVITY_DELAY 0 00051 #define S25FS512_CLK_HI 4 00052 #define S25FS512_CLK_LOW 4 00053 #define S25FS512_ALT_CLK 0 00054 #define S25FS512_CLK_POLARITY 0 00055 #define S25FS512_CLK_PHASE 0 00056 #define S25FS512_WRITE 1 00057 #define S25FS512_READ 0 00058 00059 #define INT_PORT_B 3 00060 #define INT_PIN_B 6 00061 00062 uint8_t flashBuffer[257 + 10]; 00063 00064 //****************************************************************************** 00065 S25FS512::S25FS512(QuadSpiInterface *_quadSpiInterface) { 00066 this->quadSpiInterface = _quadSpiInterface; 00067 } 00068 00069 //****************************************************************************** 00070 S25FS512::~S25FS512(void) { 00071 } 00072 00073 //****************************************************************************** 00074 int S25FS512::init(void) { 00075 setQuadMode(); 00076 return 0; 00077 } 00078 00079 //****************************************************************************** 00080 int S25FS512::wren4Wire(void) { 00081 uint8_t cmdArray[8]; 00082 // Send WREN 00083 cmdArray[0] = 0x06; 00084 wait_1mS(); 00085 return reg_write_read_multiple_4Wire(cmdArray, 1, flashBuffer, 1); 00086 } 00087 00088 //****************************************************************************** 00089 uint8_t S25FS512::wren(void) { 00090 uint8_t cmdArray[8]; 00091 // Send WREN 00092 cmdArray[0] = 0x06; 00093 wait_1mS(); 00094 return reg_write_read_multiple_quad(cmdArray, 1, flashBuffer, 0); 00095 } 00096 00097 //****************************************************************************** 00098 int8_t S25FS512::reg_write_read_multiple_quad_last(uint8_t *bufferOut, 00099 uint8_t numberOut, 00100 uint8_t *bufferIn, 00101 uint8_t numberIn, 00102 uint8_t last) { 00103 int32_t success = 0; 00104 00105 success = quadSpiInterface->SPI_Transmit( 00106 bufferOut, numberOut, 00107 bufferIn, numberIn, (int)last); 00108 00109 if (success != 0) return -1; 00110 return 0; 00111 } 00112 00113 //****************************************************************************** 00114 int8_t S25FS512::reg_write_read_multiple_4Wire(uint8_t *bufferOut, 00115 uint8_t numberOut, 00116 uint8_t *bufferIn, 00117 uint8_t numberIn) { 00118 int32_t success = 0; 00119 success = quadSpiInterface->SPI_Transmit4Wire(bufferOut, numberOut, bufferIn, 00120 numberIn, (int)1); 00121 00122 if (success != 0) return -1; 00123 return 0; 00124 } 00125 00126 //****************************************************************************** 00127 int8_t S25FS512::reg_write_read_multiple_quad(uint8_t *bufferOut, 00128 uint8_t numberOut, 00129 uint8_t *bufferIn, 00130 uint8_t numberIn) { 00131 int8_t ret; 00132 ret = reg_write_read_multiple_quad_last(bufferOut, numberOut, bufferIn, 00133 numberIn, 1); 00134 return ret; 00135 } 00136 00137 //****************************************************************************** 00138 void S25FS512::readID(uint8_t *id) { 00139 uint8_t cmd = 0x9F; 00140 reg_write_read_multiple_quad(&cmd, 1, id, 4); 00141 } 00142 00143 //****************************************************************************** 00144 int8_t S25FS512::writeAnyRegister(uint32_t address, uint8_t data) { 00145 uint8_t cmdArray[5]; 00146 cmdArray[0] = 0x71; 00147 cmdArray[1] = (address >> 16) & 0xFF; 00148 cmdArray[2] = (address >> 8) & 0xFF; 00149 cmdArray[3] = (address >> 0) & 0xFF; 00150 cmdArray[4] = data; 00151 return reg_write_read_multiple_quad(cmdArray, 5, flashBuffer, 0); 00152 } 00153 00154 int8_t S25FS512::writeAnyRegister4Wire(uint32_t address, uint8_t data) { 00155 uint8_t cmdArray[5]; 00156 cmdArray[0] = 0x71; 00157 cmdArray[1] = (address >> 16) & 0xFF; 00158 cmdArray[2] = (address >> 8) & 0xFF; 00159 cmdArray[3] = (address >> 0) & 0xFF; 00160 cmdArray[4] = data; 00161 return reg_write_read_multiple_4Wire(cmdArray, 5, flashBuffer, 5); 00162 } 00163 00164 //****************************************************************************** 00165 int8_t S25FS512::writeRegisters(void) { 00166 uint8_t cmdArray[3]; 00167 wait_1mS(); 00168 cmdArray[0] = 0x01; 00169 cmdArray[1] = 0x00; 00170 cmdArray[2] = 0x02; // set Quad to 1 00171 reg_write_read_multiple_quad(cmdArray, 3, flashBuffer, 0); 00172 return 0; 00173 } 00174 00175 //****************************************************************************** 00176 int8_t S25FS512::readAnyRegister(uint32_t address, uint8_t *data, 00177 uint32_t length) { 00178 uint8_t cmdArray[4]; 00179 cmdArray[0] = 0x65; 00180 cmdArray[1] = (address >> 16) & 0xFF; 00181 cmdArray[2] = (address >> 8) & 0xFF; 00182 cmdArray[3] = (address >> 0) & 0xFF; 00183 return reg_write_read_multiple_quad(cmdArray, 4, data, length); 00184 } 00185 00186 //****************************************************************************** 00187 int8_t S25FS512::bulkErase(void) { 00188 uint8_t cmdArray[1]; 00189 cmdArray[0] = 0x60; 00190 return reg_write_read_multiple_quad(cmdArray, 1, flashBuffer, 0); 00191 } 00192 00193 //****************************************************************************** 00194 int8_t S25FS512::pageProgram(uint32_t address, uint8_t *buffer) { 00195 uint32_t i; 00196 uint8_t cmdArray[5 + 256]; 00197 uint8_t *ptr; 00198 00199 // for (i = 0; i < 256; i++) { 00200 // dataArray[i] = i; 00201 //} 00202 cmdArray[0] = 0x02; // 0x71; 00203 // cmdArray[1] = (address >> 24) & 0xFF; 00204 cmdArray[1] = (address >> 16) & 0xFF; 00205 cmdArray[2] = (address >> 8) & 0xFF; 00206 cmdArray[3] = (address >> 0) & 0xFF; 00207 for (i = 0; i < 256; i++) { 00208 cmdArray[4 + i] = buffer[i]; 00209 } 00210 // reg_write_read_multiple_quad(cmdArray,256 + 4,flashBuffer,256 + 4); 00211 00212 ptr = cmdArray; 00213 reg_write_read_multiple_quad_last(ptr, 4 + 64, flashBuffer, 0, 0); 00214 wait_1mS(); 00215 ptr += (4 + 64); 00216 reg_write_read_multiple_quad_last(ptr, 64, flashBuffer, 0, 0); 00217 wait_1mS(); 00218 ptr += 64; 00219 reg_write_read_multiple_quad_last(ptr, 64, flashBuffer, 0, 0); 00220 wait_1mS(); 00221 ptr += 64; 00222 reg_write_read_multiple_quad_last(ptr, 64, flashBuffer, 0, 1); 00223 wait_1mS(); 00224 return 0; 00225 } 00226 00227 //****************************************************************************** 00228 int8_t S25FS512::quadIoRead_Pages(uint32_t address, uint8_t *buffer, 00229 uint32_t numberOfPages) { 00230 uint8_t cmdArray[5]; 00231 uint8_t *ptr; 00232 uint8_t last; 00233 uint32_t i; 00234 00235 cmdArray[0] = 0xEB; 00236 cmdArray[1] = (address >> 16) & 0xFF; 00237 cmdArray[2] = (address >> 8) & 0xFF; 00238 cmdArray[3] = (address >> 0) & 0xFF; 00239 ptr = buffer; 00240 last = 0; 00241 // only send the command 00242 reg_write_read_multiple_quad_last(cmdArray, 4, ptr, 0, 0); 00243 wait_1mS(); 00244 reg_write_read_multiple_quad_last(cmdArray, 0, ptr, 5, 0); 00245 wait_1mS(); 00246 for (i = 0; i < numberOfPages; i++) { 00247 reg_write_read_multiple_quad_last(cmdArray, 0, ptr, 64, 0); 00248 wait_1mS(); 00249 ptr += 64; 00250 reg_write_read_multiple_quad_last(cmdArray, 0, ptr, 64, 0); 00251 wait_1mS(); 00252 ptr += 64; 00253 reg_write_read_multiple_quad_last(cmdArray, 0, ptr, 64, 0); 00254 wait_1mS(); 00255 ptr += 64; 00256 // check if this is the last page 00257 if ((i + 1) == numberOfPages) { 00258 last = 1; 00259 } 00260 reg_write_read_multiple_quad_last(cmdArray, 0, ptr, 64, last); 00261 wait_1mS(); 00262 ptr += 64; 00263 } 00264 return 0; 00265 } 00266 00267 //****************************************************************************** 00268 int8_t S25FS512::checkBusy(void) { 00269 uint8_t cmdArray[5]; 00270 cmdArray[0] = 0x05; 00271 reg_write_read_multiple_quad(cmdArray, 1, flashBuffer, 2); 00272 return flashBuffer[1] & 0x1; 00273 } 00274 00275 //****************************************************************************** 00276 void S25FS512::waitTillNotBusy(void) { 00277 while (checkBusy() == 1) { 00278 } 00279 } 00280 00281 //****************************************************************************** 00282 int8_t S25FS512::sectorErase(uint32_t address) { 00283 uint8_t cmdArray[5]; 00284 cmdArray[0] = 0xD8; 00285 cmdArray[1] = (address >> 16) & 0xFF; 00286 cmdArray[2] = (address >> 8) & 0xFF; 00287 cmdArray[3] = (address >> 0) & 0xFF; 00288 return reg_write_read_multiple_quad(cmdArray, 4, flashBuffer, 0); 00289 } 00290 00291 //****************************************************************************** 00292 int8_t S25FS512::parameterSectorErase(uint32_t address) { 00293 uint8_t cmdArray[5]; 00294 cmdArray[0] = 0x20; 00295 cmdArray[1] = (address >> 16) & 0xFF; 00296 cmdArray[2] = (address >> 8) & 0xFF; 00297 cmdArray[3] = (address >> 0) & 0xFF; 00298 reg_write_read_multiple_quad(cmdArray, 4, flashBuffer, 0); 00299 return 0; 00300 } 00301 00302 #define ONE_MS (32768 / 500) 00303 #define ONEHUNDRED_US (32768 / 1000) 00304 #define TEM_MS (32768 / 50) 00305 00306 //****************************************************************************** 00307 void S25FS512::wait_1mS(void) { 00308 wait_ms(1); 00309 } 00310 00311 //****************************************************************************** 00312 void S25FS512::wait_100uS(void) { 00313 wait_us(100); 00314 } 00315 00316 //****************************************************************************** 00317 void S25FS512::wait_10mS(void) { 00318 wait_ms(10); 00319 } 00320 00321 //****************************************************************************** 00322 int8_t S25FS512::readIdentification(uint8_t *dataArray, uint8_t length) { 00323 // 4QIOR = 0x9F 00324 uint8_t cmdArray[1]; 00325 cmdArray[0] = 0x9F; // read ID command 00326 return reg_write_read_multiple_quad(cmdArray, 1, dataArray, length); 00327 } 00328 00329 //****************************************************************************** 00330 uint8_t S25FS512::reset(void) { 00331 uint8_t cmdArray[8]; 00332 wait_1mS(); 00333 cmdArray[0] = 0x66; 00334 reg_write_read_multiple_quad(cmdArray, 1, flashBuffer, 0); 00335 wait_1mS(); 00336 cmdArray[0] = 0x99; 00337 reg_write_read_multiple_quad(cmdArray, 1, flashBuffer, 0); 00338 return 0; 00339 } 00340 00341 //****************************************************************************** 00342 uint8_t S25FS512::enableHWReset(void) { 00343 uint8_t data[8]; 00344 wait_1mS(); 00345 // CR2V Configuration Register-2 Volatile 00346 // bit 5 00347 readAnyRegister(0x00800003, data, 8); 00348 writeAnyRegister(0x00800003, 0x64); 00349 return 0; 00350 } 00351 00352 //****************************************************************************** 00353 uint8_t S25FS512::detect(void) { 00354 uint8_t array[8]; 00355 uint8_t array2[8]; 00356 00357 // Send WREN 00358 wren(); 00359 // Send WREN 00360 wren(); 00361 // delay 00362 wait_1mS(); 00363 // Send WREN 00364 wren(); 00365 // delay 00366 wait_1mS(); 00367 00368 // Send write any register cmd 00369 writeAnyRegister(0x0003, 0x48); 00370 // delay 00371 wait_1mS(); 00372 array[0] = 0x9F; // read ID command 00373 reg_write_read_multiple_quad(array, 1, array2, 7); 00374 return 0; 00375 } 00376 00377 //****************************************************************************** 00378 int S25FS512::setQuadMode(void) { 00379 wait_1mS(); 00380 wren4Wire(); 00381 wait_1mS(); 00382 writeAnyRegister4Wire(0x800002, 0x02); // set Quad = 1 00383 wait_1mS(); 00384 wren4Wire(); 00385 wait_1mS(); 00386 writeAnyRegister4Wire(0x800003, 0x48); // set 8 latency, set QPI 4-4-4 00387 } 00388 00389 //****************************************************************************** 00390 uint32_t S25FS512::isPageEmpty(uint8_t *ptr) { 00391 int i; 00392 for (i = 0; i < 256; i++) { 00393 if (ptr[i] != 0xFF) 00394 return 0; 00395 } 00396 return 1; 00397 } 00398 00399 //****************************************************************************** 00400 int8_t S25FS512::parameterSectorErase_Helper(uint32_t address) { 00401 waitTillNotBusy(); 00402 wait_100uS(); 00403 wren(); 00404 wait_100uS(); 00405 parameterSectorErase(address); 00406 wait_100uS(); 00407 waitTillNotBusy(); 00408 wait_100uS(); 00409 return 0; 00410 } 00411 00412 //****************************************************************************** 00413 int8_t S25FS512::sectorErase_Helper(uint32_t address) { 00414 waitTillNotBusy(); 00415 wait_100uS(); 00416 wren(); 00417 wait_100uS(); 00418 if (address < 0x8000) { 00419 parameterSectorErase(address); 00420 } else { 00421 sectorErase(address); 00422 } 00423 wait_100uS(); 00424 waitTillNotBusy(); 00425 wait_100uS(); 00426 return 0; 00427 } 00428 00429 //****************************************************************************** 00430 int8_t S25FS512::bulkErase_Helper(void) { 00431 waitTillNotBusy(); 00432 wait_100uS(); 00433 wren(); 00434 wait_100uS(); 00435 bulkErase(); 00436 wait_100uS(); 00437 waitTillNotBusy(); 00438 wait_100uS(); 00439 return 0; 00440 } 00441 00442 //****************************************************************************** 00443 // write a page worth of data (256 bytes) from buffer, offset defined where in 00444 // the buffer to begin write 00445 int8_t S25FS512::writePage_Helper(uint32_t pageNumber, uint8_t *buffer, 00446 uint32_t offset) { 00447 uint8_t *ptr; 00448 waitTillNotBusy(); 00449 wait_1mS(); 00450 wren(); 00451 ptr = &buffer[offset]; 00452 wait_1mS(); 00453 pageProgram(pageNumber << 8, ptr); 00454 wait_1mS(); 00455 return 0; 00456 } 00457 00458 //****************************************************************************** 00459 // read pages from flash into buffer, offset defined where in the buffer use 00460 int8_t S25FS512::readPages_Helper(uint32_t startPageNumber, 00461 uint32_t endPageNumber, uint8_t *buffer, 00462 uint32_t offset) { 00463 uint8_t *ptr; 00464 uint32_t page; 00465 ptr = &buffer[offset]; 00466 for (page = startPageNumber; page <= endPageNumber; page++) { 00467 wait_100uS(); 00468 quadIoRead_Pages((uint32_t)(page << 8), (uint8_t *)ptr, 1); 00469 ptr += 0x100; 00470 } 00471 return 0; 00472 }
Generated on Wed Jul 13 2022 17:00:35 by
1.7.2
