hi need help in getting pwm code to work on leonardo

Hi Guys,

i found to my disappointment that the leonardo has no pwm higher than 500hz or so. When i bought it, i thought that as it had pwm pins it would have some docs “libs” to handle them but as far as i search there is no one.

Guys my question is how can i make the pwm with the timers and register without screwing up the usb connection. i tried the code bellow. It compiles fine but after uploading, i lost usb connection and leonardo is not recognized. i pressed upload and just after compiling finished i pressed reset on board to get the new empty sketch uploaded and have the Leonardo recognized again:

Code:

#define TIMER4_RESOLUTION 1023UL
#define PLL_FREQ 48000000UL

unsigned long pwmPeriod = 0;
ISR(TIMER4_OVF_vect) {}

void enable_intr(){
TIMSK4 = _BV(TOIE4);
}

void disable_intr(){
TIMSK4 = 0;
}

void initialize(unsigned long freq) {

/* Init the internal PLL /
PLLFRQ = _BV(PDIV2);
PLLCSR = _BV(PLLE);
while(!(PLLCSR & _BV(PLOCK)));
PLLFRQ |= _BV(PLLTM0); /
PCK 48MHz */

TCCR4A = (1<<PWM4A);
TCCR4E = (1<<ENHC4);
TCCR4D = (1<<WGM40); //set it to phase and frequency correct mode
TCCR4C = 0;
setPeriod(freq);
}
void setPwmDuty(unsigned int duty) {
unsigned long dutyCycle = pwmPeriod;
dutyCycle *= duty;
dutyCycle >>= 9;
TC4H = (dutyCycle) >> 8;
OCR4A = (dutyCycle) & 255;
}

void start() {
TCCR4A |= _BV(COM4A1);
}
void stop() {
TCCR4A &= ~(_BV(COM4A1));
}

void setPeriod(unsigned long freq) {
unsigned long cycles = PLL_FREQ / 2 / freq;
unsigned char clockSelectBits = 0;

if (cycles < TIMER4_RESOLUTION) {
clockSelectBits = _BV(CS40);
pwmPeriod = cycles;
} else
if (cycles < TIMER4_RESOLUTION * 2) {
clockSelectBits = _BV(CS41);
pwmPeriod = cycles / 2;
} else
if (cycles < TIMER4_RESOLUTION * 4) {
clockSelectBits = _BV(CS41) | _BV(CS40);
pwmPeriod = cycles / 4;
} else
if (cycles < TIMER4_RESOLUTION * 8) {
clockSelectBits = _BV(CS42);
pwmPeriod = cycles / 8;
} else
if (cycles < TIMER4_RESOLUTION * 16) {
clockSelectBits = _BV(CS42) | _BV(CS40);
pwmPeriod = cycles / 16;
} else
if (cycles < TIMER4_RESOLUTION * 32) {
clockSelectBits = _BV(CS42) | _BV(CS41);
pwmPeriod = cycles / 32;
} else
if (cycles < TIMER4_RESOLUTION * 64) {
clockSelectBits = _BV(CS42) | _BV(CS41) | _BV(CS40);
pwmPeriod = cycles / 64;
} else
if (cycles < TIMER4_RESOLUTION * 128) {
clockSelectBits = _BV(CS43);
pwmPeriod = cycles / 128;
} else
if (cycles < TIMER4_RESOLUTION * 256) {
clockSelectBits = _BV(CS43) | _BV(CS40);
pwmPeriod = cycles / 256;
} else
if (cycles < TIMER4_RESOLUTION * 512) {
clockSelectBits = _BV(CS43) | _BV(CS41);
pwmPeriod = cycles / 512;
} else
if (cycles < TIMER4_RESOLUTION * 1024) {
clockSelectBits = _BV(CS43) | _BV(CS41) | _BV(CS40);
pwmPeriod = cycles / 1024;
} else
if (cycles < TIMER4_RESOLUTION * 2048) {
clockSelectBits = _BV(CS43) | _BV(CS42);
pwmPeriod = cycles / 2048;
} else
if (cycles < TIMER4_RESOLUTION * 4096) {
clockSelectBits = _BV(CS43) | _BV(CS42) | _BV(CS40);
pwmPeriod = cycles / 4096;
} else
if (cycles < TIMER4_RESOLUTION * 8192) {
clockSelectBits = _BV(CS43) | _BV(CS42) | _BV(CS41);
pwmPeriod = cycles / 8192;
} else
if (cycles < TIMER4_RESOLUTION * 16384) { clockSelectBits = _BV(CS43) | _BV(CS42) | _BV(CS41) | _BV(CS40); pwmPeriod = cycles / 16384; } /*else clockSelectBits = _BV(CS43) | _BV(CS42) | _BV(CS41) | _BV(CS40); pwmPeriod = TIMER4_RESOLUTION - 1; */ TCCR4B = clockSelectBits; TC4H = pwmPeriod >> 8;
OCR4C = pwmPeriod;

}

void setup() {

pinMode(13, OUTPUT);
digitalWrite(13,LOW);
initialize(123456); // Frequency to generate in Hz
setPwmDuty(512); // Duty cycle 0-1024, 1024 is 100%, 512 is 50%
start();

}
void loop(){
}

any help is appreciated. i just started with Arduino so be gentle with me smiley-wink.

Timi

Well, the first thing that you could do is put put your code in code tags to avoid crap like this being displayed

if (cycles < TIMER4_RESOLUTION * 8){

Sorry i originaly posted on general electronic but it was the wrong place to post it. So i copy paste it in a new post. The copy obviously went wrong :stuck_out_tongue:

Please can someone help me here :). I posted the link where i got the code so you can check the article there too. If someone helps in making this one to work it would be very good for all of us.

I was trying to use the same code on a SparkFun Pro Micro (basically a Leonardo) and nothing work, until I use a <PWM.h> library special for Leonardo.

Library is here:

http://code.google.com/p/arduino-pwm-frequency-library/issues/detail?id=2

Download the PWM-leonardo.zip file and install it.

Then, I modified the PWM programs from

http://code.google.com/p/arduino-pwm-frequency-library/downloads/list

and got a nice PWM at 25KHz.

Gaston

Thanks a lot will try it as soon as i will have some free time from work.

Thanks again a lot,

Timi