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