lib : https://developer.mbed.org/users/DimiterK/code/W25Q64FVSSIG/ I try a little change code.

Dependents:   hexi_flash_mem

Fork of W25Q64FVSSIG by Dimiter K

Committer:
i_am_kitsune
Date:
Fri Sep 08 05:51:40 2017 +0000
Revision:
1:259668edf734
Parent:
0:b71060e03299
Hexiwear flash memory ; W25Q64FV; 20170908;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
DimiterK 0:b71060e03299 1 #include "W25Q64FV.h"
DimiterK 0:b71060e03299 2
DimiterK 0:b71060e03299 3 W25Q64FV::W25Q64FV(PinName mosi, PinName miso, PinName sclk, PinName cs, int frequency)
DimiterK 0:b71060e03299 4 {
DimiterK 0:b71060e03299 5
DimiterK 0:b71060e03299 6 this->cs = new DigitalOut(cs);
DimiterK 0:b71060e03299 7 this->cs->write(true);
DimiterK 0:b71060e03299 8 this->frequency = frequency;
DimiterK 0:b71060e03299 9
DimiterK 0:b71060e03299 10 spi = new SPI(mosi, miso, sclk);
DimiterK 0:b71060e03299 11 spi->format(8, 0);
DimiterK 0:b71060e03299 12 spi->frequency(frequency);
DimiterK 0:b71060e03299 13 }
DimiterK 0:b71060e03299 14
DimiterK 0:b71060e03299 15 W25Q64FV::~W25Q64FV()
DimiterK 0:b71060e03299 16 {
DimiterK 0:b71060e03299 17 delete spi;
DimiterK 0:b71060e03299 18 delete cs;
DimiterK 0:b71060e03299 19 }
DimiterK 0:b71060e03299 20
DimiterK 0:b71060e03299 21 uint16_t W25Q64FV::Id()
DimiterK 0:b71060e03299 22 {
DimiterK 0:b71060e03299 23 cs->write(0);
DimiterK 0:b71060e03299 24 spi->write(CMD_MANU_ID);
DimiterK 0:b71060e03299 25 spi->write(0);
DimiterK 0:b71060e03299 26 spi->write(0);
DimiterK 0:b71060e03299 27 spi->write(0);
DimiterK 0:b71060e03299 28 unsigned id = (spi->write(0) << 8) | spi->write(0);
DimiterK 0:b71060e03299 29 cs->write(1);
DimiterK 0:b71060e03299 30 return id;
DimiterK 0:b71060e03299 31 }
DimiterK 0:b71060e03299 32
i_am_kitsune 1:259668edf734 33 void W25Q64FV::W25Q64_readManufacturer(uint8_t* d) {
i_am_kitsune 1:259668edf734 34
i_am_kitsune 1:259668edf734 35 cs -> write(0);
i_am_kitsune 1:259668edf734 36 spi->write(CMD_MANU_ID);
i_am_kitsune 1:259668edf734 37 for (uint8_t i =0; i <5; i++) {
i_am_kitsune 1:259668edf734 38 d[i] = spi->write(0);
i_am_kitsune 1:259668edf734 39 }
i_am_kitsune 1:259668edf734 40 cs -> write(1);
i_am_kitsune 1:259668edf734 41 }
i_am_kitsune 1:259668edf734 42
DimiterK 0:b71060e03299 43 uint32_t W25Q64FV::JEDECId()
DimiterK 0:b71060e03299 44 {
DimiterK 0:b71060e03299 45 cs->write(0);
DimiterK 0:b71060e03299 46 spi->write(CMD_JEDEC_ID);
DimiterK 0:b71060e03299 47 unsigned id = (spi->write(0) << 16) | (spi->write(0) << 8) | spi->write(0);
DimiterK 0:b71060e03299 48 cs->write(1);
DimiterK 0:b71060e03299 49 return id;
DimiterK 0:b71060e03299 50 }
DimiterK 0:b71060e03299 51
DimiterK 0:b71060e03299 52 void W25Q64FV::writeEnable(void)
DimiterK 0:b71060e03299 53 {
DimiterK 0:b71060e03299 54 cs->write(0);
DimiterK 0:b71060e03299 55 spi->write(CMD_WREN);
DimiterK 0:b71060e03299 56 cs->write(1);
DimiterK 0:b71060e03299 57 }
DimiterK 0:b71060e03299 58
DimiterK 0:b71060e03299 59 void W25Q64FV::writeDisable(void)
DimiterK 0:b71060e03299 60 {
DimiterK 0:b71060e03299 61 cs->write(0);
DimiterK 0:b71060e03299 62 spi->write(CMD_WR_DISABLE) ;
DimiterK 0:b71060e03299 63 cs->write(1);
DimiterK 0:b71060e03299 64 }
DimiterK 0:b71060e03299 65
DimiterK 0:b71060e03299 66 uint8_t W25Q64FV::readStatus(void)
DimiterK 0:b71060e03299 67 {
DimiterK 0:b71060e03299 68 uint8_t data ;
DimiterK 0:b71060e03299 69 cs->write(0);
DimiterK 0:b71060e03299 70 spi->write(CMD_RDSR1) ;
DimiterK 0:b71060e03299 71 data = spi->write(DUMMY) ; // dummy
DimiterK 0:b71060e03299 72 cs->write(1);
DimiterK 0:b71060e03299 73 return( data ) ;
DimiterK 0:b71060e03299 74 }
DimiterK 0:b71060e03299 75
DimiterK 0:b71060e03299 76 void W25Q64FV::writeStatusReg(int addr) // Write SR cmd 01h + 3B data
DimiterK 0:b71060e03299 77 {
DimiterK 0:b71060e03299 78 cs->write(0);
DimiterK 0:b71060e03299 79 spi->write(CMD_WRSR1) ; // Write SR cmd 01h
DimiterK 0:b71060e03299 80 spi->write((addr >> 16)&0xFF) ; // address
DimiterK 0:b71060e03299 81 spi->write((addr >> 8)&0xFF) ;
DimiterK 0:b71060e03299 82 spi->write(addr & 0xFF) ;
DimiterK 0:b71060e03299 83 cs->write(1);
DimiterK 0:b71060e03299 84 }
DimiterK 0:b71060e03299 85
DimiterK 0:b71060e03299 86 void W25Q64FV::writeSecurityReg(int addr) // WRSCUR cmd 2Fh + 1B data
DimiterK 0:b71060e03299 87 {
DimiterK 0:b71060e03299 88 cs->write(0);
DimiterK 0:b71060e03299 89 // spi->write(CMD_WRSCUR) ; // Write SR cmd 01h
DimiterK 0:b71060e03299 90 spi->write(addr & 0xFF) ;
DimiterK 0:b71060e03299 91 cs->write(1);
DimiterK 0:b71060e03299 92 }
DimiterK 0:b71060e03299 93
DimiterK 0:b71060e03299 94
DimiterK 0:b71060e03299 95 uint8_t W25Q64FV::readByte(int addr) // Single Byte Read
DimiterK 0:b71060e03299 96 {
DimiterK 0:b71060e03299 97 uint8_t data ;
DimiterK 0:b71060e03299 98 cs->write(0);
DimiterK 0:b71060e03299 99 spi->write(CMD_READ_DATA) ; // send 03h
DimiterK 0:b71060e03299 100 spi->write((addr >> 16)&0xFF) ;
DimiterK 0:b71060e03299 101 spi->write((addr >> 8)&0xFF) ;
DimiterK 0:b71060e03299 102 spi->write(addr & 0xFF) ;
DimiterK 0:b71060e03299 103 data = spi->write(DUMMY) ; // write data is dummy
DimiterK 0:b71060e03299 104 cs->write(1);
DimiterK 0:b71060e03299 105 return( data ) ; // return 1 byte
DimiterK 0:b71060e03299 106 }
DimiterK 0:b71060e03299 107
DimiterK 0:b71060e03299 108 bool W25Q64FV::read(uint32_t addr, uint8_t* dst, uint32_t len)
DimiterK 0:b71060e03299 109 {
DimiterK 0:b71060e03299 110 cs->write(0);
DimiterK 0:b71060e03299 111 spi->write(0x03);
DimiterK 0:b71060e03299 112 spi->write((addr >> 16) & 0xff);
DimiterK 0:b71060e03299 113 spi->write((addr >> 8) & 0xff);
DimiterK 0:b71060e03299 114 spi->write(addr & 0xff);
DimiterK 0:b71060e03299 115 for (uint32_t i=0; i<len; ++i)
DimiterK 0:b71060e03299 116 dst[i] = spi->write(0);
DimiterK 0:b71060e03299 117 cs->write(1);
DimiterK 0:b71060e03299 118
DimiterK 0:b71060e03299 119 return true;
DimiterK 0:b71060e03299 120 }
DimiterK 0:b71060e03299 121
DimiterK 0:b71060e03299 122 void W25Q64FV::hsread(uint32_t addr, uint8_t* dst, uint32_t len, int frequency)
DimiterK 0:b71060e03299 123 {
DimiterK 0:b71060e03299 124 int save_frequency = this->frequency;
DimiterK 0:b71060e03299 125 spi->frequency(frequency);
DimiterK 0:b71060e03299 126 cs->write(0);
DimiterK 0:b71060e03299 127 spi->write(0x0B);
DimiterK 0:b71060e03299 128 spi->write((addr >> 16) & 0xff);
DimiterK 0:b71060e03299 129 spi->write((addr >> 8) & 0xff);
DimiterK 0:b71060e03299 130 spi->write(addr & 0xff);
DimiterK 0:b71060e03299 131 spi->write(0); // dummy
DimiterK 0:b71060e03299 132 for (uint32_t i=0; i<len; ++i)
DimiterK 0:b71060e03299 133 dst[i] = spi->write(0);
DimiterK 0:b71060e03299 134 cs->write(1);
DimiterK 0:b71060e03299 135 spi->frequency(save_frequency);
DimiterK 0:b71060e03299 136 }
DimiterK 0:b71060e03299 137
DimiterK 0:b71060e03299 138 uint8_t W25Q64FV::readSFDP(int addr) // Read SFDP
DimiterK 0:b71060e03299 139 {
DimiterK 0:b71060e03299 140 uint8_t data ;
DimiterK 0:b71060e03299 141 cs->write(0);
DimiterK 0:b71060e03299 142 spi->write(CMD_READ_SFDP) ; // send cmd 5Ah
DimiterK 0:b71060e03299 143 spi->write((addr >> 16)&0xFF) ; // address[23:16]
DimiterK 0:b71060e03299 144 spi->write((addr >> 8)&0xFF) ; // address[15:8]
DimiterK 0:b71060e03299 145 spi->write(addr & 0xFF) ; // address[7:0]
DimiterK 0:b71060e03299 146 spi->write(DUMMY) ; // dummy cycle
DimiterK 0:b71060e03299 147 data = spi->write(DUMMY) ; // return 1 byte
DimiterK 0:b71060e03299 148 cs->write(1);
DimiterK 0:b71060e03299 149 return( data ) ;
DimiterK 0:b71060e03299 150 }
DimiterK 0:b71060e03299 151
DimiterK 0:b71060e03299 152 uint8_t W25Q64FV::wait_while_busy(void)
DimiterK 0:b71060e03299 153 {
DimiterK 0:b71060e03299 154 uint8_t temp = 0;
DimiterK 0:b71060e03299 155 cs->write(0); //Enable device
DimiterK 0:b71060e03299 156 spi->write(CMD_RDSR1); //Send RDSR command
DimiterK 0:b71060e03299 157 temp = spi->write(DUMMY);
DimiterK 0:b71060e03299 158 cs->write(1); //Disable
DimiterK 0:b71060e03299 159 if (temp & 0x01) return 1;
DimiterK 0:b71060e03299 160 else return 0;
DimiterK 0:b71060e03299 161 }
DimiterK 0:b71060e03299 162
DimiterK 0:b71060e03299 163
DimiterK 0:b71060e03299 164 bool W25Q64FV::page_program(uint32_t addr, uint8_t* write_buffer, uint8_t len)
DimiterK 0:b71060e03299 165 {
DimiterK 0:b71060e03299 166 // no point in writing FF as an empty sector already has those
DimiterK 0:b71060e03299 167 // (and if not empty, write won't succeed)
DimiterK 0:b71060e03299 168 bool skipped = false;
DimiterK 0:b71060e03299 169 while (len > 0 && *write_buffer == 0xFF)
DimiterK 0:b71060e03299 170 {
DimiterK 0:b71060e03299 171 ++write_buffer;
DimiterK 0:b71060e03299 172 --len;
DimiterK 0:b71060e03299 173 ++addr;
DimiterK 0:b71060e03299 174 skipped = true;
DimiterK 0:b71060e03299 175 }
DimiterK 0:b71060e03299 176 if (len == 0 && skipped)
DimiterK 0:b71060e03299 177 return true; // special case when succeeds when nothing to do
DimiterK 0:b71060e03299 178
DimiterK 0:b71060e03299 179 if (len < 1 || len > 256)
DimiterK 0:b71060e03299 180 return false;
DimiterK 0:b71060e03299 181
DimiterK 0:b71060e03299 182 // write enable
DimiterK 0:b71060e03299 183 writeEnable();
DimiterK 0:b71060e03299 184
DimiterK 0:b71060e03299 185 cs->write(0);
DimiterK 0:b71060e03299 186 spi->write(0x02);
DimiterK 0:b71060e03299 187 spi->write((uint8_t)(addr >> 16));
DimiterK 0:b71060e03299 188 spi->write((uint8_t)(addr >> 8));
DimiterK 0:b71060e03299 189 spi->write((uint8_t)addr);
DimiterK 0:b71060e03299 190 for (uint16_t i=0; i<len; ++i)
DimiterK 0:b71060e03299 191 spi->write(write_buffer[i]);
DimiterK 0:b71060e03299 192 cs->write(1);
DimiterK 0:b71060e03299 193 wait_while_busy();
DimiterK 0:b71060e03299 194
DimiterK 0:b71060e03299 195 return true;
DimiterK 0:b71060e03299 196 }
DimiterK 0:b71060e03299 197
DimiterK 0:b71060e03299 198 void W25Q64FV::sector_erase_4k(uint32_t addr)
DimiterK 0:b71060e03299 199 {
DimiterK 0:b71060e03299 200 cs->write(0);
DimiterK 0:b71060e03299 201 spi->write(CMD_ERASE_SECTOR);
DimiterK 0:b71060e03299 202 spi->write((uint8_t)(addr >> 16));
DimiterK 0:b71060e03299 203 spi->write((uint8_t)(addr >> 8));
DimiterK 0:b71060e03299 204 spi->write((uint8_t)addr);
DimiterK 0:b71060e03299 205 cs->write(1);
DimiterK 0:b71060e03299 206 wait_while_busy();
DimiterK 0:b71060e03299 207 }
DimiterK 0:b71060e03299 208
DimiterK 0:b71060e03299 209 void W25Q64FV::block_erase_32k(uint32_t addr)
DimiterK 0:b71060e03299 210 {
DimiterK 0:b71060e03299 211 cs->write(0);
DimiterK 0:b71060e03299 212 spi->write(CMD_ERASE_BLOCK32);
DimiterK 0:b71060e03299 213 spi->write((uint8_t)(addr >> 16));
DimiterK 0:b71060e03299 214 spi->write((uint8_t)(addr >> 8));
DimiterK 0:b71060e03299 215 spi->write((uint8_t)addr);
DimiterK 0:b71060e03299 216 cs->write(1);
DimiterK 0:b71060e03299 217 wait_while_busy();
DimiterK 0:b71060e03299 218 }
DimiterK 0:b71060e03299 219
DimiterK 0:b71060e03299 220 void W25Q64FV::block_erase_64k(uint32_t addr)
DimiterK 0:b71060e03299 221 {
DimiterK 0:b71060e03299 222 cs->write(0);
DimiterK 0:b71060e03299 223 spi->write(CMD_ERASE_BLOCK64);
DimiterK 0:b71060e03299 224 spi->write((uint8_t)(addr >> 16));
DimiterK 0:b71060e03299 225 spi->write((uint8_t)(addr >> 8));
DimiterK 0:b71060e03299 226 spi->write((uint8_t)addr);
DimiterK 0:b71060e03299 227 cs->write(1);
DimiterK 0:b71060e03299 228 wait_while_busy();
DimiterK 0:b71060e03299 229 }
DimiterK 0:b71060e03299 230
DimiterK 0:b71060e03299 231 void W25Q64FV::chip_erase()
DimiterK 0:b71060e03299 232 {
DimiterK 0:b71060e03299 233 cs->write(0);
DimiterK 0:b71060e03299 234 spi->write(CMD_ERASE_CHIP);
DimiterK 0:b71060e03299 235 cs->write(1);
DimiterK 0:b71060e03299 236 wait_while_busy();
DimiterK 0:b71060e03299 237 }
DimiterK 0:b71060e03299 238
DimiterK 0:b71060e03299 239
DimiterK 0:b71060e03299 240
DimiterK 0:b71060e03299 241
DimiterK 0:b71060e03299 242
DimiterK 0:b71060e03299 243
DimiterK 0:b71060e03299 244 void W25Q64FV::writeArray(uint32_t address, uint8_t* pData, uint32_t arrayLength)
DimiterK 0:b71060e03299 245 {
DimiterK 0:b71060e03299 246 unsigned int i = 0;
DimiterK 0:b71060e03299 247 cs->write(0); //Enable device
DimiterK 0:b71060e03299 248 spi->write(CMD_WREN); //Send WREN command
DimiterK 0:b71060e03299 249 cs->write(1); //Disable device
DimiterK 0:b71060e03299 250
DimiterK 0:b71060e03299 251 cs->write(0); //Enable device
DimiterK 0:b71060e03299 252 spi->write(CMD_PAGEPROG); //Send Byte Program command
DimiterK 0:b71060e03299 253 spi->write((uint8_t)(address >> 16) & 0xFF);
DimiterK 0:b71060e03299 254 spi->write((uint8_t)(address >> 8) & 0xFF);
DimiterK 0:b71060e03299 255 spi->write(0x00);
DimiterK 0:b71060e03299 256
DimiterK 0:b71060e03299 257 for (i=0;i<arrayLength;i++)
DimiterK 0:b71060e03299 258 {
DimiterK 0:b71060e03299 259 spi->write(pData[i]); //Send byte to be programmed
DimiterK 0:b71060e03299 260 }
DimiterK 0:b71060e03299 261 cs->write(1); //Disable device
DimiterK 0:b71060e03299 262
DimiterK 0:b71060e03299 263 //Wait Busy
DimiterK 0:b71060e03299 264 while ((readStatus() & 0x01) == 0x01) //Waste time until not busy
DimiterK 0:b71060e03299 265 {
DimiterK 0:b71060e03299 266 }
DimiterK 0:b71060e03299 267 }
DimiterK 0:b71060e03299 268
DimiterK 0:b71060e03299 269
DimiterK 0:b71060e03299 270 void W25Q64FV::readArray(uint32_t address, uint8_t* pData, uint32_t arrayLength)
DimiterK 0:b71060e03299 271 {
DimiterK 0:b71060e03299 272 unsigned int i = 0;
DimiterK 0:b71060e03299 273
DimiterK 0:b71060e03299 274 cs->write(0); //Enable device
DimiterK 0:b71060e03299 275 spi->write(CMD_READ_DATA); //Read command
DimiterK 0:b71060e03299 276 spi->write((uint8_t)(address >> 16));
DimiterK 0:b71060e03299 277 spi->write((uint8_t)(address >> 8));
DimiterK 0:b71060e03299 278 spi->write((uint8_t) address);
DimiterK 0:b71060e03299 279
DimiterK 0:b71060e03299 280 for (i = 0; i <arrayLength; i++) //Read until no_bytes is reached
DimiterK 0:b71060e03299 281 {
DimiterK 0:b71060e03299 282 pData[i] = spi->write(DUMMY); //Receive bytes
DimiterK 0:b71060e03299 283 }
DimiterK 0:b71060e03299 284 cs->write(1); //Disable device
DimiterK 0:b71060e03299 285
DimiterK 0:b71060e03299 286 //Wait Busy
DimiterK 0:b71060e03299 287 while (readStatus() & 0x01) //Waste time until not busy
DimiterK 0:b71060e03299 288 {
DimiterK 0:b71060e03299 289 }
DimiterK 0:b71060e03299 290 }
DimiterK 0:b71060e03299 291
DimiterK 0:b71060e03299 292
DimiterK 0:b71060e03299 293