Xmega32E5 timer in "CTC" mode (closed)

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

I have been struggling with this since December and I think it is time that other E5 user may pitch in with ideas and a possible solution. :-)

For the record I have both timers running well in "CTC" mode by using the FREQ mode but using the compare B flags for the Compare A. I know it must be me not understanding how this mode should work.

The code below is based on some early reply I had from support but it doesn't work as I expect, I just want the counter to reach the compare A value, set the flag, and restart from zero. At the moment the flag is set at the compare A value, then the counter happily rolls past 0xffff (instead of restarting from zero) and eventually I get another interrupt.

I have marked the bits that need fixing. Yep looked at the ASF examples and about ready to kill myself. :(

/*
 * XmegaE5_timer_demo.c
 *
 *  Author: Ampertronics
 */ 

#include 
#include 

volatile uint8_t time_scaler, one_second_timer;

void init(void)
{
// Set clock to 4 MHz
	OSC_PLLCTRL=8;					// PLL mult. factor ( 2MHz x8 ) and set clock source to PLL
	OSC_CTRL=(1<<OSC_PLLEN_bp);		// Enable PLL

	while (!(OSC_STATUS & (1<<OSC_PLLRDY_bp)));

	CPU_CCP=CCP_IOREG_gc;			// Unlock sequence to access CLK_CTRL
	CLK_CTRL= OSC_PLLEN_bp;			// Select PLL as system clock 
	
	CPU_CCP=CCP_IOREG_gc;			// Unlock sequence to access CLK_CTRL
	CLK_PSCTRL= ( 1<<CLK_PSADIV1_bp |  1<<CLK_PSADIV0_bp);	//Divide by 4

// Initialise ports
// Setup Port A
	PORTA_OUT=(1<<PIN0_bp);
	PORTA_DIR=(1<<PIN3_bp | 1<<PIN2_bp | 1<<PIN0_bp);
	
	PORTCFG_MPCMASK=(1<<PIN7_bp | 1<<PIN6_bp | 1<<PIN5_bp | 1<<PIN4_bp | 1<<PIN1_bp);
	PORTA_PIN0CTRL=PORT_OPC_PULLDOWN_gc;	// Turn on pull down resistors

// Setup Port C
	PORTCFG_MPCMASK=0xff;					// Port C all inputs with pull up resistors
	PORTC_PIN0CTRL=PORT_OPC_PULLUP_gc;

// Setup Port D	
	PORTD_OUT = ( 1<<PIN5_bp | 1<<PIN4_bp );	// Leds off
	PORTD_DIR = (1<<PIN6_bp | 1<<PIN5_bp | 1<<PIN4_bp);

	PORTCFG_MPCMASK = ( 1<<PIN2_bp | 1<<PIN0_bp );
	PORTD_PIN0CTRL = PORT_OPC_PULLUP_gc;		//Turn on pull up resistors

	PORTCFG_MPCMASK = ( 1<<PIN7_bp | 1<<PIN6_bp | 1<<PIN3_bp );
	PORTD_PIN0CTRL = PORT_OPC_PULLDOWN_gc;	// Turn on pull down resistors


// Please fix so that timer works as CTC mode!
// ##########################################
//Timer4 compare tick every 4ms from 4MHz, used for 100ms and 1s soft timers
	TCC4_CTRLE = TC45_CCAMODE_COMP_gc;
	TCC4_PER = 0xffff;
	TCC4_CCA = 249;							// (249 + 1) Compare set for 4ms (250ns*64*250=4ms)
	TCC4_CTRLA = TC45_CLKSEL_DIV64_gc;		// clk/64

	TCC4_INTCTRLB |=(1<<TC4_CCAINTLVL0_bp) ;	// Low level priority
// ##########################################

// Initialise scaler	
	time_scaler = 25;							// 25*4ms=100ms
// Initialise one second scaler	
	one_second_timer = 10;					// 10*100ms
	
	PMIC_CTRL = (1<<PMIC_LOLVLEN_bp);
	sei();
}


ISR (TCC4_CCA_vect)
{
	time_scaler--;
	
	if (time_scaler == 0)
		{
		time_scaler=25;
		// 100ms tasks done here if any
		PORTD_OUTTGL = (1<<PIN5_bp);
		
		one_second_timer--;
		
		if (one_second_timer == 0)
			{
			one_second_timer=10;
			// 1s tasks done here if any
			PORTD_OUTTGL = (1<<PIN4_bp);
			}
		}		
}


int main(void)
{
	init();
	
    while(1)
    {
    }
}

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

Last Edited: Fri. May 17, 2013 - 08:00 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Looks like the period TCC4_PER should be changed from 0xFFFF to the same value as TCC4_CCA? That way it should definitely reset when it hits the capture value.

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

Quote:
TCC4_PER should be changed from 0xFFFF to the same value as TCC4_CCA?
I think I did try that before but I'll try it again.

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

Quote:
the same value as TCC4_CCA
249 doesn't work but 250 and higher does! (1 higher than TCC4_CCA value)

At last a step forward even though I'm not sure it's the correct way of doing things, at least I have the right compare flag now running even with the older pre-release version of the chip. :-)

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

