update from closetlight

This commit is contained in:
Olaf Rempel 2017-11-27 21:30:20 +01:00
parent 3467373aed
commit e6487845b4
12 changed files with 240 additions and 103 deletions

View File

@ -23,6 +23,8 @@ LDFLAGS = -Wl,-Map,$(@:.elf=.map),--cref,--relax,--gc-sections
# ---------------------------------------------------------------------------
all: $(TARGET)
$(TARGET): $(BUILD_DIR)/$(TARGET).elf
@$(SIZE) -B -x --mcu=$(MCU) $<

17
event.c
View File

@ -16,26 +16,31 @@
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include <avr/interrupt.h>
#include <avr/io.h>
#include "event.h"
#include "target.h"
/* *********************************************************************** */
#define EVENT_COUNT 16
static struct event_entry events[EVENT_COUNT];
static volatile uint8_t event_in_idx;
static volatile uint8_t event_out_idx;
/* *********************************************************************** */
void event_queue(uint8_t type, uint8_t num, uint16_t value)
{
uint8_t idx = event_in_idx;
struct event_entry *event = &events[idx++];
struct event_entry *event;
uint8_t sreg_save;
uint8_t idx;
sreg_save = SREG;
cli();
idx = event_in_idx;
event = &events[idx++];
if (event->type == EVENT_TYPE_EMPTY)
{
event->type = type;
@ -43,6 +48,8 @@ void event_queue(uint8_t type, uint8_t num, uint16_t value)
event->value = value;
event_in_idx = idx % EVENT_COUNT;
}
SREG = sreg_save;
} /* event_queue */

View File

@ -17,6 +17,7 @@ struct event_entry
#define EVENT_TYPE_INPUT_INCDEC 0x12
#define EVENT_TYPE_PWM_COMMAND 0x18
#define EVENT_TYPE_PWM_VALUE 0x19
#define EVENT_TYPE_PWM_STATUS 0x1A
#define EVENT_TYPE_TIMER_SET 0xF0
#define EVENT_TYPE_TIMER_ELAPSED 0xF1

View File

