Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions firmware/PIMORONI_BADGER2040/micropython.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ target_compile_definitions(usermod_wakeup INTERFACE
-DWAKEUP_PIN_VALUE=0b10000000000000010000000000
)

# Use our LOCAL system_speed module from firmware/modules/system_speed
include(firmware/modules/system_speed/micropython)

# Note: cppmem is *required* for C++ code to function on MicroPython
# it redirects `malloc` and `free` calls to MicroPython's heap
include(cppmem/micropython)
Expand Down
1 change: 1 addition & 0 deletions firmware/PIMORONI_BADGER2040/mpconfigboard.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// This is a hack! Need to replace with upstream board definition.
#define MICROPY_HW_BOARD_NAME "Pimoroni Badger2040 2MB"
#define MICROPY_HW_FLASH_STORAGE_BYTES (1408 * 1024)
#define PICO_VBUS_PIN 24
3 changes: 3 additions & 0 deletions firmware/PIMORONI_BADGER2040W/micropython.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ target_compile_definitions(usermod_wakeup INTERFACE
-DWAKEUP_PIN_VALUE=0b10000000000010000000000
)

# Use our LOCAL system_speed module from firmware/modules/system_speed
include(firmware/modules/system_speed/micropython)

# Note: cppmem is *required* for C++ code to function on MicroPython
# it redirects `malloc` and `free` calls to MicroPython's heap
include(cppmem/micropython)
Expand Down
1 change: 1 addition & 0 deletions firmware/PIMORONI_BADGER2040W/mpconfigboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#define CYW43_LWIP (1)
#define CYW43_GPIO (1)
#define CYW43_SPI_PIO (1)
#define CYW43_WL_GPIO_VBUS_PIN (2)

// For debugging mbedtls - also set
// Debug level (0-4) 1=warning, 2=info, 3=debug, 4=verbose
Expand Down
26 changes: 26 additions & 0 deletions firmware/modules/system_speed/micropython.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
add_library(usermod_system_speed INTERFACE)

target_sources(usermod_system_speed INTERFACE
${CMAKE_CURRENT_LIST_DIR}/system_speed.c
${CMAKE_CURRENT_LIST_DIR}/system_speed.cpp
)

target_include_directories(usermod_system_speed INTERFACE
${CMAKE_CURRENT_LIST_DIR}
)

target_compile_definitions(usermod_system_speed INTERFACE
-DMODULE_SYSTEM_SPEED_ENABLED=1
)

target_link_libraries(usermod INTERFACE usermod_system_speed
hardware_vreg
hardware_pll
hardware_resets
)

set_source_files_properties(
${CMAKE_CURRENT_LIST_DIR}/system_speed.c
PROPERTIES COMPILE_FLAGS
"-Wno-discarded-qualifiers"
)
28 changes: 28 additions & 0 deletions firmware/modules/system_speed/system_speed.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include "system_speed.h"

STATIC MP_DEFINE_CONST_FUN_OBJ_1(system_speed_set_obj, system_speed_set);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(system_speed_vbus_get_obj, system_speed_vbus_get);

STATIC const mp_map_elem_t system_speed_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_system_speed) },
{ MP_ROM_QSTR(MP_QSTR_set_speed), MP_ROM_PTR(&system_speed_set_obj) },
{ MP_ROM_QSTR(MP_QSTR_get_vbus), MP_ROM_PTR(&system_speed_vbus_get_obj) },

{ MP_ROM_QSTR(MP_QSTR_SYSTEM_VERY_SLOW), MP_ROM_INT(0) },
{ MP_ROM_QSTR(MP_QSTR_SYSTEM_SLOW), MP_ROM_INT(1) },
{ MP_ROM_QSTR(MP_QSTR_SYSTEM_NORMAL), MP_ROM_INT(2) },
{ MP_ROM_QSTR(MP_QSTR_SYSTEM_FAST), MP_ROM_INT(3) },
{ MP_ROM_QSTR(MP_QSTR_SYSTEM_TURBO), MP_ROM_INT(4) },
};
STATIC MP_DEFINE_CONST_DICT(mp_module_system_speed_globals, system_speed_globals_table);

const mp_obj_module_t system_speed_user_cmodule = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&mp_module_system_speed_globals,
};

