avr-game
changeset 0:9db99968b55e
initial commit, screen test working
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Tue, 09 Sep 2014 04:40:47 +0300 |
parents | |
children | 872e425f0e7f |
files | .hgignore Makefile avrgame.c dotmatrix.c dotmatrix.h |
diffstat | 5 files changed, 295 insertions(+), 0 deletions(-) [+] |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/.hgignore Tue Sep 09 04:40:47 2014 +0300 1.3 @@ -0,0 +1,6 @@ 1.4 +\.o$ 1.5 +\.swp$ 1.6 +\.hex$ 1.7 +\.eep$ 1.8 +^avrgame$ 1.9 +\.map$
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/Makefile Tue Sep 09 04:40:47 2014 +0300 2.3 @@ -0,0 +1,34 @@ 2.4 +src = $(wildcard *.c) 2.5 +obj = $(src:.c=.o) 2.6 +bin = avrgame 2.7 +hex = $(bin).hex 2.8 +eep = $(bin).eep 2.9 + 2.10 +mcu_gcc = atmega328p 2.11 +mcu_dude = m328p 2.12 + 2.13 +CC = avr-gcc 2.14 +OBJCOPY = avr-objcopy 2.15 + 2.16 +CFLAGS = -O2 -pedantic -Wall -mmcu=$(mcu_gcc) -DF_CPU=1000000 2.17 +LDFLAGS = -Wl,-Map,$(bin).map -mmcu=$(mcu_gcc)# -Wl,-u,vfprintf -lprintf_flt -lm 2.18 + 2.19 +.PHONY: all 2.20 +all: $(hex) $(eep) 2.21 + 2.22 +$(bin): $(obj) 2.23 + $(CC) -o $@ $(obj) $(LDFLAGS) 2.24 + 2.25 +$(hex): $(bin) 2.26 + $(OBJCOPY) -j .text -j .data -O ihex -R .eeprom $< $@ 2.27 + 2.28 +$(eep): $(bin) 2.29 + $(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O ihex $< $@ 2.30 + 2.31 +.PHONY: program 2.32 +program: $(hex) 2.33 + avrdude -c usbtiny -p $(mcu_dude) -e -U flash:w:$(hex) 2.34 + 2.35 +.PHONY: clean 2.36 +clean: 2.37 + rm -f $(bin) $(obj) $(hex) $(eep) $(bin).map
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/avrgame.c Tue Sep 09 04:40:47 2014 +0300 3.3 @@ -0,0 +1,38 @@ 3.4 +#include <avr/io.h> 3.5 +#include <util/delay.h> 3.6 +#include "dotmatrix.h" 3.7 + 3.8 +/* hardware setup 3.9 + * - Port B[1,5]: lcd signals (see dotmatrix.h) 3.10 + * - B1: clk 3.11 + * - B2: Din 3.12 + * - B3: DC 3.13 + * - B4: CE 3.14 + * - B5: RST 3.15 + */ 3.16 + 3.17 +/*int lcd_stream_write(char c, FILE *fp);*/ 3.18 + 3.19 +/*FILE stream_lcd = FDEV_SETUP_STREAM(lcd_stream_write, NULL, _FDEV_SETUP_WRITE);*/ 3.20 + 3.21 +int main(void) 3.22 +{ 3.23 + /* stdout = stderr = &stream_lcd; */ 3.24 + 3.25 + dm_init(); 3.26 + dm_test(); 3.27 + 3.28 + for(;;) { 3.29 + _delay_ms(800); 3.30 + } 3.31 + 3.32 + return 0; 3.33 +} 3.34 + 3.35 +#if 0 3.36 +int lcd_stream_write(char c, FILE *fp) 3.37 +{ 3.38 + /* TODO terminal shit handling */ 3.39 + return 0; 3.40 +} 3.41 +#endif
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/dotmatrix.c Tue Sep 09 04:40:47 2014 +0300 4.3 @@ -0,0 +1,190 @@ 4.4 +#include <util/delay.h> 4.5 +#include "dotmatrix.h" 4.6 + 4.7 +enum { CMD, DATA }; 4.8 + 4.9 +#define CMD_DISPCTL(x) (((x) & 7) | (1 << 3)) 4.10 +#define CMD_FUNCSET(x) (((x) & 7) | (1 << 5)) 4.11 +#define CMD_SETY(x) (((x) & 7) | (1 << 6)) 4.12 +#define CMD_SETX(x) (((x) & 0x7f) | (1 << 7)) 4.13 + 4.14 +#define CMD_EXT_BIAS(x) (((x) & 7) | (1 << 4)) 4.15 +#define CMD_EXT_VOP(x) (((x) & 0x7f) | (1 << 7)) 4.16 + 4.17 +#define FSET_BASIC 0 4.18 +#define FSET_EXTENDED 1 4.19 +#define FSET_VERTICAL 2 4.20 +#define FSET_POWERDOWN 3 4.21 + 4.22 +#define DCTL_BLANK 0 4.23 +#define DCTL_NORMAL 4 4.24 +#define DCTL_ALL 1 4.25 +#define DCTL_INVERSE 5 4.26 + 4.27 +#define FRAME_BYTES ((DM_WIDTH / 8) * DM_HEIGHT) 4.28 + 4.29 +#define PINMASK \ 4.30 + ((1 << DM_PIN_CLK) | \ 4.31 + (1 << DM_PIN_DIN) | \ 4.32 + (1 << DM_PIN_DC) | \ 4.33 + (1 << DM_PIN_CE) | \ 4.34 + (1 << DM_PIN_RST)) 4.35 + 4.36 +#define SET(var, bit) ((var) |= 1 << (bit)) 4.37 +#define CLR(var, bit) ((var) &= ~(1 << (bit))) 4.38 + 4.39 +#define NOP() asm volatile ("nop") 4.40 + 4.41 +static void start_send(void); 4.42 +static void send(int type, unsigned char c); 4.43 +static void stop_send(void); 4.44 +static void send_byte(int type, unsigned char c); 4.45 + 4.46 +static int mode; 4.47 + 4.48 +int dm_init(void) 4.49 +{ 4.50 + int vop; 4.51 + 4.52 + DM_DDR |= PINMASK; /* set used pins as outputs */ 4.53 + SET(DM_PORT, DM_PIN_CE); 4.54 + SET(DM_PORT, DM_PIN_RST); 4.55 + 4.56 + /* reset the lcd controller */ 4.57 + CLR(DM_PORT, DM_PIN_RST); 4.58 + NOP(); 4.59 + SET(DM_PORT, DM_PIN_RST); 4.60 + 4.61 + /* set Vop (???) */ 4.62 + start_send(); 4.63 + send(CMD, CMD_FUNCSET(FSET_EXTENDED)); 4.64 + send(CMD, CMD_EXT_VOP(80)); 4.65 + 4.66 + /* select function set (vertical addressing, basic set) */ 4.67 + send(CMD, CMD_FUNCSET(FSET_VERTICAL | FSET_BASIC)); 4.68 + 4.69 + /* enable display (normal mode) */ 4.70 + mode = DCTL_NORMAL; 4.71 + send(CMD, CMD_DISPCTL(mode)); 4.72 + stop_send(); 4.73 + 4.74 + dm_clear(0); 4.75 + 4.76 + return 0; 4.77 +} 4.78 + 4.79 +/* fill the screen with a test pattern */ 4.80 +void dm_test(void) 4.81 +{ 4.82 + static const unsigned char pattern[] = { 4.83 + 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 4.84 + 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 4.85 + 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 4.86 + 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 4.87 + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 4.88 + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 4.89 + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 4.90 + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f 4.91 + }; 4.92 + int i; 4.93 + 4.94 + for(i=0; i<DM_HEIGHT / 8; i++) { 4.95 + dm_copy(0, i * 8, pattern, sizeof pattern); 4.96 + } 4.97 + dm_copy(0, DM_HEIGHT - 4, pattern, 6 * 4); 4.98 +} 4.99 + 4.100 +void dm_invert(void) 4.101 +{ 4.102 + mode = (mode & 0xfe) | ((~mode) & 1); 4.103 + send_byte(CMD, CMD_DISPCTL(mode)); 4.104 +} 4.105 + 4.106 +void dm_clear(unsigned char val) 4.107 +{ 4.108 + int i; 4.109 + 4.110 + start_send(); 4.111 + send(CMD, CMD_SETY(0)); 4.112 + send(CMD, CMD_SETX(0)); 4.113 + 4.114 + for(i=0; i<FRAME_BYTES; i++) { 4.115 + send(DATA, val); 4.116 + } 4.117 + stop_send(); 4.118 +} 4.119 + 4.120 +void dm_copy(int x, int y, const unsigned char *fb, int bytes) 4.121 +{ 4.122 + int i; 4.123 + 4.124 + if(bytes <= 0 || bytes > FRAME_BYTES) { 4.125 + bytes = FRAME_BYTES; 4.126 + } 4.127 + 4.128 + start_send(); 4.129 + send(CMD, CMD_SETY(x / 8)); 4.130 + send(CMD, CMD_SETX(y)); 4.131 + 4.132 + for(i=0; i<bytes; i++) { 4.133 + send(DATA, *fb++); 4.134 + } 4.135 + stop_send(); 4.136 +} 4.137 + 4.138 +static void start_send(void) 4.139 +{ 4.140 + /* start by pulling CE low */ 4.141 + CLR(DM_PORT, DM_PIN_CE); 4.142 + 4.143 + /* enable SPI, master, clock/4, setup-falling, sample-rising, MSB-first */ 4.144 + SPCR = (1 << SPE) | (1 << MSTR); 4.145 +} 4.146 + 4.147 +static void stop_send(void) 4.148 +{ 4.149 + SPCR = 0; 4.150 + 4.151 + /* end transfer by pulling CE high again */ 4.152 + SET(DM_PORT, DM_PIN_CE); 4.153 +} 4.154 + 4.155 +static void send(int type, unsigned char c) 4.156 +{ 4.157 + int i; 4.158 + unsigned char bmask; 4.159 + 4.160 + if(type == CMD) { 4.161 + CLR(DM_PORT, DM_PIN_DC); 4.162 + } else { 4.163 + SET(DM_PORT, DM_PIN_DC); 4.164 + } 4.165 + 4.166 + SPDR = c; 4.167 + while(!(SPSR & (1 << SPIF))); 4.168 + 4.169 + /* bitbang */ 4.170 + /* 4.171 + bmask = 1 << 7; 4.172 + for(i=0; i<8; i++) { 4.173 + CLR(DM_PORT, DM_PIN_CLK); 4.174 + 4.175 + if(c & bmask) { 4.176 + SET(DM_PORT, DM_PIN_DIN); 4.177 + } else { 4.178 + CLR(DM_PORT, DM_PIN_DIN); 4.179 + } 4.180 + bmask >>= 1; 4.181 + 4.182 + SET(DM_PORT, DM_PIN_CLK); 4.183 + NOP(); 4.184 + } 4.185 + */ 4.186 +} 4.187 + 4.188 +static void send_byte(int type, unsigned char c) 4.189 +{ 4.190 + start_send(); 4.191 + send(type, c); 4.192 + stop_send(); 4.193 +}
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/dotmatrix.h Tue Sep 09 04:40:47 2014 +0300 5.3 @@ -0,0 +1,27 @@ 5.4 +#ifndef DOTMATRIX_H_ 5.5 +#define DOTMATRIX_H_ 5.6 + 5.7 +#include <avr/io.h> 5.8 + 5.9 +/* change these port/pin assignments to match the circuit */ 5.10 +#define DM_PORT PORTB 5.11 +#define DM_DDR DDRB 5.12 +#define DM_PIN_CLK 5 /* sck */ 5.13 +#define DM_PIN_DIN 3 /* mosi */ 5.14 +#define DM_PIN_DC 1 5.15 +#define DM_PIN_CE 2 5.16 +#define DM_PIN_RST 0 5.17 +/* end of config block, don't touch anything below */ 5.18 + 5.19 +#define DM_WIDTH 48 5.20 +#define DM_HEIGHT 84 5.21 + 5.22 +int dm_init(void); 5.23 +void dm_test(void); 5.24 + 5.25 +void dm_invert(void); 5.26 + 5.27 +void dm_clear(unsigned char val); 5.28 +void dm_copy(int x, int y, const unsigned char *fb, int bytes); 5.29 + 5.30 +#endif /* DOTMATRIX_H_ */