summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--main.c162
2 files changed, 80 insertions, 84 deletions
diff --git a/Makefile b/Makefile
index e8d729a..2bbd104 100644
--- a/Makefile
+++ b/Makefile
@@ -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.
diff --git a/main.c b/main.c
index 8cf43a1..64b811d 100644
--- a/main.c
+++ b/main.c
@@ -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);
}