1 /*
2  * Copyright (c) 2006-2023, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author            Notes
8  * 2023-04-08     wcx1024979076     first version
9  */
10 
11 #include <rtthread.h>
12 #include <rtdevice.h>
13 #include "drv_flash.h"
14 
15 #ifdef BSP_USING_ON_CHIP_FLASH
16 
17 #define DBG_LEVEL DBG_LOG
18 #define LOG_TAG  "DRV.FLASH"
19 #include <rtdbg.h>
20 
21 #define BFLB_FLASH_START_ADRESS 0x0000000
22 #define BFLB_FLASH_END_ADDRESS  0x1000000
23 #define BFLB_FLASH_SIZE         16 * 1024 * 1024
24 #define BFLB_FLASH_PAGE_SIZE    4 * 1024
25 
_flash_read(rt_uint32_t addr,rt_uint8_t * buf,size_t size)26 int _flash_read(rt_uint32_t addr, rt_uint8_t *buf, size_t size)
27 {
28     rt_err_t result = RT_EOK;
29 
30     if ((addr + size) > BFLB_FLASH_END_ADDRESS)
31     {
32         LOG_E("read outrange flash size! addr is (0x%p)", (void *)(addr + size));
33         return -RT_EINVAL;
34     }
35 
36     result = bflb_flash_read(addr - BFLB_FLASH_START_ADRESS, buf, size);
37 
38     if(result != RT_EOK)
39     {
40         LOG_E("READ ERROR result = %d, addr = %d, addr1 = %d, len = %d", result, addr, addr - BFLB_FLASH_START_ADRESS, size);
41         return -RT_ERROR;
42     }
43     else
44     {
45         return size;
46     }
47 }
48 
_flash_write(rt_uint32_t addr,const rt_uint8_t * buf,size_t size)49 int _flash_write(rt_uint32_t addr, const rt_uint8_t *buf, size_t size)
50 {
51     rt_err_t result        = RT_EOK;
52     rt_uint32_t end_addr   = addr + size;
53 
54     if (addr % 4 != 0)
55     {
56         LOG_E("write addr must be 4-byte alignment");
57         return -RT_EINVAL;
58     }
59 
60     if ((end_addr) > BFLB_FLASH_END_ADDRESS)
61     {
62         LOG_E("write outrange flash size! addr is (0x%p)", (void *)(addr + size));
63         return -RT_EINVAL;
64     }
65 
66     result = bflb_flash_write(addr - BFLB_FLASH_START_ADRESS, buf, size);
67 
68     if(result != RT_EOK)
69     {
70         LOG_E("WRITE ERROR result = %d, addr = %d, addr1 = %d, len = %d", result, addr,  addr - BFLB_FLASH_START_ADRESS, size);
71         return -RT_ERROR;
72     }
73     else
74     {
75         return size;
76     }
77 }
78 
_flash_erase(rt_uint32_t addr,size_t size)79 int _flash_erase(rt_uint32_t addr, size_t size)
80 {
81     rt_err_t result = RT_EOK;
82     rt_uint32_t end_addr = addr + size;
83     rt_uint32_t page_addr = 0;
84 
85     if ((end_addr) > BFLB_FLASH_END_ADDRESS)
86     {
87         LOG_E("erase outrange flash size! addr is (0x%p)", (void *)(addr + size));
88         return -RT_EINVAL;
89     }
90 
91     result = bflb_flash_erase(addr - BFLB_FLASH_START_ADRESS, size);
92 
93     if (result != RT_EOK)
94     {
95         LOG_E("ERASE ERROR result = %d, addr = %d, addr1 = %d, size = %d", result, addr,  addr - BFLB_FLASH_START_ADRESS, size);
96         return -RT_ERROR;
97     }
98     else
99     {
100         return size;
101     }
102 }
103 
104 #ifdef RT_USING_FAL
105 
106 #include "fal.h"
107 
108 static int fal_flash_read(long offset, rt_uint8_t *buf, size_t size);
109 static int fal_flash_write(long offset, const rt_uint8_t *buf, size_t size);
110 static int fal_flash_erase(long offset, size_t size);
111 
112 const struct fal_flash_dev _onchip_flash =
113 {
114     "bflb_onchip",
115     BFLB_FLASH_START_ADRESS,
116     BFLB_FLASH_SIZE,
117     BFLB_FLASH_PAGE_SIZE,
118     {
119         NULL,
120         fal_flash_read,
121         fal_flash_write,
122         fal_flash_erase
123     }
124 };
125 
fal_flash_read(long offset,rt_uint8_t * buf,size_t size)126 static int fal_flash_read(long offset, rt_uint8_t *buf, size_t size)
127 {
128     return _flash_read(_onchip_flash.addr + offset, buf, size);
129 }
130 
fal_flash_write(long offset,const rt_uint8_t * buf,size_t size)131 static int fal_flash_write(long offset, const rt_uint8_t *buf, size_t size)
132 {
133     return _flash_write(_onchip_flash.addr + offset, buf, size);
134 }
135 
fal_flash_erase(long offset,size_t size)136 static int fal_flash_erase(long offset, size_t size)
137 {
138     return _flash_erase(_onchip_flash.addr + offset, size);
139 }
140 
rt_hw_on_chip_flash_init(void)141 static int rt_hw_on_chip_flash_init(void)
142 {
143     fal_init();
144     return RT_EOK;
145 }
146 INIT_COMPONENT_EXPORT(rt_hw_on_chip_flash_init);
147 
148 #endif /* RT_USING_FAL */
149 #endif /* BSP_USING_ON_CHIP_FLASH */
150