1+ /* mbed Microcontroller Library 
2+  * SPDX-License-Identifier: BSD-3-Clause 
3+  ****************************************************************************** 
4+  * 
5+  * Copyright (c) 2015-2020 STMicroelectronics. 
6+  * All rights reserved. 
7+  * 
8+  * This software component is licensed by ST under BSD 3-Clause license, 
9+  * the "License"; You may not use this file except in compliance with the 
10+  * License. You may obtain a copy of the License at: 
11+  *                        opensource.org/licenses/BSD-3-Clause 
12+  * 
13+  ****************************************************************************** 
14+  */ 
15+ 
16+ #include  "flash_api.h" 
17+ #include  "platform/mbed_critical.h" 
18+ 
19+ #if  DEVICE_FLASH 
20+ #include  "mbed_assert.h" 
21+ #include  "cmsis.h" 
22+ 
23+ /** 
24+   * @brief  Gets the bank of a given address 
25+   * @param  Addr: Address of the FLASH Memory 
26+   * @retval The bank of a given address 
27+   */ 
28+ static  uint32_t  GetBank (uint32_t  Addr )
29+ {
30+     uint32_t  bank  =  0 ;
31+ 
32+     if  (Addr  <  (FLASH_BASE  +  FLASH_BANK_SIZE )) {
33+         bank  =  FLASH_BANK_1 ;
34+     } else  {
35+         bank  =  FLASH_BANK_2 ;
36+     }
37+ 
38+     return  bank ;
39+ }
40+ 
41+ /** 
42+   * @brief  Gets the sector of a given address 
43+   * @param  Address: Flash address 
44+   * @retval The sector of a given address 
45+   */ 
46+ static  uint32_t  GetSector (uint32_t  Address )
47+ {
48+     uint32_t  sector  =  0 ;
49+ 
50+     if  (Address  <  (FLASH_BASE  +  FLASH_BANK_SIZE )) {
51+         sector  =  (Address  -  FLASH_BASE ) / FLASH_SECTOR_SIZE ;
52+     } else  {
53+         sector  =  (Address  -  (FLASH_BASE  +  FLASH_BANK_SIZE )) / FLASH_SECTOR_SIZE ;
54+     }
55+ 
56+     return  sector ;
57+ }
58+ 
59+ /** Initialize the flash peripheral and the flash_t object 
60+  * 
61+  * @param obj The flash object 
62+  * @return 0 for success, -1 for error 
63+  */ 
64+ int32_t  flash_init (flash_t  * obj )
65+ {
66+     return  0 ;
67+ }
68+ 
69+ /** Uninitialize the flash peripheral and the flash_t object 
70+  * 
71+  * @param obj The flash object 
72+  * @return 0 for success, -1 for error 
73+  */ 
74+ int32_t  flash_free (flash_t  * obj )
75+ {
76+     return  0 ;
77+ }
78+ 
79+ /** Erase one sector starting at defined address 
80+  * 
81+  * The address should be at sector boundary. This function does not do any check for address alignments 
82+  * @param obj The flash object 
83+  * @param address The sector starting address 
84+  * @return 0 for success, -1 for error 
85+  */ 
86+ int32_t  flash_erase_sector (flash_t  * obj , uint32_t  address )
87+ {
88+     uint32_t  PAGEError  =  0 ;
89+     FLASH_EraseInitTypeDef  EraseInitStruct ;
90+     int32_t  status  =  0 ;
91+ 
92+     if  ((address  >= (FLASH_BASE  +  FLASH_SIZE )) ||  (address  <  FLASH_BASE )) {
93+         return  -1 ;
94+     }
95+ 
96+     if  (HAL_FLASH_Unlock () !=  HAL_OK ) {
97+         return  -1 ;
98+     }
99+ 
100+     if  (HAL_ICACHE_Disable () !=  HAL_OK )
101+     {
102+         return  -1 ;
103+     }
104+ 
105+     core_util_critical_section_enter ();
106+ 
107+     /* Clear error programming flags */ 
108+     __HAL_FLASH_CLEAR_FLAG (FLASH_FLAG_ALL_ERRORS );
109+ 
110+     /* MBED HAL erases 1 page  / sector at a time */ 
111+     /* Fill EraseInit structure*/ 
112+     EraseInitStruct .TypeErase    =  FLASH_TYPEERASE_SECTORS ;
113+     EraseInitStruct .Banks        =  GetBank (address );
114+     EraseInitStruct .Sector       =  GetSector (address );
115+     EraseInitStruct .NbSectors    =  1 ;
116+ 
117+     if  (HAL_FLASHEx_Erase (& EraseInitStruct , & PAGEError ) !=  HAL_OK ) {
118+         status  =  -1 ;
119+     }
120+ 
121+     core_util_critical_section_exit ();
122+ 
123+     if  (HAL_ICACHE_Enable () !=  HAL_OK )
124+     {
125+         return  -1 ;
126+     }
127+ 
128+     if  (HAL_FLASH_Lock () !=  HAL_OK ) {
129+         return  -1 ;
130+     }
131+ 
132+     return  status ;
133+ }
134+ 
135+ /** Program one page starting at defined address 
136+  * 
137+  * The page should be at page boundary, should not cross multiple sectors. 
138+  * This function does not do any check for address alignments or if size 
139+  * is aligned to a page size. 
140+  * @param obj The flash object 
141+  * @param address The sector starting address 
142+  * @param data The data buffer to be programmed 
143+  * @param size The number of bytes to program 
144+  * @return 0 for success, -1 for error 
145+  */ 
146+ int32_t  flash_program_page (flash_t  * obj , uint32_t  address ,
147+                            const  uint8_t  * data , uint32_t  size )
148+ {
149+     uint32_t  StartAddress  =  0 ;
150+     int32_t  status  =  0 ;
151+ 
152+     if  ((address  >= (FLASH_BASE  +  FLASH_SIZE )) ||  (address  <  FLASH_BASE )) {
153+         return  -1 ;
154+     }
155+ 
156+     if  ((size  % 16 ) !=  0 ) {
157+         /* H5 flash devices can only be programmed 128bits/16 bytes at a time */ 
158+         return  -1 ;
159+     }
160+ 
161+     if  (HAL_FLASH_Unlock () !=  HAL_OK ) {
162+         return  -1 ;
163+     }
164+ 
165+     if  (HAL_ICACHE_Disable () !=  HAL_OK )
166+     {
167+         return  -1 ;
168+     }
169+ 
170+     /* Clear error programming flags */ 
171+     __HAL_FLASH_CLEAR_FLAG (FLASH_FLAG_ALL_ERRORS );
172+ 
173+     /* Program the user Flash area word by word */ 
174+     StartAddress  =  address ;
175+ 
176+     while  ((address  <  (StartAddress  +  size )) &&  (status  ==  0 )) {
177+         if  (HAL_FLASH_Program (FLASH_TYPEPROGRAM_QUADWORD , address ,
178+                                 (uint32_t ) data )
179+                 ==  HAL_OK ) {
180+             address  =  address  +  16 ;
181+             data  =  data  +  16 ;
182+         } else  {
183+             status  =  -1 ;
184+         }
185+     }
186+ 
187+     if  (HAL_ICACHE_Enable () !=  HAL_OK )
188+     {
189+         return  -1 ;
190+     }
191+ 
192+     if  (HAL_FLASH_Lock () !=  HAL_OK ) {
193+         return  -1 ;
194+     }
195+ 
196+     return  status ;
197+ }
198+ 
199+ /** Get sector size 
200+  * 
201+  * @param obj The flash object 
202+  * @param address The sector starting address 
203+  * @return The size of a sector 
204+  */ 
205+ uint32_t  flash_get_sector_size (const  flash_t  * obj , uint32_t  address )
206+ {
207+     if  ((address  >= (FLASH_BASE  +  FLASH_SIZE )) ||  (address  <  FLASH_BASE )) {
208+         return  MBED_FLASH_INVALID_SIZE ;
209+     }
210+     return  (FLASH_SECTOR_SIZE );
211+ }
212+ 
213+ /** Get page size 
214+  * 
215+  * @param obj The flash object 
216+  * @param address The page starting address 
217+  * @return The size of a page 
218+  */ 
219+ uint32_t  flash_get_page_size (const  flash_t  * obj )
220+ {
221+     /*  Page size is the minimum programable size, which 16 bytes */ 
222+     return  16 ;
223+ }
224+ 
225+ /** Get start address for the flash region 
226+  * 
227+  * @param obj The flash object 
228+  * @return The start address for the flash region 
229+  */ 
230+ uint32_t  flash_get_start_address (const  flash_t  * obj )
231+ {
232+     return  FLASH_BASE ;
233+ }
234+ 
235+ /** Get the flash region size 
236+  * 
237+  * @param obj The flash object 
238+  * @return The flash region size 
239+  */ 
240+ uint32_t  flash_get_size (const  flash_t  * obj )
241+ {
242+     return  FLASH_SIZE ;
243+ }
244+ 
245+ uint8_t  flash_get_erase_value (const  flash_t  * obj )
246+ {
247+     (void )obj ;
248+ 
249+     return  0xFF ;
250+ }
251+ 
252+ #endif 
0 commit comments