Yilin Sun 2024-04-26 19:44:18 +03:00 zatwierdzone przez GitHub
commit 4ce50338aa
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: B5690EEEBB952194
67 zmienionych plików z 9508 dodań i 1 usunięć

@ -1 +1 @@
Subproject commit fa5a554c7944d2a196626f8d3631e44943f9abcc
Subproject commit 485ff6db37e9bc288d33d8c252cbb9dbd48678d3

321
ports/mcx/Makefile 100644
Wyświetl plik

@ -0,0 +1,321 @@
# Determine which board we are compiling for...
ifdef BOARD_DIR
BOARD ?= $(notdir $(BOARD_DIR:/=))
else
BOARD ?= FRDM_MCXN947
BOARD_DIR ?= boards/$(BOARD)
endif
ifeq ($(wildcard $(BOARD_DIR)/.),)
$(error Invalid BOARD specified: $(BOARD_DIR))
endif
BUILD ?= build-$(BOARD)
GIT_SUBMODULES += lib/nxp_driver
include ../../py/mkenv.mk
# qstr definitions (must come before including py.mk)
QSTR_DEFS = qstrdefsport.h
include $(BOARD_DIR)/mpconfigboard.mk
# MicroPython feature configurations
MICROPY_ROM_TEXT_COMPRESSION ?= 1
# File containing description of content to be frozen into firmware.
FROZEN_MANIFEST ?= boards/manifest.py
# include py core make definitions
include $(TOP)/py/py.mk
include $(TOP)/extmod/extmod.mk
include mcx.mk
CROSS_COMPILE ?= arm-none-eabi-
INC += -I.
INC += -I$(TOP)
INC += -I$(BUILD)
CFLAGS += $(INC) -Wall -Werror -std=gnu99 -nostdlib $(TARGET_CFLAGS_CPU) $(COPT)
CFLAGS_BUILTIN ?= -ffreestanding -fno-builtin -fno-lto
ASFLAGS += $(TARGET_CFLAGS_CPU)
# Configure floating point support
ifeq ($(MICROPY_FLOAT_IMPL),single)
CFLAGS += -DMICROPY_FLOAT_IMPL=MICROPY_FLOAT_IMPL_FLOAT
CFLAGS += -fsingle-precision-constant
else ifeq ($(MICROPY_FLOAT_IMPL),none)
CFLAGS += -DMICROPY_FLOAT_IMPL=MICROPY_FLOAT_IMPL_NONE
endif
LDFLAGS += -nostdlib \
$(addprefix -T,devices/$(TARGET_MCU_SERIES)/$(TARGET_MCU_VARIANT)_flash.ld) \
-Wl,-Map=$(@:.elf=.map) -Wl,--cref -Wl,--gc-sections
ifneq ($(TARGET_STACK_SIZE),)
LDFLAGS += -Wl,--defsym=__stack_size__=$(TARGET_STACK_SIZE)
endif
ifneq ($(TARGET_HEAP_SIZE),)
LDFLAGS += -Wl,--defsym=__heap_size__=$(TARGET_HEAP_SIZE)
endif
CSUPEROPT = -Os # save some code space
# PIN Generator
AF_FILE = $(TARGET_MCU_AF_FILE)
MAKE_PINS = boards/make-pins.py
PREFIX_FILE = boards/mcx_pin_prefix.c
BOARD_PINS = $(BOARD_DIR)/pins.csv
GEN_PINS_SRC = $(BUILD)/pins_$(BOARD).c
GEN_PINS_HDR = $(HEADER_BUILD)/pins.h
# SDK
SDK_DIR = lib/nxp_driver/sdk
MCUX_DIR = $(SDK_DIR)/devices/$(TARGET_MCU_SERIES)
TARGET_STARTUP_S = devices/$(TARGET_MCU_SERIES)/startup_$(TARGET_MCU_VARIANT)
TARGET_SYSTEM_C = devices/$(TARGET_MCU_SERIES)/system_$(TARGET_MCU_VARIANT)
# Tune for Debugging or Optimization
CFLAGS += -g # always include debug info in the ELF
ifeq ($(DEBUG), 1)
CFLAGS += -O0 -DDEBUG
else
CFLAGS += -Os -DNDEBUG
CFLAGS += -fdata-sections -ffunction-sections
endif
# Hardware & SDK C defines
CFLAGS += \
-D__START=main \
-D$(TARGET_MCU_DEF) \
-DMCUXPRESSO_SDK \
-D__STARTUP_CLEAR_BSS
# Hardware & SDK C includes
CFLAGS += \
-I$(BOARD_DIR) \
-I$(TOP)/$(SDK_DIR)/CMSIS/Include \
-I$(TOP)/$(MCUX_DIR) \
-I$(TOP)/$(MCUX_DIR)/drivers \
-I$(TOP)/$(MCUX_DIR)/drivers/romapi/flash \
# Flags for optional C++ source code
CXXFLAGS += $(filter-out -std=c99,$(CFLAGS))
LIBS = \
"$(shell $(CC) $(CFLAGS) -print-libgcc-file-name)"
SRC_C = \
drv_adc.c \
drv_i2c.c \
drv_iflash.c \
drv_pin.c \
drv_pwm.c \
drv_spi.c \
drv_uart.c \
hal_pin.c \
hal_stdio.c \
hal_systick.c \
machine_i2c.c \
machine_pin.c \
machine_spi.c \
main.c \
mcx_flash.c \
modmcx.c \
mphalport.c \
pendsv.c \
tusb_port.c \
SRC_BOARD_C = $(addprefix $(BOARD_DIR)/, \
board.c \
clock_config.c \
interrupts.c \
pin_mux.c \
)
SRC_SDK_C = $(addprefix $(MCUX_DIR)/, \
drivers/romapi/flash/src/fsl_flash.c \
drivers/fsl_clock.c \
drivers/fsl_common.c \
drivers/fsl_common_arm.c \
drivers/fsl_ctimer.c \
drivers/fsl_gpio.c \
drivers/fsl_lpadc.c \
drivers/fsl_lpi2c.c \
drivers/fsl_lpspi.c \
drivers/fsl_lpuart.c \
drivers/fsl_power.c \
drivers/fsl_reset.c \
drivers/fsl_spc.c \
drivers/fsl_vref.c \
)
SRC_DRIVERS_C = $(addprefix drivers/, \
bus/softspi.c \
bus/softqspi.c \
memory/spiflash.c \
dht/dht.c \
)
# TinyUSB Stack source
SRC_TINYUSB_C += \
lib/tinyusb/src/class/cdc/cdc_device.c \
lib/tinyusb/src/class/dfu/dfu_rt_device.c \
lib/tinyusb/src/class/hid/hid_device.c \
lib/tinyusb/src/class/midi/midi_device.c \
lib/tinyusb/src/class/msc/msc_device.c \
lib/tinyusb/src/class/usbtmc/usbtmc_device.c \
lib/tinyusb/src/class/vendor/vendor_device.c \
lib/tinyusb/src/common/tusb_fifo.c \
lib/tinyusb/src/device/usbd.c \
lib/tinyusb/src/device/usbd_control.c \
lib/tinyusb/src/tusb.c
CFLAGS += \
-I$(TOP)/lib/tinyusb/hw \
-I$(TOP)/lib/tinyusb/hw/bsp/mcx \
-I$(TOP)/lib/tinyusb/src \
SRC_C += $(TARGET_SYSTEM_C).c
SRC_O += $(TARGET_STARTUP_S).o
ifeq ($(TARGET_MCU_HAS_LPFLEXCOMM), 1)
SRC_SDK_C += $(MCUX_DIR)/drivers/fsl_lpflexcomm.c
CFLAGS += -DMICROPY_HW_HAS_LPFLEXCOMM
endif
ifeq ($(TARGET_MCU_HAS_OSTIMER), 1)
SRC_SDK_C += $(MCUX_DIR)/drivers/fsl_ostimer.c
CFLAGS += -DMICROPY_HW_HAS_OSTIMER
endif
ifeq ($(TARGET_MCU_HAS_USB_HS), 1)
SRC_TINYUSB_C += lib/tinyusb/src/portable/chipidea/ci_hs/dcd_ci_hs.c
CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_MCXN9
CFLAGS += -DMICROPY_HW_HAS_USB_HS
endif
ifeq ($(TARGET_MCU_HAS_FLEXSPI), 1)
SRC_SDK_C += $(MCUX_DIR)/drivers/fsl_flexspi.c
CFLAGS += -DMICROPY_HW_HAS_FLEXSPI
endif
SRC_SHARED_C = $(addprefix shared/,\
libc/printf.c \
readline/readline.c \
runtime/interrupt_char.c \
runtime/gchelper_native.c \
runtime/mpirq.c \
runtime/pyexec.c \
runtime/stdout_helpers.c \
runtime/sys_stdio_mphal.c \
)
$(BUILD)/shared/libc/string0.o: CFLAGS += $(CFLAGS_BUILTIN)
# LibC sources
SRC_LIBC_C = \
shared/libc/string0.c
# LibM sources
SRC_LIBM_C = $(addprefix lib/libm/,\
acoshf.c \
asinfacosf.c \
asinhf.c \
atan2f.c \
atanf.c \
atanhf.c \
ef_rem_pio2.c \
erf_lgamma.c \
fmodf.c \
kf_cos.c \
kf_rem_pio2.c \
kf_sin.c \
kf_tan.c \
log1pf.c \
math.c \
nearbyintf.c \
roundf.c \
sf_cos.c \
sf_erf.c \
sf_frexp.c \
sf_ldexp.c \
sf_modf.c \
sf_sin.c \
sf_tan.c \
wf_lgamma.c \
wf_tgamma.c \
)
ifeq ($(SUPPORTS_HARDWARE_FP_SINGLE),1)
SRC_LIBM_C += lib/libm/thumb_vfp_sqrtf.c
else
SRC_LIBM_C += lib/libm/ef_sqrt.c
endif
SRC_O += \
shared/runtime/gchelper_thumb2.o
SRC_QSTR += $(SRC_C) $(SRC_SHARED_C) $(GEN_PINS_SRC)
# Making OBJ use an order-only dependency on the generated pins.h file
# has the side effect of making the pins.h file before we actually compile
# any of the objects. The normal dependency generation will deal with the
# case when pins.h is modified. But when it doesn't exist, we don't know
# which source files might need it.
$(OBJ): | $(GEN_PINS_HDR)
OBJ += $(PY_O)
OBJ += $(addprefix $(BUILD)/, $(SRC_O))
OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
OBJ += $(addprefix $(BUILD)/, $(SRC_BOARD_C:.c=.o))
OBJ += $(addprefix $(BUILD)/, $(SRC_SDK_C:.c=.o))
OBJ += $(addprefix $(BUILD)/, $(SRC_DRIVERS_C:.c=.o))
OBJ += $(addprefix $(BUILD)/, $(SRC_TINYUSB_C:.c=.o))
OBJ += $(addprefix $(BUILD)/, $(SRC_SHARED_C:.c=.o))
OBJ += $(addprefix $(BUILD)/, $(SRC_CXX:.cpp=.o))
OBJ += $(addprefix $(BUILD)/, $(SRC_LIBC_C:.c=.o))
OBJ += $(addprefix $(BUILD)/, $(SRC_LIBM_C:.c=.o))
OBJ += $(GEN_PINS_SRC:.c=.o)
all: $(BUILD)/firmware.hex $(BUILD)/firmware.bin
# Need correct CPU flags to assemble this file.
$(BUILD)/shared/runtime/gchelper_thumb2.o: $(TOP)/shared/runtime/gchelper_thumb2.s
$(ECHO) "AS $<"
$(Q)$(AS) $(ASFLAGS) -o $@ $<
# Startup file requires CPP support.
$(BUILD)/$(TARGET_STARTUP_S).o: $(TARGET_STARTUP_S).S
$(ECHO) "AS $<"
$(Q)$(CC) $(CFLAGS) -c -xassembler-with-cpp -o $@ $<
$(BUILD)/firmware.elf: $(OBJ)
$(ECHO) "LINK $@"
$(Q)$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
$(Q)$(SIZE) $@
$(BUILD)/firmware.hex: $(BUILD)/firmware.elf
$(ECHO) "COPY $@"
$(Q)$(OBJCOPY) -Oihex $^ $@
$(BUILD)/firmware.bin: $(BUILD)/firmware.elf
$(ECHO) "COPY $@"
$(Q)$(OBJCOPY) -Obinary $^ $@
# Use a pattern rule here so that make will only call make-pins.py once to make
# both pins_$(BOARD).c and pins.h
$(BUILD)/%_$(BOARD).c $(HEADER_BUILD)/%.h: $(BOARD_PINS) $(MAKE_PINS) $(AF_FILE) $(PREFIX_FILE) | $(HEADER_BUILD)
$(ECHO) "GEN $@"
$(Q)$(PYTHON) $(MAKE_PINS) --board-csv $(BOARD_PINS) --af-csv $(AF_FILE) --prefix $(PREFIX_FILE) \
--output-source $(GEN_PINS_SRC) --output-header $(GEN_PINS_HDR)
include $(TOP)/py/mkrules.mk

77
ports/mcx/board.h 100644
Wyświetl plik

@ -0,0 +1,77 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2024 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef MP_PORT_MCX_BOARD_H
#define MP_PORT_MCX_BOARD_H
#include "py/mphal.h"
typedef void (*mcx_board_isr_t)(void *param);
void MCX_BoardEarlyInit(void);
/* UUID */
int MCX_BoardGetUniqueID(uint64_t *uuid);
/* GPIO and Port */
void *MCX_BoardGetPORTInstance(uint8_t id);
void *MCX_BoardGetGPIOInstance(uint8_t id);
int MCX_BoardConfigurePORTClock(uint8_t id);
int MCX_BoardConfigureGPIOClock(uint8_t id);
/* ADC */
void *MCX_BoardGetADCInstance(uint8_t id);
int MCX_BoardConfigureADCClock(uint8_t id);
/* UART */
void *MCX_BoardGetUARTInstance(uint8_t id);
int MCX_BoardConfigureUARTClock(uint8_t id);
int MCX_BoardConfigureUARTISR(uint8_t id, mcx_board_isr_t isr, void *param);
/* I2C */
void *MCX_BoardGetI2CInstance(uint8_t id);
int MCX_BoardConfigureI2CClock(uint8_t id);
/* SPI */
void *MCX_BoardGetSPIInstance(uint8_t id);
int MCX_BoardConfigureSPIClock(uint8_t id);
/* CT32 */
void *MCX_BoardGetCT32Instance(uint8_t id);
int MCX_BoardConfigureCT32Clock(uint8_t id);
/* USB HS */
int MCX_BoardConfigureUSBClock(uint8_t id);
int MCX_BoardConfigureUSBPHY(uint8_t id);
int MCX_BoardConfigureUSBISR(uint8_t id, mcx_board_isr_t isr, void *param);
/* OSTimer */
#ifdef MICROPY_HW_HAS_OSTIMER
void *MCX_BoardGetOSTimerInstance(uint8_t id);
int MCX_BoardConfigureOSTimerClock(uint8_t id);
#endif
#endif

Wyświetl plik

@ -0,0 +1,4 @@
TARGET_MCU_SERIES = MCXA153
TARGET_MCU_PART = MCXA153VLH
TARGET_MCU_CORE_HAS_DSP = 0
TARGET_MCU_CORE_HAS_FPU = 0

Wyświetl plik

@ -0,0 +1,529 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2024 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <stdio.h>
#include "board.h"
#include "fsl_spc.h"
#include "clock_config.h"
#include "pin_mux.h"
typedef struct mcxn947_irq_table_type {
mcx_board_isr_t irq_gpio[5];
void *irq_gpio_params[5];
mcx_board_isr_t irq_uart[10];
void *irq_uart_params[10];
mcx_board_isr_t irq_ostimer[1];
void *irq_ostimer_params[1];
mcx_board_isr_t irq_usb[2];
void *irq_usb_params[2];
} mcxn947_irq_table_t;
typedef struct mcxn947_irqn_prio_type {
IRQn_Type irqn;
uint8_t priority;
} mcxn947_irqn_prio_t;
static volatile mcxn947_irq_table_t s_mcxn947_irq_table;
static ADC_Type *const s_mcxn947_adc_inst_map[] = ADC_BASE_PTRS;
static LPUART_Type *const s_mcxn947_uart_inst_map[] = LPUART_BASE_PTRS;
static LPI2C_Type *const s_mcxn947_i2c_inst_map[] = LPI2C_BASE_PTRS;
static LPSPI_Type *const s_mcxn947_spi_inst_map[] = LPSPI_BASE_PTRS;
static CTIMER_Type *const s_mcxn947_ctimer_inst_map[] = CTIMER_BASE_PTRS;
static OSTIMER_Type *const s_mcxn947_ostimer_inst_map[] = OSTIMER_BASE_PTRS;
static PORT_Type *const s_mcxn947_port_inst_map[] = PORT_BASE_PTRS;
static GPIO_Type *const s_mcxn947_gpio_inst_map[] = GPIO_BASE_PTRS;
static clock_ip_name_t const s_mcxn947_port_clk_map[] = {
kCLOCK_Port0,
kCLOCK_Port1,
kCLOCK_Port2,
kCLOCK_Port3,
kCLOCK_Port4,
kCLOCK_None, /* Special: PORT5 is in VBAT domain */
};
static clock_ip_name_t const s_mcxn947_gpio_clk_map[] = {
kCLOCK_Gpio0,
kCLOCK_Gpio1,
kCLOCK_Gpio2,
kCLOCK_Gpio3,
kCLOCK_Gpio4,
kCLOCK_None, /* Special: GPIO is in VBAT domain */
};
static clock_attach_id_t const s_mcxn947_adc_clk_att_map[] = {
kFRO12M_to_ADC0,
kFRO12M_to_ADC1,
};
static clock_div_name_t const s_mcxn947_adc_clk_div_map[] = {
kCLOCK_DivAdc0Clk,
kCLOCK_DivAdc1Clk,
};
static clock_attach_id_t const s_mcxn947_flexcomm_clk_att_map[] = {
kPLL_DIV_to_FLEXCOMM0,
kPLL_DIV_to_FLEXCOMM1,
kPLL_DIV_to_FLEXCOMM2,
kPLL_DIV_to_FLEXCOMM3,
kPLL_DIV_to_FLEXCOMM4,
kPLL_DIV_to_FLEXCOMM5,
kPLL_DIV_to_FLEXCOMM6,
kPLL_DIV_to_FLEXCOMM7,
kPLL_DIV_to_FLEXCOMM8,
kPLL_DIV_to_FLEXCOMM9,
};
static clock_div_name_t const s_mcxn947_flexcomm_clk_div_map[] = {
kCLOCK_DivFlexcom0Clk,
kCLOCK_DivFlexcom1Clk,
kCLOCK_DivFlexcom2Clk,
kCLOCK_DivFlexcom3Clk,
kCLOCK_DivFlexcom4Clk,
kCLOCK_DivFlexcom5Clk,
kCLOCK_DivFlexcom6Clk,
kCLOCK_DivFlexcom7Clk,
kCLOCK_DivFlexcom8Clk,
kCLOCK_DivFlexcom9Clk,
};
static clock_attach_id_t const s_mcxn947_ctimer_clk_att_map[] = {
kPLL0_to_CTIMER0,
kPLL0_to_CTIMER1,
kPLL0_to_CTIMER2,
kPLL0_to_CTIMER3,
kPLL0_to_CTIMER4,
};
static clock_div_name_t const s_mcxn947_ctimer_clk_div_map[] = {
kCLOCK_DivCtimer0Clk,
kCLOCK_DivCtimer1Clk,
kCLOCK_DivCtimer2Clk,
kCLOCK_DivCtimer3Clk,
kCLOCK_DivCtimer4Clk,
};
static clock_attach_id_t const s_mcxn947_ostimer_clk_att_map[] = {
kCLK_1M_to_OSTIMER,
};
static mcxn947_irqn_prio_t const s_mcxn947_gpio_irqn_map[] = {
{.irqn = GPIO00_IRQn, .priority = 3}, /* TODO: Only IRQ A in use for now. */
{.irqn = GPIO10_IRQn, .priority = 3},
{.irqn = GPIO20_IRQn, .priority = 3},
{.irqn = GPIO30_IRQn, .priority = 3},
{.irqn = GPIO40_IRQn, .priority = 3},
{.irqn = GPIO50_IRQn, .priority = 3},
};
static mcxn947_irqn_prio_t const s_mcxn947_flexcomm_irqn_map[] = {
{.irqn = LP_FLEXCOMM0_IRQn, .priority = 3},
{.irqn = LP_FLEXCOMM1_IRQn, .priority = 3},
{.irqn = LP_FLEXCOMM2_IRQn, .priority = 3},
{.irqn = LP_FLEXCOMM3_IRQn, .priority = 3},
{.irqn = LP_FLEXCOMM4_IRQn, .priority = 3},
{.irqn = LP_FLEXCOMM5_IRQn, .priority = 3},
{.irqn = LP_FLEXCOMM6_IRQn, .priority = 3},
{.irqn = LP_FLEXCOMM7_IRQn, .priority = 3},
{.irqn = LP_FLEXCOMM8_IRQn, .priority = 3},
{.irqn = LP_FLEXCOMM9_IRQn, .priority = 3},
};
static mcxn947_irqn_prio_t const s_mcxn947_usb_irqn_map[] = {
{.irqn = USB0_FS_IRQn, .priority = 2},
{.irqn = USB1_HS_IRQn, .priority = 2},
};
void MCX_BoardEarlyInit(void) {
BOARD_InitBootClocks();
BOARD_InitBootPins();
/* Use PLLDIV clock (50MHz) to clock most of the peripherals. */
CLOCK_AttachClk(kPLL0_to_PLLCLKDIV);
CLOCK_SetClkDiv(kCLOCK_DivPllClk, 3U);
}
int MCX_BoardGetUniqueID(uint64_t *uuid) {
/* TODO: Implement this */
*uuid = 0xAA55BEEF0066CCFF;
return 0;
}
void *MCX_BoardGetPORTInstance(uint8_t id) {
if (id < ARRAY_SIZE(s_mcxn947_port_inst_map)) {
return s_mcxn947_port_inst_map[id];
}
return NULL;
}
void *MCX_BoardGetGPIOInstance(uint8_t id) {
if (id < ARRAY_SIZE(s_mcxn947_gpio_inst_map)) {
return s_mcxn947_gpio_inst_map[id];
}
return NULL;
}
int MCX_BoardConfigurePORTClock(uint8_t id) {
if (id < ARRAY_SIZE(s_mcxn947_port_inst_map)) {
CLOCK_EnableClock(s_mcxn947_port_clk_map[id]);
return 0;
}
return -1;
}
int MCX_BoardConfigureGPIOClock(uint8_t id) {
if (id < ARRAY_SIZE(s_mcxn947_gpio_inst_map)) {
CLOCK_EnableClock(s_mcxn947_gpio_clk_map[id]);
return 0;
}
return -1;
}
int MCX_BoardConfigureGPIOISR(uint8_t id, mcx_board_isr_t isr, void *param) {
if (id >= ARRAY_SIZE(s_mcxn947_irq_table.irq_gpio)) {
return -1;
}
s_mcxn947_irq_table.irq_gpio[id] = isr;
s_mcxn947_irq_table.irq_gpio_params[id] = param;
if (isr == NULL) {
DisableIRQ(s_mcxn947_gpio_irqn_map[id].irqn);
} else {
NVIC_SetPriority(s_mcxn947_gpio_irqn_map[id].irqn, s_mcxn947_gpio_irqn_map[id].priority);
EnableIRQ(s_mcxn947_gpio_irqn_map[id].irqn);
}
return 0;
}
void MCX_BoardGenericGPIOISR(uint8_t id) {
if (id >= ARRAY_SIZE(s_mcxn947_irq_table.irq_gpio)) {
return;
}
mcx_board_isr_t isr = s_mcxn947_irq_table.irq_gpio[id];
if (isr == NULL) {
return;
}
isr(s_mcxn947_irq_table.irq_gpio_params[id]);
}
void *MCX_BoardGetADCInstance(uint8_t id) {
if (id < ARRAY_SIZE(s_mcxn947_adc_inst_map)) {
return s_mcxn947_adc_inst_map[id];
}
return NULL;
}
int MCX_BoardConfigureADCClock(uint8_t id) {
clock_attach_id_t attach_id = kNONE_to_NONE;
clock_div_name_t div_name;
if (id >= ARRAY_SIZE(s_mcxn947_adc_clk_att_map)) {
return -1;
}
attach_id = s_mcxn947_adc_clk_att_map[id];
div_name = s_mcxn947_adc_clk_div_map[id];
CLOCK_AttachClk(attach_id);
CLOCK_SetClkDiv(div_name, 1U);
return CLOCK_GetAdcClkFreq(id);
}
void *MCX_BoardGetUARTInstance(uint8_t id) {
if (id < ARRAY_SIZE(s_mcxn947_uart_inst_map)) {
return s_mcxn947_uart_inst_map[id];
}
/* No such UART */
return NULL;
}
void *MCX_BoardGetI2CInstance(uint8_t id) {
if (id < ARRAY_SIZE(s_mcxn947_i2c_inst_map)) {
return s_mcxn947_i2c_inst_map[id];
}
/* No such I2C */
return NULL;
}
void *MCX_BoardGetSPIInstance(uint8_t id) {
if (id < ARRAY_SIZE(s_mcxn947_spi_inst_map)) {
return s_mcxn947_spi_inst_map[id];
}
/* No such SPI */
return NULL;
}
static int MCX_BoardConfigureLPFCClock(uint8_t id) {
clock_attach_id_t attach_id = kNONE_to_NONE;
clock_div_name_t div_name;
if (id >= ARRAY_SIZE(s_mcxn947_flexcomm_clk_att_map)) {
return -1;
}
attach_id = s_mcxn947_flexcomm_clk_att_map[id];
div_name = s_mcxn947_flexcomm_clk_div_map[id];
CLOCK_AttachClk(attach_id);
CLOCK_SetClkDiv(div_name, 1U);
return CLOCK_GetLPFlexCommClkFreq(id);
}
int MCX_BoardConfigureUARTClock(uint8_t id) {
return MCX_BoardConfigureLPFCClock(id);
}
int MCX_BoardConfigureI2CClock(uint8_t id) {
return MCX_BoardConfigureLPFCClock(id);
}
int MCX_BoardConfigureSPIClock(uint8_t id) {
return MCX_BoardConfigureLPFCClock(id);
}
int MCX_BoardConfigureUARTISR(uint8_t id, mcx_board_isr_t isr, void *param) {
if (id >= ARRAY_SIZE(s_mcxn947_irq_table.irq_uart)) {
return -1;
}
s_mcxn947_irq_table.irq_uart[id] = isr;
s_mcxn947_irq_table.irq_uart_params[id] = param;
/* Pass NULL as ISR to disable IRQ. */
if (isr == NULL) {
DisableIRQ(s_mcxn947_flexcomm_irqn_map[id].irqn);
} else {
NVIC_SetPriority(s_mcxn947_flexcomm_irqn_map[id].irqn, s_mcxn947_flexcomm_irqn_map[id].priority);
EnableIRQ(s_mcxn947_flexcomm_irqn_map[id].irqn);
}
return 0;
}
void MCX_BoardGenericUARTISR(uint8_t id) {
if (id >= ARRAY_SIZE(s_mcxn947_irq_table.irq_uart)) {
return;
}
mcx_board_isr_t isr = s_mcxn947_irq_table.irq_uart[id];
if (isr == NULL) {
return;
}
isr(s_mcxn947_irq_table.irq_uart_params[id]);
}
void *MCX_BoardGetCT32Instance(uint8_t id) {
if (id < ARRAY_SIZE(s_mcxn947_ctimer_inst_map)) {
return s_mcxn947_ctimer_inst_map[id];
}
/* No such CTIMER */
return NULL;
}
int MCX_BoardConfigureCT32Clock(uint8_t id) {
clock_attach_id_t attach_id = kNONE_to_NONE;
clock_div_name_t div_name;
if (id >= ARRAY_SIZE(s_mcxn947_ctimer_clk_att_map)) {
return -1;
}
attach_id = s_mcxn947_ctimer_clk_att_map[id];
div_name = s_mcxn947_ctimer_clk_div_map[id];
CLOCK_AttachClk(attach_id);
CLOCK_SetClkDiv(div_name, 1U);
return CLOCK_GetCTimerClkFreq(id);
}
void *MCX_BoardGetOSTimerInstance(uint8_t id) {
if (id < ARRAY_SIZE(s_mcxn947_ostimer_inst_map)) {
return s_mcxn947_ostimer_inst_map[id];
}
/* No such OSTimer */
return NULL;
}
int MCX_BoardConfigureUSBClock(uint8_t id) {
if (id >= ARRAY_SIZE(s_mcxn947_usb_irqn_map)) {
return -1;
}
switch (id) {
case 0: {
/* TODO: Configure FS USB here. */
break;
}
case 1: {
CLOCK_SetupExtClocking(24000000);
CLOCK_SetupClockCtrl(kCLOCK_CLKIN_ENA_FM_USBH_LPT);
CLOCK_EnableClock(kCLOCK_UsbHs);
CLOCK_EnableClock(kCLOCK_UsbHsPhy);
CLOCK_EnableUsbhsPhyPllClock(kCLOCK_Usbphy480M, 24000000);
CLOCK_EnableUsbhsClock();
break;
}
default:
break;
}
return 0;
}
int MCX_BoardConfigureUSBPHY(uint8_t id) {
if (id >= ARRAY_SIZE(s_mcxn947_gpio_irqn_map)) {
return -1;
}
switch (id) {
case 0: {
/* TODO: Implement this */
break;
}
case 1: {
USBPHY->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL2_MASK | USBPHY_CTRL_SET_ENUTMILEVEL3_MASK;
USBPHY->PWD = 0;
break;
}
default:
break;
}
return 0;
}
int MCX_BoardConfigureUSBISR(uint8_t id, mcx_board_isr_t isr, void *param) {
if (id >= ARRAY_SIZE(s_mcxn947_irq_table.irq_usb)) {
return -1;
}
s_mcxn947_irq_table.irq_usb[id] = isr;
s_mcxn947_irq_table.irq_usb_params[id] = param;
/* Pass NULL as ISR to disable IRQ. */
if (isr == NULL) {
DisableIRQ(s_mcxn947_usb_irqn_map[id].irqn);
} else {
NVIC_SetPriority(s_mcxn947_usb_irqn_map[id].irqn, s_mcxn947_usb_irqn_map[id].priority);
EnableIRQ(s_mcxn947_usb_irqn_map[id].irqn);
}
return 0;
}
void MCX_BoardGenericUSBISR(uint8_t id) {
if (id >= ARRAY_SIZE(s_mcxn947_irq_table.irq_usb)) {
return;
}
mcx_board_isr_t isr = s_mcxn947_irq_table.irq_usb[id];
if (isr == NULL) {
return;
}
isr(s_mcxn947_irq_table.irq_usb_params[id]);
}
int MCX_BoardConfigureOSTimerClock(uint8_t id) {
clock_attach_id_t attach_id = kNONE_to_NONE;
if (id >= ARRAY_SIZE(s_mcxn947_ostimer_clk_att_map)) {
return -1;
}
attach_id = s_mcxn947_ostimer_clk_att_map[id];
CLOCK_AttachClk(attach_id);
return CLOCK_GetOstimerClkFreq();
}
int MCX_BoardConfigureOSTimerISR(uint8_t id, mcx_board_isr_t isr, void *param) {
if (id >= ARRAY_SIZE(s_mcxn947_irq_table.irq_ostimer)) {
return -1;
}
s_mcxn947_irq_table.irq_ostimer[id] = isr;
s_mcxn947_irq_table.irq_ostimer_params[id] = param;
return 0;
}
void MCX_BoardGenericOSTimerISR(uint8_t id) {
if (id >= ARRAY_SIZE(s_mcxn947_irq_table.irq_ostimer)) {
return;
}
mcx_board_isr_t isr = s_mcxn947_irq_table.irq_ostimer[id];
if (isr == NULL) {
return;
}
isr(s_mcxn947_irq_table.irq_ostimer_params[id]);
}

Wyświetl plik

