 c98247e3dd
			
		
	
	
		c98247e3dd
		
	
	
	
	
		
			
			* RGB Matrix overhaul Breakout of animations to separate files Integration of optimized int based math lib Overhaul of rgb_matrix.c and animations for performance * Updating effect function api for future extensions * Combined the keypresses || keyreleases define checks into a single define so I stop forgetting it where necessary * Moving define RGB_MATRIX_KEYREACTIVE_ENABLED earlier in the include chain
		
			
				
	
	
		
			242 lines
		
	
	
	
		
			6.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			242 lines
		
	
	
	
		
			6.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #define FASTLED_INTERNAL
 | |
| #include <stdint.h>
 | |
| 
 | |
| #define RAND16_SEED  1337
 | |
| uint16_t rand16seed = RAND16_SEED;
 | |
| 
 | |
| 
 | |
| // memset8, memcpy8, memmove8:
 | |
| //  optimized avr replacements for the standard "C" library
 | |
| //  routines memset, memcpy, and memmove.
 | |
| //
 | |
| //  There are two techniques that make these routines
 | |
| //  faster than the standard avr-libc routines.
 | |
| //  First, the loops are unrolled 2X, meaning that
 | |
| //  the average loop overhead is cut in half.
 | |
| //  And second, the compare-and-branch at the bottom
 | |
| //  of each loop decrements the low byte of the
 | |
| //  counter, and if the carry is clear, it branches
 | |
| //  back up immediately.  Only if the low byte math
 | |
| //  causes carry do we bother to decrement the high
 | |
| //  byte and check that result for carry as well.
 | |
| //  Results for a 100-byte buffer are 20-40% faster
 | |
| //  than standard avr-libc, at a cost of a few extra
 | |
| //  bytes of code.
 | |
| 
 | |
| #if defined(__AVR__)
 | |
| //__attribute__ ((noinline))
 | |
| void * memset8 ( void * ptr, uint8_t val, uint16_t num )
 | |
