commit 7a6f4f31f17ce3b396051f59fdc4eee848528912
parent c26905de84b9396512331de9d52e30e21fe49c7f
Author: Brian Swetland <swetland@playground.global>
Date: Wed, 24 Feb 2016 16:48:24 -0800
debugger: stm32f0xx flash agent
Diffstat:
4 files changed, 195 insertions(+), 8 deletions(-)
diff --git a/Makefile b/Makefile
@@ -39,11 +39,12 @@ $(call program,debugger,$(SRCS))
ifneq ($(TOOLCHAIN),)
# if there's a cross-compiler, build agents from source
-$(call agent, lpclink2, 0x10080400)
-$(call agent, stm32f4xx, 0x20000400)
-$(call agent, lpc13xx, 0x10000400)
-$(call agent, lpc15xx, 0x02000400)
-$(call agent, cc13xx, 0x20000400)
+$(call agent, lpclink2, 0x10080400, M3)
+$(call agent, stm32f4xx, 0x20000400, M3)
+$(call agent, stm32f0xx, 0x20000400, M0)
+$(call agent, lpc13xx, 0x10000400, M3)
+$(call agent, lpc15xx, 0x02000400, M3)
+$(call agent, cc13xx, 0x20000400, M3)
# tool to pack the agents into a source file
SRCS := tools/mkbuiltins.c
diff --git a/agents/stm32f0xx.c b/agents/stm32f0xx.c
@@ -0,0 +1,154 @@
+// agents/stm-main.c
+//
+// Copyright 2015 Brian Swetland <swetland@frotz.net>
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#define LOADADDR 0x20000400
+
+#define FLASH_BASE 0x08000000
+#define FLASH_SIZE 0x00004000
+
+#include <agent/flash.h>
+#include <fw/io.h>
+
+#define _FLASH_BASE 0x40022000
+#define FLASH_ACR (_FLASH_BASE + 0x00)
+
+#define FLASH_KEYR (_FLASH_BASE + 0x04)
+#define FLASH_KEYR_KEY1 0x45670123
+#define FLASH_KEYR_KEY2 0xCDEF89AB
+
+#define FLASH_SR (_FLASH_BASE + 0x0C)
+#define FLASH_SR_EOP (1 << 5) // end of operation
+#define FLASH_SR_WP_ERR (1 << 4) // write protect error
+#define FLASH_SR_PG_ERR (1 << 2) // programming error
+#define FLASH_SR_BSY (1 << 0) // busy
+#define FLASH_SR_ERR_MASK (FLASH_SR_WP_ERR | FLASH_SR_PG_ERR)
+
+#define FLASH_CR (_FLASH_BASE + 0x10)
+#define FLASH_CR_OBL_LAUNCH (1 << 13) // reload option byte & reset system
+#define FLASH_CR_EOPIE (1 << 12) // enable end-of-op irq
+#define FLASH_CR_ERRIE (1 << 10) // enable error irq
+#define FLASH_CR_OPTWRE (1 << 9) // option byte write enable
+#define FLASH_CR_LOCK (1 << 7) // indicates flash is locked
+#define FLASH_CR_STRT (1 << 6) // start erase operation
+#define FLASH_CR_OPTER (1 << 5) // option byte erase
+#define FLASH_CR_OPTPG (1 << 4) // option byte program
+#define FLASH_CR_MER (1 << 2) // mass erase
+#define FLASH_CR_PER (1 << 1) // page erase
+#define FLASH_CR_PG (1 << 0) // programming
+#define FLASH_CR_MASK (~0x000036F7) // bits to not modify
+
+#define FLASH_AR (_FLASH_BASE + 0x14)
+
+static unsigned FLASH_PAGE_SIZE = 1024;
+
+int flash_agent_setup(flash_agent *agent) {
+
+ // check MCU ID
+ switch (readl(0x40015800) & 0xFFF) {
+ case 0x444: // F03x
+ case 0x445: // F04x
+ case 0x440: // F05x
+ break;
+ case 0x448: // F07x
+ case 0x442: // F09x
+ FLASH_PAGE_SIZE = 2048;
+ break;
+ default:
+ // unknown part
+ return ERR_INVALID;
+ }
+
+ // check flash size
+ agent->flash_size = readw(0x1FFFF7CC) * 1024;
+
+ writel(FLASH_KEYR_KEY1, FLASH_KEYR);
+ writel(FLASH_KEYR_KEY2, FLASH_KEYR);
+ if (readl(FLASH_CR) & FLASH_CR_LOCK) {
+ return ERR_FAIL;
+ } else {
+ return ERR_NONE;
+ }
+}
+
+int flash_agent_erase(u32 flash_addr, u32 length) {
+ u32 cr;
+ int n;
+ if (flash_addr & (FLASH_PAGE_SIZE - 1)) {
+ return ERR_ALIGNMENT;
+ }
+ cr = readl(FLASH_CR) & FLASH_CR_MASK;
+
+ while (length > 0) {
+ if (length > FLASH_PAGE_SIZE) {
+ length -= FLASH_PAGE_SIZE;
+ } else {
+ length = 0;
+ }
+ writel(cr | FLASH_CR_PER, FLASH_CR);
+ writel(flash_addr, FLASH_AR);
+ writel(cr | FLASH_CR_PER | FLASH_CR_STRT, FLASH_CR);
+ while (readl(FLASH_SR) & FLASH_SR_BSY) ;
+ for (n = 0; n < FLASH_PAGE_SIZE; n += 4) {
+ if (readl(flash_addr + n) != 0xFFFFFFFF) {
+ return ERR_FAIL;
+ }
+ }
+ flash_addr += FLASH_PAGE_SIZE;
+ }
+ return ERR_NONE;
+}
+
+int flash_agent_write(u32 flash_addr, const void *_data, u32 length) {
+ const unsigned short *data = _data;
+ u32 v, cr;
+ if ((flash_addr & 3) || (length & 3)) {
+ return ERR_ALIGNMENT;
+ }
+ cr = readl(FLASH_CR) & FLASH_CR_MASK;
+ writel(cr | FLASH_CR_PG, FLASH_CR);
+ while (length > 0) {
+ writew(*data, flash_addr);
+ while ((v = readl(FLASH_SR)) & FLASH_SR_BSY) ;
+ if (readw(flash_addr) != *data) {
+ writel(cr, FLASH_CR);
+ return ERR_FAIL;
+ }
+ data++;
+ length -= 2;
+ flash_addr += 2;
+ }
+ writel(cr, FLASH_CR);
+ return ERR_NONE;
+}
+
+int flash_agent_ioctl(u32 op, void *ptr, u32 arg0, u32 arg1) {
+ return ERR_INVALID;
+}
+
+const flash_agent __attribute((section(".vectors"))) FlashAgent = {
+ .magic = AGENT_MAGIC,
+ .version = AGENT_VERSION,
+ .flags = 0,
+ .load_addr = LOADADDR,
+ .data_addr = LOADADDR + 0x400,
+ .data_size = 0x1000,
+ .flash_addr = FLASH_BASE,
+ .flash_size = FLASH_SIZE,
+ .setup = flash_agent_setup,
+ .erase = flash_agent_erase,
+ .write = flash_agent_write,
+ .ioctl = flash_agent_ioctl,
+};
diff --git a/build/build.mk b/build/build.mk
@@ -9,10 +9,13 @@ TARGET_CC := $(TOOLCHAIN)gcc
TARGET_OBJCOPY := $(TOOLCHAIN)objcopy
TARGET_OBJDUMP := $(TOOLCHAIN)objdump
+ARCH_M3_CFLAGS := -mcpu=cortex-m3 -mthumb
+ARCH_M0_CFLAGS := -mcpu=cortex-m0 -mthumb
+
TARGET_CFLAGS := -g -Os -Wall
TARGET_CFLAGS += -Wno-unused-but-set-variable
TARGET_CFLAGS += -I. -Iinclude
-TARGET_CFLAGS += -mcpu=cortex-m3 -mthumb -mthumb-interwork
+#TARGET_CFLAGS += -mcpu=cortex-m3 -mthumb -mthumb-interwork
TARGET_CFLAGS += -ffunction-sections -fdata-sections
TARGET_CFLAGS += -fno-builtin -nostdlib
@@ -54,7 +57,7 @@ out/agent-%.lst: out/agent-%.elf
out/agent-%.elf: agents/%.c
@mkdir -p $(dir $@)
@echo compile $@
- $(QUIET)$(TARGET_CC) $(TARGET_CFLAGS) -Wl,--script=build/agent.ld -Wl,-Ttext=$(LOADADDR) -o $@ $<
+ $(QUIET)$(TARGET_CC) $(TARGET_CFLAGS) $(ARCH_$(ARCH)_CFLAGS) -Wl,--script=build/agent.ld -Wl,-Ttext=$(LOADADDR) -o $@ $<
out/%.o: %.c
@mkdir -p $(dir $@)
@@ -75,5 +78,6 @@ program = $(eval $(call _program,$1,$(patsubst %.c,out/%.o,$2),$(patsubst %.c,ou
agent = $(eval AGENTS += $(strip $1))\
$(eval ALL += $(patsubst %,out/agent-%.bin,$(strip $1)))\
$(eval ALL += $(patsubst %,out/agent-%.lst,$(strip $1)))\
-$(eval out/agent-$(strip $1).elf: LOADADDR := $(strip $2))
+$(eval out/agent-$(strip $1).elf: LOADADDR := $(strip $2))\
+$(eval out/agent-$(strip $1).elf: ARCH := $(strip $3))
diff --git a/tools/builtins.c b/tools/builtins.c
@@ -69,6 +69,34 @@ static struct {
"\x00\x00\x06\x00\x00\x00\x08\x00\x00\x00\x0A\x00\x00\x00\x0C\x00"
"\x00\x00\x0E\x00\x00\x00\x10\x00"
},
+ { "agent-stm32f0xx.bin", 408,
+ "\x66\x61\x77\x42\x00\x00\x01\x00\x00\x00\x00\x00\x00\x04\x00\x20"
+ "\x00\x08\x00\x20\x00\x10\x00\x00\x00\x00\x00\x08\x00\x40\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x41\x04\x00\x20\xAD\x04\x00\x20\x29\x05\x00\x20\x8D\x05\x00\x20"
+ "\x12\x4B\x13\x4A\x1B\x68\x1B\x05\x1B\x0D\x9B\x18\x08\x2B\x1A\xD8"
+ "\x01\x22\x9A\x40\x13\x00\x31\x22\x13\x42\x06\xD1\xD3\x32\x13\x42"
+ "\x11\xD0\x80\x22\x0B\x4B\x12\x01\x1A\x60\x0B\x4B\x0B\x4A\x1B\x88"
+ "\x9B\x02\xC3\x61\x0A\x4B\x1A\x60\x0A\x4A\x1A\x60\x0A\x4B\x18\x68"
+ "\x00\x06\xC0\x17\x01\xE0\x02\x20\x40\x42\x70\x47\x00\x58\x01\x40"
+ "\xC0\xFB\xFF\xFF\x94\x05\x00\x20\xCC\xF7\xFF\x1F\x23\x01\x67\x45"
+ "\x04\x20\x02\x40\xAB\x89\xEF\xCD\x10\x20\x02\x40\xF7\xB5\x19\x4A"
+ "\x13\x68\x01\x3B\x18\x42\x2A\xD1\x17\x4C\x18\x4B\x25\x68\x42\x26"
+ "\x2B\x40\x02\x25\x1D\x43\x33\x43\x01\x93\x00\x29\x1D\xD0\x16\x68"
+ "\xB1\x42\x01\xD9\x89\x1B\x00\xE0\x00\x21\x11\x4E\x25\x60\x30\x60"
+ "\x10\x4E\x01\x9B\xB4\x46\x01\x26\x23\x60\x67\x46\x3F\x68\x37\x42"
+ "\xFB\xD1\x06\x00\x17\x68\x33\x1A\x9F\x42\x04\xD9\x08\xCE\x01\x33"
+ "\xF9\xD0\x01\x20\x04\xE0\xC0\x19\xDF\xE7\x08\x00\x01\xE0\x03\x20"
+ "\x40\x42\xFE\xBD\x94\x05\x00\x20\x10\x20\x02\x40\x08\xC9\xFF\xFF"
+ "\x14\x20\x02\x40\x0C\x20\x02\x40\x03\x00\x13\x43\xF7\xB5\x9B\x07"
+ "\x22\xD1\x01\x26\x12\x4B\x13\x4C\x1D\x68\x37\x00\x25\x40\x34\x00"
+ "\x2C\x43\x1C\x60\x0C\x00\x40\x1A\x01\x90\x10\x1B\x08\x18\x00\x28"
+ "\x10\xD0\x01\x98\x26\x88\x20\x18\x06\x80\x0B\x4E\x36\x68\x3E\x42"
+ "\xFB\xD1\x00\x88\x26\x88\x86\x42\x02\xD0\x1D\x60\x01\x20\x04\xE0"
+ "\x02\x34\xEA\xE7\x1D\x60\x01\xE0\x03\x20\x40\x42\xFE\xBD\xC0\x46"
+ "\x10\x20\x02\x40\x08\xC9\xFF\xFF\x0C\x20\x02\x40\x02\x20\x40\x42"
+ "\x70\x47\x00\x00\x00\x04\x00\x00"
+ },
{ "agent-lpc13xx.bin", 284,
"\x66\x61\x77\x42\x00\x00\x01\x00\x01\x00\x00\x00\x00\x04\x00\x10"
"\x00\x08\x00\x10\x00\x10\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00"