And more fun than of a barrel of monkeys! :roll: Obviously I don't get thing.

The timer set up can be as simple as

//Timer4 compare tick every 4ms from 4MHz, used for 100ms and 1s soft timers	
	TCC4_CTRLA=TC45_CLKSEL_DIV64_gc;		// clk/64
	TCC4_PER = 250;
	TCC4_INTCTRLB |= (1<<TC4_CCDINTLVL0_bp);	// Low level priority, and A,B C or D	

and I get an interrupt on the correct vector A,B,C or D or all of them when the period expires. No need to set up any of the compare registers at all, very confusing.

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

C'mon guys :lol: is it possible that only DocJC and I are admitting to using the E5 out of the supposedly 200,000 user here?

Any hints on the CORRECT way to use the new TCC4 and TCC5 in the old "CTC" mode is?

So far I have 2 completely different ways of doing it, both work but I would like them to KEEP on working.

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

There is a slight bit of envy on this end as the E5 series seems to exist only in asf and paper. Find chips and the samples all are ZERO with mouser stating there is some production issues.

Just as well - much rather have someone else discover these hidden "features".

But, while on the subject - is there any word on when these might be available for us mere mortals?

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

Not sure when the general release will be.

I can confirm JS's impression that the Timer/Counter TCC4 doesn't seem to be functioning as per the current data sheets, if I am interpreting them correctly.

I can now confirm in Bascom a work around to generate a CTC mode interrupt as JS has already discovered:

One can generate a Frequency Mode, (what used to be called CTC Mode), interrupt by setting up the interrupt for Capture/Compare Channel B, while loading the TOP value in the Capture/Compare Channel A's register.

Additionally, one doesn't need to set any bits in the TCC4_CtrlE register. This register is used to enable the CC interrupts, but they fire without setting the appropriate bit, (as per my interpretation of the data sheet).

The key code to generate the interrupt being:

TCC4_CtrlA = 4    Synch = Peri Clk, Prescaler = /8
TCC4_CtrlB = 1    Normal Mode, Disable Circ Buff, Freq Mode
TCC4_IntCtrlA = 16  Low Level Timer Trigger Restart Intr Level
TCC4_IntCtrlB = 4   Enable Ch B Lo Priority
TCC4_CCA = 4000   Load the TOP value into CCA's Registers
'TCC4_CtrlE = Doesn't matter, don't set it.
.
.
.
On TCC4_CCB TickTock  SaveAll   The ISR Subroutine
.
.
.
'Now configure the interrupt and enable the global interrupt bit in SReg:
Config Priority = static, Vector = Application, Lo = enabled
Enable Interrupts
.
.
.

JC

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

Quote:
the E5 series seems to exist only in asf and paper.
Have you put in a sample request? I think it did say something about an August avalaibility for the samples from the local distributor but I was very fortunate (and grateful) to get a couple in about 2 weeks, maybe because I had already a working prototypes board ready to show to prospective clients.

So you could be surprised...or not... :wink:

Digikey doesn't yet show any of the chips but it shows availability for the XMEGA E5 XPLAINED EVAL KIT as early September (9/5/2013) http://www.digikey.com/product-s... so it looks like an August date maybe realistic.

Of course someone who may want a few hundred thousands of them may have them in stock already.

Jay the "CTC" mode seems even simpler than what I thought, may want to try it out in BASCOM.

Simply set the clock divisor, the PERIOD register (as I'm showing above) for the required time and ANY of either the A,B,C,D or oveflow (I think) interrupt bits and the correct ISR will execute. (it seems that ALL 5 flags trigger when the period rolls over)

It seems that in the simplest "CTC" mode that's all it needs. The PERIOD register from what I can see is a new thing with the TCC4 and TCC5 timers.

I would still like some official confirmation of my theory above. :-)

The ASF has a couple of timer examples but as usual I get lost there. One can set up to 4 Compare registers and generate 4 interrupts or whatever within the period.

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

Thanks John, I'll give it a try.

JC

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

I wish Mr BASCOM would release the new demo version with some Xmega support as he indicated he would so that I could try this myself in BASCOM. :-)

I'm going over some early support notes which indicated using the oveflow flag when using the FREQ mode and Compare A for the "CTC" mode as the compare A register sets the period in this mode. :roll:

This would be a 3rd way of doing the same thing, I'll try it out when I get back to "software mode"...where did I put that hat now....

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

Going back on this a bit more. The following screenshot is what I'm trying to get working correctly HOWEVER I don't want any pins affected, just the CCA flag to be set at each compare. (ie points 2 and 3 under waveform generation don't apply)

Am I wrong in expecting this to happen with the following code?

// Please fix so that timer works as CTC mode! 
//Timer4 compare tick every 4ms from 4MHz, used for 100ms and 1s soft timers	
	TCC4_CTRLA=TC45_CLKSEL_DIV64_gc;		// clk/64
	TCC4_CTRLB=TC45_WGMODE_FRQ_gc;			// CTC mode	

	TCC4_CCA=249;							// (249 + 1) Compare set for 4ms (250ns*64*250=4ms)
	TCC4_INTCTRLB=(1<<TC4_CCAINTLVL0_bp) ;		

(edit had wrong init)

Attachment(s): 

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

I guess we can put this to bed now unless we have contradictory messages from Atmel people. :-)

The simplest way to achieve "CTC mode" with the E5 is to use the period register and the CCA flag, even though when the period is up all CC flags are set including the OVF, the CC flags seem to work well but the OVF doesn't seem to work in this mode.

I'm attaching 2 projects, one in ASM and the other in C (for the ASM challenged people) which demonstrates all 3 timers running at the same time.

TCC4 is used to generate 4ms tick which are then counted to generate 100ms and 1s time ticks which toggle LED1 and LED2 on the E5 Xplain board (PD4 and PD5).

TCC5 is used to generate a 10ms tick which is used to generate a 50Hz square wave on PC0.

TCD5 is used to generate a 500us tick which is used to generate a 1KHz square wave on PC1.

I have used all 3 interrupts levels depending on how fast the timers are running, not really necessary but for fun.

And finally please don't start the usual ASM vs C war simply because the code generated by the C program is almost twice the size of the ASM size. :mrgreen:

Attachment(s): 

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

Thanks John.

I look forward to trying your code next week.

Cheers,

Ross

Ross McKenzie, Melbourne Australia

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

Quote:
The simplest way to achieve "CTC mode" with the E5 is to use the period register and the CCA flag, even though when the period is up all CC flags are set including the OVF, the CC flags seem to work well but the OVF doesn't seem to work in this mode.

Sorry to dig up the past...

Its been a long while since I first worked with an E5, and it has been frustrating as I like the features within the chip, but I had problems generating a simple timed ISR, (for debounce, heart beat, DDS, etc.).

I'm glad to say that with the current E5's, and a few Bascom updates, (Thank you, Mark! ), I can now easily generate a timed ISR.

I was previously using a "work around" figured out by JS, (Thank you, JS! ).

I now set the TCC4 in "Normal" mode, and use the Period register to hold the Top value. The Overflow interrupt then fires on Top, and automatically starts over counting at 0, similar to CTC mode in the Mega's.

