~ruther/stm32h747i-disco-usb-image-viewer

9cb6ab52fc2b86956e5f74a8630a3aaf79411f29 — Rutherther 3 months ago c298348
feat: vos0, system clock at 480 MHz
2 files changed, 56 insertions(+), 9 deletions(-)

M include/registers.h
M src/main.c
M include/registers.h => include/registers.h +8 -4
@@ 13,8 13,10 @@
inline void __attribute__((always_inline))
reg_write_bits_pos(volatile uint32_t *reg, uint32_t data, uint8_t pos,
                   uint32_t mask) {
  *reg &= ~(mask << pos);
  *reg |= (data & mask) << pos;
  uint32_t val = *reg;
  val &= ~(mask << pos);
  val |= (data & mask) << pos;
  *reg = val;
}

/**


@@ 25,8 27,10 @@ reg_write_bits_pos(volatile uint32_t *reg, uint32_t data, uint8_t pos,
 */
inline void __attribute__((always_inline)) reg_write_bits(volatile uint32_t *reg, uint32_t data,
                                  uint32_t mask) {
  *reg &= ~(mask);
  *reg |= (data & mask);
  uint32_t val = *reg;
  val &= ~(mask);
  val |= (data & mask);
  *reg = val;
}

/**

M src/main.c => src/main.c +48 -5
@@ 275,11 275,54 @@ void main()
  clocks_pll_enable(CLOCK_PLL2);
  clocks_pll_wait_ready(CLOCK_PLL2, 300);

  /* clocks_pll_configure(CLOCK_PLL1, 1, 25, PLL_SOURCE_HSE, 200, 2, 2, 2); */
  /* clocks_pll_enable(CLOCK_PLL1); */
  /* clocks_pll_wait_ready(CLOCK_PLL1, 300); */

  /* clocks_system_clock_source(CLOCK_SOURCE_PLL_1_P_CK, 1, 1, 1, 300); */
  // 1. Set pwr configuration
  reg_write_bits(&PWR->CR3,
                 (1 << PWR_CR3_SMPSEN_Pos) | (0 << PWR_CR3_LDOEN_Msk) |
                 (0 << PWR_CR3_BYPASS_Msk),
                 PWR_CR3_LDOEN_Msk | PWR_CR3_SMPSEN_Msk | PWR_CR3_BYPASS_Msk);

  // 2. Verify pwr configuration. If not working, stay here looping!
  // NOTE: this probably means you need to power cycle the board. The
  // configuration can be written only when the chip has just been connected.
  while (!(PWR->CR3 & PWR_CR3_SMPSEN) || (PWR->CR3 & PWR_CR3_LDOEN) || (PWR->CR3 & PWR_CR3_BYPASS));

  // 3. Change VOS
  // 3.1. Check current configuration (VOS 3)
  while (!(PWR->CSR1 & PWR_CSR1_ACTVOSRDY));

  // 3.2. VOS 1 transition
  reg_write_bits(&PWR->D3CR, (11 << PWR_D3CR_VOS_Pos), PWR_D3CR_VOS_Msk);
  while (!(PWR->CSR1 & PWR_D3CR_VOSRDY));

  // 3.3. VOS 0 transition
  reg_set_bits(&SYSCFG->PWRCR, SYSCFG_PWRCR_ODEN);
  while (!(PWR->CSR1 & PWR_D3CR_VOSRDY));

  // 25 MHz / 10 -> 2.5 MHz * 384 = 960 MHz (FVCO)
  // PLL1_P = 960 / 2 => 480 MHz
  clocks_pll_configure(CLOCK_PLL1, 0, 10, PLL_SOURCE_HSE, 384, 2, 0, 0);
  clocks_pll_enable(CLOCK_PLL1);
  clocks_pll_wait_ready(CLOCK_PLL1, 300);

  // Flash setup
  /* uint32_t sysck_freq_hz = 480000000; // 480 MHz */
  /* uint32_t d1cpre_freq_hz = sysck_freq_hz / 1; // 480 Mhz */
  /* uint32_t rcc_hclk = d1cpre_freq_hz / 2; // 240 MHz */

  // 240 MHz means wait states = 4, progr delay = 2
  reg_write_bits(&FLASH->ACR,
                 (2 << FLASH_ACR_WRHIGHFREQ_Pos) | (4 << FLASH_ACR_LATENCY_Pos),
                 FLASH_ACR_WRHIGHFREQ_Msk | FLASH_ACR_LATENCY_Msk);
  while (((FLASH->ACR & FLASH_ACR_LATENCY_Msk) >> FLASH_ACR_LATENCY_Pos) != 4);

  // D1CPRE = sysck / 1 => 480 MHz, HPRE = sysck / 2 => 240 MHz
  reg_write_bits(&RCC->D1CFGR,
                 (0 << RCC_D1CFGR_D1CPRE_Pos) | (1 << RCC_D1CFGR_HPRE_Pos) |
                 (0 << RCC_D1CFGR_D1CPRE_Pos),
                 RCC_D1CFGR_D1CPRE_Msk | RCC_D1CFGR_HPRE_Msk | RCC_D1CFGR_D1CPRE_Msk);

  // Sysck = PLL1_P
  clocks_system_clock_source(CLOCK_SOURCE_PLL_1_P_CK, 1, 1, 1, 300);

  fmc_t fmc;
  init_fmc(&fmc);

Do not follow this link