aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGareth McMullin2015-04-04 12:44:30 -0700
committerGareth McMullin2015-04-11 16:05:40 -0700
commitcd5d569d38ea8cc905739bd9189ac5f944de0207 (patch)
tree168dca4ce3784f902476fc056a654f2011e85942
parent54eb3a719fc78c66d0fb60944440a830092f69eb (diff)
lpc: Reduce differences between lpc11xx and lpc43xx code.
-rw-r--r--src/cortexm.c8
-rw-r--r--src/include/cortexm.h10
-rw-r--r--src/include/lpc_common.h83
-rw-r--r--src/lpc11xx.c93
-rw-r--r--src/lpc43xx.c144
5 files changed, 168 insertions, 170 deletions
diff --git a/src/cortexm.c b/src/cortexm.c
index ae1c59d..e7bed5b 100644
--- a/src/cortexm.c
+++ b/src/cortexm.c
@@ -195,14 +195,6 @@ static const char tdesc_cortex_mf[] =
" </feature>"
"</target>";
-#define REG_SP 13
-#define REG_LR 14
-#define REG_PC 15
-#define REG_XPSR 16
-#define REG_MSP 17
-#define REG_PSP 18
-#define REG_SPECIAL 19
-
bool cortexm_probe(target *t)
{
t->driver = cortexm_driver_str;
diff --git a/src/include/cortexm.h b/src/include/cortexm.h
index f7396bf..0a9c3ae 100644
--- a/src/include/cortexm.h
+++ b/src/include/cortexm.h
@@ -143,6 +143,16 @@
#define CORTEXM_DWT_FUNC_FUNC_WRITE (6 << 0)
#define CORTEXM_DWT_FUNC_FUNC_ACCESS (7 << 0)
+#define REG_SP 13
+#define REG_LR 14
+#define REG_PC 15
+#define REG_XPSR 16
+#define REG_MSP 17
+#define REG_PSP 18
+#define REG_SPECIAL 19
+
+#define ARM_THUMB_BREAKPOINT 0xBE00
+
bool cortexm_attach(target *t);
void cortexm_detach(target *t);
void cortexm_halt_resume(target *t, bool step);
diff --git a/src/include/lpc_common.h b/src/include/lpc_common.h
new file mode 100644
index 0000000..45d2964
--- /dev/null
+++ b/src/include/lpc_common.h
@@ -0,0 +1,83 @@
+/*
+ * This file is part of the Black Magic Debug project.
+ *
+ * Copyright (C) 2015 Gareth McMullin <gareth@blacksphere.co.nz>
+ *
+ * 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __LPC_COMMON_H
+#define __LPC_COMMON_H
+
+#define IAP_CMD_INIT 49
+#define IAP_CMD_PREPARE 50
+#define IAP_CMD_PROGRAM 51
+#define IAP_CMD_ERASE 52
+#define IAP_CMD_BLANKCHECK 53
+#define IAP_CMD_SET_ACTIVE_BANK 60
+
+#define IAP_STATUS_CMD_SUCCESS 0
+#define IAP_STATUS_INVALID_COMMAND 1
+#define IAP_STATUS_SRC_ADDR_ERROR 2
+#define IAP_STATUS_DST_ADDR_ERROR 3
+#define IAP_STATUS_SRC_ADDR_NOT_MAPPED 4
+#define IAP_STATUS_DST_ADDR_NOT_MAPPED 5
+#define IAP_STATUS_COUNT_ERROR 6
+#define IAP_STATUS_INVALID_SECTOR 7
+#define IAP_STATUS_SECTOR_NOT_BLANK 8
+#define IAP_STATUS_SECTOR_NOT_PREPARED 9
+#define IAP_STATUS_COMPARE_ERROR 10
+#define IAP_STATUS_BUSY 11
+
+/* CPU Frequency */
+#define CPU_CLK_KHZ 12000
+
+struct flash_param {
+ uint16_t opcode;/* opcode to return to after calling the ROM */
+ uint16_t pad0;
+ uint32_t command;/* IAP command */
+ union {
+ uint32_t words[5];/* command parameters */
+ struct {
+ uint32_t start_sector;
+ uint32_t end_sector;
+ uint32_t flash_bank;
+ } prepare;
+ struct {
+ uint32_t start_sector;
+ uint32_t end_sector;
+ uint32_t cpu_clk_khz;
+ uint32_t flash_bank;
+ } erase;
+ struct {
+ uint32_t dest;
+ uint32_t source;
+ uint32_t byte_count;
+ uint32_t cpu_clk_khz;
+ } program;
+ struct {
+ uint32_t start_sector;
+ uint32_t end_sector;
+ uint32_t flash_bank;
+ } blank_check;
+ struct {
+ uint32_t flash_bank;
+ uint32_t cpu_clk_khz;
+ } make_active;
+ };
+ uint32_t result[5]; /* result data */
+} __attribute__((aligned(4)));
+
+#endif
+
diff --git a/src/lpc11xx.c b/src/lpc11xx.c
index 3a85ded..7c6d742 100644
--- a/src/lpc11xx.c
+++ b/src/lpc11xx.c
@@ -1,6 +1,9 @@
/*
* This file is part of the Black Magic Debug project.
*
+ * Copyright (C) 2011 Mike Smith <drziplok@me.com>
+ * Copyright (C) 2015 Gareth McMullin <gareth@blacksphere.co.nz>
+ *
* 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 3 of the License, or
@@ -14,26 +17,15 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+
#include "general.h"
-#include "adiv5.h"
#include "target.h"
+#include "cortexm.h"
+#include "lpc_common.h"
#define IAP_PGM_CHUNKSIZE 256 /* should fit in RAM on any device */
-struct flash_param {
- uint16_t opcodes[2]; /* two opcodes to return to after calling the ROM */
- uint32_t command[5]; /* command operands */
- uint32_t result[4]; /* result data */
-};
-
-struct flash_program {
- struct flash_param p;
- uint8_t data[IAP_PGM_CHUNKSIZE];
-};
-
-static struct flash_program flash_pgm;
-#define MSP 17 /* Main stack pointer register number */
#define MIN_RAM_SIZE_FOR_LPC8xx 1024
#define MIN_RAM_SIZE_FOR_LPC1xxx 2048
#define RAM_USAGE_FOR_IAP_ROUTINES 32 /* IAP routines use 32 bytes at top of ram */
@@ -41,24 +33,6 @@ static struct flash_program flash_pgm;
#define IAP_ENTRYPOINT 0x1fff1ff1
#define IAP_RAM_BASE 0x10000000
-#define IAP_CMD_PREPARE 50
-#define IAP_CMD_PROGRAM 51
-#define IAP_CMD_ERASE 52
-#define IAP_CMD_BLANKCHECK 53
-
-#define IAP_STATUS_CMD_SUCCESS 0
-#define IAP_STATUS_INVALID_COMMAND 1
-#define IAP_STATUS_SRC_ADDR_ERROR 2
-#define IAP_STATUS_DST_ADDR_ERROR 3
-#define IAP_STATUS_SRC_ADDR_NOT_MAPPED 4
-#define IAP_STATUS_DST_ADDR_NOT_MAPPED 5
-#define IAP_STATUS_COUNT_ERROR 6
-#define IAP_STATUS_INVALID_SECTOR 7
-#define IAP_STATUS_SECTOR_NOT_BLANK 8
-#define IAP_STATUS_SECTOR_NOT_PREPARED 9
-#define IAP_STATUS_COMPARE_ERROR 10
-#define IAP_STATUS_BUSY 11
-
static const char lpc8xx_driver[] = "lpc8xx";
static const char lpc11xx_driver[] = "lpc11xx";
static void lpc11x_iap_call(target *t, struct flash_param *param, unsigned param_len);
@@ -67,6 +41,11 @@ static int lpc11xx_flash_erase(target *t, uint32_t addr, size_t len);
static int lpc11xx_flash_write(target *t, uint32_t dest, const uint8_t *src,
size_t len);
+struct flash_program {
+ struct flash_param p;
+ uint8_t data[IAP_PGM_CHUNKSIZE];
+};
+
/*
* Note that this memory map is actually for the largest of the lpc11xx devices;
* There seems to be no good way to decode the part number to determine the RAM
@@ -168,8 +147,8 @@ lpc11x_iap_call(target *t, struct flash_param *param, unsigned param_len)
uint32_t regs[t->regs_size / sizeof(uint32_t)];
/* fill out the remainder of the parameters and copy the structure to RAM */
- param->opcodes[0] = 0xbe00;
- param->opcodes[1] = 0x0000;
+ param->opcode = ARM_THUMB_BREAKPOINT;
+ param->pad0 = 0x0000;
target_mem_write(t, IAP_RAM_BASE, param, param_len);
/* set up for the call to the IAP ROM */
@@ -179,11 +158,11 @@ lpc11x_iap_call(target *t, struct flash_param *param, unsigned param_len)
// stack pointer - top of the smallest ram less 32 for IAP usage
if (t->driver == lpc8xx_driver)
- regs[MSP] = IAP_RAM_BASE + MIN_RAM_SIZE_FOR_LPC8xx - RAM_USAGE_FOR_IAP_ROUTINES;
+ regs[REG_MSP] = IAP_RAM_BASE + MIN_RAM_SIZE_FOR_LPC8xx - RAM_USAGE_FOR_IAP_ROUTINES;
else
- regs[MSP] = IAP_RAM_BASE + MIN_RAM_SIZE_FOR_LPC1xxx - RAM_USAGE_FOR_IAP_ROUTINES;
- regs[14] = IAP_RAM_BASE | 1;
- regs[15] = IAP_ENTRYPOINT;
+ regs[REG_MSP] = IAP_RAM_BASE + MIN_RAM_SIZE_FOR_LPC1xxx - RAM_USAGE_FOR_IAP_ROUTINES;
+ regs[REG_LR] = IAP_RAM_BASE | 1;
+ regs[REG_PC] = IAP_ENTRYPOINT;
target_regs_write(t, regs);
/* start the target and wait for it to halt again */
@@ -205,11 +184,12 @@ static int flash_page_size(target *t)
static int
lpc11xx_flash_prepare(target *t, uint32_t addr, int len)
{
+ struct flash_program flash_pgm;
/* prepare the sector(s) to be erased */
memset(&flash_pgm.p, 0, sizeof(flash_pgm.p));
- flash_pgm.p.command[0] = IAP_CMD_PREPARE;
- flash_pgm.p.command[1] = addr / flash_page_size(t);
- flash_pgm.p.command[2] = (addr + len - 1) / flash_page_size(t);
+ flash_pgm.p.command = IAP_CMD_PREPARE;
+ flash_pgm.p.prepare.start_sector = addr / flash_page_size(t);
+ flash_pgm.p.prepare.end_sector = (addr + len - 1) / flash_page_size(t);
lpc11x_iap_call(t, &flash_pgm.p, sizeof(flash_pgm.p));
if (flash_pgm.p.result[0] != IAP_STATUS_CMD_SUCCESS) {
@@ -222,6 +202,7 @@ lpc11xx_flash_prepare(target *t, uint32_t addr, int len)
static int
lpc11xx_flash_erase(target *t, uint32_t addr, size_t len)
{
+ struct flash_program flash_pgm;
if (addr % flash_page_size(t))
return -1;
@@ -231,15 +212,18 @@ lpc11xx_flash_erase(target *t, uint32_t addr, size_t len)
return -1;
/* and now erase them */
- flash_pgm.p.command[0] = IAP_CMD_ERASE;
- flash_pgm.p.command[1] = addr / flash_page_size(t);
- flash_pgm.p.command[2] = (addr + len - 1) / flash_page_size(t);
- flash_pgm.p.command[3] = 12000; /* XXX safe to assume this? */
+ flash_pgm.p.command = IAP_CMD_ERASE;
+ flash_pgm.p.erase.start_sector = addr / flash_page_size(t);
+ flash_pgm.p.erase.end_sector = (addr + len - 1) / flash_page_size(t);
+ flash_pgm.p.erase.cpu_clk_khz = CPU_CLK_KHZ;
+ flash_pgm.p.result[0] = IAP_STATUS_CMD_SUCCESS;
lpc11x_iap_call(t, &flash_pgm.p, sizeof(flash_pgm.p));
if (flash_pgm.p.result[0] != IAP_STATUS_CMD_SUCCESS) {
return -1;
}
- flash_pgm.p.command[0] = IAP_CMD_BLANKCHECK;
+
+ /* check erase ok */
+ flash_pgm.p.command = IAP_CMD_BLANKCHECK;
lpc11x_iap_call(t, &flash_pgm.p, sizeof(flash_pgm.p));
if (flash_pgm.p.result[0] != IAP_STATUS_CMD_SUCCESS) {
return -1;
@@ -255,6 +239,7 @@ lpc11xx_flash_write(target *t, uint32_t dest, const uint8_t *src, size_t len)
unsigned last_chunk = (dest + len - 1) / IAP_PGM_CHUNKSIZE;
unsigned chunk_offset = dest % IAP_PGM_CHUNKSIZE;
unsigned chunk;
+ struct flash_program flash_pgm;
for (chunk = first_chunk; chunk <= last_chunk; chunk++) {
@@ -269,8 +254,8 @@ lpc11xx_flash_write(target *t, uint32_t dest, const uint8_t *src, size_t len)
size_t copylen = IAP_PGM_CHUNKSIZE - chunk_offset;
if (copylen > len)
copylen = len;
- memcpy(&flash_pgm.data[chunk_offset], src, copylen);
+ memcpy(flash_pgm.data + chunk_offset, src, copylen);
/* if we are programming the vectors, calculate the magic number */
if ((chunk == 0) && (chunk_offset == 0)) {
if (copylen < 32) {
@@ -290,9 +275,7 @@ lpc11xx_flash_write(target *t, uint32_t dest, const uint8_t *src, size_t len)
len -= copylen;
src += copylen;
chunk_offset = 0;
-
} else {
-
/* interior chunk, must be aligned and full-sized */
memcpy(flash_pgm.data, src, IAP_PGM_CHUNKSIZE);
len -= IAP_PGM_CHUNKSIZE;
@@ -304,12 +287,12 @@ lpc11xx_flash_write(target *t, uint32_t dest, const uint8_t *src, size_t len)
return -1;
/* set the destination address and program */
- flash_pgm.p.command[0] = IAP_CMD_PROGRAM;
- flash_pgm.p.command[1] = chunk * IAP_PGM_CHUNKSIZE;
- flash_pgm.p.command[2] = IAP_RAM_BASE + offsetof(struct flash_program, data);
- flash_pgm.p.command[3] = IAP_PGM_CHUNKSIZE;
- /* assuming we are running off IRC - safe lower bound */
- flash_pgm.p.command[4] = 12000; /* XXX safe to presume this? */
+ flash_pgm.p.command = IAP_CMD_PROGRAM;
+ flash_pgm.p.program.dest = chunk * IAP_PGM_CHUNKSIZE;
+ flash_pgm.p.program.source = IAP_RAM_BASE + offsetof(struct flash_program, data);
+ flash_pgm.p.program.byte_count = IAP_PGM_CHUNKSIZE;
+ flash_pgm.p.program.cpu_clk_khz = CPU_CLK_KHZ;
+ flash_pgm.p.result[0] = IAP_STATUS_CMD_SUCCESS;
lpc11x_iap_call(t, &flash_pgm.p, sizeof(flash_pgm));
if (flash_pgm.p.result[0] != IAP_STATUS_CMD_SUCCESS) {
return -1;
diff --git a/src/lpc43xx.c b/src/lpc43xx.c
index 1519306..ad93c8d 100644
--- a/src/lpc43xx.c
+++ b/src/lpc43xx.c
@@ -1,7 +1,8 @@
/*
* This file is part of the Black Magic Debug project.
*
- * Copyright (C) 2012 Gareth McMullin <gareth@blacksphere.co.nz>
+ * Copyright (C) 2014 Allen Ibara <aibara>
+ * Copyright (C) 2015 Gareth McMullin <gareth@blacksphere.co.nz>
*
* 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
@@ -19,17 +20,13 @@
#include "general.h"
#include "command.h"
-#include "adiv5.h"
#include "target.h"
#include "gdb_packet.h"
+#include "cortexm.h"
+#include "lpc_common.h"
#define LPC43XX_CHIPID 0x40043200
#define ARM_CPUID 0xE000ED00
-#define ARM_THUMB_BREAKPOINT 0xBE00
-
-#define R_MSP 17 // Main stack pointer register number
-#define R_PC 15 // Program counter register number
-#define R_LR 14 // Link register number
#define IAP_ENTRYPOINT_LOCATION 0x10400100
@@ -47,25 +44,6 @@
#define IAP_PGM_CHUNKSIZE 4096
-#define IAP_CMD_INIT 49
-#define IAP_CMD_PREPARE 50
-#define IAP_CMD_PROGRAM 51
-#define IAP_CMD_ERASE 52
-#define IAP_CMD_BLANKCHECK 53
-#define IAP_CMD_SET_ACTIVE_BANK 60
-
-#define IAP_STATUS_CMD_SUCCESS 0
-#define IAP_STATUS_INVALID_COMMAND 1
-#define IAP_STATUS_SRC_ADDR_ERROR 2
-#define IAP_STATUS_DST_ADDR_ERROR 3
-#define IAP_STATUS_SRC_ADDR_NOT_MAPPED 4
-#define IAP_STATUS_DST_ADDR_NOT_MAPPED 5
-#define IAP_STATUS_COUNT_ERROR 6
-#define IAP_STATUS_INVALID_SECTOR 7
-#define IAP_STATUS_SECTOR_NOT_BLANK 8
-#define IAP_STATUS_SECTOR_NOT_PREPARED 9
-#define IAP_STATUS_COMPARE_ERROR 10
-#define IAP_STATUS_BUSY 11
#define FLASH_BANK_A_BASE 0x1A000000
#define FLASH_BANK_A_SIZE 0x80000
@@ -75,45 +53,6 @@
#define FLASH_NUM_SECTOR 15
#define FLASH_LARGE_SECTOR_OFFSET 0x00010000
-/* CPU Frequency */
-#define CPU_CLK_KHZ 12000
-
-struct flash_param {
- uint16_t opcode; /* opcode to return to after calling the ROM */
- uint16_t pad0;
- uint32_t command; /* IAP command */
- union {
- uint32_t words[5]; /* command parameters */
- struct {
- uint32_t start_sector;
- uint32_t end_sector;
- uint32_t flash_bank;
- } prepare;
- struct {
- uint32_t start_sector;
- uint32_t end_sector;
- uint32_t cpu_clk_khz;
- uint32_t flash_bank;
- } erase;
- struct {
- uint32_t dest;
- uint32_t source;
- uint32_t byte_count;
- uint32_t cpu_clk_khz;
- } program;
- struct {
- uint32_t start_sector;
- uint32_t end_sector;
- uint32_t flash_bank;
- } blank_check;
- struct {
- uint32_t flash_bank;
- uint32_t cpu_clk_khz;
- } make_active;
- } params;
- uint32_t result[5]; /* result data */
-} __attribute__((aligned(4)));
-
struct flash_program {
struct flash_param p;
uint8_t data[IAP_PGM_CHUNKSIZE];
@@ -242,9 +181,9 @@ static bool lpc43xx_cmd_erase(target *t, int argc, const char *argv[])
for (bank = 0; bank < FLASH_NUM_BANK; bank++)
{
flash_pgm.p.command = IAP_CMD_PREPARE;
- flash_pgm.p.params.prepare.start_sector = 0;
- flash_pgm.p.params.prepare.end_sector = FLASH_NUM_SECTOR-1;
- flash_pgm.p.params.prepare.flash_bank = bank;
+ flash_pgm.p.prepare.start_sector = 0;
+ flash_pgm.p.prepare.end_sector = FLASH_NUM_SECTOR-1;
+ flash_pgm.p.prepare.flash_bank = bank;
flash_pgm.p.result[0] = IAP_STATUS_CMD_SUCCESS;
lpc43xx_iap_call(t, &flash_pgm.p, sizeof(flash_pgm.p));
if (flash_pgm.p.result[0] != IAP_STATUS_CMD_SUCCESS) {
@@ -252,10 +191,10 @@ static bool lpc43xx_cmd_erase(target *t, int argc, const char *argv[])
}
flash_pgm.p.command = IAP_CMD_ERASE;
- flash_pgm.p.params.erase.start_sector = 0;
- flash_pgm.p.params.prepare.end_sector = FLASH_NUM_SECTOR-1;
- flash_pgm.p.params.erase.cpu_clk_khz = CPU_CLK_KHZ;
- flash_pgm.p.params.erase.flash_bank = bank;
+ flash_pgm.p.erase.start_sector = 0;
+ flash_pgm.p.prepare.end_sector = FLASH_NUM_SECTOR-1;
+ flash_pgm.p.erase.cpu_clk_khz = CPU_CLK_KHZ;
+ flash_pgm.p.erase.flash_bank = bank;
flash_pgm.p.result[0] = IAP_STATUS_CMD_SUCCESS;
lpc43xx_iap_call(t, &flash_pgm.p, sizeof(flash_pgm.p));
if (flash_pgm.p.result[0] != IAP_STATUS_CMD_SUCCESS)
@@ -343,8 +282,8 @@ static void lpc43xx_iap_call(target *t, struct flash_param *param, unsigned para
target_mem_read(t, &iap_entry, IAP_ENTRYPOINT_LOCATION, sizeof(iap_entry));
/* fill out the remainder of the parameters and copy the structure to RAM */
- param->opcode = ARM_THUMB_BREAKPOINT; /* breakpoint */
- param->pad0 = 0x0000; /* pad */
+ param->opcode = ARM_THUMB_BREAKPOINT;
+ param->pad0 = 0x0000;
target_mem_write(t, IAP_RAM_BASE, param, param_len);
/* set up for the call to the IAP ROM */
@@ -352,9 +291,9 @@ static void lpc43xx_iap_call(target *t, struct flash_param *param, unsigned para
regs[0] = IAP_RAM_BASE + offsetof(struct flash_param, command);
regs[1] = IAP_RAM_BASE + offsetof(struct flash_param, result);
- regs[R_MSP] = IAP_RAM_BASE + IAP_RAM_SIZE;
- regs[R_LR] = IAP_RAM_BASE | 1;
- regs[R_PC] = iap_entry;
+ regs[REG_MSP] = IAP_RAM_BASE + IAP_RAM_SIZE;
+ regs[REG_LR] = IAP_RAM_BASE | 1;
+ regs[REG_PC] = iap_entry;
target_regs_write(t, regs);
/* start the target and wait for it to halt again */
@@ -370,11 +309,11 @@ static int lpc43xx_flash_prepare(target *t, uint32_t addr, int len)
struct flash_program flash_pgm;
/* prepare the sector(s) to be erased */
+ memset(&flash_pgm.p, 0, sizeof(flash_pgm.p));
flash_pgm.p.command = IAP_CMD_PREPARE;
- flash_pgm.p.params.prepare.start_sector = sector_number(addr);
- flash_pgm.p.params.prepare.end_sector = sector_number(addr+len);
- flash_pgm.p.params.prepare.flash_bank = flash_bank(addr);
- flash_pgm.p.result[0] = IAP_STATUS_CMD_SUCCESS;
+ flash_pgm.p.prepare.start_sector = sector_number(addr);
+ flash_pgm.p.prepare.end_sector = sector_number(addr+len);
+ flash_pgm.p.prepare.flash_bank = flash_bank(addr);
lpc43xx_iap_call(t, &flash_pgm.p, sizeof(flash_pgm.p));
if (flash_pgm.p.result[0] != IAP_STATUS_CMD_SUCCESS) {
@@ -402,10 +341,10 @@ static int lpc43xx_flash_erase(target *t, uint32_t addr, size_t len)
/* and now erase them */
flash_pgm.p.command = IAP_CMD_ERASE;
- flash_pgm.p.params.erase.start_sector = sector_number(addr);
- flash_pgm.p.params.erase.end_sector = sector_number(addr+len);
- flash_pgm.p.params.erase.cpu_clk_khz = CPU_CLK_KHZ;
- flash_pgm.p.params.erase.flash_bank = flash_bank(addr);
+ flash_pgm.p.erase.start_sector = sector_number(addr);
+ flash_pgm.p.erase.end_sector = sector_number(addr+len);
+ flash_pgm.p.erase.cpu_clk_khz = CPU_CLK_KHZ;
+ flash_pgm.p.erase.flash_bank = flash_bank(addr);
flash_pgm.p.result[0] = IAP_STATUS_CMD_SUCCESS;
lpc43xx_iap_call(t, &flash_pgm.p, sizeof(flash_pgm.p));
if (flash_pgm.p.result[0] != IAP_STATUS_CMD_SUCCESS) {
@@ -414,9 +353,9 @@ static int lpc43xx_flash_erase(target *t, uint32_t addr, size_t len)
/* check erase ok */
flash_pgm.p.command = IAP_CMD_BLANKCHECK;
- flash_pgm.p.params.blank_check.start_sector = sector_number(addr);
- flash_pgm.p.params.blank_check.end_sector = sector_number(addr+len);
- flash_pgm.p.params.blank_check.flash_bank = flash_bank(addr);
+ flash_pgm.p.blank_check.start_sector = sector_number(addr);
+ flash_pgm.p.blank_check.end_sector = sector_number(addr+len);
+ flash_pgm.p.blank_check.flash_bank = flash_bank(addr);
flash_pgm.p.result[0] = IAP_STATUS_CMD_SUCCESS;
lpc43xx_iap_call(t, &flash_pgm.p, sizeof(flash_pgm.p));
if (flash_pgm.p.result[0] != IAP_STATUS_CMD_SUCCESS) {
@@ -437,17 +376,13 @@ static int lpc43xx_flash_write(target *t,
{
unsigned first_chunk = dest / IAP_PGM_CHUNKSIZE;
unsigned last_chunk = (dest + len - 1) / IAP_PGM_CHUNKSIZE;
- unsigned chunk_offset;
+ unsigned chunk_offset = dest % IAP_PGM_CHUNKSIZE;
unsigned chunk;
struct flash_program flash_pgm;
for (chunk = first_chunk; chunk <= last_chunk; chunk++) {
- if (chunk == first_chunk) {
- chunk_offset = dest % IAP_PGM_CHUNKSIZE;
- } else {
- chunk_offset = 0;
- }
+ DEBUG("chunk %u len %zu\n", chunk, len);
/* first and last chunk may require special handling */
if ((chunk == first_chunk) || (chunk == last_chunk)) {
@@ -464,6 +399,7 @@ static int lpc43xx_flash_write(target *t,
/* update to suit */
len -= copylen;
src += copylen;
+ chunk_offset = 0;
} else {
/* interior chunk, must be aligned and full-sized */
memcpy(flash_pgm.data, src, IAP_PGM_CHUNKSIZE);
@@ -472,21 +408,15 @@ static int lpc43xx_flash_write(target *t,
}
/* prepare... */
- if (lpc43xx_flash_prepare(t, chunk * IAP_PGM_CHUNKSIZE, IAP_PGM_CHUNKSIZE)) {
+ if (lpc43xx_flash_prepare(t, chunk * IAP_PGM_CHUNKSIZE, IAP_PGM_CHUNKSIZE))
return -1;
- }
-
- /* copy buffer into target memory */
- target_mem_write(t,
- IAP_RAM_BASE + offsetof(struct flash_program, data),
- flash_pgm.data, sizeof(flash_pgm.data));
/* set the destination address and program */
flash_pgm.p.command = IAP_CMD_PROGRAM;
- flash_pgm.p.params.program.dest = chunk * IAP_PGM_CHUNKSIZE;
- flash_pgm.p.params.program.source = IAP_RAM_BASE + offsetof(struct flash_program, data);
- flash_pgm.p.params.program.byte_count = IAP_PGM_CHUNKSIZE;
- flash_pgm.p.params.program.cpu_clk_khz = CPU_CLK_KHZ;
+ flash_pgm.p.program.dest = chunk * IAP_PGM_CHUNKSIZE;
+ flash_pgm.p.program.source = IAP_RAM_BASE + offsetof(struct flash_program, data);
+ flash_pgm.p.program.byte_count = IAP_PGM_CHUNKSIZE;
+ flash_pgm.p.program.cpu_clk_khz = CPU_CLK_KHZ;
flash_pgm.p.result[0] = IAP_STATUS_CMD_SUCCESS;
lpc43xx_iap_call(t, &flash_pgm.p, sizeof(flash_pgm));
if (flash_pgm.p.result[0] != IAP_STATUS_CMD_SUCCESS) {
@@ -524,8 +454,8 @@ static bool lpc43xx_cmd_mkboot(target *t, int argc, const char *argv[])
/* special command to compute/write magic vector for signature */
flash_pgm.p.command = IAP_CMD_SET_ACTIVE_BANK;
- flash_pgm.p.params.make_active.flash_bank = bank;
- flash_pgm.p.params.make_active.cpu_clk_khz = CPU_CLK_KHZ;
+ flash_pgm.p.make_active.flash_bank = bank;
+ flash_pgm.p.make_active.cpu_clk_khz = CPU_CLK_KHZ;
flash_pgm.p.result[0] = IAP_STATUS_CMD_SUCCESS;
lpc43xx_iap_call(t, &flash_pgm.p, sizeof(flash_pgm));
if (flash_pgm.p.result[0] != IAP_STATUS_CMD_SUCCESS) {