Skip to content

Release CodeGenerator 6.0.1 - #32

Merged
Jiu-xiao merged 43 commits into
masterfrom
dev
Oct 11, 2026
Merged

Jiu-xiao merged 43 commits into
masterfrom
dev

Conversation

@Jiu-xiao

@Jiu-xiao Jiu-xiao commented Oct 10, 2026 •

Copy link
Copy Markdown
Member

Release CodeGenerator 6.0.1 (PyPI libxr; with LibXR v2.0.1 and xrobot 1.0.1). Merge after the LibXR release: the publish workflow records LibXR master's commit as the default checkout (RELEASE.md step 3); a GitHub Release v6.0.1 on the merge commit publishes to PyPI. After the merge, dev is fast-forwarded to master.

Candidate: dev d5153df23c0338074965acadd360de121badec1d (pyproject.toml 6.0.1, xr-syntax==0.2.0). master's extra commit is the merge commit of #20, whose tree equals its dev parent.

Changes since 6.0.0

Acceptance

All six RELEASE.md checks pass and tools/check_release.py agrees with the record (details in the LibXR release PR): packages CI green on d5153df2; BSPs regenerated with 6.0.1 give unchanged output apart from the generator: pin (four STM32 BSPs and both MSPM0 migration branches).

Known issue, fixed in 6.0.2: the HPM pin data covers the IO pins only (HPM5301 QFN48 reports 29 pins; power, reset and crystal pins are missing), which shows in the pin layout.

Jiu-xiao and others added 30 commits October 4, 2026 23:57
A ThreadX project used to get the main() hint, but main() does not return once it starts the scheduler, and App_ThreadX_Init() runs before the scheduler starts. setup now names App_ThreadX_Init() and asks for a thread whose entry calls app_main().
Tell ThreadX projects to call app_main() from a thread
libxr pins <model> prints the position, name, type and selectable signals of every pin of a
chip, as YAML or JSON. The prefix of the model chooses the platform: STM32 (ST's
STM32_open_pin_data, BSD-3-Clause) and MSPM0 (the device data of TI SysConfig, TI limited
license). An STM32 package is part of the model; an MSPM0 package comes from the code in the
model suffix or from --package. MSPM0 pins also carry their PINCM and the mode of each signal.
A position can hold several entries (STM32G0 pin remapping), so pin_count counts positions.

The data is built by scripts/build_pin_data.py into src/libxr/pin_data/ (reproducible gzip
JSON, 0.7 MB) and ships with both license texts as package data. The pin names of every
.ioc in 5098 CubeMX example projects (82 STM32 parts, 15540 assignments) match the data.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
libxr pins STM32... loaded all 2898 parts (10 MB of JSON, 82 MB of Python objects), and freeing
them when the interpreter exited cost more than reading them: 0.8 s per call against 0.24 s for
libxr --version. stm32.json.gz is now only the index, from part to series and pin set, and
each series has its own stm32-<series>.json.gz (at most 0.1 MB). A call reads the index and one
shard: 0.28 s, 40 ms more than libxr --version. The same pin set is still stored once.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
libxr pins now lists, as peripherals, every peripheral found in the signal names of the
package: the instance, its kind and, per function, the pins that can carry it (USART1: TX on
PA9, PB6 or PB14). Recognition looks at the name only (ST: <instance>_<function>; TI:
<instance>.<function>), so ETH, FMC, OctoSPI and the others LibXR has no abstraction for are
listed like USART or SPI; whether a peripheral is generated is decided elsewhere. Every
signal of the ST data (78 kinds) and of the TI data (20 kinds) is recognized, apart from
GPIO and the pin names themselves, and a test keeps it so.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The peripherals of libxr pins now also list GPIOA, GPIOB, ... (plain GPIO, one function Pn per
line), EXTI (lines LINE0..., the pins that can use each, from the EXTI mode of the GPIO in ST's
data) and mark a timer that has output channels with capabilities: [pwm]. An STM32 pin gets
gpio_modes (Input, Output, Analog, EVENTOUT, EXTI) from the IOModes of ST's data. TI's device
data has no interrupt information, so an MSPM0 lists no EXTI instead of a guess.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
libxr pins -d <directory> reads what the project has selected and adds a project section to
the layout: for each pin the signal, the peripheral, the function and the GPIO label, and for
each peripheral its pins. An STM32 comes from the CubeMX .ioc (model, Pxn.Signal, Mcu.IPn);
the forms CubeMX writes that differ from ST's names are resolved (GPIO_Output, GPXTIn,
S_TIM2_CH1_ETR, ADCx_INP19 with the enabled ADC, FMC_D2_DA2, ETH_TXD1, SharedAnalog_*). An
MSPM0 comes from the ti_msp_dl_config.h of SysConfig (CONFIG_MSPM0..., the IOMUX_PINCMn_PF_
macros and the _IOMUX GPIO labels); its package is given with --package. An STM32 peripheral
is also tied to its section and key in libxr_config.yaml, with the current parameters (-c
chooses the file). The model is optional with -d. All 18723 selected signals of 5111 CubeMX
example projects resolve to a signal of their pin.

