Skip to content

Commit c5cbc6b

Browse files
committed
System Speed module for #24.
1 parent 5d3b139 commit c5cbc6b

File tree

8 files changed

+172
-0
lines changed

8 files changed

+172
-0
lines changed

firmware/PIMORONI_BADGER2040/micropython.cmake

+3
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ target_compile_definitions(usermod_wakeup INTERFACE
3939
-DWAKEUP_PIN_VALUE=0b10000000000000010000000000
4040
)
4141

42+
# Use our LOCAL system_speed module from firmware/modules/system_speed
43+
include(firmware/modules/system_speed/micropython)
44+
4245
# Note: cppmem is *required* for C++ code to function on MicroPython
4346
# it redirects `malloc` and `free` calls to MicroPython's heap
4447
include(cppmem/micropython)
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
// This is a hack! Need to replace with upstream board definition.
22
#define MICROPY_HW_BOARD_NAME "Pimoroni Badger2040 2MB"
33
#define MICROPY_HW_FLASH_STORAGE_BYTES (1408 * 1024)
4+
#define PICO_VBUS_PIN 24

firmware/PIMORONI_BADGER2040W/micropython.cmake

+3
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ target_compile_definitions(usermod_wakeup INTERFACE
4040
-DWAKEUP_PIN_VALUE=0b10000000000010000000000
4141
)
4242

43+
# Use our LOCAL system_speed module from firmware/modules/system_speed
44+
include(firmware/modules/system_speed/micropython)
45+
4346
# Note: cppmem is *required* for C++ code to function on MicroPython
4447
# it redirects `malloc` and `free` calls to MicroPython's heap
4548
include(cppmem/micropython)

firmware/PIMORONI_BADGER2040W/mpconfigboard.h

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#define CYW43_LWIP (1)
1212
#define CYW43_GPIO (1)
1313
#define CYW43_SPI_PIO (1)
14+
#define CYW43_WL_GPIO_VBUS_PIN (2)
1415

