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 * 2018-05-17 armink the first version
9 */
10
11 #include <fal.h>
12 #include <string.h>
13
14 #define DBG_TAG "FAL"
15 #ifdef FAL_USING_DEBUG
16 #define DBG_LVL DBG_LOG
17 #else
18 #define DBG_LVL DBG_WARNING
19 #endif
20 #include <rtdbg.h>
21
22 /* flash device table, must defined by user */
23 #if !defined(FAL_FLASH_DEV_TABLE)
24 #error "You must defined flash device table (FAL_FLASH_DEV_TABLE) on 'fal_cfg.h'"
25 #endif
26
27 static const struct fal_flash_dev * const device_table[] = FAL_FLASH_DEV_TABLE;
28 static const rt_size_t device_table_len = sizeof(device_table) / sizeof(device_table[0]);
29 static rt_uint8_t init_ok = 0;
30
31 /**
32 * Initialize all flash device on FAL flash table
33 *
34 * @return result
35 */
fal_flash_init(void)36 int fal_flash_init(void)
37 {
38 rt_size_t i, j, offset;
39
40 if (init_ok)
41 {
42 return 0;
43 }
44
45 for (i = 0; i < device_table_len; i++)
46 {
47 RT_ASSERT(device_table[i]->ops.read);
48 RT_ASSERT(device_table[i]->ops.write);
49 RT_ASSERT(device_table[i]->ops.erase);
50 /* init flash device on flash table */
51 if (device_table[i]->ops.init)
52 {
53 device_table[i]->ops.init();
54 }
55 LOG_D("Flash device | %*.*s | addr: 0x%08lx | len: 0x%08x | blk_size: 0x%08x |initialized finish.",
56 FAL_DEV_NAME_MAX, FAL_DEV_NAME_MAX, device_table[i]->name, device_table[i]->addr, device_table[i]->len,
57 device_table[i]->blk_size);
58 offset = 0;
59 for (j = 0; j < FAL_DEV_BLK_MAX; j ++)
60 {
61 const struct flash_blk *blk = &device_table[i]->blocks[j];
62 rt_size_t blk_len = blk->count * blk->size;
63 if (blk->count == 0 || blk->size == 0)
64 break;
65
66 if(offset > device_table[i]->len)
67 {
68 LOG_I("Flash device %*.*s: add block failed, offset %d > len %d.",
69 FAL_DEV_NAME_MAX, FAL_DEV_NAME_MAX, device_table[i]->name, device_table[i]->addr, offset, device_table[i]->len);
70 break;
71 }
72
73 LOG_D(" blk%2d | addr: 0x%08lx | len: 0x%08x | blk_size: 0x%08x |initialized finish.",
74 j, device_table[i]->addr + offset, blk_len, blk->size);
75 offset += blk_len;
76 }
77 }
78
79 init_ok = 1;
80 return 0;
81 }
82
83 /**
84 * find flash device by name
85 *
86 * @param name flash device name
87 *
88 * @return != NULL: flash device
89 * NULL: not found
90 */
fal_flash_device_find(const char * name)91 const struct fal_flash_dev *fal_flash_device_find(const char *name)
92 {
93 RT_ASSERT(init_ok);
94 RT_ASSERT(name);
95
96 rt_size_t i;
97
98 for (i = 0; i < device_table_len; i++)
99 {
100 if (!strncmp(name, device_table[i]->name, FAL_DEV_NAME_MAX)) {
101 return device_table[i];
102 }
103 }
104
105 return NULL;
106 }
107