diff options
author | Andreas Färber <afaerber@suse.de> | 2016-04-17 19:26:30 +0200 |
---|---|---|
committer | Freddie Chopin <freddie.chopin@gmail.com> | 2016-05-05 07:50:59 +0100 |
commit | 44d2c7b416fe3efe57a168dd58690b4e8d4effe0 (patch) | |
tree | 61ea685f9339df5c9a16e179959dead59ad553ba /contrib | |
parent | edf2cdc80babc2b475fd6e3079ece72d6449f2de (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/Makefile | 30 | ||||
-rw-r--r-- | contrib/loaders/flash/xmc1xxx/erase.S | 53 | ||||
-rw-r--r-- | contrib/loaders/flash/xmc1xxx/erase.inc | 4 | ||||
-rw-r--r-- | contrib/loaders/flash/xmc1xxx/erase_check.S | 67 | ||||
-rw-r--r-- | contrib/loaders/flash/xmc1xxx/erase_check.inc | 5 | ||||
-rw-r--r-- | contrib/loaders/flash/xmc1xxx/write.S | 58 | ||||
-rw-r--r-- | contrib/loaders/flash/xmc1xxx/write.inc | 4 | ||||
-rw-r--r-- | contrib/loaders/flash/xmc1xxx/xmc1xxx.S | 46 |
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 |