+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
* *
* Copyright (C) 2011 by Clement Burin des Roziers *
* clement.burin-des-roziers@hikob.com *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
{ 0x1000, "A" }, { 0x1008, "Z" }, { 0x1018, "Y" }, { 0x1038, "X" }
};
static const struct stm32lx_rev stm32_425_revs[] = {
- { 0x1000, "A" }, { 0x2000, "B" }, { 0x2008, "Y" },
+ { 0x1000, "A" }, { 0x2000, "B" }, { 0x2008, "Y" }, { 0x2018, "1, X" },
};
static const struct stm32lx_rev stm32_427_revs[] = {
{ 0x1000, "A" }, { 0x1018, "Y" }, { 0x1038, "X" }, { 0x10f8, "V" },
{ 0x1000, "A" }, { 0x1018, "Z" },
};
static const struct stm32lx_rev stm32_436_revs[] = {
- { 0x1000, "A" }, { 0x1008, "Z" }, { 0x1018, "Y" },
+ { 0x1000, "A" }, { 0x1008, "Z" }, { 0x1018, "Y" }, { 0x1038, "X" },
};
static const struct stm32lx_rev stm32_437_revs[] = {
{ 0x1000, "A" },
return retval;
retval = stm32lx_mass_erase(bank);
- if (retval == ERROR_OK) {
- /* set all sectors as erased */
- for (unsigned int i = 0; i < bank->num_sectors; i++)
- bank->sectors[i].is_erased = 1;
-
+ if (retval == ERROR_OK)
command_print(CMD, "stm32lx mass erase complete");
- } else {
+ else
command_print(CMD, "stm32lx mass erase failed");
- }
return retval;
}
struct stm32lx_flash_bank *stm32lx_info = bank->driver_priv;
uint32_t hp_nb = stm32lx_info->part_info.page_size / 2;
- uint32_t buffer_size = 16384;
+ uint32_t buffer_size = (16384 / hp_nb) * hp_nb; /* must be multiple of hp_nb */
struct working_area *write_algorithm;
struct working_area *source;
uint32_t address = bank->base + offset;
- struct reg_param reg_params[3];
+ struct reg_param reg_params[5];
struct armv7m_algorithm armv7m_info;
int retval = ERROR_OK;
};
/* Make sure we're performing a half-page aligned write. */
+ if (offset % hp_nb) {
+ LOG_ERROR("The offset must be %" PRIu32 "B-aligned but it is %" PRIi32 "B)", hp_nb, offset);
+ return ERROR_FAIL;
+ }
if (count % hp_nb) {
LOG_ERROR("The byte count must be %" PRIu32 "B-aligned but count is %" PRIu32 "B)", hp_nb, count);
return ERROR_FAIL;
LOG_WARNING("no large enough working area available, can't do block memory writes");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+ } else {
+ /* Make sure we're still asking for an integral number of half-pages */
+ buffer_size -= buffer_size % hp_nb;
}
}
init_reg_param(®_params[0], "r0", 32, PARAM_OUT);
init_reg_param(®_params[1], "r1", 32, PARAM_OUT);
init_reg_param(®_params[2], "r2", 32, PARAM_OUT);
+ init_reg_param(®_params[3], "r3", 32, PARAM_OUT);
+ init_reg_param(®_params[4], "r4", 32, PARAM_OUT);
/* Enable half-page write */
retval = stm32lx_enable_write_half_page(bank);
destroy_reg_param(®_params[0]);
destroy_reg_param(®_params[1]);
destroy_reg_param(®_params[2]);
+ destroy_reg_param(®_params[3]);
+ destroy_reg_param(®_params[4]);
return retval;
}
buf_set_u32(reg_params[0].value, 0, 32, address);
/* The source address of the copy (R1) */
buf_set_u32(reg_params[1].value, 0, 32, source->address);
- /* The length of the copy (R2) */
- buf_set_u32(reg_params[2].value, 0, 32, this_count / 4);
+ /* The number of half pages to copy (R2) */
+ buf_set_u32(reg_params[2].value, 0, 32, this_count / hp_nb);
+ /* The size in byes of a half page (R3) */
+ buf_set_u32(reg_params[3].value, 0, 32, hp_nb);
+ /* The flash base address (R4) */
+ buf_set_u32(reg_params[4].value, 0, 32, stm32lx_info->flash_base);
/* 5: Execute the bunch of code */
retval = target_run_algorithm(target, 0, NULL,
destroy_reg_param(®_params[0]);
destroy_reg_param(®_params[1]);
destroy_reg_param(®_params[2]);
+ destroy_reg_param(®_params[3]);
+ destroy_reg_param(®_params[4]);
return retval;
}