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_ */