/*************************************************************************** * 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 #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 */