1 /*
2 * Copyright (c) 2006-2024 RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2024-07-26 Ltbonewstart the first version
9 *
10 */
11 #include "fsl_romapi.h"
12
13 #include <rtdevice.h>
14
15 //#define DRV_DEBUG
16 #define LOG_TAG "drv.flash"
17 #include <drv_log.h>
18
19 #define SECTOR_INDEX_FROM_END 2U /* start from the last 2 Sector */
20
21 struct mcx_mtd_chipflash
22 {
23 struct rt_mtd_nor_device mtd_device;
24 struct rt_mutex flash_lock;
25 flash_config_t s_flashDriver; /* flash driver */
26 uint32_t destAdrss; /* Address of the target location */
27 uint32_t pflashBlockBase; /* 块基地址 */
28 uint32_t pflashBlockSize; /* 块大小 */
29 uint32_t pflashBlockCount; /* 块数量 */
30 uint32_t pflashTotalSize; /* 总大小 */
31 uint32_t pflashSectorSize; /* 扇区大小 */
32 uint32_t PflashPageSize; /* 页大小 */
33 };
34
35 struct mcx_mtd_chipflash mtd;
36
37 /**
38 * device MTD nor 设备句柄
39 * offset 偏移量
40 * data 读取的数据
41 * length 读取的数据长度
42 */
nxp_chipflash_read(struct rt_mtd_nor_device * device,rt_off_t offset,rt_uint8_t * data,rt_size_t length)43 rt_ssize_t nxp_chipflash_read(struct rt_mtd_nor_device *device, rt_off_t offset, rt_uint8_t *data, rt_size_t length)
44 {
45 rt_mutex_take(&mtd.flash_lock, RT_WAITING_FOREVER);
46 memcpy(data, ((const void *)(mtd.destAdrss + offset)), length);
47 rt_mutex_release(&mtd.flash_lock);
48 return length;
49 }
50
51 /**
52 * device MTD nor 设备句柄
53 * offset 偏移量
54 * data 读取的数据
55 * length 读取的数据长度
56 */
nxp_chipflash_write(struct rt_mtd_nor_device * device,rt_off_t offset,const rt_uint8_t * data,rt_size_t length)57 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)
58 {
59 rt_mutex_take(&mtd.flash_lock, RT_WAITING_FOREVER);
60 int32_t status = FLASH_ProgramPhrase(&mtd.s_flashDriver, mtd.destAdrss + offset, (uint8_t *)data, length);
61 if (status != kStatus_Success)
62 {
63 length = 0;
64 }
65 rt_mutex_release(&mtd.flash_lock);
66 return length;
67 }
68
69 /**
70 * device MTD nor 设备句柄
71 * offset 偏移量
72 * length 长度
73 */
nxp_chipflash_erase_block(struct rt_mtd_nor_device * device,rt_off_t offset,rt_size_t length)74 rt_err_t nxp_chipflash_erase_block(struct rt_mtd_nor_device *device, rt_off_t offset, rt_size_t length)
75 {
76 rt_mutex_take(&mtd.flash_lock, RT_WAITING_FOREVER);
77 FLASH_EraseSector(&mtd.s_flashDriver, mtd.destAdrss + offset, mtd.pflashSectorSize, kFLASH_ApiEraseKey);
78 rt_mutex_release(&mtd.flash_lock);
79 return RT_EOK;
80 }
81
82 struct rt_mtd_nor_driver_ops mcx_mtd_chipflashops =
83 {
84 RT_NULL,
85 nxp_chipflash_read,
86 nxp_chipflash_write,
87 nxp_chipflash_erase_block,
88 };
89
rt_onchip_flash_init(void)90 int rt_onchip_flash_init(void)
91 {
92 rt_err_t result = RT_EOK;
93
94 memset(&mtd.s_flashDriver, 0, sizeof(flash_config_t));
95 if (FLASH_Init(&mtd.s_flashDriver) != kStatus_Success)
96 {
97 result = -RT_ERROR;
98 }
99
100 /* 获取参数 */
101 FLASH_GetProperty(&mtd.s_flashDriver, kFLASH_PropertyPflashBlockBaseAddr, &mtd.pflashBlockBase);
102 FLASH_GetProperty(&mtd.s_flashDriver, kFLASH_PropertyPflashSectorSize, &mtd.pflashSectorSize);
103 FLASH_GetProperty(&mtd.s_flashDriver, kFLASH_PropertyPflashTotalSize, &mtd.pflashTotalSize);
104 FLASH_GetProperty(&mtd.s_flashDriver, kFLASH_PropertyPflashPageSize, &mtd.PflashPageSize);
105 FLASH_GetProperty(&mtd.s_flashDriver, kFLASH_PropertyPflashBlockSize, &mtd.pflashBlockSize);
106 FLASH_GetProperty(&mtd.s_flashDriver, kFLASH_PropertyPflashBlockCount, &mtd.pflashBlockCount);
107
108 LOG_D("flash_BlockBase: %d", mtd.pflashBlockBase);
109 LOG_D("flash_BlockCount: %d", mtd.pflashBlockCount);
110 LOG_D("flash_BlockSize: %d", mtd.pflashBlockSize);
111 LOG_D("flash_SectorSize: %d", mtd.pflashSectorSize);
112 LOG_D("flash_TotalSize: %d", mtd.pflashTotalSize);
113 LOG_D("flash_PageSize: %d", mtd.PflashPageSize);
114
115 /* 设置要测试flash的基地址 */
116 /* flash基地址+ flash总大小 - 数量*扇区大小 */
117 mtd.destAdrss = mtd.pflashBlockBase + (mtd.pflashTotalSize - (SECTOR_INDEX_FROM_END) * mtd.pflashSectorSize);
118 LOG_D("flash_destAdrss: %#x", mtd.destAdrss);
119
120 /* initialize mutex */
121 if (rt_mutex_init(&mtd.flash_lock, "m_flash", RT_IPC_FLAG_PRIO) != RT_EOK)
122 {
123 rt_kprintf("init mflash lock mutex failed\n");
124 return -RT_ERROR;
125 }
126
127 mtd.mtd_device.block_start = 0;
128 mtd.mtd_device.block_end = (mtd.pflashTotalSize - mtd.destAdrss) / mtd.pflashSectorSize;
129 mtd.mtd_device.block_size = mtd.pflashSectorSize;
130
131 /* set ops */
132 mtd.mtd_device.ops = &mcx_mtd_chipflashops;
133 rt_mtd_nor_register_device("mflash", &(mtd.mtd_device));
134
135 return result;
136 }
137 INIT_DEVICE_EXPORT(rt_onchip_flash_init);
138