Skip to content

Reduce flash size: optional CLK6/7 gate and shared PLL/init code - #117

Open
NT7S wants to merge 3 commits into
masterfrom
cursor/flash-size-refactor-9b93
Open

NT7S wants to merge 3 commits into
masterfrom
cursor/flash-size-refactor-9b93

Conversation

@NT7S

@NT7S NT7S commented Nov 8, 2026

Copy link
Copy Markdown
Member

Targeted flash-size refactor with no API change.

Changes

  • 9dcdd2f: optional SI5351_NO_CLK67 compile-time gate. It removes CLK6/7 support for builds that don't need it. Pass it as a compiler define (e.g. compiler.cpp.extra_flags=-DSI5351_NO_CLK67), not as a #define in the sketch. In a gated build, CLK6/7 calls return 1 and don't touch the registers.
  • b4a6c3b: set_pll() is now the only PLL programming path, including VCXO. init() and reset() use single loops, and set_correction() is noinline.

Size (Uno, arduino:avr 1.8.6)

  • Default bench sketch: 17,746 B (55%)
  • Gated: 16,568 B (51%)
  • flash/budgets.txt is set to these sizes.

Verification

  • Local suite on the box: run_v231_checks.sh --src, including an I2C transcript equivalence check against v2.4.2 (f885fca). Also passed: prove_v242_negative.sh and flash/check_flash_budget.sh.
  • Hardware: a 25-step bench sketch on an Si5351A covered init/reset, CLK0 at 4 kHz to 14 MHz, correction, PLLA/PLLB, PLL sharing and re-planning, CLK2 at 125 MHz, manual mode, output enable/drive, and CLK6/7. Every step passed, which Jason confirmed. The first run of the CLK6/7 step used a request the library rejects (CLK7 at 20 MHz after CLK6 at 10 MHz needs an odd divider). v2.4.2 behaves the same way, so the sketch was fixed and that step passed.
  • The gated build is checked for compile and size only, not on hardware. VCXO wasn't bench-tested because it needs an Si5351B.

cursoragent and others added 2 commits November 8, 2026 02:35
Defining SI5351_NO_CLK67 leaves out multisynth67_calc and the CLK6/CLK7
branches in set_freq, set_freq_manual, set_ms, pll_update, and ms_div.
Without the macro the public API and behavior stay the same. The Uno
flash check compiles the gated runtime sketch alongside the existing
ones and locks it at 10442 bytes.

Co-authored-by: Jason Milldrum <NT7S@users.noreply.github.com>
set_pll() is now the only copy of pll_calc, the parameter write, and
pll_update, including the VCXO parameter bytes. pll_calc uses one
feedback division for the normal and VCXO paths, both of which divide
by 1000000. init() and reset() walk the two references, both PLLs, and
the eight clocks in single loops, and set_correction() is noinline so
that sequence is not duplicated when init() is inlined into main.
Uno ceilings are now min_const 10202, min_runtime 10930, and the gated
runtime sketch 9836.

Co-authored-by: Jason Milldrum <NT7S@users.noreply.github.com>
@github-actions

github-actions Bot commented Nov 8, 2026

Copy link
Copy Markdown

Memory usage change @ b4a6c3b

Board flash % RAM for global variables %
arduino:avr:uno 💚 -642 - -540 -1.99 - -1.67 0 - 0 0.0 - 0.0
esp32:esp32:esp32 💚 -308 - -200 -0.02 - -0.02 0 - 0 0.0 - 0.0
arduino:samd:mkrzero 💚 -256 - -124 -0.1 - -0.05 0 - 0 0.0 - 0.0
rp2040:rp2040:rpipico 💚 -296 - -176 -0.01 - -0.01 0 - 0 0.0 - 0.0
Click for full report table
Board examples/si5351_calibration
flash
% examples/si5351_calibration
RAM for global variables
% examples/si5351_clk67_example
flash
% examples/si5351_clk67_example
RAM for global variables
% examples/si5351_example
flash
% examples/si5351_example
RAM for global variables
% examples/si5351_ext_ref
flash
% examples/si5351_ext_ref
RAM for global variables
% examples/si5351_outputs
flash
% examples/si5351_outputs
RAM for global variables
% examples/si5351_phase
flash
% examples/si5351_phase
RAM for global variables
% examples/si5351_sweeper
flash
% examples/si5351_sweeper
RAM for global variables
% examples/si5351_vcxo
flash
% examples/si5351_vcxo
RAM for global variables
%
arduino:avr:uno -542 -1.68 0 0.0 -628 -1.95 0 0.0 -586 -1.82 0 0.0 -540 -1.67 0 0.0 -628 -1.95 0 0.0 -632 -1.96 0 0.0 -618 -1.92 0 0.0 -642 -1.99 0 0.0
esp32:esp32:esp32 -304 -0.02 0 0.0 -304 -0.02 0 0.0 -304 -0.02 0 0.0 -304 -0.02 0 0.0 -304 -0.02 0 0.0 -308 -0.02 0 0.0 -304 -0.02 0 0.0 -200 -0.02 0 0.0
arduino:samd:mkrzero -256 -0.1 0 0.0 -256 -0.1 0 0.0 -252 -0.1 0 0.0 -252 -0.1 0 0.0 -252 -0.1 0 0.0 -252 -0.1 0 0.0 -252 -0.1 0 0.0 -124 -0.05 0 0.0
rp2040:rp2040:rpipico -296 -0.01 0 0.0 -296 -0.01 0 0.0 -296 -0.01 0 0.0 -296 -0.01 0 0.0 -296 -0.01 0 0.0 -296 -0.01 0 0.0 -296 -0.01 0 0.0 -176 -0.01 0 0.0
Click for full report CSV
Board,examples/si5351_calibration<br>flash,%,examples/si5351_calibration<br>RAM for global variables,%,examples/si5351_clk67_example<br>flash,%,examples/si5351_clk67_example<br>RAM for global variables,%,examples/si5351_example<br>flash,%,examples/si5351_example<br>RAM for global variables,%,examples/si5351_ext_ref<br>flash,%,examples/si5351_ext_ref<br>RAM for global variables,%,examples/si5351_outputs<br>flash,%,examples/si5351_outputs<br>RAM for global variables,%,examples/si5351_phase<br>flash,%,examples/si5351_phase<br>RAM for global variables,%,examples/si5351_sweeper<br>flash,%,examples/si5351_sweeper<br>RAM for global variables,%,examples/si5351_vcxo<br>flash,%,examples/si5351_vcxo<br>RAM for global variables,%
arduino:avr:uno,-542,-1.68,0,0.0,-628,-1.95,0,0.0,-586,-1.82,0,0.0,-540,-1.67,0,0.0,-628,-1.95,0,0.0,-632,-1.96,0,0.0,-618,-1.92,0,0.0,-642,-1.99,0,0.0
esp32:esp32:esp32,-304,-0.02,0,0.0,-304,-0.02,0,0.0,-304,-0.02,0,0.0,-304,-0.02,0,0.0,-304,-0.02,0,0.0,-308,-0.02,0,0.0,-304,-0.02,0,0.0,-200,-0.02,0,0.0
arduino:samd:mkrzero,-256,-0.1,0,0.0,-256,-0.1,0,0.0,-252,-0.1,0,0.0,-252,-0.1,0,0.0,-252,-0.1,0,0.0,-252,-0.1,0,0.0,-252,-0.1,0,0.0,-124,-0.05,0,0.0
rp2040:rp2040:rpipico,-296,-0.01,0,0.0,-296,-0.01,0,0.0,-296,-0.01,0,0.0,-296,-0.01,0,0.0,-296,-0.01,0,0.0,-296,-0.01,0,0.0,-296,-0.01,0,0.0,-176,-0.01,0,0.0

Arduino IDE users cannot pass per-sketch compiler flags, and a #define in
the sketch did not reach si5351.cpp. The CLK6/7-only code now lives in
weak member functions (set_freq67, ms67_div, set_ms67). When a sketch
defines SI5351_NO_CLK67 before #include <si5351.h>, the header adds stubs
that replace them, and the linker drops the originals. The compiler-flag
opt-out still works. No public API or constructor change.

Opt-out behavior is identical to the compiler-flag build (native harness,
1386 runs, byte-identical transcripts). Default builds keep 0 differing
runs vs v2.4.2 and get 62 bytes smaller on the Uno (CLK6/7 R-divider
handling moved out of ms_div).

Uno flash (arduino-cli 1.5.1, arduino:avr 1.8.6): min_runtime 10868
default, 9870 with the sketch #define, 9836 with the flag. Adds a
min_runtime_sketch_no_clk67 budget (9870) that fails at 10930 when the
define is ignored, tightens min_const/min_runtime to 10140/10868, and
documents the opt-out in the README.
@github-actions

github-actions Bot commented Nov 8, 2026

Copy link
Copy Markdown

Memory usage change @ e7dfd34

