/*---------------------------------------------------------------------------- * Copyright (c) Fenda Technologies Co., Ltd. 2020. All rights reserved. * * Description: flash_api.c * * Author: saimen * * Create: 2020-09-25 *--------------------------------------------------------------------------*/ //lib #include "stdlib.h" #include //os //sdk //drv //#include "flash_port_mspi.h" #include "flash_port_sdio.h" #include "flash_drv_kas041s1.h" #include "flash_api.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_MX25U51245G_CHIP_ID 0xC2253A #define FLASH_DS35M_CHIP_ID 0xF1 #define FLASH_EMMC_KOWIN4G_CHIP_ID 0X30343153 typedef struct { uint32_t type; /* nor,nand,emmc */ uint32_t count; uint32_t chip_id; uint32_t total_size; uint32_t erase_unit_size; uint32_t read_unit_size; uint32_t write_unit_size; uint32_t spare_unit_size; uint32_t fs_memory_base; uint32_t fs_memory_size; uint32_t fs_unit_base; uint32_t (*get_chip_id) (void); uint32_t (*get_expect_id) (void); uint32_t (*get_total_size) (void); uint32_t (*get_read_unit_size) (void); uint32_t (*get_write_unit_size) (void); uint32_t (*get_erase_unit_size) (void); uint32_t (*get_spare_unit_size) (void); int (*deinit) (void); int (*open) (void); int (*close) (void); int (*get_status) (void); int (*enter_low_power) (void); int (*exit_low_power) (void); int (*erase_chip) (void); int (*erase) (uint32_t ui32_addr); int (*read) (uint32_t ui32_addr, uint8_t *p_data, uint32_t ui32_length); int (*write) (uint32_t ui32_addr, uint8_t *p_data, uint32_t ui32_length); int (*read_ex) (uint32_t ui32_addr, uint8_t *p_data, uint32_t ui32_length); //lfs int (*lfs_erase) (uint32_t block); int (*lfs_read) (uint32_t block, uint32_t offset, uint8_t *buffer, uint32_t size); int (*lfs_write) (uint32_t block, uint32_t offset, uint8_t *buffer, uint32_t size); //yaffs int (*yaffs_erase) (uint32_t ui32_addr); int (*yaffs_read) (uint32_t page_offset, uint16_t addr_offset, uint8_t *out_data, uint16_t len); int (*yaffs_write) (uint32_t page_offset, uint16_t addr_offset, uint8_t *in_data, uint16_t len); int (*yaffs_switch_ecc) (bool sw); }flash_info; static flash_info g_flash_info = {0}; /*-------------------------------*/ // //共用接口 // /*-------------------------------*/ void flash_api_create_lock(void) { flash_port_create_mutex(); } void flash_api_null_function(void) { g_flash_info.count++; } int flash_api_init(void) { uint32_t u32_id; uint8_t i=0; g_flash_info.chip_id = NULL; flash_port_mutex_lock(); for(i=0;i<3;i++) { #if 0 if (g_flash_info.chip_id == NULL) { flash_drv_mx25u512_info_init(flash_port_transfer_cb); flash_drv_mx25u512_open(); u32_id = flash_drv_mx25u512_read_id(); if(u32_id == FLASH_MX25U51245G_CHIP_ID) { g_flash_info.type = FLASH_TYPE_NOR; g_flash_info.chip_id = u32_id; g_flash_info.get_chip_id = flash_drv_mx25u512_read_id; g_flash_info.total_size = MX25U51245G_TOTAL_SIZE; g_flash_info.erase_unit_size = MX25U51245G_SECTOR_SIZE; g_flash_info.read_unit_size = MX25U51245G_PAGE_SIZE; g_flash_info.write_unit_size = MX25U51245G_PAGE_SIZE; g_flash_info.spare_unit_size = 0; g_flash_info.fs_memory_base = MX25U51245G_FS_BASE_SECTOR*MX25U51245G_SECTOR_SIZE; g_flash_info.fs_memory_size = MX25U51245G_FS_SECTORS*MX25U51245G_SECTOR_SIZE; g_flash_info.open = flash_drv_mx25u512_open; g_flash_info.close = flash_drv_mx25u512_close; g_flash_info.get_status = flash_drv_mx25u512_read_status; g_flash_info.enter_low_power = flash_drv_mx25u512_enter_power_down; g_flash_info.exit_low_power = flash_drv_mx25u512_exit_power_down; g_flash_info.erase_chip = flash_drv_mx25u512_chip_erase; g_flash_info.erase = flash_drv_mx25u512_sector_erase; g_flash_info.read = flash_drv_mx25u512_read_nonblocking; g_flash_info.write = flash_drv_mx25u512_write_nonblocking; g_flash_info.read_ex = flash_drv_mx25u512_read_nonblocking_ex; g_flash_info.lfs_erase = flash_drv_mx25u512_sector_erase; g_flash_info.lfs_read = flash_drv_mx25u512_read_nonblocking; g_flash_info.lfs_write = flash_drv_mx25u512_write_nonblocking; g_flash_info.yaffs_erase = NULL; g_flash_info.yaffs_read = NULL; g_flash_info.yaffs_write = NULL; g_flash_info.yaffs_switch_ecc =NULL; break; } else { flash_drv_mx25u512_close(); } static_print_remind("flash_drv_mx25u512_read_id: 0X%X\r\n",u32_id); } if (g_flash_info.chip_id == NULL) { Ds35m_Init(); Ds35m_ReadId(&u16_id); if(u16_id == FLASH_DS35M_CHIP_ID) { g_flash_info.chip_id = (uint32_t)(u16_id); g_flash_info.type = FLASH_TYPE_NAND; break; } else { Ds35m_Deinit(); } static_print_remind("Ds35m_ReadId:0X%X\r\n",u16_id); } #endif if (g_flash_info.chip_id == NULL) { flash_drv_kas041s1_open(); u32_id = flash_drv_kas041s1_get_chip_id(); if(u32_id == FLASH_EMMC_KOWIN4G_CHIP_ID) { g_flash_info.type = FLASH_TYPE_EMMC; g_flash_info.chip_id = u32_id; g_flash_info.get_chip_id = flash_drv_kas041s1_get_chip_id; g_flash_info.total_size = EMMC_KAS041S1_TOTAL_SIZE; g_flash_info.erase_unit_size = EMMC_KAS041S1_ERASE_UNIT_SIZE; g_flash_info.read_unit_size = EMMC_KAS041S1_READ_UNIT_SIZE; g_flash_info.write_unit_size = EMMC_KAS041S1_WRITE_UNIT_SIZE; g_flash_info.spare_unit_size = 0; g_flash_info.fs_memory_base = EMMC_KAS041S1_FS_MEMORY_BASE; g_flash_info.fs_memory_size = EMMC_KAS041S1_FS_MEMORY_SIZE; g_flash_info.fs_unit_base = (EMMC_KAS041S1_FS_MEMORY_BASE/EMMC_KAS041S1_ERASE_UNIT_SIZE); g_flash_info.open = flash_drv_kas041s1_open; g_flash_info.close = flash_drv_kas041s1_close; g_flash_info.get_status = flash_drv_kas041s1_get_status; g_flash_info.enter_low_power = flash_drv_kas041s1_enter_low_power; g_flash_info.exit_low_power = flash_drv_kas041s1_exit_low_power; g_flash_info.erase_chip = flash_drv_kas041s1_erase_chip; g_flash_info.erase = flash_drv_kas041s1_erase; g_flash_info.read = flash_drv_kas041s1_read; g_flash_info.write = flash_drv_kas041s1_write; g_flash_info.read_ex = flash_drv_kas041s1_read_ex; g_flash_info.lfs_erase = flash_drv_kas041s1_lfs_erase; g_flash_info.lfs_read = flash_drv_kas041s1_lfs_read; g_flash_info.lfs_write = flash_drv_kas041s1_lfs_write; g_flash_info.yaffs_erase = NULL; g_flash_info.yaffs_read = NULL; g_flash_info.yaffs_write = NULL; g_flash_info.yaffs_switch_ecc =NULL; break; } else { flash_drv_kas041s1_close(); } static_print_remind("emmc_read_id: 0X%X\r\n",u32_id); } } flash_port_mutex_unlock(); static_print_remind("flash_id: 0X%X\r\n",g_flash_info.chip_id); return g_flash_info.chip_id; } int flash_api_deinit(void) { flash_port_mutex_lock(); if(g_flash_info.deinit) { g_flash_info.deinit(); } flash_port_mutex_unlock(); return true; } int flash_api_open(void) { flash_port_mutex_lock(); if(g_flash_info.open) { g_flash_info.open(); } flash_port_mutex_unlock(); return 0; } int flash_api_close(void) { flash_port_mutex_lock(); if(g_flash_info.close) { g_flash_info.close(); } flash_port_mutex_unlock(); return 0; } uint32_t flash_api_get_status(void) { if(g_flash_info.get_status) { return g_flash_info.get_status(); } return false; } int flash_api_enter_low_power(void) { flash_port_mutex_lock(); if(g_flash_info.enter_low_power) { g_flash_info.enter_low_power(); } flash_port_mutex_unlock(); return true; } int flash_api_exit_low_power(void) { flash_port_mutex_lock(); if(g_flash_info.exit_low_power) { g_flash_info.exit_low_power(); } flash_port_mutex_unlock(); return true; } uint32_t flash_api_get_chip_id(void) { uint32_t u32_ret = 0; flash_port_mutex_lock(); if(g_flash_info.get_chip_id) { u32_ret = g_flash_info.get_chip_id(); } flash_port_mutex_unlock(); return u32_ret; } uint32_t flash_api_get_expect_id(void) { return g_flash_info.chip_id; } uint32_t flash_api_get_type(void) { return g_flash_info.type; } uint32_t flash_api_get_total_size(void) { return g_flash_info.total_size; } uint32_t flash_api_get_read_unit_size(void) { return g_flash_info.read_unit_size; } uint32_t flash_api_get_write_unit_size(void) { return g_flash_info.write_unit_size; } uint32_t flash_api_get_erase_unit_size(void) { return g_flash_info.erase_unit_size; } uint32_t flash_api_get_spare_unit_size(void) { return g_flash_info.spare_unit_size; } int flash_api_erase_chip(void) { uint32_t u32_ret = 0; flash_port_mutex_lock(); if(g_flash_info.erase_chip) { u32_ret = g_flash_info.erase_chip(); } flash_port_mutex_unlock(); return u32_ret; } int flash_api_erase(uint32_t ui32_addr) { uint32_t u32_ret = 0; flash_port_mutex_lock(); if(g_flash_info.erase) { u32_ret = g_flash_info.erase(ui32_addr); } flash_port_mutex_unlock(); return u32_ret; } int flash_api_read_ex(uint32_t ui32_addr, void *p_data, uint32_t ui32_length) { uint32_t u32_ret = 0; flash_port_mutex_lock(); if(g_flash_info.read_ex) { u32_ret = g_flash_info.read_ex(ui32_addr, p_data, ui32_length); } flash_port_mutex_unlock(); return u32_ret; } int flash_api_read(uint32_t ui32_addr, void *p_data, uint32_t ui32_length) { uint32_t u32_ret = 0; flash_port_mutex_lock(); if(g_flash_info.read) { u32_ret = g_flash_info.read(ui32_addr, p_data, ui32_length); } flash_port_mutex_unlock(); return u32_ret; } int flash_api_write(uint32_t ui32_addr, void *p_data, uint32_t ui32_length) { uint32_t u32_ret = 0; flash_port_mutex_lock(); if(g_flash_info.write) { u32_ret = g_flash_info.write(ui32_addr, p_data, ui32_length); } flash_port_mutex_unlock(); return u32_ret; } uint32_t flash_api_get_fs_memory_base(void) { return g_flash_info.fs_memory_base; } uint32_t flash_api_get_fs_memory_size(void) { return g_flash_info.fs_memory_size; } /*-------------------------------*/ // //api lfs // /*-------------------------------*/ int flash_api_lfs_erase(void *c, uint32_t block) { uint32_t u32_ret = 0; flash_port_mutex_lock(); if(g_flash_info.lfs_erase) { u32_ret = g_flash_info.lfs_erase((block+g_flash_info.fs_unit_base)*g_flash_info.erase_unit_size); } flash_port_mutex_unlock(); return u32_ret; } int flash_api_lfs_read(void *c, uint32_t block, uint32_t offset, void *buffer, uint32_t size) { uint32_t u32_ret = 0; flash_port_mutex_lock(); if(g_flash_info.lfs_read) { u32_ret = g_flash_info.lfs_read((block+g_flash_info.fs_unit_base), offset, buffer, size); } flash_port_mutex_unlock(); return u32_ret; } int flash_api_lfs_write(void *c, uint32_t block, uint32_t offset, void *buffer, uint32_t size) { uint32_t u32_ret = 0; flash_port_mutex_lock(); if(g_flash_info.lfs_write) { u32_ret = g_flash_info.lfs_write((block+g_flash_info.fs_unit_base), offset, buffer, size); } flash_port_mutex_unlock(); return u32_ret; } /*-------------------------------*/ // //api yaffs // /*-------------------------------*/ int flash_api_yaffs_erase(uint32_t ui32_addr) { uint32_t u32_ret = 0; flash_port_mutex_lock(); if(g_flash_info.yaffs_erase) { u32_ret = g_flash_info.yaffs_erase(ui32_addr+g_flash_info.fs_unit_base); } flash_port_mutex_unlock(); return u32_ret; } int flash_api_yaffs_read(uint32_t page_offset, uint16_t addr_offset, uint8_t *buffer, uint16_t len) { uint32_t u32_ret = 0; flash_port_mutex_lock(); if(g_flash_info.yaffs_read) { u32_ret = g_flash_info.yaffs_read(page_offset+g_flash_info.fs_unit_base, addr_offset, buffer, len); } flash_port_mutex_unlock(); return u32_ret; } int flash_api_yaffs_write(uint32_t page_offset, uint16_t addr_offset, uint8_t *buffer, uint16_t len) { uint32_t u32_ret = 0; flash_port_mutex_lock(); if(g_flash_info.yaffs_write) { u32_ret = g_flash_info.yaffs_write(page_offset+g_flash_info.fs_unit_base, addr_offset, buffer, len); } flash_port_mutex_unlock(); return u32_ret; } int flash_api_yaffs_switch_ecc(bool sw) { uint32_t u32_ret = 0; flash_port_mutex_lock(); if(g_flash_info.yaffs_switch_ecc) { u32_ret = g_flash_info.yaffs_switch_ecc(sw); } flash_port_mutex_unlock(); return u32_ret; } //api test void flash_api_test (void) { #if 1 #define BLK_NUM 2 #define BUF_LEN 512*BLK_NUM uint8_t buffer_wr[BUF_LEN] __attribute__((aligned(8))); uint8_t buffer_rd[BUF_LEN] __attribute__((aligned(8))); uint32_t u32_addr = 0x0; #endif for (int i = 0; i < BUF_LEN; i++) { buffer_wr[i] = i % 256; } for(uint8_t i=0;i<2;i++) { flash_port_delay_ms(100); static_print_remind("FLASH CHIP ID = 0x%x \r\n",flash_api_get_chip_id()); static_print_remind("\r\n flash_api_write \r\n"); flash_api_write(u32_addr, (uint8_t *)buffer_wr, BUF_LEN); memset((void *)buffer_rd, 0x0, BUF_LEN); flash_api_read(u32_addr, (uint8_t *)buffer_rd, BUF_LEN); static_print_remind("%02x %02x %02x %02x\r\n",buffer_rd[0],buffer_rd[1],buffer_rd[2],buffer_rd[3]); static_print_remind("%02x %02x %02x %02x\r\n",buffer_rd[4],buffer_rd[5],buffer_rd[6],buffer_rd[7]); static_print_remind("\r\n flash_api_erase \r\n"); flash_api_erase(u32_addr); memset((void *)buffer_rd, 0x0, BUF_LEN); flash_api_read(u32_addr, (uint8_t *)buffer_rd, BUF_LEN); static_print_remind("%02x %02x %02x %02x\r\n",buffer_rd[0],buffer_rd[1],buffer_rd[2],buffer_rd[3]); static_print_remind("%02x %02x %02x %02x\r\n",buffer_rd[4],buffer_rd[5],buffer_rd[6],buffer_rd[7]); static_print_remind("============================================================\r\n"); } }