Move LED fading to own file

This commit is contained in:
Olaf Rempel 2021-02-06 22:33:52 +01:00
parent 3514b2576c
commit b9c11c6860
9 changed files with 325 additions and 277 deletions

30
event.c
View File

@ -1,5 +1,5 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 01/2019 by Olaf Rempel * * Copyright (C) 02/2021 by Olaf Rempel *
* razzor@kopf-tisch.de * * razzor@kopf-tisch.de *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
@ -23,9 +23,9 @@
/* *********************************************************************** */ /* *********************************************************************** */
static event_entry_t events[EVENT_COUNT]; static event_entry_t m_events[EVENT_COUNT];
static volatile uint8_t event_in_idx; static volatile uint8_t m_event_in_idx;
static volatile uint8_t event_out_idx; static volatile uint8_t m_event_out_idx;
/* *********************************************************************** */ /* *********************************************************************** */
@ -38,14 +38,14 @@ void event_queue(uint8_t type, uint8_t num, uint16_t value)
sreg_save = SREG; sreg_save = SREG;
cli(); cli();
idx = event_in_idx; idx = m_event_in_idx;
p_event = &events[idx++]; p_event = &m_events[idx];
if (p_event->type == EVENT_TYPE_EMPTY) if (p_event->type == EVENT_TYPE_EMPTY)
{ {
p_event->type = type; p_event->type = type;
p_event->num = num; p_event->num = num;
p_event->value = value; p_event->value = value;
event_in_idx = idx % EVENT_COUNT; m_event_in_idx = (idx +1) % EVENT_COUNT;
} }
SREG = sreg_save; SREG = sreg_save;
@ -54,13 +54,19 @@ void event_queue(uint8_t type, uint8_t num, uint16_t value)
event_entry_t * event_get(void) event_entry_t * event_get(void)
{ {
return &events[event_out_idx]; return &m_events[m_event_out_idx];
} /* event_get */ } /* event_get */
void event_clear(void) void event_clear(event_entry_t * p_event)
{ {
uint8_t idx = event_out_idx; uint8_t idx = m_event_out_idx;
events[idx++].type = EVENT_TYPE_EMPTY;
event_out_idx = idx % EVENT_COUNT; if ((p_event == &m_events[idx]) &&
(p_event->type != EVENT_TYPE_EMPTY)
)
{
p_event->type = EVENT_TYPE_EMPTY;
m_event_out_idx = (idx +1) % EVENT_COUNT;
}
} /* event_clear */ } /* event_clear */

14
event.h
View File

