| Author |
Message |
|
|
Posted: Jun 25, 2012 - 11:49 PM |
|

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  |
|
|
| |
|
|
|
|
|
Posted: Jun 26, 2012 - 12:08 AM |
|


Joined: Nov 22, 2002
Posts: 12197
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
|
| |
|
|
|
|
|
Posted: Jun 26, 2012 - 09:19 AM |
|


Joined: Jul 18, 2005
Posts: 62944
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 |
_________________
|
| |
|
|
|
|
|
Posted: Jun 26, 2012 - 03:58 PM |
|

Joined: Nov 17, 2004
Posts: 13960
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.
|
| |
|
|
|
|
|
Posted: Jun 26, 2012 - 06:19 PM |
|

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!  |
|
|
| |
|
|
|
|
|
Posted: Jun 26, 2012 - 06:31 PM |
|


Joined: Nov 22, 2002
Posts: 12197
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
|
| |
|
|
|
|
|
Posted: Jun 26, 2012 - 06:33 PM |
|


Joined: Jul 18, 2005
Posts: 62944
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). |
_________________
|
| |
|
|
|
|
|
Posted: Jun 26, 2012 - 06:47 PM |
|

Joined: Feb 12, 2005
Posts: 16547
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. |
|
|
| |
|
|
|
|
|
Posted: Jun 26, 2012 - 06:47 PM |
|

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: |
|
|
| |
|
|
|
|
|
Posted: Jun 26, 2012 - 07:00 PM |
|

Joined: Feb 12, 2005
Posts: 16547
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. |
|
|
| |
|
|
|
|
|
Posted: Jun 26, 2012 - 08:07 PM |
|


Joined: Jul 18, 2005
Posts: 62944
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"  |
_________________
|
| |
|
|
|
|
|
Posted: Jun 26, 2012 - 08:54 PM |
|

Joined: Feb 12, 2005
Posts: 16547
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. |
|
|
| |
|
|
|
|
|
Posted: Jun 26, 2012 - 10:30 PM |
|

Joined: Jun 25, 2012
Posts: 9
|
|
For two days I was fighting with sei(); and it appears to be not my fault
Good, them im doing it right! |
|
|
| |
|
|
|
|
|
Posted: Jun 27, 2012 - 12:58 AM |
|


Joined: Nov 22, 2002
Posts: 12197
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
|
| |
|
|
|
|
|
Posted: Jun 27, 2012 - 07:58 AM |
|

Joined: Feb 12, 2005
Posts: 16547
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. |
|
|
| |
|
|
|
|
|