PARK JAICHANG / W25Q64FVSSIG

Dependents:   hexi_flash_mem

Fork of W25Q64FVSSIG by Dimiter K

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers W25Q64FV.cpp Source File

W25Q64FV.cpp

00001 #include "W25Q64FV.h"
00002 
00003 W25Q64FV::W25Q64FV(PinName mosi, PinName miso, PinName sclk, PinName cs, int frequency)
00004 {
00005 
00006     this->cs = new DigitalOut(cs);    
00007     this->cs->write(true);
00008     this->frequency = frequency;
00009 
00010     spi = new SPI(mosi, miso, sclk);    
00011     spi->format(8, 0);
00012     spi->frequency(frequency);
00013 }
00014 
00015 W25Q64FV::~W25Q64FV()
00016 {
00017     delete spi;
00018     delete cs;
00019 }
00020 
00021 uint16_t W25Q64FV::Id()
00022 {
00023     cs->write(0);
00024     spi->write(CMD_MANU_ID);
00025     spi->write(0);
00026     spi->write(0);
00027     spi->write(0);
00028     unsigned id = (spi->write(0) << 8) | spi->write(0);
00029     cs->write(1);
00030     return id;
00031 }
00032 
00033 void W25Q64FV::W25Q64_readManufacturer(uint8_t* d) {
00034   
00035   cs -> write(0);
00036   spi->write(CMD_MANU_ID);
00037   for (uint8_t i =0; i <5; i++) {
00038     d[i] = spi->write(0);
00039   } 
00040   cs -> write(1);
00041 }
00042 
00043 uint32_t W25Q64FV::JEDECId()
00044 {
00045     cs->write(0);
00046     spi->write(CMD_JEDEC_ID);
00047     unsigned id = (spi->write(0) << 16) | (spi->write(0) << 8) | spi->write(0);
00048     cs->write(1);
00049     return id;
00050 }
00051 
00052 void W25Q64FV::writeEnable(void)
00053 {
00054     cs->write(0);
00055     spi->write(CMD_WREN);
00056     cs->write(1);
00057 }
00058  
00059 void W25Q64FV::writeDisable(void)
00060 {
00061     cs->write(0);
00062     spi->write(CMD_WR_DISABLE) ;
00063     cs->write(1);
00064 }   
00065 
00066 uint8_t W25Q64FV::readStatus(void)
00067 {   
00068     uint8_t data ;
00069     cs->write(0);
00070     spi->write(CMD_RDSR1) ;
00071     data = spi->write(DUMMY) ;                     // dummy
00072     cs->write(1);
00073     return( data ) ;
00074 }
00075 
00076 void W25Q64FV::writeStatusReg(int addr)            // Write SR cmd 01h + 3B data
00077 {   
00078     cs->write(0);
00079     spi->write(CMD_WRSR1) ;                         // Write SR cmd 01h
00080     spi->write((addr >> 16)&0xFF) ;                // address
00081     spi->write((addr >>  8)&0xFF) ;
00082     spi->write(addr & 0xFF) ;
00083     cs->write(1);
00084 }
00085 
00086 void W25Q64FV::writeSecurityReg(int addr)          // WRSCUR cmd 2Fh + 1B data
00087 {   
00088     cs->write(0);
00089    // spi->write(CMD_WRSCUR) ;                         // Write SR cmd 01h
00090     spi->write(addr & 0xFF) ;
00091     cs->write(1);
00092 }
00093 
00094 
00095 uint8_t W25Q64FV::readByte(int addr)                  // Single Byte Read
00096 {
00097     uint8_t data ;    
00098     cs->write(0);
00099     spi->write(CMD_READ_DATA) ;                         // send 03h
00100     spi->write((addr >> 16)&0xFF) ;
00101     spi->write((addr >>  8)&0xFF) ;
00102     spi->write(addr & 0xFF) ;
00103     data = spi->write(DUMMY) ;                     // write data is dummy 
00104     cs->write(1);
00105     return( data ) ;                                // return 1 byte 
00106 }
00107  
00108 bool W25Q64FV::read(uint32_t addr, uint8_t* dst, uint32_t len)
00109 {
00110     cs->write(0);
00111     spi->write(0x03);
00112     spi->write((addr >> 16) & 0xff);
00113     spi->write((addr >> 8) & 0xff);
00114     spi->write(addr & 0xff);
00115     for (uint32_t i=0; i<len; ++i)
00116         dst[i] = spi->write(0);
00117     cs->write(1);
00118     
00119     return true;
00120 }
00121 
00122 void W25Q64FV::hsread(uint32_t addr, uint8_t* dst, uint32_t len, int frequency)
00123 {
00124     int save_frequency = this->frequency;
00125     spi->frequency(frequency);
00126     cs->write(0);
00127     spi->write(0x0B);
00128     spi->write((addr >> 16) & 0xff);
00129     spi->write((addr >> 8) & 0xff);
00130     spi->write(addr & 0xff);
00131     spi->write(0); // dummy
00132     for (uint32_t i=0; i<len; ++i)
00133         dst[i] = spi->write(0);
00134     cs->write(1);
00135     spi->frequency(save_frequency);
00136 }
00137 
00138 uint8_t W25Q64FV::readSFDP(int addr)               // Read SFDP
00139 {
00140     uint8_t data ;    
00141     cs->write(0);
00142     spi->write(CMD_READ_SFDP) ;                       // send cmd 5Ah
00143     spi->write((addr >> 16)&0xFF) ;                // address[23:16]
00144     spi->write((addr >>  8)&0xFF) ;                // address[15:8]
00145     spi->write(addr & 0xFF) ;                      // address[7:0]
00146     spi->write(DUMMY) ;                            // dummy cycle
00147     data = spi->write(DUMMY) ;                     // return 1 byte 
00148     cs->write(1);
00149     return( data ) ;
00150 }
00151 
00152 uint8_t W25Q64FV::wait_while_busy(void)
00153 {
00154     uint8_t temp = 0;
00155     cs->write(0);           //Enable device
00156     spi->write(CMD_RDSR1);   //Send RDSR command
00157     temp = spi->write(DUMMY);
00158     cs->write(1);          //Disable
00159     if (temp & 0x01) return 1;
00160     else return 0;
00161 }
00162 
00163 
00164 bool W25Q64FV::page_program(uint32_t addr, uint8_t* write_buffer, uint8_t len)
00165 {
00166     // no point in writing FF as an empty sector already has those
00167     // (and if not empty, write won't succeed)
00168     bool skipped = false;
00169     while (len > 0 && *write_buffer == 0xFF)
00170     {
00171         ++write_buffer;
00172         --len;
00173         ++addr;
00174         skipped = true;
00175     }
00176     if (len == 0 && skipped)
00177         return true; // special case when succeeds when nothing to do
00178 
00179     if (len < 1 || len > 256)
00180         return false;
00181         
00182     // write enable
00183     writeEnable();
00184 
00185     cs->write(0);
00186     spi->write(0x02);
00187     spi->write((uint8_t)(addr >> 16));
00188     spi->write((uint8_t)(addr >> 8));
00189     spi->write((uint8_t)addr);
00190     for (uint16_t i=0; i<len; ++i)
00191         spi->write(write_buffer[i]);
00192     cs->write(1);
00193     wait_while_busy();
00194     
00195     return true;
00196 }
00197 
00198 void W25Q64FV::sector_erase_4k(uint32_t addr)
00199 {
00200     cs->write(0);
00201     spi->write(CMD_ERASE_SECTOR);
00202     spi->write((uint8_t)(addr >> 16));
00203     spi->write((uint8_t)(addr >> 8));
00204     spi->write((uint8_t)addr);
00205     cs->write(1);
00206     wait_while_busy();
00207 }
00208 
00209 void W25Q64FV::block_erase_32k(uint32_t addr)
00210 {
00211     cs->write(0);
00212     spi->write(CMD_ERASE_BLOCK32);
00213     spi->write((uint8_t)(addr >> 16));
00214     spi->write((uint8_t)(addr >> 8));
00215     spi->write((uint8_t)addr);
00216     cs->write(1);
00217     wait_while_busy();
00218 }    
00219 
00220 void W25Q64FV::block_erase_64k(uint32_t addr)
00221 {
00222     cs->write(0);
00223     spi->write(CMD_ERASE_BLOCK64);
00224     spi->write((uint8_t)(addr >> 16));
00225     spi->write((uint8_t)(addr >> 8));
00226     spi->write((uint8_t)addr);
00227     cs->write(1);
00228     wait_while_busy();
00229 }    
00230 
00231 void W25Q64FV::chip_erase()
00232 {
00233     cs->write(0);
00234     spi->write(CMD_ERASE_CHIP);
00235     cs->write(1);
00236     wait_while_busy();
00237 }
00238 
00239 
00240 
00241 
00242 
00243 
00244 void W25Q64FV::writeArray(uint32_t address, uint8_t* pData, uint32_t arrayLength)
00245 {
00246     unsigned int i = 0;
00247     cs->write(0);                        //Enable device
00248     spi->write(CMD_WREN);                //Send WREN command
00249     cs->write(1);                      //Disable device
00250 
00251     cs->write(0);                        //Enable device
00252     spi->write(CMD_PAGEPROG);            //Send Byte Program command
00253     spi->write((uint8_t)(address >> 16) & 0xFF);
00254     spi->write((uint8_t)(address >>  8) & 0xFF);
00255     spi->write(0x00);
00256 
00257     for (i=0;i<arrayLength;i++)
00258     {
00259         spi->write(pData[i]);            //Send byte to be programmed 
00260     }
00261     cs->write(1);              //Disable device
00262  
00263     //Wait Busy
00264     while ((readStatus() & 0x01) == 0x01) //Waste time until not busy
00265     {
00266     }
00267 }
00268 
00269 
00270 void W25Q64FV::readArray(uint32_t address, uint8_t* pData, uint32_t arrayLength)
00271 {
00272     unsigned int i = 0;
00273 
00274     cs->write(0);                                    //Enable device
00275     spi->write(CMD_READ_DATA);                       //Read command
00276     spi->write((uint8_t)(address >> 16));
00277     spi->write((uint8_t)(address >>  8));
00278     spi->write((uint8_t) address);
00279 
00280     for (i = 0; i <arrayLength; i++)                //Read until no_bytes is reached
00281     {
00282         pData[i] = spi->write(DUMMY);                      //Receive bytes
00283     }
00284     cs->write(1);                                  //Disable device
00285 
00286     //Wait Busy
00287     while (readStatus() & 0x01)      //Waste time until not busy
00288     {
00289     }
00290 }
00291 
00292 
00293