From 04eab8e1f88a717423d4a2662129ab0dce333fe1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Mellstr=C3=B6m?= Date: Thu, 3 Jun 2021 12:51:27 +0200 Subject: [PATCH 01/31] Add guard around _GNU_SOURCE define This avoids warnings if the define has already been set by the build system. --- src/include/general.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/include/general.h b/src/include/general.h index ba86da22..84a3d0ac 100644 --- a/src/include/general.h +++ b/src/include/general.h @@ -21,7 +21,9 @@ #ifndef __GENERAL_H #define __GENERAL_H -#define _GNU_SOURCE +#if !defined(_GNU_SOURCE) +# define _GNU_SOURCE +#endif #if !defined(__USE_MINGW_ANSI_STDIO) # define __USE_MINGW_ANSI_STDIO 1 #endif From 53f022d29b51623372aaf32e0b6ba833c77d0748 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Mellstr=C3=B6m?= Date: Thu, 3 Jun 2021 12:52:07 +0200 Subject: [PATCH 02/31] Require semicolon after debug log statements This also fixes a warning about an empty body in cortexm.c if PLATFORM_HAS_DEBUG is defined but debugging is not enabled: if (platform_timeout_is_expired(&to)) DEBUG_WARN("Reset seem to be stuck low!\n"); --- src/include/general.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/include/general.h b/src/include/general.h index 84a3d0ac..da7cf3dc 100644 --- a/src/include/general.h +++ b/src/include/general.h @@ -63,14 +63,14 @@ enum BMP_DEBUG { # define DEBUG_WARN printf # define DEBUG_INFO printf # else -# define DEBUG_WARN(...) -# define DEBUG_INFO(...) +# define DEBUG_WARN(...) do {} while(0) +# define DEBUG_INFO(...) do {} while(0) # endif -# define DEBUG_GDB(...) -# define DEBUG_TARGET(...) -# define DEBUG_PROBE(...) -# define DEBUG_WIRE(...) -# define DEBUG_GDB_WIRE(...) +# define DEBUG_GDB(...) do {} while(0) +# define DEBUG_TARGET(...) do {} while(0) +# define DEBUG_PROBE(...) do {} while(0) +# define DEBUG_WIRE(...) do {} while(0) +# define DEBUG_GDB_WIRE(...) do {} while(0) #else # include extern int cl_debuglevel; From 711a87f7ba450e9ed3768dcfefacc84fee57b872 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Mellstr=C3=B6m?= Date: Thu, 3 Jun 2021 12:55:28 +0200 Subject: [PATCH 03/31] Fix some warnings when compiling with -Wshadow There are still a few more places that would need to be corrected before -Wshadow could be added by default. --- src/gdb_main.c | 18 +++++++++--------- src/platforms/common/cdcacm.c | 4 ++-- src/platforms/stm32/dfucore.c | 4 ++-- src/target/adiv5_swdp.c | 6 +++--- src/target/cortexm.c | 6 +++--- src/target/sam3x.c | 2 +- src/target/stm32f1.c | 2 +- src/target/stm32f4.c | 6 +++--- src/target/target.c | 2 +- 9 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/gdb_main.c b/src/gdb_main.c index fcf79e69..cb691124 100644 --- a/src/gdb_main.c +++ b/src/gdb_main.c @@ -436,27 +436,27 @@ handle_v_packet(char *packet, int plen) } else if (!strncmp(packet, "vRun", 4)) { /* Parse command line for get_cmdline semihosting call */ char cmdline[83]; - char *pbuf = cmdline; + char *pcmdline = cmdline; char *tok = packet + 4; if (*tok == ';') tok++; *cmdline='\0'; while(*tok != '\0') { if(strlen(cmdline)+3 >= sizeof(cmdline)) break; if (*tok == ';') { - *pbuf++=' '; - *pbuf='\0'; + *pcmdline++=' '; + *pcmdline='\0'; tok++; continue; } if (isxdigit(*tok) && isxdigit(*(tok+1))) { - unhexify(pbuf, tok, 2); - if ((*pbuf == ' ') || (*pbuf == '\\')) { - *(pbuf+1)=*pbuf; - *pbuf++='\\'; + unhexify(pcmdline, tok, 2); + if ((*pcmdline == ' ') || (*pcmdline == '\\')) { + *(pcmdline+1)=*pcmdline; + *pcmdline++='\\'; } - pbuf++; + pcmdline++; tok+=2; - *pbuf='\0'; + *pcmdline='\0'; continue; } break; diff --git a/src/platforms/common/cdcacm.c b/src/platforms/common/cdcacm.c index b1a91264..99ee0fd9 100644 --- a/src/platforms/common/cdcacm.c +++ b/src/platforms/common/cdcacm.c @@ -51,7 +51,7 @@ static int cdcacm_gdb_dtr = 1; static void cdcacm_set_modem_state(usbd_device *dev, int iface, bool dsr, bool dcd); -static const struct usb_device_descriptor dev = { +static const struct usb_device_descriptor dev_desc = { .bLength = USB_DT_DEVICE_SIZE, .bDescriptorType = USB_DT_DEVICE, .bcdUSB = 0x0200, @@ -551,7 +551,7 @@ void cdcacm_init(void) serial_no_read(serial_no); - usbdev = usbd_init(&USB_DRIVER, &dev, &config, usb_strings, + usbdev = usbd_init(&USB_DRIVER, &dev_desc, &config, usb_strings, sizeof(usb_strings)/sizeof(char *), usbd_control_buffer, sizeof(usbd_control_buffer)); diff --git a/src/platforms/stm32/dfucore.c b/src/platforms/stm32/dfucore.c index 3ddadb60..b94a1142 100644 --- a/src/platforms/stm32/dfucore.c +++ b/src/platforms/stm32/dfucore.c @@ -63,7 +63,7 @@ static struct { } prog; static uint8_t current_error; -const struct usb_device_descriptor dev = { +const struct usb_device_descriptor dev_desc = { .bLength = USB_DT_DEVICE_SIZE, .bDescriptorType = USB_DT_DEVICE, .bcdUSB = 0x0200, @@ -293,7 +293,7 @@ void dfu_init(const usbd_driver *driver) { get_dev_unique_id(serial_no); - usbdev = usbd_init(driver, &dev, &config, + usbdev = usbd_init(driver, &dev_desc, &config, usb_strings, 4, usbd_control_buffer, sizeof(usbd_control_buffer)); diff --git a/src/target/adiv5_swdp.c b/src/target/adiv5_swdp.c index 65986a80..66766fb6 100644 --- a/src/target/adiv5_swdp.c +++ b/src/target/adiv5_swdp.c @@ -125,12 +125,12 @@ int adiv5_swdp_scan(uint32_t targetid) initial_dp->seq_out(0xE79E, 16); /* 0b0111100111100111 */ dp_line_reset(initial_dp); initial_dp->fault = 0; - volatile struct exception e; - TRY_CATCH (e, EXCEPTION_ALL) { + volatile struct exception e2; + TRY_CATCH (e2, EXCEPTION_ALL) { idcode = initial_dp->low_access(initial_dp, ADIV5_LOW_READ, ADIV5_DP_IDCODE, 0); } - if (e.type) { + if (e2.type) { DEBUG_WARN("No usable DP found\n"); return -1; } diff --git a/src/target/cortexm.c b/src/target/cortexm.c index 82e22b66..d0877b7e 100644 --- a/src/target/cortexm.c +++ b/src/target/cortexm.c @@ -526,7 +526,7 @@ bool cortexm_attach(target *t) platform_timeout timeout; platform_timeout_set(&timeout, 1000); while (1) { - uint32_t dhcsr = target_mem_read32(t, CORTEXM_DHCSR); + dhcsr = target_mem_read32(t, CORTEXM_DHCSR); if (!(dhcsr & CORTEXM_DHCSR_S_RESET_ST)) break; if (platform_timeout_is_expired(&timeout)) { @@ -572,8 +572,8 @@ static void cortexm_regs_read(target *t, void *data) for(i = 0; i < sizeof(regnum_cortex_m) / 4; i++) *regs++ = base_regs[regnum_cortex_m[i]]; if (t->target_options & TOPT_FLAVOUR_V7MF) - for(size_t t = 0; t < sizeof(regnum_cortex_mf) / 4; t++) - *regs++ = ap->dp->ap_reg_read(ap, regnum_cortex_mf[t]); + for(i = 0; i < sizeof(regnum_cortex_mf) / 4; i++) + *regs++ = ap->dp->ap_reg_read(ap, regnum_cortex_mf[i]); } #else if (0) {} diff --git a/src/target/sam3x.c b/src/target/sam3x.c index c869d722..4a1ba08b 100644 --- a/src/target/sam3x.c +++ b/src/target/sam3x.c @@ -248,7 +248,7 @@ bool sam3x_probe(target *t) case CHIPID_CIDR_ARCH_SAM4SDC | CHIPID_CIDR_EPROC_CM4: t->driver = "Atmel SAM4S"; target_add_ram(t, 0x20000000, 0x400000); - size_t size = sam_flash_size(cidr); + size = sam_flash_size(cidr); if (size <= 0x80000) { /* Smaller devices have a single bank */ sam4_add_flash(t, SAM4S_EEFC_BASE(0), 0x400000, size); diff --git a/src/target/stm32f1.c b/src/target/stm32f1.c index a0ade734..3bc728fd 100644 --- a/src/target/stm32f1.c +++ b/src/target/stm32f1.c @@ -386,7 +386,7 @@ static bool stm32f1_cmd_erase_mass(target *t, int argc, const char **argv) if(target_check_error(t)) return false; /* Check for error */ - uint16_t sr = target_mem_read32(t, FLASH_SR + FLASH_BANK2_OFFSET); + sr = target_mem_read32(t, FLASH_SR + FLASH_BANK2_OFFSET); if ((sr & SR_ERROR_MASK) || !(sr & SR_EOP)) return false; } diff --git a/src/target/stm32f4.c b/src/target/stm32f4.c index 148497c1..bc32cc22 100644 --- a/src/target/stm32f4.c +++ b/src/target/stm32f4.c @@ -384,9 +384,9 @@ static int stm32f4_flash_erase(struct target_flash *f, target_addr addr, stm32f4_flash_unlock(t); enum align psize = ALIGN_WORD; - for (struct target_flash *f = t->flash; f; f = f->next) { - if (f->write == stm32f4_flash_write) { - psize = ((struct stm32f4_flash *)f)->psize; + for (struct target_flash *currf = t->flash; currf; currf = currf->next) { + if (currf->write == stm32f4_flash_write) { + psize = ((struct stm32f4_flash *)currf)->psize; } } while(len) { diff --git a/src/target/target.c b/src/target/target.c index 4f4bcace..44763ad3 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -276,7 +276,7 @@ int target_flash_done(target *t) if (tmp) return tmp; if (f->done) { - int tmp = f->done(f); + tmp = f->done(f); if (tmp) return tmp; } From 4b8c4990dcc40cc18c355b92949b787b415828a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Mellstr=C3=B6m?= Date: Thu, 3 Jun 2021 12:56:41 +0200 Subject: [PATCH 04/31] Fix warning about unused variable in adiv5.c This happens if the platform has debugging support but debugging is not enabled. --- src/target/adiv5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/target/adiv5.c b/src/target/adiv5.c index 38c3c9f9..06cb09bb 100644 --- a/src/target/adiv5.c +++ b/src/target/adiv5.c @@ -334,7 +334,7 @@ static bool cortexm_prepare(ADIv5_AP_t *ap) uint32_t dhcsr_ctl = CORTEXM_DHCSR_DBGKEY | CORTEXM_DHCSR_C_DEBUGEN | CORTEXM_DHCSR_C_HALT; uint32_t dhcsr_valid = CORTEXM_DHCSR_S_HALT | CORTEXM_DHCSR_C_DEBUGEN; -#ifdef PLATFORM_HAS_DEBUG +#if defined(ENABLE_DEBUG) && defined(PLATFORM_HAS_DEBUG) uint32_t start_time = platform_time_ms(); #endif uint32_t dhcsr; From d987a8dd8c3f35f6f50a63f60cb1777dd38af2c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Mellstr=C3=B6m?= Date: Thu, 3 Jun 2021 13:56:11 +0200 Subject: [PATCH 05/31] Add define to allow platform override of debug printf function --- src/include/general.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/include/general.h b/src/include/general.h index da7cf3dc..ba329d21 100644 --- a/src/include/general.h +++ b/src/include/general.h @@ -59,9 +59,12 @@ enum BMP_DEBUG { * BMP PC-Hosted is the preferred way. Printing DEBUG_WARN * and DEBUG_INFO is kept for comptibiluty. */ +# if !defined(PLATFORM_PRINTF) +# define PLATFORM_PRINTF printf +# endif # if defined(ENABLE_DEBUG) -# define DEBUG_WARN printf -# define DEBUG_INFO printf +# define DEBUG_WARN PLATFORM_PRINTF +# define DEBUG_INFO PLATFORM_PRINTF # else # define DEBUG_WARN(...) do {} while(0) # define DEBUG_INFO(...) do {} while(0) From 5ea01030e2d3a585cd0076d2652cade69b67297c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Mellstr=C3=B6m?= Date: Thu, 3 Jun 2021 12:58:05 +0200 Subject: [PATCH 06/31] Add nRF51 command for (only) erasing the UICR registers Original implementation by: Benjamin Vedder --- src/target/nrf51.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/target/nrf51.c b/src/target/nrf51.c index 038e8a8b..4021c0a9 100644 --- a/src/target/nrf51.c +++ b/src/target/nrf51.c @@ -31,6 +31,7 @@ static int nrf51_flash_write(struct target_flash *f, target_addr dest, const void *src, size_t len); static bool nrf51_cmd_erase_all(target *t, int argc, const char **argv); +static bool nrf51_cmd_erase_uicr(target *t, int argc, const char **argv); static bool nrf51_cmd_read_hwid(target *t, int argc, const char **argv); static bool nrf51_cmd_read_fwid(target *t, int argc, const char **argv); static bool nrf51_cmd_read_deviceid(target *t, int argc, const char **argv); @@ -41,6 +42,7 @@ static bool nrf51_cmd_read(target *t, int argc, const char **argv); const struct command_s nrf51_cmd_list[] = { {"erase_mass", (cmd_handler)nrf51_cmd_erase_all, "Erase entire flash memory"}, + {"erase_uicr", (cmd_handler)nrf51_cmd_erase_uicr, "Erase UICR registers"}, {"read", (cmd_handler)nrf51_cmd_read, "Read device parameters"}, {NULL, NULL, NULL} }; @@ -244,6 +246,31 @@ static bool nrf51_cmd_erase_all(target *t, int argc, const char **argv) return true; } +static bool nrf51_cmd_erase_uicr(target *t, int argc, const char **argv) +{ + (void)argc; + (void)argv; + tc_printf(t, "erase..\n"); + + /* Enable erase */ + target_mem_write32(t, NRF51_NVMC_CONFIG, NRF51_NVMC_CONFIG_EEN); + + /* Poll for NVMC_READY */ + while (target_mem_read32(t, NRF51_NVMC_READY) == 0) + if(target_check_error(t)) + return false; + + /* Erase UICR */ + target_mem_write32(t, NRF51_NVMC_ERASEUICR, 1); + + /* Poll for NVMC_READY */ + while (target_mem_read32(t, NRF51_NVMC_READY) == 0) + if(target_check_error(t)) + return false; + + return true; +} + static bool nrf51_cmd_read_hwid(target *t, int argc, const char **argv) { (void)argc; From ea4b23299633a54be00a463d1e24b422543342af Mon Sep 17 00:00:00 2001 From: fabalthazar Date: Sun, 6 Jun 2021 23:40:42 +0200 Subject: [PATCH 07/31] Fix de83dbb: duplicate BMP_MODE_FLASH_VERIFY -> BMP_MODE_FLASH_WRITE_VERIFY --- src/platforms/pc/cl_utils.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platforms/pc/cl_utils.c b/src/platforms/pc/cl_utils.c index fc34496f..85e5caf4 100644 --- a/src/platforms/pc/cl_utils.c +++ b/src/platforms/pc/cl_utils.c @@ -419,9 +419,9 @@ 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) && - (opt->opt_mode != BMP_MODE_FLASH_WRITE) && + (opt->opt_mode != BMP_MODE_FLASH_WRITE) && (opt->opt_mode != BMP_MODE_FLASH_VERIFY) && - (opt->opt_mode != BMP_MODE_FLASH_VERIFY)) + (opt->opt_mode != BMP_MODE_FLASH_WRITE_VERIFY)) opt->opt_flash_size = lowest_flash_size; if (opt->opt_mode == BMP_MODE_SWJ_TEST) { switch (t->core[0]) { From 3cfd8226baaf13892bf56ac42d600f2cacf58850 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Thu, 17 Jun 2021 18:07:00 +0200 Subject: [PATCH 08/31] bmp_libusb: Check only for cmsis_dap if no cable has been found yet. --- src/platforms/hosted/bmp_libusb.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/platforms/hosted/bmp_libusb.c b/src/platforms/hosted/bmp_libusb.c index 8739710d..f7a15fa7 100644 --- a/src/platforms/hosted/bmp_libusb.c +++ b/src/platforms/hosted/bmp_libusb.c @@ -229,8 +229,9 @@ int find_debuggers(BMP_CL_OPTIONS_t *cl_opts,bmp_info_t *info) DEBUG_WARN("BMP in botloader mode found. Restart or reflash!\n"); continue; } - } else if ((type = find_cmsis_dap_interface(dev, info)) != BMP_TYPE_NONE) { - /* type was set by the expression */ + } else if ((type == BMP_TYPE_NONE) && + ((type = find_cmsis_dap_interface(dev, info)) != BMP_TYPE_NONE)) { + /* find_cmsis_dap_interface has set valid type*/ } else if ((strstr(manufacturer, "CMSIS")) || (strstr(product, "CMSIS"))) { type = BMP_TYPE_CMSIS_DAP_V1; } else if (desc.idVendor == VENDOR_ID_STLINK) { From b887a8d355f57f3654c04ff011366ea1469595ab Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sat, 10 Jul 2021 16:48:02 +0200 Subject: [PATCH 09/31] stm32: Portability changes Allow to compile on STM32F0 platform too. --- src/platforms/common/cdcacm.c | 2 ++ src/platforms/stm32/serialno.c | 2 +- src/platforms/stm32/usbuart.c | 34 ++++++++++++++++++++++++++++++++-- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/platforms/common/cdcacm.c b/src/platforms/common/cdcacm.c index 99ee0fd9..e28a5704 100644 --- a/src/platforms/common/cdcacm.c +++ b/src/platforms/common/cdcacm.c @@ -418,7 +418,9 @@ static void dfu_detach_complete(usbd_device *dev, struct usb_setup_data *req) platform_request_boot(); /* Reset core to enter bootloader */ +#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) scb_reset_core(); +#endif } static enum usbd_request_return_codes cdcacm_control_request(usbd_device *dev, diff --git a/src/platforms/stm32/serialno.c b/src/platforms/stm32/serialno.c index 973dee16..a8b2898b 100644 --- a/src/platforms/stm32/serialno.c +++ b/src/platforms/stm32/serialno.c @@ -40,7 +40,7 @@ char *serial_no_read(char *s) uint16_t *uid = (uint16_t *)DESIG_UNIQUE_ID_BASE; # if defined(STM32F4) || defined(STM32F7) int offset = 3; -# elif defined(STM32L0) || defined(STM32F3) +# elif defined(STM32L0) || defined(STM32F0) || defined(STM32F3) int offset = 5; # endif sprintf(s, "%04X%04X%04X", diff --git a/src/platforms/stm32/usbuart.c b/src/platforms/stm32/usbuart.c index 8c04db7b..c7f4a1bd 100644 --- a/src/platforms/stm32/usbuart.c +++ b/src/platforms/stm32/usbuart.c @@ -50,8 +50,12 @@ #define TX_LED_ACT (1 << 0) #define RX_LED_ACT (1 << 1) -#define RX_FIFO_SIZE (128) -#define TX_BUF_SIZE (128) +/* F072 with st_usbfs_v2_usb_drive drops characters at the 64 byte boundary!*/ +#if !defined(USART_DMA_BUF_SIZE) +# define USART_DMA_BUF_SIZE 128 +#endif +#define RX_FIFO_SIZE (USART_DMA_BUF_SIZE) +#define TX_BUF_SIZE (USART_DMA_BUF_SIZE) /* TX double buffer */ static uint8_t buf_tx[TX_BUF_SIZE * 2]; @@ -164,11 +168,19 @@ void usbuart_init(void) /* Enable interrupts */ nvic_set_priority(USBUSART_IRQ, IRQ_PRI_USBUSART); +#if defined(USBUSART_DMA_RXTX_IRQ) + nvic_set_priority(USBUSART_DMA_RXTX_IRQ, IRQ_PRI_USBUSART_DMA); +#else nvic_set_priority(USBUSART_DMA_TX_IRQ, IRQ_PRI_USBUSART_DMA); nvic_set_priority(USBUSART_DMA_RX_IRQ, IRQ_PRI_USBUSART_DMA); +#endif nvic_enable_irq(USBUSART_IRQ); +#if defined(USBUSART_DMA_RXTX_IRQ) + nvic_enable_irq(USBUSART_DMA_RXTX_IRQ); +#else nvic_enable_irq(USBUSART_DMA_TX_IRQ); nvic_enable_irq(USBUSART_DMA_RX_IRQ); +#endif /* Finally enable the USART */ usart_enable(USBUSART); @@ -392,7 +404,11 @@ static void usbuart_run(void) void USBUSART_ISR(void) { +#if defined(USBUSART_DMA_RXTX_IRQ) + nvic_disable_irq(USBUSART_DMA_RXTX_IRQ); +#else nvic_disable_irq(USBUSART_DMA_RX_IRQ); +#endif /* Get IDLE flag and reset interrupt flags */ const bool isIdle = usart_get_flag(USBUSART, USART_FLAG_IDLE); @@ -409,7 +425,11 @@ void USBUSART_ISR(void) usbuart_run(); } +#if defined(USBUSART_DMA_RXTX_IRQ) + nvic_enable_irq(USBUSART_DMA_RXTX_IRQ); +#else nvic_enable_irq(USBUSART_DMA_RX_IRQ); +#endif } void USBUSART_DMA_TX_ISR(void) @@ -449,6 +469,16 @@ void USBUSART_DMA_RX_ISR(void) nvic_enable_irq(USBUSART_IRQ); } +#if defined(USBUSART_DMA_RXTX_ISR) +void USBUSART_DMA_RXTX_ISR(void) +{ + if (dma_get_interrupt_flag(USBUSART_DMA_BUS, USBUSART_DMA_RX_CHAN, DMA_CGIF)) + USBUSART_DMA_RX_ISR(); + if (dma_get_interrupt_flag(USBUSART_DMA_BUS, USBUSART_DMA_TX_CHAN, DMA_CGIF)) + USBUSART_DMA_TX_ISR(); +} +#endif + #ifdef ENABLE_DEBUG enum { RDI_SYS_OPEN = 0x01, From 0c6390307115b48e57deeecf0be8f5eca89604ac Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sat, 10 Jul 2021 22:42:48 +0200 Subject: [PATCH 10/31] adiv5: Recover from bad AP access. E.g. AP1 on a STM32WLE5 points to a ROM table, but access to the ROM table via AP1 hangs forever. - Substantial reduce timeout when wait for a response. Valid access should succeed fast. - Abort AP access to free DP for other accesses - Don't throw exception, only set dp->fault - React on higher level --- src/remote.c | 2 ++ src/target/adiv5.c | 28 ++++++++++++---------------- src/target/adiv5.h | 1 + src/target/adiv5_jtagdp.c | 14 +++++++------- src/target/adiv5_swdp.c | 11 ++++++++--- 5 files changed, 30 insertions(+), 26 deletions(-) diff --git a/src/remote.c b/src/remote.c index 691f1e9e..b86943ee 100644 --- a/src/remote.c +++ b/src/remote.c @@ -144,6 +144,7 @@ void remotePacketProcessSWD(uint8_t i, char *packet) if (i==2) { remote_dp.dp_read = firmware_swdp_read; remote_dp.low_access = firmware_swdp_low_access; + remote_dp.abort = firmware_swdp_abort; swdptap_init(&remote_dp); _respond(REMOTE_RESP_OK, 0); } else { @@ -194,6 +195,7 @@ void remotePacketProcessJTAG(uint8_t i, char *packet) case REMOTE_INIT: /* JS = initialise ============================= */ remote_dp.dp_read = fw_adiv5_jtagdp_read; remote_dp.low_access = fw_adiv5_jtagdp_low_access; + remote_dp.abort = adiv5_jtagdp_abort; jtagtap_init(); _respond(REMOTE_RESP_OK, 0); break; diff --git a/src/target/adiv5.c b/src/target/adiv5.c index 06cb09bb..1994ea67 100644 --- a/src/target/adiv5.c +++ b/src/target/adiv5.c @@ -414,16 +414,11 @@ static void adiv5_component_probe(ADIv5_AP_t *ap, uint32_t addr, int recursion, if (addr == 0) /* No rom table on this AP */ return; volatile uint32_t cidr; - volatile struct exception e; - TRY_CATCH (e, EXCEPTION_TIMEOUT) { - cidr = adiv5_ap_read_id(ap, addr + CIDR0_OFFSET); - } - if (e.type) { - DEBUG_WARN("CIDR read timeout on AP%d, aborting.\n", num_entry); - adiv5_dp_abort(ap->dp, ADIV5_DP_ABORT_DAPABORT); + cidr = adiv5_ap_read_id(ap, addr + CIDR0_OFFSET); + if (ap->dp->fault) { + DEBUG_WARN("CIDR read timeout on AP%d, aborting.\n", ap->apsel); return; } - if ((cidr & ~CID_CLASS_MASK) != CID_PREAMBLE) return; #if defined(ENABLE_DEBUG) @@ -603,6 +598,15 @@ ADIv5_AP_t *adiv5_new_ap(ADIv5_DP_t *dp, uint8_t apsel) if(!tmpap.idr) /* IDR Invalid */ return NULL; + tmpap.csw = adiv5_ap_read(&tmpap, ADIV5_AP_CSW) & + ~(ADIV5_AP_CSW_SIZE_MASK | ADIV5_AP_CSW_ADDRINC_MASK); + + if (tmpap.csw & ADIV5_AP_CSW_TRINPROG) { + DEBUG_WARN("AP %d: Transaction in progress. AP is not be usable!\n", + apsel); + return NULL; + } + /* It's valid to so create a heap copy */ ap = malloc(sizeof(*ap)); if (!ap) { /* malloc failed: heap exhaustion */ @@ -612,14 +616,6 @@ ADIv5_AP_t *adiv5_new_ap(ADIv5_DP_t *dp, uint8_t apsel) memcpy(ap, &tmpap, sizeof(*ap)); - ap->csw = adiv5_ap_read(ap, ADIV5_AP_CSW) & - ~(ADIV5_AP_CSW_SIZE_MASK | ADIV5_AP_CSW_ADDRINC_MASK); - - if (ap->csw & ADIV5_AP_CSW_TRINPROG) { - DEBUG_WARN("AP transaction in progress. Target may not be usable.\n"); - ap->csw &= ~ADIV5_AP_CSW_TRINPROG; - } - #if defined(ENABLE_DEBUG) uint32_t cfg = adiv5_ap_read(ap, ADIV5_AP_CFG); DEBUG_INFO("AP %3d: IDR=%08"PRIx32" CFG=%08"PRIx32" BASE=%08" PRIx32 diff --git a/src/target/adiv5.h b/src/target/adiv5.h index 1d2a2270..5a105432 100644 --- a/src/target/adiv5.h +++ b/src/target/adiv5.h @@ -310,4 +310,5 @@ uint32_t fw_adiv5_jtagdp_read(ADIv5_DP_t *dp, uint16_t addr); uint32_t firmware_swdp_error(ADIv5_DP_t *dp); void firmware_swdp_abort(ADIv5_DP_t *dp, uint32_t abort); +void adiv5_jtagdp_abort(ADIv5_DP_t *dp, uint32_t abort); #endif diff --git a/src/target/adiv5_jtagdp.c b/src/target/adiv5_jtagdp.c index 11f11ed7..2c87dc7c 100644 --- a/src/target/adiv5_jtagdp.c +++ b/src/target/adiv5_jtagdp.c @@ -39,8 +39,6 @@ static uint32_t adiv5_jtagdp_error(ADIv5_DP_t *dp); -static void adiv5_jtagdp_abort(ADIv5_DP_t *dp, uint32_t abort); - void adiv5_jtag_dp_handler(uint8_t jd_index, uint32_t j_idcode) { ADIv5_DP_t *dp = (void*)calloc(1, sizeof(*dp)); @@ -87,23 +85,25 @@ uint32_t fw_adiv5_jtagdp_low_access(ADIv5_DP_t *dp, uint8_t RnW, jtag_dev_write_ir(&jtag_proc, dp->dp_jd_index, APnDP ? IR_APACC : IR_DPACC); - platform_timeout_set(&timeout, 2000); + platform_timeout_set(&timeout, 20); do { jtag_dev_shift_dr(&jtag_proc, dp->dp_jd_index, (uint8_t*)&response, (uint8_t*)&request, 35); ack = response & 0x07; } while(!platform_timeout_is_expired(&timeout) && (ack == JTAGDP_ACK_WAIT)); - if (ack == JTAGDP_ACK_WAIT) - raise_exception(EXCEPTION_TIMEOUT, "JTAG-DP ACK timeout"); - + if (ack == JTAGDP_ACK_WAIT) { + dp->abort(dp, ADIV5_DP_ABORT_DAPABORT); + dp->fault = 1; + return 0; + } if((ack != JTAGDP_ACK_OK)) raise_exception(EXCEPTION_ERROR, "JTAG-DP invalid ACK"); return (uint32_t)(response >> 3); } -static void adiv5_jtagdp_abort(ADIv5_DP_t *dp, uint32_t abort) +void adiv5_jtagdp_abort(ADIv5_DP_t *dp, uint32_t abort) { uint64_t request = (uint64_t)abort << 3; jtag_dev_write_ir(&jtag_proc, dp->dp_jd_index, IR_ABORT); diff --git a/src/target/adiv5_swdp.c b/src/target/adiv5_swdp.c index 66766fb6..9edb5d18 100644 --- a/src/target/adiv5_swdp.c +++ b/src/target/adiv5_swdp.c @@ -93,6 +93,8 @@ int adiv5_swdp_scan(uint32_t targetid) initial_dp->error = firmware_swdp_error; if (!initial_dp->low_access) initial_dp->low_access = firmware_swdp_low_access; + if (!initial_dp->abort) + initial_dp->abort = firmware_swdp_abort; /* DORMANT-> SWD sequence*/ initial_dp->seq_out(0xFFFFFFFF, 32); initial_dp->seq_out(0xFFFFFFFF, 32); @@ -241,7 +243,7 @@ uint32_t firmware_swdp_low_access(ADIv5_DP_t *dp, uint8_t RnW, if((addr & ADIV5_APnDP) && dp->fault) return 0; - platform_timeout_set(&timeout, 2000); + platform_timeout_set(&timeout, 20); do { dp->seq_out(request, 8); ack = dp->seq_in(3); @@ -251,8 +253,11 @@ uint32_t firmware_swdp_low_access(ADIv5_DP_t *dp, uint8_t RnW, } } while (ack == SWDP_ACK_WAIT && !platform_timeout_is_expired(&timeout)); - if (ack == SWDP_ACK_WAIT) - raise_exception(EXCEPTION_TIMEOUT, "SWDP ACK timeout"); + if (ack == SWDP_ACK_WAIT) { + dp->abort(dp, ADIV5_DP_ABORT_DAPABORT); + dp->fault = 1; + return 0; + } if(ack == SWDP_ACK_FAULT) { dp->fault = 1; From 6d6a67b44bda78663c1a46d03a2b5fc1cc9b6e87 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sun, 25 Jul 2021 23:48:35 +0200 Subject: [PATCH 11/31] timeout: Make sure we wait at least the period requested (#900, #902) Fixes bug introduced with last commit( Recover from bad AP access) Let STM32 timers run at 100 Hz against 10 Hz before. Programming STM32F103 failed random (#900) with 20 ms timeout requested against the 100 ms timeout granularity provided up to now. STM32 Firmware only ticked at 10 hertz, so the sequence "low_access", "set timeout", "send out 8 bit command", "read 3 bit result" when reading "wait" and timer increment tick happening during that sequence will already hits the timeout even so only mininal time has elapsed and not the requested timeout. --- src/include/general.h | 6 ++++++ src/platforms/hosted/platform.h | 2 ++ src/platforms/launchpad-icdi/platform.c | 3 --- src/platforms/stm32/timing_stm32.c | 18 ++++++++++++------ src/timing.c | 4 +++- 5 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/include/general.h b/src/include/general.h index ba329d21..25f83a4b 100644 --- a/src/include/general.h +++ b/src/include/general.h @@ -164,5 +164,11 @@ static inline void DEBUG_WIRE(const char *format, ...) #undef MAX #define MAX(x, y) (((x) > (y)) ? (x) : (y)) +#if !defined(SYSTICKHZ) +# define SYSTICKHZ 100 +#endif +#define SYSTICKMS (1000 / SYSTICKHZ) +#define MORSECNT ((SYSTICKHZ / 10) - 1) + #endif diff --git a/src/platforms/hosted/platform.h b/src/platforms/hosted/platform.h index bf3fa141..339fec85 100644 --- a/src/platforms/hosted/platform.h +++ b/src/platforms/hosted/platform.h @@ -10,6 +10,8 @@ void platform_buffer_flush(void); #define SET_IDLE_STATE(x) #define SET_RUN_STATE(x) +#define SYSTICKHZ 1000 + #define VENDOR_ID_BMP 0x1d50 #define PRODUCT_ID_BMP_BL 0x6017 #define PRODUCT_ID_BMP 0x6018 diff --git a/src/platforms/launchpad-icdi/platform.c b/src/platforms/launchpad-icdi/platform.c index d62a8cda..83189192 100644 --- a/src/platforms/launchpad-icdi/platform.c +++ b/src/platforms/launchpad-icdi/platform.c @@ -25,9 +25,6 @@ #include #include -#define SYSTICKHZ 100 -#define SYSTICKMS (1000 / SYSTICKHZ) - #define PLL_DIV_80MHZ 5 #define PLL_DIV_25MHZ 16 diff --git a/src/platforms/stm32/timing_stm32.c b/src/platforms/stm32/timing_stm32.c index dbf5cc3a..9f9c6984 100644 --- a/src/platforms/stm32/timing_stm32.c +++ b/src/platforms/stm32/timing_stm32.c @@ -27,12 +27,14 @@ uint8_t running_status; static volatile uint32_t time_ms; uint32_t swd_delay_cnt = 0; +static int morse_tick; + void platform_timing_init(void) { /* Setup heartbeat timer */ systick_set_clocksource(STK_CSR_CLKSOURCE_AHB_DIV8); /* Interrupt us at 10 Hz */ - systick_set_reload(rcc_ahb_frequency / (8 * 10) ); + systick_set_reload(rcc_ahb_frequency / (8 * SYSTICKHZ) ); /* SYSTICK_IRQ with low priority */ nvic_set_priority(NVIC_SYSTICK_IRQ, 14 << 4); systick_interrupt_enable(); @@ -48,12 +50,16 @@ void platform_delay(uint32_t ms) void sys_tick_handler(void) { - if(running_status) - gpio_toggle(LED_PORT, LED_IDLE_RUN); + time_ms += SYSTICKMS; - time_ms += 100; - - SET_ERROR_STATE(morse_update()); + if (morse_tick >= MORSECNT) { + if(running_status) + gpio_toggle(LED_PORT, LED_IDLE_RUN); + SET_ERROR_STATE(morse_update()); + morse_tick = 0; + } else { + morse_tick++; + } } uint32_t platform_time_ms(void) diff --git a/src/timing.c b/src/timing.c index 1717bf5a..6c9a6da9 100644 --- a/src/timing.c +++ b/src/timing.c @@ -21,10 +21,12 @@ void platform_timeout_set(platform_timeout *t, uint32_t ms) { + if (ms <= SYSTICKMS) + ms = SYSTICKMS; t->time = platform_time_ms() + ms; } bool platform_timeout_is_expired(platform_timeout *t) { - return platform_time_ms() >= t->time; + return platform_time_ms() > t->time; } From 72bd825a607e26bd72161a8a1c36f1eafabf256c Mon Sep 17 00:00:00 2001 From: Thiadmer Riemersma Date: Sat, 31 Jul 2021 15:32:57 +0200 Subject: [PATCH 12/31] Add support for NXP LPC11xx XL series, add 'readuid' command for some MCUs of the LPC11xx series where it was missing; add comments mapping Device IDs to part descriptions. --- src/target/lpc11xx.c | 183 ++++++++++++++++++++++++++----------------- 1 file changed, 111 insertions(+), 72 deletions(-) diff --git a/src/target/lpc11xx.c b/src/target/lpc11xx.c index 5b12e1c6..e8012ea4 100644 --- a/src/target/lpc11xx.c +++ b/src/target/lpc11xx.c @@ -90,40 +90,55 @@ lpc11xx_probe(target *t) uint32_t idcode; /* read the device ID register */ - /* See UM10462 Rev. 5.5 Chapter 20.13.11 Table 377 */ + /* For LPC11xx & LPC11Cxx see UM10398 Rev. 12.4 Chapter 26.5.11 Table 387 + * For LPC11Uxx see UM10462 Rev. 5.5 Chapter 20.13.11 Table 377 + * Nota Bene: the DEVICE_ID register at address 0x400483F4 is not valid + * for: + * 1) the LPC11xx & LPC11Cxx "XL" series, see UM10398 Rev.12.4 Chapter 3.1 + * 2) the LPC11U3x series, see UM10462 Rev.5.5 Chapter 3.1 + * But see the comment for the LPC8xx series below. + */ idcode = target_mem_read32(t, LPC11XX_DEVICE_ID); switch (idcode) { - case 0x041E502B: - case 0x2516D02B: - case 0x0416502B: - case 0x2516902B: /* lpc1111 */ - case 0x2524D02B: - case 0x0425502B: - case 0x2524902B: - case 0x1421102B: /* lpc1112 */ - case 0x0434502B: - case 0x2532902B: - case 0x0434102B: - case 0x2532102B: /* lpc1113 */ - case 0x0444502B: - case 0x2540902B: - case 0x0444102B: - case 0x2540102B: - case 0x1440102B: /* lpc1114 */ - case 0x0A40902B: - case 0x1A40902B: - case 0x00050080: /* lpc1115 and lpc1115L (not the XL version. See UM10398 Rev12.4 Chapter 3.1 ) */ - case 0x1431102B: /* lpc11c22 */ - case 0x1430102B: /* lpc11c24 */ - case 0x095C802B: /* lpc11u12x/201 */ - case 0x295C802B: - case 0x097A802B: /* lpc11u13/201 */ - case 0x297A802B: - case 0x0998802B: /* lpc11u14x/201 */ - case 0x2998802B: - case 0x2972402B: /* lpc11u23/301 */ - case 0x2988402B: /* lpc11u24x/301 */ - case 0x2980002B: /* lpc11u24x/401 */ + case 0x0A07102B: /* LPC1110 - 4K Flash 1K SRAM */ + case 0x1A07102B: /* LPC1110 - 4K Flash 1K SRAM */ + case 0x0A16D02B: /* LPC1111/002 - 8K Flash 2K SRAM */ + case 0x1A16D02B: /* LPC1111/002 - 8K Flash 2K SRAM */ + case 0x041E502B: /* LPC1111/101 - 8K Flash 2K SRAM */ + case 0x2516D02B: /* LPC1111/101/102 - 8K Flash 2K SRAM */ + case 0x0416502B: /* LPC1111/201 - 8K Flash 4K SRAM */ + case 0x2516902B: /* LPC1111/201/202 - 8K Flash 4K SRAM */ + case 0x0A23902B: /* LPC1112/102 - 16K Flash 4K SRAM */ + case 0x1A23902B: /* LPC1112/102 - 16K Flash 4K SRAM */ + case 0x042D502B: /* LPC1112/101 - 16K Flash 2K SRAM */ + case 0x2524D02B: /* LPC1112/101/102 - 16K Flash 2K SRAM */ + case 0x0425502B: /* LPC1112/201 - 16K Flash 4K SRAM */ + case 0x2524902B: /* LPC1112/201/202 - 16K Flash 4K SRAM */ + case 0x0434502B: /* LPC1113/201 - 24K Flash 4K SRAM */ + case 0x2532902B: /* LPC1113/201/202 - 24K Flash 4K SRAM */ + case 0x0434102B: /* LPC1113/301 - 24K Flash 8K SRAM */ + case 0x2532102B: /* LPC1113/301/302 - 24K Flash 8K SRAM */ + case 0x0A40902B: /* LPC1114/102 - 32K Flash 4K SRAM */ + case 0x1A40902B: /* LPC1114/102 - 32K Flash 4K SRAM */ + case 0x0444502B: /* LPC1114/201 - 32K Flash 4K SRAM */ + case 0x2540902B: /* LPC1114/201/202 - 32K Flash 4K SRAM */ + case 0x0444102B: /* LPC1114/301 - 32K Flash 8K SRAM */ + case 0x2540102B: /* LPC1114/301/302 & LPC11D14/302 - 32K Flash 8K SRAM */ + case 0x00050080: /* LPC1115/303 - 64K Flash 8K SRAM (redundant? see UM10398, XL has Device ID at different address) */ + case 0x1421102B: /* LPC11c12/301 - 16K Flash 8K SRAM */ + case 0x1440102B: /* LPC11c14/301 - 32K Flash 8K SRAM */ + case 0x1431102B: /* LPC11c22/301 - 16K Flash 8K SRAM */ + case 0x1430102B: /* LPC11c24/301 - 32K Flash 8K SRAM */ + case 0x095C802B: /* LPC11u12x/201 - 16K Flash 4K SRAM */ + case 0x295C802B: /* LPC11u12x/201 - 16K Flash 4K SRAM */ + case 0x097A802B: /* LPC11u13/201 - 24K Flash 4K SRAM */ + case 0x297A802B: /* LPC11u13/201 - 24K Flash 4K SRAM */ + case 0x0998802B: /* LPC11u14/201 - 32K Flash 4K SRAM */ + case 0x2998802B: /* LPC11u14/201 - 32K Flash 4K SRAM */ + case 0x2954402B: /* LPC11u22/301 - 16K Flash 6K SRAM */ + case 0x2972402B: /* LPC11u23/301 - 24K Flash 6K SRAM */ + case 0x2988402B: /* LPC11u24x/301 - 32K Flash 6K SRAM */ + case 0x2980002B: /* LPC11u24x/401 - 32K Flash 8K SRAM */ t->driver = "LPC11xx"; target_add_ram(t, 0x10000000, 0x2000); lpc11xx_add_flash(t, 0x00000000, 0x20000, 0x1000, IAP_ENTRY_MOST, 0); @@ -152,7 +167,7 @@ lpc11xx_probe(target *t) target_add_ram(t, 0x10000000, 0x2000); /* UM11074/ Flash controller/15.2: The two topmost sectors * contain the initialization code and IAP firmware. - * Do not touch the! */ + * Do not touch them! */ lpc11xx_add_flash(t, 0x00000000, 0x7800, 0x400, IAP_ENTRY_MOST, 0); target_add_commands(t, lpc11xx_cmd_list, "LPC8N04"); return true; @@ -160,91 +175,115 @@ lpc11xx_probe(target *t) if ((t->t_designer != AP_DESIGNER_SPECULAR) && idcode) { DEBUG_INFO("LPC11xx: Unknown IDCODE 0x%08" PRIx32 "\n", idcode); } + /* For LPC802, see UM11045 Rev. 1.4 Chapter 6.6.29 Table 84 + * For LPC804, see UM11065 Rev. 1.0 Chapter 6.6.31 Table 87 + * For LPC81x, see UM10601 Rev. 1.6 Chapter 4.6.33 Table 50 + * For LPC82x, see UM10800 Rev. 1.2 Chapter 5.6.34 Table 55 + * For LPC83x, see UM11021 Rev. 1.1 Chapter 5.6.34 Table 53 + * For LPC84x, see UM11029 Rev. 1.4 Chapter 8.6.49 Table 174 + * + * Not documented, but the DEVICE_ID register at address 0x400483F8 + * for the LPC8xx series is also valid for the LPC11xx "XL" and the + * LPC11U3x variants. + */ idcode = target_mem_read32(t, LPC8XX_DEVICE_ID); switch (idcode) { - case 0x00008021: /* 802M001JDH20 */ - case 0x00008022: /* 802M011JDH20 */ - case 0x00008023: /* 802M001JDH16 */ - case 0x00008024: /* 802M001JHI33 */ + case 0x00008021: /* LPC802M001JDH20 - 16K Flash 2K SRAM */ + case 0x00008022: /* LPC802M011JDH20 */ + case 0x00008023: /* LPC802M001JDH16 */ + case 0x00008024: /* LPC802M001JHI33 */ t->driver = "LPC802"; target_add_ram(t, 0x10000000, 0x800); lpc11xx_add_flash(t, 0x00000000, 0x4000, 0x400, IAP_ENTRY_84x, 2); target_add_commands(t, lpc11xx_cmd_list, "LPC802"); return true; - case 0x00008040: /* 804M101JBD64 */ - case 0x00008041: /* 804M101JDH20 */ - case 0x00008042: /* 804M101JDH24 */ - case 0x00008043: /* 804M111JDH24 */ - case 0x00008044: /* 804M101JHI33 */ + case 0x00008040: /* LPC804M101JBD64 - 32K Flash 4K SRAM */ + case 0x00008041: /* LPC804M101JDH20 */ + case 0x00008042: /* LPC804M101JDH24 */ + case 0x00008043: /* LPC804M111JDH24 */ + case 0x00008044: /* LPC804M101JHI33 */ t->driver = "LPC804"; target_add_ram(t, 0x10000000, 0x1000); lpc11xx_add_flash(t, 0x00000000, 0x8000, 0x400, IAP_ENTRY_84x, 2); target_add_commands(t, lpc11xx_cmd_list, "LPC804"); return true; - case 0x00008100: /* LPC810M021FN8 */ - case 0x00008110: /* LPC811M001JDH16 */ - case 0x00008120: /* LPC812M101JDH16 */ - case 0x00008121: /* LPC812M101JD20 */ - case 0x00008122: /* LPC812M101JDH20 / LPC812M101JTB16 */ + case 0x00008100: /* LPC810M021FN8 - 4K Flash 1K SRAM */ + case 0x00008110: /* LPC811M001JDH16 - 8K Flash 2K SRAM */ + case 0x00008120: /* LPC812M101JDH16 - 16K Flash 4K SRAM */ + case 0x00008121: /* LPC812M101JD20 - 16K Flash 4K SRAM */ + case 0x00008122: /* LPC812M101JDH20 / LPC812M101JTB16 - 16K Flash 4K SRAM */ t->driver = "LPC81x"; target_add_ram(t, 0x10000000, 0x1000); lpc11xx_add_flash(t, 0x00000000, 0x4000, 0x400, IAP_ENTRY_MOST, 0); target_add_commands(t, lpc11xx_cmd_list, "LPC81x"); return true; - case 0x00008221: /* LPC822M101JHI33 */ - case 0x00008222: /* LPC822M101JDH20 */ - case 0x00008241: /* LPC824M201JHI33 */ - case 0x00008242: /* LPC824M201JDH20 */ + case 0x00008221: /* LPC822M101JHI33 - 16K Flash 4K SRAM */ + case 0x00008222: /* LPC822M101JDH20 */ + case 0x00008241: /* LPC824M201JHI33 - 32K Flash 8K SRAM */ + case 0x00008242: /* LPC824M201JDH20 */ t->driver = "LPC82x"; target_add_ram(t, 0x10000000, 0x2000); lpc11xx_add_flash(t, 0x00000000, 0x8000, 0x400, IAP_ENTRY_MOST, 0); target_add_commands(t, lpc11xx_cmd_list, "LPC82x"); return true; - case 0x00008322: /* LPC832M101FDH20 */ + case 0x00008322: /* LPC832M101FDH20 - 16K Flash 4K SRAM */ t->driver = "LPC832"; target_add_ram(t, 0x10000000, 0x1000); lpc11xx_add_flash(t, 0x00000000, 0x4000, 0x400, IAP_ENTRY_MOST, 0); target_add_commands(t, lpc11xx_cmd_list, "LPC832"); return true; - case 0x00008341: /* LPC8341201FHI33 */ + case 0x00008341: /* LPC834M101FHI33 - 32K Flash 4K SRAM */ t->driver = "LPC834"; target_add_ram(t, 0x10000000, 0x1000); lpc11xx_add_flash(t, 0x00000000, 0x8000, 0x400, IAP_ENTRY_MOST, 0); target_add_commands(t, lpc11xx_cmd_list, "LPC834"); return true; - case 0x00008441: - case 0x00008442: - case 0x00008443: /* UM11029 Rev.1.4 list 8442 */ - case 0x00008444: + case 0x00008441: /* LPC844M201JBD64 - 64K Flash 8K SRAM */ + case 0x00008442: /* LPC844M201JBD48 */ + case 0x00008443: /* LPC844M201JHI48, note UM11029 Rev.1.4 table 29 is wrong, see table 174 (in same manual) */ + case 0x00008444: /* LPC844M201JHI33 */ t->driver = "LPC844"; target_add_ram(t, 0x10000000, 0x2000); lpc11xx_add_flash(t, 0x00000000, 0x10000, 0x400, IAP_ENTRY_84x, 0); + target_add_commands(t, lpc11xx_cmd_list, "LPC844"); return true; - case 0x00008451: - case 0x00008452: - case 0x00008453: - case 0x00008454: + case 0x00008451: /* LPC845M301JBD64 - 64K Flash 16K SRAM */ + case 0x00008452: /* LPC845M301JBD48 */ + case 0x00008453: /* LPC845M301JHI48 */ + case 0x00008454: /* LPC845M301JHI33 */ t->driver = "LPC845"; target_add_ram(t, 0x10000000, 0x4000); lpc11xx_add_flash(t, 0x00000000, 0x10000, 0x400, IAP_ENTRY_84x, 0); + target_add_commands(t, lpc11xx_cmd_list, "LPC845"); return true; - case 0x0003D440: /* LPC11U34/311 */ - case 0x0001cc40: /* LPC11U34/421 */ - case 0x0001BC40: /* LPC11U35/401 */ - case 0x0000BC40: /* LPC11U35/501 */ - case 0x00019C40: /* LPC11U36/401 */ - case 0x00017C40: /* LPC11U37FBD48/401 */ - case 0x00007C44: /* LPC11U37HFBD64/401 */ - case 0x00007C40: /* LPC11U37FBD64/501 */ + case 0x0003D440: /* LPC11U34/311 - 40K Flash 8K SRAM */ + case 0x0001cc40: /* LPC11U34/421 - 48K Flash 8K SRAM */ + case 0x0001BC40: /* LPC11U35/401 - 64K Flash 8K SRAM */ + case 0x0000BC40: /* LPC11U35/501 - 64K Flash 8K SRAM */ + case 0x00019C40: /* LPC11U36/401 - 96K Flash 8K SRAM */ + case 0x00017C40: /* LPC11U37FBD48/401 - 128K Flash 8K SRAM */ + case 0x00007C44: /* LPC11U37HFBD64/401 */ + case 0x00007C40: /* LPC11U37FBD64/501 */ t->driver = "LPC11U3x"; target_add_ram(t, 0x10000000, 0x2000); lpc11xx_add_flash(t, 0x00000000, 0x20000, 0x1000, IAP_ENTRY_MOST, 0); + target_add_commands(t, lpc11xx_cmd_list, "LPC11U3x"); return true; - case 0x00040070: /* LPC1114/333 */ - case 0x00050080: /* lpc1115XL */ - t->driver = "LPC1100XL"; + case 0x00010013: /* LPC1111/103 - 8K Flash 2K SRAM */ + case 0x00010012: /* LPC1111/203 - 8K Flash 4K SRAM */ + case 0x00020023: /* LPC1112/103 - 16K Flash 2K SRAM */ + case 0x00020022: /* LPC1112/203 - 16K Flash 4K SRAM */ + case 0x00030030: /* LPC1113/303 - 24K Flash 8K SRAM */ + case 0x00030032: /* LPC1113/203 - 24K Flash 4K SRAM */ + case 0x00040040: /* LPC1114/303 - 32K Flash 8K SRAM */ + case 0x00040042: /* LPC1114/203 - 32K Flash 4K SRAM */ + case 0x00040060: /* LPC1114/323 - 48K Flash 8K SRAM */ + case 0x00040070: /* LPC1114/333 - 56K Flash 8K SRAM */ + case 0x00050080: /* LPC1115/303 - 64K Flash 8K SRAM */ + t->driver = "LPC11xx-XL"; target_add_ram(t, 0x10000000, 0x2000); lpc11xx_add_flash(t, 0x00000000, 0x20000, 0x1000, IAP_ENTRY_MOST, 0); + target_add_commands(t, lpc11xx_cmd_list, "LPC11xx-XL"); return true; } if (idcode) { From be534a9c5e6630bbf3cba1269a482d276ac0de85 Mon Sep 17 00:00:00 2001 From: Thiadmer Riemersma Date: Fri, 6 Aug 2021 22:28:15 +0200 Subject: [PATCH 13/31] Turn error LED off after successful attach to target (error LED blinks on 'target lost'). --- src/gdb_main.c | 18 +++++++++++------- src/morse.c | 2 +- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/gdb_main.c b/src/gdb_main.c index cb691124..19bcc31a 100644 --- a/src/gdb_main.c +++ b/src/gdb_main.c @@ -284,6 +284,8 @@ int gdb_main_loop(struct target_controller *tc, bool in_syscall) else if(last_target) { cur_target = target_attach(last_target, &gdb_controller); + if(cur_target) + morse(NULL, false); target_reset(cur_target); } break; @@ -428,9 +430,10 @@ handle_v_packet(char *packet, int plen) if (sscanf(packet, "vAttach;%08lx", &addr) == 1) { /* Attach to remote target processor */ cur_target = target_attach_n(addr, &gdb_controller); - if(cur_target) + if(cur_target) { + morse(NULL, false); gdb_putpacketz("T05"); - else + } else gdb_putpacketz("E01"); } else if (!strncmp(packet, "vRun", 4)) { @@ -470,12 +473,13 @@ handle_v_packet(char *packet, int plen) cur_target = target_attach(last_target, &gdb_controller); - /* If we were able to attach to the target again */ - if (cur_target) { + /* If we were able to attach to the target again */ + if (cur_target) { target_set_cmdline(cur_target, cmdline); - target_reset(cur_target); - gdb_putpacketz("T05"); - } else gdb_putpacketz("E01"); + target_reset(cur_target); + morse(NULL, false); + gdb_putpacketz("T05"); + } else gdb_putpacketz("E01"); } else gdb_putpacketz("E01"); diff --git a/src/morse.c b/src/morse.c index 0fb947a6..fd3b6486 100644 --- a/src/morse.c +++ b/src/morse.c @@ -64,7 +64,7 @@ void morse(const char *msg, char repeat) DEBUG_WARN("%s\n", msg); (void) repeat; #else -morse_msg = morse_ptr = msg; + morse_msg = morse_ptr = msg; morse_repeat = repeat; #endif } From 5eb43a1ddbb8e5b6aeb51bc8b82bcd4649384d98 Mon Sep 17 00:00:00 2001 From: aam335 Date: Mon, 2 Aug 2021 22:42:00 +0300 Subject: [PATCH 14/31] platforms: stm32f4x1 blackpillv2 as variant of f4discovery Compile as make PROBE_HOST=f4discovery BLACKPILL=1 --- src/platforms/f4discovery/Makefile.inc | 9 ++- src/platforms/f4discovery/Readme.md | 52 +++++++++++++++++ src/platforms/f4discovery/platform.c | 81 ++++++++++++++++++++------ src/platforms/f4discovery/platform.h | 51 ++++++++++++++++ src/platforms/stm32/blackpillv2.ld | 28 +++++++++ 5 files changed, 202 insertions(+), 19 deletions(-) create mode 100644 src/platforms/stm32/blackpillv2.ld diff --git a/src/platforms/f4discovery/Makefile.inc b/src/platforms/f4discovery/Makefile.inc index c1771508..ae6b75a6 100644 --- a/src/platforms/f4discovery/Makefile.inc +++ b/src/platforms/f4discovery/Makefile.inc @@ -8,8 +8,15 @@ CFLAGS += -Istm32/include -mcpu=cortex-m4 -mthumb \ -DSTM32F4 -I../libopencm3/include \ -Iplatforms/stm32 +ifeq ($(BLACKPILL), 1) +LINKER_SCRIPT=platforms/stm32/blackpillv2.ld +CFLAGS += -DBLACKPILL=1 +else +LINKER_SCRIPT=platforms/stm32/f4discovery.ld +endif + LDFLAGS_BOOT = -lopencm3_stm32f4 \ - -Wl,-T,platforms/stm32/f4discovery.ld -nostartfiles -lc -lnosys \ + -Wl,-T,$(LINKER_SCRIPT) -nostartfiles -lc -lnosys \ -Wl,-Map=mapfile -mthumb -mcpu=cortex-m4 -Wl,-gc-sections \ -mfloat-abi=hard -mfpu=fpv4-sp-d16 \ -L../libopencm3/lib diff --git a/src/platforms/f4discovery/Readme.md b/src/platforms/f4discovery/Readme.md index a3dae25f..cef87483 100644 --- a/src/platforms/f4discovery/Readme.md +++ b/src/platforms/f4discovery/Readme.md @@ -11,3 +11,55 @@ PC6: TDO/TRACESWO
PC1: TRST
PC8: SRST
+ +# Alternate build for stm32f401 stm32f411 MiniF4 aka BlackPillV2 boards. + +https://github.com/WeActTC/MiniSTM32F4x1 + +## Connections: + +* JTAG/SWD + * PA1: TDI + * PA13: TMS/SWDIO + * PA14: TCK/SWCLK + * PB3: TDO/TRACESWO + * PB5: TRST + * PB4: SRST + +* USB USART + * PB6: USART1 TX (usbuart_xxx) + * PB7: USART1 RX (usbuart_xxx) + +* +3V3. + * PB8 - turn on IRLML5103 transistor + +How to Build +======================================== +``` +cd blackmagic +make clean +make PROBE_HOST=f4discovery BLACKPILL=1 +``` + +How to Flash with dfu +======================================== +* After build: + * 1) `apt install dfu-util` + * 2) Force the F4 into system bootloader mode by jumpering "BOOT0" to "3V3" and "PB2/BOOT1" to "GND" and reset (RESET button). System bootloader should appear. + * 3) `dfu-util -a 0 --dfuse-address 0x08000000 -D blackmagic.bin` + +To exit from dfu mode press a "key" and "reset", release reset. BMP firmware should appear + + +10 pin male from pins +======================================== + +| PB3/TDO | PB7/RX | PB8/TX | X | PA1/TDI | +| -------- | ----------- | ---------- | ---------- | ------- | +| PB4/SRST | +3V3/PB8 SW | PA13/SWDIO | PA14/SWCLK | GND | + +SWJ frequency setting +==================================== +https://github.com/blacksphere/blackmagic/pull/783#issue-529197718 + +`mon freq 900k` helps at most diff --git a/src/platforms/f4discovery/platform.c b/src/platforms/f4discovery/platform.c index 2eb6bcbc..4233f10a 100644 --- a/src/platforms/f4discovery/platform.c +++ b/src/platforms/f4discovery/platform.c @@ -37,20 +37,32 @@ #include #include +#ifdef BLACKPILL +#include +#endif + + jmp_buf fatal_error_jmpbuf; extern char _ebss[]; void platform_init(void) { volatile uint32_t *magic = (uint32_t *)_ebss; - /* Check the USER button*/ + /* Enable GPIO peripherals */ rcc_periph_clock_enable(RCC_GPIOA); + rcc_periph_clock_enable(RCC_GPIOC); +#ifdef BLACKPILL + rcc_periph_clock_enable(RCC_GPIOB); +#else + rcc_periph_clock_enable(RCC_GPIOD); +#endif + /* Check the USER button*/ if (gpio_get(GPIOA, GPIO0) || - ((magic[0] == BOOTMAGIC0) && (magic[1] == BOOTMAGIC1))) { + ((magic[0] == BOOTMAGIC0) && (magic[1] == BOOTMAGIC1))) + { magic[0] = 0; magic[1] = 0; /* Assert blue LED as indicator we are in the bootloader */ - rcc_periph_clock_enable(RCC_GPIOD); gpio_mode_setup(LED_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED_BOOTLOADER); gpio_set(LED_PORT, LED_BOOTLOADER); @@ -58,44 +70,65 @@ void platform_init(void) As we just come out of reset, no other deinit is needed!*/ rcc_periph_clock_enable(RCC_SYSCFG); SYSCFG_MEMRM &= ~3; - SYSCFG_MEMRM |= 1; + SYSCFG_MEMRM |= 1; scb_reset_core(); } - +#ifdef BLACKPILL + rcc_clock_setup_pll(&rcc_hse_25mhz_3v3[RCC_CLOCK_3V3_84MHZ]); +#else rcc_clock_setup_pll(&rcc_hse_8mhz_3v3[RCC_CLOCK_3V3_168MHZ]); +#endif /* Enable peripherals */ rcc_periph_clock_enable(RCC_OTGFS); - rcc_periph_clock_enable(RCC_GPIOC); - rcc_periph_clock_enable(RCC_GPIOD); rcc_periph_clock_enable(RCC_CRC); /* Set up USB Pins and alternate function*/ - gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO9 | GPIO11 | GPIO12); + gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO9 | GPIO11 | GPIO12); gpio_set_af(GPIOA, GPIO_AF10, GPIO9 | GPIO10 | GPIO11 | GPIO12); - GPIOC_OSPEEDR &=~0xF30; +#ifdef BLACKPILL + GPIOA_OSPEEDR &= 0x3C00000C; + GPIOA_OSPEEDR |= 0x28000008; +#else + GPIOC_OSPEEDR &= ~0xF30; GPIOC_OSPEEDR |= 0xA20; +#endif + gpio_mode_setup(JTAG_PORT, GPIO_MODE_OUTPUT, - GPIO_PUPD_NONE, - TCK_PIN | TDI_PIN); + GPIO_PUPD_NONE, + TCK_PIN | TDI_PIN); gpio_mode_setup(JTAG_PORT, GPIO_MODE_INPUT, - GPIO_PUPD_NONE, TMS_PIN); + GPIO_PUPD_NONE, TMS_PIN); gpio_set_output_options(JTAG_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, TCK_PIN | TDI_PIN | TMS_PIN); gpio_mode_setup(TDO_PORT, GPIO_MODE_INPUT, - GPIO_PUPD_NONE, - TDO_PIN); + GPIO_PUPD_NONE, + TDO_PIN); gpio_set_output_options(TDO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, - TDO_PIN| TMS_PIN); + TDO_PIN | TMS_PIN); gpio_mode_setup(LED_PORT, GPIO_MODE_OUTPUT, - GPIO_PUPD_NONE, - LED_UART | LED_IDLE_RUN | LED_ERROR | LED_BOOTLOADER); + GPIO_PUPD_NONE, + LED_IDLE_RUN | LED_ERROR | LED_BOOTLOADER); + + gpio_mode_setup(LED_PORT_UART, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED_UART); + +#ifdef PLATFORM_HAS_POWER_SWITCH + gpio_set(PWR_BR_PORT, PWR_BR_PIN); + gpio_mode_setup(PWR_BR_PORT, GPIO_MODE_OUTPUT, + GPIO_PUPD_NONE, + PWR_BR_PIN); +#endif platform_timing_init(); usbuart_init(); cdcacm_init(); +#ifdef BLACKPILL + // https://github.com/libopencm3/libopencm3/pull/1256#issuecomment-779424001 + OTG_FS_GCCFG |= OTG_GCCFG_NOVBUSSENS | OTG_GCCFG_PWRDWN; + OTG_FS_GCCFG &= ~(OTG_GCCFG_VBUSBSEN | OTG_GCCFG_VBUSASEN); +#endif } void platform_srst_set_val(bool assert) { (void)assert; } @@ -108,8 +141,20 @@ const char *platform_target_voltage(void) void platform_request_boot(void) { - uint32_t *magic = (uint32_t *) &_ebss; + uint32_t *magic = (uint32_t *)&_ebss; magic[0] = BOOTMAGIC0; magic[1] = BOOTMAGIC1; scb_reset_system(); } + +#ifdef PLATFORM_HAS_POWER_SWITCH +bool platform_target_get_power(void) +{ + return !gpio_get(PWR_BR_PORT, PWR_BR_PIN); +} + +void platform_target_set_power(bool power) +{ + gpio_set_val(PWR_BR_PORT, PWR_BR_PIN, !power); +} +#endif \ No newline at end of file diff --git a/src/platforms/f4discovery/platform.h b/src/platforms/f4discovery/platform.h index a1a06f88..0865e476 100644 --- a/src/platforms/f4discovery/platform.h +++ b/src/platforms/f4discovery/platform.h @@ -31,6 +31,55 @@ #include #define PLATFORM_HAS_TRACESWO +#ifdef BLACKPILL +#define PLATFORM_IDENT "(F4Discovery/BlackPillV2) " +/* Important pin mappings for STM32 implementation: + * JTAG/SWD + * PA1: TDI
+ * PA13: TMS/SWDIO
+ * PA14: TCK/SWCLK
+ * PB3: TDO/TRACESWO
+ * PB5: TRST
+ * PB4: SRST
+ * USB USART + * PB6: USART1 TX + * PB7: USART1 RX + * +3V3 + * PB8 - turn on IRLML5103 transistor + * Force DFU mode button: PA0 + */ + +/* Hardware definitions... */ +#define JTAG_PORT GPIOA +#define TDI_PORT JTAG_PORT +#define TMS_PORT JTAG_PORT +#define TCK_PORT JTAG_PORT +#define TDO_PORT GPIOB +#define TDI_PIN GPIO1 +#define TMS_PIN GPIO13 +#define TCK_PIN GPIO14 +#define TDO_PIN GPIO3 + +#define SWDIO_PORT JTAG_PORT +#define SWCLK_PORT JTAG_PORT +#define SWDIO_PIN TMS_PIN +#define SWCLK_PIN TCK_PIN + +#define TRST_PORT GPIOB +#define TRST_PIN GPIO5 +#define SRST_PORT GPIOB +#define SRST_PIN GPIO4 + +#define PWR_BR_PORT GPIOB +#define PWR_BR_PIN GPIO8 + +#define LED_PORT GPIOC +#define LED_PORT_UART GPIOA +#define LED_UART GPIO1 +#define LED_IDLE_RUN GPIO15 +#define LED_ERROR GPIO14 +#define LED_BOOTLOADER GPIO13 +#else #define PLATFORM_IDENT "(F4Discovery) " /* Important pin mappings for STM32 implementation: @@ -78,6 +127,8 @@ #define LED_IDLE_RUN GPIO13 #define LED_ERROR GPIO14 #define LED_BOOTLOADER GPIO15 +#endif + #define BOOTMAGIC0 0xb007da7a #define BOOTMAGIC1 0xbaadfeed diff --git a/src/platforms/stm32/blackpillv2.ld b/src/platforms/stm32/blackpillv2.ld new file mode 100644 index 00000000..4dbc774f --- /dev/null +++ b/src/platforms/stm32/blackpillv2.ld @@ -0,0 +1,28 @@ +/* + * This file is part of the libopenstm32 project. + * + * Copyright (C) 2010 Thomas Otto + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 512K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 96K +} + +/* Include the common ld script from libopenstm32. */ +INCLUDE cortex-m-generic.ld From c7bc4b6a5ddeee32c5a8763b2e90f292a53ece7f Mon Sep 17 00:00:00 2001 From: Thiadmer Riemersma Date: Wed, 11 Aug 2021 15:07:14 +0200 Subject: [PATCH 15/31] Bug fix in Flash erase function for LPC MCUs. --- src/target/lpc_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/target/lpc_common.c b/src/target/lpc_common.c index 7b6b2efc..f70c0d6e 100644 --- a/src/target/lpc_common.c +++ b/src/target/lpc_common.c @@ -184,7 +184,7 @@ int lpc_flash_erase(struct target_flash *tf, target_addr addr, size_t len) if (f->reserved_pages && ((addr + len) >= tf->length - 0x400) ) { last_full_sector -= 1; } - if (start >= last_full_sector) { + 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; From 0d78331149cbc1b1a67af47df2ce3dfff675b5c0 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Fri, 13 Aug 2021 19:45:41 +0200 Subject: [PATCH 16/31] remote/jtag_tdi_tdo_seq: Fix wrong bitmask calculation. --- src/remote.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/remote.c b/src/remote.c index b86943ee..ea093212 100644 --- a/src/remote.c +++ b/src/remote.c @@ -228,7 +228,8 @@ void remotePacketProcessJTAG(uint8_t i, char *packet) jtag_proc.jtagtap_tdi_tdo_seq((void *)&DO, (packet[1]==REMOTE_TDITDO_TMS), (void *)&DI, ticks); /* Mask extra bits on return value... */ - DO &= (1LL << (ticks + 1)) - 1; + if (ticks < 64) + DO &= (1LL << ticks) - 1; _respond(REMOTE_RESP_OK, DO); } From 1845d71f00dda59849254bbddb3c4c00f556d35c Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Mon, 28 Dec 2020 14:31:49 +0100 Subject: [PATCH 17/31] jtag_scan: Deliver full idcode to the handler. --- src/target/jtag_scan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/target/jtag_scan.c b/src/target/jtag_scan.c index 127f1ffd..88a8a576 100644 --- a/src/target/jtag_scan.c +++ b/src/target/jtag_scan.c @@ -215,7 +215,7 @@ int jtag_scan(const uint8_t *irlens) jtag_devs[i].jd_descr = dev_descr[j].descr; /* Call handler to initialise/probe device further */ if(dev_descr[j].handler) - dev_descr[j].handler(i, dev_descr[j].idcode); + dev_descr[j].handler(i, jtag_devs[i].jd_idcode); break; } From cfdf55855e1589613cf0f19fb407cbdee5b4de9e Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Wed, 30 Dec 2020 17:04:46 +0100 Subject: [PATCH 18/31] ftdi_bmp: Export and use reset functions. --- src/platforms/hosted/ftdi_bmp.h | 4 ++++ src/platforms/hosted/platform.c | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/platforms/hosted/ftdi_bmp.h b/src/platforms/hosted/ftdi_bmp.h index 931b1aa6..4ce9090a 100644 --- a/src/platforms/hosted/ftdi_bmp.h +++ b/src/platforms/hosted/ftdi_bmp.h @@ -114,6 +114,8 @@ void libftdi_jtagtap_tdi_tdo_seq( bool libftdi_swd_possible(bool *do_mpsse, bool *direct_bb_swd) {return false;}; void libftdi_max_frequency_set(uint32_t freq) {}; uint32_t libftdi_max_frequency_get(void) {return 0;}; +void libftdi_srst_set_val(bool assert){}; +bool libftdi_srst_get_val(void) { return false}; # pragma GCC diagnostic pop #else #include @@ -134,6 +136,8 @@ void libftdi_jtagtap_tdi_tdo_seq( bool libftdi_swd_possible(bool *do_mpsse, bool *direct_bb_swd); void libftdi_max_frequency_set(uint32_t freq); uint32_t libftdi_max_frequency_get(void); +void libftdi_srst_set_val(bool assert); +bool libftdi_srst_get_val(void); #endif #define MPSSE_SK 1 diff --git a/src/platforms/hosted/platform.c b/src/platforms/hosted/platform.c index a408fde4..df657d5f 100644 --- a/src/platforms/hosted/platform.c +++ b/src/platforms/hosted/platform.c @@ -299,6 +299,8 @@ void platform_srst_set_val(bool assert) return remote_srst_set_val(assert); case BMP_TYPE_JLINK: return jlink_srst_set_val(&info, assert); + case BMP_TYPE_LIBFTDI: + return libftdi_srst_set_val(assert); default: break; } @@ -313,6 +315,8 @@ bool platform_srst_get_val(void) return stlink_srst_get_val(); case BMP_TYPE_JLINK: return jlink_srst_get_val(&info); + case BMP_TYPE_LIBFTDI: + return libftdi_srst_get_val(); default: break; } From 36836d0746c6cdd74abbb41e3a8d1615b7ebf574 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Wed, 30 Dec 2020 17:03:46 +0100 Subject: [PATCH 19/31] ftdi_bmp: Fix setting bits and FTDIJTAG srst. --- src/platforms/hosted/ftdi_bmp.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/platforms/hosted/ftdi_bmp.c b/src/platforms/hosted/ftdi_bmp.c index f05a86b7..f6ed7eed 100644 --- a/src/platforms/hosted/ftdi_bmp.c +++ b/src/platforms/hosted/ftdi_bmp.c @@ -123,8 +123,8 @@ cable_desc_t cable_desc[] = { .init.ddr_low = PIN4, .init.data_high = PIN4 | PIN3 | PIN2, .init.ddr_high = PIN4 | PIN3 | PIN2 | PIN1 | PIN0, - .assert_srst.data_high = ~PIN2, - .deassert_srst.data_high = PIN2, + .assert_srst.data_high = ~PIN3, + .deassert_srst.data_high = PIN3, .srst_get_port_cmd = GET_BITS_LOW, .srst_get_pin = PIN6, .description = "FTDIJTAG", @@ -421,11 +421,11 @@ static void libftdi_set_data(data_desc_t* data) if ((data->data_low) || (data->ddr_low)) { if (data->data_low > 0) active_state.data_low |= (data->data_low & 0xff); - else + else if (data->data_low < 0) active_state.data_low &= (data->data_low & 0xff); if (data->ddr_low > 0) active_state.ddr_low |= (data->ddr_low & 0xff); - else + else if (data->ddr_low < 0) active_state.ddr_low &= (data->ddr_low & 0xff); cmd[index++] = SET_BITS_LOW; cmd[index++] = active_state.data_low; @@ -434,11 +434,11 @@ static void libftdi_set_data(data_desc_t* data) if ((data->data_high) || (data->ddr_high)) { if (data->data_high > 0) active_state.data_high |= (data->data_high & 0xff); - else + else if (data->data_high < 0) active_state.data_high &= (data->data_high & 0xff); if (data->ddr_high > 0) active_state.ddr_high |= (data->ddr_high & 0xff); - else + else if (data->ddr_high < 0) active_state.ddr_high &= (data->ddr_high & 0xff); cmd[index++] = SET_BITS_HIGH; cmd[index++] = active_state.data_high; From 8084a7563420b13de83b351f6f1a658339a3b650 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Wed, 30 Dec 2020 17:05:47 +0100 Subject: [PATCH 20/31] cl_utils: Allow Hardware reset from the command line --- src/platforms/pc/cl_utils.c | 25 ++++++++++++++++++------- src/platforms/pc/cl_utils.h | 1 + 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/platforms/pc/cl_utils.c b/src/platforms/pc/cl_utils.c index 85e5caf4..93605853 100644 --- a/src/platforms/pc/cl_utils.c +++ b/src/platforms/pc/cl_utils.c @@ -24,6 +24,7 @@ #include "general.h" #include +#include #include #include #include @@ -151,10 +152,10 @@ static void cl_help(char **argv) DEBUG_WARN("\tDefault mode is to start the debug server at :2000\n"); DEBUG_WARN("\t-j\t\t: Use JTAG. SWD is default.\n"); DEBUG_WARN("\t-f\t\t: Set minimum high and low times of SWJ waveform.\n"); - DEBUG_WARN("\t-C\t\t: Connect under reset\n"); + DEBUG_WARN("\t-C\t\t: Connect under hardware reset\n"); DEBUG_WARN("\t-t\t\t: Scan SWD or JTAG and display information about \n" "\t\t\t connected devices\n"); - DEBUG_WARN("\t-T\t\t: Continious read/write-back some value to allow\n" + DEBUG_WARN("\t-T\t\t: Continuous read/write-back some value to allow\n" "\t\t\t timing insection of SWJ. Abort with ^C\n"); DEBUG_WARN("\t-e\t\t: Assume \"resistor SWD connection\" on FTDI: TDI\n" "\t\t\t connected to TMS, TDO to TDI with eventual resistor\n"); @@ -164,7 +165,7 @@ static void cl_help(char **argv) "\t\t\t with -w to verify right after programming.\n"); DEBUG_WARN("\t-r\t\t: Read flash and write to binary file\n"); DEBUG_WARN("\t-p\t\t: Supplies power to the target (where applicable)\n"); - DEBUG_WARN("\t-R\t\t: Reset device\n"); + DEBUG_WARN("\t-R[h]\t\t: Reset device. Default via SWJ or by hardware(h)\n"); DEBUG_WARN("\t-H\t\t: Do not use high level commands (BMP-Remote)\n"); DEBUG_WARN("\t-m \t: Use (target)id for SWD multi-drop.\n"); DEBUG_WARN("\t-M \t: Run target specific monitor commands. Quote multi\n"); @@ -185,7 +186,7 @@ void cl_init(BMP_CL_OPTIONS_t *opt, int argc, char **argv) opt->opt_flash_size = 0xffffffff; opt->opt_flash_start = 0xffffffff; opt->opt_max_swj_frequency = 4000000; - while((c = getopt(argc, argv, "eEhHv:d:f:s:I:c:Cln:m:M:wVtTa:S:jpP:rR")) != -1) { + while((c = getopt(argc, argv, "eEhHv:d:f:s:I:c:Cln:m:M:wVtTa:S:jpP:rR::")) != -1) { switch(c) { case 'c': if (optarg) @@ -268,7 +269,10 @@ void cl_init(BMP_CL_OPTIONS_t *opt, int argc, char **argv) opt->opt_mode = BMP_MODE_FLASH_READ; break; case 'R': - opt->opt_mode = BMP_MODE_RESET; + if ((optarg) && (tolower(optarg[0]) == 'h')) + opt->opt_mode = BMP_MODE_RESET_HW; + else + opt->opt_mode = BMP_MODE_RESET; break; case 'p': opt->opt_tpwr = true; @@ -321,7 +325,8 @@ void cl_init(BMP_CL_OPTIONS_t *opt, int argc, char **argv) /* Checks */ if ((opt->opt_flash_file) && ((opt->opt_mode == BMP_MODE_TEST ) || (opt->opt_mode == BMP_MODE_SWJ_TEST) || - (opt->opt_mode == BMP_MODE_RESET))) { + (opt->opt_mode == BMP_MODE_RESET) || + (opt->opt_mode == BMP_MODE_RESET_HW))) { DEBUG_WARN("Ignoring filename in reset/test mode\n"); opt->opt_flash_file = NULL; } @@ -352,6 +357,12 @@ int cl_execute(BMP_CL_OPTIONS_t *opt) platform_target_set_power(true); platform_delay(500); } + if (opt->opt_mode == BMP_MODE_RESET_HW) { + platform_srst_set_val(true); + platform_delay(1); + platform_srst_set_val(false); + return 0; + } if (opt->opt_connect_under_reset) DEBUG_INFO("Connecting under reset\n"); connect_assert_srst = opt->opt_connect_under_reset; @@ -466,7 +477,7 @@ int cl_execute(BMP_CL_OPTIONS_t *opt) map.size = opt->opt_flash_size; if (opt->opt_mode == BMP_MODE_RESET) { target_reset(t); - } else if (opt->opt_mode == BMP_MODE_FLASH_ERASE) { + } else if (opt->opt_mode == BMP_MODE_FLASH_ERASE) { DEBUG_INFO("Erase %zu bytes at 0x%08" PRIx32 "\n", opt->opt_flash_size, opt->opt_flash_start); unsigned int erased = target_flash_erase(t, opt->opt_flash_start, diff --git a/src/platforms/pc/cl_utils.h b/src/platforms/pc/cl_utils.h index 4a0c1e20..ff43610d 100644 --- a/src/platforms/pc/cl_utils.h +++ b/src/platforms/pc/cl_utils.h @@ -30,6 +30,7 @@ enum bmp_cl_mode { BMP_MODE_DEBUG, BMP_MODE_TEST, BMP_MODE_RESET, + BMP_MODE_RESET_HW, BMP_MODE_FLASH_ERASE, BMP_MODE_FLASH_WRITE, BMP_MODE_FLASH_WRITE_VERIFY, From e1a1865de94cf1c38abad8816371bf7dc059f454 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sat, 17 Jul 2021 20:59:48 +0200 Subject: [PATCH 21/31] remote/jtagtap_tdi_tdo_seq: Split up large transactions. FIXME: One remote transaction still can only do up to 64 ticks, leaving room for speed enhancement with larger transactions. Firmware assumes (1LL << 65) == 0LL ! --- src/platforms/hosted/remote_jtagtap.c | 62 +++++++++++++++++---------- 1 file changed, 40 insertions(+), 22 deletions(-) diff --git a/src/platforms/hosted/remote_jtagtap.c b/src/platforms/hosted/remote_jtagtap.c index 601a3e90..a92a253c 100644 --- a/src/platforms/hosted/remote_jtagtap.c +++ b/src/platforms/hosted/remote_jtagtap.c @@ -104,35 +104,53 @@ static void jtagtap_tms_seq(uint32_t MS, int ticks) } } +/* At least up to v1.7.1-233, remote handles only up to 32 ticks in one + * call. Break up large calls. + * + * FIXME: Provide and test faster call and keep fallback + * for old firmware + */ static void jtagtap_tdi_tdo_seq( uint8_t *DO, const uint8_t final_tms, const uint8_t *DI, int ticks) { uint8_t construct[REMOTE_MAX_MSG_SIZE]; int s; - uint64_t DIl=*(uint64_t *)DI; + if(!ticks || (!DI && !DO)) + return; + uint64_t *DIl = (uint64_t *)DI; + uint64_t *DOl = (uint64_t *)DO; + while (ticks) { + int chunk; + if (ticks < 65) + chunk = ticks; + else { + chunk = 64; + } + ticks -= chunk; + uint64_t dil; + if (DI) + dil = *DIl++; + else + dil = 0; + /* Reduce the length of DI according to the bits we're transmitting */ + if (chunk < 64) + dil &= ((1LL << chunk) - 1); + s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE, + "!J%c%02x%" PRIx64 "%c", + (!ticks && final_tms) ? + REMOTE_TDITDO_TMS : REMOTE_TDITDO_NOTMS, + chunk, dil, REMOTE_EOM); + platform_buffer_write(construct,s); - if(!ticks || !DI) return; - - /* Reduce the length of DI according to the bits we're transmitting */ - DIl &= (1LL << (ticks + 1))-1; - - s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE, - REMOTE_JTAG_TDIDO_STR, - final_tms ? REMOTE_TDITDO_TMS : REMOTE_TDITDO_NOTMS, - ticks, DIl); - platform_buffer_write(construct,s); - - s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE); - if ((!s) || (construct[0] == REMOTE_RESP_ERR)) { - DEBUG_WARN("jtagtap_tms_seq failed, error %s\n", - s ? (char *)&(construct[1]) : "unknown"); - exit(-1); - } - - if (DO) { - uint64_t DOl = remotehston(-1, (char *)&construct[1]); - *(uint64_t *)DO = DOl; + s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE); + if ((!s) || (construct[0] == REMOTE_RESP_ERR)) { + DEBUG_WARN("jtagtap_tms_seq failed, error %s\n", + s ? (char *)&(construct[1]) : "unknown"); + exit(-1); + } + if (DO) + *DOl++ = remotehston(-1, (char *)&construct[1]); } } From 2d4a50313596081a64bd1397017985641fd8cad0 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sun, 3 Jan 2021 17:49:28 +0100 Subject: [PATCH 22/31] jtag_scan: Rework chain detection Fixme: stlinkv2/hosted probably does only handle STM devices. Check if jtag_devs.c really needed. --- src/Makefile | 1 - src/platforms/hosted/Makefile.inc | 2 +- src/target/adiv5.h | 8 +- src/target/jtag_scan.c | 288 +++++++++++++++--------------- 4 files changed, 152 insertions(+), 147 deletions(-) diff --git a/src/Makefile b/src/Makefile index de053656..188ecfa4 100644 --- a/src/Makefile +++ b/src/Makefile @@ -31,7 +31,6 @@ SRC = \ gdb_hostio.c \ gdb_packet.c \ hex_utils.c \ - jtag_devs.c \ jtag_scan.c \ lmi.c \ lpc_common.c \ diff --git a/src/platforms/hosted/Makefile.inc b/src/platforms/hosted/Makefile.inc index cd0ce561..fcf61ca0 100644 --- a/src/platforms/hosted/Makefile.inc +++ b/src/platforms/hosted/Makefile.inc @@ -59,7 +59,7 @@ ifneq ($(HOSTED_BMP_ONLY), 1) endif VPATH += platforms/pc -SRC += timing.c cl_utils.c utils.c +SRC += timing.c cl_utils.c utils.c jtag_devs.c SRC += bmp_remote.c remote_swdptap.c remote_jtagtap.c ifneq ($(HOSTED_BMP_ONLY), 1) SRC += bmp_libusb.c stlinkv2.c diff --git a/src/target/adiv5.h b/src/target/adiv5.h index 5a105432..890f8247 100644 --- a/src/target/adiv5.h +++ b/src/target/adiv5.h @@ -88,19 +88,23 @@ #define ADIV5_AP_BASE ADIV5_AP_REG(0xF8) #define ADIV5_AP_IDR ADIV5_AP_REG(0xFC) -/* Known designers seen in SYSROM-PIDR. Ignore Bit 0 from - * the designer bits to get JEDEC Ids with bit 7 ignored.*/ +/* Known designers seen in SYSROM-PIDR and JTAG IDCode. + * Ignore Bit 0 from the designer bits to get JEDEC Ids. + * Should get it's one file as not only related to Adiv5! + */ #define AP_DESIGNER_FREESCALE 0x00e #define AP_DESIGNER_TEXAS 0x017 #define AP_DESIGNER_ATMEL 0x01f #define AP_DESIGNER_STM 0x020 #define AP_DESIGNER_CYPRESS 0x034 #define AP_DESIGNER_INFINEON 0x041 +#define DESIGNER_XILINX 0x049 #define AP_DESIGNER_NORDIC 0x244 #define AP_DESIGNER_ARM 0x43b /*LPC845 with designer 501. Strange!? */ #define AP_DESIGNER_SPECULAR 0x501 #define AP_DESIGNER_CS 0x555 +#define DESIGNER_XAMBALA 0x61e #define AP_DESIGNER_ENERGY_MICRO 0x673 #define AP_DESIGNER_GIGADEVICE 0x751 #define AP_DESIGNER_RASPBERRY 0x927 diff --git a/src/target/jtag_scan.c b/src/target/jtag_scan.c index 88a8a576..d1c7eca6 100644 --- a/src/target/jtag_scan.c +++ b/src/target/jtag_scan.c @@ -3,6 +3,7 @@ * * Copyright (C) 2011 Black Sphere Technologies Ltd. * Written by Gareth McMullin + * Copyright (C) 2021 Uwe Bonnes(bon@elektron.ikp.physik.tu-darmstadt.de) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,16 +26,14 @@ #include "general.h" #include "jtagtap.h" -#include "jtag_scan.h" #include "target.h" #include "adiv5.h" -#include "jtag_devs.h" struct jtag_dev_s jtag_devs[JTAG_MAX_DEVS+1]; int jtag_dev_count; /* bucket of ones for don't care TDI */ -static const uint8_t ones[] = "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"; +static const uint8_t ones[] = {0xff, 0xFF, 0xFF, 0xFF}; #if PC_HOSTED == 0 void jtag_add_device(const int dev_index, const jtag_dev_t *jtag_dev) @@ -47,36 +46,32 @@ void jtag_add_device(const int dev_index, const jtag_dev_t *jtag_dev) #endif /* Scan JTAG chain for devices, store IR length and IDCODE (if present). - * Reset TAP state machine. - * Select Shift-IR state. - * Each device is assumed to shift out IR at 0x01. (this may not always be true) - * Shift in ones until we read two consecutive ones, then we have shifted out the - * IRs of all devices. * - * After this process all the IRs are loaded with the BYPASS command. - * Select Shift-DR state. - * Shift in ones and count zeros shifted out. Should be one for each device. - * Check this against device count obtained by IR scan above. + * https://www.fpga4fun.com/JTAG3.html + * Count the number of devices in the JTAG chain + * + * shift enough ones in IR + * shift enough zeros in DR + * Now shift out ones and stop if first '1' is seen. This gets the number + * of devices + * + * Assume max 32 devices with max IR len 16 = 512 bits = 16 loops * 32 bit * * Reset the TAP state machine again. This should load all IRs with IDCODE. - * For each device, shift out one bit. If this is zero IDCODE isn't present, - * continue to next device. If this is one shift out the remaining 31 bits - * of the IDCODE register. - */ + * Read 32 bit IDCODE for all devices. + */ + int jtag_scan(const uint8_t *irlens) { int i; - uint32_t j; - + void (*jd_handlers[JTAG_MAX_DEVS])(uint8_t jd_index, uint32_t j_idcode); target_list_free(); - jtag_dev_count = 0; - memset(&jtag_devs, 0, sizeof(jtag_devs)); + memset(jd_handlers, 0, sizeof(jd_handlers)); - /* Run throught the SWD to JTAG sequence for the case where an attached SWJ-DP is - * in SW-DP mode. + /* Run throught the SWD to JTAG sequence for the case where an + * attached SWJ-DP is in SW-DP mode. */ - DEBUG_INFO("Resetting TAP\n"); #if PC_HOSTED == 1 if (platform_jtagtap_init()) { DEBUG_WARN("JTAG not available\n"); @@ -86,139 +81,146 @@ int jtag_scan(const uint8_t *irlens) jtagtap_init(); #endif jtag_proc.jtagtap_reset(); - - if (irlens) { - DEBUG_WARN("Given list of IR lengths, skipping probe\n"); - DEBUG_INFO("Change state to Shift-IR\n"); - jtagtap_shift_ir(); - j = 0; - while((jtag_dev_count <= JTAG_MAX_DEVS) && - (jtag_devs[jtag_dev_count].ir_len <= JTAG_MAX_IR_LEN)) { - uint32_t irout; - if(*irlens == 0) - break; - jtag_proc.jtagtap_tdi_tdo_seq((uint8_t*)&irout, 0, ones, *irlens); - if (!(irout & 1)) { - DEBUG_WARN("check failed: IR[0] != 1\n"); - return -1; - } - jtag_devs[jtag_dev_count].ir_len = *irlens; - jtag_devs[jtag_dev_count].ir_prescan = j; - jtag_devs[jtag_dev_count].jd_dev = jtag_dev_count; - j += *irlens; - irlens++; - jtag_dev_count++; - } - } else { - DEBUG_INFO("Change state to Shift-IR\n"); - jtagtap_shift_ir(); - - DEBUG_INFO("Scanning out IRs\n"); - if(!jtag_proc.jtagtap_next(0, 1)) { - DEBUG_WARN("jtag_scan: Sanity check failed: IR[0] shifted out " - "as 0\n"); - jtag_dev_count = -1; - return -1; /* must be 1 */ - } - jtag_devs[0].ir_len = 1; j = 1; - while((jtag_dev_count <= JTAG_MAX_DEVS) && - (jtag_devs[jtag_dev_count].ir_len <= JTAG_MAX_IR_LEN)) { - if(jtag_proc.jtagtap_next(0, 1)) { - if(jtag_devs[jtag_dev_count].ir_len == 1) break; - jtag_devs[++jtag_dev_count].ir_len = 1; - jtag_devs[jtag_dev_count].ir_prescan = j; - jtag_devs[jtag_dev_count].jd_dev = jtag_dev_count; - } else jtag_devs[jtag_dev_count].ir_len++; - j++; - } - if(jtag_dev_count > JTAG_MAX_DEVS) { - DEBUG_WARN("jtag_scan: Maximum device count exceeded\n"); - jtag_dev_count = -1; - return -1; - } - if(jtag_devs[jtag_dev_count].ir_len > JTAG_MAX_IR_LEN) { - DEBUG_WARN("jtag_scan: Maximum IR length exceeded\n"); - jtag_dev_count = -1; - return -1; - } +#define LOOPS 16 + jtagtap_shift_ir(); + i = LOOPS; + uint8_t ir_chain[64], *din = ir_chain; + while (i--) { + jtag_proc.jtagtap_tdi_tdo_seq(din, (i == 0) ? 1 : 0, ones, + sizeof(ones) * 8); + din += sizeof(ones); } - - DEBUG_INFO("Return to Run-Test/Idle\n"); - jtag_proc.jtagtap_next(1, 1); - jtagtap_return_idle(); - - /* All devices should be in BYPASS now */ - - /* Count device on chain */ - DEBUG_INFO("Change state to Shift-DR\n"); - jtagtap_shift_dr(); - for(i = 0; (jtag_proc.jtagtap_next(0, 1) == 0) && (i <= jtag_dev_count); i++) - jtag_devs[i].dr_postscan = jtag_dev_count - i - 1; - - if(i != jtag_dev_count) { - DEBUG_WARN("jtag_scan: Sanity check failed: " - "BYPASS dev count doesn't match IR scan\n"); - jtag_dev_count = -1; - return -1; - } - - DEBUG_INFO("Return to Run-Test/Idle\n"); - jtag_proc.jtagtap_next(1, 1); - jtagtap_return_idle(); - if(!jtag_dev_count) { + if (!(ir_chain[0] & 1)) { + DEBUG_WARN("Unexpected IR chain!\n"); return 0; } - - /* Fill in the ir_postscan fields */ - for(i = jtag_dev_count - 1; i; i--) - jtag_devs[i-1].ir_postscan = jtag_devs[i].ir_postscan + - jtag_devs[i].ir_len; - - /* Reset jtagtap: should take all devs to IDCODE */ + jtagtap_return_idle(); + jtagtap_shift_dr(); + i = LOOPS; + uint8_t zeros[] = {0, 0, 0, 0}; + while(i--) { + jtag_proc.jtagtap_tdi_seq(0, zeros, sizeof(zeros) * 8); + } + int num_devices = 0; + while (!jtag_proc.jtagtap_next(0,1) && (i++ < 6)) + num_devices++; jtag_proc.jtagtap_reset(); jtagtap_shift_dr(); - for(i = 0; i < jtag_dev_count; i++) { - if(!jtag_proc.jtagtap_next(0, 1)) continue; - jtag_devs[i].jd_idcode = 1; - for(j = 2; j; j <<= 1) - if(jtag_proc.jtagtap_next(0, 1)) jtag_devs[i].jd_idcode |= j; - + jtag_dev_count = num_devices; + if (!num_devices) + return 0; + DEBUG_TARGET("Found %d devices\n", num_devices); + int irbit = 1; + int j = 0; + for (i = 0; i < num_devices; i++) { + uint8_t id[4]; + jtag_proc.jtagtap_tdi_tdo_seq(id, 0, ones, 32); + if (!(id[0] & 1)) { + DEBUG_WARN("Invalid IDCode!\n"); + return 0; + } + uint32_t idcode = id[3] << 24 | id[2] << 16 | id[1] << 8 | id[0]; + unsigned int designer = ((id[1] & 0xf) << 8) | (id[0] >> 1); + unsigned int product = id[2] | ((id[3] & 0xf) << 8); + unsigned int expected_irlen = 0; + switch (designer) { + case AP_DESIGNER_ARM: + switch (product) { + case 0xba0: + jtag_devs[i].jd_descr = "ADIv5 JTAG-DP port"; + jd_handlers[i] = adiv5_jtag_dp_handler; + expected_irlen = 4; + break; + default: + jtag_devs[i].jd_descr = "ARM"; + } + break; + case AP_DESIGNER_STM: + expected_irlen = 5; + jtag_devs[i].jd_descr = "STM32 BSD"; + break; + case AP_DESIGNER_ATMEL: + if ((product >= 0x940) & (product < 0x990)) { + jtag_devs[i].jd_descr = "ATMEL AVR8"; + expected_irlen = 4; + break; + } + jtag_devs[i].jd_descr = "ATMEL"; + break; + case DESIGNER_XILINX: + if (!irlens) { + /* Guessed irlen for XILINX devices is wrong. + * IR data contains status bits! + */ + DEBUG_WARN("Please provide irlens as chain contains XILINX devices!\n"); + return 0; + } + jtag_devs[i].jd_descr = "XILINX"; + break; + case DESIGNER_XAMBALA: + expected_irlen = 5; + jtag_devs[i].jd_descr = "RVDBG013"; + break; + case AP_DESIGNER_GIGADEVICE: + expected_irlen = 5; + jtag_devs[i].jd_descr = "GIGADEVICE BSD"; + break; + } + if (!jtag_devs[i].jd_descr) { + DEBUG_WARN("Unhandled designer %x\n", designer); + jtag_devs[i].jd_descr = "Unknow"; + } + bool bit; + int guessed_irlen = 0; + int advance = irbit; + do { + /* Guess IR length from the IR scan after JTAG Reset + * First bit should be '1', following bits are '0', if not used + * for instruction capture, as for Xilinx parts. + */ + bit = (ir_chain[advance / 8] & (1 << (advance & 7))); + guessed_irlen++; + advance++; + } while (!bit && (advance < (JTAG_MAX_DEVS * 16))); + if (irlens) { /* Allow to overwrite from the command line!*/ + if (*irlens != guessed_irlen) { + DEBUG_TARGET("Provides irlen %d vs guessed %d for device %d\n", + *irlens, guessed_irlen, i + 1); + } + expected_irlen = *irlens++; + } + if (!expected_irlen) { + expected_irlen = guessed_irlen++; + } + jtag_devs[i].ir_len = expected_irlen; + jtag_devs[i].ir_prescan = j; + jtag_devs[i].jd_dev = i; + jtag_devs[i].jd_idcode = idcode; + jtag_devs[i].dr_postscan = jtag_dev_count - i - 1; + jtag_devs[i].current_ir = -1; + j += expected_irlen; + irbit += expected_irlen; + DEBUG_INFO("%2d: IDCODE: 0x%08" PRIx32 ", IR len %d %s%s\n", i + 1, + idcode,jtag_devs[i].ir_len, jtag_devs[i].jd_descr, + (jd_handlers[i]) ? "" : " (Unhandled) "); + } + jtag_proc.jtagtap_reset(); + /* Fill in the ir_postscan fields */ + for(i = jtag_dev_count - 1; i; i--) { + jtag_devs[i-1].ir_postscan = jtag_devs[i].ir_postscan + + jtag_devs[i].ir_len; } - DEBUG_INFO("Return to Run-Test/Idle\n"); - jtag_proc.jtagtap_next(1, 1); - jtagtap_return_idle(); #if PC_HOSTED == 1 /*Transfer needed device information to firmware jtag_devs*/ - for(i = 0; i < jtag_dev_count; i++) - platform_add_jtag_dev(i, &jtag_devs[i]); for(i = 0; i < jtag_dev_count; i++) { - DEBUG_INFO("Idcode 0x%08" PRIx32, jtag_devs[i].jd_idcode); - for(j = 0; dev_descr[j].idcode; j++) { - if((jtag_devs[i].jd_idcode & dev_descr[j].idmask) == - dev_descr[j].idcode) { - DEBUG_INFO(": %s", - (dev_descr[j].descr) ? dev_descr[j].descr : "unknown"); - break; - } - } - DEBUG_INFO("\n"); + platform_add_jtag_dev(i, &jtag_devs[i]); } #endif - /* Check for known devices and handle accordingly */ for(i = 0; i < jtag_dev_count; i++) - for(j = 0; dev_descr[j].idcode; j++) - if((jtag_devs[i].jd_idcode & dev_descr[j].idmask) == - dev_descr[j].idcode) { - jtag_devs[i].current_ir = -1; - /* Save description in table */ - jtag_devs[i].jd_descr = dev_descr[j].descr; - /* Call handler to initialise/probe device further */ - if(dev_descr[j].handler) - dev_descr[j].handler(i, jtag_devs[i].jd_idcode); - break; - } - + /* Call handler to initialise/probe device further */ + if (jd_handlers[i]) + jd_handlers[i](i, jtag_devs[i].jd_idcode); return jtag_dev_count; } From 5c8e277663df3818044e2d9055307c937c3361d9 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Fri, 1 Jan 2021 14:10:25 +0100 Subject: [PATCH 23/31] hosted/dap: Fix tdi_tdo_seq. --- src/platforms/hosted/cmsis_dap.c | 2 +- src/platforms/hosted/dap.c | 44 +++++++++++++++++--------------- 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/platforms/hosted/cmsis_dap.c b/src/platforms/hosted/cmsis_dap.c index 19c49e39..002c44a4 100644 --- a/src/platforms/hosted/cmsis_dap.c +++ b/src/platforms/hosted/cmsis_dap.c @@ -349,7 +349,7 @@ static void cmsis_dap_jtagtap_tdi_tdo_seq(uint8_t *DO, const uint8_t final_tms, const uint8_t *DI, int ticks) { dap_jtagtap_tdi_tdo_seq(DO, (final_tms), NULL, DI, ticks); - DEBUG_PROBE("jtagtap_tdi_tdo_seq %d, %02x-> %02x\n", ticks, DI[0], DO[0]); + DEBUG_PROBE("jtagtap_tdi_tdo_seq %d, %02x-> %02x\n", ticks, DI[0], (DO)? DO[0] : 0); } static void cmsis_dap_jtagtap_tdi_seq(const uint8_t final_tms, diff --git a/src/platforms/hosted/dap.c b/src/platforms/hosted/dap.c index 5acc03e5..7da956b8 100644 --- a/src/platforms/hosted/dap.c +++ b/src/platforms/hosted/dap.c @@ -644,15 +644,16 @@ void dap_write_single(ADIv5_AP_t *ap, uint32_t dest, const void *src, void dap_jtagtap_tdi_tdo_seq(uint8_t *DO, bool final_tms, const uint8_t *TMS, const uint8_t *DI, int ticks) { + DEBUG_PROBE("dap_jtagtap_tdi_tdo_seq %s %d ticks\n", + (final_tms) ? "final" : "", ticks); uint8_t buf[64]; + const uint8_t *din = DI; + uint8_t *dout = DO; if (!TMS) { - int last_byte = 0; - int last_bit = 0; - if (final_tms) { - last_byte = ticks >> 3; - last_bit = ticks & 7; + int last_byte = last_byte = (ticks - 1) >> 3; + int last_bit = (ticks - 1) & 7; + if (final_tms) ticks --; - } while (ticks) { int transfers = ticks; if (transfers > 64) @@ -660,11 +661,12 @@ void dap_jtagtap_tdi_tdo_seq(uint8_t *DO, bool final_tms, const uint8_t *TMS, uint8_t *p = buf; *p++ = ID_DAP_JTAG_SEQUENCE; *p++ = 1; - *p++ = transfers | ((DO) ? DAP_JTAG_TDO_CAPTURE : 0); + *p++ = ((transfers == 64) ? 0 : transfers) | + ((DO) ? DAP_JTAG_TDO_CAPTURE : 0); int n_di_bytes = (transfers + 7) >> 3; - if (DI) { - p = memcpy(p, DI, n_di_bytes); - DI += n_di_bytes; + if (din) { + p = memcpy(p, din, n_di_bytes); + din += n_di_bytes; } else { p = memset(p, 0xff, n_di_bytes); } @@ -672,9 +674,9 @@ void dap_jtagtap_tdi_tdo_seq(uint8_t *DO, bool final_tms, const uint8_t *TMS, dbg_dap_cmd(buf, sizeof(buf), p - buf); if (buf[0] != DAP_OK) DEBUG_WARN("dap_jtagtap_tdi_tdo_seq failed %02x\n", buf[0]); - if (DO) { - memcpy(DO, &buf[1], (transfers + 7) >> 3); - DO += (transfers + 7) >> 3; + if (dout) { + memcpy(dout, &buf[1], (transfers + 7) >> 3); + dout += (transfers + 7) >> 3; } ticks -= transfers; } @@ -682,8 +684,8 @@ void dap_jtagtap_tdi_tdo_seq(uint8_t *DO, bool final_tms, const uint8_t *TMS, uint8_t *p = buf; *p++ = ID_DAP_JTAG_SEQUENCE; *p++ = 1; - *p++ = 1 | ((DO) ? DAP_JTAG_TDO_CAPTURE : 0) | DAP_JTAG_TMS; - if (DI) { + *p++ = 1 | ((dout) ? DAP_JTAG_TDO_CAPTURE : 0) | DAP_JTAG_TMS; + if (din) { *p++ = ((DI[last_byte] & (1 << last_bit)) ? 1 : 0); } else { *p++ = 0; @@ -691,7 +693,7 @@ void dap_jtagtap_tdi_tdo_seq(uint8_t *DO, bool final_tms, const uint8_t *TMS, dbg_dap_cmd(buf, sizeof(buf), p - buf); if (buf[0] == DAP_ERROR) DEBUG_WARN("dap_jtagtap_tdi_tdo_seq failed %02x\n", buf[0]); - if (DO) { + if (dout) { if (buf[1] & 1) DO[last_byte] |= (1 << last_bit); else @@ -709,11 +711,11 @@ void dap_jtagtap_tdi_tdo_seq(uint8_t *DO, bool final_tms, const uint8_t *TMS, *p++ = transfers; for (int i = 0; i < transfers; i++) { *p++ = 1 | ((DO) ? DAP_JTAG_TDO_CAPTURE : 0) | - ((TMS[i >> 8] & (1 << (i & 7))) ? DAP_JTAG_TMS : 0); + ((TMS[i / 8] & (1 << (i & 7))) ? DAP_JTAG_TMS : 0); if (DI) - *p++ = (DI[i >> 8] & (1 << (i & 7))) ? 1 : 0; + *p++ = (DI[i / 8] & (1 << (i & 7))) ? 1 : 0; else - *p++ = 0x55; + *p++ = 1; } dbg_dap_cmd(buf, sizeof(buf), p - buf); if (buf[0] == DAP_ERROR) @@ -721,9 +723,9 @@ void dap_jtagtap_tdi_tdo_seq(uint8_t *DO, bool final_tms, const uint8_t *TMS, if (DO) { for (int i = 0; i < transfers; i++) { if (buf[i + 1]) - DO[i >> 8] |= (1 << (i & 7)); + DO[i / 8] |= (1 << (i & 7)); else - DO[i >> 8] &= ~(1 << (i & 7)); + DO[i / 8] &= ~(1 << (i & 7)); } } ticks -= transfers; From 3df692ecb247fdc7c62f3c3dc622030ad12817e6 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Thu, 15 Jul 2021 18:35:18 +0200 Subject: [PATCH 24/31] adiv5_swdp_scan: If SWD scan fails, try a JTAG scan. --- src/platforms/pc/cl_utils.c | 2 +- src/target/adiv5_swdp.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platforms/pc/cl_utils.c b/src/platforms/pc/cl_utils.c index 93605853..65de1cf9 100644 --- a/src/platforms/pc/cl_utils.c +++ b/src/platforms/pc/cl_utils.c @@ -375,7 +375,7 @@ int cl_execute(BMP_CL_OPTIONS_t *opt) } else { num_targets = platform_adiv5_swdp_scan(opt->opt_targetid); if (!num_targets) { - DEBUG_INFO("Scan SWD failed, trying JTAG!\n"); + DEBUG_WARN("Scan SWD failed, trying JTAG!\n"); num_targets = platform_jtag_scan(NULL); } } diff --git a/src/target/adiv5_swdp.c b/src/target/adiv5_swdp.c index 9edb5d18..50b8f2e0 100644 --- a/src/target/adiv5_swdp.c +++ b/src/target/adiv5_swdp.c @@ -134,7 +134,7 @@ int adiv5_swdp_scan(uint32_t targetid) } if (e2.type) { DEBUG_WARN("No usable DP found\n"); - return -1; + return 0; } } if ((idcode & ADIV5_DP_VERSION_MASK) == ADIV5_DPv2) { From f7670fcd44424ac26f3e7501d585c2a5f1743c0f Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Thu, 15 Jul 2021 18:58:58 +0200 Subject: [PATCH 25/31] ftdi_bmp: Add verbosity for libftdi_jtagtap_tdi_tdo_seq() --- src/platforms/hosted/ftdi_bmp.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/platforms/hosted/ftdi_bmp.c b/src/platforms/hosted/ftdi_bmp.c index f6ed7eed..7d515f1c 100644 --- a/src/platforms/hosted/ftdi_bmp.c +++ b/src/platforms/hosted/ftdi_bmp.c @@ -552,7 +552,8 @@ void libftdi_jtagtap_tdi_tdo_seq( if(!ticks) return; if (!DI && !DO) return; -// printf("ticks: %d\n", ticks); + DEBUG_WIRE("libftdi_jtagtap_tdi_tdo_seq %s ticks: %d\n", + (DI && DO) ? "read/write" : ((DI) ? "read" : "write"),ticks); if(final_tms) ticks--; rticks = ticks & 7; ticks >>= 3; @@ -593,7 +594,6 @@ void libftdi_jtagtap_tdi_tdo_seq( if(final_tms) rsize--; while(rsize--) { - /*if(rsize) printf("%02X ", tmp[index]);*/ *DO++ = tmp[index++]; } if (rticks == 0) @@ -606,7 +606,6 @@ void libftdi_jtagtap_tdi_tdo_seq( if(rticks) { *DO >>= (8-rticks); } - /*printf("%02X\n", *DO);*/ } } From 6dff2a9f3179b18806acff6694ff552558447b2e Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sat, 2 Jan 2021 19:22:10 +0100 Subject: [PATCH 26/31] target: target_error_check now defaults to not indicate error. Remove unneeded nop_function from efm32 --- src/target/efm32.c | 15 --------------- src/target/target.c | 6 ++++++ 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/src/target/efm32.c b/src/target/efm32.c index 547eadc8..4589c00b 100644 --- a/src/target/efm32.c +++ b/src/target/efm32.c @@ -979,11 +979,6 @@ const struct command_s efm32_aap_cmd_list[] = { {NULL, NULL, NULL} }; -static bool nop_function(void) -{ - return true; -} - /** * AAP Probe */ @@ -1019,17 +1014,7 @@ void efm32_aap_probe(ADIv5_AP_t *ap) "EFM32 Authentication Access Port rev.%d", aap_revision); t->driver = priv_storage->aap_driver_string; - t->attach = (void*)nop_function; - t->detach = (void*)nop_function; - t->check_error = (void*)nop_function; - t->mem_read = (void*)nop_function; - t->mem_write = (void*)nop_function; t->regs_size = 4; - t->regs_read = (void*)nop_function; - t->regs_write = (void*)nop_function; - t->reset = (void*)nop_function; - t->halt_request = (void*)nop_function; - t->halt_resume = (void*)nop_function; target_add_commands(t, efm32_aap_cmd_list, t->driver); } diff --git a/src/target/target.c b/src/target/target.c index 44763ad3..d356a9a6 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -34,6 +34,11 @@ static bool nop_function(void) return true; } +static int null_function(void) +{ + return 0; +} + target *target_new(void) { target *t = (void*)calloc(1, sizeof(*t)); @@ -63,6 +68,7 @@ target *target_new(void) t->halt_request = (void*)nop_function; t->halt_poll = (void*)nop_function; t->halt_resume = (void*)nop_function; + t->check_error = (void*)null_function; t->target_storage = NULL; From 6308506276d09cde14be2985c0c5a59adc0addc6 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sat, 17 Jul 2021 22:24:41 +0200 Subject: [PATCH 27/31] jtag: Make jtag_devs argument to jtag_handler. --- src/platforms/hosted/stlinkv2.c | 2 +- src/target/adiv5.h | 2 +- src/target/adiv5_jtagdp.c | 6 +++--- src/target/jtag_devs.h | 2 +- src/target/jtag_scan.c | 6 +++--- src/target/jtag_scan.h | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/platforms/hosted/stlinkv2.c b/src/platforms/hosted/stlinkv2.c index 211ad10b..5dd99dd4 100644 --- a/src/platforms/hosted/stlinkv2.c +++ b/src/platforms/hosted/stlinkv2.c @@ -1008,7 +1008,7 @@ int jtag_scan_stlinkv2(bmp_info_t *info, const uint8_t *irlens) if((jtag_devs[i].jd_idcode & dev_descr[j].idmask) == dev_descr[j].idcode) { if(dev_descr[j].handler) - dev_descr[j].handler(i, dev_descr[j].idcode); + dev_descr[j].handler(&jtag_devs[i]); break; } diff --git a/src/target/adiv5.h b/src/target/adiv5.h index 890f8247..2c58d02b 100644 --- a/src/target/adiv5.h +++ b/src/target/adiv5.h @@ -290,7 +290,7 @@ void adiv5_ap_ref(ADIv5_AP_t *ap); void adiv5_ap_unref(ADIv5_AP_t *ap); void platform_add_jtag_dev(const int dev_index, const jtag_dev_t *jtag_dev); -void adiv5_jtag_dp_handler(uint8_t jd_index, uint32_t j_idcode); +void adiv5_jtag_dp_handler(jtag_dev_t *jd); int platform_jtag_dp_init(ADIv5_DP_t *dp); int swdptap_init(ADIv5_DP_t *dp); diff --git a/src/target/adiv5_jtagdp.c b/src/target/adiv5_jtagdp.c index 2c87dc7c..52737461 100644 --- a/src/target/adiv5_jtagdp.c +++ b/src/target/adiv5_jtagdp.c @@ -39,7 +39,7 @@ static uint32_t adiv5_jtagdp_error(ADIv5_DP_t *dp); -void adiv5_jtag_dp_handler(uint8_t jd_index, uint32_t j_idcode) +void adiv5_jtag_dp_handler(jtag_dev_t *jd) { ADIv5_DP_t *dp = (void*)calloc(1, sizeof(*dp)); if (!dp) { /* calloc failed: heap exhaustion */ @@ -47,8 +47,8 @@ void adiv5_jtag_dp_handler(uint8_t jd_index, uint32_t j_idcode) return; } - dp->dp_jd_index = jd_index; - dp->idcode = j_idcode; + dp->dp_jd_index = jd->jd_dev; + dp->idcode = jd->jd_idcode; if ((PC_HOSTED == 0 ) || (!platform_jtag_dp_init(dp))) { dp->dp_read = fw_adiv5_jtagdp_read; dp->error = adiv5_jtagdp_error; diff --git a/src/target/jtag_devs.h b/src/target/jtag_devs.h index 8c2c0b5a..8f877985 100644 --- a/src/target/jtag_devs.h +++ b/src/target/jtag_devs.h @@ -22,7 +22,7 @@ typedef const struct jtag_dev_descr_s { const uint32_t idcode; const uint32_t idmask; const char * const descr; - void (*const handler)(uint8_t jd_index, uint32_t j_idcode); + void (*const handler)(jtag_dev_t *jd); } jtag_dev_descr_t; extern jtag_dev_descr_t dev_descr[]; diff --git a/src/target/jtag_scan.c b/src/target/jtag_scan.c index d1c7eca6..eb1efc80 100644 --- a/src/target/jtag_scan.c +++ b/src/target/jtag_scan.c @@ -29,7 +29,7 @@ #include "target.h" #include "adiv5.h" -struct jtag_dev_s jtag_devs[JTAG_MAX_DEVS+1]; +jtag_dev_t jtag_devs[JTAG_MAX_DEVS+1]; int jtag_dev_count; /* bucket of ones for don't care TDI */ @@ -64,7 +64,7 @@ void jtag_add_device(const int dev_index, const jtag_dev_t *jtag_dev) int jtag_scan(const uint8_t *irlens) { int i; - void (*jd_handlers[JTAG_MAX_DEVS])(uint8_t jd_index, uint32_t j_idcode); + void (*jd_handlers[JTAG_MAX_DEVS])(jtag_dev_t *jd); target_list_free(); memset(jd_handlers, 0, sizeof(jd_handlers)); @@ -220,7 +220,7 @@ int jtag_scan(const uint8_t *irlens) for(i = 0; i < jtag_dev_count; i++) /* Call handler to initialise/probe device further */ if (jd_handlers[i]) - jd_handlers[i](i, jtag_devs[i].jd_idcode); + jd_handlers[i](&jtag_devs[i]); return jtag_dev_count; } diff --git a/src/target/jtag_scan.h b/src/target/jtag_scan.h index cc6d361a..bc76e0bc 100644 --- a/src/target/jtag_scan.h +++ b/src/target/jtag_scan.h @@ -40,7 +40,7 @@ typedef struct jtag_dev_s { uint32_t current_ir; } jtag_dev_t; -extern struct jtag_dev_s jtag_devs[JTAG_MAX_DEVS+1]; +extern jtag_dev_t jtag_devs[JTAG_MAX_DEVS+1]; extern int jtag_dev_count; void jtag_dev_write_ir(jtag_proc_t *jp, uint8_t jd_index, uint32_t ir); From 2fcd4a878a553c8e913ff59e8e0579790fb553f0 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sat, 14 Aug 2021 15:21:04 +0200 Subject: [PATCH 28/31] ftdi_bmp.h: Fix error when compiling with HOSTED_BMP_ONLY=1 --- src/platforms/hosted/ftdi_bmp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platforms/hosted/ftdi_bmp.h b/src/platforms/hosted/ftdi_bmp.h index 4ce9090a..e5553a44 100644 --- a/src/platforms/hosted/ftdi_bmp.h +++ b/src/platforms/hosted/ftdi_bmp.h @@ -115,7 +115,7 @@ bool libftdi_swd_possible(bool *do_mpsse, bool *direct_bb_swd) {return false;}; void libftdi_max_frequency_set(uint32_t freq) {}; uint32_t libftdi_max_frequency_get(void) {return 0;}; void libftdi_srst_set_val(bool assert){}; -bool libftdi_srst_get_val(void) { return false}; +bool libftdi_srst_get_val(void) { return false;}; # pragma GCC diagnostic pop #else #include From 49122b50b6581e07427c231434cc38c3bbd0efee Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sun, 15 Aug 2021 15:22:57 +0200 Subject: [PATCH 29/31] hosted: Make HOSTED_BMP_ONLY the default. Hopefully more people will use it when reporting errors! --- src/platforms/hosted/Makefile.inc | 12 ++++++------ src/platforms/hosted/Readme.md | 16 ++++++++++------ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/platforms/hosted/Makefile.inc b/src/platforms/hosted/Makefile.inc index fcf61ca0..b1322358 100644 --- a/src/platforms/hosted/Makefile.inc +++ b/src/platforms/hosted/Makefile.inc @@ -2,12 +2,12 @@ SYS = $(shell $(CC) -dumpmachine) CFLAGS += -DENABLE_DEBUG -DPLATFORM_HAS_DEBUG CFLAGS +=-I ./target -I./platforms/pc -# Define HOSTED_BMP_ONLY to '1' in order to build the hosted blackmagic -# executable with support for native BMP probes only. This makes -# linking against the libftdi and libusb libraries unnecessary. This can -# be useful to minimize external dependencies, and make building on -# windows systems easier. -HOSTED_BMP_ONLY ?= 0 +# Define HOSTED_BMP_ONLY to '0' in order to build the hosted blackmagic +# executable with support for other probes beside BMP. Default HOSTED_BMP_ONLY +# == 1 makes linking against the libftdi and libusb libraries unnecessary. +# This can be useful to minimize external dependencies, and make building on +# windows systems easier and is default now. +HOSTED_BMP_ONLY ?= 1 CFLAGS += -DHOSTED_BMP_ONLY=$(HOSTED_BMP_ONLY) ifneq (, $(findstring linux, $(SYS))) diff --git a/src/platforms/hosted/Readme.md b/src/platforms/hosted/Readme.md index 5f3e24d1..a1d56c5e 100644 --- a/src/platforms/hosted/Readme.md +++ b/src/platforms/hosted/Readme.md @@ -1,5 +1,7 @@ # PC-Hosted BMP -Compile in src with "make PROBE_HOST=hosted" +Compile in src with "make PROBE_HOST=hosted". This needs minimal external +support. "make PROBE_HOST=hosted HOSTED_BMP=0" will compile support for FTDI, +STLink, CMSIS-DAP and JLINK probes, but requires external libraries. ## Description PC-hosted BMP run on the PC and compiles as "blackmagic". When started, @@ -8,7 +10,7 @@ if either only one probe is attached to the PC or enough information is given on the command line to select one of several probes. When started without any other argument beside the probe selection, a -GDB server is started as port 2000 and up. Connect to the server as you would +GDB server is started on port 2000 and up. Connect to the server as you would connect to the BMP with the CDCACM GDB serial server. GDB functionality is the same, monitor option may vary. @@ -60,9 +62,9 @@ blackmagic -M "option help" ## Compiling on windows You can crosscompile blackmagic for windows with mingw or on windows -with cygwin. For compilation, headers for libftdi1 and libusb-1.0 are -needed. For running, libftdi1.dll and libusb-1.0.dll are needed and -the executable must be able to find them. Mingw on cygwin does not provide +with cygwin. For suppport of other probes beside BMP, headers for libftdi1 and +libusb-1.0 are needed. For running, libftdi1.dll and libusb-1.0.dll are needed +and the executable must be able to find them. Mingw on cygwin does not provide a libftdi package yet. PC-hosted BMP for windows can also be built with [MSYS2](https://www.msys2.org/), @@ -78,7 +80,8 @@ pacman -S mingw-w64-x86_64-gcc --needed PROBE_HOST=hosted make ``` -To prepare libusb access to the ftdi/stlink/jlink/cmsis-dap devices, run zadig +For suppport of other probes beside BMP, libusb access is needed. To prepare +libusb access to the ftdi/stlink/jlink/cmsis-dap devices, run zadig https://zadig.akeo.ie/. Choose WinUSB(libusb-1.0). Running cygwin/blackmagic in a cygwin console, the program does not react @@ -91,6 +94,7 @@ REMOTE_BMP is a "normal" BMP usb connected | Debugger | Speed | Remarks | ------------ | ----- | ------ | REMOTE_BMP | +++ | Requires recent firmware for decent speed +Probes below only when compiled with HOSTED_BMP=0 | ST-Link V3 | ++++ | Requires recent firmware, Only STM32 devices supported! | ST-Link V2 | +++ | Requires recent firmware, No CDCACM uart! Cortex only! | ST-Link V2/1 | +++ | Requires recent firmware, Cortex only! From 863a41daac28103660a70d7663cf29f56e818717 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sun, 15 Aug 2021 15:45:53 +0200 Subject: [PATCH 30/31] adiv5_swdp: Initialize initial_dp with the definition --- src/target/adiv5_swdp.c | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/src/target/adiv5_swdp.c b/src/target/adiv5_swdp.c index 50b8f2e0..78d91eb6 100644 --- a/src/target/adiv5_swdp.c +++ b/src/target/adiv5_swdp.c @@ -76,25 +76,17 @@ static bool firmware_dp_low_read(ADIv5_DP_t *dp, uint16_t addr, uint32_t *res) int adiv5_swdp_scan(uint32_t targetid) { target_list_free(); - ADIv5_DP_t idp, *initial_dp = &idp; - memset(initial_dp, 0, sizeof(ADIv5_DP_t)); + ADIv5_DP_t idp = { + .dp_low_write = firmware_dp_low_write, + .dp_low_read = firmware_dp_low_read, + .error = firmware_swdp_error, + .dp_read = firmware_swdp_read, + .low_access = firmware_swdp_low_access, + .abort = firmware_swdp_abort, + }; + ADIv5_DP_t *initial_dp = &idp; if (swdptap_init(initial_dp)) return -1; - /* Set defaults when no procedure given*/ - if (!initial_dp->dp_low_write) - initial_dp->dp_low_write = firmware_dp_low_write; - if (!initial_dp->dp_low_read) - initial_dp->dp_low_read = firmware_dp_low_read; - if (!initial_dp->error) - initial_dp->error = firmware_swdp_error; - if (!initial_dp->dp_read) - initial_dp->dp_read = firmware_swdp_read; - if (!initial_dp->error) - initial_dp->error = firmware_swdp_error; - if (!initial_dp->low_access) - initial_dp->low_access = firmware_swdp_low_access; - if (!initial_dp->abort) - initial_dp->abort = firmware_swdp_abort; /* DORMANT-> SWD sequence*/ initial_dp->seq_out(0xFFFFFFFF, 32); initial_dp->seq_out(0xFFFFFFFF, 32); From 35687018eb634ea329609c86d9ed476bb79c0e91 Mon Sep 17 00:00:00 2001 From: Thiadmer Riemersma Date: Tue, 31 Aug 2021 11:41:00 +0200 Subject: [PATCH 31/31] Escape '*' in responses of the Remote Serial Protocol, to avoid that it is interpreted as the start of an RLE sequence --- src/gdb_packet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gdb_packet.c b/src/gdb_packet.c index 6f31e138..41920f26 100644 --- a/src/gdb_packet.c +++ b/src/gdb_packet.c @@ -158,7 +158,7 @@ void gdb_putpacket(const char *packet, int size) else DEBUG_GDB_WIRE("\\x%02X", c); #endif - if((c == '$') || (c == '#') || (c == '}')) { + if((c == '$') || (c == '#') || (c == '}') || (c == '*')) { gdb_if_putchar('}', 0); gdb_if_putchar(c ^ 0x20, 0); csum += '}' + (c ^ 0x20);