# HG changeset patch # User Paul Boddie # Date 1694996510 -7200 # Node ID eb796e0d2f904d1092f999f43bf26e5c8a0fb35c # Parent 5a914ca513df7806b4192a341873a78c14335b05 Introduced a base class for divided clocks, changing the generic clock to be a plain undivided clock. Eliminated special undefined objects and fixed object definitions, avoiding the absurd "most vexing parse" problem that C++ has. diff -r 5a914ca513df -r eb796e0d2f90 pkg/devices/lib/cpm/include/cpm-common.h --- a/pkg/devices/lib/cpm/include/cpm-common.h Mon Sep 18 00:41:04 2023 +0200 +++ b/pkg/devices/lib/cpm/include/cpm-common.h Mon Sep 18 02:21:50 2023 +0200 @@ -153,10 +153,6 @@ // Clock source frequency. uint32_t get_frequency(Cpm_regs ®s); - - // Undefined source object. - - static Source undefined; }; @@ -208,10 +204,6 @@ int have_clock(Cpm_regs ®s); void start_clock(Cpm_regs ®s); void stop_clock(Cpm_regs ®s); - - // Undefined control. - - static Control undefined; }; @@ -295,10 +287,6 @@ int get_parameters(Cpm_regs ®s, uint32_t parameters[]); void set_parameters(Cpm_regs ®s, uint32_t parameters[]); - - // Undefined divider. - - static Divider undefined; }; @@ -482,18 +470,18 @@ // Divided clock interface. -class Clock_divided : public Clock_active +class Clock_divided_base : public Clock_active { protected: virtual Divider_base &_get_divider() = 0; public: - explicit Clock_divided(Source source) + explicit Clock_divided_base(Source source) : Clock_active(source) { } - virtual ~Clock_divided(); + virtual ~Clock_divided_base(); virtual int get_parameters(Cpm_regs ®s, uint32_t parameters[]); virtual void set_parameters(Cpm_regs ®s, uint32_t parameters[]); @@ -507,7 +495,7 @@ // PLL description. -class Pll : public Clock_divided +class Pll : public Clock_divided_base { Control_pll _control; Divider_pll _divider; @@ -517,7 +505,7 @@ public: explicit Pll(Source source, Control_pll control, Divider_pll divider) - : Clock_divided(source), _control(control), _divider(divider) + : Clock_divided_base(source), _control(control), _divider(divider) { } @@ -532,9 +520,33 @@ -// Clock description. +// Plain clock description. + +class Clock : public Clock_active +{ + Control _control; + + virtual Control_base &_get_control() { return _control; } + +public: + explicit Clock(Source source, Control control) + : Clock_active(source), _control(control) + { + } -class Clock : public Clock_divided + explicit Clock(Source source) + : Clock_active(source) + { + } + + const char *clock_type() { return "clock"; } +}; + + + +// Divided clock description. + +class Clock_divided : public Clock_divided_base { Control _control; Divider _divider; @@ -543,9 +555,8 @@ virtual Divider_base &_get_divider() { return _divider; } public: - explicit Clock(Source source, Control control = Control::undefined, - Divider divider = Divider::undefined) - : Clock_divided(source), _control(control), _divider(divider) + explicit Clock_divided(Source source, Control control, Divider divider) + : Clock_divided_base(source), _control(control), _divider(divider) { } @@ -556,7 +567,7 @@ // I2S clock description. -class Clock_divided_i2s : public Clock_divided +class Clock_divided_i2s : public Clock_divided_base { Control _control; Divider_i2s _divider; @@ -566,7 +577,7 @@ public: explicit Clock_divided_i2s(Source source, Control control, Divider_i2s divider) - : Clock_divided(source), _control(control), _divider(divider) + : Clock_divided_base(source), _control(control), _divider(divider) { } diff -r 5a914ca513df -r eb796e0d2f90 pkg/devices/lib/cpm/src/common.cc --- a/pkg/devices/lib/cpm/src/common.cc Mon Sep 18 00:41:04 2023 +0200 +++ b/pkg/devices/lib/cpm/src/common.cc Mon Sep 18 02:21:50 2023 +0200 @@ -135,10 +135,6 @@ return 0; } -// Undefined source. - -Source Source::undefined; - // Clock control. @@ -203,10 +199,6 @@ _change_enable.set_field(regs, 1); } -// Undefined control. - -Control Control::undefined; - // PLL-specific control. @@ -305,10 +297,6 @@ set_divider(regs, parameters[0]); } -// Undefined divider. - -Divider Divider::undefined; - // Feedback (13-bit) multiplier. @@ -578,26 +566,26 @@ // Divided clock interface. -Clock_divided::~Clock_divided() +Clock_divided_base::~Clock_divided_base() { } // Output clock frequencies. uint32_t -Clock_divided::get_frequency(Cpm_regs ®s) +Clock_divided_base::get_frequency(Cpm_regs ®s) { return _get_divider().get_frequency(regs, get_source_frequency(regs)); } int -Clock_divided::get_parameters(Cpm_regs ®s, uint32_t parameters[]) +Clock_divided_base::get_parameters(Cpm_regs ®s, uint32_t parameters[]) { return _get_divider().get_parameters(regs, parameters); } void -Clock_divided::set_parameters(Cpm_regs ®s, uint32_t parameters[]) +Clock_divided_base::set_parameters(Cpm_regs ®s, uint32_t parameters[]) { _get_control().change_enable(regs); _get_divider().set_parameters(regs, parameters); diff -r 5a914ca513df -r eb796e0d2f90 pkg/devices/lib/cpm/src/x1600.cc --- a/pkg/devices/lib/cpm/src/x1600.cc Mon Sep 18 00:41:04 2023 +0200 +++ b/pkg/devices/lib/cpm/src/x1600.cc Mon Sep 18 02:21:50 2023 +0200 @@ -248,105 +248,108 @@ // Clock instances. -static Clock_passive clock_external; +static Clock_null clock_none; + +static Clock_passive clock_external; -static Clock_null clock_none; +// Note the use of extra parentheses due to the annoying C++ "most vexing parse" +// problem. See: https://en.wikipedia.org/wiki/Most_vexing_parse -static Clock clock_ahb2_apb(Source(mux_core, Clock_source_hclock2)), +static Clock clock_ahb2_apb(Source(mux_core, Clock_source_hclock2)), - clock_can0(Source(mux_bus, Clock_source_can0), - Control(Clock_gate_can0, Clock_change_enable_can0, Clock_busy_can0), - Divider(Clock_divider_can0)), - - clock_can1(Source(mux_bus, Clock_source_can1), - Control(Clock_gate_can1, Clock_change_enable_can1, Clock_busy_can1), - Divider(Clock_divider_can1)), - - clock_cdbus(Source(mux_dev, Clock_source_cdbus), - Control(Clock_gate_cdbus, Clock_change_enable_cdbus, Clock_busy_cdbus), - Divider(Clock_divider_cdbus)), - - clock_cim(Source(mux_dev, Clock_source_cim), - Control(Clock_gate_cim, Clock_change_enable_cim, Clock_busy_cim), - Divider(Clock_divider_cim)), - - clock_cpu(Source(mux_core, Clock_source_cpu), - Control(Field::undefined, Clock_change_enable_cpu, Clock_busy_cpu), - Divider(Clock_divider_cpu)), - - clock_ddr(Source(mux_core, Clock_source_ddr), - Control(Clock_gate_ddr, Clock_change_enable_ddr, Clock_busy_ddr), - Divider(Clock_divider_ddr)), - - clock_dma(Source(mux_pclock), Control(Clock_gate_dma), Divider::undefined), - - clock_hclock0(Source(mux_core, Clock_source_hclock0), - Control(Clock_gate_ahb0, Clock_change_enable_ahb0), - Divider(Clock_divider_hclock0)), - - clock_hclock2(Source(mux_ahb2_apb), - Control(Clock_gate_apb0, Clock_change_enable_ahb2), - Divider(Clock_divider_hclock2)), - - clock_i2c(Source(mux_pclock), Control(Clock_gate_i2c0), Divider::undefined), - - clock_i2c0(Source(mux_pclock), Control(Clock_gate_i2c0), Divider::undefined), - - clock_i2c1(Source(mux_pclock), Control(Clock_gate_i2c1), Divider::undefined), - - clock_lcd_pixel(Source(mux_dev, Clock_source_lcd), - Control(Clock_gate_lcd_pixel, Clock_change_enable_lcd, Clock_busy_lcd), - Divider(Clock_divider_lcd)), + clock_dma((Source(mux_pclock)), (Control(Clock_gate_dma))), + + clock_i2c((Source(mux_pclock)), (Control(Clock_gate_i2c0))), + + clock_i2c0((Source(mux_pclock)), (Control(Clock_gate_i2c0))), + + clock_i2c1((Source(mux_pclock)), (Control(Clock_gate_i2c1))), + + clock_main(Source(mux_core, Clock_source_main), + Control(Clock_gate_main)), + + clock_timer((Source(mux_pclock)), (Control(Clock_gate_timer))), + + clock_uart0((Source(mux_external)), (Control(Clock_gate_uart0))), + + clock_uart1((Source(mux_external)), (Control(Clock_gate_uart1))), + + clock_uart2((Source(mux_external)), (Control(Clock_gate_uart2))), + + clock_uart3((Source(mux_external)), (Control(Clock_gate_uart3))); - clock_mac(Source(mux_dev, Clock_source_mac), - Control(Clock_gate_gmac0, Clock_change_enable_mac, Clock_busy_mac), - Divider(Clock_divider_mac)), - - clock_main(Source(mux_core, Clock_source_main), - Control(Clock_gate_main)), - - clock_msc(Source(mux_dev, Clock_source_msc0), - Control(Clock_gate_msc0, Clock_change_enable_msc0, Clock_busy_msc0), - Divider(Clock_divider_msc0)), - - clock_msc0(Source(mux_dev, Clock_source_msc0), - Control(Clock_gate_msc0, Clock_change_enable_msc0, Clock_busy_msc0), - Divider(Clock_divider_msc0)), - - clock_msc1(Source(mux_dev, Clock_source_msc1), - Control(Clock_gate_msc1, Clock_change_enable_msc1, Clock_busy_msc1), - Divider(Clock_divider_msc1)), - - clock_pclock(Source(mux_ahb2_apb), - Control(Clock_gate_apb0, Field::undefined, Field::undefined), - Divider(Clock_divider_pclock)), - - clock_pwm(Source(mux_dev, Clock_source_pwm), - Control(Clock_gate_pwm, Clock_change_enable_pwm, Clock_busy_pwm), - Divider(Clock_divider_pwm)), - - clock_pwm0(Source(mux_dev, Clock_source_pwm), - Control(Clock_gate_pwm, Clock_change_enable_pwm, Clock_busy_pwm), - Divider(Clock_divider_pwm)), - - clock_sfc(Source(mux_dev, Clock_source_sfc), - Control(Clock_gate_sfc, Clock_change_enable_sfc, Clock_busy_sfc), - Divider(Clock_divider_sfc)), - - clock_ssi(Source(mux_dev, Clock_source_ssi), - Control(Clock_gate_ssi0, Clock_change_enable_ssi, Clock_busy_ssi), - Divider(Clock_divider_ssi)), - - clock_timer(Source(mux_pclock), Control(Clock_gate_timer), Divider::undefined), - - clock_uart0(Source(mux_external), Control(Clock_gate_uart0), Divider::undefined), - - clock_uart1(Source(mux_external), Control(Clock_gate_uart1), Divider::undefined), - - clock_uart2(Source(mux_external), Control(Clock_gate_uart2), Divider::undefined), - - clock_uart3(Source(mux_external), Control(Clock_gate_uart3), Divider::undefined); - +static Clock_divided clock_can0(Source(mux_bus, Clock_source_can0), + Control(Clock_gate_can0, Clock_change_enable_can0, Clock_busy_can0), + Divider(Clock_divider_can0)), + + clock_can1(Source(mux_bus, Clock_source_can1), + Control(Clock_gate_can1, Clock_change_enable_can1, Clock_busy_can1), + Divider(Clock_divider_can1)), + + clock_cdbus(Source(mux_dev, Clock_source_cdbus), + Control(Clock_gate_cdbus, Clock_change_enable_cdbus, Clock_busy_cdbus), + Divider(Clock_divider_cdbus)), + + clock_cim(Source(mux_dev, Clock_source_cim), + Control(Clock_gate_cim, Clock_change_enable_cim, Clock_busy_cim), + Divider(Clock_divider_cim)), + + clock_cpu(Source(mux_core, Clock_source_cpu), + Control(Field::undefined, Clock_change_enable_cpu, Clock_busy_cpu), + Divider(Clock_divider_cpu)), + + clock_ddr(Source(mux_core, Clock_source_ddr), + Control(Clock_gate_ddr, Clock_change_enable_ddr, Clock_busy_ddr), + Divider(Clock_divider_ddr)), + + clock_hclock0(Source(mux_core, Clock_source_hclock0), + Control(Clock_gate_ahb0, Clock_change_enable_ahb0), + Divider(Clock_divider_hclock0)), + + clock_hclock2(Source(mux_ahb2_apb), + Control(Clock_gate_apb0, Clock_change_enable_ahb2), + Divider(Clock_divider_hclock2)), + + clock_lcd_pixel(Source(mux_dev, Clock_source_lcd), + Control(Clock_gate_lcd_pixel, Clock_change_enable_lcd, Clock_busy_lcd), + Divider(Clock_divider_lcd)), + + clock_mac(Source(mux_dev, Clock_source_mac), + Control(Clock_gate_gmac0, Clock_change_enable_mac, Clock_busy_mac), + Divider(Clock_divider_mac)), + + clock_msc(Source(mux_dev, Clock_source_msc0), + Control(Clock_gate_msc0, Clock_change_enable_msc0, Clock_busy_msc0), + Divider(Clock_divider_msc0)), + + clock_msc0(Source(mux_dev, Clock_source_msc0), + Control(Clock_gate_msc0, Clock_change_enable_msc0, Clock_busy_msc0), + Divider(Clock_divider_msc0)), + + clock_msc1(Source(mux_dev, Clock_source_msc1), + Control(Clock_gate_msc1, Clock_change_enable_msc1, Clock_busy_msc1), + Divider(Clock_divider_msc1)), + + clock_pclock((Source(mux_ahb2_apb)), + (Control(Clock_gate_apb0)), + (Divider(Clock_divider_pclock))), + + clock_pwm(Source(mux_dev, Clock_source_pwm), + Control(Clock_gate_pwm, Clock_change_enable_pwm, Clock_busy_pwm), + Divider(Clock_divider_pwm)), + + clock_pwm0(Source(mux_dev, Clock_source_pwm), + Control(Clock_gate_pwm, Clock_change_enable_pwm, Clock_busy_pwm), + Divider(Clock_divider_pwm)), + + clock_sfc(Source(mux_dev, Clock_source_sfc), + Control(Clock_gate_sfc, Clock_change_enable_sfc, Clock_busy_sfc), + Divider(Clock_divider_sfc)), + + clock_ssi(Source(mux_dev, Clock_source_ssi), + Control(Clock_gate_ssi0, Clock_change_enable_ssi, Clock_busy_ssi), + Divider(Clock_divider_ssi)); + static Clock_divided_i2s clock_i2s0_rx(Source(mux_i2s, Clock_source_i2s), Control(Clock_gate_i2s0_rx, Clock_change_enable_i2s), Divider_i2s(Clock_divider_i2s0_m, Clock_divider_i2s0_n, @@ -357,20 +360,20 @@ Divider_i2s(Clock_divider_i2s1_m, Clock_divider_i2s1_n, Clock_divider_i2s1_d)); -static Pll clock_pll_A(Source(mux_external), - Control_pll(Pll_enable_A, Pll_stable_A, Pll_bypass_A), - Divider_pll(Pll_multiplier_A, Pll_input_division_A, - Pll_output_division0_A, Pll_output_division1_A)), +static Pll clock_pll_A(Source(mux_external), + Control_pll(Pll_enable_A, Pll_stable_A, Pll_bypass_A), + Divider_pll(Pll_multiplier_A, Pll_input_division_A, + Pll_output_division0_A, Pll_output_division1_A)), - clock_pll_E(Source(mux_external), - Control_pll(Pll_enable_E, Pll_stable_E, Pll_bypass_E), - Divider_pll(Pll_multiplier_E, Pll_input_division_E, - Pll_output_division0_E, Pll_output_division1_E)), + clock_pll_E(Source(mux_external), + Control_pll(Pll_enable_E, Pll_stable_E, Pll_bypass_E), + Divider_pll(Pll_multiplier_E, Pll_input_division_E, + Pll_output_division0_E, Pll_output_division1_E)), - clock_pll_M(Source(mux_external), - Control_pll(Pll_enable_M, Pll_stable_M, Pll_bypass_M), - Divider_pll(Pll_multiplier_M, Pll_input_division_M, - Pll_output_division0_M, Pll_output_division1_M)); + clock_pll_M(Source(mux_external), + Control_pll(Pll_enable_M, Pll_stable_M, Pll_bypass_M), + Divider_pll(Pll_multiplier_M, Pll_input_division_M, + Pll_output_division0_M, Pll_output_division1_M)); @@ -473,7 +476,7 @@ int Cpm_x1600_chip::get_parameters(enum Clock_identifiers clock, uint32_t parameters[]) { - Clock_divided *clk = dynamic_cast(clocks[clock]); + Clock_divided_base *clk = dynamic_cast(clocks[clock]); if (clk != NULL) return clk->get_parameters(_cpm_regs, parameters); @@ -484,7 +487,7 @@ void Cpm_x1600_chip::set_parameters(enum Clock_identifiers clock, uint32_t parameters[]) { - Clock_divided *clk = dynamic_cast(clocks[clock]); + Clock_divided_base *clk = dynamic_cast(clocks[clock]); if (clk != NULL) clk->set_parameters(_cpm_regs, parameters); @@ -540,7 +543,7 @@ // Switch to the MPLL and attempt to set the divider. - Clock *lcd = dynamic_cast(clocks[Clock_lcd_pixel]); + Clock_divided_base *lcd = dynamic_cast(clocks[Clock_lcd_pixel]); Clock_base *pll = clocks[Clock_pll_M]; if (lcd != NULL)