99 * 2019-3-2 jinsheng add Macro judgment
1010 * 2020-1-6 duminmin support single bank mode
1111 * 2020-5-17 yufanyufan77 support support H7
12+ * 2021-3-3 zhuyf233 fix some bugs
1213 */
1314
1415#include "board.h"
2425//#define DRV_DEBUG
2526#define LOG_TAG "drv.flash"
2627#include <drv_log.h>
27- #define ADDR_FLASH_SECTOR_0 ((rt_uint32_t)0x08000000) /* Base address of Sector 0, 128 Kbytes */
28- #define ADDR_FLASH_SECTOR_1 ((rt_uint32_t)0x08020000) /* Base address of Sector 1, 128 Kbytes */
29- #define ADDR_FLASH_SECTOR_2 ((rt_uint32_t)0x08040000) /* Base address of Sector 2, 128 Kbytes */
30- #define ADDR_FLASH_SECTOR_3 ((rt_uint32_t)0x08060000) /* Base address of Sector 3, 128 Kbytes */
31- #define ADDR_FLASH_SECTOR_4 ((rt_uint32_t)0x08080000) /* Base address of Sector 4, 128 Kbytes */
32- #define ADDR_FLASH_SECTOR_5 ((rt_uint32_t)0x080A0000) /* Base address of Sector 5, 128 Kbytes */
33- #define ADDR_FLASH_SECTOR_6 ((rt_uint32_t)0x080C0000) /* Base address of Sector 6, 128 Kbytes */
34- #define ADDR_FLASH_SECTOR_7 ((rt_uint32_t)0x080E0000) /* Base address of Sector 7, 128 Kbytes */
35- #define ADDR_FLASH_SECTOR_8 ((rt_uint32_t)0x08100000) /* Base address of Sector 8, 128 Kbytes */
36-
37- #define FLASH_SECTOR_0 0U /* Sector Number 0 */
38- #define FLASH_SECTOR_1 1U /* Sector Number 1 */
39- #define FLASH_SECTOR_2 2U /* Sector Number 2 */
40- #define FLASH_SECTOR_3 3U /* Sector Number 3 */
41- #define FLASH_SECTOR_4 4U /* Sector Number 4 */
42- #define FLASH_SECTOR_5 5U /* Sector Number 5 */
43- #define FLASH_SECTOR_6 6U /* Sector Number 6 */
44- #define FLASH_SECTOR_7 7U /* Sector Number 7 */
45- /**
46- * @brief Gets the sector of a given address
47- * @param addr flash address
48- * @param flash bank
49- * @param flash sector
50- * @retval The sector of a given address
51- */
52- static void GetSector (rt_uint32_t Address ,uint32_t * bank ,uint32_t * sector )
53- {
54- #if defined (FLASH_OPTCR_nDBANK )
55- FLASH_OBProgramInitTypeDef OBInit ;
56- uint32_t nbank = 0 ;
57-
58- /* get duel bank ability:nDBANK(Bit29) */
59- HAL_FLASHEx_OBGetConfig (& OBInit );
60- nbank = ((OBInit .USERConfig & 0x20000000U ) >> 29 );
61- /* 1:single bank mode */
62- if (1 == nbank )
63- {
64- if ((Address < ADDR_FLASH_SECTOR_1 ) && (Address >= ADDR_FLASH_SECTOR_0 ))
65- {
66- sector = FLASH_SECTOR_0 ;
67- }
68- else if ((Address < ADDR_FLASH_SECTOR_2 ) && (Address >= ADDR_FLASH_SECTOR_1 ))
69- {
70- sector = FLASH_SECTOR_1 ;
71- }
72- else if ((Address < ADDR_FLASH_SECTOR_3 ) && (Address >= ADDR_FLASH_SECTOR_2 ))
73- {
74- sector = FLASH_SECTOR_2 ;
75- }
76- else if ((Address < ADDR_FLASH_SECTOR_4 ) && (Address >= ADDR_FLASH_SECTOR_3 ))
77- {
78- sector = FLASH_SECTOR_3 ;
79- }
80- else if ((Address < ADDR_FLASH_SECTOR_5 ) && (Address >= ADDR_FLASH_SECTOR_4 ))
81- {
82- sector = FLASH_SECTOR_4 ;
83- }
84- else if ((Address < ADDR_FLASH_SECTOR_6 ) && (Address >= ADDR_FLASH_SECTOR_5 ))
85- {
86- sector = FLASH_SECTOR_5 ;
87- }
88- else if ((Address < ADDR_FLASH_SECTOR_7 ) && (Address >= ADDR_FLASH_SECTOR_6 ))
89- {
90- sector = FLASH_SECTOR_6 ;
91- }
92- else if ((Address < ADDR_FLASH_SECTOR_8 ) && (Address >= ADDR_FLASH_SECTOR_7 ))
93- {
94- sector = FLASH_SECTOR_7 ;
95- }
96- else if ((Address < ADDR_FLASH_SECTOR_9 ) && (Address >= ADDR_FLASH_SECTOR_8 ))
97- {
98- sector = FLASH_SECTOR_8 ;
99- }
100- else if ((Address < ADDR_FLASH_SECTOR_10 ) && (Address >= ADDR_FLASH_SECTOR_9 ))
101- {
102- sector = FLASH_SECTOR_9 ;
103- }
104- else if ((Address < ADDR_FLASH_SECTOR_11 ) && (Address >= ADDR_FLASH_SECTOR_10 ))
105- {
106- sector = FLASH_SECTOR_10 ;
107- }
108- else
109- {
110- sector = FLASH_SECTOR_11 ;
111- }
112- }
113- else /* 0:dual bank mode */
114- {
115- LOG_E ("rtthread doesn't support duel bank mode yet!" );
116- RT_ASSERT (0 );
117- }
118- #else /* no dual bank ability */
119- * sector = (Address & 0xffffff )/FLASH_SIZE_GRANULARITY_128K ;
120- if (* sector > 7 )
121- {
122- * bank = FLASH_BANK_1 ;
123- * sector = * sector /2 ;
124- }
125- else
126- {
127- * bank = FLASH_BANK_2 ;
128- }
129- #endif
130- }
13128
13229/**
13330 * Read data from flash.
@@ -137,16 +34,16 @@ static void GetSector(rt_uint32_t Address,uint32_t* bank,uint32_t* sector)
13734 * @param buf buffer to store read data
13835 * @param size read bytes size
13936 *
140- * @return result
37+ * @retval The length of bytes that have been read
14138 */
14239int stm32_flash_read (rt_uint32_t addr , rt_uint8_t * buf , size_t size )
14340{
14441 size_t i ;
14542
146- if ((addr + size ) > STM32_FLASH_END_ADDRESS )
43+ if ((addr + size - 1 ) > FLASH_END )
14744 {
14845 LOG_E ("read outrange flash size! addr is (0x%p)" , (void * )(addr + size ));
149- return -1 ;
46+ return - RT_ERROR ;
15047 }
15148
15249 for (i = 0 ; i < size ; i ++ , buf ++ , addr ++ )
@@ -166,47 +63,68 @@ int stm32_flash_read(rt_uint32_t addr, rt_uint8_t *buf, size_t size)
16663 * @param buf the write data buffer
16764 * @param size write bytes size
16865 *
169- * @return result
66+ * @return The length of bytes that have been written
17067 */
17168int stm32_flash_write (rt_uint32_t addr , const rt_uint8_t * buf , size_t size )
17269{
17370 rt_err_t result = RT_EOK ;
174- rt_uint32_t end_addr = addr + size ;
175- rt_uint32_t bank = addr /ADDR_FLASH_SECTOR_8 ;;
71+ rt_uint32_t end_addr = addr + size - 1 , write_addr ;
72+ rt_uint32_t write_granularity = FLASH_NB_32BITWORD_IN_FLASHWORD * 4 ;
73+ rt_uint32_t write_size = write_granularity ;
74+ rt_uint8_t write_buffer [32 ] = {0 };
17675
177- if ((end_addr ) > STM32_FLASH_END_ADDRESS )
76+ if ((end_addr ) > FLASH_END )
17877 {
17978 LOG_E ("write outrange flash size! addr is (0x%p)" , (void * )(addr + size ));
18079 return - RT_EINVAL ;
18180 }
81+
82+ if (addr % 32 != 0 )
83+ {
84+ LOG_E ("write addr must be 32-byte alignment" );
85+ return - RT_EINVAL ;
86+ }
18287
18388 if (size < 1 )
18489 {
18590 return - RT_EINVAL ;
18691 }
18792
188- /* Unlock the Flash to enable the flash control register access */
18993 HAL_FLASH_Unlock ();
190- __HAL_FLASH_CLEAR_FLAG ( FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR ) ;
191-
192- for ( size_t i = 0 ; i < size / 32 ; i ++ , addr += 32 , buf += 32 )
94+ write_addr = ( uint32_t ) buf ;
95+ __HAL_FLASH_CLEAR_FLAG ( FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR );
96+ while ( addr < end_addr )
19397 {
194- /* write data to flash */
195- if (HAL_FLASH_Program (FLASH_TYPEPROGRAM_FLASHWORD , addr , (uint64_t )((uint32_t )buf )) == HAL_OK )
98+ if (end_addr - addr + 1 < write_granularity )
19699 {
197- if (* (rt_uint8_t * )addr != * buf )
100+ write_size = end_addr - addr + 1 ;
101+ for (size_t i = 0 ; i < write_size ; i ++ )
198102 {
199- result = - RT_ERROR ;
200- break ;
103+ write_buffer [i ] = * ((uint8_t * )(write_addr + i ));
201104 }
105+ write_addr = (uint32_t )((rt_uint32_t * )write_buffer );
106+ }
107+ if (HAL_FLASH_Program (FLASH_TYPEPROGRAM_FLASHWORD , addr , write_addr ) == HAL_OK )
108+ {
109+ for (rt_uint8_t i = 0 ; i < write_size ; i ++ )
110+ {
111+ if (* (rt_uint8_t * )(addr + i ) != * (rt_uint8_t * )(write_addr + i ))
112+ {
113+ result = - RT_ERROR ;
114+ goto __exit ;
115+ }
116+ }
117+ addr += write_granularity ;
118+ write_addr += write_granularity ;
202119 }
203120 else
204121 {
205122 result = - RT_ERROR ;
206- break ;
123+ goto __exit ;
207124 }
208125 }
209126
127+ __exit :
210128 HAL_FLASH_Lock ();
211129
212130 if (result != RT_EOK )
@@ -230,42 +148,74 @@ int stm32_flash_write(rt_uint32_t addr, const rt_uint8_t *buf, size_t size)
230148int stm32_flash_erase (rt_uint32_t addr , size_t size )
231149{
232150 rt_err_t result = RT_EOK ;
233- rt_uint32_t FirstSector = 0 , NbOfSectors = 0 ;
234151 rt_uint32_t SECTORError = 0 ;
235- rt_uint32_t bank = 0 ;
236152
237- if ((addr + size ) > STM32_FLASH_END_ADDRESS )
153+ if ((addr + size - 1 ) > FLASH_END )
238154 {
239155 LOG_E ("ERROR: erase outrange flash size! addr is (0x%p)\n" , (void * )(addr + size ));
240156 return - RT_EINVAL ;
241157 }
242158
159+ rt_uint32_t addr_bank1 = 0 ;
160+ rt_uint32_t size_bank1 = 0 ;
161+ rt_uint32_t addr_bank2 = 0 ;
162+ rt_uint32_t size_bank2 = 0 ;
163+
164+ if ((addr + size ) < FLASH_BANK2_BASE )
165+ {
166+ addr_bank1 = addr ;
167+ size_bank1 = size ;
168+ size_bank2 = 0 ;
169+ }
170+ else if (addr >= FLASH_BANK2_BASE )
171+ {
172+ size_bank1 = 0 ;
173+ addr_bank2 = addr ;
174+ size_bank2 = size ;
175+ }
176+ else
177+ {
178+ addr_bank1 = addr ;
179+ size_bank1 = FLASH_BANK2_BASE - addr_bank1 ;
180+ addr_bank2 = FLASH_BANK2_BASE ;
181+ size_bank2 = addr + size - FLASH_BANK2_BASE ;
182+ }
183+
243184 /*Variable used for Erase procedure*/
244185 FLASH_EraseInitTypeDef EraseInitStruct ;
245-
246186 /* Unlock the Flash to enable the flash control register access */
247187 HAL_FLASH_Unlock ();
248-
249- /* Get the 1st sector to erase */
250- GetSector (addr ,& bank ,& FirstSector );
251- /* Get the number of sector to erase from 1st sector */
252- GetSector (addr + size ,0 ,& NbOfSectors );
253- NbOfSectors = NbOfSectors - FirstSector + 1 ;
254- /* Fill EraseInit structure */
255188 EraseInitStruct .TypeErase = FLASH_TYPEERASE_SECTORS ;
256189 EraseInitStruct .VoltageRange = FLASH_VOLTAGE_RANGE_3 ;
257- EraseInitStruct .Sector = FirstSector ;
258- EraseInitStruct .NbSectors = NbOfSectors ;
259- EraseInitStruct .Banks = bank ;
190+ SCB_DisableDCache ();
191+
192+ if (size_bank1 )
193+ {
194+ EraseInitStruct .Sector = (addr_bank1 - FLASH_BANK1_BASE ) / FLASH_SECTOR_SIZE ;
195+ EraseInitStruct .NbSectors = (addr_bank1 + size_bank1 - 1 - FLASH_BANK1_BASE ) / FLASH_SECTOR_SIZE - EraseInitStruct .Sector + 1 ;
196+ EraseInitStruct .Banks = FLASH_BANK_1 ;
197+ if (HAL_FLASHEx_Erase (& EraseInitStruct , & SECTORError ) != HAL_OK )
198+ {
199+ result = - RT_ERROR ;
200+ goto __exit ;
201+ }
202+ }
260203
261- if ( HAL_FLASHEx_Erase ( & EraseInitStruct , & SECTORError ) != HAL_OK )
204+ if ( size_bank2 )
262205 {
263- result = - RT_ERROR ;
264- goto __exit ;
206+ EraseInitStruct .Sector = (addr_bank2 - FLASH_BANK2_BASE ) / FLASH_SECTOR_SIZE ;
207+ EraseInitStruct .NbSectors = (addr_bank2 + size_bank2 - 1 - FLASH_BANK2_BASE ) / FLASH_SECTOR_SIZE - EraseInitStruct .Sector + 1 ;
208+ EraseInitStruct .Banks = FLASH_BANK_2 ;
209+ if (HAL_FLASHEx_Erase (& EraseInitStruct , & SECTORError ) != HAL_OK )
210+ {
211+ result = - RT_ERROR ;
212+ goto __exit ;
213+ }
265214 }
266215
267216__exit :
268217
218+ SCB_EnableDCache ();
269219 HAL_FLASH_Lock ();
270220
271221 if (result != RT_EOK )
0 commit comments