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

Committer:
displaymodule
Date:
Tue May 20 10:30:34 2014 +0000
Revision:
0:3ecd25651727
First version

Who changed what in which revision?

UserRevisionLine numberNew 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