avr-game

view dotmatrix.c @ 2:363acf3e61d4

wha?
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 20 Mar 2015 21:03:38 +0200
parents 9db99968b55e
children
line source
1 #include <util/delay.h>
2 #include "dotmatrix.h"
4 enum { CMD, DATA };
6 #define CMD_DISPCTL(x) (((x) & 7) | (1 << 3))
7 #define CMD_FUNCSET(x) (((x) & 7) | (1 << 5))
8 #define CMD_SETY(x) (((x) & 7) | (1 << 6))
9 #define CMD_SETX(x) (((x) & 0x7f) | (1 << 7))
11 #define CMD_EXT_BIAS(x) (((x) & 7) | (1 << 4))
12 #define CMD_EXT_VOP(x) (((x) & 0x7f) | (1 << 7))
14 #define FSET_BASIC 0
15 #define FSET_EXTENDED 1
16 #define FSET_VERTICAL 2
17 #define FSET_POWERDOWN 3
19 #define DCTL_BLANK 0
20 #define DCTL_NORMAL 4
21 #define DCTL_ALL 1
22 #define DCTL_INVERSE 5
24 #define FRAME_BYTES ((DM_WIDTH / 8) * DM_HEIGHT)
26 #define PINMASK \
27 ((1 << DM_PIN_CLK) | \
28 (1 << DM_PIN_DIN) | \
29 (1 << DM_PIN_DC) | \
30 (1 << DM_PIN_CE) | \
31 (1 << DM_PIN_RST))
33 #define SET(var, bit) ((var) |= 1 << (bit))
34 #define CLR(var, bit) ((var) &= ~(1 << (bit)))
36 #define NOP() asm volatile ("nop")
38 static void start_send(void);
39 static void send(int type, unsigned char c);
40 static void stop_send(void);
41 static void send_byte(int type, unsigned char c);
43 static int mode;
45 int dm_init(void)
46 {
47 DM_DDR |= PINMASK; /* set used pins as outputs */
48 SET(DM_PORT, DM_PIN_CE);
49 SET(DM_PORT, DM_PIN_RST);
51 /* reset the lcd controller */
52 CLR(DM_PORT, DM_PIN_RST);
53 NOP();
54 SET(DM_PORT, DM_PIN_RST);
56 /* set Vop (???) */
57 start_send();
58 send(CMD, CMD_FUNCSET(FSET_EXTENDED));
59 send(CMD, CMD_EXT_VOP(78));
61 /* select function set (vertical addressing, basic set) */
62 send(CMD, CMD_FUNCSET(FSET_VERTICAL | FSET_BASIC));
64 /* enable display (normal mode) */
65 mode = DCTL_NORMAL;
66 send(CMD, CMD_DISPCTL(mode));
67 stop_send();
69 dm_clear(0);
71 return 0;
72 }
74 /* fill the screen with a test pattern */
75 void dm_test(void)
76 {
77 static const unsigned char pattern[] = {
78 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
79 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
80 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
81 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
82 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
83 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
84 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
85 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f
86 };
87 int i;
89 for(i=0; i<DM_HEIGHT / 8; i++) {
90 dm_copy(0, i * 8, pattern, sizeof pattern);
91 }
92 dm_copy(0, DM_HEIGHT - 4, pattern, 6 * 4);
93 }
95 void dm_invert(void)
96 {
97 mode = (mode & 0xfe) | ((~mode) & 1);
98 send_byte(CMD, CMD_DISPCTL(mode));
99 }
101 void dm_clear(unsigned char val)
102 {
103 int i;
105 start_send();
106 send(CMD, CMD_SETY(0));
107 send(CMD, CMD_SETX(0));
109 for(i=0; i<FRAME_BYTES; i++) {
110 send(DATA, val);
111 }
112 stop_send();
113 }
115 void dm_copy(int x, int y, const unsigned char *fb, int bytes)
116 {
117 int i;
119 if(bytes <= 0 || bytes > FRAME_BYTES) {
120 bytes = FRAME_BYTES;
121 }
123 start_send();
124 send(CMD, CMD_SETY(x / 8));
125 send(CMD, CMD_SETX(y));
127 for(i=0; i<bytes; i++) {
128 send(DATA, *fb++);
129 }
130 stop_send();
131 }
133 static void start_send(void)
134 {
135 /* start by pulling CE low */
136 CLR(DM_PORT, DM_PIN_CE);
138 /* enable SPI, master, clock/4, setup-falling, sample-rising, MSB-first */
139 SPCR = (1 << SPE) | (1 << MSTR);
140 }
142 static void stop_send(void)
143 {
144 SPCR = 0;
146 /* end transfer by pulling CE high again */
147 SET(DM_PORT, DM_PIN_CE);
148 }
150 static void send(int type, unsigned char c)
151 {
152 int i;
153 unsigned char bmask;
155 if(type == CMD) {
156 CLR(DM_PORT, DM_PIN_DC);
157 } else {
158 SET(DM_PORT, DM_PIN_DC);
159 }
161 SPDR = c;
162 while(!(SPSR & (1 << SPIF)));
164 /* bitbang */
165 /*
166 bmask = 1 << 7;
167 for(i=0; i<8; i++) {
168 CLR(DM_PORT, DM_PIN_CLK);
170 if(c & bmask) {
171 SET(DM_PORT, DM_PIN_DIN);
172 } else {
173 CLR(DM_PORT, DM_PIN_DIN);
174 }
175 bmask >>= 1;
177 SET(DM_PORT, DM_PIN_CLK);
178 NOP();
179 }
180 */
181 }
183 static void send_byte(int type, unsigned char c)
184 {
185 start_send();
186 send(type, c);
187 stop_send();
188 }