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

Dependencies:   BSP_B-L475E-IOT01

QSPIExtFlashBlockDevice/QSPIExtFlashBlockDevice.cpp

Committer:
DoronRaifman
Date:
2018-04-26
Revision:
0:0ca082ff5da6
Child:
1:2baccc030920

File content as of revision 0:0ca082ff5da6:

/* 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;
}