ATMega2560 register SREG not defined?

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

Hi,

I tried create the simple project to Atmel Studio 7:

 


#include <avr/io.h>

int main(void)
{
	unsigned char sreg=SREG;
	SREG=3;
	
	DDRD=0;
	
    /* Replace with your application code */
    while (1) 
    {
    }
}

and I have the "warning" (see screenshot)

"Goto Implimentation" not working for SREG.

I can't finde where macros SREG definded.

But compile have successful.

What is incorrect?

This topic has a solution.
Last Edited: Sun. Jan 8, 2017 - 04:13 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The source browsing is done by Visual Assist. Clearly it failed on this nested macro. 

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

Does this frequently-recurring issue need to be made into a "Sticky" ... ?

 

eg, only 4 days ago: http://www.avrfreaks.net/comment...

 

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

clawson wrote:

The source browsing is done by Visual Assist. Clearly it failed on this nested macro. 

I tried find the SREG to header files. And headers similar  iomxx0_1.h not consist macros SREG.

Now, the Atmel not show "warning" for SREG.

I hardly found, that the macros SREG describe to common.h header file.

intricate approach, it hinders the development.

 

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

Kazakov please choose a more suitable avatar, current one removed. We love all kind of political views as long as the keepers keep it to themselves and not here.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

Kazakov wrote:
intricate approach
But necessary I'm afraid so that a "common" header can be used for all the different AVR architectures. (there are at least 17). I've seen this before - Visual Assist does not seem able to parse conditional preprocessor macros.

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

Kazakov wrote:
intricate approach, it hinders the development.

Again, there's nothing wrong with the approach itself - it's a problem with the tools not properly handling it.

 

The alternative would be that you would have to #include exactly the correct header for the specific chip you're using.

 

Then people would moan that's too finicky - "why can't we just have one 'common' header which can be used for all the different AVR architectures?"

 

So Atmel can't win!

 

Last Edited: Mon. Jan 9, 2017 - 10:03 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:
So Atmel can't win!
Nothing to do with Atmel really.

 

common.h is a component of AVR-LibC which was created by the original developers of avr-gcc/AVR-LibC, nothing to do with Atmel.

(though it's true that these days some of the ongoing development of avr-gcc/AVR-LibC is now done by Atmel engineers too).

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

Hi
So, i think i'm having the same problems to program an atmega2560 (the arduino mega). I'm trying to configure the registers and create my own library, but when

i compile it there are messages indicating that the registers were not defined, and things like that. More precisely, the messages are like "error expected '' before '' token",

but i think is because that.
 

So, i think it's the same problem.
But what i want to know is how do I fix this?
Because, it seems you guys didn't show any solution.
What i understand is that maybe i should add some specific library? But if yes, which one?
 

Well, just to clarify, the problems are showed to compile this code:
ISR(TIMER1_COMPA_vect);
TCCR1B |= (1<<WGM13)|(1<<WGM12);

But at the beginning i've tried the compilation in the arduino IDE and the problem was only with "ISR(TIMER1_COMPA_vect);". Then i've started to use Eclipse

IDE with win avr, and now both don't work.

Sorry to bother, but i'm a bit newbie and don't have a deep understanding in these error messages and compilers theory. Moreover, actually i don't speak

english very well, so maybe there are some misundertandings too.
 

Thank you for any help.
Bye

Last Edited: Thu. Jan 12, 2017 - 04:25 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No idea what you are talking about:

$ cat avr.c
#include <avr/io.h>

ISR(TIMER1_COMPA_vect) {
    TCCR1B |= (1<<WGM13)|(1<<WGM12);
}

int main(void) {
    while(1);
}
$ avr-gcc -mmcu=atmega2560 -Os avr.c -o avr.elf
$

As you can see that test builds without any sign of an error. What happens when you try to build it?

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

Ok, my mistake.

The sentence:
"TCCR1B |= (1<<WGM13)|(1<<WGM12);"
It's fine.

 

But both in arduino IDE and eclipse this code:
ISR(TIMER1_COMPA_vect | TIMER1_COMPB_vect)
{
    cli();
    OCR1A = (int)((dutyCycle/100)*icr_value));
    sei();
}
Doesn't work

 

I'm getting this message referred to the first line:
expected '=', ',', ';', 'asm' or '__attribute__' before '|' token
Do you know what problem would be?

 

