Merge commit 'e6a9a1a3665e83e25d5d4077a33aa5b0110646b8' into sam-update

# Conflicts:
#	.gitignore
This commit is contained in:
Jason Kotzin 2022-08-10 19:48:21 -07:00
commit 78837173a4
24 changed files with 322 additions and 164 deletions

40
.gitattributes vendored Normal file
View File

@ -0,0 +1,40 @@
# Text for humans
LICENSE text eol=lf
HACKING text eol=lf
COPYING text eol=lf
UsingSWO text eol=lf
README.* text eol=lf
# Source code
Makefile text eol=lf
*.mk text eol=lf
*.mak text eol=lf
*.inc text eol=lf
*.py text eol=lf
*.sh text eol=lf
*.c text eol=lf
*.S text eol=lf
*.s text eol=lf
*.h text eol=lf
*.ld text eol=lf
*.yml text eol=lf
*.rules text eol=lf
# Git control files
.gitattributes eol=lf
.gitignore eol=lf
.gitmodules eol=lf
# Windows source code uses CRLF
*.vcxproj text eol=crlf
*.props text eol=crlf
*.bat text eol=crlf
*.ps1 text eol=crlf
*.inf text eol=crlf
# Other binary files
*.png binary
*.jpg binary
*.bin binary
*.elf binary
*.bin binary

2
.gitignore vendored
View File

@ -21,3 +21,5 @@ blackmagic_upgrade
.vscode .vscode
cscope.out cscope.out
cscope.files cscope.files
.gdb_history
src/artifacts/

View File

@ -14,24 +14,28 @@ monitor traceswo 115200
We are constrained on maximum input speed by both the capabilities of the We are constrained on maximum input speed by both the capabilities of the
BMP STM32F103 USART and the ability to get the packets back out over the USB BMP STM32F103 USART and the ability to get the packets back out over the USB
link. The UART baudrate is set by b=(72x10^6)/(16*d)...so for d=1 that means link. The UART baudrate is set by b=(72x10^6)/d...with d >= 16 or
a maximum speed of 4.5Mbps. For continious streaming that turns out to be a maximum speed of 4.5Mbps UART1 and 2.25 Mbps on UART2.
_too_ fast for the USB link, so the next available option is the 2.25Mbps For continious streaming that turns out to be_too_ fast for the USB
that we use. ....you can safely use the 4.5Mbps setting if your debug data link, so the next available option is the 2.25Mbps that we use. ....
You can safely use the 4.5Mbps setting if your debug data
is bursty, or if you're using a different CPU to the STM32F103 as your BMP is bursty, or if you're using a different CPU to the STM32F103 as your BMP
host, but you potentially run the risk of losing packets if you have long host, but you potentially run the risk of losing packets if you have long
runs of sending which the usb cannot flush in time (there's a 12K buffer, so runs of sending which the usb cannot flush in time (there's a 12K buffer, so
the it is a pretty long run before it becomes a problem). the it is a pretty long run before it becomes a problem).
Note that the baudrate equation means there are only certain speeds Note that the baudrate equation means there are only certain speeds
available. The highest half dozen are; available. The highest:
SWO uses USART1(stlink) USART2(swlink) BRR USART1(stlink) USART2(swlink)
1 4.50 Mbps 2.25 Mbps 16 4.50 Mbps 2.25 Mbps
2 2.25 Mbps 1.125 Mbps 17 4.235 Mbps 2.118 Mbps
3 1.50 Mbps 0.75 Mbps 18 4.000 Mbps 2.0 Mbps
4 1.125 Mbps 0.5635 Mbps 19 3.789 Mbps 1.895 Mbps
5 0.900 Mbps 0.45 Mbps 20 3.600 Mbps 1.8 Mbps
6 0.750 Mbps 0.375 Mbps ...
24 3.0 Mbps 1.5 Mbps
...
36 2.0 Mbps 1.0 Mbps
...the USART will cope with some timing slip, but it's advisible to stay as ...the USART will cope with some timing slip, but it's advisible to stay as
close to these values as you can. As the speed comes down the spread between close to these values as you can. As the speed comes down the spread between

View File

@ -3,6 +3,8 @@
* *
* 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
@ -27,6 +29,7 @@
#include "command.h" #include "command.h"
#include "gdb_packet.h" #include "gdb_packet.h"
#include "target.h" #include "target.h"
#include "target_internal.h"
#include "morse.h" #include "morse.h"
#include "version.h" #include "version.h"
#include "serialno.h" #include "serialno.h"
@ -37,13 +40,6 @@
typedef bool (*cmd_handler)(target *t, int argc, const char **argv); typedef bool (*cmd_handler)(target *t, int argc, const char **argv);
struct command_s {
const char *cmd;
cmd_handler handler;
const char *help;
};
static bool cmd_version(target *t, int argc, char **argv); static bool cmd_version(target *t, int argc, char **argv);
static bool cmd_serial(target *t, int argc, char **argv); static bool cmd_serial(target *t, int argc, char **argv);
static bool cmd_help(target *t, int argc, char **argv); static bool cmd_help(target *t, int argc, char **argv);
@ -179,10 +175,11 @@ bool cmd_help(target *t, int argc, char **argv)
(void)argv; (void)argv;
const struct command_s *c; const struct command_s *c;
if (!t || t->tc->destroy_callback) {
gdb_out("General commands:\n"); gdb_out("General commands:\n");
for(c = cmd_list; c->cmd; c++) for(c = cmd_list; c->cmd; c++)
gdb_outf("\t%s -- %s\n", c->cmd, c->help); gdb_outf("\t%s -- %s\n", c->cmd, c->help);
}
if (!t) if (!t)
return -1; return -1;
@ -240,8 +237,9 @@ static bool cmd_jtag_scan(target *t, int argc, char **argv)
bool cmd_swdp_scan(target *t, int argc, char **argv) bool cmd_swdp_scan(target *t, int argc, char **argv)
{ {
(void)t; (void)t;
(void)argc; volatile uint32_t targetid = 0;
(void)argv; if (argc > 1)
targetid = strtol(argv[1], NULL, 0);
if (platform_target_voltage()) if (platform_target_voltage())
gdb_outf("Target voltage: %s\n", platform_target_voltage()); gdb_outf("Target voltage: %s\n", platform_target_voltage());
@ -252,9 +250,9 @@ bool cmd_swdp_scan(target *t, int argc, char **argv)
volatile struct exception e; volatile struct exception e;
TRY_CATCH (e, EXCEPTION_ALL) { TRY_CATCH (e, EXCEPTION_ALL) {
#if PC_HOSTED == 1 #if PC_HOSTED == 1
devs = platform_adiv5_swdp_scan(); devs = platform_adiv5_swdp_scan(targetid);
#else #else
devs = adiv5_swdp_scan(); devs = adiv5_swdp_scan(targetid);
#endif #endif
} }
switch (e.type) { switch (e.type) {

View File

@ -35,13 +35,13 @@ typedef uint32_t target_addr;
struct target_controller; struct target_controller;
#if PC_HOSTED == 1 #if PC_HOSTED == 1
int platform_adiv5_swdp_scan(void); int platform_adiv5_swdp_scan(uint32_t targetid);
int platform_jtag_scan(const uint8_t *lrlens); int platform_jtag_scan(const uint8_t *lrlens);
#endif #endif
int adiv5_swdp_scan(void); int adiv5_swdp_scan(uint32_t targetid);
int jtag_scan(const uint8_t *lrlens); int jtag_scan(const uint8_t *lrlens);
bool target_foreach(void (*cb)(int i, target *t, void *context), void *context); int target_foreach(void (*cb)(int i, target *t, void *context), void *context);
void target_list_free(void); void target_list_free(void);
/* Attach/detach functions */ /* Attach/detach functions */

View File

@ -144,7 +144,7 @@ static const struct usb_interface_descriptor gdb_comm_iface[] = {{
.bNumEndpoints = 1, .bNumEndpoints = 1,
.bInterfaceClass = USB_CLASS_CDC, .bInterfaceClass = USB_CLASS_CDC,
.bInterfaceSubClass = USB_CDC_SUBCLASS_ACM, .bInterfaceSubClass = USB_CDC_SUBCLASS_ACM,
.bInterfaceProtocol = USB_CDC_PROTOCOL_AT, .bInterfaceProtocol = USB_CDC_PROTOCOL_NONE,
.iInterface = 4, .iInterface = 4,
.endpoint = gdb_comm_endp, .endpoint = gdb_comm_endp,
@ -174,7 +174,7 @@ static const struct usb_iface_assoc_descriptor gdb_assoc = {
.bInterfaceCount = 2, .bInterfaceCount = 2,
.bFunctionClass = USB_CLASS_CDC, .bFunctionClass = USB_CLASS_CDC,
.bFunctionSubClass = USB_CDC_SUBCLASS_ACM, .bFunctionSubClass = USB_CDC_SUBCLASS_ACM,
.bFunctionProtocol = USB_CDC_PROTOCOL_AT, .bFunctionProtocol = USB_CDC_PROTOCOL_NONE,
.iFunction = 0, .iFunction = 0,
}; };
@ -247,7 +247,7 @@ static const struct usb_interface_descriptor uart_comm_iface[] = {{
.bNumEndpoints = 1, .bNumEndpoints = 1,
.bInterfaceClass = USB_CLASS_CDC, .bInterfaceClass = USB_CLASS_CDC,
.bInterfaceSubClass = USB_CDC_SUBCLASS_ACM, .bInterfaceSubClass = USB_CDC_SUBCLASS_ACM,
.bInterfaceProtocol = USB_CDC_PROTOCOL_AT, .bInterfaceProtocol = USB_CDC_PROTOCOL_NONE,
.iInterface = 5, .iInterface = 5,
.endpoint = uart_comm_endp, .endpoint = uart_comm_endp,
@ -277,7 +277,7 @@ static const struct usb_iface_assoc_descriptor uart_assoc = {
.bInterfaceCount = 2, .bInterfaceCount = 2,
.bFunctionClass = USB_CLASS_CDC, .bFunctionClass = USB_CLASS_CDC,
.bFunctionSubClass = USB_CDC_SUBCLASS_ACM, .bFunctionSubClass = USB_CDC_SUBCLASS_ACM,
.bFunctionProtocol = USB_CDC_PROTOCOL_AT, .bFunctionProtocol = USB_CDC_PROTOCOL_NONE,
.iFunction = 0, .iFunction = 0,
}; };

View File

@ -36,7 +36,19 @@ blackmagic -V <file>.bin
``` ```
### Show more options ### Show more options
``` ```
blackmagic -h" blackmagic -h
```
### Show available monitor commands
```
blackmagic -M help
```
### Show available monitor commands on second target
```
blackmagic -n 2 -M help
```
### Monitor commands with multiple arguments, e.g.Stm32F1:
```
blackmagic -M "option help"
``` ```
## Used shared libraries: ## Used shared libraries:
### libusb ### libusb

View File

@ -1,7 +1,7 @@
/* /*
* This file is part of the Black Magic Debug project. * This file is part of the Black Magic Debug project.
* *
* Copyright (C) 2020 Uwe Bonnes (bon@elektron.ikp.physik.tu-darmstadt.de) * Copyright(C) 2020 - 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
@ -36,13 +36,15 @@
#define VENDOR_ID_SEGGER 0x1366 #define VENDOR_ID_SEGGER 0x1366
#define NO_SERIAL_NUMBER "<no serial number>"
void bmp_ident(bmp_info_t *info) void bmp_ident(bmp_info_t *info)
{ {
DEBUG_INFO("BMP hosted %s\n for ST-Link V2/3, CMSIS_DAP, JLINK and " DEBUG_INFO("BMP hosted %s\n for ST-Link V2/3, CMSIS_DAP, JLINK and "
"LIBFTDI/MPSSE\n", FIRMWARE_VERSION); "LIBFTDI/MPSSE\n", FIRMWARE_VERSION);
if (info && info->vid && info->pid) if (info && info->vid && info->pid)
DEBUG_INFO("Using %04x:%04x %s %s\n %s\n", info->vid, info->pid, DEBUG_INFO("Using %04x:%04x %s %s\n %s\n", info->vid, info->pid,
info->serial, (info->serial[0]) ? info->serial : NO_SERIAL_NUMBER,
info->manufacturer, info->manufacturer,
info->product); info->product);
} }
@ -147,22 +149,9 @@ int find_debuggers(BMP_CL_OPTIONS_t *cl_opts,bmp_info_t *info)
res = libusb_get_string_descriptor_ascii( res = libusb_get_string_descriptor_ascii(
handle, desc.iManufacturer, (uint8_t*)manufacturer, handle, desc.iManufacturer, (uint8_t*)manufacturer,
sizeof(manufacturer)); sizeof(manufacturer));
if (res > 0) {
res = libusb_get_string_descriptor_ascii( res = libusb_get_string_descriptor_ascii(
handle, desc.iProduct, (uint8_t*)product, handle, desc.iProduct, (uint8_t*)product,
sizeof(product)); sizeof(product));
if (res <= 0) {
DEBUG_WARN( "WARN:"
"libusb_get_string_descriptor_ascii "
"for ident_string failed: %s\n",
libusb_strerror(res));
libusb_close(handle);
continue;
}
} else {
libusb_close(handle);
continue;
}
libusb_close(handle); libusb_close(handle);
if (cl_opts->opt_ident_string) { if (cl_opts->opt_ident_string) {
char *match_manu = NULL; char *match_manu = NULL;
@ -233,11 +222,9 @@ int find_debuggers(BMP_CL_OPTIONS_t *cl_opts,bmp_info_t *info)
if (!cable->name) if (!cable->name)
continue; continue;
} }
if (!serial[0])
strcpy(serial, "<no serial number>");
if (report) { if (report) {
DEBUG_WARN("%2d: %s, %s, %s\n", found_debuggers + 1, DEBUG_WARN("%2d: %s, %s, %s\n", found_debuggers + 1,
serial, (serial[0]) ? serial : NO_SERIAL_NUMBER,
manufacturer,product); manufacturer,product);
} }
info->vid = desc.idVendor; info->vid = desc.idVendor;

View File

@ -73,7 +73,7 @@ bool remote_target_get_power(void)
return (construct[1] == '1'); return (construct[1] == '1');
} }
void remote_target_set_power(bool power) bool remote_target_set_power(bool power)
{ {
uint8_t construct[REMOTE_MAX_MSG_SIZE]; uint8_t construct[REMOTE_MAX_MSG_SIZE];
int s; int s;
@ -87,8 +87,9 @@ void remote_target_set_power(bool power)
if ((!s) || (construct[0] == REMOTE_RESP_ERR)) { if ((!s) || (construct[0] == REMOTE_RESP_ERR)) {
DEBUG_WARN("platform_target_set_power failed, error %s\n", DEBUG_WARN("platform_target_set_power failed, error %s\n",
s ? (char *)&(construct[1]) : "unknown"); s ? (char *)&(construct[1]) : "unknown");
exit(-1); return false;
} }
return true;
} }
void remote_srst_set_val(bool assert) void remote_srst_set_val(bool assert)

View File

@ -34,7 +34,7 @@ int remote_swdptap_init(swd_proc_t *swd_proc);
int remote_jtagtap_init(jtag_proc_t *jtag_proc); int remote_jtagtap_init(jtag_proc_t *jtag_proc);
bool remote_target_get_power(void); bool remote_target_get_power(void);
const char *remote_target_voltage(void); const char *remote_target_voltage(void);
void remote_target_set_power(bool power); bool remote_target_set_power(bool power);
void remote_srst_set_val(bool assert); void remote_srst_set_val(bool assert);
bool remote_srst_get_val(void); bool remote_srst_get_val(void);
void remote_max_frequency_set(uint32_t freq); void remote_max_frequency_set(uint32_t freq);

View File

@ -1,7 +1,7 @@
/* /*
* This file is part of the Black Magic Debug project. * This file is part of the Black Magic Debug project.
* *
* Copyright (C) 2019-20 Uwe Bonnes <bon@elektron,ikp.physik.tu-darmstadt.de> * Copyright (C) 2019-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
@ -49,10 +49,11 @@ uint8_t mode;
static hid_device *handle = NULL; static hid_device *handle = NULL;
static uint8_t hid_buffer[1024 + 1]; static uint8_t hid_buffer[1024 + 1];
static int report_size = 64 + 1; // TODO: read actual report size static int report_size = 64 + 1; // TODO: read actual report size
static bool has_swd_sequence = false;
/* LPC845 Breakout Board Rev. 0 report invalid response with > 65 bytes */ /* LPC845 Breakout Board Rev. 0 report invalid response with > 65 bytes */
int dap_init(bmp_info_t *info) int dap_init(bmp_info_t *info)
{ {
DEBUG_INFO("dap_init\n");
if (hid_init()) if (hid_init())
return -1; return -1;
int size = strlen(info->serial); int size = strlen(info->serial);
@ -71,17 +72,32 @@ int dap_init(bmp_info_t *info)
if (!handle) if (!handle)
return -1; return -1;
dap_disconnect(); dap_disconnect();
size = dap_info(DAP_INFO_FW_VER, hid_buffer, sizeof(hid_buffer));
if (size) {
DEBUG_INFO("Ver %s, ", hid_buffer);
int major = -1, minor = -1, sub = -1;
if (sscanf((const char *)hid_buffer, "%d.%d.%d",
&major, &minor, &sub)) {
if (sub == -1) {
if (minor > 10) {
minor /= 10;
sub = 0;
}
}
has_swd_sequence = ((major > 0 ) && (minor > 1));
}
}
size = dap_info(DAP_INFO_CAPABILITIES, hid_buffer, sizeof(hid_buffer)); size = dap_info(DAP_INFO_CAPABILITIES, hid_buffer, sizeof(hid_buffer));
dap_caps = hid_buffer[0]; dap_caps = hid_buffer[0];
DEBUG_INFO(" Cap (0x%2x): %s%s%s", hid_buffer[0], DEBUG_INFO("Cap (0x%2x): %s%s%s", dap_caps,
(hid_buffer[0] & 1)? "SWD" : "", (dap_caps & 1)? "SWD" : "",
((hid_buffer[0] & 3) == 3) ? "/" : "", ((dap_caps & 3) == 3) ? "/" : "",
(hid_buffer[0] & 2)? "JTAG" : ""); (dap_caps & 2)? "JTAG" : "");
if (hid_buffer[0] & 4) if (dap_caps & 4)
DEBUG_INFO(", SWO_UART"); DEBUG_INFO(", SWO_UART");
if (hid_buffer[0] & 8) if (dap_caps & 8)
DEBUG_INFO(", SWO_MANCHESTER"); DEBUG_INFO(", SWO_MANCHESTER");
if (hid_buffer[0] & 0x10) if (dap_caps & 0x10)
DEBUG_INFO(", Atomic Cmds"); DEBUG_INFO(", Atomic Cmds");
DEBUG_INFO("\n"); DEBUG_INFO("\n");
return 0; return 0;

View File

@ -27,7 +27,6 @@
#include "jtagtap.h" #include "jtagtap.h"
#include "bmp_hosted.h" #include "bmp_hosted.h"
#include <libftdi1/ftdi.h>
typedef struct data_desc_s { typedef struct data_desc_s {
int16_t data_low; int16_t data_low;
@ -101,11 +100,6 @@ typedef struct cable_desc_s {
char * name; char * name;
}cable_desc_t; }cable_desc_t;
extern cable_desc_t cable_desc[];
extern cable_desc_t *active_cable;
extern struct ftdi_context *ftdic;
extern data_desc_t active_state;
#if HOSTED_BMP_ONLY == 1 #if HOSTED_BMP_ONLY == 1
# pragma GCC diagnostic push # pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wunused-parameter" # pragma GCC diagnostic ignored "-Wunused-parameter"
@ -123,6 +117,12 @@ 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;};
# pragma GCC diagnostic pop # pragma GCC diagnostic pop
#else #else
#include <libftdi1/ftdi.h>
extern cable_desc_t cable_desc[];
extern cable_desc_t *active_cable;
extern struct ftdi_context *ftdic;
extern data_desc_t active_state;
int ftdi_bmp_init(BMP_CL_OPTIONS_t *cl_opts, bmp_info_t *info); int ftdi_bmp_init(BMP_CL_OPTIONS_t *cl_opts, bmp_info_t *info);
int libftdi_swdptap_init(swd_proc_t *swd_proc); int libftdi_swdptap_init(swd_proc_t *swd_proc);
int libftdi_jtagtap_init(jtag_proc_t *jtag_proc); int libftdi_jtagtap_init(jtag_proc_t *jtag_proc);

View File

@ -1,7 +1,7 @@
/* /*
* This file is part of the Black Magic Debug project. * This file is part of the Black Magic Debug project.
* *
* Copyright (C) 2020 Uwe Bonnes (bon@elektron.ikp.physik.tu-darmstadt.de) * Copyright (C) 2020- 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
@ -119,14 +119,16 @@ void platform_init(int argc, char **argv)
exit(ret); exit(ret);
} }
int platform_adiv5_swdp_scan(void) int platform_adiv5_swdp_scan(uint32_t targetid)
{ {
info.is_jtag = false; info.is_jtag = false;
platform_max_frequency_set(cl_opts.opt_max_swj_frequency); platform_max_frequency_set(cl_opts.opt_max_swj_frequency);
if (targetid && (info.bmp_type != BMP_TYPE_BMP))
DEBUG_WARN("Ignoring TARGETID for now!\n");
switch (info.bmp_type) { switch (info.bmp_type) {
case BMP_TYPE_BMP: case BMP_TYPE_BMP:
case BMP_TYPE_LIBFTDI: case BMP_TYPE_LIBFTDI:
return adiv5_swdp_scan(); return adiv5_swdp_scan(targetid);
break; break;
case BMP_TYPE_STLINKV2: case BMP_TYPE_STLINKV2:
{ {
@ -377,6 +379,20 @@ uint32_t platform_max_frequency_get(void)
return false; return false;
} }
void platform_target_set_power(bool power)
{
switch (info.bmp_type) {
case BMP_TYPE_BMP:
if (remote_target_set_power(power))
DEBUG_INFO("Powering up device!\n");
else
DEBUG_WARN("Powering up device unimplemented or failed\n");
break;
default:
break;
}
}
void platform_buffer_flush(void) void platform_buffer_flush(void)
{ {
switch (info.bmp_type) { switch (info.bmp_type) {

View File

@ -131,10 +131,6 @@ void platform_init(void)
GPIO_CNF_OUTPUT_PUSHPULL, GPIO_CNF_OUTPUT_PUSHPULL,
LED_UART | LED_IDLE_RUN | LED_ERROR); LED_UART | LED_IDLE_RUN | LED_ERROR);
/* FIXME: This pin in intended to be input, but the TXS0108 fails
* to release the device from reset if this floats. */
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO7);
/* Enable SRST output. Original uses a NPN to pull down, so setting the /* Enable SRST output. Original uses a NPN to pull down, so setting the
* output HIGH asserts. Mini is directly connected so use open drain output * output HIGH asserts. Mini is directly connected so use open drain output
* and set LOW to assert. * and set LOW to assert.
@ -146,7 +142,17 @@ void platform_init(void)
? GPIO_CNF_OUTPUT_PUSHPULL ? GPIO_CNF_OUTPUT_PUSHPULL
: GPIO_CNF_OUTPUT_OPENDRAIN), : GPIO_CNF_OUTPUT_OPENDRAIN),
SRST_PIN); SRST_PIN);
/* FIXME: Gareth, Esden, what versions need this fix? */
if (platform_hwversion() < 3) {
/* FIXME: This pin in intended to be input, but the TXS0108 fails
* to release the device from reset if this floats. */
gpio_set_mode(SRST_SENSE_PORT, GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, SRST_SENSE_PIN);
} else {
gpio_set(SRST_SENSE_PORT, SRST_SENSE_PIN);
gpio_set_mode(SRST_SENSE_PORT, GPIO_MODE_INPUT,
GPIO_CNF_INPUT_PULL_UPDOWN, SRST_SENSE_PIN);
}
/* Enable internal pull-up on PWR_BR so that we don't drive /* Enable internal pull-up on PWR_BR so that we don't drive
TPWR locally or inadvertently supply power to the target. */ TPWR locally or inadvertently supply power to the target. */
if (platform_hwversion () == 1) { if (platform_hwversion () == 1) {

View File

@ -1,7 +1,7 @@
/* /*
* This file is part of the Black Magic Debug project. * This file is part of the Black Magic Debug project.
* *
* Copyright (C) 2019 - 2020 Uwe Bonnes * Copyright (C) 2019 - 2021 Uwe Bonnes
* (bon@elektron.ikp.physik.tu-darmstadt.de) * (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
@ -32,6 +32,7 @@
#include "target.h" #include "target.h"
#include "target_internal.h" #include "target_internal.h"
#include "cortexm.h" #include "cortexm.h"
#include "command.h"
#include "cl_utils.h" #include "cl_utils.h"
#include "bmp_hosted.h" #include "bmp_hosted.h"
@ -45,6 +46,18 @@
# include <sys/mman.h> # include <sys/mman.h>
#endif #endif
static void cl_target_printf(struct target_controller *tc,
const char *fmt, va_list ap)
{
(void)tc;
vprintf(fmt, ap);
}
static struct target_controller cl_controller = {
.printf = cl_target_printf,
};
struct mmap_data { struct mmap_data {
void *data; void *data;
size_t size; size_t size;
@ -152,6 +165,9 @@ static void cl_help(char **argv)
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\t\t: Reset device\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 <string>\t: Run target specific monitor commands. Quote multi\n");
DEBUG_WARN("\t\t\t word strings. Run \"-M help\" for help.\n");
DEBUG_WARN("Flash operation modifiers options:\n"); DEBUG_WARN("Flash operation modifiers options:\n");
DEBUG_WARN("\tDefault action with given file is to write to flash\n"); DEBUG_WARN("\tDefault action with given file is to write to flash\n");
DEBUG_WARN("\t-a <addr>\t: Start flash operation at flash address <addr>\n" DEBUG_WARN("\t-a <addr>\t: Start flash operation at flash address <addr>\n"
@ -168,7 +184,7 @@ void cl_init(BMP_CL_OPTIONS_t *opt, int argc, char **argv)
opt->opt_flash_size = 16 * 1024 *1024; opt->opt_flash_size = 16 * 1024 *1024;
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:CnltVtTa:S:jpP:rR")) != -1) { while((c = getopt(argc, argv, "eEhHv:d:f:s:I:c:Cln:m:M:tVtTa:S:jpP:rR")) != -1) {
switch(c) { switch(c) {
case 'c': case 'c':
if (optarg) if (optarg)
@ -255,6 +271,15 @@ void cl_init(BMP_CL_OPTIONS_t *opt, int argc, char **argv)
if (optarg) if (optarg)
opt->opt_target_dev = strtol(optarg, NULL, 0); opt->opt_target_dev = strtol(optarg, NULL, 0);
break; break;
case 'm':
if (optarg)
opt->opt_targetid = strtol(optarg, NULL, 0);
break;
case 'M':
opt->opt_mode = BMP_MODE_MONITOR;
if (optarg)
opt->opt_monitor = optarg;
break;
case 'P': case 'P':
if (optarg) if (optarg)
opt->opt_position = atoi(optarg); opt->opt_position = atoi(optarg);
@ -313,13 +338,10 @@ int cl_execute(BMP_CL_OPTIONS_t *opt)
{ {
int res = -1; int res = -1;
int num_targets; int num_targets;
#if defined(PLATFORM_HAS_POWER_SWITCH)
if (opt->opt_tpwr) { if (opt->opt_tpwr) {
DEBUG_INFO("Powering up device");
platform_target_set_power(true); platform_target_set_power(true);
platform_delay(500); platform_delay(500);
} }
#endif
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;
@ -330,65 +352,51 @@ int cl_execute(BMP_CL_OPTIONS_t *opt)
if (opt->opt_usejtag) { if (opt->opt_usejtag) {
num_targets = platform_jtag_scan(NULL); num_targets = platform_jtag_scan(NULL);
} else { } else {
num_targets = platform_adiv5_swdp_scan(); num_targets = platform_adiv5_swdp_scan(opt->opt_targetid);
} }
if (!num_targets) { if (!num_targets) {
DEBUG_WARN("No target found\n"); DEBUG_WARN("No target found\n");
return res; return res;
} else { } else {
target_foreach(display_target, NULL); num_targets = target_foreach(display_target, &num_targets);
} }
if (opt->opt_target_dev > num_targets) { if (opt->opt_target_dev > num_targets) {
DEBUG_WARN("Given target nummer %d not available\n", DEBUG_WARN("Given target nummer %d not available max %d\n",
opt->opt_target_dev); opt->opt_target_dev, num_targets);
return res; return res;
} }
target *t = target_attach_n(opt->opt_target_dev, NULL); target *t = target_attach_n(opt->opt_target_dev, &cl_controller);
if (!t) { if (!t) {
DEBUG_WARN("Can not attach to target %d\n", opt->opt_target_dev); DEBUG_WARN("Can not attach to target %d\n", opt->opt_target_dev);
goto target_detach; goto target_detach;
} }
/* List each defined RAM */
int n_ram = 0;
for (struct target_ram *r = t->ram; r; r = r->next)
n_ram++;
for (int n = n_ram; n >= 0; n --) {
struct target_ram *r = t->ram;
for (int i = 1; r; r = r->next, i++)
if (i == n)
DEBUG_INFO("RAM Start: 0x%08" PRIx32 " length = 0x%" PRIx32 "\n",
r->start, (uint32_t)r->length);
}
/* Always scan memory map to find lowest flash */ /* Always scan memory map to find lowest flash */
char memory_map [1024], *p = memory_map; /* List each defined Flash */
uint32_t flash_start = 0xffffffff; uint32_t flash_start = 0xffffffff;
if (target_mem_map(t, memory_map, sizeof(memory_map))) { int n_flash = 0;
while (*p && (*p == '<')) { for (struct target_flash *f = t->flash; f; f = f->next)
unsigned int start, size; n_flash++;
char *res; for (int n = n_flash; n >= 0; n --) {
int match; struct target_flash *f = t->flash;
match = strncmp(p, "<memory-map>", strlen("<memory-map>")); for (int i = 1; f; f = f->next, i++)
if (!match) { if (i == n) {
p += strlen("<memory-map>"); DEBUG_INFO("Flash Start: 0x%08" PRIx32 " length = 0x%" PRIx32
continue; " blocksize 0x%" PRIx32 "\n",
} f->start, (uint32_t)f->length, (uint32_t)f->blocksize);
match = strncmp(p, "<memory type=\"flash\" ", strlen("<memory type=\"flash\" ")); if (f->start < flash_start)
if (!match) { flash_start = f->start;
unsigned int blocksize;
if (sscanf(p, "<memory type=\"flash\" start=\"%x\" length=\"%x\">"
"<property name=\"blocksize\">%x</property></memory>",
&start, &size, &blocksize)) {
if (opt->opt_mode == BMP_MODE_TEST)
DEBUG_INFO("Flash Start: 0x%08x, length %#9x, "
"blocksize %#8x\n", start, size, blocksize);
if (start < flash_start)
flash_start = start;
}
res = strstr(p, "</memory>");
p = res + strlen("</memory>");
continue;
}
match = strncmp(p, "<memory type=\"ram\" ", strlen("<memory type=\"ram\" "));
if (!match) {
if (sscanf(p, "<memory type=\"ram\" start=\"%x\" length=\"%x\"/",
&start, &size))
if (opt->opt_mode == BMP_MODE_TEST)
DEBUG_INFO("Ram Start: 0x%08x, length %#9x\n",
start, size);
res = strstr(p, "/>");
p = res + strlen("/>");
continue;
}
break;
} }
} }
if (opt->opt_flash_start == 0xffffffff) if (opt->opt_flash_start == 0xffffffff)
@ -406,6 +414,8 @@ int cl_execute(BMP_CL_OPTIONS_t *opt)
default: default:
DEBUG_WARN("No test for this core type yet\n"); DEBUG_WARN("No test for this core type yet\n");
} }
} else if (opt->opt_mode == BMP_MODE_MONITOR) {
command_process(t, opt->opt_monitor);
} }
if ((opt->opt_mode == BMP_MODE_TEST) || if ((opt->opt_mode == BMP_MODE_TEST) ||
(opt->opt_mode == BMP_MODE_SWJ_TEST)) (opt->opt_mode == BMP_MODE_SWJ_TEST))
@ -528,8 +538,11 @@ int cl_execute(BMP_CL_OPTIONS_t *opt)
uint32_t end_time = platform_time_ms(); uint32_t end_time = platform_time_ms();
if (read_file != -1) if (read_file != -1)
close(read_file); close(read_file);
if ((opt->opt_mode == BMP_MODE_FLASH_VERIFY) ||
(opt->opt_mode == BMP_MODE_FLASH_READ))
DEBUG_WARN("Read/Verify succeeded for %d bytes, %8.3f kiB/s\n", DEBUG_WARN("Read/Verify succeeded for %d bytes, %8.3f kiB/s\n",
bytes_read, (((bytes_read * 1.0)/(end_time - start_time)))); bytes_read,
(((bytes_read * 1.0)/(end_time - start_time))));
} }
free_map: free_map:
if (map.size) if (map.size)

View File

@ -1,7 +1,7 @@
/* /*
* This file is part of the Black Magic Debug project. * This file is part of the Black Magic Debug project.
* *
* Copyright (C) 2019 - 2020 Uwe Bonnes * Copyright (C) 2019 - 2021 Uwe Bonnes
* Written by Uwe Bonnes (bon@elektron.ikp.physik.tu-darmstadt.de) * Written by 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
@ -35,6 +35,7 @@ enum bmp_cl_mode {
BMP_MODE_FLASH_READ, BMP_MODE_FLASH_READ,
BMP_MODE_FLASH_VERIFY, BMP_MODE_FLASH_VERIFY,
BMP_MODE_SWJ_TEST, BMP_MODE_SWJ_TEST,
BMP_MODE_MONITOR,
}; };
typedef struct BMP_CL_OPTIONS_s { typedef struct BMP_CL_OPTIONS_s {
@ -48,9 +49,11 @@ typedef struct BMP_CL_OPTIONS_s {
char *opt_flash_file; char *opt_flash_file;
char *opt_device; char *opt_device;
char *opt_serial; char *opt_serial;
uint32_t opt_targetid;
char *opt_ident_string; char *opt_ident_string;
int opt_position; int opt_position;
char *opt_cable; char *opt_cable;
char *opt_monitor;
int opt_debuglevel; int opt_debuglevel;
int opt_target_dev; int opt_target_dev;
uint32_t opt_flash_start; uint32_t opt_flash_start;

View File

@ -190,7 +190,8 @@ int platform_buffer_read(uint8_t *data, int maxsize)
c = data; c = data;
tv.tv_sec = 0; tv.tv_sec = 0;
tv.tv_usec = 1000 * cortexm_wait_timeout; tv.tv_sec = cortexm_wait_timeout / 1000 ;
tv.tv_usec = 1000 * (cortexm_wait_timeout % 1000);
/* Look for start of response */ /* Look for start of response */
do { do {

View File

@ -322,7 +322,7 @@ uint64_t adiv5_ap_read_pidr(ADIv5_AP_t *ap, uint32_t addr)
* DBGMCU_CR not set. * DBGMCU_CR not set.
* *
* Keep a copy of DEMCR at startup to restore with exit, to * Keep a copy of DEMCR at startup to restore with exit, to
* not interrupt tracing initialed by the CPU. * not interrupt tracing initiated by the CPU.
*/ */
static bool cortexm_prepare(ADIv5_AP_t *ap) static bool cortexm_prepare(ADIv5_AP_t *ap)
{ {
@ -339,6 +339,8 @@ static bool cortexm_prepare(ADIv5_AP_t *ap)
while (true) { while (true) {
adiv5_mem_write(ap, CORTEXM_DHCSR, &dhcsr_ctl, sizeof(dhcsr_ctl)); adiv5_mem_write(ap, CORTEXM_DHCSR, &dhcsr_ctl, sizeof(dhcsr_ctl));
dhcsr = adiv5_mem_read32(ap, CORTEXM_DHCSR); dhcsr = adiv5_mem_read32(ap, CORTEXM_DHCSR);
/* ADIV5_DP_CTRLSTAT_READOK is always set e.g. on STM32F7 even so
CORTEXM_DHCS reads nonsense*/
/* On a sleeping STM32F7, invalid DHCSR reads with e.g. 0xffffffff and /* On a sleeping STM32F7, invalid DHCSR reads with e.g. 0xffffffff and
* 0x0xA05F0000 may happen. * 0x0xA05F0000 may happen.
* M23/33 will have S_SDE set when debug is allowed * M23/33 will have S_SDE set when debug is allowed
@ -416,6 +418,8 @@ static void adiv5_component_probe(ADIv5_AP_t *ap, uint32_t addr, int recursion,
return; /* Halting failed! */ return; /* Halting failed! */
/* CPU now halted, read cidr again. */ /* CPU now halted, read cidr again. */
cidr = adiv5_ap_read_id(ap, addr + CIDR0_OFFSET); cidr = adiv5_ap_read_id(ap, addr + CIDR0_OFFSET);
if ((cidr & ~CID_CLASS_MASK) != CID_PREAMBLE)
return;
} }
} }
#if defined(ENABLE_DEBUG) #if defined(ENABLE_DEBUG)
@ -604,9 +608,9 @@ ADIv5_AP_t *adiv5_new_ap(ADIv5_DP_t *dp, uint8_t apsel)
#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
" CSW=%08"PRIx32"\n", apsel, ap->idr, cfg, ap->base, ap->csw); " CSW=%08"PRIx32, apsel, ap->idr, cfg, ap->base, ap->csw);
DEBUG_INFO("AP#0 IDR = 0x%08" PRIx32 " (AHB-AP var%x rev%x)\n", DEBUG_INFO(" (AHB-AP var%x rev%x)\n",
ap->idr, (ap->idr >> 4) & 0xf, ap->idr >> 28); (ap->idr >> 4) & 0xf, ap->idr >> 28);
#endif #endif
adiv5_ap_ref(ap); adiv5_ap_ref(ap);
return ap; return ap;

View File

@ -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) 2020- 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
@ -33,10 +34,25 @@
#define SWDP_ACK_WAIT 0x02 #define SWDP_ACK_WAIT 0x02
#define SWDP_ACK_FAULT 0x04 #define SWDP_ACK_FAULT 0x04
int adiv5_swdp_scan(void) static unsigned int make_packet_request(uint8_t RnW, uint16_t addr)
{
bool APnDP = addr & ADIV5_APnDP;
addr &= 0xff;
unsigned int request = 0x81; /* Park and Startbit */
if(APnDP) request ^= 0x22;
if(RnW) request ^= 0x24;
addr &= 0xC;
request |= (addr << 1) & 0x18;
if((addr == 4) || (addr == 8))
request ^= 0x20;
return request;
}
int adiv5_swdp_scan(uint32_t targetid)
{ {
uint32_t ack; uint32_t ack;
(void) targetid;
target_list_free(); target_list_free();
#if PC_HOSTED == 1 #if PC_HOSTED == 1
if (platform_swdptap_init()) { if (platform_swdptap_init()) {
@ -60,7 +76,8 @@ int adiv5_swdp_scan(void)
/* Read the SW-DP IDCODE register to syncronise */ /* Read the SW-DP IDCODE register to syncronise */
/* This could be done with adiv_swdp_low_access(), but this doesn't /* This could be done with adiv_swdp_low_access(), but this doesn't
* allow the ack to be checked here. */ * allow the ack to be checked here. */
swd_proc.swdptap_seq_out(0xA5, 8); uint32_t request = make_packet_request(ADIV5_LOW_READ, ADIV5_DP_IDCODE);
swd_proc.swdptap_seq_out(request, 8);
ack = swd_proc.swdptap_seq_in(3); ack = swd_proc.swdptap_seq_in(3);
uint32_t idcode; uint32_t idcode;
if((ack != SWDP_ACK_OK) || swd_proc.swdptap_seq_in_parity(&idcode, 32)) { if((ack != SWDP_ACK_OK) || swd_proc.swdptap_seq_in_parity(&idcode, 32)) {
@ -122,22 +139,12 @@ uint32_t firmware_swdp_read(ADIv5_DP_t *dp, uint16_t addr)
uint32_t firmware_swdp_low_access(ADIv5_DP_t *dp, uint8_t RnW, uint32_t firmware_swdp_low_access(ADIv5_DP_t *dp, uint8_t RnW,
uint16_t addr, uint32_t value) uint16_t addr, uint32_t value)
{ {
bool APnDP = addr & ADIV5_APnDP; uint32_t request = make_packet_request(RnW, addr);
addr &= 0xff;
uint32_t request = 0x81;
uint32_t response = 0; uint32_t response = 0;
uint32_t ack; uint32_t ack;
platform_timeout timeout; platform_timeout timeout;
if(APnDP && dp->fault) return 0; if((addr & ADIV5_APnDP) && dp->fault) return 0;
if(APnDP) request ^= 0x22;
if(RnW) request ^= 0x24;
addr &= 0xC;
request |= (addr << 1) & 0x18;
if((addr == 4) || (addr == 8))
request ^= 0x20;
platform_timeout_set(&timeout, 2000); platform_timeout_set(&timeout, 2000);
do { do {

View File

@ -458,6 +458,8 @@ bool cortexm_probe(ADIv5_AP_t *ap)
PROBE(kinetis_probe); /* Older K-series */ PROBE(kinetis_probe); /* Older K-series */
} else if (ap->ap_partno == 0x4cb) { /* Cortex-M23 ROM */ } else if (ap->ap_partno == 0x4cb) { /* Cortex-M23 ROM */
PROBE(gd32f1_probe); /* GD32E23x uses GD32F1 peripherals */ PROBE(gd32f1_probe); /* GD32E23x uses GD32F1 peripherals */
} else if (ap->ap_partno == 0x4c0) { /* Cortex-M0+ ROM */
PROBE(lpc11xx_probe); /* some of the LPC8xx series, like LPC802 */
} }
/* Info on PIDR of these parts wanted! */ /* Info on PIDR of these parts wanted! */
PROBE(sam3x_probe); PROBE(sam3x_probe);

View File

@ -326,6 +326,13 @@ bool kinetis_probe(target *t)
kl_gen_add_flash(t, 0x00000000, 0x00040000, 0x800, K64_WRITE_LEN); /* P-Flash, 256 KB, 2 KB Sectors */ kl_gen_add_flash(t, 0x00000000, 0x00040000, 0x800, K64_WRITE_LEN); /* P-Flash, 256 KB, 2 KB Sectors */
kl_gen_add_flash(t, 0x10000000, 0x00008000, 0x800, K64_WRITE_LEN); /* FlexNVM, 32 KB, 2 KB Sectors */ kl_gen_add_flash(t, 0x10000000, 0x00008000, 0x800, K64_WRITE_LEN); /* FlexNVM, 32 KB, 2 KB Sectors */
break; break;
case 0x148: /* S32K148 */
t->driver = "S32K148";
target_add_ram(t, 0x1FFE0000, 0x20000); /* SRAM_L, 128 KB */
target_add_ram(t, 0x20000000, 0x1f000); /* SRAM_H, 124 KB */
kl_gen_add_flash(t, 0x00000000, 0x00180000, 0x1000, K64_WRITE_LEN); /* P-Flash, 1536 KB, 4 KB Sectors */
kl_gen_add_flash(t, 0x10000000, 0x80000, 0x1000, K64_WRITE_LEN); /* FlexNVM, 512 KB, 4 KB Sectors */
break;
default: default:
return false; return false;
} }

View File

@ -29,8 +29,8 @@
#define MIN_RAM_SIZE 1024 #define MIN_RAM_SIZE 1024
#define RAM_USAGE_FOR_IAP_ROUTINES 32 /* IAP routines use 32 bytes at top of ram */ #define RAM_USAGE_FOR_IAP_ROUTINES 32 /* IAP routines use 32 bytes at top of ram */
#define IAP_ENTRY_MOST 0x1fff1ff1 /* all except LPC84x */ #define IAP_ENTRY_MOST 0x1fff1ff1 /* all except LPC802, LPC804 & LPC84x */
#define IAP_ENTRY_84x 0x0f001ff1 #define IAP_ENTRY_84x 0x0f001ff1 /* LPC802, LPC804 & LPC84x */
#define IAP_RAM_BASE 0x10000000 #define IAP_RAM_BASE 0x10000000
#define LPC11XX_DEVICE_ID 0x400483F4 #define LPC11XX_DEVICE_ID 0x400483F4
@ -142,6 +142,25 @@ lpc11xx_probe(target *t)
} }
idcode = target_mem_read32(t, LPC8XX_DEVICE_ID); idcode = target_mem_read32(t, LPC8XX_DEVICE_ID);
switch (idcode) { switch (idcode) {
case 0x00008021: /* 802M001JDH20 */
case 0x00008022: /* 802M011JDH20 */
case 0x00008023: /* 802M001JDH16 */
case 0x00008024: /* 802M001JHI33 */
t->driver = "LPC802";
target_add_ram(t, 0x10000000, 0x800);
lpc11xx_add_flash(t, 0x00000000, 0x4000, 0x400, IAP_ENTRY_84x);
target_add_commands(t, lpc11xx_cmd_list, "LPC802");
return true;
case 0x00008040: /* 804M101JBD64 */
case 0x00008041: /* 804M101JDH20 */
case 0x00008042: /* 804M101JDH24 */
case 0x00008043: /* 804M111JDH24 */
case 0x00008044: /* 804M101JHI33 */
t->driver = "LPC804";
target_add_ram(t, 0x10000000, 0x1000);
lpc11xx_add_flash(t, 0x00000000, 0x8000, 0x400, IAP_ENTRY_84x);
target_add_commands(t, lpc11xx_cmd_list, "LPC804");
return true;
case 0x00008100: /* LPC810M021FN8 */ case 0x00008100: /* LPC810M021FN8 */
case 0x00008110: /* LPC811M001JDH16 */ case 0x00008110: /* LPC811M001JDH16 */
case 0x00008120: /* LPC812M101JDH16 */ case 0x00008120: /* LPC812M101JDH16 */
@ -161,6 +180,18 @@ lpc11xx_probe(target *t)
lpc11xx_add_flash(t, 0x00000000, 0x8000, 0x400, IAP_ENTRY_MOST); lpc11xx_add_flash(t, 0x00000000, 0x8000, 0x400, IAP_ENTRY_MOST);
target_add_commands(t, lpc11xx_cmd_list, "LPC82x"); target_add_commands(t, lpc11xx_cmd_list, "LPC82x");
return true; return true;
case 0x00008322: /* LPC832M101FDH20 */
t->driver = "LPC832";
target_add_ram(t, 0x10000000, 0x1000);
lpc11xx_add_flash(t, 0x00000000, 0x4000, 0x400, IAP_ENTRY_MOST);
target_add_commands(t, lpc11xx_cmd_list, "LPC832");
return true;
case 0x00008341: /* LPC8341201FHI33 */
t->driver = "LPC834";
target_add_ram(t, 0x10000000, 0x1000);
lpc11xx_add_flash(t, 0x00000000, 0x8000, 0x400, IAP_ENTRY_MOST);
target_add_commands(t, lpc11xx_cmd_list, "LPC834");
return true;
case 0x00008441: case 0x00008441:
case 0x00008442: case 0x00008442:
case 0x00008443: /* UM11029 Rev.1.4 list 8442 */ case 0x00008443: /* UM11029 Rev.1.4 list 8442 */

View File

@ -25,6 +25,13 @@
* Reference manual - STM32H7x3 advanced ARM®-based 32-bit MCUs Rev.3 * Reference manual - STM32H7x3 advanced ARM®-based 32-bit MCUs Rev.3
*/ */
/*
* While the ST document (RM 0433) claims that the stm32h750 only has 1 bank
* with 1 sector (128k) of user main memory flash (pages 151-152), we were able
* to write and successfully verify into other regions in bank 1 and also into
* bank 2 (0x0810 0000 as indicated for the other chips).
*/
#include "general.h" #include "general.h"
#include "target.h" #include "target.h"
#include "target_internal.h" #include "target_internal.h"
@ -199,13 +206,14 @@ static bool stm32h7_attach(target *t)
target_mem_map_free(t); target_mem_map_free(t);
/* Add RAM to memory map */ /* Add RAM to memory map */
/* Table 7. Memory map and default device memory area attributes RM 0433, pg 130 */
target_add_ram(t, 0x00000000, 0x10000); /* ITCM Ram, 64 k */ target_add_ram(t, 0x00000000, 0x10000); /* ITCM Ram, 64 k */
target_add_ram(t, 0x20000000, 0x20000); /* DTCM Ram, 128 k */ target_add_ram(t, 0x20000000, 0x20000); /* DTCM Ram, 128 k */
target_add_ram(t, 0x24000000, 0x80000); /* AXI Ram, 512 k */ target_add_ram(t, 0x24000000, 0x80000); /* AXI Ram, 512 k */
target_add_ram(t, 0x30000000, 0x20000); /* AHB SRAM1, 128 k */ target_add_ram(t, 0x30000000, 0x20000); /* AHB SRAM1, 128 k */
target_add_ram(t, 0x32000000, 0x20000); /* AHB SRAM2, 128 k */ target_add_ram(t, 0x30020000, 0x20000); /* AHB SRAM2, 128 k */
target_add_ram(t, 0x34000000, 0x08000); /* AHB SRAM3, 32 k */ target_add_ram(t, 0x30040000, 0x08000); /* AHB SRAM3, 32 k */
target_add_ram(t, 0x38000000, 0x01000); /* AHB SRAM4, 32 k */ target_add_ram(t, 0x38000000, 0x10000); /* AHB SRAM4, 64 k */
/* Add the flash to memory map. */ /* Add the flash to memory map. */
stm32h7_add_flash(t, 0x8000000, 0x100000, FLASH_SECTOR_SIZE); stm32h7_add_flash(t, 0x8000000, 0x100000, FLASH_SECTOR_SIZE);

View File

@ -69,13 +69,13 @@ target *target_new(void)
return t; return t;
} }
bool target_foreach(void (*cb)(int, target *t, void *context), void *context) int target_foreach(void (*cb)(int, target *t, void *context), void *context)
{ {
int i = 1; int i = 1;
target *t = target_list; target *t = target_list;
for (; t; t = t->next, i++) for (; t; t = t->next, i++)
cb(i, t, context); cb(i, t, context);
return target_list != NULL; return i;
} }
void target_mem_map_free(target *t) void target_mem_map_free(target *t)
@ -100,7 +100,7 @@ void target_list_free(void)
while(target_list) { while(target_list) {
target *t = target_list->next; target *t = target_list->next;
if (target_list->tc) if (target_list->tc && target_list->tc->destroy_callback)
target_list->tc->destroy_callback(target_list->tc, target_list); target_list->tc->destroy_callback(target_list->tc, target_list);
if (target_list->priv) if (target_list->priv)
target_list->priv_free(target_list->priv); target_list->priv_free(target_list->priv);