In many STM32 dual-clock peripherals, the kernel clock is enabled together with APB clock by a single bit in respective RCC_APBxENRx register. Also, if kernel clock can be selected from multiple choices, this selection is often done in a specialized RCC register (ST confusingly uses various names for this register in different families, including RCC_CFGRx, RCC_DCKCFGRx, RCC_CCIPRx), and the default selection is usually the APB clock. This allows to ignore the existence of separate kernel clock for most users, who don't need a different/asynchronous kernel clock for the peripherals, and then the handling of a given peripheral is identical to models where the same peripheral has single clock.
However, this is not always the case, and there are exceptions to this "rule".
In description of peripherals, the fact that kernel clock source is selected in RCC, is sometimes confusingly described as clock being selected/generated "at product level". This is consequence of manuals being compiled from separately written chapters (in the same manner as the chip itself is compiled from separately designed IP blocks), with little attention paid to adjust the chapters to given STM32 model and to unify terminology/signal names.
Here are some examples of maybe surprising kernel clock enable/selection methods:
- ADC is perhaps the most varying peripheral across STM32 families, and there are also various treatments of its kernel clock. Usually, it's selected in ADC itself (ADCx_CFGRx.CKMODE), in multi-ADC models in the common ADC control register (ADC_CCR.CKMODE); although in some cases there's also a secondary selection within RCC (if asynchronous clock is chosen). Kernel clock does not have a conspicuous separate enable bit, but it's probably gated by bits which are described to power the ADC on (ADON, ADVREFEN).
- ETH has dedicated input pins for clocks (ETH_MII_TX_CLK, ETH_MII_RX_CLK/ETH_RMII_REF_CLK) so it would appear that there's no need for selection, but the RMII/MII switch in SYSCFG impacts the treatment of the clock for the respective interface mode (in RMII mode, both Rx and Tx clocks are generated from the same single input), so it can't be omitted when using RMII instead of MII. Slightly surprisingly, ETH has not only peripheral (in this case AHB rather than APB) clock enable bit in RCC_AHBxENR, but in the same RCC_AHBxENR also dedicated enable bits for both kernel clocks (ETHMACTXEN/ETHMACRXEN), and even a third clock enable, ETHMACPTPEN, should the PTP feature of ETH be used.
- OTG_HS if used with external PHY, uses pin OTG_HS_ULPI_CK as kernel clock. It also has a separate enable bit, RCC_AHB1ENR.OTGHSULPIEN.
- in 'F723, the built-in USB HS PHY has a dedicated clock+power control unit, USBPHYC, so that's where the OTG HS kernel clock is set up (from a dedicated PLL) and enabled. However, the register portion of USBPHYC unit has its own APB enable bit in RCC_APB2ENR.
- in the combined SPI/I2S unit, the registers portion and kernel of SPI is clocked from APB clock, but I2S kernel has a separate clock. This in 'F0 is derived from SYSCLK, in 'F3 it can be selected between SYSCLK and I2S_CKIN pin, and in 'F4/'F7 can be selected between I2S_CKIN pin and a dedicated PLL. Source selection is controlled by RCC_CFGR.I2SSRC bit, while one of SPIx_I2SCFGR.I2SMOD/I2SE bits (or AND of both) serves as I2S kernel clock enable.
- RTC is in the VBAT (backup) power domain, and its kernel clock is selected (from LSE, LSI and HSE/32) and enabled in RCC_BDCR. Once selected, this selection can be changed only after a backup-domain reset. In some STM32 models, RTC has also a separate register-domain (APB) clock enable bit.
- some peripherals (e.g. SAI) function as clock-slave, i.e. the clock from external master serves as kernel clock. It appears, that some of these peripherals' implementation still requires "internal" kernel clock to be present and of a reasonably high frequency, as it is used in the synchronizer. This functionality is poorly documented.