Flash handler for M25P* chips with no Device ID.
Fork of flash25spi by
Revision 8:7b09546cb412, committed 2014-06-27
- 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
--- /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; };