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)
66 #define INFO_FLASH_START __INFO_FLASH_A_TECH_START__
67 #define INFO_FLASH_MIDDLE __INFO_FLASH_A_TECH_MIDDLE__
68 #define BSL_FLASH_START BSL_API_TABLE_ADDR
70 /* Main with trampoline */
74 MAP_WDT_A_HOLD_TIMER();
76 /* Disable interrupts */
80 switch (FLASH_LOADER->FLASH_FUNCTION) {
82 FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
84 FLASH_LOADER->FLASH_FUNCTION = 0;
86 case FLASH_MASS_ERASE:
87 FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
88 msp432_flash_mass_erase();
89 FLASH_LOADER->FLASH_FUNCTION = 0;
91 case FLASH_SECTOR_ERASE:
92 FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
93 msp432_flash_sector_erase();
94 FLASH_LOADER->FLASH_FUNCTION = 0;
97 FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
99 FLASH_LOADER->FLASH_FUNCTION = 0;
101 case FLASH_CONTINUOUS_PROGRAM:
102 FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
103 msp432_flash_continous_write();
104 FLASH_LOADER->FLASH_FUNCTION = 0;
107 FLASH_LOADER->RETURN_CODE = FLASH_BUSY;
109 FLASH_LOADER->FLASH_FUNCTION = 0;
111 case FLASH_NO_COMMAND:
114 FLASH_LOADER->RETURN_CODE = FLASH_WRONG_COMMAND;
120 /* Initialize flash */
121 void msp432_flash_init(void)
123 bool success = false;
125 /* Point to vector table in RAM */
126 SCB->VTOR = (uint32_t)0x01000000;
128 /* backup system parameters */
129 BACKUP_PARAMS->BANK0_WAIT_RESTORE =
130 MAP_FLASH_CTL_A_GET_WAIT_STATE(FLASH_A_BANK0);
131 BACKUP_PARAMS->BANK1_WAIT_RESTORE =
132 MAP_FLASH_CTL_A_GET_WAIT_STATE(FLASH_A_BANK1);
133 BACKUP_PARAMS->VCORE_LEVEL_RESTORE = MAP_PCM_GET_CORE_VOLTAGE_LEVEL();
134 BACKUP_PARAMS->PCM_VCORE_LEVEL_RESTORE = MAP_PCM_GET_POWER_STATE();
135 BACKUP_PARAMS->CS_DC0_FREQ_RESTORE = CS->CTL0 & CS_CTL0_DCORSEL_MASK;
137 /* set parameters for flashing */
138 success = MAP_PCM_SET_POWER_STATE(PCM_AM_LDO_VCORE0);
140 /* Set Flash wait states to 2 */
141 MAP_FLASH_CTL_A_SET_WAIT_STATE(FLASH_A_BANK0, 2);
142 MAP_FLASH_CTL_A_SET_WAIT_STATE(FLASH_A_BANK1, 2);
144 /* Set CPU speed to 24MHz */
145 __cs_set_dco_frequency_range(CS_DCO_FREQUENCY_24);
148 /* Indicate failed power switch */
149 FLASH_LOADER->RETURN_CODE = FLASH_POWER_ERROR;
151 FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
154 /* Erase entire flash */
155 void msp432_flash_mass_erase(void)
157 bool success = false;
159 /* Allow flash writes */
160 unlock_flash_sectors();
162 /* Allow some mass erase repeats before timeout with error */
163 int erase_repeats = FLASH_MAX_REPEATS;
164 while (!success && (erase_repeats > 0)) {
165 /* Mass erase with post-verify */
166 success = ROM_FLASH_CTL_A_PERFORM_MASS_ERASE();
170 if (erase_repeats == 0)
171 FLASH_LOADER->RETURN_CODE = FLASH_VERIFY_ERROR;
173 FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
175 /* Block flash writes */
176 lock_all_flash_sectors();
179 /* Erase one flash sector */
180 void msp432_flash_sector_erase(void)
182 bool success = false;
184 /* Allow flash writes */
185 unlock_all_flash_sectors();
187 /* Allow some sector erase repeats before timeout with error */
188 int erase_repeats = FLASH_MAX_REPEATS;
189 while (!success && (erase_repeats > 0)) {
190 /* Sector erase with post-verify */
191 success = MAP_FLASH_CTL_A_ERASE_SECTOR(FLASH_LOADER->DST_ADDRESS);
195 if (erase_repeats == 0)
196 FLASH_LOADER->RETURN_CODE = FLASH_ERROR;
198 FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
200 /* Block flash writes */
201 lock_all_flash_sectors();
204 /* Write data to flash with the help of DriverLib */
205 void msp432_flash_write(void)
207 bool success = false;
209 /* Allow flash writes */
210 unlock_all_flash_sectors();
212 while (!(FLASH_LOADER->BUFFER1_STATUS_REGISTER & BUFFER_DATA_READY))
215 FLASH_LOADER->BUFFER1_STATUS_REGISTER |= BUFFER_ACTIVE;
218 success = program_device((uint32_t *)RAM_LOADER_BUFFER1,
219 (void *)FLASH_LOADER->DST_ADDRESS, FLASH_LOADER->SRC_LENGTH);
221 FLASH_LOADER->BUFFER1_STATUS_REGISTER &=
222 ~(BUFFER_ACTIVE | BUFFER_DATA_READY);
224 /* Block flash writes */
225 lock_all_flash_sectors();
228 FLASH_LOADER->RETURN_CODE = FLASH_ERROR;
230 FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
233 /* Write data to flash with the help of DriverLib with auto-increment */
234 void msp432_flash_continous_write(void)
236 bool buffer1_in_use = false;
237 bool buffer2_in_use = false;
238 uint32_t *src_address = NULL;
239 bool success = false;
241 uint32_t bytes_to_write = FLASH_LOADER->SRC_LENGTH;
242 uint32_t write_package = 0;
243 uint32_t start_addr = FLASH_LOADER->DST_ADDRESS;
245 while (bytes_to_write > 0) {
246 if (bytes_to_write > SRC_LENGTH_MAX) {
247 write_package = SRC_LENGTH_MAX;
248 bytes_to_write -= write_package;
250 write_package = bytes_to_write;
251 bytes_to_write -= write_package;
253 unlock_all_flash_sectors();
254 while (!(FLASH_LOADER->BUFFER1_STATUS_REGISTER & BUFFER_DATA_READY) &&
255 !(FLASH_LOADER->BUFFER2_STATUS_REGISTER & BUFFER_DATA_READY))
258 if (FLASH_LOADER->BUFFER1_STATUS_REGISTER & BUFFER_DATA_READY) {
259 FLASH_LOADER->BUFFER1_STATUS_REGISTER |= BUFFER_ACTIVE;
260 src_address = (uint32_t *) RAM_LOADER_BUFFER1;
261 buffer1_in_use = true;
262 } else if (FLASH_LOADER->BUFFER2_STATUS_REGISTER & BUFFER_DATA_READY) {
263 FLASH_LOADER->BUFFER2_STATUS_REGISTER |= BUFFER_ACTIVE;
264 src_address = (uint32_t *) RAM_LOADER_BUFFER2;
265 buffer2_in_use = true;
267 if (buffer1_in_use || buffer2_in_use) {
268 success = program_device(src_address, (void *) start_addr, write_package);
269 start_addr += write_package;
271 if (buffer1_in_use) {
272 FLASH_LOADER->BUFFER1_STATUS_REGISTER &= ~(BUFFER_ACTIVE | BUFFER_DATA_READY);
273 buffer1_in_use = false;
274 } else if (buffer2_in_use) {
275 FLASH_LOADER->BUFFER2_STATUS_REGISTER &= ~(BUFFER_ACTIVE | BUFFER_DATA_READY);
276 buffer2_in_use = false;
278 /* Block flash writes */
279 lock_all_flash_sectors();
282 FLASH_LOADER->RETURN_CODE = FLASH_ERROR;
287 FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
290 /* Unlock Main/Info Flash sectors */
291 void unlock_flash_sectors(void)
293 if (FLASH_LOADER->ERASE_PARAM & ERASE_MAIN)
294 MAP_FLASH_CTL_A_UNPROTECT_MEMORY(FLASH_BASE, FLASH_BASE +
295 MAP_SYS_CTL_A_GET_FLASH_SIZE() - 1);
297 if (FLASH_LOADER->ERASE_PARAM & ERASE_INFO) {
298 MAP_FLASH_CTL_A_UNPROTECT_MEMORY(INFO_FLASH_START, TLV_BASE - 1);
299 if (FLASH_LOADER->UNLOCK_BSL == UNLOCK_BSL_KEY)
300 MAP_FLASH_CTL_A_UNPROTECT_MEMORY(BSL_FLASH_START,
301 INFO_FLASH_MIDDLE - 1);
302 MAP_FLASH_CTL_A_UNPROTECT_MEMORY(INFO_FLASH_MIDDLE, INFO_FLASH_MIDDLE +
303 MAP_SYS_CTL_A_GET_INFO_FLASH_SIZE() - 1);
307 /* Unlock All Flash sectors */
308 void unlock_all_flash_sectors(void)
310 MAP_FLASH_CTL_A_UNPROTECT_MEMORY(FLASH_BASE, FLASH_BASE +
311 MAP_SYS_CTL_A_GET_FLASH_SIZE() - 1);
312 MAP_FLASH_CTL_A_UNPROTECT_MEMORY(INFO_FLASH_START, TLV_BASE - 1);
313 if (FLASH_LOADER->UNLOCK_BSL == UNLOCK_BSL_KEY)
314 MAP_FLASH_CTL_A_UNPROTECT_MEMORY(BSL_FLASH_START,
315 INFO_FLASH_MIDDLE - 1);
316 MAP_FLASH_CTL_A_UNPROTECT_MEMORY(INFO_FLASH_MIDDLE, INFO_FLASH_MIDDLE +
317 MAP_SYS_CTL_A_GET_INFO_FLASH_SIZE() - 1);
320 /* Lock all Flash sectors */
321 void lock_all_flash_sectors(void)
323 MAP_FLASH_CTL_A_PROTECT_MEMORY(FLASH_BASE, FLASH_BASE +
324 MAP_SYS_CTL_A_GET_FLASH_SIZE() - 1);
325 MAP_FLASH_CTL_A_PROTECT_MEMORY(INFO_FLASH_START, INFO_FLASH_START +
326 MAP_SYS_CTL_A_GET_INFO_FLASH_SIZE() - 1);
329 /* Force DCO frequency range */
330 void __cs_set_dco_frequency_range(uint32_t dco_freq)
332 /* Unlocking the CS Module */
333 CS->KEY = CS_KEY_VAL;
335 /* Resetting Tuning Parameters and Setting the frequency */
336 CS->CTL0 = (CS->CTL0 & ~CS_CTL0_DCORSEL_MASK) | dco_freq;
338 /* Locking the CS Module */
342 /* Exit flash programming */
343 void msp432_flash_exit(void)
345 bool success = false;
347 /* Restore modified registers, in reverse order */
348 __cs_set_dco_frequency_range(CS_DCO_FREQUENCY_3);
350 MAP_FLASH_CTL_A_SET_WAIT_STATE(FLASH_A_BANK0,
351 BACKUP_PARAMS->BANK0_WAIT_RESTORE);
352 MAP_FLASH_CTL_A_SET_WAIT_STATE(FLASH_A_BANK1,
353 BACKUP_PARAMS->BANK1_WAIT_RESTORE);
355 success = MAP_PCM_SET_POWER_STATE(BACKUP_PARAMS->PCM_VCORE_LEVEL_RESTORE);
357 success &= MAP_PCM_SET_CORE_VOLTAGE_LEVEL(
358 BACKUP_PARAMS->VCORE_LEVEL_RESTORE);
360 __cs_set_dco_frequency_range(BACKUP_PARAMS->CS_DC0_FREQ_RESTORE);
362 /* Point to vector table in Flash */
363 SCB->VTOR = (uint32_t)0x00000000;
366 FLASH_LOADER->RETURN_CODE = FLASH_ERROR;
368 FLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;
371 static bool program_device(void *src, void *dest, uint32_t length)
373 uint32_t dst_address = (uint32_t)dest;
375 /* Flash main memory first, then information memory */
376 if ((dst_address < INFO_FLASH_START) && ((dst_address + length) >
378 uint32_t block_length = INFO_FLASH_START - dst_address;
379 uint32_t src_address = (uint32_t)src;
380 /* Main memory block */
381 bool success = MAP_FLASH_CTL_A_PROGRAM_MEMORY(src, dest, block_length);
383 src_address = src_address + block_length;
384 block_length = length - block_length;
385 /* Information memory block */
386 success &= MAP_FLASH_CTL_A_PROGRAM_MEMORY((void *)src_address,
387 (void *)INFO_FLASH_START, block_length);
390 return MAP_FLASH_CTL_A_PROGRAM_MEMORY(src, dest, length);