Tutorial - How to change firmware on 8u2

I had trouble with the arduino-0021 version of arduino-usbserial. After building and programming it onto the 8U2 the Windows would ask to install drivers for the new device. After pointing the installation to the arduino drivers directory windows would report a failure in driver installation. The Arduino IDE would not recognize the UNO after that... :-/ I compiled the 0020 version and my UNO is back in action... :sunglasses:

I noticed in the 0021 release mentioned tweaks to PID/VID values... wondering if that has something to do with it. I don't have time to look at it tonight it's 12:50am :stuck_out_tongue:

Great tutorial ant.b! Can't wait to try the joystick version tomorrow.

Update: In the arduino-0021 version of arduino-usbserial the Descriptor.c file is using VID = 0x03EB (Atmel) and PID = 0x204B (LUFA USBtoSerial demo). The Arduino UNO.inf is looking for VID=0x2341 and PID=0x0001 which is reflected in arduino-0020...

I see in the 0021 release notes indicate "Modifying VID / PID combination in 8U2 firmwares" but was this the intent?

According to the USB folks, we're not really allowed to share our VID / PIDs with other organizations. So the firmware was modified to use other ones. Probably we should create a different version of the .inf file that uses the other VID/PID pair. The intent is that any VID/PID pair should work with the IDE, but that the Arduino ones should only be used with the official Arduino hardware.

Awesome work! I wasn't looking forward to working out all this stuff on my own.

The only problem I've encountered is loading the DFU drivers in windows 7. It seems they aren't signed so win7 refuses to allow access to the device via Flip. I had to install it on an XP machine before I could write my newly compiled .hex to the 8U2.

There are ways of making win7 load unsigned drivers in test mode, but this is cumbersome.

You can also use an ISP to update the 8U2 firmware, if you have one.

It would be great if the software on the ATmega8u2 had various usb "personalities" included, selectable by software on the 328.

You could send some special string to 328 to swithch it from usb-serial mode to usb-keyboard mode or usb-joystick mode.

Then, there will be no need to upload new software to the 8u2.

When power off it could return to the default usb-serial mode.

Here's a way to get the Uno into DFU mode without any soldering. Put two wires into GND pins on either side of the board. Then put the other ends of the wires on the board as follows:

The sequence is, hold the first wire on the top left 8u2 ICSP pad, then touch the second wire against the left side of the capacitor below the RX LED. Then remove both wires. It's slightly different to the sequence in the instructions but it seems to work.

Be careful with the second wire as the capacitor is quite near a 5v track. You can try using a low-value resistor instead of a wire if you are worried about blowing up your board.

To get back to normal mode, hold wire 1 in place as above, press the reset button, then remove wire 1. Or just unplug the USB cable and plug it back in.

I doesen'T have an Arduino Uno only a nano does someone know how I can use this code on an Arduino nano 3.0

it would be realy great if anyone has an answer for me ;D

does someone know how I can use this code on an Arduino nano 3.0

Can you post a picture of your nano with a ATMega8U2 chip on it?

Found a solution to my problem:

http://www.avrfreaks.net/index.php?module=Freaks%20Files&func=viewFile&id=3842&showinfo=1

These drivers were signed by some generous avrfreak, and work with the Uno under Win7 64b. Happy days!

Great! I want to try this now.

Thanks so much for this! Got an Uno for the purpose of making a funky arduino accelerometerfmouse and was fretting about the lack of info on how to go about the USB HID part til I found this post. Can't wait to get choppin with it!

I've been lurking around in this thread for some time now.
I think I've wrapped my head around the general idea.
How hard would it be to add another 2 axes to the example joystick?
(axes A,B,C,D instead of only X-Y)

As far as I can see, it requires some tinkering in the Descriptors.c file.
Could any other "HID Usages" like Vx or Vbrx serve as my extra axes?

How hard would it be to add another 2 axes to the example joystick?

Surely you only have X,Y and Z?

