QSPI external flash block device for file system on external flash for DISCO_L475VG_IOT01

Dependencies:   BSP_B-L475E-IOT01

Revision:
0:0ca082ff5da6
Child:
1:2baccc030920
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/QSPIExtFlashBlockDevice/QSPIExtFlashBlockDevice.cpp	Thu Apr 26 09:25:47 2018 +0000
@@ -0,0 +1,335 @@
+/* QSPIExtFlashBlockDevice.cpp
+ * QSPI external flash block device to be used for file system on external flash
+ * for DISCO_L475VG_IOT01
+ * 
+ * Doron Raifman, draifman@gmail.com
+ */
+
+#include "QSPIExtFlashBlockDevice.h"
+
+
+
+ 
+QSPIExtFlashBlockDevice::QSPIExtFlashBlockDevice()
+{
+}
+
+
+QSPIExtFlashBlockDevice::~QSPIExtFlashBlockDevice()
+{
+}
+
+
+int QSPIExtFlashBlockDevice::init()
+{
+    int nRc = 0;
+    
+#if QSPIExtFlashBlockDevice_VERBOSE
+    printf("QSPIExtFlashBlockDevice::init\n");
+#endif // QSPIExtFlashBlockDevice_VERBOSE
+    nRc = _SyncLock();
+    // Todo: Allocate semaphore
+    if(nRc == 0)
+    {
+        int nTrc = BSP_QSPI_Init();
+        if(nTrc != QSPI_OK)
+        {
+          nRc = RC_QSPIExtFlash_ErrBadDevice;
+#if QSPIExtFlashBlockDevice_ERRORS
+          error("QSPIExtFlashBlockDevice QSPI init FAILED with err %d\n", nTrc);
+                
+#endif // QSPIExtFlashBlockDevice_ERRORS
+        }
+    }
+        
+    if(nRc == 0)
+    {
+        BSP_QSPI_GetInfo(&m_sQSPIExtFlash_Info);
+#if QSPIExtFlashBlockDevice_DEBUG
+        printf("QSPI flash informations: FlashSize=0x0%X %d...\n",
+            m_sQSPIExtFlash_Info.FlashSize, m_sQSPIExtFlash_Info.FlashSize);
+        printf("...EraseSectorSize=%d, ProgPageSize=%d\n", 
+            m_sQSPIExtFlash_Info.EraseSectorSize,
+            m_sQSPIExtFlash_Info.ProgPageSize);
+        printf("...EraseSectorsNumber=%d, ProgPagesNumber=%d\n", 
+            m_sQSPIExtFlash_Info.EraseSectorsNumber,
+            m_sQSPIExtFlash_Info.ProgPagesNumber);
+#endif // QSPIExtFlashBlockDevice_DEBUG
+    }
+    if(nRc != 0)
+    {
+        // Cleanup
+        // Todo: delete semaphore
+    }
+    _SyncUnlock();
+    return nRc;
+}
+
+
+int QSPIExtFlashBlockDevice::deinit()
+{
+    int nRc = 0;
+
+#if QSPIExtFlashBlockDevice_VERBOSE
+    printf("QSPIExtFlashBlockDevice::deinit\n");
+#endif // QSPIExtFlashBlockDevice_VERBOSE
+    
+    nRc = _SyncLock();
+    // Cleanup
+    int nTrc = BSP_QSPI_DeInit();
+#if QSPIExtFlashBlockDevice_ERRORS
+    if(nTrc)
+    {
+        error("BSP_QSPI_DeInit err%d\n", nTrc);
+    }
+#endif // QSPIExtFlashBlockDevice_ERRORS
+    _SyncUnlock();
+    // Todo: delete semaphore
+    return nRc;
+}
+
+
+int QSPIExtFlashBlockDevice::_SyncLock() const
+{
+    int nRc = RC_QSPIExtFlash_ErrTimeout;
+    
+    for (int i = 0; i < QSPIExtFlashBlockDeviceTimeout; i++)
+    {
+        if(1)   // Todo: handle semaphore
+        {
+            nRc = 0;
+            break;
+        }
+        wait_ms(1);
+    }
+#if QSPIExtFlashBlockDevice_ERRORS
+    if(nRc != 0)
+    {
+        error("QSPIExtFlashBlockDevice _SyncLock FAILED\n");
+    }
+#endif // QSPIExtFlashBlockDevice_ERRORS
+    return nRc;
+}
+
+
+int QSPIExtFlashBlockDevice::_SyncUnlock() const
+{
+    int nRc = 0;
+    
+    // Todo: Unlock semaphore
+    return(nRc);
+}
+
+int QSPIExtFlashBlockDevice::_WaitForWrite(const char *ptCaller)
+{
+    int nRc = 0;
+    uint8_t nStatus = 0;
+    
+    nRc = RC_QSPIExtFlash_ErrTimeout;
+    for (int i = 0; i < QSPIExtFlashBlockDeviceTimeout; i++)
+    {
+        nStatus = BSP_QSPI_GetStatus();
+        if(nStatus == 0)
+        {
+            nRc = 0;
+            break;
+        }
+        /*
+        else
+        {
+            printf("Status inside=%d\n", nStatus);
+        }
+         */
+        wait_us(100);
+    }
+#if QSPIExtFlashBlockDevice_ERRORS
+    if(nRc)
+    {
+      printf("Timeout on waiting for status ready for %s\n", ptCaller);
+    }
+#endif // QSPIExtFlashBlockDevice_ERRORS
+    return(nRc);
+}
+
+
+
+int QSPIExtFlashBlockDevice::read(void *buffer, bd_addr_t addr, bd_size_t size)
+{
+    int nRc = 0;
+    
+#if QSPIExtFlashBlockDevice_VERBOSE
+    printf("QSPIExtFlashBlockDevice::read address:%lld, size:%lld\n", addr, size);
+#endif // QSPIExtFlashBlockDevice_VERBOSE
+    nRc = _SyncLock();
+    if(nRc == 0)
+    {
+        nRc = _WaitForWrite((const char *) "QSPIExtFlashBlockDevice::read");
+    }
+    if(nRc == 0)
+    {
+        int nTrc = BSP_QSPI_Read((uint8_t *) buffer, (uint32_t) addr, size);
+        if(nTrc != QSPI_OK)
+        {
+            nRc = RC_QSPIExtFlash_ErrIO;
+#if QSPIExtFlashBlockDevice_ERRORS
+            error("QSPIExtFlashBlockDevice Read FAILED with err %d\n", nTrc);
+#endif // QSPIExtFlashBlockDevice_ERRORS
+        }
+    }
+    _SyncUnlock();
+    return nRc;
+}
+
+ 
+int QSPIExtFlashBlockDevice::program(const void *buffer, bd_addr_t addr, bd_size_t size)
+{
+    int nRc = 0;
+    
+#if QSPIExtFlashBlockDevice_VERBOSE
+    printf("QSPIExtFlashBlockDevice::program address:%lld, size:%lld\n", addr, size);
+#endif // QSPIExtFlashBlockDevice_VERBOSE
+    nRc = _SyncLock();
+    if(nRc == 0)
+    {
+        nRc = _WaitForWrite((const char *) "QSPIExtFlashBlockDevice::program");
+    }
+    if(nRc == 0)
+    {
+        int nTrc = BSP_QSPI_Write((uint8_t *) buffer, (uint32_t) addr, size);
+        if(nTrc != QSPI_OK)
+        {
+            nRc = RC_QSPIExtFlash_ErrIO;
+#if QSPIExtFlashBlockDevice_ERRORS
+            error("QSPIExtFlashBlockDevice Write FAILED with err %d\n", nTrc);
+#endif // QSPIExtFlashBlockDevice_ERRORS
+        }
+    }
+    _SyncUnlock();
+    return nRc;
+}
+
+
+int QSPIExtFlashBlockDevice::erase(bd_addr_t addr, bd_size_t size)
+{
+    int nRc = 0;
+    
+#if QSPIExtFlashBlockDevice_VERBOSE
+    printf("QSPIExtFlashBlockDevice::erase address:%lld, size:%lld\n", addr, size);
+#endif // QSPIExtFlashBlockDevice_VERBOSE
+    nRc = _SyncLock();
+    if(nRc == 0)
+    {
+        nRc = _WaitForWrite((const char *) "QSPIExtFlashBlockDevice::erase");
+    }
+    if(nRc == 0)
+    {
+        int nTrc = BSP_QSPI_Erase_Sector(((uint32_t) addr) / MX25R6435F_SECTOR_SIZE);
+        //int nTrc = BSP_QSPI_Erase_Block((uint32_t) addr);
+        if(nTrc != QSPI_OK)
+        {
+            nRc = RC_QSPIExtFlash_ErrIO;
+#if QSPIExtFlashBlockDevice_ERRORS
+            error("QSPIExtFlashBlockDevice Erase FAILED with err %d\n", nTrc);
+#endif // QSPIExtFlashBlockDevice_ERRORS
+        }
+        else
+        {
+            // Wait for erase to complete
+            nRc = _WaitForWrite((const char *) "QSPIExtFlashBlockDevice::erase wait for complete");
+        }
+    }
+    _SyncUnlock();
+    return nRc;
+}
+
+
+int QSPIExtFlashBlockDevice::EraseAllFlashMemory()
+{
+    int nRc = 0;
+    
+#if QSPIExtFlashBlockDevice_VERBOSE
+    printf("QSPIExtFlashBlockDevice::EraseAllFlashMemory\n");
+#endif // QSPIExtFlashBlockDevice_VERBOSE
+    nRc = _SyncLock();
+    if(nRc == 0)
+    {
+        nRc = _WaitForWrite((const char *) "QSPIExtFlashBlockDevice::EraseAllFlashMemory");
+#if QSPIExtFlashBlockDevice_ERRORS
+        if(nRc)
+        {
+            error("QSPIExtFlashBlockDevice EraseAllFlashMemory _WaitForWrite err with err %d\n", nRc);
+        }
+#endif // QSPIExtFlashBlockDevice_ERRORS
+    }
+    if(nRc == 0)
+    {
+        int nTrc = BSP_QSPI_Erase_Chip();
+        if(nTrc != QSPI_OK)
+        {
+            nRc = RC_QSPIExtFlash_ErrIO;
+#if QSPIExtFlashBlockDevice_ERRORS
+            error("QSPIExtFlashBlockDevice EraseAllFlashMemory FAILED with err %d\n", nTrc);
+#endif // QSPIExtFlashBlockDevice_ERRORS
+        }
+    }
+    _SyncUnlock();
+    return nRc;
+}
+
+
+bd_size_t QSPIExtFlashBlockDevice::get_read_size() const
+{
+    int nRc = 0;
+    bd_size_t nSize = 0;
+    
+    nRc = _SyncLock();
+    if(nRc == 0)
+    {
+        nSize = m_sQSPIExtFlash_Info.ProgPageSize;
+    }
+    _SyncUnlock();
+    return nSize;
+}
+
+bd_size_t QSPIExtFlashBlockDevice::get_program_size() const
+{
+    int nRc = 0;
+    
+    nRc = _SyncLock();
+    if(nRc == 0)
+    {
+        nRc = m_sQSPIExtFlash_Info.ProgPageSize;
+    }
+    _SyncUnlock();
+    return nRc;
+}
+
+
+bd_size_t QSPIExtFlashBlockDevice::get_erase_size() const
+{
+    int nRc = 0;
+    
+    nRc = _SyncLock();
+    if(nRc == 0)
+    {
+        nRc = m_sQSPIExtFlash_Info.EraseSectorSize;
+    }
+    _SyncUnlock();
+    return nRc;
+}
+
+
+bd_size_t QSPIExtFlashBlockDevice::size() const
+{
+    int nRc = 0;
+    
+    nRc = _SyncLock();
+    if(nRc == 0)
+    {
+       nRc = m_sQSPIExtFlash_Info.FlashSize;
+    }
+    _SyncUnlock();
+    return nRc;
+}
+
+