# Portal panel firmware — build and USB deploy # # Usage: # make # build only # make deploy # build + flash over USB (picotool) # make clean # # Options (passed to cmake on configure/reconfigure): # make deploy PANEL_ID=0 # make deploy NO_DHCP=1 # make deploy WS2812_PIN=28 # if data wire is on GP28 not GP27 # # Environment: # PICO_SDK_PATH default: ~/pico/pico-sdk # SERIAL_PORT default: first /dev/ttyACM* or /dev/ttyACM0 PICO_SDK_PATH ?= $(HOME)/pico/pico-sdk BUILD_DIR := build UF2 := $(BUILD_DIR)/panel.uf2 CMAKE_STAMP := $(BUILD_DIR)/.cmake_stamp JOBS ?= $(shell nproc 2>/dev/null || echo 4) SERIAL_PORT ?= $(shell ls /dev/ttyACM* 2>/dev/null | head -1) ifeq ($(SERIAL_PORT),) SERIAL_PORT := /dev/ttyACM0 endif SERIAL_BAUD ?= 115200 CMAKE_ARGS := ifdef PANEL_ID CMAKE_ARGS += -DPANEL_ID_BUILD=$(PANEL_ID) # Panels 0 and 4 are 9×39 (351); others are 9×45 (405). Always pass NUM_LEDS so # cmake cache cannot keep a stale count from a previous PANEL_ID flash. ifeq ($(PANEL_ID),0) NUM_LEDS ?= 351 else ifeq ($(PANEL_ID),4) NUM_LEDS ?= 351 else NUM_LEDS ?= 405 endif CMAKE_ARGS += -DNUM_LEDS_BUILD=$(NUM_LEDS) else ifdef NUM_LEDS CMAKE_ARGS += -DNUM_LEDS_BUILD=$(NUM_LEDS) endif endif ifdef WS2812_PIN CMAKE_ARGS += -DWS2812_PIN_BUILD=$(WS2812_PIN) endif ifeq ($(NO_DHCP),0) CMAKE_ARGS += -DPORTAL_USE_DHCP=ON else CMAKE_ARGS += -DPORTAL_USE_DHCP=OFF endif CMAKE_STAMP_BODY := $(strip $(CMAKE_ARGS)) SOURCES := $(wildcard *.c *.cpp *.h) WS2812.pio CMakeLists.txt pico_sdk_import.cmake .PHONY: all build configure reconfigure deploy flash upload monitor clean help all: build help: @echo "Targets:" @echo " make build Build panel.uf2" @echo " make deploy Build and flash over USB" @echo " make flash Alias for deploy" @echo " make monitor USB serial console (picocom, Ctrl+A Ctrl+X to quit)" @echo " make clean Remove build directory" @echo " make reconfigure Re-run cmake (e.g. after changing PANEL_ID)" build: configure @echo "==> Building panel firmware" PICO_SDK_PATH="$(PICO_SDK_PATH)" cmake --build $(BUILD_DIR) -j$(JOBS) @test -f "$(UF2)" || (echo "Error: build did not produce panel.uf2" && exit 1) @echo "==> Build OK: $(UF2)" configure: @test -d "$(PICO_SDK_PATH)" || (echo "Error: pico-sdk not found at $(PICO_SDK_PATH) (set PICO_SDK_PATH)" && exit 1) @command -v cmake >/dev/null || (echo "Error: cmake is required" && exit 1) @mkdir -p $(BUILD_DIR) @STAMP='$(CMAKE_STAMP_BODY)'; \ if [ ! -f "$(BUILD_DIR)/CMakeCache.txt" ] || [ ! -f "$(CMAKE_STAMP)" ] || [ "$$(cat $(CMAKE_STAMP))" != "$$STAMP" ]; then \ echo "==> Configuring cmake in $(BUILD_DIR) $(CMAKE_ARGS)"; \ PICO_SDK_PATH="$(PICO_SDK_PATH)" cmake -S . -B $(BUILD_DIR) $(CMAKE_ARGS); \ echo "$$STAMP" > "$(CMAKE_STAMP)"; \ fi reconfigure: @test -d "$(PICO_SDK_PATH)" || (echo "Error: pico-sdk not found at $(PICO_SDK_PATH) (set PICO_SDK_PATH)" && exit 1) @mkdir -p $(BUILD_DIR) @echo "==> Reconfiguring cmake in $(BUILD_DIR) $(CMAKE_ARGS)" PICO_SDK_PATH="$(PICO_SDK_PATH)" cmake -S . -B $(BUILD_DIR) $(CMAKE_ARGS) @echo '$(CMAKE_STAMP_BODY)' > $(CMAKE_STAMP) deploy: build @command -v picotool >/dev/null || (echo "Error: picotool not found (https://github.com/raspberrypi/picotool)" && exit 1) @picotool version 2>&1 | grep -q 'without USB support' && \ (echo "Error: picotool was built without USB support" && exit 1) || true @echo "==> Uploading $(UF2) over USB" @picotool load -x -f "$(UF2)" flash: deploy upload: deploy monitor: @command -v picocom >/dev/null || (echo "Error: picocom not found (sudo apt install picocom)" && exit 1) @test -e "$(SERIAL_PORT)" || (echo "Error: $(SERIAL_PORT) not found (plug in Pico USB, or set SERIAL_PORT=...)" && exit 1) @echo "==> Serial monitor on $(SERIAL_PORT) ($(SERIAL_BAUD) baud, Ctrl+A Ctrl+X to quit)" picocom --baud $(SERIAL_BAUD) --flow n --echo $(SERIAL_PORT) clean: rm -rf $(BUILD_DIR)