/*
 * Copyright © 2014 Kosma Moczek <kosma@cloudyourcar.com>
 * This program is free software. It comes without any warranty, to the extent
 * permitted by applicable law. You can redistribute it and/or modify it under
 * the terms of the Do What The Fuck You Want To Public License, Version 2, as
 * published by Sam Hocevar. See the COPYING file for more details.
 */
#include "lib_ringfs.h"
#include "lib_ringfs_func.h"

#if  USE_LIB_RINGFS_W25Q==1

#include "obj_spi_w25qxx.h"
#include "obj_hal_w25qxx.h"
#include "obj_soft_w25qxx.h"
#include "func_spi_w25qxx.h"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <inttypes.h>
#ifdef FLASHSIM_LOG
#define logprintf(args...) printf(args)
#else
#define logprintf(args...) do {} while (0)
#endif

#define FLASH_W25Q_SECTOR_SIZE       4096
#define FLASH_W25Q_PARTITION_OFFSET  16
#define FLASH_W25Q_PARTITION_SIZE    6	
#define FLASH_W25Q_TOTAL_SECTORS     (FLASH_W25Q_PARTITION_OFFSET + \
																			FLASH_W25Q_PARTITION_SIZE)	
	
struct rfs_dev_w25q {
		char name[32];
    int total_size;
    int sector_size;	

};

struct rfs_dev_w25q *rfs_dev_w25q_open(const char *name, int size, int sector_size);
static ssize_t op_program(struct ringfs_flash_partition *flash, int address, const void *data, size_t size);
static ssize_t op_read(struct ringfs_flash_partition *flash, int address, void *data, size_t size);

static int op_sector_erase(struct ringfs_flash_partition *flash, int address);


struct rfs_dev_w25q  rfs_dev_w25q_obj = {0};
struct rfs_dev_w25q *h_rfs_w25q = 0;

struct ringfs_flash_partition rfs_disk_w25q = {
    .sector_size 		= FLASH_W25Q_SECTOR_SIZE,
    .sector_offset 	= FLASH_W25Q_PARTITION_OFFSET,
    .sector_count 	= FLASH_W25Q_PARTITION_SIZE,

    .sector_erase 	= op_sector_erase,
    .program 				= op_program,
    .read 					= op_read,
};




void init_flash_driver_w25q(void)
{
		if(W25QXX_ID_OK() == true)
		{
			rfs_disk_w25q.sector_size = w25qxx_obj.SectorSize;
			
			//ringfs 的扇区数量为，总扇区数减去偏移量；偏移量暂定为16个扇区
			rfs_disk_w25q.sector_count 	=  w25qxx_obj.SectorCount - rfs_disk_w25q.sector_offset;
		}
		else
		{
			return;
		}
		
#if 0	
    h_rfs_w25q = rfs_dev_w25q_open("rfs_disk.w25q",
            FLASH_W25Q_TOTAL_SECTORS*FLASH_W25Q_SECTOR_SIZE,
            FLASH_W25Q_SECTOR_SIZE);
#else		
    h_rfs_w25q = rfs_dev_w25q_open("rfs_disk.w25q",
            w25qxx_obj.SectorSize*w25qxx_obj.SectorCount,
            w25qxx_obj.SectorSize);
#endif
		
}

static int op_sector_erase(struct ringfs_flash_partition *flash, int address)
{
    (void) flash;
	
		int sector_start = address - (address % flash->sector_size);
		UNUSED(sector_start);
    logprintf("rfs_dev_w25q_erase  (0x%08x) * erasing sector at 0x%08x\n", addr, sector_start);

    W25QXX_Erase_Sector(address/4096);
    return 0;
}

static ssize_t op_program(struct ringfs_flash_partition *flash, int address, const void *data, size_t size)
{
    (void) flash;
		W25QXX_Write_NoCheck((uint8_t*)data, address, size);
    return size;
}

static ssize_t op_read(struct ringfs_flash_partition *flash, int address, void *data, size_t size)
{
    (void) flash;
		W25QXX_Read((uint8_t*)data, address, size);;
    return size;
}




struct rfs_dev_w25q *rfs_dev_w25q_open(const char *name, int size, int sector_size)
{
		func_w25q_init();
	
		func_w25q_test();
		
    struct rfs_dev_w25q *h_w25q = &rfs_dev_w25q_obj;		
		h_w25q = &rfs_dev_w25q_obj;
		
		if(strlen(name) < sizeof(rfs_dev_w25q_obj.name))
		{
			strcpy(rfs_dev_w25q_obj.name,name);
		}		
	
    h_w25q->total_size  = size;
    h_w25q->sector_size = sector_size;

    return h_w25q;
}

void rfs_dev_w25q_close(struct rfs_dev_w25q *ram)
{
		return;
}


#endif //---------------------USE_LIB_RINGFS_W25Q==1--------------------//

/* vim: set ts=4 sw=4 et: */
