diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | main.c | 162 |
2 files changed, 80 insertions, 84 deletions
@@ -81,7 +81,7 @@ ASRC = # Optimization level, can be [0, 1, 2, 3, s]. # 0 = turn off optimization. s = optimize for size. # (Note: 3 is not always the best optimization level. See avr-libc FAQ.) -OPT = s +OPT = 2 # Debugging format. @@ -3,69 +3,21 @@ static char buffer[300]; -#define OUT0 "sbi %0, 5 \n" /* pull line to GND */ -#define OUT1 "cbi %0, 5 \n" /* tristate the line */ +#define OUT0 "sbi %2, 5 \n" /* pull line to GND */ +#define OUT1 "cbi %2, 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() + +int send_recv_gc(char* bytes, int len) { char* buf_ptr = buffer; - asm volatile( - "clr r16 \n" - "recv_wait_low_initial_loop: \n" - "inc r16 \n" - "breq timeout \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" + /****** SEND PART ******/ - "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++) @@ -74,11 +26,13 @@ void send_gc(char* bytes, int len) len=len*8+1; asm volatile( - "push r31 \n" + "push r31 ; save Z\n" "push r30 \n\n" + ";;;;;;;; SEND PART ;;;;;;;;\n\n" + "send_loop: \n" - "sbiw %2, 1 \n" // 2 + "sbiw %3, 1 \n" // 2 "breq send_done \n" // 1 if not done, 2 if done "ld r16, z+ \n" // 2 "tst r16 \n" // 1 @@ -109,11 +63,11 @@ void send_gc(char* bytes, int len) "; now send the stop bit and release the line \n" "nop \n nop \n nop \n" OUT0 - "; instead of WAIT10, do some sensible cleanup work \n" - "clr r16 ; needed below \n" - "pop r30 \n" - "pop r31 \n" - "nop \n nop \n nop \n nop \n nop \n" + "; instead of WAIT10, do sensible work \n" + "pop r30 ; restore Z \n" // 2 + "pop r31 \n" // 2 + "clr r16 \n" // 1 + "nop \n nop \n nop \n nop \n nop \n" // 5 OUT1 "; done :) \n\n\n" @@ -121,19 +75,62 @@ void send_gc(char* bytes, int len) "; now the final thing is to wait for DATA become high again (should be immediately anyway) \n" "send_final_loop: \n" "inc r16 \n" - "breq send_timeout \n" - "sbis %0, 5 \n" - "rjmp send_final_loop \n" - "send_timeout: \n" - - : - : "I" (_SFR_IO_ADDR(DDRC)), - "I" (_SFR_IO_ADDR(PINC)), - "w" (len), - "z" ((unsigned char volatile*) buffer) - : "r16" + "breq timeout \n" + "sbis %1, 5 \n" + "rjmp send_final_loop \n\n\n" + + + + ";;;;;;;; RECEIVE PART ;;;;;;;;\n\n" + + + "clr r16 \n" + "recv_wait_low_initial_loop: \n" + "inc r16 \n" + "breq timeout \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)), + "I" (_SFR_IO_ADDR(DDRC)), + "w" (len) + : "r16", "memory" ); + return buf_ptr-buffer; + + // a value of >=128 means "0", <127 means "1" bit. } @@ -158,14 +155,6 @@ int main (void) //PORTB=~(1 << ((temp>>9)%6)); PORTB=~temp; } - else if (!(PIND & 0x10)) - { - //PORTB=~buffer[4]; - char tmp=0; - for (int i=0;i<8;i++) - tmp|= ( (buffer[i]&0x80)?(1<<i):0 ); - PORTB=~tmp; - } else if (!(PIND & 0x20)) { PORTB=~n_received>>3; @@ -174,13 +163,20 @@ int main (void) { PORTB=~0x00; } - - _delay_ms(1); + else + { + //PORTB=~buffer[4]; + char tmp=0; + for (int i=0;i<8;i++) + tmp|= ( (buffer[i]&0x80)?0:(1<<i) ); + PORTB=~tmp; + } + + _delay_ms(1); char foo[] = { 0x40, 0x03, 0x02 }; - send_gc(foo, 3); - n_received=recv_gc(); + n_received=send_recv_gc(foo, 3); } |