1 /*
2  * Copyright (c) 2006-2021, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2021-08-05     mazhiyuan   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*512
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