aboutsummaryrefslogtreecommitdiff
path: root/include/clock.h
blob: 42e2eddeacb994a43d15de01428dec8b0f86ffd9 (plain) (blame)
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
#pragma once

#include <stdint.h>
enum clock_selection {
  CLOCK_SELECTION_PLL = 0,
  CLOCK_SELECTION_LSE,
  CLOCK_SELECTION_LSI,
  CLOCK_SELECTION_HSE,
};

typedef struct {
  enum clock_selection sel;

  union {
    /* Divisor for the PLL. If set to 0, the default value of 5 is used. */
    uint8_t pll_clock_divisor;

    /* Divisor for the HSE. If set to 0, the default value of 5 is used. */
    uint8_t hse_clock_divisor;
  };
} clock_cfg_t;

// Called when the system clock is changed.
typedef struct {
  void (*on_clk_change)(const clock_cfg_t* cfg);
} clock_chg_evt_listener_t;

/* Set the system clock configuration. */
int set_system_clock(const clock_cfg_t* clk_cfg);

/* Returns the clock configuration the system is currently in. */
int get_system_clock(clock_cfg_t* out);

/* Returns the frequency for the provided clock config.  */
uint32_t get_clock_freq(const clock_cfg_t* clk_cfg);

void configure_lse(void);

#define on_system_clock_changed(name)                                          \
  void on_system_clock_changed__##name(const clock_cfg_t*);             \
  __attribute__((                                                              \
      __section__(".clock_change_listeners"))) clock_chg_evt_listener_t name = \
      ((clock_chg_evt_listener_t){.on_clk_change =                             \
                                      on_system_clock_changed__##name});       \
  void on_system_clock_changed__##name