2 // YOU MUST COMPILE THIS WITH -O3 OR THE AVR WILL NOT BE ABLE TO KEEP UP!!!!
\r
5 //#define F_CPU 3960000
\r
6 #define F_CPU 12000000
\r
8 #if !defined(__AVR_AT94K__)
\r
9 #error you forgot to put -mmcu=at94k on the command line
\r
12 #include <avr/wdt.h>
\r
13 #include <util/delay.h>
\r
15 #include <avr/interrupt.h>
\r
19 void initUART0(unsigned int baudRate, unsigned int doubleRate) {
\r
20 UBRRHI = (((baudRate) >> 8) & 0x000F);
\r
21 UBRR0 = ((baudRate) & 0x00FF);
\r
22 UCSR0B |= ((1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0));
\r
25 UCSR0A |= (1 << U2X0);
\r
27 UCSR0A &= ~(1 << U2X0);
\r
30 #define BUFSIZE (1024)
\r
32 inline void portd(int bit, int on) {
\r
42 long int numread = 0;
\r
43 inline void cts(int c) {
\r
45 if (c /*&& numread < 10000*/) {
\r
57 static volatile int sending = 0;
\r
58 static volatile int32_t interrupt_count = 0;
\r
60 // RECV //////////////////////////////////////////////////////////////////////////////
\r
62 char read_buf[BUFSIZE];
\r
63 volatile int read_buf_head;
\r
64 volatile int read_buf_tail;
\r
65 char write_buf[BUFSIZE];
\r
66 volatile int write_buf_head;
\r
67 volatile int write_buf_tail;
\r
69 inline int inc(int x) { x++; if (x>=BUFSIZE) x=0; return x; }
\r
70 inline int read_full() { return inc(read_buf_tail)==read_buf_head; }
\r
71 inline int abs(int x) { return x<0 ? -x : x; }
\r
72 inline int read_size() { return read_buf_tail<read_buf_head ? (read_buf_head-read_buf_tail) : (read_buf_tail-read_buf_head); }
\r
73 inline int read_empty() { return read_buf_head==read_buf_tail; }
\r
74 inline int read_nearlyFull() {
\r
75 if (read_buf_tail==read_buf_head) return 0;
\r
76 if (read_buf_tail < read_buf_head) return (read_buf_head-read_buf_tail) < (BUFSIZE/2);
\r
77 return (read_buf_tail-read_buf_head) > (BUFSIZE/2);
\r
80 inline int write_full() { return inc(write_buf_tail)==write_buf_head; }
\r
81 inline int write_empty() { return write_buf_head==write_buf_tail; }
\r
82 inline int write_nearlyFull() {
\r
83 if (write_buf_tail==write_buf_head) return 0;
\r
84 if (write_buf_tail < write_buf_head) return (write_buf_head-write_buf_tail) < (BUFSIZE/2);
\r
85 return (write_buf_tail-write_buf_head) > (BUFSIZE/2);
\r
88 inline char recv() {
\r
91 while(read_empty()) cts(1);
\r
92 ret = read_buf[read_buf_head];
\r
93 read_buf_head = inc(read_buf_head);
\r
94 if (!read_nearlyFull()) cts(1);
\r
98 ISR(SIG_UART0_DATA) {
\r
99 if (write_empty()) {
\r
100 UCSR0B &= ~(1 << UDRIE0);
\r
103 char ret = write_buf[write_buf_head];
\r
104 write_buf_head = inc(write_buf_head);
\r
109 void send(char c) {
\r
110 while (write_full());
\r
111 write_buf[write_buf_tail] = c;
\r
112 write_buf_tail = inc(write_buf_tail);
\r
113 if (PORTE & (1<<2)) PORTE &= ~(1<<2);
\r
114 else PORTE |= (1<<2);
\r
115 UCSR0B |= (1 << UDRIE0);
\r
116 if (PORTE & (1<<3)) PORTE &= ~(1<<3);
\r
117 else PORTE |= (1<<3);
\r
121 void fpga_interrupts(int on) {
\r
122 if (on/* && interrupt_count<301*/) {
\r
135 write_buf_head = 0;
\r
136 write_buf_tail = 0;
\r
137 //initUART0(1, 0); //for slow board
\r
138 initUART0(0, 0); //for slow board
\r
139 //initUART0(0, 1); //for slow board
\r
142 void conf(int z, int y, int x, int d) {
\r
151 for(i=0; i<5; i++) {
\r
162 wdt_enable(WDTO_250MS);
\r
166 #define TIMERVAL 100
\r
169 ISR(SIG_FPGA_INTERRUPT15) {
\r
172 //PORTD = ~(interrupt_count & 0xff);
\r
173 //if (interrupt_count >= 301) fpga_interrupts(0);
\r
175 fpga_interrupts(1);
\r
178 ISR(SIG_OVERFLOW0) {
\r
179 fpga_interrupts(0);
\r
181 TCNT0 = TIMERVAL; // load the nearest-to-one-second value into the timer0
\r
182 TIMSK |= (1<<TOIE0); // enable the compare match1 interrupt and the timer/counter0 overflow interrupt
\r
183 if (sending) UDR1 = FISUA;
\r
184 fpga_interrupts(1);
\r
187 void init_timer() {
\r
188 TCCR0 |= (1<<CS00); // set the timer0 prescaler to CK
\r
189 TCNT0 = TIMERVAL; // load the nearest-to-one-second value into the timer0
\r
190 TIMSK |= (1<<TOIE0); //enable the compare match1 interrupt and the timer/counter0 overflow interrupt
\r
193 ISR(SIG_INTERRUPT0) { // use interrupt1 since interrupt0 is sent by the watchdog (I think)
\r
198 void die() { cli(); cts(0); _delay_ms(2000); while(1) { portd(2,0); portd(2,1); } }
\r
200 ISR(SIG_UART0_RECV) {
\r
202 if (UCSR0A & (1 << FE0)) err = 201;//{ portd(2,0); portd(3,1); die(); } // framing error, lock up with LED=01
\r
203 if ((UCSR0A & (1 << OR0))) err = 202;//{ portd(2,1); portd(3,0); die(); } // overflow; lock up with LED=10
\r
204 if (read_full()) err = 203;//{ portd(2,1); portd(3,1); die(); } // buffer overrun
\r
206 read_buf[read_buf_tail] = UDR0;
\r
207 read_buf_tail = inc(read_buf_tail);
\r
208 if (read_nearlyFull()) cts(0);
\r
213 inline int hex(char c) {
\r
214 if (c >= '0' && c <= '9') return (c - '0');
\r
215 if (c >= 'a' && c <= 'f') return ((c - 'a') + 0xa);
\r
216 if (c >= 'A' && c <= 'F') return ((c - 'A') + 0xa);
\r
221 DDRE = (1<<7) | (1<<5) | (1<<4) | (1<<3) | (1<<2);
\r
241 long int i = recv() & 0xff;
\r
242 //if (i < 0) err = 200;
\r
244 long int newi = oldi+1;
\r
245 if (newi >= 256) newi -= 256;
\r
246 if (i != newi) err++;
\r
250 send(err >= 10 ? 255 : i);
\r
266 //while(1) send(/*FISUA*/2);
\r
269 if (PORTE & (1<<6)) PORTE &= ~(1<<6);
\r
270 else PORTE |= (1<<6);
\r
285 //fpga_interrupts(0);
\r
289 //fpga_interrupts(1);
\r
302 int32_t local_interrupt_count = interrupt_count;
\r
303 interrupt_count = 0;
\r
304 send((local_interrupt_count >> 24) & 0xff);
\r
305 send((local_interrupt_count >> 16) & 0xff);
\r
306 send((local_interrupt_count >> 8) & 0xff);
\r
307 send((local_interrupt_count >> 0) & 0xff);
\r
308 fpga_interrupts(1);
\r
314 if ((r & 0x80) == 0x80) {
\r
315 switch (r & 0x44) {
\r
316 case 0x44: z = recv(); break;
\r
317 case 0x40: z++; break;
\r
318 case 0x04: z--; break;
\r
320 switch (r & 0x22) {
\r
321 case 0x22: y = recv(); break;
\r
322 case 0x20: y++; break;
\r
323 case 0x02: y--; break;
\r
325 switch (r & 0x11) {
\r
326 case 0x11: x = recv(); break;
\r
327 case 0x10: x++; break;
\r
328 case 0x01: x--; break;
\r