Merge commit '2a0d608b07487300a63908baa62e73a51a11e811' into sam-update
This commit is contained in:
commit
9ec6693e4d
@ -184,7 +184,7 @@ if __name__ == "__main__":
|
|||||||
print("Invoking DFU Device")
|
print("Invoking DFU Device")
|
||||||
timeout = 0
|
timeout = 0
|
||||||
while True :
|
while True :
|
||||||
sleep(0.5)
|
sleep(1)
|
||||||
timeout = timeout + 0.5
|
timeout = timeout + 0.5
|
||||||
dfudev = stm32_scan(args, True)
|
dfudev = stm32_scan(args, True)
|
||||||
if dfudev: break
|
if dfudev: break
|
||||||
|
@ -38,8 +38,6 @@
|
|||||||
# include "traceswo.h"
|
# include "traceswo.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef bool (*cmd_handler)(target *t, int argc, const char **argv);
|
|
||||||
|
|
||||||
static bool cmd_version(target *t, int argc, char **argv);
|
static bool cmd_version(target *t, int argc, char **argv);
|
||||||
static bool cmd_serial(target *t, int argc, char **argv);
|
static bool cmd_serial(target *t, int argc, char **argv);
|
||||||
static bool cmd_help(target *t, int argc, char **argv);
|
static bool cmd_help(target *t, int argc, char **argv);
|
||||||
|
@ -41,7 +41,6 @@
|
|||||||
#include <libopencm3/usb/cdc.h>
|
#include <libopencm3/usb/cdc.h>
|
||||||
#include <libopencm3/cm3/scb.h>
|
#include <libopencm3/cm3/scb.h>
|
||||||
#include <libopencm3/usb/dfu.h>
|
#include <libopencm3/usb/dfu.h>
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#define DFU_IF_NO 4
|
#define DFU_IF_NO 4
|
||||||
|
|
||||||
|
@ -12,8 +12,9 @@ CFLAGS += -DHOSTED_BMP_ONLY=$(HOSTED_BMP_ONLY)
|
|||||||
|
|
||||||
ifneq (, $(findstring linux, $(SYS)))
|
ifneq (, $(findstring linux, $(SYS)))
|
||||||
SRC += serial_unix.c
|
SRC += serial_unix.c
|
||||||
|
HIDAPILIB = hidapi-libusb
|
||||||
ifeq ($(ASAN), 1)
|
ifeq ($(ASAN), 1)
|
||||||
CFLAGS += -fsanitize=address
|
CFLAGS += -fsanitize=address -Wno-format-truncation
|
||||||
LDFLAGS += -lasan
|
LDFLAGS += -lasan
|
||||||
endif
|
endif
|
||||||
else ifneq (, $(findstring mingw, $(SYS)))
|
else ifneq (, $(findstring mingw, $(SYS)))
|
||||||
@ -36,6 +37,7 @@ SRC += serial_unix.c
|
|||||||
LDFLAGS += -lhidapi
|
LDFLAGS += -lhidapi
|
||||||
LDFLAGS += -framework CoreFoundation
|
LDFLAGS += -framework CoreFoundation
|
||||||
CFLAGS += -Ihidapi/hidapi
|
CFLAGS += -Ihidapi/hidapi
|
||||||
|
HIDAPILIB = hidapi
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ($(HOSTED_BMP_ONLY), 1)
|
ifneq ($(HOSTED_BMP_ONLY), 1)
|
||||||
@ -51,8 +53,8 @@ ifneq ($(HOSTED_BMP_ONLY), 1)
|
|||||||
ifneq (, $(findstring mingw, $(SYS)))
|
ifneq (, $(findstring mingw, $(SYS)))
|
||||||
SRC += hid.c
|
SRC += hid.c
|
||||||
else
|
else
|
||||||
CFLAGS += $(shell pkg-config --cflags hidapi-libusb)
|
CFLAGS += $(shell pkg-config --cflags $(HIDAPILIB))
|
||||||
LDFLAGS += $(shell pkg-config --libs hidapi-libusb)
|
LDFLAGS += $(shell pkg-config --libs $(HIDAPILIB))
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -201,9 +201,11 @@ int find_debuggers(BMP_CL_OPTIONS_t *cl_opts,bmp_info_t *info)
|
|||||||
}
|
}
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
serial[0] = 0;
|
serial[0] = 0;
|
||||||
|
manufacturer[0] = 0;
|
||||||
res = libusb_get_string_descriptor_ascii(
|
res = libusb_get_string_descriptor_ascii(
|
||||||
handle, desc.iManufacturer, (uint8_t*)manufacturer,
|
handle, desc.iManufacturer, (uint8_t*)manufacturer,
|
||||||
sizeof(manufacturer));
|
sizeof(manufacturer));
|
||||||
|
product[0] = 0;
|
||||||
res = libusb_get_string_descriptor_ascii(
|
res = libusb_get_string_descriptor_ascii(
|
||||||
handle, desc.iProduct, (uint8_t*)product,
|
handle, desc.iProduct, (uint8_t*)product,
|
||||||
sizeof(product));
|
sizeof(product));
|
||||||
@ -222,8 +224,9 @@ int find_debuggers(BMP_CL_OPTIONS_t *cl_opts,bmp_info_t *info)
|
|||||||
if (desc.idVendor == VENDOR_ID_BMP) {
|
if (desc.idVendor == VENDOR_ID_BMP) {
|
||||||
if (desc.idProduct == PRODUCT_ID_BMP) {
|
if (desc.idProduct == PRODUCT_ID_BMP) {
|
||||||
type = BMP_TYPE_BMP;
|
type = BMP_TYPE_BMP;
|
||||||
} else if (desc.idProduct == PRODUCT_ID_BMP_BL) {
|
} else {
|
||||||
DEBUG_WARN("BMP in botloader mode found. Restart or reflash!\n");
|
if (desc.idProduct == PRODUCT_ID_BMP_BL)
|
||||||
|
DEBUG_WARN("BMP in botloader mode found. Restart or reflash!\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else if ((type = find_cmsis_dap_interface(dev, info)) != BMP_TYPE_NONE) {
|
} else if ((type = find_cmsis_dap_interface(dev, info)) != BMP_TYPE_NONE) {
|
||||||
@ -252,13 +255,13 @@ int find_debuggers(BMP_CL_OPTIONS_t *cl_opts,bmp_info_t *info)
|
|||||||
if ((cable->vendor != desc.idVendor) || (cable->product != desc.idProduct))
|
if ((cable->vendor != desc.idVendor) || (cable->product != desc.idProduct))
|
||||||
continue; /* VID/PID do not match*/
|
continue; /* VID/PID do not match*/
|
||||||
if (cl_opts->opt_cable) {
|
if (cl_opts->opt_cable) {
|
||||||
if (strcmp(cable->name, cl_opts->opt_cable))
|
if (strncmp(cable->name, cl_opts->opt_cable, strlen(cable->name)))
|
||||||
continue; /* cable names do not match*/
|
continue; /* cable names do not match*/
|
||||||
else
|
else
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
if (cable->description) {
|
if (cable->description) {
|
||||||
if (strcmp(cable->description, product))
|
if (strncmp(cable->description, product, strlen(cable->description)))
|
||||||
continue; /* discriptions do not match*/
|
continue; /* discriptions do not match*/
|
||||||
else
|
else
|
||||||
found = true;
|
found = true;
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
#include "general.h"
|
#include "general.h"
|
||||||
#include "gdb_if.h"
|
#include "gdb_if.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "platform.h"
|
|
||||||
#include "remote.h"
|
#include "remote.h"
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
#include "bmp_remote.h"
|
#include "bmp_remote.h"
|
||||||
@ -33,7 +32,6 @@
|
|||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "adiv5.h"
|
#include "adiv5.h"
|
||||||
|
|
||||||
|
@ -19,18 +19,18 @@
|
|||||||
|
|
||||||
/* Find all known serial connected debuggers */
|
/* Find all known serial connected debuggers */
|
||||||
|
|
||||||
|
#include "general.h"
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include "general.h"
|
|
||||||
#include "platform.h"
|
|
||||||
#include "bmp_hosted.h"
|
#include "bmp_hosted.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
void bmp_ident(bmp_info_t *info)
|
void bmp_ident(bmp_info_t *info)
|
||||||
{
|
{
|
||||||
(void) info;
|
if (!info)
|
||||||
|
return;
|
||||||
DEBUG_INFO("BMP hosted (BMP Only) %s\n", FIRMWARE_VERSION);
|
DEBUG_INFO("BMP hosted (BMP Only) %s\n", FIRMWARE_VERSION);
|
||||||
|
DEBUG_INFO("Using:\n %s %s %s\n", info->manufacturer, info->version, info->serial);
|
||||||
}
|
}
|
||||||
|
|
||||||
void libusb_exit_function(bmp_info_t *info) {(void)info;};
|
void libusb_exit_function(bmp_info_t *info) {(void)info;};
|
||||||
@ -154,6 +154,10 @@ print_probes_info:
|
|||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
/* Old ID: Black_Sphere_Technologies_Black_Magic_Probe_BFE4D6EC-if00
|
||||||
|
* Recent: Black_Sphere_Technologies_Black_Magic_Probe_v1.7.1-212-g212292ab_7BAE7AB8-if00
|
||||||
|
* usb-Black_Sphere_Technologies_Black_Magic_Probe__SWLINK__v1.7.1-155-gf55ad67b-dirty_DECB8811-if00
|
||||||
|
*/
|
||||||
#define BMP_IDSTRING "usb-Black_Sphere_Technologies_Black_Magic_Probe"
|
#define BMP_IDSTRING "usb-Black_Sphere_Technologies_Black_Magic_Probe"
|
||||||
#define DEVICE_BY_ID "/dev/serial/by-id/"
|
#define DEVICE_BY_ID "/dev/serial/by-id/"
|
||||||
|
|
||||||
@ -172,41 +176,45 @@ static int scan_linux_id(char *name, char *type, char *version, char *serial)
|
|||||||
DEBUG_WARN("Unexpected end\n");
|
DEBUG_WARN("Unexpected end\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
char *p = strchr(name, '_');
|
char *p = name;
|
||||||
if (!p) {
|
char *delims[4] = {0,0,0,0};
|
||||||
DEBUG_WARN("type not found\n");
|
int underscores = 0;
|
||||||
return -1;
|
while (*p) {
|
||||||
|
if (*p == '_') {
|
||||||
|
while (p[1] == '_')
|
||||||
|
p++; /* remove multiple underscores */
|
||||||
|
if (underscores > 2)
|
||||||
|
return -1;
|
||||||
|
delims[underscores] = p;
|
||||||
|
underscores ++;
|
||||||
|
}
|
||||||
|
p++;
|
||||||
}
|
}
|
||||||
strncpy(type, name, p - name);
|
if (underscores == 0) { /* Old BMP native */
|
||||||
type[p - name] = 0;
|
int res;
|
||||||
name = p;
|
res = sscanf(name, "%8s-if00", serial);
|
||||||
while (*name != 'v')
|
if (res != 1)
|
||||||
name++;
|
return -1;
|
||||||
if (!*name) {
|
strcpy(type, "Native");
|
||||||
DEBUG_WARN("Unexpected end after type\n");
|
strcpy(version, "Unknown");
|
||||||
return -1;
|
} else if (underscores == 2) {
|
||||||
|
strncpy(type, name, delims[0] - name - 1);
|
||||||
|
strncpy(version, delims[0] + 1, delims[1] - delims[0] - 1);
|
||||||
|
int res = sscanf(delims[1] + 1, "%8s-if00", serial);
|
||||||
|
if (!res)
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
int res = sscanf(delims[0] + 1, "%8s-if00", serial);
|
||||||
|
if (!res)
|
||||||
|
return -1;
|
||||||
|
if (name[0] == 'v') {
|
||||||
|
strcpy(type, "Unknown");
|
||||||
|
strncpy(version, name, delims[0] - name - 1);
|
||||||
|
} else {
|
||||||
|
strncpy(type, name, delims[0] - name);
|
||||||
|
strcpy(type, "Unknown");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
p = strchr(name, '_');
|
|
||||||
if (!p) {
|
|
||||||
DEBUG_WARN("version not found\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
strncpy(version, name, p - name);
|
|
||||||
version[p - name] = 0;
|
|
||||||
name = p;
|
|
||||||
while (*name == '_')
|
|
||||||
name++;
|
|
||||||
if (!*name) {
|
|
||||||
DEBUG_WARN("Unexpected end after version\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
p = strchr(name, '-');
|
|
||||||
if (!p) {
|
|
||||||
DEBUG_WARN("Serial not found\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
strncpy(serial, name, p - name);
|
|
||||||
serial[p - name] = 0;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,8 +242,9 @@ int find_debuggers(BMP_CL_OPTIONS_t *cl_opts, bmp_info_t *info)
|
|||||||
(cl_opts->opt_position && cl_opts->opt_position == i)) {
|
(cl_opts->opt_position && cl_opts->opt_position == i)) {
|
||||||
/* With serial number given and partial match, we are done!*/
|
/* With serial number given and partial match, we are done!*/
|
||||||
strncpy(info->serial, serial, sizeof(info->serial));
|
strncpy(info->serial, serial, sizeof(info->serial));
|
||||||
strncpy(info->manufacturer, "BMP", sizeof(info->manufacturer));
|
int res = snprintf(info->manufacturer, sizeof(info->manufacturer), "Black Magic Probe (%s)", type);
|
||||||
strncpy(info->product, type, sizeof(info->product));
|
if (res)
|
||||||
|
DEBUG_WARN("Overflow\n");
|
||||||
strncpy(info->version, version, sizeof(info->version));
|
strncpy(info->version, version, sizeof(info->version));
|
||||||
found_bmps = 1;
|
found_bmps = 1;
|
||||||
break;
|
break;
|
||||||
@ -265,8 +274,7 @@ int find_debuggers(BMP_CL_OPTIONS_t *cl_opts, bmp_info_t *info)
|
|||||||
strncpy(info->serial, serial, sizeof(info->serial));
|
strncpy(info->serial, serial, sizeof(info->serial));
|
||||||
found_bmps = 1;
|
found_bmps = 1;
|
||||||
strncpy(info->serial, serial, sizeof(info->serial));
|
strncpy(info->serial, serial, sizeof(info->serial));
|
||||||
strncpy(info->manufacturer, "BMP", sizeof(info->manufacturer));
|
snprintf(info->manufacturer, sizeof(info->manufacturer), "Black Magic Probe (%s)", type);
|
||||||
strncpy(info->product, type, sizeof(info->product));
|
|
||||||
strncpy(info->version, version, sizeof(info->version));
|
strncpy(info->version, version, sizeof(info->version));
|
||||||
break;
|
break;
|
||||||
} else if (found_bmps > 0) {
|
} else if (found_bmps > 0) {
|
||||||
|
@ -44,10 +44,10 @@ uint32_t dap_swj_clock(uint32_t clock) {return 0;}
|
|||||||
void dap_exit_function(void) {};
|
void dap_exit_function(void) {};
|
||||||
void dap_adiv5_dp_defaults(ADIv5_DP_t *dp) {};
|
void dap_adiv5_dp_defaults(ADIv5_DP_t *dp) {};
|
||||||
int cmsis_dap_jtagtap_init(jtag_proc_t *jtag_proc) {return -1;}
|
int cmsis_dap_jtagtap_init(jtag_proc_t *jtag_proc) {return -1;}
|
||||||
int dap_swdptap_init(swd_proc_t *swd_proc) {return -1;}
|
int dap_swdptap_init(ADIv5_DP_t *dp) {return -1;}
|
||||||
int dap_jtag_dp_init(ADIv5_DP_t *dp) {return -1;}
|
int dap_jtag_dp_init(ADIv5_DP_t *dp) {return -1;}
|
||||||
void dap_swd_configure(uint8_t cfg) {};
|
void dap_swd_configure(uint8_t cfg) {};
|
||||||
## pragma GCC diagnostic pop
|
# pragma GCC diagnostic pop
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -32,7 +32,6 @@
|
|||||||
|
|
||||||
/*- Includes ----------------------------------------------------------------*/
|
/*- Includes ----------------------------------------------------------------*/
|
||||||
#include <general.h>
|
#include <general.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include "dap.h"
|
#include "dap.h"
|
||||||
#include "jtag_scan.h"
|
#include "jtag_scan.h"
|
||||||
|
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
*/
|
*/
|
||||||
#include "general.h"
|
#include "general.h"
|
||||||
#include "gdb_if.h"
|
#include "gdb_if.h"
|
||||||
#include "platform.h"
|
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
@ -270,7 +269,7 @@ int ftdi_bmp_init(BMP_CL_OPTIONS_t *cl_opts, bmp_info_t *info)
|
|||||||
int err;
|
int err;
|
||||||
cable_desc_t *cable = &cable_desc[0];
|
cable_desc_t *cable = &cable_desc[0];
|
||||||
for(; cable->name; cable++) {
|
for(; cable->name; cable++) {
|
||||||
if (strcmp(cable->name, cl_opts->opt_cable) == 0)
|
if (strncmp(cable->name, cl_opts->opt_cable, strlen(cable->name)) == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,7 +281,7 @@ int ftdi_bmp_init(BMP_CL_OPTIONS_t *cl_opts, bmp_info_t *info)
|
|||||||
active_cable = cable;
|
active_cable = cable;
|
||||||
memcpy(&active_state, &active_cable->init, sizeof(data_desc_t));
|
memcpy(&active_state, &active_cable->init, sizeof(data_desc_t));
|
||||||
/* If swd_(read|write) is not given for the selected cable and
|
/* If swd_(read|write) is not given for the selected cable and
|
||||||
the 'r' command line argument is give, assume resistor SWD
|
the 'e' command line argument is give, assume resistor SWD
|
||||||
connection.*/
|
connection.*/
|
||||||
if (cl_opts->external_resistor_swd &&
|
if (cl_opts->external_resistor_swd &&
|
||||||
(active_cable->mpsse_swd_read.set_data_low == 0) &&
|
(active_cable->mpsse_swd_read.set_data_low == 0) &&
|
||||||
|
@ -21,13 +21,10 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include "general.h"
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include "general.h"
|
|
||||||
#include "exception.h"
|
#include "exception.h"
|
||||||
|
|
||||||
#include "jlink.h"
|
#include "jlink.h"
|
||||||
|
@ -22,15 +22,12 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include "general.h"
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <string.h>
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <ftdi.h>
|
#include <ftdi.h>
|
||||||
#include "platform.h"
|
|
||||||
#include "ftdi_bmp.h"
|
#include "ftdi_bmp.h"
|
||||||
|
|
||||||
#include "general.h"
|
|
||||||
|
|
||||||
extern cable_desc_t *active_cable;
|
extern cable_desc_t *active_cable;
|
||||||
extern struct ftdi_context *ftdic;
|
extern struct ftdi_context *ftdic;
|
||||||
|
@ -21,12 +21,10 @@
|
|||||||
* Speed is sensible.
|
* Speed is sensible.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include "general.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include "general.h"
|
|
||||||
#include <ftdi.h>
|
#include <ftdi.h>
|
||||||
#include "platform.h"
|
|
||||||
#include "ftdi_bmp.h"
|
#include "ftdi_bmp.h"
|
||||||
|
|
||||||
enum swdio_status{
|
enum swdio_status{
|
||||||
|
@ -26,13 +26,11 @@
|
|||||||
* Should share interface with swdptap.c or at least clean up...
|
* Should share interface with swdptap.c or at least clean up...
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include "general.h"
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include "general.h"
|
|
||||||
#include "remote.h"
|
#include "remote.h"
|
||||||
#include "jtagtap.h"
|
#include "jtagtap.h"
|
||||||
#include "bmp_remote.h"
|
#include "bmp_remote.h"
|
||||||
|
@ -24,12 +24,10 @@
|
|||||||
|
|
||||||
#include "general.h"
|
#include "general.h"
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "target.h"
|
|
||||||
#include "target_internal.h"
|
#include "target_internal.h"
|
||||||
#include "cortexm.h"
|
#include "cortexm.h"
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
@ -135,6 +133,7 @@ static void cl_help(char **argv)
|
|||||||
DEBUG_WARN("\t-h\t\t: This help.\n");
|
DEBUG_WARN("\t-h\t\t: This help.\n");
|
||||||
DEBUG_WARN("\t-v[bitmask]\t: Increasing verbosity. Bitmask:\n");
|
DEBUG_WARN("\t-v[bitmask]\t: Increasing verbosity. Bitmask:\n");
|
||||||
DEBUG_WARN("\t\t\t 1 = INFO, 2 = GDB, 4 = TARGET, 8 = PROBE, 16 = WIRE\n");
|
DEBUG_WARN("\t\t\t 1 = INFO, 2 = GDB, 4 = TARGET, 8 = PROBE, 16 = WIRE\n");
|
||||||
|
DEBUG_WARN("\t-l\t\t: List available probes\n");
|
||||||
DEBUG_WARN("Probe selection arguments:\n");
|
DEBUG_WARN("Probe selection arguments:\n");
|
||||||
DEBUG_WARN("\t-d \"path\"\t: Use serial BMP device at <path>");
|
DEBUG_WARN("\t-d \"path\"\t: Use serial BMP device at <path>");
|
||||||
#if HOSTED_BMP_ONLY == 1 && defined(__APPLE__)
|
#if HOSTED_BMP_ONLY == 1 && defined(__APPLE__)
|
||||||
@ -419,7 +418,10 @@ int cl_execute(BMP_CL_OPTIONS_t *opt)
|
|||||||
}
|
}
|
||||||
if (opt->opt_flash_start == 0xffffffff)
|
if (opt->opt_flash_start == 0xffffffff)
|
||||||
opt->opt_flash_start = lowest_flash_start;
|
opt->opt_flash_start = lowest_flash_start;
|
||||||
if (opt->opt_flash_size == 0xffffffff)
|
if ((opt->opt_flash_size == 0xffffffff) &&
|
||||||
|
(opt->opt_mode != BMP_MODE_FLASH_WRITE) &&
|
||||||
|
(opt->opt_mode != BMP_MODE_FLASH_VERIFY) &&
|
||||||
|
(opt->opt_mode != BMP_MODE_FLASH_VERIFY))
|
||||||
opt->opt_flash_size = lowest_flash_size;
|
opt->opt_flash_size = lowest_flash_size;
|
||||||
if (opt->opt_mode == BMP_MODE_SWJ_TEST) {
|
if (opt->opt_mode == BMP_MODE_SWJ_TEST) {
|
||||||
switch (t->core[0]) {
|
switch (t->core[0]) {
|
||||||
|
@ -36,13 +36,11 @@
|
|||||||
# include <fcntl.h>
|
# include <fcntl.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include "general.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "general.h"
|
|
||||||
#include "gdb_if.h"
|
#include "gdb_if.h"
|
||||||
|
|
||||||
static int gdb_if_serv, gdb_if_conn;
|
static int gdb_if_serv, gdb_if_conn;
|
||||||
@ -51,8 +49,13 @@ static int gdb_if_serv, gdb_if_conn;
|
|||||||
int gdb_if_init(void)
|
int gdb_if_init(void)
|
||||||
{
|
{
|
||||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||||
|
int iResult;
|
||||||
WSADATA wsaData;
|
WSADATA wsaData;
|
||||||
WSAStartup(MAKEWORD(2, 2), &wsaData);
|
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
|
||||||
|
if (iResult != NO_ERROR) {
|
||||||
|
DEBUG_WARN("WSAStartup failed with error: %ld\n", iResult);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
int opt;
|
int opt;
|
||||||
@ -67,23 +70,47 @@ int gdb_if_init(void)
|
|||||||
addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||||
|
|
||||||
gdb_if_serv = socket(PF_INET, SOCK_STREAM, 0);
|
gdb_if_serv = socket(PF_INET, SOCK_STREAM, 0);
|
||||||
if (gdb_if_serv == -1)
|
if (gdb_if_serv == -1) {
|
||||||
|
DEBUG_WARN("PF_INET %d\n",gdb_if_serv);
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
opt = 1;
|
opt = 1;
|
||||||
if (setsockopt(gdb_if_serv, SOL_SOCKET, SO_REUSEADDR, (void*)&opt, sizeof(opt)) == -1) {
|
if (setsockopt(gdb_if_serv, SOL_SOCKET, SO_REUSEADDR, (void*)&opt, sizeof(opt)) == -1) {
|
||||||
|
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||||
|
DEBUG_WARN("error setsockopt SOL_SOCKET : %d error: %d\n", gdb_if_serv,
|
||||||
|
WSAGetLastError());
|
||||||
|
#else
|
||||||
|
DEBUG_WARN("error setsockopt SOL_SOCKET : %d error: %d\n", gdb_if_serv,
|
||||||
|
strerror(errno));
|
||||||
|
#endif
|
||||||
close(gdb_if_serv);
|
close(gdb_if_serv);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (setsockopt(gdb_if_serv, IPPROTO_TCP, TCP_NODELAY, (void*)&opt, sizeof(opt)) == -1) {
|
if (setsockopt(gdb_if_serv, IPPROTO_TCP, TCP_NODELAY, (void*)&opt, sizeof(opt)) == -1) {
|
||||||
|
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||||
|
DEBUG_WARN("error setsockopt IPPROTO_TCP : %d error: %d\n", gdb_if_serv,
|
||||||
|
WSAGetLastError());
|
||||||
|
#else
|
||||||
|
DEBUG_WARN("error setsockopt IPPROTO_TCP : %d error: %d\n", gdb_if_serv,
|
||||||
|
strerror(errno));
|
||||||
|
#endif
|
||||||
close(gdb_if_serv);
|
close(gdb_if_serv);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (bind(gdb_if_serv, (void*)&addr, sizeof(addr)) == -1) {
|
if (bind(gdb_if_serv, (void*)&addr, sizeof(addr)) == -1) {
|
||||||
|
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||||
|
DEBUG_WARN("error when binding socket: %d error: %d\n", gdb_if_serv,
|
||||||
|
WSAGetLastError());
|
||||||
|
#else
|
||||||
|
DEBUG_WARN("error when binding socket: %d error: %d\n", gdb_if_serv,
|
||||||
|
strerror(errno));
|
||||||
|
#endif
|
||||||
close(gdb_if_serv);
|
close(gdb_if_serv);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (listen(gdb_if_serv, 1) == -1) {
|
if (listen(gdb_if_serv, 1) == -1) {
|
||||||
|
DEBUG_WARN("listen closed %d\n",gdb_if_serv);
|
||||||
close(gdb_if_serv);
|
close(gdb_if_serv);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -100,6 +127,7 @@ unsigned char gdb_if_getchar(void)
|
|||||||
unsigned char ret;
|
unsigned char ret;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||||
|
int iResult;
|
||||||
unsigned long opt;
|
unsigned long opt;
|
||||||
#else
|
#else
|
||||||
int flags;
|
int flags;
|
||||||
@ -108,7 +136,10 @@ unsigned char gdb_if_getchar(void)
|
|||||||
if(gdb_if_conn <= 0) {
|
if(gdb_if_conn <= 0) {
|
||||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||||
opt = 1;
|
opt = 1;
|
||||||
ioctlsocket(gdb_if_serv, FIONBIO, &opt);
|
iResult = ioctlsocket(gdb_if_serv, FIONBIO, &opt);
|
||||||
|
if (iResult != NO_ERROR) {
|
||||||
|
DEBUG_WARN("ioctlsocket failed with error: %ld\n", iResult);
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
flags = fcntl(gdb_if_serv, F_GETFL);
|
flags = fcntl(gdb_if_serv, F_GETFL);
|
||||||
fcntl(gdb_if_serv, F_SETFL, flags | O_NONBLOCK);
|
fcntl(gdb_if_serv, F_SETFL, flags | O_NONBLOCK);
|
||||||
|
@ -61,9 +61,7 @@ extern "C" {
|
|||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <general.h>
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
|
|
||||||
#include "hidapi.h"
|
#include "hidapi.h"
|
||||||
|
|
||||||
|
@ -17,16 +17,15 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#include <sys/types.h>
|
#include "general.h"
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/select.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "general.h"
|
|
||||||
#include "remote.h"
|
#include "remote.h"
|
||||||
#include "cl_utils.h"
|
#include "cl_utils.h"
|
||||||
#include "cortexm.h"
|
#include "cortexm.h"
|
||||||
@ -60,8 +59,9 @@ static int set_interface_attribs(void)
|
|||||||
tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls,
|
tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls,
|
||||||
// enable reading
|
// enable reading
|
||||||
tty.c_cflag &= ~CSTOPB;
|
tty.c_cflag &= ~CSTOPB;
|
||||||
|
#if defined(CRTSCTS)
|
||||||
tty.c_cflag &= ~CRTSCTS;
|
tty.c_cflag &= ~CRTSCTS;
|
||||||
|
#endif
|
||||||
if (tcsetattr (fd, TCSANOW, &tty) != 0) {
|
if (tcsetattr (fd, TCSANOW, &tty) != 0) {
|
||||||
DEBUG_WARN("error %d from tcsetattr", errno);
|
DEBUG_WARN("error %d from tcsetattr", errno);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include "general.h"
|
#include "general.h"
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include "remote.h"
|
#include "remote.h"
|
||||||
|
@ -44,7 +44,14 @@ int vasprintf(char **strp, const char *fmt, va_list ap)
|
|||||||
|
|
||||||
void platform_delay(uint32_t ms)
|
void platform_delay(uint32_t ms)
|
||||||
{
|
{
|
||||||
usleep(ms * 1000);
|
#if defined(_WIN32) && !defined(__MINGW32__)
|
||||||
|
Sleep(ms);
|
||||||
|
#else
|
||||||
|
# if !defined(usleep)
|
||||||
|
int usleep(unsigned int);
|
||||||
|
# endif
|
||||||
|
usleep(ms);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t platform_time_ms(void)
|
uint32_t platform_time_ms(void)
|
||||||
|
@ -39,6 +39,7 @@ static inline void _gpio_set(uint32_t gpioport, uint16_t gpios)
|
|||||||
{
|
{
|
||||||
GPIO_BSRR(gpioport) = gpios;
|
GPIO_BSRR(gpioport) = gpios;
|
||||||
#ifdef STM32F4
|
#ifdef STM32F4
|
||||||
|
/* FIXME: Check if doubling is still needed */
|
||||||
GPIO_BSRR(gpioport) = gpios;
|
GPIO_BSRR(gpioport) = gpios;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -46,11 +47,14 @@ static inline void _gpio_set(uint32_t gpioport, uint16_t gpios)
|
|||||||
|
|
||||||
static inline void _gpio_clear(uint32_t gpioport, uint16_t gpios)
|
static inline void _gpio_clear(uint32_t gpioport, uint16_t gpios)
|
||||||
{
|
{
|
||||||
#ifndef STM32F4
|
#if defined(STM32F4)
|
||||||
|
GPIO_BSRR(gpioport) = gpios<<16;
|
||||||
|
/* FIXME: Check if doubling is still needed */
|
||||||
|
GPIO_BSRR(gpioport) = gpios<<16;
|
||||||
|
#elif defined(GPIO_BRR)
|
||||||
GPIO_BRR(gpioport) = gpios;
|
GPIO_BRR(gpioport) = gpios;
|
||||||
#else
|
#else
|
||||||
GPIO_BSRR(gpioport) = gpios<<16;
|
GPIO_BSRR(gpioport) = gpios<<16;
|
||||||
GPIO_BSRR(gpioport) = gpios<<16;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#define gpio_clear _gpio_clear
|
#define gpio_clear _gpio_clear
|
||||||
|
@ -118,8 +118,14 @@ void usbuart_init(void)
|
|||||||
USBUSART_CR1 |= USART_CR1_IDLEIE;
|
USBUSART_CR1 |= USART_CR1_IDLEIE;
|
||||||
|
|
||||||
/* Setup USART TX DMA */
|
/* Setup USART TX DMA */
|
||||||
|
#if !defined(USBUSART_TDR) && defined(USBUSART_DR)
|
||||||
|
# define USBUSART_TDR USBUSART_DR
|
||||||
|
#endif
|
||||||
|
#if !defined(USBUSART_RDR) && defined(USBUSART_DR)
|
||||||
|
# define USBUSART_RDR USBUSART_DR
|
||||||
|
#endif
|
||||||
dma_channel_reset(USBUSART_DMA_BUS, USBUSART_DMA_TX_CHAN);
|
dma_channel_reset(USBUSART_DMA_BUS, USBUSART_DMA_TX_CHAN);
|
||||||
dma_set_peripheral_address(USBUSART_DMA_BUS, USBUSART_DMA_TX_CHAN, (uint32_t)&USBUSART_DR);
|
dma_set_peripheral_address(USBUSART_DMA_BUS, USBUSART_DMA_TX_CHAN, (uint32_t)&USBUSART_TDR);
|
||||||
dma_enable_memory_increment_mode(USBUSART_DMA_BUS, USBUSART_DMA_TX_CHAN);
|
dma_enable_memory_increment_mode(USBUSART_DMA_BUS, USBUSART_DMA_TX_CHAN);
|
||||||
dma_set_peripheral_size(USBUSART_DMA_BUS, USBUSART_DMA_TX_CHAN, DMA_PSIZE_8BIT);
|
dma_set_peripheral_size(USBUSART_DMA_BUS, USBUSART_DMA_TX_CHAN, DMA_PSIZE_8BIT);
|
||||||
dma_set_memory_size(USBUSART_DMA_BUS, USBUSART_DMA_TX_CHAN, DMA_MSIZE_8BIT);
|
dma_set_memory_size(USBUSART_DMA_BUS, USBUSART_DMA_TX_CHAN, DMA_MSIZE_8BIT);
|
||||||
@ -136,7 +142,7 @@ void usbuart_init(void)
|
|||||||
|
|
||||||
/* Setup USART RX DMA */
|
/* Setup USART RX DMA */
|
||||||
dma_channel_reset(USBUSART_DMA_BUS, USBUSART_DMA_RX_CHAN);
|
dma_channel_reset(USBUSART_DMA_BUS, USBUSART_DMA_RX_CHAN);
|
||||||
dma_set_peripheral_address(USBUSART_DMA_BUS, USBUSART_DMA_RX_CHAN, (uint32_t)&USBUSART_DR);
|
dma_set_peripheral_address(USBUSART_DMA_BUS, USBUSART_DMA_RX_CHAN, (uint32_t)&USBUSART_RDR);
|
||||||
dma_set_memory_address(USBUSART_DMA_BUS, USBUSART_DMA_RX_CHAN, (uint32_t)buf_rx);
|
dma_set_memory_address(USBUSART_DMA_BUS, USBUSART_DMA_RX_CHAN, (uint32_t)buf_rx);
|
||||||
dma_set_number_of_data(USBUSART_DMA_BUS, USBUSART_DMA_RX_CHAN, RX_FIFO_SIZE);
|
dma_set_number_of_data(USBUSART_DMA_BUS, USBUSART_DMA_RX_CHAN, RX_FIFO_SIZE);
|
||||||
dma_enable_memory_increment_mode(USBUSART_DMA_BUS, USBUSART_DMA_RX_CHAN);
|
dma_enable_memory_increment_mode(USBUSART_DMA_BUS, USBUSART_DMA_RX_CHAN);
|
||||||
@ -393,8 +399,15 @@ void USBUSART_ISR(void)
|
|||||||
usart_recv(USBUSART);
|
usart_recv(USBUSART);
|
||||||
|
|
||||||
/* If line is now idle, then transmit a packet */
|
/* If line is now idle, then transmit a packet */
|
||||||
if (isIdle)
|
if (isIdle) {
|
||||||
|
#if defined(USART_ICR)
|
||||||
|
USART_ICR(USBUSART) = USART_ICR_IDLECF;
|
||||||
|
#else
|
||||||
|
/* On the older uarts, the sequence "read flags", "read DR"
|
||||||
|
* as above cleared the flags */
|
||||||
|
#endif
|
||||||
usbuart_run();
|
usbuart_run();
|
||||||
|
}
|
||||||
|
|
||||||
nvic_enable_irq(USBUSART_DMA_RX_IRQ);
|
nvic_enable_irq(USBUSART_DMA_RX_IRQ);
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,6 @@
|
|||||||
#include "gdb_packet.h"
|
#include "gdb_packet.h"
|
||||||
#include "jtagtap.h"
|
#include "jtagtap.h"
|
||||||
#include "gdb_if.h"
|
#include "gdb_if.h"
|
||||||
#include "platform.h"
|
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "exception.h"
|
#include "exception.h"
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
@ -661,8 +661,8 @@ void adiv5_dp_init(ADIv5_DP_t *dp)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DEBUG_INFO("DPIDR 0x%08" PRIx32 " (v%d %srev%d)\n", dp->idcode,
|
DEBUG_INFO("DPIDR 0x%08" PRIx32 " (v%d %srev%d)\n", dp->idcode,
|
||||||
(dp->idcode >> 12) & 0xf,
|
(uint8_t)((dp->idcode >> 12) & 0xf),
|
||||||
(dp->idcode & 0x10000) ? "MINDP " : "", dp->idcode >> 28);
|
(dp->idcode & 0x10000) ? "MINDP " : "", (uint16_t)(dp->idcode >> 28));
|
||||||
volatile uint32_t ctrlstat = 0;
|
volatile uint32_t ctrlstat = 0;
|
||||||
#if PC_HOSTED == 1
|
#if PC_HOSTED == 1
|
||||||
platform_adiv5_dp_defaults(dp);
|
platform_adiv5_dp_defaults(dp);
|
||||||
|
@ -33,7 +33,6 @@
|
|||||||
#include "target.h"
|
#include "target.h"
|
||||||
#include "target_internal.h"
|
#include "target_internal.h"
|
||||||
#include "cortexm.h"
|
#include "cortexm.h"
|
||||||
#include "platform.h"
|
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
#include "gdb_packet.h"
|
#include "gdb_packet.h"
|
||||||
|
|
||||||
@ -328,7 +327,7 @@ bool cortexm_probe(ADIv5_AP_t *ap)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (ap->ap_designer != AP_DESIGNER_ATMEL) /* Protected Atmel device?*/{
|
if (ap->ap_designer != AP_DESIGNER_ATMEL) /* Protected Atmel device?*/{
|
||||||
DEBUG_WARN("Unexpected CortexM CPUID partno %04x\n", cpuid_partno);
|
DEBUG_WARN("Unexpected CortexM CPUID partno %04" PRIx32 "\n", cpuid_partno);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DEBUG_INFO("CPUID 0x%08" PRIx32 " (%s var %" PRIx32 " rev %" PRIx32 ")\n",
|
DEBUG_INFO("CPUID 0x%08" PRIx32 " (%s var %" PRIx32 " rev %" PRIx32 ")\n",
|
||||||
@ -441,6 +440,7 @@ bool cortexm_probe(ADIv5_AP_t *ap)
|
|||||||
if (ap->ap_partno == 0x4c0) { /* Cortex-M0+ ROM */
|
if (ap->ap_partno == 0x4c0) { /* Cortex-M0+ ROM */
|
||||||
if ((ap->dp->targetid & 0xfff) == AP_DESIGNER_RASPBERRY)
|
if ((ap->dp->targetid & 0xfff) == AP_DESIGNER_RASPBERRY)
|
||||||
PROBE(rp_probe);
|
PROBE(rp_probe);
|
||||||
|
PROBE(lpc11xx_probe); /* LPC8 */
|
||||||
} else if (ap->ap_partno == 0x4c3) { /* Cortex-M3 ROM */
|
} else if (ap->ap_partno == 0x4c3) { /* Cortex-M3 ROM */
|
||||||
PROBE(stm32f1_probe); /* Care for STM32F1 clones */
|
PROBE(stm32f1_probe); /* Care for STM32F1 clones */
|
||||||
PROBE(lpc15xx_probe); /* Thanks to JojoS for testing */
|
PROBE(lpc15xx_probe); /* Thanks to JojoS for testing */
|
||||||
|
@ -267,75 +267,75 @@ const struct command_s efm32_cmd_list[] = {
|
|||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
typedef struct efm32_device_t {
|
typedef struct efm32_device_t {
|
||||||
uint16_t family_id; /* Family for device matching */
|
uint8_t family_id; /* Family for device matching */
|
||||||
char* name; /* Friendly device family name */
|
|
||||||
uint32_t flash_page_size; /* Flash page size */
|
|
||||||
uint32_t msc_addr; /* MSC Address */
|
|
||||||
bool has_radio; /* Indicates a device has attached radio */
|
bool has_radio; /* Indicates a device has attached radio */
|
||||||
uint32_t user_data_size; /* User Data (UD) region size */
|
uint16_t flash_page_size; /* Flash page size */
|
||||||
uint32_t bootloader_size; /* Bootloader (BL) region size (may be 0 for no BL region) */
|
char* name; /* Friendly device family name */
|
||||||
|
uint32_t msc_addr; /* MSC Address */
|
||||||
|
uint16_t user_data_size; /* User Data (UD) region size */
|
||||||
|
uint16_t bootloader_size; /* Bootloader (BL) region size (may be 0 for no BL region) */
|
||||||
char* description; /* Human-readable description */
|
char* description; /* Human-readable description */
|
||||||
} efm32_device_t;
|
} efm32_device_t;
|
||||||
|
|
||||||
efm32_device_t const efm32_devices[] = {
|
efm32_device_t const efm32_devices[] = {
|
||||||
/* First gen micros */
|
/* First gen micros */
|
||||||
{71, "EFM32G", 512, 0x400c0000, false, 512, 0, "Gecko"},
|
{ 71, false, 512, "EFM32G" , 0x400c0000, 512, 0, "Gecko"},
|
||||||
{72, "EFM32GG", 2048, 0x400c0000, false, 4096, 0, "Giant Gecko"},
|
{ 72, false, 2048, "EFM32GG" , 0x400c0000, 4096, 0, "Giant Gecko"},
|
||||||
{73, "EFM32TG", 512, 0x400c0000, false, 512, 0, "Tiny Gecko"},
|
{ 73, false, 512, "EFM32TG" , 0x400c0000, 512, 0, "Tiny Gecko"},
|
||||||
{74, "EFM32LG", 2048, 0x400c0000, false, 2048, 0, "Leopard Gecko"},
|
{ 74, false, 2048, "EFM32LG" , 0x400c0000, 2048, 0, "Leopard Gecko"},
|
||||||
{75, "EFM32WG", 2048, 0x400c0000, false, 2048, 0, "Wonder Gecko"},
|
{ 75, false, 2048, "EFM32WG" , 0x400c0000, 2048, 0, "Wonder Gecko"},
|
||||||
{76, "EFM32ZG", 1024, 0x400c0000, false, 1024, 0, "Zero Gecko"},
|
{ 76, false, 1024, "EFM32ZG" , 0x400c0000, 1024, 0, "Zero Gecko"},
|
||||||
{77, "EFM32HG", 1024, 0x400c0000, false, 1024, 0, "Happy Gecko"},
|
{ 77, false, 1024, "EFM32HG" , 0x400c0000, 1024, 0, "Happy Gecko"},
|
||||||
/* First (1.5) gen micro + radio */
|
/* First (1.5) gen micro + radio */
|
||||||
{120, "EZR32WG", 2048, 0x400c0000, true, 2048, 0, "EZR Wonder Gecko"},
|
{120, true , 2048, "EZR32WG" , 0x400c0000, 2048, 0, "EZR Wonder Gecko"},
|
||||||
{121, "EZR32LG", 2048, 0x400c0000, true, 2048, 0, "EZR Leopard Gecko"},
|
{121, true , 2048, "EZR32LG" , 0x400c0000, 2048, 0, "EZR Leopard Gecko"},
|
||||||
{122, "EZR32HG", 1024, 0x400c0000, true, 1024, 0, "EZR Happy Gecko"},
|
{122, true , 1024, "EZR32HG" , 0x400c0000, 1024, 0, "EZR Happy Gecko"},
|
||||||
/* Second gen micros */
|
/* Second gen micros */
|
||||||
{81, "EFM32PG1B", 2048, 0x400e0000, false, 2048, 10240, "Pearl Gecko"},
|
{ 81, false, 2048, "EFM32PG1B" , 0x400e0000, 2048, 10240, "Pearl Gecko"},
|
||||||
{83, "EFM32JG1B", 2048, 0x400e0000, false, 2048, 10240, "Jade Gecko"},
|
{ 83, false, 2048, "EFM32JG1B" , 0x400e0000, 2048, 10240, "Jade Gecko"},
|
||||||
{85, "EFM32PG12B", 2048, 0x400e0000, false, 2048, 32768,"Pearl Gecko 12"},
|
{ 85, false, 2048, "EFM32PG12B", 0x400e0000, 2048, 32768,"Pearl Gecko 12"},
|
||||||
{87, "EFM32JG12B", 2048, 0x400e0000, false, 2048, 32768, "Jade Gecko 12"},
|
{ 87, false, 2048, "EFM32JG12B", 0x400e0000, 2048, 32768, "Jade Gecko 12"},
|
||||||
/* Second (2.5) gen micros, with re-located MSC */
|
/* Second (2.5) gen micros, with re-located MSC */
|
||||||
{100, "EFM32GG11B", 4096, 0x40000000, false, 4096, 32768, "Giant Gecko 11"},
|
{100, false, 4096, "EFM32GG11B", 0x40000000, 4096, 32768, "Giant Gecko 11"},
|
||||||
{103, "EFM32TG11B", 2048, 0x40000000, false, 2048, 18432, "Tiny Gecko 11"},
|
{103, false, 2048, "EFM32TG11B", 0x40000000, 2048, 18432, "Tiny Gecko 11"},
|
||||||
{106, "EFM32GG12B", 2048, 0x40000000, false, 2048, 32768, "Giant Gecko 12"},
|
{106, false, 2048, "EFM32GG12B", 0x40000000, 2048, 32768, "Giant Gecko 12"},
|
||||||
/* Second gen devices micro + radio */
|
/* Second gen devices micro + radio */
|
||||||
{16, "EFR32MG1P", 2048, 0x400e0000, true, 2048, 10240, "Mighty Gecko"},
|
{ 16, true , 2048, "EFR32MG1P" , 0x400e0000, 2048, 10240, "Mighty Gecko"},
|
||||||
{17, "EFR32MG1B", 2048, 0x400e0000, true, 2048, 10240, "Mighty Gecko"},
|
{ 17, true , 2048, "EFR32MG1B" , 0x400e0000, 2048, 10240, "Mighty Gecko"},
|
||||||
{18, "EFR32MG1V", 2048, 0x400e0000, true, 2048, 10240, "Mighty Gecko"},
|
{ 18, true , 2048, "EFR32MG1V" , 0x400e0000, 2048, 10240, "Mighty Gecko"},
|
||||||
{19, "EFR32BG1P", 2048, 0x400e0000, true, 2048, 10240, "Blue Gecko"},
|
{ 19, true , 2048, "EFR32BG1P" , 0x400e0000, 2048, 10240, "Blue Gecko"},
|
||||||
{20, "EFR32BG1B", 2048, 0x400e0000, true, 2048, 10240, "Blue Gecko"},
|
{ 20, true , 2048, "EFR32BG1B" , 0x400e0000, 2048, 10240, "Blue Gecko"},
|
||||||
{21, "EFR32BG1V", 2048, 0x400e0000, true, 2048, 10240, "Blue Gecko"},
|
{ 21, true , 2048, "EFR32BG1V" , 0x400e0000, 2048, 10240, "Blue Gecko"},
|
||||||
{25, "EFR32FG1P", 2048, 0x400e0000, true, 2048, 10240, "Flex Gecko"},
|
{ 25, true , 2048, "EFR32FG1P" , 0x400e0000, 2048, 10240, "Flex Gecko"},
|
||||||
{26, "EFR32FG1B", 2048, 0x400e0000, true, 2048, 10240, "Flex Gecko"},
|
{ 26, true , 2048, "EFR32FG1B" , 0x400e0000, 2048, 10240, "Flex Gecko"},
|
||||||
{27, "EFR32FG1V", 2048, 0x400e0000, true, 2048, 10240, "Flex Gecko"},
|
{ 27, true , 2048, "EFR32FG1V" , 0x400e0000, 2048, 10240, "Flex Gecko"},
|
||||||
{28, "EFR32MG12P", 2048, 0x400e0000, true, 2048, 32768, "Mighty Gecko"},
|
{ 28, true , 2048, "EFR32MG12P", 0x400e0000, 2048, 32768, "Mighty Gecko"},
|
||||||
{29, "EFR32MG12B", 2048, 0x400e0000, true, 2048, 32768, "Mighty Gecko"},
|
{ 29, true , 2048, "EFR32MG12B", 0x400e0000, 2048, 32768, "Mighty Gecko"},
|
||||||
{30, "EFR32MG12V", 2048, 0x400e0000, true, 2048, 32768, "Mighty Gecko"},
|
{ 30, true , 2048, "EFR32MG12V", 0x400e0000, 2048, 32768, "Mighty Gecko"},
|
||||||
{31, "EFR32BG12P", 2048, 0x400e0000, true, 2048, 32768, "Blue Gecko"},
|
{ 31, true , 2048, "EFR32BG12P", 0x400e0000, 2048, 32768, "Blue Gecko"},
|
||||||
{32, "EFR32BG12B", 2048, 0x400e0000, true, 2048, 32768, "Blue Gecko"},
|
{ 32, true , 2048, "EFR32BG12B", 0x400e0000, 2048, 32768, "Blue Gecko"},
|
||||||
{33, "EFR32BG12V", 2048, 0x400e0000, true, 2048, 32768, "Blue Gecko"},
|
{ 33, true , 2048, "EFR32BG12V", 0x400e0000, 2048, 32768, "Blue Gecko"},
|
||||||
{37, "EFR32FG12P", 2048, 0x400e0000, true, 2048, 32768, "Flex Gecko"},
|
{ 37, true , 2048, "EFR32FG12P", 0x400e0000, 2048, 32768, "Flex Gecko"},
|
||||||
{38, "EFR32FG12B", 2048, 0x400e0000, true, 2048, 32768, "Flex Gecko"},
|
{ 38, true , 2048, "EFR32FG12B", 0x400e0000, 2048, 32768, "Flex Gecko"},
|
||||||
{39, "EFR32FG12V", 2048, 0x400e0000, true, 2048, 32768, "Flex Gecko"},
|
{ 39, true , 2048, "EFR32FG12V", 0x400e0000, 2048, 32768, "Flex Gecko"},
|
||||||
{40, "EFR32MG13P", 2048, 0x400e0000, true, 2048, 16384, "Mighty Gecko"},
|
{ 40, true , 2048, "EFR32MG13P", 0x400e0000, 2048, 16384, "Mighty Gecko"},
|
||||||
{41, "EFR32MG13B", 2048, 0x400e0000, true, 2048, 16384, "Mighty Gecko"},
|
{ 41, true , 2048, "EFR32MG13B", 0x400e0000, 2048, 16384, "Mighty Gecko"},
|
||||||
{42, "EFR32MG13V", 2048, 0x400e0000, true, 2048, 16384, "Mighty Gecko"},
|
{ 42, true , 2048, "EFR32MG13V", 0x400e0000, 2048, 16384, "Mighty Gecko"},
|
||||||
{43, "EFR32BG13P", 2048, 0x400e0000, true, 2048, 16384, "Blue Gecko"},
|
{ 43, true , 2048, "EFR32BG13P", 0x400e0000, 2048, 16384, "Blue Gecko"},
|
||||||
{44, "EFR32BG13B", 2048, 0x400e0000, true, 2048, 16384, "Blue Gecko"},
|
{ 44, true , 2048, "EFR32BG13B", 0x400e0000, 2048, 16384, "Blue Gecko"},
|
||||||
{45, "EFR32BG13V", 2048, 0x400e0000, true, 2048, 16384, "Blue Gecko"},
|
{ 45, true , 2048, "EFR32BG13V", 0x400e0000, 2048, 16384, "Blue Gecko"},
|
||||||
{49, "EFR32FG13P", 2048, 0x400e0000, true, 2048, 16384, "Flex Gecko"},
|
{ 49, true , 2048, "EFR32FG13P", 0x400e0000, 2048, 16384, "Flex Gecko"},
|
||||||
{50, "EFR32FG13B", 2048, 0x400e0000, true, 2048, 16384, "Flex Gecko"},
|
{ 50, true , 2048, "EFR32FG13B", 0x400e0000, 2048, 16384, "Flex Gecko"},
|
||||||
{51, "EFR32FG13V", 2048, 0x400e0000, true, 2048, 16384, "Flex Gecko"},
|
{ 51, true , 2048, "EFR32FG13V", 0x400e0000, 2048, 16384, "Flex Gecko"},
|
||||||
{52, "EFR32MG14P", 2048, 0x400e0000, true, 2048, 16384, "Mighty Gecko"},
|
{ 52, true , 2048, "EFR32MG14P", 0x400e0000, 2048, 16384, "Mighty Gecko"},
|
||||||
{53, "EFR32MG14B", 2048, 0x400e0000, true, 2048, 16384, "Mighty Gecko"},
|
{ 53, true , 2048, "EFR32MG14B", 0x400e0000, 2048, 16384, "Mighty Gecko"},
|
||||||
{54, "EFR32MG14V", 2048, 0x400e0000, true, 2048, 16384, "Mighty Gecko"},
|
{ 54, true , 2048, "EFR32MG14V", 0x400e0000, 2048, 16384, "Mighty Gecko"},
|
||||||
{55, "EFR32BG14P", 2048, 0x400e0000, true, 2048, 16384, "Blue Gecko"},
|
{ 55, true , 2048, "EFR32BG14P", 0x400e0000, 2048, 16384, "Blue Gecko"},
|
||||||
{56, "EFR32BG14B", 2048, 0x400e0000, true, 2048, 16384, "Blue Gecko"},
|
{ 56, true , 2048, "EFR32BG14B", 0x400e0000, 2048, 16384, "Blue Gecko"},
|
||||||
{57, "EFR32BG14V", 2048, 0x400e0000, true, 2048, 16384, "Blue Gecko"},
|
{ 57, true , 2048, "EFR32BG14V", 0x400e0000, 2048, 16384, "Blue Gecko"},
|
||||||
{61, "EFR32FG14P", 2048, 0x400e0000, true, 2048, 16384, "Flex Gecko"},
|
{ 61, true , 2048, "EFR32FG14P", 0x400e0000, 2048, 16384, "Flex Gecko"},
|
||||||
{62, "EFR32FG14B", 2048, 0x400e0000, true, 2048, 16384, "Flex Gecko"},
|
{ 62, true , 2048, "EFR32FG14B", 0x400e0000, 2048, 16384, "Flex Gecko"},
|
||||||
{63, "EFR32FG14V", 2048, 0x400e0000, true, 2048, 16384, "Flex Gecko"},
|
{ 63, true , 2048, "EFR32FG14V", 0x400e0000, 2048, 16384, "Flex Gecko"},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,6 +36,22 @@
|
|||||||
#define LPC11XX_DEVICE_ID 0x400483F4
|
#define LPC11XX_DEVICE_ID 0x400483F4
|
||||||
#define LPC8XX_DEVICE_ID 0x400483F8
|
#define LPC8XX_DEVICE_ID 0x400483F8
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CHIP Ram Flash page sector Rsvd pages EEPROM
|
||||||
|
* LPX80x 2k 16k 64 1024 2
|
||||||
|
* LPC804 4k 32k 64 1024 2
|
||||||
|
* LPC8N04 8k 32k 64 1024 32
|
||||||
|
* LPC810 1k 4k 64 1024 0
|
||||||
|
* LPC811 2k 8k 64 1024 0
|
||||||
|
* LPC812 4k 16k 64 1024
|
||||||
|
* LPC822 4k 16k 64 1024
|
||||||
|
* LPC822 8k 32k 64 1024
|
||||||
|
* LPC832 4k 16k 64 1024
|
||||||
|
* LPC834 4k 32k 64 1024
|
||||||
|
* LPC844 8k 64k 64 1024
|
||||||
|
* LPC845 16k 64k 64 1024
|
||||||
|
*/
|
||||||
|
|
||||||
static bool lpc11xx_read_uid(target *t, int argc, const char *argv[])
|
static bool lpc11xx_read_uid(target *t, int argc, const char *argv[])
|
||||||
{
|
{
|
||||||
(void)argc;
|
(void)argc;
|
||||||
@ -56,7 +72,7 @@ const struct command_s lpc11xx_cmd_list[] = {
|
|||||||
{NULL, NULL, NULL}
|
{NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
void lpc11xx_add_flash(target *t, uint32_t addr, size_t len, size_t erasesize, uint32_t iap_entry)
|
void lpc11xx_add_flash(target *t, uint32_t addr, size_t len, size_t erasesize, uint32_t iap_entry, uint8_t reserved_pages)
|
||||||
{
|
{
|
||||||
struct lpc_flash *lf = lpc_add_flash(t, addr, len);
|
struct lpc_flash *lf = lpc_add_flash(t, addr, len);
|
||||||
lf->f.blocksize = erasesize;
|
lf->f.blocksize = erasesize;
|
||||||
@ -65,6 +81,7 @@ void lpc11xx_add_flash(target *t, uint32_t addr, size_t len, size_t erasesize, u
|
|||||||
lf->iap_entry = iap_entry;
|
lf->iap_entry = iap_entry;
|
||||||
lf->iap_ram = IAP_RAM_BASE;
|
lf->iap_ram = IAP_RAM_BASE;
|
||||||
lf->iap_msp = IAP_RAM_BASE + MIN_RAM_SIZE - RAM_USAGE_FOR_IAP_ROUTINES;
|
lf->iap_msp = IAP_RAM_BASE + MIN_RAM_SIZE - RAM_USAGE_FOR_IAP_ROUTINES;
|
||||||
|
lf->reserved_pages = reserved_pages;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -109,7 +126,7 @@ lpc11xx_probe(target *t)
|
|||||||
case 0x2980002B: /* lpc11u24x/401 */
|
case 0x2980002B: /* lpc11u24x/401 */
|
||||||
t->driver = "LPC11xx";
|
t->driver = "LPC11xx";
|
||||||
target_add_ram(t, 0x10000000, 0x2000);
|
target_add_ram(t, 0x10000000, 0x2000);
|
||||||
lpc11xx_add_flash(t, 0x00000000, 0x20000, 0x1000, IAP_ENTRY_MOST);
|
lpc11xx_add_flash(t, 0x00000000, 0x20000, 0x1000, IAP_ENTRY_MOST, 0);
|
||||||
target_add_commands(t, lpc11xx_cmd_list, "LPC11xx");
|
target_add_commands(t, lpc11xx_cmd_list, "LPC11xx");
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -117,23 +134,26 @@ lpc11xx_probe(target *t)
|
|||||||
case 0x1A24902B:
|
case 0x1A24902B:
|
||||||
t->driver = "LPC1112";
|
t->driver = "LPC1112";
|
||||||
target_add_ram(t, 0x10000000, 0x1000);
|
target_add_ram(t, 0x10000000, 0x1000);
|
||||||
lpc11xx_add_flash(t, 0x00000000, 0x10000, 0x1000, IAP_ENTRY_MOST);
|
lpc11xx_add_flash(t, 0x00000000, 0x10000, 0x1000, IAP_ENTRY_MOST, 0);
|
||||||
return true;
|
return true;
|
||||||
case 0x1000002b: // FX LPC11U6 32 kB SRAM/256 kB flash (max)
|
case 0x1000002b: // FX LPC11U6 32 kB SRAM/256 kB flash (max)
|
||||||
t->driver = "LPC11U6";
|
t->driver = "LPC11U6";
|
||||||
target_add_ram(t, 0x10000000, 0x8000);
|
target_add_ram(t, 0x10000000, 0x8000);
|
||||||
lpc11xx_add_flash(t, 0x00000000, 0x40000, 0x1000, IAP_ENTRY_MOST);
|
lpc11xx_add_flash(t, 0x00000000, 0x40000, 0x1000, IAP_ENTRY_MOST, 0);
|
||||||
return true;
|
return true;
|
||||||
case 0x3000002B:
|
case 0x3000002B:
|
||||||
case 0x3D00002B:
|
case 0x3D00002B:
|
||||||
t->driver = "LPC1343";
|
t->driver = "LPC1343";
|
||||||
target_add_ram(t, 0x10000000, 0x2000);
|
target_add_ram(t, 0x10000000, 0x2000);
|
||||||
lpc11xx_add_flash(t, 0x00000000, 0x8000, 0x1000, IAP_ENTRY_MOST);
|
lpc11xx_add_flash(t, 0x00000000, 0x8000, 0x1000, IAP_ENTRY_MOST, 0);
|
||||||
return true;
|
return true;
|
||||||
case 0x00008A04: /* LPC8N04 (see UM11074 Rev.1.3 section 4.5.19) */
|
case 0x00008A04: /* LPC8N04 (see UM11074 Rev.1.3 section 4.5.19) */
|
||||||
t->driver = "LPC8N04";
|
t->driver = "LPC8N04";
|
||||||
target_add_ram(t, 0x10000000, 0x2000);
|
target_add_ram(t, 0x10000000, 0x2000);
|
||||||
lpc11xx_add_flash(t, 0x00000000, 0x8000, 0x400, IAP_ENTRY_MOST);
|
/* UM11074/ Flash controller/15.2: The two topmost sectors
|
||||||
|
* contain the initialization code and IAP firmware.
|
||||||
|
* Do not touch the! */
|
||||||
|
lpc11xx_add_flash(t, 0x00000000, 0x7800, 0x400, IAP_ENTRY_MOST, 0);
|
||||||
target_add_commands(t, lpc11xx_cmd_list, "LPC8N04");
|
target_add_commands(t, lpc11xx_cmd_list, "LPC8N04");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -148,7 +168,7 @@ lpc11xx_probe(target *t)
|
|||||||
case 0x00008024: /* 802M001JHI33 */
|
case 0x00008024: /* 802M001JHI33 */
|
||||||
t->driver = "LPC802";
|
t->driver = "LPC802";
|
||||||
target_add_ram(t, 0x10000000, 0x800);
|
target_add_ram(t, 0x10000000, 0x800);
|
||||||
lpc11xx_add_flash(t, 0x00000000, 0x4000, 0x400, IAP_ENTRY_84x);
|
lpc11xx_add_flash(t, 0x00000000, 0x4000, 0x400, IAP_ENTRY_84x, 2);
|
||||||
target_add_commands(t, lpc11xx_cmd_list, "LPC802");
|
target_add_commands(t, lpc11xx_cmd_list, "LPC802");
|
||||||
return true;
|
return true;
|
||||||
case 0x00008040: /* 804M101JBD64 */
|
case 0x00008040: /* 804M101JBD64 */
|
||||||
@ -158,7 +178,7 @@ lpc11xx_probe(target *t)
|
|||||||
case 0x00008044: /* 804M101JHI33 */
|
case 0x00008044: /* 804M101JHI33 */
|
||||||
t->driver = "LPC804";
|
t->driver = "LPC804";
|
||||||
target_add_ram(t, 0x10000000, 0x1000);
|
target_add_ram(t, 0x10000000, 0x1000);
|
||||||
lpc11xx_add_flash(t, 0x00000000, 0x8000, 0x400, IAP_ENTRY_84x);
|
lpc11xx_add_flash(t, 0x00000000, 0x8000, 0x400, IAP_ENTRY_84x, 2);
|
||||||
target_add_commands(t, lpc11xx_cmd_list, "LPC804");
|
target_add_commands(t, lpc11xx_cmd_list, "LPC804");
|
||||||
return true;
|
return true;
|
||||||
case 0x00008100: /* LPC810M021FN8 */
|
case 0x00008100: /* LPC810M021FN8 */
|
||||||
@ -168,7 +188,7 @@ lpc11xx_probe(target *t)
|
|||||||
case 0x00008122: /* LPC812M101JDH20 / LPC812M101JTB16 */
|
case 0x00008122: /* LPC812M101JDH20 / LPC812M101JTB16 */
|
||||||
t->driver = "LPC81x";
|
t->driver = "LPC81x";
|
||||||
target_add_ram(t, 0x10000000, 0x1000);
|
target_add_ram(t, 0x10000000, 0x1000);
|
||||||
lpc11xx_add_flash(t, 0x00000000, 0x4000, 0x400, IAP_ENTRY_MOST);
|
lpc11xx_add_flash(t, 0x00000000, 0x4000, 0x400, IAP_ENTRY_MOST, 0);
|
||||||
target_add_commands(t, lpc11xx_cmd_list, "LPC81x");
|
target_add_commands(t, lpc11xx_cmd_list, "LPC81x");
|
||||||
return true;
|
return true;
|
||||||
case 0x00008221: /* LPC822M101JHI33 */
|
case 0x00008221: /* LPC822M101JHI33 */
|
||||||
@ -177,19 +197,19 @@ lpc11xx_probe(target *t)
|
|||||||
case 0x00008242: /* LPC824M201JDH20 */
|
case 0x00008242: /* LPC824M201JDH20 */
|
||||||
t->driver = "LPC82x";
|
t->driver = "LPC82x";
|
||||||
target_add_ram(t, 0x10000000, 0x2000);
|
target_add_ram(t, 0x10000000, 0x2000);
|
||||||
lpc11xx_add_flash(t, 0x00000000, 0x8000, 0x400, IAP_ENTRY_MOST);
|
lpc11xx_add_flash(t, 0x00000000, 0x8000, 0x400, IAP_ENTRY_MOST, 0);
|
||||||
target_add_commands(t, lpc11xx_cmd_list, "LPC82x");
|
target_add_commands(t, lpc11xx_cmd_list, "LPC82x");
|
||||||
return true;
|
return true;
|
||||||
case 0x00008322: /* LPC832M101FDH20 */
|
case 0x00008322: /* LPC832M101FDH20 */
|
||||||
t->driver = "LPC832";
|
t->driver = "LPC832";
|
||||||
target_add_ram(t, 0x10000000, 0x1000);
|
target_add_ram(t, 0x10000000, 0x1000);
|
||||||
lpc11xx_add_flash(t, 0x00000000, 0x4000, 0x400, IAP_ENTRY_MOST);
|
lpc11xx_add_flash(t, 0x00000000, 0x4000, 0x400, IAP_ENTRY_MOST, 0);
|
||||||
target_add_commands(t, lpc11xx_cmd_list, "LPC832");
|
target_add_commands(t, lpc11xx_cmd_list, "LPC832");
|
||||||
return true;
|
return true;
|
||||||
case 0x00008341: /* LPC8341201FHI33 */
|
case 0x00008341: /* LPC8341201FHI33 */
|
||||||
t->driver = "LPC834";
|
t->driver = "LPC834";
|
||||||
target_add_ram(t, 0x10000000, 0x1000);
|
target_add_ram(t, 0x10000000, 0x1000);
|
||||||
lpc11xx_add_flash(t, 0x00000000, 0x8000, 0x400, IAP_ENTRY_MOST);
|
lpc11xx_add_flash(t, 0x00000000, 0x8000, 0x400, IAP_ENTRY_MOST, 0);
|
||||||
target_add_commands(t, lpc11xx_cmd_list, "LPC834");
|
target_add_commands(t, lpc11xx_cmd_list, "LPC834");
|
||||||
return true;
|
return true;
|
||||||
case 0x00008441:
|
case 0x00008441:
|
||||||
@ -198,7 +218,7 @@ lpc11xx_probe(target *t)
|
|||||||
case 0x00008444:
|
case 0x00008444:
|
||||||
t->driver = "LPC844";
|
t->driver = "LPC844";
|
||||||
target_add_ram(t, 0x10000000, 0x2000);
|
target_add_ram(t, 0x10000000, 0x2000);
|
||||||
lpc11xx_add_flash(t, 0x00000000, 0x10000, 0x400, IAP_ENTRY_84x);
|
lpc11xx_add_flash(t, 0x00000000, 0x10000, 0x400, IAP_ENTRY_84x, 0);
|
||||||
return true;
|
return true;
|
||||||
case 0x00008451:
|
case 0x00008451:
|
||||||
case 0x00008452:
|
case 0x00008452:
|
||||||
@ -206,7 +226,7 @@ lpc11xx_probe(target *t)
|
|||||||
case 0x00008454:
|
case 0x00008454:
|
||||||
t->driver = "LPC845";
|
t->driver = "LPC845";
|
||||||
target_add_ram(t, 0x10000000, 0x4000);
|
target_add_ram(t, 0x10000000, 0x4000);
|
||||||
lpc11xx_add_flash(t, 0x00000000, 0x10000, 0x400, IAP_ENTRY_84x);
|
lpc11xx_add_flash(t, 0x00000000, 0x10000, 0x400, IAP_ENTRY_84x, 0);
|
||||||
return true;
|
return true;
|
||||||
case 0x0003D440: /* LPC11U34/311 */
|
case 0x0003D440: /* LPC11U34/311 */
|
||||||
case 0x0001cc40: /* LPC11U34/421 */
|
case 0x0001cc40: /* LPC11U34/421 */
|
||||||
@ -218,13 +238,13 @@ lpc11xx_probe(target *t)
|
|||||||
case 0x00007C40: /* LPC11U37FBD64/501 */
|
case 0x00007C40: /* LPC11U37FBD64/501 */
|
||||||
t->driver = "LPC11U3x";
|
t->driver = "LPC11U3x";
|
||||||
target_add_ram(t, 0x10000000, 0x2000);
|
target_add_ram(t, 0x10000000, 0x2000);
|
||||||
lpc11xx_add_flash(t, 0x00000000, 0x20000, 0x1000, IAP_ENTRY_MOST);
|
lpc11xx_add_flash(t, 0x00000000, 0x20000, 0x1000, IAP_ENTRY_MOST, 0);
|
||||||
return true;
|
return true;
|
||||||
case 0x00040070: /* LPC1114/333 */
|
case 0x00040070: /* LPC1114/333 */
|
||||||
case 0x00050080: /* lpc1115XL */
|
case 0x00050080: /* lpc1115XL */
|
||||||
t->driver = "LPC1100XL";
|
t->driver = "LPC1100XL";
|
||||||
target_add_ram(t, 0x10000000, 0x2000);
|
target_add_ram(t, 0x10000000, 0x2000);
|
||||||
lpc11xx_add_flash(t, 0x00000000, 0x20000, 0x1000, IAP_ENTRY_MOST);
|
lpc11xx_add_flash(t, 0x00000000, 0x20000, 0x1000, IAP_ENTRY_MOST, 0);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (idcode) {
|
if (idcode) {
|
||||||
|
@ -33,6 +33,45 @@ struct flash_param {
|
|||||||
uint32_t result[4];
|
uint32_t result[4];
|
||||||
} __attribute__((aligned(4)));
|
} __attribute__((aligned(4)));
|
||||||
|
|
||||||
|
char *iap_error[] = {
|
||||||
|
"CMD_SUCCESS",
|
||||||
|
"Invalid command",
|
||||||
|
"Unaligned src address",
|
||||||
|
"Dst address not on boundary",
|
||||||
|
"Src not mapped",
|
||||||
|
"Dst not mapped",
|
||||||
|
"Invalid byte count",
|
||||||
|
"Invalid sector",
|
||||||
|
"Sector not blank",
|
||||||
|
"Sector not prepared",
|
||||||
|
"Compare error",
|
||||||
|
"Flash interface busy",
|
||||||
|
"Invalid or missing parameter",
|
||||||
|
"Address not on boundary",
|
||||||
|
"Address not mapped",
|
||||||
|
"Checksum error",
|
||||||
|
"16",
|
||||||
|
"17",
|
||||||
|
"18",
|
||||||
|
"19",
|
||||||
|
"20",
|
||||||
|
"21",
|
||||||
|
"22",
|
||||||
|
"FRO not powered",
|
||||||
|
"Flash not powered",
|
||||||
|
"25",
|
||||||
|
"26",
|
||||||
|
"Flash clock disabled",
|
||||||
|
"Reinvoke error",
|
||||||
|
"Invalid image",
|
||||||
|
"30",
|
||||||
|
"31",
|
||||||
|
"Flash erase failed",
|
||||||
|
"Page is invalid",
|
||||||
|
};
|
||||||
|
|
||||||
|
static int lpc_flash_write(struct target_flash *tf,
|
||||||
|
target_addr dest, const void *src, size_t len);
|
||||||
|
|
||||||
struct lpc_flash *lpc_add_flash(target *t, target_addr addr, size_t length)
|
struct lpc_flash *lpc_add_flash(target *t, target_addr addr, size_t length)
|
||||||
{
|
{
|
||||||
@ -109,11 +148,17 @@ enum iap_status lpc_iap_call(struct lpc_flash *f, void *result, enum iap_cmd cmd
|
|||||||
if (result != NULL)
|
if (result != NULL)
|
||||||
memcpy(result, param.result, sizeof(param.result));
|
memcpy(result, param.result, sizeof(param.result));
|
||||||
|
|
||||||
|
#if defined(ENABLE_DEBUG)
|
||||||
if (param.status != IAP_STATUS_CMD_SUCCESS) {
|
if (param.status != IAP_STATUS_CMD_SUCCESS) {
|
||||||
DEBUG_WARN("IAP failure code %d for cmd %d\n",
|
if (param.status > (sizeof(iap_error) / sizeof(char*)))
|
||||||
(enum iap_status)param.status, cmd);
|
DEBUG_WARN("IAP cmd %d : %d\n", cmd, param.status);
|
||||||
|
else
|
||||||
|
DEBUG_WARN("IAP cmd %d : %s\n", cmd, iap_error[param.status]);
|
||||||
|
DEBUG_WARN("return parameters: %08" PRIx32 " %08" PRIx32 " %08" PRIx32
|
||||||
|
" %08" PRIx32 "\n", param.result[0],
|
||||||
|
param.result[1], param.result[2], param.result[3]);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return param.status;
|
return param.status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,43 +167,80 @@ static uint8_t lpc_sector_for_addr(struct lpc_flash *f, uint32_t addr)
|
|||||||
return f->base_sector + (addr - f->f.start) / f->f.blocksize;
|
return f->base_sector + (addr - f->f.start) / f->f.blocksize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define LPX80X_SECTOR_SIZE 0x400
|
||||||
|
#define LPX80X_PAGE_SIZE 0x40
|
||||||
|
|
||||||
int lpc_flash_erase(struct target_flash *tf, target_addr addr, size_t len)
|
int lpc_flash_erase(struct target_flash *tf, target_addr addr, size_t len)
|
||||||
{
|
{
|
||||||
struct lpc_flash *f = (struct lpc_flash *)tf;
|
struct lpc_flash *f = (struct lpc_flash *)tf;
|
||||||
uint32_t start = lpc_sector_for_addr(f, addr);
|
uint32_t start = lpc_sector_for_addr(f, addr);
|
||||||
uint32_t end = lpc_sector_for_addr(f, addr + len - 1);
|
uint32_t end = lpc_sector_for_addr(f, addr + len - 1);
|
||||||
|
uint32_t last_full_sector = end;
|
||||||
|
|
||||||
if (lpc_iap_call(f, NULL, IAP_CMD_PREPARE, start, end, f->bank))
|
if (lpc_iap_call(f, NULL, IAP_CMD_PREPARE, start, end, f->bank))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* and now erase them */
|
/* Only LPC80x has reserved pages!*/
|
||||||
if (lpc_iap_call(f, NULL, IAP_CMD_ERASE, start, end, CPU_CLK_KHZ, f->bank))
|
if (f->reserved_pages && ((addr + len) >= tf->length - 0x400) ) {
|
||||||
return -2;
|
last_full_sector -= 1;
|
||||||
|
}
|
||||||
|
if (start >= last_full_sector) {
|
||||||
|
/* Sector erase */
|
||||||
|
if (lpc_iap_call(f, NULL, IAP_CMD_ERASE, start, last_full_sector, CPU_CLK_KHZ, f->bank))
|
||||||
|
return -2;
|
||||||
|
|
||||||
/* check erase ok */
|
/* check erase ok */
|
||||||
if (lpc_iap_call(f, NULL, IAP_CMD_BLANKCHECK, start, end, f->bank))
|
if (lpc_iap_call(f, NULL, IAP_CMD_BLANKCHECK, start, last_full_sector, f->bank))
|
||||||
return -3;
|
return -3;
|
||||||
|
}
|
||||||
|
if (last_full_sector != end) {
|
||||||
|
uint32_t page_start = (addr + len - LPX80X_SECTOR_SIZE) / LPX80X_PAGE_SIZE;
|
||||||
|
uint32_t page_end = page_start + LPX80X_SECTOR_SIZE/LPX80X_PAGE_SIZE - 1 - f->reserved_pages;
|
||||||
|
if (lpc_iap_call(f, NULL, IAP_CMD_PREPARE, end, end, f->bank))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (lpc_iap_call(f, NULL, IAP_CMD_ERASE_PAGE, page_start, page_end, CPU_CLK_KHZ, f->bank))
|
||||||
|
return -2;
|
||||||
|
/* Blank check omitted!*/
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lpc_flash_write(struct target_flash *tf,
|
static int lpc_flash_write(struct target_flash *tf,
|
||||||
target_addr dest, const void *src, size_t len)
|
target_addr dest, const void *src, size_t len)
|
||||||
{
|
{
|
||||||
struct lpc_flash *f = (struct lpc_flash *)tf;
|
struct lpc_flash *f = (struct lpc_flash *)tf;
|
||||||
/* prepare... */
|
/* prepare... */
|
||||||
uint32_t sector = lpc_sector_for_addr(f, dest);
|
uint32_t sector = lpc_sector_for_addr(f, dest);
|
||||||
if (lpc_iap_call(f, NULL, IAP_CMD_PREPARE, sector, sector, f->bank))
|
if (lpc_iap_call(f, NULL, IAP_CMD_PREPARE, sector, sector, f->bank)) {
|
||||||
|
DEBUG_WARN("Prepare failed\n");
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
/* Write payload to target ram */
|
|
||||||
uint32_t bufaddr = ALIGN(f->iap_ram + sizeof(struct flash_param), 4);
|
uint32_t bufaddr = ALIGN(f->iap_ram + sizeof(struct flash_param), 4);
|
||||||
target_mem_write(f->f.t, bufaddr, src, len);
|
target_mem_write(f->f.t, bufaddr, src, len);
|
||||||
|
/* Only LPC80x has reserved pages!*/
|
||||||
/* set the destination address and program */
|
if ((!f->reserved_pages) || ((dest + len) <= (tf->length - len))) {
|
||||||
if (lpc_iap_call(f, NULL, IAP_CMD_PROGRAM, dest, bufaddr, len, CPU_CLK_KHZ))
|
/* Write payload to target ram */
|
||||||
return -2;
|
/* set the destination address and program */
|
||||||
|
if (lpc_iap_call(f, NULL, IAP_CMD_PROGRAM, dest, bufaddr, len, CPU_CLK_KHZ))
|
||||||
|
return -2;
|
||||||
|
} else {
|
||||||
|
/* On LPC80x, write top sector in pages.
|
||||||
|
* Silently ignore write to the 2 reserved pages at top!*/
|
||||||
|
len -= 0x40 * f->reserved_pages;
|
||||||
|
while (len) {
|
||||||
|
if (lpc_iap_call(f, NULL, IAP_CMD_PREPARE, sector, sector, f->bank)) {
|
||||||
|
DEBUG_WARN("Prepare failed\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/* set the destination address and program */
|
||||||
|
if (lpc_iap_call(f, NULL, IAP_CMD_PROGRAM, dest, bufaddr, LPX80X_PAGE_SIZE, CPU_CLK_KHZ))
|
||||||
|
return -2;
|
||||||
|
dest += LPX80X_PAGE_SIZE;
|
||||||
|
bufaddr += LPX80X_PAGE_SIZE;
|
||||||
|
len -= LPX80X_PAGE_SIZE;
|
||||||
|
}
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,14 +21,23 @@
|
|||||||
#define __LPC_COMMON_H
|
#define __LPC_COMMON_H
|
||||||
|
|
||||||
enum iap_cmd {
|
enum iap_cmd {
|
||||||
|
IAP_CMD_READ_FACTORY_SETTINGS = 40,
|
||||||
IAP_CMD_INIT = 49,
|
IAP_CMD_INIT = 49,
|
||||||
IAP_CMD_PREPARE = 50,
|
IAP_CMD_PREPARE = 50,
|
||||||
IAP_CMD_PROGRAM = 51,
|
IAP_CMD_PROGRAM = 51,
|
||||||
IAP_CMD_ERASE = 52,
|
IAP_CMD_ERASE = 52,
|
||||||
IAP_CMD_BLANKCHECK = 53,
|
IAP_CMD_BLANKCHECK = 53,
|
||||||
IAP_CMD_PARTID = 54,
|
IAP_CMD_PARTID = 54,
|
||||||
|
IAP_CMD_READ_BOOTROM_VERSION = 55,
|
||||||
|
IAP_CMD_COMPARE = 56,
|
||||||
|
IAP_CMD_REINVOKE_ISP = 57,
|
||||||
IAP_CMD_READUID = 58,
|
IAP_CMD_READUID = 58,
|
||||||
|
IAP_CMD_ERASE_PAGE = 59,
|
||||||
IAP_CMD_SET_ACTIVE_BANK = 60,
|
IAP_CMD_SET_ACTIVE_BANK = 60,
|
||||||
|
IAP_CMD_READ_SIGNATURE = 70,
|
||||||
|
IAP_CMD_EXTENDED_READ_SIGNATURE = 73,
|
||||||
|
IAP_CMD_READ_EEPROM_PAGE = 80,
|
||||||
|
IAP_CMD_WRITE_EEPROM_PAGE = 81,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum iap_status {
|
enum iap_status {
|
||||||
@ -44,6 +53,16 @@ enum iap_status {
|
|||||||
IAP_STATUS_SECTOR_NOT_PREPARED = 9,
|
IAP_STATUS_SECTOR_NOT_PREPARED = 9,
|
||||||
IAP_STATUS_COMPARE_ERROR = 10,
|
IAP_STATUS_COMPARE_ERROR = 10,
|
||||||
IAP_STATUS_BUSY = 11,
|
IAP_STATUS_BUSY = 11,
|
||||||
|
IAP_STATUS_MISSING_PARAMETERS = 12,
|
||||||
|
IAP_STATUS_UNALIGNED_ADDRESS = 13,
|
||||||
|
IAP_STATUS_ADDRESS_NOT_MAPPED = 14,
|
||||||
|
IAP_STATUS_FRO_NO_POWER = 23,
|
||||||
|
IAP_STATUS_FLASH_NO_POWER = 24,
|
||||||
|
IAP_STATUS_NO_CLOCK = 27,
|
||||||
|
IAP_STATUS_REINVOKE_CFG_ERR = 28,
|
||||||
|
IAP_STATUS_NO_VALID_IMAGE = 29,
|
||||||
|
IAP_STATUS_FLASH_ERASE = 32,
|
||||||
|
IAP_STATUS_INVALID_PAGE = 33,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* CPU Frequency */
|
/* CPU Frequency */
|
||||||
@ -53,6 +72,7 @@ struct lpc_flash {
|
|||||||
struct target_flash f;
|
struct target_flash f;
|
||||||
uint8_t base_sector;
|
uint8_t base_sector;
|
||||||
uint8_t bank;
|
uint8_t bank;
|
||||||
|
uint8_t reserved_pages;
|
||||||
/* Info filled in by specific driver */
|
/* Info filled in by specific driver */
|
||||||
void (*wdt_kick)(target *t);
|
void (*wdt_kick)(target *t);
|
||||||
uint32_t iap_entry;
|
uint32_t iap_entry;
|
||||||
@ -63,8 +83,6 @@ struct lpc_flash {
|
|||||||
struct lpc_flash *lpc_add_flash(target *t, target_addr addr, size_t length);
|
struct lpc_flash *lpc_add_flash(target *t, target_addr addr, size_t length);
|
||||||
enum iap_status lpc_iap_call(struct lpc_flash *f, void *result, enum iap_cmd cmd, ...);
|
enum iap_status lpc_iap_call(struct lpc_flash *f, void *result, enum iap_cmd cmd, ...);
|
||||||
int lpc_flash_erase(struct target_flash *f, target_addr addr, size_t len);
|
int lpc_flash_erase(struct target_flash *f, target_addr addr, size_t len);
|
||||||
int lpc_flash_write(struct target_flash *f,
|
|
||||||
target_addr dest, const void *src, size_t len);
|
|
||||||
int lpc_flash_write_magic_vect(struct target_flash *f,
|
int lpc_flash_write_magic_vect(struct target_flash *f,
|
||||||
target_addr dest, const void *src, size_t len);
|
target_addr dest, const void *src, size_t len);
|
||||||
|
|
||||||
|
@ -59,6 +59,7 @@ struct rp_priv_s {
|
|||||||
uint16_t _flash_enter_cmd_xip;
|
uint16_t _flash_enter_cmd_xip;
|
||||||
uint16_t reset_usb_boot;
|
uint16_t reset_usb_boot;
|
||||||
bool is_prepared;
|
bool is_prepared;
|
||||||
|
bool is_monitor;
|
||||||
uint32_t regs[0x20];/* Register playground*/
|
uint32_t regs[0x20];/* Register playground*/
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -112,7 +113,7 @@ static bool rp2040_fill_table(struct rp_priv_s *priv, uint16_t *table, int max)
|
|||||||
/* RP ROM functions calls
|
/* RP ROM functions calls
|
||||||
*
|
*
|
||||||
* timout == 0: Do not wait for poll, use for reset_usb_boot()
|
* timout == 0: Do not wait for poll, use for reset_usb_boot()
|
||||||
* timeout > 400 (ms) : display spinner
|
* timeout > 500 (ms) : display spinner
|
||||||
*/
|
*/
|
||||||
static bool rp_rom_call(target *t, uint32_t *regs, uint32_t cmd,
|
static bool rp_rom_call(target *t, uint32_t *regs, uint32_t cmd,
|
||||||
uint32_t timeout)
|
uint32_t timeout)
|
||||||
@ -131,14 +132,23 @@ static bool rp_rom_call(target *t, uint32_t *regs, uint32_t cmd,
|
|||||||
target_halt_resume(t, false);
|
target_halt_resume(t, false);
|
||||||
if (!timeout)
|
if (!timeout)
|
||||||
return false;
|
return false;
|
||||||
DEBUG_INFO("Call cmd %04x\n", cmd);
|
DEBUG_INFO("Call cmd %04" PRIx32 "\n", cmd);
|
||||||
platform_timeout to;
|
platform_timeout to;
|
||||||
platform_timeout_set(&to, timeout);
|
platform_timeout_set(&to, timeout);
|
||||||
|
platform_timeout to_spinner;
|
||||||
|
if (timeout > 500)
|
||||||
|
platform_timeout_set(&to_spinner, 500);
|
||||||
|
else
|
||||||
|
/* never trigger if timeout is short */
|
||||||
|
platform_timeout_set(&to_spinner, timeout + 1);
|
||||||
do {
|
do {
|
||||||
if (timeout > 400)
|
if (platform_timeout_is_expired(&to_spinner)) {
|
||||||
tc_printf(t, "\b%c", spinner[spinindex++ % 4]);
|
if (ps->is_monitor)
|
||||||
|
tc_printf(t, "\b%c", spinner[spinindex++ % 4]);
|
||||||
|
platform_timeout_set(&to_spinner, 500);
|
||||||
|
}
|
||||||
if (platform_timeout_is_expired(&to)) {
|
if (platform_timeout_is_expired(&to)) {
|
||||||
DEBUG_WARN("RP Run timout %d ms reached: ", timeout);
|
DEBUG_WARN("RP Run timout %d ms reached: ", (int)timeout);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while (!target_halt_poll(t, NULL));
|
} while (!target_halt_poll(t, NULL));
|
||||||
@ -146,7 +156,7 @@ static bool rp_rom_call(target *t, uint32_t *regs, uint32_t cmd,
|
|||||||
target_regs_read(t, dbg_regs);
|
target_regs_read(t, dbg_regs);
|
||||||
bool ret = ((dbg_regs[REG_PC] &~1) != (ps->_debug_trampoline_end & ~1));
|
bool ret = ((dbg_regs[REG_PC] &~1) != (ps->_debug_trampoline_end & ~1));
|
||||||
if (ret) {
|
if (ret) {
|
||||||
DEBUG_WARN("rp_rom_call cmd %04x failed, PC %08" PRIx32 "\n",
|
DEBUG_WARN("rp_rom_call cmd %04" PRIx32 " failed, PC %08" PRIx32 "\n",
|
||||||
cmd, dbg_regs[REG_PC]);
|
cmd, dbg_regs[REG_PC]);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -156,6 +166,7 @@ static void rp_flash_prepare(target *t)
|
|||||||
{
|
{
|
||||||
struct rp_priv_s *ps = (struct rp_priv_s*)t->target_storage;
|
struct rp_priv_s *ps = (struct rp_priv_s*)t->target_storage;
|
||||||
if (!ps->is_prepared) {
|
if (!ps->is_prepared) {
|
||||||
|
DEBUG_INFO("rp_flash_prepare\n");
|
||||||
/* connect*/
|
/* connect*/
|
||||||
rp_rom_call(t, ps->regs, ps->_connect_internal_flash,100);
|
rp_rom_call(t, ps->regs, ps->_connect_internal_flash,100);
|
||||||
/* exit_xip */
|
/* exit_xip */
|
||||||
@ -164,6 +175,19 @@ static void rp_flash_prepare(target *t)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void rp_flash_resume(target *t)
|
||||||
|
{
|
||||||
|
struct rp_priv_s *ps = (struct rp_priv_s*)t->target_storage;
|
||||||
|
if (ps->is_prepared) {
|
||||||
|
DEBUG_INFO("rp_flash_resume\n");
|
||||||
|
/* flush */
|
||||||
|
rp_rom_call(t, ps->regs, ps->_flash_flush_cache,100);
|
||||||
|
/* enter_cmd_xip */
|
||||||
|
rp_rom_call(t, ps->regs, ps->_flash_enter_cmd_xip, 100);
|
||||||
|
ps->is_prepared = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* FLASHCMD_SECTOR_ERASE 45/ 400 ms
|
/* FLASHCMD_SECTOR_ERASE 45/ 400 ms
|
||||||
* 32k block erase 120/ 1600 ms
|
* 32k block erase 120/ 1600 ms
|
||||||
* 64k block erase 150/ 2000 ms
|
* 64k block erase 150/ 2000 ms
|
||||||
@ -181,7 +205,7 @@ static int rp_flash_erase(struct target_flash *f, target_addr addr,
|
|||||||
DEBUG_WARN("Unaligned len\n");
|
DEBUG_WARN("Unaligned len\n");
|
||||||
len = (len + 0xfff) & ~0xfff;
|
len = (len + 0xfff) & ~0xfff;
|
||||||
}
|
}
|
||||||
DEBUG_INFO("Erase addr %08" PRIx32 " len 0x%" PRIx32 "\n", addr, len);
|
DEBUG_INFO("Erase addr %08" PRIx32 " len 0x%" PRIx32 "\n", addr, (uint32_t)len);
|
||||||
target *t = f->t;
|
target *t = f->t;
|
||||||
rp_flash_prepare(t);
|
rp_flash_prepare(t);
|
||||||
struct rp_priv_s *ps = (struct rp_priv_s*)t->target_storage;
|
struct rp_priv_s *ps = (struct rp_priv_s*)t->target_storage;
|
||||||
@ -195,6 +219,7 @@ static int rp_flash_erase(struct target_flash *f, target_addr addr,
|
|||||||
addr -= XIP_FLASH_START;
|
addr -= XIP_FLASH_START;
|
||||||
if (len > MAX_FLASH)
|
if (len > MAX_FLASH)
|
||||||
len = MAX_FLASH;
|
len = MAX_FLASH;
|
||||||
|
bool ret = 0;
|
||||||
while (len) {
|
while (len) {
|
||||||
ps->regs[0] = addr;
|
ps->regs[0] = addr;
|
||||||
ps->regs[2] = -1;
|
ps->regs[2] = -1;
|
||||||
@ -202,14 +227,14 @@ static int rp_flash_erase(struct target_flash *f, target_addr addr,
|
|||||||
ps->regs[1] = MAX_FLASH;
|
ps->regs[1] = MAX_FLASH;
|
||||||
ps->regs[3] = FLASHCMD_CHIP_ERASE;
|
ps->regs[3] = FLASHCMD_CHIP_ERASE;
|
||||||
DEBUG_WARN("BULK_ERASE\n");
|
DEBUG_WARN("BULK_ERASE\n");
|
||||||
rp_rom_call(t, ps->regs, ps->_flash_range_erase, 25100);
|
ret = rp_rom_call(t, ps->regs, ps->_flash_range_erase, 25100);
|
||||||
len = 0;
|
len = 0;
|
||||||
} else if (len >= (64 * 1024)) {
|
} else if (len >= (64 * 1024)) {
|
||||||
uint32_t chunk = len & ~((1 << 16) - 1);
|
uint32_t chunk = len & ~((1 << 16) - 1);
|
||||||
ps->regs[1] = chunk;
|
ps->regs[1] = chunk;
|
||||||
ps->regs[3] = FLASHCMD_BLOCK64K_ERASE;
|
ps->regs[3] = FLASHCMD_BLOCK64K_ERASE;
|
||||||
DEBUG_WARN("64k_ERASE\n");
|
DEBUG_WARN("64k_ERASE\n");
|
||||||
rp_rom_call(t, ps->regs, ps->_flash_range_erase, 2100);
|
ret = rp_rom_call(t, ps->regs, ps->_flash_range_erase, 2100);
|
||||||
len -= chunk ;
|
len -= chunk ;
|
||||||
addr += chunk;
|
addr += chunk;
|
||||||
} else if (len >= (32 * 1024)) {
|
} else if (len >= (32 * 1024)) {
|
||||||
@ -217,7 +242,7 @@ static int rp_flash_erase(struct target_flash *f, target_addr addr,
|
|||||||
ps->regs[1] = chunk;
|
ps->regs[1] = chunk;
|
||||||
ps->regs[3] = FLASHCMD_BLOCK32K_ERASE;
|
ps->regs[3] = FLASHCMD_BLOCK32K_ERASE;
|
||||||
DEBUG_WARN("32k_ERASE\n");
|
DEBUG_WARN("32k_ERASE\n");
|
||||||
rp_rom_call(t, ps->regs, ps->_flash_range_erase, 1700);
|
ret = rp_rom_call(t, ps->regs, ps->_flash_range_erase, 1700);
|
||||||
len -= chunk;
|
len -= chunk;
|
||||||
addr += chunk;
|
addr += chunk;
|
||||||
} else {
|
} else {
|
||||||
@ -225,18 +250,23 @@ static int rp_flash_erase(struct target_flash *f, target_addr addr,
|
|||||||
ps->regs[2] = MAX_FLASH;
|
ps->regs[2] = MAX_FLASH;
|
||||||
ps->regs[3] = FLASHCMD_SECTOR_ERASE;
|
ps->regs[3] = FLASHCMD_SECTOR_ERASE;
|
||||||
DEBUG_WARN("Sector_ERASE\n");
|
DEBUG_WARN("Sector_ERASE\n");
|
||||||
rp_rom_call(t, ps->regs, ps->_flash_range_erase, 410);
|
ret = rp_rom_call(t, ps->regs, ps->_flash_range_erase, 410);
|
||||||
len = 0;
|
len = 0;
|
||||||
}
|
}
|
||||||
|
if (ret) {
|
||||||
|
DEBUG_WARN("Erase failed!\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
DEBUG_INFO("\nErase done!\n");
|
rp_flash_resume(t);
|
||||||
return 0;
|
DEBUG_INFO("Erase done!\n");
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int rp_flash_write(struct target_flash *f,
|
int rp_flash_write(struct target_flash *f,
|
||||||
target_addr dest, const void *src, size_t len)
|
target_addr dest, const void *src, size_t len)
|
||||||
{
|
{
|
||||||
DEBUG_INFO("RP Write %08" PRIx32 " len 0x%" PRIx32 "\n", dest, len);
|
DEBUG_INFO("RP Write %08" PRIx32 " len 0x%" PRIx32 "\n", dest, (uint32_t)len);
|
||||||
if ((dest & 0xff) || (len & 0xff)) {
|
if ((dest & 0xff) || (len & 0xff)) {
|
||||||
DEBUG_WARN("Unaligned erase\n");
|
DEBUG_WARN("Unaligned erase\n");
|
||||||
return -1;
|
return -1;
|
||||||
@ -246,6 +276,7 @@ int rp_flash_write(struct target_flash *f,
|
|||||||
struct rp_priv_s *ps = (struct rp_priv_s*)t->target_storage;
|
struct rp_priv_s *ps = (struct rp_priv_s*)t->target_storage;
|
||||||
/* Write payload to target ram */
|
/* Write payload to target ram */
|
||||||
dest -= XIP_FLASH_START;
|
dest -= XIP_FLASH_START;
|
||||||
|
bool ret = 0;
|
||||||
#define MAX_WRITE_CHUNK 0x1000
|
#define MAX_WRITE_CHUNK 0x1000
|
||||||
while (len) {
|
while (len) {
|
||||||
uint32_t chunksize = (len <= MAX_WRITE_CHUNK) ? len : MAX_WRITE_CHUNK;
|
uint32_t chunksize = (len <= MAX_WRITE_CHUNK) ? len : MAX_WRITE_CHUNK;
|
||||||
@ -254,13 +285,23 @@ int rp_flash_write(struct target_flash *f,
|
|||||||
ps->regs[0] = dest;
|
ps->regs[0] = dest;
|
||||||
ps->regs[1] = SRAM_START;
|
ps->regs[1] = SRAM_START;
|
||||||
ps->regs[2] = chunksize;
|
ps->regs[2] = chunksize;
|
||||||
rp_rom_call(t, ps->regs, ps->flash_range_program,
|
/* Loading takes 3 ms per 256 byte page
|
||||||
(3 * chunksize) >> 8); /* 3 ms per 256 byte page */
|
* however it takes much longer if the XOSC is not enabled
|
||||||
|
* so lets give ourselves a little bit more time (x10)
|
||||||
|
*/
|
||||||
|
ret |= rp_rom_call(t, ps->regs, ps->flash_range_program,
|
||||||
|
(3 * chunksize * 10) >> 8);
|
||||||
|
if (ret) {
|
||||||
|
DEBUG_WARN("Write failed!\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
len -= chunksize;
|
len -= chunksize;
|
||||||
src += chunksize;
|
src += chunksize;
|
||||||
dest += chunksize;
|
dest += chunksize;
|
||||||
}
|
}
|
||||||
return 0;
|
rp_flash_resume(t);
|
||||||
|
DEBUG_INFO("Write done!\n");
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool rp_cmd_reset_usb_boot(target *t, int argc, const char *argv[])
|
static bool rp_cmd_reset_usb_boot(target *t, int argc, const char *argv[])
|
||||||
@ -284,7 +325,11 @@ static bool rp_cmd_erase_mass(target *t, int argc, const char *argv[])
|
|||||||
(void) argv;
|
(void) argv;
|
||||||
struct target_flash f;
|
struct target_flash f;
|
||||||
f.t = t;
|
f.t = t;
|
||||||
return (rp_flash_erase(&f, XIP_FLASH_START, MAX_FLASH)) ? false: true;
|
struct rp_priv_s *ps = (struct rp_priv_s*)t->target_storage;
|
||||||
|
ps->is_monitor = true;
|
||||||
|
bool res = (rp_flash_erase(&f, XIP_FLASH_START, MAX_FLASH)) ? false: true;
|
||||||
|
ps->is_monitor = false;
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct command_s rp_cmd_list[] = {
|
const struct command_s rp_cmd_list[] = {
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "general.h"
|
#include "general.h"
|
||||||
#include "target.h"
|
|
||||||
#include "target_internal.h"
|
#include "target_internal.h"
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
@ -342,7 +341,6 @@ void target_detach(target *t)
|
|||||||
t->detach(t);
|
t->detach(t);
|
||||||
t->attached = false;
|
t->attached = false;
|
||||||
#if PC_HOSTED == 1
|
#if PC_HOSTED == 1
|
||||||
# include "platform.h"
|
|
||||||
platform_buffer_flush();
|
platform_buffer_flush();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user