eeprog

view eeprog.c @ 0:330f8891baed

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 02 Nov 2013 23:56:07 +0200
parents
children
line source
1 /* HW setup:
2 * EEPROM interface:
3 * Data bus [0, 7]: Port C
4 * Address bus [0, 7]: Port A
5 * [8, 10]: Port B [0, 2]
6 * ~OE: Port D [6]
7 * ~WE: Port D [7]
8 *
9 * Serial comm:
10 * TX: Port D [3] (TXD1)
11 * RX: Port D [2] (RXD1)
12 *
13 * 14.7456 MHz crystal connected to XTAL1/XTAL2
14 */
16 #include <stdio.h>
17 #include <string.h>
18 #include <ctype.h>
19 #include <avr/io.h>
20 #include <avr/interrupt.h>
21 #include <avr/power.h>
23 #define TIMER_OFF 0
24 #define PRESCL_1 1
25 #define PRESCL_8 2
26 #define PRESCL_64 3
27 #define PRESCL_256 4
28 #define PRESCL_1024 5
29 #define TIMER_EXT_FALL 6
30 #define TIMER_EXT_RISE 7
32 /* 1mhz internal osc */
33 /*#define CLOCK_FREQ 1000000*/
34 /* 14.7456 MHz crystal osc */
35 #define CLOCK_FREQ 14745600
36 /* 4 MHz crystal osc */
37 /*#define CLOCK_FREQ 4000000*/
39 #define BAUD 9600
40 #define UBRR_VAL (CLOCK_FREQ / 16 / BAUD - 1)
42 #define SEC_TICKS (CLOCK_FREQ / 256 / 256)
44 void init_serial(void);
45 void init_timer(void);
47 int uart_send_char(char c, FILE *fp);
48 int uart_get_char(FILE *fp);
50 void runcmd(const char *cmd);
52 #define BUF_SZ 32
53 static char outbuf[BUF_SZ];
54 static volatile int out_rd, out_wr;
56 static char inbuf[BUF_SZ];
57 static volatile int in_rd, in_wr;
59 static char linebuf[64];
60 static int line_cidx;
62 static FILE std_stream = FDEV_SETUP_STREAM(uart_send_char, uart_get_char, _FDEV_SETUP_RW);
64 int main(void)
65 {
66 stdin = stdout = stderr = &std_stream;
68 /* port B is our LED output */
69 DDRB = 0xff;
70 PORTB = 0;
72 init_timer();
73 init_serial();
74 sei();
76 fputs("eeprom programmer\n> ", stdout);
78 for(;;) {
79 int c = getchar();
80 putchar(c); /* echo back */
82 if(c == '\n') {
83 linebuf[line_cidx] = 0;
84 line_cidx = 0;
85 runcmd(linebuf);
87 fputs("> ", stdout);
89 } else if(line_cidx < sizeof linebuf - 1) {
90 linebuf[line_cidx++] = c;
91 }
92 }
94 return 0;
95 }
97 unsigned char peek(unsigned int addr)
98 {
99 return 42;
100 }
102 void poke(unsigned int addr, unsigned char data)
103 {
104 }
106 void init_serial(void)
107 {
108 power_usart0_enable();
110 /* make sure RX (D0) is input and TX (D1) is output */
111 DDRD = (DDRD & 0xfc) | 2;
113 /* set baud generator timer reset value */
114 UBRR0H = (unsigned char)(UBRR_VAL >> 8);
115 UBRR0L = (unsigned char)UBRR_VAL;
117 /* - enable receiver and transmitter
118 * - enable receive interrupt
119 */
120 UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0);
122 /* set frame format: 8N1 */
123 UCSR0C = (3 << UCSZ00);
124 }
126 #define NEXT_IDX(x) (((x) + 1) % BUF_SZ)
127 int uart_send_char(char c, FILE *fp)
128 {
129 int next;
131 if(c == '\n') {
132 uart_send_char('\r', fp);
133 }
135 next = NEXT_IDX(out_wr);
136 while(next == out_rd);
138 outbuf[out_wr] = c;
139 out_wr = next;
141 /* enable the Tx data register empty interrupt */
142 UCSR0B |= 1 << UDRIE0;
143 return 0;
144 }
146 int uart_get_char(FILE *fp)
147 {
148 char c;
149 int next = NEXT_IDX(in_rd);
151 while(in_rd == in_wr);
153 c = inbuf[in_rd];
154 in_rd = next;
155 return c;
156 }
158 void runcmd(const char *cmd)
159 {
160 unsigned int addr = 0;
161 unsigned int data = 0;
163 if(strcmp(cmd, "info") == 0) {
164 printf("Atmel ATmega644 8bit AVR microcontroller running at %ld Hz\n", CLOCK_FREQ);
165 } else if(sscanf(cmd, "peek %u", &addr) == 1) {
166 printf("%x\n", (unsigned int)peek(addr));
167 } else if(sscanf(cmd, "poke %u , %x", &addr, &data) == 2) {
168 poke(addr, data);
169 } else if(strcmp(cmd, "help") == 0) {
171 puts("Available commands:");
172 puts(" info print system info");
173 puts(" peek <addr> read a byte from a memory address");
174 puts(" poke <addr>, <byte> write a byte to a memory address");
175 puts(" help print this help screen");
177 } else {
178 printf("unknown command: %s\n", cmd);
179 }
180 }
182 void init_timer(void)
183 {
184 power_timer0_enable();
186 TCCR0A = 0;
187 TCCR0B = PRESCL_256;
189 /* enable timer overflow interrupt */
190 TIMSK0 = 1;
191 }
193 ISR(TIMER0_OVF_vect)
194 {
195 volatile static int ticks;
197 if(++ticks >= SEC_TICKS) {
198 int val = PORTB;
199 if(val & 1) {
200 PORTB &= ~1;
201 } else {
202 PORTB |= 1;
203 }
204 ticks = 0;
205 }
206 }
208 ISR(USART0_RX_vect)
209 {
210 char c = UDR0;
212 if(c == '\r') {
213 c = '\n';
214 }
216 inbuf[in_wr] = c;
217 in_wr = NEXT_IDX(in_wr);
218 }
220 /* USART Tx data register empty (can send more data) */
221 ISR(USART0_UDRE_vect)
222 {
223 if(out_rd != out_wr) {
224 UDR0 = outbuf[out_rd];
225 out_rd = NEXT_IDX(out_rd);
226 } else {
227 /* no more data to send for now, disable the interrupt */
228 UCSR0B &= ~(1 << UDRIE0);
229 }
230 }