Valid ISR names for -1 series AVRs

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

Hi,

 

I've been using a 3216 board graciously provided by Spence Konde along with his core and UPDI programmer tutorial. So far so good. I'm able to load up some sketches using the Arduino IDE, and then I'm able to get a pin change type interrupt to work by setting registers appropriately. Very satisfied with all of that. When I try to get a timer compare interrupt to kick off I get a suggestion that I'm misspelling the ISR name.  Most of what I made below comes from the app notes linked here. I'll put the code that works, doesn't work and the error below. 

 

Code that works, makes the LED toggle at every falling pin change:

#define PB2_INTERRUPT PORTB.INTFLAGS & PIN2_bm
#define PB2_CLEAR_INTERRUPT_FLAG PORTB.INTFLAGS &= PIN2_bm
#define PB2_LOW !(PORTB.IN & PIN2_bm)

void setup()
{
PORTA.DIR = PIN7_bm; //sets PA7 to output
PORTB.DIR &= ~PIN2_bm; //seta PB2 to input
PORTB.PIN2CTRL |=PORT_PULLUPEN_bm;
PORTB.PIN2CTRL |=PORT_ISC_FALLING_gc; // enables pull up and configures interrupt for PB2
}

void loop() {
  // put your main code here, to run repeatedly:
}

ISR(PORTB_PORT_vect)
{
  if(PB2_INTERRUPT)
  {
     PORTA.OUT ^=PIN7_bm; //TOGGLES THE led PIN
    //delay(250);
    PORTB.INTFLAGS &= PIN2_bm;//PB2_CLEAR_INTERRUPT_FLAG;
  }
}

 

Code that doesn't work, would like to see this code toggle the LED at every timer compare match:

 

void setup()
{
cli();
PORTA.DIR = PIN7_bm; //sets PA7 to output
TCB0.CCMP =0xFFFF; //Make the time duration a long as possible
TCB0.CTRLA = 1;// Should put a 1 in the Enable bit
TCB0.CTRLB = 0; //should be periodic interrupt mode (page 256)
TCB0.INTCTRL = 1;//Should enable capture interrupt
sei();
}

void loop() {
  // put your main code here, to run repeatedly:
}

ISR(TCB0_CAPT_vect) //not sure what this should be
{
 PORTA.OUTTGL = PIN7_bm;
 TCB0.INTFLAGS = 1; // Should clear the interrupt flag
}

 

The data sheet, table 21-4. says that the vector name is CAPT, in the format of peripheral_vectorname_vect seems like TCB0_CAPT_vect is about right... 

 

But here is the error:

:\Users\Bill\Documents\Arduino\testATTINY3216\testATTINY3216.ino:21:5: warning: 'TCB0_CAPT_vect' appears to be a misspelled 'signal' handler, missing '__vector' prefix [-Wmisspelled-isr]

 ISR(TCB0_CAPT_vect)

 

Any ideas?

This topic has a solution.

Bill

Last Edited: Sat. Dec 7, 2019 - 05:06 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That is "TCB0_INT_vect"

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

bigginsking wrote:

ISR(TCB0_CAPT_vect)

 

Yep, thats wrong. maybe you should take a look at this app note:

 

AVR1000: Getting Started with Writing C-Code for XMEGA

 

also take a look at the atdf file along with the XML description.

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

You can also look at the iotn3216.h file (probably off in a pack directory.)

 

#define TCA0_LUNF_vect      _VECTOR(8)  /*  */
#define TCA0_OVF_vect      _VECTOR(8)  /*  */
#define TCA0_HUNF_vect      _VECTOR(9)  /*  */
#define TCA0_LCMP0_vect      _VECTOR(10)  /*  */
#define TCA0_CMP0_vect      _VECTOR(10)  /*  */
#define TCA0_CMP1_vect      _VECTOR(11)  /*  */
#define TCA0_LCMP1_vect      _VECTOR(11)  /*  */
#define TCA0_CMP2_vect      _VECTOR(12)  /*  */
#define TCA0_LCMP2_vect      _VECTOR(12)  /*  */
#define TCB0_INT_vect      _VECTOR(13)  /*  */
#define TCB1_INT_vect      _VECTOR(14)  /*  */
#define TCD0_OVF_vect      _VECTOR(15)  /*  */
#define TCD0_TRIG_vect      _VECTOR(16)  /*  */

 

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


Or more generally, ALL the vectors for a 3216:

