rt-thread-official/bsp/nxp/mcx/mcxa/Libraries/drivers/drv_chipflash.c

138 lines
4.4 KiB
C
Raw Normal View History

/*
* Copyright (c) 2006-2024 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2024-07-26 Ltbonewstart the first version
*
*/
#include "fsl_romapi.h"
#include <rtdevice.h>
//#define DRV_DEBUG
#define LOG_TAG "drv.flash"
#include <drv_log.h>
#define SECTOR_INDEX_FROM_END 2U /* start from the last 2 Sector */
struct mcx_mtd_chipflash
{
struct rt_mtd_nor_device mtd_device;
struct rt_mutex flash_lock;
flash_config_t s_flashDriver; /* flash driver */
uint32_t destAdrss; /* Address of the target location */
uint32_t pflashBlockBase; /* 块基地址 */
uint32_t pflashBlockSize; /* 块大小 */
uint32_t pflashBlockCount; /* 块数量 */
uint32_t pflashTotalSize; /* 总大小 */
uint32_t pflashSectorSize; /* 扇区大小 */
uint32_t PflashPageSize; /* 页大小 */
};
struct mcx_mtd_chipflash mtd;
/**
* device MTD nor
* offset
* data
* length
*/
rt_ssize_t nxp_chipflash_read(struct rt_mtd_nor_device *device, rt_off_t offset, rt_uint8_t *data, rt_size_t length)
{
rt_mutex_take(&mtd.flash_lock, RT_WAITING_FOREVER);
memcpy(data, ((const void *)(mtd.destAdrss + offset)), length);
rt_mutex_release(&mtd.flash_lock);
return length;
}
/**
* device MTD nor
* offset
* data
* length
*/
rt_ssize_t nxp_chipflash_write(struct rt_mtd_nor_device *device, rt_off_t offset, const rt_uint8_t *data, rt_size_t length)
{
rt_mutex_take(&mtd.flash_lock, RT_WAITING_FOREVER);
int32_t status = FLASH_ProgramPhrase(&mtd.s_flashDriver, mtd.destAdrss + offset, (uint8_t *)data, length);
if (status != kStatus_Success)
{
length = 0;
}
rt_mutex_release(&mtd.flash_lock);
return length;
}
/**
* device MTD nor
* offset
* length
*/
rt_err_t nxp_chipflash_erase_block(struct rt_mtd_nor_device *device, rt_off_t offset, rt_size_t length)
{
rt_mutex_take(&mtd.flash_lock, RT_WAITING_FOREVER);
FLASH_EraseSector(&mtd.s_flashDriver, mtd.destAdrss + offset, mtd.pflashSectorSize, kFLASH_ApiEraseKey);
rt_mutex_release(&mtd.flash_lock);
return RT_EOK;
}
struct rt_mtd_nor_driver_ops mcx_mtd_chipflashops =
{
RT_NULL,
nxp_chipflash_read,
nxp_chipflash_write,
nxp_chipflash_erase_block,
};
int rt_onchip_flash_init(void)
{
rt_err_t result = RT_EOK;
memset(&mtd.s_flashDriver, 0, sizeof(flash_config_t));
if (FLASH_Init(&mtd.s_flashDriver) != kStatus_Success)
{
result = -RT_ERROR;
}
/* 获取参数 */
FLASH_GetProperty(&mtd.s_flashDriver, kFLASH_PropertyPflashBlockBaseAddr, &mtd.pflashBlockBase);
FLASH_GetProperty(&mtd.s_flashDriver, kFLASH_PropertyPflashSectorSize, &mtd.pflashSectorSize);
FLASH_GetProperty(&mtd.s_flashDriver, kFLASH_PropertyPflashTotalSize, &mtd.pflashTotalSize);
FLASH_GetProperty(&mtd.s_flashDriver, kFLASH_PropertyPflashPageSize, &mtd.PflashPageSize);
FLASH_GetProperty(&mtd.s_flashDriver, kFLASH_PropertyPflashBlockSize, &mtd.pflashBlockSize);
FLASH_GetProperty(&mtd.s_flashDriver, kFLASH_PropertyPflashBlockCount, &mtd.pflashBlockCount);
LOG_D("flash_BlockBase: %d", mtd.pflashBlockBase);
LOG_D("flash_BlockCount: %d", mtd.pflashBlockCount);
LOG_D("flash_BlockSize: %d", mtd.pflashBlockSize);
LOG_D("flash_SectorSize: %d", mtd.pflashSectorSize);
LOG_D("flash_TotalSize: %d", mtd.pflashTotalSize);
LOG_D("flash_PageSize: %d", mtd.PflashPageSize);
/* 设置要测试flash的基地址 */
/* flash基地址+ flash总大小 - 数量*扇区大小 */
mtd.destAdrss = mtd.pflashBlockBase + (mtd.pflashTotalSize - (SECTOR_INDEX_FROM_END) * mtd.pflashSectorSize);
LOG_D("flash_destAdrss: %#x", mtd.destAdrss);
/* initialize mutex */
if (rt_mutex_init(&mtd.flash_lock, "m_flash", RT_IPC_FLAG_PRIO) != RT_EOK)
{
rt_kprintf("init mflash lock mutex failed\n");
return -RT_ERROR;
}
mtd.mtd_device.block_start = 0;
mtd.mtd_device.block_end = (mtd.pflashTotalSize - mtd.destAdrss) / mtd.pflashSectorSize;
mtd.mtd_device.block_size = mtd.pflashSectorSize;
/* set ops */
mtd.mtd_device.ops = &mcx_mtd_chipflashops;
rt_mtd_nor_register_device("mflash", &(mtd.mtd_device));
return result;
}
INIT_DEVICE_EXPORT(rt_onchip_flash_init);