@ -55,16 +55,6 @@ static const struct _description_response event_desc[] PROGMEM = {
#define LED_TX 1
static uint8_t led[2];
volatile static uint8_t clock_tick;
ISR(TIMER0_OVF_vect)
{
/* 1ms interrupt */
TCNT0 = TIMER_RELOAD;
clock_tick = 1;
} /* TIMER0_OVF_vect */
static void led_tick(void)
{
@ -108,10 +98,7 @@ int main(void)
{
LED_INIT();
/* timer0, FCPU/64, overflow interrupt */
TCCR0B = (1<<CS01) | (1<<CS00);
TIMSK0 = (1<<TOIE0);
timer_init();
uart_init();
input_init();
pwm_init();
@ -124,16 +111,12 @@ int main(void)
while (1)
{
if (clock_tick)
if (timer_check(1))
{
clock_tick = 0;
/* do periodic work (wait for 5 ticks silence before start TX) */
rfm12_tick(5);
led_tick();
input_tick();
timer_tick();
}
struct event_entry *event = event_get();
@ -157,6 +140,9 @@ int main(void)
pwm_event_handler(event);
break;
case EVENT_TYPE_PWM_STATUS:
break;
case EVENT_TYPE_INPUT_INCDEC:
if (event->num == EVENT_NUM_INPUT_QUAD)
{
@ -184,7 +170,7 @@ int main(void)
{
event_queue(EVENT_TYPE_PWM_COMMAND,
EVENT_NUM_PWM_CH1,
PWM_MODE_TOGGLE
EVENT_VALUE_PWM_TOGGLE
);
}
}
@ -201,7 +187,7 @@ int main(void)
);
event_queue(EVENT_TYPE_TIMER_SET,
TIMER_DOOR_CLOSE_DELAY,
EVENT_NUM_TIMER_DOOR_CLOSE_DELAY,
2000
);
}
@ -213,7 +199,7 @@ int main(void)
);
event_queue(EVENT_TYPE_TIMER_SET,
TIMER_DOOR_CLOSE_DELAY,
EVENT_NUM_TIMER_DOOR_CLOSE_DELAY,
0
);
}
@ -225,7 +211,7 @@ int main(void)
break;
case EVENT_TYPE_TIMER_ELAPSED:
if (event->num == TIMER_DOOR_CLOSE_DELAY)
if (event->num == EVENT_NUM_TIMER_DOOR_CLOSE_DELAY)
{
event_queue(EVENT_TYPE_PWM_COMMAND,
EVENT_NUM_PWM_CH0,

49
input.c
View File

@ -19,8 +19,9 @@
#include <avr/io.h>
#include <avr/interrupt.h>
#include "input.h"
#include "event.h"
#include "input.h"
#include "timer.h"
/* *********************************************************************** */
@ -38,11 +39,15 @@ static uint8_t input_old_state[2];
static void input_send_event(uint8_t type, uint8_t num, uint8_t state)
{
if ((debounce_timer[num] == 0) && (state != input_old_state[num]))
if ((debounce_timer[num] == 0) &&
(state != input_old_state[num])
)
{
event_queue(type, num, state);
debounce_timer[num] = 1;
event_queue(type, num, state);
event_queue(EVENT_TYPE_TIMER_SET, num, INPUT_DEBOUNCE_TIMER);
debounce_timer[num] = INPUT_DEBOUNCE_TIMER;
input_old_state[num] = state;
}
} /* input_send_event */
@ -117,16 +122,14 @@ ISR(PCINT1_vect)
{
event_queue(EVENT_TYPE_INPUT_INCDEC,
EVENT_NUM_INPUT_QUAD,
EVENT_VALUE_INPUT_QUAD_DEC
);
EVENT_VALUE_INPUT_QUAD_DEC);
}
/* clock wise */
else if (quad_state == 2)
{
event_queue(EVENT_TYPE_INPUT_INCDEC,
EVENT_NUM_INPUT_QUAD,
EVENT_VALUE_INPUT_QUAD_INC
);
EVENT_VALUE_INPUT_QUAD_INC);
}
}
@ -142,30 +145,34 @@ ISR(PCINT1_vect)
} /* PCINT1_vect */
void input_tick(void)
void input_event_handler(struct event_entry *event)
{
if (debounce_timer[EVENT_NUM_INPUT_BUTTON] > 0)
if (event->type == EVENT_TYPE_TIMER_ELAPSED)
{
debounce_timer[EVENT_NUM_INPUT_BUTTON]--;
if (debounce_timer[EVENT_NUM_INPUT_BUTTON] == 0)
if (event->num == EVENT_NUM_TIMER_DEBOUNCE1)
{
input_send_event(EVENT_TYPE_INPUT_BUTTON,
debounce_timer[EVENT_NUM_INPUT_BUTTON] = 0;
input_send_event(EVENT_TYPE_INPUT_SWITCH,
EVENT_NUM_INPUT_BUTTON,
!!(PINC & (1<<PINC2)));
}
}
if (debounce_timer[EVENT_NUM_INPUT_DOOR] > 0)
{
debounce_timer[EVENT_NUM_INPUT_DOOR]--;
if (debounce_timer[EVENT_NUM_INPUT_DOOR] == 0)
else if (event->num == EVENT_NUM_TIMER_DEBOUNCE2)
{
debounce_timer[EVENT_NUM_INPUT_DOOR] = 0;
input_send_event(EVENT_TYPE_INPUT_SWITCH,
EVENT_NUM_INPUT_DOOR,
!(PINC & (1<<PINC3)));
!!(PINC & (1<<PINC3)));
}
}
} /* input_tick */
} /* input_event_handler */
uint8_t input_get_sleep_mode(void)
{
return SLEEP_MODE_PWR_DOWN;
} /* input_get_sleep_mode */
void input_init(void)

View File

@ -1,6 +1,8 @@
#ifndef __INPUT_H__
#define __INPUT_H__
#include "event.h"
/* *********************************************************************** */
#define EVENT_NUM_INPUT_BUTTON 0x00
@ -16,8 +18,9 @@
/* *********************************************************************** */
void input_init(void);
void input_tick(void);
void input_init (void);
void input_event_handler (struct event_entry *event);
uint8_t input_get_sleep_mode(void);
/* *********************************************************************** */

90
pwm.c
View File

@ -22,12 +22,14 @@
#include "event.h"
#include "pwm.h"
#include "target.h"
/* *********************************************************************** */
const uint16_t pwmtable[128] PROGMEM =
#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,
@ -41,8 +43,17 @@ const uint16_t pwmtable[128] PROGMEM =
25267, 27553, 30047, 32767, 35733, 38967, 42494, 46340, 50534,
55108, 60096, 65535
};
#define PWMTABLE_SIZE (sizeof(pwmtable) / sizeof(uint16_t))
#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[2];
static uint8_t pwm_setpoint[2];
@ -64,7 +75,7 @@ void pwm_event_handler(struct event_entry *event)
/* increment PWM */
case EVENT_VALUE_PWM_INC:
if (pwm_setpoint[channel] < (PWMTABLE_SIZE -1))
if (pwm_setpoint[channel] < (PWM_TABLE_SIZE -1))
{
pwm_setpoint[channel]++;
}
@ -85,11 +96,10 @@ void pwm_event_handler(struct event_entry *event)
/* fade to max */
case EVENT_VALUE_PWM_FADE_MAX:
pwm_setpoint[channel] = (PWMTABLE_SIZE -1);
pwm_setpoint[channel] = (PWM_TABLE_SIZE -1);
break;
// FIXME: move to some other module?
case PWM_MODE_TOGGLE:
case EVENT_VALUE_PWM_TOGGLE:
if (pwm_setpoint[channel] > 5)
{
pwm_setpoint_save[channel] = pwm_setpoint[channel];
@ -109,7 +119,14 @@ void pwm_event_handler(struct event_entry *event)
}
else if (event->type == EVENT_TYPE_PWM_VALUE)
{
pwm_setpoint[event->num] = event->value;
if (event->value < PWM_TABLE_SIZE)
{
pwm_setpoint[event->num] = event->value;
}
else
{
pwm_setpoint[event->num] = (PWM_TABLE_SIZE -1);
}
PWM_TIM_ENABLE();
}
@ -119,16 +136,32 @@ void pwm_event_handler(struct event_entry *event)
static void pwm_update(uint8_t channel)
{
if ((pwm_setpoint[channel] > pwm_index[channel]) &&
(pwm_index[channel] < (PWMTABLE_SIZE -1))
)
(pwm_index[channel] < (PWM_TABLE_SIZE -1))
)
{
pwm_index[channel]++;
/* setpoint reached, notify others */
if (pwm_index[channel] == pwm_setpoint[channel])
{
event_queue(EVENT_TYPE_PWM_STATUS,
channel,
pwm_setpoint[channel]);
}
}
else if ((pwm_setpoint[channel] < pwm_index[channel]) &&
(pwm_index[channel] > 0)
(pwm_index[channel] > 0)
)
{
pwm_index[channel]--;
/* setpoint reached, notify others */
if (pwm_index[channel] == pwm_setpoint[channel])
{
event_queue(EVENT_TYPE_PWM_STATUS,
channel,
pwm_setpoint[channel]);
}
}
/* if PWM is zero, disable output */
@ -144,7 +177,7 @@ static void pwm_update(uint8_t channel)
}
}
/* if PWM is max, enable output */
else if (pwm_index[channel] == (PWMTABLE_SIZE -1))
else if (pwm_index[channel] == (PWM_TABLE_SIZE -1))
{
if (channel == 0)
{
@ -158,14 +191,14 @@ static void pwm_update(uint8_t channel)
/* else load new PWM into timer */
else
{
if (channel == 0)
{
PWM_CH0_PWM(pgm_read_word(&pwmtable[pwm_index[0]]));
}
else
{
PWM_CH1_PWM(pgm_read_word(&pwmtable[pwm_index[1]]));
}
if (channel == 0)
{
PWM_CH0_PWM(PWM_TABLE_GET(pwm_index[0]));
}
else
{
PWM_CH1_PWM(PWM_TABLE_GET(pwm_index[1]));
}
}
} /* pwm_set */
@ -175,7 +208,7 @@ ISR(PWM_TIM_VECT)
static uint8_t delay;
delay++;
if (delay == 4)
if (delay == PWM_DELAY_COUNT)
{
delay = 0;
@ -196,6 +229,19 @@ ISR(PWM_TIM_VECT)
} /* TIM1_OVF_vect */
uint8_t pwm_get_sleep_mode(void)
{
if (PWM_TIM_RUNNING())
{
return SLEEP_MODE_IDLE;
}
else
{
return SLEEP_MODE_PWR_DOWN;
}
} /* pwm_get_sleep_mode */
void pwm_init(void)
{
PWM_TIM_INIT();

19
pwm.h
View File

@ -5,18 +5,15 @@
/* *********************************************************************** */
#define EVENT_NUM_PWM_CH0 0x00
#define EVENT_NUM_PWM_CH1 0x01
#define EVENT_NUM_PWM_CH0 0x00
#define EVENT_NUM_PWM_CH1 0x01
#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 PWM_MODE_TOGGLE 6
#define PWM_VALUE_MAX 128
#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
/* *********************************************************************** */

View File

@ -1,6 +1,8 @@
#ifndef __TARGET_H__
#define __TARGET_H__
#include <avr/io.h>
/* *********************************************************************** */
/*
* using ATmega168 @16MHz:
@ -9,12 +11,29 @@
* Fuse L: 0xFF (external crystal)
*/
#define F_CPU 16000000
#define BAUDRATE 19200
#define RFM12_ADDRESS TWAR
/* *********************************************************************** */
/* 1ms @16MHz */
#define TIMEOUT 1000
#define TIMER_RELOAD (0xFF - 250)
#define TIMER_RELOAD 250
#define TIMER_COUNT 3
#define TIMER_TIM_INIT() { \
TCCR0A = 0x00; \
TCCR0B = 0x00; \
TIMSK0 = (1<<TOIE0); \
}
/* Timer0: FCPU/64, overflow interrupt */
#define TIMER_TIM_ENABLE() { TCCR0B |= ((1<<CS01) | (1<<CS00)); }
#define TIMER_TIM_DISABLE() { TCCR0B &= ~((1<<CS01) | (1<<CS00)); }
#define TIMER_TIM_RUNNING() (TCCR0B & ((1<<CS00) | (1<<CS01) | (1<<CS02)))
#define TIMER_TIM_RELOAD(x) { TCNT0 = (0xFF - (x)); }
#define TIMER_TIM_VECT TIMER0_OVF_vect
/* *********************************************************************** */
#define EVENT_COUNT 16
/* *********************************************************************** */
@ -28,11 +47,15 @@
/* *********************************************************************** */
#define UART_BAUDRATE 19200
#define UART_RXBUF_SIZE 16
#define UART_TXBUF_SIZE 128
/* *********************************************************************** */
#define PWM_TIM_16BIT 1
#define PWM_DELAY_COUNT 4
#define PWM_TIM_INIT() { \
DDRB |= (1<<PORTB1) | (1<<PORTB2); \
/* Timer1: 8MHz, FastModePWM, overflow interrupt */ \
@ -43,6 +66,7 @@
}
#define PWM_TIM_ENABLE() { TCCR1B |= (1<<CS10); }
#define PWM_TIM_DISABLE() { TCCR1B &= ~(1<<CS10); }
#define PWM_TIM_RUNNING() (TCCR1B & ((1<<CS10) | (1<<CS11) | (1<<CS12)))
#define PWM_TIM_CHECK() (TCCR1A & ((1<<COM1A1) | (1<<COM1B1)))
#define PWM_TIM_VECT TIMER1_OVF_vect

