Interrupts on Xmega

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

I'm trying to understand the new XMEGA range, in particular the XMEGA32-E5.

I'm using CodeVision AVR (version 3) and I'm trying to wrap my head around setting an interrupt on the timer overflow, something I've done many times with the old MEGA range.

What I want is to set a timer at say 1Mhz, and have it run a bit of code each time it overflows, so I get a bit of code run at regular intervals.

How do I do this?

Come to that, how do I setup an interrupt such that when a pin has a falling edge I can execute a bit of code. Again it doesn't seem obvious.

I am assuming these are related to the event system, but I'm a bit confused, so any example code/useful URLs would be very much appreciated.

Paul

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

Quote:
I am assuming these are related to the event system

No. The Event system is totally separate, and not something you need to interact with at the moment.

You are aware there are TWO manuals (data sheets) needed for an Xmega chip. You need to both to get anything done, and you will continually open up the wrong one first. Just the way it is.

JS has some working Xmega E Series code, in C and assembly.

Perhaps he will have some insights for you.

JC

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

Check out the AVR appnotes for Xmegas, timers, on their site and they include C code. Doesn't CV's code wizard generate such code for Xmegas ?

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

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

Paul,

Here's a code snippet that does something close to what you've asked. I've had it running on an Xmega D3; should just be some minor adjustments to use a timer available on E5(with caveat: I've not used E5 at all).

void pwm_init(){
	//set up for PWM out as well as program clock
	TCE0.CTRLB = TC_WGMODE_SS_gc | TC0_CCBEN_bm | TC0_CCAEN_bm;   // 2 COMP outputs
	
	   // configure timer/counter0
	   TCE0.CTRLA = TC_CLKSEL_DIV8_gc;  
	   TCE0.PER   = 200;//sets top -- PW of 1/20k
	   
	TCE0.CCA = 1; // set duty cycle on A

	TCE0.CCB = 90; // set duty cycle on B
	
    PORTE.DIRSET = PIN0_bm | PIN1_bm;
	
	  TCE0.INTCTRLA = TC_OVFINTLVL_LO_gc;   // Enabled: Overflow interrupt with LOW Priority on port C
	  TCE0.INTCTRLB = TC_CCAINTLVL_MED_gc | TC_CCBINTLVL_MED_gc;  //Capture/Compare interrupt on CCA and CCB

	  TCE0.INTFLAGS = 0;                    // Reset: Overflow Flag in bit 0; clear any initial interrupt flags!
	  
	   PMIC.CTRL |= PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm; 

}