One additional "feature", I found I have to clear the overflow interrupt flag myself, within the ISR. Generally, at least with my prior Mega work, the flag was automatically cleared when one entered the ISR routine. No so any more with the E5's.

Thanks to JS and to Mark at Bascom for helping me get this all working!

The core setup is as below, for a 1000 Hz Interrupt:

 'Clock = 32 MHz.
   'Prescaler is / 64.  32MHz/64 --> 500,000 Hz output of PreScaler.
   '500K/500 = 1000.00 Hz as the OverFlow Intr Rate.
   'Set TCC4_Per = 499 (Roll Over counts as 1)

   Config Tcc4 = Normal , Prescale = 64
   Tcc4_per = 499   'Set Top value

   On Tcc4_ovf Ticktock  'Define ISR Label

   Enable Tcc4_ovf , Med  'Enable the Overflow ISR

   'Enable Interrupts:
   Config Priority = Static , Vector = Application , Hi = Enabled , Lo = Enabled , Med = Enabled
   Enable Interrupts  'Master Interrupts Enable

And inside the ISR:

Ticktock:
   'Timer/Counter C4 ISR.  Fires at 1000 Hz.
   'Reset the Overflow Flag inside the ISR!

   Tcc4_intflags = 1  'Clr Ovf Intr Flag

   Set PortA.0    'scope
   etc.
   Reset PortA.0  'scope
   Return

I'll clean up clearing with overflow flag to read the register, clear just that flag, and restore it. But for this testing it didn't matter as the other interrupts weren't being executed.

Still, all in all, it is nice to have a "win" now and then.

JC

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

Quote:
I found I have to clear the overflow interrupt flag myself, within the ISR
I think I have seen this before but I'm not sure if it is just overflow flag related ONLY.

Looking at my ASM code above I'm not clearing any flags within the ISRs.

And I don't know why WinZip is refusing to open the files. :evil:

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

I just got burned by that one too. Some ISRs clear the interrupt flag automatically. Others don't. Sometimes you find both of these on different bits in the same flag register. It is documented, however.
/mike

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

Yep, after working a lot with the XMEGA A and AU series, I was also tripped up by the timer overflow interrupt flag not automatically clearing when executing the ISR.  Clear it in the ISR by writing a one to its location and it works just fine (as stated in the XMEGA E Manual). 

 

Conversely, the compare and capture interrupt flags DO clear automatically when the corresponding interrupt vector is executed.  Good times.

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

Thank you so much John

 

I also try to use the E series but I am relatively new to XMEGA.

1st did use the ATMEGA32U2-AU

then changed to ATxmega32A4U becasue of higher speed and lower price, the code transfer for the low level routines from ATMEGA to ATXMEGA have been done by an external company that time.

my project/set need 2 controllers...for the smaller I want to use ATXMEGAxxE5 beacsue no need USB

I really did not epect there are so many differences between A and E series

 

sicne 2 days I am struggling to get a 1ms (or any) timer running and was so happy to find your code.

 

BUT...whatever I do the TC45_CCAINTLVL_LO_gc und such definitions are missing

I thought I did confuse my project bacsue did play around with ASF a bit.

Therefoer made a completely new project just with your  code and also cannot find the TC45_CCAINTLVL_LO_gc

the controller setting in the project is correct, I can program the controller via DragonBoard...all seems OK.

 

hopefully my question is not too dumb :-)

 

UPDATE:

I am using TC_TC4_CCAINTLVL_HI_gc and TC_TC4_CLKSEL_DIV256_gc

now it works like a charme

 

Thanks again John; the ASF made me crazy.

Martin

SundialLED: The best artifcial lighting is the sort that you do not even notice

Last Edited: Fri. Jan 27, 2017 - 08:49 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

also cannot find the TC45_CCAINTLVL_LO_gc

Did you find it now? What version of Studio were you using? It is there, I think I was using AS6.1 at that time both for ASM and C.

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

I think the defines without the TC_ are from ASF
in iox32e5.h only the defines with TC_ are defined, as I wrote in my update, it works now.

Martin

SundialLED: The best artifcial lighting is the sort that you do not even notice