/* 
Beispiel Code zum ansteuern des LED-Lauflichts. 
www.subms.de - johanneskreuzer@gmx.de
26.09.2009
Ich gebe den Code für alle Verwendungen frei 
und trete von jeglicher Verantwortung davon zurück!
Viel Spaß beim experimentieren.

Dies ist eine ungeteste Version zur Verdeutlichung der Funktion, 
die aus einem größeren Projekt extrahiert wurde.

Zur Nutzung muss u.a. noch eine I2C Lib von z.B. Peter Fleury eingebunden werden.
http://homepage.hispeed.ch/peterfleury/
*/


//Adresse PCF8574: 
#define PCF8574 0x40	//I2C Adresse eines PCF8574 allg.
#define PCF8574_1 0x40	//PCF8574 + A0,A1,A2 -> GND
#define PCF8574_2 0x42	//PCF8574 + A1,A2 -> GND; A0 -> 5V
#define PCF8574_3 0x44	//PCF8574 + A0,A2 -> GND; A1 -> 5V

volatile int16_t ledwait=0;

//Aufbau: 
//Die ersten beiden Bytes geben die Länge des Arrays in Byte an. inkl, dieser beiden.
//4 Byte: 1-3 für LEDs 1-24; 4. Byte für die Dauer der Anzeige in ms.
const uint8_t ledArray[] = 
{
0x00,0x1C
,0x10,0x18,0x08,0x64
,0x08,0x24,0x10,0x64
,0x04,0x42,0x20,0x64
,0x02,0x81,0x40,0x64
,0x81,0x00,0x81,0x64
,0x40,0x00,0x02,0x64
,0x20,0x00,0x04,0x64
};

ISR(TIMER0_COMP_vect) {
	//lifetime++; // für manche Anwendungen sehr brauchbar
	ledwait--;
}

void inline timer_init (void) {
lifetime=0;
//Timer/Counter0 stellen um jede ms einen Interrupt auszulösen
// TCCR= FOC0:1 WGM01:1 WGM00:0 COM01:0 COM00:0 CS02:0 CS01:1 CS00:1 64er prescaler
TCCR0 = 0x8B;
TCNT0 = 0x00;					//Timer/Counter Register
OCR0 = 250; 					//Output Compare Register
TIMSK = (1<<OCIE0); 	//Timer/Counter0 Output Compare Match Interrupt Enable
}

void inline setzeLeds(uint8_t led1, uint8_t led2, uint8_t led3)
{
	i2c_start_wait(PCF8574_1+I2C_WRITE); 
	i2c_write(~led1); //Gewünschte Zeile wir auf GND gezogen
	i2c_stop();
	i2c_start_wait(PCF8574_2+I2C_WRITE); 
	i2c_write(~led2); //Gewünschte Zeile wir auf GND gezogen
	i2c_stop();
	i2c_start_wait(PCF8574_3+I2C_WRITE); 
	i2c_write(~led3); //Gewünschte Zeile wir auf GND gezogen
	i2c_stop();
}

int main (void) {
sei();
timer_init();
uint32_t addr=2;
uint32_t led = 1;
//Die Array Länge aus den ersten beiden Bytes zusammensetzen:
uint16_t length=(((uint16_t)ledArray[0])<<8)|((uint16_t)ledArray[1]);
while(1){
	if (ledwait < 0) {
		setzeLeds(ledArray[addr], ledArray[addr+1],ledArray[addr+2]);
		ledwait = ledArray[(addr+3)];	
		if(addr < (length-4) ) { addr+=4; }
		else { addr = 2; };
	}
}
}