The package data test found pyproject.toml from the installed package, which CI runs the tests
on; it now finds it from the test file.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
libxr pins -d looked for fdcan1 in libxr_config.yaml, and the MC02 BSP writes FDCAN1, so the
peripheral showed as not configured. The key is now matched without regard to case and given
as the file writes it.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
libxr pins -d asked for --package when the model did not name one, but SysConfig already says
it: the @cliArgs of the .syscfg carry either --device and --package (device based) or only
--board (a LaunchPad). The package is now read from the .syscfg (the @v2CliArgs line, which
comes last, wins), or, for a board, from the board definitions of the MSPM0 SDK
(source/ti/boards/.meta: gpn and pkg), which scripts/build_pin_data.py writes to
pin_data/mspm0_boards.json with the license text of those files (BSD-3-Clause). The .syscfg is
looked for in the root, next to the header, one level above it and one level down, never in a
build folder (a CCS project keeps it in the root and the header in Debug/syscfg). A given
--package still wins; without any, the error still asks for one.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
An MSPM0 has no libxr_config.yaml, but its peripherals are configured in the .syscfg
(UART1.targetBaudRate = 2000000; UART1.peripheral.$assign = "UART0";). Each selected
peripheral now carries a sysconfig entry (the module, the name such as UART_0 and the
parameters) and project.sysconfig_file names the file. The script is read as it is written:
strings, numbers (hex too), booleans and arrays by type, an expression as a string; pin
assignments, the solver's $ items, comments, and what has no peripheral of its own (a GPIO
group) are left out. A .syscfg outside the project is not read. The settings are read-only:
SysConfig edits them.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
libxr pins -d reads the root .syscfg of an MSPM0 project (device, package, signals and
labels, with the solver's $suggestSolution and the board table as fallbacks); the
ti_msp_dl_config.h fallback is gone. The MSPM0 data is rebuilt with SysConfig 1.28.1
and carries the power domain of 108 peripheral instances.

HPM projects are new: the layout comes from the .hpmpc and the pinmux functions that
User/main.cpp calls outside any #if. The HPM data (HPM5301/5361/53M1, four packages,
analog functions included) is built from hpm_iomux.h and the ball tables of the
datasheets.
libxr parse reads the root .syscfg of a project and the ti_msp_dl_config.h/.c
that SysConfig generated (reused from build* when newer than the .syscfg, else
SYSCONFIG_TOOL runs once), and records the GPIO pins with the macros the output
actually emits, the UART/I2C/SPI/PWM instances with their DMA channels and
power domains, and the rest for display.

libxr gen emits User/app_main.cpp plus app_main.h and libxr_config.yaml: GPIO
objects only (the interrupt registration stays with the consumer), MSPM0
UART/I2C/SPI/PWM constructions from the SysConfig macros, the BUSCLK constant
per power domain, the UART DMA ownership defines, and the terminal. The
defaults of the buffer sizes and the terminal land in libxr_config.yaml and
existing values stay.
An item of USB.<instance>.cdc may set interface; it becomes the control and data interface names of the CDCUart, so a host can tell CDCs with the same VID:PID apart. Items without it generate the same code as before.
The HPM BSPs move their main out of User/ to a root main.c (C), mirroring
MSPM0, so the active pinmux functions come from there now.
libxr parse for an HPM project reads app.yaml plus the one .hpmpc under
boards/: the selected signals come from the pinmux functions the root
main.c calls outside preprocessor conditions (O2), falling back to
init_bsp_pins; a pad that two active functions select is reported and
the later signal wins, and a main.c that calls no pinmux function is
warned about. `libxr hpm setup` runs the parse and the generation (no
CubeMX step), and cli.PLATFORMS detects an HPM project.