75
timer.c
View File

@ -16,33 +16,77 @@
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include <avr/interrupt.h>
#include <avr/io.h>
#include "event.h"
#include "target.h"
#include "timer.h"
/* *********************************************************************** */
static uint16_t timers[TIMER_COUNT];
volatile static uint8_t timer_ticked;
/* *********************************************************************** */
void timer_tick(void)
ISR(TIMER_TIM_VECT)
{
uint8_t i;
/* 1ms interrupt */
TIMER_TIM_RELOAD(TIMER_RELOAD);
for (i = 0; i < TIMER_COUNT; i++)
timer_ticked = 1;
} /* TIM1_OVF_vect */
uint8_t timer_check(uint8_t timer_needed)
{
if (timer_ticked)
{
if (timers[i] > 0)
uint8_t i;
timer_ticked = 0;
for (i = 0; i < TIMER_COUNT; i++)
{
timers[i]--;
if (timers[i] == 0)
if (timers[i] > 0)
{
event_queue(EVENT_TYPE_TIMER_ELAPSED, i, 0);
timers[i]--;
if (timers[i] == 0)
{
event_queue(EVENT_TYPE_TIMER_ELAPSED, i, 0);
}
else
{
timer_needed = 1;
}
}
}
/* stop timer */
if (timer_needed == 0)
{
TIMER_TIM_DISABLE();
}
return 1;
}
} /* timer_tick */
return 0;
} /* timer_check */
uint8_t timer_get_sleep_mode(void)
{
if (TIMER_TIM_RUNNING())
{
return SLEEP_MODE_IDLE;
}
else
{
return SLEEP_MODE_PWR_DOWN;
}
} /* timer_get_sleep_mode */
void timer_event_handler(struct event_entry *event)
@ -52,5 +96,20 @@ void timer_event_handler(struct event_entry *event)
)
{
timers[event->num] = event->value;
/* start timer if needed */
if (!TIMER_TIM_RUNNING())
{
TIMER_TIM_RELOAD(TIMER_RELOAD);
TIMER_TIM_ENABLE();
}
}
} /* timer_event_handler */
void timer_init(void)
{
TIMER_TIM_INIT();
TIMER_TIM_RELOAD(TIMER_RELOAD);
TIMER_TIM_ENABLE();
} /* timer_init */

