diff --git a/.gitmodules b/.gitmodules index 9d07e70449..c152e9e774 100644 --- a/.gitmodules +++ b/.gitmodules @@ -33,3 +33,6 @@ [submodule "lib/btstack"] path = lib/btstack url = https://github.com/bluekitchen/btstack.git +[submodule "lib/nxp_driver"] + path = lib/nxp_driver + url = https://github.com/hathach/nxp_driver.git diff --git a/lib/nxp_driver b/lib/nxp_driver new file mode 160000 index 0000000000..b618cb1d52 --- /dev/null +++ b/lib/nxp_driver @@ -0,0 +1 @@ +Subproject commit b618cb1d521cc9e133bdcd0fca154dee2d925dfe diff --git a/ports/mimxrt/Makefile b/ports/mimxrt/Makefile new file mode 100644 index 0000000000..8f06c208de --- /dev/null +++ b/ports/mimxrt/Makefile @@ -0,0 +1,133 @@ +BOARD ?= TEENSY40 +BOARD_DIR ?= boards/$(BOARD) +BUILD ?= build-$(BOARD) + +CROSS_COMPILE ?= arm-none-eabi- + +ifeq ($(wildcard $(BOARD_DIR)/.),) +$(error Invalid BOARD specified: $(BOARD_DIR)) +endif + +include ../../py/mkenv.mk +include $(BOARD_DIR)/mpconfigboard.mk + +# Qstr definitions (must come before including py.mk) +QSTR_DEFS = qstrdefsport.h +QSTR_GLOBAL_DEPENDENCIES = $(BOARD_DIR)/mpconfigboard.h + +# Include py core make definitions +include $(TOP)/py/py.mk + +GIT_SUBMODULES = lib/tinyusb lib/nxp_driver + +MCU_DIR = lib/nxp_driver/sdk/devices/$(MCU_SERIES) +LD_FILES = boards/$(MCU_SERIES).ld $(TOP)/$(MCU_DIR)/gcc/$(MCU_SERIES)xxxxx_flexspi_nor.ld + +# mcu driver cause following warnings +#CFLAGS += -Wno-error=float-equal -Wno-error=nested-externs +CFLAGS += -Wno-error=unused-parameter + +INC += -I. +INC += -I$(TOP) +INC += -I$(BUILD) +INC += -I$(BOARD_DIR) +INC += -I$(TOP)/lib/cmsis/inc +INC += -I$(TOP)/$(MCU_DIR) +INC += -I$(TOP)/$(MCU_DIR)/drivers +INC += -I$(TOP)/$(MCU_DIR)/project_template +INC += -I$(TOP)/lib/tinyusb/src +INC += -I$(TOP)/lib/tinyusb/hw +INC += -I$(TOP)/lib/tinyusb/hw/bsp/teensy_40 + +CFLAGS_MCU = -mtune=cortex-m7 -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 +CFLAGS = $(INC) -Wall -Werror -std=c99 -nostdlib -mthumb $(CFLAGS_MCU) +CFLAGS += -DCPU_$(MCU_SERIES) -DCPU_$(MCU_VARIANT) +CFLAGS += -DXIP_EXTERNAL_FLASH=1 \ + -DXIP_BOOT_HEADER_ENABLE=1 \ + -DCFG_TUSB_MCU=OPT_MCU_MIMXRT10XX \ + -D__STARTUP_CLEAR_BSS \ + -D__START=main \ + -DCPU_HEADER_H='<$(MCU_SERIES).h>' + +LDFLAGS = $(addprefix -T,$(LD_FILES)) -Map=$@.map --cref +LIBS = $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) + +# Tune for Debugging or Optimization +ifeq ($(DEBUG),1) +CFLAGS += -O0 -ggdb +else +CFLAGS += -Os -DNDEBUG +LDFLAGS += --gc-sections +CFLAGS += -fdata-sections -ffunction-sections +endif + +# TinyUSB Stack source +SRC_TINYUSB_C += \ + lib/tinyusb/src/tusb.c \ + lib/tinyusb/src/common/tusb_fifo.c \ + lib/tinyusb/src/device/usbd.c \ + lib/tinyusb/src/device/usbd_control.c \ + lib/tinyusb/src/class/msc/msc_device.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/usbtmc/usbtmc_device.c \ + lib/tinyusb/src/class/vendor/vendor_device.c \ + lib/tinyusb/src/portable/nxp/transdimension/dcd_transdimension.c + +SRC_TINYUSB_IMX_C += \ + $(MCU_DIR)/system_$(MCU_SERIES).c \ + $(MCU_DIR)/xip/fsl_flexspi_nor_boot.c \ + $(MCU_DIR)/project_template/clock_config.c \ + $(MCU_DIR)/drivers/fsl_clock.c \ + $(MCU_DIR)/drivers/fsl_gpio.c \ + $(MCU_DIR)/drivers/fsl_common.c \ + $(MCU_DIR)/drivers/fsl_lpuart.c \ + $(MCU_DIR)/drivers/fsl_flexram.c \ + +SRC_C = \ + main.c \ + tusb_port.c \ + board_init.c \ + $(BOARD_DIR)/flash_config.c \ + modutime.c \ + modmachine.c \ + mphalport.c \ + lib/mp-readline/readline.c \ + lib/libc/string0.c \ + lib/utils/printf.c \ + lib/utils/pyexec.c \ + lib/utils/stdout_helpers.c \ + $(SRC_TINYUSB_C) \ + $(SRC_TINYUSB_IMX_C) \ + +SRC_SS = $(MCU_DIR)/gcc/startup_$(MCU_SERIES).S + +SRC_S = lib/utils/gchelper_m3.s \ + +# List of sources for qstr extraction +SRC_QSTR += modutime.c modmachine.c + +OBJ += $(PY_O) +OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_SS:.S=.o)) + +# Workaround for bug in older gcc, warning on "static usbd_device_t _usbd_dev = { 0 };" +$(BUILD)/lib/tinyusb/src/device/usbd.o: CFLAGS += -Wno-missing-braces + +all: $(BUILD)/firmware.hex + +$(BUILD)/firmware.elf: $(OBJ) + $(ECHO) "LINK $@" + $(Q)$(LD) $(LDFLAGS) -o $@ $^ $(LIBS) + $(Q)$(SIZE) $@ + +$(BUILD)/firmware.bin: $(BUILD)/firmware.elf + $(Q)$(OBJCOPY) -O binary $^ $@ + +$(BUILD)/firmware.hex: $(BUILD)/firmware.elf + $(Q)$(OBJCOPY) -O ihex -R .eeprom $< $@ + +include $(TOP)/py/mkrules.mk diff --git a/ports/mimxrt/README.md b/ports/mimxrt/README.md new file mode 100644 index 0000000000..1ef2f338c2 --- /dev/null +++ b/ports/mimxrt/README.md @@ -0,0 +1,14 @@ +Port of MicroPython to NXP iMX RT 10xx +====================================== + +Currently supports Teensy 4.0. + +Features: + - REPL over USB VCP + +Known issues: + - pyboard.py doesn't work with files larger than 64 bytes + +TODO: + - Enable TCM + - Peripherals (pins, LED, Timers, etc) diff --git a/ports/mimxrt/board_init.c b/ports/mimxrt/board_init.c new file mode 100644 index 0000000000..48e86c7c0c --- /dev/null +++ b/ports/mimxrt/board_init.c @@ -0,0 +1,114 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * Based on tinyusb/hw/bsp/teensy_40/teensy40.c + * + * The MIT License (MIT) + * + * Copyright (c) 2018, hathach (tinyusb.org) + * 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. + */ + +#include "py/runtime.h" + +#include "tusb.h" + +#include "fsl_device_registers.h" +#include "fsl_gpio.h" +#include "fsl_iomuxc.h" +#include "fsl_clock.h" +#include "fsl_lpuart.h" + +#include "clock_config.h" + +#define LED_STATE_ON (0) + +volatile uint32_t systick_ms = 0; + +const uint8_t dcd_data[] = { 0x00 }; + +void board_led_write(bool state); + +void board_init(void) { + // Init clock + BOARD_BootClockRUN(); + SystemCoreClockUpdate(); + + // Enable IOCON clock + CLOCK_EnableClock(kCLOCK_Iomuxc); + + // 1ms tick timer + SysTick_Config(SystemCoreClock / 1000); + + // LED + IOMUXC_SetPinMux(MICROPY_HW_LED_PINMUX, 0U); + IOMUXC_SetPinConfig(MICROPY_HW_LED_PINMUX, 0x10B0U); + + gpio_pin_config_t led_config = { kGPIO_DigitalOutput, 0, kGPIO_NoIntmode }; + GPIO_PinInit(MICROPY_HW_LED_PORT, MICROPY_HW_LED_PIN, &led_config); + board_led_write(true); + + //------------- USB0 -------------// + + // Clock + CLOCK_EnableUsbhs0PhyPllClock(kCLOCK_Usbphy480M, 480000000U); + CLOCK_EnableUsbhs0Clock(kCLOCK_Usb480M, 480000000U); + + #ifdef USBPHY1 + USBPHY_Type *usb_phy = USBPHY1; + #else + USBPHY_Type *usb_phy = USBPHY; + #endif + + // Enable PHY support for Low speed device + LS via FS Hub + usb_phy->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL2_MASK | USBPHY_CTRL_SET_ENUTMILEVEL3_MASK; + + // Enable all power for normal operation + usb_phy->PWD = 0; + + // TX Timing + uint32_t phytx = usb_phy->TX; + phytx &= ~(USBPHY_TX_D_CAL_MASK | USBPHY_TX_TXCAL45DM_MASK | USBPHY_TX_TXCAL45DP_MASK); + phytx |= USBPHY_TX_D_CAL(0x0C) | USBPHY_TX_TXCAL45DP(0x06) | USBPHY_TX_TXCAL45DM(0x06); + usb_phy->TX = phytx; + + // USB1 + // CLOCK_EnableUsbhs1PhyPllClock(kCLOCK_Usbphy480M, 480000000U); + // CLOCK_EnableUsbhs1Clock(kCLOCK_Usb480M, 480000000U); +} + +void board_led_write(bool state) { + GPIO_PinWrite(MICROPY_HW_LED_PORT, MICROPY_HW_LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); +} + +void SysTick_Handler(void) { + systick_ms++; +} + +void USB_OTG1_IRQHandler(void) { + tud_isr(0); + tud_task(); +} + +void USB_OTG2_IRQHandler(void) { + tud_isr(1); + tud_task(); +} diff --git a/ports/mimxrt/boards/MIMXRT1062.ld b/ports/mimxrt/boards/MIMXRT1062.ld new file mode 100644 index 0000000000..23520b5624 --- /dev/null +++ b/ports/mimxrt/boards/MIMXRT1062.ld @@ -0,0 +1,8 @@ +/* 32kiB stack. */ +__stack_size__ = 0x8000; +_estack = __StackTop; +_sstack = __StackLimit; + +/* Use second OCRAM bank for GC heap. */ +_gc_heap_start = ORIGIN(m_data2); +_gc_heap_end = ORIGIN(m_data2) + LENGTH(m_data2); diff --git a/ports/mimxrt/boards/TEENSY40/flash_config.c b/ports/mimxrt/boards/TEENSY40/flash_config.c new file mode 100644 index 0000000000..39a6b91088 --- /dev/null +++ b/ports/mimxrt/boards/TEENSY40/flash_config.c @@ -0,0 +1,51 @@ +/* + * Copyright 2018 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +// Based on tinyusb/hw/bsp/teensy_40/teensy40_flexspi_nor_config.c + +#include "teensy40_flexspi_nor_config.h" + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.xip_board" +#endif + +/******************************************************************************* + * Code + ******************************************************************************/ +#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) +#if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) +__attribute__((section(".boot_hdr.conf"))) +#elif defined(__ICCARM__) +#pragma location = ".boot_hdr.conf" +#endif + +const flexspi_nor_config_t qspiflash_config = { + .memConfig = + { + .tag = FLEXSPI_CFG_BLK_TAG, + .version = FLEXSPI_CFG_BLK_VERSION, + .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad, + .csHoldTime = 3u, + .csSetupTime = 3u, + // Enable DDR mode, Wordaddassable, Safe configuration, Differential clock + .sflashPadType = kSerialFlash_4Pads, + .serialClkFreq = kFlexSpiSerialClk_100MHz, + .sflashA1Size = 2u * 1024u * 1024u, + .lookupTable = + { + // Read LUTs + FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18), + FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04), + }, + }, + .pageSize = 256u, + .sectorSize = 4u * 1024u, + .blockSize = 256u * 1024u, + .isUniformBlockSize = false, +}; +#endif /* XIP_BOOT_HEADER_ENABLE */ diff --git a/ports/mimxrt/boards/TEENSY40/mpconfigboard.h b/ports/mimxrt/boards/TEENSY40/mpconfigboard.h new file mode 100644 index 0000000000..10c8b7a6d1 --- /dev/null +++ b/ports/mimxrt/boards/TEENSY40/mpconfigboard.h @@ -0,0 +1,8 @@ +#define MICROPY_HW_BOARD_NAME "Teensy 4.0" +#define MICROPY_HW_MCU_NAME "MIMXRT1062DVJ6A" + +#define BOARD_FLASH_SIZE (2 * 1024 * 1024) + +#define MICROPY_HW_LED_PINMUX IOMUXC_GPIO_B0_03_GPIO2_IO03 // D13 +#define MICROPY_HW_LED_PORT GPIO2 +#define MICROPY_HW_LED_PIN 3 diff --git a/ports/mimxrt/boards/TEENSY40/mpconfigboard.mk b/ports/mimxrt/boards/TEENSY40/mpconfigboard.mk new file mode 100644 index 0000000000..6b939a3afd --- /dev/null +++ b/ports/mimxrt/boards/TEENSY40/mpconfigboard.mk @@ -0,0 +1,5 @@ +MCU_SERIES = MIMXRT1062 +MCU_VARIANT = MIMXRT1062DVJ6A + +deploy: $(BUILD)/firmware.hex + teensy_loader_cli --mcu=imxrt1062 -v -w $< diff --git a/ports/mimxrt/boards/TEENSY40/teensy40_flexspi_nor_config.h b/ports/mimxrt/boards/TEENSY40/teensy40_flexspi_nor_config.h new file mode 100644 index 0000000000..2c7bf48b62 --- /dev/null +++ b/ports/mimxrt/boards/TEENSY40/teensy40_flexspi_nor_config.h @@ -0,0 +1,270 @@ +/* + * Copyright 2018 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +// Based on tinyusb/hw/bsp/teensy_40/teensy40_flexspi_nor_config.h + +#ifndef __TEENSY40_FLEXSPI_NOR_CONFIG__ +#define __TEENSY40_FLEXSPI_NOR_CONFIG__ + +#include +#include +#include "fsl_common.h" + +/*! @name Driver version */ +/*@{*/ +/*! @brief XIP_BOARD driver version 2.0.0. */ +#define FSL_XIP_BOARD_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*@}*/ + +/* FLEXSPI memory config block related defintions */ +#define FLEXSPI_CFG_BLK_TAG (0x42464346UL) // ascii "FCFB" Big Endian +#define FLEXSPI_CFG_BLK_VERSION (0x56010400UL) // V1.4.0 +#define FLEXSPI_CFG_BLK_SIZE (512) + +/* FLEXSPI Feature related definitions */ +#define FLEXSPI_FEATURE_HAS_PARALLEL_MODE 1 + +/* Lookup table related defintions */ +#define CMD_INDEX_READ 0 +#define CMD_INDEX_READSTATUS 1 +#define CMD_INDEX_WRITEENABLE 2 +#define CMD_INDEX_WRITE 4 + +#define CMD_LUT_SEQ_IDX_READ 0 +#define CMD_LUT_SEQ_IDX_READSTATUS 1 +#define CMD_LUT_SEQ_IDX_WRITEENABLE 3 +#define CMD_LUT_SEQ_IDX_WRITE 9 + +#define CMD_SDR 0x01 +#define CMD_DDR 0x21 +#define RADDR_SDR 0x02 +#define RADDR_DDR 0x22 +#define CADDR_SDR 0x03 +#define CADDR_DDR 0x23 +#define MODE1_SDR 0x04 +#define MODE1_DDR 0x24 +#define MODE2_SDR 0x05 +#define MODE2_DDR 0x25 +#define MODE4_SDR 0x06 +#define MODE4_DDR 0x26 +#define MODE8_SDR 0x07 +#define MODE8_DDR 0x27 +#define WRITE_SDR 0x08 +#define WRITE_DDR 0x28 +#define READ_SDR 0x09 +#define READ_DDR 0x29 +#define LEARN_SDR 0x0A +#define LEARN_DDR 0x2A +#define DATSZ_SDR 0x0B +#define DATSZ_DDR 0x2B +#define DUMMY_SDR 0x0C +#define DUMMY_DDR 0x2C +#define DUMMY_RWDS_SDR 0x0D +#define DUMMY_RWDS_DDR 0x2D +#define JMP_ON_CS 0x1F +#define STOP 0 + +#define FLEXSPI_1PAD 0 +#define FLEXSPI_2PAD 1 +#define FLEXSPI_4PAD 2 +#define FLEXSPI_8PAD 3 + +#define FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) \ + (FLEXSPI_LUT_OPERAND0(op0) | FLEXSPI_LUT_NUM_PADS0(pad0) | FLEXSPI_LUT_OPCODE0(cmd0) | FLEXSPI_LUT_OPERAND1(op1) | \ + FLEXSPI_LUT_NUM_PADS1(pad1) | FLEXSPI_LUT_OPCODE1(cmd1)) + +//!@brief Definitions for FlexSPI Serial Clock Frequency +typedef enum _FlexSpiSerialClockFreq +{ + kFlexSpiSerialClk_30MHz = 1, + kFlexSpiSerialClk_50MHz = 2, + kFlexSpiSerialClk_60MHz = 3, + kFlexSpiSerialClk_75MHz = 4, + kFlexSpiSerialClk_80MHz = 5, + kFlexSpiSerialClk_100MHz = 6, + kFlexSpiSerialClk_120MHz = 7, + kFlexSpiSerialClk_133MHz = 8, + kFlexSpiSerialClk_166MHz = 9, +} flexspi_serial_clk_freq_t; + +//!@brief FlexSPI clock configuration type +enum +{ + kFlexSpiClk_SDR, //!< Clock configure for SDR mode + kFlexSpiClk_DDR, //!< Clock configurat for DDR mode +}; + +//!@brief FlexSPI Read Sample Clock Source definition +typedef enum _FlashReadSampleClkSource +{ + kFlexSPIReadSampleClk_LoopbackInternally = 0, + kFlexSPIReadSampleClk_LoopbackFromDqsPad = 1, + kFlexSPIReadSampleClk_LoopbackFromSckPad = 2, + kFlexSPIReadSampleClk_ExternalInputFromDqsPad = 3, +} flexspi_read_sample_clk_t; + +//!@brief Misc feature bit definitions +enum +{ + kFlexSpiMiscOffset_DiffClkEnable = 0, //!< Bit for Differential clock enable + kFlexSpiMiscOffset_Ck2Enable = 1, //!< Bit for CK2 enable + kFlexSpiMiscOffset_ParallelEnable = 2, //!< Bit for Parallel mode enable + kFlexSpiMiscOffset_WordAddressableEnable = 3, //!< Bit for Word Addressable enable + kFlexSpiMiscOffset_SafeConfigFreqEnable = 4, //!< Bit for Safe Configuration Frequency enable + kFlexSpiMiscOffset_PadSettingOverrideEnable = 5, //!< Bit for Pad setting override enable + kFlexSpiMiscOffset_DdrModeEnable = 6, //!< Bit for DDR clock confiuration indication. +}; + +//!@brief Flash Type Definition +enum +{ + kFlexSpiDeviceType_SerialNOR = 1, //!< Flash devices are Serial NOR + kFlexSpiDeviceType_SerialNAND = 2, //!< Flash devices are Serial NAND + kFlexSpiDeviceType_SerialRAM = 3, //!< Flash devices are Serial RAM/HyperFLASH + kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, //!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND + kFlexSpiDeviceType_MCP_NOR_RAM = 0x13, //!< Flash deivce is MCP device, A1 is Serial NOR, A2 is Serial RAMs +}; + +//!@brief Flash Pad Definitions +enum +{ + kSerialFlash_1Pad = 1, + kSerialFlash_2Pads = 2, + kSerialFlash_4Pads = 4, + kSerialFlash_8Pads = 8, +}; + +//!@brief FlexSPI LUT Sequence structure +typedef struct _lut_sequence +{ + uint8_t seqNum; //!< Sequence Number, valid number: 1-16 + uint8_t seqId; //!< Sequence Index, valid number: 0-15 + uint16_t reserved; +} flexspi_lut_seq_t; + +//!@brief Flash Configuration Command Type +enum +{ + kDeviceConfigCmdType_Generic, //!< Generic command, for example: configure dummy cycles, drive strength, etc + kDeviceConfigCmdType_QuadEnable, //!< Quad Enable command + kDeviceConfigCmdType_Spi2Xpi, //!< Switch from SPI to DPI/QPI/OPI mode + kDeviceConfigCmdType_Xpi2Spi, //!< Switch from DPI/QPI/OPI to SPI mode + kDeviceConfigCmdType_Spi2NoCmd, //!< Switch to 0-4-4/0-8-8 mode + kDeviceConfigCmdType_Reset, //!< Reset device command +}; + +//!@brief FlexSPI Memory Configuration Block +typedef struct _FlexSPIConfig +{ + uint32_t tag; //!< [0x000-0x003] Tag, fixed value 0x42464346UL + uint32_t version; //!< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix + uint32_t reserved0; //!< [0x008-0x00b] Reserved for future use + uint8_t readSampleClkSrc; //!< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 + uint8_t csHoldTime; //!< [0x00d-0x00d] CS hold time, default value: 3 + uint8_t csSetupTime; //!< [0x00e-0x00e] CS setup time, default value: 3 + uint8_t columnAddressWidth; //!< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For + //! Serial NAND, need to refer to datasheet + uint8_t deviceModeCfgEnable; //!< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable + uint8_t deviceModeType; //!< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, + //! Generic configuration, etc. + uint16_t waitTimeCfgCommands; //!< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for + //! DPI/QPI/OPI switch or reset command + flexspi_lut_seq_t deviceModeSeq; //!< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt + //! sequence number, [31:16] Reserved + uint32_t deviceModeArg; //!< [0x018-0x01b] Argument/Parameter for device configuration + uint8_t configCmdEnable; //!< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable + uint8_t configModeType[3]; //!< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe + flexspi_lut_seq_t + configCmdSeqs[3]; //!< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq + uint32_t reserved1; //!< [0x02c-0x02f] Reserved for future use + uint32_t configCmdArgs[3]; //!< [0x030-0x03b] Arguments/Parameters for device Configuration commands + uint32_t reserved2; //!< [0x03c-0x03f] Reserved for future use + uint32_t controllerMiscOption; //!< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more + //! details + uint8_t deviceType; //!< [0x044-0x044] Device Type: See Flash Type Definition for more details + uint8_t sflashPadType; //!< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal + uint8_t serialClkFreq; //!< [0x046-0x046] Serial Flash Frequencey, device specific definitions, See System Boot + //! Chapter for more details + uint8_t lutCustomSeqEnable; //!< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot + //! be done using 1 LUT sequence, currently, only applicable to HyperFLASH + uint32_t reserved3[2]; //!< [0x048-0x04f] Reserved for future use + uint32_t sflashA1Size; //!< [0x050-0x053] Size of Flash connected to A1 + uint32_t sflashA2Size; //!< [0x054-0x057] Size of Flash connected to A2 + uint32_t sflashB1Size; //!< [0x058-0x05b] Size of Flash connected to B1 + uint32_t sflashB2Size; //!< [0x05c-0x05f] Size of Flash connected to B2 + uint32_t csPadSettingOverride; //!< [0x060-0x063] CS pad setting override value + uint32_t sclkPadSettingOverride; //!< [0x064-0x067] SCK pad setting override value + uint32_t dataPadSettingOverride; //!< [0x068-0x06b] data pad setting override value + uint32_t dqsPadSettingOverride; //!< [0x06c-0x06f] DQS pad setting override value + uint32_t timeoutInMs; //!< [0x070-0x073] Timeout threshold for read status command + uint32_t commandInterval; //!< [0x074-0x077] CS deselect interval between two commands + uint16_t dataValidTime[2]; //!< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B, in terms of 0.1ns + uint16_t busyOffset; //!< [0x07c-0x07d] Busy offset, valid value: 0-31 + uint16_t busyBitPolarity; //!< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - + //! busy flag is 0 when flash device is busy + uint32_t lookupTable[64]; //!< [0x080-0x17f] Lookup table holds Flash command sequences + flexspi_lut_seq_t lutCustomSeq[12]; //!< [0x180-0x1af] Customizable LUT Sequences + uint32_t reserved4[4]; //!< [0x1b0-0x1bf] Reserved for future use +} flexspi_mem_config_t; + +/* */ +#define NOR_CMD_INDEX_READ CMD_INDEX_READ //!< 0 +#define NOR_CMD_INDEX_READSTATUS CMD_INDEX_READSTATUS //!< 1 +#define NOR_CMD_INDEX_WRITEENABLE CMD_INDEX_WRITEENABLE //!< 2 +#define NOR_CMD_INDEX_ERASESECTOR 3 //!< 3 +#define NOR_CMD_INDEX_PAGEPROGRAM CMD_INDEX_WRITE //!< 4 +#define NOR_CMD_INDEX_CHIPERASE 5 //!< 5 +#define NOR_CMD_INDEX_DUMMY 6 //!< 6 +#define NOR_CMD_INDEX_ERASEBLOCK 7 //!< 7 + +#define NOR_CMD_LUT_SEQ_IDX_READ CMD_LUT_SEQ_IDX_READ //!< 0 READ LUT sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_READSTATUS \ + CMD_LUT_SEQ_IDX_READSTATUS //!< 1 Read Status LUT sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI \ + 2 //!< 2 Read status DPI/QPI/OPI sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE \ + CMD_LUT_SEQ_IDX_WRITEENABLE //!< 3 Write Enable sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE_XPI \ + 4 //!< 4 Write Enable DPI/QPI/OPI sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 //!< 5 Erase Sector sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_ERASEBLOCK 8 //!< 8 Erase Block sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM \ + CMD_LUT_SEQ_IDX_WRITE //!< 9 Program sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 //!< 11 Chip Erase sequence in lookupTable id stored in config block +#define NOR_CMD_LUT_SEQ_IDX_READ_SFDP 13 //!< 13 Read SFDP sequence in lookupTable id stored in config block +#define NOR_CMD_LUT_SEQ_IDX_RESTORE_NOCMD \ + 14 //!< 14 Restore 0-4-4/0-8-8 mode sequence id in lookupTable stored in config block +#define NOR_CMD_LUT_SEQ_IDX_EXIT_NOCMD \ + 15 //!< 15 Exit 0-4-4/0-8-8 mode sequence id in lookupTable stored in config blobk + +/* + * Serial NOR configuration block + */ +typedef struct _flexspi_nor_config +{ + flexspi_mem_config_t memConfig; //!< Common memory configuration info via FlexSPI + uint32_t pageSize; //!< Page size of Serial NOR + uint32_t sectorSize; //!< Sector size of Serial NOR + uint8_t ipcmdSerialClkFreq; //!< Clock frequency for IP command + uint8_t isUniformBlockSize; //!< Sector/Block size is the same + uint8_t reserved0[2]; //!< Reserved for future use + uint8_t serialNorType; //!< Serial NOR Flash type: 0/1/2/3 + uint8_t needExitNoCmdMode; //!< Need to exit NoCmd mode before other IP command + uint8_t halfClkForNonReadCmd; //!< Half the Serial Clock for non-read command: true/false + uint8_t needRestoreNoCmdMode; //!< Need to Restore NoCmd mode after IP commmand execution + uint32_t blockSize; //!< Block size + uint32_t reserve2[11]; //!< Reserved for future use +} flexspi_nor_config_t; + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif +#endif /* __EVKMIMXRT1060_FLEXSPI_NOR_CONFIG__ */ diff --git a/ports/mimxrt/main.c b/ports/mimxrt/main.c new file mode 100644 index 0000000000..a718cb46c7 --- /dev/null +++ b/ports/mimxrt/main.c @@ -0,0 +1,108 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Damien P. George + * 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. + */ + +#include "py/compile.h" +#include "py/runtime.h" +#include "py/gc.h" +#include "py/mperrno.h" +#include "py/stackctrl.h" +#include "lib/utils/gchelper.h" +#include "lib/utils/pyexec.h" +#include "tusb.h" + +extern uint8_t _sstack, _estack, _gc_heap_start, _gc_heap_end; + +void board_init(void); + +int main(void) { + board_init(); + tusb_init(); + + mp_stack_set_top(&_estack); + mp_stack_set_limit(&_estack - &_sstack - 1024); + + for (;;) { + gc_init(&_gc_heap_start, &_gc_heap_end); + mp_init(); + + mp_obj_list_init(MP_OBJ_TO_PTR(mp_sys_path), 0); + mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_)); + mp_obj_list_init(MP_OBJ_TO_PTR(mp_sys_argv), 0); + + for (;;) { + if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) { + if (pyexec_raw_repl() != 0) { + break; + } + } else { + if (pyexec_friendly_repl() != 0) { + break; + } + } + } + + mp_printf(MP_PYTHON_PRINTER, "MPY: soft reboot\n"); + gc_sweep_all(); + mp_deinit(); + } + + return 0; +} + +void gc_collect(void) { + gc_collect_start(); + uintptr_t regs[10]; + uintptr_t sp = gc_helper_get_regs_and_sp(regs); + gc_collect_root((void **)sp, ((uintptr_t)MP_STATE_THREAD(stack_top) - sp) / sizeof(uint32_t)); + gc_collect_end(); +} + +mp_lexer_t *mp_lexer_new_from_file(const char *filename) { + mp_raise_OSError(MP_ENOENT); +} + +mp_import_stat_t mp_import_stat(const char *path) { + return MP_IMPORT_STAT_NO_EXIST; +} + +mp_obj_t mp_builtin_open(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) { + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, mp_builtin_open); + +void nlr_jump_fail(void *val) { + for (;;) { + } +} + +#ifndef NDEBUG +void MP_WEAK __assert_func(const char *file, int line, const char *func, const char *expr) { + mp_printf(MP_PYTHON_PRINTER, "Assertion '%s' failed, at file %s:%d\n", expr, file, line); + for (;;) { + } +} +#endif diff --git a/ports/mimxrt/modmachine.c b/ports/mimxrt/modmachine.c new file mode 100644 index 0000000000..747b7bc27f --- /dev/null +++ b/ports/mimxrt/modmachine.c @@ -0,0 +1,57 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Damien P. George + * 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. + */ + +#include "py/runtime.h" +#include "extmod/machine_mem.h" + +#include CPU_HEADER_H + +STATIC mp_obj_t machine_reset(void) { + NVIC_SystemReset(); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_0(machine_reset_obj, machine_reset); + +STATIC mp_obj_t machine_freq(void) { + return MP_OBJ_NEW_SMALL_INT(0); +} +MP_DEFINE_CONST_FUN_OBJ_0(machine_freq_obj, machine_freq); + +STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_umachine) }, + { MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&machine_reset_obj) }, + { MP_ROM_QSTR(MP_QSTR_freq), MP_ROM_PTR(&machine_freq_obj) }, + { MP_ROM_QSTR(MP_QSTR_mem8), MP_ROM_PTR(&machine_mem8_obj) }, + { MP_ROM_QSTR(MP_QSTR_mem16), MP_ROM_PTR(&machine_mem16_obj) }, + { MP_ROM_QSTR(MP_QSTR_mem32), MP_ROM_PTR(&machine_mem32_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(machine_module_globals, machine_module_globals_table); + +const mp_obj_module_t mp_module_machine = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&machine_module_globals, +}; diff --git a/ports/mimxrt/modutime.c b/ports/mimxrt/modutime.c new file mode 100644 index 0000000000..bbdbda44e2 --- /dev/null +++ b/ports/mimxrt/modutime.c @@ -0,0 +1,48 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Damien P. George + * 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. + */ + +#include "extmod/utime_mphal.h" + +STATIC const mp_rom_map_elem_t time_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_utime) }, + + { MP_ROM_QSTR(MP_QSTR_sleep), MP_ROM_PTR(&mp_utime_sleep_obj) }, + { MP_ROM_QSTR(MP_QSTR_sleep_ms), MP_ROM_PTR(&mp_utime_sleep_ms_obj) }, + { MP_ROM_QSTR(MP_QSTR_sleep_us), MP_ROM_PTR(&mp_utime_sleep_us_obj) }, + { MP_ROM_QSTR(MP_QSTR_ticks_ms), MP_ROM_PTR(&mp_utime_ticks_ms_obj) }, + { MP_ROM_QSTR(MP_QSTR_ticks_us), MP_ROM_PTR(&mp_utime_ticks_us_obj) }, + { MP_ROM_QSTR(MP_QSTR_ticks_cpu), MP_ROM_PTR(&mp_utime_ticks_cpu_obj) }, + { MP_ROM_QSTR(MP_QSTR_ticks_add), MP_ROM_PTR(&mp_utime_ticks_add_obj) }, + { MP_ROM_QSTR(MP_QSTR_ticks_diff), MP_ROM_PTR(&mp_utime_ticks_diff_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(time_module_globals, time_module_globals_table); + +const mp_obj_module_t mp_module_utime = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&time_module_globals, +}; diff --git a/ports/mimxrt/mpconfigport.h b/ports/mimxrt/mpconfigport.h new file mode 100644 index 0000000000..344867fb81 --- /dev/null +++ b/ports/mimxrt/mpconfigport.h @@ -0,0 +1,109 @@ +/* + * 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. + */ + +// Options controlling how MicroPython is built, overriding defaults in py/mpconfig.h + +// Board specific definitions +#include "mpconfigboard.h" + +// Memory allocation policies +#define MICROPY_GC_STACK_ENTRY_TYPE uint16_t +#define MICROPY_GC_ALLOC_THRESHOLD (0) +#define MICROPY_ALLOC_PARSE_CHUNK_INIT (32) +#define MICROPY_ALLOC_PATH_MAX (256) +#define MICROPY_QSTR_BYTES_IN_HASH (1) + +// Compiler configuration +#define MICROPY_COMP_CONST (0) + +// Python internal features +#define MICROPY_ENABLE_GC (1) +#define MICROPY_KBD_EXCEPTION (1) +#define MICROPY_HELPER_REPL (1) +#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ) +#define MICROPY_ENABLE_SOURCE_LINE (1) +#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_TERSE) +#define MICROPY_CPYTHON_COMPAT (0) +#define MICROPY_CAN_OVERRIDE_BUILTINS (1) + +// Control over Python builtins +#define MICROPY_PY_ASYNC_AWAIT (0) +#define MICROPY_PY_BUILTINS_STR_COUNT (0) +#define MICROPY_PY_BUILTINS_MEMORYVIEW (1) +#define MICROPY_PY_BUILTINS_SET (1) +#define MICROPY_PY_BUILTINS_FROZENSET (0) +#define MICROPY_PY_BUILTINS_PROPERTY (0) +#define MICROPY_PY_BUILTINS_ENUMERATE (0) +#define MICROPY_PY_BUILTINS_FILTER (0) +#define MICROPY_PY_BUILTINS_REVERSED (1) +#define MICROPY_PY_BUILTINS_MIN_MAX (0) +#define MICROPY_PY___FILE__ (0) +#define MICROPY_PY_MICROPYTHON_MEM_INFO (1) +#define MICROPY_PY_ARRAY_SLICE_ASSIGN (1) +#define MICROPY_PY_ATTRTUPLE (0) +#define MICROPY_PY_COLLECTIONS (0) +#define MICROPY_PY_SYS_MAXSIZE (1) + +// Extended modules +#define MICROPY_PY_UTIME_MP_HAL (1) +#define MICROPY_PY_MACHINE (1) + +// Hooks to add builtins + +#define MICROPY_PORT_BUILTINS \ + { MP_ROM_QSTR(MP_QSTR_open), MP_ROM_PTR(&mp_builtin_open_obj) }, + +extern const struct _mp_obj_module_t mp_module_machine; +extern const struct _mp_obj_module_t mp_module_utime; + +#define MICROPY_PORT_BUILTIN_MODULES \ + { MP_ROM_QSTR(MP_QSTR_machine), MP_ROM_PTR(&mp_module_machine) }, \ + { MP_ROM_QSTR(MP_QSTR_utime), MP_ROM_PTR(&mp_module_utime) }, \ + +#define MICROPY_PORT_ROOT_POINTERS \ + const char *readline_hist[8]; + +#define MP_STATE_PORT MP_STATE_VM + +// Miscellaneous settings + +#define MICROPY_EVENT_POLL_HOOK \ + do { \ + extern void mp_handle_pending(bool); \ + mp_handle_pending(true); \ + __WFI(); \ + } while (0); + +#define MICROPY_MAKE_POINTER_CALLABLE(p) ((void *)((mp_uint_t)(p) | 1)) +#define MP_PLAT_PRINT_STRN(str, len) mp_hal_stdout_tx_strn_cooked(str, len) + +#define MP_SSIZE_MAX (0x7fffffff) +typedef int mp_int_t; // must be pointer size +typedef unsigned mp_uint_t; // must be pointer size +typedef long mp_off_t; + +// Need to provide a declaration/definition of alloca() +#include diff --git a/ports/mimxrt/mphalport.c b/ports/mimxrt/mphalport.c new file mode 100644 index 0000000000..d7642d6b6d --- /dev/null +++ b/ports/mimxrt/mphalport.c @@ -0,0 +1,103 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Damien P. George + * 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. + */ + +#include "py/runtime.h" +#include "py/mphal.h" +#include "tusb.h" + +#include CPU_HEADER_H + +#if MICROPY_KBD_EXCEPTION + +void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char) { + (void)itf; + (void)wanted_char; + tud_cdc_read_char(); // discard interrupt char + mp_keyboard_interrupt(); +} + +void mp_hal_set_interrupt_char(int c) { + tud_cdc_set_wanted_char(c); +} + +#endif + +void mp_hal_delay_ms(mp_uint_t ms) { + ms += 1; + uint32_t t0 = systick_ms; + while (systick_ms - t0 < ms) { + MICROPY_EVENT_POLL_HOOK + } +} + +void mp_hal_delay_us(mp_uint_t us) { + uint32_t ms = us / 1000 + 1; + uint32_t t0 = systick_ms; + while (systick_ms - t0 < ms) { + __WFI(); + } +} + +int mp_hal_stdin_rx_chr(void) { + for (;;) { + // TODO + // if (USARTx->USART.INTFLAG.bit.RXC) { + // return USARTx->USART.DATA.bit.DATA; + // } + if (tud_cdc_connected() && tud_cdc_available()) { + uint8_t buf[1]; + uint32_t count = tud_cdc_read(buf, sizeof(buf)); + if (count) { + return buf[0]; + } + } + __WFI(); + } +} + +void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) { + if (tud_cdc_connected()) { + for (size_t i = 0; i < len;) { + uint32_t n = len - i; + uint32_t n2 = tud_cdc_write(str + i, n); + if (n2 < n) { + while (!tud_cdc_write_flush()) { + __WFI(); + } + } + i += n2; + } + while (!tud_cdc_write_flush()) { + __WFI(); + } + } + // TODO + // while (len--) { + // while (!(USARTx->USART.INTFLAG.bit.DRE)) { } + // USARTx->USART.DATA.bit.DATA = *str++; + // } +} diff --git a/ports/mimxrt/mphalport.h b/ports/mimxrt/mphalport.h new file mode 100644 index 0000000000..e1cf84f6c2 --- /dev/null +++ b/ports/mimxrt/mphalport.h @@ -0,0 +1,48 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Damien P. George + * 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_MIMXRT_MPHALPORT_H +#define MICROPY_INCLUDED_MIMXRT_MPHALPORT_H + +#include + +extern volatile uint32_t systick_ms; + +void mp_hal_set_interrupt_char(int c); + +static inline mp_uint_t mp_hal_ticks_ms(void) { + return systick_ms; +} + +static inline mp_uint_t mp_hal_ticks_us(void) { + return systick_ms * 1000; +} + +static inline mp_uint_t mp_hal_ticks_cpu(void) { + return 0; +} + +#endif // MICROPY_INCLUDED_MIMXRT_MPHALPORT_H diff --git a/ports/mimxrt/qstrdefsport.h b/ports/mimxrt/qstrdefsport.h new file mode 100644 index 0000000000..00d3e2ae3c --- /dev/null +++ b/ports/mimxrt/qstrdefsport.h @@ -0,0 +1,2 @@ +// qstrs specific to this port +// *FORMAT-OFF* diff --git a/ports/mimxrt/tusb_config.h b/ports/mimxrt/tusb_config.h new file mode 100644 index 0000000000..f2367c2044 --- /dev/null +++ b/ports/mimxrt/tusb_config.h @@ -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_MIMXRT_TUSB_CONFIG_H +#define MICROPY_INCLUDED_MIMXRT_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 (256) +#define CFG_TUD_CDC_TX_BUFSIZE (256) + +#endif // MICROPY_INCLUDED_MIMXRT_TUSB_CONFIG_H diff --git a/ports/mimxrt/tusb_port.c b/ports/mimxrt/tusb_port.c new file mode 100644 index 0000000000..87eb104f85 --- /dev/null +++ b/ports/mimxrt/tusb_port.c @@ -0,0 +1,114 @@ +/* + * 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" + +#define USBD_VID (0xf055) +#define USBD_PID (0x9802) + +#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_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 = USBD_VID, + .idProduct = USBD_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(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, CFG_TUD_CDC_RX_BUFSIZE), +}; + +static const char *const usbd_desc_str[] = { + [USBD_STR_MANUF] = "MicroPython", + [USBD_STR_PRODUCT] = "Board in FS mode", + [USBD_STR_SERIAL] = "000000000000", // TODO + [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) { + #define DESC_STR_MAX (20) + static uint16_t desc_str[DESC_STR_MAX]; + + 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; + } + 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; +}