diff options
-rw-r--r-- | main.c | 196 |
1 files changed, 134 insertions, 62 deletions
@@ -1,6 +1,128 @@ #include <avr/io.h> #include <avr/delay.h> - + +static char buffer[300]; + +#define OUT0 "sbi %0, 5 \n" /* pull line to GND */ +#define OUT1 "cbi %0, 5 \n" /* tristate the line */ + +#define WAIT10 "ldi r16, 1 \n rcall delay_loop \n" +#define WAIT34 "ldi r16, 9 \n rcall delay_loop \n" +#define WAIT10MINUS10 "" +#define WAIT34MINUS10 "ldi r16,5 \n rcall delay_loop \n nop \n nop \n" + +int recv_gc() +{ + char* buf_ptr = buffer; + + asm volatile( + "recv_wait_low_initial_loop: \n" + "sbic %1, 5 \n" + "rjmp recv_wait_low_initial_loop \n" // from low to the start of counting: 6 cycles = 0.5us + "nop \n" + "nop \n" + "nop \n" + "nop \n" + + + "recv_loop: \n" + "recv_low_begin: \n" + "ldi r16, 128 \n" // 1 + "recv_low_loop: \n" + "inc r16 \n" // 1 + "breq timeout \n" // 1 if no timeout + "sbis %1, 5 \n" // 1 // von high auf dec: 6 + "rjmp recv_low_loop \n\n" // 2 if executed, 1 if skipped. + "nop \n" // to account for the rjmp recv_loop below. + "nop \n" + "nop \n" + "nop \n" + + "recv_high_begin: \n" + "nop \n" // to account for the ldi in recv_low_begin. + "recv_high_loop: \n" + "dec r16 \n" // 1 + "breq timeout \n" // 1 if no timeout + "sbic %1, 5 \n" // 1 // von low auf inc: 6 + "rjmp recv_high_loop \n\n" // 2 if executed, 1 if skipped + + "st z+, r16 \n" // 2 + "rjmp recv_loop \n\n" // 2 + + "timeout: \n" + + : "+z" ((unsigned char volatile*) buf_ptr) + : "I" (_SFR_IO_ADDR(PINC)) + : "r16", "memory" + ); + + return buf_ptr-buffer; + + // a value of >=128 means "0", <127 means "1" bit. +} + +void send_gc(char* bytes, int len) +{ + int k=0; + for (int i=0; i<len; i++) + for (int j=0x80; j!=0; j=j>>1, k++) + buffer[k] = ((bytes[i] & j)!=0)?1:0 ; + + len=len*8+1; + + asm volatile( + "push r31 \n" + "push r30 \n\n" + + "send_loop: \n" + "sbiw %2, 1 \n" // 2 + "breq send_done \n" // 1 if not done, 2 if done + "ld r16, z+ \n" // 2 + "tst r16 \n" // 1 + "brne send_one \n\n" // 1 if zero, 2 if nonzero + + "; otherwise, send zero \n" + "nop \n" // 1 + OUT0 + WAIT34 + OUT1 + WAIT10MINUS10 + "rjmp send_loop \n\n" // 2 + + "send_one: \n" + OUT0 + WAIT10 + OUT1 + WAIT34MINUS10 + "rjmp send_loop \n\n" + + "delay_loop:\n" + "; this costs 7 + 3*(r16) cycles \n" + "dec r16\n" + "brne delay_loop\n" + "ret\n\n" + + "send_done: \n" + "; now send the stop bit and release the line \n" + "nop \n nop \n nop \n" + OUT0 + WAIT10 + OUT1 + "; done :) \n" + "pop r30 \n" + "pop r31 \n" + + : + : "I" (_SFR_IO_ADDR(DDRC)), + "I" (_SFR_IO_ADDR(PINC)), + "w" (len), + "z" ((unsigned char volatile*) buffer) + : "r16" + ); + +} + + int main (void) { DDRC=0x00; @@ -9,73 +131,23 @@ int main (void) DDRB=0xFF; PORTB=0x55; -#define OUT0 "sbi %0, 5 \n" /* pull line to GND */ -#define OUT1 "cbi %0, 5 \n" /* tristate the line */ -#define NOP "nop \n" -#define NOP10 NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP -#define NOP12 NOP10 NOP NOP -#define WAIT10 "ldi r16, 1 \n rcall loop \n" -#define WAIT34 "ldi r16, 9 \n rcall loop \n" + PORTB=0x55; + + int temp=0; -//#define BIT0 OUT0 NOP10 NOP12 NOP12 OUT1 NOP10 -//#define BIT1 OUT0 NOP10 OUT1 NOP10 NOP12 NOP12 -#define BIT0 OUT0 WAIT34 OUT1 WAIT10 -#define BIT1 OUT0 WAIT10 OUT1 WAIT34 + while(1) + { + temp++; +// PORTB=~(1 << ((temp>>9)%6)); +PORTB=~temp; + _delay_ms(1); - PORTB=0x55; + char foo[] = { 0x40, 0x03, 0x02 }; - int temp=0; + send_gc(foo, 3); - while(1) - { - temp++; - PORTB=~(1 << ((temp>>9)%6)); - _delay_ms(1); - asm volatile( - BIT0 - BIT1 - BIT0 - BIT0 - - BIT0 - BIT0 - BIT0 - BIT0 - - BIT0 - BIT0 - BIT0 - BIT0 - - BIT0 - BIT0 - BIT1 - BIT1 - - BIT0 - BIT0 - BIT0 - BIT0 - - BIT0 - BIT0 - BIT1 - BIT0 - - - BIT1 - "rjmp done \n" - "loop:\n" - "dec r16\n" - "brne loop\n" - "ret\n" - "done: \n" - : - : "I" (_SFR_IO_ADDR(DDRC)), "I" (_SFR_IO_ADDR(PINC)) - : "r16" - ); } |