17
timer.h
View File

@ -1,15 +1,20 @@
#ifndef __TIMER_H__
#define __TIMER_H__
/* *********************************************************************** */
#define TIMER_DOOR_CLOSE_DELAY 0
#define TIMER_COUNT 2
#include "event.h"
/* *********************************************************************** */
void timer_tick (void);
void timer_event_handler (struct event_entry *event);
#define EVENT_NUM_TIMER_DEBOUNCE1 0
#define EVENT_NUM_TIMER_DEBOUNCE2 1
#define EVENT_NUM_TIMER_DOOR_CLOSE_DELAY 2
/* *********************************************************************** */
void timer_init (void);
uint8_t timer_check (uint8_t timer_needed);
void timer_event_handler (struct event_entry *event);
uint8_t timer_get_sleep_mode(void);
/* *********************************************************************** */

4
uart.c
View File

@ -65,8 +65,8 @@ ISR(USART_UDRE_vect)
void uart_init(void)
{
/* set baudrate */
UBRR0H = (UART_CALC_BAUDRATE(BAUDRATE)>>8) & 0xFF;
UBRR0L = (UART_CALC_BAUDRATE(BAUDRATE) & 0xFF);
UBRR0H = (UART_CALC_BAUDRATE(UART_BAUDRATE)>>8) & 0xFF;
UBRR0L = (UART_CALC_BAUDRATE(UART_BAUDRATE) & 0xFF);
/* USART: rx/tx enable, 8n1 */
UCSR0B = (1<<TXEN0) | (1<<RXEN0) | (1<<RXCIE0);