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