Consistently use 'target *t' for target var.
This commit is contained in:
parent
1e54139f4a
commit
9f271d5cd7
20
src/adiv5.c
20
src/adiv5.c
|
@ -37,12 +37,10 @@
|
|||
|
||||
static const char adiv5_driver_str[] = "ARM ADIv5 MEM-AP";
|
||||
|
||||
static int ap_check_error(struct target_s *target);
|
||||
static int ap_check_error(target *t);
|
||||
|
||||
static void ap_mem_read(struct target_s *target, void *dest, uint32_t src,
|
||||
size_t len);
|
||||
static void ap_mem_write(struct target_s *target, uint32_t dest,
|
||||
const void *src, size_t len);
|
||||
static void ap_mem_read(target *t, void *dest, uint32_t src, size_t len);
|
||||
static void ap_mem_write(target *t, uint32_t dest, const void *src, size_t len);
|
||||
|
||||
void adiv5_dp_ref(ADIv5_DP_t *dp)
|
||||
{
|
||||
|
@ -160,9 +158,9 @@ void adiv5_dp_init(ADIv5_DP_t *dp)
|
|||
}
|
||||
|
||||
static int
|
||||
ap_check_error(struct target_s *target)
|
||||
ap_check_error(target *t)
|
||||
{
|
||||
ADIv5_AP_t *ap = adiv5_target_ap(target);
|
||||
ADIv5_AP_t *ap = adiv5_target_ap(t);
|
||||
return adiv5_dp_error(ap->dp);
|
||||
}
|
||||
|
||||
|
@ -212,9 +210,9 @@ static void * extract(void *dest, uint32_t src, uint32_t val, enum align align)
|
|||
}
|
||||
|
||||
static void
|
||||
ap_mem_read(struct target_s *target, void *dest, uint32_t src, size_t len)
|
||||
ap_mem_read(target *t, void *dest, uint32_t src, size_t len)
|
||||
{
|
||||
ADIv5_AP_t *ap = adiv5_target_ap(target);
|
||||
ADIv5_AP_t *ap = adiv5_target_ap(t);
|
||||
uint32_t tmp;
|
||||
uint32_t osrc = src;
|
||||
enum align align = MIN(ALIGNOF(src), ALIGNOF(len));
|
||||
|
@ -241,9 +239,9 @@ ap_mem_read(struct target_s *target, void *dest, uint32_t src, size_t len)
|
|||
}
|
||||
|
||||
static void
|
||||
ap_mem_write(struct target_s *target, uint32_t dest, const void *src, size_t len)
|
||||
ap_mem_write(target *t, uint32_t dest, const void *src, size_t len)
|
||||
{
|
||||
ADIv5_AP_t *ap = adiv5_target_ap(target);
|
||||
ADIv5_AP_t *ap = adiv5_target_ap(t);
|
||||
uint32_t odest = dest;
|
||||
enum align align = MIN(ALIGNOF(dest), ALIGNOF(len));
|
||||
|
||||
|
|
10
src/crc32.c
10
src/crc32.c
|
@ -94,13 +94,13 @@ uint32_t crc32_calc(uint32_t crc, uint8_t data)
|
|||
return (crc << 8) ^ crc32_table[((crc >> 24) ^ data) & 255];
|
||||
}
|
||||
|
||||
uint32_t generic_crc32(struct target_s *target, uint32_t base, int len)
|
||||
uint32_t generic_crc32(target *t, uint32_t base, int len)
|
||||
{
|
||||
uint32_t crc = -1;
|
||||
uint8_t byte;
|
||||
|
||||
while (len--) {
|
||||
byte = target_mem_read8(target, base);
|
||||
byte = target_mem_read8(t, base);
|
||||
|
||||
crc = crc32_calc(crc, byte);
|
||||
base++;
|
||||
|
@ -109,7 +109,7 @@ uint32_t generic_crc32(struct target_s *target, uint32_t base, int len)
|
|||
}
|
||||
#else
|
||||
#include <libopencm3/stm32/crc.h>
|
||||
uint32_t generic_crc32(struct target_s *target, uint32_t base, int len)
|
||||
uint32_t generic_crc32(target *t, uint32_t base, int len)
|
||||
{
|
||||
uint32_t data;
|
||||
uint32_t crc;
|
||||
|
@ -118,7 +118,7 @@ uint32_t generic_crc32(struct target_s *target, uint32_t base, int len)
|
|||
CRC_CR |= CRC_CR_RESET;
|
||||
|
||||
while (len > 3) {
|
||||
data = target_mem_read32(target, base);
|
||||
data = target_mem_read32(t, base);
|
||||
|
||||
CRC_DR = __builtin_bswap32(data);
|
||||
base += 4;
|
||||
|
@ -128,7 +128,7 @@ uint32_t generic_crc32(struct target_s *target, uint32_t base, int len)
|
|||
crc = CRC_DR;
|
||||
|
||||
while (len--) {
|
||||
data = target_mem_read8(target, base++);
|
||||
data = target_mem_read8(t, base++);
|
||||
|
||||
crc ^= data << 24;
|
||||
for (i = 0; i < 8; i++) {
|
||||
|
|
|
@ -143,10 +143,10 @@
|
|||
#define CORTEXM_DWT_FUNC_FUNC_WRITE (6 << 0)
|
||||
#define CORTEXM_DWT_FUNC_FUNC_ACCESS (7 << 0)
|
||||
|
||||
bool cortexm_attach(struct target_s *target);
|
||||
void cortexm_detach(struct target_s *target);
|
||||
void cortexm_halt_resume(struct target_s *target, bool step);
|
||||
int cortexm_run_stub(struct target_s *target, uint32_t loadaddr,
|
||||
bool cortexm_attach(target *t);
|
||||
void cortexm_detach(target *t);
|
||||
void cortexm_halt_resume(target *t, bool step);
|
||||
int cortexm_run_stub(target *t, uint32_t loadaddr,
|
||||
const uint16_t *stub, uint32_t stublen,
|
||||
uint32_t r0, uint32_t r1, uint32_t r2, uint32_t r3);
|
||||
int cortexm_pc_write(target *t, const uint32_t val);
|
||||
|
|
|
@ -22,6 +22,6 @@
|
|||
#define __CRC32_H
|
||||
|
||||
uint32_t crc32_calc(uint32_t crc, uint8_t data);
|
||||
uint32_t generic_crc32(struct target_s *target, uint32_t base, int len);
|
||||
uint32_t generic_crc32(target *t, uint32_t base, int len);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -54,8 +54,8 @@
|
|||
|
||||
#define KL25_PAGESIZE 0x400
|
||||
|
||||
static int kl25_flash_erase(struct target_s *target, uint32_t addr, size_t len);
|
||||
static int kl25_flash_write(struct target_s *target, uint32_t dest,
|
||||
static int kl25_flash_erase(target *t, uint32_t addr, size_t len);
|
||||
static int kl25_flash_write(target *t, uint32_t dest,
|
||||
const uint8_t *src, size_t len);
|
||||
|
||||
static const char kl25_xml_memory_map[] = "<?xml version=\"1.0\"?>"
|
||||
|
@ -70,7 +70,7 @@ static const char kl25_xml_memory_map[] = "<?xml version=\"1.0\"?>"
|
|||
" <memory type=\"ram\" start=\"0x20000000\" length=\"0x3000\"/>"
|
||||
"</memory-map>";
|
||||
|
||||
bool kinetis_probe(struct target_s *t)
|
||||
bool kinetis_probe(target *t)
|
||||
{
|
||||
uint32_t sdid = target_mem_read32(t, SIM_SDID);
|
||||
switch (sdid >> 20) {
|
||||
|
@ -85,7 +85,7 @@ bool kinetis_probe(struct target_s *t)
|
|||
}
|
||||
|
||||
static bool
|
||||
kl25_command(struct target_s *t, uint8_t cmd, uint32_t addr, const uint8_t data[8])
|
||||
kl25_command(target *t, uint8_t cmd, uint32_t addr, const uint8_t data[8])
|
||||
{
|
||||
uint8_t fstat;
|
||||
|
||||
|
@ -120,7 +120,7 @@ kl25_command(struct target_s *t, uint8_t cmd, uint32_t addr, const uint8_t data[
|
|||
return true;
|
||||
}
|
||||
|
||||
static int kl25_flash_erase(struct target_s *t, uint32_t addr, size_t len)
|
||||
static int kl25_flash_erase(target *t, uint32_t addr, size_t len)
|
||||
{
|
||||
addr &= ~(KL25_PAGESIZE - 1);
|
||||
len = (len + KL25_PAGESIZE - 1) & ~(KL25_PAGESIZE - 1);
|
||||
|
@ -133,7 +133,7 @@ static int kl25_flash_erase(struct target_s *t, uint32_t addr, size_t len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int kl25_flash_write(struct target_s *t, uint32_t dest,
|
||||
static int kl25_flash_write(target *t, uint32_t dest,
|
||||
const uint8_t *src, size_t len)
|
||||
{
|
||||
/* FIXME handle misaligned start and end of sections */
|
||||
|
|
41
src/lmi.c
41
src/lmi.c
|
@ -32,8 +32,8 @@
|
|||
#include "target.h"
|
||||
#include "cortexm.h"
|
||||
|
||||
static int lmi_flash_erase(struct target_s *target, uint32_t addr, size_t len);
|
||||
static int lmi_flash_write(struct target_s *target, uint32_t dest,
|
||||
static int lmi_flash_erase(target *t, uint32_t addr, size_t len);
|
||||
static int lmi_flash_write(target *t, uint32_t dest,
|
||||
const uint8_t *src, size_t len);
|
||||
|
||||
static const char lmi_driver_str[] = "TI Stellaris/Tiva";
|
||||
|
@ -99,30 +99,30 @@ static const uint16_t lmi_flash_write_stub[] = {
|
|||
// ...
|
||||
};
|
||||
|
||||
bool lmi_probe(struct target_s *target)
|
||||
bool lmi_probe(target *t)
|
||||
{
|
||||
uint32_t did1 = target_mem_read32(target, 0x400FE004);
|
||||
uint32_t did1 = target_mem_read32(t, 0x400FE004);
|
||||
switch (did1 >> 16) {
|
||||
case 0x1049: /* LM3S3748 */
|
||||
target->driver = lmi_driver_str;
|
||||
target->xml_mem_map = lmi_xml_memory_map;
|
||||
target->flash_erase = lmi_flash_erase;
|
||||
target->flash_write = lmi_flash_write;
|
||||
t->driver = lmi_driver_str;
|
||||
t->xml_mem_map = lmi_xml_memory_map;
|
||||
t->flash_erase = lmi_flash_erase;
|
||||
t->flash_write = lmi_flash_write;
|
||||
return true;
|
||||
|
||||
case 0x10A1: /* TM4C123GH6PM */
|
||||
target->driver = lmi_driver_str;
|
||||
target->xml_mem_map = tm4c123gh6pm_xml_memory_map;
|
||||
target->flash_erase = lmi_flash_erase;
|
||||
target->flash_write = lmi_flash_write;
|
||||
t->driver = lmi_driver_str;
|
||||
t->xml_mem_map = tm4c123gh6pm_xml_memory_map;
|
||||
t->flash_erase = lmi_flash_erase;
|
||||
t->flash_write = lmi_flash_write;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int lmi_flash_erase(struct target_s *target, uint32_t addr, size_t len)
|
||||
int lmi_flash_erase(target *t, uint32_t addr, size_t len)
|
||||
{
|
||||
ADIv5_AP_t *ap = adiv5_target_ap(target);
|
||||
ADIv5_AP_t *ap = adiv5_target_ap(t);
|
||||
uint32_t tmp;
|
||||
|
||||
addr &= 0xFFFFFC00;
|
||||
|
@ -152,22 +152,21 @@ int lmi_flash_erase(struct target_s *target, uint32_t addr, size_t len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int lmi_flash_write(struct target_s *target, uint32_t dest,
|
||||
const uint8_t *src, size_t len)
|
||||
int lmi_flash_write(target *t, uint32_t dest, const uint8_t *src, size_t len)
|
||||
{
|
||||
uint32_t data[(len>>2)+2];
|
||||
data[0] = dest;
|
||||
data[1] = len >> 2;
|
||||
memcpy(&data[2], src, len);
|
||||
DEBUG("Sending stub\n");
|
||||
target_mem_write(target, 0x20000000, (void*)lmi_flash_write_stub, 0x30);
|
||||
target_mem_write(t, 0x20000000, (void*)lmi_flash_write_stub, 0x30);
|
||||
DEBUG("Sending data\n");
|
||||
target_mem_write(target, 0x20000030, data, len + 8);
|
||||
target_mem_write(t, 0x20000030, data, len + 8);
|
||||
DEBUG("Running stub\n");
|
||||
cortexm_pc_write(target, 0x20000000);
|
||||
target_halt_resume(target, 0);
|
||||
cortexm_pc_write(t, 0x20000000);
|
||||
target_halt_resume(t, 0);
|
||||
DEBUG("Waiting for halt\n");
|
||||
while(!target_halt_wait(target));
|
||||
while(!target_halt_wait(t));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -61,10 +61,10 @@ static struct flash_program flash_pgm;
|
|||
|
||||
static const char lpc8xx_driver[] = "lpc8xx";
|
||||
static const char lpc11xx_driver[] = "lpc11xx";
|
||||
static void lpc11x_iap_call(struct target_s *target, struct flash_param *param, unsigned param_len);
|
||||
static int lpc11xx_flash_prepare(struct target_s *target, uint32_t addr, int len);
|
||||
static int lpc11xx_flash_erase(struct target_s *target, uint32_t addr, size_t len);
|
||||
static int lpc11xx_flash_write(struct target_s *target, uint32_t dest, const uint8_t *src,
|
||||
static void lpc11x_iap_call(target *t, struct flash_param *param, unsigned param_len);
|
||||
static int lpc11xx_flash_prepare(target *t, uint32_t addr, int len);
|
||||
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);
|
||||
|
||||
/*
|
||||
|
@ -103,12 +103,12 @@ static const char lpc8xx_xml_memory_map[] = "<?xml version=\"1.0\"?>"
|
|||
"</memory-map>";
|
||||
|
||||
bool
|
||||
lpc11xx_probe(struct target_s *target)
|
||||
lpc11xx_probe(target *t)
|
||||
{
|
||||
uint32_t idcode;
|
||||
|
||||
/* read the device ID register */
|
||||
idcode = target_mem_read32(target, 0x400483F4);
|
||||
idcode = target_mem_read32(t, 0x400483F4);
|
||||
|
||||
switch (idcode) {
|
||||
|
||||
|
@ -143,18 +143,18 @@ lpc11xx_probe(struct target_s *target)
|
|||
case 0x2972402B: /* lpc11u23/301 */
|
||||
case 0x2988402B: /* lpc11u24x/301 */
|
||||
case 0x2980002B: /* lpc11u24x/401 */
|
||||
target->driver = lpc11xx_driver;
|
||||
target->xml_mem_map = lpc11xx_xml_memory_map;
|
||||
target->flash_erase = lpc11xx_flash_erase;
|
||||
target->flash_write = lpc11xx_flash_write;
|
||||
t->driver = lpc11xx_driver;
|
||||
t->xml_mem_map = lpc11xx_xml_memory_map;
|
||||
t->flash_erase = lpc11xx_flash_erase;
|
||||
t->flash_write = lpc11xx_flash_write;
|
||||
|
||||
return true;
|
||||
|
||||
case 0x1812202b: /* LPC812M101FDH20 */
|
||||
target->driver = lpc8xx_driver;
|
||||
target->xml_mem_map = lpc8xx_xml_memory_map;
|
||||
target->flash_erase = lpc11xx_flash_erase;
|
||||
target->flash_write = lpc11xx_flash_write;
|
||||
t->driver = lpc8xx_driver;
|
||||
t->xml_mem_map = lpc8xx_xml_memory_map;
|
||||
t->flash_erase = lpc11xx_flash_erase;
|
||||
t->flash_write = lpc11xx_flash_write;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -163,55 +163,55 @@ lpc11xx_probe(struct target_s *target)
|
|||
}
|
||||
|
||||
static void
|
||||
lpc11x_iap_call(struct target_s *target, struct flash_param *param, unsigned param_len)
|
||||
lpc11x_iap_call(target *t, struct flash_param *param, unsigned param_len)
|
||||
{
|
||||
uint32_t regs[target->regs_size / sizeof(uint32_t)];
|
||||
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;
|
||||
target_mem_write(target, IAP_RAM_BASE, param, param_len);
|
||||
target_mem_write(t, IAP_RAM_BASE, param, param_len);
|
||||
|
||||
/* set up for the call to the IAP ROM */
|
||||
target_regs_read(target, regs);
|
||||
target_regs_read(t, regs);
|
||||
regs[0] = IAP_RAM_BASE + offsetof(struct flash_param, command);
|
||||
regs[1] = IAP_RAM_BASE + offsetof(struct flash_param, result);
|
||||
|
||||
// stack pointer - top of the smallest ram less 32 for IAP usage
|
||||
if (target->driver == lpc8xx_driver)
|
||||
if (t->driver == lpc8xx_driver)
|
||||
regs[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;
|
||||
target_regs_write(target, regs);
|
||||
target_regs_write(t, regs);
|
||||
|
||||
/* start the target and wait for it to halt again */
|
||||
target_halt_resume(target, 0);
|
||||
while (!target_halt_wait(target));
|
||||
target_halt_resume(t, 0);
|
||||
while (!target_halt_wait(t));
|
||||
|
||||
/* copy back just the parameters structure */
|
||||
target_mem_read(target, param, IAP_RAM_BASE, sizeof(struct flash_param));
|
||||
target_mem_read(t, param, IAP_RAM_BASE, sizeof(struct flash_param));
|
||||
}
|
||||
|
||||
static int flash_page_size(struct target_s *target)
|
||||
static int flash_page_size(target *t)
|
||||
{
|
||||
if (target->driver == lpc8xx_driver)
|
||||
if (t->driver == lpc8xx_driver)
|
||||
return 1024;
|
||||
else
|
||||
return 4096;
|
||||
}
|
||||
|
||||
static int
|
||||
lpc11xx_flash_prepare(struct target_s *target, uint32_t addr, int len)
|
||||
lpc11xx_flash_prepare(target *t, uint32_t addr, int len)
|
||||
{
|
||||
/* 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(target);
|
||||
flash_pgm.p.command[2] = (addr + len - 1) / flash_page_size(target);
|
||||
flash_pgm.p.command[1] = addr / flash_page_size(t);
|
||||
flash_pgm.p.command[2] = (addr + len - 1) / flash_page_size(t);
|
||||
|
||||
lpc11x_iap_call(target, &flash_pgm.p, sizeof(flash_pgm.p));
|
||||
lpc11x_iap_call(t, &flash_pgm.p, sizeof(flash_pgm.p));
|
||||
if (flash_pgm.p.result[0] != IAP_STATUS_CMD_SUCCESS) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -220,27 +220,27 @@ lpc11xx_flash_prepare(struct target_s *target, uint32_t addr, int len)
|
|||
}
|
||||
|
||||
static int
|
||||
lpc11xx_flash_erase(struct target_s *target, uint32_t addr, size_t len)
|
||||
lpc11xx_flash_erase(target *t, uint32_t addr, size_t len)
|
||||
{
|
||||
|
||||
if (addr % flash_page_size(target))
|
||||
if (addr % flash_page_size(t))
|
||||
return -1;
|
||||
|
||||
/* prepare... */
|
||||
if (lpc11xx_flash_prepare(target, addr, len))
|
||||
if (lpc11xx_flash_prepare(t, addr, len))
|
||||
return -1;
|
||||
|
||||
/* and now erase them */
|
||||
flash_pgm.p.command[0] = IAP_CMD_ERASE;
|
||||
flash_pgm.p.command[1] = addr / flash_page_size(target);
|
||||
flash_pgm.p.command[2] = (addr + len - 1) / flash_page_size(target);
|
||||
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? */
|
||||
lpc11x_iap_call(target, &flash_pgm.p, sizeof(flash_pgm.p));
|
||||
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;
|
||||
lpc11x_iap_call(target, &flash_pgm.p, sizeof(flash_pgm.p));
|
||||
lpc11x_iap_call(t, &flash_pgm.p, sizeof(flash_pgm.p));
|
||||
if (flash_pgm.p.result[0] != IAP_STATUS_CMD_SUCCESS) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -249,7 +249,7 @@ lpc11xx_flash_erase(struct target_s *target, uint32_t addr, size_t len)
|
|||
}
|
||||
|
||||
static int
|
||||
lpc11xx_flash_write(struct target_s *target, uint32_t dest, const uint8_t *src, size_t len)
|
||||
lpc11xx_flash_write(target *t, uint32_t dest, const uint8_t *src, size_t len)
|
||||
{
|
||||
unsigned first_chunk = dest / IAP_PGM_CHUNKSIZE;
|
||||
unsigned last_chunk = (dest + len - 1) / IAP_PGM_CHUNKSIZE;
|
||||
|
@ -300,7 +300,7 @@ lpc11xx_flash_write(struct target_s *target, uint32_t dest, const uint8_t *src,
|
|||
}
|
||||
|
||||
/* prepare... */
|
||||
if (lpc11xx_flash_prepare(target, chunk * IAP_PGM_CHUNKSIZE, IAP_PGM_CHUNKSIZE))
|
||||
if (lpc11xx_flash_prepare(t, chunk * IAP_PGM_CHUNKSIZE, IAP_PGM_CHUNKSIZE))
|
||||
return -1;
|
||||
|
||||
/* set the destination address and program */
|
||||
|
@ -310,7 +310,7 @@ lpc11xx_flash_write(struct target_s *target, uint32_t dest, const uint8_t *src,
|
|||
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? */
|
||||
lpc11x_iap_call(target, &flash_pgm.p, sizeof(flash_pgm));
|
||||
lpc11x_iap_call(t, &flash_pgm.p, sizeof(flash_pgm));
|
||||
if (flash_pgm.p.result[0] != IAP_STATUS_CMD_SUCCESS) {
|
||||
return -1;
|
||||
}
|
||||
|
|
135
src/lpc43xx.c
135
src/lpc43xx.c
|
@ -119,20 +119,20 @@ struct flash_program {
|
|||
uint8_t data[IAP_PGM_CHUNKSIZE];
|
||||
};
|
||||
|
||||
static bool lpc43xx_cmd_erase(target *target, int argc, const char *argv[]);
|
||||
static bool lpc43xx_cmd_reset(target *target, int argc, const char *argv[]);
|
||||
static bool lpc43xx_cmd_mkboot(target *target, int argc, const char *argv[]);
|
||||
static int lpc43xx_flash_init(struct target_s *target);
|
||||
static void lpc43xx_iap_call(struct target_s *target, struct flash_param *param,
|
||||
static bool lpc43xx_cmd_erase(target *t, int argc, const char *argv[]);
|
||||
static bool lpc43xx_cmd_reset(target *t, int argc, const char *argv[]);
|
||||
static bool lpc43xx_cmd_mkboot(target *t, int argc, const char *argv[]);
|
||||
static int lpc43xx_flash_init(target *t);
|
||||
static void lpc43xx_iap_call(target *t, struct flash_param *param,
|
||||
unsigned param_len);
|
||||
static int lpc43xx_flash_prepare(struct target_s *target,
|
||||
static int lpc43xx_flash_prepare(target *t,
|
||||
uint32_t addr, int len);
|
||||
static int lpc43xx_flash_erase(struct target_s *target, uint32_t addr, size_t len);
|
||||
static int lpc43xx_flash_write(struct target_s *target,
|
||||
static int lpc43xx_flash_erase(target *t, uint32_t addr, size_t len);
|
||||
static int lpc43xx_flash_write(target *t,
|
||||
uint32_t dest, const uint8_t *src, size_t len);
|
||||
static void lpc43xx_set_internal_clock(struct target_s *target);
|
||||
static void lpc43xx_wdt_set_period(struct target_s *target);
|
||||
static void lpc43xx_wdt_pet(struct target_s *target);
|
||||
static void lpc43xx_set_internal_clock(target *t);
|
||||
static void lpc43xx_wdt_set_period(target *t);
|
||||
static void lpc43xx_wdt_pet(target *t);
|
||||
|
||||
const struct command_s lpc43xx_cmd_list[] = {
|
||||
{"erase_mass", lpc43xx_cmd_erase, "Erase entire flash memory"},
|
||||
|
@ -166,45 +166,45 @@ static const char lpc4337_xml_memory_map[] = "<?xml version=\"1.0\"?>"
|
|||
" <memory type=\"ram\" start=\"0x1B080000\" length=\"0xE4F80000\"/>"
|
||||
"</memory-map>";
|
||||
|
||||
bool lpc43xx_probe(struct target_s *target)
|
||||
bool lpc43xx_probe(target *t)
|
||||
{
|
||||
uint32_t chipid, cpuid;
|
||||
|
||||
chipid = target_mem_read32(target, LPC43XX_CHIPID);
|
||||
cpuid = target_mem_read32(target, ARM_CPUID);
|
||||
chipid = target_mem_read32(t, LPC43XX_CHIPID);
|
||||
cpuid = target_mem_read32(t, ARM_CPUID);
|
||||
|
||||
switch(chipid) {
|
||||
case 0x4906002B: /* Parts with on-chip flash */
|
||||
switch (cpuid & 0xFF00FFF0) {
|
||||
case 0x4100C240:
|
||||
target->driver = "LPC43xx Cortex-M4";
|
||||
t->driver = "LPC43xx Cortex-M4";
|
||||
if (cpuid == 0x410FC241)
|
||||
{
|
||||
/* LPC4337 */
|
||||
target->xml_mem_map = lpc4337_xml_memory_map;
|
||||
target->flash_erase = lpc43xx_flash_erase;
|
||||
target->flash_write = lpc43xx_flash_write;
|
||||
target_add_commands(target, lpc43xx_cmd_list, "LPC43xx");
|
||||
t->xml_mem_map = lpc4337_xml_memory_map;
|
||||
t->flash_erase = lpc43xx_flash_erase;
|
||||
t->flash_write = lpc43xx_flash_write;
|
||||
target_add_commands(t, lpc43xx_cmd_list, "LPC43xx");
|
||||
}
|
||||
break;
|
||||
case 0x4100C200:
|
||||
target->driver = "LPC43xx Cortex-M0";
|
||||
t->driver = "LPC43xx Cortex-M0";
|
||||
break;
|
||||
default:
|
||||
target->driver = "LPC43xx <Unknown>";
|
||||
t->driver = "LPC43xx <Unknown>";
|
||||
}
|
||||
return true;
|
||||
case 0x5906002B: /* Flashless parts */
|
||||
case 0x6906002B:
|
||||
switch (cpuid & 0xFF00FFF0) {
|
||||
case 0x4100C240:
|
||||
target->driver = "LPC43xx Cortex-M4";
|
||||
t->driver = "LPC43xx Cortex-M4";
|
||||
break;
|
||||
case 0x4100C200:
|
||||
target->driver = "LPC43xx Cortex-M0";
|
||||
t->driver = "LPC43xx Cortex-M0";
|
||||
break;
|
||||
default:
|
||||
target->driver = "LPC43xx <Unknown>";
|
||||
t->driver = "LPC43xx <Unknown>";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -213,7 +213,7 @@ bool lpc43xx_probe(struct target_s *target)
|
|||
}
|
||||
|
||||
/* Reset all major systems _except_ debug */
|
||||
static bool lpc43xx_cmd_reset(target *target, int argc, const char *argv[])
|
||||
static bool lpc43xx_cmd_reset(target *t, int argc, const char *argv[])
|
||||
{
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
@ -224,12 +224,12 @@ static bool lpc43xx_cmd_reset(target *target, int argc, const char *argv[])
|
|||
static const uint32_t reset_val = 0x05FA0004;
|
||||
|
||||
/* System reset on target */
|
||||
target_mem_write(target, AIRCR, &reset_val, sizeof(reset_val));
|
||||
target_mem_write(t, AIRCR, &reset_val, sizeof(reset_val));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool lpc43xx_cmd_erase(target *target, int argc, const char *argv[])
|
||||
static bool lpc43xx_cmd_erase(target *t, int argc, const char *argv[])
|
||||
{
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
@ -237,7 +237,7 @@ static bool lpc43xx_cmd_erase(target *target, int argc, const char *argv[])
|
|||
uint32_t bank = 0;
|
||||
struct flash_program flash_pgm;
|
||||
|
||||
lpc43xx_flash_init(target);
|
||||
lpc43xx_flash_init(t);
|
||||
|
||||
for (bank = 0; bank < FLASH_NUM_BANK; bank++)
|
||||
{
|
||||
|
@ -246,7 +246,7 @@ static bool lpc43xx_cmd_erase(target *target, int argc, const char *argv[])
|
|||
flash_pgm.p.params.prepare.end_sector = FLASH_NUM_SECTOR-1;
|
||||
flash_pgm.p.params.prepare.flash_bank = bank;
|
||||
flash_pgm.p.result[0] = IAP_STATUS_CMD_SUCCESS;
|
||||
lpc43xx_iap_call(target, &flash_pgm.p, sizeof(flash_pgm.p));
|
||||
lpc43xx_iap_call(t, &flash_pgm.p, sizeof(flash_pgm.p));
|
||||
if (flash_pgm.p.result[0] != IAP_STATUS_CMD_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
|
@ -257,7 +257,7 @@ static bool lpc43xx_cmd_erase(target *target, int argc, const char *argv[])
|
|||
flash_pgm.p.params.erase.cpu_clk_khz = CPU_CLK_KHZ;
|
||||
flash_pgm.p.params.erase.flash_bank = bank;
|
||||
flash_pgm.p.result[0] = IAP_STATUS_CMD_SUCCESS;
|
||||
lpc43xx_iap_call(target, &flash_pgm.p, sizeof(flash_pgm.p));
|
||||
lpc43xx_iap_call(t, &flash_pgm.p, sizeof(flash_pgm.p));
|
||||
if (flash_pgm.p.result[0] != IAP_STATUS_CMD_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
|
@ -269,20 +269,20 @@ static bool lpc43xx_cmd_erase(target *target, int argc, const char *argv[])
|
|||
return true;
|
||||
}
|
||||
|
||||
static int lpc43xx_flash_init(struct target_s *target)
|
||||
static int lpc43xx_flash_init(target *t)
|
||||
{
|
||||
/* Deal with WDT */
|
||||
lpc43xx_wdt_set_period(target);
|
||||
lpc43xx_wdt_set_period(t);
|
||||
|
||||
/* Force internal clock */
|
||||
lpc43xx_set_internal_clock(target);
|
||||
lpc43xx_set_internal_clock(t);
|
||||
|
||||
struct flash_program flash_pgm;
|
||||
|
||||
/* Initialize flash IAP */
|
||||
flash_pgm.p.command = IAP_CMD_INIT;
|
||||
flash_pgm.p.result[0] = IAP_STATUS_CMD_SUCCESS;
|
||||
lpc43xx_iap_call(target, &flash_pgm.p, sizeof(flash_pgm.p));
|
||||
lpc43xx_iap_call(t, &flash_pgm.p, sizeof(flash_pgm.p));
|
||||
if (flash_pgm.p.result[0] != IAP_STATUS_CMD_SUCCESS)
|
||||
return -1;
|
||||
|
||||
|
@ -332,40 +332,40 @@ static int32_t sector_number(uint32_t addr)
|
|||
}
|
||||
}
|
||||
|
||||
static void lpc43xx_iap_call(struct target_s *target, struct flash_param *param, unsigned param_len)
|
||||
static void lpc43xx_iap_call(target *t, struct flash_param *param, unsigned param_len)
|
||||
{
|
||||
uint32_t regs[target->regs_size / sizeof(uint32_t)];
|
||||
uint32_t regs[t->regs_size / sizeof(uint32_t)];
|
||||
uint32_t iap_entry;
|
||||
|
||||
/* Pet WDT before each IAP call, if it is on */
|
||||
lpc43xx_wdt_pet(target);
|
||||
lpc43xx_wdt_pet(t);
|
||||
|
||||
target_mem_read(target, &iap_entry, IAP_ENTRYPOINT_LOCATION, sizeof(iap_entry));
|
||||
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 */
|
||||
target_mem_write(target, IAP_RAM_BASE, param, param_len);
|
||||
target_mem_write(t, IAP_RAM_BASE, param, param_len);
|
||||
|
||||
/* set up for the call to the IAP ROM */
|
||||
target_regs_read(target, regs);
|
||||
target_regs_read(t, regs);
|
||||
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;
|
||||
target_regs_write(target, regs);
|
||||
target_regs_write(t, regs);
|
||||
|
||||
/* start the target and wait for it to halt again */
|
||||
target_halt_resume(target, 0);
|
||||
while (!target_halt_wait(target));
|
||||
target_halt_resume(t, 0);
|
||||
while (!target_halt_wait(t));
|
||||
|
||||
/* copy back just the parameters structure */
|
||||
target_mem_read(target, param, IAP_RAM_BASE, sizeof(struct flash_param));
|
||||
target_mem_read(t, param, IAP_RAM_BASE, sizeof(struct flash_param));
|
||||
}
|
||||
|
||||
static int lpc43xx_flash_prepare(struct target_s *target, uint32_t addr, int len)
|
||||
static int lpc43xx_flash_prepare(target *t, uint32_t addr, int len)
|
||||
{
|
||||
struct flash_program flash_pgm;
|
||||
|
||||
|
@ -376,7 +376,7 @@ static int lpc43xx_flash_prepare(struct target_s *target, uint32_t addr, int len
|
|||
flash_pgm.p.params.prepare.flash_bank = flash_bank(addr);
|
||||
flash_pgm.p.result[0] = IAP_STATUS_CMD_SUCCESS;
|
||||
|
||||
lpc43xx_iap_call(target, &flash_pgm.p, sizeof(flash_pgm.p));
|
||||
lpc43xx_iap_call(t, &flash_pgm.p, sizeof(flash_pgm.p));
|
||||
if (flash_pgm.p.result[0] != IAP_STATUS_CMD_SUCCESS) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -384,7 +384,7 @@ static int lpc43xx_flash_prepare(struct target_s *target, uint32_t addr, int len
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int lpc43xx_flash_erase(struct target_s *target, uint32_t addr, size_t len)
|
||||
static int lpc43xx_flash_erase(target *t, uint32_t addr, size_t len)
|
||||
{
|
||||
struct flash_program flash_pgm;
|
||||
|
||||
|
@ -393,11 +393,11 @@ static int lpc43xx_flash_erase(struct target_s *target, uint32_t addr, size_t le
|
|||
return -1;
|
||||
|
||||
/* init */
|
||||
if (lpc43xx_flash_init(target))
|
||||
if (lpc43xx_flash_init(t))
|
||||
return -1;
|
||||
|
||||
/* prepare... */
|
||||
if (lpc43xx_flash_prepare(target, addr, len))
|
||||
if (lpc43xx_flash_prepare(t, addr, len))
|
||||
return -1;
|
||||
|
||||
/* and now erase them */
|
||||
|
@ -407,7 +407,7 @@ static int lpc43xx_flash_erase(struct target_s *target, uint32_t addr, size_t le
|
|||
flash_pgm.p.params.erase.cpu_clk_khz = CPU_CLK_KHZ;
|
||||
flash_pgm.p.params.erase.flash_bank = flash_bank(addr);
|
||||
flash_pgm.p.result[0] = IAP_STATUS_CMD_SUCCESS;
|
||||
lpc43xx_iap_call(target, &flash_pgm.p, sizeof(flash_pgm.p));
|
||||
lpc43xx_iap_call(t, &flash_pgm.p, sizeof(flash_pgm.p));
|
||||
if (flash_pgm.p.result[0] != IAP_STATUS_CMD_SUCCESS) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -418,7 +418,7 @@ static int lpc43xx_flash_erase(struct target_s *target, uint32_t addr, size_t le
|
|||
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.result[0] = IAP_STATUS_CMD_SUCCESS;
|
||||
lpc43xx_iap_call(target, &flash_pgm.p, sizeof(flash_pgm.p));
|
||||
lpc43xx_iap_call(t, &flash_pgm.p, sizeof(flash_pgm.p));
|
||||
if (flash_pgm.p.result[0] != IAP_STATUS_CMD_SUCCESS) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -426,13 +426,13 @@ static int lpc43xx_flash_erase(struct target_s *target, uint32_t addr, size_t le
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void lpc43xx_set_internal_clock(struct target_s *target)
|
||||
static void lpc43xx_set_internal_clock(target *t)
|
||||
{
|
||||
const uint32_t val2 = (1 << 11) | (1 << 24);
|
||||
target_mem_write(target, 0x40050000 + 0x06C, &val2, sizeof(val2));
|
||||
target_mem_write(t, 0x40050000 + 0x06C, &val2, sizeof(val2));
|
||||
}
|
||||
|
||||
static int lpc43xx_flash_write(struct target_s *target,
|
||||
static int lpc43xx_flash_write(target *t,
|
||||
uint32_t dest, const uint8_t *src, size_t len)
|
||||
{
|
||||
unsigned first_chunk = dest / IAP_PGM_CHUNKSIZE;
|
||||
|
@ -472,12 +472,12 @@ static int lpc43xx_flash_write(struct target_s *target,
|
|||
}
|
||||
|
||||
/* prepare... */
|
||||
if (lpc43xx_flash_prepare(target, 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(target,
|
||||
target_mem_write(t,
|
||||
IAP_RAM_BASE + offsetof(struct flash_program, data),
|
||||
flash_pgm.data, sizeof(flash_pgm.data));
|
||||
|
||||
|
@ -488,7 +488,7 @@ static int lpc43xx_flash_write(struct target_s *target,
|
|||
flash_pgm.p.params.program.byte_count = IAP_PGM_CHUNKSIZE;
|
||||
flash_pgm.p.params.program.cpu_clk_khz = CPU_CLK_KHZ;
|
||||
flash_pgm.p.result[0] = IAP_STATUS_CMD_SUCCESS;
|
||||
lpc43xx_iap_call(target, &flash_pgm.p, sizeof(flash_pgm));
|
||||
lpc43xx_iap_call(t, &flash_pgm.p, sizeof(flash_pgm));
|
||||
if (flash_pgm.p.result[0] != IAP_STATUS_CMD_SUCCESS) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -504,7 +504,7 @@ static int lpc43xx_flash_write(struct target_s *target,
|
|||
* This is done indepently of writing to give the user a chance to verify flash
|
||||
* before changing it.
|
||||
*/
|
||||
static bool lpc43xx_cmd_mkboot(target *target, int argc, const char *argv[])
|
||||
static bool lpc43xx_cmd_mkboot(target *t, int argc, const char *argv[])
|
||||
{
|
||||
/* Usage: mkboot 0 or mkboot 1 */
|
||||
if (argc != 2) {
|
||||
|
@ -519,7 +519,7 @@ static bool lpc43xx_cmd_mkboot(target *target, int argc, const char *argv[])
|
|||
return false;
|
||||
}
|
||||
|
||||
lpc43xx_flash_init(target);
|
||||
lpc43xx_flash_init(t);
|
||||
struct flash_program flash_pgm;
|
||||
|
||||
/* special command to compute/write magic vector for signature */
|
||||
|
@ -527,7 +527,7 @@ static bool lpc43xx_cmd_mkboot(target *target, int argc, const char *argv[])
|
|||
flash_pgm.p.params.make_active.flash_bank = bank;
|
||||
flash_pgm.p.params.make_active.cpu_clk_khz = CPU_CLK_KHZ;
|
||||
flash_pgm.p.result[0] = IAP_STATUS_CMD_SUCCESS;
|
||||
lpc43xx_iap_call(target, &flash_pgm.p, sizeof(flash_pgm));
|
||||
lpc43xx_iap_call(t, &flash_pgm.p, sizeof(flash_pgm));
|
||||
if (flash_pgm.p.result[0] != IAP_STATUS_CMD_SUCCESS) {
|
||||
gdb_outf("Set bootable failed.\n");
|
||||
return false;
|
||||
|
@ -537,11 +537,11 @@ static bool lpc43xx_cmd_mkboot(target *target, int argc, const char *argv[])
|
|||
return true;
|
||||
}
|
||||
|
||||
static void lpc43xx_wdt_set_period(struct target_s *target)
|
||||
static void lpc43xx_wdt_set_period(target *t)
|
||||
{
|
||||
uint32_t wdt_mode = 0;
|
||||
/* Check if WDT is on */
|
||||
target_mem_read(target, &wdt_mode, LPC43XX_WDT_MODE, sizeof(wdt_mode));
|
||||
target_mem_read(t, &wdt_mode, LPC43XX_WDT_MODE, sizeof(wdt_mode));
|
||||
|
||||
/* If WDT on, we can't disable it, but we may be able to set a long period */
|
||||
if (wdt_mode && !(wdt_mode & LPC43XX_WDT_PROTECT))
|
||||
|
@ -549,15 +549,15 @@ static void lpc43xx_wdt_set_period(struct target_s *target)
|
|||
const uint32_t wdt_period = LPC43XX_WDT_PERIOD_MAX;
|
||||
|
||||
|
||||
target_mem_write(target, LPC43XX_WDT_CNT, &wdt_period, sizeof(wdt_period));
|
||||
target_mem_write(t, LPC43XX_WDT_CNT, &wdt_period, sizeof(wdt_period));
|
||||
}
|
||||
}
|
||||
|
||||
static void lpc43xx_wdt_pet(struct target_s *target)
|
||||
static void lpc43xx_wdt_pet(target *t)
|
||||
{
|
||||
uint32_t wdt_mode = 0;
|
||||
/* Check if WDT is on */
|
||||
target_mem_read(target, &wdt_mode, LPC43XX_WDT_MODE, sizeof(wdt_mode));
|
||||
target_mem_read(t, &wdt_mode, LPC43XX_WDT_MODE, sizeof(wdt_mode));
|
||||
|
||||
/* If WDT on, pet */
|
||||
if (wdt_mode)
|
||||
|
@ -565,8 +565,7 @@ static void lpc43xx_wdt_pet(struct target_s *target)
|
|||
const uint32_t feed1 = 0xAA;;
|
||||
const uint32_t feed2 = 0x55;;
|
||||
|
||||
|
||||
target_mem_write(target, LPC43XX_WDT_FEED, &feed1, sizeof(feed1));
|
||||
target_mem_write(target, LPC43XX_WDT_FEED, &feed2, sizeof(feed2));
|
||||
target_mem_write(t, LPC43XX_WDT_FEED, &feed1, sizeof(feed1));
|
||||
target_mem_write(t, LPC43XX_WDT_FEED, &feed2, sizeof(feed2));
|
||||
}
|
||||
}
|
||||
|
|
64
src/nrf51.c
64
src/nrf51.c
|
@ -28,8 +28,8 @@
|
|||
#include "gdb_packet.h"
|
||||
#include "cortexm.h"
|
||||
|
||||
static int nrf51_flash_erase(struct target_s *target, uint32_t addr, size_t len);
|
||||
static int nrf51_flash_write(struct target_s *target, uint32_t dest,
|
||||
static int nrf51_flash_erase(target *t, uint32_t addr, size_t len);
|
||||
static int nrf51_flash_write(target *t, uint32_t dest,
|
||||
const uint8_t *src, size_t len);
|
||||
|
||||
static bool nrf51_cmd_erase_all(target *t);
|
||||
|
@ -135,11 +135,11 @@ static const uint16_t nrf51_flash_write_stub[] = {
|
|||
|
||||
};
|
||||
|
||||
bool nrf51_probe(struct target_s *target)
|
||||
bool nrf51_probe(target *t)
|
||||
{
|
||||
target->idcode = target_mem_read32(target, NRF51_FICR_CONFIGID) & 0xFFFF;
|
||||
t->idcode = target_mem_read32(t, NRF51_FICR_CONFIGID) & 0xFFFF;
|
||||
|
||||
switch (target->idcode) {
|
||||
switch (t->idcode) {
|
||||
case 0x001D:
|
||||
case 0x002A:
|
||||
case 0x0044:
|
||||
|
@ -151,43 +151,43 @@ bool nrf51_probe(struct target_s *target)
|
|||
case 0x004D:
|
||||
case 0x0026:
|
||||
case 0x004C:
|
||||
target->driver = "Nordic nRF51";
|
||||
target->xml_mem_map = nrf51_xml_memory_map;
|
||||
target->flash_erase = nrf51_flash_erase;
|
||||
target->flash_write = nrf51_flash_write;
|
||||
target_add_commands(target, nrf51_cmd_list, "nRF51");
|
||||
t->driver = "Nordic nRF51";
|
||||
t->xml_mem_map = nrf51_xml_memory_map;
|
||||
t->flash_erase = nrf51_flash_erase;
|
||||
t->flash_write = nrf51_flash_write;
|
||||
target_add_commands(t, nrf51_cmd_list, "nRF51");
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int nrf51_flash_erase(struct target_s *target, uint32_t addr, size_t len)
|
||||
static int nrf51_flash_erase(target *t, uint32_t addr, size_t len)
|
||||
{
|
||||
addr &= ~(NRF51_PAGE_SIZE - 1);
|
||||
len &= ~(NRF51_PAGE_SIZE - 1);
|
||||
|
||||
/* Enable erase */
|
||||
target_mem_write32(target, NRF51_NVMC_CONFIG, NRF51_NVMC_CONFIG_EEN);
|
||||
target_mem_write32(t, NRF51_NVMC_CONFIG, NRF51_NVMC_CONFIG_EEN);
|
||||
|
||||
/* Poll for NVMC_READY */
|
||||
while (target_mem_read32(target, NRF51_NVMC_READY) == 0)
|
||||
if(target_check_error(target))
|
||||
while (target_mem_read32(t, NRF51_NVMC_READY) == 0)
|
||||
if(target_check_error(t))
|
||||
return -1;
|
||||
|
||||
while (len) {
|
||||
if (addr == NRF51_UICR) { // Special Case
|
||||
/* Write to the ERASE_UICR register to erase */
|
||||
target_mem_write32(target, NRF51_NVMC_ERASEUICR, 0x1);
|
||||
target_mem_write32(t, NRF51_NVMC_ERASEUICR, 0x1);
|
||||
|
||||
} else { // Standard Flash Page
|
||||
/* Write address of first word in page to erase it */
|
||||
target_mem_write32(target, NRF51_NVMC_ERASEPAGE, addr);
|
||||
target_mem_write32(t, NRF51_NVMC_ERASEPAGE, addr);
|
||||
}
|
||||
|
||||
/* Poll for NVMC_READY */
|
||||
while (target_mem_read32(target, NRF51_NVMC_READY) == 0)
|
||||
if(target_check_error(target))
|
||||
while (target_mem_read32(t, NRF51_NVMC_READY) == 0)
|
||||
if(target_check_error(t))
|
||||
return -1;
|
||||
|
||||
addr += NRF51_PAGE_SIZE;
|
||||
|
@ -195,17 +195,17 @@ static int nrf51_flash_erase(struct target_s *target, uint32_t addr, size_t len)
|
|||
}
|
||||
|
||||
/* Return to read-only */
|
||||
target_mem_write32(target, NRF51_NVMC_CONFIG, NRF51_NVMC_CONFIG_REN);
|
||||
target_mem_write32(t, NRF51_NVMC_CONFIG, NRF51_NVMC_CONFIG_REN);
|
||||
|
||||
/* Poll for NVMC_READY */
|
||||
while (target_mem_read32(target, NRF51_NVMC_READY) == 0)
|
||||
if(target_check_error(target))
|
||||
while (target_mem_read32(t, NRF51_NVMC_READY) == 0)
|
||||
if(target_check_error(t))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nrf51_flash_write(struct target_s *target, uint32_t dest,
|
||||
static int nrf51_flash_write(target *t, uint32_t dest,
|
||||
const uint8_t *src, size_t len)
|
||||
{
|
||||
uint32_t offset = dest % 4;
|
||||
|
@ -220,26 +220,26 @@ static int nrf51_flash_write(struct target_s *target, uint32_t dest,
|
|||
memcpy((uint8_t *)&data[2] + offset, src, len);
|
||||
|
||||
/* Enable write */
|
||||
target_mem_write32(target, NRF51_NVMC_CONFIG, NRF51_NVMC_CONFIG_WEN);
|
||||
target_mem_write32(t, NRF51_NVMC_CONFIG, NRF51_NVMC_CONFIG_WEN);
|
||||
|
||||
/* Poll for NVMC_READY */
|
||||
while (target_mem_read32(target, NRF51_NVMC_READY) == 0)
|
||||
if(target_check_error(target))
|
||||
while (target_mem_read32(t, NRF51_NVMC_READY) == 0)
|
||||
if(target_check_error(t))
|
||||
return -1;
|
||||
|
||||
/* Write stub and data to target ram and set PC */
|
||||
target_mem_write(target, 0x20000000, nrf51_flash_write_stub, 0x28);
|
||||
target_mem_write(target, 0x20000028, data, len + 8);
|
||||
cortexm_pc_write(target, 0x20000000);
|
||||
if(target_check_error(target))
|
||||
target_mem_write(t, 0x20000000, nrf51_flash_write_stub, 0x28);
|
||||
target_mem_write(t, 0x20000028, data, len + 8);
|
||||
cortexm_pc_write(t, 0x20000000);
|
||||
if(target_check_error(t))
|
||||
return -1;
|
||||
|
||||
/* Execute the stub */
|
||||
target_halt_resume(target, 0);
|
||||
while(!target_halt_wait(target));
|
||||
target_halt_resume(t, 0);
|
||||
while(!target_halt_wait(t));
|
||||
|
||||
/* Return to read-only */
|
||||
target_mem_write32(target, NRF51_NVMC_CONFIG, NRF51_NVMC_CONFIG_REN);
|
||||
target_mem_write32(t, NRF51_NVMC_CONFIG, NRF51_NVMC_CONFIG_REN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
104
src/sam3x.c
104
src/sam3x.c
|
@ -28,8 +28,8 @@
|
|||
#include "command.h"
|
||||
#include "gdb_packet.h"
|
||||
|
||||
static int sam3x_flash_erase(struct target_s *target, uint32_t addr, size_t len);
|
||||
static int sam3x_flash_write(struct target_s *target, uint32_t dest,
|
||||
static int sam3x_flash_erase(target *t, uint32_t addr, size_t len);
|
||||
static int sam3x_flash_write(target *t, uint32_t dest,
|
||||
const uint8_t *src, size_t len);
|
||||
|
||||
static bool sam3x_cmd_gpnvm_get(target *t);
|
||||
|
@ -146,59 +146,59 @@ static const char sam4s_xml_memory_map[] = "<?xml version=\"1.0\"?>"
|
|||
#define SAM3_PAGE_SIZE 256
|
||||
#define SAM4_PAGE_SIZE 512
|
||||
|
||||
bool sam3x_probe(struct target_s *target)
|
||||
bool sam3x_probe(target *t)
|
||||
{
|
||||
target->idcode = target_mem_read32(target, SAM3X_CHIPID_CIDR);
|
||||
t->idcode = target_mem_read32(t, SAM3X_CHIPID_CIDR);
|
||||
|
||||
/* FIXME: Check for all variants with similar flash interface */
|
||||
switch (target->idcode & (CHIPID_CIDR_ARCH_MASK | CHIPID_CIDR_EPROC_MASK)) {
|
||||
switch (t->idcode & (CHIPID_CIDR_ARCH_MASK | CHIPID_CIDR_EPROC_MASK)) {
|
||||
case CHIPID_CIDR_ARCH_SAM3XxC | CHIPID_CIDR_EPROC_CM3:
|
||||
case CHIPID_CIDR_ARCH_SAM3XxE | CHIPID_CIDR_EPROC_CM3:
|
||||
case CHIPID_CIDR_ARCH_SAM3XxG | CHIPID_CIDR_EPROC_CM3:
|
||||
target->driver = "Atmel SAM3X";
|
||||
target->xml_mem_map = sam3x_xml_memory_map;
|
||||
target->flash_erase = sam3x_flash_erase;
|
||||
target->flash_write = sam3x_flash_write;
|
||||
target_add_commands(target, sam3x_cmd_list, "SAM3X");
|
||||
t->driver = "Atmel SAM3X";
|
||||
t->xml_mem_map = sam3x_xml_memory_map;
|
||||
t->flash_erase = sam3x_flash_erase;
|
||||
t->flash_write = sam3x_flash_write;
|
||||
target_add_commands(t, sam3x_cmd_list, "SAM3X");
|
||||
return true;
|
||||
}
|
||||
|
||||
target->idcode = target_mem_read32(target, SAM3N_CHIPID_CIDR);
|
||||
switch (target->idcode & (CHIPID_CIDR_ARCH_MASK | CHIPID_CIDR_EPROC_MASK)) {
|
||||
t->idcode = target_mem_read32(t, SAM3N_CHIPID_CIDR);
|
||||
switch (t->idcode & (CHIPID_CIDR_ARCH_MASK | CHIPID_CIDR_EPROC_MASK)) {
|
||||
case CHIPID_CIDR_ARCH_SAM3NxA | CHIPID_CIDR_EPROC_CM3:
|
||||
case CHIPID_CIDR_ARCH_SAM3NxB | CHIPID_CIDR_EPROC_CM3:
|
||||
case CHIPID_CIDR_ARCH_SAM3NxC | CHIPID_CIDR_EPROC_CM3:
|
||||
target->driver = "Atmel SAM3N";
|
||||
target->xml_mem_map = sam3n_xml_memory_map;
|
||||
target->flash_erase = sam3x_flash_erase;
|
||||
target->flash_write = sam3x_flash_write;
|
||||
target_add_commands(target, sam3x_cmd_list, "SAM3N");
|
||||
t->driver = "Atmel SAM3N";
|
||||
t->xml_mem_map = sam3n_xml_memory_map;
|
||||
t->flash_erase = sam3x_flash_erase;
|
||||
t->flash_write = sam3x_flash_write;
|
||||
target_add_commands(t, sam3x_cmd_list, "SAM3N");
|
||||
return true;
|
||||
}
|
||||
|
||||
target->idcode = target_mem_read32(target, SAM3S_CHIPID_CIDR);
|
||||
switch (target->idcode & (CHIPID_CIDR_ARCH_MASK | CHIPID_CIDR_EPROC_MASK)) {
|
||||
t->idcode = target_mem_read32(t, SAM3S_CHIPID_CIDR);
|
||||
switch (t->idcode & (CHIPID_CIDR_ARCH_MASK | CHIPID_CIDR_EPROC_MASK)) {
|
||||
case CHIPID_CIDR_ARCH_SAM3SxA | CHIPID_CIDR_EPROC_CM3:
|
||||
case CHIPID_CIDR_ARCH_SAM3SxB | CHIPID_CIDR_EPROC_CM3:
|
||||
case CHIPID_CIDR_ARCH_SAM3SxC | CHIPID_CIDR_EPROC_CM3:
|
||||
target->driver = "Atmel SAM3S";
|
||||
target->xml_mem_map = sam3n_xml_memory_map;
|
||||
target->flash_erase = sam3x_flash_erase;
|
||||
target->flash_write = sam3x_flash_write;
|
||||
target_add_commands(target, sam3x_cmd_list, "SAM3S");
|
||||
t->driver = "Atmel SAM3S";
|
||||
t->xml_mem_map = sam3n_xml_memory_map;
|
||||
t->flash_erase = sam3x_flash_erase;
|
||||
t->flash_write = sam3x_flash_write;
|
||||
target_add_commands(t, sam3x_cmd_list, "SAM3S");
|
||||
return true;
|
||||
}
|
||||
|
||||
target->idcode = target_mem_read32(target, SAM4S_CHIPID_CIDR);
|
||||
switch (target->idcode & (CHIPID_CIDR_ARCH_MASK | CHIPID_CIDR_EPROC_MASK)) {
|
||||
t->idcode = target_mem_read32(t, SAM4S_CHIPID_CIDR);
|
||||
switch (t->idcode & (CHIPID_CIDR_ARCH_MASK | CHIPID_CIDR_EPROC_MASK)) {
|
||||
case CHIPID_CIDR_ARCH_SAM4SxA | CHIPID_CIDR_EPROC_CM4:
|
||||
case CHIPID_CIDR_ARCH_SAM4SxB | CHIPID_CIDR_EPROC_CM4:
|
||||
case CHIPID_CIDR_ARCH_SAM4SxC | CHIPID_CIDR_EPROC_CM4:
|
||||
target->driver = "Atmel SAM4S";
|
||||
target->xml_mem_map = sam4s_xml_memory_map;
|
||||
target->flash_erase = sam3x_flash_erase;
|
||||
target->flash_write = sam3x_flash_write;
|
||||
target_add_commands(target, sam3x_cmd_list, "SAM4S");
|
||||
t->driver = "Atmel SAM4S";
|
||||
t->xml_mem_map = sam4s_xml_memory_map;
|
||||
t->flash_erase = sam3x_flash_erase;
|
||||
t->flash_write = sam3x_flash_write;
|
||||
target_add_commands(t, sam3x_cmd_list, "SAM4S");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -206,27 +206,27 @@ bool sam3x_probe(struct target_s *target)
|
|||
}
|
||||
|
||||
static int
|
||||
sam3x_flash_cmd(struct target_s *target, uint32_t base, uint8_t cmd, uint16_t arg)
|
||||
sam3x_flash_cmd(target *t, uint32_t base, uint8_t cmd, uint16_t arg)
|
||||
{
|
||||
DEBUG("%s: base = 0x%08x cmd = 0x%02X, arg = 0x%06X\n",
|
||||
__func__, base, cmd, arg);
|
||||
target_mem_write32(target, EEFC_FCR(base),
|
||||
target_mem_write32(t, EEFC_FCR(base),
|
||||
EEFC_FCR_FKEY | cmd | ((uint32_t)arg << 8));
|
||||
|
||||
while (!(target_mem_read32(target, EEFC_FSR(base)) & EEFC_FSR_FRDY))
|
||||
if(target_check_error(target))
|
||||
while (!(target_mem_read32(t, EEFC_FSR(base)) & EEFC_FSR_FRDY))
|
||||
if(target_check_error(t))
|
||||
return -1;
|
||||
|
||||
uint32_t sr = target_mem_read32(target, EEFC_FSR(base));
|
||||
uint32_t sr = target_mem_read32(t, EEFC_FSR(base));
|
||||
return sr & EEFC_FSR_ERROR;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
sam3x_flash_base(struct target_s *target, uint32_t addr, uint32_t *offset)
|
||||
sam3x_flash_base(target *t, uint32_t addr, uint32_t *offset)
|
||||
{
|
||||
if (strcmp(target->driver, "Atmel SAM3X") == 0) {
|
||||
if (strcmp(t->driver, "Atmel SAM3X") == 0) {
|
||||
uint32_t half = -1;
|
||||
switch (target->idcode & CHIPID_CIDR_NVPSIZ_MASK) {
|
||||
switch (t->idcode & CHIPID_CIDR_NVPSIZ_MASK) {
|
||||
case CHIPID_CIDR_NVPSIZ_128K:
|
||||
half = 0x00090000;
|
||||
break;
|
||||
|
@ -248,9 +248,9 @@ sam3x_flash_base(struct target_s *target, uint32_t addr, uint32_t *offset)
|
|||
}
|
||||
}
|
||||
|
||||
if (strcmp(target->driver, "Atmel SAM4S") == 0) {
|
||||
if (strcmp(t->driver, "Atmel SAM4S") == 0) {
|
||||
uint32_t half = -1;
|
||||
switch (target->idcode & CHIPID_CIDR_NVPSIZ_MASK) {
|
||||
switch (t->idcode & CHIPID_CIDR_NVPSIZ_MASK) {
|
||||
case CHIPID_CIDR_NVPSIZ_128K:
|
||||
case CHIPID_CIDR_NVPSIZ_256K:
|
||||
case CHIPID_CIDR_NVPSIZ_512K:
|
||||
|
@ -281,16 +281,16 @@ sam3x_flash_base(struct target_s *target, uint32_t addr, uint32_t *offset)
|
|||
return SAM3N_EEFC_BASE;
|
||||
}
|
||||
|
||||
static int sam3x_flash_erase(struct target_s *target, uint32_t addr, size_t len)
|
||||
static int sam3x_flash_erase(target *t, uint32_t addr, size_t len)
|
||||
{
|
||||
uint32_t offset;
|
||||
uint32_t base = sam3x_flash_base(target, addr, &offset);
|
||||
uint32_t base = sam3x_flash_base(t, addr, &offset);
|
||||
|
||||
/* The SAM4S is the only supported device with a page erase command.
|
||||
* Erasing is done in 8-page chunks. arg[15:2] contains the page
|
||||
* number and arg[1:0] contains 0x1, indicating 8-page chunks.
|
||||
*/
|
||||
if (strcmp(target->driver, "Atmel SAM4S") == 0) {
|
||||
if (strcmp(t->driver, "Atmel SAM4S") == 0) {
|
||||
unsigned chunk = offset / SAM4_PAGE_SIZE;
|
||||
|
||||
/* Fail if the start address is not 8-page-aligned. */
|
||||
|
@ -302,7 +302,7 @@ static int sam3x_flash_erase(struct target_s *target, uint32_t addr, size_t len)
|
|||
*/
|
||||
while (len > 0) {
|
||||
int16_t arg = chunk | 0x1;
|
||||
if(sam3x_flash_cmd(target, base, EEFC_FCR_FCMD_EPA, arg))
|
||||
if(sam3x_flash_cmd(t, base, EEFC_FCR_FCMD_EPA, arg))
|
||||
return -1;
|
||||
|
||||
len -= SAM4_PAGE_SIZE * 8;
|
||||
|
@ -322,10 +322,10 @@ static int sam3x_flash_erase(struct target_s *target, uint32_t addr, size_t len)
|
|||
|
||||
memset(buf, 0xff, sizeof(buf));
|
||||
/* Only do this once, since it doesn't change. */
|
||||
target_mem_write(target, addr, buf, SAM3_PAGE_SIZE);
|
||||
target_mem_write(t, addr, buf, SAM3_PAGE_SIZE);
|
||||
|
||||
while (len) {
|
||||
if(sam3x_flash_cmd(target, base, EEFC_FCR_FCMD_EWP, chunk))
|
||||
if(sam3x_flash_cmd(t, base, EEFC_FCR_FCMD_EWP, chunk))
|
||||
return -1;
|
||||
|
||||
len -= SAM3_PAGE_SIZE;
|
||||
|
@ -336,17 +336,17 @@ static int sam3x_flash_erase(struct target_s *target, uint32_t addr, size_t len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int sam3x_flash_write(struct target_s *target, uint32_t dest,
|
||||
static int sam3x_flash_write(target *t, uint32_t dest,
|
||||
const uint8_t *src, size_t len)
|
||||
{
|
||||
unsigned page_size;
|
||||
if (strcmp(target->driver, "Atmel SAM4S") == 0) {
|
||||
if (strcmp(t->driver, "Atmel SAM4S") == 0) {
|
||||
page_size = SAM4_PAGE_SIZE;
|
||||
} else {
|
||||
page_size = SAM3_PAGE_SIZE;
|
||||
}
|
||||
uint32_t offset;
|
||||
uint32_t base = sam3x_flash_base(target, dest, &offset);
|
||||
uint32_t base = sam3x_flash_base(t, dest, &offset);
|
||||
uint8_t buf[page_size];
|
||||
unsigned first_chunk = offset / page_size;
|
||||
unsigned last_chunk = (offset + len - 1) / page_size;
|
||||
|
@ -380,8 +380,8 @@ static int sam3x_flash_write(struct target_s *target, uint32_t dest,
|
|||
src += page_size;
|
||||
}
|
||||
|
||||
target_mem_write(target, dest, buf, page_size);
|
||||
if(sam3x_flash_cmd(target, base, EEFC_FCR_FCMD_WP, chunk))
|
||||
target_mem_write(t, dest, buf, page_size);
|
||||
if(sam3x_flash_cmd(t, base, EEFC_FCR_FCMD_WP, chunk))
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
119
src/samd.c
119
src/samd.c
|
@ -40,8 +40,8 @@
|
|||
#include "gdb_packet.h"
|
||||
#include "cortexm.h"
|
||||
|
||||
static int samd_flash_erase(struct target_s *target, uint32_t addr, size_t len);
|
||||
static int samd_flash_write(struct target_s *target, uint32_t dest,
|
||||
static int samd_flash_erase(target *t, uint32_t addr, size_t len);
|
||||
static int samd_flash_write(target *t, uint32_t dest,
|
||||
const uint8_t *src, size_t len);
|
||||
|
||||
static bool samd_cmd_erase_all(target *t);
|
||||
|
@ -162,28 +162,28 @@ static const char samd_xml_memory_map[] = "<?xml version=\"1.0\"?>"
|
|||
/**
|
||||
* Reads the SAM D20 Peripheral ID
|
||||
*/
|
||||
uint64_t samd_read_pid(struct target_s *target)
|
||||
uint64_t samd_read_pid(target *t)
|
||||
{
|
||||
uint64_t pid = 0;
|
||||
uint8_t i, j;
|
||||
|
||||
/* Five PID registers to read LSB first */
|
||||
for (i = 0, j = 0; i < 5; i++, j += 8)
|
||||
pid |= (target_mem_read32(target, SAMD_DSU_PID(i)) & 0xFF) << j;
|
||||
pid |= (target_mem_read32(t, SAMD_DSU_PID(i)) & 0xFF) << j;
|
||||
|
||||
return pid;
|
||||
}
|
||||
/**
|
||||
* Reads the SAM D20 Component ID
|
||||
*/
|
||||
uint32_t samd_read_cid(struct target_s *target)
|
||||
uint32_t samd_read_cid(target *t)
|
||||
{
|
||||
uint64_t cid = 0;
|
||||
uint8_t i, j;
|
||||
|
||||
/* Four CID registers to read LSB first */
|
||||
for (i = 0, j = 0; i < 4; i++, j += 8)
|
||||
cid |= (target_mem_read32(target, SAMD_DSU_CID(i)) & 0xFF) << j;
|
||||
cid |= (target_mem_read32(t, SAMD_DSU_CID(i)) & 0xFF) << j;
|
||||
|
||||
return cid;
|
||||
}
|
||||
|
@ -193,7 +193,7 @@ uint32_t samd_read_cid(struct target_s *target)
|
|||
* removes the target from extended reset where required.
|
||||
*/
|
||||
static void
|
||||
samd_reset(struct target_s *target)
|
||||
samd_reset(target *t)
|
||||
{
|
||||
/**
|
||||
* SRST is not asserted here as it appears to reset the adiv5
|
||||
|
@ -212,31 +212,30 @@ samd_reset(struct target_s *target)
|
|||
*/
|
||||
|
||||
/* Read DHCSR here to clear S_RESET_ST bit before reset */
|
||||
target_mem_read32(target, CORTEXM_DHCSR);
|
||||
target_mem_read32(t, CORTEXM_DHCSR);
|
||||
|
||||
/* Request system reset from NVIC: SRST doesn't work correctly */
|
||||
/* This could be VECTRESET: 0x05FA0001 (reset only core)
|
||||
* or SYSRESETREQ: 0x05FA0004 (system reset)
|
||||
*/
|
||||
target_mem_write32(target, CORTEXM_AIRCR,
|
||||
target_mem_write32(t, CORTEXM_AIRCR,
|
||||
CORTEXM_AIRCR_VECTKEY | CORTEXM_AIRCR_SYSRESETREQ);
|
||||
|
||||
/* Exit extended reset */
|
||||
if (target_mem_read32(target, SAMD_DSU_CTRLSTAT) &
|
||||
if (target_mem_read32(t, SAMD_DSU_CTRLSTAT) &
|
||||
SAMD_STATUSA_CRSTEXT) {
|
||||
/* Write bit to clear from extended reset */
|
||||
target_mem_write32(target, SAMD_DSU_CTRLSTAT,
|
||||
SAMD_STATUSA_CRSTEXT);
|
||||
target_mem_write32(t, SAMD_DSU_CTRLSTAT, SAMD_STATUSA_CRSTEXT);
|
||||
}
|
||||
|
||||
/* Poll for release from reset */
|
||||
while (target_mem_read32(target, CORTEXM_DHCSR) & CORTEXM_DHCSR_S_RESET_ST);
|
||||
while (target_mem_read32(t, CORTEXM_DHCSR) & CORTEXM_DHCSR_S_RESET_ST);
|
||||
|
||||
/* Reset DFSR flags */
|
||||
target_mem_write32(target, CORTEXM_DFSR, CORTEXM_DFSR_RESETALL);
|
||||
target_mem_write32(t, CORTEXM_DFSR, CORTEXM_DFSR_RESETALL);
|
||||
|
||||
/* Clear any target errors */
|
||||
target_check_error(target);
|
||||
target_check_error(t);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -246,16 +245,16 @@ samd_reset(struct target_s *target)
|
|||
* Only required for SAM D20 _Revision B_ Silicon
|
||||
*/
|
||||
static void
|
||||
samd20_revB_detach(struct target_s *target)
|
||||
samd20_revB_detach(target *t)
|
||||
{
|
||||
cortexm_detach(target);
|
||||
cortexm_detach(t);
|
||||
|
||||
/* ---- Additional ---- */
|
||||
/* Exit extended reset */
|
||||
if (target_mem_read32(target, SAMD_DSU_CTRLSTAT) &
|
||||
if (target_mem_read32(t, SAMD_DSU_CTRLSTAT) &
|
||||
SAMD_STATUSA_CRSTEXT) {
|
||||
/* Write bit to clear from extended reset */
|
||||
target_mem_write32(target, SAMD_DSU_CTRLSTAT,
|
||||
target_mem_write32(t, SAMD_DSU_CTRLSTAT,
|
||||
SAMD_STATUSA_CRSTEXT);
|
||||
}
|
||||
}
|
||||
|
@ -267,16 +266,15 @@ samd20_revB_detach(struct target_s *target)
|
|||
* Only required for SAM D20 _Revision B_ Silicon
|
||||
*/
|
||||
static void
|
||||
samd20_revB_halt_resume(struct target_s *target, bool step)
|
||||
samd20_revB_halt_resume(target *t, bool step)
|
||||
{
|
||||
cortexm_halt_resume(target, step);
|
||||
cortexm_halt_resume(t, step);
|
||||
|
||||
/* ---- Additional ---- */
|
||||
/* Exit extended reset */
|
||||
if (target_mem_read32(target, SAMD_DSU_CTRLSTAT) &
|
||||
SAMD_STATUSA_CRSTEXT) {
|
||||
if (target_mem_read32(t, SAMD_DSU_CTRLSTAT) & SAMD_STATUSA_CRSTEXT) {
|
||||
/* Write bit to clear from extended reset */
|
||||
target_mem_write32(target, SAMD_DSU_CTRLSTAT,
|
||||
target_mem_write32(t, SAMD_DSU_CTRLSTAT,
|
||||
SAMD_STATUSA_CRSTEXT);
|
||||
}
|
||||
}
|
||||
|
@ -290,7 +288,7 @@ samd20_revB_halt_resume(struct target_s *target, bool step)
|
|||
* rescue the device.
|
||||
*/
|
||||
static bool
|
||||
samd_protected_attach(struct target_s *target)
|
||||
samd_protected_attach(target *t)
|
||||
{
|
||||
/**
|
||||
* TODO: Notify the user that we're not really attached and
|
||||
|
@ -299,7 +297,7 @@ samd_protected_attach(struct target_s *target)
|
|||
*/
|
||||
|
||||
/* Patch back in the normal cortexm attach for next time */
|
||||
target->attach = cortexm_attach;
|
||||
t->attach = cortexm_attach;
|
||||
|
||||
/* Allow attach this time */
|
||||
return true;
|
||||
|
@ -365,10 +363,10 @@ struct samd_descr samd_parse_device_id(uint32_t did)
|
|||
|
||||
|
||||
char variant_string[40];
|
||||
bool samd_probe(struct target_s *target)
|
||||
bool samd_probe(target *t)
|
||||
{
|
||||
uint32_t cid = samd_read_cid(target);
|
||||
uint32_t pid = samd_read_pid(target);
|
||||
uint32_t cid = samd_read_cid(t);
|
||||
uint32_t pid = samd_read_pid(t);
|
||||
|
||||
/* Check the ARM Coresight Component and Perhiperal IDs */
|
||||
if ((cid != SAMD_CID_VALUE) ||
|
||||
|
@ -376,14 +374,13 @@ bool samd_probe(struct target_s *target)
|
|||
return false;
|
||||
|
||||
/* Read the Device ID */
|
||||
uint32_t did = target_mem_read32(target, SAMD_DSU_DID);
|
||||
uint32_t did = target_mem_read32(t, SAMD_DSU_DID);
|
||||
|
||||
/* If the Device ID matches */
|
||||
if ((did & SAMD_DID_MASK) != SAMD_DID_CONST_VALUE)
|
||||
return false;
|
||||
|
||||
uint32_t ctrlstat = target_mem_read32(target,
|
||||
SAMD_DSU_CTRLSTAT);
|
||||
uint32_t ctrlstat = target_mem_read32(t, SAMD_DSU_CTRLSTAT);
|
||||
struct samd_descr samd = samd_parse_device_id(did);
|
||||
|
||||
/* Protected? */
|
||||
|
@ -403,8 +400,8 @@ bool samd_probe(struct target_s *target)
|
|||
}
|
||||
|
||||
/* Setup Target */
|
||||
target->driver = variant_string;
|
||||
target->reset = samd_reset;
|
||||
t->driver = variant_string;
|
||||
t->reset = samd_reset;
|
||||
|
||||
if (samd.series == 20 && samd.revision == 'B') {
|
||||
/**
|
||||
|
@ -412,8 +409,8 @@ bool samd_probe(struct target_s *target)
|
|||
* extended reset. Appears to be
|
||||
* related to Errata 35.4.1 ref 12015
|
||||
*/
|
||||
target->detach = samd20_revB_detach;
|
||||
target->halt_resume = samd20_revB_halt_resume;
|
||||
t->detach = samd20_revB_detach;
|
||||
t->halt_resume = samd20_revB_halt_resume;
|
||||
}
|
||||
if (protected) {
|
||||
/**
|
||||
|
@ -423,23 +420,23 @@ bool samd_probe(struct target_s *target)
|
|||
* attach on a temporary basis so they
|
||||
* can rescue the device.
|
||||
*/
|
||||
target->attach = samd_protected_attach;
|
||||
t->attach = samd_protected_attach;
|
||||
}
|
||||
|
||||
target->xml_mem_map = samd_xml_memory_map;
|
||||
target->flash_erase = samd_flash_erase;
|
||||
target->flash_write = samd_flash_write;
|
||||
target_add_commands(target, samd_cmd_list, "SAMD");
|
||||
t->xml_mem_map = samd_xml_memory_map;
|
||||
t->flash_erase = samd_flash_erase;
|
||||
t->flash_write = samd_flash_write;
|
||||
target_add_commands(t, samd_cmd_list, "SAMD");
|
||||
|
||||
/* If we're not in reset here */
|
||||
if (!connect_assert_srst) {
|
||||
/* We'll have to release the target from
|
||||
* extended reset to make attach possible */
|
||||
if (target_mem_read32(target, SAMD_DSU_CTRLSTAT) &
|
||||
if (target_mem_read32(t, SAMD_DSU_CTRLSTAT) &
|
||||
SAMD_STATUSA_CRSTEXT) {
|
||||
|
||||
/* Write bit to clear from extended reset */
|
||||
target_mem_write32(target, SAMD_DSU_CTRLSTAT,
|
||||
target_mem_write32(t, SAMD_DSU_CTRLSTAT,
|
||||
SAMD_STATUSA_CRSTEXT);
|
||||
}
|
||||
}
|
||||
|
@ -450,23 +447,23 @@ bool samd_probe(struct target_s *target)
|
|||
/**
|
||||
* Temporary (until next reset) flash memory locking / unlocking
|
||||
*/
|
||||
static void samd_lock_current_address(struct target_s *target)
|
||||
static void samd_lock_current_address(target *t)
|
||||
{
|
||||
/* Issue the unlock command */
|
||||
target_mem_write32(target, SAMD_NVMC_CTRLA,
|
||||
target_mem_write32(t, SAMD_NVMC_CTRLA,
|
||||
SAMD_CTRLA_CMD_KEY | SAMD_CTRLA_CMD_LOCK);
|
||||
}
|
||||
static void samd_unlock_current_address(struct target_s *target)
|
||||
static void samd_unlock_current_address(target *t)
|
||||
{
|
||||
/* Issue the unlock command */
|
||||
target_mem_write32(target, SAMD_NVMC_CTRLA,
|
||||
target_mem_write32(t, SAMD_NVMC_CTRLA,
|
||||
SAMD_CTRLA_CMD_KEY | SAMD_CTRLA_CMD_UNLOCK);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erase flash row by row
|
||||
*/
|
||||
static int samd_flash_erase(struct target_s *target, uint32_t addr, size_t len)
|
||||
static int samd_flash_erase(target *t, uint32_t addr, size_t len)
|
||||
{
|
||||
addr &= ~(SAMD_ROW_SIZE - 1);
|
||||
len &= ~(SAMD_ROW_SIZE - 1);
|
||||
|
@ -474,21 +471,21 @@ static int samd_flash_erase(struct target_s *target, uint32_t addr, size_t len)
|
|||
while (len) {
|
||||
/* Write address of first word in row to erase it */
|
||||
/* Must be shifted right for 16-bit address, see Datasheet §20.8.8 Address */
|
||||
target_mem_write32(target, SAMD_NVMC_ADDRESS, addr >> 1);
|
||||
target_mem_write32(t, SAMD_NVMC_ADDRESS, addr >> 1);
|
||||
|
||||
/* Unlock */
|
||||
samd_unlock_current_address(target);
|
||||
samd_unlock_current_address(t);
|
||||
|
||||
/* Issue the erase command */
|
||||
target_mem_write32(target, SAMD_NVMC_CTRLA,
|
||||
target_mem_write32(t, SAMD_NVMC_CTRLA,
|
||||
SAMD_CTRLA_CMD_KEY | SAMD_CTRLA_CMD_ERASEROW);
|
||||
/* Poll for NVM Ready */
|
||||
while ((target_mem_read32(target, SAMD_NVMC_INTFLAG) & SAMD_NVMC_READY) == 0)
|
||||
if (target_check_error(target))
|
||||
while ((target_mem_read32(t, SAMD_NVMC_INTFLAG) & SAMD_NVMC_READY) == 0)
|
||||
if (target_check_error(t))
|
||||
return -1;
|
||||
|
||||
/* Lock */
|
||||
samd_lock_current_address(target);
|
||||
samd_lock_current_address(t);
|
||||
|
||||
addr += SAMD_ROW_SIZE;
|
||||
len -= SAMD_ROW_SIZE;
|
||||
|
@ -500,7 +497,7 @@ static int samd_flash_erase(struct target_s *target, uint32_t addr, size_t len)
|
|||
/**
|
||||
* Write flash page by page
|
||||
*/
|
||||
static int samd_flash_write(struct target_s *target, uint32_t dest,
|
||||
static int samd_flash_write(target *t, uint32_t dest,
|
||||
const uint8_t *src, size_t len)
|
||||
{
|
||||
/* Find the size of our 32-bit data buffer */
|
||||
|
@ -529,26 +526,26 @@ static int samd_flash_write(struct target_s *target, uint32_t dest,
|
|||
length = MIN(end + 4, next_page) - addr;
|
||||
|
||||
/* Write within a single page. This may be part or all of the page */
|
||||
target_mem_write(target, addr, &data[i], length);
|
||||
target_mem_write(t, addr, &data[i], length);
|
||||
addr += length; i += (length >> 2);
|
||||
|
||||
/* If MANW=0 (default) we may have triggered an automatic
|
||||
* write. Ignore this */
|
||||
|
||||
/* Unlock */
|
||||
samd_unlock_current_address(target);
|
||||
samd_unlock_current_address(t);
|
||||
|
||||
/* Issue the write page command */
|
||||
target_mem_write32(target, SAMD_NVMC_CTRLA,
|
||||
target_mem_write32(t, SAMD_NVMC_CTRLA,
|
||||
SAMD_CTRLA_CMD_KEY | SAMD_CTRLA_CMD_WRITEPAGE);
|
||||
|
||||
/* Poll for NVM Ready */
|
||||
while ((target_mem_read32(target, SAMD_NVMC_INTFLAG) & SAMD_NVMC_READY) == 0)
|
||||
if (target_check_error(target))
|
||||
while ((target_mem_read32(t, SAMD_NVMC_INTFLAG) & SAMD_NVMC_READY) == 0)
|
||||
if (target_check_error(t))
|
||||
return -1;
|
||||
|
||||
/* Lock */
|
||||
samd_lock_current_address(target);
|
||||
samd_lock_current_address(t);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -46,11 +46,11 @@ const struct command_s stm32f1_cmd_list[] = {
|
|||
};
|
||||
|
||||
|
||||
static int stm32md_flash_erase(struct target_s *target, uint32_t addr, size_t len);
|
||||
static int stm32hd_flash_erase(struct target_s *target, uint32_t addr, size_t len);
|
||||
static int stm32f1_flash_erase(struct target_s *target, uint32_t addr, size_t len,
|
||||
static int stm32md_flash_erase(target *t, uint32_t addr, size_t len);
|
||||
static int stm32hd_flash_erase(target *t, uint32_t addr, size_t len);
|
||||
static int stm32f1_flash_erase(target *t, uint32_t addr, size_t len,
|
||||
uint32_t pagesize);
|
||||
static int stm32f1_flash_write(struct target_s *target, uint32_t dest,
|
||||
static int stm32f1_flash_write(target *t, uint32_t dest,
|
||||
const uint8_t *src, size_t len);
|
||||
|
||||
static const char stm32f1_driver_str[] = "STM32, Medium density.";
|
||||
|
@ -127,66 +127,66 @@ static const uint16_t stm32f1_flash_write_stub[] = {
|
|||
#define SRAM_BASE 0x20000000
|
||||
#define STUB_BUFFER_BASE ALIGN(SRAM_BASE + sizeof(stm32f1_flash_write_stub), 4)
|
||||
|
||||
bool stm32f1_probe(struct target_s *target)
|
||||
bool stm32f1_probe(target *t)
|
||||
{
|
||||
target->idcode = target_mem_read32(target, DBGMCU_IDCODE) & 0xfff;
|
||||
switch(target->idcode) {
|
||||
t->idcode = target_mem_read32(t, DBGMCU_IDCODE) & 0xfff;
|
||||
switch(t->idcode) {
|
||||
case 0x410: /* Medium density */
|
||||
case 0x412: /* Low denisty */
|
||||
case 0x420: /* Value Line, Low-/Medium density */
|
||||
target->driver = stm32f1_driver_str;
|
||||
target->xml_mem_map = stm32f1_xml_memory_map;
|
||||
target->flash_erase = stm32md_flash_erase;
|
||||
target->flash_write = stm32f1_flash_write;
|
||||
target_add_commands(target, stm32f1_cmd_list, "STM32 LD/MD");
|
||||
t->driver = stm32f1_driver_str;
|
||||
t->xml_mem_map = stm32f1_xml_memory_map;
|
||||
t->flash_erase = stm32md_flash_erase;
|
||||
t->flash_write = stm32f1_flash_write;
|
||||
target_add_commands(t, stm32f1_cmd_list, "STM32 LD/MD");
|
||||
return true;
|
||||
case 0x414: /* High density */
|
||||
case 0x418: /* Connectivity Line */
|
||||
case 0x428: /* Value Line, High Density */
|
||||
target->driver = stm32hd_driver_str;
|
||||
target->xml_mem_map = stm32hd_xml_memory_map;
|
||||
target->flash_erase = stm32hd_flash_erase;
|
||||
target->flash_write = stm32f1_flash_write;
|
||||
target_add_commands(target, stm32f1_cmd_list, "STM32 HD/CL");
|
||||
t->driver = stm32hd_driver_str;
|
||||
t->xml_mem_map = stm32hd_xml_memory_map;
|
||||
t->flash_erase = stm32hd_flash_erase;
|
||||
t->flash_write = stm32f1_flash_write;
|
||||
target_add_commands(t, stm32f1_cmd_list, "STM32 HD/CL");
|
||||
return true;
|
||||
case 0x422: /* STM32F30x */
|
||||
case 0x432: /* STM32F37x */
|
||||
target->driver = stm32f3_driver_str;
|
||||
target->xml_mem_map = stm32hd_xml_memory_map;
|
||||
target->flash_erase = stm32hd_flash_erase;
|
||||
target->flash_write = stm32f1_flash_write;
|
||||
target_add_commands(target, stm32f1_cmd_list, "STM32F3");
|
||||
t->driver = stm32f3_driver_str;
|
||||
t->xml_mem_map = stm32hd_xml_memory_map;
|
||||
t->flash_erase = stm32hd_flash_erase;
|
||||
t->flash_write = stm32f1_flash_write;
|
||||
target_add_commands(t, stm32f1_cmd_list, "STM32F3");
|
||||
return true;
|
||||
}
|
||||
|
||||
target->idcode = target_mem_read32(target, DBGMCU_IDCODE_F0) & 0xfff;
|
||||
switch(target->idcode) {
|
||||
t->idcode = target_mem_read32(t, DBGMCU_IDCODE_F0) & 0xfff;
|
||||
switch(t->idcode) {
|
||||
case 0x444: /* STM32F03 RM0091 Rev.7 */
|
||||
case 0x445: /* STM32F04 RM0091 Rev.7 */
|
||||
case 0x440: /* STM32F05 RM0091 Rev.7 */
|
||||
case 0x448: /* STM32F07 RM0091 Rev.7 */
|
||||
case 0x442: /* STM32F09 RM0091 Rev.7 */
|
||||
switch(target->idcode) {
|
||||
switch(t->idcode) {
|
||||
case 0x444: /* STM32F03 */
|
||||
target->driver = stm32f03_driver_str;
|
||||
t->driver = stm32f03_driver_str;
|
||||
break;
|
||||
case 0x445: /* STM32F04 */
|
||||
target->driver = stm32f04_driver_str;
|
||||
t->driver = stm32f04_driver_str;
|
||||
break;
|
||||
case 0x440: /* STM32F05 */
|
||||
target->driver = stm32f05_driver_str;
|
||||
t->driver = stm32f05_driver_str;
|
||||
break;
|
||||
case 0x448: /* STM32F07 */
|
||||
target->driver = stm32f07_driver_str;
|
||||
t->driver = stm32f07_driver_str;
|
||||
break;
|
||||
case 0x442: /* STM32F09 */
|
||||
target->driver = stm32f09_driver_str;
|
||||
t->driver = stm32f09_driver_str;
|
||||
break;
|
||||
}
|
||||
target->xml_mem_map = stm32f1_xml_memory_map;
|
||||
target->flash_erase = stm32md_flash_erase;
|
||||
target->flash_write = stm32f1_flash_write;
|
||||
target_add_commands(target, stm32f1_cmd_list, "STM32F0");
|
||||
t->xml_mem_map = stm32f1_xml_memory_map;
|
||||
t->flash_erase = stm32md_flash_erase;
|
||||
t->flash_write = stm32f1_flash_write;
|
||||
target_add_commands(t, stm32f1_cmd_list, "STM32F0");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -199,7 +199,7 @@ static void stm32f1_flash_unlock(target *t)
|
|||
target_mem_write32(t, FLASH_KEYR, KEY2);
|
||||
}
|
||||
|
||||
static int stm32f1_flash_erase(struct target_s *target, uint32_t addr,
|
||||
static int stm32f1_flash_erase(target *t, uint32_t addr,
|
||||
size_t len, uint32_t pagesize)
|
||||
{
|
||||
uint16_t sr;
|
||||
|
@ -207,19 +207,19 @@ static int stm32f1_flash_erase(struct target_s *target, uint32_t addr,
|
|||
addr &= ~(pagesize - 1);
|
||||
len = (len + pagesize - 1) & ~(pagesize - 1);
|
||||
|
||||
stm32f1_flash_unlock(target);
|
||||
stm32f1_flash_unlock(t);
|
||||
|
||||
while(len) {
|
||||
/* Flash page erase instruction */
|
||||
target_mem_write32(target, FLASH_CR, FLASH_CR_PER);
|
||||
target_mem_write32(t, FLASH_CR, FLASH_CR_PER);
|
||||
/* write address to FMA */
|
||||
target_mem_write32(target, FLASH_AR, addr);
|
||||
target_mem_write32(t, FLASH_AR, addr);
|
||||
/* Flash page erase start instruction */
|
||||
target_mem_write32(target, FLASH_CR, FLASH_CR_STRT | FLASH_CR_PER);
|
||||
target_mem_write32(t, FLASH_CR, FLASH_CR_STRT | FLASH_CR_PER);
|
||||
|
||||
/* Read FLASH_SR to poll for BSY bit */
|
||||
while (target_mem_read32(target, FLASH_SR) & FLASH_SR_BSY)
|
||||
if(target_check_error(target))
|
||||
while (target_mem_read32(t, FLASH_SR) & FLASH_SR_BSY)
|
||||
if(target_check_error(t))
|
||||
return -1;
|
||||
|
||||
len -= pagesize;
|
||||
|
@ -227,24 +227,24 @@ static int stm32f1_flash_erase(struct target_s *target, uint32_t addr,
|
|||
}
|
||||
|
||||
/* Check for error */
|
||||
sr = target_mem_read32(target, FLASH_SR);
|
||||
sr = target_mem_read32(t, FLASH_SR);
|
||||
if ((sr & SR_ERROR_MASK) || !(sr & SR_EOP))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stm32hd_flash_erase(struct target_s *target, uint32_t addr, size_t len)
|
||||
static int stm32hd_flash_erase(target *t, uint32_t addr, size_t len)
|
||||
{
|
||||
return stm32f1_flash_erase(target, addr, len, 0x800);
|
||||
return stm32f1_flash_erase(t, addr, len, 0x800);
|
||||
}
|
||||
|
||||
static int stm32md_flash_erase(struct target_s *target, uint32_t addr, size_t len)
|
||||
static int stm32md_flash_erase(target *t, uint32_t addr, size_t len)
|
||||
{
|
||||
return stm32f1_flash_erase(target, addr, len, 0x400);
|
||||
return stm32f1_flash_erase(t, addr, len, 0x400);
|
||||
}
|
||||
|
||||
static int stm32f1_flash_write(struct target_s *target, uint32_t dest,
|
||||
static int stm32f1_flash_write(target *t, uint32_t dest,
|
||||
const uint8_t *src, size_t len)
|
||||
{
|
||||
uint32_t offset = dest % 4;
|
||||
|
@ -256,8 +256,8 @@ static int stm32f1_flash_write(struct target_s *target, uint32_t dest,
|
|||
memcpy((uint8_t *)data + offset, src, len);
|
||||
|
||||
/* Write stub and data to target ram and set PC */
|
||||
target_mem_write(target, STUB_BUFFER_BASE, (void*)data, sizeof(data));
|
||||
return cortexm_run_stub(target, SRAM_BASE, stm32f1_flash_write_stub,
|
||||
target_mem_write(t, STUB_BUFFER_BASE, (void*)data, sizeof(data));
|
||||
return cortexm_run_stub(t, SRAM_BASE, stm32f1_flash_write_stub,
|
||||
sizeof(stm32f1_flash_write_stub),
|
||||
dest - offset, STUB_BUFFER_BASE, sizeof(data),
|
||||
0);
|
||||
|
|
|
@ -47,8 +47,8 @@ const struct command_s stm32f4_cmd_list[] = {
|
|||
};
|
||||
|
||||
|
||||
static int stm32f4_flash_erase(struct target_s *target, uint32_t addr, size_t len);
|
||||
static int stm32f4_flash_write(struct target_s *target, uint32_t dest,
|
||||
static int stm32f4_flash_erase(target *t, uint32_t addr, size_t len);
|
||||
static int stm32f4_flash_write(target *t, uint32_t dest,
|
||||
const uint8_t *src, size_t len);
|
||||
|
||||
static const char stm32f4_driver_str[] = "STM32F4xx";
|
||||
|
@ -127,11 +127,11 @@ static const uint16_t stm32f4_flash_write_stub[] = {
|
|||
#define SRAM_BASE 0x20000000
|
||||
#define STUB_BUFFER_BASE ALIGN(SRAM_BASE + sizeof(stm32f4_flash_write_stub), 4)
|
||||
|
||||
bool stm32f4_probe(struct target_s *target)
|
||||
bool stm32f4_probe(target *t)
|
||||
{
|
||||
uint32_t idcode;
|
||||
|
||||
idcode = target_mem_read32(target, DBGMCU_IDCODE);
|
||||
idcode = target_mem_read32(t, DBGMCU_IDCODE);
|
||||
switch(idcode & 0xFFF) {
|
||||
case 0x411: /* Documented to be 0x413! This is what I read... */
|
||||
case 0x413: /* F407VGT6 */
|
||||
|
@ -139,11 +139,11 @@ bool stm32f4_probe(struct target_s *target)
|
|||
case 0x423: /* F401 B/C RM0368 Rev.3 */
|
||||
case 0x431: /* F411 RM0383 Rev.4 */
|
||||
case 0x433: /* F401 D/E RM0368 Rev.3 */
|
||||
target->xml_mem_map = stm32f4_xml_memory_map;
|
||||
target->driver = stm32f4_driver_str;
|
||||
target->flash_erase = stm32f4_flash_erase;
|
||||
target->flash_write = stm32f4_flash_write;
|
||||
target_add_commands(target, stm32f4_cmd_list, "STM32F4");
|
||||
t->xml_mem_map = stm32f4_xml_memory_map;
|
||||
t->driver = stm32f4_driver_str;
|
||||
t->flash_erase = stm32f4_flash_erase;
|
||||
t->flash_write = stm32f4_flash_write;
|
||||
target_add_commands(t, stm32f4_cmd_list, "STM32F4");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -158,7 +158,7 @@ static void stm32f4_flash_unlock(target *t)
|
|||
}
|
||||
}
|
||||
|
||||
static int stm32f4_flash_erase(struct target_s *target, uint32_t addr, size_t len)
|
||||
static int stm32f4_flash_erase(target *t, uint32_t addr, size_t len)
|
||||
{
|
||||
uint16_t sr;
|
||||
uint32_t cr;
|
||||
|
@ -166,7 +166,7 @@ static int stm32f4_flash_erase(struct target_s *target, uint32_t addr, size_t le
|
|||
|
||||
addr &= 0x07FFC000;
|
||||
|
||||
stm32f4_flash_unlock(target);
|
||||
stm32f4_flash_unlock(t);
|
||||
|
||||
while(len) {
|
||||
if (addr < 0x10000) { /* Sector 0..3 */
|
||||
|
@ -183,13 +183,13 @@ static int stm32f4_flash_erase(struct target_s *target, uint32_t addr, size_t le
|
|||
}
|
||||
cr |= FLASH_CR_EOPIE | FLASH_CR_ERRIE | FLASH_CR_SER;
|
||||
/* Flash page erase instruction */
|
||||
target_mem_write32(target, FLASH_CR, cr);
|
||||
target_mem_write32(t, FLASH_CR, cr);
|
||||
/* write address to FMA */
|
||||
target_mem_write32(target, FLASH_CR, cr | FLASH_CR_STRT);
|
||||
target_mem_write32(t, FLASH_CR, cr | FLASH_CR_STRT);
|
||||
|
||||
/* Read FLASH_SR to poll for BSY bit */
|
||||
while(target_mem_read32(target, FLASH_SR) & FLASH_SR_BSY)
|
||||
if(target_check_error(target))
|
||||
while(target_mem_read32(t, FLASH_SR) & FLASH_SR_BSY)
|
||||
if(target_check_error(t))
|
||||
return -1;
|
||||
|
||||
len -= pagesize;
|
||||
|
@ -197,14 +197,14 @@ static int stm32f4_flash_erase(struct target_s *target, uint32_t addr, size_t le
|
|||
}
|
||||
|
||||
/* Check for error */
|
||||
sr = target_mem_read32(target, FLASH_SR);
|
||||
sr = target_mem_read32(t, FLASH_SR);
|
||||
if(sr & SR_ERROR_MASK)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stm32f4_flash_write(struct target_s *target, uint32_t dest,
|
||||
static int stm32f4_flash_write(target *t, uint32_t dest,
|
||||
const uint8_t *src, size_t len)
|
||||
{
|
||||
uint32_t offset = dest % 4;
|
||||
|
@ -216,8 +216,8 @@ static int stm32f4_flash_write(struct target_s *target, uint32_t dest,
|
|||
memcpy((uint8_t *)data + offset, src, len);
|
||||
|
||||
/* Write buffer to target ram call stub */
|
||||
target_mem_write(target, STUB_BUFFER_BASE, data, sizeof(data));
|
||||
return cortexm_run_stub(target, SRAM_BASE, stm32f4_flash_write_stub,
|
||||
target_mem_write(t, STUB_BUFFER_BASE, data, sizeof(data));
|
||||
return cortexm_run_stub(t, SRAM_BASE, stm32f4_flash_write_stub,
|
||||
sizeof(stm32f4_flash_write_stub),
|
||||
dest - offset, STUB_BUFFER_BASE, sizeof(data),
|
||||
0);
|
||||
|
|
275
src/stm32l0.c
275
src/stm32l0.c
|
@ -123,37 +123,25 @@
|
|||
|
||||
static int inhibit_stubs; /* Local option to force non-stub flash IO */
|
||||
|
||||
static int stm32lx_nvm_erase(struct target_s* target,
|
||||
uint32_t addr, size_t len);
|
||||
static int stm32lx_nvm_write(struct target_s* target,
|
||||
uint32_t destination,
|
||||
const uint8_t* source,
|
||||
static int stm32lx_nvm_erase(target *t, uint32_t addr, size_t len);
|
||||
static int stm32lx_nvm_write(target *t, uint32_t dest, const uint8_t* src,
|
||||
size_t size);
|
||||
|
||||
static int stm32lx_nvm_prog_erase(struct target_s* target,
|
||||
uint32_t addr, size_t len);
|
||||
static int stm32lx_nvm_prog_write(struct target_s* target,
|
||||
uint32_t destination,
|
||||
const uint8_t* source,
|
||||
static int stm32lx_nvm_prog_erase(target *t, uint32_t addr, size_t len);
|
||||
static int stm32lx_nvm_prog_write(target *t, uint32_t dest, const uint8_t* src,
|
||||
size_t size);
|
||||
|
||||
static int stm32lx_nvm_prog_erase_stubbed(struct target_s* target,
|
||||
uint32_t addr, size_t len);
|
||||
static int stm32lx_nvm_prog_write_stubbed(struct target_s* target,
|
||||
uint32_t destination,
|
||||
const uint8_t* source,
|
||||
size_t size);
|
||||
static int stm32lx_nvm_prog_erase_stubbed(target *t, uint32_t addr, size_t len);
|
||||
static int stm32lx_nvm_prog_write_stubbed(target *t, uint32_t dest,
|
||||
const uint8_t* src, size_t size);
|
||||
|
||||
static int stm32lx_nvm_data_erase(struct target_s* target,
|
||||
uint32_t addr, size_t len);
|
||||
static int stm32lx_nvm_data_write(struct target_s* target,
|
||||
uint32_t destination,
|
||||
const uint8_t* source,
|
||||
size_t size);
|
||||
static int stm32lx_nvm_data_erase(target *t, uint32_t addr, size_t len);
|
||||
static int stm32lx_nvm_data_write(target *t, uint32_t dest,
|
||||
const uint8_t* src, size_t size);
|
||||
|
||||
static bool stm32lx_cmd_option (target* t, int argc, char** argv);
|
||||
static bool stm32lx_cmd_eeprom (target* t, int argc, char** argv);
|
||||
static bool stm32lx_cmd_stubs (target* t, int argc, char** argv);
|
||||
static bool stm32lx_cmd_option(target* t, int argc, char** argv);
|
||||
static bool stm32lx_cmd_eeprom(target* t, int argc, char** argv);
|
||||
static bool stm32lx_cmd_stubs(target* t, int argc, char** argv);
|
||||
|
||||
static const struct command_s stm32lx_cmd_list[] = {
|
||||
{ "stubs", (cmd_handler) stm32lx_cmd_stubs,
|
||||
|
@ -216,9 +204,9 @@ static const uint16_t stm32l0_nvm_prog_erase_stub [] = {
|
|||
#include "../flashstub/stm32l05x-nvm-prog-erase.stub"
|
||||
};
|
||||
|
||||
static uint32_t stm32lx_nvm_prog_page_size(struct target_s* target)
|
||||
static uint32_t stm32lx_nvm_prog_page_size(target *t)
|
||||
{
|
||||
switch (target->idcode) {
|
||||
switch (t->idcode) {
|
||||
case 0x417: /* STM32L0xx */
|
||||
return STM32L0_NVM_PROG_PAGE_SIZE;
|
||||
default: /* STM32L1xx */
|
||||
|
@ -226,9 +214,9 @@ static uint32_t stm32lx_nvm_prog_page_size(struct target_s* target)
|
|||
}
|
||||
}
|
||||
|
||||
static bool stm32lx_is_stm32l1(struct target_s* target)
|
||||
static bool stm32lx_is_stm32l1(target *t)
|
||||
{
|
||||
switch (target->idcode) {
|
||||
switch (t->idcode) {
|
||||
case 0x417: /* STM32L0xx */
|
||||
return false;
|
||||
default: /* STM32L1xx */
|
||||
|
@ -236,9 +224,9 @@ static bool stm32lx_is_stm32l1(struct target_s* target)
|
|||
}
|
||||
}
|
||||
|
||||
static uint32_t stm32lx_nvm_eeprom_size(struct target_s* target)
|
||||
static uint32_t stm32lx_nvm_eeprom_size(target *t)
|
||||
{
|
||||
switch (target->idcode) {
|
||||
switch (t->idcode) {
|
||||
case 0x417: /* STM32L0xx */
|
||||
return STM32L0_NVM_EEPROM_SIZE;
|
||||
default: /* STM32L1xx */
|
||||
|
@ -246,9 +234,9 @@ static uint32_t stm32lx_nvm_eeprom_size(struct target_s* target)
|
|||
}
|
||||
}
|
||||
|
||||
static uint32_t stm32lx_nvm_phys(struct target_s* target)
|
||||
static uint32_t stm32lx_nvm_phys(target *t)
|
||||
{
|
||||
switch (target->idcode) {
|
||||
switch (t->idcode) {
|
||||
case 0x417: /* STM32L0xx */
|
||||
return STM32L0_NVM_PHYS;
|
||||
default: /* STM32L1xx */
|
||||
|
@ -256,9 +244,9 @@ static uint32_t stm32lx_nvm_phys(struct target_s* target)
|
|||
}
|
||||
}
|
||||
|
||||
static uint32_t stm32lx_nvm_data_page_size(struct target_s* target)
|
||||
static uint32_t stm32lx_nvm_data_page_size(target *t)
|
||||
{
|
||||
switch (target->idcode) {
|
||||
switch (t->idcode) {
|
||||
case 0x417: /* STM32L0xx */
|
||||
return STM32L0_NVM_DATA_PAGE_SIZE;
|
||||
default: /* STM32L1xx */
|
||||
|
@ -266,9 +254,9 @@ static uint32_t stm32lx_nvm_data_page_size(struct target_s* target)
|
|||
}
|
||||
}
|
||||
|
||||
static uint32_t stm32lx_nvm_option_size(struct target_s* target)
|
||||
static uint32_t stm32lx_nvm_option_size(target *t)
|
||||
{
|
||||
switch (target->idcode) {
|
||||
switch (t->idcode) {
|
||||
case 0x417: /* STM32L0xx */
|
||||
return STM32L0_NVM_OPT_SIZE;
|
||||
default: /* STM32L1xx */
|
||||
|
@ -279,40 +267,38 @@ static uint32_t stm32lx_nvm_option_size(struct target_s* target)
|
|||
/** Query MCU memory for an indication as to whether or not the
|
||||
currently attached target is served by this module. We detect the
|
||||
STM32L0xx parts as well as the STM32L1xx's. */
|
||||
bool stm32l0_probe(struct target_s* target)
|
||||
bool stm32l0_probe(target *t)
|
||||
{
|
||||
uint32_t idcode;
|
||||
|
||||
idcode = target_mem_read32(target,
|
||||
STM32L1_DBGMCU_IDCODE_PHYS) & 0xfff;
|
||||
idcode = target_mem_read32(t, STM32L1_DBGMCU_IDCODE_PHYS) & 0xfff;
|
||||
switch (idcode) {
|
||||
case 0x416: /* CAT. 1 device */
|
||||
case 0x429: /* CAT. 2 device */
|
||||
case 0x427: /* CAT. 3 device */
|
||||
case 0x436: /* CAT. 4 device */
|
||||
case 0x437: /* CAT. 5 device */
|
||||
target->idcode = idcode;
|
||||
target->driver = stm32l1_driver_str;
|
||||
target->xml_mem_map = stm32l1_xml_memory_map;
|
||||
target->flash_erase = stm32lx_nvm_erase;
|
||||
target->flash_write = stm32lx_nvm_write;
|
||||
target_add_commands(target, stm32lx_cmd_list, "STM32L1x");
|
||||
t->idcode = idcode;
|
||||
t->driver = stm32l1_driver_str;
|
||||
t->xml_mem_map = stm32l1_xml_memory_map;
|
||||
t->flash_erase = stm32lx_nvm_erase;
|
||||
t->flash_write = stm32lx_nvm_write;
|
||||
target_add_commands(t, stm32lx_cmd_list, "STM32L1x");
|
||||
return true;
|
||||
}
|
||||
|
||||
idcode = target_mem_read32(target,
|
||||
STM32L0_DBGMCU_IDCODE_PHYS) & 0xfff;
|
||||
idcode = target_mem_read32(t, STM32L0_DBGMCU_IDCODE_PHYS) & 0xfff;
|
||||
switch (idcode) {
|
||||
default:
|
||||
break;
|
||||
|
||||
case 0x417: /* STM32L0x[123] & probably others */
|
||||
target->idcode = idcode;
|
||||
target->driver = stm32l0_driver_str;
|
||||
target->xml_mem_map = stm32l0_xml_memory_map;
|
||||
target->flash_erase = stm32lx_nvm_erase;
|
||||
target->flash_write = stm32lx_nvm_write;
|
||||
target_add_commands(target, stm32lx_cmd_list, "STM32L0x");
|
||||
t->idcode = idcode;
|
||||
t->driver = stm32l0_driver_str;
|
||||
t->xml_mem_map = stm32l0_xml_memory_map;
|
||||
t->flash_erase = stm32lx_nvm_erase;
|
||||
t->flash_write = stm32lx_nvm_write;
|
||||
target_add_commands(t, stm32lx_cmd_list, "STM32L0x");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -364,17 +350,17 @@ static bool stm32lx_nvm_opt_unlock(target *t, uint32_t nvm)
|
|||
/** Erase a region of flash using a stub function. This only works
|
||||
when the MCU hasn't entered a fault state(see NOTES). The flash
|
||||
array is erased for all pages from addr to addr+len inclusive. */
|
||||
static int stm32lx_nvm_prog_erase_stubbed(struct target_s* target,
|
||||
static int stm32lx_nvm_prog_erase_stubbed(target *t,
|
||||
uint32_t addr, size_t size)
|
||||
{
|
||||
struct stm32lx_nvm_stub_info info;
|
||||
const uint32_t nvm = stm32lx_nvm_phys(target);
|
||||
const uint32_t nvm = stm32lx_nvm_phys(t);
|
||||
|
||||
info.nvm = nvm;
|
||||
info.page_size = stm32lx_nvm_prog_page_size(target);
|
||||
info.page_size = stm32lx_nvm_prog_page_size(t);
|
||||
|
||||
/* Load the stub */
|
||||
target_mem_write(target, STM32Lx_STUB_PHYS,
|
||||
target_mem_write(t, STM32Lx_STUB_PHYS,
|
||||
&stm32l0_nvm_prog_erase_stub[0],
|
||||
sizeof(stm32l0_nvm_prog_erase_stub));
|
||||
|
||||
|
@ -383,21 +369,20 @@ static int stm32lx_nvm_prog_erase_stubbed(struct target_s* target,
|
|||
info.size = size;
|
||||
|
||||
/* Copy parameters */
|
||||
target_mem_write(target, STM32Lx_STUB_INFO_PHYS,
|
||||
&info, sizeof(info));
|
||||
target_mem_write(t, STM32Lx_STUB_INFO_PHYS, &info, sizeof(info));
|
||||
|
||||
/* Execute stub */
|
||||
cortexm_pc_write(target, STM32Lx_STUB_PHYS);
|
||||
if (target_check_error(target))
|
||||
cortexm_pc_write(t, STM32Lx_STUB_PHYS);
|
||||
if (target_check_error(t))
|
||||
return -1;
|
||||
target_halt_resume(target, 0);
|
||||
while (!target_halt_wait(target))
|
||||
target_halt_resume(t, 0);
|
||||
while (!target_halt_wait(t))
|
||||
;
|
||||
{
|
||||
if (target_mem_read32(target, STM32Lx_NVM_SR(nvm))
|
||||
& STM32Lx_NVM_SR_ERR_M)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (target_mem_read32(t, STM32Lx_NVM_SR(nvm))
|
||||
& STM32Lx_NVM_SR_ERR_M)
|
||||
return -1;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -407,14 +392,14 @@ static int stm32lx_nvm_prog_erase_stubbed(struct target_s* target,
|
|||
when the MCU hasn't entered a fault state. Once the MCU faults,
|
||||
this function will not succeed because the MCU will fault before
|
||||
executing a single instruction in the stub. */
|
||||
static int stm32lx_nvm_prog_write_stubbed(struct target_s* target,
|
||||
static int stm32lx_nvm_prog_write_stubbed(target *t,
|
||||
uint32_t destination,
|
||||
const uint8_t* source,
|
||||
size_t size)
|
||||
{
|
||||
struct stm32lx_nvm_stub_info info;
|
||||
const uint32_t nvm = stm32lx_nvm_phys(target);
|
||||
const size_t page_size = stm32lx_nvm_prog_page_size(target);
|
||||
const uint32_t nvm = stm32lx_nvm_phys(t);
|
||||
const size_t page_size = stm32lx_nvm_prog_page_size(t);
|
||||
|
||||
/* We can only handle word aligned writes and even
|
||||
word-multiple ranges. The stm32lx's cannot perform
|
||||
|
@ -427,7 +412,7 @@ static int stm32lx_nvm_prog_write_stubbed(struct target_s* target,
|
|||
info.page_size = page_size;
|
||||
|
||||
/* Load the stub */
|
||||
target_mem_write(target, STM32Lx_STUB_PHYS,
|
||||
target_mem_write(t, STM32Lx_STUB_PHYS,
|
||||
&stm32l0_nvm_prog_write_stub[0],
|
||||
sizeof(stm32l0_nvm_prog_write_stub));
|
||||
|
||||
|
@ -451,7 +436,7 @@ static int stm32lx_nvm_prog_write_stubbed(struct target_s* target,
|
|||
info.size = cb;
|
||||
|
||||
/* Copy data to write to flash */
|
||||
target_mem_write(target, info.source, source, info.size);
|
||||
target_mem_write(t, info.source, source, info.size);
|
||||
|
||||
/* Move pointers early */
|
||||
destination += cb;
|
||||
|
@ -459,18 +444,18 @@ static int stm32lx_nvm_prog_write_stubbed(struct target_s* target,
|
|||
size -= cb;
|
||||
|
||||
/* Copy parameters */
|
||||
target_mem_write(target, STM32Lx_STUB_INFO_PHYS,
|
||||
target_mem_write(t, STM32Lx_STUB_INFO_PHYS,
|
||||
&info, sizeof(info));
|
||||
|
||||
/* Execute stub */
|
||||
cortexm_pc_write(target, STM32Lx_STUB_PHYS);
|
||||
if (target_check_error(target))
|
||||
cortexm_pc_write(t, STM32Lx_STUB_PHYS);
|
||||
if (target_check_error(t))
|
||||
return -1;
|
||||
target_halt_resume(target, 0);
|
||||
while (!target_halt_wait(target))
|
||||
target_halt_resume(t, 0);
|
||||
while (!target_halt_wait(t))
|
||||
;
|
||||
|
||||
if (target_mem_read32(target, STM32Lx_NVM_SR(nvm))
|
||||
if (target_mem_read32(t, STM32Lx_NVM_SR(nvm))
|
||||
& STM32Lx_NVM_SR_ERR_M)
|
||||
return -1;
|
||||
}
|
||||
|
@ -482,19 +467,19 @@ static int stm32lx_nvm_prog_write_stubbed(struct target_s* target,
|
|||
/** Erase a region of NVM for STM32Lx. This is the lead function and
|
||||
it will invoke an implementation, stubbed or not depending on the
|
||||
options and the range of addresses. */
|
||||
static int stm32lx_nvm_erase(struct target_s* target, uint32_t addr, size_t size)
|
||||
static int stm32lx_nvm_erase(target *t, uint32_t addr, size_t size)
|
||||
{
|
||||
if (addr >= STM32Lx_NVM_EEPROM_PHYS)
|
||||
return stm32lx_nvm_data_erase(target, addr, size);
|
||||
return stm32lx_nvm_data_erase(t, addr, size);
|
||||
|
||||
/* Use stub if not inhibited, the MCU is in a non-exceptonal state
|
||||
and there is stub. */
|
||||
volatile uint32_t regs[20];
|
||||
target_regs_read(target, ®s);
|
||||
target_regs_read(t, ®s);
|
||||
if (inhibit_stubs || (regs[16] & 0xf))
|
||||
return stm32lx_nvm_prog_erase(target, addr, size);
|
||||
return stm32lx_nvm_prog_erase(t, addr, size);
|
||||
|
||||
return stm32lx_nvm_prog_erase_stubbed(target, addr, size);
|
||||
return stm32lx_nvm_prog_erase_stubbed(t, addr, size);
|
||||
}
|
||||
|
||||
|
||||
|
@ -503,13 +488,13 @@ static int stm32lx_nvm_erase(struct target_s* target, uint32_t addr, size_t size
|
|||
the options and the range of addresses. Data (EEPROM) writes
|
||||
don't have to care about alignment, but the program flash does.
|
||||
There is a fixup for unaligned program flash writes. */
|
||||
static int stm32lx_nvm_write(struct target_s* target,
|
||||
static int stm32lx_nvm_write(target *t,
|
||||
uint32_t destination,
|
||||
const uint8_t* source,
|
||||
size_t size)
|
||||
{
|
||||
if (destination >= STM32Lx_NVM_EEPROM_PHYS)
|
||||
return stm32lx_nvm_data_write(target, destination, source,
|
||||
return stm32lx_nvm_data_write(t, destination, source,
|
||||
size);
|
||||
|
||||
/* Unaligned destinations. To make this feature simple to
|
||||
|
@ -532,12 +517,12 @@ static int stm32lx_nvm_write(struct target_s* target,
|
|||
/* Skip stub if the MCU is in a questionable state, or if the
|
||||
user asks us to avoid stubs. */
|
||||
volatile uint32_t regs[20];
|
||||
target_regs_read(target, ®s);
|
||||
target_regs_read(t, ®s);
|
||||
if (inhibit_stubs || (regs[16] & 0xf))
|
||||
return stm32lx_nvm_prog_write(target, destination, source,
|
||||
return stm32lx_nvm_prog_write(t, destination, source,
|
||||
size);
|
||||
|
||||
return stm32lx_nvm_prog_write_stubbed(target, destination, source,
|
||||
return stm32lx_nvm_prog_write_stubbed(t, destination, source,
|
||||
size);
|
||||
}
|
||||
|
||||
|
@ -546,49 +531,46 @@ static int stm32lx_nvm_write(struct target_s* target,
|
|||
interface. This is slower than stubbed versions(see NOTES). The
|
||||
flash array is erased for all pages from addr to addr+len
|
||||
inclusive. NVM register file address chosen from target. */
|
||||
static int stm32lx_nvm_prog_erase(struct target_s* target,
|
||||
uint32_t addr, size_t len)
|
||||
static int stm32lx_nvm_prog_erase(target *t, uint32_t addr, size_t len)
|
||||
{
|
||||
const size_t page_size = stm32lx_nvm_prog_page_size(target);
|
||||
const uint32_t nvm = stm32lx_nvm_phys(target);
|
||||
const size_t page_size = stm32lx_nvm_prog_page_size(t);
|
||||
const uint32_t nvm = stm32lx_nvm_phys(t);
|
||||
|
||||
/* Word align */
|
||||
len += (addr & 3);
|
||||
addr &= ~3;
|
||||
|
||||
if (!stm32lx_nvm_prog_data_unlock(target, nvm))
|
||||
if (!stm32lx_nvm_prog_data_unlock(t, nvm))
|
||||
return -1;
|
||||
|
||||
/* Flash page erase instruction */
|
||||
target_mem_write32(target, STM32Lx_NVM_PECR(nvm),
|
||||
target_mem_write32(t, STM32Lx_NVM_PECR(nvm),
|
||||
STM32Lx_NVM_PECR_ERASE | STM32Lx_NVM_PECR_PROG);
|
||||
|
||||
{
|
||||
uint32_t pecr = target_mem_read32(target, STM32Lx_NVM_PECR(nvm));
|
||||
if ((pecr & (STM32Lx_NVM_PECR_PROG | STM32Lx_NVM_PECR_ERASE))
|
||||
!= (STM32Lx_NVM_PECR_PROG | STM32Lx_NVM_PECR_ERASE))
|
||||
return -1;
|
||||
}
|
||||
uint32_t pecr = target_mem_read32(t, STM32Lx_NVM_PECR(nvm));
|
||||
if ((pecr & (STM32Lx_NVM_PECR_PROG | STM32Lx_NVM_PECR_ERASE))
|
||||
!= (STM32Lx_NVM_PECR_PROG | STM32Lx_NVM_PECR_ERASE))
|
||||
return -1;
|
||||
|
||||
/* Clear errors. Note that this only works when we wait for the NVM
|
||||
block to complete the last operation. */
|
||||
target_mem_write32(target, STM32Lx_NVM_SR(nvm), STM32Lx_NVM_SR_ERR_M);
|
||||
target_mem_write32(t, STM32Lx_NVM_SR(nvm), STM32Lx_NVM_SR_ERR_M);
|
||||
|
||||
while (len > 0) {
|
||||
/* Write first word of page to 0 */
|
||||
target_mem_write32(target, addr, 0);
|
||||
target_mem_write32(t, addr, 0);
|
||||
|
||||
len -= page_size;
|
||||
addr += page_size;
|
||||
}
|
||||
|
||||
/* Disable further programming by locking PECR */
|
||||
stm32lx_nvm_lock(target, nvm);
|
||||
stm32lx_nvm_lock(t, nvm);
|
||||
|
||||
/* Wait for completion or an error */
|
||||
while (1) {
|
||||
uint32_t sr = target_mem_read32(target, STM32Lx_NVM_SR(nvm));
|
||||
if (target_check_error(target))
|
||||
uint32_t sr = target_mem_read32(t, STM32Lx_NVM_SR(nvm));
|
||||
if (target_check_error(t))
|
||||
return -1;
|
||||
if (sr & STM32Lx_NVM_SR_BSY)
|
||||
continue;
|
||||
|
@ -604,13 +586,13 @@ static int stm32lx_nvm_prog_erase(struct target_s* target,
|
|||
/** Write to program flash using operations through the debug
|
||||
interface. This is slower than the stubbed write(see NOTES).
|
||||
NVM register file address chosen from target. */
|
||||
static int stm32lx_nvm_prog_write(struct target_s* target,
|
||||
static int stm32lx_nvm_prog_write(target *t,
|
||||
uint32_t destination,
|
||||
const uint8_t* source_8,
|
||||
size_t size)
|
||||
{
|
||||
const uint32_t nvm = stm32lx_nvm_phys(target);
|
||||
const bool is_stm32l1 = stm32lx_is_stm32l1(target);
|
||||
const uint32_t nvm = stm32lx_nvm_phys(t);
|
||||
const bool is_stm32l1 = stm32lx_is_stm32l1(t);
|
||||
|
||||
/* We can only handle word aligned writes and even
|
||||
word-multiple ranges. The stm32lx's cannot perform
|
||||
|
@ -619,19 +601,19 @@ static int stm32lx_nvm_prog_write(struct target_s* target,
|
|||
if ((destination & 3) || (size & 3))
|
||||
return -1;
|
||||
|
||||
if (!stm32lx_nvm_prog_data_unlock(target, nvm))
|
||||
if (!stm32lx_nvm_prog_data_unlock(t, nvm))
|
||||
return -1;
|
||||
|
||||
const size_t half_page_size = stm32lx_nvm_prog_page_size(target)/2;
|
||||
const size_t half_page_size = stm32lx_nvm_prog_page_size(t)/2;
|
||||
uint32_t* source = (uint32_t*) source_8;
|
||||
|
||||
while (size > 0) {
|
||||
|
||||
/* Wait for BSY to clear because we cannot write the PECR until
|
||||
the previous operation completes on STM32Lxxx. */
|
||||
while (target_mem_read32(target, STM32Lx_NVM_SR(nvm))
|
||||
while (target_mem_read32(t, STM32Lx_NVM_SR(nvm))
|
||||
& STM32Lx_NVM_SR_BSY)
|
||||
if (target_check_error(target)) {
|
||||
if (target_check_error(t)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -639,7 +621,7 @@ static int stm32lx_nvm_prog_write(struct target_s* target,
|
|||
// than a half page to write
|
||||
if (size < half_page_size
|
||||
|| (destination & (half_page_size - 1))) {
|
||||
target_mem_write32(target, STM32Lx_NVM_PECR(nvm),
|
||||
target_mem_write32(t, STM32Lx_NVM_PECR(nvm),
|
||||
is_stm32l1
|
||||
? 0
|
||||
: STM32Lx_NVM_PECR_PROG);
|
||||
|
@ -650,31 +632,31 @@ static int stm32lx_nvm_prog_write(struct target_s* target,
|
|||
c = size;
|
||||
size -= c;
|
||||
|
||||
target_mem_write(target, destination, source, c);
|
||||
target_mem_write(t, destination, source, c);
|
||||
source += c/4;
|
||||
destination += c;
|
||||
}
|
||||
// Or we are writing a half-page(s)
|
||||
else {
|
||||
target_mem_write32(target, STM32Lx_NVM_PECR(nvm),
|
||||
target_mem_write32(t, STM32Lx_NVM_PECR(nvm),
|
||||
STM32Lx_NVM_PECR_PROG
|
||||
| STM32Lx_NVM_PECR_FPRG);
|
||||
|
||||
size_t c = size & ~(half_page_size - 1);
|
||||
size -= c;
|
||||
target_mem_write(target, destination, source, c);
|
||||
target_mem_write(t, destination, source, c);
|
||||
source += c/4;
|
||||
destination += c;
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable further programming by locking PECR */
|
||||
stm32lx_nvm_lock(target, nvm);
|
||||
stm32lx_nvm_lock(t, nvm);
|
||||
|
||||
/* Wait for completion or an error */
|
||||
while (1) {
|
||||
uint32_t sr = target_mem_read32(target, STM32Lx_NVM_SR(nvm));
|
||||
if (target_check_error(target)) {
|
||||
uint32_t sr = target_mem_read32(t, STM32Lx_NVM_SR(nvm));
|
||||
if (target_check_error(t)) {
|
||||
return -1;
|
||||
}
|
||||
if (sr & STM32Lx_NVM_SR_BSY)
|
||||
|
@ -693,45 +675,43 @@ static int stm32lx_nvm_prog_write(struct target_s* target,
|
|||
interface . The flash is erased for all pages from addr to
|
||||
addr+len, inclusive, on a word boundary. NVM register file
|
||||
address chosen from target. */
|
||||
static int stm32lx_nvm_data_erase(struct target_s* target,
|
||||
static int stm32lx_nvm_data_erase(target *t,
|
||||
uint32_t addr, size_t len)
|
||||
{
|
||||
const size_t page_size = stm32lx_nvm_data_page_size(target);
|
||||
const uint32_t nvm = stm32lx_nvm_phys(target);
|
||||
const size_t page_size = stm32lx_nvm_data_page_size(t);
|
||||
const uint32_t nvm = stm32lx_nvm_phys(t);
|
||||
|
||||
/* Word align */
|
||||
len += (addr & 3);
|
||||
addr &= ~3;
|
||||
|
||||
if (!stm32lx_nvm_prog_data_unlock(target, nvm))
|
||||
if (!stm32lx_nvm_prog_data_unlock(t, nvm))
|
||||
return -1;
|
||||
|
||||
/* Flash data erase instruction */
|
||||
target_mem_write32(target, STM32Lx_NVM_PECR(nvm),
|
||||
target_mem_write32(t, STM32Lx_NVM_PECR(nvm),
|
||||
STM32Lx_NVM_PECR_ERASE | STM32Lx_NVM_PECR_DATA);
|
||||
|
||||
{
|
||||
uint32_t pecr = target_mem_read32(target, STM32Lx_NVM_PECR(nvm));
|
||||
if ((pecr & (STM32Lx_NVM_PECR_ERASE | STM32Lx_NVM_PECR_DATA))
|
||||
!= (STM32Lx_NVM_PECR_ERASE | STM32Lx_NVM_PECR_DATA))
|
||||
return -1;
|
||||
}
|
||||
uint32_t pecr = target_mem_read32(t, STM32Lx_NVM_PECR(nvm));
|
||||
if ((pecr & (STM32Lx_NVM_PECR_ERASE | STM32Lx_NVM_PECR_DATA))
|
||||
!= (STM32Lx_NVM_PECR_ERASE | STM32Lx_NVM_PECR_DATA))
|
||||
return -1;
|
||||
|
||||
while (len > 0) {
|
||||
/* Write first word of page to 0 */
|
||||
target_mem_write32(target, addr, 0);
|
||||
target_mem_write32(t, addr, 0);
|
||||
|
||||
len -= page_size;
|
||||
addr += page_size;
|
||||
}
|
||||
|
||||
/* Disable further programming by locking PECR */
|
||||
stm32lx_nvm_lock(target, nvm);
|
||||
stm32lx_nvm_lock(t, nvm);
|
||||
|
||||
/* Wait for completion or an error */
|
||||
while (1) {
|
||||
uint32_t sr = target_mem_read32(target, STM32Lx_NVM_SR(nvm));
|
||||
if (target_check_error(target))
|
||||
uint32_t sr = target_mem_read32(t, STM32Lx_NVM_SR(nvm));
|
||||
if (target_check_error(t))
|
||||
return -1;
|
||||
if (sr & STM32Lx_NVM_SR_BSY)
|
||||
continue;
|
||||
|
@ -748,39 +728,38 @@ static int stm32lx_nvm_data_erase(struct target_s* target,
|
|||
NVM register file address chosen from target. Unaligned
|
||||
destination writes are supported (though unaligned sources are
|
||||
not). */
|
||||
static int stm32lx_nvm_data_write(struct target_s* target,
|
||||
static int stm32lx_nvm_data_write(target *t,
|
||||
uint32_t destination,
|
||||
const uint8_t* source_8,
|
||||
size_t size)
|
||||
{
|
||||
const uint32_t nvm = stm32lx_nvm_phys(target);
|
||||
const bool is_stm32l1 = stm32lx_is_stm32l1(target);
|
||||
uint32_t* source = (uint32_t*) source_8;
|
||||
const uint32_t nvm = stm32lx_nvm_phys(t);
|
||||
const bool is_stm32l1 = stm32lx_is_stm32l1(t);
|
||||
uint32_t* source = (uint32_t*) source_8;
|
||||
|
||||
if (!stm32lx_nvm_prog_data_unlock(target, nvm))
|
||||
if (!stm32lx_nvm_prog_data_unlock(t, nvm))
|
||||
return -1;
|
||||
|
||||
|
||||
target_mem_write32(target, STM32Lx_NVM_PECR(nvm),
|
||||
target_mem_write32(t, STM32Lx_NVM_PECR(nvm),
|
||||
is_stm32l1 ? 0 : STM32Lx_NVM_PECR_DATA);
|
||||
|
||||
while (size) {
|
||||
size -= 4;
|
||||
uint32_t v = *source++;
|
||||
target_mem_write32(target, destination, v);
|
||||
target_mem_write32(t, destination, v);
|
||||
destination += 4;
|
||||
|
||||
if (target_check_error(target))
|
||||
if (target_check_error(t))
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Disable further programming by locking PECR */
|
||||
stm32lx_nvm_lock(target, nvm);
|
||||
stm32lx_nvm_lock(t, nvm);
|
||||
|
||||
/* Wait for completion or an error */
|
||||
while (1) {
|
||||
uint32_t sr = target_mem_read32(target, STM32Lx_NVM_SR(nvm));
|
||||
if (target_check_error(target))
|
||||
uint32_t sr = target_mem_read32(t, STM32Lx_NVM_SR(nvm));
|
||||
if (target_check_error(t))
|
||||
return -1;
|
||||
if (sr & STM32Lx_NVM_SR_BSY)
|
||||
continue;
|
||||
|
|
Loading…
Reference in New Issue