Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

USB_Device_GetSerialString Serial Number Nibble Question #88

Closed
jpliew opened this issue Aug 4, 2016 · 4 comments
Closed

USB_Device_GetSerialString Serial Number Nibble Question #88

jpliew opened this issue Aug 4, 2016 · 4 comments
Labels

Comments

@jpliew
Copy link

jpliew commented Aug 4, 2016

Hi,

Was wondering if anyone know if the bytes for UNIQUE SERIAL NUMBER for some devices (eg ATMEGA16U2) mentioned in the datasheet,

Unique Serial Number From 0x000E to 0x0018

are displayed in ,

High Nibble First
0x1A, display as 1A

or

Low Nibble First
0x1A, display as A1

From LUFA's Device_AVR8.h,

uint8_t SerialByte = boot_signature_byte_get(SigReadAddress);
if (SerialCharNum & 0x01)
{
    SerialByte >>= 4;
    SigReadAddress++;
}
SerialByte &= 0x0F;

Seems like the LOW nibble were displayed first.

When checking the UNIQUE SERIAL NUMBER using AVR STUDIO, the bytes were displayed HIGH nibble first.

Serial Number Read from AVR Studio
atmega16u2_serial_01

Serial Number returned by Arduino Serial Port that is using LUFA's code
atmega16u2_serial_02

From AVR Studio
Serial Number = 5732373336361511181F
From LUFA
Serial Number = 752373336363511181F1

I can't seems to find documents from ATMEL about this. If anyone know how this works, please share some light.

Cheers
JP

@jpliew jpliew changed the title USB_Device_GetSerialString Serial Number Question USB_Device_GetSerialString Serial Number Nibble Question Aug 4, 2016
@abcminiuser
Copy link
Owner

LUFA reads them out low nibble first, each nibble forming one hexadecimal digit of the serial number. The PC will them display that in MSB format, so a physical byte 0xDC will show on the PC as "DC". As the serial number is unique but opaque I though it didn't really matter how it was serialized out for the host as long as the algorithm was stable.

The device serial is effectively an internal ID code (wafer number, lot number, etc.) that is put in each device during manufacturing. I do not know the exact decoding - I didn't ask at Atmel so as not to taint my OSS efforts.

@jpliew
Copy link
Author

jpliew commented Aug 4, 2016

Hi @abcminiuser

Thank you so much for your reply.

What I got is a physical byte 0x57 , read from boot_signature_byte_get(), is being sent as 75 by LUFA to the PC and displayed as 75 by device manager (or any USB info software) as seen from the screen capture.

If you breakpoint at the following code from Device_AVR8.h

uint8_t SerialByte = boot_signature_byte_get(SigReadAddress);

you can see that the SerialByte is not the same as the one PC received from LUFA because the HIGH nibble and LOW nibble are in different order.

I suppose as long as the serial number is UNIQUE, it should be ok. Having said that, if we implement the current method used by LUFA to display the DEVICE ID, which is a few address above the UNIQUE SERIAL NUMBER, the physical bytes of ATMEGA16U2's DEVICE ID is

0x1E 0x94 0x89

Using LUFA's method to read LOW nibble first, the result will be

E1 49 98

which is an invalid DEVICE ID.

Cheers
JP

@abcminiuser
Copy link
Owner

What I got is a physical byte 0x57 , read from boot_signature_byte_get(), is being sent as 75 by LUFA to the PC and displayed as 75 by device manager (or any USB info software) as seen from the screen capture.

That's correct - LUFA is backwards. I guess I didn't notice when I implemented it, and it's too late to change it now (it would change the serial number for all devices in the wild). That said, since it's an opaque byte stream as I mentioned, there's no harm done as long as all the bits are transmitted (since it will be a unique N-bit number either way).

If you want to implement this in your user code, you aren't bound to the same algorithm as the internal USB_Device_GetSerialString() function. You can swap the nibbles as you construct the USB string descriptor in RAM so that the most significant nibble is sent as the leading digit, rather than the other way around as used by the internal LUFA serial string construction function.

@jpliew
Copy link
Author

jpliew commented Aug 4, 2016

Thanks @abcminiuser , appreciated your explanation, this clears up my question.

Keep up the good work.

@jpliew jpliew closed this as completed Aug 4, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants