Custom Serial Number - TeensyUser/doc GitHub Wiki

Why

Sometimes it might be necessary to change the standard serial number a Teensy reports to the over USB. (The following examples are for Windows, other OS might have no or other issues...)

  • Homebrew boards Since the serial number of standard Teensies is set by PJRC during production, homebrew boards will not have a unique standard S/N. This might lead to issues with Windows which distinguishes USB devices by VID/PID/SN. If it finds two devices with identical VID/PID/SN it assigns an auto generated serial number to all but the first detected boards. If your PC application now uses the serial number to identify the Teensy it needs to connect things might get confusing for users.

  • Identify boards If PC applications communicate with a microcontroller board which is connected through USB Serial you usually need the user to tell the application which COM port your device is connected to. If you have more than one device connected it can get tedious for the user to identify the correct one. However, it is not difficult to read out the serial number from the device. If you have some unique serial number scheme say 'COOLDEV001' you can easily implement an autodetection of your Teensy.

How To

Fortunately, setting a custom serial number is quickly done. It is stored in the struct usb_string_serial_number which gets set in usb_desc.h with its default value. Fortunately the struct is defined weak and can be overridden by user code as shown in the following example.

extern "C"
{
    struct usb_string_descriptor_struct
    {
        uint8_t bLength;
        uint8_t bDescriptorType;
        uint16_t wString[10];
    };

    usb_string_descriptor_struct usb_string_serial_number =
    {
         22,  // 2 + 2*length of the sn string
         3,
         {'M','Y', 'S','N', '0', '0', '0','0', '1', 0},
    };
}

//-----------------
void setup()
{
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop()
{
  digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN));
  delay(200);
}

This sets the serial number to "MYSN00001" as can be seen in the Windows device manager:

image

Please note: The bootloader will still report the standard serial number stored in the processor. Some uploaders (e.g. tyCommander) will get confused if a Teensy changes its serial number after uploading. The PJRC stock uploader works without problem.

DIY Teensies (T3.x)

If you have a DIY Teensy and want to assign serial numbers during production, the method described above might be not feasible since it stores the serial number in the sketch.

How to program your own serial number

At startup, teensyduino reads the serial number from a one time programmable section of the flash memory. Of course, in a DIY Teensy this section is not programmed and you can write your own serial number into it.

Here code writing a number to the one time programmable section. The code was tested for a DIY T3.2 (https://github.com/luni64/MicroMod_3.2)

include "Arduino.h"

// this code was tested for a  DIY T3.2 (MK20DX256 processor). It might need adjustments for other processors.

void setSerialNumberOnce(uint32_t sn)
{
    __disable_irq();
    FTFL_FSTAT = FTFL_FSTAT_RDCOLERR | FTFL_FSTAT_ACCERR | FTFL_FSTAT_FPVIOL;  // just in case, reset any errors
    FTFL_FCCOB0 = 0x43;                                                        // flash command 0x43 -> program once
    FTFL_FCCOB1 = 15;                                                          // use slot #15  (there are 16 32bit slots available, the SN needs to go into #15)
    *(uint32_t*)&FTFL_FCCOB7 = sn;                                             // set the sn to the corresponding registers
    FTFL_FSTAT = FTFL_FSTAT_CCIF;                                              // start programming
    while (!(FTFL_FSTAT & FTFL_FSTAT_CCIF));                                   // wait until done
    __enable_irq();
}

void setup()
{   
    pinMode(LED_BUILTIN, OUTPUT);

    uint32_t sn = 1234;      // in a real life program you'd get the SN to program from outside, e.g. via Serial etc.
    setSerialNumberOnce(sn); // program the serial number to the flash. This can only be done once. You can not delete or change this later
                             // programming will only succed it the old content of the slot was empty (0xFFFF'FFFF)
}

void loop()
{
    digitalToggleFast(LED_BUILTIN);
    delay(200);
}