/** @defgroup rcc_defines RCC Defines @brief Defined Constants and Types for the STM32H7xx Reset and Clock Control @ingroup STM32H7xx_defines @version 1.0.0 LGPL License Terms @ref lgpl_license */ /* * This file is part of the libopencm3 project. * * Copyright (C) 2019 Brian Viele * * This library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library. If not, see . */ #ifndef LIBOPENCM3_RCC_H #define LIBOPENCM3_RCC_H #include #include /**@{*/ /** @defgroup rcc_registers RCC Registers @{*/ #define RCC_CR MMIO32(RCC_BASE + 0x000) #define RCC_ICSCR MMIO32(RCC_BASE + 0x004) /* Y-devices only */ #define RCC_HSICFGR MMIO32(RCC_BASE + 0x004) /* V-devices only */ #define RCC_CRRCR MMIO32(RCC_BASE + 0x008) #define RCC_CSICFGR MMIO32(RCC_BASE + 0x00C) /* V-devices only */ #define RCC_CFGR MMIO32(RCC_BASE + 0x010) #define RCC_D1CFGR MMIO32(RCC_BASE + 0x018) #define RCC_D2CFGR MMIO32(RCC_BASE + 0x01C) #define RCC_D3CFGR MMIO32(RCC_BASE + 0x020) #define RCC_PLLCKSELR MMIO32(RCC_BASE + 0x028) #define RCC_PLLCFGR MMIO32(RCC_BASE + 0x02C) /* PLLs are 1-based, so reference macros to 1..3, using index 0 will give undefined behavior. */ #define RCC_PLLDIVR(n) MMIO32(RCC_BASE + 0x030 + (0x08 * ((n) - 1))) #define RCC_PLLFRACR(n) MMIO32(RCC_BASE + 0x030 + (0x08 * ((n) - 1))) #define RCC_PLL1DIVR RCC_PLLDIVR(1) #define RCC_PLL1FRACR RCC_PLLFRACR(1) #define RCC_PLL2DIVR RCC_PLLDIVR(2) #define RCC_PLL2FRACR RCC_PLLFRACR(2) #define RCC_PLL3DIVR RCC_PLLDIVR(3) #define RCC_PLL3FRACR RCC_PLLFRACR(3) #define RCC_D1CCIPR MMIO32(RCC_BASE + 0x04C) #define RCC_D2CCIP1R MMIO32(RCC_BASE + 0x050) #define RCC_D2CCIP2R MMIO32(RCC_BASE + 0x054) #define RCC_D3CCIPR MMIO32(RCC_BASE + 0x058) #define RCC_AHB1RSTR MMIO32(RCC_BASE + 0x080) #define RCC_AHB2RSTR MMIO32(RCC_BASE + 0x084) #define RCC_AHB3RSTR MMIO32(RCC_BASE + 0x07C) #define RCC_AHB4RSTR MMIO32(RCC_BASE + 0x088) #define RCC_APB1LRSTR MMIO32(RCC_BASE + 0x090) #define RCC_APB1HRSTR MMIO32(RCC_BASE + 0x094) #define RCC_APB2RSTR MMIO32(RCC_BASE + 0x098) #define RCC_APB3RSTR MMIO32(RCC_BASE + 0x08C) #define RCC_APB4RSTR MMIO32(RCC_BASE + 0x09C) #define RCC_AHB1ENR MMIO32(RCC_BASE + 0x0D8) #define RCC_AHB2ENR MMIO32(RCC_BASE + 0x0DC) #define RCC_AHB3ENR MMIO32(RCC_BASE + 0x0D4) #define RCC_AHB4ENR MMIO32(RCC_BASE + 0x0E0) #define RCC_APB1LENR MMIO32(RCC_BASE + 0x0E8) #define RCC_APB1HENR MMIO32(RCC_BASE + 0x0EC) #define RCC_APB2ENR MMIO32(RCC_BASE + 0x0F0) #define RCC_APB3ENR MMIO32(RCC_BASE + 0x0E4) #define RCC_APB4ENR MMIO32(RCC_BASE + 0x0F4) #define RCC_AHB1LPENR MMIO32(RCC_BASE + 0x100) #define RCC_AHB2LPENR MMIO32(RCC_BASE + 0x104) #define RCC_AHB4LPENR MMIO32(RCC_BASE + 0x108) #define RCC_APB1LLPENR MMIO32(RCC_BASE + 0x110) #define RCC_APB1HLPENR MMIO32(RCC_BASE + 0x114) #define RCC_APB2LPENR MMIO32(RCC_BASE + 0x118) #define RCC_APB3LPENR MMIO32(RCC_BASE + 0x10C) #define RCC_APB4LPENR MMIO32(RCC_BASE + 0x11C) #define RCC_BDCR MMIO32(RCC_BASE + 0x70) #define RCC_CSR MMIO32(RCC_BASE + 0x74) #define RCC_SSCGR MMIO32(RCC_BASE + 0x80) #define RCC_PLLI2SCFGR MMIO32(RCC_BASE + 0x84) #define RCC_PLLSAICFGR MMIO32(RCC_BASE + 0x88) #define RCC_DCKCFGR1 MMIO32(RCC_BASE + 0x8C) #define RCC_DCKCFGR2 MMIO32(RCC_BASE + 0x90) /**@}*/ /** @defgroup rcc_cr_values RCC_CR Values * @ingroup rcc_registers @{*/ #define RCC_CR_PLL3RDY BIT29 #define RCC_CR_PLL3ON BIT28 #define RCC_CR_PLL2RDY BIT27 #define RCC_CR_PLL2ON BIT26 #define RCC_CR_PLL1RDY BIT25 #define RCC_CR_PLL1ON BIT24 #define RCC_CR_HSECSSON BIT19 #define RCC_CR_HSEBYP BIT18 #define RCC_CR_HSERDY BIT17 #define RCC_CR_HSEON BIT16 #define RCC_CR_D2CKRDY BIT15 #define RCC_CR_D1CKRDY BIT14 #define RCC_CR_HSI48RDY BIT13 #define RCC_CR_HSI48ON BIT12 #define RCC_CR_CSIKERON BIT9 #define RCC_CR_CSIRDY BIT8 #define RCC_CR_CSION BIT7 #define RCC_CR_HSIDIVF BIT5 #define RCC_CR_HSIDIV_MASK (0x03) #define RCC_CR_HSIDIV_SHIFT 3 #define RCC_CR_HSIDIV(n) (((n) & RCC_CR_HSIDIV_MASK) << RCC_CR_HSIDIV_MASK) #define RCC_CR_HSIRDY BIT2 #define RCC_CR_HSIKERON BIT1 #define RCC_CR_HSION BIT0 /**@}*/ /** @defgroup rcc_cfgr_values RCC_CFGR Values * @ingroup rcc_registers @{*/ /* MCO2: Microcontroller clock output 2 */ #define RCC_CFGR_MCO2_MASK 0x7 #define RCC_CFGR_MCO2_SHIFT 29 #define RCC_CFGR_MCO2_SYSCLK 0x0 #define RCC_CFGR_MCO2_PLL2 0x1 #define RCC_CFGR_MCO2_HSE 0x2 #define RCC_CFGR_MCO2_PLL1 0x3 #define RCC_CFGR_MCO2_CSI 0x4 #define RCC_CFGR_MCO2_LSI 0x5 /* MCO1/2PRE: MCO Prescalers */ #define RCC_CFGR_MCOPRE_MASK 0xf #define RCC_CFGR_MCO2PRE_SHIFT 25 #define RCC_CFGR_MCO1PRE_SHIFT 18 #define RCC_CFGR_MCOPRE_DIV_NONE 0x0 #define RCC_CFGR_MCOPRE_DIV_BYP 0x1 #define RCC_CFGR_MCOPRE_DIV_2 0x2 #define RCC_CFGR_MCOPRE_DIV_3 0x3 #define RCC_CFGR_MCOPRE_DIV_4 0x4 /* Note: MCOPRE_DIV can go from 1 - 15 */ /* MCO1: Microcontroller clock output 1 */ #define RCC_CFGR_MCO1_MASK 0x7 #define RCC_CFGR_MCO1_SHIFT 22 #define RCC_CFGR_MCO1_HSI 0x0 #define RCC_CFGR_MCO1_LSE 0x1 #define RCC_CFGR_MCO1_HSE 0x2 #define RCC_CFGR_MCO1_PLL1 0x3 #define RCC_CFGR_MCO1_HSI48 0x4 #define RCC_CFGR_MCO_SHIFT RCC_CFGR_MCO1_SHIFT #define RCC_CFGR_MCO_MASK RCC_CFGR_MCO1_MASK /* RTCPRE: HSE division factor for RTC clock */ #define RCC_CFGR_RTCPRE_SHIFT 8 #define RCC_CFGR_RTCPRE_MASK 0x3f /* SWS: System clock switch status */ #define RCC_CFGR_SWS_SHIFT 3 #define RCC_CFGR_SWS_MASK 0x7 #define RCC_CFGR_SWS_HSI 0x0 #define RCC_CFGR_SWS_CSI 0x1 #define RCC_CFGR_SWS_HSE 0x2 #define RCC_CFGR_SWS_PLL1 0x3 /* SW: System clock switch */ #define RCC_CFGR_SW_SHIFT 0 #define RCC_CFGR_SW_MASK 0x7 #define RCC_CFGR_SW_HSI 0x0 #define RCC_CFGR_SW_CSI 0x1 #define RCC_CFGR_SW_HSE 0x2 #define RCC_CFGR_SW_PLL1 0x3 /**@}*/ /** @defgroup rcc_d1cfgr_values RCC_D1CFGR Values * @ingroup rcc_registers * @{*/ #define RCC_D1CFGR_D1CPRE_BYP 0x0 #define RCC_D1CFGR_D1CPRE_DIV2 0x8 #define RCC_D1CFGR_D1CPRE_DIV4 0x9 #define RCC_D1CFGR_D1CPRE_DIV8 0xA #define RCC_D1CFGR_D1CPRE_DIV16 0xB #define RCC_D1CFGR_D1CPRE_DIV64 0xC #define RCC_D1CFGR_D1CPRE_DIV128 0xD #define RCC_D1CFGR_D1CPRE_DIV256 0xE #define RCC_D1CFGR_D1CPRE_DIV512 0xF #define RCC_D1CFGR_D1PPRE_BYP 0x0 #define RCC_D1CFGR_D1PPRE_DIV2 0x4 #define RCC_D1CFGR_D1PPRE_DIV4 0x5 #define RCC_D1CFGR_D1PPRE_DIV8 0x6 #define RCC_D1CFGR_D1PPRE_DIV16 0x7 #define RCC_D1CFGR_D1HPRE_BYP 0x0 #define RCC_D1CFGR_D1HPRE_DIV2 0x8 #define RCC_D1CFGR_D1HPRE_DIV4 0x9 #define RCC_D1CFGR_D1HPRE_DIV8 0xA #define RCC_D1CFGR_D1HPRE_DIV16 0xB #define RCC_D1CFGR_D1HPRE_DIV64 0xC #define RCC_D1CFGR_D1HPRE_DIV128 0xD #define RCC_D1CFGR_D1HPRE_DIV256 0xE #define RCC_D1CFGR_D1HPRE_DIV512 0xF #define RCC_D1CFGR_D1CPRE_SHIFT 8 #define RCC_D1CFGR_D1PPRE_SHIFT 4 #define RCC_D1CFGR_D1CPRE(cpre) (cpre << RCC_D1CFGR_D1CPRE_SHIFT) #define RCC_D1CFGR_D1PPRE(ppre) (ppre << RCC_D1CFGR_D1PPRE_SHIFT) #define RCC_D1CFGR_D1HPRE(hpre) (hpre) /**@}*/ /** @defgroup rcc_d2cfgr_values RCC_D2CFGR Values * @ingroup rcc_registers * @{*/ #define RCC_D2CFGR_D2PPRE_BYP 0x0 #define RCC_D2CFGR_D2PPRE_DIV2 0x4 #define RCC_D2CFGR_D2PPRE_DIV4 0x5 #define RCC_D2CFGR_D2PPRE_DIV8 0x6 #define RCC_D2CFGR_D2PPRE_DIV16 0x7 #define RCC_D2CFGR_D2PPRE2_SHIFT 8 #define RCC_D2CFGR_D2PPRE1_SHIFT 4 #define RCC_D2CFGR_D2PPRE2(ppre) (ppre << RCC_D2CFGR_D2PPRE2_SHIFT) #define RCC_D2CFGR_D2PPRE1(ppre) (ppre << RCC_D2CFGR_D2PPRE1_SHIFT) /**@}*/ /** @defgroup rcc_d3cfgr_values RCC_D3CFGR Values * @ingroup rcc_registers * @{*/ #define RCC_D3CFGR_D3PPRE_BYP 0x0 #define RCC_D3CFGR_D3PPRE_DIV2 0x4 #define RCC_D3CFGR_D3PPRE_DIV4 0x5 #define RCC_D3CFGR_D3PPRE_DIV8 0x6 #define RCC_D3CFGR_D3PPRE_DIV16 0x7 #define RCC_D3CFGR_D3PPRE_SHIFT 4 #define RCC_D3CFGR_D3PPRE(ppre) (ppre << RCC_D3CFGR_D3PPRE_SHIFT) /**@}*/ /** @defgroup rcc_pllckselr_values RCC_PLLCKSELR Values * @ingroup rcc_registers * @{*/ #define RCC_PLLCKSELR_PLLSRC_HSI 0x0 #define RCC_PLLCKSELR_PLLSRC_CSI 0x1 #define RCC_PLLCKSELR_PLLSRC_HSE 0x2 #define RCC_PLLCKSELR_PLLSRC_NONE 0x3 #define RCC_PLLCKSELR_DIVM_DIS 0 #define RCC_PLLCKSELR_DIVM_BYP 1 #define RCC_PLLCKSELR_DIVM_MASK 0x3f #define RCC_PLLCKSELR_DIVM3_SHIFT 20 #define RCC_PLLCKSELR_DIVM2_SHIFT 12 #define RCC_PLLCKSELR_DIVM1_SHIFT 4 #define RCC_PLLCKSELR_DIVM3(n) ((n) << RCC_PLLCKSELR_DIVM3_SHIFT) #define RCC_PLLCKSELR_DIVM2(n) ((n) << RCC_PLLCKSELR_DIVM2_SHIFT) #define RCC_PLLCKSELR_DIVM1(n) ((n) << RCC_PLLCKSELR_DIVM1_SHIFT) /**@}*/ /** @defgroup rcc_pllcfgr_values RCC_PLLCFGR Values * @ingroup rcc_registers * @{*/ #define RCC_PLLCFGR_PLLRGE_1_2MHZ 0 #define RCC_PLLCFGR_PLLRGE_2_4MHZ 1 #define RCC_PLLCFGR_PLLRGE_4_8MHZ 2 #define RCC_PLLCFGR_PLLRGE_8_16MHZ 3 #define RCC_PLLCFGR_DIVR3EN BIT24 #define RCC_PLLCFGR_DIVQ3EN BIT23 #define RCC_PLLCFGR_DIVP3EN BIT22 #define RCC_PLLCFGR_DIVR2EN BIT21 #define RCC_PLLCFGR_DIVQ2EN BIT20 #define RCC_PLLCFGR_DIVP2EN BIT19 #define RCC_PLLCFGR_DIVR1EN BIT18 #define RCC_PLLCFGR_DIVQ1EN BIT17 #define RCC_PLLCFGR_DIVP1EN BIT16 #define RCC_PLLCFGR_PLL3RGE_SHIFT 10 #define RCC_PLLCFGR_PLL3VCO_WIDE 0 /* 192 - 836MHz base output. */ #define RCC_PLLCFGR_PLL3VCO_MED BIT9 /* 150 - 420MHz base output. */ #define RCC_PLLCFGR_PLL3FRACEN BIT8 #define RCC_PLLCFGR_PLL2RGE_SHIFT 6 #define RCC_PLLCFGR_PLL2VCO_WIDE 0 /* 192 - 836MHz base output. */ #define RCC_PLLCFGR_PLL2VCO_MED BIT5 /* 150 - 420MHz base output. */ #define RCC_PLLCFGR_PLL2FRACEN BIT4 #define RCC_PLLCFGR_PLL1RGE_SHIFT 2 #define RCC_PLLCFGR_PLL1VCO_WIDE 0 /* 192 - 836MHz base output. */ #define RCC_PLLCFGR_PLL1VCO_MED BIT1 /* 150 - 420MHz base output. */ #define RCC_PLLCFGR_PLL1FRACEN BIT0 /**@}*/ /** @defgroup rcc_plldivr_values RCC_PLLnDIVR Values * @ingroup rcc_registers * @{*/ #define RCC_PLLNDIVR_DIVR_SHIFT 24 #define RCC_PLLNDIVR_DIVQ_SHIFT 16 #define RCC_PLLNDIVR_DIVP_SHIFT 9 #define RCC_PLLNDIVR_DIVN_SHIFT 0 /* Need to preserve reserved bits, so give easy mask shortcut. */ #define RCC_PLLNDIVR_DIVR(n) (((n) - 1) << RCC_PLLNDIVR_DIVR_SHIFT) #define RCC_PLLNDIVR_DIVQ(n) (((n) - 1) << RCC_PLLNDIVR_DIVQ_SHIFT) #define RCC_PLLNDIVR_DIVP(n) (((n) - 1) << RCC_PLLNDIVR_DIVP_SHIFT) #define RCC_PLLNDIVR_DIVN(n) (((n) - 1) << RCC_PLLNDIVR_DIVN_SHIFT) /**@}*/ /** @defgroup rcc_bdcr_values RCC_BDCR Values * @ingroup rcc_registers @{*/ #define RCC_BDCR_BDRST (1 << 16) #define RCC_BDCR_RTCEN (1 << 15) #define RCC_BDCR_RTCSEL_MASK 0x3 #define RCC_BDCR_RTCSEL_SHIFT 8 #define RCC_BDCR_RTCSEL_NONE 0 #define RCC_BDCR_RTCSEL_LSE 1 #define RCC_BDCR_RTCSEL_LSI 2 #define RCC_BDCR_RTCSEL_HSE 3 #define RCC_BDCR_LSEDRV_MASK 0x3 #define RCC_BDCR_LSEDRV_SHIFT 3 #define RCC_BDCR_LSEDRV_LOW 0 #define RCC_BDCR_LSEDRV_MEDH 1 /* good job st */ #define RCC_BDCR_LSEDRV_MEDL 2 #define RCC_BDCR_LSEDRV_HIGH 3 #define RCC_BDCR_LSEBYP (1 << 2) #define RCC_BDCR_LSERDY (1 << 1) #define RCC_BDCR_LSEON (1 << 0) /**@}*/ /** @defgroup rcc_csr_values RCC_CSR Values. * @ingroup rcc_registers @{*/ #define RCC_CSR_LSIRDY (1 << 1) #define RCC_CSR_LSION (1 << 0) /**@}*/ /** @defgroup rcc_d1ccipr_values RCC_D1CCIP1R Values * @ingroup rcc_registers * @{*/ #define RCC_D1CCIPR_CKPERSEL_HSI 0 #define RCC_D1CCIPR_CKPERSEL_CSI 1 #define RCC_D1CCIPR_CKPERSEL_HSE 2 #define RCC_D1CCIPR_CKPERSEL_DISABLE 3 /**@}*/ #define RCC_D1CCIPR_CKPERSEL_SHIFT 28 #define RCC_D1CCIPR_CKPERSEL_MASK 3 #define RCC_D2CCIP1R_SWPSEL_SHIFT 31 #define RCC_D2CCIP1R_FDCANSEL_SHIFT 28 #define RCC_D2CCIP1R_FDCANSEL_MASK 0x3 #define RCC_D2CCIP1R_DFSDM1SEL_SHIFT 24 #define RCC_D2CCIP1R_SPDIFSEL_SHIFT 20 #define RCC_D2CCIP1R_SPI45SEL_SHIFT 16 #define RCC_D2CCIP1R_SPI45SEL_MASK 0x7 #define RCC_D2CCIP1R_SPI123SEL_SHIFT 12 #define RCC_D2CCIP1R_SPI123SEL_MASK 0x7 #define RCC_D2CCIP1R_SAI23SEL_SHIFT 6 #define RCC_D2CCIP1R_SAISEL_MASK 0x7 /** @defgroup rcc_d2ccip1r_values RCC_D2CCIP1R Values * @ingroup rcc_registers * @{*/ #define RCC_D2CCIP1R_SWPSEL_PCLK 0x0 #define RCC_D2CCIP1R_SWPSEL_HSI 0x1 #define RCC_D2CCIP1R_FDCANSEL_HSE 0x0 #define RCC_D2CCIP1R_FDCANSEL_PLL1Q 0x1 #define RCC_D2CCIP1R_FDCANSEL_PLL2Q 0x2 #define RCC_D2CCIP1R_DFSDM1SEL_PCLK2 0x0 #define RCC_D2CCIP1R_DFSDM1SEL_SYSCLK 0x1 #define RCC_D2CCIP1R_SPDIFSEL_PLL1Q 0x0 #define RCC_D2CCIP1R_SPDIFSEL_PLL2R 0x1 #define RCC_D2CCIP1R_SPDIFSEL_PLL3R 0x2 #define RCC_D2CCIP1R_SPDIFSEL_HSI 0x3 #define RCC_D2CCIP1R_SPI45SEL_APB4 0x0 #define RCC_D2CCIP1R_SPI45SEL_PLL2Q 0x1 #define RCC_D2CCIP1R_SPI45SEL_PLL3Q 0x2 #define RCC_D2CCIP1R_SPI45SEL_HSI 0x3 #define RCC_D2CCIP1R_SPI45SEL_CSI 0x4 #define RCC_D2CCIP1R_SPI45SEL_HSE 0x5 #define RCC_D2CCIP1R_SPI123SEL_PLL1Q 0x0 #define RCC_D2CCIP1R_SPI123SEL_PLL2P 0x1 #define RCC_D2CCIP1R_SPI123SEL_PLL3P 0x2 #define RCC_D2CCIP1R_SPI123SEL_I2SCKIN 0x3 #define RCC_D2CCIP1R_SPI123SEL_PERCK 0x4 #define RCC_D2CCIP1R_SAISEL_PLL1Q 0x0 #define RCC_D2CCIP1R_SAISEL_PLL2P 0x1 #define RCC_D2CCIP1R_SAISEL_PLL3P 0x2 #define RCC_D2CCIP1R_SAISEL_I2SCKIN 0x3 #define RCC_D2CCIP1R_SAISEL_PERCK 0x4 /**@}*/ #define RCC_D2CCIP2R_LPTIM1SEL_SHIFT 28 #define RCC_D2CCIP2R_CECSEL_SHIFT 22 #define RCC_D2CCIP2R_USBSEL_SHIFT 20 #define RCC_D2CCIP2R_I2C123SEL_SHIFT 12 #define RCC_D2CCIP2R_RNGSEL_MASK 0x3 #define RCC_D2CCIP2R_RNGSEL_SHIFT 8 #define RCC_D2CCIP2R_USART16SEL_SHIFT 3 #define RCC_D2CCIP2R_USART234578SEL_SHIFT 0 #define RCC_D2CCIP2R_USARTSEL_MASK 7 /** @defgroup rcc_d2ccip2r_values RCC_D2CCIP2R Values * @ingroup rcc_registers * @{*/ #define RCC_D2CCIP2R_RNGSEL_HSI48 0 #define RCC_D2CCIP2R_RNGSEL_PLL1Q 1 #define RCC_D2CCIP2R_RNGSEL_LSE 2 #define RCC_D2CCIP2R_RNGSEL_LSI 3 #define RCC_D2CCIP2R_USART16SEL_PCLK2 0 #define RCC_D2CCIP2R_USART234578SEL_PCLK1 0 #define RCC_D2CCIP2R_USARTSEL_PCLK 0 #define RCC_D2CCIP2R_USARTSEL_PLL2Q 1 #define RCC_D2CCIP2R_USARTSEL_PLL3Q 2 #define RCC_D2CCIP2R_USARTSEL_HSI 3 #define RCC_D2CCIP2R_USARTSEL_CSI 4 #define RCC_D2CCIP2R_USARTSEL_LSE 5 /**@}*/ #define RCC_HSI_BASE_FREQUENCY 64000000UL /** Enumerations for core system/bus clocks for user/driver/system access to base bus clocks * not directly associated with a peripheral. */ enum rcc_clock_source { RCC_CPUCLK, RCC_SYSCLK, RCC_PERCLK, RCC_SYSTICKCLK, RCC_HCLK3, RCC_AHBCLK, /* AHB1,2,4 all share base HCLK. */ RCC_APB1CLK, /* Note: APB1 and PCLK1 in manual */ RCC_APB2CLK, /* Note: APB2 and PCLK2 in manual */ RCC_APB3CLK, /* Note: APB3 and PCLK3 in manual */ RCC_APB4CLK, /* Note: APB4 and PCLK4 in manual */ }; enum rcc_osc { RCC_PLL, RCC_HSE, RCC_HSI, RCC_LSE, RCC_LSI }; /** PLL Configuration structure. */ struct rcc_pll_config { enum rcc_osc sysclock_source; /**< SYSCLK source input selection. */ uint8_t pll_source; /**< RCC_PLLCKSELR_PLLSRC_xxx value. */ uint32_t hse_frequency; /**< User specified HSE frequency, 0 if none. */ struct pll_config { uint8_t divm; /**< Pre-divider value for each PLL. 0-64 integers. */ uint16_t divn; /**< Multiplier, 0-512 integer. */ uint8_t divp; /**< Post divider for PLLP clock. */ uint8_t divq; /**< Post divider for PLLQ clock. */ uint8_t divr; /**< Post divider for PLLR clock. */ } pll1, pll2, pll3; /**< PLL1-PLL3 configurations. */ uint8_t core_pre; /**< Core prescaler note: domain 1. */ uint8_t hpre; /**< HCLK3 prescaler note: domain 1. */ uint8_t ppre1; /**< APB1 Peripheral prescaler note: domain 2. */ uint8_t ppre2; /**< APB2 Peripheral prescaler note: domain 2. */ uint8_t ppre3; /**< APB3 Peripheral prescaler note: domain 1. */ uint8_t ppre4; /**< APB4 Peripheral prescaler note: domain 3. */ uint8_t flash_waitstates; /**< Latency Value to set for flahs. */ enum pwr_vos_scale voltage_scale; /**< LDO Voltage scale used for this frequency. */ }; #define _REG_BIT(base, bit) (((base) << 5) + (bit)) enum rcc_periph_clken { /* AHB1 peripherals */ RCC_DMA1 = _REG_BIT(0xD8, 0), RCC_DMA2 = _REG_BIT(0xD8, 1), RCC_ADC12 = _REG_BIT(0xD8, 5), RCC_ETH1MAC = _REG_BIT(0xD8, 15), RCC_ETH1TX = _REG_BIT(0xD8, 16), RCC_ETH1RX = _REG_BIT(0xD8, 17), RCC_USB2OTGHSULPIEN = _REG_BIT(0xD8, 18), RCC_USB1OTGHSEN = _REG_BIT(0xD8, 25), RCC_USB1OTGHSULPIEN = _REG_BIT(0xD8, 26), RCC_USB2OTGHSEN = _REG_BIT(0xD8, 27), /* AHB2 peripherals */ RCC_DCMI = _REG_BIT(0xDC, 0), RCC_CRYP = _REG_BIT(0xDC, 4), RCC_HASH = _REG_BIT(0xDC, 5), RCC_RNG = _REG_BIT(0xDC, 6), RCC_SDMMC2 = _REG_BIT(0xDC, 9), RCC_SRAM1 = _REG_BIT(0xDC, 29), RCC_SRAM2 = _REG_BIT(0xDC, 30), RCC_SRAM3 = _REG_BIT(0xDC, 31), /* AHB3 peripherals */ RCC_MDMA = _REG_BIT(0xD4, 0), RCC_DMA2D = _REG_BIT(0xD4, 4), RCC_JPGDEC = _REG_BIT(0xD4, 5), RCC_FMC = _REG_BIT(0xD4, 12), RCC_QSPI = _REG_BIT(0xD4, 14), RCC_SDMMC1 = _REG_BIT(0xD4, 16), /* AHB4 peripherals*/ RCC_GPIOA = _REG_BIT(0xE0, 0), RCC_GPIOB = _REG_BIT(0xE0, 1), RCC_GPIOC = _REG_BIT(0xE0, 2), RCC_GPIOD = _REG_BIT(0xE0, 3), RCC_GPIOE = _REG_BIT(0xE0, 4), RCC_GPIOF = _REG_BIT(0xE0, 5), RCC_GPIOG = _REG_BIT(0xE0, 6), RCC_GPIOH = _REG_BIT(0xE0, 7), RCC_GPIOI = _REG_BIT(0xE0, 8), RCC_GPIOJ = _REG_BIT(0xE0, 9), RCC_GPIOK = _REG_BIT(0xE0, 10), RCC_CRC = _REG_BIT(0xE0, 19), RCC_BDMA = _REG_BIT(0xE0, 21), RCC_ADC3 = _REG_BIT(0xE0, 24), RCC_HSEM = _REG_BIT(0xE0, 25), RCC_BKPSRAM = _REG_BIT(0xE0, 28), /* APB1L peripherals*/ RCC_TIM2 = _REG_BIT(0xE8, 0), RCC_TIM3 = _REG_BIT(0xE8, 1), RCC_TIM4 = _REG_BIT(0xE8, 2), RCC_TIM5 = _REG_BIT(0xE8, 3), RCC_TIM6 = _REG_BIT(0xE8, 4), RCC_TIM7 = _REG_BIT(0xE8, 5), RCC_TIM12 = _REG_BIT(0xE8, 6), RCC_TIM13 = _REG_BIT(0xE8, 7), RCC_TIM14 = _REG_BIT(0xE8, 8), RCC_LPTIM1 = _REG_BIT(0xE8, 9), RCC_SPI2 = _REG_BIT(0xE8, 14), RCC_SPI3 = _REG_BIT(0xE8, 15), RCC_SPDIFRX = _REG_BIT(0xE8, 16), RCC_USART2 = _REG_BIT(0xE8, 17), RCC_USART3 = _REG_BIT(0xE8, 18), RCC_UART4 = _REG_BIT(0xE8, 19), RCC_UART5 = _REG_BIT(0xE8, 20), RCC_I2C1 = _REG_BIT(0xE8, 21), RCC_I2C2 = _REG_BIT(0xE8, 22), RCC_I2C3 = _REG_BIT(0xE8, 23), RCC_CEC = _REG_BIT(0xE8, 27), RCC_DAC = _REG_BIT(0xE8, 29), RCC_UART7 = _REG_BIT(0xE8, 30), RCC_UART8 = _REG_BIT(0xE8, 31), /* APB1H peripherals*/ RCC_CRS = _REG_BIT(0xEC, 1), RCC_SWP = _REG_BIT(0xEC, 2), RCC_OPAMP = _REG_BIT(0xEC, 4), RCC_MDIO = _REG_BIT(0xEC, 5), RCC_FDCAN = _REG_BIT(0xEC, 8), /* APB2 peripherals */ RCC_TIM1 = _REG_BIT(0xF0, 0), RCC_TIM8 = _REG_BIT(0xF0, 1), RCC_USART1 = _REG_BIT(0xF0, 4), RCC_USART6 = _REG_BIT(0xF0, 5), RCC_SPI1 = _REG_BIT(0xF0, 12), RCC_SPI4 = _REG_BIT(0xF0, 13), RCC_TIM15 = _REG_BIT(0xF0, 16), RCC_TIM16 = _REG_BIT(0xF0, 17), RCC_TIM17 = _REG_BIT(0xF0, 18), RCC_SPI5 = _REG_BIT(0xF0, 20), RCC_SAI1 = _REG_BIT(0xF0, 22), RCC_SAI2 = _REG_BIT(0xF0, 23), RCC_SAI3 = _REG_BIT(0xF0, 24), RCC_DFSDM = _REG_BIT(0xF0, 28), RCC_HRTIM = _REG_BIT(0xF0, 29), /* APB3 peripherals */ RCC_LTDCEN = _REG_BIT(0xE4, 3), RCC_WWDG1EN = _REG_BIT(0xE4, 6), /* APB4 peripherals */ RCC_SYSCFG = _REG_BIT(0xF4, 1), RCC_LPUART1 = _REG_BIT(0xF4, 3), RCC_SPI6 = _REG_BIT(0xF4, 5), RCC_I2C4 = _REG_BIT(0xF4, 7), RCC_LPTIM2 = _REG_BIT(0xF4, 9), RCC_LPTIM3 = _REG_BIT(0xF4, 10), RCC_LPTIM4 = _REG_BIT(0xF4, 11), RCC_LPTIM5 = _REG_BIT(0xF4, 12), RCC_COMP12 = _REG_BIT(0xF4, 14), RCC_VREF = _REG_BIT(0xF4, 15), RCC_RTCAPB = _REG_BIT(0xF4, 16), RCC_SAI4 = _REG_BIT(0xF4, 21), }; enum rcc_periph_rst { /* AHB1 peripherals */ RST_DMA1 = _REG_BIT(0x80, 0), RST_DMA2 = _REG_BIT(0x80, 1), RST_ADC12 = _REG_BIT(0x80, 5), RST_ETH1MAC = _REG_BIT(0x80, 15), RST_USB1OTGRST = _REG_BIT(0x80, 25), RST_USB2OTGRST = _REG_BIT(0x80, 27), /* AHB2 peripherals */ RST_DCMI = _REG_BIT(0xDC, 0), RST_CRYP = _REG_BIT(0xDC, 4), RST_HASH = _REG_BIT(0xDC, 5), RST_RNG = _REG_BIT(0xDC, 6), RST_SDMMC2 = _REG_BIT(0xDC, 9), /* AHB3 peripherals */ RST_MDMA = _REG_BIT(0x7C, 0), RST_DMA2D = _REG_BIT(0x7C, 4), RST_JPGDEC = _REG_BIT(0x7C, 5), RST_FMC = _REG_BIT(0x7C, 12), RST_QSPI = _REG_BIT(0x7C, 14), RST_SDMMC1 = _REG_BIT(0x7C, 16), /* AHB4 peripherals*/ RST_GPIOA = _REG_BIT(0x88, 0), RST_GPIOB = _REG_BIT(0x88, 1), RST_GPIOC = _REG_BIT(0x88, 2), RST_GPIOD = _REG_BIT(0x88, 3), RST_GPIOE = _REG_BIT(0x88, 4), RST_GPIOF = _REG_BIT(0x88, 5), RST_GPIOG = _REG_BIT(0x88, 6), RST_GPIOH = _REG_BIT(0x88, 7), RST_GPIOI = _REG_BIT(0x88, 8), RST_GPIOJ = _REG_BIT(0x88, 9), RST_GPIOK = _REG_BIT(0x88, 10), RST_CRC = _REG_BIT(0x88, 19), RST_BDMA = _REG_BIT(0x88, 21), RST_ADC3 = _REG_BIT(0x88, 24), RST_HSEM = _REG_BIT(0x88, 25), /* APB1L peripherals*/ RST_TIM2 = _REG_BIT(0x90, 0), RST_TIM3 = _REG_BIT(0x90, 1), RST_TIM4 = _REG_BIT(0x90, 2), RST_TIM5 = _REG_BIT(0x90, 3), RST_TIM6 = _REG_BIT(0x90, 4), RST_TIM7 = _REG_BIT(0x90, 5), RST_TIM12 = _REG_BIT(0x90, 6), RST_TIM13 = _REG_BIT(0x90, 7), RST_TIM14 = _REG_BIT(0x90, 8), RST_LPTIM1 = _REG_BIT(0x90, 9), RST_SPI2 = _REG_BIT(0x90, 14), RST_SPI3 = _REG_BIT(0x90, 15), RST_SPDIFRX = _REG_BIT(0x90, 16), RST_USART2 = _REG_BIT(0x90, 17), RST_USART3 = _REG_BIT(0x90, 18), RST_UART4 = _REG_BIT(0x90, 19), RST_UART5 = _REG_BIT(0x90, 20), RST_I2C1 = _REG_BIT(0x90, 21), RST_I2C2 = _REG_BIT(0x90, 22), RST_I2C3 = _REG_BIT(0x90, 23), RST_CEC = _REG_BIT(0x90, 27), RST_DAC = _REG_BIT(0x90, 29), RST_UART7 = _REG_BIT(0x90, 30), RST_UART8 = _REG_BIT(0x90, 31), /* APB1H peripherals*/ RST_CRS = _REG_BIT(0x94, 1), RST_SWP = _REG_BIT(0x94, 2), RST_OPAMP = _REG_BIT(0x94, 4), RST_MDIO = _REG_BIT(0x94, 5), RST_FDCAN = _REG_BIT(0x94, 8), /* APB2 peripherals */ RST_TIM1 = _REG_BIT(0x98, 0), RST_TIM8 = _REG_BIT(0x98, 1), RST_USART1 = _REG_BIT(0x98, 4), RST_USART6 = _REG_BIT(0x98, 5), RST_SPI1 = _REG_BIT(0x98, 12), RST_SPI4 = _REG_BIT(0x98, 13), RST_TIM15 = _REG_BIT(0x98, 16), RST_TIM16 = _REG_BIT(0x98, 17), RST_TIM17 = _REG_BIT(0x98, 18), RST_SPI5 = _REG_BIT(0x98, 20), RST_SAI1 = _REG_BIT(0x98, 22), RST_SAI2 = _REG_BIT(0x98, 23), RST_SAI3 = _REG_BIT(0x98, 24), RST_DFSDM = _REG_BIT(0x98, 28), RST_HRTIM = _REG_BIT(0x98, 29), /* APB3 peripherals */ RST_LTDCRST = _REG_BIT(0x8C, 3), /* APB4 peripherals */ RST_SYSCFG = _REG_BIT(0x9C, 1), RST_LPUART1 = _REG_BIT(0x9C, 3), RST_SPI6 = _REG_BIT(0x9C, 5), RST_I2C4 = _REG_BIT(0x9C, 7), RST_LPTIM2 = _REG_BIT(0x9C, 9), RST_LPTIM3 = _REG_BIT(0x9C, 10), RST_LPTIM4 = _REG_BIT(0x9C, 11), RST_LPTIM5 = _REG_BIT(0x9C, 12), RST_COMP12 = _REG_BIT(0x9C, 14), RST_VREF = _REG_BIT(0x9C, 15), RST_SAI4 = _REG_BIT(0x9C, 21), }; #undef _REG_BIT /**@}*/ /** @defgroup rcc_file RCC peripheral API * * @ingroup peripheral_apis * @{ */ #include BEGIN_DECLS /** * Setup the base PLLs and clock domains for the STM32H7. This function will * utilize the users input parameters to configure all 3 PLLs, as well as the * core clock domains (namely SYSCLK, CPU, HCLK, AHB, PCLK1-4) with the * specified dividers. Given the dividers, the RCC module will track the * the configured frequency for each of these clock domains. * * Note: If clock sources, configs, divider, etc. are modified outside of * this module, the frequency tracking may be undefined. * Note: Clock tree is fairly complex, see RM0433 Section 7 * for details. * @param[in] config Input config structure defining desired setup. */ void rcc_clock_setup_pll(const struct rcc_pll_config *config); /** * Get the clock rate (in Hz) of the specified clock source. There are * numerous clock sources and configurations on the H7, so rates for each * configured peripheral clock are aimed to be discoverd/calculated by this * module such that the user does not need to know how the MCU is configured * in order to utilize a peripheral clock. * @param[in] source Clock source desired to be fetched. * @return Clock rate in Hz for the specified clock. 0 if undefined or error. */ uint32_t rcc_get_bus_clk_freq(enum rcc_clock_source source); /** * Get the peripheral clock speed for the USART at base specified. * @param usart Base address of USART to get clock frequency for (e.g. USART1_BASE). */ uint32_t rcc_get_usart_clk_freq(uint32_t usart); /** * Get the peripheral clock speed for the Timer at base specified. * @param timer Base address of TIMER to get clock frequency for (e.g. TIM1_BASE). */ uint32_t rcc_get_timer_clk_freq(uint32_t timer); /** * Get the peripheral clock speed for the I2C device at base specified. * @param i2c Base address of I2C to get clock frequency for (e.g. I2C1_BASE). */ uint32_t rcc_get_i2c_clk_freq(uint32_t i2c); /** * Get the peripheral clock speed for the SPI device at base specified. * @param spi Base address of SPI device to get clock frequency for (e.g. SPI1_BASE). */ uint32_t rcc_get_spi_clk_freq(uint32_t spi); /** * Get the peripheral clock speed for the FDCAN device at base specified. * @param fdcan Base address of FDCAN to get clock frequency for (e.g. FDCAN1_BASE). */ uint32_t rcc_get_fdcan_clk_freq(uint32_t fdcan); /** * Set the clksel value for the specified peripheral. This code will determine * the appropriate register, shift and mask values to apply to the selection to * and set the values appropriately. * * Peripheral specific clksels functions are also available, * eg rcc_set__clksel. These provide the same functionality, you only * need one of them. for instance @ref rcc_set_fdcan_clksel or * @ref rcc_set_spi123_clksel * @param[in] periph Base address of the peripheral to set the clock sel for * @param[in] clksel Raw, unshifted selection value for the clock, depending * on peripheral, see @ref rcc_d1ccipr_values or @ref rcc_d2ccip1r_values or * @ref rcc_d2ccip2r_values */ void rcc_set_peripheral_clk_sel(uint32_t periph, uint32_t clksel); /** * Set the clock select for the FDCAN devices. * @param[in] clksel Clock source to configure for, @ref rcc_d2ccip1r_values * appropriate for the FDCAN peripherals, eg RCC_D2CCIP1R_FDCANSEL_XXX * @sa rcc_set_peripheral_clk_sel for equivalent generic functionality */ void rcc_set_fdcan_clksel(uint8_t clksel); /** * Set the clock select for the SPI 1/2/3 devices. * @param[in] clksel Clock source to configure for, @ref rcc_d2ccip1r_values * appropriate for the SPI1/2/3 peripherals, eg RCC_D2CCIP1R_SPI123_XXX * @sa rcc_set_peripheral_clk_sel for equivalent generic functionality */ void rcc_set_spi123_clksel(uint8_t clksel); /** * Set the clock select for the SPI 4/5 devices. * @param[in] clksel Clock source to configure for. @ref rcc_d2ccip1r_values * @sa rcc_set_peripheral_clk_sel for equivalent generic functionality */ void rcc_set_spi45_clksel(uint8_t clksel); /** * Set the clock select for the RNG device. * @param[in] clksel Clock source to configure for. @ref rcc_d2ccip2r_values * @sa rcc_set_peripheral_clk_sel for equivalent generic functionality */ void rcc_set_rng_clksel(uint8_t clksel); END_DECLS /**@}*/ /**@}*/ #endif