From b44c6f674683ce9b3ac34d56b5a8fc1f7b1a26d5 Mon Sep 17 00:00:00 2001 From: Myfro9 <36755290+Myfro9@users.noreply.github.com> Date: Wed, 10 Jun 2026 00:53:52 +0800 Subject: [PATCH 1/2] Remove cubemx-min-prj and BMSv4_pincfg skills Co-Authored-By: Claude Opus 4.8 --- BMSv4_pincfg/SKILL.md | 192 ------------ BMSv4_pincfg/SKILL.md.bak | 213 ------------- cubemx-min-prj/BMSv4.ioc | 152 ---------- cubemx-min-prj/DEBUG_SETUP.md | 100 ------- cubemx-min-prj/REPRODUCTION_GUIDE.md | 167 ----------- cubemx-min-prj/SKILL.md | 62 ---- cubemx-min-prj/agents/openai.yaml | 4 - cubemx-min-prj/bak | 428 --------------------------- cubemx-min-prj/c_cpp_properties.json | 16 - cubemx-min-prj/extensions.json | 19 -- cubemx-min-prj/launch.json | 66 ----- cubemx-min-prj/settings.json | 10 - cubemx-min-prj/tasks.json | 62 ---- 13 files changed, 1491 deletions(-) delete mode 100644 BMSv4_pincfg/SKILL.md delete mode 100644 BMSv4_pincfg/SKILL.md.bak delete mode 100644 cubemx-min-prj/BMSv4.ioc delete mode 100644 cubemx-min-prj/DEBUG_SETUP.md delete mode 100644 cubemx-min-prj/REPRODUCTION_GUIDE.md delete mode 100644 cubemx-min-prj/SKILL.md delete mode 100644 cubemx-min-prj/agents/openai.yaml delete mode 100644 cubemx-min-prj/bak delete mode 100644 cubemx-min-prj/c_cpp_properties.json delete mode 100644 cubemx-min-prj/extensions.json delete mode 100644 cubemx-min-prj/launch.json delete mode 100644 cubemx-min-prj/settings.json delete mode 100644 cubemx-min-prj/tasks.json diff --git a/BMSv4_pincfg/SKILL.md b/BMSv4_pincfg/SKILL.md deleted file mode 100644 index 06347a5..0000000 --- a/BMSv4_pincfg/SKILL.md +++ /dev/null @@ -1,192 +0,0 @@ ---- -name: BMSv4_pincfg -description: Modify an existing STM32CubeMX project for BMSv4 hardware pin and peripheral settings. Use when a CubeMX `.ioc` project already exists and BMSv4 SPI3, SPISW_nCSx / SPIADC_nCSx GPIO outputs, PWM outputs, CUR_poly ADC2 inputs, and specific ADC3 inputs must be configured, code regenerated, and the build re-verified. -metadata: - author: bowei-local - version: "2.1" -compatibility: Requires an existing STM32CubeMX project, local STM32CubeMX installation, and a working CMake build in the target workspace. ---- - -# BMSv4 Pin Configuration - -Apply the BMSv4 hardware pin/peripheral configuration to an existing STM32CubeMX project. Update the `.ioc`, regenerate code with the locally installed CubeMX, then verify the project still builds. - -This skill is for modifying an existing CubeMX project only. Do not create a new project when using this skill. - -## Preconditions -- Confirm the target workspace already contains a CubeMX `.ioc` file and generated STM32 project structure. -- Confirm CubeMX exists locally and detect the installed CubeMX version before editing `.ioc` metadata. -- Keep the existing project name, MCU, clock tree, toolchain, and user code sections unless the user explicitly asks to change them. -- Preserve `ProjectManager.KeepUserCode=true`. -- Treat the existing project as the baseline. Only change configuration items explicitly described in this skill or explicitly requested by the user. -- If the user asks to modify this skill itself, update only the skill file in that turn. Do not also modify any target STM32 project or `.ioc` unless the user separately asks to apply the updated skill. - -## Required BMSv4 configuration - -### SPI3 -- Enable `SPI3`. -- Configure `SPI3` as `Half-Duplex Master`. -- Use `PC10` as `SPI3_SCK`. -- Use `PC12` as `SPI3_MOSI`. -- Disable hardware NSS and use software NSS. -- Parameters: - - Frame format: `Motorola` - - Data size: `8 Bits` - - First bit: `MSB First` - - Prescaler: `2` - - CPOL: `Low` - - CPHA: `1 Edge` - - CRC calculation: `Disabled` - -### Battery switch decoder chip selects -Configure these pins as `GPIO_Output`, label them exactly as listed, and default them to inactive high unless the user explicitly requests another reset state: - -- `PE14` -> `SPISW_nCS1` -- `PE12` -> `SPISW_nCS2` -- `PE10` -> `SPISW_nCS3` -- `PE8` -> `SPISW_nCS4` -- `PG1` -> `SPISW_nCS5` -- `PF15` -> `SPISW_nCS6` - -### Battery voltage ADC decoder chip selects -Configure these pins as `GPIO_Output`, label them exactly as listed, and default them to inactive high unless the user explicitly requests another reset state: - -- `PE13` -> `SPIADC_nCS1` -- `PE11` -> `SPIADC_nCS2` -- `PE9` -> `SPIADC_nCS3` -- `PE7` -> `SPIADC_nCS4` -- `PG0` -> `SPIADC_nCS5` -- `PF14` -> `SPIADC_nCS6` - - - - -### Current-sense ADC inputs -Configure the following six pins as `ADC2` analog inputs and label them exactly as listed: - -- `PB1` -> `ADC2_IN9` -> `CUR_poly1` -- `PB0` -> `ADC2_IN8` -> `CUR_poly2` -- `PC5` -> `ADC2_IN15` -> `CUR_poly3` -- `PC4` -> `ADC2_IN14` -> `CUR_poly4` -- `PA7` -> `ADC2_IN7` -> `CUR_poly5` -- `PA6` -> `ADC2_IN6` -> `CUR_poly6` - -Requirements for these ADC inputs: -- Configure each listed pin as `Analog`. -- Use `No pull-up and no pull-down`. -- Apply the exact labels `CUR_poly1..6`. -- Use `ADC2` for all six channels. -- Preserve any existing ADC peripheral configuration unless the user explicitly asks to change sampling sequences, trigger sources, DMA, scan mode, or conversion timing. -- If the target project does not yet enable an ADC instance for these channels, add the minimum ADC configuration required for CubeMX to keep the pin-to-channel mapping valid, without altering unrelated peripherals. -- Do not stop at pin signal mapping plus regular channel/rank fields. Add whatever CubeMX metadata the installed version requires so the ADC GUI actually shows the channels as selected. - -Required `ADC2` parameters for these inputs: -- Clock Prescaler: `PCLK2 divided by 4` -- Resolution: `12 bits` -- Data Alignment: `Right alignment` -- Scan Conversion Mode: - - keep `Disabled` when only one `CUR_poly` channel is configured into the ADC2 regular group - - set `Enabled` when multiple `CUR_poly` channels are configured into the ADC2 regular group -- Continuous Conversion Mode: `Disabled` -- Discontinuous Conversion Mode: `Disabled` -- DMA Continuous Requests: `Disabled` -- End Of Conversion Selection: `EOC flag at the end of single channel conversion` -- Number Of Conversion: set this to the number of `CUR_poly` channels actually configured into the ADC2 regular group -- External Trigger Conversion Source: `Regular Conversion launched by software` -- External Trigger Conversion Edge: `None` -- Rank: - - when one `CUR_poly` channel is configured, use `Rank = 1` - - when multiple `CUR_poly` channels are configured, assign sequential regular ranks starting at `1` -- Injected Number Of Conversions: `0` -- Enable `ADC1, ADC2 and ADC3 global interrupts` in NVIC with preemption priority `0` and sub priority `0` - -### Additional ADC3 inputs -Configure the following two pins as analog `ADC3` inputs and label them exactly as listed: - -- `PA3` -> `ADC3_IN3` -> `lt3763_cur` -- `PF5` -> `ADC3_IN15` -> `ADC_VBAT_TMP` - -Requirements for these ADC inputs (BMSv31-style ADC3 workflow): -- Configure each listed pin as `Analog`. -- Use `No pull-up and no pull-down`. -- Apply the exact labels `lt3763_cur` and `ADC_VBAT_TMP`. -- Use `ADC3` for both channels. -- Preserve any existing `ADC3` configuration unless the user explicitly asks to change sampling sequences, trigger sources, DMA, scan mode, or conversion timing. -- If the target project does not yet enable an `ADC3` instance for these channels, add the minimum ADC configuration required for CubeMX to keep the pin-to-channel mapping valid, without altering unrelated peripherals. -- Keep pin mapping for both channels, but do not require both channels to be simultaneously configured in the ADC3 regular group. -- Treat `ADC3_IN15` specially on `STM32F407ZGTx`: `PF5 -> ADC3_IN15` is a valid ADC3-only pin mapping in the device database, and it must not be modeled using the same shared-signal metadata pattern as `ADC2_IN15` on `PC5`. -- Do not reuse `SH.ADCx_IN15` entries that belong to `ADC1/ADC2` when configuring `PF5 -> ADC3_IN15`. If the installed CubeMX version uses a different metadata representation for ADC3-only `IN15`, preserve or generate that exact representation instead of forcing it into the ADC1/ADC2 shared-signal format. -- ADC3 working mode must follow BMSv31 style: - - initialize ADC3 as single regular conversion (`Scan Conversion Mode = Disabled`, `Number Of Conversion = 1`, `Rank = 1`) - - keep `Continuous Conversion Mode = Disabled` - - keep `Discontinuous Conversion Mode = Disabled` - - keep `DMA Continuous Requests = Disabled` - - keep `End Of Conversion Selection = EOC flag at the end of single channel conversion` - - use software trigger (`External Trigger Conversion Source = Regular Conversion launched by software`, `External Trigger Conversion Edge = None`) - - do channel selection at runtime by reconfiguring `sConfig.Channel` before each conversion (e.g. switch between `ADC_CHANNEL_3` and `ADC_CHANNEL_15`) - -## Execution steps -1. Detect the local CubeMX version and confirm the project `.ioc` header is not stamped with a newer version than the installed tool. -2. Open the existing `.ioc` project. Do not replace it with a newly created project. -3. Compare the existing project configuration against the configuration explicitly listed in this skill. -4. Modify only the listed configuration items that differ: - - the `SPI3` mode and parameters listed above - - the twelve named GPIO output definitions listed above - - the six PWM pin assignments, timer channel mappings, timer base settings, and default duty-cycle settings listed above - - the six `CUR_poly` ADC input pin assignments, analog modes, labels, required ADC2 channel mappings, and ADC parameters listed above - - the two additional `ADC3` input pin assignments, analog modes, labels, and required ADC3 channel mappings listed above - - when configuring ADC inputs, also add the CubeMX shared-signal metadata required by the installed version so the ADC page shows the intended `INx` entries as selected - - when configuring `PF5 -> ADC3_IN15`, verify against the local device database that the mapping is ADC3-only and do not alias it to the `ADC1/ADC2 IN15` shared-signal entry used by `PC5` - - for ADC3, keep the two pin mappings but configure ADC3 peripheral as single-conversion runtime-switch mode (BMSv31 style), not fixed multi-channel scan sequence -5. Keep every other existing project configuration unchanged if it is not explicitly covered by this skill, including unrelated peripherals, clocks, middleware, pins, NVIC settings, DMA settings, and user code. -6. If any requested pin conflicts with an existing peripheral assignment, stop and report the conflict instead of silently remapping the hardware. -7. Regenerate code using the installed CubeMX while preserving user code sections. - - This is mandatory after any `.ioc` change. Do not skip regeneration. -8. Validate the generated result before finishing: - - `Core/Src/spi.c` contains `MX_SPI3_Init()` with `SPI_DIRECTION_1LINE`, master mode, prescaler `2`, `SPI_POLARITY_LOW`, `SPI_PHASE_1EDGE`, software NSS, and CRC disabled. - - `Core/Src/gpio.c` initializes the required `GPIOE`, `GPIOF`, and `GPIOG` chip-select pins as outputs. - - `Core/Inc/main.h` exports the requested pin names and ports. - - `Core/Src/tim.c` contains `MX_TIM1_Init()` and `MX_TIM3_Init()` with a `10 kHz` PWM base derived from the project timer clocks. - - The generated compare values default to `50%` duty cycle for `pwm_polyctl1..6`. - - The generated GPIO/pin metadata maps `PA9`, `PA8`, `PC9`, `PC8`, `PC7`, and `PC6` to the requested timer channels. - - The generated GPIO/pin metadata maps `PB1`, `PB0`, `PC5`, `PC4`, `PA7`, and `PA6` to `ADC2_IN9`, `ADC2_IN8`, `ADC2_IN15`, `ADC2_IN14`, `ADC2_IN7`, and `ADC2_IN6` with labels `CUR_poly1..6`. - - The generated GPIO/pin metadata maps `PA3` and `PF5` to `ADC3_IN3` and `ADC3_IN15` with labels `lt3763_cur` and `ADC_VBAT_TMP`. - - The generated ADC configuration matches the required `ADC2` settings: `PCLK2/4`, `12-bit`, right alignment, continuous disabled, discontinuous disabled, DMA continuous requests disabled, single-channel EOC, software trigger, trigger edge none, and injected conversions `0`. - - The ADC2 regular group explicitly includes the requested `CUR_poly` channels rather than only setting the pins to analog input mode. - - `Scan Conversion Mode`, `Number Of Conversion`, and the regular channel `Rank` values are adjusted to match the number of `CUR_poly` channels actually configured in ADC2. - - The `.ioc` contains the CubeMX shared ADC signal metadata needed for the locally installed version to render the requested ADC2 inputs as selected in the GUI, not just low-level regular channel fields. - - Re-open or re-load the `.ioc` with the installed CubeMX and confirm the ADC GUI shows the expected `ADC2` input selections instead of leaving the `INx` list unchecked. - - The `.ioc` contains the CubeMX shared ADC signal metadata needed for the locally installed version to render the requested ADC3 inputs as selected in the GUI, not just low-level pin signal fields. - - Re-open or re-load the `.ioc` with the installed CubeMX and confirm `PA3 -> ADC3_IN3` and `PF5 -> ADC3_IN15` pin mappings are preserved without pin-level conflict warnings. - - `Core/Src/adc.c` (or generated ADC3 init code) uses single regular conversion style for ADC3: scan disabled and number-of-conversion = 1. - - ADC3 channel usage follows runtime channel reconfiguration style instead of fixed two-channel scan sequence. - - `ADC3` `IN15` metadata must not overwrite or corrupt the existing `ADC2_IN15` representation used for `PC5`. - - The generated GPIO settings for the six ADC pins remain `Analog mode` with `No pull-up and no pull-down`. - - The generated GPIO settings for `PA3` and `PF5` remain `Analog mode` with `No pull-up and no pull-down`. - - The NVIC enables `ADC1, ADC2 and ADC3 global interrupts` with preemption priority `0` and sub priority `0`. - - If CubeMX generated or updated ADC init code, it does not silently remove unrelated existing ADC settings outside the channels required for `CUR_poly1..6`, `lt3763_cur`, and `ADC_VBAT_TMP`. - - The `.ioc` still opens in the locally installed CubeMX version. -9. Run `cmake --preset Debug`. -10. Run `cmake --build --preset Debug`. -11. Confirm the expected ELF exists under `build/Debug/`. -12. Treat the task as failed if code generation was not executed or if build is not successful. Do not report completion in that case. - -## Notes & guardrails -- Do not infer CubeMX compatibility from memory. Detect the installed version each time. -- Do not hand-edit generated C source first and then try to backfill the `.ioc`; the `.ioc` is the source of truth. -- Do not treat missing detail in this skill as permission to normalize or simplify the rest of the project. -- Do not remove or rewrite existing project configuration that is outside the explicit scope of this skill. -- Do not rename the GPIO labels. They must remain `SPISW_nCS1..6` and `SPIADC_nCS1..6`. -- Do not rename the ADC labels. They must remain `CUR_poly1..6`. -- Do not rename the additional ADC3 labels. They must remain `lt3763_cur` and `ADC_VBAT_TMP`. -- Do not guess PWM frequency parameters from screenshots alone. Derive PSC/ARR/CCR from the actual timer clock in the target project. -- Do not invent ADC parameters that are not explicitly shown or requested; keep unspecified ADC timing details at the generated or pre-existing values unless the user later constrains them. -- Do not leave ADC2 half-configured. It is not sufficient to set only pin analog mode and `ADC2_INx` signal mapping; the required regular ADC2 channels must also be present in the ADC2 configuration. -- Do not leave ADC3 half-configured. It is not sufficient to set only pin analog mode and `ADC3_INx` signal mapping; add the minimum ADC3 configuration and metadata needed for CubeMX to keep and display the requested channels. -- Do not force ADC3 into fixed multi-channel scan mode for these two channels when BMSv31-style behavior is requested. -- Do not assume `ADCx_IN15` metadata is interchangeable across ADC instances on this MCU family. `ADC2_IN15` on `PC5` and `ADC3_IN15` on `PF5` may require different `.ioc` representations. -- Do not add extra ADC channels, sampling logic, or conversion sequencing beyond what is needed to preserve the requested `CUR_poly1..6`, `lt3763_cur`, and `ADC_VBAT_TMP` pin mappings. -- For `_nCS` lines, prefer reset state high so external devices stay deselected after boot. -- If CubeMX generation removes or rewrites required user code outside the modified peripherals, stop and report before making manual source patches. -- If the project uses a non-`Debug` preset name, keep the workspace's existing preset strategy, but still verify a full configure + build path before finishing. -- Do not mark the task complete unless both conditions are met: CubeMX code generation completed successfully, and the project build completed successfully. diff --git a/BMSv4_pincfg/SKILL.md.bak b/BMSv4_pincfg/SKILL.md.bak deleted file mode 100644 index f61a277..0000000 --- a/BMSv4_pincfg/SKILL.md.bak +++ /dev/null @@ -1,213 +0,0 @@ ---- -name: BMSv4_pincfg -description: Modify an existing STM32CubeMX project for BMSv4 hardware pin and peripheral settings. Use when a CubeMX `.ioc` project already exists and BMSv4 SPI3, SPISW_nCSx / SPIADC_nCSx GPIO outputs, PWM outputs, CUR_poly ADC2 inputs, and specific ADC3 inputs must be configured, code regenerated, and the build re-verified. -metadata: - author: bowei-local - version: "2.1" -compatibility: Requires an existing STM32CubeMX project, local STM32CubeMX installation, and a working CMake build in the target workspace. ---- - -# BMSv4 Pin Configuration - -Apply the BMSv4 hardware pin/peripheral configuration to an existing STM32CubeMX project. Update the `.ioc`, regenerate code with the locally installed CubeMX, then verify the project still builds. - -This skill is for modifying an existing CubeMX project only. Do not create a new project when using this skill. - -## Preconditions -- Confirm the target workspace already contains a CubeMX `.ioc` file and generated STM32 project structure. -- Confirm CubeMX exists locally and detect the installed CubeMX version before editing `.ioc` metadata. -- Keep the existing project name, MCU, clock tree, toolchain, and user code sections unless the user explicitly asks to change them. -- Preserve `ProjectManager.KeepUserCode=true`. -- Treat the existing project as the baseline. Only change configuration items explicitly described in this skill or explicitly requested by the user. -- If the user asks to modify this skill itself, update only the skill file in that turn. Do not also modify any target STM32 project or `.ioc` unless the user separately asks to apply the updated skill. - -## Required BMSv4 configuration - -### SPI3 -- Enable `SPI3`. -- Configure `SPI3` as `Half-Duplex Master`. -- Use `PC10` as `SPI3_SCK`. -- Use `PC12` as `SPI3_MOSI`. -- Disable hardware NSS and use software NSS. -- Parameters: - - Frame format: `Motorola` - - Data size: `8 Bits` - - First bit: `MSB First` - - Prescaler: `2` - - CPOL: `Low` - - CPHA: `1 Edge` - - CRC calculation: `Disabled` - -### Battery switch decoder chip selects -Configure these pins as `GPIO_Output`, label them exactly as listed, and default them to inactive high unless the user explicitly requests another reset state: - -- `PE14` -> `SPISW_nCS1` -- `PE12` -> `SPISW_nCS2` -- `PE10` -> `SPISW_nCS3` -- `PE8` -> `SPISW_nCS4` -- `PG1` -> `SPISW_nCS5` -- `PF15` -> `SPISW_nCS6` - -### Battery voltage ADC decoder chip selects -Configure these pins as `GPIO_Output`, label them exactly as listed, and default them to inactive high unless the user explicitly requests another reset state: - -- `PE13` -> `SPIADC_nCS1` -- `PE11` -> `SPIADC_nCS2` -- `PE9` -> `SPIADC_nCS3` -- `PE7` -> `SPIADC_nCS4` -- `PG0` -> `SPIADC_nCS5` -- `PF14` -> `SPIADC_nCS6` - -### PWM outputs -Configure the following pins as timer PWM outputs and label them exactly as listed: - -- `PA9` -> `TIM1_CH2` -> `pwm_polyctl1` -- `PA8` -> `TIM1_CH1` -> `pwm_polyctl2` -- `PC9` -> `TIM3_CH4` -> `pwm_polyctl3` -- `PC8` -> `TIM3_CH3` -> `pwm_polyctl4` -- `PC7` -> `TIM3_CH2` -> `pwm_polyctl5` -- `PC6` -> `TIM3_CH1` -> `pwm_polyctl6` - -Use PWM output mode with configurable duty cycle. Default duty cycle must be `50%`. - -Timer settings for both `TIM1` and `TIM3`: -- Clock source: `Internal Clock` -- PWM frequency: `10 kHz` -- Compute timer parameters from the existing project clocks instead of guessing -- For the standard `STM32F407ZGTx` clock tree used in this workspace, `TIM1` and `TIM3` both see an `84 MHz` timer clock, so use: - - Prescaler `PSC = 83` - - Counter Period `ARR = 99` - - Default Pulse `CCR = 50` -- Keep counter mode `Up` -- Keep clock division `No Division` -- Keep repetition counter `0` unless the selected timer requires a different default generated by CubeMX - -### Current-sense ADC inputs -Configure the following six pins as `ADC2` analog inputs and label them exactly as listed: - -- `PB1` -> `ADC2_IN9` -> `CUR_poly1` -- `PB0` -> `ADC2_IN8` -> `CUR_poly2` -- `PC5` -> `ADC2_IN15` -> `CUR_poly3` -- `PC4` -> `ADC2_IN14` -> `CUR_poly4` -- `PA7` -> `ADC2_IN7` -> `CUR_poly5` -- `PA6` -> `ADC2_IN6` -> `CUR_poly6` - -Requirements for these ADC inputs: -- Configure each listed pin as `Analog`. -- Use `No pull-up and no pull-down`. -- Apply the exact labels `CUR_poly1..6`. -- Use `ADC2` for all six channels. -- Preserve any existing ADC peripheral configuration unless the user explicitly asks to change sampling sequences, trigger sources, DMA, scan mode, or conversion timing. -- If the target project does not yet enable an ADC instance for these channels, add the minimum ADC configuration required for CubeMX to keep the pin-to-channel mapping valid, without altering unrelated peripherals. -- Do not stop at pin signal mapping plus regular channel/rank fields. Add whatever CubeMX metadata the installed version requires so the ADC GUI actually shows the channels as selected. - -Required `ADC2` parameters for these inputs: -- Clock Prescaler: `PCLK2 divided by 4` -- Resolution: `12 bits` -- Data Alignment: `Right alignment` -- Scan Conversion Mode: - - keep `Disabled` when only one `CUR_poly` channel is configured into the ADC2 regular group - - set `Enabled` when multiple `CUR_poly` channels are configured into the ADC2 regular group -- Continuous Conversion Mode: `Disabled` -- Discontinuous Conversion Mode: `Disabled` -- DMA Continuous Requests: `Disabled` -- End Of Conversion Selection: `EOC flag at the end of single channel conversion` -- Number Of Conversion: set this to the number of `CUR_poly` channels actually configured into the ADC2 regular group -- External Trigger Conversion Source: `Regular Conversion launched by software` -- External Trigger Conversion Edge: `None` -- Rank: - - when one `CUR_poly` channel is configured, use `Rank = 1` - - when multiple `CUR_poly` channels are configured, assign sequential regular ranks starting at `1` -- Injected Number Of Conversions: `0` -- Enable `ADC1, ADC2 and ADC3 global interrupts` in NVIC with preemption priority `0` and sub priority `0` - -### Additional ADC3 inputs -Configure the following two pins as analog `ADC3` inputs and label them exactly as listed: - -- `PA3` -> `ADC3_IN3` -> `lt3763_cur` -- `PF5` -> `ADC3_IN15` -> `ADC_VBAT_TMP` - -Requirements for these ADC inputs (BMSv31-style ADC3 workflow): -- Configure each listed pin as `Analog`. -- Use `No pull-up and no pull-down`. -- Apply the exact labels `lt3763_cur` and `ADC_VBAT_TMP`. -- Use `ADC3` for both channels. -- Preserve any existing `ADC3` configuration unless the user explicitly asks to change sampling sequences, trigger sources, DMA, scan mode, or conversion timing. -- If the target project does not yet enable an `ADC3` instance for these channels, add the minimum ADC configuration required for CubeMX to keep the pin-to-channel mapping valid, without altering unrelated peripherals. -- Keep pin mapping for both channels, but do not require both channels to be simultaneously configured in the ADC3 regular group. -- Treat `ADC3_IN15` specially on `STM32F407ZGTx`: `PF5 -> ADC3_IN15` is a valid ADC3-only pin mapping in the device database, and it must not be modeled using the same shared-signal metadata pattern as `ADC2_IN15` on `PC5`. -- Do not reuse `SH.ADCx_IN15` entries that belong to `ADC1/ADC2` when configuring `PF5 -> ADC3_IN15`. If the installed CubeMX version uses a different metadata representation for ADC3-only `IN15`, preserve or generate that exact representation instead of forcing it into the ADC1/ADC2 shared-signal format. -- ADC3 working mode must follow BMSv31 style: - - initialize ADC3 as single regular conversion (`Scan Conversion Mode = Disabled`, `Number Of Conversion = 1`, `Rank = 1`) - - keep `Continuous Conversion Mode = Disabled` - - keep `Discontinuous Conversion Mode = Disabled` - - keep `DMA Continuous Requests = Disabled` - - keep `End Of Conversion Selection = EOC flag at the end of single channel conversion` - - use software trigger (`External Trigger Conversion Source = Regular Conversion launched by software`, `External Trigger Conversion Edge = None`) - - do channel selection at runtime by reconfiguring `sConfig.Channel` before each conversion (e.g. switch between `ADC_CHANNEL_3` and `ADC_CHANNEL_15`) - -## Execution steps -1. Detect the local CubeMX version and confirm the project `.ioc` header is not stamped with a newer version than the installed tool. -2. Open the existing `.ioc` project. Do not replace it with a newly created project. -3. Compare the existing project configuration against the configuration explicitly listed in this skill. -4. Modify only the listed configuration items that differ: - - the `SPI3` mode and parameters listed above - - the twelve named GPIO output definitions listed above - - the six PWM pin assignments, timer channel mappings, timer base settings, and default duty-cycle settings listed above - - the six `CUR_poly` ADC input pin assignments, analog modes, labels, required ADC2 channel mappings, and ADC parameters listed above - - the two additional `ADC3` input pin assignments, analog modes, labels, and required ADC3 channel mappings listed above - - when configuring ADC inputs, also add the CubeMX shared-signal metadata required by the installed version so the ADC page shows the intended `INx` entries as selected - - when configuring `PF5 -> ADC3_IN15`, verify against the local device database that the mapping is ADC3-only and do not alias it to the `ADC1/ADC2 IN15` shared-signal entry used by `PC5` - - for ADC3, keep the two pin mappings but configure ADC3 peripheral as single-conversion runtime-switch mode (BMSv31 style), not fixed multi-channel scan sequence -5. Keep every other existing project configuration unchanged if it is not explicitly covered by this skill, including unrelated peripherals, clocks, middleware, pins, NVIC settings, DMA settings, and user code. -6. If any requested pin conflicts with an existing peripheral assignment, stop and report the conflict instead of silently remapping the hardware. -7. Regenerate code using the installed CubeMX while preserving user code sections. - - This is mandatory after any `.ioc` change. Do not skip regeneration. -8. Validate the generated result before finishing: - - `Core/Src/spi.c` contains `MX_SPI3_Init()` with `SPI_DIRECTION_1LINE`, master mode, prescaler `2`, `SPI_POLARITY_LOW`, `SPI_PHASE_1EDGE`, software NSS, and CRC disabled. - - `Core/Src/gpio.c` initializes the required `GPIOE`, `GPIOF`, and `GPIOG` chip-select pins as outputs. - - `Core/Inc/main.h` exports the requested pin names and ports. - - `Core/Src/tim.c` contains `MX_TIM1_Init()` and `MX_TIM3_Init()` with a `10 kHz` PWM base derived from the project timer clocks. - - The generated compare values default to `50%` duty cycle for `pwm_polyctl1..6`. - - The generated GPIO/pin metadata maps `PA9`, `PA8`, `PC9`, `PC8`, `PC7`, and `PC6` to the requested timer channels. - - The generated GPIO/pin metadata maps `PB1`, `PB0`, `PC5`, `PC4`, `PA7`, and `PA6` to `ADC2_IN9`, `ADC2_IN8`, `ADC2_IN15`, `ADC2_IN14`, `ADC2_IN7`, and `ADC2_IN6` with labels `CUR_poly1..6`. - - The generated GPIO/pin metadata maps `PA3` and `PF5` to `ADC3_IN3` and `ADC3_IN15` with labels `lt3763_cur` and `ADC_VBAT_TMP`. - - The generated ADC configuration matches the required `ADC2` settings: `PCLK2/4`, `12-bit`, right alignment, continuous disabled, discontinuous disabled, DMA continuous requests disabled, single-channel EOC, software trigger, trigger edge none, and injected conversions `0`. - - The ADC2 regular group explicitly includes the requested `CUR_poly` channels rather than only setting the pins to analog input mode. - - `Scan Conversion Mode`, `Number Of Conversion`, and the regular channel `Rank` values are adjusted to match the number of `CUR_poly` channels actually configured in ADC2. - - The `.ioc` contains the CubeMX shared ADC signal metadata needed for the locally installed version to render the requested ADC2 inputs as selected in the GUI, not just low-level regular channel fields. - - Re-open or re-load the `.ioc` with the installed CubeMX and confirm the ADC GUI shows the expected `ADC2` input selections instead of leaving the `INx` list unchecked. - - The `.ioc` contains the CubeMX shared ADC signal metadata needed for the locally installed version to render the requested ADC3 inputs as selected in the GUI, not just low-level pin signal fields. - - Re-open or re-load the `.ioc` with the installed CubeMX and confirm `PA3 -> ADC3_IN3` and `PF5 -> ADC3_IN15` pin mappings are preserved without pin-level conflict warnings. - - `Core/Src/adc.c` (or generated ADC3 init code) uses single regular conversion style for ADC3: scan disabled and number-of-conversion = 1. - - ADC3 channel usage follows runtime channel reconfiguration style instead of fixed two-channel scan sequence. - - `ADC3` `IN15` metadata must not overwrite or corrupt the existing `ADC2_IN15` representation used for `PC5`. - - The generated GPIO settings for the six ADC pins remain `Analog mode` with `No pull-up and no pull-down`. - - The generated GPIO settings for `PA3` and `PF5` remain `Analog mode` with `No pull-up and no pull-down`. - - The NVIC enables `ADC1, ADC2 and ADC3 global interrupts` with preemption priority `0` and sub priority `0`. - - If CubeMX generated or updated ADC init code, it does not silently remove unrelated existing ADC settings outside the channels required for `CUR_poly1..6`, `lt3763_cur`, and `ADC_VBAT_TMP`. - - The `.ioc` still opens in the locally installed CubeMX version. -9. Run `cmake --preset Debug`. -10. Run `cmake --build --preset Debug`. -11. Confirm the expected ELF exists under `build/Debug/`. -12. Treat the task as failed if code generation was not executed or if build is not successful. Do not report completion in that case. - -## Notes & guardrails -- Do not infer CubeMX compatibility from memory. Detect the installed version each time. -- Do not hand-edit generated C source first and then try to backfill the `.ioc`; the `.ioc` is the source of truth. -- Do not treat missing detail in this skill as permission to normalize or simplify the rest of the project. -- Do not remove or rewrite existing project configuration that is outside the explicit scope of this skill. -- Do not rename the GPIO labels. They must remain `SPISW_nCS1..6` and `SPIADC_nCS1..6`. -- Do not rename the ADC labels. They must remain `CUR_poly1..6`. -- Do not rename the additional ADC3 labels. They must remain `lt3763_cur` and `ADC_VBAT_TMP`. -- Do not guess PWM frequency parameters from screenshots alone. Derive PSC/ARR/CCR from the actual timer clock in the target project. -- Do not invent ADC parameters that are not explicitly shown or requested; keep unspecified ADC timing details at the generated or pre-existing values unless the user later constrains them. -- Do not leave ADC2 half-configured. It is not sufficient to set only pin analog mode and `ADC2_INx` signal mapping; the required regular ADC2 channels must also be present in the ADC2 configuration. -- Do not leave ADC3 half-configured. It is not sufficient to set only pin analog mode and `ADC3_INx` signal mapping; add the minimum ADC3 configuration and metadata needed for CubeMX to keep and display the requested channels. -- Do not force ADC3 into fixed multi-channel scan mode for these two channels when BMSv31-style behavior is requested. -- Do not assume `ADCx_IN15` metadata is interchangeable across ADC instances on this MCU family. `ADC2_IN15` on `PC5` and `ADC3_IN15` on `PF5` may require different `.ioc` representations. -- Do not add extra ADC channels, sampling logic, or conversion sequencing beyond what is needed to preserve the requested `CUR_poly1..6`, `lt3763_cur`, and `ADC_VBAT_TMP` pin mappings. -- For `_nCS` lines, prefer reset state high so external devices stay deselected after boot. -- If CubeMX generation removes or rewrites required user code outside the modified peripherals, stop and report before making manual source patches. -- If the project uses a non-`Debug` preset name, keep the workspace's existing preset strategy, but still verify a full configure + build path before finishing. -- Do not mark the task complete unless both conditions are met: CubeMX code generation completed successfully, and the project build completed successfully. diff --git a/cubemx-min-prj/BMSv4.ioc b/cubemx-min-prj/BMSv4.ioc deleted file mode 100644 index da932d1..0000000 --- a/cubemx-min-prj/BMSv4.ioc +++ /dev/null @@ -1,152 +0,0 @@ -#MicroXplorer Configuration settings - do not modify -CAD.formats= -CAD.pinconfig= -CAD.provider= -Dma.Request0=USART2_RX -Dma.Request1=USART2_TX -Dma.RequestsNb=2 -Dma.USART2_RX.0.Direction=DMA_PERIPH_TO_MEMORY -Dma.USART2_RX.0.FIFOMode=DMA_FIFOMODE_DISABLE -Dma.USART2_RX.0.Instance=DMA1_Stream5 -Dma.USART2_RX.0.MemDataAlignment=DMA_MDATAALIGN_BYTE -Dma.USART2_RX.0.MemInc=DMA_MINC_ENABLE -Dma.USART2_RX.0.Mode=DMA_NORMAL -Dma.USART2_RX.0.PeriphDataAlignment=DMA_PDATAALIGN_BYTE -Dma.USART2_RX.0.PeriphInc=DMA_PINC_DISABLE -Dma.USART2_RX.0.Priority=DMA_PRIORITY_LOW -Dma.USART2_RX.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode -Dma.USART2_TX.1.Direction=DMA_MEMORY_TO_PERIPH -Dma.USART2_TX.1.FIFOMode=DMA_FIFOMODE_DISABLE -Dma.USART2_TX.1.Instance=DMA1_Stream6 -Dma.USART2_TX.1.MemDataAlignment=DMA_MDATAALIGN_BYTE -Dma.USART2_TX.1.MemInc=DMA_MINC_ENABLE -Dma.USART2_TX.1.Mode=DMA_NORMAL -Dma.USART2_TX.1.PeriphDataAlignment=DMA_PDATAALIGN_BYTE -Dma.USART2_TX.1.PeriphInc=DMA_PINC_DISABLE -Dma.USART2_TX.1.Priority=DMA_PRIORITY_LOW -Dma.USART2_TX.1.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode -File.Version=6 -GPIO.groupedBy=Group By Peripherals -KeepUserPlacement=false -Mcu.CPN=STM32F407ZGT6 -Mcu.Family=STM32F4 -Mcu.IP0=DMA -Mcu.IP1=NVIC -Mcu.IP2=RCC -Mcu.IP3=SYS -Mcu.IP4=USART2 -Mcu.IPNb=5 -Mcu.Name=STM32F407Z(E-G)Tx -Mcu.Package=LQFP144 -Mcu.Pin0=PH0-OSC_IN -Mcu.Pin1=PH1-OSC_OUT -Mcu.Pin2=PA13 -Mcu.Pin3=PA14 -Mcu.Pin4=PD5 -Mcu.Pin5=PD6 -Mcu.PinsNb=6 -Mcu.ThirdPartyNb=0 -Mcu.UserConstants= -Mcu.UserName=STM32F407ZGTx -MxCube.Version=6.11.1 -MxDb.Version=DB.6.0.111 -NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false -NVIC.DMA1_Stream5_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true -NVIC.DMA1_Stream6_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true -NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false -NVIC.ForceEnableDMAVector=true -NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false -NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false -NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false -NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false -NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 -NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false -NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true\:false -NVIC.USART2_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:true -NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false -PA13.Mode=Serial_Wire -PA13.Signal=SYS_JTMS-SWDIO -PA14.Mode=Serial_Wire -PA14.Signal=SYS_JTCK-SWCLK -PD5.Mode=Asynchronous -PD5.Signal=USART2_TX -PD6.Mode=Asynchronous -PD6.Signal=USART2_RX -PH0-OSC_IN.Mode=HSE-External-Oscillator -PH0-OSC_IN.Signal=RCC_OSC_IN -PH1-OSC_OUT.Mode=HSE-External-Oscillator -PH1-OSC_OUT.Signal=RCC_OSC_OUT -PinOutPanel.RotationAngle=0 -ProjectManager.AskForMigrate=true -ProjectManager.BackupPrevious=false -ProjectManager.CompilerOptimize=6 -ProjectManager.ComputerToolchain=false -ProjectManager.CoupleFile=true -ProjectManager.CustomerFirmwarePackage= -ProjectManager.DefaultFWLocation=true -ProjectManager.DeletePrevious=true -ProjectManager.DeviceId=STM32F407ZGTx -ProjectManager.FirmwarePackage=STM32Cube FW_F4 V1.28.3 -ProjectManager.FreePins=false -ProjectManager.HalAssertFull=false -ProjectManager.HeapSize=0x200 -ProjectManager.KeepUserCode=true -ProjectManager.LastFirmware=true -ProjectManager.LibraryCopy=1 -ProjectManager.MainLocation=Core/Src -ProjectManager.NoMain=false -ProjectManager.PreviousToolchain= -ProjectManager.ProjectBuild=false -ProjectManager.ProjectFileName=BMSv4.ioc -ProjectManager.ProjectName=BMSv4 -ProjectManager.ProjectStructure= -ProjectManager.RegisterCallBack= -ProjectManager.StackSize=0x400 -ProjectManager.TargetToolchain=CMake -ProjectManager.ToolChainLocation= -ProjectManager.UAScriptAfterPath= -ProjectManager.UAScriptBeforePath= -ProjectManager.UnderRoot=false -ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_USART2_UART_Init-USART2-false-HAL-true -RCC.48MHZClocksFreq_Value=42000000 -RCC.AHBFreq_Value=84000000 -RCC.APB1CLKDivider=RCC_HCLK_DIV2 -RCC.APB1Freq_Value=42000000 -RCC.APB1TimFreq_Value=84000000 -RCC.APB2CLKDivider=RCC_HCLK_DIV1 -RCC.APB2Freq_Value=84000000 -RCC.APB2TimFreq_Value=84000000 -RCC.CortexFreq_Value=84000000 -RCC.EthernetFreq_Value=84000000 -RCC.FCLKCortexFreq_Value=84000000 -RCC.FCLKFreq_Value=84000000 -RCC.FamilyName=M -RCC.HCLKFreq_Value=84000000 -RCC.HSE_VALUE=25000000 -RCC.HSI_VALUE=16000000 -RCC.I2SClocksFreq_Value=96000000 -RCC.IPParameters=48MHZClocksFreq_Value,AHBFreq_Value,APB1CLKDivider,APB1Freq_Value,APB1TimFreq_Value,APB2CLKDivider,APB2Freq_Value,APB2TimFreq_Value,CortexFreq_Value,EthernetFreq_Value,FCLKCortexFreq_Value,FCLKFreq_Value,FamilyName,HCLKFreq_Value,HSE_VALUE,HSI_VALUE,I2SClocksFreq_Value,LSE_VALUE,LSI_VALUE,MCO2PinFreq_Value,PLLCLKFreq_Value,PLLM,PLLN,PLLP,PLLQ,PLLQCLKFreq_Value,PLLSourceVirtual,RTCFreq_Value,RTCHSEDivFreq_Value,SYSCLKFreq_VALUE,SYSCLKSource,VCOI2SOutputFreq_Value,VCOInputFreq_Value,VCOOutputFreq_Value,VcooutputI2S -RCC.LSE_VALUE=32768 -RCC.LSI_VALUE=32000 -RCC.MCO2PinFreq_Value=84000000 -RCC.PLLCLKFreq_Value=84000000 -RCC.PLLM=25 -RCC.PLLN=168 -RCC.PLLP=RCC_PLLP_DIV2 -RCC.PLLQ=4 -RCC.PLLQCLKFreq_Value=42000000 -RCC.PLLSourceVirtual=RCC_PLLSOURCE_HSE -RCC.RTCFreq_Value=32000 -RCC.RTCHSEDivFreq_Value=12500000 -RCC.SYSCLKFreq_VALUE=84000000 -RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK -RCC.VCOI2SOutputFreq_Value=192000000 -RCC.VCOInputFreq_Value=1000000 -RCC.VCOOutputFreq_Value=168000000 -RCC.VcooutputI2S=96000000 -USART2.BaudRate=115200 -USART2.IPParameters=VirtualMode,BaudRate,Mode,OverSampling -USART2.Mode=MODE_TX_RX -USART2.OverSampling=UART_OVERSAMPLING_16 -USART2.VirtualMode=VM_ASYNC -board=custom diff --git a/cubemx-min-prj/DEBUG_SETUP.md b/cubemx-min-prj/DEBUG_SETUP.md deleted file mode 100644 index 555ff74..0000000 --- a/cubemx-min-prj/DEBUG_SETUP.md +++ /dev/null @@ -1,100 +0,0 @@ -# VS Code Debug Setup - -Use this guide when the reproduction workspace must be flashable and debuggable in VS Code with ST-Link and Cortex-Debug. - -## Expected local prerequisites - -- `STM32CubeCLT` installed locally -- `marus25.cortex-debug` extension available in VS Code -- `STM32_Programmer_CLI` on `PATH` or otherwise discoverable by VS Code tasks - -## 1. `.vscode/settings.json` - -Keep the active CMake preset on `Debug` and point VS Code to the local CubeCLT root. - -```json -{ - "files.associations": { - "tcp_client.h": "c", - "lwip.h": "c", - "ethernetif.h": "c" - }, - "cmake.configurePreset": "Debug", - "cmake.buildPreset": "Debug", - "STM32VSCodeExtension.cubeCLT.path": "C:/ST/STM32CubeCLT_1.19.0" -} -``` - -## 2. `.vscode/tasks.json` - -Provide three tasks: - -- `CMake: clean rebuild` -- `CubeProg: Flash project (SWD)` -- `Build + Flash` - -Use `${command:cmake.launchTargetPath}` for the download path so the task follows the active target. - -## 3. `.vscode/launch.json` - -Create both launch and attach profiles with: - -- `type: "cortex-debug"` -- `servertype: "stlink"` -- `device: "STM32F407ZGTx"` -- `interface: "swd"` -- `runToEntryPoint: "main"` -- `serverArgs: ["-m", "0"]` - -Point `executable` at the reproduction ELF. For this skill's default example: - -```json -"executable": "${workspaceFolder}/build/Debug/BMSv4.elf" -``` - -Keep all tool paths derived from `STM32VSCodeExtension.cubeCLT.path`: - -- `serverpath` -- `stm32cubeprogrammer` -- `stlinkPath` -- `armToolchainPath` -- `gdbPath` -- `svdFile` - -## 4. `.vscode/c_cpp_properties.json` - -Use the CMake Tools provider instead of hardcoded include paths. - -```json -{ - "version": 4, - "configurations": [ - { - "name": "STM32", - "configurationProvider": "ms-vscode.cmake-tools", - "intelliSenseMode": "${default}" - } - ] -} -``` - -## 5. `.vscode/extensions.json` - -Recommend, at minimum: - -- `ms-vscode.cpptools-extension-pack` -- `ms-vscode.cmake-tools` -- `marus25.cortex-debug` -- `mcu-debug.debug-tracker-vscode` -- `mcu-debug.memory-view` -- `mcu-debug.peripheral-viewer` -- `mcu-debug.rtos-views` - -Add project-specific editor helpers only if they are already part of the source workflow. - -## 6. Final checks - -- `cmake --build --preset Debug` succeeds before debugging. -- VS Code resolves `${command:cmake.launchTargetPath}` to the expected ELF. -- ST-Link GDB server starts without path errors. -- Flash task uses the same ELF that the debug configuration launches. diff --git a/cubemx-min-prj/REPRODUCTION_GUIDE.md b/cubemx-min-prj/REPRODUCTION_GUIDE.md deleted file mode 100644 index f55d81e..0000000 --- a/cubemx-min-prj/REPRODUCTION_GUIDE.md +++ /dev/null @@ -1,167 +0,0 @@ -# STM32CubeMX Minimal Reproduction Guide - -Use this guide when the task is to recreate the known `BMSv4` minimal project for `STM32F407ZGTx` in a clean workspace and prove that the generated project still builds. - -## Scope - -- CubeMX version: `6.11.1` -- MCU: `STM32F407ZGTx` -- Project name: `BMSv4` -- Toolchain: `CMake` -- Output folder: default to `/reproduction` - -## 1. Verify tools - -Use explicit local paths for CubeMX and fail early if they do not exist. - -```powershell -$mxRoot = "C:/Program Files/STMicroelectronics/STM32Cube/STM32CubeMX" -$mxExe = Join-Path $mxRoot "STM32CubeMX.exe" -$javaExe = Join-Path $mxRoot "jre/bin/java.exe" - -$mxInfo = Get-Item $mxExe | Select-Object FullName,@{N="Version";E={$_.VersionInfo.ProductVersion}} -$mxInfo - -if ($mxInfo.Version -notmatch '^6\.11\.1(?:-.+)?$') { - throw "Unsupported STM32CubeMX version: $($mxInfo.Version). Required: 6.11.1 or 6.11.1-*" -} -``` - -If the version is not `6.11.1` or `6.11.1-*`, stop immediately. Do not create the project, patch the `.ioc`, or generate code. - -## 2. Create the base project - -Generate the initial `.ioc` from CubeMX CLI instead of copying an existing project. - -```powershell -$workspace = (Get-Location).Path -$projDir = Join-Path $workspace "reproduction" - -New-Item -ItemType Directory -Force -Path $projDir | Out-Null -Set-Location $projDir - -@' -load STM32F407ZGTx -project name BMSv4 -project toolchain CMake -project path __PROJECT_PATH__ -config saveas BMSv4.ioc -exit -'@.Replace("__PROJECT_PATH__", $projDir) | Set-Content -Encoding ascii .mx_init.txt - -& $javaExe -jar $mxExe -q .mx_init.txt -``` - -## 3. Patch `.ioc` metadata that CubeMX CLI does not encode reliably - -This reproduction needs precise clock, DMA, and NVIC entries. Apply them directly, then regenerate code. - -```powershell -$ioc = "BMSv4.ioc" -$content = Get-Content $ioc - -$fixes = @( - "RCC.EthernetFreq_Value=84000000", - "RCC.PLLP=RCC_PLLP_DIV2", - "Dma.Request0=USART2_RX", - "Dma.Request1=USART2_TX", - "Dma.RequestsNb=2", - "Dma.USART2_RX.0.Direction=DMA_PERIPH_TO_MEMORY", - "Dma.USART2_RX.0.Instance=DMA1_Stream5", - "Dma.USART2_RX.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode", - "Dma.USART2_TX.1.Direction=DMA_MEMORY_TO_PERIPH", - "Dma.USART2_TX.1.Instance=DMA1_Stream6", - "Dma.USART2_TX.1.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode", - "Mcu.IP0=DMA", - "Mcu.IP1=NVIC", - "Mcu.IP2=RCC", - "Mcu.IP3=SYS", - "Mcu.IP4=USART2", - "Mcu.IPNb=5", - "NVIC.DMA1_Stream5_IRQn=true\\:0\\:0\\:false\\:false\\:true\\:false\\:true\\:true", - "NVIC.DMA1_Stream6_IRQn=true\\:0\\:0\\:false\\:false\\:true\\:false\\:true\\:true", - "NVIC.ForceEnableDMAVector=true", - "NVIC.USART2_IRQn=true\\:0\\:0\\:false\\:false\\:true\\:false\\:false\\:true", - "ProjectManager.UnderRoot=true", - "ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_USART2_UART_Init-USART2-false-HAL-true" -) - -$newLines = $content | Where-Object { - $_ -notmatch '^RCC\.EthernetFreq_Value' -and - $_ -notmatch '^RCC\.PLLP' -and - $_ -notmatch '^Dma\.' -and - $_ -notmatch '^Mcu\.IP' -and - $_ -notmatch '^NVIC\.DMA' -and - $_ -notmatch '^NVIC\.USART2_IRQn' -and - $_ -notmatch '^NVIC\.ForceEnableDMAVector' -and - $_ -notmatch '^ProjectManager\.functionlistsort' -and - $_ -notmatch '^ProjectManager\.UnderRoot' -} - -$newLines += $fixes -$newLines | Set-Content -Encoding ascii $ioc -``` - -## 4. Configure peripheral modes and generate code - -Use CubeMX script mode for the main project shape, then generate. - -```powershell -@' -config load BMSv4.ioc -set mode RCC HSE-External-Oscillator -set mode SYS Serial_Wire -set mode USART2 Asynchronous -set pin PH0 RCC_OSC_IN -set pin PH1 RCC_OSC_OUT -set pin PA13 SYS_JTMS-SWDIO -set pin PA14 SYS_JTCK-SWCLK -set pin PD5 USART2_TX -set pin PD6 USART2_RX -set ip parameters RCC OscillatorType RCC_OSCILLATORTYPE_HSE, OscillatorTypeHSE RCC_OSCILLATORTYPE_HSE, HSEState RCC_HSE_ON, PLLState RCC_PLL_ON, PLLSource RCC_PLLSOURCE_HSE, PLLM 25, PLLN 168, PLLP PLLP_DIV2, PLLQ 4, SYSCLKSource RCC_SYSCLKSOURCE_PLLCLK, AHBCLKDivider RCC_SYSCLK_DIV1, APB1CLKDivider RCC_HCLK_DIV2, APB2CLKDivider RCC_HCLK_DIV1 -set ip parameters USART2 VirtualMode VM_ASYNC, BaudRate 115200, Mode MODE_TX_RX, OverSampling UART_OVERSAMPLING_16 -config save -generate code . -exit -'@ | Set-Content -Encoding ascii .mx_config.txt - -& $javaExe -jar $mxExe -q .mx_config.txt -``` - -## 5. Add the minimal user code needed for reproduction - -Apply only small, isolated changes inside user-code regions. - -```powershell -$usartFile = "Core/Src/usart.c" -$usart = Get-Content $usartFile -Raw -$usartPatch = "/* USER CODE BEGIN 1 */`r`nint __io_putchar(int ch)`r`n{`r`n HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, 1000);`r`n return ch;`r`n}`r`n/* USER CODE END 1 */" -$usart = $usart -replace '(?s)/\* USER CODE BEGIN 1 \*/.*?/\* USER CODE END 1 \*/', $usartPatch -$usart | Set-Content -Encoding utf8 $usartFile - -$mainFile = "Core/Src/main.c" -$main = Get-Content $mainFile -Raw -$main = $main -replace '(?s)/\* USER CODE BEGIN PV \*/.*?/\* USER CODE END PV \*/', "/* USER CODE BEGIN PV */`r`nuint8_t receiveBuf50[50];`r`n/* USER CODE END PV */" -$main = $main -replace '(?s)/\* USER CODE BEGIN 2 \*/.*?/\* USER CODE END 2 \*/', " /* USER CODE BEGIN 2 */`r`n HAL_UARTEx_ReceiveToIdle_DMA(&huart2, receiveBuf50, sizeof(receiveBuf50));`r`n /* USER CODE END 2 */" -$main = $main -replace '(?s)/\* USER CODE BEGIN 4 \*/.*?/\* USER CODE END 4 \*/', "/* USER CODE BEGIN 4 */`r`nvoid HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)`r`n{`r`n if (huart->Instance == USART2)`r`n {`r`n HAL_UART_Transmit_DMA(&huart2, receiveBuf50, Size);`r`n HAL_UARTEx_ReceiveToIdle_DMA(&huart2, receiveBuf50, sizeof(receiveBuf50));`r`n }`r`n}`r`n/* USER CODE END 4 */" -$main = $main -replace 'PLLP_DIV2', 'RCC_PLLP_DIV2' -$main | Set-Content -Encoding utf8 $mainFile -``` - -## 6. Restore the VS Code workflow only if needed - -If the reproduction must match the existing debug flow, rebuild the `.vscode` files using the patterns in [DEBUG_SETUP.md](./DEBUG_SETUP.md). - -## 7. Validate the reproduction - -```powershell -cmake --preset Debug -cmake --build --preset Debug -``` - -Required checks: - -- `BMSv4.ioc` reopens cleanly in CubeMX. -- `Core/Src/usart.c` contains the `__io_putchar` user patch. -- `Core/Src/main.c` contains the DMA receive-to-idle user patch. -- `build/Debug/BMSv4.elf` exists after build. diff --git a/cubemx-min-prj/SKILL.md b/cubemx-min-prj/SKILL.md deleted file mode 100644 index 11d4425..0000000 --- a/cubemx-min-prj/SKILL.md +++ /dev/null @@ -1,62 +0,0 @@ ---- -name: cubemx-min-prj -description: Create a minimal STM32CubeMX reproduction project from scratch, regenerate code, and verify the local build/debug setup. Use when Codex needs to reproduce an STM32 issue in a clean workspace, derive a smallest CubeMX+CMake project from an existing board/project, rebuild `.vscode` STM32 debug files, or document the exact CubeMX CLI and `.ioc` patching steps required to recreate the project. ---- - -# CubeMX Minimal Project - -Create a fresh STM32CubeMX project that reproduces only the hardware and firmware behavior the user needs to debug. Prefer a clean, scriptable reproduction over copying a large existing workspace. - -## Workflow - -1. Inspect the source context. -- Read the target `.ioc`, build presets, and any `.vscode` files before creating the reproduction. -- Identify the minimum MCU, clock tree, peripherals, DMA/NVIC settings, and user-code hooks required to reproduce the issue. -- Keep explicit dates and tool versions. For this workspace, the known-good CubeMX version is `6.11.1`. - -2. Verify local tools. -- Detect the installed STM32CubeMX path and version before touching `.ioc` metadata. -- Run the local version check command from [REPRODUCTION_GUIDE.md](./REPRODUCTION_GUIDE.md) first. -- Stop immediately unless the detected version is exactly `6.11.1` or starts with `6.11.1-`. -- Confirm CMake, the selected toolchain, and any STM32CubeCLT paths needed for build/debug are present. -- If the installed CubeMX is older than the source `.ioc` format, stop and report the version mismatch. - -3. Create the reproduction workspace. -- Default to a new subdirectory such as `reproduction/` under the current workspace. -- Generate the base project from CubeMX CLI/script mode instead of copying generated sources. -- Keep the project minimal: only add the peripherals, pins, and middleware needed to reproduce the issue. - -4. Configure CubeMX deterministically. -- Use CubeMX script commands for project creation, pin assignment, peripheral mode selection, and code generation whenever the CLI supports it. -- If CubeMX CLI cannot express required metadata, patch the `.ioc` directly with exact keys and then regenerate code. -- Treat the `.ioc` as the source of truth. Do not hand-edit generated C files first and backfill the `.ioc` later. - -5. Patch only the user-owned parts of generated code. -- Restrict manual source changes to `/* USER CODE BEGIN */` regions or isolated helper functions added specifically for the reproduction. -- Use this for items like `printf` retargeting, DMA idle receive callbacks, or small harness logic that CubeMX cannot generate. - -6. Rebuild the developer workflow when requested. -- Mirror `.vscode/settings.json`, `tasks.json`, `launch.json`, `c_cpp_properties.json`, and `extensions.json` only if the user wants a debug-ready workspace. -- Reuse the existing project's naming and only swap the target ELF/project name where needed. -- Read [DEBUG_SETUP.md](./DEBUG_SETUP.md) for the BMSv31-style VS Code template expected in this workspace. - -7. Validate before finishing. -- Re-open the `.ioc` in CubeMX after any direct file patching and confirm the GUI reflects the intended configuration. -- Run `cmake --preset Debug` and `cmake --build --preset Debug` unless the user explicitly asks only for scaffolding. -- Confirm the expected ELF exists under `build/Debug/`. -- Treat the task as incomplete if CubeMX generation or local build verification was skipped without user approval. - -## Guardrails - -- Prefer the smallest reproducible project, not a feature-complete clone. -- Do not proceed with project creation, `.ioc` edits, or code generation when CubeMX is not `6.11.1` or `6.11.1-*`. -- Preserve exact issue-critical details such as clock values, DMA streams, NVIC enables, and peripheral modes. -- Use absolute paths inside one-off local commands only when required by CubeMX or local tooling. -- Keep generated project names, MCU names, and toolchain selections explicit in the final notes. -- If reproducing from a larger project, document what was intentionally omitted. -- If CubeMX silently rewrites required metadata, capture the exact `.ioc` keys that must be re-applied. - -## References - -- Read [REPRODUCTION_GUIDE.md](./REPRODUCTION_GUIDE.md) when the task is specifically to recreate the known STM32F407ZGTx/BMSv4 minimal project with CubeMX CLI, `.ioc` patching, user-code updates, and local build verification. -- Read [DEBUG_SETUP.md](./DEBUG_SETUP.md) when the task includes restoring VS Code Cortex-Debug, flash tasks, STM32CubeCLT paths, or extension recommendations. diff --git a/cubemx-min-prj/agents/openai.yaml b/cubemx-min-prj/agents/openai.yaml deleted file mode 100644 index 9029569..0000000 --- a/cubemx-min-prj/agents/openai.yaml +++ /dev/null @@ -1,4 +0,0 @@ -interface: - display_name: "CubeMX Minimal Project" - short_description: "Create and verify a minimal STM32CubeMX reproduction project." - default_prompt: "Use $cubemx-min-prj to create a minimal STM32CubeMX project that reproduces the target configuration and builds locally." diff --git a/cubemx-min-prj/bak b/cubemx-min-prj/bak deleted file mode 100644 index 4e7ef53..0000000 --- a/cubemx-min-prj/bak +++ /dev/null @@ -1,428 +0,0 @@ ---- -name: cubemx-min-prj -description: Create an STM32CubeMX minimum project (CMake/VS Code ready) matching STM32F407ZGTx clocks and debug setup. Use when generating a new CubeMX-based STM32 project or updating this workflow; confirm the locally installed CubeMX version before creating or editing any `.ioc` so the project stays openable on the user's machine. -metadata: - author: bowei-local - version: "1.5" -compatibility: Requires STM32CubeMX at C:/Program Files/STMicroelectronics/STM32Cube/STM32CubeMX/STM32CubeMX.exe and STM32CubeCLT available for VS Code debug. ---- - -# STM32CubeMX Project Creator - -Teach Claude to create a new STM32CubeMX project for `STM32F407ZGTx`, output a CMake build for VS Code, and prep debug tasks. The generated project must preserve the required `USART2` behavior exactly, including DMA-based idle reception and the supporting user-code hooks in `usart.c`, `main.c`, and `syscalls.c`. - -The skill must be self-contained. Do not inspect, copy from, diff against, or otherwise rely on other user projects as templates or references when generating a new project. - -## Preconditions -- Confirm CubeMX exists at `C:/Program Files/STMicroelectronics/STM32Cube/STM32CubeMX/STM32CubeMX.exe`; otherwise stop and report. -- Confirm the installed CubeMX version before generating or editing the project. If the local version cannot be determined, stop and report instead of guessing. -- REQUIRED VERSION LOCK: local STM32CubeMX must be exactly `6.11.1`. If the detected version is not exactly `6.11.1`, stop immediately and report an error; do not proceed. Note: `6.11.1-*` is equal to `6.11.1`. -- Ensure written `.ioc` metadata is `MxCube.Version=6.11.1` for this skill. -- Use only the installed CubeMX, its bundled databases, and the requested project directory as inputs. Do not use another workspace or existing STM32 project as a reference. -- Have an output directory where the new project folder will be created. -- Ask the user for the project name. -- VS Code STM32 extensions are available (CMake Tools, Cortex-Debug, STM32 VS Code Extension). - -## Strict IOC acceptance gates -- The generated `.ioc` must match this skill's required configuration exactly (MCU, clock tree, RCC/NVIC/DMA/GPIO/USART2 settings, and pin map). No partial match is acceptable. -- Re-check the final `.ioc` against the required values before finishing; if any field differs, treat as failure and fix/regenerate. -- For `USART2` compatibility, do not hand-write `WordLength/Parity/StopBits` enum lines in `.ioc`. Keep `USART2.IPParameters` minimal (`VirtualMode,BaudRate,Mode,OverSampling`) and let CubeMX resolve 8N1 defaults during load/generation. -- Opening the `.ioc` must not show `Not a valid ioc file` or required-field incompatibility errors. -- If any IOC gate fails, stop, fix in IOC, regenerate, and re-validate before any further edits. - -## MCU + clock configuration -- MCU: `STM32F407ZGTx`, package `LQFP144`. -- Clock source: HSE crystal = `25_000_000 Hz` on `PH0/PH1`. -- PLL: source HSE, `PLLM=25`, `PLLN=168`, `PLLP=2`, `PLLQ=4`. -- Resulting clocks: `SYSCLK=84 MHz`, `HCLK=84 MHz`, `APB1=42 MHz`, `APB2=84 MHz`, `I2S=96 MHz`, `MCO2=84 MHz`, `Systick=1 ms`. -- Ensure RCC: `SYSCLK source = PLLCLK`, `LSI = 32000`, and keep the divider values listed here. - -## Generation targets -- Toolchain/IDE: CMake (Ninja or Make). Enable `CMAKE_EXPORT_COMPILE_COMMANDS`. -- Languages: C + ASM, C standard C11. -- Linker script: device-generated `STM32F407ZGTx_FLASH.ld`. -- Peripherals to enable by default: RCC, SYS, NVIC, GPIO, DMA, USART2. -- GPIO baseline: - - SWD: `PA13` = `SYS_JTMS-SWDIO`, `PA14` = `SYS_JTCK-SWCLK` - - Oscillators: `PH0/PH1` for HSE - - USART pins: `PD5` = `USART2_TX`, `PD6` = `USART2_RX` - - Remove all other GPIO assignments unless the user explicitly asks for them -- NVIC baseline: - - `NVIC_PRIORITYGROUP_4` - - System handlers enabled as generated by CubeMX - - `SysTick_IRQn` enabled with priority `15` - - Enable `DMA1_Stream5_IRQn` and `DMA1_Stream6_IRQn` -- DMA baseline: - - `USART2_RX`: `DMA1_Stream5`, `DMA_CHANNEL_4`, `DMA_PERIPH_TO_MEMORY`, `DMA_NORMAL`, byte alignment, memory increment enabled, peripheral increment disabled, priority low, FIFO disabled - - `USART2_TX`: `DMA1_Stream6`, `DMA_CHANNEL_4`, `DMA_MEMORY_TO_PERIPH`, `DMA_NORMAL`, byte alignment, memory increment enabled, peripheral increment disabled, priority low, FIFO disabled -- USART2 baseline: - - Virtual mode: `VM_ASYNC` - - Parameters in generated init: `115200`, `8N1`, `TX_RX`, `UART_HWCONTROL_NONE`, `UART_OVERSAMPLING_16` - - `HAL_UART_MspInit()` must configure `PD5/PD6` as `GPIO_AF7_USART2` and link both DMA handles with `__HAL_LINKDMA` - - `stm32f4xx_it.c` must keep `DMA1_Stream5_IRQHandler()` and `DMA1_Stream6_IRQHandler()` calling `HAL_DMA_IRQHandler(&hdma_usart2_rx)` and `HAL_DMA_IRQHandler(&hdma_usart2_tx)` -- Do not add other peripherals unless the user explicitly requests them. - -## USART2 runtime behavior -- `printf` redirection pattern: - - Keep `syscalls.c` with `extern int __io_putchar(int ch) __attribute__((weak));` - - Do not implement `__io_putchar()` in `syscalls.c` - - Re-define `int __io_putchar(int ch)` in `Core/Src/usart.c` - - Implementation must call `HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, 1000);` and return `ch` -- DMA receive flow: - - In `main.c`, after `MX_GPIO_Init();`, `MX_DMA_Init();`, and `MX_USART2_UART_Init();`, call `HAL_UARTEx_ReceiveToIdle_DMA(&huart2, receiveBuf50, sizeof(receiveBuf50));` - - Implement `HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)` in user code, not the legacy `HAL_UART_RxCpltCallback()` - - In that callback, when `huart->Instance == USART2`, terminate the buffer safely, process the received command, then immediately re-arm `HAL_UARTEx_ReceiveToIdle_DMA(&huart2, receiveBuf50, sizeof(receiveBuf50));` -- Ensure the generated project includes all symbols used by this flow: - - `UART_HandleTypeDef huart2` - - `DMA_HandleTypeDef hdma_usart2_rx` - - `DMA_HandleTypeDef hdma_usart2_tx` - - a receive buffer such as `uint8_t receiveBuf50[50]` - -## VS Code integration (mirror reference patterns) -Create `.vscode/` with: -- `settings.json`: - - `"cmake.configurePreset": "Debug"` - - `"cmake.buildPreset": "Debug"` - - `"STM32VSCodeExtension.cubeCLT.path": "C:/ST/STM32CubeCLT_1.19.0"` (or user path) -- `c_cpp_properties.json`: `configurationProvider` = `ms-vscode.cmake-tools` -- `tasks.json`: include - - A fixed `CMake: configure` task that runs `cmake --preset Debug` - - A fixed default build task that runs `cmake --build --preset Debug` - - A fixed clean rebuild task that runs `cmake --build --preset Debug --clean-first` - - Mark the fixed build task as the default build group so VS Code `Ctrl+Shift+B` works immediately - - Flash task: `STM32_Programmer_CLI --connect port=swd --download ${workspaceFolder}/build/Debug/.elf -hardRst -rst --start` - - Aggregate "Build + Flash" task depending on rebuild + flash - - Avoid depending on `${command:cmake.activeBuildPresetName}`, `${command:cmake.activeConfigurePresetName}`, or `${command:cmake.launchTargetPath}` for the default build path, because `Ctrl+Shift+B` may fail before CMake Tools initializes those values -- `launch.json`: Cortex-Debug launch + attach configs: - - `servertype: stlink`, `device: STM32F407ZGTx`, `interface: swd` - - `executable: ${workspaceFolder}/build/Debug/.elf` - - `svdFile: ${config:STM32VSCodeExtension.cubeCLT.path}/STMicroelectronics_CMSIS_SVD/STM32F407.svd` - - `serverpath`/`stlinkPath`: `${config:STM32VSCodeExtension.cubeCLT.path}/STLink-gdb-server/bin/ST-LINK_gdbserver` - - `armToolchainPath`: `${config:STM32VSCodeExtension.cubeCLT.path}/GNU-tools-for-STM32/bin` - - `gdbPath`: `${config:STM32VSCodeExtension.cubeCLT.path}/GNU-tools-for-STM32/bin/arm-none-eabi-gdb` - - `preLaunchTask`: `CMake: clean rebuild` (for launch config) - -## CMake scaffolding (root) -- `CMakeLists.txt`: include toolchain `cmake/gcc-arm-none-eabi.cmake`, set `CMAKE_C_STANDARD 11`, enable C & ASM, create executable `${CMAKE_PROJECT_NAME}`, `add_subdirectory(cmake/stm32cubemx)`, add user sources, link `stm32cubemx`. -- `CMakePresets.json`: generator Ninja, binary dir `build/${presetName}`, presets Debug/RelWithDebInfo/Release/MinSizeRel inheriting default. -- `cmake/gcc-arm-none-eabi.cmake`: set `TOOLCHAIN_PREFIX=arm-none-eabi-`, compilers, target flags `-mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard`, link script `STM32F407ZGTx_FLASH.ld`, typical link flags with gc-sections and map file. -- `cmake/stm32cubemx/CMakeLists.txt`: interface lib with `USE_HAL_DRIVER`, `STM32F407xx`, includes for `Core/Inc` and `Drivers`, and CubeMX-generated sources for the minimal setup (at minimum `main.c`, `gpio.c`, `dma.c`, `usart.c`, `stm32f4xx_it.c`, `stm32f4xx_hal_msp.c`, `system_stm32f4xx.c`, `startup_stm32f407xx.s`, and required HAL driver files). Keep it aligned with CubeMX output; regenerate if peripherals differ. - -## Execution steps -1) Verify CubeMX binary exists; if missing, stop. -2) Detect and record the installed CubeMX version before doing any `.ioc` work. Use that exact version when validating compatibility and when writing `MxCube.Version` / related metadata. - - Hard stop unless the detected version is exactly `6.11.1`. -3) Do not handcraft a full STM32 project when CubeMX generation is available locally. Generate with the installed CubeMX first, then patch only the required user sections and build files. -4) Do not inspect or copy from any other project on disk. This skill must work independently from CubeMX metadata, generated output, and the instructions in this file only. -5) Ask user for project name and target directory. -6) Create project folder and open CubeMX: - - Set MCU to STM32F407ZGTx (LQFP144). - - Configure RCC: HSE 25 MHz on `PH0/PH1`, `PLLM=25`, `PLLN=168`, `PLLP=2`, `PLLQ=4`, `SYSCLK` from PLL. - - Enable required peripherals for the default template: SYS, RCC, NVIC, GPIO, DMA, USART2. - - Configure only these GPIO entries by default: `PH0`, `PH1`, `PA13`, `PA14`, `PD5`, `PD6`. - - Configure `USART2` as asynchronous on `PD5/PD6`. - - Configure DMA requests exactly as specified here: `USART2_RX -> DMA1_Stream5`, `USART2_TX -> DMA1_Stream6`. - - Set `NVIC_PRIORITYGROUP_4`, keep `SysTick_IRQn` at priority `15`, and enable both DMA stream IRQs. - - Project Manager -> Toolchain/IDE: CMake; set project name and path. - - Code Generator: Generate peripheral initialization as "HAL", keep user sections. - - Generate code. -7) Validate the generated output before patching: - - Confirm `main.c` exists and `SystemClock_Config()` uses `HSE`, `PLL_ON`, `PLLM=25`, `PLLN=168`, `PLLP=RCC_PLLP_DIV2`, `PLLQ=4`, `SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK`, `AHB = DIV1`, `APB1 = DIV2`, `APB2 = DIV1`. -- Confirm the generated project includes `USART2`, `DMA1_Stream5`, `DMA1_Stream6`, and `USART2_IRQn`. -- Confirm the generated `.ioc` does not report required-field incompatibilities for RCC, DMA, SYS, GPIO, or USART2. -- Confirm `.ioc` loads without `Not a valid ioc file`. -- Confirm `.ioc` does not contain hand-written `USART2.WordLength`, `USART2.Parity`, `USART2.StopBits` lines and `USART2.IPParameters` remains `VirtualMode,BaudRate,Mode,OverSampling` before generation. -- If CubeMX output falls back to `HSI`, `PLL_NONE`, missing DMA streams, or missing USART2 init, treat generation as failed and fix generation inputs before patching. -8) Patch the generated sources to preserve the required `USART2` runtime behavior: - - In `Core/Src/usart.c`, add `__io_putchar()` in user code and keep it bound to `HAL_UART_Transmit(&huart2, ...)`. - - In `Core/Src/syscalls.c`, leave `__io_putchar()` as a weak external declaration only. - - In `Core/Src/main.c`, declare a receive buffer, call `HAL_UARTEx_ReceiveToIdle_DMA(&huart2, receiveBuf50, sizeof(receiveBuf50));` during initialization, and implement `HAL_UARTEx_RxEventCallback()` to process and re-arm reception. - - In `Core/Src/stm32f4xx_it.c`, keep both DMA IRQ handlers for `USART2`. - - This step is the only allowed direct source-code modification step. -9) Normalize the generated layout to the required root structure if CubeMX emits a different but equivalent layout: - - Required end state is root `Core/Inc`, `Core/Src`, `Drivers`, `cmake`, `.vscode`, linker script, startup file, and root `.ioc`. - - If CubeMX emits `Inc/` and `Src/` at the root, move them to `Core/Inc` and `Core/Src` before patching build files. -10) Add/adjust the CMake scaffolding files (root CMakeLists, presets, toolchain, stm32cubemx CMakeLists) to match the templates above if CubeMX did not emit them. -11) Add `.vscode` files as above; set `executable` paths to the chosen project name. -12) Validate VS Code build behavior: - - Confirm the default VS Code build task maps to `cmake --build --preset Debug`. - - Confirm build tasks do not rely on unresolved CMake Tools command substitutions for the default build path. - - If needed, prefer fixed `Debug` preset names and fixed `${workspaceFolder}/build/Debug/.elf` paths over dynamic commands. -13) Before finishing, re-check the generated `.ioc` header and confirm its CubeMX version metadata still matches the local installation. Fix it if it drifted. - - For this skill, it must be exactly `MxCube.Version=6.11.1`. -14) Enforce no-manual-edit rule: - - Except for `USART2 runtime behavior` source edits in step 8, do not directly modify generated source code to fix config mismatches. - - All non-runtime configuration fixes must be made in `.ioc`, then regenerated from CubeMX. -15) Run `cmake --preset Debug` then `cmake --build --preset Debug` to verify build; ensure `${workspaceFolder}/build/Debug/.elf` exists. -16) Verify VS Code `Ctrl+Shift+B` can invoke the generated default build task without manual preset reselection. -17) For flashing, run VS Code task "Build + Flash" or `STM32_Programmer_CLI --connect port=swd --download build/Debug/.elf -hardRst -rst --start`. -18) For debugging, launch "Build & Debug Microcontroller - ST-Link" in VS Code (Cortex-Debug). - -## Notes & guardrails -- Prefer using commands listed in `Reference commands` whenever possible. If a listed command cannot be used, use an equivalent command and briefly state why. -- Keep `SKILL.md` concise; move verbose reference to separate files if added. -- If user chooses another MCU, re-derive clocks accordingly instead of using the above constants. -- Version policy for this skill is strict: only `6.11.1` is allowed. Any other detected version is a hard error. -- Do not continue from an invalid CubeMX load that logs missing required RCC, DMA, SYS, GPIO, or USART fields. Fix the `.ioc` / generation inputs first. -- For `USART2`, avoid hardcoding enum text values in `.ioc` for `WordLength/Parity/StopBits`; rely on CubeMX defaults and generated init checks instead. -- Do not finish if IOC cannot be opened cleanly by CubeMX. -- Do not continue patching if generated `main.c` shows `HSI` or `PLL_NONE` instead of the required `HSE + PLL` clock tree. -- This skill must remain independent. Do not read another STM32 project to discover valid `.ioc` keys, clock parameters, or file layouts. -- Prefer deterministic VS Code tasks. Do not assume VS Code `Ctrl+Shift+B` will work if the tasks depend on unresolved extension-provided command variables. -- Do not refer to the VS Code build shortcut as `Ctrl+B`; in standard VS Code usage the build shortcut is `Ctrl+Shift+B`. -- For the default build path, prefer fixed `Debug` preset tasks over dynamic `${command:...}` substitutions unless those substitutions are explicitly verified in the current workspace. -- Unless the user asks for more peripherals, remove any auto-enabled middleware or peripheral blocks beyond DMA, GPIO, NVIC, RCC, SYS, and USART2 from both the CubeMX configuration and generated build files. -- When stripping peripherals from a copied `.ioc`, also remove their dependent pins, DMA requests, NVIC entries, generated source files, and middleware references so the result stays internally consistent. -- For GPIO specifically, keep only these default pins: `PH0`, `PH1`, `PA13`, `PA14`, `PD5`, `PD6`. -- Do not replace the required `HAL_UARTEx_ReceiveToIdle_DMA()` + `HAL_UARTEx_RxEventCallback()` flow with polling, interrupt-only receive, or `HAL_UART_Receive_DMA()`. -- Do not move `__io_putchar()` into `syscalls.c`; keep the actual implementation in `usart.c` so `printf` stays coupled to `USART2`. -- Except for the explicit `USART2 runtime behavior` edits, do not directly edit generated C sources for configuration purposes; enforce configuration via IOC + regenerate. - -## Reference commands -Use these commands as operational references for this skill. Adapt `` / paths as needed. - -1) Check CubeMX binary and version -```powershell -$mx='C:/Program Files/STMicroelectronics/STM32Cube/STM32CubeMX/STM32CubeMX.exe' -Test-Path $mx -(Get-Item $mx).VersionInfo -``` - -2) Set CubeMX CLI runtime (required by later commands) -```powershell -$java='C:/Program Files/STMicroelectronics/STM32Cube/STM32CubeMX/jre/bin/java.exe' -$jar='C:/Program Files/STMicroelectronics/STM32Cube/STM32CubeMX/STM32CubeMX.exe' -``` - -3) Probe CLI command capabilities (optional, useful when syntax differs by install) -```powershell -@' -help -project -config -set -get -generate -exit -'@ | Set-Content -Encoding ascii .mx_probe_cmd.txt - -& $java -jar $jar -q .mx_probe_cmd.txt -``` - -4) Create a brand new project + IOC (empty workspace case) -```powershell -@' -load STM32F407ZGTx -project name -project toolchain CMake -generate code . -config saveas .ioc -exit -'@ | Set-Content -Encoding ascii .mx_create_cmd.txt - -& $java -jar $jar -q .mx_create_cmd.txt -``` - -5) Configure existing IOC then regenerate code (already-created IOC case) -```powershell -@' -config load .ioc -generate code . -exit -'@ | Set-Content -Encoding ascii .mx_cmd.txt - -& $java -jar $jar -q .mx_cmd.txt -``` - -6) Apply minimum required pin/peripheral modes before regeneration -```powershell -@' -config load .ioc -set mode RCC HSE-External-Oscillator -set mode SYS Serial_Wire -set mode USART2 Asynchronous -set pin PH0 RCC_OSC_IN -set pin PH1 RCC_OSC_OUT -set pin PA13 SYS_JTMS-SWDIO -set pin PA14 SYS_JTCK-SWCLK -set pin PD5 USART2_TX -set pin PD6 USART2_RX -config save -generate code . -exit -'@ | Set-Content -Encoding ascii .mx_set_basic_cmd.txt - -& $java -jar $jar -q .mx_set_basic_cmd.txt -``` - -7) Apply RCC clock parameters required by this skill, then regenerate -```powershell -@' -config load .ioc -set ip parameters RCC OscillatorType RCC_OSCILLATORTYPE_HSE -set ip parameters RCC OscillatorTypeHSE RCC_OSCILLATORTYPE_HSE -set ip parameters RCC HSEState RCC_HSE_ON -set ip parameters RCC HSEStateARG RCC_HSE_ON -set ip parameters RCC HSEUsed 1 -set ip parameters RCC PLLState RCC_PLL_ON -set ip parameters RCC PLLStateARG RCC_PLL_ON -set ip parameters RCC PLLUsed 1 -set ip parameters RCC PLLUsedForSys 1 -set ip parameters RCC PLLSource RCC_PLLSOURCE_HSE -set ip parameters RCC PLLSourceARG RCC_PLLSOURCE_HSE -set ip parameters RCC PLLSourceVirtual RCC_PLLSOURCE_HSE -set ip parameters RCC PLLM 25 -set ip parameters RCC PLLN 168 -set ip parameters RCC PLLP PLLP_DIV2 -set ip parameters RCC PLLQ 4 -set ip parameters RCC SYSCLKSource RCC_SYSCLKSOURCE_PLLCLK -set ip parameters RCC SYSCLKSourceARG RCC_SYSCLKSOURCE_PLLCLK -set ip parameters RCC AHBCLKDivider RCC_SYSCLK_DIV1 -set ip parameters RCC AHBCLKDividerARG RCC_SYSCLK_DIV1 -set ip parameters RCC APB1CLKDivider RCC_HCLK_DIV2 -set ip parameters RCC APB1CLKDividerARG RCC_HCLK_DIV2 -set ip parameters RCC APB2CLKDivider RCC_HCLK_DIV1 -set ip parameters RCC APB2CLKDividerARG RCC_HCLK_DIV1 -set ip parameters RCC FLatency FLASH_LATENCY_2 -set ip parameters RCC HCLKFreq_Value 84000000 -set ip parameters RCC AHBFreq_Value 84000000 -set ip parameters RCC APB1Freq_Value 42000000 -set ip parameters RCC APB2Freq_Value 84000000 -set ip parameters RCC APB1TimFreq_Value 84000000 -set ip parameters RCC APB2TimFreq_Value 84000000 -set ip parameters RCC SYSCLKFreq_VALUE 84000000 -set ip parameters RCC CortexFreq_Value 84000000 -set ip parameters RCC FCLKCortexFreq_Value 84000000 -set ip parameters RCC PLLCLKFreq_Value 84000000 -set ip parameters RCC PLLQCLKFreq_Value 42000000 -set ip parameters RCC VCOInputFreq_Value 1000000 -set ip parameters RCC VCOOutputFreq_Value 168000000 -set ip parameters RCC HSE_VALUE 25000000 -set ip parameters RCC LSI_VALUE 32000 -set ip parameters USART2 VirtualMode VM_ASYNC -set ip parameters USART2 BaudRate 115200 -set ip parameters USART2 Mode MODE_TX_RX -set ip parameters USART2 OverSampling UART_OVERSAMPLING_16 -config save -generate code . -exit -'@ | Set-Content -Encoding ascii .mx_clock_uart_cmd.txt - -& $java -jar $jar -q .mx_clock_uart_cmd.txt -``` - -7b) Apply DMA baseline using IOC `Dma.*` keys (CubeMX CLI does not accept `USART2_RxDMA/USART2_TxDMA` as valid `set ip parameters`) -```powershell -$ioc='.ioc' -$lines=Get-Content $ioc - -# Remove invalid/legacy USART2 DMA keys and existing Dma section before rewriting -$lines=$lines | Where-Object { - $_ -notmatch '^USART2\.USART2_RxDMA=' -and - $_ -notmatch '^USART2\.USART2_TxDMA=' -and - $_ -notmatch '^Dma\.' -} - -# Keep USART2 IP parameters minimal per skill gate -$lines=$lines | ForEach-Object { - if($_ -match '^USART2\.IPParameters='){ 'USART2.IPParameters=VirtualMode,BaudRate,Mode,OverSampling' } - elseif($_ -match '^USART2\.BaudRate='){ 'USART2.BaudRate=115200' } - elseif($_ -match '^USART2\.Mode='){ 'USART2.Mode=MODE_TX_RX' } - elseif($_ -match '^USART2\.OverSampling='){ 'USART2.OverSampling=UART_OVERSAMPLING_16' } - elseif($_ -match '^USART2\.VirtualMode='){ 'USART2.VirtualMode=VM_ASYNC' } - else { $_ } -} - -# Ensure required USART2 fields exist -if(-not ($lines -match '^USART2\.BaudRate=')){ $lines += 'USART2.BaudRate=115200' } -if(-not ($lines -match '^USART2\.IPParameters=')){ $lines += 'USART2.IPParameters=VirtualMode,BaudRate,Mode,OverSampling' } -if(-not ($lines -match '^USART2\.Mode=')){ $lines += 'USART2.Mode=MODE_TX_RX' } -if(-not ($lines -match '^USART2\.OverSampling=')){ $lines += 'USART2.OverSampling=UART_OVERSAMPLING_16' } -if(-not ($lines -match '^USART2\.VirtualMode=')){ $lines += 'USART2.VirtualMode=VM_ASYNC' } - -# DMA request block for USART2 RX/TX -$dma=@( - 'Dma.Request0=USART2_RX', - 'Dma.Request1=USART2_TX', - 'Dma.RequestsNb=2', - 'Dma.USART2_RX.0.Direction=DMA_PERIPH_TO_MEMORY', - 'Dma.USART2_RX.0.FIFOMode=DMA_FIFOMODE_DISABLE', - 'Dma.USART2_RX.0.Instance=DMA1_Stream5', - 'Dma.USART2_RX.0.MemDataAlignment=DMA_MDATAALIGN_BYTE', - 'Dma.USART2_RX.0.MemInc=DMA_MINC_ENABLE', - 'Dma.USART2_RX.0.Mode=DMA_NORMAL', - 'Dma.USART2_RX.0.PeriphDataAlignment=DMA_PDATAALIGN_BYTE', - 'Dma.USART2_RX.0.PeriphInc=DMA_PINC_DISABLE', - 'Dma.USART2_RX.0.Priority=DMA_PRIORITY_LOW', - 'Dma.USART2_RX.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode', - 'Dma.USART2_TX.1.Direction=DMA_MEMORY_TO_PERIPH', - 'Dma.USART2_TX.1.FIFOMode=DMA_FIFOMODE_DISABLE', - 'Dma.USART2_TX.1.Instance=DMA1_Stream6', - 'Dma.USART2_TX.1.MemDataAlignment=DMA_MDATAALIGN_BYTE', - 'Dma.USART2_TX.1.MemInc=DMA_MINC_ENABLE', - 'Dma.USART2_TX.1.Mode=DMA_NORMAL', - 'Dma.USART2_TX.1.PeriphDataAlignment=DMA_PDATAALIGN_BYTE', - 'Dma.USART2_TX.1.PeriphInc=DMA_PINC_DISABLE', - 'Dma.USART2_TX.1.Priority=DMA_PRIORITY_LOW', - 'Dma.USART2_TX.1.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode' -) - -# Place DMA block near top for readability -$out=@() -$inserted=$false -foreach($l in $lines){ - $out+=$l - if(-not $inserted -and $l -eq 'CAD.provider='){ - $out+=$dma - $inserted=$true - } -} -if(-not $inserted){ $out=$dma + $lines } - -if(-not ($out -match '^NVIC\.DMA1_Stream5_IRQn=')){ $out += 'NVIC.DMA1_Stream5_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true' } -if(-not ($out -match '^NVIC\.DMA1_Stream6_IRQn=')){ $out += 'NVIC.DMA1_Stream6_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true' } - -$out | Set-Content -Encoding ascii $ioc - -@' -config load .ioc -generate code . -exit -'@ | Set-Content -Encoding ascii .mx_dma_fix_cmd.txt - -& $java -jar $jar -q .mx_dma_fix_cmd.txt -``` - -8) Validate IOC can be loaded cleanly -```powershell -@' -config load .ioc -exit -'@ | Set-Content -Encoding ascii .mx_validate_cmd.txt - -& $java -jar $jar -q .mx_validate_cmd.txt -``` - -9) Inspect workspace and key files -```powershell -Get-ChildItem -Recurse -Force -Get-Content -Raw .ioc -rg -n "" . -``` - -10) Verify generated clock/USART code quickly -```powershell -rg -n "OscillatorType|HSEState|PLLState|PLLM|PLLN|PLLP|PLLQ|SYSCLKSource|APB1CLKDivider|APB2CLKDivider|FLASH_LATENCY" Src/main.c -rg -n "huart2.Init.BaudRate|huart2.Init.Mode|huart2.Init.OverSampling" Src/main.c -``` - -11) Configure and build with CMake -```powershell -cmake --preset Debug -cmake --build --preset Debug -``` - -12) VS Code default build task target (Ctrl+Shift+B) -```powershell -cmake --build --preset Debug -``` diff --git a/cubemx-min-prj/c_cpp_properties.json b/cubemx-min-prj/c_cpp_properties.json deleted file mode 100644 index 304929b..0000000 --- a/cubemx-min-prj/c_cpp_properties.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "version": 4, - "configurations": [ - { - /** - * ms-vscode.cmake-tools plugin should be installed. - * - * It provides data for C/C++ plugin, - * such as include paths, browse paths, defines, etc. - */ - "name": "STM32", - "configurationProvider": "ms-vscode.cmake-tools", - "intelliSenseMode": "${default}" - } - ] -} \ No newline at end of file diff --git a/cubemx-min-prj/extensions.json b/cubemx-min-prj/extensions.json deleted file mode 100644 index 9ec15cc..0000000 --- a/cubemx-min-prj/extensions.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "recommendations": [ - "ms-vscode.cpptools", // (dependencies to ms-vscode.cpptools-extension-pack) - "ms-vscode.cpptools-themes", // (dependencies to ms-vscode.cpptools-extension-pack) - "ms-vscode.cmake-tools", // (dependencies to ms-vscode.cpptools-extension-pack) - "twxs.cmake", // (dependencies to ms-vscode.cpptools-extension-pack) - "ms-vscode.cpptools-extension-pack", // Provides CMake and C++ file coloring, completion & support - "dan-c-underwood.arm", // Provides syntax highlighting for the Arm Assembly language - "zixuanwang.linkerscript", // Provides syntax highlighting for linker scripts - "ms-vscode.hexeditor", // Provides hex editor fo viewing & anipulating files in their raw hexadecimal representation - "trond-snekvik.gnu-mapfiles", // Provides syntax highlighting and symbol listing for GNU linker .map files - "jeff-hykin.better-cpp-syntax", // Provides syntax highlighting for C++ - "marus25.cortex-debug", // Provides debug support on Arm Cortex-M - "mcu-debug.debug-tracker-vscode", // Dependencies to "marus25.cortex-debug" - "mcu-debug.memory-view", // Dependencies to "marus25.cortex-debug" - "mcu-debug.peripheral-viewer", // Dependencies to "marus25.cortex-debug" - "mcu-debug.rtos-views" // Dependencies to "marus25.cortex-debug" - ] -} \ No newline at end of file diff --git a/cubemx-min-prj/launch.json b/cubemx-min-prj/launch.json deleted file mode 100644 index bfa74e8..0000000 --- a/cubemx-min-prj/launch.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "name": "Build & Debug Microcontroller - ST-Link", - "cwd": "${workspaceFolder}", - "type": "cortex-debug", - "executable": "${workspaceFolder}/build/Debug/BMSv3.elf", - // Let CMake extension decide executable: "${command:cmake.launchTargetPath}" - // Or fixed file path: "${workspaceFolder}/path/to/filename.elf" - "request": "launch", - "servertype": "stlink", - "device": "STM32F407ZGTx", //MCU used - "interface": "swd", - "serialNumber": "", //Set ST-Link ID if you use multiple at the same time - "runToEntryPoint": "main", - "showDevDebugOutput": "raw", - "svdFile": "${config:STM32VSCodeExtension.cubeCLT.path}/STMicroelectronics_CMSIS_SVD/STM32F407.svd", - "v1": false, //Change it depending on ST Link version - "serverpath": "${config:STM32VSCodeExtension.cubeCLT.path}/STLink-gdb-server/bin/ST-LINK_gdbserver", - "stm32cubeprogrammer":"${config:STM32VSCodeExtension.cubeCLT.path}/STM32CubeProgrammer/bin", - "stlinkPath": "${config:STM32VSCodeExtension.cubeCLT.path}/STLink-gdb-server/bin/ST-LINK_gdbserver", - "armToolchainPath": "${config:STM32VSCodeExtension.cubeCLT.path}/GNU-tools-for-STM32/bin", - "gdbPath":"${config:STM32VSCodeExtension.cubeCLT.path}/GNU-tools-for-STM32/bin/arm-none-eabi-gdb", - "serverArgs": [ - "-m","0", - ], - "preLaunchTask": "CMake: clean rebuild" - /* If you use external loader, add additional arguments */ - //"serverArgs": ["--extload", "path/to/ext/loader.stldr"], - }, - { - "name": "Attach to Microcontroller - ST-Link", - "cwd": "${workspaceFolder}", - "type": "cortex-debug", - "executable": "${workspaceFolder}/build/Debug/BMSv3.elf", - // Let CMake extension decide executable: "${command:cmake.launchTargetPath}" - // Or fixed file path: "${workspaceFolder}/path/to/filename.elf" - "request": "attach", - "servertype": "stlink", - "device": "STM32F407ZGTx", //MCU used - "interface": "swd", - "serialNumber": "", //Set ST-Link ID if you use multiple at the same time - "runToEntryPoint": "main", - "showDevDebugOutput": "raw", - "svdFile": "${config:STM32VSCodeExtension.cubeCLT.path}/STMicroelectronics_CMSIS_SVD/STM32F407.svd", - "v1": false, //Change it depending on ST Link version - "serverpath": "${config:STM32VSCodeExtension.cubeCLT.path}/STLink-gdb-server/bin/ST-LINK_gdbserver", - "stm32cubeprogrammer":"${config:STM32VSCodeExtension.cubeCLT.path}/STM32CubeProgrammer/bin", - "stlinkPath": "${config:STM32VSCodeExtension.cubeCLT.path}/STLink-gdb-server/bin/ST-LINK_gdbserver", - "armToolchainPath": "${config:STM32VSCodeExtension.cubeCLT.path}/GNU-tools-for-STM32/bin", - "gdbPath":"${config:STM32VSCodeExtension.cubeCLT.path}/GNU-tools-for-STM32/bin/arm-none-eabi-gdb", - "serverArgs": [ - "-m","0", - ], - /* If you use external loader, add additional arguments */ - //"serverArgs": ["--extload", "path/to/ext/loader.stldr"], - } - ] -} - - - diff --git a/cubemx-min-prj/settings.json b/cubemx-min-prj/settings.json deleted file mode 100644 index 2a191b5..0000000 --- a/cubemx-min-prj/settings.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "files.associations": { - "tcp_client.h": "c", - "lwip.h": "c", - "ethernetif.h": "c" - }, - "cmake.configurePreset": "Debug", - "cmake.buildPreset": "Debug", - "STM32VSCodeExtension.cubeCLT.path": "C:/ST/STM32CubeCLT_1.19.0" -} \ No newline at end of file diff --git a/cubemx-min-prj/tasks.json b/cubemx-min-prj/tasks.json deleted file mode 100644 index 26bc8a1..0000000 --- a/cubemx-min-prj/tasks.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "version": "2.0.0", - "windows": { - "options": { - "shell": { - "executable": "cmd.exe", - "args": ["/d", "/c"] - } - } - }, - "tasks": [ - { - "type": "shell", - "label": "CubeProg: Flash project (SWD)", - "command": "STM32_Programmer_CLI", - "args": [ - "--connect", - "port=swd", - "--download", - "${command:cmake.launchTargetPath}", - // Let CMake extension decide executable: "${command:cmake.launchTargetPath}", - "-hardRst", // Hardware reset - if rst pin is connected - "-rst", // Software reset (backup) - "--start" // Start execution - ], - "options": { - "cwd": "${workspaceFolder}" - }, - "problemMatcher": [] - }, - { - "label": "Build + Flash", - "dependsOrder": "sequence", - "dependsOn": [ - "CMake: clean rebuild", - "CubeProg: Flash project (SWD)", - ] - }, - { - "type": "cmake", - "label": "CMake: clean rebuild", - "command": "cleanRebuild", - "targets": [ - "all" - ], - "preset": "${command:cmake.activeBuildPresetName}", - "group": "build", - "problemMatcher": [], - "detail": "CMake template clean rebuild task" - }, - { - "type": "shell", - "label": "CubeProg: List all available communication interfaces", - "command": "STM32_Programmer_CLI", - "args": ["--list"], - "options": { - "cwd": "${workspaceFolder}" - }, - "problemMatcher": [] - } - ] -} From 237e5d8925b3b3cbcec697c10aaa4d611fa6eed7 Mon Sep 17 00:00:00 2001 From: Myfro9 <36755290+Myfro9@users.noreply.github.com> Date: Mon, 22 Jun 2026 16:40:24 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E4=BA=86=E9=83=A8?= =?UTF-8?q?=E5=88=86skill?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 + .../references/installing-and-updating.md | 143 ++++++++++++++++++ .../scripts/read_marketplace_name.py | 48 ++++++ .../scripts/update_plugin_cachebuster.py | 78 ++++++++++ langgraph-plan-review/SKILL.md | 8 +- langgraph-plan-review/scripts/review_task.py | 15 +- vivado-prj-create/SKILL.md | 2 +- 7 files changed, 290 insertions(+), 7 deletions(-) create mode 100644 .system/plugin-creator/references/installing-and-updating.md create mode 100644 .system/plugin-creator/scripts/read_marketplace_name.py create mode 100644 .system/plugin-creator/scripts/update_plugin_cachebuster.py diff --git a/.gitignore b/.gitignore index 8e32840..0a1dc58 100644 --- a/.gitignore +++ b/.gitignore @@ -345,3 +345,6 @@ vercel-react-view-transitions/references/nextjs.md vercel-react-view-transitions/references/patterns.md vercel-react-view-transitions/SKILL.md web-design-guidelines/SKILL.md +*.mjs +*.pckl +*.pyc diff --git a/.system/plugin-creator/references/installing-and-updating.md b/.system/plugin-creator/references/installing-and-updating.md new file mode 100644 index 0000000..28b3b88 --- /dev/null +++ b/.system/plugin-creator/references/installing-and-updating.md @@ -0,0 +1,143 @@ +# Updating Existing Local Plugins + +Use this reference when a plugin already exists and the request is about updating the plugin during +local development. + +All scripts here are specified relative to the skill root. Update the path for running the scripts +depending on your current working directory. + +## When To Use This Flow + +Use this flow when all of the following are true: + +- the plugin already exists locally +- the marketplace entry already points at the plugin source you are editing +- the user wants Codex to see the updated plugin without manually editing marketplace files + +If the user still needs the initial plugin entry or marketplace structure created, use the scaffold +flow first and only then switch to this reinstall flow. + +## Update Loop + +1. Update the plugin manifest to a single Codex cachebuster suffix: + +```bash +python3 scripts/update_plugin_cachebuster.py \ + +``` + +Prefer the default helper behavior here. If you omit `--cachebuster`, the helper uses a UTC +timestamp down to seconds, which is the recommended path for routine local iteration. + +Only use a manual cachebuster override when the user explicitly asks for one or when a workflow +outside Codex depends on a specific token: + +```bash +python3 scripts/update_plugin_cachebuster.py \ + \ + --cachebuster local-20260519-184516 +``` + +2. For the default scaffolded flow, read the marketplace name from the personal marketplace file: + +```bash +python3 scripts/read_marketplace_name.py +``` + +Here, "personal marketplace" means the marketplace whose file is at +`~/.agents/plugins/marketplace.json`. On Windows, use the equivalent path under the user profile. +The helper uses Python's home-directory resolution and prints the marketplace name to use when +constructing the install command. + +To read the name from a different marketplace file, pass the path directly: + +```bash +python3 scripts/read_marketplace_name.py --marketplace-path +``` + +3. Reinstall from that marketplace name: + +```bash +codex plugin add @ +``` + +The default personal marketplace is discovered implicitly from +`~/.agents/plugins/marketplace.json`. You do not need `codex plugin marketplace add` for that +path, and `codex plugin marketplace list` is not the right check for whether that default +marketplace exists. + +4. If the plugin is not using the personal marketplace file, check which configured local + marketplace is actually surfacing that plugin: + +```bash +codex plugin list +``` + +If the plugin is not in the personal marketplace file, confirm which marketplace entry points at +the plugin source you are editing and make sure that marketplace is still local. If it is a +different local marketplace, reinstall from that marketplace name instead of forcing the personal +marketplace flow. If it is not local, stop and help the user resolve the mismatch before +continuing. + +5. If the plugin lives in a different confirmed local marketplace, substitute that marketplace + name: + +```bash +codex plugin add @ +``` + +6. Prompt the user to use a new thread to try the updated plugin, so that Codex picks up new skills + and tools. + +## Cachebuster Policy + +- Preserve the existing version prefix and replace only the suffix. +- Treat the preserved prefix as everything before `+`. +- Use the format: + +```text ++codex. +``` + +Examples: + +- `0.1.0` → `0.1.0+codex.local-20260519-184516` +- `0.1.0+codex.old-token` → `0.1.0+codex.local-20260519-184516` +- `1.2.3-beta.1+codex.prev` → `1.2.3-beta.1+codex.local-20260519-184516` +- `dev-build+other-tag` → `dev-build+codex.local-20260519-184516` + +Replace the existing Codex cachebuster instead of appending another one. Do not keep incrementing +numeric version components just to trigger reinstall behavior. + +## Marketplace Rules + +- Marketplace manipulation should happen through commands, not by hand-editing `marketplace.json` + or `config.toml` during this update/reinstall flow. +- Prefer the personal marketplace file for the default scaffolded flow. +- Read the personal marketplace name with + `python3 scripts/read_marketplace_name.py` and use the printed value when constructing + `codex plugin add @`. +- For non-default marketplace files, use + `python3 scripts/read_marketplace_name.py --marketplace-path ` to read + the name before constructing reinstall commands. +- Do not tell the user to run `codex plugin marketplace add` for the default personal-marketplace + flow. That marketplace is discovered implicitly by Codex. +- If the user specified a different marketplace path, make sure that marketplace is installed + before giving install or reinstall instructions. Non-default marketplace paths are not + discovered implicitly. +- Use `codex plugin list` when the plugin lives in a different configured marketplace and you need + to confirm which marketplace is surfacing that plugin. +- If a non-default local marketplace has not been configured yet, install it with + `codex plugin marketplace add ` before telling the user to run + `codex plugin add @`. +- If the plugin is not in the personal marketplace file, confirm that the selected marketplace is + local before telling the user to reinstall from it. +- If the selected marketplace is not local, stop and help the user resolve that mismatch rather + than pretending the normal local reinstall flow applies. +- If the plugin source is not already the source referenced by the chosen marketplace entry, stop + and fix that first. This update flow does not rewrite marketplace entries. + +## After Reinstall + +After reinstalling, prompt the user to start a new thread for testing. That is the safe boundary for +picking up the updated plugin and its MCP tools. diff --git a/.system/plugin-creator/scripts/read_marketplace_name.py b/.system/plugin-creator/scripts/read_marketplace_name.py new file mode 100644 index 0000000..597e9f7 --- /dev/null +++ b/.system/plugin-creator/scripts/read_marketplace_name.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python3 +"""Print the top-level marketplace name from any marketplace.json file.""" + +from __future__ import annotations + +import argparse +import json +import sys +from pathlib import Path + + +def default_marketplace_path() -> Path: + return Path.home() / ".agents" / "plugins" / "marketplace.json" + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser( + description=( + "Print the top-level marketplace name from marketplace.json. Defaults to the personal " + "marketplace path under the current home directory." + ) + ) + parser.add_argument( + "--marketplace-path", + default=str(default_marketplace_path()), + help="Path to marketplace.json", + ) + return parser.parse_args() + + +def main() -> None: + args = parse_args() + marketplace_path = Path(args.marketplace_path).expanduser().resolve() + payload = json.loads(marketplace_path.read_text(encoding="utf-8")) + if not isinstance(payload, dict): + raise ValueError(f"{marketplace_path} must contain a JSON object.") + name = payload.get("name") + if not isinstance(name, str) or not name.strip(): + raise ValueError(f"{marketplace_path} must contain a non-empty string 'name'.") + print(name.strip()) + + +if __name__ == "__main__": + try: + main() + except Exception as err: # noqa: BLE001 - CLI should surface a single clear message. + print(str(err), file=sys.stderr) + raise SystemExit(1) from err diff --git a/.system/plugin-creator/scripts/update_plugin_cachebuster.py b/.system/plugin-creator/scripts/update_plugin_cachebuster.py new file mode 100644 index 0000000..82d19e5 --- /dev/null +++ b/.system/plugin-creator/scripts/update_plugin_cachebuster.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python3 +"""Rewrite a local plugin version to a single Codex cachebuster suffix.""" + +from __future__ import annotations + +import argparse +import json +import re +import sys +from datetime import datetime, timezone +from pathlib import Path + + +CACHEBUSTER_PREFIX = "codex" + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser( + description=( + "Rewrite a local plugin's version so it preserves everything before '+' and uses " + "a single +codex. suffix." + ) + ) + parser.add_argument("plugin_path", help="Path to the plugin root directory") + parser.add_argument( + "--cachebuster", + help="Optional cachebuster token to embed in the plugin version", + ) + return parser.parse_args() + + +def main() -> None: + args = parse_args() + plugin_root = Path(args.plugin_path).expanduser().resolve() + manifest_path = plugin_root / ".codex-plugin" / "plugin.json" + manifest = load_manifest(manifest_path) + + version = manifest.get("version") + if not isinstance(version, str) or not version.strip(): + raise ValueError(f"{manifest_path} must contain a non-empty string 'version'.") + cachebuster = sanitize_cachebuster(args.cachebuster or default_cachebuster()) + next_version = with_cachebuster(version, cachebuster) + manifest["version"] = next_version + manifest_path.write_text(json.dumps(manifest, indent=2) + "\n", encoding="utf-8") + + print(f"Updated plugin version: {version} -> {next_version}") + + +def load_manifest(manifest_path: Path) -> dict[str, object]: + if not manifest_path.is_file(): + raise FileNotFoundError(f"missing manifest: {manifest_path}") + payload = json.loads(manifest_path.read_text(encoding="utf-8")) + if not isinstance(payload, dict): + raise ValueError(f"{manifest_path} must contain a JSON object.") + return payload +def sanitize_cachebuster(value: str) -> str: + sanitized = re.sub(r"[^a-z0-9-]+", "-", value.strip().lower()) + sanitized = re.sub(r"-{2,}", "-", sanitized).strip("-") + if not sanitized: + raise ValueError("Cachebuster must contain at least one letter or digit.") + return sanitized + + +def default_cachebuster() -> str: + return datetime.now(timezone.utc).strftime("%Y%m%d%H%M%S") + + +def with_cachebuster(version: str, cachebuster: str) -> str: + version_prefix = version.split("+", 1)[0] + return f"{version_prefix}+{CACHEBUSTER_PREFIX}.{cachebuster}" + + +if __name__ == "__main__": + try: + main() + except Exception as err: # noqa: BLE001 - CLI should surface a single clear message. + print(str(err), file=sys.stderr) + raise SystemExit(1) from err diff --git a/langgraph-plan-review/SKILL.md b/langgraph-plan-review/SKILL.md index faf0814..e841ee3 100644 --- a/langgraph-plan-review/SKILL.md +++ b/langgraph-plan-review/SKILL.md @@ -77,7 +77,13 @@ C:\Users\bowei\.claude\skills\langgraph-plan-review\scripts\manage_dev_server.ps ```powershell C:\Users\bowei\.claude\skills\langgraph-plan-review\scripts\manage_dev_server.ps1 start ``` - Wait for the "Ready" confirmation before proceeding. Open the Studio URL in a browser for real-time tracking. + Wait for the "[dev-server] Ready" line in the output. Then **immediately tell the user** in your text response: + - that the dev server is running, and + - the Studio URL: `https://smith.langchain.com/studio/?baseUrl=http://127.0.0.1:2024` + + Example message to user: + > LangGraph dev server 已就绪。可在浏览器中打开 Studio 实时监控工作流: + > https://smith.langchain.com/studio/?baseUrl=http://127.0.0.1:2024 3. Start or resume the LangGraph app: ```powershell # Use double backslashes (\\) in the JSON string so Windows paths are valid JSON. diff --git a/langgraph-plan-review/scripts/review_task.py b/langgraph-plan-review/scripts/review_task.py index c1c498b..eed1a1b 100644 --- a/langgraph-plan-review/scripts/review_task.py +++ b/langgraph-plan-review/scripts/review_task.py @@ -76,14 +76,17 @@ def resolve_codex() -> str: exe = os.environ.get("CODEX_EXE", "") if exe and Path(exe).exists(): return exe - # 2. PATH lookup + # 2. Known install paths (checked before PATH to avoid picking up wrong codex variant) + for candidate in [ + r"C:\Users\bowei\miniconda3\envs\langgraph\codex.cmd", + r"C:\Users\bowei\.conda\envs\langgraph\codex.cmd", + ]: + if Path(candidate).exists(): + return candidate + # 3. PATH lookup fallback found = shutil.which("codex") or shutil.which("codex.cmd") if found: return found - # 3. Hardcoded fallback for the original developer machine - fallback = r"C:\Users\bowei\.conda\envs\langgraph\codex.cmd" - if Path(fallback).exists(): - return fallback raise FileNotFoundError( "Cannot find codex executable. Set CODEX_EXE environment variable or add codex to PATH." ) @@ -128,6 +131,8 @@ def main() -> int: command_args, capture_output=True, text=True, + encoding="utf-8", + errors="replace", timeout=timeout, input=prompt, cwd=work_dir, diff --git a/vivado-prj-create/SKILL.md b/vivado-prj-create/SKILL.md index adb22e6..3e04a4a 100644 --- a/vivado-prj-create/SKILL.md +++ b/vivado-prj-create/SKILL.md @@ -1,6 +1,6 @@ --- name: vivado-prj-create -description: DIRECT EXECUTION - Auto-create Vivado FPGA projects. Triggers: "create Vivado project", "Vivado工程", "FPGA project", "Xilinx project", "setup Vivado". When triggered, IMMEDIATELY execute Step 0 without listing skills or asking for confirmation. +description: 'DIRECT EXECUTION - Auto-create Vivado FPGA projects. Triggers: "create Vivado project", "Vivado工程", "FPGA project", "Xilinx project", "setup Vivado". When triggered, IMMEDIATELY execute Step 0 without listing skills or asking for confirmation.' --- # Vivado Project TCL Generator