fix nrf51822 i2c & spi conflict

Dependencies:   BLE_API eMPL_MPU6050 nRF51822

Fork of Seeed_Tiny_BLE_Flash by Darren Huang

Committer:
yihui
Date:
Tue Nov 17 07:48:56 2015 +0000
Revision:
5:b8c02645e6af
Parent:
4:19a0764d6b81
fix i2c & spi conflict

Who changed what in which revision?

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