mini-led-cube/firmware/main.c

107 lines
2.3 KiB
C
Raw Normal View History

2011-12-09 23:15:06 +01:00
/* CTHN.de MiniLEDCube
*
2011-12-09 23:15:06 +01:00
* Kai Lauterbach (klaute at web dot de)
*
* Based on http://mosfetkiller.de/?s=miniledcube
*
* License: General Public License (GPL v3)
*
*/
#include "main.h"
// Main
2011-12-10 00:49:39 +01:00
int __attribute__((OS_main))
main()
{
// Initialisierung
init();
init_usb();
//frame = 0x07ffffff;
mode = 2;
2011-12-17 22:03:57 +01:00
// Hauptschleife
for (;;)
{
usbPoll(); // keep connected
}
}
// Initialisierung
void init()
{
// Ports vorbereiten
DDRB = 0b11111111; // PB0-PB7: LED 1-8 (Kathoden)
PORTB = 0b11111111; // HIGH
DDRD = 0b01111000; // PD6: LED 9 (Kathode); PD5-PD3: A-C (Anoden)
PORTD = 0b01000000;
// Timer-Interrupt "TIMER1" vorbereiten
2011-11-30 00:16:21 +01:00
set_bit(TIMSK, OCIE1A); // Interrupt für ISR COMPA
2011-12-09 22:57:26 +01:00
//set_bit(TCCR1B, WGM12); // Überlauf wird unten gesetzt
// Animations-Geschwindigkeit
2011-11-05 16:52:02 +01:00
// (vergleichswert bei dem der Interrupt ausgelöst wird)
2011-11-30 00:16:21 +01:00
// 625d = 0x271 = 0b00000010, 0b01110001
OCR1AH = 0b00000010;
OCR1AL = 0b01110001;
2011-11-05 16:52:02 +01:00
// anpassen auf reihenweise ausgabe
2011-11-30 00:16:21 +01:00
// Vorteiler durch 64 (0x011) ----> CS12=0, CS11=1, CS10=1
//clear_bit(TCCR1B, CS12); // Prescaler 64
//set_bit(TCCR1B, CS11);
//set_bit(TCCR1B, CS10);
TCCR1B |= (1 << CS11) | (1 << CS10) | (1 << WGM12);
2011-11-30 00:16:21 +01:00
sei(); // Set enable interrupt bit (Muss gesetzt werden damit es überhaupt aufgerufen wird)
}
// Interruptvektor von TIMER1
2011-11-05 16:52:02 +01:00
ISR (TIMER1_COMPA_vect)
{
2011-12-18 19:35:47 +01:00
delay--;
if ( !delay )
{
if (frmnum == 32)
{
if (mode == 1)
mode = 0;
frmnum = 0;
} else {
if (mode)
{
loadEEPROMFrame(frmnum);
frmnum++;
}
}
delay = delay_max;
2011-12-18 19:35:47 +01:00
}
// PORTD = __, 9, C, B, A,D+,D-,__
PORTD &= 0b10000111; // 7tes Bit löschen (Leitung 9) und alle Ebenen deaktivieren
2011-12-17 22:03:57 +01:00
PORTD |= (1 << 6) | ((1 << level) << 3); // level setzen (Ebene A=0, B=1, C=2)
2011-12-17 22:03:57 +01:00
uint8_t tmp = level * 9;
2011-11-30 00:16:21 +01:00
// PORTB = 1..8
// 0 = leuchtet, 1 = leuchtet nicht (invertiert!)
2011-12-17 22:03:57 +01:00
PORTB = ~((frame >> tmp) & 0xff);
2011-12-17 22:03:57 +01:00
if ( (((frame >> tmp) >> 8) & 0x01) )
2011-12-09 22:57:26 +01:00
PORTD &= ~(1 << 6); // 9. led setzen falls notwendig
2011-12-17 22:03:57 +01:00
level++;
if (level > 2) level = 0;
}
void loadEEPROMFrame(uint8_t f)
2011-12-18 19:35:47 +01:00
{
frame = eeprom_read_dword( &eep_anim[f] );
}