@ -0,0 +1,162 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2023 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/***********************************************************************************************************************
* This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file
* will be overwritten if the respective MCUXpresso Config Tools is used to update this file.
**********************************************************************************************************************/
/*
* How to setup clock using clock driver functions:
*
* 1. Setup clock sources.
*
* 2. Set up wait states of the flash.
*
* 3. Set up all dividers.
*
* 4. Set up all selectors to provide selected clocks.
*
*/
/* clang-format off */
/* TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
!!GlobalInfo
product: Clocks v12.0
processor: MCXN947
package_id: MCXN947VDF
mcu_data: ksdk2_0
processor_version: 0.14.14
* BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/
/* clang-format on */
#include "fsl_clock.h"
#include "clock_config.h"
#include "fsl_spc.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/*******************************************************************************
* Variables
******************************************************************************/
/* System clock frequency. */
extern uint32_t SystemCoreClock;
/*******************************************************************************
************************ BOARD_InitBootClocks function ************************
******************************************************************************/
void BOARD_InitBootClocks(void) {
BOARD_BootClockPLL150M();
}
/*******************************************************************************
******************** Configuration BOARD_BootClockPLL150M *********************
******************************************************************************/
/* clang-format off */
/* TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
!!Configuration
name: BOARD_BootClockPLL150M
called_from_default_init: true
outputs:
- {id: CLK_144M_clock.outFreq, value: 144 MHz}
- {id: CLK_48M_clock.outFreq, value: 48 MHz}
- {id: FRO_12M_clock.outFreq, value: 12 MHz}
- {id: FRO_HF_clock.outFreq, value: 48 MHz}
- {id: MAIN_clock.outFreq, value: 150 MHz}
- {id: PLL0_CLK_clock.outFreq, value: 150 MHz}
- {id: Slow_clock.outFreq, value: 37.5 MHz}
- {id: System_clock.outFreq, value: 150 MHz}
- {id: gdet_clock.outFreq, value: 48 MHz}
- {id: trng_clock.outFreq, value: 48 MHz}
settings:
- {id: PLL0_Mode, value: Normal}
- {id: RunPowerMode, value: OD}
- {id: SCGMode, value: PLL0}
- {id: SCG.PLL0M_MULT.scale, value: '50', locked: true}
- {id: SCG.PLL0SRCSEL.sel, value: SCG.FIRC_48M}
- {id: SCG.PLL0_NDIV.scale, value: '8', locked: true}
- {id: SCG.SCSSEL.sel, value: SCG.PLL0_CLK}
- {id: SYSCON.FLEXSPICLKSEL.sel, value: NO_CLOCK}
- {id: SYSCON.FREQMEREFCLKSEL.sel, value: SYSCON.evtg_out0a}
- {id: SYSCON.FREQMETARGETCLKSEL.sel, value: SYSCON.evtg_out0a}
* BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/
/* clang-format on */
/*******************************************************************************
* Variables for BOARD_BootClockPLL150M configuration
******************************************************************************/
/*******************************************************************************
* Code for BOARD_BootClockPLL150M configuration
******************************************************************************/
void BOARD_BootClockPLL150M(void) {
CLOCK_EnableClock(kCLOCK_Scg); /*!< Enable SCG clock */
/* FRO OSC setup - begin, attach FRO12M to MainClock for safety switching */
CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /*!< Switch to FRO 12M first to ensure we can change the clock setting */
/* Set the DCDC VDD regulator to 1.2 V voltage level */
spc_active_mode_dcdc_option_t dcdcOpt = {
.DCDCVoltage = kSPC_DCDC_OverdriveVoltage,
.DCDCDriveStrength = kSPC_DCDC_NormalDriveStrength,
};
SPC_SetActiveModeDCDCRegulatorConfig(SPC0, &dcdcOpt);
/* Set the LDO_CORE VDD regulator to 1.2 V voltage level */
spc_active_mode_core_ldo_option_t ldoOpt = {
.CoreLDOVoltage = kSPC_CoreLDO_OverDriveVoltage,
.CoreLDODriveStrength = kSPC_CoreLDO_NormalDriveStrength,
};
SPC_SetActiveModeCoreLDORegulatorConfig(SPC0, &ldoOpt);
/* Configure Flash wait-states to support 1.2V voltage level and 150000000Hz frequency */;
FMU0->FCTRL = (FMU0->FCTRL & ~((uint32_t)FMU_FCTRL_RWSC_MASK)) | (FMU_FCTRL_RWSC(0x3U));
/* Specifies the 1.2V operating voltage for the SRAM's read/write timing margin */
spc_sram_voltage_config_t sramCfg = {
.operateVoltage = kSPC_sramOperateAt1P2V,
.requestVoltageUpdate = true,
};
SPC_SetSRAMOperateVoltage(SPC0, &sramCfg);
CLOCK_SetupFROHFClocking(48000000U); /*!< Enable FRO HF(48MHz) output */
/*!< Set up PLL0 */
const pll_setup_t pll0Setup = {
.pllctrl = SCG_APLLCTRL_SOURCE(1U) | SCG_APLLCTRL_SELI(27U) | SCG_APLLCTRL_SELP(13U),
.pllndiv = SCG_APLLNDIV_NDIV(8U),
.pllpdiv = SCG_APLLPDIV_PDIV(1U),
.pllmdiv = SCG_APLLMDIV_MDIV(50U),
.pllRate = 150000000U
};
CLOCK_SetPLL0Freq(&pll0Setup); /*!< Configure PLL0 to the desired values */
CLOCK_SetPll0MonitorMode(kSCG_Pll0MonitorDisable); /* Pll0 Monitor is disabled */
/*!< Set up clock selectors */
CLOCK_AttachClk(kPLL0_to_MAIN_CLK);
/*!< Set up dividers */
CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U); /*!< Set AHBCLKDIV divider to value 1 */
/* Set SystemCoreClock variable */
SystemCoreClock = BOARD_BOOTCLOCKPLL150M_CORE_CLOCK;
}

Wyświetl plik

@ -0,0 +1,86 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2023 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/***********************************************************************************************************************
* This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file
* will be overwritten if the respective MCUXpresso Config Tools is used to update this file.
**********************************************************************************************************************/
#ifndef _CLOCK_CONFIG_H_
#define _CLOCK_CONFIG_H_
#include "fsl_common.h"
/*******************************************************************************
* Definitions
******************************************************************************/
#define BOARD_XTAL0_CLK_HZ 24000000U /*!< Board xtal0 frequency in Hz */
/*******************************************************************************
************************ BOARD_InitBootClocks function ************************
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus*/
/*!
* @brief This function executes default configuration of clocks.
*
*/
void BOARD_InitBootClocks(void);
#if defined(__cplusplus)
}
#endif /* __cplusplus*/
/*******************************************************************************
******************** Configuration BOARD_BootClockPLL150M *********************
******************************************************************************/
/*******************************************************************************
* Definitions for BOARD_BootClockPLL150M configuration
******************************************************************************/
#define BOARD_BOOTCLOCKPLL150M_CORE_CLOCK 150000000U /*!< Core clock frequency: 150000000Hz */
#define BOARD_BOOTCLOCKPLL150M_ROSC_CLOCK 0U /*!< ROSC clock frequency: 0Hz */
/*******************************************************************************
* API for BOARD_BootClockPLL150M configuration
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus*/
/*!
* @brief This function executes configuration of clocks.
*
*/
void BOARD_BootClockPLL150M(void);
#if defined(__cplusplus)
}
#endif /* __cplusplus*/
#endif /* _CLOCK_CONFIG_H_ */

Wyświetl plik

@ -0,0 +1,103 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2024 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "board.h"
void MCX_BoardGenericGPIOISR(uint8_t id);
void MCX_BoardGenericUARTISR(uint8_t id);
void MCX_BoardGenericUSBISR(uint8_t id);
void GPIO00_IRQHandler(void) {
MCX_BoardGenericGPIOISR(0);
}
void GPIO10_IRQHandler(void) {
MCX_BoardGenericGPIOISR(1);
}
void GPIO20_IRQHandler(void) {
MCX_BoardGenericGPIOISR(2);
}
void GPIO30_IRQHandler(void) {
MCX_BoardGenericGPIOISR(3);
}
void GPIO40_IRQHandler(void) {
MCX_BoardGenericGPIOISR(4);
}
void GPIO50_IRQHandler(void) {
MCX_BoardGenericGPIOISR(5);
}
void LP_FLEXCOMM0_IRQHandler(void) {
MCX_BoardGenericUARTISR(0);
}
void LP_FLEXCOMM1_IRQHandler(void) {
MCX_BoardGenericUARTISR(1);
}
void LP_FLEXCOMM2_IRQHandler(void) {
MCX_BoardGenericUARTISR(2);
}
void LP_FLEXCOMM3_IRQHandler(void) {
MCX_BoardGenericUARTISR(3);
}
void LP_FLEXCOMM4_IRQHandler(void) {
MCX_BoardGenericUARTISR(4);
}
void LP_FLEXCOMM5_IRQHandler(void) {
MCX_BoardGenericUARTISR(5);
}
void LP_FLEXCOMM6_IRQHandler(void) {
MCX_BoardGenericUARTISR(6);
}
void LP_FLEXCOMM7_IRQHandler(void) {
MCX_BoardGenericUARTISR(7);
}
void LP_FLEXCOMM8_IRQHandler(void) {
MCX_BoardGenericUARTISR(8);
}
void LP_FLEXCOMM9_IRQHandler(void) {
MCX_BoardGenericUARTISR(9);
}
void USB0_FS_IRQHandler(void) {
MCX_BoardGenericUSBISR(0);
}
void USB1_HS_IRQHandler(void) {
MCX_BoardGenericUSBISR(1);
}

Wyświetl plik

@ -0,0 +1 @@
include("$(BOARD_DIR)/manifest.py")

Wyświetl plik

@ -0,0 +1,12 @@
#define MICROPY_HW_BOARD_NAME "FRDM_MCXN947"
#define MICROPY_HW_MCU_NAME "MCXN947VDF"
#define MICROPY_HW_ENABLE_UART_REPL (1)
#define MICROPY_HW_UART_REPL (4)
#define MICROPY_HW_ENABLE_USBDEV (1)
#define MICROPY_HW_USBDEV (1)
#define MICROPY_HW_ENABLE_IFS (1)
#define MICROPY_HW_IFS_START (0x100000U)
#define MICROPY_HW_IFS_LENGTH (0x100000U)

Wyświetl plik

@ -0,0 +1,12 @@
TARGET_MCU_SERIES = MCXN947
TARGET_MCU_PART = MCXN947VDF
TARGET_MCU_CORE = cm33_core0
TARGET_MCU_CORE_HAS_DSP = 1
TARGET_MCU_CORE_HAS_FPU = 1
TARGET_MCU_AF_FILE = boards/mcxn947_af.csv
TARGET_HEAP_SIZE = 0x20000
TARGET_STACK_SIZE = 0x8000
# Extmod settings
MICROPY_VFS_LFS2 = 1

Wyświetl plik

@ -0,0 +1,102 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2023 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/***********************************************************************************************************************
* This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file
* will be overwritten if the respective MCUXpresso Config Tools is used to update this file.
**********************************************************************************************************************/
/* clang-format off */
/*
* TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
!!GlobalInfo
product: Pins v14.0
processor: MCXN947
package_id: MCXN947VDF
mcu_data: ksdk2_0
processor_version: 0.14.14
* BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS ***********
*/
/* clang-format on */
#include "fsl_common.h"
#include "fsl_port.h"
#include "pin_mux.h"
/* FUNCTION ************************************************************************************************************
*
* Function Name : BOARD_InitBootPins
* Description : Calls initialization functions.
*
* END ****************************************************************************************************************/
void BOARD_InitBootPins(void) {
BOARD_InitUartConsolePins();
}
/* clang-format off */
/*
* TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
BOARD_InitUartConsolePins:
- options: {callFromInitBoot: 'true', coreID: cm33_core0, enableClock: 'true'}
- pin_list:
- {pin_num: A1, peripheral: LP_FLEXCOMM4, signal: LPFLEXCOMM_P0, pin_signal: PIO1_8/WUU0_IN10/LPTMR1_ALT3/TRACE_DATA0/FC4_P0/FC5_P4/CT_INP8/SCT0_OUT2/FLEXIO0_D16/PLU_OUT0/ENET0_TXD2/I3C1_SDA/TSI0_CH17/ADC1_A8}
- {pin_num: B1, peripheral: LP_FLEXCOMM4, signal: LPFLEXCOMM_P1, pin_signal: PIO1_9/TRACE_DATA1/FC4_P1/FC5_P5/CT_INP9/SCT0_OUT3/FLEXIO0_D17/PLU_OUT1/ENET0_TXD3/I3C1_SCL/TSI0_CH18/ADC1_A9}
* BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS ***********
*/
/* clang-format on */
/* FUNCTION ************************************************************************************************************
*
* Function Name : BOARD_InitUartConsolePins
* Description : Configures pin routing and optionally pin electrical features.
*
* END ****************************************************************************************************************/
void BOARD_InitUartConsolePins(void) {
/* Enables the clock for PORT1: Enables clock */
CLOCK_EnableClock(kCLOCK_Port1);
/* PORT1_8 (pin A1) is configured as FC4_P0 */
PORT_SetPinMux(PORT1, 8U, kPORT_MuxAlt2);
PORT1->PCR[8] = ((PORT1->PCR[8] &
/* Mask bits to zero which are setting */
(~(PORT_PCR_IBE_MASK)))
/* Input Buffer Enable: Enables. */
| PORT_PCR_IBE(PCR_IBE_ibe1));
/* PORT1_9 (pin B1) is configured as FC4_P1 */
PORT_SetPinMux(PORT1, 9U, kPORT_MuxAlt2);
PORT1->PCR[9] = ((PORT1->PCR[9] &
/* Mask bits to zero which are setting */
(~(PORT_PCR_IBE_MASK)))
/* Input Buffer Enable: Enables. */
| PORT_PCR_IBE(PCR_IBE_ibe1));
}
/***********************************************************************************************************************
* EOF
**********************************************************************************************************************/

Wyświetl plik

@ -0,0 +1,72 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2023 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/***********************************************************************************************************************
* This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file
* will be overwritten if the respective MCUXpresso Config Tools is used to update this file.
**********************************************************************************************************************/
#ifndef _PIN_MUX_H_
#define _PIN_MUX_H_
/*!
* @addtogroup pin_mux
* @{
*/
/***********************************************************************************************************************
* API
**********************************************************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @brief Calls initialization functions.
*
*/
void BOARD_InitBootPins(void);
#define PCR_IBE_ibe1 0x01u /*!<@brief Input Buffer Enable: Enables */
/*!
* @brief Configures pin routing and optionally pin electrical features.
*
*/
void BOARD_InitUartConsolePins(void);
#if defined(__cplusplus)
}
#endif
/*!
* @}
*/
#endif /* _PIN_MUX_H_ */
/***********************************************************************************************************************
* EOF
**********************************************************************************************************************/

Wyświetl plik

@ -0,0 +1,124 @@
P0_0 ,P0_0
P0_1 ,P0_1
P0_2 ,P0_2
P0_3 ,P0_3
P0_4 ,P0_4
P0_5 ,P0_5
P0_6 ,P0_6
P0_7 ,P0_7
P0_8 ,P0_8
P0_9 ,P0_9
D9 ,P0_10
P0_11 ,P0_11
P0_12 ,P0_12
P0_13 ,P0_13
A2 ,P0_14
A4 ,P0_15
P0_16 ,P0_16
P0_17 ,P0_17
P0_18 ,P0_18
P0_19 ,P0_19
P0_20 ,P0_20
P0_21 ,P0_21
A3 ,P0_22
A5 ,P0_23
D11 ,P0_24
D13 ,P0_25
D12 ,P0_26
D10 ,P0_27
D8 ,P0_28
D2 ,P0_29
D4 ,P0_30
D7 ,P0_31
P1_0 ,P1_0
P1_1 ,P1_1
D6 ,P1_2
P1_3 ,P1_3
P1_4 ,P1_4
P1_5 ,P1_5
P1_6 ,P1_6
P1_7 ,P1_7
P1_8 ,P1_8
P1_9 ,P1_9
P1_10 ,P1_10
P1_11 ,P1_11
P1_12 ,P1_12
P1_13 ,P1_13
P1_14 ,P1_14
P1_15 ,P1_15
P1_16 ,P1_16
P1_17 ,P1_17
P1_18 ,P1_18
P1_19 ,P1_19
P1_20 ,P1_20
D5 ,P1_21
P1_22 ,P1_22
D3 ,P1_23
P1_30 ,P1_30
P1_31 ,P1_31
P2_0 ,P2_0
P2_1 ,P2_1
P2_2 ,P2_2
P2_3 ,P2_3
P2_4 ,P2_4
P2_5 ,P2_5
P2_6 ,P2_6
P2_7 ,P2_7
P2_8 ,P2_8
P2_9 ,P2_9
P2_10 ,P2_10
P2_11 ,P2_11
P3_0 ,P3_0
P3_1 ,P3_1
P3_2 ,P3_2
P3_3 ,P3_3
P3_4 ,P3_4
P3_5 ,P3_5
P3_6 ,P3_6
P3_7 ,P3_7
P3_8 ,P3_8
P3_9 ,P3_9
P3_10 ,P3_10
P3_11 ,P3_11
P3_12 ,P3_12
P3_13 ,P3_13
P3_14 ,P3_14
P3_15 ,P3_15
P3_16 ,P3_16
P3_17 ,P3_17
P3_18 ,P3_18
P3_19 ,P3_19
P3_20 ,P3_20
P3_21 ,P3_21
P3_22 ,P3_22
P3_23 ,P3_23
D18 ,P4_0
D19 ,P4_1
D1 ,P4_2
D0 ,P4_3
P4_4 ,P4_4
P4_5 ,P4_5
P4_6 ,P4_6
P4_7 ,P4_7
P4_12 ,P4_12
P4_13 ,P4_13
P4_14 ,P4_14
P4_15 ,P4_15
P4_16 ,P4_16
P4_17 ,P4_17
P4_18 ,P4_18
P4_19 ,P4_19
P4_20 ,P4_20
P4_21 ,P4_21
P4_22 ,P4_22
P4_23 ,P4_23
P5_0 ,P5_0
P5_1 ,P5_1
P5_2 ,P5_2
P5_3 ,P5_3
P5_4 ,P5_4
P5_5 ,P5_5
P5_6 ,P5_6
P5_7 ,P5_7
P5_8 ,P5_8
P5_9 ,P5_9
1 P0_0 P0_0
2 P0_1 P0_1
3 P0_2 P0_2
4 P0_3 P0_3
5 P0_4 P0_4
6 P0_5 P0_5
7 P0_6 P0_6
8 P0_7 P0_7
9 P0_8 P0_8
10 P0_9 P0_9
11 D9 P0_10
12 P0_11 P0_11
13 P0_12 P0_12
14 P0_13 P0_13
15 A2 P0_14
16 A4 P0_15
17 P0_16 P0_16
18 P0_17 P0_17
19 P0_18 P0_18
20 P0_19 P0_19
21 P0_20 P0_20
22 P0_21 P0_21
23 A3 P0_22
24 A5 P0_23
25 D11 P0_24
26 D13 P0_25
27 D12 P0_26
28 D10 P0_27
29 D8 P0_28
30 D2 P0_29
31 D4 P0_30
32 D7 P0_31
33 P1_0 P1_0
34 P1_1 P1_1
35 D6 P1_2
36 P1_3 P1_3
37 P1_4 P1_4
38 P1_5 P1_5
39 P1_6 P1_6
40 P1_7 P1_7
41 P1_8 P1_8
42 P1_9 P1_9
43 P1_10 P1_10
44 P1_11 P1_11
45 P1_12 P1_12
46 P1_13 P1_13
47 P1_14 P1_14
48 P1_15 P1_15
49 P1_16 P1_16
50 P1_17 P1_17
51 P1_18 P1_18
52 P1_19 P1_19
53 P1_20 P1_20
54 D5 P1_21
55 P1_22 P1_22
56 D3 P1_23
57 P1_30 P1_30
58 P1_31 P1_31
59 P2_0 P2_0
60 P2_1 P2_1
61 P2_2 P2_2
62 P2_3 P2_3
63 P2_4 P2_4
64 P2_5 P2_5
65 P2_6 P2_6
66 P2_7 P2_7
67 P2_8 P2_8
68 P2_9 P2_9
69 P2_10 P2_10
70 P2_11 P2_11
71 P3_0 P3_0
72 P3_1 P3_1
73 P3_2 P3_2
74 P3_3 P3_3
75 P3_4 P3_4
76 P3_5 P3_5
77 P3_6 P3_6
78 P3_7 P3_7
79 P3_8 P3_8
80 P3_9 P3_9
81 P3_10 P3_10
82 P3_11 P3_11
83 P3_12 P3_12
84 P3_13 P3_13
85 P3_14 P3_14
86 P3_15 P3_15
87 P3_16 P3_16
88 P3_17 P3_17
89 P3_18 P3_18
90 P3_19 P3_19
91 P3_20 P3_20
92 P3_21 P3_21
93 P3_22 P3_22
94 P3_23 P3_23
95 D18 P4_0
96 D19 P4_1
97 D1 P4_2
98 D0 P4_3
99 P4_4 P4_4
100 P4_5 P4_5
101 P4_6 P4_6
102 P4_7 P4_7
103 P4_12 P4_12
104 P4_13 P4_13
105 P4_14 P4_14
106 P4_15 P4_15
107 P4_16 P4_16
108 P4_17 P4_17
109 P4_18 P4_18
110 P4_19 P4_19
111 P4_20 P4_20
112 P4_21 P4_21
113 P4_22 P4_22
114 P4_23 P4_23
115 P5_0 P5_0
116 P5_1 P5_1
117 P5_2 P5_2
118 P5_3 P5_3
119 P5_4 P5_4
120 P5_5 P5_5
121 P5_6 P5_6
122 P5_7 P5_7
123 P5_8 P5_8
124 P5_9 P5_9

Wyświetl plik

@ -0,0 +1,161 @@
#!/usr/bin/env python
"""Creates the pin file for MCX series"""
import os
import re
import sys
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "../../../tools"))
import boardgen
# Dictionary contains the supported AF and its regexp to select one
SUPPORTED_AF = {
"GPIO": "P([0-9]+)_([0-9]+)",
"LPFC": "FC([0-9]+)_P([0-9]+)",
"CT32": "CT([0-9]*)_(MAT|INP)([0-9]+)",
}
ADC_RE = "ADC([0-9]+)_([A-B])([0-9]+)"
class MCXPin(boardgen.Pin):
def __init__(self, cpu_pin_name):
super().__init__(cpu_pin_name)
self.__af_table = []
self.__adc_table = []
def add_af(self, af_idx, af_name, af):
if af_name == "ADC":
m = re.match(ADC_RE, af)
if not m:
print("Unable to detect ADC parameter from AF {:s}".format(af))
else:
self.__af_add_adc(int(m.group(1)), m.group(2), int(m.group(3)))
else:
for k, v in SUPPORTED_AF.items():
m = re.match(v, af)
if m:
match k:
case "GPIO":
self.__af_add_gpio(af_idx, int(m.group(1)), int(m.group(2)))
case "LPFC":
self.__af_add_flexcomm(af_idx, int(m.group(1)), int(m.group(2)))
case "CT32":
# Instance may be None.
instance = m.group(1)
if instance == "":
instance = "0"
attribute = "{:s}{:s}".format(m.group(2), m.group(3))
self.__af_add_ctimer(af_idx, int(instance), attribute)
case _:
# Simply does not exist.
print("??")
def definition(self):
port, pin = self.__get_pin_id()
af_name = "pin_{:d}_{:d}_af".format(port, pin)
adc_name = "NULL"
if len(self.__adc_table):
adc_name = "&pin_{:d}_{:d}_adc".format(port, pin)
pin_def = "PIN({:s}, {:d}, {:d}, {:s}, {:s})".format(
self.name(), port, pin, af_name, adc_name
)
return pin_def
def print_source(self, out_source):
port, pin = self.__get_pin_id()
print("const machine_pin_af_t pin_{:d}_{:d}_af[] = {{".format(port, pin), file=out_source)
for af_item in self.__af_table:
print(
" AF({:d}, {:s}, {:d}, {:s}),".format(
af_item["index"], af_item["type"], af_item["instance"], af_item["attribute"]
),
file=out_source,
)
print("};", file=out_source)
for adc_item in self.__adc_table:
# Add ADC item entries.
print(
"const machine_pin_adc_t pin_{:d}_{:d}_adc = ADC({:d}, '{:s}', {:d});".format(
port, pin, adc_item["instance"], adc_item["side"], adc_item["channel"]
),
file=out_source,
)
print("", file=out_source)
def __af_add_adc(self, instance, side, channel):
self.__adc_table.append({"instance": instance, "side": side, "channel": channel})
def __af_add_gpio(self, af_idx, instance, attribute):
self.__af_table.append(
{
"type": "GPIO",
"index": af_idx,
"instance": instance,
"attribute": "GPIO_P{:d}".format(attribute),
}
)
def __af_add_flexcomm(self, af_idx, instance, attribute):
self.__af_table.append(
{
"type": "LPFC",
"index": af_idx,
"instance": instance,
"attribute": "LPFC_P{:d}".format(attribute),
}
)
def __af_add_ctimer(self, af_idx, instance, attribute):
self.__af_table.append(
{
"type": "CT32",
"index": af_idx,
"instance": instance,
"attribute": "CT32_{:s}".format(attribute),
}
)
def __get_pin_id(self):
m = re.match("P([0-9]+)_([0-9]+)", self.name())
if not m:
raise boardgen.PinGeneratorError(
"Port ID not found for given pin {:s}".format(self.name())
)
return int(m.group(1)), int(m.group(2))
class MCXPinGenerator(boardgen.PinGenerator):
def __init__(self):
# Use custom pin type above, and also enable the --af-csv argument.
super().__init__(
pin_type=MCXPin,
enable_af=True,
)
def board_name_define_prefix(self):
return "pyb_"
def parse_af_csv(self, filename):
return super().parse_af_csv(filename, header_rows=1, pin_col=1, af_col=2)
def print_source(self, out_source):
super().print_source(out_source)
def print_header(self, out_header):
super().print_header(out_header)
if __name__ == "__main__":
MCXPinGenerator().main()

Wyświetl plik

@ -0,0 +1,7 @@
include("$(MPY_DIR)/extmod/asyncio")
require("onewire")
require("ds18x20")
require("dht")
freeze("$(PORT_DIR)/modules")

Wyświetl plik

@ -0,0 +1,37 @@
// mcx_pin_prefix.c becomes the initial portion of the generated pins file.
#include <stdio.h>
#include "py/obj.h"
#include "py/mphal.h"
#include "extmod/modmachine.h"
/* Struct definitions */
#include "machine_pin.h"
#define AF(p_af_id, p_af_type, p_af_inst, p_af_attr) \
{ \
.af_id = p_af_id, \
.af_type = MACHINE_PIN_AF_TYPE_##p_af_type, \
.af_instance_id = p_af_inst, \
.af_attribute = MACHINE_PIN_AF_ATTR_##p_af_attr, \
}
#define ADC(p_adc_id, p_adc_side, p_adc_channel) \
{ \
.adc_id = p_adc_id, \
.adc_side = p_adc_side, \
.adc_channel = p_adc_channel, \
}
#define PIN(p_name, p_port, p_pin, p_af, p_adc) \
{ \
{ &machine_pin_type }, \
.name = MP_QSTR_##p_name, \
.port = p_port, \
.pin = p_pin, \
.af_count = sizeof(p_af) / sizeof(p_af[0]), \
.af = p_af, \
.adc = p_adc, \
}

Wyświetl plik

