MAX30001-MAX32630FTHR SYS EvKit

Dependencies:   USBDevice max32630fthr

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers S25FS512.cpp Source File

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 }
00473