ATTINY85: IR receiver + 3 pin PWM...What's the best approach?

I'm trying to implement an PWM RGB LED and IR receiver in an attiny85.

-I'm using this core: Google Code Archive - Long-term storage for Google Code Project Hosting.
-I'm using this attiny IR library: http://gammon.com.au/Arduino/IRremote_Attiny.zip
-My PWM setup is as follows:

	// from "attiny85 with 3 PWN pins" http://forum.arduino.cc/index.php?topic=134754.0
	// Timer 0, A side
	TCCR0A = _BV (WGM00) | _BV (WGM01) | _BV (COM0A1); // fast PWM, clear OC0A on compare
	TCCR0B = _BV (CS00);           // fast PWM, top at 0xFF, no prescaler

	// Timer 0, B side
	TCCR0A |= _BV (COM0B1);        // clear OC0B on compare
	
	// Timer 1
	TCCR1 = _BV (CS10);           // no prescaler
	GTCCR = _BV (COM1B1) | _BV (PWM1B);  //  clear OC1B on compare
	
	// Initial RGB values
	OCR0A = 0;
	OCR0B = 0;
	OCR1B = 0;

Problems:
-I need this project in a POV type application, so I need arduino pins 0, 1, and 4 running with no prescaler so there are no gaps in the trails. Problem is, pin 4 runs on timer 1, affecting my IRremote library.
-After enabling the PWM, debugging was difficult as I no longer was able to use the serial monitor with this method: http://lukasz.io/hardware/serial-monitor-with-attiny85-and-arduino/

Questions:
-Is it possible to get the serial monitor working with the PWM settings applied?

-What would I need to change in the IRremote library to get this working again? I tried modifying the prescale values but I'm assuming there's more to it I'm not understanding. Tough to debug because of the lack of serial monitor.

-As a last resort, it's acceptable to manually toggle the entire PWM setup on/off if it means my IR receiver will work. I tried using this post as a guide, even copying the exact pwm setup, but was unable to replicate the results. I'm assuming it's a little more complicated than pasting the code blocks where I want to enable/disable PWM. Reseting ATTiny85 timer so millis and delay will work properly - Programming Questions - Arduino Forum

Thanks!

-Also, my program makes use of millis()/micros() during PWM output, what would I need to change to make use of these again? Right now I'm just using a hard coded scaler that's close, but I'd like something more accurate.

d4j0n:
-Is it possible to get the serial monitor working with the PWM settings applied?

The pin assignments for Tiny Debug Serial are handled here...

Change TINY_DEBUG_SERIAL_BIT to whichever pin you want to use for serial output.

I think you may be out of timers there....

You need three pwm at crazy frequency (you might need to pre scale it a little), which means you can't have millis working on a chip with two timers. You need three - maybe a tiny841? I think that's the cheapest 3-timer chip, and I happen to love them (two serials! Adc on all pins! 3 timers, and hardware spi)

Why can't I just scale the millis() and micros() by some constant according to my prescaler?

You may have to modify the code in wiring.c but I do know it is possible to run the millis/micros timer at a prescaler of 8 or 1. The biggest problem is that the interrupt service routine is called 8 times or 64 times more frequently. If I remember correctly, the net result is that as much as 6% of the CPU time is spent servicing the interrupt. If your application can survive that much overhead then the idea has merit.

Oh, wait. You are using the Tiny Core. I believe there is a switch for that ... well ... sort of ... it looks like you would modify this section...

Thanks, I'll look into that.

So my serial monitor now says I'm receiving the IR signals as expected, but when I enableIRIn(), I cannot turn on PB0 at all and PB1 can only go fully high, regardless of the value of OCR0B. My suspicion is that PB0 and PB1 are sharing the timer being used for IR so they are not playing nice together...

The code for enableIRIn() is as follows:

TCCR0A = 0;  // normal mode

  //Prescale /8 (16M/8 = 0.5 microseconds per tick)
  // Therefore, the timer interval can range from 0.5 to 128 microseconds
  // depending on the reset value (255 to 0)
  cbi(TCCR0B,CS02);
  sbi(TCCR0B,CS01);
  cbi(TCCR0B,CS00);

  //Timer2 Overflow Interrupt Enable
  sbi(TIMSK,TOIE0);

The interrupt is as follows:

// TIMER2 interrupt code to collect raw data.
// Widths of alternating SPACE, MARK are recorded in rawbuf.
// Recorded in ticks of 50 microseconds.
// rawlen counts the number of entries recorded so far.
// First entry is the SPACE between transmissions.
// As soon as a SPACE gets long, ready is set, state switches to IDLE, timing of SPACE continues.
// As soon as first MARK arrives, gap width is recorded, ready is cleared, and new logging starts
ISR(TIMER0_OVF_vect)
{
  RESET_TIMER2;

  uint8_t irdata = (uint8_t)digitalRead(irparams.recvpin);

  irparams.timer++; // One more 50us tick
  if (irparams.rawlen >= RAWBUF) {
    // Buffer overflow
    irparams.rcvstate = STATE_STOP;
  }
  switch(irparams.rcvstate) {
  case STATE_IDLE: // In the middle of a gap
    if (irdata == MARK) {
      if (irparams.timer < GAP_TICKS) {
        // Not big enough to be a gap.
        irparams.timer = 0;
      } 
      else {
        // gap just ended, record duration and start recording transmission
        irparams.rawlen = 0;
        irparams.rawbuf[irparams.rawlen++] = irparams.timer;
        irparams.timer = 0;
        irparams.rcvstate = STATE_MARK;
      }
    }
    break;
  case STATE_MARK: // timing MARK
    if (irdata == SPACE) {   // MARK ended, record time
      irparams.rawbuf[irparams.rawlen++] = irparams.timer;
      irparams.timer = 0;
      irparams.rcvstate = STATE_SPACE;
    }
    break;
  case STATE_SPACE: // timing SPACE
    if (irdata == MARK) { // SPACE just ended, record it
      irparams.rawbuf[irparams.rawlen++] = irparams.timer;
      irparams.timer = 0;
      irparams.rcvstate = STATE_MARK;
    } 
    else { // SPACE
      if (irparams.timer > GAP_TICKS) {
        // big SPACE, indicates gap between codes
        // Mark current code as ready for processing
        // Switch to STOP
        // Don't reset timer; keep counting space width
        irparams.rcvstate = STATE_STOP;
      } 
    }
    break;
  case STATE_STOP: // waiting, measuring gap
    if (irdata == MARK) { // reset gap timer
      irparams.timer = 0;
    }
    break;
  }

  if (irparams.blinkflag) {
    if (irdata == MARK) {
      PORTB |= B00100000;  // turn pin 13 LED on
    } 
    else {
      PORTB &= B11011111;  // turn pin 13 LED off
    }
  }
}

Is it possible to receive IR and do RGB PWM at the same time, or would I need more timers?