/*--------------------------------------------------------------------------*/
ISR(TIMER0_A1, rtimer_a01_isr)
{
  /* store the IV register as any read/write resets interrupt flags */
  uint16_t ivreg = TA0IV;

  if(ivreg & TA0IV_TACCR1) {
    /* rtimer interrupt */
    TA0CCTL1 &= ~CCIFG;
    watchdog_start();

    /* check for and run any pending rtimers */
    rtimer_run_next();

    /* also check for any pending events and wake up if needed */
    if(process_nevents() > 0) {
      LPM4_EXIT;
    }
    watchdog_stop();




  } else if(ivreg & TA0IV_TACCR2) {
    /* simple pwm interrupt */
    TA0CCTL2 &= ~CCIFG;

    if(spwm.on_time > 0) {
      if(spwm.on_time == period) {
        TA0CCTL2 &= ~CCIE;  /* no need for interrupt, is at 100% DC */
/*        SIMPLE_PWM_PORT(OUT) |= (1 << spwm.pin);*/
        pwm_on_cb();

      } else {
        /* normal on-case */
        if(period_end) {
          period_end = 0;
          TA0CCR2 = TAR + spwm.on_time;
/*          SIMPLE_PWM_PORT(OUT) |= (1 << spwm.pin);*/
          pwm_off_cb();

        } else {
          period_end = 1;
          TA0CCR2 = TAR + (period - spwm.on_time);
/*          SIMPLE_PWM_PORT(OUT) &= ~(1 << spwm.pin);*/
          pwm_on_cb();
        }
      }
    }
  }
}
/*
 * set pwm on at a duty cycle expressed in percent from 0 to 100. If crucial,
 * calculate your own pulsetime and use that function due to rounding errors in
 * this function.
 */
void
simple_pwm_on(uint8_t dc)
{
  if(dc > 100) {
    return;
  }

  if(dc == 100) {
    TA0CCTL2 &= ~CCIE;  /* no need for interrupt */
    spwm.on_time = period;
/*    SIMPLE_PWM_PORT(OUT) |= (1 << spwm.pin);*/
    pwm_on_cb();

  } else if(dc == 0) {
    TA0CCTL2 &= ~CCIE;  /* no need for interrupt */
    spwm.on_time = 0;
/*    SIMPLE_PWM_PORT(OUT) &= ~(1 << spwm.pin);*/
    pwm_off_cb();

  } else {
    /* convert duty cycle to PWM clock ticks */
    uint8_t finetime = (dc * period) / 100;
    if(finetime == 0 && dc != 0) {
      /* rounding errors, go for minimum-like */
      finetime = 2;
    }

    /* set up a compare match for the next PWM period */
    TA0CCR2 = TAR + finetime;
    TA0CCTL2 = CCIE;
    spwm.on_time = finetime;
  }
}
/*
 * set pwm on at a specified pulsetime measured in SIMPLE_PWM_SECOND ticks/s.
 *
 * The period is (SIMPLE_PWM_SECOND / SIMPLE_PWM_FREQ) - 1, measured in the
 * same number of ticks/s. Default is 128 Hz and 32768 ticks/s, leaving us w
 * 255 ticks/period, so the range becomes 0..255.
 * Use this for precision work, eg a servo motor.
 */
void
simple_pwm_pulsetime(uint16_t finetime)
{
  if(finetime >= period) {
    TA0CCTL2 &= ~CCIE;  /* no need for interrupt */
    spwm.on_time = period;
/*    SIMPLE_PWM_PORT(OUT) |= (1 << spwm.pin);*/
    pwm_on_cb();

  } else if(finetime == 0) {
    TA0CCTL2 &= ~CCIE;  /* no need for interrupt */
    spwm.on_time = 0;
/*    SIMPLE_PWM_PORT(OUT) &= ~(1 << spwm.pin);*/
    pwm_off_cb();

  } else {
    /* set up a compare match for the next PWM period */
    TA0CCR2 = TAR + finetime;
    TA0CCTL2 = CCIE;
    spwm.on_time = finetime;
  }
}