Merge commit 'a65ce77466077b4259d99232d6f3c168b476ce79' into sam-update

This commit is contained in:
Jason Kotzin 2022-08-01 20:05:36 -07:00
commit 4b4d0fcfcf
18 changed files with 176 additions and 76 deletions

View File

@ -4,10 +4,39 @@ sudo: required
before_install:
- sudo add-apt-repository -y ppa:team-gcc-arm-embedded/ppa
- sudo apt-get update -qq
- sudo apt-get install -y build-essential libftdi-dev gcc-arm-embedded
- pip install --user intelhex
- gpg --recv-keys 3CEA9B8868BC3852618EB5B4707F91A424F006F5
- wget http://www.intra2net.com/en/developer/libftdi/download/libftdi1-1.2.tar.bz2
- wget http://www.intra2net.com/en/developer/libftdi/download/libftdi1-1.2.tar.bz2.sig
- gpg --trust-model always --verify libftdi1-1.2.tar.bz2.sig
- tar -xjf libftdi1-1.2.tar.bz2
- sudo apt-get install -y build-essential libboost-all-dev gcc-arm-embedded libusb-1.0-0-dev
install: true
install:
- cd libftdi1-1.2
- if [ "$TRAVIS_OS_NAME" = "linux" ];
then
sudo apt-get update -qq;
if [ "$ARCH" = "x86_64" ];
then
sudo apt-get install -qq libusb-1.0-0-dev;
elif [ "$ARCH" = "i386" ];
then
sudo apt-get install -qq gcc-multilib libusb-1.0-0-dev:i386 pkg-config:i386;
export CFLAGS="-m32";
fi
fi
- if [ "$TRAVIS_OS_NAME" = "osx" ];
then
brew update;
brew install libusb;
fi
- mkdir build
- cd build
- cmake ../
- make
- sudo make install
- cd ../../
script:
- make -C libopencm3 lib

View File

@ -0,0 +1,7 @@
# Black Magic Probe
# there are two connections, one for GDB and one for UART debugging
# copy this to /etc/udev/rules.d/99-blackmagic.rules
SUBSYSTEM=="tty", ACTION=="add", ATTRS{interface}=="Black Magic GDB Server", SYMLINK+="ttyBmpGdb"
SUBSYSTEM=="tty", ACTION=="add", ATTRS{interface}=="Black Magic UART Port", SYMLINK+="ttyBmpTarg"
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="1d50", ATTR{idProduct}=="6017", MODE="0666"
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="1d50", ATTR{idProduct}=="6018", MODE="0666"

View File

