Jerry Bradshaw
/
mbed-os-test
ddd
Embed:
(wiki syntax)
Show/hide line numbers
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 Tue Jul 12 2022 21:12:44 by 1.7.2