#if MICROPY_VERSION <= 70144
MP_REGISTER_MODULE(MP_QSTR_system_speed, system_speed_user_cmodule, MODULE_SYSTEM_SPEED_ENABLED);
#else
MP_REGISTER_MODULE(MP_QSTR_system_speed, system_speed_user_cmodule);
#endif
122 changes: 122 additions & 0 deletions firmware/modules/system_speed/system_speed.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
#include "hardware/gpio.h"
#include "common/pimoroni_common.hpp"

extern "C" {
#include "system_speed.h"
#include "pico/stdlib.h"
#include "hardware/vreg.h"
#include "hardware/clocks.h"
#include "hardware/pll.h"

#if defined CYW43_WL_GPIO_VBUS_PIN
#include "extmod/modnetwork.h"
#include "lib/cyw43-driver/src/cyw43.h"
#endif

#if MICROPY_HW_ENABLE_UART_REPL
#include "uart.h"
#endif

static void _set_system_speed(uint32_t selected_speed) {
uint32_t sys_freq;

switch (selected_speed)
{
case 4: // TURBO: 250 MHZ, 1.2V
vreg_set_voltage(VREG_VOLTAGE_1_20);
set_sys_clock_khz(250000, true);
return;
case 3: // FAST: 133 MHZ
vreg_set_voltage(VREG_VOLTAGE_1_10);
set_sys_clock_khz(133000, true);
return;

default:
case 2: // NORMAL: 48 MHZ
vreg_set_voltage(VREG_VOLTAGE_1_10);
set_sys_clock_48mhz();
return;

case 1: // SLOW: 12 MHZ, 1.0V
sys_freq = 12 * MHZ;
break;

case 0: // VERY_SLOW: 4 MHZ, 1.0V
sys_freq = 4 * MHZ;
break;
}

// Set the configured clock speed, by dividing the USB PLL
clock_configure(clk_sys,
CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLKSRC_CLK_SYS_AUX,
CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB,
48 * MHZ,
sys_freq);

clock_configure(clk_peri,
0,
CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLK_SYS,
sys_freq,
sys_freq);

clock_configure(clk_adc,
0,
CLOCKS_CLK_ADC_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB,
48 * MHZ,
sys_freq);

// No longer using the SYS PLL so disable it
pll_deinit(pll_sys);

// Not using USB so stop the clock
clock_stop(clk_usb);

// Drop the core voltage
vreg_set_voltage(VREG_VOLTAGE_1_00);
}

static bool _vbus_get() {
bool vbus = false;
#if defined CYW43_WL_GPIO_VBUS_PIN
cyw43_gpio_get(&cyw43_state, CYW43_WL_GPIO_VBUS_PIN, &vbus);
#else
gpio_set_function(PICO_VBUS_PIN, GPIO_FUNC_SIO);
vbus = gpio_get(PICO_VBUS_PIN);
#endif
return vbus;
}

mp_obj_t system_speed_vbus_get() {
return _vbus_get() ? mp_const_true : mp_const_false;
}

mp_obj_t system_speed_set(mp_obj_t speed) {
uint32_t selected_speed = mp_obj_get_int(speed);

if (_vbus_get() && selected_speed < 2) {
// If on USB never go slower than normal speed.
selected_speed = 2;
}

_set_system_speed(selected_speed);

#if MICROPY_HW_ENABLE_UART_REPL
setup_default_uart();
mp_uart_init();
#endif

// TODO Make this work...
if (selected_speed >= 2) {
spi_set_baudrate(PIMORONI_SPI_DEFAULT_INSTANCE, 12 * MHZ);
}
else {
// Set the SPI baud rate for communicating with the display to
// go as fast as possible (which is now 6 or 2 MHz)
spi_get_hw(PIMORONI_SPI_DEFAULT_INSTANCE)->cpsr = 2;
hw_write_masked(&spi_get_hw(PIMORONI_SPI_DEFAULT_INSTANCE)->cr0, 0, SPI_SSPCR0_SCR_BITS);
}

return mp_const_none;
}

}
5 changes: 5 additions & 0 deletions firmware/modules/system_speed/system_speed.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#include "py/runtime.h"
#include "py/objstr.h"

extern mp_obj_t system_speed_set(mp_obj_t speed);
extern mp_obj_t system_speed_vbus_get();