Hands On
In this lab we make some experience with the FRDM-MCXW23 board using the SDK project to implement a simple LED blinking. Once we will get familiar with the example project, we will integrate simple modifications.
Hardware Requirements
- Personal Computer
- FRDM-MCXW23 Board
- Type C USB Cable
Software Requirements
- IDE: Visual Studio Code 1.91.1 or newer
- Extension: MCUXpresso for VS Code v25.06.97 or newer
- SDK: SDK next gen v25.06.00 or newer
- SPSDK Tool
- Windows OS (It was used Windows 11 for this hands-on)
Note: In order to make downloads in NXP website, it is necessary to have an account. Please, register and log-in for moving forward.
MCUXpresso for Visual Studio Code
MCUXpresso for Visual Studio Code (VS Code) provides an optimized embedded developer experience for code editing and development. The extension enables NXP developers to use one of the most popular embedded editors tools and provides an easy and fast way to create, build and debug applications based on MCUXpresso SDK or Zephyr projects.
Install it following the next steps:
- Download Visual Studio Code from Microsoft Store or visual studio code web page
- Access to vscode for MCUX wiki and download MCUXpresso Installer
- Run MCUXpresso Installer and for this Hands On install at least
- MCUXpresso SDK Developer
- Arm GNU Toolchain
- PEmicro
Installing the FRDM-MCXW23 SDK v 25.06.00
Each MCU has its own SDK that includes driver, examples, middleware, docs and other components. To get and build the demo, let’s install the SDK into VS Code:
- Once MCUXpresso for Visual Studio Code is installed open VS Code.
- Go to MCUXpresso for VS Code extension that is on the tools column at the left.
- Look for INSTALLED REPOSITORIES option and press ‘+’. Detail steps are described in
- Use the steps for import a remote Git repository
- wiki page.
4.Search for FRDM-MCXW23 v25.06.00 SDK and complete installation.
Lab Section: LED it Shine
- Open VSCode and follow the steps in this section to import the led_blinky example from SDK, belonging to the demo_apps section in the MCUXpresso SDK as per the following snapshot:
- Click on Import button to import the full project into your workspace. Check the frdmmcxw23_led_blinky_lpc project in the Project explorer tab.
- Build and Debug the project, follow the steps explained in the previous lab. Start the Debug session and hit the breakpoint at the first instruction in main, then click on Continue (F5) to start the debug session and you will see the RGB GREEN LED blinking at one second rate. Click on Stop (red square button) to stop the debugging.
Note: User BLUE LED will continue blinking at the same rate as before because the Debug takes care about flashing the memory.
Now is time to play with the code. In the next steps we will add a new blinking LED. Having a look at the schematic of the FRDM-MCXW23 board in the RGB LED section, we notice RED is connected to GPIO0_0 and BLUE is connected to GPIO0_4 while the RED LED (digging a little more in depth in the document) is connected to GPIO0_1.

