Browse Source

saved up to 240 bytes (depending on borg hw), translated some German comments into English and cleaned up formatting (sorry about the noise)

feature/2015
Christian Kroll 13 years ago
parent
commit
d4ae78fee3
  1. 26
      animations/amphibian.c
  2. 14
      animations/gameoflife.c
  3. 3
      borg_hw/borg_hw.h
  4. 97
      borg_hw/borg_hw_andreborg.c
  5. 102
      borg_hw/borg_hw_borg16.c
  6. 25
      borg_hw/borg_hw_borg_ls.c
  7. 34
      borg_hw/borg_hw_borg_mh.c
  8. 54
      borg_hw/borg_hw_gigaborg.c
  9. 71
      borg_hw/borg_hw_panel_one.c
  10. 79
      borg_hw/borg_hw_pd1165.c
  11. 83
      borg_hw/borg_hw_pingpong.c
  12. 24
      borg_hw/borg_hw_rotor.c
  13. 18
      games/tetris/variant_std.c

26
animations/amphibian.c

@ -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

14
animations/gameoflife.c

@ -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);
} }
} }
} }

3
borg_hw/borg_hw.h

@ -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)

97
borg_hw/borg_hw_andreborg.c

@ -1,4 +1,3 @@
#include "../config.h" #include "../config.h"
#include "../makros.h" #include "../makros.h"
@ -8,23 +7,25 @@
#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
// reset pin is negated
#define PIN_MCLR PD4 #define PIN_MCLR PD4
#define PIN_CLK PD5 #define PIN_CLK PD5
//das dier sind die individuellen Dateneingänge für die Schieberegister
// these are the individual data input pins for the shift registers
#define PIN_DATA1 PD6 #define PIN_DATA1 PD6
#define PIN_DATA2 PD7 #define PIN_DATA2 PD7
*/ */
@ -39,26 +40,23 @@
#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) {
//Zeile 0: Das erste Schieberegister initialisieren // row 0: initialize first shift register
ROWPORT &= ~(1 << PIN_MCLR); ROWPORT &= ~(1 << PIN_MCLR);
ROWPORT |= (1 << PIN_MCLR); ROWPORT |= (1 << PIN_MCLR);
ROWPORT |= (1 << PIN_DATA1); ROWPORT |= (1 << PIN_DATA1);
@ -66,19 +64,12 @@ inline void rowshow(unsigned char row, unsigned char plane){
ROWPORT &= ~(1 << PIN_CLK); ROWPORT &= ~(1 << PIN_CLK);
ROWPORT &= ~(1 << PIN_DATA1); ROWPORT &= ~(1 << PIN_DATA1);
//Je nachdem, welche der Ebenen wir Zeichnen, die Zeile verschieden lange Anzeigen // depending on the currently drawn plane, display the row for a
switch (plane){ // specific amount of time
case 0: static unsigned char const ocr0_table[] = {5, 8, 20};
OCR0 = 5; OCR0 = ocr0_table[plane];
break;
case 1:
OCR0 = 8;
break;
case 2:
OCR0 = 20;
}
} else if (row == 8) { } else if (row == 8) {
//Zeile 8: Das Zweite Schieberegister initialisieren // row 8: initialize second shift register
ROWPORT &= ~(1 << PIN_MCLR); ROWPORT &= ~(1 << PIN_MCLR);
ROWPORT |= (1 << PIN_MCLR); ROWPORT |= (1 << PIN_MCLR);
ROWPORT |= (1 << PIN_DATA2); ROWPORT |= (1 << PIN_DATA2);
@ -86,41 +77,41 @@ inline void rowshow(unsigned char row, unsigned char plane){
ROWPORT &= ~(1 << PIN_CLK); ROWPORT &= ~(1 << PIN_CLK);
ROWPORT &= ~(1 << PIN_DATA2); ROWPORT &= ~(1 << PIN_DATA2);
} 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);
} }
//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();
@ -138,9 +129,8 @@ void timer0_off(){
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
@ -149,41 +139,40 @@ void timer0_on(){
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
} }

102
borg_hw/borg_hw_borg16.c

