-//
-// 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;
-
-}
-