1 /*
2  * Copyright (C) 2022-2024, Xiaohua Semiconductor Co., Ltd.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2022-04-28     CDT          first version
9  */
10 
11 #include <board.h>
12 #include <drv_spi.h>
13 #include <rtdevice.h>
14 #include <rthw.h>
15 #include <finsh.h>
16 #include <dfs_fs.h>
17 #include <fal.h>
18 
19 #ifdef BSP_USING_SPI_FLASH
20 
21 #include "dev_spi_flash.h"
22 #ifdef RT_USING_SFUD
23     #include "dev_spi_flash_sfud.h"
24 #endif
25 
26 #if defined(HC32F4A0) || defined(HC32F448) || defined(HC32F4A8)
27     #define SPI_BUS_NAME                "spi1"
28     #define SPI_FLASH_DEVICE_NAME       "spi10"
29     #define SPI_FLASH_CHIP              "w25q64"
30     #define SPI_FLASH_SS_PIN            GET_PIN(C, 7)
31 #elif defined(HC32F460)
32     #define SPI_BUS_NAME                "spi3"
33     #define SPI_FLASH_DEVICE_NAME       "spi30"
34     #define SPI_FLASH_CHIP              "w25q64"
35     #define SPI_FLASH_SS_PIN            GET_PIN(C, 7)
36 #elif defined(HC32F472)
37     #define SPI_BUS_NAME                "spi1"
38     #define SPI_FLASH_DEVICE_NAME       "spi10"
39     #define SPI_FLASH_CHIP              "w25q64"
40     #define SPI_FLASH_SS_PIN            GET_PIN(B,12)
41 #endif
42 #define SPI_FLASH_CMD_ENABLE_RESET      0x66
43 #define SPI_FLASH_CMD_RESET_DEVICE      0x99
44 
45 /* Partition Name */
46 #define FS_PARTITION_NAME              "filesystem"
47 
48 
49 #ifdef RT_USING_SFUD
rt_hw_spi_flash_reset(char * spi_dev_name)50 static void rt_hw_spi_flash_reset(char *spi_dev_name)
51 {
52     struct rt_spi_device *spi_dev_w25;
53     rt_uint8_t w25_en_reset = SPI_FLASH_CMD_ENABLE_RESET;
54     rt_uint8_t w25_reset_dev = SPI_FLASH_CMD_RESET_DEVICE;
55 
56     spi_dev_w25 = (struct rt_spi_device *)rt_device_find(spi_dev_name);
57     if (!spi_dev_w25)
58     {
59         rt_kprintf("Can't find %s device!\n", spi_dev_name);
60     }
61     else
62     {
63         rt_spi_send(spi_dev_w25, &w25_en_reset, 1U);
64         rt_spi_send(spi_dev_w25, &w25_reset_dev, 1U);
65         DDL_DelayMS(1U);
66         rt_kprintf("Reset ext flash!\n");
67     }
68 }
69 
rt_hw_spi_flash_with_sfud_init(void)70 static int rt_hw_spi_flash_with_sfud_init(void)
71 {
72     rt_hw_spi_device_attach(SPI_BUS_NAME, SPI_FLASH_DEVICE_NAME, SPI_FLASH_SS_PIN);
73 
74     if (RT_NULL == rt_sfud_flash_probe(SPI_FLASH_CHIP, SPI_FLASH_DEVICE_NAME))
75     {
76         rt_hw_spi_flash_reset(SPI_FLASH_DEVICE_NAME);
77         if (RT_NULL == rt_sfud_flash_probe(SPI_FLASH_CHIP, SPI_FLASH_DEVICE_NAME))
78         {
79             return -RT_ERROR;
80         }
81     }
82 
83     return RT_EOK;
84 }
85 INIT_COMPONENT_EXPORT(rt_hw_spi_flash_with_sfud_init);
86 
rt_hw_fs_init(void)87 static int rt_hw_fs_init(void)
88 {
89     struct rt_device *mtd_dev = RT_NULL;
90 
91     /* 初始化 fal */
92     fal_init();
93     /* 生成 mtd 设备 */
94     mtd_dev = fal_mtd_nor_device_create(FS_PARTITION_NAME);
95     if (!mtd_dev)
96     {
97         LOG_E("Can't create a mtd device on '%s' partition.", FS_PARTITION_NAME);
98         return -RT_ERROR;
99     }
100     else
101     {
102         /* 挂载 littlefs */
103         if (RT_EOK == dfs_mount(FS_PARTITION_NAME, "/", "lfs", 0, 0))
104         {
105             LOG_I("Filesystem initialized!");
106             return RT_EOK;
107         }
108         else
109         {
110             /* 格式化文件系统 */
111             if (RT_EOK == dfs_mkfs("lfs", FS_PARTITION_NAME))
112             {
113                 /* 挂载 littlefs */
114                 if (RT_EOK == dfs_mount(FS_PARTITION_NAME, "/", "lfs", 0, 0))
115                 {
116                     LOG_I("Filesystem initialized!");
117                     return RT_EOK;
118                 }
119                 else
120                 {
121                     LOG_E("Failed to initialize filesystem!");
122                     return -RT_ERROR;
123                 }
124             }
125             else
126             {
127                 LOG_E("Failed to Format fs!");
128                 return -RT_ERROR;
129             }
130         }
131     }
132 }
133 INIT_APP_EXPORT(rt_hw_fs_init);
134 
135 #endif /* RT_USING_SFUD */
136 
137 #endif /* BSP_USING_SPI_FLASH */
138