| {
 | |
|     asm volatile(
 | |
|          "  movw r26, %[ptr]        \n\t"
 | |
|          "  sbrs %A[num], 0         \n\t"
 | |
|          "  rjmp Lseteven_%=        \n\t"
 | |
|          "  rjmp Lsetodd_%=         \n\t"
 | |
|          "Lsetloop_%=:              \n\t"
 | |
|          "  st X+, %[val]           \n\t"
 | |
|          "Lsetodd_%=:               \n\t"
 | |
|          "  st X+, %[val]           \n\t"
 | |
|          "Lseteven_%=:              \n\t"
 | |
|          "  subi %A[num], 2         \n\t"
 | |
|          "  brcc Lsetloop_%=        \n\t"
 | |
|          "  sbci %B[num], 0         \n\t"
 | |
|          "  brcc Lsetloop_%=        \n\t"
 | |
|          : [num] "+r" (num)
 | |
|          : [ptr]  "r" (ptr),
 | |
|            [val]  "r" (val)
 | |
|          : "memory"
 | |
|          );
 | |
|     return ptr;
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| //__attribute__ ((noinline))
 | |
| void * memcpy8 ( void * dst, const void* src, uint16_t num )
 | |
| {
 | |
|     asm volatile(
 | |
|          "  movw r30, %[src]        \n\t"
 | |
|          "  movw r26, %[dst]        \n\t"
 | |
|          "  sbrs %A[num], 0         \n\t"
 | |
|          "  rjmp Lcpyeven_%=        \n\t"
 | |
|          "  rjmp Lcpyodd_%=         \n\t"
 | |
|          "Lcpyloop_%=:              \n\t"
 | |
|          "  ld __tmp_reg__, Z+      \n\t"
 | |
|          "  st X+, __tmp_reg__      \n\t"
 | |
|          "Lcpyodd_%=:               \n\t"
 | |
|          "  ld __tmp_reg__, Z+      \n\t"
 | |
|          "  st X+, __tmp_reg__      \n\t"
 | |
|          "Lcpyeven_%=:              \n\t"
 | |
|          "  subi %A[num], 2         \n\t"
 | |
|          "  brcc Lcpyloop_%=        \n\t"
 | |
|          "  sbci %B[num], 0         \n\t"
 | |
|          "  brcc Lcpyloop_%=        \n\t"
 | |
|          : [num] "+r" (num)
 | |
|          : [src] "r" (src),
 | |
|            [dst] "r" (dst)
 | |
|          : "memory"
 | |
|          );
 | |
|     return dst;
 | |
| }
 | |
| 
 | |
| //__attribute__ ((noinline))
 | |
| void * memmove8 ( void * dst, const void* src, uint16_t num )
 | |
| {
 | |
|     if( src > dst) {
 | |
|         // if src > dst then we can use the forward-stepping memcpy8
 | |
|         return memcpy8( dst, src, num);
 | |
|     } else {
 | |
|         // if src < dst then we have to step backward:
 | |
|         dst = (char*)dst + num;
 | |
|         src = (char*)src + num;
 | |
|         asm volatile(
 | |
|              "  movw r30, %[src]        \n\t"
 | |
|              "  movw r26, %[dst]        \n\t"
 | |
|              "  sbrs %A[num], 0         \n\t"
 | |
|              "  rjmp Lmoveven_%=        \n\t"
 | |
|              "  rjmp Lmovodd_%=         \n\t"
 | |
|              "Lmovloop_%=:              \n\t"
 | |
|              "  ld __tmp_reg__, -Z      \n\t"
 | |
|              "  st -X, __tmp_reg__      \n\t"
 | |
|              "Lmovodd_%=:               \n\t"
 | |
|              "  ld __tmp_reg__, -Z      \n\t"
 | |
|              "  st -X, __tmp_reg__      \n\t"
 | |
|              "Lmoveven_%=:              \n\t"
 | |
|              "  subi %A[num], 2         \n\t"
 | |
|              "  brcc Lmovloop_%=        \n\t"
 | |
|              "  sbci %B[num], 0         \n\t"
 | |
|              "  brcc Lmovloop_%=        \n\t"
 | |
|              : [num] "+r" (num)
 | |
|              : [src] "r" (src),
 | |
|                [dst] "r" (dst)
 | |
|              : "memory"
 | |
|              );
 | |
|         return dst;
 | |
|     }
 | |
| }
 | |
| 
 | |
| #endif /* AVR */
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| #if 0
 | |
| // TEST / VERIFICATION CODE ONLY BELOW THIS POINT
 | |
| #include <Arduino.h>
 | |
| #include "lib8tion.h"
 | |
| 
 | |
| void test1abs( int8_t i)
 | |
| {
 | |
|     Serial.print("abs("); Serial.print(i); Serial.print(") = ");
 | |
|     int8_t j = abs8(i);
 | |
|     Serial.print(j); Serial.println(" ");
 | |
| }
 | |
| 
 | |
| void testabs()
 | |
| {
 | |
|     delay(5000);
 | |
|     for( int8_t q = -128; q != 127; q++) {
 | |
|         test1abs(q);
 | |
|     }
 | |
|     for(;;){};
 | |
| }
 | |
| 
 | |
| 
 | |
| void testmul8()
 | |
| {
 | |
|     delay(5000);
 | |
|     byte r, c;
 | |
| 
 | |
|     Serial.println("mul8:");
 | |
|     for( r = 0; r <= 20; r += 1) {
 | |
|         Serial.print(r); Serial.print(" : ");
 | |
|         for( c = 0; c <= 20; c += 1) {
 | |
|             byte t;
 | |
|             t = mul8( r, c);
 | |
|             Serial.print(t); Serial.print(' ');
 | |
|         }
 | |
|         Serial.println(' ');
 | |
|     }
 | |
|     Serial.println("done.");
 | |
|     for(;;){};
 | |
| }
 | |
| 
 | |
| 
 | |
| void testscale8()
 | |
| {
 | |
|     delay(5000);
 | |
|     byte r, c;
 | |
| 
 | |
|     Serial.println("scale8:");
 | |
|     for( r = 0; r <= 240; r += 10) {
 | |
|         Serial.print(r); Serial.print(" : ");
 | |
|         for( c = 0; c <= 240; c += 10) {
 | |
|             byte t;
 | |
|             t = scale8( r, c);
 | |
|             Serial.print(t); Serial.print(' ');
 | |
|         }
 | |
|         Serial.println(' ');
 | |
|     }
 | |
| 
 | |
|     Serial.println(' ');
 | |
|     Serial.println("scale8_video:");
 | |
| 
 | |
|     for( r = 0; r <= 100; r += 4) {
 | |
|         Serial.print(r); Serial.print(" : ");
 | |
|         for( c = 0; c <= 100; c += 4) {
 | |
|             byte t;
 | |
|             t = scale8_video( r, c);
 | |
|             Serial.print(t); Serial.print(' ');
 | |
|         }
 | |
|         Serial.println(' ');
 | |
|     }
 | |
| 
 | |
|     Serial.println("done.");
 | |
|     for(;;){};
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| void testqadd8()
 | |
| {
 | |
|     delay(5000);
 | |
|     byte r, c;
 | |
|     for( r = 0; r <= 240; r += 10) {
 | |
|         Serial.print(r); Serial.print(" : ");
 | |
|         for( c = 0; c <= 240; c += 10) {
 | |
|             byte t;
 | |
|             t = qadd8( r, c);
 | |
|             Serial.print(t); Serial.print(' ');
 | |
|         }
 | |
|         Serial.println(' ');
 | |
|     }
 | |
|     Serial.println("done.");
 | |
|     for(;;){};
 | |
| }
 | |
| 
 | |
| void testnscale8x3()
 | |
| {
 | |
|     delay(5000);
 | |
|     byte r, g, b, sc;
 | |
|     for( byte z = 0; z < 10; z++) {
 | |
|         r = random8(); g = random8(); b = random8(); sc = random8();
 | |
| 
 | |
|         Serial.print("nscale8x3_video( ");
 | |
|         Serial.print(r); Serial.print(", ");
 | |
|         Serial.print(g); Serial.print(", ");
 | |
|         Serial.print(b); Serial.print(", ");
 | |
|         Serial.print(sc); Serial.print(") = [ ");
 | |
| 
 | |
|         nscale8x3_video( r, g, b, sc);
 | |
| 
 | |
|         Serial.print(r); Serial.print(", ");
 | |
|         Serial.print(g); Serial.print(", ");
 | |
|         Serial.print(b); Serial.print("]");
 | |
| 
 | |
|         Serial.println(' ');
 | |
|     }
 | |
|     Serial.println("done.");
 | |
|     for(;;){};
 | |
| }
 | |
| 
 | |
| #endif
 |