Teensy4.1 fusemap confusion... my MAC entries appear to be programmed already...

Status
Not open for further replies.

edsut

Well-known member
Hi,
I'm currently trying to understand the OCOTP and Fusemap on the iMXRT1062.
Seems my Teensy4.1 came with the MAC0 (Fusemap 0x620 & 0x630) location
programmed... Is that supposed to be pre-programmed?

According to the 1060's reference manual, that should be all zeros (with each OTP
bit then programmable to 1).

Note, its possible that I am not correctly reading the fusemap (see below).

More (already posted similar question to iMXRT forum)...
I'm having a hard time understanding how to correlate between what appears to be three different
descriptions and mapping of the same things...
  • the Fusemap Descriptions Table (section 22.3) which uses addresses between 0x400 and 0x8c0
  • the Fuse Shadow Memory Footprint (section 23.4.2) which uses addresses from 0x00 thru 0x3f
  • the OCOTP register bank

If anyone understands this and wants to give me a paragraph of explanation, I'd sure appreciate it.
 
Last edited:
Seems my Teensy4.1 came with the MAC0 (Fusemap 0x620 & 0x630) location
programmed... Is that supposed to be pre-programmed?

Yes. Every Teensy 4.0 & 4.1 comes with a unique 48 bit mac address pre-programmed into those fuses. Those address are from a OUI for PJRC assigned by IEEE, so it is a proper mac address.

PJRC writes this mac address into every Teensy 4 during product testing. If you buy a chip directly from NXP, those fuses will be all zeros.


More (already posted similar question to iMXRT forum)...

Please think of the many other people who will read these threads, perhaps months or years later if they have a similar question and find them by search. At the very least, please share a link on each thread to the others you've started, so anyone who finds the first on 1 site can also find the answers on the other(s).


I'm having a hard time understanding how to correlate between what appears to be three different
descriptions and mapping of the same things...
  • the Fusemap Descriptions Table (section 22.3) which uses addresses between 0x400 and 0x8c0
  • the Fuse Shadow Memory Footprint (section 23.4.2) which uses addresses from 0x00 thru 0x3f
  • the OCOTP register bank

Indeed NXP's documentation leaves much to be desired.

My understanding is the chip has 2048 OTP fuses, arranged at 64 addresses of 32 fuses per address. Whether all 64 are really implemented isn't really known (at least to me and probably anyone outside NXP), as most of the locations are "reserved". Some of the reserved locations are meant for storing encryption keys. Others have purpose (or no use at all) which is only known to NXP.

The first of those 32 bit fuse words appear at address 0x401F4400 in the ARM's 32 bit address space, and each subsequent 32 bit word is offset 16 bytes in the address space. Why they didn't offset them by 4 bytes is unknown to me. There also seems to be a strange 256 byte gap at 0x401F4700, where the 48th fuse appear at 0x401F46F0, and then the 49th fuse is at 0x401F4800.

Sometimes (often) NXP refers to the fuses by the low 12 bits of its location in the ARM address space, so 0x400 for the first 32 bit fuse word. But other times they refer to fuse word addresses as 0 to 0x3F, like figure 23-2 on page 1329.

fuses.jpg
(click for full size)

I personally find this diagram the most useful for visualizing the fuse memory, though it sure would be nice if it showed by the 0-3F and ARM address or at least 12 bits next to the integer index.
 
I see you added the link to your question on NXP's forum. Thanks.

Regarding your question on MISC_CONF0 and bits [19:16] on NXP's forum...

1: Indeed NXP documentation of MISC0_CONF0 on page 1367-1377 is pretty much worthless. Printing the visual representing of the register with its contents described as only "BITS" and "See the Fusemap Descriptions Table in the Fusemap chapter for more fuse details" would be better if they had just omitted the worthless diagram and instead made the words "See the Fusemap Descriptions Table" a hyperlink to the actual documentation of MISC_CONF0. But they didn't. They included a misleadingly empty register diagram (giving the false visual impression its bits don't do anything) and didn't bother to make the reference to the real documentation a link or even mention the specific page number. Like so much of NXP's documentation, it feels so terribly lazy & sloppy. But then again, I would be pretty hypocritical if I didn't confess that nearly all of PJRC's website needs a tremendous amount of work. Good documentation is not easy, even for a huge & well funded corporation like NXP.

2: On Teensy, assuming you're using Teensyduino or a system like PlatformIO or Visual Micro which uses the code PJRC publishes, those 4 bits have no effect. Very early in the Teensy's startup code we reconfigure the FlexRAM1 memory for only as much ITCM as your code needs, and the rest as DTCM. None of the FlexRAM1 bank is configured as OCRAM. All of FlexRAM2 is used as OCRAM (via the slower AXI bus), so we allocate all of FlexRAM1 to the fast ITCM & DTCM buses, effectively overriding at runtime whatever those 4 fuses specify.
 
Last edited:
Yea, I've pondered that diagram (for too long) trying to figure out how the "non-reserved" entries (0,5,6,7,F, etc..) correspond to locations in the fusemap.

Some are clear (LOCK@0x00 = fusemap-0x400, etc..) but others aren't as obvious to me. For example, how do the three
BOOT_CFG entries (0x05/6/7) in the OTP Memory Footprint correspond to the single 32-bit value at 0x450 (BOOT_CFG1-4)
in the fusemap?

(Note, this is great discussion, but if at anytime you wanna tell me to "go to the NXP forum", don't hesitate, I'm there already).