ISR (TCE0_OVF_vect)
{
t++;
//code on overflow
}
ISR (TCE0_CCA_vect)
{
//code for CCA compare
}
ISR (TCE0_CCB_vect)
{
//code on CCB compare	
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

TWO datasheets?
oh dear god, thanks, I'll revisit the site.

as for teh CV AVR wizard, yes it should generate the stuff for me, but I can't see 'timers' on the list anywhere. But then I'm using version 3 now and I'm used to version 2 so a lot has changed. I'll continue poking it some more.

Thanks for the info about the app notes and the code example...

More time needed with the chip I think.

thanks guys

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

Update, I did some digging.... Seems the XMEGA32-E doesn't have a timer, at least not in the CodeVision wizard :(

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

Of course it has timers (look in the two datasheets). Usually the XMegas have many timers, the E5's only have three 16 bit timers (TCC4, TCC5, TCD5). The RTC module have a 16 bit timer. There's two 8 bit timers associated with the XCL module.

Here's a short example (for avr-gcc) that setup a timer with overflow interrupt for the XMegaE5.

#include 
#include 

ISR(TCC4_OVF_vect)
{
    // Clear interrupt flag
    TCC4.INTFLAGS = TC4_OVFIF_bm;
    // Toggle a pin to tell we were here
    PORTA.OUTTGL = PIN0_bm;
}

int main(void)
{
    // PA0 output
    PORTA.DIR = PIN0_bm;
    // TCC4 1MHz timer tick, 1kHz overflow if F_CPU=2MHz
    TCC4.PER = 999;
    // Low level overflow interrupt
    TCC4.INTCTRLA = TC45_OVFINTLVL_LO_gc;
    // Start timer with presc. 1:2
    TCC4.CTRLA = TC45_CLKSEL_DIV2_gc;

    // Enable low level interrupts
    PMIC.CTRL |= PMIC_LOLVLEN_bm;
    sei();

    while(1)
    {
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You probably forgot to set the PMIC.CTRL register as it's not mentioned in the timer section, but in the interrupt section.

I'm in the same boat as you: still rather adrift in the sea of xMega.

If you don't know my whole story, keep your mouth shut.

If you know my whole story, you're an accomplice. Keep your mouth shut. 

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

Tried some more settings, I can't get the timer settings to appear in the CVAVR wizard, so I've mailed them to ask.

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

I just use Atmel Studio. Perhaps the E5's are still too new for CV to know about.

If you don't know my whole story, keep your mouth shut.

If you know my whole story, you're an accomplice. Keep your mouth shut. 

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

Quote:
Perhaps the E5's are still too new for CV to know about.
No, you need V3.05 at least. V3.06 is now out and about to download.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

JS, thanks, but I have V3.05 and just updated to V3.06 to see if that corrected it, it doesn't..

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

I have V3.06 and there is no timers for the 32E5 in the wizard

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

The XMEGA E5 chips are new and the timers are different than the rest of XMega devices, so we haven't got the time to add them yet in the CodeWizard.
The compiler itself however fully supports the E5 chips.
We will add the timers in V3.07.
In the meantime the Atmel XMEGA E manual must be used for programming them.

Regards,
Pavel

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

This is the fruit of several weeks (months??) of struggle with the E5 timers
https://www.avrfreaks.net/index.p...

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

Except for trying to use the wrong timer, I found it pretty easy to work a servo with an 8E5.

I still find it hard to guess what the name of a register or bit will be in the io.h from reading the data pdf. I had it mostly figured out for tinys.

If you don't know my whole story, keep your mouth shut.

If you know my whole story, you're an accomplice. Keep your mouth shut. 

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

dears hello

I have a problem in XMEGA TCC0 OVER FOLLOW INTRRUPT in assembly code

what should I do ? and how I have to write in assembly

 

 

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

Which assembler?

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

Atmel Studio 6

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

Dear clawson I used Atmel Studio 6

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

Dear all Hello

does any body Knows how to write a simple blinking LED with Timer /Counter0 in Assembly with using TCC0 interrupt in Atmel Studio6 or 7

I Have problem with interrup routin

 

best regards

essi_M

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

When you post about software questions, ALWAYS list the toolchain, and chip you're using, . WHICH Xmega are you using and what problem do you have ? I suggest learning C ...programming these chips exclusively in assembly just makes no sense. Do you have any code you've written ( post it if you do ) ?

 

Also, go to Atmel's site look in the 8 bit controller area for Xmega group and you'll find App notes and code for the subsystems.

 

 

Jerome

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

Last Edited: Thu. Jun 23, 2016 - 09:07 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Which assembler?

Atmel Studio 6

There are TWO assemblers in Studio, which one are you using?

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

 

; * test1.asm
; *
; *  Created: 2016/02/27 09:47:36 ?.?
; *   Author: E-Maleki
 
 .include "Atxmega64a3udef.inc"

.cseg
.org      0x00
rjmp      main
.org      TCC0_OVF_vect == 0x1c
rjmp       TCC0_OVF_handler

;setting stack pointer address to ramend
         ldi       r16                 , HIGH(RAMEND)                     ;Set Stack pointer to RamEnd of internal SRAM
         out       CPU_sph             , r16                              ;Set Stack pointer to RamEnd of internal SRAM
         ldi       r16                 , LOW(RAMEND)                      ;Set Stack pointer to RamEnd of internal SRAM
         out       CPU_SPL             , r16                             ;Set Stack pointer to RamEnd of internal SRAM
         clr       r16                                                   ;clear temp

;********************************************************************************************************************************
;********************************************************************************************************************************
;********************************************************  main routin  *********************************************************
;********************************************************************************************************************************
;********************************************************************************************************************************
main:
;setting internal oscilator(for 32K or 2M comment should be removed and 32M should be commented)
;         rcall     Select32KCLK                                          ;setting internal oscilator at 32 khz
          rcall     Select2MCLK                                           ;setting internal oscilator at 2 Mhz
;         rcall     Select32MCLK                                           ;setting internal oscilator at 32 Mhz

 

         ldi       r16            , 0xFF                                  ;Load r16 with 0xff
         sts       PORTE_DIR      , r16                                   ;PORTE_DIR(1664d=0x0680h) as output
         ldi       r16            , 0xFF                                  ;Load r16 with 0xff
         sts       PORTE_OUTSET   , r16                                   ;PORTE_OUTSET(1669d=0x0685h) all pins high

         ldi       r16            , 0xFF                                  ;Load r16 with 0xff
         sts       PORTF_DIR      , r16                                   ;PORTF_DIR(1696d=0x06A0h) as output

; PORTF_DIRSET=PIN6_bm|PIN5_bm|PIN4_bm|PIN3_bm|PIN2_bm|PIN1_bm;
         ldi       r24            , 0x7E
         sts    PORTF_DIRSET      , r24
; TCC0_INTCTRLA=TC_OVFINTLVL_LO_gc;
         ldi       r18            , TC_OVFINTLVL_LO_gc
         sts       TCC0_INTCTRLA  , r18
; TCC0_PER=3999;   // overflow time = 2 ms
         ldi       r24            , 0x24
         ldi       r25            , 0x0
         sts       TCC0_PER_LOW   , r24
         sts       TCC0_PER_HIGH  , r25
; TCC0_CTRLA=TC_CLKSEL_DIV1_gc;
         ldi       r18            , TC_OVFINTLVL_LO_gc
         sts       TCC0_CTRLA     , r18
; PMIC_CTRL=PMIC_LOLVLEN_bm;
         ldi       r18            , PMIC_LOLVLEN_bm
         sts       PMIC_CTRL      , r18
         sei

ESSI_1:
         rjmp       ESSI_1

TCC0_OVF_handler:
         cli
         ldi       r16            , 0xFE                                  ;
         sts       PORTF_OUTTGL   , r16
         reti

 

;************************************************************************************************************
;                                     routin for setting internal oscilator
;************************************************************************************************************
;-------------------------------------------------------------------------
;-------------------------------------------------------------------------
;setting internal oscilator to 32k
Select32KCLK:
         lds       r16                 , OSC_CTRL
         ori       r16                 , OSC_RC32KEN_bm
         sts       OSC_CTRL            , r16
;do {} while ( CLKSYS_IsReady( OSC_RC32KRDY_bm ) == 0 )                   ;
c32kclk:
         lds       r16                 , OSC_STATUS
         sbrs      r16, 0
         rjmp      c32kclk         
;CLKSYS_Main_ClockSource_Select( CLK_SCLKSEL_RC32K_gc )                   ;
         lds       r16                 , CLK_CTRL
         andi      r16                 , 0xF8                             ; 248
         ldi       r17                 , CLK_SCLKSEL_RC32K_gc
         or        r17                 , r16
         cli
         ldi       r16                 , CCP_IOREG_gc
         sts       CPU_CCP             , r16
         sts       CLK_CTRL            , r17
;CLKSYS_Disable( OSC_RC32MEN_bm | OSC_RC2MEN_bm )                         ;
         ldi      r16                  , OSC_RC32MEN_bm | OSC_RC2MEN_bm
         sts      OSC_CTRL             , r16
         ret
;-------------------------------------------------------------------------
;-------------------------------------------------------------------------
;setting internal oscilator to 2M
Select2MCLK:
         lds       r16                 , OSC_CTRL
         ori       r16                 , OSC_RC2MEN_bm
         sts       OSC_CTRL            , r16
;do {} while ( CLKSYS_IsReady( OSC_RC2MRDY_bm ) == 0 )                    ;
c2clk:
         lds       r16                 , OSC_STATUS
         sbrs      r16                 , 0
         rjmp      c2clk         
;CLKSYS_Main_ClockSource_Select( CLK_SCLKSEL_RC2M_gc )                    ;
         lds       r16                 ,CLK_CTRL
         andi     r16                  , 0xF8                             ;
         ldi      r17                  , CLK_SCLKSEL_RC2M_gc
         or       r17                  , r16
         cli
         ldi      r16                  , CCP_IOREG_gc
         sts      CPU_CCP              , r16
         sts      CLK_CTRL             , r17
;CLKSYS_Disable( OSC_RC32MEN_bm | OSC_RC32KEN_bm )                        ;
         ldi       r16                 , OSC_RC32MEN_bm | OSC_RC32KEN_bm
         sts       OSC_CTRL            , r16
         ret
;-------------------------------------------------------------------------
;-------------------------------------------------------------------------
;setting internal oscilator to 32M
Select32MCLK:
;CLKSYS_Enable( OSC_RC32MEN_bm )                                          ;
         lds       r16                 , OSC_CTRL
         ori       r16                 , OSC_RC32MEN_bm
         sts       OSC_CTRL            , r16
;do {} while ( CLKSYS_IsReady( OSC_RC32MRDY_bm ) == 0 )                   ;
c32mclk:
         lds       r16                 , OSC_STATUS
         sbrs      r16                 , 1
         rjmp      c32mclk
;CLKSYS_Main_ClockSource_Select( CLK_SCLKSEL_RC32M_gc )                   ;
         lds       r16                 , CLK_CTRL
         andi      r16                 , 0xF8                             ;
         ldi       r17                 , CLK_SCLKSEL_RC32M_gc
         or        r17                 , r16
         cli
         ldi       r16                 , CCP_IOREG_gc
         sts       CPU_CCP             , r16
         sts       CLK_CTRL            , r17
;CLKSYS_Disable( OSC_RC2MEN_bm | OSC_RC32KEN_bm )                         ;
         ldi       r16                 , OSC_RC2MEN_bm | OSC_RC32KEN_bm   ;
         sts       OSC_CTRL            , r16
         ret

 

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

A simple program just for int , but it does not work

 

; * test1.asm
; *
; *  Created: 2016/02/27 09:47:36 ?.?
; *   Author: E-Maleki
 
 .include "Atxmega64a3udef.inc"

.cseg
.org      0x00
rjmp      main
.org      TCC0_OVF_vect
rjmp       TCC0_OVF_handler

;setting stack pointer address to ramend
         ldi       r16                 , HIGH(RAMEND)                     ;Set Stack pointer to RamEnd of internal SRAM
         out       CPU_sph             , r16                              ;Set Stack pointer to RamEnd of internal SRAM
         ldi       r16                 , LOW(RAMEND)                      ;Set Stack pointer to RamEnd of internal SRAM
         out       CPU_SPL             , r16                             ;Set Stack pointer to RamEnd of internal SRAM
         clr       r16                                                   ;clear temp

;********************************************************************************************************************************
;********************************************************************************************************************************
;********************************************************  main routin  *********************************************************
;********************************************************************************************************************************
;********************************************************************************************************************************
main:

         ldi       r16            , 0xFF                                  ;Load r16 with 0xff
         sts       PORTE_DIR      , r16                                   ;PORTE_DIR(1664d=0x0680h) as output
         ldi       r16            , 0xFF                                  ;Load r16 with 0xff
         sts       PORTE_OUTSET   , r16                                   ;PORTE_OUTSET(1669d=0x0685h) all pins high

         ldi       r16            , 0xFF                                  ;Load r16 with 0xff
         sts       PORTF_DIR      , r16                                   ;PORTF_DIR(1696d=0x06A0h) as output

; PORTF_DIRSET=PIN6_bm|PIN5_bm|PIN4_bm|PIN3_bm|PIN2_bm|PIN1_bm;
         ldi       r24            , 0x7E
         sts    PORTF_DIRSET      , r24
; TCC0_INTCTRLA=TC_OVFINTLVL_LO_gc;
         ldi       r18            , TC_OVFINTLVL_LO_gc
         sts       TCC0_INTCTRLA  , r18
; TCC0_PER=3999;   // overflow time = 2 ms
         ldi       r24            , 0x24
         ldi       r25            , 0x0
         sts       TCC0_PER_LOW   , r24
         sts       TCC0_PER_HIGH  , r25
; TCC0_CTRLA=TC_CLKSEL_DIV1_gc;
         ldi       r18            , TC_OVFINTLVL_LO_gc
         sts       TCC0_CTRLA     , r18
; PMIC_CTRL=PMIC_LOLVLEN_bm;
         ldi       r18            , PMIC_LOLVLEN_bm
         sts       PMIC_CTRL      , r18
         sei

ESSI_1:
         rjmp       ESSI_1

TCC0_OVF_handler:
         cli
         ldi       r16            , 0xFE                                  ;
         sts       PORTF_OUTTGL   , r16
         reti

 

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

Several times now you have said "I have a problem" without actually telling us what the problem is.

 

BTW your stack setting code is unreachable isn't it? (it probably doesn't matter as I imagine the Xmega are like all modern tiny/mega and set SP to RAMEND at power on anyway)

 

Oh and i cannot help but notice that your comments are written as C statements:

; PORTF_DIRSET=PIN6_bm|PIN5_bm|PIN4_bm|PIN3_bm|PIN2_bm|PIN1_bm;
; TCC0_INTCTRLA=TC_OVFINTLVL_LO_gc;
; TCC0_PER=3999;   // overflow time = 2 ms
; TCC0_CTRLA=TC_CLKSEL_DIV1_gc;
; PMIC_CTRL=PMIC_LOLVLEN_bm;

So if you know C why not write this in C, compile it then look at the Asm code the C compiler generates and compare it to what you are trying to use.