QSPI external flash block device for file system on external flash for DISCO_L475VG_IOT01
Dependencies: BSP_B-L475E-IOT01
Diff: QSPIExtFlashBlockDevice/QSPIExtFlashBlockDevice.cpp
- Revision:
- 0:0ca082ff5da6
- Child:
- 1:2baccc030920
diff -r 000000000000 -r 0ca082ff5da6 QSPIExtFlashBlockDevice/QSPIExtFlashBlockDevice.cpp --- /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; +} + +