Thanks

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

Please post a "complete" small test program that demos the problem, we can not tell from the snippet of code where the problem is.

It looks like some thing is missing, like a ";" or "}" on the previous line, a complete program is needed to help you find the problem.

 

 

Jim

 

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

.. you can't OR vector names together (and, why is the sei and cli there?)

:: Morten

 

(yes, I work for Atmel, yes, I do this in my spare time, now stop sending PMs)

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

I  don't think that you can have a single ISR for two interrupts: ISR(TIMER1_COMPA_vect | TIMER1_COMPB_vect)

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

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

Ohh, sorry, didn't know about that, anyway ...

 

The full .c file is:

#include <avr/io.h>
#include <inttypes.h>
#include <avr/interrupt.h>

double dutyCycle;
int icr_value;

void timer1_init1(double dutyCycle1, int icr_value1) //fast-pwm
{
    DDRB |= (1 << PORTB5);

    TCCR1B |= (1<<WGM13)|(1<<WGM12);
    TCCR1A |= (1<<WGM11);
    TCCR1A |= (1<<COM1A1)|(1<<COM1A0);
    TIMSK1 |= (1<<OCIE1A)|(1<<OCIE1B);

    OCR1A = ICR1 - (int)((dutyCycle1/100)*icr_value1);

    ICR1 = icr_value;
    TCCR1B |= (1<<CS10);
}

 

ISR(TIMER1_COMPA_vect | TIMER1_COMPB_vect)
{
    cli();
    OCR1A = (int)((dutyCycle/100)*icr_value));
    sei();
}

with an associated .h file:

#ifndef PWM_BIBL1_H_INCLUDED
#define PWM_BIBL1_H_INCLUDED

 

void timer1_init1(double dutyCycle1, int icr_value1);
ISR(TIMER1_COMPA_vect | TIMER1_COMPB_vect);

 

#endif // PWM_BIBL1_H_INCLUDED

 

Well, i'll try to follow your hints

Sorry for bothering, and thanks again!

Bye

Last Edited: Thu. Jan 12, 2017 - 06:04 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What is that second line about the ISR (in the ifndef block)? There should only be one reference to an ISR, and that is its definition. Other modules do not have to know anything about that ISR.

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

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

Yes, remove it from the header file.

:: Morten

 

(yes, I work for Atmel, yes, I do this in my spare time, now stop sending PMs)

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

As other have said sei()/cli() almost never appear within an ISR(). The fact is that the AVR design is such that when it starts to make a vector jump to an ISR() the I flag in SREG is cleared (effectively CLI) during the process and the end of the ISR at the } causes the code to be RETI rather than just RET as for a normal C function. Indeed that is part of what is "special" about the use of ISR().

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

ka7ehk wrote:
I  don't think that you can have a single ISR for two interrupts

Well, in principle, you could have two vector locations that both point to the same service routine.

 

But, as Morten noted, you can't just OR the vectors together! They aren't bitmaps!

 

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

:: Morten

 

(yes, I work for Atmel, yes, I do this in my spare time, now stop sending PMs)

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

Here's a rather off the wall, left-field idea.. how about the USER MANUAL:

 

http://www.nongnu.org/avr-libc/u...

 

Don't know about anyone else but it seems to me that ISR_ALIAS() thing might be a bit of an idea of using the same handler for two vectors ;-)

 

Now given the code above:

ISR(TIMER1_COMPA_vect | TIMER1_COMPB_vect)
{
    cli();
    OCR1A = (int)((dutyCycle/100)*icr_value));
    sei();
}

I was going to present a suggested implementation using ISR_ALIAS(). The only thing is that when you look at that (and ditch the pointless cli() and sei()) all you are left with is:

ISR(TIMER1_COMPA_vect | TIMER1_COMPB_vect)
{
    OCR1A = (int)((dutyCycle/100)*icr_value));
}

Now is it really the intention that both the COMPA and the COMPB vector both set OCR1A ? I cannot help thinking that the intention here is really:

ISR(TIMER1_COMPA_vect)
{
    OCR1A = (int)((dutyCycle/100)*icr_value));
}

ISR(TIMER1_COMPB_vect)
{
    OCR1B = (int)((dutyCycle/100)*icr_value));
}

in which case I cannot see a way to implement that with anything but two separate ISR()s.

 