@ -0,0 +1,125 @@
Port ,Pin ,AF0 ,AF1 ,AF2 ,AF3 ,AF4 ,AF5 ,AF6 ,AF7 ,AF8 ,AF9 ,AF10 ,AF11 ,AF12 ,AF13 ,AF14 ,AF15 ,ADC
PORT1 ,P1_8 ,P1_8 ,TRACE_DATA0 ,FC4_P0 ,FC5_P4 ,CT_INP8 ,SCT0_OUT2 ,FLEXIO0_D16 ,EZH_PIO4 ,PLU_OUT0 ,ENET0_TXD2 ,I3C1_SDA , , , , , ,ADC1_A8
PORT1 ,P1_9 ,P1_9 ,TRACE_DATA1 ,FC4_P1 ,FC5_P5 ,CT_INP9 ,SCT0_OUT3 ,FLEXIO0_D17 ,EZH_PIO5 ,PLU_OUT1 ,ENET0_TXD3 ,I3C1_SCL , , , , , ,ADC1_A9
PORT1 ,P1_10 ,P1_10 ,TRACE_DATA2 ,FC4_P2 ,FC5_P6 ,CT2_MAT0 ,SCT0_IN2 ,FLEXIO0_D18 ,EZH_PIO6 ,PLU_IN0 ,ENET0_TXER , ,CAN0_TXD , , , , ,ADC1_A10
PORT1 ,P1_11 ,P1_11 ,TRACE_DATA3 ,FC4_P3 , ,CT2_MAT1 ,SCT0_IN3 ,FLEXIO0_D19 ,EZH_PIO7 ,PLU_IN1 ,ENET0_RX_CLK ,I3C1_PUR ,CAN0_RXD , , , , ,ADC1_A11
PORT1 ,P1_12 ,P1_12 ,TRACE_CLK ,FC4_P4 ,FC3_P0 ,CT2_MAT2 ,SCT0_OUT4 ,FLEXIO0_D20 ,EZH_PIO8 ,PLU_OUT2 ,ENET0_RXER , ,CAN1_RXD , , , , ,ADC1_A12
PORT1 ,P1_13 ,P1_13 ,TRIG_IN3 ,FC4_P5 ,FC3_P1 ,CT2_MAT3 ,SCT0_OUT5 ,FLEXIO0_D21 ,EZH_PIO9 ,PLU_OUT3 ,ENET0_RXDV , ,CAN1_TXD , , , , ,ADC1_A13
PORT1 ,P1_14 ,P1_14 , ,FC4_P6 ,FC3_P2 ,CT_INP10 ,SCT0_IN4 ,FLEXIO0_D22 ,EZH_PIO10 ,PLU_IN2 ,ENET0_RXD0 , , , , , , ,ADC1_A14
PORT1 ,P1_15 ,P1_15 , , ,FC3_P3 ,CT_INP11 ,SCT0_IN5 ,FLEXIO0_D23 ,EZH_PIO11 ,PLU_IN3 ,ENET0_RXD1 ,I3C1_PUR , , , , , ,ADC1_A15
PORT1 ,P1_16 ,P1_16 , ,FC5_P0 ,FC3_P4 ,CT_INP12 ,SCT0_OUT6 ,FLEXIO0_D24 ,EZH_PIO12 ,PLU_OUT4 ,ENET0_RXD2 ,I3C1_SDA , , , , , ,ADC1_A16
PORT1 ,P1_17 ,P1_17 , ,FC5_P1 ,FC3_P5 ,CT_INP13 ,SCT0_OUT7 ,FLEXIO0_D25 ,EZH_PIO13 ,PLU_OUT5 ,ENET0_RXD3 ,I3C1_SCL , , , , , ,ADC1_A17
PORT1 ,P1_18 ,P1_18 ,FREQME_CLK_IN0 ,FC5_P2 ,FC3_P6 ,CT3_MAT0 ,SCT0_IN6 ,FLEXIO0_D26 ,EZH_PIO14 ,PLU_IN4 ,ENET0_COL , ,CAN0_TXD , , , , ,ADC1_A18
PORT1 ,P1_19 ,P1_19 ,FREQME_CLK_IN1 ,FC5_P3 , ,CT3_MAT1 ,SCT0_IN7 ,FLEXIO0_D27 ,EZH_PIO15 ,PLU_IN5 ,ENET0_CRS , ,CAN0_RXD , , , , ,ADC1_A19
PORT1 ,P1_20 ,P1_20 ,TRIG_IN2 ,FC5_P4 ,FC4_P0 ,CT3_MAT2 ,SCT0_OUT8 ,FLEXIO0_D28 ,EZH_PIO16 ,PLU_OUT6 ,ENET0_MDC , ,CAN1_TXD , , , , ,ADC1_A20
PORT1 ,P1_21 ,P1_21 ,TRIG_OUT2 ,FC5_P5 ,FC4_P1 ,CT3_MAT3 ,SCT0_OUT9 ,FLEXIO0_D29 ,EZH_PIO17 ,PLU_OUT7 ,ENET0_MDIO ,SAI1_MCLK ,CAN1_RXD , , , , ,ADC1_A21
PORT1 ,P1_22 ,P1_22 ,TRIG_IN3 ,FC5_P6 ,FC4_P2 ,CT_INP14 ,SCT0_OUT4 ,FLEXIO0_D30 ,EZH_PIO18 , , , , , , , , ,ADC1_A22
PORT1 ,P1_23 ,P1_23 , , ,FC4_P3 ,CT_INP15 ,SCT0_OUT5 ,FLEXIO0_D31 ,EZH_PIO19 , , , , , , , , ,ADC1_A23
PORT1 ,P1_30 ,P1_30 ,TRIG_OUT3 , , ,CT_INP16 ,SCT0_OUT8 , , , , ,SAI0_MCLK , , , , , ,
PORT1 ,P1_31 ,P1_31 ,TRIG_IN4 , , ,CT_INP17 ,SCT0_OUT9 , , , , , , , , , , ,
PORT2 ,P2_0 ,P2_0 ,TRIG_IN5 ,FC9_P6 ,uSDHC0_DATA5 ,SCT0_IN0 ,PWM1_A3 ,FLEXIO0_D8 ,EZH_PIO20 ,FLEXSPI0_B_SS1_b, ,SAI0_RX_BCLK ,ESPI0_RST , , , , ,
PORT2 ,P2_1 ,P2_1 ,TRACE_CLK , ,uSDHC0_DATA4 ,SCT0_IN1 ,PWM1_B3 ,FLEXIO0_D9 ,EZH_PIO21 ,FLEXSPI0_B_DQS ,SINC0_MCLK_OUT0 ,SAI0_RX_FS ,ESPI0_NOTIFY , , , , ,
PORT2 ,P2_2 ,P2_2 ,CLKOUT ,FC9_P3 ,uSDHC0_DATA1 ,SCT0_OUT0 ,PWM1_A2 ,FLEXIO0_D10 ,EZH_PIO22 ,FLEXSPI0_B_SS0_b,SINC0_MCLK0 ,SAI0_TXD0 ,ESPI0_CSn , , , , ,
PORT2 ,P2_3 ,P2_3 , ,FC9_P1 ,uSDHC0_DATA0 ,SCT0_OUT1 ,PWM1_B2 ,FLEXIO0_D11 ,EZH_PIO23 ,FLEXSPI0_B_SCLK ,SINC0_MBIT0 ,SAI0_RXD0 ,ESPI0_CLK , , , , ,
PORT2 ,P2_4 ,P2_4 , ,FC9_P0 ,uSDHC0_CLK ,SCT0_OUT2 ,PWM1_A1 ,FLEXIO0_D12 ,EZH_PIO24 ,FLEXSPI0_B_DATA0,SINC0_MCLK1 ,SAI0_RXD1 ,ESPI0_DATA0 , , , , ,
PORT2 ,P2_5 ,P2_5 ,TRIG_OUT3 ,FC9_P2 ,uSDHC0_CMD ,SCT0_OUT3 ,PWM1_B1 ,FLEXIO0_D13 ,EZH_PIO25 ,FLEXSPI0_B_DATA1,SINC0_MBIT1 ,SAI0_TXD1 ,ESPI0_DATA1 , , , , ,
PORT2 ,P2_6 ,P2_6 ,TRIG_IN4 ,FC9_P4 ,uSDHC0_DATA3 ,SCT0_OUT4 ,PWM1_A0 ,FLEXIO0_D14 ,EZH_PIO26 ,FLEXSPI0_B_DATA2,SINC0_MCLK2 ,SAI0_TX_BCLK ,ESPI0_DATA2 , , , , ,
PORT2 ,P2_7 ,P2_7 ,TRIG_IN5 ,FC9_P5 ,uSDHC0_DATA2 ,SCT0_OUT5 ,PWM1_B0 ,FLEXIO0_D15 ,EZH_PIO27 ,FLEXSPI0_B_DATA3,SINC0_MBIT2 ,SAI0_TX_FS ,ESPI0_DATA3 , , , , ,
PORT2 ,P2_8 ,P2_8 ,TRACE_DATA0 , ,uSDHC0_DATA7 ,SCT0_IN2 ,PWM1_X0 ,FLEXIO0_D16 ,EZH_PIO28 ,FLEXSPI0_B_DATA4,SINC0_MCLK3 ,SAI1_TXD0 , , , , , ,
PORT2 ,P2_9 ,P2_9 ,TRACE_DATA1 , ,uSDHC0_DATA6 ,SCT0_IN3 ,PWM1_X1 ,FLEXIO0_D17 ,EZH_PIO29 ,FLEXSPI0_B_DATA5,SINC0_MBIT3 ,SAI1_RXD0 , , , , , ,
PORT2 ,P2_10 ,P2_10 ,TRACE_DATA2 , , ,SCT0_IN4 ,PWM1_X2 ,FLEXIO0_D18 ,EZH_PIO31 ,FLEXSPI0_B_DATA6,SINC0_MCLK4 ,SAI1_RXD1 , , , , , ,
PORT2 ,P2_11 ,P2_11 ,TRACE_DATA3 , , ,SCT0_IN5 ,PWM1_X3 ,FLEXIO0_D19 ,EZH_PIO30 ,FLEXSPI0_B_DATA7,SINC0_MBIT4 ,SAI1_TXD1 , , , , , ,
PORT4 ,P4_0 ,P4_0 ,TRIG_IN6 ,FC2_P0 , ,CT_INP16 , , ,EZH_PIO24 ,PLU_IN0 ,SINC0_MCLK3 , , , , , , ,
PORT4 ,P4_1 ,P4_1 ,TRIG_IN7 ,FC2_P1 , ,CT_INP17 , , ,EZH_PIO25 ,PLU_IN1 , , , , , , , ,
PORT4 ,P4_2 ,P4_2 ,TRIG_IN6 ,FC2_P2 , ,CT_INP12 , , ,EZH_PIO26 ,PLU_IN2 ,SINC0_MBIT3 , , , , , , ,ADC1_A4
PORT4 ,P4_3 ,P4_3 ,TRIG_IN7 ,FC2_P3 , ,CT_INP13 , , ,EZH_PIO27 ,PLU_IN3 , , , , , , , ,ADC1_B4
PORT4 ,P4_4 ,P4_4 , ,FC2_P4 , ,CT_INP14 , , ,EZH_PIO28 ,PLU_IN4 ,SINC0_MCLK4 , , , , , , ,
PORT4 ,P4_5 ,P4_5 , ,FC2_P5 , ,CT_INP15 , , ,EZH_PIO29 ,PLU_IN5 ,SINC0_MBIT4 , , , , , , ,
PORT4 ,P4_6 ,P4_6 ,TRIG_OUT4 ,FC2_P6 , ,CT_INP18 , , ,EZH_PIO30 ,PLU_CLK , , , , , , , ,
PORT4 ,P4_7 ,P4_7 , , , ,CT_INP19 , , ,EZH_PIO31 , , , , , , , , ,
PORT4 ,P4_12 ,P4_12 ,USB0_VBUS_DET ,FC2_P0 , ,CT4_MAT0 , ,FLEXIO0_D20 , ,PLU_OUT0 ,SINC0_MCLK0 , ,CAN0_RXD , , , , ,ADC1_A5
PORT4 ,P4_13 ,P4_13 ,TRIG_IN8 ,FC2_P1 ,USB1_OTGn_ID ,CT4_MAT1 , ,FLEXIO0_D21 , ,PLU_OUT1 ,SINC0_MBIT0 , ,CAN0_TXD , , , , ,ADC1_B5
PORT4 ,P4_14 ,P4_14 , , , ,CT4_MAT2 , ,FLEXIO0_D22 , ,PLU_OUT2 , , , , , , , ,
PORT4 ,P4_15 ,P4_15 ,TRIG_OUT4 , ,#N/A ,CT4_MAT3 , ,FLEXIO0_D23 , ,PLU_OUT3 ,SINC0_MCLK_OUT0 , ,CAN1_RXD , , , , ,ADC0_A1
PORT4 ,P4_16 ,P4_16 , ,FC2_P2 ,USB1_OTGn_PWR ,CT3_MAT0 , ,FLEXIO0_D24 , ,PLU_OUT4 ,SINC0_MCLK1 , ,CAN1_TXD , , , , ,ADC0_A6
PORT4 ,P4_17 ,P4_17 ,TRIG_IN9 ,FC2_P3 ,USB1_OTGn_OC ,CT3_MAT1 , ,FLEXIO0_D25 , ,PLU_OUT5 ,SINC0_MBIT1 , , , , , , ,ADC0_B6
PORT4 ,P4_18 ,P4_18 , , , ,CT3_MAT2 , ,FLEXIO0_D26 , ,PLU_OUT6 , , , , , , , ,
PORT4 ,P4_19 ,P4_19 ,TRIG_OUT5 , , ,CT3_MAT3 , ,FLEXIO0_D27 , ,PLU_OUT7 ,SINC0_MCLK_OUT1 , , , , , , ,ADC0_B1
PORT4 ,P4_20 ,P4_20 ,TRIG_IN8 ,FC2_P4 , ,CT2_MAT0 , ,FLEXIO0_D28 , , ,SINC0_MCLK2 , , , , , , ,ADC1_A6
PORT4 ,P4_21 ,P4_21 ,TRIG_IN9 ,FC2_P5 , ,CT2_MAT1 , ,FLEXIO0_D29 , , ,SINC0_MBIT2 , , , , , , ,ADC1_B6
PORT4 ,P4_22 ,P4_22 , , , ,CT2_MAT2 , ,FLEXIO0_D30 , , , , , , , , , ,
PORT4 ,P4_23 ,P4_23 ,TRIG_OUT5 ,FC2_P6 , ,CT2_MAT3 , ,FLEXIO0_D31 , , ,SINC0_MCLK_OUT2 , , , , , , ,ADC1_B3
PORT5 ,P5_0 ,P5_0 ,TRIG_IN10 ,LPTMR0_ALT2 , , , , , , , , , , , , , ,ADC1_B8
PORT5 ,P5_1 ,P5_1 ,TRIG_OUT6 ,LPTMR1_ALT2 , , , , , , , , , , , , , ,ADC1_B9
PORT5 ,P5_2 ,P5_2 ,VBAT_WAKEUP_b ,SPC_LPREQ ,TAMPER0 , , , , , , , , , , , , ,ADC1_B10
PORT5 ,P5_3 ,P5_3 ,TRIG_IN11 ,RTC_CLKOUT ,TAMPER1 , , , , , , , , , , , , ,ADC1_B11
PORT5 ,P5_4 ,P5_4 ,TRIG_OUT7 ,SPC_LPREQ ,TAMPER2 , , , , , , , , , , , , ,ADC1_B12
PORT5 ,P5_5 ,P5_5 ,TRIG_IN10 ,LPTMR0_ALT2 ,TAMPER3 , , , , , , , , , , , , ,ADC1_B13
PORT5 ,P5_6 ,P5_6 ,TRIG_OUT6 ,LPTMR1_ALT2 ,TAMPER4 , , , , , , , , , , , , ,ADC1_B14
PORT5 ,P5_7 ,P5_7 ,TRIG_IN11 , ,TAMPER5 , , , , , , , , , , , , ,ADC1_B15
PORT5 ,P5_8 ,P5_8 ,TRIG_OUT7 , ,TAMPER6 , , , , , , , , , , , , ,ADC1_B16
PORT5 ,P5_9 ,P5_9 , , ,TAMPER7 , , , , , , , , , , , , ,ADC1_B17
PORT3 ,P3_23 ,P3_23 , , ,FC6_P3 ,CT_INP11 ,PWM1_X3 ,FLEXIO0_D31 ,EZH_PIO23 , , ,SAI1_TXD1 , , , , , ,
PORT3 ,P3_22 ,P3_22 , ,FC8_P6 ,FC6_P2 ,CT_INP10 ,PWM1_X2 ,FLEXIO0_D30 ,EZH_PIO22 , ,SIM0_VCCEN ,SAI1_RXD1 , , , , , ,
PORT3 ,P3_21 ,P3_21 ,TRIG_OUT1 ,FC8_P5 ,FC6_P1 ,CT2_MAT3 ,PWM1_B3 ,FLEXIO0_D29 ,EZH_PIO21 , ,SIM0_RST ,SAI1_RXD0 ,PF_SPI_CS1_DIS_n, , , , ,
PORT3 ,P3_20 ,P3_20 ,TRIG_OUT0 ,FC8_P4 ,FC6_P0 ,CT2_MAT2 ,PWM1_A3 ,FLEXIO0_D28 ,EZH_PIO20 , ,SIM0_PD ,SAI1_TXD0 ,PF_SPI_CS0_DIS_n, , , , ,
PORT3 ,P3_19 ,P3_19 , ,FC7_P6 , ,CT2_MAT1 ,PWM1_X1 ,FLEXIO0_D27 ,EZH_PIO19 , , ,SAI1_RX_FS , , , , , ,
PORT3 ,P3_18 ,P3_18 , , ,FC6_P6 ,CT2_MAT0 ,PWM1_X0 ,FLEXIO0_D26 ,EZH_PIO18 , , ,SAI1_RX_BCLK , , , , , ,
PORT3 ,P3_17 ,P3_17 , ,FC8_P3 , ,CT_INP9 ,PWM1_B2 ,FLEXIO0_D25 ,EZH_PIO17 , ,SIM0_IO ,SAI1_TX_FS , , , , , ,
PORT3 ,P3_16 ,P3_16 , ,FC8_P2 , ,CT_INP8 ,PWM1_A2 ,FLEXIO0_D24 ,EZH_PIO16 , ,SIM0_CLK ,SAI1_TX_BCLK , , , , , ,
PORT3 ,P3_15 ,P3_15 , ,FC8_P1 , ,CT_INP7 ,PWM1_B1 ,FLEXIO0_D23 ,EZH_PIO15 ,FLEXSPI0_A_DATA7, ,SAI0_RX_FS ,PF_SPI_SCKIN , , , , ,
PORT3 ,P3_14 ,P3_14 , ,FC8_P0 , ,CT_INP6 ,PWM1_A1 ,FLEXIO0_D22 ,EZH_PIO14 ,FLEXSPI0_A_DATA6, ,SAI0_RX_BCLK ,PF_SPI_DATA , , , , ,
PORT3 ,P3_13 ,P3_13 , ,FC7_P5 ,FC6_P5 ,CT1_MAT3 ,PWM1_B0 ,FLEXIO0_D21 ,EZH_PIO13 ,FLEXSPI0_A_DATA5, ,SAI0_TXD1 ,PF_SPI_CS0_n , , , , ,
PORT3 ,P3_12 ,P3_12 , ,FC7_P4 ,FC6_P4 ,CT1_MAT2 ,PWM1_A0 ,FLEXIO0_D20 ,EZH_PIO12 ,FLEXSPI0_A_DATA4, ,SAI0_RXD1 , , , , , ,
PORT3 ,P3_11 ,P3_11 , ,FC6_P3 ,FC7_P5 ,CT1_MAT1 ,PWM0_B3 ,FLEXIO0_D19 ,EZH_PIO11 ,FLEXSPI0_A_DATA3,SIM0_IO ,SAI0_RXD0 ,PF_QSPI_DATA3 , , , , ,
PORT3 ,P3_10 ,P3_10 , ,FC6_P2 ,FC7_P4 ,CT1_MAT0 ,PWM0_A3 ,FLEXIO0_D18 ,EZH_PIO10 ,FLEXSPI0_A_DATA2,SIM0_CLK ,SAI0_TXD0 ,PF_QSPI_DATA2 , , , , ,
PORT3 ,P3_9 ,P3_9 , ,FC6_P5 ,FC7_P2 ,CT_INP5 ,PWM0_B2 ,FLEXIO0_D17 ,EZH_PIO9 ,FLEXSPI0_A_DATA1,SIM0_RST ,SAI0_TX_FS ,PF_QSPI_DATA1 , , , , ,
PORT3 ,P3_8 ,P3_8 , ,FC6_P4 ,FC7_P0 ,CT_INP4 ,PWM0_A2 ,FLEXIO0_D16 ,EZH_PIO8 ,FLEXSPI0_A_DATA0,SIM0_PD ,SAI0_TX_BCLK ,PF_QSPI_DATA0 , , , , ,
PORT3 ,P3_7 ,P3_7 , ,FC6_P6 ,FC7_P1 ,CT4_MAT3 ,PWM0_B1 ,FLEXIO0_D15 ,EZH_PIO7 ,FLEXSPI0_A_SCLK ,SIM0_VCCEN ,SAI0_MCLK ,PF_QSPI_SCKIN , , , , ,
PORT3 ,P3_6 ,P3_6 ,CLKOUT ,FC6_P1 , ,CT4_MAT2 ,PWM0_A1 ,FLEXIO0_D14 ,EZH_PIO6 ,FLEXSPI0_A_DQS ,SIM1_VCCEN ,SAI1_MCLK ,PF_QSPI_CS_n ,FREQME_CLK_OUT1 , , , ,
PORT3 ,P3_5 ,P3_5 , ,FC7_P3 , ,CT_INP19 ,PWM0_X3 ,FLEXIO0_D13 ,EZH_PIO5 , ,SIM1_IO , , , , , , ,
PORT3 ,P3_4 ,P3_4 , ,FC7_P2 , ,CT_INP18 ,PWM0_X2 ,FLEXIO0_D12 ,EZH_PIO4 , ,SIM1_CLK , , , , , , ,
PORT3 ,P3_3 ,P3_3 , ,FC7_P1 , ,CT4_MAT1 ,PWM0_X1 ,FLEXIO0_D11 ,EZH_PIO3 , ,SIM1_RST , , , , , , ,
PORT3 ,P3_2 ,P3_2 , ,FC7_P0 , ,CT4_MAT0 ,PWM0_X0 ,FLEXIO0_D10 ,EZH_PIO2 , ,SIM1_PD , , , , , , ,
PORT3 ,P3_1 ,P3_1 ,TRIG_IN1 ,FC6_P0 ,FC7_P6 ,CT_INP17 ,PWM0_B0 ,FLEXIO0_D9 ,EZH_PIO1 ,FLEXSPI0_A_SS1_b, , ,PF_QSPI_CS1_DIS ,FREQME_CLK_OUT0 , , , ,
PORT3 ,P3_0 ,P3_0 ,TRIG_IN0 , ,FC7_P3 ,CT_INP16 ,PWM0_A0 ,FLEXIO0_D8 ,EZH_PIO0 ,FLEXSPI0_A_SS0_b, , ,PF_QSPI_CS0_DIS , , , , ,
PORT0 ,P0_0 ,P0_0 ,TMS/SWDIO ,FC1_P0 , ,CT_INP0 , , , , , , , , , , , ,
PORT0 ,P0_1 ,P0_1 ,TCLK/SWCLK ,FC1_P1 , ,CT_INP1 , , , , , , , , , , , ,
PORT0 ,P0_2 ,P0_2 ,TDO/SWO ,FC1_P2 , ,CT0_MAT0 ,UTICK_CAP0 , , , , ,I3C0_PUR , , , , , ,
PORT0 ,P0_3 ,P0_3 ,TDI ,FC1_P3 , ,CT0_MAT1 ,UTICK_CAP1 , , ,HSCMP0_OUT , , , , , , , ,
PORT0 ,P0_4 ,P0_4 ,EWM0_IN ,FC0_P0 ,FC1_P4 ,CT0_MAT2 ,UTICK_CAP2 , , ,HSCMP1_OUT ,PDM0_CLK , , , , , , ,
PORT0 ,P0_5 ,P0_5 ,EWM0_OUT_b ,FC0_P1 ,FC1_P5 ,CT0_MAT3 ,UTICK_CAP3 , , , ,PDM0_DATA0 , , , , , , ,
PORT0 ,P0_6 ,P0_6 ,ISPMODE_N ,FC0_P2 ,FC1_P6 ,CT_INP2 , , , ,HSCMP2_OUT ,PDM0_DATA1 , , ,CLKOUT , , , ,
PORT0 ,P0_7 ,P0_7 , ,FC0_P3 , ,CT_INP3 , , , , , , , , , , , ,
PORT0 ,P0_8 ,P0_8 , ,FC0_P4 , ,CT_INP0 , ,FLEXIO0_D0 , , , , , , , , , ,ADC0_B8
PORT0 ,P0_9 ,P0_9 , ,FC0_P5 , ,CT_INP1 , ,FLEXIO0_D1 , , , , , , , , , ,ADC0_B9
PORT0 ,P0_10 ,P0_10 , ,FC0_P6 , ,CT0_MAT0 , ,FLEXIO0_D2 , , , , , , , , , ,ADC0_B10
PORT0 ,P0_11 ,P0_11 , , , ,CT0_MAT1 , ,FLEXIO0_D3 , ,HSCMP2_OUT , , , , , , , ,ADC0_B11
PORT0 ,P0_12 ,P0_12 , ,FC1_P4 ,FC0_P0 ,CT0_MAT2 , ,FLEXIO0_D4 , , , , , , , , , ,ADC0_B12
PORT0 ,P0_13 ,P0_13 , ,FC1_P5 ,FC0_P1 ,CT0_MAT3 , ,FLEXIO0_D5 , , , , , , , , , ,ADC0_B13
PORT0 ,P0_14 ,P0_14 , ,FC1_P6 ,FC0_P2 ,CT_INP2 ,UTICK_CAP0 ,FLEXIO0_D6 , , , , , , , , , ,ADC0_B14
PORT0 ,P0_15 ,P0_15 , , ,FC0_P3 ,CT_INP3 ,UTICK_CAP1 ,FLEXIO0_D7 , , , , , , , , , ,ADC0_B15
PORT0 ,P0_16 ,P0_16 , ,FC0_P0 , ,CT0_MAT0 ,UTICK_CAP2 ,FLEXIO0_D0 , , ,PDM0_CLK ,I3C0_SDA , , , , , ,ADC0_A8
PORT0 ,P0_17 ,P0_17 , ,FC0_P1 , ,CT0_MAT1 ,UTICK_CAP3 ,FLEXIO0_D1 , , ,PDM0_DATA0 ,I3C0_SCL , , , , , ,ADC0_A9
PORT0 ,P0_18 ,P0_18 ,EWM0_IN ,FC0_P2 , ,CT0_MAT2 , ,FLEXIO0_D2 , ,HSCMP0_OUT ,PDM0_DATA1 , , , , , , ,ADC0_A10
PORT0 ,P0_19 ,P0_19 ,EWM0_OUT_b ,FC0_P3 , ,CT0_MAT3 , ,FLEXIO0_D3 , ,HSCMP1_OUT , , , , , , , ,ADC0_A11
PORT0 ,P0_20 ,P0_20 , ,FC0_P4 ,FC1_P0 ,CT_INP0 , ,FLEXIO0_D4 , , , ,I3C0_SDA , , , , , ,ADC0_A12
PORT0 ,P0_21 ,P0_21 , ,FC0_P5 ,FC1_P1 ,CT_INP1 , ,FLEXIO0_D5 , , , ,I3C0_SCL , , , , , ,ADC0_A13
PORT0 ,P0_22 ,P0_22 ,EWM0_IN ,FC0_P6 ,FC1_P2 ,CT_INP2 , ,FLEXIO0_D6 , , , ,I3C0_PUR , , , , , ,ADC0_A14
PORT0 ,P0_23 ,P0_23 ,EWM0_OUT_b , ,FC1_P3 ,CT_INP3 , ,FLEXIO0_D7 , , , , , , , , , ,ADC0_A15
PORT0 ,P0_24 ,P0_24 , ,FC1_P0 , ,CT0_MAT0 , , , , , , , , , , , ,ADC0_B16
PORT0 ,P0_25 ,P0_25 , ,FC1_P1 , ,CT0_MAT1 , , , , , , , , , , , ,ADC0_B17
PORT0 ,P0_26 ,P0_26 , ,FC1_P2 , ,CT0_MAT2 , , , , , , , , , , , ,ADC0_B18
PORT0 ,P0_27 ,P0_27 , ,FC1_P3 , ,CT0_MAT3 , , , , , , , , , , , ,ADC0_B19
PORT0 ,P0_28 ,P0_28 , ,FC1_P4 ,FC0_P4 ,CT_INP0 , , , , , , , , , , , ,ADC0_B20
PORT0 ,P0_29 ,P0_29 , ,FC1_P5 ,FC0_P5 ,CT_INP1 , , , , , , , , , , , ,ADC0_B21
PORT0 ,P0_30 ,P0_30 , ,FC1_P6 ,FC0_P6 ,CT_INP2 , , , , , , , , , , , ,ADC0_B22
PORT0 ,P0_31 ,P0_31 , , , ,CT_INP3 , , , , , , , , , , , ,ADC0_B23
PORT1 ,P1_0 ,P1_0 ,TRIG_IN0 ,FC3_P0 ,FC4_P4 ,CT_INP4 ,SCT0_OUT6 ,FLEXIO0_D8 , , , ,SAI1_TX_BCLK , , , , , ,ADC0_A16
PORT1 ,P1_1 ,P1_1 ,TRIG_IN1 ,FC3_P1 ,FC4_P5 ,CT_INP5 ,SCT0_OUT7 ,FLEXIO0_D9 , , , ,SAI1_TX_FS , , , , , ,ADC0_A17
PORT1 ,P1_2 ,P1_2 ,TRIG_OUT0 ,FC3_P2 ,FC4_P6 ,CT1_MAT0 ,SCT0_IN6 ,FLEXIO0_D10 , , ,ENET0_MDC ,SAI1_TXD0 ,CAN0_TXD , , , , ,ADC0_A18
PORT1 ,P1_3 ,P1_3 ,TRIG_OUT1 ,FC3_P3 , ,CT1_MAT1 ,SCT0_IN7 ,FLEXIO0_D11 , , ,ENET0_MDIO ,SAI1_RXD0 ,CAN0_RXD , , , , ,ADC0_A19
PORT1 ,P1_4 ,P1_4 ,FREQME_CLK_IN0 ,FC3_P4 ,FC5_P0 ,CT1_MAT2 ,SCT0_OUT0 ,FLEXIO0_D12 ,EZH_PIO0 , ,ENET0_TX_CLK ,SAI0_TXD1 , , , , , ,ADC0_A20
PORT1 ,P1_5 ,P1_5 ,FREQME_CLK_IN1 ,FC3_P5 ,FC5_P1 ,CT1_MAT3 ,SCT0_OUT1 ,FLEXIO0_D13 ,EZH_PIO1 , ,ENET0_TXEN ,SAI0_RXD1 , , , , , ,ADC0_A21
PORT1 ,P1_6 ,P1_6 ,TRIG_IN2 ,FC3_P6 ,FC5_P2 ,CT_INP6 ,SCT0_IN0 ,FLEXIO0_D14 ,EZH_PIO2 , ,ENET0_TXD0 ,SAI1_RX_BCLK ,CAN1_TXD , , , , ,ADC0_A22
PORT1 ,P1_7 ,P1_7 ,TRIG_OUT2 , ,FC5_P3 ,CT_INP7 ,SCT0_IN1 ,FLEXIO0_D15 ,EZH_PIO3 ,PLU_CLK ,ENET0_TXD1 ,SAI1_RX_FS ,CAN1_RXD , , , , ,ADC0_A23
1 Port Pin AF0 AF1 AF2 AF3 AF4 AF5 AF6 AF7 AF8 AF9 AF10 AF11 AF12 AF13 AF14 AF15 ADC
2 PORT1 P1_8 P1_8 TRACE_DATA0 FC4_P0 FC5_P4 CT_INP8 SCT0_OUT2 FLEXIO0_D16 EZH_PIO4 PLU_OUT0 ENET0_TXD2 I3C1_SDA ADC1_A8
3 PORT1 P1_9 P1_9 TRACE_DATA1 FC4_P1 FC5_P5 CT_INP9 SCT0_OUT3 FLEXIO0_D17 EZH_PIO5 PLU_OUT1 ENET0_TXD3 I3C1_SCL ADC1_A9
4 PORT1 P1_10 P1_10 TRACE_DATA2 FC4_P2 FC5_P6 CT2_MAT0 SCT0_IN2 FLEXIO0_D18 EZH_PIO6 PLU_IN0 ENET0_TXER CAN0_TXD ADC1_A10
5 PORT1 P1_11 P1_11 TRACE_DATA3 FC4_P3 CT2_MAT1 SCT0_IN3 FLEXIO0_D19 EZH_PIO7 PLU_IN1 ENET0_RX_CLK I3C1_PUR CAN0_RXD ADC1_A11
6 PORT1 P1_12 P1_12 TRACE_CLK FC4_P4 FC3_P0 CT2_MAT2 SCT0_OUT4 FLEXIO0_D20 EZH_PIO8 PLU_OUT2 ENET0_RXER CAN1_RXD ADC1_A12
7 PORT1 P1_13 P1_13 TRIG_IN3 FC4_P5 FC3_P1 CT2_MAT3 SCT0_OUT5 FLEXIO0_D21 EZH_PIO9 PLU_OUT3 ENET0_RXDV CAN1_TXD ADC1_A13
8 PORT1 P1_14 P1_14 FC4_P6 FC3_P2 CT_INP10 SCT0_IN4 FLEXIO0_D22 EZH_PIO10 PLU_IN2 ENET0_RXD0 ADC1_A14
9 PORT1 P1_15 P1_15 FC3_P3 CT_INP11 SCT0_IN5 FLEXIO0_D23 EZH_PIO11 PLU_IN3 ENET0_RXD1 I3C1_PUR ADC1_A15
10 PORT1 P1_16 P1_16 FC5_P0 FC3_P4 CT_INP12 SCT0_OUT6 FLEXIO0_D24 EZH_PIO12 PLU_OUT4 ENET0_RXD2 I3C1_SDA ADC1_A16
11 PORT1 P1_17 P1_17 FC5_P1 FC3_P5 CT_INP13 SCT0_OUT7 FLEXIO0_D25 EZH_PIO13 PLU_OUT5 ENET0_RXD3 I3C1_SCL ADC1_A17
12 PORT1 P1_18 P1_18 FREQME_CLK_IN0 FC5_P2 FC3_P6 CT3_MAT0 SCT0_IN6 FLEXIO0_D26 EZH_PIO14 PLU_IN4 ENET0_COL CAN0_TXD ADC1_A18
13 PORT1 P1_19 P1_19 FREQME_CLK_IN1 FC5_P3 CT3_MAT1 SCT0_IN7 FLEXIO0_D27 EZH_PIO15 PLU_IN5 ENET0_CRS CAN0_RXD ADC1_A19
14 PORT1 P1_20 P1_20 TRIG_IN2 FC5_P4 FC4_P0 CT3_MAT2 SCT0_OUT8 FLEXIO0_D28 EZH_PIO16 PLU_OUT6 ENET0_MDC CAN1_TXD ADC1_A20
15 PORT1 P1_21 P1_21 TRIG_OUT2 FC5_P5 FC4_P1 CT3_MAT3 SCT0_OUT9 FLEXIO0_D29 EZH_PIO17 PLU_OUT7 ENET0_MDIO SAI1_MCLK CAN1_RXD ADC1_A21
16 PORT1 P1_22 P1_22 TRIG_IN3 FC5_P6 FC4_P2 CT_INP14 SCT0_OUT4 FLEXIO0_D30 EZH_PIO18 ADC1_A22
17 PORT1 P1_23 P1_23 FC4_P3 CT_INP15 SCT0_OUT5 FLEXIO0_D31 EZH_PIO19 ADC1_A23
18 PORT1 P1_30 P1_30 TRIG_OUT3 CT_INP16 SCT0_OUT8 SAI0_MCLK
19 PORT1 P1_31 P1_31 TRIG_IN4 CT_INP17 SCT0_OUT9
20 PORT2 P2_0 P2_0 TRIG_IN5 FC9_P6 uSDHC0_DATA5 SCT0_IN0 PWM1_A3 FLEXIO0_D8 EZH_PIO20 FLEXSPI0_B_SS1_b SAI0_RX_BCLK ESPI0_RST
21 PORT2 P2_1 P2_1 TRACE_CLK uSDHC0_DATA4 SCT0_IN1 PWM1_B3 FLEXIO0_D9 EZH_PIO21 FLEXSPI0_B_DQS SINC0_MCLK_OUT0 SAI0_RX_FS ESPI0_NOTIFY
22 PORT2 P2_2 P2_2 CLKOUT FC9_P3 uSDHC0_DATA1 SCT0_OUT0 PWM1_A2 FLEXIO0_D10 EZH_PIO22 FLEXSPI0_B_SS0_b SINC0_MCLK0 SAI0_TXD0 ESPI0_CSn
23 PORT2 P2_3 P2_3 FC9_P1 uSDHC0_DATA0 SCT0_OUT1 PWM1_B2 FLEXIO0_D11 EZH_PIO23 FLEXSPI0_B_SCLK SINC0_MBIT0 SAI0_RXD0 ESPI0_CLK
24 PORT2 P2_4 P2_4 FC9_P0 uSDHC0_CLK SCT0_OUT2 PWM1_A1 FLEXIO0_D12 EZH_PIO24 FLEXSPI0_B_DATA0 SINC0_MCLK1 SAI0_RXD1 ESPI0_DATA0
25 PORT2 P2_5 P2_5 TRIG_OUT3 FC9_P2 uSDHC0_CMD SCT0_OUT3 PWM1_B1 FLEXIO0_D13 EZH_PIO25 FLEXSPI0_B_DATA1 SINC0_MBIT1 SAI0_TXD1 ESPI0_DATA1
26 PORT2 P2_6 P2_6 TRIG_IN4 FC9_P4 uSDHC0_DATA3 SCT0_OUT4 PWM1_A0 FLEXIO0_D14 EZH_PIO26 FLEXSPI0_B_DATA2 SINC0_MCLK2 SAI0_TX_BCLK ESPI0_DATA2
27 PORT2 P2_7 P2_7 TRIG_IN5 FC9_P5 uSDHC0_DATA2 SCT0_OUT5 PWM1_B0 FLEXIO0_D15 EZH_PIO27 FLEXSPI0_B_DATA3 SINC0_MBIT2 SAI0_TX_FS ESPI0_DATA3
28 PORT2 P2_8 P2_8 TRACE_DATA0 uSDHC0_DATA7 SCT0_IN2 PWM1_X0 FLEXIO0_D16 EZH_PIO28 FLEXSPI0_B_DATA4 SINC0_MCLK3 SAI1_TXD0
29 PORT2 P2_9 P2_9 TRACE_DATA1 uSDHC0_DATA6 SCT0_IN3 PWM1_X1 FLEXIO0_D17 EZH_PIO29 FLEXSPI0_B_DATA5 SINC0_MBIT3 SAI1_RXD0
30 PORT2 P2_10 P2_10 TRACE_DATA2 SCT0_IN4 PWM1_X2 FLEXIO0_D18 EZH_PIO31 FLEXSPI0_B_DATA6 SINC0_MCLK4 SAI1_RXD1
31 PORT2 P2_11 P2_11 TRACE_DATA3 SCT0_IN5 PWM1_X3 FLEXIO0_D19 EZH_PIO30 FLEXSPI0_B_DATA7 SINC0_MBIT4 SAI1_TXD1
32 PORT4 P4_0 P4_0 TRIG_IN6 FC2_P0 CT_INP16 EZH_PIO24 PLU_IN0 SINC0_MCLK3
33 PORT4 P4_1 P4_1 TRIG_IN7 FC2_P1 CT_INP17 EZH_PIO25 PLU_IN1
34 PORT4 P4_2 P4_2 TRIG_IN6 FC2_P2 CT_INP12 EZH_PIO26 PLU_IN2 SINC0_MBIT3 ADC1_A4
35 PORT4 P4_3 P4_3 TRIG_IN7 FC2_P3 CT_INP13 EZH_PIO27 PLU_IN3 ADC1_B4
36 PORT4 P4_4 P4_4 FC2_P4 CT_INP14 EZH_PIO28 PLU_IN4 SINC0_MCLK4
37 PORT4 P4_5 P4_5 FC2_P5 CT_INP15 EZH_PIO29 PLU_IN5 SINC0_MBIT4
38 PORT4 P4_6 P4_6 TRIG_OUT4 FC2_P6 CT_INP18 EZH_PIO30 PLU_CLK
39 PORT4 P4_7 P4_7 CT_INP19 EZH_PIO31
40 PORT4 P4_12 P4_12 USB0_VBUS_DET FC2_P0 CT4_MAT0 FLEXIO0_D20 PLU_OUT0 SINC0_MCLK0 CAN0_RXD ADC1_A5
41 PORT4 P4_13 P4_13 TRIG_IN8 FC2_P1 USB1_OTGn_ID CT4_MAT1 FLEXIO0_D21 PLU_OUT1 SINC0_MBIT0 CAN0_TXD ADC1_B5
42 PORT4 P4_14 P4_14 CT4_MAT2 FLEXIO0_D22 PLU_OUT2
43 PORT4 P4_15 P4_15 TRIG_OUT4 #N/A CT4_MAT3 FLEXIO0_D23 PLU_OUT3 SINC0_MCLK_OUT0 CAN1_RXD ADC0_A1
44 PORT4 P4_16 P4_16 FC2_P2 USB1_OTGn_PWR CT3_MAT0 FLEXIO0_D24 PLU_OUT4 SINC0_MCLK1 CAN1_TXD ADC0_A6
45 PORT4 P4_17 P4_17 TRIG_IN9 FC2_P3 USB1_OTGn_OC CT3_MAT1 FLEXIO0_D25 PLU_OUT5 SINC0_MBIT1 ADC0_B6
46 PORT4 P4_18 P4_18 CT3_MAT2 FLEXIO0_D26 PLU_OUT6
47 PORT4 P4_19 P4_19 TRIG_OUT5 CT3_MAT3 FLEXIO0_D27 PLU_OUT7 SINC0_MCLK_OUT1 ADC0_B1
48 PORT4 P4_20 P4_20 TRIG_IN8 FC2_P4 CT2_MAT0 FLEXIO0_D28 SINC0_MCLK2 ADC1_A6
49 PORT4 P4_21 P4_21 TRIG_IN9 FC2_P5 CT2_MAT1 FLEXIO0_D29 SINC0_MBIT2 ADC1_B6
50 PORT4 P4_22 P4_22 CT2_MAT2 FLEXIO0_D30
51 PORT4 P4_23 P4_23 TRIG_OUT5 FC2_P6 CT2_MAT3 FLEXIO0_D31 SINC0_MCLK_OUT2 ADC1_B3
52 PORT5 P5_0 P5_0 TRIG_IN10 LPTMR0_ALT2 ADC1_B8
53 PORT5 P5_1 P5_1 TRIG_OUT6 LPTMR1_ALT2 ADC1_B9
54 PORT5 P5_2 P5_2 VBAT_WAKEUP_b SPC_LPREQ TAMPER0 ADC1_B10
55 PORT5 P5_3 P5_3 TRIG_IN11 RTC_CLKOUT TAMPER1 ADC1_B11
56 PORT5 P5_4 P5_4 TRIG_OUT7 SPC_LPREQ TAMPER2 ADC1_B12
57 PORT5 P5_5 P5_5 TRIG_IN10 LPTMR0_ALT2 TAMPER3 ADC1_B13
58 PORT5 P5_6 P5_6 TRIG_OUT6 LPTMR1_ALT2 TAMPER4 ADC1_B14
59 PORT5 P5_7 P5_7 TRIG_IN11 TAMPER5 ADC1_B15
60 PORT5 P5_8 P5_8 TRIG_OUT7 TAMPER6 ADC1_B16
61 PORT5 P5_9 P5_9 TAMPER7 ADC1_B17
62 PORT3 P3_23 P3_23 FC6_P3 CT_INP11 PWM1_X3 FLEXIO0_D31 EZH_PIO23 SAI1_TXD1
63 PORT3 P3_22 P3_22 FC8_P6 FC6_P2 CT_INP10 PWM1_X2 FLEXIO0_D30 EZH_PIO22 SIM0_VCCEN SAI1_RXD1
64 PORT3 P3_21 P3_21 TRIG_OUT1 FC8_P5 FC6_P1 CT2_MAT3 PWM1_B3 FLEXIO0_D29 EZH_PIO21 SIM0_RST SAI1_RXD0 PF_SPI_CS1_DIS_n
65 PORT3 P3_20 P3_20 TRIG_OUT0 FC8_P4 FC6_P0 CT2_MAT2 PWM1_A3 FLEXIO0_D28 EZH_PIO20 SIM0_PD SAI1_TXD0 PF_SPI_CS0_DIS_n
66 PORT3 P3_19 P3_19 FC7_P6 CT2_MAT1 PWM1_X1 FLEXIO0_D27 EZH_PIO19 SAI1_RX_FS
67 PORT3 P3_18 P3_18 FC6_P6 CT2_MAT0 PWM1_X0 FLEXIO0_D26 EZH_PIO18 SAI1_RX_BCLK
68 PORT3 P3_17 P3_17 FC8_P3 CT_INP9 PWM1_B2 FLEXIO0_D25 EZH_PIO17 SIM0_IO SAI1_TX_FS
69 PORT3 P3_16 P3_16 FC8_P2 CT_INP8 PWM1_A2 FLEXIO0_D24 EZH_PIO16 SIM0_CLK SAI1_TX_BCLK
70 PORT3 P3_15 P3_15 FC8_P1 CT_INP7 PWM1_B1 FLEXIO0_D23 EZH_PIO15 FLEXSPI0_A_DATA7 SAI0_RX_FS PF_SPI_SCKIN
71 PORT3 P3_14 P3_14 FC8_P0 CT_INP6 PWM1_A1 FLEXIO0_D22 EZH_PIO14 FLEXSPI0_A_DATA6 SAI0_RX_BCLK PF_SPI_DATA
72 PORT3 P3_13 P3_13 FC7_P5 FC6_P5 CT1_MAT3 PWM1_B0 FLEXIO0_D21 EZH_PIO13 FLEXSPI0_A_DATA5 SAI0_TXD1 PF_SPI_CS0_n
73 PORT3 P3_12 P3_12 FC7_P4 FC6_P4 CT1_MAT2 PWM1_A0 FLEXIO0_D20 EZH_PIO12 FLEXSPI0_A_DATA4 SAI0_RXD1
74 PORT3 P3_11 P3_11 FC6_P3 FC7_P5 CT1_MAT1 PWM0_B3 FLEXIO0_D19 EZH_PIO11 FLEXSPI0_A_DATA3 SIM0_IO SAI0_RXD0 PF_QSPI_DATA3
75 PORT3 P3_10 P3_10 FC6_P2 FC7_P4 CT1_MAT0 PWM0_A3 FLEXIO0_D18 EZH_PIO10 FLEXSPI0_A_DATA2 SIM0_CLK SAI0_TXD0 PF_QSPI_DATA2
76 PORT3 P3_9 P3_9 FC6_P5 FC7_P2 CT_INP5 PWM0_B2 FLEXIO0_D17 EZH_PIO9 FLEXSPI0_A_DATA1 SIM0_RST SAI0_TX_FS PF_QSPI_DATA1
77 PORT3 P3_8 P3_8 FC6_P4 FC7_P0 CT_INP4 PWM0_A2 FLEXIO0_D16 EZH_PIO8 FLEXSPI0_A_DATA0 SIM0_PD SAI0_TX_BCLK PF_QSPI_DATA0
78 PORT3 P3_7 P3_7 FC6_P6 FC7_P1 CT4_MAT3 PWM0_B1 FLEXIO0_D15 EZH_PIO7 FLEXSPI0_A_SCLK SIM0_VCCEN SAI0_MCLK PF_QSPI_SCKIN
79 PORT3 P3_6 P3_6 CLKOUT FC6_P1 CT4_MAT2 PWM0_A1 FLEXIO0_D14 EZH_PIO6 FLEXSPI0_A_DQS SIM1_VCCEN SAI1_MCLK PF_QSPI_CS_n FREQME_CLK_OUT1
80 PORT3 P3_5 P3_5 FC7_P3 CT_INP19 PWM0_X3 FLEXIO0_D13 EZH_PIO5 SIM1_IO
81 PORT3 P3_4 P3_4 FC7_P2 CT_INP18 PWM0_X2 FLEXIO0_D12 EZH_PIO4 SIM1_CLK
82 PORT3 P3_3 P3_3 FC7_P1 CT4_MAT1 PWM0_X1 FLEXIO0_D11 EZH_PIO3 SIM1_RST
83 PORT3 P3_2 P3_2 FC7_P0 CT4_MAT0 PWM0_X0 FLEXIO0_D10 EZH_PIO2 SIM1_PD
84 PORT3 P3_1 P3_1 TRIG_IN1 FC6_P0 FC7_P6 CT_INP17 PWM0_B0 FLEXIO0_D9 EZH_PIO1 FLEXSPI0_A_SS1_b PF_QSPI_CS1_DIS FREQME_CLK_OUT0
85 PORT3 P3_0 P3_0 TRIG_IN0 FC7_P3 CT_INP16 PWM0_A0 FLEXIO0_D8 EZH_PIO0 FLEXSPI0_A_SS0_b PF_QSPI_CS0_DIS
86 PORT0 P0_0 P0_0 TMS/SWDIO FC1_P0 CT_INP0
87 PORT0 P0_1 P0_1 TCLK/SWCLK FC1_P1 CT_INP1
88 PORT0 P0_2 P0_2 TDO/SWO FC1_P2 CT0_MAT0 UTICK_CAP0 I3C0_PUR
89 PORT0 P0_3 P0_3 TDI FC1_P3 CT0_MAT1 UTICK_CAP1 HSCMP0_OUT
90 PORT0 P0_4 P0_4 EWM0_IN FC0_P0 FC1_P4 CT0_MAT2 UTICK_CAP2 HSCMP1_OUT PDM0_CLK
91 PORT0 P0_5 P0_5 EWM0_OUT_b FC0_P1 FC1_P5 CT0_MAT3 UTICK_CAP3 PDM0_DATA0
92 PORT0 P0_6 P0_6 ISPMODE_N FC0_P2 FC1_P6 CT_INP2 HSCMP2_OUT PDM0_DATA1 CLKOUT
93 PORT0 P0_7 P0_7 FC0_P3 CT_INP3
94 PORT0 P0_8 P0_8 FC0_P4 CT_INP0 FLEXIO0_D0 ADC0_B8
95 PORT0 P0_9 P0_9 FC0_P5 CT_INP1 FLEXIO0_D1 ADC0_B9
96 PORT0 P0_10 P0_10 FC0_P6 CT0_MAT0 FLEXIO0_D2 ADC0_B10
97 PORT0 P0_11 P0_11 CT0_MAT1 FLEXIO0_D3 HSCMP2_OUT ADC0_B11
98 PORT0 P0_12 P0_12 FC1_P4 FC0_P0 CT0_MAT2 FLEXIO0_D4 ADC0_B12
99 PORT0 P0_13 P0_13 FC1_P5 FC0_P1 CT0_MAT3 FLEXIO0_D5 ADC0_B13
100 PORT0 P0_14 P0_14 FC1_P6 FC0_P2 CT_INP2 UTICK_CAP0 FLEXIO0_D6 ADC0_B14
101 PORT0 P0_15 P0_15 FC0_P3 CT_INP3 UTICK_CAP1 FLEXIO0_D7 ADC0_B15
102 PORT0 P0_16 P0_16 FC0_P0 CT0_MAT0 UTICK_CAP2 FLEXIO0_D0 PDM0_CLK I3C0_SDA ADC0_A8
103 PORT0 P0_17 P0_17 FC0_P1 CT0_MAT1 UTICK_CAP3 FLEXIO0_D1 PDM0_DATA0 I3C0_SCL ADC0_A9
104 PORT0 P0_18 P0_18 EWM0_IN FC0_P2 CT0_MAT2 FLEXIO0_D2 HSCMP0_OUT PDM0_DATA1 ADC0_A10
105 PORT0 P0_19 P0_19 EWM0_OUT_b FC0_P3 CT0_MAT3 FLEXIO0_D3 HSCMP1_OUT ADC0_A11
106 PORT0 P0_20 P0_20 FC0_P4 FC1_P0 CT_INP0 FLEXIO0_D4 I3C0_SDA ADC0_A12
107 PORT0 P0_21 P0_21 FC0_P5 FC1_P1 CT_INP1 FLEXIO0_D5 I3C0_SCL ADC0_A13
108 PORT0 P0_22 P0_22 EWM0_IN FC0_P6 FC1_P2 CT_INP2 FLEXIO0_D6 I3C0_PUR ADC0_A14
109 PORT0 P0_23 P0_23 EWM0_OUT_b FC1_P3 CT_INP3 FLEXIO0_D7 ADC0_A15
110 PORT0 P0_24 P0_24 FC1_P0 CT0_MAT0 ADC0_B16
111 PORT0 P0_25 P0_25 FC1_P1 CT0_MAT1 ADC0_B17
112 PORT0 P0_26 P0_26 FC1_P2 CT0_MAT2 ADC0_B18
113 PORT0 P0_27 P0_27 FC1_P3 CT0_MAT3 ADC0_B19
114 PORT0 P0_28 P0_28 FC1_P4 FC0_P4 CT_INP0 ADC0_B20
115 PORT0 P0_29 P0_29 FC1_P5 FC0_P5 CT_INP1 ADC0_B21
116 PORT0 P0_30 P0_30 FC1_P6 FC0_P6 CT_INP2 ADC0_B22
117 PORT0 P0_31 P0_31 CT_INP3 ADC0_B23
118 PORT1 P1_0 P1_0 TRIG_IN0 FC3_P0 FC4_P4 CT_INP4 SCT0_OUT6 FLEXIO0_D8 SAI1_TX_BCLK ADC0_A16
119 PORT1 P1_1 P1_1 TRIG_IN1 FC3_P1 FC4_P5 CT_INP5 SCT0_OUT7 FLEXIO0_D9 SAI1_TX_FS ADC0_A17
120 PORT1 P1_2 P1_2 TRIG_OUT0 FC3_P2 FC4_P6 CT1_MAT0 SCT0_IN6 FLEXIO0_D10 ENET0_MDC SAI1_TXD0 CAN0_TXD ADC0_A18
121 PORT1 P1_3 P1_3 TRIG_OUT1 FC3_P3 CT1_MAT1 SCT0_IN7 FLEXIO0_D11 ENET0_MDIO SAI1_RXD0 CAN0_RXD ADC0_A19
122 PORT1 P1_4 P1_4 FREQME_CLK_IN0 FC3_P4 FC5_P0 CT1_MAT2 SCT0_OUT0 FLEXIO0_D12 EZH_PIO0 ENET0_TX_CLK SAI0_TXD1 ADC0_A20
123 PORT1 P1_5 P1_5 FREQME_CLK_IN1 FC3_P5 FC5_P1 CT1_MAT3 SCT0_OUT1 FLEXIO0_D13 EZH_PIO1 ENET0_TXEN SAI0_RXD1 ADC0_A21
124 PORT1 P1_6 P1_6 TRIG_IN2 FC3_P6 FC5_P2 CT_INP6 SCT0_IN0 FLEXIO0_D14 EZH_PIO2 ENET0_TXD0 SAI1_RX_BCLK CAN1_TXD ADC0_A22
125 PORT1 P1_7 P1_7 TRIG_OUT2 FC5_P3 CT_INP7 SCT0_IN1 FLEXIO0_D15 EZH_PIO3 PLU_CLK ENET0_TXD1 SAI1_RX_FS CAN1_RXD ADC0_A23

