Forum Menu




 


Log in Problems?
New User? Sign Up!
AVR Freaks Forum Index

Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Author Message
AdisK1
PostPosted: Jun 25, 2012 - 11:49 PM
Newbie


Joined: Jun 25, 2012
Posts: 9


New to AVR, migrated from PIC and love it so far!

Im am doing some tests with interrupts and cant get it to work. Im using attiny861a. When I debug, and step to the sei(); the I-bit won't set.

The code below is just some testings. The problem is as I can see in the debug is that global interrupts never sets.

Code:

/*
 * FadeLED.c
 *
 * Created: 2012-06-26 13:18:07
 *  Author: Adis
 */
#define F_CPU 5000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <inttypes.h>
#include <avr/interrupt.h>

#define SETBIT(ADDRESS,BIT)      (ADDRESS |= (1<<BIT))
#define CLEARBIT(ADDRESS,BIT)   (ADDRESS &= ~(1<<BIT))
#define CHECKBIT(ADDRESS,BIT)   (ADDRESS & (1<<BIT))

#define LED 0
#define POT   1   // ADC1
#define PWM_MIN 5
#define PWM_MAX 254

uint8_t   value   =   0;
uint8_t   step   =   1;

int main(void)
{
   sei();
   SP=RAMEND;
   DDRB   =   0b10111011;
   PORTB   =   0b00000100; // Button pullup
   
   // Init PWM
   SETBIT(TCCR1A,COM1A1);
   SETBIT(TCCR1A,PWM1A);
   
   CLEARBIT(TCCR1D,WGM10);
   CLEARBIT(TCCR1D,WGM11);
   
   CLEARBIT(TCCR1B,CS10);
   CLEARBIT(TCCR1B,CS11);
   CLEARBIT(TCCR1B,CS12);
   SETBIT(TCCR1B,CS13);
   
   TCNT1=0;
   OCR1A=0;
   
   // Init ADC
   
   // Select ADC1
   SETBIT(ADMUX,MUX0);
   
   // VCC as reference
   CLEARBIT(ADMUX,REFS0);
   CLEARBIT(ADMUX,REFS1);
   
   // Devider select
   SETBIT(ADCSRA,ADPS0);
   SETBIT(ADCSRA,ADPS1);
   
   // Left bit position
   SETBIT(ADMUX,ADLAR);
   
   // Enable ADC
   SETBIT(ADCSRA,ADEN);
   
   // Start ADC conversion
   SETBIT(ADCSRA,ADSC);
   
   
   // Init Interupt
   
   SETBIT(MCUCR,ISC01);   // Trig on rising edge
   SETBIT(MCUCR,ISC00);
   SETBIT(GIMSK,INT0);      // Enable interrupt on INT1
   
   
    while(1)
    {
        //OCR1A   =   value;
      asm("nop");
      //value = ADCH;
      //SETBIT(ADCSRA,ADSC);
    }
   
   return 0;
}

ISR(INT0_vect)
{
   cli();
   value   =   0;
   OCR1A   =   value;
   sei();
}


Im out of ideas Sad
 
 View user's profile Send private message  
Reply with quote Back to top
ka7ehk
PostPosted: Jun 26, 2012 - 12:08 AM
10k+ Postman


Joined: Nov 22, 2002
Posts: 12035
Location: Tangent, OR, USA

What happens if you keep stepping. The compiler may not put the SEI in exactly that spot.

Even better, single step with the disassembled code display turned on. Then, you will see exactly what is happening.

Jim

_________________
Jim Wagner
Oregon Research Electronics, Consulting Div.
Tangent, OR, USA

"The only thing standing between us and victory is defeat" P.G.Wodhouse in Wooster & Jeeves series
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Jun 26, 2012 - 09:19 AM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62227
Location: (using avr-gcc in) Finchingfield, Essex, England

Quote:

ISR(INT0_vect)
{
cli();
value = 0;
OCR1A = value;
sei();
}

The use of cli() and especially sei() here is a very bad one. When the AVR vectors to an interrupt the I bit in SREG is automatically cleared anyway and part of what you get for ISR() is a RETI rather than RET at the end. The difference being that at the last moment this sets the I bit in SREG again. So do not try to take control of I yourself.

I also fail to see what you are hoping this code to do and the purpose of 'value' at all - you set it to 0 then "OCR1A = value", you might as well just have used "OCR1A = 0".

If, however the commented bits suggest you are trying to share 'value' between the ISR and the main() code then you have made the classic error in using an optimising compiler. My signature below has FAQ#1 as the solution to your problem. This is based on the user manual that I'm guessing you haven't looked at where FAQ entry number 1 is also about this problem:

http://www.nongnu.org/avr-libc/user-manual/FAQ.html

To further explain the issue I then wrote this tutorial:

Optimisation and the importance of volatile in GCC

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
Koshchi
PostPosted: Jun 26, 2012 - 03:58 PM
10k+ Postman


Joined: Nov 17, 2004
Posts: 13815
Location: Vancouver, BC

And I would put the sei() at the end of your setup, not at the beginning.

_________________
Regards,
Steve A.

The Board helps those that help themselves.
 
 View user's profile Send private message  
Reply with quote Back to top
AdisK1
PostPosted: Jun 26, 2012 - 06:19 PM
Newbie


Joined: Jun 25, 2012
Posts: 9


ka7ehk, what do you mean with "disassembled code display"?
(Using AtmelStudio 6) Right now im stepping trough my code row by row in combination with IO view.

All the unoptimized things in the program is there because of learning.

Lets take this for example:
Code:



#define F_CPU 1000000UL
#include <avr/io.h>
#include <avr/interrupt.h>


int main(void)
{
   sei();
   
    while(1)
    {
       
      asm("nop");
      
    }
}


Still, the I-bit wont set. Why oh why! Crying or Very sad
 
 View user's profile Send private message  
Reply with quote Back to top
ka7ehk
PostPosted: Jun 26, 2012 - 06:31 PM
10k+ Postman


Joined: Nov 22, 2002
Posts: 12035
Location: Tangent, OR, USA

I'm not much of a Studio6 user, yet, so someone please explain to the OP how to view disassembled code?

The disassembled code display shows the actual machine instructions that are executed for each line of c-code, and you get to see it in the actual order that it is executed. It will often not be in the order that you expect. Though it ought to be close in the second example.

How are you determining that the I bit is NOT set?

As a side note, it is possible that the compiler has left it out of your second example because there are no interrupts.

Thanks
Jim

_________________
Jim Wagner
Oregon Research Electronics, Consulting Div.
Tangent, OR, USA

"The only thing standing between us and victory is defeat" P.G.Wodhouse in Wooster & Jeeves series
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Jun 26, 2012 - 06:33 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62227
Location: (using avr-gcc in) Finchingfield, Essex, England

Clearly this is a bug in the simulator. I built -O0 for t861A and then stepped the disasm viwe in the simulator and even as it crossed the SEI opcode the "Processor" view of the SREG flags did not show I being set.

I tried build/simulate for mega16 and the same thing happened (no update of SREG in Processor display).

So yup the simulator is FUBAR. Hopefully Atmel will be along in a minute to add this to their bug-tracker.

Quote:
I'm not much of a Studio6 user, yet, so someone please explain to the OP how to view disassembled code?
For the record it's very like AS4 - right click in the C display and use "Go to disassembly" (which has always been a misnomer when it's "mixed C and Asm view" in fact).

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
david.prentice
PostPosted: Jun 26, 2012 - 06:47 PM
10k+ Postman


Joined: Feb 12, 2005
Posts: 16267
Location: Wormshill, England

Well, I tried it for myself.

Sure enough, the I bit does not display.

You can get it to display by saying SREG |= 0x80;
But this seems a little convoluted.

Bear in mind you are leaving am MCU with a horrible architecture but reliable tools.
You now have a pleasant MCU with 'almost' tools. AS4 works quite well. AS6 is quite pleasant to use but has 'features'.