The generation writes User/app_main.cpp, app_main.h and
libxr_config.yaml, keeping main.c BSP-owned and the User Code regions
of an existing file. Objects follow the post-#332 signatures: HPMGPIO
with its port IRQ (direction from gpiom, pull from padCtls, named after
the pin by default and renamed through the GPIO section of
libxr_config), HPMI2C with the configured speed, and HPMPWM on a GPTMR
comparator. The GPTMR PWM is generated only when the SoC's pin data has
no PWM peripheral signal (HPM5301) and is then registered like any
object; on a SoC with one (HPM5361) the GPTMRs stay in Other for
display. Neither the object nor the registration may sit inside #if,
because xrobot's generator cannot evaluate build options and rejects an
XR_REGISTER there. UART, SPI and MCAN are recognized but generate no
objects yet. GPIO interrupt wiring (RegisterCallback, EnableInterrupt)
belongs to the consumer, like a Module binding.

The fixtures are the real project files of the two HPM BSPs with their
reviewed expected output, committed as test data.
…p_main.cpp

Mirrors libxr hpm setup so the VS Code extension can offer the same one-step
setup for MSPM0 projects as for HPM ones.
The parse now takes from the SysConfig output what the .syscfg leaves out: the SPI clock
configuration (gSPI_1_clockConfig with aligned members), the PWM channels
(GPIO_<name>_C<n>_IDX), the pin of a GPIO given as port plus pin number, the peripheral
the solver chose and a DMA channel without a $name. Pins accept $suggestSolution like
libxr pins. An I2C in target mode and an SPI in peripheral mode go to Other with a
warning, an RX timeout DMA trigger counts as RX, the default interrupt polarity is
DISABLE, a default pin name such as PIN_0 falls back to group plus name, and a name that
is a device or SysConfig macro is an error. Every skipped GPIO pin is warned about.

SysConfig runs whenever SYSCONFIG_TOOL and MSPM0_SDK_INSTALL_DIR are usable; otherwise a
newer output under build*, cmake-build* or out is reused. A wrong path is named, a failed
start or a timeout and an unknown device are formatted errors without a traceback, and
the summary is translated.

New fixture: tests/data/mspm0/variants.syscfg with the SysConfig 1.28.1 output.
…l of libxr gen

An SPI clock constant is generated whenever the code uses it (MFCLK or LFCLK with any
divider, BUSCLK with a divider); an unsupported clock source and a project YAML without
the power domain or CPUCLK are errors instead of the <name>_INST_FREQUENCY macro that
SysConfig never defines for an I2C or SPI. A PWM is named pwm_<timer>_c<n> after its
peripheral (TIMG0), as libxr pins -d names its settings.

Every libxr_config value is checked: null takes the default, buffers and queues are
positive integers, a DMA threshold is a non-negative integer, the UART tx_buffer_size is
a multiple of 4 up to 65532 as the driver asserts, and a PWM frequency is a positive
integer or null for no SetConfig. Settings keys match without regard to case and keep
the file's spelling. terminal_source follows STM32: an empty value or none stays off
across regenerations; the first UART is chosen only while the file has no such key.

Warnings for an unused UART DMA RX channel, PWM channels of one timer with different
frequencies, and a hand-written app_main whose lines outside User Code are replaced.
The UART and SPI DMA errors name the SysConfig option. The redundant "No UART has DMA
TX" warning and the duplicated _setting_int are gone.
…m32 setup does

Without --xrobot or --no-xrobot both setups keep the choice of the existing output file,
and a new file uses no XRobot, as libxr stm32 setup does; before, they always turned
XRobot on. Both write .gitignore (ignoring .config.yaml) when it is missing and, like
stm32 setup, give the XRobot setup steps while Modules/modules.yaml does not exist.
User/xrobot_main.hpp stays untouched, as on STM32: xrobot setup / xrobot gen owns it.
…rals of each SoC

The pin table of the HPM5300 datasheet has an LQFP80 column that no part
uses, and its analog functions are one table for the whole series. Each SoC
now gets only the packages of its ordering part numbers (HPM5301: QFN48;
HPM5361: LQFP100, LQFP64, QFN48) and only the signals of the peripherals its
hpm_soc_ip.h declares (no ADC1, DAC or op-amp on a HPM5301). HPM53M1 is not
among the part numbers of the datasheet and leaves the data.
…xtension do

An app.yaml with a .hpmpc under boards/ is HPM even when the root also holds
a .syscfg.
- One reader of the .hpmpc for parse and pins: UTF-8 BOM, null managers,
  gpiom and selectPins, a formatted error for a malformed file, the SoC name
  in upper case.
