#include <stdint.h>
#include <stdbool.h>
#ifndef CLOCKS_H
#define CLOCKS_H
typedef enum {
CLOCK_PLL1 = 0,
CLOCK_PLL2 = 1,
CLOCK_PLL3 = 2,
} clock_pll_t;
typedef enum {
CLOCK_SOURCE_HSI = 0,
CLOCK_SOURCE_HSE = 1,
CLOCK_SOURCE_CSI = 2,
CLOCK_SOURCE_PLL_1_P_CK = 3,
} sysclock_source_t;
typedef enum {
PLL_SOURCE_HSI = 0,
PLL_SOURCE_CSI = 1,
PLL_SOURCE_HSE = 2,
PLL_SOURCE_NONE = 3,
} pll_source_t;
typedef enum {
CLOCK_HSI,
CLOCK_HSE,
CLOCK_HSI48,
} clock_t;
/**
* @brief Make sure the given clock is enabled
* @param[in] clock The clock type to enable
*/
void clocks_enable(clock_t clock);
/**
* @brief Check if clock is ready (running)
* @param[in] clock The clock to check
* @return True if the clock is ready.
*/
bool clocks_ready(clock_t clock);
/**
* @brief Wait until the clock is ready.
* @details Useful after enabling the clock.
* @param[in] clock The clock to wait for.
*/
void clocks_wait_ready(clock_t clock);
/**
* @brief Configures parameters of a pll.
* @details Fractional scaling is currently not supported. The clock frequency will be input_freq / divm * divn / divX, where X is p, q, r for each output respectively.
* @param[in] pll The pll number.
* @param[in] vcosel What vco to select. See reference manual for details.
* @param[in] divm Divide initial clock frequency by this
* @param[in] source Where the source clock to pll is coming from.
* @param[in] divn Multiply the frequency of in / divm by this number
* @param[in] divp Divisor on the output P. If zero, the output is disabled.
* @param[in] divq Divisor on the output Q. If zero, the output is disabled.
* @param[in] divr Divisor on the output R. If zero, the output is disabled.
*/
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);
/**
* @brief Enable the given pll, after configuring.
* @param[in] pll The pll to enable.
*/
void clocks_pll_enable(clock_pll_t pll);
/**
* @brief Disable the given pll.
* @details This should be done only if the pll is not being used at the moment.
* @param[in] pll Description
*/
void clocks_pll_disable(clock_pll_t pll);
/**
* @brief Wait until the pll is ready.
* @param[in] pll The pll to wait for.
* @param[in] timeout_us Timeout, with maximum wait for the pll.
*/
void clocks_pll_wait_ready(clock_pll_t pll, uint16_t timeout_us);
/**
* @brief Change system clock to the specified clock.
* @details The flash read time might have to be adjusted. Also don't forget about rising the voltage if frequency is too high.
* @param[in] source Where to obtain system clock from.
* @param[in] d1cpre Divisor for 1cpre
* @param[in] d1ppre Divisor for 1ppre
* @param[in] hpre Description Divisor for hpre
* @param[in] timeout_us Description The maximum wait time.
*/
void clocks_system_clock_source(sysclock_source_t source, uint8_t d1cpre,
uint8_t d1ppre, uint8_t hpre,
uint16_t timeout_us);
#endif // CLOCKS_H