Problems with HIDkeys on atmega32 @WinXP
Problems with HIDkeys on atmega32 @WinXP
Hi there,
I'm trying to get the HIDkeys project running on an atmega32, but the device doesn't gets recognized by the pc (running with WinXP SP2):
if I connect the the device, the USB logo shows up as a system tray icon near to the system clock. A few seconds later, this icon disappears, just to show up again after some seconds.
This process repeats over and over again. Tools like usbview or snoopypro seem not to be able to log what's going on during this startup phase, so I'm happy for every hint...
I've ensured that the uC is running with external clock, Zener-diodes have been connected to the D-lines (during startup I have 3,2V at D+ and 0V at D-)
I'm trying to get the HIDkeys project running on an atmega32, but the device doesn't gets recognized by the pc (running with WinXP SP2):
if I connect the the device, the USB logo shows up as a system tray icon near to the system clock. A few seconds later, this icon disappears, just to show up again after some seconds.
This process repeats over and over again. Tools like usbview or snoopypro seem not to be able to log what's going on during this startup phase, so I'm happy for every hint...
I've ensured that the uC is running with external clock, Zener-diodes have been connected to the D-lines (during startup I have 3,2V at D+ and 0V at D-)
When I plug the device to my Linux box, I get following messages:
Does anybody knows what error -71 means?
usb 1-1.1: new low speed USB device using uhci_hcd and address 4
usb 1-1.1: device descriptor read/64, error -71
usb 1-1.1: device descriptor read/64, error -71
usb 1-1.1: new low speed USB device using uhci_hcd and address 5
usb 1-1.1: device descriptor read/64, error -71
usb 1-1.1: device descriptor read/64, error -71
usb 1-1.1: new low speed USB device using uhci_hcd and address ...
Does anybody knows what error -71 means?
Hi,
I checked everything again this morning and found another wiring problem. After fixing this, the device gets recognized by windows, but not in the expected way:
I try to get this running on my evaluation board, which means I have lots of wires connected -> is the length of the wires of the D-lines critical (at the moment they are ~10cm long)?
I checked everything again this morning and found another wiring problem. After fixing this, the device gets recognized by windows, but not in the expected way:
- - In the device manager, it's still shown as 'unknown device' in the category 'usb-controller'
- Sometimes, there's a yellow exclamation mark, sometimes not
- In all cases, usbview says 'DeviceFailedEnumeration'
- In all cases, snoopypro isn't able to log any communication with the device
- Although I enabled the debugging interface (-DDEBUG_LEVEL=2), I get no response from the device => which settings have to be made for Hyperterminal?
I try to get this running on my evaluation board, which means I have lots of wires connected -> is the length of the wires of the D-lines critical (at the moment they are ~10cm long)?
Christian,
I've stripped the main routine down so that it only contains the functionality which is needed to establish communication.
In my understanding, the following code should be sufficient to get the device properly recognized by windows:
The device still gets detected as 'unknown device'
As I already wrote, I'm using the Atmega32 instead of Atmega8 - all I did change was the makefile (MCU=atmega8 to MCU=atmega32).
Because D- is connected to PD0 (pin 14) and D+ is connected to PD2 (pin 16) I didn't have to change anything in usbconfig.h -- is that right?
Are there any other places where the microcontroller is considered?
Are there any other methods how to verify that the usb-stack works fine?
I know, these are many annoying questions, but I want to get this thing running. Other users don't seem to run into those problems so I assume that I'm doing something very wrong
I've stripped the main routine down so that it only contains the functionality which is needed to establish communication.
In my understanding, the following code should be sufficient to get the device properly recognized by windows:
Code: Select all
int main(void)
{
wdt_enable(WDTO_2S);
hardwareInit();
usbInit();
sei();
for(;;){ /* main event loop */
wdt_reset();
usbPoll();
}
return 0;
}
The device still gets detected as 'unknown device'
As I already wrote, I'm using the Atmega32 instead of Atmega8 - all I did change was the makefile (MCU=atmega8 to MCU=atmega32).
Because D- is connected to PD0 (pin 14) and D+ is connected to PD2 (pin 16) I didn't have to change anything in usbconfig.h -- is that right?
Are there any other places where the microcontroller is considered?
Are there any other methods how to verify that the usb-stack works fine?
I know, these are many annoying questions, but I want to get this thing running. Other users don't seem to run into those problems so I assume that I'm doing something very wrong
If the device fails enumeration, USB does not work (probably not at all). You get a "not recognized" even if you only connect the 1.5k pull-up resistor.
The ATMega32 should work without any changes, at least at the first glance. I have never used this chip myself, though. It definitely needs other fuse values than the ATMega8. What fuse values do you use?
If you don't see any debug output when debugging is enabled, the bit rate may be wrong. This would be a strong hint that you run the MCU from the internal RC oscillator instead of the crystal.
The ATMega32 should work without any changes, at least at the first glance. I have never used this chip myself, though. It definitely needs other fuse values than the ATMega8. What fuse values do you use?
If you don't see any debug output when debugging is enabled, the bit rate may be wrong. This would be a strong hint that you run the MCU from the internal RC oscillator instead of the crystal.
The ATMega32 should work without any changes, at least at the first glance. I have never used this chip myself, though. It definitely needs other fuse values than the ATMega8. What fuse values do you use?
The lfuse is programmed to 0x9F, the hfuse to 0x09 -- these are the same settings as on the atmega8, the only difference is that the jtag-interface of the atmega32 is enabled (JTAGEN=0, OCDEN=0).
I compared the suggestions in the makefile with the settings I made to the atmega32 with the help of the 'AVR Fuse Calculator' (http://palmavr.sourceforge.net/cgi-bin/fc.cgi?P_PREV=ATmega32) just to prevent errors from wrong fuses.
If you don't see any debug output when debugging is enabled, the bit rate may be wrong. This would be a strong hint that you run the MCU from the internal RC oscillator instead of the crystal.
I've ensured that the micro is running on crystal clock the following way: I toggle a LED if timer1 overflows. timer1 is configured in that way, that the LED should toggle with a period of 1s (extClk=12MHz, prescaler=256 countvalue=46875 ==> period=1s) -- this works.
If the system would run on internal oscillator (1MHz) the LED would toggle about every 12s.
I know, this isn't a very exact method, but it's sufficient to prove the micro is running with the right clock.
Anyway, what are the settings I have to make in Hyperterminal to see any messages from the device (Baudrate, Datab bits, Parity, Stopp bits, Flow control)?
Regards,
Oliver
OK, so let's assume that the fuse values are correct.
The debug output is at 19200 bps by default. Since only the TxD pin is used, there is no flow control. I don't know what settings you need for Hyperterminal, though, if you just want to receive data. If you interface to a PC, you need an inverter (and in principle you need a level converter) because RS232 operates with inverted +/- 12 V levels.
If you add
DBG1(0x00, 0, 0);
to your main() after odDebugInit(), you should at least see this "00" output after startup. Otherwise the driver should print USB Reset ("ff") and received and transmitted packets.
The debug output is at 19200 bps by default. Since only the TxD pin is used, there is no flow control. I don't know what settings you need for Hyperterminal, though, if you just want to receive data. If you interface to a PC, you need an inverter (and in principle you need a level converter) because RS232 operates with inverted +/- 12 V levels.
If you add
DBG1(0x00, 0, 0);
to your main() after odDebugInit(), you should at least see this "00" output after startup. Otherwise the driver should print USB Reset ("ff") and received and transmitted packets.
Finaly I was able to log some data via uart: after plug-in of the device, I receive 1 time "00" (1st message) and 15 times "ff" -- that's all. I guess, this isn't a good sign
Next, I will test if port D works as expected on my ATmega32 - maybe the micro itself has some errors....
Anyway, is there any point where I can start to debug the usb-stack? Is there a point which is crucial for establishing a communication via USB? I have plenty of LEDs to connect and a JTAG debugger to dig into the code
Next, I will test if port D works as expected on my ATmega32 - maybe the micro itself has some errors....
Anyway, is there any point where I can start to debug the usb-stack? Is there a point which is crucial for establishing a communication via USB? I have plenty of LEDs to connect and a JTAG debugger to dig into the code
christian wrote:Did you check the disassembler output to see whether the interrupt table has been compiled correctly?
Can you please give me a hint where I have to look and what it should look like?
christian wrote:And did you try a different interrupt?
I tried INT1 instead of INT0 - I connected D+ to INT1 (pin 17) and made following modifications to the code.
in main.c (hardwareInit()):
Code: Select all
PORTD = 0xf6; /* 1111 0110 bin: activate pull-ups except on USB lines */
DDRD = 0x0b; /* 0000 1011 bin: all pins input except USB (-> USB reset) */
j = 0;
while(--j){ /* USB Reset by device only required on Watchdog Reset */
i = 0;
while(--i); /* delay >10ms for USB reset */
}
DDRD = 0x02; /* 0000 0010 bin: remove USB reset condition */
in usbconfig.h:
Code: Select all
#define USB_INTR_CFG_SET ((1 << ISC10) | (1 << ISC11))
#define USB_INTR_ENABLE_BIT INT1
#define USB_INTR_PENDING_BIT INTF1
Now I get absolutely no reaction on the PC if I connect the device to it - is there any other section I have to modify if I want to use INT1?
Here are the latest results (there's still no change ):
The interrupttable looks good for INT0 and INT1:
INT0:
INT1:
If I'm using INT1 instead of INT0 the device still reacts in the same way. I also tried different configurations (D+ connected to INT0 and nothing else, D+ connected to INT0 and PD2) and different versions of the usb stack (2007/03/29 and 2007/12/01) - nothing helped.
It's interesting to see that if I'm using the old usb-stack, I always get the 'toggling behaviour' I described in my very first topic.
Now I assume that the problem is coupled to my evaluation board: yesterday I found out that INT0 is very sensitive to any changes. It is sufficient enough to touch the isolated wires on the backside of the circuit board with my finger to trigger the interrupt service routine if no pull-up resistor is connected.
I ordered some new parts and I will build another evaluation board with short lines especially dedicated for testing this usb-stuff.
If you have another idea where to look please let me know.
Lastly, I activated some more compiler-warnings and got some interesting response:
I'm concerned about the warning "passing argument x of 'XYZ' with different width due to prototype" -> I didn't investigate this further but from my experience this point will create problems sooner or later; what do you think about it?
Oh, one last point: which version of winAVR are you using? Maybe this is the reason for all my problems.
I'm currently using winAVR build 20070525
Thanks for your help so far -- have a nice weekend and a happy new year!
Regards,
Oliver
The interrupttable looks good for INT0 and INT1:
INT0:
Code: Select all
Disassembly of section .text:
00000000 <__vectors>:
0: 0c 94 7f 00 jmp 0xfe ; 0xfe <__ctors_end>
4: 0c 94 f6 02 jmp 0x5ec ; 0x5ec <__vector_1>
8: 0c 94 9c 00 jmp 0x138 ; 0x138 <__bad_interrupt>
c: 0c 94 9c 00 jmp 0x138 ; 0x138 <__bad_interrupt>
...
INT1:
Code: Select all
Disassembly of section .text:
00000000 <__vectors>:
0: 0c 94 7f 00 jmp 0xfe ; 0xfe <__ctors_end>
4: 0c 94 9c 00 jmp 0x138 ; 0x138 <__bad_interrupt>
8: 0c 94 f6 02 jmp 0x5ec ; 0x5ec <__vector_2>
c: 0c 94 9c 00 jmp 0x138 ; 0x138 <__bad_interrupt>
...
And did you try a different interrupt?
If I'm using INT1 instead of INT0 the device still reacts in the same way. I also tried different configurations (D+ connected to INT0 and nothing else, D+ connected to INT0 and PD2) and different versions of the usb stack (2007/03/29 and 2007/12/01) - nothing helped.
It's interesting to see that if I'm using the old usb-stack, I always get the 'toggling behaviour' I described in my very first topic.
Now I assume that the problem is coupled to my evaluation board: yesterday I found out that INT0 is very sensitive to any changes. It is sufficient enough to touch the isolated wires on the backside of the circuit board with my finger to trigger the interrupt service routine if no pull-up resistor is connected.
I ordered some new parts and I will build another evaluation board with short lines especially dedicated for testing this usb-stuff.
If you have another idea where to look please let me know.
Lastly, I activated some more compiler-warnings and got some interesting response:
Code: Select all
usbdrv/usbdrv.c: In function 'usbSetInterrupt':
usbdrv/usbdrv.c:232: warning: passing argument 2 of 'usbCrc16Append' with different width due to prototype
usbdrv/usbdrv.c:234: warning: passing argument 1 of 'odDebug' with different width due to prototype
usbdrv/usbdrv.c:234: warning: passing argument 3 of 'odDebug' with different width due to prototype
usbdrv/usbdrv.c: In function 'usbProcessRx':
usbdrv/usbdrv.c:321: warning: passing argument 1 of 'odDebug' with different width due to prototype
usbdrv/usbdrv.c:321: warning: passing argument 3 of 'odDebug' with different width due to prototype
usbdrv/usbdrv.c: In function 'usbBuildTxBlock':
usbdrv/usbdrv.c:470: warning: passing argument 2 of 'usbRead' with different width due to prototype
usbdrv/usbdrv.c:472: warning: passing argument 2 of 'usbCrc16Append' with different width due to prototype
usbdrv/usbdrv.c:482: warning: passing argument 1 of 'odDebug' with different width due to prototype
usbdrv/usbdrv.c:482: warning: passing argument 3 of 'odDebug' with different width due to prototype
usbdrv/usbdrv.c: In function 'usbPoll':
usbdrv/usbdrv.c:511: warning: passing argument 2 of 'usbProcessRx' with different width due to prototype
usbdrv/usbdrv.c:537: warning: passing argument 1 of 'odDebug' with different width due to prototype
usbdrv/usbdrv.c:537: warning: passing argument 3 of 'odDebug' with different width due to prototype
usbdrv/oddebug.c: In function 'printHex':
usbdrv/oddebug.c:34: warning: passing argument 1 of 'hexAscii' with different width due to prototype
usbdrv/oddebug.c:34: warning: passing argument 1 of 'uartPutc' with different width due to prototype
usbdrv/oddebug.c:35: warning: passing argument 1 of 'hexAscii' with different width due to prototype
usbdrv/oddebug.c:35: warning: passing argument 1 of 'uartPutc' with different width due to prototype
usbdrv/oddebug.c: In function 'odDebug':
usbdrv/oddebug.c:40: warning: passing argument 1 of 'printHex' with different width due to prototype
usbdrv/oddebug.c:41: warning: passing argument 1 of 'uartPutc' with different width due to prototype
usbdrv/oddebug.c:43: warning: passing argument 1 of 'uartPutc' with different width due to prototype
usbdrv/oddebug.c:44: warning: passing argument 1 of 'printHex' with different width due to prototype
usbdrv/oddebug.c:46: warning: passing argument 1 of 'uartPutc' with different width due to prototype
usbdrv/oddebug.c:47: warning: passing argument 1 of 'uartPutc' with different width due to prototype
main.c: In function 'usbFunctionSetup':
main.c:240: warning: passing argument 1 of 'buildReport' with different width due to prototype
main.c: In function 'main':
main.c:268: warning: passing argument 1 of 'odDebug' with different width due to prototype
main.c:268: warning: passing argument 3 of 'odDebug' with different width due to prototype
main.c:294: warning: passing argument 1 of 'buildReport' with different width due to prototype
main.c:295: warning: passing argument 2 of 'usbSetInterrupt' with different width due to prototype
I'm concerned about the warning "passing argument x of 'XYZ' with different width due to prototype" -> I didn't investigate this further but from my experience this point will create problems sooner or later; what do you think about it?
Oh, one last point: which version of winAVR are you using? Maybe this is the reason for all my problems.
I'm currently using winAVR build 20070525
Thanks for your help so far -- have a nice weekend and a happy new year!
Regards,
Oliver
I'm beginning to mix up threads. My reply should have gone to another thread where USB works when connected to INT0 but not with any other interrupt.
If I remember correctly, it does not work regardless of the interrupt in your case.
If the interrupt pin is "open", then it's normal that it is very sensitive to touching or other changes. But it should be connected to D+ anyway.
The warnings are OK. This means that the data type had to be converted for a function call. I'm NOT using WinAVR because I have a Mac, but I know that the driver can be compiled with WinAVR 20070525.
Let's concentrate on the debug output. You get the startup message and you see USB Reset, but you don't get any data. This can be because the interrupt never occurs or because the data is identified as garbage by the interrupt handler.
You should be able to verify whether the interrupt occurs by toggling a LED in the interrupt service routine (temporarily use your own interrupt handler for that). If it does occur and the handler thinks the data is garbage, things become harder to debug. You could toggle LEDs in various places in the assembler module, but that's hard if you are not the author of the code.
If I remember correctly, it does not work regardless of the interrupt in your case.
If the interrupt pin is "open", then it's normal that it is very sensitive to touching or other changes. But it should be connected to D+ anyway.
The warnings are OK. This means that the data type had to be converted for a function call. I'm NOT using WinAVR because I have a Mac, but I know that the driver can be compiled with WinAVR 20070525.
Let's concentrate on the debug output. You get the startup message and you see USB Reset, but you don't get any data. This can be because the interrupt never occurs or because the data is identified as garbage by the interrupt handler.
You should be able to verify whether the interrupt occurs by toggling a LED in the interrupt service routine (temporarily use your own interrupt handler for that). If it does occur and the handler thinks the data is garbage, things become harder to debug. You could toggle LEDs in various places in the assembler module, but that's hard if you are not the author of the code.
christian wrote:If I remember correctly, it does not work regardless of the interrupt in your case.
Right
christian wrote:Let's concentrate on the debug output. You get the startup message and you see USB Reset, but you don't get any data. This can be because the interrupt never occurs or because the data is identified as garbage by the interrupt handler.
You should be able to verify whether the interrupt occurs by toggling a LED in the interrupt service routine (temporarily use your own interrupt handler for that).
I have done so - the LED toggles several times after the device has been plugged to the USB. This means that the ISR is triggered as excepted and - following your explanation - the incoming data is garbled or corrupted. Do you have any references (screenshot from oscilloscope) of how the D+ and D- line should look like?
christian wrote:If it does occur and the handler thinks the data is garbage, things become harder to debug. You could toggle LEDs in various places in the assembler module, but that's hard if you are not the author of the code.
Ok, any ideas?