flash/nor/stm32f1x: Add support for GD32F1x0/3x0
authorasier70 <asier70@gmail.com>
Mon, 12 Apr 2021 12:09:36 +0000 (14:09 +0200)
committerTomas Vanek <vanekt@fbl.cz>
Sun, 2 May 2021 21:39:38 +0000 (22:39 +0100)
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>
doc/openocd.texi
src/flash/nor/stm32f1x.c

index d717311380b4a5dcd588583e7d25ee399bc25ee0..a05f85d5ebd6f500a999ab76d720d5cfaf356fdc 100644 (file)
@@ -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.
 
index 9cd282d65d7088055f0091b6f7daba719d2c1ecb..125f77691574d58fefd0dd1df58ced9434327c92 100644 (file)
@@ -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;