1 /*
2 * Copyright (c) 2022-2025, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2025-01-22 chasel first version
9 */
10
11
12 #include <rtthread.h>
13 #include "hal_flash.h"
14 #include "drv_flash.h"
15
16 #define OCFLASH_BLK_SIZE 1024
17 #define OCFLASH_LEN 1024*256
18 #define OCFLASH_ADDR 0x08000000
19
20 #ifdef OCFLASH_USE_FAL
21 #include <fal.h>
22 #endif
23
24 #ifdef OCFLASH_USE_LFS
25 #include <dfs_fs.h>
26 #define FS_PARTITION_NAME "filesystem"
27 #endif
28
init(void)29 static int init(void)
30 {
31 /* do nothing now */
32 return 0;
33 }
34
read(long offset,uint8_t * buf,size_t size)35 static int read(long offset, uint8_t *buf, size_t size)
36 {
37 size_t i;
38 uint32_t addr = OCFLASH_ADDR + offset;
39 for (i = 0; i < size; i++)
40 {
41 *buf = *(__IO uint8_t *)addr;
42 buf++;
43 addr++;
44 }
45 return size;
46 }
47
write(long offset,const uint8_t * buf,size_t size)48 static int write(long offset, const uint8_t *buf, size_t size)
49 {
50 size_t i;
51 uint32_t addr = OCFLASH_ADDR + offset;
52
53 FLASH->KEYR = 0x45670123;
54 FLASH->KEYR = 0xCDEF89AB;
55 FLASH->SR = 0x00000001 | 0x00000004 | 0x00000010;
56 FLASH->CR |= 0x1;
57
58 i = 0;
59 while (i < size)
60 {
61 *(__IO uint16_t *)addr = *buf | *(buf + 1) << 8;
62 addr = addr + 2;
63 buf += 2;
64 i += 2;
65 }
66 //Lock flash
67 FLASH->CR |= 0x00000080;
68
69 return size;
70 }
71
erase(long offset,size_t size)72 static int erase(long offset, size_t size)
73 {
74 int len;
75 RT_ASSERT(offset > 0 && offset < OCFLASH_LEN);
76 int page_addr = (offset >> 10) << 10;
77 len = size + (offset - page_addr);
78 while (len > 0)
79 {
80 FLASH_Unlock();
81 FLASH_ErasePage(page_addr);
82 FLASH_Lock();
83 len -= OCFLASH_BLK_SIZE;
84 page_addr += OCFLASH_BLK_SIZE;
85 }
86
87 return size;
88 }
89
90 #ifdef OCFLASH_USE_FAL
91 const struct fal_flash_dev mm32_onchip_flash =
92 {
93 .name = "mm32_onchip",
94 .addr = 0x08000000,
95 .len = 1024 * 512,
96 .blk_size = 1024,
97 .ops = {init, read, write, erase},
98 .write_gran = 2
99 };
100 #endif
101
flash_init(void)102 int flash_init(void)
103 {
104 #ifdef OCFLASH_USE_FAL
105 fal_init();
106 #endif
107 #ifdef OCFLASH_USE_LFS
108 struct rt_device *flash_dev = fal_mtd_nor_device_create(FS_PARTITION_NAME);
109
110 if (flash_dev == NULL)
111 {
112 rt_kprintf("Can't create a mtd device on '%s' partition.\n", FS_PARTITION_NAME);
113 }
114 else
115 {
116 rt_kprintf("Create a mtd device on the %s partition of flash successful.\n", FS_PARTITION_NAME);
117 }
118
119 if (rt_device_find(FS_PARTITION_NAME) != RT_NULL)
120 {
121 if (dfs_mount(FS_PARTITION_NAME, "/", "lfs", 0, 0) == RT_EOK)
122 {
123 rt_kprintf("onchip lfs filesystem mount to '/'\n");
124 }
125 else
126 {
127 dfs_mkfs("lfs", FS_PARTITION_NAME);
128 if (dfs_mount(FS_PARTITION_NAME, "/", "lfs", 0, 0) == RT_EOK)
129 {
130 rt_kprintf("onchip lfs filesystem mount to '/' with mkfs\n");
131 }
132 else
133 {
134 rt_kprintf("onchip lfs filesystem mount to '/' failed!\n");
135 }
136 }
137 }
138 else
139 {
140 rt_kprintf("find filesystem portion failed\r\n");
141 }
142 #endif
143 return 0;
144 }
145 INIT_APP_EXPORT(flash_init);
146