1516
// For debugging mbedtls - also set
1617
// Debug level (0-4) 1=warning, 2=info, 3=debug, 4=verbose
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
add_library(usermod_system_speed INTERFACE)
2+
3+
target_sources(usermod_system_speed INTERFACE
4+
${CMAKE_CURRENT_LIST_DIR}/system_speed.c
5+
${CMAKE_CURRENT_LIST_DIR}/system_speed.cpp
6+
)
7+
8+
target_include_directories(usermod_system_speed INTERFACE
9+
${CMAKE_CURRENT_LIST_DIR}
10+
)
11+
12+
target_compile_definitions(usermod_system_speed INTERFACE
13+
-DMODULE_SYSTEM_SPEED_ENABLED=1
14+
)
15+
16+
target_link_libraries(usermod INTERFACE usermod_system_speed
17+
hardware_vreg
18+
hardware_pll
19+
hardware_resets
20+
)
21+
22+
set_source_files_properties(
23+
${CMAKE_CURRENT_LIST_DIR}/system_speed.c
24+
PROPERTIES COMPILE_FLAGS
25+
"-Wno-discarded-qualifiers"
26+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#include "system_speed.h"
2+
3+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(system_speed_set_obj, system_speed_set);
4+
5+
STATIC const mp_map_elem_t system_speed_globals_table[] = {
6+
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_system_speed) },
7+
{ MP_ROM_QSTR(MP_QSTR_set_speed), MP_ROM_PTR(&system_speed_set_obj) },
8+
9+
{ MP_ROM_QSTR(MP_QSTR_SYSTEM_VERY_SLOW), MP_ROM_INT(0) },
10+
{ MP_ROM_QSTR(MP_QSTR_SYSTEM_SLOW), MP_ROM_INT(1) },
11+
{ MP_ROM_QSTR(MP_QSTR_SYSTEM_NORMAL), MP_ROM_INT(2) },
12+
{ MP_ROM_QSTR(MP_QSTR_SYSTEM_FAST), MP_ROM_INT(3) },
13+
{ MP_ROM_QSTR(MP_QSTR_SYSTEM_TURBO), MP_ROM_INT(4) },
14+
};
15+
STATIC MP_DEFINE_CONST_DICT(mp_module_system_speed_globals, system_speed_globals_table);
16+
17+
const mp_obj_module_t system_speed_user_cmodule = {
18+
.base = { &mp_type_module },
19+
.globals = (mp_obj_dict_t*)&mp_module_system_speed_globals,
20+
};
21+
22+
#if MICROPY_VERSION <= 70144
23+
MP_REGISTER_MODULE(MP_QSTR_system_speed, system_speed_user_cmodule, MODULE_SYSTEM_SPEED_ENABLED);
24+
#else
25+
MP_REGISTER_MODULE(MP_QSTR_system_speed, system_speed_user_cmodule);
26+
#endif
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
#include "hardware/gpio.h"
2+
3+
extern "C" {
4+
#include "system_speed.h"
5+
#include "hardware/vreg.h"
6+
#include "hardware/clocks.h"
7+
#include "hardware/pll.h"
8+
9+
#if defined CYW43_WL_GPIO_VBUS_PIN
10+
#include "pico/cyw43_arch.h"
11+
#endif
12+
13+
#if MICROPY_HW_ENABLE_UART_REPL
14+
#include "uart.h"
15+
#endif
16+
17+
static void _set_system_speed(uint32_t selected_speed) {
18+
uint32_t sys_freq;
19+
20+
switch (selected_speed)
21+
{
22+
case 4: // TURBO: 250 MHZ, 1.2V
23+
vreg_set_voltage(VREG_VOLTAGE_1_20);
24+
set_sys_clock_khz(250000, true);
25+
return;
26+
case 3: // FAST: 133 MHZ
27+
vreg_set_voltage(VREG_VOLTAGE_1_10);
28+
set_sys_clock_khz(133000, true);
29+
return;
30+
31+
default:
32+
case 2: // NORMAL: 48 MHZ
33+
vreg_set_voltage(VREG_VOLTAGE_1_10);
34+
set_sys_clock_48mhz();
35+
return;
36+
37+
case 1: // SLOW: 12 MHZ, 1.0V
38+
sys_freq = 12 * MHZ;
39+
break;
40+
41+
case 0: // VERY_SLOW: 4 MHZ, 1.0V
42+
sys_freq = 4 * MHZ;
43+
break;
44+
}
45+
46+
// Set the configured clock speed, by dividing the USB PLL
47+
clock_configure(clk_sys,
48+
CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLKSRC_CLK_SYS_AUX,
49+
CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB,
50+
48 * MHZ,
51+
sys_freq);
52+
53+
clock_configure(clk_peri,
54+
0,
55+
CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLK_SYS,
56+
sys_freq,
57+
sys_freq);
58+
59+
clock_configure(clk_adc,
60+
0,
61+
CLOCKS_CLK_ADC_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB,
62+
48 * MHZ,
63+
sys_freq);
64+
65+
// No longer using the SYS PLL so disable it
66+
pll_deinit(pll_sys);
67+
68+
// Not using USB so stop the clock
69+
clock_stop(clk_usb);
70+
71+
// Drop the core voltage
72+
vreg_set_voltage(VREG_VOLTAGE_1_00);
73+
}
74+
75+
mp_obj_t system_speed_set(mp_obj_t speed) {
76+
uint32_t selected_speed = mp_obj_get_int(speed);
77+
78+
#if defined CYW43_WL_GPIO_VBUS_PIN
79+
bool vbus = cyw43_arch_gpio_get(CYW43_WL_GPIO_VBUS_PIN);
80+
#else
81+
bool vbus = gpio_get(PICO_VBUS_PIN);
82+
#endif
83+
if (vbus && selected_speed < 2) {
84+
// If on USB never go slower than normal speed.
85+
selected_speed = 2;
86+
}
87+
88+
_set_system_speed(selected_speed);
89+
90+
#if MICROPY_HW_ENABLE_UART_REPL
91+
setup_default_uart();
92+
mp_uart_init();
93+
#endif
94+
95+
if (selected_speed >= 2) {
96+
spi_set_baudrate(PIMORONI_SPI_DEFAULT_INSTANCE, 12 * MHZ);
97+
}
98+
else {
99+
// Set the SPI baud rate for communicating with the display to
100+
// go as fast as possible (which is now 6 or 2 MHz)
101+
spi_get_hw(PIMORONI_SPI_DEFAULT_INSTANCE)->cpsr = 2;
102+
hw_write_masked(&spi_get_hw(PIMORONI_SPI_DEFAULT_INSTANCE)->cr0, 0, SPI_SSPCR0_SCR_BITS);
103+
}
104+
105+
return mp_const_none;
106+
}
107+
108+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#include "py/runtime.h"
2+
#include "py/objstr.h"
3+
4+
extern mp_obj_t system_speed_set(mp_obj_t speed);

0 commit comments

Comments
 (0)