1 /*
2  * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #ifndef _PICO_STDLIB_H
8 #define _PICO_STDLIB_H
9 
10 #include "pico.h"
11 #include "pico/stdio.h"
12 #include "pico/time.h"
13 #include "hardware/gpio.h"
14 #include "hardware/uart.h"
15 
16 #ifdef __cplusplus
17 extern "C" {
18 #endif
19 
20 /** \file stdlib.h
21  *  \defgroup pico_stdlib pico_stdlib
22  *
23  * Aggregation of a core subset of Raspberry Pi Pico SDK libraries used by most executables along with some additional
24  * utility methods. Including pico_stdlib gives you everything you need to get a basic program running
25  * which prints to stdout or flashes a LED
26  *
27  * This library aggregates:
28  *   - @ref hardware_uart
29  *   - @ref hardware_gpio
30  *   - @ref pico_binary_info
31  *   - @ref pico_runtime
32  *   - @ref pico_platform
33  *   - @ref pico_printf
34  *   - @ref pico_stdio
35  *   - @ref pico_standard_link
36  *   - @ref pico_util
37  *
38  * There are some basic default values used by these functions that will default to
39  * usable values, however, they can be customised in a board definition header via
40  * config.h or similar
41  */
42 
43 // Note PICO_STDIO_UART, PICO_STDIO_USB, PICO_STDIO_SEMIHOSTING are set by the
44 // respective INTERFACE libraries, so these defines are set if the library
45 // is included for the target executable
46 
47 #if LIB_PICO_STDIO_UART
48 #include "pico/stdio_uart.h"
49 #endif
50 
51 #if LIB_PICO_STDIO_USB
52 #include "pico/stdio_usb.h"
53 #endif
54 
55 #if LIB_PICO_STDIO_SEMIHOSTING
56 #include "pico/stdio_semihosting.h"
57 #endif
58 
59 // PICO_CONFIG: PICO_DEFAULT_LED_PIN, Optionally define a pin that drives a regular LED on the board, group=pico_stdlib
60 
61 // PICO_CONFIG: PICO_DEFAULT_LED_PIN_INVERTED, 1 if LED is inverted or 0 if not, type=int, default=0, group=pico_stdlib
62 #ifndef PICO_DEFAULT_LED_PIN_INVERTED
63 #define PICO_DEFAULT_LED_PIN_INVERTED 0
64 #endif
65 
66 // PICO_CONFIG: PICO_DEFAULT_WS2812_PIN, Optionally define a pin that controls data to a WS2812 compatible LED on the board, group=pico_stdlib
67 // PICO_CONFIG: PICO_DEFAULT_WS2812_POWER_PIN, Optionally define a pin that controls power to a WS2812 compatible LED on the board, group=pico_stdlib
68 
69 /*! \brief Set up the default UART and assign it to the default GPIO's
70  *  \ingroup pico_stdlib
71  *
72  * By default this will use UART 0, with TX to pin GPIO 0,
73  * RX to pin GPIO 1, and the baudrate to 115200
74  *
75  * Calling this method also initializes stdin/stdout over UART if the
76  * @ref pico_stdio_uart library is linked.
77  *
78  * Defaults can be changed using configuration defines,
79  *  PICO_DEFAULT_UART_INSTANCE,
80  *  PICO_DEFAULT_UART_BAUD_RATE
81  *  PICO_DEFAULT_UART_TX_PIN
82  *  PICO_DEFAULT_UART_RX_PIN
83  */
84 void setup_default_uart(void);
85 
86 /*! \brief Initialise the system clock to 48MHz
87  *  \ingroup pico_stdlib
88  *
89  *  Set the system clock to 48MHz, and set the peripheral clock to match.
90  */
91 void set_sys_clock_48mhz(void);
92 
93 /*! \brief Initialise the system clock
94  *  \ingroup pico_stdlib
95  *
96  * \param vco_freq The voltage controller oscillator frequency to be used by the SYS PLL
97  * \param post_div1 The first post divider for the SYS PLL
98  * \param post_div2 The second post divider for the SYS PLL.
99  *
100  * See the PLL documentation in the datasheet for details of driving the PLLs.
101  */
102 void set_sys_clock_pll(uint32_t vco_freq, uint post_div1, uint post_div2);
103 
104 /*! \brief Check if a given system clock frequency is valid/attainable
105  *  \ingroup pico_stdlib
106  *
107  * \param freq_khz Requested frequency
108  * \param vco_freq_out On success, the voltage controller oscillator frequeucny to be used by the SYS PLL
109  * \param post_div1_out On success, The first post divider for the SYS PLL
110  * \param post_div2_out On success, The second post divider for the SYS PLL.
111  * @return true if the frequency is possible and the output parameters have been written.
112  */
113 bool check_sys_clock_khz(uint32_t freq_khz, uint *vco_freq_out, uint *post_div1_out, uint *post_div2_out);
114 
115 /*! \brief Attempt to set a system clock frequency in khz
116  *  \ingroup pico_stdlib
117  *
118  * Note that not all clock frequencies are possible; it is preferred that you
119  * use src/rp2_common/hardware_clocks/scripts/vcocalc.py to calculate the parameters
120  * for use with set_sys_clock_pll
121  *
122  * \param freq_khz Requested frequency
123  * \param required if true then this function will assert if the frequency is not attainable.
124  * \return true if the clock was configured
125  */
set_sys_clock_khz(uint32_t freq_khz,bool required)126 static inline bool set_sys_clock_khz(uint32_t freq_khz, bool required) {
127     uint vco, postdiv1, postdiv2;
128     if (check_sys_clock_khz(freq_khz, &vco, &postdiv1, &postdiv2)) {
129         set_sys_clock_pll(vco, postdiv1, postdiv2);
130         return true;
131     } else if (required) {
132         panic("System clock of %u kHz cannot be exactly achieved", freq_khz);
133     }
134     return false;
135 }
136 
137 #ifdef __cplusplus
138 }
139 #endif
140 #endif
141