AVR-USB on ATmega 162

General discussions about V-USB, our firmware-only implementation of a low speed USB device on Atmel's AVR microcontrollers
Post Reply
Stefan

AVR-USB on ATmega 162

Post by Stefan » Fri Jan 11, 2008 12:51 pm

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!

Stefan

Post by Stefan » Fri Jan 11, 2008 12:56 pm

I forgot to say what inputs I use for USB: PB2 USB-, PB3 for USB+

vobs
Posts: 5
Joined: Sun Jul 29, 2007 8:02 pm
Location: Stuttgart, Germany
Contact:

Post by vobs » Fri Jan 11, 2008 6:18 pm

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.

christian
Objective Development
Objective Development
Posts: 1443
Joined: Thu Nov 09, 2006 11:46 am

Post by christian » Sun Jan 13, 2008 7:14 pm

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.

Stefan

Post by Stefan » Mon Jan 14, 2008 11:36 am

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.

Stefan

Post by Stefan » Mon Jan 14, 2008 11:36 am

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.

christian
Objective Development
Objective Development
Posts: 1443
Joined: Thu Nov 09, 2006 11:46 am

Post by christian » Mon Jan 14, 2008 3:30 pm

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.

Stefan

Post by Stefan » Tue Jan 15, 2008 6:06 pm

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.

christian
Objective Development
Objective Development
Posts: 1443
Joined: Thu Nov 09, 2006 11:46 am

Post by christian » Wed Jan 16, 2008 1:34 pm

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.

Stefan_Guest

Post by Stefan_Guest » Thu Jan 24, 2008 12:37 pm

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

christian
Objective Development
Objective Development
Posts: 1443
Joined: Thu Nov 09, 2006 11:46 am

Post by christian » Thu Jan 24, 2008 2:31 pm

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.

Post Reply