Merge pull request #948 from fabalthazar/STM32G0-OTP

STM32G0 OTP area programming and hosted monitor command allowed as preliminary action
This commit is contained in:
UweBonnes 2021-11-16 14:23:20 +01:00 committed by GitHub
commit efa889156f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 36 additions and 13 deletions

View File

@ -290,7 +290,6 @@ void cl_init(BMP_CL_OPTIONS_t *opt, int argc, char **argv)
opt->opt_targetid = strtol(optarg, NULL, 0);
break;
case 'M':
opt->opt_mode = BMP_MODE_MONITOR;
if (optarg)
opt->opt_monitor = optarg;
break;
@ -321,7 +320,11 @@ void cl_init(BMP_CL_OPTIONS_t *opt, int argc, char **argv)
if (opt->opt_mode == BMP_MODE_DEBUG)
opt->opt_mode = BMP_MODE_FLASH_WRITE;
opt->opt_flash_file = argv[optind];
} else if ((opt->opt_mode == BMP_MODE_DEBUG) &&
(opt->opt_monitor)) {
opt->opt_mode = BMP_MODE_MONITOR; // To avoid DEBUG mode
}
/* Checks */
if ((opt->opt_flash_file) && ((opt->opt_mode == BMP_MODE_TEST ) ||
(opt->opt_mode == BMP_MODE_SWJ_TEST) ||
@ -448,10 +451,6 @@ int cl_execute(BMP_CL_OPTIONS_t *opt)
default:
DEBUG_WARN("No test for this core type yet\n");
}
} else if (opt->opt_mode == BMP_MODE_MONITOR) {
res = command_process(t, opt->opt_monitor);
if (res)
DEBUG_WARN("Command \"%s\" failed\n", opt->opt_monitor);
}
if ((opt->opt_mode == BMP_MODE_TEST) ||
(opt->opt_mode == BMP_MODE_SWJ_TEST))
@ -480,9 +479,14 @@ int cl_execute(BMP_CL_OPTIONS_t *opt)
if (opt->opt_flash_size < map.size)
/* restrict to size given on command line */
map.size = opt->opt_flash_size;
if (opt->opt_monitor) {
res = command_process(t, opt->opt_monitor);
if (res)
DEBUG_WARN("Command \"%s\" failed\n", opt->opt_monitor);
}
if (opt->opt_mode == BMP_MODE_RESET) {
target_reset(t);
} else if (opt->opt_mode == BMP_MODE_FLASH_ERASE) {
} else if (opt->opt_mode == BMP_MODE_FLASH_ERASE) {
DEBUG_INFO("Erase %zu bytes at 0x%08" PRIx32 "\n", opt->opt_flash_size,
opt->opt_flash_start);
unsigned int erased = target_flash_erase(t, opt->opt_flash_start,
@ -510,6 +514,8 @@ int cl_execute(BMP_CL_OPTIONS_t *opt)
unsigned int flashed = target_flash_write(t, opt->opt_flash_start,
map.data, map.size);
/* Buffered write cares for padding*/
if (!flashed)
flashed = target_flash_done(t);
if (flashed) {
DEBUG_WARN("Flashing failed!\n");
res = -1;
@ -518,7 +524,6 @@ int cl_execute(BMP_CL_OPTIONS_t *opt)
DEBUG_INFO("Success!\n");
}
}
target_flash_done(t);
uint32_t end_time = platform_time_ms();
DEBUG_WARN("Flash Write succeeded for %d bytes, %8.3f kiB/s\n",
(int)map.size, (((map.size * 1.0)/(end_time - start_time))));

View File

@ -52,6 +52,9 @@
#define FLASH_MEMORY_SIZE 0x1FFF75E0
#define FLASH_PAGE_SIZE 0x800
#define FLASH_BANK2_START_PAGE_NB 256U
#define FLASH_OTP_START 0x1FFF7000
#define FLASH_OTP_SIZE 0x400
#define FLASH_OTP_BLOCKSIZE 0x8
#define FLASH_SIZE_MAX_G03_4 (64U * 1024U) // 64 kiB
#define FLASH_SIZE_MAX_G05_6 (64U * 1024U) // 64 kiB
#define FLASH_SIZE_MAX_G07_8 (128U * 1024U) // 128 kiB
@ -189,7 +192,7 @@ static void stm32g0_add_flash(target *t, uint32_t addr, size_t length,
f->blocksize = blocksize;
f->erase = stm32g0_flash_erase;
f->write = stm32g0_flash_write;
f->buf_size = FLASH_PAGE_SIZE;
f->buf_size = blocksize;
f->erased = 0xFF;
target_add_flash(t, f);
}
@ -249,6 +252,9 @@ bool stm32g0_probe(target *t)
priv_storage->irreversible_enabled = false;
t->target_storage = (void*)priv_storage;
/* OTP Flash area */
stm32g0_add_flash(t, FLASH_OTP_START, FLASH_OTP_SIZE, FLASH_OTP_BLOCKSIZE);
return true;
}
@ -311,6 +317,7 @@ static void stm32g0_flash_lock(target *t)
/*
* Flash erasure function.
* OTP case: this function clears any previous error and returns.
*/
static int stm32g0_flash_erase(struct target_flash *f, target_addr addr,
size_t len)
@ -328,11 +335,6 @@ static int stm32g0_flash_erase(struct target_flash *f, target_addr addr,
if (len == (size_t)0U)
goto exit_cleanup;
nb_pages_to_erase = (uint16_t)((len - 1U) / f->blocksize) + 1U;
if (t->idcode == STM32G0B_C) // Dual-bank devices
bank1_end_page_nb = ((f->length / 2U) - 1U) / f->blocksize;
page_nb = (uint16_t)((addr - f->start) / f->blocksize);
/* Wait for Flash ready */
while (target_mem_read32(t, FLASH_SR) & FLASH_SR_BSY_MASK) {
if (target_check_error(t))
@ -342,6 +344,14 @@ static int stm32g0_flash_erase(struct target_flash *f, target_addr addr,
/* Clear any previous programming error */
target_mem_write32(t, FLASH_SR, target_mem_read32(t, FLASH_SR));
if (addr >= (target_addr)FLASH_OTP_START)
goto exit_cleanup;
nb_pages_to_erase = (uint16_t)((len - 1U) / f->blocksize) + 1U;
if (t->idcode == STM32G0B_C) // Dual-bank devices
bank1_end_page_nb = ((f->length / 2U) - 1U) / f->blocksize;
page_nb = (uint16_t)((addr - f->start) / f->blocksize);
stm32g0_flash_unlock(t);
do {
@ -392,12 +402,20 @@ exit_cleanup:
* The SR is supposed to be ready and free of any error.
* After a successful programming, the EMPTY bit is cleared to allow rebooting
* in Main Flash memory without power cycle.
* OTP area is programmed as the "program" area. It can be programmed 8-bytes
* by 8-bytes.
*/
static int stm32g0_flash_write(struct target_flash *f, target_addr dest,
const void *src, size_t len)
{
target *t = f->t;
int ret = 0;
struct stm32g0_priv_s *ps = (struct stm32g0_priv_s*)t->target_storage;
if ((dest >= (target_addr)FLASH_OTP_START) && !ps->irreversible_enabled) {
tc_printf(t, "Irreversible operations disabled\n");
goto exit_error;
}
stm32g0_flash_unlock(t);