A Playstation Dualshock styled controller has 2 thumbsticks.
So four usable axes.
I would just like to pipe 4 different sensor values into Unity using no intermediate software whatsoever, so that's why.

A Playstation Dualshock styled controller has 2 thumbsticks.
So four usable axes.
I would just like to pipe 4 different sensor values into Unity using no intermediate software whatsoever, so that's why.

Ahh I see.

PS2 has 2 more axes: Z and Rz
So Descriptors.c has to be modified:

Replace

      0x09, 0x30,          /*     Usage (X)                                      */
      0x09, 0x31,          /*     Usage (Y)                                      */
      0x15, 0x9c,          /*     Logical Minimum (-100)                         */
      0x25, 0x64,          /*     Logical Maximum (100)                          */
      0x75, 0x08,          /*     Report Size (8)                                */
      0x95, 0x02,          /*     Report Count (2)                               */

by

      0x09, 0x30,          /*     Usage (X)                                      */
      0x09, 0x31,          /*     Usage (Y)                                      */
      0x09, 0x32,          /*     Usage (Z)                                      */
      0x09, 0x35,          /*     Usage (Rz)                                      */
      0x15, 0x9c,          /*     Logical Minimum (-100)                         */
      0x25, 0x64,          /*     Logical Maximum (100)                          */
      0x75, 0x08,          /*     Report Size (8)                                */
      0x95, 0x04,          /*     Report Count (4)                               */

And change the data structure:
in Joystick.h

Replace

typedef struct
            {
                  int8_t  X; /**< Current absolute joystick X position, as a signed 8-bit integer */
                  int8_t  Y; /**< Current absolute joystick Y position, as a signed 8-bit integer */
                  uint8_t Button; /**< Bit mask of the currently pressed joystick buttons */
            } USB_JoystickReport_Data_t;

by:

            typedef struct
            {
                  int8_t  X; /**< Current absolute joystick X position, as a signed 8-bit integer */
                  int8_t  Y; /**< Current absolute joystick Y position, as a signed 8-bit integer */
                  int8_t  Z; /**< Current absolute joystick Z position, as a signed 8-bit integer */                  
                  int8_t  Rz; /**< Current absolute joystick Rz position, as a signed 8-bit integer */
                  uint8_t Button; /**< Bit mask of the currently pressed joystick buttons */
            } USB_JoystickReport_Data_t;

I think it's the only thing to modify to see the 8u2 as a 4 axes joystick.
The code that is used to manage serial communication between 8u2 and arduino has to be updated to.

Alright Ant!
Great work man, thanks!
Can you also direct me to the pages where you found this info?
The specific usage pages and hex values?

Hey,
I'm experimenting with this today.
I implemented your code. (Thanks!)
Now I have to figure out the encoding / decoding procedure.

My idea was this: send an "identification char" (a, b, c, d)
followed by the sensor data (0-255).

So in Arduino I do "Serial.println('a')" followed by "Serial.println(serialData)". That seems simple enough.

In the 82U I have this code.

bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo,
                                         uint8_t* const ReportID,
                                         const uint8_t ReportType,
                                         void* ReportData,
                                         uint16_t* const ReportSize)
{
USB_JoystickReport_Data_t* JoystickReport = (USB_JoystickReport_Data_t*)ReportData;

while (Serial_IsCharReceived())
      {
      temp=Serial_RxByte();
      if (temp == "a"){JoystickReport->X  =  Serial_RxByte();}
      if (temp == "b"){JoystickReport->Y  =  Serial_RxByte();}
      if (temp == "c"){JoystickReport->Z  =  Serial_RxByte();}
      if (temp == "d"){JoystickReport->Rz =  Serial_RxByte();}
      }

*ReportSize = sizeof(USB_JoystickReport_Data_t);
      return false; 
}

But that don't work. Bummer.
Could somebody point me to why?

Comment : I have had some difficulties with Flip : I often had the error 'Address is out of range'. I don't really now why?? Does someone have an idea?

I think this might actually have to do with the size of the generated HEX file. Whenever I wrote too much code, I got over 4KB and I got this error too.