Is there a hook to know when the on/off pin on the Teensy 4.0 has been grounded?

@Defragster:
I'm not sure what the "reserved" Bit24 does exactly, but it helps (and seems to work now):
Code:
void setup() {
  Serial.println(IMXRT_SNVS.offset100, HEX);
  Serial.println(IMXRT_SNVS.offset104, HEX);
  SNVS_LPCR |= (1<<24); //Enable NVRAM(?!) - undocumented
  IMXRT_SNVS.offset100 = 0xbeef;
  IMXRT_SNVS.offset104 = 0x1234;
  Serial.println(IMXRT_SNVS.offset100, HEX);
  Serial.println(IMXRT_SNVS.offset104, HEX);
... 
reset or power down
Note, Bit 24 must be set before write(?) - found it by try and error. Tested without battery - power dwn and reset only.
I've fixed a little issue in the library (SNVS reset not needed), please download again. It's needed here.

One should measure/verify the power consumption on power off - with bit 24 set and without.
Could that it enables ways more..?
 
Last edited:
A demo for that:
Code:
#include "T4_PowerButton.h"

void myCallback(void) {
  digitalWriteFast( 13, 1);
  Serial.println ("Callback called - Switching off now.");
  delay(100);
}

void setup() {
  pinMode(13, OUTPUT);
  Serial.begin(115200);
  while (!Serial && millis() < 4000 );

  if (arm_power_button_pressed()) {
    Serial.println("Restart after power down");
  } else {
    Serial.println("First power on");
  }

  Serial.println(IMXRT_SNVS.offset100, HEX);
  Serial.println(IMXRT_SNVS.offset104, HEX);
  SNVS_LPCR |= (1<<24); //Enable NVRAM(?!) - undocumented
  IMXRT_SNVS.offset100 = 0xbeef;
  IMXRT_SNVS.offset104 = 0x1234;
  Serial.println(IMXRT_SNVS.offset100, HEX);
  Serial.println(IMXRT_SNVS.offset104, HEX);
  set_arm_power_button_callback(&myCallback); //Start callback

}

uint32_t tm = millis();
void loop() {
  digitalWriteFast( 13, !digitalReadFast(13));
  delay(100);
  if (millis() - tm > 10000) {
    Serial.println("\n\nReset!!!!!");
    delay(500);
    arm_reset();
  }
}
 
Last edited:
… telling me this post is too short ... ???
@Defragster:
I'm not sure what the "reserved" Bit24 does exactly, but it helps (and seems to work now):
Code:
void setup() {
  Serial.println(IMXRT_SNVS.offset100, HEX);
  Serial.println(IMXRT_SNVS.offset104, HEX);
[B][U][COLOR="#FF0000"]  SNVS_LPCR |= (1<<24); //Enable NVRAM(?!) - undocumented[/COLOR][/U][/B]
  IMXRT_SNVS.offset100 = 0xbeef;
  IMXRT_SNVS.offset104 = 0x1234;
  Serial.println(IMXRT_SNVS.offset100, HEX);
  Serial.println(IMXRT_SNVS.offset104, HEX);
... 
reset or power down
Note, Bit 24 must be set before write(?) - found it by try and error. Tested without battery - power dwn and reset only.
I've fixed a little issue in the library (SNVS reset not needed), please download again. It's needed here.

One should measure/verify the power consumption on power off - with bit 24 set and without.
Could that it enables ways more..?

THAT DOES IT - GREAT FIND Frank! I did some searches and scanning of NXP docs and I found no indications of what you explored to find.

I can now write to those four DWORDS!

Once that bit is set it stays while powered USB or RTC vBat. That bit auto resets on full power loss. But I don't see any trouble in always setting it.

Here is sample code showing the two ways used to index to that 128 bits of NVRAM with 'NVRAM_UINT32':
Code:
// #define NVRAM_UINT32 ((uint32_t *)0x400D4100)
uint32_t *NVRAM_UINT32 ((uint32_t *)0x400D4100);

elapsedMillis tSome;
uint32_t lOne = NVRAM_UINT32[0];
void setup() {
	SNVS_LPCR |= (1 << 24); //Enable NVRAM(?!) - undocumented
	Serial.begin(115200);
	while (!Serial && millis() < 4000 );
	Serial.println("\n" __FILE__ " " __DATE__ " " __TIME__);
	tSome = 0;
}
void loop() {
	if ( tSome >= 1000 ) {
		tSome -= 1000;
		for ( int ii = 0; ii < 4; ii++ ) {
			Serial.print( "  " );
			Serial.print( NVRAM_UINT32[ii], HEX );
		}
		Serial.print( "  diff =" );
		Serial.print( NVRAM_UINT32[0] - lOne );
		Serial.println();
		lOne = NVRAM_UINT32[0];
	}
	for ( int ii = 0; ii < 4; ii++ ) {
		NVRAM_UINT32[ii]++;
	}
}

Here is sample output - the diff count is pretty low for updating for a second? I wonder how slow the access is?
1118AD 1118AC 10764F 10764C diff =1365
111E01 111E00 107BA3 107BA0 diff =1364
112356 112355 1080F8 1080F5 diff =1365
1128AB 1128AA 10864D 10864A diff =1365
 
@Frank, thanks a lot for the library.
You implemented the T4.0 software reset function that many people were looking for.
Great work!
 
It also allows a faster power-off with the button (use a empty callback).

for the records: If you want to start the bootloader from your program: asm("bkpt #251");
 
For those cases where expected Restart stops in bootloader - that may be on Paul's list to address as possible.
 
Tim,
maybe it's so slow because it is clocked by the 32khz crystal.
Just a guess.

It must relate to that Frank.
I did a quick edit to write only 1 of the four when updated from a RAM value {rather than read inc and write of all four NVRAM's} and it went to 10915 updates / second from 1365/sec.
 
I've added hardfault-handling to the T4_PowerButton library (need to update its name someday)

Just #include <T4_PowerButton.h> that is all to do.

In case of a hardfault, the Teensy will reset and print the reason.
Yout look for the return address in the symbol file which is created during compilation to find out where it crashed.

Example:
Code:
#include <T4_PowerButton.h>

#define  ADDR   (*(volatile uint32_t *)0xdeadbeef)

void errAddr() {
  //Program will crash here:
  
 // access not allowed address:
 // [COLOR=#ff0000]ADDR = 9;  //<-- Crash here[/COLOR]
 
 //Nullptr:
 int32_t * p = nullptr; 
 [COLOR=#ff0000]*p = 7;//<-- Crash here[/COLOR]
}


void setup() {
  
  pinMode(LED_BUILTIN, OUTPUT);
  while(!Serial);
  digitalWriteFast(LED_BUILTIN, HIGH);
  Serial.println("Start");  
  delay(2); 

  errAddr();
}


void loop() {
  digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN) );
  delay(750);
}

Output:
Code:
Hardfault.
Return Address: 0x00000[COLOR=#40e0d0]1BA[/COLOR] IPSR:0x03 CSFR: 0x00000082 XPSR: 0x61010000
    (DACCVIOL) Data Access Violation
    (MMARVALID) Accessed Address: [COLOR=#ff0000]0x00000000 <-- nullptr from above[/COLOR]

If you look now at the symbol file:
Code:
00000174 00000068 T setup
000001dc 0000002c T loop
0x1BA is somewhere in setup(). void errAddr() was optimized away. The address is more usable if you turn off optimizations.

Most of the code is taken from startup.c, and written by Paul.

I'm looking for a way to enable divbyzero exceptions, now.
 
Last edited:
SCB_CCR = 0x10; //Enable "Div By Zero" exceptions

Another fun find by FrankB :) When I was looking at the fault handler code I wondered why that went 'ignored'.

@mjs513 typed in the value check and "naming" for the Faults, that code as noted in startup.c I found at community.nxp.com/thread/389002 that was working when enabled in Beta, but having it show on boot is handy.

Looks like you did good incorporating that for the T_4.x's - had been meaning to get back to that but never seemed to come up often enough to keep my attention for the debug stuff I did on 3.x's then 4.x's ...

Not sure if that link above (similar area or a search) had some notes about stack trace following - but it wasn't clear

Did you see the NXP 1070 doc just noted? Apparently there is a large static ram on chip - 4 KB or Kbit? I'll email it.
 
Maybe you want to add this to the T3, too? You'll need a storage area which survives a reset.
You could do write a lib that supports both, T3 & t4. Feel free to use the code from T4_PowerButton.

Did you see the NXP 1070 doc just noted? Apparently there is a large static ram on chip - 4 KB or Kbit? I'll email it.
Thank you for the doc!
Oh I bet we'll find a usage for these 4K :)
 
Added temperature panic print.
After that, it shuts down, as before - I think, that's the best in this case.
 
This thread is a very interesting read indeed!

I'm looking to implement the power switch functionality, but it seems that the T4_PowerButton library is gone... Has it moved somewhere else? Are there other alternatives?
 
I've set it back to "Public".

This functionality should *really* be in the official Teensyduino.
It's not a task for a user contributed lib.

(And at least for some time I'll will not contribute such things anymore, as I've seen too many cases where some were just copying my code but "forgot" license files and header comments.)



https://github.com/FrankBoesing/T4_PowerButton/
 
Back
Top