@ -1,4 +1,3 @@
#include "../config.h" #include "../config.h"
#include "../makros.h" #include "../makros.h"
@ -8,23 +7,25 @@
#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
// reset pin is negated
#define PIN_MCLR PD4 #define PIN_MCLR PD4
#define PIN_CLK PD6 #define PIN_CLK PD6
//das dier sind die individuellen Dateneingänge für die Schieberegister
// these are the individual data input pins for the shift registers
#define PIN_DATA PD7 #define PIN_DATA PD7
*/ */
@ -38,26 +39,23 @@
#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);
@ -73,36 +71,26 @@ inline void nextrow(uint8_t row){
#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];
@ -124,7 +112,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;
@ -137,17 +126,16 @@ inline void rowshow(unsigned char row, unsigned char plane){
} }
// 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) {
@ -156,11 +144,10 @@ SIGNAL(SIG_OUTPUT_COMPARE0)
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();
@ -178,9 +165,8 @@ void timer0_off(){
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
@ -189,40 +175,40 @@ void timer0_on(){
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() { 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
} }

25
borg_hw/borg_hw_borg_ls.c

@ -1,4 +1,3 @@
#include "../config.h" #include "../config.h"
#include "../makros.h" #include "../makros.h"
@ -8,8 +7,9 @@
#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
@ -23,9 +23,11 @@
*/ */
#define COLDDR DDR(COLPORT) #define COLDDR DDR(COLPORT)
#define ROWDDR DDR(ROWPORT) #define ROWDDR DDR(ROWPORT)
unsigned char pixmap[NUMPLANE][NUM_ROWS][LINEBYTES]; unsigned char pixmap[NUMPLANE][NUM_ROWS][LINEBYTES];
@ -34,7 +36,6 @@ inline void rowshow(unsigned char row, unsigned char plane){
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];
@ -53,8 +54,8 @@ inline void rowshow(unsigned char row, unsigned char plane){
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;
@ -75,13 +76,13 @@ SIGNAL(SIG_OUTPUT_COMPARE0)
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() { 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
@ -95,10 +96,11 @@ void timer0_on(){
*/ */
TCCR0 = 0x08 | 0x04; // CTC Mode, clk/256 TCCR0 = 0x08 | 0x04; // CTC Mode, clk/256
TCNT0 = 0; // reset timer TCNT0 = 0; // reset timer
OCR0 = 0x30; // Compare with this value OCR0 = 0x30; // compare with this value
TIMSK = 0x02; // Compare match Interrupt on TIMSK = 0x02; // compare match Interrupt on
} }
void timer0_off() { void timer0_off() {
cli(); cli();
@ -108,13 +110,14 @@ void timer0_off(){
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);

34
borg_hw/borg_hw_borg_mh.c

@ -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,7 +24,6 @@
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;
@ -38,12 +35,10 @@ inline void rowshow(unsigned char row, unsigned char plane){
MYPORT &= ~(1 << PIN_ENABLE); MYPORT &= ~(1 << PIN_ENABLE);
// MYPORT |= (1 << PIN_ENABLE); //hide // MYPORT |= (1 << PIN_ENABLE); //hide
// MYPORT |= (1 << PIN_ENABLE); //hide // MYPORT |= (1 << PIN_ENABLE); //hide
for (n=7;n<8;n--) for (n = 7; n < 8; n--) {
{
outb = pixmap[plane][row][n]; outb = pixmap[plane][row][n];
p = 0x80; p = 0x80;
for (m=0;m<8;m++) for (m = 0; m < 8; m++) {
{
if (outb & p) if (outb & p)
// MYPORT |= (1 << PIN_DATA); // MYPORT |= (1 << PIN_DATA);
MYPORT &= ~(1 << PIN_DATA); MYPORT &= ~(1 << PIN_DATA);
@ -59,15 +54,12 @@ inline void rowshow(unsigned char row, unsigned char plane){
} }
} }
} }
MYPORT |= (1 << PIN_ENABLE) ; // MYPORT |= (1 << PIN_ENABLE);
//MYPORT &= ~(1 << PIN_ENABLE) ; //MYPORT &= ~(1 << PIN_ENABLE) ;
// for(n=0;n<250;n++) asm ("nop"); // 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;
@ -93,12 +85,11 @@ SIGNAL(SIG_OUTPUT_COMPARE0)
rowshow(row, plane); rowshow(row, plane);
} }
if(++plane==NUMPLANE) plane=0; if (++plane == NUMPLANE)
plane = 0;
wdt_reset(); wdt_reset();
} }
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
@ -108,12 +99,11 @@ void timer0_on(){
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 = 0x08 |0x04; // CTC Mode, clk/256 MH: slower 5 statt 4 TCCR0 = 0x08 | 0x04; // CTC Mode, clk/256 MH: slower 5 instead of 4
TCNT0 = 0; // reset timer TCNT0 = 0; // reset timer
OCR0 = 0x30; // Compare with this value 0x30 OCR0 = 0x30; // compare with this value 0x30
TIMSK = 0x02; // Compare match Interrupt on TIMSK = 0x02; // compare match Interrupt on
} }
void timer0_off() { void timer0_off() {
@ -127,21 +117,17 @@ void timer0_off(){
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; DDRA = 0xFF;
DDRC = 0xFF; DDRC = 0xFF;
watchdog_enable(); watchdog_enable();

54
borg_hw/borg_hw_gigaborg.c

@ -1,4 +1,3 @@
#include "../config.h" #include "../config.h"
#include "../makros.h" #include "../makros.h"
@ -8,23 +7,25 @@
#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
// reset pin is negated
#define PIN_MCLR PD4 #define PIN_MCLR PD4
#define PIN_CLK PD6 #define PIN_CLK PD6
//das dier sind die individuellen Dateneingänge für die Schieberegister
// these are the individual data input pins for the shift registers
#define PIN_DATA PD7 #define PIN_DATA PD7
*/ */
@ -39,17 +40,16 @@
#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);
} }
@ -66,14 +66,13 @@ void timer0_off(){
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
@ -83,38 +82,38 @@ void timer0_on(){
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() { 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;
//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++) {
@ -122,10 +121,9 @@ void borg_hw_init(){
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
} }

71
borg_hw/borg_hw_panel_one.c

@ -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
* Die Werte für die LED spalten Werden mit CP1 und CP2 in die
* Latches übernommen (insgesammt 16 Spalten)
* Die Nummer der Zeile wird beim löschen von /show übernommen.
* *
* Die Tasten sind in einer 8*8 Matrix angeordnet. * The LEDs are aligned to a 12*16 matrix. The values for the LED columns are
* Über Latch 4 werden die Zeilen einzeln auf high gesetzt, über * passed to the latches via CP1 und CP2 (16 columns total). The index of the
* Latch 3 können dann die Spalten gelesen werden. * row is passed during the deletion of "/show".
* *
* 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 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,11 +78,13 @@
#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++){
@ -93,7 +93,7 @@ inline void busywait() {
} }
//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
@ -116,6 +116,7 @@ inline void rowshow(unsigned char row, unsigned char plane){
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) {
@ -142,22 +143,23 @@ inline void checkkeys(uint8_t row){
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;
// reset watchdog
//Watchdog zurücksetzen
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,7 +186,7 @@ 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
@ -194,27 +196,28 @@ void timer0_on(){
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 // switch off all columns for now
//Spalten Ports auf Ausgang // switch column ports to output mode
COLDDR = 0xFF; 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
} }

79
borg_hw/borg_hw_pd1165.c

@ -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
// reset pin is negated
#define PIN_MCLR PD4 #define PIN_MCLR PD4
#define PIN_CLK PD6 #define PIN_CLK PD6
//das dier sind die individuellen Dateneingänge für die Schieberegister
// these are the individual data input pins for the shift registers
#define PIN_DATA PD7 #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,11 +50,10 @@
//#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;
@ -77,17 +76,17 @@ inline void pd1165_write(uint8_t addr, uint8_t data){
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
// amount of time
switch (plane) { switch (plane) {
case 0: case 0:
OCR0 = 3; OCR0 = 3;
@ -100,7 +99,7 @@ inline void rowshow(unsigned char row, unsigned char plane){
} }
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];
@ -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;
@ -134,23 +134,22 @@ inline void rowshow(unsigned char row, unsigned char plane){
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++) {
@ -164,7 +163,6 @@ SIGNAL(SIG_OUTPUT_COMPARE0)
//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++) { for (row = 8; row < NUM_ROWS; row++) {
@ -177,7 +175,8 @@ SIGNAL(SIG_OUTPUT_COMPARE0)
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
// amount of time
switch (plane) { switch (plane) {
case 0: case 0:
OCR0 = 3; OCR0 = 3;
@ -187,10 +186,10 @@ SIGNAL(SIG_OUTPUT_COMPARE0)
break; break;
case 2: case 2:
OCR0 = 22; OCR0 = 22;
break;
} }
//increment both row and plane
//Zeile und Ebene inkrementieren
if (++plane == NUMPLANE) { if (++plane == NUMPLANE) {
plane = 0; plane = 0;
} }
@ -200,13 +199,12 @@ SIGNAL(SIG_OUTPUT_COMPARE0)
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
@ -220,10 +218,11 @@ void timer0_on(){
*/ */
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() { void timer2_on() {
/* TCCR2: FOC2 WGM20 COM21 COM20 WGM21 CS22 CS21 CS20 /* TCCR2: FOC2 WGM20 COM21 COM20 WGM21 CS22 CS21 CS20
CS02 CS01 CS00 CS02 CS01 CS00
@ -236,20 +235,19 @@ void timer2_on(){
1 1 0 clk/256 1 1 0 clk/256
1 1 1 clk/1024 1 1 1 clk/1024
Table 51. Compare Output Mode, non-PWM Mode Table 51. Compare Output Mode, non-PWM Mode
COM21 COM20 Description COM21 COM20 Description
0 0 Normal port operation, OC2 disconnected. 0 0 normal port operation, OC2 disconnected.
0 1 Toggle OC2 on compare match 0 1 toggle OC2 on compare match
1 0 Clear OC2 on compare match 1 0 clear OC2 on compare match
1 1 Set OC2 on compare match 1 1 set OC2 on compare match
*/ */
TCCR2 = (1 << WGM21) | (1 << COM20) | 1; //CTC, OC2 toggle, clk/1 TCCR2 = (1 << WGM21) | (1 << COM20) | 1; //CTC, OC2 toggle, clk/1
OCR2 = 92; // 80kHz clock on OC2 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);
@ -257,14 +255,11 @@ void borg_hw_init(){
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();
@ -273,7 +268,7 @@ void borg_hw_init(){
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
} }

83
borg_hw/borg_hw_pingpong.c

@ -1,4 +1,3 @@
#include "../config.h" #include "../config.h"
#include "../makros.h" #include "../makros.h"
@ -12,84 +11,70 @@
#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 {
else { // remaining rows: just shift forward
//In jeder anderen Zeile einfach nur einen weiter schieben
PORTB |= (1 << PIN_CLK); PORTB |= (1 << PIN_CLK);
PORTB &= ~(1 << PIN_CLK); PORTB &= ~(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");
} }
} }
// 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) {
@ -98,7 +83,7 @@ SIGNAL(SIG_OVERFLOW0)
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);
} }
@ -115,9 +100,8 @@ void timer0_off(){
} }
// 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
@ -126,29 +110,28 @@ void timer0_on(){
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 TCCR0 = 0x03; // clk/64
TCNT0 = 0xFF - 20; // reset timer TCNT0 = 0xFF - 20; // reset timer
TIMSK |= (1<<TOIE0); // Compare match Interrupt on TIMSK |= (1 << TOIE0); // compare match Interrupt on
} }
void borg_hw_init(){
// Nötige Pins auf Ausgang void borg_hw_init() {
// set required pins to output mode
DDRC = 0x0F; // PC0-3 - Row 0-3 DDRC = 0x0F; // PC0-3 - Row 0-3
DDRD=0xF4; // PD4-7 - Row 4-7 PD2 - Masse für Joy DDRD = 0xF4; // PD4-7 - Row 4-7 PD2 - ground for joy
DDRB = 0x1F; // PB0-1 - Row 8-9 PB2-3 - STR, CLK, d DDRB = 0x1F; // PB0-1 - Row 8-9 PB2-3 - STR, CLK, d
// Alle Spalten erstmal aus, clk aus, d und str an // turn off all columns for now, clk off, d and str on
// PC4-5, PD013 Pullup an // PC4-5, PD013 pullup on
PORTC = 0x30; PORTC = 0x30;
PORTD = 0x0B; PORTD = 0x0B;
PORTB = 0x14; 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
} }

