336 lines
9.4 KiB
C
336 lines
9.4 KiB
C
/*----------------------------------------------------------------------------
|
||
* Copyright (c) Fenda Technologies Co., Ltd. 2020. All rights reserved.
|
||
*
|
||
* Description: flash_drv_kas041s1.c
|
||
*
|
||
* Author: saimen
|
||
*
|
||
* Create: 2021-04-27
|
||
*--------------------------------------------------------------------------*/
|
||
//lib
|
||
#include "stdlib.h"
|
||
#include "string.h"
|
||
//os
|
||
//sdk
|
||
//drv
|
||
#include "flash_port_sdio.h"
|
||
#include "flash_drv_kas041s1.h"
|
||
//user
|
||
|
||
#define ENABLE_STATIC_PRINT false
|
||
extern uint32_t flash_port_print(const char *pcFmt, ...);
|
||
#define static_print_remind(...) flash_port_print(__VA_ARGS__)
|
||
#if ENABLE_STATIC_PRINT
|
||
#define static_print_info(...) flash_port_print(__VA_ARGS__)
|
||
#else
|
||
#define static_print_info(...)
|
||
#endif
|
||
|
||
#define FLASH_KAS041S1_CHIP_ID 0x533034315331
|
||
|
||
/***************************************************************************************************/
|
||
//config
|
||
uint32_t flash_drv_kas041s1_get_chip_id(void)
|
||
{
|
||
return flash_port_get_id();
|
||
}
|
||
|
||
int flash_drv_kas041s1_open(void)
|
||
{
|
||
int ret;
|
||
flash_port_power_on();
|
||
flash_port_bus_pins_enable();
|
||
ret = flash_port_sdio_init();
|
||
return ret;
|
||
}
|
||
|
||
int flash_drv_kas041s1_close(void)
|
||
{
|
||
int ret;
|
||
//flash_port_enter_sleep();
|
||
ret = flash_port_sdio_deinit();
|
||
flash_port_bus_pins_disable();
|
||
flash_port_power_off();
|
||
return ret;
|
||
}
|
||
|
||
|
||
int flash_drv_kas041s1_enter_low_power(void)
|
||
{
|
||
return flash_port_enter_sleep();
|
||
}
|
||
|
||
int flash_drv_kas041s1_exit_low_power(void)
|
||
{
|
||
return flash_port_exit_sleep();
|
||
}
|
||
|
||
int flash_drv_kas041s1_get_status(void)
|
||
{
|
||
return true;
|
||
}
|
||
|
||
//read,write,erase
|
||
int flash_drv_kas041s1_erase_chip(void)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
int flash_drv_kas041s1_erase(uint32_t addr)
|
||
{
|
||
return flash_port_block_erase(addr/EMMC_KAS041S1_ERASE_UNIT_SIZE,1);
|
||
}
|
||
|
||
int flash_drv_kas041s1_read(uint32_t ui32_addr, uint8_t *p_data, uint32_t ui32_length)
|
||
{
|
||
int ret;
|
||
uint8_t buf[EMMC_KAS041S1_READ_UNIT_SIZE];
|
||
uint32_t blk_start,blk_end,blk_num,index;
|
||
uint16_t read_start_size = 0;
|
||
uint16_t read_end_size = 0;
|
||
uint16_t offset;
|
||
|
||
blk_start = ui32_addr/EMMC_KAS041S1_READ_UNIT_SIZE;
|
||
offset = ui32_addr%EMMC_KAS041S1_READ_UNIT_SIZE;
|
||
if(offset)
|
||
{
|
||
read_start_size = EMMC_KAS041S1_READ_UNIT_SIZE - offset;
|
||
if(read_start_size>ui32_length)
|
||
{
|
||
read_start_size = ui32_length;
|
||
}
|
||
}
|
||
else if(ui32_length<EMMC_KAS041S1_READ_UNIT_SIZE)
|
||
{
|
||
read_start_size = ui32_length;
|
||
}
|
||
|
||
blk_end = (ui32_addr + ui32_length)/EMMC_KAS041S1_READ_UNIT_SIZE;
|
||
if(blk_end>blk_start)
|
||
{
|
||
read_end_size = (ui32_addr + ui32_length)%EMMC_KAS041S1_READ_UNIT_SIZE;
|
||
}
|
||
else
|
||
{
|
||
read_end_size = 0;
|
||
}
|
||
blk_num = (ui32_length - read_start_size - read_end_size)/EMMC_KAS041S1_READ_UNIT_SIZE;
|
||
|
||
index = 0;
|
||
if(read_start_size)
|
||
{
|
||
ret = flash_port_block_rw(blk_start, 1, (uint8_t *)buf, true, false);
|
||
memcpy(p_data,&buf[offset],read_start_size);
|
||
blk_start++;
|
||
index += read_start_size;
|
||
}
|
||
|
||
if(blk_num)
|
||
{
|
||
ret = flash_port_block_rw(blk_start, blk_num, &p_data[index], true, false);
|
||
blk_start += blk_num;
|
||
index += blk_num*EMMC_KAS041S1_READ_UNIT_SIZE;
|
||
}
|
||
|
||
if(read_end_size)
|
||
{
|
||
ret = flash_port_block_rw(blk_start, 1, (uint8_t *)buf, true, false);
|
||
memcpy(&p_data[index],buf,read_end_size);
|
||
index += read_end_size;
|
||
}
|
||
if(index != ui32_length)
|
||
{
|
||
static_print_remind("error: ui32_addr %d index %d ui32_length %d\r\n",ui32_addr,index,ui32_length);
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
int flash_drv_kas041s1_write(uint32_t ui32_addr, uint8_t *p_data, uint32_t ui32_length)
|
||
{
|
||
int ret;
|
||
uint8_t buf[EMMC_KAS041S1_READ_UNIT_SIZE];
|
||
uint32_t blk_start,blk_end,blk_num,index;
|
||
uint16_t read_start_size = 0;
|
||
uint16_t read_end_size = 0;
|
||
uint16_t offset;
|
||
|
||
blk_start = ui32_addr/EMMC_KAS041S1_READ_UNIT_SIZE;
|
||
offset = ui32_addr%EMMC_KAS041S1_READ_UNIT_SIZE;
|
||
if(offset)
|
||
{
|
||
read_start_size = EMMC_KAS041S1_READ_UNIT_SIZE - offset;
|
||
if(read_start_size>ui32_length)
|
||
{
|
||
read_start_size = ui32_length;
|
||
}
|
||
}
|
||
else if(ui32_length<EMMC_KAS041S1_READ_UNIT_SIZE)
|
||
{
|
||
read_start_size = ui32_length;
|
||
}
|
||
|
||
blk_end = (ui32_addr + ui32_length)/EMMC_KAS041S1_READ_UNIT_SIZE;
|
||
if(blk_end>blk_start)
|
||
{
|
||
read_end_size = (ui32_addr + ui32_length)%EMMC_KAS041S1_READ_UNIT_SIZE;
|
||
}
|
||
else
|
||
{
|
||
read_end_size = 0;
|
||
}
|
||
blk_num = (ui32_length - read_start_size - read_end_size)/EMMC_KAS041S1_READ_UNIT_SIZE;
|
||
|
||
index = 0;
|
||
if(read_start_size)
|
||
{
|
||
ret = flash_port_block_rw(blk_start, 1, (uint8_t *)buf, true, false);
|
||
memcpy((void*)&buf[offset],p_data,read_start_size);
|
||
ret = flash_port_block_rw(blk_start, 1, (uint8_t *)buf, false, false);
|
||
blk_start++;
|
||
index += read_start_size;
|
||
}
|
||
|
||
if(blk_num)
|
||
{
|
||
ret = flash_port_block_rw(blk_start, blk_num, &p_data[index], false, false);
|
||
blk_start += blk_num;
|
||
index += blk_num*EMMC_KAS041S1_READ_UNIT_SIZE;
|
||
}
|
||
|
||
if(read_end_size)
|
||
{
|
||
ret = flash_port_block_rw(blk_start, 1, (uint8_t *)buf, true, false);
|
||
memcpy((void*)&buf,&p_data[index],read_end_size);
|
||
ret = flash_port_block_rw(blk_start, 1, (uint8_t *)buf, false, false);
|
||
index += read_end_size;
|
||
}
|
||
if(index != ui32_length)
|
||
{
|
||
static_print_remind("error: ui32_addr %d index %d ui32_length %d\r\n",ui32_addr,index,ui32_length);
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
int flash_drv_kas041s1_read_ex(uint32_t ui32_addr, uint8_t *p_data, uint32_t ui32_length)
|
||
{
|
||
int ret;
|
||
uint8_t buf[EMMC_KAS041S1_READ_UNIT_SIZE];
|
||
uint32_t blk_start,blk_end,blk_num,index;
|
||
uint16_t read_start_size = 0;
|
||
uint16_t read_end_size = 0;
|
||
uint16_t offset;
|
||
|
||
blk_start = ui32_addr/EMMC_KAS041S1_READ_UNIT_SIZE;
|
||
offset = ui32_addr%EMMC_KAS041S1_READ_UNIT_SIZE;
|
||
if(offset)
|
||
{
|
||
read_start_size = EMMC_KAS041S1_READ_UNIT_SIZE - offset;
|
||
if(read_start_size>ui32_length)
|
||
{
|
||
read_start_size = ui32_length;
|
||
}
|
||
}
|
||
else if(ui32_length<EMMC_KAS041S1_READ_UNIT_SIZE)
|
||
{
|
||
read_start_size = ui32_length;
|
||
}
|
||
|
||
blk_end = (ui32_addr + ui32_length)/EMMC_KAS041S1_READ_UNIT_SIZE;
|
||
if(blk_end>blk_start)
|
||
{
|
||
read_end_size = (ui32_addr + ui32_length)%EMMC_KAS041S1_READ_UNIT_SIZE;
|
||
}
|
||
else
|
||
{
|
||
read_end_size = 0;
|
||
}
|
||
blk_num = (ui32_length - read_start_size - read_end_size)/EMMC_KAS041S1_READ_UNIT_SIZE;
|
||
|
||
index = 0;
|
||
if(read_start_size)
|
||
{
|
||
ret = flash_port_block_rw(blk_start, 1, (uint8_t *)buf, true, false);
|
||
memcpy(p_data,&buf[offset],read_start_size);
|
||
blk_start++;
|
||
index += read_start_size;
|
||
}
|
||
|
||
if(blk_num)
|
||
{
|
||
ret = flash_port_block_rw(blk_start, blk_num, &p_data[index], true, false);
|
||
blk_start += blk_num;
|
||
index += blk_num*EMMC_KAS041S1_READ_UNIT_SIZE;
|
||
}
|
||
|
||
if(read_end_size)
|
||
{
|
||
ret = flash_port_block_rw(blk_start, 1, (uint8_t *)buf, true, false);
|
||
memcpy(&p_data[index],(void *)buf,read_end_size);
|
||
index += read_end_size;
|
||
}
|
||
if(index != ui32_length)
|
||
{
|
||
static_print_remind("error: ui32_addr %d index %d ui32_length %d\r\n",ui32_addr,index,ui32_length);
|
||
}
|
||
return ret;
|
||
}
|
||
//fs:read,write,erase
|
||
int flash_drv_kas041s1_lfs_erase(uint32_t addr)
|
||
{
|
||
return flash_port_block_erase(addr/EMMC_KAS041S1_ERASE_UNIT_SIZE,1);
|
||
}
|
||
|
||
int flash_drv_kas041s1_lfs_read(uint32_t block, uint32_t offset, uint8_t *buffer, uint32_t size)
|
||
{
|
||
int ret;
|
||
uint8_t buf[EMMC_KAS041S1_READ_UNIT_SIZE];
|
||
|
||
if(block < (EMMC_KAS041S1_FS_MEMORY_BASE/EMMC_KAS041S1_ERASE_UNIT_SIZE))
|
||
{
|
||
static_print_remind("error: flash_drv block=0x%x,offset=0x%x,size=0x%x\r\n",block,offset,size);
|
||
}
|
||
if((offset+size)<=EMMC_KAS041S1_READ_UNIT_SIZE)
|
||
{
|
||
if(offset==0&&size==EMMC_KAS041S1_READ_UNIT_SIZE)
|
||
{
|
||
ret = flash_port_block_rw(block, 1, (uint8_t *)(buffer), true, false);
|
||
}
|
||
else
|
||
{
|
||
ret = flash_port_block_rw(block, 1, (uint8_t *)buf, true, false);
|
||
memcpy(buffer,&buf[offset],size);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
static_print_remind("error: block=0x%x offset=0x%x,size=0x%x\r\n",block,offset,size);
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
int flash_drv_kas041s1_lfs_write(uint32_t block, uint32_t offset, uint8_t *buffer, uint32_t size)
|
||
{
|
||
int ret;
|
||
uint8_t buf[EMMC_KAS041S1_READ_UNIT_SIZE];
|
||
|
||
if((offset+size)<=EMMC_KAS041S1_READ_UNIT_SIZE)
|
||
{
|
||
if(offset==0&&size==EMMC_KAS041S1_READ_UNIT_SIZE)
|
||
{
|
||
ret = flash_port_block_rw(block, 1, (uint8_t *)(buffer), false, false);
|
||
}
|
||
else
|
||
{
|
||
ret = flash_port_block_rw(block, 1, (uint8_t *)buf, true, false);
|
||
memcpy((void*)&buf[offset],(uint8_t *)(buffer),size);
|
||
ret = flash_port_block_rw(block, 1, (uint8_t *)buf, false, false);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
static_print_remind("error: block=0x%x offset=0x%x,size=0x%x\r\n",block,offset,size);
|
||
}
|
||
return ret;
|
||
}
|
||
|