Flash handler for M25P* chips with no Device ID.

Dependencies:   RTOS_SPI_Clean

Fork of flash25spi by Klaus Steinhammer

Files at this revision

API Documentation at this revision

Comitter:
Tomo2k
Date:
Fri Jun 27 10:13:16 2014 +0000
Parent:
7:fae78b14f38f
Child:
9:8d3cd5aacee7
Commit message:
Now uses DMA for page read/writes. Requires RTOS

Changed in this revision

RTOS_SPI.lib Show annotated file Show diff for this revision Revisions of this file
flash25spi.cpp Show annotated file Show diff for this revision Revisions of this file
flash25spi.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/RTOS_SPI.lib	Fri Jun 27 10:13:16 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/Sissors/code/RTOS_SPI/#d052724e2ad6
--- 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;
     }
 }
 
--- a/flash25spi.h	Mon Apr 28 10:39:17 2014 +0000
+++ b/flash25spi.h	Fri Jun 27 10:13:16 2014 +0000
@@ -31,10 +31,15 @@
 */
 
 #pragma once
+
+// RTOS DMA-enabled version
+#include "rtos.h"
+#include "RTOS_SPI.h"
+
 #include "mbed.h"
 
 /**
-An interface class to read and write M25P* serial SPI flash devices.
+An RTOS interface class to read and write M25P* serial SPI flash devices.
 Supports M25P10-A and M25P40 ICs with no Device ID.
 */
 class FlashM25PSpi
@@ -43,11 +48,12 @@
     /**
         Create the flash interface class.
         It will autodetect the Signature of your device. If your device is not recognized, add the devices parameters to the device data structure.
-        @param spi the SPI port where the flash is connected. Must be set to speed matching your device.
-        Will automatically set it to format(8,3).
+        @param spi the RTOS_SPI port where the flash is connected. Must be set to speed matching your device.
         @param enable the pin name for the port where /CS is connected
+        @param bits SPI bits format. If zero, leave SPI Format unchanged
+        @param mode SPI mode.
     */
-    FlashM25PSpi(SPI *spi, PinName enable);
+    FlashM25PSpi(RTOS_SPI *spi, PinName enable, int bits = 8, int mode = 3);
 
     /**
         Destroy the interface and power down the flash chip
@@ -103,13 +109,13 @@
     }
 
 private:
-    bool writePage(uint32_t startAddr, const char* data, size_t len);
+    bool writePage(uint32_t startAddr, const uint8_t* data, size_t len);
     int readStatus();
     void waitForWrite();
     void enableWrite();
 
+    RTOS_SPI* _spi;
 
-    SPI* _spi;
     DigitalOut _enable;
     size_t _size, _pageSize, _sectorSize;
 };