@ -1,5 +1,5 @@
#ifndef __EVENT_H__ #ifndef EVENT_H_SEEN
#define __EVENT_H__ #define EVENT_H_SEEN
#include <stdint.h> #include <stdint.h>
@ -8,6 +8,12 @@
#define EVENT_COUNT 16 #define EVENT_COUNT 16
#define EVENT_TYPE_EMPTY 0x00 #define EVENT_TYPE_EMPTY 0x00
#define EVENT_TYPE_TIMER_SET 0x01
#define EVENT_TYPE_TIMER_ELAPSED 0x02
#define EVENT_TYPE_PWM_VALUE 0x03
#define EVENT_TYPE_LEDFADE_COMMAND 0x04
#define EVENT_TYPE_LEDFADE_VALUE 0x05
#define EVENT_TYPE_LEDFADE_STATUS 0x06
typedef struct event_entry_s typedef struct event_entry_s
{ {
@ -20,8 +26,8 @@ typedef struct event_entry_s
void event_queue (uint8_t type, uint8_t num, uint16_t value); void event_queue (uint8_t type, uint8_t num, uint16_t value);
event_entry_t * event_get (void); event_entry_t * event_get (void);
void event_clear (void); void event_clear (event_entry_t * p_event);
/* *********************************************************************** */ /* *********************************************************************** */
#endif /* __EVENT_H__ */ #endif /* EVENT_H_SEEN */

199
ledfade.c Normal file
View File

@ -0,0 +1,199 @@
/***************************************************************************
* 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 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)
{
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);
}
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);
}
else if ((p_event->type == EVENT_TYPE_TIMER_ELAPSED) &&
(p_event->num == EVENT_NUM_TIMER_LEDFADE)
)
{
m_ledfade_timer_running = 0;
ledfade_update(0);
ledfade_update(1);
}
} /* ledfade_event_handler */

25
ledfade.h Normal file
View File

@ -0,0 +1,25 @@
#ifndef LEDFADE_H_SEEN
#define LEDFADE_H_SEEN
#include <stdint.h>
#include "event.h"
/* *********************************************************************** */
#define EVENT_NUM_LED_CH0 0x00
#define EVENT_NUM_LED_CH1 0x01
#define EVENT_VALUE_LEDFADE_KEEP 0x00
#define EVENT_VALUE_LEDFADE_INC 0x01
#define EVENT_VALUE_LEDFADE_DEC 0x02
#define EVENT_VALUE_LEDFADE_MIN 0x03
#define EVENT_VALUE_LEDFADE_MAX 0x04
#define EVENT_VALUE_LEDFADE_TOGGLE 0x05
/* *********************************************************************** */
void ledfade_event_handler (event_entry_t * p_event);
/* *********************************************************************** */
#endif /* LEDFADE_H_SEEN */

36
main.c
View File

@ -6,6 +6,7 @@
#include "Descriptors.h" #include "Descriptors.h"
#include "event.h" #include "event.h"
#include "ledfade.h"
#include "pwm.h" #include "pwm.h"
#include "timer.h" #include "timer.h"
@ -47,9 +48,9 @@ int main(void)
GlobalInterruptEnable(); GlobalInterruptEnable();
event_queue(EVENT_TYPE_PWM_COMMAND, 0, EVENT_VALUE_PWM_FADE_MAX); event_queue(EVENT_TYPE_LEDFADE_COMMAND, EVENT_NUM_LED_CH0, EVENT_VALUE_LEDFADE_MAX);
event_queue(EVENT_TYPE_PWM_COMMAND, 1, EVENT_VALUE_PWM_FADE_MAX); event_queue(EVENT_TYPE_LEDFADE_COMMAND, EVENT_NUM_LED_CH1, EVENT_VALUE_LEDFADE_MAX);
event_queue(EVENT_TYPE_PWM_COMMAND, 2, EVENT_VALUE_PWM_FADE_MAX); event_queue(EVENT_TYPE_PWM_VALUE, EVENT_NUM_PWM_CH2, 0x8000);
for (;;) for (;;)
{ {
@ -59,35 +60,36 @@ int main(void)
timer_check(0); timer_check(0);
event_entry_t* p_event = event_get(); event_entry_t* p_event = event_get();
if (p_event->type != EVENT_TYPE_EMPTY)
{
switch (p_event->type) switch (p_event->type)
{ {
case EVENT_TYPE_PWM_COMMAND:
case EVENT_TYPE_PWM_VALUE:
pwm_event_handler(p_event);
break;
case EVENT_TYPE_PWM_STATUS:
break;
case EVENT_TYPE_TIMER_SET: case EVENT_TYPE_TIMER_SET:
timer_event_handler(p_event); timer_event_handler(p_event);
break; break;
case EVENT_TYPE_TIMER_ELAPSED: case EVENT_TYPE_TIMER_ELAPSED:
if (p_event->num == EVENT_NUM_TIMER_PWM) if (p_event->num == EVENT_NUM_TIMER_LEDFADE)
{ {
pwm_event_handler(p_event); ledfade_event_handler(p_event);
} }
break; break;
case EVENT_TYPE_PWM_VALUE:
pwm_event_handler(p_event);
break;
case EVENT_TYPE_LEDFADE_COMMAND:
case EVENT_TYPE_LEDFADE_VALUE:
ledfade_event_handler(p_event);
break;
case EVENT_TYPE_LEDFADE_STATUS:
break;
default: default:
break; break;
} }
event_clear(); event_clear(p_event);
}
} }
} }

214
pwm.c
View File

