1 /* SPDX-License-Identifier: BSD-3-Clause */
3 /******************************************************************************
5 * Copyright (C) 2017-2018 Texas Instruments Incorporated - http://www.ti.com/
7 ******************************************************************************/
11 #include "flashloader.h"
13 /* Data buffers used by host to communicate with flashloader */
15 /* Flashloader parameter structure. */
16 __attribute__ ((section(".buffers.g_cfg")))
17 volatile struct flash_params g_cfg[2];
19 __attribute__ ((section(".buffers.g_buf1")))
20 uint8_t g_buf1[BUFFER_LEN];
22 __attribute__ ((section(".buffers.g_buf2")))
23 uint8_t g_buf2[BUFFER_LEN];
25 /* Buffer used for program with retain feature */
26 __attribute__ ((section(".buffers.g_retain_buf")))
27 uint8_t g_retain_buf[BUFFER_LEN];
29 uint32_t g_curr_buf; /* Current buffer used. */
30 uint32_t g_vims_ctl; /* Saved flash cache state. */
32 /******************************************************************************
34 * This function stores the current VIMS configuration before
35 * - disabling VIMS flash cache
36 * - flushing the flash line buffers.
38 * Note Not using driverlib calls because it requires using "NO_ROM" define in
39 * order to work for both Cha. R1 and R2 using the same code. Manually
40 * doing the steps to minimize code footprint.
42 ******************************************************************************/
43 static void disable_flash_cache()
45 /* 1. Make sure VIMS is not currently changing mode (VIMS:STAT register) */
46 while ((HWREG(0x40034000) & 0x00000008) == 0x8)
49 /* Save current VIMS:CTL state */
50 g_vims_ctl = HWREG(0x40034004);
52 /* 2. Set VIMS mode to OFF and disable flash line buffers */
53 uint32_t new_vims_ctl = g_vims_ctl | 0x33;
54 HWREG(0x40034004) = new_vims_ctl;
56 /* 3. Wait for VIMS to have changed mode (VIMS:STAT register) */
57 while ((HWREG(0x40034000) & 0x00000008) == 0x8)
61 /******************************************************************************
63 * This function restores the VIMS configuration saved off by
64 * disable_flash_cache().
66 * Note Not using driverlib calls because it requires using "NO_ROM" define in
67 * order to work for both Cha. R1 and R2 using the same code. Manually
68 * doing the steps to minimize code footprint.
70 ******************************************************************************/
71 static void restore_cache_state()
73 HWREG(0x40034004) = g_vims_ctl;
75 /* Wait for VIMS to have changed mode (VIMS:STAT register) */
76 while ((HWREG(0x40034000) & 0x00000008) == 0x8)
80 /******************************************************************************
82 * CC13xx/CC26xx flashloader main function.
84 ******************************************************************************/
87 flashloader_init((struct flash_params *)g_cfg, g_buf1, g_buf2);
89 g_curr_buf = 0; /* start with the first buffer */
93 /* Wait for host to signal buffer is ready */
94 while (g_cfg[g_curr_buf].full == BUFFER_EMPTY)
97 disable_flash_cache();
99 /* Perform requested task */
100 switch (g_cfg[g_curr_buf].cmd) {
102 status = flashloader_erase_all();
107 (uint8_t *)g_cfg[g_curr_buf].buf_addr,
108 g_cfg[g_curr_buf].dest, g_cfg[g_curr_buf].len);
110 case CMD_ERASE_AND_PROGRAM:
112 flashloader_erase_and_program(
113 (uint8_t *)g_cfg[g_curr_buf].buf_addr,
114 g_cfg[g_curr_buf].dest, g_cfg[g_curr_buf].len);
116 case CMD_ERASE_AND_PROGRAM_WITH_RETAIN:
118 flashloader_program_with_retain(
119 (uint8_t *)g_cfg[g_curr_buf].buf_addr,
120 g_cfg[g_curr_buf].dest, g_cfg[g_curr_buf].len);
122 case CMD_ERASE_SECTORS:
124 flashloader_erase_sectors(g_cfg[g_curr_buf].dest,
125 g_cfg[g_curr_buf].len);
128 status = STATUS_FAILED_UNKNOWN_COMMAND;
132 restore_cache_state();
134 /* Enter infinite loop on error condition */
135 if (status != STATUS_OK) {
136 g_cfg[g_curr_buf].full = status;
141 /* Mark current task complete, and begin looking at next buffer */
142 g_cfg[g_curr_buf].full = BUFFER_EMPTY;
147 void _exit(int status)
149 /* Enter infinite loop on hitting an exit condition */
150 (void)status; /* Unused parameter */