#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
\r
#define BUFSIZE (1024)\r
\r
-inline void portd(int bit, int on) {\r
- /*\r
- if (on) {\r
- PORTD &= ~(1<<bit);\r
- } else {\r
- PORTD |= (1<<bit);\r
- }\r
- */\r
-}\r
-\r
long int numread = 0;\r
inline void cts(int c) {\r
numread++;\r
if (c) {\r
PORTE &= ~(1 << 7);\r
- portd(0, 0);\r
} else {\r
PORTE |= (1 << 7);\r
- portd(0, 1);\r
}\r
}\r
\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
- if (PORTE & (1<<3)) PORTE &= ~(1<<3);\r
- else PORTE |= (1<<3);\r
return ret;\r
}\r
\r
+// Interrupt Handlers //////////////////////////////////////////////////////////////////////////////\r
+\r
ISR(SIG_UART0_DATA) {\r
if (write_empty()) {\r
UCSR0B &= ~(1 << UDRIE0);\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
- if (PORTE & (1<<2)) PORTE &= ~(1<<2);\r
- else PORTE |= (1<<2);\r
UCSR0B |= (1 << UDRIE0);\r
}\r
\r
\r
void fpga_interrupts(int on) {\r
- if (on/* && interrupt_count<301*/) {\r
+ if (on) {\r
//FISUA = 0x1;\r
FISCR = 0x80;\r
- FISUD = 0x08;\r
+ FISUA = 0x01;\r
} else {\r
- FISUD = 0;\r
+ FISUA = 0;\r
FISCR = 0;\r
}\r
}\r
\r
-void init() {\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
- initUART0(0, 0); //for slow board\r
- //initUART0(0, 1); //for slow board\r
-}\r
-\r
-void conf(int z, int y, int x, int d) {\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
-void doreset() {\r
- int i;\r
- for(i=0; i<5; i++) {\r
- PORTD = ~0x01;\r
- _delay_ms(50);\r
- PORTD = ~0x02;\r
- _delay_ms(50);\r
- PORTD = ~0x04;\r
- _delay_ms(50);\r
- PORTD = ~0x08;\r
- _delay_ms(50);\r
- }\r
- PORTD = ~0x00;\r
- wdt_enable(WDTO_250MS);\r
- while(1) { }\r
-}\r
-\r
#define TIMERVAL 100\r
-int portdc = 0;\r
\r
-ISR(SIG_FPGA_INTERRUPT15) { \r
- PORTD = portdc++;\r
+ISR(SIG_FPGA_INTERRUPT0) { \r
interrupt_count++;\r
- //PORTD = ~(interrupt_count & 0xff);\r
- //if (interrupt_count >= 301) fpga_interrupts(0);\r
- //sei();\r
- fpga_interrupts(1);\r
-}\r
-/*\r
-ISR(SIG_OVERFLOW0) { \r
- fpga_interrupts(0);\r
- PORTD = ~FISUA;\r
- TCNT0 = TIMERVAL; // load the nearest-to-one-second value into the timer0\r
- TIMSK |= (1<<TOIE0); // enable the compare match1 interrupt and the timer/counter0 overflow interrupt\r
- if (sending) UDR1 = FISUA;\r
fpga_interrupts(1);\r
sei();\r
-} \r
-void init_timer() { \r
- TCCR0 |= (1<<CS00); // set the timer0 prescaler to CK\r
- TCNT0 = TIMERVAL; // load the nearest-to-one-second value into the timer0\r
- TIMSK |= (1<<TOIE0); //enable the compare match1 interrupt and the timer/counter0 overflow interrupt\r
-} \r
-*/\r
-ISR(SIG_INTERRUPT0) { // use interrupt1 since interrupt0 is sent by the watchdog (I think)\r
- SREG = 0;\r
- //PORTE |= (1<<0);\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
-void die() { cli(); PORTE|=(1<<5); _delay_ms(2000); while(1) { portd(2,0); portd(2,1); } }\r
\r
-ISR(SIG_UART0_RECV) {\r
+//void die() { dead = 1; cli(); PORTE|=(1<<5); _delay_ms(2000); while(1) { } }\r
\r
- if (UCSR0A & (1 << FE0)) err = 201;//{ portd(2,0); portd(3,1); die(); } // framing error, lock up with LED=01\r
- if ((UCSR0A & (1 << OR0))) err = 202;//{ portd(2,1); portd(3,0); die(); } // overflow; lock up with LED=10\r
- if (read_full()) err = 203;//{ portd(2,1); portd(3,1); die(); } // buffer overrun\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(0, 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
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
+ DDRE = (1<<7) | (1<<5) | (1<<3) | (1<<2);\r
PORTE = 0;\r
\r
- init();\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
- PORTE &= ~(1<<7);\r
+ TCNT1 = 0;\r
+ TIFR&=~(1<<TOV1);\r
+ TIMSK|=(1<<TOIE1);\r
+ TCCR1B = 3;\r
\r
- int count = 0;\r
- long long bad = 0;\r
- int left = 0;\r
- char v = 0;\r
- long int oldi = 0;\r
cts(0);\r
cts(1);\r
- /*\r
- while(1) {\r
- long int i = recv() & 0xff;\r
- //if (i < 0) err = 200;\r
- //if (err < 200) {\r
- long int newi = oldi+1;\r
- if (newi >= 256) newi -= 256;\r
- if (i != newi) err++;\r
- //}\r
- oldi = i;\r
-\r
- send(err >= 10 ? 255 : i);\r
- //send(err);\r
- }\r
- */\r
\r
int x=0, y=0, z=0;\r
- //while(1) send(/*FISUA*/2);\r
+ int flag=0;\r
for(;;) {\r
- /*\r
- if (PORTE & (1<<6)) PORTE &= ~(1<<6);\r
- else PORTE |= (1<<6);\r
- */\r
int i, d=0;\r
int r = recv();\r
switch(r) {\r
send('I');\r
send('T');\r
send('S');\r
- PORTE |= (1<<3);\r
+ fpga_interrupts(1);\r
+ if (flag) die(1, 1, 1);\r
break;\r
+\r
case 1:\r
z = recv();\r
y = recv();\r
x = recv();\r
d = recv();\r
- //portd(1,1);\r
conf(z, y, x, d);\r
- //portd(1,0);\r
break;\r
+\r
case 2:\r
- //fpga_interrupts(0);\r
- //portd(1,1);\r
- send(FISUA);\r
- //portd(1,0);\r
- //fpga_interrupts(1);\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
case 5:\r
sending = 0;\r
break;\r
- case 6: {\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
- fpga_interrupts(1);\r
- break;\r
- }\r
- */\r
- /*\r
- default: {\r
- if ((r & 0x80) == 0x80) {\r
- switch (r & 0x44) {\r
- case 0x44: z = recv(); break;\r
- case 0x40: z++; break;\r
- case 0x04: z--; break;\r
- }\r
- switch (r & 0x22) {\r
- case 0x22: y = recv(); break;\r
- case 0x20: y++; break;\r
- case 0x02: y--; break;\r
- }\r
- switch (r & 0x11) {\r
- case 0x11: x = recv(); break;\r
- case 0x10: x++; break;\r
- case 0x01: x--; break;\r
- }\r
- d = recv();\r
- portd(1,1);\r
- conf(z, y, x, d);\r
- portd(1,0);\r
- break;\r
- }\r
- die();\r
- }\r
*/\r
}\r
}\r