stm32l0: Run clang-format across the code
This commit is contained in:
parent
b84f883aeb
commit
a22d6e5056
|
@ -78,162 +78,149 @@
|
|||
#include "target_internal.h"
|
||||
#include "cortexm.h"
|
||||
|
||||
#define STM32Lx_NVM_PECR(p) ((p) + 0x04)
|
||||
#define STM32Lx_NVM_PEKEYR(p) ((p) + 0x0C)
|
||||
#define STM32Lx_NVM_PRGKEYR(p) ((p) + 0x10)
|
||||
#define STM32Lx_NVM_OPTKEYR(p) ((p) + 0x14)
|
||||
#define STM32Lx_NVM_SR(p) ((p) + 0x18)
|
||||
#define STM32Lx_NVM_OPTR(p) ((p) + 0x1C)
|
||||
#define STM32Lx_NVM_PECR(p) ((p) + 0x04)
|
||||
#define STM32Lx_NVM_PEKEYR(p) ((p) + 0x0C)
|
||||
#define STM32Lx_NVM_PRGKEYR(p) ((p) + 0x10)
|
||||
#define STM32Lx_NVM_OPTKEYR(p) ((p) + 0x14)
|
||||
#define STM32Lx_NVM_SR(p) ((p) + 0x18)
|
||||
#define STM32Lx_NVM_OPTR(p) ((p) + 0x1C)
|
||||
|
||||
#define STM32L0_NVM_PHYS (0x40022000ul)
|
||||
#define STM32L0_NVM_OPT_SIZE (12)
|
||||
#define STM32L0_NVM_EEPROM_CAT1_SIZE (1*512)
|
||||
#define STM32L0_NVM_EEPROM_CAT2_SIZE (1*1024)
|
||||
#define STM32L0_NVM_EEPROM_CAT3_SIZE (2*1024)
|
||||
#define STM32L0_NVM_EEPROM_CAT5_SIZE (6*1024)
|
||||
#define STM32L0_NVM_EEPROM_CAT1_SIZE (1 * 512)
|
||||
#define STM32L0_NVM_EEPROM_CAT2_SIZE (1 * 1024)
|
||||
#define STM32L0_NVM_EEPROM_CAT3_SIZE (2 * 1024)
|
||||
#define STM32L0_NVM_EEPROM_CAT5_SIZE (6 * 1024)
|
||||
|
||||
#define STM32L1_NVM_PHYS (0x40023c00ul)
|
||||
#define STM32L1_NVM_OPT_SIZE (32)
|
||||
#define STM32L1_NVM_EEPROM_SIZE (16*1024)
|
||||
#define STM32L1_NVM_PHYS (0x40023c00ul)
|
||||
#define STM32L1_NVM_OPT_SIZE (32)
|
||||
#define STM32L1_NVM_EEPROM_SIZE (16 * 1024)
|
||||
|
||||
#define STM32Lx_NVM_OPT_PHYS 0x1ff80000ul
|
||||
#define STM32Lx_NVM_EEPROM_PHYS 0x08080000ul
|
||||
#define STM32Lx_NVM_OPT_PHYS 0x1ff80000ul
|
||||
#define STM32Lx_NVM_EEPROM_PHYS 0x08080000ul
|
||||
|
||||
#define STM32Lx_NVM_PEKEY1 (0x89abcdeful)
|
||||
#define STM32Lx_NVM_PEKEY2 (0x02030405ul)
|
||||
#define STM32Lx_NVM_PRGKEY1 (0x8c9daebful)
|
||||
#define STM32Lx_NVM_PRGKEY2 (0x13141516ul)
|
||||
#define STM32Lx_NVM_OPTKEY1 (0xfbead9c8ul)
|
||||
#define STM32Lx_NVM_OPTKEY2 (0x24252627ul)
|
||||
#define STM32Lx_NVM_PEKEY1 (0x89abcdeful)
|
||||
#define STM32Lx_NVM_PEKEY2 (0x02030405ul)
|
||||
#define STM32Lx_NVM_PRGKEY1 (0x8c9daebful)
|
||||
#define STM32Lx_NVM_PRGKEY2 (0x13141516ul)
|
||||
#define STM32Lx_NVM_OPTKEY1 (0xfbead9c8ul)
|
||||
#define STM32Lx_NVM_OPTKEY2 (0x24252627ul)
|
||||
|
||||
#define STM32Lx_NVM_PECR_OBL_LAUNCH (1<<18)
|
||||
#define STM32Lx_NVM_PECR_ERRIE (1<<17)
|
||||
#define STM32Lx_NVM_PECR_EOPIE (1<<16)
|
||||
#define STM32Lx_NVM_PECR_FPRG (1<<10)
|
||||
#define STM32Lx_NVM_PECR_ERASE (1<< 9)
|
||||
#define STM32Lx_NVM_PECR_FIX (1<< 8) /* FTDW */
|
||||
#define STM32Lx_NVM_PECR_DATA (1<< 4)
|
||||
#define STM32Lx_NVM_PECR_PROG (1<< 3)
|
||||
#define STM32Lx_NVM_PECR_OPTLOCK (1<< 2)
|
||||
#define STM32Lx_NVM_PECR_PRGLOCK (1<< 1)
|
||||
#define STM32Lx_NVM_PECR_PELOCK (1<< 0)
|
||||
#define STM32Lx_NVM_PECR_OBL_LAUNCH (1 << 18)
|
||||
#define STM32Lx_NVM_PECR_ERRIE (1 << 17)
|
||||
#define STM32Lx_NVM_PECR_EOPIE (1 << 16)
|
||||
#define STM32Lx_NVM_PECR_FPRG (1 << 10)
|
||||
#define STM32Lx_NVM_PECR_ERASE (1 << 9)
|
||||
#define STM32Lx_NVM_PECR_FIX (1 << 8) /* FTDW */
|
||||
#define STM32Lx_NVM_PECR_DATA (1 << 4)
|
||||
#define STM32Lx_NVM_PECR_PROG (1 << 3)
|
||||
#define STM32Lx_NVM_PECR_OPTLOCK (1 << 2)
|
||||
#define STM32Lx_NVM_PECR_PRGLOCK (1 << 1)
|
||||
#define STM32Lx_NVM_PECR_PELOCK (1 << 0)
|
||||
|
||||
#define STM32Lx_NVM_SR_NOTZEROERR (1<<16)
|
||||
#define STM32Lx_NVM_SR_SIZERR (1<<10)
|
||||
#define STM32Lx_NVM_SR_PGAERR (1<<9)
|
||||
#define STM32Lx_NVM_SR_WRPERR (1<<8)
|
||||
#define STM32Lx_NVM_SR_EOP (1<<1)
|
||||
#define STM32Lx_NVM_SR_BSY (1<<0)
|
||||
#define STM32Lx_NVM_SR_ERR_M (STM32Lx_NVM_SR_WRPERR | \
|
||||
STM32Lx_NVM_SR_PGAERR | \
|
||||
STM32Lx_NVM_SR_SIZERR | \
|
||||
STM32Lx_NVM_SR_NOTZEROERR)
|
||||
#define STM32Lx_NVM_SR_NOTZEROERR (1 << 16)
|
||||
#define STM32Lx_NVM_SR_SIZERR (1 << 10)
|
||||
#define STM32Lx_NVM_SR_PGAERR (1 << 9)
|
||||
#define STM32Lx_NVM_SR_WRPERR (1 << 8)
|
||||
#define STM32Lx_NVM_SR_EOP (1 << 1)
|
||||
#define STM32Lx_NVM_SR_BSY (1 << 0)
|
||||
#define STM32Lx_NVM_SR_ERR_M \
|
||||
(STM32Lx_NVM_SR_WRPERR | STM32Lx_NVM_SR_PGAERR | STM32Lx_NVM_SR_SIZERR | STM32Lx_NVM_SR_NOTZEROERR)
|
||||
|
||||
#define STM32L0_NVM_OPTR_BOOT1 (1<<31)
|
||||
#define STM32Lx_NVM_OPTR_WDG_SW (1<<20)
|
||||
#define STM32L0_NVM_OPTR_WPRMOD (1<<8)
|
||||
#define STM32Lx_NVM_OPTR_RDPROT_S (0)
|
||||
#define STM32Lx_NVM_OPTR_RDPROT_M (0xff)
|
||||
#define STM32Lx_NVM_OPTR_RDPROT_0 (0xaa)
|
||||
#define STM32Lx_NVM_OPTR_RDPROT_2 (0xcc)
|
||||
#define STM32L0_NVM_OPTR_BOOT1 (1 << 31)
|
||||
#define STM32Lx_NVM_OPTR_WDG_SW (1 << 20)
|
||||
#define STM32L0_NVM_OPTR_WPRMOD (1 << 8)
|
||||
#define STM32Lx_NVM_OPTR_RDPROT_S (0)
|
||||
#define STM32Lx_NVM_OPTR_RDPROT_M (0xff)
|
||||
#define STM32Lx_NVM_OPTR_RDPROT_0 (0xaa)
|
||||
#define STM32Lx_NVM_OPTR_RDPROT_2 (0xcc)
|
||||
|
||||
#define STM32L1_NVM_OPTR_nBFB2 (1<<23)
|
||||
#define STM32L1_NVM_OPTR_nRST_STDBY (1<<22)
|
||||
#define STM32L1_NVM_OPTR_nRST_STOP (1<<21)
|
||||
#define STM32L1_NVM_OPTR_BOR_LEV_S (16)
|
||||
#define STM32L1_NVM_OPTR_BOR_LEV_M (0xf)
|
||||
#define STM32L1_NVM_OPTR_SPRMOD (1<<8)
|
||||
#define STM32L1_NVM_OPTR_nBFB2 (1 << 23)
|
||||
#define STM32L1_NVM_OPTR_nRST_STDBY (1 << 22)
|
||||
#define STM32L1_NVM_OPTR_nRST_STOP (1 << 21)
|
||||
#define STM32L1_NVM_OPTR_BOR_LEV_S (16)
|
||||
#define STM32L1_NVM_OPTR_BOR_LEV_M (0xf)
|
||||
#define STM32L1_NVM_OPTR_SPRMOD (1 << 8)
|
||||
|
||||
static int stm32lx_nvm_prog_erase(struct target_flash* f,
|
||||
target_addr addr, size_t len);
|
||||
static int stm32lx_nvm_prog_write(struct target_flash* f,
|
||||
target_addr destination,
|
||||
const void* src,
|
||||
size_t size);
|
||||
static int stm32lx_nvm_prog_erase(struct target_flash *f, target_addr addr, size_t len);
|
||||
static int stm32lx_nvm_prog_write(struct target_flash *f, target_addr destination, const void *src, size_t size);
|
||||
|
||||
static int stm32lx_nvm_data_erase(struct target_flash* f,
|
||||
target_addr addr, size_t len);
|
||||
static int stm32lx_nvm_data_write(struct target_flash* f,
|
||||
target_addr destination,
|
||||
const void* source,
|
||||
size_t size);
|
||||
static int stm32lx_nvm_data_erase(struct target_flash *f, target_addr addr, size_t len);
|
||||
static int stm32lx_nvm_data_write(struct target_flash *f, target_addr destination, const void *source, size_t size);
|
||||
|
||||
static bool stm32lx_cmd_option (target* t, int argc, char** argv);
|
||||
static bool stm32lx_cmd_eeprom (target* t, int argc, char** argv);
|
||||
static bool stm32lx_cmd_option(target *t, int argc, char **argv);
|
||||
static bool stm32lx_cmd_eeprom(target *t, int argc, char **argv);
|
||||
|
||||
static const struct command_s stm32lx_cmd_list[] = {
|
||||
{ "option", (cmd_handler) stm32lx_cmd_option,
|
||||
"Manipulate option bytes"},
|
||||
{ "eeprom", (cmd_handler) stm32lx_cmd_eeprom,
|
||||
"Manipulate EEPROM(NVM data) memory"},
|
||||
{ NULL, NULL, NULL },
|
||||
{"option", (cmd_handler)stm32lx_cmd_option, "Manipulate option bytes"},
|
||||
{"eeprom", (cmd_handler)stm32lx_cmd_eeprom, "Manipulate EEPROM(NVM data) memory"},
|
||||
{NULL, NULL, NULL},
|
||||
};
|
||||
|
||||
enum {
|
||||
STM32L0_DBGMCU_IDCODE_PHYS = 0x40015800,
|
||||
STM32L1_DBGMCU_IDCODE_PHYS = 0xe0042000,
|
||||
enum stm32l_idcode_e {
|
||||
STM32L0_DBGMCU_IDCODE_PHYS = 0x40015800,
|
||||
STM32L1_DBGMCU_IDCODE_PHYS = 0xe0042000,
|
||||
};
|
||||
|
||||
static bool stm32lx_is_stm32l1(target* t)
|
||||
static bool stm32lx_is_stm32l1(target *t)
|
||||
{
|
||||
switch (t->idcode) {
|
||||
case 0x457: /* STM32L0xx Cat1 */
|
||||
case 0x425: /* STM32L0xx Cat2 */
|
||||
case 0x417: /* STM32L0xx Cat3 */
|
||||
case 0x447: /* STM32L0xx Cat5 */
|
||||
return false;
|
||||
default: /* STM32L1xx */
|
||||
return true;
|
||||
}
|
||||
switch (t->idcode) {
|
||||
case 0x457: /* STM32L0xx Cat1 */
|
||||
case 0x425: /* STM32L0xx Cat2 */
|
||||
case 0x417: /* STM32L0xx Cat3 */
|
||||
case 0x447: /* STM32L0xx Cat5 */
|
||||
return false;
|
||||
default: /* STM32L1xx */
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t stm32lx_nvm_eeprom_size(target *t)
|
||||
{
|
||||
switch (t->idcode) {
|
||||
case 0x457: /* STM32L0xx Cat1 */
|
||||
return STM32L0_NVM_EEPROM_CAT1_SIZE;
|
||||
case 0x425: /* STM32L0xx Cat2 */
|
||||
return STM32L0_NVM_EEPROM_CAT2_SIZE;
|
||||
case 0x417: /* STM32L0xx Cat3 */
|
||||
return STM32L0_NVM_EEPROM_CAT3_SIZE;
|
||||
case 0x447: /* STM32L0xx Cat5 */
|
||||
return STM32L0_NVM_EEPROM_CAT5_SIZE;
|
||||
default: /* STM32L1xx */
|
||||
return STM32L1_NVM_EEPROM_SIZE;
|
||||
}
|
||||
switch (t->idcode) {
|
||||
case 0x457: /* STM32L0xx Cat1 */
|
||||
return STM32L0_NVM_EEPROM_CAT1_SIZE;
|
||||
case 0x425: /* STM32L0xx Cat2 */
|
||||
return STM32L0_NVM_EEPROM_CAT2_SIZE;
|
||||
case 0x417: /* STM32L0xx Cat3 */
|
||||
return STM32L0_NVM_EEPROM_CAT3_SIZE;
|
||||
case 0x447: /* STM32L0xx Cat5 */
|
||||
return STM32L0_NVM_EEPROM_CAT5_SIZE;
|
||||
default: /* STM32L1xx */
|
||||
return STM32L1_NVM_EEPROM_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t stm32lx_nvm_phys(target *t)
|
||||
{
|
||||
switch (t->idcode) {
|
||||
case 0x457: /* STM32L0xx Cat1 */
|
||||
case 0x425: /* STM32L0xx Cat2 */
|
||||
case 0x417: /* STM32L0xx Cat3 */
|
||||
case 0x447: /* STM32L0xx Cat5 */
|
||||
return STM32L0_NVM_PHYS;
|
||||
default: /* STM32L1xx */
|
||||
return STM32L1_NVM_PHYS;
|
||||
}
|
||||
switch (t->idcode) {
|
||||
case 0x457: /* STM32L0xx Cat1 */
|
||||
case 0x425: /* STM32L0xx Cat2 */
|
||||
case 0x417: /* STM32L0xx Cat3 */
|
||||
case 0x447: /* STM32L0xx Cat5 */
|
||||
return STM32L0_NVM_PHYS;
|
||||
default: /* STM32L1xx */
|
||||
return STM32L1_NVM_PHYS;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t stm32lx_nvm_option_size(target *t)
|
||||
{
|
||||
switch (t->idcode) {
|
||||
case 0x457: /* STM32L0xx Cat1 */
|
||||
case 0x425: /* STM32L0xx Cat2 */
|
||||
case 0x417: /* STM32L0xx Cat3 */
|
||||
case 0x447: /* STM32L0xx Cat5 */
|
||||
return STM32L0_NVM_OPT_SIZE;
|
||||
default: /* STM32L1xx */
|
||||
return STM32L1_NVM_OPT_SIZE;
|
||||
}
|
||||
switch (t->idcode) {
|
||||
case 0x457: /* STM32L0xx Cat1 */
|
||||
case 0x425: /* STM32L0xx Cat2 */
|
||||
case 0x417: /* STM32L0xx Cat3 */
|
||||
case 0x447: /* STM32L0xx Cat5 */
|
||||
return STM32L0_NVM_OPT_SIZE;
|
||||
default: /* STM32L1xx */
|
||||
return STM32L1_NVM_OPT_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
static void stm32l_add_flash(target *t,
|
||||
uint32_t addr, size_t length, size_t erasesize)
|
||||
static void stm32l_add_flash(target *t, uint32_t addr, size_t length, size_t erasesize)
|
||||
{
|
||||
struct target_flash *f = calloc(1, sizeof(*f));
|
||||
if (!f) { /* calloc failed: heap exhaustion */
|
||||
if (!f) { /* calloc failed: heap exhaustion */
|
||||
DEBUG_WARN("calloc: failed in %s\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
@ -243,14 +230,14 @@ static void stm32l_add_flash(target *t,
|
|||
f->blocksize = erasesize;
|
||||
f->erase = stm32lx_nvm_prog_erase;
|
||||
f->write = stm32lx_nvm_prog_write;
|
||||
f->buf_size = erasesize/2;
|
||||
f->buf_size = erasesize / 2;
|
||||
target_add_flash(t, f);
|
||||
}
|
||||
|
||||
static void stm32l_add_eeprom(target *t, uint32_t addr, size_t length)
|
||||
{
|
||||
struct target_flash *f = calloc(1, sizeof(*f));
|
||||
if (!f) { /* calloc failed: heap exhaustion */
|
||||
if (!f) { /* calloc failed: heap exhaustion */
|
||||
DEBUG_WARN("calloc: failed in %s\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
@ -266,24 +253,24 @@ static void stm32l_add_eeprom(target *t, uint32_t addr, size_t length)
|
|||
/** Query MCU memory for an indication as to whether or not the
|
||||
currently attached target is served by this module. We detect the
|
||||
STM32L0xx parts as well as the STM32L1xx's. */
|
||||
bool stm32l0_probe(target* t)
|
||||
bool stm32l0_probe(target *t)
|
||||
{
|
||||
switch (t->idcode) {
|
||||
case 0x416: /* CAT. 1 device */
|
||||
case 0x429: /* CAT. 2 device */
|
||||
case 0x427: /* CAT. 3 device */
|
||||
case 0x436: /* CAT. 4 device */
|
||||
case 0x437: /* CAT. 5 device */
|
||||
case 0x416: /* CAT. 1 device */
|
||||
case 0x429: /* CAT. 2 device */
|
||||
case 0x427: /* CAT. 3 device */
|
||||
case 0x436: /* CAT. 4 device */
|
||||
case 0x437: /* CAT. 5 device */
|
||||
t->driver = "STM32L1x";
|
||||
target_add_ram(t, 0x20000000, 0x14000);
|
||||
stm32l_add_flash(t, 0x8000000, 0x80000, 0x100);
|
||||
//stm32l_add_eeprom(t, 0x8080000, 0x4000);
|
||||
target_add_commands(t, stm32lx_cmd_list, "STM32L1x");
|
||||
return true;
|
||||
case 0x457: /* STM32L0xx Cat1 */
|
||||
case 0x425: /* STM32L0xx Cat2 */
|
||||
case 0x417: /* STM32L0xx Cat3 */
|
||||
case 0x447: /* STM32L0xx Cat5 */
|
||||
case 0x457: /* STM32L0xx Cat1 */
|
||||
case 0x425: /* STM32L0xx Cat2 */
|
||||
case 0x417: /* STM32L0xx Cat3 */
|
||||
case 0x447: /* STM32L0xx Cat5 */
|
||||
t->driver = "STM32L0x";
|
||||
target_add_ram(t, 0x20000000, 0x5000);
|
||||
stm32l_add_flash(t, 0x8000000, 0x10000, 0x80);
|
||||
|
@ -297,68 +284,60 @@ bool stm32l0_probe(target* t)
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
/** Lock the NVM control registers preventing writes or erases. */
|
||||
static void stm32lx_nvm_lock(target *t, uint32_t nvm)
|
||||
{
|
||||
target_mem_write32(t, STM32Lx_NVM_PECR(nvm), STM32Lx_NVM_PECR_PELOCK);
|
||||
target_mem_write32(t, STM32Lx_NVM_PECR(nvm), STM32Lx_NVM_PECR_PELOCK);
|
||||
}
|
||||
|
||||
|
||||
/** Unlock the NVM control registers for modifying program or
|
||||
data flash. Returns true if the unlock succeeds. */
|
||||
static bool stm32lx_nvm_prog_data_unlock(target* t, uint32_t nvm)
|
||||
static bool stm32lx_nvm_prog_data_unlock(target *t, uint32_t nvm)
|
||||
{
|
||||
/* Always lock first because that's the only way to know that the
|
||||
/* Always lock first because that's the only way to know that the
|
||||
unlock can succeed on the STM32L0's. */
|
||||
target_mem_write32(t, STM32Lx_NVM_PECR(nvm), STM32Lx_NVM_PECR_PELOCK);
|
||||
target_mem_write32(t, STM32Lx_NVM_PEKEYR(nvm), STM32Lx_NVM_PEKEY1);
|
||||
target_mem_write32(t, STM32Lx_NVM_PEKEYR(nvm), STM32Lx_NVM_PEKEY2);
|
||||
target_mem_write32(t, STM32Lx_NVM_PRGKEYR(nvm), STM32Lx_NVM_PRGKEY1);
|
||||
target_mem_write32(t, STM32Lx_NVM_PRGKEYR(nvm), STM32Lx_NVM_PRGKEY2);
|
||||
target_mem_write32(t, STM32Lx_NVM_PECR(nvm), STM32Lx_NVM_PECR_PELOCK);
|
||||
target_mem_write32(t, STM32Lx_NVM_PEKEYR(nvm), STM32Lx_NVM_PEKEY1);
|
||||
target_mem_write32(t, STM32Lx_NVM_PEKEYR(nvm), STM32Lx_NVM_PEKEY2);
|
||||
target_mem_write32(t, STM32Lx_NVM_PRGKEYR(nvm), STM32Lx_NVM_PRGKEY1);
|
||||
target_mem_write32(t, STM32Lx_NVM_PRGKEYR(nvm), STM32Lx_NVM_PRGKEY2);
|
||||
|
||||
return !(target_mem_read32(t, STM32Lx_NVM_PECR(nvm))
|
||||
& STM32Lx_NVM_PECR_PRGLOCK);
|
||||
return !(target_mem_read32(t, STM32Lx_NVM_PECR(nvm)) & STM32Lx_NVM_PECR_PRGLOCK);
|
||||
}
|
||||
|
||||
|
||||
/** Unlock the NVM control registers for modifying option bytes.
|
||||
Returns true if the unlock succeeds. */
|
||||
static bool stm32lx_nvm_opt_unlock(target *t, uint32_t nvm)
|
||||
{
|
||||
/* Always lock first because that's the only way to know that the
|
||||
/* Always lock first because that's the only way to know that the
|
||||
unlock can succeed on the STM32L0's. */
|
||||
target_mem_write32(t, STM32Lx_NVM_PECR(nvm), STM32Lx_NVM_PECR_PELOCK);
|
||||
target_mem_write32(t, STM32Lx_NVM_PEKEYR(nvm), STM32Lx_NVM_PEKEY1);
|
||||
target_mem_write32(t, STM32Lx_NVM_PEKEYR(nvm), STM32Lx_NVM_PEKEY2);
|
||||
target_mem_write32(t, STM32Lx_NVM_OPTKEYR(nvm), STM32Lx_NVM_OPTKEY1);
|
||||
target_mem_write32(t, STM32Lx_NVM_OPTKEYR(nvm), STM32Lx_NVM_OPTKEY2);
|
||||
target_mem_write32(t, STM32Lx_NVM_PECR(nvm), STM32Lx_NVM_PECR_PELOCK);
|
||||
target_mem_write32(t, STM32Lx_NVM_PEKEYR(nvm), STM32Lx_NVM_PEKEY1);
|
||||
target_mem_write32(t, STM32Lx_NVM_PEKEYR(nvm), STM32Lx_NVM_PEKEY2);
|
||||
target_mem_write32(t, STM32Lx_NVM_OPTKEYR(nvm), STM32Lx_NVM_OPTKEY1);
|
||||
target_mem_write32(t, STM32Lx_NVM_OPTKEYR(nvm), STM32Lx_NVM_OPTKEY2);
|
||||
|
||||
return !(target_mem_read32(t, STM32Lx_NVM_PECR(nvm))
|
||||
& STM32Lx_NVM_PECR_OPTLOCK);
|
||||
return !(target_mem_read32(t, STM32Lx_NVM_PECR(nvm)) & STM32Lx_NVM_PECR_OPTLOCK);
|
||||
}
|
||||
|
||||
/** Erase a region of program flash using operations through the debug
|
||||
interface. This is slower than stubbed versions(see NOTES). The
|
||||
flash array is erased for all pages from addr to addr+len
|
||||
inclusive. NVM register file address chosen from target. */
|
||||
static int stm32lx_nvm_prog_erase(struct target_flash* f,
|
||||
target_addr addr, size_t len)
|
||||
static int stm32lx_nvm_prog_erase(struct target_flash *f, target_addr addr, size_t len)
|
||||
{
|
||||
target *t = f->t;
|
||||
const size_t page_size = f->blocksize;
|
||||
const uint32_t nvm = stm32lx_nvm_phys(t);
|
||||
|
||||
if (!stm32lx_nvm_prog_data_unlock(t, nvm))
|
||||
return -1;
|
||||
return -1;
|
||||
|
||||
/* Flash page erase instruction */
|
||||
target_mem_write32(t, STM32Lx_NVM_PECR(nvm),
|
||||
STM32Lx_NVM_PECR_ERASE | STM32Lx_NVM_PECR_PROG);
|
||||
target_mem_write32(t, STM32Lx_NVM_PECR(nvm), STM32Lx_NVM_PECR_ERASE | STM32Lx_NVM_PECR_PROG);
|
||||
|
||||
uint32_t pecr = target_mem_read32(t, STM32Lx_NVM_PECR(nvm));
|
||||
if ((pecr & (STM32Lx_NVM_PECR_PROG | STM32Lx_NVM_PECR_ERASE))
|
||||
!= (STM32Lx_NVM_PECR_PROG | STM32Lx_NVM_PECR_ERASE))
|
||||
if ((pecr & (STM32Lx_NVM_PECR_PROG | STM32Lx_NVM_PECR_ERASE)) != (STM32Lx_NVM_PECR_PROG | STM32Lx_NVM_PECR_ERASE))
|
||||
return -1;
|
||||
|
||||
/* Clear errors. Note that this only works when we wait for the NVM
|
||||
|
@ -369,7 +348,7 @@ static int stm32lx_nvm_prog_erase(struct target_flash* f,
|
|||
/* Write first word of page to 0 */
|
||||
target_mem_write32(t, addr, 0);
|
||||
if (len > page_size)
|
||||
len -= page_size;
|
||||
len -= page_size;
|
||||
else
|
||||
len = 0;
|
||||
addr += page_size;
|
||||
|
@ -384,36 +363,29 @@ static int stm32lx_nvm_prog_erase(struct target_flash* f,
|
|||
sr = target_mem_read32(t, STM32Lx_NVM_SR(nvm));
|
||||
} while (sr & STM32Lx_NVM_SR_BSY);
|
||||
|
||||
if ((sr & STM32Lx_NVM_SR_ERR_M) || !(sr & STM32Lx_NVM_SR_EOP) ||
|
||||
target_check_error(t))
|
||||
return -1;
|
||||
if ((sr & STM32Lx_NVM_SR_ERR_M) || !(sr & STM32Lx_NVM_SR_EOP) || target_check_error(t))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/** Write to program flash using operations through the debug
|
||||
interface. */
|
||||
static int stm32lx_nvm_prog_write(struct target_flash *f,
|
||||
target_addr dest,
|
||||
const void* src,
|
||||
size_t size)
|
||||
static int stm32lx_nvm_prog_write(struct target_flash *f, target_addr dest, const void *src, size_t size)
|
||||
{
|
||||
target *t = f->t;
|
||||
const uint32_t nvm = stm32lx_nvm_phys(t);
|
||||
|
||||
if (!stm32lx_nvm_prog_data_unlock(t, nvm))
|
||||
return -1;
|
||||
return -1;
|
||||
|
||||
/* Wait for BSY to clear because we cannot write the PECR until
|
||||
the previous operation completes on STM32Lxxx. */
|
||||
while (target_mem_read32(t, STM32Lx_NVM_SR(nvm))
|
||||
& STM32Lx_NVM_SR_BSY)
|
||||
while (target_mem_read32(t, STM32Lx_NVM_SR(nvm)) & STM32Lx_NVM_SR_BSY)
|
||||
if (target_check_error(t))
|
||||
return -1;
|
||||
|
||||
target_mem_write32(t, STM32Lx_NVM_PECR(nvm),
|
||||
STM32Lx_NVM_PECR_PROG | STM32Lx_NVM_PECR_FPRG);
|
||||
target_mem_write32(t, STM32Lx_NVM_PECR(nvm), STM32Lx_NVM_PECR_PROG | STM32Lx_NVM_PECR_FPRG);
|
||||
target_mem_write(t, dest, src, size);
|
||||
|
||||
/* Disable further programming by locking PECR */
|
||||
|
@ -425,9 +397,8 @@ static int stm32lx_nvm_prog_write(struct target_flash *f,
|
|||
sr = target_mem_read32(t, STM32Lx_NVM_SR(nvm));
|
||||
} while (sr & STM32Lx_NVM_SR_BSY);
|
||||
|
||||
if ((sr & STM32Lx_NVM_SR_ERR_M) || !(sr & STM32Lx_NVM_SR_EOP) ||
|
||||
target_check_error(t))
|
||||
return -1;
|
||||
if ((sr & STM32Lx_NVM_SR_ERR_M) || !(sr & STM32Lx_NVM_SR_EOP) || target_check_error(t))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -436,8 +407,7 @@ static int stm32lx_nvm_prog_write(struct target_flash *f,
|
|||
interface . The flash is erased for all pages from addr to
|
||||
addr+len, inclusive, on a word boundary. NVM register file
|
||||
address chosen from target. */
|
||||
static int stm32lx_nvm_data_erase(struct target_flash *f,
|
||||
target_addr addr, size_t len)
|
||||
static int stm32lx_nvm_data_erase(struct target_flash *f, target_addr addr, size_t len)
|
||||
{
|
||||
target *t = f->t;
|
||||
const size_t page_size = f->blocksize;
|
||||
|
@ -451,12 +421,10 @@ static int stm32lx_nvm_data_erase(struct target_flash *f,
|
|||
return -1;
|
||||
|
||||
/* Flash data erase instruction */
|
||||
target_mem_write32(t, STM32Lx_NVM_PECR(nvm),
|
||||
STM32Lx_NVM_PECR_ERASE | STM32Lx_NVM_PECR_DATA);
|
||||
target_mem_write32(t, STM32Lx_NVM_PECR(nvm), STM32Lx_NVM_PECR_ERASE | STM32Lx_NVM_PECR_DATA);
|
||||
|
||||
uint32_t pecr = target_mem_read32(t, STM32Lx_NVM_PECR(nvm));
|
||||
if ((pecr & (STM32Lx_NVM_PECR_ERASE | STM32Lx_NVM_PECR_DATA))
|
||||
!= (STM32Lx_NVM_PECR_ERASE | STM32Lx_NVM_PECR_DATA))
|
||||
if ((pecr & (STM32Lx_NVM_PECR_ERASE | STM32Lx_NVM_PECR_DATA)) != (STM32Lx_NVM_PECR_ERASE | STM32Lx_NVM_PECR_DATA))
|
||||
return -1;
|
||||
|
||||
while (len > 0) {
|
||||
|
@ -464,7 +432,7 @@ static int stm32lx_nvm_data_erase(struct target_flash *f,
|
|||
target_mem_write32(t, addr, 0);
|
||||
|
||||
if (len > page_size)
|
||||
len -= page_size;
|
||||
len -= page_size;
|
||||
else
|
||||
len = 0;
|
||||
addr += page_size;
|
||||
|
@ -479,33 +447,27 @@ static int stm32lx_nvm_data_erase(struct target_flash *f,
|
|||
sr = target_mem_read32(t, STM32Lx_NVM_SR(nvm));
|
||||
} while (sr & STM32Lx_NVM_SR_BSY);
|
||||
|
||||
if ((sr & STM32Lx_NVM_SR_ERR_M) || !(sr & STM32Lx_NVM_SR_EOP) ||
|
||||
target_check_error(t))
|
||||
return -1;
|
||||
if ((sr & STM32Lx_NVM_SR_ERR_M) || !(sr & STM32Lx_NVM_SR_EOP) || target_check_error(t))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/** Write to data flash using operations through the debug interface.
|
||||
NVM register file address chosen from target. Unaligned
|
||||
destination writes are supported (though unaligned sources are
|
||||
not). */
|
||||
static int stm32lx_nvm_data_write(struct target_flash *f,
|
||||
target_addr destination,
|
||||
const void* src,
|
||||
size_t size)
|
||||
static int stm32lx_nvm_data_write(struct target_flash *f, target_addr destination, const void *src, size_t size)
|
||||
{
|
||||
target *t = f->t;
|
||||
const uint32_t nvm = stm32lx_nvm_phys(t);
|
||||
const bool is_stm32l1 = stm32lx_is_stm32l1(t);
|
||||
uint32_t* source = (uint32_t*) src;
|
||||
uint32_t *source = (uint32_t *)src;
|
||||
|
||||
if (!stm32lx_nvm_prog_data_unlock(t, nvm))
|
||||
return -1;
|
||||
|
||||
target_mem_write32(t, STM32Lx_NVM_PECR(nvm),
|
||||
is_stm32l1 ? 0 : STM32Lx_NVM_PECR_DATA);
|
||||
target_mem_write32(t, STM32Lx_NVM_PECR(nvm), is_stm32l1 ? 0 : STM32Lx_NVM_PECR_DATA);
|
||||
|
||||
while (size) {
|
||||
size -= 4;
|
||||
|
@ -526,14 +488,12 @@ static int stm32lx_nvm_data_write(struct target_flash *f,
|
|||
sr = target_mem_read32(t, STM32Lx_NVM_SR(nvm));
|
||||
} while (sr & STM32Lx_NVM_SR_BSY);
|
||||
|
||||
if ((sr & STM32Lx_NVM_SR_ERR_M) || !(sr & STM32Lx_NVM_SR_EOP) ||
|
||||
target_check_error(t))
|
||||
return -1;
|
||||
if ((sr & STM32Lx_NVM_SR_ERR_M) || !(sr & STM32Lx_NVM_SR_EOP) || target_check_error(t))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/** Write one option word. The address is the physical address of the
|
||||
word and the value is a complete word value. The caller is
|
||||
responsible for making sure that the value satisfies the proper
|
||||
|
@ -542,21 +502,20 @@ static int stm32lx_nvm_data_write(struct target_flash *f,
|
|||
The return value is true if the write succeeded. */
|
||||
static bool stm32lx_option_write(target *t, uint32_t address, uint32_t value)
|
||||
{
|
||||
const uint32_t nvm = stm32lx_nvm_phys(t);
|
||||
const uint32_t nvm = stm32lx_nvm_phys(t);
|
||||
|
||||
/* Erase and program option in one go. */
|
||||
target_mem_write32(t, STM32Lx_NVM_PECR(nvm), STM32Lx_NVM_PECR_FIX);
|
||||
target_mem_write32(t, address, value);
|
||||
/* Erase and program option in one go. */
|
||||
target_mem_write32(t, STM32Lx_NVM_PECR(nvm), STM32Lx_NVM_PECR_FIX);
|
||||
target_mem_write32(t, address, value);
|
||||
|
||||
uint32_t sr;
|
||||
do {
|
||||
sr = target_mem_read32(t, STM32Lx_NVM_SR(nvm));
|
||||
} while (sr & STM32Lx_NVM_SR_BSY);
|
||||
uint32_t sr;
|
||||
do {
|
||||
sr = target_mem_read32(t, STM32Lx_NVM_SR(nvm));
|
||||
} while (sr & STM32Lx_NVM_SR_BSY);
|
||||
|
||||
return !(sr & STM32Lx_NVM_SR_ERR_M);
|
||||
return !(sr & STM32Lx_NVM_SR_ERR_M);
|
||||
}
|
||||
|
||||
|
||||
/** Write one eeprom value. This version is more flexible than that
|
||||
bulk version used for writing data from the executable file. The
|
||||
address is the physical address of the word and the value is a
|
||||
|
@ -564,206 +523,180 @@ static bool stm32lx_option_write(target *t, uint32_t address, uint32_t value)
|
|||
complete. The return value is true if the write succeeded.
|
||||
FWIW, byte writing isn't supported because the adiv5 layer
|
||||
doesn't support byte-level operations. */
|
||||
static bool stm32lx_eeprom_write(target *t, uint32_t address,
|
||||
size_t cb, uint32_t value)
|
||||
static bool stm32lx_eeprom_write(target *t, uint32_t address, size_t cb, uint32_t value)
|
||||
{
|
||||
const uint32_t nvm = stm32lx_nvm_phys(t);
|
||||
const bool is_stm32l1 = stm32lx_is_stm32l1(t);
|
||||
const uint32_t nvm = stm32lx_nvm_phys(t);
|
||||
const bool is_stm32l1 = stm32lx_is_stm32l1(t);
|
||||
|
||||
/* Clear errors. */
|
||||
target_mem_write32(t, STM32Lx_NVM_SR(nvm), STM32Lx_NVM_SR_ERR_M);
|
||||
/* Clear errors. */
|
||||
target_mem_write32(t, STM32Lx_NVM_SR(nvm), STM32Lx_NVM_SR_ERR_M);
|
||||
|
||||
/* Erase and program option in one go. */
|
||||
target_mem_write32(t, STM32Lx_NVM_PECR(nvm),
|
||||
(is_stm32l1 ? 0 : STM32Lx_NVM_PECR_DATA)
|
||||
| STM32Lx_NVM_PECR_FIX);
|
||||
if (cb == 4)
|
||||
target_mem_write32(t, address, value);
|
||||
else if (cb == 2)
|
||||
target_mem_write16(t, address, value);
|
||||
else if (cb == 1)
|
||||
target_mem_write8(t, address, value);
|
||||
else
|
||||
return false;
|
||||
/* Erase and program option in one go. */
|
||||
target_mem_write32(t, STM32Lx_NVM_PECR(nvm), (is_stm32l1 ? 0 : STM32Lx_NVM_PECR_DATA) | STM32Lx_NVM_PECR_FIX);
|
||||
if (cb == 4)
|
||||
target_mem_write32(t, address, value);
|
||||
else if (cb == 2)
|
||||
target_mem_write16(t, address, value);
|
||||
else if (cb == 1)
|
||||
target_mem_write8(t, address, value);
|
||||
else
|
||||
return false;
|
||||
|
||||
uint32_t sr;
|
||||
do {
|
||||
sr = target_mem_read32(t, STM32Lx_NVM_SR(nvm));
|
||||
} while (sr & STM32Lx_NVM_SR_BSY);
|
||||
uint32_t sr;
|
||||
do {
|
||||
sr = target_mem_read32(t, STM32Lx_NVM_SR(nvm));
|
||||
} while (sr & STM32Lx_NVM_SR_BSY);
|
||||
|
||||
return !(sr & STM32Lx_NVM_SR_ERR_M);
|
||||
return !(sr & STM32Lx_NVM_SR_ERR_M);
|
||||
}
|
||||
|
||||
static bool stm32lx_cmd_option(target* t, int argc, char** argv)
|
||||
static bool stm32lx_cmd_option(target *t, int argc, char **argv)
|
||||
{
|
||||
const uint32_t nvm = stm32lx_nvm_phys(t);
|
||||
const size_t opt_size = stm32lx_nvm_option_size(t);
|
||||
const uint32_t nvm = stm32lx_nvm_phys(t);
|
||||
const size_t opt_size = stm32lx_nvm_option_size(t);
|
||||
|
||||
if (!stm32lx_nvm_opt_unlock(t, nvm)) {
|
||||
tc_printf(t, "unable to unlock NVM option bytes\n");
|
||||
return true;
|
||||
}
|
||||
if (!stm32lx_nvm_opt_unlock(t, nvm)) {
|
||||
tc_printf(t, "unable to unlock NVM option bytes\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (argc < 2 )
|
||||
goto usage;
|
||||
size_t cb = strlen(argv[1]);
|
||||
if (argc < 2)
|
||||
goto usage;
|
||||
size_t cb = strlen(argv[1]);
|
||||
|
||||
if (argc == 2 && !strncasecmp(argv[1], "obl_launch", cb)) {
|
||||
target_mem_write32(t, STM32Lx_NVM_PECR(nvm),
|
||||
STM32Lx_NVM_PECR_OBL_LAUNCH);
|
||||
}
|
||||
else if (argc == 4 && !strncasecmp(argv[1], "raw", cb)) {
|
||||
uint32_t addr = strtoul(argv[2], NULL, 0);
|
||||
uint32_t val = strtoul(argv[3], NULL, 0);
|
||||
tc_printf(t, "raw %08x <- %08x\n", addr, val);
|
||||
if ( addr < STM32Lx_NVM_OPT_PHYS
|
||||
|| addr >= STM32Lx_NVM_OPT_PHYS + opt_size
|
||||
|| (addr & 3))
|
||||
goto usage;
|
||||
if (!stm32lx_option_write(t, addr, val))
|
||||
tc_printf(t, "option write failed\n");
|
||||
}
|
||||
else if (argc == 4 && !strncasecmp(argv[1], "write", cb)) {
|
||||
uint32_t addr = strtoul(argv[2], NULL, 0);
|
||||
uint32_t val = strtoul(argv[3], NULL, 0);
|
||||
val = (val & 0xffff) | ((~val & 0xffff) << 16);
|
||||
tc_printf(t, "write %08x <- %08x\n", addr, val);
|
||||
if ( addr < STM32Lx_NVM_OPT_PHYS
|
||||
|| addr >= STM32Lx_NVM_OPT_PHYS + opt_size
|
||||
|| (addr & 3))
|
||||
goto usage;
|
||||
if (!stm32lx_option_write(t, addr, val))
|
||||
tc_printf(t, "option write failed\n");
|
||||
}
|
||||
if (argc == 2 && !strncasecmp(argv[1], "obl_launch", cb)) {
|
||||
target_mem_write32(t, STM32Lx_NVM_PECR(nvm), STM32Lx_NVM_PECR_OBL_LAUNCH);
|
||||
} else if (argc == 4 && !strncasecmp(argv[1], "raw", cb)) {
|
||||
uint32_t addr = strtoul(argv[2], NULL, 0);
|
||||
uint32_t val = strtoul(argv[3], NULL, 0);
|
||||
tc_printf(t, "raw %08x <- %08x\n", addr, val);
|
||||
if (addr < STM32Lx_NVM_OPT_PHYS || addr >= STM32Lx_NVM_OPT_PHYS + opt_size || (addr & 3))
|
||||
goto usage;
|
||||
if (!stm32lx_option_write(t, addr, val))
|
||||
tc_printf(t, "option write failed\n");
|
||||
} else if (argc == 4 && !strncasecmp(argv[1], "write", cb)) {
|
||||
uint32_t addr = strtoul(argv[2], NULL, 0);
|
||||
uint32_t val = strtoul(argv[3], NULL, 0);
|
||||
val = (val & 0xffff) | ((~val & 0xffff) << 16);
|
||||
tc_printf(t, "write %08x <- %08x\n", addr, val);
|
||||
if (addr < STM32Lx_NVM_OPT_PHYS || addr >= STM32Lx_NVM_OPT_PHYS + opt_size || (addr & 3))
|
||||
goto usage;
|
||||
if (!stm32lx_option_write(t, addr, val))
|
||||
tc_printf(t, "option write failed\n");
|
||||
}
|
||||
|
||||
/* Report the current option values */
|
||||
for(unsigned i = 0; i < opt_size; i += sizeof(uint32_t)) {
|
||||
uint32_t addr = STM32Lx_NVM_OPT_PHYS + i;
|
||||
uint32_t val = target_mem_read32(t, addr);
|
||||
tc_printf(t, "0x%08x: 0x%04x 0x%04x %s\n",
|
||||
addr, val & 0xffff, (val >> 16) & 0xffff,
|
||||
((val & 0xffff) == ((~val >> 16) & 0xffff))
|
||||
? "OK" : "ERR");
|
||||
}
|
||||
/* Report the current option values */
|
||||
for (unsigned i = 0; i < opt_size; i += sizeof(uint32_t)) {
|
||||
uint32_t addr = STM32Lx_NVM_OPT_PHYS + i;
|
||||
uint32_t val = target_mem_read32(t, addr);
|
||||
tc_printf(t, "0x%08x: 0x%04x 0x%04x %s\n", addr, val & 0xffff, (val >> 16) & 0xffff,
|
||||
((val & 0xffff) == ((~val >> 16) & 0xffff)) ? "OK" : "ERR");
|
||||
}
|
||||
|
||||
if (stm32lx_is_stm32l1(t)) {
|
||||
uint32_t optr = target_mem_read32(t, STM32Lx_NVM_OPTR(nvm));
|
||||
uint8_t rdprot = (optr >> STM32Lx_NVM_OPTR_RDPROT_S)
|
||||
& STM32Lx_NVM_OPTR_RDPROT_M;
|
||||
if (rdprot == STM32Lx_NVM_OPTR_RDPROT_0)
|
||||
rdprot = 0;
|
||||
else if (rdprot == STM32Lx_NVM_OPTR_RDPROT_2)
|
||||
rdprot = 2;
|
||||
else
|
||||
rdprot = 1;
|
||||
tc_printf(t, "OPTR: 0x%08x, RDPRT %d, SPRMD %d, "
|
||||
"BOR %d, WDG_SW %d, nRST_STP %d, nRST_STBY %d, "
|
||||
"nBFB2 %d\n",
|
||||
optr, rdprot,
|
||||
(optr & STM32L1_NVM_OPTR_SPRMOD) ? 1 : 0,
|
||||
(optr >> STM32L1_NVM_OPTR_BOR_LEV_S)
|
||||
& STM32L1_NVM_OPTR_BOR_LEV_M,
|
||||
(optr & STM32Lx_NVM_OPTR_WDG_SW) ? 1 : 0,
|
||||
(optr & STM32L1_NVM_OPTR_nRST_STOP) ? 1 : 0,
|
||||
(optr & STM32L1_NVM_OPTR_nRST_STDBY) ? 1 : 0,
|
||||
(optr & STM32L1_NVM_OPTR_nBFB2) ? 1 : 0);
|
||||
}
|
||||
else {
|
||||
uint32_t optr = target_mem_read32(t, STM32Lx_NVM_OPTR(nvm));
|
||||
uint8_t rdprot = (optr >> STM32Lx_NVM_OPTR_RDPROT_S)
|
||||
& STM32Lx_NVM_OPTR_RDPROT_M;
|
||||
if (rdprot == STM32Lx_NVM_OPTR_RDPROT_0)
|
||||
rdprot = 0;
|
||||
else if (rdprot == STM32Lx_NVM_OPTR_RDPROT_2)
|
||||
rdprot = 2;
|
||||
else
|
||||
rdprot = 1;
|
||||
tc_printf(t, "OPTR: 0x%08x, RDPROT %d, WPRMOD %d, WDG_SW %d, "
|
||||
"BOOT1 %d\n",
|
||||
optr, rdprot,
|
||||
(optr & STM32L0_NVM_OPTR_WPRMOD) ? 1 : 0,
|
||||
(optr & STM32Lx_NVM_OPTR_WDG_SW) ? 1 : 0,
|
||||
(optr & STM32L0_NVM_OPTR_BOOT1) ? 1 : 0);
|
||||
}
|
||||
if (stm32lx_is_stm32l1(t)) {
|
||||
uint32_t optr = target_mem_read32(t, STM32Lx_NVM_OPTR(nvm));
|
||||
uint8_t rdprot = (optr >> STM32Lx_NVM_OPTR_RDPROT_S) & STM32Lx_NVM_OPTR_RDPROT_M;
|
||||
if (rdprot == STM32Lx_NVM_OPTR_RDPROT_0)
|
||||
rdprot = 0;
|
||||
else if (rdprot == STM32Lx_NVM_OPTR_RDPROT_2)
|
||||
rdprot = 2;
|
||||
else
|
||||
rdprot = 1;
|
||||
tc_printf(t,
|
||||
"OPTR: 0x%08x, RDPRT %d, SPRMD %d, "
|
||||
"BOR %d, WDG_SW %d, nRST_STP %d, nRST_STBY %d, "
|
||||
"nBFB2 %d\n",
|
||||
optr, rdprot, (optr & STM32L1_NVM_OPTR_SPRMOD) ? 1 : 0,
|
||||
(optr >> STM32L1_NVM_OPTR_BOR_LEV_S) & STM32L1_NVM_OPTR_BOR_LEV_M, (optr & STM32Lx_NVM_OPTR_WDG_SW) ? 1 : 0,
|
||||
(optr & STM32L1_NVM_OPTR_nRST_STOP) ? 1 : 0, (optr & STM32L1_NVM_OPTR_nRST_STDBY) ? 1 : 0,
|
||||
(optr & STM32L1_NVM_OPTR_nBFB2) ? 1 : 0);
|
||||
} else {
|
||||
uint32_t optr = target_mem_read32(t, STM32Lx_NVM_OPTR(nvm));
|
||||
uint8_t rdprot = (optr >> STM32Lx_NVM_OPTR_RDPROT_S) & STM32Lx_NVM_OPTR_RDPROT_M;
|
||||
if (rdprot == STM32Lx_NVM_OPTR_RDPROT_0)
|
||||
rdprot = 0;
|
||||
else if (rdprot == STM32Lx_NVM_OPTR_RDPROT_2)
|
||||
rdprot = 2;
|
||||
else
|
||||
rdprot = 1;
|
||||
tc_printf(t,
|
||||
"OPTR: 0x%08x, RDPROT %d, WPRMOD %d, WDG_SW %d, "
|
||||
"BOOT1 %d\n",
|
||||
optr, rdprot, (optr & STM32L0_NVM_OPTR_WPRMOD) ? 1 : 0, (optr & STM32Lx_NVM_OPTR_WDG_SW) ? 1 : 0,
|
||||
(optr & STM32L0_NVM_OPTR_BOOT1) ? 1 : 0);
|
||||
}
|
||||
|
||||
goto done;
|
||||
goto done;
|
||||
|
||||
usage:
|
||||
tc_printf(t, "usage: monitor option [ARGS]\n");
|
||||
tc_printf(t, " show - Show options in NVM and as"
|
||||
" loaded\n");
|
||||
tc_printf(t, " obl_launch - Reload options from NVM\n");
|
||||
tc_printf(t, " write <addr> <value16> - Set option half-word; "
|
||||
"complement computed\n");
|
||||
tc_printf(t, " raw <addr> <value32> - Set option word\n");
|
||||
tc_printf(t, "The value of <addr> must be word aligned and from 0x%08x "
|
||||
"to +0x%x\n",
|
||||
STM32Lx_NVM_OPT_PHYS,
|
||||
STM32Lx_NVM_OPT_PHYS + opt_size - sizeof(uint32_t));
|
||||
tc_printf(t, "usage: monitor option [ARGS]\n");
|
||||
tc_printf(t, " show - Show options in NVM and as"
|
||||
" loaded\n");
|
||||
tc_printf(t, " obl_launch - Reload options from NVM\n");
|
||||
tc_printf(t, " write <addr> <value16> - Set option half-word; "
|
||||
"complement computed\n");
|
||||
tc_printf(t, " raw <addr> <value32> - Set option word\n");
|
||||
tc_printf(t,
|
||||
"The value of <addr> must be word aligned and from 0x%08x "
|
||||
"to +0x%x\n",
|
||||
STM32Lx_NVM_OPT_PHYS, STM32Lx_NVM_OPT_PHYS + opt_size - sizeof(uint32_t));
|
||||
|
||||
done:
|
||||
stm32lx_nvm_lock(t, nvm);
|
||||
return true;
|
||||
stm32lx_nvm_lock(t, nvm);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static bool stm32lx_cmd_eeprom(target* t, int argc, char** argv)
|
||||
static bool stm32lx_cmd_eeprom(target *t, int argc, char **argv)
|
||||
{
|
||||
const uint32_t nvm = stm32lx_nvm_phys(t);
|
||||
const uint32_t nvm = stm32lx_nvm_phys(t);
|
||||
|
||||
if (!stm32lx_nvm_prog_data_unlock(t, nvm)) {
|
||||
tc_printf(t, "unable to unlock EEPROM\n");
|
||||
return true;
|
||||
}
|
||||
if (!stm32lx_nvm_prog_data_unlock(t, nvm)) {
|
||||
tc_printf(t, "unable to unlock EEPROM\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t cb = strlen(argv[1]);
|
||||
size_t cb = strlen(argv[1]);
|
||||
|
||||
if (argc == 4) {
|
||||
uint32_t addr = strtoul(argv[2], NULL, 0);
|
||||
uint32_t val = strtoul(argv[3], NULL, 0);
|
||||
if (argc == 4) {
|
||||
uint32_t addr = strtoul(argv[2], NULL, 0);
|
||||
uint32_t val = strtoul(argv[3], NULL, 0);
|
||||
|
||||
if ( addr < STM32Lx_NVM_EEPROM_PHYS
|
||||
|| addr >= STM32Lx_NVM_EEPROM_PHYS
|
||||
+ stm32lx_nvm_eeprom_size(t))
|
||||
goto usage;
|
||||
if (addr < STM32Lx_NVM_EEPROM_PHYS || addr >= STM32Lx_NVM_EEPROM_PHYS + stm32lx_nvm_eeprom_size(t))
|
||||
goto usage;
|
||||
|
||||
if (!strncasecmp(argv[1], "byte", cb)) {
|
||||
tc_printf(t, "write byte 0x%08x <- 0x%08x\n", addr, val);
|
||||
if (!stm32lx_eeprom_write(t, addr, 1, val))
|
||||
tc_printf(t, "eeprom write failed\n");
|
||||
} else if (!strncasecmp(argv[1], "halfword", cb)) {
|
||||
val &= 0xffff;
|
||||
tc_printf(t, "write halfword 0x%08x <- 0x%04x\n",
|
||||
addr, val);
|
||||
if (addr & 1)
|
||||
goto usage;
|
||||
if (!stm32lx_eeprom_write(t, addr, 2, val))
|
||||
tc_printf(t, "eeprom write failed\n");
|
||||
} else if (!strncasecmp(argv[1], "word", cb)) {
|
||||
tc_printf(t, "write word 0x%08x <- 0x%08x\n", addr, val);
|
||||
if (addr & 3)
|
||||
goto usage;
|
||||
if (!stm32lx_eeprom_write(t, addr, 4, val))
|
||||
tc_printf(t, "eeprom write failed\n");
|
||||
}
|
||||
else
|
||||
goto usage;
|
||||
}
|
||||
else
|
||||
goto usage;
|
||||
if (!strncasecmp(argv[1], "byte", cb)) {
|
||||
tc_printf(t, "write byte 0x%08x <- 0x%08x\n", addr, val);
|
||||
if (!stm32lx_eeprom_write(t, addr, 1, val))
|
||||
tc_printf(t, "eeprom write failed\n");
|
||||
} else if (!strncasecmp(argv[1], "halfword", cb)) {
|
||||
val &= 0xffff;
|
||||
tc_printf(t, "write halfword 0x%08x <- 0x%04x\n", addr, val);
|
||||
if (addr & 1)
|
||||
goto usage;
|
||||
if (!stm32lx_eeprom_write(t, addr, 2, val))
|
||||
tc_printf(t, "eeprom write failed\n");
|
||||
} else if (!strncasecmp(argv[1], "word", cb)) {
|
||||
tc_printf(t, "write word 0x%08x <- 0x%08x\n", addr, val);
|
||||
if (addr & 3)
|
||||
goto usage;
|
||||
if (!stm32lx_eeprom_write(t, addr, 4, val))
|
||||
tc_printf(t, "eeprom write failed\n");
|
||||
} else
|
||||
goto usage;
|
||||
} else
|
||||
goto usage;
|
||||
|
||||
goto done;
|
||||
goto done;
|
||||
|
||||
usage:
|
||||
tc_printf(t, "usage: monitor eeprom [ARGS]\n");
|
||||
tc_printf(t, " byte <addr> <value8> - Write a byte\n");
|
||||
tc_printf(t, " halfword <addr> <value16> - Write a half-word\n");
|
||||
tc_printf(t, " word <addr> <value32> - Write a word\n");
|
||||
tc_printf(t, "The value of <addr> must in the interval [0x%08x, 0x%x)\n",
|
||||
STM32Lx_NVM_EEPROM_PHYS,
|
||||
STM32Lx_NVM_EEPROM_PHYS + stm32lx_nvm_eeprom_size(t));
|
||||
tc_printf(t, "usage: monitor eeprom [ARGS]\n");
|
||||
tc_printf(t, " byte <addr> <value8> - Write a byte\n");
|
||||
tc_printf(t, " halfword <addr> <value16> - Write a half-word\n");
|
||||
tc_printf(t, " word <addr> <value32> - Write a word\n");
|
||||
tc_printf(t, "The value of <addr> must in the interval [0x%08x, 0x%x)\n", STM32Lx_NVM_EEPROM_PHYS,
|
||||
STM32Lx_NVM_EEPROM_PHYS + stm32lx_nvm_eeprom_size(t));
|
||||
|
||||
done:
|
||||
stm32lx_nvm_lock(t, nvm);
|
||||
return true;
|
||||
stm32lx_nvm_lock(t, nvm);
|
||||
return true;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue