eeprog

changeset 0:330f8891baed tip

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 02 Nov 2013 23:56:07 +0200
parents
children
files .hgignore Makefile eeprog.c
diffstat 3 files changed, 274 insertions(+), 0 deletions(-) [+]
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/.hgignore	Sat Nov 02 23:56:07 2013 +0200
     1.3 @@ -0,0 +1,6 @@
     1.4 +\.swp$
     1.5 +\.o$
     1.6 +\.hex$
     1.7 +\.eep$
     1.8 +\.map$
     1.9 +^eeprog$
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/Makefile	Sat Nov 02 23:56:07 2013 +0200
     2.3 @@ -0,0 +1,38 @@
     2.4 +src = $(wildcard *.c)
     2.5 +obj = $(src:.c=.o)
     2.6 +bin = eeprog
     2.7 +hex = $(bin).hex
     2.8 +eep = $(bin).eep
     2.9 +
    2.10 +mcu_gcc = atmega644p
    2.11 +mcu_dude = m644p
    2.12 +
    2.13 +CC = avr-gcc
    2.14 +OBJCOPY = avr-objcopy
    2.15 +
    2.16 +CFLAGS = -O2 -pedantic -Wall -mmcu=$(mcu_gcc)
    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: fuses
    2.32 +fuses:
    2.33 +	avrdude -c usbtiny -p $(mcu_dude) -U lfuse:w:0xe6:m
    2.34 +
    2.35 +.PHONY: program
    2.36 +program: $(hex)
    2.37 +	avrdude -c usbtiny -p $(mcu_dude) -e -U flash:w:$(hex)
    2.38 +
    2.39 +.PHONY: clean
    2.40 +clean:
    2.41 +	rm -f $(bin) $(obj) $(hex) $(eep) $(bin).map
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/eeprog.c	Sat Nov 02 23:56:07 2013 +0200
     3.3 @@ -0,0 +1,230 @@
     3.4 +/* HW setup:
     3.5 + * EEPROM interface:
     3.6 + *    Data bus [0, 7]: Port C
     3.7 + *    Address bus [0, 7]: Port A
     3.8 + *                [8, 10]: Port B [0, 2]
     3.9 + *    ~OE: Port D [6]
    3.10 + *    ~WE: Port D [7]
    3.11 + *
    3.12 + * Serial comm:
    3.13 + *    TX: Port D [3] (TXD1)
    3.14 + *    RX: Port D [2] (RXD1)
    3.15 + *
    3.16 + * 14.7456 MHz crystal connected to XTAL1/XTAL2
    3.17 + */
    3.18 +
    3.19 +#include <stdio.h>
    3.20 +#include <string.h>
    3.21 +#include <ctype.h>
    3.22 +#include <avr/io.h>
    3.23 +#include <avr/interrupt.h>
    3.24 +#include <avr/power.h>
    3.25 +
    3.26 +#define TIMER_OFF		0
    3.27 +#define PRESCL_1		1
    3.28 +#define PRESCL_8		2
    3.29 +#define PRESCL_64		3
    3.30 +#define PRESCL_256		4
    3.31 +#define PRESCL_1024		5
    3.32 +#define TIMER_EXT_FALL	6
    3.33 +#define TIMER_EXT_RISE	7
    3.34 +
    3.35 +/* 1mhz internal osc */
    3.36 +/*#define CLOCK_FREQ	1000000*/
    3.37 +/* 14.7456 MHz crystal osc */
    3.38 +#define CLOCK_FREQ	14745600
    3.39 +/* 4 MHz crystal osc */
    3.40 +/*#define CLOCK_FREQ		4000000*/
    3.41 +
    3.42 +#define BAUD		9600
    3.43 +#define UBRR_VAL	(CLOCK_FREQ / 16 / BAUD - 1)
    3.44 +
    3.45 +#define SEC_TICKS	(CLOCK_FREQ / 256 / 256)
    3.46 +
    3.47 +void init_serial(void);
    3.48 +void init_timer(void);
    3.49 +
    3.50 +int uart_send_char(char c, FILE *fp);
    3.51 +int uart_get_char(FILE *fp);
    3.52 +
    3.53 +void runcmd(const char *cmd);
    3.54 +
    3.55 +#define BUF_SZ	32
    3.56 +static char outbuf[BUF_SZ];
    3.57 +static volatile int out_rd, out_wr;
    3.58 +
    3.59 +static char inbuf[BUF_SZ];
    3.60 +static volatile int in_rd, in_wr;
    3.61 +
    3.62 +static char linebuf[64];
    3.63 +static int line_cidx;
    3.64 +
    3.65 +static FILE std_stream = FDEV_SETUP_STREAM(uart_send_char, uart_get_char, _FDEV_SETUP_RW);
    3.66 +
    3.67 +int main(void)
    3.68 +{
    3.69 +	stdin = stdout = stderr = &std_stream;
    3.70 +
    3.71 +	/* port B is our LED output */
    3.72 +	DDRB = 0xff;
    3.73 +	PORTB = 0;
    3.74 +
    3.75 +	init_timer();
    3.76 +	init_serial();
    3.77 +	sei();
    3.78 +
    3.79 +	fputs("eeprom programmer\n> ", stdout);
    3.80 +
    3.81 +	for(;;) {
    3.82 +		int c = getchar();
    3.83 +		putchar(c);		/* echo back */
    3.84 +
    3.85 +		if(c == '\n') {
    3.86 +			linebuf[line_cidx] = 0;
    3.87 +			line_cidx = 0;
    3.88 +			runcmd(linebuf);
    3.89 +
    3.90 +			fputs("> ", stdout);
    3.91 +
    3.92 +		} else if(line_cidx < sizeof linebuf - 1) {
    3.93 +			linebuf[line_cidx++] = c;
    3.94 +		}
    3.95 +	}
    3.96 +
    3.97 +	return 0;
    3.98 +}
    3.99 +
   3.100 +unsigned char peek(unsigned int addr)
   3.101 +{
   3.102 +	return 42;
   3.103 +}
   3.104 +
   3.105 +void poke(unsigned int addr, unsigned char data)
   3.106 +{
   3.107 +}
   3.108 +
   3.109 +void init_serial(void)
   3.110 +{
   3.111 +	power_usart0_enable();
   3.112 +
   3.113 +	/* make sure RX (D0) is input and TX (D1) is output */
   3.114 +	DDRD = (DDRD & 0xfc) | 2;
   3.115 +
   3.116 +	/* set baud generator timer reset value */
   3.117 +	UBRR0H = (unsigned char)(UBRR_VAL >> 8);
   3.118 +	UBRR0L = (unsigned char)UBRR_VAL;
   3.119 +
   3.120 +	/* - enable receiver and transmitter
   3.121 +	 * - enable receive interrupt
   3.122 +	 */
   3.123 +	UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0);
   3.124 +
   3.125 +	/* set frame format: 8N1 */
   3.126 +	UCSR0C = (3 << UCSZ00);
   3.127 +}
   3.128 +
   3.129 +#define NEXT_IDX(x)	(((x) + 1) % BUF_SZ)
   3.130 +int uart_send_char(char c, FILE *fp)
   3.131 +{
   3.132 +	int next;
   3.133 +
   3.134 +	if(c == '\n') {
   3.135 +		uart_send_char('\r', fp);
   3.136 +	}
   3.137 +
   3.138 +	next = NEXT_IDX(out_wr);
   3.139 +	while(next == out_rd);
   3.140 +
   3.141 +	outbuf[out_wr] = c;
   3.142 +	out_wr = next;
   3.143 +
   3.144 +	/* enable the Tx data register empty interrupt */
   3.145 +	UCSR0B |= 1 << UDRIE0;
   3.146 +	return 0;
   3.147 +}
   3.148 +
   3.149 +int uart_get_char(FILE *fp)
   3.150 +{
   3.151 +	char c;
   3.152 +	int next = NEXT_IDX(in_rd);
   3.153 +
   3.154 +	while(in_rd == in_wr);
   3.155 +
   3.156 +	c = inbuf[in_rd];
   3.157 +	in_rd = next;
   3.158 +	return c;
   3.159 +}
   3.160 +
   3.161 +void runcmd(const char *cmd)
   3.162 +{
   3.163 +	unsigned int addr = 0;
   3.164 +	unsigned int data = 0;
   3.165 +
   3.166 +	if(strcmp(cmd, "info") == 0) {
   3.167 +		printf("Atmel ATmega644 8bit AVR microcontroller running at %ld Hz\n", CLOCK_FREQ);
   3.168 +	} else if(sscanf(cmd, "peek %u", &addr) == 1) {
   3.169 +		printf("%x\n", (unsigned int)peek(addr));
   3.170 +	} else if(sscanf(cmd, "poke %u , %x", &addr, &data) == 2) {
   3.171 +		poke(addr, data);
   3.172 +	} else if(strcmp(cmd, "help") == 0) {
   3.173 +
   3.174 +		puts("Available commands:");
   3.175 +		puts(" info                 print system info");
   3.176 +		puts(" peek <addr>   		read a byte from a memory address");
   3.177 +		puts(" poke <addr>, <byte>  write a byte to a memory address");
   3.178 +		puts(" help                 print this help screen");
   3.179 +
   3.180 +	} else {
   3.181 +		printf("unknown command: %s\n", cmd);
   3.182 +	}
   3.183 +}
   3.184 +
   3.185 +void init_timer(void)
   3.186 +{
   3.187 +	power_timer0_enable();
   3.188 +
   3.189 +	TCCR0A = 0;
   3.190 +	TCCR0B = PRESCL_256;
   3.191 +
   3.192 +	/* enable timer overflow interrupt */
   3.193 +	TIMSK0 = 1;
   3.194 +}
   3.195 +
   3.196 +ISR(TIMER0_OVF_vect)
   3.197 +{
   3.198 +	volatile static int ticks;
   3.199 +
   3.200 +	if(++ticks >= SEC_TICKS) {
   3.201 +		int val = PORTB;
   3.202 +		if(val & 1) {
   3.203 +			PORTB &= ~1;
   3.204 +		} else {
   3.205 +			PORTB |= 1;
   3.206 +		}
   3.207 +		ticks = 0;
   3.208 +	}
   3.209 +}
   3.210 +
   3.211 +ISR(USART0_RX_vect)
   3.212 +{
   3.213 +	char c = UDR0;
   3.214 +
   3.215 +	if(c == '\r') {
   3.216 +		c = '\n';
   3.217 +	}
   3.218 +
   3.219 +	inbuf[in_wr] = c;
   3.220 +	in_wr = NEXT_IDX(in_wr);
   3.221 +}
   3.222 +
   3.223 +/* USART Tx data register empty (can send more data) */
   3.224 +ISR(USART0_UDRE_vect)
   3.225 +{
   3.226 +	if(out_rd != out_wr) {
   3.227 +		UDR0 = outbuf[out_rd];
   3.228 +		out_rd = NEXT_IDX(out_rd);
   3.229 +	} else {
   3.230 +		/* no more data to send for now, disable the interrupt */
   3.231 +		UCSR0B &= ~(1 << UDRIE0);
   3.232 +	}
   3.233 +}