PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

212 lines
7.3KB

  1. /* Copyright (c) 2009 by Alex Leone <acleone ~AT~ gmail.com>
  2. This file is part of the Arduino TLC5940 Library.
  3. The Arduino TLC5940 Library is free software: you can redistribute it
  4. and/or modify it under the terms of the GNU General Public License as
  5. published by the Free Software Foundation, either version 3 of the
  6. License, or (at your option) any later version.
  7. The Arduino TLC5940 Library is distributed in the hope that it will be
  8. useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with The Arduino TLC5940 Library. If not, see
  13. <http://www.gnu.org/licenses/>. */
  14. #ifndef TLC_FADES_H
  15. #define TLC_FADES_H
  16. /** \file
  17. TLC fading functions. */
  18. #include <avr/interrupt.h>
  19. #include "Tlc5940.h"
  20. #if defined(ARDUINO) && ARDUINO >= 100
  21. #include "Arduino.h"
  22. #else
  23. #include "WProgram.h"
  24. #endif
  25. #ifndef TLC_FADE_BUFFER_LENGTH
  26. /** The default fade buffer length (24). Uses 24*13 = 312 bytes of ram. */
  27. #define TLC_FADE_BUFFER_LENGTH 24
  28. #endif
  29. /** Data for a single fade */
  30. struct Tlc_Fade {
  31. TLC_CHANNEL_TYPE channel; /**< channel this fade is on */
  32. int16_t startValue; /**< value when the fade starts (0 - 4095) */
  33. int16_t changeValue; /**< start + changeValue = endValue (0 - 4095) */
  34. uint32_t startMillis; /**< millis() when to start */
  35. uint32_t endMillis; /**< millis() when to end */
  36. } tlc_fadeBuffer[TLC_FADE_BUFFER_LENGTH];
  37. /** The current fade buffer size */
  38. uint8_t tlc_fadeBufferSize;
  39. uint8_t tlc_updateFades();
  40. uint8_t tlc_updateFades(uint32_t currentMillis);
  41. uint8_t tlc_addFade(struct Tlc_Fade *fade);
  42. uint8_t tlc_addFade(TLC_CHANNEL_TYPE channel, int16_t startValue,
  43. int16_t endValue, uint32_t startMillis, uint32_t endMillis);
  44. uint8_t tlc_isFading(TLC_CHANNEL_TYPE channel);
  45. uint8_t tlc_removeFades(TLC_CHANNEL_TYPE channel);
  46. static void tlc_removeFadeFromBuffer(struct Tlc_Fade *current,
  47. struct Tlc_Fade *end);
  48. /** \addtogroup ExtendedFunctions
  49. \code #include "tlc_fades.h" \endcode
  50. - uint8_t tlc_updateFades() - updates all fades
  51. - uint8_t tlc_updateFades(uint32_t currentMillis) - updates fades using
  52. currentMillis as the current time
  53. - uint8_t tlc_addFade(struct Tlc_Fade *fade) - copies fade into the
  54. fade buffer
  55. - uint8_t tlc_addFade(TLC_CHANNEL_TYPE channel, int16_t startValue,
  56. int16_t endValue, uint32_t startMillis, uint32_t endMillis) - adds
  57. a fade to the fade buffer
  58. - uint8_t tlc_isFading(TLC_CHANNEL_TYPE channel) - returns 1 if there's
  59. a fade on this channel in the buffer
  60. - uint8_t tlc_removeFades(TLC_CHANNEL_TYPE channel) - removes all fades
  61. on channel */
  62. /* @{ */
  63. /** Adds a fade to the buffer.
  64. \param fade the fade to be copied into the buffer
  65. \returns 0 if the fade buffer is full, fadeBufferSize if added successfully
  66. */
  67. uint8_t tlc_addFade(struct Tlc_Fade *fade)
  68. {
  69. if (tlc_fadeBufferSize == TLC_FADE_BUFFER_LENGTH) {
  70. return 0; // fade buffer full
  71. }
  72. struct Tlc_Fade *p = tlc_fadeBuffer + tlc_fadeBufferSize++;
  73. p->channel = fade->channel;
  74. p->startValue = fade->startValue;
  75. p->changeValue = fade->changeValue;
  76. p->startMillis = fade->startMillis;
  77. p->endMillis = fade->endMillis;
  78. return tlc_fadeBufferSize;
  79. }
  80. /** Adds a fade to the fade buffer.
  81. \param channel the ouput channel this fade is on
  82. \param startValue the value at the start of the fade
  83. \param endValue the value at the end of the fade
  84. \param startMillis the millis() when to start the fade
  85. \param endMillis the millis() when to end the fade
  86. \returns 0 if the fade buffer is full, fadeBufferSize if added successfully
  87. */
  88. uint8_t tlc_addFade(TLC_CHANNEL_TYPE channel, int16_t startValue,
  89. int16_t endValue, uint32_t startMillis, uint32_t endMillis)
  90. {
  91. if (tlc_fadeBufferSize == TLC_FADE_BUFFER_LENGTH) {
  92. return 0; // fade buffer full
  93. }
  94. struct Tlc_Fade *p = tlc_fadeBuffer + tlc_fadeBufferSize++;
  95. p->channel = channel;
  96. p->startValue = startValue;
  97. p->changeValue = endValue - startValue;
  98. p->startMillis = startMillis;
  99. p->endMillis = endMillis;
  100. return tlc_fadeBufferSize;
  101. }
  102. /** Checks to see if any fades are happening on channel
  103. \param channel the channel to check
  104. \returns 1 if there is a fade in the buffer on this channel, 0 otherwise */
  105. uint8_t tlc_isFading(TLC_CHANNEL_TYPE channel)
  106. {
  107. struct Tlc_Fade *end = tlc_fadeBuffer + tlc_fadeBufferSize;
  108. for (struct Tlc_Fade *p = tlc_fadeBuffer; p < end; p++) {
  109. if (p->channel == channel) {
  110. return 1;
  111. }
  112. }
  113. return 0;
  114. }
  115. /** Removes any fades from the fade buffer on this channel.
  116. \param channel which channel the fades are on
  117. \returns how many fades were removed */
  118. uint8_t tlc_removeFades(TLC_CHANNEL_TYPE channel)
  119. {
  120. uint8_t removed = 0;
  121. struct Tlc_Fade *end = tlc_fadeBuffer + tlc_fadeBufferSize;
  122. for (struct Tlc_Fade *p = tlc_fadeBuffer; p < end; p++) {
  123. if (p->channel == channel) {
  124. removed++;
  125. tlc_removeFadeFromBuffer(p, --end);
  126. }
  127. }
  128. return removed;
  129. }
  130. /** Copies the end of the buffer to the current and decrements
  131. tlc_fadeBufferSize. This will change the end of the buffer (pass by
  132. reference)
  133. \param current the fade to be removed
  134. \param endp the end of the fade buffer (pointer to pointer) */
  135. static void tlc_removeFadeFromBuffer(struct Tlc_Fade *current,
  136. struct Tlc_Fade *endp)
  137. {
  138. if (endp != current) { // if this is not the last fade
  139. current->channel = endp->channel;
  140. current->startValue = endp->startValue;
  141. current->changeValue = endp->changeValue;
  142. current->startMillis = endp->startMillis;
  143. current->endMillis = endp->endMillis;
  144. }
  145. tlc_fadeBufferSize--;
  146. }
  147. /** Updates fades using millis()
  148. \returns 0 if there are no fades left in the buffer. */
  149. uint8_t tlc_updateFades()
  150. {
  151. return tlc_updateFades(millis());
  152. }
  153. /** Updates any running fades.
  154. \param currentMillis the current millis() time.
  155. \returns 0 if there are no fades left in the buffer. */
  156. uint8_t tlc_updateFades(uint32_t currentMillis)
  157. {
  158. struct Tlc_Fade *end = tlc_fadeBuffer + tlc_fadeBufferSize;
  159. uint8_t needsUpdate = 0;
  160. for (struct Tlc_Fade *p = tlc_fadeBuffer; p < end;){
  161. if (currentMillis >= p->endMillis) { // fade done
  162. Tlc.set(p->channel, p->startValue + p->changeValue);
  163. needsUpdate = 1;
  164. tlc_removeFadeFromBuffer(p, --end);
  165. continue;
  166. } else {
  167. uint32_t startMillis = p->startMillis;
  168. if (currentMillis >= startMillis) {
  169. Tlc.set(p->channel, p->startValue + p->changeValue
  170. * (int32_t)(currentMillis - startMillis)
  171. / (int32_t)(p->endMillis - startMillis));
  172. needsUpdate = 1;
  173. }
  174. }
  175. p++;
  176. }
  177. if (needsUpdate) {
  178. Tlc.update();
  179. if (tlc_fadeBufferSize == 0) {
  180. while (tlc_needXLAT)
  181. ;
  182. }
  183. }
  184. return tlc_fadeBufferSize;
  185. }
  186. /* @} */
  187. #endif