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.
Fork of W25Q64FVSSIG by
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
Generated on Fri Jul 15 2022 19:23:23 by
1.7.2