But if the intention really is that both interrupts act on OCR1A I guess the syntax is:

ISR(TIMER1_COMPA_vect)
{
    OCR1A = (int)((dutyCycle/100)*icr_value));
}

ISR_ALIAS(TIMER1_COMPB_vect, TIMER1_COMPA_vect);

If using GCC 4.2+ then there is also:

ISR(TIMER1_COMPA_vect)
{
    OCR1A = (int)((dutyCycle/100)*icr_value));
}

ISR(TIMER1_COMPB_vect, ISR_ALIASOF(TIMER1_COMPA_vect));

(at least I think that's what the manual is implying for the syntax - but I'd just go with ISR_ALIAS() I think.

 

(actually if you want an example of ISR_ALIASOF I can almost guarantee that Dean will have used it somewhere in his code!!)

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

OK, because the manual says ISR_ALIAS() is deprecated and ISR_ALIASOF() should be preferred I persevered with an example:

$ cat avr.c
#include <avr/io.h>
#include <avr/interrupt.h>

ISR(TIMER1_COMPA_vect) {
    PORTB = 0x55;
}

ISR(TIMER1_COMPB_vect, ISR_ALIASOF(TIMER1_COMPA_vect));

int main(void) {
    while(1);
}
$ avr-gcc -save-temps -Os -mmcu=atmega16 avr.c -o avr.elf
$ avr-objdump -S avr.elf

avr.elf:     file format elf32-avr


Disassembly of section .text:

00000000 <__vectors>:
   0:	0c 94 2a 00 	jmp	0x54	; 0x54 <__ctors_end>
   4:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
   8:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
   c:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  10:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  14:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  18:	0c 94 36 00 	jmp	0x6c	; 0x6c <__vector_6>
  1c:	0c 94 36 00 	jmp	0x6c	; 0x6c <__vector_6>
  20:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  24:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  28:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  2c:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  30:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  34:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  38:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  3c:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  40:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  44:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  48:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  4c:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>
  50:	0c 94 34 00 	jmp	0x68	; 0x68 <__bad_interrupt>

00000054 <__ctors_end>:
  54:	11 24       	eor	r1, r1
  56:	1f be       	out	0x3f, r1	; 63
  58:	cf e5       	ldi	r28, 0x5F	; 95
  5a:	d4 e0       	ldi	r29, 0x04	; 4
  5c:	de bf       	out	0x3e, r29	; 62
  5e:	cd bf       	out	0x3d, r28	; 61
  60:	0e 94 44 00 	call	0x88	; 0x88 <main>
  64:	0c 94 45 00 	jmp	0x8a	; 0x8a <_exit>

00000068 <__bad_interrupt>:
  68:	0c 94 00 00 	jmp	0	; 0x0 <__vectors>

0000006c <__vector_6>:
  6c:	1f 92       	push	r1
  6e:	0f 92       	push	r0
  70:	0f b6       	in	r0, 0x3f	; 63
  72:	0f 92       	push	r0
  74:	11 24       	eor	r1, r1
  76:	8f 93       	push	r24
  78:	85 e5       	ldi	r24, 0x55	; 85
  7a:	88 bb       	out	0x18, r24	; 24
  7c:	8f 91       	pop	r24
  7e:	0f 90       	pop	r0
  80:	0f be       	out	0x3f, r0	; 63
  82:	0f 90       	pop	r0
  84:	1f 90       	pop	r1
  86:	18 95       	reti

00000088 <main>:
  88:	ff cf       	rjmp	.-2      	; 0x88 <main>

0000008a <_exit>:
  8a:	f8 94       	cli

0000008c <__stop_program>:
  8c:	ff cf       	rjmp	.-2      	; 0x8c <__stop_program>

Certainly seems to have worked. Only code for __vector_6 (the COMPA) and both vectors 6 and 7 have a jump to that code.

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

Hi, thanks for more explanations and other hints.
I think some of it really helps me to clarify some points.
I'll try to use the vectors in different calls.
See you!

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

clawson wrote:
I cannot see a way to implement that with anything but two separate ISR()s.

Maybe what the OP is worried about is the repeated expression

 

(int)((dutyCycle/100)*icr_value));

 

Which could be addressed with a #define or an inline function ...

 

And how far from the original topic - ATMega2560 register SREG not defined - are we now?!