Skip to content

Commit a92f203

Browse files
committed
Add frdm-mcxw71
1 parent 00d772e commit a92f203

File tree

6 files changed

+553
-0
lines changed

6 files changed

+553
-0
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
CFLAGS ?= -W -Wall -Wextra -Werror -Wundef -Wshadow -Wdouble-promotion -Wformat-truncation -fno-common
2+
CFLAGS += -g3 -Os -ffunction-sections -fdata-sections -Wno-shadow
3+
CFLAGS += -I. -Iinclude -Icmsis_core/CMSIS/Core/Include
4+
CFLAGS += -Icmsis_mcxw71/devices/MCXW716C
5+
CFLAGS += -Icmsis_mcxw71/devices/MCXW716C/periph2
6+
CFLAGS += -DCPU_MCXW716CMFTA -D__ATOLLIC__
7+
CFLAGS += -mcpu=cortex-m33 -mthumb -mfpu=fpv5-sp-d16 -mfloat-abi=hard $(CFLAGS_EXTRA)
8+
9+
LDFLAGS ?= -Tlink.ld -nostartfiles -nostdlib --specs nano.specs -lc -lgcc -Wl,--gc-sections -Wl,-Map=$@.map
10+
SOURCES = main.c syscalls.c startup.c
11+
12+
#LDFLAGS ?= -Tcmsis_mcxw71/devices/MCXW716C/gcc/mcxw716_flash.ld -nostartfiles -nostdlib --specs nano.specs -lc -lgcc -Wl,--gc-sections -Wl,-Map=$@.map
13+
#SOURCES += cmsis_mcxw71/devices/MCXW716C/system_MCXW716C.c
14+
#SOURCES += cmsis_mcxw71/devices/MCXW716C/gcc/startup_MCXW716C.S
15+
16+
build: firmware.bin
17+
18+
firmware.elf: cmsis_core cmsis_mcxw71 hal.h link.ld Makefile $(SOURCES)
19+
arm-none-eabi-gcc $(SOURCES) $(CFLAGS) $(CFLAGS_EXTRA) $(LDFLAGS) -o $@
20+
21+
firmware.bin: firmware.elf
22+
arm-none-eabi-objcopy -O binary $< $@
23+
24+
flash: firmware.bin
25+
(echo LoadFile $< 0; echo exit) | JLinkExe -nogui 1 -device mcxw716 -if swd -AutoConnect 1 -speed 4000
26+
27+
cmsis_core:
28+
git clone -q -c advice.detachedHead=false --depth 1 -b 5.9.0 https://github.com/ARM-software/CMSIS_5 $@
29+
30+
cmsis_mcxw71:
31+
curl -sL https://mcuxpresso.nxp.com/cmsis_pack/repo/NXP.MCXW716C_DFP.25.03.00.pack -o x.zip && mkdir -p $@ && (cd $@ && unzip -q ../x.zip && rm -f ../x.zip)
32+
33+
clean:
34+
rm -rf firmware.* cmsis_*

templates/blinky/frdm-mcxw71/hal.h

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
// Copyright (c) 2025 Cesanta Software Limited
2+
// SPDX-License-Identifier: MIT
3+
4+
#pragma once
5+
6+
#include <stdbool.h>
7+
#include <stdint.h>
8+
#include <stdio.h>
9+
#include <string.h>
10+
11+
#include "MCXW716C.h"
12+
#include "MCXW716C_COMMON.h"
13+
14+
#define BIT(x) (1UL << (x))
15+
#define CLRSET(R, CLEARMASK, SETMASK) (R) = ((R) & ~(CLEARMASK)) | (SETMASK)
16+
#define PIN(bank, num) ((((bank) - 'A') << 8) | (num))
17+
#define PINNO(pin) (pin & 255)
18+
#define PINBANK(pin) (pin >> 8)
19+
20+
#define SYS_FREQUENCY 6000000
21+
22+
static inline void spin(volatile uint32_t count) {
23+
while (count--) (void) 0;
24+
}
25+
26+
enum { GPIO_MODE_INPUT, GPIO_MODE_OUTPUT, GPIO_MODE_AF, GPIO_MODE_ANALOG };
27+
enum { GPIO_OTYPE_PUSH_PULL, GPIO_OTYPE_OPEN_DRAIN };
28+
enum { GPIO_SPEED_LOW, GPIO_SPEED_MEDIUM, GPIO_SPEED_HIGH, GPIO_SPEED_INSANE };
29+
enum { GPIO_PULL_NONE, GPIO_PULL_UP, GPIO_PULL_DOWN };
30+
31+
static inline GPIO_Type *gpio_bank(uint16_t pin) {
32+
uint8_t bank = PINBANK(pin);
33+
return (GPIO_Type *) (bank == 0 ? GPIOA
34+
: bank == 1 ? GPIOB
35+
: bank == 2 ? GPIOC
36+
: bank == 3 ? GPIOD
37+
: 0);
38+
}
39+
40+
static inline void gpio_toggle(uint16_t pin) {
41+
GPIO_Type *gpio = gpio_bank(pin);
42+
gpio->PTOR |= BIT(PINNO(pin));
43+
}
44+
45+
static inline bool gpio_read(uint16_t pin) {
46+
GPIO_Type *gpio = gpio_bank(pin);
47+
return gpio->PDR[PINNO(pin)];
48+
}
49+
50+
static inline void gpio_write(uint16_t pin, bool val) {
51+
GPIO_Type *gpio = gpio_bank(pin);
52+
if (val) {
53+
// gpio->PSOR |= BIT(PINNO(pin));
54+
gpio->PDR[PINNO(pin)] = 1U;
55+
} else {
56+
// gpio->PCOR |= BIT(PINNO(pin));
57+
gpio->PDR[PINNO(pin)] = 0;
58+
}
59+
}
60+
61+
static inline void gpio_init(uint16_t pin, uint8_t mode, uint8_t type,
62+
uint8_t speed, uint8_t pull, uint8_t af) {
63+
GPIO_Type *gpio = gpio_bank(pin);
64+
(void) pin, (void) mode, (void) type, (void) speed, (void) pull, (void) af;
65+
#if 0
66+
if (gpio == GPIOA) {
67+
CLRSET(MRCC->MRCC_GPIOA, MRCC_MRCC_GPIOA_CC_MASK, 1U);
68+
} else if (gpio == GPIOB) {
69+
CLRSET(MRCC->MRCC_GPIOB, MRCC_MRCC_GPIOB_CC_MASK, 1U);
70+
} else if (gpio == GPIOC) {
71+
CLRSET(MRCC->MRCC_GPIOC, MRCC_MRCC_GPIOC_CC_MASK, 1U);
72+
}
73+
__ISB();
74+
__DSB();
75+
#endif
76+
if (mode == GPIO_MODE_OUTPUT) {
77+
// gpio->PDOR &= ~BIT(PINNO(pin));
78+
gpio->PDOR |= BIT(PINNO(pin));
79+
gpio->PDDR |= BIT(PINNO(pin));
80+
} else {
81+
gpio->PDDR &= ~BIT(PINNO(pin));
82+
}
83+
}
84+
static inline void gpio_input(uint16_t pin) {
85+
gpio_init(pin, GPIO_MODE_INPUT, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH,
86+
GPIO_PULL_NONE, 0);
87+
}
88+
static inline void gpio_output(uint16_t pin) {
89+
gpio_init(pin, GPIO_MODE_OUTPUT, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH,
90+
GPIO_PULL_NONE, 0);
91+
}
92+
93+
static inline void uart_init(LPUART_Type *uart, unsigned long baud) {
94+
uint32_t val = 0x80000000U; // Module present
95+
val |= 0x40000000U; // Release from reset
96+
val |= 1U; // Enable clock
97+
val |= 2U << 4; // Clock mux: FRO-6M
98+
if (uart == LPUART0) {
99+
MRCC->MRCC_LPUART0 = val;
100+
} else if (uart == LPUART1) {
101+
MRCC->MRCC_LPUART1 = val;
102+
}
103+
(void) baud;
104+
}
105+
106+
static inline void uart_write_byte(LPUART_Type *uart, uint8_t byte) {
107+
// while ((uart->FIFOSTAT & UART_FIFOSTAT_TXNOTFULL_MASK) == 0) spin(1);
108+
return;
109+
uart->FIFO = byte;
110+
}
111+
static inline void uart_write_buf(LPUART_Type *uart, char *buf, size_t len) {
112+
while (len-- > 0) uart_write_byte(uart, *(uint8_t *) buf++);
113+
}
114+
115+
// t: expiration time, prd: period, now: current time. Return true if expired
116+
static inline bool timer_expired(volatile uint64_t *t, uint64_t prd,
117+
uint64_t now) {
118+
if (now + prd < *t) *t = 0; // Time wrapped? Reset timer
119+
if (*t == 0) *t = now + prd; // Firt poll? Set expiration
120+
if (*t > now) return false; // Not expired yet, return
121+
*t = (now - *t) > prd ? now + prd : *t + prd; // Next expiration time
122+
return true; // Expired, return true
123+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
ENTRY(Reset_Handler);
2+
MEMORY {
3+
flash(rx) : ORIGIN = 0x00000000, LENGTH = 1024k
4+
sram(rwx) : ORIGIN = 0x20000000, LENGTH = 112k
5+
}
6+
STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x0800;
7+
__StackTop = ORIGIN(sram) + LENGTH(sram); /* stack points to end of SRAM */
8+
__StackLimit = __StackTop - STACK_SIZE;
9+
10+
SECTIONS {
11+
.vectors : { KEEP(*(.isr_vector)) } > flash
12+
.text : { *(.text* .text.*) } > flash
13+
.rodata : { *(.rodata*) } > flash
14+
__etext = .;
15+
.data : { __data_start__ = .; *(.first_data) *(.data SORT(.data.*)) __data_end__ = .; } > sram AT > flash
16+
_sidata = LOADADDR(.data);
17+
.bss : { __bss_start__ = .; *(.bss SORT(.bss.*) COMMON) __bss_end__ = .; } > sram
18+
. = ALIGN(8);
19+
__end__ = .;
20+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// Copyright (c) 2025 Cesanta Software Limited
2+
// SPDX-License-Identifier: MIT
3+
4+
#include "hal.h"
5+
6+
#define UART_DEBUG LPUART1
7+
8+
#define LED1_PIN PIN('A', 19) // Green
9+
//#define LED2_PIN PIN('A', 20) // Blue
10+
#define LED2_PIN PIN('C', 1) // Blue
11+
#define LED3_PIN PIN('A', 21) // Red
12+
13+
#define BLINK_PERIOD_MS 500 // LED blinking period in millis
14+
#define LOG_PERIOD_MS 1000 // Info log period in millis
15+
16+
// Retarget standard IO functions ouput (printf, fwrite, etc) to use UART
17+
int _write(int fd, char *ptr, int len) {
18+
if (fd == 1) uart_write_buf(UART_DEBUG, ptr, (size_t) len);
19+
return len;
20+
}
21+
22+
static volatile uint64_t s_ticks; // Milliseconds since boot
23+
void SysTick_Handler(void) { // SyStick IRQ handler, triggered every 1ms
24+
s_ticks++;
25+
}
26+
27+
static void led_task(void) { // Blink LED every BLINK_PERIOD_MS
28+
static uint64_t timer = 0;
29+
if (timer_expired(&timer, BLINK_PERIOD_MS, s_ticks)) {
30+
gpio_toggle(LED2_PIN);
31+
}
32+
}
33+
34+
static void log_task(void) { // Print a log every LOG_PERIOD_MS
35+
static uint64_t timer = 0;
36+
if (timer_expired(&timer, LOG_PERIOD_MS, s_ticks)) {
37+
printf("tick: %5lu, CPU %lu MHz\n", (unsigned long) s_ticks,
38+
SystemCoreClock / 1000000);
39+
}
40+
}
41+
42+
uint32_t SystemCoreClock;
43+
void SystemInit(void) {
44+
// set CP10, CP11 Full Access in Secure and Non-secure mode
45+
SCB->CPACR |= ((3UL << 10 * 2) | (3UL << 11 * 2));
46+
SystemCoreClock = SYS_FREQUENCY; // Required by CMSIS
47+
SysTick_Config(SystemCoreClock / 1000); // Sys tick every 1ms
48+
}
49+
50+
int main(void) {
51+
MRCC_Type *x = MRCC;
52+
gpio_output(LED1_PIN);
53+
gpio_write(LED1_PIN, 1);
54+
55+
gpio_output(LED2_PIN);
56+
gpio_write(LED2_PIN, 1);
57+
58+
printf("%p", x);
59+
60+
uart_init(UART_DEBUG, 115200);
61+
62+
for (;;) {
63+
led_task();
64+
log_task();
65+
}
66+
67+
return 0;
68+
}

0 commit comments

Comments
 (0)