C:\Program Files (x86)\Atmel\Studio\7.0\packs\atmel\ATtiny_DFP\1.3.229\include\avr>grep _VECTOR iotn3216.h
#define CRCSCAN_NMI_vect      _VECTOR(1)  /*  */
#define BOD_VLM_vect      _VECTOR(2)  /*  */
#define PORTA_PORT_vect      _VECTOR(3)  /*  */
#define PORTB_PORT_vect      _VECTOR(4)  /*  */
#define PORTC_PORT_vect      _VECTOR(5)  /*  */
#define RTC_CNT_vect      _VECTOR(6)  /*  */
#define RTC_PIT_vect      _VECTOR(7)  /*  */
#define TCA0_LUNF_vect      _VECTOR(8)  /*  */
#define TCA0_OVF_vect      _VECTOR(8)  /*  */
#define TCA0_HUNF_vect      _VECTOR(9)  /*  */
#define TCA0_LCMP0_vect      _VECTOR(10)  /*  */
#define TCA0_CMP0_vect      _VECTOR(10)  /*  */
#define TCA0_CMP1_vect      _VECTOR(11)  /*  */
#define TCA0_LCMP1_vect      _VECTOR(11)  /*  */
#define TCA0_CMP2_vect      _VECTOR(12)  /*  */
#define TCA0_LCMP2_vect      _VECTOR(12)  /*  */
#define TCB0_INT_vect      _VECTOR(13)  /*  */
#define TCB1_INT_vect      _VECTOR(14)  /*  */
#define TCD0_OVF_vect      _VECTOR(15)  /*  */
#define TCD0_TRIG_vect      _VECTOR(16)  /*  */
#define AC0_AC_vect      _VECTOR(17)  /*  */
#define AC1_AC_vect      _VECTOR(18)  /*  */
#define AC2_AC_vect      _VECTOR(19)  /*  */
#define ADC0_RESRDY_vect      _VECTOR(20)  /*  */
#define ADC0_WCOMP_vect      _VECTOR(21)  /*  */
#define ADC1_RESRDY_vect      _VECTOR(22)  /*  */
#define ADC1_WCOMP_vect      _VECTOR(23)  /*  */
#define TWI0_TWIS_vect      _VECTOR(24)  /*  */
#define TWI0_TWIM_vect      _VECTOR(25)  /*  */
#define SPI0_INT_vect      _VECTOR(26)  /*  */
#define USART0_RXC_vect      _VECTOR(27)  /*  */
#define USART0_DRE_vect      _VECTOR(28)  /*  */
#define USART0_TXC_vect      _VECTOR(29)  /*  */
#define NVMCTRL_EE_vect      _VECTOR(30)  /*  */
#define _VECTOR_SIZE 4 /* Size of individual vector. */
#define _VECTORS_SIZE (31 * _VECTOR_SIZE)

Another way to access this is to simply start a project in AS7 for 3216. Don't bother to add anything to the empty main() but just build it. As soon as you have you will find:

 

 

In that file just search for "_VECTOR":

 

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

bigginsking wrote:
Code that works...

ISR(PORTB_PORT_vect)

As you have (at least) one ISR which compiles OK, another possibility to find where the vector names are defined would be to use the IDE's "Go To Definition" facility - it is likely that they will all be in the same place (and previous posts have shown that they are).

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Tue. Dec 3, 2019 - 10:02 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for all the great advice, this forum is fantastic.

 

I'm still monkeying with registers to get the timer to work right but I should be able to get that all squared away.

 

 

Bill

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You're welcome.

 

If that's resolved the issue, see Tip #5.

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

For completeness here is my code for making the LED toggle with a compare interrupt using the Arduino IDE:

 



//compare interrupt based LED toggle set to toggle every ~420 ms with 20MHz processor
void setup() 
{
PORTA.DIR = PIN7_bm; //sets PA7 to output
cli(); //shut of interrupts 
CCP = CCP_IOREG_gc; //write the Configuration Change Protection signature to allow the next instruction to execute
CLKCTRL.MCLKCTRLB = CLKCTRL_PDIV_64X_gc|CLKCTRL_PEN_bm; //set up prescaler for clk/64
TCB0.CCMP =0xFFFF; //Make the time duration a long as possible
TCB0.CTRLA = TCB_CLKSEL_CLKDIV2_gc|TCB_ENABLE_bm;// take the processor clock and divide by 2 | enable TCB 
TCB0.CTRLB = TCB_CNTMODE_INT_gc|TCB_CCMPEN_bm; //periodic interrupt mode (page 256) | enable CCMP/compare capture mode
TCB0.INTCTRL = TCB_CAPT_bm;//Should enable capture interrupt
sei(); // turn interrupts back on
}

