Merge commit '7719e9618e753ac41a46a2488dfba549ac578891' into riscv-upd

This commit is contained in:
Liviu Ionescu 2017-10-01 01:57:46 +03:00
commit 7dc04d7d0a
30 changed files with 1681 additions and 630 deletions

View File

@ -6,7 +6,7 @@ ARM_OBJCOPY ?= $(ARM_CROSS_COMPILE)objcopy
ARM_AFLAGS = -EL -mthumb
arm: armv7m_kinetis_wdog.inc
arm: armv7m_kinetis_wdog.inc armv7m_kinetis_wdog32.inc
armv7m_%.elf: armv7m_%.s
$(ARM_AS) $(ARM_AFLAGS) $< -o $@

View File

@ -1,4 +1,3 @@
/* Autogenerated with ../../../src/helper/bin2char.sh */
0x04,0x4b,0x05,0x4a,0xda,0x81,0x05,0x4a,0xda,0x81,0x01,0x24,0x1a,0x88,0xa2,0x43,
0x1a,0x80,0x06,0xe0,0x00,0x20,0x05,0x40,0x20,0xc5,0x00,0x00,0x28,0xd9,0x00,0x00,
0x00,0x00,0x00,0xbe,
0x04,0x4a,0xc2,0x81,0x04,0x4a,0xc2,0x81,0x01,0x24,0x02,0x88,0xa2,0x43,0x02,0x80,
0x05,0xe0,0x00,0x00,0x20,0xc5,0x00,0x00,0x28,0xd9,0x00,0x00,0x00,0x00,0x00,0xbe,

View File

@ -19,7 +19,9 @@
/*
Disable watchdog for Kinetis Kx and KVx
Parameters: none
Parameters:
r0 ... WDOG base (in)
Used instruction set should work on both Cortex-M4 and M0+
*/
@ -28,7 +30,6 @@
.cpu cortex-m0
.thumb
WDOG_ADDR = 0x40052000
/* WDOG registers offsets */
WDOG_STCTRLH = 0
WDOG_UNLOCK = 0x0e
@ -39,17 +40,16 @@ WDOG_KEY2 = 0xd928
.thumb_func
start:
/* WDOG_UNLOCK = 0xC520 */
ldr r3, =WDOG_ADDR
ldr r2, =WDOG_KEY1
strh r2, [r3, WDOG_UNLOCK]
strh r2, [r0, WDOG_UNLOCK]
/* WDOG_UNLOCK = 0xD928 */
ldr r2, =WDOG_KEY2
strh r2, [r3, WDOG_UNLOCK]
strh r2, [r0, WDOG_UNLOCK]
/* WDOG_STCTRLH clear bit 0 */
movs r4, #1
ldrh r2, [r3, WDOG_STCTRLH]
ldrh r2, [r0, WDOG_STCTRLH]
bics r2, r4
strh r2, [r3, WDOG_STCTRLH]
strh r2, [r0, WDOG_STCTRLH]
/* OpenOCD checks exit point address. Jump to the very end. */
b done

View File

@ -0,0 +1,5 @@
/* Autogenerated with ../../../src/helper/bin2char.sh */
0x02,0x68,0x08,0x4b,0x1a,0x42,0x08,0x4b,0x01,0xd0,0x43,0x60,0x02,0xe0,0x83,0x80,
0x1b,0x0c,0x83,0x80,0x80,0x24,0xa2,0x43,0x20,0x24,0x22,0x43,0x02,0x60,0x03,0x4b,
0x83,0x60,0x06,0xe0,0x00,0x20,0x00,0x00,0x20,0xc5,0x28,0xd9,0x00,0x04,0x00,0x00,
0x00,0x00,0x00,0xbe,

View File

@ -0,0 +1,81 @@
/***************************************************************************
* Copyright (C) 2017 Tomas Vanek *
* vanekt@fbl.cz *
* *
* 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, write to the *
* Free Software Foundation, Inc. *
***************************************************************************/
/*
Disable watchdog, 32-bit version for newer Kinetis
Parameters:
r0 ... WDOG32 base (in)
Used instruction set should work on both Cortex-M4 and M0+
*/
.text
.syntax unified
.cpu cortex-m0
.thumb
/* WDOG registers offsets */
WDOG_CS = 0
WDOG_CNT = 4
WDOG_TOVAL = 8
WDOG_KEY = 0xd928c520
.thumb_func
start:
/* test WDOG_CS bit CMD32EN */
ldr r2, [r0, WDOG_CS]
ldr r3, =0x2000
tst r2, r3
ldr r3, =WDOG_KEY
beq cmd16
/* WDOG_CNT = key */
str r3, [r0, WDOG_CNT]
b unlocked
cmd16:
/* WDOG_CNT = key, halfword by halfword */
strh r3, [r0, WDOG_CNT]
lsrs r3, r3, #16
strh r3, [r0, WDOG_CNT]
/* WDOG_CS: clear EN bit 7, set UPDATE bit 5 */
unlocked:
movs r4, #0x80
bics r2, r4
movs r4, #0x20
orrs r2, r4
str r2, [r0, WDOG_CS]
/* All active WDOG registers have to be updated, set dummy timeout */
/* WDOG_TOVAL = 0x400 */
ldr r3, =0x400
str r3, [r0, WDOG_TOVAL]
/* OpenOCD checks exit point address. Jump to the very end. */
b done
.pool
/* Avoid padding at .text segment end. Otherwise exit point check fails. */
.skip ( . - start + 2) & 2, 0
done:
bkpt #0
.end

View File