Wyświetl plik

@ -0,0 +1,249 @@
/*
** ###################################################################
** Processors: MCXN947VDF_cm33_core0
** MCXN947VNL_cm33_core0
**
** Compiler: GNU C Compiler
** Reference manual: MCXNx4x Reference Manual
** Version: rev. 1.0, 2021-08-03
** Build: b230607
**
** Abstract:
** Linker file for the GNU C Compiler
**
** Copyright 2016 Freescale Semiconductor, Inc.
** Copyright 2016-2023 NXP
** SPDX-License-Identifier: BSD-3-Clause
**
** http: www.nxp.com
** mail: support@nxp.com
**
** ###################################################################
*/
/* Entry Point */
ENTRY(Reset_Handler)
HEAP_SIZE = DEFINED(__heap_size__) ? __heap_size__ : 0x0400;
STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x0800;
RPMSG_SHMEM_SIZE = DEFINED(__use_shmem__) ? 0x2000 : 0;
TEXT_START = DEFINED(__qspi_xip__) ? 0x80001000 : 0x00000000; /* flexspi boot image start with 0x80000000 */
TEXT_SIZE = DEFINED(__qspi_xip__) ? 0x0FFFF000 : 0x000C0000; /* flexspi boot image offset at 0x80001000 */
/* Specify the memory areas */
MEMORY
{
m_interrupts (RX) : ORIGIN = TEXT_START, LENGTH = 0x00000400
m_text (RX) : ORIGIN = TEXT_START + 0x00000400, LENGTH = TEXT_SIZE - 0x00000400
m_core1_image (RX) : ORIGIN = 0x000C0000, LENGTH = 0x00040000
m_data (RW) : ORIGIN = 0x20000000, LENGTH = 0x0004E000 - RPMSG_SHMEM_SIZE
rpmsg_sh_mem (RW) : ORIGIN = 0x2004E000 - RPMSG_SHMEM_SIZE, LENGTH = RPMSG_SHMEM_SIZE
m_flash1 (RX) : ORIGIN = 0x00100000, LENGTH = 0x00100000
m_sramx (RW) : ORIGIN = 0x04000000, LENGTH = 0x00018000
m_flash_config (RX) : ORIGIN = 0x80000400, LENGTH = 0x00000200
m_usb_sram (RW) : ORIGIN = 0x400BA000, LENGTH = 0x00001000
}
/* Define output sections */
SECTIONS
{
/* section for storing the secondary core image */
.core1_code :
{
. = ALIGN(4) ;
KEEP (*(.core1_code))
*(.core1_code*)
. = ALIGN(4) ;
} > m_core1_image
/* NOINIT section for rpmsg_sh_mem */
.noinit_rpmsg_sh_mem (NOLOAD) : ALIGN(4)
{
__RPMSG_SH_MEM_START__ = .;
*(.noinit.$rpmsg_sh_mem*)
. = ALIGN(4) ;
__RPMSG_SH_MEM_END__ = .;
} > rpmsg_sh_mem
.flash_config :
{
. = ALIGN(4);
__FLASH_BASE = .;
KEEP(* (.flexspi_fcb)) /* FCB section */
. = ALIGN(4);
} > m_flash_config
/* The startup code goes first into internal flash */
.interrupts :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} > m_interrupts
/* The program code and other data goes into internal flash */
.text :
{
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
*(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
} > m_text
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > m_text
.ARM :
{
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} > m_text
.ctors :
{
__CTOR_LIST__ = .;
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
KEEP (*crtbegin?.o(.ctors))
/* We don't want to include the .ctor section from
from the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
__CTOR_END__ = .;
} > m_text
.dtors :
{
__DTOR_LIST__ = .;
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
__DTOR_END__ = .;
} > m_text
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*))
PROVIDE_HIDDEN (__preinit_array_end = .);
} > m_text
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} > m_text
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
} > m_text
__etext = .; /* define a global symbol at end of code */
__DATA_ROM = .; /* Symbol is used by startup for data initialization */
.data : AT(__DATA_ROM)
{
. = ALIGN(4);
__DATA_RAM = .;
__data_start__ = .; /* create a global symbol at data start */
*(.ramfunc*) /* for functions in ram */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
*(NonCacheable.init) /* NonCacheable init section */
*(NonCacheable) /* NonCacheable section */
*(CodeQuickAccess) /* quick access code section */
*(DataQuickAccess) /* quick access data section */
KEEP(*(.jcr*))
. = ALIGN(4);
__data_end__ = .; /* define a global symbol at data end */
} > m_data
__DATA_END = __DATA_ROM + (__data_end__ - __data_start__);
text_end = ORIGIN(m_text) + LENGTH(m_text);
ASSERT(__DATA_END <= text_end, "region m_text overflowed with text and data")
/* Uninitialized data section */
.bss :
{
/* This is used by the startup in order to initialize the .bss section */
. = ALIGN(4);
__START_BSS = .;
__bss_start__ = .;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
__END_BSS = .;
} > m_data
.heap :
{
. = ALIGN(8);
__end__ = .;
PROVIDE(end = .);
__HeapBase = .;
. += HEAP_SIZE;
__HeapLimit = .;
__heap_limit = .; /* Add for _sbrk */
} > m_data
.stack :
{
. = ALIGN(8);
. += STACK_SIZE;
} > m_data
m_usb_bdt (NOLOAD) :
{
. = ALIGN(512);
*(m_usb_bdt)
} > m_usb_sram
m_usb_global (NOLOAD) :
{
*(m_usb_global)
} > m_usb_sram
/* Initializes stack on the end of block */
__StackTop = ORIGIN(m_data) + LENGTH(m_data);
__StackLimit = __StackTop - STACK_SIZE;
PROVIDE(__stack = __StackTop);
.ARM.attributes 0 : { *(.ARM.attributes) }
ASSERT(__StackLimit >= __HeapLimit, "region m_data overflowed with stack and heap")
}

Wyświetl plik

@ -0,0 +1,129 @@
/*
** ###################################################################
** Processors: MCXN947VDF_cm33_core0
** MCXN947VNL_cm33_core0
**
** Compilers: GNU C Compiler
** IAR ANSI C/C++ Compiler for ARM
** Keil ARM C/C++ Compiler
** MCUXpresso Compiler
**
** Reference manual: MCXNx4x Reference Manual
** Version: rev. 2.0, 2023-02-01
** Build: b231120
**
** Abstract:
** Provides a system configuration function and a global variable that
** contains the system frequency. It configures the device and initializes
** the oscillator (PLL) that is part of the microcontroller device.
**
** Copyright 2016 Freescale Semiconductor, Inc.
** Copyright 2016-2023 NXP
** SPDX-License-Identifier: BSD-3-Clause
**
** http: www.nxp.com
** mail: support@nxp.com
**
** Revisions:
** - rev. 1.0 (2022-10-01)
** Initial version
** - rev. 2.0 (2023-02-01)
** Initial version based on Rev. 2 Draft B
**
** ###################################################################
*/
/*!
* @file MCXN947_cm33_core0
* @version 2.0
* @date 2023-02-01
* @brief Device specific configuration file for MCXN947_cm33_core0
* (implementation file)
*
* Provides a system configuration function and a global variable that contains
* the system frequency. It configures the device and initializes the oscillator
* (PLL) that is part of the microcontroller device.
*/
#include <stdint.h>
#include "fsl_device_registers.h"
/* ----------------------------------------------------------------------------
-- Core clock
---------------------------------------------------------------------------- */
uint32_t SystemCoreClock = DEFAULT_SYSTEM_CLOCK;
/* ----------------------------------------------------------------------------
-- SystemInit()
---------------------------------------------------------------------------- */
__attribute__ ((weak)) void SystemInit(void) {
#if ((__FPU_PRESENT == 1) && (__FPU_USED == 1))
SCB->CPACR |= ((3UL << 10 * 2) | (3UL << 11 * 2)); /* set CP10, CP11 Full Access in Secure mode */
#if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
SCB_NS->CPACR |= ((3UL << 10 * 2) | (3UL << 11 * 2)); /* set CP10, CP11 Full Access in Non-secure mode */
#endif /* (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
#endif /* ((__FPU_PRESENT == 1) && (__FPU_USED == 1)) */
SCB->CPACR |= ((3UL << 0 * 2) | (3UL << 1 * 2)); /* set CP0, CP1 Full Access in Secure mode (enable PowerQuad) */
#if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
SCB_NS->CPACR |= ((3UL << 0 * 2) | (3UL << 1 * 2)); /* set CP0, CP1 Full Access in Normal mode (enable PowerQuad) */
#endif /* (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
SCB->NSACR |= ((3UL << 0) | (3UL << 10)); /* enable CP0, CP1, CP10, CP11 Non-secure Access */
SYSCON->ECC_ENABLE_CTRL = 0; /* disable RAM ECC to get max RAM size */
// SYSCON->NVM_CTRL &= ~SYSCON_NVM_CTRL_DIS_MBECC_ERR_DATA_MASK; /* enables bus error on multi-bit ECC error for data */
#if defined(__MCUXPRESSO)
extern void(*const g_pfnVectors[]) (void);
SCB->VTOR = (uint32_t)&g_pfnVectors;
#else
extern void *__Vectors;
SCB->VTOR = (uint32_t)&__Vectors;
#endif
/* enable the flash cache LPCAC */
SYSCON->LPCAC_CTRL &= ~SYSCON_LPCAC_CTRL_DIS_LPCAC_MASK;
/* Disable aGDET trigger the CHIP_RESET */
ITRC0->OUT_SEL[4][0] = (ITRC0->OUT_SEL[4][0] & ~ITRC_OUTX_SEL_OUTX_SELY_OUT_SEL_IN9_SELn_MASK) | (ITRC_OUTX_SEL_OUTX_SELY_OUT_SEL_IN9_SELn(0x2));
ITRC0->OUT_SEL[4][1] = (ITRC0->OUT_SEL[4][1] & ~ITRC_OUTX_SEL_OUTX_SELY_OUT_SEL_IN9_SELn_MASK) | (ITRC_OUTX_SEL_OUTX_SELY_OUT_SEL_IN9_SELn(0x2));
/* Disable aGDET interrupt and reset */
SPC0->ACTIVE_CFG |= SPC_ACTIVE_CFG_GLITCH_DETECT_DISABLE_MASK;
SPC0->VDD_CORE_GLITCH_DETECT_SC &= ~SPC_VDD_CORE_GLITCH_DETECT_SC_LOCK_MASK;
SPC0->VDD_CORE_GLITCH_DETECT_SC = 0x3C;
/* Disable dGDET trigger the CHIP_RESET */
ITRC0->OUT_SEL[4][0] = (ITRC0->OUT_SEL[4][0] & ~ITRC_OUTX_SEL_OUTX_SELY_OUT_SEL_IN0_SELn_MASK) | (ITRC_OUTX_SEL_OUTX_SELY_OUT_SEL_IN0_SELn(0x2));
ITRC0->OUT_SEL[4][1] = (ITRC0->OUT_SEL[4][1] & ~ITRC_OUTX_SEL_OUTX_SELY_OUT_SEL_IN0_SELn_MASK) | (ITRC_OUTX_SEL_OUTX_SELY_OUT_SEL_IN0_SELn(0x2));
GDET0->GDET_ENABLE1 = 0;
GDET1->GDET_ENABLE1 = 0;
SystemInitHook();
}
/* ----------------------------------------------------------------------------
-- SystemCoreClockUpdate()
---------------------------------------------------------------------------- */
void SystemCoreClockUpdate(void) {
}
/* ----------------------------------------------------------------------------
-- SystemInitHook()
---------------------------------------------------------------------------- */
__attribute__ ((weak)) void SystemInitHook(void) {
/* Void implementation of the weak function. */
}

Wyświetl plik

@ -0,0 +1,108 @@
/*
** ###################################################################
** Processors: MCXN947VDF_cm33_core0
** MCXN947VNL_cm33_core0
**
** Compilers: GNU C Compiler
** IAR ANSI C/C++ Compiler for ARM
** Keil ARM C/C++ Compiler
** MCUXpresso Compiler
**
** Reference manual: MCXNx4x Reference Manual
** Version: rev. 2.0, 2023-02-01
** Build: b231026
**
** Abstract:
** Provides a system configuration function and a global variable that
** contains the system frequency. It configures the device and initializes
** the oscillator (PLL) that is part of the microcontroller device.
**
** Copyright 2016 Freescale Semiconductor, Inc.
** Copyright 2016-2023 NXP
** SPDX-License-Identifier: BSD-3-Clause
**
** http: www.nxp.com
** mail: support@nxp.com
**
** Revisions:
** - rev. 1.0 (2022-10-01)
** Initial version
** - rev. 2.0 (2023-02-01)
** Initial version based on Rev. 2 Draft B
**
** ###################################################################
*/
/*!
* @file MCXN947_cm33_core0
* @version 2.0
* @date 2023-02-01
* @brief Device specific configuration file for MCXN947_cm33_core0 (header file)
*
* Provides a system configuration function and a global variable that contains
* the system frequency. It configures the device and initializes the oscillator
* (PLL) that is part of the microcontroller device.
*/
#ifndef _SYSTEM_MCXN947_cm33_core0_H_
#define _SYSTEM_MCXN947_cm33_core0_H_ /**< Symbol preventing repeated inclusion */
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#define DEFAULT_SYSTEM_CLOCK 48000000u /* Default System clock value */
#define CLK_FRO_12MHZ 12000000u /* FRO 12 MHz (fro_12m) */
#define CLK_FRO_144MHZ 144000000u /* FRO 144 MHz (fro_144m) */
/**
* @brief System clock frequency (core clock)
*
* The system clock frequency supplied to the SysTick timer and the processor
* core clock. This variable can be used by the user application to setup the
* SysTick timer or configure other parameters. It may also be used by debugger to
* query the frequency of the debug timer or configure the trace clock speed
* SystemCoreClock is initialized with a correct predefined value.
*/
extern uint32_t SystemCoreClock;
/**
* @brief Setup the microcontroller system.
*
* Typically this function configures the oscillator (PLL) that is part of the
* microcontroller device. For systems with variable clock speed it also updates
* the variable SystemCoreClock. SystemInit is called from startup_device file.
*/
void SystemInit(void);
/**
* @brief Updates the SystemCoreClock variable.
*
* It must be called whenever the core clock is changed during program
* execution. SystemCoreClockUpdate() evaluates the clock register settings and calculates
* the current core clock.
*/
void SystemCoreClockUpdate(void);
/**
* @brief SystemInit function hook.
*
* This weak function allows to call specific initialization code during the
* SystemInit() execution.This can be used when an application specific code needs
* to be called as close to the reset entry as possible (for example the Multicore
* Manager MCMGR_EarlyInit() function call).
* NOTE: No global r/w variables can be used in this hook function because the
* initialization of these variables happens after this function.
*/
void SystemInitHook(void);
#ifdef __cplusplus
}
#endif
#endif /* _SYSTEM_MCXN947_cm33_core0_H_ */

108
ports/mcx/drv_adc.c 100644
Wyświetl plik

@ -0,0 +1,108 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2024 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "board.h"
#include "fsl_lpadc.h"
#include "fsl_spc.h"
#include "fsl_vref.h"
#include "drv_adc.h"
int drv_adc_init(drv_adc_t *adc, uint8_t id) {
adc->instance = MCX_BoardGetADCInstance(id);
if (adc->instance == NULL) {
return -EINVAL;
}
adc->id = id;
int adc_inputfreq = MCX_BoardConfigureADCClock(id);
if (adc_inputfreq <= 0) {
return -EINVAL;
}
ADC_Type *lpadc = adc->instance;
SPC_EnableActiveModeAnalogModules(SPC0, kSPC_controlVref);
vref_config_t vref_cfg;
VREF_GetDefaultConfig(&vref_cfg);
vref_cfg.bufferMode = kVREF_ModeBandgapOnly;
VREF_Init(VREF0, &vref_cfg);
lpadc_config_t adc_cfg;
LPADC_GetDefaultConfig(&adc_cfg);
adc_cfg.enableAnalogPreliminary = true;
adc_cfg.referenceVoltageSource = kLPADC_ReferenceVoltageAlt3;
LPADC_Init(lpadc, &adc_cfg);
LPADC_DoOffsetCalibration(lpadc);
LPADC_DoAutoCalibration(lpadc);
return 0;
}
int drv_adc_measure(drv_adc_t *adc, drv_adc_side_t side, uint8_t ch, uint16_t *result) {
ADC_Type *lpadc = adc->instance;
lpadc_conv_command_config_t cmd_cfg;
LPADC_GetDefaultConvCommandConfig(&cmd_cfg);
cmd_cfg.channelNumber = ch;
cmd_cfg.conversionResolutionMode = kLPADC_ConversionResolutionHigh;
if (side == DRV_ADCSideA) {
cmd_cfg.sampleChannelMode = kLPADC_SampleChannelSingleEndSideA;
} else {
cmd_cfg.sampleChannelMode = kLPADC_SampleChannelSingleEndSideB;
}
LPADC_SetConvCommandConfig(lpadc, 15, &cmd_cfg);
lpadc_conv_trigger_config_t trig_cfg;
LPADC_GetDefaultConvTriggerConfig(&trig_cfg);
trig_cfg.targetCommandId = 15;
trig_cfg.enableHardwareTrigger = false;
LPADC_SetConvTriggerConfig(lpadc, 0U, &trig_cfg);
LPADC_DoSoftwareTrigger(lpadc, 1U << 0U);
lpadc_conv_result_t rs;
while (!LPADC_GetConvResult(lpadc, &rs, 0U)) {
;
}
*result = rs.convValue;
return 0;
}

Wyświetl plik

@ -0,0 +1,45 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2024 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef MP_PORT_MCX_DRV_ADC_H
#define MP_PORT_MCX_DRV_ADC_H
#include <stdint.h>
typedef enum {
DRV_ADCSideA,
DRV_ADCSideB,
} drv_adc_side_t;
typedef struct {
uint8_t id;
void *instance;
} drv_adc_t;
int drv_adc_init(drv_adc_t *adc, uint8_t id);
int drv_adc_measure(drv_adc_t *adc, drv_adc_side_t side, uint8_t ch, uint16_t *result);
#endif

Wyświetl plik

