aboutsummaryrefslogtreecommitdiff
path: root/contrib/loaders
diff options
context:
space:
mode:
authorAndreas Färber <afaerber@suse.de>2015-04-20 02:51:23 +0200
committerAndreas Fritiofson <andreas.fritiofson@gmail.com>2016-02-29 19:40:20 +0000
commit43ff5acd45017fd9828cc56f54b929e600956c3b (patch)
treef6642b088a641491ce0c8de96423cb1f45b6f1f2 /contrib/loaders
parent13618ab99426b0786d6825e5816a3b082f8aa973 (diff)
flash: New Spansion FM4 flash driver
The Spansion FM4 family of microcontrollers does not offer a way to identify the chip model nor the flash size, except for Dual Flash vs. regular layout. Therefore the family is passed as argument and wildcard-matched - MB9BFx6x and S6E2CC families are supported. Iterations showed that ... 1) Just doing the flash command sequence from SRAM loader code for each half-word took 20 minutes for an 8 KB block. 2) Doing the busy-wait in the loader merely reduced the time to 19 minutes. 3) Significant performance gains were achieved by looping in loader code rather than in OpenOCD and by maximizing the batch size across sectors, getting us down to ~2 seconds for 8 KB and ~2.5 minutes for 1.1 MB. (Tested with SK-FM4-176L-S6E2CC-ETH v11, CMSIS-DAP v23.) gcc, objcopy -Obinary and bin2char.sh are used for automating the integration of hand-written assembler snippets. Change-Id: I092c81074662534f50b71b91d54eb8e0098fec76 Signed-off-by: Andreas Färber <afaerber@suse.de> Reviewed-on: http://openocd.zylin.com/2190 Tested-by: jenkins Reviewed-by: Spencer Oliver <spen@spen-soft.co.uk>
Diffstat (limited to 'contrib/loaders')
-rw-r--r--contrib/loaders/flash/fm4/Makefile30
-rw-r--r--contrib/loaders/flash/fm4/erase.S77
-rw-r--r--contrib/loaders/flash/fm4/erase.inc7
-rw-r--r--contrib/loaders/flash/fm4/fm4.h19
-rw-r--r--contrib/loaders/flash/fm4/write.S85
-rw-r--r--contrib/loaders/flash/fm4/write.inc7
6 files changed, 225 insertions, 0 deletions
diff --git a/contrib/loaders/flash/fm4/Makefile b/contrib/loaders/flash/fm4/Makefile
new file mode 100644
index 00000000..eb4cbd0c
--- /dev/null
+++ b/contrib/loaders/flash/fm4/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 write.inc
+
+.PHONY: clean
+
+.INTERMEDIATE: erase.elf write.elf
+
+erase.elf write.elf: fm4.h
+
+%.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/fm4/erase.S b/contrib/loaders/flash/fm4/erase.S
new file mode 100644
index 00000000..6fdf81dc
--- /dev/null
+++ b/contrib/loaders/flash/fm4/erase.S
@@ -0,0 +1,77 @@
+/*
+ * Spansion FM4 flash sector erase algorithm
+ *
+ * Copyright (c) 2015 Andreas Färber
+ *
+ * Based on S6E2CC_MN709-00007 for S6E2CC/C5/C4/C3/C2/C1 series
+ */
+
+#include "fm4.h"
+
+#define RESULT_OKAY 0
+#define RESULT_NONE 1
+#define RESULT_TIMEOUT 2
+
+ .macro busy_wait, res, addr, tmp1, tmp2, tmp3
+
+ ldrb \tmp1, [\addr] /* ignore */
+1001:
+ ldrb \tmp1, [\addr]
+ ldrb \tmp2, [\addr]
+
+ and \tmp3, \tmp1, #FLASH_TOGG
+ and \tmp2, \tmp2, #FLASH_TOGG
+ cmp \tmp3, \tmp2
+ beq 1010f
+
+ and \tmp2, \tmp1, #FLASH_TLOV
+ cmp \tmp2, #0
+ beq 1001b
+
+ ldrb \tmp1, [\addr]
+ ldrb \tmp2, [\addr]
+
+ and \tmp3, \tmp1, #FLASH_TOGG
+ and \tmp2, \tmp2, #FLASH_TOGG
+ cmp \tmp3, \tmp2
+ beq 1010f
+
+ mov \res, #RESULT_TIMEOUT
+ bkpt #0
+1010:
+ mov \res, #RESULT_OKAY
+
+ .endm
+
+
+ .macro erase, cmdseqaddr1, cmdseqaddr2, sa, res, tmp1, tmp2, tmp3
+
+ mov \res, #RESULT_NONE
+
+ mov \tmp1, #0xAA
+ strh \tmp1, [\cmdseqaddr1]
+ mov \tmp2, #0x55
+ strh \tmp2, [\cmdseqaddr2]
+ mov \tmp3, #0x80
+ strh \tmp3, [\cmdseqaddr1]
+ strh \tmp1, [\cmdseqaddr1]
+ strh \tmp2, [\cmdseqaddr2]
+ mov \tmp3, #0x30
+ strh \tmp3, [\sa]
+
+ busy_wait \res, \sa, \tmp1, \tmp2, \tmp3
+
+ .endm
+
+
+ /* r0 = 0xAA8
+ * r1 = 0x554
+ * r2 = SA
+ * r3 = result
+ */
+erase:
+ erase r0, r1, r2, r3, r4, r5, r6
+
+ bkpt #0
+
+data:
diff --git a/contrib/loaders/flash/fm4/erase.inc b/contrib/loaders/flash/fm4/erase.inc
new file mode 100644
index 00000000..9f380674
--- /dev/null
+++ b/contrib/loaders/flash/fm4/erase.inc
@@ -0,0 +1,7 @@
+/* Autogenerated with ../../../../src/helper/bin2char.sh */
+0x4f,0xf0,0x01,0x03,0x4f,0xf0,0xaa,0x04,0x04,0x80,0x4f,0xf0,0x55,0x05,0x0d,0x80,
+0x4f,0xf0,0x80,0x06,0x06,0x80,0x04,0x80,0x0d,0x80,0x4f,0xf0,0x30,0x06,0x16,0x80,
+0x14,0x78,0x14,0x78,0x15,0x78,0x04,0xf0,0x40,0x06,0x05,0xf0,0x40,0x05,0xae,0x42,
+0x0e,0xd0,0x04,0xf0,0x20,0x05,0x00,0x2d,0xf3,0xd0,0x14,0x78,0x15,0x78,0x04,0xf0,
+0x40,0x06,0x05,0xf0,0x40,0x05,0xae,0x42,0x02,0xd0,0x4f,0xf0,0x02,0x03,0x00,0xbe,
+0x4f,0xf0,0x00,0x03,0x00,0xbe,
diff --git a/contrib/loaders/flash/fm4/fm4.h b/contrib/loaders/flash/fm4/fm4.h
new file mode 100644
index 00000000..603aac87
--- /dev/null
+++ b/contrib/loaders/flash/fm4/fm4.h
@@ -0,0 +1,19 @@
+/*
+ * Spansion FM4 flash macros
+ *
+ * Copyright (c) 2015 Andreas Färber
+ *
+ * Based on S6E2CC_MN709-00007 for S6E2CC/C5/C4/C3/C2/C1 series
+ */
+
+ .text
+ .syntax unified
+ .cpu cortex-m4
+ .thumb
+ .thumb_func
+
+
+#define FLASH_DPOL (1 << 7)
+#define FLASH_TOGG (1 << 6)
+#define FLASH_TLOV (1 << 5)
+#define FLASH_TOGG2 (1 << 2)
diff --git a/contrib/loaders/flash/fm4/write.S b/contrib/loaders/flash/fm4/write.S
new file mode 100644
index 00000000..a8d01cde
--- /dev/null
+++ b/contrib/loaders/flash/fm4/write.S
@@ -0,0 +1,85 @@
+/*
+ * Spansion FM4 flash write algorithm
+ *
+ * Copyright (c) 2015 Andreas Färber
+ *
+ * Based on S6E2CC_MN709-00007 for S6E2CC/C5/C4/C3/C2/C1 series
+ */
+
+#include "fm4.h"
+
+#define RESULT_OKAY 0
+#define RESULT_NONE 1
+#define RESULT_TIMEOUT 2
+
+ .macro busy_wait, res, addr, data, tmp1, tmp2, tmp3
+
+ ldrb \tmp1, [\addr] /* ignore */
+ and \tmp2, \data, #FLASH_DPOL
+1001:
+ ldrb \tmp1, [\addr]
+ and \tmp3, \tmp1, #FLASH_DPOL
+ cmp \tmp3, \tmp2
+ beq 1010f
+
+ and \tmp3, \tmp1, #FLASH_TLOV
+ cmp \tmp3, #0
+ beq 1001b
+
+ ldrb \tmp1, [\addr]
+ and \tmp3, \tmp1, #FLASH_DPOL
+ cmp \tmp3, \tmp2
+ beq 1010f
+
+ mov \res, #RESULT_TIMEOUT
+ bkpt #0
+1010:
+ .endm
+
+
+ .macro write_one, res, cmdseqaddr1, cmdseqaddr2, pa, pd, tmp1, tmp2, tmp3
+
+ mov \tmp1, #0xAA
+ strh \tmp1, [\cmdseqaddr1]
+ mov \tmp1, #0x55
+ strh \tmp1, [\cmdseqaddr2]
+ mov \tmp1, #0xA0
+ strh \tmp1, [\cmdseqaddr1]
+ strh \pd, [\pa]
+
+ busy_wait \res, \pa, \pd, \tmp1, \tmp2, \tmp3
+
+ .endm
+
+
+ .macro write, cmdseqaddr1, cmdseqaddr2, dest, src, cnt, res, tmp1, tmp2, tmp3, tmp4
+
+ mov \res, #RESULT_NONE
+2001:
+ cbz \cnt, 2010f
+
+ ldrh \tmp1, [\src]
+ write_one \res, \cmdseqaddr1, \cmdseqaddr2, \dest, \tmp1, \tmp2, \tmp3, \tmp4
+
+ sub \cnt, \cnt, #1
+ add \dest, \dest, #2
+ add \src, \src, #2
+ b 2001b
+2010:
+ mov \res, #RESULT_OKAY
+ .endm
+
+
+ /* r0 = 0xAA8
+ * r1 = 0x554
+ * r2 = dest
+ * r3 = src
+ * r4 = cnt
+ * r5 = result
+ */
+write:
+ write r0, r1, r2, r3, r4, r5, r6, r7, r8, r9
+
+ bkpt #0
+
+data:
diff --git a/contrib/loaders/flash/fm4/write.inc b/contrib/loaders/flash/fm4/write.inc
new file mode 100644
index 00000000..3d8472ba
--- /dev/null
+++ b/contrib/loaders/flash/fm4/write.inc
@@ -0,0 +1,7 @@
+/* Autogenerated with ../../../../src/helper/bin2char.sh */
+0x4f,0xf0,0x01,0x05,0x34,0xb3,0x1e,0x88,0x4f,0xf0,0xaa,0x07,0x07,0x80,0x4f,0xf0,
+0x55,0x07,0x0f,0x80,0x4f,0xf0,0xa0,0x07,0x07,0x80,0x16,0x80,0x17,0x78,0x06,0xf0,
+0x80,0x08,0x17,0x78,0x07,0xf0,0x80,0x09,0xc1,0x45,0x0c,0xd0,0x07,0xf0,0x20,0x09,
+0xb9,0xf1,0x00,0x0f,0xf5,0xd0,0x17,0x78,0x07,0xf0,0x80,0x09,0xc1,0x45,0x02,0xd0,
+0x4f,0xf0,0x02,0x05,0x00,0xbe,0xa4,0xf1,0x01,0x04,0x02,0xf1,0x02,0x02,0x03,0xf1,
+0x02,0x03,0xd7,0xe7,0x4f,0xf0,0x00,0x05,0x00,0xbe,