- The pinmux calls are those of the body of main, with comments and string
  literals removed; spaces, (void) and several calls on a line are allowed.
  A function called inside #if, or not at all, is warned about.
- An unknown SoC or package is an error in parse and gen instead of a SoC
  "without PWM"; pins and parse agree that a GPTMR of a SoC with a PWM
  peripheral has no PWM settings.
- parse checks every pad and signal against the layout, needs SCL and SDA
  for an I2C, keeps a capture-only GPTMR out of PWM, warns about a GPTMR
  whose capture inputs generate nothing and about a comparator on two pads,
  and skips a GPIO assigned to a controller other than GPIO0.
- gen validates the GPIO renames (identifier, keyword, reserved, SDK and
  generated names, uniqueness, all problems at once) and the PWM frequency,
  finds settings keys in any case as pins does, writes the rename table with
  null entries (dropping the null entries of pins that left the project),
  writes no Terminal or terminal_source for HPM and says in the notice when
  main.c calls no pinmux function.
- The GPIO ports and the PWM-capable GPTMR and PWM timers are in the
  peripheral index of libxr pins; GPIO lines drop their leading zero (P3).
…ject an SPI RX timeout trigger

A UART Extend instance (SYS_UARTADV in the SysConfig device data) with DMA RX
on a FULL-DMA channel now receives by circular DMA through
MSPM0_UART_EXTEND_INIT: the RX channel annotations, the
<name>_LIBXR_EXTEND_CAPABLE mark and a receive ring of rx_dma_buffer_size
bytes (even, default 128) are generated. An RX channel that is no FULL-DMA
channel is an error naming the SysConfig option; DMA RX on a UART Main
instance stays a warning. The pin data gains the UART Extend instances and
the FULL-DMA channel count of each family, and the parse records Extend,
DMA_RX_ID and DMAFullChannels. The generated code of the variants project
compiles with -Werror against libxr 121b1db and MSPM0 SDK 2.11.

An SPI whose DMA RX runs on the RX timeout trigger is an error in gen: the
driver moves every byte on the trigger SysConfig configured, so a counted
transfer on RX timeout never completes. The variants project uses the RX
trigger, as every TI example does.
libxr stm32, mspm0 and hpm setup do not update User/xrobot_main.hpp. Once an
XRobot project has Modules/modules.yaml, every setup now ends with the
reminder to run `xrobot gen`; before that it still lists the XRobot setup
steps.
…view found

- pins offers no settings for what gen does not generate: an MSPM0 I2C that
  is not a controller, an MSPM0 SPI in peripheral mode, an HPM I2C without
  SCL or SDA, and an HPM GPIO on a controller other than GPIO0.
- pins finds the HPM GPIO rename key in any case and keeps the file's
  spelling, as gen does.
- pins reads MSPM0 GPIO pins given as port plus pin number, and labels every
  GPIO with the object name gen generates (PIN_0 gives gpio_btn_pin_0); the
  naming rule is one shared function.
- HPM: when main calls pinmux functions only inside #if, nothing is read and
  there is no init_bsp_pins fallback, in parse and pins alike (O2).
- HPM settings read like the other platforms: null is the default and a
  string is an integer literal.
- A GPTMR of a SoC with a PWM peripheral is not PWM-capable in the index.
- GPIO names: the HPM check refuses the function-like SDK macros (MAX, MIN,
  ARRAY_SIZE, fencei, ...) and no longer refuses gpio_led or board_led; both
  HPM and MSPM0 count the names in the generated code and refuse one that
  the code already uses (timebase, NORMAL, ...).
Generate the LibXR layer of MSPM0 (SysConfig) and HPM (Pinmux Tool) projects
The help still said STM32 and MSPM0 only and that -d reads the
ti_msp_dl_config.h of an MSPM0; libxr pins supports HPM too and reads the root
.syscfg of an MSPM0 and the .hpmpc of an HPM. An HPM example is added.
Parsing an MSPM0 project runs SysConfig only when SYSCONFIG_TOOL and
MSPM0_SDK_INSTALL_DIR are set and reuses a build output otherwise; the two
sections get headings in the README's style; UART, I2C and SPI objects take the
lower-case peripheral name; the HPM init_bsp_pins fallback applies only when
main calls no pinmux function; the package rules and the data license name HPM.
The setup of every platform reminds to run xrobot gen once Modules/modules.yaml
exists; the XRobot integration section named stm32 setup and the steps before
modules.yaml only, and the MSPM0 and HPM example outputs lacked the reminder.
Name HPM and the .syscfg/.hpmpc inputs in the help of libxr pins
Document MSPM0, HPM and the pin layout in the README
MSPM0 and HPM now emit static MSPM0PowerManager / HPMPowerManager power_manager
after PlatformInit and include mspm0_power.hpp / hpm_power.hpp; with XRobot the
object is registered as a PowerManager (like STM32), and GPIO renames cannot
take its name. The expected app_main fixtures and the README sections of both
platforms follow.
…0261008