@ -0,0 +1,96 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2024 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "board.h"
/* SDK drivers */
#include "fsl_lpi2c.h"
#include "drv_i2c.h"
int drv_i2c_init(drv_i2c_t *i2c, uint8_t id, drv_i2c_config_t *cfg) {
i2c->instance = MCX_BoardGetI2CInstance(id);
if (i2c->instance == NULL) {
return -EINVAL;
}
i2c->id = id;
int i2c_inputfreq = MCX_BoardConfigureI2CClock(id);
if (i2c_inputfreq <= 0) {
return -EINVAL;
}
lpi2c_master_config_t i2c_cfg;
LPI2C_MasterGetDefaultConfig(&i2c_cfg);
i2c_cfg.baudRate_Hz = cfg->frequency;
LPI2C_Type *lpi2c = i2c->instance;
LPI2C_MasterInit(lpi2c, &i2c_cfg, i2c_inputfreq);
return 0;
}
int drv_i2c_write(drv_i2c_t *i2c, uint16_t addr, uint8_t *data, uint32_t len, uint32_t timeout, bool stop) {
LPI2C_Type *lpi2c = i2c->instance;
lpi2c_master_transfer_t xfer = {
.direction = kLPI2C_Write,
.slaveAddress = addr,
.subaddress = 0,
.subaddressSize = 0U,
.data = data,
.dataSize = len,
.flags = stop ? kLPI2C_TransferDefaultFlag : kLPI2C_TransferNoStopFlag,
};
if (LPI2C_MasterTransferBlocking(lpi2c, &xfer) != kStatus_Success) {
return -EIO;
}
return 0;
}
int drv_i2c_read(drv_i2c_t *i2c, uint16_t addr, uint8_t *data, uint32_t len, uint32_t timeout, bool stop) {
LPI2C_Type *lpi2c = i2c->instance;
lpi2c_master_transfer_t xfer = {
.direction = kLPI2C_Read,
.slaveAddress = addr,
.subaddress = 0,
.subaddressSize = 0U,
.data = data,
.dataSize = len,
.flags = stop ? kLPI2C_TransferDefaultFlag : kLPI2C_TransferNoStopFlag,
};
if (LPI2C_MasterTransferBlocking(lpi2c, &xfer) != kStatus_Success) {
return -EIO;
}
return 0;
}

Wyświetl plik

@ -0,0 +1,50 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2024 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef MP_PORT_MCX_DRV_I2C_H
#define MP_PORT_MCX_DRV_I2C_H
#include "py/obj.h"
typedef enum {
DRV_I2CDirectionRead,
DRV_I2CDirectionWrite,
} drv_i2c_xfer_direction_t;
typedef struct {
uint32_t frequency;
} drv_i2c_config_t;
typedef struct {
uint8_t id;
void *instance;
} drv_i2c_t;
int drv_i2c_init(drv_i2c_t *i2c, uint8_t id, drv_i2c_config_t *cfg);
int drv_i2c_write(drv_i2c_t *i2c, uint16_t addr, uint8_t *data, uint32_t len, uint32_t timeout, bool stop);
int drv_i2c_read(drv_i2c_t *i2c, uint16_t addr, uint8_t *data, uint32_t len, uint32_t timeout, bool stop);
#endif

Wyświetl plik

@ -0,0 +1,95 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2024 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "board.h"
#include "fsl_cache_lpcac.h"
#include "drv_iflash.h"
int drv_iflash_init(drv_iflash_t *iflash) {
status_t ret = FLASH_Init(&iflash->flash_cfg);
if (ret != kStatus_Success) {
return -1;
}
return 0;
}
int drv_iflash_attr_get(drv_iflash_t *iflash, drv_iflash_attr_t *attr) {
status_t ret;
ret = FLASH_GetProperty(&iflash->flash_cfg, kFLASH_PropertyPflashSectorSize, &attr->sector_size);
if (ret != kStatus_Success) {
return -1;
}
ret = FLASH_GetProperty(&iflash->flash_cfg, kFLASH_PropertyPflashPageSize, &attr->page_size);
if (ret != kStatus_Success) {
return -1;
}
return 0;
}
int drv_iflash_read(drv_iflash_t *iflash, uint32_t addr, uint8_t *data, uint32_t len) {
memcpy(data, (uint8_t *)addr, len);
return 0;
}
int drv_iflash_erase_sector(drv_iflash_t *iflash, uint32_t sector_addr) {
uint32_t sector_size = 0U;
status_t ret = FLASH_GetProperty(&iflash->flash_cfg, kFLASH_PropertyPflashSectorSize, &sector_size);
if (ret != kStatus_Success) {
return -1;
}
ret = FLASH_Erase(&iflash->flash_cfg, sector_addr, sector_size, kFLASH_ApiEraseKey);
if (ret != kStatus_Success) {
return -1;
}
L1CACHE_InvalidateCodeCache();
return 0;
}
int drv_iflash_program_page(drv_iflash_t *iflash, uint32_t page_addr, uint8_t *data) {
uint32_t page_size = 0U;
status_t ret = FLASH_GetProperty(&iflash->flash_cfg, kFLASH_PropertyPflashPageSize, &page_size);
if (ret != kStatus_Success) {
return -1;
}
ret = FLASH_Program(&iflash->flash_cfg, page_addr, data, page_size);
if (ret != kStatus_Success) {
return -1;
}
L1CACHE_InvalidateCodeCache();
return 0;
}

Wyświetl plik

@ -0,0 +1,49 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2024 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef MP_PORT_MCX_DRV_IFLASH_H
#define MP_PORT_MCX_DRV_IFLASH_H
#include <stdint.h>
#include "fsl_flash.h"
typedef struct drv_iflash_attr_type {
uint32_t sector_size;
uint32_t page_size;
} drv_iflash_attr_t;
typedef struct {
flash_config_t flash_cfg;
} drv_iflash_t;
int drv_iflash_init(drv_iflash_t *iflash);
int drv_iflash_attr_get(drv_iflash_t *iflash, drv_iflash_attr_t *attr);
int drv_iflash_read(drv_iflash_t *iflash, uint32_t addr, uint8_t *data, uint32_t len);
int drv_iflash_erase_sector(drv_iflash_t *iflash, uint32_t sector_addr);
int drv_iflash_program_page(drv_iflash_t *iflash, uint32_t page_addr, uint8_t *data);
#endif

351
ports/mcx/drv_pin.c 100644
Wyświetl plik

@ -0,0 +1,351 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2024 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "board.h"
/* SDK drivers */
#include "fsl_gpio.h"
#include "fsl_port.h"
#include "drv_pin.h"
int drv_pin_init(drv_pin_t *pin) {
if (MCX_BoardConfigurePORTClock(pin->port) != 0) {
return -ENOENT;
}
if (MCX_BoardConfigureGPIOClock(pin->port) != 0) {
return -ENOENT;
}
return 0;
}
/**
* Initialize pin to specific AF or analog function
*/
int drv_pin_config_set(drv_pin_t *pin, drv_pin_config_t *cfg) {
int ret = 0;
ret = drv_pin_mode_set(pin, cfg->mode, cfg->af);
if (ret < 0) {
return ret;
}
ret = drv_pin_pull_set(pin, cfg->pull);
if (ret < 0) {
return ret;
}
ret = drv_pin_drive_set(pin, cfg->drive);
if (ret < 0) {
return ret;
}
return ret;
}
int drv_pin_config_get(drv_pin_t *pin, drv_pin_config_t *cfg) {
int ret = 0;
ret = drv_pin_mode_get(pin, &cfg->mode, &cfg->af);
if (ret < 0) {
return ret;
}
ret = drv_pin_pull_get(pin, &cfg->pull);
if (ret < 0) {
return ret;
}
ret = drv_pin_drive_get(pin, &cfg->drive);
if (ret < 0) {
return ret;
}
return ret;
}
int drv_pin_drive_set(drv_pin_t *pin, drv_pin_drive_t drive) {
PORT_Type *port = MCX_BoardGetPORTInstance(pin->port);
uint8_t pin_num = pin->pin;
/* Sanity checks */
if (port == NULL) {
return -ENOENT;
}
if (pin_num >= 32) {
return -EINVAL;
}
uint32_t pcr = port->PCR[pin_num];
pcr &= ~(PORT_PCR_DSE_MASK);
switch (drive) {
case DRV_PIN_DRIVE_HIGH:
pcr |= PORT_PCR_DSE(1U);
break;
case DRV_PIN_DRIVE_LOW:
default:
break;
}
port->PCR[pin_num] = pcr;
return 0;
}
int drv_pin_drive_get(drv_pin_t *pin, drv_pin_drive_t *drive) {
PORT_Type *port = MCX_BoardGetPORTInstance(pin->port);
uint8_t pin_num = pin->pin;
/* Sanity checks */
if (port == NULL) {
return -ENOENT;
}
if (pin_num >= 32) {
return -EINVAL;
}
uint32_t pcr = port->PCR[pin_num];
/* Drive */
if (pcr & PORT_PCR_DSE_MASK) {
*drive = DRV_PIN_DRIVE_HIGH;
} else {
*drive = DRV_PIN_DRIVE_LOW;
}
return 0;
}
int drv_pin_pull_set(drv_pin_t *pin, drv_pin_pull_type_t pull) {
PORT_Type *port = MCX_BoardGetPORTInstance(pin->port);
uint8_t pin_num = pin->pin;
/* Sanity checks */
if (port == NULL) {
return -ENOENT;
}
if (pin_num >= 32) {
return -EINVAL;
}
uint32_t pcr = port->PCR[pin_num];
pcr &= ~(PORT_PCR_PE_MASK | PORT_PCR_PS_MASK);
switch (pull) {
case DRV_PIN_PULL_UP:
pcr |= (PORT_PCR_PE_MASK | PORT_PCR_PS_MASK);
break;
case DRV_PIN_PULL_DOWN:
pcr |= PORT_PCR_PE_MASK;
break;
default:
case DRV_PIN_PULL_NONE:
break;
}
port->PCR[pin_num] = pcr;
return 0;
}
int drv_pin_pull_get(drv_pin_t *pin, drv_pin_pull_type_t *pull) {
PORT_Type *port = MCX_BoardGetPORTInstance(pin->port);
uint8_t pin_num = pin->pin;
/* Sanity checks */
if (port == NULL) {
return -ENOENT;
}
if (pin_num >= 32) {
return -EINVAL;
}
uint32_t pcr = port->PCR[pin_num];
/* Pull enabled */
if (pcr & PORT_PCR_PE_MASK) {
if (pcr & PORT_PCR_PS_MASK) {
*pull = DRV_PIN_PULL_UP;
} else {
*pull = DRV_PIN_PULL_DOWN;
}
} else {
*pull = DRV_PIN_PULL_NONE;
}
return 0;
}
int drv_pin_mode_set(drv_pin_t *pin, drv_pin_mode_t mode, uint8_t af) {
PORT_Type *port = MCX_BoardGetPORTInstance(pin->port);
GPIO_Type *gpio = MCX_BoardGetGPIOInstance(pin->port);
uint8_t pin_num = pin->pin;
/* Sanity checks */
if (port == NULL) {
return -ENOENT;
}
if (gpio == NULL) {
return -ENOENT;
}
if (pin_num >= 32) {
return -EINVAL;
}
uint32_t pcr = port->PCR[pin_num];
pcr &= ~(PORT_PCR_MUX_MASK | PORT_PCR_ODE_MASK);
pcr |= PORT_PCR_IBE(1U);
gpio_pin_config_t gpio_cfg = {
.pinDirection = kGPIO_DigitalInput,
.outputLogic = 0U,
};
uint8_t alt_id = af;
switch (mode) {
case DRV_PIN_MODE_INPUT:
alt_id = kPORT_MuxAlt0;
break;
case DRV_PIN_MODE_AF_PP:
break;
case DRV_PIN_MODE_OUTPUT_PP:
gpio_cfg.pinDirection = kGPIO_DigitalOutput;
GPIO_PinInit(gpio, pin_num, &gpio_cfg);
alt_id = kPORT_MuxAlt0;
break;
case DRV_PIN_MODE_OUTPUT_OD:
gpio_cfg.pinDirection = kGPIO_DigitalOutput;
GPIO_PinInit(gpio, pin_num, &gpio_cfg);
pcr |= PORT_PCR_ODE(1U);
alt_id = kPORT_MuxAlt0;
break;
case DRV_PIN_MODE_AF_OD:
pcr |= PORT_PCR_ODE(1U);
break;
case DRV_PIN_MODE_ANALOG:
default:
/* Clear IBE for analog functions */
pcr &= ~(PORT_PCR_IBE_MASK);
break;
}
/* Apply corresponding AF */
pcr |= PORT_PCR_MUX(alt_id);
port->PCR[pin_num] = pcr;
return 0;
}
int drv_pin_mode_get(drv_pin_t *pin, drv_pin_mode_t *mode, uint8_t *af) {
PORT_Type *port = MCX_BoardGetPORTInstance(pin->port);
GPIO_Type *gpio = MCX_BoardGetGPIOInstance(pin->port);
uint8_t pin_num = pin->pin;
/* Sanity checks */
if (port == NULL) {
return -ENOENT;
}
if (gpio == NULL) {
return -ENOENT;
}
if (pin_num >= 32) {
return -EINVAL;
}
uint32_t pcr = port->PCR[pin_num];
uint8_t mux = (pcr & PORT_PCR_MUX_MASK) >> PORT_PCR_MUX_SHIFT;
bool od = (pcr & PORT_PCR_ODE_MASK) >> PORT_PCR_ODE_SHIFT;
if (mux == 0) { /* GPIO or Analog mode */
if ((pcr & PORT_PCR_IBE_MASK) == 0U) {
*mode = DRV_PIN_MODE_ANALOG;
} else {
bool gpio_mode = (gpio->PDDR & (1U << pin_num)) ? true : false;
if (gpio_mode) {
if (od) {
*mode = DRV_PIN_MODE_OUTPUT_OD;
} else {
*mode = DRV_PIN_MODE_OUTPUT_PP;
}
} else {
*mode = DRV_PIN_MODE_INPUT;
}
}
} else {
if (od) {
*mode = DRV_PIN_MODE_AF_OD;
} else {
*mode = DRV_PIN_MODE_AF_PP;
}
*af = mux;
}
return 0;
}
int drv_pin_read(drv_pin_t *pin) {
GPIO_Type *gpio = MCX_BoardGetGPIOInstance(pin->port);
if (gpio == NULL) {
return -ENOENT;
}
uint32_t gpio_value = GPIO_PinRead(gpio, pin->pin);
return gpio_value ? 1 : 0;
}
int drv_pin_write(drv_pin_t *pin, bool value) {
GPIO_Type *gpio = MCX_BoardGetGPIOInstance(pin->port);
if (gpio == NULL) {
return -ENOENT;
}
uint8_t val = value ? 1 : 0;
GPIO_PinWrite(gpio, pin->pin, val);
return 0;
}

Wyświetl plik

@ -0,0 +1,83 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2024 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef MP_PORT_MCX_DRV_PIN_H
#define MP_PORT_MCX_DRV_PIN_H
#include "py/obj.h"
typedef enum {
DRV_PIN_PULL_NONE,
DRV_PIN_PULL_UP,
DRV_PIN_PULL_DOWN,
DRV_PIN_PULL_END,
} drv_pin_pull_type_t;
typedef enum {
DRV_PIN_DRIVE_LOW,
DRV_PIN_DRIVE_HIGH,
DRV_PIN_DRIVE_END,
} drv_pin_drive_t;
typedef enum {
DRV_PIN_MODE_ANALOG = 0U,
DRV_PIN_MODE_INPUT,
DRV_PIN_MODE_OUTPUT_PP,
DRV_PIN_MODE_OUTPUT_OD,
DRV_PIN_MODE_AF_PP,
DRV_PIN_MODE_AF_OD,
DRV_PIN_MODE_END,
} drv_pin_mode_t;
typedef struct drv_pin_config_type {
drv_pin_mode_t mode;
drv_pin_pull_type_t pull;
drv_pin_drive_t drive;
uint8_t af;
} drv_pin_config_t;
typedef struct drv_pin_type {
uint8_t port;
uint8_t pin;
} drv_pin_t;
int drv_pin_init(drv_pin_t *pin);
int drv_pin_config_set(drv_pin_t *pin, drv_pin_config_t *cfg);
int drv_pin_config_get(drv_pin_t *pin, drv_pin_config_t *cfg);
int drv_pin_drive_set(drv_pin_t *pin, drv_pin_drive_t drive);
int drv_pin_drive_get(drv_pin_t *pin, drv_pin_drive_t *drive);
int drv_pin_pull_set(drv_pin_t *pin, drv_pin_pull_type_t pull);
int drv_pin_pull_get(drv_pin_t *pin, drv_pin_pull_type_t *pull);
int drv_pin_mode_set(drv_pin_t *pin, drv_pin_mode_t mode, uint8_t af);
int drv_pin_mode_get(drv_pin_t *pin, drv_pin_mode_t *mode, uint8_t *af);
int drv_pin_read(drv_pin_t *pin);
int drv_pin_write(drv_pin_t *pin, bool value);
#endif

307
ports/mcx/drv_pwm.c 100644
Wyświetl plik

@ -0,0 +1,307 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2024 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "board.h"
/* SDK drivers */
#include "fsl_ctimer.h"
#include "drv_pwm.h"
static int drv_pwm_current_period_channel(drv_pwm_t *pwm) {
CTIMER_Type *ct = (CTIMER_Type *)pwm->instance;
uint32_t mcr = ct->MCR;
for (uint8_t i = 0; i < 4; i++) {
if (mcr & (1U << (3 * i + CTIMER_MCR_MR0R_SHIFT))) {
return i;
}
}
return -1;
}
static int drv_pwm_first_free_channel(drv_pwm_t *pwm) {
CTIMER_Type *ct = (CTIMER_Type *)pwm->instance;
int pc = drv_pwm_current_period_channel(pwm);
uint32_t pwmc = ct->PWMC;
for (uint8_t i = 0; i < 4; i++) {
if (pwmc & (1U << i)) {
/* Skip this channel if there's an active PWM output */
continue;
}
if (i == pc) {
/* Skip this channel if this channel is the current period channel */
continue;
}
return i;
}
/* There are no free channels left. */
return -1;
}
int drv_pwm_init(drv_pwm_t *pwm, uint8_t id, uint8_t channel, uint32_t freq, bool inverted) {
pwm->id = id;
pwm->channel = channel;
pwm->instance = MCX_BoardGetCT32Instance(id);
if (pwm->instance == NULL) {
return -EINVAL;
}
pwm->input_freq = MCX_BoardConfigureCT32Clock(id);
pwm->inverted = inverted;
CTIMER_Type *ct = (CTIMER_Type *)pwm->instance;
if ((ct->TCR & CTIMER_TCR_CEN_MASK) == 0U) {
/* There's two conditions for a all-zero TCR: either a reset condition or timer is stopped. */
/* In either case, we need to initialize the timer instance (AHB RST CTRL). */
/* TODO: Do not use SDK functions */
ctimer_config_t ct_cfg = {
.mode = kCTIMER_TimerMode,
.prescale = 1U,
};
/* Frequency: 150MHz max., we got 32bit counters, we can take that. */
/* Approx. maximum period: 28.6 seconds. */
CTIMER_Init(ct, &ct_cfg);
/* Current timer is not running, we are the first channel being configured. */
ct->TC = 0U; /* Reset counter */
ct->PC = 0U; /* Reset prescaler counter */
ct->PR = 0U; /* Prescaler, divide by 1 to get best resolution */
ct->MCR = 0U; /* Reset interrupt and reset condition */
ct->EMR = 0U; /* Do nothing on match event and output 0 as default state */
ct->PWMC = 0U; /* Disable all PWM channels, outputs will be controlled by EMn */
/* Here, we have a favoritism of using channel 3 as period channel, unless channel 3 is used for output */
if (channel != 3) {
ct->MR[3] = pwm->input_freq / freq;
ct->MCR |= CTIMER_MCR_MR3R_MASK;
} else {
/* Use channel 2 as period channel. */
ct->MR[2] = pwm->input_freq / freq;
ct->MCR |= CTIMER_MCR_MR2R_MASK;
}
/* Start counter */
ct->TCR |= CTIMER_TCR_CEN_MASK;
} else {
/*
* Due to the nature of the CTimer, one of the 4 match channels is needed for period control (frequency)
* To find out which one is the current period channel, check the MRxR bit for each match output.
* If we are configuring the same match being used as periodic channel, configure the next free match as period
* then current channel can be re-used. If all 4 channels are in use then the function will fail with an errno.
*/
/* The timer is running, check whether we need to re-locate the period channel */
int p_channel = drv_pwm_current_period_channel(pwm);
if (p_channel < 0) {
return -EINVAL;
}
if (p_channel == channel) {
/* We need to re-locate the period channel */
int f_channel = drv_pwm_first_free_channel(pwm);
if (f_channel < 0) {
/* There's no free channel, bail out. */
return -EBUSY;
}
/* Transfer the period channel to first free channel */
/* Step 1: Copy current period to first free channel */
ct->MR[f_channel] = ct->MR[p_channel];
/* Step 2: Enable reset for new period channel */
/* Note: it's safe doing it here since both old and new channel MRs contains same value */
ct->MCR |= (CTIMER_MCR_MR0R_MASK << (3 * f_channel));
/* Step 3: Disable reset for old period channel */
ct->MCR &= ~(CTIMER_MCR_MR0R_MASK << (3 * p_channel));
/* The old period channel is now available for PWM output */
p_channel = f_channel;
}
if (drv_pwm_freq_set(pwm, freq) < 0) {
return -EINVAL;
}
}
return 0;
}
int drv_pwm_deinit(drv_pwm_t *pwm) {
CTIMER_Type *ct = (CTIMER_Type *)pwm->instance;
/* Disable PWM output for channel, now the output is controlled by EMR */
ct->PWMC &= ~(CTIMER_PWMC_PWMEN0_MASK << pwm->channel);
/* Check whether there's still enabled channels */
if ((ct->PWMC & 0x0FU) == 0) {
/* Stop counter if this is the last. */
ct->TCR &= ~CTIMER_TCR_CEN_MASK;
}
return 0;
}
int drv_pwm_start(drv_pwm_t *pwm) {
CTIMER_Type *ct = (CTIMER_Type *)pwm->instance;
ct->PWMC |= (1U << pwm->channel);
return 0;
}
int drv_pwm_stop(drv_pwm_t *pwm) {
CTIMER_Type *ct = (CTIMER_Type *)pwm->instance;
ct->PWMC &= ~(1U << pwm->channel);
return 0;
}
int drv_pwm_freq_set(drv_pwm_t *pwm, uint32_t freq) {
CTIMER_Type *ct = (CTIMER_Type *)pwm->instance;
int p_channel = drv_pwm_current_period_channel(pwm);
if (p_channel < 0) {
return -EINVAL;
}
/* Store new values in shadow registers */
ct->MSR[p_channel] = pwm->input_freq / freq;
/* Enable period channel interrupt to check a reload event occurs.
* Since interrupts are not configured from NVIC, so no ISR will occur.
* Check IR[MRnINT] for reload point.
*/
uint32_t mcr_mask = (CTIMER_MCR_MR0RL_MASK << p_channel) | (CTIMER_MCR_MR0I_MASK << (3 * p_channel));
for (uint8_t i = 0; i < 4; i++) {
if (ct->PWMC & (1U << i)) {
/* Channel PWM output is enabled, calculate new values and store into shadow registers */
uint32_t new_mr = ct->MR[i] * ct->MSR[p_channel] / ct->MR[p_channel];
ct->MSR[i] = new_mr;
/* Update MRnRL map */
mcr_mask |= CTIMER_MCR_MR0RL_MASK << i;
}
}
/* Reload MRs on next counter reset, enable reload MR interrupt */
ct->MCR |= mcr_mask;
while ((ct->IR & (CTIMER_IR_MR0INT_MASK << p_channel)) == 0U) {
/* -- */
}
/* Disable reload channel interrupt and MSR synchronization */
ct->MCR &= ~mcr_mask;
/* Clear interrupt flags. */
ct->IR |= (CTIMER_IR_MR0INT_MASK << p_channel);
return 0;
}
int drv_pwm_freq_get(drv_pwm_t *pwm, uint32_t *freq) {
CTIMER_Type *ct = (CTIMER_Type *)pwm->instance;
int p_channel = drv_pwm_current_period_channel(pwm);
if (p_channel < 0) {
return -1;
}
*freq = pwm->input_freq / ct->MR[p_channel];
return 0;
}
int drv_pwm_duty_set(drv_pwm_t *pwm, uint16_t duty_u16) {
CTIMER_Type *ct = (CTIMER_Type *)pwm->instance;
int p_channel = drv_pwm_current_period_channel(pwm);
if (p_channel < 0) {
return -1;
}
/* To avoid overflow, use 64bit values here. */
uint64_t period = ct->MR[p_channel];
if (pwm->inverted) {
ct->MSR[pwm->channel] = period * duty_u16 / 65535;
} else {
ct->MSR[pwm->channel] = period - (period * duty_u16 / 65535);
}
/* Reload MRn on the next cycle */
ct->MCR |= (CTIMER_MCR_MR0RL_MASK << pwm->channel);
/* Wait for new duty cycle loaded into the MRn */
while (ct->MR[pwm->channel] != ct->MSR[pwm->channel]) {
/* -- */
}
/* Disable shadow register updates */
ct->MCR &= ~(CTIMER_MCR_MR0RL_MASK << pwm->channel);
return 0;
}
int drv_pwm_duty_get(drv_pwm_t *pwm, uint16_t *duty_u16) {
CTIMER_Type *ct = (CTIMER_Type *)pwm->instance;
int p_channel = drv_pwm_current_period_channel(pwm);
if (p_channel < 0) {
return -1;
}
uint32_t period = ct->MR[p_channel];
/* To avoid overflow, use 64bit values here. */
uint64_t duty = ct->MR[pwm->channel];
*duty_u16 = duty * 65535 / period;
return 0;
}

Wyświetl plik

@ -0,0 +1,51 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2024 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef MP_PORT_MCX_DRV_PWM_H
#define MP_PORT_MCX_DRV_PWM_H
#include <stdbool.h>
#include <stdint.h>
typedef struct drv_pwm_type {
uint8_t id;
void *instance;
uint8_t channel;
bool inverted;
uint32_t input_freq;
} drv_pwm_t;
int drv_pwm_init(drv_pwm_t *pwm, uint8_t id, uint8_t channel, uint32_t freq, bool inverted);
int drv_pwm_deinit(drv_pwm_t *pwm);
int drv_pwm_start(drv_pwm_t *pwm);
int drv_pwm_stop(drv_pwm_t *pwm);
int drv_pwm_freq_set(drv_pwm_t *pwm, uint32_t freq);
int drv_pwm_freq_get(drv_pwm_t *pwm, uint32_t *freq);
int drv_pwm_duty_set(drv_pwm_t *pwm, uint16_t duty_u16);
int drv_pwm_duty_get(drv_pwm_t *pwm, uint16_t *duty_u16);
#endif

Wyświetl plik

@ -0,0 +1,79 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2024 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "board.h"
/* SDK drivers */
#include "fsl_lpspi.h"
#include "drv_spi.h"
int drv_spi_init(drv_spi_t *spi, uint8_t id, drv_spi_config_t *cfg) {
spi->instance = MCX_BoardGetSPIInstance(id);
if (spi->instance == NULL) {
return -ENOENT;
}
spi->id = id;
int spi_inputfreq = MCX_BoardConfigureSPIClock(id);
if (spi_inputfreq <= 0) {
return -EINVAL;
}
lpspi_master_config_t spi_cfg;
LPSPI_MasterGetDefaultConfig(&spi_cfg);
spi_cfg.baudRate = cfg->frequency;
spi_cfg.bitsPerFrame = cfg->frame_size;
spi_cfg.cpol = cfg->cpol ? kLPSPI_ClockPolarityActiveLow : kLPSPI_ClockPolarityActiveHigh;
spi_cfg.cpha = cfg->cpha ? kLPSPI_ClockPhaseSecondEdge : kLPSPI_ClockPhaseFirstEdge;
spi_cfg.direction = cfg->lsbfirst ? kLPSPI_LsbFirst : kLPSPI_MsbFirst;
LPSPI_Type *lpspi = spi->instance;
LPSPI_MasterInit(lpspi, &spi_cfg, spi_inputfreq);
return 0;
}
int drv_spi_transfer(drv_spi_t *spi, drv_spi_transfer_t *transfer) {
LPSPI_Type *lpspi = spi->instance;
/* TODO: Ditch SDK drivers, prepare DMA transfer. */
lpspi_transfer_t xfer = {
.txData = (uint8_t *)transfer->tx_data, /* To SDK: Please do not touch that. */
.rxData = transfer->rx_data,
.dataSize = transfer->len,
};
status_t status = LPSPI_MasterTransferBlocking(lpspi, &xfer);
if (status != kStatus_Success) {
return -EIO;
}
return 0;
}

Wyświetl plik

@ -0,0 +1,54 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2024 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef MP_PORT_MCX_DRV_SPI_H
#define MP_PORT_MCX_DRV_SPI_H
#include "py/obj.h"
typedef struct drv_spi_config_type {
uint32_t frequency;
uint8_t cpol;
uint8_t cpha;
uint8_t frame_size;
bool lsbfirst;
} drv_spi_config_t;
typedef struct drv_spi_transfer_type {
const uint8_t *tx_data;
uint8_t *rx_data;
uint32_t len;
} drv_spi_transfer_t;
typedef struct drv_spi_type {
uint8_t id;
void *instance;
} drv_spi_t;
int drv_spi_init(drv_spi_t *spi, uint8_t id, drv_spi_config_t *cfg);
int drv_spi_transfer(drv_spi_t *spi, drv_spi_transfer_t *transfer);
#endif

Wyświetl plik

@ -0,0 +1,299 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2024 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "board.h"
/* SDK drivers */
#include "fsl_lpuart.h"
#if defined(MICROPY_HW_HAS_LPFLEXCOMM)
#include "fsl_lpflexcomm.h"
#endif
#include "drv_uart.h"
static void drv_uart_irq_handler(void *handle);
int drv_uart_init(drv_uart_t *uart, uint8_t id, drv_uart_config_t *cfg) {
uart->instance = MCX_BoardGetUARTInstance(id);
if (uart->instance == NULL) {
return -EINVAL;
}
uart->id = id;
int uart_inputfreq = MCX_BoardConfigureUARTClock(id);
if (uart_inputfreq <= 0) {
return -EINVAL;
}
lpuart_config_t uart_cfg;
LPUART_GetDefaultConfig(&uart_cfg);
uart_cfg.baudRate_Bps = cfg->baud_rate;
uart_cfg.enableRx = true;
uart_cfg.enableTx = true;
#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT
if (cfg->data_bits == DRV_Uart7DataBits) {
uart_cfg.dataBitsCount = kLPUART_SevenDataBits;
}
#endif
if (cfg->data_bits == DRV_Uart8DataBits) {
uart_cfg.dataBitsCount = kLPUART_EightDataBits;
}
switch (cfg->parity) {
case DRV_UartNoParity:
uart_cfg.parityMode = kLPUART_ParityDisabled;
break;
case DRV_UartEvenParity:
uart_cfg.parityMode = kLPUART_ParityEven;
break;
case DRV_UartOddParity:
uart_cfg.parityMode = kLPUART_ParityOdd;
break;
default:
break;
}
/* TODO: Flow control settings. */
LPUART_Type *lpuart = uart->instance;
if (LPUART_Init(lpuart, &uart_cfg, uart_inputfreq) != kStatus_Success) {
return -EIO;
}
#if defined(MICROPY_HW_HAS_LPFLEXCOMM)
/* For now, SDK drivers does not handle LPUART using P2/P3 correctly, initialize the pin functions manually. */
if (cfg->i2c_shared) {
LP_FLEXCOMM_Init(id, LP_FLEXCOMM_PERIPH_LPI2CAndLPUART);
}
#endif
uart->status = DRV_UartStatusIdle;
return 0;
}
int drv_uart_deinit(drv_uart_t *uart) {
int ret = 0;
LPUART_Type *lpuart = uart->instance;
LPUART_EnableTx(lpuart, false);
LPUART_EnableRx(lpuart, false);
LPUART_DisableInterrupts(lpuart, kLPUART_RxDataRegFullInterruptEnable);
lpuart->FIFO |= LPUART_FIFO_TXFLUSH_MASK | LPUART_FIFO_RXFLUSH_MASK;
return ret;
}
int drv_uart_write(drv_uart_t *uart, const uint8_t *data, int len, mp_uint_t timeout) {
int ret = 0;
LPUART_Type *lpuart = uart->instance;
/* TX can be used when async RX is enabled */
if (uart->status == DRV_UartStatusBusy) {
return -EBUSY;
}
/* Flush TX FIFO */
lpuart->FIFO |= LPUART_FIFO_TXFLUSH_MASK;
LPUART_EnableTx(lpuart, true);
mp_uint_t time_start = mp_hal_ticks_ms();
int tx_count;
for (tx_count = 0; tx_count < len; tx_count++) {
/* Wait for room in TX FIFO */
while (LPUART_GetTxFifoCount(lpuart) >= FSL_FEATURE_LPUART_FIFO_SIZEn(uart->id) - 1) {
if (timeout && (mp_hal_ticks_ms() - time_start > timeout)) {
ret = -ETIMEDOUT;
goto timeout_exit;
}
MICROPY_EVENT_POLL_HOOK
}
LPUART_WriteByte(lpuart, data[tx_count]);
}
/* Wait for all items in FIFO has been sent... */
while (LPUART_GetTxFifoCount(lpuart) > 0) {
if (timeout && (mp_hal_ticks_ms() - time_start > timeout)) {
ret = -ETIMEDOUT;
goto timeout_exit;
}
}
ret = tx_count;
timeout_exit:
LPUART_EnableTx(lpuart, false);
return ret;
}
int drv_uart_send_break(drv_uart_t *uart) {
/* TODO: Implement this */
return 0;
}
int drv_uart_read(drv_uart_t *uart, uint8_t *data, int len, mp_uint_t timeout) {
int ret = 0;
LPUART_Type *lpuart = uart->instance;
if (uart->status != DRV_UartStatusIdle) {
return -EBUSY;
}
uart->status = DRV_UartStatusBusy;
lpuart->FIFO |= LPUART_FIFO_RXFLUSH_MASK;
LPUART_EnableRx(lpuart, true);
mp_uint_t time_start = mp_hal_ticks_ms();
int rx_count;
for (rx_count = 0; rx_count < len; rx_count++) {
while (LPUART_GetRxFifoCount(lpuart) == 0) {
if (timeout && (mp_hal_ticks_ms() - time_start > timeout)) {
ret = rx_count;
goto timeout_exit;
}
MICROPY_EVENT_POLL_HOOK
}
data[rx_count] = LPUART_ReadByte(lpuart);
}
ret = rx_count;
timeout_exit:
LPUART_EnableRx(lpuart, false);
uart->status = DRV_UartStatusIdle;
return ret;
}
int drv_uart_async_callback(drv_uart_t *uart, drv_uart_async_fn_t fn) {
if (uart->status != DRV_UartStatusIdle) {
return -EBUSY;
}
uart->async_fn = fn;
return 0;
}
int drv_uart_async_start(drv_uart_t *uart, drv_uart_async_fn_t fn, void *param) {
if (uart->status != DRV_UartStatusIdle) {
return -EBUSY;
}
LPUART_Type *lpuart = uart->instance;
uart->async_fn = fn;
uart->async_fn_param = param;
uart->status = DRV_UartStatusAsyncRx;
/* Flush FIFO */
lpuart->FIFO |= LPUART_FIFO_RXFLUSH_MASK;
/* Set watermark to 0 to generate a interrupt whenever there's data in FIFO. */
LPUART_SetRxFifoWatermark(lpuart, 0U);
/* RXFE interrupt */
LPUART_EnableInterrupts(lpuart, kLPUART_RxDataRegFullInterruptEnable);
MCX_BoardConfigureUARTISR(uart->id, drv_uart_irq_handler, uart);
LPUART_EnableRx(lpuart, true);
return 0;
}
int drv_uart_async_read(drv_uart_t *uart, uint8_t *data, uint8_t len) {
LPUART_Type *lpuart = uart->instance;
for (uint8_t i = 0; i < len; i++) {
data[i] = lpuart->DATA;
}
return len;
}
int drv_uart_async_cancel(drv_uart_t *uart) {
drv_uart_status_t status = uart->status;
LPUART_Type *lpuart = uart->instance;
if (status == DRV_UartStatusBusy) {
return -EBUSY;
}
if (status == DRV_UartStatusIdle) {
return -EINVAL;
}
if (status == DRV_UartStatusAsyncRx) {
LPUART_EnableRx(lpuart, false);
lpuart->FIFO |= LPUART_FIFO_RXFLUSH_MASK;
LPUART_DisableInterrupts(lpuart, kLPUART_RxDataRegFullInterruptEnable);
MCX_BoardConfigureUARTISR(uart->id, NULL, NULL);
}
return 0;
}
static void drv_uart_irq_handler(void *handle) {
drv_uart_t *uart = (drv_uart_t *)handle;
LPUART_Type *lpuart = uart->instance;
uint32_t ip_status = LPUART_GetStatusFlags(lpuart);
if (ip_status & kLPUART_RxDataRegFullFlag) {
if (uart->status == DRV_UartStatusAsyncRx) {
/* Interrupt is only active for Async RX mode. */
uint8_t lvl = LPUART_GetRxFifoCount(lpuart);
uart->async_fn(uart, uart->async_fn_param, lvl);
}
}
LPUART_ClearStatusFlags(lpuart, ip_status);
}