24
borg_hw/borg_hw_rotor.c

@ -1,4 +1,3 @@
#include "../config.h" #include "../config.h"
#include "../makros.h" #include "../makros.h"
#include "../ioport.h" #include "../ioport.h"
@ -9,14 +8,13 @@
#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
// display a row
inline void rowshow(unsigned char row) {
// output data of the current row to the column drivers
COLPORT1 = pixmap[0][row][0]; COLPORT1 = pixmap[0][row][0];
COLPORT2 = pixmap[0][row][1]; COLPORT2 = pixmap[0][row][1];
@ -42,9 +40,10 @@ 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;
@ -56,9 +55,9 @@ ISR(SIG_OUTPUT_COMPARE0)
if (++row == NUM_ROWS) { if (++row == NUM_ROWS) {
row = NUM_ROWS - 1; row = NUM_ROWS - 1;
} }
} }
ISR(INT0_vect) { ISR(INT0_vect) {
if (akku > (64ul * 256ul * 64ul)) { if (akku > (64ul * 256ul * 64ul)) {
akku -= OCR1A - TCNT1; akku -= OCR1A - TCNT1;
@ -74,19 +73,18 @@ 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;
@ -97,7 +95,7 @@ void borg_hw_init(){
timer1_on(); timer1_on();
//Watchdog Timer aktivieren // activate watchdog timer
wdt_reset(); wdt_reset();
wdt_enable(0x00); // 17ms Watchdog wdt_enable(0x00); // 17ms watchdog
} }

18
games/tetris/variant_std.c

@ -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…
Cancel
Save