diff --git a/docs/shared_bindings_matrix.py b/docs/shared_bindings_matrix.py index 4a858a7be374..3fd00e9b66ca 100644 --- a/docs/shared_bindings_matrix.py +++ b/docs/shared_bindings_matrix.py @@ -40,6 +40,7 @@ "mimxrt10xx", "nordic", "raspberrypi", + "renode", "silabs", "stm", ] diff --git a/docs/supported_ports.rst b/docs/supported_ports.rst index 02159083034d..69eaa5ef1489 100644 --- a/docs/supported_ports.rst +++ b/docs/supported_ports.rst @@ -20,6 +20,7 @@ Additional testing is limited. ../ports/mimxrt10xx/README ../ports/nordic/README ../ports/raspberrypi/README + ../ports/renode/README ../ports/silabs/README ../ports/stm/README ../ports/unix/README diff --git a/main.c b/main.c index 25f17d79e538..192dfa1a7ec0 100644 --- a/main.c +++ b/main.c @@ -58,7 +58,6 @@ #include "supervisor/shared/tick.h" #include "supervisor/shared/traceback.h" #include "supervisor/shared/workflow.h" -#include "supervisor/usb.h" #include "supervisor/workflow.h" #include "supervisor/shared/external_flash/external_flash.h" @@ -115,10 +114,14 @@ #include "supervisor/shared/status_bar.h" #endif -#if CIRCUITPY_USB_HID +#if CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_HID #include "shared-module/usb_hid/__init__.h" #endif +#if CIRCUITPY_TINYUSB +#include "supervisor/usb.h" +#endif + #if CIRCUITPY_WIFI #include "shared-bindings/wifi/__init__.h" #endif @@ -429,7 +432,7 @@ STATIC void print_code_py_status_message(safe_mode_t safe_mode) { } } -STATIC bool run_code_py(safe_mode_t safe_mode, bool *simulate_reset) { +STATIC bool __attribute__((noinline)) run_code_py(safe_mode_t safe_mode, bool *simulate_reset) { bool serial_connected_at_start = serial_connected(); bool printed_safe_mode_message = false; #if CIRCUITPY_AUTORELOAD_DELAY_MS > 0 @@ -1160,7 +1163,7 @@ void gc_collect(void) { common_hal_bleio_gc_collect(); #endif - #if CIRCUITPY_USB_HID + #if CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_HID usb_hid_gc_collect(); #endif diff --git a/ports/espressif/common-hal/_bleio/Adapter.c b/ports/espressif/common-hal/_bleio/Adapter.c index a5cf3da6ac8a..36bc618be7d1 100644 --- a/ports/espressif/common-hal/_bleio/Adapter.c +++ b/ports/espressif/common-hal/_bleio/Adapter.c @@ -37,7 +37,6 @@ #include "supervisor/shared/bluetooth/bluetooth.h" #include "supervisor/shared/safe_mode.h" #include "supervisor/shared/tick.h" -#include "supervisor/usb.h" #include "shared-bindings/_bleio/__init__.h" #include "shared-bindings/_bleio/Adapter.h" #include "shared-bindings/_bleio/Address.h" @@ -59,6 +58,10 @@ #include "esp_bt.h" #include "esp_nimble_hci.h" +#if CIRCUITPY_TINYUSB +#include "supervisor/usb.h" +#endif + #if CIRCUITPY_OS_GETENV #include "shared-module/os/__init__.h" #endif diff --git a/ports/espressif/supervisor/internal_flash.c b/ports/espressif/supervisor/internal_flash.c index 21cac3bc6fb4..a9e6526bf55f 100644 --- a/ports/espressif/supervisor/internal_flash.c +++ b/ports/espressif/supervisor/internal_flash.c @@ -43,7 +43,10 @@ #include "supervisor/filesystem.h" #include "supervisor/flash.h" + +#if CIRCUITPY_USB_DEVICE #include "supervisor/usb.h" +#endif #define OP_READ 0 #define OP_WRITE 1 diff --git a/ports/nordic/background.c b/ports/nordic/background.c index f2df4db0e0bd..40a349935d3b 100644 --- a/ports/nordic/background.c +++ b/ports/nordic/background.c @@ -27,10 +27,7 @@ #include "background.h" #include "py/runtime.h" -#include "supervisor/filesystem.h" #include "supervisor/port.h" -#include "supervisor/shared/stack.h" -#include "supervisor/usb.h" #if CIRCUITPY_DISPLAYIO #include "shared-module/displayio/__init__.h" diff --git a/ports/nordic/common-hal/_bleio/Adapter.c b/ports/nordic/common-hal/_bleio/Adapter.c index fd750352d295..b2f67648b3d3 100644 --- a/ports/nordic/common-hal/_bleio/Adapter.c +++ b/ports/nordic/common-hal/_bleio/Adapter.c @@ -26,7 +26,6 @@ * THE SOFTWARE. */ -#include #include #include #include @@ -43,14 +42,15 @@ #include "supervisor/shared/bluetooth/bluetooth.h" #include "supervisor/shared/safe_mode.h" #include "supervisor/shared/tick.h" -#include "supervisor/usb.h" #include "shared-bindings/_bleio/__init__.h" #include "shared-bindings/_bleio/Adapter.h" #include "shared-bindings/_bleio/Address.h" #include "shared-bindings/nvm/ByteArray.h" #include "shared-bindings/_bleio/Connection.h" -#include "shared-bindings/_bleio/ScanEntry.h" -#include "shared-bindings/time/__init__.h" + +#if CIRCUITPY_USB_DEVICE +#include "supervisor/usb.h" +#endif #if CIRCUITPY_OS_GETENV #include "shared-bindings/os/__init__.h" diff --git a/ports/renode/Makefile b/ports/renode/Makefile new file mode 100644 index 000000000000..6687ef2fcbc8 --- /dev/null +++ b/ports/renode/Makefile @@ -0,0 +1,128 @@ +# This file is part of the MicroPython project, http://micropython.org/ +# +# The MIT License (MIT) +# +# SPDX-FileCopyrightText: Copyright (c) 2019 Dan Halbert for Adafruit Industries +# +# 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/circuitpy_mkenv.mk + +CROSS_COMPILE = arm-none-eabi- + +INC += \ + -I. \ + -I../.. \ + -I../lib/mp-readline \ + -I../shared/timeutils \ + -Iboards/$(BOARD) \ + -Iboards/ \ + -isystem ./../../lib/cmsis/inc \ + -I$(BUILD) + +CFLAGS += -ggdb3 -Os + +DISABLE_WARNINGS = -Wno-cast-align +CFLAGS += $(INC) -Wall -Werror -std=gnu11 -fshort-enums $(BASE_CFLAGS) $(CFLAGS_MOD) $(COPT) $(DISABLE_WARNINGS) -Werror=missing-prototypes + +CFLAGS += \ + -march=armv6-m \ + -mthumb \ + -mabi=aapcs \ + -mcpu=cortex-m0plus \ + -msoft-float \ + -mfloat-abi=soft \ + --specs=nano.specs + +# Use toolchain libm if we're not using our own. +ifndef INTERNAL_LIBM +LIBS += -lm +endif + +LIBS += -lc + +SRC_C += \ + boards/$(BOARD)/board.c \ + boards/$(BOARD)/pins.c \ + background.c \ + mphalport.c \ + + +SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \ + $(addprefix shared-bindings/, $(SRC_BINDINGS_ENUMS)) \ + $(addprefix common-hal/, $(SRC_COMMON_HAL)) + +SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(SRC_SHARED_MODULE)) \ + $(addprefix shared-module/, $(SRC_SHARED_MODULE)) \ + $(addprefix shared-module/, $(SRC_SHARED_MODULE_INTERNAL)) + +# There may be duplicates between SRC_COMMON_HAL_EXPANDED and SRC_SHARED_MODULE_EXPANDED, +# because a few modules have files both in common-hal/ and shared-module/. +# Doing a $(sort ...) removes duplicates as part of sorting. +SRC_COMMON_HAL_SHARED_MODULE_EXPANDED = $(sort $(SRC_COMMON_HAL_EXPANDED) $(SRC_SHARED_MODULE_EXPANDED)) + +SRC_S = supervisor/$(CPU)_cpu.s + +OBJ = $(PY_O) $(SUPERVISOR_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_COMMON_HAL_SHARED_MODULE_EXPANDED:.c=.o)) +ifeq ($(INTERNAL_LIBM),1) +OBJ += $(addprefix $(BUILD)/, $(SRC_LIBM:.c=.o)) +endif +OBJ += $(addprefix $(BUILD)/, $(SRC_CIRCUITPY_COMMON:.c=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_S_UPPER:.S=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o)) + +$(BUILD)/%.o: $(BUILD)/%.S + $(STEPECHO) "CC $<" + $(Q)$(CC) $(CFLAGS) -c -o $@ $< + +SRC_QSTR += $(SRC_C) $(SRC_SUPERVISOR) $(SRC_COMMON_HAL_EXPANDED) $(SRC_SHARED_MODULE_EXPANDED) $(SRC_CIRCUITPY_COMMON) + +all: $(BUILD)/firmware.elf $(BUILD)/circuitpy.img + +BOARD_LD := $(wildcard boards/$(BOARD)/link.ld) + +ifneq ($(BOARD_LD),) + LINKER_SCRIPTS = -Wl,-T,$(BOARD_LD) +endif + +LINKER_SCRIPTS += -Wl,-T,link.ld + +$(BUILD)/circuitpy.img: circuitpy/code.py + $(STEPECHO) "Create $@" + $(Q)dd if=/dev/zero of=$(BUILD)/circuitpy.img bs=1 count=0 seek=512K + $(Q)mkfs.fat -n CIRCUITPY --offset=0 $(BUILD)/circuitpy.img + $(Q)mcopy -i $(BUILD)/circuitpy.img circuitpy/* :: + +ifeq ($(VALID_BOARD),) +$(BUILD)/firmware.elf: invalid-board +else +$(BUILD)/firmware.elf: $(OBJ) $(BOARD_LD) link.ld + $(STEPECHO) "LINK $@" + $(Q)echo $(OBJ) > $(BUILD)/firmware.objs + $(Q)echo $(PICO_LDFLAGS) > $(BUILD)/firmware.ldflags + $(Q)$(CC) -o $@ $(CFLAGS) @$(BUILD)/firmware.ldflags $(LINKER_SCRIPTS) -Wl,--print-memory-usage -Wl,-Map=$@.map -Wl,-cref -Wl,--gc-sections @$(BUILD)/firmware.objs -Wl,-lc +endif + +$(BUILD)/firmware.bin: $(BUILD)/firmware.elf + $(STEPECHO) "Create $@" + $(Q)$(OBJCOPY) -O binary -R .dtcm_bss $^ $@ + +include $(TOP)/py/mkrules.mk diff --git a/ports/renode/README.md b/ports/renode/README.md new file mode 100644 index 000000000000..16b6ba6ca4c2 --- /dev/null +++ b/ports/renode/README.md @@ -0,0 +1,49 @@ +# Renode + +Renode is an emulator targeting microcontroller-class devices. This port is a +minimal version of CircuitPython that runs under Renode. Renode is designed to +mimic full microcontrollers but CP uses more peripherals than what Renode has +implemented so far. This port allows us to run on a variety of CPUs without +worrying about peripherals. + +## Running + +1. Get Renode: https://renode.io/#downloads +2. `cd ports/renode` +3. `make BOARD=renode_cortex_m0plus` +4. In another tab: `tio /tmp/cp-uart` +5. `renode` +6. In renode: `include @renode.resc` +7. +8. `start` +9. `pause` +10. `quit` + +Step 4 sets up `tio` to talk to CircuitPython via UART <-> PTY bridge. + +## Other stuff + +### Emulator logging +Renode modules have debug logging that can be enabled with `logLevel` with an int +between `-1` for `NOISY` and `3` for errors only. + +### GDB + +Renode can provide a GDB server. It is very useful for precisely controlling the +emulator's execution. + +``` +machine StartGdbServer 3333 true +``` + +### Execution profiling + +In renode do `cpu EnableProfiler CollapsedStack $ORIGIN/profile.folded` before starting +the emulation. You can view it using [Speedscope](https://www.speedscope.app/). CircuitPython calls +a lot of functions and may overwhelm speedscope. You can enable this tracing over a specific +section of CircuitPython execution to limit the capture size. + +[Related Renode Docs](https://renode.readthedocs.io/en/latest/advanced/execution-tracing.html) + +### Execution tracing +If you want to see every instruction run you can do: `cpu CreateExecutionTracing "tracer_name" $ORIGIN/instruction_trace.txt Disassembly`. diff --git a/ports/renode/Simple32kHz.cs b/ports/renode/Simple32kHz.cs new file mode 100644 index 000000000000..9c7bc13696e9 --- /dev/null +++ b/ports/renode/Simple32kHz.cs @@ -0,0 +1,50 @@ +// +// Copyright (c) 2010-2022 Antmicro +// Copyright (c) 2011-2015 Realtime Embedded +// +// This file is licensed under the MIT License. +// Full license text is available in 'licenses/MIT.txt'. +// +// This is modified for CircuitPython to tick at 32kHz like a slow external +// crystal would. +using System; +using Antmicro.Renode.Core; +using Antmicro.Renode.Peripherals.Bus; +using Antmicro.Renode.Time; +using Antmicro.Renode.Logging; +using System.Threading; + +namespace Antmicro.Renode.Peripherals.Timers +{ + public class Simple32kHz : IDoubleWordPeripheral, IKnownSize + { + public long Size { get { return 0x4; } } + + public Simple32kHz(IMachine machine) + { + machine.ClockSource.AddClockEntry(new ClockEntry(1, 32768, OnTick, this, String.Empty)); + } + + public virtual uint ReadDoubleWord(long offset) + { + return (uint)counter; + } + + public virtual void WriteDoubleWord(long offset, uint value) + { + this.LogUnhandledWrite(offset, value); + } + + public virtual void Reset() + { + Interlocked.Exchange(ref counter, 0); + } + + private void OnTick() + { + Interlocked.Increment(ref counter); + } + + private int counter; + } +} diff --git a/ports/renode/background.c b/ports/renode/background.c new file mode 100644 index 000000000000..e2a3a10e3e5d --- /dev/null +++ b/ports/renode/background.c @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Scott Shawcroft for Adafruit Industries + * + * 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 "supervisor/port.h" + +void port_start_background_tick(void) { +} + +void port_finish_background_tick(void) { +} + +void port_background_tick(void) { +} + +void port_background_task(void) { +} diff --git a/ports/renode/background.h b/ports/renode/background.h new file mode 100644 index 000000000000..27752bd4adb9 --- /dev/null +++ b/ports/renode/background.h @@ -0,0 +1,27 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#pragma once diff --git a/ports/renode/boards/peripherals.repl b/ports/renode/boards/peripherals.repl new file mode 100644 index 000000000000..32eddfd1e549 --- /dev/null +++ b/ports/renode/boards/peripherals.repl @@ -0,0 +1,13 @@ +flash_firmware: Memory.MappedMemory @ sysbus 0x00000000 + size: 0x80000 // 512k + +flash_filesystem: Memory.MappedMemory @ sysbus 0x10000000 + size: 0x80000 // 512k + +sram: Memory.MappedMemory @ sysbus 0x20000000 + size: 0x20000 // 128k + + +uart: UART.PicoSoC_SimpleUART @ sysbus 0x40000000 + +time: Timers.Simple32kHz @ sysbus 0x40001000 diff --git a/ports/renode/boards/renode_cortex_m0plus/board.c b/ports/renode/boards/renode_cortex_m0plus/board.c new file mode 100644 index 000000000000..331653173ecd --- /dev/null +++ b/ports/renode/boards/renode_cortex_m0plus/board.c @@ -0,0 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Scott Shawcroft for Adafruit Industries + * + * 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 "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/renode/boards/renode_cortex_m0plus/board.repl b/ports/renode/boards/renode_cortex_m0plus/board.repl new file mode 100644 index 000000000000..3917413d5414 --- /dev/null +++ b/ports/renode/boards/renode_cortex_m0plus/board.repl @@ -0,0 +1,10 @@ +using "../peripherals.repl" + +cpu: CPU.CortexM @ sysbus + cpuType: "cortex-m0" + nvic: nvic + +nvic: IRQControllers.NVIC @ sysbus 0xE000E000 + priorityMask: 0xF0 + systickFrequency: 100000000 + IRQ -> cpu@0 diff --git a/ports/renode/boards/renode_cortex_m0plus/mpconfigboard.h b/ports/renode/boards/renode_cortex_m0plus/mpconfigboard.h new file mode 100644 index 000000000000..3d9d38ffac39 --- /dev/null +++ b/ports/renode/boards/renode_cortex_m0plus/mpconfigboard.h @@ -0,0 +1,8 @@ +#define MICROPY_HW_BOARD_NAME "Renode Cortex-M0+" +#define MICROPY_HW_MCU_NAME "cortex-m0+" + +#define DEFAULT_UART_BUS_RX (&pin_GPIO1) +#define DEFAULT_UART_BUS_TX (&pin_GPIO0) + +#define CIRCUITPY_CONSOLE_UART_TX DEFAULT_UART_BUS_TX +#define CIRCUITPY_CONSOLE_UART_RX DEFAULT_UART_BUS_RX diff --git a/ports/renode/boards/renode_cortex_m0plus/mpconfigboard.mk b/ports/renode/boards/renode_cortex_m0plus/mpconfigboard.mk new file mode 100644 index 000000000000..96431b9e7ee1 --- /dev/null +++ b/ports/renode/boards/renode_cortex_m0plus/mpconfigboard.mk @@ -0,0 +1 @@ +CPU = cortex-m0+ diff --git a/ports/renode/boards/renode_cortex_m0plus/pins.c b/ports/renode/boards/renode_cortex_m0plus/pins.c new file mode 100644 index 000000000000..5ecb12fdacc3 --- /dev/null +++ b/ports/renode/boards/renode_cortex_m0plus/pins.c @@ -0,0 +1,11 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/renode/circuitpy/code.py b/ports/renode/circuitpy/code.py new file mode 100644 index 000000000000..c1d54872a620 --- /dev/null +++ b/ports/renode/circuitpy/code.py @@ -0,0 +1,4 @@ +print("hello from renode") + +# This folder gets merged into a FATFS image loaded into renode. Put what you +# want here and run `make BOARD=renode_cortex_m0plus` diff --git a/ports/renode/common-hal/board/__init__.c b/ports/renode/common-hal/board/__init__.c new file mode 100644 index 000000000000..b429ab358d5a --- /dev/null +++ b/ports/renode/common-hal/board/__init__.c @@ -0,0 +1,30 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Scott Shawcroft for Adafruit Industries + * + * 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 + +// Pins aren't actually defined here. They are in the board specific directory +// such as boards/arduino_zero/pins.c. diff --git a/ports/renode/common-hal/busio/I2C.c b/ports/renode/common-hal/busio/I2C.c new file mode 100644 index 000000000000..4dbf4c2b4a6e --- /dev/null +++ b/ports/renode/common-hal/busio/I2C.c @@ -0,0 +1,80 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/busio/I2C.h" + +#include "py/mperrno.h" +#include "py/runtime.h" + +#define NO_PIN 0xff + +void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, + const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda, uint32_t frequency, uint32_t timeout) { + mp_raise_NotImplementedError(NULL); +} + +bool common_hal_busio_i2c_deinited(busio_i2c_obj_t *self) { + return true; +} + +void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) { + if (common_hal_busio_i2c_deinited(self)) { + return; + } +} + +bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) { + return false; +} + +bool common_hal_busio_i2c_try_lock(busio_i2c_obj_t *self) { + return false; +} + +bool common_hal_busio_i2c_has_lock(busio_i2c_obj_t *self) { + return false; +} + +void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) { +} + +uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, + const uint8_t *data, size_t len) { + return 0; +} + +uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, + uint8_t *data, size_t len) { + return MP_EIO; +} + +uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, + uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) { + return MP_EIO; +} + +void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self) { +} diff --git a/ports/renode/common-hal/busio/I2C.h b/ports/renode/common-hal/busio/I2C.h new file mode 100644 index 000000000000..2d16b69e4f88 --- /dev/null +++ b/ports/renode/common-hal/busio/I2C.h @@ -0,0 +1,33 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#pragma once + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; +} busio_i2c_obj_t; diff --git a/ports/renode/common-hal/busio/SPI.c b/ports/renode/common-hal/busio/SPI.c new file mode 100644 index 000000000000..d505cb9ac905 --- /dev/null +++ b/ports/renode/common-hal/busio/SPI.c @@ -0,0 +1,91 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/busio/SPI.h" + +#include "py/runtime.h" + +void common_hal_busio_spi_construct(busio_spi_obj_t *self, + const mcu_pin_obj_t *clock, const mcu_pin_obj_t *mosi, + const mcu_pin_obj_t *miso, bool half_duplex) { + mp_raise_NotImplementedError(NULL); +} + +void common_hal_busio_spi_never_reset(busio_spi_obj_t *self) { +} + +bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) { + return true; +} + +void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { + if (common_hal_busio_spi_deinited(self)) { + return; + } +} + +bool common_hal_busio_spi_configure(busio_spi_obj_t *self, + uint32_t baudrate, uint8_t polarity, uint8_t phase, uint8_t bits) { + return true; +} + +bool common_hal_busio_spi_try_lock(busio_spi_obj_t *self) { + return false; +} + +bool common_hal_busio_spi_has_lock(busio_spi_obj_t *self) { + return false; +} + +void common_hal_busio_spi_unlock(busio_spi_obj_t *self) { +} + + +bool common_hal_busio_spi_write(busio_spi_obj_t *self, + const uint8_t *data, size_t len) { + return false; +} + +bool common_hal_busio_spi_read(busio_spi_obj_t *self, + uint8_t *data, size_t len, uint8_t write_value) { + return false; +} + +bool common_hal_busio_spi_transfer(busio_spi_obj_t *self, const uint8_t *data_out, uint8_t *data_in, size_t len) { + return false; +} + +uint32_t common_hal_busio_spi_get_frequency(busio_spi_obj_t *self) { + return 0; +} + +uint8_t common_hal_busio_spi_get_phase(busio_spi_obj_t *self) { + return 0; +} + +uint8_t common_hal_busio_spi_get_polarity(busio_spi_obj_t *self) { + return 0; +} diff --git a/ports/renode/common-hal/busio/SPI.h b/ports/renode/common-hal/busio/SPI.h new file mode 100644 index 000000000000..8a5bda837843 --- /dev/null +++ b/ports/renode/common-hal/busio/SPI.h @@ -0,0 +1,33 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#pragma once + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; +} busio_spi_obj_t; diff --git a/ports/renode/common-hal/busio/UART.c b/ports/renode/common-hal/busio/UART.c new file mode 100644 index 000000000000..6c6ffda0fa37 --- /dev/null +++ b/ports/renode/common-hal/busio/UART.c @@ -0,0 +1,107 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 microDev + * + * 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 "shared-bindings/busio/UART.h" +#include "py/runtime.h" + +#define RXTX ((volatile uint32_t *)0x40000004) +#define NO_CHAR (0xffffffff) + +void common_hal_busio_uart_construct(busio_uart_obj_t *self, + const mcu_pin_obj_t *tx, const mcu_pin_obj_t *rx, + const mcu_pin_obj_t *rts, const mcu_pin_obj_t *cts, + const mcu_pin_obj_t *rs485_dir, bool rs485_invert, + uint32_t baudrate, uint8_t bits, busio_uart_parity_t parity, uint8_t stop, + mp_float_t timeout, uint16_t receiver_buffer_size, byte *receiver_buffer, + bool sigint_enabled) { + self->pending_char = NO_CHAR; +} + +bool common_hal_busio_uart_deinited(busio_uart_obj_t *self) { + return true; +} + +void common_hal_busio_uart_deinit(busio_uart_obj_t *self) { + if (common_hal_busio_uart_deinited(self)) { + return; + } +} + +// Write characters. +size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data, size_t len, int *errcode) { + for (size_t i = 0; i < len; i++) { + *RXTX = data[i]; + } + return len; +} + +// Read characters. +size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t len, int *errcode) { + size_t read = 0; + while (self->pending_char != NO_CHAR && read < len) { + data[read] = self->pending_char; + read++; + self->pending_char = *RXTX; + } + return read; +} + +uint32_t common_hal_busio_uart_get_baudrate(busio_uart_obj_t *self) { + return 0; +} + +void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, uint32_t baudrate) { + mp_raise_NotImplementedError(NULL); +} + +mp_float_t common_hal_busio_uart_get_timeout(busio_uart_obj_t *self) { + return 0; +} + +void common_hal_busio_uart_set_timeout(busio_uart_obj_t *self, mp_float_t timeout) { +} + +uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) { + if (self->pending_char != NO_CHAR) { + return 1; + } + self->pending_char = *RXTX; + if (self->pending_char != NO_CHAR) { + return 1; + } + return 0; +} + +void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self) { + self->pending_char = NO_CHAR; +} + +bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self) { + return true; +} + +void common_hal_busio_uart_never_reset(busio_uart_obj_t *self) { +} diff --git a/ports/renode/common-hal/busio/UART.h b/ports/renode/common-hal/busio/UART.h new file mode 100644 index 000000000000..a0d9ec47be6c --- /dev/null +++ b/ports/renode/common-hal/busio/UART.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 microDev + * + * 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. + */ + +#pragma once + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + uint32_t pending_char; +} busio_uart_obj_t; diff --git a/ports/renode/common-hal/busio/__init__.c b/ports/renode/common-hal/busio/__init__.c new file mode 100644 index 000000000000..41761b6743ae --- /dev/null +++ b/ports/renode/common-hal/busio/__init__.c @@ -0,0 +1 @@ +// No busio module functions. diff --git a/ports/renode/common-hal/microcontroller/Pin.c b/ports/renode/common-hal/microcontroller/Pin.c new file mode 100644 index 000000000000..16730d23635c --- /dev/null +++ b/ports/renode/common-hal/microcontroller/Pin.c @@ -0,0 +1,79 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/microcontroller/Pin.h" + +void reset_all_pins(void) { +} + +void never_reset_pin_number(uint8_t pin_number) { +} + +void reset_pin_number(uint8_t pin_number) { +} + +void common_hal_never_reset_pin(const mcu_pin_obj_t *pin) { + never_reset_pin_number(pin->number); +} + +void common_hal_reset_pin(const mcu_pin_obj_t *pin) { + reset_pin_number(pin->number); +} + +void claim_pin(const mcu_pin_obj_t *pin) { +} + +bool pin_number_is_free(uint8_t pin_number) { + return true; +} + +bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t *pin) { + return pin_number_is_free(pin->number); +} + +uint8_t common_hal_mcu_pin_number(const mcu_pin_obj_t *pin) { + return pin->number; +} + +void common_hal_mcu_pin_claim(const mcu_pin_obj_t *pin) { + return claim_pin(pin); +} + +void common_hal_mcu_pin_reset_number(uint8_t pin_no) { + reset_pin_number(pin_no); +} + +// This macro is used to simplify pin definition in boards//pins.c +#define PIN(p_number) \ + const mcu_pin_obj_t pin_GPIO##p_number = { \ + { &mcu_pin_type }, \ + .number = p_number \ + } + +PIN(0); +PIN(1); diff --git a/ports/renode/common-hal/microcontroller/Pin.h b/ports/renode/common-hal/microcontroller/Pin.h new file mode 100644 index 000000000000..b4f526983b1f --- /dev/null +++ b/ports/renode/common-hal/microcontroller/Pin.h @@ -0,0 +1,54 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#pragma once + +#include +#include + +#include + +typedef struct { + mp_obj_base_t base; + uint8_t number; +} mcu_pin_obj_t; + +extern const mcu_pin_obj_t pin_GPIO0; +extern const mcu_pin_obj_t pin_GPIO1; + +// If a board needs a different reset state for one or more pins, implement +// board_reset_pin_number so that it sets this state and returns `true` for those +// pin numbers, `false` for others. +// A default weak implementation always returns `false`. +bool board_reset_pin_number(uint8_t pin_number); + +void reset_all_pins(void); +// reset_pin_number takes the pin number instead of the pointer so that objects don't +// need to store a full pointer. +void reset_pin_number(uint8_t pin_number); +void never_reset_pin_number(uint8_t pin_number); +void claim_pin(const mcu_pin_obj_t *pin); +bool pin_number_is_free(uint8_t pin_number); diff --git a/ports/renode/common-hal/microcontroller/Processor.c b/ports/renode/common-hal/microcontroller/Processor.c new file mode 100644 index 000000000000..372e4525af0d --- /dev/null +++ b/ports/renode/common-hal/microcontroller/Processor.c @@ -0,0 +1,57 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Scott Shawcroft for Adafruit Industries + * + * 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 +#include + +#include "common-hal/microcontroller/Processor.h" +#include "py/runtime.h" +#include "shared-bindings/microcontroller/Processor.h" +#include "shared-bindings/microcontroller/ResetReason.h" + +float common_hal_mcu_processor_get_temperature(void) { + return NAN; +} + +float common_hal_mcu_processor_get_voltage(void) { + return NAN; +} + +uint32_t common_hal_mcu_processor_get_frequency(void) { + return 100000000; +} + +void common_hal_mcu_processor_set_frequency(mcu_processor_obj_t *self, uint32_t frequency) { + mp_raise_NotImplementedError(NULL); +} + +void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { + raw_id[0] = 0xaf; +} + +mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) { + return RESET_REASON_POWER_ON; +} diff --git a/ports/renode/common-hal/microcontroller/Processor.h b/ports/renode/common-hal/microcontroller/Processor.h new file mode 100644 index 000000000000..ca96a9804d64 --- /dev/null +++ b/ports/renode/common-hal/microcontroller/Processor.h @@ -0,0 +1,36 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#pragma once + +#define COMMON_HAL_MCU_PROCESSOR_UID_LENGTH 1 + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + // Stores no state currently. +} mcu_processor_obj_t; diff --git a/ports/renode/common-hal/microcontroller/__init__.c b/ports/renode/common-hal/microcontroller/__init__.c new file mode 100644 index 000000000000..96729539b738 --- /dev/null +++ b/ports/renode/common-hal/microcontroller/__init__.c @@ -0,0 +1,134 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Scott Shawcroft for Adafruit Industries + * + * 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/obj.h" + +#include "common-hal/microcontroller/__init__.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/microcontroller/Processor.h" +#include "supervisor/filesystem.h" +#include "supervisor/port.h" +#include "supervisor/shared/safe_mode.h" + +void common_hal_mcu_delay_us(uint32_t delay) { + mp_hal_delay_us(delay); +} + +volatile uint32_t nesting_count = 0; +void common_hal_mcu_disable_interrupts(void) { + // We don't use save_and_disable_interrupts() from the sdk because we don't want to worry about PRIMASK. + // This is what we do on the SAMD21 via CMSIS. + asm volatile ("cpsid i" : : : "memory"); + // __dmb(); + nesting_count++; +} + +void common_hal_mcu_enable_interrupts(void) { + if (nesting_count == 0) { + // reset_into_safe_mode(SAFE_MODE_INTERRUPT_ERROR); + } + nesting_count--; + if (nesting_count > 0) { + return; + } + // __dmb(); + asm volatile ("cpsie i" : : : "memory"); +} + +static bool next_reset_to_bootloader = false; + +void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) { + switch (runmode) { + case RUNMODE_UF2: + case RUNMODE_BOOTLOADER: + next_reset_to_bootloader = true; + break; + case RUNMODE_SAFE_MODE: + safe_mode_on_next_reset(SAFE_MODE_PROGRAMMATIC); + break; + default: + break; + } +} + +void common_hal_mcu_reset(void) { + filesystem_flush(); + if (next_reset_to_bootloader) { + reset_to_bootloader(); + } else { + reset_cpu(); + } +} + +// The singleton microcontroller.Processor object, bound to microcontroller.cpu +// It currently only has properties, and no state. +#if CIRCUITPY_PROCESSOR_COUNT > 1 +static const mcu_processor_obj_t processor0 = { + .base = { + .type = &mcu_processor_type, + }, +}; + +static const mcu_processor_obj_t processor1 = { + .base = { + .type = &mcu_processor_type, + }, +}; + +const mp_rom_obj_tuple_t common_hal_multi_processor_obj = { + {&mp_type_tuple}, + CIRCUITPY_PROCESSOR_COUNT, + { + MP_ROM_PTR(&processor0), + MP_ROM_PTR(&processor1) + } +}; +#endif + +const mcu_processor_obj_t common_hal_mcu_processor_obj = { + .base = { + .type = &mcu_processor_type, + }, +}; + +// This maps MCU pin names to pin objects. +const mp_rom_map_elem_t mcu_pin_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_GPIO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GPIO1), MP_ROM_PTR(&pin_GPIO1) }, +}; +MP_DEFINE_CONST_DICT(mcu_pin_globals, mcu_pin_global_dict_table); + +const mcu_pin_obj_t *mcu_get_pin_by_number(int number) { + for (size_t i = 0; i < MP_ARRAY_SIZE(mcu_pin_global_dict_table); i++) { + mcu_pin_obj_t *obj = MP_OBJ_TO_PTR(mcu_pin_global_dict_table[i].value); + if (obj->base.type == &mcu_pin_type && obj->number == number) { + return obj; + } + } + return NULL; +} diff --git a/ports/renode/common-hal/microcontroller/__init__.h b/ports/renode/common-hal/microcontroller/__init__.h new file mode 100644 index 000000000000..d40d4d190c59 --- /dev/null +++ b/ports/renode/common-hal/microcontroller/__init__.h @@ -0,0 +1,31 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#pragma once + +#include "shared-bindings/microcontroller/Pin.h" + +const mcu_pin_obj_t *mcu_get_pin_by_number(int); diff --git a/ports/renode/common-hal/os/__init__.c b/ports/renode/common-hal/os/__init__.c new file mode 100644 index 000000000000..bace29c3c3c2 --- /dev/null +++ b/ports/renode/common-hal/os/__init__.c @@ -0,0 +1,63 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Scott Shawcroft for Adafruit Industries + * + * 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 "genhdr/mpversion.h" +#include "py/mpconfig.h" +#include "py/objstr.h" +#include "py/objtuple.h" +#include "py/qstr.h" + +#include "shared-bindings/os/__init__.h" + +STATIC const qstr os_uname_info_fields[] = { + MP_QSTR_sysname, MP_QSTR_nodename, + MP_QSTR_release, MP_QSTR_version, MP_QSTR_machine +}; +STATIC const MP_DEFINE_STR_OBJ(os_uname_info_sysname_obj, "renode"); +STATIC const MP_DEFINE_STR_OBJ(os_uname_info_nodename_obj, "renode"); +STATIC const MP_DEFINE_STR_OBJ(os_uname_info_release_obj, MICROPY_VERSION_STRING); +STATIC const MP_DEFINE_STR_OBJ(os_uname_info_version_obj, MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE); +STATIC const MP_DEFINE_STR_OBJ(os_uname_info_machine_obj, MICROPY_HW_BOARD_NAME " with " MICROPY_HW_MCU_NAME); + + +STATIC MP_DEFINE_ATTRTUPLE( + os_uname_info_obj, + os_uname_info_fields, + 5, + (mp_obj_t)&os_uname_info_sysname_obj, + (mp_obj_t)&os_uname_info_nodename_obj, + (mp_obj_t)&os_uname_info_release_obj, + (mp_obj_t)&os_uname_info_version_obj, + (mp_obj_t)&os_uname_info_machine_obj + ); + +mp_obj_t common_hal_os_uname(void) { + return (mp_obj_t)&os_uname_info_obj; +} + +bool common_hal_os_urandom(uint8_t *buffer, mp_uint_t length) { + return false; +} diff --git a/ports/renode/link.ld b/ports/renode/link.ld new file mode 100644 index 000000000000..125c0b0a0097 --- /dev/null +++ b/ports/renode/link.ld @@ -0,0 +1,65 @@ +MEMORY +{ + FLASH_FIRMWARE (rx) : ORIGIN = 0x00000000, LENGTH = 512k + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 128k +} + +SECTIONS +{ + .irqs : { + . = ALIGN(4); + KEEP(*(.rodata.interrupt_table .rodata.interrupt_table.*)) + . = ALIGN(4); + } > FLASH_FIRMWARE + + .text : { + *(.text*) + . = ALIGN(4); + } > FLASH_FIRMWARE + + .rodata : { + *(.rodata*) + . = ALIGN(4); + } > FLASH_FIRMWARE + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH_FIRMWARE + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH_FIRMWARE + __exidx_end = .; + + /* End of .text-like segments */ + __etext = .; + + .data : { + __data_start__ = .; + *(.data*) + /* All data end */ + __data_end__ = .; + } > RAM AT> FLASH_FIRMWARE + _ld_ocram_data_destination = ADDR(.data); + _ld_ocram_data_flash_copy = LOADADDR(.data); + _ld_ocram_data_size = SIZEOF(.data); + + /* Uninitialized data section */ + .bss : { + . = ALIGN(4); + __bss_start__ = .; + *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*))) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + _ld_ocram_bss_start = ADDR(.bss); + _ld_ocram_bss_size = SIZEOF(.bss); + _ld_heap_start = _ld_ocram_bss_start + _ld_ocram_bss_size; + _ld_ocram_start = ORIGIN(RAM); + _ld_ocram_end = ORIGIN(RAM) + LENGTH(RAM); + _ld_heap_end = _ld_ocram_end; +} diff --git a/ports/renode/mpconfigport.h b/ports/renode/mpconfigport.h new file mode 100644 index 000000000000..c3a4de927c33 --- /dev/null +++ b/ports/renode/mpconfigport.h @@ -0,0 +1,36 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#pragma once + +#define MICROPY_PY_SYS_PLATFORM "Renode" + +#define MICROPY_USE_INTERNAL_PRINTF (1) + +// This also includes mpconfigboard.h. +#include "py/circuitpy_mpconfig.h" + +#define CIRCUITPY_DEFAULT_STACK_SIZE (24 * 1024) diff --git a/ports/renode/mpconfigport.mk b/ports/renode/mpconfigport.mk new file mode 100644 index 000000000000..e2171c5b6c00 --- /dev/null +++ b/ports/renode/mpconfigport.mk @@ -0,0 +1,40 @@ +LONGINT_IMPL = MPZ +INTERNAL_LIBM = 1 + +# We build .elf files to run in the simulator. Generally, this will be a file +# type supported by the chip family's bootloader. +CIRCUITPY_BUILD_EXTENSIONS = elf + +# The port manages flash itself instead of using SPI flash via busio.SPI. +INTERNAL_FLASH_FILESYSTEM = 1 + +# Usually lots of flash space available +CIRCUITPY_MESSAGE_COMPRESSION_LEVEL = 1 + +# Disable modules included in full builds +CIRCUITPY_FULL_BUILD = 0 + +# Most ports will want to enable this early to use the USB workflow in testing +# module implementation. It depends on TinyUSB supporting the USB peripheral. +# Renode uses UART instead of USB. +CIRCUITPY_USB_DEVICE = 0 + +# Disable modules included in slim builds directly. Enable these as they are +# implemented. +CIRCUITPY_ANALOGBUFIO = 0 +CIRCUITPY_ANALOGIO = 0 +CIRCUITPY_BUSIO_I2C = 0 +CIRCUITPY_BUSIO_SPI = 0 +CIRCUITPY_DIGITALIO = 0 +CIRCUITPY_NEOPIXEL_WRITE = 0 +CIRCUITPY_NVM = 0 +CIRCUITPY_ONEWIREIO = 0 +CIRCUITPY_PWMIO = 0 +CIRCUITPY_RANDOM = 0 +CIRCUITPY_ROTARYIO = 0 +CIRCUITPY_ROTARYIO_SOFTENCODER = 0 +CIRCUITPY_RTC = 0 +CIRCUITPY_STORAGE = 0 +CIRCUITPY_TOUCHIO = 0 + +CIRCUITPY_BITBANGIO = $(CIRCUITPY_DIGITALIO) diff --git a/ports/renode/mphalport.c b/ports/renode/mphalport.c new file mode 100644 index 000000000000..84e9a4685a3c --- /dev/null +++ b/ports/renode/mphalport.c @@ -0,0 +1,45 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Scott Shawcroft for Adafruit Industries + * + * 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 "shared-bindings/microcontroller/__init__.h" + +#include "mpconfigboard.h" +#include "mphalport.h" + +extern uint32_t common_hal_mcu_processor_get_frequency(void); + +void mp_hal_delay_us(mp_uint_t delay) { + // TODO busy_wait_us_32(delay); +} + +void mp_hal_disable_all_interrupts(void) { + common_hal_mcu_disable_interrupts(); +} + +void mp_hal_enable_all_interrupts(void) { + common_hal_mcu_enable_interrupts(); +} diff --git a/ports/renode/mphalport.h b/ports/renode/mphalport.h new file mode 100644 index 000000000000..30e5aaf76203 --- /dev/null +++ b/ports/renode/mphalport.h @@ -0,0 +1,35 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#pragma once + +// Global millisecond tick count (driven by SysTick interrupt). +#define mp_hal_ticks_ms() ((mp_uint_t)supervisor_ticks_ms32()) + +void mp_hal_set_interrupt_char(int c); + +void mp_hal_disable_all_interrupts(void); +void mp_hal_enable_all_interrupts(void); diff --git a/ports/renode/qstrdefsport.h b/ports/renode/qstrdefsport.h new file mode 100644 index 000000000000..3ba897069bf7 --- /dev/null +++ b/ports/renode/qstrdefsport.h @@ -0,0 +1 @@ +// qstrs specific to this port diff --git a/ports/renode/renode.resc b/ports/renode/renode.resc new file mode 100644 index 000000000000..11c95e084196 --- /dev/null +++ b/ports/renode/renode.resc @@ -0,0 +1,29 @@ +using sysbus + +include @Simple32kHz.cs +emulation CreateUartPtyTerminal "term" "/tmp/cp-uart" + +$board?="renode_cortex_m0plus" +mach create $board + +machine LoadPlatformDescription $ORIGIN/boards/renode_cortex_m0plus/board.repl + +# uart RecordToAsciinema $ORIGIN/build-renode_cortex_m0plus/serial.asciinema +connector Connect sysbus.uart term + +sysbus LoadELF @build-renode_cortex_m0plus/firmware.elf +cpu VectorTableOffset `sysbus GetSymbolAddress "interrupt_table"` + +sysbus LoadBinary @build-renode_cortex_m0plus/circuitpy.img 0x10000000 + +# Enable all debug logging +# logLevel -1 + +# Enable function profiling +# cpu EnableProfiler CollapsedStack $ORIGIN/profile.folded true + +# Enable execution tracing +# cpu CreateExecutionTracing "tracer_name" $ORIGIN/instruction_trace.txt Disassembly + +# Enable the gdb server +# machine StartGdbServer 3333 true diff --git a/ports/renode/supervisor/cortex-m0+_cpu.s b/ports/renode/supervisor/cortex-m0+_cpu.s new file mode 100755 index 000000000000..741bb21358ad --- /dev/null +++ b/ports/renode/supervisor/cortex-m0+_cpu.s @@ -0,0 +1,35 @@ +.syntax unified +.cpu cortex-m0 +.thumb +.text +.align 2 + +@ uint cpu_get_regs_and_sp(r0=uint regs[10]) +.global cpu_get_regs_and_sp +.thumb +.thumb_func +.type cpu_get_regs_and_sp, %function +cpu_get_regs_and_sp: +@ store registers into given array +str r4, [r0, #0] +str r5, [r0, #4] +str r6, [r0, #8] +str r7, [r0, #12] +push {r1} +mov r1, r8 +str r1, [r0, #16] +mov r1, r9 +str r1, [r0, #20] +mov r1, r10 +str r1, [r0, #24] +mov r1, r11 +str r1, [r0, #28] +mov r1, r12 +str r1, [r0, #32] +mov r1, r13 +str r1, [r0, #36] +pop {r1} + +@ return the sp +mov r0, sp +bx lr diff --git a/ports/renode/supervisor/internal_flash.c b/ports/renode/supervisor/internal_flash.c new file mode 100644 index 000000000000..0d75cb9cc979 --- /dev/null +++ b/ports/renode/supervisor/internal_flash.c @@ -0,0 +1,68 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Scott Shawcroft for Adafruit Industries + * + * 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 "supervisor/internal_flash.h" + +#include +#include +#include + +#include "supervisor/flash.h" + +#define FLASH_BASE 0x10000000 +#define FLASH_SIZE 0x80000 + +void supervisor_flash_init(void) { +} + +uint32_t supervisor_flash_get_block_size(void) { + return FILESYSTEM_BLOCK_SIZE; +} + +uint32_t supervisor_flash_get_block_count(void) { + return FLASH_SIZE / FILESYSTEM_BLOCK_SIZE; +} + +void port_internal_flash_flush(void) { +} + +mp_uint_t supervisor_flash_read_blocks(uint8_t *dest, uint32_t block, uint32_t num_blocks) { + memcpy(dest, + (void *)(FLASH_BASE + block * FILESYSTEM_BLOCK_SIZE), + num_blocks * FILESYSTEM_BLOCK_SIZE); + return 0; +} + +mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32_t num_blocks) { + memcpy((void *)(FLASH_BASE + lba * FILESYSTEM_BLOCK_SIZE), + src, + num_blocks * FILESYSTEM_BLOCK_SIZE); + + return 0; // success +} + +void supervisor_flash_release_cache(void) { +} diff --git a/ports/renode/supervisor/internal_flash.h b/ports/renode/supervisor/internal_flash.h new file mode 100644 index 000000000000..3706b719460a --- /dev/null +++ b/ports/renode/supervisor/internal_flash.h @@ -0,0 +1,28 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Scott Shawcroft for Adafruit Industries + * + * 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. + */ +#pragma once + +#include diff --git a/ports/renode/supervisor/port.c b/ports/renode/supervisor/port.c new file mode 100644 index 000000000000..bf2f71953ee4 --- /dev/null +++ b/ports/renode/supervisor/port.c @@ -0,0 +1,237 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Scott Shawcroft for Adafruit Industries + * + * 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 +#include +#include + +#include "supervisor/background_callback.h" +#include "supervisor/port.h" + +#include "genhdr/mpversion.h" +#include "shared-bindings/microcontroller/__init__.h" + +#include "supervisor/shared/safe_mode.h" + + +extern uint32_t _ld_flash_size; +extern uint32_t _ld_stack_top; + +extern uint32_t __isr_vector[]; + +extern uint32_t _ld_ocram_start; +extern uint32_t _ld_ocram_bss_start; +extern uint32_t _ld_ocram_bss_size; +extern uint32_t _ld_ocram_data_destination; +extern uint32_t _ld_ocram_data_size; +extern uint32_t _ld_ocram_data_flash_copy; +extern uint32_t _ld_ocram_end; +extern uint32_t _ld_dtcm_bss_start; +extern uint32_t _ld_dtcm_bss_size; +extern uint32_t _ld_dtcm_data_destination; +extern uint32_t _ld_dtcm_data_size; +extern uint32_t _ld_dtcm_data_flash_copy; +extern uint32_t _ld_itcm_destination; +extern uint32_t _ld_itcm_size; +extern uint32_t _ld_itcm_flash_copy; +extern uint32_t _ld_isr_destination; +extern uint32_t _ld_isr_size; +extern uint32_t _ld_isr_flash_copy; + +extern void main(void); + +// This replaces the Reset_Handler in startup_*.S and SystemInit in system_*.c. +// Turn off optimize("no-tree-loop-distribute-patterns") so that this isn't replaced +// by calls to memcpy because we're copying it over now. +void Reset_Handler(void); +__attribute__((used, naked, no_instrument_function, optimize("no-tree-loop-distribute-patterns"))) void Reset_Handler(void) { + // Copy all of the itcm code to run from ITCM. Do this while the MPU is disabled because we write + // protect it. + // for (uint32_t i = 0; i < ((size_t)&_ld_itcm_size) / 4; i++) { + // (&_ld_itcm_destination)[i] = (&_ld_itcm_flash_copy)[i]; + // } + + // for (uint32_t i = 0; i < ((size_t)&_ld_isr_size) / 4; i++) { + // (&_ld_isr_destination)[i] = (&_ld_isr_flash_copy)[i]; + // } + + // Copy all of the data to run from DTCM. + // for (uint32_t i = 0; i < ((size_t)&_ld_dtcm_data_size) / 4; i++) { + // (&_ld_dtcm_data_destination)[i] = (&_ld_dtcm_data_flash_copy)[i]; + // } + + // // Clear DTCM bss. + // for (uint32_t i = 0; i < ((size_t)&_ld_dtcm_bss_size) / 4; i++) { + // (&_ld_dtcm_bss_start)[i] = 0; + // } + + // Copy all of the data to run from OCRAM. + for (uint32_t i = 0; i < ((size_t)&_ld_ocram_data_size) / 4; i++) { + (&_ld_ocram_data_destination)[i] = (&_ld_ocram_data_flash_copy)[i]; + } + + // Clear OCRAM bss. + for (uint32_t i = 0; i < ((size_t)&_ld_ocram_bss_size) / 4; i++) { + (&_ld_ocram_bss_start)[i] = 0; + } + + main(); +} + +typedef void (*isr_vector)(void); +const isr_vector __attribute__((used)) interrupt_table[17] = { + (isr_vector) & _ld_ocram_end, + Reset_Handler, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL +}; + +safe_mode_t __attribute__((used)) port_init(void) { + // Reset everything into a known state before board_init. + reset_port(); + + return SAFE_MODE_NONE; +} + +void reset_port(void) { + // Older ports will do blanket resets here. Instead, move to a model that + // uses the deinit() functions to reset internal state. +} + +void reset_to_bootloader(void) { + while (true) { + } +} + +void reset_cpu(void) { + while (true) { + // __wfi(); + } +} + +// From the linker script +extern uint32_t _ld_heap_start; +extern uint32_t _ld_heap_end; +uint32_t *port_stack_get_limit(void) { + #pragma GCC diagnostic push + + #pragma GCC diagnostic ignored "-Warray-bounds" + return port_stack_get_top() - (CIRCUITPY_DEFAULT_STACK_SIZE + CIRCUITPY_EXCEPTION_STACK_SIZE) / sizeof(uint32_t); + #pragma GCC diagnostic pop +} + +uint32_t *port_stack_get_top(void) { + return &_ld_heap_end; +} + +uint32_t *port_heap_get_bottom(void) { + return &_ld_heap_start; +} + +uint32_t *port_heap_get_top(void) { + return port_stack_get_limit(); +} + +uint32_t saved_word; +void port_set_saved_word(uint32_t value) { + // Store in RAM because the watchdog scratch registers don't survive + // resetting by pulling the RUN pin low. + saved_word = value; +} + +uint32_t port_get_saved_word(void) { + return saved_word; +} + +static volatile bool ticks_enabled; +static volatile bool _woken_up; + +uint64_t port_get_raw_ticks(uint8_t *subticks) { + volatile uint32_t *ticks_32khz = ((volatile uint32_t *)0x40001000); + uint32_t total_ticks = *ticks_32khz; + if (subticks != NULL) { + *subticks = total_ticks % 32; + } + return total_ticks / 32; +} + +// Enable 1/1024 second tick. +void port_enable_tick(void) { + ticks_enabled = true; +} + +// Disable 1/1024 second tick. +void port_disable_tick(void) { + // One additional _tick_callback may occur, but it will just return + // whenever !ticks_enabled. Cancel is not called just in case + // it could nuke a timeout set by port_interrupt_after_ticks. + ticks_enabled = false; +} + +// This is called by sleep, we ignore it when our ticks are enabled because +// they'll wake us up earlier. If we don't, we'll mess up ticks by overwriting +// the next RTC wake up time. +void port_interrupt_after_ticks(uint32_t ticks) { + _woken_up = false; +} + +void port_idle_until_interrupt(void) { + common_hal_mcu_disable_interrupts(); + if (!background_callback_pending() && !_woken_up) { + // __DSB(); + // __WFI(); + } + common_hal_mcu_enable_interrupts(); +} + +/** + * \brief Default interrupt handler for unused IRQs. + */ +extern void HardFault_Handler(void); // provide a prototype to avoid a missing-prototypes diagnostic +__attribute__((used)) void HardFault_Handler(void) { + while (true) { + asm ("nop;"); + } +} + +void port_yield() { +} + +void port_boot_info(void) { +} diff --git a/ports/renode/tools/split_profile.py b/ports/renode/tools/split_profile.py new file mode 100644 index 000000000000..3c3ed153ec62 --- /dev/null +++ b/ports/renode/tools/split_profile.py @@ -0,0 +1,24 @@ +# Split a profile file into smaller chunks. + +import pathlib +import sys + +input_file = pathlib.Path(sys.argv[-1]) + +supervisor = input_file.with_suffix(".supervisor" + input_file.suffix) +boot_py = input_file.with_suffix(".boot_py" + input_file.suffix) +code_py = input_file.with_suffix(".code_py" + input_file.suffix) + +supervisor_f = supervisor.open("w") +boot_py_f = boot_py.open("w") +code_py_f = code_py.open("w") + +for line in input_file.open(): + if "run_boot_py" in line: + boot_py_f.write(line) + if "run_code_py" in line: + code_py_f.write(line) + +supervisor_f.close() +boot_py_f.close() +code_py_f.close() diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index 711b14caf3fa..76f8a4fad179 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -554,6 +554,12 @@ CFLAGS += -DCIRCUITPY_UHEAP=$(CIRCUITPY_UHEAP) CIRCUITPY_USB_DEVICE ?= 1 CFLAGS += -DCIRCUITPY_USB_DEVICE=$(CIRCUITPY_USB_DEVICE) +ifneq ($(CIRCUITPY_USB_DEVICE),0) +ifndef USB_NUM_ENDPOINT_PAIRS +$(error "USB_NUM_ENDPOINT_PAIRS (number of USB endpoint pairs)must be defined") +endif +CFLAGS += -DUSB_NUM_ENDPOINT_PAIRS=$(USB_NUM_ENDPOINT_PAIRS) + # Compute these value once, so the shell command is not reinvoked many times. USB_NUM_ENDPOINT_PAIRS_5_OR_GREATER := $(shell expr $(USB_NUM_ENDPOINT_PAIRS) '>=' 5) USB_NUM_ENDPOINT_PAIRS_8_OR_GREATER := $(shell expr $(USB_NUM_ENDPOINT_PAIRS) '>=' 8) @@ -567,6 +573,9 @@ CFLAGS += -DUSB_NUM_IN_ENDPOINTS=$(USB_NUM_IN_ENDPOINTS) USB_NUM_OUT_ENDPOINTS ?= $(USB_NUM_ENDPOINT_PAIRS) CFLAGS += -DUSB_NUM_OUT_ENDPOINTS=$(USB_NUM_OUT_ENDPOINTS) +CIRCUITPY_USB_IDENTIFICATION ?= $(CIRCUITPY_USB_DEVICE) +CFLAGS += -DCIRCUITPY_USB_IDENTIFICATION=$(CIRCUITPY_USB_IDENTIFICATION) + CIRCUITPY_USB_CDC ?= $(CIRCUITPY_USB_DEVICE) CFLAGS += -DCIRCUITPY_USB_CDC=$(CIRCUITPY_USB_CDC) CIRCUITPY_USB_CDC_CONSOLE_ENABLED_DEFAULT ?= 1 @@ -586,19 +595,6 @@ CFLAGS += -DCIRCUITPY_USB_VIDEO=$(CIRCUITPY_USB_VIDEO) CIRCUITPY_USB_HOST ?= 0 CFLAGS += -DCIRCUITPY_USB_HOST=$(CIRCUITPY_USB_HOST) -CIRCUITPY_PYUSB ?= $(call enable-if-any,$(CIRCUITPY_USB_HOST) $(CIRCUITPY_MAX3421E)) -CFLAGS += -DCIRCUITPY_PYUSB=$(CIRCUITPY_PYUSB) - -CIRCUITPY_USB_IDENTIFICATION ?= $(CIRCUITPY_USB_DEVICE) -CFLAGS += -DCIRCUITPY_USB_IDENTIFICATION=$(CIRCUITPY_USB_IDENTIFICATION) - -CIRCUITPY_TINYUSB_HOST ?= $(call enable-if-any,$(CIRCUITPY_USB_HOST) $(CIRCUITPY_MAX3421E)) -CIRCUITPY_USB_KEYBOARD_WORKFLOW ?= $(CIRCUITPY_TINYUSB_HOST) -CFLAGS += -DCIRCUITPY_USB_KEYBOARD_WORKFLOW=$(CIRCUITPY_USB_KEYBOARD_WORKFLOW) - -CIRCUITPY_TINYUSB ?= $(call enable-if-any,$(CIRCUITPY_TINYUSB_HOST) $(CIRCUITPY_USB_DEVICE)) -CFLAGS += -DCIRCUITPY_TINYUSB=$(CIRCUITPY_TINYUSB) - # MIDI is available by default, but is not turned on if there are fewer than 8 endpoints. CIRCUITPY_USB_MIDI ?= $(CIRCUITPY_USB_DEVICE) CFLAGS += -DCIRCUITPY_USB_MIDI=$(CIRCUITPY_USB_MIDI) @@ -615,11 +611,25 @@ CFLAGS += -DCIRCUITPY_USB_MSC_ENABLED_DEFAULT=$(CIRCUITPY_USB_MSC_ENABLED_DEFAUL # setting in their mpconfigport.mk and/or mpconfigboard.mk files yet. CIRCUITPY_USB_VENDOR ?= 0 CFLAGS += -DCIRCUITPY_USB_VENDOR=$(CIRCUITPY_USB_VENDOR) - -ifndef USB_NUM_ENDPOINT_PAIRS -$(error "USB_NUM_ENDPOINT_PAIRS (number of USB endpoint pairs)must be defined") endif -CFLAGS += -DUSB_NUM_ENDPOINT_PAIRS=$(USB_NUM_ENDPOINT_PAIRS) + + +CIRCUITPY_PYUSB ?= $(call enable-if-any,$(CIRCUITPY_USB_HOST) $(CIRCUITPY_MAX3421E)) +CFLAGS += -DCIRCUITPY_PYUSB=$(CIRCUITPY_PYUSB) + +CIRCUITPY_TINYUSB_HOST ?= $(call enable-if-any,$(CIRCUITPY_USB_HOST) $(CIRCUITPY_MAX3421E)) + +CIRCUITPY_TINYUSB ?= $(call enable-if-any,$(CIRCUITPY_TINYUSB_HOST) $(CIRCUITPY_USB_DEVICE)) +CFLAGS += -DCIRCUITPY_TINYUSB=$(CIRCUITPY_TINYUSB) + +CIRCUITPY_USB_HOST ?= 0 +CFLAGS += -DCIRCUITPY_USB_HOST=$(CIRCUITPY_USB_HOST) + +CIRCUITPY_PYUSB ?= $(call enable-if-any,$(CIRCUITPY_USB_HOST) $(CIRCUITPY_MAX3421E)) +CFLAGS += -DCIRCUITPY_PYUSB=$(CIRCUITPY_PYUSB) + +CIRCUITPY_USB_KEYBOARD_WORKFLOW ?= $(call enable-if-any,$(CIRCUITPY_USB_HOST) $(CIRCUITPY_MAX3421E)) +CFLAGS += -DCIRCUITPY_USB_KEYBOARD_WORKFLOW=$(CIRCUITPY_USB_KEYBOARD_WORKFLOW) # For debugging. CIRCUITPY_USTACK ?= 0 diff --git a/shared-bindings/storage/__init__.c b/shared-bindings/storage/__init__.c index 608f0d4d3ce6..880088bbb347 100644 --- a/shared-bindings/storage/__init__.c +++ b/shared-bindings/storage/__init__.c @@ -203,7 +203,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(storage_erase_filesystem_obj, 0, storage_erase_filesy //| ... //| STATIC mp_obj_t storage_disable_usb_drive(void) { - #if CIRCUITPY_USB_MSC + #if CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_MSC if (!common_hal_storage_disable_usb_drive()) { #else if (true) { @@ -228,7 +228,7 @@ MP_DEFINE_CONST_FUN_OBJ_0(storage_disable_usb_drive_obj, storage_disable_usb_dri //| ... //| STATIC mp_obj_t storage_enable_usb_drive(void) { - #if CIRCUITPY_USB_MSC + #if CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_MSC if (!common_hal_storage_enable_usb_drive()) { #else if (true) { diff --git a/shared-bindings/supervisor/__init__.c b/shared-bindings/supervisor/__init__.c index b59c6236e51b..692f02f0e8fd 100644 --- a/shared-bindings/supervisor/__init__.c +++ b/shared-bindings/supervisor/__init__.c @@ -36,7 +36,7 @@ #include "supervisor/shared/traceback.h" #include "supervisor/shared/workflow.h" -#if CIRCUITPY_USB_IDENTIFICATION +#if CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_IDENTIFICATION #include "supervisor/usb.h" #endif @@ -279,7 +279,7 @@ MP_DEFINE_CONST_FUN_OBJ_2(supervisor_reset_terminal_obj, supervisor_reset_termin //| ... //| STATIC mp_obj_t supervisor_set_usb_identification(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - #if CIRCUITPY_USB_IDENTIFICATION + #if CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_IDENTIFICATION static const mp_arg_t allowed_args[] = { { MP_QSTR_manufacturer, MP_ARG_OBJ, {.u_rom_obj = mp_const_none} }, { MP_QSTR_product, MP_ARG_OBJ, {.u_rom_obj = mp_const_none} }, diff --git a/shared-bindings/supervisor/__init__.h b/shared-bindings/supervisor/__init__.h index ec98be946172..134dc18d3bfb 100644 --- a/shared-bindings/supervisor/__init__.h +++ b/shared-bindings/supervisor/__init__.h @@ -24,15 +24,17 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_SUPERVISOR___INIT___H -#define MICROPY_INCLUDED_SHARED_BINDINGS_SUPERVISOR___INIT___H +#pragma once // #include "py/mpconfig.h" #include "py/obj.h" #include "shared-module/supervisor/Runtime.h" #include "shared-module/supervisor/StatusBar.h" + +#if CIRCUITPY_USB_DEVICE #include "supervisor/usb.h" +#endif typedef struct { uint8_t options; @@ -46,6 +48,7 @@ extern mp_obj_t supervisor_ticks_ms(void); extern char *prev_traceback_string; extern supervisor_next_code_info_t *next_code_configuration; -extern usb_identification_t *custom_usb_identification; -#endif // MICROPY_INCLUDED_SHARED_BINDINGS_SUPERVISOR___INIT___H +#if CIRCUITPY_USB_DEVICE +extern usb_identification_t *custom_usb_identification; +#endif diff --git a/shared-module/busdisplay/BusDisplay.c b/shared-module/busdisplay/BusDisplay.c index ef76613f1731..3753a1c2407a 100644 --- a/shared-module/busdisplay/BusDisplay.c +++ b/shared-module/busdisplay/BusDisplay.c @@ -42,7 +42,10 @@ #include "shared-module/displayio/display_core.h" #include "supervisor/shared/display.h" #include "supervisor/shared/tick.h" + +#if CIRCUITPY_TINYUSB #include "supervisor/usb.h" +#endif #include #include diff --git a/shared-module/epaperdisplay/EPaperDisplay.c b/shared-module/epaperdisplay/EPaperDisplay.c index 96ad6e2d2ebd..15013bb7e738 100644 --- a/shared-module/epaperdisplay/EPaperDisplay.c +++ b/shared-module/epaperdisplay/EPaperDisplay.c @@ -35,7 +35,10 @@ #include "shared-module/displayio/__init__.h" #include "supervisor/shared/display.h" #include "supervisor/shared/tick.h" + +#if CIRCUITPY_TINYUSB #include "supervisor/usb.h" +#endif #include #include diff --git a/shared-module/framebufferio/FramebufferDisplay.c b/shared-module/framebufferio/FramebufferDisplay.c index a217dc809b6d..9e9c9a093f2c 100644 --- a/shared-module/framebufferio/FramebufferDisplay.c +++ b/shared-module/framebufferio/FramebufferDisplay.c @@ -35,7 +35,10 @@ #include "shared-module/displayio/display_core.h" #include "supervisor/shared/display.h" #include "supervisor/shared/tick.h" + +#if CIRCUITPY_TINYUSB #include "supervisor/usb.h" +#endif #include #include diff --git a/shared-module/storage/__init__.c b/shared-module/storage/__init__.c index 31180571c45d..8e106415a38c 100644 --- a/shared-module/storage/__init__.c +++ b/shared-module/storage/__init__.c @@ -38,9 +38,12 @@ #include "shared-bindings/storage/__init__.h" #include "supervisor/filesystem.h" #include "supervisor/flash.h" + +#if CIRCUITPY_USB_DEVICE #include "supervisor/usb.h" +#endif -#if CIRCUITPY_USB_MSC +#if CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_MSC #include "tusb.h" static const uint8_t usb_msc_descriptor_template[] = { @@ -262,7 +265,7 @@ void common_hal_storage_remount(const char *mount_path, bool readonly, bool disa mp_raise_OSError(MP_EINVAL); } - #if CIRCUITPY_USB_MSC + #if CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_MSC if (!usb_msc_ejected() && storage_usb_is_enabled) { mp_raise_RuntimeError(MP_ERROR_TEXT("Cannot remount '/' when visible via USB.")); } diff --git a/shared-module/storage/__init__.h b/shared-module/storage/__init__.h index d95ea851cfe5..cbcf6f5b9967 100644 --- a/shared-module/storage/__init__.h +++ b/shared-module/storage/__init__.h @@ -26,10 +26,9 @@ #pragma once -#include "py/mpconfig.h" +#if CIRCUITPY_USB_DEVICE #include "supervisor/usb.h" -#if CIRCUITPY_USB_DEVICE bool storage_usb_enabled(void); void storage_usb_set_defaults(void); size_t storage_usb_descriptor_length(void); diff --git a/shared-module/supervisor/__init__.c b/shared-module/supervisor/__init__.c index 8e346251737c..9a0a0a7b7d57 100644 --- a/shared-module/supervisor/__init__.c +++ b/shared-module/supervisor/__init__.c @@ -50,5 +50,7 @@ char *prev_traceback_string = NULL; // Custom settings for next code run. supervisor_next_code_info_t *next_code_configuration = NULL; +#if CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_IDENTIFICATION // Custom USB settings. usb_identification_t *custom_usb_identification = NULL; +#endif diff --git a/supervisor/shared/bluetooth/file_transfer.c b/supervisor/shared/bluetooth/file_transfer.c index df95451c8155..628d06f99db2 100644 --- a/supervisor/shared/bluetooth/file_transfer.c +++ b/supervisor/shared/bluetooth/file_transfer.c @@ -26,32 +26,22 @@ #include -#include "extmod/vfs.h" #include "extmod/vfs_fat.h" #include "shared/timeutils/timeutils.h" -#include "shared-bindings/_bleio/__init__.h" -#include "shared-bindings/_bleio/Adapter.h" #include "shared-bindings/_bleio/Characteristic.h" #include "shared-bindings/_bleio/PacketBuffer.h" #include "shared-bindings/_bleio/Service.h" #include "shared-bindings/_bleio/UUID.h" -#include "shared-module/storage/__init__.h" #include "bluetooth/ble_drv.h" -#include "common-hal/_bleio/__init__.h" - #include "supervisor/fatfs.h" #include "supervisor/filesystem.h" #include "supervisor/shared/reload.h" #include "supervisor/shared/bluetooth/file_transfer.h" #include "supervisor/shared/bluetooth/file_transfer_protocol.h" #include "supervisor/shared/workflow.h" -#include "supervisor/shared/tick.h" -#include "supervisor/usb.h" - -#include "py/mpstate.h" STATIC bleio_service_obj_t supervisor_ble_service; STATIC bleio_uuid_obj_t supervisor_ble_service_uuid; diff --git a/supervisor/shared/serial.c b/supervisor/shared/serial.c index 5b0a62090bac..abea966b59d1 100644 --- a/supervisor/shared/serial.c +++ b/supervisor/shared/serial.c @@ -34,15 +34,18 @@ #include "supervisor/shared/display.h" #include "shared-bindings/terminalio/Terminal.h" #include "supervisor/shared/serial.h" -#include "supervisor/usb.h" #include "shared-bindings/microcontroller/Pin.h" -#include "shared-module/usb_cdc/__init__.h" #if CIRCUITPY_SERIAL_BLE #include "supervisor/shared/bluetooth/serial.h" #endif +#if CIRCUITPY_USB_DEVICE +#include "shared-module/usb_cdc/__init__.h" +#endif + #if CIRCUITPY_TINYUSB +#include "supervisor/usb.h" #include "tusb.h" #endif @@ -70,7 +73,7 @@ byte console_uart_rx_buf[64]; static bool _first_write_done = false; #endif -#if CIRCUITPY_USB_VENDOR +#if CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_VENDOR bool tud_vendor_connected(void); #endif @@ -185,7 +188,7 @@ void serial_init(void) { } bool serial_connected(void) { - #if CIRCUITPY_USB_VENDOR + #if CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_VENDOR if (tud_vendor_connected()) { return true; } @@ -201,7 +204,7 @@ bool serial_connected(void) { } #endif - #if CIRCUITPY_USB_CDC + #if CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_CDC if (usb_cdc_console_enabled() && tud_cdc_connected()) { return true; } @@ -236,7 +239,7 @@ bool serial_connected(void) { } char serial_read(void) { - #if CIRCUITPY_USB_VENDOR + #if CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_VENDOR if (tud_vendor_connected() && tud_vendor_available() > 0) { char tiny_buffer; tud_vendor_read(&tiny_buffer, 1); @@ -282,7 +285,7 @@ char serial_read(void) { return port_serial_read(); } - #if CIRCUITPY_USB_CDC + #if CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_CDC if (!usb_cdc_console_enabled()) { return -1; } @@ -298,7 +301,7 @@ uint32_t serial_bytes_available(void) { // There may be multiple serial input channels, so sum the count from all. uint32_t count = 0; - #if CIRCUITPY_USB_VENDOR + #if CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_VENDOR if (tud_vendor_connected()) { count += tud_vendor_available(); } @@ -320,7 +323,7 @@ uint32_t serial_bytes_available(void) { count += usb_keyboard_chars_available(); #endif - #if CIRCUITPY_USB_CDC + #if CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_CDC if (usb_cdc_console_enabled()) { count += tud_cdc_available(); } @@ -355,7 +358,7 @@ void serial_write_substring(const char *text, uint32_t length) { return; } - #if CIRCUITPY_USB_VENDOR + #if CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_VENDOR if (tud_vendor_connected()) { tud_vendor_write(text, length); } @@ -378,7 +381,7 @@ void serial_write_substring(const char *text, uint32_t length) { websocket_write(text, length); #endif - #if CIRCUITPY_USB_CDC + #if CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_CDC if (!usb_cdc_console_enabled()) { return; } diff --git a/supervisor/shared/usb/usb.c b/supervisor/shared/usb/usb.c index 4905e2857029..bbd51678b236 100644 --- a/supervisor/shared/usb/usb.c +++ b/supervisor/shared/usb/usb.c @@ -40,7 +40,6 @@ #if CIRCUITPY_USB_DEVICE #include "shared-bindings/supervisor/__init__.h" -#endif #if CIRCUITPY_USB_CDC #include "shared-module/usb_cdc/__init__.h" @@ -58,6 +57,8 @@ #include "shared-module/usb_video/__init__.h" #endif +#endif + #include "tusb.h" bool usb_enabled(void) { @@ -71,17 +72,21 @@ void usb_init(void) { #if CIRCUITPY_USB_DEVICE usb_identification_t defaults; usb_identification_t *identification; + #if CIRCUITPY_USB_IDENTIFICATION if (custom_usb_identification != NULL) { identification = custom_usb_identification; } else { - // This compiles to less code than using a struct initializer. - defaults.vid = USB_VID; - defaults.pid = USB_PID; - strcpy(defaults.manufacturer_name, USB_MANUFACTURER); - strcpy(defaults.product_name, USB_PRODUCT); - identification = &defaults; - // This memory only needs to be live through the end of usb_build_descriptors. - } + #endif + // This compiles to less code than using a struct initializer. + defaults.vid = USB_VID; + defaults.pid = USB_PID; + strcpy(defaults.manufacturer_name, USB_MANUFACTURER); + strcpy(defaults.product_name, USB_PRODUCT); + identification = &defaults; + // This memory only needs to be live through the end of usb_build_descriptors. + #if CIRCUITPY_USB_IDENTIFICATION +} + #endif if (!usb_build_descriptors(identification)) { return; } @@ -96,7 +101,7 @@ void usb_init(void) { post_usb_init(); - #if MICROPY_KBD_EXCEPTION && CIRCUITPY_USB_CDC + #if MICROPY_KBD_EXCEPTION && CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_CDC // Set Ctrl+C as wanted char, tud_cdc_rx_wanted_cb() usb_callback will be invoked when Ctrl+C is received // This usb_callback always got invoked regardless of mp_interrupt_char value since we only set it once here @@ -110,6 +115,7 @@ void usb_init(void) { // Set up USB defaults before any USB changes are made in boot.py void usb_set_defaults(void) { + #if CIRCUITPY_USB_DEVICE #if CIRCUITPY_STORAGE && CIRCUITPY_USB_MSC storage_usb_set_defaults(); #endif @@ -125,10 +131,12 @@ void usb_set_defaults(void) { #if CIRCUITPY_USB_MIDI usb_midi_set_defaults(); #endif + #endif }; // Call this when ready to run code.py or a REPL, and a VM has been started. void usb_setup_with_vm(void) { + #if CIRCUITPY_USB_DEVICE #if CIRCUITPY_USB_HID usb_hid_setup_devices(); #endif @@ -136,6 +144,7 @@ void usb_setup_with_vm(void) { #if CIRCUITPY_USB_MIDI usb_midi_setup_ports(); #endif + #endif } void usb_background(void) { @@ -151,13 +160,13 @@ void usb_background(void) { vTaskDelay(0); #endif // No need to flush if there's no REPL. - #if CIRCUITPY_USB_CDC + #if CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_CDC if (usb_cdc_console_enabled()) { // Console will always be itf 0. tud_cdc_write_flush(); } #endif - #if CIRCUITPY_USB_VIDEO + #if CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_VIDEO usb_video_task(); #endif } diff --git a/supervisor/shared/web_workflow/web_workflow.c b/supervisor/shared/web_workflow/web_workflow.c index 7d32b2ad58c0..83b7bedd8ec7 100644 --- a/supervisor/shared/web_workflow/web_workflow.c +++ b/supervisor/shared/web_workflow/web_workflow.c @@ -35,24 +35,19 @@ #include "genhdr/mpversion.h" #include "py/mperrno.h" #include "py/mpstate.h" -#include "py/stackctrl.h" #include "shared-bindings/wifi/Radio.h" -#include "shared-module/storage/__init__.h" #include "shared/timeutils/timeutils.h" #include "supervisor/fatfs.h" #include "supervisor/filesystem.h" #include "supervisor/port.h" #include "supervisor/shared/reload.h" -#include "supervisor/shared/translate/translate.h" #include "supervisor/shared/web_workflow/web_workflow.h" #include "supervisor/shared/web_workflow/websocket.h" #include "supervisor/shared/workflow.h" -#include "supervisor/usb.h" #include "shared-bindings/hashlib/__init__.h" #include "shared-bindings/hashlib/Hash.h" -#include "lib/oofatfs/diskio.h" #if CIRCUITPY_FOURWIRE #include "shared-module/displayio/__init__.h" @@ -64,7 +59,6 @@ #endif #include "shared-bindings/microcontroller/Processor.h" -#include "shared-bindings/socketpool/__init__.h" #include "shared-bindings/socketpool/Socket.h" #include "shared-bindings/socketpool/SocketPool.h" diff --git a/tools/ci_check_duplicate_usb_vid_pid.py b/tools/ci_check_duplicate_usb_vid_pid.py index 1b432b98704a..26e8ad0d22da 100644 --- a/tools/ci_check_duplicate_usb_vid_pid.py +++ b/tools/ci_check_duplicate_usb_vid_pid.py @@ -110,6 +110,10 @@ def check_vid_pid(files, clusterlist): creation = CREATION_PATTERN.search(src_text) non_usb = usb_pattern.search(src_text) board_name = board_config.parts[-2] + port_name = board_config.parts[-4] + + if port_name == "renode": + continue if usb_vid and usb_pid: id_group = f"0x{int(usb_vid.group(1), 16):04X}:0x{int(usb_pid.group(1), 16):04X}" diff --git a/tools/ci_fetch_deps.py b/tools/ci_fetch_deps.py index 5f6c4c2d7d94..bf465d0ecfb4 100644 --- a/tools/ci_fetch_deps.py +++ b/tools/ci_fetch_deps.py @@ -88,6 +88,7 @@ def matching_submodules(s): "lib/tlsf", "data/nvm.toml/", ], + "renode": ["lib/tlsf"], "silabs": ["extmod/ulab/", "data/nvm.toml/", "lib/tlsf"], "stm": [ "extmod/ulab/",