Wyświetl plik

@ -0,0 +1,90 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2024 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef MP_PORT_MCX_DRV_UART_H
#define MP_PORT_MCX_DRV_UART_H
#include <stdint.h>
#include <stdbool.h>
typedef enum {
DRV_Uart7DataBits,
DRV_Uart8DataBits,
} drv_uart_data_bits_t;
typedef enum {
DRV_Uart1StopBits,
DRV_Uart2StopBits,
} drv_uart_stop_bits_t;
typedef enum {
DRV_UartNoParity,
DRV_UartEvenParity,
DRV_UartOddParity,
} drv_uart_parity_t;
typedef enum {
DRV_UartNoFlowControl,
DRV_UartCtsFlowControl,
DRV_UartRtsFlowControl,
DRV_UartCtsRtsFlowControl,
} drv_uart_flow_control_t;
typedef enum {
DRV_UartStatusIdle,
DRV_UartStatusBusy,
DRV_UartStatusAsyncRx,
} drv_uart_status_t;
typedef void (*drv_uart_async_fn_t)(void *uart, void *param, uint8_t len);
typedef struct drv_uart_type {
uint8_t id;
void *instance;
drv_uart_status_t status;
drv_uart_async_fn_t async_fn;
void *async_fn_param;
} drv_uart_t;
typedef struct drv_uart_config_type {
uint32_t baud_rate;
bool i2c_shared;
drv_uart_data_bits_t data_bits;
drv_uart_stop_bits_t stop_bits;
drv_uart_parity_t parity;
drv_uart_flow_control_t flow_control;
} drv_uart_config_t;
int drv_uart_init(drv_uart_t *uart, uint8_t id, drv_uart_config_t *cfg);
int drv_uart_deinit(drv_uart_t *uart);
int drv_uart_write(drv_uart_t *uart, const uint8_t *data, int len, mp_uint_t timeout);
int drv_uart_send_break(drv_uart_t *uart);
int drv_uart_read(drv_uart_t *uart, uint8_t *data, int len, mp_uint_t timeout);
int drv_uart_async_start(drv_uart_t *uart, drv_uart_async_fn_t fn, void *param);
int drv_uart_async_read(drv_uart_t *uart, uint8_t *data, uint8_t len);
int drv_uart_async_cancel(drv_uart_t *uart);
#endif

227
ports/mcx/hal_pin.c 100644
Wyświetl plik

@ -0,0 +1,227 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2024 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "py/runtime.h"
#include "py/mphal.h"
#include "fsl_common.h"
#include "fsl_common_arm.h"
/* Note: the HAL pin interface is used by several extmods,
* which requires a machine.Pin object as its parameter.
* As the corresponding PORT and GPIO clocks are initialized in drv_pin_init(),
* which is called by Machine.Pin() constructor, only basic functions are required here.
* Same for alternative functions and pin modes.
*/
const mp_hal_pin_obj_t mp_hal_pin_find_named_pin(const mp_obj_dict_t *named_pins, mp_obj_t name) {
const mp_map_t *named_map = &named_pins->map;
mp_map_elem_t *named_elem = mp_map_lookup((mp_map_t *)named_map, name, MP_MAP_LOOKUP);
if (named_elem == NULL || named_elem->value == MP_OBJ_NULL) {
return NULL;
}
return MP_OBJ_TO_PTR(named_elem->value);
}
const machine_pin_af_t *mp_hal_pin_find_af(const mp_hal_pin_obj_t pin, machine_pin_af_type_t type,
uint8_t idx, machine_pin_af_attr_t attr) {
for (uint8_t i = 0; i < pin->af_count; i++) {
if (pin->af[i].af_type != type) {
continue;
}
if (pin->af[i].af_instance_id != idx) {
continue;
}
if (pin->af[i].af_attribute != attr) {
continue;
}
return &pin->af[i];
}
return NULL;
}
const machine_pin_adc_t *mp_hal_pin_find_adc(const mp_hal_pin_obj_t pin) {
return pin->adc;
}
const machine_pin_af_t *mp_hal_pin_find_pwm(const mp_hal_pin_obj_t pin) {
for (uint8_t i = 0; i < pin->af_count; i++) {
if (pin->af[i].af_type != MACHINE_PIN_AF_TYPE_CT32) {
continue;
}
/* Attribute with bit 7 set is a input capture channel */
if (pin->af[i].af_attribute & 0x80) {
continue;
}
return &pin->af[i];
}
return NULL;
}
bool mp_hal_pin_read(mp_hal_pin_obj_t pin) {
drv_pin_t p = {
.port = pin->port,
.pin = pin->pin,
};
return drv_pin_read(&p);
}
void mp_hal_pin_write(mp_hal_pin_obj_t pin, bool value) {
drv_pin_t p = {
.port = pin->port,
.pin = pin->pin,
};
drv_pin_write(&p, value);
}
void mp_hal_pin_high(mp_hal_pin_obj_t pin) {
drv_pin_t p = {
.port = pin->port,
.pin = pin->pin,
};
drv_pin_write(&p, true);
}
void mp_hal_pin_od_high(mp_hal_pin_obj_t pin) {
drv_pin_t p = {
.port = pin->port,
.pin = pin->pin,
};
drv_pin_write(&p, true);
}
void mp_hal_pin_low(mp_hal_pin_obj_t pin) {
drv_pin_t p = {
.port = pin->port,
.pin = pin->pin,
};
drv_pin_write(&p, false);
}
void mp_hal_pin_od_low(mp_hal_pin_obj_t pin) {
drv_pin_t p = {
.port = pin->port,
.pin = pin->pin,
};
drv_pin_write(&p, false);
}
void mp_hal_pin_open_drain(mp_hal_pin_obj_t pin) {
drv_pin_t p = {
.port = pin->port,
.pin = pin->pin,
};
drv_pin_mode_set(&p, DRV_PIN_MODE_OUTPUT_OD, 0U);
}
void mp_hal_pin_output(mp_hal_pin_obj_t pin) {
drv_pin_t p = {
.port = pin->port,
.pin = pin->pin,
};
drv_pin_mode_set(&p, DRV_PIN_MODE_OUTPUT_PP, 0U);
}
void mp_hal_pin_input(mp_hal_pin_obj_t pin) {
drv_pin_t p = {
.port = pin->port,
.pin = pin->pin,
};
drv_pin_mode_set(&p, DRV_PIN_MODE_INPUT, 0U);
}
void mp_hal_pin_analog(mp_hal_pin_obj_t pin) {
drv_pin_t p = {
.port = pin->port,
.pin = pin->pin,
};
drv_pin_mode_set(&p, DRV_PIN_MODE_ANALOG, 0U);
}
void mp_hal_pin_af(mp_hal_pin_obj_t pin, uint8_t af_num) {
drv_pin_t p = {
.port = pin->port,
.pin = pin->pin,
};
drv_pin_mode_set(&p, DRV_PIN_MODE_AF_PP, af_num);
}
void mp_hal_pin_af_od(mp_hal_pin_obj_t pin, uint8_t af_num) {
drv_pin_t p = {
.port = pin->port,
.pin = pin->pin,
};
drv_pin_mode_set(&p, DRV_PIN_MODE_AF_OD, af_num);
}
void mp_hal_pin_pull_up(mp_hal_pin_obj_t pin) {
drv_pin_t p = {
.port = pin->port,
.pin = pin->pin,
};
drv_pin_pull_set(&p, DRV_PIN_PULL_UP);
}
void mp_hal_pin_pull_down(mp_hal_pin_obj_t pin) {
drv_pin_t p = {
.port = pin->port,
.pin = pin->pin,
};
drv_pin_pull_set(&p, DRV_PIN_PULL_DOWN);
}
void mp_hal_pin_pull_none(mp_hal_pin_obj_t pin) {
drv_pin_t p = {
.port = pin->port,
.pin = pin->pin,
};
drv_pin_pull_set(&p, DRV_PIN_PULL_NONE);
}

Wyświetl plik

@ -0,0 +1,84 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2024 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef MP_PORT_MCX_HAL_PIN_H
#define MP_PORT_MCX_HAL_PIN_H
#include "drv_pin.h"
#include "machine_pin.h"
#define mp_hal_pin_obj_t machine_pin_obj_t *
#define mp_hal_get_pin_obj(p) (p)
#define MP_HAL_PIN_MODE_ANALOG (DRV_PIN_MODE_ANALOG)
#define MP_HAL_PIN_MODE_INPUT (DRV_PIN_MODE_INPUT)
#define MP_HAL_PIN_MODE_OUTPUT (DRV_PIN_MODE_OUTPUT_PP)
#define MP_HAL_PIN_MODE_OPEN_DRAIN (DRV_PIN_MODE_OUTPUT_OD)
#define MP_HAL_PIN_MODE_ALT (DRV_PIN_MODE_AF_PP)
#define MP_HAL_PIN_MODE_ALT_OPEN_DRAIN (DRV_PIN_MODE_AF_OD)
#define MP_HAL_PIN_PULL_NONE (DRV_PIN_PULL_NONE)
#define MP_HAL_PIN_PULL_UP (DRV_PIN_PULL_UP)
#define MP_HAL_PIN_PULL_DOWN (DRV_PIN_PULL_DOWN)
#define MP_HAL_PIN_TRIGGER_FALLING (GPIO_IRQ_FALLING)
#define MP_HAL_PIN_TRIGGER_RISING (GPIO_IRQ_RISING)
#define MP_HAL_PIN_TRIGGER_LOWLEVEL (GPIO_IRQ_LOWLEVEL)
#define MP_HAL_PIN_TRIGGER_HIGHLEVEL (GPIO_IRQ_HIGHLEVEL)
#define MP_HAL_PIN_DRIVE_0 (DRV_PIN_DRIVE_LOW)
#define MP_HAL_PIN_DRIVE_1 (DRV_PIN_DRIVE_HIGH)
const mp_hal_pin_obj_t mp_hal_pin_find_named_pin(const mp_obj_dict_t *named_pins, mp_obj_t name);
const machine_pin_af_t *mp_hal_pin_find_af(const mp_hal_pin_obj_t pin, machine_pin_af_type_t type,
uint8_t idx, machine_pin_af_attr_t attr);
const machine_pin_adc_t *mp_hal_pin_find_adc(const mp_hal_pin_obj_t pin);
const machine_pin_af_t *mp_hal_pin_find_pwm(const mp_hal_pin_obj_t pin);
void mp_hal_pin_high(mp_hal_pin_obj_t pin);
void mp_hal_pin_od_high(mp_hal_pin_obj_t pin);
void mp_hal_pin_low(mp_hal_pin_obj_t pin);
void mp_hal_pin_od_low(mp_hal_pin_obj_t pin);
bool mp_hal_pin_read(mp_hal_pin_obj_t pin);
void mp_hal_pin_write(mp_hal_pin_obj_t pin, bool value);
void mp_hal_pin_open_drain(mp_hal_pin_obj_t pin);
void mp_hal_pin_output(mp_hal_pin_obj_t pin);
void mp_hal_pin_input(mp_hal_pin_obj_t pin);
void mp_hal_pin_analog(mp_hal_pin_obj_t pin);
void mp_hal_pin_af(mp_hal_pin_obj_t pin, uint8_t af_num);
void mp_hal_pin_af_od(mp_hal_pin_obj_t pin, uint8_t af_num);
void mp_hal_pin_pull_up(mp_hal_pin_obj_t pin);
void mp_hal_pin_pull_down(mp_hal_pin_obj_t pin);
void mp_hal_pin_pull_none(mp_hal_pin_obj_t pin);
#endif

Wyświetl plik

@ -0,0 +1,154 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2024 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "py/runtime.h"
#include "py/stream.h"
#include "py/mperrno.h"
#include "py/mphal.h"
#include "py/ringbuf.h"
#include "extmod/misc.h"
#include "tusb.h"
#include "drv_uart.h"
#include "pendsv.h"
static uint8_t s_stdin_rb_array[512];
static ringbuf_t s_stdin_rb = {
.buf = s_stdin_rb_array,
.size = sizeof(s_stdin_rb_array),
};
static void mp_hal_stdin_intr_callback(void *handle, void *param, uint8_t len);
int mp_hal_stdio_init(void) {
drv_uart_t *uart = MP_STATE_PORT(stdio_uart);
return drv_uart_async_start(uart, mp_hal_stdin_intr_callback, &s_stdin_rb);
}
uintptr_t mp_hal_stdio_poll(uintptr_t poll_flags) {
return mp_os_dupterm_poll(poll_flags);
}
mp_uint_t mp_hal_stdout_tx_strn(const char *str, size_t len) {
mp_uint_t ret = len;
bool write_done = false;
#if MICROPY_HW_ENABLE_UART_REPL
drv_uart_t *uart = MP_STATE_PORT(stdio_uart);
drv_uart_write(uart, (const uint8_t *)str, len, 1000);
write_done = true;
#endif
#if MICROPY_HW_USB_CDC
if (tud_cdc_connected()) {
size_t i = 0;
while (i < len) {
uint32_t n = len - i;
if (n > CFG_TUD_CDC_EP_BUFSIZE) {
n = CFG_TUD_CDC_EP_BUFSIZE;
}
int timeout = 0;
// Wait with a max of USC_CDC_TIMEOUT ms
while (n > tud_cdc_write_available() && timeout++ < 1000) {
MICROPY_EVENT_POLL_HOOK
}
if (timeout >= 1000) {
break;
}
uint32_t n2 = tud_cdc_write(str + i, n);
tud_cdc_write_flush();
i += n2;
}
write_done = true;
}
#endif
#if MICROPY_PY_OS_DUPTERM
int dupterm_res = mp_os_dupterm_tx_strn(str, len);
if (dupterm_res >= 0) {
ret = MIN((mp_uint_t)dupterm_res, ret);
}
#endif
if (!write_done) {
ret = 0U;
}
return ret;
}
int mp_hal_stdin_rx_chr(void) {
char ch = 0x00;
for (;;) {
if (ringbuf_avail(&s_stdin_rb)) {
ch = ringbuf_get(&s_stdin_rb);
break;
}
MICROPY_EVENT_POLL_HOOK
}
return ch;
}
void tud_cdc_rx_cb(uint8_t itf) {
/* TODO: This implementation is not safe when UART ISR is interrupted by USB ISR. */
/* Both terminals will write to the same ring-buffer, which is not guarded. */
uint32_t bytes_avail = tud_cdc_n_available(itf);
while (bytes_avail > 0) {
int ch = tud_cdc_read_char();
if (ch == mp_interrupt_char) {
mp_sched_keyboard_interrupt();
} else {
ringbuf_put(&s_stdin_rb, ch);
}
bytes_avail--;
}
}
static void mp_hal_stdin_intr_callback(void *handle, void *param, uint8_t len) {
ringbuf_t *rb = (ringbuf_t *)param;
drv_uart_t *uart = (drv_uart_t *)handle;
uint8_t ch;
for (uint8_t i = 0; i < len; i++) {
drv_uart_async_read(uart, &ch, 1);
if (ch == mp_interrupt_char) {
pendsv_kbd_intr();
} else {
ringbuf_put(rb, ch);
}
}
}
MP_REGISTER_ROOT_POINTER(struct drv_uart_type *stdio_uart);

Wyświetl plik

@ -0,0 +1,76 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2024 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "py/runtime.h"
#include "py/mphal.h"
#include "fsl_common.h"
#include "fsl_common_arm.h"
volatile mp_uint_t s_current_tick;
void mp_hal_delay_ms(mp_uint_t ms) {
mp_uint_t t_start = s_current_tick;
while (s_current_tick < (t_start + ms)) {
MICROPY_EVENT_POLL_HOOK
}
}
void mp_hal_delay_us(mp_uint_t us) {
mp_uint_t t_end = mp_hal_ticks_us() + us;
while (mp_hal_ticks_us() < t_end) {
/* Do not poll events here */
}
/* TODO: handle condition when interrupts are disabled. */
}
mp_uint_t mp_hal_ticks_ms(void) {
return s_current_tick * 1000 / MICROPY_HAL_SYSTICK_RATE;
}
mp_uint_t mp_hal_ticks_us(void) {
mp_uint_t reload = SysTick->LOAD;
mp_uint_t usec = (reload - SysTick->VAL) * (1000000 / MICROPY_HAL_SYSTICK_RATE) / reload;
return s_current_tick * (1000000 / MICROPY_HAL_SYSTICK_RATE) + usec;
}
uint64_t mp_hal_time_ns(void) {
return mp_hal_ticks_us() * 1000;
}
mp_uint_t mp_hal_ticks_cpu(void) {
for (;;) {
/* -- */
}
}
void SysTick_Handler(void) {
s_current_tick++;
}

Wyświetl plik

@ -0,0 +1,107 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2013-2017 Damien P. George
* Copyright (c) 2024 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
// This file is never compiled standalone, it's included directly from
// extmod/machine_adc.c via MICROPY_PY_MACHINE_ADC_INCLUDEFILE.
#include "py/mphal.h"
#include "drv_adc.h"
#define MICROPY_PY_MACHINE_ADC_CLASS_CONSTANTS
typedef struct _machine_adc_obj_t {
mp_obj_base_t base;
uint8_t id;
drv_adc_t drv;
drv_adc_side_t side;
uint8_t channel;
} machine_adc_obj_t;
static void mp_machine_adc_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
machine_adc_obj_t *self = MP_OBJ_TO_PTR(self_in);
mp_printf(print, "ADC(%u,", self->id);
char side = 'A';
if (self->side == DRV_ADCSideB) {
side = 'B';
}
mp_printf(print, " side=%c, channel=%u)", side, self->channel);
}
static mp_obj_t mp_machine_adc_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 1, 1, false);
mp_obj_t pin_obj = args[0];
if (!mp_obj_is_type(pin_obj, &machine_pin_type)) {
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("Object is not a Pin object."));
}
mp_hal_pin_obj_t pin = MP_OBJ_TO_PTR(pin_obj);
const machine_pin_adc_t *adc = mp_hal_pin_find_adc(pin);
if (adc == NULL) {
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("Pin does not have ADC capabilities."));
}
machine_adc_obj_t *self = mp_obj_malloc(machine_adc_obj_t, &machine_adc_type);
mp_hal_pin_analog(pin);
self->id = adc->adc_id;
self->channel = adc->adc_channel;
switch (adc->adc_side) {
case 'A':
default:
self->side = DRV_ADCSideA;
break;
case 'B':
self->side = DRV_ADCSideB;
break;
}
if (drv_adc_init(&self->drv, self->id) < 0) {
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("failed to initialize ADC"));
}
return MP_OBJ_FROM_PTR(self);
}
static mp_int_t mp_machine_adc_read_u16(machine_adc_obj_t *self) {
uint16_t ad_val;
int ret = drv_adc_measure(&self->drv, self->side, self->channel, &ad_val);
if (ret < 0) {
return ret;
}
return ad_val;
}

Wyświetl plik

@ -0,0 +1,153 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2013-2017 Damien P. George
* Copyright (c) 2024 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "extmod/modmachine.h"
#include "drv_i2c.h"
typedef struct _machine_i2c_obj_t {
mp_obj_base_t base;
uint8_t id;
uint32_t frequency;
drv_i2c_t drv;
uint32_t timeout;
} machine_i2c_obj_t;
static void machine_i2c_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
machine_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in);
mp_printf(print, "I2C(%u, freq=%u)", self->id, self->frequency);
}
static void mp_machine_i2c_init_helper(machine_i2c_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_freq, ARG_scl, ARG_sda, ARG_timeout };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_freq, MP_ARG_INT, {.u_int = 400000} },
{ MP_QSTR_scl, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE}},
{ MP_QSTR_sda, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE}},
{ MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 500}},
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
drv_i2c_config_t i2c_cfg;
self->frequency = args[ARG_freq].u_int;
i2c_cfg.frequency = self->frequency;
if (args[ARG_scl].u_obj == mp_const_none) {
/* TODO: Prepare a default pin for SCL*/
} else {
mp_hal_pin_obj_t pin = args[ARG_scl].u_obj;
/* TODO: Non LP-Flexcomm pinmap for future A series */
const machine_pin_af_t *af = mp_hal_pin_find_af(pin, MACHINE_PIN_AF_TYPE_LPFC, self->id, MACHINE_PIN_AF_ATTR_LPFC_P1);
if (af == NULL) {
mp_raise_ValueError(MP_ERROR_TEXT("unsupported SCL AF"));
}
mp_hal_pin_af_od(pin, af->af_id);
mp_hal_pin_pull_up(pin);
}
if (args[ARG_sda].u_obj == mp_const_none) {
/* TODO: Prepare a default pin for SCL*/
} else {
mp_hal_pin_obj_t pin = args[ARG_sda].u_obj;
/* TODO: Non LP-Flexcomm pinmap for future A series */
const machine_pin_af_t *af = mp_hal_pin_find_af(pin, MACHINE_PIN_AF_TYPE_LPFC, self->id, MACHINE_PIN_AF_ATTR_LPFC_P0);
if (af == NULL) {
mp_raise_ValueError(MP_ERROR_TEXT("unsupported SDA AF"));
}
mp_hal_pin_af_od(pin, af->af_id);
mp_hal_pin_pull_up(pin);
}
self->timeout = args[ARG_timeout].u_int;
/* TODO: Check return values */
drv_i2c_init(&self->drv, self->id, &i2c_cfg);
}
mp_obj_t machine_i2c_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
if (!mp_obj_is_int(args[0])) {
mp_raise_ValueError(MP_ERROR_TEXT("unsupported I2C id."));
return mp_const_none;
}
machine_i2c_obj_t *self = mp_obj_malloc(machine_i2c_obj_t, &machine_i2c_type);
self->id = mp_obj_get_int(args[0]);
mp_map_t kw_args;
mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
mp_machine_i2c_init_helper(self, n_args - 1, args + 1, &kw_args);
return MP_OBJ_FROM_PTR(self);
}
static int machine_i2c_transfer_single(mp_obj_base_t *self_in, uint16_t addr, size_t len, uint8_t *buf, unsigned int flags) {
machine_i2c_obj_t *self = MP_OBJ_FROM_PTR(self_in);
int ret;
bool stop = (flags & MP_MACHINE_I2C_FLAG_STOP) ? true : false;
if (flags & MP_MACHINE_I2C_FLAG_READ) {
ret = drv_i2c_read(&self->drv, addr, buf, len, self->timeout, stop);
if (ret < 0) {
return ret;
}
} else {
ret = drv_i2c_write(&self->drv, addr, buf, len, self->timeout, stop);
if (ret < 0) {
return ret;
}
}
return len;
}
static const mp_machine_i2c_p_t machine_i2c_p = {
.transfer = mp_machine_i2c_transfer_adaptor,
.transfer_single = machine_i2c_transfer_single,
};
MP_DEFINE_CONST_OBJ_TYPE(
machine_i2c_type,
MP_QSTR_I2C,
MP_TYPE_FLAG_NONE,
make_new, machine_i2c_make_new,
print, machine_i2c_print,
protocol, &machine_i2c_p,
locals_dict, &mp_machine_i2c_locals_dict
);

Wyświetl plik

@ -0,0 +1,349 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2013-2017 Damien P. George
* Copyright (c) 2024 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "extmod/modmachine.h"
#include "extmod/virtpin.h"
#include "machine_pin.h"
#include "machine_pin_defs.h"
static mp_obj_t machine_pin_obj_init_helper(const machine_pin_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_mode, ARG_pull, ARG_value, ARG_drive, ARG_alt };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_mode, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE }},
{ MP_QSTR_pull, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE}},
{ MP_QSTR_value, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE}},
{ MP_QSTR_drive, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE}},
{ MP_QSTR_alt, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0}},
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
drv_pin_t pin = {
.port = self->port,
.pin = self->pin,
};
drv_pin_config_t pin_cfg;
/* Retrieve current (default) configuration */
drv_pin_config_get(&pin, &pin_cfg);
/* TODO: check return value */
/* Validate and set mode */
if (args[ARG_mode].u_obj != mp_const_none) {
pin_cfg.mode = (drv_pin_mode_t)mp_obj_get_int(args[ARG_mode].u_obj);
if (pin_cfg.mode >= DRV_PIN_MODE_END) {
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("invalid pin mode: %d"), pin_cfg.mode);
}
}
/* Validate and set pull mode */
if (args[ARG_pull].u_obj != mp_const_none) {
pin_cfg.pull = (drv_pin_pull_type_t)mp_obj_get_int(args[ARG_pull].u_obj);
if (pin_cfg.pull >= DRV_PIN_PULL_END) {
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("invalid pull mode: %d"), pin_cfg.pull);
}
}
/* Validate and set drive strength */
if (args[ARG_drive].u_obj != mp_const_none) {
pin_cfg.drive = (drv_pin_drive_t)mp_obj_get_int(args[ARG_drive].u_obj);
if (pin_cfg.drive >= DRV_PIN_DRIVE_END) {
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("invalid drive strength settings: %d"), pin_cfg.drive);
}
}
/* Validate and set alternative function */
pin_cfg.af = args[ARG_alt].u_int;
int ret = drv_pin_config_set(&pin, &pin_cfg);
if (ret != 0) {
mp_raise_msg_varg(&mp_type_RuntimeError, MP_ERROR_TEXT("failed to set pin mode: %d"), ret);
}
/* Validate and set initial value IF MODE IS GPIO OUTPUT OR OD */
if ((pin_cfg.mode == DRV_PIN_MODE_OUTPUT_OD) || (pin_cfg.mode == DRV_PIN_MODE_OUTPUT_PP)) {
if (args[ARG_value].u_obj != mp_const_none) {
bool write_value = mp_obj_get_int(args[ARG_value].u_obj) ? true : false;
drv_pin_write(&pin, write_value);
}
}
return mp_const_none;
}
static void machine_pin_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
machine_pin_obj_t *self = MP_OBJ_TO_PTR(self_in);
drv_pin_t pin = {
.port = self->port,
.pin = self->pin,
};
/* Note: a common hardfault reason is a direct print call from Pin.cpu._ or Pin.board._,
* which is not initialized using a proper constructor. Currently it seems there's no way
* finding out whether this pin is initialized or not (every obj is a const ROM obj).
* WORKAROUND: Init the called pin (enable the PORT and GPIO clocks).
*/
drv_pin_init(&pin);
drv_pin_config_t pin_cfg;
drv_pin_config_get(&pin, &pin_cfg);
mp_printf(print, "Pin(Pin.cpu.%q, mode=Pin.", self->name);
qstr mode_qst;
switch (pin_cfg.mode) {
case DRV_PIN_MODE_INPUT:
mode_qst = MP_QSTR_IN;
break;
case DRV_PIN_MODE_OUTPUT_PP:
mode_qst = MP_QSTR_OUTPUT;
break;
case DRV_PIN_MODE_OUTPUT_OD:
mode_qst = MP_QSTR_OPEN_DRAIN;
break;
case DRV_PIN_MODE_AF_PP:
mode_qst = MP_QSTR_ALT;
break;
case DRV_PIN_MODE_AF_OD:
mode_qst = MP_QSTR_ALT_OPEN_DRAIN;
break;
case DRV_PIN_MODE_ANALOG:
default:
mode_qst = MP_QSTR_ANALOG;
break;
}
mp_printf(print, "%s", qstr_str(mode_qst));
qstr pull_qst;
switch (pin_cfg.pull) {
case DRV_PIN_PULL_UP:
pull_qst = MP_QSTR_PULL_UP;
break;
case DRV_PIN_PULL_DOWN:
pull_qst = MP_QSTR_PULL_DOWN;
break;
case DRV_PIN_PULL_NONE:
default:
pull_qst = MP_QSTR_PULL_NONE;
break;
}
mp_printf(print, " pull=Pin.%s", qstr_str(pull_qst));
qstr drive_qst;
switch (pin_cfg.drive) {
case DRV_PIN_DRIVE_HIGH:
drive_qst = MP_QSTR_DRIVE_HIGH;
break;
case DRV_PIN_DRIVE_LOW:
default:
drive_qst = MP_QSTR_DRIVE_LOW;
break;
}
mp_printf(print, " drive=Pin.%s", qstr_str(drive_qst));
/* AF */
mp_printf(print, " alt=%d", pin_cfg.af);
/* TODO: Add other attributes */
mp_printf(print, ")");
}
static mp_obj_t machine_pin_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 0, 1, false);
machine_pin_obj_t *self = MP_OBJ_TO_PTR(self_in);
if (n_args == 0) {
int read_val = mp_hal_pin_read(self);
/* TODO: Check negative read errors (does this even occur?). */
return MP_OBJ_NEW_SMALL_INT(read_val);
} else {
mp_hal_pin_write(self, mp_obj_is_true(args[0]));
return mp_const_none;
}
}
static mp_obj_t machine_pin_obj_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
return machine_pin_obj_init_helper(args[0], n_args - 1, args + 1, kw_args);
}
MP_DEFINE_CONST_FUN_OBJ_KW(machine_pin_init_obj, 1, machine_pin_obj_init);
static mp_obj_t machine_pin_value(size_t n_args, const mp_obj_t *args) {
return machine_pin_call(args[0], n_args - 1, 0, args + 1);
}
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_pin_value_obj, 1, 2, machine_pin_value);
static mp_obj_t machine_pin_high(mp_obj_t self_in) {
machine_pin_obj_t *self = MP_OBJ_TO_PTR(self_in);
mp_hal_pin_high(self);
return mp_const_none;
}
static MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_high_obj, machine_pin_high);
static mp_obj_t machine_pin_low(mp_obj_t self_in) {
machine_pin_obj_t *self = MP_OBJ_TO_PTR(self_in);
mp_hal_pin_low(self);
return mp_const_none;
}
static MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_low_obj, machine_pin_low);
static mp_uint_t machine_pin_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) {
machine_pin_obj_t *self = MP_OBJ_TO_PTR(self_in);
bool output_val = (int)arg ? true : false;
switch (request) {
case MP_PIN_READ:
return mp_hal_pin_read(self);
break;
case MP_PIN_WRITE:
mp_hal_pin_write(self, output_val);
break;
default:
return -1;
break;
}
return 0;
}
mp_obj_t mp_pin_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
mp_obj_t pin_obj = args[0];
const machine_pin_obj_t *pin;
if (mp_obj_is_type(pin_obj, &machine_pin_type)) {
pin = MP_OBJ_TO_PTR(pin_obj);
} else {
pin = mp_hal_pin_find_named_pin(&machine_pin_board_pins_locals_dict, pin_obj);
if (pin == NULL) {
pin = mp_hal_pin_find_named_pin(&machine_pin_cpu_pins_locals_dict, pin_obj);
}
if (pin == NULL) {
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("Pin(%s) doesn't exist"), mp_obj_str_get_str(pin_obj));
}
}
drv_pin_t drv_pin = {
.port = pin->port,
.pin = pin->pin,
};
/* TODO: check return value */
drv_pin_init(&drv_pin);
if (n_args > 1 || n_kw > 0) {
// pin mode given, so configure this GPIO
mp_map_t kw_args;
mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
machine_pin_obj_init_helper(pin, n_args - 1, args + 1, &kw_args);
}
return MP_OBJ_FROM_PTR(pin);
}
static const mp_pin_p_t machine_pin_pin_p = {
.ioctl = machine_pin_ioctl,
};
MP_DEFINE_CONST_OBJ_TYPE(
machine_pin_cpu_pins_obj_type,
MP_QSTR_cpu,
MP_TYPE_FLAG_NONE,
locals_dict, &machine_pin_cpu_pins_locals_dict
);
MP_DEFINE_CONST_OBJ_TYPE(
machine_pin_board_pins_obj_type,
MP_QSTR_board,
MP_TYPE_FLAG_NONE,
locals_dict, &machine_pin_board_pins_locals_dict
);
static const mp_rom_map_elem_t machine_pin_locals_dict_table[] = {
/* Instance methods */
{ MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_pin_init_obj) },
{ MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&machine_pin_value_obj) },
{ MP_ROM_QSTR(MP_QSTR_high), MP_ROM_PTR(&machine_pin_high_obj) },
{ MP_ROM_QSTR(MP_QSTR_low), MP_ROM_PTR(&machine_pin_low_obj) },
{ MP_ROM_QSTR(MP_QSTR_on), MP_ROM_PTR(&machine_pin_high_obj) },
{ MP_ROM_QSTR(MP_QSTR_off), MP_ROM_PTR(&machine_pin_low_obj) },
// class attributes
{ MP_ROM_QSTR(MP_QSTR_board), MP_ROM_PTR(&machine_pin_board_pins_obj_type) },
{ MP_ROM_QSTR(MP_QSTR_cpu), MP_ROM_PTR(&machine_pin_cpu_pins_obj_type) },
/* Class constants */
{ MP_ROM_QSTR(MP_QSTR_IN), MP_ROM_INT(MP_HAL_PIN_MODE_INPUT) },
{ MP_ROM_QSTR(MP_QSTR_OUT), MP_ROM_INT(MP_HAL_PIN_MODE_OUTPUT) },
{ MP_ROM_QSTR(MP_QSTR_OPEN_DRAIN), MP_ROM_INT(MP_HAL_PIN_MODE_OPEN_DRAIN) },
{ MP_ROM_QSTR(MP_QSTR_ALT), MP_ROM_INT(MP_HAL_PIN_MODE_ALT) },
{ MP_ROM_QSTR(MP_QSTR_ALT_OPEN_DRAIN), MP_ROM_INT(MP_HAL_PIN_MODE_ALT_OPEN_DRAIN) },
{ MP_ROM_QSTR(MP_QSTR_ANALOG), MP_ROM_INT(MP_HAL_PIN_MODE_ANALOG) },
{ MP_ROM_QSTR(MP_QSTR_PULL_NONE), MP_ROM_INT(MP_HAL_PIN_PULL_NONE) },
{ MP_ROM_QSTR(MP_QSTR_PULL_UP), MP_ROM_INT(MP_HAL_PIN_PULL_UP) },
{ MP_ROM_QSTR(MP_QSTR_PULL_DOWN), MP_ROM_INT(MP_HAL_PIN_PULL_DOWN) },
{ MP_ROM_QSTR(MP_QSTR_DRIVE_HIGH), MP_ROM_INT(MP_HAL_PIN_DRIVE_0) },
{ MP_ROM_QSTR(MP_QSTR_DRIVE_LOW), MP_ROM_INT(MP_HAL_PIN_DRIVE_1) },
};
static MP_DEFINE_CONST_DICT(machine_pin_locals_dict, machine_pin_locals_dict_table);
MP_DEFINE_CONST_OBJ_TYPE(
machine_pin_type,
MP_QSTR_Pin,
MP_TYPE_FLAG_NONE,
make_new, mp_pin_make_new,
locals_dict, &machine_pin_locals_dict,
print, machine_pin_print,
call, machine_pin_call,
protocol, &machine_pin_pin_p
);

Wyświetl plik

@ -0,0 +1,71 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2013-2017 Damien P. George
* Copyright (c) 2024 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef MP_PORT_MCX_MACHINE_PIN_H
#define MP_PORT_MCX_MACHINE_PIN_H
#include "shared/runtime/mpirq.h"
#include "py/obj.h"
#include "machine_pin_defs.h"
typedef struct {
uint8_t af_id; /* AF0 - AF15 */
machine_pin_af_type_t af_type;
uint8_t af_instance_id;
machine_pin_af_attr_t af_attribute; /* Identify what signal this is. */
} machine_pin_af_t;
typedef struct {
uint8_t adc_id;
char adc_side;
uint8_t adc_channel;
} machine_pin_adc_t;
typedef struct {
mp_obj_base_t base;
qstr name;
uint8_t port;
uint8_t pin;
uint8_t af_count;
const machine_pin_af_t *af;
const machine_pin_adc_t *adc;
} machine_pin_obj_t;
#include "genhdr/pins.h"
extern const mp_obj_type_t machine_pin_board_pins_obj_type;
extern const mp_obj_type_t machine_pin_cpu_pins_obj_type;
extern const mp_obj_dict_t machine_pin_cpu_pins_locals_dict;
extern const mp_obj_dict_t machine_pin_board_pins_locals_dict;
#endif

Wyświetl plik

@ -0,0 +1,106 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2024 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef MP_PORT_MCX_MACHINE_PIN_DEFS_H
#define MP_PORT_MCX_MACHINE_PIN_DEFS_H
typedef enum {
MACHINE_PIN_AF_TYPE_GPIO = 0U, /* GPIO */
MACHINE_PIN_AF_TYPE_LPFC, /* LP_FLEXCOMM */
MACHINE_PIN_AF_TYPE_UART, /* LPUART */
MACHINE_PIN_AF_TYPE_CT32, /* CTIMER */
} machine_pin_af_type_t;
typedef enum {
MACHINE_PIN_AF_ATTR_GPIO_P0 = 0U,
MACHINE_PIN_AF_ATTR_GPIO_P1,
MACHINE_PIN_AF_ATTR_GPIO_P2,
MACHINE_PIN_AF_ATTR_GPIO_P3,
MACHINE_PIN_AF_ATTR_GPIO_P4,
MACHINE_PIN_AF_ATTR_GPIO_P5,
MACHINE_PIN_AF_ATTR_GPIO_P6,
MACHINE_PIN_AF_ATTR_GPIO_P7,
MACHINE_PIN_AF_ATTR_GPIO_P8,
MACHINE_PIN_AF_ATTR_GPIO_P9,
MACHINE_PIN_AF_ATTR_GPIO_P10,
MACHINE_PIN_AF_ATTR_GPIO_P11,
MACHINE_PIN_AF_ATTR_GPIO_P12,
MACHINE_PIN_AF_ATTR_GPIO_P13,
MACHINE_PIN_AF_ATTR_GPIO_P14,
MACHINE_PIN_AF_ATTR_GPIO_P15,
MACHINE_PIN_AF_ATTR_GPIO_P16,
MACHINE_PIN_AF_ATTR_GPIO_P17,
MACHINE_PIN_AF_ATTR_GPIO_P18,
MACHINE_PIN_AF_ATTR_GPIO_P19,
MACHINE_PIN_AF_ATTR_GPIO_P20,
MACHINE_PIN_AF_ATTR_GPIO_P21,
MACHINE_PIN_AF_ATTR_GPIO_P22,
MACHINE_PIN_AF_ATTR_GPIO_P23,
MACHINE_PIN_AF_ATTR_GPIO_P24,
MACHINE_PIN_AF_ATTR_GPIO_P25,
MACHINE_PIN_AF_ATTR_GPIO_P26,
MACHINE_PIN_AF_ATTR_GPIO_P27,
MACHINE_PIN_AF_ATTR_GPIO_P28,
MACHINE_PIN_AF_ATTR_GPIO_P29,
MACHINE_PIN_AF_ATTR_GPIO_P30,
MACHINE_PIN_AF_ATTR_GPIO_P31,
MACHINE_PIN_AF_ATTR_LPFC_P0 = 0U,
MACHINE_PIN_AF_ATTR_LPFC_P1,
MACHINE_PIN_AF_ATTR_LPFC_P2,
MACHINE_PIN_AF_ATTR_LPFC_P3,
MACHINE_PIN_AF_ATTR_LPFC_P4,
MACHINE_PIN_AF_ATTR_LPFC_P5,
MACHINE_PIN_AF_ATTR_LPFC_P6,
MACHINE_PIN_AF_ATTR_CT32_MAT0 = 0U,
MACHINE_PIN_AF_ATTR_CT32_MAT1,
MACHINE_PIN_AF_ATTR_CT32_MAT2,
MACHINE_PIN_AF_ATTR_CT32_MAT3,
MACHINE_PIN_AF_ATTR_CT32_INP0 = (0x80U | 0U), /* Special mark */
MACHINE_PIN_AF_ATTR_CT32_INP1 = (0x80U | 1U),
MACHINE_PIN_AF_ATTR_CT32_INP2 = (0x80U | 2U),
MACHINE_PIN_AF_ATTR_CT32_INP3 = (0x80U | 3U),
MACHINE_PIN_AF_ATTR_CT32_INP4 = (0x80U | 4U),
MACHINE_PIN_AF_ATTR_CT32_INP5 = (0x80U | 5U),
MACHINE_PIN_AF_ATTR_CT32_INP6 = (0x80U | 6U),
MACHINE_PIN_AF_ATTR_CT32_INP7 = (0x80U | 7U),
MACHINE_PIN_AF_ATTR_CT32_INP8 = (0x80U | 8U),
MACHINE_PIN_AF_ATTR_CT32_INP9 = (0x80U | 9U),
MACHINE_PIN_AF_ATTR_CT32_INP10 = (0x80U | 10U),
MACHINE_PIN_AF_ATTR_CT32_INP11 = (0x80U | 11U),
MACHINE_PIN_AF_ATTR_CT32_INP12 = (0x80U | 12U),
MACHINE_PIN_AF_ATTR_CT32_INP13 = (0x80U | 13U),
MACHINE_PIN_AF_ATTR_CT32_INP14 = (0x80U | 14U),
MACHINE_PIN_AF_ATTR_CT32_INP15 = (0x80U | 15U),
MACHINE_PIN_AF_ATTR_CT32_INP16 = (0x80U | 16U),
MACHINE_PIN_AF_ATTR_CT32_INP17 = (0x80U | 17U),
MACHINE_PIN_AF_ATTR_CT32_INP18 = (0x80U | 18U),
MACHINE_PIN_AF_ATTR_CT32_INP19 = (0x80U | 19U),
} machine_pin_af_attr_t;
#endif

Wyświetl plik

@ -0,0 +1,180 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2016 Damien P. George
* Copyright (c) 2024 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
// This file is never compiled standalone, it's included directly from
// extmod/machine_pwm.c via MICROPY_PY_MACHINE_PWM_INCLUDEFILE.
#include "py/mphal.h"
#include "py/mperrno.h"
#include "drv_pwm.h"
typedef struct _machine_pwm_obj_t {
mp_obj_base_t base;
uint8_t instance;
uint8_t channel;
drv_pwm_t drv;
} machine_pwm_obj_t;
static void mp_machine_pwm_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
machine_pwm_obj_t *self = MP_OBJ_TO_PTR(self_in);
uint32_t freq;
uint16_t duty;
drv_pwm_freq_get(&self->drv, &freq);
drv_pwm_duty_get(&self->drv, &duty);
uint32_t duty_ns = (uint64_t)duty * 1000000000 / 65536 / freq;
mp_printf(print, "PWM(%d, ch=%d, ", self->instance, self->channel);
mp_printf(print, "freq=%d, duty_u16=%d, duty_ns=%d", freq, duty, duty_ns);
mp_printf(print, ")");
}
static mp_obj_t mp_machine_pwm_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
machine_pwm_obj_t *self = mp_obj_malloc(machine_pwm_obj_t, &machine_pwm_type);
mp_map_t kw_args;
mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
mp_machine_pwm_init_helper(self, n_args, args, &kw_args);
return MP_OBJ_FROM_PTR(self);
}
static void mp_machine_pwm_init_helper(machine_pwm_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
/* Differences from RA port: freq is a kw_arg (compatible with machine.PWM class). */
enum { ARG_pin, ARG_freq, ARG_duty_u16, ARG_duty_ns, ARG_invert };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_pin, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} },
{ MP_QSTR_freq, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
{ MP_QSTR_duty_u16, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
{ MP_QSTR_duty_ns, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
{ MP_QSTR_invert, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
if (args[ARG_pin].u_obj == mp_const_none) {
mp_raise_ValueError(MP_ERROR_TEXT("pin does not exists."));
} else {
mp_hal_pin_obj_t pin = args[ARG_pin].u_obj;
const machine_pin_af_t *af = mp_hal_pin_find_pwm(pin);
if (af == NULL) {
mp_raise_ValueError(MP_ERROR_TEXT("pin is not PWM capable."));
}
self->instance = af->af_instance_id;
self->channel = af->af_attribute;
mp_hal_pin_af(pin, af->af_id);
}
if (args[ARG_freq].u_int == -1) {
mp_raise_ValueError(MP_ERROR_TEXT("freq is not provided."));
}
bool inverted = args[ARG_invert].u_int ? true : false;
int ret = drv_pwm_init(&self->drv, self->instance, self->channel, args[ARG_freq].u_int, inverted);
if (ret < 0) {
if (ret == -EBUSY) {
/* No free channel for the PWM instance */
mp_raise_ValueError(MP_ERROR_TEXT("channel is not available"));
} else {
mp_raise_ValueError(MP_ERROR_TEXT("channel initialization failed"));
}
}
if ((args[ARG_duty_u16].u_int == -1) && (args[ARG_duty_ns].u_int == -1)) {
mp_raise_ValueError(MP_ERROR_TEXT("one of the duty options must be provided"));
}
if ((args[ARG_duty_u16].u_int != -1) && (args[ARG_duty_ns].u_int != -1)) {
mp_raise_ValueError(MP_ERROR_TEXT("only one of the duty options can be provided"));
}
if (args[ARG_duty_u16].u_int != -1) {
drv_pwm_duty_set(&self->drv, args[ARG_duty_u16].u_int);
}
if (args[ARG_duty_ns].u_int != -1) {
uint16_t duty_u16 = (args[ARG_duty_ns].u_int * 65536 * args[ARG_freq].u_int) / 1000000000;
drv_pwm_duty_set(&self->drv, duty_u16);
}
drv_pwm_start(&self->drv);
}
static void mp_machine_pwm_deinit(machine_pwm_obj_t *self) {
drv_pwm_deinit(&self->drv);
/* TODO: Do we need to configure the IO to its previous state? */
}
static mp_obj_t mp_machine_pwm_freq_get(machine_pwm_obj_t *self) {
uint32_t freq;
drv_pwm_freq_get(&self->drv, &freq);
return MP_OBJ_NEW_SMALL_INT(freq);
}
static void mp_machine_pwm_freq_set(machine_pwm_obj_t *self, mp_int_t freq) {
drv_pwm_freq_set(&self->drv, freq);
}
static mp_obj_t mp_machine_pwm_duty_get_u16(machine_pwm_obj_t *self) {
uint16_t duty_u16;
drv_pwm_duty_get(&self->drv, &duty_u16);
return MP_OBJ_NEW_SMALL_INT(duty_u16);
}
static void mp_machine_pwm_duty_set_u16(machine_pwm_obj_t *self, mp_int_t duty_u16) {
drv_pwm_duty_set(&self->drv, duty_u16);
}
static mp_obj_t mp_machine_pwm_duty_get_ns(machine_pwm_obj_t *self) {
return MP_OBJ_NEW_SMALL_INT(0);
}
static void mp_machine_pwm_duty_set_ns(machine_pwm_obj_t *self, mp_int_t duty_ns) {
uint32_t freq;
drv_pwm_freq_get(&self->drv, &freq);
uint64_t duty = ((uint64_t)duty_ns * freq * 65536) / 1000000000;
drv_pwm_duty_set(&self->drv, duty);
}

Wyświetl plik

@ -0,0 +1,185 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2020-2021 Damien P. George
* Copyright (c) 2024 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "py/runtime.h"
#include "py/mphal.h"
#include "py/mperrno.h"
#include "extmod/modmachine.h"
#include "drv_spi.h"
typedef struct _machine_spi_obj_t {
mp_obj_base_t base;
uint8_t id;
uint32_t baudrate;
drv_spi_t drv;
} machine_spi_obj_t;
static void machine_spi_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
machine_spi_obj_t *self = MP_OBJ_TO_PTR(self_in);
mp_printf(print, "SPI(%d, ", self->id);
mp_printf(print, "baudrate=%d", self->baudrate);
mp_printf(print, ")");
}
static void machine_spi_init_helper(machine_spi_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_baudrate, ARG_polarity, ARG_phase, ARG_bits, ARG_firstbit, ARG_sck, ARG_mosi, ARG_miso };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_baudrate, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1000000} },
{ MP_QSTR_polarity, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_phase, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} },
{ MP_QSTR_firstbit, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = MICROPY_PY_MACHINE_SPI_MSB} },
{ MP_QSTR_sck, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} },
{ MP_QSTR_mosi, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} },
{ MP_QSTR_miso, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
if (args[ARG_sck].u_obj == mp_const_none) {
/* TODO: Prepare a default pin for SCK */
} else {
mp_hal_pin_obj_t pin = args[ARG_sck].u_obj;
/* TODO: Non LP-Flexcomm pinmap for future A series */
const machine_pin_af_t *af = mp_hal_pin_find_af(pin, MACHINE_PIN_AF_TYPE_LPFC, self->id, MACHINE_PIN_AF_ATTR_LPFC_P1);
if (af == NULL) {
mp_raise_ValueError(MP_ERROR_TEXT("unsupported SCK af"));
}
mp_hal_pin_af(pin, af->af_id);
}
if (args[ARG_mosi].u_obj == mp_const_none) {
/* TODO: Prepare a default pin for MOSI */
} else {
mp_hal_pin_obj_t pin = args[ARG_mosi].u_obj;
/* TODO: Non LP-Flexcomm pinmap for future A series */
const machine_pin_af_t *af = mp_hal_pin_find_af(pin, MACHINE_PIN_AF_TYPE_LPFC, self->id, MACHINE_PIN_AF_ATTR_LPFC_P0);
if (af == NULL) {
mp_raise_ValueError(MP_ERROR_TEXT("unsupported MOSI af"));
}
mp_hal_pin_af(pin, af->af_id);
}
if (args[ARG_miso].u_obj == mp_const_none) {
/* TODO: Prepare a default pin for MISO */
} else {
mp_hal_pin_obj_t pin = args[ARG_miso].u_obj;
/* TODO: Non LP-Flexcomm pinmap for future A series */
const machine_pin_af_t *af = mp_hal_pin_find_af(pin, MACHINE_PIN_AF_TYPE_LPFC, self->id, MACHINE_PIN_AF_ATTR_LPFC_P2);
if (af == NULL) {
mp_raise_ValueError(MP_ERROR_TEXT("unsupported MISO af"));
}
mp_hal_pin_af(pin, af->af_id);
}
/* TODO: Initialize SPI peripheral */
drv_spi_config_t spi_cfg;
self->baudrate = args[ARG_baudrate].u_int;
spi_cfg.frequency = self->baudrate;
spi_cfg.cpol = args[ARG_polarity].u_int;
spi_cfg.cpha = args[ARG_phase].u_int;
spi_cfg.frame_size = args[ARG_bits].u_int;
if (args[ARG_firstbit].u_int == MICROPY_PY_MACHINE_SPI_MSB) {
spi_cfg.lsbfirst = false;
} else {
spi_cfg.lsbfirst = true;
}
int ret = drv_spi_init(&self->drv, self->id, &spi_cfg);
if (ret < 0) {
if (ret == -ENOENT) {
mp_raise_ValueError(MP_ERROR_TEXT("SPI not found."));
} else {
mp_raise_msg_varg(&mp_type_RuntimeError, MP_ERROR_TEXT("failed to init SPI instance"));
}
}
}
mp_obj_t machine_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
machine_spi_obj_t *self = mp_obj_malloc(machine_spi_obj_t, &machine_spi_type);
self->id = mp_obj_get_int(args[0]);
/* Initialize SPI instance only if kw arguments are given. */
if (n_kw > 0) {
mp_map_t kw_args;
mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
machine_spi_init_helper(self, n_args - 1, args + 1, &kw_args);
}
return self;
}
static void machine_spi_init(mp_obj_base_t *self_in, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
machine_spi_obj_t *self = (machine_spi_obj_t *)self_in;
/* Takes same parameters as constructor. */
machine_spi_init_helper(self, n_args, pos_args, kw_args);
}
static void machine_spi_transfer(mp_obj_base_t *self_in, size_t len, const uint8_t *src, uint8_t *dest) {
machine_spi_obj_t *self = (machine_spi_obj_t *)self_in;
drv_spi_transfer_t xfer = {
.tx_data = src,
.rx_data = dest,
.len = len,
};
drv_spi_transfer(&self->drv, &xfer);
}
static const mp_machine_spi_p_t machine_spi_p = {
.init = machine_spi_init,
.transfer = machine_spi_transfer,
};
MP_DEFINE_CONST_OBJ_TYPE(
machine_spi_type,
MP_QSTR_SPI,
MP_TYPE_FLAG_NONE,
make_new, machine_spi_make_new,
print, machine_spi_print,
protocol, &machine_spi_p,
locals_dict, &mp_machine_spi_locals_dict
);

Wyświetl plik

@ -0,0 +1,320 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2013-2017 Damien P. George
* Copyright (c) 2024 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
// This file is never compiled standalone, it's included directly from
// extmod/machine_uart.c via MICROPY_PY_MACHINE_UART_INCLUDEFILE.
#include "py/ringbuf.h"
#include "drv_uart.h"
#define MACHINE_UART_FC_FLAG_RTS 1U
#define MACHINE_UART_FC_FLAG_CTS 2U
#define MICROPY_PY_MACHINE_UART_CLASS_CONSTANTS \
{ MP_ROM_QSTR(MP_QSTR_RTS), MP_ROM_INT(MACHINE_UART_FC_FLAG_RTS) }, \
{ MP_ROM_QSTR(MP_QSTR_CTS), MP_ROM_INT(MACHINE_UART_FC_FLAG_CTS) }, \
struct _machine_uart_obj_t {
mp_obj_base_t base;
uint8_t id;
mp_uint_t timeout;
drv_uart_t drv;
ringbuf_t rx_buf;
};
static void mp_machine_uart_sendbreak(machine_uart_obj_t *self) {
drv_uart_send_break(&self->drv);
}
static mp_int_t mp_machine_uart_any(machine_uart_obj_t *self) {
return ringbuf_avail(&self->rx_buf);
}
static bool mp_machine_uart_txdone(machine_uart_obj_t *self) {
return true;
}
static mp_int_t mp_machine_uart_readchar(machine_uart_obj_t *self) {
uint8_t ch = 0U;
drv_uart_read(&self->drv, &ch, 1U, self->timeout);
return ch;
}
static mp_uint_t mp_machine_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) {
machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
uint8_t *rx_buf = buf_in;
mp_uint_t buf_avail = ringbuf_avail(&self->rx_buf);
if (buf_avail > size) {
buf_avail = size;
}
ringbuf_get_bytes(&self->rx_buf, rx_buf, buf_avail);
if (buf_avail < size) {
mp_uint_t bytes_left = size - buf_avail;
mp_uint_t time_start = mp_hal_ticks_ms();
while (bytes_left) {
if (ringbuf_avail(&self->rx_buf)) {
rx_buf[buf_avail++] = ringbuf_get(&self->rx_buf);
bytes_left--;
}
if (self->timeout && ((mp_hal_ticks_ms() - time_start) > self->timeout)) {
*errcode = MP_EAGAIN;
break;
}
MICROPY_EVENT_POLL_HOOK
}
}
return buf_avail;
}
static void mp_machine_uart_writechar(machine_uart_obj_t *self, uint16_t data) {
uint8_t data_buf[1] = { data };
/* TODO: Use async write? */
/* TODO: Check return values */
drv_uart_write(&self->drv, data_buf, 1U, self->timeout);
}
static mp_uint_t mp_machine_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) {
machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
/* TODO: Use async write? */
/* TODO: Check return values */
drv_uart_write(&self->drv, buf_in, size, self->timeout);
return 0;
}
static mp_uint_t mp_machine_uart_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) {
mp_uint_t ret = 0;
machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
switch (request) {
case MP_STREAM_POLL:
if ((arg & MP_STREAM_POLL_RD) && ringbuf_avail(&self->rx_buf)) {
ret |= MP_STREAM_POLL_RD;
}
break;
case MP_STREAM_FLUSH:
/* TX is blocking, so no flush is needed. */
break;
default:
ret = MP_STREAM_ERROR;
break;
}
return ret;
}
static void mp_machine_uart_async_rx_callback(void *uart, void *param, uint8_t len) {
machine_uart_obj_t *self = param;
uint8_t ch;
for (uint8_t i = 0; i < len; i++) {
if (drv_uart_async_read(uart, &ch, 1) == 1) {
ringbuf_put(&self->rx_buf, ch);
}
}
}
static void mp_machine_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
mp_printf(print, "UART(%d)", self->id);
}
static void mp_machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_baudrate, ARG_bits, ARG_parity, ARG_stop,
ARG_tx, ARG_rx, ARG_cts, ARG_rts, ARG_flow,
ARG_timeout, ARG_timeout_char, ARG_txbuf, ARG_rxbuf };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_baudrate, MP_ARG_INT, {.u_int = 9600U} },
{ MP_QSTR_bits, MP_ARG_INT, {.u_int = 8} },
{ MP_QSTR_parity, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} },
{ MP_QSTR_stop, MP_ARG_INT, {.u_int = 1} },
{ MP_QSTR_tx, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} },
{ MP_QSTR_rx, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} },
{ MP_QSTR_cts, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} },
{ MP_QSTR_rts, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} },
{ MP_QSTR_flow, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_timeout_char, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_txbuf, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 32} },
{ MP_QSTR_rxbuf, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 32} },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
drv_uart_config_t uart_cfg;
uart_cfg.baud_rate = args[ARG_baudrate].u_int;
switch (args[ARG_bits].u_int) {
case 7:
uart_cfg.data_bits = DRV_Uart7DataBits;
break;
case 8:
uart_cfg.data_bits = DRV_Uart8DataBits;
break;
default:
mp_raise_ValueError(MP_ERROR_TEXT("unsupported combination of bits and parity"));
break;
}
if (args[ARG_parity].u_obj == mp_const_none) {
uart_cfg.parity = DRV_UartNoParity;
} else {
if (args[ARG_parity].u_int) {
uart_cfg.parity = DRV_UartOddParity;
} else {
uart_cfg.parity = DRV_UartEvenParity;
}
}
switch (args[ARG_stop].u_int) {
case 1:
uart_cfg.stop_bits = DRV_Uart1StopBits;
break;
case 2:
uart_cfg.stop_bits = DRV_Uart2StopBits;
break;
default:
mp_raise_ValueError(MP_ERROR_TEXT("unsupportd stop bit"));
break;
}
switch (args[ARG_flow].u_int) {
case (MACHINE_UART_FC_FLAG_RTS):
uart_cfg.flow_control = DRV_UartRtsFlowControl;
break;
case (MACHINE_UART_FC_FLAG_CTS):
uart_cfg.flow_control = DRV_UartCtsFlowControl;
break;
case (MACHINE_UART_FC_FLAG_RTS | MACHINE_UART_FC_FLAG_CTS):
uart_cfg.flow_control = DRV_UartCtsRtsFlowControl;
break;
default:
uart_cfg.flow_control = DRV_UartNoFlowControl;
break;
}
if (args[ARG_tx].u_obj == mp_const_none) {
/* TODO: Prepare a default pin for TX */
} else {
/* TODO: Non LP-Flexcomm pinmap for future A series */
mp_hal_pin_obj_t pin = args[ARG_tx].u_obj;
const machine_pin_af_t *af = mp_hal_pin_find_af(pin, MACHINE_PIN_AF_TYPE_LPFC, self->id, MACHINE_PIN_AF_ATTR_LPFC_P1);
if (af == NULL) {
af = mp_hal_pin_find_af(pin, MACHINE_PIN_AF_TYPE_LPFC, self->id, MACHINE_PIN_AF_ATTR_LPFC_P2);
if (af == NULL) {
mp_raise_ValueError(MP_ERROR_TEXT("unsupported TX AF"));
}
/* TODO: Validate if both TX and RX are I2C-remapped mode. */
uart_cfg.i2c_shared = true;
}
mp_hal_pin_af(pin, af->af_id);
}
uart_cfg.i2c_shared = false;
if (args[ARG_rx].u_obj == mp_const_none) {
/* TODO: Prepare a default pin for RX */
} else {
/* TODO: Non LP-Flexcomm pinmap for future A series */
mp_hal_pin_obj_t pin = args[ARG_rx].u_obj;
const machine_pin_af_t *af = mp_hal_pin_find_af(pin, MACHINE_PIN_AF_TYPE_LPFC, self->id, MACHINE_PIN_AF_ATTR_LPFC_P0);
if (af == NULL) {
af = mp_hal_pin_find_af(pin, MACHINE_PIN_AF_TYPE_LPFC, self->id, MACHINE_PIN_AF_ATTR_LPFC_P3);
if (af == NULL) {
mp_raise_ValueError(MP_ERROR_TEXT("unsupported RX AF"));
}
/* TODO: Validate if both TX and RX are I2C-remapped mode. */
uart_cfg.i2c_shared = true;
}
mp_hal_pin_af(pin, af->af_id);
}
self->timeout = args[ARG_timeout].u_int;
ringbuf_alloc(&self->rx_buf, args[ARG_rxbuf].u_int + 1);
drv_uart_init(&self->drv, self->id, &uart_cfg);
drv_uart_async_start(&self->drv, mp_machine_uart_async_rx_callback, self);
}
static mp_obj_t mp_machine_uart_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
if (!mp_obj_is_int(args[0])) {
mp_raise_ValueError(MP_ERROR_TEXT("unsupported UART id."));
return mp_const_none;
}
machine_uart_obj_t *self = mp_obj_malloc(machine_uart_obj_t, &machine_uart_type);
self->id = mp_obj_get_int(args[0]);
mp_map_t kw_args;
mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
mp_machine_uart_init_helper(self, n_args - 1, args + 1, &kw_args);
return MP_OBJ_FROM_PTR(self);
}
static void mp_machine_uart_deinit(machine_uart_obj_t *self) {
drv_uart_async_cancel(&self->drv);
drv_uart_deinit(&self->drv);
}

184
ports/mcx/main.c 100644
Wyświetl plik

@ -0,0 +1,184 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2013-2017 Damien P. George
* Copyright (c) 2024 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "py/builtin.h"
#include "py/compile.h"
#include "py/gc.h"
#include "py/runtime.h"
#include "py/repl.h"
#include "py/stackctrl.h"
#include "py/mperrno.h"
#include "shared/readline/readline.h"
#include "shared/runtime/gchelper.h"
#include "shared/runtime/pyexec.h"
#include "extmod/vfs.h"
#include "tusb.h"
#include "drv_uart.h"
#include "pendsv.h"
#include "board.h"
static drv_uart_t s_stdio_uart_obj;
#if MICROPY_HW_ENABLE_USBDEV
static inline void board_usb_irq_handler(void *param) {
uint8_t rhport = (uint8_t)((int)param & 0xFFU);
tud_int_handler(rhport);
/* TODO: Use sched. */
tud_task();
__SEV();
}
#endif
#if MICROPY_ENABLE_COMPILER
void do_str(const char *src, mp_parse_input_kind_t input_kind) {
nlr_buf_t nlr;
if (nlr_push(&nlr) == 0) {
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
qstr source_name = lex->source_name;
mp_parse_tree_t parse_tree = mp_parse(lex, input_kind);
mp_obj_t module_fun = mp_compile(&parse_tree, source_name, true);
mp_call_function_0(module_fun);
nlr_pop();
} else {
// uncaught exception
mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val);
}
}
#endif
extern uint32_t __StackTop, __StackLimit, __HeapBase, __HeapLimit;
int main(int argc, char **argv) {
MCX_BoardEarlyInit();
#ifdef MICROPY_HW_ENABLE_USBDEV
MCX_BoardConfigureUSBClock(MICROPY_HW_USBDEV);
MCX_BoardConfigureUSBPHY(MICROPY_HW_USBDEV);
MCX_BoardConfigureUSBISR(MICROPY_HW_USBDEV, board_usb_irq_handler, (void *)MICROPY_HW_USBDEV);
tusb_init();
#endif
soft_reset:
mp_stack_set_top(&__StackTop);
mp_stack_set_limit((char *)&__StackTop - (char *)&__StackLimit - 1024);
gc_init((void *)&__HeapBase, (void *)&__HeapLimit);
mp_hal_init();
pendsv_init();
#if defined(MICROPY_HW_UART_REPL)
MP_STATE_PORT(stdio_uart) = &s_stdio_uart_obj;
drv_uart_config_t uart_cfg = {
.baud_rate = 115200,
.data_bits = DRV_Uart8DataBits,
.stop_bits = DRV_Uart1StopBits,
.parity = DRV_UartNoParity,
};
drv_uart_init(&s_stdio_uart_obj, MICROPY_HW_UART_REPL, &uart_cfg);
mp_hal_stdio_init();
#endif
mp_init();
readline_init0();
/* Exec boot script to set up internal flash */
pyexec_frozen_module("_boot.py", false);
/* Execute start-up script. */
if (pyexec_file_if_exists("boot.py") == PYEXEC_FORCED_EXIT) {
goto soft_reset_exit;
}
if (pyexec_file_if_exists("main.py") == PYEXEC_FORCED_EXIT) {
goto soft_reset_exit;
}
#if MICROPY_ENABLE_COMPILER
// Main script is finished, so now go into REPL mode.
// The REPL mode can change, or it can request a soft reset.
for (;;) {
if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) {
if (pyexec_raw_repl() != 0) {
break;
}
} else {
if (pyexec_friendly_repl() != 0) {
break;
}
}
}
#endif
soft_reset_exit:
mp_printf(&mp_plat_print, "MPY: soft reboot\n");
drv_uart_deinit(&s_stdio_uart_obj);
gc_sweep_all();
mp_deinit();
goto soft_reset;
}
void gc_collect(void) {
gc_collect_start();
gc_helper_collect_regs_and_stack();
gc_collect_end();
gc_dump_info(&mp_plat_print);
}
void NORETURN __fatal_error(const char *msg) {
while (1) {
;
}
}
void nlr_jump_fail(void *val) {
printf("FATAL: uncaught exception %p\n", val);
mp_obj_print_exception(&mp_plat_print, MP_OBJ_FROM_PTR(val));
__fatal_error("");
}
#ifndef NDEBUG
void MP_WEAK __assert_func(const char *file, int line, const char *func, const char *expr) {
printf("Assertion '%s' failed, at file %s:%d\n", expr, file, line);
__fatal_error("Assertion failed");
}
#endif

