-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
29 changed files
with
2,997 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
.build | ||
build/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
#!/bin/bash -e | ||
|
||
# This script is used to compile the holly low-power mode firmware using the pico-sdk. | ||
# It then exports it to 'flash.h' for inclusion in the QMK firmware. | ||
# This does not need to be re-run unless the low-power firmware is changed. | ||
|
||
# push into the script directory so that relative paths are correct | ||
SCRIPT_PATH=$(dirname "$(realpath -s "$0")") | ||
pushd "$SCRIPT_PATH" || exit 1 | ||
pushd holly_lpm || exit 1 | ||
|
||
# build the firmware | ||
mkdir -p build && pushd build && cmake .. -DPICO_BOARD="holly"; make -j"$(nproc)" | ||
LPM_FW_PATH="$(realpath holly_lpm.bin)" | ||
popd || exit 1 | ||
|
||
# get the path to uf2conv.py | ||
UF2CONV="$(realpath util/uf2conv.py)" | ||
popd || exit 1 | ||
python3 "$UF2CONV" "$LPM_FW_PATH" --carray | ||
|
||
# build the QMK firmware | ||
# qmk compile -kb nullbitsco/holly -km via |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
/* | ||
Copyright 2021 Jay Greco | ||
This program is free software: you can redistribute it and/or modify | ||
it under the terms of the GNU General Public License as published by | ||
the Free Software Foundation, either version 2 of the License, or | ||
(at your option) any later version. | ||
This program is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
GNU General Public License for more details. | ||
You should have received a copy of the GNU General Public License | ||
along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
/* NOTE: This config file is specific to RP2040 builds. */ | ||
|
||
#pragma once | ||
|
||
#define RGBLIGHT_DEFAULT_MODE RGBLIGHT_MODE_CHRISTMAS | ||
|
||
/* RP2040-specific defines*/ | ||
#define PICO_XOSC_STARTUP_DELAY_MULTIPLIER 64 | ||
#define RP2040_FLASH_GENERIC_03H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
// Copyright 2022 Jay Greco | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
|
||
#pragma once | ||
|
||
#define HAL_USE_ADC TRUE | ||
|
||
#include_next <halconf.h> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
// Copyright 2022 Jay Greco | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
|
||
#include "holly.h" | ||
#include "flash.h" | ||
#include "usb_util.h" | ||
#include "analog.h" | ||
|
||
static void disable_interrupts(void) | ||
{ | ||
SysTick_CTRL &= ~1; | ||
|
||
NVIC_ICER = 0xFFFFFFFF; | ||
NVIC_ICPR = 0xFFFFFFFF; | ||
} | ||
|
||
static void reset_peripherals(void) | ||
{ | ||
RESET = ~( | ||
RESETS_RESET_IO_QSPI_BITS | | ||
RESETS_RESET_PADS_QSPI_BITS | | ||
RESETS_RESET_SYSCFG_BITS | | ||
RESETS_RESET_PLL_SYS_BITS | ||
); | ||
} | ||
|
||
static void jump_to_vtor(uint32_t vtor) | ||
{ | ||
uint32_t reset_vector = *(volatile uint32_t *)(vtor + 0x04); | ||
|
||
SCB_VTOR = (volatile uint32_t)(vtor); | ||
|
||
asm volatile("msr msp, %0"::"g" (*(volatile uint32_t *)vtor)); | ||
asm volatile("bx %0"::"r" (reset_vector)); | ||
} | ||
|
||
void keyboard_post_init_kb(void) { | ||
#ifdef CONSOLE_ENABLE | ||
debug_enable = true; | ||
debug_matrix = true; | ||
#endif | ||
|
||
keyboard_post_init_user(); | ||
|
||
#define SAMPLE_PERIODS 10 | ||
#define MIN_READINGS 800 | ||
|
||
int rolling_sum = 0; | ||
for (int i=0; i<SAMPLE_PERIODS; i++) { | ||
uint16_t reading = analogReadPin(VIN_PIN); | ||
rolling_sum += (int)reading; | ||
dprintf("adc reading: %u\n", reading); | ||
wait_ms(100); | ||
} | ||
|
||
rolling_sum /= SAMPLE_PERIODS; | ||
dprintf("final avg: %d\n", rolling_sum); | ||
|
||
// If either of the following are true, assume that we're running on battery power | ||
// Jump into the low-power optimized firmware, which will last much longer | ||
if (!usb_connected_state() || rolling_sum < MIN_READINGS) { | ||
dprintf("jumping to: %lu\n", (uint32_t)&bindata); | ||
wait_ms(100); | ||
disable_interrupts(); | ||
reset_peripherals(); | ||
jump_to_vtor((uint32_t)&bindata); | ||
} else { | ||
// Turn on the RGB LED power supplies | ||
setPinOutput(LED_VCC1); | ||
setPinOutput(LED_VCC2); | ||
writePinHigh(LED_VCC1); | ||
writePinHigh(LED_VCC2); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
// Copyright 2022 Jay Greco | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
|
||
#pragma once | ||
|
||
#include "quantum.h" | ||
#include <hal.h> | ||
|
||
#define LED_VCC1 GP7 | ||
#define LED_VCC2 GP6 | ||
#define VIN_PIN GP29 | ||
|
||
#define RESETS_RESET_IO_QSPI_BITS 0x00000040 | ||
#define RESETS_RESET_PADS_QSPI_BITS 0x00000200 | ||
#define RESETS_RESET_SYSCFG_BITS 0x00040000 | ||
#define RESETS_RESET_PLL_SYS_BITS 0x00001000 | ||
|
||
#define SysTick_CTRL (*(uint32_t *)(0xE0000000UL + 0xE010UL)) | ||
#define NVIC_ICER (*(uint32_t *)(0xE0000000UL + 0xE180UL)) | ||
#define NVIC_ICPR (*(uint32_t *)(0xE0000000UL + 0xE280UL)) | ||
#define RESET (*(uint32_t *)(0x4000C000UL + 0x2000UL)) | ||
#define SCB_VTOR (*(uint32_t *)(0xE0000000UL + 0xED08UL)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
cmake_minimum_required(VERSION 3.13) | ||
|
||
set(PICO_SDK_FETCH_FROM_GIT on) | ||
|
||
include(pico_sdk_import.cmake) | ||
project(test_project C CXX ASM) | ||
set(PICO_BOARD_HEADER_DIRS ${CMAKE_SOURCE_DIR}) | ||
|
||
pico_sdk_init() | ||
|
||
set(CMAKE_C_STANDARD 11) | ||
set(CMAKE_CXX_STANDARD 17) | ||
|
||
add_executable(holly_lpm holly_lpm.c) | ||
|
||
target_sources(holly_lpm PUBLIC | ||
${CMAKE_CURRENT_LIST_DIR}/clocks.c | ||
${CMAKE_CURRENT_LIST_DIR}/peripherals.c | ||
${CMAKE_CURRENT_LIST_DIR}/sleep.c | ||
) | ||
|
||
target_link_libraries(holly_lpm pico_stdlib hardware_pio hardware_rtc hardware_clocks) | ||
|
||
pico_add_extra_outputs(holly_lpm) | ||
|
||
pico_enable_stdio_usb(holly_lpm 0) | ||
pico_enable_stdio_uart(holly_lpm 0) | ||
|
||
# Check if the -DBOOT2 flag is defined | ||
# -DBOOT2 enables boot2 | ||
if (DEFINED BOOT2 AND BOOT2 EQUAL 1) | ||
message(STATUS "BOOT2 flag is ${BOOT2}, building with boot2") | ||
else () | ||
message(STATUS "BOOT2 flag is not set, building without boot2") | ||
pico_set_linker_script(holly_lpm ${CMAKE_CURRENT_LIST_DIR}/memmap_custom.ld) | ||
endif () | ||
|
||
# Check if the -DDEBUG flag is defined | ||
# -DDEBUG enables DEBUG and turns on debug via USB | ||
if (DEFINED DEBUG AND DEBUG EQUAL 1) | ||
message(STATUS "DEBUG flag is ${DEBUG}, building with debug") | ||
pico_enable_stdio_usb(holly_lpm 1) | ||
set_target_properties(holly_lpm PROPERTIES OUTPUT_NAME "holly_lpm_debug") | ||
else () | ||
message(STATUS "DEBUG flag is not set, building NODEBUG") | ||
endif () |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
#include "clocks.h" | ||
|
||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include "pico/stdlib.h" | ||
|
||
#include "hardware/clocks.h" | ||
#include "hardware/pll.h" | ||
#include "hardware/xosc.h" | ||
#include "hardware/structs/rosc.h" | ||
|
||
const uint32_t clocks_hw_wake_en0 = ~( | ||
CLOCKS_WAKE_EN0_CLK_SYS_SPI1_BITS | | ||
CLOCKS_WAKE_EN0_CLK_PERI_SPI1_BITS | | ||
CLOCKS_WAKE_EN0_CLK_SYS_SPI0_BITS | | ||
CLOCKS_WAKE_EN0_CLK_PERI_SPI0_BITS | | ||
CLOCKS_WAKE_EN0_CLK_SYS_PWM_BITS | | ||
CLOCKS_WAKE_EN0_CLK_SYS_PIO1_BITS | | ||
CLOCKS_WAKE_EN0_CLK_SYS_JTAG_BITS | | ||
CLOCKS_WAKE_EN0_CLK_SYS_I2C1_BITS | | ||
CLOCKS_WAKE_EN0_CLK_SYS_I2C0_BITS | | ||
CLOCKS_WAKE_EN0_CLK_SYS_DMA_BITS | | ||
CLOCKS_WAKE_EN0_CLK_SYS_ADC_BITS | | ||
CLOCKS_WAKE_EN0_CLK_ADC_ADC_BITS ); | ||
|
||
const uint32_t clocks_hw_wake_en1 = ~( | ||
CLOCKS_WAKE_EN1_CLK_SYS_WATCHDOG_BITS | | ||
#if !LIB_PICO_STDIO_USB | ||
CLOCKS_WAKE_EN1_CLK_USB_USBCTRL_BITS | | ||
CLOCKS_WAKE_EN1_CLK_SYS_USBCTRL_BITS | | ||
#endif | ||
CLOCKS_WAKE_EN1_CLK_SYS_UART0_BITS | | ||
CLOCKS_WAKE_EN1_CLK_PERI_UART0_BITS ); | ||
|
||
const uint32_t clocks_hw_sleep_en0 = ~( | ||
CLOCKS_SLEEP_EN0_CLK_SYS_SPI1_BITS | | ||
CLOCKS_SLEEP_EN0_CLK_PERI_SPI1_BITS | | ||
CLOCKS_SLEEP_EN0_CLK_SYS_SPI0_BITS | | ||
CLOCKS_SLEEP_EN0_CLK_PERI_SPI0_BITS | | ||
CLOCKS_SLEEP_EN0_CLK_SYS_ROM_BITS | | ||
CLOCKS_SLEEP_EN0_CLK_SYS_SIO_BITS | | ||
CLOCKS_SLEEP_EN0_CLK_SYS_PWM_BITS | | ||
CLOCKS_SLEEP_EN0_CLK_SYS_PSM_BITS | | ||
CLOCKS_SLEEP_EN0_CLK_SYS_PIO1_BITS | | ||
CLOCKS_SLEEP_EN0_CLK_SYS_PADS_BITS | | ||
CLOCKS_SLEEP_EN0_CLK_SYS_JTAG_BITS | | ||
CLOCKS_SLEEP_EN0_CLK_SYS_I2C1_BITS | | ||
CLOCKS_SLEEP_EN0_CLK_SYS_I2C0_BITS | | ||
CLOCKS_SLEEP_EN0_CLK_SYS_DMA_BITS | | ||
CLOCKS_SLEEP_EN0_CLK_SYS_ADC_BITS | | ||
CLOCKS_SLEEP_EN0_CLK_ADC_ADC_BITS ); | ||
|
||
const uint32_t clocks_hw_sleep_en1 = ~( | ||
CLOCKS_SLEEP_EN1_CLK_SYS_XIP_BITS | | ||
CLOCKS_SLEEP_EN1_CLK_SYS_WATCHDOG_BITS | | ||
#if !LIB_PICO_STDIO_USB | ||
CLOCKS_SLEEP_EN1_CLK_USB_USBCTRL_BITS | | ||
CLOCKS_SLEEP_EN1_CLK_SYS_USBCTRL_BITS | | ||
#endif | ||
CLOCKS_SLEEP_EN1_CLK_SYS_UART1_BITS | | ||
CLOCKS_SLEEP_EN1_CLK_PERI_UART1_BITS | | ||
CLOCKS_SLEEP_EN1_CLK_SYS_UART0_BITS | | ||
CLOCKS_SLEEP_EN1_CLK_PERI_UART0_BITS ); | ||
|
||
static inline void rosc_write(io_rw_32 *addr, uint32_t value) { | ||
hw_clear_bits(&rosc_hw->status, ROSC_STATUS_BADWRITE_BITS); | ||
*addr = value; | ||
}; | ||
|
||
static void rosc_set_range(uint range) { | ||
rosc_write(&rosc_hw->ctrl, (ROSC_CTRL_ENABLE_VALUE_ENABLE << ROSC_CTRL_ENABLE_LSB) | range); | ||
} | ||
|
||
void measure_freqs(void) { | ||
uint f_pll_sys = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_PLL_SYS_CLKSRC_PRIMARY); | ||
uint f_pll_usb = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_PLL_USB_CLKSRC_PRIMARY); | ||
uint f_rosc = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_ROSC_CLKSRC_PH); | ||
uint f_xosc = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_XOSC_CLKSRC); | ||
uint f_clk_sys = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_SYS); | ||
uint f_clk_peri = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_PERI); | ||
uint f_clk_usb = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_USB); | ||
uint f_clk_adc = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_ADC); | ||
uint f_clk_rtc = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_CLK_RTC); | ||
|
||
DBG_PRINTF("pll_sys = %dkHz\n", f_pll_sys); | ||
DBG_PRINTF("pll_usb = %dkHz\n", f_pll_usb); | ||
DBG_PRINTF("rosc = %dkHz\n", f_rosc); | ||
DBG_PRINTF("xosc = %dkHz\n", f_xosc); | ||
DBG_PRINTF("clk_sys = %dkHz\n", f_clk_sys); | ||
DBG_PRINTF("clk_peri = %dkHz\n", f_clk_peri); | ||
DBG_PRINTF("clk_usb = %dkHz\n", f_clk_usb); | ||
DBG_PRINTF("clk_adc = %dkHz\n", f_clk_adc); | ||
DBG_PRINTF("clk_rtc = %dkHz\n", f_clk_rtc); | ||
|
||
DBG_PRINTF("sysclk_get_hz: %d\n", clock_get_hz(clk_sys)); | ||
} | ||
|
||
void configure_clocks(void) { | ||
#if LIB_PICO_STDIO_USB | ||
stdio_init_all(); | ||
sleep_ms(1000); | ||
#endif | ||
|
||
// Bump up ROSC freq before switching over | ||
// rosc_set_range(ROSC_CTRL_FREQ_RANGE_VALUE_MEDIUM); | ||
uint f_rosc = frequency_count_khz(CLOCKS_FC0_SRC_VALUE_ROSC_CLKSRC); | ||
|
||
// CLK_REF = XOSC or ROSC | ||
clock_configure(clk_ref, | ||
CLOCKS_CLK_REF_CTRL_SRC_VALUE_ROSC_CLKSRC_PH, | ||
0, // No aux mux | ||
f_rosc * KHZ, | ||
f_rosc * KHZ); | ||
|
||
// CLK SYS = CLK_REF | ||
clock_configure(clk_sys, | ||
CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLK_REF, | ||
0, // Using glitchless mux | ||
f_rosc * KHZ, | ||
f_rosc * KHZ); | ||
|
||
#if !LIB_PICO_STDIO_USB | ||
clock_stop(clk_usb); | ||
#endif | ||
clock_stop(clk_adc); | ||
|
||
// CLK RTC = clk_sys | ||
clock_configure(clk_rtc, | ||
0, // No GLMUX | ||
CLOCKS_CLK_RTC_CTRL_AUXSRC_VALUE_ROSC_CLKSRC_PH, | ||
f_rosc * KHZ, | ||
46875); | ||
|
||
// CLK PERI = clk_sys. Used as reference clock for Peripherals. No dividers so just select and enable | ||
clock_configure(clk_peri, | ||
0, | ||
CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLK_SYS, | ||
f_rosc * KHZ, | ||
f_rosc * KHZ); | ||
|
||
pll_deinit(pll_sys); | ||
#if !LIB_PICO_STDIO_USB | ||
pll_deinit(pll_usb); | ||
xosc_disable(); | ||
#else | ||
stdio_init_all(); | ||
sleep_ms(1000); | ||
measure_freqs(); | ||
#endif | ||
|
||
// Set default sleep and wake clocks | ||
clocks_hw->wake_en0 = clocks_hw_wake_en0; | ||
clocks_hw->wake_en1 = clocks_hw_wake_en1; | ||
|
||
clocks_hw->sleep_en0 = clocks_hw_sleep_en0; | ||
clocks_hw->sleep_en1 = clocks_hw_sleep_en1; | ||
} | ||
|
||
__force_inline void restore_clocks(void) { | ||
// Reset sleep-mode clocks back to default | ||
clocks_hw->sleep_en0 = clocks_hw_sleep_en0; | ||
clocks_hw->sleep_en1 = clocks_hw_sleep_en1; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
#pragma once | ||
|
||
void measure_freqs(void); | ||
void configure_clocks(void); | ||
void restore_clocks(void); |
Oops, something went wrong.