返事がない。ただの屍のようだ。
CubeMXでstm32f4-discovery用のサンプルコードを吐かせてステップ実行すると、HAL_Init()の後にある
SystemClock_Config();
で反応が帰ってこない。これは中で呼ばれている HAL_RCC_OscConfig() がエラーを返すから。
HAL_RCC_OscConfig() が定義されている stm32f4xx_hal_rc.c の541行目あたり
pll_config = RCC->PLLCFGR;
...
//[1]
if (((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_OFF) ||
(READ_BIT(pll_config, RCC_PLLCFGR_PLLSRC) != RCC_OscInitStruct->PLL.PLLSource) ||
(READ_BIT(pll_config, RCC_PLLCFGR_PLLM) != (RCC_OscInitStruct->PLL.PLLM) << RCC_PLLCFGR_PLLM_Pos) ||
(READ_BIT(pll_config, RCC_PLLCFGR_PLLN) != (RCC_OscInitStruct->PLL.PLLN) << RCC_PLLCFGR_PLLN_Pos) ||
(READ_BIT(pll_config, RCC_PLLCFGR_PLLP) != (((RCC_OscInitStruct->PLL.PLLP >> 1U) - 1U)) << RCC_PLLCFGR_PLLP_Pos) ||
(READ_BIT(pll_config, RCC_PLLCFGR_PLLQ) != (RCC_OscInitStruct->PLL.PLLQ << RCC_PLLCFGR_PLLQ_Pos)))
のチェックで、PLLの設定レジスタPLLCFGRが意図した設定になっていないため、エラーが返ってくる。
どうしてそうなった
PLLの設定レジスタPLLFGRへの書き込みはstm32f4xx_hal_rc.cの492行目
//[2]
WRITE_REG(RCC->PLLCFGR, (RCC_OscInitStruct->PLL.PLLSource | \
RCC_OscInitStruct->PLL.PLLM | \
(RCC_OscInitStruct->PLL.PLLN << RCC_PLLCFGR_PLLN_Pos) | \
(((RCC_OscInitStruct->PLL.PLLP >> 1U) - 1U) << RCC_PLLCFGR_PLLP_Pos) | \
(RCC_OscInitStruct->PLL.PLLQ << RCC_PLLCFGR_PLLQ_Pos)));
で行われている。しかしここを通過するには465行目の
//[3]
if (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_CFGR_SWS_PLL)
のチェックで、RCC_CFGRのSWSレジスタがPLL以外に指定されていないといけない。
デフォルトがPLLになっている、リセットでクリアされない、など色々要因はあると思うがここは深掘りしていない。しかしどういう事情であれ、一旦このレジスタでPLLが設定されると、以後レジスタの設定はシレっとスキップされてしまう。
じゃあどうしよう?
これを避けるには、main.cで予めRCC_CFGRのSWSレジスタをHSEに倒しておくのが良かった。
main.cの87行目あたりにユーザが書いても変更されない区画があるので、そこに
/* USER CODE BEGIN Init */
__HAL_RCC_SYSCLK_CONFIG(RCC_SYSCLKSOURCE_HSE);
/* USER CODE END Init */
とかして、[2]のチェックにいく手前でSWSビットをPLL以外とする。これでPLL設定ルーチンがスキップされなくなるので、ことなきを得る。
が、これって文句出てないのだろうか??