moonglow/pcan_pro_x

HSE frequency auto-detect?

rusefillc opened this issue · 1 comments

Any chance for HSE frequency auto detect in light of https://rusefi.com/forum/viewtopic.php?f=13&t=2243?

rusEFI has that like this

static constexpr float rtcpreDivider = 31;

// This only works if you're using the PLL as the configured clock source!
static_assert(STM32_SW == RCC_CFGR_SW_PLL);

static void enableTimer() {
	RCC->APB2ENR |= RCC_APB2ENR_TIM11EN;
}

static void disableTimer() {
	RCC->APB2ENR &= ~RCC_APB2ENR_TIM11EN;
}

static void reprogramPll(uint8_t roundedHseMhz) {
	// Switch back to HSI to configure PLL
	// clear SW to use HSI
	RCC->CFGR &= ~RCC_CFGR_SW;

	// Stop the PLL
	RCC->CR &= ~RCC_CR_PLLON;

	// Mask out the old PLLM and PLLSRC
	RCC->PLLCFGR &= ~(RCC_PLLCFGR_PLLM_Msk | RCC_PLLCFGR_PLLSRC_Msk);

	// Stick in the new PLLM value
	RCC->PLLCFGR |= (roundedHseMhz << RCC_PLLCFGR_PLLM_Pos) & RCC_PLLCFGR_PLLM_Msk;
	// Set PLLSRC to HSE
	RCC->PLLCFGR |= RCC_PLLCFGR_PLLSRC_HSE;

	// Reenable PLL, wait for lock
	RCC->CR |= RCC_CR_PLLON;
	while (!(RCC->CR & RCC_CR_PLLRDY));

	// Switch clock source back to PLL
	RCC->CFGR &= ~RCC_CFGR_SW;
	RCC->CFGR |= RCC_CFGR_SW_PLL;
	while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2));
}

// __late_init runs after bss/zero initialziation, but before static constructors and main
extern "C" void __late_init() {
	// Set RTCPRE to /31 - just set all the bits
	RCC->CFGR |= RCC_CFGR_RTCPRE_Msk;

	// Turn on timer
	enableTimer();

	// Remap to connect HSERTC to CH1
#ifdef STM32H7XX
	// TI1SEL = 2, HSE_1MHz
	TIMER->TISEL = TIM_TISEL_TI1SEL_1;
#elif defined(STM32F4XX)
	TIMER->OR = TIM_OR_TI1_RMP_1;
#else
	// the definition has a different name on F7 for whatever reason
	TIMER->OR = TIM11_OR_TI1_RMP_1;
#endif

	// Enable capture on channel 1
	TIMER->CCMR1 = TIM_CCMR1_CC1S_0;
	TIMER->CCER = TIM_CCER_CC1E;

	// Start timer
	TIMER->CR1 |= TIM_CR1_CEN;

	// Measure HSE against SYSCLK
	auto hseCounts = getTimerCounts(10);

	// Turn off timer now that we're done with it
	disableTimer();

	float hseFrequencyHz = 10 * rtcpreDivider * STM32_TIMCLK2 / hseCounts;

	hseFrequencyMhz = hseFrequencyHz / 1e6;
	autoDetectedRoundedMhz = efiRound(hseFrequencyMhz, 1);

	reprogramPll(autoDetectedRoundedMhz);
}

It useless for many cases, as examples your hardware is not used same LIN/CAN/USB/LED pins and so on. Automatic HSE detection is nice feature ,but it does not solve others problem.