Generate a power_manager object for MSPM0 and HPM
@greptile-apps

greptile-apps Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 2/5

[High impact] Adds support for two new microcontroller platforms with new code generators.

Fix the UART DMA lookup, HPM save failure handling, and CDC string escaping before merging.

Fix All in Claude CodeFindings

  1. P1 Configured UART cannot generate ▶
  2. P1 Failed save reports success ▶
  3. P1 CDC name breaks generated code ▶
  4. P2 Failed rebuild removes pin data ▶
Fix with agent prompt
### Issue 1
src/libxr/peripheral_analyzer_mspm0.py:628
When a UART has only TX DMA and its channel keeps the default name, `_header_dma_channel` misses it. SysConfig emits `UART_0_INST_DMA_TRIGGER` without a numbered suffix, but this pattern requires one. The parsed record then lacks `DMA_TX`, so generation stops with “no DMA TX channel” even though DMA is configured.

Accept both numbered and unnumbered trigger names, and test the TX-only case without an explicit channel name.

### Issue 2
src/libxr/peripheral_analyzer_hpm.py:338
`parse_project` ignores a failed `_save_to_yaml` call. If the HPM output cannot be written, `libxr parse` still exits successfully. During `libxr hpm setup`, generation also continues and can read an old `.config.yaml` when the write failed before opening it.

Exit with an error when saving returns `False`, as the MSPM0 parser does.

### Issue 3
src/libxr/generator_code_stm32.py:2194
The new CDC `interface` value escapes quotes but not backslashes or line breaks before inserting it into a C++ string. A valid YAML name ending in a backslash escapes the generated closing quote and breaks compilation. Other backslash sequences can change the interface name seen by the host.

Escape the complete C++ string value before passing it to `layout`, and add tests for backslashes and line breaks.

### Issue 4
scripts/build_pin_data.py:505-507
The data builder deletes the existing files before reading and building their replacements. A wrong vendor path, unreadable input, or failed extraction leaves the output directory without its working pin data. Developers must restore it before running pin commands or building a package. The MSPM0 and HPM branches use the same ordering.

Build into a temporary directory first. Replace the files and remove obsolete shards only after the build succeeds.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Summary

Releases CodeGenerator 6.0.1 with MSPM0 and HPM parsing, code generation, and packaged pin layouts.

  • MSPM0 projects can now generate LibXR application code.
  • HPM projects can now generate LibXR application code.
  • libxr pins shows chip layouts and project pin choices.
  • Each STM32 CDC can now give its USB interfaces a name.
  • STM32 setup now gives ThreadX and XRobot projects platform-specific next steps.
  • The package and its setup examples now name version 6.0.1.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  CLI["libxr parse / setup"] --> Platform{"Project platform"}
  Platform --> STM32["CubeMX .ioc"]
  Platform --> MSPM0[".syscfg + SysConfig output"]
  Platform --> HPM[".hpmpc + main.c calls"]
  STM32 --> YAML[".config.yaml"]
  MSPM0 --> YAML
  HPM --> YAML
  YAML --> Gen["Platform generator"]
  Settings["libxr_config.yaml"] --> Gen
  Gen --> App["app_main.cpp + app_main.h"]
  Data["Packaged pin data"] --> Pins["libxr pins"]
  STM32 --> Pins
  MSPM0 --> Pins
  HPM --> Pins
Loading

Reviews (1) · Last reviewed commit: "Merge pull request #31 from xrobot-org/c..." · Reviewed by Greptile

Comment thread src/libxr/peripheral_analyzer_mspm0.py Outdated
for macro, value in defines.items():
if macro.endswith("_CHAN_ID"):
channel = macro[: -len("_CHAN_ID")]
elif re.fullmatch(rf"{re.escape(name)}_INST_DMA_TRIGGER_\d+", macro):

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Configured UART cannot generate

When a UART has only TX DMA and its channel keeps the default name, _header_dma_channel misses it. SysConfig emits UART_0_INST_DMA_TRIGGER without a numbered suffix, but this pattern requires one. The parsed record then lacks DMA_TX, so generation stops with “no DMA TX channel” even though DMA is configured.

