1 /******************************************************************************
3 * Copyright (C) 2013-2018 Texas Instruments Incorporated - http://www.ti.com/
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the
17 * Neither the name of Texas Instruments Incorporated nor the names of
18 * its contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 ******************************************************************************/
37 #include "driverlib.h"
39 #include "MSP432P4_FlashLibIf.h"
41 /* Number of erase repeats until timeout */
42 #define FLASH_MAX_REPEATS 5
44 /* Local prototypes */
45 void msp432_flash_init(void);
46 void msp432_flash_mass_erase(void);
47 void msp432_flash_sector_erase(void);
48 void msp432_flash_write(void);
49 void msp432_flash_continous_write(void);
50 void msp432_flash_exit(void);
51 void unlock_flash_sectors(void);
52 void unlock_all_flash_sectors(void);
53 void lock_all_flash_sectors(void);
54 void __cs_set_dco_frequency_range(uint32_t dco_freq);
55 static bool program_device(void *src, void *dest, uint32_t length);
57 struct backup_params {
58 uint32_t BANK0_WAIT_RESTORE;
59 uint32_t BANK1_WAIT_RESTORE;
60 uint32_t CS_DC0_FREQ_RESTORE;
61 uint8_t VCORE_LEVEL_RESTORE;
62 uint8_t PCM_VCORE_LEVEL_RESTORE;
65 #define BACKUP_PARAMS ((struct backup_params *) 0x20000180)
67 /* Main with trampoline */
71 MAP_WDT_A_HOLD_TIMER();
73 /* Disable interrupts */
77 switch (FLASH_LOADER->FLASH_FUNCTION) {
79 FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
81 FLASH_LOADER->FLASH_FUNCTION = 0;
83 case FLASH_MASS_ERASE:
84 FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
85 msp432_flash_mass_erase();
86 FLASH_LOADER->FLASH_FUNCTION = 0;
88 case FLASH_SECTOR_ERASE:
89 FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
90 msp432_flash_sector_erase();
91 FLASH_LOADER->FLASH_FUNCTION = 0;
94 FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
96 FLASH_LOADER->FLASH_FUNCTION = 0;
98 case FLASH_CONTINUOUS_PROGRAM:
99 FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
100 msp432_flash_continous_write();
101 FLASH_LOADER->FLASH_FUNCTION = 0;
104 FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
106 FLASH_LOADER->FLASH_FUNCTION = 0;
108 case FLASH_NO_COMMAND:
111 FLASH_LOADER->RETURN_CODE = FLASH_WRONG_COMMAND;
117 /* Initialize flash */
118 void msp432_flash_init(void)
120 bool success = false;
122 /* Point to vector table in RAM */
123 SCB->VTOR = (uint32_t)0x01000000;
125 /* backup system parameters */
126 BACKUP_PARAMS->BANK0_WAIT_RESTORE =
127 MAP_FLASH_CTL_GET_WAIT_STATE(FLASH_BANK0);
128 BACKUP_PARAMS->BANK1_WAIT_RESTORE =
129 MAP_FLASH_CTL_GET_WAIT_STATE(FLASH_BANK1);
130 BACKUP_PARAMS->VCORE_LEVEL_RESTORE = MAP_PCM_GET_CORE_VOLTAGE_LEVEL();
131 BACKUP_PARAMS->PCM_VCORE_LEVEL_RESTORE = MAP_PCM_GET_POWER_STATE();
132 BACKUP_PARAMS->CS_DC0_FREQ_RESTORE = CS->CTL0 & CS_CTL0_DCORSEL_MASK;
134 /* set parameters for flashing */
135 success = MAP_PCM_SET_POWER_STATE(PCM_AM_LDO_VCORE0);
137 /* Set Flash wait states to 2 */
138 MAP_FLASH_CTL_SET_WAIT_STATE(FLASH_BANK0, 2);
139 MAP_FLASH_CTL_SET_WAIT_STATE(FLASH_BANK1, 2);
141 /* Set CPU speed to 24MHz */
142 __cs_set_dco_frequency_range(CS_DCO_FREQUENCY_24);
145 /* Indicate failed power switch */
146 FLASH_LOADER->RETURN_CODE = FLASH_POWER_ERROR;
148 FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
151 /* Erase entire flash */
152 void msp432_flash_mass_erase(void)
154 bool success = false;
156 /* Allow flash writes */
157 unlock_flash_sectors();
159 /* Allow some mass erase repeats before timeout with error */
160 int erase_repeats = FLASH_MAX_REPEATS;
161 while (!success && (erase_repeats > 0)) {
162 /* Mass erase with post-verify */
163 success = MAP_FLASH_CTL_PERFORM_MASS_ERASE();
167 if (erase_repeats == 0)
168 FLASH_LOADER->RETURN_CODE = FLASH_VERIFY_ERROR;
170 FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
172 /* Block flash writes */
173 lock_all_flash_sectors();
176 /* Erase one flash sector */
177 void msp432_flash_sector_erase(void)
179 bool success = false;
181 /* Allow flash writes */
182 unlock_all_flash_sectors();
184 /* Allow some sector erase repeats before timeout with error */
185 int erase_repeats = FLASH_MAX_REPEATS;
186 while (!success && (erase_repeats > 0)) {
187 /* Sector erase with post-verify */
188 success = MAP_FLASH_CTL_ERASE_SECTOR(FLASH_LOADER->DST_ADDRESS);
192 if (erase_repeats == 0)
193 FLASH_LOADER->RETURN_CODE = FLASH_ERROR;
195 FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
197 /* Block flash writes */
198 lock_all_flash_sectors();
201 /* Write data to flash with the help of DriverLib */
202 void msp432_flash_write(void)
204 bool success = false;
206 /* Allow flash writes */
207 unlock_all_flash_sectors();
209 while (!(FLASH_LOADER->BUFFER1_STATUS_REGISTER & BUFFER_DATA_READY))
212 FLASH_LOADER->BUFFER1_STATUS_REGISTER |= BUFFER_ACTIVE;
215 success = program_device((uint32_t *)RAM_LOADER_BUFFER1,
216 (void *)FLASH_LOADER->DST_ADDRESS, FLASH_LOADER->SRC_LENGTH);
218 FLASH_LOADER->BUFFER1_STATUS_REGISTER &=
219 ~(BUFFER_ACTIVE | BUFFER_DATA_READY);
221 /* Block flash writes */
222 lock_all_flash_sectors();
225 FLASH_LOADER->RETURN_CODE = FLASH_ERROR;
227 FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
230 /* Write data to flash with the help of DriverLib with auto-increment */
231 void msp432_flash_continous_write(void)
233 bool buffer1_in_use = false;
234 bool buffer2_in_use = false;
235 uint32_t *src_address = NULL;
236 bool success = false;
238 uint32_t bytes_to_write = FLASH_LOADER->SRC_LENGTH;
239 uint32_t write_package = 0;
240 uint32_t start_addr = FLASH_LOADER->DST_ADDRESS;
242 while (bytes_to_write > 0) {
243 if (bytes_to_write > SRC_LENGTH_MAX) {
244 write_package = SRC_LENGTH_MAX;
245 bytes_to_write -= write_package;
247 write_package = bytes_to_write;
248 bytes_to_write -= write_package;
250 unlock_all_flash_sectors();
252 while (!(FLASH_LOADER->BUFFER1_STATUS_REGISTER & BUFFER_DATA_READY) &&
253 !(FLASH_LOADER->BUFFER2_STATUS_REGISTER & BUFFER_DATA_READY))
256 if (FLASH_LOADER->BUFFER1_STATUS_REGISTER & BUFFER_DATA_READY) {
257 FLASH_LOADER->BUFFER1_STATUS_REGISTER |= BUFFER_ACTIVE;
258 src_address = (uint32_t *)RAM_LOADER_BUFFER1;
259 buffer1_in_use = true;
260 } else if (FLASH_LOADER->BUFFER2_STATUS_REGISTER & BUFFER_DATA_READY) {
261 FLASH_LOADER->BUFFER2_STATUS_REGISTER |= BUFFER_ACTIVE;
262 src_address = (uint32_t *)RAM_LOADER_BUFFER2;
263 buffer2_in_use = true;
265 if (buffer1_in_use || buffer2_in_use) {
266 success = program_device(src_address,
267 (void *)start_addr, write_package);
270 P6->OUT &= ~BIT4; /* Program from B1 */
271 else if (buffer2_in_use)
272 P3->OUT &= ~BIT6; /* Program from B1 */
274 start_addr += write_package;
276 if (buffer1_in_use) {
277 FLASH_LOADER->BUFFER1_STATUS_REGISTER &=
278 ~(BUFFER_ACTIVE | BUFFER_DATA_READY);
279 buffer1_in_use = false;
280 } else if (buffer2_in_use) {
281 FLASH_LOADER->BUFFER2_STATUS_REGISTER &=
282 ~(BUFFER_ACTIVE | BUFFER_DATA_READY);
283 buffer2_in_use = false;
285 /* Block flash writes */
286 lock_all_flash_sectors();
289 FLASH_LOADER->RETURN_CODE = FLASH_ERROR;
294 FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
297 /* Unlock Main/Info Flash sectors */
298 void unlock_flash_sectors(void)
300 if (FLASH_LOADER->ERASE_PARAM & ERASE_MAIN) {
301 MAP_FLASH_CTL_UNPROTECT_SECTOR(FLASH_MAIN_MEMORY_SPACE_BANK0,
303 MAP_FLASH_CTL_UNPROTECT_SECTOR(FLASH_MAIN_MEMORY_SPACE_BANK1,
306 if (FLASH_LOADER->ERASE_PARAM & ERASE_INFO) {
307 MAP_FLASH_CTL_UNPROTECT_SECTOR(FLASH_INFO_MEMORY_SPACE_BANK0,
308 FLASH_SECTOR0 | FLASH_SECTOR1);
309 if (FLASH_LOADER->UNLOCK_BSL == UNLOCK_BSL_KEY)
310 MAP_FLASH_CTL_UNPROTECT_SECTOR(FLASH_INFO_MEMORY_SPACE_BANK1,
311 FLASH_SECTOR0 | FLASH_SECTOR1);
315 /* Unlock All Flash sectors */
316 void unlock_all_flash_sectors(void)
318 MAP_FLASH_CTL_UNPROTECT_SECTOR(FLASH_MAIN_MEMORY_SPACE_BANK0, 0xFFFFFFFF);
319 MAP_FLASH_CTL_UNPROTECT_SECTOR(FLASH_MAIN_MEMORY_SPACE_BANK1, 0xFFFFFFFF);
320 MAP_FLASH_CTL_UNPROTECT_SECTOR(FLASH_INFO_MEMORY_SPACE_BANK0,
321 FLASH_SECTOR0 | FLASH_SECTOR1);
322 if (FLASH_LOADER->UNLOCK_BSL == UNLOCK_BSL_KEY)
323 MAP_FLASH_CTL_UNPROTECT_SECTOR(FLASH_INFO_MEMORY_SPACE_BANK1,
324 FLASH_SECTOR0 | FLASH_SECTOR1);
328 /* Lock all Flash sectors */
329 void lock_all_flash_sectors(void)
331 MAP_FLASH_CTL_PROTECT_SECTOR(FLASH_MAIN_MEMORY_SPACE_BANK0, 0xFFFFFFFF);
332 MAP_FLASH_CTL_PROTECT_SECTOR(FLASH_MAIN_MEMORY_SPACE_BANK1, 0xFFFFFFFF);
333 MAP_FLASH_CTL_PROTECT_SECTOR(FLASH_INFO_MEMORY_SPACE_BANK0,
334 FLASH_SECTOR0 | FLASH_SECTOR1);
335 MAP_FLASH_CTL_PROTECT_SECTOR(FLASH_INFO_MEMORY_SPACE_BANK1,
336 FLASH_SECTOR0 | FLASH_SECTOR1);
340 /* Force DCO frequency range */
341 void __cs_set_dco_frequency_range(uint32_t dco_freq)
343 /* Unlocking the CS Module */
344 CS->KEY = CS_KEY_VAL;
346 /* Resetting Tuning Parameters and Setting the frequency */
347 CS->CTL0 = (CS->CTL0 & ~CS_CTL0_DCORSEL_MASK) | dco_freq;
349 /* Locking the CS Module */
353 /* Exit flash programming */
354 void msp432_flash_exit(void)
356 bool success = false;
358 /* Restore modified registers, in reverse order */
359 __cs_set_dco_frequency_range(CS_DCO_FREQUENCY_3);
361 MAP_FLASH_CTL_SET_WAIT_STATE(FLASH_BANK0,
362 BACKUP_PARAMS->BANK0_WAIT_RESTORE);
363 MAP_FLASH_CTL_SET_WAIT_STATE(FLASH_BANK1,
364 BACKUP_PARAMS->BANK1_WAIT_RESTORE);
366 success = MAP_PCM_SET_POWER_STATE(BACKUP_PARAMS->PCM_VCORE_LEVEL_RESTORE);
368 success &= MAP_PCM_SET_CORE_VOLTAGE_LEVEL(
369 BACKUP_PARAMS->VCORE_LEVEL_RESTORE);
371 __cs_set_dco_frequency_range(BACKUP_PARAMS->CS_DC0_FREQ_RESTORE);
373 /* Point to vector table in Flash */
374 SCB->VTOR = (uint32_t)0x00000000;
377 FLASH_LOADER->RETURN_CODE = FLASH_ERROR;
379 FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
382 static bool program_device(void *src, void *dest, uint32_t length)
384 return MAP_FLASH_CTL_PROGRAM_MEMORY(src, dest, length);