diff --git a/dmx8chan.c b/dmx8chan.c index 56eeea8..957eb08 100644 --- a/dmx8chan.c +++ b/dmx8chan.c @@ -27,53 +27,56 @@ // channel values volatile uint8_t chan[8] = { 0xFF, 0xFE, 0x80, 0x40, 0x20, 0x10, 0x01, 0x00 }; -// rx variables +// rx receive variables static uint16_t rx_chan; static uint16_t my_base; -// next OCR1 value +// timer variables static uint8_t cnt; -static uint16_t pwm_load; +static uint16_t pwm_next; +static uint8_t out_next; -/* - * Timer 1 Overflow (every 10ms) - * - reload 10ms - * - schedule compare match in 40us - */ +/* Timer 1 Overflow (every 10ms) */ ISR(SIG_OVERFLOW1) { TCNT1 = TIMER1_RELOAD; OCR1A = (TIMER1_RELOAD + TIMER1_STEP); - pwm_load = (TIMER1_RELOAD + (TIMER1_STEP * 2)); + + pwm_next = (TIMER1_RELOAD + (TIMER1_STEP * 2)); cnt = 0x00; } /* * Timer 1 Compare Match (every 40us) - * - schedule next compare match in 40us - * - set PWM Outputs (PORTB) + * asap: + * - schedule next compare match + * - set PWM Outputs + * interruptible: + * - calc next compare match + * - calc next output values */ ISR(SIG_OUTPUT_COMPARE1A) { - OCR1A = pwm_load; - pwm_load += TIMER1_STEP; + OCR1A = pwm_next; + PORTB = out_next; + + /* rest can be interrupted by DMX receive */ + sei(); + + pwm_next += TIMER1_STEP; + if (cnt == 0x00) + out_next = 0x00; cnt--; - uint8_t out = PORTB; - if (cnt == 0xFF) - out = 0x00; - uint8_t i, shift = 1; - uint8_t *tmp = chan; - + volatile uint8_t *tmp = chan; for (i = 0; i < 8; i++) { if (*tmp++ >= cnt) - out |= shift; + out_next |= shift; shift <<= 1; } - PORTB = out; } /*