mirror of
https://github.com/PaulStoffregen/Tlc5940
synced 2025-06-27 02:17:53 +02:00
212 lines
7.3 KiB
C
212 lines
7.3 KiB
C
/* 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
|
|
|