Forum Rule: Always post complete source code & details to reproduce any issue!
Page 1 of 6 1 2 3 ... LastLast
Results 1 to 25 of 128

Thread: teensy 3 MAC address

  1. #1

    teensy 3 MAC address

    After a conversation with Paul, I think I've figured out how to access the unique Ethernet media access (MAC) address burnt into the Teensy3. This number will be different on every teensy 3, and isn't overwritten by the bootloader flashing process like the EEPROM is.

    Given this class:

    Code:
    /** Retrieve Ethernet MAC from Teensy 3 */
    class mac_addr : public Printable {
    public:
        uint8_t m[6];
    
        mac_addr() : m({0}) {
            // Retrieve the 6 byte MAC address Paul burnt into two 32 bit words
            // at the end of the "READ ONCE" area of the flash controller.
            read(0xe,0);
            read(0xf,3);
        }
    
        void read(uint8_t word, uint8_t loc) {
    
            // To understand what's going on here, see
            // "Kinetis Peripheral Module Quick Reference" page 85 and
            // "K20 Sub-Family Reference Manual" page 548.
    
            FTFL_FCCOB0 = 0x41;             // Selects the READONCE command
            FTFL_FCCOB1 = word;             // read the given word of read once area
                                            // -- this is one half of the mac addr.
            FTFL_FSTAT = FTFL_FSTAT_CCIF;   // Launch command sequence
            while(!(FTFL_FSTAT & FTFL_FSTAT_CCIF)) {
                                            // Wait for command completion
            }
            *(m+loc) =   FTFL_FCCOB5;       // collect only the top three bytes,
            *(m+loc+1) = FTFL_FCCOB6;       // in the right orientation (big endian).
            *(m+loc+2) = FTFL_FCCOB7;       // Skip FTFL_FCCOB4 as it's always 0.
        }
    
        virtual size_t printTo(Print & p) const {
            size_t count = 0;
            for(uint8_t i = 0; i < 6; ++i) {
                if (i!=0) count += p.print(":");
                count += p.print((*(m+i) & 0xF0) >> 4, 16);
                count += p.print(*(m+i) & 0x0F, 16);
            }
            return count;
        }
    };
    You can print out the MAC like:
    Code:
    Serial.print("MAC: ");
    mac_addr mac;
    Serial.println(mac);
    On mine, this prints:
    Code:
    MAC: 04:E9:E5:00:0D:59
    I hope Paul can verify my work here. This number at least seems to line up with the PJRC IEEE registration.

    Hope this is useful.

    -c
    Last edited by cmason; 11-06-2012 at 04:13 PM.

  2. #2
    Junior Member
    Join Date
    Oct 2012
    Location
    Switzerland
    Posts
    19
    Thank you cmason. It works well for me. I removed the C++ stuff and made a small Ardiono Sketch (see attachment).
    Attached Files Attached Files

  3. #3
    Senior Member
    Join Date
    Jun 2013
    Posts
    556
    I just stumbled upon this. This is great as it can be used as copy protection system. Is there anything like this available on the Teensy 2?

  4. #4
    Senior Member
    Join Date
    Jun 2013
    Location
    So. Calif
    Posts
    2,825
    Is that an ethernet address or a generic IEEE OUI that's not coded as in the Ethernet MAC range?
    IEEE 802.11 and 802.15.4 radios have a MAC in the OUI range, with MSBs to say which family.

    This chip-unique number helps a great deal with devices like WizNet Ethernet devices that have no factory assigned MAC address.

  5. #5
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    27,973
    Shortly before releasing Teensy 3.0, PJRC registered for an IEEE OUI usable for Ethernet. Every Teensy 3.0 and 3.1 has been programmed with this OUI and an incrementing 24 bit serial number. It was specifically intended for the Ethernet library with Wiznet chips.

    If you use cmason's code, I would recommend disabling interrupts within the read() function. You might also want to declare read() as static, to avoid possible conflicts with such a generic function name possibly being used in any other files.

  6. #6
    Senior Member
    Join Date
    Jan 2013
    Posts
    966
    I have been using the version posted by user THT in post #2. The Teensy3 ID has served perfectly as an Ethernet MAC for the WIZ820io so I can register more that one Teensy3 on my network using Bonjour without having to worry about a conflict.

  7. #7
    Senior Member
    Join Date
    Jun 2013
    Location
    So. Calif
    Posts
    2,825
    If need be on the Teensy2 et al that have no S/N, you can use the IEEE 'self administered' MAC address range.
    If I recall correctly, its a 0x02 in the MSByte.
    With that bit on, you can use any bits you wish and no manufacturer's MAC will conflict.

  8. #8
    Senior Member
    Join Date
    Jun 2013
    Location
    So. Calif
    Posts
    2,825
    Quote Originally Posted by PaulStoffregen View Post
    Shortly before releasing Teensy 3.0, PJRC registered for an IEEE OUI usable for Ethernet. Every Teensy 3.0 and 3.1 has been programmed with this OUI and an incrementing 24 bit serial number. It was specifically intended for the Ethernet library with Wiznet chips.
    Another good but not well known thing!

  9. #9
    Senior Member mortonkopf's Avatar
    Join Date
    Apr 2013
    Location
    London, uk
    Posts
    966
    thanks headroom,steve. That THT-cmason sketch is great, just pulled the mac out. now going to use this for the wiznet module.
    Last edited by mortonkopf; 02-21-2014 at 04:55 PM.

  10. #10
    Junior Member
    Join Date
    Apr 2014
    Posts
    6

    additional changes

    Quote Originally Posted by cmason View Post
    After a conversation with Paul, I think I've figured out how to access the unique Ethernet media access (MAC) address burnt into the Teensy3. This number will be different on every teensy 3, and isn't overwritten by the bootloader flashing process like the EEPROM is.

    Given this class:
    ------- snip -------
    Hope this is useful.

    -c
    I made a few changes to this, here is the results:
    Code:
    // macAddress.h
    #ifndef _MACADDR_H_
    #define _MACADDR_H_
    
    /** Retrieve Ethernet MAC from Teensy 3 */
    
    /*
     from http://forum.pjrc.com/threads/91-teensy-3-MAC-address 
     Edited by: Gene Reeves 04/23/2014
    	* added [] operator
    	* added uint8_t * operator for use in Ethernet.begin()
    */
    
    class macAddress : public Printable {
    protected:
        uint8_t _m[6];
    public:
        macAddress() : _m({0}) {
            // Retrieve the 6 byte MAC address Paul burnt into two 32 bit words
            // at the end of the "READ ONCE" area of the flash controller.
            read(0xe,0);
            read(0xf,3);
        }
    	
    	// gives access to individual elements 
    	uint8_t operator[](int index) const {return _m[index];}
    	uint8_t& operator[](int index) {return _m[index];}
    	
        // gives access to uint8_t array, use like this: Ethernet.begin(mac_address)
    	operator uint8_t *() {return &(_m[0]);}
    
        void read(uint8_t word, uint8_t loc) {
    
            // To understand what's going on here, see
            // "Kinetis Peripheral Module Quick Reference" page 85 and
            // "K20 Sub-Family Reference Manual" page 548.
    
            cli();
            FTFL_FCCOB0 = 0x41;             // Selects the READONCE command
            FTFL_FCCOB1 = word;             // read the given word of read once area
                                            // -- this is one half of the mac addr.
            FTFL_FSTAT = FTFL_FSTAT_CCIF;   // Launch command sequence
            while(!(FTFL_FSTAT & FTFL_FSTAT_CCIF)) {
                                            // Wait for command completion
            }
            *(_m+loc) =   FTFL_FCCOB5;       // collect only the top three bytes,
            *(_m+loc+1) = FTFL_FCCOB6;       // in the right orientation (big endian).
            *(_m+loc+2) = FTFL_FCCOB7;       // Skip FTFL_FCCOB4 as it's always 0.
            sei();
        }
    
        virtual size_t printTo(Print & p) const {
            size_t count = 0;
            for(uint8_t i = 0; i < 6; ++i) {
                if (i!=0) count += p.print(":");
                count += p.print((*(_m+i) & 0xF0) >> 4, 16);
                count += p.print(*(_m+i) & 0x0F, 16);
            }
            return count;
        }
        friend class EthernetClass;
        friend class UDP;
        friend class Client;
        friend class Server;
        friend class DhcpClass;
        friend class DNSClient;
    };
    #endif
    with the above code you can do this:
    Code:
    macAddress myMac;
    // print our MAC
    Serial.print("My MAC is ");
    Serial.println(myMac);
    
    Serial.println("Starting Network using DHCP.");
    
    if (Ethernet.begin(myMac)==0)
    {
        Serial.println("Failed to acquire IP address using DHCP, halting.");
        while(1) {;}
    }
    Serial.print("My IP is ");
    Serial.println(Ethernet.localIP());
    //
    // rest of your code here
    Hope someone finds this useful.

    if you see anything that does not look correct, please post a reply,
    Gene_R

  11. #11
    Per Paul's suggestion in December, you should probably be disabling interrupts around the manipulation of the flash.

  12. #12
    Junior Member
    Join Date
    Apr 2014
    Posts
    6
    Quote Originally Posted by jimlux View Post
    Per Paul's suggestion in December, you should probably be disabling interrupts around the manipulation of the flash.
    i am doing a cli and sei in the read function.. is that what your referring to?

  13. #13
    Senior Member xxxajk's Avatar
    Join Date
    Nov 2013
    Location
    Buffalo, NY USA
    Posts
    602
    Paul: this unique Ethernet MAC address is absolutely perfect for what I am doing, and solves a gigantic issue for me!
    --THANK YOU!--
    Now all I need to do is write the CDC EEM code and attach it to my IP stack! You rock!

  14. #14
    Senior Member johnnyfp's Avatar
    Join Date
    Jan 2014
    Location
    New Zealand
    Posts
    264
    Arduino IDE formatted library.

    Just unpack into your arduino library dir and enjoy.
    Attached Files Attached Files

  15. #15
    Senior Member johnnyfp's Avatar
    Join Date
    Jan 2014
    Location
    New Zealand
    Posts
    264
    Is the K20 burnt with the MAC address or the MINI54T (bootloader) that then gets loaded into the K20?

  16. #16
    Senior Member
    Join Date
    Jan 2013
    Posts
    966
    IIRC the MAC address ins burnt into the K20. It has a small write-once memory area where the MAC is stored.

  17. #17
    Senior Member johnnyfp's Avatar
    Join Date
    Jan 2014
    Location
    New Zealand
    Posts
    264
    Ok that would explain why I get FF:FF:FF:FF:FF:FF from my custom board.

  18. #18
    Senior Member
    Join Date
    Jun 2013
    Location
    So. Calif
    Posts
    2,825
    Yes, Paul burns that MAC using a PJRC registered OUI.

  19. #19
    Junior Member
    Join Date
    Dec 2014
    Posts
    1
    This is not working with Teensy 3.1. Is it supposed to? I was hoping it would help me with using the SD Card and Wiznet820io which work separately but not together despite trying various CS pins. I will post this on a different thread, none of which have helped me get these working together.

  20. #20
    Senior Member
    Join Date
    Jan 2013
    Posts
    966
    Yes, this works on the Teensy 3.1 as well and Ethernet is one of the reason for the existence of the burned in code. This works perfectly with the WIZ820io. I have not tinkered around with SD card stuff yet, but you'll find many references to SD card related problems on the forum.
    It depends often on the specific SD card used.

    Why would the MAC burned into the K20 help you with the SD card ?
    Last edited by Headroom; 12-06-2014 at 10:58 PM.

  21. #21
    Senior Member
    Join Date
    Sep 2015
    Posts
    102
    Ive just tried the zip file mentioned,
    and I'm getting an error on #include <Arduion.h> on the T3_readmac example.

    Anything I should obviously do apart from cry !!

    I know this is an old thread, so is there a different way of getting the MAC number off a teensy 3.2 ?

  22. #22
    Senior Member
    Join Date
    Apr 2014
    Location
    -
    Posts
    9,735
    I dont think so. It is the same chip.

  23. #23
    Senior Member mortonkopf's Avatar
    Join Date
    Apr 2013
    Location
    London, uk
    Posts
    966
    it should compile without errors. Have you put the lib into your lib folder and restarted arduino IDE?

  24. #24
    Senior Member
    Join Date
    Sep 2015
    Posts
    102
    Even re booted the PC

    here is the sketch

    #include "T3Mac.h"

    void setup() {
    delay(1000);
    Serial.begin(57600);

    Serial.println("Reading MAC from hardware...");
    read_mac();

    Serial.print("MAC: ");
    print_mac();
    Serial.println();

    Serial.print("Finished.");
    }

    void loop() {
    }




    and this is the message

    In file included from T3_readmac.ino:1:0:
    C:\Users\A123456\Documents\Arduino\libraries\T3Mac/T3Mac.h:4:21: warning: extra tokens at end of #include directive [enabled by default]
    #include <Arduino.h>;
    ^
    In file included from C:\Users\A123456\Documents\Arduino\libraries\T3Mac \T3Mac.cpp:1:0:
    C:\Users\A123456\Documents\Arduino\libraries\T3Mac \T3Mac.h:4:21: warning: extra tokens at end of #include directive [enabled by default]
    #include <Arduino.h>;

  25. #25
    Senior Member
    Join Date
    Jul 2014
    Posts
    3,497
    Quote Originally Posted by drjohnsmith View Post
    Even re booted the PC

    <snip\>

    and this is the message

    In file included from T3_readmac.ino:1:0:
    C:\Users\A123456\Documents\Arduino\libraries\T3Mac/T3Mac.h:4:21: warning: extra tokens at end of #include directive [enabled by default]
    #include <Arduino.h>;
    ^
    In file included from C:\Users\A123456\Documents\Arduino\libraries\T3Mac \T3Mac.cpp:1:0:
    C:\Users\A123456\Documents\Arduino\libraries\T3Mac \T3Mac.h:4:21: warning: extra tokens at end of #include directive [enabled by default]
    #include <Arduino.h>;
    this one is too easy!
    remove the semicolon at the end of the #include line.
    (the compiler suggested that this token is too much)
    Last edited by WMXZ; 11-04-2015 at 12:26 PM. Reason: spelling

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •