-//\r
-// YOU MUST COMPILE THIS WITH -O3 OR THE AVR WILL NOT BE ABLE TO KEEP UP!!!!\r
-//\r
-\r
-#define F_CPU 12000000\r
-\r
-#if !defined(__AVR_AT94K__)\r
-#error you forgot to put -mmcu=at94k on the command line\r
-#endif\r
-\r
-#include <avr/wdt.h>\r
-#include <util/delay.h>\r
-#include <avr/io.h>\r
-#include <avr/interrupt.h>\r
-\r
-volatile int32_t upper = 0;\r
-\r
-int err = 0;\r
-\r
-void initUART0(unsigned int baudRate, unsigned int doubleRate) {\r
- UBRRHI = (((baudRate) >> 8) & 0x000F); \r
- UBRR0 = ((baudRate) & 0x00FF); \r
- UCSR0B |= ((1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0)); \r
-\r
- if (doubleRate)\r
- UCSR0A |= (1 << U2X0);\r
- else\r
- UCSR0A &= ~(1 << U2X0);\r
-}\r
-\r
-#define BUFSIZE (1024)\r
-\r
-long int numread = 0;\r
-inline void cts(int c) {\r
- numread++;\r
- if (c) {\r
- PORTE &= ~(1 << 7);\r
- } else {\r
- PORTE |= (1 << 7);\r
- }\r
-}\r
-\r
-\r
-static volatile int sending = 0;\r
-static volatile int32_t interrupt_count = 0;\r
-\r
-// RECV //////////////////////////////////////////////////////////////////////////////\r
-\r
-char read_buf[BUFSIZE];\r
-volatile int read_buf_head;\r
-volatile int read_buf_tail;\r
-char write_buf[BUFSIZE];\r
-volatile int write_buf_head;\r
-volatile int write_buf_tail;\r
-\r
-inline int inc(int x) { x++; if (x>=BUFSIZE) x=0; return x; }\r
-inline int read_full() { return inc(read_buf_tail)==read_buf_head; }\r
-inline int abs(int x) { return x<0 ? -x : x; }\r
-inline int read_size() { return read_buf_tail<read_buf_head ? (read_buf_head-read_buf_tail) : (read_buf_tail-read_buf_head); }\r
-inline int read_empty() { return read_buf_head==read_buf_tail; }\r
-inline int read_nearlyFull() {\r
- if (read_buf_tail==read_buf_head) return 0;\r
- if (read_buf_tail < read_buf_head) return (read_buf_head-read_buf_tail) < (BUFSIZE/2);\r
- return (read_buf_tail-read_buf_head) > (BUFSIZE/2);\r
-}\r
-\r
-inline int write_full() { return inc(write_buf_tail)==write_buf_head; }\r
-inline int write_empty() { return write_buf_head==write_buf_tail; }\r
-inline int write_nearlyFull() {\r
- if (write_buf_tail==write_buf_head) return 0;\r
- if (write_buf_tail < write_buf_head) return (write_buf_head-write_buf_tail) < (BUFSIZE/2);\r
- return (write_buf_tail-write_buf_head) > (BUFSIZE/2);\r
-}\r
-\r
-int32_t timer = 0;\r
-\r
-inline char recv() {\r
- int q;\r
- char ret;\r
-\r
- PORTE |= (1<<3);\r
- while(read_empty()) cts(1);\r
- PORTE &= ~(1<<3);\r
-\r
- ret = read_buf[read_buf_head];\r
- read_buf_head = inc(read_buf_head);\r
- if (!read_nearlyFull()) cts(1);\r
- return ret;\r
-}\r
-\r
-// Interrupt Handlers //////////////////////////////////////////////////////////////////////////////\r
-\r
-ISR(SIG_UART0_DATA) {\r
- if (write_empty()) {\r
- UCSR0B &= ~(1 << UDRIE0);\r
- return;\r
- }\r
- char ret = write_buf[write_buf_head];\r
- write_buf_head = inc(write_buf_head);\r
- UDR0 = (int)ret;\r
- sei();\r
-}\r
-\r
-void send(char c) {\r
- PORTE |= (1<<2);\r
- while (write_full());\r
- PORTE &= ~(1<<2);\r
- write_buf[write_buf_tail] = c;\r
- write_buf_tail = inc(write_buf_tail);\r
- UCSR0B |= (1 << UDRIE0);\r
-}\r
-\r
-\r
-void fpga_interrupts(int on) {\r
- if (on) {\r
- //FISUA = 0x1;\r
- FISCR = 0x80;\r
- FISUA = 0x01;\r
- } else {\r
- FISUA = 0;\r
- FISCR = 0;\r
- }\r
-}\r
-\r
-inline void conf(int z, int y, int x, int d) {\r
- FPGAX = x;\r
- FPGAY = y;\r
- FPGAZ = z;\r
- FPGAD = d;\r
-}\r
-\r
-#define TIMERVAL 100\r
-\r
-ISR(SIG_FPGA_INTERRUPT0) { \r
- interrupt_count++;\r
- sei();\r
-}\r
-\r
-volatile int dead = 0;\r
-\r
-ISR(SIG_OVERFLOW1) { \r
- upper = upper + 1;\r
-\r
- if (!dead) {\r
- if (PORTE & (1<<5)) PORTE &= ~(1<<5);\r
- else PORTE |= (1<<5);\r
- }\r
-\r
- TCNT1 = 0;\r
- sei();\r
-}\r
-\r
-//void die() { dead = 1; cli(); PORTE|=(1<<5); _delay_ms(2000); while(1) { } }\r
-\r
-void die(int two, int three, int five) {\r
- dead = 1;\r
- PORTE &~ ((1<<2) | (1<<3) | (1<<5));\r
- if (two) PORTE |= (1<<2);\r
- if (three) PORTE |= (1<<3);\r
- if (five) PORTE |= (1<<5);\r
- while(1) { }\r
-}\r
-\r
-ISR(SIG_UART0_RECV) {\r
- if (UCSR0A & (1 << FE0)) die(0, 0, 1);\r
- if ((UCSR0A & (1 << OR0))) die(1, 1, 1);\r
- if (read_full()) die(1, 0, 1);\r
-\r
- read_buf[read_buf_tail] = UDR0;\r
- read_buf_tail = inc(read_buf_tail);\r
- if (read_nearlyFull()) cts(0);\r
- SREG |= 0x80;\r
- sei();\r
-}\r
-\r
-inline int hex(char c) {\r
- if (c >= '0' && c <= '9') return (c - '0');\r
- if (c >= 'a' && c <= 'f') return ((c - 'a') + 0xa);\r
- if (c >= 'A' && c <= 'F') return ((c - 'A') + 0xa);\r
- return -1;\r
-}\r
-\r
-int readFPGA() {\r
- fpga_interrupts(0);\r
- int ret = FISUA;\r
- fpga_interrupts(1);\r
- return ret;\r
-}\r
-\r
-int main() {\r
- DDRE = (1<<7) | (1<<5) | (1<<3) | (1<<2);\r
- PORTE = 0;\r
-\r
- PORTE |= (1<<5);\r
-\r
- read_buf_head = 0;\r
- read_buf_tail = 0;\r
- write_buf_head = 0;\r
- write_buf_tail = 0;\r
- initUART0(1, 0); //for slow board\r
-\r
- EIMF = 0xFF;\r
- SREG = INT0;\r
- sei();\r
-\r
- TCNT1 = 0;\r
- TIFR&=~(1<<TOV1);\r
- TIMSK|=(1<<TOIE1);\r
- TCCR1B = 3;\r
-\r
- cts(0);\r
- cts(1);\r
-\r
- int x=0, y=0, z=0;\r
- int flag=0;\r
- for(;;) {\r
- int i, d=0;\r
- int r = recv();\r
- switch(r) {\r
- case 0:\r
- send('O');\r
- send('B');\r
- send('I');\r
- send('T');\r
- send('S');\r
- fpga_interrupts(1);\r
- if (flag) die(0, 1, 1);\r
- break;\r
-\r
- case 1:\r
- z = recv();\r
- y = recv();\r
- x = recv();\r
- d = recv();\r
- conf(z, y, x, d);\r
- break;\r
-\r
- case 2:\r
- flag=1;\r
- send(readFPGA());\r
- break;\r
-\r
- case 3: {\r
- int32_t local_interrupt_count = interrupt_count;\r
- interrupt_count = 0;\r
- send((local_interrupt_count >> 24) & 0xff);\r
- send((local_interrupt_count >> 16) & 0xff);\r
- send((local_interrupt_count >> 8) & 0xff);\r
- send((local_interrupt_count >> 0) & 0xff);\r
- \r
- int32_t local_timer = TCNT1;\r
- int32_t local_upper = upper;\r
- TCCR1B = 0;\r
- TIFR&=~(1<<TOV1);\r
- TIMSK|=(1<<TOIE1);\r
- upper = 0;\r
- TCNT1 = 0;\r
- TCCR1B = 3;\r
- send((local_upper >> 8) & 0xff);\r
- send((local_upper >> 0) & 0xff);\r
- send((local_timer >> 8) & 0xff);\r
- send((local_timer >> 0) & 0xff);\r
- break;\r
- }\r
-\r
- /*\r
- case 3:\r
- //init_timer();\r
- break;\r
- case 4:\r
- sending = 1;\r
- break;\r
- case 5:\r
- sending = 0;\r
- break;\r
- */\r
- }\r
- }\r
- return 0;\r
-\r
-} \r
-\r
+//
+// YOU MUST COMPILE THIS WITH -O3 OR THE AVR WILL NOT BE ABLE TO KEEP UP!!!!
+//
+
+#define F_CPU 12000000
+
+#if !defined(__AVR_AT94K__)
+#error you forgot to put -mmcu=at94k on the command line
+#endif
+
+#include <avr/wdt.h>
+#include <util/delay.h>
+#include <avr/io.h>
+#include <avr/interrupt.h>
+
+volatile int32_t upper = 0;
+
+int err = 0;
+
+void initUART0(unsigned int baudRate, unsigned int doubleRate) {
+ UBRRHI = (((baudRate) >> 8) & 0x000F);
+ UBRR0 = ((baudRate) & 0x00FF);
+ UCSR0B |= ((1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0));
+
+ if (doubleRate)
+ UCSR0A |= (1 << U2X0);
+ else
+ UCSR0A &= ~(1 << U2X0);
+}
+
+#define BUFSIZE (1024)
+
+long int numread = 0;
+inline void cts(int c) {
+ numread++;
+ if (c) {
+ PORTE &= ~(1 << 7);
+ } else {
+ PORTE |= (1 << 7);
+ }
+}
+
+
+static volatile int sending = 0;
+static volatile int32_t interrupt_count = 0;
+
+// RECV //////////////////////////////////////////////////////////////////////////////
+
+char read_buf[BUFSIZE];
+volatile int read_buf_head;
+volatile int read_buf_tail;
+char write_buf[BUFSIZE];
+volatile int write_buf_head;
+volatile int write_buf_tail;
+
+inline int inc(int x) { x++; if (x>=BUFSIZE) x=0; return x; }
+inline int read_full() { return inc(read_buf_tail)==read_buf_head; }
+inline int abs(int x) { return x<0 ? -x : x; }
+inline int read_size() { return read_buf_tail<read_buf_head ? (read_buf_head-read_buf_tail) : (read_buf_tail-read_buf_head); }
+inline int read_empty() { return read_buf_head==read_buf_tail; }
+inline int read_nearlyFull() {
+ if (read_buf_tail==read_buf_head) return 0;
+ if (read_buf_tail < read_buf_head) return (read_buf_head-read_buf_tail) < (BUFSIZE/2);
+ return (read_buf_tail-read_buf_head) > (BUFSIZE/2);
+}
+
+inline int write_full() { return inc(write_buf_tail)==write_buf_head; }
+inline int write_empty() { return write_buf_head==write_buf_tail; }
+inline int write_nearlyFull() {
+ if (write_buf_tail==write_buf_head) return 0;
+ if (write_buf_tail < write_buf_head) return (write_buf_head-write_buf_tail) < (BUFSIZE/2);
+ return (write_buf_tail-write_buf_head) > (BUFSIZE/2);
+}
+
+int32_t timer = 0;
+
+inline char recv() {
+ int q;
+ char ret;
+
+ PORTE |= (1<<3);
+ while(read_empty()) cts(1);
+ PORTE &= ~(1<<3);
+
+ ret = read_buf[read_buf_head];
+ read_buf_head = inc(read_buf_head);
+ if (!read_nearlyFull()) cts(1);
+ return ret;
+}
+
+// Interrupt Handlers //////////////////////////////////////////////////////////////////////////////
+
+ISR(SIG_UART0_DATA) {
+ if (write_empty()) {
+ UCSR0B &= ~(1 << UDRIE0);
+ return;
+ }
+ char ret = write_buf[write_buf_head];
+ write_buf_head = inc(write_buf_head);
+ UDR0 = (int)ret;
+ sei();
+}
+
+void send(char c) {
+ PORTE |= (1<<2);
+ while (write_full());
+ PORTE &= ~(1<<2);
+ write_buf[write_buf_tail] = c;
+ write_buf_tail = inc(write_buf_tail);
+ UCSR0B |= (1 << UDRIE0);
+}
+
+
+void fpga_interrupts(int on) {
+ if (on) {
+ //FISUA = 0x1;
+ FISCR = 0x80;
+ FISUA = 0x01;
+ } else {
+ FISUA = 0;
+ FISCR = 0;
+ }
+}
+
+inline void conf(int z, int y, int x, int d) {
+ FPGAX = x;
+ FPGAY = y;
+ FPGAZ = z;
+ FPGAD = d;
+}
+
+#define TIMERVAL 100
+
+ISR(SIG_FPGA_INTERRUPT0) {
+ interrupt_count++;
+ sei();
+}
+
+volatile int dead = 0;
+
+ISR(SIG_OVERFLOW1) {
+ upper = upper + 1;
+
+ if (!dead) {
+ if (PORTE & (1<<5)) PORTE &= ~(1<<5);
+ else PORTE |= (1<<5);
+ }
+
+ TCNT1 = 0;
+ sei();
+}
+
+//void die() { dead = 1; cli(); PORTE|=(1<<5); _delay_ms(2000); while(1) { } }
+
+void die(int two, int three, int five) {
+ dead = 1;
+ PORTE &~ ((1<<2) | (1<<3) | (1<<5));
+ if (two) PORTE |= (1<<2);
+ if (three) PORTE |= (1<<3);
+ if (five) PORTE |= (1<<5);
+ while(1) { }
+}
+
+ISR(SIG_UART0_RECV) {
+ if (UCSR0A & (1 << FE0)) die(0, 0, 1);
+ if ((UCSR0A & (1 << OR0))) die(1, 1, 1);
+ if (read_full()) die(1, 0, 1);
+
+ read_buf[read_buf_tail] = UDR0;
+ read_buf_tail = inc(read_buf_tail);
+ if (read_nearlyFull()) cts(0);
+ SREG |= 0x80;
+ sei();
+}
+
+inline int hex(char c) {
+ if (c >= '0' && c <= '9') return (c - '0');
+ if (c >= 'a' && c <= 'f') return ((c - 'a') + 0xa);
+ if (c >= 'A' && c <= 'F') return ((c - 'A') + 0xa);
+ return -1;
+}
+
+int readFPGA() {
+ fpga_interrupts(0);
+ int ret = FISUA;
+ fpga_interrupts(1);
+ return ret;
+}
+
+int main() {
+ DDRE = (1<<7) | (1<<5) | (1<<3) | (1<<2);
+ PORTE = 0;
+
+ PORTE |= (1<<5);
+
+ read_buf_head = 0;
+ read_buf_tail = 0;
+ write_buf_head = 0;
+ write_buf_tail = 0;
+ initUART0(1, 0); //for slow board
+
+ EIMF = 0xFF;
+ SREG = INT0;
+ sei();
+
+ TCNT1 = 0;
+ TIFR&=~(1<<TOV1);
+ TIMSK|=(1<<TOIE1);
+ TCCR1B = 3;
+
+ cts(0);
+ cts(1);
+
+ int x=0, y=0, z=0;
+ int flag=0;
+ for(;;) {
+ int i, d=0;
+ int r = recv();
+ switch(r) {
+ case 0:
+ send('O');
+ send('B');
+ send('I');
+ send('T');
+ send('S');
+ fpga_interrupts(1);
+ if (flag) die(0, 1, 1);
+ break;
+
+ case 1:
+ z = recv();
+ y = recv();
+ x = recv();
+ d = recv();
+ conf(z, y, x, d);
+ break;
+
+ case 2:
+ flag=1;
+ send(readFPGA());
+ break;
+
+ case 3: {
+ int32_t local_interrupt_count = interrupt_count;
+ interrupt_count = 0;
+ send((local_interrupt_count >> 24) & 0xff);
+ send((local_interrupt_count >> 16) & 0xff);
+ send((local_interrupt_count >> 8) & 0xff);
+ send((local_interrupt_count >> 0) & 0xff);
+
+ int32_t local_timer = TCNT1;
+ int32_t local_upper = upper;
+ TCCR1B = 0;
+ TIFR&=~(1<<TOV1);
+ TIMSK|=(1<<TOIE1);
+ upper = 0;
+ TCNT1 = 0;
+ TCCR1B = 3;
+ send((local_upper >> 8) & 0xff);
+ send((local_upper >> 0) & 0xff);
+ send((local_timer >> 8) & 0xff);
+ send((local_timer >> 0) & 0xff);
+ break;
+ }
+
+ /*
+ case 3:
+ //init_timer();
+ break;
+ case 4:
+ sending = 1;
+ break;
+ case 5:
+ sending = 0;
+ break;
+ */
+ }
+ }
+ return 0;
+
+}
+