MKL28 How to disable NMI_b on PTA4

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

MKL28 How to disable NMI_b on PTA4

2,667 Views
mci
Contributor III

Hi,

We have a problem on POR of MKL28 due to newer HW circuit connected to its pin 38 (PTA4) which is causing NMI on power-up & gets stuck in while(1){} loop.   That's because by default PTA4 is configured as ALT7 or "NMI_b" & MCU could be detecting a low input (-NMI) signal on that pin from the HW ckt which enables NMI.

Otherwise, if bootup reached my firmware, PTA4 will be assigned as ALT1, normal GPIO/output.

I've done some readings and from MKL28Z512V datasheet, page 72, I have do 2 things to disable NMI:

1.  remap NMI interrupt handler to other pin function (normal FW will do that).

2.  Disable NMI function by clearing FOPT[NMI_DIS] bit to zero which will take effect on next POR.

I found this 2013 post that shows how to disable NMI inside CodeWarrior IDE(?) for KL15.

https://community.nxp.com/thread/310241

(See image re-shown here below)

Does anyone know how I can do the same inside MCUXpresso for KL28 MCU?

Or better, how do I do steps 1 and 2 stated above in code?

I don't see any SDK example on this matter.

Thanks for the help.

MI

This is for MKL15 MCU:

NMI_MKL15.png

Labels (1)
6 Replies

2,447 Views
mci
Contributor III

Continuation...

Hi again, Robin.

So I changed flash config's 13th byte at 0x40d to be 39h whereby bit 2 NMI_DIS is changed from 1 (enable NMI) to 0 (disable NMI).

First, that's all I did. 

Please note that PTA4 is driving the base of an NPN transistor which will amplify the LED to reach its maximum lit intensity when turned on.   Basically, the application FW sets PTA4 (default alt 7= NMI_b) to alt1 = plain PTA4 output.

After flashing and going to in-service normal operation, the LED is turned on (1) by the app.

PROBLEM STILL THERE:

However, if reset or powered-off, the board goes to this on state & still hangs & LED stays on - which to me means it is stuck inside the NMI interrupt handler(?)

So I tried 3 ways to do something inside the NMI interrupt handler - still none worked - stays hang & LED stays on - never going / proceeding to my application.

Within startup_mkl28z7.c :

1)  removed the while(1) forever loop, & do nothing else - my thought is it will proceed to the rest of initialization to go to the application FW.

2)  directly add the pin-muxing and setup of PTA4 inside the NMI function.

3)  de-reference the default NMI handler such that on the upper level application FW, the low level NMI handler will be redirected to my own NMI handler where PTA is configured as alt1 GPIO, initialized and such.

All the while I have kept NMI_DIS bit = 0 (0x40d = 39h).  

Is that wrong?   If I'm putting up the NMI interrupt handler, whether method 1,2 or 3, should I have put back 0x40d = 3dh? (NMI_DIS = 1)?

Are those directives 1 and 2 I stated originally supposed to be BOTH to do?  or EITHER-OR do?

That's the case since this morning & I have set this issue aside because I need to move on to other things to do.

Meanwhile, since we have a "spare" pin to use, our HW engineer left PTA4 floating (high) by disconnecting it from the NPN transistor base and we transferred the LED to another pin.   This is our quickfix for now. 

Unless someone can direct me how to code the NMI function or if it is do both ways or either-or way clearly,  I will not come back to this matter until after the prototype we're developing is complete.

So please let me know if you have idea where I did wrong.

Thanks,

MI

0 Kudos
Reply

2,447 Views
mjbcswitzerland
Specialist V

Hi

Beware that PTA4 is also the BOOTCFG0 input (if not disabled) so you may indeed be disabling the NMI but a '0' on PTA4 still causes the ROM loader to be entered, which looks like it is hanging too.

You can spot this with the debugger because the program counter will be in the 0x1c000000 area (the ROM).

To disable the BOOTCFG0 pin you can set bit 1 to '1'.


I have seen that the new SDK has made some progress in that the flash parameters are not in an assembler file but I see that there are still no user-friendly defines for the content, meaning that one has to carefully count bytes and bits and hopefully not make too many mistakes in the process.
I tend to use:

