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

Thread: Help Needed - Proper way to read Teensy 3.6 MAC Address

  1. #1

    Help Needed - Proper way to read Teensy 3.6 MAC Address

    What is the proper way to obtain the preprogrammed MAC address from a Teensy 3.6 ??

    The following test program uses the previously published "read_t3_mac_word" code snippit that works well on a Teensy 3.2 and but only obtains a half correct answer when used with a Teensy 3.6...

    // Enter a MAC default address
    byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // default test mac address
    /** Retrieve Ethernet MAC from Teensy 3 */
    void read_t3_mac_word(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
      *(mac + loc) =   FTFL_FCCOB5;     // collect only the top three bytes,
      *(mac + loc + 1) = FTFL_FCCOB6;   // in the right orientation (big endian).
      *(mac + loc + 2) = FTFL_FCCOB7;   // Skip FTFL_FCCOB4 as it's always 0.
    void setup() {
      delay(1000); // allow time for Windoze USB to reconnect
      // Open serial communications and wait for port to open:
      // this check is only needed on the Leonardo:
      while (!Serial) {
        ; // wait for serial port to connect. Needed for Leonardo only
      Serial.println("...Teensy 3.6 Read MAC Address Test Starting...");
      read_t3_mac_word(0xe, 0); // get mac address unique to this teensy
      read_t3_mac_word(0xf, 3);
      Serial.printf("\nMy MAC Address is %02X:%02X:%02X:%02X:%02X:%02X\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
      Serial.printf("\n...Done - Looping Forever...\n");
    void loop() {
    This example returns 04:E9:E5:04:E9:E5 for all of my Teensy 3.6s. The first three bytes are as expected but the last three bytes are not correct.

    Question #1 - What is the correct way to obtain the second half of the MAC address ?

    Question #2 - This program fails if the CPU Speed is above 120MHz.

    At CPU speeds above 120MHz the program returns 00:00:00:00:00:00

    I have followed the experiments others have used to read Teensy 3.6 EEPROM at speeds above 120MHz but wonder if there is now an accepted or suggested best way to obtain the MAC address from Teensy 3.6 EEPROM at the higher speeds.

    Thanks very much for your interest and support !

  2. #2
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    The spec speed of the T_3.6 processor is 180 MHz, but it must go into an HSRUN- High Speed Run / OverClocking mode over 120 MHz. This apparently involves boosting internal voltages in such a way the it cannot safely write to the EEPROM, or access certain other areas across some internal 'wall' (alternate substrate or whatever it might be). The Write once values area where the serial number bytes are stored are on the other side of that wall. Without HSRUN being enabled the high speed clocks will not start. Linked thread below started by trying to drop processor speed and HSRUN - performing the needed processes and then restoring - however that mucks up any clock reference - or any bus type I/O that relies on it - like USB/SPI/I2C. FrankB helpfully said - just drop HSRUN - and I blindly tried it. It "SEEMS" perfectly functional to drop out of HSRUN mode while AT SPEED over 120 MHz ( based on my variety and hours of testing ).

    Additionally the T_3.6/T_3.5 have different internals and require a 64 bit read of the Serial # storage area - so there is an altered method to get the serial number even at 120 MHz or below. The linked Pull below shows the core code that has that process under #ifdef.

    Paul is looking into a fix on his end - not sure if there is some fundamental prohibition against doing what I did - but it works - especially to get the Serial # for startup usage, where I observed once the value is pulled over the wall - it stays cached - in ways I tested it.

    So - wait for PJRC solution, perhaps in this TD_1.31 Beta cycle - or if you dare try my code - if you are running TD_1.30/1.31b1 you can swap the core files and linked below and give it a try. {it has been tested to work by others than myself and I tested it on two beta T_3.6's and 6 KS units }

    As noted - and in the thread below the 4K EEPROM area is read only over 120 MHZ - so if you want to write to EEPROM today you have to drop to 120 or under - or try my fix - or see what the pending PJRC solution is.

    There are other posts on this - here is my thread on the EEPROM affect and solution I came up with - this same PULL request ( edit to Teensy Core files for Paul to consider ) picked up my related fix/pull request to address this: EEPROM-writing-on-T_3-6-in-HSRUN-mode

    For reference this comes from the beta thread:
    Quote Originally Posted by KurtE View Post
    Paul: It would be great if you could put some form of fix (Hack) to fix the issue where the USB serial # does not work on T3.6 when running at CPU speed > 120mhz.
    Quote Originally Posted by PaulStoffregen View Post
    It's near the top of my todo list. So is basic SDIO support in the SD library.

    Whether I get it in tomorrow or early next week is a good question. Friday to Monday will be consumed with travel for NY Maker Faire.
    And my ping yesterday: K66-Beta-Test?
    Last edited by defragster; 10-15-2016 at 07:41 AM.

Posting Permissions

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