Flash handler for M25P* chips with no Device ID.

Dependencies:   RTOS_SPI_Clean

Fork of flash25spi by Klaus Steinhammer

Revision:
8:7b09546cb412
Parent:
7:fae78b14f38f
--- a/flash25spi.cpp	Mon Apr 28 10:39:17 2014 +0000
+++ b/flash25spi.cpp	Fri Jun 27 10:13:16 2014 +0000
@@ -56,7 +56,7 @@
 //const uint8_t FLASH_WRDI = 0x04;    // Write Disable (Unused)
 //const uint8_t FLASH_RDID = 0x9F;    // Read Device IDentification (not supported)
 const uint8_t FLASH_RDSR = 0x05;    // Read Status Register
-const uint8_t FLASH_WRSR = 0x01;    // Write Status Register
+//const uint8_t FLASH_WRSR = 0x01;    // Write Status Register (not used)
 const uint8_t FLASH_READ = 0x03;    // Read Data Bytes
 //const uint8_t FLASH_FAST_READ = 0x0B;   // Read Data Bytes Faster
 const uint8_t FLASH_PP = 0x02;      // Page Program (max pagesize bytes)
@@ -69,15 +69,20 @@
 #define MID(x) ((x&0xff00)>>8)
 #define LOW(x) (x&0xff)
 
-FlashM25PSpi::FlashM25PSpi(SPI *spi, PinName enable) :
+
+FlashM25PSpi::FlashM25PSpi(RTOS_SPI *spi, PinName enable, int bits, int mode) :
     _spi(spi)
     , _enable(enable)
     , _size(0)
 {
-    _spi->format(8,3);
+    if (bits) _spi->format(bits, mode);
 
     _enable = 1;
-    wait_us(1000);
+    if (osKernelRunning()) {
+        Thread::wait(1);
+    } else {
+        wait_us(1000);
+    }
     _enable = 0;
     wait_us(1);
     uint8_t chipSig;
@@ -113,8 +118,9 @@
 
 FlashM25PSpi::~FlashM25PSpi()
 {
+    // Wait until chip finishes cycle
+//    waitForWrite();
     // Shutdown the flash chip into lowest-power mode
-    // Assumes no writes could be in progress
     _enable = 0;
     wait_us(1);
     _spi->write(FLASH_DP);
@@ -130,19 +136,18 @@
     _enable = 0;
     wait_us(1);
 
-    // Cast to char
-    char *dest8 = (char*)destination;
-
     // Send address
     _spi->write(FLASH_READ);
     _spi->write(HIGH(startAddr));
     _spi->write(MID(startAddr));
     _spi->write(LOW(startAddr));
 
-    // Read into destination buffer
-    while (len--) {
-        *dest8++ = _spi->write(0);
-    }
+    uint8_t dummy = 0;
+
+    // Bulk read into destination buffer (DMA)
+    // Be sure to write the same dummy databyte repeatedly
+    _spi->bulkReadWrite((uint8_t*)destination, &dummy, len, false);
+
     wait_us(1);
     _enable = 1;
     return true;
@@ -153,8 +158,8 @@
     if (startAddr + len > _size)
         return false;
 
-    // Cast to char
-    char *data8 = (char*)data;
+    // Cast to uint8_t
+    uint8_t *data8 = (uint8_t*)data;
 
     size_t ofs = 0;
     while (ofs < len) {
@@ -171,7 +176,7 @@
     return true;
 }
 
-bool FlashM25PSpi::writePage(uint32_t startAddr, const char* data, size_t len)
+bool FlashM25PSpi::writePage(uint32_t startAddr, const uint8_t* data, size_t len)
 {
     enableWrite();
 
@@ -183,10 +188,9 @@
     _spi->write(MID(startAddr));
     _spi->write(LOW(startAddr));
 
-    // do real write
-    for (unsigned int i=0; i<len; ++i) {
-        _spi->write(data[i]);
-    }
+    // Bulk write using DMA
+    _spi->bulkWrite(data, len);
+
     wait_us(1);
     // disable to start physical write
     _enable = 1;
@@ -237,9 +241,9 @@
 void FlashM25PSpi::waitForWrite()
 {
     while (true) {
-        if (0 == (readStatus()&1))
-            break;
-        wait_us(10);
+        // Allow something else to do some work
+        Thread::yield();
+        if (0 == (readStatus()&1)) return;
     }
 }