1
+ #include " hardware/gpio.h"
2
+ #include " common/pimoroni_common.hpp"
3
+
4
+ extern " C" {
5
+ #include " system_speed.h"
6
+ #include " pico/stdlib.h"
7
+ #include " hardware/vreg.h"
8
+ #include " hardware/clocks.h"
9
+ #include " hardware/pll.h"
10
+
11
+ #if defined CYW43_WL_GPIO_VBUS_PIN
12
+ #include " extmod/modnetwork.h"
13
+ #include " lib/cyw43-driver/src/cyw43.h"
14
+ #endif
15
+
16
+ #if MICROPY_HW_ENABLE_UART_REPL
17
+ #include " uart.h"
18
+ #endif
19
+
20
+ static void _set_system_speed (uint32_t selected_speed) {
21
+ uint32_t sys_freq;
22
+
23
+ switch (selected_speed)
24
+ {
25
+ case 4 : // TURBO: 250 MHZ, 1.2V
26
+ vreg_set_voltage (VREG_VOLTAGE_1_20);
27
+ set_sys_clock_khz (250000 , true );
28
+ return ;
29
+ case 3 : // FAST: 133 MHZ
30
+ vreg_set_voltage (VREG_VOLTAGE_1_10);
31
+ set_sys_clock_khz (133000 , true );
32
+ return ;
33
+
34
+ default :
35
+ case 2 : // NORMAL: 48 MHZ
36
+ vreg_set_voltage (VREG_VOLTAGE_1_10);
37
+ set_sys_clock_48mhz ();
38
+ return ;
39
+
40
+ case 1 : // SLOW: 12 MHZ, 1.0V
41
+ sys_freq = 12 * MHZ;
42
+ break ;
43
+
44
+ case 0 : // VERY_SLOW: 4 MHZ, 1.0V
45
+ sys_freq = 4 * MHZ;
46
+ break ;
47
+ }
48
+
49
+ // Set the configured clock speed, by dividing the USB PLL
50
+ clock_configure (clk_sys,
51
+ CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLKSRC_CLK_SYS_AUX,
52
+ CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB,
53
+ 48 * MHZ,
54
+ sys_freq);
55
+
56
+ clock_configure (clk_peri,
57
+ 0 ,
58
+ CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLK_SYS,
59
+ sys_freq,
60
+ sys_freq);
61
+
62
+ clock_configure (clk_adc,
63
+ 0 ,
64
+ CLOCKS_CLK_ADC_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB,
65
+ 48 * MHZ,
66
+ sys_freq);
67
+
68
+ // No longer using the SYS PLL so disable it
69
+ pll_deinit (pll_sys);
70
+
71
+ // Not using USB so stop the clock
72
+ clock_stop (clk_usb);
73
+
74
+ // Drop the core voltage
75
+ vreg_set_voltage (VREG_VOLTAGE_1_00);
76
+ }
77
+
78
+ static bool _vbus_get () {
79
+ bool vbus = false ;
80
+ #if defined CYW43_WL_GPIO_VBUS_PIN
81
+ cyw43_gpio_get (&cyw43_state, CYW43_WL_GPIO_VBUS_PIN, &vbus);
82
+ #else
83
+ gpio_set_function (PICO_VBUS_PIN, GPIO_FUNC_SIO);
84
+ vbus = gpio_get (PICO_VBUS_PIN);
85
+ #endif
86
+ return vbus;
87
+ }
88
+
89
+ mp_obj_t system_speed_vbus_get () {
90
+ return _vbus_get () ? mp_const_true : mp_const_false;
91
+ }
92
+
93
+ mp_obj_t system_speed_set (mp_obj_t speed) {
94
+ uint32_t selected_speed = mp_obj_get_int (speed);
95
+
96
+ if (_vbus_get () && selected_speed < 2 ) {
97
+ // If on USB never go slower than normal speed.
98
+ selected_speed = 2 ;
99
+ }
100
+
101
+ _set_system_speed (selected_speed);
102
+
103
+ #if MICROPY_HW_ENABLE_UART_REPL
104
+ setup_default_uart ();
105
+ mp_uart_init ();
106
+ #endif
107
+
108
+ // TODO Make this work...
109
+ if (selected_speed >= 2 ) {
110
+ spi_set_baudrate (PIMORONI_SPI_DEFAULT_INSTANCE, 12 * MHZ);
111
+ }
112
+ else {
113
+ // Set the SPI baud rate for communicating with the display to
114
+ // go as fast as possible (which is now 6 or 2 MHz)
115
+ spi_get_hw (PIMORONI_SPI_DEFAULT_INSTANCE)->cpsr = 2 ;
116
+ hw_write_masked (&spi_get_hw (PIMORONI_SPI_DEFAULT_INSTANCE)->cr0 , 0 , SPI_SSPCR0_SCR_BITS);
117
+ }
118
+
119
+ return mp_const_none;
120
+ }
121
+
122
+ }
0 commit comments