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