|
- /* Copyright (c) 2009 by Alex Leone <acleone ~AT~ gmail.com>
-
- This file is part of the Arduino TLC5940 Library.
-
- The Arduino TLC5940 Library is free software: you can redistribute it
- and/or modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation, either version 3 of the
- License, or (at your option) any later version.
-
- The Arduino TLC5940 Library is distributed in the hope that it will be
- useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with The Arduino TLC5940 Library. If not, see
- <http://www.gnu.org/licenses/>. */
-
- #ifndef TLC_FADES_H
- #define TLC_FADES_H
-
- /** \file
- TLC fading functions. */
-
- #include <avr/interrupt.h>
-
- #include "Tlc5940.h"
-
- #if defined(ARDUINO) && ARDUINO >= 100
- #include "Arduino.h"
- #else
- #include "WProgram.h"
- #endif
-
- #ifndef TLC_FADE_BUFFER_LENGTH
- /** The default fade buffer length (24). Uses 24*13 = 312 bytes of ram. */
- #define TLC_FADE_BUFFER_LENGTH 24
- #endif
-
- /** Data for a single fade */
- struct Tlc_Fade {
- TLC_CHANNEL_TYPE channel; /**< channel this fade is on */
- int16_t startValue; /**< value when the fade starts (0 - 4095) */
- int16_t changeValue; /**< start + changeValue = endValue (0 - 4095) */
- uint32_t startMillis; /**< millis() when to start */
- uint32_t endMillis; /**< millis() when to end */
- } tlc_fadeBuffer[TLC_FADE_BUFFER_LENGTH];
-
- /** The current fade buffer size */
- uint8_t tlc_fadeBufferSize;
-
- uint8_t tlc_updateFades();
- uint8_t tlc_updateFades(uint32_t currentMillis);
- uint8_t tlc_addFade(struct Tlc_Fade *fade);
- uint8_t tlc_addFade(TLC_CHANNEL_TYPE channel, int16_t startValue,
- int16_t endValue, uint32_t startMillis, uint32_t endMillis);
- uint8_t tlc_isFading(TLC_CHANNEL_TYPE channel);
- uint8_t tlc_removeFades(TLC_CHANNEL_TYPE channel);
- static void tlc_removeFadeFromBuffer(struct Tlc_Fade *current,
- struct Tlc_Fade *end);
-
- /** \addtogroup ExtendedFunctions
- \code #include "tlc_fades.h" \endcode
- - uint8_t tlc_updateFades() - updates all fades
- - uint8_t tlc_updateFades(uint32_t currentMillis) - updates fades using
- currentMillis as the current time
- - uint8_t tlc_addFade(struct Tlc_Fade *fade) - copies fade into the
- fade buffer
- - uint8_t tlc_addFade(TLC_CHANNEL_TYPE channel, int16_t startValue,
- int16_t endValue, uint32_t startMillis, uint32_t endMillis) - adds
- a fade to the fade buffer
- - uint8_t tlc_isFading(TLC_CHANNEL_TYPE channel) - returns 1 if there's
- a fade on this channel in the buffer
- - uint8_t tlc_removeFades(TLC_CHANNEL_TYPE channel) - removes all fades
- on channel */
- /* @{ */
-
- /** Adds a fade to the buffer.
- \param fade the fade to be copied into the buffer
- \returns 0 if the fade buffer is full, fadeBufferSize if added successfully
- */
- uint8_t tlc_addFade(struct Tlc_Fade *fade)
- {
- if (tlc_fadeBufferSize == TLC_FADE_BUFFER_LENGTH) {
- return 0; // fade buffer full
- }
- struct Tlc_Fade *p = tlc_fadeBuffer + tlc_fadeBufferSize++;
- p->channel = fade->channel;
- p->startValue = fade->startValue;
- p->changeValue = fade->changeValue;
- p->startMillis = fade->startMillis;
- p->endMillis = fade->endMillis;
- return tlc_fadeBufferSize;
- }
-
- /** Adds a fade to the fade buffer.
- \param channel the ouput channel this fade is on
- \param startValue the value at the start of the fade
- \param endValue the value at the end of the fade
- \param startMillis the millis() when to start the fade
- \param endMillis the millis() when to end the fade
- \returns 0 if the fade buffer is full, fadeBufferSize if added successfully
- */
- uint8_t tlc_addFade(TLC_CHANNEL_TYPE channel, int16_t startValue,
- int16_t endValue, uint32_t startMillis, uint32_t endMillis)
- {
- if (tlc_fadeBufferSize == TLC_FADE_BUFFER_LENGTH) {
- return 0; // fade buffer full
- }
- struct Tlc_Fade *p = tlc_fadeBuffer + tlc_fadeBufferSize++;
- p->channel = channel;
- p->startValue = startValue;
- p->changeValue = endValue - startValue;
- p->startMillis = startMillis;
- p->endMillis = endMillis;
- return tlc_fadeBufferSize;
- }
-
- /** Checks to see if any fades are happening on channel
- \param channel the channel to check
- \returns 1 if there is a fade in the buffer on this channel, 0 otherwise */
- uint8_t tlc_isFading(TLC_CHANNEL_TYPE channel)
- {
- struct Tlc_Fade *end = tlc_fadeBuffer + tlc_fadeBufferSize;
- for (struct Tlc_Fade *p = tlc_fadeBuffer; p < end; p++) {
- if (p->channel == channel) {
- return 1;
- }
- }
- return 0;
- }
-
- /** Removes any fades from the fade buffer on this channel.
- \param channel which channel the fades are on
- \returns how many fades were removed */
- uint8_t tlc_removeFades(TLC_CHANNEL_TYPE channel)
- {
- uint8_t removed = 0;
- struct Tlc_Fade *end = tlc_fadeBuffer + tlc_fadeBufferSize;
- for (struct Tlc_Fade *p = tlc_fadeBuffer; p < end; p++) {
- if (p->channel == channel) {
- removed++;
- tlc_removeFadeFromBuffer(p, --end);
- }
- }
- return removed;
- }
-
- /** Copies the end of the buffer to the current and decrements
- tlc_fadeBufferSize. This will change the end of the buffer (pass by
- reference)
- \param current the fade to be removed
- \param endp the end of the fade buffer (pointer to pointer) */
- static void tlc_removeFadeFromBuffer(struct Tlc_Fade *current,
- struct Tlc_Fade *endp)
- {
- if (endp != current) { // if this is not the last fade
- current->channel = endp->channel;
- current->startValue = endp->startValue;
- current->changeValue = endp->changeValue;
- current->startMillis = endp->startMillis;
- current->endMillis = endp->endMillis;
- }
- tlc_fadeBufferSize--;
- }
-
- /** Updates fades using millis()
- \returns 0 if there are no fades left in the buffer. */
- uint8_t tlc_updateFades()
- {
- return tlc_updateFades(millis());
- }
-
- /** Updates any running fades.
- \param currentMillis the current millis() time.
- \returns 0 if there are no fades left in the buffer. */
- uint8_t tlc_updateFades(uint32_t currentMillis)
- {
- struct Tlc_Fade *end = tlc_fadeBuffer + tlc_fadeBufferSize;
- uint8_t needsUpdate = 0;
- for (struct Tlc_Fade *p = tlc_fadeBuffer; p < end;){
- if (currentMillis >= p->endMillis) { // fade done
- Tlc.set(p->channel, p->startValue + p->changeValue);
- needsUpdate = 1;
- tlc_removeFadeFromBuffer(p, --end);
- continue;
- } else {
- uint32_t startMillis = p->startMillis;
- if (currentMillis >= startMillis) {
- Tlc.set(p->channel, p->startValue + p->changeValue
- * (int32_t)(currentMillis - startMillis)
- / (int32_t)(p->endMillis - startMillis));
- needsUpdate = 1;
- }
- }
- p++;
- }
- if (needsUpdate) {
- Tlc.update();
- if (tlc_fadeBufferSize == 0) {
- while (tlc_needXLAT)
- ;
- }
- }
- return tlc_fadeBufferSize;
- }
-
- /* @} */
-
- #endif
|