Board flash % RAM for global variables %
arduino:avr:uno 💚 -704 - -562 -2.18 - -1.74 0 - 0 0.0 - 0.0
esp32:esp32:esp32 💚 -264 - -156 -0.02 - -0.01 0 - 0 0.0 - 0.0
arduino:samd:mkrzero 💚 -264 - -124 -0.1 - -0.05 0 - 0 0.0 - 0.0
rp2040:rp2040:rpipico 💚 -296 - -176 -0.01 - -0.01 0 - 0 0.0 - 0.0
Click for full report table
Board examples/si5351_calibration
flash
% examples/si5351_calibration
RAM for global variables
% examples/si5351_clk67_example
flash
% examples/si5351_clk67_example
RAM for global variables
% examples/si5351_example
flash
% examples/si5351_example
RAM for global variables
% examples/si5351_ext_ref
flash
% examples/si5351_ext_ref
RAM for global variables
% examples/si5351_outputs
flash
% examples/si5351_outputs
RAM for global variables
% examples/si5351_phase
flash
% examples/si5351_phase
RAM for global variables
% examples/si5351_sweeper
flash
% examples/si5351_sweeper
RAM for global variables
% examples/si5351_vcxo
flash
% examples/si5351_vcxo
RAM for global variables
%
arduino:avr:uno -604 -1.87 0 0.0 -698 -2.16 0 0.0 -640 -1.98 0 0.0 -562 -1.74 0 0.0 -690 -2.14 0 0.0 -694 -2.15 0 0.0 -680 -2.11 0 0.0 -704 -2.18 0 0.0
esp32:esp32:esp32 -248 -0.02 0 0.0 -248 -0.02 0 0.0 -248 -0.02 0 0.0 -248 -0.02 0 0.0 -248 -0.02 0 0.0 -264 -0.02 0 0.0 -248 -0.02 0 0.0 -156 -0.01 0 0.0
arduino:samd:mkrzero -264 -0.1 0 0.0 -264 -0.1 0 0.0 -260 -0.1 0 0.0 -260 -0.1 0 0.0 -260 -0.1 0 0.0 -252 -0.1 0 0.0 -264 -0.1 0 0.0 -124 -0.05 0 0.0
rp2040:rp2040:rpipico -288 -0.01 0 0.0 -288 -0.01 0 0.0 -288 -0.01 0 0.0 -288 -0.01 0 0.0 -296 -0.01 0 0.0 -288 -0.01 0 0.0 -296 -0.01 0 0.0 -176 -0.01 0 0.0
Click for full report CSV
Board,examples/si5351_calibration<br>flash,%,examples/si5351_calibration<br>RAM for global variables,%,examples/si5351_clk67_example<br>flash,%,examples/si5351_clk67_example<br>RAM for global variables,%,examples/si5351_example<br>flash,%,examples/si5351_example<br>RAM for global variables,%,examples/si5351_ext_ref<br>flash,%,examples/si5351_ext_ref<br>RAM for global variables,%,examples/si5351_outputs<br>flash,%,examples/si5351_outputs<br>RAM for global variables,%,examples/si5351_phase<br>flash,%,examples/si5351_phase<br>RAM for global variables,%,examples/si5351_sweeper<br>flash,%,examples/si5351_sweeper<br>RAM for global variables,%,examples/si5351_vcxo<br>flash,%,examples/si5351_vcxo<br>RAM for global variables,%
arduino:avr:uno,-604,-1.87,0,0.0,-698,-2.16,0,0.0,-640,-1.98,0,0.0,-562,-1.74,0,0.0,-690,-2.14,0,0.0,-694,-2.15,0,0.0,-680,-2.11,0,0.0,-704,-2.18,0,0.0
esp32:esp32:esp32,-248,-0.02,0,0.0,-248,-0.02,0,0.0,-248,-0.02,0,0.0,-248,-0.02,0,0.0,-248,-0.02,0,0.0,-264,-0.02,0,0.0,-248,-0.02,0,0.0,-156,-0.01,0,0.0
arduino:samd:mkrzero,-264,-0.1,0,0.0,-264,-0.1,0,0.0,-260,-0.1,0,0.0,-260,-0.1,0,0.0,-260,-0.1,0,0.0,-252,-0.1,0,0.0,-264,-0.1,0,0.0,-124,-0.05,0,0.0
rp2040:rp2040:rpipico,-288,-0.01,0,0.0,-288,-0.01,0,0.0,-288,-0.01,0,0.0,-288,-0.01,0,0.0,-296,-0.01,0,0.0,-288,-0.01,0,0.0,-296,-0.01,0,0.0,-176,-0.01,0,0.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants