I'm trying to enable a PWM on an Arduino Mega (ATmega2560), but I'm facing to some issues.
First, I'm trying to program this in Ada. I desire to use the three Timer3 channels with FastPWM, so I wrote
procedure Main is
begin
-- Nullify Timer3 buffers
TCCR3A := 0;
TCCR3B := 0;
TCCR3C := 0;
-- Waveform Generation Mode
-- Fast PW, 8-bit, TOP = 0x00FF, Update OCR3x at BOTTOM, TOV3 Flag Set on TOP
-- => WGM33|WGM32|WGM31|WGM30 = 0|1|0|1
TCCR3A := TCCR3A or TCCR3A_WGM30;
TCCR3B := TCCR3B or TCCR3B_WGM32;
-- Compare Output Mode:
-- Fast PWM, non-inverting mode
-- => COM3A1|COM3A0|COM3B1|COM3B0|COM3C1|COM3C0 = 1|0|1|0|1|0
TCCR3A := TCCR3A or TCCR3A_COM3A1 or TCCR3A_COM3B1 or TCCR3A_COM3C1;
-- Clock Select: clk/1024 => CS32|CS31|CS30 = 1|1|1
TCCR3B := TCCR3B or TCCR3B_CS32 or TCCR3B_CS31 or TCCR3B_CS30;
-- Set Timer3 pins as output :
-- Channel A : Digital Pin 5 / Chip Pin 5 (PE3/OC3A/AIN1)
-- Channel B : Digital Pin 2 / Chip Pin 6 (PE4/OC3B/INT4)
-- Channel C : Digital Pin 3 / Chip Pin 7 (PE5/OC3C/INT5)
DDRE := DDRE_DDE3 or DDRE_DDE4 or DDRE_DDE5;
OCR3AH := 0;
OCR3AL := 250;
OCR3BH := 0;
OCR3BL := 250;
OCR3CH := 0;
OCR3CL := 250;
end Main;
The hardware connections are OK; I tested it using simple code on the Arduino IDE. So for me it's very clear that the code is lacking something or making something wrong, and this should be caused by an issue in PWM initialization. Could someone explain me where did I make such a mistake?
Thanks in advance.
Update
If Ada can be difficult to get the whole logic, the equivalent code in C is (you can build it using AS6, the result is the same, i.e., no signal is generated):
int main(void){
TCCR3A = 0;
TCCR3B = 0;
TCCR3C = 0;
/* Waveform Generation Mode
Fast PW, 8-bit, TOP = 0x00FF, Update OCR3x at BOTTOM, TOV3 Flag Set on TOP
=> WGM33|WGM32|WGM31|WGM30 = 0|1|0|1 */
TCCR3A = TCCR3A|(1<<WGM30);
TCCR3B = TCCR3B|(1<<WGM32);
/* Compare Output Mode:
Fast PWM, non-inverting mode
=> COM3A1|COM3A0|COM3B1|COM3B0|COM3C1|COM3C0 = 1|0|1|0|1|0*/
TCCR3A = TCCR3A|(1<<COM3A1)|(1<<COM3B1)|(1<<COM3C1);
/* Clock Select: clk/1024 => CS32|CS31|CS30 = 1|1|1 */
TCCR3B = TCCR3B|(1<<CS32)|(1<<CS31)|(1<<CS30);
/* Set Timer3 pins as output :
Channel A : Digital Pin 5 / Chip Pin 5 (PE3/OC3A/AIN1)
Channel B : Digital Pin 2 / Chip Pin 6 (PE4/OC3B/INT4)
Channel C : Digital Pin 3 / Chip Pin 7 (PE5/OC3C/INT5)*/
DDRE = DDRE|(1<<DDE3)|(1<<DDE4)|(1<<DDE5);
/* Set PWM Duty Cycles */
OCR3AH = 0;
OCR3AL = 250;
OCR3BH = 0;
OCR3BL = 250;
OCR3CH = 0;
OCR3CL = 250;
}
Looking at www.atmel.com/Images/doc2549.pdf page 136, I see a note:
"The Power Reduction Timer/Counter3 bit, PRTIM3, in “PRR1 – Power Reduction Register 1” on page 57 must be written to zero to enable Timer/Counter3 module."
May be relevant?
I don't know what the defaults are for the power management regs, and I haven't used the 2560.
The rest looks OK to me, though I have used the timer libraries avr-timer0.adb etc on the 328p instead of rolling my own.