saved up to 240 bytes (depending on borg hw), translated some German comments into English and cleaned up formatting (sorry about the noise)
This commit is contained in:
parent
3e8768866c
commit
d4ae78fee3
|
@ -128,31 +128,13 @@ static uint8_t amphibian_getChunk(unsigned char const nBitPlane,
|
||||||
{0x06, 0x30, 0xC6},
|
{0x06, 0x30, 0xC6},
|
||||||
{0x07, 0xF0, 0xFE}}};
|
{0x07, 0xF0, 0xFE}}};
|
||||||
|
|
||||||
|
static uint8_t const nOffsetTable[] PROGMEM =
|
||||||
|
{UINT8_MAX, 0, 4, 8, 12, 8, 4, 0};
|
||||||
|
uint8_t const nOffset = pgm_read_byte(&nOffsetTable[(nFrame >> 1) % 8]);
|
||||||
|
|
||||||
if ((nChunkX <= 2) && (nChunkY >= 2) && (nChunkY <= 5)
|
if ((nChunkX <= 2) && (nChunkY >= 2) && (nChunkY <= 5)
|
||||||
&& (((nFrame >> 1) % 8) != 0))
|
&& (nOffset != UINT8_MAX))
|
||||||
{
|
{
|
||||||
uint8_t nOffset;
|
|
||||||
switch ((nFrame >> 1) % 8)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
case 7:
|
|
||||||
nOffset = 0;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
case 6:
|
|
||||||
nOffset = 4;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
case 5:
|
|
||||||
nOffset = 8;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
default:
|
|
||||||
nOffset = 12;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return pgm_read_byte(&aEye[nBitPlane][nChunkY-2+nOffset][nChunkX]);
|
return pgm_read_byte(&aEye[nBitPlane][nChunkY-2+nOffset][nChunkX]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -106,7 +106,7 @@ typedef uint8_t field_t[FIELD_YSIZE][FIELD_XSIZE];
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
void setcell(field_t pf, coord_t x, coord_t y, cell_t value) {
|
static void setcell(field_t pf, coord_t x, coord_t y, cell_t value) {
|
||||||
if (value != dead) {
|
if (value != dead) {
|
||||||
pf[y][x / 8] |= shl_table[x & 7];
|
pf[y][x / 8] |= shl_table[x & 7];
|
||||||
} else {
|
} else {
|
||||||
|
@ -144,25 +144,23 @@ void nextiteration(field_t dest, field_t src) {
|
||||||
uint8_t tc;
|
uint8_t tc;
|
||||||
for (y = YSIZE; y--;) {
|
for (y = YSIZE; y--;) {
|
||||||
for (x = XSIZE; x--;) {
|
for (x = XSIZE; x--;) {
|
||||||
|
cell_t cell;
|
||||||
tc = countsurroundingalive(src, x, y);
|
tc = countsurroundingalive(src, x, y);
|
||||||
switch (tc) {
|
switch (tc) {
|
||||||
// case 0:
|
|
||||||
// case 1:
|
|
||||||
// /* dead */
|
|
||||||
// setcell(dest, x,y, dead);
|
|
||||||
case 2:
|
case 2:
|
||||||
/* keep */
|
/* keep */
|
||||||
setcell(dest, x, y, getcell(src, x, y));
|
continue;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
/* alive */
|
/* alive */
|
||||||
setcell(dest, x, y, alive);
|
cell = alive;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* dead */
|
/* dead */
|
||||||
setcell(dest, x, y, dead);
|
cell = dead;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
setcell(dest, x, y, cell);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
#ifndef BORG_HW_H
|
#ifndef BORG_HW_H
|
||||||
#define BORG_HW_H
|
#define BORG_HW_H
|
||||||
|
|
||||||
//Linebytes gibt die Zahl der Bytes pro Zeile in der
|
// LINEBYTES holds the amount of bytes per line within the framebuffer (pixmap)
|
||||||
//Pixmap an, also Spaltenzahl/8 aufgerundet
|
|
||||||
#define LINEBYTES (((NUM_COLS-1)/8)+1)
|
#define LINEBYTES (((NUM_COLS-1)/8)+1)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
#include "../config.h"
|
#include "../config.h"
|
||||||
#include "../makros.h"
|
#include "../makros.h"
|
||||||
|
|
||||||
|
@ -8,25 +7,27 @@
|
||||||
#include "borg_hw.h"
|
#include "borg_hw.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// Diese #defines werden nun durch menuconfig gesetzt
|
// those macros get defined via menuconfig, now
|
||||||
|
|
||||||
// 16 Spalten insgesamt direkt gesteuert, dafür 2 Ports
|
// 16 columns total directly controlled, therefore 2 ports
|
||||||
#define COLPORT1 PORTA
|
#define COLPORT1 PORTA
|
||||||
#define COLDDR1 DDRA
|
#define COLDDR1 DDRA
|
||||||
|
|
||||||
#define COLPORT2 PORTC
|
#define COLPORT2 PORTC
|
||||||
#define COLDDR2 DDRC
|
#define COLDDR2 DDRC
|
||||||
|
|
||||||
// Der andere Port übernimmt die Steuerung der Schieberegister
|
// the other port controls the shift registers
|
||||||
#define ROWPORT PORTD
|
#define ROWPORT PORTD
|
||||||
#define ROWDDR DDRD
|
#define ROWDDR DDRD
|
||||||
// Clock und reset gehen gemeinsam an beide Schieberegister
|
|
||||||
// der reset pin ist negiert
|
// both clock and reset are connected to each shift register
|
||||||
#define PIN_MCLR PD4
|
// reset pin is negated
|
||||||
#define PIN_CLK PD5
|
#define PIN_MCLR PD4
|
||||||
//das dier sind die individuellen Dateneingänge für die Schieberegister
|
#define PIN_CLK PD5
|
||||||
#define PIN_DATA1 PD6
|
|
||||||
#define PIN_DATA2 PD7
|
// these are the individual data input pins for the shift registers
|
||||||
|
#define PIN_DATA1 PD6
|
||||||
|
#define PIN_DATA2 PD7
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define COLDDR1 DDR(COLPORT1)
|
#define COLDDR1 DDR(COLPORT1)
|
||||||
|
@ -39,90 +40,80 @@
|
||||||
#define SIG_OUTPUT_COMPARE0 SIG_OUTPUT_COMPARE0A
|
#define SIG_OUTPUT_COMPARE0 SIG_OUTPUT_COMPARE0A
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// buffer which holds the currently shown frame
|
||||||
//Der Puffer, in dem das aktuelle Bild gespeichert wird
|
|
||||||
unsigned char pixmap[NUMPLANE][NUM_ROWS][LINEBYTES];
|
unsigned char pixmap[NUMPLANE][NUM_ROWS][LINEBYTES];
|
||||||
|
|
||||||
|
// display a row
|
||||||
//Eine Zeile anzeigen
|
static void rowshow(unsigned char row, unsigned char plane) {
|
||||||
inline void rowshow(unsigned char row, unsigned char plane){
|
//reset states of preceding row
|
||||||
//Die Zustände von der vorherigen Zeile löschen
|
|
||||||
COLPORT1 = 0;
|
COLPORT1 = 0;
|
||||||
COLPORT2 = 0;
|
COLPORT2 = 0;
|
||||||
|
|
||||||
//kurze Warteschleife, damit die Treiber auch wirklich ausschalten
|
// short delay loop, to ensure proper deactivation of the drivers
|
||||||
unsigned char i;
|
unsigned char i;
|
||||||
for(i=0;i<20;i++){
|
for (i = 0; i < 20; i++) {
|
||||||
asm volatile("nop");
|
asm volatile("nop");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (row == 0) {
|
||||||
if (row == 0){
|
// row 0: initialize first shift register
|
||||||
//Zeile 0: Das erste Schieberegister initialisieren
|
ROWPORT &= ~(1 << PIN_MCLR);
|
||||||
ROWPORT&= ~(1<<PIN_MCLR);
|
ROWPORT |= (1 << PIN_MCLR);
|
||||||
ROWPORT|= (1<<PIN_MCLR);
|
ROWPORT |= (1 << PIN_DATA1);
|
||||||
ROWPORT|= (1<<PIN_DATA1);
|
ROWPORT |= (1 << PIN_CLK);
|
||||||
ROWPORT|= (1<<PIN_CLK);
|
ROWPORT &= ~(1 << PIN_CLK);
|
||||||
ROWPORT&= ~(1<<PIN_CLK);
|
ROWPORT &= ~(1 << PIN_DATA1);
|
||||||
ROWPORT&= ~(1<<PIN_DATA1);
|
|
||||||
|
// depending on the currently drawn plane, display the row for a
|
||||||
//Je nachdem, welche der Ebenen wir Zeichnen, die Zeile verschieden lange Anzeigen
|
// specific amount of time
|
||||||
switch (plane){
|
static unsigned char const ocr0_table[] = {5, 8, 20};
|
||||||
case 0:
|
OCR0 = ocr0_table[plane];
|
||||||
OCR0 = 5;
|
} else if (row == 8) {
|
||||||
break;
|
// row 8: initialize second shift register
|
||||||
case 1:
|
ROWPORT &= ~(1 << PIN_MCLR);
|
||||||
OCR0 = 8;
|
ROWPORT |= (1 << PIN_MCLR);
|
||||||
break;
|
ROWPORT |= (1 << PIN_DATA2);
|
||||||
case 2:
|
ROWPORT |= (1 << PIN_CLK);
|
||||||
OCR0 = 20;
|
ROWPORT &= ~(1 << PIN_CLK);
|
||||||
}
|
ROWPORT &= ~(1 << PIN_DATA2);
|
||||||
}else if(row == 8){
|
} else {
|
||||||
//Zeile 8: Das Zweite Schieberegister initialisieren
|
// remaining rows: just shift forward
|
||||||
ROWPORT&= ~(1<<PIN_MCLR);
|
ROWPORT |= (1 << PIN_CLK);
|
||||||
ROWPORT|= (1<<PIN_MCLR);
|
ROWPORT &= ~(1 << PIN_CLK);
|
||||||
ROWPORT|= (1<<PIN_DATA2);
|
|
||||||
ROWPORT|= (1<<PIN_CLK);
|
|
||||||
ROWPORT&= ~(1<<PIN_CLK);
|
|
||||||
ROWPORT&= ~(1<<PIN_DATA2);
|
|
||||||
}else{
|
|
||||||
//In jeder anderen Zeile einfach nur einen weiter schieben
|
|
||||||
ROWPORT|= (1<<PIN_CLK);
|
|
||||||
ROWPORT&= ~(1<<PIN_CLK);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//ncoh eine Warteschleife, damit die Zeilentreiber bereit sind
|
// another delay loop, to ensure that the drivers are ready
|
||||||
for(i=0;i<20;i++){
|
for (i = 0; i < 20; i++) {
|
||||||
asm volatile("nop");
|
asm volatile("nop");
|
||||||
}
|
}
|
||||||
|
|
||||||
//die Daten für die aktuelle Zeile auf die Spaltentreiber ausgeben
|
// output data of the current row to the column drivers
|
||||||
COLPORT1 = pixmap[plane][row][0];
|
COLPORT1 = pixmap[plane][row][0];
|
||||||
COLPORT2 = pixmap[plane][row][1];
|
COLPORT2 = pixmap[plane][row][1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// depending on the plane this interrupt gets triggered at 50 kHz, 31.25 kHz or
|
||||||
//Dieser Interrupt wird je nach Ebene mit 50kHz 31,25kHz oder 12,5kHz ausgeführt
|
// 12.5 kHz
|
||||||
SIGNAL(SIG_OUTPUT_COMPARE0)
|
SIGNAL(SIG_OUTPUT_COMPARE0) {
|
||||||
{
|
|
||||||
static unsigned char plane = 0;
|
static unsigned char plane = 0;
|
||||||
static unsigned char row = 0;
|
static unsigned char row = 0;
|
||||||
|
|
||||||
//Watchdog zurücksetzen
|
// reset watchdog
|
||||||
wdt_reset();
|
wdt_reset();
|
||||||
|
|
||||||
//Die aktuelle Zeile in der aktuellen Ebene ausgeben
|
// output current row according to current plane
|
||||||
rowshow(row, plane);
|
rowshow(row, plane);
|
||||||
|
|
||||||
//Zeile und Ebene inkrementieren
|
// increment both row and plane
|
||||||
if(++row == NUM_ROWS){
|
if (++row == NUM_ROWS) {
|
||||||
row = 0;
|
row = 0;
|
||||||
if(++plane==NUMPLANE) plane=0;
|
if (++plane == NUMPLANE) {
|
||||||
|
plane = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void timer0_off() {
|
||||||
void timer0_off(){
|
|
||||||
cli();
|
cli();
|
||||||
|
|
||||||
COLPORT1 = 0;
|
COLPORT1 = 0;
|
||||||
|
@ -130,60 +121,58 @@ void timer0_off(){
|
||||||
ROWPORT = 0;
|
ROWPORT = 0;
|
||||||
|
|
||||||
#ifdef __AVR_ATmega644P__
|
#ifdef __AVR_ATmega644P__
|
||||||
TCCR0A = 0x00;
|
TCCR0A = 0x00;
|
||||||
TCCR0B = 0x00;
|
TCCR0B = 0x00;
|
||||||
#else
|
#else
|
||||||
TCCR0 = 0x00;
|
TCCR0 = 0x00;
|
||||||
#endif
|
#endif
|
||||||
sei();
|
sei();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// initialize timer which triggers the interrupt
|
||||||
// Den Timer, der denn Interrupt auslöst, initialisieren
|
static void timer0_on() {
|
||||||
void timer0_on(){
|
/* TCCR0: FOC0 WGM00 COM01 COM00 WGM01 CS02 CS01 CS00
|
||||||
/* TCCR0: FOC0 WGM00 COM01 COM00 WGM01 CS02 CS01 CS00
|
CS02 CS01 CS00
|
||||||
CS02 CS01 CS00
|
0 0 0 stop
|
||||||
0 0 0 stop
|
0 0 1 clk
|
||||||
0 0 1 clk
|
0 1 0 clk/8
|
||||||
0 1 0 clk/8
|
0 1 1 clk/64
|
||||||
0 1 1 clk/64
|
1 0 0 clk/256
|
||||||
1 0 0 clk/256
|
1 0 1 clk/1024
|
||||||
1 0 1 clk/1024
|
*/
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef __AVR_ATmega644P__
|
#ifdef __AVR_ATmega644P__
|
||||||
TCCR0A = 0x02; // CTC Mode
|
TCCR0A = 0x02; // CTC Mode
|
||||||
TCCR0B = 0x03; // clk/64
|
TCCR0B = 0x03; // clk/64
|
||||||
TCNT0 = 0; // reset timer
|
TCNT0 = 0; // reset timer
|
||||||
OCR0 = 20; // Compare with this value
|
OCR0 = 20; // compare with this value
|
||||||
TIMSK0 = 0x02; // Compare match Interrupt on
|
TIMSK0 = 0x02; // compare match Interrupt on
|
||||||
#else
|
#else
|
||||||
TCCR0 = 0x0B; // CTC Mode, clk/64
|
TCCR0 = 0x0B; // CTC Mode, clk/64
|
||||||
TCNT0 = 0; // reset timer
|
TCNT0 = 0; // reset timer
|
||||||
OCR0 = 20; // Compare with this value
|
OCR0 = 20; // compare with this value
|
||||||
TIMSK = 0x02; // Compare match Interrupt on
|
TIMSK = 0x02; // compare match Interrupt on
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void borg_hw_init(){
|
void borg_hw_init() {
|
||||||
//Spalten Ports auf Ausgang
|
// switch column ports to output mode
|
||||||
COLDDR1 = 0xFF;
|
COLDDR1 = 0xFF;
|
||||||
COLDDR2 = 0xFF;
|
COLDDR2 = 0xFF;
|
||||||
|
|
||||||
//Pins am Zeilenport auf Ausgang
|
// switch pins of the row port to output mode
|
||||||
ROWDDR = (1<<PIN_MCLR) | (1<<PIN_CLK) | (1<< PIN_DATA1) | (1<<PIN_DATA2);
|
ROWDDR = (1<<PIN_MCLR) | (1<<PIN_CLK) | (1<<PIN_DATA1) | (1<<PIN_DATA2);
|
||||||
|
|
||||||
//Alle Spalten erstmal aus
|
// switch off all columns for now
|
||||||
COLPORT1 = 0;
|
COLPORT1 = 0;
|
||||||
COLPORT2 = 0;
|
COLPORT2 = 0;
|
||||||
|
|
||||||
//Schieberegister für Zeilen zurücksetzen
|
// reset shift registers for the rows
|
||||||
ROWPORT = 0;
|
ROWPORT = 0;
|
||||||
|
|
||||||
timer0_on();
|
timer0_on();
|
||||||
|
|
||||||
//Watchdog Timer aktivieren
|
// activate watchdog timer
|
||||||
wdt_reset();
|
wdt_reset();
|
||||||
wdt_enable(0x00); // 17ms Watchdog
|
wdt_enable(0x00); // 17ms watchdog
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
#include "../config.h"
|
#include "../config.h"
|
||||||
#include "../makros.h"
|
#include "../makros.h"
|
||||||
|
|
||||||
|
@ -8,24 +7,26 @@
|
||||||
#include "borg_hw.h"
|
#include "borg_hw.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// Diese #defines werden nun durch menuconfig gesetzt
|
// those macros get defined via menuconfig, now
|
||||||
|
|
||||||
// 16 Spalten insgesamt direkt gesteuert, dafür 2 Ports
|
// 16 columns total directly controlled, therefore 2 ports
|
||||||
#define COLPORT1 PORTC
|
#define COLPORT1 PORTC
|
||||||
#define COLDDR1 DDRC
|
#define COLDDR1 DDRC
|
||||||
|
|
||||||
#define COLPORT2 PORTA
|
#define COLPORT2 PORTA
|
||||||
#define COLDDR2 DDRA
|
#define COLDDR2 DDRA
|
||||||
|
|
||||||
// Der andere Port übernimmt die Steuerung der Schieberegister
|
// the other port controls the shift registers
|
||||||
#define ROWPORT PORTD
|
#define ROWPORT PORTD
|
||||||
#define ROWDDR DDRD
|
#define ROWDDR DDRD
|
||||||
// Clock und reset gehen gemeinsam an beide Schieberegister
|
|
||||||
// der reset pin ist negiert
|
// both clock and reset are connected to each shift register
|
||||||
#define PIN_MCLR PD4
|
// reset pin is negated
|
||||||
#define PIN_CLK PD6
|
#define PIN_MCLR PD4
|
||||||
//das dier sind die individuellen Dateneingänge für die Schieberegister
|
#define PIN_CLK PD6
|
||||||
#define PIN_DATA PD7
|
|
||||||
|
// these are the individual data input pins for the shift registers
|
||||||
|
#define PIN_DATA PD7
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define COLDDR1 DDR(COLPORT1)
|
#define COLDDR1 DDR(COLPORT1)
|
||||||
|
@ -38,33 +39,30 @@
|
||||||
#define SIG_OUTPUT_COMPARE0 SIG_OUTPUT_COMPARE0A
|
#define SIG_OUTPUT_COMPARE0 SIG_OUTPUT_COMPARE0A
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// buffer which holds the currently shown frame
|
||||||
//Der Puffer, in dem das aktuelle Bild gespeichert wird
|
|
||||||
unsigned char pixmap[NUMPLANE][NUM_ROWS][LINEBYTES];
|
unsigned char pixmap[NUMPLANE][NUM_ROWS][LINEBYTES];
|
||||||
|
|
||||||
|
// switch to next row
|
||||||
//zur nächsten Zeile weiterschalten
|
static void nextrow(uint8_t row) {
|
||||||
inline void nextrow(uint8_t row){
|
//reset states of preceding row
|
||||||
//Die Zustände von der vorherigen Zeile löschen
|
|
||||||
COLPORT1 = 0;
|
COLPORT1 = 0;
|
||||||
COLPORT2 = 0;
|
COLPORT2 = 0;
|
||||||
|
|
||||||
//kurze Warteschleife, damit die Treiber auch wirklich ausschalten
|
// short delay loop, to ensure proper deactivation of the drivers
|
||||||
|
|
||||||
unsigned char i;
|
unsigned char i;
|
||||||
for(i=0;i<10;i++){
|
for (i = 0; i < 10; i++) {
|
||||||
asm volatile("nop");
|
asm volatile("nop");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (row == 0){
|
if (row == 0) {
|
||||||
//Zeile 0: Das erste Schieberegister initialisieren
|
// row 0: initialize first shift register
|
||||||
#ifndef INVERT_ROWS
|
#ifndef INVERT_ROWS
|
||||||
ROWPORT&= ~(1<<PIN_MCLR);
|
ROWPORT &= ~(1 << PIN_MCLR);
|
||||||
ROWPORT|= (1<<PIN_MCLR);
|
ROWPORT |= (1 << PIN_MCLR);
|
||||||
ROWPORT|= (1<<PIN_DATA);
|
ROWPORT |= (1 << PIN_DATA);
|
||||||
ROWPORT|= (1<<PIN_CLK);
|
ROWPORT |= (1 << PIN_CLK);
|
||||||
ROWPORT&= ~(1<<PIN_CLK);
|
ROWPORT &= ~(1 << PIN_CLK);
|
||||||
ROWPORT&= ~(1<<PIN_DATA);
|
ROWPORT &= ~(1 << PIN_DATA);
|
||||||
#else
|
#else
|
||||||
ROWPORT&= ~(1<<PIN_DATA);
|
ROWPORT&= ~(1<<PIN_DATA);
|
||||||
ROWPORT|= (1<<PIN_CLK);
|
ROWPORT|= (1<<PIN_CLK);
|
||||||
|
@ -72,43 +70,33 @@ inline void nextrow(uint8_t row){
|
||||||
ROWPORT|= (1<<PIN_DATA);
|
ROWPORT|= (1<<PIN_DATA);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}else{
|
} else {
|
||||||
//In jeder anderen Zeile einfach nur einen weiter schieben
|
// remaining rows: just shift forward
|
||||||
ROWPORT|= (1<<PIN_CLK);
|
ROWPORT |= (1 << PIN_CLK);
|
||||||
ROWPORT&= ~(1<<PIN_CLK);
|
ROWPORT &= ~(1 << PIN_CLK);
|
||||||
}
|
}
|
||||||
|
|
||||||
//noch eine Warteschleife, damit die Zeilentreiber bereit sind
|
// another delay loop, to ensure that the drivers are ready
|
||||||
for(i=0;i<20;i++){
|
for (i = 0; i < 20; i++) {
|
||||||
asm volatile("nop");
|
asm volatile("nop");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// show a row
|
||||||
|
static void rowshow(unsigned char row, unsigned char plane) {
|
||||||
|
// depending on the currently drawn plane, display the row for a specific
|
||||||
|
// amount of time
|
||||||
|
static unsigned char const ocr_table[] = {3, 4, 22};
|
||||||
|
OCR0 = ocr_table[plane];
|
||||||
|
|
||||||
|
// output data of the current row to the column drivers
|
||||||
//Eine Zeile anzeigen
|
|
||||||
inline void rowshow(unsigned char row, unsigned char plane){
|
|
||||||
//Je nachdem, welche der Ebenen wir Zeichnen, die Zeile verschieden lange Anzeigen
|
|
||||||
switch (plane){
|
|
||||||
case 0:
|
|
||||||
OCR0 = 3;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
OCR0 = 4;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
OCR0 = 22;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t tmp, tmp1;
|
uint8_t tmp, tmp1;
|
||||||
//die Daten für die aktuelle Zeile auf die Spaltentreiber ausgeben
|
|
||||||
|
|
||||||
#ifndef INTERLACED_ROWS
|
#ifndef INTERLACED_ROWS
|
||||||
tmp = pixmap[plane][row][0];
|
tmp = pixmap[plane][row][0];
|
||||||
tmp1 = pixmap[plane][row][1];
|
tmp1 = pixmap[plane][row][1];
|
||||||
#else
|
#else
|
||||||
row = (row>>1) + ((row & 0x01)?8:0 );
|
row = (row>>1) + ((row & 0x01)?8:0 );
|
||||||
tmp = pixmap[plane][row][0];
|
tmp = pixmap[plane][row][0];
|
||||||
tmp1 = pixmap[plane][row][1];
|
tmp1 = pixmap[plane][row][1];
|
||||||
#endif
|
#endif
|
||||||
#ifdef REVERSE_COLS
|
#ifdef REVERSE_COLS
|
||||||
|
@ -124,44 +112,43 @@ inline void rowshow(unsigned char row, unsigned char plane){
|
||||||
#else
|
#else
|
||||||
#ifdef INTERLACED_COLS
|
#ifdef INTERLACED_COLS
|
||||||
static uint8_t interlace_table[16] = {
|
static uint8_t interlace_table[16] = {
|
||||||
0x00, 0x01, 0x04, 0x05, 0x10, 0x11, 0x14, 0x15, 0x40, 0x41, 0x44, 0x45, 0x50, 0x51, 0x54, 0x55
|
0x00, 0x01, 0x04, 0x05, 0x10, 0x11, 0x14, 0x15, 0x40, 0x41, 0x44, 0x45,
|
||||||
|
0x50, 0x51, 0x54, 0x55
|
||||||
};
|
};
|
||||||
COLPORT1 = interlace_table[tmp&0x0f] | (interlace_table[tmp1&0x0f]<<1);
|
COLPORT1 = interlace_table[tmp&0x0f] | (interlace_table[tmp1&0x0f]<<1);
|
||||||
tmp>>=4; tmp1>>=4;
|
tmp>>=4; tmp1>>=4;
|
||||||
COLPORT2 = interlace_table[tmp] | (interlace_table[tmp1]<<1);
|
COLPORT2 = interlace_table[tmp] | (interlace_table[tmp1]<<1);
|
||||||
#else
|
#else
|
||||||
COLPORT1 = tmp;
|
COLPORT1 = tmp;
|
||||||
COLPORT2 = tmp1;
|
COLPORT2 = tmp1;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// depending on the plane this interrupt triggers at 50 kHz, 31.25 kHz or
|
||||||
//Dieser Interrupt wird je nach Ebene mit 50kHz 31,25kHz oder 12,5kHz ausgeführt
|
// 12.5 kHz
|
||||||
SIGNAL(SIG_OUTPUT_COMPARE0)
|
SIGNAL(SIG_OUTPUT_COMPARE0) {
|
||||||
{
|
|
||||||
static unsigned char plane = 0;
|
static unsigned char plane = 0;
|
||||||
static unsigned char row = 0;
|
static unsigned char row = 0;
|
||||||
|
|
||||||
//Watchdog zurücksetzen
|
// reset watchdog
|
||||||
wdt_reset();
|
wdt_reset();
|
||||||
|
|
||||||
//Zeile und Ebene inkrementieren
|
// increment both row and plane
|
||||||
if(++plane==NUMPLANE){
|
if (++plane == NUMPLANE) {
|
||||||
plane=0;
|
plane = 0;
|
||||||
if(++row == NUM_ROWS){
|
if (++row == NUM_ROWS) {
|
||||||
row = 0;
|
row = 0;
|
||||||
}
|
}
|
||||||
nextrow(row);
|
nextrow(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Die aktuelle Zeile in der aktuellen Ebene ausgeben
|
// output current row according to current plane
|
||||||
rowshow(row, plane);
|
rowshow(row, plane);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void timer0_off() {
|
||||||
void timer0_off(){
|
|
||||||
cli();
|
cli();
|
||||||
|
|
||||||
COLPORT1 = 0;
|
COLPORT1 = 0;
|
||||||
|
@ -169,60 +156,59 @@ void timer0_off(){
|
||||||
ROWPORT = 0;
|
ROWPORT = 0;
|
||||||
|
|
||||||
#ifdef __AVR_ATmega644P__
|
#ifdef __AVR_ATmega644P__
|
||||||
TCCR0A = 0x00;
|
TCCR0A = 0x00;
|
||||||
TCCR0B = 0x00;
|
TCCR0B = 0x00;
|
||||||
#else
|
#else
|
||||||
|
|
||||||
TCCR0 = 0x00;
|
TCCR0 = 0x00;
|
||||||
#endif
|
#endif
|
||||||
sei();
|
sei();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// initialize timer which triggers the interrupt
|
||||||
|
static 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
|
||||||
|
*/
|
||||||
|
|
||||||
// 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
|
|
||||||
|
|
||||||
*/
|
|
||||||
#ifdef __AVR_ATmega644P__
|
#ifdef __AVR_ATmega644P__
|
||||||
TCCR0A = 0x02; // CTC Mode
|
TCCR0A = 0x02; // CTC Mode
|
||||||
TCCR0B = 0x04; // clk/256
|
TCCR0B = 0x04; // clk/256
|
||||||
TCNT0 = 0; // reset timer
|
TCNT0 = 0; // reset timer
|
||||||
OCR0 = 20; // Compare with this value
|
OCR0 = 20; // compare with this value
|
||||||
TIMSK0 = 0x02; // Compare match Interrupt on
|
TIMSK0 = 0x02; // compare match Interrupt on
|
||||||
#else
|
#else
|
||||||
TCCR0 = 0x0C; // CTC Mode, clk/256
|
TCCR0 = 0x0C; // CTC Mode, clk/256
|
||||||
TCNT0 = 0; // reset timer
|
TCNT0 = 0; // reset timer
|
||||||
OCR0 = 20; // Compare with this value
|
OCR0 = 20; // compare with this value
|
||||||
TIMSK = 0x02; // Compare match Interrupt on
|
TIMSK = 0x02; // compare match Interrupt on
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void borg_hw_init(){
|
void borg_hw_init() {
|
||||||
//Spalten Ports auf Ausgang
|
// switch column ports to output mode
|
||||||
COLDDR1 = 0xFF;
|
COLDDR1 = 0xFF;
|
||||||
COLDDR2 = 0xFF;
|
COLDDR2 = 0xFF;
|
||||||
|
|
||||||
//Pins am Zeilenport auf Ausgang
|
// switch pins of the row port to output mode
|
||||||
ROWDDR = (1<<PIN_MCLR) | (1<<PIN_CLK) | (1<< PIN_DATA);
|
ROWDDR = (1 << PIN_MCLR) | (1 << PIN_CLK) | (1 << PIN_DATA);
|
||||||
|
|
||||||
//Alle Spalten erstmal aus
|
// switch off all columns for now
|
||||||
COLPORT1 = 0;
|
COLPORT1 = 0;
|
||||||
COLPORT2 = 0;
|
COLPORT2 = 0;
|
||||||
|
|
||||||
//Schieberegister für Zeilen zurücksetzen
|
// reset shift registers for the rows
|
||||||
ROWPORT = 0;
|
ROWPORT = 0;
|
||||||
|
|
||||||
timer0_on();
|
timer0_on();
|
||||||
|
|
||||||
//Watchdog Timer aktivieren
|
// activate watchdog timer
|
||||||
wdt_reset();
|
wdt_reset();
|
||||||
wdt_enable(0x00); // 17ms Watchdog
|
wdt_enable(0x00); // 17ms watchdog
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
#include "../config.h"
|
#include "../config.h"
|
||||||
#include "../makros.h"
|
#include "../makros.h"
|
||||||
|
|
||||||
|
@ -8,119 +7,123 @@
|
||||||
|
|
||||||
#include "borg_hw.h"
|
#include "borg_hw.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// Diese #defines werden nun durch menuconfig gesetzt
|
// those macros get defined via menuconfig, now
|
||||||
|
|
||||||
#define ROWPORT PORTB
|
#define ROWPORT PORTB
|
||||||
#define ROWDDR DDRB
|
#define ROWDDR DDRB
|
||||||
|
|
||||||
#define COLPORT PORTD
|
#define COLPORT PORTD
|
||||||
#define COLDDR DDRD
|
#define COLDDR DDRD
|
||||||
|
|
||||||
#define PIN_DATA PC4
|
#define PIN_DATA PC4
|
||||||
#define PIN_CLK PC6 //active low
|
#define PIN_CLK PC6 //active low
|
||||||
#define PIN_LINE_EN PC5 //active low
|
#define PIN_LINE_EN PC5 //active low
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#define COLDDR DDR(COLPORT)
|
||||||
|
#define ROWDDR DDR(ROWPORT)
|
||||||
|
|
||||||
#define COLDDR DDR(COLPORT)
|
|
||||||
#define ROWDDR DDR(ROWPORT)
|
|
||||||
|
|
||||||
unsigned char pixmap[NUMPLANE][NUM_ROWS][LINEBYTES];
|
unsigned char pixmap[NUMPLANE][NUM_ROWS][LINEBYTES];
|
||||||
|
|
||||||
|
|
||||||
inline void rowshow(unsigned char row, unsigned char plane){
|
inline void rowshow(unsigned char row, unsigned char plane) {
|
||||||
COLPORT |= (1<<PIN_LINE_EN);//blank display
|
COLPORT |= (1 << PIN_LINE_EN); //blank display
|
||||||
|
|
||||||
ROWPORT = (ROWPORT & 0xF8) | row;
|
ROWPORT = (ROWPORT & 0xF8) | row;
|
||||||
|
|
||||||
|
|
||||||
unsigned char b, d, x;
|
unsigned char b, d, x;
|
||||||
for(b=0;b<LINEBYTES;b++){
|
for (b = 0; b < LINEBYTES; b++) {
|
||||||
d = pixmap[plane][row][b];
|
d = pixmap[plane][row][b];
|
||||||
for(x=0;x<8;x++){
|
for (x = 0; x < 8; x++) {
|
||||||
if(d & 0x01){
|
if (d & 0x01) {
|
||||||
COLPORT |= (1<<PIN_DATA);
|
COLPORT |= (1 << PIN_DATA);
|
||||||
}else{
|
} else {
|
||||||
COLPORT &= ~(1<<PIN_DATA);
|
COLPORT &= ~(1 << PIN_DATA);
|
||||||
}
|
}
|
||||||
d>>=1;
|
d >>= 1;
|
||||||
COLPORT &= ~(1<<PIN_CLK);
|
COLPORT &= ~(1 << PIN_CLK);
|
||||||
COLPORT |= (1<<PIN_CLK);
|
COLPORT |= (1 << PIN_CLK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
COLPORT &= ~(1<<PIN_LINE_EN);//unblank display
|
COLPORT &= ~(1 << PIN_LINE_EN); // unblank display
|
||||||
}
|
}
|
||||||
|
|
||||||
SIGNAL(SIG_OUTPUT_COMPARE0)
|
|
||||||
{
|
SIGNAL(SIG_OUTPUT_COMPARE0) {
|
||||||
static unsigned char plane = 0;
|
static unsigned char plane = 0;
|
||||||
static unsigned char row = 0;
|
static unsigned char row = 0;
|
||||||
|
|
||||||
if (row == 0){
|
if (row == 0) {
|
||||||
switch (plane){
|
switch (plane) {
|
||||||
case 0:
|
case 0:
|
||||||
OCR0 = 7;
|
OCR0 = 7;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
OCR0 = 20;
|
OCR0 = 20;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
OCR0 = 40;
|
OCR0 = 40;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rowshow(row, plane);
|
rowshow(row, plane);
|
||||||
|
|
||||||
if(++row == NUM_ROWS){
|
if (++row == NUM_ROWS) {
|
||||||
row = 0;
|
row = 0;
|
||||||
if(++plane==NUMPLANE) plane=0;
|
if (++plane == NUMPLANE)
|
||||||
|
plane = 0;
|
||||||
}
|
}
|
||||||
wdt_reset();
|
wdt_reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
void timer0_on(){
|
*/
|
||||||
/* TCCR0: FOC0 WGM00 COM01 COM00 WGM01 CS02 CS01 CS00
|
TCCR0 = 0x08 | 0x04; // CTC Mode, clk/256
|
||||||
CS02 CS01 CS00
|
TCNT0 = 0; // reset timer
|
||||||
0 0 0 stop
|
OCR0 = 0x30; // compare with this value
|
||||||
0 0 1 clk
|
TIMSK = 0x02; // compare match Interrupt on
|
||||||
0 1 0 clk/8
|
|
||||||
0 1 1 clk/64
|
|
||||||
1 0 0 clk/256
|
|
||||||
1 0 1 clk/1024
|
|
||||||
|
|
||||||
*/
|
|
||||||
TCCR0 = 0x08 |0x04; // CTC Mode, clk/256
|
|
||||||
TCNT0 = 0; // reset timer
|
|
||||||
OCR0 = 0x30; // Compare with this value
|
|
||||||
TIMSK = 0x02; // Compare match Interrupt on
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void timer0_off(){
|
|
||||||
|
void timer0_off() {
|
||||||
cli();
|
cli();
|
||||||
|
|
||||||
COLPORT |= (1<<PIN_LINE_EN);//blank display
|
COLPORT |= (1 << PIN_LINE_EN); //blank display
|
||||||
|
|
||||||
TCCR0 = 0x00;
|
TCCR0 = 0x00;
|
||||||
sei();
|
sei();
|
||||||
}
|
}
|
||||||
|
|
||||||
void watchdog_enable()
|
|
||||||
{
|
void watchdog_enable() {
|
||||||
wdt_reset();
|
wdt_reset();
|
||||||
wdt_enable(0x00); // 17ms
|
wdt_enable(0x00); // 17ms
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void borg_hw_init(){
|
|
||||||
COLPORT |= (1<<PIN_CLK) | (1<<PIN_LINE_EN);
|
void borg_hw_init() {
|
||||||
COLDDR |= (1<<PIN_CLK) | (1<<PIN_LINE_EN) | (1<<PIN_DATA);
|
COLPORT |= (1 << PIN_CLK) | (1 << PIN_LINE_EN);
|
||||||
|
COLDDR |= (1 << PIN_CLK) | (1 << PIN_LINE_EN) | (1 << PIN_DATA);
|
||||||
|
|
||||||
ROWDDR |= 0x07;
|
ROWDDR |= 0x07;
|
||||||
|
|
||||||
watchdog_enable();
|
watchdog_enable();
|
||||||
timer0_on();
|
timer0_on();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
#include "../config.h"
|
#include "../config.h"
|
||||||
#include "../makros.h"
|
#include "../makros.h"
|
||||||
|
|
||||||
|
@ -8,7 +7,6 @@
|
||||||
|
|
||||||
#include "borg_hw.h"
|
#include "borg_hw.h"
|
||||||
|
|
||||||
|
|
||||||
#define ROWPORT PORTC
|
#define ROWPORT PORTC
|
||||||
#define ROWDDR DDRC
|
#define ROWDDR DDRC
|
||||||
|
|
||||||
|
@ -26,125 +24,113 @@
|
||||||
|
|
||||||
unsigned char pixmap[NUMPLANE][NUM_ROWS][LINEBYTES];
|
unsigned char pixmap[NUMPLANE][NUM_ROWS][LINEBYTES];
|
||||||
|
|
||||||
|
inline void rowshow(unsigned char row, unsigned char plane) {
|
||||||
|
|
||||||
inline void rowshow(unsigned char row, unsigned char plane){
|
unsigned char p, n, m, outb, clkmsk;
|
||||||
|
|
||||||
unsigned char p, n,m, outb, clkmsk;
|
|
||||||
|
|
||||||
clkmsk = 0x80>>row;
|
clkmsk = 0x80 >> row;
|
||||||
|
|
||||||
// if (row==4)
|
|
||||||
{
|
|
||||||
MYPORT &= ~(1 << PIN_ENABLE) ;
|
|
||||||
//MYPORT |= (1 << PIN_ENABLE) ; //hide
|
|
||||||
// MYPORT |= (1 << PIN_ENABLE) ; //hide
|
|
||||||
for (n=7;n<8;n--)
|
|
||||||
{
|
|
||||||
outb = pixmap[plane][row][n];
|
|
||||||
p=0x80;
|
|
||||||
for (m=0;m<8;m++)
|
|
||||||
{
|
|
||||||
if (outb & p)
|
|
||||||
// MYPORT |= (1 << PIN_DATA);
|
|
||||||
MYPORT &= ~(1 << PIN_DATA) ;
|
|
||||||
else
|
|
||||||
// MYPORT &= ~(1 << PIN_DATA) ; //off
|
|
||||||
MYPORT |= (1 << PIN_DATA);
|
|
||||||
|
|
||||||
MYPORT2 &= ~clkmsk ;
|
|
||||||
MYPORT2 |= clkmsk ;
|
|
||||||
|
|
||||||
p>>=1;
|
// if (row==4)
|
||||||
|
{
|
||||||
|
MYPORT &= ~(1 << PIN_ENABLE);
|
||||||
|
// MYPORT |= (1 << PIN_ENABLE); //hide
|
||||||
|
// MYPORT |= (1 << PIN_ENABLE); //hide
|
||||||
|
for (n = 7; n < 8; n--) {
|
||||||
|
outb = pixmap[plane][row][n];
|
||||||
|
p = 0x80;
|
||||||
|
for (m = 0; m < 8; m++) {
|
||||||
|
if (outb & p)
|
||||||
|
// MYPORT |= (1 << PIN_DATA);
|
||||||
|
MYPORT &= ~(1 << PIN_DATA);
|
||||||
|
else
|
||||||
|
// MYPORT &= ~(1 << PIN_DATA); //off
|
||||||
|
MYPORT |= (1 << PIN_DATA);
|
||||||
|
|
||||||
}
|
MYPORT2 &= ~clkmsk;
|
||||||
}
|
MYPORT2 |= clkmsk;
|
||||||
}
|
|
||||||
MYPORT |= (1 << PIN_ENABLE) ; //
|
|
||||||
//MYPORT &= ~(1 << PIN_ENABLE) ;
|
|
||||||
// for(n=0;n<250;n++) asm ("nop");
|
|
||||||
|
|
||||||
|
|
||||||
|
p >>= 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MYPORT |= (1 << PIN_ENABLE);
|
||||||
|
//MYPORT &= ~(1 << PIN_ENABLE) ;
|
||||||
|
// for(n=0;n<250;n++) asm ("nop");
|
||||||
}
|
}
|
||||||
|
|
||||||
SIGNAL(SIG_OUTPUT_COMPARE0)
|
SIGNAL( SIG_OUTPUT_COMPARE0) {
|
||||||
{
|
static unsigned char plane = 0;
|
||||||
static unsigned char plane = 0;
|
unsigned char row = 0;
|
||||||
unsigned char row = 0;
|
|
||||||
|
|
||||||
switch (plane){
|
switch (plane) {
|
||||||
case 0:
|
case 0:
|
||||||
OCR0 = 60;
|
OCR0 = 60;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
OCR0 = 120;
|
OCR0 = 120;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
OCR0 = 160;
|
OCR0 = 160;
|
||||||
break;
|
break;
|
||||||
// case 3:
|
// case 3:
|
||||||
// OCR0 = 24;
|
// OCR0 = 24;
|
||||||
// break;
|
// break;
|
||||||
// case 4:
|
// case 4:
|
||||||
// OCR0 = 48;
|
// OCR0 = 48;
|
||||||
// break;
|
// break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(row=0;row<NUM_ROWS;row++){
|
for (row = 0; row < NUM_ROWS; row++) {
|
||||||
rowshow(row, plane);
|
rowshow(row, plane);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(++plane==NUMPLANE) plane=0;
|
if (++plane == NUMPLANE)
|
||||||
wdt_reset();
|
plane = 0;
|
||||||
|
wdt_reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void timer0_on() {
|
||||||
|
/* TCCR0: FOC0 WGM00 COM01 COM00 WGM01 CS02 CS01 CS00
|
||||||
void timer0_on(){
|
CS02 CS01 CS00
|
||||||
/* TCCR0: FOC0 WGM00 COM01 COM00 WGM01 CS02 CS01 CS00
|
0 0 0 stop
|
||||||
CS02 CS01 CS00
|
0 0 1 clk
|
||||||
0 0 0 stop
|
0 1 0 clk/8
|
||||||
0 0 1 clk
|
0 1 1 clk/64
|
||||||
0 1 0 clk/8
|
1 0 0 clk/256
|
||||||
0 1 1 clk/64
|
1 0 1 clk/1024
|
||||||
1 0 0 clk/256
|
*/
|
||||||
1 0 1 clk/1024
|
TCCR0 = 0x08 | 0x04; // CTC Mode, clk/256 MH: slower 5 instead of 4
|
||||||
|
TCNT0 = 0; // reset timer
|
||||||
*/
|
OCR0 = 0x30; // compare with this value 0x30
|
||||||
TCCR0 = 0x08 |0x04; // CTC Mode, clk/256 MH: slower 5 statt 4
|
TIMSK = 0x02; // compare match Interrupt on
|
||||||
TCNT0 = 0; // reset timer
|
|
||||||
OCR0 = 0x30; // Compare with this value 0x30
|
|
||||||
TIMSK = 0x02; // Compare match Interrupt on
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void timer0_off(){
|
void timer0_off() {
|
||||||
cli();
|
cli();
|
||||||
|
|
||||||
MYPORT &= ~(1 << PIN_ENABLE) ;
|
MYPORT &= ~(1 << PIN_ENABLE);
|
||||||
//MYPORT |= (1 << PIN_ENABLE) ; //hide
|
// MYPORT |= (1 << PIN_ENABLE); // hide
|
||||||
//COLPORT |= (1<<PIN_LINE_EN);//blank display
|
// COLPORT |= (1<<PIN_LINE_EN); // blank display
|
||||||
// PORTD |= 0x01;//blank display
|
// PORTD |= 0x01; // blank display
|
||||||
TCCR0 = 0x00;
|
TCCR0 = 0x00;
|
||||||
sei();
|
sei();
|
||||||
}
|
}
|
||||||
|
|
||||||
void watchdog_enable()
|
void watchdog_enable() {
|
||||||
{
|
wdt_reset();
|
||||||
wdt_reset();
|
wdt_enable(0x00); // 17ms
|
||||||
wdt_enable(0x00); // 17ms
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void borg_hw_init(){
|
void borg_hw_init() {
|
||||||
//COLPORT |= (1<<PIN_CLK) | (1<<PIN_LINE_EN);
|
//COLPORT |= (1<<PIN_CLK) | (1<<PIN_LINE_EN);
|
||||||
//COLDDR |= (1<<PIN_CLK) | (1<<PIN_LINE_EN) | (1<<PIN_DATA);
|
//COLDDR |= (1<<PIN_CLK) | (1<<PIN_LINE_EN) | (1<<PIN_DATA);
|
||||||
|
|
||||||
//ROWDDR |= 0x07;
|
//ROWDDR |= 0x07;
|
||||||
|
|
||||||
DDRA = 0xFF;
|
|
||||||
|
|
||||||
DDRC = 0xFF;
|
DDRA = 0xFF;
|
||||||
|
DDRC = 0xFF;
|
||||||
watchdog_enable();
|
|
||||||
timer0_on();
|
watchdog_enable();
|
||||||
|
timer0_on();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
#include "../config.h"
|
#include "../config.h"
|
||||||
#include "../makros.h"
|
#include "../makros.h"
|
||||||
|
|
||||||
|
@ -8,24 +7,26 @@
|
||||||
#include "borg_hw.h"
|
#include "borg_hw.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// Diese #defines werden nun durch menuconfig gesetzt
|
// those macros get defined via menuconfig, now
|
||||||
|
|
||||||
// 16 Spalten insgesamt direkt gesteuert, dafür 2 Ports
|
// 16 columns total directly controlled, therefore 2 ports
|
||||||
#define COLPORT1 PORTC
|
#define COLPORT1 PORTC
|
||||||
#define COLDDR1 DDRC
|
#define COLDDR1 DDRC
|
||||||
|
|
||||||
#define COLPORT2 PORTA
|
#define COLPORT2 PORTA
|
||||||
#define COLDDR2 DDRA
|
#define COLDDR2 DDRA
|
||||||
|
|
||||||
// Der andere Port übernimmt die Steuerung der Schieberegister
|
// the other port controls the shift registers
|
||||||
#define ROWPORT PORTD
|
#define ROWPORT PORTD
|
||||||
#define ROWDDR DDRD
|
#define ROWDDR DDRD
|
||||||
// Clock und reset gehen gemeinsam an beide Schieberegister
|
|
||||||
// der reset pin ist negiert
|
// both clock and reset are connected to each shift register
|
||||||
#define PIN_MCLR PD4
|
// reset pin is negated
|
||||||
#define PIN_CLK PD6
|
#define PIN_MCLR PD4
|
||||||
//das dier sind die individuellen Dateneingänge für die Schieberegister
|
#define PIN_CLK PD6
|
||||||
#define PIN_DATA PD7
|
|
||||||
|
// these are the individual data input pins for the shift registers
|
||||||
|
#define PIN_DATA PD7
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define COLDDR1 DDR(COLPORT1)
|
#define COLDDR1 DDR(COLPORT1)
|
||||||
|
@ -39,23 +40,22 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
//Der Puffer, in dem das aktuelle Bild gespeichert wird
|
// buffer which holds the currently shown frame
|
||||||
unsigned char pixmap[NUMPLANE][NUM_ROWS][LINEBYTES];
|
unsigned char pixmap[NUMPLANE][NUM_ROWS][LINEBYTES];
|
||||||
|
|
||||||
|
|
||||||
//Dieser Interrupt wird je nach Ebene mit 50kHz 31,25kHz oder 12,5kHz ausgeführt
|
// depending on the plane this interrupt gets triggered at 50 kHz, 31.25 kHz or
|
||||||
SIGNAL(SIG_OUTPUT_COMPARE0)
|
// 12.5 kHz
|
||||||
{
|
SIGNAL( SIG_OUTPUT_COMPARE0) {
|
||||||
//Watchdog zurücksetzen
|
// reset watchdog
|
||||||
wdt_reset();
|
wdt_reset();
|
||||||
|
|
||||||
|
|
||||||
COLPORT1 = (pixmap[0][0][0] & 0x0f) | (pixmap[0][1][0] << 4);
|
COLPORT1 = (pixmap[0][0][0] & 0x0f) | (pixmap[0][1][0] << 4);
|
||||||
COLPORT2 = (pixmap[0][2][0] & 0x0f) | (pixmap[0][3][0] << 4);
|
COLPORT2 = (pixmap[0][2][0] & 0x0f) | (pixmap[0][3][0] << 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void timer0_off(){
|
void timer0_off() {
|
||||||
cli();
|
cli();
|
||||||
|
|
||||||
COLPORT1 = 0;
|
COLPORT1 = 0;
|
||||||
|
@ -63,69 +63,67 @@ void timer0_off(){
|
||||||
ROWPORT = 0;
|
ROWPORT = 0;
|
||||||
|
|
||||||
#ifdef __AVR_ATmega644P__
|
#ifdef __AVR_ATmega644P__
|
||||||
TCCR0A = 0x00;
|
TCCR0A = 0x00;
|
||||||
TCCR0B = 0x00;
|
TCCR0B = 0x00;
|
||||||
#else
|
#else
|
||||||
|
|
||||||
TCCR0 = 0x00;
|
TCCR0 = 0x00;
|
||||||
#endif
|
#endif
|
||||||
sei();
|
sei();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Den Timer, der denn Interrupt auslöst, initialisieren
|
// initialize timer which triggers the interrupt
|
||||||
void timer0_on(){
|
void timer0_on() {
|
||||||
/* TCCR0: FOC0 WGM00 COM01 COM00 WGM01 CS02 CS01 CS00
|
/* TCCR0: FOC0 WGM00 COM01 COM00 WGM01 CS02 CS01 CS00
|
||||||
CS02 CS01 CS00
|
CS02 CS01 CS00
|
||||||
0 0 0 stop
|
0 0 0 stop
|
||||||
0 0 1 clk
|
0 0 1 clk
|
||||||
0 1 0 clk/8
|
0 1 0 clk/8
|
||||||
0 1 1 clk/64
|
0 1 1 clk/64
|
||||||
1 0 0 clk/256
|
1 0 0 clk/256
|
||||||
1 0 1 clk/1024
|
1 0 1 clk/1024
|
||||||
|
*/
|
||||||
*/
|
|
||||||
#ifdef __AVR_ATmega644P__
|
#ifdef __AVR_ATmega644P__
|
||||||
TCCR0A = 0x02; // CTC Mode
|
TCCR0A = 0x02; // CTC Mode
|
||||||
TCCR0B = 0x04; // clk/256
|
TCCR0B = 0x04; // clk/256
|
||||||
TCNT0 = 0; // reset timer
|
TCNT0 = 0; // reset timer
|
||||||
OCR0 = 20; // Compare with this value
|
OCR0 = 20; // compare with this value
|
||||||
TIMSK0 = 0x02; // Compare match Interrupt on
|
TIMSK0 = 0x02; // compare match Interrupt on
|
||||||
#else
|
#else
|
||||||
TCCR0 = 0x0C; // CTC Mode, clk/256
|
TCCR0 = 0x0C; // CTC Mode, clk/256
|
||||||
TCNT0 = 0; // reset timer
|
TCNT0 = 0; // reset timer
|
||||||
OCR0 = 20; // Compare with this value
|
OCR0 = 20; // compare with this value
|
||||||
TIMSK = 0x02; // Compare match Interrupt on
|
TIMSK = 0x02; // compare match Interrupt on
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void borg_hw_init(){
|
|
||||||
//Spalten Ports auf Ausgang
|
void borg_hw_init() {
|
||||||
|
// switch column ports to output mode
|
||||||
COLDDR1 = 0xFF;
|
COLDDR1 = 0xFF;
|
||||||
COLDDR2 = 0xFF;
|
COLDDR2 = 0xFF;
|
||||||
|
|
||||||
//Pins am Zeilenport auf Ausgang
|
// switch pins of the row port to output mode
|
||||||
ROWDDR = (1<<PIN_MCLR) | (1<<PIN_CLK) | (1<< PIN_DATA);
|
ROWDDR = (1 << PIN_MCLR) | (1 << PIN_CLK) | (1 << PIN_DATA);
|
||||||
|
|
||||||
//Alle Spalten erstmal aus
|
// switch off all columns for now
|
||||||
COLPORT1 = 0;
|
COLPORT1 = 0;
|
||||||
COLPORT2 = 0;
|
COLPORT2 = 0;
|
||||||
|
|
||||||
//Schieberegister für Zeilen zurücksetzen
|
// reset shift registers for the rows
|
||||||
ROWPORT = 0;
|
ROWPORT = 0;
|
||||||
|
|
||||||
//Alle Zeilen ausgänge an bei gigaborg
|
// switch on all row output ports of the gigaborg
|
||||||
ROWPORT |= (1<<PIN_DATA) | (1<<PIN_MCLR);
|
ROWPORT |= (1 << PIN_DATA) | (1 << PIN_MCLR);
|
||||||
uint8_t x;
|
uint8_t x;
|
||||||
for(x=0;x<16;x++){
|
for (x = 0; x < 16; x++) {
|
||||||
ROWPORT|= (1<<PIN_CLK);
|
ROWPORT |= (1 << PIN_CLK);
|
||||||
ROWPORT&= ~(1<<PIN_CLK);
|
ROWPORT &= ~(1 << PIN_CLK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
timer0_on();
|
timer0_on();
|
||||||
|
|
||||||
//Watchdog Timer aktivieren
|
// activate watchdog timer
|
||||||
wdt_reset();
|
wdt_reset();
|
||||||
wdt_enable(0x00); // 17ms Watchdog
|
wdt_enable(0x00); // 17ms watchdog
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
|
|
||||||
#include"../autoconf.h"
|
#include"../autoconf.h"
|
||||||
#include <avr/interrupt.h>
|
#include <avr/interrupt.h>
|
||||||
#include <avr/io.h>
|
#include <avr/io.h>
|
||||||
#include <avr/wdt.h>
|
#include <avr/wdt.h>
|
||||||
#include "borg_hw.h"
|
#include "borg_hw.h"
|
||||||
|
|
||||||
/* Steckerbelegung Flachbandkabel am Panel
|
|
||||||
* (die Nummerierung ist in wirklichkeit umgekehrt)
|
/* pinout of the ribbon cable connected to the panel
|
||||||
|
* (the numbering is actually upside down)
|
||||||
*
|
*
|
||||||
* 1-3 GND
|
* 1-3 GND
|
||||||
* 4 +5V für Logic
|
* 4 +5V for logic
|
||||||
* 5-8 +12V
|
* 5-8 +12V
|
||||||
* 9-10 GND
|
* 9-10 GND
|
||||||
* 11 CP3
|
* 11 CP3
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
* 17-18 GND
|
* 17-18 GND
|
||||||
* 19-26 D0-D7
|
* 19-26 D0-D7
|
||||||
*
|
*
|
||||||
* Und nochmal richtigrum:
|
* and now the right way round:
|
||||||
* 1 D7
|
* 1 D7
|
||||||
* 2 D6
|
* 2 D6
|
||||||
* 3 D5
|
* 3 D5
|
||||||
|
@ -49,22 +49,20 @@
|
||||||
* 25 GND
|
* 25 GND
|
||||||
* 26 GND
|
* 26 GND
|
||||||
*
|
*
|
||||||
* Es werden 4 40374 Latches benutzt. Nr. 1,2 und 4 treiben vom Datenbus
|
* Four 40374 latches are used. No. 1, 2 and 4 drive from the data bus to the
|
||||||
* in Richtung Panel, Nr. 3 treibt von den Tastenausgängen auf den Datenbus.
|
* panel, no. 3 drives from the button outputs to the data bus. The EOs of
|
||||||
* Die EOs von 1,2 und 4 liegen fest auf GND.
|
* 1, 2 and 4 are hardwired to GND.
|
||||||
*
|
*
|
||||||
* Die LEDs sind in einer 12*16 Matrix angeordnet
|
* The LEDs are aligned to a 12*16 matrix. The values for the LED columns are
|
||||||
* Die Werte für die LED spalten Werden mit CP1 und CP2 in die
|
* passed to the latches via CP1 und CP2 (16 columns total). The index of the
|
||||||
* Latches übernommen (insgesammt 16 Spalten)
|
* row is passed during the deletion of "/show".
|
||||||
* Die Nummer der Zeile wird beim löschen von /show übernommen.
|
|
||||||
*
|
*
|
||||||
* Die Tasten sind in einer 8*8 Matrix angeordnet.
|
* The buttons are aligned to an 8*8 matrix. The rows get separately set to
|
||||||
* Über Latch 4 werden die Zeilen einzeln auf high gesetzt, über
|
* "high" via latch 4. The columns can then be read via latch 3.
|
||||||
* Latch 3 können dann die Spalten gelesen werden.
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//Datenport für das Panel
|
|
||||||
|
// data port for the panel
|
||||||
#define COLPORT PORTC
|
#define COLPORT PORTC
|
||||||
#define COLDDR DDRC
|
#define COLDDR DDRC
|
||||||
#define COLPIN PINC
|
#define COLPIN PINC
|
||||||
|
@ -72,7 +70,7 @@
|
||||||
#define CTRLPORT PORTD
|
#define CTRLPORT PORTD
|
||||||
#define CTRLDDR DDRD
|
#define CTRLDDR DDRD
|
||||||
|
|
||||||
// PINs on CTRLPORT
|
// pins on CTRLPORT
|
||||||
#define PIN_EO3 PD7
|
#define PIN_EO3 PD7
|
||||||
#define PIN_CP4 PD2
|
#define PIN_CP4 PD2
|
||||||
#define PIN_SHOW PD3
|
#define PIN_SHOW PD3
|
||||||
|
@ -80,84 +78,88 @@
|
||||||
#define PIN_CP2 PD5
|
#define PIN_CP2 PD5
|
||||||
#define PIN_CP3 PD6
|
#define PIN_CP3 PD6
|
||||||
|
|
||||||
//Der Puffer, in dem das aktuelle Bild gespeichert wird
|
|
||||||
|
// buffer which holds the currently shown frame
|
||||||
unsigned char pixmap[NUMPLANE][NUM_ROWS][LINEBYTES];
|
unsigned char pixmap[NUMPLANE][NUM_ROWS][LINEBYTES];
|
||||||
|
|
||||||
volatile uint8_t keys[8];
|
volatile uint8_t keys[8];
|
||||||
|
|
||||||
|
|
||||||
inline void busywait() {
|
inline void busywait() {
|
||||||
//unsigned char i;
|
//unsigned char i;
|
||||||
//for(i=0;i<20;i++){
|
//for(i=0; i < 20; i++){
|
||||||
// asm volatile("nop");
|
// asm volatile("nop");
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//Eine Zeile anzeigen
|
// display a row
|
||||||
inline void rowshow(unsigned char row, unsigned char plane){
|
inline void rowshow(unsigned char row, unsigned char plane){
|
||||||
CTRLPORT |= (1<<PIN_SHOW);//blank
|
CTRLPORT |= (1 << PIN_SHOW); //blank
|
||||||
|
|
||||||
COLPORT = pixmap[plane][row][0];
|
COLPORT = pixmap[plane][row][0];
|
||||||
busywait();
|
busywait();
|
||||||
CTRLPORT |= (1<<PIN_CP1);
|
CTRLPORT |= (1 << PIN_CP1);
|
||||||
busywait();
|
busywait();
|
||||||
CTRLPORT &= ~(1<<PIN_CP1);
|
CTRLPORT &= ~(1 << PIN_CP1);
|
||||||
busywait();
|
busywait();
|
||||||
|
|
||||||
COLPORT = pixmap[plane][row][1];
|
COLPORT = pixmap[plane][row][1];
|
||||||
busywait();
|
busywait();
|
||||||
CTRLPORT |= (1<<PIN_CP2);
|
CTRLPORT |= (1 << PIN_CP2);
|
||||||
busywait();
|
busywait();
|
||||||
CTRLPORT &= ~(1<<PIN_CP2);
|
CTRLPORT &= ~(1 << PIN_CP2);
|
||||||
busywait();
|
busywait();
|
||||||
|
|
||||||
COLPORT = row;
|
COLPORT = row;
|
||||||
busywait();
|
busywait();
|
||||||
CTRLPORT &= ~(1<<PIN_SHOW);
|
CTRLPORT &= ~(1 << PIN_SHOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void checkkeys(uint8_t row){
|
inline void checkkeys(uint8_t row){
|
||||||
static uint8_t mask;
|
static uint8_t mask;
|
||||||
if(row == 0){
|
if (row == 0) {
|
||||||
mask = 1;
|
mask = 1;
|
||||||
}else{
|
} else {
|
||||||
//read keyboard cols into latch
|
//read keyboard cols into latch
|
||||||
COLDDR = 0;
|
COLDDR = 0;
|
||||||
CTRLPORT &= ~(1<<PIN_EO3);
|
CTRLPORT &= ~(1 << PIN_EO3);
|
||||||
CTRLPORT |= (1<<PIN_CP3);
|
CTRLPORT |= (1 << PIN_CP3);
|
||||||
busywait();
|
busywait();
|
||||||
CTRLPORT &= ~(1<<PIN_CP3);
|
CTRLPORT &= ~(1 << PIN_CP3);
|
||||||
busywait();
|
busywait();
|
||||||
keys[row-1] = COLPIN;
|
keys[row - 1] = COLPIN;
|
||||||
CTRLPORT |= (1<<PIN_EO3);
|
CTRLPORT |= (1 << PIN_EO3);
|
||||||
busywait();
|
busywait();
|
||||||
COLDDR = 0xFF;
|
COLDDR = 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
COLPORT = mask;
|
COLPORT = mask;
|
||||||
mask <<= 1;
|
mask <<= 1;
|
||||||
busywait();
|
busywait();
|
||||||
CTRLPORT |= (1<<PIN_CP4);
|
CTRLPORT |= (1 << PIN_CP4);
|
||||||
busywait();
|
busywait();
|
||||||
CTRLPORT &= ~(1<<PIN_CP4);
|
CTRLPORT &= ~(1 << PIN_CP4);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Dieser Interrupt wird je nach Ebene mit 50kHz 31,25kHz oder 12,5kHz ausgeführt
|
|
||||||
|
// depending on the plane this interrupt gets triggered at 50 kHz, 31.25 kHz or
|
||||||
|
// 12.5 kHz
|
||||||
SIGNAL(SIG_OUTPUT_COMPARE0)
|
SIGNAL(SIG_OUTPUT_COMPARE0)
|
||||||
{
|
{
|
||||||
static unsigned char plane = 0;
|
static unsigned char plane = 0;
|
||||||
static unsigned char row = 0;
|
static unsigned char row = 0;
|
||||||
|
|
||||||
|
|
||||||
//Watchdog zurücksetzen
|
// reset watchdog
|
||||||
wdt_reset();
|
wdt_reset();
|
||||||
|
|
||||||
//Die aktuelle Zeile in der aktuellen Ebene ausgeben
|
// output current row according to current plane
|
||||||
rowshow(row, plane);
|
rowshow(row, plane);
|
||||||
|
|
||||||
if( (plane == 2) && (row<9) ) checkkeys(row);
|
if( (plane == 2) && (row<9) ) checkkeys(row);
|
||||||
|
|
||||||
//Zeile und Ebene inkrementieren
|
// increment both row and plane
|
||||||
if(++row == NUM_ROWS){
|
if(++row == NUM_ROWS){
|
||||||
row = 0;
|
row = 0;
|
||||||
if(++plane==NUMPLANE) plane=0;
|
if(++plane==NUMPLANE) plane=0;
|
||||||
|
@ -184,37 +186,38 @@ void timer0_off(){
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Den Timer, der denn Interrupt auslöst, initialisieren
|
// initialize timer which triggers the interrupt
|
||||||
void timer0_on(){
|
void timer0_on(){
|
||||||
/* TCCR0: FOC0 WGM00 COM01 COM00 WGM01 CS02 CS01 CS00
|
/* TCCR0: FOC0 WGM00 COM01 COM00 WGM01 CS02 CS01 CS00
|
||||||
CS02 CS01 CS00
|
CS02 CS01 CS00
|
||||||
0 0 0 stop
|
0 0 0 stop
|
||||||
0 0 1 clk
|
0 0 1 clk
|
||||||
0 1 0 clk/8
|
0 1 0 clk/8
|
||||||
0 1 1 clk/64
|
0 1 1 clk/64
|
||||||
1 0 0 clk/256
|
1 0 0 clk/256
|
||||||
1 0 1 clk/1024
|
1 0 1 clk/1024
|
||||||
|
*/
|
||||||
*/
|
TCCR0 = 0x0C; // CTC Mode, clk/64
|
||||||
TCCR0 = 0x0C; // CTC Mode, clk/64
|
TCNT0 = 0; // reset timer
|
||||||
TCNT0 = 0; // reset timer
|
OCR0 = 20; // compare with this value
|
||||||
OCR0 = 20; // Compare with this value
|
TIMSK = 0x02; // compare match Interrupt on
|
||||||
TIMSK = 0x02; // Compare match Interrupt on
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void borg_hw_init(){
|
void borg_hw_init(){
|
||||||
//Pins am Zeilenport auf Ausgang
|
//Pins am Zeilenport auf Ausgang
|
||||||
CTRLPORT |= (1<<PIN_EO3)|(1<<PIN_SHOW);
|
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);
|
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
|
// switch off all columns for now
|
||||||
COLDDR = 0xFF;
|
// switch column ports to output mode
|
||||||
|
COLDDR = 0xFF;
|
||||||
COLPORT = 0x00;
|
COLPORT = 0x00;
|
||||||
|
|
||||||
timer0_on();
|
timer0_on();
|
||||||
|
|
||||||
//Watchdog Timer aktivieren
|
// activate watchdog timer
|
||||||
wdt_reset();
|
wdt_reset();
|
||||||
wdt_enable(0x00); // 17ms Watchdog
|
wdt_enable(0x00); // 17ms watchdog
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
#include "../config.h"
|
#include "../config.h"
|
||||||
#include "../makros.h"
|
#include "../makros.h"
|
||||||
|
|
||||||
|
@ -8,30 +7,31 @@
|
||||||
#include "borg_hw.h"
|
#include "borg_hw.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// Diese #defines werden nun durch menuconfig gesetzt
|
// those macros get defined via menuconfig, now
|
||||||
|
|
||||||
// 16 Spalten insgesamt direkt gesteuert, dafür 2 Ports
|
// 16 columns total directly controlled, therefore 2 ports
|
||||||
#define COLPORT1 PORTC
|
#define COLPORT1 PORTC
|
||||||
#define COLDDR1 DDRC
|
#define COLDDR1 DDRC
|
||||||
|
|
||||||
#define COLPORT2 PORTA
|
#define COLPORT2 PORTA
|
||||||
#define COLDDR2 DDRA
|
#define COLDDR2 DDRA
|
||||||
|
|
||||||
// Der andere Port übernimmt die Steuerung der Schieberegister
|
// the other port controls the shift registers
|
||||||
#define ROWPORT PORTD
|
#define ROWPORT PORTD
|
||||||
#define ROWDDR DDRD
|
#define ROWDDR DDRD
|
||||||
// Clock und reset gehen gemeinsam an beide Schieberegister
|
|
||||||
// der reset pin ist negiert
|
// both clock and reset are connected to each shift register
|
||||||
#define PIN_MCLR PD4
|
// reset pin is negated
|
||||||
#define PIN_CLK PD6
|
#define PIN_MCLR PD4
|
||||||
//das dier sind die individuellen Dateneingänge für die Schieberegister
|
#define PIN_CLK PD6
|
||||||
#define PIN_DATA PD7
|
|
||||||
*/
|
// these are the individual data input pins for the shift registers
|
||||||
|
#define PIN_DATA PD7
|
||||||
|
*/
|
||||||
|
|
||||||
//#define COLDDR1 DDR(COLPORT1)
|
//#define COLDDR1 DDR(COLPORT1)
|
||||||
//#define COLDDR2 DDR(COLPORT2)
|
//#define COLDDR2 DDR(COLPORT2)
|
||||||
//#define ROWDDR DDR(ROWPORT)
|
//#define ROWDDR DDR(ROWPORT)
|
||||||
|
|
||||||
//#define DATAPORT PORTC
|
//#define DATAPORT PORTC
|
||||||
#define DATADDR DDR(DATAPORT)
|
#define DATADDR DDR(DATAPORT)
|
||||||
|
|
||||||
|
@ -50,64 +50,63 @@
|
||||||
|
|
||||||
//#define BIT_RW 6
|
//#define BIT_RW 6
|
||||||
|
|
||||||
//Der Puffer, in dem das aktuelle Bild gespeichert wird
|
// buffer which holds the currently shown frame
|
||||||
unsigned char pixmap[NUMPLANE][NUM_ROWS][LINEBYTES];
|
unsigned char pixmap[NUMPLANE][NUM_ROWS][LINEBYTES];
|
||||||
|
|
||||||
|
|
||||||
|
inline void pd1165_write(uint8_t addr, uint8_t data) {
|
||||||
inline void pd1165_write(uint8_t addr, uint8_t data){
|
|
||||||
ADDRPORT = (ADDRPORT & 0xf0) | addr;
|
ADDRPORT = (ADDRPORT & 0xf0) | addr;
|
||||||
|
|
||||||
DATAPORT = data;
|
DATAPORT = data;
|
||||||
/*
|
/*
|
||||||
switch (display){
|
switch (display) {
|
||||||
case 0:
|
case 0:
|
||||||
CTRLPORT &= ~((1<<BIT_CS0)|(1<<BIT_RW));
|
CTRLPORT &= ~((1 << BIT_CS0) | (1 << BIT_RW));
|
||||||
CTRLPORT |= ((1<<BIT_CS0));
|
CTRLPORT |= ((1 << BIT_CS0));
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
CTRLPORT &= ~((1<<BIT_CS1)|(1<<BIT_RW));
|
CTRLPORT &= ~((1 << BIT_CS1) | (1 << BIT_RW));
|
||||||
CTRLPORT |= ((1<<BIT_CS1));
|
CTRLPORT |= ((1 << BIT_CS1));
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
CTRLPORT &= ~((1<<BIT_CS2)|(1<<BIT_RW));
|
CTRLPORT &= ~((1 << BIT_CS2) | (1 << BIT_RW));
|
||||||
CTRLPORT |= ((1<<BIT_CS2));
|
CTRLPORT |= ((1 << BIT_CS2));
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
CTRLPORT &= ~((1<<BIT_CS3)|(1<<BIT_RW));
|
CTRLPORT &= ~((1 << BIT_CS3) | (1 << BIT_RW));
|
||||||
CTRLPORT |= ((1<<BIT_CS3));
|
CTRLPORT |= ((1 << BIT_CS3));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
//Eine Zeile anzeigen
|
// display a row
|
||||||
inline void rowshow(unsigned char row, unsigned char plane){
|
inline void rowshow(unsigned char row, unsigned char plane) {
|
||||||
int addr = row;
|
int addr = row;
|
||||||
//Je nachdem, welche der Ebenen wir Zeichnen, die Zeile verschieden lange Anzeigen
|
// depending on the currently drawn plane, display the row for a specific
|
||||||
switch (plane){
|
// amount of time
|
||||||
case 0:
|
switch (plane) {
|
||||||
OCR0 = 3;
|
case 0:
|
||||||
break;
|
OCR0 = 3;
|
||||||
case 1:
|
break;
|
||||||
OCR0 = 4;
|
case 1:
|
||||||
break;
|
OCR0 = 4;
|
||||||
case 2:
|
break;
|
||||||
OCR0 = 22;
|
case 2:
|
||||||
|
OCR0 = 22;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t tmp, tmp1;
|
uint8_t tmp, tmp1;
|
||||||
//die Daten für die aktuelle Zeile auf die Spaltentreiber ausgeben
|
// output data of current row to the column drivers
|
||||||
|
|
||||||
#ifndef INTERLACED_ROWS
|
#ifndef INTERLACED_ROWS
|
||||||
tmp = pixmap[plane][row][0];
|
tmp = pixmap[plane][row][0];
|
||||||
tmp1 = pixmap[plane][row][1];
|
tmp1 = pixmap[plane][row][1];
|
||||||
#else
|
#else
|
||||||
row = (row>>1) + ((row & 0x01)?8:0 );
|
row = (row>>1) + ((row & 0x01)?8:0 );
|
||||||
tmp = pixmap[plane][row][0];
|
tmp = pixmap[plane][row][0];
|
||||||
tmp1 = pixmap[plane][row][1];
|
tmp1 = pixmap[plane][row][1];
|
||||||
#endif
|
#endif
|
||||||
#ifdef REVERSE_COLS
|
#ifdef REVERSE_COLS
|
||||||
|
@ -123,7 +122,8 @@ inline void rowshow(unsigned char row, unsigned char plane){
|
||||||
#else
|
#else
|
||||||
#ifdef INTERLACED_COLS
|
#ifdef INTERLACED_COLS
|
||||||
static uint8_t interlace_table[16] = {
|
static uint8_t interlace_table[16] = {
|
||||||
0x00, 0x01, 0x04, 0x05, 0x10, 0x11, 0x14, 0x15, 0x40, 0x41, 0x44, 0x45, 0x50, 0x51, 0x54, 0x55
|
0x00, 0x01, 0x04, 0x05, 0x10, 0x11, 0x14, 0x15,
|
||||||
|
0x40, 0x41, 0x44, 0x45, 0x50, 0x51, 0x54, 0x55
|
||||||
};
|
};
|
||||||
//COLPORT1 = interlace_table[tmp&0x0f] | (interlace_table[tmp1&0x0f]<<1);
|
//COLPORT1 = interlace_table[tmp&0x0f] | (interlace_table[tmp1&0x0f]<<1);
|
||||||
tmp>>=4; tmp1>>=4;
|
tmp>>=4; tmp1>>=4;
|
||||||
|
@ -133,147 +133,142 @@ inline void rowshow(unsigned char row, unsigned char plane){
|
||||||
//COLPORT2 = tmp1;
|
//COLPORT2 = tmp1;
|
||||||
|
|
||||||
pd1165_write(row, tmp);
|
pd1165_write(row, tmp);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//Dieser Interrupt wird je nach Ebene mit 50kHz 31,25kHz oder 12,5kHz ausgeführt
|
|
||||||
SIGNAL(SIG_OUTPUT_COMPARE0)
|
// depending on the plane this interrupt gets triggered at 50 kHz, 31.25 kHz or
|
||||||
{
|
// 12.5 kHz
|
||||||
|
SIGNAL(SIG_OUTPUT_COMPARE0) {
|
||||||
static unsigned char plane = 0;
|
static unsigned char plane = 0;
|
||||||
unsigned char row = 0;
|
unsigned char row = 0;
|
||||||
|
|
||||||
//Watchdog zurücksetzen
|
// reset watchdog
|
||||||
wdt_reset();
|
wdt_reset();
|
||||||
|
|
||||||
//Tasten für joystick einlesen
|
// determine button status of the joystick
|
||||||
readButtons();
|
readButtons();
|
||||||
|
|
||||||
for(row=0; row < 8; row++){
|
for (row = 0; row < 8; row++) {
|
||||||
pd1165_write(row, pixmap[plane][row][0]);
|
pd1165_write(row, pixmap[plane][row][0]);
|
||||||
CTRLPORT &= ~((1<<BIT_CS3)|(1<<BIT_RW));
|
CTRLPORT &= ~((1 << BIT_CS3) | (1 << BIT_RW));
|
||||||
CTRLPORT |= ((1<<BIT_CS3));
|
CTRLPORT |= ((1 << BIT_CS3));
|
||||||
|
|
||||||
pd1165_write(row, pixmap[plane][row][1]);
|
pd1165_write(row, pixmap[plane][row][1]);
|
||||||
CTRLPORT &= ~((1<<BIT_CS2)|(1<<BIT_RW));
|
CTRLPORT &= ~((1 << BIT_CS2) | (1 << BIT_RW));
|
||||||
CTRLPORT |= ((1<<BIT_CS2));
|
CTRLPORT |= ((1 << BIT_CS2));
|
||||||
|
|
||||||
//pd1165_write(0, row, pixmap[plane][row][0]);
|
//pd1165_write(0, row, pixmap[plane][row][0]);
|
||||||
//pd1165_write(1, row, pixmap[plane][row][1]);
|
//pd1165_write(1, row, pixmap[plane][row][1]);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
for (row = 8; row < NUM_ROWS; row++) {
|
||||||
|
pd1165_write(row - 8, pixmap[plane][row][0]);
|
||||||
for(row=8; row < NUM_ROWS; row++){
|
CTRLPORT &= ~((1 << BIT_CS0) | (1 << BIT_RW));
|
||||||
pd1165_write(row-8, pixmap[plane][row][0]);
|
CTRLPORT |= ((1 << BIT_CS0));
|
||||||
CTRLPORT &= ~((1<<BIT_CS0)|(1<<BIT_RW));
|
|
||||||
CTRLPORT |= ((1<<BIT_CS0));
|
|
||||||
|
|
||||||
pd1165_write(row-8, pixmap[plane][row][1]);
|
pd1165_write(row - 8, pixmap[plane][row][1]);
|
||||||
CTRLPORT &= ~((1<<BIT_CS1)|(1<<BIT_RW));
|
CTRLPORT &= ~((1 << BIT_CS1) | (1 << BIT_RW));
|
||||||
CTRLPORT |= ((1<<BIT_CS1));
|
CTRLPORT |= ((1 << BIT_CS1));
|
||||||
}
|
}
|
||||||
|
|
||||||
//Je nachdem, welche der Ebenen wir Zeichnen, die Zeile verschieden lange Anzeigen
|
// depending on the currently drawn plane, display the row for a specific
|
||||||
switch (plane){
|
// amount of time
|
||||||
case 0:
|
switch (plane) {
|
||||||
OCR0 = 3;
|
case 0:
|
||||||
break;
|
OCR0 = 3;
|
||||||
case 1:
|
break;
|
||||||
OCR0 = 4;
|
case 1:
|
||||||
break;
|
OCR0 = 4;
|
||||||
case 2:
|
break;
|
||||||
OCR0 = 22;
|
case 2:
|
||||||
|
OCR0 = 22;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//increment both row and plane
|
||||||
//Zeile und Ebene inkrementieren
|
if (++plane == NUMPLANE) {
|
||||||
if(++plane==NUMPLANE){
|
plane = 0;
|
||||||
plane=0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void timer0_off(){
|
void timer0_off() {
|
||||||
cli();
|
cli();
|
||||||
|
|
||||||
|
|
||||||
TCCR0 = 0x00;
|
TCCR0 = 0x00;
|
||||||
sei();
|
sei();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Den Timer, der denn Interrupt auslöst, initialisieren
|
// initialize timer which triggers the interrupt
|
||||||
void timer0_on(){
|
void timer0_on() {
|
||||||
/* TCCR0: FOC0 WGM00 COM01 COM00 WGM01 CS02 CS01 CS00
|
/* TCCR0: FOC0 WGM00 COM01 COM00 WGM01 CS02 CS01 CS00
|
||||||
CS02 CS01 CS00
|
CS02 CS01 CS00
|
||||||
0 0 0 stop
|
0 0 0 stop
|
||||||
0 0 1 clk
|
0 0 1 clk
|
||||||
0 1 0 clk/8
|
0 1 0 clk/8
|
||||||
0 1 1 clk/64
|
0 1 1 clk/64
|
||||||
1 0 0 clk/256
|
1 0 0 clk/256
|
||||||
1 0 1 clk/1024
|
1 0 1 clk/1024
|
||||||
|
|
||||||
*/
|
*/
|
||||||
TCCR0 = 0x0D; // CTC Mode, clk/64
|
TCCR0 = 0x0D; // CTC Mode, clk/64
|
||||||
TCNT0 = 0; // reset timer
|
TCNT0 = 0; // reset timer
|
||||||
OCR0 = 20; // Compare with this value
|
OCR0 = 20; // compare with this value
|
||||||
TIMSK = 0x02; // Compare match Interrupt on
|
TIMSK = 0x02; // compare match Interrupt on
|
||||||
}
|
}
|
||||||
|
|
||||||
void timer2_on(){
|
|
||||||
/* TCCR2: FOC2 WGM20 COM21 COM20 WGM21 CS22 CS21 CS20
|
|
||||||
CS02 CS01 CS00
|
|
||||||
0 0 0 stop
|
|
||||||
0 0 1 clk
|
|
||||||
0 1 0 clk/8
|
|
||||||
0 1 1 clk/32
|
|
||||||
1 0 0 clk/64
|
|
||||||
1 0 1 clk/128
|
|
||||||
1 1 0 clk/256
|
|
||||||
1 1 1 clk/1024
|
|
||||||
|
|
||||||
|
|
||||||
Table 51. Compare Output Mode, non-PWM Mode
|
|
||||||
COM21 COM20 Description
|
|
||||||
0 0 Normal port operation, OC2 disconnected.
|
|
||||||
0 1 Toggle OC2 on compare match
|
|
||||||
1 0 Clear OC2 on compare match
|
|
||||||
1 1 Set OC2 on compare match
|
|
||||||
|
|
||||||
*/
|
|
||||||
TCCR2 = (1<<WGM21) | (1<<COM20) | 1 ; //CTC, OC2 toggle, clk/1
|
|
||||||
OCR2 = 92; //80kHz clock on OC2
|
|
||||||
|
|
||||||
|
void timer2_on() {
|
||||||
|
/* TCCR2: FOC2 WGM20 COM21 COM20 WGM21 CS22 CS21 CS20
|
||||||
|
CS02 CS01 CS00
|
||||||
|
0 0 0 stop
|
||||||
|
0 0 1 clk
|
||||||
|
0 1 0 clk/8
|
||||||
|
0 1 1 clk/32
|
||||||
|
1 0 0 clk/64
|
||||||
|
1 0 1 clk/128
|
||||||
|
1 1 0 clk/256
|
||||||
|
1 1 1 clk/1024
|
||||||
|
|
||||||
|
Table 51. Compare Output Mode, non-PWM Mode
|
||||||
|
COM21 COM20 Description
|
||||||
|
0 0 normal port operation, OC2 disconnected.
|
||||||
|
0 1 toggle OC2 on compare match
|
||||||
|
1 0 clear OC2 on compare match
|
||||||
|
1 1 set OC2 on compare match
|
||||||
|
*/
|
||||||
|
|
||||||
|
TCCR2 = (1 << WGM21) | (1 << COM20) | 1; //CTC, OC2 toggle, clk/1
|
||||||
|
OCR2 = 92; // 80kHz clock on OC2
|
||||||
}
|
}
|
||||||
|
|
||||||
void borg_hw_init(){
|
|
||||||
|
void borg_hw_init() {
|
||||||
CTRLDDR = (1<<BIT_CS0)|(1<<BIT_CS1)|(1<<BIT_CS2)|(1<<BIT_CS3)|(1<<BIT_RW);
|
CTRLDDR = (1<<BIT_CS0)|(1<<BIT_CS1)|(1<<BIT_CS2)|(1<<BIT_CS3)|(1<<BIT_RW);
|
||||||
CTRLPORT = (1<<BIT_CS0)|(1<<BIT_CS1)|(1<<BIT_CS2)|(1<<BIT_CS3)|(1<<BIT_RW);
|
CTRLPORT = (1<<BIT_CS0)|(1<<BIT_CS1)|(1<<BIT_CS2)|(1<<BIT_CS3)|(1<<BIT_RW);
|
||||||
DATADDR = 0xff;
|
DATADDR = 0xff;
|
||||||
ADDRDDR |= 0x0f;
|
ADDRDDR |= 0x0f;
|
||||||
CTRLPORT = (1<<BIT_CS0)|(1<<BIT_CS1)|(1<<BIT_CS2)|(1<<BIT_CS3)|(1<<BIT_RW);
|
CTRLPORT = (1<<BIT_CS0)|(1<<BIT_CS1)|(1<<BIT_CS2)|(1<<BIT_CS3)|(1<<BIT_RW);
|
||||||
|
|
||||||
|
pd1165_write(8, 0x10|7);
|
||||||
pd1165_write(8, 0x10 | 7);
|
|
||||||
|
|
||||||
CTRLPORT &= ~((1<<BIT_CS0)|(1<<BIT_CS1)|(1<<BIT_CS2)|(1<<BIT_CS3)|(1<<BIT_RW));
|
CTRLPORT &= ~((1<<BIT_CS0)|(1<<BIT_CS1)|(1<<BIT_CS2)|(1<<BIT_CS3)|(1<<BIT_RW));
|
||||||
|
|
||||||
CTRLPORT |= ((1<<BIT_CS0)|(1<<BIT_CS1)|(1<<BIT_CS2)|(1<<BIT_CS3));
|
CTRLPORT |= ((1<<BIT_CS0)|(1<<BIT_CS1)|(1<<BIT_CS2)|(1<<BIT_CS3));
|
||||||
|
|
||||||
|
|
||||||
timer0_on();
|
timer0_on();
|
||||||
timer2_on();
|
timer2_on();
|
||||||
|
|
||||||
DDRD |= 1<<PD7; //OC2 pin to output
|
DDRD |= 1 << PD7; // OC2 pin to output
|
||||||
|
|
||||||
RDIMPORT |= (1<<BIT_RDIM);
|
RDIMPORT |= (1 << BIT_RDIM);
|
||||||
RDIMDDR |= (1<<BIT_RDIM);
|
RDIMDDR |= (1 << BIT_RDIM);
|
||||||
|
|
||||||
//Watchdog Timer aktivieren
|
// activate watchdog timer
|
||||||
wdt_reset();
|
wdt_reset();
|
||||||
wdt_enable(0x00); // 17ms Watchdog
|
wdt_enable(0x00); // 17ms watchdog
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
#include "../config.h"
|
#include "../config.h"
|
||||||
#include "../makros.h"
|
#include "../makros.h"
|
||||||
|
|
||||||
|
@ -12,143 +11,127 @@
|
||||||
#define PIN_STR PB2
|
#define PIN_STR PB2
|
||||||
|
|
||||||
|
|
||||||
|
// buffer which holds the currently shown frame
|
||||||
//Der Puffer, in dem das aktuelle Bild gespeichert wird
|
|
||||||
unsigned char pixmap[NUMPLANE][NUM_ROWS][LINEBYTES];
|
unsigned char pixmap[NUMPLANE][NUM_ROWS][LINEBYTES];
|
||||||
|
|
||||||
|
|
||||||
//zur nächsten Zeile weiterschalten
|
// switch to next row
|
||||||
inline void nextrow(uint8_t row){
|
static void nextrow(uint8_t row) {
|
||||||
|
// clear states of the preceding row
|
||||||
//Die Zustände von der vorherigen Zeile löschen
|
|
||||||
PORTC &= 0xF0;
|
PORTC &= 0xF0;
|
||||||
PORTD &= 0x0F;
|
PORTD &= 0x0F;
|
||||||
PORTB &= 0xFC;
|
PORTB &= 0xFC;
|
||||||
|
|
||||||
//kurze Warteschleife, damit die Treiber auch wirklich ausschalten
|
// short delay loop, to ensure proper deactivation of the drivers
|
||||||
|
|
||||||
unsigned char i;
|
unsigned char i;
|
||||||
for(i=0;i<10;i++){
|
for (i = 0; i < 10; i++) {
|
||||||
asm volatile("nop");
|
asm volatile("nop");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (row == 0){
|
if (row == 0) {
|
||||||
//Zeile 0: Das erste Schieberegister initialisieren
|
// row 0: initialize first shift register
|
||||||
PORTB &= ~(1<<PIN_DATA); // zeile ist aktiv auf low
|
PORTB &= ~(1 << PIN_DATA); // row is active low
|
||||||
PORTB |= (1<<PIN_CLK);
|
PORTB |= (1 << PIN_CLK);
|
||||||
PORTB &= ~(1<<PIN_CLK);
|
PORTB &= ~(1 << PIN_CLK);
|
||||||
PORTB |= (1<<PIN_DATA);
|
PORTB |= (1 << PIN_DATA);
|
||||||
|
} else {
|
||||||
|
// remaining rows: just shift forward
|
||||||
|
PORTB |= (1 << PIN_CLK);
|
||||||
|
PORTB &= ~(1 << PIN_CLK);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
//In jeder anderen Zeile einfach nur einen weiter schieben
|
// another delay loop, to ensure that the drivers are ready
|
||||||
PORTB |= (1<<PIN_CLK);
|
for (i = 0; i < 20; i++) {
|
||||||
PORTB &= ~(1<<PIN_CLK);
|
|
||||||
}
|
|
||||||
|
|
||||||
//noch eine Warteschleife, damit die Zeilentreiber bereit sind
|
|
||||||
for(i=0;i<20;i++){
|
|
||||||
asm volatile("nop");
|
asm volatile("nop");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// display a row
|
||||||
|
static void rowshow(unsigned char row, unsigned char plane) {
|
||||||
|
// depending on the currently drawn plane, display the row for a specific
|
||||||
|
// amount of time
|
||||||
|
static unsigned char const tcnt0_table[] = {244, 236, 206};
|
||||||
|
TCNT0 = tcnt0_table[plane];
|
||||||
|
|
||||||
//Eine Zeile anzeigen
|
// output data of the current row to the column drivers
|
||||||
inline void rowshow(unsigned char row, unsigned char plane){
|
|
||||||
//Je nachdem, welche der Ebenen wir Zeichnen, die Zeile verschieden lange Anzeigen
|
|
||||||
switch (plane){
|
|
||||||
case 0:
|
|
||||||
TCNT0 = 0x100-12;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
TCNT0 = 0x100-20;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
TCNT0 = 0x100-50;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t tmp, tmp1;
|
uint8_t tmp, tmp1;
|
||||||
//die Daten für die aktuelle Zeile auf die Spaltentreiber ausgeben
|
tmp = pixmap[plane][row][0];
|
||||||
|
|
||||||
tmp = pixmap[plane][row][0];
|
|
||||||
tmp1 = pixmap[plane][row][1];
|
tmp1 = pixmap[plane][row][1];
|
||||||
|
|
||||||
PORTC = ( PORTC & 0xF0 ) | (tmp & 0x0F);
|
PORTC = (PORTC & 0xF0) | (tmp & 0x0F);
|
||||||
PORTD = ( PORTD & 0x0F ) | (tmp & 0xF0);
|
PORTD = (PORTD & 0x0F) | (tmp & 0xF0);
|
||||||
PORTB = ( PORTB & 0xFC ) | (tmp1 & 0x03);
|
PORTB = (PORTB & 0xFC) | (tmp1 & 0x03);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//Dieser Interrupt wird je nach Ebene mit 50kHz 31,25kHz oder 12,5kHz ausgeführt
|
// depending on the plane this interrupt gets triggered at 50 kHz, 31.25 kHz or
|
||||||
SIGNAL(SIG_OVERFLOW0)
|
// 12.5 kHz
|
||||||
{
|
SIGNAL(SIG_OVERFLOW0) {
|
||||||
static unsigned char plane = 0;
|
static unsigned char plane = 0;
|
||||||
static unsigned char row = 0;
|
static unsigned char row = 0;
|
||||||
|
|
||||||
//Watchdog zurücksetzen
|
// reset watchdog
|
||||||
wdt_reset();
|
wdt_reset();
|
||||||
|
|
||||||
//Zeile und Ebene inkrementieren
|
// increment both row and plane
|
||||||
if(++plane==NUMPLANE){
|
if (++plane == NUMPLANE) {
|
||||||
plane=0;
|
plane = 0;
|
||||||
if(++row == NUM_ROWS){
|
if (++row == NUM_ROWS) {
|
||||||
row = 0;
|
row = 0;
|
||||||
}
|
}
|
||||||
nextrow(row);
|
nextrow(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Die aktuelle Zeile in der aktuellen Ebene ausgeben
|
// output current row according to current plane
|
||||||
rowshow(row, plane);
|
rowshow(row, plane);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void timer0_off(){
|
void timer0_off() {
|
||||||
cli();
|
cli();
|
||||||
/*
|
/*
|
||||||
COLPORT1 = 0;
|
COLPORT1 = 0;
|
||||||
COLPORT2 = 0;
|
COLPORT2 = 0;
|
||||||
ROWPORT = 0;
|
ROWPORT = 0;
|
||||||
*/
|
*/
|
||||||
TCCR0 = 0x00;
|
TCCR0 = 0x00;
|
||||||
sei();
|
sei();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Den Timer, der denn Interrupt auslöst, initialisieren
|
// initialize timer which triggers the interrupt
|
||||||
void timer0_on(){
|
static void timer0_on() {
|
||||||
|
/* TCCR0: FOC0 WGM00 COM01 COM00 WGM01 CS02 CS01 CS00
|
||||||
/* TCCR0: FOC0 WGM00 COM01 COM00 WGM01 CS02 CS01 CS00
|
CS02 CS01 CS00
|
||||||
CS02 CS01 CS00
|
0 0 0 stop
|
||||||
0 0 0 stop
|
0 0 1 clk
|
||||||
0 0 1 clk
|
0 1 0 clk/8
|
||||||
0 1 0 clk/8
|
0 1 1 clk/64
|
||||||
0 1 1 clk/64
|
1 0 0 clk/256
|
||||||
1 0 0 clk/256
|
1 0 1 clk/1024
|
||||||
1 0 1 clk/1024
|
*/
|
||||||
|
TCCR0 = 0x03; // clk/64
|
||||||
*/
|
TCNT0 = 0xFF - 20; // reset timer
|
||||||
TCCR0 = 0x03; // clk/64
|
TIMSK |= (1 << TOIE0); // compare match Interrupt on
|
||||||
TCNT0 = 0xFF-20; // reset timer
|
|
||||||
TIMSK |= (1<<TOIE0); // Compare match Interrupt on
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void borg_hw_init(){
|
|
||||||
|
|
||||||
// Nötige Pins auf Ausgang
|
void borg_hw_init() {
|
||||||
DDRC=0x0F; // PC0-3 - Row 0-3
|
// set required pins to output mode
|
||||||
DDRD=0xF4; // PD4-7 - Row 4-7 PD2 - Masse für Joy
|
DDRC = 0x0F; // PC0-3 - Row 0-3
|
||||||
DDRB=0x1F; // PB0-1 - Row 8-9 PB2-3 - STR, CLK, d
|
DDRD = 0xF4; // PD4-7 - Row 4-7 PD2 - ground for joy
|
||||||
|
DDRB = 0x1F; // PB0-1 - Row 8-9 PB2-3 - STR, CLK, d
|
||||||
// Alle Spalten erstmal aus, clk aus, d und str an
|
|
||||||
// PC4-5, PD013 Pullup an
|
// turn off all columns for now, clk off, d and str on
|
||||||
PORTC=0x30;
|
// PC4-5, PD013 pullup on
|
||||||
PORTD=0x0B;
|
PORTC = 0x30;
|
||||||
PORTB=0x14;
|
PORTD = 0x0B;
|
||||||
|
PORTB = 0x14;
|
||||||
|
|
||||||
timer0_on();
|
timer0_on();
|
||||||
|
|
||||||
//Watchdog Timer aktivieren
|
// activate watchdog timer
|
||||||
wdt_reset();
|
wdt_reset();
|
||||||
wdt_enable(0x00); // 17ms Watchdog
|
wdt_enable(0x00); // 17ms watchdog
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
#include "../config.h"
|
#include "../config.h"
|
||||||
#include "../makros.h"
|
#include "../makros.h"
|
||||||
#include "../ioport.h"
|
#include "../ioport.h"
|
||||||
|
@ -9,29 +8,28 @@
|
||||||
#include "borg_hw.h"
|
#include "borg_hw.h"
|
||||||
|
|
||||||
|
|
||||||
|
// buffer which holds the currently shown frame
|
||||||
//Der Puffer, in dem das aktuelle Bild gespeichert wird
|
|
||||||
unsigned char pixmap[NUMPLANE][NUM_ROWS][LINEBYTES];
|
unsigned char pixmap[NUMPLANE][NUM_ROWS][LINEBYTES];
|
||||||
|
|
||||||
//Eine Zeile anzeigen
|
|
||||||
inline void rowshow(unsigned char row){
|
|
||||||
//die Daten für die aktuelle Zeile auf die Spaltentreiber ausgeben
|
|
||||||
|
|
||||||
COLPORT1 = pixmap[0][row][0];
|
// display a row
|
||||||
COLPORT2 = pixmap[0][row][1];
|
inline void rowshow(unsigned char row) {
|
||||||
|
// output data of the current row to the column drivers
|
||||||
|
COLPORT1 = pixmap[0][row][0];
|
||||||
|
COLPORT2 = pixmap[0][row][1];
|
||||||
|
|
||||||
OUTPUT_ON(LATCH_R);
|
OUTPUT_ON(LATCH_R);
|
||||||
OUTPUT_OFF(LATCH_R);
|
OUTPUT_OFF(LATCH_R);
|
||||||
|
|
||||||
COLPORT1 = pixmap[1][row][0];
|
COLPORT1 = pixmap[1][row][0];
|
||||||
COLPORT2 = pixmap[1][row][1];
|
COLPORT2 = pixmap[1][row][1];
|
||||||
|
|
||||||
OUTPUT_ON(LATCH_G);
|
OUTPUT_ON(LATCH_G);
|
||||||
OUTPUT_OFF(LATCH_G);
|
OUTPUT_OFF(LATCH_G);
|
||||||
|
|
||||||
COLPORT1 = pixmap[2][row][0];
|
COLPORT1 = pixmap[2][row][0];
|
||||||
COLPORT2 = pixmap[2][row][1];
|
COLPORT2 = pixmap[2][row][1];
|
||||||
|
|
||||||
OUTPUT_ON(LATCH_B);
|
OUTPUT_ON(LATCH_B);
|
||||||
OUTPUT_OFF(LATCH_B);
|
OUTPUT_OFF(LATCH_B);
|
||||||
}
|
}
|
||||||
|
@ -41,28 +39,29 @@ uint32_t mod = 1280000ul;
|
||||||
uint32_t akku;
|
uint32_t akku;
|
||||||
|
|
||||||
unsigned char row = 0;
|
unsigned char row = 0;
|
||||||
|
|
||||||
|
|
||||||
ISR(SIG_OUTPUT_COMPARE0)
|
ISR(SIG_OUTPUT_COMPARE0)
|
||||||
{
|
{
|
||||||
//Watchdog zurücksetzen
|
// reset watchdog
|
||||||
wdt_reset();
|
wdt_reset();
|
||||||
|
|
||||||
akku += mod;
|
akku += mod;
|
||||||
|
|
||||||
OCR1A = akku / 256;
|
OCR1A = akku / 256;
|
||||||
|
|
||||||
rowshow(row);
|
rowshow(row);
|
||||||
|
|
||||||
if(++row == NUM_ROWS){
|
if (++row == NUM_ROWS) {
|
||||||
row = NUM_ROWS - 1;
|
row = NUM_ROWS - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ISR(INT0_vect){
|
|
||||||
if(akku > (64ul * 256ul * 64ul)){
|
ISR(INT0_vect) {
|
||||||
|
if (akku > (64ul * 256ul * 64ul)) {
|
||||||
akku -= OCR1A - TCNT1;
|
akku -= OCR1A - TCNT1;
|
||||||
|
|
||||||
mod = akku / 64;
|
mod = akku / 64;
|
||||||
akku = 0;
|
akku = 0;
|
||||||
row = 0;
|
row = 0;
|
||||||
|
@ -72,32 +71,31 @@ ISR(INT0_vect){
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void timer0_off(){
|
void timer0_off() {
|
||||||
cli();
|
cli();
|
||||||
|
|
||||||
TCCR1B = 0x00;
|
TCCR1B = 0x00;
|
||||||
|
|
||||||
sei();
|
sei();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Den Timer, der denn Interrupt auslöst, initialisieren
|
// initialize timer which triggers the interrupt
|
||||||
void timer1_on(){
|
void timer1_on() {
|
||||||
TCCR1B = 1; //clk/1
|
TCCR1B = 1; // clk/1
|
||||||
TIMSK |= (1<<OCIE1A);
|
TIMSK |= (1 << OCIE1A);
|
||||||
}
|
}
|
||||||
|
|
||||||
void borg_hw_init(){
|
|
||||||
|
void borg_hw_init() {
|
||||||
DDR(COLPORT1) = 0xff;
|
DDR(COLPORT1) = 0xff;
|
||||||
DDR(COLPORT2) = 0xff;
|
DDR(COLPORT2) = 0xff;
|
||||||
|
|
||||||
SET_DDR(LATCH_R);
|
SET_DDR(LATCH_R);
|
||||||
SET_DDR(LATCH_G);
|
SET_DDR(LATCH_G);
|
||||||
SET_DDR(LATCH_B);
|
SET_DDR(LATCH_B);
|
||||||
|
|
||||||
timer1_on();
|
timer1_on();
|
||||||
|
|
||||||
//Watchdog Timer aktivieren
|
// activate watchdog timer
|
||||||
wdt_reset();
|
wdt_reset();
|
||||||
wdt_enable(0x00); // 17ms Watchdog
|
wdt_enable(0x00); // 17ms watchdog
|
||||||
}
|
}
|
||||||
|
|
|
@ -146,25 +146,13 @@ void tetris_std_removedLines(void *pVariantData,
|
||||||
tetris_standard_variant_t *pStdVariant =
|
tetris_standard_variant_t *pStdVariant =
|
||||||
(tetris_standard_variant_t *)pVariantData;
|
(tetris_standard_variant_t *)pVariantData;
|
||||||
uint8_t nLines = tetris_bucket_calculateLines(nRowMask);
|
uint8_t nLines = tetris_bucket_calculateLines(nRowMask);
|
||||||
|
assert(nLines <= 4);
|
||||||
pStdVariant->nLines += nLines;
|
pStdVariant->nLines += nLines;
|
||||||
pStdVariant->nLevel = ((pStdVariant->nLines / 10) < TETRIS_INPUT_LEVELS) ?
|
pStdVariant->nLevel = ((pStdVariant->nLines / 10) < TETRIS_INPUT_LEVELS) ?
|
||||||
(pStdVariant->nLines / 10) : (TETRIS_INPUT_LEVELS - 1);
|
(pStdVariant->nLines / 10) : (TETRIS_INPUT_LEVELS - 1);
|
||||||
|
|
||||||
switch (nLines)
|
static uint16_t const nScoreTable[] PROGMEM = {0, 50, 150, 250, 400};
|
||||||
{
|
pStdVariant->nScore += pgm_read_word(&nScoreTable[nLines]);
|
||||||
case 1:
|
|
||||||
pStdVariant->nScore += 50;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
pStdVariant->nScore += 150;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
pStdVariant->nScore += 250;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
pStdVariant->nScore += 400;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue