#include "imp.h"
#include <helper/binarybuffer.h>
#include <target/algorithm.h>
-#include <target/armv7m.h>
+#include <target/cortex_m.h>
/* Regarding performance:
*
* can be very different.
*
* To reduce testing complexity and dangers of regressions,
- * a seperate file is used for stm32fx2x.
+ * a separate file is used for stm32fx2x.
*
* Sector sizes in kiBytes:
* 1 MiByte part with 4 x 16, 1 x 64, 7 x 128.
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 */
+ unsigned int protection_bits; /* F413/423 */
uint32_t user_bank_size;
};
retval = stm32x_get_flash_status(bank, &status);
if (retval != ERROR_OK)
return retval;
- LOG_DEBUG("status: 0x%" PRIx32 "", status);
+ LOG_DEBUG("status: 0x%" PRIx32, status);
if ((status & FLASH_BSY) == 0)
break;
if (timeout-- <= 0) {
return retval;
if (ctrl & FLASH_LOCK) {
- LOG_ERROR("flash not unlocked STM32_FLASH_CR: %" PRIx32, ctrl);
+ LOG_ERROR("flash not unlocked STM32_FLASH_CR: 0x%" PRIx32, ctrl);
return ERROR_TARGET_FAILURE;
}
return retval;
if (ctrl & OPTCR_LOCK) {
- LOG_ERROR("options not unlocked STM32_FLASH_OPTCR: %" PRIx32, ctrl);
+ LOG_ERROR("options not unlocked STM32_FLASH_OPTCR: 0x%" PRIx32, ctrl);
return ERROR_TARGET_FAILURE;
}
if (retval != ERROR_OK)
return retval;
- /* FLASH_OPTCR1 has quite diffent meanings ... */
+ /* FLASH_OPTCR1 has quite different meanings ... */
if (stm32x_info->has_boot_addr) {
/* for F7xx it contains boot0 and boot1 */
stm32x_info->option_bytes.boot_addr = optiondata;
{
struct stm32x_flash_bank *stm32x_info = bank->driver_priv;
struct flash_sector *prot_blocks;
- int num_prot_blocks;
+ unsigned int num_prot_blocks;
int retval;
/* if it's the OTP bank, look at the lock bits there */
prot_blocks = bank->sectors;
}
- for (int i = 0; i < num_prot_blocks; i++)
+ for (unsigned int i = 0; i < num_prot_blocks; i++)
prot_blocks[i].is_protected =
~(stm32x_info->option_bytes.protection >> i) & 1;
retval = stm32x_wait_status_busy(bank, FLASH_ERASE_TIMEOUT);
if (retval != ERROR_OK)
return retval;
-
- bank->sectors[i].is_erased = 1;
}
retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR), FLASH_LOCK);
LOG_ERROR("flash memory write protected");
if (error != 0) {
- LOG_ERROR("flash write failed = %08" PRIx32, error);
+ LOG_ERROR("flash write failed = 0x%08" PRIx32, error);
/* Clear but report errors */
target_write_u32(target, STM32_FLASH_SR, error);
retval = ERROR_FAIL;
bank->sectors[i].offset = bank->size;
bank->sectors[i].size = size;
bank->size += bank->sectors[i].size;
- LOG_DEBUG("sector %d: %dkBytes", i, size >> 10);
+ LOG_DEBUG("sector %u: %ukBytes", i, size >> 10);
}
-static uint16_t sector_size_in_kb(int i, uint16_t max_sector_size_in_kb)
+static uint16_t sector_size_in_kb(unsigned int i, uint16_t max_sector_size_in_kb)
{
- assert(i >= 0);
if (i < 4)
return max_sector_size_in_kb / 8;
if (i == 4)
return max_sector_size_in_kb;
}
-static int calculate_number_of_sectors(struct flash_bank *bank,
+static unsigned int calculate_number_of_sectors(struct flash_bank *bank,
uint16_t flash_size_in_kb,
uint16_t max_sector_size_in_kb)
{
struct stm32x_flash_bank *stm32x_info = bank->driver_priv;
uint16_t remaining_flash_size_in_kb = flash_size_in_kb;
- int nr_sectors;
+ unsigned int nr_sectors;
/* Dual Bank Flash has two identically-arranged banks of sectors. */
if (stm32x_info->has_large_mem)
return stm32x_info->has_large_mem ? nr_sectors*2 : nr_sectors;
}
-static void setup_bank(struct flash_bank *bank, int start,
+static void setup_bank(struct flash_bank *bank, unsigned int start,
uint16_t flash_size_in_kb, uint16_t max_sector_size_in_kb)
{
uint16_t remaining_flash_size_in_kb = flash_size_in_kb;
- int sector_index = 0;
+ unsigned int sector_index = 0;
while (remaining_flash_size_in_kb > 0) {
uint16_t size_in_kb = sector_size_in_kb(sector_index, max_sector_size_in_kb);
if (size_in_kb > remaining_flash_size_in_kb) {
* Only effects Rev A silicon */
struct target *target = bank->target;
- uint32_t cpuid;
+ struct cortex_m_common *cortex_m = target_to_cm(target);
/* read stm32 device id register */
int retval = target_read_u32(target, 0xE0042000, device_id);
if (retval != ERROR_OK)
return retval;
- if ((*device_id & 0xfff) == 0x411) {
- /* read CPUID reg to check core type */
- retval = target_read_u32(target, 0xE000ED00, &cpuid);
- if (retval != ERROR_OK)
- return retval;
-
- /* check for cortex_m4 */
- if (((cpuid >> 4) & 0xFFF) == 0xC24) {
- *device_id &= ~((0xFFFF << 16) | 0xfff);
- *device_id |= (0x1000 << 16) | 0x413;
- LOG_INFO("stm32f4x errata detected - fixing incorrect MCU_IDCODE");
- }
+ if ((*device_id & 0xfff) == 0x411 && cortex_m->core_info->partno == CORTEX_M4_PARTNO) {
+ *device_id &= ~((0xFFFF << 16) | 0xfff);
+ *device_id |= (0x1000 << 16) | 0x413;
+ LOG_INFO("stm32f4x errata detected - fixing incorrect MCU_IDCODE");
}
return retval;
}
{
struct target *target = bank->target;
struct stm32x_flash_bank *stm32x_info = bank->driver_priv;
- int i, num_prot_blocks, num_sectors;
+ unsigned int num_prot_blocks, num_sectors;
uint16_t flash_size_in_kb;
uint16_t otp_size_in_b;
uint16_t otp_sector_size;
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;
- }
+ 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;
- }
+ free(bank->prot_blocks);
+ bank->num_prot_blocks = 0;
+ bank->prot_blocks = NULL;
- /* if explicitely called out as OTP bank, short circuit probe */
+ /* if explicitly called out as OTP bank, short circuit probe */
if (stm32x_is_otp(bank)) {
if (stm32x_otp_is_f7(bank)) {
otp_size_in_b = STM32F7_OTP_SIZE;
}
num_sectors = otp_size_in_b / otp_sector_size;
- LOG_INFO("flash size = %d bytes", otp_size_in_b);
+ LOG_INFO("flash size = %" PRIu16 " bytes", otp_size_in_b);
assert(num_sectors > 0);
else
bank->size = STM32F2_OTP_SIZE;
- for (i = 0; i < num_sectors; i++) {
+ for (unsigned int i = 0; i < num_sectors; i++) {
bank->sectors[i].offset = i * otp_sector_size;
bank->sectors[i].size = otp_sector_size;
bank->sectors[i].is_erased = 1;
int retval = stm32x_get_device_id(bank, &device_id);
if (retval != ERROR_OK)
return retval;
- LOG_INFO("device id = 0x%08" PRIx32 "", device_id);
+ 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 */
/* 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) {
- LOG_WARNING("STM32 flash size failed, probe inaccurate - assuming %dk flash",
+ LOG_WARNING("STM32 flash size failed, probe inaccurate - assuming %" PRIu16 "k flash",
max_flash_size_in_kb);
flash_size_in_kb = max_flash_size_in_kb;
}
flash_size_in_kb = stm32x_info->user_bank_size / 1024;
}
- LOG_INFO("flash size = %d kbytes", flash_size_in_kb);
+ LOG_INFO("flash size = %" PRIu16 " kbytes", flash_size_in_kb);
/* did we assign flash size? */
assert(flash_size_in_kb != 0xffff);
}
if ((flash_size_in_kb > 1024) || (optiondata & OPTCR_DB1M)) {
stm32x_info->has_large_mem = true;
- LOG_INFO("Dual Bank %d kiB STM32F42x/43x/469/479 found", flash_size_in_kb);
+ LOG_INFO("Dual Bank %" PRIu16 " kiB STM32F42x/43x/469/479 found", flash_size_in_kb);
} else {
stm32x_info->has_large_mem = false;
- LOG_INFO("Single Bank %d kiB STM32F42x/43x/469/479 found", flash_size_in_kb);
+ LOG_INFO("Single Bank %" PRIu16 " kiB STM32F42x/43x/469/479 found", flash_size_in_kb);
}
}
}
if (optiondata & OPTCR_NDBANK) {
stm32x_info->has_large_mem = false;
- LOG_INFO("Single Bank %d kiB STM32F76x/77x found", flash_size_in_kb);
+ LOG_INFO("Single Bank %" PRIu16 " kiB STM32F76x/77x found", flash_size_in_kb);
} else {
stm32x_info->has_large_mem = true;
max_sector_size_in_kb >>= 1; /* sector size divided by 2 in dual-bank mode */
- LOG_INFO("Dual Bank %d kiB STM32F76x/77x found", flash_size_in_kb);
+ LOG_INFO("Dual Bank %" PRIu16 " kiB STM32F76x/77x found", flash_size_in_kb);
}
}
/* calculate numbers of pages */
- int num_pages = calculate_number_of_sectors(
+ unsigned int num_pages = calculate_number_of_sectors(
bank, flash_size_in_kb, max_sector_size_in_kb);
bank->base = base_address;
bank->num_sectors = num_pages;
bank->sectors = calloc(num_pages, sizeof(struct flash_sector));
- for (i = 0; i < num_pages; i++) {
+ for (unsigned int i = 0; i < num_pages; i++) {
bank->sectors[i].is_erased = -1;
bank->sectors[i].is_protected = 0;
}
bank->size = 0;
- LOG_DEBUG("allocated %d sectors", num_pages);
+ LOG_DEBUG("allocated %u sectors", num_pages);
/* F76x/77x in dual bank mode */
if ((device_id == 0x451) && stm32x_info->has_large_mem)
if (num_prot_blocks) {
bank->prot_blocks = malloc(sizeof(struct flash_sector) * num_prot_blocks);
- for (i = 0; i < num_prot_blocks; i++)
+ for (unsigned int i = 0; i < num_prot_blocks; i++)
bank->prot_blocks[i].is_protected = 0;
- LOG_DEBUG("allocated %d prot blocks", num_prot_blocks);
+ LOG_DEBUG("allocated %u prot blocks", num_prot_blocks);
}
if (stm32x_info->has_large_mem) {
/* 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++) {
+ for (unsigned int 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
+ bank->sectors[(i << 1) + 1].size;
/* F413/F423, sectors 14 and 15 share one common protection bit */
if (device_id == 0x463) {
- for (i = 0; i < num_prot_blocks; i++) {
+ for (unsigned int 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;
}
return stm32x_probe(bank);
}
-static int get_stm32x_info(struct flash_bank *bank, char *buf, int buf_size)
+static int get_stm32x_info(struct flash_bank *bank, struct command_invocation *cmd)
{
uint32_t dbgmcu_idcode;
break;
default:
- snprintf(buf, buf_size, "Cannot identify target as a STM32F2/4/7\n");
+ command_print_sameline(cmd, "Cannot identify target as a STM32F2/4/7\n");
return ERROR_FAIL;
}
- if (rev_str != NULL)
- snprintf(buf, buf_size, "%s - Rev: %s", device_str, rev_str);
+ if (rev_str)
+ command_print_sameline(cmd, "%s - Rev: %s", device_str, rev_str);
else
- snprintf(buf, buf_size, "%s - Rev: unknown (0x%04x)", device_str, rev_id);
+ command_print_sameline(cmd, "%s - Rev: unknown (0x%04" PRIx16 ")", device_str, rev_id);
return ERROR_OK;
}
struct flash_bank *bank;
int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
- if (ERROR_OK != retval)
+ if (retval != ERROR_OK)
return retval;
stm32x_info = bank->driver_priv;
struct flash_bank *bank;
int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
- if (ERROR_OK != retval)
+ if (retval != ERROR_OK)
return retval;
stm32x_info = bank->driver_priv;
struct flash_bank *bank;
int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
- if (ERROR_OK != retval)
+ if (retval != ERROR_OK)
return retval;
retval = stm32x_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;
-
command_print(CMD, "stm32x mass erase complete");
} else {
command_print(CMD, "stm32x mass erase failed");
}
retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
- if (ERROR_OK != retval)
+ if (retval != ERROR_OK)
return retval;
retval = stm32x_read_options(bank);
- if (ERROR_OK != retval)
+ if (retval != ERROR_OK)
return retval;
stm32x_info = bank->driver_priv;
if (stm32x_info->has_boot_addr) {
uint32_t boot_addr = stm32x_info->option_bytes.boot_addr;
- command_print(CMD, "stm32f2x user_options 0x%03X,"
- " boot_add0 0x%04X, boot_add1 0x%04X",
+ command_print(CMD, "stm32f2x user_options 0x%03" PRIX16 ","
+ " boot_add0 0x%04" PRIX32 ", boot_add1 0x%04" PRIX32,
stm32x_info->option_bytes.user_options,
boot_addr & 0xffff, (boot_addr & 0xffff0000) >> 16);
if (stm32x_info->has_optcr2_pcrop) {
- command_print(CMD, "stm32f2x optcr2_pcrop 0x%08X",
+ command_print(CMD, "stm32f2x optcr2_pcrop 0x%08" PRIX32,
stm32x_info->option_bytes.optcr2_pcrop);
}
} else {
- command_print(CMD, "stm32f2x user_options 0x%03X",
+ command_print(CMD, "stm32f2x user_options 0x%03" PRIX16,
stm32x_info->option_bytes.user_options);
}
} else {
- command_print(CMD, "stm32f2x user_options 0x%02X",
+ command_print(CMD, "stm32f2x user_options 0x%02" PRIX16,
stm32x_info->option_bytes.user_options);
}
}
retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
- if (ERROR_OK != retval)
+ if (retval != ERROR_OK)
return retval;
retval = stm32x_read_options(bank);
- if (ERROR_OK != retval)
+ if (retval != ERROR_OK)
return retval;
stm32x_info = bank->driver_priv;
}
retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
- if (ERROR_OK != retval)
+ if (retval != ERROR_OK)
return retval;
stm32x_info = bank->driver_priv;
" finally unlock it. Clears PCROP and mass erases flash.");
retval = stm32x_read_options(bank);
- if (ERROR_OK != retval)
+ if (retval != ERROR_OK)
return retval;
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], optcr2_pcrop);
struct flash_bank *bank;
int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
- if (ERROR_OK != retval)
+ if (retval != ERROR_OK)
return retval;
if (stm32x_is_otp(bank)) {
if (strcmp(CMD_ARGV[1], "enable") == 0) {
stm32x_otp_disable(bank);
} else if (strcmp(CMD_ARGV[1], "show") == 0) {
command_print(CMD,
- "OTP memory bank #%d is %s for write commands.",
+ "OTP memory bank #%u is %s for write commands.",
bank->bank_number,
stm32x_is_otp_unlocked(bank) ? "enabled" : "disabled");
} else {