Skip to content

type: readme status: current summary: Layout, CMake shape and descriptions of the base and programmer board firmware targets: MCU, board and SWD implementation of each.


Embedded Bases

embedded/bases contains firmware targets for base and programmer boards. These targets use generated board files from embedded/boards, shared base support from embedded/bases/common, and ChibiOS sources from the repository ChibiOS submodule. Base targets pass 0 as the protocol target because they do not compile tag nanopb protocol sources.

File Organization

embedded/bases/
  CMakeLists.txt              Active base target list
  BUILD_SOURCES.md            Source inventory from successful builds
  TODO.md                     Open work on the bases
  design/investigations/      Dated measurement records
  common/
    inc/                      Shared USB, SWD, ST-Link, and app headers
    src/                      Shared USB, SWD, ST-Link, and ADC sources
    make.mk                   Shared ChibiOS make scaffold for STM32F042 bases
    make-c071.mk              Shared ChibiOS make scaffold for STM32C071 bases
  <base-target>/
    CMakeLists.txt            Firmware target and board dependency
    Makefile                  Includes a shared or target-local make scaffold
    project.mk                Board include and local/shared source list
    cfg/                      ChibiOS configuration overrides
    src/                      Base-local application or SWD implementation

Each active base target follows this CMake shape:

add_embedded_target(<base-target> 0)
add_dependencies(<base-target> <board-target>)

The corresponding project.mk includes the generated board make fragment:

include $(BOARDDIR)/<BOARD_TYPE>/board.mk

Generated firmware artifacts are written under the CMake build tree, not the source tree. Base targets are not installed or packaged: add_embedded_target() installs only targets passed DISTRIBUTE, and no base passes it.

Active Bases

Base target Board target Board include
bittag-base-jlcpcb-v3 board-bittag-base-jlcpcb-v3 bittag-base-jlcpcb-v3/board.mk
bittag-base-v7 board-bittag-base-v7 BITTAG_BASE_V7/board.mk
tag-base-c071 board-tag-base-c071v1 ST_NUCLEO64_C071RB/board.mk
tag-breakout-base-jlcpcb32-v1 board-tag-breakout-base-jlcpcb32-v1 tag-breakout-base-jlcpcb32-v1/board.mk
tag-breakout-base-l432-v1 board-tag-breakout-base-l432-v1 Tag_Breakout_Base_L432_V1/board.mk
tag-breakout-base-l432-u375-1v8 board-tag-breakout-base-l432-u375-1v8 Tag_Breakout_Base_L432_U375_1V8/board.mk

Base Descriptions

A base is a USB SWD programmer for tags: it presents itself to the host as an ST-LINK (common/src/stlink.c, over usbcfg.c) and drives the tag's SWD lines from its own MCU. The CMake download targets prefer it by its USB PID, 0483:3748 (see Embedded Source Layout). Each base differs in MCU, board, and how it clocks SWD.

Base target Base MCU Board SWD implementation
bittag-base-jlcpcb-v3 STM32F042 BitTag Base JLCPCB v3 GPIO bitbang, common/src/ll_swd.c
bittag-base-v7 STM32F042x6 BitTag Base v7 GPIO bitbang, common/src/ll_swd.c
tag-breakout-base-jlcpcb32-v1 STM32F042 Tag Breakout Base JLCPCB32 v1 GPIO bitbang, common/src/ll_swd.c
tag-breakout-base-l432-v1 STM32F042x6 Tag Breakout Base L432 v1 optimized GPIO bitbang, local src/ll_swd.c
tag-breakout-base-l432-u375-1v8 STM32L432 Tag Breakout Base L432 U375 1V8 hybrid SPI/GPIO, local src/ll_swd_spi.c
tag-base-c071 STM32C071 ST Nucleo64-C071RB hybrid SPI/GPIO, local src/ll_swd_spi.c

The STM32F042 bases build with common/make.mk; tag-breakout-base-l432-u375-1v8 has its own make-l432.mk, and tag-base-c071 uses common/make-c071.mk. A local file in a base's src/ replaces the common/src/ file of the same name (VPATH lists ./src first). Each target's project.mk lists exactly what it compiles; see also BUILD_SOURCES.md.

Build any of them with cmake --build <build-dir> --target <base-target>.

bittag-base-jlcpcb-v3

For BitTag Base v6 boards (boards/bittag-base-jlcpcb-v3/Note.txt). STM32F042 in a 32-pin LQFP package. Its board still uses the static generate_board_files() path. The previous board revision, bittag-base-jlcpcb-v2 (Tagbase v5c, 28-pin PLCC package), has a board directory but no base target and is not configured.

