mirror of
https://github.com/micropython/micropython.git
synced 2025-12-13 08:20:13 +01:00
alif: Add initial port to Alif Ensemble MCUs.
This commit adds the beginning of a new alif port with support for Alif Ensemble MCUs. See https://alifsemi.com/ Supported features of this port added by this commit: - UART REPL. - TinyUSB support, for REPL and MSC. - Octal SPI flash support, for filesystem. - machine.Pin support. General notes about the port: - It uses make, similar to other bare-metal ports here. - The toolchain is the standard arm-none-eabi- toolchain. - Flashing a board can be done using either the built-in serial bootloader, or JLink (both supported here). - There are two required submodules (one for drivers/SDK, one for security tools), both of which are open source and on GitHub. - No special hardware or software is needed for development, just a board connected over USB. OpenMV have generously sponsored the development of this port. Signed-off-by: Damien George <damien@micropython.org> Signed-off-by: iabdalkader <i.abdalkader@gmail.com>
This commit is contained in:
261
ports/alif/Makefile
Normal file
261
ports/alif/Makefile
Normal file
@@ -0,0 +1,261 @@
|
||||
################################################################################
|
||||
# Initial setup of Makefile environment
|
||||
|
||||
BOARD ?= ALIF_ENSEMBLE
|
||||
BOARD_DIR ?= boards/$(BOARD)
|
||||
BUILD ?= build-$(BOARD)
|
||||
|
||||
ifeq ($(wildcard $(BOARD_DIR)/.),)
|
||||
$(error Invalid BOARD specified: $(BOARD_DIR))
|
||||
endif
|
||||
|
||||
include ../../py/mkenv.mk
|
||||
include mpconfigport.mk
|
||||
include $(BOARD_DIR)/mpconfigboard.mk
|
||||
|
||||
# qstr definitions (must come before including py.mk)
|
||||
QSTR_DEFS += qstrdefsport.h
|
||||
|
||||
# include py core make definitions
|
||||
include $(TOP)/py/py.mk
|
||||
include $(TOP)/extmod/extmod.mk
|
||||
|
||||
################################################################################
|
||||
# Project specific settings and compiler/linker flags
|
||||
|
||||
CROSS_COMPILE ?= arm-none-eabi-
|
||||
GIT_SUBMODULES += lib/tinyusb lib/alif_ensemble-cmsis-dfp lib/alif-security-toolkit
|
||||
PORT ?= /dev/ttyACM0
|
||||
|
||||
ALIF_TOOLS ?= ../../lib/alif-security-toolkit/toolkit
|
||||
ALIF_DFP_REL_TOP ?= lib/alif_ensemble-cmsis-dfp
|
||||
ALIF_DFP_REL_HERE ?= $(TOP)/lib/alif_ensemble-cmsis-dfp
|
||||
CMSIS_DIR ?= $(TOP)/lib/cmsis/inc
|
||||
|
||||
MCU_CORE ?= M55_HP
|
||||
ALIF_CONFIG ?= mcu/$(MCU_CORE)_cfg.json
|
||||
LD_FILE ?= mcu/ensemble.ld.S
|
||||
|
||||
INC += -I.
|
||||
INC += -I$(TOP)
|
||||
INC += -I$(BUILD)
|
||||
INC += -I$(BOARD_DIR)
|
||||
INC += -I$(CMSIS_DIR)
|
||||
INC += -I$(ALIF_DFP_REL_HERE)/drivers/include/
|
||||
INC += -I$(ALIF_DFP_REL_HERE)/ospi_xip/source/ospi
|
||||
INC += -I$(ALIF_DFP_REL_HERE)/Device/common/config/
|
||||
INC += -I$(ALIF_DFP_REL_HERE)/Device/common/include/
|
||||
INC += -I$(ALIF_DFP_REL_HERE)/Device/core/$(MCU_CORE)/config/
|
||||
INC += -I$(ALIF_DFP_REL_HERE)/Device/core/$(MCU_CORE)/include/
|
||||
INC += -I$(ALIF_DFP_REL_HERE)/Device/$(MCU_SERIES)/$(MCU_VARIANT)/
|
||||
INC += -I$(TOP)/lib/tinyusb/src
|
||||
INC += -Itinyusb_port
|
||||
|
||||
GEN_PIN_MKPINS = mcu/make-pins.py
|
||||
GEN_PIN_PREFIX = mcu/pins_prefix.c
|
||||
GEN_PINS_BOARD_CSV = $(BOARD_DIR)/pins.csv
|
||||
GEN_PINS_SRC = $(BUILD)/pins_board.c
|
||||
GEN_PINS_HDR = $(HEADER_BUILD)/pins_board.h
|
||||
|
||||
CFLAGS_FPU += -mfloat-abi=hard -mfpu=fpv5-d16
|
||||
CFLAGS_CORTEX_M55 += -mthumb -mcpu=cortex-m55 -mtune=cortex-m55 $(CFLAGS_FPU)
|
||||
|
||||
CFLAGS += $(INC) -Wall -Werror -std=c99 $(CFLAGS_CORTEX_M55) -nostdlib
|
||||
CFLAGS += -Wdouble-promotion -Wfloat-conversion
|
||||
CFLAGS += -fdata-sections -ffunction-sections
|
||||
CFLAGS += -D$(MCU_CORE) -DCORE_$(MCU_CORE) -DALIF_CMSIS_H="\"$(MCU_CORE).h\""
|
||||
|
||||
ifeq ($(MICROPY_FLOAT_IMPL),float)
|
||||
CFLAGS += -fsingle-precision-constant
|
||||
CFLAGS += -DMICROPY_FLOAT_IMPL=MICROPY_FLOAT_IMPL_FLOAT
|
||||
else
|
||||
CFLAGS += -DMICROPY_FLOAT_IMPL=MICROPY_FLOAT_IMPL_DOUBLE
|
||||
endif
|
||||
|
||||
AFLAGS = -mthumb -march=armv8.1-m.main $(CFLAGS_FPU)
|
||||
|
||||
LDFLAGS += -nostdlib
|
||||
LDFLAGS += -T$(BUILD)/ensemble.ld -Map=$@.map --cref --gc-sections
|
||||
LDFLAGS += --wrap=dcd_event_handler
|
||||
|
||||
# Tune for Debugging or Optimization
|
||||
ifeq ($(DEBUG), 1)
|
||||
CFLAGS += -Og -ggdb3
|
||||
# Disable text compression in debug builds
|
||||
MICROPY_ROM_TEXT_COMPRESSION = 0
|
||||
else
|
||||
CFLAGS += -O2 -DNDEBUG
|
||||
endif
|
||||
|
||||
LIBS += "$(shell $(CC) $(CFLAGS) -print-libgcc-file-name)"
|
||||
|
||||
JLINK_CMD = '\
|
||||
ExitOnError 1\n\
|
||||
Device $(JLINK_DEV)\n\
|
||||
SelectInterface SWD\n\
|
||||
Speed auto\n\
|
||||
Connect\n\
|
||||
Reset\n\
|
||||
ShowHWStatus\n\
|
||||
LoadFile "$(BUILD)/firmware_toc.bin",0x8057f1c0\n\
|
||||
LoadFile "$(BUILD)/firmware.bin",0x80000000\n\
|
||||
Reset\n\
|
||||
Exit'
|
||||
|
||||
################################################################################
|
||||
# Source files and libraries
|
||||
|
||||
SRC_O += \
|
||||
shared/runtime/gchelper_thumb2.o
|
||||
|
||||
SRC_C = \
|
||||
alif_flash.c \
|
||||
fatfs_port.c \
|
||||
machine_pin.c \
|
||||
main.c \
|
||||
modalif.c \
|
||||
mphalport.c \
|
||||
mpuart.c \
|
||||
msc_disk.c \
|
||||
ospi_flash.c \
|
||||
pendsv.c \
|
||||
usbd.c \
|
||||
$(wildcard $(BOARD_DIR)/*.c)
|
||||
|
||||
ifeq ($(MICROPY_FLOAT_IMPL),float)
|
||||
LIBM_SRC_C += $(SRC_LIB_LIBM_C)
|
||||
LIBM_SRC_C += $(SRC_LIB_LIBM_SQRT_HW_C)
|
||||
$(BUILD)/lib/libm/%.o: CFLAGS += -Wno-maybe-uninitialized
|
||||
else
|
||||
LIBM_SRC_C += $(SRC_LIB_LIBM_DBL_C)
|
||||
LIBM_SRC_C += $(SRC_LIB_LIBM_DBL_SQRT_HW_C)
|
||||
$(BUILD)/lib/libm_dbl/%.o: CFLAGS += -Wno-maybe-uninitialized
|
||||
endif
|
||||
|
||||
SHARED_SRC_C += $(addprefix shared/,\
|
||||
libc/string0.c \
|
||||
netutils/dhcpserver.c \
|
||||
netutils/netutils.c \
|
||||
netutils/trace.c \
|
||||
readline/readline.c \
|
||||
runtime/gchelper_native.c \
|
||||
runtime/interrupt_char.c \
|
||||
runtime/mpirq.c \
|
||||
runtime/pyexec.c \
|
||||
runtime/softtimer.c \
|
||||
runtime/stdout_helpers.c \
|
||||
runtime/sys_stdio_mphal.c \
|
||||
timeutils/timeutils.c \
|
||||
tinyusb/mp_usbd.c \
|
||||
tinyusb/mp_usbd_cdc.c \
|
||||
tinyusb/mp_usbd_descriptor.c \
|
||||
)
|
||||
|
||||
DRIVERS_SRC_C += $(addprefix drivers/,\
|
||||
bus/softspi.c \
|
||||
bus/softqspi.c \
|
||||
memory/spiflash.c \
|
||||
dht/dht.c \
|
||||
)
|
||||
|
||||
TINYUSB_SRC_C += \
|
||||
lib/tinyusb/src/tusb.c \
|
||||
lib/tinyusb/src/class/cdc/cdc_device.c \
|
||||
lib/tinyusb/src/class/msc/msc_device.c \
|
||||
lib/tinyusb/src/common/tusb_fifo.c \
|
||||
lib/tinyusb/src/device/usbd.c \
|
||||
lib/tinyusb/src/device/usbd_control.c \
|
||||
tinyusb_port/tusb_alif_dcd.c \
|
||||
|
||||
ALIF_SRC_C += $(addprefix $(ALIF_DFP_REL_TOP)/,\
|
||||
Device/common/source/clk.c \
|
||||
Device/common/source/mpu_M55.c \
|
||||
Device/common/source/system_M55.c \
|
||||
Device/common/source/system_utils.c \
|
||||
Device/core/$(MCU_CORE)/source/startup_$(MCU_CORE).c \
|
||||
drivers/source/pinconf.c \
|
||||
drivers/source/uart.c \
|
||||
ospi_xip/source/ospi/ospi_drv.c \
|
||||
)
|
||||
|
||||
$(BUILD)/tinyusb_port/tusb_alif_dcd.o: CFLAGS += -Wno-unused-variable -DTUSB_ALIF_NO_IRQ_CFG=1
|
||||
|
||||
# List of sources for qstr extraction
|
||||
SRC_QSTR += $(SRC_C) $(SHARED_SRC_C) $(GEN_PINS_SRC)
|
||||
|
||||
OBJ += $(PY_O)
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_O))
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(LIBM_SRC_C:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(SHARED_SRC_C:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(DRIVERS_SRC_C:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(TINYUSB_SRC_C:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(ALIF_SRC_C:.c=.o))
|
||||
OBJ += $(GEN_PINS_SRC:.c=.o)
|
||||
|
||||
################################################################################
|
||||
# Main targets
|
||||
|
||||
.DELETE_ON_ERROR:
|
||||
|
||||
.PHONY: all
|
||||
all: $(BUILD)/firmware_toc.bin
|
||||
|
||||
$(BUILD)/ensemble.ld: $(LD_FILE)
|
||||
$(ECHO) "Preprocess linker script $@"
|
||||
$(Q)$(CPP) -P -E $(CFLAGS) $^ > $@
|
||||
|
||||
$(BUILD)/firmware.elf: $(OBJ) $(BUILD)/ensemble.ld
|
||||
$(ECHO) "Link $@"
|
||||
$(Q)$(LD) $(LDFLAGS) -o $@ $(OBJ) $(LIBS)
|
||||
$(Q)$(SIZE) $@
|
||||
|
||||
$(BUILD)/firmware.bin: $(BUILD)/firmware.elf
|
||||
$(Q)$(OBJCOPY) -Obinary $^ $(BUILD)/firmware.bin
|
||||
|
||||
$(BUILD)/firmware_toc.bin: $(BUILD)/firmware.bin
|
||||
$(Q)python $(ALIF_TOOLS)/app-gen-toc.py \
|
||||
--filename $(abspath $(BUILD)/$(ALIF_TOC_CONFIG)) \
|
||||
--output-dir $(BUILD) \
|
||||
--firmware-dir $(BUILD) \
|
||||
--output $@
|
||||
|
||||
.PHONY: deploy
|
||||
deploy: $(BUILD)/firmware_toc.bin
|
||||
$(ECHO) "Writing $< to the board"
|
||||
$(Q)python $(ALIF_TOOLS)/app-write-mram.py \
|
||||
--cfg-part $(ALIF_TOOLKIT_CFG_PART) \
|
||||
--port $(PORT) \
|
||||
--pad \
|
||||
--images file:$(BUILD)/application_package.ds
|
||||
|
||||
.PHONY: deploy-jlink
|
||||
deploy-jlink: $(BUILD)/firmware_toc.bin
|
||||
$(Q)echo -e $(JLINK_CMD) | $(JLINK_EXE)
|
||||
|
||||
.PHONY: maintenance
|
||||
maintenance:
|
||||
$(Q)python $(ALIF_TOOLS)/maintenance.py \
|
||||
--cfg-part $(ALIF_TOOLKIT_CFG_PART) \
|
||||
--port $(PORT)
|
||||
|
||||
.PHONY: update-system-package
|
||||
update-system-package:
|
||||
$(Q)python $(ALIF_TOOLS)/updateSystemPackage.py \
|
||||
--cfg-part $(ALIF_TOOLKIT_CFG_PART) \
|
||||
--port $(PORT)
|
||||
|
||||
################################################################################
|
||||
# Remaining make rules
|
||||
|
||||
# Use a pattern rule here so that make will only call make-pins.py once to make
|
||||
# both pins_board.c and pins_board.h
|
||||
$(BUILD)/%_board.c $(HEADER_BUILD)/%_board.h: $(BOARD_DIR)/%.csv $(GEN_PIN_MKPINS) $(GEN_PIN_PREFIX) | $(HEADER_BUILD)
|
||||
$(ECHO) "GEN $@"
|
||||
$(Q)$(PYTHON) $(GEN_PIN_MKPINS) \
|
||||
--board-csv $(GEN_PINS_BOARD_CSV) \
|
||||
--prefix $(GEN_PIN_PREFIX) \
|
||||
--output-source $(GEN_PINS_SRC) \
|
||||
--output-header $(GEN_PINS_HDR)
|
||||
|
||||
include $(TOP)/py/mkrules.mk
|
||||
21
ports/alif/README.md
Normal file
21
ports/alif/README.md
Normal file
@@ -0,0 +1,21 @@
|
||||
MicroPython port to Alif Ensemble MCUs
|
||||
======================================
|
||||
|
||||
This is a port of MicroPython to the Alif Ensemble series of microcontrollers.
|
||||
|
||||
Initial development of this Alif port was sponsored by OpenMV LLC.
|
||||
|
||||
Features currently supported:
|
||||
- UART REPL.
|
||||
- TinyUSB with CDC and MSC device support.
|
||||
- Octal SPI flash with XIP mode.
|
||||
- machine.Pin support with named pins.
|
||||
- machine.UART, machine.SPI, machine.I2C, machine.RTC peripherals.
|
||||
- WiFi and Bluetooth using cyw43.
|
||||
- Dual core support of the HE and HP cores using Open-AMP.
|
||||
- Low power modes.
|
||||
|
||||
The following more advanced features will follow later:
|
||||
- Ethernet support.
|
||||
- SDRAM support.
|
||||
- Other machine modules.
|
||||
160
ports/alif/alif_flash.c
Normal file
160
ports/alif/alif_flash.c
Normal file
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2024 OpenMV LLC.
|
||||
*
|
||||
* 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/mphal.h"
|
||||
#include "py/runtime.h"
|
||||
#include "extmod/vfs.h"
|
||||
#include "modalif.h"
|
||||
#include "ospi_flash.h"
|
||||
|
||||
typedef struct _alif_flash_obj_t {
|
||||
mp_obj_base_t base;
|
||||
uint32_t flash_base_addr;
|
||||
uint32_t flash_size;
|
||||
} alif_flash_obj_t;
|
||||
|
||||
static alif_flash_obj_t alif_flash_obj = {
|
||||
.base = { &alif_flash_type },
|
||||
.flash_base_addr = MICROPY_HW_FLASH_STORAGE_BASE_ADDR,
|
||||
.flash_size = MICROPY_HW_FLASH_STORAGE_BYTES,
|
||||
};
|
||||
|
||||
static mp_obj_t alif_flash_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
|
||||
// Parse arguments
|
||||
enum { ARG_start, ARG_len };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
|
||||
{ MP_QSTR_len, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
|
||||
};
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
if (args[ARG_start].u_int == -1 && args[ARG_len].u_int == -1) {
|
||||
// Default singleton object that accesses entire flash
|
||||
return MP_OBJ_FROM_PTR(&alif_flash_obj);
|
||||
}
|
||||
|
||||
alif_flash_obj_t *self = mp_obj_malloc(alif_flash_obj_t, &alif_flash_type);
|
||||
|
||||
mp_int_t start = args[ARG_start].u_int;
|
||||
if (start == -1) {
|
||||
start = 0;
|
||||
} else if (!(0 <= start && start < MICROPY_HW_FLASH_STORAGE_BYTES && start % MICROPY_HW_FLASH_BLOCK_SIZE_BYTES == 0)) {
|
||||
mp_raise_ValueError(NULL);
|
||||
}
|
||||
|
||||
mp_int_t len = args[ARG_len].u_int;
|
||||
if (len == -1) {
|
||||
len = MICROPY_HW_FLASH_STORAGE_BYTES - start;
|
||||
} else if (!(0 < len && start + len <= MICROPY_HW_FLASH_STORAGE_BYTES && len % MICROPY_HW_FLASH_BLOCK_SIZE_BYTES == 0)) {
|
||||
mp_raise_ValueError(NULL);
|
||||
}
|
||||
|
||||
self->flash_base_addr = MICROPY_HW_FLASH_STORAGE_BASE_ADDR + start;
|
||||
self->flash_size = len;
|
||||
|
||||
return MP_OBJ_FROM_PTR(self);
|
||||
}
|
||||
|
||||
static mp_obj_t alif_flash_readblocks(size_t n_args, const mp_obj_t *args) {
|
||||
alif_flash_obj_t *self = MP_OBJ_TO_PTR(args[0]);
|
||||
uint32_t offset = mp_obj_get_int(args[1]) * MICROPY_HW_FLASH_BLOCK_SIZE_BYTES;
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(args[2], &bufinfo, MP_BUFFER_WRITE);
|
||||
if (n_args == 4) {
|
||||
offset += mp_obj_get_int(args[3]);
|
||||
}
|
||||
int ret = ospi_flash_read(self->flash_base_addr + offset, bufinfo.len, bufinfo.buf);
|
||||
mp_event_handle_nowait();
|
||||
return MP_OBJ_NEW_SMALL_INT(ret);
|
||||
}
|
||||
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alif_flash_readblocks_obj, 3, 4, alif_flash_readblocks);
|
||||
|
||||
static mp_obj_t alif_flash_writeblocks(size_t n_args, const mp_obj_t *args) {
|
||||
alif_flash_obj_t *self = MP_OBJ_TO_PTR(args[0]);
|
||||
uint32_t offset = mp_obj_get_int(args[1]) * MICROPY_HW_FLASH_BLOCK_SIZE_BYTES;
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(args[2], &bufinfo, MP_BUFFER_READ);
|
||||
if (n_args == 3) {
|
||||
uint32_t addr = self->flash_base_addr + offset;
|
||||
int32_t len = bufinfo.len;
|
||||
while (len > 0) {
|
||||
int ret = ospi_flash_erase_sector(addr);
|
||||
mp_event_handle_nowait();
|
||||
if (ret < 0) {
|
||||
return MP_OBJ_NEW_SMALL_INT(ret);
|
||||
}
|
||||
addr += MICROPY_HW_FLASH_BLOCK_SIZE_BYTES;
|
||||
len -= MICROPY_HW_FLASH_BLOCK_SIZE_BYTES;
|
||||
}
|
||||
} else {
|
||||
offset += mp_obj_get_int(args[3]);
|
||||
}
|
||||
int ret = ospi_flash_write(self->flash_base_addr + offset, bufinfo.len, bufinfo.buf);
|
||||
mp_event_handle_nowait();
|
||||
return MP_OBJ_NEW_SMALL_INT(ret);
|
||||
}
|
||||
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alif_flash_writeblocks_obj, 3, 4, alif_flash_writeblocks);
|
||||
|
||||
static mp_obj_t alif_flash_ioctl(mp_obj_t self_in, mp_obj_t cmd_in, mp_obj_t arg_in) {
|
||||
alif_flash_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
mp_int_t cmd = mp_obj_get_int(cmd_in);
|
||||
switch (cmd) {
|
||||
case MP_BLOCKDEV_IOCTL_INIT:
|
||||
return MP_OBJ_NEW_SMALL_INT(0);
|
||||
case MP_BLOCKDEV_IOCTL_DEINIT:
|
||||
return MP_OBJ_NEW_SMALL_INT(0);
|
||||
case MP_BLOCKDEV_IOCTL_SYNC:
|
||||
return MP_OBJ_NEW_SMALL_INT(0);
|
||||
case MP_BLOCKDEV_IOCTL_BLOCK_COUNT:
|
||||
return MP_OBJ_NEW_SMALL_INT(self->flash_size / MICROPY_HW_FLASH_BLOCK_SIZE_BYTES);
|
||||
case MP_BLOCKDEV_IOCTL_BLOCK_SIZE:
|
||||
return MP_OBJ_NEW_SMALL_INT(MICROPY_HW_FLASH_BLOCK_SIZE_BYTES);
|
||||
case MP_BLOCKDEV_IOCTL_BLOCK_ERASE: {
|
||||
uint32_t offset = mp_obj_get_int(arg_in) * MICROPY_HW_FLASH_BLOCK_SIZE_BYTES;
|
||||
int ret = ospi_flash_erase_sector(self->flash_base_addr + offset);
|
||||
return MP_OBJ_NEW_SMALL_INT(ret);
|
||||
}
|
||||
default:
|
||||
return mp_const_none;
|
||||
}
|
||||
}
|
||||
static MP_DEFINE_CONST_FUN_OBJ_3(alif_flash_ioctl_obj, alif_flash_ioctl);
|
||||
|
||||
static const mp_rom_map_elem_t alif_flash_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_readblocks), MP_ROM_PTR(&alif_flash_readblocks_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_writeblocks), MP_ROM_PTR(&alif_flash_writeblocks_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_ioctl), MP_ROM_PTR(&alif_flash_ioctl_obj) },
|
||||
};
|
||||
static MP_DEFINE_CONST_DICT(alif_flash_locals_dict, alif_flash_locals_dict_table);
|
||||
|
||||
MP_DEFINE_CONST_OBJ_TYPE(
|
||||
alif_flash_type,
|
||||
MP_QSTR_Flash,
|
||||
MP_TYPE_FLAG_NONE,
|
||||
make_new, alif_flash_make_new,
|
||||
locals_dict, &alif_flash_locals_dict
|
||||
);
|
||||
5
ports/alif/boards/manifest.py
Normal file
5
ports/alif/boards/manifest.py
Normal file
@@ -0,0 +1,5 @@
|
||||
freeze("$(PORT_DIR)/modules")
|
||||
include("$(MPY_DIR)/extmod/asyncio")
|
||||
require("dht")
|
||||
require("neopixel")
|
||||
require("onewire")
|
||||
38
ports/alif/fatfs_port.c
Normal file
38
ports/alif/fatfs_port.c
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2024 OpenMV LLC.
|
||||
*
|
||||
* 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 "lib/oofatfs/ff.h"
|
||||
|
||||
DWORD get_fattime(void) {
|
||||
// TODO
|
||||
int year = 2024;
|
||||
int month = 1;
|
||||
int day = 1;
|
||||
int hour = 0;
|
||||
int min = 0;
|
||||
int sec = 0;
|
||||
return ((year - 1980) << 25) | (month << 21) | (day << 16) | (hour << 11) | (min << 5) | (sec / 2);
|
||||
}
|
||||
84
ports/alif/irq.h
Normal file
84
ports/alif/irq.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013-2023 Damien P. George
|
||||
* Copyright (c) 2024 OpenMV LLC.
|
||||
*
|
||||
* 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_ALIF_IRQ_H
|
||||
#define MICROPY_INCLUDED_ALIF_IRQ_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include ALIF_CMSIS_H
|
||||
|
||||
// IRQ priority definitions.
|
||||
//
|
||||
// The M55-HP CPU has __NVIC_PRIO_BITS==8 bits for setting the IRQ priority.
|
||||
// It uses NVIC_SetPriorityGrouping(0) which is 7 bits for preempt priority
|
||||
// and 1 bit for the sub-priority.
|
||||
//
|
||||
// Lower number implies higher interrupt priority.
|
||||
|
||||
#define NVIC_PRIORITYGROUP_7 ((uint32_t)0x00000000U)
|
||||
#define IRQ_PRI_SYSTEM_TICK NVIC_EncodePriority(NVIC_PRIORITYGROUP_7, 0, 0)
|
||||
#define IRQ_PRI_QUIET_TIMING NVIC_EncodePriority(NVIC_PRIORITYGROUP_7, 1, 0)
|
||||
#define IRQ_PRI_UART_REPL NVIC_EncodePriority(NVIC_PRIORITYGROUP_7, 1, 0)
|
||||
#define IRQ_PRI_USB NVIC_EncodePriority(NVIC_PRIORITYGROUP_7, 5, 0)
|
||||
#define IRQ_PRI_PENDSV NVIC_EncodePriority(NVIC_PRIORITYGROUP_7, 127, 0)
|
||||
|
||||
// these states correspond to values from query_irq, enable_irq and disable_irq
|
||||
#define IRQ_STATE_DISABLED (0x00000001)
|
||||
#define IRQ_STATE_ENABLED (0x00000000)
|
||||
|
||||
static inline uint32_t query_irq(void) {
|
||||
return __get_PRIMASK();
|
||||
}
|
||||
|
||||
static inline void enable_irq(uint32_t state) {
|
||||
__set_PRIMASK(state);
|
||||
}
|
||||
|
||||
static inline uint32_t disable_irq(void) {
|
||||
uint32_t state = __get_PRIMASK();
|
||||
__disable_irq();
|
||||
return state;
|
||||
}
|
||||
|
||||
// irqs with a priority value greater or equal to "pri" will be disabled
|
||||
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);
|
||||
}
|
||||
|
||||
#endif // MICROPY_INCLUDED_ALIF_IRQ_H
|
||||
298
ports/alif/machine_pin.c
Normal file
298
ports/alif/machine_pin.c
Normal file
@@ -0,0 +1,298 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2024 OpenMV LLC.
|
||||
*
|
||||
* 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 "extmod/modmachine.h"
|
||||
#include "extmod/virtpin.h"
|
||||
#include "shared/runtime/mpirq.h"
|
||||
|
||||
extern const mp_obj_dict_t machine_pin_cpu_pins_locals_dict;
|
||||
extern const mp_obj_dict_t machine_pin_board_pins_locals_dict;
|
||||
|
||||
static const machine_pin_obj_t *machine_pin_find_named(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 != NULL) {
|
||||
return MP_OBJ_TO_PTR(named_elem->value);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const machine_pin_obj_t *machine_pin_find(mp_obj_t pin) {
|
||||
// Is already a object of the proper type
|
||||
if (mp_obj_is_type(pin, &machine_pin_type)) {
|
||||
return MP_OBJ_TO_PTR(pin);
|
||||
}
|
||||
if (mp_obj_is_str(pin)) {
|
||||
// Try to find the pin in the board pins first.
|
||||
const machine_pin_obj_t *self = machine_pin_find_named(&machine_pin_board_pins_locals_dict, pin);
|
||||
if (self != NULL) {
|
||||
return self;
|
||||
}
|
||||
|
||||
// If not found, try to find the pin in the cpu pins.
|
||||
self = machine_pin_find_named(&machine_pin_cpu_pins_locals_dict, pin);
|
||||
if (self != NULL) {
|
||||
return self;
|
||||
}
|
||||
|
||||
// Pin name not found.
|
||||
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("unknown named pin \"%s\""), mp_obj_str_get_str(pin));
|
||||
}
|
||||
mp_raise_ValueError(MP_ERROR_TEXT("invalid pin"));
|
||||
}
|
||||
|
||||
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 = self_in;
|
||||
|
||||
uint8_t alt_func, pad_ctrl;
|
||||
pinconf_get(self->port, self->pin, &alt_func, &pad_ctrl);
|
||||
|
||||
qstr mode_qst;
|
||||
if (gpio_get_direction(self->gpio, self->pin) == GPIO_PIN_DIR_INPUT) {
|
||||
mode_qst = MP_QSTR_IN;
|
||||
} else {
|
||||
if (pad_ctrl & PADCTRL_DRIVER_OPEN_DRAIN) {
|
||||
mode_qst = MP_QSTR_OPEN_DRAIN;
|
||||
} else {
|
||||
mode_qst = MP_QSTR_OUT;
|
||||
}
|
||||
}
|
||||
mp_printf(print, "Pin(%q, mode=%q", self->name, mode_qst);
|
||||
uint8_t pad_ctrl_pull = pad_ctrl & (PADCTRL_DRIVER_DISABLED_PULL_DOWN | PADCTRL_DRIVER_DISABLED_PULL_UP);
|
||||
if (pad_ctrl_pull == PADCTRL_DRIVER_DISABLED_PULL_UP) {
|
||||
mp_printf(print, ", pull=%q", MP_QSTR_PULL_UP);
|
||||
} else if (pad_ctrl_pull == PADCTRL_DRIVER_DISABLED_PULL_DOWN) {
|
||||
mp_printf(print, ", pull=%q", MP_QSTR_PULL_DOWN);
|
||||
}
|
||||
if (alt_func != PINMUX_ALTERNATE_FUNCTION_0) {
|
||||
mp_printf(print, ", alt=%u", alt_func);
|
||||
}
|
||||
mp_printf(print, ")");
|
||||
}
|
||||
|
||||
enum {
|
||||
ARG_mode, ARG_pull, ARG_value, 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_alt, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0}},
|
||||
};
|
||||
|
||||
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) {
|
||||
|
||||
// parse args
|
||||
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);
|
||||
|
||||
// get initial value of pin (only valid for OUT and OPEN_DRAIN modes)
|
||||
int value = -1;
|
||||
if (args[ARG_value].u_obj != mp_const_none) {
|
||||
value = mp_obj_is_true(args[ARG_value].u_obj);
|
||||
}
|
||||
|
||||
// configure mode
|
||||
if (args[ARG_mode].u_obj != mp_const_none) {
|
||||
mp_int_t mode = mp_obj_get_int(args[ARG_mode].u_obj);
|
||||
if (mode == MP_HAL_PIN_MODE_INPUT) {
|
||||
mp_hal_pin_input(self);
|
||||
} else if (mode == MP_HAL_PIN_MODE_OUTPUT) {
|
||||
if (value != -1) {
|
||||
// set initial output value before configuring mode
|
||||
mp_hal_pin_write(self, value);
|
||||
}
|
||||
mp_hal_pin_output(self);
|
||||
} else if (mode == MP_HAL_PIN_MODE_OPEN_DRAIN) {
|
||||
if (value != -1) {
|
||||
// set initial output value before configuring mode
|
||||
mp_hal_pin_write(self, value);
|
||||
}
|
||||
mp_hal_pin_open_drain(self);
|
||||
}
|
||||
}
|
||||
|
||||
// Configure pull (unconditionally because None means no-pull).
|
||||
uint32_t pull = 0;
|
||||
if (args[ARG_pull].u_obj != mp_const_none) {
|
||||
pull = mp_obj_get_int(args[ARG_pull].u_obj);
|
||||
}
|
||||
uint8_t alt_func;
|
||||
uint8_t pad_ctrl;
|
||||
pinconf_get(self->port, self->pin, &alt_func, &pad_ctrl);
|
||||
alt_func = PINMUX_ALTERNATE_FUNCTION_0;
|
||||
pad_ctrl |= PADCTRL_READ_ENABLE;
|
||||
pad_ctrl &= ~(PADCTRL_DRIVER_DISABLED_PULL_DOWN | PADCTRL_DRIVER_DISABLED_PULL_UP);
|
||||
if (pull & MP_HAL_PIN_PULL_UP) {
|
||||
pad_ctrl |= PADCTRL_DRIVER_DISABLED_PULL_UP;
|
||||
}
|
||||
if (pull & MP_HAL_PIN_PULL_DOWN) {
|
||||
pad_ctrl |= PADCTRL_DRIVER_DISABLED_PULL_DOWN;
|
||||
}
|
||||
pinconf_set(self->port, self->pin, alt_func, pad_ctrl);
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
// constructor(id, ...)
|
||||
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);
|
||||
|
||||
const machine_pin_obj_t *self = machine_pin_find(args[0]);
|
||||
|
||||
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(self, n_args - 1, args + 1, &kw_args);
|
||||
}
|
||||
return MP_OBJ_FROM_PTR(self);
|
||||
}
|
||||
|
||||
// fast method for getting/setting pin value
|
||||
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 = self_in;
|
||||
if (n_args == 0) {
|
||||
// get pin
|
||||
return MP_OBJ_NEW_SMALL_INT(mp_hal_pin_read(self));
|
||||
} else {
|
||||
// set pin
|
||||
bool value = mp_obj_is_true(args[0]);
|
||||
mp_hal_pin_write(self, value);
|
||||
return mp_const_none;
|
||||
}
|
||||
}
|
||||
|
||||
// pin.init(mode, pull)
|
||||
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);
|
||||
|
||||
// pin.value([value])
|
||||
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);
|
||||
|
||||
// pin.low()
|
||||
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);
|
||||
|
||||
// pin.high()
|
||||
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);
|
||||
|
||||
// pin.toggle()
|
||||
static mp_obj_t machine_pin_toggle(mp_obj_t self_in) {
|
||||
machine_pin_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
gpio_toggle_value(self->gpio, self->pin);
|
||||
return mp_const_none;
|
||||
}
|
||||
static MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_toggle_obj, machine_pin_toggle);
|
||||
|
||||
static MP_DEFINE_CONST_OBJ_TYPE(
|
||||
pin_cpu_pins_obj_type,
|
||||
MP_QSTR_cpu,
|
||||
MP_TYPE_FLAG_NONE,
|
||||
locals_dict, &machine_pin_cpu_pins_locals_dict
|
||||
);
|
||||
|
||||
static MP_DEFINE_CONST_OBJ_TYPE(
|
||||
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_low), MP_ROM_PTR(&machine_pin_low_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_high), MP_ROM_PTR(&machine_pin_high_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_off), 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_toggle), MP_ROM_PTR(&machine_pin_toggle_obj) },
|
||||
|
||||
// class attributes
|
||||
{ MP_ROM_QSTR(MP_QSTR_board), MP_ROM_PTR(&pin_board_pins_obj_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_cpu), MP_ROM_PTR(&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_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) },
|
||||
};
|
||||
static MP_DEFINE_CONST_DICT(machine_pin_locals_dict, machine_pin_locals_dict_table);
|
||||
|
||||
static mp_uint_t pin_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) {
|
||||
(void)errcode;
|
||||
machine_pin_obj_t *self = self_in;
|
||||
|
||||
switch (request) {
|
||||
case MP_PIN_READ: {
|
||||
return mp_hal_pin_read(self);
|
||||
}
|
||||
case MP_PIN_WRITE: {
|
||||
mp_hal_pin_write(self, arg);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const mp_pin_p_t pin_pin_p = {
|
||||
.ioctl = pin_ioctl,
|
||||
};
|
||||
|
||||
MP_DEFINE_CONST_OBJ_TYPE(
|
||||
machine_pin_type,
|
||||
MP_QSTR_Pin,
|
||||
MP_TYPE_FLAG_NONE,
|
||||
make_new, mp_pin_make_new,
|
||||
print, machine_pin_print,
|
||||
call, machine_pin_call,
|
||||
protocol, &pin_pin_p,
|
||||
locals_dict, &machine_pin_locals_dict
|
||||
);
|
||||
|
||||
mp_hal_pin_obj_t mp_hal_get_pin_obj(mp_obj_t obj) {
|
||||
return machine_pin_find(obj);
|
||||
}
|
||||
145
ports/alif/main.c
Normal file
145
ports/alif/main.c
Normal file
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2024 OpenMV LLC.
|
||||
*
|
||||
* 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/mphal.h"
|
||||
#include "py/stackctrl.h"
|
||||
#include "shared/readline/readline.h"
|
||||
#include "shared/runtime/gchelper.h"
|
||||
#include "shared/runtime/pyexec.h"
|
||||
#include "shared/tinyusb/mp_usbd.h"
|
||||
#include "tusb.h"
|
||||
#include "mpuart.h"
|
||||
#include "ospi_flash.h"
|
||||
#include "pendsv.h"
|
||||
|
||||
extern uint8_t __StackTop, __StackLimit;
|
||||
extern uint8_t __GcHeapStart, __GcHeapEnd;
|
||||
|
||||
NORETURN void panic(const char *msg) {
|
||||
mp_hal_stdout_tx_strn("\nFATAL ERROR:\n", 14);
|
||||
mp_hal_stdout_tx_strn(msg, strlen(msg));
|
||||
for (;;) {
|
||||
*(volatile uint32_t *)0x4900C000 ^= 9;
|
||||
for (volatile uint delay = 0; delay < 10000000; delay++) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _start(void) {
|
||||
SysTick_Config(SystemCoreClock / 1000);
|
||||
|
||||
MICROPY_BOARD_STARTUP();
|
||||
|
||||
pendsv_init();
|
||||
|
||||
MICROPY_BOARD_EARLY_INIT();
|
||||
|
||||
#if MICROPY_HW_ENABLE_UART_REPL
|
||||
mp_uart_init();
|
||||
#endif
|
||||
|
||||
if (ospi_flash_init() != 0) {
|
||||
MICROPY_BOARD_FATAL_ERROR("ospi_init failed");
|
||||
}
|
||||
|
||||
#if MICROPY_HW_ENABLE_USBDEV
|
||||
NVIC_ClearPendingIRQ(USB_IRQ_IRQn);
|
||||
NVIC_SetPriority(USB_IRQ_IRQn, IRQ_PRI_USB);
|
||||
#endif
|
||||
|
||||
// Initialise stack extents and GC heap.
|
||||
mp_stack_set_top(&__StackTop);
|
||||
mp_stack_set_limit(&__StackTop - &__StackLimit - 1024);
|
||||
gc_init(&__GcHeapStart, &__GcHeapEnd);
|
||||
|
||||
for (;;) {
|
||||
// Initialise MicroPython runtime.
|
||||
mp_init();
|
||||
|
||||
// Initialise sub-systems.
|
||||
readline_init0();
|
||||
|
||||
// Execute _boot.py to set up the filesystem.
|
||||
pyexec_frozen_module("_boot.py", false);
|
||||
|
||||
// Execute user scripts.
|
||||
int ret = pyexec_file_if_exists("boot.py");
|
||||
#if MICROPY_HW_ENABLE_USBDEV
|
||||
mp_usbd_init();
|
||||
#endif
|
||||
if (ret & PYEXEC_FORCED_EXIT) {
|
||||
goto soft_reset_exit;
|
||||
}
|
||||
if (pyexec_mode_kind == PYEXEC_MODE_FRIENDLY_REPL && ret != 0) {
|
||||
ret = pyexec_file_if_exists("main.py");
|
||||
if (ret & PYEXEC_FORCED_EXIT) {
|
||||
goto soft_reset_exit;
|
||||
}
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) {
|
||||
if (pyexec_raw_repl() != 0) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (pyexec_friendly_repl() != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
soft_reset_exit:
|
||||
mp_printf(MP_PYTHON_PRINTER, "MPY: soft reboot\n");
|
||||
gc_sweep_all();
|
||||
mp_deinit();
|
||||
}
|
||||
}
|
||||
|
||||
void gc_collect(void) {
|
||||
gc_collect_start();
|
||||
gc_helper_collect_regs_and_stack();
|
||||
gc_collect_end();
|
||||
}
|
||||
|
||||
void nlr_jump_fail(void *val) {
|
||||
mp_printf(&mp_plat_print, "FATAL: uncaught exception %p\n", val);
|
||||
mp_obj_print_exception(&mp_plat_print, MP_OBJ_FROM_PTR(val));
|
||||
for (;;) {
|
||||
__WFE();
|
||||
}
|
||||
}
|
||||
|
||||
#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);
|
||||
panic("Assertion failed");
|
||||
}
|
||||
#endif
|
||||
14
ports/alif/mcu/M55_HP_cfg.json
Normal file
14
ports/alif/mcu/M55_HP_cfg.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"USER_APP": {
|
||||
"binary": "firmware.bin",
|
||||
"mramAddress": "0x80000000",
|
||||
"version": "1.0.0",
|
||||
"cpu_id": "M55_HP",
|
||||
"flags": ["boot"],
|
||||
"signed": false
|
||||
},
|
||||
"DEVICE": {
|
||||
"binary": "app-device-config.json",
|
||||
"version" : "0.5.00"
|
||||
}
|
||||
}
|
||||
165
ports/alif/mcu/ensemble.ld.S
Normal file
165
ports/alif/mcu/ensemble.ld.S
Normal file
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2023 OpenMV LLC.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// Entry Point
|
||||
ENTRY(Reset_Handler)
|
||||
|
||||
MEMORY
|
||||
{
|
||||
ROM (rx) : ORIGIN = 0x80000000, LENGTH = 0x0057F000
|
||||
ITCM (rwx) : ORIGIN = 0x00000000, LENGTH = 0x00040000
|
||||
#ifdef CORE_M55_HP
|
||||
DTCM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00100000
|
||||
#else
|
||||
DTCM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00040000
|
||||
#endif
|
||||
SRAM0 (rwx) : ORIGIN = 0x02000000, LENGTH = 0x00400000
|
||||
SRAM1 (rwx) : ORIGIN = 0x08000000, LENGTH = 0x00280000
|
||||
}
|
||||
|
||||
__STACK_SIZE = 0x00004000;
|
||||
__HEAP_SIZE = 0x00004000;
|
||||
__MP_HEAP_SIZE = 0x00040000;
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text : ALIGN(16)
|
||||
{
|
||||
KEEP(*(.vectors))
|
||||
. = ALIGN(4);
|
||||
*(.text*)
|
||||
. = ALIGN(4);
|
||||
*(.rodata*)
|
||||
. = ALIGN(16);
|
||||
} > ROM
|
||||
|
||||
.copy.table : ALIGN(4)
|
||||
{
|
||||
__copy_table_start__ = .;
|
||||
LONG ( LOADADDR(.data) )
|
||||
LONG ( ADDR(.data) )
|
||||
LONG ( SIZEOF(.data)/4 )
|
||||
__copy_table_end__ = .;
|
||||
. = ALIGN(16);
|
||||
} > ROM
|
||||
|
||||
.zero.table : ALIGN(4)
|
||||
{
|
||||
__zero_table_start__ = .;
|
||||
LONG (ADDR(.bss))
|
||||
LONG (SIZEOF(.bss)/4)
|
||||
LONG (ADDR(.bss.sram0))
|
||||
LONG (SIZEOF(.bss.sram0)/4)
|
||||
__zero_table_end__ = .;
|
||||
. = ALIGN(16);
|
||||
} > ROM
|
||||
|
||||
.data : ALIGN(8)
|
||||
{
|
||||
*(.data)
|
||||
. = ALIGN(8);
|
||||
*(.data.*)
|
||||
. = ALIGN(16);
|
||||
} > DTCM AT > ROM
|
||||
|
||||
/* Peripherals in expansion master 0 (USB, Ethernet, SD/MMC)
|
||||
are by default configured as non-secure, so they don't
|
||||
have access to DTCMs. This can be fixed in the ToC by allowing
|
||||
access to DTCMs to all bus masters, for now these peripherals
|
||||
should place buffers in regular SRAM */
|
||||
.bss.sram0 (NOLOAD) : ALIGN(4)
|
||||
{
|
||||
* (.bss.sram0*)
|
||||
} > SRAM0
|
||||
|
||||
.bss : ALIGN(4)
|
||||
{
|
||||
__bss_start__ = .;
|
||||
*(.bss)
|
||||
. = ALIGN(4);
|
||||
*(.bss.*)
|
||||
. = ALIGN(4);
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
__bss_end__ = .;
|
||||
} > DTCM
|
||||
|
||||
.heap (NOLOAD) : ALIGN(4)
|
||||
{
|
||||
__end__ = .;
|
||||
PROVIDE(end = .);
|
||||
. = . + __HEAP_SIZE;
|
||||
. = ALIGN(4);
|
||||
__HeapLimit = .;
|
||||
|
||||
/* MicroPython GC heap */
|
||||
. = ALIGN(16);
|
||||
__GcHeapStart = .;
|
||||
. = . + __MP_HEAP_SIZE;
|
||||
__GcHeapEnd = .;
|
||||
} > DTCM
|
||||
|
||||
.stack (NOLOAD) : ALIGN(4)
|
||||
{
|
||||
__StackLimit = .;
|
||||
. = . + __STACK_SIZE;
|
||||
. = ALIGN(4);
|
||||
__StackTop = .;
|
||||
} > DTCM
|
||||
PROVIDE(__stack = __StackTop);
|
||||
|
||||
.init_fini_arrays : ALIGN(16)
|
||||
{
|
||||
KEEP(*(.init))
|
||||
KEEP(*(.fini))
|
||||
|
||||
. = ALIGN(4);
|
||||
/* preinit data */
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP(*(.preinit_array))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
|
||||
. = ALIGN(4);
|
||||
/* init data */
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
KEEP(*(SORT(.init_array.*)))
|
||||
KEEP(*(.init_array))
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
|
||||
. = ALIGN(4);
|
||||
/* finit data */
|
||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||
KEEP(*(SORT(.fini_array.*)))
|
||||
KEEP(*(.fini_array))
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
|
||||
KEEP(*(.eh_frame*))
|
||||
. = ALIGN(16);
|
||||
} > ROM
|
||||
|
||||
/* Check if data + heap + stack exceeds RAM limit */
|
||||
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
|
||||
}
|
||||
64
ports/alif/mcu/make-pins.py
Executable file
64
ports/alif/mcu/make-pins.py
Executable file
@@ -0,0 +1,64 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "../../../tools"))
|
||||
import boardgen
|
||||
|
||||
NUM_PORTS = 16
|
||||
NUM_PINS_PER_PORT = 8
|
||||
|
||||
|
||||
class AlifPin(boardgen.Pin):
|
||||
# Emit the struct which contains the pin instance.
|
||||
def definition(self):
|
||||
port, pin = self.name()[1:].split("_")
|
||||
base = "LPGPIO_BASE" if port == "15" else "GPIO{}_BASE".format(port)
|
||||
return (
|
||||
"{{ "
|
||||
".base = {{ .type = &machine_pin_type }}, "
|
||||
".gpio = (GPIO_Type *){base}, "
|
||||
".port = PORT_{port}, "
|
||||
".pin = PIN_{pin}, "
|
||||
".name = MP_QSTR_P{port}_{pin} "
|
||||
"}}".format(port=port, pin=pin, base=base)
|
||||
)
|
||||
|
||||
# Alif cpu names must be "Pn_m".
|
||||
@staticmethod
|
||||
def validate_cpu_pin_name(cpu_pin_name):
|
||||
boardgen.Pin.validate_cpu_pin_name(cpu_pin_name)
|
||||
|
||||
if not (m := re.match("P([0-9]){1,2}_([0-9])", cpu_pin_name)):
|
||||
raise boardgen.PinGeneratorError(
|
||||
"Invalid cpu pin name '{}', must be 'Pn_m'".format(cpu_pin_name)
|
||||
)
|
||||
|
||||
port = int(m.group(1))
|
||||
pin = int(m.group(2))
|
||||
if not (0 <= port < NUM_PORTS and 0 <= pin < NUM_PINS_PER_PORT):
|
||||
raise boardgen.PinGeneratorError("Unknown cpu pin '{}'".format(cpu_pin_name))
|
||||
|
||||
|
||||
class AlifPinGenerator(boardgen.PinGenerator):
|
||||
def __init__(self):
|
||||
# Use custom pin type above.
|
||||
super().__init__(pin_type=AlifPin)
|
||||
|
||||
# Pre-define the pins (i.e. don't require them to be listed in pins.csv).
|
||||
for i in range(NUM_PORTS):
|
||||
for j in range(NUM_PINS_PER_PORT):
|
||||
self.add_cpu_pin("P{}_{}".format(i, j))
|
||||
|
||||
# Only use pre-defined cpu pins (do not let board.csv create them).
|
||||
def find_pin_by_cpu_pin_name(self, cpu_pin_name, create=True):
|
||||
return super().find_pin_by_cpu_pin_name(cpu_pin_name, create=False)
|
||||
|
||||
def cpu_table_size(self):
|
||||
return "{} * {}".format(NUM_PORTS, NUM_PINS_PER_PORT)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
AlifPinGenerator().main()
|
||||
2
ports/alif/mcu/pins_prefix.c
Normal file
2
ports/alif/mcu/pins_prefix.c
Normal file
@@ -0,0 +1,2 @@
|
||||
#include "py/mphal.h"
|
||||
#include "extmod/modmachine.h"
|
||||
46
ports/alif/modalif.c
Normal file
46
ports/alif/modalif.c
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2024 OpenMV LLC.
|
||||
*
|
||||
* 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/mphal.h"
|
||||
#include "py/runtime.h"
|
||||
#include "modalif.h"
|
||||
|
||||
static const mp_rom_map_elem_t alif_module_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_alif) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_Flash), MP_ROM_PTR(&alif_flash_type) },
|
||||
#if MICROPY_HW_USB_MSC
|
||||
// Attribute to indicate USB MSC is enabled.
|
||||
{ MP_ROM_QSTR(MP_QSTR_usb_msc), MP_ROM_TRUE },
|
||||
#endif
|
||||
};
|
||||
static MP_DEFINE_CONST_DICT(alif_module_globals, alif_module_globals_table);
|
||||
|
||||
const mp_obj_module_t mp_module_alif = {
|
||||
.base = { &mp_type_module },
|
||||
.globals = (mp_obj_dict_t *)&alif_module_globals,
|
||||
};
|
||||
|
||||
MP_REGISTER_MODULE(MP_QSTR_alif, mp_module_alif);
|
||||
33
ports/alif/modalif.h
Normal file
33
ports/alif/modalif.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2024 OpenMV LLC.
|
||||
*
|
||||
* 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_ALIF_MODALIF_H
|
||||
#define MICROPY_INCLUDED_ALIF_MODALIF_H
|
||||
|
||||
#include "py/obj.h"
|
||||
|
||||
extern const mp_obj_type_t alif_flash_type;
|
||||
|
||||
#endif // MICROPY_INCLUDED_ALIF_MODALIF_H
|
||||
79
ports/alif/modmachine.c
Normal file
79
ports/alif/modmachine.c
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2024 OpenMV LLC.
|
||||
*
|
||||
* 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) }, \
|
||||
|
||||
static void mp_machine_idle(void) {
|
||||
mp_event_wait_indefinite();
|
||||
}
|
||||
|
||||
static mp_obj_t mp_machine_unique_id(void) {
|
||||
return mp_obj_new_bytes((const uint8_t *)"ABCD", 4);
|
||||
}
|
||||
|
||||
NORETURN static void mp_machine_reset(void) {
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
NORETURN void mp_machine_bootloader(size_t n_args, const mp_obj_t *args) {
|
||||
__disable_irq();
|
||||
|
||||
MICROPY_BOARD_ENTER_BOOTLOADER(n_args, args);
|
||||
|
||||
while (1) {
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
static mp_int_t mp_machine_reset_cause(void) {
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
static mp_obj_t mp_machine_get_freq(void) {
|
||||
return MP_OBJ_NEW_SMALL_INT(SystemCoreClock);
|
||||
}
|
||||
|
||||
static void mp_machine_set_freq(size_t n_args, const mp_obj_t *args) {
|
||||
mp_raise_NotImplementedError(NULL);
|
||||
}
|
||||
|
||||
static void mp_machine_lightsleep(size_t n_args, const mp_obj_t *args) {
|
||||
mp_int_t delay = -1;
|
||||
if (n_args == 1) {
|
||||
delay = mp_obj_get_int(args[0]);
|
||||
}
|
||||
mp_hal_delay_ms(delay);
|
||||
}
|
||||
|
||||
NORETURN static void mp_machine_deepsleep(size_t n_args, const mp_obj_t *args) {
|
||||
mp_machine_lightsleep(n_args, args);
|
||||
mp_machine_reset();
|
||||
}
|
||||
23
ports/alif/modules/_boot.py
Normal file
23
ports/alif/modules/_boot.py
Normal file
@@ -0,0 +1,23 @@
|
||||
import sys, os, alif
|
||||
|
||||
|
||||
bdev = alif.Flash()
|
||||
if hasattr(alif, "usb_msc"):
|
||||
try:
|
||||
# This may fail on VfsFat construction, or mount.
|
||||
os.mount(os.VfsFat(bdev), "/flash")
|
||||
except:
|
||||
os.VfsFat.mkfs(bdev)
|
||||
os.mount(os.VfsFat(bdev), "/flash")
|
||||
else:
|
||||
try:
|
||||
os.mount(os.VfsLfs2(bdev, progsize=256), "/flash")
|
||||
except:
|
||||
os.VfsLfs2.mkfs(bdev, progsize=256)
|
||||
os.mount(os.VfsLfs2(bdev, progsize=256), "/flash")
|
||||
|
||||
sys.path.append("/flash")
|
||||
sys.path.append("/flash/lib")
|
||||
os.chdir("/flash")
|
||||
|
||||
del sys, os, alif, bdev
|
||||
155
ports/alif/mpconfigport.h
Normal file
155
ports/alif/mpconfigport.h
Normal file
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2024 OpenMV LLC.
|
||||
*
|
||||
* 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
|
||||
|
||||
#include <stdint.h>
|
||||
#include <alloca.h> // for alloca()
|
||||
|
||||
// board specific definitions
|
||||
#include "mpconfigboard.h"
|
||||
|
||||
#ifndef MICROPY_CONFIG_ROM_LEVEL
|
||||
#define MICROPY_CONFIG_ROM_LEVEL (MICROPY_CONFIG_ROM_LEVEL_FULL_FEATURES)
|
||||
#endif
|
||||
|
||||
#define MICROPY_HW_ENABLE_UART_REPL (1) // useful if there is no USB
|
||||
#define MICROPY_HW_ENABLE_USBDEV (1)
|
||||
|
||||
#ifndef MICROPY_HW_USB_PRODUCT_FS_STRING
|
||||
#define MICROPY_HW_USB_PRODUCT_FS_STRING "Board in HS mode"
|
||||
#endif
|
||||
#define MICROPY_HW_USB_CDC (1)
|
||||
#define MICROPY_HW_USB_CDC_TX_TIMEOUT (500)
|
||||
#ifndef MICROPY_HW_USB_MSC
|
||||
#define MICROPY_HW_USB_MSC (0)
|
||||
#endif
|
||||
#ifndef MICROPY_HW_USB_VID
|
||||
#define MICROPY_HW_USB_VID (0xf055)
|
||||
#endif
|
||||
#ifndef MICROPY_HW_USB_PID
|
||||
#define MICROPY_HW_USB_PID (0x9802) // interface has CDC only
|
||||
#endif
|
||||
|
||||
#define MICROPY_HW_FLASH_BLOCK_SIZE_BYTES (4096)
|
||||
|
||||
// Memory allocation policies
|
||||
#ifndef MICROPY_ALLOC_GC_STACK_SIZE
|
||||
#define MICROPY_ALLOC_GC_STACK_SIZE (128)
|
||||
#endif
|
||||
#define MICROPY_ALLOC_PATH_MAX (128)
|
||||
#define MICROPY_QSTR_BYTES_IN_HASH (1)
|
||||
|
||||
// MicroPython emitters
|
||||
#define MICROPY_PERSISTENT_CODE_LOAD (1)
|
||||
#define MICROPY_EMIT_THUMB (1)
|
||||
#define MICROPY_EMIT_THUMB_ARMV7M (1)
|
||||
#define MICROPY_EMIT_INLINE_THUMB (1)
|
||||
#define MICROPY_EMIT_INLINE_THUMB_FLOAT (1)
|
||||
|
||||
// Optimisations
|
||||
#define MICROPY_OPT_COMPUTED_GOTO (1)
|
||||
|
||||
// Python internal features
|
||||
#define MICROPY_READER_VFS (1)
|
||||
#define MICROPY_ENABLE_GC (1)
|
||||
#define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF (1)
|
||||
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ)
|
||||
#define MICROPY_SCHEDULER_DEPTH (8)
|
||||
#define MICROPY_SCHEDULER_STATIC_NODES (1)
|
||||
#define MICROPY_USE_INTERNAL_ERRNO (1)
|
||||
|
||||
// Fine control over Python builtins, classes, modules, etc
|
||||
#define MICROPY_PY_SYS_PLATFORM "alif"
|
||||
|
||||
// Extended modules
|
||||
#define MICROPY_EPOCH_IS_1970 (1)
|
||||
#define MICROPY_PY_OS_DUPTERM (1)
|
||||
#define MICROPY_PY_OS_SEP (1)
|
||||
#define MICROPY_PY_OS_SYNC (1)
|
||||
#define MICROPY_PY_OS_UNAME (1)
|
||||
#define MICROPY_PY_TIME (1)
|
||||
#define MICROPY_PY_MACHINE (1)
|
||||
#define MICROPY_PY_MACHINE_INCLUDEFILE "ports/alif/modmachine.c"
|
||||
#define MICROPY_PY_MACHINE_RESET (1)
|
||||
#define MICROPY_PY_MACHINE_BOOTLOADER (1)
|
||||
#define MICROPY_PY_MACHINE_BARE_METAL_FUNCS (1)
|
||||
#define MICROPY_PY_MACHINE_DISABLE_IRQ_ENABLE_IRQ (1)
|
||||
#define MICROPY_PY_MACHINE_DHT_READINTO (1)
|
||||
#define MICROPY_PY_MACHINE_PULSE (1)
|
||||
#define MICROPY_PY_MACHINE_SOFTI2C (1)
|
||||
#define MICROPY_PY_MACHINE_SOFTSPI (1)
|
||||
#define MICROPY_PY_MACHINE_TIMER (1)
|
||||
#define MICROPY_VFS (1)
|
||||
|
||||
// fatfs configuration
|
||||
#define MICROPY_FATFS_ENABLE_LFN (1)
|
||||
#define MICROPY_FATFS_LFN_CODE_PAGE 437 /* 1=SFN/ANSI 437=LFN/U.S.(OEM) */
|
||||
#define MICROPY_FATFS_RPATH (2)
|
||||
#if MICROPY_HW_USB_MSC
|
||||
#define MICROPY_FATFS_USE_LABEL (1)
|
||||
#define MICROPY_FATFS_MULTI_PARTITION (1)
|
||||
// Set FatFS block size to flash sector size to avoid caching
|
||||
// the flash sector in memory to support smaller block sizes.
|
||||
#define MICROPY_FATFS_MAX_SS (MICROPY_HW_FLASH_BLOCK_SIZE_BYTES)
|
||||
#endif
|
||||
|
||||
#define MP_STATE_PORT MP_STATE_VM
|
||||
|
||||
// Miscellaneous settings
|
||||
|
||||
// We need an implementation of the log2 function which is not a macro
|
||||
#define MP_NEED_LOG2 (1)
|
||||
|
||||
#define MICROPY_MAKE_POINTER_CALLABLE(p) ((void *)((mp_uint_t)(p) | 1))
|
||||
|
||||
#define MP_SSIZE_MAX (0x7fffffff)
|
||||
|
||||
// Assume that if we already defined the obj repr then we also defined these items
|
||||
#ifndef MICROPY_OBJ_REPR
|
||||
typedef intptr_t mp_int_t; // must be pointer size
|
||||
typedef uintptr_t mp_uint_t; // must be pointer size
|
||||
typedef intptr_t mp_off_t;
|
||||
#endif
|
||||
|
||||
// Board configuration settings.
|
||||
|
||||
#ifndef MICROPY_BOARD_STARTUP
|
||||
#define MICROPY_BOARD_STARTUP()
|
||||
#endif
|
||||
|
||||
#ifndef MICROPY_BOARD_EARLY_INIT
|
||||
#define MICROPY_BOARD_EARLY_INIT()
|
||||
#endif
|
||||
|
||||
#ifndef MICROPY_BOARD_FATAL_ERROR
|
||||
extern void panic(const char *);
|
||||
#define MICROPY_BOARD_FATAL_ERROR panic
|
||||
#endif
|
||||
|
||||
#ifndef MICROPY_BOARD_ENTER_BOOTLOADER
|
||||
#define MICROPY_BOARD_ENTER_BOOTLOADER(nargs, args)
|
||||
#endif
|
||||
12
ports/alif/mpconfigport.mk
Normal file
12
ports/alif/mpconfigport.mk
Normal file
@@ -0,0 +1,12 @@
|
||||
# Enable/disable extra modules and features
|
||||
|
||||
# MicroPython feature configurations
|
||||
MICROPY_ROM_TEXT_COMPRESSION ?= 1
|
||||
MICROPY_FLOAT_IMPL ?= double
|
||||
|
||||
# VFS support.
|
||||
MICROPY_VFS_FAT ?= 1
|
||||
MICROPY_VFS_LFS2 ?= 1
|
||||
|
||||
# File containing description of content to be frozen into firmware.
|
||||
FROZEN_MANIFEST ?= boards/manifest.py
|
||||
152
ports/alif/mphalport.c
Normal file
152
ports/alif/mphalport.c
Normal file
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2023 Damien P. George
|
||||
* Copyright (c) 2024 OpenMV LLC.
|
||||
*
|
||||
* 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/mphal.h"
|
||||
#include "py/ringbuf.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/stream.h"
|
||||
#include "extmod/misc.h"
|
||||
#include "shared/runtime/interrupt_char.h"
|
||||
#include "shared/timeutils/timeutils.h"
|
||||
#include "shared/tinyusb/mp_usbd.h"
|
||||
#include "shared/tinyusb/mp_usbd_cdc.h"
|
||||
#include "tusb.h"
|
||||
#include "mpuart.h"
|
||||
|
||||
#ifndef MICROPY_HW_STDIN_BUFFER_LEN
|
||||
#define MICROPY_HW_STDIN_BUFFER_LEN 512
|
||||
#endif
|
||||
|
||||
static uint8_t stdin_ringbuf_array[MICROPY_HW_STDIN_BUFFER_LEN];
|
||||
ringbuf_t stdin_ringbuf = { stdin_ringbuf_array, sizeof(stdin_ringbuf_array) };
|
||||
|
||||
uintptr_t mp_hal_stdio_poll(uintptr_t poll_flags) {
|
||||
uintptr_t ret = 0;
|
||||
#if MICROPY_HW_USB_CDC
|
||||
ret |= mp_usbd_cdc_poll_interfaces(poll_flags);
|
||||
#endif
|
||||
#if MICROPY_HW_ENABLE_UART_REPL
|
||||
if (poll_flags & MP_STREAM_POLL_WR) {
|
||||
ret |= MP_STREAM_POLL_WR;
|
||||
}
|
||||
#endif
|
||||
#if MICROPY_PY_OS_DUPTERM
|
||||
ret |= mp_os_dupterm_poll(poll_flags);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Receive single character
|
||||
int mp_hal_stdin_rx_chr(void) {
|
||||
for (;;) {
|
||||
#if MICROPY_HW_USB_CDC
|
||||
mp_usbd_cdc_poll_interfaces(0);
|
||||
#endif
|
||||
int c = ringbuf_get(&stdin_ringbuf);
|
||||
if (c != -1) {
|
||||
return c;
|
||||
}
|
||||
#if MICROPY_PY_OS_DUPTERM
|
||||
int dupterm_c = mp_os_dupterm_rx_chr();
|
||||
if (dupterm_c >= 0) {
|
||||
return dupterm_c;
|
||||
}
|
||||
#endif
|
||||
mp_event_wait_indefinite();
|
||||
}
|
||||
}
|
||||
|
||||
// Send string of given length
|
||||
mp_uint_t mp_hal_stdout_tx_strn(const char *str, size_t len) {
|
||||
mp_uint_t ret = len;
|
||||
bool did_write = false;
|
||||
|
||||
#if MICROPY_HW_ENABLE_UART_REPL
|
||||
mp_uart_write_strn(str, len);
|
||||
did_write = true;
|
||||
#endif
|
||||
|
||||
#if MICROPY_HW_USB_CDC
|
||||
mp_uint_t cdc_res = mp_usbd_cdc_tx_strn(str, len);
|
||||
if (cdc_res > 0) {
|
||||
did_write = true;
|
||||
ret = MIN(cdc_res, ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MICROPY_PY_OS_DUPTERM
|
||||
int dupterm_res = mp_os_dupterm_tx_strn(str, len);
|
||||
if (dupterm_res >= 0) {
|
||||
did_write = true;
|
||||
ret = MIN((mp_uint_t)dupterm_res, ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
return did_write ? ret : 0;
|
||||
}
|
||||
|
||||
static uint32_t volatile ticks_ms;
|
||||
|
||||
void SysTick_Handler(void) {
|
||||
++ticks_ms;
|
||||
}
|
||||
|
||||
mp_uint_t mp_hal_ticks_cpu(void) {
|
||||
if (!(DWT->CTRL & DWT_CTRL_CYCCNTENA_Msk)) {
|
||||
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
|
||||
#if defined(__CORTEX_M) && __CORTEX_M == 7
|
||||
// on Cortex-M7 we must unlock the DWT before writing to its registers
|
||||
DWT->LAR = 0xc5acce55;
|
||||
#endif
|
||||
DWT->CYCCNT = 0;
|
||||
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
|
||||
}
|
||||
return DWT->CYCCNT;
|
||||
}
|
||||
|
||||
mp_uint_t mp_hal_ticks_us(void) {
|
||||
return ticks_ms / 1000;
|
||||
}
|
||||
|
||||
mp_uint_t mp_hal_ticks_ms(void) {
|
||||
return ticks_ms;
|
||||
}
|
||||
|
||||
void mp_hal_delay_us(mp_uint_t us) {
|
||||
mp_hal_delay_ms(us / 1000);
|
||||
}
|
||||
|
||||
void mp_hal_delay_ms(mp_uint_t ms) {
|
||||
uint32_t t0 = mp_hal_ticks_ms();
|
||||
while ((mp_hal_ticks_ms() - t0) < ms) {
|
||||
__WFI();
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t mp_hal_time_ns(void) {
|
||||
return 0;
|
||||
}
|
||||
152
ports/alif/mphalport.h
Normal file
152
ports/alif/mphalport.h
Normal file
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2024 OpenMV LLC.
|
||||
*
|
||||
* 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/ringbuf.h"
|
||||
#include "shared/runtime/interrupt_char.h"
|
||||
#include "irq.h"
|
||||
#include ALIF_CMSIS_H
|
||||
|
||||
#define MICROPY_BEGIN_ATOMIC_SECTION() disable_irq()
|
||||
#define MICROPY_END_ATOMIC_SECTION(state) enable_irq(state)
|
||||
|
||||
// For regular code that wants to prevent "background tasks" from running.
|
||||
// These background tasks (LWIP, Bluetooth) run in PENDSV context.
|
||||
#define MICROPY_PY_PENDSV_ENTER uint32_t atomic_state = raise_irq_pri(IRQ_PRI_PENDSV);
|
||||
#define MICROPY_PY_PENDSV_REENTER atomic_state = raise_irq_pri(IRQ_PRI_PENDSV);
|
||||
#define MICROPY_PY_PENDSV_EXIT restore_irq_pri(atomic_state);
|
||||
|
||||
// Port level Wait-for-Event macro
|
||||
//
|
||||
// Do not use this macro directly, include py/runtime.h and
|
||||
// call mp_event_wait_indefinite() or mp_event_wait_ms(timeout)
|
||||
#define MICROPY_INTERNAL_WFE(TIMEOUT_MS) \
|
||||
do { \
|
||||
if ((TIMEOUT_MS) < 0) { \
|
||||
__WFE(); \
|
||||
} else { \
|
||||
/* TODO */ \
|
||||
__WFE(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
// TODO requires mods to py/emitglue.c for this to be picked up
|
||||
#define MP_HAL_CLEAN_DCACHE(addr, size) \
|
||||
(SCB_CleanDCache_by_Addr((uint32_t *)((uint32_t)addr & ~0x1f), \
|
||||
((uint32_t)((uint8_t *)addr + size + 0x1f) & ~0x1f) - ((uint32_t)addr & ~0x1f)))
|
||||
|
||||
extern ringbuf_t stdin_ringbuf;
|
||||
|
||||
// TODO
|
||||
#define mp_hal_quiet_timing_enter() 0
|
||||
#define mp_hal_quiet_timing_exit(x) (void)x
|
||||
#define mp_hal_delay_us_fast mp_hal_delay_us
|
||||
|
||||
/******************************************************************************/
|
||||
// C-level pin HAL
|
||||
|
||||
#include "py/obj.h"
|
||||
#include "gpio.h"
|
||||
#include "pinconf.h"
|
||||
|
||||
#define MP_HAL_PIN_FMT "%q"
|
||||
#define MP_HAL_PIN_MODE_INPUT (0)
|
||||
#define MP_HAL_PIN_MODE_OUTPUT (1)
|
||||
#define MP_HAL_PIN_MODE_OPEN_DRAIN (2)
|
||||
#define MP_HAL_PIN_PULL_NONE (0)
|
||||
#define MP_HAL_PIN_PULL_UP (1)
|
||||
#define MP_HAL_PIN_PULL_DOWN (2)
|
||||
|
||||
#define mp_hal_pin_obj_t const machine_pin_obj_t *
|
||||
|
||||
typedef struct _machine_pin_obj_t {
|
||||
mp_obj_base_t base;
|
||||
GPIO_Type *gpio;
|
||||
uint8_t port;
|
||||
uint8_t pin;
|
||||
qstr name;
|
||||
} machine_pin_obj_t;
|
||||
|
||||
mp_hal_pin_obj_t mp_hal_get_pin_obj(mp_obj_t pin_in);
|
||||
|
||||
static inline qstr mp_hal_pin_name(mp_hal_pin_obj_t pin) {
|
||||
return pin->name;
|
||||
}
|
||||
|
||||
static inline void mp_hal_pin_input(mp_hal_pin_obj_t pin) {
|
||||
uint8_t alt_func = PINMUX_ALTERNATE_FUNCTION_0;
|
||||
uint8_t pad_ctrl = PADCTRL_READ_ENABLE;
|
||||
pinconf_set(pin->port, pin->pin, alt_func, pad_ctrl);
|
||||
gpio_set_direction_input(pin->gpio, pin->pin);
|
||||
}
|
||||
|
||||
static inline void mp_hal_pin_output(mp_hal_pin_obj_t pin) {
|
||||
uint8_t alt_func = PINMUX_ALTERNATE_FUNCTION_0;
|
||||
uint8_t pad_ctrl = PADCTRL_READ_ENABLE;
|
||||
pinconf_set(pin->port, pin->pin, alt_func, pad_ctrl);
|
||||
gpio_set_direction_output(pin->gpio, pin->pin);
|
||||
}
|
||||
|
||||
static inline void mp_hal_pin_open_drain(mp_hal_pin_obj_t pin) {
|
||||
uint8_t alt_func = PINMUX_ALTERNATE_FUNCTION_0;
|
||||
uint8_t pad_ctrl = PADCTRL_DRIVER_OPEN_DRAIN | PADCTRL_READ_ENABLE;
|
||||
pinconf_set(pin->port, pin->pin, alt_func, pad_ctrl);
|
||||
gpio_set_direction_output(pin->gpio, pin->pin);
|
||||
}
|
||||
|
||||
static inline void mp_hal_pin_low(mp_hal_pin_obj_t pin) {
|
||||
gpio_set_value_low(pin->gpio, pin->pin);
|
||||
}
|
||||
|
||||
static inline void mp_hal_pin_high(mp_hal_pin_obj_t pin) {
|
||||
gpio_set_value_high(pin->gpio, pin->pin);
|
||||
}
|
||||
|
||||
static inline int mp_hal_pin_read(mp_hal_pin_obj_t pin) {
|
||||
return gpio_get_value(pin->gpio, pin->pin);
|
||||
}
|
||||
|
||||
static inline void mp_hal_pin_write(mp_hal_pin_obj_t pin, int v) {
|
||||
if (v) {
|
||||
mp_hal_pin_high(pin);
|
||||
} else {
|
||||
mp_hal_pin_low(pin);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void mp_hal_pin_od_low(mp_hal_pin_obj_t pin) {
|
||||
mp_hal_pin_low(pin);
|
||||
}
|
||||
|
||||
static inline void mp_hal_pin_od_high(mp_hal_pin_obj_t pin) {
|
||||
mp_hal_pin_high(pin);
|
||||
}
|
||||
|
||||
static inline void mp_hal_wake_main_task_from_isr(void) {
|
||||
// Defined for tinyusb support, nothing needs to be done here.
|
||||
}
|
||||
|
||||
// Include all the pin definitions.
|
||||
#include "genhdr/pins_board.h"
|
||||
113
ports/alif/mpuart.c
Normal file
113
ports/alif/mpuart.c
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2024 OpenMV LLC.
|
||||
*
|
||||
* 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"
|
||||
#include "mpuart.h"
|
||||
|
||||
#if MICROPY_HW_ENABLE_UART_REPL
|
||||
|
||||
#include "pinconf.h"
|
||||
#include "sys_ctrl_uart.h"
|
||||
#include "uart.h"
|
||||
|
||||
#define TX_PORT PORT_12
|
||||
#define TX_PIN PIN_2
|
||||
#define RX_PORT PORT_12
|
||||
#define RX_PIN PIN_1
|
||||
#define UART_ID 4
|
||||
#define UART_IRQN UART4_IRQ_IRQn
|
||||
#define UART_PTR ((UART_Type *)UART4_BASE)
|
||||
#define BAUDRATE 115200
|
||||
#define SYST_PCLK 100000000
|
||||
|
||||
static UART_TRANSFER transfer;
|
||||
|
||||
void mp_uart_init(void) {
|
||||
pinconf_set(TX_PORT, TX_PIN, PINMUX_ALTERNATE_FUNCTION_2, 0);
|
||||
pinconf_set(RX_PORT, RX_PIN, PINMUX_ALTERNATE_FUNCTION_2, PADCTRL_READ_ENABLE);
|
||||
select_uart_clock_syst_pclk(UART_ID);
|
||||
enable_uart_clock(UART_ID);
|
||||
uart_software_reset(UART_PTR);
|
||||
uart_enable_fifo(UART_PTR);
|
||||
uart_disable_tx_irq(UART_PTR);
|
||||
uart_disable_rx_irq(UART_PTR);
|
||||
uart_set_baudrate(UART_PTR, SYST_PCLK, BAUDRATE);
|
||||
uart_set_data_parity_stop_bits(UART_PTR, UART_DATA_BITS_8, UART_PARITY_NONE, UART_STOP_BITS_1);
|
||||
uart_set_flow_control(UART_PTR, UART_FLOW_CONTROL_NONE);
|
||||
NVIC_ClearPendingIRQ(UART_IRQN);
|
||||
NVIC_SetPriority(UART_IRQN, IRQ_PRI_UART_REPL);
|
||||
NVIC_EnableIRQ(UART_IRQN);
|
||||
uart_set_tx_trigger(UART_PTR, UART_TX_FIFO_EMPTY);
|
||||
uart_set_rx_trigger(UART_PTR, UART_RX_ONE_CHAR_IN_FIFO);
|
||||
uart_enable_rx_irq(UART_PTR);
|
||||
}
|
||||
|
||||
void mp_uart_write_strn(const char *str, size_t len) {
|
||||
memset(&transfer, 0, sizeof(transfer));
|
||||
transfer.tx_buf = (uint8_t *)str;
|
||||
transfer.tx_total_num = len;
|
||||
transfer.tx_curr_cnt = 0U;
|
||||
transfer.status = UART_TRANSFER_STATUS_NONE;
|
||||
|
||||
uart_enable_tx_irq(UART_PTR);
|
||||
|
||||
uint32_t start = mp_hal_ticks_ms();
|
||||
while (transfer.status == UART_TRANSFER_STATUS_NONE) {
|
||||
if (mp_hal_ticks_ms() - start > 10 * len) {
|
||||
break;
|
||||
}
|
||||
__WFE();
|
||||
}
|
||||
uart_disable_tx_irq(UART_PTR);
|
||||
}
|
||||
|
||||
void UART4_IRQHandler(void) {
|
||||
if (UART_PTR->UART_RFL) {
|
||||
for (;;) {
|
||||
uint32_t rx_fifo_available_cnt = UART_PTR->UART_RFL;
|
||||
if (rx_fifo_available_cnt == 0) {
|
||||
break;
|
||||
}
|
||||
for (uint32_t i = 0; i < rx_fifo_available_cnt; ++i) {
|
||||
int c = UART_PTR->UART_RBR;
|
||||
#if MICROPY_KBD_EXCEPTION
|
||||
if (c == mp_interrupt_char) {
|
||||
mp_sched_keyboard_interrupt();
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
ringbuf_put(&stdin_ringbuf, c);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
uart_irq_handler(UART_PTR, &transfer);
|
||||
}
|
||||
__SEV();
|
||||
}
|
||||
|
||||
#endif
|
||||
32
ports/alif/mpuart.h
Normal file
32
ports/alif/mpuart.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2024 OpenMV LLC.
|
||||
*
|
||||
* 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_ALIF2_UART_H
|
||||
#define MICROPY_INCLUDED_ALIF2_UART_H
|
||||
|
||||
void mp_uart_init(void);
|
||||
void mp_uart_write_strn(const char *str, size_t len);
|
||||
|
||||
#endif // MICROPY_INCLUDED_ALIF2_UART_H
|
||||
151
ports/alif/msc_disk.c
Normal file
151
ports/alif/msc_disk.c
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* 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 OpenMV LLC.
|
||||
*
|
||||
* 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/mpconfig.h"
|
||||
#include "py/misc.h"
|
||||
#include "ospi_flash.h"
|
||||
#include "tusb.h"
|
||||
|
||||
#if CFG_TUD_MSC
|
||||
|
||||
#if MICROPY_FATFS_MAX_SS != MICROPY_HW_FLASH_BLOCK_SIZE_BYTES
|
||||
#error MICROPY_FATFS_MAX_SS must be the same size as MICROPY_HW_FLASH_BLOCK_SIZE_BYTES
|
||||
#endif
|
||||
|
||||
#define BLOCK_SIZE (MICROPY_HW_FLASH_BLOCK_SIZE_BYTES)
|
||||
#define BLOCK_COUNT (MICROPY_HW_FLASH_STORAGE_BYTES / BLOCK_SIZE)
|
||||
#define FLASH_BASE_ADDR (MICROPY_HW_FLASH_STORAGE_BASE_ADDR)
|
||||
|
||||
static bool ejected = false;
|
||||
|
||||
// Invoked on SCSI_CMD_INQUIRY.
|
||||
// Fill vendor id, product id and revision with string up to 8, 16, 4 characters respectively.
|
||||
void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4]) {
|
||||
memcpy(vendor_id, MICROPY_HW_USB_MSC_INQUIRY_VENDOR_STRING, MIN(strlen(MICROPY_HW_USB_MSC_INQUIRY_VENDOR_STRING), 8));
|
||||
memcpy(product_id, MICROPY_HW_USB_MSC_INQUIRY_PRODUCT_STRING, MIN(strlen(MICROPY_HW_USB_MSC_INQUIRY_PRODUCT_STRING), 16));
|
||||
memcpy(product_rev, MICROPY_HW_USB_MSC_INQUIRY_REVISION_STRING, MIN(strlen(MICROPY_HW_USB_MSC_INQUIRY_REVISION_STRING), 4));
|
||||
}
|
||||
|
||||
// Invoked on Test-Unit-Ready command.
|
||||
// Return true allowing host to read/write this LUN (e.g SD card inserted).
|
||||
bool tud_msc_test_unit_ready_cb(uint8_t lun) {
|
||||
if (ejected) {
|
||||
tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x3a, 0x00);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Invoked on SCSI_CMD_READ_CAPACITY_10 and SCSI_CMD_READ_FORMAT_CAPACITY to determine the disk size.
|
||||
void tud_msc_capacity_cb(uint8_t lun, uint32_t *block_count, uint16_t *block_size) {
|
||||
*block_size = BLOCK_SIZE;
|
||||
*block_count = BLOCK_COUNT;
|
||||
}
|
||||
|
||||
// Invoked on Start-Stop-Unit command:
|
||||
// - Start = 0 : stopped power mode, if load_eject = 1 : unload disk storage
|
||||
// - Start = 1 : active mode, if load_eject = 1 : load disk storage
|
||||
bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject) {
|
||||
if (load_eject) {
|
||||
if (start) {
|
||||
// load disk storage
|
||||
ejected = false;
|
||||
} else {
|
||||
// unload disk storage
|
||||
ejected = true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Callback invoked on READ10 command.
|
||||
// Copy disk's data to buffer (up to bufsize) and return number of read bytes.
|
||||
int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void *buffer, uint32_t bufsize) {
|
||||
uint32_t addr = FLASH_BASE_ADDR + lba * BLOCK_SIZE;
|
||||
uint32_t block_count = bufsize / BLOCK_SIZE;
|
||||
int ret = ospi_flash_read(addr, block_count * BLOCK_SIZE, buffer);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
return block_count * BLOCK_SIZE;
|
||||
}
|
||||
|
||||
// Callback invoked on WRITE10 command.
|
||||
// Process data in buffer to disk's storage and return number of written bytes.
|
||||
int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t *buffer, uint32_t bufsize) {
|
||||
if (bufsize < BLOCK_SIZE) {
|
||||
// Workaround for issue with TinyUSB passing in a small buffer.
|
||||
uint32_t addr = FLASH_BASE_ADDR + lba * BLOCK_SIZE + offset;
|
||||
if (offset == 0) {
|
||||
int ret = ospi_flash_erase_sector(addr);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
int ret = ospi_flash_write(addr, bufsize, buffer);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
return bufsize;
|
||||
}
|
||||
|
||||
uint32_t addr = FLASH_BASE_ADDR + lba * BLOCK_SIZE;
|
||||
uint32_t block_count = bufsize / BLOCK_SIZE;
|
||||
for (uint32_t block = 0; block < block_count; ++block) {
|
||||
int ret = ospi_flash_erase_sector(addr);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
ret = ospi_flash_write(addr, BLOCK_SIZE, buffer);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
addr += BLOCK_SIZE;
|
||||
buffer += BLOCK_SIZE;
|
||||
}
|
||||
return block_count * BLOCK_SIZE;
|
||||
}
|
||||
|
||||
// Callback invoked on a SCSI command that's not handled by TinyUSB.
|
||||
int32_t tud_msc_scsi_cb(uint8_t lun, uint8_t const scsi_cmd[16], void *buffer, uint16_t bufsize) {
|
||||
int32_t resplen = 0;
|
||||
switch (scsi_cmd[0]) {
|
||||
case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
|
||||
// Sync the logical unit if needed.
|
||||
break;
|
||||
|
||||
default:
|
||||
// Set Sense = Invalid Command Operation
|
||||
tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00);
|
||||
// negative means error -> tinyusb could stall and/or response with failed status
|
||||
resplen = -1;
|
||||
break;
|
||||
}
|
||||
return resplen;
|
||||
}
|
||||
|
||||
#endif
|
||||
265
ports/alif/ospi_flash.c
Normal file
265
ports/alif/ospi_flash.c
Normal file
@@ -0,0 +1,265 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2024 OpenMV LLC.
|
||||
*
|
||||
* 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/mperrno.h"
|
||||
#include "py/mphal.h"
|
||||
#include "ospi_flash.h"
|
||||
|
||||
#include "ospi_drv.h"
|
||||
#include "pinconf.h"
|
||||
|
||||
#define CMD_RDSR (0x05)
|
||||
#define CMD_WREN (0x06)
|
||||
#define CMD_SEC_ERASE_32ADDR (0x21) // 4kiB sector erase with 32-bit address
|
||||
#define CMD_WRVOL (0x81)
|
||||
#define CMD_RD_DEVID (0x9f)
|
||||
|
||||
#define WAIT_SR_TIMEOUT (1000000)
|
||||
|
||||
// maximum bytes we can write in one SPI transfer
|
||||
// limited by 256 byte FIFO buffer (can't go up to 256)
|
||||
// need to use DMA to make this 256
|
||||
#define PAGE_SIZE (128)
|
||||
|
||||
#define ISSI_MODE_OCTAL_DDR_DQS (0xe7)
|
||||
|
||||
// All OSPI1 pins use the same alternate function.
|
||||
#define OSPI1_PIN_FUNCTION PINMUX_ALTERNATE_FUNCTION_1
|
||||
|
||||
typedef struct _mp_spiflash_t {
|
||||
ospi_flash_cfg_t cfg;
|
||||
} mp_spiflash_t;
|
||||
|
||||
static mp_spiflash_t global_flash;
|
||||
|
||||
// Alif version of this function can overwrite the destination buffer.
|
||||
static void ospi_recv_blocking2(ospi_flash_cfg_t *ospi_cfg, uint32_t command, uint8_t *buffer) {
|
||||
uint32_t val;
|
||||
|
||||
ospi_writel(ospi_cfg, data_reg, command);
|
||||
ospi_writel(ospi_cfg, ser, ospi_cfg->ser);
|
||||
|
||||
ospi_cfg->rx_cnt = 0;
|
||||
|
||||
while (ospi_cfg->rx_cnt < ospi_cfg->rx_req) {
|
||||
unsigned int timeout = 100000;
|
||||
while (ospi_readl(ospi_cfg, rxflr) == 0) {
|
||||
if (--timeout == 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
val = ospi_readl(ospi_cfg, data_reg);
|
||||
*buffer++ = (uint8_t)val;
|
||||
ospi_cfg->rx_cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
static int mp_spiflash_read_cmd(mp_spiflash_t *self, uint8_t cmd, size_t len, uint8_t *dest) {
|
||||
ospi_setup_read(&self->cfg, 0, len, 8);
|
||||
ospi_recv_blocking2(&self->cfg, cmd, dest);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mp_spiflash_write_cmd(mp_spiflash_t *self, uint8_t cmd) {
|
||||
ospi_setup_write(&self->cfg, 0);
|
||||
ospi_send_blocking(&self->cfg, cmd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mp_spiflash_wait_sr(mp_spiflash_t *self, uint8_t mask, uint8_t val, uint32_t timeout) {
|
||||
do {
|
||||
uint8_t sr;
|
||||
int ret = mp_spiflash_read_cmd(self, CMD_RDSR, 1, &sr);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
if ((sr & mask) == val) {
|
||||
return 0; // success
|
||||
}
|
||||
} while (timeout--);
|
||||
|
||||
return -MP_ETIMEDOUT;
|
||||
}
|
||||
|
||||
static int mp_spiflash_wait_wel1(mp_spiflash_t *self) {
|
||||
return mp_spiflash_wait_sr(self, 2, 2, WAIT_SR_TIMEOUT);
|
||||
}
|
||||
|
||||
static int mp_spiflash_wait_wip0(mp_spiflash_t *self) {
|
||||
return mp_spiflash_wait_sr(self, 1, 0, WAIT_SR_TIMEOUT);
|
||||
}
|
||||
|
||||
static uint32_t ospi_flash_read_id(mp_spiflash_t *self) {
|
||||
uint8_t buf[8];
|
||||
ospi_setup_read(&self->cfg, 0, 3, ospi_flash_settings.read_id_dummy_cycles);
|
||||
ospi_recv_blocking2(&self->cfg, CMD_RD_DEVID, buf);
|
||||
return buf[0] | buf[1] << 8 | buf[2] << 16;
|
||||
}
|
||||
|
||||
static void ospi_flash_write_reg_sdr(mp_spiflash_t *self, uint8_t cmd, uint8_t addr, uint8_t value) {
|
||||
mp_spiflash_write_cmd(self, CMD_WREN);
|
||||
ospi_setup_write_sdr(&self->cfg, 6);
|
||||
ospi_push(&self->cfg, cmd);
|
||||
ospi_push(&self->cfg, 0x00);
|
||||
ospi_push(&self->cfg, 0x00);
|
||||
ospi_push(&self->cfg, addr);
|
||||
ospi_send_blocking(&self->cfg, value);
|
||||
}
|
||||
|
||||
int ospi_flash_init(void) {
|
||||
mp_spiflash_t *self = &global_flash;
|
||||
|
||||
uint32_t pad_ctrl = PADCTRL_OUTPUT_DRIVE_STRENGTH_12MA | PADCTRL_SLEW_RATE_FAST | PADCTRL_READ_ENABLE;
|
||||
|
||||
pinconf_set(pin_OSPI1_CS->port, pin_OSPI1_CS->pin, OSPI1_PIN_FUNCTION, PADCTRL_OUTPUT_DRIVE_STRENGTH_12MA);
|
||||
pinconf_set(pin_OSPI1_SCLK->port, pin_OSPI1_SCLK->pin, OSPI1_PIN_FUNCTION, PADCTRL_OUTPUT_DRIVE_STRENGTH_12MA | PADCTRL_SLEW_RATE_FAST);
|
||||
pinconf_set(pin_OSPI1_D0->port, pin_OSPI1_D0->pin, OSPI1_PIN_FUNCTION, pad_ctrl);
|
||||
pinconf_set(pin_OSPI1_D1->port, pin_OSPI1_D1->pin, OSPI1_PIN_FUNCTION, pad_ctrl);
|
||||
pinconf_set(pin_OSPI1_D2->port, pin_OSPI1_D2->pin, OSPI1_PIN_FUNCTION, pad_ctrl);
|
||||
pinconf_set(pin_OSPI1_D3->port, pin_OSPI1_D3->pin, OSPI1_PIN_FUNCTION, pad_ctrl);
|
||||
#if defined(pin_OSPI1_D4)
|
||||
pinconf_set(pin_OSPI1_D4->port, pin_OSPI1_D4->pin, OSPI1_PIN_FUNCTION, pad_ctrl);
|
||||
pinconf_set(pin_OSPI1_D5->port, pin_OSPI1_D5->pin, OSPI1_PIN_FUNCTION, pad_ctrl);
|
||||
pinconf_set(pin_OSPI1_D6->port, pin_OSPI1_D6->pin, OSPI1_PIN_FUNCTION, pad_ctrl);
|
||||
pinconf_set(pin_OSPI1_D7->port, pin_OSPI1_D7->pin, OSPI1_PIN_FUNCTION, pad_ctrl);
|
||||
#endif
|
||||
#if defined(pin_OSPI1_RXDS)
|
||||
pinconf_set(pin_OSPI1_RXDS->port, pin_OSPI1_RXDS->pin, OSPI1_PIN_FUNCTION, pad_ctrl);
|
||||
#endif
|
||||
|
||||
#if defined(pin_OSPI1_RXDS)
|
||||
if (pin_OSPI1_RXDS->port == PORT_10 && pin_OSPI1_RXDS->pin == PIN_7) {
|
||||
// Alif: P5_6 is needed to support proper alt function selection of P10_7.
|
||||
pinconf_set(PORT_5, PIN_6, OSPI1_PIN_FUNCTION, pad_ctrl);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Reset the SPI flash.
|
||||
mp_hal_pin_output(pin_OSPI1_RESET);
|
||||
mp_hal_pin_low(pin_OSPI1_RESET);
|
||||
mp_hal_delay_us(30);
|
||||
mp_hal_pin_high(pin_OSPI1_RESET);
|
||||
|
||||
// Configure the OSPI peripheral.
|
||||
self->cfg.regs = (ssi_regs_t *)OSPI1_BASE;
|
||||
self->cfg.aes_regs = (aes_regs_t *)AES1_BASE;
|
||||
self->cfg.xip_base = (volatile void *)OSPI1_XIP_BASE;
|
||||
self->cfg.ser = 1;
|
||||
self->cfg.addrlen = 8; // 32-bit address length
|
||||
self->cfg.ospi_clock = ospi_flash_settings.freq_mhz;
|
||||
self->cfg.ddr_en = 0;
|
||||
self->cfg.wait_cycles = 0; // used only for ospi_xip_exit
|
||||
ospi_init(&self->cfg);
|
||||
|
||||
if (ospi_flash_settings.is_oct && ospi_flash_settings.is_ddr) {
|
||||
// Switch SPI flash to Octal DDR mode.
|
||||
ospi_flash_write_reg_sdr(self, CMD_WRVOL, 0x00, ISSI_MODE_OCTAL_DDR_DQS);
|
||||
self->cfg.ddr_en = 1;
|
||||
}
|
||||
|
||||
// Check the device ID.
|
||||
if (ospi_flash_read_id(self) != ospi_flash_settings.jedec_id) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ospi_flash_erase_sector(uint32_t addr) {
|
||||
mp_spiflash_t *self = &global_flash;
|
||||
|
||||
mp_spiflash_write_cmd(self, CMD_WREN);
|
||||
int ret = mp_spiflash_wait_wel1(self);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ospi_setup_write(&self->cfg, 8 /* 32-bit addr len*/);
|
||||
ospi_push(&self->cfg, CMD_SEC_ERASE_32ADDR);
|
||||
ospi_send_blocking(&self->cfg, addr);
|
||||
|
||||
return mp_spiflash_wait_wip0(self);
|
||||
}
|
||||
|
||||
int ospi_flash_read(uint32_t addr, uint32_t len, uint8_t *dest) {
|
||||
// OSPI FIFO is limited to 256 bytes. Need DMA to get a longer read.
|
||||
mp_spiflash_t *self = &global_flash;
|
||||
|
||||
while (len) {
|
||||
uint32_t l = len;
|
||||
if (l > 256) {
|
||||
l = 256;
|
||||
}
|
||||
ospi_setup_read(&self->cfg, 8 /* 32-bit addr len*/, l, ospi_flash_settings.read_dummy_cycles);
|
||||
ospi_push(&self->cfg, ospi_flash_settings.read_command);
|
||||
ospi_recv_blocking2(&self->cfg, addr, dest);
|
||||
addr += l;
|
||||
len -= l;
|
||||
dest += l;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ospi_flash_write_page(uint32_t addr, uint32_t len, const uint8_t *src) {
|
||||
mp_spiflash_t *self = &global_flash;
|
||||
|
||||
mp_spiflash_write_cmd(self, CMD_WREN);
|
||||
int ret = mp_spiflash_wait_wel1(self);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ospi_setup_write(&self->cfg, 8 /* 32-bit addr len*/);
|
||||
ospi_push(&self->cfg, ospi_flash_settings.write_command);
|
||||
ospi_push(&self->cfg, addr);
|
||||
while (--len) {
|
||||
ospi_push(&self->cfg, *src++);
|
||||
}
|
||||
ospi_send_blocking(&self->cfg, *src);
|
||||
|
||||
return mp_spiflash_wait_wip0(self);
|
||||
}
|
||||
|
||||
int ospi_flash_write(uint32_t addr, uint32_t len, const uint8_t *src) {
|
||||
int ret = 0;
|
||||
uint32_t offset = addr & (PAGE_SIZE - 1);
|
||||
while (len) {
|
||||
size_t rest = PAGE_SIZE - offset;
|
||||
if (rest > len) {
|
||||
rest = len;
|
||||
}
|
||||
ret = ospi_flash_write_page(addr, rest, src);
|
||||
if (ret != 0) {
|
||||
break;
|
||||
}
|
||||
len -= rest;
|
||||
addr += rest;
|
||||
src += rest;
|
||||
offset = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
52
ports/alif/ospi_flash.h
Normal file
52
ports/alif/ospi_flash.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2024 OpenMV LLC.
|
||||
*
|
||||
* 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_ALIF_OSPI_FLASH_H
|
||||
#define MICROPY_INCLUDED_ALIF_OSPI_FLASH_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct _ospi_flash_settings_t {
|
||||
uint32_t jedec_id;
|
||||
uint32_t freq_mhz;
|
||||
bool is_quad : 1;
|
||||
bool is_oct : 1;
|
||||
bool is_ddr : 1;
|
||||
uint8_t read_id_dummy_cycles;
|
||||
uint8_t read_dummy_cycles;
|
||||
uint8_t read_command;
|
||||
uint8_t write_command;
|
||||
} ospi_flash_settings_t;
|
||||
|
||||
// Provided by the board when it enables OSPI1.
|
||||
extern const ospi_flash_settings_t ospi_flash_settings;
|
||||
|
||||
int ospi_flash_init(void);
|
||||
int ospi_flash_erase_sector(uint32_t addr);
|
||||
int ospi_flash_read(uint32_t addr, uint32_t len, uint8_t *dest);
|
||||
int ospi_flash_write(uint32_t addr, uint32_t len, const uint8_t *src);
|
||||
|
||||
#endif // MICROPY_INCLUDED_ALIF_OSPI_FLASH_H
|
||||
5
ports/alif/ospi_xip_user.h
Normal file
5
ports/alif/ospi_xip_user.h
Normal file
@@ -0,0 +1,5 @@
|
||||
// This file is needed by ospi_xip/source/ospi/ospi_drv.c.
|
||||
#define OSPI_XIP_ENABLE_AES_DECRYPTION (0)
|
||||
#define OSPI_XIP_RX_SAMPLE_DELAY (4)
|
||||
#define OSPI_XIP_DDR_DRIVE_EDGE (1)
|
||||
#define OSPI_XIP_RXDS_DELAY (12)
|
||||
49
ports/alif/pendsv.c
Normal file
49
ports/alif/pendsv.c
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2024 OpenMV LLC.
|
||||
*
|
||||
* 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 "pendsv.h"
|
||||
#include "irq.h"
|
||||
|
||||
static pendsv_dispatch_t pendsv_dispatch_table[PENDSV_DISPATCH_NUM_SLOTS];
|
||||
|
||||
void pendsv_init(void) {
|
||||
NVIC_SetPriority(PendSV_IRQn, IRQ_PRI_PENDSV);
|
||||
}
|
||||
|
||||
void pendsv_schedule_dispatch(size_t slot, pendsv_dispatch_t f) {
|
||||
pendsv_dispatch_table[slot] = f;
|
||||
SCB->ICSR = SCB_ICSR_PENDSVSET_Msk;
|
||||
}
|
||||
|
||||
void PendSV_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();
|
||||
}
|
||||
}
|
||||
}
|
||||
48
ports/alif/pendsv.h
Normal file
48
ports/alif/pendsv.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2024 OpenMV LLC.
|
||||
*
|
||||
* 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_ALIF_PENDSV_H
|
||||
#define MICROPY_INCLUDED_ALIF_PENDSV_H
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
|
||||
#ifndef MICROPY_BOARD_PENDSV_ENTRIES
|
||||
#define MICROPY_BOARD_PENDSV_ENTRIES
|
||||
#endif
|
||||
|
||||
enum {
|
||||
PENDSV_DISPATCH_SOFT_TIMER,
|
||||
MICROPY_BOARD_PENDSV_ENTRIES
|
||||
PENDSV_DISPATCH_MAX
|
||||
};
|
||||
|
||||
#define PENDSV_DISPATCH_NUM_SLOTS PENDSV_DISPATCH_MAX
|
||||
|
||||
typedef void (*pendsv_dispatch_t)(void);
|
||||
|
||||
void pendsv_init(void);
|
||||
void pendsv_schedule_dispatch(size_t slot, pendsv_dispatch_t f);
|
||||
|
||||
#endif // MICROPY_INCLUDED_ALIF_PENDSV_H
|
||||
2
ports/alif/qstrdefsport.h
Normal file
2
ports/alif/qstrdefsport.h
Normal file
@@ -0,0 +1,2 @@
|
||||
// qstrs specific to this port
|
||||
// *FORMAT-OFF*
|
||||
73
ports/alif/tinyusb_port/tusb_config.h
Normal file
73
ports/alif/tinyusb_port/tusb_config.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
*
|
||||
* 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 _ALIF_TUSB_CONFIG_H_
|
||||
#define _ALIF_TUSB_CONFIG_H_
|
||||
|
||||
// --------------------------------------------------------------------+
|
||||
// Board Specific Configuration
|
||||
// --------------------------------------------------------------------+
|
||||
|
||||
#define CFG_TUSB_MCU OPT_MCU_NONE
|
||||
// #define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE
|
||||
#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED)
|
||||
#define TUP_DCD_ENDPOINT_MAX 8
|
||||
#define TUD_OPT_RHPORT 0
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// COMMON CONFIGURATION
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#define CFG_TUSB_OS OPT_OS_NONE
|
||||
#define CFG_TUSB_DEBUG 0
|
||||
|
||||
// Enable Device stack
|
||||
#define CFG_TUD_ENABLED 1
|
||||
|
||||
// Default is max speed that hardware controller could support with on-chip PHY
|
||||
#define CFG_TUD_MAX_SPEED OPT_MODE_HIGH_SPEED
|
||||
|
||||
/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment.
|
||||
* Tinyusb use follows macros to declare transferring memory so that they can be put
|
||||
* into those specific section.
|
||||
*/
|
||||
#define CFG_TUSB_MEM_SECTION __attribute__((section(".bss.sram0")))
|
||||
|
||||
#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(32)))
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// DEVICE CONFIGURATION
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#define CFG_TUD_ENDPOINT0_SIZE 64
|
||||
|
||||
// CDC Endpoint transfer buffer size, more is faster
|
||||
#define CFG_TUD_CDC_EP_BUFSIZE (4096)
|
||||
#define CFG_TUD_CDC_RX_BUFSIZE (4096)
|
||||
#define CFG_TUD_CDC_TX_BUFSIZE (4096)
|
||||
|
||||
#include "shared/tinyusb/tusb_config.h"
|
||||
|
||||
#endif /* _ALIF_TUSB_CONFIG_H_ */
|
||||
41
ports/alif/usbd.c
Normal file
41
ports/alif/usbd.c
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2024 OpenMV LLC.
|
||||
*
|
||||
* 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/mpconfig.h"
|
||||
|
||||
#if MICROPY_HW_ENABLE_USBDEV
|
||||
|
||||
#include "shared/tinyusb/mp_usbd.h"
|
||||
#include "tusb.h"
|
||||
|
||||
void mp_usbd_port_get_serial_number(char *serial_buf) {
|
||||
// TODO
|
||||
uint8_t id[8] = "ABCDEFGH";
|
||||
MP_STATIC_ASSERT(sizeof(id) * 2 <= MICROPY_HW_USB_DESC_STR_MAX);
|
||||
mp_usbd_hex_str(serial_buf, id, sizeof(id));
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user