added mpardemo
[slipway.git] / src / edu / berkeley / slipway / FtdiBoardSlave.c
index c1264e7..163e717 100644 (file)
-//\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;
+
+}  
+