David.
 
 View user's profile Send private message Send e-mail  
Reply with quote Back to top
AdisK1
PostPosted: Jun 26, 2012 - 06:47 PM
Newbie


Joined: Jun 25, 2012
Posts: 9


It doesent matter witch device I choose. Tested with mega168 and the same problem. Thing is that when I program the tiny861, the INT0 pin hase non effect. So, there is something relly strange here.

ka7ehk, here you have some pics to see how it looks:
 
 View user's profile Send private message  
Reply with quote Back to top
david.prentice
PostPosted: Jun 26, 2012 - 07:00 PM
10k+ Postman


Joined: Feb 12, 2005
Posts: 16267
Location: Wormshill, England

You can click on the I bit. This should set / clear the bit in SREG.

However the SEI and CLI machine instructions are not reflected in SREG.

To be honest, I have simulated / jtagged several AS6 projects. Just never noticed the AS6 feature. i.e. it does the ISR() correctly. I never looked at the I bit.

David.
 
 View user's profile Send private message Send e-mail  
Reply with quote Back to top
clawson
PostPosted: Jun 26, 2012 - 08:07 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62227
Location: (using avr-gcc in) Finchingfield, Essex, England

Quote:

I never looked at the I bit.

But like UCSRC registers it's one of those "clutch at straws" things to worry about when the code otherwise isn't working. The fault is never that I wasn't set or that UCSRC isn't set to 8N1 but folks manage to confuse themselves (not helped by buggy simulators) and focus on the unimportant to the exclusion of what is.

I'll bet what we're really looking at here is an optimisation/volatile problem to explain an INT0 that "doesn't work" Wink

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
david.prentice
PostPosted: Jun 26, 2012 - 08:54 PM
10k+ Postman


Joined: Feb 12, 2005
Posts: 16267
Location: Wormshill, England

Guess what. Not only does SEI, CLI not get simulated, but RETI does not either !

Obviously I must have only used interrupts in AS6 with a hardware debugger.

You can enable interrupts by doing SREG |= 0x80 in every pass of your main loop.

Otherwise interrupts just stop after the first RETI.

I am tired. I presume that this 'feature' is well reported. OTOH, has Atmel got a workaround ?

David.

Edit. I had a look at Bugzilla and it appears that the Simulator is ok if you just don't step on a SEI.
 
 View user's profile Send private message Send e-mail  
Reply with quote Back to top
AdisK1
PostPosted: Jun 26, 2012 - 10:30 PM
Newbie


Joined: Jun 25, 2012
Posts: 9


For two days I was fighting with sei(); and it appears to be not my fault Smile
Good, them im doing it right!
 
 View user's profile Send private message  
Reply with quote Back to top
ka7ehk
PostPosted: Jun 27, 2012 - 12:58 AM
10k+ Postman


Joined: Nov 22, 2002
Posts: 12035
Location: Tangent, OR, USA

Does single-step debugging on live hardware do it correctly?

Jim

_________________
Jim Wagner
Oregon Research Electronics, Consulting Div.
Tangent, OR, USA

"The only thing standing between us and victory is defeat" P.G.Wodhouse in Wooster & Jeeves series
 
 View user's profile Send private message  
Reply with quote Back to top
david.prentice
PostPosted: Jun 27, 2012 - 07:58 AM
10k+ Postman


Joined: Feb 12, 2005
Posts: 16267
Location: Wormshill, England

Single stepping on real hardware works fine. After all it is reading SREG.

The Simulation is not the end of the world. All you have to do is avoid putting a breakpoint on the SEI instruction. e.g. put it on following instruction.

In practice this means don't single-step on a SEI. Most apps have a single sei() in the initialisation before the loop in main(). Interrupts remain enabled for the rest of the app. You very seldom single-step on a RETI instruction.

David.
 
 View user's profile Send private message Send e-mail  
Reply with quote Back to top
Display posts from previous:     
Jump to:  
All times are GMT + 1 Hour
Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Powered by PNphpBB2 © 2003-2006 The PNphpBB Group
Credits