Shows how to use a display, the onboard SD Card and the onboard SPI Flash. Requires a display module with direct Arduino pinning
Dependencies: DmTftLibrary SDFileSystem mbed
W25Q16BV.cpp@6:0f69891b105e, 2015-01-22 (annotated)
- Committer:
- displaymodule
- Date:
- Thu Jan 22 05:54:22 2015 +0000
- Revision:
- 6:0f69891b105e
- Parent:
- 0:3ecd25651727
Add DM_TFT43_108, DM_TFT50_111 based on new lib drv: DmTftRa8875
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
displaymodule | 0:3ecd25651727 | 1 | // W25Q16BV.cpp |
displaymodule | 0:3ecd25651727 | 2 | |
displaymodule | 0:3ecd25651727 | 3 | #include"W25Q16BV.h" |
displaymodule | 0:3ecd25651727 | 4 | |
displaymodule | 0:3ecd25651727 | 5 | // CONSTRUCTOR |
displaymodule | 0:3ecd25651727 | 6 | W25Q16BV::W25Q16BV(PinName mosi, PinName miso, PinName sclk, PinName cs) : _spi(mosi, miso, sclk), _cs(cs) { |
displaymodule | 0:3ecd25651727 | 7 | _spi.format(SPI_NBIT, SPI_MODE); |
displaymodule | 0:3ecd25651727 | 8 | _spi.frequency(SPI_FREQ); |
displaymodule | 0:3ecd25651727 | 9 | chipDisable(); |
displaymodule | 0:3ecd25651727 | 10 | |
displaymodule | 0:3ecd25651727 | 11 | exitDeepPowerDown(); |
displaymodule | 0:3ecd25651727 | 12 | // The SPI Flash cannot safely be accessed the first 1-10 ms after power ON |
displaymodule | 0:3ecd25651727 | 13 | // wait_us(WAIT_US_TPUW); |
displaymodule | 0:3ecd25651727 | 14 | } |
displaymodule | 0:3ecd25651727 | 15 | |
displaymodule | 0:3ecd25651727 | 16 | |
displaymodule | 0:3ecd25651727 | 17 | // READING |
displaymodule | 0:3ecd25651727 | 18 | int W25Q16BV::readByte(int addr) { |
displaymodule | 0:3ecd25651727 | 19 | chipEnable(); |
displaymodule | 0:3ecd25651727 | 20 | _spi.write(R_INST); |
displaymodule | 0:3ecd25651727 | 21 | _spi.write((addr >> 16) & 0xff); |
displaymodule | 0:3ecd25651727 | 22 | _spi.write((addr >> 8) & 0xff); |
displaymodule | 0:3ecd25651727 | 23 | _spi.write((addr ) & 0xff); |
displaymodule | 0:3ecd25651727 | 24 | int response = _spi.write(DUMMY_ADDR); |
displaymodule | 0:3ecd25651727 | 25 | chipDisable(); |
displaymodule | 0:3ecd25651727 | 26 | return response; |
displaymodule | 0:3ecd25651727 | 27 | } |
displaymodule | 0:3ecd25651727 | 28 | int W25Q16BV::readByte(int a2, int a1, int a0) { |
displaymodule | 0:3ecd25651727 | 29 | chipEnable(); |
displaymodule | 0:3ecd25651727 | 30 | _spi.write(R_INST); |
displaymodule | 0:3ecd25651727 | 31 | _spi.write(a2); |
displaymodule | 0:3ecd25651727 | 32 | _spi.write(a1); |
displaymodule | 0:3ecd25651727 | 33 | _spi.write(a0); |
displaymodule | 0:3ecd25651727 | 34 | int response = _spi.write(DUMMY_ADDR); |
displaymodule | 0:3ecd25651727 | 35 | chipDisable(); |
displaymodule | 0:3ecd25651727 | 36 | return response; |
displaymodule | 0:3ecd25651727 | 37 | } |
displaymodule | 0:3ecd25651727 | 38 | void W25Q16BV::readStream(int addr, char* buf, int count) { |
displaymodule | 0:3ecd25651727 | 39 | if (count < 1) |
displaymodule | 0:3ecd25651727 | 40 | return; |
displaymodule | 0:3ecd25651727 | 41 | chipEnable(); |
displaymodule | 0:3ecd25651727 | 42 | _spi.write(R_INST); |
displaymodule | 0:3ecd25651727 | 43 | _spi.write((addr >> 16) & 0xff); |
displaymodule | 0:3ecd25651727 | 44 | _spi.write((addr >> 8) & 0xff); |
displaymodule | 0:3ecd25651727 | 45 | _spi.write((addr ) & 0xff); |
displaymodule | 0:3ecd25651727 | 46 | for (int i = 0; i < count; i++) |
displaymodule | 0:3ecd25651727 | 47 | buf[i] = _spi.write(DUMMY_ADDR); |
displaymodule | 0:3ecd25651727 | 48 | chipDisable(); |
displaymodule | 0:3ecd25651727 | 49 | } |
displaymodule | 0:3ecd25651727 | 50 | void W25Q16BV::readJEDEC(uint8_t* manId, uint8_t* memType, uint8_t* cap) |
displaymodule | 0:3ecd25651727 | 51 | { |
displaymodule | 0:3ecd25651727 | 52 | chipEnable(); |
displaymodule | 0:3ecd25651727 | 53 | _spi.write(JDEC_INST); |
displaymodule | 0:3ecd25651727 | 54 | *manId = _spi.write(DUMMY_ADDR); |
displaymodule | 0:3ecd25651727 | 55 | *memType = _spi.write(DUMMY_ADDR); |
displaymodule | 0:3ecd25651727 | 56 | *cap = _spi.write(DUMMY_ADDR); |
displaymodule | 0:3ecd25651727 | 57 | chipDisable(); |
displaymodule | 0:3ecd25651727 | 58 | } |
displaymodule | 0:3ecd25651727 | 59 | uint8_t W25Q16BV::readStatus1() |
displaymodule | 0:3ecd25651727 | 60 | { |
displaymodule | 0:3ecd25651727 | 61 | uint8_t status; |
displaymodule | 0:3ecd25651727 | 62 | chipEnable(); |
displaymodule | 0:3ecd25651727 | 63 | _spi.write(STATUS1_INST); |
displaymodule | 0:3ecd25651727 | 64 | status = _spi.write(DUMMY_ADDR); |
displaymodule | 0:3ecd25651727 | 65 | chipDisable(); |
displaymodule | 0:3ecd25651727 | 66 | return status; |
displaymodule | 0:3ecd25651727 | 67 | } |
displaymodule | 0:3ecd25651727 | 68 | uint8_t W25Q16BV::readStatus2() |
displaymodule | 0:3ecd25651727 | 69 | { |
displaymodule | 0:3ecd25651727 | 70 | uint8_t status; |
displaymodule | 0:3ecd25651727 | 71 | chipEnable(); |
displaymodule | 0:3ecd25651727 | 72 | _spi.write(STATUS2_INST); |
displaymodule | 0:3ecd25651727 | 73 | status = _spi.write(DUMMY_ADDR); |
displaymodule | 0:3ecd25651727 | 74 | chipDisable(); |
displaymodule | 0:3ecd25651727 | 75 | return status; |
displaymodule | 0:3ecd25651727 | 76 | } |
displaymodule | 0:3ecd25651727 | 77 | |
displaymodule | 0:3ecd25651727 | 78 | // WRITING |
displaymodule | 0:3ecd25651727 | 79 | void W25Q16BV::writeByte(int addr, int data) { |
displaymodule | 0:3ecd25651727 | 80 | writeEnable(); |
displaymodule | 0:3ecd25651727 | 81 | chipEnable(); |
displaymodule | 0:3ecd25651727 | 82 | _spi.write(W_INST); |
displaymodule | 0:3ecd25651727 | 83 | _spi.write((addr >> 16) & 0xff); |
displaymodule | 0:3ecd25651727 | 84 | _spi.write((addr >> 8) & 0xff); |
displaymodule | 0:3ecd25651727 | 85 | _spi.write((addr ) & 0xff); |
displaymodule | 0:3ecd25651727 | 86 | _spi.write(data); |
displaymodule | 0:3ecd25651727 | 87 | chipDisable(); |
displaymodule | 0:3ecd25651727 | 88 | writeDisable(); |
displaymodule | 0:3ecd25651727 | 89 | // wait_us(WAIT_US_TBP); |
displaymodule | 0:3ecd25651727 | 90 | waitWhileBusy(); |
displaymodule | 0:3ecd25651727 | 91 | } |
displaymodule | 0:3ecd25651727 | 92 | void W25Q16BV::writeByte(int a2, int a1, int a0, int data) { |
displaymodule | 0:3ecd25651727 | 93 | writeEnable(); |
displaymodule | 0:3ecd25651727 | 94 | chipEnable(); |
displaymodule | 0:3ecd25651727 | 95 | _spi.write(W_INST); |
displaymodule | 0:3ecd25651727 | 96 | _spi.write(a2); |
displaymodule | 0:3ecd25651727 | 97 | _spi.write(a1); |
displaymodule | 0:3ecd25651727 | 98 | _spi.write(a0); |
displaymodule | 0:3ecd25651727 | 99 | _spi.write(data); |
displaymodule | 0:3ecd25651727 | 100 | chipDisable(); |
displaymodule | 0:3ecd25651727 | 101 | writeDisable(); |
displaymodule | 0:3ecd25651727 | 102 | // wait_us(WAIT_US_TBP); |
displaymodule | 0:3ecd25651727 | 103 | waitWhileBusy(); |
displaymodule | 0:3ecd25651727 | 104 | } |
displaymodule | 0:3ecd25651727 | 105 | #if 0 |
displaymodule | 0:3ecd25651727 | 106 | void W25Q16BV::writeStream(int addr, char* buf, int count) { |
displaymodule | 0:3ecd25651727 | 107 | if (count < 1) |
displaymodule | 0:3ecd25651727 | 108 | return; |
displaymodule | 0:3ecd25651727 | 109 | writeEnable(); |
displaymodule | 0:3ecd25651727 | 110 | chipEnable(); |
displaymodule | 0:3ecd25651727 | 111 | _spi.write(W_INST); |
displaymodule | 0:3ecd25651727 | 112 | _spi.write((addr & ADDR_BMASK2) >> ADDR_BSHIFT2); |
displaymodule | 0:3ecd25651727 | 113 | _spi.write((addr & ADDR_BMASK1) >> ADDR_BSHIFT1); |
displaymodule | 0:3ecd25651727 | 114 | _spi.write((addr & ADDR_BMASK0) >> ADDR_BSHIFT0); |
displaymodule | 0:3ecd25651727 | 115 | for (int i = 0; i < count; i++) |
displaymodule | 0:3ecd25651727 | 116 | _spi.write(buf[i]); |
displaymodule | 0:3ecd25651727 | 117 | chipDisable(); |
displaymodule | 0:3ecd25651727 | 118 | writeDisable(); |
displaymodule | 0:3ecd25651727 | 119 | wait(WAIT_TIME_MS); |
displaymodule | 0:3ecd25651727 | 120 | } |
displaymodule | 0:3ecd25651727 | 121 | #else |
displaymodule | 0:3ecd25651727 | 122 | void W25Q16BV::writeStream(int addr, char* buf, int count) |
displaymodule | 0:3ecd25651727 | 123 | { |
displaymodule | 0:3ecd25651727 | 124 | int left = count; |
displaymodule | 0:3ecd25651727 | 125 | int offset = 0; |
displaymodule | 0:3ecd25651727 | 126 | int len = 0; |
displaymodule | 0:3ecd25651727 | 127 | |
displaymodule | 0:3ecd25651727 | 128 | if (count < 1) { |
displaymodule | 0:3ecd25651727 | 129 | return; |
displaymodule | 0:3ecd25651727 | 130 | } |
displaymodule | 0:3ecd25651727 | 131 | |
displaymodule | 0:3ecd25651727 | 132 | // find length of first page write |
displaymodule | 0:3ecd25651727 | 133 | if ((addr / PAGE_SIZE) != ((addr + count) / PAGE_SIZE)) { |
displaymodule | 0:3ecd25651727 | 134 | //spans across at least one boundary |
displaymodule | 0:3ecd25651727 | 135 | len = PAGE_SIZE - (addr % PAGE_SIZE); |
displaymodule | 0:3ecd25651727 | 136 | } else { |
displaymodule | 0:3ecd25651727 | 137 | // ends inside same page => use normal length |
displaymodule | 0:3ecd25651727 | 138 | len = count % PAGE_SIZE; |
displaymodule | 0:3ecd25651727 | 139 | } |
displaymodule | 0:3ecd25651727 | 140 | |
displaymodule | 0:3ecd25651727 | 141 | //break up large write operation into several page write operations |
displaymodule | 0:3ecd25651727 | 142 | while (left > 0) { |
displaymodule | 0:3ecd25651727 | 143 | writeEnable(); |
displaymodule | 0:3ecd25651727 | 144 | chipEnable(); |
displaymodule | 0:3ecd25651727 | 145 | _spi.write(W_INST); |
displaymodule | 0:3ecd25651727 | 146 | _spi.write(((addr + offset) >> 16) & 0xff); |
displaymodule | 0:3ecd25651727 | 147 | _spi.write(((addr + offset) >> 8) & 0xff); |
displaymodule | 0:3ecd25651727 | 148 | _spi.write(((addr + offset) ) & 0xff); |
displaymodule | 0:3ecd25651727 | 149 | for (int i = 0; i < len; i++) { |
displaymodule | 0:3ecd25651727 | 150 | _spi.write(buf[offset + i]); |
displaymodule | 0:3ecd25651727 | 151 | } |
displaymodule | 0:3ecd25651727 | 152 | chipDisable(); |
displaymodule | 0:3ecd25651727 | 153 | //writeDisable(); |
displaymodule | 0:3ecd25651727 | 154 | |
displaymodule | 0:3ecd25651727 | 155 | offset += len; |
displaymodule | 0:3ecd25651727 | 156 | left -= len; |
displaymodule | 0:3ecd25651727 | 157 | len = (left < PAGE_SIZE) ? left : PAGE_SIZE; |
displaymodule | 0:3ecd25651727 | 158 | |
displaymodule | 0:3ecd25651727 | 159 | //wait_us(WAIT_US_TPP); |
displaymodule | 0:3ecd25651727 | 160 | waitWhileBusy(); |
displaymodule | 0:3ecd25651727 | 161 | } |
displaymodule | 0:3ecd25651727 | 162 | } |
displaymodule | 0:3ecd25651727 | 163 | #endif |
displaymodule | 0:3ecd25651727 | 164 | |
displaymodule | 0:3ecd25651727 | 165 | //ERASING |
displaymodule | 0:3ecd25651727 | 166 | void W25Q16BV::chipErase() { |
displaymodule | 0:3ecd25651727 | 167 | writeEnable(); |
displaymodule | 0:3ecd25651727 | 168 | chipEnable(); |
displaymodule | 0:3ecd25651727 | 169 | _spi.write(C_ERASE_INST); |
displaymodule | 0:3ecd25651727 | 170 | chipDisable(); |
displaymodule | 0:3ecd25651727 | 171 | // writeDisable(); |
displaymodule | 0:3ecd25651727 | 172 | // wait_us(WAIT_US_TCE); |
displaymodule | 0:3ecd25651727 | 173 | waitWhileBusy(); |
displaymodule | 0:3ecd25651727 | 174 | } |
displaymodule | 0:3ecd25651727 | 175 | bool W25Q16BV::blockErase(int startBlock, int num) { |
displaymodule | 0:3ecd25651727 | 176 | if ((num < 1) || (startBlock < 0) || ((startBlock+num) > NUM_64KB_BLOCKS)) { |
displaymodule | 0:3ecd25651727 | 177 | return false; |
displaymodule | 0:3ecd25651727 | 178 | } |
displaymodule | 0:3ecd25651727 | 179 | for (int i = 0; i < num; i++) { |
displaymodule | 0:3ecd25651727 | 180 | writeEnable(); |
displaymodule | 0:3ecd25651727 | 181 | chipEnable(); |
displaymodule | 0:3ecd25651727 | 182 | _spi.write(B_ERASE_INST); |
displaymodule | 0:3ecd25651727 | 183 | _spi.write(startBlock + i); |
displaymodule | 0:3ecd25651727 | 184 | _spi.write(0); |
displaymodule | 0:3ecd25651727 | 185 | _spi.write(0); |
displaymodule | 0:3ecd25651727 | 186 | chipDisable(); |
displaymodule | 0:3ecd25651727 | 187 | // writeDisable(); |
displaymodule | 0:3ecd25651727 | 188 | // wait_us(WAIT_US_TBE); |
displaymodule | 0:3ecd25651727 | 189 | waitWhileBusy(); |
displaymodule | 0:3ecd25651727 | 190 | } |
displaymodule | 0:3ecd25651727 | 191 | return true; |
displaymodule | 0:3ecd25651727 | 192 | } |
displaymodule | 0:3ecd25651727 | 193 | bool W25Q16BV::sectorErase(int startSector, int num) { |
displaymodule | 0:3ecd25651727 | 194 | if ((num < 1) || (startSector < 0) || ((startSector+num) > NUM_SECTORS)) { |
displaymodule | 0:3ecd25651727 | 195 | return false; |
displaymodule | 0:3ecd25651727 | 196 | } |
displaymodule | 0:3ecd25651727 | 197 | int addr = startSector * SECTOR_SIZE; |
displaymodule | 0:3ecd25651727 | 198 | for (int i = 0; i < num; i++) { |
displaymodule | 0:3ecd25651727 | 199 | writeEnable(); |
displaymodule | 0:3ecd25651727 | 200 | chipEnable(); |
displaymodule | 0:3ecd25651727 | 201 | _spi.write(S_ERASE_INST); |
displaymodule | 0:3ecd25651727 | 202 | _spi.write((addr >> 16) & 0xff); |
displaymodule | 0:3ecd25651727 | 203 | _spi.write((addr >> 8) & 0xff); |
displaymodule | 0:3ecd25651727 | 204 | _spi.write((addr ) & 0xff); |
displaymodule | 0:3ecd25651727 | 205 | chipDisable(); |
displaymodule | 0:3ecd25651727 | 206 | // writeDisable(); |
displaymodule | 0:3ecd25651727 | 207 | // wait_us(WAIT_US_TSE); |
displaymodule | 0:3ecd25651727 | 208 | waitWhileBusy(); |
displaymodule | 0:3ecd25651727 | 209 | |
displaymodule | 0:3ecd25651727 | 210 | addr += SECTOR_SIZE; |
displaymodule | 0:3ecd25651727 | 211 | } |
displaymodule | 0:3ecd25651727 | 212 | return true; |
displaymodule | 0:3ecd25651727 | 213 | } |
displaymodule | 0:3ecd25651727 | 214 | |
displaymodule | 0:3ecd25651727 | 215 | // Wakeup from deep power down (default state) |
displaymodule | 0:3ecd25651727 | 216 | void W25Q16BV::exitDeepPowerDown() { |
displaymodule | 0:3ecd25651727 | 217 | chipEnable(); |
displaymodule | 0:3ecd25651727 | 218 | _spi.write(POWERUP_INST); |
displaymodule | 0:3ecd25651727 | 219 | chipDisable(); |
displaymodule | 0:3ecd25651727 | 220 | wait_us(WAIT_US_TRES1); |
displaymodule | 0:3ecd25651727 | 221 | } |
displaymodule | 0:3ecd25651727 | 222 | |
displaymodule | 0:3ecd25651727 | 223 | void W25Q16BV::waitWhileBusy() { |
displaymodule | 0:3ecd25651727 | 224 | uint8_t status = 0; |
displaymodule | 0:3ecd25651727 | 225 | int i = 0; |
displaymodule | 0:3ecd25651727 | 226 | |
displaymodule | 0:3ecd25651727 | 227 | do { |
displaymodule | 0:3ecd25651727 | 228 | for (i = 0; i < 0x2000; i++); |
displaymodule | 0:3ecd25651727 | 229 | |
displaymodule | 0:3ecd25651727 | 230 | status = readStatus1(); |
displaymodule | 0:3ecd25651727 | 231 | } |
displaymodule | 0:3ecd25651727 | 232 | while ((status & STATUS_1_BUSY) != 0); |
displaymodule | 0:3ecd25651727 | 233 | } |
displaymodule | 0:3ecd25651727 | 234 | |
displaymodule | 0:3ecd25651727 | 235 | //ENABLE/DISABLE (private functions) |
displaymodule | 0:3ecd25651727 | 236 | void W25Q16BV::writeEnable() { |
displaymodule | 0:3ecd25651727 | 237 | chipEnable(); |
displaymodule | 0:3ecd25651727 | 238 | _spi.write(WE_INST); |
displaymodule | 0:3ecd25651727 | 239 | chipDisable(); |
displaymodule | 0:3ecd25651727 | 240 | } |
displaymodule | 0:3ecd25651727 | 241 | void W25Q16BV::writeDisable() { |
displaymodule | 0:3ecd25651727 | 242 | chipEnable(); |
displaymodule | 0:3ecd25651727 | 243 | _spi.write(WD_INST); |
displaymodule | 0:3ecd25651727 | 244 | chipDisable(); |
displaymodule | 0:3ecd25651727 | 245 | } |
displaymodule | 0:3ecd25651727 | 246 | void W25Q16BV::chipEnable() { |
displaymodule | 0:3ecd25651727 | 247 | _cs = 0; |
displaymodule | 0:3ecd25651727 | 248 | } |
displaymodule | 0:3ecd25651727 | 249 | void W25Q16BV::chipDisable() { |
displaymodule | 0:3ecd25651727 | 250 | _cs = 1; |
displaymodule | 0:3ecd25651727 | 251 | } |
displaymodule | 0:3ecd25651727 | 252 |