@ -1,5 +1,5 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 01/2019 by Olaf Rempel * * Copyright (C) 02/2021 by Olaf Rempel *
* razzor@kopf-tisch.de * * razzor@kopf-tisch.de *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
@ -17,34 +17,26 @@
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#include <avr/interrupt.h> #include <avr/io.h>
#include <avr/pgmspace.h>
#include "pwm.h" #include "pwm.h"
#include "timer.h"
/* *********************************************************************** */ /* *********************************************************************** */
#define PWM_TIM_16BIT 1 #define PWM_MIN 0x0000
#define PWM_MAX 0xFFFF
#define PWM_TIM_INIT() { \ #define PWM_TIM_INIT() { \
/* enable output for OC1A, OC1B, OC3A */ \ /* enable output for OC1A, OC1B, OC3A */ \
DDRB |= (1<<PORTB5) | (1<<PORTB6); \ DDRB |= (1<<PORTB5) | (1<<PORTB6); \
DDRC |= (1<<PORTC6); \ DDRC |= (1<<PORTC6); \
/* reset and hold prescaler */ \
GTCCR = (1<<TSM) | (1<<PSRSYNC); \
/* FastModePWM, ICRn is TOP */ \ /* FastModePWM, ICRn is TOP */ \
TCCR1A = (1<<WGM11); \ TCCR1A = (1<<WGM11); \
TCCR1B = (1<<WGM13) | (1<<WGM12); \ TCCR1B = (1<<WGM13) | (1<<WGM12); \
ICR1 = 0xFFFF; \ ICR1 = 0xFFFF; \
TCNT1 = 0x0000; \
TCCR3A = (1<<WGM31); \ TCCR3A = (1<<WGM31); \
TCCR3B = (1<<WGM33) | (1<<WGM32); \ TCCR3B = (1<<WGM33) | (1<<WGM32); \
ICR3 = 0xFFFF; \ ICR3 = 0xFFFF; \
TCNT3 = 0x8000; \
/* release prescaler */ \
GTCCR = (1<<PSRSYNC); \
} }
#define PWM_TIM1_ENABLE() { TCCR1B |= (1<<CS10); } #define PWM_TIM1_ENABLE() { TCCR1B |= (1<<CS10); }
@ -57,107 +49,30 @@
#define PWM_TIM3_RUNNING() (TCCR3B & ((1<<CS30) | (1<<CS31) | (1<<CS32))) #define PWM_TIM3_RUNNING() (TCCR3B & ((1<<CS30) | (1<<CS31) | (1<<CS32)))
#define PWM_TIM3_CHECK() (TCCR3A & ((1<<COM3A1) | (1<<COM3B1))) #define PWM_TIM3_CHECK() (TCCR3A & ((1<<COM3A1) | (1<<COM3B1)))
#define PWM_TIMER_FADE_STEP_MS 10
#define PWM_CH0_PORT PORTB #define PWM_CH0_PORT PORTB
#define PWM_CH0_NUM 5 #define PWM_CH0_NUM 5
#define PWM_CH0_OFF() { PWM_CH0_PORT &= ~(1<<PWM_CH0_NUM); TCCR1A &= ~(1<<COM1A1); } #define PWM_CH0_OFF() { PWM_CH0_PORT &= ~(1<<PWM_CH0_NUM); TCCR1A &= ~(1<<COM1A1); }
#define PWM_CH0_ON() { PWM_CH0_PORT |= (1<<PWM_CH0_NUM); TCCR1A &= ~(1<<COM1A1); } #define PWM_CH0_ON() { PWM_CH0_PORT |= (1<<PWM_CH0_NUM); TCCR1A &= ~(1<<COM1A1); }
#define PWM_CH0_PWM(x) { PWM_CH0_PORT &= ~(1<<PWM_CH0_NUM); TCCR1A |= (1<<COM1A1); OCR1A = x; } #define PWM_CH0_PWM(x) { PWM_CH0_PORT &= ~(1<<PWM_CH0_NUM); TCCR1A |= (1<<COM1A1); OCR1A = x; }
#define PWM_CH1_PORT PORTB #define PWM_CH1_PORT PORTC
#define PWM_CH1_NUM 6 #define PWM_CH1_NUM 6
#define PWM_CH1_OFF() { PWM_CH1_PORT &= ~(1<<PWM_CH1_NUM); TCCR1A &= ~(1<<COM1B1); } #define PWM_CH1_OFF() { PWM_CH1_PORT &= ~(1<<PWM_CH1_NUM); TCCR3A &= ~(1<<COM3A1); }
#define PWM_CH1_ON() { PWM_CH1_PORT |= (1<<PWM_CH1_NUM); TCCR1A &= ~(1<<COM1B1); } #define PWM_CH1_ON() { PWM_CH1_PORT |= (1<<PWM_CH1_NUM); TCCR3A &= ~(1<<COM3A1); }
#define PWM_CH1_PWM(x) { PWM_CH1_PORT &= ~(1<<PWM_CH1_NUM); TCCR1A |= (1<<COM1B1); OCR1B = x; } #define PWM_CH1_PWM(x) { PWM_CH1_PORT &= ~(1<<PWM_CH1_NUM); TCCR3A |= (1<<COM3A1); OCR3A = x; }
#define PWM_CH2_PORT PORTC #define PWM_CH2_PORT PORTB
#define PWM_CH2_NUM 6 #define PWM_CH2_NUM 6
#define PWM_CH2_OFF() { PWM_CH2_PORT &= ~(1<<PWM_CH2_NUM); TCCR3A &= ~(1<<COM3A1); } #define PWM_CH2_OFF() { PWM_CH2_PORT &= ~(1<<PWM_CH2_NUM); TCCR1A &= ~(1<<COM1B1); }
#define PWM_CH2_ON() { PWM_CH2_PORT |= (1<<PWM_CH2_NUM); TCCR3A &= ~(1<<COM3A1); } #define PWM_CH2_ON() { PWM_CH2_PORT |= (1<<PWM_CH2_NUM); TCCR1A &= ~(1<<COM1B1); }
#define PWM_CH2_PWM(x) { PWM_CH2_PORT &= ~(1<<PWM_CH2_NUM); TCCR3A |= (1<<COM3A1); OCR3A = x; } #define PWM_CH2_PWM(x) { PWM_CH2_PORT &= ~(1<<PWM_CH2_NUM); TCCR1A |= (1<<COM1B1); OCR1B = x; }
#if (PWM_TIM_16BIT)
#define PWM_TABLE_SIZE 128
#define PWM_TABLE_GET(x) pgm_read_word(&pwmtable16[x])
const uint16_t pwmtable16[PWM_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 PWM_TABLE_SIZE 32
#define PWM_TABLE_GET(x) pgm_read_byte(&pwmtable8[x])
const uint8_t pwmtable8[PWM_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
static uint8_t pwm_index[3];
static uint8_t pwm_setpoint[3];
static uint8_t pwm_setpoint_save[3];
static uint8_t pwm_fade_timer_running;
/* *********************************************************************** */ /* *********************************************************************** */
static void pwm_update(uint8_t channel) static void pwm_update(uint8_t channel, uint16_t value)
{ {
uint8_t check_setpoint = 0;
if (pwm_setpoint[channel] >= 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 is zero, disable output */
if (pwm_index[channel] == 0) if (value == PWM_MIN)
{ {
switch (channel) switch (channel)
{ {
@ -178,7 +93,7 @@ static void pwm_update(uint8_t channel)
} }
} }
/* if PWM is max, enable output */ /* if PWM is max, enable output */
else if (pwm_index[channel] == (PWM_TABLE_SIZE - 1)) else if (value == PWM_MAX)
{ {
switch (channel) switch (channel)
{ {
@ -204,15 +119,15 @@ static void pwm_update(uint8_t channel)
switch (channel) switch (channel)
{ {
case 0: case 0:
PWM_CH0_PWM(PWM_TABLE_GET(pwm_index[0])); PWM_CH0_PWM(value);
break; break;
case 1: case 1:
PWM_CH1_PWM(PWM_TABLE_GET(pwm_index[1])); PWM_CH1_PWM(value);
break; break;
case 2: case 2:
PWM_CH2_PWM(PWM_TABLE_GET(pwm_index[2])); PWM_CH2_PWM(value);
break; break;
default: default:
@ -223,7 +138,7 @@ static void pwm_update(uint8_t channel)
switch (channel) switch (channel)
{ {
case 0: case 0:
case 1: case 2:
/* disable timer if all channels are ON or OFF */ /* disable timer if all channels are ON or OFF */
if (PWM_TIM1_CHECK()) if (PWM_TIM1_CHECK())
{ {
@ -235,7 +150,7 @@ static void pwm_update(uint8_t channel)
} }
break; break;
case 2: case 1:
/* disable timer if all channels are ON or OFF */ /* disable timer if all channels are ON or OFF */
if (PWM_TIM3_CHECK()) if (PWM_TIM3_CHECK())
{ {
@ -252,99 +167,16 @@ static void pwm_update(uint8_t channel)
void pwm_event_handler(event_entry_t * p_event) void pwm_event_handler(event_entry_t * p_event)
{ {
if (p_event->type == EVENT_TYPE_PWM_COMMAND) if (p_event->type == EVENT_TYPE_PWM_VALUE)
{ {
uint8_t channel = p_event->num; pwm_update(p_event->num, p_event->value);
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 */ } /* pwm_event_handler */
uint8_t pwm_get_sleep_mode(void) uint8_t pwm_get_sleep_mode(void)
{ {
if (PWM_TIM1_RUNNING() || PWM_TIM3_RUNNING()) return !!(PWM_TIM1_RUNNING() || PWM_TIM3_RUNNING());
{
return SLEEP_MODE_IDLE;
}
else
{
return SLEEP_MODE_PWR_DOWN;
}
} /* pwm_get_sleep_mode */ } /* pwm_get_sleep_mode */

19
pwm.h
View File

@ -1,32 +1,21 @@
#ifndef __PWM_H__ #ifndef PWM_H_SEEN
#define __PWM_H__ #define PWM_H_SEEN
#include <stdint.h> #include <stdint.h>
#include "event.h" #include "event.h"
/* *********************************************************************** */ /* *********************************************************************** */
#define EVENT_TYPE_PWM_COMMAND 0x04
#define EVENT_TYPE_PWM_VALUE 0x05
#define EVENT_TYPE_PWM_STATUS 0x06
#define EVENT_NUM_PWM_CH0 0x00 #define EVENT_NUM_PWM_CH0 0x00
#define EVENT_NUM_PWM_CH1 0x01 #define EVENT_NUM_PWM_CH1 0x01
#define EVENT_NUM_PWM_CH2 0x02 #define EVENT_NUM_PWM_CH2 0x02
#define EVENT_VALUE_PWM_KEEP 0x00
#define EVENT_VALUE_PWM_INC 0x01
#define EVENT_VALUE_PWM_DEC 0x02
#define EVENT_VALUE_PWM_FADE_MIN 0x03
#define EVENT_VALUE_PWM_FADE_MAX 0x04
#define EVENT_VALUE_PWM_TOGGLE 0x05
/* *********************************************************************** */ /* *********************************************************************** */
void pwm_init (void); void pwm_init (void);
void pwm_event_handler (event_entry_t * p_event); void pwm_event_handler (event_entry_t * p_event);
uint8_t pwm_get_sleep_mode (void); uint8_t pwm_need_hw_clock (void);
/* *********************************************************************** */ /* *********************************************************************** */
#endif /* __PWM_H__ */ #endif /* PWM_H_SEEN */

32
timer.c
View File

@ -18,7 +18,6 @@
***************************************************************************/ ***************************************************************************/
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include <avr/io.h> #include <avr/io.h>
#include <avr/sleep.h>
#include "event.h" #include "event.h"
#include "timer.h" #include "timer.h"
@ -43,8 +42,8 @@
#define TIMER_MSEC2TICKS(x) ((x * F_CPU) / (TIMER_DIVISOR * 1000ULL)) #define TIMER_MSEC2TICKS(x) ((x * F_CPU) / (TIMER_DIVISOR * 1000ULL))
#define TIMER_MSEC2IRQCNT(x) (x / TIMER_IRQFREQ_MS) #define TIMER_MSEC2IRQCNT(x) (x / TIMER_IRQFREQ_MS)
static uint16_t timers[TIMER_COUNT]; static uint16_t m_timers[TIMER_COUNT];
volatile static uint8_t timer_ticked; volatile static uint8_t m_timer_ticked;
/* *********************************************************************** */ /* *********************************************************************** */
@ -53,24 +52,24 @@ ISR(TIMER_TIM_VECT)
/* 1ms interrupt */ /* 1ms interrupt */
TIMER_TIM_RELOAD(TIMER_MSEC2TICKS(TIMER_IRQFREQ_MS)); TIMER_TIM_RELOAD(TIMER_MSEC2TICKS(TIMER_IRQFREQ_MS));
timer_ticked = 1; m_timer_ticked = 1;
} /* TIM1_OVF_vect */ } /* TIM1_OVF_vect */
uint8_t timer_check(uint8_t timer_needed) uint8_t timer_check(uint8_t timer_needed)
{ {
if (timer_ticked) if (m_timer_ticked)
{ {
uint8_t i; uint8_t i;
timer_ticked = 0; m_timer_ticked = 0;
for (i = 0; i < TIMER_COUNT; i++) for (i = 0; i < TIMER_COUNT; i++)
{ {
if (timers[i] > 0) if (m_timers[i] > 0)
{ {
timers[i]--; m_timers[i]--;
if (timers[i] == 0) if (m_timers[i] == 0)
{ {
event_queue(EVENT_TYPE_TIMER_ELAPSED, i, 0); event_queue(EVENT_TYPE_TIMER_ELAPSED, i, 0);
} }
@ -100,7 +99,7 @@ void timer_event_handler(event_entry_t * p_event)
(p_event->num < TIMER_COUNT) (p_event->num < TIMER_COUNT)
) )
{ {
timers[p_event->num] = p_event->value; m_timers[p_event->num] = p_event->value;
/* start timer if needed */ /* start timer if needed */
if (!TIMER_TIM_RUNNING()) if (!TIMER_TIM_RUNNING())
@ -112,17 +111,10 @@ void timer_event_handler(event_entry_t * p_event)
} /* timer_event_handler */ } /* timer_event_handler */
uint8_t timer_get_sleep_mode(void) uint8_t timer_need_hw_clock(void)
{ {
if (TIMER_TIM_RUNNING()) return !!TIMER_TIM_RUNNING();
{ } /* timer_get_sleep_mode */
return SLEEP_MODE_IDLE;
}
else
{
return SLEEP_MODE_PWR_DOWN;
}
} /* timer_get_sleep_mode */
void timer_init(void) void timer_init(void)

13
timer.h
View File

@ -1,5 +1,5 @@
#ifndef __TIMER_H__ #ifndef TIMER_H_SEEN
#define __TIMER_H__ #define TIMER_H_SEEN
#include <stdint.h> #include <stdint.h>
#include "event.h" #include "event.h"
@ -8,18 +8,15 @@
#define TIMER_COUNT 1 #define TIMER_COUNT 1
#define EVENT_TYPE_TIMER_SET 0x01 #define EVENT_NUM_TIMER_LEDFADE 0
#define EVENT_TYPE_TIMER_ELAPSED 0x02
#define EVENT_NUM_TIMER_PWM 0
/* *********************************************************************** */ /* *********************************************************************** */
void timer_init (void); void timer_init (void);
uint8_t timer_check (uint8_t timer_needed); uint8_t timer_check (uint8_t timer_needed);
void timer_event_handler (event_entry_t * p_event); void timer_event_handler (event_entry_t * p_event);
uint8_t timer_get_sleep_mode (void); uint8_t timer_need_hw_clock (void);
/* *********************************************************************** */ /* *********************************************************************** */
#endif /* __TIMER_H__ */ #endif /* TIMER_H_SEEN */