Accept both numbered and unnumbered trigger names, and test the TX-only case without an explicit channel name.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/libxr/peripheral_analyzer_mspm0.py
Line: 628

Comment:
**Configured UART cannot generate**

When a UART has only TX DMA and its channel keeps the default name, `_header_dma_channel` misses it. SysConfig emits `UART_0_INST_DMA_TRIGGER` without a numbered suffix, but this pattern requires one. The parsed record then lacks `DMA_TX`, so generation stops with “no DMA TX channel” even though DMA is configured.

Accept both numbered and unnumbered trigger names, and test the TX-only case without an explicit channel name.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Fix in Claude Code Fix in Codex

"活动的 pinmux 函数没有选择任何 GPIO 或外设引脚",
)
)
_save_to_yaml(data, str(output_path))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Failed save reports success

parse_project ignores a failed _save_to_yaml call. If the HPM output cannot be written, libxr parse still exits successfully. During libxr hpm setup, generation also continues and can read an old .config.yaml when the write failed before opening it.

Exit with an error when saving returns False, as the MSPM0 parser does.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/libxr/peripheral_analyzer_hpm.py
Line: 338

Comment:
**Failed save reports success**

`parse_project` ignores a failed `_save_to_yaml` call. If the HPM output cannot be written, `libxr parse` still exits successfully. During `libxr hpm setup`, generation also continues and can read an old `.config.yaml` when the write failed before opening it.

Exit with an error when saving returns `False`, as the MSPM0 parser does.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Fix in Claude Code Fix in Codex

# 各路 CDC。
# A set interface names both the control and the data interface; the host tells the
# CDCs that share VID:PID apart by it.
interface = cdc["interface"].replace('"', '\\"')

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 CDC name breaks generated code

The new CDC interface value escapes quotes but not backslashes or line breaks before inserting it into a C++ string. A valid YAML name ending in a backslash escapes the generated closing quote and breaks compilation. Other backslash sequences can change the interface name seen by the host.

Escape the complete C++ string value before passing it to layout, and add tests for backslashes and line breaks.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/libxr/generator_code_stm32.py
Line: 2194

Comment:
**CDC name breaks generated code**

The new CDC `interface` value escapes quotes but not backslashes or line breaks before inserting it into a C++ string. A valid YAML name ending in a backslash escapes the generated closing quote and breaks compilation. Other backslash sequences can change the interface name seen by the host.

Escape the complete C++ string value before passing it to `layout`, and add tests for backslashes and line breaks.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Fix in Claude Code Fix in Codex

Comment thread scripts/build_pin_data.py
Comment on lines +505 to +507
for old in args.output.glob("stm32*.json.gz"):
old.unlink()
index, shards = build_stm32(args.st_data)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Failed rebuild removes pin data

The data builder deletes the existing files before reading and building their replacements. A wrong vendor path, unreadable input, or failed extraction leaves the output directory without its working pin data. Developers must restore it before running pin commands or building a package. The MSPM0 and HPM branches use the same ordering.

Build into a temporary directory first. Replace the files and remove obsolete shards only after the build succeeds.

Prompt To Fix With AI
This is a comment left during a code review.
Path: scripts/build_pin_data.py
Line: 505-507

Comment:
**Failed rebuild removes pin data**

The data builder deletes the existing files before reading and building their replacements. A wrong vendor path, unreadable input, or failed extraction leaves the output directory without its working pin data. Developers must restore it before running pin commands or building a package. The MSPM0 and HPM branches use the same ordering.

Build into a temporary directory first. Replace the files and remove obsolete shards only after the build succeeds.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Fix in Claude Code Fix in Codex

SysConfig writes <instance>_INST_DMA_TRIGGER without a number while an
instance has one DMA trigger, and _0, _1 from two on. _header_dma_channel()
matched only the numbered form, so an instance whose .syscfg names no DMA
channel (only DMA_CHANNEL_TX.peripheral.$assign, as in the
uart_tx_multibyte_fifo_dma_interrupts example of the SDK) found nothing and
generation stopped with "no DMA TX channel".

Both forms are accepted now. An SPI reaches the same lookup and is covered by
the same change. The error message names both forms, and the tests cover the
two lookups, an SPI with one event, and the example end to end.
fix(mspm0): accept the unnumbered DMA trigger macro
@Jiu-xiao
Jiu-xiao merged commit dbb0f49 into master Oct 11, 2026
54 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant