Skip to content

Commit

Permalink
πŸ§‘β€πŸ’» Define, apply F_CPU on HC32 (#27086)
Browse files Browse the repository at this point in the history
Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
  • Loading branch information
shadow578 and thinkyhead committed May 15, 2024
1 parent 6eedeae commit f320c2a
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 31 deletions.
9 changes: 7 additions & 2 deletions Marlin/src/HAL/HC32/app_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,12 @@
// redirect printf to host serial
#define REDIRECT_PRINTF_TO_SERIAL 1

// FIXME override F_CPU to PCLK1, as marlin freaks out otherwise
#define F_CPU (SYSTEM_CLOCK_FREQUENCIES.pclk1)
// F_CPU must be known at compile time, but on HC32F460 it's not.
// Thus we assume HCLK to be 200MHz, as that's what is configured in
// 'core_hook_sysclock_init' in 'sysclock.cpp'.
// If you face issues with this assumption, please double-check with the values
// printed by 'MarlinHAL::HAL_clock_frequencies_dump'.
// see also: HAL_TIMER_RATE in timers.h
#define F_CPU 200000000 // 200MHz HCLK

#endif // _HC32_APP_CONFIG_H_
4 changes: 2 additions & 2 deletions Marlin/src/HAL/HC32/sysclock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@ void core_hook_sysclock_init() {
#endif
#endif

// sysclk is now configured to 200 MHz PLL output
constexpr uint32_t sysclock = 200000000;
// sysclk is now configured according to F_CPU (i.e., 200MHz PLL output)
constexpr uint32_t sysclock = F_CPU;

// Setup clock divisors for sysclk = 200 MHz
// Note: PCLK1 is used for step+temp timers, and need to be kept at 50 MHz (until there is a better solution)
Expand Down
58 changes: 31 additions & 27 deletions Marlin/src/HAL/HC32/timers.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,44 +38,48 @@ extern Timer0 step_timer;
// Timer Configurations
//

// TODO: some calculations (step irq min_step_rate) require the timer rate to be known at compile time
// this is not possible with the HC32F460, as the timer rate depends on PCLK1
// as a workaround, PCLK1 = 50MHz is assumed (check with clock dump in MarlinHAL::init())
#define HAL_TIMER_RATE 50000000 // 50MHz
// #define HAL_TIMER_RATE TIMER0_BASE_FREQUENCY

// TODO: CYCLES_PER_MICROSECOND seems to be used by Marlin to calculate the number of cycles per microsecond in the timer ISRs
// by default, it uses F_CPU, but since that is not known at compile time for HC32, we overwrite it here
#undef CYCLES_PER_MICROSECOND
#define CYCLES_PER_MICROSECOND (HAL_TIMER_RATE / 1000000UL)
/**
* HAL_TIMER_RATE must be known at compile time since it's used to calculate
* STEPPER_TIMER_RATE, which is used in 'constexpr' calculations.
* On the HC32F460 the timer rate depends on PCLK1, which is derived from the
* system clock configured at runtime. As a workaround, we use the existing
* assumption of a 200MHz clock, defining F_CPU as 200000000, then configure PCLK1
* as F_CPU with a divider of 4 in 'sysclock.cpp::core_hook_sysclock_init'.
*
* If you face issues with this assumption, please double-check with the values
* printed by 'MarlinHAL::HAL_clock_frequencies_dump'.
*
* TODO: If the 'constexpr' requirement is ever lifted, use TIMER0_BASE_FREQUENCY instead
*/
#define HAL_TIMER_RATE (F_CPU / 4) // i.e., 50MHz
//#define HAL_TIMER_RATE TIMER0_BASE_FREQUENCY

// Temperature timer
#define TEMP_TIMER_NUM (&temp_timer)
#define TEMP_TIMER_PRIORITY DDL_IRQ_PRIORITY_02
#define TEMP_TIMER_PRESCALE 16ul
#define TEMP_TIMER_RATE 1000 // 1kHz
#define TEMP_TIMER_FREQUENCY TEMP_TIMER_RATE // Alias for Marlin
#define TEMP_TIMER_NUM (&temp_timer)
#define TEMP_TIMER_PRIORITY DDL_IRQ_PRIORITY_02
#define TEMP_TIMER_PRESCALE 16UL // 12.5MHz
#define TEMP_TIMER_RATE 1000 // 1kHz
#define TEMP_TIMER_FREQUENCY TEMP_TIMER_RATE // 1kHz also

// Stepper timer
#define STEP_TIMER_NUM (&step_timer)
#define STEP_TIMER_PRIORITY DDL_IRQ_PRIORITY_01
#define STEPPER_TIMER_PRESCALE 16ul
#define STEP_TIMER_NUM (&step_timer)
#define STEP_TIMER_PRIORITY DDL_IRQ_PRIORITY_00 // Top priority, nothing else uses it
#define STEPPER_TIMER_PRESCALE 16UL // 12.5MHz

// TODO: STEPPER_TIMER_RATE seems to work fine like this, but requires further testing...
#define STEPPER_TIMER_RATE (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE) // 50MHz / 16 = 3.125MHz
#define STEPPER_TIMER_TICKS_PER_US (STEPPER_TIMER_RATE / 1000000)
#define STEPPER_TIMER_RATE (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE) // 50MHz / 16 = 3.125MHz
#define STEPPER_TIMER_TICKS_PER_US (STEPPER_TIMER_RATE / 1000000UL) // Integer 3

// Pulse timer (== stepper timer)
#define PULSE_TIMER_NUM STEP_TIMER_NUM
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
#define PULSE_TIMER_NUM STEP_TIMER_NUM
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US

//
// Channel aliases
//
#define MF_TIMER_TEMP TEMP_TIMER_NUM
#define MF_TIMER_STEP STEP_TIMER_NUM
#define MF_TIMER_PULSE PULSE_TIMER_NUM
#define MF_TIMER_TEMP TEMP_TIMER_NUM
#define MF_TIMER_STEP STEP_TIMER_NUM
#define MF_TIMER_PULSE PULSE_TIMER_NUM

//
// HAL functions
Expand Down
7 changes: 7 additions & 0 deletions Marlin/src/inc/Warnings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -864,3 +864,10 @@
#if DISABLED(EDITABLE_STEPS_PER_UNIT)
#warning "EDITABLE_STEPS_PER_UNIT is required to enable G92 runtime configuration of steps-per-unit."
#endif

/**
* HC32 clock speed is hard-coded in Marlin
*/
#if defined(ARDUINO_ARCH_HC32) && F_CPU == 200000000
#warning "HC32 clock is assumed to be 200MHz. If this isn't the case for your board please submit a report so we can add support."
#endif

0 comments on commit f320c2a

Please sign in to comment.