![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
Flash programming with Nucleo-L432KC version 1
main.cpp@0:2a3497bbe04d, 2017-12-28 (annotated)
- Committer:
- DuyLionTran
- Date:
- Thu Dec 28 13:07:15 2017 +0000
- Revision:
- 0:2a3497bbe04d
L432KC flash programming version 0.5
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
DuyLionTran | 0:2a3497bbe04d | 1 | #include "mbed.h" |
DuyLionTran | 0:2a3497bbe04d | 2 | #include "stm32l4xx_hal_flash.h" |
DuyLionTran | 0:2a3497bbe04d | 3 | #include "stm32l4xx_hal_flash_ex.h" |
DuyLionTran | 0:2a3497bbe04d | 4 | #include "flash_programming.h" |
DuyLionTran | 0:2a3497bbe04d | 5 | |
DuyLionTran | 0:2a3497bbe04d | 6 | #define FLASH_PAGE_PROGRAM 1 |
DuyLionTran | 0:2a3497bbe04d | 7 | |
DuyLionTran | 0:2a3497bbe04d | 8 | uint32_t DATA_32 = 0x12345222; |
DuyLionTran | 0:2a3497bbe04d | 9 | uint64_t DATA_64 = 0x1234522212345222; |
DuyLionTran | 0:2a3497bbe04d | 10 | |
DuyLionTran | 0:2a3497bbe04d | 11 | uint32_t StartPage = 0, EndPage = 0; |
DuyLionTran | 0:2a3497bbe04d | 12 | uint32_t Address = 0; |
DuyLionTran | 0:2a3497bbe04d | 13 | uint32_t PageError = 0; |
DuyLionTran | 0:2a3497bbe04d | 14 | |
DuyLionTran | 0:2a3497bbe04d | 15 | __IO FlashReturnStatus MemoryProgramStatus = PASSED; |
DuyLionTran | 0:2a3497bbe04d | 16 | |
DuyLionTran | 0:2a3497bbe04d | 17 | FLASH_EraseInitTypeDef EraseInitStruct; |
DuyLionTran | 0:2a3497bbe04d | 18 | FLASH_OBProgramInitTypeDef OptionsBytesStruct, OptionsBytesStruct2; |
DuyLionTran | 0:2a3497bbe04d | 19 | |
DuyLionTran | 0:2a3497bbe04d | 20 | Serial serial(USBTX, USBRX); |
DuyLionTran | 0:2a3497bbe04d | 21 | |
DuyLionTran | 0:2a3497bbe04d | 22 | DigitalOut led3(LED1); |
DuyLionTran | 0:2a3497bbe04d | 23 | |
DuyLionTran | 0:2a3497bbe04d | 24 | void main() { |
DuyLionTran | 0:2a3497bbe04d | 25 | serial.baud(115200); |
DuyLionTran | 0:2a3497bbe04d | 26 | printf("PROGRAM STARTS\r\n"); |
DuyLionTran | 0:2a3497bbe04d | 27 | led3 = 0; |
DuyLionTran | 0:2a3497bbe04d | 28 | |
DuyLionTran | 0:2a3497bbe04d | 29 | /* Initialize test status */ |
DuyLionTran | 0:2a3497bbe04d | 30 | MemoryProgramStatus = PASSED; |
DuyLionTran | 0:2a3497bbe04d | 31 | |
DuyLionTran | 0:2a3497bbe04d | 32 | /* Unlock the Flash to enable the flash control register access *************/ |
DuyLionTran | 0:2a3497bbe04d | 33 | HAL_FLASH_Unlock(); |
DuyLionTran | 0:2a3497bbe04d | 34 | |
DuyLionTran | 0:2a3497bbe04d | 35 | /* Clear OPTVERR bit set on virgin samples */ |
DuyLionTran | 0:2a3497bbe04d | 36 | __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR); |
DuyLionTran | 0:2a3497bbe04d | 37 | |
DuyLionTran | 0:2a3497bbe04d | 38 | /* Unlock the Options Bytes *************************************************/ |
DuyLionTran | 0:2a3497bbe04d | 39 | HAL_FLASH_OB_Unlock(); |
DuyLionTran | 0:2a3497bbe04d | 40 | |
DuyLionTran | 0:2a3497bbe04d | 41 | /* Get the number of the start and end pages */ |
DuyLionTran | 0:2a3497bbe04d | 42 | StartPage = GetPage(FLASH_USER_START_ADDR); |
DuyLionTran | 0:2a3497bbe04d | 43 | EndPage = GetPage(FLASH_USER_END_ADDR); |
DuyLionTran | 0:2a3497bbe04d | 44 | |
DuyLionTran | 0:2a3497bbe04d | 45 | OptionsBytesStruct.WRPArea = OB_WRPAREA_BANK1_AREAA; |
DuyLionTran | 0:2a3497bbe04d | 46 | OptionsBytesStruct2.WRPArea = OB_WRPAREA_BANK1_AREAB; |
DuyLionTran | 0:2a3497bbe04d | 47 | |
DuyLionTran | 0:2a3497bbe04d | 48 | /* Get pages write protection status ****************************************/ |
DuyLionTran | 0:2a3497bbe04d | 49 | HAL_FLASHEx_OBGetConfig(&OptionsBytesStruct); |
DuyLionTran | 0:2a3497bbe04d | 50 | HAL_FLASHEx_OBGetConfig(&OptionsBytesStruct2); |
DuyLionTran | 0:2a3497bbe04d | 51 | |
DuyLionTran | 0:2a3497bbe04d | 52 | /* Configure write protected pages */ |
DuyLionTran | 0:2a3497bbe04d | 53 | if (OptionsBytesStruct.OptionType == OPTIONBYTE_WRP) |
DuyLionTran | 0:2a3497bbe04d | 54 | { |
DuyLionTran | 0:2a3497bbe04d | 55 | if(HAL_FLASHEx_OBProgram(&OptionsBytesStruct) != HAL_OK) |
DuyLionTran | 0:2a3497bbe04d | 56 | { |
DuyLionTran | 0:2a3497bbe04d | 57 | /* Error occurred while options bytes programming. **********************/ |
DuyLionTran | 0:2a3497bbe04d | 58 | while (1) |
DuyLionTran | 0:2a3497bbe04d | 59 | { |
DuyLionTran | 0:2a3497bbe04d | 60 | /* Make LED3 blink (100ms on, 2s off) to indicate error in operation */ |
DuyLionTran | 0:2a3497bbe04d | 61 | led3 = 1; |
DuyLionTran | 0:2a3497bbe04d | 62 | wait(100/1000); |
DuyLionTran | 0:2a3497bbe04d | 63 | led3 = 0; |
DuyLionTran | 0:2a3497bbe04d | 64 | wait(2000/1000); |
DuyLionTran | 0:2a3497bbe04d | 65 | } |
DuyLionTran | 0:2a3497bbe04d | 66 | } |
DuyLionTran | 0:2a3497bbe04d | 67 | } |
DuyLionTran | 0:2a3497bbe04d | 68 | |
DuyLionTran | 0:2a3497bbe04d | 69 | if (OptionsBytesStruct2.OptionType == OPTIONBYTE_WRP) |
DuyLionTran | 0:2a3497bbe04d | 70 | { |
DuyLionTran | 0:2a3497bbe04d | 71 | if(HAL_FLASHEx_OBProgram(&OptionsBytesStruct2) != HAL_OK) |
DuyLionTran | 0:2a3497bbe04d | 72 | { |
DuyLionTran | 0:2a3497bbe04d | 73 | /* Error occurred while options bytes programming. **********************/ |
DuyLionTran | 0:2a3497bbe04d | 74 | while (1) |
DuyLionTran | 0:2a3497bbe04d | 75 | { |
DuyLionTran | 0:2a3497bbe04d | 76 | /* Make LED3 blink (100ms on, 2s off) to indicate error in operation */ |
DuyLionTran | 0:2a3497bbe04d | 77 | led3 = 1; |
DuyLionTran | 0:2a3497bbe04d | 78 | wait(100/1000); |
DuyLionTran | 0:2a3497bbe04d | 79 | led3 = 0; |
DuyLionTran | 0:2a3497bbe04d | 80 | wait(2000/1000); |
DuyLionTran | 0:2a3497bbe04d | 81 | } |
DuyLionTran | 0:2a3497bbe04d | 82 | } |
DuyLionTran | 0:2a3497bbe04d | 83 | } |
DuyLionTran | 0:2a3497bbe04d | 84 | |
DuyLionTran | 0:2a3497bbe04d | 85 | /* Generate System Reset to load the new option byte values ***************/ |
DuyLionTran | 0:2a3497bbe04d | 86 | if ((OptionsBytesStruct.OptionType == OPTIONBYTE_WRP) || (OptionsBytesStruct2.OptionType == OPTIONBYTE_WRP)) |
DuyLionTran | 0:2a3497bbe04d | 87 | { |
DuyLionTran | 0:2a3497bbe04d | 88 | HAL_FLASH_OB_Launch(); |
DuyLionTran | 0:2a3497bbe04d | 89 | } |
DuyLionTran | 0:2a3497bbe04d | 90 | |
DuyLionTran | 0:2a3497bbe04d | 91 | /* Lock the Options Bytes *************************************************/ |
DuyLionTran | 0:2a3497bbe04d | 92 | HAL_FLASH_OB_Lock(); |
DuyLionTran | 0:2a3497bbe04d | 93 | |
DuyLionTran | 0:2a3497bbe04d | 94 | #ifdef FLASH_PAGE_PROGRAM |
DuyLionTran | 0:2a3497bbe04d | 95 | printf("Test flash step 2\r\n"); |
DuyLionTran | 0:2a3497bbe04d | 96 | /* The selected pages are write protected *******************************/ |
DuyLionTran | 0:2a3497bbe04d | 97 | if (((OptionsBytesStruct.WRPStartOffset <= StartPage) && (OptionsBytesStruct.WRPEndOffset >= EndPage)) || |
DuyLionTran | 0:2a3497bbe04d | 98 | ((OptionsBytesStruct2.WRPStartOffset <= StartPage) && (OptionsBytesStruct2.WRPEndOffset >= EndPage))) |
DuyLionTran | 0:2a3497bbe04d | 99 | { |
DuyLionTran | 0:2a3497bbe04d | 100 | printf("Step 2: 1\r\n"); |
DuyLionTran | 0:2a3497bbe04d | 101 | /* The desired pages are write protected */ |
DuyLionTran | 0:2a3497bbe04d | 102 | /* Check that it is not allowed to write in this page */ |
DuyLionTran | 0:2a3497bbe04d | 103 | Address = FLASH_USER_START_ADDR; |
DuyLionTran | 0:2a3497bbe04d | 104 | if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, Address, DATA_64) != HAL_OK) |
DuyLionTran | 0:2a3497bbe04d | 105 | { |
DuyLionTran | 0:2a3497bbe04d | 106 | /* Error returned during programmation. */ |
DuyLionTran | 0:2a3497bbe04d | 107 | /* Check that WRPERR flag is well set */ |
DuyLionTran | 0:2a3497bbe04d | 108 | if ((HAL_FLASH_GetError() & HAL_FLASH_ERROR_WRP) != 0) |
DuyLionTran | 0:2a3497bbe04d | 109 | { |
DuyLionTran | 0:2a3497bbe04d | 110 | MemoryProgramStatus = FAILED; |
DuyLionTran | 0:2a3497bbe04d | 111 | } |
DuyLionTran | 0:2a3497bbe04d | 112 | else |
DuyLionTran | 0:2a3497bbe04d | 113 | { |
DuyLionTran | 0:2a3497bbe04d | 114 | /* Another error occurred. |
DuyLionTran | 0:2a3497bbe04d | 115 | User can add here some code to deal with this error */ |
DuyLionTran | 0:2a3497bbe04d | 116 | while (1) |
DuyLionTran | 0:2a3497bbe04d | 117 | { |
DuyLionTran | 0:2a3497bbe04d | 118 | /* Make LED3 blink (100ms on, 2s off) to indicate error in Write operation */ |
DuyLionTran | 0:2a3497bbe04d | 119 | led3 = 1; |
DuyLionTran | 0:2a3497bbe04d | 120 | wait(100/1000); |
DuyLionTran | 0:2a3497bbe04d | 121 | led3 = 0; |
DuyLionTran | 0:2a3497bbe04d | 122 | wait(2000/1000); |
DuyLionTran | 0:2a3497bbe04d | 123 | } |
DuyLionTran | 0:2a3497bbe04d | 124 | } |
DuyLionTran | 0:2a3497bbe04d | 125 | } |
DuyLionTran | 0:2a3497bbe04d | 126 | else |
DuyLionTran | 0:2a3497bbe04d | 127 | { |
DuyLionTran | 0:2a3497bbe04d | 128 | /* Write operation is successful. Should not occur |
DuyLionTran | 0:2a3497bbe04d | 129 | User can add here some code to deal with this error */ |
DuyLionTran | 0:2a3497bbe04d | 130 | while (1) |
DuyLionTran | 0:2a3497bbe04d | 131 | { |
DuyLionTran | 0:2a3497bbe04d | 132 | /* Make LED3 blink (100ms on, 2s off) to indicate error in Write operation */ |
DuyLionTran | 0:2a3497bbe04d | 133 | led3 = 1; |
DuyLionTran | 0:2a3497bbe04d | 134 | wait(100/1000); |
DuyLionTran | 0:2a3497bbe04d | 135 | led3 = 0; |
DuyLionTran | 0:2a3497bbe04d | 136 | wait(2000/1000); |
DuyLionTran | 0:2a3497bbe04d | 137 | } |
DuyLionTran | 0:2a3497bbe04d | 138 | } |
DuyLionTran | 0:2a3497bbe04d | 139 | } |
DuyLionTran | 0:2a3497bbe04d | 140 | else |
DuyLionTran | 0:2a3497bbe04d | 141 | { |
DuyLionTran | 0:2a3497bbe04d | 142 | printf("Step 2: 2\r\n"); |
DuyLionTran | 0:2a3497bbe04d | 143 | /* The desired pages are not write protected */ |
DuyLionTran | 0:2a3497bbe04d | 144 | /* Fill EraseInit structure************************************************/ |
DuyLionTran | 0:2a3497bbe04d | 145 | |
DuyLionTran | 0:2a3497bbe04d | 146 | EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES; |
DuyLionTran | 0:2a3497bbe04d | 147 | EraseInitStruct.Banks = FLASH_BANK_1; |
DuyLionTran | 0:2a3497bbe04d | 148 | EraseInitStruct.Page = StartPage; |
DuyLionTran | 0:2a3497bbe04d | 149 | EraseInitStruct.NbPages = EndPage - StartPage + 1; |
DuyLionTran | 0:2a3497bbe04d | 150 | |
DuyLionTran | 0:2a3497bbe04d | 151 | printf("Step 2: 2: 1\r\n"); |
DuyLionTran | 0:2a3497bbe04d | 152 | if (HAL_FLASHEx_Erase(&EraseInitStruct, &PageError) != HAL_OK) |
DuyLionTran | 0:2a3497bbe04d | 153 | { |
DuyLionTran | 0:2a3497bbe04d | 154 | printf("Step 2: 2: 2\r\n"); |
DuyLionTran | 0:2a3497bbe04d | 155 | /* |
DuyLionTran | 0:2a3497bbe04d | 156 | Error occurred while page erase. |
DuyLionTran | 0:2a3497bbe04d | 157 | User can add here some code to deal with this error. |
DuyLionTran | 0:2a3497bbe04d | 158 | PageError will contain the faulty page and then to know the code error on this page, |
DuyLionTran | 0:2a3497bbe04d | 159 | user can call function 'HAL_FLASH_GetError()' |
DuyLionTran | 0:2a3497bbe04d | 160 | */ |
DuyLionTran | 0:2a3497bbe04d | 161 | while (1) |
DuyLionTran | 0:2a3497bbe04d | 162 | { |
DuyLionTran | 0:2a3497bbe04d | 163 | /* Make LED3 blink (100ms on, 2s off) to indicate error in Erase operation */ |
DuyLionTran | 0:2a3497bbe04d | 164 | led3 = 1; |
DuyLionTran | 0:2a3497bbe04d | 165 | wait(100/1000); |
DuyLionTran | 0:2a3497bbe04d | 166 | led3 = 0; |
DuyLionTran | 0:2a3497bbe04d | 167 | wait(2000/1000); |
DuyLionTran | 0:2a3497bbe04d | 168 | } |
DuyLionTran | 0:2a3497bbe04d | 169 | } |
DuyLionTran | 0:2a3497bbe04d | 170 | printf("Step 2: 2: 3\r\n"); |
DuyLionTran | 0:2a3497bbe04d | 171 | /* FLASH Word program of DATA_32 at addresses defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR */ |
DuyLionTran | 0:2a3497bbe04d | 172 | Address = FLASH_USER_START_ADDR; |
DuyLionTran | 0:2a3497bbe04d | 173 | while (Address < FLASH_USER_END_ADDR) |
DuyLionTran | 0:2a3497bbe04d | 174 | { |
DuyLionTran | 0:2a3497bbe04d | 175 | printf("Step 2: 2: 4\r\n"); |
DuyLionTran | 0:2a3497bbe04d | 176 | if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, Address, DATA_64) == HAL_OK) |
DuyLionTran | 0:2a3497bbe04d | 177 | { |
DuyLionTran | 0:2a3497bbe04d | 178 | Address = Address + 8; |
DuyLionTran | 0:2a3497bbe04d | 179 | } |
DuyLionTran | 0:2a3497bbe04d | 180 | else |
DuyLionTran | 0:2a3497bbe04d | 181 | { |
DuyLionTran | 0:2a3497bbe04d | 182 | /* Error occurred while writing data in Flash memory. |
DuyLionTran | 0:2a3497bbe04d | 183 | User can add here some code to deal with this error */ |
DuyLionTran | 0:2a3497bbe04d | 184 | while (1) |
DuyLionTran | 0:2a3497bbe04d | 185 | { |
DuyLionTran | 0:2a3497bbe04d | 186 | /* Make LED3 blink (100ms on, 2s off) to indicate error in Write operation */ |
DuyLionTran | 0:2a3497bbe04d | 187 | led3 = 1; |
DuyLionTran | 0:2a3497bbe04d | 188 | wait(100/1000); |
DuyLionTran | 0:2a3497bbe04d | 189 | led3 = 0; |
DuyLionTran | 0:2a3497bbe04d | 190 | wait(2000/1000); |
DuyLionTran | 0:2a3497bbe04d | 191 | } |
DuyLionTran | 0:2a3497bbe04d | 192 | } |
DuyLionTran | 0:2a3497bbe04d | 193 | } |
DuyLionTran | 0:2a3497bbe04d | 194 | |
DuyLionTran | 0:2a3497bbe04d | 195 | /* Check the correctness of written data */ |
DuyLionTran | 0:2a3497bbe04d | 196 | Address = FLASH_USER_START_ADDR; |
DuyLionTran | 0:2a3497bbe04d | 197 | |
DuyLionTran | 0:2a3497bbe04d | 198 | while (Address < FLASH_USER_END_ADDR) |
DuyLionTran | 0:2a3497bbe04d | 199 | { |
DuyLionTran | 0:2a3497bbe04d | 200 | if((*(__IO uint32_t*) Address) != DATA_32) |
DuyLionTran | 0:2a3497bbe04d | 201 | { |
DuyLionTran | 0:2a3497bbe04d | 202 | MemoryProgramStatus = FAILED; |
DuyLionTran | 0:2a3497bbe04d | 203 | } |
DuyLionTran | 0:2a3497bbe04d | 204 | Address += 4; |
DuyLionTran | 0:2a3497bbe04d | 205 | } |
DuyLionTran | 0:2a3497bbe04d | 206 | } |
DuyLionTran | 0:2a3497bbe04d | 207 | #endif /* FLASH_PAGE_PROGRAM */ |
DuyLionTran | 0:2a3497bbe04d | 208 | |
DuyLionTran | 0:2a3497bbe04d | 209 | /* Lock the Flash to disable the flash control register access (recommended |
DuyLionTran | 0:2a3497bbe04d | 210 | to protect the FLASH memory against possible unwanted operation) *********/ |
DuyLionTran | 0:2a3497bbe04d | 211 | HAL_FLASH_Lock(); |
DuyLionTran | 0:2a3497bbe04d | 212 | |
DuyLionTran | 0:2a3497bbe04d | 213 | /*Check if there is an issue to program data*/ |
DuyLionTran | 0:2a3497bbe04d | 214 | if (MemoryProgramStatus == PASSED) |
DuyLionTran | 0:2a3497bbe04d | 215 | { |
DuyLionTran | 0:2a3497bbe04d | 216 | /* No error detected. Switch on LED3*/ |
DuyLionTran | 0:2a3497bbe04d | 217 | printf("Write OK\r\n"); |
DuyLionTran | 0:2a3497bbe04d | 218 | led3 = 1; |
DuyLionTran | 0:2a3497bbe04d | 219 | } |
DuyLionTran | 0:2a3497bbe04d | 220 | else |
DuyLionTran | 0:2a3497bbe04d | 221 | { |
DuyLionTran | 0:2a3497bbe04d | 222 | printf("Write failed\r\n"); |
DuyLionTran | 0:2a3497bbe04d | 223 | /* Error detected. LED3 will blink with 1s period */ |
DuyLionTran | 0:2a3497bbe04d | 224 | while (1) |
DuyLionTran | 0:2a3497bbe04d | 225 | { |
DuyLionTran | 0:2a3497bbe04d | 226 | led3 = 1; |
DuyLionTran | 0:2a3497bbe04d | 227 | wait(1000/1000); |
DuyLionTran | 0:2a3497bbe04d | 228 | led3 = 0; |
DuyLionTran | 0:2a3497bbe04d | 229 | wait(1000/1000); |
DuyLionTran | 0:2a3497bbe04d | 230 | } |
DuyLionTran | 0:2a3497bbe04d | 231 | } |
DuyLionTran | 0:2a3497bbe04d | 232 | } |