aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/openocd.texi6
-rw-r--r--src/flash/nor/lpc2000.c26
-rw-r--r--tcl/target/lpc8nxx.cfg81
-rw-r--r--tcl/target/nhs31xx.cfg4
4 files changed, 113 insertions, 4 deletions
diff --git a/doc/openocd.texi b/doc/openocd.texi
index c36ec30..83f6052 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -5900,8 +5900,8 @@ Command disables watchdog timer.
@deffn {Flash Driver} lpc2000
This is the driver to support internal flash of all members of the
LPC11(x)00 and LPC1300 microcontroller families and most members of
-the LPC800, LPC1500, LPC1700, LPC1800, LPC2000, LPC4000 and LPC54100
-microcontroller families from NXP.
+the LPC800, LPC1500, LPC1700, LPC1800, LPC2000, LPC4000, LPC54100,
+LPC8Nxx and NHS31xx microcontroller families from NXP.
@quotation Note
There are LPC2000 devices which are not supported by the @var{lpc2000}
@@ -5926,7 +5926,7 @@ LPC43x[2357])
@option{lpc54100} (LPC541xx)
@option{lpc4000} (LPC40xx)
or @option{auto} - automatically detects flash variant and size for LPC11(x)00,
-LPC8xx, LPC13xx, LPC17xx and LPC40xx
+LPC8xx, LPC13xx, LPC17xx, LPC40xx, LPC8Nxx and NHS31xx
@item @var{clock_kHz} ... the frequency, in kiloHertz,
at which the core is running
@item @option{calc_checksum} ... optional (but you probably want to provide this!),
diff --git a/src/flash/nor/lpc2000.c b/src/flash/nor/lpc2000.c
index 77beac1..53ece42 100644
--- a/src/flash/nor/lpc2000.c
+++ b/src/flash/nor/lpc2000.c
@@ -12,6 +12,9 @@
* by Nemui Trinomius *
* nemuisan_kawausogasuki@live.jp *
* *
+ * LPC8N04/HNS31xx support Copyright (C) 2018 *
+ * by Jean-Christian de Rivaz jcdr [at] innodelec [dot] ch *
+ * *
* 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 *
@@ -38,7 +41,7 @@
/**
* @file
- * flash programming support for NXP LPC8xx,LPC1xxx,LPC4xxx,LP5410x and LPC2xxx devices.
+ * flash programming support for NXP LPC8xx,LPC1xxx,LPC4xxx,LP5410x,LPC2xxx and NHS31xx devices.
*
* @todo Provide a way to update CCLK after declaring the flash bank. The value which is correct after chip reset will
* rarely still work right after the clocks switch to use the PLL (e.g. 4MHz --> 100 MHz).
@@ -77,6 +80,8 @@
* lpc800:
* - 810 | 1 | 2 (tested with LPC810/LPC811/LPC812)
* - 822 | 4 (tested with LPC824)
+ * - 8N04
+ * - NHS31xx (tested with NHS3100)
*
* lpc1100:
* - 11xx
@@ -111,6 +116,8 @@
* - 408x
* - 81x
* - 82x
+ * - 8N04
+ * - NHS31xx
*/
/* Part IDs for autodetection */
@@ -257,6 +264,11 @@
#define LPC824_201 0x00008241
#define LPC824_201_1 0x00008242
+#define LPC8N04 0x00008A04
+#define NHS3100 0x4e310020
+#define NHS3152 0x4e315220
+#define NHS3153 0x4e315320 /* Only specified in Rev.1 of the datasheet */
+
#define IAP_CODE_LEN 0x34
#define LPC11xx_REG_SECTORS 24
@@ -526,6 +538,10 @@ static int lpc2000_build_sector_list(struct flash_bank *bank)
case 16 * 1024:
bank->num_sectors = 16;
break;
+ case 30 * 1024:
+ lpc2000_info->cmd51_max_buffer = 1024; /* For LPC8N04 and NHS31xx, have 8kB of SRAM */
+ bank->num_sectors = 30; /* There have only 30kB of writable Flash out of 32kB */
+ break;
case 32 * 1024:
lpc2000_info->cmd51_max_buffer = 1024; /* For LPC824, has 8kB of SRAM */
bank->num_sectors = 32;
@@ -1452,6 +1468,14 @@ static int lpc2000_auto_probe_flash(struct flash_bank *bank)
bank->size = 32 * 1024;
break;
+ case LPC8N04:
+ case NHS3100:
+ case NHS3152:
+ case NHS3153:
+ lpc2000_info->variant = lpc800;
+ bank->size = 30 * 1024;
+ break;
+
default:
LOG_ERROR("BUG: unknown Part ID encountered: 0x%" PRIx32, part_id);
exit(-1);
diff --git a/tcl/target/lpc8nxx.cfg b/tcl/target/lpc8nxx.cfg
new file mode 100644
index 0000000..b933290
--- /dev/null
+++ b/tcl/target/lpc8nxx.cfg
@@ -0,0 +1,81 @@
+# NXP LPC8Nxx NHS31xx Cortex-M0+ with 8kB SRAM
+# Copyright (C) 2018 by Jean-Christian de Rivaz
+# Based on NXP proposal https://community.nxp.com/message/1011149
+# Many thanks to Dries Moors from NXP support.
+# SWD only transport
+
+source [find target/swj-dp.tcl]
+source [find mem_helper.tcl]
+
+if { [info exists CHIPNAME] } {
+ set _CHIPNAME $CHIPNAME
+} else {
+ set _CHIPNAME lpc8nxx
+}
+
+swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id 0
+dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu
+
+set _TARGETNAME $_CHIPNAME.cpu
+target create $_TARGETNAME cortex_m -endian little -dap $_CHIPNAME.dap
+if {![using_hla]} {
+ # If srst is not fitted use SYSRESETREQ to perform a soft reset
+ cortex_m reset_config sysresetreq
+}
+adapter_nsrst_delay 100
+
+$_TARGETNAME configure -work-area-phys 0x10000000 -work-area-size 0x1ff0 -work-area-backup 0
+
+flash bank $_CHIPNAME.flash lpc2000 0x0 0x7800 0 0 $_TARGETNAME lpc800 500
+
+echo "*********************************************************************************"
+echo "* !!!!! IMPORTANT NOTICE FOR LPC8Nxx and NHS31xx CHIPS !!!!!"
+echo "* When this IC is in power-off or peep power down mode, the SWD HW block is also"
+echo "* unpowered. These modes can be entered by firmware. The default firmware image"
+echo "* (flashed in production) makes use of this. Best is to avoid these power modes"
+echo "* during development, and only later add them when the functionality is complete."
+echo "* Hardware reset or NFC field are the only ways to connect in case the SWD is"
+echo "* powered off. OpenOCD can do a hardware reset if you wire the adapter SRST"
+echo "* signal to the chip RESETN pin and add the following in your configuration:"
+echo "* reset_config srst_only; flash init; catch init; reset"
+echo "* But if the actual firmware immediately set the power down mode after reset,"
+echo "* OpenOCD might be not fast enough to halt the CPU before the SWD lost power. In"
+echo "* that case the only solution is to apply a NFC field to keep the SWD powered."
+echo "*********************************************************************************"
+
+# Using soft-reset 'reset_config none' is strongly discouraged.
+# RESETN sets the system clock to 500 kHz. Unlike soft-reset does not.
+# Set the system clock to 500 kHz before reset to simulate the functionality of hw reset.
+#
+proc set_sysclk_500khz {} {
+ set SYSCLKCTRL 0x40048020
+ set SYSCLKUEN 0x40048024
+ mww $SYSCLKUEN 0
+ mmw $SYSCLKCTRL 0x8 0xe
+ mww $SYSCLKUEN 1
+ echo "Notice: sysclock set to 500kHz."
+}
+
+# Do not remap the ARM interrupt vectors to anything but the beginning ot the flash.
+# Table System memory remap register (SYSMEMREMAP, address 0x4004 8000) bit description
+# Bit Symbol Value Description
+# 0 map - interrupt vector remap. 0 after boot.
+# 0 interrupt vector reside in Flash
+# 1 interrupt vector reside in SRAM
+# 5:1 offset - system memory remap offset. 00000b after boot.
+# 00000b interrupt vectors in flash or remapped to SRAM but no offset
+# 00001b -
+# 00111b interrupt vectors offset in flash or SRAM to 1K word segment
+# 01000b -
+# 11111b interrupt vectors offset in flash to 1K word segment 8 to 31
+# 31:6 reserved
+#
+proc set_no_remap {} {
+ mww 0x40048000 0x00
+ echo "Notice: interrupt vector set to no remap."
+}
+
+$_TARGETNAME configure -event reset-init {
+ set_sysclk_500khz
+ set_no_remap
+}
diff --git a/tcl/target/nhs31xx.cfg b/tcl/target/nhs31xx.cfg
new file mode 100644
index 0000000..964be7b
--- /dev/null
+++ b/tcl/target/nhs31xx.cfg
@@ -0,0 +1,4 @@
+# NXP NHS31xx Cortex-M0+ with 8kB SRAM
+
+set CHIPNAME nhs31xx
+source [find target/lpc8nxx.cfg]