From 1aa93415495a16a994d896f9cbb888189bd1403b Mon Sep 17 00:00:00 2001 From: Ain <41307858+nero@users.noreply.github.com> Date: Wed, 3 Oct 2018 00:53:55 +0000 Subject: [PATCH] Add support for the franzis pingpong hardware --- boards/pingpong.mk | 11 ++++++ drivers/framebuffer.c | 4 ++ drivers/framebuffer.h | 26 +++++++++++++ drivers/franzis_pp.c | 91 +++++++++++++++++++++++++++++++++++++++++++ drivers/franzis_pp.h | 48 +++++++++++++++++++++++ pingpong.c | 36 +++++++++++++++++ 6 files changed, 216 insertions(+) create mode 100644 boards/pingpong.mk create mode 100644 drivers/framebuffer.c create mode 100644 drivers/framebuffer.h create mode 100644 drivers/franzis_pp.c create mode 100644 drivers/franzis_pp.h create mode 100644 pingpong.c diff --git a/boards/pingpong.mk b/boards/pingpong.mk new file mode 100644 index 0000000..bfd3792 --- /dev/null +++ b/boards/pingpong.mk @@ -0,0 +1,11 @@ +# Franzis Ping-Pong thing +MCU_TARGET = atmega8 +MCU_FREQ = 8000000UL + +CPPFLAGS += -DFB_WIDTH=12 -DFB_HEIGHT=10 -DFB_DEPTH=1 + +DRIVER_OBJ += drivers/franzis_pp.o + +AVRDUDE_TYPE = usbasp + +PROG ?= pingpong diff --git a/drivers/framebuffer.c b/drivers/framebuffer.c new file mode 100644 index 0000000..82ecab4 --- /dev/null +++ b/drivers/framebuffer.c @@ -0,0 +1,4 @@ +#define DONT_DECLARE_FRAMEBUFFER 1 +#include "framebuffer.h" + +FRAMEBUFFER; diff --git a/drivers/framebuffer.h b/drivers/framebuffer.h new file mode 100644 index 0000000..e1f05b9 --- /dev/null +++ b/drivers/framebuffer.h @@ -0,0 +1,26 @@ +#include + +#define CEILDIV(x, y) (((x)+((y)-1))/(y)) + +#if FB_DEPTH==1 + +#define FB_WIDTH_BYTES CEILDIV(FB_WIDTH, 8) +#define FRAMEBUFFER uint8_t framebuffer[FB_HEIGHT][FB_WIDTH_BYTES]; +#define FB_SET(w,h,c) if (c) { \ + framebuffer[h][w>>3] |= (1 << (w & 7)); \ + } else { \ + framebuffer[h][w>>3] &= ~(1 << (w & 7)); \ + } +#define FB_CLEAR() memset(framebuffer, 0, sizeof(framebuffer[0][0]) * FB_HEIGHT * FB_WIDTH_BYTES); + +#elif FB_DEPTH==8 + +#define FRAMEBUFFER uint8_t framebuffer][FB_HEIGHT][FB_WIDTH]; +#define FB_SET(w,h,c) framebuffer[h][w] = c +#define FB_CLEAR() memset(framebuffer, 0, sizeof(framebuffer[0][0]) * FB_HEIGHT * FB_WIDTH); + +#endif + +#ifndef DONT_DECLARE_FRAMEBUFFER +extern FRAMEBUFFER +#endif diff --git a/drivers/franzis_pp.c b/drivers/franzis_pp.c new file mode 100644 index 0000000..43a9b37 --- /dev/null +++ b/drivers/franzis_pp.c @@ -0,0 +1,91 @@ +#include +#include + +#include "franzis_pp.h" +#include "framebuffer.h" + +void __attribute__ ((naked)) __attribute__ ((section (".init6"))) franzis_pingpong_init() { + ROW0_DDR |= (1 << ROW0_PIN); + ROW1_DDR |= (1 << ROW1_PIN); + ROW2_DDR |= (1 << ROW2_PIN); + ROW3_DDR |= (1 << ROW3_PIN); + ROW4_DDR |= (1 << ROW4_PIN); + ROW5_DDR |= (1 << ROW5_PIN); + ROW6_DDR |= (1 << ROW6_PIN); + ROW7_DDR |= (1 << ROW7_PIN); + ROW8_DDR |= (1 << ROW8_PIN); + ROW9_DDR |= (1 << ROW9_PIN); + + COLS_DDR |= (1 << COLS_STR); + COLS_DDR |= (1 << COLS_DATA); + COLS_DDR |= (1 << COLS_CLK); + + ROW2_PORT |= (1 << ROW2_PIN); + + COLS_PORT |= (1 << COLS_CLK); + + TCCR2 = (1 << CS22); + TIMSK = (1 << TOIE2); + + sei(); +} + +void franzis_pingpong_push(uint16_t data) { + COLS_PORT |= (1 << COLS_STR); + + uint8_t i; + for (i = 0; i<=11; i++) { + COLS_PORT &= ~(1 << COLS_CLK); + if (data & 1) { + COLS_PORT &= ~(1 << COLS_DATA); + } else { + COLS_PORT |= (1 << COLS_DATA); + } + COLS_PORT |= (1 << COLS_CLK); + data = data >> 1; + } + + COLS_PORT &= ~(1 << COLS_STR); +} + +void franzis_pingpong_clear_row() { + ROW0_PORT &= ~(1 << ROW0_PIN); + ROW1_PORT &= ~(1 << ROW1_PIN); + ROW2_PORT &= ~(1 << ROW2_PIN); + ROW3_PORT &= ~(1 << ROW3_PIN); + ROW4_PORT &= ~(1 << ROW4_PIN); + ROW5_PORT &= ~(1 << ROW5_PIN); + ROW6_PORT &= ~(1 << ROW6_PIN); + ROW7_PORT &= ~(1 << ROW7_PIN); + ROW8_PORT &= ~(1 << ROW8_PIN); + ROW9_PORT &= ~(1 << ROW9_PIN); +} + +void franzis_pingpong_select_row(uint8_t row) { + switch(row) { + case 0: ROW0_PORT |= (1 << ROW0_PIN); break; + case 1: ROW1_PORT |= (1 << ROW1_PIN); break; + case 2: ROW2_PORT |= (1 << ROW2_PIN); break; + case 3: ROW3_PORT |= (1 << ROW3_PIN); break; + case 4: ROW4_PORT |= (1 << ROW4_PIN); break; + case 5: ROW5_PORT |= (1 << ROW5_PIN); break; + case 6: ROW6_PORT |= (1 << ROW6_PIN); break; + case 7: ROW7_PORT |= (1 << ROW7_PIN); break; + case 8: ROW8_PORT |= (1 << ROW8_PIN); break; + case 9: ROW9_PORT |= (1 << ROW9_PIN); break; + } +} + +uint8_t fb_nextrow = 0; + +ISR(TIMER2_OVF_vect) { + franzis_pingpong_clear_row(); + + uint16_t data = ( framebuffer[fb_nextrow][0] ) | ( framebuffer[fb_nextrow][1] << 8); + franzis_pingpong_push(data); + + franzis_pingpong_select_row(fb_nextrow); + + fb_nextrow++; + fb_nextrow = fb_nextrow % 10; +} diff --git a/drivers/franzis_pp.h b/drivers/franzis_pp.h new file mode 100644 index 0000000..9f6ecec --- /dev/null +++ b/drivers/franzis_pp.h @@ -0,0 +1,48 @@ +#define ROW0_DDR DDRB +#define ROW0_PORT PORTB +#define ROW0_PIN PB1 + +#define ROW1_DDR DDRB +#define ROW1_PORT PORTB +#define ROW1_PIN PB0 + +#define ROW2_DDR DDRD +#define ROW2_PORT PORTD +#define ROW2_PIN PD7 + +#define ROW3_DDR DDRD +#define ROW3_PORT PORTD +#define ROW3_PIN PD6 + +#define ROW4_DDR DDRD +#define ROW4_PORT PORTD +#define ROW4_PIN PD5 + +#define ROW5_DDR DDRD +#define ROW5_PORT PORTD +#define ROW5_PIN PD4 + +#define ROW6_DDR DDRC +#define ROW6_PORT PORTC +#define ROW6_PIN PC3 + +#define ROW7_DDR DDRC +#define ROW7_PORT PORTC +#define ROW7_PIN PC2 + +#define ROW8_DDR DDRC +#define ROW8_PORT PORTC +#define ROW8_PIN PC1 + +#define ROW9_DDR DDRC +#define ROW9_PORT PORTC +#define ROW9_PIN PC0 + +#define COLS_DDR DDRB +#define COLS_PORT PORTB + +#define COLS_STR PB2 +#define COLS_DATA PB4 +#define COLS_CLK PB3 + +void fb_hsync(); diff --git a/pingpong.c b/pingpong.c new file mode 100644 index 0000000..c3ab4a6 --- /dev/null +++ b/pingpong.c @@ -0,0 +1,36 @@ +#include +#include "drivers/framebuffer.h" + +int main(void) { + int8_t px, py, mx, my; + + px = 0; + py = 0; + mx = 1; + my = 1; + + while(1) { + if (px <= 0) { + mx = 1; + } + + if (py <= 0) { + my = 1; + } + + if (px >= FB_WIDTH - 1) { + mx = -1; + } + + if (py >= FB_HEIGHT - 1) { + my = -1; + } + + FB_SET(px,py,0); + px += mx; + py += my; + FB_SET(px,py,1); + + _delay_ms(50); + } +}