ATmega3208 TCA0 - stupid me

Go To Last Post
5 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I must have missed something in my understanding of single slope PWM on TCA0 in a 3208.

 

Here a code snippet:

 ISR(TCA0_OVF_vect)
 {
 	PORTD_OUTTGL = PIN7_bm;
 }

 void main_task_init(void)
 {
 	system_state.task_10ms_flag=0;
 	system_state.ms_counter=0;

 	/* Configure TCC0 for 10ms periodic tick */
 	TCA0_SINGLE_CTRLA &= ~(TCA_SINGLE_ENABLE_bm); // stop the timer
 	TCA0_SINGLE_PER = 800;
 	TCA0_SINGLE_INTCTRL = TCA_SINGLE_OVF_bm;

 	// Enable the timer
 	TCA0_SINGLE_CTRLA = TCA_SINGLE_CLKSEL_DIV1024_gc;
 	TCA0_SINGLE_CTRLA |= TCA_SINGLE_ENABLE_bm;

}

 

No matter what I cahange for the TCA0_SINGLE_PER (800 in the example above) or the clock prescaler (TCA_SINGLE_CLKSEL_DIV1024_gc above) the frequency of the interrupt does not change.

I have a 'scope on PORTD7 and no matter what values I use, the pin toggles at 357 kHz.

 

For clarity here is my clock setup code...

    _PROTECTED_WRITE(CPUINT.CTRLA,			0); // Reset ISR vectors to APP location.
	_PROTECTED_WRITE(CLKCTRL.MCLKCTRLB,		0);	// Turn off the system clock pre-scaler. We are running at 20 Mhz now.
	_PROTECTED_WRITE(CLKCTRL.OSC32KCTRLA, 0x02); // Turn the 32KHZ oscillator on too.
	

 

I'm guessing I've mis-understood how the single slope PWM should work. I'll go read the datasheet again while I let you laugh at my mistake... feel free to point it out to me. 

 

This topic has a solution.

SpiderKenny
@spiderelectron
www.spider-e.com

 

Last Edited: Mon. Oct 28, 2019 - 11:36 AM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The interrupt flag is not cleared automatically.
Please do as follows.

 

ISR(TCA0_OVF_vect)
{
	PORTD_OUTTGL = PIN7_bm;
	TCA0.SINGLE.INTFLAGS = TCA_SINGLE_OVF_bm;
}

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@kabasan Thanks!

Told you I was being stupid!

 

Thanks for being nice about it too!

SpiderKenny
@spiderelectron
www.spider-e.com

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

On any AVR architecture, not just this one, when you see a time interrupt being used to only toggle a pin you cannot help but wonder if there is not some way to simply configure the timer to do the pin wiggling anyway and cut out the overhead (and possibly jitter) or ISR entry/exit.

 

I know that on "old school" AVrs you were sometimes forced into the "ISR wiggles pin" paradigm because it was a different pin to the one the time offers to drive but these Xmega like new chips have stuff like "event systems" and "combinatorial logic" and stuff which I believe makes it easier to hardwire something like a timer expiry to a particular pin wiggle or whatever. The chips often have "pin multiplexers" too so different things can be arranged to appear on different pins. Or, failing all that, you can just relay your schematic to have the output on the pin that the timer "owns" by default.

 

Just thinking aloud...

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
when you see a time interrupt being used to only toggle a pin you cannot help but wonder

Hi clawson, yeah - that ISR won't be toggling any pins, that was just minimized test code.

SpiderKenny
@spiderelectron
www.spider-e.com