summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEdward Fewell2017-12-18 20:55:01 -0600
committerEdward Fewell2017-12-18 20:55:01 -0600
commit2749f0d0372b410be91cee7134fef4cd14da7bf4 (patch)
treee5dc98555be0839a3edb8e8af2aa7bfa88eee32f
parent9f688ff4b1fe0acf7b742b8682f66b75a0bb811f (diff)
downloadopenocd-2749f0d0372b410be91cee7134fef4cd14da7bf4.tar.gz
openocd-2749f0d0372b410be91cee7134fef4cd14da7bf4.tar.xz
openocd-2749f0d0372b410be91cee7134fef4cd14da7bf4.zip
Add support for CC32xx and CC3220SF targets
-rw-r--r--openocd/Makefile.in45
-rw-r--r--openocd/src/flash/nor/Makefile.am2
-rw-r--r--openocd/src/flash/nor/cc3220sf.c435
-rw-r--r--openocd/src/flash/nor/cc3220sf.h135
-rw-r--r--openocd/src/flash/nor/drivers.c2
-rw-r--r--openocd/tcl/board/ti_cc3220sf_launchpad.cfg7
-rw-r--r--openocd/tcl/board/ti_cc32xx_launchpad.cfg7
-rw-r--r--openocd/tcl/target/ti_cc32xx.cfg71
8 files changed, 684 insertions, 20 deletions
diff --git a/openocd/Makefile.in b/openocd/Makefile.in
index b52ccf6..399e401 100644
--- a/openocd/Makefile.in
+++ b/openocd/Makefile.in
@@ -238,26 +238,26 @@ am__objects_3 = src/flash/nor/aduc702x.lo src/flash/nor/aducm360.lo \
238 src/flash/nor/at91sam4l.lo src/flash/nor/at91samd.lo \ 238 src/flash/nor/at91sam4l.lo src/flash/nor/at91samd.lo \
239 src/flash/nor/at91sam3.lo src/flash/nor/at91sam7.lo \ 239 src/flash/nor/at91sam3.lo src/flash/nor/at91sam7.lo \
240 src/flash/nor/atsamv.lo src/flash/nor/avrf.lo \ 240 src/flash/nor/atsamv.lo src/flash/nor/avrf.lo \
241 src/flash/nor/cfi.lo src/flash/nor/dsp5680xx_flash.lo \ 241 src/flash/nor/cc3220sf.lo src/flash/nor/cfi.lo \
242 src/flash/nor/efm32.lo src/flash/nor/em357.lo \ 242 src/flash/nor/dsp5680xx_flash.lo src/flash/nor/efm32.lo \
243 src/flash/nor/faux.lo src/flash/nor/fm3.lo \ 243 src/flash/nor/em357.lo src/flash/nor/faux.lo \
244 src/flash/nor/fm4.lo src/flash/nor/jtagspi.lo \ 244 src/flash/nor/fm3.lo src/flash/nor/fm4.lo \
245 src/flash/nor/kinetis.lo src/flash/nor/kinetis_ke.lo \ 245 src/flash/nor/jtagspi.lo src/flash/nor/kinetis.lo \
246 src/flash/nor/lpc2000.lo src/flash/nor/lpc288x.lo \ 246 src/flash/nor/kinetis_ke.lo src/flash/nor/lpc2000.lo \
247 src/flash/nor/lpc2900.lo src/flash/nor/lpcspifi.lo \ 247 src/flash/nor/lpc288x.lo src/flash/nor/lpc2900.lo \
248 src/flash/nor/mdr.lo src/flash/nor/mrvlqspi.lo \ 248 src/flash/nor/lpcspifi.lo src/flash/nor/mdr.lo \
249 src/flash/nor/msp432.lo src/flash/nor/niietcm4.lo \ 249 src/flash/nor/mrvlqspi.lo src/flash/nor/msp432.lo \
250 src/flash/nor/non_cfi.lo src/flash/nor/nrf51.lo \ 250 src/flash/nor/niietcm4.lo src/flash/nor/non_cfi.lo \
251 src/flash/nor/numicro.lo src/flash/nor/ocl.lo \ 251 src/flash/nor/nrf51.lo src/flash/nor/numicro.lo \
252 src/flash/nor/pic32mx.lo src/flash/nor/psoc4.lo \ 252 src/flash/nor/ocl.lo src/flash/nor/pic32mx.lo \
253 src/flash/nor/sim3x.lo src/flash/nor/spi.lo \ 253 src/flash/nor/psoc4.lo src/flash/nor/sim3x.lo \
254 src/flash/nor/stmsmi.lo src/flash/nor/stellaris.lo \ 254 src/flash/nor/spi.lo src/flash/nor/stmsmi.lo \
255 src/flash/nor/stm32f1x.lo src/flash/nor/stm32f2x.lo \ 255 src/flash/nor/stellaris.lo src/flash/nor/stm32f1x.lo \
256 src/flash/nor/stm32lx.lo src/flash/nor/stm32l4x.lo \ 256 src/flash/nor/stm32f2x.lo src/flash/nor/stm32lx.lo \
257 src/flash/nor/str7x.lo src/flash/nor/str9x.lo \ 257 src/flash/nor/stm32l4x.lo src/flash/nor/str7x.lo \
258 src/flash/nor/str9xpec.lo src/flash/nor/tms470.lo \ 258 src/flash/nor/str9x.lo src/flash/nor/str9xpec.lo \
259 src/flash/nor/virtual.lo src/flash/nor/xmc1xxx.lo \ 259 src/flash/nor/tms470.lo src/flash/nor/virtual.lo \
260 src/flash/nor/xmc4xxx.lo 260 src/flash/nor/xmc1xxx.lo src/flash/nor/xmc4xxx.lo
261am_src_flash_nor_libocdflashnor_la_OBJECTS = src/flash/nor/core.lo \ 261am_src_flash_nor_libocdflashnor_la_OBJECTS = src/flash/nor/core.lo \
262 src/flash/nor/tcl.lo $(am__objects_3) src/flash/nor/drivers.lo \ 262 src/flash/nor/tcl.lo $(am__objects_3) src/flash/nor/drivers.lo \
263 $(am__objects_2) 263 $(am__objects_2)
@@ -1479,6 +1479,7 @@ NOR_DRIVERS = \
1479 src/flash/nor/at91sam7.c \ 1479 src/flash/nor/at91sam7.c \
1480 src/flash/nor/atsamv.c \ 1480 src/flash/nor/atsamv.c \
1481 src/flash/nor/avrf.c \ 1481 src/flash/nor/avrf.c \
1482 src/flash/nor/cc3220sf.c \
1482 src/flash/nor/cfi.c \ 1483 src/flash/nor/cfi.c \
1483 src/flash/nor/dsp5680xx_flash.c \ 1484 src/flash/nor/dsp5680xx_flash.c \
1484 src/flash/nor/efm32.c \ 1485 src/flash/nor/efm32.c \
@@ -1521,6 +1522,7 @@ NOR_DRIVERS = \
1521 1522
1522NORHEADERS = \ 1523NORHEADERS = \
1523 src/flash/nor/core.h \ 1524 src/flash/nor/core.h \
1525 src/flash/nor/cc3220sf.h \
1524 src/flash/nor/cfi.h \ 1526 src/flash/nor/cfi.h \
1525 src/flash/nor/driver.h \ 1527 src/flash/nor/driver.h \
1526 src/flash/nor/imp.h \ 1528 src/flash/nor/imp.h \
@@ -1741,6 +1743,8 @@ src/flash/nor/atsamv.lo: src/flash/nor/$(am__dirstamp) \
1741 src/flash/nor/$(DEPDIR)/$(am__dirstamp) 1743 src/flash/nor/$(DEPDIR)/$(am__dirstamp)
1742src/flash/nor/avrf.lo: src/flash/nor/$(am__dirstamp) \ 1744src/flash/nor/avrf.lo: src/flash/nor/$(am__dirstamp) \
1743 src/flash/nor/$(DEPDIR)/$(am__dirstamp) 1745 src/flash/nor/$(DEPDIR)/$(am__dirstamp)
1746src/flash/nor/cc3220sf.lo: src/flash/nor/$(am__dirstamp) \
1747 src/flash/nor/$(DEPDIR)/$(am__dirstamp)
1744src/flash/nor/cfi.lo: src/flash/nor/$(am__dirstamp) \ 1748src/flash/nor/cfi.lo: src/flash/nor/$(am__dirstamp) \
1745 src/flash/nor/$(DEPDIR)/$(am__dirstamp) 1749 src/flash/nor/$(DEPDIR)/$(am__dirstamp)
1746src/flash/nor/dsp5680xx_flash.lo: src/flash/nor/$(am__dirstamp) \ 1750src/flash/nor/dsp5680xx_flash.lo: src/flash/nor/$(am__dirstamp) \
@@ -2560,6 +2564,7 @@ distclean-compile:
2560@AMDEP_TRUE@@am__include@ @am__quote@src/flash/nor/$(DEPDIR)/at91samd.Plo@am__quote@ 2564@AMDEP_TRUE@@am__include@ @am__quote@src/flash/nor/$(DEPDIR)/at91samd.Plo@am__quote@
2561@AMDEP_TRUE@@am__include@ @am__quote@src/flash/nor/$(DEPDIR)/atsamv.Plo@am__quote@ 2565@AMDEP_TRUE@@am__include@ @am__quote@src/flash/nor/$(DEPDIR)/atsamv.Plo@am__quote@
2562@AMDEP_TRUE@@am__include@ @am__quote@src/flash/nor/$(DEPDIR)/avrf.Plo@am__quote@ 2566@AMDEP_TRUE@@am__include@ @am__quote@src/flash/nor/$(DEPDIR)/avrf.Plo@am__quote@
2567@AMDEP_TRUE@@am__include@ @am__quote@src/flash/nor/$(DEPDIR)/cc3220sf.Plo@am__quote@
2563@AMDEP_TRUE@@am__include@ @am__quote@src/flash/nor/$(DEPDIR)/cfi.Plo@am__quote@ 2568@AMDEP_TRUE@@am__include@ @am__quote@src/flash/nor/$(DEPDIR)/cfi.Plo@am__quote@
2564@AMDEP_TRUE@@am__include@ @am__quote@src/flash/nor/$(DEPDIR)/core.Plo@am__quote@ 2569@AMDEP_TRUE@@am__include@ @am__quote@src/flash/nor/$(DEPDIR)/core.Plo@am__quote@
2565@AMDEP_TRUE@@am__include@ @am__quote@src/flash/nor/$(DEPDIR)/drivers.Plo@am__quote@ 2570@AMDEP_TRUE@@am__include@ @am__quote@src/flash/nor/$(DEPDIR)/drivers.Plo@am__quote@
diff --git a/openocd/src/flash/nor/Makefile.am b/openocd/src/flash/nor/Makefile.am
index 2b6753c..4b40326 100644
--- a/openocd/src/flash/nor/Makefile.am
+++ b/openocd/src/flash/nor/Makefile.am
@@ -17,6 +17,7 @@ NOR_DRIVERS = \
17 %D%/at91sam7.c \ 17 %D%/at91sam7.c \
18 %D%/atsamv.c \ 18 %D%/atsamv.c \
19 %D%/avrf.c \ 19 %D%/avrf.c \
20 %D%/cc3220sf.c \
20 %D%/cfi.c \ 21 %D%/cfi.c \
21 %D%/dsp5680xx_flash.c \ 22 %D%/dsp5680xx_flash.c \
22 %D%/efm32.c \ 23 %D%/efm32.c \
@@ -59,6 +60,7 @@ NOR_DRIVERS = \
59 60
60NORHEADERS = \ 61NORHEADERS = \
61 %D%/core.h \ 62 %D%/core.h \
63 %D%/cc3220sf.h \
62 %D%/cfi.h \ 64 %D%/cfi.h \
63 %D%/driver.h \ 65 %D%/driver.h \
64 %D%/imp.h \ 66 %D%/imp.h \
diff --git a/openocd/src/flash/nor/cc3220sf.c b/openocd/src/flash/nor/cc3220sf.c
new file mode 100644
index 0000000..6841c58
--- /dev/null
+++ b/openocd/src/flash/nor/cc3220sf.c
@@ -0,0 +1,435 @@
1/***************************************************************************
2 * Copyright (C) 2017 by Texas Instruments, Inc. *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
16 ***************************************************************************/
17
18#ifdef HAVE_CONFIG_H
19#include "config.h"
20#endif
21
22#include "imp.h"
23#include "cc3220sf.h"
24#include <helper/time_support.h>
25#include <target/algorithm.h>
26#include <target/armv7m.h>
27
28#define FLASH_TIMEOUT 5000
29
30struct cc3220sf_bank {
31 bool probed;
32 struct working_area *working_area;
33 struct armv7m_algorithm armv7m_info;
34};
35
36static int cc3220sf_mass_erase(struct flash_bank *bank)
37{
38 struct target *target = bank->target;
39 bool done;
40 long long start_ms;
41 long long elapsed_ms;
42 uint32_t value;
43
44 int retval = ERROR_OK;
45
46 if (TARGET_HALTED != target->state) {
47 LOG_ERROR("Target not halted");
48 return ERROR_TARGET_NOT_HALTED;
49 }
50
51 /* Set starting address to erase to zero */
52 value = 0;
53 retval = target_write_buffer(target, FMA_REGISTER_ADDR,
54 sizeof(value), (uint8_t *)&value);
55 if (ERROR_OK != retval)
56 return retval;
57
58 /* Write the MERASE bit of the FMC register */
59 value = FMC_DEFAULT_VALUE | FMC_MERASE_BIT;
60 retval = target_write_buffer(target, FMC_REGISTER_ADDR,
61 sizeof(value), (uint8_t *)&value);
62 if (ERROR_OK != retval)
63 return retval;
64
65 /* Poll the MERASE bit until the mass erase is complete */
66 done = false;
67 start_ms = timeval_ms();
68 while (!done) {
69 retval = target_read_buffer(target, FMC_REGISTER_ADDR,
70 sizeof(value), (uint8_t *)&value);
71 if (ERROR_OK != retval)
72 return retval;
73
74 if ((value & FMC_MERASE_BIT) == 0) {
75 /* Bit clears when mass erase is finished */
76 done = true;
77 } else {
78 elapsed_ms = timeval_ms() - start_ms;
79 if (elapsed_ms > 500)
80 keep_alive();
81 if (elapsed_ms > FLASH_TIMEOUT)
82 break;
83 }
84 }
85
86 if (!done) {
87 /* Mass erase timed out waiting for confirmation */
88 return ERROR_FAIL;
89 }
90
91 /* Mark all sectors erased */
92 if (0 != bank->sectors) {
93 for (int i = 0; i < bank->num_sectors; i++)
94 bank->sectors[i].is_erased = 1;
95 }
96
97 return retval;
98}
99
100FLASH_BANK_COMMAND_HANDLER(cc3220sf_flash_bank_command)
101{
102 struct cc3220sf_bank *cc3220sf_bank;
103
104 if (CMD_ARGC < 6)
105 return ERROR_COMMAND_SYNTAX_ERROR;
106
107 cc3220sf_bank = malloc(sizeof(struct cc3220sf_bank));
108 if (0 == cc3220sf_bank)
109 return ERROR_FAIL;
110
111 /* Initialize private flash information */
112 cc3220sf_bank->probed = false;
113 cc3220sf_bank->working_area = 0;
114
115 /* Finish initialization of flash bank */
116 bank->driver_priv = cc3220sf_bank;
117 bank->next = 0;
118
119 return ERROR_OK;
120}
121
122static int cc3220sf_erase(struct flash_bank *bank, int first, int last)
123{
124 struct target *target = bank->target;
125 bool done;
126 long long start_ms;
127 long long elapsed_ms;
128 uint32_t address;
129 uint32_t value;
130
131 int retval = ERROR_OK;
132
133 if (TARGET_HALTED != target->state) {
134 LOG_ERROR("Target not halted");
135 return ERROR_TARGET_NOT_HALTED;
136 }
137
138 /* Do a mass erase if user requested all sectors of flash */
139 if ((first == 0) && (last == (bank->num_sectors - 1))) {
140 /* Request mass erase of flash */
141 return cc3220sf_mass_erase(bank);
142 }
143
144 /* Erase requested sectors one by one */
145 for (int i = first; i <= last; i++) {
146
147 /* Determine address of sector to erase */
148 address = FLASH_BASE_ADDR + i * FLASH_SECTOR_SIZE;
149
150 /* Set starting address to erase */
151 retval = target_write_buffer(target, FMA_REGISTER_ADDR,
152 sizeof(address), (uint8_t *)&address);
153 if (ERROR_OK != retval)
154 return retval;
155
156 /* Write the ERASE bit of the FMC register */
157 value = FMC_DEFAULT_VALUE | FMC_ERASE_BIT;
158 retval = target_write_buffer(target, FMC_REGISTER_ADDR,
159 sizeof(value), (uint8_t *)&value);
160 if (ERROR_OK != retval)
161 return retval;
162
163 /* Poll the ERASE bit until the erase is complete */
164 done = false;
165 start_ms = timeval_ms();
166 while (!done) {
167 retval = target_read_buffer(target, FMC_REGISTER_ADDR,
168 sizeof(value), (uint8_t *)&value);
169 if (ERROR_OK != retval)
170 return retval;
171
172 if ((value & FMC_ERASE_BIT) == 0) {
173 /* Bit clears when mass erase is finished */
174 done = true;
175 } else {
176 elapsed_ms = timeval_ms() - start_ms;
177 if (elapsed_ms > 500)
178 keep_alive();
179 if (elapsed_ms > FLASH_TIMEOUT)
180 break;
181 }
182 }
183
184 if (!done) {
185 /* Sector erase timed out waiting for confirmation */
186 return ERROR_FAIL;
187 }
188
189 /* Mark the sector as erased */
190 if (0 != bank->sectors)
191 bank->sectors[i].is_erased = 1;
192 }
193
194 return retval;
195}
196
197static int cc3220sf_protect(struct flash_bank *bank, int set, int first,
198 int last)
199{
200 return ERROR_OK;
201}
202
203static int cc3220sf_write(struct flash_bank *bank, const uint8_t *buffer,
204 uint32_t offset, uint32_t count)
205{
206 struct target *target = bank->target;
207 struct cc3220sf_bank *cc3220sf_bank = bank->driver_priv;
208 struct reg_param reg_params[3];
209 uint32_t address;
210 uint32_t remaining;
211 uint32_t words;
212 uint32_t end_address = offset + count - 1;
213 uint32_t sector;
214 uint32_t result;
215
216 int retval = ERROR_OK;
217
218 if (TARGET_HALTED != target->state) {
219 LOG_ERROR("Target not halted");
220 return ERROR_TARGET_NOT_HALTED;
221 }
222
223 /* Check for working area to use for flash helper algorithm */
224 if (0 != cc3220sf_bank->working_area)
225 target_free_working_area(target, cc3220sf_bank->working_area);
226 retval = target_alloc_working_area(target, ALGO_WORKING_SIZE,
227 &cc3220sf_bank->working_area);
228 if (ERROR_OK != retval)
229 return retval;
230
231 /* Confirm the defined working address is the area we need to use */
232 if (ALGO_BASE_ADDR != cc3220sf_bank->working_area->address)
233 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
234
235 /* Write flash helper algorithm into target memory */
236 retval = target_write_buffer(target, ALGO_BASE_ADDR,
237 sizeof(cc3220sf_algo), cc3220sf_algo);
238 if (ERROR_OK != retval)
239 return retval;
240
241 /* Initialize the ARMv7m specific info to run the algorithm */
242 cc3220sf_bank->armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
243 cc3220sf_bank->armv7m_info.core_mode = ARM_MODE_THREAD;
244
245 /* Initialize register params for flash helper algorithm */
246 init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
247 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
248 init_reg_param(&reg_params[2], "r2", 32, PARAM_IN_OUT);
249
250 /* Prepare to write to flash */
251 address = FLASH_BASE_ADDR + offset;
252 remaining = count;
253
254 while (remaining > 0) {
255 /* Helper parameters are passed in registers R0-R2 */
256 /* Set address to write to and start of data buffer */
257 buf_set_u32(reg_params[0].value, 0, 32, ALGO_BUFFER_ADDR);
258 buf_set_u32(reg_params[1].value, 0, 32, address);
259
260 /* Download data to write into memory buffer */
261 if (remaining >= ALGO_BUFFER_SIZE) {
262 /* Fill up buffer with data to flash */
263 retval = target_write_buffer(target, ALGO_BUFFER_ADDR,
264 ALGO_BUFFER_SIZE, buffer);
265 if (ERROR_OK != retval)
266 break;
267
268 /* Count to write is in 32-bit words */
269 words = ALGO_BUFFER_SIZE / 4;
270
271 /* Bump variables to next data */
272 address += ALGO_BUFFER_SIZE;
273 buffer += ALGO_BUFFER_SIZE;
274 remaining -= ALGO_BUFFER_SIZE;
275 } else {
276 /* Fill buffer with what's left of the data */
277 retval = target_write_buffer(target, ALGO_BUFFER_ADDR,
278 remaining, buffer);
279 if (ERROR_OK != retval)
280 break;
281
282 /* Calculate the final word count to write */
283 words = remaining / 4;
284 if (0 != (remaining % 4))
285 words++;
286
287 /* All done after this last buffer */
288 remaining = 0;
289 }
290
291 /* Set number of words to write */
292 buf_set_u32(reg_params[2].value, 0, 32, words);
293
294 /* Execute the flash helper algorithm */
295 retval = target_run_algorithm(target, 0, 0, 3, reg_params,
296 ALGO_BASE_ADDR, 0, FLASH_TIMEOUT,
297 &cc3220sf_bank->armv7m_info);
298 if (ERROR_OK != retval) {
299 LOG_ERROR("cc3220sf: Flash algorithm failed to run");
300 break;
301 }
302
303 /* Check that all words were written to flash */
304 result = buf_get_u32(reg_params[2].value, 0, 32);
305 if (0 != result) {
306 retval = ERROR_FAIL;
307 LOG_ERROR("cc3220sf: Flash operation failed");
308 break;
309 }
310 }
311
312 /* Free resources */
313 destroy_reg_param(&reg_params[0]);
314 destroy_reg_param(&reg_params[1]);
315 destroy_reg_param(&reg_params[2]);
316
317 target_free_working_area(target, cc3220sf_bank->working_area);
318 cc3220sf_bank->working_area = 0;
319
320 if (ERROR_OK == retval) {
321 /* Mark flashed sectors as "not erased" */
322 while (offset <= end_address) {
323 sector = offset / FLASH_SECTOR_SIZE;
324 bank->sectors[sector].is_erased = 0;
325 offset += FLASH_SECTOR_SIZE;
326 }
327 }
328
329 return retval;
330}
331
332static int cc3220sf_probe(struct flash_bank *bank)
333{
334 struct target *target = bank->target;
335 struct cc3220sf_bank *cc3220sf_bank = bank->driver_priv;
336
337 uint32_t base;
338 uint32_t size;
339 int num_sectors;
340 int bank_id;
341
342 bank_id = bank->bank_number;
343
344 if (TARGET_HALTED != target->state) {
345 LOG_ERROR("Target not halted");
346 return ERROR_TARGET_NOT_HALTED;
347 }
348
349 if (0 == bank_id) {
350 base = FLASH_BASE_ADDR;
351 size = FLASH_NUM_SECTORS * FLASH_SECTOR_SIZE;
352 num_sectors = FLASH_NUM_SECTORS;
353 } else {
354 /* Invalid bank number somehow */
355 return ERROR_FAIL;
356 }
357
358 if (0 != bank->sectors) {
359 free(bank->sectors);
360 bank->sectors = 0;
361 }
362
363 bank->sectors = malloc(sizeof(struct flash_sector) * num_sectors);
364 if (0 == bank->sectors)
365 return ERROR_FAIL;
366
367 bank->base = base;
368 bank->size = size;
369 bank->num_sectors = num_sectors;
370
371 for (int i = 0; i < num_sectors; i++) {
372 bank->sectors[i].offset = i * FLASH_SECTOR_SIZE;
373 bank->sectors[i].size = FLASH_SECTOR_SIZE;
374 bank->sectors[i].is_erased = -1;
375 bank->sectors[i].is_protected = 0;
376 }
377
378 /* We've successfully determined the stats on this flash bank */
379 cc3220sf_bank->probed = true;
380
381 /* If we fall through to here, then all went well */
382
383 return ERROR_OK;
384}
385
386static int cc3220sf_auto_probe(struct flash_bank *bank)
387{
388 struct cc3220sf_bank *cc3220sf_bank = bank->driver_priv;
389
390 int retval = ERROR_OK;
391
392 if (0 != bank->bank_number) {
393 /* Invalid bank number somehow */
394 return ERROR_FAIL;
395 }
396
397 if (!cc3220sf_bank->probed)
398 retval = cc3220sf_probe(bank);
399
400 return retval;
401}
402
403static int cc3220sf_protect_check(struct flash_bank *bank)
404{
405 return ERROR_OK;
406}
407
408static int cc3220sf_info(struct flash_bank *bank, char *buf, int buf_size)
409{
410 int printed = 0;
411
412 printed = snprintf(buf, buf_size, "CC3220SF with 1MB internal flash\n");
413
414 buf += printed;
415 buf_size -= printed;
416
417 if (0 > buf_size)
418 return ERROR_BUF_TOO_SMALL;
419
420 return ERROR_OK;
421}
422
423struct flash_driver cc3220sf_flash = {
424 .name = "cc3220sf",
425 .flash_bank_command = cc3220sf_flash_bank_command,
426 .erase = cc3220sf_erase,
427 .protect = cc3220sf_protect,
428 .write = cc3220sf_write,
429 .read = default_flash_read,
430 .probe = cc3220sf_probe,
431 .auto_probe = cc3220sf_auto_probe,
432 .erase_check = default_flash_blank_check,
433 .protect_check = cc3220sf_protect_check,
434 .info = cc3220sf_info,
435};
diff --git a/openocd/src/flash/nor/cc3220sf.h b/openocd/src/flash/nor/cc3220sf.h
new file mode 100644
index 0000000..40bbad7
--- /dev/null
+++ b/openocd/src/flash/nor/cc3220sf.h
@@ -0,0 +1,135 @@
1/***************************************************************************
2 * Copyright (C) 2017 by Texas Instruments, Inc. *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
16 ***************************************************************************/
17
18#ifndef OPENOCD_FLASH_NOR_CC3220SF_H
19#define OPENOCD_FLASH_NOR_CC3220SF_H
20
21/* CC3220SF device types */
22#define CC3220_NO_TYPE 0 /* Device type not determined yet */
23#define CC3220_OTHER 1 /* CC3220 variant without flash */
24#define CC3220SF 2 /* CC3220SF variant with flash */
25
26/* Flash parameters */
27#define FLASH_BASE_ADDR 0x01000000
28#define FLASH_SECTOR_SIZE 2048
29#define FLASH_NUM_SECTORS 512
30
31/* CC2200SF flash registers */
32#define FMA_REGISTER_ADDR 0x400FD000
33#define FMC_REGISTER_ADDR 0x400FD008
34#define FMC_DEFAULT_VALUE 0xA4420000
35#define FMC_ERASE_BIT 0x00000002
36#define FMC_MERASE_BIT 0x00000004
37
38/* Flash helper algorithm addresses and values */
39#define ALGO_BASE_ADDR 0x20000000
40#define ALGO_BUFFER_ADDR 0x20000400
41#define ALGO_BUFFER_SIZE 0x1000
42#define ALGO_WORKING_SIZE 0x1400
43
44/* Flash helper algorithm for CC3220SF (assembled by hand) */
45const uint8_t cc3220sf_algo[] = {
46 /* ; flash programming key */
47 0xdf, 0xf8, 0x7c, 0xa0, /* 1: ldr r10, =0xa4420001 */
48 /* ; base of FWB */
49 0xdf, 0xf8, 0x7c, 0xb0, /* ldr r11, =0x400fd100 */
50 /* ; base of flash regs */
51 0xdf, 0xf8, 0x7c, 0xc0, /* ldr r12, =0x400fd000 */
52 /* ; is the dest address 32-bit aligned? */
53 0x01, 0xf0, 0x7f, 0x03, /* and r3, r1, #0x7f */
54 0x00, 0x2b, /* cmp r3, #0 */
55 /* ; if not aligned do one word at a time */
56 0x1e, 0xd1, /* bne %6 */
57
58 /* ; program using the write buffers */
59 /* ; start the buffer word counter at 0 */
60 0x4f, 0xf0, 0x00, 0x04, /* ldr r4, =0 */
61 /* ; store the dest addr in FMA */
62 0xcc, 0xf8, 0x00, 0x10, /* str r1, [r12] */
63 /* ; get the word to write to FWB */
64 0x03, 0x68, /* 2: ldr r3, [r0] */
65 /* ; store the word in the FWB */
66 0xcb, 0xf8, 0x00, 0x30, /* str r3, [r11] */
67 /* ; increment the FWB pointer */
68 0x0b, 0xf1, 0x04, 0x0b, /* add r11, r11, #4 */
69 /* ; increment the source pointer */
70 0x00, 0xf1, 0x04, 0x00, /* add r0, r0, #4 */
71 /* ; decrement the total word counter */
72 0xa2, 0xf1, 0x01, 0x02, /* sub r2, r2, #1 */
73 /* ; increment the buffer word counter */
74 0x04, 0xf1, 0x01, 0x04, /* add r4, r4, #1 */
75 /* ; increment the dest pointer */
76 0x01, 0xf1, 0x04, 0x01, /* add r1, r1, #4 */
77 /* ; is the total word counter now 0? */
78 0x00, 0x2a, /* cmp r2, #0 */
79 /* ; go to end if total word counter is 0 */
80 0x01, 0xd0, /* beq %3 */
81 /* ; is the buffer word counter now 32? */
82 0x20, 0x2c, /* cmp r4, #32 */
83 /* ; go to continue to fill buffer */
84 0xee, 0xd1, /* bne %2 */
85 /* ; store the key and write bit to FMC2 */
86 0xcc, 0xf8, 0x20, 0xa0, /* 3: str r10, [r12, #0x20] */
87 /* ; read FMC2 */
88 0xdc, 0xf8, 0x20, 0x30, /* 4: ldr r3, [r12, #0x20] */
89 /* ; see if the write bit is cleared */
90 0x13, 0xf0, 0x01, 0x0f, /* tst r3, #1 */
91 /* ; go to read FMC2 if bit not cleared */
92 0xfa, 0xd1, /* bne %4 */
93 /* ; is the total word counter now 0? */
94 0x00, 0x2a, /* cmp r2, #0 */
95 /* ; go if there is more to program */
96 0xd7, 0xd1, /* bne %1 */
97 0x13, 0xe0, /* b %5 */
98
99 /* ; program 1 word at a time */
100 /* ; store the dest addr in FMA */
101 0xcc, 0xf8, 0x00, 0x10, /* 6: str r1, [r12] */
102 /* ; get the word to write to FMD */
103 0x03, 0x68, /* ldr r3, [r0] */
104 /* ; store the word in FMD */
105 0xcc, 0xf8, 0x04, 0x30, /* str r3, [r12, #0x4] */
106 /* ; store the key and write bit to FMC */
107 0xcc, 0xf8, 0x08, 0xa0, /* str r10, [r12, #0x8] */
108 /* ; read FMC */
109 0xdc, 0xf8, 0x08, 0x30, /* 7: ldr r3, [r12, #0x8] */
110 /* ; see if the write bit is cleared */
111 0x13, 0xf0, 0x01, 0x0f, /* tst r3, #1 */
112 /* ; go to read FMC if bit not cleared */
113 0xfa, 0xd1, /* bne %7 */
114 /* ; decrement the total word counter */
115 0xa2, 0xf1, 0x01, 0x02, /* sub r2, r2, #1 */
116 /* ; increment the source pointer */
117 0x00, 0xf1, 0x04, 0x00, /* add r0, r0, #4 */
118 /* ; increment the dest pointer */
119 0x01, 0xf1, 0x04, 0x01, /* add r1, r1, #4 */
120 /* ; is the total word counter now 0 */
121 0x00, 0x2a, /* cmp r2, #0 */
122 /* ; go if there is more to program */
123 0xc2, 0xd1, /* bne %1 */
124 /* ; end */
125 0x00, 0xbe, /* 5: bkpt #0 */
126 0x01, 0xbe, /* bkpt #1 */
127 0xfc, 0xe7, /* b %5 */
128
129 /* ; flash register address constants */
130 0x01, 0x00, 0x42, 0xa4, /* .word 0xa4420001 */
131 0x00, 0xd1, 0x0f, 0x40, /* .word 0x400fd100 */
132 0x00, 0xd0, 0x0f, 0x40 /* .word 0x400fd000 */
133};
134
135#endif /* OPENOCD_FLASH_NOR_CC3220SF_H */
diff --git a/openocd/src/flash/nor/drivers.c b/openocd/src/flash/nor/drivers.c
index 99b212f..a8d6167 100644
--- a/openocd/src/flash/nor/drivers.c
+++ b/openocd/src/flash/nor/drivers.c
@@ -30,6 +30,7 @@ extern struct flash_driver at91sam7_flash;
30extern struct flash_driver at91samd_flash; 30extern struct flash_driver at91samd_flash;
31extern struct flash_driver atsamv_flash; 31extern struct flash_driver atsamv_flash;
32extern struct flash_driver avr_flash; 32extern struct flash_driver avr_flash;
33extern struct flash_driver cc3220sf_flash;
33extern struct flash_driver cfi_flash; 34extern struct flash_driver cfi_flash;
34extern struct flash_driver dsp5680xx_flash; 35extern struct flash_driver dsp5680xx_flash;
35extern struct flash_driver efm32_flash; 36extern struct flash_driver efm32_flash;
@@ -83,6 +84,7 @@ static struct flash_driver *flash_drivers[] = {
83 &at91samd_flash, 84 &at91samd_flash,
84 &atsamv_flash, 85 &atsamv_flash,
85 &avr_flash, 86 &avr_flash,
87 &cc3220sf_flash,
86 &cfi_flash, 88 &cfi_flash,
87 &dsp5680xx_flash, 89 &dsp5680xx_flash,
88 &efm32_flash, 90 &efm32_flash,
diff --git a/openocd/tcl/board/ti_cc3220sf_launchpad.cfg b/openocd/tcl/board/ti_cc3220sf_launchpad.cfg
new file mode 100644
index 0000000..205f3cd
--- /dev/null
+++ b/openocd/tcl/board/ti_cc3220sf_launchpad.cfg
@@ -0,0 +1,7 @@
1#
2# TI CC3220SF-LaunchXL Evaluation Kit
3#
4source [find interface/xds110.cfg]
5transport select swd
6source [find target/ti_cc3220sf.cfg]
7adapter_khz 2500
diff --git a/openocd/tcl/board/ti_cc32xx_launchpad.cfg b/openocd/tcl/board/ti_cc32xx_launchpad.cfg
new file mode 100644
index 0000000..edd58ea
--- /dev/null
+++ b/openocd/tcl/board/ti_cc32xx_launchpad.cfg
@@ -0,0 +1,7 @@
1#
2# TI CC32xx-LaunchXL Evaluation Kit
3#
4source [find interface/xds110.cfg]
5transport select swd
6source [find target/ti_cc32xx.cfg]
7adapter_khz 2500
diff --git a/openocd/tcl/target/ti_cc32xx.cfg b/openocd/tcl/target/ti_cc32xx.cfg
new file mode 100644
index 0000000..bc2316b
--- /dev/null
+++ b/openocd/tcl/target/ti_cc32xx.cfg
@@ -0,0 +1,71 @@
1#
2# Texas Instruments CC32xx - ARM Cortex-M4
3#
4# http://www.ti.com/product/CC3200
5# http://www.ti.com/product/CC3220
6#
7
8source [find target/swj-dp.tcl]
9source [find target/icepick.cfg]
10
11if { [info exists CHIPNAME] } {
12 set _CHIPNAME $CHIPNAME
13} else {
14 set _CHIPNAME cc32xx
15}
16
17#
18# Main DAP
19#
20if { [info exists DAP_TAPID] } {
21 set _DAP_TAPID $DAP_TAPID
22} else {
23 if {[using_jtag]} {
24 set _DAP_TAPID 0x4BA00477
25 } else {
26 set _DAP_TAPID 0x2BA01477
27 }
28}
29
30if {[using_jtag]} {
31 jtag newtap $_CHIPNAME dap -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -disable
32 jtag configure $_CHIPNAME.dap -event tap-enable "icepick_c_tapenable $_CHIPNAME.jrc 0"
33} else {
34 swj_newdap $_CHIPNAME dap -expected-id $_DAP_TAPID
35}
36
37#
38# ICEpick-C (JTAG route controller)
39#
40if { [info exists JRC_TAPID] } {
41 set _JRC_TAPID $JRC_TAPID
42} else {
43 set _JRC_TAPID 0x0B97C02F
44}
45
46if {[using_jtag]} {
47 jtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f -expected-id $_JRC_TAPID -ignore-version
48 jtag configure $_CHIPNAME.jrc -event setup "jtag tapenable $_CHIPNAME.dap"
49}
50
51set _TARGETNAME $_CHIPNAME.cpu
52target create $_TARGETNAME cortex_m -chain-position $_CHIPNAME.dap
53
54if { [info exists WORKAREASIZE] } {
55 set _WORKAREASIZE $WORKAREASIZE
56} else {
57 set _WORKAREASIZE 0x2000
58}
59
60$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0
61
62if { ![using_hla] } {
63 cortex_m reset_config sysresetreq
64}
65
66gdb_memory_map enable
67gdb_flash_program enable
68
69$_TARGETNAME configure -event gdb-attach {
70 halt
71}