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.
S25FS512.cpp
00001 00002 /******************************************************************************* 00003 * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. 00004 * 00005 * Permission is hereby granted, free of charge, to any person obtaining a 00006 * copy of this software and associated documentation files (the "Software"), 00007 * to deal in the Software without restriction, including without limitation 00008 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00009 * and/or sell copies of the Software, and to permit persons to whom the 00010 * Software is furnished to do so, subject to the following conditions: 00011 * 00012 * The above copyright notice and this permission notice shall be included 00013 * in all copies or substantial portions of the Software. 00014 * 00015 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00016 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00017 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 00018 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES 00019 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 00020 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 00021 * OTHER DEALINGS IN THE SOFTWARE. 00022 * 00023 * Except as contained in this notice, the name of Maxim Integrated 00024 * Products, Inc. shall not be used except as stated in the Maxim Integrated 00025 * Products, Inc. Branding Policy. 00026 * 00027 * The mere transfer of this software does not imply any licenses 00028 * of trade secrets, proprietary technology, copyrights, patents, 00029 * trademarks, maskwork rights, or any other form of intellectual 00030 * property whatsoever. Maxim Integrated Products, Inc. retains all 00031 * ownership rights. 00032 ******************************************************************************* 00033 */ 00034 00035 #include "mbed.h" 00036 #include "S25FS512.h" 00037 #include "QuadSpiInterface.h" 00038 //#include "DebugRoutines.h" 00039 00040 //****************************************************************************** 00041 S25FS512::S25FS512(QuadSpiInterface *_quadSpiInterface) { 00042 this->quadSpiInterface = _quadSpiInterface; 00043 } 00044 00045 //****************************************************************************** 00046 S25FS512::~S25FS512() 00047 { 00048 } 00049 00050 //****************************************************************************** 00051 void S25FS512::init(void) { 00052 setQuadMode(); 00053 } 00054 00055 //****************************************************************************** 00056 int S25FS512::wren4Wire(void) { 00057 uint8_t cmdArray[8]; 00058 // Send WREN 00059 cmdArray[0] = 0x06; 00060 //wait_ms(1); 00061 return reg_write_read_multiple_4Wire(cmdArray, 1, flashBuffer, 1); 00062 } 00063 00064 //****************************************************************************** 00065 uint8_t S25FS512::wren(void) { 00066 uint8_t cmdArray[8]; 00067 // Send WREN 00068 cmdArray[0] = 0x06; 00069 //wait_ms(1); 00070 return reg_write_read_multiple_quad(cmdArray, 1, flashBuffer, 0); 00071 } 00072 00073 //****************************************************************************** 00074 int8_t S25FS512::reg_write_read_multiple_quad_last(uint8_t *bufferOut, uint8_t numberOut, uint8_t *bufferIn, uint8_t numberIn, uint8_t last) { 00075 int32_t success = 0; 00076 //if (spiSlave.port != 1) { 00077 // while (1); 00078 //} 00079 // success = SPI_Transmit(&spiSlave, dataIn, numberIn, dataOut, numberOut, MXC_E_SPI_UNIT_BYTES, MXC_E_SPI_MODE_QUAD, 0, last);//MXC_E_SPI_MODE_QUAD 00080 00081 success = quadSpiInterface->SPI_Transmit( 00082 bufferOut, numberOut, 00083 bufferIn, numberIn, 00084 (int)last); 00085 00086 if (success != 0) return -1; 00087 return 0; 00088 } 00089 00090 //****************************************************************************** 00091 int8_t S25FS512::reg_write_read_multiple_4Wire(uint8_t *bufferOut, 00092 uint8_t numberOut, 00093 uint8_t *bufferIn, 00094 uint8_t numberIn) { 00095 int32_t success = 0; 00096 success = quadSpiInterface->SPI_Transmit4Wire(bufferOut, numberOut, bufferIn, 00097 numberIn, (int)1); 00098 00099 if (success != 0) return -1; 00100 return 0; 00101 } 00102 00103 //****************************************************************************** 00104 int8_t S25FS512::reg_write_read_multiple_quad(uint8_t *bufferOut, uint8_t numberOut, uint8_t *bufferIn, uint8_t numberIn) { 00105 int8_t ret; 00106 ret = reg_write_read_multiple_quad_last(bufferOut,numberOut,bufferIn,numberIn,1); 00107 return ret; 00108 } 00109 00110 //****************************************************************************** 00111 void S25FS512::readID(uint8_t *id) { 00112 uint8_t cmd = 0x9F; 00113 reg_write_read_multiple_quad(&cmd, 1, id, 4); 00114 } 00115 00116 //****************************************************************************** 00117 int8_t S25FS512::writeAnyRegister(uint32_t address, uint8_t data) { 00118 uint8_t cmdArray[5]; 00119 cmdArray[0] = 0x71; 00120 cmdArray[1] = (address >> 16) & 0xFF; 00121 cmdArray[2] = (address >> 8) & 0xFF; 00122 cmdArray[3] = (address >> 0) & 0xFF; 00123 cmdArray[4] = data; 00124 return reg_write_read_multiple_quad(cmdArray,5,flashBuffer,0); 00125 } 00126 00127 //****************************************************************************** 00128 int8_t S25FS512::writeAnyRegister4Wire(uint32_t address, uint8_t data) { 00129 uint8_t cmdArray[5]; 00130 cmdArray[0] = 0x71; 00131 cmdArray[1] = (address >> 16) & 0xFF; 00132 cmdArray[2] = (address >> 8) & 0xFF; 00133 cmdArray[3] = (address >> 0) & 0xFF; 00134 cmdArray[4] = data; 00135 return reg_write_read_multiple_4Wire(cmdArray, 5, flashBuffer, 5); 00136 } 00137 00138 //****************************************************************************** 00139 int8_t S25FS512::writeRegisters(void) { 00140 uint8_t cmdArray[3]; 00141 wait_ms(1); 00142 cmdArray[0] = 0x01; 00143 cmdArray[1] = 0x00; 00144 cmdArray[2] = 0x02; // set Quad to 1 00145 reg_write_read_multiple_quad(cmdArray,3,flashBuffer,0); 00146 return 0; 00147 } 00148 00149 //****************************************************************************** 00150 int8_t S25FS512::readAnyRegister(uint32_t address, uint8_t *data, uint32_t length) { 00151 uint8_t cmdArray[4]; 00152 cmdArray[0] = 0x65; 00153 cmdArray[1] = (address >> 16) & 0xFF; 00154 cmdArray[2] = (address >> 8) & 0xFF; 00155 cmdArray[3] = (address >> 0) & 0xFF; 00156 return reg_write_read_multiple_quad(cmdArray,4,data,length); 00157 } 00158 00159 //****************************************************************************** 00160 int8_t S25FS512::bulkErase(void) { 00161 uint8_t cmdArray[1]; 00162 cmdArray[0] = 0x60; 00163 return reg_write_read_multiple_quad(cmdArray,1,flashBuffer,0); 00164 } 00165 00166 //****************************************************************************** 00167 int8_t S25FS512::pageProgram(uint32_t address, uint8_t *buffer) { 00168 uint32_t i; 00169 uint8_t cmdArray[6 + 256]; 00170 uint8_t *ptr; 00171 00172 //for (i = 0; i < 256; i++) { 00173 // dataArray[i] = i; 00174 //} 00175 cmdArray[0] = 0x12; //0x02; //0x71; 00176 cmdArray[1] = (address >> 24) & 0xFF; 00177 cmdArray[2] = (address >> 16) & 0xFF; 00178 cmdArray[3] = (address >> 8) & 0xFF; 00179 cmdArray[4] = (address >> 0) & 0xFF; 00180 for (i = 0; i < 256; i++) { 00181 cmdArray[5 + i] = buffer[i]; 00182 } 00183 // reg_write_read_multiple_quad(cmdArray,256 + 4,flashBuffer,256 + 4); 00184 00185 ptr = cmdArray; 00186 reg_write_read_multiple_quad_last(ptr,5 + 64,flashBuffer,0,0); 00187 //wait_ms(1); 00188 ptr += (5 + 64); 00189 reg_write_read_multiple_quad_last(ptr,64,flashBuffer,0,0); 00190 //wait_ms(1); 00191 ptr += 64; 00192 reg_write_read_multiple_quad_last(ptr,64,flashBuffer,0,0); 00193 //wait_ms(1); 00194 ptr += 64; 00195 reg_write_read_multiple_quad_last(ptr,64,flashBuffer,0,1); 00196 //wait_ms(1); 00197 return 0; 00198 } 00199 00200 // 00201 // read page 0 and assure that it is empty 00202 // 00203 void S25FS512::test_verifyPage0Empty(uint8_t *ptr, int currentPage, int pagesWrittenTo) { 00204 uint8_t data[512]; 00205 bool pageEmpty; 00206 readPages_Helper(0, 0, data, 0); 00207 pageEmpty = isPageEmpty(data); 00208 if (pageEmpty == false) { 00209 //PRINTD_2("ERROR: Page 0 is no longer empty!!!!!!!\r\n"); 00210 //PRINTD_2("Page 0->\r\n"); 00211 //DebugRoutines::dumpBuffer(data, 256); 00212 //PRINTD_2("Page 0->\r\n"); 00213 readPages_Helper(0, 0, data, 0); 00214 //DebugRoutines::dumpBuffer(data, 256); 00215 //PRINTD_2("Page 0->\r\n"); 00216 readPages_Helper(0, 0, data, 0); 00217 //DebugRoutines::dumpBuffer(data, 256); 00218 if (ptr != NULL) { 00219 //PRINTD_2("currentPage=%d ", (int)currentPage); 00220 //PRINTD_2("pagesWrittenTo=%d\r\n", (int)pagesWrittenTo); 00221 //PRINTD_2("Writing page data->\r\n"); 00222 //DebugRoutines::dumpBuffer(ptr, 256); 00223 } 00224 while (1) ; 00225 } 00226 } 00227 00228 //****************************************************************************** 00229 int8_t S25FS512::quadIoRead_Pages(uint32_t address, uint8_t *buffer, uint32_t numberOfPages) { 00230 uint8_t cmdArray[5]; 00231 uint8_t *ptr; 00232 uint8_t last; 00233 uint32_t i; 00234 cmdArray[0] = 0xEC; //0xEB; 00235 cmdArray[1] = (address >> 24) & 0xFF; 00236 cmdArray[2] = (address >> 16) & 0xFF; 00237 cmdArray[3] = (address >> 8) & 0xFF; 00238 cmdArray[4] = (address >> 0) & 0xFF; 00239 //reg_write_read_multiple_quad(cmdArray,4,flashBuffer,32); 00240 /* last = 0; 00241 num = 0; 00242 inc = 32; 00243 while (num < number) {*/ 00244 ptr = buffer; 00245 last = 0; 00246 // only send the command 00247 reg_write_read_multiple_quad_last(cmdArray, 5, ptr, 0, 0); 00248 //wait_ms(1); 00249 reg_write_read_multiple_quad_last(cmdArray, 0, ptr, 5, 0); 00250 //wait_ms(1); 00251 for (i = 0; i < numberOfPages; i++) { 00252 reg_write_read_multiple_quad_last(cmdArray,0,ptr,64, 0); 00253 //wait_ms(1); 00254 ptr += 64; 00255 reg_write_read_multiple_quad_last(cmdArray,0,ptr,64, 0); 00256 //wait_ms(1); 00257 ptr += 64; 00258 reg_write_read_multiple_quad_last(cmdArray,0,ptr,64, 0); 00259 //wait_ms(1); 00260 ptr += 64; 00261 // check if this is the last page 00262 if ((i + 1) == numberOfPages) { 00263 last = 1; 00264 } 00265 reg_write_read_multiple_quad_last(cmdArray,0,ptr,64, last); 00266 //wait_ms(1); 00267 ptr += 64; 00268 } 00269 return 0; 00270 } 00271 00272 //****************************************************************************** 00273 int8_t S25FS512::quadIoRead_PartialPage(uint32_t address, uint8_t *buffer, uint32_t numberOfBytesInPage) { 00274 uint8_t cmdArray[5]; 00275 uint8_t *ptr; 00276 uint8_t last; 00277 uint32_t packetSize; 00278 uint32_t xferCount; 00279 cmdArray[0] = 0xEC; //0xEB; 00280 cmdArray[1] = (address >> 24) & 0xFF; 00281 cmdArray[2] = (address >> 16) & 0xFF; 00282 cmdArray[3] = (address >> 8) & 0xFF; 00283 cmdArray[4] = (address >> 0) & 0xFF; 00284 //reg_write_read_multiple_quad(cmdArray,4,flashBuffer,32); 00285 ptr = buffer; 00286 last = 0; 00287 // only send the command 00288 reg_write_read_multiple_quad_last(cmdArray, 5, ptr, 0, 0); 00289 //wait_ms(1); 00290 reg_write_read_multiple_quad_last(cmdArray, 0, ptr, 5, 0); 00291 //wait_ms(1); 00292 00293 xferCount = 0; 00294 do { 00295 packetSize = 64; 00296 if ((xferCount + packetSize) > numberOfBytesInPage) { 00297 packetSize = numberOfBytesInPage; 00298 last = 1; 00299 } 00300 reg_write_read_multiple_quad_last(cmdArray,0,ptr,packetSize, 0); 00301 xferCount += packetSize; 00302 ptr += packetSize; 00303 } while (last != 1); 00304 return 0; 00305 } 00306 00307 //****************************************************************************** 00308 int8_t S25FS512::checkBusy(void) { 00309 uint8_t cmdArray[5]; 00310 cmdArray[0] = 0x05; 00311 reg_write_read_multiple_quad(cmdArray,1,flashBuffer,2); 00312 return flashBuffer[1] & 0x1; 00313 } 00314 00315 //****************************************************************************** 00316 void S25FS512::waitTillNotBusy(void) { 00317 while (checkBusy() == 1) { } 00318 } 00319 00320 //****************************************************************************** 00321 int8_t S25FS512::sectorErase(uint32_t address) { 00322 uint8_t cmdArray[5]; 00323 cmdArray[0] = 0xDC; //0xD8; 00324 cmdArray[1] = (address >> 24) & 0xFF; 00325 cmdArray[2] = (address >> 16) & 0xFF; 00326 cmdArray[3] = (address >> 8) & 0xFF; 00327 cmdArray[4] = (address >> 0) & 0xFF; 00328 return reg_write_read_multiple_quad(cmdArray,5,flashBuffer,0); 00329 } 00330 00331 //****************************************************************************** 00332 int8_t S25FS512::parameterSectorErase(uint32_t address) { 00333 uint8_t cmdArray[5]; 00334 cmdArray[0] = 0x21; //0x20 (P4E), 0x21 (4P4E) 00335 cmdArray[1] = (address >> 24) & 0xFF; 00336 cmdArray[2] = (address >> 16) & 0xFF; 00337 cmdArray[3] = (address >> 8) & 0xFF; 00338 cmdArray[4] = (address >> 0) & 0xFF; 00339 reg_write_read_multiple_quad(cmdArray,5,flashBuffer,0); 00340 return 0; 00341 } 00342 00343 //****************************************************************************** 00344 int8_t S25FS512::readIdentification(uint8_t *dataArray, uint8_t length) { 00345 // 4QIOR = 0x9F 00346 uint8_t cmdArray[1]; 00347 cmdArray[0] = 0x9F; // read ID command 00348 return reg_write_read_multiple_quad(cmdArray,1,dataArray,length); 00349 } 00350 00351 //****************************************************************************** 00352 uint8_t S25FS512::reset(void) { 00353 uint8_t cmdArray[8]; 00354 wait_ms(1); 00355 cmdArray[0] = 0x66; 00356 reg_write_read_multiple_quad(cmdArray,1,flashBuffer,0); 00357 wait_ms(1); 00358 cmdArray[0] = 0x99; 00359 reg_write_read_multiple_quad(cmdArray,1,flashBuffer,0); 00360 return 0; 00361 } 00362 00363 //****************************************************************************** 00364 uint8_t S25FS512::enableHWReset(void) { 00365 uint8_t data[8]; 00366 wait_ms(1); 00367 // CR2V Configuration Register-2 Volatile 00368 // bit 5 00369 readAnyRegister(0x00800003,data, 8); 00370 writeAnyRegister(0x00800003,0x64); 00371 return 0; 00372 } 00373 00374 //****************************************************************************** 00375 uint8_t S25FS512::detect(void) { 00376 uint8_t array[8]; 00377 uint8_t array2[8]; 00378 00379 // Send WREN 00380 wren(); 00381 // Send WREN 00382 wren(); 00383 // delay 00384 wait_ms(1); 00385 // Put into quad mode 00386 //setQuadMode(); 00387 00388 // Send WDIS 00389 // array[0] = 0x04; 00390 // test_reg_write_multiple_4wire(array,1); 00391 00392 // Send WREN 00393 wren(); 00394 // delay 00395 wait_ms(1); 00396 00397 // Send write any register cmd 00398 writeAnyRegister(0x0003, 0x48); 00399 /* 00400 // 00401 // try reading the ID by using 4 wire spi for the command and quad for reading 00402 // 00403 00404 // send read id cmd 00405 array[0] = 0x9F; 00406 test_reg_write_multiple_4wire(array,1); 00407 // send read id via quad 00408 test_reg_read_multiple_quad(array,7); 00409 */ 00410 // delay 00411 wait_ms(1); 00412 array[0] = 0x9F; // read ID command 00413 reg_write_read_multiple_quad(array,1,array2,7); 00414 00415 /* 00416 //uint8_t val[5]; 00417 uint32_t result; 00418 test_reg_write(0x9F); 00419 test_reg_read2(0x9F,&result); 00420 test_reg_read3(0x9F,&result); 00421 */ 00422 return 0; 00423 } 00424 00425 //****************************************************************************** 00426 int S25FS512::setQuadMode(void) { 00427 wait_ms(1); 00428 wren4Wire(); 00429 wait_ms(1); 00430 writeAnyRegister4Wire(0x800002, 0x02); // set Quad = 1 00431 wait_ms(1); 00432 wren4Wire(); 00433 wait_ms(1); 00434 writeAnyRegister4Wire(0x800003, 0x48); // set 8 latency, set QPI 4-4-4 00435 return 0; 00436 } 00437 00438 //****************************************************************************** 00439 bool S25FS512::isPageEmpty(uint8_t *ptr) { 00440 int i; 00441 for (i = 0; i < 256; i++) { 00442 if (ptr[i] != 0xFF) return false; 00443 } 00444 return true; 00445 } 00446 00447 //****************************************************************************** 00448 int8_t S25FS512::parameterSectorErase_Helper(uint32_t address) { 00449 waitTillNotBusy(); 00450 wait_us(100); 00451 wren(); 00452 wait_us(200); 00453 parameterSectorErase(address); 00454 wait_us(100); 00455 waitTillNotBusy(); 00456 return 0; 00457 } 00458 00459 //****************************************************************************** 00460 int8_t S25FS512::sectorErase_Helper(uint32_t address) { 00461 waitTillNotBusy(); 00462 wait_us(100); 00463 wren(); 00464 wait_us(200); 00465 sectorErase(address); 00466 wait_us(100); 00467 waitTillNotBusy(); 00468 return 0; 00469 } 00470 00471 //****************************************************************************** 00472 int8_t S25FS512::bulkErase_Helper(void) { 00473 waitTillNotBusy(); 00474 wait_us(100); 00475 wren(); 00476 wait_us(100); 00477 bulkErase(); 00478 wait_us(100); 00479 waitTillNotBusy(); 00480 wait_us(100); 00481 return 0; 00482 } 00483 00484 //****************************************************************************** 00485 // write a page worth of data (256 bytes) from buffer, offset defined where in the buffer to begin write 00486 int8_t S25FS512::writePage_Helper(uint32_t pageNumber, uint8_t *buffer, uint32_t offset) { 00487 uint8_t *ptr; 00488 waitTillNotBusy(); 00489 //wait_ms(1); 00490 wren(); 00491 ptr = &buffer[offset]; 00492 //wait_ms(1); 00493 pageProgram(pageNumber << 8,ptr); 00494 wait_us(100); 00495 waitTillNotBusy(); 00496 00497 //wait_ms(1); 00498 return 0; 00499 } 00500 00501 //****************************************************************************** 00502 // read pages from flash into buffer, offset defined where in the buffer use 00503 int8_t S25FS512::readPages_Helper(uint32_t startPageNumber,uint32_t endPageNumber, uint8_t *buffer, uint32_t offset) { 00504 int8_t status = 0; 00505 uint8_t *ptr; 00506 uint32_t page; 00507 ptr = &buffer[offset]; 00508 waitTillNotBusy(); 00509 for (page = startPageNumber; page <= endPageNumber; page++) { 00510 wait_us(100); 00511 status = quadIoRead_Pages((uint32_t)(page << 8), (uint8_t *)ptr, 1); 00512 ptr += 0x100; 00513 } 00514 return status; 00515 } 00516 00517 //****************************************************************************** 00518 int8_t S25FS512::readPartialPage_Helper(uint32_t pageNumber, uint8_t *buffer, uint32_t count) { 00519 int8_t status = 0; 00520 waitTillNotBusy(); 00521 status = quadIoRead_PartialPage((uint32_t)(pageNumber << 8), (uint8_t *)buffer, count); 00522 return status; 00523 } 00524 00525 00526
Generated on Wed Jul 13 2022 02:29:55 by
1.7.2