teensy 4 SVNS nonvolantile ram

Thanks, I have figuered it out!

Code:
#include "ILI9341_t3n.h"

ILI9341_t3n tft(255, //uint8_t _CS,
                28, // uint8_t _DC,
                255, //uint8_t _RST = 255,
                26, //uint8_t _MOSI=11,
                27, //uint8_t _SCLK=13,
                255); //uint8_t _MISO=12);

void setup() {
  SNVS_LPCR |= (1 << 24); // Enable NVRAM - documented in SDK (what SDK? where do I get this?!)
  
  tft.begin();
// Note: you can now set the SPI speed to any value
// the default value is 30Mhz, but most ILI9341 displays
// can handle at least 60Mhz and as much as 100Mhz
//  tft.setClock(60000000);
  tft.fillScreen(ILI9341_BLACK);
  tft.setTextColor(ILI9341_WHITE,ILI9341_BLACK);
  tft.setTextSize(1);
  tft.setRotation(0);
}


const char Nibble(uint32_t x) {
  x &= 0xF;
  return ((x < 10) ? '0' : ('A'-10)) + x;
}

const char *Hex(uint32_t x) {
  static char buf[12];
  buf[9] = '\0';
  buf[8] = Nibble(x); x>>=4;
  buf[7] = Nibble(x); x>>=4;
  buf[6] = Nibble(x); x>>=4;
  buf[5] = Nibble(x); x>>=4;
  buf[4] = ' ';
  buf[3] = Nibble(x); x>>=4;
  buf[2] = Nibble(x); x>>=4;
  buf[1] = Nibble(x); x>>=4;
  buf[0] = Nibble(x);
  return buf;
}

void loop(void) {
  tft.setCursor(0, 0);
  tft.println("IOMUXC_SNVS_GPR_GPR values, 4 Bytes each");
  tft.print("IOMUXC_SNVS_GPR_GPR0: ");
  tft.println(Hex(IOMUXC_SNVS_GPR_GPR0));
  tft.print("IOMUXC_SNVS_GPR_GPR1: ");
  tft.println(Hex(IOMUXC_SNVS_GPR_GPR1));
  tft.print("IOMUXC_SNVS_GPR_GPR2: ");
  tft.println(Hex(IOMUXC_SNVS_GPR_GPR2));
  tft.println("soneone fools around with the high word of IOMUXC_SNVS_GPR_GPR3 during boot");
  tft.print("IOMUXC_SNVS_GPR_GPR3: ");
  tft.println(Hex(IOMUXC_SNVS_GPR_GPR3));
  IOMUXC_SNVS_GPR_GPR0 += 1001;
  IOMUXC_SNVS_GPR_GPR1 += 2002;
  IOMUXC_SNVS_GPR_GPR2 += 3003;
  IOMUXC_SNVS_GPR_GPR3 = IOMUXC_SNVS_GPR_GPR2;
  tft.println("now turn off and on again");
  while (1) delay(1000);
}

A little sad that there are just 16Bytes - or rather only 14 bytes, because 2 are overwritten by the bootloader with eigther 8 or 9. What a waste.
Not 16kB like the above documentation suggests.
And the memory really starts literally at 0x400A_4000 like in the documentation, but the end is not 0x400A_7FFF but much sooner.

Code:
imxrt.h:#define IMXRT_IOMUXC_SNVS_GPR	(*(IMXRT_REGISTER32_t *)0x400A4000)
imxrt.h:#define IOMUXC_SNVS_GPR_GPR0		(IMXRT_IOMUXC_SNVS_GPR.offset000)
imxrt.h:#define IOMUXC_SNVS_GPR_GPR1		(IMXRT_IOMUXC_SNVS_GPR.offset004)
imxrt.h:#define IOMUXC_SNVS_GPR_GPR2		(IMXRT_IOMUXC_SNVS_GPR.offset008)
imxrt.h:#define IOMUXC_SNVS_GPR_GPR3		(IMXRT_IOMUXC_SNVS_GPR.offset00C)
 
This post shows usage of the known 4 DWORDS of battery backed storage: Teensy-4-x-Battery-backed-Non-volitile-memory?p=281008&viewfull=1#post281008

Not seen any discovery or work on the indicated area. Compare the linked code and maybe it shares something ...

Wow! A hidden feature! I have had a look at the sketch in your link, and it seems to me that there are at least 16 more battery-backed bytes at this address:
Code:
uint32_t *NVRAM_UINT32 = ((uint32_t *)0x400D4100);
I have verified that these are independent of the 16 bytes in IOMUXC_SNVS_GPR_GPR[0123], So now i have already 30 bytes of persistent storage!
Thank you! Perhaps there are still more at NVRAM_UINT32[4] and later, I will try.
 
