mcu_hi3321_watch/tjd/driver/nandflash/flash_drv_kas041s1.c
2025-05-26 20:15:20 +08:00

336 lines
9.4 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*----------------------------------------------------------------------------
* 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;
}
//fsread,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;
}