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:
Christian Kroll 2011-08-17 01:16:25 +00:00
parent 3e8768866c
commit d4ae78fee3
13 changed files with 784 additions and 876 deletions

View File

@ -128,31 +128,13 @@ static uint8_t amphibian_getChunk(unsigned char const nBitPlane,
{0x06, 0x30, 0xC6},
{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)
&& (((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]);
}
else

View File

@ -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) {
pf[y][x / 8] |= shl_table[x & 7];
} else {
@ -144,25 +144,23 @@ void nextiteration(field_t dest, field_t src) {
uint8_t tc;
for (y = YSIZE; y--;) {
for (x = XSIZE; x--;) {
cell_t cell;
tc = countsurroundingalive(src, x, y);
switch (tc) {
// case 0:
// case 1:
// /* dead */
// setcell(dest, x,y, dead);
case 2:
/* keep */
setcell(dest, x, y, getcell(src, x, y));
continue;
break;
case 3:
/* alive */
setcell(dest, x, y, alive);
cell = alive;
break;
default:
/* dead */
setcell(dest, x, y, dead);
cell = dead;
break;
}
setcell(dest, x, y, cell);
}
}
}

View File

@ -1,8 +1,7 @@
#ifndef BORG_HW_H
#define BORG_HW_H
//Linebytes gibt die Zahl der Bytes pro Zeile in der
//Pixmap an, also Spaltenzahl/8 aufgerundet
// LINEBYTES holds the amount of bytes per line within the framebuffer (pixmap)
#define LINEBYTES (((NUM_COLS-1)/8)+1)

View File

@ -1,4 +1,3 @@
#include "../config.h"
#include "../makros.h"
@ -8,25 +7,27 @@
#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
#define COLPORT1 PORTA
#define COLDDR1 DDRA
// 16 columns total directly controlled, therefore 2 ports
#define COLPORT1 PORTA
#define COLDDR1 DDRA
#define COLPORT2 PORTC
#define COLDDR2 DDRC
#define COLPORT2 PORTC
#define COLDDR2 DDRC
// Der andere Port übernimmt die Steuerung der Schieberegister
#define ROWPORT PORTD
#define ROWDDR DDRD
// Clock und reset gehen gemeinsam an beide Schieberegister
// der reset pin ist negiert
#define PIN_MCLR PD4
#define PIN_CLK PD5
//das dier sind die individuellen Dateneingänge für die Schieberegister
#define PIN_DATA1 PD6
#define PIN_DATA2 PD7
// the other port controls the shift registers
#define ROWPORT PORTD
#define ROWDDR DDRD
// both clock and reset are connected to each shift register
// reset pin is negated
#define PIN_MCLR PD4
#define PIN_CLK PD5
// these are the individual data input pins for the shift registers
#define PIN_DATA1 PD6
#define PIN_DATA2 PD7
*/
#define COLDDR1 DDR(COLPORT1)
@ -39,90 +40,80 @@
#define SIG_OUTPUT_COMPARE0 SIG_OUTPUT_COMPARE0A
#endif
//Der Puffer, in dem das aktuelle Bild gespeichert wird
// buffer which holds the currently shown frame
unsigned char pixmap[NUMPLANE][NUM_ROWS][LINEBYTES];
//Eine Zeile anzeigen
inline void rowshow(unsigned char row, unsigned char plane){
//Die Zustände von der vorherigen Zeile löschen
// display a row
static void rowshow(unsigned char row, unsigned char plane) {
//reset states of preceding row
COLPORT1 = 0;
COLPORT2 = 0;
//kurze Warteschleife, damit die Treiber auch wirklich ausschalten
// short delay loop, to ensure proper deactivation of the drivers
unsigned char i;
for(i=0;i<20;i++){
for (i = 0; i < 20; i++) {
asm volatile("nop");
}
if (row == 0){
//Zeile 0: Das erste Schieberegister initialisieren
ROWPORT&= ~(1<<PIN_MCLR);
ROWPORT|= (1<<PIN_MCLR);
ROWPORT|= (1<<PIN_DATA1);
ROWPORT|= (1<<PIN_CLK);
ROWPORT&= ~(1<<PIN_CLK);
ROWPORT&= ~(1<<PIN_DATA1);
//Je nachdem, welche der Ebenen wir Zeichnen, die Zeile verschieden lange Anzeigen
switch (plane){
case 0:
OCR0 = 5;
break;
case 1:
OCR0 = 8;
break;
case 2:
OCR0 = 20;
}
}else if(row == 8){
//Zeile 8: Das Zweite Schieberegister initialisieren
ROWPORT&= ~(1<<PIN_MCLR);
ROWPORT|= (1<<PIN_MCLR);
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);
if (row == 0) {
// row 0: initialize first shift register
ROWPORT &= ~(1 << PIN_MCLR);
ROWPORT |= (1 << PIN_MCLR);
ROWPORT |= (1 << PIN_DATA1);
ROWPORT |= (1 << PIN_CLK);
ROWPORT &= ~(1 << PIN_CLK);
ROWPORT &= ~(1 << PIN_DATA1);
// depending on the currently drawn plane, display the row for a
// specific amount of time
static unsigned char const ocr0_table[] = {5, 8, 20};
OCR0 = ocr0_table[plane];
} else if (row == 8) {
// row 8: initialize second shift register
ROWPORT &= ~(1 << PIN_MCLR);
ROWPORT |= (1 << PIN_MCLR);
ROWPORT |= (1 << PIN_DATA2);
ROWPORT |= (1 << PIN_CLK);
ROWPORT &= ~(1 << PIN_CLK);
ROWPORT &= ~(1 << PIN_DATA2);
} else {
// remaining rows: just shift forward
ROWPORT |= (1 << PIN_CLK);
ROWPORT &= ~(1 << PIN_CLK);
}
//ncoh eine Warteschleife, damit die Zeilentreiber bereit sind
for(i=0;i<20;i++){
// another delay loop, to ensure that the drivers are ready
for (i = 0; i < 20; i++) {
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];
COLPORT2 = pixmap[plane][row][1];
}
//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 row = 0;
//Watchdog zurücksetzen
// reset watchdog
wdt_reset();
//Die aktuelle Zeile in der aktuellen Ebene ausgeben
// output current row according to current plane
rowshow(row, plane);
//Zeile und Ebene inkrementieren
if(++row == NUM_ROWS){
// increment both row and plane
if (++row == NUM_ROWS) {
row = 0;
if(++plane==NUMPLANE) plane=0;
if (++plane == NUMPLANE) {
plane = 0;
}
}
}
void timer0_off(){
void timer0_off() {
cli();
COLPORT1 = 0;
@ -130,60 +121,58 @@ void timer0_off(){
ROWPORT = 0;
#ifdef __AVR_ATmega644P__
TCCR0A = 0x00;
TCCR0B = 0x00;
TCCR0A = 0x00;
TCCR0B = 0x00;
#else
TCCR0 = 0x00;
#endif
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
*/
// 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
*/
#ifdef __AVR_ATmega644P__
TCCR0A = 0x02; // CTC Mode
TCCR0B = 0x03; // clk/64
TCNT0 = 0; // reset timer
OCR0 = 20; // Compare with this value
TIMSK0 = 0x02; // Compare match Interrupt on
TCCR0A = 0x02; // CTC Mode
TCCR0B = 0x03; // clk/64
TCNT0 = 0; // reset timer
OCR0 = 20; // compare with this value
TIMSK0 = 0x02; // compare match Interrupt on
#else
TCCR0 = 0x0B; // CTC Mode, clk/64
TCNT0 = 0; // reset timer
OCR0 = 20; // Compare with this value
TIMSK = 0x02; // Compare match Interrupt on
TCCR0 = 0x0B; // CTC Mode, clk/64
TCNT0 = 0; // reset timer
OCR0 = 20; // compare with this value
TIMSK = 0x02; // compare match Interrupt on
#endif
}
void borg_hw_init(){
//Spalten Ports auf Ausgang
void borg_hw_init() {
// switch column ports to output mode
COLDDR1 = 0xFF;
COLDDR2 = 0xFF;
//Pins am Zeilenport auf Ausgang
ROWDDR = (1<<PIN_MCLR) | (1<<PIN_CLK) | (1<< PIN_DATA1) | (1<<PIN_DATA2);
//Alle Spalten erstmal aus
// switch pins of the row port to output mode
ROWDDR = (1<<PIN_MCLR) | (1<<PIN_CLK) | (1<<PIN_DATA1) | (1<<PIN_DATA2);
// switch off all columns for now
COLPORT1 = 0;
COLPORT2 = 0;
//Schieberegister für Zeilen zurücksetzen
// reset shift registers for the rows
ROWPORT = 0;
timer0_on();
//Watchdog Timer aktivieren
// activate watchdog timer
wdt_reset();
wdt_enable(0x00); // 17ms Watchdog
wdt_enable(0x00); // 17ms watchdog
}

View File

@ -1,4 +1,3 @@
#include "../config.h"
#include "../makros.h"
@ -8,24 +7,26 @@
#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
#define COLPORT1 PORTC
#define COLDDR1 DDRC
// 16 columns total directly controlled, therefore 2 ports
#define COLPORT1 PORTC
#define COLDDR1 DDRC
#define COLPORT2 PORTA
#define COLDDR2 DDRA
#define COLPORT2 PORTA
#define COLDDR2 DDRA
// Der andere Port übernimmt die Steuerung der Schieberegister
#define ROWPORT PORTD
#define ROWDDR DDRD
// Clock und reset gehen gemeinsam an beide Schieberegister
// der reset pin ist negiert
#define PIN_MCLR PD4
#define PIN_CLK PD6
//das dier sind die individuellen Dateneingänge für die Schieberegister
#define PIN_DATA PD7
// the other port controls the shift registers
#define ROWPORT PORTD
#define ROWDDR DDRD
// both clock and reset are connected to each shift register
// reset pin is negated
#define PIN_MCLR PD4
#define PIN_CLK PD6
// these are the individual data input pins for the shift registers
#define PIN_DATA PD7
*/
#define COLDDR1 DDR(COLPORT1)
@ -38,33 +39,30 @@
#define SIG_OUTPUT_COMPARE0 SIG_OUTPUT_COMPARE0A
#endif
//Der Puffer, in dem das aktuelle Bild gespeichert wird
// buffer which holds the currently shown frame
unsigned char pixmap[NUMPLANE][NUM_ROWS][LINEBYTES];
//zur nächsten Zeile weiterschalten
inline void nextrow(uint8_t row){
//Die Zustände von der vorherigen Zeile löschen
// switch to next row
static void nextrow(uint8_t row) {
//reset states of preceding row
COLPORT1 = 0;
COLPORT2 = 0;
//kurze Warteschleife, damit die Treiber auch wirklich ausschalten
// short delay loop, to ensure proper deactivation of the drivers
unsigned char i;
for(i=0;i<10;i++){
for (i = 0; i < 10; i++) {
asm volatile("nop");
}
if (row == 0){
//Zeile 0: Das erste Schieberegister initialisieren
if (row == 0) {
// row 0: initialize first shift register
#ifndef INVERT_ROWS
ROWPORT&= ~(1<<PIN_MCLR);
ROWPORT|= (1<<PIN_MCLR);
ROWPORT|= (1<<PIN_DATA);
ROWPORT|= (1<<PIN_CLK);
ROWPORT&= ~(1<<PIN_CLK);
ROWPORT&= ~(1<<PIN_DATA);
ROWPORT &= ~(1 << PIN_MCLR);
ROWPORT |= (1 << PIN_MCLR);
ROWPORT |= (1 << PIN_DATA);
ROWPORT |= (1 << PIN_CLK);
ROWPORT &= ~(1 << PIN_CLK);
ROWPORT &= ~(1 << PIN_DATA);
#else
ROWPORT&= ~(1<<PIN_DATA);
ROWPORT|= (1<<PIN_CLK);
@ -72,43 +70,33 @@ inline void nextrow(uint8_t row){
ROWPORT|= (1<<PIN_DATA);
#endif
}else{
//In jeder anderen Zeile einfach nur einen weiter schieben
ROWPORT|= (1<<PIN_CLK);
ROWPORT&= ~(1<<PIN_CLK);
} else {
// remaining rows: just shift forward
ROWPORT |= (1 << PIN_CLK);
ROWPORT &= ~(1 << PIN_CLK);
}
//noch eine Warteschleife, damit die Zeilentreiber bereit sind
for(i=0;i<20;i++){
// another delay loop, to ensure that the drivers are ready
for (i = 0; i < 20; i++) {
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];
//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;
}
// output data of the current row to the column drivers
uint8_t tmp, tmp1;
//die Daten für die aktuelle Zeile auf die Spaltentreiber ausgeben
#ifndef INTERLACED_ROWS
tmp = pixmap[plane][row][0];
tmp = pixmap[plane][row][0];
tmp1 = pixmap[plane][row][1];
#else
row = (row>>1) + ((row & 0x01)?8:0 );
tmp = pixmap[plane][row][0];
tmp = pixmap[plane][row][0];
tmp1 = pixmap[plane][row][1];
#endif
#ifdef REVERSE_COLS
@ -124,44 +112,43 @@ inline void rowshow(unsigned char row, unsigned char plane){
#else
#ifdef INTERLACED_COLS
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;
COLPORT2 = interlace_table[tmp] | (interlace_table[tmp1]<<1);
COLPORT2 = interlace_table[tmp] | (interlace_table[tmp1]<<1);
#else
COLPORT1 = tmp;
COLPORT2 = tmp1;
#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 triggers at 50 kHz, 31.25 kHz or
// 12.5 kHz
SIGNAL(SIG_OUTPUT_COMPARE0) {
static unsigned char plane = 0;
static unsigned char row = 0;
//Watchdog zurücksetzen
// reset watchdog
wdt_reset();
//Zeile und Ebene inkrementieren
if(++plane==NUMPLANE){
plane=0;
if(++row == NUM_ROWS){
// increment both row and plane
if (++plane == NUMPLANE) {
plane = 0;
if (++row == NUM_ROWS) {
row = 0;
}
nextrow(row);
}
//Die aktuelle Zeile in der aktuellen Ebene ausgeben
// output current row according to current plane
rowshow(row, plane);
}
void timer0_off(){
void timer0_off() {
cli();
COLPORT1 = 0;
@ -169,60 +156,59 @@ void timer0_off(){
ROWPORT = 0;
#ifdef __AVR_ATmega644P__
TCCR0A = 0x00;
TCCR0B = 0x00;
TCCR0A = 0x00;
TCCR0B = 0x00;
#else
TCCR0 = 0x00;
#endif
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__
TCCR0A = 0x02; // CTC Mode
TCCR0B = 0x04; // clk/256
TCNT0 = 0; // reset timer
OCR0 = 20; // Compare with this value
TIMSK0 = 0x02; // Compare match Interrupt on
TCCR0A = 0x02; // CTC Mode
TCCR0B = 0x04; // clk/256
TCNT0 = 0; // reset timer
OCR0 = 20; // compare with this value
TIMSK0 = 0x02; // compare match Interrupt on
#else
TCCR0 = 0x0C; // CTC Mode, clk/256
TCNT0 = 0; // reset timer
OCR0 = 20; // Compare with this value
TIMSK = 0x02; // Compare match Interrupt on
TCCR0 = 0x0C; // CTC Mode, clk/256
TCNT0 = 0; // reset timer
OCR0 = 20; // compare with this value
TIMSK = 0x02; // compare match Interrupt on
#endif
}
void borg_hw_init(){
//Spalten Ports auf Ausgang
void borg_hw_init() {
// switch column ports to output mode
COLDDR1 = 0xFF;
COLDDR2 = 0xFF;
//Pins am Zeilenport auf Ausgang
ROWDDR = (1<<PIN_MCLR) | (1<<PIN_CLK) | (1<< PIN_DATA);
//Alle Spalten erstmal aus
// switch pins of the row port to output mode
ROWDDR = (1 << PIN_MCLR) | (1 << PIN_CLK) | (1 << PIN_DATA);
// switch off all columns for now
COLPORT1 = 0;
COLPORT2 = 0;
//Schieberegister für Zeilen zurücksetzen
// reset shift registers for the rows
ROWPORT = 0;
timer0_on();
//Watchdog Timer aktivieren
// activate watchdog timer
wdt_reset();
wdt_enable(0x00); // 17ms Watchdog
wdt_enable(0x00); // 17ms watchdog
}

View File

@ -1,4 +1,3 @@
#include "../config.h"
#include "../makros.h"
@ -8,119 +7,123 @@
#include "borg_hw.h"
/*
// Diese #defines werden nun durch menuconfig gesetzt
// those macros get defined via menuconfig, now
#define ROWPORT PORTB
#define ROWDDR DDRB
#define ROWPORT PORTB
#define ROWDDR DDRB
#define COLPORT PORTD
#define COLDDR DDRD
#define COLPORT PORTD
#define COLDDR DDRD
#define PIN_DATA PC4
#define PIN_CLK PC6 //active low
#define PIN_LINE_EN PC5 //active low
#define PIN_DATA PC4
#define PIN_CLK PC6 //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];
inline void rowshow(unsigned char row, unsigned char plane){
COLPORT |= (1<<PIN_LINE_EN);//blank display
inline void rowshow(unsigned char row, unsigned char plane) {
COLPORT |= (1 << PIN_LINE_EN); //blank display
ROWPORT = (ROWPORT & 0xF8) | row;
unsigned char b, d, x;
for(b=0;b<LINEBYTES;b++){
for (b = 0; b < LINEBYTES; b++) {
d = pixmap[plane][row][b];
for(x=0;x<8;x++){
if(d & 0x01){
COLPORT |= (1<<PIN_DATA);
}else{
COLPORT &= ~(1<<PIN_DATA);
for (x = 0; x < 8; x++) {
if (d & 0x01) {
COLPORT |= (1 << PIN_DATA);
} else {
COLPORT &= ~(1 << PIN_DATA);
}
d>>=1;
COLPORT &= ~(1<<PIN_CLK);
COLPORT |= (1<<PIN_CLK);
d >>= 1;
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 row = 0;
if (row == 0){
switch (plane){
case 0:
OCR0 = 7;
break;
case 1:
OCR0 = 20;
break;
case 2:
OCR0 = 40;
if (row == 0) {
switch (plane) {
case 0:
OCR0 = 7;
break;
case 1:
OCR0 = 20;
break;
case 2:
OCR0 = 40;
}
}
rowshow(row, plane);
if(++row == NUM_ROWS){
if (++row == NUM_ROWS) {
row = 0;
if(++plane==NUMPLANE) plane=0;
if (++plane == NUMPLANE)
plane = 0;
}
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
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 = 0x08 |0x04; // CTC Mode, clk/256
TCNT0 = 0; // reset timer
OCR0 = 0x30; // Compare with this value
TIMSK = 0x02; // Compare match Interrupt on
*/
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();
COLPORT |= (1<<PIN_LINE_EN);//blank display
COLPORT |= (1 << PIN_LINE_EN); //blank display
TCCR0 = 0x00;
sei();
}
void watchdog_enable()
{
void watchdog_enable() {
wdt_reset();
wdt_enable(0x00); // 17ms
wdt_enable(0x00); // 17ms
}
void borg_hw_init(){
COLPORT |= (1<<PIN_CLK) | (1<<PIN_LINE_EN);
COLDDR |= (1<<PIN_CLK) | (1<<PIN_LINE_EN) | (1<<PIN_DATA);
void borg_hw_init() {
COLPORT |= (1 << PIN_CLK) | (1 << PIN_LINE_EN);
COLDDR |= (1 << PIN_CLK) | (1 << PIN_LINE_EN) | (1 << PIN_DATA);
ROWDDR |= 0x07;
watchdog_enable();
timer0_on();
}

View File

@ -1,4 +1,3 @@
#include "../config.h"
#include "../makros.h"
@ -8,7 +7,6 @@
#include "borg_hw.h"
#define ROWPORT PORTC
#define ROWDDR DDRC
@ -26,125 +24,113 @@
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;
// 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 ;
clkmsk = 0x80 >> row;
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);
}
}
}
MYPORT |= (1 << PIN_ENABLE) ; //
//MYPORT &= ~(1 << PIN_ENABLE) ;
// for(n=0;n<250;n++) asm ("nop");
MYPORT2 &= ~clkmsk;
MYPORT2 |= clkmsk;
p >>= 1;
}
}
}
MYPORT |= (1 << PIN_ENABLE);
//MYPORT &= ~(1 << PIN_ENABLE) ;
// for(n=0;n<250;n++) asm ("nop");
}
SIGNAL(SIG_OUTPUT_COMPARE0)
{
static unsigned char plane = 0;
unsigned char row = 0;
SIGNAL( SIG_OUTPUT_COMPARE0) {
static unsigned char plane = 0;
unsigned char row = 0;
switch (plane){
case 0:
OCR0 = 60;
break;
case 1:
OCR0 = 120;
break;
case 2:
OCR0 = 160;
break;
// case 3:
// OCR0 = 24;
// break;
// case 4:
// OCR0 = 48;
// break;
}
for(row=0;row<NUM_ROWS;row++){
rowshow(row, plane);
}
if(++plane==NUMPLANE) plane=0;
wdt_reset();
switch (plane) {
case 0:
OCR0 = 60;
break;
case 1:
OCR0 = 120;
break;
case 2:
OCR0 = 160;
break;
// case 3:
// OCR0 = 24;
// break;
// case 4:
// OCR0 = 48;
// break;
}
for (row = 0; row < NUM_ROWS; row++) {
rowshow(row, plane);
}
if (++plane == NUMPLANE)
plane = 0;
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
*/
TCCR0 = 0x08 |0x04; // CTC Mode, clk/256 MH: slower 5 statt 4
TCNT0 = 0; // reset timer
OCR0 = 0x30; // Compare with this value 0x30
TIMSK = 0x02; // Compare match Interrupt on
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 = 0x08 | 0x04; // CTC Mode, clk/256 MH: slower 5 instead of 4
TCNT0 = 0; // reset timer
OCR0 = 0x30; // compare with this value 0x30
TIMSK = 0x02; // compare match Interrupt on
}
void timer0_off(){
cli();
MYPORT &= ~(1 << PIN_ENABLE) ;
//MYPORT |= (1 << PIN_ENABLE) ; //hide
//COLPORT |= (1<<PIN_LINE_EN);//blank display
// PORTD |= 0x01;//blank display
TCCR0 = 0x00;
sei();
void timer0_off() {
cli();
MYPORT &= ~(1 << PIN_ENABLE);
// MYPORT |= (1 << PIN_ENABLE); // hide
// COLPORT |= (1<<PIN_LINE_EN); // blank display
// PORTD |= 0x01; // blank display
TCCR0 = 0x00;
sei();
}
void watchdog_enable()
{
wdt_reset();
wdt_enable(0x00); // 17ms
void watchdog_enable() {
wdt_reset();
wdt_enable(0x00); // 17ms
}
void borg_hw_init(){
void borg_hw_init() {
//COLPORT |= (1<<PIN_CLK) | (1<<PIN_LINE_EN);
//COLDDR |= (1<<PIN_CLK) | (1<<PIN_LINE_EN) | (1<<PIN_DATA);
//ROWDDR |= 0x07;
DDRA = 0xFF;
DDRC = 0xFF;
watchdog_enable();
timer0_on();
DDRA = 0xFF;
DDRC = 0xFF;
watchdog_enable();
timer0_on();
}

View File

@ -1,4 +1,3 @@
#include "../config.h"
#include "../makros.h"
@ -8,24 +7,26 @@
#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
#define COLPORT1 PORTC
#define COLDDR1 DDRC
// 16 columns total directly controlled, therefore 2 ports
#define COLPORT1 PORTC
#define COLDDR1 DDRC
#define COLPORT2 PORTA
#define COLDDR2 DDRA
#define COLPORT2 PORTA
#define COLDDR2 DDRA
// Der andere Port übernimmt die Steuerung der Schieberegister
#define ROWPORT PORTD
#define ROWDDR DDRD
// Clock und reset gehen gemeinsam an beide Schieberegister
// der reset pin ist negiert
#define PIN_MCLR PD4
#define PIN_CLK PD6
//das dier sind die individuellen Dateneingänge für die Schieberegister
#define PIN_DATA PD7
// the other port controls the shift registers
#define ROWPORT PORTD
#define ROWDDR DDRD
// both clock and reset are connected to each shift register
// reset pin is negated
#define PIN_MCLR PD4
#define PIN_CLK PD6
// these are the individual data input pins for the shift registers
#define PIN_DATA PD7
*/
#define COLDDR1 DDR(COLPORT1)
@ -39,23 +40,22 @@
#endif
//Der Puffer, in dem das aktuelle Bild gespeichert wird
// buffer which holds the currently shown frame
unsigned char pixmap[NUMPLANE][NUM_ROWS][LINEBYTES];
//Dieser Interrupt wird je nach Ebene mit 50kHz 31,25kHz oder 12,5kHz ausgeführt
SIGNAL(SIG_OUTPUT_COMPARE0)
{
//Watchdog zurücksetzen
// depending on the plane this interrupt gets triggered at 50 kHz, 31.25 kHz or
// 12.5 kHz
SIGNAL( SIG_OUTPUT_COMPARE0) {
// reset watchdog
wdt_reset();
COLPORT1 = (pixmap[0][0][0] & 0x0f) | (pixmap[0][1][0] << 4);
COLPORT2 = (pixmap[0][2][0] & 0x0f) | (pixmap[0][3][0] << 4);
}
void timer0_off(){
void timer0_off() {
cli();
COLPORT1 = 0;
@ -63,69 +63,67 @@ void timer0_off(){
ROWPORT = 0;
#ifdef __AVR_ATmega644P__
TCCR0A = 0x00;
TCCR0B = 0x00;
TCCR0A = 0x00;
TCCR0B = 0x00;
#else
TCCR0 = 0x00;
#endif
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
*/
// initialize timer which triggers the interrupt
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__
TCCR0A = 0x02; // CTC Mode
TCCR0B = 0x04; // clk/256
TCNT0 = 0; // reset timer
OCR0 = 20; // Compare with this value
TIMSK0 = 0x02; // Compare match Interrupt on
TCCR0A = 0x02; // CTC Mode
TCCR0B = 0x04; // clk/256
TCNT0 = 0; // reset timer
OCR0 = 20; // compare with this value
TIMSK0 = 0x02; // compare match Interrupt on
#else
TCCR0 = 0x0C; // CTC Mode, clk/256
TCNT0 = 0; // reset timer
OCR0 = 20; // Compare with this value
TIMSK = 0x02; // Compare match Interrupt on
TCCR0 = 0x0C; // CTC Mode, clk/256
TCNT0 = 0; // reset timer
OCR0 = 20; // compare with this value
TIMSK = 0x02; // compare match Interrupt on
#endif
}
void borg_hw_init(){
//Spalten Ports auf Ausgang
void borg_hw_init() {
// switch column ports to output mode
COLDDR1 = 0xFF;
COLDDR2 = 0xFF;
//Pins am Zeilenport auf Ausgang
ROWDDR = (1<<PIN_MCLR) | (1<<PIN_CLK) | (1<< PIN_DATA);
//Alle Spalten erstmal aus
// switch pins of the row port to output mode
ROWDDR = (1 << PIN_MCLR) | (1 << PIN_CLK) | (1 << PIN_DATA);
// switch off all columns for now
COLPORT1 = 0;
COLPORT2 = 0;
//Schieberegister für Zeilen zurücksetzen
// reset shift registers for the rows
ROWPORT = 0;
//Alle Zeilen ausgänge an bei gigaborg
ROWPORT |= (1<<PIN_DATA) | (1<<PIN_MCLR);
// switch on all row output ports of the gigaborg
ROWPORT |= (1 << PIN_DATA) | (1 << PIN_MCLR);
uint8_t x;
for(x=0;x<16;x++){
ROWPORT|= (1<<PIN_CLK);
ROWPORT&= ~(1<<PIN_CLK);
for (x = 0; x < 16; x++) {
ROWPORT |= (1 << PIN_CLK);
ROWPORT &= ~(1 << PIN_CLK);
}
timer0_on();
//Watchdog Timer aktivieren
// activate watchdog timer
wdt_reset();
wdt_enable(0x00); // 17ms Watchdog
wdt_enable(0x00); // 17ms watchdog
}

View File

@ -1,15 +1,15 @@
#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)
/* pinout of the ribbon cable connected to the panel
* (the numbering is actually upside down)
*
* 1-3 GND
* 4 +5V für Logic
* 4 +5V for logic
* 5-8 +12V
* 9-10 GND
* 11 CP3
@ -21,7 +21,7 @@
* 17-18 GND
* 19-26 D0-D7
*
* Und nochmal richtigrum:
* and now the right way round:
* 1 D7
* 2 D6
* 3 D5
@ -49,22 +49,20 @@
* 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.
* Four 40374 latches are used. No. 1, 2 and 4 drive from the data bus to the
* panel, no. 3 drives from the button outputs to the data bus. The EOs of
* 1, 2 and 4 are hardwired to 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.
* The LEDs are aligned to a 12*16 matrix. The values for the LED columns are
* passed to the latches via CP1 und CP2 (16 columns total). The index of the
* row is passed during the deletion of "/show".
*
* 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.
*
* The buttons are aligned to an 8*8 matrix. The rows get separately set to
* "high" via latch 4. The columns can then be read via latch 3.
*/
//Datenport für das Panel
// data port for the panel
#define COLPORT PORTC
#define COLDDR DDRC
#define COLPIN PINC
@ -72,7 +70,7 @@
#define CTRLPORT PORTD
#define CTRLDDR DDRD
// PINs on CTRLPORT
// pins on CTRLPORT
#define PIN_EO3 PD7
#define PIN_CP4 PD2
#define PIN_SHOW PD3
@ -80,84 +78,88 @@
#define PIN_CP2 PD5
#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];
volatile uint8_t keys[8];
inline void busywait() {
//unsigned char i;
//for(i=0;i<20;i++){
//for(i=0; i < 20; i++){
// asm volatile("nop");
//}
}
//Eine Zeile anzeigen
// display a row
inline void rowshow(unsigned char row, unsigned char plane){
CTRLPORT |= (1<<PIN_SHOW);//blank
COLPORT = pixmap[plane][row][0];
CTRLPORT |= (1 << PIN_SHOW); //blank
COLPORT = pixmap[plane][row][0];
busywait();
CTRLPORT |= (1<<PIN_CP1);
CTRLPORT |= (1 << PIN_CP1);
busywait();
CTRLPORT &= ~(1<<PIN_CP1);
CTRLPORT &= ~(1 << PIN_CP1);
busywait();
COLPORT = pixmap[plane][row][1];
COLPORT = pixmap[plane][row][1];
busywait();
CTRLPORT |= (1<<PIN_CP2);
CTRLPORT |= (1 << PIN_CP2);
busywait();
CTRLPORT &= ~(1<<PIN_CP2);
CTRLPORT &= ~(1 << PIN_CP2);
busywait();
COLPORT = row;
COLPORT = row;
busywait();
CTRLPORT &= ~(1<<PIN_SHOW);
CTRLPORT &= ~(1 << PIN_SHOW);
}
inline void checkkeys(uint8_t row){
static uint8_t mask;
if(row == 0){
if (row == 0) {
mask = 1;
}else{
} else {
//read keyboard cols into latch
COLDDR = 0;
CTRLPORT &= ~(1<<PIN_EO3);
CTRLPORT |= (1<<PIN_CP3);
CTRLPORT &= ~(1 << PIN_EO3);
CTRLPORT |= (1 << PIN_CP3);
busywait();
CTRLPORT &= ~(1<<PIN_CP3);
CTRLPORT &= ~(1 << PIN_CP3);
busywait();
keys[row-1] = COLPIN;
CTRLPORT |= (1<<PIN_EO3);
keys[row - 1] = COLPIN;
CTRLPORT |= (1 << PIN_EO3);
busywait();
COLDDR = 0xFF;
}
COLPORT = mask;
COLPORT = mask;
mask <<= 1;
busywait();
CTRLPORT |= (1<<PIN_CP4);
CTRLPORT |= (1 << PIN_CP4);
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)
{
static unsigned char plane = 0;
static unsigned char row = 0;
//Watchdog zurücksetzen
// reset watchdog
wdt_reset();
//Die aktuelle Zeile in der aktuellen Ebene ausgeben
// output current row according to current plane
rowshow(row, plane);
if( (plane == 2) && (row<9) ) checkkeys(row);
//Zeile und Ebene inkrementieren
// increment both row and plane
if(++row == NUM_ROWS){
row = 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(){
/* 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
/* 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;
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);
// switch off all columns for now
// switch column ports to output mode
COLDDR = 0xFF;
COLPORT = 0x00;
timer0_on();
//Watchdog Timer aktivieren
// activate watchdog timer
wdt_reset();
wdt_enable(0x00); // 17ms Watchdog
wdt_enable(0x00); // 17ms watchdog
}

View File

@ -1,4 +1,3 @@
#include "../config.h"
#include "../makros.h"
@ -8,30 +7,31 @@
#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
#define COLPORT1 PORTC
#define COLDDR1 DDRC
// 16 columns total directly controlled, therefore 2 ports
#define COLPORT1 PORTC
#define COLDDR1 DDRC
#define COLPORT2 PORTA
#define COLDDR2 DDRA
#define COLPORT2 PORTA
#define COLDDR2 DDRA
// Der andere Port übernimmt die Steuerung der Schieberegister
#define ROWPORT PORTD
#define ROWDDR DDRD
// Clock und reset gehen gemeinsam an beide Schieberegister
// der reset pin ist negiert
#define PIN_MCLR PD4
#define PIN_CLK PD6
//das dier sind die individuellen Dateneingänge für die Schieberegister
#define PIN_DATA PD7
*/
// the other port controls the shift registers
#define ROWPORT PORTD
#define ROWDDR DDRD
// both clock and reset are connected to each shift register
// reset pin is negated
#define PIN_MCLR PD4
#define PIN_CLK PD6
// these are the individual data input pins for the shift registers
#define PIN_DATA PD7
*/
//#define COLDDR1 DDR(COLPORT1)
//#define COLDDR2 DDR(COLPORT2)
//#define ROWDDR DDR(ROWPORT)
//#define DATAPORT PORTC
#define DATADDR DDR(DATAPORT)
@ -50,64 +50,63 @@
//#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];
inline void pd1165_write(uint8_t addr, uint8_t data){
inline void pd1165_write(uint8_t addr, uint8_t data) {
ADDRPORT = (ADDRPORT & 0xf0) | addr;
DATAPORT = data;
/*
switch (display){
case 0:
CTRLPORT &= ~((1<<BIT_CS0)|(1<<BIT_RW));
CTRLPORT |= ((1<<BIT_CS0));
break;
case 1:
CTRLPORT &= ~((1<<BIT_CS1)|(1<<BIT_RW));
CTRLPORT |= ((1<<BIT_CS1));
break;
case 2:
CTRLPORT &= ~((1<<BIT_CS2)|(1<<BIT_RW));
CTRLPORT |= ((1<<BIT_CS2));
break;
case 3:
CTRLPORT &= ~((1<<BIT_CS3)|(1<<BIT_RW));
CTRLPORT |= ((1<<BIT_CS3));
break;
switch (display) {
case 0:
CTRLPORT &= ~((1 << BIT_CS0) | (1 << BIT_RW));
CTRLPORT |= ((1 << BIT_CS0));
break;
case 1:
CTRLPORT &= ~((1 << BIT_CS1) | (1 << BIT_RW));
CTRLPORT |= ((1 << BIT_CS1));
break;
case 2:
CTRLPORT &= ~((1 << BIT_CS2) | (1 << BIT_RW));
CTRLPORT |= ((1 << BIT_CS2));
break;
case 3:
CTRLPORT &= ~((1 << BIT_CS3) | (1 << BIT_RW));
CTRLPORT |= ((1 << BIT_CS3));
break;
}
*/
}
/*
//Eine Zeile anzeigen
inline void rowshow(unsigned char row, unsigned char plane){
// display a row
inline void rowshow(unsigned char row, unsigned char plane) {
int addr = row;
//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;
// depending on the currently drawn plane, display the row for a specific
// amount of time
switch (plane) {
case 0:
OCR0 = 3;
break;
case 1:
OCR0 = 4;
break;
case 2:
OCR0 = 22;
}
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
tmp = pixmap[plane][row][0];
tmp = pixmap[plane][row][0];
tmp1 = pixmap[plane][row][1];
#else
row = (row>>1) + ((row & 0x01)?8:0 );
tmp = pixmap[plane][row][0];
tmp = pixmap[plane][row][0];
tmp1 = pixmap[plane][row][1];
#endif
#ifdef REVERSE_COLS
@ -123,7 +122,8 @@ inline void rowshow(unsigned char row, unsigned char plane){
#else
#ifdef INTERLACED_COLS
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);
tmp>>=4; tmp1>>=4;
@ -133,147 +133,142 @@ inline void rowshow(unsigned char row, unsigned char plane){
//COLPORT2 = tmp1;
pd1165_write(row, tmp);
#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;
unsigned char row = 0;
//Watchdog zurücksetzen
// reset watchdog
wdt_reset();
//Tasten für joystick einlesen
// determine button status of the joystick
readButtons();
for(row=0; row < 8; row++){
for (row = 0; row < 8; row++) {
pd1165_write(row, pixmap[plane][row][0]);
CTRLPORT &= ~((1<<BIT_CS3)|(1<<BIT_RW));
CTRLPORT |= ((1<<BIT_CS3));
CTRLPORT &= ~((1 << BIT_CS3) | (1 << BIT_RW));
CTRLPORT |= ((1 << BIT_CS3));
pd1165_write(row, pixmap[plane][row][1]);
CTRLPORT &= ~((1<<BIT_CS2)|(1<<BIT_RW));
CTRLPORT |= ((1<<BIT_CS2));
CTRLPORT &= ~((1 << BIT_CS2) | (1 << BIT_RW));
CTRLPORT |= ((1 << BIT_CS2));
//pd1165_write(0, row, pixmap[plane][row][0]);
//pd1165_write(1, row, pixmap[plane][row][1]);
}
}
for(row=8; row < NUM_ROWS; row++){
pd1165_write(row-8, pixmap[plane][row][0]);
CTRLPORT &= ~((1<<BIT_CS0)|(1<<BIT_RW));
CTRLPORT |= ((1<<BIT_CS0));
for (row = 8; row < NUM_ROWS; row++) {
pd1165_write(row - 8, pixmap[plane][row][0]);
CTRLPORT &= ~((1 << BIT_CS0) | (1 << BIT_RW));
CTRLPORT |= ((1 << BIT_CS0));
pd1165_write(row-8, pixmap[plane][row][1]);
CTRLPORT &= ~((1<<BIT_CS1)|(1<<BIT_RW));
CTRLPORT |= ((1<<BIT_CS1));
pd1165_write(row - 8, pixmap[plane][row][1]);
CTRLPORT &= ~((1 << BIT_CS1) | (1 << BIT_RW));
CTRLPORT |= ((1 << BIT_CS1));
}
//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;
// depending on the currently drawn plane, display the row for a specific
// amount of time
switch (plane) {
case 0:
OCR0 = 3;
break;
case 1:
OCR0 = 4;
break;
case 2:
OCR0 = 22;
break;
}
//Zeile und Ebene inkrementieren
if(++plane==NUMPLANE){
plane=0;
//increment both row and plane
if (++plane == NUMPLANE) {
plane = 0;
}
}
void timer0_off(){
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 = 0x0D; // CTC Mode, clk/64
TCNT0 = 0; // reset timer
OCR0 = 20; // Compare with this value
TIMSK = 0x02; // Compare match Interrupt on
// initialize timer which triggers the interrupt
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 = 0x0D; // CTC Mode, clk/64
TCNT0 = 0; // reset timer
OCR0 = 20; // compare with this value
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);
CTRLPORT = (1<<BIT_CS0)|(1<<BIT_CS1)|(1<<BIT_CS2)|(1<<BIT_CS3)|(1<<BIT_RW);
DATADDR = 0xff;
ADDRDDR |= 0x0f;
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));
timer0_on();
timer2_on();
DDRD |= 1<<PD7; //OC2 pin to output
RDIMPORT |= (1<<BIT_RDIM);
RDIMDDR |= (1<<BIT_RDIM);
//Watchdog Timer aktivieren
DDRD |= 1 << PD7; // OC2 pin to output
RDIMPORT |= (1 << BIT_RDIM);
RDIMDDR |= (1 << BIT_RDIM);
// activate watchdog timer
wdt_reset();
wdt_enable(0x00); // 17ms Watchdog
wdt_enable(0x00); // 17ms watchdog
}

View File

@ -1,4 +1,3 @@
#include "../config.h"
#include "../makros.h"
@ -12,143 +11,127 @@
#define PIN_STR PB2
//Der Puffer, in dem das aktuelle Bild gespeichert wird
// buffer which holds the currently shown frame
unsigned char pixmap[NUMPLANE][NUM_ROWS][LINEBYTES];
//zur nächsten Zeile weiterschalten
inline void nextrow(uint8_t row){
//Die Zustände von der vorherigen Zeile löschen
// switch to next row
static void nextrow(uint8_t row) {
// clear states of the preceding row
PORTC &= 0xF0;
PORTD &= 0x0F;
PORTB &= 0xFC;
//kurze Warteschleife, damit die Treiber auch wirklich ausschalten
// short delay loop, to ensure proper deactivation of the drivers
unsigned char i;
for(i=0;i<10;i++){
for (i = 0; i < 10; i++) {
asm volatile("nop");
}
if (row == 0){
//Zeile 0: Das erste Schieberegister initialisieren
PORTB &= ~(1<<PIN_DATA); // zeile ist aktiv auf low
PORTB |= (1<<PIN_CLK);
PORTB &= ~(1<<PIN_CLK);
PORTB |= (1<<PIN_DATA);
if (row == 0) {
// row 0: initialize first shift register
PORTB &= ~(1 << PIN_DATA); // row is active low
PORTB |= (1 << PIN_CLK);
PORTB &= ~(1 << PIN_CLK);
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
PORTB |= (1<<PIN_CLK);
PORTB &= ~(1<<PIN_CLK);
}
//noch eine Warteschleife, damit die Zeilentreiber bereit sind
for(i=0;i<20;i++){
// another delay loop, to ensure that the drivers are ready
for (i = 0; i < 20; i++) {
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
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;
}
// output data of the current row to the column drivers
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];
PORTC = ( PORTC & 0xF0 ) | (tmp & 0x0F);
PORTD = ( PORTD & 0x0F ) | (tmp & 0xF0);
PORTB = ( PORTB & 0xFC ) | (tmp1 & 0x03);
PORTC = (PORTC & 0xF0) | (tmp & 0x0F);
PORTD = (PORTD & 0x0F) | (tmp & 0xF0);
PORTB = (PORTB & 0xFC) | (tmp1 & 0x03);
}
//Dieser Interrupt wird je nach Ebene mit 50kHz 31,25kHz oder 12,5kHz ausgeführt
SIGNAL(SIG_OVERFLOW0)
{
// depending on the plane this interrupt gets triggered at 50 kHz, 31.25 kHz or
// 12.5 kHz
SIGNAL(SIG_OVERFLOW0) {
static unsigned char plane = 0;
static unsigned char row = 0;
//Watchdog zurücksetzen
// reset watchdog
wdt_reset();
//Zeile und Ebene inkrementieren
if(++plane==NUMPLANE){
plane=0;
if(++row == NUM_ROWS){
// increment both row and plane
if (++plane == NUMPLANE) {
plane = 0;
if (++row == NUM_ROWS) {
row = 0;
}
nextrow(row);
}
//Die aktuelle Zeile in der aktuellen Ebene ausgeben
// output current row according to current plane
rowshow(row, plane);
}
void timer0_off(){
void timer0_off() {
cli();
/*
COLPORT1 = 0;
COLPORT2 = 0;
ROWPORT = 0;
*/
/*
COLPORT1 = 0;
COLPORT2 = 0;
ROWPORT = 0;
*/
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 = 0x03; // clk/64
TCNT0 = 0xFF-20; // reset timer
TIMSK |= (1<<TOIE0); // Compare match Interrupt on
// 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
*/
TCCR0 = 0x03; // clk/64
TCNT0 = 0xFF - 20; // reset timer
TIMSK |= (1 << TOIE0); // compare match Interrupt on
}
void borg_hw_init(){
// Nötige Pins auf Ausgang
DDRC=0x0F; // PC0-3 - Row 0-3
DDRD=0xF4; // PD4-7 - Row 4-7 PD2 - Masse für 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
PORTC=0x30;
PORTD=0x0B;
PORTB=0x14;
void borg_hw_init() {
// set required pins to output mode
DDRC = 0x0F; // PC0-3 - Row 0-3
DDRD = 0xF4; // PD4-7 - Row 4-7 PD2 - ground for joy
DDRB = 0x1F; // PB0-1 - Row 8-9 PB2-3 - STR, CLK, d
// turn off all columns for now, clk off, d and str on
// PC4-5, PD013 pullup on
PORTC = 0x30;
PORTD = 0x0B;
PORTB = 0x14;
timer0_on();
//Watchdog Timer aktivieren
// activate watchdog timer
wdt_reset();
wdt_enable(0x00); // 17ms Watchdog
wdt_enable(0x00); // 17ms watchdog
}

View File

@ -1,4 +1,3 @@
#include "../config.h"
#include "../makros.h"
#include "../ioport.h"
@ -9,29 +8,28 @@
#include "borg_hw.h"
//Der Puffer, in dem das aktuelle Bild gespeichert wird
// buffer which holds the currently shown frame
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];
COLPORT2 = pixmap[0][row][1];
// display a row
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_OFF(LATCH_R);
COLPORT1 = pixmap[1][row][0];
COLPORT2 = pixmap[1][row][1];
COLPORT1 = pixmap[1][row][0];
COLPORT2 = pixmap[1][row][1];
OUTPUT_ON(LATCH_G);
OUTPUT_OFF(LATCH_G);
COLPORT1 = pixmap[2][row][0];
COLPORT2 = pixmap[2][row][1];
COLPORT1 = pixmap[2][row][0];
COLPORT2 = pixmap[2][row][1];
OUTPUT_ON(LATCH_B);
OUTPUT_OFF(LATCH_B);
}
@ -41,28 +39,29 @@ uint32_t mod = 1280000ul;
uint32_t akku;
unsigned char row = 0;
ISR(SIG_OUTPUT_COMPARE0)
{
//Watchdog zurücksetzen
// reset watchdog
wdt_reset();
akku += mod;
OCR1A = akku / 256;
rowshow(row);
if(++row == NUM_ROWS){
if (++row == NUM_ROWS) {
row = NUM_ROWS - 1;
}
}
ISR(INT0_vect){
if(akku > (64ul * 256ul * 64ul)){
ISR(INT0_vect) {
if (akku > (64ul * 256ul * 64ul)) {
akku -= OCR1A - TCNT1;
mod = akku / 64;
akku = 0;
row = 0;
@ -72,32 +71,31 @@ ISR(INT0_vect){
}
void timer0_off(){
void timer0_off() {
cli();
TCCR1B = 0x00;
sei();
}
// Den Timer, der denn Interrupt auslöst, initialisieren
void timer1_on(){
TCCR1B = 1; //clk/1
TIMSK |= (1<<OCIE1A);
// initialize timer which triggers the interrupt
void timer1_on() {
TCCR1B = 1; // clk/1
TIMSK |= (1 << OCIE1A);
}
void borg_hw_init(){
void borg_hw_init() {
DDR(COLPORT1) = 0xff;
DDR(COLPORT2) = 0xff;
SET_DDR(LATCH_R);
SET_DDR(LATCH_G);
SET_DDR(LATCH_B);
timer1_on();
//Watchdog Timer aktivieren
// activate watchdog timer
wdt_reset();
wdt_enable(0x00); // 17ms Watchdog
wdt_enable(0x00); // 17ms watchdog
}

View File

@ -146,25 +146,13 @@ void tetris_std_removedLines(void *pVariantData,
tetris_standard_variant_t *pStdVariant =
(tetris_standard_variant_t *)pVariantData;
uint8_t nLines = tetris_bucket_calculateLines(nRowMask);
assert(nLines <= 4);
pStdVariant->nLines += nLines;
pStdVariant->nLevel = ((pStdVariant->nLines / 10) < TETRIS_INPUT_LEVELS) ?
(pStdVariant->nLines / 10) : (TETRIS_INPUT_LEVELS - 1);
switch (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;
}
static uint16_t const nScoreTable[] PROGMEM = {0, 50, 150, 250, 400};
pStdVariant->nScore += pgm_read_word(&nScoreTable[nLines]);
}