Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 14 of 14

Thread: Teensy 4.1 MAC Address

  1. #1
    Member KD0RC's Avatar
    Join Date
    May 2019
    Location
    Colorado, USA
    Posts
    75

    Teensy 4.1 MAC Address

    I have my Teensy 4.1 working (for the most part...) but it does not seem to have a MAC address. If I feed NativeEthernet a legitimate MAC address for another device, DHCP serves up a nice ip address and my Teensy uses it to connect to my Flex SDR radio. If I want two devices on the same network segment, it only works for the last device added as the local ip is the same for both devices (I think because the MAC address is the same). Is there a trick to NativeEthernet that will give me a different ip for a second device connection? Am I approaching this problem all wrong? Is there a get MAC address function or something that will help me? I am not a network guy, so I am fumbling around with this...

    Thanks,
    Len

  2. #2
    Senior Member vjmuzik's Avatar
    Join Date
    Apr 2017
    Posts
    732
    They do come preprogrammed with a unique MAC address, this is the code that retrieves it for a Teensy 4.x, just supply it with your MAC address array that's 6 bytes long and it'll set it accordingly:
    Code:
    void teensyMAC(uint8_t *mac) {
        for(uint8_t by=0; by<2; by++) mac[by]=(HW_OCOTP_MAC1 >> ((1-by)*8)) & 0xFF;
        for(uint8_t by=0; by<4; by++) mac[by+2]=(HW_OCOTP_MAC0 >> ((3-by)*8)) & 0xFF;
        Serial.printf("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
    }

  3. #3
    Senior Member
    Join Date
    Mar 2016
    Posts
    292
    vj answered the MAC question. I can confirm each one is unique (or at least the 4 I have are).

    To the IP addr question, if you select DHCP, you get unique IP addrs. (I think that's the default...) You can also specify a static IP addr but probably better to use DHCP and then reserve those addrs on your router. It plays a lot nicer with your network. You may need the MAC for that on some routers.

  4. #4
    Member KD0RC's Avatar
    Join Date
    May 2019
    Location
    Colorado, USA
    Posts
    75
    AH! Thanks VJ, I really appreciate that. I included your code in my program, and it worked! I now have two devices connected to the same SDR radio and communicating properly. I really appreciate all that you have done with the NativeEthernet library. Using it I have made huge strides in my project. Without it, I never would have gotten off the starting line.

    Thanks,
    Len

  5. #5
    Quote Originally Posted by vjmuzik View Post
    They do come preprogrammed with a unique MAC address, this is the code that retrieves it for a Teensy 4.x, just supply it with your MAC address array that's 6 bytes long and it'll set it accordingly:
    Code:
    void teensyMAC(uint8_t *mac) {
        for(uint8_t by=0; by<2; by++) mac[by]=(HW_OCOTP_MAC1 >> ((1-by)*8)) & 0xFF;
        for(uint8_t by=0; by<4; by++) mac[by+2]=(HW_OCOTP_MAC0 >> ((3-by)*8)) & 0xFF;
        Serial.printf("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
    }
    Do you think that NativeEthernet should have a constructor where this is used to instantiate the MAC address for those new at this? Or maybe just have it as a "getSystemMAC()" function? I'm just starting out with Ethernet on the Teensy 4.1 (this is actually my first time doing anything with Ethernet honestly), and I think other newcomers might want this too. Thoughts?

  6. #6
    Junior Member
    Join Date
    Jan 2021
    Location
    Stratford on Avon
    Posts
    3
    I'd agree with that. This Ethernet stuff is a bit of a black art to me. The above seems to say "just supply it with your MAC address array that's 6 bytes long" - but isn't the MAC address the thing I am trying to find out.
    I would really appreciate something that I can just run and I'll work out what it means afterwards.
    I'm just trying to send a simple email - which on the Raspberry Pi is straight forward - but I can't seem to find the equivalent for and Arduino or more specifically the Teensy.

  7. #7
    I'm right there with you. I'm still trying to figure out which Ethernet library is the right one. Looks like a lot of documentation hasn't yet caught up to the 4.1 release.

    Which library are you using? Got it working yet? I have 2 T4.1's here that I'm trying to get to chat to each other.

  8. #8
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    13,462
    Quote Originally Posted by gajjer View Post
    I'd agree with that. This Ethernet stuff is a bit of a black art to me. The above seems to say "just supply it with your MAC address array that's 6 bytes long" - but isn't the MAC address the thing I am trying to find out.
    I would really appreciate something that I can just run and I'll work out what it means afterwards.
    I'm just trying to send a simple email - which on the Raspberry Pi is straight forward - but I can't seem to find the equivalent for and Arduino or more specifically the Teensy.
    That need to send the 'address array' is where the Teensy's MAC will be written when the code shown above is executed. 'just supply' means allocate the needed 6 byte variable and pass to the function shown in p#2 and it returns with the device MAC.


    Quote Originally Posted by bschena View Post
    I'm right there with you. I'm still trying to figure out which Ethernet library is the right one. Looks like a lot of documentation hasn't yet caught up to the 4.1 release.

    Which library are you using? Got it working yet? I have 2 T4.1's here that I'm trying to get to chat to each other.
    The library that works for the T_4.1 AFAIK ( no it is not noted with ethernet on the T_4.1 page ) is :: (arduino)\hardware\teensy\avr\libraries\NativeEthe rnet
    Check the examples - it works like prior libraries for ethernet - though there is a thread for that library indicating it maps into a more powerful underlying code (IIRC FNET?) that can be used directly.

  9. #9
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    13,462
    Here is that library thread :: T4-1-Ethernet-Library

  10. #10
    Senior Member
    Join Date
    Mar 2014
    Location
    Switzerland
    Posts
    107
    Hi All

    I didn't realise that the Teensy 4.1 had a MAC address burned into its eFUSEs until reading this thread so I read out the eFUSEs on my board:

    eFUSEs
    ======
    LOCK
    0x40528107
    CFG
    0x677f0555
    0x184c71d2
    0x500000bb
    0x00420002
    0x00000000
    0x00080018
    0x00000000
    MEM
    0x00000000
    0x00009400
    0x0000007c
    0x00000000
    0x00000000
    ANALOG
    0x00000000
    0x51d4b65f
    0x00000000
    SRK
    0x00000000
    0x00000000
    0x00000000
    0x00000000
    0x00000000
    0x00000000
    0x00000000
    0x00000000
    SJC
    0x00000000
    0x00000000
    MAC (locked)
    0xe50d301a
    0x000004e9
    0x00000000
    GP
    0x00000000
    0x00000000
    SW GP
    0x00000000
    0x00000000
    0x00000000
    0x00000000
    0x00000000
    MISC
    0x00000040
    0x00000000
    REVOKE
    0x00000000
    PATCH
    0x00000000
    0x00000000
    0x00000000
    0x00000000
    0x00000000
    0x00000000
    0x00000000
    0x00000000
    GP3
    0x00000000
    0x00000000
    0x00000000
    0x00000000
    0x00000000
    0x00000000
    0x00000000
    0x00000000


    where it is seen that the MAC address is set and locked so that it can't be modified in any way.

    In the IEEE list of organizationally unique identifiers PJRC is registered as owner of the block of 16M that the addresses are defined from.

    04-E9-E5 (hex) PJRC.COM, LLC
    04E9E5 (base 16) PJRC.COM, LLC
    14723 SW Brooke Ct
    Sherwood Oregon 97140
    US


    Since there is a registered OUI but without confidentiality (which costs $3'565 a year at the moment) I presume that PJRC invested $3'085 in this block of addresses (or had done so earlier for assigning MAC addresses to previous products too).
    The MAC address probably contributes to the price of the board so I think that it makes sense in using it for the intended reasons that this cost is not wasted ;-)

    Regards

    Mark

  11. #11

    Share ROM dump code?

    Any chance you would be willing to share the code you used to scrape the eFUSE registers from T4.1?

    Quote Originally Posted by uTasker View Post
    Hi All

    I didn't realise that the Teensy 4.1 had a MAC address burned into its eFUSEs until reading this thread so I read out the eFUSEs on my board:

    eFUSEs
    ======
    LOCK
    0x40528107
    CFG
    0x677f0555
    0x184c71d2
    0x500000bb
    0x00420002
    0x00000000
    0x00080018
    0x00000000
    MEM
    0x00000000
    0x00009400
    0x0000007c
    0x00000000
    0x00000000
    ANALOG
    0x00000000
    0x51d4b65f
    0x00000000
    SRK
    0x00000000
    0x00000000
    0x00000000
    0x00000000
    0x00000000
    0x00000000
    0x00000000
    0x00000000
    SJC
    0x00000000
    0x00000000
    MAC (locked)
    0xe50d301a
    0x000004e9
    0x00000000
    GP
    0x00000000
    0x00000000
    SW GP
    0x00000000
    0x00000000
    0x00000000
    0x00000000
    0x00000000
    MISC
    0x00000040
    0x00000000
    REVOKE
    0x00000000
    PATCH
    0x00000000
    0x00000000
    0x00000000
    0x00000000
    0x00000000
    0x00000000
    0x00000000
    0x00000000
    GP3
    0x00000000
    0x00000000
    0x00000000
    0x00000000
    0x00000000
    0x00000000
    0x00000000
    0x00000000


    where it is seen that the MAC address is set and locked so that it can't be modified in any way.

    In the IEEE list of organizationally unique identifiers PJRC is registered as owner of the block of 16M that the addresses are defined from.

    04-E9-E5 (hex) PJRC.COM, LLC
    04E9E5 (base 16) PJRC.COM, LLC
    14723 SW Brooke Ct
    Sherwood Oregon 97140
    US


    Since there is a registered OUI but without confidentiality (which costs $3'565 a year at the moment) I presume that PJRC invested $3'085 in this block of addresses (or had done so earlier for assigning MAC addresses to previous products too).
    The MAC address probably contributes to the price of the board so I think that it makes sense in using it for the intended reasons that this cost is not wasted ;-)

    Regards

    Mark

  12. #12
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    23,742
    Quote Originally Posted by uTasker View Post
    Since there is a registered OUI but without confidentiality (which costs $3'565 a year at the moment) I presume that PJRC invested $3'085 in this block of addresses (or had done so earlier for assigning MAC addresses to previous products too).
    Yes, I can confirm PJRC registered with IEEE several years ago for a 24 bit OUI.

  13. #13
    Senior Member
    Join Date
    Mar 2014
    Location
    Switzerland
    Posts
    107
    Hi

    Below is the code that I use which you may be able to reverse engineer to your environment. It is from the uTasker project so uses different headers and formatted output commands.
    If you just want to read the values on your board you can simply load the iHex from here to do it https://www.utasker.com/iMX/Teensy_4_1.html - just command "eFUSE" in the Administrator menu (menu 4) to get it to print them out over the USB

    Code:
            {
                int i;
                volatile unsigned long *ptrRegister = HW_OCOTP_CFG0_ADD;
                POWER_UP_ATOMIC(2, OCOTP_CTRL_CLOCK);
                fnDebugMsg("eFUSEs\r\n======\r\nLOCK\r\n");
                fnDebugHex(HW_OCOTP_LOCK, (WITH_SPACE | WITH_LEADIN | WITH_CR_LF | sizeof(unsigned long)));
                fnDebugMsg("CFG\r\n");
                i = 7;
                while (i-- != 0) {
                    fnDebugHex(*ptrRegister, (WITH_SPACE | WITH_LEADIN | WITH_CR_LF | sizeof(unsigned long)));
                    ptrRegister += 4;
                }
                fnDebugMsg("MEM\r\n");
                ptrRegister = HW_OCOTP_MEM0_ADD;
                i = 5;
                while (i-- != 0) {
                    fnDebugHex(*ptrRegister, (WITH_SPACE | WITH_LEADIN | WITH_CR_LF | sizeof(unsigned long)));
                    ptrRegister += 4;
                }
                fnDebugMsg("ANALOG\r\n");
                ptrRegister = HW_OCOTP_ANA0_ADD;
                i = 3;
                while (i-- != 0) {
                    fnDebugHex(*ptrRegister, (WITH_SPACE | WITH_LEADIN | WITH_CR_LF | sizeof(unsigned long)));
                    ptrRegister += 4;
                }
                fnDebugMsg("SRK\r\n");
                ptrRegister = HW_OCOTP_SRK0_ADD;
                i = 8;
                while (i-- != 0) {
                    fnDebugHex(*ptrRegister, (WITH_SPACE | WITH_LEADIN | WITH_CR_LF | sizeof(unsigned long)));
                    ptrRegister += 4;
                }
                fnDebugMsg("SJC\r\n");
                fnDebugHex(HW_OCOTP_SJC_RESP0, (WITH_SPACE | WITH_LEADIN | WITH_CR_LF | sizeof(unsigned long)));
                fnDebugHex(HW_OCOTP_SJC_RESP1, (WITH_SPACE | WITH_LEADIN | WITH_CR_LF | sizeof(unsigned long)));
                fnDebugMsg("MAC");
                if ((HW_OCOTP_LOCK & eFUSE_LOCK_MAC_ADDR_LOCK_MASK) != 0) {
                    fnDebugMsg(" (locked)\r\n");
                }
                else {
                    fnDebugMsg("\r\n");
                }
                fnDebugHex(HW_OCOTP_MAC0, (WITH_SPACE | WITH_LEADIN | WITH_CR_LF | sizeof(unsigned long)));
                fnDebugHex(HW_OCOTP_MAC1, (WITH_SPACE | WITH_LEADIN | WITH_CR_LF | sizeof(unsigned long)));
        #if defined HW_OCOTP_MAC2
                fnDebugHex(HW_OCOTP_MAC2, (WITH_SPACE | WITH_LEADIN | WITH_CR_LF | sizeof(unsigned long)));
                fnDebugMsg("GP\r\n");
        #else
                fnDebugMsg("GP\r\n");
                fnDebugHex(HW_OCOTP_GP3, (WITH_SPACE | WITH_LEADIN | WITH_CR_LF | sizeof(unsigned long)));
        #endif
                fnDebugHex(HW_OCOTP_GP1, (WITH_SPACE | WITH_LEADIN | WITH_CR_LF | sizeof(unsigned long)));
                fnDebugHex(HW_OCOTP_GP2, (WITH_SPACE | WITH_LEADIN | WITH_CR_LF | sizeof(unsigned long)));
                fnDebugMsg("SW GP\r\n");
                ptrRegister = HW_OCOTP_SW_GP1_ADD;
                i = 5;
                while (i-- != 0) {
                    fnDebugHex(*ptrRegister, (WITH_SPACE | WITH_LEADIN | WITH_CR_LF | sizeof(unsigned long)));
                    ptrRegister += 4;
                }
                fnDebugMsg("MISC\r\n");
                fnDebugHex(HW_OCOTP_MISC_CONF0, (WITH_SPACE | WITH_LEADIN | WITH_CR_LF | sizeof(unsigned long)));
                fnDebugHex(HW_OCOTP_MISC_CONF1, (WITH_SPACE | WITH_LEADIN | WITH_CR_LF | sizeof(unsigned long)));
                fnDebugMsg("REVOKE\r\n");
                fnDebugHex(HW_OCOTP_SRK_REVOKE, (WITH_SPACE | WITH_LEADIN | WITH_CR_LF | sizeof(unsigned long)));
        #if defined HW_OCOTP_ROM_PATCH0
                fnDebugMsg("PATCH\r\n");
                ptrRegister = HW_OCOTP_ROM_PATCH0_ADD;
                i = 8;
                while (i-- != 0) {
                    fnDebugHex(*ptrRegister, (WITH_SPACE | WITH_LEADIN | WITH_CR_LF | sizeof(unsigned long)));
                    ptrRegister += 4;
                }
                fnDebugMsg("GP3\r\n");
                ptrRegister = HW_OCOTP_GP30_ADD;
                i = 8;
                while (i-- != 0) {
                    fnDebugHex(*ptrRegister, (WITH_SPACE | WITH_LEADIN | WITH_CR_LF | sizeof(unsigned long)));
                    ptrRegister += 4;
                }
                POWER_DOWN_ATOMIC(2, OCOTP_CTRL_CLOCK);
        #endif
            }
    Note that the uTasker project simulates the i.MX RT 1062 and the Teensy board as well as the eFUSEs - I have a video showing the simulation of this and the security module in the chip (allowing XiP on-the-fly decryption to be used on the Teensy 4.1 too - without actually needing to program the eFUSEs): https://youtu.be/o7hQbOqhJoc

    Regards

    Mark

  14. #14
    Awesome Mark, thank you! uTasker looks like an interesting project, I'll check out the links and info you mentioned.

    Cheers!

    /b/

Posting Permissions

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