Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
f4ec9d9
bmp-v3: Begun fleshing out the platform definitions for the pinout
dragonmux Oct 31, 2025
20d6d7f
bmp-v3: Added pin definitions for all the most major moving pieces
dragonmux Oct 31, 2025
8a029ea
adiv5_swd: Fixed some issues in the copyright header
dragonmux Oct 31, 2025
1b31e62
bmp-v3: Started filling in interrupt setup and control macros
dragonmux Oct 31, 2025
8e9fc93
common/stm32: Defined the STM32U5 as a viable BMP platform target
dragonmux Oct 31, 2025
009390e
native: Fixed the copyright headers
dragonmux Nov 1, 2025
c830d2b
common: Enable various facilities for the STM32U5 series
dragonmux Nov 3, 2025
03d4170
bmp-v3: Roughly implemented the SWDIO drive mode switch macros
dragonmux Nov 3, 2025
8501650
bmp-v3: Added configuration for the SWO pin
dragonmux Nov 3, 2025
e2d40ba
bmp-v3: Defined the DMA setup for the SWO and AUX UART subsystems
dragonmux Nov 3, 2025
45834b8
common/aux_serial: Implemented support for sourcing data from two UAR…
dragonmux Nov 4, 2025
53dc4d0
bmp-v3: Added a linker script for the platform
dragonmux Nov 4, 2025
8818f0a
common/aux_serial: Built out DMA configuration for the STM32U5 as it'…
dragonmux Nov 10, 2025
1e6f639
ch32vx: Gate the read Flash size function properly on whether DEBUG_I…
dragonmux Nov 11, 2025
7fee604
common/swo_uart: Built out DMA configuration for the STM32U5 as it's …
dragonmux Nov 12, 2025
b76c4c1
common/swo_manchester: Handle the STM32U5 timer input multiplexing pr…
dragonmux Nov 17, 2025
fb16954
meson: Added the new BMPv3 platform to the build system, integrating …
dragonmux Nov 17, 2025
1c05f36
bmp-v3: Begun implementing the platform-specific functions
dragonmux Nov 17, 2025
8a1bb8e
native: Removed a duplicated include line
dragonmux Nov 18, 2025
230688f
native: Fixed up the copyright header
dragonmux Nov 18, 2025
52fd3e9
bmp-v3: Defined the first part of platform initialisation, bringing u…
dragonmux Nov 19, 2025
24cc5ba
stlinkv3: Removed a duplicated include line
dragonmux Nov 20, 2025
e1dcfcb
native: Added some `const` to the ADC code the updated locm3 allows
dragonmux Nov 20, 2025
3d1386d
bmp-v3: Implemented target voltage readout using the ADCs and tpwr se…
dragonmux Nov 20, 2025
ae5c46c
bmp-v3: Implemented bringup of the various core peripherals and clocking
dragonmux Nov 20, 2025
adce30b
bmp-v3: Implemented the boot request logic
dragonmux Nov 21, 2025
ef61f42
bmp-v3: Implemented handling for the hardware version info
dragonmux Nov 21, 2025
4e7d07f
bmp-v3: Fleshed out GPIO configuration and bringup
dragonmux Nov 21, 2025
0ec29d8
bmp-v3: Defined clocking for the platform
dragonmux Nov 21, 2025
a299468
bmp-v3: Built out the bootloader for the platform
dragonmux Nov 21, 2025
cb57e90
common: Built a new, more suitable bootloader backend for the STM32U5
dragonmux Nov 24, 2025
0b44a59
common: Enabled the STM32U5 in the core DFU bootloader
dragonmux Nov 24, 2025
e565e2a
common: Cleaned up the core DFU bootloader using the buffer_utils header
dragonmux Nov 27, 2025
538ac08
bmp-v3: Initialise the UART subsystem and configure the UART pins app…
dragonmux Dec 22, 2025
0471600
misc: Turn off a clang-analyzer-core lint that we cannot avoid due to…
dragonmux Dec 22, 2025
4733051
bmp-v3: Initialise the LED pins so we can see the GDB machinary state
dragonmux Dec 22, 2025
5e1e19b
common: Enable the USB DFU stub to properly reboot cores that are ARM…
dragonmux Dec 22, 2025
438b170
common/usb_serial: Cleanup to improve nomenclature consistency and re…
dragonmux Dec 23, 2025
588cc77
common/stm32/gdb_if: Upgraded the receive callback mechanism with pro…
dragonmux Dec 31, 2025
04219b6
common/stm32/gdb_if: Nomenclature fixes to make things easier to read…
dragonmux Dec 31, 2025
8aab082
common/usb_serial: Fixed some clang-tidy lints
dragonmux Dec 31, 2025
269e6f5
common/ctxlink/gdb_if: Upgraded the receive callback mechanism with p…
dragonmux Dec 31, 2025
7c8b463
common/usb_descriptors: Switch to a 125ms polling interval for state …
dragonmux Jan 2, 2026
d3eb144
bmp-v3: Implemented target power support
dragonmux Jan 2, 2026
d1a4137
bmp-v3: Refactor the GPIO init into its own function
dragonmux Jan 3, 2026
43a3479
bmp-v3: More GPIO initialisation work, making sure nRST is bought up …
dragonmux Jan 4, 2026
87a21da
native: Fixed up some nomenclature and warnings in the tpwr voltage r…
dragonmux Jan 4, 2026
3f03049
bmp-v3: Handle proper initialisation of the bus direction pins
dragonmux Jan 5, 2026
12896f4
bmp-v3: Defined the pin setup for the QSPI Flash memory interface to …
dragonmux Jan 6, 2026
523a19a
common/swdptap: Small tweak to where the read happens in the I/O cycl…
dragonmux Jan 6, 2026
1f2706c
common/aux_serial: Implemented more of the multi-UART logic for hooki…
dragonmux Jan 11, 2026
97223d9
common/aux_serial: Handle errors that can occur on the UARTs so DMA d…
dragonmux Jan 19, 2026
befce0b
common/aux_serial: More tweaks for the IRQ handling to make things sa…
dragonmux Jan 19, 2026
3ccc04d
common/aux_serial: Fixed an order of includes error that meant certai…
dragonmux Jan 26, 2026
13dd2bd
common/aux_serial: Impelemented the UART1 half of the switchable UART…
dragonmux Jan 26, 2026
6988739
common/aux_serial: Roughly implemented the UART2 half of the switchab…
dragonmux Jan 26, 2026
f918d4a
bmp-v3: Implemented platform support for UART RX/TX switching for the…
dragonmux Feb 4, 2026
8b54428
common/timing_stm32: Implemented handling for seeing which way around…
dragonmux Feb 4, 2026
de99e5d
bmp-v3: Implemented logic for enabling and disabling the secondary UA…
dragonmux Feb 17, 2026
1e1fc5f
github: Enabled BMPv3 in both the PR and build-and-upload flows
dragonmux Feb 23, 2026
5ffd749
f072/atomic: Implemented compare-exchange and fetch-add for 32-bit un…
dragonmux Feb 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .clang-tidy
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
Checks: 'bugprone-*,cert-*,clang-analyzer-*,misc-*,modernize-*,portability-*,performance-*,readability-*,-readability-magic-numbers,-readability-braces-around-statements,-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,-modernize-macro-to-enum,-bugprone-easily-swappable-parameters,-misc-include-cleaner,-misc-no-recursion,-misc-header-include-cycle'
Checks: 'bugprone-*,cert-*,clang-analyzer-*,misc-*,modernize-*,portability-*,performance-*,readability-*,-readability-magic-numbers,-readability-braces-around-statements,-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,-modernize-macro-to-enum,-bugprone-easily-swappable-parameters,-misc-include-cleaner,-misc-no-recursion,-misc-header-include-cycle,-clang-analyzer-core.FixedAddressDereference'
FormatStyle: 'none'
HeaderFilterRegex: '(src|upgrade)/.+'
#AnalyzeTemporaryDtors: false
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/build-and-upload.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ jobs:
- 'blackpill-f401ce'
- 'blackpill-f411ce'
- 'bluepill'
- 'bmp-v3'
- 'ctxlink'
- 'f072'
- 'f3'
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/build-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ jobs:
- 'blackpill-f401ce'
- 'blackpill-f411ce'
- 'bluepill'
- 'bmp-v3'
- 'ctxlink'
- 'f072'
- 'f3'
Expand Down
25 changes: 25 additions & 0 deletions cross-file/bmp-v3.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# This a cross-file for the Black Magic Probe v3, providing sane default options for it.

[binaries]
c = 'arm-none-eabi-gcc'
cpp = 'arm-none-eabi-g++'
ld = 'arm-none-eabi-gcc'
ar = 'arm-none-eabi-ar'
nm = 'arm-none-eabi-nm'
strip = 'arm-none-eabi-strip'
objcopy = 'arm-none-eabi-objcopy'
objdump = 'arm-none-eabi-objdump'
size = 'arm-none-eabi-size'

[host_machine]
system = 'bare-metal'
cpu_family = 'arm'
cpu = 'arm'
endian = 'little'

[project options]
probe = 'bmp-v3'
targets = 'cortexar,cortexm,riscv32,riscv64,apollo3,at32f4,ch32,ch32v,ch579,efm,gd32,hc32,lpc,mm32,nrf,nxp,puya,renesas,rp,sam,stm,ti,xilinx'
rtt_support = true
bmd_bootloader = true
enable_riscv_accel = true
1 change: 1 addition & 0 deletions meson_options.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ option(
'blackpill-f401ce',
'blackpill-f411ce',
'bluepill',
'bmp-v3',
'ctxlink',
'f072',
'f3',
Expand Down
1 change: 1 addition & 0 deletions src/include/buffer_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@

#include <stdint.h>
#include <stddef.h>
#include <string.h>

static inline void write_le2(uint8_t *const buffer, const size_t offset, const uint16_t value)
{
Expand Down
2 changes: 1 addition & 1 deletion src/include/gdb_if.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

#if CONFIG_BMDA == 0 && !defined(NO_LIBOPENCM3)
#include <libopencm3/usb/usbd.h>
void gdb_usb_out_cb(usbd_device *dev, uint8_t ep);
void gdb_usb_receive_callback(usbd_device *dev, uint8_t ep);
#endif

int gdb_if_init(void);
Expand Down
15 changes: 15 additions & 0 deletions src/include/platform_support.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,19 @@ uint8_t platform_spi_xfer(spi_bus_e bus, uint8_t value);
const char *platform_ident(void);
#endif

#ifdef PLATFORM_MULTI_UART
typedef enum uart_state {
UART_STATE_UNKNOWN,
UART_STATE_IDLE,
UART_STATE_LOST,
} uart_state_e;

void platform_enable_uart2(void);
void platform_disable_uart2(void);
bool platform_is_uart2_enabled(void);
void platform_switch_dir_uart2(void);
void platform_uart2_state_change(uint32_t state);
uart_state_e platform_uart2_state(void);
#endif

#endif /* INCLUDE_PLATFORM_SUPPORT_H */
42 changes: 42 additions & 0 deletions src/platforms/bmp-v3/bmp-v3.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* This file is part of the libopenstm32 project.
*
* Copyright (C) 2010 Thomas Otto <tommi@viadmin.org>
* Copyright (C) 2024-2025 1BitSquared <info@1bitsquared.com>
* Modified by Rachel Mant <git@dragonmux.network>
*
* 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 = 2M
/*
* We actually have 786KiB available, but we want to be in the main 512KiB area
* that optionally runs ECC. We're not using ECC, however this is one large 8x64KiB
* block that is contiguous, marked NS, and behaves the way we expect it to.
*
* NB: SRAM on this part is mapped as:
* SRAM1: 0x20000000 - 0x20030000
* SRAM2: 0x20030000 - 0x20080000
* SRAM3: 0x20080000 - 0x200c0000
*
* SRAM2 is erased when the system is reset, all other SRAMs retain their contents.
*/
ram (rwx) : ORIGIN = 0x20080000, LENGTH = 512K
}

/* Include the platform common linker script. */
INCLUDE ../common/blackmagic.ld
154 changes: 154 additions & 0 deletions src/platforms/bmp-v3/bootloader.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2025 1BitSquared <info@1bitsquared.com>
* Written by Rachel Mant <git@dragonmux.network>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include <string.h>
#include <libopencm3/cm3/systick.h>
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/crs.h>
#include <libopencm3/stm32/pwr.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/cm3/scb.h>

#include "usbdfu.h"
#include "platform.h"
#include "rcc_clocking.h"

uintptr_t app_address = 0x08004000U;
uint8_t dfu_activity_counter = 0U;

void dfu_detach(void)
{
/* USB device must detach, we just reset... */
scb_reset_system();
}

int main(void)
{
/* Check the force bootloader pin */
rcc_periph_clock_enable(RCC_GPIOA);
if (gpio_get(BNT_BOOT_REQ_PORT, BTN_BOOT_REQ_PIN))
dfu_jump_app_if_valid();

dfu_protect(false);

/* Bring up the clocks for operation, setting SysTick to 160MHz / 8 (20MHz) */
rcc_clock_setup_pll(&rcc_hsi_config);
rcc_clock_setup_hsi48();
crs_autotrim_usb_enable();
rcc_set_iclk_clksel(RCC_CCIPR1_ICLKSEL_HSI48);
rcc_set_peripheral_clk_sel(SYS_TICK_BASE, RCC_CCIPR1_SYSTICKSEL_HCLK_DIV8);
systick_set_clocksource(STK_CSR_CLKSOURCE_EXT);
/* Reload every 100ms */
systick_set_reload(2000000U);
/* Power up USB controller */
pwr_enable_vddusb();

/* Configure USB related clocks and pins. */
rcc_periph_clock_enable(RCC_GPIOB);
rcc_periph_clock_enable(RCC_OTGFS);

/* Finish setting up and enabling SysTick */
systick_interrupt_enable();
systick_counter_enable();

/* Configure the LED pins. */
gpio_set_output_options(LED0_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, LED0_PIN);
gpio_mode_setup(LED0_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED0_PIN);
gpio_set_output_options(LED1_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, LED1_PIN);
gpio_mode_setup(LED1_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED1_PIN);
gpio_set_output_options(LED2_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, LED2_PIN);
gpio_mode_setup(LED2_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED2_PIN);
gpio_set_output_options(LED3_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, LED3_PIN);
gpio_mode_setup(LED3_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED3_PIN);

dfu_init(&otgfs_usb_driver);

dfu_main();
}

void dfu_event(void)
{
/* If the counter was at 0 before we should reset LED status. */
if (dfu_activity_counter == 0) {
gpio_clear(LED0_PORT, LED0_PIN);
gpio_clear(LED1_PORT, LED1_PIN);
gpio_clear(LED2_PORT, LED2_PIN);
gpio_clear(LED3_PORT, LED3_PIN);
}

/* Prevent the sys_tick_handler from blinking leds for a bit. */
dfu_activity_counter = 10;

/* Toggle the DFU activity LED. */
gpio_toggle(LED1_PORT, LED1_PIN);
}

void sys_tick_handler(void)
{
static int count = 0;
static bool reset = true;

/* Run the LED show only if there is no DFU activity. */
if (dfu_activity_counter != 0) {
--dfu_activity_counter;
reset = true;
} else {
if (reset) {
gpio_clear(LED0_PORT, LED0_PIN);
gpio_clear(LED1_PORT, LED1_PIN);
gpio_clear(LED2_PORT, LED2_PIN);
gpio_clear(LED3_PORT, LED3_PIN);
count = 0;
reset = false;
}

switch (count) {
case 0:
gpio_toggle(LED3_PORT, LED3_PIN); /* LED3 on/off */
break;
case 1:
gpio_toggle(LED2_PORT, LED2_PIN); /* LED2 on/off */
break;
case 2:
gpio_toggle(LED1_PORT, LED1_PIN); /* LED1 on/off */
break;
case 3:
gpio_toggle(LED0_PORT, LED0_PIN); /* LED0 on/off */
break;
default:
break;
}
++count;
count &= 3U;
}
}
86 changes: 86 additions & 0 deletions src/platforms/bmp-v3/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# This file is part of the Black Magic Debug project.
#
# Copyright (C) 2025 1BitSquared <info@1bitsquared.com>
# Written by Rachel Mant <git@dragonmux.network>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

probe_bmp_includes = include_directories('.')

probe_bmp_sources = files('platform.c')

probe_bmp_dfu_sources = files('bootloader.c')

probe_bmp_args = [
'-DDFU_SERIAL_LENGTH=9',
'-DBLACKMAGICPROBE_V3',
]

trace_protocol = get_option('trace_protocol')
probe_bmp_args += [f'-DSWO_ENCODING=@trace_protocol@']
probe_bmp_dependencies = [platform_stm32_swo]
if trace_protocol in ['1', '3']
probe_bmp_dependencies += platform_stm32_swo_manchester
endif
if trace_protocol in ['2', '3']
probe_bmp_dependencies += platform_stm32_swo_uart
endif

probe_bmp_common_link_args = [
'-L@0@'.format(meson.current_source_dir()),
'-T@0@'.format('bmp-v3.ld'),
]

probe_bmp_link_args = [
# Reserve two pages for the bootloader
'-Wl,-Ttext=0x8004000',
]

probe_host = declare_dependency(
include_directories: probe_bmp_includes,
sources: probe_bmp_sources,
compile_args: probe_bmp_args,
link_args: probe_bmp_common_link_args + probe_bmp_link_args,
dependencies: [platform_common, platform_stm32u5, probe_bmp_dependencies],
)

probe_bootloader = declare_dependency(
include_directories: [platform_common_includes, probe_bmp_includes],
sources: probe_bmp_dfu_sources,
compile_args: probe_bmp_args,
link_args: probe_bmp_common_link_args,
dependencies: platform_stm32u5_dfu,
)

summary(
{
'Name': 'Black Magic Probe v3',
'Platform': 'STM32U5',
'Bootloader': 'Black Magic Debug Bootloader',
'Load Address': '0x8002000',
},
section: 'Probe',
)
Loading
Loading