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