--- /dev/null
+uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')
+
+DEVICE=attiny85
+F_CPU=1000000
+#F_CPU=128000
+ifeq ($(uname_S),Linux)
+#SERIAL:=/dev/ttyACM0
+#AVRDUDE = avrdude -c usbasp -p $(DEVICE) -b 19200
+AVRDUDE = avrdude -c atmelice_isp -p $(DEVICE)
+else
+SERIAL=COM5
+AVRDUDE = avrdude -c avrisp -p $(DEVICE) -P $(SERIAL) -b 19200 \
+ -C/opt/arduino-1.0.3/hardware/tools/avr/etc/avrdude.conf
+endif
+
+INC = -I.
+COMPILE = avr-gcc -Wall -Os $(INC) -mmcu=$(DEVICE) -DF_CPU=$(F_CPU)
+
+OBJECTS = main.o
+
+# symbolic targets:
+all: main.hex
+
+.c.o:
+ $(COMPILE) -c $< -o $@
+
+.S.o:
+ @$(COMPILE) -x assembler-with-cpp -c $< -o $@
+# "-x assembler-with-cpp" should not be necessary since this is the default
+# file type for the .S (with capital S) extension. However, upper case
+# characters are not always preserved on Windows. To ensure WinAVR
+# compatibility define the file type manually.
+
+.c.s:
+ @$(COMPILE) -S $< -o $@
+
+flash: all
+ $(AVRDUDE) -U flash:w:main.hex:i
+
+# Fuse high byte:
+# 0xdd = 1 1 0 1 1 1 0 1
+# ^ ^ ^ ^ ^ \-+-/
+# | | | | | +------ BODLEVEL 2..0 (brownout trigger level -> 2.7V)
+# | | | | +---------- EESAVE (preserve EEPROM on Chip Erase -> not preserved)
+# | | | +-------------- WDTON (watchdog timer always on -> disable)
+# | | +---------------- SPIEN (enable serial programming -> enabled)
+# | +------------------ DWEN (debug wire enable)
+# +-------------------- RSTDISBL (disable external reset -> enabled)
+#
+# Fuse low byte:
+# 0xe1 = 1 1 1 0 0 0 0 1
+# ^ ^ \+/ \--+--/
+# | | | +------- CKSEL 3..0 (clock selection -> HF PLL)
+# | | +--------------- SUT 1..0 (BOD enabled, fast rising power)
+# | +------------------ CKOUT (clock output on CKOUT pin -> disabled)
+# +-------------------- CKDIV8 (divide clock by 8, 1 means divided)
+# For 16.5MHz internal: -U hfuse:w:0xd5:m -U lfuse:w:0xe1:m
+# For 12MHz crystal: -U hfuse:w:0xdd:m -U lfuse:w:0b11111111:m
+# For 8MHz internal: -U hfuse:w:0xd5:m -U lfuse:w:0xe2:m
+# For 1MHz internal: -U hfuse:w:0xd5:m -U lfuse:w:0x62:m
+# For 128kHz clock : -U hfuse:w:0xdf:m -U lfuse:w:0xe4:m
+# Note: 0xd5 is as per 0xdd but with EESAVE enabled.
+
+fuse:
+ @echo "Programming fuses for 1MHz internal oscillator (BOD disabled)"
+ $(AVRDUDE) -U hfuse:w:0xdf:m -U lfuse:w:0x62:m
+
+readcal:
+ $(AVRDUDE) -U calibration:r:/dev/stdout:i | head -1
+
+eeread:
+ $(AVRDUDE) -U eeprom:r:eeprom:i
+
+eewrite:
+ $(AVRDUDE) -U eeprom:w:eeprom:i
+
+clean:
+ @rm -f main.hex main.lst main.obj main.cof main.list main.map main.eep.hex main.bin *.o
+
+# file targets:
+main.bin: $(OBJECTS)
+ $(COMPILE) -o main.bin $(OBJECTS)
+
+main.hex: main.bin
+ @rm -f main.hex
+ @avr-objcopy -j .text -j .data -O ihex main.bin main.hex
+ @$(SHELL) checksize main.bin 8192 256
+# do the checksize script as our last action to allow successful compilation
+# on Windows with WinAVR where the Unix commands will fail.
+
+eeprom: main.eep.hex
+main.eep.hex: main.bin
+ @avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \
+ --change-section-lma .eeprom=0 -O ihex main.bin main.eep.hex
+ @echo call configure_eeprom.py to set eeprom values
+
+flash_eeprom:
+ $(AVRDUDE) -U eeprom:w:main.eep.hex:i
+
+disasm: main.bin
+ avr-objdump -d main.bin
+
+cpp:
+ $(COMPILE) -E main.c
--- /dev/null
+#!/bin/sh
+# Name: checksize
+# Project: PowerSwitch/AVR-USB
+# Author: Christian Starkjohann
+# Creation Date: 2004-12-29
+# Tabsize: 4
+# Copyright: (c) 2005 OBJECTIVE DEVELOPMENT Software GmbH.
+# Revision: $Id: checksize 83 2006-01-05 22:20:53Z cs $
+
+error=0
+codelimit=2048 # default value
+datalimit=96 # default value; leave 32 bytes for stack
+AWK=$(which gawk || which awk)
+
+if [ $# -gt 1 ]; then
+ codelimit="$2"
+fi
+if [ $# -gt 2 ]; then
+ datalimit="$3"
+fi
+
+set -- `avr-size -d "$1" | $AWK '/[0-9]/ {print $1 + $2, $2 + $3, $2}'`
+if [ $1 -gt $codelimit ]; then
+ echo "*** code size $1 exceeds limit of $codelimit"
+ error=1
+else
+ echo "ROM: $1 bytes (data=$3)"
+fi
+if [ $2 -gt $datalimit ]; then
+ echo "*** data size $2 exceeds limit of $datalimit"
+ error=1
+else
+ echo "RAM: $2 bytes"
+fi
+
+exit $error
--- /dev/null
+/* Copyright (c) 2016 Pat Thoyts <patthoyts@users.sourceforge.net>
+ *
+ * Demonstration using the watchdog timer to put an ATtiny to sleep
+ * for long periods. Using the WDT allows us to power the device
+ * down completely and only wake it up once a second to update the
+ * count of seconds. Could use to turn on a sensor package once
+ * every half hour for instance.
+ *
+ * Measuring pin voltages with an oscilloscope shows it really is off
+ * for all but 500ns of the second. Also that the WDT timer is not
+ * very accurate. I measured 1.09s intervals.
+ *
+ * Fuses set to run the clock at 8MHz. Could drop to 1Mhz for more
+ * power saving? Acc. the datasheet, 8MHz@3V3 is 3mA but 0.7mA for 1MHz
+ * and around 0.1mA using the 128kHz clock source.
+ * For this purpose, use 128kHz. Still has same accuracy and same on
+ * time when measured.
+ *
+ * On my board, measured 1.48mA when asleep and around 4mA when active
+ * (including LED) at 3V3. Seems the same at 128kHz and 1Mhz.
+ */
+
+#ifndef F_CPU
+#error F_CPU undefined
+#endif
+
+#include <avr/interrupt.h>
+#include <avr/io.h>
+#include <avr/power.h>
+#include <avr/sleep.h>
+#include <avr/wdt.h>
+#include <util/delay.h>
+
+#define SLEEP_TIME 10;
+volatile uint16_t counter = SLEEP_TIME;
+
+ISR(WDT_vect)
+{
+ --counter;
+ if (counter == 0)
+ {
+ PORTB |= _BV(PB4);
+ counter = SLEEP_TIME;
+ } else {
+ PORTB &= ~_BV(PB4);
+ }
+}
+
+int __attribute__((noreturn))
+main(void)
+{
+ int n;
+
+ if (bit_is_set(MCUSR, WDRF)) /* if reset caused by wdt */
+ {
+ MCUSR &= ~_BV(WDRF); /* clear wdt reset bit */
+ wdt_disable();
+ }
+
+ cli();
+ WDTCR |= _BV(WDCE) | _BV(WDE); /* enable change bit */
+ WDTCR = _BV(WDIE) | WDTO_1S; /* enable wdt interrupt */
+ sei();
+
+ /* set all ports output and low */
+ DDRB = 0xff;
+ PORTB = 0x00;
+
+ /* some fast flashes to show startup */
+ for (n = 0; n < 12; ++n)
+ {
+ PORTB ^= _BV(PB3);
+ _delay_ms(50);
+ }
+
+ power_all_disable();
+ set_sleep_mode(SLEEP_MODE_PWR_DOWN);
+ sleep_enable();
+ sei();
+
+ for (;;)
+ {
+ sleep_enable();
+ /* testing shows awake for 500ns then sleep for 1s */
+ PORTB &= ~_BV(PB3);
+ cli();
+ sleep_bod_disable();
+ sei();
+ sleep_cpu();
+ sleep_disable();
+ PORTB |= _BV(PB3);
+ }
+}