kopia lustrzana https://github.com/micropython/micropython
Merge 3171c925b7
into e60e8079a7
commit
4ce50338aa
|
@ -1 +1 @@
|
|||
Subproject commit fa5a554c7944d2a196626f8d3631e44943f9abcc
|
||||
Subproject commit 485ff6db37e9bc288d33d8c252cbb9dbd48678d3
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,4 @@
|
|||
TARGET_MCU_SERIES = MCXA153
|
||||
TARGET_MCU_PART = MCXA153VLH
|
||||
TARGET_MCU_CORE_HAS_DSP = 0
|
||||
TARGET_MCU_CORE_HAS_FPU = 0
|
|
@ -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]);
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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_ */
|
|
@ -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);
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
include("$(BOARD_DIR)/manifest.py")
|
|
@ -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)
|
|
@ -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
|
|
@ -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
|
||||
**********************************************************************************************************************/
|
|
@ -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
|
||||
**********************************************************************************************************************/
|
|
@ -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
|
|
|
@ -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()
|
|
@ -0,0 +1,7 @@
|
|||
include("$(MPY_DIR)/extmod/asyncio")
|
||||
|
||||
require("onewire")
|
||||
require("ds18x20")
|
||||
require("dht")
|
||||
|
||||
freeze("$(PORT_DIR)/modules")
|
|
@ -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, \
|
||||
}
|
|
@ -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
|
|
|
@ -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")
|
||||
}
|
||||
|
Plik diff jest za duży
Load Diff
|
@ -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. */
|
||||
}
|
|
@ -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_ */
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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, §or_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;
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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);
|
|
@ -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++;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
);
|
|
@ -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
|
||||
);
|
|
@ -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
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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
|
||||
);
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
);
|
|
@ -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();
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef MP_PORT_MCX_MODMACHINE_H
|
||||
#define MP_PORT_MCX_MODMACHINE_H
|
||||
|
||||
#include "py/obj.h"
|
||||
|
||||
#endif
|
|
@ -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);
|
|
@ -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
|
|
@ -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) {
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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"
|
||||
);
|
||||
}
|
|
@ -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
|
|
@ -0,0 +1,2 @@
|
|||
// qstrs specific to this port
|
||||
// *FORMAT-OFF*
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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,
|
||||
|
|
Ładowanie…
Reference in New Issue