cmd: add missing usage var
[fw/openocd] / src / flash / nor / stm32f1x.c
index 142b03e8da8caf0e4aa7ab01a93efba27402f251..b4ec93f6339754e9f69778e47923be747f1b6784 100644 (file)
@@ -5,6 +5,9 @@
  *   Copyright (C) 2008 by Spencer Oliver                                  *
  *   spen@spen-soft.co.uk                                                  *
  *                                                                         *
+ *   Copyright (C) 2011 by Andreas Fritiofson                              *
+ *   andreas.fritiofson@gmail.com                                          *
+ *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
  *   the Free Software Foundation; either version 2 of the License, or     *
@@ -127,8 +130,7 @@ FLASH_BANK_COMMAND_HANDLER(stm32x_flash_bank_command)
 
        if (CMD_ARGC < 6)
        {
-               LOG_WARNING("incomplete flash_bank stm32x configuration");
-               return ERROR_FLASH_BANK_INVALID;
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
        stm32x_info = malloc(sizeof(struct stm32x_flash_bank));
@@ -623,34 +625,45 @@ static int stm32x_write_block(struct flash_bank *bank, uint8_t *buffer,
        uint32_t buffer_size = 16384;
        struct working_area *source;
        uint32_t address = bank->base + offset;
-       struct reg_param reg_params[4];
+       struct reg_param reg_params[5];
        struct armv7m_algorithm armv7m_info;
        int retval = ERROR_OK;
 
-       /* see contib/loaders/flash/stm32x.s for src */
+       /* see contrib/loaders/flash/stm32f1x.S for src */
 
        static const uint8_t stm32x_flash_write_code[] = {
-                                                                       /* #define STM32_FLASH_CR_OFFSET        0x10 */
-                                                                       /* #define STM32_FLASH_SR_OFFSET        0x0C */
-                                                                       /* write: */
-               0x08, 0x4c,                                     /* ldr  r4, STM32_FLASH_BASE */
-               0x1c, 0x44,                                     /* add  r4, r3 */
-                                                                       /* write_half_word: */
-               0x01, 0x23,                                     /* movs r3, #0x01 */
-               0x23, 0x61,                                     /* str  r3, [r4, #STM32_FLASH_CR_OFFSET] */
-               0x30, 0xf8, 0x02, 0x3b,         /* ldrh r3, [r0], #0x02 */
-               0x21, 0xf8, 0x02, 0x3b,         /* strh r3, [r1], #0x02 */
-                                                                       /* busy: */
-               0xe3, 0x68,                                     /* ldr  r3, [r4, #STM32_FLASH_SR_OFFSET] */
-               0x13, 0xf0, 0x01, 0x0f,         /* tst  r3, #0x01 */
-               0xfb, 0xd0,                                     /* beq  busy */
-               0x13, 0xf0, 0x14, 0x0f,         /* tst  r3, #0x14 */
-               0x01, 0xd1,                                     /* bne  exit */
-               0x01, 0x3a,                                     /* subs r2, r2, #0x01 */
-               0xf0, 0xd1,                                     /* bne  write_half_word */
-                                                                       /* exit: */
-               0x00, 0xbe,                                     /* bkpt #0x00 */
-               0x00, 0x20, 0x02, 0x40,         /* STM32_FLASH_BASE: .word 0x40022000 */
+               /* #define STM32_FLASH_CR_OFFSET 0x10 */
+               /* #define STM32_FLASH_SR_OFFSET 0x0C */
+               /* wait_fifo: */
+                       0x16, 0x68,             /* ldr          r6, [r2, #0] */
+                       0x00, 0x2e,             /* cmp          r6, #0 */
+                       0x1a, 0xd0,             /* beq          exit */
+                       0x55, 0x68,             /* ldr          r5, [r2, #4] */
+                       0xb5, 0x42,             /* cmp          r5, r6 */
+                       0xf9, 0xd0,             /* beq          wait_fifo */
+                       0x01, 0x26,             /* movs         r6, #1 */
+                       0x06, 0x61,             /* str          r6, [r0, #STM32_FLASH_CR_OFFSET] */
+                       0x35, 0xf8, 0x02, 0x6b, /* ldrh         r6, [r5], #2 */
+                       0x24, 0xf8, 0x02, 0x6b, /* strh         r6, [r4], #2 */
+               /* busy: */
+                       0xc6, 0x68,             /* ldr          r6, [r0, #STM32_FLASH_SR_OFFSET] */
+                       0x16, 0xf0, 0x01, 0x0f, /* tst          r6, #1 */
+                       0xfb, 0xd1,             /* bne          busy */
+                       0x16, 0xf0, 0x14, 0x0f, /* tst          r6, #0x14 */
+                       0x07, 0xd1,             /* bne          error */
+                       0x9d, 0x42,             /* cmp          r5, r3 */
+                       0x28, 0xbf,             /* it           cs */
+                       0x02, 0xf1, 0x08, 0x05, /* addcs        r5, r2, #8 */
+                       0x55, 0x60,             /* str          r5, [r2, #4] */
+                       0x01, 0x39,             /* subs         r1, r1, #1 */
+                       0x19, 0xb1,             /* cbz          r1, exit */
+                       0xe4, 0xe7,             /* b            wait_fifo */
+               /* error: */
+                       0x00, 0x20,             /* movs         r0, #0 */
+                       0xc2, 0xf8,     0x02, 0x00, /* str      r0, [r2, #2] */
+               /* exit: */
+                       0x30, 0x46,             /* mov          r0, r6 */
+                       0x00, 0xbe,             /* bkpt         #0 */
        };
 
        /* flash write code */
@@ -670,6 +683,7 @@ static int stm32x_write_block(struct flash_bank *bank, uint8_t *buffer,
        while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK)
        {
                buffer_size /= 2;
+               buffer_size &= ~3UL; // Make sure it's 4 byte aligned
                if (buffer_size <= 256)
                {
                        /* if we already allocated the writing code, but failed to get a
@@ -682,60 +696,152 @@ static int stm32x_write_block(struct flash_bank *bank, uint8_t *buffer,
                }
        };
 
+       /* Set up working area. First word is write pointer, second word is read pointer,
+        * rest is fifo data area. */
+       uint32_t wp_addr = source->address;
+       uint32_t rp_addr = source->address + 4;
+       uint32_t fifo_start_addr = source->address + 8;
+       uint32_t fifo_end_addr = source->address + source->size;
+
+       uint32_t wp = fifo_start_addr;
+       uint32_t rp = fifo_start_addr;
+
+       retval = target_write_u32(target, wp_addr, wp);
+       if (retval != ERROR_OK)
+               return retval;
+       retval = target_write_u32(target, rp_addr, rp);
+       if (retval != ERROR_OK)
+               return retval;
+
+       init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT); /* flash base (in), status (out) */
+       init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);    /* count (halfword-16bit) */
+       init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);    /* buffer start */
+       init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT);    /* buffer end */
+       init_reg_param(&reg_params[4], "r4", 32, PARAM_IN_OUT); /* target address */
+
+       buf_set_u32(reg_params[0].value, 0, 32, stm32x_info->register_base);
+       buf_set_u32(reg_params[1].value, 0, 32, count);
+       buf_set_u32(reg_params[2].value, 0, 32, source->address);
+       buf_set_u32(reg_params[3].value, 0, 32, source->address + source->size);
+       buf_set_u32(reg_params[4].value, 0, 32, address);
+
        armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
        armv7m_info.core_mode = ARMV7M_MODE_ANY;
 
-       init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
-       init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
-       init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);
-       init_reg_param(&reg_params[3], "r3", 32, PARAM_IN_OUT);
+       /* Start up algorithm on target and let it idle while writing the first chunk */
+       if ((retval = target_start_algorithm(target, 0, NULL, 5, reg_params,
+                       stm32x_info->write_algorithm->address,
+                       0,
+                       &armv7m_info)) != ERROR_OK)
+       {
+               LOG_ERROR("error starting stm32x flash write algorithm");
+               goto cleanup;
+       }
 
        while (count > 0)
        {
-               uint32_t thisrun_count = (count > (buffer_size / 2)) ?
-                               (buffer_size / 2) : count;
-
-               if ((retval = target_write_buffer(target, source->address,
-                               thisrun_count * 2, buffer)) != ERROR_OK)
+               retval = target_read_u32(target, rp_addr, &rp);
+               if (retval != ERROR_OK)
+               {
+                       LOG_ERROR("failed to get read pointer");
                        break;
+               }
 
-               buf_set_u32(reg_params[0].value, 0, 32, source->address);
-               buf_set_u32(reg_params[1].value, 0, 32, address);
-               buf_set_u32(reg_params[2].value, 0, 32, thisrun_count);
-               buf_set_u32(reg_params[3].value, 0, 32, stm32x_info->register_base - FLASH_REG_BASE_B0);
+               LOG_DEBUG("count 0x%"PRIx32" wp 0x%"PRIx32" rp 0x%"PRIx32, count, wp, rp);
 
-               if ((retval = target_run_algorithm(target, 0, NULL, 4, reg_params,
-                               stm32x_info->write_algorithm->address,
-                               0,
-                               10000, &armv7m_info)) != ERROR_OK)
+               if (rp == 0)
                {
-                       LOG_ERROR("error executing stm32x flash write algorithm");
+                       LOG_ERROR("flash write algorithm aborted by target");
+                       retval = ERROR_FLASH_OPERATION_FAILED;
                        break;
                }
 
-               if (buf_get_u32(reg_params[3].value, 0, 32) & FLASH_PGERR)
+               if ((rp & 1) || rp < fifo_start_addr || rp >= fifo_end_addr)
+               {
+                       LOG_ERROR("corrupted fifo read pointer 0x%"PRIx32, rp);
+                       break;
+               }
+
+               /* Count the number of bytes available in the fifo without
+                * crossing the wrap around. Make sure to not fill it completely,
+                * because that would make wp == rp and that's the empty condition. */
+               uint32_t thisrun_bytes;
+               if (rp > wp)
+                       thisrun_bytes = rp - wp - 2;
+               else if (rp > fifo_start_addr)
+                       thisrun_bytes = fifo_end_addr - wp;
+               else
+                       thisrun_bytes = fifo_end_addr - wp - 2;
+
+               if (thisrun_bytes == 0)
+               {
+                       /* Throttle polling a bit if transfer is (much) faster than flash
+                        * programming. The exact delay shouldn't matter as long as it's
+                        * less than buffer size / flash speed. This is very unlikely to
+                        * run when using high latency connections such as USB. */
+                       alive_sleep(10);
+                       continue;
+               }
+
+               /* Limit to the amount of data we actually want to write */
+               if (thisrun_bytes > count * 2)
+                       thisrun_bytes = count * 2;
+
+               /* Write data to fifo */
+               retval = target_write_buffer(target, wp, thisrun_bytes, buffer);
+               if (retval != ERROR_OK)
+                       break;
+
+               /* Update counters and wrap write pointer */
+               buffer += thisrun_bytes;
+               count -= thisrun_bytes / 2;
+               wp += thisrun_bytes;
+               if (wp >= fifo_end_addr)
+                       wp = fifo_start_addr;
+
+               /* Store updated write pointer to target */
+               retval = target_write_u32(target, wp_addr, wp);
+               if (retval != ERROR_OK)
+                       break;
+       }
+
+       if (retval != ERROR_OK)
+       {
+               /* abort flash write algorithm on target */
+               target_write_u32(target, wp_addr, 0);
+       }
+
+       int retval2;
+       if ((retval2 = target_wait_algorithm(target, 0, NULL, 5, reg_params,
+                       0,
+                       10000,
+                       &armv7m_info)) != ERROR_OK)
+       {
+               LOG_ERROR("error waiting for stm32x flash write algorithm");
+               retval = retval2;
+       }
+
+       if (retval == ERROR_FLASH_OPERATION_FAILED)
+       {
+               LOG_ERROR("flash write failed at address 0x%"PRIx32,
+                               buf_get_u32(reg_params[4].value, 0, 32));
+
+               if (buf_get_u32(reg_params[0].value, 0, 32) & FLASH_PGERR)
                {
                        LOG_ERROR("flash memory not erased before writing");
                        /* Clear but report errors */
                        target_write_u32(target, STM32_FLASH_SR_B0, FLASH_PGERR);
-                       retval = ERROR_FAIL;
-                       break;
                }
 
-               if (buf_get_u32(reg_params[3].value, 0, 32) & FLASH_WRPRTERR)
+               if (buf_get_u32(reg_params[0].value, 0, 32) & FLASH_WRPRTERR)
                {
                        LOG_ERROR("flash memory write protected");
                        /* Clear but report errors */
                        target_write_u32(target, STM32_FLASH_SR_B0, FLASH_WRPRTERR);
-                       retval = ERROR_FAIL;
-                       break;
                }
-
-               buffer += thisrun_count * 2;
-               address += thisrun_count * 2;
-               count -= thisrun_count;
        }
 
+cleanup:
        target_free_working_area(target, source);
        target_free_working_area(target, stm32x_info->write_algorithm);
 
@@ -743,6 +849,7 @@ static int stm32x_write_block(struct flash_bank *bank, uint8_t *buffer,
        destroy_reg_param(&reg_params[1]);
        destroy_reg_param(&reg_params[2]);
        destroy_reg_param(&reg_params[3]);
+       destroy_reg_param(&reg_params[4]);
 
        return retval;
 }
@@ -847,7 +954,7 @@ static int stm32x_probe(struct flash_bank *bank)
        struct target *target = bank->target;
        struct stm32x_flash_bank *stm32x_info = bank->driver_priv;
        int i;
-       uint16_t num_pages;
+       uint16_t flash_size_in_kb;
        uint32_t device_id;
        int page_size;
        uint32_t base_address = 0x08000000;
@@ -862,107 +969,93 @@ static int stm32x_probe(struct flash_bank *bank)
        LOG_INFO("device id = 0x%08" PRIx32 "", device_id);
 
        /* get flash size from target. */
-       retval = target_read_u16(target, 0x1FFFF7E0, &num_pages);
+       retval = target_read_u16(target, 0x1FFFF7E0, &flash_size_in_kb);
        if (retval != ERROR_OK)
        {
                LOG_WARNING("failed reading flash size, default to max target family");
                /* failed reading flash size, default to max target family */
-               num_pages = 0xffff;
+               flash_size_in_kb = 0xffff;
        }
 
