jtag: linuxgpiod: drop extra parenthesis
[openocd.git] / src / flash / nor / stm32f2x.c
index e3625f32268840d818e99e000ee00cf43dbf2cea..4e0f731827133f4452620ecb8ee7f802fc44dc47 100644 (file)
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
 /***************************************************************************
  *   Copyright (C) 2005 by Dominic Rath                                    *
  *   Dominic.Rath@gmx.de                                                   *
@@ -7,19 +9,6 @@
  *                                                                         *
  *   Copyright (C) 2011 Ã˜yvind Harboe                                      *
  *   oyvind.harboe@zylin.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     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
  ***************************************************************************/
 
 #ifdef HAVE_CONFIG_H
@@ -29,7 +18,7 @@
 #include "imp.h"
 #include <helper/binarybuffer.h>
 #include <target/algorithm.h>
-#include <target/armv7m.h>
+#include <target/cortex_m.h>
 
 /* Regarding performance:
  *
@@ -241,11 +230,11 @@ static int stm32x_otp_enable(struct flash_bank *bank)
        struct stm32x_flash_bank *stm32x_info = bank->driver_priv;
 
        if (!stm32x_info->otp_unlocked) {
-               LOG_INFO("OTP memory bank #%u is is enabled for write commands.",
+               LOG_INFO("OTP memory bank #%u is enabled for write commands.",
                         bank->bank_number);
                stm32x_info->otp_unlocked = true;
        } else {
-               LOG_WARNING("OTP memory bank #%u is is already enabled for write commands.",
+               LOG_WARNING("OTP memory bank #%u is already enabled for write commands.",
                            bank->bank_number);
        }
        return ERROR_OK;
@@ -636,8 +625,8 @@ static int stm32x_erase(struct flash_bank *bank, unsigned int first,
 
        for (unsigned int i = first; i <= last; i++) {
                unsigned int snb;
-               if (stm32x_info->has_large_mem && i >= 12)
-                       snb = (i - 12) | 0x10;
+               if (stm32x_info->has_large_mem && i >= (bank->num_sectors / 2))
+                       snb = (i - (bank->num_sectors / 2)) | 0x10;
                else
                        snb = i;
 
@@ -649,8 +638,6 @@ static int stm32x_erase(struct flash_bank *bank, unsigned int first,
                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);
@@ -672,8 +659,10 @@ static int stm32x_protect(struct flash_bank *bank, int set, unsigned int first,
        }
 
        if (stm32x_is_otp(bank)) {
-               if (!set)
+               if (!set) {
+                       LOG_ERROR("OTP protection can only be enabled");
                        return ERROR_COMMAND_ARGUMENT_INVALID;
+               }
 
                return stm32x_otp_protect(bank, first, last);
        }
@@ -858,15 +847,12 @@ static int stm32x_write(struct flash_bank *bank, const uint8_t *buffer,
        Wait for the BSY bit to be cleared
        */
        while (words_remaining > 0) {
-               uint16_t value;
-               memcpy(&value, buffer + bytes_written, sizeof(uint16_t));
-
                retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR),
                                FLASH_PG | FLASH_PSIZE_16);
                if (retval != ERROR_OK)
                        return retval;
 
-               retval = target_write_u16(target, address, value);
+               retval = target_write_memory(target, address, 2, 1, buffer + bytes_written);
                if (retval != ERROR_OK)
                        return retval;
 
@@ -968,25 +954,17 @@ static int stm32x_get_device_id(struct flash_bank *bank, uint32_t *device_id)
         * Only effects Rev A silicon */
 
        struct target *target = bank->target;
-       uint32_t cpuid;
 
        /* read stm32 device id register */
        int retval = target_read_u32(target, 0xE0042000, device_id);
        if (retval != ERROR_OK)
                return retval;
 
