MCX Microcontrollers Knowledge Base

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

MCX Microcontrollers Knowledge Base

Discussions

Sort by:
Developing code for MCXN family from Scratch The MCX family is a newly released MCU family, of course, the SDK package includes almost all the examples of the MCXN modules based on the SDK driver, for example led_blinky which shows the method of toggling GPIO, CTimer interrupt, etc. While the program in this article doesn’t use SDK driver. It focuses on understanding the related module from register level which is friendly to beginners to understand MCX working mechanism. The doc introduces how to toggle a GPIO, how to have CTimer generate interrupt, and in the CTimer ISR, toggle a LED, while it also describes how to initialize the NVIC so that CTimer can generate ISR by writing the module registers without calling the SDK driver. Environment: FRDM-MCXN947 board MCUXPresso IDE v11.9.0 IDE on Win10 OS   1. Toggle a LED On the FRDM-MCXN947 board, the PIO0_10(P0_10) of MCXN947 is connected to a LED. With MCUXPresso IDE with v11.9.0, you can add the code to test the LED toggling and CTimer interrupt function.   1.1 Configure the PIO0_10 pin as GPIO0_10 pin SYSCON->AHBCLKCTRLSET[0]=1<<13; PORT0->PCR[10]=0x1000; Before you initialize the PORT0 register to assign the PIO0_10 function, you have to enable the PORT0 gated clock in the SYSCON->AHBCLKCTRL0 reg. Write the PORT0->PCR[10]=0x1000; to configure the PIO0_10 as GPIO0_10 function. 1.2 Configure the GPIO0_10 pin as GPIO output mode and toggle the GPIO pin. SYSCON->AHBCLKCTRLSET[0]=1<<19; GPIO0->PDDR|=1<<10; GPIO0->PTOR=1<<10; Before you initialize the GPIO0 registers, you have to enable the GPIO0 gated clock in the SYSCON->AHBCLKCTRL0 reg. Set the bit 10 of GPIO0->PDDR so that the GPIO0_10 is in GPIO output mode. Toggle GPIO0_10 pin by writing the bit 10 in GPIO0->PTOR reg   Set a break point in the debugger on the GPIO0->PTOR=1<<10; line,and run step by step, you can see that led toggles.   2. Initialize CTimer 2.1 enable Ctimer gated clock and clock source and divider. Before you initialize the CTimer register, you have to enable the CTimer gated clock. For example, enable CTimer4 gated clock with the line: SYSCON->AHBCLKCTRLSET[2]=1<<22; You have to also select the CTimer clock source and Ctimer clock divider. For example, set the CTimer4 clock source and divider. SYSCON->CTIMERCLKSEL[4]=0x04; SYSCON->CTIMERCLKDIV[4]=0x02; //P0_10 is LED red void GPIOInit(void) { SYSCON->AHBCLKCTRLSET[0]=1<<13; PORT0->PCR[10]=0x1000; //enable gated clock of GPIO SYSCON->AHBCLKCTRLSET[0]=1<<19; GPIO0->PDDR|=1<<10; GPIO0->PTOR=1<<10; //set break point here GPIO0->PTOR=1<<10; GPIO0->PTOR=1<<10; GPIO0->PTOR=1<<10; GPIO0->PTOR=1<<10; } 2.2 Initialize the CTimer register. CTIMER4->CTCR=0x00; CTIMER4->PR=0x00; //set the CTimet4 mode and enable interrupt for match0 CTIMER4->MCR=0x03; CTIMER4->PWMC=0x00; //set the CTimer4 cycle time CTIMER4->MR[0]=2000000; CTIMER4->MSR[0]=2000000; //Start up CTimer4 CTIMER4->TCR=0x01; 2.3 Initialize the NVIC The IRQ number of CTimer4 is 56, so you have to set the bit 24 of both NVIC->ISER[1]|=1<<24; NVIC->ICPR[1]|=1<<24; and set the priority of NVIC->IPR[56] with 0x00; NVIC->IPR[56]=0x00;   //CTimer4 IRQ 56, 56-32=24 void cTimer0Init(void) { //CLOCK_SetClkDiv(kCLOCK_DivCtimer4Clk, 1u); //CLOCK_AttachClk(kFRO_HF_to_CTIMER4); //enable Ctimer4 gated clock SYSCON->AHBCLKCTRLSET[2]=1<<22; SYSCON->PRESETCTRLSET[2]=1<<22; SYSCON->PRESETCTRLCLR[2]=1<<22; SYSCON->CTIMERGLOBALSTARTEN|=1<<4; //select CTimer4 clock source SYSCON->CTIMERCLKSEL[4]=0x04; SYSCON->CTIMERCLKDIV[4]=0x02; //init the CTimer0 CTIMER4->CTCR=0x00; CTIMER4->PR=0x00; CTIMER4->MCR=0x03; CTIMER4->PWMC=0x00; CTIMER4->MR[0]=2000000; CTIMER4->MSR[0]=2000000; //CTIMER0->IR=0x01; CTIMER4->TCR=0x01; NVIC->ISER[1]|=1<<24; NVIC->ICPR[1]|=1<<24; NVIC->IPR[56]=0x00; } 2.3 Each interrupt source has unique interrupt service routine in the file startup_mcxn947_cm33_core0.c For the CTimer4 ISR, it is called: CTIMER4_IRQHandler So it is okay to fill the function: void CTIMER4_IRQHandler(void) { //clear flag CTIMER4->IR|=0x01; //toggle LED GPIO0->PTOR=1<<10; } In conclusion, the doc gives a snippet which can toggle a LED by writing the register directly. It also give the code to configure CTimer4 so that it can generate interrupt, in the ISR, toggle a LED. Appendix This is the entire source code:   /* * Copyright 2019 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include "pin_mux.h" #include "peripherals.h" #include "board.h" /******************************************************************************* * Definitions ******************************************************************************/ void clockOUTInit(void); void GPIOInit(void); void cTimer0Init(void); void MRTInit(void); /******************************************************************************* * Prototypes ******************************************************************************/ /******************************************************************************* * Variables ******************************************************************************/ /******************************************************************************* * Code ******************************************************************************/ /*! * @brief Main function */ int main(void) { /* Board pin init */ CLOCK_EnableClock(kCLOCK_Gpio0); BOARD_InitPins(); BOARD_BootClockFRO12M(); //FlexPWMPinInit(); GPIOInit(); cTimer0Init(); //MRTInit(); __asm("nop"); while (1) { } } //P0_10 is LED red void GPIOInit(void) { SYSCON->AHBCLKCTRLSET[0]=1<<13; PORT0->PCR[10]=0x1000; //enable gated clock of GPIO SYSCON->AHBCLKCTRLSET[0]=1<<19; GPIO0->PDDR|=1<<10; //set a break point here and run step by step GPIO0->PTOR=1<<10; GPIO0->PTOR=1<<10; GPIO0->PTOR=1<<10; GPIO0->PTOR=1<<10; GPIO0->PTOR=1<<10; GPIO0->PTOR=1<<10; GPIO0->PTOR=1<<10; GPIO0->PTOR=1<<10; GPIO0->PTOR=1<<10; } //CTimer4 IRQ 56, 56-32=24 void cTimer0Init(void) { // CLOCK_SetClkDiv(kCLOCK_DivCtimer4Clk, 1u); // CLOCK_AttachClk(kFRO_HF_to_CTIMER4); //enable Ctimer4 gated clock SYSCON->AHBCLKCTRLSET[2]=1<<22; SYSCON->PRESETCTRLSET[2]=1<<22; SYSCON->PRESETCTRLCLR[2]=1<<22; SYSCON->CTIMERGLOBALSTARTEN|=1<<4; //select CTimer4 clock source SYSCON->CTIMERCLKSEL[4]=0x04; SYSCON->CTIMERCLKDIV[4]=0x02; //init the CTimer0 CTIMER4->CTCR=0x00; CTIMER4->PR=0x00; CTIMER4->MCR=0x03; CTIMER4->PWMC=0x00; CTIMER4->MR[0]=2000000; CTIMER4->MSR[0]=2000000; //CTIMER0->IR=0x01; CTIMER4->TCR=0x01; NVIC->ISER[1]|=1<<24; NVIC->ICPR[1]|=1<<24; NVIC->IPR[56]=0x00; } void CTIMER4_IRQHandler(void) { //clear flag CTIMER4->IR|=0x01; //toggle LED GPIO0->PTOR=1<<10; } //MRT0 interrupt IRQ is 30 void MRTInit(void) { SYSCON->AHBCLKCTRLSET[1]=1<<0; SYSCON->PRESETCTRLSET[1]=1<<0; SYSCON->PRESETCTRLCLR[1]=1<<0; MRT0->CHANNEL[0].INTVAL=6000000; MRT0->CHANNEL[0].INTVAL|=1<<31; MRT0->CHANNEL[0].CTRL=0x01; NVIC->ISER[0]|=1<<30; NVIC->ICPR[0]|=1<<30; NVIC->IPR[30]=0x00; } void MRT0_IRQHandler(void) { if(MRT0->CHANNEL[0].STAT&0x01) { MRT0->CHANNEL[0].STAT|=0x01; } //toggle LED GPIO0->PTOR=1<<10; }
View full article