bittag-base-v7

BitTag Base v7 on an STM32F042x6. SYSCLK is 48 MHz from the PLL fed by HSI/2 (8 MHz / 2 x 12); USB is clocked from HSI48.

tag-breakout-base-jlcpcb32-v1

Tag Breakout Base JLCPCB32 v1 on an STM32F042. Its board still uses the static generate_board_files() path.

tag-breakout-base-l432-v1

An STM32F042x6 SWD bridge, already at the F042's 48 MHz maximum SYSCLK/HCLK (PLL from HSI/2, USB from HSI48). Its project.mk adds -DUSEEPRINTF to CXXFLAGS, which no rule in the ChibiOS make scaffold reads, so it has no effect on these C sources. Its local src/ll_swd.c is the optimized bitbang: lower-level GPIO helpers in place of PAL line calls, cached direction changes, and fixed-width unrolled shift helpers. Keep that file at the target's normal optimization level; -O3 was slower and larger (investigation). The F042's SRAM is essentially full. The directory also holds an src/ll_swd_spi.c that is not compiled.

tag-breakout-base-l432-u375-1v8

STLink-compatible breakout base for an STM32U375 target with 1.8 V analog buffer enable and explicit SWDIO direction control.

The STM32L432 base MCU runs from an 80 MHz HSI16-derived PLL. USB uses HSI48 with CRS sync. EN1V8 is a static high board output, TGT_RESET is active-high, and SWD drives SWDIO_DIR high for transmit and low for receive.

SWD is hybrid: SW_ShiftOutBytes() sends byte-aligned phases through SPI1, and every other phase -- the odd-width shift-ins above all -- is GPIO bitbang. SWD_DELAY_COUNT and SWD_SPI_BR in project.mk set the bitbang delay and the SPI baud-rate divider. Local src/usbcfg.c replaces the common one; the local src/ll_swd.c is not compiled.

LED_GREEN is PA3 routed to TIM2 channel 4 (AF1). The LED flashes only while stlink_open is true. TIM2 drives a 1 kHz PWM brightness carrier, while a ChibiOS virtual timer separately gates the channel for the visible blink. Tune apparent brightness with LED_GREEN_PWM_DUTY_PERCENT; tune the visible blink envelope with LED_GREEN_BLINK_ON_MS and LED_GREEN_BLINK_OFF_MS. This target uses periodic SysTick timing (CH_CFG_ST_TIMEDELTA == 0) so TIM2 is available to the PWM driver on STM32L432.

tag-base-c071

An STM32C071 on an ST Nucleo64-C071RB development board. It links with the ChibiOS STM32C071xB.ld from $(STARTUPLD) (common/make-c071.mk); the STM32C071xB.ld in the target directory is not used. project.mk maps the tag SWD lines onto SPI pins (LINE_TAG_SWCLK=LINE_SPI1_SCK, LINE_TAG_SWDIO=LINE_SPI1_MOSI, LINE_TAG_SWDIO_IN=LINE_SPI2_MOSI). Its src/ll_swd_spi.c was the reference for the hybrid approach: SPI handles SW_ShiftOutBytes(), and reads switch back to GPIO bitbang. src/stlink-local.c is present but not compiled.

Open work on the bases is in TODO.md.

Identifying a Base

A base cannot be told apart from a genuine ST-LINK, or from another base, by the ST-LINK protocol: every base reports itself as an ST-LINK/V2, firmware V2J37S7. So the bases answer one command of their own, F6 99, which is not an ST-LINK command:

Bytes Content
0-1 0x80 0x00 (STLINK_DEBUG_ERR_OK)
2 format version, 1
3 reserved, 0
4-127 NUL-padded ASCII base=<target>;fw=<git hash>;dirty=<0\|1>;date=<commit date>;stlink=V2J37S7

The reply is always 128 bytes. <target> is the base's CMake target, which names its hardware; the git fields come from the version.h CMake generates for the target, and BASE_TARGET from PROJECT, both wired in by the make scaffolds. The definitions are STLINK_TAGBASE_* in common/inc/stlink.h.

Bases built before the command answer F6 with a 2-byte FAULT (2026 firmware) or not at all (the 2022 firmware), so a host reads the full length with a short timeout and treats anything else as "unidentified". tagcore's LinkAdapt::BaseIdentity() does this, and tag-info prints the result as its first line. The command touches no target state.

Maintenance Notes

  • Update this README when adding, removing, or renaming a base target.
  • Update BUILD_SOURCES.md when CMake source lists or base build membership changes.
  • Keep board pin and signal changes in embedded/boards; keep base USB, SWD, programming, and command behavior here.