diff --git a/scripts/stm32_mem.py b/scripts/stm32_mem.py index 690657e0..51a8537b 100755 --- a/scripts/stm32_mem.py +++ b/scripts/stm32_mem.py @@ -184,7 +184,7 @@ if __name__ == "__main__": print("Invoking DFU Device") timeout = 0 while True : - sleep(0.5) + sleep(1) timeout = timeout + 0.5 dfudev = stm32_scan(args, True) if dfudev: break diff --git a/src/command.c b/src/command.c index 979ae82a..3a00a25d 100644 --- a/src/command.c +++ b/src/command.c @@ -38,8 +38,6 @@ # include "traceswo.h" #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_serial(target *t, int argc, char **argv); static bool cmd_help(target *t, int argc, char **argv); diff --git a/src/platforms/common/cdcacm.c b/src/platforms/common/cdcacm.c index 2d7376af..0c9986ad 100644 --- a/src/platforms/common/cdcacm.c +++ b/src/platforms/common/cdcacm.c @@ -41,7 +41,6 @@ #include #include #include -#include #define DFU_IF_NO 4 diff --git a/src/platforms/hosted/Makefile.inc b/src/platforms/hosted/Makefile.inc index b73f6d75..cd0ce561 100644 --- a/src/platforms/hosted/Makefile.inc +++ b/src/platforms/hosted/Makefile.inc @@ -12,8 +12,9 @@ CFLAGS += -DHOSTED_BMP_ONLY=$(HOSTED_BMP_ONLY) ifneq (, $(findstring linux, $(SYS))) SRC += serial_unix.c +HIDAPILIB = hidapi-libusb ifeq ($(ASAN), 1) -CFLAGS += -fsanitize=address +CFLAGS += -fsanitize=address -Wno-format-truncation LDFLAGS += -lasan endif else ifneq (, $(findstring mingw, $(SYS))) @@ -36,6 +37,7 @@ SRC += serial_unix.c LDFLAGS += -lhidapi LDFLAGS += -framework CoreFoundation CFLAGS += -Ihidapi/hidapi +HIDAPILIB = hidapi endif ifneq ($(HOSTED_BMP_ONLY), 1) @@ -51,8 +53,8 @@ ifneq ($(HOSTED_BMP_ONLY), 1) ifneq (, $(findstring mingw, $(SYS))) SRC += hid.c else - CFLAGS += $(shell pkg-config --cflags hidapi-libusb) - LDFLAGS += $(shell pkg-config --libs hidapi-libusb) + CFLAGS += $(shell pkg-config --cflags $(HIDAPILIB)) + LDFLAGS += $(shell pkg-config --libs $(HIDAPILIB)) endif endif diff --git a/src/platforms/hosted/bmp_libusb.c b/src/platforms/hosted/bmp_libusb.c index 743f25b1..8739710d 100644 --- a/src/platforms/hosted/bmp_libusb.c +++ b/src/platforms/hosted/bmp_libusb.c @@ -201,9 +201,11 @@ int find_debuggers(BMP_CL_OPTIONS_t *cl_opts,bmp_info_t *info) } if (res < 0) serial[0] = 0; + manufacturer[0] = 0; res = libusb_get_string_descriptor_ascii( handle, desc.iManufacturer, (uint8_t*)manufacturer, sizeof(manufacturer)); + product[0] = 0; res = libusb_get_string_descriptor_ascii( handle, desc.iProduct, (uint8_t*)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.idProduct == PRODUCT_ID_BMP) { type = BMP_TYPE_BMP; - } else if (desc.idProduct == PRODUCT_ID_BMP_BL) { - DEBUG_WARN("BMP in botloader mode found. Restart or reflash!\n"); + } else { + if (desc.idProduct == PRODUCT_ID_BMP_BL) + DEBUG_WARN("BMP in botloader mode found. Restart or reflash!\n"); continue; } } 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)) continue; /* VID/PID do not match*/ 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*/ else found = true; } if (cable->description) { - if (strcmp(cable->description, product)) + if (strncmp(cable->description, product, strlen(cable->description))) continue; /* discriptions do not match*/ else found = true; diff --git a/src/platforms/hosted/bmp_remote.c b/src/platforms/hosted/bmp_remote.c index b8dc1d2e..1ca68621 100644 --- a/src/platforms/hosted/bmp_remote.c +++ b/src/platforms/hosted/bmp_remote.c @@ -22,7 +22,6 @@ #include "general.h" #include "gdb_if.h" #include "version.h" -#include "platform.h" #include "remote.h" #include "target.h" #include "bmp_remote.h" @@ -33,7 +32,6 @@ #include #include #include -#include #include "adiv5.h" diff --git a/src/platforms/hosted/bmp_serial.c b/src/platforms/hosted/bmp_serial.c index a7baa77c..c04807b9 100644 --- a/src/platforms/hosted/bmp_serial.c +++ b/src/platforms/hosted/bmp_serial.c @@ -19,18 +19,18 @@ /* Find all known serial connected debuggers */ +#include "general.h" #include #include -#include -#include "general.h" -#include "platform.h" #include "bmp_hosted.h" #include "version.h" void bmp_ident(bmp_info_t *info) { - (void) info; + if (!info) + return; 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;}; @@ -154,6 +154,10 @@ print_probes_info: } #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 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"); return -1; } - char *p = strchr(name, '_'); - if (!p) { - DEBUG_WARN("type not found\n"); - return -1; + char *p = name; + char *delims[4] = {0,0,0,0}; + int underscores = 0; + 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); - type[p - name] = 0; - name = p; - while (*name != 'v') - name++; - if (!*name) { - DEBUG_WARN("Unexpected end after type\n"); - return -1; + if (underscores == 0) { /* Old BMP native */ + int res; + res = sscanf(name, "%8s-if00", serial); + if (res != 1) + return -1; + strcpy(type, "Native"); + strcpy(version, "Unknown"); + } 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; } @@ -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)) { /* With serial number given and partial match, we are done!*/ strncpy(info->serial, serial, sizeof(info->serial)); - strncpy(info->manufacturer, "BMP", sizeof(info->manufacturer)); - strncpy(info->product, type, sizeof(info->product)); + int res = snprintf(info->manufacturer, sizeof(info->manufacturer), "Black Magic Probe (%s)", type); + if (res) + DEBUG_WARN("Overflow\n"); strncpy(info->version, version, sizeof(info->version)); found_bmps = 1; 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)); found_bmps = 1; strncpy(info->serial, serial, sizeof(info->serial)); - strncpy(info->manufacturer, "BMP", sizeof(info->manufacturer)); - strncpy(info->product, type, sizeof(info->product)); + snprintf(info->manufacturer, sizeof(info->manufacturer), "Black Magic Probe (%s)", type); strncpy(info->version, version, sizeof(info->version)); break; } else if (found_bmps > 0) { diff --git a/src/platforms/hosted/cmsis_dap.h b/src/platforms/hosted/cmsis_dap.h index d23726db..a060d585 100644 --- a/src/platforms/hosted/cmsis_dap.h +++ b/src/platforms/hosted/cmsis_dap.h @@ -44,10 +44,10 @@ uint32_t dap_swj_clock(uint32_t clock) {return 0;} void dap_exit_function(void) {}; void dap_adiv5_dp_defaults(ADIv5_DP_t *dp) {}; 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;} void dap_swd_configure(uint8_t cfg) {}; -## pragma GCC diagnostic pop +# pragma GCC diagnostic pop #endif diff --git a/src/platforms/hosted/dap.c b/src/platforms/hosted/dap.c index 9d93ab7c..5acc03e5 100644 --- a/src/platforms/hosted/dap.c +++ b/src/platforms/hosted/dap.c @@ -32,7 +32,6 @@ /*- Includes ----------------------------------------------------------------*/ #include -#include #include "dap.h" #include "jtag_scan.h" diff --git a/src/platforms/hosted/ftdi_bmp.c b/src/platforms/hosted/ftdi_bmp.c index 77cb369a..f05a86b7 100644 --- a/src/platforms/hosted/ftdi_bmp.c +++ b/src/platforms/hosted/ftdi_bmp.c @@ -20,7 +20,6 @@ */ #include "general.h" #include "gdb_if.h" -#include "platform.h" #include "target.h" #include @@ -270,7 +269,7 @@ int ftdi_bmp_init(BMP_CL_OPTIONS_t *cl_opts, bmp_info_t *info) int err; cable_desc_t *cable = &cable_desc[0]; 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; } @@ -282,7 +281,7 @@ int ftdi_bmp_init(BMP_CL_OPTIONS_t *cl_opts, bmp_info_t *info) active_cable = cable; memcpy(&active_state, &active_cable->init, sizeof(data_desc_t)); /* 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.*/ if (cl_opts->external_resistor_swd && (active_cable->mpsse_swd_read.set_data_low == 0) && diff --git a/src/platforms/hosted/jlink_jtagtap.c b/src/platforms/hosted/jlink_jtagtap.c index 4b20e146..17dd3a29 100644 --- a/src/platforms/hosted/jlink_jtagtap.c +++ b/src/platforms/hosted/jlink_jtagtap.c @@ -21,13 +21,10 @@ * */ -#include +#include "general.h" #include -#include - #include -#include "general.h" #include "exception.h" #include "jlink.h" diff --git a/src/platforms/hosted/jtagtap.c b/src/platforms/hosted/jtagtap.c deleted file mode 100644 index e69de29b..00000000 diff --git a/src/platforms/hosted/libftdi_jtagtap.c b/src/platforms/hosted/libftdi_jtagtap.c index 905faaf9..9443df53 100644 --- a/src/platforms/hosted/libftdi_jtagtap.c +++ b/src/platforms/hosted/libftdi_jtagtap.c @@ -22,15 +22,12 @@ * */ -#include +#include "general.h" #include -#include #include #include -#include "platform.h" #include "ftdi_bmp.h" -#include "general.h" extern cable_desc_t *active_cable; extern struct ftdi_context *ftdic; diff --git a/src/platforms/hosted/libftdi_swdptap.c b/src/platforms/hosted/libftdi_swdptap.c index 13a981bc..4878437f 100644 --- a/src/platforms/hosted/libftdi_swdptap.c +++ b/src/platforms/hosted/libftdi_swdptap.c @@ -21,12 +21,10 @@ * Speed is sensible. */ -#include +#include "general.h" #include -#include "general.h" #include -#include "platform.h" #include "ftdi_bmp.h" enum swdio_status{ diff --git a/src/platforms/hosted/remote_jtagtap.c b/src/platforms/hosted/remote_jtagtap.c index d98663b5..601a3e90 100644 --- a/src/platforms/hosted/remote_jtagtap.c +++ b/src/platforms/hosted/remote_jtagtap.c @@ -26,13 +26,11 @@ * Should share interface with swdptap.c or at least clean up... */ -#include +#include "general.h" #include -#include #include -#include "general.h" #include "remote.h" #include "jtagtap.h" #include "bmp_remote.h" diff --git a/src/platforms/hosted/swdptap.c b/src/platforms/hosted/swdptap.c deleted file mode 100644 index e69de29b..00000000 diff --git a/src/platforms/pc/cl_utils.c b/src/platforms/pc/cl_utils.c index b67bd9bd..fc34496f 100644 --- a/src/platforms/pc/cl_utils.c +++ b/src/platforms/pc/cl_utils.c @@ -24,12 +24,10 @@ #include "general.h" #include -#include #include #include #include #include "version.h" -#include "target.h" #include "target_internal.h" #include "cortexm.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-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-l\t\t: List available probes\n"); DEBUG_WARN("Probe selection arguments:\n"); DEBUG_WARN("\t-d \"path\"\t: Use serial BMP device at "); #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) 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; if (opt->opt_mode == BMP_MODE_SWJ_TEST) { switch (t->core[0]) { diff --git a/src/platforms/pc/gdb_if.c b/src/platforms/pc/gdb_if.c index 2657d841..2734a7e2 100644 --- a/src/platforms/pc/gdb_if.c +++ b/src/platforms/pc/gdb_if.c @@ -36,13 +36,11 @@ # include #endif -#include +#include "general.h" #include #include -#include #include -#include "general.h" #include "gdb_if.h" 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) { #if defined(_WIN32) || defined(__CYGWIN__) + int iResult; 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 struct sockaddr_in addr; int opt; @@ -67,23 +70,47 @@ int gdb_if_init(void) addr.sin_addr.s_addr = htonl(INADDR_ANY); 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; + } 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); continue; } 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); continue; } 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); continue; } if (listen(gdb_if_serv, 1) == -1) { + DEBUG_WARN("listen closed %d\n",gdb_if_serv); close(gdb_if_serv); continue; } @@ -100,6 +127,7 @@ unsigned char gdb_if_getchar(void) unsigned char ret; int i = 0; #if defined(_WIN32) || defined(__CYGWIN__) + int iResult; unsigned long opt; #else int flags; @@ -108,7 +136,10 @@ unsigned char gdb_if_getchar(void) if(gdb_if_conn <= 0) { #if defined(_WIN32) || defined(__CYGWIN__) 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 flags = fcntl(gdb_if_serv, F_GETFL); fcntl(gdb_if_serv, F_SETFL, flags | O_NONBLOCK); diff --git a/src/platforms/pc/hid.c b/src/platforms/pc/hid.c index 3d0425c5..75fc3099 100755 --- a/src/platforms/pc/hid.c +++ b/src/platforms/pc/hid.c @@ -61,9 +61,7 @@ extern "C" { } /* extern "C" */ #endif -#include -#include - +#include #include "hidapi.h" diff --git a/src/platforms/pc/serial_unix.c b/src/platforms/pc/serial_unix.c index 96e2da92..08f01134 100644 --- a/src/platforms/pc/serial_unix.c +++ b/src/platforms/pc/serial_unix.c @@ -17,16 +17,15 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -#include +#include "general.h" #include +#include #include #include #include #include #include -#include -#include "general.h" #include "remote.h" #include "cl_utils.h" #include "cortexm.h" @@ -60,8 +59,9 @@ static int set_interface_attribs(void) tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls, // enable reading tty.c_cflag &= ~CSTOPB; +#if defined(CRTSCTS) tty.c_cflag &= ~CRTSCTS; - +#endif if (tcsetattr (fd, TCSANOW, &tty) != 0) { DEBUG_WARN("error %d from tcsetattr", errno); return -1; diff --git a/src/platforms/pc/serial_win.c b/src/platforms/pc/serial_win.c index 57f78067..b08e87ea 100644 --- a/src/platforms/pc/serial_win.c +++ b/src/platforms/pc/serial_win.c @@ -17,7 +17,6 @@ * along with this program. If not, see . */ -#include #include "general.h" #include #include "remote.h" diff --git a/src/platforms/pc/utils.c b/src/platforms/pc/utils.c index b74c8ae3..e5de7148 100644 --- a/src/platforms/pc/utils.c +++ b/src/platforms/pc/utils.c @@ -44,7 +44,14 @@ int vasprintf(char **strp, const char *fmt, va_list ap) 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) diff --git a/src/platforms/stm32/gpio.h b/src/platforms/stm32/gpio.h index dad20bb2..5fb75e0e 100644 --- a/src/platforms/stm32/gpio.h +++ b/src/platforms/stm32/gpio.h @@ -39,6 +39,7 @@ static inline void _gpio_set(uint32_t gpioport, uint16_t gpios) { GPIO_BSRR(gpioport) = gpios; #ifdef STM32F4 + /* FIXME: Check if doubling is still needed */ GPIO_BSRR(gpioport) = gpios; #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) { -#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; #else GPIO_BSRR(gpioport) = gpios<<16; - GPIO_BSRR(gpioport) = gpios<<16; #endif } #define gpio_clear _gpio_clear diff --git a/src/platforms/stm32/usbuart.c b/src/platforms/stm32/usbuart.c index 786bbc38..8c04db7b 100644 --- a/src/platforms/stm32/usbuart.c +++ b/src/platforms/stm32/usbuart.c @@ -118,8 +118,14 @@ void usbuart_init(void) USBUSART_CR1 |= USART_CR1_IDLEIE; /* 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_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_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); @@ -136,7 +142,7 @@ void usbuart_init(void) /* Setup USART RX DMA */ 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_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); @@ -393,8 +399,15 @@ void USBUSART_ISR(void) usart_recv(USBUSART); /* 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(); + } nvic_enable_irq(USBUSART_DMA_RX_IRQ); } diff --git a/src/remote.c b/src/remote.c index 955c2f10..691f1e9e 100644 --- a/src/remote.c +++ b/src/remote.c @@ -24,7 +24,6 @@ #include "gdb_packet.h" #include "jtagtap.h" #include "gdb_if.h" -#include "platform.h" #include "version.h" #include "exception.h" #include diff --git a/src/target/adiv5.c b/src/target/adiv5.c index f8e6b58f..38c3c9f9 100644 --- a/src/target/adiv5.c +++ b/src/target/adiv5.c @@ -661,8 +661,8 @@ void adiv5_dp_init(ADIv5_DP_t *dp) return; } DEBUG_INFO("DPIDR 0x%08" PRIx32 " (v%d %srev%d)\n", dp->idcode, - (dp->idcode >> 12) & 0xf, - (dp->idcode & 0x10000) ? "MINDP " : "", dp->idcode >> 28); + (uint8_t)((dp->idcode >> 12) & 0xf), + (dp->idcode & 0x10000) ? "MINDP " : "", (uint16_t)(dp->idcode >> 28)); volatile uint32_t ctrlstat = 0; #if PC_HOSTED == 1 platform_adiv5_dp_defaults(dp); diff --git a/src/target/cortexm.c b/src/target/cortexm.c index 32c262da..82e22b66 100644 --- a/src/target/cortexm.c +++ b/src/target/cortexm.c @@ -33,7 +33,6 @@ #include "target.h" #include "target_internal.h" #include "cortexm.h" -#include "platform.h" #include "command.h" #include "gdb_packet.h" @@ -328,7 +327,7 @@ bool cortexm_probe(ADIv5_AP_t *ap) break; default: 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", @@ -441,6 +440,7 @@ bool cortexm_probe(ADIv5_AP_t *ap) if (ap->ap_partno == 0x4c0) { /* Cortex-M0+ ROM */ if ((ap->dp->targetid & 0xfff) == AP_DESIGNER_RASPBERRY) PROBE(rp_probe); + PROBE(lpc11xx_probe); /* LPC8 */ } else if (ap->ap_partno == 0x4c3) { /* Cortex-M3 ROM */ PROBE(stm32f1_probe); /* Care for STM32F1 clones */ PROBE(lpc15xx_probe); /* Thanks to JojoS for testing */ diff --git a/src/target/efm32.c b/src/target/efm32.c index 6ad4f32f..547eadc8 100644 --- a/src/target/efm32.c +++ b/src/target/efm32.c @@ -267,75 +267,75 @@ const struct command_s efm32_cmd_list[] = { /* -------------------------------------------------------------------------- */ typedef struct efm32_device_t { - uint16_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 */ + uint8_t family_id; /* Family for device matching */ bool has_radio; /* Indicates a device has attached radio */ - uint32_t user_data_size; /* User Data (UD) region size */ - uint32_t bootloader_size; /* Bootloader (BL) region size (may be 0 for no BL region) */ + uint16_t flash_page_size; /* Flash page size */ + 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 */ } efm32_device_t; efm32_device_t const efm32_devices[] = { /* First gen micros */ - {71, "EFM32G", 512, 0x400c0000, false, 512, 0, "Gecko"}, - {72, "EFM32GG", 2048, 0x400c0000, false, 4096, 0, "Giant Gecko"}, - {73, "EFM32TG", 512, 0x400c0000, false, 512, 0, "Tiny Gecko"}, - {74, "EFM32LG", 2048, 0x400c0000, false, 2048, 0, "Leopard Gecko"}, - {75, "EFM32WG", 2048, 0x400c0000, false, 2048, 0, "Wonder Gecko"}, - {76, "EFM32ZG", 1024, 0x400c0000, false, 1024, 0, "Zero Gecko"}, - {77, "EFM32HG", 1024, 0x400c0000, false, 1024, 0, "Happy Gecko"}, + { 71, false, 512, "EFM32G" , 0x400c0000, 512, 0, "Gecko"}, + { 72, false, 2048, "EFM32GG" , 0x400c0000, 4096, 0, "Giant Gecko"}, + { 73, false, 512, "EFM32TG" , 0x400c0000, 512, 0, "Tiny Gecko"}, + { 74, false, 2048, "EFM32LG" , 0x400c0000, 2048, 0, "Leopard Gecko"}, + { 75, false, 2048, "EFM32WG" , 0x400c0000, 2048, 0, "Wonder Gecko"}, + { 76, false, 1024, "EFM32ZG" , 0x400c0000, 1024, 0, "Zero Gecko"}, + { 77, false, 1024, "EFM32HG" , 0x400c0000, 1024, 0, "Happy Gecko"}, /* First (1.5) gen micro + radio */ - {120, "EZR32WG", 2048, 0x400c0000, true, 2048, 0, "EZR Wonder Gecko"}, - {121, "EZR32LG", 2048, 0x400c0000, true, 2048, 0, "EZR Leopard Gecko"}, - {122, "EZR32HG", 1024, 0x400c0000, true, 1024, 0, "EZR Happy Gecko"}, + {120, true , 2048, "EZR32WG" , 0x400c0000, 2048, 0, "EZR Wonder Gecko"}, + {121, true , 2048, "EZR32LG" , 0x400c0000, 2048, 0, "EZR Leopard Gecko"}, + {122, true , 1024, "EZR32HG" , 0x400c0000, 1024, 0, "EZR Happy Gecko"}, /* Second gen micros */ - {81, "EFM32PG1B", 2048, 0x400e0000, false, 2048, 10240, "Pearl Gecko"}, - {83, "EFM32JG1B", 2048, 0x400e0000, false, 2048, 10240, "Jade Gecko"}, - {85, "EFM32PG12B", 2048, 0x400e0000, false, 2048, 32768,"Pearl Gecko 12"}, - {87, "EFM32JG12B", 2048, 0x400e0000, false, 2048, 32768, "Jade Gecko 12"}, + { 81, false, 2048, "EFM32PG1B" , 0x400e0000, 2048, 10240, "Pearl Gecko"}, + { 83, false, 2048, "EFM32JG1B" , 0x400e0000, 2048, 10240, "Jade Gecko"}, + { 85, false, 2048, "EFM32PG12B", 0x400e0000, 2048, 32768,"Pearl Gecko 12"}, + { 87, false, 2048, "EFM32JG12B", 0x400e0000, 2048, 32768, "Jade Gecko 12"}, /* Second (2.5) gen micros, with re-located MSC */ - {100, "EFM32GG11B", 4096, 0x40000000, false, 4096, 32768, "Giant Gecko 11"}, - {103, "EFM32TG11B", 2048, 0x40000000, false, 2048, 18432, "Tiny Gecko 11"}, - {106, "EFM32GG12B", 2048, 0x40000000, false, 2048, 32768, "Giant Gecko 12"}, + {100, false, 4096, "EFM32GG11B", 0x40000000, 4096, 32768, "Giant Gecko 11"}, + {103, false, 2048, "EFM32TG11B", 0x40000000, 2048, 18432, "Tiny Gecko 11"}, + {106, false, 2048, "EFM32GG12B", 0x40000000, 2048, 32768, "Giant Gecko 12"}, /* Second gen devices micro + radio */ - {16, "EFR32MG1P", 2048, 0x400e0000, true, 2048, 10240, "Mighty Gecko"}, - {17, "EFR32MG1B", 2048, 0x400e0000, true, 2048, 10240, "Mighty Gecko"}, - {18, "EFR32MG1V", 2048, 0x400e0000, true, 2048, 10240, "Mighty Gecko"}, - {19, "EFR32BG1P", 2048, 0x400e0000, true, 2048, 10240, "Blue Gecko"}, - {20, "EFR32BG1B", 2048, 0x400e0000, true, 2048, 10240, "Blue Gecko"}, - {21, "EFR32BG1V", 2048, 0x400e0000, true, 2048, 10240, "Blue Gecko"}, - {25, "EFR32FG1P", 2048, 0x400e0000, true, 2048, 10240, "Flex Gecko"}, - {26, "EFR32FG1B", 2048, 0x400e0000, true, 2048, 10240, "Flex Gecko"}, - {27, "EFR32FG1V", 2048, 0x400e0000, true, 2048, 10240, "Flex Gecko"}, - {28, "EFR32MG12P", 2048, 0x400e0000, true, 2048, 32768, "Mighty Gecko"}, - {29, "EFR32MG12B", 2048, 0x400e0000, true, 2048, 32768, "Mighty Gecko"}, - {30, "EFR32MG12V", 2048, 0x400e0000, true, 2048, 32768, "Mighty Gecko"}, - {31, "EFR32BG12P", 2048, 0x400e0000, true, 2048, 32768, "Blue Gecko"}, - {32, "EFR32BG12B", 2048, 0x400e0000, true, 2048, 32768, "Blue Gecko"}, - {33, "EFR32BG12V", 2048, 0x400e0000, true, 2048, 32768, "Blue Gecko"}, - {37, "EFR32FG12P", 2048, 0x400e0000, true, 2048, 32768, "Flex Gecko"}, - {38, "EFR32FG12B", 2048, 0x400e0000, true, 2048, 32768, "Flex Gecko"}, - {39, "EFR32FG12V", 2048, 0x400e0000, true, 2048, 32768, "Flex Gecko"}, - {40, "EFR32MG13P", 2048, 0x400e0000, true, 2048, 16384, "Mighty Gecko"}, - {41, "EFR32MG13B", 2048, 0x400e0000, true, 2048, 16384, "Mighty Gecko"}, - {42, "EFR32MG13V", 2048, 0x400e0000, true, 2048, 16384, "Mighty Gecko"}, - {43, "EFR32BG13P", 2048, 0x400e0000, true, 2048, 16384, "Blue Gecko"}, - {44, "EFR32BG13B", 2048, 0x400e0000, true, 2048, 16384, "Blue Gecko"}, - {45, "EFR32BG13V", 2048, 0x400e0000, true, 2048, 16384, "Blue Gecko"}, - {49, "EFR32FG13P", 2048, 0x400e0000, true, 2048, 16384, "Flex Gecko"}, - {50, "EFR32FG13B", 2048, 0x400e0000, true, 2048, 16384, "Flex Gecko"}, - {51, "EFR32FG13V", 2048, 0x400e0000, true, 2048, 16384, "Flex Gecko"}, - {52, "EFR32MG14P", 2048, 0x400e0000, true, 2048, 16384, "Mighty Gecko"}, - {53, "EFR32MG14B", 2048, 0x400e0000, true, 2048, 16384, "Mighty Gecko"}, - {54, "EFR32MG14V", 2048, 0x400e0000, true, 2048, 16384, "Mighty Gecko"}, - {55, "EFR32BG14P", 2048, 0x400e0000, true, 2048, 16384, "Blue Gecko"}, - {56, "EFR32BG14B", 2048, 0x400e0000, true, 2048, 16384, "Blue Gecko"}, - {57, "EFR32BG14V", 2048, 0x400e0000, true, 2048, 16384, "Blue Gecko"}, - {61, "EFR32FG14P", 2048, 0x400e0000, true, 2048, 16384, "Flex Gecko"}, - {62, "EFR32FG14B", 2048, 0x400e0000, true, 2048, 16384, "Flex Gecko"}, - {63, "EFR32FG14V", 2048, 0x400e0000, true, 2048, 16384, "Flex Gecko"}, + { 16, true , 2048, "EFR32MG1P" , 0x400e0000, 2048, 10240, "Mighty Gecko"}, + { 17, true , 2048, "EFR32MG1B" , 0x400e0000, 2048, 10240, "Mighty Gecko"}, + { 18, true , 2048, "EFR32MG1V" , 0x400e0000, 2048, 10240, "Mighty Gecko"}, + { 19, true , 2048, "EFR32BG1P" , 0x400e0000, 2048, 10240, "Blue Gecko"}, + { 20, true , 2048, "EFR32BG1B" , 0x400e0000, 2048, 10240, "Blue Gecko"}, + { 21, true , 2048, "EFR32BG1V" , 0x400e0000, 2048, 10240, "Blue Gecko"}, + { 25, true , 2048, "EFR32FG1P" , 0x400e0000, 2048, 10240, "Flex Gecko"}, + { 26, true , 2048, "EFR32FG1B" , 0x400e0000, 2048, 10240, "Flex Gecko"}, + { 27, true , 2048, "EFR32FG1V" , 0x400e0000, 2048, 10240, "Flex Gecko"}, + { 28, true , 2048, "EFR32MG12P", 0x400e0000, 2048, 32768, "Mighty Gecko"}, + { 29, true , 2048, "EFR32MG12B", 0x400e0000, 2048, 32768, "Mighty Gecko"}, + { 30, true , 2048, "EFR32MG12V", 0x400e0000, 2048, 32768, "Mighty Gecko"}, + { 31, true , 2048, "EFR32BG12P", 0x400e0000, 2048, 32768, "Blue Gecko"}, + { 32, true , 2048, "EFR32BG12B", 0x400e0000, 2048, 32768, "Blue Gecko"}, + { 33, true , 2048, "EFR32BG12V", 0x400e0000, 2048, 32768, "Blue Gecko"}, + { 37, true , 2048, "EFR32FG12P", 0x400e0000, 2048, 32768, "Flex Gecko"}, + { 38, true , 2048, "EFR32FG12B", 0x400e0000, 2048, 32768, "Flex Gecko"}, + { 39, true , 2048, "EFR32FG12V", 0x400e0000, 2048, 32768, "Flex Gecko"}, + { 40, true , 2048, "EFR32MG13P", 0x400e0000, 2048, 16384, "Mighty Gecko"}, + { 41, true , 2048, "EFR32MG13B", 0x400e0000, 2048, 16384, "Mighty Gecko"}, + { 42, true , 2048, "EFR32MG13V", 0x400e0000, 2048, 16384, "Mighty Gecko"}, + { 43, true , 2048, "EFR32BG13P", 0x400e0000, 2048, 16384, "Blue Gecko"}, + { 44, true , 2048, "EFR32BG13B", 0x400e0000, 2048, 16384, "Blue Gecko"}, + { 45, true , 2048, "EFR32BG13V", 0x400e0000, 2048, 16384, "Blue Gecko"}, + { 49, true , 2048, "EFR32FG13P", 0x400e0000, 2048, 16384, "Flex Gecko"}, + { 50, true , 2048, "EFR32FG13B", 0x400e0000, 2048, 16384, "Flex Gecko"}, + { 51, true , 2048, "EFR32FG13V", 0x400e0000, 2048, 16384, "Flex Gecko"}, + { 52, true , 2048, "EFR32MG14P", 0x400e0000, 2048, 16384, "Mighty Gecko"}, + { 53, true , 2048, "EFR32MG14B", 0x400e0000, 2048, 16384, "Mighty Gecko"}, + { 54, true , 2048, "EFR32MG14V", 0x400e0000, 2048, 16384, "Mighty Gecko"}, + { 55, true , 2048, "EFR32BG14P", 0x400e0000, 2048, 16384, "Blue Gecko"}, + { 56, true , 2048, "EFR32BG14B", 0x400e0000, 2048, 16384, "Blue Gecko"}, + { 57, true , 2048, "EFR32BG14V", 0x400e0000, 2048, 16384, "Blue Gecko"}, + { 61, true , 2048, "EFR32FG14P", 0x400e0000, 2048, 16384, "Flex Gecko"}, + { 62, true , 2048, "EFR32FG14B", 0x400e0000, 2048, 16384, "Flex Gecko"}, + { 63, true , 2048, "EFR32FG14V", 0x400e0000, 2048, 16384, "Flex Gecko"}, }; diff --git a/src/target/lpc11xx.c b/src/target/lpc11xx.c index d487f337..5b12e1c6 100644 --- a/src/target/lpc11xx.c +++ b/src/target/lpc11xx.c @@ -36,6 +36,22 @@ #define LPC11XX_DEVICE_ID 0x400483F4 #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[]) { (void)argc; @@ -56,7 +72,7 @@ const struct command_s lpc11xx_cmd_list[] = { {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); 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_ram = IAP_RAM_BASE; lf->iap_msp = IAP_RAM_BASE + MIN_RAM_SIZE - RAM_USAGE_FOR_IAP_ROUTINES; + lf->reserved_pages = reserved_pages; } bool @@ -109,7 +126,7 @@ lpc11xx_probe(target *t) case 0x2980002B: /* lpc11u24x/401 */ t->driver = "LPC11xx"; 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"); return true; @@ -117,23 +134,26 @@ lpc11xx_probe(target *t) case 0x1A24902B: t->driver = "LPC1112"; 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; case 0x1000002b: // FX LPC11U6 32 kB SRAM/256 kB flash (max) t->driver = "LPC11U6"; 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; case 0x3000002B: case 0x3D00002B: t->driver = "LPC1343"; 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; case 0x00008A04: /* LPC8N04 (see UM11074 Rev.1.3 section 4.5.19) */ t->driver = "LPC8N04"; 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"); return true; } @@ -148,7 +168,7 @@ lpc11xx_probe(target *t) case 0x00008024: /* 802M001JHI33 */ t->driver = "LPC802"; 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"); return true; case 0x00008040: /* 804M101JBD64 */ @@ -158,7 +178,7 @@ lpc11xx_probe(target *t) case 0x00008044: /* 804M101JHI33 */ t->driver = "LPC804"; 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"); return true; case 0x00008100: /* LPC810M021FN8 */ @@ -168,7 +188,7 @@ lpc11xx_probe(target *t) case 0x00008122: /* LPC812M101JDH20 / LPC812M101JTB16 */ t->driver = "LPC81x"; 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"); return true; case 0x00008221: /* LPC822M101JHI33 */ @@ -177,19 +197,19 @@ lpc11xx_probe(target *t) case 0x00008242: /* LPC824M201JDH20 */ t->driver = "LPC82x"; 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"); return true; case 0x00008322: /* LPC832M101FDH20 */ t->driver = "LPC832"; 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"); return true; case 0x00008341: /* LPC8341201FHI33 */ t->driver = "LPC834"; 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"); return true; case 0x00008441: @@ -198,7 +218,7 @@ lpc11xx_probe(target *t) case 0x00008444: t->driver = "LPC844"; 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; case 0x00008451: case 0x00008452: @@ -206,7 +226,7 @@ lpc11xx_probe(target *t) case 0x00008454: t->driver = "LPC845"; 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; case 0x0003D440: /* LPC11U34/311 */ case 0x0001cc40: /* LPC11U34/421 */ @@ -218,13 +238,13 @@ lpc11xx_probe(target *t) case 0x00007C40: /* LPC11U37FBD64/501 */ t->driver = "LPC11U3x"; 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; case 0x00040070: /* LPC1114/333 */ case 0x00050080: /* lpc1115XL */ t->driver = "LPC1100XL"; 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; } if (idcode) { diff --git a/src/target/lpc_common.c b/src/target/lpc_common.c index b16c22c2..7b6b2efc 100644 --- a/src/target/lpc_common.c +++ b/src/target/lpc_common.c @@ -33,6 +33,45 @@ struct flash_param { uint32_t result[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) { @@ -109,11 +148,17 @@ enum iap_status lpc_iap_call(struct lpc_flash *f, void *result, enum iap_cmd cmd if (result != NULL) memcpy(result, param.result, sizeof(param.result)); +#if defined(ENABLE_DEBUG) if (param.status != IAP_STATUS_CMD_SUCCESS) { - DEBUG_WARN("IAP failure code %d for cmd %d\n", - (enum iap_status)param.status, cmd); + if (param.status > (sizeof(iap_error) / sizeof(char*))) + 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; } @@ -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; } +#define LPX80X_SECTOR_SIZE 0x400 +#define LPX80X_PAGE_SIZE 0x40 + int lpc_flash_erase(struct target_flash *tf, target_addr addr, size_t len) { struct lpc_flash *f = (struct lpc_flash *)tf; uint32_t start = lpc_sector_for_addr(f, addr); 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)) return -1; - /* and now erase them */ - if (lpc_iap_call(f, NULL, IAP_CMD_ERASE, start, end, CPU_CLK_KHZ, f->bank)) - return -2; + /* Only LPC80x has reserved pages!*/ + if (f->reserved_pages && ((addr + len) >= tf->length - 0x400) ) { + 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 */ - if (lpc_iap_call(f, NULL, IAP_CMD_BLANKCHECK, start, end, f->bank)) - return -3; + /* check erase ok */ + if (lpc_iap_call(f, NULL, IAP_CMD_BLANKCHECK, start, last_full_sector, f->bank)) + 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; } -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) { struct lpc_flash *f = (struct lpc_flash *)tf; /* prepare... */ 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; - - /* Write payload to target ram */ + } uint32_t bufaddr = ALIGN(f->iap_ram + sizeof(struct flash_param), 4); target_mem_write(f->f.t, bufaddr, src, len); - - /* set the destination address and program */ - if (lpc_iap_call(f, NULL, IAP_CMD_PROGRAM, dest, bufaddr, len, CPU_CLK_KHZ)) - return -2; - + /* Only LPC80x has reserved pages!*/ + if ((!f->reserved_pages) || ((dest + len) <= (tf->length - len))) { + /* Write payload to target ram */ + /* 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; } diff --git a/src/target/lpc_common.h b/src/target/lpc_common.h index 3130e96b..5d17eef9 100644 --- a/src/target/lpc_common.h +++ b/src/target/lpc_common.h @@ -21,14 +21,23 @@ #define __LPC_COMMON_H enum iap_cmd { + IAP_CMD_READ_FACTORY_SETTINGS = 40, IAP_CMD_INIT = 49, IAP_CMD_PREPARE = 50, IAP_CMD_PROGRAM = 51, IAP_CMD_ERASE = 52, IAP_CMD_BLANKCHECK = 53, 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_ERASE_PAGE = 59, 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 { @@ -44,6 +53,16 @@ enum iap_status { IAP_STATUS_SECTOR_NOT_PREPARED = 9, IAP_STATUS_COMPARE_ERROR = 10, 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 */ @@ -53,6 +72,7 @@ struct lpc_flash { struct target_flash f; uint8_t base_sector; uint8_t bank; + uint8_t reserved_pages; /* Info filled in by specific driver */ void (*wdt_kick)(target *t); 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); 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_write(struct target_flash *f, - target_addr dest, const void *src, size_t len); int lpc_flash_write_magic_vect(struct target_flash *f, target_addr dest, const void *src, size_t len); diff --git a/src/target/rp.c b/src/target/rp.c index 5d95085c..c62bd0a0 100644 --- a/src/target/rp.c +++ b/src/target/rp.c @@ -59,6 +59,7 @@ struct rp_priv_s { uint16_t _flash_enter_cmd_xip; uint16_t reset_usb_boot; bool is_prepared; + bool is_monitor; 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 * * 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, 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); if (!timeout) return false; - DEBUG_INFO("Call cmd %04x\n", cmd); + DEBUG_INFO("Call cmd %04" PRIx32 "\n", cmd); platform_timeout to; 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 { - if (timeout > 400) - tc_printf(t, "\b%c", spinner[spinindex++ % 4]); + if (platform_timeout_is_expired(&to_spinner)) { + if (ps->is_monitor) + tc_printf(t, "\b%c", spinner[spinindex++ % 4]); + platform_timeout_set(&to_spinner, 500); + } 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; } } 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); bool ret = ((dbg_regs[REG_PC] &~1) != (ps->_debug_trampoline_end & ~1)); 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]); } 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; if (!ps->is_prepared) { + DEBUG_INFO("rp_flash_prepare\n"); /* connect*/ rp_rom_call(t, ps->regs, ps->_connect_internal_flash,100); /* 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 * 32k block erase 120/ 1600 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"); 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; rp_flash_prepare(t); 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; if (len > MAX_FLASH) len = MAX_FLASH; + bool ret = 0; while (len) { ps->regs[0] = addr; 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[3] = FLASHCMD_CHIP_ERASE; 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; } else if (len >= (64 * 1024)) { uint32_t chunk = len & ~((1 << 16) - 1); ps->regs[1] = chunk; ps->regs[3] = FLASHCMD_BLOCK64K_ERASE; 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 ; addr += chunk; } 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[3] = FLASHCMD_BLOCK32K_ERASE; 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; addr += chunk; } else { @@ -225,18 +250,23 @@ static int rp_flash_erase(struct target_flash *f, target_addr addr, ps->regs[2] = MAX_FLASH; ps->regs[3] = FLASHCMD_SECTOR_ERASE; 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; } + if (ret) { + DEBUG_WARN("Erase failed!\n"); + break; + } } - DEBUG_INFO("\nErase done!\n"); - return 0; + rp_flash_resume(t); + DEBUG_INFO("Erase done!\n"); + return ret; } int rp_flash_write(struct target_flash *f, 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)) { DEBUG_WARN("Unaligned erase\n"); 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; /* Write payload to target ram */ dest -= XIP_FLASH_START; + bool ret = 0; #define MAX_WRITE_CHUNK 0x1000 while (len) { 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[1] = SRAM_START; ps->regs[2] = chunksize; - rp_rom_call(t, ps->regs, ps->flash_range_program, - (3 * chunksize) >> 8); /* 3 ms per 256 byte page */ + /* Loading takes 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; src += 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[]) @@ -284,7 +325,11 @@ static bool rp_cmd_erase_mass(target *t, int argc, const char *argv[]) (void) argv; struct target_flash f; 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[] = { diff --git a/src/target/target.c b/src/target/target.c index c17e9158..4f4bcace 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -19,7 +19,6 @@ */ #include "general.h" -#include "target.h" #include "target_internal.h" #include @@ -342,7 +341,6 @@ void target_detach(target *t) t->detach(t); t->attached = false; #if PC_HOSTED == 1 -# include "platform.h" platform_buffer_flush(); #endif }