Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FastLED/FastLED.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Garcia <danielgarcia@gmail.com>2013-11-24 08:12:36 +0400
committerDaniel Garcia <danielgarcia@gmail.com>2013-11-24 08:12:36 +0400
commit29e9e4a26a810f3f8742ed44139b33a1fd1cf6af (patch)
tree9d2e61f54f17162fefebc350c9e7b4cd684527d4 /clockless_trinket.h
parent365ceb1b99c0af86abf12c9830c33e4149fe7f2d (diff)
Cleaning up comments and asm code some more. Still need to make the code clock-speed agnostic
Diffstat (limited to 'clockless_trinket.h')
-rw-r--r--clockless_trinket.h85
1 files changed, 25 insertions, 60 deletions
diff --git a/clockless_trinket.h b/clockless_trinket.h
index b50f9e6c..1869a72c 100644
--- a/clockless_trinket.h
+++ b/clockless_trinket.h
@@ -133,84 +133,49 @@ public:
[PORT] "M" (0x18) \
: /* clobber registers */
-#ifdef USE_ASM_MACROS
+// 1 cycle, write hi to the port
#define HI1 asm __volatile__("out %[PORT], %[hi]" ASM_VARS );
+// 1 cycle, write lo to the port
#define LO1 asm __volatile__("out %[PORT], %[lo]" ASM_VARS );
+// 2 cycles, sbrs on flipping the lne to lo if we're pushing out a 0
#define QLO2(B, N) asm __volatile__("sbrs %[" #B "], " #N ASM_VARS ); LO1;
+// 0 cycle placeholder nop to keep code columns lined up
#define NOP0
+// 1 cycle nop/delay
#define NOP1 asm __volatile__("cp r0,r0" ASM_VARS );
+// 2 cycle nop/delay
#define NOP2 asm __volatile__("rjmp .+0" ASM_VARS );
+// 3 cycle nop/delay
#define NOP3 NOP1 NOP2
+// 4 cycle nop/delay
#define NOP4 NOP2 NOP2
+// load a byte from ram into the given var with the given offset
#define LD2(B,O) asm __volatile__("ldd %[" #B "], Z + %[" #O "]" ASM_VARS );
+// 3 cycles - load a byte from ram into the scaling scratch space with the given offset, clear the target var
#define LDSCL3(B,O) asm __volatile__("ldd %[scale_base], Z + %[" #O "]\n\tclr %[" #B "]" ASM_VARS );
+// 2 cycles - increment the data pointer
#define IDATA2 asm __volatile__("add %A[data], %A[ADV]\n\tadc %B[data], %B[ADV]" ASM_VARS );
+// 2 cycles - decrement the counter
#define DCOUNT2 asm __volatile__("sbiw %[count], 1" ASM_VARS );
+// 2 cycles - jump to the beginning of the loop
#define JMPLOOP2 asm __volatile__("rjmp 1b" ASM_VARS );
+// 2 cycles - jump out of the loop
#define BRLOOP1 asm __volatile__("breq 2f" ASM_VARS );
+// 2 cycles - perform one step of the scaling (if a given bit is set in scale, add scale-base to the scratch space)
#define SCALE2(B, N) asm __volatile__("sbrc %[scale], " #N "\n\tadd %[" #B "], %[scale_base]" ASM_VARS );
+// 1 cycle - rotate right, pulling in from carry
#define ROR1(B) asm __volatile__("ror %[" #B "]" ASM_VARS );
+// 1 cycle, clear the carry bit
#define CLC1 asm __volatile__("clc" ASM_VARS );
+// 1 cycle, move one register to another
#define MOV1(B1, B2) asm __volatile__("mov %[" #B1 "], %[" #B2 "]" ASM_VARS );
+// 4 cycles, rotate, clear carry, scale next bit
#define RORSC4(B, N) ROR1(B) CLC1 SCALE2(B, N)
+// 4 cycles, scale bit, rotate, clear carry
#define SCROR4(B, N) SCALE2(B,N) ROR1(B) CLC1
+// define the beginning of the loop
#define LOOP asm __volatile__("1:" ASM_VARS );
#define DONE asm __volatile__("2:" ASM_VARS );
-#define ASM_BEGIN
-#define ASM_END
-#else
-/// Macro defs for the asm block, flagged with cycle timings
-// 1 cycle, write hi to the port
-#define HI1 "out %[PORT], %[hi]\n\t"
-
-// 1 cycle, write lo to the port
-#define LO1 "out %[PORT], %[lo]\n\t"
-// 2 cycles, sbrs on flipping the line to lo if we're pushing out a 0
-#define QLO2(B, N) "sbrs %[" #B "], " #N "\n\t" \
- "out %[PORT], %[lo]\n\t"
-// 0 cycles - nop0 - used to placeholder where wait points would be for other timings/chipsets
-#define NOP0 ""
-// 1 cycle nop
-#define NOP1 "nop\n\t"
-// 2 cycle nop - trick found via adafruit's neopixel code - two cycle inst
-#define NOP2 "rjmp .+0\n\t"
-// 3 cycle nop
-#define NOP3 NOP2 NOP1
-// 4 cycle nop
-#define NOP4 NOP2 NOP2
-// 2 cycle byte load
-#define LD2(B,O) "ldd %[" #B "], Z + %[" #O "]\n\t"
-// 3 cycle byte load to scale scratch and clear
-#define LDSCL3(B,O) "ldd %[scale_base], Z + %[" #O "]\n\t" \
- "clr %[" #B "]\n\t"
-
-// 2 cycle data pointer increment
-#define IDATA2 "add %A[data], %A[ADV]\n\tadc %B[data], %B[ADV]\n\t"
-
-// 2 cycle decrement counter
-#define DCOUNT2 "sbiw %[count], 1\n\t"
-// 2 cycle loop jump
-#define JMPLOOP2 "rjmp 1b\n\t"
-// 1 cycle (if not branched) end of loop check
-#define BRLOOP1 "breq 2f\n\t"
-// 2 cycle scale operation, 1/2 of scaling
-#define SCALE2(B,N) "sbrc %[scale], " #N "\n\t"\
- "add %[" #B "], %[scale_base]\n\t"
-// 2 cycle rotate output byte, clear carry flag
-#define ROR1(B) "ror %[" #B "]\n\t"
-#define CLC1 "clc\n\t"
-
-#define MOV1(B1, B2) "mov %[" #B1 "], %[" #B2 "]\n\t"
-
-#define RORSC4(B, N) ROR1(B) CLC1 SCALE2(B, N)
-#define SCROR4(B, N) SCALE2(B, N) ROR1(B) CLC1
-
-#define LOOP "1:\n\t"
-#define DONE "2:\n\t"
-
-#define ASM_BEGIN asm __volatile__(
-#define ASM_END ASM_VARS );
-#endif
// This method is made static to force making register Y available to use for data on AVR - if the method is non-static, then
// gcc will use register Y for the this pointer.
@@ -240,7 +205,7 @@ public:
// multiply count by 3, don't use * because there's no hardware multiply
count = count+(count<<1);
advanceBy = advance ? 1 : 0;
- ASM_BEGIN
+ {
/* asm */
LOOP
// Sum of the clock counts across each row should be 10 for 8Mhz, WS2811
@@ -278,11 +243,11 @@ public:
#endif
DONE
NOP2 LO1 NOP2
- ASM_END
+ }
}
else
{
- ASM_BEGIN
+ {
/* asm */
LOOP
// Sum of the clock counts across each row should be 10 for 8Mhz, WS2811
@@ -349,7 +314,7 @@ public:
#endif
DONE
NOP2 LO1 NOP2
- ASM_END
+ }
}
}