Closed HokieGeek closed 8 years ago
#include <avr/interrupt.h>
#include <avr/sleep.h>
// #include "spi.h"
// #include "led-patterns.h"
#define VIBRATOR_PIN PB0
#define LEDS_PIN_DATA PB1
#define LEDS_PIN_SERIALCLOCK PB2
#define LEDS_PIN_CHIPSELECT PB3
#define PHOTOCELL_PIN PB4
// #define PHOTOCELL_ACTIVATE_THRESHOLD 80
// #define VIBRATE_PULSE 50
// SpiDevice *leds;
ISR(WDT_vect) {
// Nothing to do. Just wake up
}
int read_photocell() {
ADCSRA |= (1 << ADSC); // Start the conversion
while (ADCSRA & (1 << ADSC)); // Wait for conversion
return ADC;
}
int vibrate(int pulse) {
OCR0A = pulse;
}
void analyze_and_activate() {
/*
if (read_photocell() < PHOTOCELL_ACTIVATE_THRESHOLD) {
// TODO: vibrate(VIBRATE_PULSE);
// TODO: Apply an animation
// TODO: Turn on all leds
} else {
// TODO: Turn off all leds
}
*/
vibrate(read_photocell()); // This is strictly for testing
}
void init_pins() {
// Vibrator
TCCR0B |= (1 << CS01); // clock/8 (See 11-9)
TCCR0A |= (1 << WGM01) | (1 << WGM00); // Set for fast PWM with 0xFF Max (See 11-8)
TCCR0A |= (1 << COM0A1); // Clear on compare match (See 11-5)
DDRB |= (1 << VIBRATOR_PIN);
// The LEDS
/*
leds = Init3WireSpiDevice(LEDS_PIN_CHIPSELECT,
LEDS_PIN_SERIALCLOCK,
LEDS_PIN_DATA);
*/
// The photocell ADC. Enable ADC2 / PB4 as an ADC pin
ADMUX |= (0 << REFS0) | (1 << MUX1) | (0 << MUX0);
ADCSRA |= (1 << ADPS1) | (1 << ADPS0) | (1 << ADEN); // Enable ADC and set prescaler to clock/128
}
void init_interrupts() {
cli(); // JIC
// See table 8-2 on datasheet
// WDTCR |= (1 << WDP2) | (1 << WDP1) | (1 << WDP0); // Sleep for ~2s
WDTCR |= (1 << WDP2) | (1 << WDP1); // Sleep for ~1s
// WDTCR |= (1 << WDP2) | (1 << WDP0); // Sleep for ~30s
// WDTCR |= (1 << WDP2); // Sleep for ~15s
WDTCR |= (1 << WDTIE) | (0 << WDE); // Enable watchdog timer
WDTCR |= (0 << WDE);
sei();
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
}
int main(void) {
init_pins();
// init_interrupts();
// TODO: Read from light sensor (ADC)
// TODO: Do the vibrator (PWM)
// TODO: Control the LEDs (SPI)
// TODO: go to sleep for 30 seconds
for (;;) {
// ADCSRA &= ~(1 << ADEN); // Disable ADC
// sleep_mode();
// ADCSRA |= (1 << ADEN); // Enable ADC
analyze_and_activate();
}
}
prog=main
chip=t13
cpu_freq=
programmer=usbtiny
port=usb
CC=avr-gcc
CFLAGS=-funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes
DEPS =
OBJ = $(prog).o $(DEPS:.h=.o)
all: $(prog).eep $(prog).lss $(prog).sym
%.o: %.c $(DEPS)
@echo "== Compiling object file: $@" && \
$(CC) -c -mdeb -mmcu=$(chip) -I. -gdwarf-2 $(cpu_freq) -Os $(CFLAGS) -Wa,-adhlns=./$@.lst -std=gnu99 $< -o $@ || true
$(prog).eep: $(prog).elf
@echo "== Creating load file for EEPROM" && \
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 --no-change-warnings -O ihex $< $@
$(prog).lss: $(prog).elf
@echo "== Creating Extended Listing" && \
avr-objdump -h -S -z $< > $@
$(prog).sym: $(prog).elf
@echo "== Creating Symbol Table" && \
avr-nm -n $< > $@
$(prog).elf: $(prog).hex
@echo "== Creating load file for Flash" && \
avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock -R .signature $@ $^
$(prog).hex: $(OBJ)
@echo "== Creating hex" && \
$(CC) -mmcu=$(chip) -I. -mdeb -gdwarf-2 $(cpu_freq) -Os $(CFLAGS) -Wa,-adhlns=$< -std=gnu99 -MMD -MP -MF .dep/$(prog).elf.d $^ --output $(prog).elf -Wl,-Map=$(prog).map,--cref -lm
upload: all
@echo "== Uploading to chip"
sudo avrdude -p $(chip) -P $(port) -c $(programmer) -U flash:w:$(prog).hex
clean:
rm -rf *.{eep,elf,hex,lss,lst,map,o,sym}
.PHONY: all upload clean
http://www.adnbr.co.uk/articles/adc-and-pwm-basics https://gist.github.com/adnbr/9289235 https://arduinodiy.wordpress.com/2015/06/22/flashing-an-led-with-attiny13/ http://www.avrfreaks.net/forum/please-big-help-attiny13-adc
Reuse these: https://github.com/HokieGeek/power-supply-voltage-selector/blob/master/spi.h https://github.com/HokieGeek/power-supply-voltage-selector/blob/master/spi.c