project
Ghost Hand
Public Unreviewedby John Lauer
A small battery gadget that keeps an automatic sink faucet running while you use the sink: it learns the faucet's timeout, re-arms with the shortest blip, and stops after 10 minutes or when picked up.
main
John Lauer
Studio: project overview, how it works, lights, charging, battery life, firmware source, dashboard screenshots; licenseā¦
c2eaf61
3d ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
# Ghost Hand firmware : ATtiny1616 @ 5 MHz (OSC20M / 4), avr-gcc + avr-libc
#
# make build build/ghost-hand.elf/.hex and print the size
# make test host-side learner tests (plain gcc)
# make flash program over UPDI with pymcuprog (serial UPDI adapter)
# make flash-avrdude same with avrdude -c serialupdi
# make fuses write the fuses listed below
#
# Toolchain: uses avr-gcc on PATH if it knows the attiny1616, otherwise the
# user-space Microchip toolchain + ATtiny DFP unpacked in .toolchain/ (see README).
PORT ?= /dev/ttyUSB0
MCU := attiny1616
TARGET := ghost-hand
BUILD := build
SRC := $(wildcard src/*.c)
OBJ := $(patsubst src/%.c,$(BUILD)/%.o,$(SRC))
TC := .toolchain/avr8-gnu-toolchain-linux_x86_64/bin
DFP := .toolchain/dfp
ifneq ($(wildcard $(TC)/avr-gcc),)
CC := $(TC)/avr-gcc
OBJCOPY := $(TC)/avr-objcopy
SIZE := $(TC)/avr-size
DEVFLAGS := -B $(DFP)/gcc/dev/$(MCU) -isystem $(DFP)/include
else
CC := avr-gcc
OBJCOPY := avr-objcopy
SIZE := avr-size
DEVFLAGS :=
endif
CFLAGS := -mmcu=$(MCU) $(DEVFLAGS) -DF_CPU=5000000UL -Os -std=gnu11 \
-Wall -Wextra -Wno-unused-parameter -ffunction-sections -fdata-sections \
-fshort-enums -flto
LDFLAGS := -mmcu=$(MCU) $(DEVFLAGS) -Wl,--gc-sections -flto -Os
# Fuses (ATtiny1614/16/17 datasheet 6.10.3 Fuse Summary)
# WDTCFG (0) 0x00 watchdog off at reset, firmware enables it (1 s) while awake
# BODCFG (1) 0x44 BOD 2.6 V (LVL=2), enabled in active, disabled in sleep (saves ~1 uA)
# OSCCFG (2) 0x02 FREQSEL 20 MHz (the firmware divides by 4 -> 5 MHz, by 2 -> 10 MHz)
# TCD0CFG (4) 0x00
# SYSCFG0 (5) 0xC5 CRCSRC none, RSTPINCFG UPDI, EESAVE=1 (keep the learnt faucet across reflash)
# SYSCFG1 (6) 0x07 64 ms start-up
# APPEND (7) 0x00, BOOTEND (8) 0x00 no boot section
FUSES := 0:0x00 1:0x44 2:0x02 4:0x00 5:0xC5 6:0x07 7:0x00 8:0x00
.PHONY: all size test flash flash-avrdude fuses fuses-avrdude clean
all: $(BUILD)/$(TARGET).hex size
$(BUILD)/%.o: src/%.c src/*.h | $(BUILD)
$(CC) $(CFLAGS) -c $< -o $@
$(BUILD)/$(TARGET).elf: $(OBJ)
$(CC) $(LDFLAGS) $^ -o $@ -Wl,-Map,$(BUILD)/$(TARGET).map
$(BUILD)/$(TARGET).hex: $(BUILD)/$(TARGET).elf
$(OBJCOPY) -O ihex -R .eeprom -R .fuse -R .lock -R .signature $< $@
$(BUILD):
mkdir -p $@
size: $(BUILD)/$(TARGET).elf
$(SIZE) $<
@echo "ATtiny1616: 16384 B flash, 2048 B SRAM, 256 B EEPROM"
test:
$(MAKE) -C test
flash: $(BUILD)/$(TARGET).hex
pymcuprog write -t uart -u $(PORT) -d $(MCU) -f $< --erase --verify
flash-avrdude: $(BUILD)/$(TARGET).hex
avrdude -c serialupdi -P $(PORT) -p t1616 -U flash:w:$<:i
fuses:
pymcuprog write -t uart -u $(PORT) -d $(MCU) -m fuses -o 0 -l 0x00 0x44 0x02
pymcuprog write -t uart -u $(PORT) -d $(MCU) -m fuses -o 4 -l 0x00 0xC5 0x07 0x00 0x00
fuses-avrdude:
avrdude -c serialupdi -P $(PORT) -p t1616 -U wdtcfg:w:0x00:m -U bodcfg:w:0x44:m \
-U osccfg:w:0x02:m -U syscfg0:w:0xC5:m -U syscfg1:w:0x07:m -U append:w:0x00:m -U bootend:w:0x00:m
clean:
rm -rf $(BUILD)
$(MAKE) -C test clean