USB (AVRUSB) code works on 0016, fails on 0018?

diI've got an AVRUSB-based project (now V-USB, but I'm still using an old codebase before converting it to the new library) which works fine on both my 168 and my 328 using 0016, but simply will not work with 0018.

The first part of the problem is just that one file was .c but should be compiled as .cpp, so I renamed it (easy enough). The library now compiles in 0018... but the code does not work correctly.

The original library had to be precompiled for 0016 using the command line

avr-g++ -Wall -Os -I. -DUSB_CFG_CLOCK_KHZ=16000 -mmcu=atmega168 -c usbdrvasm.S -c usbdrv.c

The important parts are the define for the frequency, and the -mmcu switch, I think. I have tried editing the header files to force the definition of the frequency, and now 0018 compiles and the device almost works on my 168 (in that my USB device is recognized by the system... but does not function correctly), but on my 328, the generated USB device is not even recognized at all! Looking at the obdev forums, they suggest compiling as if for the 168 and just using it that way... but that doesn't work so much in 0018, where I can't figure out how to specify how the libraries should be compiled.

Obviously this is not desired. Any suggestions? I can continue to use 0016, but I would like it to work with newer versions of the Arduino environment, and I can't see why it wouldn't--aside from which anyone who downloads the code is probably going to want to use the most recent version of the environment...

I think you should be able to put .h and .o files for the AVRUSB code into a library folder (a sub-folder of the "libraries" folder of your Arduino sketch folder), although that may not work if you switch board selections.

If you hold down shift while pressing the play (verify / compile) toolbar button, you can see the command lines used by Arduino to compile your sketch, etc. That might help you figure out what the significant difference in command lines is.

There's not really any way to tweak the command lines used currently, but this would be a good use case and argument for changing that. If you figure out what needs to be changed, it would be great if you posted here or opened an issue in the Google Code project: http://code.google.com/p/arduino/issues/list

Thanks, mellis--seeing the lines does help and that seems to be exactly my problem.

I haven't worked out why it doesn't work on the 168 yet, but on the 328 the line switches to "-mmcu=atmega328p", and V-USB has known problems with the 328p (see here, may have something to do with fuses (?) or interrupt vectors), which may be fixed in a future release but aren't yet--the current solution is "compile as for the 168 and just upload it".

I'll try to poke more, but I think there certainly should be some mechanism for changing compilation flags for libraries, particularly when using code bases that may require special switches/defines/whatever for Arduino. As it is I'm not sure what to do (I still need to figure out why it's not working on the 168). I guess for the moment my users (heh--all what, three of them?) will just have to use 0016. Any way to do the "shift-compile-button" trick on 0016 and see what the build steps are?

Thanks for the help. This may just turn out to be a project I should have done with a "proper" USB-based AVR, but it worked fine with 0016, so I'm determined to get it working again eventually.

Any way to do the "shift-compile-button" trick on 0016 and see what the build steps are?

Add a line with "build.verbose=true" to the arduino preferences.txt file. This enables verbose output permanently. (build.verbose=false disables it.)

If you want to see the upload-cmds too add another line with "upload.verbose=true"

Eberhard

Thanks; that confirmed what I thought already (ie 0016 didn't compile the library, just linked with it, which is what I wanted). I'll try putting just the header files and .o files in my library dir and see what happens...

Yep, no go--it didn't try to link to the .o files and thus gave a bunch of "undefined reference" errors as one would expect. So I either need a way to prescribe the compilation flags for my library or I need a way to link to precompiled libraries, one or the other.

Is there such a facility? I did some googling and didn't turn anything up, but it seems a bit surprising. I know that arduino is meant for more casual hacking, but I feel like there should be SOME facility for this sort of thing.

Hmm, see if you can figure out why it doesn't work on the ATmega168 (i.e. what command line flags need to be different). That would help figure out how to design the compilation-flag tweaking functionality.

I could add support for linking .o files back in, but it's not very robust since it wouldn't support multiple boards. Probably we'll need support for binary libraries at some point (for non-open source ones), but it should probably support per-board .o files. I added this as an issue: http://code.google.com/p/arduino/issues/detail?id=199

Mellis:

see if you can figure out why it doesn’t work on the ATmega168

PEBKAC in the case of the 168; I had specified the wrong hardware device to communicate with (the wrong controller for the Arduino to talk to). So the 168 works fine once I moved the “defines” from the command line to the header file (ie instead of passing -DUSB_CFG_CLOCK_KHZ=16000, I just set the line in the .h file to “#define USB_CFG_CLOCK_KHZ=16000”, inelegant but it works), and once again is turning an expensive CAD input device into a cheesy game controller like it rightfully should be.

So now the problem for the 328 is… well, really in the source code. In other words, V-USB is not compiling correctly because Arduino is passing avr-g++ the “-mmcu=atmega328p” flag, and it won’t compile except with the -mmcu=atmega168 flag. I am looking at their forums to see if there’s anything to do source-code wise.

So hmm; one of those design decisions above my pay grade, I guess–should Arduino be hackable enough to link with arbitrary badly-coded libraries? (I’m not trying to grouse too much on V-USB, which is an amazing piece of work–just that it should work on the 328p with just the switch). Hacker part of my brain says yes, but the code maintainer in me has a great deal of sympathy…

Problem "solved".

I'm still of the opinion that libraries for the AVR series should at least have some ability to set custom #defines, but by editing the source of the V-USB library to force the requisite #defines, that was fixable.

The problem with compilation for the 328p was very obscure (to me). I will quote the relevant portion of the V-USB forums:

I discovered that the cause is a change in the identifier of the INT0 vector. V-USB is using the outdated "SIG_INTERRUPT0" as default in usbdrvasm.S (Line 60) which is only supported by "old" headerfiles for "old" controllers. The headerfiles for the controller with a "p" only support the new identifier "INT0_vect". So the vector to the interrupt routine is not written into the vector table and unfortunately in this case you will not get any warning or error message

By changing that line, the code (which indeed compiled without error in both cases) built correctly and my device and library are working at what appears to be 100% in 0018.

Thanks for the help!

Glad you got it working.

I agree that we probably need some flexibility in the compilation commands, but I think we need to find more real world use cases (that don't get solved through easy work arounds) to figure out how to design the feature properly.