2290461_en-US

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

2290461_en-US

2290461_en-US

MM9z1J638D Timed wakeup by PTBx only works for once

Hi there,


I got the timed wakeup function working with PTB1. But it only would wake up once from PTB1. Everything seems fine after the first wakeup, LIN and application code running no problem.


The second time going to SLEEP mode, the uC seems to go to a different state that I can't understand

  1. the current draw slightly drops from normal operation, unlike the first time it goes to sleep where the current is basically zero
  2. debugger loses connection and cannot reconnect
  3. uC becomes secured.

The only way to get out of this state is by power cycling. 


One more observation is that if the wakeup is triggered by LIN, there seems no issue waking up multiple times. Only if the wake up is triggered the timed wakeup PTB1, the issue occurs.


Here's my SLEEP mode configuration

#define  Wakeup_counter  (unsigned int) 10*1000 // counter value in terms of ALFCLK (1ms by default)
char Wakeup_counter_hi = (char) ((Wakeup_counter & 0xFF00U) >> 8); // get the high byte
char Wakeup_counter_lo = (char) ((Wakeup_counter & 0x00FFU) >> 0); // get the low byte

void Handle_SleepRequest()
{
....... // save parameters to EEPROM
RTIDisable(); 
ADCDisable();											
TsenseDisable();
B_GPIO_VSENSE = 0;
l_sys_irq_disable(BSC2_Node1);  	// only SCI!!!						
B_TIE_C3I = 0;	// LIN timer interrupt disabled										
IrqDisable();
B_GPIO_IN1_TCAP1 = 0; // PTB1 input buffer disconnected from Timer channel 1 - input capture
B_GPIO_OUT1_TCOMP1 = 1; // Timer channel 1 - output compare connected to PTB1 output buffer OR gate (needs to be configured to allow OC to generate a system wakeup)
B_GPIO_CTL |= B_GPIO_CTL_DIR1_MASK | B_GPIO_CTL_DIR1M_MASK; // set PTB1 to output 
B_GPIO_CTL |= 0|B_GPIO_CTL_PE1M_MASK; // PTB1 I/O to high impedance mode so that it's not connected to outside of MCU

// force internal PTB1 to low
B_TSCR1_TEN = 1;
B_TCTL1 	= B_TCTL1_OM1_MASK;           // clear on OC
B_CFORC_FOC1 = 1;          		// force OC to clear because TCTL1 set to clear on OC
B_TSCR1_TEN = 0; 		// disable the timer to setup timer
B_TCNT 		= 0x0000U; // reset counter 
B_TIOS_IOS1 = 1; // Timer channel 1 acts as an output compare to allow TC1 write	
/*Timer clock selection to be Timerclk/1 see table 647*/
B_TSCR2_PR0 = 0;
B_TSCR2_PR1 = 0;
B_TSCR2_PR2 = 0;

B_TSCR2_TCRE = 0; //Inhibits timer counter reset and couter continuews to run

			

// setup a rising edge on hitting the OC
B_TCTL1  	 = B_TCTL1_OM1_MASK | B_TCTL1_OL1_MASK; // configure to be set on OC
B_TC1Hi      = Wakeup_counter_hi; // compare register needs to write the high byte before low byte
B_TC1Lo      = Wakeup_counter_lo;
B_TFLG1_C1F  = 1; 					// enable Timer channel 1 to cause a hardware interrupt

ADCLpEnable();
B_PCR_WUEH_WUPTB1 = 1;	 // enable PTB1 as the internal timed wake up source
PCREnterSleepMode();
while(1) DO_NOTHING;	// should not reach here
}

 My wakeup handling function 

void Wakeup_Process(void){
if (B_PCR_CTL_OPM & 2) 
{       // Check if Wake Up from Sleep mode (see page RM3.0 110 Intermediate Mode)
       B_PCR_CTL = OPM_SET_NORMAL; // set normal mode
       while (!(B_PCR_SRH_WLPMF )) DO_NOTHING; // Wait for Clock Domain Change   
    }
else{
       if(!B_PCR_SR_HWRF) {
          PCRReset(); 
    	         }
	}
}

main function


void main ()
{
        SYS_Init();
	CPMUInit(&ClockConf);
	D2DInit((TYPE_D2DCLKDIV) ClockConf.D2dDiv);												
	XirqEnable(); // enable XIRQ -> isrD2DErr() "write-once" 

	Wakeup_Process(); // Process wakeup event to bring CPU to normal if it is waken up
	B_WD_CTL = WD_OFF;    	
	PCRInit(ClockConf.PCRprescaler);
	SYSStartupTrimming();
        ADCInit();
        GPIOInit();
	RTIInit();
	RTIEnable();
	IrqEnable();
	EEPROM_Init(0x05);// 6.25MHz busclk
        ReadEEPROM();
        for EVER {
                    ...... // main application loop
                    if (SleepRequested){Handle_SleepRequest();}
                 } 

}

Appreciate your help.

