spif
spif copied to clipboard
Use with LittleFS
Hi Thanks for you great library. I am struggling to use your library in combination with littlefs. Have you ever implemented the littlefs filesystem with your driver?
Hello. This is good idea.
@marcellangmaier It is very simple, you can refer to my configuration for LFS
#define LFS_READ_SIZE (128)
#define LFS_PROG_SIZE (LFS_READ_SIZE)
#define LFS_LOOKAHEAD_SIZE (LFS_READ_SIZE / 8)
#define LFS_BLOCK_SIZE (65536)
#define LFS_BLOCK_COUNT (1024)
#define LFS_BLOCK_CYCLES (-1)
#define LFS_CACHE_SIZE (64 % LFS_PROG_SIZE == 0 ? 64 : LFS_PROG_SIZE)
#define LFS_ERASE_VALUE (0xff)
#define LFS_ERASE_CYCLES (-1)
#define LFS_BADBLOCK_BEHAVIOR (LFS_TESTBD_BADBLOCK_PROGERROR)
/* Static Allocate Buffer for R/W on Files */
static uint8_t Flash_RD_Cache[LFS_READ_SIZE];
static uint8_t Flash_WR_Cache[LFS_PROG_SIZE];
static uint8_t Flash_LKH_Cache[LFS_LOOKAHEAD_SIZE];
static int Flash_ReadBlock(const struct lfs_config *c, lfs_block_t block,
lfs_off_t off, void *buffer, lfs_size_t size);
static int Flash_WriteBlock(const struct lfs_config *c, lfs_block_t block,
lfs_off_t off, const void *buffer, lfs_size_t size);
static int Flash_EraseBlock(const struct lfs_config *c, lfs_block_t block);
static int Flash_SyncDevice(const struct lfs_config *c);
static lfs_t lfs;
static lfs_file_t file;
const struct lfs_config lfsconfig= {
.context = NULL,
.read = Flash_ReadBlock,
.prog = Flash_WriteBlock,
.erase = Flash_EraseBlock,
.sync = Flash_SyncDevice,
.read_size = FLASH_LFS_READ_SIZE,
.prog_size = FLASH_LFS_PROG_SIZE,
.block_size = FLASH_LFS_BLOCK_SIZE,
.block_count = FLASH_LFS_BLOCK_COUNT,
.block_cycles = FLASH_LFS_BLOCK_CYCLES,
.cache_size = FLASH_LFS_CACHE_SIZE,
.lookahead_size = FLASH_LFS_LOOKAHEAD_SIZE,
.name_max = LFS_NAME_MAX,
.file_max = LFS_FILE_MAX,
.attr_max = LFS_ATTR_MAX,
.read_buffer = AudioFlash_RD_Cache,
.prog_buffer = AudioFlash_WR_Cache,
.lookahead_buffer = AudioFlash_LKH_Cache,
};
static int Flash_ReadBlock(const struct lfs_config *c, lfs_block_t block,
lfs_off_t off, void *buffer, lfs_size_t size)
{
return W25qxx_ReadBlock((uint8_t*)buffer, block, off, size);
}
static int Flash_WriteBlock(const struct lfs_config *c, lfs_block_t block,
lfs_off_t off, const void *buffer, lfs_size_t size)
{
return W25qxx_WriteBlock((uint8_t*)buffer, block, off, size);
}
static int Flash_EraseBlock(const struct lfs_config *c, lfs_block_t block)
{
return W25qxx_EraseBlock(block);
}
static int Flash_SyncDevice(const struct lfs_config *c)
{
/* Not support at now */
return 0;
}
then create a main function to init littlefs
#include "lfs.h"
#include "w25qxx.h"
void main()
{
W25qxx_Init();
/* you have to ensure the SPI work well first */
uint32_t status = lfs_mount(&lfs, &lfsconfig);
if(status != 0)
{
printf("Warning: Try to format flash\n");
status = lfs_format(&lfs, &lfsconfig);
if(status == STATUS_SUCCESS)
{
status = lfs_mount(&lfs, &lfsconfig);
}
}
return status;
}
Noted:
We need to change W25qxx_ReadBlock(), W25qxx_WriteBlock(), W25qxx_EraseBlock() from return void to return status values. It needs for Littlefs checking error @nimaltd
typedef uint32_t status_t;
//############################################################################
// in Page,Sector and block read/write functions, can put 0 to read maximum bytes
//############################################################################
uint32_t W25qxx_Init(void);
status_t W25qxx_EraseChip(void);
status_t W25qxx_EraseSector(uint32_t SectorAddr);
status_t W25qxx_EraseBlock(uint32_t BlockAddr);
uint32_t W25qxx_PageToSector(uint32_t PageAddress);
uint32_t W25qxx_PageToBlock(uint32_t PageAddress);
uint32_t W25qxx_SectorToBlock(uint32_t SectorAddress);
uint32_t W25qxx_SectorToPage(uint32_t SectorAddress);
uint32_t W25qxx_BlockToPage(uint32_t BlockAddress);
bool W25qxx_IsEmptyPage(uint32_t Page_Address, uint32_t OffsetInByte, uint32_t NumByteToCheck_up_to_PageSize);
bool W25qxx_IsEmptySector(uint32_t Sector_Address, uint32_t OffsetInByte, uint32_t NumByteToCheck_up_to_SectorSize);
bool W25qxx_IsEmptyBlock(uint32_t Block_Address, uint32_t OffsetInByte, uint32_t NumByteToCheck_up_to_BlockSize);
status_t W25qxx_WriteByte(uint8_t pBuffer, uint32_t Bytes_Address);
status_t W25qxx_WritePage(uint8_t *pBuffer, uint32_t Page_Address, uint32_t OffsetInByte, uint32_t NumByteToWrite_up_to_PageSize);
status_t W25qxx_WriteSector(uint8_t *pBuffer, uint32_t Sector_Address, uint32_t OffsetInByte, uint32_t NumByteToWrite_up_to_SectorSize);
status_t W25qxx_WriteBlock(uint8_t *pBuffer, uint32_t Block_Address, uint32_t OffsetInByte, uint32_t NumByteToWrite_up_to_BlockSize);
status_t W25qxx_ReadByte(uint8_t *pBuffer, uint32_t Bytes_Address);
status_t W25qxx_ReadBytes(uint8_t *pBuffer, uint32_t ReadAddr, uint32_t NumByteToRead);
status_t W25qxx_ReadPage(uint8_t *pBuffer, uint32_t Page_Address, uint32_t OffsetInByte, uint32_t NumByteToRead_up_to_PageSize);
status_t W25qxx_ReadSector(uint8_t *pBuffer, uint32_t Sector_Address, uint32_t OffsetInByte, uint32_t NumByteToRead_up_to_SectorSize);
status_t W25qxx_ReadBlock(uint8_t *pBuffer, uint32_t Block_Address, uint32_t OffsetInByte, uint32_t NumByteToRead_up_to_BlockSize);
#endif
Hello @nguyenlkdn . for sure. Please Push your new code