diff --git a/doc/openocd.texi b/doc/openocd.texi index d71731138..a05f85d5e 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -6927,7 +6927,8 @@ applied to all of them. @deffn {Flash Driver} {stm32f1x} All members of the STM32F0, STM32F1 and STM32F3 microcontroller families -from STMicroelectronics include internal flash and use ARM Cortex-M0/M3/M4 cores. +from STMicroelectronics and all members of the GD32F1x0 and GD32F3x0 microcontroller +families from GigaDevice include internal flash and use ARM Cortex-M0/M3/M4 cores. The driver automatically recognizes a number of these chips using the chip identification register, and autoconfigures itself. diff --git a/src/flash/nor/stm32f1x.c b/src/flash/nor/stm32f1x.c index 9cd282d65..125f77691 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;