AVR32 Interrupt Routines with Atmel Studio 7

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

How can the RTC interrupt link to the INTC?

And how to call the interrupt routine function without ASF (I found it hard to use ASF sometimes) in Atmel Studio? I am now currently using AT32UC3B0512.

Thanks,

An

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

The RTC can generate a timer-overflow interrupt if you set the TOPI bit in the IER register., and that interrupt-request will go to the INTC controller.
The INTC must be configured before interrupts can be processed by your interrupt-handlers.
The ASF has 2 routines to do all that,
INTC_init_interrupts( ); which you call once to configure the INTC module, and
INTC_register_interrupt( your_interrupt_handler, interrupt-number, interrupt-priority ); which you use to link the interrupt-source(s) to your interrupt-handler(s).


If you do not want to use the ASF then you will need to configure the INTC module and that can become 'interesting' because ;
a) the interrupt-handlers must be within +16kb from the start of the EVBA (interrupt vector table) and
b) the compiler may place your interrupt-handlers outside of that 16kb region.

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

Thanks. 

The reason why I do not want to use ASF is that there are several strange errors happen. 

/*
 * Test_3.c
 *
 * Created: 2017/7/31 4:02:08
 * Author : Frank
 */ 

#include <avr32/io.h>
#include "intc.h"

void delay_1()
{
	int i;
	for(i=0;i<100;i++);
}

int main(void)
{
	AVR32_GPIO.port[1].gpers |= 0x4;
	AVR32_GPIO.port[1].oders |= 0x4; //PB02 EN
	AVR32_RTC.ier  |= 0x1; //Enable interrupt
	AVR32_RTC.ctrl |= 0x1001b; //En, CLKEN, BUSY, PCLR, CLK32
	unsigned int a =0;
	unsigned int s =0;
	
	
    /* Replace with your application code */
    while (1) 
    {
		while (a<100)
		{
			if (AVR32_RTC.isr & 1) a++;
			
		}
		a = 0;
		AVR32_RTC.idr |= 0x1; //Disable Interrupt
		AVR32_GPIO.port[1].ovrs ^= ~s << 2; //PB02 LED
		AVR32_RTC.ier |= 0x1; //Enable Interrupt
    }
}

Which outputs (I haven't use the functions inside intc.h) errors:


Error		multiple definition of `_stext'	Test_3		1
Error		multiple definition of `_start'	Test_3		1
Error		first defined here	Test_3	c:\program files (x86)\atmel\studio\7.0\toolchain\avr32\avr32-gnu-toolchain\avr32\lib\ucr2\crt0.o	1
Error		first defined here	Test_3	c:\program files (x86)\atmel\studio\7.0\toolchain\avr32\avr32-gnu-toolchain\avr32\lib\ucr2\crt0.o	1
Error		recipe for target 'Test_3.elf' failed	Test_3	c:\users\frank\Documents\Atmel Studio\7.0\Test_3\Test_3\Debug\Makefile	206

Also, for some includes such as gpio.h, rtc.h, it needs board.h that cannot be found inside the install directory. I soldered my own evaluation board for the cost-effective reason so some pre-setup inside the includes for EVK1101 is not useful.

I know that the ASF is very easy to use. It will be better if there are no strange errors.

 

Have you met this situation while compiling?

Thanks.

 

An

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

Those errors occur because your project is using the wrong C startup code.
go to the menu : Project -> ... Properties -> Toolchain -> AVR32/GNU Linker -> General and tick the "Do not use standard start files (-nostartfiles)" option.

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

Well, cheers. Except some modules(that needs to include board.h), I can include all the other modules.

Thanks very much!

Last Edited: Tue. Aug 1, 2017 - 06:09 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Registers in the AVR32 can have several access-modes, such as; Read, Write, Write-only, Set, Clear and Toggle., but you must check the 'Access Type' description for what is allowed on the register that you want to manipulate.


AVR32_GPIO.port[1].gpers |= 0x4; will probably work, but AVR32_GPIO.port[1].gpers = 0x4; is better.
AVR32_RTC.ier |= 0x1; is incorrect, because it tries to read from a write-only register., use AVR32_RTC.ier = 0x1;
AVR32_RTC.idr |= 0x1; is incorrect, because it tries to read from a write-only register., use AVR32_RTC.idr = 0x1;


Enabling interrupts without having an interrupt-handler is 'not a good idea'.


To toggle an output, you should use AVR32_GPIO.port[1].ovrt = ~s << 2; because it is faster and simpler. (no need for you to read the current value and then invert it)


Be careful with statements such as AVR32_RTC.ctrl |= 0x1001b; because it is equivalent to AVR32_RTC.ctrl = AVR32_RTC.ctrl | 0x1001b;
which reads the old value, sets some bits and writes the new value, but, you must know what the old value was or unexpected things might happen.
The reset value of RTC.ctrl is 0x0001000 so AVR32_RTC.ctrl |= 0x1001b; will do what you expect, but it will be incorrect if you did not want the CLKEN bit to be set at this time.

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

Yes, you are right. I ignore some 'read' actions that hide inside the operations. And giving value directly somewhere is a safer way to set the registers.

I am finding out the evba and other registers. And.. RTC's registers.

 

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

The most difficult thing: there are very few example codes for me to reference and the only reference is the complete manual.. The application notes are not very useful for general use I think. If someone can write some codes or lessons like ATmega, there must be more people focusing on it. Just imagine Arduino with AT32 ;D

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

I have found a new include file on atmel official site: macro.h!

And the disappeared file AVR32101: http://www.doc88.com/p-989628910023.html

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
/*
 * Test_3.c
 *
 * Created: 2017/7/31 4:02:08
 * Author : Frank
 */ 

#include <avr32/io.h>
#include "intc.h"
#include "interrupt.h"


unsigned int a =0;
unsigned int s =0;

__attribute__((__interrupt__)) void rtc_handler()
{
	if (a<100) {a++;}
	else 
		{
			a=0;
			AVR32_GPIO.port[1].ovrt = ~s << 2; //PB02 LED
		}
}

int main(void)
{
	Disable_global_interrupt();
	INTC_init_interrupts();
	AVR32_GPIO.port[1].gpers = 0x4;
	AVR32_GPIO.port[1].oders |= 0x4; //PB02 EN
	AVR32_RTC.ier  = 0x1; //Enable interrupt
	AVR32_RTC.ctrl = 0x1001b; //En, CLKEN, BUSY, PCLR, CLK32
	
	INTC_register_interrupt(&rtc_handler, AVR32_RTC_IRQ, AVR32_INTC_INT3); //RTC interrupt
	
	Enable_global_interrupt();
	
    /* Replace with your application code */
    while (1) 
    {
		;
    }
}

Compile success. Haven't run on board. Thanks for steed

Now waiting for my PCB board mailed home.

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

MrAn wrote:
The most difficult thing: there are very few example codes for me to reference

So why did you choose this processor, then?

 

It has always been a "niche" processor: http://www.avrfreaks.net/comment... - so really not the one to choose if you want wide support!

 

And this is unlikely to change as the AVR32 is, essentially, a legacy product:

 

http://www.avrfreaks.net/forum/uc3-legacy

 

http://www.avrfreaks.net/forum/avr32-dead-long-live-what

 

 

If someone can write some codes or lessons like ATmega

See above - there just isn't the call for it.

 

Why not just us an ATmega?

 

 

#AVR32niche

 

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

awneil wrote:
Why not just us an ATmega?
Or if you need "32 bit power" then a Cortex M0(+), M3 or M4 (ie Atmel SAM D20/21, SAM3 or SAM4)