@ -43,12 +43,6 @@ struct command_s {
const char *help;
};
enum assert_srst_t{
ASSERT_NEVER = 0,
ASSERT_UNTIL_SCAN,
ASSERT_UNTIL_ATTACH
};
static bool cmd_version(void);
static bool cmd_serial(void);
static bool cmd_help(target *t);
@ -57,8 +51,8 @@ static bool cmd_jtag_scan(target *t, int argc, char **argv);
static bool cmd_swdp_scan(void);
static bool cmd_targets(void);
static bool cmd_morse(void);
static bool cmd_assert_srst(target *t, int argc, const char **argv);
static bool cmd_halt_timeout(target *t, int argc, const char **argv);
static bool cmd_connect_srst(target *t, int argc, const char **argv);
static bool cmd_hard_srst(void);
#ifdef PLATFORM_HAS_POWER_SWITCH
static bool cmd_target_power(target *t, int argc, const char **argv);
@ -87,8 +81,8 @@ const struct command_s cmd_list[] = {
{"swdp_scan", (cmd_handler)cmd_swdp_scan, "Scan SW-DP for devices" },
{"targets", (cmd_handler)cmd_targets, "Display list of available targets" },
{"morse", (cmd_handler)cmd_morse, "Display morse error message" },
{"assert_srst", (cmd_handler)cmd_assert_srst, "Assert SRST until:(never(default)| scan | attach)" },
{"halt_timeout", (cmd_handler)cmd_halt_timeout, "Timeout (ms) to wait until Cortex-M is halted: (Default 2000)" },
{"connect_srst", (cmd_handler)cmd_connect_srst, "Configure connect under SRST: (enable|disable)" },
{"hard_srst", (cmd_handler)cmd_hard_srst, "Force a pulse on the hard SRST line - disconnects target" },
#ifdef PLATFORM_HAS_POWER_SWITCH
{"tpwr", (cmd_handler)cmd_target_power, "Supplies power to the target: (enable|disable)"},
@ -109,7 +103,7 @@ const struct command_s cmd_list[] = {
{NULL, NULL, NULL}
};
static enum assert_srst_t assert_srst;
static bool connect_assert_srst;
#ifdef PLATFORM_HAS_DEBUG
bool debug_bmp;
#endif
@ -186,10 +180,8 @@ static bool cmd_jtag_scan(target *t, int argc, char **argv)
irlens[argc-1] = 0;
}
if(assert_srst != ASSERT_NEVER)
platform_srst_set_val(true);
if(assert_srst == ASSERT_UNTIL_SCAN)
platform_srst_set_val(false);
if(connect_assert_srst)
platform_srst_set_val(true); /* will be deasserted after attach */
int devs = -1;
volatile struct exception e;
@ -219,10 +211,8 @@ bool cmd_swdp_scan(void)
{
gdb_outf("Target voltage: %s\n", platform_target_voltage());
if(assert_srst != ASSERT_NEVER)
platform_srst_set_val(true);
if(assert_srst == ASSERT_UNTIL_SCAN)
platform_srst_set_val(false);
if(connect_assert_srst)
platform_srst_set_val(true); /* will be deasserted after attach */
int devs = -1;
volatile struct exception e;
@ -275,20 +265,14 @@ bool cmd_morse(void)
return true;
}
static bool cmd_assert_srst(target *t, int argc, const char **argv)
static bool cmd_connect_srst(target *t, int argc, const char **argv)
{
(void)t;
if (argc > 1) {
if (!strcmp(argv[1], "attach"))
assert_srst = ASSERT_UNTIL_ATTACH;
else if (!strcmp(argv[1], "scan"))
assert_srst = ASSERT_UNTIL_SCAN;
if (argc == 1)
gdb_outf("Assert SRST during connect: %s\n",
connect_assert_srst ? "enabled" : "disabled");
else
assert_srst = ASSERT_NEVER;
}
gdb_outf("Assert SRST %s\n",
(assert_srst == ASSERT_UNTIL_ATTACH) ? "until attach" :
(assert_srst == ASSERT_UNTIL_SCAN) ? "until scan" : "never");
connect_assert_srst = !strcmp(argv[1], "enable");
return true;
}

View File

@ -29,6 +29,7 @@
#include <stdio.h>
#include <stddef.h>
#include <inttypes.h>
#include <sys/types.h>
#include "platform.h"
#include "platform_support.h"
@ -44,5 +45,15 @@
#undef MAX
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#ifdef _WIN32
# ifdef _WIN64
# define PRI_SIZET PRIu64
# else
# define PRI_SIZET PRIu32
# endif
#else
# define PRI_SIZET "zu"
#endif
#endif

View File

@ -1,4 +1,10 @@
SYS = $(shell $(CC) -dumpmachine)
CFLAGS += -DLIBFTDI
LDFLAGS += -lftdi -lusb
LDFLAGS += -lftdi1
ifneq (, $(findstring mingw, $(SYS)))
LDFLAGS += -lusb-1.0 -lws2_32
CFLAGS += -Wno-cast-function-type
else ifneq (, $(findstring cygwin, $(SYS)))
LDFLAGS += -lusb-1.0 -lws2_32
endif
SRC += timing.c \

View File

@ -0,0 +1,14 @@
Compiling on windows
You can crosscompile blackmagic for windows with mingw or on windows
with cygwin. For compilation, headers for libftdi1 and libusb-1.0 are
needed. For running, libftdi1.dll and libusb-1.0.dll are needed and
the executable must be able to find them. Mingw on cygwin does not provide
a libftdi package yet.
To prepare libusb access to the ftdi device, run zadig https://zadig.akeo.ie/.
Choose WinUSB(libusb-1.0) for the BMP Ftdi device.
Running cygwin/blackmagic in a cygwin console, the program does not react
on ^C. In another console, run "ps ax" to find the WINPID of the process
and then "taskkill /F ?PID (WINPID)".

View File

@ -22,19 +22,19 @@
* Serial Debugging protocol is implemented. This implementation for Linux
* uses a TCP server on port 2000.
*/
#include <stdio.h>
#ifndef WIN32
#if defined(_WIN32) || defined(__CYGWIN__)
# include <winsock2.h>
# include <windows.h>
# include <ws2tcpip.h>
#else
# include <sys/socket.h>
# include <netinet/in.h>
# include <netinet/tcp.h>
# include <sys/select.h>
#else
# include <winsock2.h>
# include <windows.h>
# include <ws2tcpip.h>
#endif
#include <stdio.h>
#include <assert.h>
#include "general.h"
@ -44,7 +44,7 @@ static int gdb_if_serv, gdb_if_conn;
int gdb_if_init(void)
{
#ifdef WIN32
#if defined(_WIN32) || defined(__CYGWIN__)
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
#endif
@ -93,7 +93,11 @@ unsigned char gdb_if_getchar(void)
unsigned char gdb_if_getchar_to(int timeout)
{
fd_set fds;
# if defined(__CYGWIN__)
TIMEVAL tv;
#else
struct timeval tv;
#endif
if(gdb_if_conn == -1) return -1;
@ -111,7 +115,11 @@ unsigned char gdb_if_getchar_to(int timeout)
void gdb_if_putchar(unsigned char c, int flush)
{
#if defined(__WIN32__) || defined(__CYGWIN__)
static char buf[2048];
#else
static uint8_t buf[2048];
#endif
static int bufsize = 0;
if (gdb_if_conn > 0) {
buf[bufsize++] = c;

View File

@ -30,8 +30,6 @@
#include <assert.h>
#include <ftdi.h>
#include "general.h"
#include "jtagtap.h"

View File

@ -286,7 +286,7 @@ int platform_buffer_read(uint8_t *data, int size)
return size;
}
#ifdef WIN32
#if defined(_WIN32) && !defined(__MINGW32__)
#warning "This vasprintf() is dubious!"
int vasprintf(char **strp, const char *fmt, va_list ap)
{

View File

@ -21,11 +21,11 @@
#ifndef __PLATFORM_H
#define __PLATFORM_H
#include <ftdi.h>
#include <libftdi1/ftdi.h>
#include "timing.h"
#ifndef WIN32
#ifndef _WIN32
# include <alloca.h>
#else
# ifndef alloca

View File

@ -24,7 +24,6 @@
#include <stdio.h>
#include <assert.h>
#include <ftdi.h>
#include "general.h"
#include "swdptap.h"
@ -186,7 +185,7 @@ uint32_t swdptap_seq_in(int ticks)
void swdptap_seq_out(uint32_t MS, int ticks)
{
uint8_t cmd[15];
uint index = 0;
unsigned int index = 0;
swdptap_turnaround(0);
while (ticks) {
cmd[index++] = MPSSE_TMS_SHIFT;
@ -209,7 +208,7 @@ void swdptap_seq_out_parity(uint32_t MS, int ticks)
uint8_t parity = 0;
int steps = ticks;
uint8_t cmd[18];
uint index = 0;
unsigned int index = 0;
uint32_t data = MS;
swdptap_turnaround(0);
while (steps) {

View File

@ -31,6 +31,7 @@
#include "target.h"
#include "target_internal.h"
#include "cortexm.h"
#include "platform.h"
#include <unistd.h>
@ -239,17 +240,10 @@ static void cortexm_priv_free(void *priv)
static bool cortexm_forced_halt(target *t)
{
uint32_t start_time = platform_time_ms();
target_halt_request(t);
platform_srst_set_val(false);
/* Wait until SRST is released.*/
while (platform_time_ms() < start_time + 2000) {
if (!platform_srst_get_val())
break;
}
if (platform_srst_get_val())
return false;
uint32_t dhcsr = 0;
start_time = platform_time_ms();
uint32_t start_time = platform_time_ms();
/* Try hard to halt the target. STM32F7 in WFI
needs multiple writes!*/
while (platform_time_ms() < start_time + cortexm_wait_timeout) {
@ -323,7 +317,11 @@ bool cortexm_probe(ADIv5_AP_t *ap, bool forced)
target_check_error(t);
}
if (forced)
/* Only force halt if read ROM Table failed and there is no DPv2
* targetid!
* So long, only STM32L0 is expected to enter this cause.
*/
if (forced && !ap->dp->targetid)
if (!cortexm_forced_halt(t))
return false;
@ -536,6 +534,11 @@ static void cortexm_reset(target *t)
/* Reset DFSR flags */
target_mem_write32(t, CORTEXM_DFSR, CORTEXM_DFSR_RESETALL);
/* 1ms delay to ensure that things such as the stm32f1 HSI clock have started
* up fully.
*/
platform_delay(1);
}
static void cortexm_halt_request(target *t)

View File

@ -74,7 +74,7 @@ lpc11xx_probe(target *t)
case 0x1440102B: /* lpc1114 */
case 0x0A40902B:
case 0x1A40902B:
case 0x2058002B: /* lpc1115 */
case 0x00050080: /* lpc1115 and lpc1115L (not the XL version. See UM10398 Rev12.4 Chapter 3.1 ) */
case 0x1431102B: /* lpc11c22 */
case 0x1430102B: /* lpc11c24 */
case 0x095C802B: /* lpc11u12x/201 */
@ -130,6 +130,11 @@ lpc11xx_probe(target *t)
target_add_ram(t, 0x10000000, 0x2000);
lpc11xx_add_flash(t, 0x00000000, 0x20000, 0x1000);
return true;
case 0x00050080: /* lpc1115XL */
t->driver = "LPC1100XL";
target_add_ram(t, 0x10000000, 0x2000);
lpc11xx_add_flash(t, 0x00000000, 0x20000, 0x1000);
return true;
}
return false;

View File

@ -289,7 +289,7 @@ static int msp432_flash_write(struct target_flash *f, target_addr dest,
regs[1] = dest; // Flash address to be write to in R1
regs[2] = len; // Size of buffer to be flashed in R2
DEBUG("Writing 0x%04"PRIX32" bytes at 0x%08zX\n", dest, len);
DEBUG("Writing 0x%04" PRIX32 " bytes at 0x%08" PRI_SIZET "\n", dest, len);
/* Call ROM */
msp432_call_ROM(t, mf->FlashCtl_programMemory, regs);

View File

@ -202,8 +202,10 @@ static int stm32f1_flash_erase(struct target_flash *f,
/* Read FLASH_SR to poll for BSY bit */
while (target_mem_read32(t, FLASH_SR) & FLASH_SR_BSY)
if(target_check_error(t))
if(target_check_error(t)) {
DEBUG("stm32f1 flash erase: comm error\n");
return -1;
}
len -= f->blocksize;
addr += f->blocksize;
@ -211,8 +213,10 @@ static int stm32f1_flash_erase(struct target_flash *f,
/* Check for error */
sr = target_mem_read32(t, FLASH_SR);
if ((sr & SR_ERROR_MASK) || !(sr & SR_EOP))
if ((sr & SR_ERROR_MASK) || !(sr & SR_EOP)) {
DEBUG("stm32f1 flash erase error 0x%" PRIx32 "\n", sr);
return -1;
}
return 0;
}

View File

@ -183,9 +183,20 @@ char *stm32f4_get_chip_name(uint32_t idcode)
}
}
static void stm32f7_detach(target *t)
{
target_mem_write32(t, DBGMCU_CR, t->target_storage);
cortexm_detach(t);
}
bool stm32f4_probe(target *t)
{
uint32_t idcode = target_mem_read32(t, DBGMCU_IDCODE) & 0xFFF;
ADIv5_AP_t *ap = cortexm_ap(t);
uint32_t idcode;
idcode = (ap->dp->targetid >> 16) & 0xfff;
if (!idcode)
idcode = target_mem_read32(t, DBGMCU_IDCODE) & 0xFFF;
if (idcode == ID_STM32F20X) {
/* F405 revision A have a wrong IDCODE, use ARM_CPUID to make the
@ -199,8 +210,8 @@ bool stm32f4_probe(target *t)
case ID_STM32F74X: /* F74x RM0385 Rev.4 */
case ID_STM32F76X: /* F76x F77x RM0410 */
case ID_STM32F72X: /* F72x F73x RM0431 */
target_mem_write32(t, DBGMCU_CR, DBG_SLEEP);
/* fallthrough */
t->detach = stm32f7_detach;
/* fall through */
case ID_STM32F40X:
case ID_STM32F42X: /* 427/437 */
case ID_STM32F46X: /* 469/479 */
@ -280,6 +291,8 @@ static bool stm32f4_attach(target *t)
target_mem_map_free(t);
uint32_t flashsize = target_mem_read32(t, flashsize_base) & 0xffff;
if (is_f7) {
t->target_storage = target_mem_read32(t, DBGMCU_CR);
target_mem_write32(t, DBGMCU_CR, DBG_SLEEP);
target_add_ram(t, 0x00000000, 0x4000); /* 16 k ITCM Ram */
target_add_ram(t, 0x20000000, 0x20000); /* 128 k DTCM Ram */
target_add_ram(t, 0x20020000, 0x60000); /* 384 k Ram */

View File

@ -172,15 +172,39 @@ static void stm32h7_add_flash(target *t,
target_add_flash(t, f);
}
bool stm32h7_probe(target *t)
static bool stm32h7_attach(target *t)
{
uint32_t idcode = target_mem_read32(t, DBGMCU_IDCODE) & 0xFFF;
if (idcode == ID_STM32H74x) {
if (!cortexm_attach(t))
return false;
/* RM0433 Rev 4 is not really clear, what bits are needed.
* Set all possible relevant bits for now. */
uint32_t dbgmcu_cr = target_mem_read32(t, DBGMCU_CR);
t->target_storage = dbgmcu_cr;
target_mem_write32(t, DBGMCU_CR, DBGSLEEP_D1 | D1DBGCKEN);
/* If IWDG runs as HARDWARE watchdog (44.3.4) erase
* will be aborted by the Watchdog and erase fails!
* Setting IWDG_KR to 0xaaaa does not seem to help!*/
uint32_t optsr = target_mem_read32(t, FPEC1_BASE + FLASH_OPTSR);
if (!(optsr & FLASH_OPTSR_IWDG1_SW))
tc_printf(t, "Hardware IWDG running. Expect failure. Set IWDG1_SW!");
return true;
}
static void stm32h7_detach(target *t)
{
target_mem_write32(t, DBGMCU_CR, t->target_storage);
cortexm_detach(t);
}
bool stm32h7_probe(target *t)
{
ADIv5_AP_t *ap = cortexm_ap(t);
uint32_t idcode = (ap->dp->targetid >> 16) & 0xfff;
if (idcode == ID_STM32H74x) {
t->idcode = idcode;
t->driver = stm32h74_driver_str;
t->attach = stm32h7_attach;
t->detach = stm32h7_detach;
target_add_commands(t, stm32h7_cmd_list, stm32h74_driver_str);
target_add_ram(t, 0x00000000, 0x10000); /* ITCM Ram, 64 k */
target_add_ram(t, 0x20000000, 0x20000); /* DTCM Ram, 128 k */
@ -191,12 +215,6 @@ bool stm32h7_probe(target *t)
target_add_ram(t, 0x38000000, 0x01000); /* AHB SRAM4, 32 k */
stm32h7_add_flash(t, 0x8000000, 0x100000, FLASH_SECTOR_SIZE);
stm32h7_add_flash(t, 0x8100000, 0x100000, FLASH_SECTOR_SIZE);
/* If IWDG runs as HARDWARE watchdog (44.3.4) erase
* will be aborted by the Watchdog and erase fails!
* Setting IWDG_KR to 0xaaaa does not seem to help!*/
uint32_t optsr = target_mem_read32(t, FPEC1_BASE + FLASH_OPTSR);
if (!(optsr & FLASH_OPTSR_IWDG1_SW))
tc_printf(t, "Hardware IWDG running. Expect failure. Set IWDG1_SW!");
return true;
}
return false;

View File

@ -108,6 +108,7 @@ struct target_s {
/* target-defined options */
unsigned target_options;
uint32_t idcode;
uint32_t target_storage;
struct target_ram *ram;
struct target_flash *flash;