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
- Detect the local CubeMX version and confirm the project
.ioc header is not stamped with a newer version than the installed tool.
- Open the existing
.ioc project. Do not replace it with a newly created project.
- Compare the existing project configuration against the configuration explicitly listed in this skill.
- 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
- 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.
- If any requested pin conflicts with an existing peripheral assignment, stop and report the conflict instead of silently remapping the hardware.
- Regenerate code using the installed CubeMX while preserving user code sections.
- This is mandatory after any
.ioc change. Do not skip regeneration.
- 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.
- Run
cmake --preset Debug.
- Run
cmake --build --preset Debug.
- Confirm the expected ELF exists under
build/Debug/.
- 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.
1---2name: bmsv4-pincfg3description: 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.4---56# BMSv4 Pin Configuration78Apply 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.910This skill is for modifying an existing CubeMX project only. Do not create a new project when using this skill.1112## Preconditions13- Confirm the target workspace already contains a CubeMX `.ioc` file and generated STM32 project structure.14- Confirm CubeMX exists locally and detect the installed CubeMX version before editing `.ioc` metadata.15- Keep the existing project name, MCU, clock tree, toolchain, and user code sections unless the user explicitly asks to change them.16- Preserve `ProjectManager.KeepUserCode=true`.17- Treat the existing project as the baseline. Only change configuration items explicitly described in this skill or explicitly requested by the user.18- 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.1920## Required BMSv4 configuration2122### SPI323- Enable `SPI3`.24- Configure `SPI3` as `Half-Duplex Master`.25- Use `PC10` as `SPI3_SCK`.26- Use `PC12` as `SPI3_MOSI`.27- Disable hardware NSS and use software NSS.28- Parameters:29 - Frame format: `Motorola`30 - Data size: `8 Bits`31 - First bit: `MSB First`32 - Prescaler: `2`33 - CPOL: `Low`34 - CPHA: `1 Edge`35 - CRC calculation: `Disabled`3637### Battery switch decoder chip selects38Configure these pins as `GPIO_Output`, label them exactly as listed, and default them to inactive high unless the user explicitly requests another reset state:3940- `PE14` -> `SPISW_nCS1`41- `PE12` -> `SPISW_nCS2`42- `PE10` -> `SPISW_nCS3`43- `PE8` -> `SPISW_nCS4`44- `PG1` -> `SPISW_nCS5`45- `PF15` -> `SPISW_nCS6`4647### Battery voltage ADC decoder chip selects48Configure these pins as `GPIO_Output`, label them exactly as listed, and default them to inactive high unless the user explicitly requests another reset state:4950- `PE13` -> `SPIADC_nCS1`51- `PE11` -> `SPIADC_nCS2`52- `PE9` -> `SPIADC_nCS3`53- `PE7` -> `SPIADC_nCS4`54- `PG0` -> `SPIADC_nCS5`55- `PF14` -> `SPIADC_nCS6`5657### PWM outputs58Configure the following pins as timer PWM outputs and label them exactly as listed:5960- `PA9` -> `TIM1_CH2` -> `pwm_polyctl1`61- `PA8` -> `TIM1_CH1` -> `pwm_polyctl2`62- `PC9` -> `TIM3_CH4` -> `pwm_polyctl3`63- `PC8` -> `TIM3_CH3` -> `pwm_polyctl4`64- `PC7` -> `TIM3_CH2` -> `pwm_polyctl5`65- `PC6` -> `TIM3_CH1` -> `pwm_polyctl6`6667Use PWM output mode with configurable duty cycle. Default duty cycle must be `50%`.6869Timer settings for both `TIM1` and `TIM3`:70- Clock source: `Internal Clock`71- PWM frequency: `10 kHz`72- Compute timer parameters from the existing project clocks instead of guessing73- For the standard `STM32F407ZGTx` clock tree used in this workspace, `TIM1` and `TIM3` both see an `84 MHz` timer clock, so use:74 - Prescaler `PSC = 83`75 - Counter Period `ARR = 99`76 - Default Pulse `CCR = 50`77- Keep counter mode `Up`78- Keep clock division `No Division`79- Keep repetition counter `0` unless the selected timer requires a different default generated by CubeMX8081### Current-sense ADC inputs82Configure the following six pins as `ADC2` analog inputs and label them exactly as listed:8384- `PB1` -> `ADC2_IN9` -> `CUR_poly1`85- `PB0` -> `ADC2_IN8` -> `CUR_poly2`86- `PC5` -> `ADC2_IN15` -> `CUR_poly3`87- `PC4` -> `ADC2_IN14` -> `CUR_poly4`88- `PA7` -> `ADC2_IN7` -> `CUR_poly5`89- `PA6` -> `ADC2_IN6` -> `CUR_poly6`9091Requirements for these ADC inputs:92- Configure each listed pin as `Analog`.93- Use `No pull-up and no pull-down`.94- Apply the exact labels `CUR_poly1..6`.95- Use `ADC2` for all six channels.96- Preserve any existing ADC peripheral configuration unless the user explicitly asks to change sampling sequences, trigger sources, DMA, scan mode, or conversion timing.97- 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.98- 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.99100Required `ADC2` parameters for these inputs:101- Clock Prescaler: `PCLK2 divided by 4`102- Resolution: `12 bits`103- Data Alignment: `Right alignment`104- Scan Conversion Mode:105 - keep `Disabled` when only one `CUR_poly` channel is configured into the ADC2 regular group106 - set `Enabled` when multiple `CUR_poly` channels are configured into the ADC2 regular group107- Continuous Conversion Mode: `Disabled`108- Discontinuous Conversion Mode: `Disabled`109- DMA Continuous Requests: `Disabled`110- End Of Conversion Selection: `EOC flag at the end of single channel conversion`111- Number Of Conversion: set this to the number of `CUR_poly` channels actually configured into the ADC2 regular group112- External Trigger Conversion Source: `Regular Conversion launched by software`113- External Trigger Conversion Edge: `None`114- Rank:115 - when one `CUR_poly` channel is configured, use `Rank = 1`116 - when multiple `CUR_poly` channels are configured, assign sequential regular ranks starting at `1`117- Injected Number Of Conversions: `0`118- Enable `ADC1, ADC2 and ADC3 global interrupts` in NVIC with preemption priority `0` and sub priority `0`119120### Additional ADC3 inputs121Configure the following two pins as analog `ADC3` inputs and label them exactly as listed:122123- `PA3` -> `ADC3_IN3` -> `lt3763_cur`124- `PF5` -> `ADC3_IN15` -> `ADC_VBAT_TMP`125126Requirements for these ADC inputs (BMSv31-style ADC3 workflow):127- Configure each listed pin as `Analog`.128- Use `No pull-up and no pull-down`.129- Apply the exact labels `lt3763_cur` and `ADC_VBAT_TMP`.130- Use `ADC3` for both channels.131- Preserve any existing `ADC3` configuration unless the user explicitly asks to change sampling sequences, trigger sources, DMA, scan mode, or conversion timing.132- 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.133- Keep pin mapping for both channels, but do not require both channels to be simultaneously configured in the ADC3 regular group.134- 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`.135- 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.136- ADC3 working mode must follow BMSv31 style:137 - initialize ADC3 as single regular conversion (`Scan Conversion Mode = Disabled`, `Number Of Conversion = 1`, `Rank = 1`)138 - keep `Continuous Conversion Mode = Disabled`139 - keep `Discontinuous Conversion Mode = Disabled`140 - keep `DMA Continuous Requests = Disabled`141 - keep `End Of Conversion Selection = EOC flag at the end of single channel conversion`142 - use software trigger (`External Trigger Conversion Source = Regular Conversion launched by software`, `External Trigger Conversion Edge = None`)143 - do channel selection at runtime by reconfiguring `sConfig.Channel` before each conversion (e.g. switch between `ADC_CHANNEL_3` and `ADC_CHANNEL_15`)144145## Execution steps1461. Detect the local CubeMX version and confirm the project `.ioc` header is not stamped with a newer version than the installed tool.1472. Open the existing `.ioc` project. Do not replace it with a newly created project.1483. Compare the existing project configuration against the configuration explicitly listed in this skill.1494. Modify only the listed configuration items that differ:150 - the `SPI3` mode and parameters listed above151 - the twelve named GPIO output definitions listed above152 - the six PWM pin assignments, timer channel mappings, timer base settings, and default duty-cycle settings listed above153 - the six `CUR_poly` ADC input pin assignments, analog modes, labels, required ADC2 channel mappings, and ADC parameters listed above154 - the two additional `ADC3` input pin assignments, analog modes, labels, and required ADC3 channel mappings listed above155 - 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 selected156 - 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`157 - for ADC3, keep the two pin mappings but configure ADC3 peripheral as single-conversion runtime-switch mode (BMSv31 style), not fixed multi-channel scan sequence1585. 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.1596. If any requested pin conflicts with an existing peripheral assignment, stop and report the conflict instead of silently remapping the hardware.1607. Regenerate code using the installed CubeMX while preserving user code sections.161 - This is mandatory after any `.ioc` change. Do not skip regeneration.1628. Validate the generated result before finishing:163 - `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.164 - `Core/Src/gpio.c` initializes the required `GPIOE`, `GPIOF`, and `GPIOG` chip-select pins as outputs.165 - `Core/Inc/main.h` exports the requested pin names and ports.166 - `Core/Src/tim.c` contains `MX_TIM1_Init()` and `MX_TIM3_Init()` with a `10 kHz` PWM base derived from the project timer clocks.167 - The generated compare values default to `50%` duty cycle for `pwm_polyctl1..6`.168 - The generated GPIO/pin metadata maps `PA9`, `PA8`, `PC9`, `PC8`, `PC7`, and `PC6` to the requested timer channels.169 - 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`.170 - The generated GPIO/pin metadata maps `PA3` and `PF5` to `ADC3_IN3` and `ADC3_IN15` with labels `lt3763_cur` and `ADC_VBAT_TMP`.171 - 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`.172 - The ADC2 regular group explicitly includes the requested `CUR_poly` channels rather than only setting the pins to analog input mode.173 - `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.174 - 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.175 - 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.176 - 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.177 - 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.178 - `Core/Src/adc.c` (or generated ADC3 init code) uses single regular conversion style for ADC3: scan disabled and number-of-conversion = 1.179 - ADC3 channel usage follows runtime channel reconfiguration style instead of fixed two-channel scan sequence.180 - `ADC3` `IN15` metadata must not overwrite or corrupt the existing `ADC2_IN15` representation used for `PC5`.181 - The generated GPIO settings for the six ADC pins remain `Analog mode` with `No pull-up and no pull-down`.182 - The generated GPIO settings for `PA3` and `PF5` remain `Analog mode` with `No pull-up and no pull-down`.183 - The NVIC enables `ADC1, ADC2 and ADC3 global interrupts` with preemption priority `0` and sub priority `0`.184 - 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`.185 - The `.ioc` still opens in the locally installed CubeMX version.1869. Run `cmake --preset Debug`.18710. Run `cmake --build --preset Debug`.18811. Confirm the expected ELF exists under `build/Debug/`.18912. Treat the task as failed if code generation was not executed or if build is not successful. Do not report completion in that case.190191## Notes & guardrails192- Do not infer CubeMX compatibility from memory. Detect the installed version each time.193- Do not hand-edit generated C source first and then try to backfill the `.ioc`; the `.ioc` is the source of truth.194- Do not treat missing detail in this skill as permission to normalize or simplify the rest of the project.195- Do not remove or rewrite existing project configuration that is outside the explicit scope of this skill.196- Do not rename the GPIO labels. They must remain `SPISW_nCS1..6` and `SPIADC_nCS1..6`.197- Do not rename the ADC labels. They must remain `CUR_poly1..6`.198- Do not rename the additional ADC3 labels. They must remain `lt3763_cur` and `ADC_VBAT_TMP`.199- Do not guess PWM frequency parameters from screenshots alone. Derive PSC/ARR/CCR from the actual timer clock in the target project.200- 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.201- 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.202- 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.203- Do not force ADC3 into fixed multi-channel scan mode for these two channels when BMSv31-style behavior is requested.204- 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.205- 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.206- For `_nCS` lines, prefer reset state high so external devices stay deselected after boot.207- If CubeMX generation removes or rewrites required user code outside the modified peripherals, stop and report before making manual source patches.208- 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.209- Do not mark the task complete unless both conditions are met: CubeMX code generation completed successfully, and the project build completed successfully.