-       if ((device_id & 0x7ff) == 0x410)
-       {
+       if ((device_id & 0xfff) == 0x410) {
                /* medium density - we have 1k pages
                 * 4 pages for a protection area */
                page_size = 1024;
                stm32x_info->ppage_size = 4;
 
                /* check for early silicon */
-               if (num_pages == 0xffff)
+               if (flash_size_in_kb == 0xffff)
                {
                        /* number of sectors incorrect on revA */
                        LOG_WARNING("STM32 flash size failed, probe inaccurate - assuming 128k flash");
-                       num_pages = 128;
+                       flash_size_in_kb = 128;
                }
-       }
-       else if ((device_id & 0x7ff) == 0x412)
-       {
+       } else if ((device_id & 0xfff) == 0x412) {
                /* low density - we have 1k pages
                 * 4 pages for a protection area */
                page_size = 1024;
                stm32x_info->ppage_size = 4;
 
                /* check for early silicon */
-               if (num_pages == 0xffff)
+               if (flash_size_in_kb == 0xffff)
                {
                        /* number of sectors incorrect on revA */
                        LOG_WARNING("STM32 flash size failed, probe inaccurate - assuming 32k flash");
-                       num_pages = 32;
+                       flash_size_in_kb = 32;
                }
-       }
-       else if ((device_id & 0x7ff) == 0x414)
-       {
+       } else if ((device_id & 0xfff) == 0x414) {
                /* high density - we have 2k pages
                 * 2 pages for a protection area */
                page_size = 2048;
                stm32x_info->ppage_size = 2;
 
                /* check for early silicon */
-               if (num_pages == 0xffff)
+               if (flash_size_in_kb == 0xffff)
                {
                        /* number of sectors incorrect on revZ */
                        LOG_WARNING("STM32 flash size failed, probe inaccurate - assuming 512k flash");
-                       num_pages = 512;
+                       flash_size_in_kb = 512;
                }
-       }
-       else if ((device_id & 0x7ff) == 0x418)
-       {
+       } else if ((device_id & 0xfff) == 0x418) {
                /* connectivity line density - we have 2k pages
                 * 2 pages for a protection area */
                page_size = 2048;
                stm32x_info->ppage_size = 2;
 
                /* check for early silicon */
-               if (num_pages == 0xffff)
+               if (flash_size_in_kb == 0xffff)
                {
                        /* number of sectors incorrect on revZ */
                        LOG_WARNING("STM32 flash size failed, probe inaccurate - assuming 256k flash");
-                       num_pages = 256;
+                       flash_size_in_kb = 256;
                }
-       }
-       else if ((device_id & 0x7ff) == 0x420)
-       {
+       } else if ((device_id & 0xfff) == 0x420) {
                /* value line density - we have 1k pages
                 * 4 pages for a protection area */
                page_size = 1024;
                stm32x_info->ppage_size = 4;
 
                /* check for early silicon */
-               if (num_pages == 0xffff)
+               if (flash_size_in_kb == 0xffff)
                {
                        /* number of sectors may be incorrrect on early silicon */
                        LOG_WARNING("STM32 flash size failed, probe inaccurate - assuming 128k flash");
-                       num_pages = 128;
+                       flash_size_in_kb = 128;
                }
-       }
-       else if ((device_id & 0x7ff) == 0x428)
-       {
-               /* value line density - we have 1k pages
+       } else if ((device_id & 0xfff) == 0x428) {
+               /* value line High density - we have 2k pages
                 * 4 pages for a protection area */
                page_size = 2048;
                stm32x_info->ppage_size = 4;
 
                /* check for early silicon */
-               if (num_pages == 0xffff)
+               if (flash_size_in_kb == 0xffff)
                {
                        /* number of sectors may be incorrrect on early silicon */
                        LOG_WARNING("STM32 flash size failed, probe inaccurate - assuming 128k flash");
-                       num_pages = 128;
+                       flash_size_in_kb = 128;
                }
-       }
-
-       else if ((device_id & 0x7ff) == 0x430)
-       {
+       } else if ((device_id & 0xfff) == 0x430) {
                /* xl line density - we have 2k pages
                 * 2 pages for a protection area */
                page_size = 2048;
@@ -970,22 +1063,22 @@ static int stm32x_probe(struct flash_bank *bank)
                stm32x_info->has_dual_banks = true;
 
                /* check for early silicon */
-               if (num_pages == 0xffff)
+               if (flash_size_in_kb == 0xffff)
                {
                        /* number of sectors may be incorrrect on early silicon */
                        LOG_WARNING("STM32 flash size failed, probe inaccurate - assuming 1024k flash");
-                       num_pages = 1024;
+                       flash_size_in_kb = 1024;
                }
 
                /* split reported size into matching bank */
                if (bank->base != 0x08080000)
                {
                        /* bank 0 will be fixed 512k */
-                       num_pages = 512;
+                       flash_size_in_kb = 512;
                }
                else
                {
-                       num_pages -= 512;
+                       flash_size_in_kb -= 512;
                        /* bank1 also uses a register offset */
                        stm32x_info->register_base = FLASH_REG_BASE_B1;
                        base_address = 0x08080000;
@@ -997,10 +1090,16 @@ static int stm32x_probe(struct flash_bank *bank)
                return ERROR_FAIL;
        }
 
-       LOG_INFO("flash size = %dkbytes", num_pages);
+       LOG_INFO("flash size = %dkbytes", flash_size_in_kb);
+
+       /* did we assign flash size? */
+       assert(flash_size_in_kb != 0xffff);
 
        /* calculate numbers of pages */
-       num_pages /= (page_size / 1024);
+       int num_pages = flash_size_in_kb * 1024 / page_size;
+
+       /* check that calculation result makes sense */
+       assert(num_pages > 0);
 
        if (bank->sectors)
        {
@@ -1052,8 +1151,7 @@ static int get_stm32x_info(struct flash_bank *bank, char *buf, int buf_size)
        if (retval != ERROR_OK)
                return retval;
 
-       if ((device_id & 0x7ff) == 0x410)
-       {
+       if ((device_id & 0xfff) == 0x410) {
                printed = snprintf(buf, buf_size, "stm32x (Medium Density) - Rev: ");
                buf += printed;
                buf_size -= printed;
@@ -1080,9 +1178,7 @@ static int get_stm32x_info(struct flash_bank *bank, char *buf, int buf_size)
                                snprintf(buf, buf_size, "unknown");
                                break;
                }
-       }
-       else if ((device_id & 0x7ff) == 0x412)
-       {
+       } else if ((device_id & 0xfff) == 0x412) {
                printed = snprintf(buf, buf_size, "stm32x (Low Density) - Rev: ");
                buf += printed;
                buf_size -= printed;
@@ -1097,9 +1193,7 @@ static int get_stm32x_info(struct flash_bank *bank, char *buf, int buf_size)
                                snprintf(buf, buf_size, "unknown");
                                break;
                }
-       }
-       else if ((device_id & 0x7ff) == 0x414)
-       {
+       } else if ((device_id & 0xfff) == 0x414) {
                printed = snprintf(buf, buf_size, "stm32x (High Density) - Rev: ");
                buf += printed;
                buf_size -= printed;
@@ -1118,9 +1212,7 @@ static int get_stm32x_info(struct flash_bank *bank, char *buf, int buf_size)
                                snprintf(buf, buf_size, "unknown");
                                break;
                }
-       }
-       else if ((device_id & 0x7ff) == 0x418)
-       {
+       } else if ((device_id & 0xfff) == 0x418) {
                printed = snprintf(buf, buf_size, "stm32x (Connectivity) - Rev: ");
                buf += printed;
                buf_size -= printed;
@@ -1139,9 +1231,7 @@ static int get_stm32x_info(struct flash_bank *bank, char *buf, int buf_size)
                                snprintf(buf, buf_size, "unknown");
                                break;
                }
-       }
-       else if ((device_id & 0x7ff) == 0x420)
-       {
+       } else if ((device_id & 0xfff) == 0x420) {
                printed = snprintf(buf, buf_size, "stm32x (Value) - Rev: ");
                buf += printed;
                buf_size -= printed;
@@ -1160,9 +1250,7 @@ static int get_stm32x_info(struct flash_bank *bank, char *buf, int buf_size)
                                snprintf(buf, buf_size, "unknown");
                                break;
                }
