Firmware enhancements for HSP_RPC_GUI 3.0.1

Dependencies:   USBDevice

Fork of HSP_RPC_GUI by Maxim Integrated

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers S25FS512.cpp Source File

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