Ship UDP RGB panel firmware (eight WS2812 strips) and drop the ESP32 Wi-Fi/MicroPython stack. Co-authored-by: Cursor <cursoragent@cursor.com>
148 lines
4.5 KiB
Makefile
148 lines
4.5 KiB
Makefile
# Portal panel firmware — build and USB deploy
|
|
#
|
|
# make # build only
|
|
# make deploy # build + flash over USB (picotool)
|
|
#
|
|
# Options (also via repo-root .env — see .env.example):
|
|
# make deploy PANEL_ID=0
|
|
# make deploy NETWORK=dhcp
|
|
# make deploy IP=10.1.1.10 GATEWAY=10.1.1.1
|
|
# make deploy WS2812_PIN=26 WS2812_PIN1=27
|
|
#
|
|
# Environment:
|
|
# PICO_SDK_PATH default: ~/pico-sdk (fallback ~/pico/pico-sdk)
|
|
|
|
MAKEFILE_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
|
|
-include $(MAKEFILE_DIR)../.env
|
|
-include $(MAKEFILE_DIR).env
|
|
|
|
ifeq ($(origin PICO_SDK_PATH), undefined)
|
|
ifneq ($(wildcard $(HOME)/pico-sdk/pico_sdk_init.cmake),)
|
|
PICO_SDK_PATH := $(HOME)/pico-sdk
|
|
else
|
|
PICO_SDK_PATH := $(HOME)/pico/pico-sdk
|
|
endif
|
|
endif
|
|
|
|
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
|
|
NETWORK ?= static
|
|
|
|
comma := ,
|
|
dot_to_csv = $(subst .,$(comma),$(1))
|
|
|
|
CMAKE_ARGS :=
|
|
ifdef PANEL_ID
|
|
CMAKE_ARGS += -DPANEL_ID_BUILD=$(PANEL_ID)
|
|
endif
|
|
ifdef WS2812_PIN
|
|
CMAKE_ARGS += -DWS2812_PIN_BUILD=$(WS2812_PIN)
|
|
endif
|
|
ifdef WS2812_PIN1
|
|
CMAKE_ARGS += -DWS2812_PIN1_BUILD=$(WS2812_PIN1)
|
|
endif
|
|
ifdef IP
|
|
CMAKE_ARGS += -DSTATIC_IP_BUILD=$(call dot_to_csv,$(IP))
|
|
endif
|
|
ifdef NETMASK
|
|
CMAKE_ARGS += -DSTATIC_SN_BUILD=$(call dot_to_csv,$(NETMASK))
|
|
endif
|
|
ifdef GATEWAY
|
|
CMAKE_ARGS += -DSTATIC_GW_BUILD=$(call dot_to_csv,$(GATEWAY))
|
|
endif
|
|
ifdef DNS
|
|
CMAKE_ARGS += -DSTATIC_DNS_BUILD=$(call dot_to_csv,$(DNS))
|
|
endif
|
|
ifeq ($(NETWORK),dhcp)
|
|
CMAKE_ARGS += -DPORTAL_USE_DHCP=ON
|
|
else ifeq ($(NO_DHCP),0)
|
|
CMAKE_ARGS += -DPORTAL_USE_DHCP=ON
|
|
else
|
|
CMAKE_ARGS += -DPORTAL_USE_DHCP=OFF
|
|
endif
|
|
|
|
CMAKE_STAMP_BODY := $(strip $(CMAKE_ARGS))
|
|
|
|
.PHONY: all build configure reconfigure deploy flash upload reset monitor clean help
|
|
|
|
all: build
|
|
|
|
help:
|
|
@echo "Targets:"
|
|
@echo " make build Build panel.uf2"
|
|
@echo " make deploy Build and flash over USB"
|
|
@echo " make reset USB reboot Pico"
|
|
@echo " make monitor USB serial console"
|
|
@echo " make clean Remove build directory"
|
|
|
|
build: configure
|
|
@echo "==> Building panel firmware"
|
|
# Host GCC 15 needs cstdint for pico-sdk pioasm
|
|
CXXFLAGS='-include cstdint' 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)" && 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)"; \
|
|
CXXFLAGS='-include cstdint' PICO_SDK_PATH="$(PICO_SDK_PATH)" cmake -S . -B $(BUILD_DIR) $(CMAKE_ARGS); \
|
|
echo "$$STAMP" > "$(CMAKE_STAMP)"; \
|
|
fi
|
|
|
|
reconfigure:
|
|
@mkdir -p $(BUILD_DIR)
|
|
CXXFLAGS='-include cstdint' 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"; exit 1; }
|
|
@echo "==> Uploading $(UF2) over USB"
|
|
@picotool load -x -f "$(UF2)"
|
|
|
|
flash: deploy
|
|
upload: deploy
|
|
|
|
reset:
|
|
@command -v picotool >/dev/null || { echo "Error: picotool not found"; exit 1; }
|
|
@picotool reboot -f
|
|
@i=0; last=; \
|
|
while [ $$i -lt 50 ]; do \
|
|
cur=$$(ls /dev/ttyACM* 2>/dev/null | head -1); \
|
|
if [ -n "$$cur" ] && [ "$$cur" = "$$last" ]; then \
|
|
sleep 0.5; \
|
|
if [ -e "$$cur" ]; then echo "==> Ready ($$cur)"; exit 0; fi; \
|
|
fi; \
|
|
last=$$cur; \
|
|
i=$$((i + 1)); sleep 0.2; \
|
|
done; \
|
|
echo "==> Warning: serial not ready yet"; exit 0
|
|
|
|
monitor:
|
|
@command -v picocom >/dev/null || { echo "Error: picocom not found"; exit 1; }
|
|
@SERIAL=; i=0; \
|
|
while [ $$i -lt 40 ]; do \
|
|
for d in $(SERIAL_PORT) $$(ls /dev/ttyACM* 2>/dev/null); do \
|
|
[ -n "$$d" ] && [ -e "$$d" ] || continue; \
|
|
SERIAL=$$d; break; \
|
|
done; \
|
|
[ -n "$$SERIAL" ] && [ -e "$$SERIAL" ] && break; \
|
|
i=$$((i + 1)); sleep 0.25; \
|
|
done; \
|
|
if [ -z "$$SERIAL" ] || [ ! -e "$$SERIAL" ]; then echo "Error: no serial port"; exit 1; fi; \
|
|
echo "==> monitor $$SERIAL"; \
|
|
exec picocom --baud $(SERIAL_BAUD) --flow n --echo --noreset "$$SERIAL"
|
|
|
|
clean:
|
|
rm -rf $(BUILD_DIR)
|