#include"../autoconf.h" #include <avr/interrupt.h> #include <avr/io.h> #include <avr/wdt.h> #include "borg_hw.h" /* Steckerbelegung Flachbandkabel am Panel * (die Nummerierung ist in wirklichkeit umgekehrt) * * 1-3 GND * 4 +5V für Logic * 5-8 +12V * 9-10 GND * 11 CP3 * 12 CP2 * 13 CP1 * 14 /show * 15 CP4 * 16 /EO3 * 17-18 GND * 19-26 D0-D7 * * Und nochmal richtigrum: * 1 D7 * 2 D6 * 3 D5 * 4 D4 * 5 D3 * 6 D2 * 7 D1 * 8 D0 * 9 GND * 10 GND * 11 /EO3 * 12 CP4 * 13 /show * 14 CP1 * 15 CP2 * 16 CP3 * 17 GND * 18 GND * 19 +12V * 20 +12V * 21 +12V * 22 +12V * 23 +5V * 24 GND * 25 GND * 26 GND * * Es werden 4 40374 Latches benutzt. Nr. 1,2 und 4 treiben vom Datenbus * in Richtung Panel, Nr. 3 treibt von den Tastenausgängen auf den Datenbus. * Die EOs von 1,2 und 4 liegen fest auf GND. * * Die LEDs sind in einer 12*16 Matrix angeordnet * Die Werte für die LED spalten Werden mit CP1 und CP2 in die * Latches übernommen (insgesammt 16 Spalten) * Die Nummer der Zeile wird beim löschen von /show übernommen. * * Die Tasten sind in einer 8*8 Matrix angeordnet. * Über Latch 4 werden die Zeilen einzeln auf high gesetzt, über * Latch 3 können dann die Spalten gelesen werden. * */ //Datenport für das Panel #define COLPORT PORTC #define COLDDR DDRC #define COLPIN PINC #define CTRLPORT PORTD #define CTRLDDR DDRD // PINs on CTRLPORT #define PIN_EO3 PD7 #define PIN_CP4 PD2 #define PIN_SHOW PD3 #define PIN_CP1 PD4 #define PIN_CP2 PD5 #define PIN_CP3 PD6 //Der Puffer, in dem das aktuelle Bild gespeichert wird unsigned char pixmap[NUMPLANE][NUM_ROWS][LINEBYTES]; volatile uint8_t keys[8]; inline void busywait() { //unsigned char i; //for(i=0;i<20;i++){ // asm volatile("nop"); //} } //Eine Zeile anzeigen inline void rowshow(unsigned char row, unsigned char plane){ CTRLPORT |= (1<<PIN_SHOW);//blank COLPORT = pixmap[plane][row][0]; busywait(); CTRLPORT |= (1<<PIN_CP1); busywait(); CTRLPORT &= ~(1<<PIN_CP1); busywait(); COLPORT = pixmap[plane][row][1]; busywait(); CTRLPORT |= (1<<PIN_CP2); busywait(); CTRLPORT &= ~(1<<PIN_CP2); busywait(); COLPORT = row; busywait(); CTRLPORT &= ~(1<<PIN_SHOW); } inline void checkkeys(uint8_t row){ static uint8_t mask; if(row == 0){ mask = 1; }else{ //read keyboard cols into latch COLDDR = 0; CTRLPORT &= ~(1<<PIN_EO3); CTRLPORT |= (1<<PIN_CP3); busywait(); CTRLPORT &= ~(1<<PIN_CP3); busywait(); keys[row-1] = COLPIN; CTRLPORT |= (1<<PIN_EO3); busywait(); COLDDR = 0xFF; } COLPORT = mask; mask <<= 1; busywait(); CTRLPORT |= (1<<PIN_CP4); busywait(); CTRLPORT &= ~(1<<PIN_CP4); } //Dieser Interrupt wird je nach Ebene mit 50kHz 31,25kHz oder 12,5kHz ausgeführt SIGNAL(SIG_OUTPUT_COMPARE0) { static unsigned char plane = 0; static unsigned char row = 0; //Watchdog zurücksetzen wdt_reset(); //Die aktuelle Zeile in der aktuellen Ebene ausgeben rowshow(row, plane); if( (plane == 2) && (row<9) ) checkkeys(row); //Zeile und Ebene inkrementieren if(++row == NUM_ROWS){ row = 0; if(++plane==NUMPLANE) plane=0; switch(plane){ case 0: OCR0 = 5; break; case 1: OCR0 = 12; break; case 2: OCR0 = 20; break; } } } void timer0_off(){ cli(); TCCR0 = 0x00; sei(); } // Den Timer, der denn Interrupt auslöst, initialisieren void timer0_on(){ /* TCCR0: FOC0 WGM00 COM01 COM00 WGM01 CS02 CS01 CS00 CS02 CS01 CS00 0 0 0 stop 0 0 1 clk 0 1 0 clk/8 0 1 1 clk/64 1 0 0 clk/256 1 0 1 clk/1024 */ TCCR0 = 0x0C; // CTC Mode, clk/64 TCNT0 = 0; // reset timer OCR0 = 20; // Compare with this value TIMSK = 0x02; // Compare match Interrupt on } void borg_hw_init(){ //Pins am Zeilenport auf Ausgang CTRLPORT |= (1<<PIN_EO3)|(1<<PIN_SHOW); CTRLDDR |= (1<<PIN_EO3) | (1<<PIN_CP4) | (1<<PIN_SHOW) | (1<<PIN_CP1) | (1<<PIN_CP2) | (1<<PIN_CP3); //Alle Spalten erstmal aus //Spalten Ports auf Ausgang COLDDR = 0xFF; COLPORT = 0x00; timer0_on(); //Watchdog Timer aktivieren wdt_reset(); wdt_enable(0x00); // 17ms Watchdog }