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

ref: c298348f285fbfddea5180435c867af1e2b429f6 stm32h747i-disco-usb-image-viewer/src/clocks.c -rw-r--r-- 2.7 KiB
c298348f — Rutherther few minorities 3 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#include "clocks.h"
#include "registers.h"
#include <stm32h747xx.h>

void clocks_enable(clock_t clock) {
  uint32_t mask = 0;
  switch (clock) {
  case CLOCK_HSI:
    mask = RCC_CR_HSION_Msk;
    break;
  case CLOCK_HSE:
    mask = RCC_CR_HSEON_Msk;
    break;
  case CLOCK_HSI48:
    mask = RCC_CR_HSI48ON_Msk;
    break;
  }

  RCC->CR |= mask;
}

bool clocks_ready(clock_t clock) {
  uint32_t mask = 0;
  switch (clock) {
  case CLOCK_HSI:
    mask = RCC_CR_HSIRDY_Msk;
    break;
  case CLOCK_HSE:
    mask = RCC_CR_HSERDY_Msk;
    break;
  case CLOCK_HSI48:
    mask = RCC_CR_HSI48RDY_Msk;
    break;
  }

  return (RCC->CR & mask) != 0;
}

void clocks_wait_ready(clock_t clock) {
  while (!clocks_ready(clock));
}

void clocks_pll_configure(clock_pll_t pll, uint8_t vcosel,
                          uint8_t divm, pll_source_t source,
                          uint16_t divn, uint8_t divp, uint8_t divq,
                          uint8_t divr) {
  clocks_pll_disable(pll);


  bool enable_p = divp > 0;
  bool enable_q = divq > 0;
  bool enable_r = divr > 0;

  reg_write_bits_pos(&RCC->PLLCFGR,
                     (enable_p << 0) | (enable_q << 1) | (enable_r << 2),
                     3*pll + RCC_PLLCFGR_DIVR1EN_Pos, 0x7);

  reg_write_bits_pos(&RCC->PLLCFGR, vcosel, (4*pll + RCC_PLLCFGR_PLL1VCOSEL_Pos), 1);

  reg_write_bits_pos(&RCC->PLLCKSELR, divm, RCC_PLLCKSELR_DIVM1_Pos + ((pll << 1) << 3), 0x3F);
  reg_write_bits_pos(&RCC->PLLCKSELR, source, RCC_PLLCKSELR_PLLSRC_Pos, 0x3);

  reg_write_bits(&RCC->PLL1DIVR + (pll << 1),
                 (((divr - 1) & 0x7F) << RCC_PLL1DIVR_R1_Pos) |
                 (((divq - 1) & 0x7F) << RCC_PLL1DIVR_Q1_Pos) |
                 (((divp - 1) & 0x7F) << RCC_PLL1DIVR_P1_Pos) |
                 (((divn - 1) & 0x1FF) << RCC_PLL1DIVR_N1_Pos),
                 0x7F7FFFFF);
}
void clocks_pll_enable(clock_pll_t pll) {
  reg_set_bits(&RCC->CR, RCC_CR_PLL1ON << (uint8_t)(pll << 1));
}
void clocks_pll_disable(clock_pll_t pll) {
  reg_clear_bits(&RCC->CR, RCC_CR_PLL1ON << ((uint8_t)(pll << 1)));
}
void clocks_pll_wait_ready(clock_pll_t pll, uint16_t timeout_us) {
  while (reg_read_bits_pos(&RCC->CR, RCC_CR_PLL1ON_Pos + (uint8_t)(pll << 1) + 1, 1) == 0);
}

void clocks_system_clock_source(sysclock_source_t source, uint8_t d1cpre, uint8_t d1ppre, uint8_t hpre, uint16_t timeout_us) {
  reg_write_bits(&RCC->D1CFGR,
                 ((d1cpre & 0xF) << RCC_D1CFGR_D1CPRE_Pos) |
                 ((d1ppre & 0x7) << RCC_D1CFGR_D1PPRE_Pos) |
                 ((hpre & 0xF) << RCC_D1CFGR_HPRE_Pos),
                 RCC_D1CFGR_D1CPRE_Msk | RCC_D1CFGR_D1PPRE_Msk | RCC_D1CFGR_HPRE_Msk);
  reg_write_bits(&RCC->CFGR, source, RCC_CFGR_SW);
  while (reg_read_bits_pos(&RCC->CFGR, RCC_CFGR_SWS_Pos, 0x7) != source);
}
Do not follow this link