At 0x400D4100 there ar 32 additional bytes of NVRAM apart from the 16-2 Bytes at 0x400A_4000. All these bytes are persistent as long as the battery is plugged in. When the battery is removed while the teensy is turned off, the Bytes become not undefined, but ZERO. Very neat. This is my sketch:
Code:
#include "ILI9341_t3n.h"

ILI9341_t3n tft(255, //uint8_t _CS,
                28, // uint8_t _DC,
                255, //uint8_t _RST = 255,
                26, //uint8_t _MOSI=11,
                27, //uint8_t _SCLK=13,
                255); //uint8_t _MISO=12);

void setup() {
  SNVS_LPCR |= (1 << 24); // Enable NVRAM - documented in SDK (what SDK? where do I get this?!)
  
  tft.begin();
// Note: you can now set the SPI speed to any value
// the default value is 30Mhz, but most ILI9341 displays
// can handle at least 60Mhz and as much as 100Mhz
//  tft.setClock(60000000);
  tft.fillScreen(ILI9341_BLACK);
  tft.setTextColor(ILI9341_WHITE,ILI9341_BLACK);
  tft.setTextSize(1);
  tft.setRotation(0);
}


const char Nibble(uint32_t x) {
  x &= 0xF;
  return ((x < 10) ? '0' : ('A'-10)) + x;
}

const char *Hex(uint32_t x) {
  static char buf[12];
  buf[9] = '\0';
  buf[8] = Nibble(x); x>>=4;
  buf[7] = Nibble(x); x>>=4;
  buf[6] = Nibble(x); x>>=4;
  buf[5] = Nibble(x); x>>=4;
  buf[4] = ' ';
  buf[3] = Nibble(x); x>>=4;
  buf[2] = Nibble(x); x>>=4;
  buf[1] = Nibble(x); x>>=4;
  buf[0] = Nibble(x);
  return buf;
}

uint32_t *NVRAM_UINT32 = ((uint32_t *)0x400D4100);

void loop(void) {
  tft.setCursor(0, 0);
  tft.println("IOMUXC_SNVS_GPR_GPR values, 4 Bytes each");
  tft.print("IOMUXC_SNVS_GPR_GPR0: ");
  tft.println(Hex(IOMUXC_SNVS_GPR_GPR0));
  tft.print("IOMUXC_SNVS_GPR_GPR1: ");
  tft.println(Hex(IOMUXC_SNVS_GPR_GPR1));
  tft.print("IOMUXC_SNVS_GPR_GPR2: ");
  tft.println(Hex(IOMUXC_SNVS_GPR_GPR2));
  tft.println("soneone fools around with the high word of IOMUXC_SNVS_GPR_GPR3 during boot");
  tft.print("IOMUXC_SNVS_GPR_GPR3: ");
  tft.println(Hex(IOMUXC_SNVS_GPR_GPR3));
  IOMUXC_SNVS_GPR_GPR0 += 1001;
  IOMUXC_SNVS_GPR_GPR1 += 2002;
  IOMUXC_SNVS_GPR_GPR2 += 3003;
  IOMUXC_SNVS_GPR_GPR3 = IOMUXC_SNVS_GPR_GPR2;

  tft.println("\ntesting NVRAM at 0x400D4100:");
  uint32_t x = NVRAM_UINT32[0];
  int i = 0;
  if (x) {
    do {
      i++;
      x = 0x12345679*x+0x456789AB;
    } while (NVRAM_UINT32[i]==x && i<16);
    if (i >= 16) tft.print("at least ");
    tft.print(4*i);
    tft.println(" bytes");
  } else {
    do {
      i++;
    } while (NVRAM_UINT32[i]==0 && i<16);
    tft.print(4*i);
    tft.println(" bytes are ZERO");
  }
  x = 1+NVRAM_UINT32[0];
  for (i=0;i<16;i++) {
    NVRAM_UINT32[i] = x;
    x = 0x12345679*x+0x456789AB;
  }
  tft.println("now turn off and on again\n");

  while (1) delay(1000);
}

Since the 32bytes at 0x400D4100 become ZERO again when turned off and battery disconnected, I believe that these addresses have no meaning other than storing persistent data.
The doc I have says nothing about this address range. And in imxrt.h I also find nothing.
 
Didn't yet look into any added areas noted.

Note the 4 DWORDS linked in p#2 are only 32 bit writeable as 4 bytes.
 
Back
Top