38
|
1 /**
|
|
2 ******************************************************************************
|
|
3 * @file RTE_FLashAccess.c based on BonexFlashAccess.c based on firmwareEraseProgram.v
|
|
4 * @author heinrichs weikamp gmbh
|
|
5 * @version V0.0.1
|
|
6 * @date 20-July-2016
|
|
7 * @version V0.0.1
|
|
8 * @since 20-July-2016
|
|
9 * @brief erase and program the STM32F4xx internal FLASH memory for compasss calib etc.
|
|
10 * based on firmwareEraseProgram.c from OSTC4
|
|
11 *
|
|
12 @verbatim
|
|
13 ==============================================================================
|
|
14 ##### How to use #####
|
|
15 ==============================================================================
|
|
16
|
|
17 4 x 32 Byte with first block can not be 0xFFFFFFFF
|
|
18
|
|
19
|
|
20
|
|
21 @endverbatim
|
|
22 ******************************************************************************
|
|
23 * @attention
|
|
24 *
|
|
25 * <h2><center>© COPYRIGHT(c) 2015 heinrichs weikamp</center></h2>
|
|
26 *
|
|
27 ******************************************************************************
|
|
28 */
|
|
29
|
|
30 /* Includes ------------------------------------------------------------------*/
|
|
31 #include "RTE_FlashAccess.h"
|
|
32 #include "stdio.h"
|
|
33
|
|
34 /** @addtogroup BONEXINFOSYSTEM
|
|
35 * @{
|
|
36 */
|
|
37
|
|
38 /* Exported variables --------------------------------------------------------*/
|
|
39
|
|
40 /* Private types -------------------------------------------------------------*/
|
|
41 /* taken from
|
|
42 * C:\Users\hw\STM32Cube\Repository\STM32Cube_FW_F3_V1.2.0\Projects\STM32F3-Discovery\Examples\FLASH\FLASH_EraseProgram
|
|
43 */
|
|
44
|
|
45 #define FLASH_SECTOR_SIZE_128KB (0x00020000)
|
|
46 #define FLASH_USER_START_ADDR (ADDR_FLASH_SECTOR_7) /* Start @ of user Flash area */
|
|
47 #define FLASH_USER_END_ADDR (ADDR_FLASH_SECTOR_7 + FLASH_SECTOR_SIZE_128KB) /* End @ of user Flash area */
|
|
48
|
|
49 /* Base address of the Flash pages */
|
|
50
|
|
51 #define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) /* Base @ of Sector 0, 16 Kbytes */
|
|
52 #define ADDR_FLASH_SECTOR_1 ((uint32_t)0x08004000) /* Base @ of Sector 1, 16 Kbytes */
|
|
53 #define ADDR_FLASH_SECTOR_2 ((uint32_t)0x08008000) /* Base @ of Sector 2, 16 Kbytes */
|
|
54 #define ADDR_FLASH_SECTOR_3 ((uint32_t)0x0800C000) /* Base @ of Sector 3, 16 Kbytes */
|
|
55 #define ADDR_FLASH_SECTOR_4 ((uint32_t)0x08010000) /* Base @ of Sector 4, 64 Kbytes */
|
|
56 #define ADDR_FLASH_SECTOR_5 ((uint32_t)0x08020000) /* Base @ of Sector 5, 128 Kbytes */
|
|
57 #define ADDR_FLASH_SECTOR_6 ((uint32_t)0x08040000) /* Base @ of Sector 6, 128 Kbytes */
|
|
58 #define ADDR_FLASH_SECTOR_7 ((uint32_t)0x08060000) /* Base @ of Sector 7, 128 Kbytes */
|
|
59
|
|
60
|
|
61
|
|
62
|
|
63 /* Private variables ---------------------------------------------------------*/
|
|
64
|
|
65 //static FLASH_EraseInitTypeDef EraseInitStruct; //Variable used for Erase procedure
|
|
66
|
|
67 uint32_t Address = 0;
|
|
68 uint32_t PageError = 0;
|
|
69 __IO uint32_t data32 = 0 , MemoryProgramStatus = 0;
|
|
70
|
|
71 /* Private function prototypes -----------------------------------------------*/
|
|
72 //uint8_t BFA_eraseSectors(uint32_t SectorAddress, uint32_t NbSectors);
|
|
73 //uint8_t BFA_eraseSectorsAll(void);
|
|
74 uint8_t BFA_FindLastDataBlockAndSetAddress(void);
|
|
75
|
|
76 /* Exported functions --------------------------------------------------------*/
|
|
77
|
|
78 uint8_t BFA_readLastDataBlock(uint32_t *dataArray4)
|
|
79 {
|
|
80 uint8_t answer;
|
|
81
|
|
82 answer = BFA_FindLastDataBlockAndSetAddress();
|
|
83 if(answer != BFA_OK)
|
|
84 return answer;
|
|
85
|
|
86 dataArray4[0] = *(__IO uint32_t*)(Address + 0);
|
|
87 dataArray4[1] = *(__IO uint32_t*)(Address + 4);
|
|
88 dataArray4[2] = *(__IO uint32_t*)(Address + 8);
|
|
89 dataArray4[3] = *(__IO uint32_t*)(Address + 12);
|
|
90 return BFA_OK;
|
|
91 }
|
|
92
|
|
93
|
|
94 uint8_t BFA_writeDataBlock(const uint32_t *dataArray4)
|
|
95 {
|
|
96 uint8_t answer;
|
|
97 uint32_t dataTest[4];
|
|
98 uint32_t StartAddress;
|
|
99
|
|
100 answer = BFA_FindLastDataBlockAndSetAddress();
|
|
101 Address = Address + 16;
|
|
102
|
|
103 if((answer == BFA_EMPTY) || (Address >= FLASH_USER_END_ADDR) || (Address < FLASH_USER_START_ADDR))
|
|
104 Address = FLASH_USER_START_ADDR;
|
|
105
|
|
106 dataTest[0] = *(__IO uint32_t*)(Address + 0);
|
|
107 dataTest[1] = *(__IO uint32_t*)(Address + 4);
|
|
108 dataTest[2] = *(__IO uint32_t*)(Address + 8);
|
|
109 dataTest[3] = *(__IO uint32_t*)(Address + 12);
|
|
110
|
|
111 for(int i=0;i<4;i++)
|
|
112 {
|
|
113 if(dataTest[i] != 0xFFFFFFFF)
|
|
114 {
|
|
115 return 0;
|
|
116 // answer = BFA_eraseSectorsAll();
|
|
117 // break;
|
|
118 }
|
|
119 else
|
|
120 answer = BFA_OK;
|
|
121 }
|
|
122
|
|
123 // can I write?
|
|
124 if(answer != BFA_OK)
|
|
125 return answer;
|
|
126
|
|
127 StartAddress = Address;
|
|
128 HAL_FLASH_Unlock();
|
|
129 for(int i=0;i<4;i++)
|
|
130 {
|
|
131 answer = HAL_FLASH_Program(TYPEPROGRAM_WORD, Address, dataArray4[i]);
|
|
132 Address = Address + 4;
|
|
133 }
|
|
134 HAL_FLASH_Lock();
|
|
135 Address = StartAddress; // back to start of this data set (for reading etc.)
|
|
136 return answer;
|
|
137 }
|
|
138
|
|
139
|
|
140 /* Private functions ---------------------------------------------------------*/
|
|
141 /*
|
|
142 uint8_t BFA_eraseSectorsAll(void)
|
|
143 {
|
|
144 return BFA_eraseSectors(FLASH_USER_START_ADDR, (FLASH_USER_END_ADDR - FLASH_USER_START_ADDR)/FLASH_SECTOR_SIZE_128KB);
|
|
145 }
|
|
146
|
|
147
|
|
148 uint8_t BFA_eraseSectors(uint32_t SectorAddress, uint32_t NbSectors)
|
|
149 {
|
|
150 if((NbSectors > 1) || (SectorAddress != FLASH_USER_START_ADDR))
|
|
151 return 0;
|
|
152
|
|
153 uint8_t answer;
|
|
154 uint32_t PageError = 0;
|
|
155
|
|
156 HAL_FLASH_Unlock();
|
|
157
|
|
158 EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;//ERASE_SECTORS;
|
|
159 EraseInitStruct.Sector = SectorAddress;
|
|
160 EraseInitStruct.NbSectors = NbSectors;
|
|
161
|
|
162 answer = HAL_FLASHEx_Erase(&EraseInitStruct, &PageError);
|
|
163
|
|
164 HAL_FLASH_Lock();
|
|
165 return answer;
|
|
166 }
|
|
167 */
|
|
168
|
|
169 uint8_t BFA_FindLastDataBlockAndSetAddress(void)
|
|
170 {
|
|
171 uint32_t StartAddress;
|
|
172
|
|
173 // first part from here to the end
|
|
174 // there it should be, most likely at Address itself
|
|
175 if(Address == 0)
|
|
176 Address = FLASH_USER_END_ADDR - 16;
|
|
177 else
|
|
178 Address &= 0xFFFFFFF0; // align with 16Byte
|
|
179
|
|
180 StartAddress = Address;
|
|
181 while (Address >= FLASH_USER_START_ADDR)
|
|
182 {
|
|
183 data32 = *(__IO uint32_t*)Address;
|
|
184 if(data32 != 0xFFFFFFFF)
|
|
185 {
|
|
186 return BFA_OK;
|
|
187 }
|
|
188 Address = Address - 16;
|
|
189 }
|
|
190
|
|
191 // second part from the end to here
|
|
192 if(StartAddress == FLASH_USER_END_ADDR - 16)
|
|
193 return BFA_EMPTY;
|
|
194
|
|
195 Address = FLASH_USER_END_ADDR - 16;
|
|
196 while (Address > StartAddress)
|
|
197 {
|
|
198 data32 = *(__IO uint32_t*)Address;
|
|
199 if(data32 != 0xFFFFFFFF)
|
|
200 {
|
|
201 return BFA_OK;
|
|
202 }
|
|
203 Address = Address - 16;
|
|
204 }
|
|
205
|
|
206 // empty flash
|
|
207 return BFA_EMPTY;
|
|
208 }
|
|
209 /**
|
|
210 * @}
|
|
211 */
|
|
212
|
|
213 /************************ (C) COPYRIGHT heinrichs weikamp *****END OF FILE****/
|
|
214
|
|
215
|