1 /* SPDX-License-Identifier: BSD-3-Clause */
3 /******************************************************************************
5 * Copyright (C) 2013-2018 Texas Instruments Incorporated - http://www.ti.com/
7 ******************************************************************************/
11 #include "driverlib.h"
13 #include "MSP432P4_FlashLibIf.h"
15 /* Number of erase repeats until timeout */
16 #define FLASH_MAX_REPEATS 5
18 /* Local prototypes */
19 void msp432_flash_init(void);
20 void msp432_flash_mass_erase(void);
21 void msp432_flash_sector_erase(void);
22 void msp432_flash_write(void);
23 void msp432_flash_continous_write(void);
24 void msp432_flash_exit(void);
25 void unlock_flash_sectors(void);
26 void unlock_all_flash_sectors(void);
27 void lock_all_flash_sectors(void);
28 void __cs_set_dco_frequency_range(uint32_t dco_freq);
29 static bool program_device(void *src, void *dest, uint32_t length);
31 struct backup_params {
32 uint32_t BANK0_WAIT_RESTORE;
33 uint32_t BANK1_WAIT_RESTORE;
34 uint32_t CS_DC0_FREQ_RESTORE;
35 uint8_t VCORE_LEVEL_RESTORE;
36 uint8_t PCM_VCORE_LEVEL_RESTORE;
39 #define BACKUP_PARAMS ((struct backup_params *) 0x20000180)
41 /* Main with trampoline */
45 MAP_WDT_A_HOLD_TIMER();
47 /* Disable interrupts */
51 switch (FLASH_LOADER->FLASH_FUNCTION) {
53 FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
55 FLASH_LOADER->FLASH_FUNCTION = 0;
57 case FLASH_MASS_ERASE:
58 FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
59 msp432_flash_mass_erase();
60 FLASH_LOADER->FLASH_FUNCTION = 0;
62 case FLASH_SECTOR_ERASE:
63 FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
64 msp432_flash_sector_erase();
65 FLASH_LOADER->FLASH_FUNCTION = 0;
68 FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
70 FLASH_LOADER->FLASH_FUNCTION = 0;
72 case FLASH_CONTINUOUS_PROGRAM:
73 FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
74 msp432_flash_continous_write();
75 FLASH_LOADER->FLASH_FUNCTION = 0;
78 FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
80 FLASH_LOADER->FLASH_FUNCTION = 0;
82 case FLASH_NO_COMMAND:
85 FLASH_LOADER->RETURN_CODE = FLASH_WRONG_COMMAND;
91 /* Initialize flash */
92 void msp432_flash_init(void)
96 /* Point to vector table in RAM */
97 SCB->VTOR = (uint32_t)0x01000000;
99 /* backup system parameters */
100 BACKUP_PARAMS->BANK0_WAIT_RESTORE =
101 MAP_FLASH_CTL_GET_WAIT_STATE(FLASH_BANK0);
102 BACKUP_PARAMS->BANK1_WAIT_RESTORE =
103 MAP_FLASH_CTL_GET_WAIT_STATE(FLASH_BANK1);
104 BACKUP_PARAMS->VCORE_LEVEL_RESTORE = MAP_PCM_GET_CORE_VOLTAGE_LEVEL();
105 BACKUP_PARAMS->PCM_VCORE_LEVEL_RESTORE = MAP_PCM_GET_POWER_STATE();
106 BACKUP_PARAMS->CS_DC0_FREQ_RESTORE = CS->CTL0 & CS_CTL0_DCORSEL_MASK;
108 /* set parameters for flashing */
109 success = MAP_PCM_SET_POWER_STATE(PCM_AM_LDO_VCORE0);
111 /* Set Flash wait states to 2 */
112 MAP_FLASH_CTL_SET_WAIT_STATE(FLASH_BANK0, 2);
113 MAP_FLASH_CTL_SET_WAIT_STATE(FLASH_BANK1, 2);
115 /* Set CPU speed to 24MHz */
116 __cs_set_dco_frequency_range(CS_DCO_FREQUENCY_24);
119 /* Indicate failed power switch */
120 FLASH_LOADER->RETURN_CODE = FLASH_POWER_ERROR;
122 FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
125 /* Erase entire flash */
126 void msp432_flash_mass_erase(void)
128 bool success = false;
130 /* Allow flash writes */
131 unlock_flash_sectors();
133 /* Allow some mass erase repeats before timeout with error */
134 int erase_repeats = FLASH_MAX_REPEATS;
135 while (!success && (erase_repeats > 0)) {
136 /* Mass erase with post-verify */
137 success = MAP_FLASH_CTL_PERFORM_MASS_ERASE();
141 if (erase_repeats == 0)
142 FLASH_LOADER->RETURN_CODE = FLASH_VERIFY_ERROR;
144 FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
146 /* Block flash writes */
147 lock_all_flash_sectors();
150 /* Erase one flash sector */
151 void msp432_flash_sector_erase(void)
153 bool success = false;
155 /* Allow flash writes */
156 unlock_all_flash_sectors();
158 /* Allow some sector erase repeats before timeout with error */
159 int erase_repeats = FLASH_MAX_REPEATS;
160 while (!success && (erase_repeats > 0)) {
161 /* Sector erase with post-verify */
162 success = MAP_FLASH_CTL_ERASE_SECTOR(FLASH_LOADER->DST_ADDRESS);
166 if (erase_repeats == 0)
167 FLASH_LOADER->RETURN_CODE = FLASH_ERROR;
169 FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
171 /* Block flash writes */
172 lock_all_flash_sectors();
175 /* Write data to flash with the help of DriverLib */
176 void msp432_flash_write(void)
178 bool success = false;
180 /* Allow flash writes */
181 unlock_all_flash_sectors();
183 while (!(FLASH_LOADER->BUFFER1_STATUS_REGISTER & BUFFER_DATA_READY))
186 FLASH_LOADER->BUFFER1_STATUS_REGISTER |= BUFFER_ACTIVE;
189 success = program_device((uint32_t *)RAM_LOADER_BUFFER1,
190 (void *)FLASH_LOADER->DST_ADDRESS, FLASH_LOADER->SRC_LENGTH);
192 FLASH_LOADER->BUFFER1_STATUS_REGISTER &=
193 ~(BUFFER_ACTIVE | BUFFER_DATA_READY);
195 /* Block flash writes */
196 lock_all_flash_sectors();
199 FLASH_LOADER->RETURN_CODE = FLASH_ERROR;
201 FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
204 /* Write data to flash with the help of DriverLib with auto-increment */
205 void msp432_flash_continous_write(void)
207 bool buffer1_in_use = false;
208 bool buffer2_in_use = false;
209 uint32_t *src_address = NULL;
210 bool success = false;
212 uint32_t bytes_to_write = FLASH_LOADER->SRC_LENGTH;
213 uint32_t write_package = 0;
214 uint32_t start_addr = FLASH_LOADER->DST_ADDRESS;
216 while (bytes_to_write > 0) {
217 if (bytes_to_write > SRC_LENGTH_MAX) {
218 write_package = SRC_LENGTH_MAX;
219 bytes_to_write -= write_package;
221 write_package = bytes_to_write;
222 bytes_to_write -= write_package;
224 unlock_all_flash_sectors();
226 while (!(FLASH_LOADER->BUFFER1_STATUS_REGISTER & BUFFER_DATA_READY) &&
227 !(FLASH_LOADER->BUFFER2_STATUS_REGISTER & BUFFER_DATA_READY))
230 if (FLASH_LOADER->BUFFER1_STATUS_REGISTER & BUFFER_DATA_READY) {
231 FLASH_LOADER->BUFFER1_STATUS_REGISTER |= BUFFER_ACTIVE;
232 src_address = (uint32_t *)RAM_LOADER_BUFFER1;
233 buffer1_in_use = true;
234 } else if (FLASH_LOADER->BUFFER2_STATUS_REGISTER & BUFFER_DATA_READY) {
235 FLASH_LOADER->BUFFER2_STATUS_REGISTER |= BUFFER_ACTIVE;
236 src_address = (uint32_t *)RAM_LOADER_BUFFER2;
237 buffer2_in_use = true;
239 if (buffer1_in_use || buffer2_in_use) {
240 success = program_device(src_address,
241 (void *)start_addr, write_package);
244 P6->OUT &= ~BIT4; /* Program from B1 */
245 else if (buffer2_in_use)
246 P3->OUT &= ~BIT6; /* Program from B1 */
248 start_addr += write_package;
250 if (buffer1_in_use) {
251 FLASH_LOADER->BUFFER1_STATUS_REGISTER &=
252 ~(BUFFER_ACTIVE | BUFFER_DATA_READY);
253 buffer1_in_use = false;
254 } else if (buffer2_in_use) {
255 FLASH_LOADER->BUFFER2_STATUS_REGISTER &=
256 ~(BUFFER_ACTIVE | BUFFER_DATA_READY);
257 buffer2_in_use = false;
259 /* Block flash writes */
260 lock_all_flash_sectors();
263 FLASH_LOADER->RETURN_CODE = FLASH_ERROR;
268 FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
271 /* Unlock Main/Info Flash sectors */
272 void unlock_flash_sectors(void)
274 if (FLASH_LOADER->ERASE_PARAM & ERASE_MAIN) {
275 MAP_FLASH_CTL_UNPROTECT_SECTOR(FLASH_MAIN_MEMORY_SPACE_BANK0,
277 MAP_FLASH_CTL_UNPROTECT_SECTOR(FLASH_MAIN_MEMORY_SPACE_BANK1,
280 if (FLASH_LOADER->ERASE_PARAM & ERASE_INFO) {
281 MAP_FLASH_CTL_UNPROTECT_SECTOR(FLASH_INFO_MEMORY_SPACE_BANK0,
282 FLASH_SECTOR0 | FLASH_SECTOR1);
283 if (FLASH_LOADER->UNLOCK_BSL == UNLOCK_BSL_KEY)
284 MAP_FLASH_CTL_UNPROTECT_SECTOR(FLASH_INFO_MEMORY_SPACE_BANK1,
285 FLASH_SECTOR0 | FLASH_SECTOR1);
289 /* Unlock All Flash sectors */
290 void unlock_all_flash_sectors(void)
292 MAP_FLASH_CTL_UNPROTECT_SECTOR(FLASH_MAIN_MEMORY_SPACE_BANK0, 0xFFFFFFFF);
293 MAP_FLASH_CTL_UNPROTECT_SECTOR(FLASH_MAIN_MEMORY_SPACE_BANK1, 0xFFFFFFFF);
294 MAP_FLASH_CTL_UNPROTECT_SECTOR(FLASH_INFO_MEMORY_SPACE_BANK0,
295 FLASH_SECTOR0 | FLASH_SECTOR1);
296 if (FLASH_LOADER->UNLOCK_BSL == UNLOCK_BSL_KEY)
297 MAP_FLASH_CTL_UNPROTECT_SECTOR(FLASH_INFO_MEMORY_SPACE_BANK1,
298 FLASH_SECTOR0 | FLASH_SECTOR1);
302 /* Lock all Flash sectors */
303 void lock_all_flash_sectors(void)
305 MAP_FLASH_CTL_PROTECT_SECTOR(FLASH_MAIN_MEMORY_SPACE_BANK0, 0xFFFFFFFF);
306 MAP_FLASH_CTL_PROTECT_SECTOR(FLASH_MAIN_MEMORY_SPACE_BANK1, 0xFFFFFFFF);
307 MAP_FLASH_CTL_PROTECT_SECTOR(FLASH_INFO_MEMORY_SPACE_BANK0,
308 FLASH_SECTOR0 | FLASH_SECTOR1);
309 MAP_FLASH_CTL_PROTECT_SECTOR(FLASH_INFO_MEMORY_SPACE_BANK1,
310 FLASH_SECTOR0 | FLASH_SECTOR1);
314 /* Force DCO frequency range */
315 void __cs_set_dco_frequency_range(uint32_t dco_freq)
317 /* Unlocking the CS Module */
318 CS->KEY = CS_KEY_VAL;
320 /* Resetting Tuning Parameters and Setting the frequency */
321 CS->CTL0 = (CS->CTL0 & ~CS_CTL0_DCORSEL_MASK) | dco_freq;
323 /* Locking the CS Module */
327 /* Exit flash programming */
328 void msp432_flash_exit(void)
330 bool success = false;
332 /* Restore modified registers, in reverse order */
333 __cs_set_dco_frequency_range(CS_DCO_FREQUENCY_3);
335 MAP_FLASH_CTL_SET_WAIT_STATE(FLASH_BANK0,
336 BACKUP_PARAMS->BANK0_WAIT_RESTORE);
337 MAP_FLASH_CTL_SET_WAIT_STATE(FLASH_BANK1,
338 BACKUP_PARAMS->BANK1_WAIT_RESTORE);
340 success = MAP_PCM_SET_POWER_STATE(BACKUP_PARAMS->PCM_VCORE_LEVEL_RESTORE);
342 success &= MAP_PCM_SET_CORE_VOLTAGE_LEVEL(
343 BACKUP_PARAMS->VCORE_LEVEL_RESTORE);
345 __cs_set_dco_frequency_range(BACKUP_PARAMS->CS_DC0_FREQ_RESTORE);
347 /* Point to vector table in Flash */
348 SCB->VTOR = (uint32_t)0x00000000;
351 FLASH_LOADER->RETURN_CODE = FLASH_ERROR;
353 FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
356 static bool program_device(void *src, void *dest, uint32_t length)
358 return MAP_FLASH_CTL_PROGRAM_MEMORY(src, dest, length);