I assume the protocol discussed just prior to that diagram in section 23.4.1.2 and 23.4.1.3 use those addresses (0x00-0x3f) to retrieve the fusemap data.
The SDK provides code that does that, and I assume if I "unlock" and do a "write" it will burn in the bit (haven't tried that yet).

Then I discovered that the SDK header file also has a large overlay structure that is used to access the OCOTP registers.
Comments in that structure imply a direct mapping between OCOTP registers and the fusemap address space. For example,
each of the non-reserved fuse addresses of table 22.9 have a corresponding OCOTP register. Here's a snippet of that header
file showing the registers that correspond to the non-reserved fusemap addresses:

Code:
[FONT=Courier New]
__IO uint32_t LOCK;                /**< Value of OTP Bank0 Word0 (Lock controls), offset: 0x400 */
__IO uint32_t CFG0;                /**< Value of OTP Bank0 Word1 (Configuration and Manufacturing Info.), offset: 0x410 */
__IO uint32_t CFG1;                /**< Value of OTP Bank0 Word2 (Configuration and Manufacturing Info.), offset: 0x420 */
__IO uint32_t CFG2;                /**< Value of OTP Bank0 Word3 (Configuration and Manufacturing Info.), offset: 0x430 */
__IO uint32_t CFG3;                /**< Value of OTP Bank0 Word4 (Configuration and Manufacturing Info.), offset: 0x440 */
__IO uint32_t CFG4;                /**< Value of OTP Bank0 Word5 (Configuration and Manufacturing Info.), offset: 0x450 */
__IO uint32_t CFG5;                /**< Value of OTP Bank0 Word6 (Configuration and Manufacturing Info.), offset: 0x460 */
__IO uint32_t CFG6;                /**< Value of OTP Bank0 Word7 (Configuration and Manufacturing Info.), offset: 0x470 */
__IO uint32_t ANA2;                /**< Value of OTP Bank1 Word7 (General Purpose Customer Defined Info.), offset: 0x4F0 */
__IO uint32_t SJC_RESP0;           /**< Value of OTP Bank4 Word0 (Secure JTAG Response Field), offset: 0x600 */
__IO uint32_t MAC0;                /**< Value of OTP Bank4 Word2 (MAC Address), offset: 0x620 */
__IO uint32_t MAC1;                /**< Value of OTP Bank4 Word3 (MAC Address), offset: 0x630 */
__IO uint32_t GP1;                 /**< Value of OTP Bank4 Word6 (General Purpose Customer Defined Info), offset: 0x660 */
__IO uint32_t GP2;                 /**< Value of OTP Bank4 Word7 (General Purpose Customer Defined Info), offset: 0x670 */
__IO uint32_t SW_GP1;              /**< Value of OTP Bank5 Word0 (SW GP1), offset: 0x680 */
__IO uint32_t MISC_CONF0;          /**< Value of OTP Bank5 Word5 (Misc Conf), offset: 0x6D0 */
__IO uint32_t MISC_CONF1;          /**< Value of OTP Bank5 Word6 (Misc Conf), offset: 0x6E0 */
__IO uint32_t GP30;                /**< Value of OTP Bank7 Word0 (GP3), offset: 0x880 */
[/FONT]

Do these registers just provide an alternative mechanism for reading the shadow registers of the fusemap?
Very unclear to me...

Anyway, I'm still a bit confused, but at least I know that I am correctly reading the MAC fusebits,
and I guess I can just use that MAC address for systems that will have a network, true?
 
By the way, I am referencing the code in Teensyduino libs, but that's about it.
Just using GCC and teensy_loader_cli with a COM port tied to one of the UARTs for initial devel.
Painful, but a very good learning process.
My hope is to soon have my boot monitor on Teensy4.1 with 1 PSRAM chip and optional Ethernet.
Once I finish that, then I can get back to the audio work as an application that is launched out of
the monitor.
Lots of fun stuff, but quite frustrating with the limited documentation.
 
Painful, but a very good learning process.
....
Lots of fun stuff, but quite frustrating with the limited documentation.

Teensyduino tries to avoid requiring all this painful fiddling. I'm sure you have some good reason why you want to do all this, but we try very hard with Teensy's software to not require any of it.
 
Yup, understood.
Your environment is really nice; no question there.
I've got other iMXRT projects on the queue that a Teensy won't fit in,
so I need to climb this learning curve anyway.
Thanks much for your responses, and unfortunately for you, I'll be back!
 
Sorry if this is documented somewhere...
The 6 bytes of the MAC address are stored in OTP@22 and OTP@23 (relative to figure 23-2).
OTP@22 has the entire word programmed (4-bytes) and OTP@23 has the lower 2 bytes programmed...
Is it correct to assume the two bytes of OTP@23 are the upper 2 bytes of the MAC address
and the 4 bytes of OTP@22 are the lower 4?
 
Nevermind, I just verified that the MAC address that I use with the above orientation is in fact from PJRC...
Tx
 
From msg #2 in this thread:

Yes, it is prepropgrammed by pjrc.


And from msg #3:

Every Teensy 4.0 & 4.1 comes with a unique 48 bit mac address pre-programmed into those fuses. Those address are from a OUI for PJRC assigned by IEEE, so it is a proper mac address.

PJRC writes this mac address into every Teensy 4 during product testing. If you buy a chip directly from NXP, those fuses will be all zeros.
 
Status
Not open for further replies.
Back
Top