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