X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Fedu%2Fberkeley%2Fslipway%2FFtdiBoardSlave.c;h=163e717824ebdb76d27f3270de76cb879dee9181;hb=88262b67660010569acf55be49e3d5f88f73bfba;hp=84290184170fd9657c5d2110fc6762885efc2477;hpb=86a9f741672ac1ca31965c008151c13b490d2949;p=slipway.git diff --git a/src/edu/berkeley/slipway/FtdiBoardSlave.c b/src/edu/berkeley/slipway/FtdiBoardSlave.c index 8429018..163e717 100644 --- a/src/edu/berkeley/slipway/FtdiBoardSlave.c +++ b/src/edu/berkeley/slipway/FtdiBoardSlave.c @@ -1,231 +1,282 @@ -// -// 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 -#include -#include -#include - -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 (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); -} - -inline char recv() { - int q; - char ret; - while(read_empty()) cts(1); - ret = read_buf[read_buf_head]; - read_buf_head = inc(read_buf_head); - if (!read_nearlyFull()) cts(1); - if (PORTE & (1<<3)) PORTE &= ~(1<<3); - else PORTE |= (1<<3); - 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) { - while (write_full()); - write_buf[write_buf_tail] = c; - write_buf_tail = inc(write_buf_tail); - if (PORTE & (1<<2)) PORTE &= ~(1<<2); - else PORTE |= (1<<2); - UCSR0B |= (1 << UDRIE0); -} - - -void fpga_interrupts(int on) { - if (on) { - //FISUA = 0x1; - FISCR = 0x80; - FISUD = 0x08; - } else { - FISUD = 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_INTERRUPT15) { - interrupt_count++; - fpga_interrupts(1); - sei(); -} - -void die() { cli(); PORTE|=(1<<5); _delay_ms(2000); while(1) { } } - -ISR(SIG_UART0_RECV) { - if (UCSR0A & (1 << FE0)) err = 201;//{ portd(2,0); portd(3,1); die(); } // framing error, lock up with LED=01 - if ((UCSR0A & (1 << OR0))) err = 202;//{ portd(2,1); portd(3,0); die(); } // overflow; lock up with LED=10 - if (read_full()) err = 203;//{ portd(2,1); portd(3,1); die(); } // buffer overrun - - 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; - - read_buf_head = 0; - read_buf_tail = 0; - write_buf_head = 0; - write_buf_tail = 0; - initUART0(0, 0); //for slow board - - EIMF = 0xFF; - SREG = INT0; - sei(); - - cts(0); - cts(1); - - int x=0, y=0, z=0; - for(;;) { - int i, d=0; - int r = recv(); - switch(r) { - case 0: - send('O'); - send('B'); - send('I'); - send('T'); - send('S'); - PORTE |= (1<<3); - break; - - case 1: - z = recv(); - y = recv(); - x = recv(); - d = recv(); - conf(z, y, x, d); - break; - - case 2: - send(readFPGA()); - break; - - case 6: { - 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); - break; - } - - /* - case 3: - //init_timer(); - break; - case 4: - sending = 1; - break; - case 5: - sending = 0; - break; - */ - } - } - return 0; - -} - +// +// 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 +#include +#include +#include + +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 (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<> 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<> 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; + +} +