This is an automated email from Gerrit. Edward Fewell ([email protected]) just uploaded a new patch set to Gerrit, which you can find at http://openocd.zylin.com/4319
-- gerrit commit 6654041d1b6d9f25546aac64e4fc18cf9290e1f2 Author: Edward Fewell <[email protected]> Date: Thu Dec 28 17:38:21 2017 -0600 flash/nor: Add support for TI CC3220SF internal flash Added cc3220sf flash driver to support the TI CC3220SF microcontrollers. Implemented flash driver to support the internal flash of the CC3220SF. The implementation does not support the serial flash of the CC32xx family that requires connection over UART, and not via JTAG/SWD debug. Added config files for both CC32xx devices (no flash) and CC3220SF (with flash). Change-Id: I58fc1478d07238d39c7ef02339f1097a91668c47 Signed-off-by: Edward Fewell <[email protected]> diff --git a/doc/openocd.texi b/doc/openocd.texi index ebd03c4..68bd6d7 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -5298,6 +5298,20 @@ The AVR 8-bit microcontrollers from Atmel integrate flash memory. @comment - defines mass_erase ... pointless given flash_erase_address @end deffn +@deffn {Flash Driver} cc3220sf +The CC3220SF version of the SimpleLink CC32xx microcontrollers from Texas +Instruments includes 1MB of internal flash. The cc3220sf flash driver only +supports the internal flash. The serial flash on SimpleLink boards is +programmed via the bootloader over a UART connection. Security features of +the CC3220SF may erase the internal flash during power on reset. Refer to +documentation at @url{www.ti.com/cc3220sf} for details on security features +and programming the serial flash. + +@example +flash bank $_FLASHNAME cc3220sf 0 0 0 0 $_TARGETNAME +@end example +@end deffn + @deffn {Flash Driver} efm32 All members of the EFM32 microcontroller family from Energy Micro include internal flash and use ARM Cortex-M3 cores. The driver automatically recognizes diff --git a/src/flash/nor/Makefile.am b/src/flash/nor/Makefile.am index ebf4775..e4a806a 100644 --- a/src/flash/nor/Makefile.am +++ b/src/flash/nor/Makefile.am @@ -18,6 +18,7 @@ NOR_DRIVERS = \ %D%/ath79.c \ %D%/atsamv.c \ %D%/avrf.c \ + %D%/cc3220sf.c \ %D%/cfi.c \ %D%/dsp5680xx_flash.c \ %D%/efm32.c \ @@ -60,6 +61,7 @@ NOR_DRIVERS = \ NORHEADERS = \ %D%/core.h \ + %D%/cc3220sf.h \ %D%/cfi.h \ %D%/driver.h \ %D%/imp.h \ diff --git a/src/flash/nor/cc3220sf.c b/src/flash/nor/cc3220sf.c new file mode 100644 index 0000000..6841c58 --- /dev/null +++ b/src/flash/nor/cc3220sf.c @@ -0,0 +1,435 @@ +/*************************************************************************** + * Copyright (C) 2017 by Texas Instruments, Inc. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + ***************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "imp.h" +#include "cc3220sf.h" +#include <helper/time_support.h> +#include <target/algorithm.h> +#include <target/armv7m.h> + +#define FLASH_TIMEOUT 5000 + +struct cc3220sf_bank { + bool probed; + struct working_area *working_area; + struct armv7m_algorithm armv7m_info; +}; + +static int cc3220sf_mass_erase(struct flash_bank *bank) +{ + struct target *target = bank->target; + bool done; + long long start_ms; + long long elapsed_ms; + uint32_t value; + + int retval = ERROR_OK; + + if (TARGET_HALTED != target->state) { + LOG_ERROR("Target not halted"); + return ERROR_TARGET_NOT_HALTED; + } + + /* Set starting address to erase to zero */ + value = 0; + retval = target_write_buffer(target, FMA_REGISTER_ADDR, + sizeof(value), (uint8_t *)&value); + if (ERROR_OK != retval) + return retval; + + /* Write the MERASE bit of the FMC register */ + value = FMC_DEFAULT_VALUE | FMC_MERASE_BIT; + retval = target_write_buffer(target, FMC_REGISTER_ADDR, + sizeof(value), (uint8_t *)&value); + if (ERROR_OK != retval) + return retval; + + /* Poll the MERASE bit until the mass erase is complete */ + done = false; + start_ms = timeval_ms(); + while (!done) { + retval = target_read_buffer(target, FMC_REGISTER_ADDR, + sizeof(value), (uint8_t *)&value); + if (ERROR_OK != retval) + return retval; + + if ((value & FMC_MERASE_BIT) == 0) { + /* Bit clears when mass erase is finished */ + done = true; + } else { + elapsed_ms = timeval_ms() - start_ms; + if (elapsed_ms > 500) + keep_alive(); + if (elapsed_ms > FLASH_TIMEOUT) + break; + } + } + + if (!done) { + /* Mass erase timed out waiting for confirmation */ + return ERROR_FAIL; + } + + /* Mark all sectors erased */ + if (0 != bank->sectors) { + for (int i = 0; i < bank->num_sectors; i++) + bank->sectors[i].is_erased = 1; + } + + return retval; +} + +FLASH_BANK_COMMAND_HANDLER(cc3220sf_flash_bank_command) +{ + struct cc3220sf_bank *cc3220sf_bank; + + if (CMD_ARGC < 6) + return ERROR_COMMAND_SYNTAX_ERROR; + + cc3220sf_bank = malloc(sizeof(struct cc3220sf_bank)); + if (0 == cc3220sf_bank) + return ERROR_FAIL; + + /* Initialize private flash information */ + cc3220sf_bank->probed = false; + cc3220sf_bank->working_area = 0; + + /* Finish initialization of flash bank */ + bank->driver_priv = cc3220sf_bank; + bank->next = 0; + + return ERROR_OK; +} + +static int cc3220sf_erase(struct flash_bank *bank, int first, int last) +{ + struct target *target = bank->target; + bool done; + long long start_ms; + long long elapsed_ms; + uint32_t address; + uint32_t value; + + int retval = ERROR_OK; + + if (TARGET_HALTED != target->state) { + LOG_ERROR("Target not halted"); + return ERROR_TARGET_NOT_HALTED; + } + + /* Do a mass erase if user requested all sectors of flash */ + if ((first == 0) && (last == (bank->num_sectors - 1))) { + /* Request mass erase of flash */ + return cc3220sf_mass_erase(bank); + } + + /* Erase requested sectors one by one */ + for (int i = first; i <= last; i++) { + + /* Determine address of sector to erase */ + address = FLASH_BASE_ADDR + i * FLASH_SECTOR_SIZE; + + /* Set starting address to erase */ + retval = target_write_buffer(target, FMA_REGISTER_ADDR, + sizeof(address), (uint8_t *)&address); + if (ERROR_OK != retval) + return retval; + + /* Write the ERASE bit of the FMC register */ + value = FMC_DEFAULT_VALUE | FMC_ERASE_BIT; + retval = target_write_buffer(target, FMC_REGISTER_ADDR, + sizeof(value), (uint8_t *)&value); + if (ERROR_OK != retval) + return retval; + + /* Poll the ERASE bit until the erase is complete */ + done = false; + start_ms = timeval_ms(); + while (!done) { + retval = target_read_buffer(target, FMC_REGISTER_ADDR, + sizeof(value), (uint8_t *)&value); + if (ERROR_OK != retval) + return retval; + + if ((value & FMC_ERASE_BIT) == 0) { + /* Bit clears when mass erase is finished */ + done = true; + } else { + elapsed_ms = timeval_ms() - start_ms; + if (elapsed_ms > 500) + keep_alive(); + if (elapsed_ms > FLASH_TIMEOUT) + break; + } + } + + if (!done) { + /* Sector erase timed out waiting for confirmation */ + return ERROR_FAIL; + } + + /* Mark the sector as erased */ + if (0 != bank->sectors) + bank->sectors[i].is_erased = 1; + } + + return retval; +} + +static int cc3220sf_protect(struct flash_bank *bank, int set, int first, + int last) +{ + return ERROR_OK; +} + +static int cc3220sf_write(struct flash_bank *bank, const uint8_t *buffer, + uint32_t offset, uint32_t count) +{ + struct target *target = bank->target; + struct cc3220sf_bank *cc3220sf_bank = bank->driver_priv; + struct reg_param reg_params[3]; + uint32_t address; + uint32_t remaining; + uint32_t words; + uint32_t end_address = offset + count - 1; + uint32_t sector; + uint32_t result; + + int retval = ERROR_OK; + + if (TARGET_HALTED != target->state) { + LOG_ERROR("Target not halted"); + return ERROR_TARGET_NOT_HALTED; + } + + /* Check for working area to use for flash helper algorithm */ + if (0 != cc3220sf_bank->working_area) + target_free_working_area(target, cc3220sf_bank->working_area); + retval = target_alloc_working_area(target, ALGO_WORKING_SIZE, + &cc3220sf_bank->working_area); + if (ERROR_OK != retval) + return retval; + + /* Confirm the defined working address is the area we need to use */ + if (ALGO_BASE_ADDR != cc3220sf_bank->working_area->address) + return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; + + /* Write flash helper algorithm into target memory */ + retval = target_write_buffer(target, ALGO_BASE_ADDR, + sizeof(cc3220sf_algo), cc3220sf_algo); + if (ERROR_OK != retval) + return retval; + + /* Initialize the ARMv7m specific info to run the algorithm */ + cc3220sf_bank->armv7m_info.common_magic = ARMV7M_COMMON_MAGIC; + cc3220sf_bank->armv7m_info.core_mode = ARM_MODE_THREAD; + + /* Initialize register params for flash helper algorithm */ + init_reg_param(®_params[0], "r0", 32, PARAM_OUT); + init_reg_param(®_params[1], "r1", 32, PARAM_OUT); + init_reg_param(®_params[2], "r2", 32, PARAM_IN_OUT); + + /* Prepare to write to flash */ + address = FLASH_BASE_ADDR + offset; + remaining = count; + + while (remaining > 0) { + /* Helper parameters are passed in registers R0-R2 */ + /* Set address to write to and start of data buffer */ + buf_set_u32(reg_params[0].value, 0, 32, ALGO_BUFFER_ADDR); + buf_set_u32(reg_params[1].value, 0, 32, address); + + /* Download data to write into memory buffer */ + if (remaining >= ALGO_BUFFER_SIZE) { + /* Fill up buffer with data to flash */ + retval = target_write_buffer(target, ALGO_BUFFER_ADDR, + ALGO_BUFFER_SIZE, buffer); + if (ERROR_OK != retval) + break; + + /* Count to write is in 32-bit words */ + words = ALGO_BUFFER_SIZE / 4; + + /* Bump variables to next data */ + address += ALGO_BUFFER_SIZE; + buffer += ALGO_BUFFER_SIZE; + remaining -= ALGO_BUFFER_SIZE; + } else { + /* Fill buffer with what's left of the data */ + retval = target_write_buffer(target, ALGO_BUFFER_ADDR, + remaining, buffer); + if (ERROR_OK != retval) + break; + + /* Calculate the final word count to write */ + words = remaining / 4; + if (0 != (remaining % 4)) + words++; + + /* All done after this last buffer */ + remaining = 0; + } + + /* Set number of words to write */ + buf_set_u32(reg_params[2].value, 0, 32, words); + + /* Execute the flash helper algorithm */ + retval = target_run_algorithm(target, 0, 0, 3, reg_params, + ALGO_BASE_ADDR, 0, FLASH_TIMEOUT, + &cc3220sf_bank->armv7m_info); + if (ERROR_OK != retval) { + LOG_ERROR("cc3220sf: Flash algorithm failed to run"); + break; + } + + /* Check that all words were written to flash */ + result = buf_get_u32(reg_params[2].value, 0, 32); + if (0 != result) { + retval = ERROR_FAIL; + LOG_ERROR("cc3220sf: Flash operation failed"); + break; + } + } + + /* Free resources */ + destroy_reg_param(®_params[0]); + destroy_reg_param(®_params[1]); + destroy_reg_param(®_params[2]); + + target_free_working_area(target, cc3220sf_bank->working_area); + cc3220sf_bank->working_area = 0; + + if (ERROR_OK == retval) { + /* Mark flashed sectors as "not erased" */ + while (offset <= end_address) { + sector = offset / FLASH_SECTOR_SIZE; + bank->sectors[sector].is_erased = 0; + offset += FLASH_SECTOR_SIZE; + } + } + + return retval; +} + +static int cc3220sf_probe(struct flash_bank *bank) +{ + struct target *target = bank->target; + struct cc3220sf_bank *cc3220sf_bank = bank->driver_priv; + + uint32_t base; + uint32_t size; + int num_sectors; + int bank_id; + + bank_id = bank->bank_number; + + if (TARGET_HALTED != target->state) { + LOG_ERROR("Target not halted"); + return ERROR_TARGET_NOT_HALTED; + } + + if (0 == bank_id) { + base = FLASH_BASE_ADDR; + size = FLASH_NUM_SECTORS * FLASH_SECTOR_SIZE; + num_sectors = FLASH_NUM_SECTORS; + } else { + /* Invalid bank number somehow */ + return ERROR_FAIL; + } + + if (0 != bank->sectors) { + free(bank->sectors); + bank->sectors = 0; + } + + bank->sectors = malloc(sizeof(struct flash_sector) * num_sectors); + if (0 == bank->sectors) + return ERROR_FAIL; + + bank->base = base; + bank->size = size; + bank->num_sectors = num_sectors; + + for (int i = 0; i < num_sectors; i++) { + bank->sectors[i].offset = i * FLASH_SECTOR_SIZE; + bank->sectors[i].size = FLASH_SECTOR_SIZE; + bank->sectors[i].is_erased = -1; + bank->sectors[i].is_protected = 0; + } + + /* We've successfully determined the stats on this flash bank */ + cc3220sf_bank->probed = true; + + /* If we fall through to here, then all went well */ + + return ERROR_OK; +} + +static int cc3220sf_auto_probe(struct flash_bank *bank) +{ + struct cc3220sf_bank *cc3220sf_bank = bank->driver_priv; + + int retval = ERROR_OK; + + if (0 != bank->bank_number) { + /* Invalid bank number somehow */ + return ERROR_FAIL; + } + + if (!cc3220sf_bank->probed) + retval = cc3220sf_probe(bank); + + return retval; +} + +static int cc3220sf_protect_check(struct flash_bank *bank) +{ + return ERROR_OK; +} + +static int cc3220sf_info(struct flash_bank *bank, char *buf, int buf_size) +{ + int printed = 0; + + printed = snprintf(buf, buf_size, "CC3220SF with 1MB internal flash\n"); + + buf += printed; + buf_size -= printed; + + if (0 > buf_size) + return ERROR_BUF_TOO_SMALL; + + return ERROR_OK; +} + +struct flash_driver cc3220sf_flash = { + .name = "cc3220sf", + .flash_bank_command = cc3220sf_flash_bank_command, + .erase = cc3220sf_erase, + .protect = cc3220sf_protect, + .write = cc3220sf_write, + .read = default_flash_read, + .probe = cc3220sf_probe, + .auto_probe = cc3220sf_auto_probe, + .erase_check = default_flash_blank_check, + .protect_check = cc3220sf_protect_check, + .info = cc3220sf_info, +}; diff --git a/src/flash/nor/cc3220sf.h b/src/flash/nor/cc3220sf.h new file mode 100644 index 0000000..40bbad7 --- /dev/null +++ b/src/flash/nor/cc3220sf.h @@ -0,0 +1,135 @@ +/*************************************************************************** + * Copyright (C) 2017 by Texas Instruments, Inc. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + ***************************************************************************/ + +#ifndef OPENOCD_FLASH_NOR_CC3220SF_H +#define OPENOCD_FLASH_NOR_CC3220SF_H + +/* CC3220SF device types */ +#define CC3220_NO_TYPE 0 /* Device type not determined yet */ +#define CC3220_OTHER 1 /* CC3220 variant without flash */ +#define CC3220SF 2 /* CC3220SF variant with flash */ + +/* Flash parameters */ +#define FLASH_BASE_ADDR 0x01000000 +#define FLASH_SECTOR_SIZE 2048 +#define FLASH_NUM_SECTORS 512 + +/* CC2200SF flash registers */ +#define FMA_REGISTER_ADDR 0x400FD000 +#define FMC_REGISTER_ADDR 0x400FD008 +#define FMC_DEFAULT_VALUE 0xA4420000 +#define FMC_ERASE_BIT 0x00000002 +#define FMC_MERASE_BIT 0x00000004 + +/* Flash helper algorithm addresses and values */ +#define ALGO_BASE_ADDR 0x20000000 +#define ALGO_BUFFER_ADDR 0x20000400 +#define ALGO_BUFFER_SIZE 0x1000 +#define ALGO_WORKING_SIZE 0x1400 + +/* Flash helper algorithm for CC3220SF (assembled by hand) */ +const uint8_t cc3220sf_algo[] = { + /* ; flash programming key */ + 0xdf, 0xf8, 0x7c, 0xa0, /* 1: ldr r10, =0xa4420001 */ + /* ; base of FWB */ + 0xdf, 0xf8, 0x7c, 0xb0, /* ldr r11, =0x400fd100 */ + /* ; base of flash regs */ + 0xdf, 0xf8, 0x7c, 0xc0, /* ldr r12, =0x400fd000 */ + /* ; is the dest address 32-bit aligned? */ + 0x01, 0xf0, 0x7f, 0x03, /* and r3, r1, #0x7f */ + 0x00, 0x2b, /* cmp r3, #0 */ + /* ; if not aligned do one word at a time */ + 0x1e, 0xd1, /* bne %6 */ + + /* ; program using the write buffers */ + /* ; start the buffer word counter at 0 */ + 0x4f, 0xf0, 0x00, 0x04, /* ldr r4, =0 */ + /* ; store the dest addr in FMA */ + 0xcc, 0xf8, 0x00, 0x10, /* str r1, [r12] */ + /* ; get the word to write to FWB */ + 0x03, 0x68, /* 2: ldr r3, [r0] */ + /* ; store the word in the FWB */ + 0xcb, 0xf8, 0x00, 0x30, /* str r3, [r11] */ + /* ; increment the FWB pointer */ + 0x0b, 0xf1, 0x04, 0x0b, /* add r11, r11, #4 */ + /* ; increment the source pointer */ + 0x00, 0xf1, 0x04, 0x00, /* add r0, r0, #4 */ + /* ; decrement the total word counter */ + 0xa2, 0xf1, 0x01, 0x02, /* sub r2, r2, #1 */ + /* ; increment the buffer word counter */ + 0x04, 0xf1, 0x01, 0x04, /* add r4, r4, #1 */ + /* ; increment the dest pointer */ + 0x01, 0xf1, 0x04, 0x01, /* add r1, r1, #4 */ + /* ; is the total word counter now 0? */ + 0x00, 0x2a, /* cmp r2, #0 */ + /* ; go to end if total word counter is 0 */ + 0x01, 0xd0, /* beq %3 */ + /* ; is the buffer word counter now 32? */ + 0x20, 0x2c, /* cmp r4, #32 */ + /* ; go to continue to fill buffer */ + 0xee, 0xd1, /* bne %2 */ + /* ; store the key and write bit to FMC2 */ + 0xcc, 0xf8, 0x20, 0xa0, /* 3: str r10, [r12, #0x20] */ + /* ; read FMC2 */ + 0xdc, 0xf8, 0x20, 0x30, /* 4: ldr r3, [r12, #0x20] */ + /* ; see if the write bit is cleared */ + 0x13, 0xf0, 0x01, 0x0f, /* tst r3, #1 */ + /* ; go to read FMC2 if bit not cleared */ + 0xfa, 0xd1, /* bne %4 */ + /* ; is the total word counter now 0? */ + 0x00, 0x2a, /* cmp r2, #0 */ + /* ; go if there is more to program */ + 0xd7, 0xd1, /* bne %1 */ + 0x13, 0xe0, /* b %5 */ + + /* ; program 1 word at a time */ + /* ; store the dest addr in FMA */ + 0xcc, 0xf8, 0x00, 0x10, /* 6: str r1, [r12] */ + /* ; get the word to write to FMD */ + 0x03, 0x68, /* ldr r3, [r0] */ + /* ; store the word in FMD */ + 0xcc, 0xf8, 0x04, 0x30, /* str r3, [r12, #0x4] */ + /* ; store the key and write bit to FMC */ + 0xcc, 0xf8, 0x08, 0xa0, /* str r10, [r12, #0x8] */ + /* ; read FMC */ + 0xdc, 0xf8, 0x08, 0x30, /* 7: ldr r3, [r12, #0x8] */ + /* ; see if the write bit is cleared */ + 0x13, 0xf0, 0x01, 0x0f, /* tst r3, #1 */ + /* ; go to read FMC if bit not cleared */ + 0xfa, 0xd1, /* bne %7 */ + /* ; decrement the total word counter */ + 0xa2, 0xf1, 0x01, 0x02, /* sub r2, r2, #1 */ + /* ; increment the source pointer */ + 0x00, 0xf1, 0x04, 0x00, /* add r0, r0, #4 */ + /* ; increment the dest pointer */ + 0x01, 0xf1, 0x04, 0x01, /* add r1, r1, #4 */ + /* ; is the total word counter now 0 */ + 0x00, 0x2a, /* cmp r2, #0 */ + /* ; go if there is more to program */ + 0xc2, 0xd1, /* bne %1 */ + /* ; end */ + 0x00, 0xbe, /* 5: bkpt #0 */ + 0x01, 0xbe, /* bkpt #1 */ + 0xfc, 0xe7, /* b %5 */ + + /* ; flash register address constants */ + 0x01, 0x00, 0x42, 0xa4, /* .word 0xa4420001 */ + 0x00, 0xd1, 0x0f, 0x40, /* .word 0x400fd100 */ + 0x00, 0xd0, 0x0f, 0x40 /* .word 0x400fd000 */ +}; + +#endif /* OPENOCD_FLASH_NOR_CC3220SF_H */ diff --git a/src/flash/nor/drivers.c b/src/flash/nor/drivers.c index eacca03..5e5a98c 100644 --- a/src/flash/nor/drivers.c +++ b/src/flash/nor/drivers.c @@ -31,6 +31,7 @@ extern struct flash_driver at91samd_flash; extern struct flash_driver ath79_flash; extern struct flash_driver atsamv_flash; extern struct flash_driver avr_flash; +extern struct flash_driver cc3220sf_flash; extern struct flash_driver cfi_flash; extern struct flash_driver dsp5680xx_flash; extern struct flash_driver efm32_flash; @@ -86,6 +87,7 @@ static struct flash_driver *flash_drivers[] = { &ath79_flash, &atsamv_flash, &avr_flash, + &cc3220sf_flash, &cfi_flash, &dsp5680xx_flash, &efm32_flash, diff --git a/tcl/target/ti_cc3220sf.cfg b/tcl/target/ti_cc3220sf.cfg new file mode 100644 index 0000000..c040f67 --- /dev/null +++ b/tcl/target/ti_cc3220sf.cfg @@ -0,0 +1,73 @@ +# +# Texas Instruments CC3220SF - ARM Cortex-M4 +# +# http://www.ti.com/CC3220SF +# + +source [find target/swj-dp.tcl] +source [find target/icepick.cfg] + +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} else { + set _CHIPNAME cc3220sf +} + +# +# Main DAP +# +if { [info exists DAP_TAPID] } { + set _DAP_TAPID $DAP_TAPID +} else { + if {[using_jtag]} { + set _DAP_TAPID 0x4BA00477 + } else { + set _DAP_TAPID 0x2BA01477 + } +} + +if {[using_jtag]} { + jtag newtap $_CHIPNAME dap -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -disable + jtag configure $_CHIPNAME.dap -event tap-enable "icepick_c_tapenable $_CHIPNAME.jrc 0" +} else { + swj_newdap $_CHIPNAME dap -expected-id $_DAP_TAPID +} + +# +# ICEpick-C (JTAG route controller) +# +if { [info exists JRC_TAPID] } { + set _JRC_TAPID $JRC_TAPID +} else { + set _JRC_TAPID 0x0B97C02F +} + +if {[using_jtag]} { + jtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f -expected-id $_JRC_TAPID -ignore-version + jtag configure $_CHIPNAME.jrc -event setup "jtag tapenable $_CHIPNAME.dap" +} + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME cortex_m -chain-position $_CHIPNAME.dap + +if { [info exists WORKAREASIZE] } { + set _WORKAREASIZE $WORKAREASIZE +} else { + set _WORKAREASIZE 0x2000 +} + +$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 + +set _FLASHNAME $_CHIPNAME.flash +flash bank $_FLASHNAME cc3220sf 0 0 0 0 $_TARGETNAME + +if { ![using_hla] } { + cortex_m reset_config sysresetreq +} + +gdb_memory_map enable +gdb_flash_program enable + +$_TARGETNAME configure -event gdb-attach { + halt +} diff --git a/tcl/target/ti_cc32xx.cfg b/tcl/target/ti_cc32xx.cfg new file mode 100644 index 0000000..bc2316b --- /dev/null +++ b/tcl/target/ti_cc32xx.cfg @@ -0,0 +1,71 @@ +# +# Texas Instruments CC32xx - ARM Cortex-M4 +# +# http://www.ti.com/product/CC3200 +# http://www.ti.com/product/CC3220 +# + +source [find target/swj-dp.tcl] +source [find target/icepick.cfg] + +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} else { + set _CHIPNAME cc32xx +} + +# +# Main DAP +# +if { [info exists DAP_TAPID] } { + set _DAP_TAPID $DAP_TAPID +} else { + if {[using_jtag]} { + set _DAP_TAPID 0x4BA00477 + } else { + set _DAP_TAPID 0x2BA01477 + } +} + +if {[using_jtag]} { + jtag newtap $_CHIPNAME dap -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -disable + jtag configure $_CHIPNAME.dap -event tap-enable "icepick_c_tapenable $_CHIPNAME.jrc 0" +} else { + swj_newdap $_CHIPNAME dap -expected-id $_DAP_TAPID +} + +# +# ICEpick-C (JTAG route controller) +# +if { [info exists JRC_TAPID] } { + set _JRC_TAPID $JRC_TAPID +} else { + set _JRC_TAPID 0x0B97C02F +} + +if {[using_jtag]} { + jtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f -expected-id $_JRC_TAPID -ignore-version + jtag configure $_CHIPNAME.jrc -event setup "jtag tapenable $_CHIPNAME.dap" +} + +set _TARGETNAME $_CHIPNAME.cpu +target create $_TARGETNAME cortex_m -chain-position $_CHIPNAME.dap + +if { [info exists WORKAREASIZE] } { + set _WORKAREASIZE $WORKAREASIZE +} else { + set _WORKAREASIZE 0x2000 +} + +$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0 + +if { ![using_hla] } { + cortex_m reset_config sysresetreq +} + +gdb_memory_map enable +gdb_flash_program enable + +$_TARGETNAME configure -event gdb-attach { + halt +} -- ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ OpenOCD-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/openocd-devel
