# Attiny4 - Possible Errata Found With PWM

I have searched the AtTiny data sheet and not found anything about this. I'm experiencing a weird PWM bug. When I expect 100% on I'm getting less. I'm using an inverted PWM scheme, so setting it equal to 0 should be full on, but my scope shows a ~95% on duty pulse.

Below I posted applicable setup code, then the function I call occasionally in my main() to change the PWM rate... When I set the OCR0B=0, I do not get a full on PWM.

I'll also note all other PWM settings appear to work correctly, the duty cycle matches what is expected.

Anyone want to take a look to check I'm sane before I complain to Microchip/Atmel?

//Setup Pins:
DDRB =  DDRB |  0b00000010;     //set B1 output and B2 to input.
PUEB = PUEB |   0b00000100;     //Pullup on B2

//Setup Timer:
//output pin is OC0B (PB1)
//Set PWM Fast Mode 8 Bit, enable output on all PWM pins (only 1 on tiny5).
TCCR0A = 1<<COM0A1 | 1<<COM0B1 | 1<<COM0A0 | 1<<COM0B0 | 1<<WGM01;  //COM0A0 COM0B0 set to 1 for inverting PWM.
//Set PWM top [ICR0] to 5bit (this allows effective 31khz pwm)
ICR0 = TOP_PWM; //Set TOP...
//Set PWM Mode Fast 8 bit & No pre-scaler.
TCCR0B =  1<<CS00 | 1<<WGM02 | 1<<WGM03;

//Setup INO0 (External Interrupt):
EICRA = 1<<ISC00 | 1<<ISC01;    //Enable rising edge interrupt
EIMSK = 1<<INT0;                //Enable INT0

----------------------------------------------------------------

/******************************************
* Function to decide what speed to set.
* NOTE: All alterations to motor speed should
*       be done in this function!
* Also note that inverse PWM is used,
* so 0 is full speed, and TOP_PWM is stopped.
******************************************/
void speedLogic()
{
//Speed logic
if      (speed_state == 0)
speed = TOP_PWM;//Off
else if (speed_state == 1)
speed = 24;     //Slow
else if (speed_state == 2)
speed = 16;     //Med
else if (speed_state == 3)
speed = 0;      //Fast (3=91% Otherwise 0=100%)
else
speed = TOP_PWM;

//Set PWM Reg
OCR0B = speed;

//Increment State Variable
speed_state++;
if (speed_state > 3)
speed_state = 0;
}


I believe, it is a feature not a bug. Citing from the datasheet (page 94):

The extreme values for the OCR0x registers represents special cases when generating a PWM waveform output in the Fast PWM mode. If the OCR0x is set equal to BOTTOM (0x0000) the output will be a narrow spike for each TOP+1 timer clock cycle. Setting the OCR0x equal to TOP will result in a constant high or low output (depending on the polarity of the output which is controlled by COM0x[1:0]).

This describes your observation pretty well. With 5 bit PWM (32 steps, right?) the duty cycle should be 97 % (not 95 %), but it is probably good enough for approximately.

• This makes sense, but seems odd? So then to get a 0 PWM output, I would need to flip the COM0x0 bit? I have never seen a PWM setup quite like that. Feb 28 '18 at 2:45
• This or stop the timer or change the WG mode or something else (there is probably a few other possibilities). It is not completely clear to me from the datasheet, but I guess the waveform generator uses the same logic as a OCF0x flag, that is action happens at the start of next tick after the match. Maybe strange or impractical, but probably allows more simple HW implementation. (I suspect that for full 0 to 100 %, the HW would have to implement one of edge value as a special case.) Feb 28 '18 at 3:07