channel PWM reimplemeted

This commit is contained in:
King Kévin 2013-10-19 22:17:59 +02:00
parent 7f637bc705
commit bdc953feff
1 changed files with 26 additions and 32 deletions

View File

@ -90,13 +90,14 @@ uint16_t burst[PULSE_MAX]; /* pulse times forming a burst (from timer) */
/* channel variables */
#define LEVELS 10 /* the number of PWM levels */
volatile uint8_t ch_tick = 0; /* the tick counter for the channel PWM */
volatile uint8_t ch_tick = 0; /* to tick for the channel PWM */
uint8_t on[CHANNELS_1+CHANNELS_2]; /* at which tick turn the channel on */
uint8_t off[CHANNELS_1+CHANNELS_2]; /* at which tick turn the channel off */
/* flags, set in the interrupts and handled in the main program */
volatile bool uart_flag = false; /* an incoming activity on the UART */
volatile bool power_flag = false; /* a change in the power or fan */
volatile bool ir_flag = false; /* to process a burst */
volatile bool pwm_flag = false; /* to trigger a PWM tick */
volatile bool channel_flag = false; /* indicate a change in the channel PWM values */
volatile bool learn_flag = false; /* learn an IR command for an action */
enum IR_ACTIONS to_learn = IR_ACTION_END; /* IR action to learn */
@ -163,8 +164,23 @@ ISR(TIMER1_COMPA_vect) { /* timer 1 OCR1A match interrupt vector */
/* timer 0 interrupt used generate a PWM for the channels */
ISR(TIMER0_COMPA_vect) { /* timer 0 OCR0A match interrupt vector */
ch_tick = (ch_tick+1)%LEVELS;
pwm_flag = true;
ch_tick++;
if (pwr_ok) {
for (int i=0; i<CHANNELS_1+CHANNELS_2; i++) {
if (on[i]==ch_tick) {
if (on[i]!=off[i]) {
*(PORTS[i]) |= (1<<BITS[i]);
} else if (brightness[mode][i]==0) {
*(PORTS[i]) &= ~(1<<BITS[i]);
} else {
*(PORTS[i]) |= (1<<BITS[i]);
}
} else if (off[i]==ch_tick && brightness[mode][i]!=0xff) {
*(PORTS[i]) &= ~(1<<BITS[i]);
}
}
PIND = (1<<LED);
}
}
/* disable watched when booting */
@ -245,7 +261,7 @@ void ioinit(void)
TCCR0B &= ~(1<<CS02);
TCCR0B |= (1<<CS01);
TCCR0B &= ~(1<<CS00);
OCR0A = 0xff; /* set PWM frequency (with prescale=8, 0x00=2304kHz-0xff=9kHz) */
OCR0A = 0x40; /* set PWM frequency (with prescale=8, 0x00=2304kHz-0xff=9kHz) */
TIFR0 = (1<<OCF0A); /* clear timer 0 compare interrupt flag */
TIMSK0 |= (1<<OCIE0A); /* enable timer 0 compare interrupt */
@ -280,10 +296,6 @@ int main(void)
ir_data.command = 0;
uint8_t ir_repeat = 0; /* number of times the IR data has been repeated */
uint8_t on[CHANNELS_1+CHANNELS_2]; /* times when to switch on the output on the channels */
uint8_t off[CHANNELS_1+CHANNELS_2]; /* times when to switch off the output on the channels */
channel_flag = true; /* calculate above values later */
puts("LED dimmer up & running");
/* load (or initialize) settings */
@ -299,6 +311,7 @@ int main(void)
load_settings();
puts("settings loaded");
}
channel_flag = true; /* calculate channel values later */
/* switch power supply as saved */
if (power) {
@ -312,32 +325,12 @@ int main(void)
while (channel_flag) {
uint8_t start = 0;
for (uint8_t i=0; i<CHANNELS_1+CHANNELS_2; i++) {
on[i] = (start)%LEVELS;
off[i] = (on[i]+brightness[mode][i])%LEVELS;
start = (start+brightness[mode][i])%LEVELS;
on[i] = start;
start += brightness[mode][i];
off[i] = start;
}
channel_flag = false;
}
/* generate PWM for channel */
while (pwm_flag) {
if (pwr_ok) {
for (int i=0; i<CHANNELS_1+CHANNELS_2; i++) {
if (on[i]==ch_tick) {
if (on[i]!=off[i]) {
*(PORTS[i]) |= (1<<BITS[i]);
} else if (brightness[mode][i]==0) {
*(PORTS[i]) &= ~(1<<BITS[i]);
} else {
*(PORTS[i]) |= (1<<BITS[i]);
}
} else if (off[i]==ch_tick) {
*(PORTS[i]) &= ~(1<<BITS[i]);
}
}
PIND |= (1<<LED);
}
pwm_flag = false;
}
/* handle UART input */
while (uart_flag) {
/* echo back */
@ -553,6 +546,7 @@ void uart_action(char* str)
goto error;
}
brightness[mode][channel] = (uint8_t)br;
channel_flag = true;
}
} else {
goto error;