guix-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

07/07: gnu: openocd: Update to 9a877a83a1c8b1f105cdc0de46c5cbc4d9e8799e.


From: guix-commits
Subject: 07/07: gnu: openocd: Update to 9a877a83a1c8b1f105cdc0de46c5cbc4d9e8799e.
Date: Thu, 22 Oct 2020 11:11:34 -0400 (EDT)

civodul pushed a commit to branch master
in repository guix.

commit cad55e91fd5a481279e6286a2728761b8da7c07a
Author: Malte Frank Gerdes <malte.f.gerdes@gmail.com>
AuthorDate: Sat Oct 10 15:31:14 2020 +0200

    gnu: openocd: Update to 9a877a83a1c8b1f105cdc0de46c5cbc4d9e8799e.
    
    * gnu/packages/embedded.scm (openocd): Update to 
9a877a83a1c8b1f105cdc0de46c5cbc4d9e8799e.
    [version]: Substitute release with current master.
    [source]: Remove openocd-nrf52.patch
    [arguments]: Replace bootstrap build phase.
    
    * gnu/local.mk: Remove openocd-nrf52.patch.
    * gnu/packages/patches/openocd-nrf52.patch: Remove file.
    
    Signed-off-by: Ludovic Courtès <ludo@gnu.org>
---
 gnu/local.mk                             |   2 +-
 gnu/packages/embedded.scm                | 124 ++---
 gnu/packages/patches/openocd-nrf52.patch | 827 -------------------------------
 3 files changed, 65 insertions(+), 888 deletions(-)

diff --git a/gnu/local.mk b/gnu/local.mk
index 607f78b..31385d0 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -37,6 +37,7 @@
 # Copyright © 2020 Brice Waegeneire <brice@waegenei.re>
 # Copyright © 2020 Tanguy Le Carrour <tanguy@bioneland.org>
 # Copyright © 2020 Martin Becze <mjbecze@riseup.net>
+# Copyright © 2020 Malte Frank Gerdes <mate.f.gerdes@gmail.com>
 #
 # This file is part of GNU Guix.
 #
@@ -1393,7 +1394,6 @@ dist_patch_DATA =                                         
\
   %D%/packages/patches/openfoam-4.1-cleanup.patch                      \
   %D%/packages/patches/openjdk-10-idlj-reproducibility.patch   \
   %D%/packages/patches/openmpi-mtl-priorities.patch            \
-  %D%/packages/patches/openocd-nrf52.patch                     \
   %D%/packages/patches/openssh-hurd.patch                      \
   %D%/packages/patches/openresolv-restartcmd-guix.patch        \
   %D%/packages/patches/openscad-parser-boost-1.72.patch        \