@ -682,7 +682,8 @@ bash$ openocd --help
--version | -v display OpenOCD version
--file | -f use configuration file <name>
--search | -s dir to search for config files and scripts
--debug | -d set debug level <0-3>
--debug | -d set debug level to 3
| -d<n> set debug level to <level>
--log_output | -l redirect log output to file <name>
--command | -c run <command>
@end verbatim
@ -4715,15 +4716,18 @@ each block, and the specified length must stay within that bank.
@end deffn
@comment no current checks for errors if fill blocks touch multiple banks!
@deffn Command {flash write_bank} num filename offset
@deffn Command {flash write_bank} num filename [offset]
Write the binary @file{filename} to flash bank @var{num},
starting at @var{offset} bytes from the beginning of the bank.
starting at @var{offset} bytes from the beginning of the bank. If @var{offset}
is omitted, start at the beginning of the flash bank.
The @var{num} parameter is a value shown by @command{flash banks}.
@end deffn
@deffn Command {flash read_bank} num filename offset length
@deffn Command {flash read_bank} num filename [offset [length]]
Read @var{length} bytes from the flash bank @var{num} starting at @var{offset}
and write the contents to the binary @file{filename}.
and write the contents to the binary @file{filename}. If @var{offset} is
omitted, start at the beginning of the flash bank. If @var{length} is omitted,
read the remaining bytes from the flash bank.
The @var{num} parameter is a value shown by @command{flash banks}.
@end deffn
@ -5361,15 +5365,28 @@ nor is Chip Erase (only Sector Erase is implemented).}
@deffn {Flash Driver} kinetis
@cindex kinetis
Kx and KLx members of the Kinetis microcontroller family from Freescale include
Kx, KLx, KVx and KE1x members of the Kinetis microcontroller family
from NXP (former Freescale) include
internal flash and use ARM Cortex-M0+ or M4 cores. The driver automatically
recognizes flash size and a number of flash banks (1-4) using the chip
identification register, and autoconfigures itself.
Use kinetis_ke driver for KE0x devices.
The @var{kinetis} driver defines option:
@itemize
@item -sim-base @var{addr} ... base of System Integration Module where chip identification resides. Driver tries two known locations if option is omitted.
@end itemize
@example
flash bank $_FLASHNAME kinetis 0 0 0 0 $_TARGETNAME
@end example
@deffn Command {kinetis create_banks}
Configuration command enables automatic creation of additional flash banks
based on real flash layout of device. Banks are created during device probe.
Use 'flash probe 0' to force probe.
@end deffn
@deffn Command {kinetis fcf_source} [protection|write]
Select what source is used when writing to a Flash Configuration Field.
@option{protection} mode builds FCF content from protection bits previously
@ -5446,10 +5463,11 @@ Command disables watchdog timer.
@deffn {Flash Driver} kinetis_ke
@cindex kinetis_ke
KE members of the Kinetis microcontroller family from Freescale include
KE0x members of the Kinetis microcontroller family from Freescale include
internal flash and use ARM Cortex-M0+. The driver automatically recognizes
the KE family and sub-family using the chip identification register, and
the KE0x sub-family using the chip identification register, and
autoconfigures itself.
Use kinetis (not kinetis_ke) driver for KE1x devices.
@example
flash bank $_FLASHNAME kinetis_ke 0 0 0 0 $_TARGETNAME
@ -5971,16 +5989,21 @@ The @var{num} parameter is a value shown by @command{flash banks}.
@end deffn
@deffn Command {stm32f2x options_read} num
Reads and displays user options and (where implemented) boot_addr0 and boot_addr1.
Reads and displays user options and (where implemented) boot_addr0, boot_addr1, optcr2.
The @var{num} parameter is a value shown by @command{flash banks}.
@end deffn
@deffn Command {stm32f2x options_write} num user_options boot_addr0 boot_addr1
Writes user options and (where implemented) boot_addr0 and boot_addr1 in raw format.
Warning: The meaning of the various bits depends on the device, always check datasheet!
The @var{num} parameter is a value shown by @command{flash banks}, user_options a
12 bit value, consisting of bits 31-28 and 7-0 of FLASH_OPTCR, boot_addr0 and boot_addr1
two halfwords (of FLASH_OPTCR1).
The @var{num} parameter is a value shown by @command{flash banks}, @var{user_options} a
12 bit value, consisting of bits 31-28 and 7-0 of FLASH_OPTCR, @var{boot_addr0} and
@var{boot_addr1} two halfwords (of FLASH_OPTCR1).
@end deffn
@deffn Command {stm32f2x optcr2_write} num optcr2
Writes FLASH_OPTCR2 options. Warning: Clearing PCROPi bits requires a full mass erase!
The @var{num} parameter is a value shown by @command{flash banks}, @var{optcr2} a 32-bit word.
@end deffn
@end deffn
@ -6832,12 +6855,13 @@ non-zero exit code to the parent process.
@deffn Command debug_level [n]
@cindex message level
Display debug level.
If @var{n} (from 0..3) is provided, then set it to that level.
If @var{n} (from 0..4) is provided, then set it to that level.
This affects the kind of messages sent to the server log.
Level 0 is error messages only;
level 1 adds warnings;
level 2 adds informational messages;
and level 3 adds debugging messages.
level 3 adds debugging messages;
and level 4 adds verbose low-level debug messages.
The default is level 2, but that can be overridden on
the command line along with the location of that log
file (which is normally the server's standard output).

View File

@ -464,7 +464,7 @@ static const struct sam4_chip_details all_sam4_details[] = {
.bank_number = 0,
.base_address = FLASH_BANK_BASE_S,
.controller_address = 0x400e0a00,
.flash_wait_states = 6, /* workaround silicon bug */
.flash_wait_states = 5,
.present = 1,
.size_bytes = 1024 * 1024,
.nsectors = 128,
@ -499,7 +499,7 @@ static const struct sam4_chip_details all_sam4_details[] = {
.bank_number = 0,
.base_address = FLASH_BANK_BASE_S,
.controller_address = 0x400e0a00,
.flash_wait_states = 6, /* workaround silicon bug */
.flash_wait_states = 5,
.present = 1,
.size_bytes = 512 * 1024,
.nsectors = 64,
@ -532,7 +532,7 @@ static const struct sam4_chip_details all_sam4_details[] = {
.bank_number = 0,
.base_address = FLASH_BANK_BASE_S,
.controller_address = 0x400e0a00,
.flash_wait_states = 6, /* workaround silicon bug */
.flash_wait_states = 5,
.present = 1,
.size_bytes = 512 * 1024,
.nsectors = 64,
@ -565,7 +565,7 @@ static const struct sam4_chip_details all_sam4_details[] = {
.bank_number = 0,
.base_address = FLASH_BANK_BASE_S,
.controller_address = 0x400e0a00,
.flash_wait_states = 6, /* workaround silicon bug */
.flash_wait_states = 5,
.present = 1,
.size_bytes = 512 * 1024,
.nsectors = 64,
@ -598,7 +598,7 @@ static const struct sam4_chip_details all_sam4_details[] = {
.bank_number = 0,
.base_address = FLASH_BANK_BASE_S,
.controller_address = 0x400e0a00,
.flash_wait_states = 6, /* workaround silicon bug */
.flash_wait_states = 5,
.present = 1,
.size_bytes = 1024 * 1024,
.nsectors = 128,
@ -631,7 +631,7 @@ static const struct sam4_chip_details all_sam4_details[] = {
.bank_number = 0,
.base_address = FLASH_BANK_BASE_S,
.controller_address = 0x400e0a00,
.flash_wait_states = 6, /* workaround silicon bug */
.flash_wait_states = 5,
.present = 1,
.size_bytes = 1024 * 1024,
.nsectors = 128,
@ -1279,7 +1279,7 @@ static const struct sam4_chip_details all_sam4_details[] = {
.bank_number = 0,
.base_address = FLASH_BANK0_BASE_SD,
.controller_address = 0x400e0a00,
.flash_wait_states = 6, /* workaround silicon bug */
.flash_wait_states = 5,
.present = 1,
.size_bytes = 512 * 1024,
.nsectors = 64,
@ -1295,7 +1295,7 @@ static const struct sam4_chip_details all_sam4_details[] = {
.bank_number = 1,
.base_address = FLASH_BANK1_BASE_1024K_SD,
.controller_address = 0x400e0c00,
.flash_wait_states = 6, /* workaround silicon bug */
.flash_wait_states = 5,
.present = 1,
.size_bytes = 512 * 1024,
.nsectors = 64,
@ -1305,10 +1305,10 @@ static const struct sam4_chip_details all_sam4_details[] = {
},
},
/* at91samg53n19 */
/* atsamg53n19 */
{
.chipid_cidr = 0x247e0ae0,
.name = "at91samg53n19",
.name = "atsamg53n19",
.total_flash_size = 512 * 1024,
.total_sram_size = 96 * 1024,
.n_gpnvms = 2,
@ -1323,7 +1323,7 @@ static const struct sam4_chip_details all_sam4_details[] = {
.bank_number = 0,
.base_address = FLASH_BANK_BASE_S,
.controller_address = 0x400e0a00,
.flash_wait_states = 6, /* workaround silicon bug */
.flash_wait_states = 5,
.present = 1,
.size_bytes = 512 * 1024,
.nsectors = 64,

View File

@ -25,7 +25,7 @@
#include <target/cortex_m.h>
#define SAMD_NUM_SECTORS 16
#define SAMD_NUM_PROT_BLOCKS 16
#define SAMD_PAGE_SIZE_MAX 1024
#define SAMD_FLASH ((uint32_t)0x00000000) /* physical Flash memory */
@ -286,6 +286,7 @@ struct samd_info {
uint32_t page_size;
int num_pages;
int sector_size;
int prot_block_size;
bool probed;
struct target *target;
@ -319,7 +320,7 @@ static const struct samd_part *samd_find_part(uint32_t id)
static int samd_protect_check(struct flash_bank *bank)
{
int res;
int res, prot_block;
uint16_t lock;
res = target_read_u16(bank->target,
@ -328,8 +329,8 @@ static int samd_protect_check(struct flash_bank *bank)
return res;
/* Lock bits are active-low */
for (int i = 0; i < bank->num_sectors; i++)
bank->sectors[i].is_protected = !(lock & (1<<i));
for (prot_block = 0; prot_block < bank->num_prot_blocks; prot_block++)
bank->prot_blocks[prot_block].is_protected = !(lock & (1u<<prot_block));
return ERROR_OK;
}
@ -380,8 +381,6 @@ static int samd_probe(struct flash_bank *bank)
bank->size = part->flash_kb * 1024;
chip->sector_size = bank->size / SAMD_NUM_SECTORS;
res = samd_get_flash_page_info(bank->target, &chip->page_size,
&chip->num_pages);
if (res != ERROR_OK) {
@ -397,21 +396,23 @@ static int samd_probe(struct flash_bank *bank)
part->flash_kb, chip->num_pages, chip->page_size);
}
/* Erase granularity = 1 row = 4 pages */
chip->sector_size = chip->page_size * 4;
/* Allocate the sector table */
bank->num_sectors = SAMD_NUM_SECTORS;
bank->sectors = calloc(bank->num_sectors, sizeof((bank->sectors)[0]));
bank->num_sectors = chip->num_pages / 4;
bank->sectors = alloc_block_array(0, chip->sector_size, bank->num_sectors);
if (!bank->sectors)
return ERROR_FAIL;
/* Fill out the sector information: all SAMD sectors are the same size and
* there is always a fixed number of them. */
for (int i = 0; i < bank->num_sectors; i++) {
bank->sectors[i].size = chip->sector_size;
bank->sectors[i].offset = i * chip->sector_size;
/* mark as unknown */
bank->sectors[i].is_erased = -1;
bank->sectors[i].is_protected = -1;
}
/* 16 protection blocks per device */
chip->prot_block_size = bank->size / SAMD_NUM_PROT_BLOCKS;
/* Allocate the table of protection blocks */
bank->num_prot_blocks = SAMD_NUM_PROT_BLOCKS;
bank->prot_blocks = alloc_block_array(0, chip->prot_block_size, bank->num_prot_blocks);
if (!bank->prot_blocks)
return ERROR_FAIL;
samd_protect_check(bank);
@ -606,9 +607,10 @@ out_user_row:
return res;
}
static int samd_protect(struct flash_bank *bank, int set, int first, int last)
static int samd_protect(struct flash_bank *bank, int set, int first_prot_bl, int last_prot_bl)
{
struct samd_info *chip = (struct samd_info *)bank->driver_priv;
int res = ERROR_OK;
int prot_block;
/* We can issue lock/unlock region commands with the target running but
* the settings won't persist unless we're able to modify the LOCK regions
@ -618,18 +620,16 @@ static int samd_protect(struct flash_bank *bank, int set, int first, int last)
return ERROR_TARGET_NOT_HALTED;
}
int res = ERROR_OK;
for (int s = first; s <= last; s++) {
if (set != bank->sectors[s].is_protected) {
/* Load an address that is within this sector (we use offset 0) */
for (prot_block = first_prot_bl; prot_block <= last_prot_bl; prot_block++) {
if (set != bank->prot_blocks[prot_block].is_protected) {
/* Load an address that is within this protection block (we use offset 0) */
res = target_write_u32(bank->target,
SAMD_NVMCTRL + SAMD_NVMCTRL_ADDR,
((s * chip->sector_size) >> 1));
bank->prot_blocks[prot_block].offset >> 1);
if (res != ERROR_OK)
goto exit;
/* Tell the controller to lock that sector */
/* Tell the controller to lock that block */
res = samd_issue_nvmctrl_command(bank->target,
set ? SAMD_NVM_CMD_LR : SAMD_NVM_CMD_UR);
if (res != ERROR_OK)
@ -644,7 +644,7 @@ static int samd_protect(struct flash_bank *bank, int set, int first, int last)
* locked. See Table 9-3 in the SAMD20 datasheet for more details. */
res = samd_modify_user_row(bank->target, set ? 0x0000 : 0xFFFF,
48 + first, 48 + last);
48 + first_prot_bl, 48 + last_prot_bl);
if (res != ERROR_OK)
LOG_WARNING("SAMD: protect settings were not made persistent!");
@ -656,10 +656,9 @@ exit:
return res;
}
static int samd_erase(struct flash_bank *bank, int first, int last)
static int samd_erase(struct flash_bank *bank, int first_sect, int last_sect)
{
int res;
int rows_in_sector;
int res, s;
struct samd_info *chip = (struct samd_info *)bank->driver_priv;
if (bank->target->state != TARGET_HALTED) {
@ -673,26 +672,12 @@ static int samd_erase(struct flash_bank *bank, int first, int last)
return ERROR_FLASH_BANK_NOT_PROBED;
}
/* The SAMD NVM has row erase granularity. There are four pages in a row
* and the number of rows in a sector depends on the sector size, which in
* turn depends on the Flash capacity as there is a fixed number of
* sectors. */
rows_in_sector = chip->sector_size / (chip->page_size * 4);
/* For each sector to be erased */
for (int s = first; s <= last; s++) {
if (bank->sectors[s].is_protected) {
LOG_ERROR("SAMD: failed to erase sector %d. That sector is write-protected", s);
return ERROR_FLASH_OPERATION_FAILED;
}
/* For each row in that sector */
for (int r = s * rows_in_sector; r < (s + 1) * rows_in_sector; r++) {
res = samd_erase_row(bank->target, r * chip->page_size * 4);
if (res != ERROR_OK) {
LOG_ERROR("SAMD: failed to erase sector %d", s);
return res;
}
for (s = first_sect; s <= last_sect; s++) {
res = samd_erase_row(bank->target, bank->sectors[s].offset);
if (res != ERROR_OK) {
LOG_ERROR("SAMD: failed to erase sector %d at 0x%08" PRIx32, s, bank->sectors[s].offset);
return res;
}
}

View File

@ -48,6 +48,7 @@
#define EFM_FAMILY_ID_HAPPY_GECKO 77
#define EZR_FAMILY_ID_WONDER_GECKO 120
#define EZR_FAMILY_ID_LEOPARD_GECKO 121
#define EZR_FAMILY_ID_HAPPY_GECKO 122
#define EFM32_FLASH_ERASE_TMO 100
#define EFM32_FLASH_WDATAREADY_TMO 100
@ -178,7 +179,8 @@ static int efm32x_read_info(struct flash_bank *bank,
EFM_FAMILY_ID_TINY_GECKO == efm32_info->part_family)
efm32_info->page_size = 512;
else if (EFM_FAMILY_ID_ZERO_GECKO == efm32_info->part_family ||
EFM_FAMILY_ID_HAPPY_GECKO == efm32_info->part_family)
EFM_FAMILY_ID_HAPPY_GECKO == efm32_info->part_family ||
EZR_FAMILY_ID_HAPPY_GECKO == efm32_info->part_family)
efm32_info->page_size = 1024;
else if (EFM_FAMILY_ID_GIANT_GECKO == efm32_info->part_family ||
EFM_FAMILY_ID_LEOPARD_GECKO == efm32_info->part_family) {
@ -236,6 +238,7 @@ static int efm32x_decode_info(struct efm32_info *info, char *buf, int buf_size)
switch (info->part_family) {
case EZR_FAMILY_ID_WONDER_GECKO:
case EZR_FAMILY_ID_LEOPARD_GECKO:
case EZR_FAMILY_ID_HAPPY_GECKO:
printed = snprintf(buf, buf_size, "EZR32 ");
break;
default:
@ -270,6 +273,7 @@ static int efm32x_decode_info(struct efm32_info *info, char *buf, int buf_size)
printed = snprintf(buf, buf_size, "Zero Gecko");
break;
case EFM_FAMILY_ID_HAPPY_GECKO:
case EZR_FAMILY_ID_HAPPY_GECKO:
printed = snprintf(buf, buf_size, "Happy Gecko");
break;
}

File diff suppressed because it is too large Load Diff

View File

@ -59,10 +59,14 @@
*
* Sector sizes in kiBytes:
* 1 MiByte part with 4 x 16, 1 x 64, 7 x 128.
* 1.5 MiByte part with 4 x 16, 1 x 64, 11 x 128.
* 2 MiByte part with 4 x 16, 1 x 64, 7 x 128, 4 x 16, 1 x 64, 7 x 128.
* 1 MiByte STM32F42x/43x part with DB1M Option set:
* 4 x 16, 1 x 64, 3 x 128, 4 x 16, 1 x 64, 3 x 128.
*
* STM32F7[2|3]
* 512 kiByte part with 4 x 16, 1 x 64, 3 x 128.
*
* STM32F7[4|5]
* 1 MiByte part with 4 x 32, 1 x 128, 3 x 256.
*
@ -93,6 +97,12 @@
* RM0410
* http://www.st.com/resource/en/reference_manual/dm00224583.pdf
*
* RM0430
* http://www.st.com/resource/en/reference_manual/dm00305666.pdf
*
* RM0431
* http://www.st.com/resource/en/reference_manual/dm00305990.pdf
*
* STM32F1x series - notice that this code was copy, pasted and knocked
* into a stm32f2x driver, so in case something has been converted or
* bugs haven't been fixed, here are the original manuals:
@ -121,6 +131,7 @@
#define STM32_FLASH_CR 0x40023c10
#define STM32_FLASH_OPTCR 0x40023c14
#define STM32_FLASH_OPTCR1 0x40023c18
#define STM32_FLASH_OPTCR2 0x40023c1c
/* FLASH_CR register bits */
#define FLASH_PG (1 << 0)
@ -152,6 +163,10 @@
#define OPTCR_START (1 << 1)
#define OPTCR_NDBANK (1 << 29) /* not dual bank mode */
#define OPTCR_DB1M (1 << 30) /* 1 MiB devices dual flash bank option */
#define OPTCR_SPRMOD (1 << 31) /* switches PCROPi/nWPRi interpretation */
/* STM32_FLASH_OPTCR2 register bits */
#define OPTCR2_PCROP_RDP (1 << 31) /* erase PCROP zone when decreasing RDP */
/* register unlock keys */
#define KEY1 0x45670123
@ -166,14 +181,17 @@ struct stm32x_options {
uint16_t user_options; /* bit 0-7 usual options, bit 8-11 extra options */
uint32_t protection;
uint32_t boot_addr;
uint32_t optcr2_pcrop;
};
struct stm32x_flash_bank {
struct stm32x_options option_bytes;
int probed;
bool has_large_mem; /* F42x/43x/469/479/7xx in dual bank mode */
bool has_boot_addr; /* F7xx */
bool has_extra_options; /* F42x/43x/469/479/7xx */
bool has_boot_addr; /* F7xx */
bool has_optcr2_pcrop; /* F72x/73x */
int protection_bits; /* F413/423 */
uint32_t user_bank_size;
};
@ -328,11 +346,13 @@ static int stm32x_read_options(struct flash_bank *bank)
* whereas F7 6 bits (IWDG_SW and WWDG_SW) in user_options */
stm32x_info->option_bytes.user_options = optiondata & 0xfc;
stm32x_info->option_bytes.RDP = (optiondata >> 8) & 0xff;
stm32x_info->option_bytes.protection = (optiondata >> 16) & 0xfff;
stm32x_info->option_bytes.protection =
(optiondata >> 16) & (~(0xffff << stm32x_info->protection_bits) & 0xffff);
if (stm32x_info->has_extra_options) {
/* F42x/43x/469/479 and 7xx have up to 4 bits of extra options */
stm32x_info->option_bytes.user_options |= (optiondata >> 20) & 0xf00;
stm32x_info->option_bytes.user_options |= (optiondata >> 20) &
((0xf00 << (stm32x_info->protection_bits - 12)) & 0xf00);
}
if (stm32x_info->has_large_mem || stm32x_info->has_boot_addr) {
@ -350,6 +370,20 @@ static int stm32x_read_options(struct flash_bank *bank)
}
}
if (stm32x_info->has_optcr2_pcrop) {
retval = target_read_u32(target, STM32_FLASH_OPTCR2, &optiondata);
if (retval != ERROR_OK)
return retval;
stm32x_info->option_bytes.optcr2_pcrop = optiondata;
if (stm32x_info->has_optcr2_pcrop &&
(stm32x_info->option_bytes.optcr2_pcrop & ~OPTCR2_PCROP_RDP)) {
LOG_INFO("PCROP Engaged");
}
} else {
stm32x_info->option_bytes.optcr2_pcrop = 0x0;
}
if (stm32x_info->option_bytes.RDP != 0xAA)
LOG_INFO("Device Security Bit Set");
@ -371,11 +405,13 @@ static int stm32x_write_options(struct flash_bank *bank)
/* rebuild option data */
optiondata = stm32x_info->option_bytes.user_options & 0xfc;
optiondata |= stm32x_info->option_bytes.RDP << 8;
optiondata |= (stm32x_info->option_bytes.protection & 0x0fff) << 16;
optiondata |= (stm32x_info->option_bytes.protection &
(~(0xffff << stm32x_info->protection_bits))) << 16;
if (stm32x_info->has_extra_options) {
/* F42x/43x/469/479 and 7xx have up to 4 bits of extra options */
optiondata |= (stm32x_info->option_bytes.user_options & 0xf00) << 20;
optiondata |= (stm32x_info->option_bytes.user_options &
((0xf00 << (stm32x_info->protection_bits - 12)) & 0xf00)) << 20;
}
if (stm32x_info->has_large_mem || stm32x_info->has_boot_addr) {
@ -392,6 +428,14 @@ static int stm32x_write_options(struct flash_bank *bank)
return retval;
}
/* program extra pcrop register */
if (stm32x_info->has_optcr2_pcrop) {
retval = target_write_u32(target, STM32_FLASH_OPTCR2,
stm32x_info->option_bytes.optcr2_pcrop);
if (retval != ERROR_OK)
return retval;
}
/* program options */
retval = target_write_u32(target, STM32_FLASH_OPTCR, optiondata);
if (retval != ERROR_OK)
@ -418,6 +462,8 @@ static int stm32x_write_options(struct flash_bank *bank)
static int stm32x_protect_check(struct flash_bank *bank)
{
struct stm32x_flash_bank *stm32x_info = bank->driver_priv;
struct flash_sector *prot_blocks;
int num_prot_blocks;
/* read write protection settings */
int retval = stm32x_read_options(bank);
@ -426,27 +472,18 @@ static int stm32x_protect_check(struct flash_bank *bank)
return retval;
}
if (stm32x_info->has_boot_addr && stm32x_info->has_large_mem) {
/* F76x/77x: bit k protects sectors 2*k and 2*k+1 */
for (int i = 0; i < (bank->num_sectors >> 1); i++) {
if (stm32x_info->option_bytes.protection & (1 << i)) {
bank->sectors[i << 1].is_protected = 0;
bank->sectors[(i << 1) + 1].is_protected = 0;
} else {
bank->sectors[i << 1].is_protected = 1;
bank->sectors[(i << 1) + 1].is_protected = 1;
}
}
if (bank->prot_blocks) {
num_prot_blocks = bank->num_prot_blocks;
prot_blocks = bank->prot_blocks;
} else {
/* one protection bit per sector */
for (int i = 0; i < bank->num_sectors; i++) {
if (stm32x_info->option_bytes.protection & (1 << i))
bank->sectors[i].is_protected = 0;
else
bank->sectors[i].is_protected = 1;
}
num_prot_blocks = bank->num_sectors;
prot_blocks = bank->sectors;
}
for (int i = 0; i < num_prot_blocks; i++)
prot_blocks[i].is_protected =
~(stm32x_info->option_bytes.protection >> i) & 1;
return ERROR_OK;
}
@ -515,17 +552,6 @@ static int stm32x_protect(struct flash_bank *bank, int set, int first, int last)
return retval;
}
if (stm32x_info->has_boot_addr && stm32x_info->has_large_mem) {
/* F76x/77x: bit k protects sectors 2*k and 2*k+1 */
if ((first & 1) != 0 || (last & 1) != 1) {
LOG_ERROR("sector protection must be double sector aligned");
return ERROR_FAIL;
} else {
first >>= 1;
last >>= 1;
}
}
for (int i = first; i <= last; i++) {
if (set)
stm32x_info->option_bytes.protection &= ~(1 << i);
@ -829,7 +855,7 @@ static int stm32x_probe(struct flash_bank *bank)
{
struct target *target = bank->target;
struct stm32x_flash_bank *stm32x_info = bank->driver_priv;
int i;
int i, num_prot_blocks;
uint16_t flash_size_in_kb;
uint32_t flash_size_reg = 0x1FFF7A22;
uint16_t max_sector_size_in_kb = 128;
@ -841,15 +867,31 @@ static int stm32x_probe(struct flash_bank *bank)
stm32x_info->has_large_mem = false;
stm32x_info->has_boot_addr = false;
stm32x_info->has_extra_options = false;
stm32x_info->has_optcr2_pcrop = false;
stm32x_info->protection_bits = 12; /* max. number of nWRPi bits (in FLASH_OPTCR !!!) */
num_prot_blocks = 0;
if (bank->sectors) {
free(bank->sectors);
bank->num_sectors = 0;
bank->sectors = NULL;
}
if (bank->prot_blocks) {
free(bank->prot_blocks);
bank->num_prot_blocks = 0;
bank->prot_blocks = NULL;
}
/* read stm32 device id register */
int retval = stm32x_get_device_id(bank, &device_id);
if (retval != ERROR_OK)
return retval;
LOG_INFO("device id = 0x%08" PRIx32 "", device_id);
device_id &= 0xfff; /* only bits 0-11 are used further on */
/* set max flash size depending on family, id taken from AN2606 */
switch (device_id & 0xfff) {
switch (device_id) {
case 0x411: /* F20x/21x */
case 0x413: /* F40x/41x */
max_flash_size_in_kb = 1024;
@ -892,6 +934,21 @@ static int stm32x_probe(struct flash_bank *bank)
stm32x_info->has_boot_addr = true;
break;
case 0x452: /* F72x/73x */
max_flash_size_in_kb = 512;
flash_size_reg = 0x1FF07A22; /* yes, 0x1FF*0*7A22, not 0x1FF*F*7A22 */
stm32x_info->has_extra_options = true;
stm32x_info->has_boot_addr = true;
stm32x_info->has_optcr2_pcrop = true;
break;
case 0x463: /* F413x/423x */
max_flash_size_in_kb = 1536;
stm32x_info->has_extra_options = true;
stm32x_info->protection_bits = 15;
num_prot_blocks = 15;
break;
default:
LOG_WARNING("Cannot identify target as a STM32 family.");
return ERROR_FAIL;
@ -920,12 +977,8 @@ static int stm32x_probe(struct flash_bank *bank)
/* did we assign flash size? */
assert(flash_size_in_kb != 0xffff);
/* Devices with > 1024 kiByte always are dual-banked */
if (flash_size_in_kb > 1024)
stm32x_info->has_large_mem = true;
/* F42x/43x/469/479 1024 kiByte devices have a dual bank option */
if ((device_id & 0xfff) == 0x419 || (device_id & 0xfff) == 0x434) {
if ((device_id == 0x419) || (device_id == 0x434)) {
uint32_t optiondata;
retval = target_read_u32(target, STM32_FLASH_OPTCR, &optiondata);
if (retval != ERROR_OK) {
@ -942,7 +995,7 @@ static int stm32x_probe(struct flash_bank *bank)
}
/* F76x/77x devices have a dual bank option */
if ((device_id & 0xfff) == 0x451) {
if (device_id == 0x451) {
uint32_t optiondata;
retval = target_read_u32(target, STM32_FLASH_OPTCR, &optiondata);
if (retval != ERROR_OK) {
@ -963,11 +1016,6 @@ static int stm32x_probe(struct flash_bank *bank)
int num_pages = flash_size_in_kb / max_sector_size_in_kb
+ (stm32x_info->has_large_mem ? 8 : 4);
if (bank->sectors) {
free(bank->sectors);
bank->sectors = NULL;
}
bank->base = base_address;
bank->num_sectors = num_pages;
bank->sectors = malloc(sizeof(struct flash_sector) * num_pages);
@ -978,15 +1026,44 @@ static int stm32x_probe(struct flash_bank *bank)
bank->size = 0;
LOG_DEBUG("allocated %d sectors", num_pages);
/* F76x/77x in dual bank mode */
if ((device_id == 0x451) && stm32x_info->has_large_mem)
num_prot_blocks = num_pages >> 1;
if (num_prot_blocks) {
bank->prot_blocks = malloc(sizeof(struct flash_sector) * num_prot_blocks);
for (i = 0; i < num_prot_blocks; i++)
bank->prot_blocks[i].is_protected = 0;
LOG_DEBUG("allocated %d prot blocks", num_prot_blocks);
}
if (stm32x_info->has_large_mem) {
/* dual-bank */
setup_bank(bank, 0, flash_size_in_kb >> 1, max_sector_size_in_kb);
setup_bank(bank, num_pages >> 1, flash_size_in_kb >> 1,
max_sector_size_in_kb);
/* F767x/F77x in dual mode, one protection bit refers to two adjacent sectors */
if (device_id == 0x451) {
for (i = 0; i < num_prot_blocks; i++) {
bank->prot_blocks[i].offset = bank->sectors[i << 1].offset;
bank->prot_blocks[i].size = bank->sectors[i << 1].size << 1;
}
}
} else {
/* single-bank */
setup_bank(bank, 0, flash_size_in_kb, max_sector_size_in_kb);
/* F413/F423, sectors 14 and 15 share one common protection bit */
if (device_id == 0x463) {
for (i = 0; i < num_prot_blocks; i++) {
bank->prot_blocks[i].offset = bank->sectors[i].offset;
bank->prot_blocks[i].size = bank->sectors[i].size;
}
bank->prot_blocks[num_prot_blocks - 1].size <<= 1;
}
}
bank->num_prot_blocks = num_prot_blocks;
assert((bank->size >> 10) == flash_size_in_kb);
stm32x_info->probed = 1;
@ -1107,6 +1184,14 @@ static int get_stm32x_info(struct flash_bank *bank, char *buf, int buf_size)
case 0x1001:
rev_str = "Z";
break;
case 0x2000:
rev_str = "B";
break;
case 0x3000:
rev_str = "C";
break;
}
break;
@ -1134,6 +1219,26 @@ static int get_stm32x_info(struct flash_bank *bank, char *buf, int buf_size)
}
break;
case 0x452:
device_str = "STM32F7[2|3]x";
switch (rev_id) {
case 0x1000:
rev_str = "A";
break;
}
break;
case 0x463:
device_str = "STM32F4[1|2]3";
switch (rev_id) {
case 0x1000:
rev_str = "A";
break;
}
break;
default:
snprintf(buf, buf_size, "Cannot identify target as a STM32F2/4/7\n");
return ERROR_FAIL;
@ -1164,8 +1269,8 @@ COMMAND_HANDLER(stm32x_handle_lock_command)
target = bank->target;
if (target->state != TARGET_HALTED) {
LOG_ERROR("Target not halted");
return ERROR_TARGET_NOT_HALTED;
LOG_INFO("Target not halted");
/* return ERROR_TARGET_NOT_HALTED; */
}
if (stm32x_read_options(bank) != ERROR_OK) {
@ -1203,8 +1308,8 @@ COMMAND_HANDLER(stm32x_handle_unlock_command)
target = bank->target;
if (target->state != TARGET_HALTED) {
LOG_ERROR("Target not halted");
return ERROR_TARGET_NOT_HALTED;
LOG_INFO("Target not halted");
/* return ERROR_TARGET_NOT_HALTED; */
}
if (stm32x_read_options(bank) != ERROR_OK) {
@ -1215,6 +1320,9 @@ COMMAND_HANDLER(stm32x_handle_unlock_command)
/* clear readout protection and complementary option bytes
* this will also force a device unlock if set */
stm32x_info->option_bytes.RDP = 0xAA;
if (stm32x_info->has_optcr2_pcrop) {
stm32x_info->option_bytes.optcr2_pcrop = OPTCR2_PCROP_RDP | (~1 << bank->num_sectors);
}
if (stm32x_write_options(bank) != ERROR_OK) {
command_print(CMD_CTX, "%s failed to unlock device", bank->driver->name);
@ -1327,8 +1435,12 @@ COMMAND_HANDLER(stm32f2x_handle_options_read_command)
" boot_add0 0x%04X, boot_add1 0x%04X",
stm32x_info->option_bytes.user_options,
boot_addr & 0xffff, (boot_addr & 0xffff0000) >> 16);
if (stm32x_info->has_optcr2_pcrop) {
command_print(CMD_CTX, "stm32f2x optcr2_pcrop 0x%08X",
stm32x_info->option_bytes.optcr2_pcrop);
}
} else {
command_print(CMD_CTX, "stm32f2x user_options 0x%03X,",
command_print(CMD_CTX, "stm32f2x user_options 0x%03X",
stm32x_info->option_bytes.user_options);
}
} else {
@ -1345,7 +1457,7 @@ COMMAND_HANDLER(stm32f2x_handle_options_write_command)
int retval;
struct flash_bank *bank;
struct stm32x_flash_bank *stm32x_info = NULL;
uint16_t user_options, boot_addr0, boot_addr1;
uint16_t user_options, boot_addr0, boot_addr1, options_mask;
if (CMD_ARGC < 1) {
command_print(CMD_CTX, "stm32f2x options_write <bank> ...");
@ -1378,9 +1490,11 @@ COMMAND_HANDLER(stm32f2x_handle_options_write_command)
}
COMMAND_PARSE_NUMBER(u16, CMD_ARGV[1], user_options);
if (user_options & (stm32x_info->has_extra_options ? ~0xffc : ~0xfc)) {
options_mask = !stm32x_info->has_extra_options ? ~0xfc :
~(((0xf00 << (stm32x_info->protection_bits - 12)) | 0xff) & 0xffc);
if (user_options & options_mask) {
command_print(CMD_CTX, "stm32f2x invalid user_options");
return ERROR_COMMAND_SYNTAX_ERROR;
return ERROR_COMMAND_ARGUMENT_INVALID;
}
stm32x_info->option_bytes.user_options = user_options;
@ -1400,6 +1514,48 @@ COMMAND_HANDLER(stm32f2x_handle_options_write_command)
return retval;
}
COMMAND_HANDLER(stm32f2x_handle_optcr2_write_command)
{
int retval;
struct flash_bank *bank;
struct stm32x_flash_bank *stm32x_info = NULL;
uint32_t optcr2_pcrop;
if (CMD_ARGC != 2) {
command_print(CMD_CTX, "stm32f2x optcr2_write <bank> <optcr2_value>");
return ERROR_COMMAND_SYNTAX_ERROR;
}
retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
if (ERROR_OK != retval)
return retval;
stm32x_info = bank->driver_priv;
if (!stm32x_info->has_optcr2_pcrop) {
command_print(CMD_CTX, "no optcr2 register");
return ERROR_COMMAND_ARGUMENT_INVALID;
}
command_print(CMD_CTX, "INFO: To disable PCROP, set PCROP_RDP"
" with PCROPi bits STILL SET, then\nlock device and"
" finally unlock it. Clears PCROP and mass erases flash.");
retval = stm32x_read_options(bank);
if (ERROR_OK != retval)
return retval;
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], optcr2_pcrop);
stm32x_info->option_bytes.optcr2_pcrop = optcr2_pcrop;
if (stm32x_write_options(bank) != ERROR_OK) {
command_print(CMD_CTX, "stm32f2x failed to write options");
return ERROR_OK;
}
command_print(CMD_CTX, "stm32f2x optcr2_write complete.");
return retval;
}
static const struct command_registration stm32x_exec_command_handlers[] = {
{
.name = "lock",
@ -1433,9 +1589,17 @@ static const struct command_registration stm32x_exec_command_handlers[] = {
.name = "options_write",
.handler = stm32f2x_handle_options_write_command,
.mode = COMMAND_EXEC,
.usage = "bank_id user_options [ boot_add0 boot_add1]",
.usage = "bank_id user_options [ boot_add0 boot_add1 ]",
.help = "Write option bytes",
},
{
.name = "optcr2_write",
.handler = stm32f2x_handle_optcr2_write_command,
.mode = COMMAND_EXEC,
.usage = "bank_id optcr2",
.help = "Write optcr2 word",
},
COMMAND_REGISTRATION_DONE
};

View File

@ -790,6 +790,11 @@ static int stm32lx_probe(struct flash_bank *bank)
flash_size_in_kb = 256;
}
/* 0x429 devices only use the lowest 8 bits of the flash size register */
if (retval == ERROR_OK && (device_id & 0xfff) == 0x429) {
flash_size_in_kb &= 0xff;
}
/* Failed reading flash size or flash size invalid (early silicon),
* default to max target family */
if (retval != ERROR_OK || flash_size_in_kb == 0xffff || flash_size_in_kb == 0) {

View File

@ -583,9 +583,10 @@ COMMAND_HANDLER(handle_flash_write_bank_command)
{
uint32_t offset;
uint8_t *buffer;
size_t length;
struct fileio *fileio;
if (CMD_ARGC != 3)
if (CMD_ARGC < 2 || CMD_ARGC > 3)
return ERROR_COMMAND_SYNTAX_ERROR;
struct duration bench;
@ -596,7 +597,16 @@ COMMAND_HANDLER(handle_flash_write_bank_command)
if (ERROR_OK != retval)
return retval;
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], offset);
offset = 0;
if (CMD_ARGC > 2)
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], offset);
if (offset > p->size) {
LOG_ERROR("Offset 0x%8.8" PRIx32 " is out of range of the flash bank",
offset);
return ERROR_COMMAND_ARGUMENT_INVALID;
}
if (fileio_open(&fileio, CMD_ARGV[1], FILEIO_READ, FILEIO_BINARY) != ERROR_OK)
return ERROR_FAIL;
@ -608,20 +618,38 @@ COMMAND_HANDLER(handle_flash_write_bank_command)
return retval;
}
buffer = malloc(filesize);
length = MIN(filesize, p->size - offset);
if (!length) {
LOG_INFO("Nothing to write to flash bank");
fileio_close(fileio);
return ERROR_OK;
}
if (length != filesize)
LOG_INFO("File content exceeds flash bank size. Only writing the "
"first %zu bytes of the file", length);
buffer = malloc(length);
if (buffer == NULL) {
fileio_close(fileio);
LOG_ERROR("Out of memory");
return ERROR_FAIL;
}
size_t buf_cnt;
if (fileio_read(fileio, filesize, buffer, &buf_cnt) != ERROR_OK) {
if (fileio_read(fileio, length, buffer, &buf_cnt) != ERROR_OK) {
free(buffer);
fileio_close(fileio);
return ERROR_FAIL;
}
retval = flash_driver_write(p, buffer, offset, buf_cnt);
if (buf_cnt != length) {
LOG_ERROR("Short read");
free(buffer);
return ERROR_FAIL;
}
retval = flash_driver_write(p, buffer, offset, length);
free(buffer);
buffer = NULL;
@ -629,8 +657,8 @@ COMMAND_HANDLER(handle_flash_write_bank_command)
if ((ERROR_OK == retval) && (duration_measure(&bench) == ERROR_OK)) {
command_print(CMD_CTX, "wrote %zu bytes from file %s to flash bank %u"
" at offset 0x%8.8" PRIx32 " in %fs (%0.3f KiB/s)",
filesize, CMD_ARGV[1], p->bank_number, offset,
duration_elapsed(&bench), duration_kbps(&bench, filesize));
length, CMD_ARGV[1], p->bank_number, offset,
duration_elapsed(&bench), duration_kbps(&bench, length));
}
fileio_close(fileio);
@ -646,7 +674,7 @@ COMMAND_HANDLER(handle_flash_read_bank_command)
uint32_t length;
size_t written;
if (CMD_ARGC != 4)
if (CMD_ARGC < 2 || CMD_ARGC > 4)
return ERROR_COMMAND_SYNTAX_ERROR;
struct duration bench;
@ -654,11 +682,31 @@ COMMAND_HANDLER(handle_flash_read_bank_command)
struct flash_bank *p;
int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p);
if (ERROR_OK != retval)
return retval;
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], offset);
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], length);
offset = 0;
if (CMD_ARGC > 2)
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], offset);
if (offset > p->size) {
LOG_ERROR("Offset 0x%8.8" PRIx32 " is out of range of the flash bank",
offset);
return ERROR_COMMAND_ARGUMENT_INVALID;
}
length = p->size - offset;
if (CMD_ARGC > 3)
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], length);
if (offset + length > p->size) {
LOG_ERROR("Length of %" PRIu32 " bytes with offset 0x%8.8" PRIx32
" is out of range of the flash bank", length, offset);
return ERROR_COMMAND_ARGUMENT_INVALID;
}
buffer = malloc(length);
if (buffer == NULL) {
@ -705,6 +753,7 @@ COMMAND_HANDLER(handle_flash_verify_bank_command)
struct fileio *fileio;
size_t read_cnt;
size_t filesize;
size_t length;
int differ;
if (CMD_ARGC < 2 || CMD_ARGC > 3)
@ -741,14 +790,26 @@ COMMAND_HANDLER(handle_flash_verify_bank_command)
return retval;
}
buffer_file = malloc(filesize);
length = MIN(filesize, p->size - offset);
if (!length) {
LOG_INFO("Nothing to compare with flash bank");
fileio_close(fileio);
return ERROR_OK;
}
if (length != filesize)
LOG_INFO("File content exceeds flash bank size. Only comparing the "
"first %zu bytes of the file", length);
buffer_file = malloc(length);
if (buffer_file == NULL) {
LOG_ERROR("Out of memory");
fileio_close(fileio);
return ERROR_FAIL;
}
retval = fileio_read(fileio, filesize, buffer_file, &read_cnt);
retval = fileio_read(fileio, length, buffer_file, &read_cnt);
fileio_close(fileio);
if (retval != ERROR_OK) {
LOG_ERROR("File read failure");
@ -756,20 +817,20 @@ COMMAND_HANDLER(handle_flash_verify_bank_command)
return retval;
}
if (read_cnt != filesize) {
if (read_cnt != length) {
LOG_ERROR("Short read");
free(buffer_file);
return ERROR_FAIL;
}
buffer_flash = malloc(filesize);
buffer_flash = malloc(length);
if (buffer_flash == NULL) {
LOG_ERROR("Out of memory");
free(buffer_file);
return ERROR_FAIL;
}
retval = flash_driver_read(p, buffer_flash, offset, read_cnt);
retval = flash_driver_read(p, buffer_flash, offset, length);
if (retval != ERROR_OK) {
LOG_ERROR("Flash read error");
free(buffer_flash);
@ -780,15 +841,15 @@ COMMAND_HANDLER(handle_flash_verify_bank_command)
if (duration_measure(&bench) == ERROR_OK)
command_print(CMD_CTX, "read %zd bytes from file %s and flash bank %u"
" at offset 0x%8.8" PRIx32 " in %fs (%0.3f KiB/s)",
read_cnt, CMD_ARGV[1], p->bank_number, offset,
duration_elapsed(&bench), duration_kbps(&bench, read_cnt));
length, CMD_ARGV[1], p->bank_number, offset,
duration_elapsed(&bench), duration_kbps(&bench, length));
differ = memcmp(buffer_file, buffer_flash, read_cnt);
differ = memcmp(buffer_file, buffer_flash, length);
command_print(CMD_CTX, "contents %s", differ ? "differ" : "match");
if (differ) {
uint32_t t;
int diffs = 0;
for (t = 0; t < read_cnt; t++) {
for (t = 0; t < length; t++) {
if (buffer_flash[t] == buffer_file[t])
continue;
command_print(CMD_CTX, "diff %d address 0x%08x. Was 0x%02x instead of 0x%02x",
@ -908,10 +969,9 @@ static const struct command_registration flash_exec_command_handlers[] = {
.name = "write_bank",
.handler = handle_flash_write_bank_command,
.mode = COMMAND_EXEC,
.usage = "bank_id filename offset",
.help = "Write binary data from file to flash bank, "
"starting at specified byte offset from the "
"beginning of the bank.",
.usage = "bank_id filename [offset]",
.help = "Write binary data from file to flash bank. Allow optional "
"offset from beginning of the bank (defaults to zero).",
},
{
.name = "write_image",
@ -926,10 +986,9 @@ static const struct command_registration flash_exec_command_handlers[] = {
.name = "read_bank",
.handler = handle_flash_read_bank_command,
.mode = COMMAND_EXEC,
.usage = "bank_id filename offset length",
.help = "Read binary data from flash bank to file, "
"starting at specified byte offset from the "
"beginning of the bank.",
.usage = "bank_id filename [offset [length]]",
.help = "Read binary data from flash bank to file. Allow optional "
"offset from beginning of the bank (defaults to zero).",
},
{
.name = "verify_bank",

View File

@ -50,11 +50,12 @@ static int64_t current_time;
static int64_t start;
static const char * const log_strings[5] = {
static const char * const log_strings[6] = {
"User : ",
"Error: ",
"Warn : ", /* want a space after each colon, all same width, colons aligned */
"Info : ",
"Debug: ",
"Debug: "
};
@ -234,8 +235,8 @@ COMMAND_HANDLER(handle_debug_level_command)
if (CMD_ARGC == 1) {
int new_level;
COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], new_level);
if ((new_level > LOG_LVL_DEBUG) || (new_level < LOG_LVL_SILENT)) {
LOG_ERROR("level must be between %d and %d", LOG_LVL_SILENT, LOG_LVL_DEBUG);
if ((new_level > LOG_LVL_DEBUG_IO) || (new_level < LOG_LVL_SILENT)) {
LOG_ERROR("level must be between %d and %d", LOG_LVL_SILENT, LOG_LVL_DEBUG_IO);
return ERROR_COMMAND_SYNTAX_ERROR;
}
debug_level = new_level;
@ -279,7 +280,8 @@ static struct command_registration log_command_handlers[] = {
.mode = COMMAND_ANY,
.help = "Sets the verbosity level of debugging output. "
"0 shows errors only; 1 adds warnings; "
"2 (default) adds other info; 3 adds debugging.",
"2 (default) adds other info; 3 adds debugging; "
"4 adds extra verbose debugging.",
.usage = "number",
},
COMMAND_REGISTRATION_DONE
@ -303,7 +305,7 @@ void log_init(void)
int retval = parse_int(debug_env, &value);
if (ERROR_OK == retval &&
debug_level >= LOG_LVL_SILENT &&
debug_level <= LOG_LVL_DEBUG)
debug_level <= LOG_LVL_DEBUG_IO)
debug_level = value;
}

View File

@ -46,6 +46,7 @@
* LOG_LVL_WARNING - non-fatal errors, that may be resolved later
* LOG_LVL_INFO - state information, etc.
* LOG_LVL_DEBUG - debug statements, execution trace
* LOG_LVL_DEBUG_IO - verbose debug, low-level I/O trace
*/
enum log_levels {
LOG_LVL_SILENT = -3,
@ -54,7 +55,8 @@ enum log_levels {
LOG_LVL_ERROR = 0,
LOG_LVL_WARNING = 1,
LOG_LVL_INFO = 2,
LOG_LVL_DEBUG = 3
LOG_LVL_DEBUG = 3,
LOG_LVL_DEBUG_IO = 4,
};
void log_printf(enum log_levels level, const char *file, unsigned line,
@ -102,6 +104,14 @@ extern int debug_level;
#define LOG_LEVEL_IS(FOO) ((debug_level) >= (FOO))
#define LOG_DEBUG_IO(expr ...) \
do { \
if (debug_level >= LOG_LVL_DEBUG_IO) \
log_printf_lf(LOG_LVL_DEBUG, \
__FILE__, __LINE__, __func__, \
expr); \
} while (0)
#define LOG_DEBUG(expr ...) \
do { \
if (debug_level >= LOG_LVL_DEBUG) \

View File

@ -596,7 +596,7 @@ static int cmsis_dap_swd_run_queue(void)
{
uint8_t *buffer = cmsis_dap_handle->packet_buffer;
LOG_DEBUG("Executing %d queued transactions", pending_transfer_count);
LOG_DEBUG_IO("Executing %d queued transactions", pending_transfer_count);
if (queued_retval != ERROR_OK) {
LOG_DEBUG("Skipping due to previous errors: %d", queued_retval);
@ -616,7 +616,7 @@ static int cmsis_dap_swd_run_queue(void)
uint8_t cmd = pending_transfers[i].cmd;
uint32_t data = pending_transfers[i].data;
LOG_DEBUG("%s %s reg %x %"PRIx32,
LOG_DEBUG_IO("%s %s reg %x %"PRIx32,
cmd & SWD_CMD_APnDP ? "AP" : "DP",
cmd & SWD_CMD_RnW ? "read" : "write",
(cmd & SWD_CMD_A32) >> 1, data);
@ -674,7 +674,7 @@ static int cmsis_dap_swd_run_queue(void)
uint32_t tmp = data;
idx += 4;
LOG_DEBUG("Read result: %"PRIx32, data);
LOG_DEBUG_IO("Read result: %"PRIx32, data);
/* Imitate posted AP reads */
if ((pending_transfers[i].cmd & SWD_CMD_APnDP) ||

View File

@ -1109,12 +1109,12 @@ static void ftdi_swd_swdio_en(bool enable)
*/
static int ftdi_swd_run_queue(void)
{
LOG_DEBUG("Executing %zu queued transactions", swd_cmd_queue_length);
LOG_DEBUG_IO("Executing %zu queued transactions", swd_cmd_queue_length);
int retval;
struct signal *led = find_signal_by_name("LED");
if (queued_retval != ERROR_OK) {
LOG_DEBUG("Skipping due to previous errors: %d", queued_retval);
LOG_DEBUG_IO("Skipping due to previous errors: %d", queued_retval);
goto skip;
}
@ -1135,7 +1135,7 @@ static int ftdi_swd_run_queue(void)
for (size_t i = 0; i < swd_cmd_queue_length; i++) {
int ack = buf_get_u32(swd_cmd_queue[i].trn_ack_data_parity_trn, 1, 3);
LOG_DEBUG("%s %s %s reg %X = %08"PRIx32,
LOG_DEBUG_IO("%s %s %s reg %X = %08"PRIx32,
ack == SWD_ACK_OK ? "OK" : ack == SWD_ACK_WAIT ? "WAIT" : ack == SWD_ACK_FAULT ? "FAULT" : "JUNK",
swd_cmd_queue[i].cmd & SWD_CMD_APnDP ? "AP" : "DP",
swd_cmd_queue[i].cmd & SWD_CMD_RnW ? "read" : "write",

View File

@ -1,5 +1,5 @@
/***************************************************************************
* Copyright (C) 2016 by Square, Inc. *
* Copyright (C) 2017 by Square, Inc. *
* Steven Stallion <stallion@squareup.com> *
* *
* This program is free software; you can redistribute it and/or modify *
@ -20,34 +20,35 @@
#include "config.h"
#endif
#include "rtos.h"
#include "rtos_standard_stackings.h"
#include "target/armv7m.h"
#include <helper/types.h>
#include <rtos/rtos.h>
#include <rtos/rtos_standard_stackings.h>
#include <target/armv7m.h>
static const struct stack_register_offset rtos_uCOS_III_Cortex_M_stack_offsets[ARMV7M_NUM_CORE_REGS] = {
{ 0x20, 32 }, /* r0 */
{ 0x24, 32 }, /* r1 */
{ 0x28, 32 }, /* r2 */
{ 0x2c, 32 }, /* r3 */
{ 0x00, 32 }, /* r4 */
{ 0x04, 32 }, /* r5 */
{ 0x08, 32 }, /* r6 */
{ 0x0c, 32 }, /* r7 */
{ 0x10, 32 }, /* r8 */
{ 0x14, 32 }, /* r9 */
{ 0x18, 32 }, /* r10 */
{ 0x1c, 32 }, /* r11 */
{ 0x30, 32 }, /* r12 */
{ -2, 32 }, /* sp */
{ 0x34, 32 }, /* lr */
{ 0x38, 32 }, /* pc */
{ 0x3c, 32 }, /* xPSR */
static const struct stack_register_offset rtos_uCOS_III_Cortex_M_stack_offsets[] = {
{ 0x20, 32 }, /* r0 */
{ 0x24, 32 }, /* r1 */
{ 0x28, 32 }, /* r2 */
{ 0x2c, 32 }, /* r3 */
{ 0x00, 32 }, /* r4 */
{ 0x04, 32 }, /* r5 */
{ 0x08, 32 }, /* r6 */
{ 0x0c, 32 }, /* r7 */
{ 0x10, 32 }, /* r8 */
{ 0x14, 32 }, /* r9 */
{ 0x18, 32 }, /* r10 */
{ 0x1c, 32 }, /* r11 */
{ 0x30, 32 }, /* r12 */
{ -2, 32 }, /* sp */
{ 0x34, 32 }, /* lr */
{ 0x38, 32 }, /* pc */
{ 0x3c, 32 }, /* xPSR */
};
const struct rtos_register_stacking rtos_uCOS_III_Cortex_M_stacking = {
0x40, /* stack_registers_size */
-1, /* stack_growth_direction */
ARMV7M_NUM_CORE_REGS, /* num_output_registers */
rtos_generic_stack_align8, /* stack_alignment */
rtos_uCOS_III_Cortex_M_stack_offsets /* register_offsets */
0x40, /* stack_registers_size */
-1, /* stack_growth_direction */
ARRAY_SIZE(rtos_uCOS_III_Cortex_M_stack_offsets), /* num_output_registers */
rtos_generic_stack_align8, /* stack_alignment */
rtos_uCOS_III_Cortex_M_stack_offsets /* register_offsets */
};

View File

@ -1,5 +1,5 @@
/***************************************************************************
* Copyright (C) 2016 by Square, Inc. *
* Copyright (C) 2017 by Square, Inc. *
* Steven Stallion <stallion@squareup.com> *
* *
* This program is free software; you can redistribute it and/or modify *
@ -23,7 +23,7 @@
#include "config.h"
#endif
#include "rtos.h"
#include <rtos/rtos.h>
extern const struct rtos_register_stacking rtos_uCOS_III_Cortex_M_stacking;

View File

@ -1,5 +1,5 @@
/***************************************************************************
* Copyright (C) 2016 by Square, Inc. *
* Copyright (C) 2017 by Square, Inc. *
* Steven Stallion <stallion@squareup.com> *
* *
* This program is free software; you can redistribute it and/or modify *
@ -20,14 +20,14 @@
#include "config.h"
#endif
#include <helper/log.h>
#include <helper/time_support.h>
#include <jtag/jtag.h>
#include "target/target.h"
#include "target/target_type.h"
#include "rtos.h"
#include "helper/log.h"
#include "helper/types.h"
#include "rtos/rtos_ucos_iii_stackings.h"
#include <helper/types.h>
#include <rtos/rtos.h>
#include <target/target.h>
#include <target/target_type.h>
#include "rtos_ucos_iii_stackings.h"
#ifndef UCOS_III_MAX_STRLEN
#define UCOS_III_MAX_STRLEN 64
@ -55,18 +55,18 @@ struct uCOS_III_params {
static const struct uCOS_III_params uCOS_III_params_list[] = {
{
"cortex_m", /* target_name */
sizeof(uint32_t), /* pointer_width */
0, /* thread_stack_offset */
0, /* thread_name_offset */
0, /* thread_state_offset */
0, /* thread_priority_offset */
0, /* thread_prev_offset */
0, /* thread_next_offset */
false, /* thread_offsets_updated */
1, /* threadid_start */
"cortex_m", /* target_name */
sizeof(uint32_t), /* pointer_width */
0, /* thread_stack_offset */
0, /* thread_name_offset */
0, /* thread_state_offset */
0, /* thread_priority_offset */
0, /* thread_prev_offset */
0, /* thread_next_offset */
false, /* thread_offsets_updated */
1, /* threadid_start */
&rtos_uCOS_III_Cortex_M_stacking, /* stacking_info */
0, /* num_threads */
0, /* num_threads */
},
};
@ -159,10 +159,10 @@ static int uCOS_III_find_last_thread_address(struct rtos *rtos, symbol_address_t
symbol_address_t thread_list_address = 0;
retval = target_read_memory(rtos->target,
rtos->symbols[uCOS_III_VAL_OSTaskDbgListPtr].address,
params->pointer_width,
1,
(void *)&thread_list_address);
rtos->symbols[uCOS_III_VAL_OSTaskDbgListPtr].address,
params->pointer_width,
1,
(void *)&thread_list_address);
if (retval != ERROR_OK) {
LOG_ERROR("uCOS-III: failed to read thread list address");
return retval;
@ -173,10 +173,10 @@ static int uCOS_III_find_last_thread_address(struct rtos *rtos, symbol_address_t
*thread_address = thread_list_address;
retval = target_read_memory(rtos->target,
thread_list_address + params->thread_next_offset,
params->pointer_width,
1,
(void *)&thread_list_address);
thread_list_address + params->thread_next_offset,
params->pointer_width,
1,
(void *)&thread_list_address);
if (retval != ERROR_OK) {
LOG_ERROR("uCOS-III: failed to read next thread address");
return retval;
@ -227,10 +227,10 @@ static int uCOS_III_update_thread_offsets(struct rtos *rtos)
const struct thread_offset_map *thread_offset_map = &thread_offset_maps[i];
int retval = target_read_memory(rtos->target,
rtos->symbols[thread_offset_map->symbol_value].address,
params->pointer_width,
1,
(void *)thread_offset_map->thread_offset);
rtos->symbols[thread_offset_map->symbol_value].address,
params->pointer_width,
1,
(void *)thread_offset_map->thread_offset);
if (retval != ERROR_OK) {
LOG_ERROR("uCOS-III: failed to read thread offset");
return retval;
@ -244,7 +244,7 @@ static int uCOS_III_update_thread_offsets(struct rtos *rtos)
static int uCOS_III_detect_rtos(struct target *target)
{
return target->rtos->symbols != NULL &&
target->rtos->symbols[uCOS_III_VAL_OSRunning].address != 0;
target->rtos->symbols[uCOS_III_VAL_OSRunning].address != 0;
}
static int uCOS_III_reset_handler(struct target *target, enum target_reset_mode reset_mode, void *priv)
@ -263,8 +263,7 @@ static int uCOS_III_create(struct target *target)
for (size_t i = 0; i < ARRAY_SIZE(uCOS_III_params_list); i++)
if (strcmp(uCOS_III_params_list[i].target_name, target->type->name) == 0) {
params = malloc(sizeof(*params) +
UCOS_III_MAX_THREADS * sizeof(*params->threads));
params = malloc(sizeof(*params) + (UCOS_III_MAX_THREADS * sizeof(*params->threads)));
if (params == NULL) {
LOG_ERROR("uCOS-III: out of memory");
return ERROR_FAIL;
@ -294,13 +293,18 @@ static int uCOS_III_update_threads(struct rtos *rtos)
uint8_t rtos_running;
retval = target_read_u8(rtos->target,
rtos->symbols[uCOS_III_VAL_OSRunning].address,
&rtos_running);
rtos->symbols[uCOS_III_VAL_OSRunning].address,
&rtos_running);
if (retval != ERROR_OK) {
LOG_ERROR("uCOS-III: failed to read RTOS running");
return retval;
}
if (rtos_running != 1 && rtos_running != 0) {
LOG_ERROR("uCOS-III: invalid RTOS running value");
return ERROR_FAIL;
}
if (!rtos_running) {
rtos->thread_details = calloc(1, sizeof(struct thread_detail));
if (rtos->thread_details == NULL) {
@ -327,10 +331,10 @@ static int uCOS_III_update_threads(struct rtos *rtos)
symbol_address_t current_thread_address = 0;
retval = target_read_memory(rtos->target,
rtos->symbols[uCOS_III_VAL_OSTCBCurPtr].address,
params->pointer_width,
1,
(void *)&current_thread_address);
rtos->symbols[uCOS_III_VAL_OSTCBCurPtr].address,
params->pointer_width,
1,
(void *)&current_thread_address);
if (retval != ERROR_OK) {
LOG_ERROR("uCOS-III: failed to read current thread address");
return retval;
@ -338,8 +342,8 @@ static int uCOS_III_update_threads(struct rtos *rtos)
/* read number of tasks */
retval = target_read_u16(rtos->target,
rtos->symbols[uCOS_III_VAL_OSTaskQty].address,
(void *)&rtos->thread_count);
rtos->symbols[uCOS_III_VAL_OSTaskQty].address,
(void *)&rtos->thread_count);
if (retval != ERROR_OK) {
LOG_ERROR("uCOS-III: failed to read thread count");
return retval;
@ -368,9 +372,7 @@ static int uCOS_III_update_threads(struct rtos *rtos)
char thread_str_buffer[UCOS_III_MAX_STRLEN + 1];
/* find or create new threadid */
retval = uCOS_III_find_or_create_thread(rtos,
thread_address,
&thread_detail->threadid);
retval = uCOS_III_find_or_create_thread(rtos, thread_address, &thread_detail->threadid);
if (retval != ERROR_OK) {
LOG_ERROR("uCOS-III: failed to find or create thread");
return retval;
@ -385,19 +387,19 @@ static int uCOS_III_update_threads(struct rtos *rtos)
symbol_address_t thread_name_address = 0;
retval = target_read_memory(rtos->target,
thread_address + params->thread_name_offset,
params->pointer_width,
1,
(void *)&thread_name_address);
thread_address + params->thread_name_offset,
params->pointer_width,
1,
(void *)&thread_name_address);
if (retval != ERROR_OK) {
LOG_ERROR("uCOS-III: failed to name address");
return retval;
}
retval = target_read_buffer(rtos->target,
thread_name_address,
sizeof(thread_str_buffer),
(void *)thread_str_buffer);
thread_name_address,
sizeof(thread_str_buffer),
(void *)thread_str_buffer);
if (retval != ERROR_OK) {
LOG_ERROR("uCOS-III: failed to read thread name");
return retval;
@ -411,16 +413,16 @@ static int uCOS_III_update_threads(struct rtos *rtos)
uint8_t thread_priority;
retval = target_read_u8(rtos->target,
thread_address + params->thread_state_offset,
&thread_state);
thread_address + params->thread_state_offset,
&thread_state);
if (retval != ERROR_OK) {
LOG_ERROR("uCOS-III: failed to read thread state");
return retval;
}
retval = target_read_u8(rtos->target,
thread_address + params->thread_priority_offset,
&thread_priority);
thread_address + params->thread_priority_offset,
&thread_priority);
if (retval != ERROR_OK) {
LOG_ERROR("uCOS-III: failed to read thread priority");
return retval;
@ -434,15 +436,15 @@ static int uCOS_III_update_threads(struct rtos *rtos)
thread_state_str = "Unknown";
snprintf(thread_str_buffer, sizeof(thread_str_buffer), "State: %s, Priority: %d",
thread_state_str, thread_priority);
thread_state_str, thread_priority);
thread_detail->extra_info_str = strdup(thread_str_buffer);
/* read previous thread address */
retval = target_read_memory(rtos->target,
thread_address + params->thread_prev_offset,
params->pointer_width,
1,
(void *)&thread_address);
thread_address + params->thread_prev_offset,
params->pointer_width,
1,
(void *)&thread_address);
if (retval != ERROR_OK) {
LOG_ERROR("uCOS-III: failed to read previous thread address");
return retval;
@ -470,19 +472,19 @@ static int uCOS_III_get_thread_reg_list(struct rtos *rtos, threadid_t threadid,
symbol_address_t stack_address = 0;
retval = target_read_memory(rtos->target,
thread_address + params->thread_stack_offset,
params->pointer_width,
1,
(void *)&stack_address);
thread_address + params->thread_stack_offset,
params->pointer_width,
1,
(void *)&stack_address);
if (retval != ERROR_OK) {
LOG_ERROR("uCOS-III: failed to read stack address");
return retval;
}
return rtos_generic_stack_read(rtos->target,
params->stacking_info,
stack_address,
hex_reg_list);
params->stacking_info,
stack_address,
hex_reg_list);
}
static int uCOS_III_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[])

View File

@ -3037,16 +3037,16 @@ static void handle_md_output(struct command_context *cmd_ctx,
const char *value_fmt;
switch (size) {
case 8:
value_fmt = "%16.16llx ";
value_fmt = "%16.16"PRIx64" ";
break;
case 4:
value_fmt = "%8.8x ";
value_fmt = "%8.8"PRIx64" ";
break;
case 2:
value_fmt = "%4.4x ";
value_fmt = "%4.4"PRIx64" ";
break;
case 1:
value_fmt = "%2.2x ";
value_fmt = "%2.2"PRIx64" ";
break;
default:
/* "can't happen", caller checked */

View File

@ -1,6 +0,0 @@
#
# Freescale Kinetis KE02 devices
#
set CHIPNAME ke02
source [find target/kex.cfg]

View File

@ -1,6 +0,0 @@
#
# Freescale Kinetis KE04 devices
#
set CHIPNAME ke04
source [find target/kex.cfg]

View File

@ -1,6 +0,0 @@
#
# Freescale Kinetis KE06 devices
#
set CHIPNAME ke06
source [find target/kex.cfg]

View File

@ -1,5 +1,5 @@
#
# Freescale Kinetis KE series devices
# Freescale Kinetis KE0x series devices
#
source [find target/swj-dp.tcl]
@ -21,11 +21,7 @@ if { [info exists WORKAREASIZE] } {
if { [info exists CPUTAPID] } {
set _CPUTAPID $CPUTAPID
} else {
if { [using_jtag] } {
set _CPUTAPID 0x4ba00477
} {
set _CPUTAPID 0x2ba01477
}
set _CPUTAPID 0x0bc11477
}
swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID

7
tcl/target/ke1xf.cfg Normal file
View File

@ -0,0 +1,7 @@
#
# NXP (Freescale) Kinetis KE1xF devices
#
set CHIPNAME ke
source [find target/kx.cfg]

7
tcl/target/ke1xz.cfg Normal file
View File

@ -0,0 +1,7 @@
#
# NXP (Freescale) Kinetis KE1xZ devices
#
set CHIPNAME ke
source [find target/klx.cfg]

View File

@ -1,5 +1,6 @@
#
# Freescale Kinetis KL series devices
# NXP (former Freescale) Kinetis KL series devices
# Also used for Cortex-M0+ equipped members of KVx and KE1xZ series
#
source [find target/swj-dp.tcl]
@ -31,11 +32,13 @@ target create $_TARGETNAME cortex_m -chain-position $_CHIPNAME.cpu
$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0
set _FLASHNAME $_CHIPNAME.flash
set _FLASHNAME $_CHIPNAME.pflash
flash bank $_FLASHNAME kinetis 0 0 0 0 $_TARGETNAME
kinetis create_banks
# Table 5-1. Clock Summary of KL25 Sub-Family Reference Manual
# specifies up to 1MHz for VLPR mode.
# specifies up to 1MHz for VLPR mode and up to 24MHz for run mode;
# Table 17 of Sub-Family Data Sheet rev4 lists 25MHz as the maximum frequency.
adapter_khz 1000
reset_config srst_nogate
@ -51,10 +54,9 @@ if {![using_hla]} {
cortex_m reset_config sysresetreq
}
# Table 5-1. Clock Summary of KL25 Sub-Family Reference Manual
# specifies up to 24MHz for run mode; Table 17 of Sub-Family Data
# Sheet rev4 lists 25MHz as the maximum frequency.
# Uncoment only if VLPR mode is not used
#$_TARGETNAME configure -event reset-init {
# adapter_khz 24000
#}
# Disable watchdog not to disturb OpenOCD algorithms running on MCU
# (e.g. armv7m_checksum_memory() in verify_image)
# Flash driver also disables watchdog before FTFA flash programming.
$_TARGETNAME configure -event reset-init {
kinetis disable_wdog
}

View File

@ -1,5 +1,6 @@
#
# Freescale Kinetis Kx series devices
# NXP (former Freescale) Kinetis Kx series devices
# Also used for Cortex-M4 equipped members of KVx and KE1xF series
#
source [find target/swj-dp.tcl]
@ -35,8 +36,9 @@ target create $_TARGETNAME cortex_m -chain-position $_CHIPNAME.cpu
$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0
set _FLASHNAME $_CHIPNAME.flash
set _FLASHNAME $_CHIPNAME.pflash
flash bank $_FLASHNAME kinetis 0 0 0 0 $_TARGETNAME
kinetis create_banks
adapter_khz 1000
@ -52,3 +54,11 @@ if {![using_hla]} {
# perform a soft reset
cortex_m reset_config sysresetreq
}
# Disable watchdog not to disturb OpenOCD algorithms running on MCU
# (e.g. armv7m_checksum_memory() in verify_image)
# Flash driver also disables watchdog before FTFA flash programming.
$_TARGETNAME configure -event reset-init {
kinetis disable_wdog
}

View File

@ -10,7 +10,8 @@ set _TARGETNAME $_CHIPNAME.cpu
jtag newtap zynq_pl bs -irlen 6 -ircapture 0x1 -irmask 0x03 \
-expected-id 0x23727093 \
-expected-id 0x13722093 \
-expected-id 0x03727093
-expected-id 0x03727093 \
-expected-id 0x03736093
jtag newtap $_CHIPNAME dap -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id 0x4ba00477