Skip to content

Commit d69c411

Browse files
authored
Merge pull request #4405 from zhuyf233/master
[bsp][stm32]fix stm32h7 flash driver error
2 parents d7595d5 + 2d5bbbf commit d69c411

File tree

1 file changed

+88
-138
lines changed

1 file changed

+88
-138
lines changed

bsp/stm32/libraries/HAL_Drivers/drv_flash/drv_flash_h7.c

Lines changed: 88 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
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"
@@ -24,110 +25,6 @@
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
*/
14239
int 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
*/
17168
int 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)
230148
int 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

Comments
 (0)