// GeneZap joypad controler firmware for ATTiny 25
// CC Furrtek 2012
// Version 1

#include "avr/io.h"
#include "avr/interrupt.h"
#include "util/delay.h"
#include <inttypes.h>

#define LED		PB2
#define SELECT	PB3
#define SIG		PB4

uint8_t volatile edge = 0;

ISR(PCINT0_vect) {
	edge++;			// Count edges on pin change interrupt
	TCNT0 = 0;		// Reset Timer0
}

ISR(TIMER0_OVF_vect) {
	uint8_t pulse,zap;

	if (edge >= 16) {			
		// If edges counted >= 16: long zap
	 	PORTB = _BV(LED);
		for (pulse=0;pulse<20;pulse++) {	// 20 bursts of 10 spikes
			for (zap=0;zap<10;zap++) {
				PORTB = _BV(SIG) | _BV(LED);
				_delay_us(300);
				PORTB = _BV(LED);
				_delay_ms(4);
			}
			_delay_ms(50);
		}
		PORTB = 0;
	} else if ((edge < 16) && (edge > 10)) {
		// If edges counter > 10 and < 16: short zap
	 	PORTB = _BV(LED);
		for (pulse=0;pulse<2;pulse++) {		// 2 bursts of 10 spikes
			for (zap=0;zap<10;zap++) {
				PORTB = _BV(SIG) | _BV(LED);
				_delay_us(300);
				PORTB = _BV(LED);
				_delay_ms(4);
			}
			_delay_ms(50);
		}
		PORTB = 0;
	}
	edge = 0;	// Reset edge count
}

int main(void) {
	uint8_t blink;

	WDTCR = (1<<WDCE) | (1<<WDE);	// Put watchdog asleep
	WDTCR = 0x00;

	PORTB = 0b00000000;
	DDRB = _BV(SIG) | _BV(LED);		// SIG and LED as outputs

	TCCR0A = 0b00000000;			// Normal operation
	TCCR0B = 0b00000011;			// Prescaler = /64
	TIMSK = 0b00000010;				// Overflow interrupt activated

	GIMSK = 0b00100000;				// Pin change interrupt activated
	PCMSK = _BV(SELECT);			// Pin change interrupt on SELECT pin only

	_delay_ms(100);					// Wait for settling

	for (blink=0;blink<10;blink++) {
		PORTB = _BV(LED);			// Blink LED to show we're running fine
		_delay_ms(10);							
		PORTB = 0;
		_delay_ms(100);
	}

	sei();							// Activate interrupts

	for (;;) {}
    return 0;
}
