upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/Makefile
diff options
context:
space:
mode:
Diffstat (limited to 'Makefile')
-rw-r--r--Makefile206
1 files changed, 206 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..7de799e
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,206 @@
1SHELL := /bin/bash
2.DEFAULT_GOAL := help
3
4-include .env
5export
6
7IDF_PATH ?= $(HOME)/esp/esp-idf
8PROJECT_DIR := $(shell pwd)
9BUILD_DIR := $(PROJECT_DIR)/build
10PORT_A ?= /dev/ttyACM0
11PORT_B ?= /dev/ttyACM1
12PORT ?= $(PORT_A)
13BAUD ?= 460800
14TARGET ?= esp32s3
15
16NODE ?= node
17NPM ?= npm
18PYTHON ?= python3
19
20.PHONY: help setup detect-ports detect-chip detect-all
21.PHONY: flash flash-a flash-b monitor monitor-a monitor-b
22.PHONY: test smoke test-api test-portal test-network test-full
23.PHONY: tokens test-payment
24.PHONY: clean erase-nvs reset serial-log
25.PHONY: bootstrap-config
26
27help:
28 @echo "TollGate ESP32 — Makefile"
29 @echo ""
30 @echo "Discovery:"
31 @echo " detect-ports List connected ESP32 serial ports"
32 @echo " detect-chip Identify chip type on PORT"
33 @echo " detect-all Full device inventory"
34 @echo ""
35 @echo "Build & Flash:"
36 @echo " flash Build + flash to PORT (default: PORT_A)"
37 @echo " flash-a Flash to PORT_A"
38 @echo " flash-b Flash to PORT_B"
39 @echo " monitor Serial monitor on PORT"
40 @echo ""
41 @echo "Test (Phase 1):"
42 @echo " test Run all Phase 1 tests"
43 @echo " smoke Quick 30s smoke test"
44 @echo " test-api curl API endpoint tests"
45 @echo " test-portal Playwright captive portal tests"
46 @echo " test-network DNS/NAT connectivity tests"
47 @echo " test-full All 14 Phase 1 tests"
48 @echo ""
49 @echo "Test (Phase 2):"
50 @echo " tokens Mint test Cashu tokens (AMOUNT=21)"
51 @echo " test-payment Payment flow tests"
52 @echo ""
53 @echo "Utilities:"
54 @echo " setup One-time: install esptool, deps"
55 @echo " clean Clean build"
56 @echo " erase-nvs Erase NVS partition on PORT"
57 @echo " reset Hardware reset on PORT"
58 @echo " bootstrap-config Write .env values to SPIFFS config.json"
59 @echo " serial-log Capture serial output"
60
61# ──────────────────────────────────────────────
62# Discovery
63# ──────────────────────────────────────────────
64
65detect-ports:
66 @echo "=== Serial Ports ==="
67 @ls /dev/ttyACM* /dev/ttyUSB* 2>/dev/null || echo "No serial ports found"
68 @echo ""
69 @echo "=== USB Devices ==="
70 @lsusb 2>/dev/null | grep -i -E "serial|uart|cp210|ch340|ftdi|esp" || true
71 @echo ""
72 @echo "=== By ID ==="
73 @ls -la /dev/serial/by-id/ 2>/dev/null || true
74
75detect-chip:
76 @echo "=== Detecting chip on $(PORT) ==="
77 @python3 -m esptool --port $(PORT) chip_id 2>&1 || \
78 $(PYTHON) -c "import esptool; esptool.main(['--port','$(PORT)','chip_id'])" 2>&1 || \
79 echo "esptool not found. Run: pip install esptool"
80 @echo ""
81 @python3 -m esptool --port $(PORT) flash_id 2>&1 || true
82
83detect-all: detect-ports
84 @for port in /dev/ttyACM* /dev/ttyUSB*; do \
85 [ -e "$$port" ] || continue; \
86 echo ""; \
87 echo "=== Device at $$port ==="; \
88 python3 -m esptool --port $$port chip_id 2>&1 | head -5 || true; \
89 python3 -m esptool --port $$port flash_id 2>&1 | head -5 || true; \
90 done
91
92# ──────────────────────────────────────────────
93# Setup
94# ──────────────────────────────────────────────
95
96setup:
97 @echo "=== Installing esptool ==="
98 pip install esptool 2>/dev/null || pip3 install esptool
99 @echo ""
100 @echo "=== Checking ESP-IDF ==="
101 @test -d $(IDF_PATH) && echo "ESP-IDF found at $(IDF_PATH)" || \
102 echo "ESP-IDF not found at $(IDF_PATH). Install from https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/"
103 @echo ""
104 @echo "=== Installing Node deps ==="
105 $(NPM) install
106 @echo ""
107 @echo "=== Installing Python deps ==="
108 pip install pyserial 2>/dev/null || pip3 install pyserial
109 @echo ""
110 @echo "Setup complete!"
111
112# ──────────────────────────────────────────────
113# Build & Flash
114# ──────────────────────────────────────────────
115
116flash: build
117 @echo "=== Flashing to $(PORT) ==="
118 . $(IDF_PATH)/export.sh && idf.py -p $(PORT) -b $(BAUD) flash
119
120flash-a: PORT=$(PORT_A)
121flash-a: flash
122
123flash-b: PORT=$(PORT_B)
124flash-b: flash
125
126build:
127 @echo "=== Building $(TARGET) ==="
128 . $(IDF_PATH)/export.sh && \
129 idf.py set-target $(TARGET) 2>/dev/null; \
130 idf.py build
131
132monitor:
133 . $(IDF_PATH)/export.sh && idf.py -p $(PORT) monitor
134
135monitor-a: PORT=$(PORT_A)
136monitor-a: monitor
137
138monitor-b: PORT=$(PORT_B)
139monitor-b: monitor
140
141# ──────────────────────────────────────────────
142# Test Infrastructure
143# ──────────────────────────────────────────────
144
145test: test-api test-network
146 @echo "=== All tests passed ==="
147
148smoke:
149 @echo "=== Running smoke test (30s) ==="
150 $(NODE) tests/smoke.mjs $(PORT)
151
152test-api:
153 @echo "=== Running API tests ==="
154 $(NODE) tests/api.mjs
155
156test-portal:
157 @echo "=== Running Playwright portal tests ==="
158 npx playwright test tests/captive-portal.spec.mjs
159
160test-network:
161 @echo "=== Running network tests ==="
162 $(NODE) tests/network.mjs
163
164test-full: test-api test-portal test-network
165 @echo "=== Full test suite passed ==="
166
167# ──────────────────────────────────────────────
168# Phase 2: Payment Testing
169# ──────────────────────────────────────────────
170
171tokens:
172 @echo "=== Minting test tokens from $(TEST_MINT) ==="
173 @AMOUNT=$${AMOUNT:-21}; \
174 cd scripts/mint-token && go run main.go -mint https://$(TEST_MINT) -amount $$AMOUNT
175
176test-payment:
177 @echo "=== Running payment tests ==="
178 $(NODE) tests/payment.mjs
179
180# ──────────────────────────────────────────────
181# Utilities
182# ──────────────────────────────────────────────
183
184clean:
185 rm -rf $(BUILD_DIR) sdkconfig sdkconfig.old
186 . $(IDF_PATH)/export.sh && idf.py fullclean
187
188erase-nvs:
189 @echo "=== Erasing NVS on $(PORT) ==="
190 . $(IDF_PATH)/export.sh && \
191 partition_offset=$$(idf.py partition-table 2>/dev/null | grep nvs | awk '{print $$2}'); \
192 python3 -m esptool --port $(PORT) erase_region $$partition_offset 0x6000
193
194reset:
195 @echo "=== Resetting device on $(PORT) ==="
196 python3 -m esptool --port $(PORT) run 2>/dev/null || true
197
198serial-log:
199 @echo "=== Capturing serial output from $(PORT) ==="
200 python3 -c "import serial; s=serial.Serial('$(PORT)',115200,timeout=1); \
201 [print(s.readline().decode(errors='replace'),end='') for _ in iter(lambda: s.readline(), b'')]"
202
203bootstrap-config:
204 @echo "=== Bootstrapping config.json ==="
205 @echo '{"wifi_networks":[{"ssid":"$(WIFI_SSID)","password":"$(WIFI_PASSWORD)"}],"ap_ssid":"$(AP_SSID)","ap_password":"$(AP_PASSWORD)","mint_url":"$(MINT_URL)","lnurl_url":"$(LNURL_URL)","price_per_step":$(PRICE_PER_STEP),"step_size_ms":$(STEP_SIZE)}' > main/config.json
206 @echo "Config written to main/config.json"