200 lines
6.6 KiB
C
200 lines
6.6 KiB
C
/***************************************************************************
|
|
* Copyright (C) 02/2021 by Olaf Rempel *
|
|
* razzor@kopf-tisch.de *
|
|
* *
|
|
* This program 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; version 2 of the License, *
|
|
* *
|
|
* This program 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 this program; if not, write to the *
|
|
* Free Software Foundation, Inc., *
|
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
|
***************************************************************************/
|
|
|
|
#include <avr/pgmspace.h>
|
|
|
|
#include "event.h"
|
|
#include "ledfade.h"
|
|
#include "timer.h"
|
|
|
|
/* *********************************************************************** */
|
|
|
|
#define LEDFADE_CHANNEL_COUNT 2
|
|
#define LEDFADE_FULL_FADE_MS 1000
|
|
#define LEDFADE_16BIT 1
|
|
|
|
#if (LEDFADE_16BIT)
|
|
#define LEDFADE_TABLE_SIZE 128
|
|
#define LEDFADE_TABLE_GET(x) pgm_read_word(&m_ledfade_table16[x])
|
|
const uint16_t m_ledfade_table16[LEDFADE_TABLE_SIZE] PROGMEM =
|
|
{
|
|
0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5,
|
|
6, 6, 7, 8, 9, 9, 10, 11, 12, 14, 15, 16, 18, 20, 22, 24, 26,
|
|
28, 31, 34, 37, 40, 44, 48, 53, 58, 63, 69, 75, 82, 90, 98,
|
|
107, 116, 127, 139, 151, 165, 180, 196, 214, 234, 255, 278,
|
|
303, 331, 361, 394, 430, 469, 511, 557, 608, 663, 723, 789,
|
|
860, 938, 1023, 1116, 1217, 1327, 1447, 1578, 1721, 1877,
|
|
2047, 2232, 2434, 2655, 2895, 3157, 3443, 3755, 4095, 4466,
|
|
4870, 5311, 5792, 6316, 6888, 7511, 8191, 8932, 9741, 10623,
|
|
11584, 12633, 13776, 15023, 16383, 17866, 19483, 21246, 23169,
|
|
25267, 27553, 30047, 32767, 35733, 38967, 42494, 46340, 50534,
|
|
55108, 60096, 65535
|
|
};
|
|
#else
|
|
#define LEDFADE_TABLE_SIZE 32
|
|
#define LEDFADE_TABLE_GET(x) pgm_read_byte(&m_ledfade_table8[x])
|
|
const uint8_t m_ledfade_table8[LEDFADE_TABLE_SIZE] PROGMEM =
|
|
{
|
|
0, 0, 1, 1, 1, 2, 2, 3,
|
|
4, 5, 6, 7, 9, 10, 12, 15,
|
|
18, 22, 26, 31, 37, 44, 53, 63,
|
|
75, 90, 107, 127, 151, 180, 214, 255
|
|
};
|
|
#endif
|
|
|
|
#define LEDFADE_FADE_STEP_MS ((LEDFADE_FULL_FADE_MS + LEDFADE_TABLE_SIZE) / LEDFADE_TABLE_SIZE)
|
|
|
|
static uint8_t m_ledfade_value[LEDFADE_CHANNEL_COUNT];
|
|
static uint8_t m_ledfade_setpoint[LEDFADE_CHANNEL_COUNT];
|
|
static uint8_t m_ledfade_setpoint_save[LEDFADE_CHANNEL_COUNT];
|
|
static uint8_t m_ledfade_timer_running;
|
|
|
|
/* *********************************************************************** */
|
|
|
|
static void ledfade_update(uint8_t channel, uint8_t force_event)
|
|
{
|
|
uint8_t update_pwm = 0;
|
|
|
|
if (m_ledfade_setpoint[channel] >= LEDFADE_TABLE_SIZE)
|
|
{
|
|
m_ledfade_setpoint[channel] = (LEDFADE_TABLE_SIZE -1);
|
|
}
|
|
|
|
if ((m_ledfade_setpoint[channel] > m_ledfade_value[channel]) &&
|
|
(m_ledfade_value[channel] < (LEDFADE_TABLE_SIZE -1))
|
|
)
|
|
{
|
|
m_ledfade_value[channel]++;
|
|
update_pwm = 1;
|
|
}
|
|
else if ((m_ledfade_setpoint[channel] < m_ledfade_value[channel]) &&
|
|
(m_ledfade_value[channel] > 0)
|
|
)
|
|
{
|
|
m_ledfade_value[channel]--;
|
|
update_pwm = 1;
|
|
}
|
|
|
|
if (update_pwm || force_event)
|
|
{
|
|
event_queue(EVENT_TYPE_PWM_VALUE,
|
|
channel,
|
|
LEDFADE_TABLE_GET(m_ledfade_value[channel]));
|
|
|
|
if (m_ledfade_value[channel] == m_ledfade_setpoint[channel])
|
|
{
|
|
event_queue(EVENT_TYPE_LEDFADE_STATUS,
|
|
channel,
|
|
m_ledfade_value[channel]);
|
|
}
|
|
else if (!m_ledfade_timer_running)
|
|
{
|
|
event_queue(EVENT_TYPE_TIMER_SET,
|
|
EVENT_NUM_TIMER_LEDFADE,
|
|
LEDFADE_FADE_STEP_MS);
|
|
|
|
m_ledfade_timer_running = 1;
|
|
}
|
|
}
|
|
} /* ledfade_update */
|
|
|
|
|
|
void ledfade_event_handler(event_entry_t * p_event)
|
|
{
|
|
if (p_event->type == EVENT_TYPE_LEDFADE_COMMAND)
|
|
{
|
|
uint8_t channel = p_event->num;
|
|
|
|
switch (p_event->value)
|
|
{
|
|
case EVENT_VALUE_LEDFADE_KEEP:
|
|
m_ledfade_setpoint[channel] = m_ledfade_value[channel];
|
|
break;
|
|
|
|
/* increment */
|
|
case EVENT_VALUE_LEDFADE_INC:
|
|
if (m_ledfade_setpoint[channel] < (LEDFADE_TABLE_SIZE -1))
|
|
{
|
|
m_ledfade_setpoint[channel]++;
|
|
}
|
|
break;
|
|
|
|
/* decrement */
|
|
case EVENT_VALUE_LEDFADE_DEC:
|
|
if (m_ledfade_setpoint[channel] > 0)
|
|
{
|
|
m_ledfade_setpoint[channel]--;
|
|
}
|
|
break;
|
|
|
|
/* fade to min */
|
|
case EVENT_VALUE_LEDFADE_MIN:
|
|
m_ledfade_setpoint[channel] = 0;
|
|
break;
|
|
|
|
/* fade to max */
|
|
case EVENT_VALUE_LEDFADE_MAX:
|
|
m_ledfade_setpoint[channel] = (LEDFADE_TABLE_SIZE -1);
|
|
break;
|
|
|
|
/* toggle between 0 and stored value */
|
|
case EVENT_VALUE_LEDFADE_TOGGLE:
|
|
if (m_ledfade_setpoint[channel] > 5)
|
|
{
|
|
m_ledfade_setpoint_save[channel] = m_ledfade_setpoint[channel];
|
|
m_ledfade_setpoint[channel] = 0;
|
|
}
|
|
else
|
|
{
|
|
m_ledfade_setpoint[channel] = m_ledfade_setpoint_save[channel];
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
ledfade_update(channel, 1);
|
|
}
|
|
else if (p_event->type == EVENT_TYPE_LEDFADE_VALUE)
|
|
{
|
|
uint8_t channel = p_event->num;
|
|
|
|
if (p_event->value < LEDFADE_TABLE_SIZE)
|
|
{
|
|
m_ledfade_setpoint[channel] = p_event->value;
|
|
}
|
|
else
|
|
{
|
|
m_ledfade_setpoint[channel] = (LEDFADE_TABLE_SIZE -1);
|
|
}
|
|
|
|
ledfade_update(channel, 1);
|
|
}
|
|
else if ((p_event->type == EVENT_TYPE_TIMER_ELAPSED) &&
|
|
(p_event->num == EVENT_NUM_TIMER_LEDFADE)
|
|
)
|
|
{
|
|
m_ledfade_timer_running = 0;
|
|
|
|
ledfade_update(0, 0);
|
|
ledfade_update(1, 0);
|
|
}
|
|
} /* ledfade_event_handler */
|