Statistics
| Branch: | Revision:

root / main.c @ 3e2454a3

History | View | Annotate | Download (3.45 KB)

1
#define F_CPU 16000000L
2

    
3
#include <inttypes.h>
4
#include <avr/io.h>
5
#include <util/delay.h>
6
#include <avr/interrupt.h>
7
#include <avr/pgmspace.h>
8
#include "buffer.h"
9
//let's make our lives easier :)
10
#define PORT_(port) PORT ## port
11
#define DDR_(port)  DDR  ## port
12
#define PIN_(port)  PIN  ## port
13
#define PORT(port) PORT_(port)
14
#define DDR(port)  DDR_(port)
15
#define PIN(port)  PIN_(port)
16

    
17
// wallboard pins:
18
#define WALLBOARD_PORT         B
19
#define CLOCK_PIN         PB0
20
#define DATA_GREEN_PIN         PB3
21
#define DATA_RED_PIN         PB1
22
#define OUTPUT_ENABLE_PIN PB2
23
// address lines - please note that the address lines have to be
24
// on the same port and in the current implementation are on 0-3
25
#define ADDRESS_PORT         C
26
#define A0                 PC0
27
#define A1                 PC1
28
#define A2                 PC2
29
#define A3                 PC3
30

    
31

    
32
int main(void);
33
inline void customColor(uint8_t colorPins);
34
inline void OE(void);
35
inline void ODE(void);
36
static inline void drawEverything(void);
37
inline void printLineBasic(int16_t line, uint8_t round, uint8_t color);
38

    
39
inline void setPixelAtPos(uint8_t x, uint8_t y){
40
        lines[y] |= (1<<x);
41
}
42

    
43
// yes, this is right, we need 16bit input and output 8bit, "it fits"(tm)
44
static inline int16_t i16abs(int16_t x) { return x < 0 ? -x : x; }
45

    
46
// draw a line from the first coordinate to the second one
47
void drawLine(int16_t x_from, int16_t y_from,
48
                int16_t x_to  , int16_t y_to) {
49
        int16_t dx = i16abs((int16_t)x_to - (int16_t)x_from);
50
        int16_t dy = i16abs((int16_t)y_to - (int16_t)y_from);
51

    
52
        int16_t sx = x_from < x_to ? 1 : -1;
53
        int16_t sy = y_from < y_to ? 1 : -1;
54

    
55
        int16_t err = dx - dy;
56

    
57
        setPixelAtPos(x_from, y_from);
58

    
59
        while(x_from != x_to || y_from != y_to) {
60
                int16_t e2 = 2 * err;
61

    
62
                if(e2 > -dy) {
63
                        err -= dy;
64
                        x_from += sx;
65
                }
66

    
67
                if(e2 < dx) {
68
                        err += dx;
69
                        y_from += sy;
70
                }
71

    
72
                setPixelAtPos(x_from, y_from);
73
        }
74
}
75

    
76
void clearBuffer(){
77
        for(uint8_t i = 0; i < 90; i++){
78
                lines[i] = 0;
79
        }
80
}
81

    
82
int main(){
83
        // hardware init
84
        // clock, data and output enable
85
        DDR(WALLBOARD_PORT) |= (1<<CLOCK_PIN) | (1<<DATA_RED_PIN) | (1<<DATA_GREEN_PIN) | (1<<OUTPUT_ENABLE_PIN);
86
        // address lines:
87
        DDR(ADDRESS_PORT) |= (1<<A3) | (1<<A2) | (1<<A1) | (1<<A0);
88
        
89
        drawLine(0,0, 15, 89);
90
        uint8_t x1 = 0;
91
        uint8_t y1 = 0;
92
        uint8_t x2 = 15;
93
        uint8_t y2 = 89;
94
        while(1){
95
                drawEverything();
96
                clearBuffer();
97
                drawLine(x1, y1, x2, y2);
98
                if(x1 < 15 && y2 == 89){
99
                        x1++;
100
                        x2--;
101
                }
102
                else if(y1 != 89){
103
                        y1++;
104
                        y2--;
105
                }
106
                else{
107
                        x1 = 0;
108
                        y1 = 0;
109
                        x2 = 15;
110
                        y2 = 89;
111
                }
112
        }
113
}
114

    
115
static inline void drawEverything(){
116
        for(uint8_t intensity = 0; intensity < 16; intensity++){
117
                for(uint8_t round = 0; round < intensity; round++){
118
                        PORT(ADDRESS_PORT) = round;
119
                        for(int16_t line = 0; line < 90; line++){
120
                                printLineBasic(line, round, (1<<DATA_GREEN_PIN));
121
                        }
122
                        OE();
123
                        _delay_us(30);
124
                        ODE();
125
                        _delay_us(1); // avoid ghosting
126
                }
127
                for(uint8_t round = intensity; round < 16; round++){
128
                        PORT(ADDRESS_PORT) = round;
129
                        for(int16_t line = 0; line < 90; line++){
130
                                printLineBasic(line, round, (1<<DATA_RED_PIN));
131
                        }
132
                        OE();
133
                        _delay_us(30);
134
                        ODE();
135
                        _delay_us(1); // avoid ghosting
136
                }
137
        }
138
}
139

    
140
inline void printLineBasic(int16_t line, uint8_t round, uint8_t color){
141
        if((1<<round) & lines[line]){
142
                customColor(color);
143
        }
144
        else{
145
                customColor(0);
146
        }
147
}
148

    
149
inline void customColor(uint8_t colorPins){
150
        PORT(WALLBOARD_PORT) |= colorPins | (1<<CLOCK_PIN);
151
        PORT(WALLBOARD_PORT) &= ~(colorPins | (1<<CLOCK_PIN));
152
}
153

    
154
inline void OE(){
155
        PORT(WALLBOARD_PORT) |= (1<<OUTPUT_ENABLE_PIN);
156
}
157

    
158
inline void ODE(){
159
        PORT(WALLBOARD_PORT) &= ~(1<<OUTPUT_ENABLE_PIN);
160
}