forked from sooda/metro_station_display
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprintline.c
134 lines (122 loc) · 3.23 KB
/
printline.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// staattinen kuva lcd-näytölle juttelemalla suoraan väylälle
// luo kuva printline_to_header.py:n avulla
// testattu teensy++ 2.0:lla @ 16 MHz
#include <avr/io.h>
#include <avr/power.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include <stdint.h>
#include "image.h"
// datanasta C0:ssa, strobet heti sen jälkeen
#define DATAPORT PORTC
#define DATADDR DDRC
#define DATAPIN _BV(0)
#define TOPSTROBEPIN _BV(1)
#define BOTSTROBEPIN _BV(2)
#define DATAPORTMASK (DATAPIN | TOPSTROBEPIN | BOTSTROBEPIN)
// osoite D:n alussa, seitebitti niiden perässä
#define ADDRPORT PORTD
#define ADDRDDR DDRD
#define ADDRROW0 _BV(0)
#define ADDRROW1 _BV(1)
#define ADDRROW2 _BV(2)
#define ADDRSEITE _BV(3)
#define SEITE0 0
#define SEITE1 ADDRSEITE
#define ADDRROWMASK (ADDRROW0 | ADDRROW1 | ADDRROW2)
#define ADDRPORTMASK (ADDRROWMASK | ADDRSEITE)
//#define CLKDELAY() _delay_us(1) // näinkin voi tehdä, mutta kokeillaan nyt nopeilla tarkasti
// vähempikin toimii, mutta tulee pari virhebittiä
// hidastuukohan näyttö esim. pakkasessa?
#define CLKDELAY() __asm__("nop\n\tnop\n\tnop\n\tnop\n\tnop\n\tnop\n\tnop")
#define LATCHDELAY() __asm__("nop\n\tnop\n\tnop")
void address(int seitebit, int addrbit) {
ADDRPORT = seitebit | addrbit;
}
void data(int yes) {
if (yes)
DATAPORT |= DATAPIN;
else
DATAPORT &= ~DATAPIN;
}
void strobetop(void) {
DATAPORT |= TOPSTROBEPIN;
CLKDELAY();
DATAPORT &= ~TOPSTROBEPIN;
}
void strobebot(void) {
DATAPORT |= BOTSTROBEPIN;
CLKDELAY();
DATAPORT &= ~BOTSTROBEPIN;
}
void sendtop(int yes) {
data(yes);
strobetop();
}
void sendbot(int yes) {
data(yes);
strobebot();
}
int byte, bit, jekku;
void topcol(void) {
for (int colbit = 0; colbit < 12; colbit++) {
unsigned int x = pgm_read_byte(&imagetop[byte]) & bit;
if (jekku) x = !x;
sendtop(x);
bit <<= 1;
if (!(bit & 0xff)) {
bit = 1;
byte++;
}
}
}
void botcol(void) {
for (int colbit = 0; colbit < 11; colbit++) {
unsigned int x = pgm_read_byte(&imagebot[byte]) & bit;
if (jekku) x = !x;
sendbot(x);
bit <<= 1;
if (!(bit & 0xff)) {
bit = 1;
byte++;
}
}
}
int main(void) {
clock_prescale_set(clock_div_1);
DATADDR = DATAPORTMASK;
ADDRDDR = ADDRPORTMASK;
// jekku vilkuttaa näyttöä käänteiseksi yo. funktioissa
jekku = 0;
int div = 5;
int max = 20;
unsigned char blinkcnt = 0;
for (;;) {
for (int rivi = 0; rivi < 3; rivi++) {
byte = rivi == 2 ? (2*24*12 / 8) : 0; // reunarivihän oli muita lyhyempi, skippaa kaksi moduulia
bit = 1;
for (int colblk = 0; colblk < (rivi == 2 ? 8 : 16); colblk++) { // 16 * 6 = 96 = 4 * 24
for (int p = 0; p < 4; p++) sendtop(0);
for (int c = 0; c < 6; c++) topcol();
for (int p = 0; p < 4; p++) sendtop(0);
}
byte = 0;
bit = 1;
for (int colblk = 0; colblk < (rivi == 2 ? 2 : 4); colblk++) { // 4 * (10 + 10 + 4) = 96
for (int p = 0; p < 36; p++) sendbot(0);
for (int c = 0; c < 4; c++) botcol();
for (int p = 0; p < 5; p++) sendbot(0);
for (int c = 0; c < 10; c++) botcol();
for (int p = 0; p < 10; p++) sendbot(0);
for (int c = 0; c < 10; c++) botcol();
for (int p = 0; p < 5; p++) sendbot(0);
}
address(SEITE0, _BV(rivi));
LATCHDELAY();
address(0, 0);
}
jekku = blinkcnt < div;
blinkcnt++;
if (blinkcnt == max) blinkcnt = 0;
}
}