-       if ((*device_id & 0xfff) == 0x411) {
-               /* read CPUID reg to check core type */
-               retval = target_read_u32(target, 0xE000ED00, &cpuid);
-               if (retval != ERROR_OK)
-                       return retval;
-
-               /* check for cortex_m4 */
-               if (((cpuid >> 4) & 0xFFF) == 0xC24) {
-                       *device_id &= ~((0xFFFF << 16) | 0xfff);
-                       *device_id |= (0x1000 << 16) | 0x413;
-                       LOG_INFO("stm32f4x errata detected - fixing incorrect MCU_IDCODE");
-               }
+       if ((*device_id & 0xfff) == 0x411
+                       && cortex_m_get_impl_part(target) == CORTEX_M4_PARTNO) {
+               *device_id &= ~((0xFFFF << 16) | 0xfff);
+               *device_id |= (0x1000 << 16) | 0x413;
+               LOG_INFO("stm32f4x errata detected - fixing incorrect MCU_IDCODE");
        }
        return retval;
 }
@@ -1021,6 +999,11 @@ static int stm32x_probe(struct flash_bank *bank)
        bank->num_prot_blocks = 0;
        bank->prot_blocks = NULL;
 
+       if (!target_was_examined(target)) {
+               LOG_ERROR("Target not examined yet");
+               return ERROR_TARGET_NOT_EXAMINED;
+       }
+
        /* if explicitly called out as OTP bank, short circuit probe */
        if (stm32x_is_otp(bank)) {
                if (stm32x_otp_is_f7(bank)) {
@@ -1144,7 +1127,7 @@ static int stm32x_probe(struct flash_bank *bank)
                flash_size_in_kb = stm32x_info->user_bank_size / 1024;
        }
 
-       LOG_INFO("flash size = %" PRIu16 " kbytes", flash_size_in_kb);
+       LOG_INFO("flash size = %" PRIu16 " KiB", flash_size_in_kb);
 
        /* did we assign flash size? */
        assert(flash_size_in_kb != 0xffff);
@@ -1251,7 +1234,7 @@ static int stm32x_auto_probe(struct flash_bank *bank)
        return stm32x_probe(bank);
 }
 
-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;
 
@@ -1416,14 +1399,14 @@ static int get_stm32x_info(struct flash_bank *bank, char *buf, int buf_size)
                break;
 
        default:
-               snprintf(buf, buf_size, "Cannot identify target as a STM32F2/4/7\n");
+               command_print_sameline(cmd, "Cannot identify target as a STM32F2/4/7\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%04" PRIx16 ")", device_str, rev_id);
+               command_print_sameline(cmd, "%s - Rev: unknown (0x%04" PRIx16 ")", device_str, rev_id);
 
        return ERROR_OK;
 }
@@ -1438,7 +1421,7 @@ COMMAND_HANDLER(stm32x_handle_lock_command)
 
        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;
@@ -1477,7 +1460,7 @@ COMMAND_HANDLER(stm32x_handle_unlock_command)
 
        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;
