加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
tiny_kvdb_port_hc32l110.c 4.30 KB
一键复制 编辑 原始数据 按行查看 历史
/**
*******************************************************************************
* @file tiny_kvdb_port.c
* @brief port functions for tiny kvdb.
*******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "tiny_kvdb.h"
#include "flash.h"
#include "string.h"
/* Private Defines -----------------------------------------------------------*/
#define FLASH_BYPASS() M0P_FLASH->BYPASS_f.BYSEQ = 0x5A5A;\
M0P_FLASH->BYPASS_f.BYSEQ = 0xA5A5;
#define SECTOR_SIZE 512
/* Private TypeDefs ----------------------------------------------------------*/
typedef enum en_flash_lock
{
LockAll = 0x0000u,
UnlockAll = 0xFFFFu,
} en_flash_lock_t;
/* Private Macros ------------------------------------------------------------*/
/* Private Variables ---------------------------------------------------------*/
/* Extern Variables ----------------------------------------------------------*/
/* Private FunctionPrototypes ------------------------------------------------*/
/* Extern FunctionPrototypes -------------------------------------------------*/
/* Private Functions ---------------------------------------------------------*/
int flash_init (void)
{
return 1;
}
int flash_read (uint32_t addr, void * p_dst, uint32_t len)
{
uint8_t *p = p_dst;
for (uint32_t i = 0; i < len; i++, addr++, p++)
{
*p = *(uint8_t *) addr;
}
return len;
}
int flash_write (uint32_t addr, void * p_src, uint32_t len)
{
uint32_t write_addr = addr;
uint32_t data_write;
const uint8_t *p = (uint8_t *)p_src;
__disable_irq();
/* address not word-aligned */
if (write_addr & 0x03)
{
if (!(write_addr & 0x02))
{
data_write = *p + ((uint16_t)*(p+1) << 8);
Flash_WriteHalfWord(write_addr, (uint16_t)data_write);
write_addr += 2;
len -= 2;
p += 2;
}
if ((write_addr & 0x01))
{
data_write = *p;
Flash_WriteHalfWord(write_addr, (uint8_t)data_write);
write_addr += 1;
len -= 1;
p += 1;
}
}
if (len >= 4)
{
/* unlock flash */
FLASH_BYPASS();
M0P_FLASH->SLOCK_f.SLOCK = UnlockAll;
while (TRUE == M0P_FLASH->CR_f.BUSY)
{
;
}
/* set OP */
FLASH_BYPASS();
M0P_FLASH->CR_f.OP = 1;
while(len >= 4)
{
/* source address is word-aligned */
if (((uint32_t)p & 0x03) == 0)
{
data_write = *(uint32_t *)p;
}
else
{
data_write = ((uint32_t)*(p+3) << 24) + ((uint32_t)*(p+2) << 16) + ((uint32_t)*(p+1) << 8) + *p;
}
/* write data */
*((volatile uint32_t*)write_addr) = data_write;
while (TRUE == M0P_FLASH->CR_f.BUSY)
{
;
}
write_addr += 4;
len -= 4;
p += 4;
}
/* lock flash */
FLASH_BYPASS();
M0P_FLASH->SLOCK_f.SLOCK = LockAll;
}
if (len >= 2)
{
data_write = *p + ((uint16_t)*(p+1) << 8);
Flash_WriteHalfWord(write_addr, (uint16_t)data_write);
write_addr += 2;
len -= 2;
p += 2;
}
if (len != 0) /* len == 1 */
{
Flash_WriteByte(write_addr, *(uint8_t *)p);
}
__enable_irq();
return len;
}
int flash_erase (uint32_t addr, uint32_t len)
{
uint32_t start_addr = addr;
uint32_t end_addr = start_addr + len;
uint32_t sec_start_addr = start_addr & ~(SECTOR_SIZE - 1);
__disable_irq();
while (sec_start_addr < end_addr)
{
Flash_SectorErase(sec_start_addr);
sec_start_addr += SECTOR_SIZE;
}
__enable_irq();
return len;
}
tiny_db_device_t hc32l110_onchip_flash =
{
.device_id = 0x48434C31, /* HCL1 */
.start_addr = 0x0,
.max_size = 32*1024,
.sector_size= 512,
.write_unit = 2,
.init = flash_init,
.read = flash_read,
.write = flash_write,
.erase = flash_erase
};
/******************************** END OF FILE *********************************/
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化