Developing Code for MCXN Family from Scratch

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

Developing Code for MCXN Family from Scratch

Developing Code for MCXN Family from Scratch

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.

xiangjun_rong_1-1706087170709.png

 

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;
}
評価なし
バージョン履歴
最終更新日:
‎01-24-2024 02:26 AM
更新者: