/*************************************************************************** * Copyright (C) 01/2019 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 #include "pwm.h" #include "timer.h" /* *********************************************************************** */ #define PWM_TIM_16BIT 1 #define PWM_TIM_INIT() { \ /* enable output for OC1A, OC1B, OC3A */ \ DDRB |= (1<= PWM_TABLE_SIZE) { pwm_setpoint[channel] = (PWM_TABLE_SIZE - 1); } if ((pwm_setpoint[channel] > pwm_index[channel]) && (pwm_index[channel] < (PWM_TABLE_SIZE - 1)) ) { pwm_index[channel]++; check_setpoint = 1; } else if ((pwm_setpoint[channel] < pwm_index[channel]) && (pwm_index[channel] > 0) ) { pwm_index[channel]--; check_setpoint = 1; } /* setpoint reached, notify others */ if (check_setpoint) { if (pwm_index[channel] == pwm_setpoint[channel]) { event_queue(EVENT_TYPE_PWM_STATUS, channel, pwm_setpoint[channel]); } else if (!pwm_fade_timer_running) { event_queue(EVENT_TYPE_TIMER_SET, EVENT_NUM_TIMER_PWM, PWM_TIMER_FADE_STEP_MS); pwm_fade_timer_running = 1; } } /* if PWM is zero, disable output */ if (pwm_index[channel] == 0) { switch (channel) { case 0: PWM_CH0_OFF(); break; case 1: PWM_CH1_OFF(); break; case 2: PWM_CH2_OFF(); break; default: break; } } /* if PWM is max, enable output */ else if (pwm_index[channel] == (PWM_TABLE_SIZE - 1)) { switch (channel) { case 0: PWM_CH0_ON(); break; case 1: PWM_CH1_ON(); break; case 2: PWM_CH2_ON(); break; default: break; } } /* else load new PWM into timer */ else { switch (channel) { case 0: PWM_CH0_PWM(PWM_TABLE_GET(pwm_index[0])); break; case 1: PWM_CH1_PWM(PWM_TABLE_GET(pwm_index[1])); break; case 2: PWM_CH2_PWM(PWM_TABLE_GET(pwm_index[2])); break; default: break; } } switch (channel) { case 0: case 1: /* disable timer if all channels are ON or OFF */ if (PWM_TIM1_CHECK()) { PWM_TIM1_ENABLE(); } else { PWM_TIM1_DISABLE(); } break; case 2: /* disable timer if all channels are ON or OFF */ if (PWM_TIM3_CHECK()) { PWM_TIM3_ENABLE(); } else { PWM_TIM3_DISABLE(); } break; } } /* pwm_update */ void pwm_event_handler(event_entry_t * p_event) { if (p_event->type == EVENT_TYPE_PWM_COMMAND) { uint8_t channel = p_event->num; switch (p_event->value) { case EVENT_VALUE_PWM_KEEP: pwm_setpoint[channel] = pwm_index[channel]; break; /* increment PWM */ case EVENT_VALUE_PWM_INC: if (pwm_setpoint[channel] < (PWM_TABLE_SIZE - 1)) { pwm_setpoint[channel]++; } break; /* decrement PWM */ case EVENT_VALUE_PWM_DEC: if (pwm_setpoint[channel] > 0) { pwm_setpoint[channel]--; } break; /* fade to min */ case EVENT_VALUE_PWM_FADE_MIN: pwm_setpoint[channel] = 0; break; /* fade to max */ case EVENT_VALUE_PWM_FADE_MAX: pwm_setpoint[channel] = (PWM_TABLE_SIZE - 1); break; /* toggle between 0 and stored value */ case EVENT_VALUE_PWM_TOGGLE: if (pwm_setpoint[channel] > 5) { pwm_setpoint_save[channel] = pwm_setpoint[channel]; pwm_setpoint[channel] = 0; } else { pwm_setpoint[channel] = pwm_setpoint_save[channel]; } break; default: break; } pwm_update(channel); } else if (p_event->type == EVENT_TYPE_PWM_VALUE) { uint8_t channel = p_event->num; if (p_event->value < PWM_TABLE_SIZE) { pwm_setpoint[channel] = p_event->value; } else { pwm_setpoint[channel] = (PWM_TABLE_SIZE - 1); } pwm_update(channel); } else if ((p_event->type == EVENT_TYPE_TIMER_ELAPSED) && (p_event->num == EVENT_NUM_TIMER_PWM) ) { pwm_fade_timer_running = 0; pwm_update(0); pwm_update(1); pwm_update(2); } } /* pwm_event_handler */ uint8_t pwm_get_sleep_mode(void) { if (PWM_TIM1_RUNNING() || PWM_TIM3_RUNNING()) { return SLEEP_MODE_IDLE; } else { return SLEEP_MODE_PWR_DOWN; } } /* pwm_get_sleep_mode */ void pwm_init(void) { PWM_TIM_INIT(); } /* pwm_init */