Merge commit '35687018eb634ea329609c86d9ed476bb79c0e91' into sam-update
# Conflicts: # src/platforms/common/cdcacm.c # src/target/adiv5_swdp.c
This commit is contained in:
commit
9dc79becc2
@ -31,7 +31,6 @@ SRC = \
|
|||||||
gdb_hostio.c \
|
gdb_hostio.c \
|
||||||
gdb_packet.c \
|
gdb_packet.c \
|
||||||
hex_utils.c \
|
hex_utils.c \
|
||||||
jtag_devs.c \
|
|
||||||
jtag_scan.c \
|
jtag_scan.c \
|
||||||
lmi.c \
|
lmi.c \
|
||||||
lpc_common.c \
|
lpc_common.c \
|
||||||
|
@ -284,6 +284,8 @@ int gdb_main_loop(struct target_controller *tc, bool in_syscall)
|
|||||||
else if(last_target) {
|
else if(last_target) {
|
||||||
cur_target = target_attach(last_target,
|
cur_target = target_attach(last_target,
|
||||||
&gdb_controller);
|
&gdb_controller);
|
||||||
|
if(cur_target)
|
||||||
|
morse(NULL, false);
|
||||||
target_reset(cur_target);
|
target_reset(cur_target);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -428,35 +430,36 @@ handle_v_packet(char *packet, int plen)
|
|||||||
if (sscanf(packet, "vAttach;%08lx", &addr) == 1) {
|
if (sscanf(packet, "vAttach;%08lx", &addr) == 1) {
|
||||||
/* Attach to remote target processor */
|
/* Attach to remote target processor */
|
||||||
cur_target = target_attach_n(addr, &gdb_controller);
|
cur_target = target_attach_n(addr, &gdb_controller);
|
||||||
if(cur_target)
|
if(cur_target) {
|
||||||
|
morse(NULL, false);
|
||||||
gdb_putpacketz("T05");
|
gdb_putpacketz("T05");
|
||||||
else
|
} else
|
||||||
gdb_putpacketz("E01");
|
gdb_putpacketz("E01");
|
||||||
|
|
||||||
} else if (!strncmp(packet, "vRun", 4)) {
|
} else if (!strncmp(packet, "vRun", 4)) {
|
||||||
/* Parse command line for get_cmdline semihosting call */
|
/* Parse command line for get_cmdline semihosting call */
|
||||||
char cmdline[83];
|
char cmdline[83];
|
||||||
char *pbuf = cmdline;
|
char *pcmdline = cmdline;
|
||||||
char *tok = packet + 4;
|
char *tok = packet + 4;
|
||||||
if (*tok == ';') tok++;
|
if (*tok == ';') tok++;
|
||||||
*cmdline='\0';
|
*cmdline='\0';
|
||||||
while(*tok != '\0') {
|
while(*tok != '\0') {
|
||||||
if(strlen(cmdline)+3 >= sizeof(cmdline)) break;
|
if(strlen(cmdline)+3 >= sizeof(cmdline)) break;
|
||||||
if (*tok == ';') {
|
if (*tok == ';') {
|
||||||
*pbuf++=' ';
|
*pcmdline++=' ';
|
||||||
*pbuf='\0';
|
*pcmdline='\0';
|
||||||
tok++;
|
tok++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (isxdigit(*tok) && isxdigit(*(tok+1))) {
|
if (isxdigit(*tok) && isxdigit(*(tok+1))) {
|
||||||
unhexify(pbuf, tok, 2);
|
unhexify(pcmdline, tok, 2);
|
||||||
if ((*pbuf == ' ') || (*pbuf == '\\')) {
|
if ((*pcmdline == ' ') || (*pcmdline == '\\')) {
|
||||||
*(pbuf+1)=*pbuf;
|
*(pcmdline+1)=*pcmdline;
|
||||||
*pbuf++='\\';
|
*pcmdline++='\\';
|
||||||
}
|
}
|
||||||
pbuf++;
|
pcmdline++;
|
||||||
tok+=2;
|
tok+=2;
|
||||||
*pbuf='\0';
|
*pcmdline='\0';
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -470,12 +473,13 @@ handle_v_packet(char *packet, int plen)
|
|||||||
cur_target = target_attach(last_target,
|
cur_target = target_attach(last_target,
|
||||||
&gdb_controller);
|
&gdb_controller);
|
||||||
|
|
||||||
/* If we were able to attach to the target again */
|
/* If we were able to attach to the target again */
|
||||||
if (cur_target) {
|
if (cur_target) {
|
||||||
target_set_cmdline(cur_target, cmdline);
|
target_set_cmdline(cur_target, cmdline);
|
||||||
target_reset(cur_target);
|
target_reset(cur_target);
|
||||||
gdb_putpacketz("T05");
|
morse(NULL, false);
|
||||||
} else gdb_putpacketz("E01");
|
gdb_putpacketz("T05");
|
||||||
|
} else gdb_putpacketz("E01");
|
||||||
|
|
||||||
} else gdb_putpacketz("E01");
|
} else gdb_putpacketz("E01");
|
||||||
|
|
||||||
|
@ -158,7 +158,7 @@ void gdb_putpacket(const char *packet, int size)
|
|||||||
else
|
else
|
||||||
DEBUG_GDB_WIRE("\\x%02X", c);
|
DEBUG_GDB_WIRE("\\x%02X", c);
|
||||||
#endif
|
#endif
|
||||||
if((c == '$') || (c == '#') || (c == '}')) {
|
if((c == '$') || (c == '#') || (c == '}') || (c == '*')) {
|
||||||
gdb_if_putchar('}', 0);
|
gdb_if_putchar('}', 0);
|
||||||
gdb_if_putchar(c ^ 0x20, 0);
|
gdb_if_putchar(c ^ 0x20, 0);
|
||||||
csum += '}' + (c ^ 0x20);
|
csum += '}' + (c ^ 0x20);
|
||||||
|
@ -21,7 +21,9 @@
|
|||||||
#ifndef __GENERAL_H
|
#ifndef __GENERAL_H
|
||||||
#define __GENERAL_H
|
#define __GENERAL_H
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
#if !defined(_GNU_SOURCE)
|
||||||
|
# define _GNU_SOURCE
|
||||||
|
#endif
|
||||||
#if !defined(__USE_MINGW_ANSI_STDIO)
|
#if !defined(__USE_MINGW_ANSI_STDIO)
|
||||||
# define __USE_MINGW_ANSI_STDIO 1
|
# define __USE_MINGW_ANSI_STDIO 1
|
||||||
#endif
|
#endif
|
||||||
@ -57,18 +59,21 @@ enum BMP_DEBUG {
|
|||||||
* BMP PC-Hosted is the preferred way. Printing DEBUG_WARN
|
* BMP PC-Hosted is the preferred way. Printing DEBUG_WARN
|
||||||
* and DEBUG_INFO is kept for comptibiluty.
|
* and DEBUG_INFO is kept for comptibiluty.
|
||||||
*/
|
*/
|
||||||
# if defined(ENABLE_DEBUG)
|
# if !defined(PLATFORM_PRINTF)
|
||||||
# define DEBUG_WARN printf
|
# define PLATFORM_PRINTF printf
|
||||||
# define DEBUG_INFO printf
|
|
||||||
# else
|
|
||||||
# define DEBUG_WARN(...)
|
|
||||||
# define DEBUG_INFO(...)
|
|
||||||
# endif
|
# endif
|
||||||
# define DEBUG_GDB(...)
|
# if defined(ENABLE_DEBUG)
|
||||||
# define DEBUG_TARGET(...)
|
# define DEBUG_WARN PLATFORM_PRINTF
|
||||||
# define DEBUG_PROBE(...)
|
# define DEBUG_INFO PLATFORM_PRINTF
|
||||||
# define DEBUG_WIRE(...)
|
# else
|
||||||
# define DEBUG_GDB_WIRE(...)
|
# define DEBUG_WARN(...) do {} while(0)
|
||||||
|
# define DEBUG_INFO(...) do {} while(0)
|
||||||
|
# endif
|
||||||
|
# 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
|
#else
|
||||||
# include <stdarg.h>
|
# include <stdarg.h>
|
||||||
extern int cl_debuglevel;
|
extern int cl_debuglevel;
|
||||||
@ -159,5 +164,11 @@ static inline void DEBUG_WIRE(const char *format, ...)
|
|||||||
#undef MAX
|
#undef MAX
|
||||||
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
|
#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
|
#endif
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ void morse(const char *msg, char repeat)
|
|||||||
DEBUG_WARN("%s\n", msg);
|
DEBUG_WARN("%s\n", msg);
|
||||||
(void) repeat;
|
(void) repeat;
|
||||||
#else
|
#else
|
||||||
morse_msg = morse_ptr = msg;
|
morse_msg = morse_ptr = msg;
|
||||||
morse_repeat = repeat;
|
morse_repeat = repeat;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -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 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,
|
.bLength = USB_DT_DEVICE_SIZE,
|
||||||
.bDescriptorType = USB_DT_DEVICE,
|
.bDescriptorType = USB_DT_DEVICE,
|
||||||
.bcdUSB = 0x0200,
|
.bcdUSB = 0x0200,
|
||||||
@ -555,7 +555,7 @@ void cdcacm_init(void)
|
|||||||
|
|
||||||
serial_no_read(serial_no);
|
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 *),
|
sizeof(usb_strings)/sizeof(char *),
|
||||||
usbd_control_buffer, sizeof(usbd_control_buffer));
|
usbd_control_buffer, sizeof(usbd_control_buffer));
|
||||||
|
|
||||||
|
@ -8,8 +8,15 @@ CFLAGS += -Istm32/include -mcpu=cortex-m4 -mthumb \
|
|||||||
-DSTM32F4 -I../libopencm3/include \
|
-DSTM32F4 -I../libopencm3/include \
|
||||||
-Iplatforms/stm32
|
-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 \
|
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 \
|
-Wl,-Map=mapfile -mthumb -mcpu=cortex-m4 -Wl,-gc-sections \
|
||||||
-mfloat-abi=hard -mfpu=fpv4-sp-d16 \
|
-mfloat-abi=hard -mfpu=fpv4-sp-d16 \
|
||||||
-L../libopencm3/lib
|
-L../libopencm3/lib
|
||||||
|
@ -11,3 +11,55 @@ PC6: TDO/TRACESWO<br>
|
|||||||
|
|
||||||
PC1: TRST<br>
|
PC1: TRST<br>
|
||||||
PC8: SRST<br>
|
PC8: SRST<br>
|
||||||
|
|
||||||
|
# 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
|
||||||
|
@ -37,20 +37,32 @@
|
|||||||
#include <libopencm3/cm3/systick.h>
|
#include <libopencm3/cm3/systick.h>
|
||||||
#include <libopencm3/cm3/cortex.h>
|
#include <libopencm3/cm3/cortex.h>
|
||||||
|
|
||||||
|
#ifdef BLACKPILL
|
||||||
|
#include <libopencm3/usb/dwc/otg_fs.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
jmp_buf fatal_error_jmpbuf;
|
jmp_buf fatal_error_jmpbuf;
|
||||||
extern char _ebss[];
|
extern char _ebss[];
|
||||||
|
|
||||||
void platform_init(void)
|
void platform_init(void)
|
||||||
{
|
{
|
||||||
volatile uint32_t *magic = (uint32_t *)_ebss;
|
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_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) ||
|
if (gpio_get(GPIOA, GPIO0) ||
|
||||||
((magic[0] == BOOTMAGIC0) && (magic[1] == BOOTMAGIC1))) {
|
((magic[0] == BOOTMAGIC0) && (magic[1] == BOOTMAGIC1)))
|
||||||
|
{
|
||||||
magic[0] = 0;
|
magic[0] = 0;
|
||||||
magic[1] = 0;
|
magic[1] = 0;
|
||||||
/* Assert blue LED as indicator we are in the bootloader */
|
/* 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_mode_setup(LED_PORT, GPIO_MODE_OUTPUT,
|
||||||
GPIO_PUPD_NONE, LED_BOOTLOADER);
|
GPIO_PUPD_NONE, LED_BOOTLOADER);
|
||||||
gpio_set(LED_PORT, 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!*/
|
As we just come out of reset, no other deinit is needed!*/
|
||||||
rcc_periph_clock_enable(RCC_SYSCFG);
|
rcc_periph_clock_enable(RCC_SYSCFG);
|
||||||
SYSCFG_MEMRM &= ~3;
|
SYSCFG_MEMRM &= ~3;
|
||||||
SYSCFG_MEMRM |= 1;
|
SYSCFG_MEMRM |= 1;
|
||||||
scb_reset_core();
|
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]);
|
rcc_clock_setup_pll(&rcc_hse_8mhz_3v3[RCC_CLOCK_3V3_168MHZ]);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Enable peripherals */
|
/* Enable peripherals */
|
||||||
rcc_periph_clock_enable(RCC_OTGFS);
|
rcc_periph_clock_enable(RCC_OTGFS);
|
||||||
rcc_periph_clock_enable(RCC_GPIOC);
|
|
||||||
rcc_periph_clock_enable(RCC_GPIOD);
|
|
||||||
rcc_periph_clock_enable(RCC_CRC);
|
rcc_periph_clock_enable(RCC_CRC);
|
||||||
|
|
||||||
/* Set up USB Pins and alternate function*/
|
/* 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);
|
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;
|
GPIOC_OSPEEDR |= 0xA20;
|
||||||
|
#endif
|
||||||
|
|
||||||
gpio_mode_setup(JTAG_PORT, GPIO_MODE_OUTPUT,
|
gpio_mode_setup(JTAG_PORT, GPIO_MODE_OUTPUT,
|
||||||
GPIO_PUPD_NONE,
|
GPIO_PUPD_NONE,
|
||||||
TCK_PIN | TDI_PIN);
|
TCK_PIN | TDI_PIN);
|
||||||
gpio_mode_setup(JTAG_PORT, GPIO_MODE_INPUT,
|
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,
|
gpio_set_output_options(JTAG_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ,
|
||||||
TCK_PIN | TDI_PIN | TMS_PIN);
|
TCK_PIN | TDI_PIN | TMS_PIN);
|
||||||
gpio_mode_setup(TDO_PORT, GPIO_MODE_INPUT,
|
gpio_mode_setup(TDO_PORT, GPIO_MODE_INPUT,
|
||||||
GPIO_PUPD_NONE,
|
GPIO_PUPD_NONE,
|
||||||
TDO_PIN);
|
TDO_PIN);
|
||||||
gpio_set_output_options(TDO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ,
|
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_mode_setup(LED_PORT, GPIO_MODE_OUTPUT,
|
||||||
GPIO_PUPD_NONE,
|
GPIO_PUPD_NONE,
|
||||||
LED_UART | LED_IDLE_RUN | LED_ERROR | LED_BOOTLOADER);
|
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();
|
platform_timing_init();
|
||||||
usbuart_init();
|
usbuart_init();
|
||||||
cdcacm_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; }
|
void platform_srst_set_val(bool assert) { (void)assert; }
|
||||||
@ -108,8 +141,20 @@ const char *platform_target_voltage(void)
|
|||||||
|
|
||||||
void platform_request_boot(void)
|
void platform_request_boot(void)
|
||||||
{
|
{
|
||||||
uint32_t *magic = (uint32_t *) &_ebss;
|
uint32_t *magic = (uint32_t *)&_ebss;
|
||||||
magic[0] = BOOTMAGIC0;
|
magic[0] = BOOTMAGIC0;
|
||||||
magic[1] = BOOTMAGIC1;
|
magic[1] = BOOTMAGIC1;
|
||||||
scb_reset_system();
|
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
|
@ -31,6 +31,55 @@
|
|||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
|
|
||||||
#define PLATFORM_HAS_TRACESWO
|
#define PLATFORM_HAS_TRACESWO
|
||||||
|
#ifdef BLACKPILL
|
||||||
|
#define PLATFORM_IDENT "(F4Discovery/BlackPillV2) "
|
||||||
|
/* Important pin mappings for STM32 implementation:
|
||||||
|
* JTAG/SWD
|
||||||
|
* PA1: TDI<br>
|
||||||
|
* PA13: TMS/SWDIO<br>
|
||||||
|
* PA14: TCK/SWCLK<br>
|
||||||
|
* PB3: TDO/TRACESWO<br>
|
||||||
|
* PB5: TRST<br>
|
||||||
|
* PB4: SRST<br>
|
||||||
|
* 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) "
|
#define PLATFORM_IDENT "(F4Discovery) "
|
||||||
|
|
||||||
/* Important pin mappings for STM32 implementation:
|
/* Important pin mappings for STM32 implementation:
|
||||||
@ -78,6 +127,8 @@
|
|||||||
#define LED_IDLE_RUN GPIO13
|
#define LED_IDLE_RUN GPIO13
|
||||||
#define LED_ERROR GPIO14
|
#define LED_ERROR GPIO14
|
||||||
#define LED_BOOTLOADER GPIO15
|
#define LED_BOOTLOADER GPIO15
|
||||||
|
#endif
|
||||||
|
|
||||||
#define BOOTMAGIC0 0xb007da7a
|
#define BOOTMAGIC0 0xb007da7a
|
||||||
#define BOOTMAGIC1 0xbaadfeed
|
#define BOOTMAGIC1 0xbaadfeed
|
||||||
|
|
||||||
|
@ -2,12 +2,12 @@ SYS = $(shell $(CC) -dumpmachine)
|
|||||||
CFLAGS += -DENABLE_DEBUG -DPLATFORM_HAS_DEBUG
|
CFLAGS += -DENABLE_DEBUG -DPLATFORM_HAS_DEBUG
|
||||||
CFLAGS +=-I ./target -I./platforms/pc
|
CFLAGS +=-I ./target -I./platforms/pc
|
||||||
|
|
||||||
# Define HOSTED_BMP_ONLY to '1' in order to build the hosted blackmagic
|
# Define HOSTED_BMP_ONLY to '0' in order to build the hosted blackmagic
|
||||||
# executable with support for native BMP probes only. This makes
|
# executable with support for other probes beside BMP. Default HOSTED_BMP_ONLY
|
||||||
# linking against the libftdi and libusb libraries unnecessary. This can
|
# == 1 makes linking against the libftdi and libusb libraries unnecessary.
|
||||||
# be useful to minimize external dependencies, and make building on
|
# This can be useful to minimize external dependencies, and make building on
|
||||||
# windows systems easier.
|
# windows systems easier and is default now.
|
||||||
HOSTED_BMP_ONLY ?= 0
|
HOSTED_BMP_ONLY ?= 1
|
||||||
CFLAGS += -DHOSTED_BMP_ONLY=$(HOSTED_BMP_ONLY)
|
CFLAGS += -DHOSTED_BMP_ONLY=$(HOSTED_BMP_ONLY)
|
||||||
|
|
||||||
ifneq (, $(findstring linux, $(SYS)))
|
ifneq (, $(findstring linux, $(SYS)))
|
||||||
@ -59,7 +59,7 @@ ifneq ($(HOSTED_BMP_ONLY), 1)
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
VPATH += platforms/pc
|
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
|
SRC += bmp_remote.c remote_swdptap.c remote_jtagtap.c
|
||||||
ifneq ($(HOSTED_BMP_ONLY), 1)
|
ifneq ($(HOSTED_BMP_ONLY), 1)
|
||||||
SRC += bmp_libusb.c stlinkv2.c
|
SRC += bmp_libusb.c stlinkv2.c
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
# PC-Hosted BMP
|
# 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
|
## Description
|
||||||
PC-hosted BMP run on the PC and compiles as "blackmagic". When started,
|
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.
|
given on the command line to select one of several probes.
|
||||||
|
|
||||||
When started without any other argument beside the probe selection, a
|
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
|
connect to the BMP with the CDCACM GDB serial server. GDB functionality
|
||||||
is the same, monitor option may vary.
|
is the same, monitor option may vary.
|
||||||
|
|
||||||
@ -60,9 +62,9 @@ blackmagic -M "option help"
|
|||||||
## Compiling on windows
|
## Compiling on windows
|
||||||
|
|
||||||
You can crosscompile blackmagic for windows with mingw or 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
|
with cygwin. For suppport of other probes beside BMP, headers for libftdi1 and
|
||||||
needed. For running, libftdi1.dll and libusb-1.0.dll are needed and
|
libusb-1.0 are needed. For running, libftdi1.dll and libusb-1.0.dll are needed
|
||||||
the executable must be able to find them. Mingw on cygwin does not provide
|
and the executable must be able to find them. Mingw on cygwin does not provide
|
||||||
a libftdi package yet.
|
a libftdi package yet.
|
||||||
|
|
||||||
PC-hosted BMP for windows can also be built with [MSYS2](https://www.msys2.org/),
|
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
|
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).
|
https://zadig.akeo.ie/. Choose WinUSB(libusb-1.0).
|
||||||
|
|
||||||
Running cygwin/blackmagic in a cygwin console, the program does not react
|
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
|
| Debugger | Speed | Remarks
|
||||||
| ------------ | ----- | ------
|
| ------------ | ----- | ------
|
||||||
| REMOTE_BMP | +++ | Requires recent firmware for decent speed
|
| 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 V3 | ++++ | Requires recent firmware, Only STM32 devices supported!
|
||||||
| ST-Link V2 | +++ | Requires recent firmware, No CDCACM uart! Cortex only!
|
| ST-Link V2 | +++ | Requires recent firmware, No CDCACM uart! Cortex only!
|
||||||
| ST-Link V2/1 | +++ | Requires recent firmware, Cortex only!
|
| ST-Link V2/1 | +++ | Requires recent firmware, Cortex only!
|
||||||
|
@ -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");
|
DEBUG_WARN("BMP in botloader mode found. Restart or reflash!\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else if ((type = find_cmsis_dap_interface(dev, info)) != BMP_TYPE_NONE) {
|
} else if ((type == BMP_TYPE_NONE) &&
|
||||||
/* type was set by the expression */
|
((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"))) {
|
} else if ((strstr(manufacturer, "CMSIS")) || (strstr(product, "CMSIS"))) {
|
||||||
type = BMP_TYPE_CMSIS_DAP_V1;
|
type = BMP_TYPE_CMSIS_DAP_V1;
|
||||||
} else if (desc.idVendor == VENDOR_ID_STLINK) {
|
} else if (desc.idVendor == VENDOR_ID_STLINK) {
|
||||||
|
@ -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)
|
const uint8_t *DI, int ticks)
|
||||||
{
|
{
|
||||||
dap_jtagtap_tdi_tdo_seq(DO, (final_tms), NULL, DI, 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,
|
static void cmsis_dap_jtagtap_tdi_seq(const uint8_t final_tms,
|
||||||
|
@ -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,
|
void dap_jtagtap_tdi_tdo_seq(uint8_t *DO, bool final_tms, const uint8_t *TMS,
|
||||||
const uint8_t *DI, int ticks)
|
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];
|
uint8_t buf[64];
|
||||||
|
const uint8_t *din = DI;
|
||||||
|
uint8_t *dout = DO;
|
||||||
if (!TMS) {
|
if (!TMS) {
|
||||||
int last_byte = 0;
|
int last_byte = last_byte = (ticks - 1) >> 3;
|
||||||
int last_bit = 0;
|
int last_bit = (ticks - 1) & 7;
|
||||||
if (final_tms) {
|
if (final_tms)
|
||||||
last_byte = ticks >> 3;
|
|
||||||
last_bit = ticks & 7;
|
|
||||||
ticks --;
|
ticks --;
|
||||||
}
|
|
||||||
while (ticks) {
|
while (ticks) {
|
||||||
int transfers = ticks;
|
int transfers = ticks;
|
||||||
if (transfers > 64)
|
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;
|
uint8_t *p = buf;
|
||||||
*p++ = ID_DAP_JTAG_SEQUENCE;
|
*p++ = ID_DAP_JTAG_SEQUENCE;
|
||||||
*p++ = 1;
|
*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;
|
int n_di_bytes = (transfers + 7) >> 3;
|
||||||
if (DI) {
|
if (din) {
|
||||||
p = memcpy(p, DI, n_di_bytes);
|
p = memcpy(p, din, n_di_bytes);
|
||||||
DI += n_di_bytes;
|
din += n_di_bytes;
|
||||||
} else {
|
} else {
|
||||||
p = memset(p, 0xff, n_di_bytes);
|
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);
|
dbg_dap_cmd(buf, sizeof(buf), p - buf);
|
||||||
if (buf[0] != DAP_OK)
|
if (buf[0] != DAP_OK)
|
||||||
DEBUG_WARN("dap_jtagtap_tdi_tdo_seq failed %02x\n", buf[0]);
|
DEBUG_WARN("dap_jtagtap_tdi_tdo_seq failed %02x\n", buf[0]);
|
||||||
if (DO) {
|
if (dout) {
|
||||||
memcpy(DO, &buf[1], (transfers + 7) >> 3);
|
memcpy(dout, &buf[1], (transfers + 7) >> 3);
|
||||||
DO += (transfers + 7) >> 3;
|
dout += (transfers + 7) >> 3;
|
||||||
}
|
}
|
||||||
ticks -= transfers;
|
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;
|
uint8_t *p = buf;
|
||||||
*p++ = ID_DAP_JTAG_SEQUENCE;
|
*p++ = ID_DAP_JTAG_SEQUENCE;
|
||||||
*p++ = 1;
|
*p++ = 1;
|
||||||
*p++ = 1 | ((DO) ? DAP_JTAG_TDO_CAPTURE : 0) | DAP_JTAG_TMS;
|
*p++ = 1 | ((dout) ? DAP_JTAG_TDO_CAPTURE : 0) | DAP_JTAG_TMS;
|
||||||
if (DI) {
|
if (din) {
|
||||||
*p++ = ((DI[last_byte] & (1 << last_bit)) ? 1 : 0);
|
*p++ = ((DI[last_byte] & (1 << last_bit)) ? 1 : 0);
|
||||||
} else {
|
} else {
|
||||||
*p++ = 0;
|
*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);
|
dbg_dap_cmd(buf, sizeof(buf), p - buf);
|
||||||
if (buf[0] == DAP_ERROR)
|
if (buf[0] == DAP_ERROR)
|
||||||
DEBUG_WARN("dap_jtagtap_tdi_tdo_seq failed %02x\n", buf[0]);
|
DEBUG_WARN("dap_jtagtap_tdi_tdo_seq failed %02x\n", buf[0]);
|
||||||
if (DO) {
|
if (dout) {
|
||||||
if (buf[1] & 1)
|
if (buf[1] & 1)
|
||||||
DO[last_byte] |= (1 << last_bit);
|
DO[last_byte] |= (1 << last_bit);
|
||||||
else
|
else
|
||||||
@ -709,11 +711,11 @@ void dap_jtagtap_tdi_tdo_seq(uint8_t *DO, bool final_tms, const uint8_t *TMS,
|
|||||||
*p++ = transfers;
|
*p++ = transfers;
|
||||||
for (int i = 0; i < transfers; i++) {
|
for (int i = 0; i < transfers; i++) {
|
||||||
*p++ = 1 | ((DO) ? DAP_JTAG_TDO_CAPTURE : 0) |
|
*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)
|
if (DI)
|
||||||
*p++ = (DI[i >> 8] & (1 << (i & 7))) ? 1 : 0;
|
*p++ = (DI[i / 8] & (1 << (i & 7))) ? 1 : 0;
|
||||||
else
|
else
|
||||||
*p++ = 0x55;
|
*p++ = 1;
|
||||||
}
|
}
|
||||||
dbg_dap_cmd(buf, sizeof(buf), p - buf);
|
dbg_dap_cmd(buf, sizeof(buf), p - buf);
|
||||||
if (buf[0] == DAP_ERROR)
|
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) {
|
if (DO) {
|
||||||
for (int i = 0; i < transfers; i++) {
|
for (int i = 0; i < transfers; i++) {
|
||||||
if (buf[i + 1])
|
if (buf[i + 1])
|
||||||
DO[i >> 8] |= (1 << (i & 7));
|
DO[i / 8] |= (1 << (i & 7));
|
||||||
else
|
else
|
||||||
DO[i >> 8] &= ~(1 << (i & 7));
|
DO[i / 8] &= ~(1 << (i & 7));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ticks -= transfers;
|
ticks -= transfers;
|
||||||
|
@ -123,8 +123,8 @@ cable_desc_t cable_desc[] = {
|
|||||||
.init.ddr_low = PIN4,
|
.init.ddr_low = PIN4,
|
||||||
.init.data_high = PIN4 | PIN3 | PIN2,
|
.init.data_high = PIN4 | PIN3 | PIN2,
|
||||||
.init.ddr_high = PIN4 | PIN3 | PIN2 | PIN1 | PIN0,
|
.init.ddr_high = PIN4 | PIN3 | PIN2 | PIN1 | PIN0,
|
||||||
.assert_srst.data_high = ~PIN2,
|
.assert_srst.data_high = ~PIN3,
|
||||||
.deassert_srst.data_high = PIN2,
|
.deassert_srst.data_high = PIN3,
|
||||||
.srst_get_port_cmd = GET_BITS_LOW,
|
.srst_get_port_cmd = GET_BITS_LOW,
|
||||||
.srst_get_pin = PIN6,
|
.srst_get_pin = PIN6,
|
||||||
.description = "FTDIJTAG",
|
.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) || (data->ddr_low)) {
|
||||||
if (data->data_low > 0)
|
if (data->data_low > 0)
|
||||||
active_state.data_low |= (data->data_low & 0xff);
|
active_state.data_low |= (data->data_low & 0xff);
|
||||||
else
|
else if (data->data_low < 0)
|
||||||
active_state.data_low &= (data->data_low & 0xff);
|
active_state.data_low &= (data->data_low & 0xff);
|
||||||
if (data->ddr_low > 0)
|
if (data->ddr_low > 0)
|
||||||
active_state.ddr_low |= (data->ddr_low & 0xff);
|
active_state.ddr_low |= (data->ddr_low & 0xff);
|
||||||
else
|
else if (data->ddr_low < 0)
|
||||||
active_state.ddr_low &= (data->ddr_low & 0xff);
|
active_state.ddr_low &= (data->ddr_low & 0xff);
|
||||||
cmd[index++] = SET_BITS_LOW;
|
cmd[index++] = SET_BITS_LOW;
|
||||||
cmd[index++] = active_state.data_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) || (data->ddr_high)) {
|
||||||
if (data->data_high > 0)
|
if (data->data_high > 0)
|
||||||
active_state.data_high |= (data->data_high & 0xff);
|
active_state.data_high |= (data->data_high & 0xff);
|
||||||
else
|
else if (data->data_high < 0)
|
||||||
active_state.data_high &= (data->data_high & 0xff);
|
active_state.data_high &= (data->data_high & 0xff);
|
||||||
if (data->ddr_high > 0)
|
if (data->ddr_high > 0)
|
||||||
active_state.ddr_high |= (data->ddr_high & 0xff);
|
active_state.ddr_high |= (data->ddr_high & 0xff);
|
||||||
else
|
else if (data->ddr_high < 0)
|
||||||
active_state.ddr_high &= (data->ddr_high & 0xff);
|
active_state.ddr_high &= (data->ddr_high & 0xff);
|
||||||
cmd[index++] = SET_BITS_HIGH;
|
cmd[index++] = SET_BITS_HIGH;
|
||||||
cmd[index++] = active_state.data_high;
|
cmd[index++] = active_state.data_high;
|
||||||
@ -552,7 +552,8 @@ void libftdi_jtagtap_tdi_tdo_seq(
|
|||||||
if(!ticks) return;
|
if(!ticks) return;
|
||||||
if (!DI && !DO) 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--;
|
if(final_tms) ticks--;
|
||||||
rticks = ticks & 7;
|
rticks = ticks & 7;
|
||||||
ticks >>= 3;
|
ticks >>= 3;
|
||||||
@ -593,7 +594,6 @@ void libftdi_jtagtap_tdi_tdo_seq(
|
|||||||
if(final_tms) rsize--;
|
if(final_tms) rsize--;
|
||||||
|
|
||||||
while(rsize--) {
|
while(rsize--) {
|
||||||
/*if(rsize) printf("%02X ", tmp[index]);*/
|
|
||||||
*DO++ = tmp[index++];
|
*DO++ = tmp[index++];
|
||||||
}
|
}
|
||||||
if (rticks == 0)
|
if (rticks == 0)
|
||||||
@ -606,7 +606,6 @@ void libftdi_jtagtap_tdi_tdo_seq(
|
|||||||
if(rticks) {
|
if(rticks) {
|
||||||
*DO >>= (8-rticks);
|
*DO >>= (8-rticks);
|
||||||
}
|
}
|
||||||
/*printf("%02X\n", *DO);*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,6 +114,8 @@ void libftdi_jtagtap_tdi_tdo_seq(
|
|||||||
bool libftdi_swd_possible(bool *do_mpsse, bool *direct_bb_swd) {return false;};
|
bool libftdi_swd_possible(bool *do_mpsse, bool *direct_bb_swd) {return false;};
|
||||||
void libftdi_max_frequency_set(uint32_t freq) {};
|
void libftdi_max_frequency_set(uint32_t freq) {};
|
||||||
uint32_t libftdi_max_frequency_get(void) {return 0;};
|
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
|
# pragma GCC diagnostic pop
|
||||||
#else
|
#else
|
||||||
#include <ftdi.h>
|
#include <ftdi.h>
|
||||||
@ -134,6 +136,8 @@ void libftdi_jtagtap_tdi_tdo_seq(
|
|||||||
bool libftdi_swd_possible(bool *do_mpsse, bool *direct_bb_swd);
|
bool libftdi_swd_possible(bool *do_mpsse, bool *direct_bb_swd);
|
||||||
void libftdi_max_frequency_set(uint32_t freq);
|
void libftdi_max_frequency_set(uint32_t freq);
|
||||||
uint32_t libftdi_max_frequency_get(void);
|
uint32_t libftdi_max_frequency_get(void);
|
||||||
|
void libftdi_srst_set_val(bool assert);
|
||||||
|
bool libftdi_srst_get_val(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MPSSE_SK 1
|
#define MPSSE_SK 1
|
||||||
|
@ -299,6 +299,8 @@ void platform_srst_set_val(bool assert)
|
|||||||
return remote_srst_set_val(assert);
|
return remote_srst_set_val(assert);
|
||||||
case BMP_TYPE_JLINK:
|
case BMP_TYPE_JLINK:
|
||||||
return jlink_srst_set_val(&info, assert);
|
return jlink_srst_set_val(&info, assert);
|
||||||
|
case BMP_TYPE_LIBFTDI:
|
||||||
|
return libftdi_srst_set_val(assert);
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -313,6 +315,8 @@ bool platform_srst_get_val(void)
|
|||||||
return stlink_srst_get_val();
|
return stlink_srst_get_val();
|
||||||
case BMP_TYPE_JLINK:
|
case BMP_TYPE_JLINK:
|
||||||
return jlink_srst_get_val(&info);
|
return jlink_srst_get_val(&info);
|
||||||
|
case BMP_TYPE_LIBFTDI:
|
||||||
|
return libftdi_srst_get_val();
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,8 @@ void platform_buffer_flush(void);
|
|||||||
#define SET_IDLE_STATE(x)
|
#define SET_IDLE_STATE(x)
|
||||||
#define SET_RUN_STATE(x)
|
#define SET_RUN_STATE(x)
|
||||||
|
|
||||||
|
#define SYSTICKHZ 1000
|
||||||
|
|
||||||
#define VENDOR_ID_BMP 0x1d50
|
#define VENDOR_ID_BMP 0x1d50
|
||||||
#define PRODUCT_ID_BMP_BL 0x6017
|
#define PRODUCT_ID_BMP_BL 0x6017
|
||||||
#define PRODUCT_ID_BMP 0x6018
|
#define PRODUCT_ID_BMP 0x6018
|
||||||
|
@ -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(
|
static void jtagtap_tdi_tdo_seq(
|
||||||
uint8_t *DO, const uint8_t final_tms, const uint8_t *DI, int ticks)
|
uint8_t *DO, const uint8_t final_tms, const uint8_t *DI, int ticks)
|
||||||
{
|
{
|
||||||
uint8_t construct[REMOTE_MAX_MSG_SIZE];
|
uint8_t construct[REMOTE_MAX_MSG_SIZE];
|
||||||
int s;
|
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;
|
s = platform_buffer_read(construct, REMOTE_MAX_MSG_SIZE);
|
||||||
|
if ((!s) || (construct[0] == REMOTE_RESP_ERR)) {
|
||||||
/* Reduce the length of DI according to the bits we're transmitting */
|
DEBUG_WARN("jtagtap_tms_seq failed, error %s\n",
|
||||||
DIl &= (1LL << (ticks + 1))-1;
|
s ? (char *)&(construct[1]) : "unknown");
|
||||||
|
exit(-1);
|
||||||
s = snprintf((char *)construct, REMOTE_MAX_MSG_SIZE,
|
}
|
||||||
REMOTE_JTAG_TDIDO_STR,
|
if (DO)
|
||||||
final_tms ? REMOTE_TDITDO_TMS : REMOTE_TDITDO_NOTMS,
|
*DOl++ = remotehston(-1, (char *)&construct[1]);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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) ==
|
if((jtag_devs[i].jd_idcode & dev_descr[j].idmask) ==
|
||||||
dev_descr[j].idcode) {
|
dev_descr[j].idcode) {
|
||||||
if(dev_descr[j].handler)
|
if(dev_descr[j].handler)
|
||||||
dev_descr[j].handler(i, dev_descr[j].idcode);
|
dev_descr[j].handler(&jtag_devs[i]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ ifeq ($(ENABLE_DEBUG), 1)
|
|||||||
CFLAGS += -g3 -ggdb
|
CFLAGS += -g3 -ggdb
|
||||||
endif
|
endif
|
||||||
|
|
||||||
CFLAGS += -mthumb -mcpu=cortex-m0plus \
|
CFLAGS += -mthumb -mcpu=cortex-m0plus -DDFU_SERIAL_LENGTH=9 \
|
||||||
-DSAMD -DSAMD21E17 -DBLACKMAGIC -I../libopencm3/include \
|
-DSAMD -DSAMD21E17 -DBLACKMAGIC -I../libopencm3/include \
|
||||||
-Iplatforms/samd -msoft-float -ffunction-sections -fdata-sections -MD
|
-Iplatforms/samd -msoft-float -ffunction-sections -fdata-sections -MD
|
||||||
|
|
||||||
|
@ -252,11 +252,8 @@ const char *platform_target_voltage(void)
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *serial_no_read(char *s, int max)
|
char *serial_no_read(char *s)
|
||||||
{
|
{
|
||||||
if (max >= 8)
|
|
||||||
max = 8;
|
|
||||||
|
|
||||||
#ifdef CUSTOM_SER
|
#ifdef CUSTOM_SER
|
||||||
s[0] = 'J';
|
s[0] = 'J';
|
||||||
s[1] = 'E';
|
s[1] = 'E';
|
||||||
@ -265,17 +262,18 @@ char *serial_no_read(char *s, int max)
|
|||||||
return s;
|
return s;
|
||||||
#else
|
#else
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
volatile uint32_t unique_id = *(volatile uint32_t *)0x0080A00C +
|
volatile uint32_t unique_id = *(volatile uint32_t *)0x0080A00C +
|
||||||
*(volatile uint32_t *)0x0080A040 +
|
*(volatile uint32_t *)0x0080A040 +
|
||||||
*(volatile uint32_t *)0x0080A044 +
|
*(volatile uint32_t *)0x0080A044 +
|
||||||
*(volatile uint32_t *)0x0080A048;
|
*(volatile uint32_t *)0x0080A048;
|
||||||
|
|
||||||
/* Fetch serial number from chip's unique ID */
|
/* Fetch serial number from chip's unique ID */
|
||||||
for(i = 0; i < max; i++) {
|
for(i = 0; i < 8; i++) {
|
||||||
s[7-i] = ((unique_id >> (4*i)) & 0xF) + '0';
|
s[7-i] = ((unique_id >> (4*i)) & 0xF) + '0';
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = 0; i < max; i++)
|
for(i = 0; i < 8; i++)
|
||||||
if(s[i] > '9')
|
if(s[i] > '9')
|
||||||
s[i] += 'A' - '9' - 1;
|
s[i] += 'A' - '9' - 1;
|
||||||
s[8] = 0;
|
s[8] = 0;
|
||||||
|
@ -25,9 +25,6 @@
|
|||||||
#include <libopencm3/cm3/systick.h>
|
#include <libopencm3/cm3/systick.h>
|
||||||
#include <libopencm3/lm4f/usb.h>
|
#include <libopencm3/lm4f/usb.h>
|
||||||
|
|
||||||
#define SYSTICKHZ 100
|
|
||||||
#define SYSTICKMS (1000 / SYSTICKHZ)
|
|
||||||
|
|
||||||
#define PLL_DIV_80MHZ 5
|
#define PLL_DIV_80MHZ 5
|
||||||
#define PLL_DIV_25MHZ 16
|
#define PLL_DIV_25MHZ 16
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include "general.h"
|
#include "general.h"
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <ctype.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
@ -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("\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-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-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"
|
DEBUG_WARN("\t-t\t\t: Scan SWD or JTAG and display information about \n"
|
||||||
"\t\t\t connected devices\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");
|
"\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"
|
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");
|
"\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");
|
"\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-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-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-H\t\t: Do not use high level commands (BMP-Remote)\n");
|
||||||
DEBUG_WARN("\t-m <target>\t: Use (target)id for SWD multi-drop.\n");
|
DEBUG_WARN("\t-m <target>\t: Use (target)id for SWD multi-drop.\n");
|
||||||
DEBUG_WARN("\t-M <string>\t: Run target specific monitor commands. Quote multi\n");
|
DEBUG_WARN("\t-M <string>\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_size = 0xffffffff;
|
||||||
opt->opt_flash_start = 0xffffffff;
|
opt->opt_flash_start = 0xffffffff;
|
||||||
opt->opt_max_swj_frequency = 4000000;
|
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) {
|
switch(c) {
|
||||||
case 'c':
|
case 'c':
|
||||||
if (optarg)
|
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;
|
opt->opt_mode = BMP_MODE_FLASH_READ;
|
||||||
break;
|
break;
|
||||||
case 'R':
|
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;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
opt->opt_tpwr = true;
|
opt->opt_tpwr = true;
|
||||||
@ -321,7 +325,8 @@ void cl_init(BMP_CL_OPTIONS_t *opt, int argc, char **argv)
|
|||||||
/* Checks */
|
/* Checks */
|
||||||
if ((opt->opt_flash_file) && ((opt->opt_mode == BMP_MODE_TEST ) ||
|
if ((opt->opt_flash_file) && ((opt->opt_mode == BMP_MODE_TEST ) ||
|
||||||
(opt->opt_mode == BMP_MODE_SWJ_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");
|
DEBUG_WARN("Ignoring filename in reset/test mode\n");
|
||||||
opt->opt_flash_file = NULL;
|
opt->opt_flash_file = NULL;
|
||||||
}
|
}
|
||||||
@ -352,6 +357,12 @@ int cl_execute(BMP_CL_OPTIONS_t *opt)
|
|||||||
platform_target_set_power(true);
|
platform_target_set_power(true);
|
||||||
platform_delay(500);
|
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)
|
if (opt->opt_connect_under_reset)
|
||||||
DEBUG_INFO("Connecting under reset\n");
|
DEBUG_INFO("Connecting under reset\n");
|
||||||
connect_assert_srst = opt->opt_connect_under_reset;
|
connect_assert_srst = opt->opt_connect_under_reset;
|
||||||
@ -364,7 +375,7 @@ int cl_execute(BMP_CL_OPTIONS_t *opt)
|
|||||||
} else {
|
} else {
|
||||||
num_targets = platform_adiv5_swdp_scan(opt->opt_targetid);
|
num_targets = platform_adiv5_swdp_scan(opt->opt_targetid);
|
||||||
if (!num_targets) {
|
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);
|
num_targets = platform_jtag_scan(NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -419,9 +430,9 @@ int cl_execute(BMP_CL_OPTIONS_t *opt)
|
|||||||
if (opt->opt_flash_start == 0xffffffff)
|
if (opt->opt_flash_start == 0xffffffff)
|
||||||
opt->opt_flash_start = lowest_flash_start;
|
opt->opt_flash_start = lowest_flash_start;
|
||||||
if ((opt->opt_flash_size == 0xffffffff) &&
|
if ((opt->opt_flash_size == 0xffffffff) &&
|
||||||
(opt->opt_mode != BMP_MODE_FLASH_WRITE) &&
|
(opt->opt_mode != BMP_MODE_FLASH_WRITE) &&
|
||||||
(opt->opt_mode != BMP_MODE_FLASH_VERIFY) &&
|
(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;
|
opt->opt_flash_size = lowest_flash_size;
|
||||||
if (opt->opt_mode == BMP_MODE_SWJ_TEST) {
|
if (opt->opt_mode == BMP_MODE_SWJ_TEST) {
|
||||||
switch (t->core[0]) {
|
switch (t->core[0]) {
|
||||||
@ -466,7 +477,7 @@ int cl_execute(BMP_CL_OPTIONS_t *opt)
|
|||||||
map.size = opt->opt_flash_size;
|
map.size = opt->opt_flash_size;
|
||||||
if (opt->opt_mode == BMP_MODE_RESET) {
|
if (opt->opt_mode == BMP_MODE_RESET) {
|
||||||
target_reset(t);
|
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,
|
DEBUG_INFO("Erase %zu bytes at 0x%08" PRIx32 "\n", opt->opt_flash_size,
|
||||||
opt->opt_flash_start);
|
opt->opt_flash_start);
|
||||||
unsigned int erased = target_flash_erase(t, opt->opt_flash_start,
|
unsigned int erased = target_flash_erase(t, opt->opt_flash_start,
|
||||||
|
@ -30,6 +30,7 @@ enum bmp_cl_mode {
|
|||||||
BMP_MODE_DEBUG,
|
BMP_MODE_DEBUG,
|
||||||
BMP_MODE_TEST,
|
BMP_MODE_TEST,
|
||||||
BMP_MODE_RESET,
|
BMP_MODE_RESET,
|
||||||
|
BMP_MODE_RESET_HW,
|
||||||
BMP_MODE_FLASH_ERASE,
|
BMP_MODE_FLASH_ERASE,
|
||||||
BMP_MODE_FLASH_WRITE,
|
BMP_MODE_FLASH_WRITE,
|
||||||
BMP_MODE_FLASH_WRITE_VERIFY,
|
BMP_MODE_FLASH_WRITE_VERIFY,
|
||||||
|
28
src/platforms/stm32/blackpillv2.ld
Normal file
28
src/platforms/stm32/blackpillv2.ld
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libopenstm32 project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 Thomas Otto <tommi@viadmin.org>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* 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
|
@ -63,7 +63,7 @@ static struct {
|
|||||||
} prog;
|
} prog;
|
||||||
static uint8_t current_error;
|
static uint8_t current_error;
|
||||||
|
|
||||||
const struct usb_device_descriptor dev = {
|
const struct usb_device_descriptor dev_desc = {
|
||||||
.bLength = USB_DT_DEVICE_SIZE,
|
.bLength = USB_DT_DEVICE_SIZE,
|
||||||
.bDescriptorType = USB_DT_DEVICE,
|
.bDescriptorType = USB_DT_DEVICE,
|
||||||
.bcdUSB = 0x0200,
|
.bcdUSB = 0x0200,
|
||||||
@ -293,7 +293,7 @@ void dfu_init(const usbd_driver *driver)
|
|||||||
{
|
{
|
||||||
get_dev_unique_id(serial_no);
|
get_dev_unique_id(serial_no);
|
||||||
|
|
||||||
usbdev = usbd_init(driver, &dev, &config,
|
usbdev = usbd_init(driver, &dev_desc, &config,
|
||||||
usb_strings, 4,
|
usb_strings, 4,
|
||||||
usbd_control_buffer, sizeof(usbd_control_buffer));
|
usbd_control_buffer, sizeof(usbd_control_buffer));
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ char *serial_no_read(char *s)
|
|||||||
uint16_t *uid = (uint16_t *)DESIG_UNIQUE_ID_BASE;
|
uint16_t *uid = (uint16_t *)DESIG_UNIQUE_ID_BASE;
|
||||||
# if defined(STM32F4) || defined(STM32F7)
|
# if defined(STM32F4) || defined(STM32F7)
|
||||||
int offset = 3;
|
int offset = 3;
|
||||||
# elif defined(STM32L0) || defined(STM32F3)
|
# elif defined(STM32L0) || defined(STM32F0) || defined(STM32F3)
|
||||||
int offset = 5;
|
int offset = 5;
|
||||||
# endif
|
# endif
|
||||||
sprintf(s, "%04X%04X%04X",
|
sprintf(s, "%04X%04X%04X",
|
||||||
|
@ -27,12 +27,14 @@ uint8_t running_status;
|
|||||||
static volatile uint32_t time_ms;
|
static volatile uint32_t time_ms;
|
||||||
uint32_t swd_delay_cnt = 0;
|
uint32_t swd_delay_cnt = 0;
|
||||||
|
|
||||||
|
static int morse_tick;
|
||||||
|
|
||||||
void platform_timing_init(void)
|
void platform_timing_init(void)
|
||||||
{
|
{
|
||||||
/* Setup heartbeat timer */
|
/* Setup heartbeat timer */
|
||||||
systick_set_clocksource(STK_CSR_CLKSOURCE_AHB_DIV8);
|
systick_set_clocksource(STK_CSR_CLKSOURCE_AHB_DIV8);
|
||||||
/* Interrupt us at 10 Hz */
|
/* 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 */
|
/* SYSTICK_IRQ with low priority */
|
||||||
nvic_set_priority(NVIC_SYSTICK_IRQ, 14 << 4);
|
nvic_set_priority(NVIC_SYSTICK_IRQ, 14 << 4);
|
||||||
systick_interrupt_enable();
|
systick_interrupt_enable();
|
||||||
@ -48,12 +50,16 @@ void platform_delay(uint32_t ms)
|
|||||||
|
|
||||||
void sys_tick_handler(void)
|
void sys_tick_handler(void)
|
||||||
{
|
{
|
||||||
if(running_status)
|
time_ms += SYSTICKMS;
|
||||||
gpio_toggle(LED_PORT, LED_IDLE_RUN);
|
|
||||||
|
|
||||||
time_ms += 100;
|
if (morse_tick >= MORSECNT) {
|
||||||
|
if(running_status)
|
||||||
SET_ERROR_STATE(morse_update());
|
gpio_toggle(LED_PORT, LED_IDLE_RUN);
|
||||||
|
SET_ERROR_STATE(morse_update());
|
||||||
|
morse_tick = 0;
|
||||||
|
} else {
|
||||||
|
morse_tick++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t platform_time_ms(void)
|
uint32_t platform_time_ms(void)
|
||||||
|
@ -50,8 +50,12 @@
|
|||||||
#define TX_LED_ACT (1 << 0)
|
#define TX_LED_ACT (1 << 0)
|
||||||
#define RX_LED_ACT (1 << 1)
|
#define RX_LED_ACT (1 << 1)
|
||||||
|
|
||||||
#define RX_FIFO_SIZE (128)
|
/* F072 with st_usbfs_v2_usb_drive drops characters at the 64 byte boundary!*/
|
||||||
#define TX_BUF_SIZE (128)
|
#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 */
|
/* TX double buffer */
|
||||||
static uint8_t buf_tx[TX_BUF_SIZE * 2];
|
static uint8_t buf_tx[TX_BUF_SIZE * 2];
|
||||||
@ -164,11 +168,19 @@ void usbuart_init(void)
|
|||||||
|
|
||||||
/* Enable interrupts */
|
/* Enable interrupts */
|
||||||
nvic_set_priority(USBUSART_IRQ, IRQ_PRI_USBUSART);
|
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_TX_IRQ, IRQ_PRI_USBUSART_DMA);
|
||||||
nvic_set_priority(USBUSART_DMA_RX_IRQ, IRQ_PRI_USBUSART_DMA);
|
nvic_set_priority(USBUSART_DMA_RX_IRQ, IRQ_PRI_USBUSART_DMA);
|
||||||
|
#endif
|
||||||
nvic_enable_irq(USBUSART_IRQ);
|
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_TX_IRQ);
|
||||||
nvic_enable_irq(USBUSART_DMA_RX_IRQ);
|
nvic_enable_irq(USBUSART_DMA_RX_IRQ);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Finally enable the USART */
|
/* Finally enable the USART */
|
||||||
usart_enable(USBUSART);
|
usart_enable(USBUSART);
|
||||||
@ -392,7 +404,11 @@ static void usbuart_run(void)
|
|||||||
|
|
||||||
void USBUSART_ISR(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);
|
nvic_disable_irq(USBUSART_DMA_RX_IRQ);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Get IDLE flag and reset interrupt flags */
|
/* Get IDLE flag and reset interrupt flags */
|
||||||
const bool isIdle = usart_get_flag(USBUSART, USART_FLAG_IDLE);
|
const bool isIdle = usart_get_flag(USBUSART, USART_FLAG_IDLE);
|
||||||
@ -409,7 +425,11 @@ void USBUSART_ISR(void)
|
|||||||
usbuart_run();
|
usbuart_run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(USBUSART_DMA_RXTX_IRQ)
|
||||||
|
nvic_enable_irq(USBUSART_DMA_RXTX_IRQ);
|
||||||
|
#else
|
||||||
nvic_enable_irq(USBUSART_DMA_RX_IRQ);
|
nvic_enable_irq(USBUSART_DMA_RX_IRQ);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void USBUSART_DMA_TX_ISR(void)
|
void USBUSART_DMA_TX_ISR(void)
|
||||||
@ -449,6 +469,16 @@ void USBUSART_DMA_RX_ISR(void)
|
|||||||
nvic_enable_irq(USBUSART_IRQ);
|
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
|
#ifdef ENABLE_DEBUG
|
||||||
enum {
|
enum {
|
||||||
RDI_SYS_OPEN = 0x01,
|
RDI_SYS_OPEN = 0x01,
|
||||||
|
@ -144,6 +144,7 @@ void remotePacketProcessSWD(uint8_t i, char *packet)
|
|||||||
if (i==2) {
|
if (i==2) {
|
||||||
remote_dp.dp_read = firmware_swdp_read;
|
remote_dp.dp_read = firmware_swdp_read;
|
||||||
remote_dp.low_access = firmware_swdp_low_access;
|
remote_dp.low_access = firmware_swdp_low_access;
|
||||||
|
remote_dp.abort = firmware_swdp_abort;
|
||||||
swdptap_init(&remote_dp);
|
swdptap_init(&remote_dp);
|
||||||
_respond(REMOTE_RESP_OK, 0);
|
_respond(REMOTE_RESP_OK, 0);
|
||||||
} else {
|
} else {
|
||||||
@ -194,6 +195,7 @@ void remotePacketProcessJTAG(uint8_t i, char *packet)
|
|||||||
case REMOTE_INIT: /* JS = initialise ============================= */
|
case REMOTE_INIT: /* JS = initialise ============================= */
|
||||||
remote_dp.dp_read = fw_adiv5_jtagdp_read;
|
remote_dp.dp_read = fw_adiv5_jtagdp_read;
|
||||||
remote_dp.low_access = fw_adiv5_jtagdp_low_access;
|
remote_dp.low_access = fw_adiv5_jtagdp_low_access;
|
||||||
|
remote_dp.abort = adiv5_jtagdp_abort;
|
||||||
jtagtap_init();
|
jtagtap_init();
|
||||||
_respond(REMOTE_RESP_OK, 0);
|
_respond(REMOTE_RESP_OK, 0);
|
||||||
break;
|
break;
|
||||||
@ -226,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);
|
jtag_proc.jtagtap_tdi_tdo_seq((void *)&DO, (packet[1]==REMOTE_TDITDO_TMS), (void *)&DI, ticks);
|
||||||
|
|
||||||
/* Mask extra bits on return value... */
|
/* Mask extra bits on return value... */
|
||||||
DO &= (1LL << (ticks + 1)) - 1;
|
if (ticks < 64)
|
||||||
|
DO &= (1LL << ticks) - 1;
|
||||||
|
|
||||||
_respond(REMOTE_RESP_OK, DO);
|
_respond(REMOTE_RESP_OK, DO);
|
||||||
}
|
}
|
||||||
|
@ -334,7 +334,7 @@ static bool cortexm_prepare(ADIv5_AP_t *ap)
|
|||||||
uint32_t dhcsr_ctl = CORTEXM_DHCSR_DBGKEY | CORTEXM_DHCSR_C_DEBUGEN |
|
uint32_t dhcsr_ctl = CORTEXM_DHCSR_DBGKEY | CORTEXM_DHCSR_C_DEBUGEN |
|
||||||
CORTEXM_DHCSR_C_HALT;
|
CORTEXM_DHCSR_C_HALT;
|
||||||
uint32_t dhcsr_valid = CORTEXM_DHCSR_S_HALT | CORTEXM_DHCSR_C_DEBUGEN;
|
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();
|
uint32_t start_time = platform_time_ms();
|
||||||
#endif
|
#endif
|
||||||
uint32_t dhcsr;
|
uint32_t dhcsr;
|
||||||
@ -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 */
|
if (addr == 0) /* No rom table on this AP */
|
||||||
return;
|
return;
|
||||||
volatile uint32_t cidr;
|
volatile uint32_t cidr;
|
||||||
volatile struct exception e;
|
cidr = adiv5_ap_read_id(ap, addr + CIDR0_OFFSET);
|
||||||
TRY_CATCH (e, EXCEPTION_TIMEOUT) {
|
if (ap->dp->fault) {
|
||||||
cidr = adiv5_ap_read_id(ap, addr + CIDR0_OFFSET);
|
DEBUG_WARN("CIDR read timeout on AP%d, aborting.\n", ap->apsel);
|
||||||
}
|
|
||||||
if (e.type) {
|
|
||||||
DEBUG_WARN("CIDR read timeout on AP%d, aborting.\n", num_entry);
|
|
||||||
adiv5_dp_abort(ap->dp, ADIV5_DP_ABORT_DAPABORT);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((cidr & ~CID_CLASS_MASK) != CID_PREAMBLE)
|
if ((cidr & ~CID_CLASS_MASK) != CID_PREAMBLE)
|
||||||
return;
|
return;
|
||||||
#if defined(ENABLE_DEBUG)
|
#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 */
|
if(!tmpap.idr) /* IDR Invalid */
|
||||||
return NULL;
|
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 */
|
/* It's valid to so create a heap copy */
|
||||||
ap = malloc(sizeof(*ap));
|
ap = malloc(sizeof(*ap));
|
||||||
if (!ap) { /* malloc failed: heap exhaustion */
|
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));
|
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)
|
#if defined(ENABLE_DEBUG)
|
||||||
uint32_t cfg = adiv5_ap_read(ap, ADIV5_AP_CFG);
|
uint32_t cfg = adiv5_ap_read(ap, ADIV5_AP_CFG);
|
||||||
DEBUG_INFO("AP %3d: IDR=%08"PRIx32" CFG=%08"PRIx32" BASE=%08" PRIx32
|
DEBUG_INFO("AP %3d: IDR=%08"PRIx32" CFG=%08"PRIx32" BASE=%08" PRIx32
|
||||||
|
@ -88,19 +88,23 @@
|
|||||||
#define ADIV5_AP_BASE ADIV5_AP_REG(0xF8)
|
#define ADIV5_AP_BASE ADIV5_AP_REG(0xF8)
|
||||||
#define ADIV5_AP_IDR ADIV5_AP_REG(0xFC)
|
#define ADIV5_AP_IDR ADIV5_AP_REG(0xFC)
|
||||||
|
|
||||||
/* Known designers seen in SYSROM-PIDR. Ignore Bit 0 from
|
/* Known designers seen in SYSROM-PIDR and JTAG IDCode.
|
||||||
* the designer bits to get JEDEC Ids with bit 7 ignored.*/
|
* 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_FREESCALE 0x00e
|
||||||
#define AP_DESIGNER_TEXAS 0x017
|
#define AP_DESIGNER_TEXAS 0x017
|
||||||
#define AP_DESIGNER_ATMEL 0x01f
|
#define AP_DESIGNER_ATMEL 0x01f
|
||||||
#define AP_DESIGNER_STM 0x020
|
#define AP_DESIGNER_STM 0x020
|
||||||
#define AP_DESIGNER_CYPRESS 0x034
|
#define AP_DESIGNER_CYPRESS 0x034
|
||||||
#define AP_DESIGNER_INFINEON 0x041
|
#define AP_DESIGNER_INFINEON 0x041
|
||||||
|
#define DESIGNER_XILINX 0x049
|
||||||
#define AP_DESIGNER_NORDIC 0x244
|
#define AP_DESIGNER_NORDIC 0x244
|
||||||
#define AP_DESIGNER_ARM 0x43b
|
#define AP_DESIGNER_ARM 0x43b
|
||||||
/*LPC845 with designer 501. Strange!? */
|
/*LPC845 with designer 501. Strange!? */
|
||||||
#define AP_DESIGNER_SPECULAR 0x501
|
#define AP_DESIGNER_SPECULAR 0x501
|
||||||
#define AP_DESIGNER_CS 0x555
|
#define AP_DESIGNER_CS 0x555
|
||||||
|
#define DESIGNER_XAMBALA 0x61e
|
||||||
#define AP_DESIGNER_ENERGY_MICRO 0x673
|
#define AP_DESIGNER_ENERGY_MICRO 0x673
|
||||||
#define AP_DESIGNER_GIGADEVICE 0x751
|
#define AP_DESIGNER_GIGADEVICE 0x751
|
||||||
#define AP_DESIGNER_RASPBERRY 0x927
|
#define AP_DESIGNER_RASPBERRY 0x927
|
||||||
@ -286,7 +290,7 @@ void adiv5_ap_ref(ADIv5_AP_t *ap);
|
|||||||
void adiv5_ap_unref(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 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 platform_jtag_dp_init(ADIv5_DP_t *dp);
|
||||||
int swdptap_init(ADIv5_DP_t *dp);
|
int swdptap_init(ADIv5_DP_t *dp);
|
||||||
|
|
||||||
@ -310,4 +314,5 @@ uint32_t fw_adiv5_jtagdp_read(ADIv5_DP_t *dp, uint16_t addr);
|
|||||||
uint32_t firmware_swdp_error(ADIv5_DP_t *dp);
|
uint32_t firmware_swdp_error(ADIv5_DP_t *dp);
|
||||||
|
|
||||||
void firmware_swdp_abort(ADIv5_DP_t *dp, uint32_t abort);
|
void firmware_swdp_abort(ADIv5_DP_t *dp, uint32_t abort);
|
||||||
|
void adiv5_jtagdp_abort(ADIv5_DP_t *dp, uint32_t abort);
|
||||||
#endif
|
#endif
|
||||||
|
@ -39,9 +39,7 @@
|
|||||||
|
|
||||||
static uint32_t adiv5_jtagdp_error(ADIv5_DP_t *dp);
|
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(jtag_dev_t *jd)
|
||||||
|
|
||||||
void adiv5_jtag_dp_handler(uint8_t jd_index, uint32_t j_idcode)
|
|
||||||
{
|
{
|
||||||
ADIv5_DP_t *dp = (void*)calloc(1, sizeof(*dp));
|
ADIv5_DP_t *dp = (void*)calloc(1, sizeof(*dp));
|
||||||
if (!dp) { /* calloc failed: heap exhaustion */
|
if (!dp) { /* calloc failed: heap exhaustion */
|
||||||
@ -49,8 +47,8 @@ void adiv5_jtag_dp_handler(uint8_t jd_index, uint32_t j_idcode)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dp->dp_jd_index = jd_index;
|
dp->dp_jd_index = jd->jd_dev;
|
||||||
dp->idcode = j_idcode;
|
dp->idcode = jd->jd_idcode;
|
||||||
if ((PC_HOSTED == 0 ) || (!platform_jtag_dp_init(dp))) {
|
if ((PC_HOSTED == 0 ) || (!platform_jtag_dp_init(dp))) {
|
||||||
dp->dp_read = fw_adiv5_jtagdp_read;
|
dp->dp_read = fw_adiv5_jtagdp_read;
|
||||||
dp->error = adiv5_jtagdp_error;
|
dp->error = adiv5_jtagdp_error;
|
||||||
@ -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);
|
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 {
|
do {
|
||||||
jtag_dev_shift_dr(&jtag_proc, dp->dp_jd_index, (uint8_t*)&response,
|
jtag_dev_shift_dr(&jtag_proc, dp->dp_jd_index, (uint8_t*)&response,
|
||||||
(uint8_t*)&request, 35);
|
(uint8_t*)&request, 35);
|
||||||
ack = response & 0x07;
|
ack = response & 0x07;
|
||||||
} while(!platform_timeout_is_expired(&timeout) && (ack == JTAGDP_ACK_WAIT));
|
} while(!platform_timeout_is_expired(&timeout) && (ack == JTAGDP_ACK_WAIT));
|
||||||
|
|
||||||
if (ack == JTAGDP_ACK_WAIT)
|
if (ack == JTAGDP_ACK_WAIT) {
|
||||||
raise_exception(EXCEPTION_TIMEOUT, "JTAG-DP ACK timeout");
|
dp->abort(dp, ADIV5_DP_ABORT_DAPABORT);
|
||||||
|
dp->fault = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
if((ack != JTAGDP_ACK_OK))
|
if((ack != JTAGDP_ACK_OK))
|
||||||
raise_exception(EXCEPTION_ERROR, "JTAG-DP invalid ACK");
|
raise_exception(EXCEPTION_ERROR, "JTAG-DP invalid ACK");
|
||||||
|
|
||||||
return (uint32_t)(response >> 3);
|
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;
|
uint64_t request = (uint64_t)abort << 3;
|
||||||
jtag_dev_write_ir(&jtag_proc, dp->dp_jd_index, IR_ABORT);
|
jtag_dev_write_ir(&jtag_proc, dp->dp_jd_index, IR_ABORT);
|
||||||
|
@ -75,24 +75,18 @@ static bool firmware_dp_low_read(ADIv5_DP_t *dp, uint16_t addr, uint32_t *res)
|
|||||||
*/
|
*/
|
||||||
int adiv5_swdp_scan(uint32_t targetid)
|
int adiv5_swdp_scan(uint32_t targetid)
|
||||||
{
|
{
|
||||||
ADIv5_DP_t idp, *initial_dp = &idp;
|
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;
|
||||||
target_list_free();
|
target_list_free();
|
||||||
memset(initial_dp, 0, sizeof(ADIv5_DP_t));
|
|
||||||
if (swdptap_init(initial_dp))
|
if (swdptap_init(initial_dp))
|
||||||
return -1;
|
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;
|
|
||||||
/* DORMANT-> SWD sequence*/
|
/* DORMANT-> SWD sequence*/
|
||||||
initial_dp->seq_out(0xFFFFFFFF, 32);
|
initial_dp->seq_out(0xFFFFFFFF, 32);
|
||||||
initial_dp->seq_out(0xFFFFFFFF, 32);
|
initial_dp->seq_out(0xFFFFFFFF, 32);
|
||||||
@ -125,14 +119,14 @@ int adiv5_swdp_scan(uint32_t targetid)
|
|||||||
initial_dp->seq_out(0xE79E, 16); /* 0b0111100111100111 */
|
initial_dp->seq_out(0xE79E, 16); /* 0b0111100111100111 */
|
||||||
dp_line_reset(initial_dp);
|
dp_line_reset(initial_dp);
|
||||||
initial_dp->fault = 0;
|
initial_dp->fault = 0;
|
||||||
volatile struct exception e;
|
volatile struct exception e2;
|
||||||
TRY_CATCH (e, EXCEPTION_ALL) {
|
TRY_CATCH (e2, EXCEPTION_ALL) {
|
||||||
idcode = initial_dp->low_access(initial_dp, ADIV5_LOW_READ,
|
idcode = initial_dp->low_access(initial_dp, ADIV5_LOW_READ,
|
||||||
ADIV5_DP_IDCODE, 0);
|
ADIV5_DP_IDCODE, 0);
|
||||||
}
|
}
|
||||||
if (e.type) {
|
if (e2.type) {
|
||||||
DEBUG_WARN("No usable DP found\n");
|
DEBUG_WARN("No usable DP found\n");
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((idcode & ADIV5_DP_VERSION_MASK) == ADIV5_DPv2) {
|
if ((idcode & ADIV5_DP_VERSION_MASK) == ADIV5_DPv2) {
|
||||||
@ -241,7 +235,7 @@ uint32_t firmware_swdp_low_access(ADIv5_DP_t *dp, uint8_t RnW,
|
|||||||
|
|
||||||
if((addr & ADIV5_APnDP) && dp->fault) return 0;
|
if((addr & ADIV5_APnDP) && dp->fault) return 0;
|
||||||
|
|
||||||
platform_timeout_set(&timeout, 2000);
|
platform_timeout_set(&timeout, 20);
|
||||||
do {
|
do {
|
||||||
dp->seq_out(request, 8);
|
dp->seq_out(request, 8);
|
||||||
ack = dp->seq_in(3);
|
ack = dp->seq_in(3);
|
||||||
@ -251,8 +245,11 @@ uint32_t firmware_swdp_low_access(ADIv5_DP_t *dp, uint8_t RnW,
|
|||||||
}
|
}
|
||||||
} while (ack == SWDP_ACK_WAIT && !platform_timeout_is_expired(&timeout));
|
} while (ack == SWDP_ACK_WAIT && !platform_timeout_is_expired(&timeout));
|
||||||
|
|
||||||
if (ack == SWDP_ACK_WAIT)
|
if (ack == SWDP_ACK_WAIT) {
|
||||||
raise_exception(EXCEPTION_TIMEOUT, "SWDP ACK timeout");
|
dp->abort(dp, ADIV5_DP_ABORT_DAPABORT);
|
||||||
|
dp->fault = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if(ack == SWDP_ACK_FAULT) {
|
if(ack == SWDP_ACK_FAULT) {
|
||||||
dp->fault = 1;
|
dp->fault = 1;
|
||||||
|
@ -526,7 +526,7 @@ bool cortexm_attach(target *t)
|
|||||||
platform_timeout timeout;
|
platform_timeout timeout;
|
||||||
platform_timeout_set(&timeout, 1000);
|
platform_timeout_set(&timeout, 1000);
|
||||||
while (1) {
|
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))
|
if (!(dhcsr & CORTEXM_DHCSR_S_RESET_ST))
|
||||||
break;
|
break;
|
||||||
if (platform_timeout_is_expired(&timeout)) {
|
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++)
|
for(i = 0; i < sizeof(regnum_cortex_m) / 4; i++)
|
||||||
*regs++ = base_regs[regnum_cortex_m[i]];
|
*regs++ = base_regs[regnum_cortex_m[i]];
|
||||||
if (t->target_options & TOPT_FLAVOUR_V7MF)
|
if (t->target_options & TOPT_FLAVOUR_V7MF)
|
||||||
for(size_t t = 0; t < sizeof(regnum_cortex_mf) / 4; t++)
|
for(i = 0; i < sizeof(regnum_cortex_mf) / 4; i++)
|
||||||
*regs++ = ap->dp->ap_reg_read(ap, regnum_cortex_mf[t]);
|
*regs++ = ap->dp->ap_reg_read(ap, regnum_cortex_mf[i]);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (0) {}
|
if (0) {}
|
||||||
|
@ -979,11 +979,6 @@ const struct command_s efm32_aap_cmd_list[] = {
|
|||||||
{NULL, NULL, NULL}
|
{NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool nop_function(void)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AAP Probe
|
* AAP Probe
|
||||||
*/
|
*/
|
||||||
@ -1019,17 +1014,7 @@ void efm32_aap_probe(ADIv5_AP_t *ap)
|
|||||||
"EFM32 Authentication Access Port rev.%d",
|
"EFM32 Authentication Access Port rev.%d",
|
||||||
aap_revision);
|
aap_revision);
|
||||||
t->driver = priv_storage->aap_driver_string;
|
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_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);
|
target_add_commands(t, efm32_aap_cmd_list, t->driver);
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ typedef const struct jtag_dev_descr_s {
|
|||||||
const uint32_t idcode;
|
const uint32_t idcode;
|
||||||
const uint32_t idmask;
|
const uint32_t idmask;
|
||||||
const char * const descr;
|
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;
|
} jtag_dev_descr_t;
|
||||||
extern jtag_dev_descr_t dev_descr[];
|
extern jtag_dev_descr_t dev_descr[];
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (C) 2011 Black Sphere Technologies Ltd.
|
* Copyright (C) 2011 Black Sphere Technologies Ltd.
|
||||||
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
|
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
|
||||||
|
* Copyright (C) 2021 Uwe Bonnes(bon@elektron.ikp.physik.tu-darmstadt.de)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -25,16 +26,14 @@
|
|||||||
|
|
||||||
#include "general.h"
|
#include "general.h"
|
||||||
#include "jtagtap.h"
|
#include "jtagtap.h"
|
||||||
#include "jtag_scan.h"
|
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
#include "adiv5.h"
|
#include "adiv5.h"
|
||||||
#include "jtag_devs.h"
|
|
||||||
|
|
||||||
struct jtag_dev_s jtag_devs[JTAG_MAX_DEVS+1];
|
jtag_dev_t jtag_devs[JTAG_MAX_DEVS+1];
|
||||||
int jtag_dev_count;
|
int jtag_dev_count;
|
||||||
|
|
||||||
/* bucket of ones for don't care TDI */
|
/* 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
|
#if PC_HOSTED == 0
|
||||||
void jtag_add_device(const int dev_index, const jtag_dev_t *jtag_dev)
|
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
|
#endif
|
||||||
|
|
||||||
/* Scan JTAG chain for devices, store IR length and IDCODE (if present).
|
/* 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.
|
* https://www.fpga4fun.com/JTAG3.html
|
||||||
* Select Shift-DR state.
|
* Count the number of devices in the JTAG chain
|
||||||
* Shift in ones and count zeros shifted out. Should be one for each device.
|
*
|
||||||
* Check this against device count obtained by IR scan above.
|
* 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.
|
* 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,
|
* Read 32 bit IDCODE for all devices.
|
||||||
* continue to next device. If this is one shift out the remaining 31 bits
|
*/
|
||||||
* of the IDCODE register.
|
|
||||||
*/
|
|
||||||
int jtag_scan(const uint8_t *irlens)
|
int jtag_scan(const uint8_t *irlens)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
uint32_t j;
|
void (*jd_handlers[JTAG_MAX_DEVS])(jtag_dev_t *jd);
|
||||||
|
|
||||||
target_list_free();
|
target_list_free();
|
||||||
|
|
||||||
jtag_dev_count = 0;
|
memset(jd_handlers, 0, sizeof(jd_handlers));
|
||||||
memset(&jtag_devs, 0, sizeof(jtag_devs));
|
|
||||||
|
|
||||||
/* Run throught the SWD to JTAG sequence for the case where an attached SWJ-DP is
|
/* Run throught the SWD to JTAG sequence for the case where an
|
||||||
* in SW-DP mode.
|
* attached SWJ-DP is in SW-DP mode.
|
||||||
*/
|
*/
|
||||||
DEBUG_INFO("Resetting TAP\n");
|
|
||||||
#if PC_HOSTED == 1
|
#if PC_HOSTED == 1
|
||||||
if (platform_jtagtap_init()) {
|
if (platform_jtagtap_init()) {
|
||||||
DEBUG_WARN("JTAG not available\n");
|
DEBUG_WARN("JTAG not available\n");
|
||||||
@ -86,139 +81,146 @@ int jtag_scan(const uint8_t *irlens)
|
|||||||
jtagtap_init();
|
jtagtap_init();
|
||||||
#endif
|
#endif
|
||||||
jtag_proc.jtagtap_reset();
|
jtag_proc.jtagtap_reset();
|
||||||
|
#define LOOPS 16
|
||||||
if (irlens) {
|
jtagtap_shift_ir();
|
||||||
DEBUG_WARN("Given list of IR lengths, skipping probe\n");
|
i = LOOPS;
|
||||||
DEBUG_INFO("Change state to Shift-IR\n");
|
uint8_t ir_chain[64], *din = ir_chain;
|
||||||
jtagtap_shift_ir();
|
while (i--) {
|
||||||
j = 0;
|
jtag_proc.jtagtap_tdi_tdo_seq(din, (i == 0) ? 1 : 0, ones,
|
||||||
while((jtag_dev_count <= JTAG_MAX_DEVS) &&
|
sizeof(ones) * 8);
|
||||||
(jtag_devs[jtag_dev_count].ir_len <= JTAG_MAX_IR_LEN)) {
|
din += sizeof(ones);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (!(ir_chain[0] & 1)) {
|
||||||
DEBUG_INFO("Return to Run-Test/Idle\n");
|
DEBUG_WARN("Unexpected IR chain!\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) {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
jtagtap_return_idle();
|
||||||
/* Fill in the ir_postscan fields */
|
jtagtap_shift_dr();
|
||||||
for(i = jtag_dev_count - 1; i; i--)
|
i = LOOPS;
|
||||||
jtag_devs[i-1].ir_postscan = jtag_devs[i].ir_postscan +
|
uint8_t zeros[] = {0, 0, 0, 0};
|
||||||
jtag_devs[i].ir_len;
|
while(i--) {
|
||||||
|
jtag_proc.jtagtap_tdi_seq(0, zeros, sizeof(zeros) * 8);
|
||||||
/* Reset jtagtap: should take all devs to IDCODE */
|
}
|
||||||
|
int num_devices = 0;
|
||||||
|
while (!jtag_proc.jtagtap_next(0,1) && (i++ < 6))
|
||||||
|
num_devices++;
|
||||||
jtag_proc.jtagtap_reset();
|
jtag_proc.jtagtap_reset();
|
||||||
jtagtap_shift_dr();
|
jtagtap_shift_dr();
|
||||||
for(i = 0; i < jtag_dev_count; i++) {
|
jtag_dev_count = num_devices;
|
||||||
if(!jtag_proc.jtagtap_next(0, 1)) continue;
|
if (!num_devices)
|
||||||
jtag_devs[i].jd_idcode = 1;
|
return 0;
|
||||||
for(j = 2; j; j <<= 1)
|
DEBUG_TARGET("Found %d devices\n", num_devices);
|
||||||
if(jtag_proc.jtagtap_next(0, 1)) jtag_devs[i].jd_idcode |= j;
|
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
|
#if PC_HOSTED == 1
|
||||||
/*Transfer needed device information to firmware jtag_devs*/
|
/*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++) {
|
for(i = 0; i < jtag_dev_count; i++) {
|
||||||
DEBUG_INFO("Idcode 0x%08" PRIx32, jtag_devs[i].jd_idcode);
|
platform_add_jtag_dev(i, &jtag_devs[i]);
|
||||||
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");
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Check for known devices and handle accordingly */
|
/* Check for known devices and handle accordingly */
|
||||||
for(i = 0; i < jtag_dev_count; i++)
|
for(i = 0; i < jtag_dev_count; i++)
|
||||||
for(j = 0; dev_descr[j].idcode; j++)
|
/* Call handler to initialise/probe device further */
|
||||||
if((jtag_devs[i].jd_idcode & dev_descr[j].idmask) ==
|
if (jd_handlers[i])
|
||||||
dev_descr[j].idcode) {
|
jd_handlers[i](&jtag_devs[i]);
|
||||||
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, dev_descr[j].idcode);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return jtag_dev_count;
|
return jtag_dev_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ typedef struct jtag_dev_s {
|
|||||||
uint32_t current_ir;
|
uint32_t current_ir;
|
||||||
} jtag_dev_t;
|
} 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;
|
extern int jtag_dev_count;
|
||||||
|
|
||||||
void jtag_dev_write_ir(jtag_proc_t *jp, uint8_t jd_index, uint32_t ir);
|
void jtag_dev_write_ir(jtag_proc_t *jp, uint8_t jd_index, uint32_t ir);
|
||||||
|
@ -90,40 +90,55 @@ lpc11xx_probe(target *t)
|
|||||||
uint32_t idcode;
|
uint32_t idcode;
|
||||||
|
|
||||||
/* read the device ID register */
|
/* 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);
|
idcode = target_mem_read32(t, LPC11XX_DEVICE_ID);
|
||||||
switch (idcode) {
|
switch (idcode) {
|
||||||
case 0x041E502B:
|
case 0x0A07102B: /* LPC1110 - 4K Flash 1K SRAM */
|
||||||
case 0x2516D02B:
|
case 0x1A07102B: /* LPC1110 - 4K Flash 1K SRAM */
|
||||||
case 0x0416502B:
|
case 0x0A16D02B: /* LPC1111/002 - 8K Flash 2K SRAM */
|
||||||
case 0x2516902B: /* lpc1111 */
|
case 0x1A16D02B: /* LPC1111/002 - 8K Flash 2K SRAM */
|
||||||
case 0x2524D02B:
|
case 0x041E502B: /* LPC1111/101 - 8K Flash 2K SRAM */
|
||||||
case 0x0425502B:
|
case 0x2516D02B: /* LPC1111/101/102 - 8K Flash 2K SRAM */
|
||||||
case 0x2524902B:
|
case 0x0416502B: /* LPC1111/201 - 8K Flash 4K SRAM */
|
||||||
case 0x1421102B: /* lpc1112 */
|
case 0x2516902B: /* LPC1111/201/202 - 8K Flash 4K SRAM */
|
||||||
case 0x0434502B:
|
case 0x0A23902B: /* LPC1112/102 - 16K Flash 4K SRAM */
|
||||||
case 0x2532902B:
|
case 0x1A23902B: /* LPC1112/102 - 16K Flash 4K SRAM */
|
||||||
case 0x0434102B:
|
case 0x042D502B: /* LPC1112/101 - 16K Flash 2K SRAM */
|
||||||
case 0x2532102B: /* lpc1113 */
|
case 0x2524D02B: /* LPC1112/101/102 - 16K Flash 2K SRAM */
|
||||||
case 0x0444502B:
|
case 0x0425502B: /* LPC1112/201 - 16K Flash 4K SRAM */
|
||||||
case 0x2540902B:
|
case 0x2524902B: /* LPC1112/201/202 - 16K Flash 4K SRAM */
|
||||||
case 0x0444102B:
|
case 0x0434502B: /* LPC1113/201 - 24K Flash 4K SRAM */
|
||||||
case 0x2540102B:
|
case 0x2532902B: /* LPC1113/201/202 - 24K Flash 4K SRAM */
|
||||||
case 0x1440102B: /* lpc1114 */
|
case 0x0434102B: /* LPC1113/301 - 24K Flash 8K SRAM */
|
||||||
case 0x0A40902B:
|
case 0x2532102B: /* LPC1113/301/302 - 24K Flash 8K SRAM */
|
||||||
case 0x1A40902B:
|
case 0x0A40902B: /* LPC1114/102 - 32K Flash 4K SRAM */
|
||||||
case 0x00050080: /* lpc1115 and lpc1115L (not the XL version. See UM10398 Rev12.4 Chapter 3.1 ) */
|
case 0x1A40902B: /* LPC1114/102 - 32K Flash 4K SRAM */
|
||||||
case 0x1431102B: /* lpc11c22 */
|
case 0x0444502B: /* LPC1114/201 - 32K Flash 4K SRAM */
|
||||||
case 0x1430102B: /* lpc11c24 */
|
case 0x2540902B: /* LPC1114/201/202 - 32K Flash 4K SRAM */
|
||||||
case 0x095C802B: /* lpc11u12x/201 */
|
case 0x0444102B: /* LPC1114/301 - 32K Flash 8K SRAM */
|
||||||
case 0x295C802B:
|
case 0x2540102B: /* LPC1114/301/302 & LPC11D14/302 - 32K Flash 8K SRAM */
|
||||||
case 0x097A802B: /* lpc11u13/201 */
|
case 0x00050080: /* LPC1115/303 - 64K Flash 8K SRAM (redundant? see UM10398, XL has Device ID at different address) */
|
||||||
case 0x297A802B:
|
case 0x1421102B: /* LPC11c12/301 - 16K Flash 8K SRAM */
|
||||||
case 0x0998802B: /* lpc11u14x/201 */
|
case 0x1440102B: /* LPC11c14/301 - 32K Flash 8K SRAM */
|
||||||
case 0x2998802B:
|
case 0x1431102B: /* LPC11c22/301 - 16K Flash 8K SRAM */
|
||||||
case 0x2972402B: /* lpc11u23/301 */
|
case 0x1430102B: /* LPC11c24/301 - 32K Flash 8K SRAM */
|
||||||
case 0x2988402B: /* lpc11u24x/301 */
|
case 0x095C802B: /* LPC11u12x/201 - 16K Flash 4K SRAM */
|
||||||
case 0x2980002B: /* lpc11u24x/401 */
|
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";
|
t->driver = "LPC11xx";
|
||||||
target_add_ram(t, 0x10000000, 0x2000);
|
target_add_ram(t, 0x10000000, 0x2000);
|
||||||
lpc11xx_add_flash(t, 0x00000000, 0x20000, 0x1000, IAP_ENTRY_MOST, 0);
|
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);
|
target_add_ram(t, 0x10000000, 0x2000);
|
||||||
/* UM11074/ Flash controller/15.2: The two topmost sectors
|
/* UM11074/ Flash controller/15.2: The two topmost sectors
|
||||||
* contain the initialization code and IAP firmware.
|
* 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);
|
lpc11xx_add_flash(t, 0x00000000, 0x7800, 0x400, IAP_ENTRY_MOST, 0);
|
||||||
target_add_commands(t, lpc11xx_cmd_list, "LPC8N04");
|
target_add_commands(t, lpc11xx_cmd_list, "LPC8N04");
|
||||||
return true;
|
return true;
|
||||||
@ -160,91 +175,115 @@ lpc11xx_probe(target *t)
|
|||||||
if ((t->t_designer != AP_DESIGNER_SPECULAR) && idcode) {
|
if ((t->t_designer != AP_DESIGNER_SPECULAR) && idcode) {
|
||||||
DEBUG_INFO("LPC11xx: Unknown IDCODE 0x%08" PRIx32 "\n", 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);
|
idcode = target_mem_read32(t, LPC8XX_DEVICE_ID);
|
||||||
switch (idcode) {
|
switch (idcode) {
|
||||||
case 0x00008021: /* 802M001JDH20 */
|
case 0x00008021: /* LPC802M001JDH20 - 16K Flash 2K SRAM */
|
||||||
case 0x00008022: /* 802M011JDH20 */
|
case 0x00008022: /* LPC802M011JDH20 */
|
||||||
case 0x00008023: /* 802M001JDH16 */
|
case 0x00008023: /* LPC802M001JDH16 */
|
||||||
case 0x00008024: /* 802M001JHI33 */
|
case 0x00008024: /* LPC802M001JHI33 */
|
||||||
t->driver = "LPC802";
|
t->driver = "LPC802";
|
||||||
target_add_ram(t, 0x10000000, 0x800);
|
target_add_ram(t, 0x10000000, 0x800);
|
||||||
lpc11xx_add_flash(t, 0x00000000, 0x4000, 0x400, IAP_ENTRY_84x, 2);
|
lpc11xx_add_flash(t, 0x00000000, 0x4000, 0x400, IAP_ENTRY_84x, 2);
|
||||||
target_add_commands(t, lpc11xx_cmd_list, "LPC802");
|
target_add_commands(t, lpc11xx_cmd_list, "LPC802");
|
||||||
return true;
|
return true;
|
||||||
case 0x00008040: /* 804M101JBD64 */
|
case 0x00008040: /* LPC804M101JBD64 - 32K Flash 4K SRAM */
|
||||||
case 0x00008041: /* 804M101JDH20 */
|
case 0x00008041: /* LPC804M101JDH20 */
|
||||||
case 0x00008042: /* 804M101JDH24 */
|
case 0x00008042: /* LPC804M101JDH24 */
|
||||||
case 0x00008043: /* 804M111JDH24 */
|
case 0x00008043: /* LPC804M111JDH24 */
|
||||||
case 0x00008044: /* 804M101JHI33 */
|
case 0x00008044: /* LPC804M101JHI33 */
|
||||||
t->driver = "LPC804";
|
t->driver = "LPC804";
|
||||||
target_add_ram(t, 0x10000000, 0x1000);
|
target_add_ram(t, 0x10000000, 0x1000);
|
||||||
lpc11xx_add_flash(t, 0x00000000, 0x8000, 0x400, IAP_ENTRY_84x, 2);
|
lpc11xx_add_flash(t, 0x00000000, 0x8000, 0x400, IAP_ENTRY_84x, 2);
|
||||||
target_add_commands(t, lpc11xx_cmd_list, "LPC804");
|
target_add_commands(t, lpc11xx_cmd_list, "LPC804");
|
||||||
return true;
|
return true;
|
||||||
case 0x00008100: /* LPC810M021FN8 */
|
case 0x00008100: /* LPC810M021FN8 - 4K Flash 1K SRAM */
|
||||||
case 0x00008110: /* LPC811M001JDH16 */
|
case 0x00008110: /* LPC811M001JDH16 - 8K Flash 2K SRAM */
|
||||||
case 0x00008120: /* LPC812M101JDH16 */
|
case 0x00008120: /* LPC812M101JDH16 - 16K Flash 4K SRAM */
|
||||||
case 0x00008121: /* LPC812M101JD20 */
|
case 0x00008121: /* LPC812M101JD20 - 16K Flash 4K SRAM */
|
||||||
case 0x00008122: /* LPC812M101JDH20 / LPC812M101JTB16 */
|
case 0x00008122: /* LPC812M101JDH20 / LPC812M101JTB16 - 16K Flash 4K SRAM */
|
||||||
t->driver = "LPC81x";
|
t->driver = "LPC81x";
|
||||||
target_add_ram(t, 0x10000000, 0x1000);
|
target_add_ram(t, 0x10000000, 0x1000);
|
||||||
lpc11xx_add_flash(t, 0x00000000, 0x4000, 0x400, IAP_ENTRY_MOST, 0);
|
lpc11xx_add_flash(t, 0x00000000, 0x4000, 0x400, IAP_ENTRY_MOST, 0);
|
||||||
target_add_commands(t, lpc11xx_cmd_list, "LPC81x");
|
target_add_commands(t, lpc11xx_cmd_list, "LPC81x");
|
||||||
return true;
|
return true;
|
||||||
case 0x00008221: /* LPC822M101JHI33 */
|
case 0x00008221: /* LPC822M101JHI33 - 16K Flash 4K SRAM */
|
||||||
case 0x00008222: /* LPC822M101JDH20 */
|
case 0x00008222: /* LPC822M101JDH20 */
|
||||||
case 0x00008241: /* LPC824M201JHI33 */
|
case 0x00008241: /* LPC824M201JHI33 - 32K Flash 8K SRAM */
|
||||||
case 0x00008242: /* LPC824M201JDH20 */
|
case 0x00008242: /* LPC824M201JDH20 */
|
||||||
t->driver = "LPC82x";
|
t->driver = "LPC82x";
|
||||||
target_add_ram(t, 0x10000000, 0x2000);
|
target_add_ram(t, 0x10000000, 0x2000);
|
||||||
lpc11xx_add_flash(t, 0x00000000, 0x8000, 0x400, IAP_ENTRY_MOST, 0);
|
lpc11xx_add_flash(t, 0x00000000, 0x8000, 0x400, IAP_ENTRY_MOST, 0);
|
||||||
target_add_commands(t, lpc11xx_cmd_list, "LPC82x");
|
target_add_commands(t, lpc11xx_cmd_list, "LPC82x");
|
||||||
return true;
|
return true;
|
||||||
case 0x00008322: /* LPC832M101FDH20 */
|
case 0x00008322: /* LPC832M101FDH20 - 16K Flash 4K SRAM */
|
||||||
t->driver = "LPC832";
|
t->driver = "LPC832";
|
||||||
target_add_ram(t, 0x10000000, 0x1000);
|
target_add_ram(t, 0x10000000, 0x1000);
|
||||||
lpc11xx_add_flash(t, 0x00000000, 0x4000, 0x400, IAP_ENTRY_MOST, 0);
|
lpc11xx_add_flash(t, 0x00000000, 0x4000, 0x400, IAP_ENTRY_MOST, 0);
|
||||||
target_add_commands(t, lpc11xx_cmd_list, "LPC832");
|
target_add_commands(t, lpc11xx_cmd_list, "LPC832");
|
||||||
return true;
|
return true;
|
||||||
case 0x00008341: /* LPC8341201FHI33 */
|
case 0x00008341: /* LPC834M101FHI33 - 32K Flash 4K SRAM */
|
||||||
t->driver = "LPC834";
|
t->driver = "LPC834";
|
||||||
target_add_ram(t, 0x10000000, 0x1000);
|
target_add_ram(t, 0x10000000, 0x1000);
|
||||||
lpc11xx_add_flash(t, 0x00000000, 0x8000, 0x400, IAP_ENTRY_MOST, 0);
|
lpc11xx_add_flash(t, 0x00000000, 0x8000, 0x400, IAP_ENTRY_MOST, 0);
|
||||||
target_add_commands(t, lpc11xx_cmd_list, "LPC834");
|
target_add_commands(t, lpc11xx_cmd_list, "LPC834");
|
||||||
return true;
|
return true;
|
||||||
case 0x00008441:
|
case 0x00008441: /* LPC844M201JBD64 - 64K Flash 8K SRAM */
|
||||||
case 0x00008442:
|
case 0x00008442: /* LPC844M201JBD48 */
|
||||||
case 0x00008443: /* UM11029 Rev.1.4 list 8442 */
|
case 0x00008443: /* LPC844M201JHI48, note UM11029 Rev.1.4 table 29 is wrong, see table 174 (in same manual) */
|
||||||
case 0x00008444:
|
case 0x00008444: /* LPC844M201JHI33 */
|
||||||
t->driver = "LPC844";
|
t->driver = "LPC844";
|
||||||
target_add_ram(t, 0x10000000, 0x2000);
|
target_add_ram(t, 0x10000000, 0x2000);
|
||||||
lpc11xx_add_flash(t, 0x00000000, 0x10000, 0x400, IAP_ENTRY_84x, 0);
|
lpc11xx_add_flash(t, 0x00000000, 0x10000, 0x400, IAP_ENTRY_84x, 0);
|
||||||
|
target_add_commands(t, lpc11xx_cmd_list, "LPC844");
|
||||||
return true;
|
return true;
|
||||||
case 0x00008451:
|
case 0x00008451: /* LPC845M301JBD64 - 64K Flash 16K SRAM */
|
||||||
case 0x00008452:
|
case 0x00008452: /* LPC845M301JBD48 */
|
||||||
case 0x00008453:
|
case 0x00008453: /* LPC845M301JHI48 */
|
||||||
case 0x00008454:
|
case 0x00008454: /* LPC845M301JHI33 */
|
||||||
t->driver = "LPC845";
|
t->driver = "LPC845";
|
||||||
target_add_ram(t, 0x10000000, 0x4000);
|
target_add_ram(t, 0x10000000, 0x4000);
|
||||||
lpc11xx_add_flash(t, 0x00000000, 0x10000, 0x400, IAP_ENTRY_84x, 0);
|
lpc11xx_add_flash(t, 0x00000000, 0x10000, 0x400, IAP_ENTRY_84x, 0);
|
||||||
|
target_add_commands(t, lpc11xx_cmd_list, "LPC845");
|
||||||
return true;
|
return true;
|
||||||
case 0x0003D440: /* LPC11U34/311 */
|
case 0x0003D440: /* LPC11U34/311 - 40K Flash 8K SRAM */
|
||||||
case 0x0001cc40: /* LPC11U34/421 */
|
case 0x0001cc40: /* LPC11U34/421 - 48K Flash 8K SRAM */
|
||||||
case 0x0001BC40: /* LPC11U35/401 */
|
case 0x0001BC40: /* LPC11U35/401 - 64K Flash 8K SRAM */
|
||||||
case 0x0000BC40: /* LPC11U35/501 */
|
case 0x0000BC40: /* LPC11U35/501 - 64K Flash 8K SRAM */
|
||||||
case 0x00019C40: /* LPC11U36/401 */
|
case 0x00019C40: /* LPC11U36/401 - 96K Flash 8K SRAM */
|
||||||
case 0x00017C40: /* LPC11U37FBD48/401 */
|
case 0x00017C40: /* LPC11U37FBD48/401 - 128K Flash 8K SRAM */
|
||||||
case 0x00007C44: /* LPC11U37HFBD64/401 */
|
case 0x00007C44: /* LPC11U37HFBD64/401 */
|
||||||
case 0x00007C40: /* LPC11U37FBD64/501 */
|
case 0x00007C40: /* LPC11U37FBD64/501 */
|
||||||
t->driver = "LPC11U3x";
|
t->driver = "LPC11U3x";
|
||||||
target_add_ram(t, 0x10000000, 0x2000);
|
target_add_ram(t, 0x10000000, 0x2000);
|
||||||
lpc11xx_add_flash(t, 0x00000000, 0x20000, 0x1000, IAP_ENTRY_MOST, 0);
|
lpc11xx_add_flash(t, 0x00000000, 0x20000, 0x1000, IAP_ENTRY_MOST, 0);
|
||||||
|
target_add_commands(t, lpc11xx_cmd_list, "LPC11U3x");
|
||||||
return true;
|
return true;
|
||||||
case 0x00040070: /* LPC1114/333 */
|
case 0x00010013: /* LPC1111/103 - 8K Flash 2K SRAM */
|
||||||
case 0x00050080: /* lpc1115XL */
|
case 0x00010012: /* LPC1111/203 - 8K Flash 4K SRAM */
|
||||||
t->driver = "LPC1100XL";
|
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);
|
target_add_ram(t, 0x10000000, 0x2000);
|
||||||
lpc11xx_add_flash(t, 0x00000000, 0x20000, 0x1000, IAP_ENTRY_MOST, 0);
|
lpc11xx_add_flash(t, 0x00000000, 0x20000, 0x1000, IAP_ENTRY_MOST, 0);
|
||||||
|
target_add_commands(t, lpc11xx_cmd_list, "LPC11xx-XL");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (idcode) {
|
if (idcode) {
|
||||||
|
@ -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) ) {
|
if (f->reserved_pages && ((addr + len) >= tf->length - 0x400) ) {
|
||||||
last_full_sector -= 1;
|
last_full_sector -= 1;
|
||||||
}
|
}
|
||||||
if (start >= last_full_sector) {
|
if (start <= last_full_sector) {
|
||||||
/* Sector erase */
|
/* Sector erase */
|
||||||
if (lpc_iap_call(f, NULL, IAP_CMD_ERASE, start, last_full_sector, CPU_CLK_KHZ, f->bank))
|
if (lpc_iap_call(f, NULL, IAP_CMD_ERASE, start, last_full_sector, CPU_CLK_KHZ, f->bank))
|
||||||
return -2;
|
return -2;
|
||||||
|
@ -31,6 +31,7 @@ static int nrf51_flash_write(struct target_flash *f,
|
|||||||
target_addr dest, const void *src, size_t len);
|
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_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_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_fwid(target *t, int argc, const char **argv);
|
||||||
static bool nrf51_cmd_read_deviceid(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[] = {
|
const struct command_s nrf51_cmd_list[] = {
|
||||||
{"erase_mass", (cmd_handler)nrf51_cmd_erase_all, "Erase entire flash memory"},
|
{"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"},
|
{"read", (cmd_handler)nrf51_cmd_read, "Read device parameters"},
|
||||||
{NULL, NULL, NULL}
|
{NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
@ -244,6 +246,31 @@ static bool nrf51_cmd_erase_all(target *t, int argc, const char **argv)
|
|||||||
return true;
|
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)
|
static bool nrf51_cmd_read_hwid(target *t, int argc, const char **argv)
|
||||||
{
|
{
|
||||||
(void)argc;
|
(void)argc;
|
||||||
|
@ -248,7 +248,7 @@ bool sam3x_probe(target *t)
|
|||||||
case CHIPID_CIDR_ARCH_SAM4SDC | CHIPID_CIDR_EPROC_CM4:
|
case CHIPID_CIDR_ARCH_SAM4SDC | CHIPID_CIDR_EPROC_CM4:
|
||||||
t->driver = "Atmel SAM4S";
|
t->driver = "Atmel SAM4S";
|
||||||
target_add_ram(t, 0x20000000, 0x400000);
|
target_add_ram(t, 0x20000000, 0x400000);
|
||||||
size_t size = sam_flash_size(cidr);
|
size = sam_flash_size(cidr);
|
||||||
if (size <= 0x80000) {
|
if (size <= 0x80000) {
|
||||||
/* Smaller devices have a single bank */
|
/* Smaller devices have a single bank */
|
||||||
sam4_add_flash(t, SAM4S_EEFC_BASE(0), 0x400000, size);
|
sam4_add_flash(t, SAM4S_EEFC_BASE(0), 0x400000, size);
|
||||||
|
@ -386,7 +386,7 @@ static bool stm32f1_cmd_erase_mass(target *t, int argc, const char **argv)
|
|||||||
if(target_check_error(t))
|
if(target_check_error(t))
|
||||||
return false;
|
return false;
|
||||||
/* Check for error */
|
/* 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))
|
if ((sr & SR_ERROR_MASK) || !(sr & SR_EOP))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -384,9 +384,9 @@ static int stm32f4_flash_erase(struct target_flash *f, target_addr addr,
|
|||||||
stm32f4_flash_unlock(t);
|
stm32f4_flash_unlock(t);
|
||||||
|
|
||||||
enum align psize = ALIGN_WORD;
|
enum align psize = ALIGN_WORD;
|
||||||
for (struct target_flash *f = t->flash; f; f = f->next) {
|
for (struct target_flash *currf = t->flash; currf; currf = currf->next) {
|
||||||
if (f->write == stm32f4_flash_write) {
|
if (currf->write == stm32f4_flash_write) {
|
||||||
psize = ((struct stm32f4_flash *)f)->psize;
|
psize = ((struct stm32f4_flash *)currf)->psize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while(len) {
|
while(len) {
|
||||||
|
@ -34,6 +34,11 @@ static bool nop_function(void)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int null_function(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
target *target_new(void)
|
target *target_new(void)
|
||||||
{
|
{
|
||||||
target *t = (void*)calloc(1, sizeof(*t));
|
target *t = (void*)calloc(1, sizeof(*t));
|
||||||
@ -63,6 +68,7 @@ target *target_new(void)
|
|||||||
t->halt_request = (void*)nop_function;
|
t->halt_request = (void*)nop_function;
|
||||||
t->halt_poll = (void*)nop_function;
|
t->halt_poll = (void*)nop_function;
|
||||||
t->halt_resume = (void*)nop_function;
|
t->halt_resume = (void*)nop_function;
|
||||||
|
t->check_error = (void*)null_function;
|
||||||
|
|
||||||
t->target_storage = NULL;
|
t->target_storage = NULL;
|
||||||
|
|
||||||
@ -276,7 +282,7 @@ int target_flash_done(target *t)
|
|||||||
if (tmp)
|
if (tmp)
|
||||||
return tmp;
|
return tmp;
|
||||||
if (f->done) {
|
if (f->done) {
|
||||||
int tmp = f->done(f);
|
tmp = f->done(f);
|
||||||
if (tmp)
|
if (tmp)
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
@ -21,10 +21,12 @@
|
|||||||
|
|
||||||
void platform_timeout_set(platform_timeout *t, uint32_t ms)
|
void platform_timeout_set(platform_timeout *t, uint32_t ms)
|
||||||
{
|
{
|
||||||
|
if (ms <= SYSTICKMS)
|
||||||
|
ms = SYSTICKMS;
|
||||||
t->time = platform_time_ms() + ms;
|
t->time = platform_time_ms() + ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool platform_timeout_is_expired(platform_timeout *t)
|
bool platform_timeout_is_expired(platform_timeout *t)
|
||||||
{
|
{
|
||||||
return platform_time_ms() >= t->time;
|
return platform_time_ms() > t->time;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user