#include "imp.h"
#include <helper/binarybuffer.h>
#include <target/algorithm.h>
-#include <target/armv7m.h>
+#include <target/cortex_m.h>
/* stm32x register locations */
uint32_t protection;
int retval = stm32x_check_operation_supported(bank);
- if (ERROR_OK != retval)
+ if (retval != ERROR_OK)
return retval;
/* medium density - each bit refers to a 4 sector protection block
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);
* discrete accesses. */
if (count & 1) {
new_buffer = malloc(count + 1);
- if (new_buffer == NULL) {
+ if (!new_buffer) {
LOG_ERROR("odd number of bytes to write and no memory for padding buffer");
return ERROR_FAIL;
}
static int stm32x_get_device_id(struct flash_bank *bank, uint32_t *device_id)
{
- /* This check the device CPUID core register to detect
- * the M0 from the M3 devices. */
-
struct target *target = bank->target;
- uint32_t cpuid, device_id_register = 0;
+ struct cortex_m_common *cortex_m = target_to_cm(target);
+ uint32_t device_id_register = 0;
- /* Get the CPUID from the ARM Core
- * http://infocenter.arm.com/help/topic/com.arm.doc.ddi0432c/DDI0432C_cortex_m0_r0p0_trm.pdf 4.2.1 */
- int retval = target_read_u32(target, 0xE000ED00, &cpuid);
- if (retval != ERROR_OK)
- return retval;
+ if (!target_was_examined(target)) {
+ LOG_ERROR("Target not examined yet");
+ return ERROR_FAIL;
+ }
- if (((cpuid >> 4) & 0xFFF) == 0xC20) {
- /* 0xC20 is M0 devices */
+ switch (cortex_m->core_info->partno) {
+ case CORTEX_M0_PARTNO: /* STM32F0x devices */
device_id_register = 0x40015800;
- } else if (((cpuid >> 4) & 0xFFF) == 0xC23) {
- /* 0xC23 is M3 devices */
+ break;
+ case CORTEX_M3_PARTNO: /* STM32F1x devices */
device_id_register = 0xE0042000;
- } else if (((cpuid >> 4) & 0xFFF) == 0xC24) {
- /* 0xC24 is M4 devices */
+ break;
+ case CORTEX_M4_PARTNO: /* STM32F3x devices */
device_id_register = 0xE0042000;
- } else {
+ break;
+ case CORTEX_M23_PARTNO: /* GD32E23x devices */
+ device_id_register = 0x40015800;
+ break;
+ default:
LOG_ERROR("Cannot identify target as a stm32x");
return ERROR_FAIL;
}
/* read stm32 device id register */
- retval = target_read_u32(target, device_id_register, device_id);
+ int retval = target_read_u32(target, device_id_register, device_id);
if (retval != ERROR_OK)
return retval;
static int stm32x_get_flash_size(struct flash_bank *bank, uint16_t *flash_size_in_kb)
{
struct target *target = bank->target;
- uint32_t cpuid, flash_size_reg;
+ struct cortex_m_common *cortex_m = target_to_cm(target);
+ uint32_t flash_size_reg;
- int retval = target_read_u32(target, 0xE000ED00, &cpuid);
- if (retval != ERROR_OK)
- return retval;
+ if (!target_was_examined(target)) {
+ LOG_ERROR("Target not examined yet");
+ return ERROR_FAIL;
+ }
- if (((cpuid >> 4) & 0xFFF) == 0xC20) {
- /* 0xC20 is M0 devices */
+ switch (cortex_m->core_info->partno) {
+ case CORTEX_M0_PARTNO: /* STM32F0x devices */
flash_size_reg = 0x1FFFF7CC;
- } else if (((cpuid >> 4) & 0xFFF) == 0xC23) {
- /* 0xC23 is M3 devices */
+ break;
+ case CORTEX_M3_PARTNO: /* STM32F1x devices */
flash_size_reg = 0x1FFFF7E0;
- } else if (((cpuid >> 4) & 0xFFF) == 0xC24) {
- /* 0xC24 is M4 devices */
+ break;
+ case CORTEX_M4_PARTNO: /* STM32F3x devices */
flash_size_reg = 0x1FFFF7CC;
- } else {
+ break;
+ case CORTEX_M23_PARTNO: /* GD32E23x devices */
+ flash_size_reg = 0x1FFFF7E0;
+ break;
+ default:
LOG_ERROR("Cannot identify target as a stm32x");
return ERROR_FAIL;
}
- retval = target_read_u16(target, flash_size_reg, flash_size_in_kb);
+ int retval = target_read_u16(target, flash_size_reg, flash_size_in_kb);
if (retval != ERROR_OK)
return retval;
page_size = 1024;
stm32x_info->ppage_size = 4;
max_flash_size_in_kb = 128;
- /* GigaDevice GD32F1x0 & GD32F3x0 series devices share DEV_ID
- with STM32F101/2/3 medium-density line,
+ /* GigaDevice GD32F1x0 & GD32F3x0 & GD32E23x series devices
+ share DEV_ID with STM32F101/2/3 medium-density line,
however they use a REV_ID different from any STM32 device.
The main difference is another offset of user option bits
(like WDG_SW, nRST_STOP, nRST_STDBY) in option byte register
stm32x_info->user_data_offset = 16;
stm32x_info->option_offset = 6;
break;
+ case 0x1909: /* gd32e23x */
+ stm32x_info->user_data_offset = 16;
+ stm32x_info->option_offset = 6;
+ max_flash_size_in_kb = 64;
+ break;
}
break;
case 0x412: /* stm32f1x low-density */
return rev_str;
}
-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;
- /* read stm32 device id register */
+ /* read stm32 device id register */
int retval = stm32x_get_device_id(bank, &dbgmcu_idcode);
if (retval != ERROR_OK)
return retval;
device_str = "GD32F3x0";
break;
+ case 0x1909: /* gd32e23x */
+ device_str = "GD32E23x";
+ break;
+
case 0x2000:
rev_str = "B";
break;
break;
default:
- snprintf(buf, buf_size, "Cannot identify target as a STM32F0/1/3\n");
+ command_print_sameline(cmd, "Cannot identify target as a STM32F0/1/3\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%04x)", 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;
}
retval = stm32x_check_operation_supported(bank);
- if (ERROR_OK != retval)
+ if (retval != ERROR_OK)
return retval;
if (stm32x_erase_options(bank) != 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;
target = bank->target;
}
retval = stm32x_check_operation_supported(bank);
- if (ERROR_OK != retval)
+ if (retval != ERROR_OK)
return retval;
if (stm32x_erase_options(bank) != 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;
}
retval = stm32x_check_operation_supported(bank);
- if (ERROR_OK != retval)
+ if (retval != ERROR_OK)
return retval;
retval = target_read_u32(target, STM32_FLASH_OBR_B0, &optionbyte);
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;
}
retval = stm32x_check_operation_supported(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;
/* start with current options */
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;
struct stm32x_flash_bank *stm32x_info = bank->driver_priv;
}
retval = stm32x_check_operation_supported(bank);
- if (ERROR_OK != retval)
+ if (retval != ERROR_OK)
return retval;
/* unlock option flash registers */
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;
-
+ if (retval == ERROR_OK)
command_print(CMD, "stm32x mass erase complete");
- } else
+ else
command_print(CMD, "stm32x mass erase failed");
return retval;