aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorasier70 <asier70@gmail.com>2021-04-12 14:09:36 +0200
committerTomas Vanek <vanekt@fbl.cz>2021-05-02 22:39:38 +0100
commit64a3e7ba4f47c5340543d9a5cadd41bc45d93c93 (patch)
treebecc840b87051aa1d0481c292a89c774e8dd85ef /src
parent87c90393fedc8bb278d189aa53bcd93f4892012b (diff)
downloadriscv-openocd-64a3e7ba4f47c5340543d9a5cadd41bc45d93c93.zip
riscv-openocd-64a3e7ba4f47c5340543d9a5cadd41bc45d93c93.tar.gz
riscv-openocd-64a3e7ba4f47c5340543d9a5cadd41bc45d93c93.tar.bz2
flash/nor/stm32f1x: Add support for GD32F1x0/3x0
Nowadays, when it's difficult to buy STM32F030, the use of GD32F130 seems to be an interesting functional alternative. This is cortex-M3 and it works with the stm32f1x driver, but unfortunately not fully. The main difference is another offset of user option bits (like WDG_SW, nRST_STOP, nRST_STDBY) in option byte register (FLASH_OBR/FMC_OBSTAT 0x4002201C). Any use of functions like lock or unlock results in change default values of the those bits stored in flash. Thus broken microcontroller is malfunctioning, e.g. flash block programming is interrupted by unexpected active hardware watchog (after 0.4s). This patch is a simplified version of #4592 done by Dominik Peklo (http://openocd.zylin.com/#/c/4592/). GigaDevice GD32F1x0 & GD32F3x0 series devices share DEV_ID with STM32F101/2/3 medium-density line, however they use a REV_ID different from any STM32 device, so can be succesfully detected. Change-Id: I252cdf738d94983b70676a3497326f90c329e292 Signed-off-by: asier70Andrzej Sierżęga <asier70@gmail.com> Reviewed-on: http://openocd.zylin.com/6164 Tested-by: jenkins Reviewed-by: Tomas Vanek <vanekt@fbl.cz>
Diffstat (limited to 'src')
-rw-r--r--src/flash/nor/stm32f1x.c38
1 files changed, 34 insertions, 4 deletions
diff --git a/src/flash/nor/stm32f1x.c b/src/flash/nor/stm32f1x.c
index 9cd282d..125f776 100644
--- a/src/flash/nor/stm32f1x.c
+++ b/src/flash/nor/stm32f1x.c
@@ -692,7 +692,7 @@ static int stm32x_probe(struct flash_bank *bank)
struct stm32x_flash_bank *stm32x_info = bank->driver_priv;
uint16_t flash_size_in_kb;
uint16_t max_flash_size_in_kb;
- uint32_t device_id;
+ uint32_t dbgmcu_idcode;
int page_size;
uint32_t base_address = 0x08000000;
@@ -705,14 +705,17 @@ static int stm32x_probe(struct flash_bank *bank)
stm32x_info->default_rdp = 0xA5;
/* read stm32 device id register */
- int retval = stm32x_get_device_id(bank, &device_id);
+ int retval = stm32x_get_device_id(bank, &dbgmcu_idcode);
if (retval != ERROR_OK)
return retval;
- LOG_INFO("device id = 0x%08" PRIx32 "", device_id);
+ LOG_INFO("device id = 0x%08" PRIx32 "", dbgmcu_idcode);
+
+ uint16_t device_id = dbgmcu_idcode & 0xfff;
+ uint16_t rev_id = dbgmcu_idcode >> 16;
/* set page size, protection granularity and max flash size depending on family */
- switch (device_id & 0xfff) {
+ switch (device_id) {
case 0x440: /* stm32f05x */
page_size = 1024;
stm32x_info->ppage_size = 4;
@@ -754,6 +757,25 @@ static int stm32x_probe(struct flash_bank *bank)
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,
+ 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
+ (FLASH_OBR/FMC_OBSTAT 0x4002201C).
+ This caused problems e.g. during flash block programming
+ because of unexpected active hardware watchog. */
+ switch (rev_id) {
+ case 0x1303: /* gd32f1x0 */
+ stm32x_info->user_data_offset = 16;
+ stm32x_info->option_offset = 6;
+ max_flash_size_in_kb = 64;
+ break;
+ case 0x1704: /* gd32f3x0 */
+ stm32x_info->user_data_offset = 16;
+ stm32x_info->option_offset = 6;
+ break;
+ }
break;
case 0x412: /* stm32f1x low-density */
page_size = 1024;
@@ -955,6 +977,14 @@ static int get_stm32x_info(struct flash_bank *bank, char *buf, int buf_size)
rev_str = "A";
break;
+ case 0x1303: /* gd32f1x0 */
+ device_str = "GD32F1x0";
+ break;
+
+ case 0x1704: /* gd32f3x0 */
+ device_str = "GD32F3x0";
+ break;
+
case 0x2000:
rev_str = "B";
break;