fix nrf51822 i2c & spi conflict

Dependencies:   BLE_API eMPL_MPU6050 nRF51822

Fork of Seeed_Tiny_BLE_Flash by Darren Huang

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers W25Q16BV.cpp Source File

W25Q16BV.cpp

00001 // W25Q16BV.cpp
00002 
00003 #include"W25Q16BV.h"
00004 
00005 // CONSTRUCTOR 
00006 W25Q16BV::W25Q16BV(PinName mosi, PinName miso, PinName sclk, PinName cs) : _spi(mosi, miso, sclk), _cs(cs) {
00007     _spi.format(SPI_NBIT, SPI_MODE);
00008     _spi.frequency(SPI_FREQ);
00009     chipDisable();
00010 
00011     exitDeepPowerDown();
00012     // The SPI Flash cannot safely be accessed the first 1-10 ms after power ON
00013 //    wait_us(WAIT_US_TPUW);
00014 }
00015 
00016 
00017 // READING
00018 int W25Q16BV::readByte(int addr) {
00019     chipEnable();
00020     _spi.write(R_INST);
00021     _spi.write((addr >> 16) & 0xff);
00022     _spi.write((addr >>  8) & 0xff);
00023     _spi.write((addr      ) & 0xff);
00024     int response = _spi.write(DUMMY_ADDR);
00025     chipDisable();
00026     return response;
00027 }
00028 int W25Q16BV::readByte(int a2, int a1, int a0) {
00029    chipEnable();
00030    _spi.write(R_INST);
00031    _spi.write(a2);
00032    _spi.write(a1);
00033    _spi.write(a0);
00034    int response = _spi.write(DUMMY_ADDR);
00035     chipDisable();
00036     return response;
00037 }
00038 void W25Q16BV::readStream(int addr, char* buf, int count) {
00039     if (count < 1)
00040         return;
00041     chipEnable();
00042     _spi.write(R_INST);
00043     _spi.write((addr >> 16) & 0xff);
00044     _spi.write((addr >>  8) & 0xff);
00045     _spi.write((addr      ) & 0xff);
00046     for (int i = 0; i < count; i++)
00047         buf[i] =  _spi.write(DUMMY_ADDR);
00048     chipDisable();
00049 }
00050 void W25Q16BV::readJEDEC(uint8_t* manId, uint8_t* memType, uint8_t* cap)
00051 {
00052     chipEnable();
00053     _spi.write(JDEC_INST);
00054     *manId = _spi.write(DUMMY_ADDR);
00055     *memType = _spi.write(DUMMY_ADDR);
00056     *cap = _spi.write(DUMMY_ADDR);
00057     chipDisable();
00058 }
00059 uint8_t W25Q16BV::readStatus1()
00060 {
00061   uint8_t status;
00062   chipEnable();
00063   _spi.write(STATUS1_INST);
00064   status = _spi.write(DUMMY_ADDR);
00065   chipDisable();
00066   return status;
00067 }
00068 uint8_t W25Q16BV::readStatus2()
00069 {
00070   uint8_t status;
00071   chipEnable();
00072   _spi.write(STATUS2_INST);
00073   status = _spi.write(DUMMY_ADDR);
00074   chipDisable();
00075   return status;
00076 }
00077 
00078 // WRITING
00079 void W25Q16BV::writeByte(int addr, int data) {
00080     writeEnable();
00081     chipEnable();
00082     _spi.write(W_INST);
00083     _spi.write((addr >> 16) & 0xff);
00084     _spi.write((addr >>  8) & 0xff);
00085     _spi.write((addr      ) & 0xff);
00086     _spi.write(data);
00087     chipDisable();
00088     writeDisable();
00089 //    wait_us(WAIT_US_TBP);
00090     waitWhileBusy();
00091 }
00092 void W25Q16BV::writeByte(int a2, int a1, int a0, int data) {
00093     writeEnable();
00094     chipEnable();
00095     _spi.write(W_INST);
00096     _spi.write(a2);
00097     _spi.write(a1);
00098     _spi.write(a0);
00099     _spi.write(data);
00100     chipDisable();
00101     writeDisable();
00102 //    wait_us(WAIT_US_TBP);
00103     waitWhileBusy();
00104 }
00105 #if 0
00106 void W25Q16BV::writeStream(int addr, char* buf, int count) {
00107     if (count < 1)
00108         return;
00109     writeEnable();
00110     chipEnable();
00111     _spi.write(W_INST);
00112     _spi.write((addr & ADDR_BMASK2) >> ADDR_BSHIFT2);
00113     _spi.write((addr & ADDR_BMASK1) >> ADDR_BSHIFT1);
00114     _spi.write((addr & ADDR_BMASK0) >> ADDR_BSHIFT0);
00115     for (int i = 0; i < count; i++)
00116         _spi.write(buf[i]);
00117     chipDisable();
00118     writeDisable();
00119     wait(WAIT_TIME_MS);
00120 }
00121 #else
00122 void W25Q16BV::writeStream(int addr, char* buf, int count)
00123 {
00124   int left = count;
00125   int offset = 0;
00126   int len = 0;
00127   
00128   if (count < 1) {
00129     return;
00130   }
00131     
00132   // find length of first page write
00133   if ((addr / PAGE_SIZE) != ((addr + count) / PAGE_SIZE)) {
00134     //spans across at least one boundary
00135     len = PAGE_SIZE - (addr % PAGE_SIZE);
00136   } else {
00137     // ends inside same page => use normal length
00138     len = count % PAGE_SIZE;
00139   }
00140   
00141   //break up large write operation into several page write operations
00142   while (left > 0) {
00143     writeEnable();
00144     chipEnable();
00145     _spi.write(W_INST);
00146     _spi.write(((addr + offset) >> 16) & 0xff);
00147     _spi.write(((addr + offset) >>  8) & 0xff);
00148     _spi.write(((addr + offset)      ) & 0xff);
00149     for (int i = 0; i < len; i++) {
00150       _spi.write(buf[offset + i]);
00151     }
00152     chipDisable();
00153     //writeDisable();
00154     
00155     offset += len;
00156     left -= len;
00157     len = (left < PAGE_SIZE) ? left : PAGE_SIZE;
00158     
00159     //wait_us(WAIT_US_TPP);
00160     waitWhileBusy();
00161   }
00162 }
00163 #endif
00164 
00165 //ERASING
00166 void W25Q16BV::chipErase() {
00167     writeEnable();
00168     chipEnable();
00169     _spi.write(C_ERASE_INST);
00170     chipDisable();
00171 //    writeDisable();
00172 //    wait_us(WAIT_US_TCE);
00173     waitWhileBusy();
00174 }
00175 bool W25Q16BV::blockErase(int startBlock, int num) {
00176   if ((num < 1) || (startBlock < 0) || ((startBlock+num) > NUM_64KB_BLOCKS)) {
00177     return false;
00178   }
00179   for (int i = 0; i < num; i++) {
00180     writeEnable();
00181     chipEnable();
00182     _spi.write(B_ERASE_INST);
00183     _spi.write(startBlock + i);
00184     _spi.write(0);
00185     _spi.write(0);
00186     chipDisable();
00187 //    writeDisable();
00188 //    wait_us(WAIT_US_TBE);
00189     waitWhileBusy();
00190   }
00191   return true;
00192 }
00193 bool W25Q16BV::sectorErase(int startSector, int num) {
00194   if ((num < 1) || (startSector < 0) || ((startSector+num) > NUM_SECTORS)) {
00195     return false;
00196   }
00197   int addr = startSector * SECTOR_SIZE;
00198   for (int i = 0; i < num; i++) {
00199     writeEnable();
00200     chipEnable();
00201     _spi.write(S_ERASE_INST);
00202     _spi.write((addr >> 16) & 0xff);
00203     _spi.write((addr >>  8) & 0xff);
00204     _spi.write((addr      ) & 0xff);
00205     chipDisable();
00206 //    writeDisable();
00207 //    wait_us(WAIT_US_TSE);
00208     waitWhileBusy();
00209     
00210     addr += SECTOR_SIZE;
00211   }
00212   return true;
00213 }
00214 
00215 // Wakeup from deep power down (default state)
00216 void W25Q16BV::exitDeepPowerDown() {
00217     chipEnable();
00218     _spi.write(POWERUP_INST);
00219     chipDisable();
00220   wait_us(WAIT_US_TRES1);
00221 }
00222 
00223 void W25Q16BV::waitWhileBusy() {
00224   uint8_t status = 0;
00225   int i = 0;
00226 
00227   do {
00228     for (i = 0; i < 0x2000; i++);
00229 
00230     status = readStatus1();
00231   }
00232   while ((status & STATUS_1_BUSY) != 0);
00233 }
00234 
00235 //ENABLE/DISABLE (private functions)
00236 void W25Q16BV::writeEnable() {
00237     chipEnable();
00238     _spi.write(WE_INST);
00239     chipDisable();
00240 }
00241 void W25Q16BV::writeDisable() {
00242     chipEnable();
00243     _spi.write(WD_INST);
00244     chipDisable();
00245 }
00246 void W25Q16BV::chipEnable() {
00247     _cs = 0;
00248 }
00249 void W25Q16BV::chipDisable() {
00250     _cs = 1;
00251 }
00252