What we want to do is to have a RED LED blinking at the same one second rate but will blink in the inverse time as the GREEN LED, this means when RED is on BLUE is off and vice versa. To do this we will add few code modification.
1. Let us first explore a couple of defines part of the example. Open led_blinky.c file, at line 13 you will add the following two defines:
#define RED_LED_PIN 1U
#define RED_LED_PORT 0
Respectively these two are defining the new LED under control in the application, GPIO0 and pin 1 as per the schematic portion provided above.
Have a look then in the code and you will see that at line 65 you will encounter the following function call
GPIO_PortToggle(GPIO, BOARD_LED_PORT, 1u << BOARD_LED_PIN;
This is the function that effectively toggles the LED under control. Let's modify the code to toggle the second LED and also add the name of the color.
GPIO_PortToggle(GPIO, BOARD_LED_PORT, 1u << BOARD_LED_PIN;
GPIO_PortToggle(GPIO, RED_LED_PORT, 1<< RED_LED_PIN;
2.Now, open the pin_mux.c file and look for BOARD_InitPins on line 67. In line 70 and 72 code enables the clock for the Iocon and GPIO0
/* Enables the clock for the I/O controller.: Enable Clock. */
CLOCK_EnableClock(kCLOCK_Iocon;
/* Enables the clock for the GPIO0 module */
CLOCK_EnableClock(kCLOCK_Gpio0;
Since BLUE LED is on the same port and GPIO group as RED LED we will not need to add a new one.
3. In line 76 we have the configuration for the GREEN LED
gpio_pin_config_t LED_BLUE_config = {
.pinDirection = kGPIO_DigitalOutput,
.outputLogic = 0U
};
const uint32_t LED_BLUE = (/* Pin is configuBLUE as PIO0_19 */
IOCON_PIO_FUNC0 |
/* No addition pin function */
IOCON_PIO_MODE_INACT |
/* Standard mode, output slew rate control is enabled */
IOCON_PIO_SLEW_STANDARD |
/* Input function is not inverted */
IOCON_PIO_INV_DI |
/* Enables digital function */
IOCON_PIO_DIGITAL_EN |
/* Open drain is disabled */
IOCON_PIO_OPENDRAIN_DI);
/* PORT0 PIN19 (coords: 7) is configuBLUE as PIO0_19 */
IOCON_PinMuxSet(IOCON, BOARD_INITPINS_LED_BLUE_PORT, BOARD_INITPINS_LED_BLUE_PIN, LED_BLUE);
Now we need to add the configuration for the RED LED, add the next code after BLUE LED configuration. Notice that default output logic is 1 the opposite of BLUE LED this will be use to have the opposite state when LEDs toggle.
/* Initialize GPIO functionality on pin PIO0_1 */
GPIO_PinInit(BOARD_INITPINS_LED_RED_GPIO, BOARD_INITPINS_LED_RED_PORT, BOARD_INITPINS_LED_RED_PIN, &LED_RED_config);
const uint32_t LED_RED = (/* Pin is configuBLUE as PIO0_19 */
IOCON_PIO_FUNC0 |
/* No addition pin function */
IOCON_PIO_MODE_INACT |
/* Standard mode, output slew rate control is enabled */
IOCON_PIO_SLEW_STANDARD |
/* Input function is not inverted */
IOCON_PIO_INV_DI |
/* Enables digital function */
IOCON_PIO_DIGITAL_EN |
/* Open drain is disabled */
IOCON_PIO_OPENDRAIN_DI);
/* PORT0 PIN19 (coords: 7) is configuBLUE as PIO0_19 */
IOCON_PinMuxSet(IOCON, BOARD_INITPINS_LED_RED_PORT, BOARD_INITPINS_LED_RED_PIN, LED_RED);
4. If you tried to compile now you will get some errors this is because we use some defines that are not created yet. Go to pin_mux.h, in this file we have definitions for BLUE LED as well starting on line 45.
/* Symbols to be used with GPIO driver */
#define BOARD_INITPINS_LED_BLUE_GPIO GPIO /*!<@brief GPIO peripheral base pointer */
#define BOARD_INITPINS_LED_BLUE_GPIO_PIN_MASK (1U << 19U) /*!<@brief GPIO pin mask */
#define BOARD_INITPINS_LED_BLUE_PORT 0U /*!<@brief PORT peripheral base pointer */
#define BOARD_INITPINS_LED_BLUE_PIN 19U /*!<@brief PORT pin number */
#define BOARD_INITPINS_LED_BLUE_PIN_MASK (1U << 19U) /*!<@brief PORT pin mask */
Create defines for REDS LED, copy next test after BLUE LED defines
#define BOARD_INITPINS_LED_RED_GPIO GPIO /*!<@brief GPIO peripheral base pointer */
#define BOARD_INITPINS_LED_RED_GPIO_PIN_MASK (1U << 1U) /*!<@brief GPIO pin mask */
#define BOARD_INITPINS_LED_RED_PORT 0U /*!<@brief PORT peripheral base pointer */
#define BOARD_INITPINS_LED_RED_PIN 1U /*!<@brief PORT pin number */
#define BOARD_INITPINS_LED_RED_PIN_MASK (1U << 1U) /*!<@brief PORT pin mask */
5. Follow the steps described at point 3 to Build and Debug the application and hit the Continue button to start the debugging session. You will see the BLUE LED blinking at the same one second rate alternating with GREEN one.
What if we want to change the blinking rate?
Having a look at the led_blinky.c file, we notice there one special function called SysTick_Handler(void) defined at line 33. This is the interrupt routine associated to the so called Systick timer which is a timer embedded within the Cortex-M33 core typically used as a system tick for many RTOSes. The interrupt routine toggles the LED in use at a specific moment. We do not see any initialization function of it, though.
The Systick Timer in this particular implementation is initialized by the function SysTick_Config(SystemCoreClock/1000U); invoked at line 59, this function simply initialize the internal SysTick Timer to a certain value taken as time base. The blinking delay is ensured by the SysTick_Config(1000U) function called at line 69. Check what happens if you change the value of 1000U to another value.
6. Navigate to the ultimate call, and let us see what happens if we modify the call at line 69 like this:
SysTick_DelayTicks(1000U/2);
7. Save the modification (CTRL+S), Build and start the debugging.
What are you observing? Has the blinking rate changed, if yes, is it faster or slower?
Congratulations, you have mastered the LED it shine Lab.