#define KINETIS_FLASH_CONFIGURATION_NONVOL_OPTION  (FTFL_FOPT_LPBOOT_CLK_DIV_1 | FTFL_FOPT_RESET_PIN_ENABLED | FTFL_FOPT_BOOTSRC_SEL_FLASH | FTFL_FOPT_BOOTPIN_OPT_DISABLE | FTFL_FOPT_NMI_DISABLED)

for the KL28, which gives

pastedImage_2.png

However (!!), there is also a further point to be careful of. The debugger that is used may NOT program the values that you intend since they often refuse to program all possible settings in an effort to avoid one unwittingly setting a mode that could disable the debug interface forever. Therefore always read back the values with a debugger to be sure that it is as intended. For example, if one programs with IAR and the P&E debugger the data 'actually' written is as follows and so the behavior is not as intended, even though the code is correct....

pastedImage_1.png

Regards

Mark

0 Kudos
Reply

2,447 Views
mci
Contributor III

   (Edited to only change bit 2 of flash config byte 0x40d which is exactly the NMI_DIS bit.  So value 00111101 (0x3d) becomes 00111001 (0x39.)

Hi Robin,

THAT'S WHAT I'M LOOKING FOR!   I went to "startup" yesterday but I ignored & did not open the startup_mkl28z7.c file.   So I'll just replace single byte position 0x40d which says "0x3d" with "0x39" as stated on instruction in the reference manual?    Where NMI_DIS bit 2 changes from 1 to 0.

And if I do that, I don't need to supply any alternate function for this hanging while-loop NMI handler in startup file?  That's where it hangs.

WEAK_AV void NMI_Handler(void)

{ while(1) {}

}

Please confirm if my understanding is correct.

Thanks so much for the help. 

MI

0 Kudos
Reply

2,447 Views
Robin_Shen
NXP TechSupport
NXP TechSupport

Hi MI,

Please find the Flash_Config in startup_mkl28z7.c then modify it.

Flash_Config.png

Best Regards,

Robin

 

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

2,447 Views
mjbcswitzerland
Specialist V

Hi

I think that in the SDK you need to search for an assembler file that contains the byte sequence that is set at 0x400. You must know where the value is situated and change it accordingly.

In the uTasker project it is done with a user define so controlled purely in C code which makes it easier to use. Eg.:

#define KINETIS_FLASH_CONFIGURATION_NONVOL_OPTION  (FTFL_FOPT_LPBOOT_CLK_DIV_1 | FTFL_FOPT_RESET_PIN_ENABLED | FTFL_FOPT_BOOTSRC_SEL_FLASH | FTFL_FOPT_BOOTPIN_OPT_DISABLE | FTFL_FOPT_NMI_DISABLED) // never use boot ROM

Note that FTFL_FOPT_NMI_DISABLED means that 0x04 is set to '0'.

If you prefer to leave the NMI option enabled but control it in code this is how it is done (the uTasker has the option #define NMI_IN_FLASH for this configuration).

1. Put an NMI handler in the vector in Flash (it has to be in flash at address 0x00000008). Eg. a routine called irq_NMI()

2. Have a handler that reconfigures the NMI pin to be a GPIO input. Eg, for the KL28 the uTasker project does:

static void irq_NMI(void)
{
    _CONFIG_PORT_INPUT_FAST_LOW(A, PORTA_BIT4, PORT_PS_UP_ENABLE);       // set the NMI line to an input to remove the NMI function and allow the processor to continue
}

This will immediately clear the pending NMI and allow the processor to boot.

3. If you later want to use the NMI you can enter a new handler (in RAM) and re-enable the NMI pin.

The uTasker KL28 code does:

// Allow the user to enter an NMI handler, ensuring that the NMI pin is configured as NMI function
// - note that the NMI may not have been disabled to allow this to work
//
extern void fnEnterNMI(void (*_NMI_handler)(void))
{
    VECTOR_TABLE *ptrVect = (VECTOR_TABLE *)(RAM_START_ADDRESS);
    ptrVect->ptrNMI = _NMI_handler;                                       // enter interrupt handler
    _CONFIG_PERIPHERAL(A, 4, (PA_4_NMI | PORT_PS_UP_ENABLE));¨// // set the NMI pin function
}

Regards

Mark

0 Kudos
Reply

2,447 Views
mci
Contributor III

Thanks, Mark.  

I was looking more for the solution as what Robin provided, but thanks for the info.

0 Kudos
Reply