
#ifdef  USE_MID_LFS_RAM
#include <stdio.h>
#include "lfs.h"
#include "mid_littlefs_ram.h"
#include "cmsis_os.h"
 
#define LFS_SECT_SIZE   	64
//#define LFS_BLOCK_SIZE   	(LFS_SECT_SIZE*4)
#define LFS_BLOCK_SIZE		64
#define LFS_BLOCK_CNT   	32
 
/* lfs for W25Q128 *********************************************************/
lfs_t lfs; 
lfs_file_t file;

// configuration of the filesystem is provided by this struct

typedef struct lfs_sys_bufffer
{
	uint8_t read[LFS_BLOCK_SIZE];
	uint8_t prog[LFS_BLOCK_SIZE];
	
	uint32_t lookahead[LFS_BLOCK_CNT/(4*8)+1];
}lfs_sys_buff;

lfs_sys_buff lfs_sys_buf = {0};

uint8_t ram_block[LFS_BLOCK_CNT][LFS_SECT_SIZE] = {0};

/* lfs for STM32Flash ********************************************************/
lfs_t lfs_Stm32_ram; 
lfs_file_t file_ram;



// configuration of the filesystem is provided by this struct
const struct lfs_config cfg_Stm32Flash = {
    // block device operations
    .read  = ram_block_read,
    .prog  = ram_block_prog,
    .erase = ram_block_erase,
    .sync  = ram_block_sync,

    // block device configuration
    .read_size 		= LFS_SECT_SIZE,
    .prog_size 		= LFS_SECT_SIZE,
    .block_size 	= LFS_BLOCK_SIZE,
    .block_count 	= LFS_BLOCK_CNT,
	
    .cache_size 	= LFS_BLOCK_SIZE,
	
    .lookahead_size = sizeof(lfs_sys_buf.lookahead),
    .block_cycles = 500,
		
		//
		.read_buffer = lfs_sys_buf.read,	
	  .prog_buffer = lfs_sys_buf.prog,	
	
		.lookahead_buffer = lfs_sys_buf.lookahead,	
};




int mid_little_fs_ram_main(void)
{
	int err = -1;
	
	
	err = lfs_mount(&lfs_Stm32_ram, &cfg_Stm32Flash);
	
	if( err )
	{
		lfs_format(&lfs_Stm32_ram, &cfg_Stm32Flash);
		lfs_mount(&lfs_Stm32_ram, &cfg_Stm32Flash);
	}
	
		
	
	while(1)
	{

		
		uint32_t boot_count = 0;
		lfs_file_open_user(&lfs_Stm32_ram, &file_ram, "boot_count", LFS_O_RDWR | LFS_O_CREAT);
		lfs_file_read(&lfs_Stm32_ram, &file_ram, &boot_count, sizeof(boot_count));

		
		// update boot count
		boot_count += 1;
		lfs_file_rewind(&lfs_Stm32_ram, &file_ram);  // seek the file to begin
		lfs_file_write(&lfs_Stm32_ram, &file_ram, &boot_count, sizeof(boot_count));

		// remember the storage is not updated until the file is closed successfully
		lfs_file_close(&lfs_Stm32_ram, &file_ram);

//		// release any resources we were using
   

		// print the boot count
		printf("boot_count: %d\n", boot_count);
		
		osDelay(1000);

	}
	//lfs_unmount(&lfs);
}



int ram_block_read(const struct lfs_config *c, lfs_block_t block,
            lfs_off_t off, void *buffer, lfs_size_t size)
{
    uint8_t* pSrc 	= (uint8_t*)&ram_block[block][0] + off;
    uint8_t* pDest = (uint8_t*)buffer;
	
    memcpy(pDest,pSrc,size);

    return 0;
}            

int ram_block_prog(const struct lfs_config *c, lfs_block_t block,
            lfs_off_t off, const void *buffer, lfs_size_t size)
{

    uint8_t* pDest = (uint8_t*)&ram_block[block][0] + off;
    uint8_t* pSrc = (uint8_t*)buffer;
	
    memcpy(pDest,pSrc,size);
    return 0;
}

int ram_block_erase(const struct lfs_config *c, lfs_block_t block)
{
    uint8_t* pDest = (uint8_t*)&ram_block[block][0];
	
    memset(pDest,0xff,c->block_size);
    return 0;
}

int ram_block_sync(const struct lfs_config *c)
{
    return 0;
}

// Statically allocated file buffer. Must be cache_size.
static uint8_t file_buffer[LFS_BLOCK_SIZE];

struct lfs_file_config file_cfg = {
		.buffer = file_buffer
};

int lfs_file_open_user(lfs_t *lfs, lfs_file_t *file, const char *path, int flags) 
{
	return lfs_file_opencfg(lfs, file, path, flags, &file_cfg);
}

#endif	//---------------------USE_MID_LFS_RAM-----------------------//
