You've already forked ivan-torvalds-GuitarPedal
forked from AllSpiceMirrors/torvalds-GuitarPedal
Drop copy_to_ram. It was always the lazy option - I didn't want to work out which functions actually needed to be in SRAM, so I put all of them there. Now that the audio core is marked, the linker script already does the right thing: it pulls '.time_critical*' out of flash, and everything else is cold enough to run from XIP. RAM before: 73132 text + 386972 bss = 460104 RAM after: 20504 data + 384652 bss = 405156 which is 54948 bytes back, and takes the headroom from 70K to 124K out of 520K. That matters more than it sounds: bss is already 384K, mostly the 64K analyzer ring and the 64K FFT buffer, so headroom is the thing that was going to run out first. Also add scripts/check-audio.py, run after every link. Everything in a '.time_critical.audio_*' section may only call into another one, and anything else fails the build. Right now there is nothing on the allowed list at all - the audio path doesn't call a single library function - which is the whole reason to add the check now rather than after it has rotted. The last one to go was the newlib 'lrintf()' a couple of commits ago. The one thing this cannot check is that the code still *works* from flash. cpu1 is unaffected by construction since all of it is in RAM, but cpu0 now takes XIP cache misses, and the tuner does an 8192-point FFT at 25Hz. I think the cache holds the inner loop fine. I have not proven it on hardware. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
171 lines
4.6 KiB
CMake
171 lines
4.6 KiB
CMake
cmake_minimum_required(VERSION 3.13...3.27)
|
|
|
|
# initialize the SDK based on PICO_SDK_PATH
|
|
# note: this must happen before project()
|
|
include(pico-sdk/pico_sdk_init.cmake)
|
|
|
|
project(rp2350)
|
|
|
|
# initialize the Raspberry Pi Pico SDK
|
|
pico_sdk_init()
|
|
|
|
add_executable(blink)
|
|
|
|
# I should have used different PIO pins for MIDI
|
|
# but they conflict with the second rotary encoder
|
|
set(MIDI_HW OFF CACHE BOOL "Enable MIDI HW (not just MIDI over USB-C) support")
|
|
|
|
# The eeprom chip has changed from a 2kbit to a 64kbit one,
|
|
# and they aren't sw-compatible
|
|
set(EEPROM_64KBIT OFF CACHE BOOL "Configure for 64kbit eeprom chip")
|
|
|
|
set(SAMPLES_PER_SEC 48000.0)
|
|
set(SCRIPT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/scripts")
|
|
|
|
#
|
|
# Only the audio core runs from RAM: everything marked with
|
|
# __audio_func() lands in a '.time_critical.audio_*' section, which the
|
|
# default linker script already pulls out of flash. The rest is cold
|
|
# enough to run from XIP.
|
|
#
|
|
|
|
# Math table generation
|
|
set(POW2_STEP_SHIFT 8)
|
|
set(POW2_HEADER "${CMAKE_CURRENT_BINARY_DIR}/pow2.h")
|
|
add_custom_command(
|
|
OUTPUT "${POW2_HEADER}"
|
|
COMMAND "${SCRIPT_DIR}/pow2.py"
|
|
"${POW2_HEADER}"
|
|
"${POW2_STEP_SHIFT}"
|
|
DEPENDS "${SCRIPT_DIR}/pow2.py"
|
|
)
|
|
target_sources(blink PRIVATE "${POW2_HEADER}")
|
|
|
|
set(LOG2_STEP_SHIFT 8)
|
|
set(LOG2_HEADER "${CMAKE_CURRENT_BINARY_DIR}/log2.h")
|
|
add_custom_command(
|
|
OUTPUT "${LOG2_HEADER}"
|
|
COMMAND "${SCRIPT_DIR}/log2.py"
|
|
"${LOG2_HEADER}"
|
|
"${LOG2_STEP_SHIFT}"
|
|
DEPENDS "${SCRIPT_DIR}/log2.py"
|
|
)
|
|
target_sources(blink PRIVATE "${LOG2_HEADER}")
|
|
|
|
set(SINE_STEP_SHIFT 8)
|
|
set(SINE_HEADER "${CMAKE_CURRENT_BINARY_DIR}/quarter_sine.h")
|
|
add_custom_command(
|
|
OUTPUT "${SINE_HEADER}"
|
|
COMMAND "${SCRIPT_DIR}/quarter_sine.py"
|
|
"${SINE_HEADER}"
|
|
"${SINE_STEP_SHIFT}"
|
|
DEPENDS "${SCRIPT_DIR}/quarter_sine.py"
|
|
)
|
|
target_sources(blink PRIVATE "${SINE_HEADER}")
|
|
|
|
set(EQ_W0_HEADER "${CMAKE_CURRENT_BINARY_DIR}/eq-w0.h")
|
|
add_custom_command(
|
|
OUTPUT "${EQ_W0_HEADER}"
|
|
COMMAND "${SCRIPT_DIR}/eq-w0.py"
|
|
"${EQ_W0_HEADER}"
|
|
"${SAMPLES_PER_SEC}"
|
|
DEPENDS "${SCRIPT_DIR}/eq-w0.py"
|
|
)
|
|
target_sources(blink PRIVATE "${EQ_W0_HEADER}")
|
|
|
|
file(GLOB EFFECT_HEADERS CONFIGURE_DEPENDS "effects/*.h")
|
|
set(EFFECT_MAP_HEADER "${CMAKE_CURRENT_BINARY_DIR}/effect_map.h")
|
|
set(EFFECT_JS "${CMAKE_CURRENT_SOURCE_DIR}/WebMIDI/effects.js")
|
|
set(EFFECT_MD "${CMAKE_CURRENT_SOURCE_DIR}/MIDI_CC_MAP.md")
|
|
|
|
add_custom_command(
|
|
OUTPUT "${EFFECT_MAP_HEADER}" "${EFFECT_JS}" "${EFFECT_MD}"
|
|
COMMAND "${SCRIPT_DIR}/gen_effects.py"
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/effects"
|
|
"${EFFECT_MAP_HEADER}"
|
|
"${EFFECT_JS}"
|
|
"${EFFECT_MD}"
|
|
${EFFECT_HEADERS}
|
|
DEPENDS "${SCRIPT_DIR}/gen_effects.py" ${EFFECT_HEADERS}
|
|
)
|
|
target_sources(blink PRIVATE "${EFFECT_MAP_HEADER}")
|
|
|
|
set(PIO_DIR "${CMAKE_CURRENT_SOURCE_DIR}/pio")
|
|
|
|
pico_generate_pio_header(blink ${PIO_DIR}/ws2812.pio)
|
|
pico_generate_pio_header(blink ${PIO_DIR}/debounce.pio)
|
|
pico_generate_pio_header(blink ${PIO_DIR}/rotary.pio)
|
|
pico_generate_pio_header(blink ${PIO_DIR}/i2s.pio)
|
|
|
|
target_compile_definitions(blink PRIVATE
|
|
SYS_CLK_KHZ=153600
|
|
PLL_SYS_VCO_FREQ_HZ=768000000
|
|
PLL_SYS_POSTDIV1=5
|
|
PLL_SYS_POSTDIV2=1
|
|
MIDI_HW=$<BOOL:${MIDI_HW}>
|
|
EEPROM_64KBIT=$<BOOL:${EEPROM_64KBIT}>
|
|
SAMPLES_PER_SEC=${SAMPLES_PER_SEC}f
|
|
CFG_TUSB_MCU=OPT_MCU_RP2040
|
|
CFG_TUSB_OS=OPT_OS_PICO
|
|
CFG_TUSB_DEBUG=0)
|
|
|
|
target_sources(blink PRIVATE
|
|
blink.c
|
|
"${SINE_HEADER}"
|
|
tinyusb/src/tusb.c
|
|
tinyusb/src/common/tusb_fifo.c
|
|
tinyusb/src/portable/raspberrypi/rp2040/rp2040_usb.c
|
|
)
|
|
|
|
target_sources(blink PRIVATE
|
|
usb-device.c
|
|
tinyusb/src/device/usbd.c
|
|
tinyusb/src/class/audio/audio_device.c
|
|
tinyusb/src/class/midi/midi_device.c
|
|
tinyusb/src/portable/raspberrypi/rp2040/dcd_rp2040.c)
|
|
|
|
target_link_libraries(blink
|
|
pico_stdlib
|
|
pico_multicore
|
|
hardware_gpio
|
|
hardware_pwm
|
|
hardware_pio
|
|
hardware_i2c
|
|
hardware_dma)
|
|
|
|
target_include_directories(blink PRIVATE
|
|
include
|
|
tinyusb/src
|
|
"${CMAKE_CURRENT_BINARY_DIR}")
|
|
|
|
#
|
|
# We really don't care about IEEE precision, nor
|
|
# do we want double-precision math just because
|
|
# of some random constant (and adding ".0f" to them
|
|
# everywhere is just cray-cray)
|
|
#
|
|
# Add -fsingle-precision-constant / -Wdouble-promotion
|
|
# when starting to do FP for audio
|
|
#
|
|
target_compile_options(blink PRIVATE
|
|
-Wall -O2
|
|
-ffast-math
|
|
-fsingle-precision-constant
|
|
-Wfloat-conversion)
|
|
|
|
# Our own sources only - we don't get to pick the SDK's warnings
|
|
set_source_files_properties(blink.c usb-device.c PROPERTIES
|
|
COMPILE_OPTIONS -Wdouble-promotion)
|
|
|
|
# create map/bin/hex/uf2 file in addition to ELF.
|
|
pico_add_extra_outputs(blink)
|
|
|
|
# Nothing on the audio core is allowed to call out to a library
|
|
add_custom_command(TARGET blink POST_BUILD
|
|
COMMAND "${SCRIPT_DIR}/check-audio.py"
|
|
"$<TARGET_FILE:blink>.map"
|
|
"$<TARGET_FILE:blink>"
|
|
"${CMAKE_OBJDUMP}"
|
|
VERBATIM)
|
|
|