Page 1 of 1

AVR-USB on ATmega 162

Posted: Fri Jan 11, 2008 12:51 pm
by Stefan
Hello,

I'm trying to port an application based on the AVR-USB from an ATtiny2312 to an ATmega162.

The AVR-USB without my custom code is running fine on the ATmega162.

But I have part in my code which sets the interrupt enable bit for Timer/Counter1.

TIMSK = _BV(OCIE1A);

With this bit set, the AVR-USB stops working, the device is no longer recognized by Windows.

I cannot see why this collides with the ATmega162. All is working fine on the ATtiny2312.

Any idea?

Thanks!

Posted: Fri Jan 11, 2008 12:56 pm
by Stefan
I forgot to say what inputs I use for USB: PB2 USB-, PB3 for USB+

Posted: Fri Jan 11, 2008 6:18 pm
by vobs
Stefan,
Stefan wrote:I forgot to say what inputs I use for USB: PB2 USB-, PB3 for USB+

are you sure, that you do not enable the 2nd UART's transmitter or receiver unit? As these use PB2 and PB3, this might be the true reason for your problem. I use AVR-USB on a Mega162 and it works fine, even when timer2 overflow interrupt is enabled.

Posted: Sun Jan 13, 2008 7:14 pm
by christian
Does the interrupt handler routine set the global interrupt enable flag as its first instruction? If not and the interrupt rate is high, this could interfere with the USB interrupt.

Posted: Mon Jan 14, 2008 11:36 am
by Stefan
Hi vobs, christian,

I'm quite sure that I did not enable the UARTS. Anyway, I tried a different port for the USB wires (PA0, PA1), still no luck.

sei(), which enables the global interrupts is first called in the main() function and then in the SIG_TIMER1_COMPA() interrupt handler.

At the moment, only the sei() instruction is called in this interrupt handler.

Posted: Mon Jan 14, 2008 11:36 am
by Stefan
Hi vobs, christian,

I'm quite sure that I did not enable the UARTS. Anyway, I tried a different port for the USB wires (PA0, PA1), still no luck.

sei(), which enables the global interrupts is first called in the main() function and then in the SIG_TIMER1_COMPA() interrupt handler.

At the moment, only the sei() instruction is called in this interrupt handler.

Posted: Mon Jan 14, 2008 3:30 pm
by christian
It's not sufficient to put your own sei() into the interrupt handler, you must declare it with __attribute__ ((interrupt)) so that gcc emits an sei() as the first instruction.

Other than that: Did you make sure that D+ triggers an interrupt and that the interrupt line is an input with internal pull-up disabled? And did you ensure that your D+ and D- pins are configured as inputs without internal pull-up?

Then there are the obvious things like fuse values, system clock divider etc. to make sure that the AVR runs on the desired crystal clock.

Posted: Tue Jan 15, 2008 6:06 pm
by Stefan
Other than that: Did you make sure that D+ triggers an interrupt and that the interrupt line is an input with internal pull-up disabled? And did you ensure that your D+ and D- pins are configured as inputs without internal pull-up?

Then there are the obvious things like fuse values, system clock divider etc. to make sure that the AVR runs on the desired crystal clock.


This is all ok, because USB is working fine if I do not set the interrupt enable bit with

TIMSK = _BV(OCIE1A);

USB does not work only if this bit is set.

I have now checked the behavior on an ATmega8, it is all the same.

Everything is working on the ATtiny2313, it fails only on the ATmega162 /8.

I have ordered an AVR Dragon for debuging. I hope that I will get it tomorrow.

Posted: Wed Jan 16, 2008 1:34 pm
by christian
OK, then this MUST be a problem with the interrupt routine. There are two possible causes: Either you enable an interrupt and define a service routine for another interrupt so that it jumps into nirvana when the interrupt occurs, or the interrupt rate is way too high and uses up all CPU time.

Posted: Thu Jan 24, 2008 12:37 pm
by Stefan_Guest
Hi all,

I have got now the AVR Dragon for debugging, but still no luck.

Here is what I see and what I have verified:

- the basic USB functionality is working if I don't use the Timer/Counter1
- if I enable TImer/Counter1, the USB stops working. (message: connected device is not ok...)
- the program does not hang, if I stop the program, it holds at different positions in the code (usb_poll)
- I have implemented the following ISR: SIG_INPUT_CAPTURE1 and SIG_TIMER1_COMPA
- both are ok, they are called if they should, this is verified

Here is how I enable the TImer and the output compare units:

TCCR1B = _BV(ICNC1) // noise canceler, trigger on negative edge
| _BV(CS11); // clock source clk/8
TIMSK = _BV(OCIE1A) // output compare 1A match interrupt enable
| _BV(TICIE1); // input capture 1 interrupt enable

Does the USB stack use a Timer or something else which could interfere with my settings?

Any other idea, what I could check? As I said, I can use a AVR dragon for debugging.

Many thanks!
Stefan

Posted: Thu Jan 24, 2008 2:31 pm
by christian
The logical conclusion would be that there is something in your interrupt handler which affects AVR-USB.

You DID declare your interrupt handler with __attribute__ ((interrupt)), right? And there is no cli() in the interrupt handler or any other code which runs only if the interrupt occurs?

To analyze this, can you replace the interrupt handlers with an empty function and check whether USB works in this case? If it does, go back to the original code for one of them, then the other to find out which caused the problem. If you nailed down one particular interrupt handler, start with an empty function and add more and more of the desired code until you know which change causes the problem.