Re: MM9z1J638D Timed wakeup by PTBx only works for once

They are already cleared in PCREnterSleepMode() function.

void PCREnterSleepMode_SMP(void){


  IrqDisable();       

  B_INT_MSK = 0xFF3F;     // Mask Analog Interrupts 
  B_ACQ_SRH = 0xFF;       // Clear pending Flags
  B_INT_MSK = 0xFF00;     // Enable Analog Int 

  B_PCR_SR =  0xFFFF;     // Clear Flags
  B_TFLG1  =  0xFF; 	  // Clear timer interrupt flag1
  B_PCR_CTL = OPM_SET_SLEEP;  	// Goto Sleep Mode
  StopEnable();		
  StopEnter();
}

But I think I found out the problem. I have a decondition function executed everytime the wakeup happens, that reverses the PTB1 configuration as the opposite of configuring PTB1 for wake-up source, like resetting counter OC, reversing GPIO configuration, etc. But the problem seems to be the resets don't register unless I put a while loop to check if the registers are updated. For example, if I don't put the while loop, the TC1 counter still holds the period I set up before going to sleep even though I am setting TC1 to 0x0000 in the deconditioning function. 

Now that I added a while loop check to make sure the registers are reset, the wake-up functions normally and succeeds every time.

void PTB1_WU_Decondition(allow_Continue){
	/* Configure port before enable it*/
	B_GPIO_IN1_TCAP1 = 0; // PTB1 input buffer disconnected from Timer channel 1 - input capture
	// B_GPIO_IN1_TCAP1 = 1; // PTB1 input buffer disconnected from Timer channel 1 - input capture
	B_GPIO_OUT1_TCOMP1 = 0; // Timer channel 1 - output compare connected to PTB1 output buffer OR gate (needs to be configured to allow OC to generate a system wakeup)
	B_GPIO_CTL |= 0 | B_GPIO_CTL_DIR1M_MASK; // set PTB1 to output 
	// B_GPIO_CTL |= 0 | B_GPIO_CTL_DIR1M_MASK; // set PTB1 to input 
	// B_GPIO_CTL |= B_GPIO_CTL_PE1_MASK|B_GPIO_CTL_PE1M_MASK; // PTB1 I/O enable mask enabled PTB1 enabled (not seem necessary due to figure 33.)
	B_GPIO_CTL |= 0|B_GPIO_CTL_PE1M_MASK; // PTB1 I/O to high impedance mode so that it's not connected to outside of MCU


	

	B_TIOS_IOS1 = 0; // Timer channel 1 disabled
	/*				Timer clock selection to be Timerclk/1 see table 647*/
	B_TSCR2_PR0 = 0;
	B_TSCR2_PR1 = 0;
	B_TSCR2_PR2 = 0;

	B_TSCR2_TCRE = 0; //Inhibits timer counter reset and couter continuews to run



	// setup a rising edge on hitting the OC
	
	B_TSCR1_TEN  = 1; 					// enable the timer to reset TC1
	B_TC1Hi      = 0x00U; 				// compare register needs to write the high byte before low byte
	B_TC1Lo      = 0x00U;
	B_TSCR1_TEN = 0; 					// disable the timer
	B_TFLG1_C1F  = 1; 					// clear timer 1 flag
	while(B_TFLG1_C1F != 0 && B_TC1 != 0x0000U || allow_Continue){}; // MUST WAIT otherwise, the settings don't register
	B_PCR_WUEH_WUPTB1 = 0;				// disable PTB1 as the internal timed wake up source

}

Re: MM9z1J638D Timed wakeup by PTBx only works for once

Hi @WWsmp,

The read-after-write sequence is a good practice.

Maybe you can rearrange the function, will it pass without the wait loop?

B_GPIO_OUT1_TCOMP1 = 0;// Detach OC from PTB1
B_GPIO_IN1_TCAP1= 0;// No capture routing
B_GPIO_CTL|= B_GPIO_CTL_DIR1M_MASK;// Internal buffer direction benign
B_GPIO_CTL|= B_GPIO_CTL_PE1M_MASK;// High impedance to outside
B_TSCR1_TEN= 0;// Stop counter

B_TIOS_IOS1= 1;// Channel 1 acts as Output Compare
B_TCTL1&= ~(B_TCTL1_OM1_MASK | B_TCTL1_OL1_MASK);// No OC action
B_TSCR2_PR0 = 0;
B_TSCR2_PR1 = 0;
B_TSCR2_PR2 = 0;

B_TFLG1_C1F= 1;// write-1-to-clear
B_TCNT= 0x0000U;// ensure counter starts from 0
B_TC1Hi= 0x00U;// high byte first
B_TC1Lo= 0x00U;

B_TSCR1_TEN= 1;
B_PCR_WUEH_WUPTB1  = 0;

Re: MM9z1J638D Timed wakeup by PTBx only works for once

Hi @danielmartynek ,


I thought I fixed it but actually it is not 100% working. The issue still persists but in a different way now that I added the while loop. It looked like I was able to put the uC sleep and wake up consistently but the PCRReset() was somehow triggered but not from my application. The PCRReset() is triggered by isrD2DErr(). 

/*! \brief Interrupt Service Routine for D2D error interrupts. 
 * 
 * Interrupts are caused by errors detected by the D2D Initiator (uC side) 
 * during D2D transferes. This error is critical NMI and you need to have the
 * CCR X-bit cleared 
  */
interrupt VectorNumber_Vd2di_err void isrD2DErr(void)  {

	while(1)  {
		if(D2DSTAT0_ERRIF)  {
			D2DSTAT0_ERRIF = 1;											// clear flag
		}else{
			PCRReset();													// issue an analog die reset 
		}
	}
}

How I realized it is that I have a variable saving the wakeup reason and reset reason. Normally, when it wakes up from PTB1, B_PCR_SRL_WUPTB1F is set to 1 and B_PCR_SRH_HVRF is set to 1. But after my "fix", I realized B_PCR_SRH_HVRF, B_PCR_SRH_WDRF and B_PCR_SRH_HWRF are all set to 1 and no WU bits are set. It is like the behavior I'd call PCRReset(). And I traced down to D2D error. 


Is there a specific reason you would think of that can trigger this error? 

Re: MM9z1J638D Timed wakeup by PTBx only works for once

Hi @WWsmp,

Let me trigger a discussion with the development team.

It may take some time.


Thank you,

Daniel

Re: MM9z1J638D Timed wakeup by PTBx only works for once

Hi @WWsmp,

No issue has been found in the code you posted.

Below is the possible source of isrD2Derr errors. The isrD2Derr indicates that an error was detected on the Die‑to‑Die (D2D) interface between the Analog Die and the MCU (S12Z) Die. The error can be caused by electrical, timing, power, mode‑control, or software issues.


  1. Power Supply–Related Issues
  • VDDH / VDDD2D (2.5 V D2D supply) instability
    • Voltage dips, ripple, or insufficient decoupling can corrupt D2D signaling.
    • Often results in parity errors or acknowledge errors.
  • Supply sequencing problems
    • One die becomes operational earlier than the other.
    • D2D access occurs while the target die is still in reset or brown‑out.
  • Cranking or VSUP undervoltage
    • During automotive cranking, one die may enter reset or retention while the other continues running.
    • Leads to timeout errors.
  1. Clock and Timing Problems
  • D2D clock instability
    • PLL unlock, IRC drift, or clock monitor events can break D2D timing.
  • Excessive D2D clock frequency margin
    • Running close to the maximum D2D frequency reduces noise margin.
    • More sensitive to EMC and temperature.
  • Clock domain mismatch
    • One die clock gated or slowed while the other continues issuing D2D transactions.
  1. Reset and Power‑Mode Synchronization Errors
  • Asynchronous reset between dies
    • MCU resets while analog die stays active (or vice versa).
    • Any D2D access during this window triggers timeout or ACK error.
  • Stop / Sleep mode mismatch
    • MCU enters STOP/SLEEP while analog die remains in NORMAL mode.
    • D2D access attempted while the target die clock is gated.
  • Improper wake‑up sequence
    • D2D transaction issued before the target die has fully exited low‑power mode.
  1. D2D Protocol / Transaction Timing Issues
  • Timeout due to delayed servicing
    • Long interrupt masking or critical sections block D2D servicing.
    • High ISR load or long non‑preemptible code paths.
  • Excessive burst access
    • Large or rapid sequences of D2D register reads/writes without spacing.
    • Can exceed internal service latency.
  • Invalid or illegal D2D access
    • Access to unmapped or restricted D2D register windows.
    • Incorrect transaction size or sequence.
  1. Software Initialization and Configuration Errors
  • Startup trimming not executed correctly
    • IFR values not copied at startup.
    • Leads to clock/reference drift and higher bit‑error probability.
  • Improper D2D initialization order
    • D2D used before clocks, power domains, or error flags are fully cleared.
  • Conflicting configuration modes
    • Automatic temperature gain compensation (ATGCE) enabled together with calibration request interrupts.
    • Causes excessive D2D traffic and contention.
  1. EMC, Noise, and Environmental Stress
  • EMI / ESD disturbances
    • Fast transients can flip D2D data bits, causing parity errors.
    • Common during ISO 7637‑2 pulse tests.
  • Ground bounce or poor grounding
    • Shared return paths with high current (shunt, LIN, CAN).
    • Affects D2D signal integrity.
  • High temperature or thermal gradients
    • Clock drift and regulator derating increase timing margin violations.
  1. Layout and Hardware Implementation Issues
  • Insufficient decoupling near VDDH/VDDD2D pins
  • Poor separation between analog, digital, and high‑current paths
  • Reference design deviations
    • Missing or altered filtering components compared to NXP reference designs.

BR, Daniel

Tags (1)
No ratings
Version history
Last update:
‎01-28-2026 04:22 AM
Updated by: