aboutsummaryrefslogtreecommitdiff
path: root/contrib
diff options
context:
space:
mode:
authorAndreas Färber <afaerber@suse.de>2016-04-17 19:26:30 +0200
committerFreddie Chopin <freddie.chopin@gmail.com>2016-05-05 07:50:59 +0100
commit44d2c7b416fe3efe57a168dd58690b4e8d4effe0 (patch)
tree61ea685f9339df5c9a16e179959dead59ad553ba /contrib
parentedf2cdc80babc2b475fd6e3079ece72d6449f2de (diff)
flash/nor: Add Infineon XMC1000 flash driver
The XMC1000 family uses a very different flash interface from XMC4000. Tested on XMC 2Go and XMC1100 Boot Kit. Change-Id: I3edaed420ef1c0fb89fdf221022c8b04163d41b3 Signed-off-by: Andreas Färber <afaerber@suse.de> Reviewed-on: http://openocd.zylin.com/3418 Reviewed-by: Freddie Chopin <freddie.chopin@gmail.com> Tested-by: jenkins
Diffstat (limited to 'contrib')
-rw-r--r--contrib/loaders/flash/xmc1xxx/Makefile30
-rw-r--r--contrib/loaders/flash/xmc1xxx/erase.S53
-rw-r--r--contrib/loaders/flash/xmc1xxx/erase.inc4
-rw-r--r--contrib/loaders/flash/xmc1xxx/erase_check.S67
-rw-r--r--contrib/loaders/flash/xmc1xxx/erase_check.inc5
-rw-r--r--contrib/loaders/flash/xmc1xxx/write.S58
-rw-r--r--contrib/loaders/flash/xmc1xxx/write.inc4
-rw-r--r--contrib/loaders/flash/xmc1xxx/xmc1xxx.S46
8 files changed, 267 insertions, 0 deletions
diff --git a/contrib/loaders/flash/xmc1xxx/Makefile b/contrib/loaders/flash/xmc1xxx/Makefile
new file mode 100644
index 00000000..066466ef
--- /dev/null
+++ b/contrib/loaders/flash/xmc1xxx/Makefile
@@ -0,0 +1,30 @@
+BIN2C = ../../../../src/helper/bin2char.sh
+
+CROSS_COMPILE ?= arm-none-eabi-
+
+CC=$(CROSS_COMPILE)gcc
+OBJCOPY=$(CROSS_COMPILE)objcopy
+OBJDUMP=$(CROSS_COMPILE)objdump
+
+all: erase.inc erase_check.inc write.inc
+
+.PHONY: clean
+
+.INTERMEDIATE: erase.elf erase_check.elf write.elf
+
+erase.elf erase_check.elf write.elf: xmc1xxx.S
+
+%.elf: %.S
+ $(CC) -static -nostartfiles $< -o $@
+
+%.lst: %.elf
+ $(OBJDUMP) -S $< > $@
+
+%.bin: %.elf
+ $(OBJCOPY) -Obinary $< $@
+
+%.inc: %.bin
+ $(BIN2C) < $< > $@
+
+clean:
+ -rm -f *.elf *.lst *.bin *.inc
diff --git a/contrib/loaders/flash/xmc1xxx/erase.S b/contrib/loaders/flash/xmc1xxx/erase.S
new file mode 100644
index 00000000..e5a4808f
--- /dev/null
+++ b/contrib/loaders/flash/xmc1xxx/erase.S
@@ -0,0 +1,53 @@
+/*
+ * Infineon XMC1000 flash sectors erase
+ *
+ * Copyright (c) 2016 Andreas Färber
+ *
+ * Based on XMC1100 AA-Step Reference Manual
+ *
+ * License: GPL-2.0+
+ */
+
+#include "xmc1xxx.S"
+
+#define DUMMY_VALUE 0x42
+
+ .macro erase_page, nvmbase, addr, tmp, tmp2
+
+ movs \tmp, #DUMMY_VALUE
+ str \tmp, [\addr]
+
+ busy_wait \nvmbase, \tmp, \tmp2
+
+ .endm
+
+
+ .macro erase, nvmbase, addr, end, tmp, tmp2
+
+ movs \tmp, #NVMPROG_ACTION_PAGE_ERASE_CONTINUOUS
+ strh \tmp, [\nvmbase, #NVMPROG]
+2001:
+ erase_page \nvmbase, \addr, \tmp, \tmp2
+
+ movs \tmp, #(NVM_PAGE_SIZE - 1)
+ adds \tmp, \tmp, #1
+ add \addr, \addr, \tmp
+ cmp \addr, \end
+ blt 2001b
+
+ movs \tmp, #NVMPROG_ACTION_IDLE
+ strh \tmp, [\nvmbase, #NVMPROG]
+
+ .endm
+
+
+ /*
+ * r0 = 0x40050000
+ * r1 = e.g. 0x10001000
+ * r2 = e.g. 0x10011000
+ * NVMPROG.ACTION = 0x00
+ */
+erase:
+ erase r0, r1, r2, r3, r4
+
+ bkpt #0
diff --git a/contrib/loaders/flash/xmc1xxx/erase.inc b/contrib/loaders/flash/xmc1xxx/erase.inc
new file mode 100644
index 00000000..b33e57d1
--- /dev/null
+++ b/contrib/loaders/flash/xmc1xxx/erase.inc
@@ -0,0 +1,4 @@
+/* Autogenerated with ../../../../src/helper/bin2char.sh */
+0xa2,0x23,0x83,0x80,0x42,0x23,0x0b,0x60,0x03,0x88,0x01,0x24,0x23,0x40,0xa3,0x42,
+0xfa,0xd0,0xff,0x23,0x01,0x33,0x19,0x44,0x91,0x42,0xf3,0xdb,0x00,0x23,0x83,0x80,
+0x00,0xbe,
diff --git a/contrib/loaders/flash/xmc1xxx/erase_check.S b/contrib/loaders/flash/xmc1xxx/erase_check.S
new file mode 100644
index 00000000..6c993443
--- /dev/null
+++ b/contrib/loaders/flash/xmc1xxx/erase_check.S
@@ -0,0 +1,67 @@
+/*
+ * Infineon XMC1000 flash sector erase check
+ *
+ * Copyright (c) 2016 Andreas Färber
+ *
+ * Based on XMC1100 AA-Step Reference Manual
+ *
+ * License: GPL-2.0+
+ */
+
+#include "xmc1xxx.S"
+
+ .macro verify_block, nvmbase, addr, tmp, tmp2
+
+ movs \tmp, #0x00
+ mvns \tmp, \tmp
+ str \tmp, [\addr, #0x0]
+ str \tmp, [\addr, #0x4]
+ str \tmp, [\addr, #0x8]
+ str \tmp, [\addr, #0xC]
+
+ busy_wait \nvmbase, \tmp, \tmp2
+
+ .endm
+
+
+ .macro erase_check, nvmbase, addr, end, tmp, tmp2
+
+ ldrh \tmp, [\nvmbase, #NVMCONF]
+ movs \tmp2, #NVMCONF_HRLEV_MASK
+ mvns \tmp2, \tmp2
+ ands \tmp, \tmp, \tmp2
+ movs \tmp2, #NVMCONF_HRLEV_HRE
+ orrs \tmp, \tmp, \tmp2
+ strh \tmp, [\nvmbase, #NVMCONF]
+
+ movs \tmp, #NVMPROG_ACTION_VERIFY_CONTINUOUS
+ strh \tmp, [\nvmbase, #NVMPROG]
+2001:
+ verify_block \nvmbase, \addr, \tmp, \tmp2
+
+ ldrh \tmp, [\nvmbase, #NVMSTATUS]
+ movs \tmp2, #NVMSTATUS_VERR_MASK
+ ands \tmp, \tmp, \tmp2
+ cmp \tmp, #NVMSTATUS_VERR_NOFAIL
+ bne 2010f
+
+ adds \addr, \addr, #NVM_BLOCK_SIZE
+ cmp \addr, \end
+ blt 2001b
+2010:
+ movs \tmp, #NVMPROG_ACTION_IDLE
+ strh \tmp, [\nvmbase, #NVMPROG]
+
+ .endm
+
+
+ /*
+ * r0 = 0x40050000
+ * r1 = e.g. 0x10001000
+ * r2 = e.g. 0x10002000
+ * NVMPROG.ACTION = 0x00
+ */
+erase_check:
+ erase_check r0, r1, r2, r3, r4
+
+ bkpt #0
diff --git a/contrib/loaders/flash/xmc1xxx/erase_check.inc b/contrib/loaders/flash/xmc1xxx/erase_check.inc
new file mode 100644
index 00000000..8fc8e0b5
--- /dev/null
+++ b/contrib/loaders/flash/xmc1xxx/erase_check.inc
@@ -0,0 +1,5 @@
+/* Autogenerated with ../../../../src/helper/bin2char.sh */
+0x03,0x89,0x06,0x24,0xe4,0x43,0x23,0x40,0x04,0x24,0x23,0x43,0x03,0x81,0xe0,0x23,
+0x83,0x80,0x00,0x23,0xdb,0x43,0x0b,0x60,0x4b,0x60,0x8b,0x60,0xcb,0x60,0x03,0x88,
+0x01,0x24,0x23,0x40,0xa3,0x42,0xfa,0xd0,0x03,0x88,0x0c,0x24,0x23,0x40,0x00,0x2b,
+0x02,0xd1,0x10,0x31,0x91,0x42,0xec,0xdb,0x00,0x23,0x83,0x80,0x00,0xbe,
diff --git a/contrib/loaders/flash/xmc1xxx/write.S b/contrib/loaders/flash/xmc1xxx/write.S
new file mode 100644
index 00000000..640f6ca9
--- /dev/null
+++ b/contrib/loaders/flash/xmc1xxx/write.S
@@ -0,0 +1,58 @@
+/*
+ * Infineon XMC1000 flash write
+ *
+ * Copyright (c) 2016 Andreas Färber
+ *
+ * Based on XMC1100 AA-Step Reference Manual
+ *
+ * License: GPL-2.0+
+ */
+
+#include "xmc1xxx.S"
+
+ .macro write_block, nvmbase, dest, src, tmp, tmp2
+
+ ldr \tmp, [\src, #0x0]
+ str \tmp, [\dest, #0x0]
+ ldr \tmp, [\src, #0x4]
+ str \tmp, [\dest, #0x4]
+ ldr \tmp, [\src, #0x8]
+ str \tmp, [\dest, #0x8]
+ ldr \tmp, [\src, #0xc]
+ str \tmp, [\dest, #0xc]
+
+ busy_wait \nvmbase, \tmp, \tmp2
+
+ .endm
+
+
+ .macro write, nvmbase, dest, src, count, tmp, tmp2
+
+ movs \tmp, #NVMPROG_ACTION_WRITE_CONTINUOUS
+ strh \tmp, [\nvmbase, #NVMPROG]
+1001:
+ write_block \nvmbase, \dest, \src, \tmp, \tmp2
+
+ adds \dest, \dest, #NVM_BLOCK_SIZE
+ adds \src, \src, #NVM_BLOCK_SIZE
+ subs \count, \count, #1
+ cmp \count, #0
+ bgt 1001b
+
+ movs \tmp, #NVMPROG_ACTION_IDLE
+ strh \tmp, [\nvmbase, #NVMPROG]
+
+ .endm
+
+
+ /*
+ * r0 = 0x40050000
+ * r1 = e.g. 0x10001000
+ * r2 = e.g. 0x20000000
+ * r3 = e.g. 1
+ * NVMPROG.ACTION = 0x00
+ */
+write:
+ write r0, r1, r2, r3, r4, r5
+
+ bkpt #0
diff --git a/contrib/loaders/flash/xmc1xxx/write.inc b/contrib/loaders/flash/xmc1xxx/write.inc
new file mode 100644
index 00000000..8272bb7e
--- /dev/null
+++ b/contrib/loaders/flash/xmc1xxx/write.inc
@@ -0,0 +1,4 @@
+/* Autogenerated with ../../../../src/helper/bin2char.sh */
+0xa1,0x24,0x84,0x80,0x14,0x68,0x0c,0x60,0x54,0x68,0x4c,0x60,0x94,0x68,0x8c,0x60,
+0xd4,0x68,0xcc,0x60,0x04,0x88,0x01,0x25,0x2c,0x40,0xac,0x42,0xfa,0xd0,0x10,0x31,
+0x10,0x32,0x01,0x3b,0x00,0x2b,0xed,0xdc,0x00,0x24,0x84,0x80,0x00,0xbe,
diff --git a/contrib/loaders/flash/xmc1xxx/xmc1xxx.S b/contrib/loaders/flash/xmc1xxx/xmc1xxx.S
new file mode 100644
index 00000000..dfe7d3f4
--- /dev/null
+++ b/contrib/loaders/flash/xmc1xxx/xmc1xxx.S
@@ -0,0 +1,46 @@
+/*
+ * Infineon XMC1000 flash
+ *
+ * Copyright (c) 2016 Andreas Färber
+ *
+ * Based on XMC1100 AA-Step Reference Manual
+ *
+ * License: GPL-2.0+
+ */
+
+ .text
+ .syntax unified
+ .cpu cortex-m0
+ .thumb
+ .thumb_func
+
+#define NVMSTATUS 0x00
+#define NVMPROG 0x04
+#define NVMCONF 0x08
+
+#define NVMSTATUS_BUSY (1 << 0)
+#define NVMSTATUS_VERR_NOFAIL (0x0 << 2)
+#define NVMSTATUS_VERR_MASK (0x3 << 2)
+
+#define NVMPROG_ACTION_IDLE 0x00
+#define NVMPROG_ACTION_WRITE_CONTINUOUS 0xA1
+#define NVMPROG_ACTION_PAGE_ERASE_CONTINUOUS 0xA2
+#define NVMPROG_ACTION_VERIFY_CONTINUOUS 0xE0
+
+#define NVMCONF_HRLEV_NR (0x0 << 1)
+#define NVMCONF_HRLEV_HRE (0x2 << 1)
+#define NVMCONF_HRLEV_MASK (0x3 << 1)
+
+#define NVM_WORD_SIZE 4
+#define NVM_BLOCK_SIZE (4 * NVM_WORD_SIZE)
+#define NVM_PAGE_SIZE (16 * NVM_BLOCK_SIZE)
+
+ .macro busy_wait, nvmbase, tmp, tmp2
+1:
+ ldrh \tmp, [\nvmbase, #NVMSTATUS]
+ movs \tmp2, #NVMSTATUS_BUSY
+ ands \tmp, \tmp, \tmp2
+ cmp \tmp, \tmp2
+ beq 1b
+
+ .endm