31
ports/mcx/mcx.mk 100644
Wyświetl plik

@ -0,0 +1,31 @@
ifeq ($(TARGET_MCU_SERIES), $(filter $(TARGET_MCU_SERIES), MCXN947 MCXN547 MCXN946 MCXN546))
TARGET_MCU_HAS_LPFLEXCOMM = 1
TARGET_MCU_HAS_FLEXSPI = 1
TARGET_MCU_HAS_OSTIMER = 1
TARGET_MCU_HAS_USB_HS = 1
endif
# Generic CPU features
ifeq ($(TARGET_MCU_CORE_HAS_DSP), 1)
TARGET_CFLAGS_CPU += -mcpu=cortex-m33
else
TARGET_CFLAGS_CPU += -mcpu=cortex-m33+nodsp
endif
ifeq ($(TARGET_MCU_CORE_HAS_FPU), 1)
TARGET_CFLAGS_CPU += -mfloat-abi=hard -mfpu=fpv5-sp-d16
else
TARGET_CFLAGS_CPU += -mfloat-abi=soft
endif
TARGET_CFLAGS_CPU += -mthumb
# Common macros
ifeq ($(TARGET_MCU_CORE),) # Single core MCU
TARGET_MCU_VARIANT = $(TARGET_MCU_SERIES)
TARGET_MCU_DEF = CPU_$(TARGET_MCU_PART)
else # Multi core MCU
TARGET_MCU_VARIANT = $(TARGET_MCU_SERIES)_$(TARGET_MCU_CORE)
TARGET_MCU_DEF = CPU_$(TARGET_MCU_PART)_$(TARGET_MCU_CORE)
endif

Wyświetl plik

@ -0,0 +1,230 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2024 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "py/runtime.h"
#include "extmod/vfs.h"
#include "drv_iflash.h"
#include "modmcx.h"
typedef enum {
MCX_FLASH_TYPE_INTERNAL,
#if MICROPY_HW_ENABLE_EFS
MCX_FLASH_TYPE_EXTERNAL,
#endif
MCX_FLASH_TYPE_END,
} mcx_flash_type_t;
typedef struct mcx_flash_obj_type {
mp_obj_base_t base;
mcx_flash_type_t type;
drv_iflash_t iflash;
} mcx_flash_obj_t;
static mp_obj_t mcx_flash_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 0, 1, true);
mcx_flash_obj_t *self = mp_obj_malloc(mcx_flash_obj_t, &mcx_flash_type);
if (n_args > 1) {
self->type = mp_obj_get_int(args[1]);
}
if (self->type >= MCX_FLASH_TYPE_END) {
self->type = MCX_FLASH_TYPE_INTERNAL;
}
if (self->type == MCX_FLASH_TYPE_INTERNAL) {
if (drv_iflash_init(&self->iflash) < 0) {
mp_raise_msg_varg(&mp_type_RuntimeError, MP_ERROR_TEXT("Failed to initialize Flash API"));
}
}
return MP_OBJ_FROM_PTR(self);
}
static void mcx_flash_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
mcx_flash_obj_t *self = MP_OBJ_TO_PTR(self_in);
qstr type_qst;
switch (self->type) {
#if MICROPY_HW_ENABLE_EFS
case MCX_FLASH_TYPE_EXTERNAL:
type_qst = MP_QSTR_EXTERNAL;
break;
#endif
default:
case MCX_FLASH_TYPE_INTERNAL:
type_qst = MP_QSTR_INTERNAL;
break;
}
mp_printf(print, "Flash(Flash.%s)", qstr_str(type_qst));
}
static mp_obj_t mcx_flash_readblocks(size_t n_args, const mp_obj_t *args) {
mcx_flash_obj_t *self = MP_OBJ_TO_PTR(args[0]);
uint32_t block_id = mp_obj_get_int(args[1]);
uint32_t block_off = 0;
if (n_args == 4) {
block_off = mp_obj_get_int(args[3]);
}
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(args[2], &bufinfo, MP_BUFFER_WRITE);
if (self->type == MCX_FLASH_TYPE_INTERNAL) {
drv_iflash_attr_t attr;
drv_iflash_attr_get(&self->iflash, &attr);
uint32_t flash_addr = MICROPY_HW_IFS_START + attr.sector_size * block_id + block_off;
drv_iflash_read(&self->iflash, flash_addr, bufinfo.buf, bufinfo.len);
}
return mp_const_none;
}
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mcx_flash_readblocks_obj, 3, 4, mcx_flash_readblocks);
static mp_obj_t mcx_flash_writeblocks(size_t n_args, const mp_obj_t *args) {
mcx_flash_obj_t *self = MP_OBJ_TO_PTR(args[0]);
uint32_t block_id = mp_obj_get_int(args[1]);
uint32_t block_off = 0;
if (n_args == 4) {
block_off = mp_obj_get_int(args[3]);
}
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(args[2], &bufinfo, MP_BUFFER_READ);
if (self->type == MCX_FLASH_TYPE_INTERNAL) {
drv_iflash_attr_t attr;
drv_iflash_attr_get(&self->iflash, &attr);
uint32_t page_addr = MICROPY_HW_IFS_START + block_id * attr.sector_size + block_off;
uint32_t page_count = bufinfo.len / attr.page_size;
for (uint32_t i = 0; i < page_count; i++) {
uint8_t *buf_ptr = &((uint8_t *)bufinfo.buf)[i * attr.page_size];
int ret = drv_iflash_program_page(&self->iflash, page_addr + i * attr.page_size, buf_ptr);
if (ret < 0) {
mp_raise_msg_varg(&mp_type_RuntimeError, MP_ERROR_TEXT("program phrase failed: %d"), ret);
}
}
}
return mp_const_none;
}
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mcx_flash_writeblocks_obj, 3, 4, mcx_flash_writeblocks);
static mp_obj_t mcx_flash_progsize(mp_obj_t self_in) {
mcx_flash_obj_t *self = MP_OBJ_TO_PTR(self_in);
if (self->type == MCX_FLASH_TYPE_INTERNAL) {
drv_iflash_attr_t attr;
drv_iflash_attr_get(&self->iflash, &attr);
return MP_OBJ_NEW_SMALL_INT(attr.page_size);
}
return MP_OBJ_NEW_SMALL_INT(0);
}
static MP_DEFINE_CONST_FUN_OBJ_1(mcx_flash_progsize_obj, mcx_flash_progsize);
static mp_obj_t mcx_flash_ioctl(mp_obj_t self_in, mp_obj_t cmd_in, mp_obj_t arg_in) {
mcx_flash_obj_t *self = MP_OBJ_TO_PTR(self_in);
uint32_t erase_size = 0U;
uint32_t block_count = 0U;
uint32_t block_id = mp_obj_get_int(arg_in);
if (self->type == MCX_FLASH_TYPE_INTERNAL) {
drv_iflash_attr_t attr;
drv_iflash_attr_get(&self->iflash, &attr);
erase_size = attr.sector_size;
block_count = MICROPY_HW_IFS_LENGTH / erase_size;
}
mp_int_t cmd = mp_obj_get_int(cmd_in);
switch (cmd) {
case MP_BLOCKDEV_IOCTL_INIT:
case MP_BLOCKDEV_IOCTL_DEINIT:
case MP_BLOCKDEV_IOCTL_SYNC:
return MP_OBJ_NEW_SMALL_INT(0);
case MP_BLOCKDEV_IOCTL_BLOCK_COUNT:
return MP_OBJ_NEW_SMALL_INT(block_count);
case MP_BLOCKDEV_IOCTL_BLOCK_SIZE:
return MP_OBJ_NEW_SMALL_INT(erase_size);
case MP_BLOCKDEV_IOCTL_BLOCK_ERASE: {
if (self->type == MCX_FLASH_TYPE_INTERNAL) {
if (drv_iflash_erase_sector(&self->iflash, MICROPY_HW_IFS_START + block_id * erase_size) < 0) {
mp_raise_msg_varg(&mp_type_RuntimeError, MP_ERROR_TEXT("Erase sector failed."));
}
}
return MP_OBJ_NEW_SMALL_INT(0);
}
default:
return mp_const_none;
}
}
static MP_DEFINE_CONST_FUN_OBJ_3(mcx_flash_ioctl_obj, mcx_flash_ioctl);
static const mp_rom_map_elem_t mcx_flash_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_readblocks), MP_ROM_PTR(&mcx_flash_readblocks_obj) },
{ MP_ROM_QSTR(MP_QSTR_writeblocks), MP_ROM_PTR(&mcx_flash_writeblocks_obj) },
{ MP_ROM_QSTR(MP_QSTR_progsize), MP_ROM_PTR(&mcx_flash_progsize_obj)},
{ MP_ROM_QSTR(MP_QSTR_ioctl), MP_ROM_PTR(&mcx_flash_ioctl_obj) },
/* Constants */
{ MP_ROM_QSTR(MP_QSTR_INTERNAL), MP_ROM_INT(MCX_FLASH_TYPE_INTERNAL) },
#if MICROPY_HW_ENABLE_EFS
{ MP_ROM_QSTR(MP_QSTR_EXTERNAL), MP_ROM_INT(MCX_FLASH_TYPE_EXTERNAL) },
#endif
};
static MP_DEFINE_CONST_DICT(mcx_flash_locals_dict, mcx_flash_locals_dict_table);
MP_DEFINE_CONST_OBJ_TYPE(
mcx_flash_type,
MP_QSTR_Flash,
MP_TYPE_FLAG_NONE,
make_new, mcx_flash_make_new,
print, mcx_flash_print,
locals_dict, &mcx_flash_locals_dict
);

Wyświetl plik

@ -0,0 +1,43 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2020-2023 Damien P. George
* Copyright (c) 2024 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
// This file is never compiled standalone, it's included directly from
// extmod/modmachine.c via MICROPY_PY_MACHINE_INCLUDEFILE.
#define MICROPY_PY_MACHINE_EXTRA_GLOBALS \
{ MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&machine_pin_type) }, \
void machine_init(void) {
}
void machine_deinit(void) {
}
static void mp_machine_idle(void) {
__WFI();
}

Wyświetl plik

@ -0,0 +1,6 @@
#ifndef MP_PORT_MCX_MODMACHINE_H
#define MP_PORT_MCX_MODMACHINE_H
#include "py/obj.h"
#endif

46
ports/mcx/modmcx.c 100644
Wyświetl plik

@ -0,0 +1,46 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2019 Damien P. George
* Copyright (c) 2024 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "string.h"
#include "py/runtime.h"
#include "py/mphal.h"
extern const mp_obj_type_t mcx_flash_type;
static const mp_rom_map_elem_t mcx_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_mcx) },
{ MP_ROM_QSTR(MP_QSTR_Flash), MP_ROM_PTR(&mcx_flash_type) },
};
static MP_DEFINE_CONST_DICT(mcx_module_globals, mcx_module_globals_table);
const mp_obj_module_t mp_module_mcx = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t *)&mcx_module_globals,
};
MP_REGISTER_MODULE(MP_QSTR_mcx, mp_module_mcx);

34
ports/mcx/modmcx.h 100644
Wyświetl plik

@ -0,0 +1,34 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2024 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef MP_PORT_MCX_MODMCX_H
#define MP_PORT_MCX_MODMCX_H
#include "py/obj.h"
extern const mp_obj_type_t mcx_flash_type;
#endif

34
ports/mcx/modos.c 100644
Wyświetl plik

@ -0,0 +1,34 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2024 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "py/runtime.h"
bool mp_os_dupterm_is_builtin_stream(mp_const_obj_t stream) {
return true;
}
void mp_os_dupterm_stream_detached_attached(mp_obj_t stream_detached, mp_obj_t stream_attached) {
}

Wyświetl plik

@ -0,0 +1,15 @@
import os, mcx
ifs = mcx.Flash()
prog_size = ifs.progsize()
try:
vfs = os.VfsLfs2(ifs, progsize=prog_size)
except:
os.VfsLfs2.mkfs(ifs, progsize=prog_size)
vfs = os.VfsLfs2(ifs, progsize=prog_size)
os.mount(vfs, "/")
del os, ifs, vfs, prog_size

Wyświetl plik

@ -0,0 +1,38 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2024 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef MP_PORT_MCX_MPCONFIGBOARD_COMMON_H
#define MP_PORT_MCX_MPCONFIGBOARD_COMMON_H
#include <errno.h>
#include <math.h>
#include "fsl_common.h"
#include "fsl_common_arm.h"
#define MICROPY_HAL_SYSTICK_RATE (1000)
#endif

Wyświetl plik

@ -0,0 +1,207 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2013-2017 Damien P. George
* Copyright (c) 2024 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <stdint.h>
// Options to control how MicroPython is built for this port,
// overriding defaults in py/mpconfig.h.
// board specific definitions
#include "mpconfigboard_common.h"
#include "mpconfigboard.h"
// Default configuration
#ifndef MICROPY_CONFIG_ROM_LEVEL
#define MICROPY_CONFIG_ROM_LEVEL (MICROPY_CONFIG_ROM_LEVEL_EXTRA_FEATURES)
#endif
// You can disable the built-in MicroPython compiler by setting the following
// config option to 0. If you do this then you won't get a REPL prompt, but you
// will still be able to execute pre-compiled scripts, compiled with mpy-cross.
#define MICROPY_ENABLE_COMPILER (1)
// Python internal features
#define MICROPY_READER_VFS (1)
#define MICROPY_ENABLE_GC (1)
#define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF (1)
#define MICROPY_EMERGENCY_EXCEPTION_BUF_SIZE (0)
#define MICROPY_REPL_INFO (1)
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ)
#ifndef MICROPY_FLOAT_IMPL // can be configured by each board via mpconfigboard.mk
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT)
#endif
#define MICROPY_USE_INTERNAL_ERRNO (1)
#define MICROPY_SCHEDULER_STATIC_NODES (1)
#define MICROPY_SCHEDULER_DEPTH (8)
#define MICROPY_VFS (1)
#ifndef MICROPY_VFS_LFS2
#define MICROPY_VFS_LFS2 (1)
#endif
// Hardware features
#ifndef MICROPY_HW_ENABLE_USBDEV
#define MICROPY_HW_ENABLE_USBDEV (0)
#endif
#ifndef MICROPY_HW_ENABLE_UART_REPL
#define MICROPY_HW_ENABLE_UART_REPL (1) // useful if there is no USB
#endif
#if MICROPY_HW_ENABLE_USBDEV
#ifndef MICROPY_HW_USBDEV
#define MICROPY_HW_USBDEV (0)
#endif
// Enable USB-CDC serial port
#ifndef MICROPY_HW_USB_CDC
#define MICROPY_HW_USB_CDC (1)
#endif
// Enable USB Mass Storage with FatFS filesystem.
#ifndef MICROPY_HW_USB_MSC
#define MICROPY_HW_USB_MSC (0)
#endif
#endif
#if MICROPY_HW_ENABLE_UART_REPL
#ifndef MICROPY_HW_UART_REPL
#define MICROPY_HW_UART_REPL (0)
#endif
#endif
#ifndef MICROPY_HW_ENABLE_IFS
#define MICROPY_HW_ENABLE_IFS (0)
#endif
#if MICROPY_HW_ENABLE_IFS
// IFS start
#ifndef MICROPY_HW_IFS_START
#define MICROPY_HW_IFS_START (0x100000)
#endif
// IFS length
#ifndef MICROPY_HW_IFS_LENGTH
#define MICROPY_HW_IFS_LENGTH (0x100000)
#endif
#endif
#ifndef MICROPY_HW_ENABLE_EFS
#define MICROPY_HW_ENABLE_EFS (0)
#endif
// Extended modules
#define MICROPY_PY_OS_INCLUDEFILE "ports/mcx/modos.c"
#define MICROPY_PY_OS_DUPTERM (3)
#define MICROPY_PY_OS_DUPTERM_BUILTIN_STREAM (1)
#define MICROPY_PY_OS_DUPTERM_STREAM_DETACHED_ATTACHED (1)
#define MICROPY_PY_ONEWIRE (1)
// Machine configs
#define MICROPY_PY_MACHINE (1)
#define MICROPY_PY_MACHINE_INCLUDEFILE "ports/mcx/modmachine.c"
#define MICROPY_PY_MACHINE_DHT_READINTO (1)
#define MICROPY_PY_MACHINE_PIN_MAKE_NEW mp_pin_make_new
#define MICROPY_PY_MACHINE_PULSE (1)
#define MICROPY_PY_MACHINE_ADC (1)
#define MICROPY_PY_MACHINE_ADC_INCLUDEFILE "ports/mcx/machine_adc.c"
#define MICROPY_PY_MACHINE_UART (1)
#define MICROPY_PY_MACHINE_UART_INCLUDEFILE "ports/mcx/machine_uart.c"
#define MICROPY_PY_MACHINE_UART_IRQ (0)
#define MICROPY_PY_MACHINE_UART_READCHAR_WRITECHAR (1)
#define MICROPY_PY_MACHINE_UART_SENDBREAK (1)
#define MICROPY_PY_MACHINE_I2C (1)
#define MICROPY_PY_MACHINE_SPI (1)
#define MICROPY_PY_MACHINE_SPI_MSB (0)
#define MICROPY_PY_MACHINE_SPI_LSB (1)
#define MICROPY_PY_MACHINE_PWM (1)
#define MICROPY_PY_MACHINE_PWM_DUTY (0)
#define MICROPY_PY_MACHINE_PWM_INCLUDEFILE "ports/mcx/machine_pwm.c"
// type definitions for the specific machine
typedef intptr_t mp_int_t; // must be pointer size
typedef uintptr_t mp_uint_t; // must be pointer size
typedef long mp_off_t;
// We need to provide a declaration/definition of alloca()
#include <alloca.h>
#ifndef MICROPY_HW_BOARD_NAME
#define MICROPY_HW_BOARD_NAME "Unknown MCX series board"
#endif
#ifndef MICROPY_HW_MCU_NAME
#define MICROPY_HW_MCU_NAME "Unknown MCX series MCU"
#endif
#ifndef MICROPY_PY_SYS_PLATFORM
#define MICROPY_PY_SYS_PLATFORM "mcx"
#endif
// We need an implementation of the log2 function which is not a macro
#define MP_NEED_LOG2 (1)
#define MP_SSIZE_MAX (0x7fffffff)
#define MP_STATE_PORT MP_STATE_VM
#if MICROPY_PY_THREAD
#define MICROPY_EVENT_POLL_HOOK \
do { \
extern void mp_handle_pending(bool); \
mp_handle_pending(true); \
if (pyb_thread_enabled) { \
MP_THREAD_GIL_EXIT(); \
pyb_thread_yield(); \
MP_THREAD_GIL_ENTER(); \
} else { \
__WFI(); \
} \
} while (0);
#define MICROPY_THREAD_YIELD() pyb_thread_yield()
#else
#define MICROPY_EVENT_POLL_HOOK \
do { \
extern void mp_handle_pending(bool); \
mp_handle_pending(true); \
__WFI(); \
} while (0);
#define MICROPY_THREAD_YIELD()
#endif

Wyświetl plik

@ -0,0 +1,53 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2024 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "board.h"
extern volatile mp_uint_t s_current_tick;
void mp_hal_init(void) {
SysTick_Config(CLOCK_GetCoreSysClkFreq() / MICROPY_HAL_SYSTICK_RATE);
s_current_tick = 0ULL;
NVIC_SetPriority(SysTick_IRQn, 0U);
EnableIRQ(SysTick_IRQn);
}
void mp_hal_deinit(void) {
DisableIRQ(SysTick_IRQn);
SysTick->CTRL = 0U;
}
void mp_hal_get_unique_id(uint8_t *uid) {
uint64_t uuid;
MCX_BoardGetUniqueID(&uuid);
for (uint8_t i = 0; i < 8; i++) {
uid[i] = (uuid >> (i * 8)) & 0xFFU;
}
}

Wyświetl plik

@ -0,0 +1,79 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2024 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef MP_PORT_MCX_MPHALPORT_H
#define MP_PORT_MCX_MPHALPORT_H
void mp_hal_init(void);
/* UUID*/
void mp_hal_get_unique_id(uint8_t *uid);
/* STDIO */
int mp_hal_stdio_init(void);
/* Pin */
#include "hal_pin.h"
static inline void enable_irq(mp_uint_t state) {
__set_PRIMASK(state);
}
static inline mp_uint_t disable_irq(void) {
mp_uint_t state = __get_PRIMASK();
__disable_irq();
return state;
}
static inline uint32_t raise_irq_pri(uint32_t pri) {
uint32_t basepri = __get_BASEPRI();
// If non-zero, the processor does not process any exception with a
// priority value greater than or equal to BASEPRI.
// When writing to BASEPRI_MAX the write goes to BASEPRI only if either:
// - Rn is non-zero and the current BASEPRI value is 0
// - Rn is non-zero and less than the current BASEPRI value
pri <<= (8 - __NVIC_PRIO_BITS);
__ASM volatile ("msr basepri_max, %0" : : "r" (pri) : "memory");
return basepri;
}
// "basepri" should be the value returned from raise_irq_pri
static inline void restore_irq_pri(uint32_t basepri) {
__set_BASEPRI(basepri);
}
#define mp_hal_quiet_timing_enter() raise_irq_pri(1)
#define mp_hal_quiet_timing_exit(irq_state) restore_irq_pri(irq_state)
/* Additional delay */
#define mp_hal_delay_us_fast mp_hal_delay_us
extern int mp_interrupt_char;
static inline void mp_hal_set_interrupt_char(char c) {
mp_interrupt_char = c;
}
#endif

146
ports/mcx/pendsv.c 100644
Wyświetl plik

@ -0,0 +1,146 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2022 Damien P. George
* Copyright (c) 2024 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <stdlib.h>
#include "MCXN947_cm33_core0.h"
#include "py/runtime.h"
#include "pendsv.h"
volatile void *pendsv_object;
#if defined(PENDSV_DISPATCH_NUM_SLOTS)
uint32_t pendsv_dispatch_active;
pendsv_dispatch_t pendsv_dispatch_table[PENDSV_DISPATCH_NUM_SLOTS];
#endif
void pendsv_init(void) {
#if defined(PENDSV_DISPATCH_NUM_SLOTS)
pendsv_dispatch_active = false;
#endif
NVIC_SetPriority(PendSV_IRQn, 7);
}
void pendsv_kbd_intr(void) {
if (MP_STATE_MAIN_THREAD(mp_pending_exception) == MP_OBJ_NULL) {
mp_sched_keyboard_interrupt();
} else {
MP_STATE_MAIN_THREAD(mp_pending_exception) = MP_OBJ_NULL;
pendsv_object = &MP_STATE_VM(mp_kbd_exception);
SCB->ICSR = SCB_ICSR_PENDSVSET_Msk;
}
}
#if defined(PENDSV_DISPATCH_NUM_SLOTS)
void pendsv_schedule_dispatch(size_t slot, pendsv_dispatch_t f) {
pendsv_dispatch_table[slot] = f;
pendsv_dispatch_active = true;
SCB->ICSR = SCB_ICSR_PENDSVSET_Msk;
}
void pendsv_dispatch_handler(void) {
for (size_t i = 0; i < PENDSV_DISPATCH_NUM_SLOTS; ++i) {
if (pendsv_dispatch_table[i] != NULL) {
pendsv_dispatch_t f = pendsv_dispatch_table[i];
pendsv_dispatch_table[i] = NULL;
f();
}
}
}
#endif
__attribute__((naked)) void PendSV_Handler(void) {
// Handle a PendSV interrupt
//
// For the case of an asynchronous exception, re-jig the
// stack so that when we return from this interrupt handler
// it returns instead to nlr_jump with argument pendsv_object
// note that stack has a different layout if DEBUG is enabled
//
// For the case of a thread switch, swap stacks.
//
// on entry to this (naked) function, stack has the following layout:
//
// stack layout with DEBUG disabled:
// sp[6]: pc=r15
// sp[5]: lr=r14
// sp[4]: r12
// sp[3]: r3
// sp[2]: r2
// sp[1]: r1
// sp[0]: r0
//
// stack layout with DEBUG enabled:
// sp[8]: pc=r15
// sp[7]: lr=r14
// sp[6]: r12
// sp[5]: r3
// sp[4]: r2
// sp[3]: r1
// sp[2]: r0
// sp[1]: 0xfffffff9
// sp[0]: ?
__asm volatile (
#if defined(PENDSV_DISPATCH_NUM_SLOTS)
// Check if there are any pending calls to dispatch to
"ldr r1, pendsv_dispatch_active_ptr\n"
"ldr r0, [r1]\n"
"cmp r0, #0\n"
"beq .no_dispatch\n"
"mov r2, #0\n"
"str r2, [r1]\n" // clear pendsv_dispatch_active
"b pendsv_dispatch_handler\n" // jump to the handler
".no_dispatch:\n"
#endif
// Check if there is an active object to throw via nlr_jump
"ldr r1, pendsv_object_ptr\n"
"ldr r0, [r1]\n"
"cmp r0, #0\n"
"beq .no_obj\n"
"str r0, [sp, #0]\n" // store to r0 on stack
"mov r0, #0\n"
"str r0, [r1]\n" // clear pendsv_object
"ldr r0, nlr_jump_ptr\n"
"str r0, [sp, #24]\n" // store to pc on stack
"bx lr\n" // return from interrupt; will return to nlr_jump
".no_obj:\n" // pendsv_object==NULL
// Data
".align 2\n"
#if defined(PENDSV_DISPATCH_NUM_SLOTS)
"pendsv_dispatch_active_ptr: .word pendsv_dispatch_active\n"
#endif
"pendsv_object_ptr: .word pendsv_object\n"
"nlr_jump_ptr: .word nlr_jump\n"
);
}

44
ports/mcx/pendsv.h 100644
Wyświetl plik

@ -0,0 +1,44 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2022 Damien P. George
* Copyright (c) 2024 NXP
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef MP_PORT_MCX_PENDSV_H
#define MP_PORT_MCX_PENDSV_H
enum {
PENDSV_DISPATCH_SOFT_TIMER,
PENDSV_DISPATCH_MAX
};
#define PENDSV_DISPATCH_NUM_SLOTS PENDSV_DISPATCH_MAX
typedef void (*pendsv_dispatch_t)(void);
void pendsv_init(void);
void pendsv_kbd_intr(void);
void pendsv_schedule_dispatch(size_t slot, pendsv_dispatch_t f);
#endif

Wyświetl plik

@ -0,0 +1,2 @@
// qstrs specific to this port
// *FORMAT-OFF*

Wyświetl plik

@ -0,0 +1,36 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2020 Jim Mussared
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
#ifndef MICROPY_INCLUDED_MCX_TUSB_CONFIG_H
#define MICROPY_INCLUDED_MCX_TUSB_CONFIG_H
#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED)
#define CFG_TUSB_OS (OPT_OS_NONE)
#define CFG_TUD_CDC (1)
#define CFG_TUD_CDC_RX_BUFSIZE (512)
#define CFG_TUD_CDC_TX_BUFSIZE (512)
#endif // MICROPY_INCLUDED_MIMXRT_TUSB_CONFIG_H

Wyświetl plik

@ -0,0 +1,138 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2019 Damien P. George
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "tusb.h"
#include "mphalport.h"
#ifndef MICROPY_HW_USB_VID
#define MICROPY_HW_USB_VID (0xf055)
#endif
#ifndef MICROPY_HW_USB_PID
#define MICROPY_HW_USB_PID (0x9802)
#endif
#ifndef MICROPY_HW_USB_MANUFACTURER_STRING
#define MICROPY_HW_USB_MANUFACTURER_STRING ("MicroPython")
#endif
#define USBD_DESC_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN)
#define USBD_MAX_POWER_MA (250)
#define USBD_ITF_CDC (0) // needs 2 interfaces
#define USBD_ITF_MAX (2)
#define USBD_CDC_EP_CMD (0x81)
#define USBD_CDC_EP_OUT (0x02)
#define USBD_CDC_EP_IN (0x82)
#define USBD_CDC_CMD_MAX_SIZE (8)
#define USBD_CDC_IN_OUT_MAX_SIZE (512)
#define USBD_STR_0 (0x00)
#define USBD_STR_MANUF (0x01)
#define USBD_STR_PRODUCT (0x02)
#define USBD_STR_SERIAL (0x03)
#define USBD_STR_CDC (0x04)
// Note: descriptors returned from callbacks must exist long enough for transfer to complete
static const tusb_desc_device_t usbd_desc_device = {
.bLength = sizeof(tusb_desc_device_t),
.bDescriptorType = TUSB_DESC_DEVICE,
.bcdUSB = 0x0200,
.bDeviceClass = TUSB_CLASS_MISC,
.bDeviceSubClass = MISC_SUBCLASS_COMMON,
.bDeviceProtocol = MISC_PROTOCOL_IAD,
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
.idVendor = MICROPY_HW_USB_VID,
.idProduct = MICROPY_HW_USB_PID,
.bcdDevice = 0x0100,
.iManufacturer = USBD_STR_MANUF,
.iProduct = USBD_STR_PRODUCT,
.iSerialNumber = USBD_STR_SERIAL,
.bNumConfigurations = 1,
};
static const uint8_t usbd_desc_cfg[USBD_DESC_LEN] = {
TUD_CONFIG_DESCRIPTOR(1, USBD_ITF_MAX, USBD_STR_0, USBD_DESC_LEN,
TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, USBD_MAX_POWER_MA),
TUD_CDC_DESCRIPTOR(USBD_ITF_CDC, USBD_STR_CDC, USBD_CDC_EP_CMD,
USBD_CDC_CMD_MAX_SIZE, USBD_CDC_EP_OUT, USBD_CDC_EP_IN, USBD_CDC_IN_OUT_MAX_SIZE),
};
static const char *const usbd_desc_str[] = {
[USBD_STR_MANUF] = MICROPY_HW_USB_MANUFACTURER_STRING,
[USBD_STR_PRODUCT] = MICROPY_HW_BOARD_NAME,
[USBD_STR_SERIAL] = "00000000000000000000",
[USBD_STR_CDC] = "Board CDC",
};
const uint8_t *tud_descriptor_device_cb(void) {
return (const uint8_t *)&usbd_desc_device;
}
const uint8_t *tud_descriptor_configuration_cb(uint8_t index) {
(void)index;
return usbd_desc_cfg;
}
const uint16_t *tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
#define DESC_STR_MAX (20)
static uint16_t desc_str[DESC_STR_MAX];
static const char hexchr[16] = "0123456789ABCDEF";
memset(desc_str, 0, sizeof(desc_str));
uint8_t len;
if (index == 0) {
desc_str[1] = 0x0409; // supported language is English
len = 1;
} else {
if (index >= sizeof(usbd_desc_str) / sizeof(usbd_desc_str[0])) {
return NULL;
}
if (index == USBD_STR_SERIAL) {
uint8_t uid[8];
mp_hal_get_unique_id(uid);
// store it as a hex string
for (len = 0; len < 16; len += 2) {
desc_str[1 + len] = hexchr[uid[len / 2] >> 4];
desc_str[1 + len + 1] = hexchr[uid[len / 2] & 0x0f];
}
} else {
const char *str = usbd_desc_str[index];
for (len = 0; len < DESC_STR_MAX - 1 && str[len]; ++len) {
desc_str[1 + len] = str[len];
}
}
}
// first byte is length (including header), second byte is string type
desc_str[0] = (TUSB_DESC_STRING << 8) | (2 * len + 2);
return desc_str;
}

Wyświetl plik

@ -156,8 +156,11 @@ void machine_rtc_start(void) {
SNVS->HPCOMR |= SNVS_HPCOMR_NPSWA_EN_MASK;
// Do a basic init.
SNVS_LP_Init(SNVS);
#if defined(FSL_FEATURE_SNVS_HAS_MULTIPLE_TAMPER) && (FSL_FEATURE_SNVS_HAS_MULTIPLE_TAMPER > 0)
// Disable all external Tamper
SNVS_LP_DisableAllExternalTamper(SNVS);
#endif
SNVS_LP_SRTC_StartTimer(SNVS);
// If the date is not set, set it to a more recent start date,