avr-game

annotate dotmatrix.c @ 2:363acf3e61d4

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