diff --git a/gnu/packages/embedded.scm b/gnu/packages/embedded.scm
index 1eacb72..cc26b17 100644
--- a/gnu/packages/embedded.scm
+++ b/gnu/packages/embedded.scm
@@ -514,67 +514,71 @@ language.")
     (license license:bsd-2)))
 
 (define-public openocd
-  (package
-    (name "openocd")
-    (version "0.10.0")
-    (source (origin
-              (method url-fetch)
-              (uri (string-append "mirror://sourceforge/openocd/openocd/"
-                                  version "/openocd-" version ".tar.gz"))
-              (sha256
-               (base32
-                "09p57y3c2spqx4vjjlz1ljm1lcd0j9q8g76ywxqgn3yc34wv18zd"))
-              ;; FIXME: Remove after nrf52 patch is merged.
-              (patches
-               (search-patches "openocd-nrf52.patch"))))
-    (build-system gnu-build-system)
-    (native-inputs
-     `(("autoconf" ,autoconf)
-       ("automake" ,automake)
-       ("libtool" ,libtool)
-       ("pkg-config" ,pkg-config)))
-    (inputs
-     `(("hidapi" ,hidapi)
-       ("jimtcl" ,jimtcl)
-       ("libftdi" ,libftdi)
-       ("libjaylink" ,libjaylink)
-       ("libusb-compat" ,libusb-compat)))
-    (arguments
-     '(#:configure-flags
-       (append (list "--disable-werror"
-                     "--enable-sysfsgpio"
-                     "--disable-internal-jimtcl"
-                     "--disable-internal-libjaylink")
-               (map (lambda (programmer)
-                      (string-append "--enable-" programmer))
-                    '("amtjtagaccel" "armjtagew" "buspirate" "ftdi"
-                      "gw16012" "jlink" "opendous" "osbdm"
-                      "parport" "aice" "cmsis-dap" "dummy" "jtag_vpi"
-                      "remote-bitbang" "rlink" "stlink" "ti-icdi" "ulink"
-                      "usbprog" "vsllink" "usb-blaster-2" "usb_blaster"
-                      "presto" "openjtag")))
-       #:phases
-       (modify-phases %standard-phases
-         ;; Required because of patched sources.
-         (add-before 'configure 'autoreconf
-           (lambda _ (invoke "autoreconf" "-vfi") #t))
-         (add-after 'autoreconf 'change-udev-group
-           (lambda _
-             (substitute* "contrib/60-openocd.rules"
-               (("plugdev") "dialout"))
-             #t))
-         (add-after 'install 'install-udev-rules
-           (lambda* (#:key outputs #:allow-other-keys)
-             (install-file "contrib/60-openocd.rules"
-                           (string-append
-                            (assoc-ref outputs "out")
-                            "/lib/udev/rules.d/"))
-             #t)))))
-    (home-page "http://openocd.org";)
-    (synopsis "On-Chip Debugger")
-    (description "OpenOCD provides on-chip programming and debugging support
+  (let ((commit "9a877a83a1c8b1f105cdc0de46c5cbc4d9e8799e")
+        (revision "0"))
+    (package
+      (name "openocd")
+      (version (string-append "0.10.0-" revision "."
+                              (string-take commit 7)))
+      (source (origin
+                (method git-fetch)
+                (uri (git-reference
+                      (url "https://git.code.sf.net/p/openocd/code";)
+                      (commit commit)))
+                (file-name (string-append name "-" version "-checkout"))
+                (sha256
+                 (base32
+                  "1q536cp80v2bcy6xwk08f1r2ljyw13jchx3a1z7d3ni3vqql7rc6"))))
+      (build-system gnu-build-system)
+      (native-inputs
+       `(("autoconf" ,autoconf)
+         ("automake" ,automake)
+         ("libtool" ,libtool)
+         ("which" ,base:which)
+         ("pkg-config" ,pkg-config)))
+      (inputs
+       `(("hidapi" ,hidapi)
+         ("jimtcl" ,jimtcl)
+         ("libftdi" ,libftdi)
+         ("libjaylink" ,libjaylink)
+         ("libusb-compat" ,libusb-compat)))
+      (arguments
+       '(#:configure-flags
+         (append (list "--disable-werror"
+                       "--enable-sysfsgpio"
+                       "--disable-internal-jimtcl"
+                       "--disable-internal-libjaylink")
+                 (map (lambda (programmer)
+                        (string-append "--enable-" programmer))
+                      '("amtjtagaccel" "armjtagew" "buspirate" "ftdi"
+                        "gw16012" "jlink" "opendous" "osbdm"
+                        "parport" "aice" "cmsis-dap" "dummy" "jtag_vpi"
+                        "remote-bitbang" "rlink" "stlink" "ti-icdi" "ulink"
+                        "usbprog" "vsllink" "usb-blaster-2" "usb_blaster"
+                        "presto" "openjtag")))
+         #:phases
+         (modify-phases %standard-phases
+           (replace 'bootstrap
+             (lambda _
+               (patch-shebang "bootstrap")
+               (invoke "./bootstrap" "nosubmodule")))
+           (add-after 'autoreconf 'change-udev-group
+             (lambda _
+               (substitute* "contrib/60-openocd.rules"
+                 (("plugdev") "dialout"))
+               #t))
+           (add-after 'install 'install-udev-rules
+             (lambda* (#:key outputs #:allow-other-keys)
+               (install-file "contrib/60-openocd.rules"
+                             (string-append
+                              (assoc-ref outputs "out")
+                              "/lib/udev/rules.d/"))
+               #t)))))
+      (home-page "http://openocd.org";)
+      (synopsis "On-Chip Debugger")
+      (description "OpenOCD provides on-chip programming and debugging support
 with a layered architecture of JTAG interface and TAP support.")
-    (license license:gpl2+)))
+      (license license:gpl2+))))
 
 ;; The commits for all propeller tools are the stable versions published at
 ;; https://github.com/propellerinc/propgcc in the release_1_0.  According to
diff --git a/gnu/packages/patches/openocd-nrf52.patch 
b/gnu/packages/patches/openocd-nrf52.patch
deleted file mode 100644
index 0ec4348..0000000
--- a/gnu/packages/patches/openocd-nrf52.patch
+++ /dev/null
@@ -1,827 +0,0 @@
-This patch adds support for nRF52 series devices.  It is patchset 7 from
-<http://openocd.zylin.com/#/c/3511/>, which has been tested, but not
-merged yet in master.
-
-From: Michael Dietz <mjdietzx@gmail.com>
-Date: Mon, 30 May 2016 12:50:44 +0000 (-0700)
-Subject: Added support for nRF52 Series Devices.
-X-Git-Url: 
http://openocd.zylin.com/gitweb?p=openocd.git;a=commitdiff_plain;h=9ba15633e221d9d72e320372ba8f49d3f30d4bce
-
-Added support for nRF52 Series Devices.
-
-Both nrf52.c and nrf52.cfg are based off of previous nRF51 files.
-- Some possible race conditions with NVMC have been fixed in nRF52.c
-- Removed nrf51_get_probed_chip_if_halted() as the core does not have to be 
halted to perform operations where it is called.
-- Only registers that are needed by openOCD are defined, some registers in 
nRF51 don't exist in nRF52 and are removed.
-- Some all around cleanup has been done.
-- The protection mechanism is completely different on nRF52 and this has not 
been implemented yet - just prints a warning and returns for now.
-
-Change-Id: I4dd42c86f33f450709bb981806c2655f04aa6201
-Signed-off-by: Michael Dietz <mjdietzx@gmail.com>
----
-
-diff --git a/src/flash/nor/Makefile.am b/src/flash/nor/Makefile.am
-index 727e4f2..839667c 100644
---- a/src/flash/nor/Makefile.am
-+++ b/src/flash/nor/Makefile.am
-@@ -36,6 +36,7 @@ NOR_DRIVERS = \
-       %D%/niietcm4.c \
-       %D%/non_cfi.c \
-       %D%/nrf51.c \
-+      %D%/nrf52.c \
-       %D%/numicro.c \
-       %D%/ocl.c \
-       %D%/pic32mx.c \
-diff --git a/src/flash/nor/drivers.c b/src/flash/nor/drivers.c
-index 56a5cb2..071273e 100644
---- a/src/flash/nor/drivers.c
-+++ b/src/flash/nor/drivers.c
-@@ -48,6 +48,7 @@ extern struct flash_driver mdr_flash;
- extern struct flash_driver mrvlqspi_flash;
- extern struct flash_driver niietcm4_flash;
- extern struct flash_driver nrf51_flash;
-+extern struct flash_driver nrf52_flash;
- extern struct flash_driver numicro_flash;
- extern struct flash_driver ocl_flash;
- extern struct flash_driver pic32mx_flash;
-@@ -100,6 +101,7 @@ static struct flash_driver *flash_drivers[] = {
-       &mrvlqspi_flash,
-       &niietcm4_flash,
-       &nrf51_flash,
-+       &nrf52_flash,
-       &numicro_flash,
-       &ocl_flash,
-       &pic32mx_flash,
-diff --git a/src/flash/nor/nrf52.c b/src/flash/nor/nrf52.c
-new file mode 100644
-index 0000000..7f2bd35
---- /dev/null
-+++ b/src/flash/nor/nrf52.c
-@@ -0,0 +1,733 @@
-+/***************************************************************************
-+ *   Copyright (C) 2013 Synapse Product Development                        *
-+ *   Andrey Smirnov <andrew.smironv@gmail.com>                             *
-+ *   Angus Gratton <gus@projectgus.com>                                    *
-+ *   Erdem U. Altunyurt <spamjunkeater@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     *
-+ *   (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
-+#include "config.h"
-+#endif
-+
-+#include <stdlib.h>
-+
-+#include "imp.h"
-+#include <target/algorithm.h>
-+#include <target/armv7m.h>
-+#include <helper/types.h>
-+
-+/* nRF52 Register addresses used by openOCD. */
-+#define NRF52_FLASH_BASE_ADDR        (0x0)
-+
-+#define NRF52_FICR_BASE_ADDR         (0x10000000)
-+#define NRF52_FICR_CODEPAGESIZE_ADDR (NRF52_FICR_BASE_ADDR | 0x010)
-+#define NRF52_FICR_CODESIZE_ADDR     (NRF52_FICR_BASE_ADDR | 0x014)
-+
-+#define NRF52_UICR_BASE_ADDR         (0x10001000)
-+
-+#define NRF52_NVMC_BASE_ADDR         (0x4001E000)
-+#define NRF52_NVMC_READY_ADDR        (NRF52_NVMC_BASE_ADDR | 0x400)
-+#define NRF52_NVMC_CONFIG_ADDR       (NRF52_NVMC_BASE_ADDR | 0x504)
-+#define NRF52_NVMC_ERASEPAGE_ADDR    (NRF52_NVMC_BASE_ADDR | 0x508)
-+#define NRF52_NVMC_ERASEALL_ADDR     (NRF52_NVMC_BASE_ADDR | 0x50C)
-+#define NRF52_NVMC_ERASEUICR_ADDR    (NRF52_NVMC_BASE_ADDR | 0x514)
-+
-+/* nRF52 bit fields. */
-+enum nrf52_nvmc_config_bits {
-+      NRF52_NVMC_CONFIG_REN = 0x0,
-+      NRF52_NVMC_CONFIG_WEN = 0x01,
-+      NRF52_NVMC_CONFIG_EEN = 0x02
-+};
-+
-+enum nrf52_nvmc_ready_bits {
-+      NRF52_NVMC_BUSY  = 0x0,
-+      NRF52_NVMC_READY = 0x01
-+};
-+
-+/* nRF52 state information. */
-+struct nrf52_info {
-+      uint32_t code_page_size; /* Size of FLASH page in bytes. */
-+      uint32_t code_memory_size; /* Size of Code FLASH region in bytes. */
-+
-+      struct {
-+              bool probed;
-+              int (*write) (struct flash_bank *bank,
-+                              struct nrf52_info *chip,
-+                              const uint8_t *buffer, uint32_t offset, 
uint32_t count);
-+      } bank[2]; /* There are two regions in nRF52 FLASH - Code and UICR. */
-+      struct target *target;
-+};
-+
-+static int nrf52_protect_check(struct flash_bank *bank);
-+
-+static int nrf52_probe(struct flash_bank *bank)
-+{
-+      int res;
-+      struct nrf52_info *chip = bank->driver_priv;
-+      assert(chip != NULL);
-+
-+      res = target_read_u32(chip->target,
-+                                              NRF52_FICR_CODEPAGESIZE_ADDR,
-+                                              &chip->code_page_size);
-+      if (res != ERROR_OK) {
-+              LOG_ERROR("Couldn't read code page size");
-+              return res;
-+      }
-+
-+      res = target_read_u32(chip->target,
-+                                              NRF52_FICR_CODESIZE_ADDR,
-+                                              &chip->code_memory_size);
-+      if (res != ERROR_OK) {
-+              LOG_ERROR("Couldn't read code memory size");
-+              return res;
-+      }
-+
-+      chip->code_memory_size = chip->code_memory_size * chip->code_page_size;
-+
-+      if (bank->base == NRF52_FLASH_BASE_ADDR) {
-+              bank->size = chip->code_memory_size;
-+              bank->num_sectors = bank->size / chip->code_page_size;
-+              bank->sectors = calloc(bank->num_sectors,
-+                                                      
sizeof((bank->sectors)[0]));
-+              if (!bank->sectors)
-+                      return ERROR_FLASH_BANK_NOT_PROBED;
-+
-+              /* Fill out the sector information: All nRF51 sectors are the 
same size. */
-+              for (int i = 0; i < bank->num_sectors; i++) {
-+                      bank->sectors[i].size = chip->code_page_size;
-+                      bank->sectors[i].offset = i * chip->code_page_size;
-+
-+                      /* Mark as unknown. */
-+                      bank->sectors[i].is_erased = -1;
-+                      bank->sectors[i].is_protected = -1;
-+              }
-+
-+              nrf52_protect_check(bank);
-+
-+              chip->bank[0].probed = true;
-+      } else { /* This is the UICR bank. */
-+              bank->size = chip->code_page_size;
-+              bank->num_sectors = 1;
-+              bank->sectors = calloc(bank->num_sectors,
-+                                                      
sizeof((bank->sectors)[0]));
-+              if (!bank->sectors)
-+                      return ERROR_FLASH_BANK_NOT_PROBED;
-+
-+              bank->sectors[0].size = bank->size;
-+              bank->sectors[0].offset = 0;
-+
-+              bank->sectors[0].is_erased = -1;
-+              bank->sectors[0].is_protected = -1;
-+
-+              chip->bank[1].probed = true;
-+      }
-+
-+      return ERROR_OK;
-+}
-+
-+static int nrf52_bank_is_probed(struct flash_bank *bank)
-+{
-+      struct nrf52_info *chip = bank->driver_priv;
-+      assert(chip != NULL);
-+
-+      return chip->bank[bank->bank_number].probed;
-+}
-+
-+static int nrf52_auto_probe(struct flash_bank *bank)
-+{
-+      if (!nrf52_bank_is_probed(bank))
-+              return nrf52_probe(bank);
-+      else
-+              return ERROR_OK;
-+}
-+
-+static int nrf52_wait_for_nvmc(struct nrf52_info *chip)
-+{
-+      int res;
-+      uint32_t ready;
-+      int timeout = 100;
-+
-+      do {
-+              res = target_read_u32(chip->target, NRF52_NVMC_READY_ADDR, 
&ready);
-+              if (res != ERROR_OK) {
-+                      LOG_ERROR("Couldn't read NVMC_READY register");
-+                      return res;
-+              }
-+
-+              if (ready == NRF52_NVMC_READY)
-+                      return ERROR_OK;
-+
-+              alive_sleep(1);
-+      } while (timeout--);
-+
-+      LOG_DEBUG("Timed out waiting for the NVMC to be ready");
-+      return ERROR_FLASH_BUSY;
-+}
-+
-+static int nrf52_nvmc_erase_enable(struct nrf52_info *chip)
-+{
-+      int res;
-+
-+      res = nrf52_wait_for_nvmc(chip);
-+      if (res != ERROR_OK)
-+              return res;
-+
-+      res = target_write_u32(chip->target,
-+                                              NRF52_NVMC_CONFIG_ADDR,
-+                                              NRF52_NVMC_CONFIG_EEN);
-+      if (res != ERROR_OK) {
-+              LOG_ERROR("Failed to configure the NVMC for erasing");
-+              return res;
-+      }
-+
-+      return res;
-+}
-+
-+static int nrf52_nvmc_write_enable(struct nrf52_info *chip)
-+{
-+      int res;
-+
-+      res = nrf52_wait_for_nvmc(chip);
-+      if (res != ERROR_OK)
-+              return res;
-+
-+      res = target_write_u32(chip->target,
-+                                              NRF52_NVMC_CONFIG_ADDR,
-+                                              NRF52_NVMC_CONFIG_WEN);
-+      if (res != ERROR_OK) {
-+              LOG_ERROR("Failed to configure the NVMC for writing");
-+              return res;
-+      }
-+
-+      return res;
-+}
-+
-+static int nrf52_nvmc_read_only(struct nrf52_info *chip)
-+{
-+      int res;
-+
-+      res = nrf52_wait_for_nvmc(chip);
-+      if (res != ERROR_OK)
-+              return res;
-+
-+      res = target_write_u32(chip->target,
-+                                              NRF52_NVMC_CONFIG_ADDR,
-+                                              NRF52_NVMC_CONFIG_REN);
-+      if (res != ERROR_OK) {
-+              LOG_ERROR("Failed to configure the NVMC for read-only");
-+              return res;
-+      }
-+
-+      return res;
-+}
-+
-+static int nrf52_nvmc_generic_erase(struct nrf52_info *chip,
-+                                                              uint32_t 
erase_register,
-+                                                              uint32_t 
erase_value)
-+{
-+      int res;
-+
-+      res = nrf52_nvmc_erase_enable(chip);
-+      if (res != ERROR_OK)
-+              return res;
-+
-+      res = target_write_u32(chip->target,
-+                                              erase_register,
-+                                              erase_value);
-+      if (res != ERROR_OK)
-+              LOG_ERROR("Failed to write NVMC erase register");
-+
-+      return nrf52_nvmc_read_only(chip);
-+}
-+
-+static int nrf52_protect_check(struct flash_bank *bank)
-+{
-+      LOG_WARNING("nrf52_protect_check() is not implemented for nRF52 series 
devices yet");
-+      return ERROR_OK;
-+}
-+
-+static int nrf52_protect(struct flash_bank *bank, int set, int first, int 
last)
-+{
-+      LOG_WARNING("nrf52_protect() is not implemented for nRF52 series 
devices yet");
-+      return ERROR_OK;
-+}
-+
-+static struct flash_sector *nrf52_find_sector_by_address(struct flash_bank 
*bank, uint32_t address)
-+{
-+      struct nrf52_info *chip = bank->driver_priv;
-+      assert(chip != NULL);
-+
-+      for (int i = 0; i < bank->num_sectors; i++)
-+              if (bank->sectors[i].offset <= address &&
-+                      address < (bank->sectors[i].offset + 
chip->code_page_size)) {
-+                      return &bank->sectors[i];
-+              }
-+
-+      return NULL;
-+}
-+
-+static int nrf52_erase_all(struct nrf52_info *chip)
-+{
-+      LOG_DEBUG("Erasing all non-volatile memory");
-+      return nrf52_nvmc_generic_erase(chip,
-+                                                              
NRF52_NVMC_ERASEALL_ADDR,
-+                                                              0x01);
-+}
-+
-+static int nrf52_erase_page(struct flash_bank *bank,
-+                                                      struct nrf52_info *chip,
-+                                                      struct flash_sector 
*sector)
-+{
-+      int res;
-+
-+      LOG_DEBUG("Erasing page at 0x%"PRIx32, sector->offset);
-+      if (sector->is_protected == 1) {
-+              LOG_ERROR("Cannot erase protected sector at 0x%" PRIx32, 
sector->offset);
-+              return ERROR_FAIL;
-+      }
-+
-+      if (bank->base == NRF52_UICR_BASE_ADDR) {
-+              res = nrf52_nvmc_generic_erase(chip,
-+                                                                      
NRF52_NVMC_ERASEUICR_ADDR,
-+                                                                      
0x00000001);
-+      } else {
-+              res = nrf52_nvmc_generic_erase(chip,
-+                                                                      
NRF52_NVMC_ERASEPAGE_ADDR,
-+                                                                      
sector->offset);
-+      }
-+
-+      if (res == ERROR_OK)
-+              sector->is_erased = 1;
-+      return res;
-+}
-+
-+static const uint8_t nrf52_flash_write_code[] = {
-+      /* See contrib/loaders/flash/cortex-m0.S */
-+      /* <wait_fifo>: */
-+      0x0d, 0x68,             /* ldr  r5,     [r1,    #0] */
-+      0x00, 0x2d,             /* cmp  r5,     #0 */
-+      0x0b, 0xd0,             /* beq.n        1e <exit> */
-+      0x4c, 0x68,             /* ldr  r4,     [r1,    #4] */
-+      0xac, 0x42,             /* cmp  r4,     r5 */
-+      0xf9, 0xd0,             /* beq.n        0 <wait_fifo> */
-+      0x20, 0xcc,             /* ldmia        r4!,    {r5} */
-+      0x20, 0xc3,             /* stmia        r3!,    {r5} */
-+      0x94, 0x42,             /* cmp  r4,     r2 */
-+      0x01, 0xd3,             /* bcc.n        18 <no_wrap> */
-+      0x0c, 0x46,             /* mov  r4,     r1 */
-+      0x08, 0x34,             /* adds r4,     #8 */
-+      /* <no_wrap>: */
-+      0x4c, 0x60,             /* str  r4, [r1,        #4] */
-+      0x04, 0x38,             /* subs r0, #4 */
-+      0xf0, 0xd1,             /* bne.n        0 <wait_fifo> */
-+      /* <exit>: */
-+      0x00, 0xbe              /* bkpt 0x0000 */
-+};
-+
-+
-+/* Start a low level flash write for the specified region */
-+static int nrf52_ll_flash_write(struct nrf52_info *chip, uint32_t offset, 
const uint8_t *buffer, uint32_t bytes)
-+{
-+      struct target *target = chip->target;
-+      uint32_t buffer_size = 8192;
-+      struct working_area *write_algorithm;
-+      struct working_area *source;
-+      uint32_t address = NRF52_FLASH_BASE_ADDR + offset;
-+      struct reg_param reg_params[4];
-+      struct armv7m_algorithm armv7m_info;
-+      int retval = ERROR_OK;
-+
-+      LOG_DEBUG("Writing buffer to flash offset=0x%"PRIx32" bytes=0x%"PRIx32, 
offset, bytes);
-+      assert(bytes % 4 == 0);
-+
-+      /* allocate working area with flash programming code */
-+      if (target_alloc_working_area(target, sizeof(nrf52_flash_write_code),
-+                      &write_algorithm) != ERROR_OK) {
-+              LOG_WARNING("no working area available, falling back to slow 
memory writes");
-+
-+              for (; bytes > 0; bytes -= 4) {
-+                      retval = target_write_memory(chip->target,
-+                                                                              
offset, 4, 1, buffer);
-+                      if (retval != ERROR_OK)
-+                              return retval;
-+
-+                      retval = nrf52_wait_for_nvmc(chip);
-+                      if (retval != ERROR_OK)
-+                              return retval;
-+
-+                      offset += 4;
-+                      buffer += 4;
-+              }
-+
-+              return ERROR_OK;
-+      }
-+
-+      LOG_WARNING("using fast async flash loader. This is currently 
supported");
-+      LOG_WARNING("only with ST-Link and CMSIS-DAP. If you have issues, add");
-+      LOG_WARNING("\"set WORKAREASIZE 0\" before sourcing nrf52.cfg to 
disable it");
-+
-+      retval = target_write_buffer(target, write_algorithm->address,
-+                              sizeof(nrf52_flash_write_code),
-+                              nrf52_flash_write_code);
-+      if (retval != ERROR_OK)
-+              return retval;
-+
-+      /* memory buffer */
-+      while (target_alloc_working_area(target, buffer_size, &source) != 
ERROR_OK) {
-+              buffer_size /= 2;
-+              buffer_size &= ~3UL; /* Make sure it's 4 byte aligned */
-+              if (buffer_size <= 256) {
-+                      /* free working area, write algorithm already allocated 
*/
-+                      target_free_working_area(target, write_algorithm);
-+
-+                      LOG_WARNING("No large enough working area available, 
can't do block memory writes");
-+                      return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
-+              }
-+      }
-+
-+      armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
-+      armv7m_info.core_mode = ARM_MODE_THREAD;
-+
-+      init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT); /* byte count */
-+      init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);    /* buffer start 
*/
-+      init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);    /* buffer end */
-+      init_reg_param(&reg_params[3], "r3", 32, PARAM_IN_OUT); /* target 
address */
-+
-+      buf_set_u32(reg_params[0].value, 0, 32, bytes);
-+      buf_set_u32(reg_params[1].value, 0, 32, source->address);
-+      buf_set_u32(reg_params[2].value, 0, 32, source->address + source->size);
-+      buf_set_u32(reg_params[3].value, 0, 32, address);
-+
-+      retval = target_run_flash_async_algorithm(target, buffer, bytes/4, 4,
-+                      0, NULL,
-+                      4, reg_params,
-+                      source->address, source->size,
-+                      write_algorithm->address, 0,
-+                      &armv7m_info);
-+
-+      target_free_working_area(target, source);
-+      target_free_working_area(target, write_algorithm);
-+
-+      destroy_reg_param(&reg_params[0]);
-+      destroy_reg_param(&reg_params[1]);
-+      destroy_reg_param(&reg_params[2]);
-+      destroy_reg_param(&reg_params[3]);
-+
-+      return retval;
-+}
-+
-+/* Check and erase flash sectors in specified range, then start a low level 
page write.
-+   start/end must be sector aligned.
-+*/
-+static int nrf52_write_pages(struct flash_bank *bank, uint32_t start, 
uint32_t end, const uint8_t *buffer)
-+{
-+      int res;
-+      uint32_t offset;
-+      struct flash_sector *sector;
-+      struct nrf52_info *chip = bank->driver_priv;
-+      assert(chip != NULL);
-+
-+      assert(start % chip->code_page_size == 0);
-+      assert(end % chip->code_page_size == 0);
-+
-+      /* Erase all sectors */
-+      for (offset = start; offset < end; offset += chip->code_page_size) {
-+              sector = nrf52_find_sector_by_address(bank, offset);
-+
-+              if (sector == NULL) {
-+                      LOG_ERROR("Invalid sector @ 0x%08"PRIx32, offset);
-+                      return ERROR_FLASH_SECTOR_INVALID;
-+              }
-+
-+              if (sector->is_protected == 1) {
-+                      LOG_ERROR("Can't erase protected sector @ 0x%08"PRIx32, 
offset);
-+                      return ERROR_FAIL;
-+              }
-+
-+              if (sector->is_erased != 1) {   /* 1 = erased, 0= not erased, 
-1 = unknown */
-+                      res = nrf52_erase_page(bank, chip, sector);
-+                      if (res != ERROR_OK) {
-+                              LOG_ERROR("Failed to erase sector @ 
0x%08"PRIx32, sector->offset);
-+                              return res;
-+                      }
-+              }
-+              sector->is_erased = 1;
-+      }
-+
-+      res = nrf52_nvmc_write_enable(chip);
-+      if (res != ERROR_OK)
-+              return res;
-+
-+      res = nrf52_ll_flash_write(chip, start, buffer, (end - start));
-+      if (res != ERROR_OK) {
-+              LOG_ERROR("Failed to write FLASH");
-+              nrf52_nvmc_read_only(chip);
-+              return res;
-+      }
-+
-+      return nrf52_nvmc_read_only(chip);
-+}
-+
-+static int nrf52_erase(struct flash_bank *bank, int first, int last)
-+{
-+      int res = ERROR_OK;
-+      struct nrf52_info *chip = bank->driver_priv;
-+      assert(chip != NULL);
-+
-+      /* For each sector to be erased */
-+      for (int s = first; s <= last && res == ERROR_OK; s++)
-+              res = nrf52_erase_page(bank, chip, &bank->sectors[s]);
-+
-+      return res;
-+}
-+
-+static int nrf52_code_flash_write(struct flash_bank *bank,
-+                                                              struct 
nrf52_info *chip,
-+                                                              const uint8_t 
*buffer, uint32_t offset, uint32_t count)
-+{
-+      int res;
-+      /* Need to perform reads to fill any gaps we need to preserve in the 
first page,
-+         before the start of buffer, or in the last page, after the end of 
buffer */
-+      uint32_t first_page = offset / chip->code_page_size;
-+      uint32_t last_page = DIV_ROUND_UP(offset+count, chip->code_page_size);
-+
-+      uint32_t first_page_offset = first_page * chip->code_page_size;
-+      uint32_t last_page_offset = last_page * chip->code_page_size;
-+
-+      LOG_DEBUG("Padding write from 0x%08"PRIx32"-0x%08"PRIx32" as 
0x%08"PRIx32"-0x%08"PRIx32,
-+                      offset, offset+count, first_page_offset, 
last_page_offset);
-+
-+      uint32_t page_cnt = last_page - first_page;
-+      uint8_t buffer_to_flash[page_cnt * chip->code_page_size];
-+
-+      /* Fill in any space between start of first page and start of buffer */
-+      uint32_t pre = offset - first_page_offset;
-+      if (pre > 0) {
-+              res = target_read_memory(bank->target, first_page_offset, 1, 
pre, buffer_to_flash);
-+              if (res != ERROR_OK)
-+                      return res;
-+      }
-+
-+      /* Fill in main contents of buffer */
-+      memcpy(buffer_to_flash + pre, buffer, count);
-+
-+      /* Fill in any space between end of buffer and end of last page */
-+      uint32_t post = last_page_offset - (offset + count);
-+      if (post > 0) {
-+              /* Retrieve the full row contents from Flash */
-+              res = target_read_memory(bank->target, offset + count, 1, post, 
buffer_to_flash + pre + count);
-+              if (res != ERROR_OK)
-+                      return res;
-+      }
-+
-+      return nrf52_write_pages(bank, first_page_offset, last_page_offset, 
buffer_to_flash);
-+}
-+
-+static int nrf52_uicr_flash_write(struct flash_bank *bank,
-+                                                              struct 
nrf52_info *chip,
-+                                                              const uint8_t 
*buffer, uint32_t offset, uint32_t count)
-+{
-+      int res;
-+      uint32_t nrf52_uicr_size = chip->code_page_size;
-+      uint8_t uicr[nrf52_uicr_size];
-+      struct flash_sector *sector = &bank->sectors[0];
-+
-+      if ((offset + count) > nrf52_uicr_size)
-+              return ERROR_FAIL;
-+
-+      res = target_read_memory(bank->target, NRF52_UICR_BASE_ADDR, 1, 
nrf52_uicr_size, uicr);
-+
-+      if (res != ERROR_OK)
-+              return res;
-+
-+      if (sector->is_erased != 1) {
-+              res = nrf52_erase_page(bank, chip, sector);
-+              if (res != ERROR_OK)
-+                      return res;
-+      }
-+
-+      memcpy(&uicr[offset], buffer, count);
-+
-+      res = nrf52_nvmc_write_enable(chip);
-+      if (res != ERROR_OK)
-+              return res;
-+
-+      res = nrf52_ll_flash_write(chip, NRF52_UICR_BASE_ADDR, uicr, 
nrf52_uicr_size);
-+      if (res != ERROR_OK) {
-+              nrf52_nvmc_read_only(chip);
-+              return res;
-+      }
-+
-+      return nrf52_nvmc_read_only(chip);
-+}
-+
-+
-+static int nrf52_write(struct flash_bank *bank, const uint8_t *buffer,
-+                                      uint32_t offset, uint32_t count)
-+{
-+      struct nrf52_info *chip = bank->driver_priv;
-+      assert(chip != NULL);
-+
-+      return chip->bank[bank->bank_number].write(bank, chip, buffer, offset, 
count);
-+}
-+
-+
-+FLASH_BANK_COMMAND_HANDLER(nrf52_flash_bank_command)
-+{
-+      static struct nrf52_info *chip;
-+
-+      assert(bank != NULL);
-+
-+      switch (bank->base) {
-+      case NRF52_FLASH_BASE_ADDR:
-+              bank->bank_number = 0;
-+              break;
-+      case NRF52_UICR_BASE_ADDR:
-+              bank->bank_number = 1;
-+              break;
-+      default:
-+              LOG_ERROR("Invalid bank address 0x%08" PRIx32, bank->base);
-+              return ERROR_FAIL;
-+      }
-+
-+      if (!chip) {
-+              /* Create a new chip */
-+              chip = calloc(1, sizeof(*chip));
-+              assert(chip != NULL);
-+
-+              chip->target = bank->target;
-+      }
-+
-+      switch (bank->base) {
-+      case NRF52_FLASH_BASE_ADDR:
-+              chip->bank[bank->bank_number].write = nrf52_code_flash_write;
-+              break;
-+      case NRF52_UICR_BASE_ADDR:
-+              chip->bank[bank->bank_number].write = nrf52_uicr_flash_write;
-+              break;
-+      }
-+
-+      chip->bank[bank->bank_number].probed = false;
-+      bank->driver_priv = chip;
-+
-+      return ERROR_OK;
-+}
-+
-+COMMAND_HANDLER(nrf52_handle_mass_erase_command)
-+{
-+      int res;
-+      struct flash_bank *bank = NULL;
-+      struct target *target = get_current_target(CMD_CTX);
-+
-+      res = get_flash_bank_by_addr(target, NRF52_FLASH_BASE_ADDR, true, 
&bank);
-+      if (res != ERROR_OK)
-+              return res;
-+
-+      assert(bank != NULL);
-+
-+      struct nrf52_info *chip = bank->driver_priv;
-+      assert(chip != NULL);
-+
-+      res = nrf52_erase_all(chip);
-+      if (res != ERROR_OK) {
-+              LOG_ERROR("Failed to erase the chip");
-+              nrf52_protect_check(bank);
-+              return res;
-+      }
-+
-+      for (int i = 0; i < bank->num_sectors; i++)
-+              bank->sectors[i].is_erased = 1;
-+
-+      res = nrf52_protect_check(bank);
-+      if (res != ERROR_OK) {
-+              LOG_ERROR("Failed to check chip's write protection");
-+              return res;
-+      }
-+
-+      res = get_flash_bank_by_addr(target, NRF52_UICR_BASE_ADDR, true, &bank);
-+      if (res != ERROR_OK)
-+              return res;
-+
-+      bank->sectors[0].is_erased = 1;
-+
-+      return ERROR_OK;
-+}
-+
-+static int nrf52_info(struct flash_bank *bank, char *buf, int buf_size)
-+{
-+      int res;
-+      uint32_t ficr[2];
-+      struct nrf52_info *chip = bank->driver_priv;
-+      assert(chip != NULL);
-+
-+      res = target_read_u32(chip->target, NRF52_FICR_CODEPAGESIZE_ADDR, 
&ficr[0]);
-+              if (res != ERROR_OK) {
-+                      LOG_ERROR("Couldn't read NVMC_READY register");
-+                      return res;
-+              }
-+
-+      res = target_read_u32(chip->target, NRF52_FICR_CODESIZE_ADDR, &ficr[1]);
-+              if (res != ERROR_OK) {
-+                      LOG_ERROR("Couldn't read NVMC_READY register");
-+                      return res;
-+              }
-+
-+      snprintf(buf, buf_size,
-+                      "\n--------nRF52 Series Device--------\n\n"
-+                      "\n[factory information control block]\n"
-+                      "code page size: %"PRIu32"B\n"
-+                      "code memory size: %"PRIu32"kB\n",
-+                      ficr[0],
-+                      (ficr[1] * ficr[0]) / 1024);
-+
-+      return ERROR_OK;
-+}
-+
-+static const struct command_registration nrf52_exec_command_handlers[] = {
-+      {
-+              .name           = "mass_erase",
-+              .handler        = nrf52_handle_mass_erase_command,
-+              .mode           = COMMAND_EXEC,
-+              .help           = "Erase all flash contents of the chip.",
-+      },
-+      COMMAND_REGISTRATION_DONE
-+};
-+
-+static const struct command_registration nrf52_command_handlers[] = {
-+      {
-+              .name   = "nrf52",
-+              .mode   = COMMAND_ANY,
-+              .help   = "nrf52 flash command group",
-+              .usage  = "",
-+              .chain  = nrf52_exec_command_handlers,
-+      },
-+      COMMAND_REGISTRATION_DONE
-+};
-+
-+struct flash_driver nrf52_flash = {
-+      .name                   = "nrf52",
-+      .commands               = nrf52_command_handlers,
-+      .flash_bank_command     = nrf52_flash_bank_command,
-+      .info                   = nrf52_info,
-+      .erase                  = nrf52_erase,
-+      .protect                = nrf52_protect,
-+      .write                  = nrf52_write,
-+      .read                   = default_flash_read,
-+      .probe                  = nrf52_probe,
-+      .auto_probe             = nrf52_auto_probe,
-+      .erase_check    = default_flash_blank_check,
-+      .protect_check  = nrf52_protect_check,
-+};
-diff --git a/tcl/target/nrf52.cfg b/tcl/target/nrf52.cfg
-index c1cbf1a..41a22ff 100644
---- a/tcl/target/nrf52.cfg
-+++ b/tcl/target/nrf52.cfg
-@@ -10,6 +10,13 @@ if { [info exists CHIPNAME] } {
-       set _CHIPNAME nrf52
- }
- 
-+# Work-area is a space in RAM used for flash programming, by default use 16kB.
-+if { [info exists WORKAREASIZE] } {
-+        set _WORKAREASIZE $WORKAREASIZE
-+} else {
-+        set _WORKAREASIZE 0x4000
-+}
-+
- if { [info exists CPUTAPID] } {
-       set _CPUTAPID $CPUTAPID
- } else {
-@@ -22,7 +29,15 @@ set _TARGETNAME $_CHIPNAME.cpu
- target create $_TARGETNAME cortex_m -chain-position $_TARGETNAME
- 
- adapter_khz 10000
-+$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size 
$_WORKAREASIZE -work-area-backup 0
- 
- if { ![using_hla] } {
-       cortex_m reset_config sysresetreq
- }
-+
-+flash bank $_CHIPNAME.flash nrf52 0x00000000 0 1 1 $_TARGETNAME
-+flash bank $_CHIPNAME.uicr nrf52 0x10001000 0 1 1 $_TARGETNAME
-+
-+adapter_khz 1000
-+
-+$_TARGETNAME configure -event reset-end {}



reply via email to

[Prev in Thread] Current Thread [Next in Thread]