|
@@ -0,0 +1,137 @@
|
|
|
+/*
|
|
|
+ * 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);
|