You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

242 lines
6.3 KiB

  1. #define FASTLED_INTERNAL
  2. #include <stdint.h>
  3. #define RAND16_SEED 1337
  4. uint16_t rand16seed = RAND16_SEED;
  5. // memset8, memcpy8, memmove8:
  6. // optimized avr replacements for the standard "C" library
  7. // routines memset, memcpy, and memmove.
  8. //
  9. // There are two techniques that make these routines
  10. // faster than the standard avr-libc routines.
  11. // First, the loops are unrolled 2X, meaning that
  12. // the average loop overhead is cut in half.
  13. // And second, the compare-and-branch at the bottom
  14. // of each loop decrements the low byte of the
  15. // counter, and if the carry is clear, it branches
  16. // back up immediately. Only if the low byte math
  17. // causes carry do we bother to decrement the high
  18. // byte and check that result for carry as well.
  19. // Results for a 100-byte buffer are 20-40% faster
  20. // than standard avr-libc, at a cost of a few extra
  21. // bytes of code.
  22. #if defined(__AVR__)
  23. //__attribute__ ((noinline))
  24. void * memset8 ( void * ptr, uint8_t val, uint16_t num )
  25. {
  26. asm volatile(
  27. " movw r26, %[ptr] \n\t"
  28. " sbrs %A[num], 0 \n\t"
  29. " rjmp Lseteven_%= \n\t"
  30. " rjmp Lsetodd_%= \n\t"
  31. "Lsetloop_%=: \n\t"
  32. " st X+, %[val] \n\t"
  33. "Lsetodd_%=: \n\t"
  34. " st X+, %[val] \n\t"
  35. "Lseteven_%=: \n\t"
  36. " subi %A[num], 2 \n\t"
  37. " brcc Lsetloop_%= \n\t"
  38. " sbci %B[num], 0 \n\t"
  39. " brcc Lsetloop_%= \n\t"
  40. : [num] "+r" (num)
  41. : [ptr] "r" (ptr),
  42. [val] "r" (val)
  43. : "memory"
  44. );
  45. return ptr;
  46. }
  47. //__attribute__ ((noinline))
  48. void * memcpy8 ( void * dst, const void* src, uint16_t num )
  49. {
  50. asm volatile(
  51. " movw r30, %[src] \n\t"
  52. " movw r26, %[dst] \n\t"
  53. " sbrs %A[num], 0 \n\t"
  54. " rjmp Lcpyeven_%= \n\t"
  55. " rjmp Lcpyodd_%= \n\t"
  56. "Lcpyloop_%=: \n\t"
  57. " ld __tmp_reg__, Z+ \n\t"
  58. " st X+, __tmp_reg__ \n\t"
  59. "Lcpyodd_%=: \n\t"
  60. " ld __tmp_reg__, Z+ \n\t"
  61. " st X+, __tmp_reg__ \n\t"
  62. "Lcpyeven_%=: \n\t"
  63. " subi %A[num], 2 \n\t"
  64. " brcc Lcpyloop_%= \n\t"
  65. " sbci %B[num], 0 \n\t"
  66. " brcc Lcpyloop_%= \n\t"
  67. : [num] "+r" (num)
  68. : [src] "r" (src),
  69. [dst] "r" (dst)
  70. : "memory"
  71. );
  72. return dst;
  73. }
  74. //__attribute__ ((noinline))
  75. void * memmove8 ( void * dst, const void* src, uint16_t num )
  76. {
  77. if( src > dst) {
  78. // if src > dst then we can use the forward-stepping memcpy8
  79. return memcpy8( dst, src, num);
  80. } else {
  81. // if src < dst then we have to step backward:
  82. dst = (char*)dst + num;
  83. src = (char*)src + num;
  84. asm volatile(
  85. " movw r30, %[src] \n\t"
  86. " movw r26, %[dst] \n\t"
  87. " sbrs %A[num], 0 \n\t"
  88. " rjmp Lmoveven_%= \n\t"
  89. " rjmp Lmovodd_%= \n\t"
  90. "Lmovloop_%=: \n\t"
  91. " ld __tmp_reg__, -Z \n\t"
  92. " st -X, __tmp_reg__ \n\t"
  93. "Lmovodd_%=: \n\t"
  94. " ld __tmp_reg__, -Z \n\t"
  95. " st -X, __tmp_reg__ \n\t"
  96. "Lmoveven_%=: \n\t"
  97. " subi %A[num], 2 \n\t"
  98. " brcc Lmovloop_%= \n\t"
  99. " sbci %B[num], 0 \n\t"
  100. " brcc Lmovloop_%= \n\t"
  101. : [num] "+r" (num)
  102. : [src] "r" (src),
  103. [dst] "r" (dst)
  104. : "memory"
  105. );
  106. return dst;
  107. }
  108. }
  109. #endif /* AVR */
  110. #if 0
  111. // TEST / VERIFICATION CODE ONLY BELOW THIS POINT
  112. #include <Arduino.h>
  113. #include "lib8tion.h"
  114. void test1abs( int8_t i)
  115. {
  116. Serial.print("abs("); Serial.print(i); Serial.print(") = ");
  117. int8_t j = abs8(i);
  118. Serial.print(j); Serial.println(" ");
  119. }
  120. void testabs()
  121. {
  122. delay(5000);
  123. for( int8_t q = -128; q != 127; q++) {
  124. test1abs(q);
  125. }
  126. for(;;){};
  127. }
  128. void testmul8()
  129. {
  130. delay(5000);
  131. byte r, c;
  132. Serial.println("mul8:");
  133. for( r = 0; r <= 20; r += 1) {
  134. Serial.print(r); Serial.print(" : ");
  135. for( c = 0; c <= 20; c += 1) {
  136. byte t;
  137. t = mul8( r, c);
  138. Serial.print(t); Serial.print(' ');
  139. }
  140. Serial.println(' ');
  141. }
  142. Serial.println("done.");
  143. for(;;){};
  144. }
  145. void testscale8()
  146. {
  147. delay(5000);
  148. byte r, c;
  149. Serial.println("scale8:");
  150. for( r = 0; r <= 240; r += 10) {
  151. Serial.print(r); Serial.print(" : ");
  152. for( c = 0; c <= 240; c += 10) {
  153. byte t;
  154. t = scale8( r, c);
  155. Serial.print(t); Serial.print(' ');
  156. }
  157. Serial.println(' ');
  158. }
  159. Serial.println(' ');
  160. Serial.println("scale8_video:");
  161. for( r = 0; r <= 100; r += 4) {
  162. Serial.print(r); Serial.print(" : ");
  163. for( c = 0; c <= 100; c += 4) {
  164. byte t;
  165. t = scale8_video( r, c);
  166. Serial.print(t); Serial.print(' ');
  167. }
  168. Serial.println(' ');
  169. }
  170. Serial.println("done.");
  171. for(;;){};
  172. }
  173. void testqadd8()
  174. {
  175. delay(5000);
  176. byte r, c;
  177. for( r = 0; r <= 240; r += 10) {
  178. Serial.print(r); Serial.print(" : ");
  179. for( c = 0; c <= 240; c += 10) {
  180. byte t;
  181. t = qadd8( r, c);
  182. Serial.print(t); Serial.print(' ');
  183. }
  184. Serial.println(' ');
  185. }
  186. Serial.println("done.");
  187. for(;;){};
  188. }
  189. void testnscale8x3()
  190. {
  191. delay(5000);
  192. byte r, g, b, sc;
  193. for( byte z = 0; z < 10; z++) {
  194. r = random8(); g = random8(); b = random8(); sc = random8();
  195. Serial.print("nscale8x3_video( ");
  196. Serial.print(r); Serial.print(", ");
  197. Serial.print(g); Serial.print(", ");
  198. Serial.print(b); Serial.print(", ");
  199. Serial.print(sc); Serial.print(") = [ ");
  200. nscale8x3_video( r, g, b, sc);
  201. Serial.print(r); Serial.print(", ");
  202. Serial.print(g); Serial.print(", ");
  203. Serial.print(b); Serial.print("]");
  204. Serial.println(' ');
  205. }
  206. Serial.println("done.");
  207. for(;;){};
  208. }
  209. #endif