+++ /dev/null
-// FIXMEs for SLIPWAY:\r
-// - use INT3 instead of INT1\r
-// - use PORTE[0:1] instead of PORTE[2:3]\r
-// - use UART0 instead of UART1\r
-// - clock frequency\r
-\r
-//\r
-// YOU MUST COMPILE THIS WITH -O3 OR THE AVR WILL NOT BE ABLE TO KEEP UP!!!!\r
-//\r
-\r
-//#define F_CPU 3960000\r
-#define F_CPU 4000000\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
-void initUART1(unsigned int baudRate, unsigned int doubleRate) {\r
- UBRRHI = (((baudRate) >> 8) & 0x000F); \r
- UBRR1 = ((baudRate) & 0x00FF); \r
- UCSR1B |= ((1 << RXEN1) | (1 << TXEN1) | (1 << RXCIE1)); \r
-\r
- if (doubleRate)\r
- UCSR1A |= (1 << U2X1);\r
- /*\r
- else\r
- UCSR1A &= ~(1 << U2X1);\r
- */\r
-}\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
-inline void cts(int c) {\r
- if (c) {\r
- PORTE &= ~(1 << 4);\r
- portd(0, 1);\r
- } else {\r
- PORTE |= (1 << 4);\r
- portd(0, 0);\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 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
-inline char recv() {\r
- int q;\r
- char ret;\r
- while(read_empty()) cts(1);\r
- ret = read_buf[read_buf_head];\r
- read_buf_head = inc(read_buf_head);\r
- if (!read_nearlyFull()) cts(0);\r
- return ret;\r
-}\r
-\r
-ISR(SIG_UART1_DATA) {\r
-\r
- if (write_empty()) {\r
- UCSR1B &= ~(1 << UDRIE1);\r
- return;\r
- }\r
- /*\r
- portd(1, 0);\r
- _delay_ms(10);\r
- portd(1, 1);\r
- _delay_ms(10);\r
- */\r
- char ret = write_buf[write_buf_head];\r
- write_buf_head = inc(write_buf_head);\r
- UDR1 = (int)ret;\r
-\r
- sei();\r
-}\r
-\r
-void send(char c) {\r
-\r
- while (write_full());\r
-\r
- write_buf[write_buf_tail] = c;\r
- write_buf_tail = inc(write_buf_tail);\r
-\r
- UCSR1B |= (1 << UDRIE1);\r
-\r
- //while(!(UCSR1A & (1 << UDRE1))); /* Wait for data Regiester to be empty */\r
-}\r
-\r
-\r
-void fpga_interrupts(int on) {\r
- if (on/* && interrupt_count<301*/) {\r
- //FISUA = 0x1;\r
- FISCR = 0x80;\r
- FISUD = 0x08;\r
- } else {\r
- FISUD = 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
- EIMF = 0xFF; /* Enalbe External Interrrupt*/ \r
- DDRD = 0xFF; /* Configure PORTD as Output */\r
- DDRE = 1 << 4; /* ability to write to E4 */\r
- initUART1(12, 1); //for slow board\r
- //initUART1(1, 0);\r
- fpga_interrupts(1);\r
- SREG |= 0x80;\r
- sei();\r
-}\r
-\r
-\r
-\r
-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
-ISR(SIG_FPGA_INTERRUPT15) { \r
- PORTD = portdc++;\r
- interrupt_count++;\r
- //PORTD = ~(interrupt_count & 0xff);\r
- //if (interrupt_count >= 301) fpga_interrupts(0);\r
- //sei();\r
- fpga_interrupts(1);\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_INTERRUPT1) { // use interrupt1 since interrupt0 is sent by the watchdog (I think)\r
- doreset();\r
-}\r
-\r
-void die() { cli(); cts(0); _delay_ms(2000); while(1) { portd(2,0); portd(2,1); } }\r
-ISR(SIG_UART1_RECV) {\r
- if (UCSR1A & (1 << FE1)) { portd(2,0); portd(3,1); die(); } // framing error, lock up with LED=01\r
- if ((UCSR1A & (1 << OR1))) { portd(2,1); portd(3,0); die(); } // overflow; lock up with LED=10\r
- if (read_full()) { portd(2,1); portd(3,1); die(); } // buffer overrun\r
- read_buf[read_buf_tail] = UDR1;\r
- read_buf_tail = inc(read_buf_tail);\r
- SREG |= 0x80;\r
- sei();\r
- if (read_nearlyFull()) cts(0);\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 main() {\r
- int count;\r
- init();\r
- cts(0);\r
- send('O');\r
- send('B');\r
- send('I');\r
- send('T');\r
- send('S');\r
- send('\n');\r
- cts(1);\r
- int x=0, y=0, z=0;\r
- for(;;) {\r
- int i, d=0;\r
- int r = recv();\r
- switch(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
- case 2:\r
- fpga_interrupts(0);\r
- portd(1,1);\r
- send(FISUA);\r
- portd(1,0);\r
- fpga_interrupts(1);\r
- break;\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
- 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
- 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
- return 0;\r
-} \r
-\r