void loop() {
  // put your main code here, to run repeatedly:
}

ISR(TCB0_INT_vect)
{
 PORTA.OUTTGL = PIN7_bm;//Toggle pin
 TCB0.INTFLAGS |= 0x1;//clear the interrupt flag
}

 

Bill

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

bigginsking wrote:

 TCB0.INTFLAGS |= 0x1;//clear the interrupt flag

I'm not an expert on the newfangled series, but this line scares me.  While the code may work perfectly fine for TCB0 having only one used bit in INTFLAGS as in '3216, wouldn't a RMW as shown on e.g. TCA0.INTFLAGS cause all the bits to be cleared?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

If you are asking then I really don't know... how do you write a "1" to the targeted bit while leaving the others untouched? Is that what the "|=" operator does?

 

For sure this is a change from the ATtiny84 that I'm used to. If you don't clear the int flag it never leaves the interrupt (or that's what it seems like is happening)

 

I trawled through the iotn3216.h for a while looking for a bit mask specifically for TCB INTFLAGS and didn't find anything.

 

I'm all ears if you have a better way! Thanks for the input.

Bill

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

Just looked through "TB3217-Getting-Started-with-TCA-90003217A"

 

They do use "TCA0.SINGLE.INTFLAGS = TCA_SINGLE_OVF_bm;"

 

So perhaps I should drop the "|" ?

Bill

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

The datasheet for that model isn't as explicit about "write a 1 to clear an int flag" as in traditional AVR8s.  It does imply the same action.  Experienced users of this model will need to confirm.

 

The result of the |= would be to clear all int flags in that register, as the RMW would write back one's that are set.

 

"Write a 1 to clear an int flag -- why?" is one of the oldest topics on this forum.

https://www.avrfreaks.net/forum/...

https://www.avrfreaks.net/forum/...

https://www.avrfreaks.net/forum/...

...

 

Now, for your model you must ignore the parts about int flags automatically cleared when the servicing ISR is entered.

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

>The datasheet for that model isn't as explicit about "write a 1 to clear an int flag" as in traditional AVR8s.

 

Its spelled out in the datasheet, and looks plain enough-

This bit is cleared by writing a '1' to it or when the Capture register is read in Capture mode.

 

With only a single bit in this particular intflags register, it makes no difference, but it will soon enough for other intflags registers so may as well do it correctly.

 

 

In addition to the datasheet, the header spells out what they use for the flag bit-

 

/* TCB.INTCTRL  bit masks and bit positions */
#define TCB_CAPT_bm  0x01  /* Capture or Timeout bit mask. */
#define TCB_CAPT_bp  0  /* Capture or Timeout bit position. */

 

/* TCB.INTFLAGS  bit masks and bit positions */
/* TCB_CAPT  is already defined. */

 

so you use-

 

TCB.INTFLAGS = TCB_CAPT_bm;

Last Edited: Sat. Dec 7, 2019 - 10:13 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

for sure good habits pay off.

 

Looks like you need to put the instance in there so:

 

 TCB0.INTFLAGS =  TCB_CAPT_bm;

 

Bill

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

>Looks like you need to put the instance in there

A mistake. I don't use these headers and I am prone to mistakes when using these verbose uppercase underscore things.

 

My idea of a good time in the coding department-

 

 

//#includes here

//mega4809 curiosity nano

 

Port<PF5, OUTL> led; //low is on
Tcb<Tcb0_Default> tcb; //tcb0, default pins (unused)
constexpr uint16_t blink_ms{ 1000_ms }; //blink rate

 

int main(){
    tcb.compare( Clkctrl::cpuSpeed()/100 - 1 ); //10ms period
    tcb.irqFunc(
        [](){
            static uint16_t count;
            tcb.irqClearFlag();
            if( ++count < blink_ms/2/10 ) return;
            led.toggle();
            count = 0;
        }
    );
    tcb.on();

    for(;;){}

 

    //or to simply blink led

    //for(;;){ Delay::wait( blink_ms/2 ); led.toggle(); }
}

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

curtvm wrote:

Its spelled out in the datasheet, and looks plain enough-

This bit is cleared by writing a '1' to it or when the Capture register is read in Capture mode.

What I meant was discussion of possible semi-hidden RMW effects.  Now, was that a discussion here, or really in the datasheets as I imagine? ;)  Gotta peek at a couple.  Perhaps I was just thinking of discussions here.

 

[edit] I only find what I was thinking of in the case of the "hidden" ADIF bit [the only flag bit in the control register].  So carry on here without me. ;)

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Last Edited: Sun. Dec 8, 2019 - 02:04 PM