@@ -1557,22 +1540,16 @@ static int stm32x_mass_erase(struct flash_bank *bank)
 
 COMMAND_HANDLER(stm32x_handle_mass_erase_command)
 {
-       if (CMD_ARGC < 1) {
-               command_print(CMD, "stm32x mass_erase <bank>");
+       if (CMD_ARGC != 1)
                return ERROR_COMMAND_SYNTAX_ERROR;
-       }
 
        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;
-
                command_print(CMD, "stm32x mass erase complete");
        } else {
                command_print(CMD, "stm32x mass erase failed");
@@ -1587,17 +1564,15 @@ COMMAND_HANDLER(stm32f2x_handle_options_read_command)
        struct flash_bank *bank;
        struct stm32x_flash_bank *stm32x_info = NULL;
 
-       if (CMD_ARGC != 1) {
-               command_print(CMD, "stm32f2x options_read <bank>");
+       if (CMD_ARGC != 1)
                return ERROR_COMMAND_SYNTAX_ERROR;
-       }
 
        retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &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;
 
        stm32x_info = bank->driver_priv;
@@ -1633,34 +1608,27 @@ COMMAND_HANDLER(stm32f2x_handle_options_write_command)
        struct stm32x_flash_bank *stm32x_info = NULL;
        uint16_t user_options, boot_addr0, boot_addr1, options_mask;
 
-       if (CMD_ARGC < 1) {
-               command_print(CMD, "stm32f2x options_write <bank> ...");
+       if (CMD_ARGC < 1)
                return ERROR_COMMAND_SYNTAX_ERROR;
-       }
 
        retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &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;
 
        stm32x_info = bank->driver_priv;
        if (stm32x_info->has_boot_addr) {
-               if (CMD_ARGC != 4) {
-                       command_print(CMD, "stm32f2x options_write <bank> <user_options>"
-                               " <boot_addr0> <boot_addr1>");
+               if (CMD_ARGC != 4)
                        return ERROR_COMMAND_SYNTAX_ERROR;
-               }
+
                COMMAND_PARSE_NUMBER(u16, CMD_ARGV[2], boot_addr0);
                COMMAND_PARSE_NUMBER(u16, CMD_ARGV[3], boot_addr1);
                stm32x_info->option_bytes.boot_addr = boot_addr0 | (((uint32_t) boot_addr1) << 16);
-       } else {
-               if (CMD_ARGC != 2) {
-                       command_print(CMD, "stm32f2x options_write <bank> <user_options>");
-                       return ERROR_COMMAND_SYNTAX_ERROR;
-               }
+       } else if (CMD_ARGC != 2) {
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
        COMMAND_PARSE_NUMBER(u16, CMD_ARGV[1], user_options);
@@ -1695,13 +1663,11 @@ COMMAND_HANDLER(stm32f2x_handle_optcr2_write_command)
        struct stm32x_flash_bank *stm32x_info = NULL;
        uint32_t optcr2_pcrop;
 
-       if (CMD_ARGC != 2) {
-               command_print(CMD, "stm32f2x optcr2_write <bank> <optcr2_value>");
+       if (CMD_ARGC != 2)
                return ERROR_COMMAND_SYNTAX_ERROR;
-       }
 
        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;
@@ -1715,7 +1681,7 @@ COMMAND_HANDLER(stm32f2x_handle_optcr2_write_command)
                                " finally unlock it. Clears PCROP and mass erases flash.");
 
        retval = stm32x_read_options(bank);
-       if (ERROR_OK != retval)
+       if (retval != ERROR_OK)
                return retval;
 
        COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], optcr2_pcrop);
@@ -1732,14 +1698,12 @@ COMMAND_HANDLER(stm32f2x_handle_optcr2_write_command)
 
 COMMAND_HANDLER(stm32x_handle_otp_command)
 {
-       if (CMD_ARGC < 2) {
-               command_print(CMD, "stm32x otp <bank> (enable|disable|show)");
+       if (CMD_ARGC != 2)
                return ERROR_COMMAND_SYNTAX_ERROR;
-       }
 
        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;
        if (stm32x_is_otp(bank)) {
                if (strcmp(CMD_ARGV[1], "enable") == 0) {
@@ -1761,7 +1725,7 @@ COMMAND_HANDLER(stm32x_handle_otp_command)
        return retval;
 }
 
-static const struct command_registration stm32x_exec_command_handlers[] = {
+static const struct command_registration stm32f2x_exec_command_handlers[] = {
        {
                .name = "lock",
                .handler = stm32x_handle_lock_command,
@@ -1808,26 +1772,26 @@ static const struct command_registration stm32x_exec_command_handlers[] = {
                .name = "otp",
                .handler = stm32x_handle_otp_command,
                .mode = COMMAND_EXEC,
-               .usage = "bank_id",
+               .usage = "bank_id (enable|disable|show)",
                .help = "OTP (One Time Programmable) memory write enable/disable.",
        },
        COMMAND_REGISTRATION_DONE
 };
 
-static const struct command_registration stm32x_command_handlers[] = {
+static const struct command_registration stm32f2x_command_handlers[] = {
        {
                .name = "stm32f2x",
                .mode = COMMAND_ANY,
                .help = "stm32f2x flash command group",
                .usage = "",
-               .chain = stm32x_exec_command_handlers,
+               .chain = stm32f2x_exec_command_handlers,
        },
        COMMAND_REGISTRATION_DONE
 };
 
 const struct flash_driver stm32f2x_flash = {
        .name = "stm32f2x",
-       .commands = stm32x_command_handlers,
+       .commands = stm32f2x_command_handlers,
        .flash_bank_command = stm32x_flash_bank_command,
        .erase = stm32x_erase,
        .protect = stm32x_protect,

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)