2 // YOU MUST COMPILE THIS WITH -O3 OR THE AVR WILL NOT BE ABLE TO KEEP UP!!!!
7 #if !defined(__AVR_AT94K__)
8 #error you forgot to put -mmcu=at94k on the command line
12 #include <util/delay.h>
14 #include <avr/interrupt.h>
16 volatile int32_t upper = 0;
20 void initUART0(unsigned int baudRate, unsigned int doubleRate) {
21 UBRRHI = (((baudRate) >> 8) & 0x000F);
22 UBRR0 = ((baudRate) & 0x00FF);
23 UCSR0B |= ((1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0));
26 UCSR0A |= (1 << U2X0);
28 UCSR0A &= ~(1 << U2X0);
31 #define BUFSIZE (1024)
34 inline void cts(int c) {
44 static volatile int sending = 0;
45 static volatile int32_t interrupt_count = 0;
47 // RECV //////////////////////////////////////////////////////////////////////////////
49 char read_buf[BUFSIZE];
50 volatile int read_buf_head;
51 volatile int read_buf_tail;
52 char write_buf[BUFSIZE];
53 volatile int write_buf_head;
54 volatile int write_buf_tail;
56 inline int inc(int x) { x++; if (x>=BUFSIZE) x=0; return x; }
57 inline int read_full() { return inc(read_buf_tail)==read_buf_head; }
58 inline int abs(int x) { return x<0 ? -x : x; }
59 inline int read_size() { return read_buf_tail<read_buf_head ? (read_buf_head-read_buf_tail) : (read_buf_tail-read_buf_head); }
60 inline int read_empty() { return read_buf_head==read_buf_tail; }
61 inline int read_nearlyFull() {
62 if (read_buf_tail==read_buf_head) return 0;
63 if (read_buf_tail < read_buf_head) return (read_buf_head-read_buf_tail) < (BUFSIZE/2);
64 return (read_buf_tail-read_buf_head) > (BUFSIZE/2);
67 inline int write_full() { return inc(write_buf_tail)==write_buf_head; }
68 inline int write_empty() { return write_buf_head==write_buf_tail; }
69 inline int write_nearlyFull() {
70 if (write_buf_tail==write_buf_head) return 0;
71 if (write_buf_tail < write_buf_head) return (write_buf_head-write_buf_tail) < (BUFSIZE/2);
72 return (write_buf_tail-write_buf_head) > (BUFSIZE/2);
82 while(read_empty()) cts(1);
85 ret = read_buf[read_buf_head];
86 read_buf_head = inc(read_buf_head);
87 if (!read_nearlyFull()) cts(1);
91 // Interrupt Handlers //////////////////////////////////////////////////////////////////////////////
95 UCSR0B &= ~(1 << UDRIE0);
98 char ret = write_buf[write_buf_head];
99 write_buf_head = inc(write_buf_head);
106 while (write_full());
108 write_buf[write_buf_tail] = c;
109 write_buf_tail = inc(write_buf_tail);
110 UCSR0B |= (1 << UDRIE0);
114 void fpga_interrupts(int on) {
125 inline void conf(int z, int y, int x, int d) {
134 ISR(SIG_FPGA_INTERRUPT0) {
139 volatile int dead = 0;
145 if (PORTE & (1<<5)) PORTE &= ~(1<<5);
146 else PORTE |= (1<<5);
153 //void die() { dead = 1; cli(); PORTE|=(1<<5); _delay_ms(2000); while(1) { } }
155 void die(int two, int three, int five) {
157 PORTE &~ ((1<<2) | (1<<3) | (1<<5));
158 if (two) PORTE |= (1<<2);
159 if (three) PORTE |= (1<<3);
160 if (five) PORTE |= (1<<5);
164 ISR(SIG_UART0_RECV) {
165 if (UCSR0A & (1 << FE0)) die(0, 0, 1);
166 if ((UCSR0A & (1 << OR0))) die(1, 1, 1);
167 if (read_full()) die(1, 0, 1);
169 read_buf[read_buf_tail] = UDR0;
170 read_buf_tail = inc(read_buf_tail);
171 if (read_nearlyFull()) cts(0);
176 inline int hex(char c) {
177 if (c >= '0' && c <= '9') return (c - '0');
178 if (c >= 'a' && c <= 'f') return ((c - 'a') + 0xa);
179 if (c >= 'A' && c <= 'F') return ((c - 'A') + 0xa);
191 DDRE = (1<<7) | (1<<5) | (1<<3) | (1<<2);
200 initUART0(1, 0); //for slow board
227 if (flag) die(0, 1, 1);
244 int32_t local_interrupt_count = interrupt_count;
246 send((local_interrupt_count >> 24) & 0xff);
247 send((local_interrupt_count >> 16) & 0xff);
248 send((local_interrupt_count >> 8) & 0xff);
249 send((local_interrupt_count >> 0) & 0xff);
251 int32_t local_timer = TCNT1;
252 int32_t local_upper = upper;
259 send((local_upper >> 8) & 0xff);
260 send((local_upper >> 0) & 0xff);
261 send((local_timer >> 8) & 0xff);
262 send((local_timer >> 0) & 0xff);