So… a bit of head scratching this afternoon. I had working PWM on the LEDs… which was fantastic.
With the trade-off of LEDs being ⅛ brightness maximum, which is fine since the LED strings that I’ve been given for this project would make Manfred Mann proud…
I was a little stumped with my audio PWM. I could not get a peep out of it, not via the amplifier or anything else. Tracing back, I was getting nothing out of the PWM pin. Real strange. Looked up the data sheets, couldn’t see what I was doing wrong.
My code for initialising Timer1 looked like this:
/* Timer 1 configuration for PWM */
OCR1B = 128; /* Initial PWM value: audio */
OCR1D = 32; /* Initial PWM value: light */
OCR1C = 255; /* Maximum PWM value */
TCCR1A = (2 << COM1B0) /* Clear OC1B on match,
nOC1B not used */
| (1 << PWM1B); /* Enable PWM channel B */
TCCR1B = (1 << CS10); /* No prescaling, max speed */
TCCR1C = (3 << COM1D0) /* Set OC1D on match,
nOC1D not used */
| (1 << PWM1D); /* Enable PWM channel D */
TCCR1D = (0 << WGM10); /* Fast PWM mode */
It looked fine… even checked the header files to see there wasn’t some cock up in the headers. Never had an issue with avr-libc, but you never know, and of course, no problem there.
In exasperation, I swapped setting up TCCR1A and TCCR1C. Bingo, I had PWM both channels. Why? Turns out there are some bits in TCCR1C that shadow TCCR1A, and I was inadvertently setting those back to 0 when I set up TCCR1C. So my code now:
/* Timer 1 configuration for PWM */
OCR1C = 255; /* Maximum PWM value */
TC1H = 0; /* Reset counter high bits */
TCNT1 = 0; /* Reset counter low bits */
OCR1A = 0; /* Initial PWM value: spare */
OCR1B = 127; /* Initial PWM value: audio */
OCR1D = 127; /* Initial PWM value: light */
TCCR1A = (1 << PWM1B); /*
* Clear TCCR1A except for PWM1B,
* we'll configure OC1B
* via the shadow bits in TCCR1C
*/
TCCR1B = (1 << CS10); /* No prescaling, max speed */
TCCR1C = (2 << COM1B0S) /* Clear OC1B on match,
nOC1B not used */
| (3 << COM1D0) /* Set OC1D on match,
nOC1D not used */
| (1 << PWM1D); /* Enable PWM channel D */
TCCR1D = (0 << WGM10); /* Fast PWM mode */
TCCR1E = 0; /* Not used: PWM6 mode */
We still need to turn PWM1B on via TCCR1A… but we set the output control mode via TCCR1C to avoid clobbering our settings.
Having fixed that, I now have a second problem, in my dead-bugging of the amp, I got my left and right arse-about, which would explain why my amp is making no noise. That’ll be a tomorrow job methinks, at 22:30 UTC+10:00 it is too dark to work on PCBs. I’ll just keep myself amused looking at the waveform on the oscilloscope.