-       }
-       else if ((device_id & 0x7ff) == 0x428)
-       {
+       } else if ((device_id & 0xfff) == 0x428) {
                printed = snprintf(buf, buf_size, "stm32x (Value HD) - Rev: ");
                buf += printed;
                buf_size -= printed;
@@ -1181,9 +1269,7 @@ static int get_stm32x_info(struct flash_bank *bank, char *buf, int buf_size)
                                snprintf(buf, buf_size, "unknown");
                                break;
                }
-       }
-       else if ((device_id & 0x7ff) == 0x430)
-       {
+       } else if ((device_id & 0xfff) == 0x430) {
                printed = snprintf(buf, buf_size, "stm32x (XL) - Rev: ");
                buf += printed;
                buf_size -= printed;
@@ -1215,8 +1301,7 @@ COMMAND_HANDLER(stm32x_handle_lock_command)
 
        if (CMD_ARGC < 1)
        {
-               command_print(CMD_CTX, "stm32x lock <bank>");
-               return ERROR_OK;
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
        struct flash_bank *bank;
@@ -1264,8 +1349,7 @@ COMMAND_HANDLER(stm32x_handle_unlock_command)
 
        if (CMD_ARGC < 1)
        {
-               command_print(CMD_CTX, "stm32x unlock <bank>");
-               return ERROR_OK;
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
        struct flash_bank *bank;
@@ -1312,8 +1396,7 @@ COMMAND_HANDLER(stm32x_handle_options_read_command)
 
        if (CMD_ARGC < 1)
        {
-               command_print(CMD_CTX, "stm32x options_read <bank>");
-               return ERROR_OK;
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
        struct flash_bank *bank;
@@ -1382,9 +1465,7 @@ COMMAND_HANDLER(stm32x_handle_options_write_command)
 
        if (CMD_ARGC < 4)
        {
-               command_print(CMD_CTX, "stm32x options_write <bank> <SWWDG | HWWDG> "
-                               "<RSTSTNDBY | NORSTSTNDBY> <RSTSTOP | NORSTSTOP> <BOOT0 | BOOT1>");
-               return ERROR_OK;
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
        struct flash_bank *bank;
@@ -1517,8 +1598,7 @@ COMMAND_HANDLER(stm32x_handle_mass_erase_command)
 
        if (CMD_ARGC < 1)
        {
-               command_print(CMD_CTX, "stm32x mass_erase <bank>");
-               return ERROR_OK;
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
        struct flash_bank *bank;
@@ -1591,6 +1671,7 @@ static const struct command_registration stm32x_command_handlers[] = {
                .name = "stm32f1x",
                .mode = COMMAND_ANY,
                .help = "stm32f1x flash command group",
+               .usage = "",
                .chain = stm32x_exec_command_handlers,
        },
        COMMAND_REGISTRATION_DONE