Skip to content

Commit bbc9893

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

File tree

8 files changed

+188
-0
lines changed

8 files changed

+188
-0
lines changed

firmware/PIMORONI_BADGER2040/micropython.cmake

Lines changed: 3 additions & 0 deletions
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)
Lines changed: 1 addition & 0 deletions
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

Lines changed: 3 additions & 0 deletions
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

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

0 commit comments

Comments
 (0)