From 67357431df7a53ff5ec88436889a72e7cd860b76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Thu, 25 Jun 2026 10:32:18 -0600 Subject: [PATCH 01/58] Add nanoFramework.Hardware.Rp2040 PIO native assembly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds the PIO library's InternalCall native implementations to the RP_PICO_RP2040 target following the standard class-library integration (same pattern as nanoFramework.Hardware.Stm32): - Kconfig API_HARDWARE_RP2040 (Kconfig.apis) + NF_Kconfig.cmake mapping + defconfig enable - FindnanoFramework.Hardware.Rp2040.cmake + registration in FindNF_NativeAssemblies.cmake - native sources in targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/ (MDP-generated table/marshalling + hand-written register implementations) The RP2040 ChibiOS port has no pico-sdk hardware_pio, so the implementations drive the PIO peripheral registers directly via the CMSIS RP2040 device header. The MDP-generated table carries the managed assembly checksum (0xBC826B58) so the CLR binds the InternalCalls. Firmware builds and boots the C# deployment on the RP2040Sharp emulator. Signed-off-by: Iván Montiel Cardona --- CMake/Modules/FindNF_NativeAssemblies.cmake | 7 + .../FindnanoFramework.Hardware.Rp2040.cmake | 47 ++++ CMake/Modules/NF_Kconfig.cmake | 1 + Kconfig.apis | 5 + targets/ChibiOS/PICO_RP2040_W/defconfig | 1 + .../nanoFramework_Hardware_Rp2040.cpp | 153 ++++++++++++ .../nanoFramework_Hardware_Rp2040.h | 236 ++++++++++++++++++ ...Framework_Hardware_Rp2040_Pio_PioBlock.cpp | 83 ++++++ ...noFramework_Hardware_Rp2040_Pio_PioBlock.h | 35 +++ ...work_Hardware_Rp2040_Pio_PioBlock_mshl.cpp | 76 ++++++ ...rk_Hardware_Rp2040_Pio_PioStateMachine.cpp | 182 ++++++++++++++ ...work_Hardware_Rp2040_Pio_PioStateMachine.h | 43 ++++ ...rdware_Rp2040_Pio_PioStateMachine_mshl.cpp | 151 +++++++++++ 13 files changed, 1020 insertions(+) create mode 100644 CMake/Modules/FindnanoFramework.Hardware.Rp2040.cmake create mode 100644 targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040.cpp create mode 100644 targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040.h create mode 100644 targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.cpp create mode 100644 targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.h create mode 100644 targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock_mshl.cpp create mode 100644 targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.cpp create mode 100644 targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.h create mode 100644 targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine_mshl.cpp diff --git a/CMake/Modules/FindNF_NativeAssemblies.cmake b/CMake/Modules/FindNF_NativeAssemblies.cmake index 2d52b64b7b..5398d4ab13 100644 --- a/CMake/Modules/FindNF_NativeAssemblies.cmake +++ b/CMake/Modules/FindNF_NativeAssemblies.cmake @@ -42,6 +42,7 @@ option(API_nanoFramework.Networking.Thread "option for nanoFramewor # Stm32 only option(API_Hardware.Stm32 "option for Hardware.Stm32") +option(API_Hardware.Rp2040 "option for Hardware.Rp2040") # TI CC13xxCC26xx option(API_nanoFramework.TI.EasyLink "option for nanoFramework.TI.EasyLink API") @@ -270,6 +271,12 @@ if(API_Hardware.Stm32) PerformSettingsForApiEntry("nanoFramework.Hardware.Stm32") endif() +# Hardware.Rp2040 +if(API_Hardware.Rp2040) + ##### API name here (doted name) + PerformSettingsForApiEntry("nanoFramework.Hardware.Rp2040") +endif() + # nanoFramework.Device.Can if(API_nanoFramework.Device.Can) ##### API name here (doted name) diff --git a/CMake/Modules/FindnanoFramework.Hardware.Rp2040.cmake b/CMake/Modules/FindnanoFramework.Hardware.Rp2040.cmake new file mode 100644 index 0000000000..fdd5ea59ef --- /dev/null +++ b/CMake/Modules/FindnanoFramework.Hardware.Rp2040.cmake @@ -0,0 +1,47 @@ +# +# Copyright (c) .NET Foundation and Contributors +# See LICENSE file in the project root for full license information. +# + + +# native code directory +set(BASE_PATH_FOR_THIS_MODULE "${BASE_PATH_FOR_CLASS_LIBRARIES_MODULES}/nanoFramework.Hardware.Rp2040") + + +# set include directories +list(APPEND nanoFramework.Hardware.Rp2040_INCLUDE_DIRS "${BASE_PATH_FOR_THIS_MODULE}") + + +# source files +set(nanoFramework.Hardware.Rp2040_SRCS + + nanoFramework_Hardware_Rp2040.cpp + nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.cpp + nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock_mshl.cpp + nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.cpp + nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine_mshl.cpp +) + +foreach(SRC_FILE ${nanoFramework.Hardware.Rp2040_SRCS}) + + set(nanoFramework.Hardware.Rp2040_SRC_FILE SRC_FILE-NOTFOUND) + + find_file(nanoFramework.Hardware.Rp2040_SRC_FILE ${SRC_FILE} + PATHS + ${BASE_PATH_FOR_THIS_MODULE} + + CMAKE_FIND_ROOT_PATH_BOTH + ) + + if (BUILD_VERBOSE) + message("${SRC_FILE} >> ${nanoFramework.Hardware.Rp2040_SRC_FILE}") + endif() + + list(APPEND nanoFramework.Hardware.Rp2040_SOURCES ${nanoFramework.Hardware.Rp2040_SRC_FILE}) + +endforeach() + + +include(FindPackageHandleStandardArgs) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS(nanoFramework.Hardware.Rp2040 DEFAULT_MSG nanoFramework.Hardware.Rp2040_INCLUDE_DIRS nanoFramework.Hardware.Rp2040_SOURCES) diff --git a/CMake/Modules/NF_Kconfig.cmake b/CMake/Modules/NF_Kconfig.cmake index 1183cbba72..3b1dc6d431 100644 --- a/CMake/Modules/NF_Kconfig.cmake +++ b/CMake/Modules/NF_Kconfig.cmake @@ -43,6 +43,7 @@ set(_NF_KCONFIG_API_MAP # Platform-specific APIs "API_HARDWARE_STM32|API_Hardware.Stm32" + "API_HARDWARE_RP2040|API_Hardware.Rp2040" "API_HARDWARE_ESP32|API_Hardware.Esp32" "API_NANOFRAMEWORK_HARDWARE_ESP32_RMT|API_nanoFramework.Hardware.Esp32.Rmt" "API_NANOFRAMEWORK_HARDWARE_TI|API_nanoFramework.Hardware.TI" diff --git a/Kconfig.apis b/Kconfig.apis index 39b81eff66..36bd224bda 100644 --- a/Kconfig.apis +++ b/Kconfig.apis @@ -113,6 +113,11 @@ config API_HARDWARE_STM32 depends on RTOS_CHIBIOS default n +config API_HARDWARE_RP2040 + bool "Hardware.Rp2040" + depends on RTOS_CHIBIOS + default n + config API_HARDWARE_ESP32 bool "Hardware.Esp32" depends on RTOS_ESP32 diff --git a/targets/ChibiOS/PICO_RP2040_W/defconfig b/targets/ChibiOS/PICO_RP2040_W/defconfig index 5c5759133e..14cfe599f7 100644 --- a/targets/ChibiOS/PICO_RP2040_W/defconfig +++ b/targets/ChibiOS/PICO_RP2040_W/defconfig @@ -9,6 +9,7 @@ CONFIG_API_SYSTEM_DEVICE_WIFI=y CONFIG_API_SYSTEM_IO_FILESYSTEM=y CONFIG_API_SYSTEM_IO_PORTS=y CONFIG_API_SYSTEM_NET=y +CONFIG_API_HARDWARE_RP2040=y CONFIG_API_NANOFRAMEWORK_RESOURCEMANAGER=y CONFIG_API_NANOFRAMEWORK_SYSTEM_COLLECTIONS=y CONFIG_API_NANOFRAMEWORK_SYSTEM_TEXT=y diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040.cpp new file mode 100644 index 0000000000..b88a9ec9a5 --- /dev/null +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040.cpp @@ -0,0 +1,153 @@ + //----------------------------------------------------------------------------- + // + // ** DO NOT EDIT THIS FILE! ** + // This file was generated by a tool + // re-running the tool will overwrite this file. + // + //----------------------------------------------------------------------------- + + #include "nanoFramework_Hardware_Rp2040.h" + + // clang-format off + + static const CLR_RT_MethodHandler method_lookup[] = + { + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock::NativeAddProgram___STATIC__I4__I4__SZARRAY_U2__I4__I4, + Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock::NativeRemoveProgram___STATIC__VOID__I4__I4__I4, + Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock::NativeClaimUnusedSm___STATIC__I4__I4__BOOLEAN, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeInit___STATIC__VOID__I4__I4__I4__SZARRAY_U4, + Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeSetEnabled___STATIC__VOID__I4__I4__BOOLEAN, + Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativePutBlocking___STATIC__VOID__I4__I4__U4, + Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeGetBlocking___STATIC__U4__I4__I4, + Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeTxFull___STATIC__BOOLEAN__I4__I4, + Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeRxEmpty___STATIC__BOOLEAN__I4__I4, + Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeUnclaim___STATIC__VOID__I4__I4, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + }; + + const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Rp2040 = + { + "nanoFramework.Hardware.Rp2040", + 0xBC826B58, + method_lookup, + { 1, 0, 0, 0 } + }; + + // clang-format on + \ No newline at end of file diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040.h b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040.h new file mode 100644 index 0000000000..4733f3e4bd --- /dev/null +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040.h @@ -0,0 +1,236 @@ + //----------------------------------------------------------------------------- + // + // ** DO NOT EDIT THIS FILE! ** + // This file was generated by a tool + // re-running the tool will overwrite this file. + // + //----------------------------------------------------------------------------- + + #ifndef NANOFRAMEWORK_HARDWARE_RP2040_H + #define NANOFRAMEWORK_HARDWARE_RP2040_H + + #include + #include + #include + + typedef enum __nfpack PioCondition + { + PioCondition_Always = 0, + PioCondition_XZero = 1, + PioCondition_XPostDec = 2, + PioCondition_YZero = 3, + PioCondition_YPostDec = 4, + PioCondition_XNotEqualY = 5, + PioCondition_Pin = 6, + PioCondition_OsrNotEmpty = 7, + } PioCondition; + + typedef enum __nfpack PioDest + { + PioDest_Pins = 0, + PioDest_X = 1, + PioDest_Y = 2, + PioDest_Null = 3, + PioDest_PinDirs = 4, + PioDest_Pc = 5, + PioDest_Status = 5, + PioDest_Isr = 6, + PioDest_Osr = 7, + PioDest_Exec = 7, + } PioDest; + + typedef enum __nfpack PioMovOp + { + PioMovOp_None = 0, + PioMovOp_Invert = 1, + PioMovOp_BitReverse = 2, + } PioMovOp; + + typedef enum __nfpack PioShiftDir + { + PioShiftDir_Left = 0, + PioShiftDir_Right = 1, + } PioShiftDir; + + typedef enum __nfpack PioSrc + { + PioSrc_Pins = 0, + PioSrc_X = 1, + PioSrc_Y = 2, + PioSrc_Null = 3, + PioSrc_Status = 5, + PioSrc_Isr = 6, + PioSrc_Osr = 7, + } PioSrc; + + typedef enum __nfpack PioVersion + { + PioVersion_Rp2040 = 0, + PioVersion_Rp2350 = 1, + } PioVersion; + + typedef enum __nfpack PioWaitSource + { + PioWaitSource_Gpio = 0, + PioWaitSource_Pin = 1, + PioWaitSource_Irq = 2, + } PioWaitSource; + + struct Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_Pio + { + static const int FIELD_STATIC___blocks = 0; + + //--// + }; + + struct Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioAssemblerOptions + { + static const int FIELD__Version = 1; + static const int FIELD__SideSetCount = 2; + static const int FIELD__SideSetOpt = 3; + static const int FIELD__SideSetPinDirs = 4; + + //--// + }; + + struct Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioAssembler__Instr + { + static const int FIELD__BaseBits = 1; + static const int FIELD__Delay = 2; + static const int FIELD__SideValue = 3; + static const int FIELD__SideUsed = 4; + static const int FIELD__JmpLabel = 5; + + //--// + }; + + struct Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioInstructionRef + { + static const int FIELD___instr = 1; + + //--// + }; + + struct Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioLabel + { + // renamed backing field 'k__BackingField' + static const int FIELD__Id = 1; + // renamed backing field '
k__BackingField' + static const int FIELD__Address = 2; + + //--// + }; + + struct Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioAssembler + { + static const int FIELD___instrs = 1; + static const int FIELD___labels = 2; + static const int FIELD___version = 3; + static const int FIELD___sideSetCount = 4; + static const int FIELD___sideSetOpt = 5; + static const int FIELD___sideSetPinDirs = 6; + static const int FIELD___wrapTarget = 7; + static const int FIELD___wrap = 8; + static const int FIELD___origin = 9; + static const int FIELD___outShiftDir = 10; + static const int FIELD___autoPull = 11; + static const int FIELD___pullThreshold = 12; + static const int FIELD___inShiftDir = 13; + static const int FIELD___autoPush = 14; + static const int FIELD___pushThreshold = 15; + + //--// + }; + + struct Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock + { + static const int FIELD___index = 1; + + NANOCLR_NATIVE_DECLARE(NativeAddProgram___STATIC__I4__I4__SZARRAY_U2__I4__I4); + NANOCLR_NATIVE_DECLARE(NativeRemoveProgram___STATIC__VOID__I4__I4__I4); + NANOCLR_NATIVE_DECLARE(NativeClaimUnusedSm___STATIC__I4__I4__BOOLEAN); + + //--// + }; + + struct Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioProgram + { + // renamed backing field 'k__BackingField' + static const int FIELD__Instructions = 1; + // renamed backing field 'k__BackingField' + static const int FIELD__Wrap = 2; + // renamed backing field 'k__BackingField' + static const int FIELD__WrapTarget = 3; + // renamed backing field 'k__BackingField' + static const int FIELD__Origin = 4; + // renamed backing field 'k__BackingField' + static const int FIELD__SideSetCount = 5; + // renamed backing field 'k__BackingField' + static const int FIELD__SideSetOpt = 6; + // renamed backing field 'k__BackingField' + static const int FIELD__SideSetPinDirs = 7; + // renamed backing field 'k__BackingField' + static const int FIELD__OutShiftDir = 8; + // renamed backing field 'k__BackingField' + static const int FIELD__AutoPull = 9; + // renamed backing field 'k__BackingField' + static const int FIELD__PullThreshold = 10; + // renamed backing field 'k__BackingField' + static const int FIELD__InShiftDir = 11; + // renamed backing field 'k__BackingField' + static const int FIELD__AutoPush = 12; + // renamed backing field 'k__BackingField' + static const int FIELD__PushThreshold = 13; + // renamed backing field 'k__BackingField' + static const int FIELD__Version = 14; + + //--// + }; + + struct Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine + { + static const int FIELD___block = 1; + static const int FIELD___sm = 2; + static const int FIELD___disposed = 3; + + NANOCLR_NATIVE_DECLARE(NativeInit___STATIC__VOID__I4__I4__I4__SZARRAY_U4); + NANOCLR_NATIVE_DECLARE(NativeSetEnabled___STATIC__VOID__I4__I4__BOOLEAN); + NANOCLR_NATIVE_DECLARE(NativePutBlocking___STATIC__VOID__I4__I4__U4); + NANOCLR_NATIVE_DECLARE(NativeGetBlocking___STATIC__U4__I4__I4); + NANOCLR_NATIVE_DECLARE(NativeTxFull___STATIC__BOOLEAN__I4__I4); + NANOCLR_NATIVE_DECLARE(NativeRxEmpty___STATIC__BOOLEAN__I4__I4); + NANOCLR_NATIVE_DECLARE(NativeUnclaim___STATIC__VOID__I4__I4); + + //--// + }; + + struct Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachineConfig + { + static const int FIELD___outBase = 1; + static const int FIELD___outCount = 2; + static const int FIELD___setBase = 3; + static const int FIELD___setCount = 4; + static const int FIELD___sideSetBase = 5; + static const int FIELD___inBase = 6; + static const int FIELD___jmpPin = 7; + static const int FIELD___sideSetCount = 8; + static const int FIELD___sideSetOpt = 9; + static const int FIELD___sideSetPinDirs = 10; + static const int FIELD___outShiftDir = 11; + static const int FIELD___autoPull = 12; + static const int FIELD___pullThreshold = 13; + static const int FIELD___inShiftDir = 14; + static const int FIELD___autoPush = 15; + static const int FIELD___pushThreshold = 16; + static const int FIELD___wrapTarget = 17; + static const int FIELD___wrap = 18; + static const int FIELD___clkDivInt = 19; + static const int FIELD___clkDivFrac = 20; + + //--// + }; + + extern const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Rp2040; + + #endif // NANOFRAMEWORK_HARDWARE_RP2040_H + \ No newline at end of file diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.cpp new file mode 100644 index 0000000000..64abd06b7c --- /dev/null +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.cpp @@ -0,0 +1,83 @@ +// +// Copyright (c) .NET nanoFramework PIO contributors +// +// + +#include "nanoFramework_Hardware_Rp2040.h" +#include "nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.h" +#include "rp2040.h" + +using namespace nanoFramework_Hardware_Rp2040::nanoFramework_Hardware_Rp2040; + +static PIO_TypeDef *PioFromIndex(int index) +{ + switch (index) + { + case 0: + return PIO0; + case 1: + return PIO1; + default: + return nullptr; + } +} + +signed int PioBlock::NativeAddProgram( + signed int param0, + CLR_RT_TypedArray_UINT16 param1, + signed int param2, + signed int param3, + HRESULT &hr) +{ + (void)param3; + + PIO_TypeDef *pio = PioFromIndex(param0); + if (pio == nullptr) + { + hr = CLR_E_INVALID_PARAMETER; + return -1; + } + + unsigned short *instr = param1.GetBuffer(); + int length = param2; + for (int i = 0; i < length && i < 32; i++) + { + pio->INSTR_MEM[i] = instr[i]; + } + + return 0; +} + +void PioBlock::NativeRemoveProgram(signed int param0, signed int param1, signed int param2, HRESULT &hr) +{ + (void)param1; + (void)param2; + + PIO_TypeDef *pio = PioFromIndex(param0); + if (pio == nullptr) + { + hr = CLR_E_INVALID_PARAMETER; + } +} + +signed int PioBlock::NativeClaimUnusedSm(signed int param0, bool param1, HRESULT &hr) +{ + (void)param1; + + PIO_TypeDef *pio = PioFromIndex(param0); + if (pio == nullptr) + { + hr = CLR_E_INVALID_PARAMETER; + return -1; + } + + for (int sm = 0; sm < 4; sm++) + { + if ((pio->CTRL & (1u << sm)) == 0) + { + return sm; + } + } + + return 0; +} diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.h b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.h new file mode 100644 index 0000000000..a4e6b3e697 --- /dev/null +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.h @@ -0,0 +1,35 @@ +//----------------------------------------------------------------------------- +// +// ** WARNING! ** +// This file was generated automatically by a tool. +// Re-running the tool will overwrite this file. +// You should copy this file to a custom location +// before adding any customization in the copy to +// prevent loss of your changes when the tool is +// re-run. +// +//----------------------------------------------------------------------------- + +#ifndef NANOFRAMEWORK_HARDWARE_RP2040_NANOFRAMEWORK_HARDWARE_RP2040_NANOFRAMEWORK_HARDWARE_RP2040_PIO_PIOBLOCK_H +#define NANOFRAMEWORK_HARDWARE_RP2040_NANOFRAMEWORK_HARDWARE_RP2040_NANOFRAMEWORK_HARDWARE_RP2040_PIO_PIOBLOCK_H + +namespace nanoFramework_Hardware_Rp2040 +{ + namespace nanoFramework_Hardware_Rp2040 + { + struct PioBlock + { + // Helper Functions to access fields of managed object + // Declaration of stubs. These functions are implemented by Interop code developers + + static signed int NativeAddProgram( signed int param0, CLR_RT_TypedArray_UINT16 param1, signed int param2, signed int param3, HRESULT &hr ); + + static void NativeRemoveProgram( signed int param0, signed int param1, signed int param2, HRESULT &hr ); + + static signed int NativeClaimUnusedSm( signed int param0, bool param1, HRESULT &hr ); + + }; + } +} + +#endif // NANOFRAMEWORK_HARDWARE_RP2040_NANOFRAMEWORK_HARDWARE_RP2040_NANOFRAMEWORK_HARDWARE_RP2040_PIO_PIOBLOCK_H diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock_mshl.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock_mshl.cpp new file mode 100644 index 0000000000..5b1a83ca93 --- /dev/null +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock_mshl.cpp @@ -0,0 +1,76 @@ +//----------------------------------------------------------------------------- +// +// ** DO NOT EDIT THIS FILE! ** +// This file was generated by a tool +// re-running the tool will overwrite this file. +// +//----------------------------------------------------------------------------- + +#include "nanoFramework_Hardware_Rp2040.h" +#include "nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.h" + +using namespace nanoFramework_Hardware_Rp2040::nanoFramework_Hardware_Rp2040; + + +HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock::NativeAddProgram___STATIC__I4__I4__SZARRAY_U2__I4__I4( CLR_RT_StackFrame& stack ) +{ + NANOCLR_HEADER(); hr = S_OK; + { + + signed int param0; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 0, param0 ) ); + + CLR_RT_TypedArray_UINT16 param1; + NANOCLR_CHECK_HRESULT( Interop_Marshal_UINT16_ARRAY( stack, 1, param1 ) ); + + signed int param2; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 2, param2 ) ); + + signed int param3; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 3, param3 ) ); + + signed int retValue = PioBlock::NativeAddProgram( param0, param1, param2, param3, hr ); + NANOCLR_CHECK_HRESULT( hr ); + SetResult_INT32( stack, retValue ); + } + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock::NativeRemoveProgram___STATIC__VOID__I4__I4__I4( CLR_RT_StackFrame& stack ) +{ + NANOCLR_HEADER(); hr = S_OK; + { + + signed int param0; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 0, param0 ) ); + + signed int param1; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 1, param1 ) ); + + signed int param2; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 2, param2 ) ); + + PioBlock::NativeRemoveProgram( param0, param1, param2, hr ); + NANOCLR_CHECK_HRESULT( hr ); + + } + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock::NativeClaimUnusedSm___STATIC__I4__I4__BOOLEAN( CLR_RT_StackFrame& stack ) +{ + NANOCLR_HEADER(); hr = S_OK; + { + + signed int param0; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 0, param0 ) ); + + bool param1; + NANOCLR_CHECK_HRESULT( Interop_Marshal_bool( stack, 1, param1 ) ); + + signed int retValue = PioBlock::NativeClaimUnusedSm( param0, param1, hr ); + NANOCLR_CHECK_HRESULT( hr ); + SetResult_INT32( stack, retValue ); + } + NANOCLR_NOCLEANUP(); +} diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.cpp new file mode 100644 index 0000000000..5a3e52a649 --- /dev/null +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.cpp @@ -0,0 +1,182 @@ +// +// Copyright (c) .NET nanoFramework PIO contributors +// +// + +#include "nanoFramework_Hardware_Rp2040.h" +#include "nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.h" +#include "rp2040.h" + +using namespace nanoFramework_Hardware_Rp2040::nanoFramework_Hardware_Rp2040; + +enum PioCfgBlob +{ + PIO_CFG_OUT_BASE = 0, + PIO_CFG_OUT_COUNT = 1, + PIO_CFG_SET_BASE = 2, + PIO_CFG_SET_COUNT = 3, + PIO_CFG_SIDESET_BASE = 4, + PIO_CFG_SIDESET_COUNT = 5, + PIO_CFG_SIDESET_OPT = 6, + PIO_CFG_SIDESET_PINDIRS = 7, + PIO_CFG_IN_BASE = 8, + PIO_CFG_JMP_PIN = 9, + PIO_CFG_OUT_SHIFT_RIGHT = 10, + PIO_CFG_AUTOPULL = 11, + PIO_CFG_PULL_THRESHOLD = 12, + PIO_CFG_IN_SHIFT_RIGHT = 13, + PIO_CFG_AUTOPUSH = 14, + PIO_CFG_PUSH_THRESHOLD = 15, + PIO_CFG_WRAP_TARGET = 16, + PIO_CFG_WRAP = 17, + PIO_CFG_CLKDIV_INT = 18, + PIO_CFG_CLKDIV_FRAC = 19, + PIO_CFG_BLOB_LENGTH = 20, +}; + +static PIO_TypeDef *PioFromIndex(int index) +{ + switch (index) + { + case 0: + return PIO0; + case 1: + return PIO1; + default: + return nullptr; + } +} + +void PioStateMachine::NativeInit( + signed int param0, + signed int param1, + signed int param2, + CLR_RT_TypedArray_UINT32 param3, + HRESULT &hr) +{ + PIO_TypeDef *pio = PioFromIndex(param0); + int sm = param1; + if (pio == nullptr || sm < 0 || sm > 3 || param3.GetSize() < PIO_CFG_BLOB_LENGTH) + { + hr = CLR_E_INVALID_PARAMETER; + return; + } + + unsigned int *b = param3.GetBuffer(); + + pio->CTRL &= ~(1u << sm); + pio->CTRL |= (1u << (4 + sm)); // SM_RESTART + + pio->SM[sm].CLKDIV = (b[PIO_CFG_CLKDIV_INT] << 16) | (b[PIO_CFG_CLKDIV_FRAC] << 8); + + unsigned int sidesetTotal = b[PIO_CFG_SIDESET_COUNT] + b[PIO_CFG_SIDESET_OPT]; + pio->SM[sm].PINCTRL = + (sidesetTotal << 29) | (b[PIO_CFG_SET_COUNT] << 26) | (b[PIO_CFG_OUT_COUNT] << 20) | + (b[PIO_CFG_IN_BASE] << 15) | (b[PIO_CFG_SIDESET_BASE] << 10) | (b[PIO_CFG_SET_BASE] << 5) | + b[PIO_CFG_OUT_BASE]; + + unsigned int execCtrl = + (b[PIO_CFG_WRAP] << 12) | (b[PIO_CFG_WRAP_TARGET] << 7) | (b[PIO_CFG_JMP_PIN] << 24); + if (b[PIO_CFG_SIDESET_OPT]) + { + execCtrl |= (1u << 30); + } + if (b[PIO_CFG_SIDESET_PINDIRS]) + { + execCtrl |= (1u << 29); + } + pio->SM[sm].EXECCTRL = execCtrl; + + unsigned int pushThresh = b[PIO_CFG_PUSH_THRESHOLD] & 0x1F; + unsigned int pullThresh = b[PIO_CFG_PULL_THRESHOLD] & 0x1F; + pio->SM[sm].SHIFTCTRL = + (b[PIO_CFG_IN_SHIFT_RIGHT] << 18) | (b[PIO_CFG_OUT_SHIFT_RIGHT] << 19) | + (b[PIO_CFG_AUTOPUSH] << 16) | (b[PIO_CFG_AUTOPULL] << 17) | (pushThresh << 20) | + (pullThresh << 25); + + pio->SM[sm].INSTR = (unsigned int)(param2 & 0x1F); +} + +void PioStateMachine::NativeSetEnabled(signed int param0, signed int param1, bool param2, HRESULT &hr) +{ + PIO_TypeDef *pio = PioFromIndex(param0); + if (pio == nullptr) + { + hr = CLR_E_INVALID_PARAMETER; + return; + } + + if (param2) + { + pio->CTRL |= (1u << param1); + } + else + { + pio->CTRL &= ~(1u << param1); + } +} + +void PioStateMachine::NativePutBlocking(signed int param0, signed int param1, unsigned int param2, HRESULT &hr) +{ + PIO_TypeDef *pio = PioFromIndex(param0); + if (pio == nullptr) + { + hr = CLR_E_INVALID_PARAMETER; + return; + } + + while (pio->FSTAT & (1u << (16 + param1))) + { + } + pio->TXF[param1] = param2; +} + +unsigned int PioStateMachine::NativeGetBlocking(signed int param0, signed int param1, HRESULT &hr) +{ + PIO_TypeDef *pio = PioFromIndex(param0); + if (pio == nullptr) + { + hr = CLR_E_INVALID_PARAMETER; + return 0; + } + + while (pio->FSTAT & (1u << (8 + param1))) + { + } + return pio->RXF[param1]; +} + +bool PioStateMachine::NativeTxFull(signed int param0, signed int param1, HRESULT &hr) +{ + PIO_TypeDef *pio = PioFromIndex(param0); + if (pio == nullptr) + { + hr = CLR_E_INVALID_PARAMETER; + return false; + } + + return (pio->FSTAT & (1u << (16 + param1))) != 0; +} + +bool PioStateMachine::NativeRxEmpty(signed int param0, signed int param1, HRESULT &hr) +{ + PIO_TypeDef *pio = PioFromIndex(param0); + if (pio == nullptr) + { + hr = CLR_E_INVALID_PARAMETER; + return true; + } + + return (pio->FSTAT & (1u << (8 + param1))) != 0; +} + +void PioStateMachine::NativeUnclaim(signed int param0, signed int param1, HRESULT &hr) +{ + (void)param1; + + PIO_TypeDef *pio = PioFromIndex(param0); + if (pio == nullptr) + { + hr = CLR_E_INVALID_PARAMETER; + } +} diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.h b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.h new file mode 100644 index 0000000000..e680ba84d5 --- /dev/null +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.h @@ -0,0 +1,43 @@ +//----------------------------------------------------------------------------- +// +// ** WARNING! ** +// This file was generated automatically by a tool. +// Re-running the tool will overwrite this file. +// You should copy this file to a custom location +// before adding any customization in the copy to +// prevent loss of your changes when the tool is +// re-run. +// +//----------------------------------------------------------------------------- + +#ifndef NANOFRAMEWORK_HARDWARE_RP2040_NANOFRAMEWORK_HARDWARE_RP2040_NANOFRAMEWORK_HARDWARE_RP2040_PIO_PIOSTATEMACHINE_H +#define NANOFRAMEWORK_HARDWARE_RP2040_NANOFRAMEWORK_HARDWARE_RP2040_NANOFRAMEWORK_HARDWARE_RP2040_PIO_PIOSTATEMACHINE_H + +namespace nanoFramework_Hardware_Rp2040 +{ + namespace nanoFramework_Hardware_Rp2040 + { + struct PioStateMachine + { + // Helper Functions to access fields of managed object + // Declaration of stubs. These functions are implemented by Interop code developers + + static void NativeInit( signed int param0, signed int param1, signed int param2, CLR_RT_TypedArray_UINT32 param3, HRESULT &hr ); + + static void NativeSetEnabled( signed int param0, signed int param1, bool param2, HRESULT &hr ); + + static void NativePutBlocking( signed int param0, signed int param1, unsigned int param2, HRESULT &hr ); + + static unsigned int NativeGetBlocking( signed int param0, signed int param1, HRESULT &hr ); + + static bool NativeTxFull( signed int param0, signed int param1, HRESULT &hr ); + + static bool NativeRxEmpty( signed int param0, signed int param1, HRESULT &hr ); + + static void NativeUnclaim( signed int param0, signed int param1, HRESULT &hr ); + + }; + } +} + +#endif // NANOFRAMEWORK_HARDWARE_RP2040_NANOFRAMEWORK_HARDWARE_RP2040_NANOFRAMEWORK_HARDWARE_RP2040_PIO_PIOSTATEMACHINE_H diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine_mshl.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine_mshl.cpp new file mode 100644 index 0000000000..df5eafe04b --- /dev/null +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine_mshl.cpp @@ -0,0 +1,151 @@ +//----------------------------------------------------------------------------- +// +// ** DO NOT EDIT THIS FILE! ** +// This file was generated by a tool +// re-running the tool will overwrite this file. +// +//----------------------------------------------------------------------------- + +#include "nanoFramework_Hardware_Rp2040.h" +#include "nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.h" + +using namespace nanoFramework_Hardware_Rp2040::nanoFramework_Hardware_Rp2040; + + +HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeInit___STATIC__VOID__I4__I4__I4__SZARRAY_U4( CLR_RT_StackFrame& stack ) +{ + NANOCLR_HEADER(); hr = S_OK; + { + + signed int param0; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 0, param0 ) ); + + signed int param1; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 1, param1 ) ); + + signed int param2; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 2, param2 ) ); + + CLR_RT_TypedArray_UINT32 param3; + NANOCLR_CHECK_HRESULT( Interop_Marshal_UINT32_ARRAY( stack, 3, param3 ) ); + + PioStateMachine::NativeInit( param0, param1, param2, param3, hr ); + NANOCLR_CHECK_HRESULT( hr ); + + } + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeSetEnabled___STATIC__VOID__I4__I4__BOOLEAN( CLR_RT_StackFrame& stack ) +{ + NANOCLR_HEADER(); hr = S_OK; + { + + signed int param0; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 0, param0 ) ); + + signed int param1; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 1, param1 ) ); + + bool param2; + NANOCLR_CHECK_HRESULT( Interop_Marshal_bool( stack, 2, param2 ) ); + + PioStateMachine::NativeSetEnabled( param0, param1, param2, hr ); + NANOCLR_CHECK_HRESULT( hr ); + + } + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativePutBlocking___STATIC__VOID__I4__I4__U4( CLR_RT_StackFrame& stack ) +{ + NANOCLR_HEADER(); hr = S_OK; + { + + signed int param0; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 0, param0 ) ); + + signed int param1; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 1, param1 ) ); + + unsigned int param2; + NANOCLR_CHECK_HRESULT( Interop_Marshal_UINT32( stack, 2, param2 ) ); + + PioStateMachine::NativePutBlocking( param0, param1, param2, hr ); + NANOCLR_CHECK_HRESULT( hr ); + + } + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeGetBlocking___STATIC__U4__I4__I4( CLR_RT_StackFrame& stack ) +{ + NANOCLR_HEADER(); hr = S_OK; + { + + signed int param0; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 0, param0 ) ); + + signed int param1; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 1, param1 ) ); + + unsigned int retValue = PioStateMachine::NativeGetBlocking( param0, param1, hr ); + NANOCLR_CHECK_HRESULT( hr ); + SetResult_UINT32( stack, retValue ); + } + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeTxFull___STATIC__BOOLEAN__I4__I4( CLR_RT_StackFrame& stack ) +{ + NANOCLR_HEADER(); hr = S_OK; + { + + signed int param0; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 0, param0 ) ); + + signed int param1; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 1, param1 ) ); + + bool retValue = PioStateMachine::NativeTxFull( param0, param1, hr ); + NANOCLR_CHECK_HRESULT( hr ); + SetResult_bool( stack, retValue ); + } + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeRxEmpty___STATIC__BOOLEAN__I4__I4( CLR_RT_StackFrame& stack ) +{ + NANOCLR_HEADER(); hr = S_OK; + { + + signed int param0; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 0, param0 ) ); + + signed int param1; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 1, param1 ) ); + + bool retValue = PioStateMachine::NativeRxEmpty( param0, param1, hr ); + NANOCLR_CHECK_HRESULT( hr ); + SetResult_bool( stack, retValue ); + } + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeUnclaim___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) +{ + NANOCLR_HEADER(); hr = S_OK; + { + + signed int param0; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 0, param0 ) ); + + signed int param1; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 1, param1 ) ); + + PioStateMachine::NativeUnclaim( param0, param1, hr ); + NANOCLR_CHECK_HRESULT( hr ); + + } + NANOCLR_NOCLEANUP(); +} From 1282a807b662743e80427abf1c75993135d0ebcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Thu, 25 Jun 2026 10:32:18 -0600 Subject: [PATCH 02/58] Bump-allocate PIO instruction memory, relocate JMP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit NativeAddProgram loaded every program at offset 0, so only one PIO program (hence effectively one configured layout) could exist per block. Now it bump-allocates the next free instruction slot per block and relocates relocatable programs' JMP targets by the load offset, so several programs can share a block and drive several state machines at once. Honors a fixed origin when one is given. Same InternalCall signature (assembly checksum unchanged). Signed-off-by: Iván Montiel Cardona --- ...Framework_Hardware_Rp2040_Pio_PioBlock.cpp | 32 +++++++++++++++---- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.cpp index 64abd06b7c..c713dc2e40 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.cpp @@ -22,6 +22,8 @@ static PIO_TypeDef *PioFromIndex(int index) } } +static int s_nextFree[3] = {0, 0, 0}; + signed int PioBlock::NativeAddProgram( signed int param0, CLR_RT_TypedArray_UINT16 param1, @@ -29,10 +31,8 @@ signed int PioBlock::NativeAddProgram( signed int param3, HRESULT &hr) { - (void)param3; - PIO_TypeDef *pio = PioFromIndex(param0); - if (pio == nullptr) + if (pio == nullptr || param0 < 0 || param0 > 2) { hr = CLR_E_INVALID_PARAMETER; return -1; @@ -40,12 +40,32 @@ signed int PioBlock::NativeAddProgram( unsigned short *instr = param1.GetBuffer(); int length = param2; - for (int i = 0; i < length && i < 32; i++) + int origin = param3; + + int offset = origin >= 0 ? origin : s_nextFree[param0]; + if (offset + length > 32) { - pio->INSTR_MEM[i] = instr[i]; + return -1; // no room } - return 0; + bool relocate = origin < 0; + for (int i = 0; i < length; i++) + { + unsigned short w = instr[i]; + if (relocate && (w & 0xE000) == 0x0000) + { + unsigned int target = ((unsigned int)(w & 0x1F) + (unsigned int)offset) & 0x1F; + w = (unsigned short)((w & ~0x1F) | target); + } + pio->INSTR_MEM[offset + i] = w; + } + + if (origin < 0) + { + s_nextFree[param0] = offset + length; + } + + return offset; } void PioBlock::NativeRemoveProgram(signed int param0, signed int param1, signed int param2, HRESULT &hr) From 1cc4be2c5db271fec74a3782fa0128b1d2045a09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Thu, 25 Jun 2026 10:32:18 -0600 Subject: [PATCH 03/58] Add pio_gpio_init and set_consecutive_pindirs interop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds NativeInitGpio (routes a pad to PIO0/PIO1 via IO_BANK0 FUNCSEL + enables the pad) and NativeSetConsecutivePinDirs (mirrors pio_sm_set_consecutive_pindirs by pointing the SM's SET group at the pins and executing SET pindirs in chunks of 5). Regenerated the MDP table/headers for the two new InternalCalls. Lets a deployed C# program actually drive GPIO pins from PIO. Signed-off-by: Iván Montiel Cardona --- .../nanoFramework_Hardware_Rp2040.cpp | 10 +++++- .../nanoFramework_Hardware_Rp2040.h | 2 ++ ...Framework_Hardware_Rp2040_Pio_PioBlock.cpp | 14 ++++++++ ...noFramework_Hardware_Rp2040_Pio_PioBlock.h | 2 ++ ...work_Hardware_Rp2040_Pio_PioBlock_mshl.cpp | 18 ++++++++++ ...rk_Hardware_Rp2040_Pio_PioStateMachine.cpp | 35 +++++++++++++++++++ ...work_Hardware_Rp2040_Pio_PioStateMachine.h | 2 ++ ...rdware_Rp2040_Pio_PioStateMachine_mshl.cpp | 27 ++++++++++++++ 8 files changed, 109 insertions(+), 1 deletion(-) diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040.cpp index b88a9ec9a5..8d85e57f97 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040.cpp @@ -65,9 +65,16 @@ NULL, NULL, NULL, + NULL, + NULL, + NULL, + NULL, + NULL, Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock::NativeAddProgram___STATIC__I4__I4__SZARRAY_U2__I4__I4, Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock::NativeRemoveProgram___STATIC__VOID__I4__I4__I4, Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock::NativeClaimUnusedSm___STATIC__I4__I4__BOOLEAN, + Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock::NativeInitGpio___STATIC__VOID__I4__I4, + NULL, NULL, NULL, NULL, @@ -127,6 +134,7 @@ Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeTxFull___STATIC__BOOLEAN__I4__I4, Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeRxEmpty___STATIC__BOOLEAN__I4__I4, Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeUnclaim___STATIC__VOID__I4__I4, + Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeSetConsecutivePinDirs___STATIC__VOID__I4__I4__I4__I4__BOOLEAN, NULL, NULL, NULL, @@ -144,7 +152,7 @@ const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Rp2040 = { "nanoFramework.Hardware.Rp2040", - 0xBC826B58, + 0x4888E4A4, method_lookup, { 1, 0, 0, 0 } }; diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040.h b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040.h index 4733f3e4bd..6073495006 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040.h +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040.h @@ -149,6 +149,7 @@ NANOCLR_NATIVE_DECLARE(NativeAddProgram___STATIC__I4__I4__SZARRAY_U2__I4__I4); NANOCLR_NATIVE_DECLARE(NativeRemoveProgram___STATIC__VOID__I4__I4__I4); NANOCLR_NATIVE_DECLARE(NativeClaimUnusedSm___STATIC__I4__I4__BOOLEAN); + NANOCLR_NATIVE_DECLARE(NativeInitGpio___STATIC__VOID__I4__I4); //--// }; @@ -200,6 +201,7 @@ NANOCLR_NATIVE_DECLARE(NativeTxFull___STATIC__BOOLEAN__I4__I4); NANOCLR_NATIVE_DECLARE(NativeRxEmpty___STATIC__BOOLEAN__I4__I4); NANOCLR_NATIVE_DECLARE(NativeUnclaim___STATIC__VOID__I4__I4); + NANOCLR_NATIVE_DECLARE(NativeSetConsecutivePinDirs___STATIC__VOID__I4__I4__I4__I4__BOOLEAN); //--// }; diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.cpp index c713dc2e40..c581c6f973 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.cpp @@ -101,3 +101,17 @@ signed int PioBlock::NativeClaimUnusedSm(signed int param0, bool param1, HRESULT return 0; } + +void PioBlock::NativeInitGpio(signed int param0, signed int param1, HRESULT &hr) +{ + int block = param0; + int pin = param1; + if (block < 0 || block > 1 || pin < 0 || pin > 29) + { + hr = CLR_E_INVALID_PARAMETER; + return; + } + + IO_BANK0->GPIO[pin].CTRL = (block == 0) ? 6u : 7u; + PADS_BANK0->GPIO[pin] = (PADS_BANK0->GPIO[pin] & ~0x80u) | 0x40u; // clear OD, set IE +} diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.h b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.h index a4e6b3e697..f8f99a43c0 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.h +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.h @@ -28,6 +28,8 @@ namespace nanoFramework_Hardware_Rp2040 static signed int NativeClaimUnusedSm( signed int param0, bool param1, HRESULT &hr ); + static void NativeInitGpio( signed int param0, signed int param1, HRESULT &hr ); + }; } } diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock_mshl.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock_mshl.cpp index 5b1a83ca93..b9fd5f27e9 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock_mshl.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock_mshl.cpp @@ -74,3 +74,21 @@ HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_ } NANOCLR_NOCLEANUP(); } + +HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock::NativeInitGpio___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) +{ + NANOCLR_HEADER(); hr = S_OK; + { + + signed int param0; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 0, param0 ) ); + + signed int param1; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 1, param1 ) ); + + PioBlock::NativeInitGpio( param0, param1, hr ); + NANOCLR_CHECK_HRESULT( hr ); + + } + NANOCLR_NOCLEANUP(); +} diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.cpp index 5a3e52a649..0c625e74bf 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.cpp @@ -180,3 +180,38 @@ void PioStateMachine::NativeUnclaim(signed int param0, signed int param1, HRESUL hr = CLR_E_INVALID_PARAMETER; } } + +void PioStateMachine::NativeSetConsecutivePinDirs( + signed int param0, + signed int param1, + signed int param2, + signed int param3, + bool param4, + HRESULT &hr) +{ + PIO_TypeDef *pio = PioFromIndex(param0); + int sm = param1; + if (pio == nullptr || sm < 0 || sm > 3) + { + hr = CLR_E_INVALID_PARAMETER; + return; + } + + int pin = param2; + int remaining = param3; + unsigned int savedPinCtrl = pio->SM[sm].PINCTRL; + + while (remaining > 0) + { + int chunk = remaining < 5 ? remaining : 5; + unsigned int dirs = param4 ? ((1u << chunk) - 1u) : 0u; + + pio->SM[sm].PINCTRL = ((unsigned int)chunk << 26) | ((unsigned int)pin << 5); + pio->SM[sm].INSTR = 0xE000u | (4u << 5) | (dirs & 0x1Fu); + + remaining -= chunk; + pin += chunk; + } + + pio->SM[sm].PINCTRL = savedPinCtrl; +} diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.h b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.h index e680ba84d5..2a3404d726 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.h +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.h @@ -36,6 +36,8 @@ namespace nanoFramework_Hardware_Rp2040 static void NativeUnclaim( signed int param0, signed int param1, HRESULT &hr ); + static void NativeSetConsecutivePinDirs( signed int param0, signed int param1, signed int param2, signed int param3, bool param4, HRESULT &hr ); + }; } } diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine_mshl.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine_mshl.cpp index df5eafe04b..0674a7d7d1 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine_mshl.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine_mshl.cpp @@ -149,3 +149,30 @@ HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_ } NANOCLR_NOCLEANUP(); } + +HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeSetConsecutivePinDirs___STATIC__VOID__I4__I4__I4__I4__BOOLEAN( CLR_RT_StackFrame& stack ) +{ + NANOCLR_HEADER(); hr = S_OK; + { + + signed int param0; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 0, param0 ) ); + + signed int param1; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 1, param1 ) ); + + signed int param2; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 2, param2 ) ); + + signed int param3; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 3, param3 ) ); + + bool param4; + NANOCLR_CHECK_HRESULT( Interop_Marshal_bool( stack, 4, param4 ) ); + + PioStateMachine::NativeSetConsecutivePinDirs( param0, param1, param2, param3, param4, hr ); + NANOCLR_CHECK_HRESULT( hr ); + + } + NANOCLR_NOCLEANUP(); +} From 1de041715f5dfb8fb2d4a68504dfc172f00e107b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Thu, 25 Jun 2026 10:32:18 -0600 Subject: [PATCH 04/58] Wire the PIO native interop into RP_PICO2_RP2350 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The PIO v0 register layout is a prefix of v1, so the same native drives both chips. Select the CMSIS header by the ChibiOS RP2040/RP2350 macro, add PIO2 (RP2350's third block) to PioFromIndex, and enable API_HARDWARE_RP2040 in the RP2350 defconfig. The firmware links with the PIO natives (24 symbols) — chip parity at the build level; same managed assembly, same native checksum. Signed-off-by: Iván Montiel Cardona --- targets/ChibiOS/PICO2_RP2350/defconfig | 1 + ..._Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.cpp | 8 ++++++++ ..._nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.cpp | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/targets/ChibiOS/PICO2_RP2350/defconfig b/targets/ChibiOS/PICO2_RP2350/defconfig index a23ec3e4b3..dd72268915 100644 --- a/targets/ChibiOS/PICO2_RP2350/defconfig +++ b/targets/ChibiOS/PICO2_RP2350/defconfig @@ -9,6 +9,7 @@ CONFIG_API_SYSTEM_IO_PORTS=y CONFIG_API_NANOFRAMEWORK_RESOURCEMANAGER=y CONFIG_API_NANOFRAMEWORK_SYSTEM_COLLECTIONS=y CONFIG_API_NANOFRAMEWORK_SYSTEM_TEXT=y +CONFIG_API_HARDWARE_RP2040=y # CONFIG_CHIBIOS_CONTRIB_REQUIRED is not set # CONFIG_CHIBIOS_SWO_OUTPUT is not set # CONFIG_NF_BUILD_RTM is not set diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.cpp index c581c6f973..025258e17d 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.cpp @@ -5,7 +5,11 @@ #include "nanoFramework_Hardware_Rp2040.h" #include "nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.h" +#if defined(RP2350) +#include "rp2350.h" +#else #include "rp2040.h" +#endif using namespace nanoFramework_Hardware_Rp2040::nanoFramework_Hardware_Rp2040; @@ -17,6 +21,10 @@ static PIO_TypeDef *PioFromIndex(int index) return PIO0; case 1: return PIO1; +#if defined(RP2350) + case 2: + return PIO2; +#endif default: return nullptr; } diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.cpp index 0c625e74bf..1f81b07ec2 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.cpp @@ -5,7 +5,11 @@ #include "nanoFramework_Hardware_Rp2040.h" #include "nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.h" +#if defined(RP2350) +#include "rp2350.h" +#else #include "rp2040.h" +#endif using namespace nanoFramework_Hardware_Rp2040::nanoFramework_Hardware_Rp2040; @@ -42,6 +46,10 @@ static PIO_TypeDef *PioFromIndex(int index) return PIO0; case 1: return PIO1; +#if defined(RP2350) + case 2: + return PIO2; +#endif default: return nullptr; } From 3c91fd654b91fdb1e90201c8dae0f7d43da32b10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Thu, 25 Jun 2026 10:32:18 -0600 Subject: [PATCH 05/58] Bring the PIO block out of reset before configuring it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On RP2040/RP2350 every peripheral powers up held in reset (clock-gated): register reads return 0 and writes are silent no-ops until its RESETS bit is deasserted. ChibiOS only un-resets the blocks it uses (UART/USB/GPIO banks), NOT the PIO. So the native's PIO register sequence — validated against the emulators, which don't model reset gating — did nothing on real silicon: the LED never toggled even though Main ran. NativeAddProgram now deasserts the PIO block's reset (and the IO/PAD banks) via RESETS->CLR.RESET + waits RESET_DONE. Reset-bit positions differ RP2040 vs RP2350 (each +1), keyed off the RP2350 macro. Confirmed end-to-end on a Pico 2: a C#-assembled PIO program blinks GPIO 25. Signed-off-by: Iván Montiel Cardona --- ...Framework_Hardware_Rp2040_Pio_PioBlock.cpp | 30 +++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.cpp index 025258e17d..0ae589eb0b 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.cpp @@ -32,6 +32,26 @@ static PIO_TypeDef *PioFromIndex(int index) static int s_nextFree[3] = {0, 0, 0}; +#if defined(RP2350) +#define PIO_RESET_LSB 11u // RP2350: PIO0=11, PIO1=12, PIO2=13 +#define IO_BANK0_RESET_BIT (1u << 6) +#define PADS_BANK0_RESET_BIT (1u << 9) +#else +#define PIO_RESET_LSB 10u // RP2040: PIO0=10, PIO1=11 +#define IO_BANK0_RESET_BIT (1u << 5) +#define PADS_BANK0_RESET_BIT (1u << 8) +#endif + +static void PioEnsureOutOfReset(int blockIndex) +{ + unsigned int bits = + (1u << (PIO_RESET_LSB + (unsigned int)blockIndex)) | IO_BANK0_RESET_BIT | PADS_BANK0_RESET_BIT; + RESETS->CLR.RESET = bits; // atomic-clear alias: deassert these resets + while ((RESETS->RESET_DONE & bits) != bits) + { + } +} + signed int PioBlock::NativeAddProgram( signed int param0, CLR_RT_TypedArray_UINT16 param1, @@ -46,6 +66,8 @@ signed int PioBlock::NativeAddProgram( return -1; } + PioEnsureOutOfReset(param0); + unsigned short *instr = param1.GetBuffer(); int length = param2; int origin = param3; @@ -114,12 +136,16 @@ void PioBlock::NativeInitGpio(signed int param0, signed int param1, HRESULT &hr) { int block = param0; int pin = param1; +#if defined(RP2350) + if (block < 0 || block > 2 || pin < 0 || pin > 47) +#else if (block < 0 || block > 1 || pin < 0 || pin > 29) +#endif { hr = CLR_E_INVALID_PARAMETER; return; } - IO_BANK0->GPIO[pin].CTRL = (block == 0) ? 6u : 7u; - PADS_BANK0->GPIO[pin] = (PADS_BANK0->GPIO[pin] & ~0x80u) | 0x40u; // clear OD, set IE + IO_BANK0->GPIO[pin].CTRL = 6u + (unsigned int)block; + PADS_BANK0->GPIO[pin] = (PADS_BANK0->GPIO[pin] & ~0x180u) | 0x40u; } From b3f64e3670f7fa0066f46d7ab9f6b52f1bee2c9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Thu, 25 Jun 2026 21:04:12 -0600 Subject: [PATCH 06/58] RP2040 PIO: FifoJoin/GpioBase, real SM/program allocation, FIFO ops, IRQ events, Pico W - NativeInit now writes SHIFTCTRL FJOIN and (RP2350) GPIOBASE from the config blob, matching the managed PioEmuRunner reference the C++ had fallen behind. - PioBlock: real per-block state-machine claim bitmask (honours `required`) and real instruction-memory alloc/free (first-fit + RemoveProgram reclaim), replacing the monotonic bump allocator and the no-op remove. - New SDK ops (ClearFifos/DrainTxFifo/Restart/ClkDivRestart/Exec) wired through the regenerated interop stubs; native checksum 0x4888E4A4 -> 0x349D04B9. - PioIrqDriver: SM `irq` flags -> NVIC -> managed NativeEventDispatcher event ("PioIrqDriver"); a pure native driver (no InternalCall, checksum unchanged). The ISR handlers live in a companion C file because the ARMv6-M SMP OSAL_IRQ_HANDLER trampoline references its body by an un-mangled symbol. Registered via FindNF_NativeAssemblies.cmake. - Enable CONFIG_API_HARDWARE_RP2040 on the Pico W target. --- CMake/Modules/FindNF_NativeAssemblies.cmake | 5 + .../FindnanoFramework.Hardware.Rp2040.cmake | 2 + .../nanoFramework_Hardware_Rp2040.cpp | 27 +++- .../nanoFramework_Hardware_Rp2040.h | 66 ++++---- ...Framework_Hardware_Rp2040_PioIrqDriver.cpp | 143 ++++++++++++++++++ ...Framework_Hardware_Rp2040_PioIrqHandlers.c | 26 ++++ ...Framework_Hardware_Rp2040_Pio_PioBlock.cpp | 92 +++++++++-- ...rk_Hardware_Rp2040_Pio_PioStateMachine.cpp | 94 +++++++++++- ...work_Hardware_Rp2040_Pio_PioStateMachine.h | 10 ++ ...rdware_Rp2040_Pio_PioStateMachine_mshl.cpp | 93 ++++++++++++ 10 files changed, 509 insertions(+), 49 deletions(-) create mode 100644 targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_PioIrqDriver.cpp create mode 100644 targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_PioIrqHandlers.c diff --git a/CMake/Modules/FindNF_NativeAssemblies.cmake b/CMake/Modules/FindNF_NativeAssemblies.cmake index 5398d4ab13..f0ed46310b 100644 --- a/CMake/Modules/FindNF_NativeAssemblies.cmake +++ b/CMake/Modules/FindNF_NativeAssemblies.cmake @@ -275,6 +275,11 @@ endif() if(API_Hardware.Rp2040) ##### API name here (doted name) PerformSettingsForApiEntry("nanoFramework.Hardware.Rp2040") + + # special: the PIO IRQ driver is an internal interrupt driver (no managed end of its own); it is + # delivered to managed code through NativeEventDispatcher("PioIrqDriver", ...). + list(APPEND CLR_RT_NativeAssemblyDataList "extern const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Rp2040_PioIrqDriver;") + list(APPEND CLR_RT_NativeAssemblyDataTableEntriesList "&g_CLR_AssemblyNative_nanoFramework_Hardware_Rp2040_PioIrqDriver,") endif() # nanoFramework.Device.Can diff --git a/CMake/Modules/FindnanoFramework.Hardware.Rp2040.cmake b/CMake/Modules/FindnanoFramework.Hardware.Rp2040.cmake index fdd5ea59ef..c7853d590f 100644 --- a/CMake/Modules/FindnanoFramework.Hardware.Rp2040.cmake +++ b/CMake/Modules/FindnanoFramework.Hardware.Rp2040.cmake @@ -20,6 +20,8 @@ set(nanoFramework.Hardware.Rp2040_SRCS nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock_mshl.cpp nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.cpp nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine_mshl.cpp + nanoFramework_Hardware_Rp2040_PioIrqDriver.cpp + nanoFramework_Hardware_Rp2040_PioIrqHandlers.c ) foreach(SRC_FILE ${nanoFramework.Hardware.Rp2040_SRCS}) diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040.cpp index 8d85e57f97..4abbc67bed 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040.cpp @@ -70,6 +70,10 @@ NULL, NULL, NULL, + NULL, + NULL, + NULL, + NULL, Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock::NativeAddProgram___STATIC__I4__I4__SZARRAY_U2__I4__I4, Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock::NativeRemoveProgram___STATIC__VOID__I4__I4__I4, Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock::NativeClaimUnusedSm___STATIC__I4__I4__BOOLEAN, @@ -127,6 +131,17 @@ NULL, NULL, NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeInit___STATIC__VOID__I4__I4__I4__SZARRAY_U4, Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeSetEnabled___STATIC__VOID__I4__I4__BOOLEAN, Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativePutBlocking___STATIC__VOID__I4__I4__U4, @@ -135,6 +150,16 @@ Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeRxEmpty___STATIC__BOOLEAN__I4__I4, Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeUnclaim___STATIC__VOID__I4__I4, Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeSetConsecutivePinDirs___STATIC__VOID__I4__I4__I4__I4__BOOLEAN, + Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeClearFifos___STATIC__VOID__I4__I4, + Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeDrainTxFifo___STATIC__VOID__I4__I4, + Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeRestart___STATIC__VOID__I4__I4, + Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeClkDivRestart___STATIC__VOID__I4__I4, + Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeExec___STATIC__VOID__I4__I4__U2, + NULL, + NULL, + NULL, + NULL, + NULL, NULL, NULL, NULL, @@ -152,7 +177,7 @@ const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Rp2040 = { "nanoFramework.Hardware.Rp2040", - 0x4888E4A4, + 0x349D04B9, method_lookup, { 1, 0, 0, 0 } }; diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040.h b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040.h index 6073495006..33c28fcf5c 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040.h +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040.h @@ -39,6 +39,16 @@ PioDest_Exec = 7, } PioDest; + typedef enum __nfpack PioFifoJoin + { + PioFifoJoin_None = 0, + PioFifoJoin_Tx = 1, + PioFifoJoin_Rx = 2, + PioFifoJoin_TxGet = 4, + PioFifoJoin_TxPut = 8, + PioFifoJoin_PutGet = 12, + } PioFifoJoin; + typedef enum __nfpack PioMovOp { PioMovOp_None = 0, @@ -93,20 +103,10 @@ //--// }; - struct Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioAssembler__Instr - { - static const int FIELD__BaseBits = 1; - static const int FIELD__Delay = 2; - static const int FIELD__SideValue = 3; - static const int FIELD__SideUsed = 4; - static const int FIELD__JmpLabel = 5; - - //--// - }; - struct Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioInstructionRef { - static const int FIELD___instr = 1; + static const int FIELD___owner = 1; + static const int FIELD___index = 2; //--// }; @@ -123,21 +123,26 @@ struct Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioAssembler { - static const int FIELD___instrs = 1; - static const int FIELD___labels = 2; - static const int FIELD___version = 3; - static const int FIELD___sideSetCount = 4; - static const int FIELD___sideSetOpt = 5; - static const int FIELD___sideSetPinDirs = 6; - static const int FIELD___wrapTarget = 7; - static const int FIELD___wrap = 8; - static const int FIELD___origin = 9; - static const int FIELD___outShiftDir = 10; - static const int FIELD___autoPull = 11; - static const int FIELD___pullThreshold = 12; - static const int FIELD___inShiftDir = 13; - static const int FIELD___autoPush = 14; - static const int FIELD___pushThreshold = 15; + static const int FIELD___baseBits = 1; + static const int FIELD___delay = 2; + static const int FIELD___sideValue = 3; + static const int FIELD___sideUsed = 4; + static const int FIELD___jmpLabel = 5; + static const int FIELD___count = 6; + static const int FIELD___labelCount = 7; + static const int FIELD___version = 8; + static const int FIELD___sideSetCount = 9; + static const int FIELD___sideSetOpt = 10; + static const int FIELD___sideSetPinDirs = 11; + static const int FIELD___wrapTarget = 12; + static const int FIELD___wrap = 13; + static const int FIELD___origin = 14; + static const int FIELD___outShiftDir = 15; + static const int FIELD___autoPull = 16; + static const int FIELD___pullThreshold = 17; + static const int FIELD___inShiftDir = 18; + static const int FIELD___autoPush = 19; + static const int FIELD___pushThreshold = 20; //--// }; @@ -202,6 +207,11 @@ NANOCLR_NATIVE_DECLARE(NativeRxEmpty___STATIC__BOOLEAN__I4__I4); NANOCLR_NATIVE_DECLARE(NativeUnclaim___STATIC__VOID__I4__I4); NANOCLR_NATIVE_DECLARE(NativeSetConsecutivePinDirs___STATIC__VOID__I4__I4__I4__I4__BOOLEAN); + NANOCLR_NATIVE_DECLARE(NativeClearFifos___STATIC__VOID__I4__I4); + NANOCLR_NATIVE_DECLARE(NativeDrainTxFifo___STATIC__VOID__I4__I4); + NANOCLR_NATIVE_DECLARE(NativeRestart___STATIC__VOID__I4__I4); + NANOCLR_NATIVE_DECLARE(NativeClkDivRestart___STATIC__VOID__I4__I4); + NANOCLR_NATIVE_DECLARE(NativeExec___STATIC__VOID__I4__I4__U2); //--// }; @@ -228,6 +238,8 @@ static const int FIELD___wrap = 18; static const int FIELD___clkDivInt = 19; static const int FIELD___clkDivFrac = 20; + static const int FIELD___fifoJoin = 21; + static const int FIELD___gpioBase = 22; //--// }; diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_PioIrqDriver.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_PioIrqDriver.cpp new file mode 100644 index 0000000000..f5eb45ffc8 --- /dev/null +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_PioIrqDriver.cpp @@ -0,0 +1,143 @@ +// +// Copyright (c) .NET nanoFramework PIO contributors +// +// +// +// + +#include "nanoFramework_Hardware_Rp2040.h" +#include +#include // nvicEnableVector / nvicDisableVector + RP_PIOx_IRQ_0_NUMBER +#if defined(RP2350) +#include "rp2350.h" +#else +#include "rp2040.h" +#endif + +static CLR_RT_HeapBlock_NativeEventDispatcher *s_pioCtx[3] = {nullptr, nullptr, nullptr}; + +static PIO_TypeDef *PioFromIndex(int index) +{ + switch (index) + { + case 0: + return PIO0; + case 1: + return PIO1; +#if defined(RP2350) + case 2: + return PIO2; +#endif + default: + return nullptr; + } +} + +static int BlockOfContext(CLR_RT_HeapBlock_NativeEventDispatcher *pContext) +{ + for (int b = 0; b < 3; b++) + { + if (s_pioCtx[b] == pContext) + { + return b; + } + } + + return -1; +} + +extern "C" void PioIrqServiceBlock(int block) +{ + PIO_TypeDef *pio = PioFromIndex(block); + if (pio == nullptr) + { + return; + } + + unsigned int flags = (pio->IRQ0_INTS >> 8) & 0x0Fu; + if (flags != 0) + { + CLR_RT_HeapBlock_NativeEventDispatcher *ctx = s_pioCtx[block]; + if (ctx != nullptr) + { + CLR_UINT32 packed = + ((CLR_UINT32)flags << 16) | ((CLR_UINT32)EVENT_CUSTOM << 8) | (CLR_UINT32)block; + SaveNativeEventToHALQueue(ctx, packed, (CLR_UINT32)flags); + } + + pio->IRQ = flags; + } +} + +// ---- NativeEventDispatcher driver procs ------------------------------------- + +static HRESULT PioIrqInitialize(CLR_RT_HeapBlock_NativeEventDispatcher *pContext, unsigned __int64 userData) +{ + int block = (int)(userData & 0xFF); + if (block < 0 || block > 2 || PioFromIndex(block) == nullptr) + { + return CLR_E_INVALID_PARAMETER; + } + + s_pioCtx[block] = pContext; + return S_OK; +} + +static HRESULT PioIrqEnableDisable(CLR_RT_HeapBlock_NativeEventDispatcher *pContext, bool fEnable) +{ + int block = BlockOfContext(pContext); + PIO_TypeDef *pio = (block >= 0) ? PioFromIndex(block) : nullptr; + if (pio == nullptr) + { + return CLR_E_INVALID_PARAMETER; + } + +#if !defined(RP2350) + int vector = (block == 0) ? RP_PIO0_IRQ_0_NUMBER : RP_PIO1_IRQ_0_NUMBER; + if (fEnable) + { + pio->IRQ0_INTE |= (0x0Fu << 8); + nvicEnableVector(vector, 3); // priority 3: kernel-safe, matches the low-priority peripherals + } + else + { + pio->IRQ0_INTE &= ~(0x0Fu << 8); + nvicDisableVector(vector); + } +#else + (void)fEnable; +#endif + + return S_OK; +} + +static HRESULT PioIrqCleanup(CLR_RT_HeapBlock_NativeEventDispatcher *pContext) +{ + int block = BlockOfContext(pContext); + if (block >= 0) + { +#if !defined(RP2350) + PIO_TypeDef *pio = PioFromIndex(block); + if (pio != nullptr) + { + pio->IRQ0_INTE &= ~(0x0Fu << 8); + nvicDisableVector(block == 0 ? RP_PIO0_IRQ_0_NUMBER : RP_PIO1_IRQ_0_NUMBER); + } +#endif + s_pioCtx[block] = nullptr; + } + + CleanupNativeEventsFromHALQueue(pContext); + return S_OK; +} + +static const CLR_RT_DriverInterruptMethods g_PioIrqDriverMethods = { + PioIrqInitialize, + PioIrqEnableDisable, + PioIrqCleanup}; + +extern const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Rp2040_PioIrqDriver = { + "PioIrqDriver", + DRIVER_INTERRUPT_METHODS_CHECKSUM, + &g_PioIrqDriverMethods, + {1, 0, 0, 0}}; diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_PioIrqHandlers.c b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_PioIrqHandlers.c new file mode 100644 index 0000000000..3d609f3a82 --- /dev/null +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_PioIrqHandlers.c @@ -0,0 +1,26 @@ +// +// Copyright (c) .NET nanoFramework PIO contributors +// +// + +#include + +#if !defined(RP2350) + +extern void PioIrqServiceBlock(int block); + +OSAL_IRQ_HANDLER(RP_PIO0_IRQ_0_HANDLER) +{ + OSAL_IRQ_PROLOGUE(); + PioIrqServiceBlock(0); + OSAL_IRQ_EPILOGUE(); +} + +OSAL_IRQ_HANDLER(RP_PIO1_IRQ_0_HANDLER) +{ + OSAL_IRQ_PROLOGUE(); + PioIrqServiceBlock(1); + OSAL_IRQ_EPILOGUE(); +} + +#endif // !RP2350 diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.cpp index 0ae589eb0b..50475b9ddd 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.cpp @@ -1,6 +1,8 @@ // // Copyright (c) .NET nanoFramework PIO contributors // +// PioBlock InternalCalls. Drives PIO registers directly (CMSIS, no pico-sdk). PIO v0 is a prefix of v1 +// so the same code serves RP2040 and RP2350 (which adds PIO2). // #include "nanoFramework_Hardware_Rp2040.h" @@ -30,8 +32,26 @@ static PIO_TypeDef *PioFromIndex(int index) } } -static int s_nextFree[3] = {0, 0, 0}; +// per-block bookkeeping (external linkage; PioStateMachine::NativeUnclaim releases a claim too) +// g_PioInstrUsed: bit per instruction slot 0..31 in use +// g_PioClaimedSm: bit per state machine 0..3 claimed +unsigned int g_PioInstrUsed[3] = {0, 0, 0}; +unsigned int g_PioClaimedSm[3] = {0, 0, 0}; +// mask of `length` slots from `offset` +static unsigned int PioSlotMask(int offset, int length) +{ + if (length <= 0) + { + return 0u; + } + + unsigned int span = (length >= 32) ? 0xFFFFFFFFu : ((1u << length) - 1u); + return span << offset; +} + +// PIO powers up held in reset and ChibiOS doesn't un-reset it (only UART/USB/GPIO), so registers read 0 +// and ignore writes until the block (and the IO/PAD banks) are taken out of reset. #if defined(RP2350) #define PIO_RESET_LSB 11u // RP2350: PIO0=11, PIO1=12, PIO2=13 #define IO_BANK0_RESET_BIT (1u << 6) @@ -46,7 +66,7 @@ static void PioEnsureOutOfReset(int blockIndex) { unsigned int bits = (1u << (PIO_RESET_LSB + (unsigned int)blockIndex)) | IO_BANK0_RESET_BIT | PADS_BANK0_RESET_BIT; - RESETS->CLR.RESET = bits; // atomic-clear alias: deassert these resets + RESETS->CLR.RESET = bits; // atomic-clear alias while ((RESETS->RESET_DONE & bits) != bits) { } @@ -66,14 +86,40 @@ signed int PioBlock::NativeAddProgram( return -1; } + // first PIO call in any flow, so un-reset here PioEnsureOutOfReset(param0); unsigned short *instr = param1.GetBuffer(); int length = param2; int origin = param3; - int offset = origin >= 0 ? origin : s_nextFree[param0]; - if (offset + length > 32) + if (length <= 0 || length > 32) + { + return -1; + } + + // fixed origin needs its exact slots free; relocatable takes the lowest free run (first-fit) + int offset = -1; + if (origin >= 0) + { + if (origin + length <= 32 && (g_PioInstrUsed[param0] & PioSlotMask(origin, length)) == 0) + { + offset = origin; + } + } + else + { + for (int candidate = 0; candidate + length <= 32; candidate++) + { + if ((g_PioInstrUsed[param0] & PioSlotMask(candidate, length)) == 0) + { + offset = candidate; + break; + } + } + } + + if (offset < 0) { return -1; // no room } @@ -82,6 +128,7 @@ signed int PioBlock::NativeAddProgram( for (int i = 0; i < length; i++) { unsigned short w = instr[i]; + // relocate JMP (opcode 0b000) targets by the load offset if (relocate && (w & 0xE000) == 0x0000) { unsigned int target = ((unsigned int)(w & 0x1F) + (unsigned int)offset) & 0x1F; @@ -90,30 +137,33 @@ signed int PioBlock::NativeAddProgram( pio->INSTR_MEM[offset + i] = w; } - if (origin < 0) - { - s_nextFree[param0] = offset + length; - } + g_PioInstrUsed[param0] |= PioSlotMask(offset, length); return offset; } void PioBlock::NativeRemoveProgram(signed int param0, signed int param1, signed int param2, HRESULT &hr) { - (void)param1; - (void)param2; - PIO_TypeDef *pio = PioFromIndex(param0); - if (pio == nullptr) + int length = param1; + int offset = param2; + if (pio == nullptr || offset < 0 || length <= 0 || offset + length > 32) { hr = CLR_E_INVALID_PARAMETER; + return; + } + + // reclaim slots, blank to JMP-to-self so a stray enable can't run stale opcodes + for (int i = 0; i < length; i++) + { + pio->INSTR_MEM[offset + i] = (unsigned short)((offset + i) & 0x1F); } + + g_PioInstrUsed[param0] &= ~PioSlotMask(offset, length); } signed int PioBlock::NativeClaimUnusedSm(signed int param0, bool param1, HRESULT &hr) { - (void)param1; - PIO_TypeDef *pio = PioFromIndex(param0); if (pio == nullptr) { @@ -121,15 +171,23 @@ signed int PioBlock::NativeClaimUnusedSm(signed int param0, bool param1, HRESULT return -1; } + // first unclaimed SM for (int sm = 0; sm < 4; sm++) { - if ((pio->CTRL & (1u << sm)) == 0) + if ((g_PioClaimedSm[param0] & (1u << sm)) == 0) { + g_PioClaimedSm[param0] |= (1u << sm); return sm; } } - return 0; + // none free: `required` hard-fails, else soft -1 + if (param1) + { + hr = CLR_E_INVALID_OPERATION; + } + + return -1; } void PioBlock::NativeInitGpio(signed int param0, signed int param1, HRESULT &hr) @@ -146,6 +204,8 @@ void PioBlock::NativeInitGpio(signed int param0, signed int param1, HRESULT &hr) return; } + // FUNCSEL = 6 (PIO0), 7 (PIO1), 8 (PIO2) IO_BANK0->GPIO[pin].CTRL = 6u + (unsigned int)block; + // clear OD (bit 7), set IE (bit 6); also clear the RP2350 pad isolation latch (bit 8, resets to 1) PADS_BANK0->GPIO[pin] = (PADS_BANK0->GPIO[pin] & ~0x180u) | 0x40u; } diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.cpp index 1f81b07ec2..266cea011b 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.cpp @@ -35,7 +35,9 @@ enum PioCfgBlob PIO_CFG_WRAP = 17, PIO_CFG_CLKDIV_INT = 18, PIO_CFG_CLKDIV_FRAC = 19, - PIO_CFG_BLOB_LENGTH = 20, + PIO_CFG_FIFO_JOIN = 20, + PIO_CFG_GPIO_BASE = 21, + PIO_CFG_BLOB_LENGTH = 22, }; static PIO_TypeDef *PioFromIndex(int index) @@ -97,10 +99,15 @@ void PioStateMachine::NativeInit( unsigned int pushThresh = b[PIO_CFG_PUSH_THRESHOLD] & 0x1F; unsigned int pullThresh = b[PIO_CFG_PULL_THRESHOLD] & 0x1F; + unsigned int join = b[PIO_CFG_FIFO_JOIN]; pio->SM[sm].SHIFTCTRL = (b[PIO_CFG_IN_SHIFT_RIGHT] << 18) | (b[PIO_CFG_OUT_SHIFT_RIGHT] << 19) | (b[PIO_CFG_AUTOPUSH] << 16) | (b[PIO_CFG_AUTOPULL] << 17) | (pushThresh << 20) | - (pullThresh << 25); + (pullThresh << 25) | ((join & 3u) << 30) | ((join >> 2) << 14); + +#if defined(RP2350) + *(volatile unsigned int *)&pio->GPIOBASE = b[PIO_CFG_GPIO_BASE]; +#endif pio->SM[sm].INSTR = (unsigned int)(param2 & 0x1F); } @@ -178,15 +185,20 @@ bool PioStateMachine::NativeRxEmpty(signed int param0, signed int param1, HRESUL return (pio->FSTAT & (1u << (8 + param1))) != 0; } +extern unsigned int g_PioClaimedSm[3]; + void PioStateMachine::NativeUnclaim(signed int param0, signed int param1, HRESULT &hr) { - (void)param1; - PIO_TypeDef *pio = PioFromIndex(param0); - if (pio == nullptr) + int sm = param1; + if (pio == nullptr || sm < 0 || sm > 3) { hr = CLR_E_INVALID_PARAMETER; + return; } + + pio->CTRL &= ~(1u << sm); + g_PioClaimedSm[param0] &= ~(1u << sm); } void PioStateMachine::NativeSetConsecutivePinDirs( @@ -223,3 +235,75 @@ void PioStateMachine::NativeSetConsecutivePinDirs( pio->SM[sm].PINCTRL = savedPinCtrl; } + +void PioStateMachine::NativeClearFifos(signed int param0, signed int param1, HRESULT &hr) +{ + PIO_TypeDef *pio = PioFromIndex(param0); + int sm = param1; + if (pio == nullptr || sm < 0 || sm > 3) + { + hr = CLR_E_INVALID_PARAMETER; + return; + } + + unsigned int fjoinRx = (1u << 31); + pio->SM[sm].SHIFTCTRL ^= fjoinRx; + pio->SM[sm].SHIFTCTRL ^= fjoinRx; +} + +void PioStateMachine::NativeDrainTxFifo(signed int param0, signed int param1, HRESULT &hr) +{ + PIO_TypeDef *pio = PioFromIndex(param0); + int sm = param1; + if (pio == nullptr || sm < 0 || sm > 3) + { + hr = CLR_E_INVALID_PARAMETER; + return; + } + + unsigned int autopull = pio->SM[sm].SHIFTCTRL & (1u << 17); + unsigned int instr = autopull ? 0x6060u : 0x8080u; + while ((pio->FSTAT & (1u << (24 + sm))) == 0) + { + pio->SM[sm].INSTR = instr; + } +} + +void PioStateMachine::NativeRestart(signed int param0, signed int param1, HRESULT &hr) +{ + PIO_TypeDef *pio = PioFromIndex(param0); + int sm = param1; + if (pio == nullptr || sm < 0 || sm > 3) + { + hr = CLR_E_INVALID_PARAMETER; + return; + } + + pio->CTRL |= (1u << (4 + sm)); +} + +void PioStateMachine::NativeClkDivRestart(signed int param0, signed int param1, HRESULT &hr) +{ + PIO_TypeDef *pio = PioFromIndex(param0); + int sm = param1; + if (pio == nullptr || sm < 0 || sm > 3) + { + hr = CLR_E_INVALID_PARAMETER; + return; + } + + pio->CTRL |= (1u << (8 + sm)); +} + +void PioStateMachine::NativeExec(signed int param0, signed int param1, unsigned short param2, HRESULT &hr) +{ + PIO_TypeDef *pio = PioFromIndex(param0); + int sm = param1; + if (pio == nullptr || sm < 0 || sm > 3) + { + hr = CLR_E_INVALID_PARAMETER; + return; + } + + pio->SM[sm].INSTR = (unsigned int)param2; +} diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.h b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.h index 2a3404d726..9217e3693d 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.h +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.h @@ -38,6 +38,16 @@ namespace nanoFramework_Hardware_Rp2040 static void NativeSetConsecutivePinDirs( signed int param0, signed int param1, signed int param2, signed int param3, bool param4, HRESULT &hr ); + static void NativeClearFifos( signed int param0, signed int param1, HRESULT &hr ); + + static void NativeDrainTxFifo( signed int param0, signed int param1, HRESULT &hr ); + + static void NativeRestart( signed int param0, signed int param1, HRESULT &hr ); + + static void NativeClkDivRestart( signed int param0, signed int param1, HRESULT &hr ); + + static void NativeExec( signed int param0, signed int param1, uint16_t param2, HRESULT &hr ); + }; } } diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine_mshl.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine_mshl.cpp index 0674a7d7d1..bf6a22dc30 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine_mshl.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine_mshl.cpp @@ -176,3 +176,96 @@ HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_ } NANOCLR_NOCLEANUP(); } + +HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeClearFifos___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) +{ + NANOCLR_HEADER(); hr = S_OK; + { + + signed int param0; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 0, param0 ) ); + + signed int param1; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 1, param1 ) ); + + PioStateMachine::NativeClearFifos( param0, param1, hr ); + NANOCLR_CHECK_HRESULT( hr ); + + } + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeDrainTxFifo___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) +{ + NANOCLR_HEADER(); hr = S_OK; + { + + signed int param0; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 0, param0 ) ); + + signed int param1; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 1, param1 ) ); + + PioStateMachine::NativeDrainTxFifo( param0, param1, hr ); + NANOCLR_CHECK_HRESULT( hr ); + + } + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeRestart___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) +{ + NANOCLR_HEADER(); hr = S_OK; + { + + signed int param0; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 0, param0 ) ); + + signed int param1; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 1, param1 ) ); + + PioStateMachine::NativeRestart( param0, param1, hr ); + NANOCLR_CHECK_HRESULT( hr ); + + } + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeClkDivRestart___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) +{ + NANOCLR_HEADER(); hr = S_OK; + { + + signed int param0; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 0, param0 ) ); + + signed int param1; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 1, param1 ) ); + + PioStateMachine::NativeClkDivRestart( param0, param1, hr ); + NANOCLR_CHECK_HRESULT( hr ); + + } + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeExec___STATIC__VOID__I4__I4__U2( CLR_RT_StackFrame& stack ) +{ + NANOCLR_HEADER(); hr = S_OK; + { + + signed int param0; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 0, param0 ) ); + + signed int param1; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 1, param1 ) ); + + uint16_t param2; + NANOCLR_CHECK_HRESULT( Interop_Marshal_UINT16( stack, 2, param2 ) ); + + PioStateMachine::NativeExec( param0, param1, param2, hr ); + NANOCLR_CHECK_HRESULT( hr ); + + } + NANOCLR_NOCLEANUP(); +} From 68b0a75a990dddd0a3dd475543163ef2c36bf819 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Thu, 25 Jun 2026 21:24:55 -0600 Subject: [PATCH 07/58] Fix PIO interop: SM-index bounds, ISR critical section, Pico W vector clash, FIFO timeout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Validate the state-machine index (0-3) in NativeSetEnabled/Put/Get/TxFull/RxEmpty, which previously only null-checked the PIO block — a managed sm>3 caused an out-of-range TXF/RXF[] write and an unbounded shift. - Wrap the PIO IRQ service routine in NATIVE_INTERRUPT_START + chSysLockFromISR like the GPIO driver, so it can't corrupt the shared HAL event queue from ISR context. - Guard PioIrqHandlers.c with !RP_PIO_REQUIRED so its IRQ0 vector handlers don't clash at link time with ChibiOS rp_pio.c (pulled in on the Pico W for the CYW43); the Pico/Pico2 still get them. - Bound the blocking Put/Get FIFO spin so a stalled state machine raises CLR_E_TIMEOUT instead of hanging the non-interruptible interpreter forever. --- ...Framework_Hardware_Rp2040_PioIrqDriver.cpp | 26 ++++++++-- ...Framework_Hardware_Rp2040_PioIrqHandlers.c | 5 +- ...rk_Hardware_Rp2040_Pio_PioStateMachine.cpp | 51 ++++++++++++++++--- 3 files changed, 70 insertions(+), 12 deletions(-) diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_PioIrqDriver.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_PioIrqDriver.cpp index f5eb45ffc8..f1fdca57f7 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_PioIrqDriver.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_PioIrqDriver.cpp @@ -1,19 +1,22 @@ // // Copyright (c) .NET nanoFramework PIO contributors // -// -// +// PIO SM irq -> managed NativeEventDispatcher event ("PioIrqDriver", one dispatcher per block). +// Pure native driver, no InternalCalls. The NVIC vector handlers live in PioIrqHandlers.c (C, for the +// un-mangled OSAL_IRQ_HANDLER symbol) and call PioIrqServiceBlock below. // #include "nanoFramework_Hardware_Rp2040.h" #include -#include // nvicEnableVector / nvicDisableVector + RP_PIOx_IRQ_0_NUMBER +#include // chSysLockFromISR +#include // nvicEnableVector + RP_PIOx_IRQ_0_NUMBER #if defined(RP2350) #include "rp2350.h" #else #include "rp2040.h" #endif +// dispatcher context per block static CLR_RT_HeapBlock_NativeEventDispatcher *s_pioCtx[3] = {nullptr, nullptr, nullptr}; static PIO_TypeDef *PioFromIndex(int index) @@ -46,6 +49,7 @@ static int BlockOfContext(CLR_RT_HeapBlock_NativeEventDispatcher *pContext) return -1; } +// Called from the block's IRQ0 ISR (PioIrqHandlers.c), hence extern "C". extern "C" void PioIrqServiceBlock(int block) { PIO_TypeDef *pio = PioFromIndex(block); @@ -54,6 +58,12 @@ extern "C" void PioIrqServiceBlock(int block) return; } + // SaveNativeEventToHALQueue touches the shared HAL queue, so take the ISR critical section like GPIO. + NATIVE_INTERRUPT_START + + chSysLockFromISR(); + + // SM irq flags -> IRQ0_INTS bits [11:8] unsigned int flags = (pio->IRQ0_INTS >> 8) & 0x0Fu; if (flags != 0) { @@ -65,8 +75,13 @@ extern "C" void PioIrqServiceBlock(int block) SaveNativeEventToHALQueue(ctx, packed, (CLR_UINT32)flags); } + // write-1-to-clear pio->IRQ = flags; } + + chSysUnlockFromISR(); + + NATIVE_INTERRUPT_END } // ---- NativeEventDispatcher driver procs ------------------------------------- @@ -93,11 +108,12 @@ static HRESULT PioIrqEnableDisable(CLR_RT_HeapBlock_NativeEventDispatcher *pCont } #if !defined(RP2350) + // SM irq flags = IRQ0_INTE bits [11:8] int vector = (block == 0) ? RP_PIO0_IRQ_0_NUMBER : RP_PIO1_IRQ_0_NUMBER; if (fEnable) { pio->IRQ0_INTE |= (0x0Fu << 8); - nvicEnableVector(vector, 3); // priority 3: kernel-safe, matches the low-priority peripherals + nvicEnableVector(vector, 3); // kernel-safe priority } else { @@ -106,6 +122,7 @@ static HRESULT PioIrqEnableDisable(CLR_RT_HeapBlock_NativeEventDispatcher *pCont } #else (void)fEnable; + // RP2350 IRQ wiring is a follow-up #endif return S_OK; @@ -136,6 +153,7 @@ static const CLR_RT_DriverInterruptMethods g_PioIrqDriverMethods = { PioIrqEnableDisable, PioIrqCleanup}; +// looked up by name from `new NativeEventDispatcher("PioIrqDriver", block)` extern const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Rp2040_PioIrqDriver = { "PioIrqDriver", DRIVER_INTERRUPT_METHODS_CHECKSUM, diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_PioIrqHandlers.c b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_PioIrqHandlers.c index 3d609f3a82..4604e7fbe6 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_PioIrqHandlers.c +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_PioIrqHandlers.c @@ -1,11 +1,14 @@ // // Copyright (c) .NET nanoFramework PIO contributors // +// PIO IRQ0 vector handlers. Compiled as C so OSAL_IRQ_HANDLER's un-mangled symbol resolves; they just +// forward to PioIrqServiceBlock() in PioIrqDriver.cpp. // #include -#if !defined(RP2350) +// RP_PIO_REQUIRED -> ChibiOS rp_pio.c owns these vectors (Pico W / CYW43); skip ours to avoid a clash. +#if !defined(RP2350) && !defined(RP_PIO_REQUIRED) extern void PioIrqServiceBlock(int block); diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.cpp index 266cea011b..0f9ec4cbd9 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.cpp @@ -1,6 +1,7 @@ // // Copyright (c) .NET nanoFramework PIO contributors // +// PioStateMachine InternalCalls. NativeInit unpacks the config blob into the SM registers. // #include "nanoFramework_Hardware_Rp2040.h" @@ -13,6 +14,10 @@ using namespace nanoFramework_Hardware_Rp2040::nanoFramework_Hardware_Rp2040; +// FIFO busy-wait cap so a stalled SM times out instead of hanging the interpreter. +static const unsigned int PIO_FIFO_WAIT_LIMIT = 0x4000000u; + +// blob indices, must match PioStateMachineConfig.cs enum PioCfgBlob { PIO_CFG_OUT_BASE = 0, @@ -74,17 +79,21 @@ void PioStateMachine::NativeInit( unsigned int *b = param3.GetBuffer(); + // disable + restart before reconfigure pio->CTRL &= ~(1u << sm); pio->CTRL |= (1u << (4 + sm)); // SM_RESTART + // CLKDIV: int [31:16], frac [15:8] pio->SM[sm].CLKDIV = (b[PIO_CFG_CLKDIV_INT] << 16) | (b[PIO_CFG_CLKDIV_FRAC] << 8); + // side-set count includes the optional enable bit unsigned int sidesetTotal = b[PIO_CFG_SIDESET_COUNT] + b[PIO_CFG_SIDESET_OPT]; pio->SM[sm].PINCTRL = (sidesetTotal << 29) | (b[PIO_CFG_SET_COUNT] << 26) | (b[PIO_CFG_OUT_COUNT] << 20) | (b[PIO_CFG_IN_BASE] << 15) | (b[PIO_CFG_SIDESET_BASE] << 10) | (b[PIO_CFG_SET_BASE] << 5) | b[PIO_CFG_OUT_BASE]; + // EXECCTRL: wrap [16:12], wrap_target [11:7], side_en [30], side_pindir [29], jmp_pin [28:24] unsigned int execCtrl = (b[PIO_CFG_WRAP] << 12) | (b[PIO_CFG_WRAP_TARGET] << 7) | (b[PIO_CFG_JMP_PIN] << 24); if (b[PIO_CFG_SIDESET_OPT]) @@ -97,8 +106,10 @@ void PioStateMachine::NativeInit( } pio->SM[sm].EXECCTRL = execCtrl; + // a 32-bit threshold encodes as 0 in the 5-bit field unsigned int pushThresh = b[PIO_CFG_PUSH_THRESHOLD] & 0x1F; unsigned int pullThresh = b[PIO_CFG_PULL_THRESHOLD] & 0x1F; + // FJOIN: low 2 bits -> TX [30] / RX [31]; high 2 bits (PIO v1) -> RX_GET [14] / RX_PUT [15] unsigned int join = b[PIO_CFG_FIFO_JOIN]; pio->SM[sm].SHIFTCTRL = (b[PIO_CFG_IN_SHIFT_RIGHT] << 18) | (b[PIO_CFG_OUT_SHIFT_RIGHT] << 19) | @@ -106,16 +117,18 @@ void PioStateMachine::NativeInit( (pullThresh << 25) | ((join & 3u) << 30) | ((join >> 2) << 14); #if defined(RP2350) + // GPIOBASE is 0 or 16; CMSIS types it __I so write through a volatile pointer *(volatile unsigned int *)&pio->GPIOBASE = b[PIO_CFG_GPIO_BASE]; #endif + // set PC via JMP (opcode 0) pio->SM[sm].INSTR = (unsigned int)(param2 & 0x1F); } void PioStateMachine::NativeSetEnabled(signed int param0, signed int param1, bool param2, HRESULT &hr) { PIO_TypeDef *pio = PioFromIndex(param0); - if (pio == nullptr) + if (pio == nullptr || param1 < 0 || param1 > 3) { hr = CLR_E_INVALID_PARAMETER; return; @@ -134,14 +147,21 @@ void PioStateMachine::NativeSetEnabled(signed int param0, signed int param1, boo void PioStateMachine::NativePutBlocking(signed int param0, signed int param1, unsigned int param2, HRESULT &hr) { PIO_TypeDef *pio = PioFromIndex(param0); - if (pio == nullptr) + if (pio == nullptr || param1 < 0 || param1 > 3) { hr = CLR_E_INVALID_PARAMETER; return; } - while (pio->FSTAT & (1u << (16 + param1))) + // FSTAT TX_FULL = bits [19:16] + unsigned int guard = PIO_FIFO_WAIT_LIMIT; + while ((pio->FSTAT & (1u << (16 + param1))) && --guard) + { + } + if (guard == 0) { + hr = CLR_E_TIMEOUT; + return; } pio->TXF[param1] = param2; } @@ -149,22 +169,29 @@ void PioStateMachine::NativePutBlocking(signed int param0, signed int param1, un unsigned int PioStateMachine::NativeGetBlocking(signed int param0, signed int param1, HRESULT &hr) { PIO_TypeDef *pio = PioFromIndex(param0); - if (pio == nullptr) + if (pio == nullptr || param1 < 0 || param1 > 3) { hr = CLR_E_INVALID_PARAMETER; return 0; } - while (pio->FSTAT & (1u << (8 + param1))) + // FSTAT RX_EMPTY = bits [11:8] + unsigned int guard = PIO_FIFO_WAIT_LIMIT; + while ((pio->FSTAT & (1u << (8 + param1))) && --guard) { } + if (guard == 0) + { + hr = CLR_E_TIMEOUT; + return 0; + } return pio->RXF[param1]; } bool PioStateMachine::NativeTxFull(signed int param0, signed int param1, HRESULT &hr) { PIO_TypeDef *pio = PioFromIndex(param0); - if (pio == nullptr) + if (pio == nullptr || param1 < 0 || param1 > 3) { hr = CLR_E_INVALID_PARAMETER; return false; @@ -176,7 +203,7 @@ bool PioStateMachine::NativeTxFull(signed int param0, signed int param1, HRESULT bool PioStateMachine::NativeRxEmpty(signed int param0, signed int param1, HRESULT &hr) { PIO_TypeDef *pio = PioFromIndex(param0); - if (pio == nullptr) + if (pio == nullptr || param1 < 0 || param1 > 3) { hr = CLR_E_INVALID_PARAMETER; return true; @@ -185,6 +212,7 @@ bool PioStateMachine::NativeRxEmpty(signed int param0, signed int param1, HRESUL return (pio->FSTAT & (1u << (8 + param1))) != 0; } +// claim bitmask owned by PioBlock.cpp extern unsigned int g_PioClaimedSm[3]; void PioStateMachine::NativeUnclaim(signed int param0, signed int param1, HRESULT &hr) @@ -197,6 +225,7 @@ void PioStateMachine::NativeUnclaim(signed int param0, signed int param1, HRESUL return; } + // stop + release the claim pio->CTRL &= ~(1u << sm); g_PioClaimedSm[param0] &= ~(1u << sm); } @@ -217,6 +246,7 @@ void PioStateMachine::NativeSetConsecutivePinDirs( return; } + // in chunks of up to 5 pins, point SET at them and exec "SET pindirs, dirs", then restore PINCTRL int pin = param2; int remaining = param3; unsigned int savedPinCtrl = pio->SM[sm].PINCTRL; @@ -226,7 +256,9 @@ void PioStateMachine::NativeSetConsecutivePinDirs( int chunk = remaining < 5 ? remaining : 5; unsigned int dirs = param4 ? ((1u << chunk) - 1u) : 0u; + // PINCTRL: SET_COUNT [28:26], SET_BASE [9:5] pio->SM[sm].PINCTRL = ((unsigned int)chunk << 26) | ((unsigned int)pin << 5); + // SET pindirs, dirs pio->SM[sm].INSTR = 0xE000u | (4u << 5) | (dirs & 0x1Fu); remaining -= chunk; @@ -246,6 +278,7 @@ void PioStateMachine::NativeClearFifos(signed int param0, signed int param1, HRE return; } + // toggle FJOIN_RX (bit 31) twice to flush both FIFOs, SHIFTCTRL unchanged unsigned int fjoinRx = (1u << 31); pio->SM[sm].SHIFTCTRL ^= fjoinRx; pio->SM[sm].SHIFTCTRL ^= fjoinRx; @@ -261,6 +294,7 @@ void PioStateMachine::NativeDrainTxFifo(signed int param0, signed int param1, HR return; } + // exec OUT NULL,32 (autopull) or PULL noblock until TX empty. FSTAT TX_EMPTY = bits [27:24] unsigned int autopull = pio->SM[sm].SHIFTCTRL & (1u << 17); unsigned int instr = autopull ? 0x6060u : 0x8080u; while ((pio->FSTAT & (1u << (24 + sm))) == 0) @@ -279,6 +313,7 @@ void PioStateMachine::NativeRestart(signed int param0, signed int param1, HRESUL return; } + // SM_RESTART = bits [7:4] pio->CTRL |= (1u << (4 + sm)); } @@ -292,6 +327,7 @@ void PioStateMachine::NativeClkDivRestart(signed int param0, signed int param1, return; } + // CLKDIV_RESTART = bits [11:8] pio->CTRL |= (1u << (8 + sm)); } @@ -305,5 +341,6 @@ void PioStateMachine::NativeExec(signed int param0, signed int param1, unsigned return; } + // exec out of band, PC unchanged pio->SM[sm].INSTR = (unsigned int)param2; } From eaf988bbd46a68244f641acf01a3400a6c750e09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Fri, 26 Jun 2026 00:05:40 -0600 Subject: [PATCH 08/58] RP2040 PIO: RP2350 IRQ, Pico W guard, cooperative FIFO wait, status/levels/PC, force-clear IRQ - PioIrqDriver: wire PIO IRQ on RP2350 too (per-chip vector + PIO0/1/2 handlers); guard the enable/cleanup with RP_PIO_REQUIRED so it stays clear of the CYW43-owned PIO HAL on Pico W. - NativeInit applies the EXECCTRL STATUS source (mov-status select/N) from the config blob. - New SM reads: FLEVEL (TX/RX levels) and the program counter (ADDR). - PioBlock: force/clear a PIO IRQ flag from the CPU (IRQ_FORCE / IRQ). - Regenerated interop stubs; native checksum 0x349D04B9 -> 0x3D709E25. The blocking Put/Get now yield in managed code instead of busy-spinning the interpreter. --- .../nanoFramework_Hardware_Rp2040.cpp | 13 ++++- .../nanoFramework_Hardware_Rp2040.h | 13 +++++ ...Framework_Hardware_Rp2040_PioIrqDriver.cpp | 28 +++++++--- ...Framework_Hardware_Rp2040_PioIrqHandlers.c | 13 ++++- ...Framework_Hardware_Rp2040_Pio_PioBlock.cpp | 24 +++++++++ ...noFramework_Hardware_Rp2040_Pio_PioBlock.h | 4 ++ ...work_Hardware_Rp2040_Pio_PioBlock_mshl.cpp | 36 +++++++++++++ ...rk_Hardware_Rp2040_Pio_PioStateMachine.cpp | 46 +++++++++++++++- ...work_Hardware_Rp2040_Pio_PioStateMachine.h | 6 +++ ...rdware_Rp2040_Pio_PioStateMachine_mshl.cpp | 54 +++++++++++++++++++ 10 files changed, 226 insertions(+), 11 deletions(-) diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040.cpp index 4abbc67bed..a9ad249f7a 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040.cpp @@ -74,10 +74,17 @@ NULL, NULL, NULL, + NULL, + NULL, Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock::NativeAddProgram___STATIC__I4__I4__SZARRAY_U2__I4__I4, Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock::NativeRemoveProgram___STATIC__VOID__I4__I4__I4, Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock::NativeClaimUnusedSm___STATIC__I4__I4__BOOLEAN, Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock::NativeInitGpio___STATIC__VOID__I4__I4, + Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock::NativeForceIrq___STATIC__VOID__I4__I4, + Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock::NativeClearIrq___STATIC__VOID__I4__I4, + NULL, + NULL, + NULL, NULL, NULL, NULL, @@ -155,6 +162,10 @@ Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeRestart___STATIC__VOID__I4__I4, Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeClkDivRestart___STATIC__VOID__I4__I4, Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeExec___STATIC__VOID__I4__I4__U2, + Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeTxLevel___STATIC__U4__I4__I4, + Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeRxLevel___STATIC__U4__I4__I4, + Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeGetPc___STATIC__U4__I4__I4, + NULL, NULL, NULL, NULL, @@ -177,7 +188,7 @@ const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Rp2040 = { "nanoFramework.Hardware.Rp2040", - 0x349D04B9, + 0x3D709E25, method_lookup, { 1, 0, 0, 0 } }; diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040.h b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040.h index 33c28fcf5c..e457f4737a 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040.h +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040.h @@ -56,6 +56,12 @@ PioMovOp_BitReverse = 2, } PioMovOp; + typedef enum __nfpack PioMovStatusSel + { + PioMovStatusSel_TxLevel = 0, + PioMovStatusSel_RxLevel = 1, + } PioMovStatusSel; + typedef enum __nfpack PioShiftDir { PioShiftDir_Left = 0, @@ -155,6 +161,8 @@ NANOCLR_NATIVE_DECLARE(NativeRemoveProgram___STATIC__VOID__I4__I4__I4); NANOCLR_NATIVE_DECLARE(NativeClaimUnusedSm___STATIC__I4__I4__BOOLEAN); NANOCLR_NATIVE_DECLARE(NativeInitGpio___STATIC__VOID__I4__I4); + NANOCLR_NATIVE_DECLARE(NativeForceIrq___STATIC__VOID__I4__I4); + NANOCLR_NATIVE_DECLARE(NativeClearIrq___STATIC__VOID__I4__I4); //--// }; @@ -212,6 +220,9 @@ NANOCLR_NATIVE_DECLARE(NativeRestart___STATIC__VOID__I4__I4); NANOCLR_NATIVE_DECLARE(NativeClkDivRestart___STATIC__VOID__I4__I4); NANOCLR_NATIVE_DECLARE(NativeExec___STATIC__VOID__I4__I4__U2); + NANOCLR_NATIVE_DECLARE(NativeTxLevel___STATIC__U4__I4__I4); + NANOCLR_NATIVE_DECLARE(NativeRxLevel___STATIC__U4__I4__I4); + NANOCLR_NATIVE_DECLARE(NativeGetPc___STATIC__U4__I4__I4); //--// }; @@ -240,6 +251,8 @@ static const int FIELD___clkDivFrac = 20; static const int FIELD___fifoJoin = 21; static const int FIELD___gpioBase = 22; + static const int FIELD___movStatusSel = 23; + static const int FIELD___movStatusN = 24; //--// }; diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_PioIrqDriver.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_PioIrqDriver.cpp index f1fdca57f7..4c6f5a598b 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_PioIrqDriver.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_PioIrqDriver.cpp @@ -49,6 +49,23 @@ static int BlockOfContext(CLR_RT_HeapBlock_NativeEventDispatcher *pContext) return -1; } +static int PioIrqVector(int block) +{ + switch (block) + { + case 0: + return RP_PIO0_IRQ_0_NUMBER; + case 1: + return RP_PIO1_IRQ_0_NUMBER; +#if defined(RP2350) + case 2: + return RP_PIO2_IRQ_0_NUMBER; +#endif + default: + return -1; + } +} + // Called from the block's IRQ0 ISR (PioIrqHandlers.c), hence extern "C". extern "C" void PioIrqServiceBlock(int block) { @@ -107,9 +124,8 @@ static HRESULT PioIrqEnableDisable(CLR_RT_HeapBlock_NativeEventDispatcher *pCont return CLR_E_INVALID_PARAMETER; } -#if !defined(RP2350) - // SM irq flags = IRQ0_INTE bits [11:8] - int vector = (block == 0) ? RP_PIO0_IRQ_0_NUMBER : RP_PIO1_IRQ_0_NUMBER; +#if !defined(RP_PIO_REQUIRED) + int vector = PioIrqVector(block); if (fEnable) { pio->IRQ0_INTE |= (0x0Fu << 8); @@ -122,7 +138,7 @@ static HRESULT PioIrqEnableDisable(CLR_RT_HeapBlock_NativeEventDispatcher *pCont } #else (void)fEnable; - // RP2350 IRQ wiring is a follow-up + (void)pio; #endif return S_OK; @@ -133,12 +149,12 @@ static HRESULT PioIrqCleanup(CLR_RT_HeapBlock_NativeEventDispatcher *pContext) int block = BlockOfContext(pContext); if (block >= 0) { -#if !defined(RP2350) +#if !defined(RP_PIO_REQUIRED) PIO_TypeDef *pio = PioFromIndex(block); if (pio != nullptr) { pio->IRQ0_INTE &= ~(0x0Fu << 8); - nvicDisableVector(block == 0 ? RP_PIO0_IRQ_0_NUMBER : RP_PIO1_IRQ_0_NUMBER); + nvicDisableVector(PioIrqVector(block)); } #endif s_pioCtx[block] = nullptr; diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_PioIrqHandlers.c b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_PioIrqHandlers.c index 4604e7fbe6..abd8c4ab55 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_PioIrqHandlers.c +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_PioIrqHandlers.c @@ -8,7 +8,7 @@ #include // RP_PIO_REQUIRED -> ChibiOS rp_pio.c owns these vectors (Pico W / CYW43); skip ours to avoid a clash. -#if !defined(RP2350) && !defined(RP_PIO_REQUIRED) +#if !defined(RP_PIO_REQUIRED) extern void PioIrqServiceBlock(int block); @@ -26,4 +26,13 @@ OSAL_IRQ_HANDLER(RP_PIO1_IRQ_0_HANDLER) OSAL_IRQ_EPILOGUE(); } -#endif // !RP2350 +#if defined(RP2350) +OSAL_IRQ_HANDLER(RP_PIO2_IRQ_0_HANDLER) +{ + OSAL_IRQ_PROLOGUE(); + PioIrqServiceBlock(2); + OSAL_IRQ_EPILOGUE(); +} +#endif + +#endif // !RP_PIO_REQUIRED diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.cpp index 50475b9ddd..02666699da 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.cpp @@ -209,3 +209,27 @@ void PioBlock::NativeInitGpio(signed int param0, signed int param1, HRESULT &hr) // clear OD (bit 7), set IE (bit 6); also clear the RP2350 pad isolation latch (bit 8, resets to 1) PADS_BANK0->GPIO[pin] = (PADS_BANK0->GPIO[pin] & ~0x180u) | 0x40u; } + +void PioBlock::NativeForceIrq(signed int param0, signed int param1, HRESULT &hr) +{ + PIO_TypeDef *pio = PioFromIndex(param0); + if (pio == nullptr || param1 < 0 || param1 > 7) + { + hr = CLR_E_INVALID_PARAMETER; + return; + } + + pio->IRQ_FORCE = (1u << param1); +} + +void PioBlock::NativeClearIrq(signed int param0, signed int param1, HRESULT &hr) +{ + PIO_TypeDef *pio = PioFromIndex(param0); + if (pio == nullptr || param1 < 0 || param1 > 7) + { + hr = CLR_E_INVALID_PARAMETER; + return; + } + + pio->IRQ = (1u << param1); +} diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.h b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.h index f8f99a43c0..a22be1e88a 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.h +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.h @@ -30,6 +30,10 @@ namespace nanoFramework_Hardware_Rp2040 static void NativeInitGpio( signed int param0, signed int param1, HRESULT &hr ); + static void NativeForceIrq( signed int param0, signed int param1, HRESULT &hr ); + + static void NativeClearIrq( signed int param0, signed int param1, HRESULT &hr ); + }; } } diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock_mshl.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock_mshl.cpp index b9fd5f27e9..664e294450 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock_mshl.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock_mshl.cpp @@ -92,3 +92,39 @@ HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_ } NANOCLR_NOCLEANUP(); } + +HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock::NativeForceIrq___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) +{ + NANOCLR_HEADER(); hr = S_OK; + { + + signed int param0; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 0, param0 ) ); + + signed int param1; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 1, param1 ) ); + + PioBlock::NativeForceIrq( param0, param1, hr ); + NANOCLR_CHECK_HRESULT( hr ); + + } + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock::NativeClearIrq___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) +{ + NANOCLR_HEADER(); hr = S_OK; + { + + signed int param0; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 0, param0 ) ); + + signed int param1; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 1, param1 ) ); + + PioBlock::NativeClearIrq( param0, param1, hr ); + NANOCLR_CHECK_HRESULT( hr ); + + } + NANOCLR_NOCLEANUP(); +} diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.cpp index 0f9ec4cbd9..8d9b04f983 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.cpp @@ -42,7 +42,9 @@ enum PioCfgBlob PIO_CFG_CLKDIV_FRAC = 19, PIO_CFG_FIFO_JOIN = 20, PIO_CFG_GPIO_BASE = 21, - PIO_CFG_BLOB_LENGTH = 22, + PIO_CFG_MOV_STATUS_SEL = 22, + PIO_CFG_MOV_STATUS_N = 23, + PIO_CFG_BLOB_LENGTH = 24, }; static PIO_TypeDef *PioFromIndex(int index) @@ -95,7 +97,8 @@ void PioStateMachine::NativeInit( // EXECCTRL: wrap [16:12], wrap_target [11:7], side_en [30], side_pindir [29], jmp_pin [28:24] unsigned int execCtrl = - (b[PIO_CFG_WRAP] << 12) | (b[PIO_CFG_WRAP_TARGET] << 7) | (b[PIO_CFG_JMP_PIN] << 24); + (b[PIO_CFG_WRAP] << 12) | (b[PIO_CFG_WRAP_TARGET] << 7) | (b[PIO_CFG_JMP_PIN] << 24) | + ((b[PIO_CFG_MOV_STATUS_SEL] & 1u) << 4) | (b[PIO_CFG_MOV_STATUS_N] & 0xFu); if (b[PIO_CFG_SIDESET_OPT]) { execCtrl |= (1u << 30); @@ -344,3 +347,42 @@ void PioStateMachine::NativeExec(signed int param0, signed int param1, unsigned // exec out of band, PC unchanged pio->SM[sm].INSTR = (unsigned int)param2; } + +unsigned int PioStateMachine::NativeTxLevel(signed int param0, signed int param1, HRESULT &hr) +{ + PIO_TypeDef *pio = PioFromIndex(param0); + int sm = param1; + if (pio == nullptr || sm < 0 || sm > 3) + { + hr = CLR_E_INVALID_PARAMETER; + return 0; + } + + return (pio->FLEVEL >> (8 * sm)) & 0xFu; +} + +unsigned int PioStateMachine::NativeRxLevel(signed int param0, signed int param1, HRESULT &hr) +{ + PIO_TypeDef *pio = PioFromIndex(param0); + int sm = param1; + if (pio == nullptr || sm < 0 || sm > 3) + { + hr = CLR_E_INVALID_PARAMETER; + return 0; + } + + return (pio->FLEVEL >> (8 * sm + 4)) & 0xFu; +} + +unsigned int PioStateMachine::NativeGetPc(signed int param0, signed int param1, HRESULT &hr) +{ + PIO_TypeDef *pio = PioFromIndex(param0); + int sm = param1; + if (pio == nullptr || sm < 0 || sm > 3) + { + hr = CLR_E_INVALID_PARAMETER; + return 0; + } + + return pio->SM[sm].ADDR & 0x1Fu; +} diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.h b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.h index 9217e3693d..1f35d7762a 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.h +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.h @@ -48,6 +48,12 @@ namespace nanoFramework_Hardware_Rp2040 static void NativeExec( signed int param0, signed int param1, uint16_t param2, HRESULT &hr ); + static unsigned int NativeTxLevel( signed int param0, signed int param1, HRESULT &hr ); + + static unsigned int NativeRxLevel( signed int param0, signed int param1, HRESULT &hr ); + + static unsigned int NativeGetPc( signed int param0, signed int param1, HRESULT &hr ); + }; } } diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine_mshl.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine_mshl.cpp index bf6a22dc30..6cab897d2b 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine_mshl.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine_mshl.cpp @@ -269,3 +269,57 @@ HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_ } NANOCLR_NOCLEANUP(); } + +HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeTxLevel___STATIC__U4__I4__I4( CLR_RT_StackFrame& stack ) +{ + NANOCLR_HEADER(); hr = S_OK; + { + + signed int param0; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 0, param0 ) ); + + signed int param1; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 1, param1 ) ); + + unsigned int retValue = PioStateMachine::NativeTxLevel( param0, param1, hr ); + NANOCLR_CHECK_HRESULT( hr ); + SetResult_UINT32( stack, retValue ); + } + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeRxLevel___STATIC__U4__I4__I4( CLR_RT_StackFrame& stack ) +{ + NANOCLR_HEADER(); hr = S_OK; + { + + signed int param0; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 0, param0 ) ); + + signed int param1; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 1, param1 ) ); + + unsigned int retValue = PioStateMachine::NativeRxLevel( param0, param1, hr ); + NANOCLR_CHECK_HRESULT( hr ); + SetResult_UINT32( stack, retValue ); + } + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeGetPc___STATIC__U4__I4__I4( CLR_RT_StackFrame& stack ) +{ + NANOCLR_HEADER(); hr = S_OK; + { + + signed int param0; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 0, param0 ) ); + + signed int param1; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 1, param1 ) ); + + unsigned int retValue = PioStateMachine::NativeGetPc( param0, param1, hr ); + NANOCLR_CHECK_HRESULT( hr ); + SetResult_UINT32( stack, retValue ); + } + NANOCLR_NOCLEANUP(); +} From 976167ba287b0b5f749678e9f5de02fb1e2910c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Fri, 26 Jun 2026 00:30:54 -0600 Subject: [PATCH 09/58] Rename interop assembly nanoFramework.Hardware.Rp2040 -> nanoFramework.Hardware.Rpi Renames the assembly, namespaces, native symbols, CMake find module, Kconfig (API_HARDWARE_RPI) and the three Pico defconfigs. Also lands the OUT special config (OUT_STICKY / INLINE_OUT_EN / OUT_EN_SEL) and a runtime SetClockDivisor; native checksum 0x388EAED7 -> 0xFE5AB47E. Builds green on RP2040 and RP2350. --- CMake/Modules/FindNF_NativeAssemblies.cmake | 10 +- .../FindnanoFramework.Hardware.Rp2040.cmake | 49 ----- .../FindnanoFramework.Hardware.Rpi.cmake | 49 +++++ CMake/Modules/NF_Kconfig.cmake | 2 +- Kconfig.apis | 2 +- targets/ChibiOS/PICO2_RP2350/defconfig | 2 +- targets/ChibiOS/PICO2_RP2350_W/defconfig | 1 + .../nanoFramework_Hardware_Rp2040.cpp | 197 ----------------- .../nanoFramework_Hardware_Rpi.cpp | 200 ++++++++++++++++++ .../nanoFramework_Hardware_Rpi.h} | 30 +-- ...noFramework_Hardware_Rpi_PioIrqDriver.cpp} | 4 +- ...noFramework_Hardware_Rpi_PioIrqHandlers.c} | 0 ...noFramework_Hardware_Rpi_Pio_PioBlock.cpp} | 6 +- ...nanoFramework_Hardware_Rpi_Pio_PioBlock.h} | 10 +- ...mework_Hardware_Rpi_Pio_PioBlock_mshl.cpp} | 18 +- ...work_Hardware_Rpi_Pio_PioStateMachine.cpp} | 34 ++- ...mework_Hardware_Rpi_Pio_PioStateMachine.h} | 12 +- ...Hardware_Rpi_Pio_PioStateMachine_mshl.cpp} | 62 ++++-- 18 files changed, 373 insertions(+), 315 deletions(-) delete mode 100644 CMake/Modules/FindnanoFramework.Hardware.Rp2040.cmake create mode 100644 CMake/Modules/FindnanoFramework.Hardware.Rpi.cmake delete mode 100644 targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040.cpp create mode 100644 targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi.cpp rename targets/ChibiOS/_nanoCLR/{nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040.h => nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi.h} (87%) rename targets/ChibiOS/_nanoCLR/{nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_PioIrqDriver.cpp => nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_PioIrqDriver.cpp} (98%) rename targets/ChibiOS/_nanoCLR/{nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_PioIrqHandlers.c => nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_PioIrqHandlers.c} (100%) rename targets/ChibiOS/_nanoCLR/{nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.cpp => nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock.cpp} (96%) rename targets/ChibiOS/_nanoCLR/{nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.h => nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock.h} (76%) rename targets/ChibiOS/_nanoCLR/{nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock_mshl.cpp => nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock_mshl.cpp} (72%) rename targets/ChibiOS/_nanoCLR/{nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.cpp => nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.cpp} (91%) rename targets/ChibiOS/_nanoCLR/{nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.h => nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.h} (81%) rename targets/ChibiOS/_nanoCLR/{nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine_mshl.cpp => nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine_mshl.cpp} (69%) diff --git a/CMake/Modules/FindNF_NativeAssemblies.cmake b/CMake/Modules/FindNF_NativeAssemblies.cmake index f0ed46310b..16739f56ba 100644 --- a/CMake/Modules/FindNF_NativeAssemblies.cmake +++ b/CMake/Modules/FindNF_NativeAssemblies.cmake @@ -42,7 +42,7 @@ option(API_nanoFramework.Networking.Thread "option for nanoFramewor # Stm32 only option(API_Hardware.Stm32 "option for Hardware.Stm32") -option(API_Hardware.Rp2040 "option for Hardware.Rp2040") +option(API_Hardware.Rpi "option for Hardware.Rp2040") # TI CC13xxCC26xx option(API_nanoFramework.TI.EasyLink "option for nanoFramework.TI.EasyLink API") @@ -272,14 +272,14 @@ if(API_Hardware.Stm32) endif() # Hardware.Rp2040 -if(API_Hardware.Rp2040) +if(API_Hardware.Rpi) ##### API name here (doted name) - PerformSettingsForApiEntry("nanoFramework.Hardware.Rp2040") + PerformSettingsForApiEntry("nanoFramework.Hardware.Rpi") # special: the PIO IRQ driver is an internal interrupt driver (no managed end of its own); it is # delivered to managed code through NativeEventDispatcher("PioIrqDriver", ...). - list(APPEND CLR_RT_NativeAssemblyDataList "extern const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Rp2040_PioIrqDriver;") - list(APPEND CLR_RT_NativeAssemblyDataTableEntriesList "&g_CLR_AssemblyNative_nanoFramework_Hardware_Rp2040_PioIrqDriver,") + list(APPEND CLR_RT_NativeAssemblyDataList "extern const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Rpi_PioIrqDriver;") + list(APPEND CLR_RT_NativeAssemblyDataTableEntriesList "&g_CLR_AssemblyNative_nanoFramework_Hardware_Rpi_PioIrqDriver,") endif() # nanoFramework.Device.Can diff --git a/CMake/Modules/FindnanoFramework.Hardware.Rp2040.cmake b/CMake/Modules/FindnanoFramework.Hardware.Rp2040.cmake deleted file mode 100644 index c7853d590f..0000000000 --- a/CMake/Modules/FindnanoFramework.Hardware.Rp2040.cmake +++ /dev/null @@ -1,49 +0,0 @@ -# -# Copyright (c) .NET Foundation and Contributors -# See LICENSE file in the project root for full license information. -# - - -# native code directory -set(BASE_PATH_FOR_THIS_MODULE "${BASE_PATH_FOR_CLASS_LIBRARIES_MODULES}/nanoFramework.Hardware.Rp2040") - - -# set include directories -list(APPEND nanoFramework.Hardware.Rp2040_INCLUDE_DIRS "${BASE_PATH_FOR_THIS_MODULE}") - - -# source files -set(nanoFramework.Hardware.Rp2040_SRCS - - nanoFramework_Hardware_Rp2040.cpp - nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.cpp - nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock_mshl.cpp - nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.cpp - nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine_mshl.cpp - nanoFramework_Hardware_Rp2040_PioIrqDriver.cpp - nanoFramework_Hardware_Rp2040_PioIrqHandlers.c -) - -foreach(SRC_FILE ${nanoFramework.Hardware.Rp2040_SRCS}) - - set(nanoFramework.Hardware.Rp2040_SRC_FILE SRC_FILE-NOTFOUND) - - find_file(nanoFramework.Hardware.Rp2040_SRC_FILE ${SRC_FILE} - PATHS - ${BASE_PATH_FOR_THIS_MODULE} - - CMAKE_FIND_ROOT_PATH_BOTH - ) - - if (BUILD_VERBOSE) - message("${SRC_FILE} >> ${nanoFramework.Hardware.Rp2040_SRC_FILE}") - endif() - - list(APPEND nanoFramework.Hardware.Rp2040_SOURCES ${nanoFramework.Hardware.Rp2040_SRC_FILE}) - -endforeach() - - -include(FindPackageHandleStandardArgs) - -FIND_PACKAGE_HANDLE_STANDARD_ARGS(nanoFramework.Hardware.Rp2040 DEFAULT_MSG nanoFramework.Hardware.Rp2040_INCLUDE_DIRS nanoFramework.Hardware.Rp2040_SOURCES) diff --git a/CMake/Modules/FindnanoFramework.Hardware.Rpi.cmake b/CMake/Modules/FindnanoFramework.Hardware.Rpi.cmake new file mode 100644 index 0000000000..c737887081 --- /dev/null +++ b/CMake/Modules/FindnanoFramework.Hardware.Rpi.cmake @@ -0,0 +1,49 @@ +# +# Copyright (c) .NET Foundation and Contributors +# See LICENSE file in the project root for full license information. +# + + +# native code directory +set(BASE_PATH_FOR_THIS_MODULE "${BASE_PATH_FOR_CLASS_LIBRARIES_MODULES}/nanoFramework.Hardware.Rpi") + + +# set include directories +list(APPEND nanoFramework.Hardware.Rpi_INCLUDE_DIRS "${BASE_PATH_FOR_THIS_MODULE}") + + +# source files +set(nanoFramework.Hardware.Rpi_SRCS + + nanoFramework_Hardware_Rpi.cpp + nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock.cpp + nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock_mshl.cpp + nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.cpp + nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine_mshl.cpp + nanoFramework_Hardware_Rpi_PioIrqDriver.cpp + nanoFramework_Hardware_Rpi_PioIrqHandlers.c +) + +foreach(SRC_FILE ${nanoFramework.Hardware.Rpi_SRCS}) + + set(nanoFramework.Hardware.Rpi_SRC_FILE SRC_FILE-NOTFOUND) + + find_file(nanoFramework.Hardware.Rpi_SRC_FILE ${SRC_FILE} + PATHS + ${BASE_PATH_FOR_THIS_MODULE} + + CMAKE_FIND_ROOT_PATH_BOTH + ) + + if (BUILD_VERBOSE) + message("${SRC_FILE} >> ${nanoFramework.Hardware.Rpi_SRC_FILE}") + endif() + + list(APPEND nanoFramework.Hardware.Rpi_SOURCES ${nanoFramework.Hardware.Rpi_SRC_FILE}) + +endforeach() + + +include(FindPackageHandleStandardArgs) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS(nanoFramework.Hardware.Rpi DEFAULT_MSG nanoFramework.Hardware.Rpi_INCLUDE_DIRS nanoFramework.Hardware.Rpi_SOURCES) diff --git a/CMake/Modules/NF_Kconfig.cmake b/CMake/Modules/NF_Kconfig.cmake index 3b1dc6d431..ac55176013 100644 --- a/CMake/Modules/NF_Kconfig.cmake +++ b/CMake/Modules/NF_Kconfig.cmake @@ -43,7 +43,7 @@ set(_NF_KCONFIG_API_MAP # Platform-specific APIs "API_HARDWARE_STM32|API_Hardware.Stm32" - "API_HARDWARE_RP2040|API_Hardware.Rp2040" + "API_HARDWARE_RPI|API_Hardware.Rpi" "API_HARDWARE_ESP32|API_Hardware.Esp32" "API_NANOFRAMEWORK_HARDWARE_ESP32_RMT|API_nanoFramework.Hardware.Esp32.Rmt" "API_NANOFRAMEWORK_HARDWARE_TI|API_nanoFramework.Hardware.TI" diff --git a/Kconfig.apis b/Kconfig.apis index 36bd224bda..a9cdb673dd 100644 --- a/Kconfig.apis +++ b/Kconfig.apis @@ -113,7 +113,7 @@ config API_HARDWARE_STM32 depends on RTOS_CHIBIOS default n -config API_HARDWARE_RP2040 +config API_HARDWARE_RPI bool "Hardware.Rp2040" depends on RTOS_CHIBIOS default n diff --git a/targets/ChibiOS/PICO2_RP2350/defconfig b/targets/ChibiOS/PICO2_RP2350/defconfig index dd72268915..202dd7ba46 100644 --- a/targets/ChibiOS/PICO2_RP2350/defconfig +++ b/targets/ChibiOS/PICO2_RP2350/defconfig @@ -9,7 +9,7 @@ CONFIG_API_SYSTEM_IO_PORTS=y CONFIG_API_NANOFRAMEWORK_RESOURCEMANAGER=y CONFIG_API_NANOFRAMEWORK_SYSTEM_COLLECTIONS=y CONFIG_API_NANOFRAMEWORK_SYSTEM_TEXT=y -CONFIG_API_HARDWARE_RP2040=y +CONFIG_API_HARDWARE_RPI=y # CONFIG_CHIBIOS_CONTRIB_REQUIRED is not set # CONFIG_CHIBIOS_SWO_OUTPUT is not set # CONFIG_NF_BUILD_RTM is not set diff --git a/targets/ChibiOS/PICO2_RP2350_W/defconfig b/targets/ChibiOS/PICO2_RP2350_W/defconfig index 33c68cebd1..e97ae44f23 100644 --- a/targets/ChibiOS/PICO2_RP2350_W/defconfig +++ b/targets/ChibiOS/PICO2_RP2350_W/defconfig @@ -9,6 +9,7 @@ CONFIG_API_SYSTEM_DEVICE_WIFI=y CONFIG_API_SYSTEM_IO_FILESYSTEM=y CONFIG_API_SYSTEM_IO_PORTS=y CONFIG_API_SYSTEM_NET=y +CONFIG_API_HARDWARE_RPI=y CONFIG_API_NANOFRAMEWORK_RESOURCEMANAGER=y CONFIG_API_NANOFRAMEWORK_SYSTEM_COLLECTIONS=y CONFIG_API_NANOFRAMEWORK_SYSTEM_TEXT=y diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040.cpp deleted file mode 100644 index a9ad249f7a..0000000000 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040.cpp +++ /dev/null @@ -1,197 +0,0 @@ - //----------------------------------------------------------------------------- - // - // ** DO NOT EDIT THIS FILE! ** - // This file was generated by a tool - // re-running the tool will overwrite this file. - // - //----------------------------------------------------------------------------- - - #include "nanoFramework_Hardware_Rp2040.h" - - // clang-format off - - static const CLR_RT_MethodHandler method_lookup[] = - { - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock::NativeAddProgram___STATIC__I4__I4__SZARRAY_U2__I4__I4, - Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock::NativeRemoveProgram___STATIC__VOID__I4__I4__I4, - Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock::NativeClaimUnusedSm___STATIC__I4__I4__BOOLEAN, - Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock::NativeInitGpio___STATIC__VOID__I4__I4, - Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock::NativeForceIrq___STATIC__VOID__I4__I4, - Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock::NativeClearIrq___STATIC__VOID__I4__I4, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeInit___STATIC__VOID__I4__I4__I4__SZARRAY_U4, - Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeSetEnabled___STATIC__VOID__I4__I4__BOOLEAN, - Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativePutBlocking___STATIC__VOID__I4__I4__U4, - Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeGetBlocking___STATIC__U4__I4__I4, - Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeTxFull___STATIC__BOOLEAN__I4__I4, - Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeRxEmpty___STATIC__BOOLEAN__I4__I4, - Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeUnclaim___STATIC__VOID__I4__I4, - Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeSetConsecutivePinDirs___STATIC__VOID__I4__I4__I4__I4__BOOLEAN, - Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeClearFifos___STATIC__VOID__I4__I4, - Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeDrainTxFifo___STATIC__VOID__I4__I4, - Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeRestart___STATIC__VOID__I4__I4, - Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeClkDivRestart___STATIC__VOID__I4__I4, - Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeExec___STATIC__VOID__I4__I4__U2, - Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeTxLevel___STATIC__U4__I4__I4, - Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeRxLevel___STATIC__U4__I4__I4, - Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeGetPc___STATIC__U4__I4__I4, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - }; - - const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Rp2040 = - { - "nanoFramework.Hardware.Rp2040", - 0x3D709E25, - method_lookup, - { 1, 0, 0, 0 } - }; - - // clang-format on - \ No newline at end of file diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi.cpp new file mode 100644 index 0000000000..d1cd9cdc30 --- /dev/null +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi.cpp @@ -0,0 +1,200 @@ + //----------------------------------------------------------------------------- + // + // ** DO NOT EDIT THIS FILE! ** + // This file was generated by a tool + // re-running the tool will overwrite this file. + // + //----------------------------------------------------------------------------- + + #include "nanoFramework_Hardware_Rpi.h" + + // clang-format off + + static const CLR_RT_MethodHandler method_lookup[] = + { + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeAddProgram___STATIC__I4__I4__SZARRAY_U2__I4__I4, + Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeRemoveProgram___STATIC__VOID__I4__I4__I4, + Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeClaimUnusedSm___STATIC__I4__I4__BOOLEAN, + Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeInitGpio___STATIC__VOID__I4__I4, + Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeForceIrq___STATIC__VOID__I4__I4, + Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeClearIrq___STATIC__VOID__I4__I4, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeInit___STATIC__VOID__I4__I4__I4__SZARRAY_U4, + Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeSetEnabled___STATIC__VOID__I4__I4__BOOLEAN, + Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativePutBlocking___STATIC__VOID__I4__I4__U4, + Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeGetBlocking___STATIC__U4__I4__I4, + Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeTxFull___STATIC__BOOLEAN__I4__I4, + Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeRxEmpty___STATIC__BOOLEAN__I4__I4, + Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeUnclaim___STATIC__VOID__I4__I4, + Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeSetConsecutivePinDirs___STATIC__VOID__I4__I4__I4__I4__BOOLEAN, + Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeClearFifos___STATIC__VOID__I4__I4, + Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeDrainTxFifo___STATIC__VOID__I4__I4, + Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeRestart___STATIC__VOID__I4__I4, + Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeClkDivRestart___STATIC__VOID__I4__I4, + Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeExec___STATIC__VOID__I4__I4__U2, + Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeTxLevel___STATIC__U4__I4__I4, + Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeRxLevel___STATIC__U4__I4__I4, + Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeGetPc___STATIC__U4__I4__I4, + Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeSetClockDivisor___STATIC__VOID__I4__I4__I4__I4, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + }; + + const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Rpi = + { + "nanoFramework.Hardware.Rpi", + 0xFE5AB47E, + method_lookup, + { 1, 0, 0, 0 } + }; + + // clang-format on + \ No newline at end of file diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040.h b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi.h similarity index 87% rename from targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040.h rename to targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi.h index e457f4737a..44563d28ba 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040.h +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi.h @@ -6,8 +6,8 @@ // //----------------------------------------------------------------------------- - #ifndef NANOFRAMEWORK_HARDWARE_RP2040_H - #define NANOFRAMEWORK_HARDWARE_RP2040_H + #ifndef NANOFRAMEWORK_HARDWARE_RPI_H + #define NANOFRAMEWORK_HARDWARE_RPI_H #include #include @@ -92,14 +92,14 @@ PioWaitSource_Irq = 2, } PioWaitSource; - struct Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_Pio + struct Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_Pio { static const int FIELD_STATIC___blocks = 0; //--// }; - struct Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioAssemblerOptions + struct Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioAssemblerOptions { static const int FIELD__Version = 1; static const int FIELD__SideSetCount = 2; @@ -109,7 +109,7 @@ //--// }; - struct Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioInstructionRef + struct Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioInstructionRef { static const int FIELD___owner = 1; static const int FIELD___index = 2; @@ -117,7 +117,7 @@ //--// }; - struct Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioLabel + struct Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioLabel { // renamed backing field 'k__BackingField' static const int FIELD__Id = 1; @@ -127,7 +127,7 @@ //--// }; - struct Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioAssembler + struct Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioAssembler { static const int FIELD___baseBits = 1; static const int FIELD___delay = 2; @@ -153,7 +153,7 @@ //--// }; - struct Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock + struct Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock { static const int FIELD___index = 1; @@ -167,7 +167,7 @@ //--// }; - struct Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioProgram + struct Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioProgram { // renamed backing field 'k__BackingField' static const int FIELD__Instructions = 1; @@ -201,7 +201,7 @@ //--// }; - struct Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine + struct Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine { static const int FIELD___block = 1; static const int FIELD___sm = 2; @@ -223,11 +223,12 @@ NANOCLR_NATIVE_DECLARE(NativeTxLevel___STATIC__U4__I4__I4); NANOCLR_NATIVE_DECLARE(NativeRxLevel___STATIC__U4__I4__I4); NANOCLR_NATIVE_DECLARE(NativeGetPc___STATIC__U4__I4__I4); + NANOCLR_NATIVE_DECLARE(NativeSetClockDivisor___STATIC__VOID__I4__I4__I4__I4); //--// }; - struct Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachineConfig + struct Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachineConfig { static const int FIELD___outBase = 1; static const int FIELD___outCount = 2; @@ -253,11 +254,14 @@ static const int FIELD___gpioBase = 22; static const int FIELD___movStatusSel = 23; static const int FIELD___movStatusN = 24; + static const int FIELD___outSticky = 25; + static const int FIELD___inlineOutEn = 26; + static const int FIELD___outEnSel = 27; //--// }; - extern const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Rp2040; + extern const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Rpi; - #endif // NANOFRAMEWORK_HARDWARE_RP2040_H + #endif // NANOFRAMEWORK_HARDWARE_RPI_H \ No newline at end of file diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_PioIrqDriver.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_PioIrqDriver.cpp similarity index 98% rename from targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_PioIrqDriver.cpp rename to targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_PioIrqDriver.cpp index 4c6f5a598b..9cddbfe42c 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_PioIrqDriver.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_PioIrqDriver.cpp @@ -6,7 +6,7 @@ // un-mangled OSAL_IRQ_HANDLER symbol) and call PioIrqServiceBlock below. // -#include "nanoFramework_Hardware_Rp2040.h" +#include "nanoFramework_Hardware_Rpi.h" #include #include // chSysLockFromISR #include // nvicEnableVector + RP_PIOx_IRQ_0_NUMBER @@ -170,7 +170,7 @@ static const CLR_RT_DriverInterruptMethods g_PioIrqDriverMethods = { PioIrqCleanup}; // looked up by name from `new NativeEventDispatcher("PioIrqDriver", block)` -extern const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Rp2040_PioIrqDriver = { +extern const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Rpi_PioIrqDriver = { "PioIrqDriver", DRIVER_INTERRUPT_METHODS_CHECKSUM, &g_PioIrqDriverMethods, diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_PioIrqHandlers.c b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_PioIrqHandlers.c similarity index 100% rename from targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_PioIrqHandlers.c rename to targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_PioIrqHandlers.c diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock.cpp similarity index 96% rename from targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.cpp rename to targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock.cpp index 02666699da..0b8900d294 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock.cpp @@ -5,15 +5,15 @@ // so the same code serves RP2040 and RP2350 (which adds PIO2). // -#include "nanoFramework_Hardware_Rp2040.h" -#include "nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.h" +#include "nanoFramework_Hardware_Rpi.h" +#include "nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock.h" #if defined(RP2350) #include "rp2350.h" #else #include "rp2040.h" #endif -using namespace nanoFramework_Hardware_Rp2040::nanoFramework_Hardware_Rp2040; +using namespace nanoFramework_Hardware_Rpi::nanoFramework_Hardware_Rpi; static PIO_TypeDef *PioFromIndex(int index) { diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.h b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock.h similarity index 76% rename from targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.h rename to targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock.h index a22be1e88a..76ef4220dc 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.h +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock.h @@ -10,12 +10,12 @@ // //----------------------------------------------------------------------------- -#ifndef NANOFRAMEWORK_HARDWARE_RP2040_NANOFRAMEWORK_HARDWARE_RP2040_NANOFRAMEWORK_HARDWARE_RP2040_PIO_PIOBLOCK_H -#define NANOFRAMEWORK_HARDWARE_RP2040_NANOFRAMEWORK_HARDWARE_RP2040_NANOFRAMEWORK_HARDWARE_RP2040_PIO_PIOBLOCK_H +#ifndef NANOFRAMEWORK_HARDWARE_RPI_NANOFRAMEWORK_HARDWARE_RPI_NANOFRAMEWORK_HARDWARE_RPI_PIO_PIOBLOCK_H +#define NANOFRAMEWORK_HARDWARE_RPI_NANOFRAMEWORK_HARDWARE_RPI_NANOFRAMEWORK_HARDWARE_RPI_PIO_PIOBLOCK_H -namespace nanoFramework_Hardware_Rp2040 +namespace nanoFramework_Hardware_Rpi { - namespace nanoFramework_Hardware_Rp2040 + namespace nanoFramework_Hardware_Rpi { struct PioBlock { @@ -38,4 +38,4 @@ namespace nanoFramework_Hardware_Rp2040 } } -#endif // NANOFRAMEWORK_HARDWARE_RP2040_NANOFRAMEWORK_HARDWARE_RP2040_NANOFRAMEWORK_HARDWARE_RP2040_PIO_PIOBLOCK_H +#endif // NANOFRAMEWORK_HARDWARE_RPI_NANOFRAMEWORK_HARDWARE_RPI_NANOFRAMEWORK_HARDWARE_RPI_PIO_PIOBLOCK_H diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock_mshl.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock_mshl.cpp similarity index 72% rename from targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock_mshl.cpp rename to targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock_mshl.cpp index 664e294450..a62541d016 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock_mshl.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock_mshl.cpp @@ -6,13 +6,13 @@ // //----------------------------------------------------------------------------- -#include "nanoFramework_Hardware_Rp2040.h" -#include "nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock.h" +#include "nanoFramework_Hardware_Rpi.h" +#include "nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock.h" -using namespace nanoFramework_Hardware_Rp2040::nanoFramework_Hardware_Rp2040; +using namespace nanoFramework_Hardware_Rpi::nanoFramework_Hardware_Rpi; -HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock::NativeAddProgram___STATIC__I4__I4__SZARRAY_U2__I4__I4( CLR_RT_StackFrame& stack ) +HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeAddProgram___STATIC__I4__I4__SZARRAY_U2__I4__I4( CLR_RT_StackFrame& stack ) { NANOCLR_HEADER(); hr = S_OK; { @@ -36,7 +36,7 @@ HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_ NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock::NativeRemoveProgram___STATIC__VOID__I4__I4__I4( CLR_RT_StackFrame& stack ) +HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeRemoveProgram___STATIC__VOID__I4__I4__I4( CLR_RT_StackFrame& stack ) { NANOCLR_HEADER(); hr = S_OK; { @@ -57,7 +57,7 @@ HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_ NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock::NativeClaimUnusedSm___STATIC__I4__I4__BOOLEAN( CLR_RT_StackFrame& stack ) +HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeClaimUnusedSm___STATIC__I4__I4__BOOLEAN( CLR_RT_StackFrame& stack ) { NANOCLR_HEADER(); hr = S_OK; { @@ -75,7 +75,7 @@ HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_ NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock::NativeInitGpio___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) +HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeInitGpio___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) { NANOCLR_HEADER(); hr = S_OK; { @@ -93,7 +93,7 @@ HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_ NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock::NativeForceIrq___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) +HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeForceIrq___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) { NANOCLR_HEADER(); hr = S_OK; { @@ -111,7 +111,7 @@ HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_ NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioBlock::NativeClearIrq___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) +HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeClearIrq___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) { NANOCLR_HEADER(); hr = S_OK; { diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.cpp similarity index 91% rename from targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.cpp rename to targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.cpp index 8d9b04f983..75178944eb 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.cpp @@ -4,15 +4,15 @@ // PioStateMachine InternalCalls. NativeInit unpacks the config blob into the SM registers. // -#include "nanoFramework_Hardware_Rp2040.h" -#include "nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.h" +#include "nanoFramework_Hardware_Rpi.h" +#include "nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.h" #if defined(RP2350) #include "rp2350.h" #else #include "rp2040.h" #endif -using namespace nanoFramework_Hardware_Rp2040::nanoFramework_Hardware_Rp2040; +using namespace nanoFramework_Hardware_Rpi::nanoFramework_Hardware_Rpi; // FIFO busy-wait cap so a stalled SM times out instead of hanging the interpreter. static const unsigned int PIO_FIFO_WAIT_LIMIT = 0x4000000u; @@ -44,7 +44,10 @@ enum PioCfgBlob PIO_CFG_GPIO_BASE = 21, PIO_CFG_MOV_STATUS_SEL = 22, PIO_CFG_MOV_STATUS_N = 23, - PIO_CFG_BLOB_LENGTH = 24, + PIO_CFG_OUT_STICKY = 24, + PIO_CFG_INLINE_OUT_EN = 25, + PIO_CFG_OUT_EN_SEL = 26, + PIO_CFG_BLOB_LENGTH = 27, }; static PIO_TypeDef *PioFromIndex(int index) @@ -98,7 +101,9 @@ void PioStateMachine::NativeInit( // EXECCTRL: wrap [16:12], wrap_target [11:7], side_en [30], side_pindir [29], jmp_pin [28:24] unsigned int execCtrl = (b[PIO_CFG_WRAP] << 12) | (b[PIO_CFG_WRAP_TARGET] << 7) | (b[PIO_CFG_JMP_PIN] << 24) | - ((b[PIO_CFG_MOV_STATUS_SEL] & 1u) << 4) | (b[PIO_CFG_MOV_STATUS_N] & 0xFu); + ((b[PIO_CFG_MOV_STATUS_SEL] & 1u) << 4) | (b[PIO_CFG_MOV_STATUS_N] & 0xFu) | + ((b[PIO_CFG_OUT_STICKY] & 1u) << 17) | ((b[PIO_CFG_INLINE_OUT_EN] & 1u) << 18) | + ((b[PIO_CFG_OUT_EN_SEL] & 0x1Fu) << 19); if (b[PIO_CFG_SIDESET_OPT]) { execCtrl |= (1u << 30); @@ -386,3 +391,22 @@ unsigned int PioStateMachine::NativeGetPc(signed int param0, signed int param1, return pio->SM[sm].ADDR & 0x1Fu; } + +void PioStateMachine::NativeSetClockDivisor( + signed int param0, + signed int param1, + signed int param2, + signed int param3, + HRESULT &hr) +{ + PIO_TypeDef *pio = PioFromIndex(param0); + int sm = param1; + if (pio == nullptr || sm < 0 || sm > 3) + { + hr = CLR_E_INVALID_PARAMETER; + return; + } + + pio->SM[sm].CLKDIV = ((unsigned int)param2 << 16) | ((unsigned int)param3 << 8); + pio->CTRL |= (1u << (8 + sm)); +} diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.h b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.h similarity index 81% rename from targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.h rename to targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.h index 1f35d7762a..48ba91fd22 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.h +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.h @@ -10,12 +10,12 @@ // //----------------------------------------------------------------------------- -#ifndef NANOFRAMEWORK_HARDWARE_RP2040_NANOFRAMEWORK_HARDWARE_RP2040_NANOFRAMEWORK_HARDWARE_RP2040_PIO_PIOSTATEMACHINE_H -#define NANOFRAMEWORK_HARDWARE_RP2040_NANOFRAMEWORK_HARDWARE_RP2040_NANOFRAMEWORK_HARDWARE_RP2040_PIO_PIOSTATEMACHINE_H +#ifndef NANOFRAMEWORK_HARDWARE_RPI_NANOFRAMEWORK_HARDWARE_RPI_NANOFRAMEWORK_HARDWARE_RPI_PIO_PIOSTATEMACHINE_H +#define NANOFRAMEWORK_HARDWARE_RPI_NANOFRAMEWORK_HARDWARE_RPI_NANOFRAMEWORK_HARDWARE_RPI_PIO_PIOSTATEMACHINE_H -namespace nanoFramework_Hardware_Rp2040 +namespace nanoFramework_Hardware_Rpi { - namespace nanoFramework_Hardware_Rp2040 + namespace nanoFramework_Hardware_Rpi { struct PioStateMachine { @@ -54,8 +54,10 @@ namespace nanoFramework_Hardware_Rp2040 static unsigned int NativeGetPc( signed int param0, signed int param1, HRESULT &hr ); + static void NativeSetClockDivisor( signed int param0, signed int param1, signed int param2, signed int param3, HRESULT &hr ); + }; } } -#endif // NANOFRAMEWORK_HARDWARE_RP2040_NANOFRAMEWORK_HARDWARE_RP2040_NANOFRAMEWORK_HARDWARE_RP2040_PIO_PIOSTATEMACHINE_H +#endif // NANOFRAMEWORK_HARDWARE_RPI_NANOFRAMEWORK_HARDWARE_RPI_NANOFRAMEWORK_HARDWARE_RPI_PIO_PIOSTATEMACHINE_H diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine_mshl.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine_mshl.cpp similarity index 69% rename from targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine_mshl.cpp rename to targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine_mshl.cpp index 6cab897d2b..c7bd9ed1d1 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rp2040/nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine_mshl.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine_mshl.cpp @@ -6,13 +6,13 @@ // //----------------------------------------------------------------------------- -#include "nanoFramework_Hardware_Rp2040.h" -#include "nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine.h" +#include "nanoFramework_Hardware_Rpi.h" +#include "nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.h" -using namespace nanoFramework_Hardware_Rp2040::nanoFramework_Hardware_Rp2040; +using namespace nanoFramework_Hardware_Rpi::nanoFramework_Hardware_Rpi; -HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeInit___STATIC__VOID__I4__I4__I4__SZARRAY_U4( CLR_RT_StackFrame& stack ) +HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeInit___STATIC__VOID__I4__I4__I4__SZARRAY_U4( CLR_RT_StackFrame& stack ) { NANOCLR_HEADER(); hr = S_OK; { @@ -36,7 +36,7 @@ HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_ NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeSetEnabled___STATIC__VOID__I4__I4__BOOLEAN( CLR_RT_StackFrame& stack ) +HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeSetEnabled___STATIC__VOID__I4__I4__BOOLEAN( CLR_RT_StackFrame& stack ) { NANOCLR_HEADER(); hr = S_OK; { @@ -57,7 +57,7 @@ HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_ NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativePutBlocking___STATIC__VOID__I4__I4__U4( CLR_RT_StackFrame& stack ) +HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativePutBlocking___STATIC__VOID__I4__I4__U4( CLR_RT_StackFrame& stack ) { NANOCLR_HEADER(); hr = S_OK; { @@ -78,7 +78,7 @@ HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_ NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeGetBlocking___STATIC__U4__I4__I4( CLR_RT_StackFrame& stack ) +HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeGetBlocking___STATIC__U4__I4__I4( CLR_RT_StackFrame& stack ) { NANOCLR_HEADER(); hr = S_OK; { @@ -96,7 +96,7 @@ HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_ NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeTxFull___STATIC__BOOLEAN__I4__I4( CLR_RT_StackFrame& stack ) +HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeTxFull___STATIC__BOOLEAN__I4__I4( CLR_RT_StackFrame& stack ) { NANOCLR_HEADER(); hr = S_OK; { @@ -114,7 +114,7 @@ HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_ NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeRxEmpty___STATIC__BOOLEAN__I4__I4( CLR_RT_StackFrame& stack ) +HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeRxEmpty___STATIC__BOOLEAN__I4__I4( CLR_RT_StackFrame& stack ) { NANOCLR_HEADER(); hr = S_OK; { @@ -132,7 +132,7 @@ HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_ NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeUnclaim___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) +HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeUnclaim___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) { NANOCLR_HEADER(); hr = S_OK; { @@ -150,7 +150,7 @@ HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_ NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeSetConsecutivePinDirs___STATIC__VOID__I4__I4__I4__I4__BOOLEAN( CLR_RT_StackFrame& stack ) +HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeSetConsecutivePinDirs___STATIC__VOID__I4__I4__I4__I4__BOOLEAN( CLR_RT_StackFrame& stack ) { NANOCLR_HEADER(); hr = S_OK; { @@ -177,7 +177,7 @@ HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_ NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeClearFifos___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) +HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeClearFifos___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) { NANOCLR_HEADER(); hr = S_OK; { @@ -195,7 +195,7 @@ HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_ NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeDrainTxFifo___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) +HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeDrainTxFifo___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) { NANOCLR_HEADER(); hr = S_OK; { @@ -213,7 +213,7 @@ HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_ NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeRestart___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) +HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeRestart___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) { NANOCLR_HEADER(); hr = S_OK; { @@ -231,7 +231,7 @@ HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_ NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeClkDivRestart___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) +HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeClkDivRestart___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) { NANOCLR_HEADER(); hr = S_OK; { @@ -249,7 +249,7 @@ HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_ NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeExec___STATIC__VOID__I4__I4__U2( CLR_RT_StackFrame& stack ) +HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeExec___STATIC__VOID__I4__I4__U2( CLR_RT_StackFrame& stack ) { NANOCLR_HEADER(); hr = S_OK; { @@ -270,7 +270,7 @@ HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_ NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeTxLevel___STATIC__U4__I4__I4( CLR_RT_StackFrame& stack ) +HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeTxLevel___STATIC__U4__I4__I4( CLR_RT_StackFrame& stack ) { NANOCLR_HEADER(); hr = S_OK; { @@ -288,7 +288,7 @@ HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_ NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeRxLevel___STATIC__U4__I4__I4( CLR_RT_StackFrame& stack ) +HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeRxLevel___STATIC__U4__I4__I4( CLR_RT_StackFrame& stack ) { NANOCLR_HEADER(); hr = S_OK; { @@ -306,7 +306,7 @@ HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_ NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_PioStateMachine::NativeGetPc___STATIC__U4__I4__I4( CLR_RT_StackFrame& stack ) +HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeGetPc___STATIC__U4__I4__I4( CLR_RT_StackFrame& stack ) { NANOCLR_HEADER(); hr = S_OK; { @@ -323,3 +323,27 @@ HRESULT Library_nanoFramework_Hardware_Rp2040_nanoFramework_Hardware_Rp2040_Pio_ } NANOCLR_NOCLEANUP(); } + +HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeSetClockDivisor___STATIC__VOID__I4__I4__I4__I4( CLR_RT_StackFrame& stack ) +{ + NANOCLR_HEADER(); hr = S_OK; + { + + signed int param0; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 0, param0 ) ); + + signed int param1; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 1, param1 ) ); + + signed int param2; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 2, param2 ) ); + + signed int param3; + NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 3, param3 ) ); + + PioStateMachine::NativeSetClockDivisor( param0, param1, param2, param3, hr ); + NANOCLR_CHECK_HRESULT( hr ); + + } + NANOCLR_NOCLEANUP(); +} From 84feca915ee6c4e40e0c157774a773a119516886 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Fri, 26 Jun 2026 00:40:22 -0600 Subject: [PATCH 10/58] Bound the TX-FIFO drain loop with the same timeout guard as Put/Get --- ..._Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.cpp index 75178944eb..637f567e20 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.cpp @@ -305,10 +305,15 @@ void PioStateMachine::NativeDrainTxFifo(signed int param0, signed int param1, HR // exec OUT NULL,32 (autopull) or PULL noblock until TX empty. FSTAT TX_EMPTY = bits [27:24] unsigned int autopull = pio->SM[sm].SHIFTCTRL & (1u << 17); unsigned int instr = autopull ? 0x6060u : 0x8080u; - while ((pio->FSTAT & (1u << (24 + sm))) == 0) + unsigned int guard = PIO_FIFO_WAIT_LIMIT; + while ((pio->FSTAT & (1u << (24 + sm))) == 0 && --guard) { pio->SM[sm].INSTR = instr; } + if (guard == 0) + { + hr = CLR_E_TIMEOUT; + } } void PioStateMachine::NativeRestart(signed int param0, signed int param1, HRESULT &hr) From a5380aee95126b203c28fd8fe43a8f677ce1b7fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Fri, 26 Jun 2026 01:54:21 -0600 Subject: [PATCH 11/58] PIO: regenerate native interop for the managed event/Dispose additions; align to nf_hardware_rpi_native The managed PioBlock.Interrupt event, PioStateMachine finalizer and Enabled getter add methods to the InternalCall-bearing classes, shifting the native method_lookup table; the table and checksum are regenerated (0xFE5AB47E -> 0xB566C02F). Native files, symbols and the generated header are renamed to the nf_hardware_rpi_native skeleton (matching the convention used by the other hardware libraries) and the PioFromIndex helper is consolidated into nf_hardware_rpi_native_target.h. Builds green on RP2040 and RP2350. --- .../FindnanoFramework.Hardware.Rpi.cmake | 14 +- .../nanoFramework_Hardware_Rpi.cpp | 200 ----------------- .../nf_hardware_rpi_native.cpp | 202 ++++++++++++++++++ ...ardware_Rpi.h => nf_hardware_rpi_native.h} | 40 ++-- ...> nf_hardware_rpi_native_PioIrqDriver.cpp} | 20 +- ...> nf_hardware_rpi_native_PioIrqHandlers.c} | 0 ...noFramework_Hardware_Rpi_Pio_PioBlock.cpp} | 24 +-- ...nanoFramework_Hardware_Rpi_Pio_PioBlock.h} | 2 +- ...mework_Hardware_Rpi_Pio_PioBlock_mshl.cpp} | 18 +- ...work_Hardware_Rpi_Pio_PioStateMachine.cpp} | 24 +-- ...mework_Hardware_Rpi_Pio_PioStateMachine.h} | 2 +- ...Hardware_Rpi_Pio_PioStateMachine_mshl.cpp} | 40 ++-- .../nf_hardware_rpi_native_target.h | 30 +++ 13 files changed, 304 insertions(+), 312 deletions(-) delete mode 100644 targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi.cpp create mode 100644 targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native.cpp rename targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/{nanoFramework_Hardware_Rpi.h => nf_hardware_rpi_native.h} (85%) rename targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/{nanoFramework_Hardware_Rpi_PioIrqDriver.cpp => nf_hardware_rpi_native_PioIrqDriver.cpp} (92%) rename targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/{nanoFramework_Hardware_Rpi_PioIrqHandlers.c => nf_hardware_rpi_native_PioIrqHandlers.c} (100%) rename targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/{nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock.cpp => nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock.cpp} (92%) rename targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/{nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock.h => nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock.h} (97%) rename targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/{nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock_mshl.cpp => nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock_mshl.cpp} (73%) rename targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/{nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.cpp => nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.cpp} (95%) rename targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/{nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.h => nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.h} (98%) rename targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/{nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine_mshl.cpp => nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine_mshl.cpp} (75%) create mode 100644 targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_target.h diff --git a/CMake/Modules/FindnanoFramework.Hardware.Rpi.cmake b/CMake/Modules/FindnanoFramework.Hardware.Rpi.cmake index c737887081..83800330ce 100644 --- a/CMake/Modules/FindnanoFramework.Hardware.Rpi.cmake +++ b/CMake/Modules/FindnanoFramework.Hardware.Rpi.cmake @@ -15,13 +15,13 @@ list(APPEND nanoFramework.Hardware.Rpi_INCLUDE_DIRS "${BASE_PATH_FOR_THIS_MODULE # source files set(nanoFramework.Hardware.Rpi_SRCS - nanoFramework_Hardware_Rpi.cpp - nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock.cpp - nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock_mshl.cpp - nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.cpp - nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine_mshl.cpp - nanoFramework_Hardware_Rpi_PioIrqDriver.cpp - nanoFramework_Hardware_Rpi_PioIrqHandlers.c + nf_hardware_rpi_native.cpp + nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock.cpp + nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock_mshl.cpp + nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.cpp + nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine_mshl.cpp + nf_hardware_rpi_native_PioIrqDriver.cpp + nf_hardware_rpi_native_PioIrqHandlers.c ) foreach(SRC_FILE ${nanoFramework.Hardware.Rpi_SRCS}) diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi.cpp deleted file mode 100644 index d1cd9cdc30..0000000000 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi.cpp +++ /dev/null @@ -1,200 +0,0 @@ - //----------------------------------------------------------------------------- - // - // ** DO NOT EDIT THIS FILE! ** - // This file was generated by a tool - // re-running the tool will overwrite this file. - // - //----------------------------------------------------------------------------- - - #include "nanoFramework_Hardware_Rpi.h" - - // clang-format off - - static const CLR_RT_MethodHandler method_lookup[] = - { - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeAddProgram___STATIC__I4__I4__SZARRAY_U2__I4__I4, - Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeRemoveProgram___STATIC__VOID__I4__I4__I4, - Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeClaimUnusedSm___STATIC__I4__I4__BOOLEAN, - Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeInitGpio___STATIC__VOID__I4__I4, - Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeForceIrq___STATIC__VOID__I4__I4, - Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeClearIrq___STATIC__VOID__I4__I4, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeInit___STATIC__VOID__I4__I4__I4__SZARRAY_U4, - Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeSetEnabled___STATIC__VOID__I4__I4__BOOLEAN, - Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativePutBlocking___STATIC__VOID__I4__I4__U4, - Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeGetBlocking___STATIC__U4__I4__I4, - Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeTxFull___STATIC__BOOLEAN__I4__I4, - Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeRxEmpty___STATIC__BOOLEAN__I4__I4, - Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeUnclaim___STATIC__VOID__I4__I4, - Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeSetConsecutivePinDirs___STATIC__VOID__I4__I4__I4__I4__BOOLEAN, - Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeClearFifos___STATIC__VOID__I4__I4, - Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeDrainTxFifo___STATIC__VOID__I4__I4, - Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeRestart___STATIC__VOID__I4__I4, - Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeClkDivRestart___STATIC__VOID__I4__I4, - Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeExec___STATIC__VOID__I4__I4__U2, - Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeTxLevel___STATIC__U4__I4__I4, - Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeRxLevel___STATIC__U4__I4__I4, - Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeGetPc___STATIC__U4__I4__I4, - Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeSetClockDivisor___STATIC__VOID__I4__I4__I4__I4, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - }; - - const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Rpi = - { - "nanoFramework.Hardware.Rpi", - 0xFE5AB47E, - method_lookup, - { 1, 0, 0, 0 } - }; - - // clang-format on - \ No newline at end of file diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native.cpp new file mode 100644 index 0000000000..657c254bd1 --- /dev/null +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native.cpp @@ -0,0 +1,202 @@ + #include "nf_hardware_rpi_native.h" + + // clang-format off + + static const CLR_RT_MethodHandler method_lookup[] = + { + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeAddProgram___STATIC__I4__I4__SZARRAY_U2__I4__I4, + Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeRemoveProgram___STATIC__VOID__I4__I4__I4, + Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeClaimUnusedSm___STATIC__I4__I4__BOOLEAN, + Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeInitGpio___STATIC__VOID__I4__I4, + Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeForceIrq___STATIC__VOID__I4__I4, + Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeClearIrq___STATIC__VOID__I4__I4, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeInit___STATIC__VOID__I4__I4__I4__SZARRAY_U4, + Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeSetEnabled___STATIC__VOID__I4__I4__BOOLEAN, + Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativePutBlocking___STATIC__VOID__I4__I4__U4, + Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeGetBlocking___STATIC__U4__I4__I4, + Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeTxFull___STATIC__BOOLEAN__I4__I4, + Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeRxEmpty___STATIC__BOOLEAN__I4__I4, + Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeUnclaim___STATIC__VOID__I4__I4, + Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeSetConsecutivePinDirs___STATIC__VOID__I4__I4__I4__I4__BOOLEAN, + Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeClearFifos___STATIC__VOID__I4__I4, + Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeDrainTxFifo___STATIC__VOID__I4__I4, + Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeRestart___STATIC__VOID__I4__I4, + Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeClkDivRestart___STATIC__VOID__I4__I4, + Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeExec___STATIC__VOID__I4__I4__U2, + Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeTxLevel___STATIC__U4__I4__I4, + Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeRxLevel___STATIC__U4__I4__I4, + Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeGetPc___STATIC__U4__I4__I4, + Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeSetClockDivisor___STATIC__VOID__I4__I4__I4__I4, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + }; + + const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Rpi = + { + "nanoFramework.Hardware.Rpi", + 0xB566C02F, + method_lookup, + { 1, 0, 0, 0 } + }; + + // clang-format on + \ No newline at end of file diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi.h b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native.h similarity index 85% rename from targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi.h rename to targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native.h index 44563d28ba..a281134441 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi.h +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native.h @@ -1,18 +1,23 @@ //----------------------------------------------------------------------------- // - // ** DO NOT EDIT THIS FILE! ** - // This file was generated by a tool - // re-running the tool will overwrite this file. + // ** WARNING! ** + // This file was generated automatically by a tool. + // Re-running the tool will overwrite this file. + // You should copy this file to a custom location + // before adding any customization in the copy to + // prevent loss of your changes when the tool is + // re-run. // //----------------------------------------------------------------------------- - #ifndef NANOFRAMEWORK_HARDWARE_RPI_H - #define NANOFRAMEWORK_HARDWARE_RPI_H + #ifndef NF_HARDWARE_RPI_NATIVE_H + #define NF_HARDWARE_RPI_NATIVE_H #include #include #include - + #include + typedef enum __nfpack PioCondition { PioCondition_Always = 0, @@ -92,14 +97,14 @@ PioWaitSource_Irq = 2, } PioWaitSource; - struct Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_Pio + struct Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_Pio { static const int FIELD_STATIC___blocks = 0; //--// }; - struct Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioAssemblerOptions + struct Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioAssemblerOptions { static const int FIELD__Version = 1; static const int FIELD__SideSetCount = 2; @@ -109,7 +114,7 @@ //--// }; - struct Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioInstructionRef + struct Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioInstructionRef { static const int FIELD___owner = 1; static const int FIELD___index = 2; @@ -117,7 +122,7 @@ //--// }; - struct Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioLabel + struct Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioLabel { // renamed backing field 'k__BackingField' static const int FIELD__Id = 1; @@ -127,7 +132,7 @@ //--// }; - struct Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioAssembler + struct Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioAssembler { static const int FIELD___baseBits = 1; static const int FIELD___delay = 2; @@ -153,9 +158,11 @@ //--// }; - struct Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock + struct Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock { static const int FIELD___index = 1; + static const int FIELD___irqDispatcher = 2; + static const int FIELD___interruptCallbacks = 3; NANOCLR_NATIVE_DECLARE(NativeAddProgram___STATIC__I4__I4__SZARRAY_U2__I4__I4); NANOCLR_NATIVE_DECLARE(NativeRemoveProgram___STATIC__VOID__I4__I4__I4); @@ -167,7 +174,7 @@ //--// }; - struct Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioProgram + struct Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioProgram { // renamed backing field 'k__BackingField' static const int FIELD__Instructions = 1; @@ -201,11 +208,12 @@ //--// }; - struct Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine + struct Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine { static const int FIELD___block = 1; static const int FIELD___sm = 2; static const int FIELD___disposed = 3; + static const int FIELD___enabled = 4; NANOCLR_NATIVE_DECLARE(NativeInit___STATIC__VOID__I4__I4__I4__SZARRAY_U4); NANOCLR_NATIVE_DECLARE(NativeSetEnabled___STATIC__VOID__I4__I4__BOOLEAN); @@ -228,7 +236,7 @@ //--// }; - struct Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachineConfig + struct Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachineConfig { static const int FIELD___outBase = 1; static const int FIELD___outCount = 2; @@ -263,5 +271,5 @@ extern const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Rpi; - #endif // NANOFRAMEWORK_HARDWARE_RPI_H + #endif // NF_HARDWARE_RPI_NATIVE_H \ No newline at end of file diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_PioIrqDriver.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_PioIrqDriver.cpp similarity index 92% rename from targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_PioIrqDriver.cpp rename to targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_PioIrqDriver.cpp index 9cddbfe42c..16cf888d7e 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_PioIrqDriver.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_PioIrqDriver.cpp @@ -6,7 +6,7 @@ // un-mangled OSAL_IRQ_HANDLER symbol) and call PioIrqServiceBlock below. // -#include "nanoFramework_Hardware_Rpi.h" +#include "nf_hardware_rpi_native.h" #include #include // chSysLockFromISR #include // nvicEnableVector + RP_PIOx_IRQ_0_NUMBER @@ -15,27 +15,11 @@ #else #include "rp2040.h" #endif +#include "nf_hardware_rpi_native_target.h" // dispatcher context per block static CLR_RT_HeapBlock_NativeEventDispatcher *s_pioCtx[3] = {nullptr, nullptr, nullptr}; -static PIO_TypeDef *PioFromIndex(int index) -{ - switch (index) - { - case 0: - return PIO0; - case 1: - return PIO1; -#if defined(RP2350) - case 2: - return PIO2; -#endif - default: - return nullptr; - } -} - static int BlockOfContext(CLR_RT_HeapBlock_NativeEventDispatcher *pContext) { for (int b = 0; b < 3; b++) diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_PioIrqHandlers.c b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_PioIrqHandlers.c similarity index 100% rename from targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_PioIrqHandlers.c rename to targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_PioIrqHandlers.c diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock.cpp similarity index 92% rename from targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock.cpp rename to targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock.cpp index 0b8900d294..324172900b 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock.cpp @@ -5,32 +5,16 @@ // so the same code serves RP2040 and RP2350 (which adds PIO2). // -#include "nanoFramework_Hardware_Rpi.h" -#include "nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock.h" +#include "nf_hardware_rpi_native.h" +#include "nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock.h" #if defined(RP2350) #include "rp2350.h" #else #include "rp2040.h" #endif +#include "nf_hardware_rpi_native_target.h" -using namespace nanoFramework_Hardware_Rpi::nanoFramework_Hardware_Rpi; - -static PIO_TypeDef *PioFromIndex(int index) -{ - switch (index) - { - case 0: - return PIO0; - case 1: - return PIO1; -#if defined(RP2350) - case 2: - return PIO2; -#endif - default: - return nullptr; - } -} +using namespace nf_hardware_rpi_native::nanoFramework_Hardware_Rpi; // per-block bookkeeping (external linkage; PioStateMachine::NativeUnclaim releases a claim too) // g_PioInstrUsed: bit per instruction slot 0..31 in use diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock.h b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock.h similarity index 97% rename from targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock.h rename to targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock.h index 76ef4220dc..da492f7443 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock.h +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock.h @@ -13,7 +13,7 @@ #ifndef NANOFRAMEWORK_HARDWARE_RPI_NANOFRAMEWORK_HARDWARE_RPI_NANOFRAMEWORK_HARDWARE_RPI_PIO_PIOBLOCK_H #define NANOFRAMEWORK_HARDWARE_RPI_NANOFRAMEWORK_HARDWARE_RPI_NANOFRAMEWORK_HARDWARE_RPI_PIO_PIOBLOCK_H -namespace nanoFramework_Hardware_Rpi +namespace nf_hardware_rpi_native { namespace nanoFramework_Hardware_Rpi { diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock_mshl.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock_mshl.cpp similarity index 73% rename from targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock_mshl.cpp rename to targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock_mshl.cpp index a62541d016..e0165e3781 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock_mshl.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock_mshl.cpp @@ -6,13 +6,13 @@ // //----------------------------------------------------------------------------- -#include "nanoFramework_Hardware_Rpi.h" -#include "nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock.h" +#include "nf_hardware_rpi_native.h" +#include "nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock.h" -using namespace nanoFramework_Hardware_Rpi::nanoFramework_Hardware_Rpi; +using namespace nf_hardware_rpi_native::nanoFramework_Hardware_Rpi; -HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeAddProgram___STATIC__I4__I4__SZARRAY_U2__I4__I4( CLR_RT_StackFrame& stack ) +HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeAddProgram___STATIC__I4__I4__SZARRAY_U2__I4__I4( CLR_RT_StackFrame& stack ) { NANOCLR_HEADER(); hr = S_OK; { @@ -36,7 +36,7 @@ HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlo NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeRemoveProgram___STATIC__VOID__I4__I4__I4( CLR_RT_StackFrame& stack ) +HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeRemoveProgram___STATIC__VOID__I4__I4__I4( CLR_RT_StackFrame& stack ) { NANOCLR_HEADER(); hr = S_OK; { @@ -57,7 +57,7 @@ HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlo NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeClaimUnusedSm___STATIC__I4__I4__BOOLEAN( CLR_RT_StackFrame& stack ) +HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeClaimUnusedSm___STATIC__I4__I4__BOOLEAN( CLR_RT_StackFrame& stack ) { NANOCLR_HEADER(); hr = S_OK; { @@ -75,7 +75,7 @@ HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlo NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeInitGpio___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) +HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeInitGpio___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) { NANOCLR_HEADER(); hr = S_OK; { @@ -93,7 +93,7 @@ HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlo NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeForceIrq___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) +HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeForceIrq___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) { NANOCLR_HEADER(); hr = S_OK; { @@ -111,7 +111,7 @@ HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlo NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeClearIrq___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) +HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeClearIrq___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) { NANOCLR_HEADER(); hr = S_OK; { diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.cpp similarity index 95% rename from targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.cpp rename to targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.cpp index 637f567e20..aa4adb8c8a 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.cpp @@ -4,15 +4,16 @@ // PioStateMachine InternalCalls. NativeInit unpacks the config blob into the SM registers. // -#include "nanoFramework_Hardware_Rpi.h" -#include "nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.h" +#include "nf_hardware_rpi_native.h" +#include "nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.h" #if defined(RP2350) #include "rp2350.h" #else #include "rp2040.h" #endif +#include "nf_hardware_rpi_native_target.h" -using namespace nanoFramework_Hardware_Rpi::nanoFramework_Hardware_Rpi; +using namespace nf_hardware_rpi_native::nanoFramework_Hardware_Rpi; // FIFO busy-wait cap so a stalled SM times out instead of hanging the interpreter. static const unsigned int PIO_FIFO_WAIT_LIMIT = 0x4000000u; @@ -50,23 +51,6 @@ enum PioCfgBlob PIO_CFG_BLOB_LENGTH = 27, }; -static PIO_TypeDef *PioFromIndex(int index) -{ - switch (index) - { - case 0: - return PIO0; - case 1: - return PIO1; -#if defined(RP2350) - case 2: - return PIO2; -#endif - default: - return nullptr; - } -} - void PioStateMachine::NativeInit( signed int param0, signed int param1, diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.h b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.h similarity index 98% rename from targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.h rename to targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.h index 48ba91fd22..57d72f5531 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.h +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.h @@ -13,7 +13,7 @@ #ifndef NANOFRAMEWORK_HARDWARE_RPI_NANOFRAMEWORK_HARDWARE_RPI_NANOFRAMEWORK_HARDWARE_RPI_PIO_PIOSTATEMACHINE_H #define NANOFRAMEWORK_HARDWARE_RPI_NANOFRAMEWORK_HARDWARE_RPI_NANOFRAMEWORK_HARDWARE_RPI_PIO_PIOSTATEMACHINE_H -namespace nanoFramework_Hardware_Rpi +namespace nf_hardware_rpi_native { namespace nanoFramework_Hardware_Rpi { diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine_mshl.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine_mshl.cpp similarity index 75% rename from targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine_mshl.cpp rename to targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine_mshl.cpp index c7bd9ed1d1..7b86a5343d 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine_mshl.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine_mshl.cpp @@ -6,13 +6,13 @@ // //----------------------------------------------------------------------------- -#include "nanoFramework_Hardware_Rpi.h" -#include "nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.h" +#include "nf_hardware_rpi_native.h" +#include "nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.h" -using namespace nanoFramework_Hardware_Rpi::nanoFramework_Hardware_Rpi; +using namespace nf_hardware_rpi_native::nanoFramework_Hardware_Rpi; -HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeInit___STATIC__VOID__I4__I4__I4__SZARRAY_U4( CLR_RT_StackFrame& stack ) +HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeInit___STATIC__VOID__I4__I4__I4__SZARRAY_U4( CLR_RT_StackFrame& stack ) { NANOCLR_HEADER(); hr = S_OK; { @@ -36,7 +36,7 @@ HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioSta NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeSetEnabled___STATIC__VOID__I4__I4__BOOLEAN( CLR_RT_StackFrame& stack ) +HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeSetEnabled___STATIC__VOID__I4__I4__BOOLEAN( CLR_RT_StackFrame& stack ) { NANOCLR_HEADER(); hr = S_OK; { @@ -57,7 +57,7 @@ HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioSta NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativePutBlocking___STATIC__VOID__I4__I4__U4( CLR_RT_StackFrame& stack ) +HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativePutBlocking___STATIC__VOID__I4__I4__U4( CLR_RT_StackFrame& stack ) { NANOCLR_HEADER(); hr = S_OK; { @@ -78,7 +78,7 @@ HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioSta NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeGetBlocking___STATIC__U4__I4__I4( CLR_RT_StackFrame& stack ) +HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeGetBlocking___STATIC__U4__I4__I4( CLR_RT_StackFrame& stack ) { NANOCLR_HEADER(); hr = S_OK; { @@ -96,7 +96,7 @@ HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioSta NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeTxFull___STATIC__BOOLEAN__I4__I4( CLR_RT_StackFrame& stack ) +HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeTxFull___STATIC__BOOLEAN__I4__I4( CLR_RT_StackFrame& stack ) { NANOCLR_HEADER(); hr = S_OK; { @@ -114,7 +114,7 @@ HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioSta NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeRxEmpty___STATIC__BOOLEAN__I4__I4( CLR_RT_StackFrame& stack ) +HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeRxEmpty___STATIC__BOOLEAN__I4__I4( CLR_RT_StackFrame& stack ) { NANOCLR_HEADER(); hr = S_OK; { @@ -132,7 +132,7 @@ HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioSta NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeUnclaim___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) +HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeUnclaim___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) { NANOCLR_HEADER(); hr = S_OK; { @@ -150,7 +150,7 @@ HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioSta NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeSetConsecutivePinDirs___STATIC__VOID__I4__I4__I4__I4__BOOLEAN( CLR_RT_StackFrame& stack ) +HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeSetConsecutivePinDirs___STATIC__VOID__I4__I4__I4__I4__BOOLEAN( CLR_RT_StackFrame& stack ) { NANOCLR_HEADER(); hr = S_OK; { @@ -177,7 +177,7 @@ HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioSta NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeClearFifos___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) +HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeClearFifos___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) { NANOCLR_HEADER(); hr = S_OK; { @@ -195,7 +195,7 @@ HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioSta NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeDrainTxFifo___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) +HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeDrainTxFifo___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) { NANOCLR_HEADER(); hr = S_OK; { @@ -213,7 +213,7 @@ HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioSta NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeRestart___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) +HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeRestart___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) { NANOCLR_HEADER(); hr = S_OK; { @@ -231,7 +231,7 @@ HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioSta NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeClkDivRestart___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) +HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeClkDivRestart___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) { NANOCLR_HEADER(); hr = S_OK; { @@ -249,7 +249,7 @@ HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioSta NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeExec___STATIC__VOID__I4__I4__U2( CLR_RT_StackFrame& stack ) +HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeExec___STATIC__VOID__I4__I4__U2( CLR_RT_StackFrame& stack ) { NANOCLR_HEADER(); hr = S_OK; { @@ -270,7 +270,7 @@ HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioSta NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeTxLevel___STATIC__U4__I4__I4( CLR_RT_StackFrame& stack ) +HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeTxLevel___STATIC__U4__I4__I4( CLR_RT_StackFrame& stack ) { NANOCLR_HEADER(); hr = S_OK; { @@ -288,7 +288,7 @@ HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioSta NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeRxLevel___STATIC__U4__I4__I4( CLR_RT_StackFrame& stack ) +HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeRxLevel___STATIC__U4__I4__I4( CLR_RT_StackFrame& stack ) { NANOCLR_HEADER(); hr = S_OK; { @@ -306,7 +306,7 @@ HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioSta NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeGetPc___STATIC__U4__I4__I4( CLR_RT_StackFrame& stack ) +HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeGetPc___STATIC__U4__I4__I4( CLR_RT_StackFrame& stack ) { NANOCLR_HEADER(); hr = S_OK; { @@ -324,7 +324,7 @@ HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioSta NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Hardware_Rpi_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeSetClockDivisor___STATIC__VOID__I4__I4__I4__I4( CLR_RT_StackFrame& stack ) +HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeSetClockDivisor___STATIC__VOID__I4__I4__I4__I4( CLR_RT_StackFrame& stack ) { NANOCLR_HEADER(); hr = S_OK; { diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_target.h b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_target.h new file mode 100644 index 0000000000..0d53706576 --- /dev/null +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_target.h @@ -0,0 +1,30 @@ +// +// Copyright (c) .NET nanoFramework PIO contributors +// +// Shared helpers for the RP2040/RP2350 PIO native interop. Include after the CMSIS header +// (rp2040.h / rp2350.h) so PIO_TypeDef and PIO0/PIO1/PIO2 are defined. +// + +#ifndef NF_HARDWARE_RPI_NATIVE_TARGET_H +#define NF_HARDWARE_RPI_NATIVE_TARGET_H + +// Maps a PIO block index to its register block, or nullptr for an invalid index. +// RP2040 exposes PIO0/PIO1; RP2350 adds PIO2. +static inline PIO_TypeDef *PioFromIndex(int index) +{ + switch (index) + { + case 0: + return PIO0; + case 1: + return PIO1; +#if defined(RP2350) + case 2: + return PIO2; +#endif + default: + return nullptr; + } +} + +#endif // NF_HARDWARE_RPI_NATIVE_TARGET_H From 9ef9b54b6042f5ce718d41a89d5b46df1e98e2e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Fri, 26 Jun 2026 03:04:22 -0600 Subject: [PATCH 12/58] PIO: guard PioIrqVector behind !RP_PIO_REQUIRED so the Pico W build is warning-clean On RP_PIO_REQUIRED targets (Pico W, where the PIO is reserved for the CYW43) the IRQ0->NVIC wiring is compiled out, leaving PioIrqVector defined-but-unused and tripping -Werror=unused-function. Guard the helper with the same condition. No effect on RP2040/RP2350. --- .../nf_hardware_rpi_native_PioIrqDriver.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_PioIrqDriver.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_PioIrqDriver.cpp index 16cf888d7e..8471e97eb0 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_PioIrqDriver.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_PioIrqDriver.cpp @@ -33,6 +33,8 @@ static int BlockOfContext(CLR_RT_HeapBlock_NativeEventDispatcher *pContext) return -1; } +// Used only by the IRQ0->NVIC wiring, compiled out on RP_PIO_REQUIRED (Pico W). +#if !defined(RP_PIO_REQUIRED) static int PioIrqVector(int block) { switch (block) @@ -49,6 +51,7 @@ static int PioIrqVector(int block) return -1; } } +#endif // Called from the block's IRQ0 ISR (PioIrqHandlers.c), hence extern "C". extern "C" void PioIrqServiceBlock(int block) From 1bee7ddf0906297ec8f062d9d93a4ff33759571c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Fri, 26 Jun 2026 03:33:46 -0600 Subject: [PATCH 13/58] PIO: fix leftover Hardware.Rp2040 display labels after the Rpi rename --- CMake/Modules/FindNF_NativeAssemblies.cmake | 4 ++-- Kconfig.apis | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMake/Modules/FindNF_NativeAssemblies.cmake b/CMake/Modules/FindNF_NativeAssemblies.cmake index 16739f56ba..5f1fbd0952 100644 --- a/CMake/Modules/FindNF_NativeAssemblies.cmake +++ b/CMake/Modules/FindNF_NativeAssemblies.cmake @@ -42,7 +42,7 @@ option(API_nanoFramework.Networking.Thread "option for nanoFramewor # Stm32 only option(API_Hardware.Stm32 "option for Hardware.Stm32") -option(API_Hardware.Rpi "option for Hardware.Rp2040") +option(API_Hardware.Rpi "option for Hardware.Rpi") # TI CC13xxCC26xx option(API_nanoFramework.TI.EasyLink "option for nanoFramework.TI.EasyLink API") @@ -271,7 +271,7 @@ if(API_Hardware.Stm32) PerformSettingsForApiEntry("nanoFramework.Hardware.Stm32") endif() -# Hardware.Rp2040 +# Hardware.Rpi if(API_Hardware.Rpi) ##### API name here (doted name) PerformSettingsForApiEntry("nanoFramework.Hardware.Rpi") diff --git a/Kconfig.apis b/Kconfig.apis index a9cdb673dd..0fe20f945c 100644 --- a/Kconfig.apis +++ b/Kconfig.apis @@ -114,7 +114,7 @@ config API_HARDWARE_STM32 default n config API_HARDWARE_RPI - bool "Hardware.Rp2040" + bool "Hardware.Rpi" depends on RTOS_CHIBIOS default n From 9a2d8e19afd2a91f4222bac01bb1b669be8c4b96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Fri, 26 Jun 2026 03:46:33 -0600 Subject: [PATCH 14/58] PIO: standard license headers, fix file encoding, drop redundant CMake comments Addresses review feedback: replace the headers on the native interop files with the standard .NET Foundation header, normalize the mangled line endings to clean CRLF, and remove the leftover template/explanatory comments from the FindNF_NativeAssemblies entry. --- CMake/Modules/FindNF_NativeAssemblies.cmake | 3 - .../nf_hardware_rpi_native.cpp | 795 +++++++++--- .../nf_hardware_rpi_native.h | 1130 +++++++++++++---- .../nf_hardware_rpi_native_PioIrqDriver.cpp | 7 +- .../nf_hardware_rpi_native_PioIrqHandlers.c | 6 +- ...anoFramework_Hardware_Rpi_Pio_PioBlock.cpp | 6 +- ..._nanoFramework_Hardware_Rpi_Pio_PioBlock.h | 11 +- ...amework_Hardware_Rpi_Pio_PioBlock_mshl.cpp | 7 +- ...ework_Hardware_Rpi_Pio_PioStateMachine.cpp | 5 +- ...amework_Hardware_Rpi_Pio_PioStateMachine.h | 11 +- ..._Hardware_Rpi_Pio_PioStateMachine_mshl.cpp | 7 +- .../nf_hardware_rpi_native_target.h | 6 +- 12 files changed, 1466 insertions(+), 528 deletions(-) diff --git a/CMake/Modules/FindNF_NativeAssemblies.cmake b/CMake/Modules/FindNF_NativeAssemblies.cmake index 5f1fbd0952..69789e6438 100644 --- a/CMake/Modules/FindNF_NativeAssemblies.cmake +++ b/CMake/Modules/FindNF_NativeAssemblies.cmake @@ -273,11 +273,8 @@ endif() # Hardware.Rpi if(API_Hardware.Rpi) - ##### API name here (doted name) PerformSettingsForApiEntry("nanoFramework.Hardware.Rpi") - # special: the PIO IRQ driver is an internal interrupt driver (no managed end of its own); it is - # delivered to managed code through NativeEventDispatcher("PioIrqDriver", ...). list(APPEND CLR_RT_NativeAssemblyDataList "extern const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Rpi_PioIrqDriver;") list(APPEND CLR_RT_NativeAssemblyDataTableEntriesList "&g_CLR_AssemblyNative_nanoFramework_Hardware_Rpi_PioIrqDriver,") endif() diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native.cpp index 657c254bd1..8354686b50 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native.cpp @@ -1,202 +1,593 @@ - #include "nf_hardware_rpi_native.h" - - // clang-format off - - static const CLR_RT_MethodHandler method_lookup[] = - { - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeAddProgram___STATIC__I4__I4__SZARRAY_U2__I4__I4, - Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeRemoveProgram___STATIC__VOID__I4__I4__I4, - Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeClaimUnusedSm___STATIC__I4__I4__BOOLEAN, - Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeInitGpio___STATIC__VOID__I4__I4, - Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeForceIrq___STATIC__VOID__I4__I4, - Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeClearIrq___STATIC__VOID__I4__I4, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeInit___STATIC__VOID__I4__I4__I4__SZARRAY_U4, - Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeSetEnabled___STATIC__VOID__I4__I4__BOOLEAN, - Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativePutBlocking___STATIC__VOID__I4__I4__U4, - Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeGetBlocking___STATIC__U4__I4__I4, - Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeTxFull___STATIC__BOOLEAN__I4__I4, - Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeRxEmpty___STATIC__BOOLEAN__I4__I4, - Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeUnclaim___STATIC__VOID__I4__I4, - Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeSetConsecutivePinDirs___STATIC__VOID__I4__I4__I4__I4__BOOLEAN, - Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeClearFifos___STATIC__VOID__I4__I4, - Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeDrainTxFifo___STATIC__VOID__I4__I4, - Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeRestart___STATIC__VOID__I4__I4, - Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeClkDivRestart___STATIC__VOID__I4__I4, - Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeExec___STATIC__VOID__I4__I4__U2, - Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeTxLevel___STATIC__U4__I4__I4, - Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeRxLevel___STATIC__U4__I4__I4, - Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeGetPc___STATIC__U4__I4__I4, - Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeSetClockDivisor___STATIC__VOID__I4__I4__I4__I4, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - }; - - const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Rpi = - { - "nanoFramework.Hardware.Rpi", - 0xB566C02F, - method_lookup, - { 1, 0, 0, 0 } - }; - - // clang-format on - \ No newline at end of file +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include "nf_hardware_rpi_native.h" + + + +// clang-format off + + + +static const CLR_RT_MethodHandler method_lookup[] = + +{ + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeAddProgram___STATIC__I4__I4__SZARRAY_U2__I4__I4, + + + Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeRemoveProgram___STATIC__VOID__I4__I4__I4, + + + Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeClaimUnusedSm___STATIC__I4__I4__BOOLEAN, + + + Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeInitGpio___STATIC__VOID__I4__I4, + + + Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeForceIrq___STATIC__VOID__I4__I4, + + + Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeClearIrq___STATIC__VOID__I4__I4, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeInit___STATIC__VOID__I4__I4__I4__SZARRAY_U4, + + + Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeSetEnabled___STATIC__VOID__I4__I4__BOOLEAN, + + + Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativePutBlocking___STATIC__VOID__I4__I4__U4, + + + Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeGetBlocking___STATIC__U4__I4__I4, + + + Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeTxFull___STATIC__BOOLEAN__I4__I4, + + + Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeRxEmpty___STATIC__BOOLEAN__I4__I4, + + + Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeUnclaim___STATIC__VOID__I4__I4, + + + Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeSetConsecutivePinDirs___STATIC__VOID__I4__I4__I4__I4__BOOLEAN, + + + Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeClearFifos___STATIC__VOID__I4__I4, + + + Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeDrainTxFifo___STATIC__VOID__I4__I4, + + + Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeRestart___STATIC__VOID__I4__I4, + + + Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeClkDivRestart___STATIC__VOID__I4__I4, + + + Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeExec___STATIC__VOID__I4__I4__U2, + + + Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeTxLevel___STATIC__U4__I4__I4, + + + Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeRxLevel___STATIC__U4__I4__I4, + + + Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeGetPc___STATIC__U4__I4__I4, + + + Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeSetClockDivisor___STATIC__VOID__I4__I4__I4__I4, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + + NULL, + + +}; + + + +const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Rpi = + +{ + + "nanoFramework.Hardware.Rpi", + + 0xB566C02F, + + method_lookup, + + { 1, 0, 0, 0 } + +}; + + + +// clang-format on + + diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native.h b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native.h index a281134441..fc503002e7 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native.h +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native.h @@ -1,275 +1,855 @@ - //----------------------------------------------------------------------------- - // - // ** WARNING! ** - // This file was generated automatically by a tool. - // Re-running the tool will overwrite this file. - // You should copy this file to a custom location - // before adding any customization in the copy to - // prevent loss of your changes when the tool is - // re-run. - // - //----------------------------------------------------------------------------- - - #ifndef NF_HARDWARE_RPI_NATIVE_H - #define NF_HARDWARE_RPI_NATIVE_H - - #include - #include - #include - #include - - typedef enum __nfpack PioCondition - { - PioCondition_Always = 0, - PioCondition_XZero = 1, - PioCondition_XPostDec = 2, - PioCondition_YZero = 3, - PioCondition_YPostDec = 4, - PioCondition_XNotEqualY = 5, - PioCondition_Pin = 6, - PioCondition_OsrNotEmpty = 7, - } PioCondition; - - typedef enum __nfpack PioDest - { - PioDest_Pins = 0, - PioDest_X = 1, - PioDest_Y = 2, - PioDest_Null = 3, - PioDest_PinDirs = 4, - PioDest_Pc = 5, - PioDest_Status = 5, - PioDest_Isr = 6, - PioDest_Osr = 7, - PioDest_Exec = 7, - } PioDest; - - typedef enum __nfpack PioFifoJoin - { - PioFifoJoin_None = 0, - PioFifoJoin_Tx = 1, - PioFifoJoin_Rx = 2, - PioFifoJoin_TxGet = 4, - PioFifoJoin_TxPut = 8, - PioFifoJoin_PutGet = 12, - } PioFifoJoin; - - typedef enum __nfpack PioMovOp - { - PioMovOp_None = 0, - PioMovOp_Invert = 1, - PioMovOp_BitReverse = 2, - } PioMovOp; - - typedef enum __nfpack PioMovStatusSel - { - PioMovStatusSel_TxLevel = 0, - PioMovStatusSel_RxLevel = 1, - } PioMovStatusSel; - - typedef enum __nfpack PioShiftDir - { - PioShiftDir_Left = 0, - PioShiftDir_Right = 1, - } PioShiftDir; - - typedef enum __nfpack PioSrc - { - PioSrc_Pins = 0, - PioSrc_X = 1, - PioSrc_Y = 2, - PioSrc_Null = 3, - PioSrc_Status = 5, - PioSrc_Isr = 6, - PioSrc_Osr = 7, - } PioSrc; - - typedef enum __nfpack PioVersion - { - PioVersion_Rp2040 = 0, - PioVersion_Rp2350 = 1, - } PioVersion; - - typedef enum __nfpack PioWaitSource - { - PioWaitSource_Gpio = 0, - PioWaitSource_Pin = 1, - PioWaitSource_Irq = 2, - } PioWaitSource; - - struct Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_Pio - { - static const int FIELD_STATIC___blocks = 0; - - //--// - }; - - struct Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioAssemblerOptions - { - static const int FIELD__Version = 1; - static const int FIELD__SideSetCount = 2; - static const int FIELD__SideSetOpt = 3; - static const int FIELD__SideSetPinDirs = 4; - - //--// - }; - - struct Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioInstructionRef - { - static const int FIELD___owner = 1; - static const int FIELD___index = 2; - - //--// - }; - - struct Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioLabel - { - // renamed backing field 'k__BackingField' - static const int FIELD__Id = 1; - // renamed backing field '
k__BackingField' - static const int FIELD__Address = 2; - - //--// - }; - - struct Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioAssembler - { - static const int FIELD___baseBits = 1; - static const int FIELD___delay = 2; - static const int FIELD___sideValue = 3; - static const int FIELD___sideUsed = 4; - static const int FIELD___jmpLabel = 5; - static const int FIELD___count = 6; - static const int FIELD___labelCount = 7; - static const int FIELD___version = 8; - static const int FIELD___sideSetCount = 9; - static const int FIELD___sideSetOpt = 10; - static const int FIELD___sideSetPinDirs = 11; - static const int FIELD___wrapTarget = 12; - static const int FIELD___wrap = 13; - static const int FIELD___origin = 14; - static const int FIELD___outShiftDir = 15; - static const int FIELD___autoPull = 16; - static const int FIELD___pullThreshold = 17; - static const int FIELD___inShiftDir = 18; - static const int FIELD___autoPush = 19; - static const int FIELD___pushThreshold = 20; - - //--// - }; - - struct Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock - { - static const int FIELD___index = 1; - static const int FIELD___irqDispatcher = 2; - static const int FIELD___interruptCallbacks = 3; - - NANOCLR_NATIVE_DECLARE(NativeAddProgram___STATIC__I4__I4__SZARRAY_U2__I4__I4); - NANOCLR_NATIVE_DECLARE(NativeRemoveProgram___STATIC__VOID__I4__I4__I4); - NANOCLR_NATIVE_DECLARE(NativeClaimUnusedSm___STATIC__I4__I4__BOOLEAN); - NANOCLR_NATIVE_DECLARE(NativeInitGpio___STATIC__VOID__I4__I4); - NANOCLR_NATIVE_DECLARE(NativeForceIrq___STATIC__VOID__I4__I4); - NANOCLR_NATIVE_DECLARE(NativeClearIrq___STATIC__VOID__I4__I4); - - //--// - }; - - struct Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioProgram - { - // renamed backing field 'k__BackingField' - static const int FIELD__Instructions = 1; - // renamed backing field 'k__BackingField' - static const int FIELD__Wrap = 2; - // renamed backing field 'k__BackingField' - static const int FIELD__WrapTarget = 3; - // renamed backing field 'k__BackingField' - static const int FIELD__Origin = 4; - // renamed backing field 'k__BackingField' - static const int FIELD__SideSetCount = 5; - // renamed backing field 'k__BackingField' - static const int FIELD__SideSetOpt = 6; - // renamed backing field 'k__BackingField' - static const int FIELD__SideSetPinDirs = 7; - // renamed backing field 'k__BackingField' - static const int FIELD__OutShiftDir = 8; - // renamed backing field 'k__BackingField' - static const int FIELD__AutoPull = 9; - // renamed backing field 'k__BackingField' - static const int FIELD__PullThreshold = 10; - // renamed backing field 'k__BackingField' - static const int FIELD__InShiftDir = 11; - // renamed backing field 'k__BackingField' - static const int FIELD__AutoPush = 12; - // renamed backing field 'k__BackingField' - static const int FIELD__PushThreshold = 13; - // renamed backing field 'k__BackingField' - static const int FIELD__Version = 14; - - //--// - }; - - struct Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine - { - static const int FIELD___block = 1; - static const int FIELD___sm = 2; - static const int FIELD___disposed = 3; - static const int FIELD___enabled = 4; - - NANOCLR_NATIVE_DECLARE(NativeInit___STATIC__VOID__I4__I4__I4__SZARRAY_U4); - NANOCLR_NATIVE_DECLARE(NativeSetEnabled___STATIC__VOID__I4__I4__BOOLEAN); - NANOCLR_NATIVE_DECLARE(NativePutBlocking___STATIC__VOID__I4__I4__U4); - NANOCLR_NATIVE_DECLARE(NativeGetBlocking___STATIC__U4__I4__I4); - NANOCLR_NATIVE_DECLARE(NativeTxFull___STATIC__BOOLEAN__I4__I4); - NANOCLR_NATIVE_DECLARE(NativeRxEmpty___STATIC__BOOLEAN__I4__I4); - NANOCLR_NATIVE_DECLARE(NativeUnclaim___STATIC__VOID__I4__I4); - NANOCLR_NATIVE_DECLARE(NativeSetConsecutivePinDirs___STATIC__VOID__I4__I4__I4__I4__BOOLEAN); - NANOCLR_NATIVE_DECLARE(NativeClearFifos___STATIC__VOID__I4__I4); - NANOCLR_NATIVE_DECLARE(NativeDrainTxFifo___STATIC__VOID__I4__I4); - NANOCLR_NATIVE_DECLARE(NativeRestart___STATIC__VOID__I4__I4); - NANOCLR_NATIVE_DECLARE(NativeClkDivRestart___STATIC__VOID__I4__I4); - NANOCLR_NATIVE_DECLARE(NativeExec___STATIC__VOID__I4__I4__U2); - NANOCLR_NATIVE_DECLARE(NativeTxLevel___STATIC__U4__I4__I4); - NANOCLR_NATIVE_DECLARE(NativeRxLevel___STATIC__U4__I4__I4); - NANOCLR_NATIVE_DECLARE(NativeGetPc___STATIC__U4__I4__I4); - NANOCLR_NATIVE_DECLARE(NativeSetClockDivisor___STATIC__VOID__I4__I4__I4__I4); - - //--// - }; - - struct Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachineConfig - { - static const int FIELD___outBase = 1; - static const int FIELD___outCount = 2; - static const int FIELD___setBase = 3; - static const int FIELD___setCount = 4; - static const int FIELD___sideSetBase = 5; - static const int FIELD___inBase = 6; - static const int FIELD___jmpPin = 7; - static const int FIELD___sideSetCount = 8; - static const int FIELD___sideSetOpt = 9; - static const int FIELD___sideSetPinDirs = 10; - static const int FIELD___outShiftDir = 11; - static const int FIELD___autoPull = 12; - static const int FIELD___pullThreshold = 13; - static const int FIELD___inShiftDir = 14; - static const int FIELD___autoPush = 15; - static const int FIELD___pushThreshold = 16; - static const int FIELD___wrapTarget = 17; - static const int FIELD___wrap = 18; - static const int FIELD___clkDivInt = 19; - static const int FIELD___clkDivFrac = 20; - static const int FIELD___fifoJoin = 21; - static const int FIELD___gpioBase = 22; - static const int FIELD___movStatusSel = 23; - static const int FIELD___movStatusN = 24; - static const int FIELD___outSticky = 25; - static const int FIELD___inlineOutEn = 26; - static const int FIELD___outEnSel = 27; - - //--// - }; - - extern const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Rpi; - - #endif // NF_HARDWARE_RPI_NATIVE_H - \ No newline at end of file +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#ifndef NF_HARDWARE_RPI_NATIVE_H + +#define NF_HARDWARE_RPI_NATIVE_H + + + +#include + +#include + +#include + + +#include + + + + + +typedef enum __nfpack PioCondition + +{ + + + PioCondition_Always = 0, + + + PioCondition_XZero = 1, + + + PioCondition_XPostDec = 2, + + + PioCondition_YZero = 3, + + + PioCondition_YPostDec = 4, + + + PioCondition_XNotEqualY = 5, + + + PioCondition_Pin = 6, + + + PioCondition_OsrNotEmpty = 7, + + + +} PioCondition; + + + +typedef enum __nfpack PioDest + +{ + + + PioDest_Pins = 0, + + + PioDest_X = 1, + + + PioDest_Y = 2, + + + PioDest_Null = 3, + + + PioDest_PinDirs = 4, + + + PioDest_Pc = 5, + + + PioDest_Status = 5, + + + PioDest_Isr = 6, + + + PioDest_Osr = 7, + + + PioDest_Exec = 7, + + + +} PioDest; + + + +typedef enum __nfpack PioFifoJoin + +{ + + + PioFifoJoin_None = 0, + + + PioFifoJoin_Tx = 1, + + + PioFifoJoin_Rx = 2, + + + PioFifoJoin_TxGet = 4, + + + PioFifoJoin_TxPut = 8, + + + PioFifoJoin_PutGet = 12, + + + +} PioFifoJoin; + + + +typedef enum __nfpack PioMovOp + +{ + + + PioMovOp_None = 0, + + + PioMovOp_Invert = 1, + + + PioMovOp_BitReverse = 2, + + + +} PioMovOp; + + + +typedef enum __nfpack PioMovStatusSel + +{ + + + PioMovStatusSel_TxLevel = 0, + + + PioMovStatusSel_RxLevel = 1, + + + +} PioMovStatusSel; + + + +typedef enum __nfpack PioShiftDir + +{ + + + PioShiftDir_Left = 0, + + + PioShiftDir_Right = 1, + + + +} PioShiftDir; + + + +typedef enum __nfpack PioSrc + +{ + + + PioSrc_Pins = 0, + + + PioSrc_X = 1, + + + PioSrc_Y = 2, + + + PioSrc_Null = 3, + + + PioSrc_Status = 5, + + + PioSrc_Isr = 6, + + + PioSrc_Osr = 7, + + + +} PioSrc; + + + +typedef enum __nfpack PioVersion + +{ + + + PioVersion_Rp2040 = 0, + + + PioVersion_Rp2350 = 1, + + + +} PioVersion; + + + +typedef enum __nfpack PioWaitSource + +{ + + + PioWaitSource_Gpio = 0, + + + PioWaitSource_Pin = 1, + + + PioWaitSource_Irq = 2, + + + +} PioWaitSource; + + + + + +struct Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_Pio + +{ + + + + + static const int FIELD_STATIC___blocks = 0; + + + + + + + + + + + //--// + +}; + + + +struct Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioAssemblerOptions + +{ + + + + + + + + static const int FIELD__Version = 1; + + + + static const int FIELD__SideSetCount = 2; + + + + static const int FIELD__SideSetOpt = 3; + + + + static const int FIELD__SideSetPinDirs = 4; + + + + + + + + //--// + +}; + + + +struct Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioInstructionRef + +{ + + + + + + + + static const int FIELD___owner = 1; + + + + static const int FIELD___index = 2; + + + + + + + + //--// + +}; + + + +struct Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioLabel + +{ + + + + + + + + // renamed backing field 'k__BackingField' + + + static const int FIELD__Id = 1; + + + + // renamed backing field '
k__BackingField' + + + static const int FIELD__Address = 2; + + + + + + + + //--// + +}; + + + +struct Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioAssembler + +{ + + + + + + + + static const int FIELD___baseBits = 1; + + + + static const int FIELD___delay = 2; + + + + static const int FIELD___sideValue = 3; + + + + static const int FIELD___sideUsed = 4; + + + + static const int FIELD___jmpLabel = 5; + + + + static const int FIELD___count = 6; + + + + static const int FIELD___labelCount = 7; + + + + static const int FIELD___version = 8; + + + + static const int FIELD___sideSetCount = 9; + + + + static const int FIELD___sideSetOpt = 10; + + + + static const int FIELD___sideSetPinDirs = 11; + + + + static const int FIELD___wrapTarget = 12; + + + + static const int FIELD___wrap = 13; + + + + static const int FIELD___origin = 14; + + + + static const int FIELD___outShiftDir = 15; + + + + static const int FIELD___autoPull = 16; + + + + static const int FIELD___pullThreshold = 17; + + + + static const int FIELD___inShiftDir = 18; + + + + static const int FIELD___autoPush = 19; + + + + static const int FIELD___pushThreshold = 20; + + + + + + + + //--// + +}; + + + +struct Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock + +{ + + + + + + + + static const int FIELD___index = 1; + + + + static const int FIELD___irqDispatcher = 2; + + + + static const int FIELD___interruptCallbacks = 3; + + + + + + NANOCLR_NATIVE_DECLARE(NativeAddProgram___STATIC__I4__I4__SZARRAY_U2__I4__I4); + + + NANOCLR_NATIVE_DECLARE(NativeRemoveProgram___STATIC__VOID__I4__I4__I4); + + + NANOCLR_NATIVE_DECLARE(NativeClaimUnusedSm___STATIC__I4__I4__BOOLEAN); + + + NANOCLR_NATIVE_DECLARE(NativeInitGpio___STATIC__VOID__I4__I4); + + + NANOCLR_NATIVE_DECLARE(NativeForceIrq___STATIC__VOID__I4__I4); + + + NANOCLR_NATIVE_DECLARE(NativeClearIrq___STATIC__VOID__I4__I4); + + + + + //--// + +}; + + + +struct Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioProgram + +{ + + + + + + + + // renamed backing field 'k__BackingField' + + + static const int FIELD__Instructions = 1; + + + + // renamed backing field 'k__BackingField' + + + static const int FIELD__Wrap = 2; + + + + // renamed backing field 'k__BackingField' + + + static const int FIELD__WrapTarget = 3; + + + + // renamed backing field 'k__BackingField' + + + static const int FIELD__Origin = 4; + + + + // renamed backing field 'k__BackingField' + + + static const int FIELD__SideSetCount = 5; + + + + // renamed backing field 'k__BackingField' + + + static const int FIELD__SideSetOpt = 6; + + + + // renamed backing field 'k__BackingField' + + + static const int FIELD__SideSetPinDirs = 7; + + + + // renamed backing field 'k__BackingField' + + + static const int FIELD__OutShiftDir = 8; + + + + // renamed backing field 'k__BackingField' + + + static const int FIELD__AutoPull = 9; + + + + // renamed backing field 'k__BackingField' + + + static const int FIELD__PullThreshold = 10; + + + + // renamed backing field 'k__BackingField' + + + static const int FIELD__InShiftDir = 11; + + + + // renamed backing field 'k__BackingField' + + + static const int FIELD__AutoPush = 12; + + + + // renamed backing field 'k__BackingField' + + + static const int FIELD__PushThreshold = 13; + + + + // renamed backing field 'k__BackingField' + + + static const int FIELD__Version = 14; + + + + + + + + //--// + +}; + + + +struct Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine + +{ + + + + + + + + static const int FIELD___block = 1; + + + + static const int FIELD___sm = 2; + + + + static const int FIELD___disposed = 3; + + + + static const int FIELD___enabled = 4; + + + + + + NANOCLR_NATIVE_DECLARE(NativeInit___STATIC__VOID__I4__I4__I4__SZARRAY_U4); + + + NANOCLR_NATIVE_DECLARE(NativeSetEnabled___STATIC__VOID__I4__I4__BOOLEAN); + + + NANOCLR_NATIVE_DECLARE(NativePutBlocking___STATIC__VOID__I4__I4__U4); + + + NANOCLR_NATIVE_DECLARE(NativeGetBlocking___STATIC__U4__I4__I4); + + + NANOCLR_NATIVE_DECLARE(NativeTxFull___STATIC__BOOLEAN__I4__I4); + + + NANOCLR_NATIVE_DECLARE(NativeRxEmpty___STATIC__BOOLEAN__I4__I4); + + + NANOCLR_NATIVE_DECLARE(NativeUnclaim___STATIC__VOID__I4__I4); + + + NANOCLR_NATIVE_DECLARE(NativeSetConsecutivePinDirs___STATIC__VOID__I4__I4__I4__I4__BOOLEAN); + + + NANOCLR_NATIVE_DECLARE(NativeClearFifos___STATIC__VOID__I4__I4); + + + NANOCLR_NATIVE_DECLARE(NativeDrainTxFifo___STATIC__VOID__I4__I4); + + + NANOCLR_NATIVE_DECLARE(NativeRestart___STATIC__VOID__I4__I4); + + + NANOCLR_NATIVE_DECLARE(NativeClkDivRestart___STATIC__VOID__I4__I4); + + + NANOCLR_NATIVE_DECLARE(NativeExec___STATIC__VOID__I4__I4__U2); + + + NANOCLR_NATIVE_DECLARE(NativeTxLevel___STATIC__U4__I4__I4); + + + NANOCLR_NATIVE_DECLARE(NativeRxLevel___STATIC__U4__I4__I4); + + + NANOCLR_NATIVE_DECLARE(NativeGetPc___STATIC__U4__I4__I4); + + + NANOCLR_NATIVE_DECLARE(NativeSetClockDivisor___STATIC__VOID__I4__I4__I4__I4); + + + + + //--// + +}; + + + +struct Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachineConfig + +{ + + + + + + + + static const int FIELD___outBase = 1; + + + + static const int FIELD___outCount = 2; + + + + static const int FIELD___setBase = 3; + + + + static const int FIELD___setCount = 4; + + + + static const int FIELD___sideSetBase = 5; + + + + static const int FIELD___inBase = 6; + + + + static const int FIELD___jmpPin = 7; + + + + static const int FIELD___sideSetCount = 8; + + + + static const int FIELD___sideSetOpt = 9; + + + + static const int FIELD___sideSetPinDirs = 10; + + + + static const int FIELD___outShiftDir = 11; + + + + static const int FIELD___autoPull = 12; + + + + static const int FIELD___pullThreshold = 13; + + + + static const int FIELD___inShiftDir = 14; + + + + static const int FIELD___autoPush = 15; + + + + static const int FIELD___pushThreshold = 16; + + + + static const int FIELD___wrapTarget = 17; + + + + static const int FIELD___wrap = 18; + + + + static const int FIELD___clkDivInt = 19; + + + + static const int FIELD___clkDivFrac = 20; + + + + static const int FIELD___fifoJoin = 21; + + + + static const int FIELD___gpioBase = 22; + + + + static const int FIELD___movStatusSel = 23; + + + + static const int FIELD___movStatusN = 24; + + + + static const int FIELD___outSticky = 25; + + + + static const int FIELD___inlineOutEn = 26; + + + + static const int FIELD___outEnSel = 27; + + + + + + + + //--// + +}; + + + +extern const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Rpi; + + +#endif // NF_HARDWARE_RPI_NATIVE_H + diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_PioIrqDriver.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_PioIrqDriver.cpp index 8471e97eb0..b45a1f8264 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_PioIrqDriver.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_PioIrqDriver.cpp @@ -1,9 +1,6 @@ // -// Copyright (c) .NET nanoFramework PIO contributors -// -// PIO SM irq -> managed NativeEventDispatcher event ("PioIrqDriver", one dispatcher per block). -// Pure native driver, no InternalCalls. The NVIC vector handlers live in PioIrqHandlers.c (C, for the -// un-mangled OSAL_IRQ_HANDLER symbol) and call PioIrqServiceBlock below. +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. // #include "nf_hardware_rpi_native.h" diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_PioIrqHandlers.c b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_PioIrqHandlers.c index abd8c4ab55..bb11b57b0a 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_PioIrqHandlers.c +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_PioIrqHandlers.c @@ -1,8 +1,6 @@ // -// Copyright (c) .NET nanoFramework PIO contributors -// -// PIO IRQ0 vector handlers. Compiled as C so OSAL_IRQ_HANDLER's un-mangled symbol resolves; they just -// forward to PioIrqServiceBlock() in PioIrqDriver.cpp. +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. // #include diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock.cpp index 324172900b..dc8a5ddece 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock.cpp @@ -1,8 +1,6 @@ // -// Copyright (c) .NET nanoFramework PIO contributors -// -// PioBlock InternalCalls. Drives PIO registers directly (CMSIS, no pico-sdk). PIO v0 is a prefix of v1 -// so the same code serves RP2040 and RP2350 (which adds PIO2). +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. // #include "nf_hardware_rpi_native.h" diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock.h b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock.h index da492f7443..b77109d342 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock.h +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock.h @@ -1,14 +1,7 @@ -//----------------------------------------------------------------------------- // -// ** WARNING! ** -// This file was generated automatically by a tool. -// Re-running the tool will overwrite this file. -// You should copy this file to a custom location -// before adding any customization in the copy to -// prevent loss of your changes when the tool is -// re-run. +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. // -//----------------------------------------------------------------------------- #ifndef NANOFRAMEWORK_HARDWARE_RPI_NANOFRAMEWORK_HARDWARE_RPI_NANOFRAMEWORK_HARDWARE_RPI_PIO_PIOBLOCK_H #define NANOFRAMEWORK_HARDWARE_RPI_NANOFRAMEWORK_HARDWARE_RPI_NANOFRAMEWORK_HARDWARE_RPI_PIO_PIOBLOCK_H diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock_mshl.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock_mshl.cpp index e0165e3781..fa085c361e 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock_mshl.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock_mshl.cpp @@ -1,10 +1,7 @@ -//----------------------------------------------------------------------------- // -// ** DO NOT EDIT THIS FILE! ** -// This file was generated by a tool -// re-running the tool will overwrite this file. +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. // -//----------------------------------------------------------------------------- #include "nf_hardware_rpi_native.h" #include "nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock.h" diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.cpp index aa4adb8c8a..4127a5fefb 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.cpp @@ -1,7 +1,6 @@ // -// Copyright (c) .NET nanoFramework PIO contributors -// -// PioStateMachine InternalCalls. NativeInit unpacks the config blob into the SM registers. +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. // #include "nf_hardware_rpi_native.h" diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.h b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.h index 57d72f5531..ec7031b308 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.h +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.h @@ -1,14 +1,7 @@ -//----------------------------------------------------------------------------- // -// ** WARNING! ** -// This file was generated automatically by a tool. -// Re-running the tool will overwrite this file. -// You should copy this file to a custom location -// before adding any customization in the copy to -// prevent loss of your changes when the tool is -// re-run. +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. // -//----------------------------------------------------------------------------- #ifndef NANOFRAMEWORK_HARDWARE_RPI_NANOFRAMEWORK_HARDWARE_RPI_NANOFRAMEWORK_HARDWARE_RPI_PIO_PIOSTATEMACHINE_H #define NANOFRAMEWORK_HARDWARE_RPI_NANOFRAMEWORK_HARDWARE_RPI_NANOFRAMEWORK_HARDWARE_RPI_PIO_PIOSTATEMACHINE_H diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine_mshl.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine_mshl.cpp index 7b86a5343d..faf9a900ea 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine_mshl.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine_mshl.cpp @@ -1,10 +1,7 @@ -//----------------------------------------------------------------------------- // -// ** DO NOT EDIT THIS FILE! ** -// This file was generated by a tool -// re-running the tool will overwrite this file. +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. // -//----------------------------------------------------------------------------- #include "nf_hardware_rpi_native.h" #include "nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.h" diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_target.h b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_target.h index 0d53706576..e871ab9aa1 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_target.h +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_target.h @@ -1,8 +1,6 @@ // -// Copyright (c) .NET nanoFramework PIO contributors -// -// Shared helpers for the RP2040/RP2350 PIO native interop. Include after the CMSIS header -// (rp2040.h / rp2350.h) so PIO_TypeDef and PIO0/PIO1/PIO2 are defined. +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. // #ifndef NF_HARDWARE_RPI_NATIVE_TARGET_H From fd5d3e3b3d39c604720282718d68cf72bcba3086 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Fri, 26 Jun 2026 09:06:26 -0600 Subject: [PATCH 15/58] PIO: make nanoFramework.Hardware.Rpi a core library (skip the Interop marshalling layer) The nfproj already sets NF_IsCoreLibrary; regenerate the native interop to match so it skips the Interop safety layer: the InternalCalls now take CLR_RT_StackFrame& directly and the _mshl wrappers and per-class headers are dropped. Same native checksum (0xB566C02F). Builds green on RP2040 and RP2350; PIO samples pass on the virtual device and on RP2350Sharp. --- .../FindnanoFramework.Hardware.Rpi.cmake | 2 - ...anoFramework_Hardware_Rpi_Pio_PioBlock.cpp | 269 ++++---- ..._nanoFramework_Hardware_Rpi_Pio_PioBlock.h | 34 - ...amework_Hardware_Rpi_Pio_PioBlock_mshl.cpp | 127 ---- ...ework_Hardware_Rpi_Pio_PioStateMachine.cpp | 617 ++++++++++-------- ...amework_Hardware_Rpi_Pio_PioStateMachine.h | 56 -- ..._Hardware_Rpi_Pio_PioStateMachine_mshl.cpp | 346 ---------- 7 files changed, 500 insertions(+), 951 deletions(-) delete mode 100644 targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock.h delete mode 100644 targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock_mshl.cpp delete mode 100644 targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.h delete mode 100644 targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine_mshl.cpp diff --git a/CMake/Modules/FindnanoFramework.Hardware.Rpi.cmake b/CMake/Modules/FindnanoFramework.Hardware.Rpi.cmake index 83800330ce..b13dfebe50 100644 --- a/CMake/Modules/FindnanoFramework.Hardware.Rpi.cmake +++ b/CMake/Modules/FindnanoFramework.Hardware.Rpi.cmake @@ -17,9 +17,7 @@ set(nanoFramework.Hardware.Rpi_SRCS nf_hardware_rpi_native.cpp nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock.cpp - nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock_mshl.cpp nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.cpp - nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine_mshl.cpp nf_hardware_rpi_native_PioIrqDriver.cpp nf_hardware_rpi_native_PioIrqHandlers.c ) diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock.cpp index dc8a5ddece..4b0b9529bb 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock.cpp @@ -4,7 +4,6 @@ // #include "nf_hardware_rpi_native.h" -#include "nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock.h" #if defined(RP2350) #include "rp2350.h" #else @@ -12,15 +11,9 @@ #endif #include "nf_hardware_rpi_native_target.h" -using namespace nf_hardware_rpi_native::nanoFramework_Hardware_Rpi; - -// per-block bookkeeping (external linkage; PioStateMachine::NativeUnclaim releases a claim too) -// g_PioInstrUsed: bit per instruction slot 0..31 in use -// g_PioClaimedSm: bit per state machine 0..3 claimed unsigned int g_PioInstrUsed[3] = {0, 0, 0}; unsigned int g_PioClaimedSm[3] = {0, 0, 0}; -// mask of `length` slots from `offset` static unsigned int PioSlotMask(int offset, int length) { if (length <= 0) @@ -32,14 +25,12 @@ static unsigned int PioSlotMask(int offset, int length) return span << offset; } -// PIO powers up held in reset and ChibiOS doesn't un-reset it (only UART/USB/GPIO), so registers read 0 -// and ignore writes until the block (and the IO/PAD banks) are taken out of reset. #if defined(RP2350) -#define PIO_RESET_LSB 11u // RP2350: PIO0=11, PIO1=12, PIO2=13 +#define PIO_RESET_LSB 11u #define IO_BANK0_RESET_BIT (1u << 6) #define PADS_BANK0_RESET_BIT (1u << 9) #else -#define PIO_RESET_LSB 10u // RP2040: PIO0=10, PIO1=11 +#define PIO_RESET_LSB 10u #define IO_BANK0_RESET_BIT (1u << 5) #define PADS_BANK0_RESET_BIT (1u << 8) #endif @@ -48,170 +39,198 @@ static void PioEnsureOutOfReset(int blockIndex) { unsigned int bits = (1u << (PIO_RESET_LSB + (unsigned int)blockIndex)) | IO_BANK0_RESET_BIT | PADS_BANK0_RESET_BIT; - RESETS->CLR.RESET = bits; // atomic-clear alias + RESETS->CLR.RESET = bits; while ((RESETS->RESET_DONE & bits) != bits) { } } -signed int PioBlock::NativeAddProgram( - signed int param0, - CLR_RT_TypedArray_UINT16 param1, - signed int param2, - signed int param3, - HRESULT &hr) +HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock:: + NativeAddProgram___STATIC__I4__I4__SZARRAY_U2__I4__I4(CLR_RT_StackFrame &stack) { - PIO_TypeDef *pio = PioFromIndex(param0); - if (pio == nullptr || param0 < 0 || param0 > 2) + NANOCLR_HEADER(); { - hr = CLR_E_INVALID_PARAMETER; - return -1; - } + int block = stack.Arg0().NumericByRef().s4; + unsigned short *instr = (unsigned short *)stack.Arg1().DereferenceArray()->GetFirstElement(); + int length = stack.Arg2().NumericByRef().s4; + int origin = stack.Arg3().NumericByRef().s4; - // first PIO call in any flow, so un-reset here - PioEnsureOutOfReset(param0); - - unsigned short *instr = param1.GetBuffer(); - int length = param2; - int origin = param3; + PIO_TypeDef *pio = PioFromIndex(block); + if (pio == nullptr || block < 0 || block > 2) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } - if (length <= 0 || length > 32) - { - return -1; - } + // first PIO call in any flow, so un-reset here + PioEnsureOutOfReset(block); - // fixed origin needs its exact slots free; relocatable takes the lowest free run (first-fit) - int offset = -1; - if (origin >= 0) - { - if (origin + length <= 32 && (g_PioInstrUsed[param0] & PioSlotMask(origin, length)) == 0) + int offset = -1; + if (length > 0 && length <= 32) { - offset = origin; + // fixed origin needs its exact slots free; relocatable takes the lowest free run (first-fit) + if (origin >= 0) + { + if (origin + length <= 32 && (g_PioInstrUsed[block] & PioSlotMask(origin, length)) == 0) + { + offset = origin; + } + } + else + { + for (int candidate = 0; candidate + length <= 32; candidate++) + { + if ((g_PioInstrUsed[block] & PioSlotMask(candidate, length)) == 0) + { + offset = candidate; + break; + } + } + } } - } - else - { - for (int candidate = 0; candidate + length <= 32; candidate++) + + if (offset >= 0) { - if ((g_PioInstrUsed[param0] & PioSlotMask(candidate, length)) == 0) + bool relocate = origin < 0; + for (int i = 0; i < length; i++) { - offset = candidate; - break; + unsigned short w = instr[i]; + // relocate JMP (opcode 0b000) targets by the load offset + if (relocate && (w & 0xE000) == 0x0000) + { + unsigned int target = ((unsigned int)(w & 0x1F) + (unsigned int)offset) & 0x1F; + w = (unsigned short)((w & ~0x1F) | target); + } + pio->INSTR_MEM[offset + i] = w; } + g_PioInstrUsed[block] |= PioSlotMask(offset, length); } - } - if (offset < 0) - { - return -1; // no room + stack.SetResult_I4(offset); } + NANOCLR_NOCLEANUP(); +} - bool relocate = origin < 0; - for (int i = 0; i < length; i++) +HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock:: + NativeRemoveProgram___STATIC__VOID__I4__I4__I4(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); { - unsigned short w = instr[i]; - // relocate JMP (opcode 0b000) targets by the load offset - if (relocate && (w & 0xE000) == 0x0000) + int block = stack.Arg0().NumericByRef().s4; + int length = stack.Arg1().NumericByRef().s4; + int offset = stack.Arg2().NumericByRef().s4; + + PIO_TypeDef *pio = PioFromIndex(block); + if (pio == nullptr || offset < 0 || length <= 0 || offset + length > 32) { - unsigned int target = ((unsigned int)(w & 0x1F) + (unsigned int)offset) & 0x1F; - w = (unsigned short)((w & ~0x1F) | target); + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } - pio->INSTR_MEM[offset + i] = w; - } - g_PioInstrUsed[param0] |= PioSlotMask(offset, length); + // reclaim slots, blank to JMP-to-self so a stray enable can't run stale opcodes + for (int i = 0; i < length; i++) + { + pio->INSTR_MEM[offset + i] = (unsigned short)((offset + i) & 0x1F); + } - return offset; + g_PioInstrUsed[block] &= ~PioSlotMask(offset, length); + } + NANOCLR_NOCLEANUP(); } -void PioBlock::NativeRemoveProgram(signed int param0, signed int param1, signed int param2, HRESULT &hr) +HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock:: + NativeClaimUnusedSm___STATIC__I4__I4__BOOLEAN(CLR_RT_StackFrame &stack) { - PIO_TypeDef *pio = PioFromIndex(param0); - int length = param1; - int offset = param2; - if (pio == nullptr || offset < 0 || length <= 0 || offset + length > 32) + NANOCLR_HEADER(); { - hr = CLR_E_INVALID_PARAMETER; - return; - } + int block = stack.Arg0().NumericByRef().s4; + bool required = stack.Arg1().NumericByRef().u1; - // reclaim slots, blank to JMP-to-self so a stray enable can't run stale opcodes - for (int i = 0; i < length; i++) - { - pio->INSTR_MEM[offset + i] = (unsigned short)((offset + i) & 0x1F); - } - - g_PioInstrUsed[param0] &= ~PioSlotMask(offset, length); -} + PIO_TypeDef *pio = PioFromIndex(block); + if (pio == nullptr) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } -signed int PioBlock::NativeClaimUnusedSm(signed int param0, bool param1, HRESULT &hr) -{ - PIO_TypeDef *pio = PioFromIndex(param0); - if (pio == nullptr) - { - hr = CLR_E_INVALID_PARAMETER; - return -1; - } + int claimed = -1; + for (int sm = 0; sm < 4; sm++) + { + if ((g_PioClaimedSm[block] & (1u << sm)) == 0) + { + g_PioClaimedSm[block] |= (1u << sm); + claimed = sm; + break; + } + } - // first unclaimed SM - for (int sm = 0; sm < 4; sm++) - { - if ((g_PioClaimedSm[param0] & (1u << sm)) == 0) + // none free: `required` hard-fails, else soft -1 + if (claimed < 0 && required) { - g_PioClaimedSm[param0] |= (1u << sm); - return sm; + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); } - } - // none free: `required` hard-fails, else soft -1 - if (param1) - { - hr = CLR_E_INVALID_OPERATION; + stack.SetResult_I4(claimed); } - - return -1; + NANOCLR_NOCLEANUP(); } -void PioBlock::NativeInitGpio(signed int param0, signed int param1, HRESULT &hr) +HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock:: + NativeInitGpio___STATIC__VOID__I4__I4(CLR_RT_StackFrame &stack) { - int block = param0; - int pin = param1; + NANOCLR_HEADER(); + { + int block = stack.Arg0().NumericByRef().s4; + int pin = stack.Arg1().NumericByRef().s4; + #if defined(RP2350) - if (block < 0 || block > 2 || pin < 0 || pin > 47) + if (block < 0 || block > 2 || pin < 0 || pin > 47) #else - if (block < 0 || block > 1 || pin < 0 || pin > 29) + if (block < 0 || block > 1 || pin < 0 || pin > 29) #endif - { - hr = CLR_E_INVALID_PARAMETER; - return; - } + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } - // FUNCSEL = 6 (PIO0), 7 (PIO1), 8 (PIO2) - IO_BANK0->GPIO[pin].CTRL = 6u + (unsigned int)block; - // clear OD (bit 7), set IE (bit 6); also clear the RP2350 pad isolation latch (bit 8, resets to 1) - PADS_BANK0->GPIO[pin] = (PADS_BANK0->GPIO[pin] & ~0x180u) | 0x40u; + // FUNCSEL = 6 (PIO0), 7 (PIO1), 8 (PIO2) + IO_BANK0->GPIO[pin].CTRL = 6u + (unsigned int)block; + // clear OD (bit 7), set IE (bit 6); also clear the RP2350 pad isolation latch (bit 8, resets to 1) + PADS_BANK0->GPIO[pin] = (PADS_BANK0->GPIO[pin] & ~0x180u) | 0x40u; + } + NANOCLR_NOCLEANUP(); } -void PioBlock::NativeForceIrq(signed int param0, signed int param1, HRESULT &hr) +HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock:: + NativeForceIrq___STATIC__VOID__I4__I4(CLR_RT_StackFrame &stack) { - PIO_TypeDef *pio = PioFromIndex(param0); - if (pio == nullptr || param1 < 0 || param1 > 7) + NANOCLR_HEADER(); { - hr = CLR_E_INVALID_PARAMETER; - return; - } + int block = stack.Arg0().NumericByRef().s4; + int irq = stack.Arg1().NumericByRef().s4; - pio->IRQ_FORCE = (1u << param1); + PIO_TypeDef *pio = PioFromIndex(block); + if (pio == nullptr || irq < 0 || irq > 7) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + pio->IRQ_FORCE = (1u << irq); + } + NANOCLR_NOCLEANUP(); } -void PioBlock::NativeClearIrq(signed int param0, signed int param1, HRESULT &hr) +HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock:: + NativeClearIrq___STATIC__VOID__I4__I4(CLR_RT_StackFrame &stack) { - PIO_TypeDef *pio = PioFromIndex(param0); - if (pio == nullptr || param1 < 0 || param1 > 7) + NANOCLR_HEADER(); { - hr = CLR_E_INVALID_PARAMETER; - return; - } + int block = stack.Arg0().NumericByRef().s4; + int irq = stack.Arg1().NumericByRef().s4; - pio->IRQ = (1u << param1); + PIO_TypeDef *pio = PioFromIndex(block); + if (pio == nullptr || irq < 0 || irq > 7) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + pio->IRQ = (1u << irq); + } + NANOCLR_NOCLEANUP(); } diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock.h b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock.h deleted file mode 100644 index b77109d342..0000000000 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock.h +++ /dev/null @@ -1,34 +0,0 @@ -// -// Copyright (c) .NET Foundation and Contributors -// See LICENSE file in the project root for full license information. -// - -#ifndef NANOFRAMEWORK_HARDWARE_RPI_NANOFRAMEWORK_HARDWARE_RPI_NANOFRAMEWORK_HARDWARE_RPI_PIO_PIOBLOCK_H -#define NANOFRAMEWORK_HARDWARE_RPI_NANOFRAMEWORK_HARDWARE_RPI_NANOFRAMEWORK_HARDWARE_RPI_PIO_PIOBLOCK_H - -namespace nf_hardware_rpi_native -{ - namespace nanoFramework_Hardware_Rpi - { - struct PioBlock - { - // Helper Functions to access fields of managed object - // Declaration of stubs. These functions are implemented by Interop code developers - - static signed int NativeAddProgram( signed int param0, CLR_RT_TypedArray_UINT16 param1, signed int param2, signed int param3, HRESULT &hr ); - - static void NativeRemoveProgram( signed int param0, signed int param1, signed int param2, HRESULT &hr ); - - static signed int NativeClaimUnusedSm( signed int param0, bool param1, HRESULT &hr ); - - static void NativeInitGpio( signed int param0, signed int param1, HRESULT &hr ); - - static void NativeForceIrq( signed int param0, signed int param1, HRESULT &hr ); - - static void NativeClearIrq( signed int param0, signed int param1, HRESULT &hr ); - - }; - } -} - -#endif // NANOFRAMEWORK_HARDWARE_RPI_NANOFRAMEWORK_HARDWARE_RPI_NANOFRAMEWORK_HARDWARE_RPI_PIO_PIOBLOCK_H diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock_mshl.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock_mshl.cpp deleted file mode 100644 index fa085c361e..0000000000 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock_mshl.cpp +++ /dev/null @@ -1,127 +0,0 @@ -// -// Copyright (c) .NET Foundation and Contributors -// See LICENSE file in the project root for full license information. -// - -#include "nf_hardware_rpi_native.h" -#include "nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock.h" - -using namespace nf_hardware_rpi_native::nanoFramework_Hardware_Rpi; - - -HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeAddProgram___STATIC__I4__I4__SZARRAY_U2__I4__I4( CLR_RT_StackFrame& stack ) -{ - NANOCLR_HEADER(); hr = S_OK; - { - - signed int param0; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 0, param0 ) ); - - CLR_RT_TypedArray_UINT16 param1; - NANOCLR_CHECK_HRESULT( Interop_Marshal_UINT16_ARRAY( stack, 1, param1 ) ); - - signed int param2; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 2, param2 ) ); - - signed int param3; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 3, param3 ) ); - - signed int retValue = PioBlock::NativeAddProgram( param0, param1, param2, param3, hr ); - NANOCLR_CHECK_HRESULT( hr ); - SetResult_INT32( stack, retValue ); - } - NANOCLR_NOCLEANUP(); -} - -HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeRemoveProgram___STATIC__VOID__I4__I4__I4( CLR_RT_StackFrame& stack ) -{ - NANOCLR_HEADER(); hr = S_OK; - { - - signed int param0; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 0, param0 ) ); - - signed int param1; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 1, param1 ) ); - - signed int param2; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 2, param2 ) ); - - PioBlock::NativeRemoveProgram( param0, param1, param2, hr ); - NANOCLR_CHECK_HRESULT( hr ); - - } - NANOCLR_NOCLEANUP(); -} - -HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeClaimUnusedSm___STATIC__I4__I4__BOOLEAN( CLR_RT_StackFrame& stack ) -{ - NANOCLR_HEADER(); hr = S_OK; - { - - signed int param0; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 0, param0 ) ); - - bool param1; - NANOCLR_CHECK_HRESULT( Interop_Marshal_bool( stack, 1, param1 ) ); - - signed int retValue = PioBlock::NativeClaimUnusedSm( param0, param1, hr ); - NANOCLR_CHECK_HRESULT( hr ); - SetResult_INT32( stack, retValue ); - } - NANOCLR_NOCLEANUP(); -} - -HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeInitGpio___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) -{ - NANOCLR_HEADER(); hr = S_OK; - { - - signed int param0; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 0, param0 ) ); - - signed int param1; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 1, param1 ) ); - - PioBlock::NativeInitGpio( param0, param1, hr ); - NANOCLR_CHECK_HRESULT( hr ); - - } - NANOCLR_NOCLEANUP(); -} - -HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeForceIrq___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) -{ - NANOCLR_HEADER(); hr = S_OK; - { - - signed int param0; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 0, param0 ) ); - - signed int param1; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 1, param1 ) ); - - PioBlock::NativeForceIrq( param0, param1, hr ); - NANOCLR_CHECK_HRESULT( hr ); - - } - NANOCLR_NOCLEANUP(); -} - -HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeClearIrq___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) -{ - NANOCLR_HEADER(); hr = S_OK; - { - - signed int param0; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 0, param0 ) ); - - signed int param1; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 1, param1 ) ); - - PioBlock::NativeClearIrq( param0, param1, hr ); - NANOCLR_CHECK_HRESULT( hr ); - - } - NANOCLR_NOCLEANUP(); -} diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.cpp index 4127a5fefb..da8f205bae 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.cpp @@ -4,7 +4,6 @@ // #include "nf_hardware_rpi_native.h" -#include "nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.h" #if defined(RP2350) #include "rp2350.h" #else @@ -12,8 +11,6 @@ #endif #include "nf_hardware_rpi_native_target.h" -using namespace nf_hardware_rpi_native::nanoFramework_Hardware_Rpi; - // FIFO busy-wait cap so a stalled SM times out instead of hanging the interpreter. static const unsigned int PIO_FIFO_WAIT_LIMIT = 0x4000000u; @@ -50,351 +47,449 @@ enum PioCfgBlob PIO_CFG_BLOB_LENGTH = 27, }; -void PioStateMachine::NativeInit( - signed int param0, - signed int param1, - signed int param2, - CLR_RT_TypedArray_UINT32 param3, - HRESULT &hr) -{ - PIO_TypeDef *pio = PioFromIndex(param0); - int sm = param1; - if (pio == nullptr || sm < 0 || sm > 3 || param3.GetSize() < PIO_CFG_BLOB_LENGTH) - { - hr = CLR_E_INVALID_PARAMETER; - return; - } +// claim bitmask owned by PioBlock.cpp +extern unsigned int g_PioClaimedSm[3]; - unsigned int *b = param3.GetBuffer(); - - // disable + restart before reconfigure - pio->CTRL &= ~(1u << sm); - pio->CTRL |= (1u << (4 + sm)); // SM_RESTART - - // CLKDIV: int [31:16], frac [15:8] - pio->SM[sm].CLKDIV = (b[PIO_CFG_CLKDIV_INT] << 16) | (b[PIO_CFG_CLKDIV_FRAC] << 8); - - // side-set count includes the optional enable bit - unsigned int sidesetTotal = b[PIO_CFG_SIDESET_COUNT] + b[PIO_CFG_SIDESET_OPT]; - pio->SM[sm].PINCTRL = - (sidesetTotal << 29) | (b[PIO_CFG_SET_COUNT] << 26) | (b[PIO_CFG_OUT_COUNT] << 20) | - (b[PIO_CFG_IN_BASE] << 15) | (b[PIO_CFG_SIDESET_BASE] << 10) | (b[PIO_CFG_SET_BASE] << 5) | - b[PIO_CFG_OUT_BASE]; - - // EXECCTRL: wrap [16:12], wrap_target [11:7], side_en [30], side_pindir [29], jmp_pin [28:24] - unsigned int execCtrl = - (b[PIO_CFG_WRAP] << 12) | (b[PIO_CFG_WRAP_TARGET] << 7) | (b[PIO_CFG_JMP_PIN] << 24) | - ((b[PIO_CFG_MOV_STATUS_SEL] & 1u) << 4) | (b[PIO_CFG_MOV_STATUS_N] & 0xFu) | - ((b[PIO_CFG_OUT_STICKY] & 1u) << 17) | ((b[PIO_CFG_INLINE_OUT_EN] & 1u) << 18) | - ((b[PIO_CFG_OUT_EN_SEL] & 0x1Fu) << 19); - if (b[PIO_CFG_SIDESET_OPT]) - { - execCtrl |= (1u << 30); - } - if (b[PIO_CFG_SIDESET_PINDIRS]) +HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine:: + NativeInit___STATIC__VOID__I4__I4__I4__SZARRAY_U4(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); { - execCtrl |= (1u << 29); - } - pio->SM[sm].EXECCTRL = execCtrl; - - // a 32-bit threshold encodes as 0 in the 5-bit field - unsigned int pushThresh = b[PIO_CFG_PUSH_THRESHOLD] & 0x1F; - unsigned int pullThresh = b[PIO_CFG_PULL_THRESHOLD] & 0x1F; - // FJOIN: low 2 bits -> TX [30] / RX [31]; high 2 bits (PIO v1) -> RX_GET [14] / RX_PUT [15] - unsigned int join = b[PIO_CFG_FIFO_JOIN]; - pio->SM[sm].SHIFTCTRL = - (b[PIO_CFG_IN_SHIFT_RIGHT] << 18) | (b[PIO_CFG_OUT_SHIFT_RIGHT] << 19) | - (b[PIO_CFG_AUTOPUSH] << 16) | (b[PIO_CFG_AUTOPULL] << 17) | (pushThresh << 20) | - (pullThresh << 25) | ((join & 3u) << 30) | ((join >> 2) << 14); + int block = stack.Arg0().NumericByRef().s4; + int sm = stack.Arg1().NumericByRef().s4; + int offset = stack.Arg2().NumericByRef().s4; + CLR_RT_HeapBlock_Array *blobArray = stack.Arg3().DereferenceArray(); + unsigned int *b = (unsigned int *)blobArray->GetFirstElement(); + + PIO_TypeDef *pio = PioFromIndex(block); + if (pio == nullptr || sm < 0 || sm > 3 || (int)blobArray->m_numOfElements < PIO_CFG_BLOB_LENGTH) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + // disable + restart before reconfigure + pio->CTRL &= ~(1u << sm); + pio->CTRL |= (1u << (4 + sm)); // SM_RESTART + + // CLKDIV: int [31:16], frac [15:8] + pio->SM[sm].CLKDIV = (b[PIO_CFG_CLKDIV_INT] << 16) | (b[PIO_CFG_CLKDIV_FRAC] << 8); + + // side-set count includes the optional enable bit + unsigned int sidesetTotal = b[PIO_CFG_SIDESET_COUNT] + b[PIO_CFG_SIDESET_OPT]; + pio->SM[sm].PINCTRL = + (sidesetTotal << 29) | (b[PIO_CFG_SET_COUNT] << 26) | (b[PIO_CFG_OUT_COUNT] << 20) | + (b[PIO_CFG_IN_BASE] << 15) | (b[PIO_CFG_SIDESET_BASE] << 10) | (b[PIO_CFG_SET_BASE] << 5) | + b[PIO_CFG_OUT_BASE]; + + // EXECCTRL: wrap [16:12], wrap_target [11:7], side_en [30], side_pindir [29], jmp_pin [28:24] + unsigned int execCtrl = + (b[PIO_CFG_WRAP] << 12) | (b[PIO_CFG_WRAP_TARGET] << 7) | (b[PIO_CFG_JMP_PIN] << 24) | + ((b[PIO_CFG_MOV_STATUS_SEL] & 1u) << 4) | (b[PIO_CFG_MOV_STATUS_N] & 0xFu) | + ((b[PIO_CFG_OUT_STICKY] & 1u) << 17) | ((b[PIO_CFG_INLINE_OUT_EN] & 1u) << 18) | + ((b[PIO_CFG_OUT_EN_SEL] & 0x1Fu) << 19); + if (b[PIO_CFG_SIDESET_OPT]) + { + execCtrl |= (1u << 30); + } + if (b[PIO_CFG_SIDESET_PINDIRS]) + { + execCtrl |= (1u << 29); + } + pio->SM[sm].EXECCTRL = execCtrl; + + // a 32-bit threshold encodes as 0 in the 5-bit field + unsigned int pushThresh = b[PIO_CFG_PUSH_THRESHOLD] & 0x1F; + unsigned int pullThresh = b[PIO_CFG_PULL_THRESHOLD] & 0x1F; + // FJOIN: low 2 bits -> TX [30] / RX [31]; high 2 bits (PIO v1) -> RX_GET [14] / RX_PUT [15] + unsigned int join = b[PIO_CFG_FIFO_JOIN]; + pio->SM[sm].SHIFTCTRL = + (b[PIO_CFG_IN_SHIFT_RIGHT] << 18) | (b[PIO_CFG_OUT_SHIFT_RIGHT] << 19) | + (b[PIO_CFG_AUTOPUSH] << 16) | (b[PIO_CFG_AUTOPULL] << 17) | (pushThresh << 20) | + (pullThresh << 25) | ((join & 3u) << 30) | ((join >> 2) << 14); #if defined(RP2350) - // GPIOBASE is 0 or 16; CMSIS types it __I so write through a volatile pointer - *(volatile unsigned int *)&pio->GPIOBASE = b[PIO_CFG_GPIO_BASE]; + // GPIOBASE is 0 or 16; CMSIS types it __I so write through a volatile pointer + *(volatile unsigned int *)&pio->GPIOBASE = b[PIO_CFG_GPIO_BASE]; #endif - // set PC via JMP (opcode 0) - pio->SM[sm].INSTR = (unsigned int)(param2 & 0x1F); + // set PC via JMP (opcode 0) + pio->SM[sm].INSTR = (unsigned int)(offset & 0x1F); + } + NANOCLR_NOCLEANUP(); } -void PioStateMachine::NativeSetEnabled(signed int param0, signed int param1, bool param2, HRESULT &hr) +HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine:: + NativeSetEnabled___STATIC__VOID__I4__I4__BOOLEAN(CLR_RT_StackFrame &stack) { - PIO_TypeDef *pio = PioFromIndex(param0); - if (pio == nullptr || param1 < 0 || param1 > 3) + NANOCLR_HEADER(); { - hr = CLR_E_INVALID_PARAMETER; - return; + int block = stack.Arg0().NumericByRef().s4; + int sm = stack.Arg1().NumericByRef().s4; + bool enabled = stack.Arg2().NumericByRef().u1; + + PIO_TypeDef *pio = PioFromIndex(block); + if (pio == nullptr || sm < 0 || sm > 3) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + if (enabled) + { + pio->CTRL |= (1u << sm); + } + else + { + pio->CTRL &= ~(1u << sm); + } } + NANOCLR_NOCLEANUP(); +} - if (param2) - { - pio->CTRL |= (1u << param1); - } - else +HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine:: + NativePutBlocking___STATIC__VOID__I4__I4__U4(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); { - pio->CTRL &= ~(1u << param1); + int block = stack.Arg0().NumericByRef().s4; + int sm = stack.Arg1().NumericByRef().s4; + unsigned int value = stack.Arg2().NumericByRef().u4; + + PIO_TypeDef *pio = PioFromIndex(block); + if (pio == nullptr || sm < 0 || sm > 3) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + // FSTAT TX_FULL = bits [19:16] + unsigned int guard = PIO_FIFO_WAIT_LIMIT; + while ((pio->FSTAT & (1u << (16 + sm))) && --guard) + { + } + if (guard == 0) + { + NANOCLR_SET_AND_LEAVE(CLR_E_TIMEOUT); + } + pio->TXF[sm] = value; } + NANOCLR_NOCLEANUP(); } -void PioStateMachine::NativePutBlocking(signed int param0, signed int param1, unsigned int param2, HRESULT &hr) +HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine:: + NativeGetBlocking___STATIC__U4__I4__I4(CLR_RT_StackFrame &stack) { - PIO_TypeDef *pio = PioFromIndex(param0); - if (pio == nullptr || param1 < 0 || param1 > 3) + NANOCLR_HEADER(); { - hr = CLR_E_INVALID_PARAMETER; - return; + int block = stack.Arg0().NumericByRef().s4; + int sm = stack.Arg1().NumericByRef().s4; + + PIO_TypeDef *pio = PioFromIndex(block); + if (pio == nullptr || sm < 0 || sm > 3) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + // FSTAT RX_EMPTY = bits [11:8] + unsigned int guard = PIO_FIFO_WAIT_LIMIT; + while ((pio->FSTAT & (1u << (8 + sm))) && --guard) + { + } + if (guard == 0) + { + NANOCLR_SET_AND_LEAVE(CLR_E_TIMEOUT); + } + stack.SetResult_U4(pio->RXF[sm]); } + NANOCLR_NOCLEANUP(); +} - // FSTAT TX_FULL = bits [19:16] - unsigned int guard = PIO_FIFO_WAIT_LIMIT; - while ((pio->FSTAT & (1u << (16 + param1))) && --guard) - { - } - if (guard == 0) +HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine:: + NativeTxFull___STATIC__BOOLEAN__I4__I4(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); { - hr = CLR_E_TIMEOUT; - return; + int block = stack.Arg0().NumericByRef().s4; + int sm = stack.Arg1().NumericByRef().s4; + + PIO_TypeDef *pio = PioFromIndex(block); + if (pio == nullptr || sm < 0 || sm > 3) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + stack.SetResult_Boolean((pio->FSTAT & (1u << (16 + sm))) != 0); } - pio->TXF[param1] = param2; + NANOCLR_NOCLEANUP(); } -unsigned int PioStateMachine::NativeGetBlocking(signed int param0, signed int param1, HRESULT &hr) +HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine:: + NativeRxEmpty___STATIC__BOOLEAN__I4__I4(CLR_RT_StackFrame &stack) { - PIO_TypeDef *pio = PioFromIndex(param0); - if (pio == nullptr || param1 < 0 || param1 > 3) + NANOCLR_HEADER(); { - hr = CLR_E_INVALID_PARAMETER; - return 0; - } + int block = stack.Arg0().NumericByRef().s4; + int sm = stack.Arg1().NumericByRef().s4; - // FSTAT RX_EMPTY = bits [11:8] - unsigned int guard = PIO_FIFO_WAIT_LIMIT; - while ((pio->FSTAT & (1u << (8 + param1))) && --guard) - { - } - if (guard == 0) - { - hr = CLR_E_TIMEOUT; - return 0; + PIO_TypeDef *pio = PioFromIndex(block); + if (pio == nullptr || sm < 0 || sm > 3) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + stack.SetResult_Boolean((pio->FSTAT & (1u << (8 + sm))) != 0); } - return pio->RXF[param1]; + NANOCLR_NOCLEANUP(); } -bool PioStateMachine::NativeTxFull(signed int param0, signed int param1, HRESULT &hr) +HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine:: + NativeUnclaim___STATIC__VOID__I4__I4(CLR_RT_StackFrame &stack) { - PIO_TypeDef *pio = PioFromIndex(param0); - if (pio == nullptr || param1 < 0 || param1 > 3) + NANOCLR_HEADER(); { - hr = CLR_E_INVALID_PARAMETER; - return false; + int block = stack.Arg0().NumericByRef().s4; + int sm = stack.Arg1().NumericByRef().s4; + + PIO_TypeDef *pio = PioFromIndex(block); + if (pio == nullptr || sm < 0 || sm > 3) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + // stop + release the claim + pio->CTRL &= ~(1u << sm); + g_PioClaimedSm[block] &= ~(1u << sm); } - - return (pio->FSTAT & (1u << (16 + param1))) != 0; + NANOCLR_NOCLEANUP(); } -bool PioStateMachine::NativeRxEmpty(signed int param0, signed int param1, HRESULT &hr) +HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine:: + NativeSetConsecutivePinDirs___STATIC__VOID__I4__I4__I4__I4__BOOLEAN(CLR_RT_StackFrame &stack) { - PIO_TypeDef *pio = PioFromIndex(param0); - if (pio == nullptr || param1 < 0 || param1 > 3) + NANOCLR_HEADER(); { - hr = CLR_E_INVALID_PARAMETER; - return true; + int block = stack.Arg0().NumericByRef().s4; + int sm = stack.Arg1().NumericByRef().s4; + int basePin = stack.Arg2().NumericByRef().s4; + int count = stack.Arg3().NumericByRef().s4; + bool output = stack.Arg4().NumericByRef().u1; + + PIO_TypeDef *pio = PioFromIndex(block); + if (pio == nullptr || sm < 0 || sm > 3) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + // in chunks of up to 5 pins, point SET at them and exec "SET pindirs, dirs", then restore PINCTRL + int pin = basePin; + int remaining = count; + unsigned int savedPinCtrl = pio->SM[sm].PINCTRL; + + while (remaining > 0) + { + int chunk = remaining < 5 ? remaining : 5; + unsigned int dirs = output ? ((1u << chunk) - 1u) : 0u; + + // PINCTRL: SET_COUNT [28:26], SET_BASE [9:5] + pio->SM[sm].PINCTRL = ((unsigned int)chunk << 26) | ((unsigned int)pin << 5); + // SET pindirs, dirs + pio->SM[sm].INSTR = 0xE000u | (4u << 5) | (dirs & 0x1Fu); + + remaining -= chunk; + pin += chunk; + } + + pio->SM[sm].PINCTRL = savedPinCtrl; } - - return (pio->FSTAT & (1u << (8 + param1))) != 0; + NANOCLR_NOCLEANUP(); } -// claim bitmask owned by PioBlock.cpp -extern unsigned int g_PioClaimedSm[3]; - -void PioStateMachine::NativeUnclaim(signed int param0, signed int param1, HRESULT &hr) +HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine:: + NativeClearFifos___STATIC__VOID__I4__I4(CLR_RT_StackFrame &stack) { - PIO_TypeDef *pio = PioFromIndex(param0); - int sm = param1; - if (pio == nullptr || sm < 0 || sm > 3) + NANOCLR_HEADER(); { - hr = CLR_E_INVALID_PARAMETER; - return; + int block = stack.Arg0().NumericByRef().s4; + int sm = stack.Arg1().NumericByRef().s4; + + PIO_TypeDef *pio = PioFromIndex(block); + if (pio == nullptr || sm < 0 || sm > 3) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + // toggle FJOIN_RX (bit 31) twice to flush both FIFOs, SHIFTCTRL unchanged + unsigned int fjoinRx = (1u << 31); + pio->SM[sm].SHIFTCTRL ^= fjoinRx; + pio->SM[sm].SHIFTCTRL ^= fjoinRx; } - - // stop + release the claim - pio->CTRL &= ~(1u << sm); - g_PioClaimedSm[param0] &= ~(1u << sm); + NANOCLR_NOCLEANUP(); } -void PioStateMachine::NativeSetConsecutivePinDirs( - signed int param0, - signed int param1, - signed int param2, - signed int param3, - bool param4, - HRESULT &hr) +HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine:: + NativeDrainTxFifo___STATIC__VOID__I4__I4(CLR_RT_StackFrame &stack) { - PIO_TypeDef *pio = PioFromIndex(param0); - int sm = param1; - if (pio == nullptr || sm < 0 || sm > 3) + NANOCLR_HEADER(); { - hr = CLR_E_INVALID_PARAMETER; - return; + int block = stack.Arg0().NumericByRef().s4; + int sm = stack.Arg1().NumericByRef().s4; + + PIO_TypeDef *pio = PioFromIndex(block); + if (pio == nullptr || sm < 0 || sm > 3) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + // exec OUT NULL,32 (autopull) or PULL noblock until TX empty. FSTAT TX_EMPTY = bits [27:24] + unsigned int autopull = pio->SM[sm].SHIFTCTRL & (1u << 17); + unsigned int instr = autopull ? 0x6060u : 0x8080u; + unsigned int guard = PIO_FIFO_WAIT_LIMIT; + while ((pio->FSTAT & (1u << (24 + sm))) == 0 && --guard) + { + pio->SM[sm].INSTR = instr; + } + if (guard == 0) + { + NANOCLR_SET_AND_LEAVE(CLR_E_TIMEOUT); + } } + NANOCLR_NOCLEANUP(); +} - // in chunks of up to 5 pins, point SET at them and exec "SET pindirs, dirs", then restore PINCTRL - int pin = param2; - int remaining = param3; - unsigned int savedPinCtrl = pio->SM[sm].PINCTRL; - - while (remaining > 0) +HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine:: + NativeRestart___STATIC__VOID__I4__I4(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); { - int chunk = remaining < 5 ? remaining : 5; - unsigned int dirs = param4 ? ((1u << chunk) - 1u) : 0u; + int block = stack.Arg0().NumericByRef().s4; + int sm = stack.Arg1().NumericByRef().s4; - // PINCTRL: SET_COUNT [28:26], SET_BASE [9:5] - pio->SM[sm].PINCTRL = ((unsigned int)chunk << 26) | ((unsigned int)pin << 5); - // SET pindirs, dirs - pio->SM[sm].INSTR = 0xE000u | (4u << 5) | (dirs & 0x1Fu); + PIO_TypeDef *pio = PioFromIndex(block); + if (pio == nullptr || sm < 0 || sm > 3) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } - remaining -= chunk; - pin += chunk; + // SM_RESTART = bits [7:4] + pio->CTRL |= (1u << (4 + sm)); } - - pio->SM[sm].PINCTRL = savedPinCtrl; + NANOCLR_NOCLEANUP(); } -void PioStateMachine::NativeClearFifos(signed int param0, signed int param1, HRESULT &hr) +HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine:: + NativeClkDivRestart___STATIC__VOID__I4__I4(CLR_RT_StackFrame &stack) { - PIO_TypeDef *pio = PioFromIndex(param0); - int sm = param1; - if (pio == nullptr || sm < 0 || sm > 3) + NANOCLR_HEADER(); { - hr = CLR_E_INVALID_PARAMETER; - return; - } + int block = stack.Arg0().NumericByRef().s4; + int sm = stack.Arg1().NumericByRef().s4; - // toggle FJOIN_RX (bit 31) twice to flush both FIFOs, SHIFTCTRL unchanged - unsigned int fjoinRx = (1u << 31); - pio->SM[sm].SHIFTCTRL ^= fjoinRx; - pio->SM[sm].SHIFTCTRL ^= fjoinRx; -} + PIO_TypeDef *pio = PioFromIndex(block); + if (pio == nullptr || sm < 0 || sm > 3) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } -void PioStateMachine::NativeDrainTxFifo(signed int param0, signed int param1, HRESULT &hr) -{ - PIO_TypeDef *pio = PioFromIndex(param0); - int sm = param1; - if (pio == nullptr || sm < 0 || sm > 3) - { - hr = CLR_E_INVALID_PARAMETER; - return; - } - - // exec OUT NULL,32 (autopull) or PULL noblock until TX empty. FSTAT TX_EMPTY = bits [27:24] - unsigned int autopull = pio->SM[sm].SHIFTCTRL & (1u << 17); - unsigned int instr = autopull ? 0x6060u : 0x8080u; - unsigned int guard = PIO_FIFO_WAIT_LIMIT; - while ((pio->FSTAT & (1u << (24 + sm))) == 0 && --guard) - { - pio->SM[sm].INSTR = instr; - } - if (guard == 0) - { - hr = CLR_E_TIMEOUT; + // CLKDIV_RESTART = bits [11:8] + pio->CTRL |= (1u << (8 + sm)); } + NANOCLR_NOCLEANUP(); } -void PioStateMachine::NativeRestart(signed int param0, signed int param1, HRESULT &hr) +HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine:: + NativeExec___STATIC__VOID__I4__I4__U2(CLR_RT_StackFrame &stack) { - PIO_TypeDef *pio = PioFromIndex(param0); - int sm = param1; - if (pio == nullptr || sm < 0 || sm > 3) + NANOCLR_HEADER(); { - hr = CLR_E_INVALID_PARAMETER; - return; + int block = stack.Arg0().NumericByRef().s4; + int sm = stack.Arg1().NumericByRef().s4; + unsigned short instruction = stack.Arg2().NumericByRef().u2; + + PIO_TypeDef *pio = PioFromIndex(block); + if (pio == nullptr || sm < 0 || sm > 3) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + // exec out of band, PC unchanged + pio->SM[sm].INSTR = (unsigned int)instruction; } - - // SM_RESTART = bits [7:4] - pio->CTRL |= (1u << (4 + sm)); + NANOCLR_NOCLEANUP(); } -void PioStateMachine::NativeClkDivRestart(signed int param0, signed int param1, HRESULT &hr) +HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine:: + NativeTxLevel___STATIC__U4__I4__I4(CLR_RT_StackFrame &stack) { - PIO_TypeDef *pio = PioFromIndex(param0); - int sm = param1; - if (pio == nullptr || sm < 0 || sm > 3) + NANOCLR_HEADER(); { - hr = CLR_E_INVALID_PARAMETER; - return; - } + int block = stack.Arg0().NumericByRef().s4; + int sm = stack.Arg1().NumericByRef().s4; - // CLKDIV_RESTART = bits [11:8] - pio->CTRL |= (1u << (8 + sm)); -} + PIO_TypeDef *pio = PioFromIndex(block); + if (pio == nullptr || sm < 0 || sm > 3) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } -void PioStateMachine::NativeExec(signed int param0, signed int param1, unsigned short param2, HRESULT &hr) -{ - PIO_TypeDef *pio = PioFromIndex(param0); - int sm = param1; - if (pio == nullptr || sm < 0 || sm > 3) - { - hr = CLR_E_INVALID_PARAMETER; - return; + stack.SetResult_U4((pio->FLEVEL >> (8 * sm)) & 0xFu); } - - // exec out of band, PC unchanged - pio->SM[sm].INSTR = (unsigned int)param2; + NANOCLR_NOCLEANUP(); } -unsigned int PioStateMachine::NativeTxLevel(signed int param0, signed int param1, HRESULT &hr) +HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine:: + NativeRxLevel___STATIC__U4__I4__I4(CLR_RT_StackFrame &stack) { - PIO_TypeDef *pio = PioFromIndex(param0); - int sm = param1; - if (pio == nullptr || sm < 0 || sm > 3) + NANOCLR_HEADER(); { - hr = CLR_E_INVALID_PARAMETER; - return 0; - } + int block = stack.Arg0().NumericByRef().s4; + int sm = stack.Arg1().NumericByRef().s4; - return (pio->FLEVEL >> (8 * sm)) & 0xFu; -} + PIO_TypeDef *pio = PioFromIndex(block); + if (pio == nullptr || sm < 0 || sm > 3) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } -unsigned int PioStateMachine::NativeRxLevel(signed int param0, signed int param1, HRESULT &hr) -{ - PIO_TypeDef *pio = PioFromIndex(param0); - int sm = param1; - if (pio == nullptr || sm < 0 || sm > 3) - { - hr = CLR_E_INVALID_PARAMETER; - return 0; + stack.SetResult_U4((pio->FLEVEL >> (8 * sm + 4)) & 0xFu); } - - return (pio->FLEVEL >> (8 * sm + 4)) & 0xFu; + NANOCLR_NOCLEANUP(); } -unsigned int PioStateMachine::NativeGetPc(signed int param0, signed int param1, HRESULT &hr) +HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine:: + NativeGetPc___STATIC__U4__I4__I4(CLR_RT_StackFrame &stack) { - PIO_TypeDef *pio = PioFromIndex(param0); - int sm = param1; - if (pio == nullptr || sm < 0 || sm > 3) + NANOCLR_HEADER(); { - hr = CLR_E_INVALID_PARAMETER; - return 0; - } + int block = stack.Arg0().NumericByRef().s4; + int sm = stack.Arg1().NumericByRef().s4; - return pio->SM[sm].ADDR & 0x1Fu; + PIO_TypeDef *pio = PioFromIndex(block); + if (pio == nullptr || sm < 0 || sm > 3) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + stack.SetResult_U4(pio->SM[sm].ADDR & 0x1Fu); + } + NANOCLR_NOCLEANUP(); } -void PioStateMachine::NativeSetClockDivisor( - signed int param0, - signed int param1, - signed int param2, - signed int param3, - HRESULT &hr) +HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine:: + NativeSetClockDivisor___STATIC__VOID__I4__I4__I4__I4(CLR_RT_StackFrame &stack) { - PIO_TypeDef *pio = PioFromIndex(param0); - int sm = param1; - if (pio == nullptr || sm < 0 || sm > 3) + NANOCLR_HEADER(); { - hr = CLR_E_INVALID_PARAMETER; - return; + int block = stack.Arg0().NumericByRef().s4; + int sm = stack.Arg1().NumericByRef().s4; + int clkDivInt = stack.Arg2().NumericByRef().s4; + int clkDivFrac = stack.Arg3().NumericByRef().s4; + + PIO_TypeDef *pio = PioFromIndex(block); + if (pio == nullptr || sm < 0 || sm > 3) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + pio->SM[sm].CLKDIV = ((unsigned int)clkDivInt << 16) | ((unsigned int)clkDivFrac << 8); + pio->CTRL |= (1u << (8 + sm)); } - - pio->SM[sm].CLKDIV = ((unsigned int)param2 << 16) | ((unsigned int)param3 << 8); - pio->CTRL |= (1u << (8 + sm)); + NANOCLR_NOCLEANUP(); } diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.h b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.h deleted file mode 100644 index ec7031b308..0000000000 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.h +++ /dev/null @@ -1,56 +0,0 @@ -// -// Copyright (c) .NET Foundation and Contributors -// See LICENSE file in the project root for full license information. -// - -#ifndef NANOFRAMEWORK_HARDWARE_RPI_NANOFRAMEWORK_HARDWARE_RPI_NANOFRAMEWORK_HARDWARE_RPI_PIO_PIOSTATEMACHINE_H -#define NANOFRAMEWORK_HARDWARE_RPI_NANOFRAMEWORK_HARDWARE_RPI_NANOFRAMEWORK_HARDWARE_RPI_PIO_PIOSTATEMACHINE_H - -namespace nf_hardware_rpi_native -{ - namespace nanoFramework_Hardware_Rpi - { - struct PioStateMachine - { - // Helper Functions to access fields of managed object - // Declaration of stubs. These functions are implemented by Interop code developers - - static void NativeInit( signed int param0, signed int param1, signed int param2, CLR_RT_TypedArray_UINT32 param3, HRESULT &hr ); - - static void NativeSetEnabled( signed int param0, signed int param1, bool param2, HRESULT &hr ); - - static void NativePutBlocking( signed int param0, signed int param1, unsigned int param2, HRESULT &hr ); - - static unsigned int NativeGetBlocking( signed int param0, signed int param1, HRESULT &hr ); - - static bool NativeTxFull( signed int param0, signed int param1, HRESULT &hr ); - - static bool NativeRxEmpty( signed int param0, signed int param1, HRESULT &hr ); - - static void NativeUnclaim( signed int param0, signed int param1, HRESULT &hr ); - - static void NativeSetConsecutivePinDirs( signed int param0, signed int param1, signed int param2, signed int param3, bool param4, HRESULT &hr ); - - static void NativeClearFifos( signed int param0, signed int param1, HRESULT &hr ); - - static void NativeDrainTxFifo( signed int param0, signed int param1, HRESULT &hr ); - - static void NativeRestart( signed int param0, signed int param1, HRESULT &hr ); - - static void NativeClkDivRestart( signed int param0, signed int param1, HRESULT &hr ); - - static void NativeExec( signed int param0, signed int param1, uint16_t param2, HRESULT &hr ); - - static unsigned int NativeTxLevel( signed int param0, signed int param1, HRESULT &hr ); - - static unsigned int NativeRxLevel( signed int param0, signed int param1, HRESULT &hr ); - - static unsigned int NativeGetPc( signed int param0, signed int param1, HRESULT &hr ); - - static void NativeSetClockDivisor( signed int param0, signed int param1, signed int param2, signed int param3, HRESULT &hr ); - - }; - } -} - -#endif // NANOFRAMEWORK_HARDWARE_RPI_NANOFRAMEWORK_HARDWARE_RPI_NANOFRAMEWORK_HARDWARE_RPI_PIO_PIOSTATEMACHINE_H diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine_mshl.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine_mshl.cpp deleted file mode 100644 index faf9a900ea..0000000000 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine_mshl.cpp +++ /dev/null @@ -1,346 +0,0 @@ -// -// Copyright (c) .NET Foundation and Contributors -// See LICENSE file in the project root for full license information. -// - -#include "nf_hardware_rpi_native.h" -#include "nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.h" - -using namespace nf_hardware_rpi_native::nanoFramework_Hardware_Rpi; - - -HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeInit___STATIC__VOID__I4__I4__I4__SZARRAY_U4( CLR_RT_StackFrame& stack ) -{ - NANOCLR_HEADER(); hr = S_OK; - { - - signed int param0; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 0, param0 ) ); - - signed int param1; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 1, param1 ) ); - - signed int param2; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 2, param2 ) ); - - CLR_RT_TypedArray_UINT32 param3; - NANOCLR_CHECK_HRESULT( Interop_Marshal_UINT32_ARRAY( stack, 3, param3 ) ); - - PioStateMachine::NativeInit( param0, param1, param2, param3, hr ); - NANOCLR_CHECK_HRESULT( hr ); - - } - NANOCLR_NOCLEANUP(); -} - -HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeSetEnabled___STATIC__VOID__I4__I4__BOOLEAN( CLR_RT_StackFrame& stack ) -{ - NANOCLR_HEADER(); hr = S_OK; - { - - signed int param0; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 0, param0 ) ); - - signed int param1; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 1, param1 ) ); - - bool param2; - NANOCLR_CHECK_HRESULT( Interop_Marshal_bool( stack, 2, param2 ) ); - - PioStateMachine::NativeSetEnabled( param0, param1, param2, hr ); - NANOCLR_CHECK_HRESULT( hr ); - - } - NANOCLR_NOCLEANUP(); -} - -HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativePutBlocking___STATIC__VOID__I4__I4__U4( CLR_RT_StackFrame& stack ) -{ - NANOCLR_HEADER(); hr = S_OK; - { - - signed int param0; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 0, param0 ) ); - - signed int param1; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 1, param1 ) ); - - unsigned int param2; - NANOCLR_CHECK_HRESULT( Interop_Marshal_UINT32( stack, 2, param2 ) ); - - PioStateMachine::NativePutBlocking( param0, param1, param2, hr ); - NANOCLR_CHECK_HRESULT( hr ); - - } - NANOCLR_NOCLEANUP(); -} - -HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeGetBlocking___STATIC__U4__I4__I4( CLR_RT_StackFrame& stack ) -{ - NANOCLR_HEADER(); hr = S_OK; - { - - signed int param0; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 0, param0 ) ); - - signed int param1; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 1, param1 ) ); - - unsigned int retValue = PioStateMachine::NativeGetBlocking( param0, param1, hr ); - NANOCLR_CHECK_HRESULT( hr ); - SetResult_UINT32( stack, retValue ); - } - NANOCLR_NOCLEANUP(); -} - -HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeTxFull___STATIC__BOOLEAN__I4__I4( CLR_RT_StackFrame& stack ) -{ - NANOCLR_HEADER(); hr = S_OK; - { - - signed int param0; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 0, param0 ) ); - - signed int param1; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 1, param1 ) ); - - bool retValue = PioStateMachine::NativeTxFull( param0, param1, hr ); - NANOCLR_CHECK_HRESULT( hr ); - SetResult_bool( stack, retValue ); - } - NANOCLR_NOCLEANUP(); -} - -HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeRxEmpty___STATIC__BOOLEAN__I4__I4( CLR_RT_StackFrame& stack ) -{ - NANOCLR_HEADER(); hr = S_OK; - { - - signed int param0; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 0, param0 ) ); - - signed int param1; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 1, param1 ) ); - - bool retValue = PioStateMachine::NativeRxEmpty( param0, param1, hr ); - NANOCLR_CHECK_HRESULT( hr ); - SetResult_bool( stack, retValue ); - } - NANOCLR_NOCLEANUP(); -} - -HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeUnclaim___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) -{ - NANOCLR_HEADER(); hr = S_OK; - { - - signed int param0; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 0, param0 ) ); - - signed int param1; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 1, param1 ) ); - - PioStateMachine::NativeUnclaim( param0, param1, hr ); - NANOCLR_CHECK_HRESULT( hr ); - - } - NANOCLR_NOCLEANUP(); -} - -HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeSetConsecutivePinDirs___STATIC__VOID__I4__I4__I4__I4__BOOLEAN( CLR_RT_StackFrame& stack ) -{ - NANOCLR_HEADER(); hr = S_OK; - { - - signed int param0; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 0, param0 ) ); - - signed int param1; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 1, param1 ) ); - - signed int param2; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 2, param2 ) ); - - signed int param3; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 3, param3 ) ); - - bool param4; - NANOCLR_CHECK_HRESULT( Interop_Marshal_bool( stack, 4, param4 ) ); - - PioStateMachine::NativeSetConsecutivePinDirs( param0, param1, param2, param3, param4, hr ); - NANOCLR_CHECK_HRESULT( hr ); - - } - NANOCLR_NOCLEANUP(); -} - -HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeClearFifos___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) -{ - NANOCLR_HEADER(); hr = S_OK; - { - - signed int param0; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 0, param0 ) ); - - signed int param1; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 1, param1 ) ); - - PioStateMachine::NativeClearFifos( param0, param1, hr ); - NANOCLR_CHECK_HRESULT( hr ); - - } - NANOCLR_NOCLEANUP(); -} - -HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeDrainTxFifo___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) -{ - NANOCLR_HEADER(); hr = S_OK; - { - - signed int param0; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 0, param0 ) ); - - signed int param1; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 1, param1 ) ); - - PioStateMachine::NativeDrainTxFifo( param0, param1, hr ); - NANOCLR_CHECK_HRESULT( hr ); - - } - NANOCLR_NOCLEANUP(); -} - -HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeRestart___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) -{ - NANOCLR_HEADER(); hr = S_OK; - { - - signed int param0; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 0, param0 ) ); - - signed int param1; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 1, param1 ) ); - - PioStateMachine::NativeRestart( param0, param1, hr ); - NANOCLR_CHECK_HRESULT( hr ); - - } - NANOCLR_NOCLEANUP(); -} - -HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeClkDivRestart___STATIC__VOID__I4__I4( CLR_RT_StackFrame& stack ) -{ - NANOCLR_HEADER(); hr = S_OK; - { - - signed int param0; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 0, param0 ) ); - - signed int param1; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 1, param1 ) ); - - PioStateMachine::NativeClkDivRestart( param0, param1, hr ); - NANOCLR_CHECK_HRESULT( hr ); - - } - NANOCLR_NOCLEANUP(); -} - -HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeExec___STATIC__VOID__I4__I4__U2( CLR_RT_StackFrame& stack ) -{ - NANOCLR_HEADER(); hr = S_OK; - { - - signed int param0; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 0, param0 ) ); - - signed int param1; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 1, param1 ) ); - - uint16_t param2; - NANOCLR_CHECK_HRESULT( Interop_Marshal_UINT16( stack, 2, param2 ) ); - - PioStateMachine::NativeExec( param0, param1, param2, hr ); - NANOCLR_CHECK_HRESULT( hr ); - - } - NANOCLR_NOCLEANUP(); -} - -HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeTxLevel___STATIC__U4__I4__I4( CLR_RT_StackFrame& stack ) -{ - NANOCLR_HEADER(); hr = S_OK; - { - - signed int param0; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 0, param0 ) ); - - signed int param1; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 1, param1 ) ); - - unsigned int retValue = PioStateMachine::NativeTxLevel( param0, param1, hr ); - NANOCLR_CHECK_HRESULT( hr ); - SetResult_UINT32( stack, retValue ); - } - NANOCLR_NOCLEANUP(); -} - -HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeRxLevel___STATIC__U4__I4__I4( CLR_RT_StackFrame& stack ) -{ - NANOCLR_HEADER(); hr = S_OK; - { - - signed int param0; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 0, param0 ) ); - - signed int param1; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 1, param1 ) ); - - unsigned int retValue = PioStateMachine::NativeRxLevel( param0, param1, hr ); - NANOCLR_CHECK_HRESULT( hr ); - SetResult_UINT32( stack, retValue ); - } - NANOCLR_NOCLEANUP(); -} - -HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeGetPc___STATIC__U4__I4__I4( CLR_RT_StackFrame& stack ) -{ - NANOCLR_HEADER(); hr = S_OK; - { - - signed int param0; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 0, param0 ) ); - - signed int param1; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 1, param1 ) ); - - unsigned int retValue = PioStateMachine::NativeGetPc( param0, param1, hr ); - NANOCLR_CHECK_HRESULT( hr ); - SetResult_UINT32( stack, retValue ); - } - NANOCLR_NOCLEANUP(); -} - -HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeSetClockDivisor___STATIC__VOID__I4__I4__I4__I4( CLR_RT_StackFrame& stack ) -{ - NANOCLR_HEADER(); hr = S_OK; - { - - signed int param0; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 0, param0 ) ); - - signed int param1; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 1, param1 ) ); - - signed int param2; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 2, param2 ) ); - - signed int param3; - NANOCLR_CHECK_HRESULT( Interop_Marshal_INT32( stack, 3, param3 ) ); - - PioStateMachine::NativeSetClockDivisor( param0, param1, param2, param3, hr ); - NANOCLR_CHECK_HRESULT( hr ); - - } - NANOCLR_NOCLEANUP(); -} From 3565d251b223e599384d77774da9ca0588b03f6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Fri, 26 Jun 2026 09:24:54 -0600 Subject: [PATCH 16/58] PIO: harden native input validation and decouple the PIO reset release Address review feedback on the native interop: - validate the instruction buffer length in AddProgram before reading it - release each PIO block from reset on first use of any entry point, not only on program load (idempotent), instead of coupling it to AddProgram - mask the config-blob fields to their register widths so a malformed blob can't spill into adjacent fields - range-check the pin window in SetConsecutivePinDirs and the clock divisor - reject a second IRQ dispatcher for the same block, and return NOT_SUPPORTED for IRQ enable on Pico W where PIO IRQ0 belongs to the CYW43 driver --- .../nf_hardware_rpi_native_PioIrqDriver.cpp | 9 ++- ...anoFramework_Hardware_Rpi_Pio_PioBlock.cpp | 55 +++++++++------- ...ework_Hardware_Rpi_Pio_PioStateMachine.cpp | 66 +++++++++++++------ .../nf_hardware_rpi_native_target.h | 4 ++ 4 files changed, 91 insertions(+), 43 deletions(-) diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_PioIrqDriver.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_PioIrqDriver.cpp index b45a1f8264..2eeaacac5a 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_PioIrqDriver.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_PioIrqDriver.cpp @@ -95,6 +95,12 @@ static HRESULT PioIrqInitialize(CLR_RT_HeapBlock_NativeEventDispatcher *pContext return CLR_E_INVALID_PARAMETER; } + // one dispatcher per block + if (s_pioCtx[block] != nullptr && s_pioCtx[block] != pContext) + { + return CLR_E_INVALID_OPERATION; + } + s_pioCtx[block] = pContext; return S_OK; } @@ -121,8 +127,9 @@ static HRESULT PioIrqEnableDisable(CLR_RT_HeapBlock_NativeEventDispatcher *pCont nvicDisableVector(vector); } #else + // PIO IRQ0 is owned by the CYW43 driver on Pico W, so it can't reach managed code (void)fEnable; - (void)pio; + return CLR_E_NOT_SUPPORTED; #endif return S_OK; diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock.cpp index 4b0b9529bb..a8f45af244 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock.cpp @@ -35,14 +35,24 @@ static unsigned int PioSlotMask(int offset, int length) #define PADS_BANK0_RESET_BIT (1u << 8) #endif -static void PioEnsureOutOfReset(int blockIndex) +// PIO boots held in reset; release each block once, on first use of any entry point +static unsigned int g_PioOutOfReset = 0; + +void PioEnsureOutOfReset(int blockIndex) { + if (g_PioOutOfReset & (1u << blockIndex)) + { + return; + } + unsigned int bits = (1u << (PIO_RESET_LSB + (unsigned int)blockIndex)) | IO_BANK0_RESET_BIT | PADS_BANK0_RESET_BIT; - RESETS->CLR.RESET = bits; + RESETS->CLR.RESET = bits; // atomic-clear alias while ((RESETS->RESET_DONE & bits) != bits) { } + + g_PioOutOfReset |= (1u << blockIndex); } HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock:: @@ -51,39 +61,37 @@ HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock:: NANOCLR_HEADER(); { int block = stack.Arg0().NumericByRef().s4; - unsigned short *instr = (unsigned short *)stack.Arg1().DereferenceArray()->GetFirstElement(); + CLR_RT_HeapBlock_Array *instrArray = stack.Arg1().DereferenceArray(); int length = stack.Arg2().NumericByRef().s4; int origin = stack.Arg3().NumericByRef().s4; - PIO_TypeDef *pio = PioFromIndex(block); - if (pio == nullptr || block < 0 || block > 2) + if (PioFromIndex(block) == nullptr || block < 0 || block > 2 || instrArray == nullptr || + length <= 0 || length > 32 || (int)instrArray->m_numOfElements < length) { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } - // first PIO call in any flow, so un-reset here + PIO_TypeDef *pio = PioFromIndex(block); + unsigned short *instr = (unsigned short *)instrArray->GetFirstElement(); PioEnsureOutOfReset(block); int offset = -1; - if (length > 0 && length <= 32) + // fixed origin: exact slots; relocatable: first-fit + if (origin >= 0) { - // fixed origin needs its exact slots free; relocatable takes the lowest free run (first-fit) - if (origin >= 0) + if (origin + length <= 32 && (g_PioInstrUsed[block] & PioSlotMask(origin, length)) == 0) { - if (origin + length <= 32 && (g_PioInstrUsed[block] & PioSlotMask(origin, length)) == 0) - { - offset = origin; - } + offset = origin; } - else + } + else + { + for (int candidate = 0; candidate + length <= 32; candidate++) { - for (int candidate = 0; candidate + length <= 32; candidate++) + if ((g_PioInstrUsed[block] & PioSlotMask(candidate, length)) == 0) { - if ((g_PioInstrUsed[block] & PioSlotMask(candidate, length)) == 0) - { - offset = candidate; - break; - } + offset = candidate; + break; } } } @@ -124,6 +132,7 @@ HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock:: { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } + PioEnsureOutOfReset(block); // reclaim slots, blank to JMP-to-self so a stray enable can't run stale opcodes for (int i = 0; i < length; i++) @@ -144,8 +153,7 @@ HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock:: int block = stack.Arg0().NumericByRef().s4; bool required = stack.Arg1().NumericByRef().u1; - PIO_TypeDef *pio = PioFromIndex(block); - if (pio == nullptr) + if (PioFromIndex(block) == nullptr) { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } @@ -188,6 +196,7 @@ HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock:: { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } + PioEnsureOutOfReset(block); // FUNCSEL = 6 (PIO0), 7 (PIO1), 8 (PIO2) IO_BANK0->GPIO[pin].CTRL = 6u + (unsigned int)block; @@ -210,6 +219,7 @@ HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock:: { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } + PioEnsureOutOfReset(block); pio->IRQ_FORCE = (1u << irq); } @@ -229,6 +239,7 @@ HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock:: { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } + PioEnsureOutOfReset(block); pio->IRQ = (1u << irq); } diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.cpp index da8f205bae..9339c89fa3 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.cpp @@ -11,7 +11,7 @@ #endif #include "nf_hardware_rpi_native_target.h" -// FIFO busy-wait cap so a stalled SM times out instead of hanging the interpreter. +// busy-wait cap so a stalled SM times out instead of hanging static const unsigned int PIO_FIFO_WAIT_LIMIT = 0x4000000u; // blob indices, must match PioStateMachineConfig.cs @@ -59,34 +59,38 @@ HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMa int sm = stack.Arg1().NumericByRef().s4; int offset = stack.Arg2().NumericByRef().s4; CLR_RT_HeapBlock_Array *blobArray = stack.Arg3().DereferenceArray(); - unsigned int *b = (unsigned int *)blobArray->GetFirstElement(); PIO_TypeDef *pio = PioFromIndex(block); - if (pio == nullptr || sm < 0 || sm > 3 || (int)blobArray->m_numOfElements < PIO_CFG_BLOB_LENGTH) + if (pio == nullptr || sm < 0 || sm > 3 || blobArray == nullptr || + (int)blobArray->m_numOfElements < PIO_CFG_BLOB_LENGTH) { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } + PioEnsureOutOfReset(block); + + unsigned int *b = (unsigned int *)blobArray->GetFirstElement(); // disable + restart before reconfigure pio->CTRL &= ~(1u << sm); pio->CTRL |= (1u << (4 + sm)); // SM_RESTART // CLKDIV: int [31:16], frac [15:8] - pio->SM[sm].CLKDIV = (b[PIO_CFG_CLKDIV_INT] << 16) | (b[PIO_CFG_CLKDIV_FRAC] << 8); + pio->SM[sm].CLKDIV = ((b[PIO_CFG_CLKDIV_INT] & 0xFFFFu) << 16) | ((b[PIO_CFG_CLKDIV_FRAC] & 0xFFu) << 8); - // side-set count includes the optional enable bit + // side-set count includes the opt enable bit; each field masked to its width unsigned int sidesetTotal = b[PIO_CFG_SIDESET_COUNT] + b[PIO_CFG_SIDESET_OPT]; pio->SM[sm].PINCTRL = - (sidesetTotal << 29) | (b[PIO_CFG_SET_COUNT] << 26) | (b[PIO_CFG_OUT_COUNT] << 20) | - (b[PIO_CFG_IN_BASE] << 15) | (b[PIO_CFG_SIDESET_BASE] << 10) | (b[PIO_CFG_SET_BASE] << 5) | - b[PIO_CFG_OUT_BASE]; + ((sidesetTotal & 0x7u) << 29) | ((b[PIO_CFG_SET_COUNT] & 0x7u) << 26) | + ((b[PIO_CFG_OUT_COUNT] & 0x3Fu) << 20) | ((b[PIO_CFG_IN_BASE] & 0x1Fu) << 15) | + ((b[PIO_CFG_SIDESET_BASE] & 0x1Fu) << 10) | ((b[PIO_CFG_SET_BASE] & 0x1Fu) << 5) | + (b[PIO_CFG_OUT_BASE] & 0x1Fu); // EXECCTRL: wrap [16:12], wrap_target [11:7], side_en [30], side_pindir [29], jmp_pin [28:24] unsigned int execCtrl = - (b[PIO_CFG_WRAP] << 12) | (b[PIO_CFG_WRAP_TARGET] << 7) | (b[PIO_CFG_JMP_PIN] << 24) | - ((b[PIO_CFG_MOV_STATUS_SEL] & 1u) << 4) | (b[PIO_CFG_MOV_STATUS_N] & 0xFu) | - ((b[PIO_CFG_OUT_STICKY] & 1u) << 17) | ((b[PIO_CFG_INLINE_OUT_EN] & 1u) << 18) | - ((b[PIO_CFG_OUT_EN_SEL] & 0x1Fu) << 19); + ((b[PIO_CFG_WRAP] & 0x1Fu) << 12) | ((b[PIO_CFG_WRAP_TARGET] & 0x1Fu) << 7) | + ((b[PIO_CFG_JMP_PIN] & 0x1Fu) << 24) | ((b[PIO_CFG_MOV_STATUS_SEL] & 1u) << 4) | + (b[PIO_CFG_MOV_STATUS_N] & 0xFu) | ((b[PIO_CFG_OUT_STICKY] & 1u) << 17) | + ((b[PIO_CFG_INLINE_OUT_EN] & 1u) << 18) | ((b[PIO_CFG_OUT_EN_SEL] & 0x1Fu) << 19); if (b[PIO_CFG_SIDESET_OPT]) { execCtrl |= (1u << 30); @@ -103,13 +107,13 @@ HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMa // FJOIN: low 2 bits -> TX [30] / RX [31]; high 2 bits (PIO v1) -> RX_GET [14] / RX_PUT [15] unsigned int join = b[PIO_CFG_FIFO_JOIN]; pio->SM[sm].SHIFTCTRL = - (b[PIO_CFG_IN_SHIFT_RIGHT] << 18) | (b[PIO_CFG_OUT_SHIFT_RIGHT] << 19) | - (b[PIO_CFG_AUTOPUSH] << 16) | (b[PIO_CFG_AUTOPULL] << 17) | (pushThresh << 20) | - (pullThresh << 25) | ((join & 3u) << 30) | ((join >> 2) << 14); + ((b[PIO_CFG_IN_SHIFT_RIGHT] & 1u) << 18) | ((b[PIO_CFG_OUT_SHIFT_RIGHT] & 1u) << 19) | + ((b[PIO_CFG_AUTOPUSH] & 1u) << 16) | ((b[PIO_CFG_AUTOPULL] & 1u) << 17) | (pushThresh << 20) | + (pullThresh << 25) | ((join & 3u) << 30) | (((join >> 2) & 3u) << 14); #if defined(RP2350) // GPIOBASE is 0 or 16; CMSIS types it __I so write through a volatile pointer - *(volatile unsigned int *)&pio->GPIOBASE = b[PIO_CFG_GPIO_BASE]; + *(volatile unsigned int *)&pio->GPIOBASE = (b[PIO_CFG_GPIO_BASE] == 16) ? 16u : 0u; #endif // set PC via JMP (opcode 0) @@ -132,6 +136,7 @@ HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMa { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } + PioEnsureOutOfReset(block); if (enabled) { @@ -159,6 +164,7 @@ HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMa { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } + PioEnsureOutOfReset(block); // FSTAT TX_FULL = bits [19:16] unsigned int guard = PIO_FIFO_WAIT_LIMIT; @@ -187,6 +193,7 @@ HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMa { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } + PioEnsureOutOfReset(block); // FSTAT RX_EMPTY = bits [11:8] unsigned int guard = PIO_FIFO_WAIT_LIMIT; @@ -215,6 +222,7 @@ HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMa { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } + PioEnsureOutOfReset(block); stack.SetResult_Boolean((pio->FSTAT & (1u << (16 + sm))) != 0); } @@ -234,6 +242,7 @@ HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMa { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } + PioEnsureOutOfReset(block); stack.SetResult_Boolean((pio->FSTAT & (1u << (8 + sm))) != 0); } @@ -253,6 +262,7 @@ HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMa { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } + PioEnsureOutOfReset(block); // stop + release the claim pio->CTRL &= ~(1u << sm); @@ -273,12 +283,17 @@ HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMa bool output = stack.Arg4().NumericByRef().u1; PIO_TypeDef *pio = PioFromIndex(block); - if (pio == nullptr || sm < 0 || sm > 3) +#if defined(RP2350) + if (pio == nullptr || sm < 0 || sm > 3 || basePin < 0 || count < 0 || basePin + count > 48) +#else + if (pio == nullptr || sm < 0 || sm > 3 || basePin < 0 || count < 0 || basePin + count > 30) +#endif { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } + PioEnsureOutOfReset(block); - // in chunks of up to 5 pins, point SET at them and exec "SET pindirs, dirs", then restore PINCTRL + // up to 5 pins per "SET pindirs" exec, then restore PINCTRL int pin = basePin; int remaining = count; unsigned int savedPinCtrl = pio->SM[sm].PINCTRL; @@ -289,7 +304,7 @@ HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMa unsigned int dirs = output ? ((1u << chunk) - 1u) : 0u; // PINCTRL: SET_COUNT [28:26], SET_BASE [9:5] - pio->SM[sm].PINCTRL = ((unsigned int)chunk << 26) | ((unsigned int)pin << 5); + pio->SM[sm].PINCTRL = ((unsigned int)chunk << 26) | (((unsigned int)pin & 0x1Fu) << 5); // SET pindirs, dirs pio->SM[sm].INSTR = 0xE000u | (4u << 5) | (dirs & 0x1Fu); @@ -315,6 +330,7 @@ HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMa { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } + PioEnsureOutOfReset(block); // toggle FJOIN_RX (bit 31) twice to flush both FIFOs, SHIFTCTRL unchanged unsigned int fjoinRx = (1u << 31); @@ -337,6 +353,7 @@ HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMa { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } + PioEnsureOutOfReset(block); // exec OUT NULL,32 (autopull) or PULL noblock until TX empty. FSTAT TX_EMPTY = bits [27:24] unsigned int autopull = pio->SM[sm].SHIFTCTRL & (1u << 17); @@ -367,6 +384,7 @@ HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMa { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } + PioEnsureOutOfReset(block); // SM_RESTART = bits [7:4] pio->CTRL |= (1u << (4 + sm)); @@ -387,6 +405,7 @@ HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMa { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } + PioEnsureOutOfReset(block); // CLKDIV_RESTART = bits [11:8] pio->CTRL |= (1u << (8 + sm)); @@ -408,6 +427,7 @@ HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMa { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } + PioEnsureOutOfReset(block); // exec out of band, PC unchanged pio->SM[sm].INSTR = (unsigned int)instruction; @@ -428,6 +448,7 @@ HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMa { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } + PioEnsureOutOfReset(block); stack.SetResult_U4((pio->FLEVEL >> (8 * sm)) & 0xFu); } @@ -447,6 +468,7 @@ HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMa { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } + PioEnsureOutOfReset(block); stack.SetResult_U4((pio->FLEVEL >> (8 * sm + 4)) & 0xFu); } @@ -466,6 +488,7 @@ HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMa { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } + PioEnsureOutOfReset(block); stack.SetResult_U4(pio->SM[sm].ADDR & 0x1Fu); } @@ -483,10 +506,13 @@ HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMa int clkDivFrac = stack.Arg3().NumericByRef().s4; PIO_TypeDef *pio = PioFromIndex(block); - if (pio == nullptr || sm < 0 || sm > 3) + // 16-bit int + 8-bit frac fields + if (pio == nullptr || sm < 0 || sm > 3 || clkDivInt < 0 || clkDivInt > 0xFFFF || clkDivFrac < 0 || + clkDivFrac > 0xFF) { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } + PioEnsureOutOfReset(block); pio->SM[sm].CLKDIV = ((unsigned int)clkDivInt << 16) | ((unsigned int)clkDivFrac << 8); pio->CTRL |= (1u << (8 + sm)); diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_target.h b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_target.h index e871ab9aa1..8683f857aa 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_target.h +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_target.h @@ -25,4 +25,8 @@ static inline PIO_TypeDef *PioFromIndex(int index) } } +// Releases a PIO block (and the IO/PAD banks) from reset on first use; idempotent. Defined in +// the PioBlock translation unit so the reset state is shared across all entry points. +void PioEnsureOutOfReset(int blockIndex); + #endif // NF_HARDWARE_RPI_NATIVE_TARGET_H From ec7f42bee4fefce7b7b56ebb942eee18affd3045 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Fri, 26 Jun 2026 10:46:32 -0600 Subject: [PATCH 17/58] Rename the native assembly to nanoFramework.Hardware.Pico The managed library was renamed nanoFramework.Hardware.Rpi -> nanoFramework.Hardware.Pico; rename the native interop to match (files, symbols, include guards, assembly name and native checksum 0x7733E84B). Same core-library form and PIO functionality. --- .../nanoFramework_hardware_pico_native.cpp | 206 ++++++ .../nanoFramework_hardware_pico_native.h} | 614 +----------------- ...ork_hardware_pico_native_PioIrqDriver.cpp} | 6 +- ...ork_hardware_pico_native_PioIrqHandlers.c} | 0 ...oFramework_Hardware_Pico_Pio_PioBlock.cpp} | 16 +- ...ork_Hardware_Pico_Pio_PioStateMachine.cpp} | 38 +- ...noFramework_hardware_pico_native_target.h} | 6 +- .../nf_hardware_rpi_native.cpp | 593 ----------------- 8 files changed, 252 insertions(+), 1227 deletions(-) create mode 100644 targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp rename targets/ChibiOS/_nanoCLR/{nanoFramework.Hardware.Rpi/nf_hardware_rpi_native.h => nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.h} (84%) rename targets/ChibiOS/_nanoCLR/{nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_PioIrqDriver.cpp => nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_PioIrqDriver.cpp} (96%) rename targets/ChibiOS/_nanoCLR/{nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_PioIrqHandlers.c => nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_PioIrqHandlers.c} (100%) rename targets/ChibiOS/_nanoCLR/{nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock.cpp => nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp} (91%) rename targets/ChibiOS/_nanoCLR/{nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.cpp => nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp} (89%) rename targets/ChibiOS/_nanoCLR/{nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_target.h => nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_target.h} (82%) delete mode 100644 targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native.cpp diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp new file mode 100644 index 0000000000..26a7302148 --- /dev/null +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp @@ -0,0 +1,206 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include "nanoFramework_hardware_pico_native.h" + +// clang-format off + +static const CLR_RT_MethodHandler method_lookup[] = +{ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::NativeAddProgram___STATIC__I4__I4__SZARRAY_U2__I4__I4, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::NativeRemoveProgram___STATIC__VOID__I4__I4__I4, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::NativeClaimUnusedSm___STATIC__I4__I4__BOOLEAN, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::NativeInitGpio___STATIC__VOID__I4__I4, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::NativeForceIrq___STATIC__VOID__I4__I4, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::NativeClearIrq___STATIC__VOID__I4__I4, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeInit___STATIC__VOID__I4__I4__I4__SZARRAY_U4, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeSetEnabled___STATIC__VOID__I4__I4__BOOLEAN, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativePutBlocking___STATIC__VOID__I4__I4__U4, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeGetBlocking___STATIC__U4__I4__I4, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeTxFull___STATIC__BOOLEAN__I4__I4, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeRxEmpty___STATIC__BOOLEAN__I4__I4, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeUnclaim___STATIC__VOID__I4__I4, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeSetConsecutivePinDirs___STATIC__VOID__I4__I4__I4__I4__BOOLEAN, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeClearFifos___STATIC__VOID__I4__I4, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeDrainTxFifo___STATIC__VOID__I4__I4, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeRestart___STATIC__VOID__I4__I4, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeClkDivRestart___STATIC__VOID__I4__I4, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeExec___STATIC__VOID__I4__I4__U2, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeTxLevel___STATIC__U4__I4__I4, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeRxLevel___STATIC__U4__I4__I4, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeGetPc___STATIC__U4__I4__I4, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeSetClockDivisor___STATIC__VOID__I4__I4__I4__I4, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, +}; + +const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Pico = +{ + "nanoFramework.Hardware.Pico", + 0x7733E84B, + method_lookup, + { 1, 0, 0, 0 } +}; + +// clang-format on diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native.h b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.h similarity index 84% rename from targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native.h rename to targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.h index fc503002e7..2e8b7fa940 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native.h +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.h @@ -3,853 +3,265 @@ // See LICENSE file in the project root for full license information. // -#ifndef NF_HARDWARE_RPI_NATIVE_H - -#define NF_HARDWARE_RPI_NATIVE_H - - +#ifndef NANOFRAMEWORK_HARDWARE_PICO_NATIVE_H +#define NANOFRAMEWORK_HARDWARE_PICO_NATIVE_H #include - #include - #include - - #include - - - - typedef enum __nfpack PioCondition - { - - PioCondition_Always = 0, - - PioCondition_XZero = 1, - - PioCondition_XPostDec = 2, - - PioCondition_YZero = 3, - - PioCondition_YPostDec = 4, - - PioCondition_XNotEqualY = 5, - - PioCondition_Pin = 6, - - PioCondition_OsrNotEmpty = 7, - - - } PioCondition; - - typedef enum __nfpack PioDest - { - - PioDest_Pins = 0, - - PioDest_X = 1, - - PioDest_Y = 2, - - PioDest_Null = 3, - - PioDest_PinDirs = 4, - - PioDest_Pc = 5, - - PioDest_Status = 5, - - PioDest_Isr = 6, - - PioDest_Osr = 7, - - PioDest_Exec = 7, - - - } PioDest; - - typedef enum __nfpack PioFifoJoin - { - - PioFifoJoin_None = 0, - - PioFifoJoin_Tx = 1, - - PioFifoJoin_Rx = 2, - - PioFifoJoin_TxGet = 4, - - PioFifoJoin_TxPut = 8, - - PioFifoJoin_PutGet = 12, - - - } PioFifoJoin; - - typedef enum __nfpack PioMovOp - { - - PioMovOp_None = 0, - - PioMovOp_Invert = 1, - - PioMovOp_BitReverse = 2, - - - } PioMovOp; - - typedef enum __nfpack PioMovStatusSel - { - - PioMovStatusSel_TxLevel = 0, - - PioMovStatusSel_RxLevel = 1, - - - } PioMovStatusSel; - - typedef enum __nfpack PioShiftDir - { - - PioShiftDir_Left = 0, - - PioShiftDir_Right = 1, - - - } PioShiftDir; - - typedef enum __nfpack PioSrc - { - - PioSrc_Pins = 0, - - PioSrc_X = 1, - - PioSrc_Y = 2, - - PioSrc_Null = 3, - - PioSrc_Status = 5, - - PioSrc_Isr = 6, - - PioSrc_Osr = 7, - - - } PioSrc; - - typedef enum __nfpack PioVersion - { - - PioVersion_Rp2040 = 0, - - PioVersion_Rp2350 = 1, - - - } PioVersion; - - typedef enum __nfpack PioWaitSource - { - - PioWaitSource_Gpio = 0, - - PioWaitSource_Pin = 1, - - PioWaitSource_Irq = 2, - - - } PioWaitSource; - - - - -struct Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_Pio - +struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_Pio { - - - - static const int FIELD_STATIC___blocks = 0; - - - - - - - - - //--// - }; - - -struct Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioAssemblerOptions - +struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioAssemblerOptions { - - - - - - - static const int FIELD__Version = 1; - - - static const int FIELD__SideSetCount = 2; - - - static const int FIELD__SideSetOpt = 3; - - - static const int FIELD__SideSetPinDirs = 4; - - - - - - //--// - }; - - -struct Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioInstructionRef - +struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioInstructionRef { - - - - - - - static const int FIELD___owner = 1; - - - static const int FIELD___index = 2; - - - - - - //--// - }; - - -struct Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioLabel - +struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioLabel { - - - - - - - // renamed backing field 'k__BackingField' - - static const int FIELD__Id = 1; - - - // renamed backing field '
k__BackingField' - - static const int FIELD__Address = 2; - - - - - - //--// - }; - - -struct Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioAssembler - +struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioAssembler { - - - - - - - static const int FIELD___baseBits = 1; - - - static const int FIELD___delay = 2; - - - static const int FIELD___sideValue = 3; - - - static const int FIELD___sideUsed = 4; - - - static const int FIELD___jmpLabel = 5; - - - static const int FIELD___count = 6; - - - static const int FIELD___labelCount = 7; - - - static const int FIELD___version = 8; - - - static const int FIELD___sideSetCount = 9; - - - static const int FIELD___sideSetOpt = 10; - - - static const int FIELD___sideSetPinDirs = 11; - - - static const int FIELD___wrapTarget = 12; - - - static const int FIELD___wrap = 13; - - - static const int FIELD___origin = 14; - - - static const int FIELD___outShiftDir = 15; - - - static const int FIELD___autoPull = 16; - - - static const int FIELD___pullThreshold = 17; - - - static const int FIELD___inShiftDir = 18; - - - static const int FIELD___autoPush = 19; - - - static const int FIELD___pushThreshold = 20; - - - - - - //--// - }; - - -struct Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock - +struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock { - - - - - - - static const int FIELD___index = 1; - - - static const int FIELD___irqDispatcher = 2; - - - static const int FIELD___interruptCallbacks = 3; - - - - NANOCLR_NATIVE_DECLARE(NativeAddProgram___STATIC__I4__I4__SZARRAY_U2__I4__I4); - - NANOCLR_NATIVE_DECLARE(NativeRemoveProgram___STATIC__VOID__I4__I4__I4); - - NANOCLR_NATIVE_DECLARE(NativeClaimUnusedSm___STATIC__I4__I4__BOOLEAN); - - NANOCLR_NATIVE_DECLARE(NativeInitGpio___STATIC__VOID__I4__I4); - - NANOCLR_NATIVE_DECLARE(NativeForceIrq___STATIC__VOID__I4__I4); - - NANOCLR_NATIVE_DECLARE(NativeClearIrq___STATIC__VOID__I4__I4); - - - //--// - }; - - -struct Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioProgram - +struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioProgram { - - - - - - - // renamed backing field 'k__BackingField' - - static const int FIELD__Instructions = 1; - - - // renamed backing field 'k__BackingField' - - static const int FIELD__Wrap = 2; - - - // renamed backing field 'k__BackingField' - - static const int FIELD__WrapTarget = 3; - - - // renamed backing field 'k__BackingField' - - static const int FIELD__Origin = 4; - - - // renamed backing field 'k__BackingField' - - static const int FIELD__SideSetCount = 5; - - - // renamed backing field 'k__BackingField' - - static const int FIELD__SideSetOpt = 6; - - - // renamed backing field 'k__BackingField' - - static const int FIELD__SideSetPinDirs = 7; - - - // renamed backing field 'k__BackingField' - - static const int FIELD__OutShiftDir = 8; - - - // renamed backing field 'k__BackingField' - - static const int FIELD__AutoPull = 9; - - - // renamed backing field 'k__BackingField' - - static const int FIELD__PullThreshold = 10; - - - // renamed backing field 'k__BackingField' - - static const int FIELD__InShiftDir = 11; - - - // renamed backing field 'k__BackingField' - - static const int FIELD__AutoPush = 12; - - - // renamed backing field 'k__BackingField' - - static const int FIELD__PushThreshold = 13; - - - // renamed backing field 'k__BackingField' - - static const int FIELD__Version = 14; - - - - - - //--// - }; - - -struct Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine - +struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine { - - - - - - - static const int FIELD___block = 1; - - - static const int FIELD___sm = 2; - - - static const int FIELD___disposed = 3; - - - static const int FIELD___enabled = 4; - - - - NANOCLR_NATIVE_DECLARE(NativeInit___STATIC__VOID__I4__I4__I4__SZARRAY_U4); - - NANOCLR_NATIVE_DECLARE(NativeSetEnabled___STATIC__VOID__I4__I4__BOOLEAN); - - NANOCLR_NATIVE_DECLARE(NativePutBlocking___STATIC__VOID__I4__I4__U4); - - NANOCLR_NATIVE_DECLARE(NativeGetBlocking___STATIC__U4__I4__I4); - - NANOCLR_NATIVE_DECLARE(NativeTxFull___STATIC__BOOLEAN__I4__I4); - - NANOCLR_NATIVE_DECLARE(NativeRxEmpty___STATIC__BOOLEAN__I4__I4); - - NANOCLR_NATIVE_DECLARE(NativeUnclaim___STATIC__VOID__I4__I4); - - NANOCLR_NATIVE_DECLARE(NativeSetConsecutivePinDirs___STATIC__VOID__I4__I4__I4__I4__BOOLEAN); - - NANOCLR_NATIVE_DECLARE(NativeClearFifos___STATIC__VOID__I4__I4); - - NANOCLR_NATIVE_DECLARE(NativeDrainTxFifo___STATIC__VOID__I4__I4); - - NANOCLR_NATIVE_DECLARE(NativeRestart___STATIC__VOID__I4__I4); - - NANOCLR_NATIVE_DECLARE(NativeClkDivRestart___STATIC__VOID__I4__I4); - - NANOCLR_NATIVE_DECLARE(NativeExec___STATIC__VOID__I4__I4__U2); - - NANOCLR_NATIVE_DECLARE(NativeTxLevel___STATIC__U4__I4__I4); - - NANOCLR_NATIVE_DECLARE(NativeRxLevel___STATIC__U4__I4__I4); - - NANOCLR_NATIVE_DECLARE(NativeGetPc___STATIC__U4__I4__I4); - - NANOCLR_NATIVE_DECLARE(NativeSetClockDivisor___STATIC__VOID__I4__I4__I4__I4); - - - //--// - }; - - -struct Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachineConfig - +struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachineConfig { - - - - - - - static const int FIELD___outBase = 1; - - - static const int FIELD___outCount = 2; - - - static const int FIELD___setBase = 3; - - - static const int FIELD___setCount = 4; - - - static const int FIELD___sideSetBase = 5; - - - static const int FIELD___inBase = 6; - - - static const int FIELD___jmpPin = 7; - - - static const int FIELD___sideSetCount = 8; - - - static const int FIELD___sideSetOpt = 9; - - - static const int FIELD___sideSetPinDirs = 10; - - - static const int FIELD___outShiftDir = 11; - - - static const int FIELD___autoPull = 12; - - - static const int FIELD___pullThreshold = 13; - - - static const int FIELD___inShiftDir = 14; - - - static const int FIELD___autoPush = 15; - - - static const int FIELD___pushThreshold = 16; - - - static const int FIELD___wrapTarget = 17; - - - static const int FIELD___wrap = 18; - - - static const int FIELD___clkDivInt = 19; - - - static const int FIELD___clkDivFrac = 20; - - - static const int FIELD___fifoJoin = 21; - - - static const int FIELD___gpioBase = 22; - - - static const int FIELD___movStatusSel = 23; - - - static const int FIELD___movStatusN = 24; - - - static const int FIELD___outSticky = 25; - - - static const int FIELD___inlineOutEn = 26; - - - static const int FIELD___outEnSel = 27; - - - - - - //--// - }; +extern const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Pico; - -extern const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Rpi; - - -#endif // NF_HARDWARE_RPI_NATIVE_H - +#endif // NANOFRAMEWORK_HARDWARE_PICO_NATIVE_H diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_PioIrqDriver.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_PioIrqDriver.cpp similarity index 96% rename from targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_PioIrqDriver.cpp rename to targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_PioIrqDriver.cpp index 2eeaacac5a..32d2d55642 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_PioIrqDriver.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_PioIrqDriver.cpp @@ -3,7 +3,7 @@ // See LICENSE file in the project root for full license information. // -#include "nf_hardware_rpi_native.h" +#include "nanoFramework_hardware_pico_native.h" #include #include // chSysLockFromISR #include // nvicEnableVector + RP_PIOx_IRQ_0_NUMBER @@ -12,7 +12,7 @@ #else #include "rp2040.h" #endif -#include "nf_hardware_rpi_native_target.h" +#include "nanoFramework_hardware_pico_native_target.h" // dispatcher context per block static CLR_RT_HeapBlock_NativeEventDispatcher *s_pioCtx[3] = {nullptr, nullptr, nullptr}; @@ -161,7 +161,7 @@ static const CLR_RT_DriverInterruptMethods g_PioIrqDriverMethods = { PioIrqCleanup}; // looked up by name from `new NativeEventDispatcher("PioIrqDriver", block)` -extern const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Rpi_PioIrqDriver = { +extern const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Pico_PioIrqDriver = { "PioIrqDriver", DRIVER_INTERRUPT_METHODS_CHECKSUM, &g_PioIrqDriverMethods, diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_PioIrqHandlers.c b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_PioIrqHandlers.c similarity index 100% rename from targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_PioIrqHandlers.c rename to targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_PioIrqHandlers.c diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp similarity index 91% rename from targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock.cpp rename to targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp index a8f45af244..d98cb4763a 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp @@ -3,13 +3,13 @@ // See LICENSE file in the project root for full license information. // -#include "nf_hardware_rpi_native.h" +#include "nanoFramework_hardware_pico_native.h" #if defined(RP2350) #include "rp2350.h" #else #include "rp2040.h" #endif -#include "nf_hardware_rpi_native_target.h" +#include "nanoFramework_hardware_pico_native_target.h" unsigned int g_PioInstrUsed[3] = {0, 0, 0}; unsigned int g_PioClaimedSm[3] = {0, 0, 0}; @@ -55,7 +55,7 @@ void PioEnsureOutOfReset(int blockIndex) g_PioOutOfReset |= (1u << blockIndex); } -HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock:: +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock:: NativeAddProgram___STATIC__I4__I4__SZARRAY_U2__I4__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); @@ -118,7 +118,7 @@ HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock:: NANOCLR_NOCLEANUP(); } -HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock:: +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock:: NativeRemoveProgram___STATIC__VOID__I4__I4__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); @@ -145,7 +145,7 @@ HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock:: NANOCLR_NOCLEANUP(); } -HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock:: +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock:: NativeClaimUnusedSm___STATIC__I4__I4__BOOLEAN(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); @@ -180,7 +180,7 @@ HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock:: NANOCLR_NOCLEANUP(); } -HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock:: +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock:: NativeInitGpio___STATIC__VOID__I4__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); @@ -206,7 +206,7 @@ HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock:: NANOCLR_NOCLEANUP(); } -HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock:: +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock:: NativeForceIrq___STATIC__VOID__I4__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); @@ -226,7 +226,7 @@ HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock:: NANOCLR_NOCLEANUP(); } -HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock:: +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock:: NativeClearIrq___STATIC__VOID__I4__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp similarity index 89% rename from targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.cpp rename to targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp index 9339c89fa3..e91ff62c67 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp @@ -3,13 +3,13 @@ // See LICENSE file in the project root for full license information. // -#include "nf_hardware_rpi_native.h" +#include "nanoFramework_hardware_pico_native.h" #if defined(RP2350) #include "rp2350.h" #else #include "rp2040.h" #endif -#include "nf_hardware_rpi_native_target.h" +#include "nanoFramework_hardware_pico_native_target.h" // busy-wait cap so a stalled SM times out instead of hanging static const unsigned int PIO_FIFO_WAIT_LIMIT = 0x4000000u; @@ -50,7 +50,7 @@ enum PioCfgBlob // claim bitmask owned by PioBlock.cpp extern unsigned int g_PioClaimedSm[3]; -HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine:: +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: NativeInit___STATIC__VOID__I4__I4__I4__SZARRAY_U4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); @@ -122,7 +122,7 @@ HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMa NANOCLR_NOCLEANUP(); } -HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine:: +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: NativeSetEnabled___STATIC__VOID__I4__I4__BOOLEAN(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); @@ -150,7 +150,7 @@ HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMa NANOCLR_NOCLEANUP(); } -HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine:: +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: NativePutBlocking___STATIC__VOID__I4__I4__U4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); @@ -180,7 +180,7 @@ HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMa NANOCLR_NOCLEANUP(); } -HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine:: +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: NativeGetBlocking___STATIC__U4__I4__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); @@ -209,7 +209,7 @@ HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMa NANOCLR_NOCLEANUP(); } -HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine:: +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: NativeTxFull___STATIC__BOOLEAN__I4__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); @@ -229,7 +229,7 @@ HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMa NANOCLR_NOCLEANUP(); } -HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine:: +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: NativeRxEmpty___STATIC__BOOLEAN__I4__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); @@ -249,7 +249,7 @@ HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMa NANOCLR_NOCLEANUP(); } -HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine:: +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: NativeUnclaim___STATIC__VOID__I4__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); @@ -271,7 +271,7 @@ HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMa NANOCLR_NOCLEANUP(); } -HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine:: +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: NativeSetConsecutivePinDirs___STATIC__VOID__I4__I4__I4__I4__BOOLEAN(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); @@ -317,7 +317,7 @@ HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMa NANOCLR_NOCLEANUP(); } -HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine:: +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: NativeClearFifos___STATIC__VOID__I4__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); @@ -340,7 +340,7 @@ HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMa NANOCLR_NOCLEANUP(); } -HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine:: +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: NativeDrainTxFifo___STATIC__VOID__I4__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); @@ -371,7 +371,7 @@ HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMa NANOCLR_NOCLEANUP(); } -HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine:: +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: NativeRestart___STATIC__VOID__I4__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); @@ -392,7 +392,7 @@ HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMa NANOCLR_NOCLEANUP(); } -HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine:: +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: NativeClkDivRestart___STATIC__VOID__I4__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); @@ -413,7 +413,7 @@ HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMa NANOCLR_NOCLEANUP(); } -HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine:: +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: NativeExec___STATIC__VOID__I4__I4__U2(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); @@ -435,7 +435,7 @@ HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMa NANOCLR_NOCLEANUP(); } -HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine:: +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: NativeTxLevel___STATIC__U4__I4__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); @@ -455,7 +455,7 @@ HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMa NANOCLR_NOCLEANUP(); } -HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine:: +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: NativeRxLevel___STATIC__U4__I4__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); @@ -475,7 +475,7 @@ HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMa NANOCLR_NOCLEANUP(); } -HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine:: +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: NativeGetPc___STATIC__U4__I4__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); @@ -495,7 +495,7 @@ HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMa NANOCLR_NOCLEANUP(); } -HRESULT Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine:: +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: NativeSetClockDivisor___STATIC__VOID__I4__I4__I4__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_target.h b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_target.h similarity index 82% rename from targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_target.h rename to targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_target.h index 8683f857aa..fc51062454 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native_target.h +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_target.h @@ -3,8 +3,8 @@ // See LICENSE file in the project root for full license information. // -#ifndef NF_HARDWARE_RPI_NATIVE_TARGET_H -#define NF_HARDWARE_RPI_NATIVE_TARGET_H +#ifndef NANOFRAMEWORK_HARDWARE_PICO_NATIVE_TARGET_H +#define NANOFRAMEWORK_HARDWARE_PICO_NATIVE_TARGET_H // Maps a PIO block index to its register block, or nullptr for an invalid index. // RP2040 exposes PIO0/PIO1; RP2350 adds PIO2. @@ -29,4 +29,4 @@ static inline PIO_TypeDef *PioFromIndex(int index) // the PioBlock translation unit so the reset state is shared across all entry points. void PioEnsureOutOfReset(int blockIndex); -#endif // NF_HARDWARE_RPI_NATIVE_TARGET_H +#endif // NANOFRAMEWORK_HARDWARE_PICO_NATIVE_TARGET_H diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native.cpp deleted file mode 100644 index 8354686b50..0000000000 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Rpi/nf_hardware_rpi_native.cpp +++ /dev/null @@ -1,593 +0,0 @@ -// -// Copyright (c) .NET Foundation and Contributors -// See LICENSE file in the project root for full license information. -// - -#include "nf_hardware_rpi_native.h" - - - -// clang-format off - - - -static const CLR_RT_MethodHandler method_lookup[] = - -{ - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeAddProgram___STATIC__I4__I4__SZARRAY_U2__I4__I4, - - - Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeRemoveProgram___STATIC__VOID__I4__I4__I4, - - - Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeClaimUnusedSm___STATIC__I4__I4__BOOLEAN, - - - Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeInitGpio___STATIC__VOID__I4__I4, - - - Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeForceIrq___STATIC__VOID__I4__I4, - - - Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock::NativeClearIrq___STATIC__VOID__I4__I4, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeInit___STATIC__VOID__I4__I4__I4__SZARRAY_U4, - - - Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeSetEnabled___STATIC__VOID__I4__I4__BOOLEAN, - - - Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativePutBlocking___STATIC__VOID__I4__I4__U4, - - - Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeGetBlocking___STATIC__U4__I4__I4, - - - Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeTxFull___STATIC__BOOLEAN__I4__I4, - - - Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeRxEmpty___STATIC__BOOLEAN__I4__I4, - - - Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeUnclaim___STATIC__VOID__I4__I4, - - - Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeSetConsecutivePinDirs___STATIC__VOID__I4__I4__I4__I4__BOOLEAN, - - - Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeClearFifos___STATIC__VOID__I4__I4, - - - Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeDrainTxFifo___STATIC__VOID__I4__I4, - - - Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeRestart___STATIC__VOID__I4__I4, - - - Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeClkDivRestart___STATIC__VOID__I4__I4, - - - Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeExec___STATIC__VOID__I4__I4__U2, - - - Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeTxLevel___STATIC__U4__I4__I4, - - - Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeRxLevel___STATIC__U4__I4__I4, - - - Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeGetPc___STATIC__U4__I4__I4, - - - Library_nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine::NativeSetClockDivisor___STATIC__VOID__I4__I4__I4__I4, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - - NULL, - - -}; - - - -const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Rpi = - -{ - - "nanoFramework.Hardware.Rpi", - - 0xB566C02F, - - method_lookup, - - { 1, 0, 0, 0 } - -}; - - - -// clang-format on - - From 50447df720781ea688fe0e72a8e3b4bc8facc3df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Fri, 26 Jun 2026 10:46:32 -0600 Subject: [PATCH 18/58] Update the build glue for the Pico rename Rename the Find module, the API entry in FindNF_NativeAssemblies, the Kconfig symbol and option mapping, and the Pico target defconfigs from Rpi to Pico. --- CMake/Modules/FindNF_NativeAssemblies.cmake | 13 ++--- .../FindnanoFramework.Hardware.Pico.cmake | 47 +++++++++++++++++++ .../FindnanoFramework.Hardware.Rpi.cmake | 47 ------------------- CMake/Modules/NF_Kconfig.cmake | 2 +- Kconfig.apis | 4 +- targets/ChibiOS/PICO2_RP2350/defconfig | 2 +- targets/ChibiOS/PICO2_RP2350_W/defconfig | 2 +- 7 files changed, 59 insertions(+), 58 deletions(-) create mode 100644 CMake/Modules/FindnanoFramework.Hardware.Pico.cmake delete mode 100644 CMake/Modules/FindnanoFramework.Hardware.Rpi.cmake diff --git a/CMake/Modules/FindNF_NativeAssemblies.cmake b/CMake/Modules/FindNF_NativeAssemblies.cmake index 69789e6438..23c2646ff9 100644 --- a/CMake/Modules/FindNF_NativeAssemblies.cmake +++ b/CMake/Modules/FindNF_NativeAssemblies.cmake @@ -42,7 +42,7 @@ option(API_nanoFramework.Networking.Thread "option for nanoFramewor # Stm32 only option(API_Hardware.Stm32 "option for Hardware.Stm32") -option(API_Hardware.Rpi "option for Hardware.Rpi") +option(API_Hardware.Pico "option for Hardware.Pico") # TI CC13xxCC26xx option(API_nanoFramework.TI.EasyLink "option for nanoFramework.TI.EasyLink API") @@ -271,12 +271,13 @@ if(API_Hardware.Stm32) PerformSettingsForApiEntry("nanoFramework.Hardware.Stm32") endif() -# Hardware.Rpi -if(API_Hardware.Rpi) - PerformSettingsForApiEntry("nanoFramework.Hardware.Rpi") +# Hardware.Pico +if(API_Hardware.Pico) + ##### API name here (doted name) + PerformSettingsForApiEntry("nanoFramework.Hardware.Pico") - list(APPEND CLR_RT_NativeAssemblyDataList "extern const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Rpi_PioIrqDriver;") - list(APPEND CLR_RT_NativeAssemblyDataTableEntriesList "&g_CLR_AssemblyNative_nanoFramework_Hardware_Rpi_PioIrqDriver,") + list(APPEND CLR_RT_NativeAssemblyDataList "extern const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Pico_PioIrqDriver;") + list(APPEND CLR_RT_NativeAssemblyDataTableEntriesList "&g_CLR_AssemblyNative_nanoFramework_Hardware_Pico_PioIrqDriver,") endif() # nanoFramework.Device.Can diff --git a/CMake/Modules/FindnanoFramework.Hardware.Pico.cmake b/CMake/Modules/FindnanoFramework.Hardware.Pico.cmake new file mode 100644 index 0000000000..bcda9a8feb --- /dev/null +++ b/CMake/Modules/FindnanoFramework.Hardware.Pico.cmake @@ -0,0 +1,47 @@ +# +# Copyright (c) .NET Foundation and Contributors +# See LICENSE file in the project root for full license information. +# + + +# native code directory +set(BASE_PATH_FOR_THIS_MODULE "${BASE_PATH_FOR_CLASS_LIBRARIES_MODULES}/nanoFramework.Hardware.Pico") + + +# set include directories +list(APPEND nanoFramework.Hardware.Pico_INCLUDE_DIRS "${BASE_PATH_FOR_THIS_MODULE}") + + +# source files +set(nanoFramework.Hardware.Pico_SRCS + + nanoFramework_hardware_pico_native.cpp + nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp + nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp + nanoFramework_hardware_pico_native_PioIrqDriver.cpp + nanoFramework_hardware_pico_native_PioIrqHandlers.c +) + +foreach(SRC_FILE ${nanoFramework.Hardware.Pico_SRCS}) + + set(nanoFramework.Hardware.Pico_SRC_FILE SRC_FILE-NOTFOUND) + + find_file(nanoFramework.Hardware.Pico_SRC_FILE ${SRC_FILE} + PATHS + ${BASE_PATH_FOR_THIS_MODULE} + + CMAKE_FIND_ROOT_PATH_BOTH + ) + + if (BUILD_VERBOSE) + message("${SRC_FILE} >> ${nanoFramework.Hardware.Pico_SRC_FILE}") + endif() + + list(APPEND nanoFramework.Hardware.Pico_SOURCES ${nanoFramework.Hardware.Pico_SRC_FILE}) + +endforeach() + + +include(FindPackageHandleStandardArgs) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS(nanoFramework.Hardware.Pico DEFAULT_MSG nanoFramework.Hardware.Pico_INCLUDE_DIRS nanoFramework.Hardware.Pico_SOURCES) diff --git a/CMake/Modules/FindnanoFramework.Hardware.Rpi.cmake b/CMake/Modules/FindnanoFramework.Hardware.Rpi.cmake deleted file mode 100644 index b13dfebe50..0000000000 --- a/CMake/Modules/FindnanoFramework.Hardware.Rpi.cmake +++ /dev/null @@ -1,47 +0,0 @@ -# -# Copyright (c) .NET Foundation and Contributors -# See LICENSE file in the project root for full license information. -# - - -# native code directory -set(BASE_PATH_FOR_THIS_MODULE "${BASE_PATH_FOR_CLASS_LIBRARIES_MODULES}/nanoFramework.Hardware.Rpi") - - -# set include directories -list(APPEND nanoFramework.Hardware.Rpi_INCLUDE_DIRS "${BASE_PATH_FOR_THIS_MODULE}") - - -# source files -set(nanoFramework.Hardware.Rpi_SRCS - - nf_hardware_rpi_native.cpp - nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioBlock.cpp - nf_hardware_rpi_native_nanoFramework_Hardware_Rpi_Pio_PioStateMachine.cpp - nf_hardware_rpi_native_PioIrqDriver.cpp - nf_hardware_rpi_native_PioIrqHandlers.c -) - -foreach(SRC_FILE ${nanoFramework.Hardware.Rpi_SRCS}) - - set(nanoFramework.Hardware.Rpi_SRC_FILE SRC_FILE-NOTFOUND) - - find_file(nanoFramework.Hardware.Rpi_SRC_FILE ${SRC_FILE} - PATHS - ${BASE_PATH_FOR_THIS_MODULE} - - CMAKE_FIND_ROOT_PATH_BOTH - ) - - if (BUILD_VERBOSE) - message("${SRC_FILE} >> ${nanoFramework.Hardware.Rpi_SRC_FILE}") - endif() - - list(APPEND nanoFramework.Hardware.Rpi_SOURCES ${nanoFramework.Hardware.Rpi_SRC_FILE}) - -endforeach() - - -include(FindPackageHandleStandardArgs) - -FIND_PACKAGE_HANDLE_STANDARD_ARGS(nanoFramework.Hardware.Rpi DEFAULT_MSG nanoFramework.Hardware.Rpi_INCLUDE_DIRS nanoFramework.Hardware.Rpi_SOURCES) diff --git a/CMake/Modules/NF_Kconfig.cmake b/CMake/Modules/NF_Kconfig.cmake index ac55176013..5b3fa9c2a3 100644 --- a/CMake/Modules/NF_Kconfig.cmake +++ b/CMake/Modules/NF_Kconfig.cmake @@ -43,7 +43,7 @@ set(_NF_KCONFIG_API_MAP # Platform-specific APIs "API_HARDWARE_STM32|API_Hardware.Stm32" - "API_HARDWARE_RPI|API_Hardware.Rpi" + "API_HARDWARE_PICO|API_Hardware.Pico" "API_HARDWARE_ESP32|API_Hardware.Esp32" "API_NANOFRAMEWORK_HARDWARE_ESP32_RMT|API_nanoFramework.Hardware.Esp32.Rmt" "API_NANOFRAMEWORK_HARDWARE_TI|API_nanoFramework.Hardware.TI" diff --git a/Kconfig.apis b/Kconfig.apis index 0fe20f945c..d9148e7411 100644 --- a/Kconfig.apis +++ b/Kconfig.apis @@ -113,8 +113,8 @@ config API_HARDWARE_STM32 depends on RTOS_CHIBIOS default n -config API_HARDWARE_RPI - bool "Hardware.Rpi" +config API_HARDWARE_PICO + bool "Hardware.Pico" depends on RTOS_CHIBIOS default n diff --git a/targets/ChibiOS/PICO2_RP2350/defconfig b/targets/ChibiOS/PICO2_RP2350/defconfig index 202dd7ba46..34177cc1b0 100644 --- a/targets/ChibiOS/PICO2_RP2350/defconfig +++ b/targets/ChibiOS/PICO2_RP2350/defconfig @@ -9,7 +9,7 @@ CONFIG_API_SYSTEM_IO_PORTS=y CONFIG_API_NANOFRAMEWORK_RESOURCEMANAGER=y CONFIG_API_NANOFRAMEWORK_SYSTEM_COLLECTIONS=y CONFIG_API_NANOFRAMEWORK_SYSTEM_TEXT=y -CONFIG_API_HARDWARE_RPI=y +CONFIG_API_HARDWARE_PICO=y # CONFIG_CHIBIOS_CONTRIB_REQUIRED is not set # CONFIG_CHIBIOS_SWO_OUTPUT is not set # CONFIG_NF_BUILD_RTM is not set diff --git a/targets/ChibiOS/PICO2_RP2350_W/defconfig b/targets/ChibiOS/PICO2_RP2350_W/defconfig index e97ae44f23..20f2c2d88d 100644 --- a/targets/ChibiOS/PICO2_RP2350_W/defconfig +++ b/targets/ChibiOS/PICO2_RP2350_W/defconfig @@ -9,7 +9,7 @@ CONFIG_API_SYSTEM_DEVICE_WIFI=y CONFIG_API_SYSTEM_IO_FILESYSTEM=y CONFIG_API_SYSTEM_IO_PORTS=y CONFIG_API_SYSTEM_NET=y -CONFIG_API_HARDWARE_RPI=y +CONFIG_API_HARDWARE_PICO=y CONFIG_API_NANOFRAMEWORK_RESOURCEMANAGER=y CONFIG_API_NANOFRAMEWORK_SYSTEM_COLLECTIONS=y CONFIG_API_NANOFRAMEWORK_SYSTEM_TEXT=y From 5627bc6f4dac75858b8cf01ae8db85e77260102e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Fri, 26 Jun 2026 11:22:46 -0600 Subject: [PATCH 19/58] Harden PIO native input validation Address review feedback on the PIO native interop: - reject program offsets outside 0..31 before programming the state-machine PC - use overflow-safe (subtractive) bounds checks for the program slot range in AddProgram/RemoveProgram and for the consecutive pin-direction range - only let RemoveProgram reclaim a slot range that is fully owned, so it can't corrupt the allocation map or clobber other programs --- ...ive_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp | 13 ++++++++++--- ...oFramework_Hardware_Pico_Pio_PioStateMachine.cpp | 8 +++++--- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp index d98cb4763a..c1d9820687 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp @@ -79,7 +79,7 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P // fixed origin: exact slots; relocatable: first-fit if (origin >= 0) { - if (origin + length <= 32 && (g_PioInstrUsed[block] & PioSlotMask(origin, length)) == 0) + if (origin <= 32 - length && (g_PioInstrUsed[block] & PioSlotMask(origin, length)) == 0) { offset = origin; } @@ -128,7 +128,14 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P int offset = stack.Arg2().NumericByRef().s4; PIO_TypeDef *pio = PioFromIndex(block); - if (pio == nullptr || offset < 0 || length <= 0 || offset + length > 32) + if (pio == nullptr || offset < 0 || length <= 0 || length > 32 || offset > 32 - length) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + // only reclaim a range that is fully owned, else we'd corrupt the map and clobber other programs + unsigned int mask = PioSlotMask(offset, length); + if ((g_PioInstrUsed[block] & mask) != mask) { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } @@ -140,7 +147,7 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P pio->INSTR_MEM[offset + i] = (unsigned short)((offset + i) & 0x1F); } - g_PioInstrUsed[block] &= ~PioSlotMask(offset, length); + g_PioInstrUsed[block] &= ~mask; } NANOCLR_NOCLEANUP(); } diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp index e91ff62c67..22543abf95 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp @@ -61,7 +61,7 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P CLR_RT_HeapBlock_Array *blobArray = stack.Arg3().DereferenceArray(); PIO_TypeDef *pio = PioFromIndex(block); - if (pio == nullptr || sm < 0 || sm > 3 || blobArray == nullptr || + if (pio == nullptr || sm < 0 || sm > 3 || offset < 0 || offset > 31 || blobArray == nullptr || (int)blobArray->m_numOfElements < PIO_CFG_BLOB_LENGTH) { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); @@ -284,10 +284,12 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P PIO_TypeDef *pio = PioFromIndex(block); #if defined(RP2350) - if (pio == nullptr || sm < 0 || sm > 3 || basePin < 0 || count < 0 || basePin + count > 48) + const int maxPins = 48; #else - if (pio == nullptr || sm < 0 || sm > 3 || basePin < 0 || count < 0 || basePin + count > 30) + const int maxPins = 30; #endif + if (pio == nullptr || sm < 0 || sm > 3 || basePin < 0 || count < 0 || basePin > maxPins || + count > maxPins - basePin) { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } From c6f9048c673146cef7cc808aea39ffebb4ddf020 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Fri, 26 Jun 2026 11:22:46 -0600 Subject: [PATCH 20/58] Document PIO support on the Pico targets Add a PIO (Programmable I/O) section to the RP2040 and RP2350 target READMEs and list the API_Hardware.Pico build option. --- targets/ChibiOS/PICO2_RP2350/README.md | 29 ++++++++++++++++++++++++++ targets/ChibiOS/PICO_RP2040/README.md | 29 ++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/targets/ChibiOS/PICO2_RP2350/README.md b/targets/ChibiOS/PICO2_RP2350/README.md index d8c9725567..49f2bfce04 100644 --- a/targets/ChibiOS/PICO2_RP2350/README.md +++ b/targets/ChibiOS/PICO2_RP2350/README.md @@ -134,6 +134,34 @@ int raw = tempChannel.ReadValue(); - **Resolution:** 12-bit (0–4095) - **Reference voltage:** 3.3V (internal) +### PIO (Programmable I/O) + +The RP2350's **three PIO blocks** (4 state machines each) are exposed through the `nanoFramework.Hardware.Pico` library. Write small PIO programs with the inline `PioAssembler`, load them onto a block and run them on a state machine — useful for precise or custom protocols (WS2812, bit-banged SPI/UART, etc.) the fixed peripherals don't cover. + +```csharp +using nanoFramework.Hardware.Pico.Pio; + +// pull a word and drive its low bit onto the OUT pin +var asm = new PioAssembler(); +PioLabel loop = asm.DefineLabel(); +asm.MarkLabel(loop); +asm.Pull(ifEmpty: false, block: true); +asm.Out(PioDest.Pins, 1); +asm.Jmp(PioCondition.Always, loop); +PioProgram program = asm.Build(); + +PioBlock pio = Pio.Get(0); +uint offset = pio.AddProgram(program); +PioStateMachine sm = pio.ClaimStateMachine(); +sm.Init(offset, PioStateMachineConfig.FromProgram(program, (int)offset).OutPins(25, 1)); +pio.InitGpio(25); +sm.SetConsecutivePinDirs(25, 1, true); +sm.Enabled = true; +sm.Put(1); // drive the on-board LED +``` + +> Provided by the `nanoFramework.Hardware.Pico` NuGet package. State machine interrupts surface as the managed `PioBlock.Interrupt` event. + ## Pico Board Pinout Reference ``` @@ -182,6 +210,7 @@ Key CMake preset options (`CMakePresets.json`): "API_System.Device.I2c": "ON", "API_System.Device.Pwm": "ON", "API_System.Device.Adc": "ON", + "API_Hardware.Pico": "ON", "USE_RNG": "OFF" } ``` diff --git a/targets/ChibiOS/PICO_RP2040/README.md b/targets/ChibiOS/PICO_RP2040/README.md index 4418093ff4..8dd79b1050 100644 --- a/targets/ChibiOS/PICO_RP2040/README.md +++ b/targets/ChibiOS/PICO_RP2040/README.md @@ -137,6 +137,34 @@ int raw = tempChannel.ReadValue(); - **Resolution:** 12-bit (0–4095) - **Reference voltage:** 3.3V (internal) +### PIO (Programmable I/O) + +The RP2040's **two PIO blocks** (4 state machines each) are exposed through the `nanoFramework.Hardware.Pico` library. Write small PIO programs with the inline `PioAssembler`, load them onto a block and run them on a state machine — useful for precise or custom protocols (WS2812, bit-banged SPI/UART, etc.) the fixed peripherals don't cover. + +```csharp +using nanoFramework.Hardware.Pico.Pio; + +// pull a word and drive its low bit onto the OUT pin +var asm = new PioAssembler(); +PioLabel loop = asm.DefineLabel(); +asm.MarkLabel(loop); +asm.Pull(ifEmpty: false, block: true); +asm.Out(PioDest.Pins, 1); +asm.Jmp(PioCondition.Always, loop); +PioProgram program = asm.Build(); + +PioBlock pio = Pio.Get(0); +uint offset = pio.AddProgram(program); +PioStateMachine sm = pio.ClaimStateMachine(); +sm.Init(offset, PioStateMachineConfig.FromProgram(program, (int)offset).OutPins(25, 1)); +pio.InitGpio(25); +sm.SetConsecutivePinDirs(25, 1, true); +sm.Enabled = true; +sm.Put(1); // drive the on-board LED +``` + +> Provided by the `nanoFramework.Hardware.Pico` NuGet package. State machine interrupts surface as the managed `PioBlock.Interrupt` event. + ## Pico Board Pinout Reference ``` @@ -185,6 +213,7 @@ Key CMake preset options (`CMakePresets.json`): "API_System.Device.I2c": "ON", "API_System.Device.Pwm": "ON", "API_System.Device.Adc": "ON", + "API_Hardware.Pico": "ON", "USE_RNG": "OFF" } ``` From 850073f66183d0bb26bb90bcecb82b9e4013a107 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Fri, 26 Jun 2026 12:38:06 -0600 Subject: [PATCH 21/58] Fix DrainTxFifo to drain the whole TX FIFO The non-autopull drain used 0x8080 (PULL IfEmpty), which only pulls while the OSR is empty, so it stopped after the first word and left the rest in the FIFO. Use 0x8000 (PULL NoBlock) so every queued word is pulled out. Found by the strengthened PIO coverage tests. --- ...o_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp index 22543abf95..090cb038a4 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp @@ -359,7 +359,7 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P // exec OUT NULL,32 (autopull) or PULL noblock until TX empty. FSTAT TX_EMPTY = bits [27:24] unsigned int autopull = pio->SM[sm].SHIFTCTRL & (1u << 17); - unsigned int instr = autopull ? 0x6060u : 0x8080u; + unsigned int instr = autopull ? 0x6060u : 0x8000u; unsigned int guard = PIO_FIFO_WAIT_LIMIT; while ((pio->FSTAT & (1u << (24 + sm))) == 0 && --guard) { From c06a1916fd1afe859560344feb00453bbba76ff8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Fri, 26 Jun 2026 13:38:32 -0600 Subject: [PATCH 22/58] Fix RP2350 GPIO 32-47 aliasing in SetConsecutivePinDirs The 5-bit SET_BASE field is relative to the state machine's GPIO base window, so basePin 32-47 folded down to 0-15 through pin & 0x1F and changed the wrong pins. Make SET_BASE relative to the SM's GPIOBASE and reject ranges that fall outside the addressable 32-pin window or the chip's pins. --- ...e_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp index 090cb038a4..aaa6f5248f 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp @@ -285,11 +285,14 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P PIO_TypeDef *pio = PioFromIndex(block); #if defined(RP2350) const int maxPins = 48; + const int gpioBase = (pio != nullptr) ? (int)pio->GPIOBASE : 0; #else const int maxPins = 30; + const int gpioBase = 0; #endif - if (pio == nullptr || sm < 0 || sm > 3 || basePin < 0 || count < 0 || basePin > maxPins || - count > maxPins - basePin) + // SET_BASE is 5-bit, relative to the SM's GPIO base, so reject pins outside the 32-pin window + if (pio == nullptr || sm < 0 || sm > 3 || count < 0 || count > 32 || basePin < gpioBase || + basePin - gpioBase > 32 - count || basePin > maxPins - count) { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } @@ -306,7 +309,7 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P unsigned int dirs = output ? ((1u << chunk) - 1u) : 0u; // PINCTRL: SET_COUNT [28:26], SET_BASE [9:5] - pio->SM[sm].PINCTRL = ((unsigned int)chunk << 26) | (((unsigned int)pin & 0x1Fu) << 5); + pio->SM[sm].PINCTRL = ((unsigned int)chunk << 26) | (((unsigned int)(pin - gpioBase) & 0x1Fu) << 5); // SET pindirs, dirs pio->SM[sm].INSTR = 0xE000u | (4u << 5) | (dirs & 0x1Fu); From fe75957d8b1fc227dbb510d93487d0d88cf8685d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Fri, 26 Jun 2026 17:38:20 -0600 Subject: [PATCH 23/58] Regenerate native interop table for the FromEncoded metadata overload The managed library gained PioProgramOptions and a FromEncoded overload, shifting the method table and changing the declaration checksum (0x7733E84B -> 0x58CA3F79). Regenerate the dispatch table to match; the native implementations are unchanged. --- .../nanoFramework_hardware_pico_native.cpp | 35 ++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp index 26a7302148..e621ebb0b7 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp @@ -76,6 +76,15 @@ static const CLR_RT_MethodHandler method_lookup[] = NULL, NULL, NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::NativeAddProgram___STATIC__I4__I4__SZARRAY_U2__I4__I4, Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::NativeRemoveProgram___STATIC__VOID__I4__I4__I4, Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::NativeClaimUnusedSm___STATIC__I4__I4__BOOLEAN, @@ -157,6 +166,30 @@ static const CLR_RT_MethodHandler method_lookup[] = NULL, NULL, NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeInit___STATIC__VOID__I4__I4__I4__SZARRAY_U4, Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeSetEnabled___STATIC__VOID__I4__I4__BOOLEAN, Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativePutBlocking___STATIC__VOID__I4__I4__U4, @@ -198,7 +231,7 @@ static const CLR_RT_MethodHandler method_lookup[] = const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Pico = { "nanoFramework.Hardware.Pico", - 0x7733E84B, + 0x58CA3F79, method_lookup, { 1, 0, 0, 0 } }; From b885c6fdf43210dca26bbf6ae7249ec2e3e9875a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Mon, 29 Jun 2026 00:38:10 -0600 Subject: [PATCH 24/58] Prototype: DMA-backed bulk PIO read for PioStateMachine.Read Add NativeStartDmaRead/NativeDmaReadComplete/NativeFinishDmaRead. Start claims a DMA channel that drains the SM RX FIFO into a native bounce buffer, paced by the SM RX DREQ; the managed side polls completion while yielding, then Finish copies the bounce buffer into the managed array and frees the channel. The DMA never touches managed memory, so the moving GC can't relocate the target mid-transfer. Regenerates the native interop table (checksum 0x779AF39A). --- .../nanoFramework_hardware_pico_native.cpp | 467 +++++++++- .../nanoFramework_hardware_pico_native.h | 795 +++++++++++++++++- ...work_Hardware_Pico_Pio_PioStateMachine.cpp | 129 +++ 3 files changed, 1359 insertions(+), 32 deletions(-) diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp index e621ebb0b7..3e4a9794a8 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp @@ -5,235 +5,700 @@ #include "nanoFramework_hardware_pico_native.h" + + // clang-format off + + static const CLR_RT_MethodHandler method_lookup[] = + { + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::NativeAddProgram___STATIC__I4__I4__SZARRAY_U2__I4__I4, + + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::NativeRemoveProgram___STATIC__VOID__I4__I4__I4, + + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::NativeClaimUnusedSm___STATIC__I4__I4__BOOLEAN, + + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::NativeInitGpio___STATIC__VOID__I4__I4, + + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::NativeForceIrq___STATIC__VOID__I4__I4, + + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::NativeClearIrq___STATIC__VOID__I4__I4, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeStartDmaRead___STATIC__BOOLEAN__I4__I4__I4, + + + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeDmaReadComplete___STATIC__BOOLEAN__I4__I4, + + + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeFinishDmaRead___STATIC__I4__I4__I4__SZARRAY_U4__I4, + + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeInit___STATIC__VOID__I4__I4__I4__SZARRAY_U4, + + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeSetEnabled___STATIC__VOID__I4__I4__BOOLEAN, + + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativePutBlocking___STATIC__VOID__I4__I4__U4, + + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeGetBlocking___STATIC__U4__I4__I4, + + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeTxFull___STATIC__BOOLEAN__I4__I4, + + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeRxEmpty___STATIC__BOOLEAN__I4__I4, + + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeUnclaim___STATIC__VOID__I4__I4, + + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeSetConsecutivePinDirs___STATIC__VOID__I4__I4__I4__I4__BOOLEAN, + + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeClearFifos___STATIC__VOID__I4__I4, + + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeDrainTxFifo___STATIC__VOID__I4__I4, + + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeRestart___STATIC__VOID__I4__I4, + + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeClkDivRestart___STATIC__VOID__I4__I4, + + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeExec___STATIC__VOID__I4__I4__U2, + + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeTxLevel___STATIC__U4__I4__I4, + + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeRxLevel___STATIC__U4__I4__I4, + + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeGetPc___STATIC__U4__I4__I4, + + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeSetClockDivisor___STATIC__VOID__I4__I4__I4__I4, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + NULL, + + }; + + const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Pico = + { + "nanoFramework.Hardware.Pico", - 0x58CA3F79, + + 0x779AF39A, + method_lookup, + { 1, 0, 0, 0 } + }; + + // clang-format on + + diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.h b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.h index 2e8b7fa940..8678690814 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.h +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.h @@ -4,264 +4,997 @@ // #ifndef NANOFRAMEWORK_HARDWARE_PICO_NATIVE_H + #define NANOFRAMEWORK_HARDWARE_PICO_NATIVE_H + + #include + #include + #include + + #include + + + + typedef enum __nfpack PioCondition + { + + PioCondition_Always = 0, + + PioCondition_XZero = 1, + + PioCondition_XPostDec = 2, + + PioCondition_YZero = 3, + + PioCondition_YPostDec = 4, + + PioCondition_XNotEqualY = 5, + + PioCondition_Pin = 6, + + PioCondition_OsrNotEmpty = 7, + + + } PioCondition; + + typedef enum __nfpack PioDest + { + + PioDest_Pins = 0, + + PioDest_X = 1, + + PioDest_Y = 2, + + PioDest_Null = 3, + + PioDest_PinDirs = 4, + + PioDest_Pc = 5, + + PioDest_Status = 5, + + PioDest_Isr = 6, + + PioDest_Osr = 7, + + PioDest_Exec = 7, + + + } PioDest; + + typedef enum __nfpack PioFifoJoin + { + + PioFifoJoin_None = 0, + + PioFifoJoin_Tx = 1, + + PioFifoJoin_Rx = 2, + + PioFifoJoin_TxGet = 4, + + PioFifoJoin_TxPut = 8, + + PioFifoJoin_PutGet = 12, + + + } PioFifoJoin; + + typedef enum __nfpack PioMovOp + { + + PioMovOp_None = 0, + + PioMovOp_Invert = 1, + + PioMovOp_BitReverse = 2, + + + } PioMovOp; + + typedef enum __nfpack PioMovStatusSel + { + + PioMovStatusSel_TxLevel = 0, + + PioMovStatusSel_RxLevel = 1, + + + } PioMovStatusSel; + + typedef enum __nfpack PioShiftDir + { + + PioShiftDir_Left = 0, + + PioShiftDir_Right = 1, + + + } PioShiftDir; + + typedef enum __nfpack PioSrc + { + + PioSrc_Pins = 0, + + PioSrc_X = 1, + + PioSrc_Y = 2, + + PioSrc_Null = 3, + + PioSrc_Status = 5, + + PioSrc_Isr = 6, + + PioSrc_Osr = 7, + + + } PioSrc; + + typedef enum __nfpack PioVersion + { + + PioVersion_Rp2040 = 0, + + PioVersion_Rp2350 = 1, + + + } PioVersion; + + typedef enum __nfpack PioWaitSource + { + + PioWaitSource_Gpio = 0, + + PioWaitSource_Pin = 1, + + PioWaitSource_Irq = 2, + + + } PioWaitSource; + + + + struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_Pio + { + + + + static const int FIELD_STATIC___blocks = 0; + + + static const int FIELD_STATIC___lock = 1; + + + + + + + + + + //--// + }; + + struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioAssemblerOptions + { + + + + + + + + // renamed backing field 'k__BackingField' + + static const int FIELD__Version = 1; + + + + // renamed backing field 'k__BackingField' + + static const int FIELD__SideSetCount = 2; + + + + // renamed backing field 'k__BackingField' + + static const int FIELD__SideSetOpt = 3; + + + + // renamed backing field 'k__BackingField' + + static const int FIELD__SideSetPinDirs = 4; + + + + + + //--// + }; + + struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioInstructionRef + { + + + + + + + static const int FIELD___owner = 1; + + + static const int FIELD___index = 2; + + + + + + //--// + }; + + struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioLabel + { + + + + + + + // renamed backing field 'k__BackingField' + + static const int FIELD__Id = 1; + + + + // renamed backing field 'k__BackingField' + + + static const int FIELD__Owner = 2; + + + // renamed backing field '
k__BackingField' - static const int FIELD__Address = 2; - //--// -}; -struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioAssembler -{ - static const int FIELD___baseBits = 1; - static const int FIELD___delay = 2; - static const int FIELD___sideValue = 3; + static const int FIELD__Address = 3; + + + + + + + + //--// + +}; + + + +struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioAssembler + +{ + + + + + + + + static const int FIELD___baseBits = 1; + + + + static const int FIELD___delay = 2; + + + + static const int FIELD___sideValue = 3; + + + static const int FIELD___sideUsed = 4; + + + static const int FIELD___jmpLabel = 5; + + + static const int FIELD___count = 6; + + + static const int FIELD___labelCount = 7; + + + static const int FIELD___version = 8; + + + static const int FIELD___sideSetCount = 9; + + + static const int FIELD___sideSetOpt = 10; + + + static const int FIELD___sideSetPinDirs = 11; + + + static const int FIELD___wrapTarget = 12; + + + static const int FIELD___wrap = 13; + + + static const int FIELD___origin = 14; + + + static const int FIELD___outShiftDir = 15; + + + static const int FIELD___autoPull = 16; + + + static const int FIELD___pullThreshold = 17; + + + static const int FIELD___inShiftDir = 18; + + + static const int FIELD___autoPush = 19; + + + static const int FIELD___pushThreshold = 20; + + + + + + //--// + }; + + struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock + { + + + + + + + static const int FIELD___index = 1; + + + static const int FIELD___irqDispatcher = 2; + + + static const int FIELD___interruptCallbacks = 3; + + + static const int FIELD___irqLock = 4; + + + + + NANOCLR_NATIVE_DECLARE(NativeAddProgram___STATIC__I4__I4__SZARRAY_U2__I4__I4); + + NANOCLR_NATIVE_DECLARE(NativeRemoveProgram___STATIC__VOID__I4__I4__I4); + + NANOCLR_NATIVE_DECLARE(NativeClaimUnusedSm___STATIC__I4__I4__BOOLEAN); + + NANOCLR_NATIVE_DECLARE(NativeInitGpio___STATIC__VOID__I4__I4); + + NANOCLR_NATIVE_DECLARE(NativeForceIrq___STATIC__VOID__I4__I4); + + NANOCLR_NATIVE_DECLARE(NativeClearIrq___STATIC__VOID__I4__I4); + + + //--// + }; + + +struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioProgramOptions + +{ + + + + + + + + // renamed backing field 'k__BackingField' + + + static const int FIELD__Version = 1; + + + + // renamed backing field 'k__BackingField' + + + static const int FIELD__Origin = 2; + + + + // renamed backing field 'k__BackingField' + + + static const int FIELD__SideSetCount = 3; + + + + // renamed backing field 'k__BackingField' + + + static const int FIELD__SideSetOpt = 4; + + + + // renamed backing field 'k__BackingField' + + + static const int FIELD__SideSetPinDirs = 5; + + + + // renamed backing field 'k__BackingField' + + + static const int FIELD__OutShiftDir = 6; + + + + // renamed backing field 'k__BackingField' + + + static const int FIELD__AutoPull = 7; + + + + // renamed backing field 'k__BackingField' + + + static const int FIELD__PullThreshold = 8; + + + + // renamed backing field 'k__BackingField' + + + static const int FIELD__InShiftDir = 9; + + + + // renamed backing field 'k__BackingField' + + + static const int FIELD__AutoPush = 10; + + + + // renamed backing field 'k__BackingField' + + + static const int FIELD__PushThreshold = 11; + + + + + + + + //--// + +}; + + + struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioProgram + { + + + + + + + // renamed backing field 'k__BackingField' + + static const int FIELD__Instructions = 1; + + + // renamed backing field 'k__BackingField' + + static const int FIELD__Wrap = 2; + + + // renamed backing field 'k__BackingField' + + static const int FIELD__WrapTarget = 3; + + + // renamed backing field 'k__BackingField' + + static const int FIELD__Origin = 4; + + + // renamed backing field 'k__BackingField' + + static const int FIELD__SideSetCount = 5; + + + // renamed backing field 'k__BackingField' + + static const int FIELD__SideSetOpt = 6; + + + // renamed backing field 'k__BackingField' + + static const int FIELD__SideSetPinDirs = 7; + + + // renamed backing field 'k__BackingField' + + static const int FIELD__OutShiftDir = 8; + + + // renamed backing field 'k__BackingField' + + static const int FIELD__AutoPull = 9; + + + // renamed backing field 'k__BackingField' + + static const int FIELD__PullThreshold = 10; + + + // renamed backing field 'k__BackingField' + + static const int FIELD__InShiftDir = 11; + + + // renamed backing field 'k__BackingField' + + static const int FIELD__AutoPush = 12; + + + // renamed backing field 'k__BackingField' + + static const int FIELD__PushThreshold = 13; + + + // renamed backing field 'k__BackingField' + + static const int FIELD__Version = 14; + + + + + + //--// + }; + + struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine + { + + + + + + + static const int FIELD___block = 1; + + + static const int FIELD___sm = 2; - static const int FIELD___disposed = 3; - static const int FIELD___enabled = 4; + + + + static const int FIELD___owned = 3; + + + + static const int FIELD___disposed = 4; + + + + static const int FIELD___enabled = 5; + + + + + + NANOCLR_NATIVE_DECLARE(NativeStartDmaRead___STATIC__BOOLEAN__I4__I4__I4); + + + NANOCLR_NATIVE_DECLARE(NativeDmaReadComplete___STATIC__BOOLEAN__I4__I4); + + + NANOCLR_NATIVE_DECLARE(NativeFinishDmaRead___STATIC__I4__I4__I4__SZARRAY_U4__I4); + NANOCLR_NATIVE_DECLARE(NativeInit___STATIC__VOID__I4__I4__I4__SZARRAY_U4); + + NANOCLR_NATIVE_DECLARE(NativeSetEnabled___STATIC__VOID__I4__I4__BOOLEAN); + + NANOCLR_NATIVE_DECLARE(NativePutBlocking___STATIC__VOID__I4__I4__U4); + + NANOCLR_NATIVE_DECLARE(NativeGetBlocking___STATIC__U4__I4__I4); + + NANOCLR_NATIVE_DECLARE(NativeTxFull___STATIC__BOOLEAN__I4__I4); + + NANOCLR_NATIVE_DECLARE(NativeRxEmpty___STATIC__BOOLEAN__I4__I4); + + NANOCLR_NATIVE_DECLARE(NativeUnclaim___STATIC__VOID__I4__I4); + + NANOCLR_NATIVE_DECLARE(NativeSetConsecutivePinDirs___STATIC__VOID__I4__I4__I4__I4__BOOLEAN); + + NANOCLR_NATIVE_DECLARE(NativeClearFifos___STATIC__VOID__I4__I4); + + NANOCLR_NATIVE_DECLARE(NativeDrainTxFifo___STATIC__VOID__I4__I4); + + NANOCLR_NATIVE_DECLARE(NativeRestart___STATIC__VOID__I4__I4); + + NANOCLR_NATIVE_DECLARE(NativeClkDivRestart___STATIC__VOID__I4__I4); + + NANOCLR_NATIVE_DECLARE(NativeExec___STATIC__VOID__I4__I4__U2); + + NANOCLR_NATIVE_DECLARE(NativeTxLevel___STATIC__U4__I4__I4); + + NANOCLR_NATIVE_DECLARE(NativeRxLevel___STATIC__U4__I4__I4); + + NANOCLR_NATIVE_DECLARE(NativeGetPc___STATIC__U4__I4__I4); + + NANOCLR_NATIVE_DECLARE(NativeSetClockDivisor___STATIC__VOID__I4__I4__I4__I4); + + + //--// + }; + + struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachineConfig + { + + + + + + + static const int FIELD___outBase = 1; + + + static const int FIELD___outCount = 2; + + + static const int FIELD___setBase = 3; + + + static const int FIELD___setCount = 4; + + + static const int FIELD___sideSetBase = 5; + + + static const int FIELD___inBase = 6; - static const int FIELD___jmpPin = 7; - static const int FIELD___sideSetCount = 8; - static const int FIELD___sideSetOpt = 9; - static const int FIELD___sideSetPinDirs = 10; - static const int FIELD___outShiftDir = 11; - static const int FIELD___autoPull = 12; - static const int FIELD___pullThreshold = 13; - static const int FIELD___inShiftDir = 14; - static const int FIELD___autoPush = 15; - static const int FIELD___pushThreshold = 16; - static const int FIELD___wrapTarget = 17; - static const int FIELD___wrap = 18; - static const int FIELD___clkDivInt = 19; - static const int FIELD___clkDivFrac = 20; - static const int FIELD___fifoJoin = 21; - static const int FIELD___gpioBase = 22; - static const int FIELD___movStatusSel = 23; - static const int FIELD___movStatusN = 24; - static const int FIELD___outSticky = 25; - static const int FIELD___inlineOutEn = 26; - static const int FIELD___outEnSel = 27; + + + + static const int FIELD___inBaseSet = 7; + + + + static const int FIELD___jmpPin = 8; + + + + static const int FIELD___jmpPinSet = 9; + + + + static const int FIELD___sideSetCount = 10; + + + + static const int FIELD___sideSetOpt = 11; + + + + static const int FIELD___sideSetPinDirs = 12; + + + + static const int FIELD___outShiftDir = 13; + + + + static const int FIELD___autoPull = 14; + + + + static const int FIELD___pullThreshold = 15; + + + + static const int FIELD___inShiftDir = 16; + + + + static const int FIELD___autoPush = 17; + + + + static const int FIELD___pushThreshold = 18; + + + + static const int FIELD___wrapTarget = 19; + + + + static const int FIELD___wrap = 20; + + + + static const int FIELD___clkDivInt = 21; + + + + static const int FIELD___clkDivFrac = 22; + + + + static const int FIELD___fifoJoin = 23; + + + + static const int FIELD___gpioBase = 24; + + + + static const int FIELD___movStatusSel = 25; + + + + static const int FIELD___movStatusN = 26; + + + + static const int FIELD___outSticky = 27; + + + + static const int FIELD___inlineOutEn = 28; + + + + static const int FIELD___outEnSel = 29; + + + + + + //--// + }; + + extern const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Pico; + #endif // NANOFRAMEWORK_HARDWARE_PICO_NATIVE_H + diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp index aaa6f5248f..f7d5ce40f5 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp @@ -14,6 +14,12 @@ // busy-wait cap so a stalled SM times out instead of hanging static const unsigned int PIO_FIFO_WAIT_LIMIT = 0x4000000u; +// DMA bulk-read prototype state (one slot per block/sm; channel == -1 when idle) +static int g_PioDmaChannel[3][4] = {{-1, -1, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}}; +static unsigned int *g_PioDmaBuffer[3][4] = {{0}}; +static unsigned int g_PioDmaCount[3][4] = {{0}}; +static unsigned int g_PioDmaClaimed = 0; // bitmap of the 12 DMA channels we hold + // blob indices, must match PioStateMachineConfig.cs enum PioCfgBlob { @@ -524,3 +530,126 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P } NANOCLR_NOCLEANUP(); } + +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeStartDmaRead___STATIC__BOOLEAN__I4__I4__I4(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + { + int block = stack.Arg0().NumericByRef().s4; + int sm = stack.Arg1().NumericByRef().s4; + int count = stack.Arg2().NumericByRef().s4; + + // the PIO RX DREQ is only mapped for PIO0/PIO1 here; PIO2 (RP2350) is out of scope for the prototype + PIO_TypeDef *pio = PioFromIndex(block); + if (pio == nullptr || block > 1 || sm < 0 || sm > 3 || count <= 0 || g_PioDmaChannel[block][sm] >= 0) + { + stack.SetResult_Boolean(false); + NANOCLR_SET_AND_LEAVE(S_OK); + } + + int ch = -1; + for (int c = 0; c < 12; c++) + { + if ((g_PioDmaClaimed & (1u << c)) == 0) + { + g_PioDmaClaimed |= (1u << c); + ch = c; + break; + } + } + if (ch < 0) + { + stack.SetResult_Boolean(false); + NANOCLR_SET_AND_LEAVE(S_OK); + } + + unsigned int *buf = (unsigned int *)platform_malloc((size_t)count * 4); + if (buf == nullptr) + { + g_PioDmaClaimed &= ~(1u << ch); + stack.SetResult_Boolean(false); + NANOCLR_SET_AND_LEAVE(S_OK); + } + + // read = SM RX FIFO (fixed), write = bounce buffer (incrementing), paced by the SM RX DREQ + unsigned int dreq = (block == 0 ? 4u : 12u) + (unsigned int)sm; + DMA->CH[ch].READ_ADDR = (unsigned int)(size_t)&pio->RXF[sm]; + DMA->CH[ch].WRITE_ADDR = (unsigned int)(size_t)buf; + DMA->CH[ch].TRANS_COUNT = (unsigned int)count; + DMA->CH[ch].CTRL_TRIG = DMA_CTRL_TRIG_EN | DMA_CTRL_TRIG_DATA_SIZE_WORD | DMA_CTRL_TRIG_INCR_WRITE | + DMA_CTRL_TRIG_TREQ_SEL(dreq) | DMA_CTRL_TRIG_CHAIN_TO(ch); + + g_PioDmaChannel[block][sm] = ch; + g_PioDmaBuffer[block][sm] = buf; + g_PioDmaCount[block][sm] = (unsigned int)count; + stack.SetResult_Boolean(true); + } + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeDmaReadComplete___STATIC__BOOLEAN__I4__I4(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + { + int block = stack.Arg0().NumericByRef().s4; + int sm = stack.Arg1().NumericByRef().s4; + + bool done = true; + if (block >= 0 && block < 3 && sm >= 0 && sm < 4) + { + int ch = g_PioDmaChannel[block][sm]; + if (ch >= 0) + { + done = (DMA->CH[ch].CTRL_TRIG & DMA_CTRL_TRIG_BUSY) == 0; + } + } + stack.SetResult_Boolean(done); + } + NANOCLR_NOCLEANUP_NOLABEL(); +} + +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeFinishDmaRead___STATIC__I4__I4__I4__SZARRAY_U4__I4(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + { + int block = stack.Arg0().NumericByRef().s4; + int sm = stack.Arg1().NumericByRef().s4; + CLR_RT_HeapBlock_Array *arr = stack.Arg2().DereferenceArray(); + int offset = stack.Arg3().NumericByRef().s4; + + int transferred = 0; + if (block >= 0 && block < 3 && sm >= 0 && sm < 4 && g_PioDmaChannel[block][sm] >= 0) + { + int ch = g_PioDmaChannel[block][sm]; + + // on timeout the channel is still busy; abort it so it can't write after we free the buffer + if (DMA->CH[ch].CTRL_TRIG & DMA_CTRL_TRIG_BUSY) + { + DMA->CHAN_ABORT = (1u << ch); + while (DMA->CHAN_ABORT & (1u << ch)) + { + } + } + + transferred = (int)(g_PioDmaCount[block][sm] - DMA->CH[ch].TRANS_COUNT); + if (transferred < 0) + { + transferred = 0; + } + + if (arr != nullptr && offset >= 0 && transferred > 0 && + (offset + transferred) <= (int)arr->m_numOfElements) + { + memcpy(arr->GetFirstElement() + (size_t)offset * 4, g_PioDmaBuffer[block][sm], (size_t)transferred * 4); + } + + platform_free(g_PioDmaBuffer[block][sm]); + g_PioDmaBuffer[block][sm] = nullptr; + g_PioDmaCount[block][sm] = 0; + g_PioDmaChannel[block][sm] = -1; + g_PioDmaClaimed &= ~(1u << ch); + } + stack.SetResult_I4(transferred); + } + NANOCLR_NOCLEANUP_NOLABEL(); +} From 34dee4f044823133b8b838a9ede82c16e2729c46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Mon, 29 Jun 2026 02:23:44 -0600 Subject: [PATCH 25/58] Update Pico target README PIO examples for the renamed managed enums --- targets/ChibiOS/PICO2_RP2350/README.md | 2 +- targets/ChibiOS/PICO_RP2040/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/targets/ChibiOS/PICO2_RP2350/README.md b/targets/ChibiOS/PICO2_RP2350/README.md index 49f2bfce04..c489342b69 100644 --- a/targets/ChibiOS/PICO2_RP2350/README.md +++ b/targets/ChibiOS/PICO2_RP2350/README.md @@ -146,7 +146,7 @@ var asm = new PioAssembler(); PioLabel loop = asm.DefineLabel(); asm.MarkLabel(loop); asm.Pull(ifEmpty: false, block: true); -asm.Out(PioDest.Pins, 1); +asm.Out(DestinationOperand.Pins, 1); asm.Jmp(PioCondition.Always, loop); PioProgram program = asm.Build(); diff --git a/targets/ChibiOS/PICO_RP2040/README.md b/targets/ChibiOS/PICO_RP2040/README.md index 8dd79b1050..6bb594addb 100644 --- a/targets/ChibiOS/PICO_RP2040/README.md +++ b/targets/ChibiOS/PICO_RP2040/README.md @@ -149,7 +149,7 @@ var asm = new PioAssembler(); PioLabel loop = asm.DefineLabel(); asm.MarkLabel(loop); asm.Pull(ifEmpty: false, block: true); -asm.Out(PioDest.Pins, 1); +asm.Out(DestinationOperand.Pins, 1); asm.Jmp(PioCondition.Always, loop); PioProgram program = asm.Build(); From 7819b8b89f1ccb23e8e6c212a200ebabd60237a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Tue, 30 Jun 2026 21:37:53 -0600 Subject: [PATCH 26/58] Implement PIO NativeRead with a native CLR thread-yield (WaitEvents) Replace the DMA read prototype's start/poll/finish trio with a single re-entrant NativeRead InternalCall: it arms a ChibiOS RP DMA channel (completion callback, not a raw NVIC vector, so no clash with the SPI DMA) and parks the calling thread via CLR_E_THREAD_WAITING until the new SYSTEM_EVENT_FLAG_PICOPIO / Event_PicoPio event fires -- no busy-wait, no CLR starvation. Modeled on the SerialPort driver. --- src/CLR/Core/Hardware/Hardware.cpp | 5 + src/CLR/Include/nanoCLR_Hardware.h | 2 +- src/CLR/Include/nanoCLR_Runtime.h | 1 + src/HAL/Include/nanoHAL_v2.h | 1 + .../nanoFramework_hardware_pico_native.cpp | 14 +- .../nanoFramework_hardware_pico_native.h | 141 ++++++------ ...work_Hardware_Pico_Pio_PioStateMachine.cpp | 203 ++++++++++-------- 7 files changed, 204 insertions(+), 163 deletions(-) diff --git a/src/CLR/Core/Hardware/Hardware.cpp b/src/CLR/Core/Hardware/Hardware.cpp index 8f6c144d8d..7cc54aed26 100644 --- a/src/CLR/Core/Hardware/Hardware.cpp +++ b/src/CLR/Core/Hardware/Hardware.cpp @@ -173,6 +173,11 @@ void CLR_HW_Hardware::ProcessActivity() eventsCLR |= Event_StorageIo; } + if (events & SYSTEM_EVENT_FLAG_PICOPIO) + { + eventsCLR |= Event_PicoPio; + } + if (events & SYSTEM_EVENT_FLAG_RADIO) { eventsCLR |= Event_Radio; diff --git a/src/CLR/Include/nanoCLR_Hardware.h b/src/CLR/Include/nanoCLR_Hardware.h index cae49ba20e..d170ce332b 100644 --- a/src/CLR/Include/nanoCLR_Hardware.h +++ b/src/CLR/Include/nanoCLR_Hardware.h @@ -21,7 +21,7 @@ struct CLR_HW_Hardware { static const CLR_UINT32 c_Default_PowerLevel = PowerLevel__Sleep; static const CLR_UINT32 c_Default_WakeupEvents = - SYSTEM_EVENT_FLAG_COM_IN | SYSTEM_EVENT_FLAG_COM_OUT | SYSTEM_EVENT_FLAG_STORAGE_IO | + SYSTEM_EVENT_FLAG_COM_IN | SYSTEM_EVENT_FLAG_COM_OUT | SYSTEM_EVENT_FLAG_STORAGE_IO | SYSTEM_EVENT_FLAG_PICOPIO | SYSTEM_EVENT_FLAG_SYSTEM_TIMER | SYSTEM_EVENT_FLAG_USB_IN | SYSTEM_EVENT_FLAG_USB_OUT | SYSTEM_EVENT_FLAG_SPI_MASTER | SYSTEM_EVENT_FLAG_I2C_MASTER | SYSTEM_EVENT_FLAG_I2C_SLAVE | SYSTEM_EVENT_HW_INTERRUPT | SYSTEM_EVENT_FLAG_SOCKET | SYSTEM_EVENT_FLAG_DEBUGGER_ACTIVITY | diff --git a/src/CLR/Include/nanoCLR_Runtime.h b/src/CLR/Include/nanoCLR_Runtime.h index 2d1e666eb0..6dc60dfb84 100644 --- a/src/CLR/Include/nanoCLR_Runtime.h +++ b/src/CLR/Include/nanoCLR_Runtime.h @@ -3441,6 +3441,7 @@ typedef enum Events Event_SerialPortIn = 0x00000002, Event_SerialPortOut = 0x00000004, Event_EndPoint = 0x00000008, + Event_PicoPio = 0x00000010, Event_StorageIo = 0x00000020, Event_I2cMaster = 0x00000080, Event_SpiMaster = 0x00000100, diff --git a/src/HAL/Include/nanoHAL_v2.h b/src/HAL/Include/nanoHAL_v2.h index c3a637be4c..c59bf553ca 100644 --- a/src/HAL/Include/nanoHAL_v2.h +++ b/src/HAL/Include/nanoHAL_v2.h @@ -60,6 +60,7 @@ typedef enum SLEEP_LEVEL #define SYSTEM_EVENT_FLAG_COM_IN 0x00000001 #define SYSTEM_EVENT_FLAG_COM_OUT 0x00000002 #define SYSTEM_EVENT_FLAG_STORAGE_IO 0x00000004 +#define SYSTEM_EVENT_FLAG_PICOPIO 0x00000008 #define SYSTEM_EVENT_FLAG_SYSTEM_TIMER 0x00000010 #define SYSTEM_EVENT_FLAG_USB_IN 0x00000020 #define SYSTEM_EVENT_FLAG_USB_OUT 0x00000040 diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp index 3e4a9794a8..e8d1feb80a 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp @@ -3,6 +3,10 @@ // See LICENSE file in the project root for full license information. // + + + + #include "nanoFramework_hardware_pico_native.h" @@ -562,13 +566,7 @@ static const CLR_RT_MethodHandler method_lookup[] = NULL, - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeStartDmaRead___STATIC__BOOLEAN__I4__I4__I4, - - - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeDmaReadComplete___STATIC__BOOLEAN__I4__I4, - - - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeFinishDmaRead___STATIC__I4__I4__I4__SZARRAY_U4__I4, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeRead___STATIC__I4__I4__I4__SZARRAY_U4__I4__I4__I4, Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeInit___STATIC__VOID__I4__I4__I4__SZARRAY_U4, @@ -689,7 +687,7 @@ const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Pico "nanoFramework.Hardware.Pico", - 0x779AF39A, + 0xD87B7417, method_lookup, diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.h b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.h index 8678690814..f1850de94c 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.h +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.h @@ -3,6 +3,33 @@ // See LICENSE file in the project root for full license information. // + + +//----------------------------------------------------------------------------- + +// + +// ** WARNING! ** + +// This file was generated automatically by a tool. + +// Re-running the tool will overwrite this file. + +// You should copy this file to a custom location + +// before adding any customization in the copy to + +// prevent loss of your changes when the tool is + +// re-run. + +// + +//----------------------------------------------------------------------------- + + + + #ifndef NANOFRAMEWORK_HARDWARE_PICO_NATIVE_H #define NANOFRAMEWORK_HARDWARE_PICO_NATIVE_H @@ -22,77 +49,77 @@ -typedef enum __nfpack PioCondition +typedef enum __nfpack DestinationOperand { - PioCondition_Always = 0, + DestinationOperand_Pins = 0, - PioCondition_XZero = 1, + DestinationOperand_RegisterX = 1, - PioCondition_XPostDec = 2, + DestinationOperand_RegisterY = 2, - PioCondition_YZero = 3, + DestinationOperand_DiscardsData = 3, - PioCondition_YPostDec = 4, + DestinationOperand_PinDirs = 4, - PioCondition_XNotEqualY = 5, + DestinationOperand_Pc = 5, - PioCondition_Pin = 6, + DestinationOperand_Status = 5, - PioCondition_OsrNotEmpty = 7, + DestinationOperand_InputShiftRegister = 6, + DestinationOperand_OutputShiftRegister = 7, -} PioCondition; + DestinationOperand_Executes = 7, -typedef enum __nfpack PioDest -{ +} DestinationOperand; - PioDest_Pins = 0, +typedef enum __nfpack PioCondition - PioDest_X = 1, +{ - PioDest_Y = 2, + PioCondition_Always = 0, - PioDest_Null = 3, + PioCondition_XZero = 1, - PioDest_PinDirs = 4, + PioCondition_XPostDec = 2, - PioDest_Pc = 5, + PioCondition_YZero = 3, - PioDest_Status = 5, + PioCondition_YPostDec = 4, - PioDest_Isr = 6, + PioCondition_XNotEqualY = 5, - PioDest_Osr = 7, + PioCondition_Pin = 6, - PioDest_Exec = 7, + PioCondition_OsrNotEmpty = 7, -} PioDest; +} PioCondition; @@ -159,85 +186,85 @@ typedef enum __nfpack PioMovStatusSel -typedef enum __nfpack PioShiftDir +typedef enum __nfpack PioVersion { - PioShiftDir_Left = 0, + PioVersion_Rp2040 = 0, - PioShiftDir_Right = 1, + PioVersion_Rp2350 = 1, -} PioShiftDir; +} PioVersion; -typedef enum __nfpack PioSrc +typedef enum __nfpack PioWaitSource { - PioSrc_Pins = 0, + PioWaitSource_Gpio = 0, - PioSrc_X = 1, + PioWaitSource_Pin = 1, - PioSrc_Y = 2, + PioWaitSource_Irq = 2, - PioSrc_Null = 3, +} PioWaitSource; - PioSrc_Status = 5, - PioSrc_Isr = 6, +typedef enum __nfpack ShiftDirection +{ - PioSrc_Osr = 7, + ShiftDirection_Left = 0, -} PioSrc; + ShiftDirection_Right = 1, -typedef enum __nfpack PioVersion +} ShiftDirection; -{ - PioVersion_Rp2040 = 0, +typedef enum __nfpack SourceOperand +{ - PioVersion_Rp2350 = 1, + SourceOperand_Pins = 0, -} PioVersion; + SourceOperand_RegisterX = 1, + SourceOperand_RegisterY = 2, -typedef enum __nfpack PioWaitSource -{ + SourceOperand_Null = 3, - PioWaitSource_Gpio = 0, + SourceOperand_Status = 5, - PioWaitSource_Pin = 1, + SourceOperand_InputShiftRegister = 6, - PioWaitSource_Irq = 2, + SourceOperand_OutputShiftRegister = 7, -} PioWaitSource; +} SourceOperand; @@ -295,10 +322,10 @@ struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pi - // renamed backing field 'k__BackingField' + // renamed backing field 'k__BackingField' - static const int FIELD__SideSetOpt = 3; + static const int FIELD__SideSetOption = 3; @@ -573,10 +600,10 @@ struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pi - // renamed backing field 'k__BackingField' + // renamed backing field 'k__BackingField' - static const int FIELD__SideSetOpt = 4; + static const int FIELD__SideSetOptional = 4; @@ -684,10 +711,10 @@ struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pi - // renamed backing field 'k__BackingField' + // renamed backing field 'k__BackingField' - static const int FIELD__SideSetOpt = 6; + static const int FIELD__SideSetOptional = 6; @@ -789,13 +816,7 @@ struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pi - NANOCLR_NATIVE_DECLARE(NativeStartDmaRead___STATIC__BOOLEAN__I4__I4__I4); - - - NANOCLR_NATIVE_DECLARE(NativeDmaReadComplete___STATIC__BOOLEAN__I4__I4); - - - NANOCLR_NATIVE_DECLARE(NativeFinishDmaRead___STATIC__I4__I4__I4__SZARRAY_U4__I4); + NANOCLR_NATIVE_DECLARE(NativeRead___STATIC__I4__I4__I4__SZARRAY_U4__I4__I4__I4); NANOCLR_NATIVE_DECLARE(NativeInit___STATIC__VOID__I4__I4__I4__SZARRAY_U4); diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp index f7d5ce40f5..81aea2bb4d 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp @@ -10,15 +10,29 @@ #include "rp2040.h" #endif #include "nanoFramework_hardware_pico_native_target.h" +#include +#include // busy-wait cap so a stalled SM times out instead of hanging static const unsigned int PIO_FIFO_WAIT_LIMIT = 0x4000000u; -// DMA bulk-read prototype state (one slot per block/sm; channel == -1 when idle) -static int g_PioDmaChannel[3][4] = {{-1, -1, -1, -1}, {-1, -1, -1, -1}, {-1, -1, -1, -1}}; -static unsigned int *g_PioDmaBuffer[3][4] = {{0}}; -static unsigned int g_PioDmaCount[3][4] = {{0}}; -static unsigned int g_PioDmaClaimed = 0; // bitmap of the 12 DMA channels we hold +// DMA bulk-read state, one slot per block/sm (Channel == nullptr when idle). The channel is a ChibiOS +// RP DMA descriptor so completion arrives via PioDmaCallback (no raw NVIC vector, no clash with the SPI DMA). +struct PioDmaWork +{ + const rp_dma_channel_t *Channel; + unsigned int *Buffer; + unsigned int Count; +}; +static PioDmaWork g_PioDmaWork[3][4] = {}; + +// DMA completion callback (ChibiOS shared handler dispatches here); just wake the waiting thread +static void PioDmaCallback(void *p, uint32_t ct) +{ + (void)p; + (void)ct; + Events_Set(SYSTEM_EVENT_FLAG_PICOPIO); +} // blob indices, must match PioStateMachineConfig.cs enum PioCfgBlob @@ -531,125 +545,126 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeStartDmaRead___STATIC__BOOLEAN__I4__I4__I4(CLR_RT_StackFrame &stack) +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeRead___STATIC__I4__I4__I4__SZARRAY_U4__I4__I4__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); - { - int block = stack.Arg0().NumericByRef().s4; - int sm = stack.Arg1().NumericByRef().s4; - int count = stack.Arg2().NumericByRef().s4; - // the PIO RX DREQ is only mapped for PIO0/PIO1 here; PIO2 (RP2350) is out of scope for the prototype - PIO_TypeDef *pio = PioFromIndex(block); - if (pio == nullptr || block > 1 || sm < 0 || sm > 3 || count <= 0 || g_PioDmaChannel[block][sm] >= 0) + CLR_RT_HeapBlock hbTimeout; + CLR_INT64 *timeoutTicks; + bool eventResult = true; + int transferred = 0; + + int block = stack.Arg0().NumericByRef().s4; + int sm = stack.Arg1().NumericByRef().s4; + CLR_RT_HeapBlock_Array *arr = stack.Arg2().DereferenceArray(); + int offset = stack.Arg3().NumericByRef().s4; + int count = stack.Arg4().NumericByRef().s4; + int timeoutMs = stack.Arg5().NumericByRef().s4; + + PIO_TypeDef *pio = PioFromIndex(block); + PioDmaWork *work = &g_PioDmaWork[block][sm]; + + // re-established on each re-entry; SetupTimeoutFromTicks pushes hbTimeout once + hbTimeout.SetInteger((CLR_INT64)timeoutMs * TIME_CONVERSION__TO_MILLISECONDS); + NANOCLR_CHECK_HRESULT(stack.SetupTimeoutFromTicks(hbTimeout, timeoutTicks)); + + // first call: validate + arm the DMA + park. jose's pattern: m_customState 1 => setup, 2 => waiting + if (stack.m_customState == 1) + { + // PIO RX DREQ is only mapped for PIO0/PIO1; PIO2 (RP2350) not wired yet + if (pio == nullptr || block > 1 || sm < 0 || sm > 3) { - stack.SetResult_Boolean(false); - NANOCLR_SET_AND_LEAVE(S_OK); + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); } - - int ch = -1; - for (int c = 0; c < 12; c++) + // native ownership check replaces the managed _disposed test + if ((g_PioClaimedSm[block] & (1u << sm)) == 0) { - if ((g_PioDmaClaimed & (1u << c)) == 0) - { - g_PioDmaClaimed |= (1u << c); - ch = c; - break; - } + NANOCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); + } + if (arr == nullptr || count <= 0 || work->Channel != nullptr) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); } - if (ch < 0) + + // ChibiOS-owned DMA channel + completion callback (no raw vector, no clash with the SPI DMA) + const rp_dma_channel_t *ch = dmaChannelAlloc(RP_DMA_CHANNEL_ID_ANY, 3, PioDmaCallback, work); + if (ch == nullptr) { - stack.SetResult_Boolean(false); - NANOCLR_SET_AND_LEAVE(S_OK); + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); } unsigned int *buf = (unsigned int *)platform_malloc((size_t)count * 4); if (buf == nullptr) { - g_PioDmaClaimed &= ~(1u << ch); - stack.SetResult_Boolean(false); - NANOCLR_SET_AND_LEAVE(S_OK); + dmaChannelFree(ch); + NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_MEMORY); } // read = SM RX FIFO (fixed), write = bounce buffer (incrementing), paced by the SM RX DREQ unsigned int dreq = (block == 0 ? 4u : 12u) + (unsigned int)sm; - DMA->CH[ch].READ_ADDR = (unsigned int)(size_t)&pio->RXF[sm]; - DMA->CH[ch].WRITE_ADDR = (unsigned int)(size_t)buf; - DMA->CH[ch].TRANS_COUNT = (unsigned int)count; - DMA->CH[ch].CTRL_TRIG = DMA_CTRL_TRIG_EN | DMA_CTRL_TRIG_DATA_SIZE_WORD | DMA_CTRL_TRIG_INCR_WRITE | - DMA_CTRL_TRIG_TREQ_SEL(dreq) | DMA_CTRL_TRIG_CHAIN_TO(ch); - - g_PioDmaChannel[block][sm] = ch; - g_PioDmaBuffer[block][sm] = buf; - g_PioDmaCount[block][sm] = (unsigned int)count; - stack.SetResult_Boolean(true); + ch->channel->READ_ADDR = (unsigned int)(size_t)&pio->RXF[sm]; + ch->channel->WRITE_ADDR = (unsigned int)(size_t)buf; + ch->channel->TRANS_COUNT = (unsigned int)count; + dmaChannelEnableInterruptX(ch); + ch->channel->CTRL_TRIG = DMA_CTRL_TRIG_EN | DMA_CTRL_TRIG_DATA_SIZE_WORD | DMA_CTRL_TRIG_INCR_WRITE | + DMA_CTRL_TRIG_TREQ_SEL(dreq) | DMA_CTRL_TRIG_CHAIN_TO(ch->chnidx); + + work->Channel = ch; + work->Buffer = buf; + work->Count = (unsigned int)count; + + Events_Get(SYSTEM_EVENT_FLAG_PICOPIO); + stack.m_customState = 2; } - NANOCLR_NOCLEANUP(); -} -HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeDmaReadComplete___STATIC__BOOLEAN__I4__I4(CLR_RT_StackFrame &stack) -{ - NANOCLR_HEADER(); + // wait on the shared PICOPIO event; re-check OUR channel's busy bit each wake (shared-event safe) + while (work->Channel != nullptr && dmaChannelIsBusyX(work->Channel)) { - int block = stack.Arg0().NumericByRef().s4; - int sm = stack.Arg1().NumericByRef().s4; - - bool done = true; - if (block >= 0 && block < 3 && sm >= 0 && sm < 4) + NANOCLR_CHECK_HRESULT( + g_CLR_RT_ExecutionEngine.WaitEvents(stack.m_owningThread, *timeoutTicks, Event_PicoPio, eventResult)); + if (!eventResult) { - int ch = g_PioDmaChannel[block][sm]; - if (ch >= 0) - { - done = (DMA->CH[ch].CTRL_TRIG & DMA_CTRL_TRIG_BUSY) == 0; - } + // timed out; the finish path below aborts the channel + break; } - stack.SetResult_Boolean(done); } - NANOCLR_NOCLEANUP_NOLABEL(); -} -HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeFinishDmaRead___STATIC__I4__I4__I4__SZARRAY_U4__I4(CLR_RT_StackFrame &stack) -{ - NANOCLR_HEADER(); + if (work->Channel != nullptr) { - int block = stack.Arg0().NumericByRef().s4; - int sm = stack.Arg1().NumericByRef().s4; - CLR_RT_HeapBlock_Array *arr = stack.Arg2().DereferenceArray(); - int offset = stack.Arg3().NumericByRef().s4; + const rp_dma_channel_t *ch = work->Channel; - int transferred = 0; - if (block >= 0 && block < 3 && sm >= 0 && sm < 4 && g_PioDmaChannel[block][sm] >= 0) + // on timeout the channel is still busy; stop it so it can't write after we free the buffer + if (dmaChannelIsBusyX(ch)) { - int ch = g_PioDmaChannel[block][sm]; - - // on timeout the channel is still busy; abort it so it can't write after we free the buffer - if (DMA->CH[ch].CTRL_TRIG & DMA_CTRL_TRIG_BUSY) - { - DMA->CHAN_ABORT = (1u << ch); - while (DMA->CHAN_ABORT & (1u << ch)) - { - } - } - - transferred = (int)(g_PioDmaCount[block][sm] - DMA->CH[ch].TRANS_COUNT); - if (transferred < 0) - { - transferred = 0; - } - - if (arr != nullptr && offset >= 0 && transferred > 0 && - (offset + transferred) <= (int)arr->m_numOfElements) + ch->channel->CTRL_TRIG &= ~DMA_CTRL_TRIG_EN; + DMA->CHAN_ABORT = (1u << ch->chnidx); + while (DMA->CHAN_ABORT & (1u << ch->chnidx)) { - memcpy(arr->GetFirstElement() + (size_t)offset * 4, g_PioDmaBuffer[block][sm], (size_t)transferred * 4); } + } - platform_free(g_PioDmaBuffer[block][sm]); - g_PioDmaBuffer[block][sm] = nullptr; - g_PioDmaCount[block][sm] = 0; - g_PioDmaChannel[block][sm] = -1; - g_PioDmaClaimed &= ~(1u << ch); + transferred = (int)(work->Count - ch->channel->TRANS_COUNT); + if (transferred < 0) + { + transferred = 0; } - stack.SetResult_I4(transferred); + if (arr != nullptr && offset >= 0 && transferred > 0 && + (offset + transferred) <= (int)arr->m_numOfElements) + { + memcpy(arr->GetFirstElement() + (size_t)offset * 4, work->Buffer, (size_t)transferred * 4); + } + + (void)dmaChannelGetAndClearInterrupts(ch); + dmaChannelFree(ch); + platform_free(work->Buffer); + work->Channel = nullptr; + work->Buffer = nullptr; + work->Count = 0; } - NANOCLR_NOCLEANUP_NOLABEL(); + + // pop the timeout heap block and return the word count actually transferred + stack.PopValue(); + stack.SetResult_I4(transferred); + + NANOCLR_NOCLEANUP(); } From 6b4fc07245772cbbb2422a960b8a00485e0884cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Wed, 1 Jul 2026 13:02:17 -0600 Subject: [PATCH 27/58] Implement PIO NativeWrite (TX mirror of NativeRead) Adds the NativeWrite re-entrant handler (independent TX work slots, ChibiOS DMA channel + completion callback, WaitEvents yield) and regenerates the interop table/header at checksum 0x52CD0E56. --- .../nanoFramework_hardware_pico_native.cpp | 8 +- .../nanoFramework_hardware_pico_native.h | 3 + ...work_Hardware_Pico_Pio_PioStateMachine.cpp | 127 ++++++++++++++++++ 3 files changed, 137 insertions(+), 1 deletion(-) diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp index e8d1feb80a..54e0f690d2 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp @@ -566,9 +566,15 @@ static const CLR_RT_MethodHandler method_lookup[] = NULL, + NULL, + + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeRead___STATIC__I4__I4__I4__SZARRAY_U4__I4__I4__I4, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeWrite___STATIC__I4__I4__I4__SZARRAY_U4__I4__I4__I4, + + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeInit___STATIC__VOID__I4__I4__I4__SZARRAY_U4, @@ -687,7 +693,7 @@ const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Pico "nanoFramework.Hardware.Pico", - 0xD87B7417, + 0x52CD0E56, method_lookup, diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.h b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.h index f1850de94c..e4af11ac5c 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.h +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.h @@ -819,6 +819,9 @@ struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pi NANOCLR_NATIVE_DECLARE(NativeRead___STATIC__I4__I4__I4__SZARRAY_U4__I4__I4__I4); + NANOCLR_NATIVE_DECLARE(NativeWrite___STATIC__I4__I4__I4__SZARRAY_U4__I4__I4__I4); + + NANOCLR_NATIVE_DECLARE(NativeInit___STATIC__VOID__I4__I4__I4__SZARRAY_U4); diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp index 81aea2bb4d..9e0f022af4 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp @@ -26,6 +26,9 @@ struct PioDmaWork }; static PioDmaWork g_PioDmaWork[3][4] = {}; +// Independent TX slots so a Write can run concurrently with a Read on the same state machine. +static PioDmaWork g_PioDmaWorkTx[3][4] = {}; + // DMA completion callback (ChibiOS shared handler dispatches here); just wake the waiting thread static void PioDmaCallback(void *p, uint32_t ct) { @@ -668,3 +671,127 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NANOCLR_NOCLEANUP(); } + +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeWrite___STATIC__I4__I4__I4__SZARRAY_U4__I4__I4__I4(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + CLR_RT_HeapBlock hbTimeout; + CLR_INT64 *timeoutTicks; + bool eventResult = true; + int transferred = 0; + + int block = stack.Arg0().NumericByRef().s4; + int sm = stack.Arg1().NumericByRef().s4; + CLR_RT_HeapBlock_Array *arr = stack.Arg2().DereferenceArray(); + int offset = stack.Arg3().NumericByRef().s4; + int count = stack.Arg4().NumericByRef().s4; + int timeoutMs = stack.Arg5().NumericByRef().s4; + + PIO_TypeDef *pio = PioFromIndex(block); + PioDmaWork *work = &g_PioDmaWorkTx[block][sm]; + + // re-established on each re-entry; SetupTimeoutFromTicks pushes hbTimeout once + hbTimeout.SetInteger((CLR_INT64)timeoutMs * TIME_CONVERSION__TO_MILLISECONDS); + NANOCLR_CHECK_HRESULT(stack.SetupTimeoutFromTicks(hbTimeout, timeoutTicks)); + + // first call: validate + copy out + arm the DMA + park. jose's pattern: m_customState 1 => setup, 2 => waiting + if (stack.m_customState == 1) + { + // PIO TX DREQ is only mapped for PIO0/PIO1; PIO2 (RP2350) not wired yet + if (pio == nullptr || block > 1 || sm < 0 || sm > 3) + { + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); + } + // native ownership check replaces the managed _disposed test + if ((g_PioClaimedSm[block] & (1u << sm)) == 0) + { + NANOCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); + } + if (arr == nullptr || count <= 0 || work->Channel != nullptr || offset < 0 || + (offset + count) > (int)arr->m_numOfElements) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + + // ChibiOS-owned DMA channel + completion callback (no raw vector, no clash with the SPI DMA) + const rp_dma_channel_t *ch = dmaChannelAlloc(RP_DMA_CHANNEL_ID_ANY, 3, PioDmaCallback, work); + if (ch == nullptr) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + + unsigned int *buf = (unsigned int *)platform_malloc((size_t)count * 4); + if (buf == nullptr) + { + dmaChannelFree(ch); + NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_MEMORY); + } + + // copy the words out into the bounce buffer before the DMA drains it into the TX FIFO + memcpy(buf, arr->GetFirstElement() + (size_t)offset * 4, (size_t)count * 4); + + // read = bounce buffer (incrementing), write = SM TX FIFO (fixed), paced by the SM TX DREQ + unsigned int dreq = (block == 0 ? 0u : 8u) + (unsigned int)sm; + ch->channel->READ_ADDR = (unsigned int)(size_t)buf; + ch->channel->WRITE_ADDR = (unsigned int)(size_t)&pio->TXF[sm]; + ch->channel->TRANS_COUNT = (unsigned int)count; + dmaChannelEnableInterruptX(ch); + ch->channel->CTRL_TRIG = DMA_CTRL_TRIG_EN | DMA_CTRL_TRIG_DATA_SIZE_WORD | DMA_CTRL_TRIG_INCR_READ | + DMA_CTRL_TRIG_TREQ_SEL(dreq) | DMA_CTRL_TRIG_CHAIN_TO(ch->chnidx); + + work->Channel = ch; + work->Buffer = buf; + work->Count = (unsigned int)count; + + Events_Get(SYSTEM_EVENT_FLAG_PICOPIO); + stack.m_customState = 2; + } + + // wait on the shared PICOPIO event; re-check OUR channel's busy bit each wake (shared-event safe) + while (work->Channel != nullptr && dmaChannelIsBusyX(work->Channel)) + { + NANOCLR_CHECK_HRESULT( + g_CLR_RT_ExecutionEngine.WaitEvents(stack.m_owningThread, *timeoutTicks, Event_PicoPio, eventResult)); + if (!eventResult) + { + // timed out; the finish path below aborts the channel + break; + } + } + + if (work->Channel != nullptr) + { + const rp_dma_channel_t *ch = work->Channel; + + // on timeout the channel is still busy; stop it so it can't read after we free the buffer + if (dmaChannelIsBusyX(ch)) + { + ch->channel->CTRL_TRIG &= ~DMA_CTRL_TRIG_EN; + DMA->CHAN_ABORT = (1u << ch->chnidx); + while (DMA->CHAN_ABORT & (1u << ch->chnidx)) + { + } + } + + // data already went out to the TX FIFO -- nothing to copy back + transferred = (int)(work->Count - ch->channel->TRANS_COUNT); + if (transferred < 0) + { + transferred = 0; + } + + (void)dmaChannelGetAndClearInterrupts(ch); + dmaChannelFree(ch); + platform_free(work->Buffer); + work->Channel = nullptr; + work->Buffer = nullptr; + work->Count = 0; + } + + // pop the timeout heap block and return the word count actually transferred + stack.PopValue(); + stack.SetResult_I4(transferred); + + NANOCLR_NOCLEANUP(); +} From 1fb0893f553603d458361230ffe5f969ddd407f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Wed, 1 Jul 2026 17:02:14 -0600 Subject: [PATCH 28/58] Trim NativeRead/NativeWrite comments per review Drop the common-pattern timeout explanation and the maintainer-name aside from the re-entry comments. --- ...tive_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp index 9e0f022af4..eb7f5293be 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp @@ -567,11 +567,10 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P PIO_TypeDef *pio = PioFromIndex(block); PioDmaWork *work = &g_PioDmaWork[block][sm]; - // re-established on each re-entry; SetupTimeoutFromTicks pushes hbTimeout once hbTimeout.SetInteger((CLR_INT64)timeoutMs * TIME_CONVERSION__TO_MILLISECONDS); NANOCLR_CHECK_HRESULT(stack.SetupTimeoutFromTicks(hbTimeout, timeoutTicks)); - // first call: validate + arm the DMA + park. jose's pattern: m_customState 1 => setup, 2 => waiting + // first call: validate + arm the DMA + park if (stack.m_customState == 1) { // PIO RX DREQ is only mapped for PIO0/PIO1; PIO2 (RP2350) not wired yet @@ -691,11 +690,10 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P PIO_TypeDef *pio = PioFromIndex(block); PioDmaWork *work = &g_PioDmaWorkTx[block][sm]; - // re-established on each re-entry; SetupTimeoutFromTicks pushes hbTimeout once hbTimeout.SetInteger((CLR_INT64)timeoutMs * TIME_CONVERSION__TO_MILLISECONDS); NANOCLR_CHECK_HRESULT(stack.SetupTimeoutFromTicks(hbTimeout, timeoutTicks)); - // first call: validate + copy out + arm the DMA + park. jose's pattern: m_customState 1 => setup, 2 => waiting + // first call: validate + copy out + arm the DMA + park if (stack.m_customState == 1) { // PIO TX DREQ is only mapped for PIO0/PIO1; PIO2 (RP2350) not wired yet From 4f32d28d03b390a943e6fbc4fa47170528991ff2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Sat, 11 Jul 2026 02:32:04 -0600 Subject: [PATCH 29/58] Name the FSTAT status bits in the PIO state-machine native Replace the bare 8/16 shift bases used to test FSTAT RXEMPTY/TXFULL with named constants (PIO_FSTAT_RXEMPTY_LSB / PIO_FSTAT_TXFULL_LSB) so the FIFO-status checks are self-explanatory. --- ...noFramework_Hardware_Pico_Pio_PioStateMachine.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp index eb7f5293be..31e0131d9b 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp @@ -13,6 +13,10 @@ #include #include +// PIO FSTAT: RXEMPTY [11:8], TXFULL [19:16] -- one status bit per state machine +#define PIO_FSTAT_RXEMPTY_LSB 8u +#define PIO_FSTAT_TXFULL_LSB 16u + // busy-wait cap so a stalled SM times out instead of hanging static const unsigned int PIO_FIFO_WAIT_LIMIT = 0x4000000u; @@ -191,7 +195,7 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P // FSTAT TX_FULL = bits [19:16] unsigned int guard = PIO_FIFO_WAIT_LIMIT; - while ((pio->FSTAT & (1u << (16 + sm))) && --guard) + while ((pio->FSTAT & (1u << (PIO_FSTAT_TXFULL_LSB + sm))) && --guard) { } if (guard == 0) @@ -220,7 +224,7 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P // FSTAT RX_EMPTY = bits [11:8] unsigned int guard = PIO_FIFO_WAIT_LIMIT; - while ((pio->FSTAT & (1u << (8 + sm))) && --guard) + while ((pio->FSTAT & (1u << (PIO_FSTAT_RXEMPTY_LSB + sm))) && --guard) { } if (guard == 0) @@ -247,7 +251,7 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P } PioEnsureOutOfReset(block); - stack.SetResult_Boolean((pio->FSTAT & (1u << (16 + sm))) != 0); + stack.SetResult_Boolean((pio->FSTAT & (1u << (PIO_FSTAT_TXFULL_LSB + sm))) != 0); } NANOCLR_NOCLEANUP(); } @@ -267,7 +271,7 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P } PioEnsureOutOfReset(block); - stack.SetResult_Boolean((pio->FSTAT & (1u << (8 + sm))) != 0); + stack.SetResult_Boolean((pio->FSTAT & (1u << (PIO_FSTAT_RXEMPTY_LSB + sm))) != 0); } NANOCLR_NOCLEANUP(); } From 3e1d438a7c0e9e8180d382f51983b21eebbb35b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Thu, 23 Jul 2026 19:25:00 -0600 Subject: [PATCH 30/58] Delete the double new lines generated by the stub generator --- .../nanoFramework_hardware_pico_native.cpp | 471 +---------- .../nanoFramework_hardware_pico_native.h | 777 +----------------- 2 files changed, 5 insertions(+), 1243 deletions(-) diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp index 54e0f690d2..b32992814e 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp @@ -3,706 +3,237 @@ // See LICENSE file in the project root for full license information. // - - - - #include "nanoFramework_hardware_pico_native.h" - - // clang-format off - - - static const CLR_RT_MethodHandler method_lookup[] = - { - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::NativeAddProgram___STATIC__I4__I4__SZARRAY_U2__I4__I4, - - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::NativeRemoveProgram___STATIC__VOID__I4__I4__I4, - - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::NativeClaimUnusedSm___STATIC__I4__I4__BOOLEAN, - - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::NativeInitGpio___STATIC__VOID__I4__I4, - - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::NativeForceIrq___STATIC__VOID__I4__I4, - - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::NativeClearIrq___STATIC__VOID__I4__I4, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeRead___STATIC__I4__I4__I4__SZARRAY_U4__I4__I4__I4, - - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeWrite___STATIC__I4__I4__I4__SZARRAY_U4__I4__I4__I4, - - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeInit___STATIC__VOID__I4__I4__I4__SZARRAY_U4, - - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeSetEnabled___STATIC__VOID__I4__I4__BOOLEAN, - - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativePutBlocking___STATIC__VOID__I4__I4__U4, - - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeGetBlocking___STATIC__U4__I4__I4, - - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeTxFull___STATIC__BOOLEAN__I4__I4, - - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeRxEmpty___STATIC__BOOLEAN__I4__I4, - - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeUnclaim___STATIC__VOID__I4__I4, - - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeSetConsecutivePinDirs___STATIC__VOID__I4__I4__I4__I4__BOOLEAN, - - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeClearFifos___STATIC__VOID__I4__I4, - - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeDrainTxFifo___STATIC__VOID__I4__I4, - - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeRestart___STATIC__VOID__I4__I4, - - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeClkDivRestart___STATIC__VOID__I4__I4, - - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeExec___STATIC__VOID__I4__I4__U2, - - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeTxLevel___STATIC__U4__I4__I4, - - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeRxLevel___STATIC__U4__I4__I4, - - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeGetPc___STATIC__U4__I4__I4, - - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeSetClockDivisor___STATIC__VOID__I4__I4__I4__I4, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - NULL, - - }; - - const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Pico = - { - - "nanoFramework.Hardware.Pico", - - 0x52CD0E56, - - method_lookup, - - { 1, 0, 0, 0 } - + "nanoFramework.Hardware.Pico",0x52CD0E56,method_lookup,{ 1, 0, 0, 0 } }; - - // clang-format on - - diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.h b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.h index e4af11ac5c..f90d6e4a64 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.h +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.h @@ -3,1022 +3,253 @@ // See LICENSE file in the project root for full license information. // - - -//----------------------------------------------------------------------------- - -// - -// ** WARNING! ** - -// This file was generated automatically by a tool. - -// Re-running the tool will overwrite this file. - -// You should copy this file to a custom location - -// before adding any customization in the copy to - -// prevent loss of your changes when the tool is - -// re-run. - -// - -//----------------------------------------------------------------------------- - - - - #ifndef NANOFRAMEWORK_HARDWARE_PICO_NATIVE_H - #define NANOFRAMEWORK_HARDWARE_PICO_NATIVE_H - - - #include - #include - #include - - #include - - - - typedef enum __nfpack DestinationOperand - { - - DestinationOperand_Pins = 0, - - DestinationOperand_RegisterX = 1, - - DestinationOperand_RegisterY = 2, - - DestinationOperand_DiscardsData = 3, - - DestinationOperand_PinDirs = 4, - - DestinationOperand_Pc = 5, - - DestinationOperand_Status = 5, - - DestinationOperand_InputShiftRegister = 6, - - DestinationOperand_OutputShiftRegister = 7, - - DestinationOperand_Executes = 7, - - - } DestinationOperand; - - typedef enum __nfpack PioCondition - { - - PioCondition_Always = 0, - - PioCondition_XZero = 1, - - PioCondition_XPostDec = 2, - - PioCondition_YZero = 3, - - PioCondition_YPostDec = 4, - - PioCondition_XNotEqualY = 5, - - PioCondition_Pin = 6, - - PioCondition_OsrNotEmpty = 7, - - - } PioCondition; - - typedef enum __nfpack PioFifoJoin - { - - PioFifoJoin_None = 0, - - PioFifoJoin_Tx = 1, - - PioFifoJoin_Rx = 2, - - PioFifoJoin_TxGet = 4, - - PioFifoJoin_TxPut = 8, - - PioFifoJoin_PutGet = 12, - - - } PioFifoJoin; - - typedef enum __nfpack PioMovOp - { - - PioMovOp_None = 0, - - PioMovOp_Invert = 1, - - PioMovOp_BitReverse = 2, - - - } PioMovOp; - - typedef enum __nfpack PioMovStatusSel - { - - PioMovStatusSel_TxLevel = 0, - - PioMovStatusSel_RxLevel = 1, - - - } PioMovStatusSel; - - typedef enum __nfpack PioVersion - { - - PioVersion_Rp2040 = 0, - - PioVersion_Rp2350 = 1, - - - } PioVersion; - - typedef enum __nfpack PioWaitSource - { - - PioWaitSource_Gpio = 0, - - PioWaitSource_Pin = 1, - - PioWaitSource_Irq = 2, - - - } PioWaitSource; - - typedef enum __nfpack ShiftDirection - { - - ShiftDirection_Left = 0, - - ShiftDirection_Right = 1, - - - } ShiftDirection; - - typedef enum __nfpack SourceOperand - { - - SourceOperand_Pins = 0, - - SourceOperand_RegisterX = 1, - - SourceOperand_RegisterY = 2, - - SourceOperand_Null = 3, - - SourceOperand_Status = 5, - - SourceOperand_InputShiftRegister = 6, - - SourceOperand_OutputShiftRegister = 7, - - - } SourceOperand; - - - - struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_Pio - { - - - - static const int FIELD_STATIC___blocks = 0; - - - static const int FIELD_STATIC___lock = 1; - - - - - - - - - - - //--// - }; - - struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioAssemblerOptions - { - - - - - - - - // renamed backing field 'k__BackingField' - - static const int FIELD__Version = 1; - - - - // renamed backing field 'k__BackingField' - - static const int FIELD__SideSetCount = 2; - - - - // renamed backing field 'k__BackingField' - - static const int FIELD__SideSetOption = 3; - - - - // renamed backing field 'k__BackingField' - - static const int FIELD__SideSetPinDirs = 4; - - - - - - - - //--// - }; - - struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioInstructionRef - { - - - - - - - static const int FIELD___owner = 1; - - - static const int FIELD___index = 2; - - - - - - - - //--// - }; - - struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioLabel - { - - - - - - - - // renamed backing field 'k__BackingField' - - - static const int FIELD__Id = 1; - - - - // renamed backing field 'k__BackingField' - - - static const int FIELD__Owner = 2; - - - - // renamed backing field '
k__BackingField' - - - static const int FIELD__Address = 3; - - - - - - - - //--// - -}; - - + static const int FIELD__Id = 1; + static const int FIELD__Owner = 2; + static const int FIELD__Address = 3; +}; struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioAssembler - { - - - - - - - static const int FIELD___baseBits = 1; - - - static const int FIELD___delay = 2; - - - static const int FIELD___sideValue = 3; - - - static const int FIELD___sideUsed = 4; - - - static const int FIELD___jmpLabel = 5; - - - static const int FIELD___count = 6; - - - static const int FIELD___labelCount = 7; - - - static const int FIELD___version = 8; - - - static const int FIELD___sideSetCount = 9; - - - static const int FIELD___sideSetOpt = 10; - - - static const int FIELD___sideSetPinDirs = 11; - - - static const int FIELD___wrapTarget = 12; - - - static const int FIELD___wrap = 13; - - - static const int FIELD___origin = 14; - - - static const int FIELD___outShiftDir = 15; - - - static const int FIELD___autoPull = 16; - - - static const int FIELD___pullThreshold = 17; - - - static const int FIELD___inShiftDir = 18; - - - static const int FIELD___autoPush = 19; - - - static const int FIELD___pushThreshold = 20; - - - - - - - - //--// - }; - - struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock - { - - - - - - - static const int FIELD___index = 1; - - - static const int FIELD___irqDispatcher = 2; - - - static const int FIELD___interruptCallbacks = 3; - - - static const int FIELD___irqLock = 4; - - - - NANOCLR_NATIVE_DECLARE(NativeAddProgram___STATIC__I4__I4__SZARRAY_U2__I4__I4); - - NANOCLR_NATIVE_DECLARE(NativeRemoveProgram___STATIC__VOID__I4__I4__I4); - - NANOCLR_NATIVE_DECLARE(NativeClaimUnusedSm___STATIC__I4__I4__BOOLEAN); - - NANOCLR_NATIVE_DECLARE(NativeInitGpio___STATIC__VOID__I4__I4); - - NANOCLR_NATIVE_DECLARE(NativeForceIrq___STATIC__VOID__I4__I4); - - NANOCLR_NATIVE_DECLARE(NativeClearIrq___STATIC__VOID__I4__I4); - - - - - //--// - }; - - struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioProgramOptions - { - - - - - - - - // renamed backing field 'k__BackingField' - - static const int FIELD__Version = 1; - - - - // renamed backing field 'k__BackingField' - - static const int FIELD__Origin = 2; - - - - // renamed backing field 'k__BackingField' - - static const int FIELD__SideSetCount = 3; - - - - // renamed backing field 'k__BackingField' - - static const int FIELD__SideSetOptional = 4; - - - - // renamed backing field 'k__BackingField' - - static const int FIELD__SideSetPinDirs = 5; - - - - // renamed backing field 'k__BackingField' - - static const int FIELD__OutShiftDir = 6; - - - - // renamed backing field 'k__BackingField' - - static const int FIELD__AutoPull = 7; - - - - // renamed backing field 'k__BackingField' - - static const int FIELD__PullThreshold = 8; - - - - // renamed backing field 'k__BackingField' - - static const int FIELD__InShiftDir = 9; - - - - // renamed backing field 'k__BackingField' - - static const int FIELD__AutoPush = 10; - - - - // renamed backing field 'k__BackingField' - - static const int FIELD__PushThreshold = 11; - - - - - - - - //--// - }; - - struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioProgram - { - - - - - - - - // renamed backing field 'k__BackingField' - - static const int FIELD__Instructions = 1; - - - - // renamed backing field 'k__BackingField' - - static const int FIELD__Wrap = 2; - - - - // renamed backing field 'k__BackingField' - - static const int FIELD__WrapTarget = 3; - - - - // renamed backing field 'k__BackingField' - - static const int FIELD__Origin = 4; - - - - // renamed backing field 'k__BackingField' - - static const int FIELD__SideSetCount = 5; - - - - // renamed backing field 'k__BackingField' - - static const int FIELD__SideSetOptional = 6; - - - - // renamed backing field 'k__BackingField' - - static const int FIELD__SideSetPinDirs = 7; - - - - // renamed backing field 'k__BackingField' - - static const int FIELD__OutShiftDir = 8; - - - - // renamed backing field 'k__BackingField' - - static const int FIELD__AutoPull = 9; - - - - // renamed backing field 'k__BackingField' - - static const int FIELD__PullThreshold = 10; - - - - // renamed backing field 'k__BackingField' - - static const int FIELD__InShiftDir = 11; - - - - // renamed backing field 'k__BackingField' - - static const int FIELD__AutoPush = 12; - - - - // renamed backing field 'k__BackingField' - - static const int FIELD__PushThreshold = 13; - - - - // renamed backing field 'k__BackingField' - - static const int FIELD__Version = 14; - - - - - - - - //--// - }; - - struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine - { - - - - - - - static const int FIELD___block = 1; - - - static const int FIELD___sm = 2; - - - static const int FIELD___owned = 3; - - - static const int FIELD___disposed = 4; - - - static const int FIELD___enabled = 5; - - - - NANOCLR_NATIVE_DECLARE(NativeRead___STATIC__I4__I4__I4__SZARRAY_U4__I4__I4__I4); - - NANOCLR_NATIVE_DECLARE(NativeWrite___STATIC__I4__I4__I4__SZARRAY_U4__I4__I4__I4); - - NANOCLR_NATIVE_DECLARE(NativeInit___STATIC__VOID__I4__I4__I4__SZARRAY_U4); - - NANOCLR_NATIVE_DECLARE(NativeSetEnabled___STATIC__VOID__I4__I4__BOOLEAN); - - NANOCLR_NATIVE_DECLARE(NativePutBlocking___STATIC__VOID__I4__I4__U4); - - NANOCLR_NATIVE_DECLARE(NativeGetBlocking___STATIC__U4__I4__I4); - - NANOCLR_NATIVE_DECLARE(NativeTxFull___STATIC__BOOLEAN__I4__I4); - - NANOCLR_NATIVE_DECLARE(NativeRxEmpty___STATIC__BOOLEAN__I4__I4); - - NANOCLR_NATIVE_DECLARE(NativeUnclaim___STATIC__VOID__I4__I4); - - NANOCLR_NATIVE_DECLARE(NativeSetConsecutivePinDirs___STATIC__VOID__I4__I4__I4__I4__BOOLEAN); - - NANOCLR_NATIVE_DECLARE(NativeClearFifos___STATIC__VOID__I4__I4); - - NANOCLR_NATIVE_DECLARE(NativeDrainTxFifo___STATIC__VOID__I4__I4); - - NANOCLR_NATIVE_DECLARE(NativeRestart___STATIC__VOID__I4__I4); - - NANOCLR_NATIVE_DECLARE(NativeClkDivRestart___STATIC__VOID__I4__I4); - - NANOCLR_NATIVE_DECLARE(NativeExec___STATIC__VOID__I4__I4__U2); - - NANOCLR_NATIVE_DECLARE(NativeTxLevel___STATIC__U4__I4__I4); - - NANOCLR_NATIVE_DECLARE(NativeRxLevel___STATIC__U4__I4__I4); - - NANOCLR_NATIVE_DECLARE(NativeGetPc___STATIC__U4__I4__I4); - - NANOCLR_NATIVE_DECLARE(NativeSetClockDivisor___STATIC__VOID__I4__I4__I4__I4); - - - - - //--// - }; - - struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachineConfig - { - - - - - - - static const int FIELD___outBase = 1; - - - static const int FIELD___outCount = 2; - - - static const int FIELD___setBase = 3; - - - static const int FIELD___setCount = 4; - - - static const int FIELD___sideSetBase = 5; - - - static const int FIELD___inBase = 6; - - - static const int FIELD___inBaseSet = 7; - - - static const int FIELD___jmpPin = 8; - - - static const int FIELD___jmpPinSet = 9; - - - static const int FIELD___sideSetCount = 10; - - - static const int FIELD___sideSetOpt = 11; - - - static const int FIELD___sideSetPinDirs = 12; - - - static const int FIELD___outShiftDir = 13; - - - static const int FIELD___autoPull = 14; - - - static const int FIELD___pullThreshold = 15; - - - static const int FIELD___inShiftDir = 16; - - - static const int FIELD___autoPush = 17; - - - static const int FIELD___pushThreshold = 18; - - - static const int FIELD___wrapTarget = 19; - - - static const int FIELD___wrap = 20; - - - static const int FIELD___clkDivInt = 21; - - - static const int FIELD___clkDivFrac = 22; - - - static const int FIELD___fifoJoin = 23; - - - static const int FIELD___gpioBase = 24; - - - static const int FIELD___movStatusSel = 25; - - - static const int FIELD___movStatusN = 26; - - - static const int FIELD___outSticky = 27; - - - static const int FIELD___inlineOutEn = 28; - - - static const int FIELD___outEnSel = 29; - - - - - - - - //--// - }; - - extern const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Pico; - #endif // NANOFRAMEWORK_HARDWARE_PICO_NATIVE_H - From c36f3780c64c77bc19ba373a9eebdb94da322ac3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Thu, 23 Jul 2026 20:44:21 -0600 Subject: [PATCH 31/58] Clean up PIO native code for type safety and style consistency --- ...noFramework_Hardware_Pico_Pio_PioBlock.cpp | 242 +++--- ...work_Hardware_Pico_Pio_PioStateMachine.cpp | 686 +++++++++--------- 2 files changed, 476 insertions(+), 452 deletions(-) diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp index c1d9820687..e66dd07c28 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp @@ -45,8 +45,8 @@ void PioEnsureOutOfReset(int blockIndex) return; } - unsigned int bits = - (1u << (PIO_RESET_LSB + (unsigned int)blockIndex)) | IO_BANK0_RESET_BIT | PADS_BANK0_RESET_BIT; + const unsigned int bits = + (1u << (PIO_RESET_LSB + static_cast(blockIndex))) | IO_BANK0_RESET_BIT | PADS_BANK0_RESET_BIT; RESETS->CLR.RESET = bits; // atomic-clear alias while ((RESETS->RESET_DONE & bits) != bits) { @@ -59,62 +59,65 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NativeAddProgram___STATIC__I4__I4__SZARRAY_U2__I4__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); - { - int block = stack.Arg0().NumericByRef().s4; - CLR_RT_HeapBlock_Array *instrArray = stack.Arg1().DereferenceArray(); - int length = stack.Arg2().NumericByRef().s4; - int origin = stack.Arg3().NumericByRef().s4; - if (PioFromIndex(block) == nullptr || block < 0 || block > 2 || instrArray == nullptr || - length <= 0 || length > 32 || (int)instrArray->m_numOfElements < length) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } + PIO_TypeDef *pio; + unsigned short *instr; + int offset; + bool relocate; - PIO_TypeDef *pio = PioFromIndex(block); - unsigned short *instr = (unsigned short *)instrArray->GetFirstElement(); - PioEnsureOutOfReset(block); + const int block = stack.Arg0().NumericByRef().s4; + CLR_RT_HeapBlock_Array *instrArray = stack.Arg1().DereferenceArray(); + const int length = stack.Arg2().NumericByRef().s4; + const int origin = stack.Arg3().NumericByRef().s4; - int offset = -1; - // fixed origin: exact slots; relocatable: first-fit - if (origin >= 0) + if (PioFromIndex(block) == nullptr || block < 0 || block > 2 || instrArray == nullptr || + length <= 0 || length > 32 || static_cast(instrArray->m_numOfElements) < length) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + pio = PioFromIndex(block); + instr = reinterpret_cast(instrArray->GetFirstElement()); + PioEnsureOutOfReset(block); + + offset = -1; + if (origin >= 0) + { + if (origin <= 32 - length && (g_PioInstrUsed[block] & PioSlotMask(origin, length)) == 0) { - if (origin <= 32 - length && (g_PioInstrUsed[block] & PioSlotMask(origin, length)) == 0) - { - offset = origin; - } + offset = origin; } - else + } + else + { + for (int candidate = 0; candidate + length <= 32; candidate++) { - for (int candidate = 0; candidate + length <= 32; candidate++) + if ((g_PioInstrUsed[block] & PioSlotMask(candidate, length)) == 0) { - if ((g_PioInstrUsed[block] & PioSlotMask(candidate, length)) == 0) - { - offset = candidate; - break; - } + offset = candidate; + break; } } + } - if (offset >= 0) + if (offset >= 0) + { + relocate = origin < 0; + for (int i = 0; i < length; i++) { - bool relocate = origin < 0; - for (int i = 0; i < length; i++) + unsigned short w = instr[i]; + if (relocate && (w & 0xE000) == 0x0000) { - unsigned short w = instr[i]; - // relocate JMP (opcode 0b000) targets by the load offset - if (relocate && (w & 0xE000) == 0x0000) - { - unsigned int target = ((unsigned int)(w & 0x1F) + (unsigned int)offset) & 0x1F; - w = (unsigned short)((w & ~0x1F) | target); - } - pio->INSTR_MEM[offset + i] = w; + const unsigned int target = (static_cast(w & 0x1F) + static_cast(offset)) & 0x1F; + w = static_cast((w & ~0x1F) | target); } - g_PioInstrUsed[block] |= PioSlotMask(offset, length); + pio->INSTR_MEM[offset + i] = w; } - - stack.SetResult_I4(offset); + g_PioInstrUsed[block] |= PioSlotMask(offset, length); } + + stack.SetResult_I4(offset); + NANOCLR_NOCLEANUP(); } @@ -122,33 +125,33 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NativeRemoveProgram___STATIC__VOID__I4__I4__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); - { - int block = stack.Arg0().NumericByRef().s4; - int length = stack.Arg1().NumericByRef().s4; - int offset = stack.Arg2().NumericByRef().s4; - PIO_TypeDef *pio = PioFromIndex(block); - if (pio == nullptr || offset < 0 || length <= 0 || length > 32 || offset > 32 - length) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } + unsigned int mask; - // only reclaim a range that is fully owned, else we'd corrupt the map and clobber other programs - unsigned int mask = PioSlotMask(offset, length); - if ((g_PioInstrUsed[block] & mask) != mask) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } - PioEnsureOutOfReset(block); + const int block = stack.Arg0().NumericByRef().s4; + const int length = stack.Arg1().NumericByRef().s4; + const int offset = stack.Arg2().NumericByRef().s4; - // reclaim slots, blank to JMP-to-self so a stray enable can't run stale opcodes - for (int i = 0; i < length; i++) - { - pio->INSTR_MEM[offset + i] = (unsigned short)((offset + i) & 0x1F); - } + PIO_TypeDef *pio = PioFromIndex(block); + if (pio == nullptr || offset < 0 || length <= 0 || length > 32 || offset > 32 - length) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } - g_PioInstrUsed[block] &= ~mask; + mask = PioSlotMask(offset, length); + if ((g_PioInstrUsed[block] & mask) != mask) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } + PioEnsureOutOfReset(block); + + for (int i = 0; i < length; i++) + { + pio->INSTR_MEM[offset + i] = static_cast((offset + i) & 0x1F); + } + + g_PioInstrUsed[block] &= ~mask; + NANOCLR_NOCLEANUP(); } @@ -156,34 +159,35 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NativeClaimUnusedSm___STATIC__I4__I4__BOOLEAN(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); - { - int block = stack.Arg0().NumericByRef().s4; - bool required = stack.Arg1().NumericByRef().u1; - if (PioFromIndex(block) == nullptr) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } + int claimed; - int claimed = -1; - for (int sm = 0; sm < 4; sm++) - { - if ((g_PioClaimedSm[block] & (1u << sm)) == 0) - { - g_PioClaimedSm[block] |= (1u << sm); - claimed = sm; - break; - } - } + const int block = stack.Arg0().NumericByRef().s4; + const bool required = stack.Arg1().NumericByRef().u1; + + if (PioFromIndex(block) == nullptr) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } - // none free: `required` hard-fails, else soft -1 - if (claimed < 0 && required) + claimed = -1; + for (int sm = 0; sm < 4; sm++) + { + if ((g_PioClaimedSm[block] & (1u << sm)) == 0) { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + g_PioClaimedSm[block] |= (1u << sm); + claimed = sm; + break; } + } - stack.SetResult_I4(claimed); + if (claimed < 0 && required) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); } + + stack.SetResult_I4(claimed); + NANOCLR_NOCLEANUP(); } @@ -191,25 +195,23 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NativeInitGpio___STATIC__VOID__I4__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); - { - int block = stack.Arg0().NumericByRef().s4; - int pin = stack.Arg1().NumericByRef().s4; + + const int block = stack.Arg0().NumericByRef().s4; + const int pin = stack.Arg1().NumericByRef().s4; #if defined(RP2350) - if (block < 0 || block > 2 || pin < 0 || pin > 47) + if (block < 0 || block > 2 || pin < 0 || pin > 47) #else - if (block < 0 || block > 1 || pin < 0 || pin > 29) + if (block < 0 || block > 1 || pin < 0 || pin > 29) #endif - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } - PioEnsureOutOfReset(block); - - // FUNCSEL = 6 (PIO0), 7 (PIO1), 8 (PIO2) - IO_BANK0->GPIO[pin].CTRL = 6u + (unsigned int)block; - // clear OD (bit 7), set IE (bit 6); also clear the RP2350 pad isolation latch (bit 8, resets to 1) - PADS_BANK0->GPIO[pin] = (PADS_BANK0->GPIO[pin] & ~0x180u) | 0x40u; + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } + PioEnsureOutOfReset(block); + + IO_BANK0->GPIO[pin].CTRL = 6u + static_cast(block); + PADS_BANK0->GPIO[pin] = (PADS_BANK0->GPIO[pin] & ~0x180u) | 0x40u; + NANOCLR_NOCLEANUP(); } @@ -217,19 +219,19 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NativeForceIrq___STATIC__VOID__I4__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); - { - int block = stack.Arg0().NumericByRef().s4; - int irq = stack.Arg1().NumericByRef().s4; - PIO_TypeDef *pio = PioFromIndex(block); - if (pio == nullptr || irq < 0 || irq > 7) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } - PioEnsureOutOfReset(block); + const int block = stack.Arg0().NumericByRef().s4; + const int irq = stack.Arg1().NumericByRef().s4; - pio->IRQ_FORCE = (1u << irq); + PIO_TypeDef *pio = PioFromIndex(block); + if (pio == nullptr || irq < 0 || irq > 7) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } + PioEnsureOutOfReset(block); + + pio->IRQ_FORCE = (1u << irq); + NANOCLR_NOCLEANUP(); } @@ -237,18 +239,18 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NativeClearIrq___STATIC__VOID__I4__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); - { - int block = stack.Arg0().NumericByRef().s4; - int irq = stack.Arg1().NumericByRef().s4; - PIO_TypeDef *pio = PioFromIndex(block); - if (pio == nullptr || irq < 0 || irq > 7) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } - PioEnsureOutOfReset(block); + const int block = stack.Arg0().NumericByRef().s4; + const int irq = stack.Arg1().NumericByRef().s4; - pio->IRQ = (1u << irq); + PIO_TypeDef *pio = PioFromIndex(block); + if (pio == nullptr || irq < 0 || irq > 7) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } + PioEnsureOutOfReset(block); + + pio->IRQ = (1u << irq); + NANOCLR_NOCLEANUP(); } diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp index 31e0131d9b..3ad59db976 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp @@ -13,12 +13,10 @@ #include #include -// PIO FSTAT: RXEMPTY [11:8], TXFULL [19:16] -- one status bit per state machine #define PIO_FSTAT_RXEMPTY_LSB 8u #define PIO_FSTAT_TXFULL_LSB 16u -// busy-wait cap so a stalled SM times out instead of hanging -static const unsigned int PIO_FIFO_WAIT_LIMIT = 0x4000000u; +static constexpr unsigned int PIO_FIFO_WAIT_LIMIT = 0x4000000u; // DMA bulk-read state, one slot per block/sm (Channel == nullptr when idle). The channel is a ChibiOS // RP DMA descriptor so completion arrives via PioDmaCallback (no raw NVIC vector, no clash with the SPI DMA). @@ -41,7 +39,6 @@ static void PioDmaCallback(void *p, uint32_t ct) Events_Set(SYSTEM_EVENT_FLAG_PICOPIO); } -// blob indices, must match PioStateMachineConfig.cs enum PioCfgBlob { PIO_CFG_OUT_BASE = 0, @@ -74,78 +71,86 @@ enum PioCfgBlob PIO_CFG_BLOB_LENGTH = 27, }; -// claim bitmask owned by PioBlock.cpp extern unsigned int g_PioClaimedSm[3]; HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: NativeInit___STATIC__VOID__I4__I4__I4__SZARRAY_U4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); + + unsigned int *b; + unsigned int sidesetTotal; + unsigned int execCtrl; + unsigned int pushThresh; + unsigned int pullThresh; + // FJOIN: low 2 bits -> TX [30] / RX [31]; high 2 bits (PIO v1) -> RX_GET [14] / RX_PUT [15] + unsigned int join; + + const int block = stack.Arg0().NumericByRef().s4; + const int sm = stack.Arg1().NumericByRef().s4; + const int offset = stack.Arg2().NumericByRef().s4; + CLR_RT_HeapBlock_Array *blobArray = stack.Arg3().DereferenceArray(); + + PIO_TypeDef *pio = PioFromIndex(block); + if (pio == nullptr || sm < 0 || sm > 3 || offset < 0 || offset > 31 || blobArray == nullptr || + static_cast(blobArray->m_numOfElements) < PIO_CFG_BLOB_LENGTH) { - int block = stack.Arg0().NumericByRef().s4; - int sm = stack.Arg1().NumericByRef().s4; - int offset = stack.Arg2().NumericByRef().s4; - CLR_RT_HeapBlock_Array *blobArray = stack.Arg3().DereferenceArray(); + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + PioEnsureOutOfReset(block); - PIO_TypeDef *pio = PioFromIndex(block); - if (pio == nullptr || sm < 0 || sm > 3 || offset < 0 || offset > 31 || blobArray == nullptr || - (int)blobArray->m_numOfElements < PIO_CFG_BLOB_LENGTH) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } - PioEnsureOutOfReset(block); + b = reinterpret_cast(blobArray->GetFirstElement()); - unsigned int *b = (unsigned int *)blobArray->GetFirstElement(); + // disable + restart before reconfigure + pio->CTRL &= ~(1u << sm); + pio->CTRL |= (1u << (4 + sm)); // SM_RESTART - // disable + restart before reconfigure - pio->CTRL &= ~(1u << sm); - pio->CTRL |= (1u << (4 + sm)); // SM_RESTART - - // CLKDIV: int [31:16], frac [15:8] - pio->SM[sm].CLKDIV = ((b[PIO_CFG_CLKDIV_INT] & 0xFFFFu) << 16) | ((b[PIO_CFG_CLKDIV_FRAC] & 0xFFu) << 8); - - // side-set count includes the opt enable bit; each field masked to its width - unsigned int sidesetTotal = b[PIO_CFG_SIDESET_COUNT] + b[PIO_CFG_SIDESET_OPT]; - pio->SM[sm].PINCTRL = - ((sidesetTotal & 0x7u) << 29) | ((b[PIO_CFG_SET_COUNT] & 0x7u) << 26) | - ((b[PIO_CFG_OUT_COUNT] & 0x3Fu) << 20) | ((b[PIO_CFG_IN_BASE] & 0x1Fu) << 15) | - ((b[PIO_CFG_SIDESET_BASE] & 0x1Fu) << 10) | ((b[PIO_CFG_SET_BASE] & 0x1Fu) << 5) | - (b[PIO_CFG_OUT_BASE] & 0x1Fu); - - // EXECCTRL: wrap [16:12], wrap_target [11:7], side_en [30], side_pindir [29], jmp_pin [28:24] - unsigned int execCtrl = - ((b[PIO_CFG_WRAP] & 0x1Fu) << 12) | ((b[PIO_CFG_WRAP_TARGET] & 0x1Fu) << 7) | - ((b[PIO_CFG_JMP_PIN] & 0x1Fu) << 24) | ((b[PIO_CFG_MOV_STATUS_SEL] & 1u) << 4) | - (b[PIO_CFG_MOV_STATUS_N] & 0xFu) | ((b[PIO_CFG_OUT_STICKY] & 1u) << 17) | - ((b[PIO_CFG_INLINE_OUT_EN] & 1u) << 18) | ((b[PIO_CFG_OUT_EN_SEL] & 0x1Fu) << 19); - if (b[PIO_CFG_SIDESET_OPT]) - { - execCtrl |= (1u << 30); - } - if (b[PIO_CFG_SIDESET_PINDIRS]) - { - execCtrl |= (1u << 29); - } - pio->SM[sm].EXECCTRL = execCtrl; - - // a 32-bit threshold encodes as 0 in the 5-bit field - unsigned int pushThresh = b[PIO_CFG_PUSH_THRESHOLD] & 0x1F; - unsigned int pullThresh = b[PIO_CFG_PULL_THRESHOLD] & 0x1F; - // FJOIN: low 2 bits -> TX [30] / RX [31]; high 2 bits (PIO v1) -> RX_GET [14] / RX_PUT [15] - unsigned int join = b[PIO_CFG_FIFO_JOIN]; - pio->SM[sm].SHIFTCTRL = - ((b[PIO_CFG_IN_SHIFT_RIGHT] & 1u) << 18) | ((b[PIO_CFG_OUT_SHIFT_RIGHT] & 1u) << 19) | - ((b[PIO_CFG_AUTOPUSH] & 1u) << 16) | ((b[PIO_CFG_AUTOPULL] & 1u) << 17) | (pushThresh << 20) | - (pullThresh << 25) | ((join & 3u) << 30) | (((join >> 2) & 3u) << 14); + // CLKDIV: int [31:16], frac [15:8] + pio->SM[sm].CLKDIV = ((b[PIO_CFG_CLKDIV_INT] & 0xFFFFu) << 16) | ((b[PIO_CFG_CLKDIV_FRAC] & 0xFFu) << 8); + + // side-set count includes the opt enable bit; each field masked to its width + sidesetTotal = b[PIO_CFG_SIDESET_COUNT] + b[PIO_CFG_SIDESET_OPT]; + pio->SM[sm].PINCTRL = + ((sidesetTotal & 0x7u) << 29) | ((b[PIO_CFG_SET_COUNT] & 0x7u) << 26) | + ((b[PIO_CFG_OUT_COUNT] & 0x3Fu) << 20) | ((b[PIO_CFG_IN_BASE] & 0x1Fu) << 15) | + ((b[PIO_CFG_SIDESET_BASE] & 0x1Fu) << 10) | ((b[PIO_CFG_SET_BASE] & 0x1Fu) << 5) | + (b[PIO_CFG_OUT_BASE] & 0x1Fu); + + // EXECCTRL: wrap [16:12], wrap_target [11:7], side_en [30], side_pindir [29], jmp_pin [28:24] + execCtrl = + ((b[PIO_CFG_WRAP] & 0x1Fu) << 12) | ((b[PIO_CFG_WRAP_TARGET] & 0x1Fu) << 7) | + ((b[PIO_CFG_JMP_PIN] & 0x1Fu) << 24) | ((b[PIO_CFG_MOV_STATUS_SEL] & 1u) << 4) | + (b[PIO_CFG_MOV_STATUS_N] & 0xFu) | ((b[PIO_CFG_OUT_STICKY] & 1u) << 17) | + ((b[PIO_CFG_INLINE_OUT_EN] & 1u) << 18) | ((b[PIO_CFG_OUT_EN_SEL] & 0x1Fu) << 19); + + if (b[PIO_CFG_SIDESET_OPT]) + { + execCtrl |= (1u << 30); + } + if (b[PIO_CFG_SIDESET_PINDIRS]) + { + execCtrl |= (1u << 29); + } + pio->SM[sm].EXECCTRL = execCtrl; + + // a 32-bit threshold encodes as 0 in the 5-bit field + pushThresh = b[PIO_CFG_PUSH_THRESHOLD] & 0x1F; + pullThresh = b[PIO_CFG_PULL_THRESHOLD] & 0x1F; + // FJOIN: low 2 bits -> TX [30] / RX [31]; high 2 bits (PIO v1) -> RX_GET [14] / RX_PUT [15] + join = b[PIO_CFG_FIFO_JOIN]; + pio->SM[sm].SHIFTCTRL = + ((b[PIO_CFG_IN_SHIFT_RIGHT] & 1u) << 18) | ((b[PIO_CFG_OUT_SHIFT_RIGHT] & 1u) << 19) | + ((b[PIO_CFG_AUTOPUSH] & 1u) << 16) | ((b[PIO_CFG_AUTOPULL] & 1u) << 17) | (pushThresh << 20) | + (pullThresh << 25) | ((join & 3u) << 30) | (((join >> 2) & 3u) << 14); #if defined(RP2350) - // GPIOBASE is 0 or 16; CMSIS types it __I so write through a volatile pointer - *(volatile unsigned int *)&pio->GPIOBASE = (b[PIO_CFG_GPIO_BASE] == 16) ? 16u : 0u; + // GPIOBASE is 0 or 16; CMSIS types it __I so write through a volatile pointer + *reinterpret_cast(&pio->GPIOBASE) = (b[PIO_CFG_GPIO_BASE] == 16) ? 16u : 0u; #endif - // set PC via JMP (opcode 0) - pio->SM[sm].INSTR = (unsigned int)(offset & 0x1F); - } + // set PC via JMP (opcode 0) + pio->SM[sm].INSTR = static_cast(offset & 0x1F); + NANOCLR_NOCLEANUP(); } @@ -153,27 +158,27 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NativeSetEnabled___STATIC__VOID__I4__I4__BOOLEAN(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); - { - int block = stack.Arg0().NumericByRef().s4; - int sm = stack.Arg1().NumericByRef().s4; - bool enabled = stack.Arg2().NumericByRef().u1; - PIO_TypeDef *pio = PioFromIndex(block); - if (pio == nullptr || sm < 0 || sm > 3) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } - PioEnsureOutOfReset(block); + const int block = stack.Arg0().NumericByRef().s4; + const int sm = stack.Arg1().NumericByRef().s4; + const bool enabled = stack.Arg2().NumericByRef().u1; - if (enabled) - { - pio->CTRL |= (1u << sm); - } - else - { - pio->CTRL &= ~(1u << sm); - } + PIO_TypeDef *pio = PioFromIndex(block); + if (pio == nullptr || sm < 0 || sm > 3) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + PioEnsureOutOfReset(block); + + if (enabled) + { + pio->CTRL |= (1u << sm); } + else + { + pio->CTRL &= ~(1u << sm); + } + NANOCLR_NOCLEANUP(); } @@ -181,29 +186,31 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NativePutBlocking___STATIC__VOID__I4__I4__U4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); - { - int block = stack.Arg0().NumericByRef().s4; - int sm = stack.Arg1().NumericByRef().s4; - unsigned int value = stack.Arg2().NumericByRef().u4; - PIO_TypeDef *pio = PioFromIndex(block); - if (pio == nullptr || sm < 0 || sm > 3) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } - PioEnsureOutOfReset(block); + unsigned int guard; - // FSTAT TX_FULL = bits [19:16] - unsigned int guard = PIO_FIFO_WAIT_LIMIT; - while ((pio->FSTAT & (1u << (PIO_FSTAT_TXFULL_LSB + sm))) && --guard) - { - } - if (guard == 0) - { - NANOCLR_SET_AND_LEAVE(CLR_E_TIMEOUT); - } - pio->TXF[sm] = value; + const int block = stack.Arg0().NumericByRef().s4; + const int sm = stack.Arg1().NumericByRef().s4; + const unsigned int value = stack.Arg2().NumericByRef().u4; + + PIO_TypeDef *pio = PioFromIndex(block); + if (pio == nullptr || sm < 0 || sm > 3) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + PioEnsureOutOfReset(block); + + // FSTAT TX_FULL = bits [19:16] + guard = PIO_FIFO_WAIT_LIMIT; + while ((pio->FSTAT & (1u << (PIO_FSTAT_TXFULL_LSB + sm))) && --guard) + { } + if (guard == 0) + { + NANOCLR_SET_AND_LEAVE(CLR_E_TIMEOUT); + } + pio->TXF[sm] = value; + NANOCLR_NOCLEANUP(); } @@ -211,28 +218,30 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NativeGetBlocking___STATIC__U4__I4__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); - { - int block = stack.Arg0().NumericByRef().s4; - int sm = stack.Arg1().NumericByRef().s4; - PIO_TypeDef *pio = PioFromIndex(block); - if (pio == nullptr || sm < 0 || sm > 3) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } - PioEnsureOutOfReset(block); + unsigned int guard; - // FSTAT RX_EMPTY = bits [11:8] - unsigned int guard = PIO_FIFO_WAIT_LIMIT; - while ((pio->FSTAT & (1u << (PIO_FSTAT_RXEMPTY_LSB + sm))) && --guard) - { - } - if (guard == 0) - { - NANOCLR_SET_AND_LEAVE(CLR_E_TIMEOUT); - } - stack.SetResult_U4(pio->RXF[sm]); + const int block = stack.Arg0().NumericByRef().s4; + const int sm = stack.Arg1().NumericByRef().s4; + + const PIO_TypeDef *pio = PioFromIndex(block); + if (pio == nullptr || sm < 0 || sm > 3) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } + PioEnsureOutOfReset(block); + + // FSTAT RX_EMPTY = bits [11:8] + guard = PIO_FIFO_WAIT_LIMIT; + while ((pio->FSTAT & (1u << (PIO_FSTAT_RXEMPTY_LSB + sm))) && --guard) + { + } + if (guard == 0) + { + NANOCLR_SET_AND_LEAVE(CLR_E_TIMEOUT); + } + stack.SetResult_U4(pio->RXF[sm]); + NANOCLR_NOCLEANUP(); } @@ -240,19 +249,19 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NativeTxFull___STATIC__BOOLEAN__I4__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); - { - int block = stack.Arg0().NumericByRef().s4; - int sm = stack.Arg1().NumericByRef().s4; - PIO_TypeDef *pio = PioFromIndex(block); - if (pio == nullptr || sm < 0 || sm > 3) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } - PioEnsureOutOfReset(block); + const int block = stack.Arg0().NumericByRef().s4; + const int sm = stack.Arg1().NumericByRef().s4; - stack.SetResult_Boolean((pio->FSTAT & (1u << (PIO_FSTAT_TXFULL_LSB + sm))) != 0); + const PIO_TypeDef *pio = PioFromIndex(block); + if (pio == nullptr || sm < 0 || sm > 3) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } + PioEnsureOutOfReset(block); + + stack.SetResult_Boolean((pio->FSTAT & (1u << (PIO_FSTAT_TXFULL_LSB + sm))) != 0); + NANOCLR_NOCLEANUP(); } @@ -260,19 +269,19 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NativeRxEmpty___STATIC__BOOLEAN__I4__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); - { - int block = stack.Arg0().NumericByRef().s4; - int sm = stack.Arg1().NumericByRef().s4; - PIO_TypeDef *pio = PioFromIndex(block); - if (pio == nullptr || sm < 0 || sm > 3) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } - PioEnsureOutOfReset(block); + const int block = stack.Arg0().NumericByRef().s4; + const int sm = stack.Arg1().NumericByRef().s4; - stack.SetResult_Boolean((pio->FSTAT & (1u << (PIO_FSTAT_RXEMPTY_LSB + sm))) != 0); + const PIO_TypeDef *pio = PioFromIndex(block); + if (pio == nullptr || sm < 0 || sm > 3) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } + PioEnsureOutOfReset(block); + + stack.SetResult_Boolean((pio->FSTAT & (1u << (PIO_FSTAT_RXEMPTY_LSB + sm))) != 0); + NANOCLR_NOCLEANUP(); } @@ -280,21 +289,21 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NativeUnclaim___STATIC__VOID__I4__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); - { - int block = stack.Arg0().NumericByRef().s4; - int sm = stack.Arg1().NumericByRef().s4; - PIO_TypeDef *pio = PioFromIndex(block); - if (pio == nullptr || sm < 0 || sm > 3) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } - PioEnsureOutOfReset(block); + const int block = stack.Arg0().NumericByRef().s4; + const int sm = stack.Arg1().NumericByRef().s4; - // stop + release the claim - pio->CTRL &= ~(1u << sm); - g_PioClaimedSm[block] &= ~(1u << sm); + PIO_TypeDef *pio = PioFromIndex(block); + if (pio == nullptr || sm < 0 || sm > 3) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } + PioEnsureOutOfReset(block); + + // stop + release the claim + pio->CTRL &= ~(1u << sm); + g_PioClaimedSm[block] &= ~(1u << sm); + NANOCLR_NOCLEANUP(); } @@ -302,50 +311,54 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NativeSetConsecutivePinDirs___STATIC__VOID__I4__I4__I4__I4__BOOLEAN(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); - { - int block = stack.Arg0().NumericByRef().s4; - int sm = stack.Arg1().NumericByRef().s4; - int basePin = stack.Arg2().NumericByRef().s4; - int count = stack.Arg3().NumericByRef().s4; - bool output = stack.Arg4().NumericByRef().u1; - PIO_TypeDef *pio = PioFromIndex(block); + int pin; + int remaining; + unsigned int savedPinCtrl; + + const int block = stack.Arg0().NumericByRef().s4; + const int sm = stack.Arg1().NumericByRef().s4; + const int basePin = stack.Arg2().NumericByRef().s4; + const int count = stack.Arg3().NumericByRef().s4; + const bool output = stack.Arg4().NumericByRef().u1; + + PIO_TypeDef *pio = PioFromIndex(block); #if defined(RP2350) - const int maxPins = 48; - const int gpioBase = (pio != nullptr) ? (int)pio->GPIOBASE : 0; + constexpr int maxPins = 48; + const int gpioBase = (pio != nullptr) ? (int)pio->GPIOBASE : 0; #else - const int maxPins = 30; - const int gpioBase = 0; + constexpr int maxPins = 30; + const int gpioBase = 0; #endif - // SET_BASE is 5-bit, relative to the SM's GPIO base, so reject pins outside the 32-pin window - if (pio == nullptr || sm < 0 || sm > 3 || count < 0 || count > 32 || basePin < gpioBase || - basePin - gpioBase > 32 - count || basePin > maxPins - count) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } - PioEnsureOutOfReset(block); - - // up to 5 pins per "SET pindirs" exec, then restore PINCTRL - int pin = basePin; - int remaining = count; - unsigned int savedPinCtrl = pio->SM[sm].PINCTRL; + // SET_BASE is 5-bit, relative to the SM's GPIO base, so reject pins outside the 32-pin window + if (pio == nullptr || sm < 0 || sm > 3 || count < 0 || count > 32 || basePin < gpioBase || + basePin - gpioBase > 32 - count || basePin > maxPins - count) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + PioEnsureOutOfReset(block); - while (remaining > 0) - { - int chunk = remaining < 5 ? remaining : 5; - unsigned int dirs = output ? ((1u << chunk) - 1u) : 0u; + // up to 5 pins per "SET pindirs" exec, then restore PINCTRL + pin = basePin; + remaining = count; + savedPinCtrl = pio->SM[sm].PINCTRL; - // PINCTRL: SET_COUNT [28:26], SET_BASE [9:5] - pio->SM[sm].PINCTRL = ((unsigned int)chunk << 26) | (((unsigned int)(pin - gpioBase) & 0x1Fu) << 5); - // SET pindirs, dirs - pio->SM[sm].INSTR = 0xE000u | (4u << 5) | (dirs & 0x1Fu); + while (remaining > 0) + { + const int chunk = remaining < 5 ? remaining : 5; + const unsigned int dirs = output ? ((1u << chunk) - 1u) : 0u; - remaining -= chunk; - pin += chunk; - } + // PINCTRL: SET_COUNT [28:26], SET_BASE [9:5] + pio->SM[sm].PINCTRL = (static_cast(chunk) << 26) | ((static_cast(pin - gpioBase) & 0x1Fu) << 5); + // SET pindirs, dirs + pio->SM[sm].INSTR = 0xE000u | (4u << 5) | (dirs & 0x1Fu); - pio->SM[sm].PINCTRL = savedPinCtrl; + remaining -= chunk; + pin += chunk; } + + pio->SM[sm].PINCTRL = savedPinCtrl; + NANOCLR_NOCLEANUP(); } @@ -353,22 +366,24 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NativeClearFifos___STATIC__VOID__I4__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); - { - int block = stack.Arg0().NumericByRef().s4; - int sm = stack.Arg1().NumericByRef().s4; - PIO_TypeDef *pio = PioFromIndex(block); - if (pio == nullptr || sm < 0 || sm > 3) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } - PioEnsureOutOfReset(block); + unsigned int fjoinRx; + + const int block = stack.Arg0().NumericByRef().s4; + const int sm = stack.Arg1().NumericByRef().s4; - // toggle FJOIN_RX (bit 31) twice to flush both FIFOs, SHIFTCTRL unchanged - unsigned int fjoinRx = (1u << 31); - pio->SM[sm].SHIFTCTRL ^= fjoinRx; - pio->SM[sm].SHIFTCTRL ^= fjoinRx; + PIO_TypeDef *pio = PioFromIndex(block); + if (pio == nullptr || sm < 0 || sm > 3) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } + PioEnsureOutOfReset(block); + + // toggle FJOIN_RX (bit 31) twice to flush both FIFOs, SHIFTCTRL unchanged + fjoinRx = (1u << 31); + pio->SM[sm].SHIFTCTRL ^= fjoinRx; + pio->SM[sm].SHIFTCTRL ^= fjoinRx; + NANOCLR_NOCLEANUP(); } @@ -376,30 +391,35 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NativeDrainTxFifo___STATIC__VOID__I4__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); + + unsigned int autopull; + unsigned int instr; + unsigned int guard; + + const int block = stack.Arg0().NumericByRef().s4; + const int sm = stack.Arg1().NumericByRef().s4; + + PIO_TypeDef *pio = PioFromIndex(block); + if (pio == nullptr || sm < 0 || sm > 3) { - int block = stack.Arg0().NumericByRef().s4; - int sm = stack.Arg1().NumericByRef().s4; + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + PioEnsureOutOfReset(block); - PIO_TypeDef *pio = PioFromIndex(block); - if (pio == nullptr || sm < 0 || sm > 3) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } - PioEnsureOutOfReset(block); + // exec OUT NULL,32 (autopull) or PULL noblock until TX empty. FSTAT TX_EMPTY = bits [27:24] + autopull = pio->SM[sm].SHIFTCTRL & (1u << 17); + instr = autopull ? 0x6060u : 0x8000u; + guard = PIO_FIFO_WAIT_LIMIT; - // exec OUT NULL,32 (autopull) or PULL noblock until TX empty. FSTAT TX_EMPTY = bits [27:24] - unsigned int autopull = pio->SM[sm].SHIFTCTRL & (1u << 17); - unsigned int instr = autopull ? 0x6060u : 0x8000u; - unsigned int guard = PIO_FIFO_WAIT_LIMIT; - while ((pio->FSTAT & (1u << (24 + sm))) == 0 && --guard) - { - pio->SM[sm].INSTR = instr; - } - if (guard == 0) - { - NANOCLR_SET_AND_LEAVE(CLR_E_TIMEOUT); - } + while ((pio->FSTAT & (1u << (24 + sm))) == 0 && --guard) + { + pio->SM[sm].INSTR = instr; } + if (guard == 0) + { + NANOCLR_SET_AND_LEAVE(CLR_E_TIMEOUT); + } + NANOCLR_NOCLEANUP(); } @@ -407,20 +427,20 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NativeRestart___STATIC__VOID__I4__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); - { - int block = stack.Arg0().NumericByRef().s4; - int sm = stack.Arg1().NumericByRef().s4; - PIO_TypeDef *pio = PioFromIndex(block); - if (pio == nullptr || sm < 0 || sm > 3) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } - PioEnsureOutOfReset(block); + const int block = stack.Arg0().NumericByRef().s4; + const int sm = stack.Arg1().NumericByRef().s4; - // SM_RESTART = bits [7:4] - pio->CTRL |= (1u << (4 + sm)); + PIO_TypeDef *pio = PioFromIndex(block); + if (pio == nullptr || sm < 0 || sm > 3) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } + PioEnsureOutOfReset(block); + + // SM_RESTART = bits [7:4] + pio->CTRL |= (1u << (4 + sm)); + NANOCLR_NOCLEANUP(); } @@ -428,20 +448,20 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NativeClkDivRestart___STATIC__VOID__I4__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); - { - int block = stack.Arg0().NumericByRef().s4; - int sm = stack.Arg1().NumericByRef().s4; - PIO_TypeDef *pio = PioFromIndex(block); - if (pio == nullptr || sm < 0 || sm > 3) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } - PioEnsureOutOfReset(block); + const int block = stack.Arg0().NumericByRef().s4; + const int sm = stack.Arg1().NumericByRef().s4; - // CLKDIV_RESTART = bits [11:8] - pio->CTRL |= (1u << (8 + sm)); + PIO_TypeDef *pio = PioFromIndex(block); + if (pio == nullptr || sm < 0 || sm > 3) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } + PioEnsureOutOfReset(block); + + // CLKDIV_RESTART = bits [11:8] + pio->CTRL |= (1u << (8 + sm)); + NANOCLR_NOCLEANUP(); } @@ -449,21 +469,21 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NativeExec___STATIC__VOID__I4__I4__U2(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); - { - int block = stack.Arg0().NumericByRef().s4; - int sm = stack.Arg1().NumericByRef().s4; - unsigned short instruction = stack.Arg2().NumericByRef().u2; - PIO_TypeDef *pio = PioFromIndex(block); - if (pio == nullptr || sm < 0 || sm > 3) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } - PioEnsureOutOfReset(block); + const int block = stack.Arg0().NumericByRef().s4; + const int sm = stack.Arg1().NumericByRef().s4; + const unsigned short instruction = stack.Arg2().NumericByRef().u2; - // exec out of band, PC unchanged - pio->SM[sm].INSTR = (unsigned int)instruction; + PIO_TypeDef *pio = PioFromIndex(block); + if (pio == nullptr || sm < 0 || sm > 3) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } + PioEnsureOutOfReset(block); + + // exec out of band, PC unchanged + pio->SM[sm].INSTR = static_cast(instruction); + NANOCLR_NOCLEANUP(); } @@ -471,19 +491,19 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NativeTxLevel___STATIC__U4__I4__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); - { - int block = stack.Arg0().NumericByRef().s4; - int sm = stack.Arg1().NumericByRef().s4; - PIO_TypeDef *pio = PioFromIndex(block); - if (pio == nullptr || sm < 0 || sm > 3) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } - PioEnsureOutOfReset(block); + const int block = stack.Arg0().NumericByRef().s4; + const int sm = stack.Arg1().NumericByRef().s4; - stack.SetResult_U4((pio->FLEVEL >> (8 * sm)) & 0xFu); + const PIO_TypeDef *pio = PioFromIndex(block); + if (pio == nullptr || sm < 0 || sm > 3) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } + PioEnsureOutOfReset(block); + + stack.SetResult_U4((pio->FLEVEL >> (8 * sm)) & 0xFu); + NANOCLR_NOCLEANUP(); } @@ -491,19 +511,19 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NativeRxLevel___STATIC__U4__I4__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); - { - int block = stack.Arg0().NumericByRef().s4; - int sm = stack.Arg1().NumericByRef().s4; - PIO_TypeDef *pio = PioFromIndex(block); - if (pio == nullptr || sm < 0 || sm > 3) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } - PioEnsureOutOfReset(block); + const int block = stack.Arg0().NumericByRef().s4; + const int sm = stack.Arg1().NumericByRef().s4; - stack.SetResult_U4((pio->FLEVEL >> (8 * sm + 4)) & 0xFu); + const PIO_TypeDef *pio = PioFromIndex(block); + if (pio == nullptr || sm < 0 || sm > 3) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } + PioEnsureOutOfReset(block); + + stack.SetResult_U4((pio->FLEVEL >> (8 * sm + 4)) & 0xFu); + NANOCLR_NOCLEANUP(); } @@ -511,19 +531,19 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NativeGetPc___STATIC__U4__I4__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); - { - int block = stack.Arg0().NumericByRef().s4; - int sm = stack.Arg1().NumericByRef().s4; - PIO_TypeDef *pio = PioFromIndex(block); - if (pio == nullptr || sm < 0 || sm > 3) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } - PioEnsureOutOfReset(block); + const int block = stack.Arg0().NumericByRef().s4; + const int sm = stack.Arg1().NumericByRef().s4; - stack.SetResult_U4(pio->SM[sm].ADDR & 0x1Fu); + const PIO_TypeDef *pio = PioFromIndex(block); + if (pio == nullptr || sm < 0 || sm > 3) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } + PioEnsureOutOfReset(block); + + stack.SetResult_U4(pio->SM[sm].ADDR & 0x1Fu); + NANOCLR_NOCLEANUP(); } @@ -531,47 +551,48 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NativeSetClockDivisor___STATIC__VOID__I4__I4__I4__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); - { - int block = stack.Arg0().NumericByRef().s4; - int sm = stack.Arg1().NumericByRef().s4; - int clkDivInt = stack.Arg2().NumericByRef().s4; - int clkDivFrac = stack.Arg3().NumericByRef().s4; - PIO_TypeDef *pio = PioFromIndex(block); - // 16-bit int + 8-bit frac fields - if (pio == nullptr || sm < 0 || sm > 3 || clkDivInt < 0 || clkDivInt > 0xFFFF || clkDivFrac < 0 || - clkDivFrac > 0xFF) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } - PioEnsureOutOfReset(block); + const int block = stack.Arg0().NumericByRef().s4; + const int sm = stack.Arg1().NumericByRef().s4; + const int clkDivInt = stack.Arg2().NumericByRef().s4; + const int clkDivFrac = stack.Arg3().NumericByRef().s4; - pio->SM[sm].CLKDIV = ((unsigned int)clkDivInt << 16) | ((unsigned int)clkDivFrac << 8); - pio->CTRL |= (1u << (8 + sm)); + PIO_TypeDef *pio = PioFromIndex(block); + // 16-bit int + 8-bit frac fields + if (pio == nullptr || sm < 0 || sm > 3 || clkDivInt < 0 || clkDivInt > 0xFFFF || clkDivFrac < 0 || + clkDivFrac > 0xFF) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } + PioEnsureOutOfReset(block); + + pio->SM[sm].CLKDIV = (static_cast(clkDivInt) << 16) | (static_cast(clkDivFrac) << 8); + pio->CTRL |= (1u << (8 + sm)); + NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeRead___STATIC__I4__I4__I4__SZARRAY_U4__I4__I4__I4(CLR_RT_StackFrame &stack) +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: + NativeRead___STATIC__I4__I4__I4__SZARRAY_U4__I4__I4__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); - CLR_RT_HeapBlock hbTimeout; + CLR_RT_HeapBlock hbTimeout{}; CLR_INT64 *timeoutTicks; bool eventResult = true; int transferred = 0; - int block = stack.Arg0().NumericByRef().s4; - int sm = stack.Arg1().NumericByRef().s4; + const int block = stack.Arg0().NumericByRef().s4; + const int sm = stack.Arg1().NumericByRef().s4; CLR_RT_HeapBlock_Array *arr = stack.Arg2().DereferenceArray(); - int offset = stack.Arg3().NumericByRef().s4; - int count = stack.Arg4().NumericByRef().s4; - int timeoutMs = stack.Arg5().NumericByRef().s4; + const int offset = stack.Arg3().NumericByRef().s4; + const int count = stack.Arg4().NumericByRef().s4; + const int timeoutMs = stack.Arg5().NumericByRef().s4; PIO_TypeDef *pio = PioFromIndex(block); PioDmaWork *work = &g_PioDmaWork[block][sm]; - hbTimeout.SetInteger((CLR_INT64)timeoutMs * TIME_CONVERSION__TO_MILLISECONDS); + hbTimeout.SetInteger(static_cast(timeoutMs) * TIME_CONVERSION__TO_MILLISECONDS); NANOCLR_CHECK_HRESULT(stack.SetupTimeoutFromTicks(hbTimeout, timeoutTicks)); // first call: validate + arm the DMA + park @@ -599,7 +620,7 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); } - unsigned int *buf = (unsigned int *)platform_malloc((size_t)count * 4); + unsigned int *buf = static_cast(platform_malloc(static_cast(count) * 4)); if (buf == nullptr) { dmaChannelFree(ch); @@ -607,17 +628,17 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P } // read = SM RX FIFO (fixed), write = bounce buffer (incrementing), paced by the SM RX DREQ - unsigned int dreq = (block == 0 ? 4u : 12u) + (unsigned int)sm; - ch->channel->READ_ADDR = (unsigned int)(size_t)&pio->RXF[sm]; - ch->channel->WRITE_ADDR = (unsigned int)(size_t)buf; - ch->channel->TRANS_COUNT = (unsigned int)count; + const unsigned int dreq = (block == 0 ? 4u : 12u) + static_cast(sm); + ch->channel->READ_ADDR = reinterpret_cast(&pio->RXF[sm]); + ch->channel->WRITE_ADDR = reinterpret_cast(buf); + ch->channel->TRANS_COUNT = static_cast(count); dmaChannelEnableInterruptX(ch); ch->channel->CTRL_TRIG = DMA_CTRL_TRIG_EN | DMA_CTRL_TRIG_DATA_SIZE_WORD | DMA_CTRL_TRIG_INCR_WRITE | DMA_CTRL_TRIG_TREQ_SEL(dreq) | DMA_CTRL_TRIG_CHAIN_TO(ch->chnidx); work->Channel = ch; work->Buffer = buf; - work->Count = (unsigned int)count; + work->Count = static_cast(count); Events_Get(SYSTEM_EVENT_FLAG_PICOPIO); stack.m_customState = 2; @@ -649,15 +670,15 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P } } - transferred = (int)(work->Count - ch->channel->TRANS_COUNT); + transferred = static_cast(work->Count - ch->channel->TRANS_COUNT); if (transferred < 0) { transferred = 0; } if (arr != nullptr && offset >= 0 && transferred > 0 && - (offset + transferred) <= (int)arr->m_numOfElements) + (offset + transferred) <= static_cast(arr->m_numOfElements)) { - memcpy(arr->GetFirstElement() + (size_t)offset * 4, work->Buffer, (size_t)transferred * 4); + memcpy(arr->GetFirstElement() + static_cast(offset) * 4, work->Buffer, static_cast(transferred) * 4); } (void)dmaChannelGetAndClearInterrupts(ch); @@ -675,26 +696,27 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeWrite___STATIC__I4__I4__I4__SZARRAY_U4__I4__I4__I4(CLR_RT_StackFrame &stack) +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: + NativeWrite___STATIC__I4__I4__I4__SZARRAY_U4__I4__I4__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); - CLR_RT_HeapBlock hbTimeout; + CLR_RT_HeapBlock hbTimeout{}; CLR_INT64 *timeoutTicks; bool eventResult = true; int transferred = 0; - int block = stack.Arg0().NumericByRef().s4; - int sm = stack.Arg1().NumericByRef().s4; + const int block = stack.Arg0().NumericByRef().s4; + const int sm = stack.Arg1().NumericByRef().s4; CLR_RT_HeapBlock_Array *arr = stack.Arg2().DereferenceArray(); - int offset = stack.Arg3().NumericByRef().s4; - int count = stack.Arg4().NumericByRef().s4; - int timeoutMs = stack.Arg5().NumericByRef().s4; + const int offset = stack.Arg3().NumericByRef().s4; + const int count = stack.Arg4().NumericByRef().s4; + const int timeoutMs = stack.Arg5().NumericByRef().s4; PIO_TypeDef *pio = PioFromIndex(block); PioDmaWork *work = &g_PioDmaWorkTx[block][sm]; - hbTimeout.SetInteger((CLR_INT64)timeoutMs * TIME_CONVERSION__TO_MILLISECONDS); + hbTimeout.SetInteger(static_cast(timeoutMs) * TIME_CONVERSION__TO_MILLISECONDS); NANOCLR_CHECK_HRESULT(stack.SetupTimeoutFromTicks(hbTimeout, timeoutTicks)); // first call: validate + copy out + arm the DMA + park @@ -711,7 +733,7 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NANOCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); } if (arr == nullptr || count <= 0 || work->Channel != nullptr || offset < 0 || - (offset + count) > (int)arr->m_numOfElements) + (offset + count) > static_cast(arr->m_numOfElements)) { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); } @@ -723,7 +745,7 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); } - unsigned int *buf = (unsigned int *)platform_malloc((size_t)count * 4); + unsigned int *buf = static_cast(platform_malloc(static_cast(count) * 4)); if (buf == nullptr) { dmaChannelFree(ch); @@ -731,20 +753,20 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P } // copy the words out into the bounce buffer before the DMA drains it into the TX FIFO - memcpy(buf, arr->GetFirstElement() + (size_t)offset * 4, (size_t)count * 4); + memcpy(buf, arr->GetFirstElement() + static_cast(offset) * 4, static_cast(count) * 4); // read = bounce buffer (incrementing), write = SM TX FIFO (fixed), paced by the SM TX DREQ - unsigned int dreq = (block == 0 ? 0u : 8u) + (unsigned int)sm; - ch->channel->READ_ADDR = (unsigned int)(size_t)buf; - ch->channel->WRITE_ADDR = (unsigned int)(size_t)&pio->TXF[sm]; - ch->channel->TRANS_COUNT = (unsigned int)count; + unsigned int dreq = (block == 0 ? 0u : 8u) + static_cast(sm); + ch->channel->READ_ADDR = (unsigned int)reinterpret_cast(buf); + ch->channel->WRITE_ADDR = (unsigned int)reinterpret_cast(&pio->TXF[sm]); + ch->channel->TRANS_COUNT = static_cast(count); dmaChannelEnableInterruptX(ch); ch->channel->CTRL_TRIG = DMA_CTRL_TRIG_EN | DMA_CTRL_TRIG_DATA_SIZE_WORD | DMA_CTRL_TRIG_INCR_READ | DMA_CTRL_TRIG_TREQ_SEL(dreq) | DMA_CTRL_TRIG_CHAIN_TO(ch->chnidx); work->Channel = ch; work->Buffer = buf; - work->Count = (unsigned int)count; + work->Count = static_cast(count); Events_Get(SYSTEM_EVENT_FLAG_PICOPIO); stack.m_customState = 2; @@ -777,7 +799,7 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P } // data already went out to the TX FIFO -- nothing to copy back - transferred = (int)(work->Count - ch->channel->TRANS_COUNT); + transferred = static_cast(work->Count - ch->channel->TRANS_COUNT); if (transferred < 0) { transferred = 0; From 497ec231144bf9c0b4bb6ffff9e4f21d9acfea6f Mon Sep 17 00:00:00 2001 From: nfbot Date: Fri, 24 Jul 2026 07:44:07 +0000 Subject: [PATCH 32/58] Code style fixes Automated fixes for code style. --- src/CLR/Include/nanoCLR_Hardware.h | 12 +++--- ...work_hardware_pico_native_PioIrqDriver.cpp | 10 ++--- ...noFramework_Hardware_Pico_Pio_PioBlock.cpp | 15 ++++---- ...work_Hardware_Pico_Pio_PioStateMachine.cpp | 37 +++++++++---------- 4 files changed, 34 insertions(+), 40 deletions(-) diff --git a/src/CLR/Include/nanoCLR_Hardware.h b/src/CLR/Include/nanoCLR_Hardware.h index d170ce332b..db4113a777 100644 --- a/src/CLR/Include/nanoCLR_Hardware.h +++ b/src/CLR/Include/nanoCLR_Hardware.h @@ -21,12 +21,12 @@ struct CLR_HW_Hardware { static const CLR_UINT32 c_Default_PowerLevel = PowerLevel__Sleep; static const CLR_UINT32 c_Default_WakeupEvents = - SYSTEM_EVENT_FLAG_COM_IN | SYSTEM_EVENT_FLAG_COM_OUT | SYSTEM_EVENT_FLAG_STORAGE_IO | SYSTEM_EVENT_FLAG_PICOPIO | - SYSTEM_EVENT_FLAG_SYSTEM_TIMER | SYSTEM_EVENT_FLAG_USB_IN | SYSTEM_EVENT_FLAG_USB_OUT | - SYSTEM_EVENT_FLAG_SPI_MASTER | SYSTEM_EVENT_FLAG_I2C_MASTER | SYSTEM_EVENT_FLAG_I2C_SLAVE | - SYSTEM_EVENT_HW_INTERRUPT | SYSTEM_EVENT_FLAG_SOCKET | SYSTEM_EVENT_FLAG_DEBUGGER_ACTIVITY | - SYSTEM_EVENT_FLAG_MESSAGING_ACTIVITY | SYSTEM_EVENT_FLAG_ONEWIRE_MASTER | SYSTEM_EVENT_FLAG_RADIO | - SYSTEM_EVENT_FLAG_WIFI_STATION | SYSTEM_EVENT_FLAG_BLUETOOTH; + SYSTEM_EVENT_FLAG_COM_IN | SYSTEM_EVENT_FLAG_COM_OUT | SYSTEM_EVENT_FLAG_STORAGE_IO | + SYSTEM_EVENT_FLAG_PICOPIO | SYSTEM_EVENT_FLAG_SYSTEM_TIMER | SYSTEM_EVENT_FLAG_USB_IN | + SYSTEM_EVENT_FLAG_USB_OUT | SYSTEM_EVENT_FLAG_SPI_MASTER | SYSTEM_EVENT_FLAG_I2C_MASTER | + SYSTEM_EVENT_FLAG_I2C_SLAVE | SYSTEM_EVENT_HW_INTERRUPT | SYSTEM_EVENT_FLAG_SOCKET | + SYSTEM_EVENT_FLAG_DEBUGGER_ACTIVITY | SYSTEM_EVENT_FLAG_MESSAGING_ACTIVITY | SYSTEM_EVENT_FLAG_ONEWIRE_MASTER | + SYSTEM_EVENT_FLAG_RADIO | SYSTEM_EVENT_FLAG_WIFI_STATION | SYSTEM_EVENT_FLAG_BLUETOOTH; //--// diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_PioIrqDriver.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_PioIrqDriver.cpp index 32d2d55642..c3d9dd7ff2 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_PioIrqDriver.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_PioIrqDriver.cpp @@ -71,8 +71,7 @@ extern "C" void PioIrqServiceBlock(int block) CLR_RT_HeapBlock_NativeEventDispatcher *ctx = s_pioCtx[block]; if (ctx != nullptr) { - CLR_UINT32 packed = - ((CLR_UINT32)flags << 16) | ((CLR_UINT32)EVENT_CUSTOM << 8) | (CLR_UINT32)block; + CLR_UINT32 packed = ((CLR_UINT32)flags << 16) | ((CLR_UINT32)EVENT_CUSTOM << 8) | (CLR_UINT32)block; SaveNativeEventToHALQueue(ctx, packed, (CLR_UINT32)flags); } @@ -161,8 +160,5 @@ static const CLR_RT_DriverInterruptMethods g_PioIrqDriverMethods = { PioIrqCleanup}; // looked up by name from `new NativeEventDispatcher("PioIrqDriver", block)` -extern const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Pico_PioIrqDriver = { - "PioIrqDriver", - DRIVER_INTERRUPT_METHODS_CHECKSUM, - &g_PioIrqDriverMethods, - {1, 0, 0, 0}}; +extern const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Pico_PioIrqDriver = + {"PioIrqDriver", DRIVER_INTERRUPT_METHODS_CHECKSUM, &g_PioIrqDriverMethods, {1, 0, 0, 0}}; diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp index c1d9820687..eebc3fc2c6 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp @@ -26,12 +26,12 @@ static unsigned int PioSlotMask(int offset, int length) } #if defined(RP2350) -#define PIO_RESET_LSB 11u -#define IO_BANK0_RESET_BIT (1u << 6) +#define PIO_RESET_LSB 11u +#define IO_BANK0_RESET_BIT (1u << 6) #define PADS_BANK0_RESET_BIT (1u << 9) #else -#define PIO_RESET_LSB 10u -#define IO_BANK0_RESET_BIT (1u << 5) +#define PIO_RESET_LSB 10u +#define IO_BANK0_RESET_BIT (1u << 5) #define PADS_BANK0_RESET_BIT (1u << 8) #endif @@ -45,8 +45,7 @@ void PioEnsureOutOfReset(int blockIndex) return; } - unsigned int bits = - (1u << (PIO_RESET_LSB + (unsigned int)blockIndex)) | IO_BANK0_RESET_BIT | PADS_BANK0_RESET_BIT; + unsigned int bits = (1u << (PIO_RESET_LSB + (unsigned int)blockIndex)) | IO_BANK0_RESET_BIT | PADS_BANK0_RESET_BIT; RESETS->CLR.RESET = bits; // atomic-clear alias while ((RESETS->RESET_DONE & bits) != bits) { @@ -65,8 +64,8 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P int length = stack.Arg2().NumericByRef().s4; int origin = stack.Arg3().NumericByRef().s4; - if (PioFromIndex(block) == nullptr || block < 0 || block > 2 || instrArray == nullptr || - length <= 0 || length > 32 || (int)instrArray->m_numOfElements < length) + if (PioFromIndex(block) == nullptr || block < 0 || block > 2 || instrArray == nullptr || length <= 0 || + length > 32 || (int)instrArray->m_numOfElements < length) { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp index 31e0131d9b..48dcc1b60d 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp @@ -15,7 +15,7 @@ // PIO FSTAT: RXEMPTY [11:8], TXFULL [19:16] -- one status bit per state machine #define PIO_FSTAT_RXEMPTY_LSB 8u -#define PIO_FSTAT_TXFULL_LSB 16u +#define PIO_FSTAT_TXFULL_LSB 16u // busy-wait cap so a stalled SM times out instead of hanging static const unsigned int PIO_FIFO_WAIT_LIMIT = 0x4000000u; @@ -106,18 +106,16 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P // side-set count includes the opt enable bit; each field masked to its width unsigned int sidesetTotal = b[PIO_CFG_SIDESET_COUNT] + b[PIO_CFG_SIDESET_OPT]; - pio->SM[sm].PINCTRL = - ((sidesetTotal & 0x7u) << 29) | ((b[PIO_CFG_SET_COUNT] & 0x7u) << 26) | - ((b[PIO_CFG_OUT_COUNT] & 0x3Fu) << 20) | ((b[PIO_CFG_IN_BASE] & 0x1Fu) << 15) | - ((b[PIO_CFG_SIDESET_BASE] & 0x1Fu) << 10) | ((b[PIO_CFG_SET_BASE] & 0x1Fu) << 5) | - (b[PIO_CFG_OUT_BASE] & 0x1Fu); + pio->SM[sm].PINCTRL = ((sidesetTotal & 0x7u) << 29) | ((b[PIO_CFG_SET_COUNT] & 0x7u) << 26) | + ((b[PIO_CFG_OUT_COUNT] & 0x3Fu) << 20) | ((b[PIO_CFG_IN_BASE] & 0x1Fu) << 15) | + ((b[PIO_CFG_SIDESET_BASE] & 0x1Fu) << 10) | ((b[PIO_CFG_SET_BASE] & 0x1Fu) << 5) | + (b[PIO_CFG_OUT_BASE] & 0x1Fu); // EXECCTRL: wrap [16:12], wrap_target [11:7], side_en [30], side_pindir [29], jmp_pin [28:24] - unsigned int execCtrl = - ((b[PIO_CFG_WRAP] & 0x1Fu) << 12) | ((b[PIO_CFG_WRAP_TARGET] & 0x1Fu) << 7) | - ((b[PIO_CFG_JMP_PIN] & 0x1Fu) << 24) | ((b[PIO_CFG_MOV_STATUS_SEL] & 1u) << 4) | - (b[PIO_CFG_MOV_STATUS_N] & 0xFu) | ((b[PIO_CFG_OUT_STICKY] & 1u) << 17) | - ((b[PIO_CFG_INLINE_OUT_EN] & 1u) << 18) | ((b[PIO_CFG_OUT_EN_SEL] & 0x1Fu) << 19); + unsigned int execCtrl = ((b[PIO_CFG_WRAP] & 0x1Fu) << 12) | ((b[PIO_CFG_WRAP_TARGET] & 0x1Fu) << 7) | + ((b[PIO_CFG_JMP_PIN] & 0x1Fu) << 24) | ((b[PIO_CFG_MOV_STATUS_SEL] & 1u) << 4) | + (b[PIO_CFG_MOV_STATUS_N] & 0xFu) | ((b[PIO_CFG_OUT_STICKY] & 1u) << 17) | + ((b[PIO_CFG_INLINE_OUT_EN] & 1u) << 18) | ((b[PIO_CFG_OUT_EN_SEL] & 0x1Fu) << 19); if (b[PIO_CFG_SIDESET_OPT]) { execCtrl |= (1u << 30); @@ -133,10 +131,10 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P unsigned int pullThresh = b[PIO_CFG_PULL_THRESHOLD] & 0x1F; // FJOIN: low 2 bits -> TX [30] / RX [31]; high 2 bits (PIO v1) -> RX_GET [14] / RX_PUT [15] unsigned int join = b[PIO_CFG_FIFO_JOIN]; - pio->SM[sm].SHIFTCTRL = - ((b[PIO_CFG_IN_SHIFT_RIGHT] & 1u) << 18) | ((b[PIO_CFG_OUT_SHIFT_RIGHT] & 1u) << 19) | - ((b[PIO_CFG_AUTOPUSH] & 1u) << 16) | ((b[PIO_CFG_AUTOPULL] & 1u) << 17) | (pushThresh << 20) | - (pullThresh << 25) | ((join & 3u) << 30) | (((join >> 2) & 3u) << 14); + pio->SM[sm].SHIFTCTRL = ((b[PIO_CFG_IN_SHIFT_RIGHT] & 1u) << 18) | ((b[PIO_CFG_OUT_SHIFT_RIGHT] & 1u) << 19) | + ((b[PIO_CFG_AUTOPUSH] & 1u) << 16) | ((b[PIO_CFG_AUTOPULL] & 1u) << 17) | + (pushThresh << 20) | (pullThresh << 25) | ((join & 3u) << 30) | + (((join >> 2) & 3u) << 14); #if defined(RP2350) // GPIOBASE is 0 or 16; CMSIS types it __I so write through a volatile pointer @@ -552,7 +550,8 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeRead___STATIC__I4__I4__I4__SZARRAY_U4__I4__I4__I4(CLR_RT_StackFrame &stack) +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: + NativeRead___STATIC__I4__I4__I4__SZARRAY_U4__I4__I4__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); @@ -654,8 +653,7 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P { transferred = 0; } - if (arr != nullptr && offset >= 0 && transferred > 0 && - (offset + transferred) <= (int)arr->m_numOfElements) + if (arr != nullptr && offset >= 0 && transferred > 0 && (offset + transferred) <= (int)arr->m_numOfElements) { memcpy(arr->GetFirstElement() + (size_t)offset * 4, work->Buffer, (size_t)transferred * 4); } @@ -675,7 +673,8 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeWrite___STATIC__I4__I4__I4__SZARRAY_U4__I4__I4__I4(CLR_RT_StackFrame &stack) +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: + NativeWrite___STATIC__I4__I4__I4__SZARRAY_U4__I4__I4__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); From ef57fcf66273fe5b4ba49453b8a4e1a9d721c2f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Fri, 24 Jul 2026 15:28:00 -0600 Subject: [PATCH 33/58] Enhance PIO native code style and readability --- ...noFramework_Hardware_Pico_Pio_PioBlock.cpp | 11 ++++--- ...work_Hardware_Pico_Pio_PioStateMachine.cpp | 33 ++++++++++--------- ...anoFramework_hardware_pico_native_target.h | 4 --- 3 files changed, 23 insertions(+), 25 deletions(-) diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp index 988a46c34b..8685b20b16 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp @@ -59,7 +59,6 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P { NANOCLR_HEADER(); - PIO_TypeDef *pio; unsigned short *instr; int offset; bool relocate; @@ -69,13 +68,14 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P const int length = stack.Arg2().NumericByRef().s4; const int origin = stack.Arg3().NumericByRef().s4; - if (PioFromIndex(block) == nullptr || block < 0 || block > 2 || instrArray == nullptr || - length <= 0 || length > 32 || static_cast(instrArray->m_numOfElements) < length) + PIO_TypeDef *pio = PioFromIndex(block); + + if (pio == nullptr || block < 0 || block > 2 || instrArray == nullptr || length <= 0 || length > 32 || + static_cast(instrArray->m_numOfElements) < length) { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } - pio = PioFromIndex(block); instr = reinterpret_cast(instrArray->GetFirstElement()); PioEnsureOutOfReset(block); @@ -107,7 +107,8 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P unsigned short w = instr[i]; if (relocate && (w & 0xE000) == 0x0000) { - const unsigned int target = (static_cast(w & 0x1F) + static_cast(offset)) & 0x1F; + const unsigned int target = + (static_cast(w & 0x1F) + static_cast(offset)) & 0x1F; w = static_cast((w & ~0x1F) | target); } pio->INSTR_MEM[offset + i] = w; diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp index 08d608831c..4be037d073 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp @@ -110,18 +110,16 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P // side-set count includes the opt enable bit; each field masked to its width sidesetTotal = b[PIO_CFG_SIDESET_COUNT] + b[PIO_CFG_SIDESET_OPT]; - pio->SM[sm].PINCTRL = - ((sidesetTotal & 0x7u) << 29) | ((b[PIO_CFG_SET_COUNT] & 0x7u) << 26) | - ((b[PIO_CFG_OUT_COUNT] & 0x3Fu) << 20) | ((b[PIO_CFG_IN_BASE] & 0x1Fu) << 15) | - ((b[PIO_CFG_SIDESET_BASE] & 0x1Fu) << 10) | ((b[PIO_CFG_SET_BASE] & 0x1Fu) << 5) | - (b[PIO_CFG_OUT_BASE] & 0x1Fu); + pio->SM[sm].PINCTRL = ((sidesetTotal & 0x7u) << 29) | ((b[PIO_CFG_SET_COUNT] & 0x7u) << 26) | + ((b[PIO_CFG_OUT_COUNT] & 0x3Fu) << 20) | ((b[PIO_CFG_IN_BASE] & 0x1Fu) << 15) | + ((b[PIO_CFG_SIDESET_BASE] & 0x1Fu) << 10) | ((b[PIO_CFG_SET_BASE] & 0x1Fu) << 5) | + (b[PIO_CFG_OUT_BASE] & 0x1Fu); // EXECCTRL: wrap [16:12], wrap_target [11:7], side_en [30], side_pindir [29], jmp_pin [28:24] - execCtrl = - ((b[PIO_CFG_WRAP] & 0x1Fu) << 12) | ((b[PIO_CFG_WRAP_TARGET] & 0x1Fu) << 7) | - ((b[PIO_CFG_JMP_PIN] & 0x1Fu) << 24) | ((b[PIO_CFG_MOV_STATUS_SEL] & 1u) << 4) | - (b[PIO_CFG_MOV_STATUS_N] & 0xFu) | ((b[PIO_CFG_OUT_STICKY] & 1u) << 17) | - ((b[PIO_CFG_INLINE_OUT_EN] & 1u) << 18) | ((b[PIO_CFG_OUT_EN_SEL] & 0x1Fu) << 19); + execCtrl = ((b[PIO_CFG_WRAP] & 0x1Fu) << 12) | ((b[PIO_CFG_WRAP_TARGET] & 0x1Fu) << 7) | + ((b[PIO_CFG_JMP_PIN] & 0x1Fu) << 24) | ((b[PIO_CFG_MOV_STATUS_SEL] & 1u) << 4) | + (b[PIO_CFG_MOV_STATUS_N] & 0xFu) | ((b[PIO_CFG_OUT_STICKY] & 1u) << 17) | + ((b[PIO_CFG_INLINE_OUT_EN] & 1u) << 18) | ((b[PIO_CFG_OUT_EN_SEL] & 0x1Fu) << 19); if (b[PIO_CFG_SIDESET_OPT]) { @@ -138,10 +136,9 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P pullThresh = b[PIO_CFG_PULL_THRESHOLD] & 0x1F; // FJOIN: low 2 bits -> TX [30] / RX [31]; high 2 bits (PIO v1) -> RX_GET [14] / RX_PUT [15] join = b[PIO_CFG_FIFO_JOIN]; - pio->SM[sm].SHIFTCTRL = - ((b[PIO_CFG_IN_SHIFT_RIGHT] & 1u) << 18) | ((b[PIO_CFG_OUT_SHIFT_RIGHT] & 1u) << 19) | - ((b[PIO_CFG_AUTOPUSH] & 1u) << 16) | ((b[PIO_CFG_AUTOPULL] & 1u) << 17) | (pushThresh << 20) | - (pullThresh << 25) | ((join & 3u) << 30) | (((join >> 2) & 3u) << 14); + pio->SM[sm].SHIFTCTRL = ((b[PIO_CFG_IN_SHIFT_RIGHT] & 1u) << 18) | ((b[PIO_CFG_OUT_SHIFT_RIGHT] & 1u) << 19) | + ((b[PIO_CFG_AUTOPUSH] & 1u) << 16) | ((b[PIO_CFG_AUTOPULL] & 1u) << 17) | + (pushThresh << 20) | (pullThresh << 25) | ((join & 3u) << 30) | (((join >> 2) & 3u) << 14); #if defined(RP2350) // GPIOBASE is 0 or 16; CMSIS types it __I so write through a volatile pointer @@ -349,7 +346,8 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P const unsigned int dirs = output ? ((1u << chunk) - 1u) : 0u; // PINCTRL: SET_COUNT [28:26], SET_BASE [9:5] - pio->SM[sm].PINCTRL = (static_cast(chunk) << 26) | ((static_cast(pin - gpioBase) & 0x1Fu) << 5); + pio->SM[sm].PINCTRL = + (static_cast(chunk) << 26) | ((static_cast(pin - gpioBase) & 0x1Fu) << 5); // SET pindirs, dirs pio->SM[sm].INSTR = 0xE000u | (4u << 5) | (dirs & 0x1Fu); @@ -678,7 +676,10 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P if (arr != nullptr && offset >= 0 && transferred > 0 && (offset + transferred) <= static_cast(arr->m_numOfElements)) { - memcpy(arr->GetFirstElement() + static_cast(offset) * 4, work->Buffer, static_cast(transferred) * 4); + memcpy( + arr->GetFirstElement() + static_cast(offset) * 4, + work->Buffer, + static_cast(transferred) * 4); } (void)dmaChannelGetAndClearInterrupts(ch); diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_target.h b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_target.h index fc51062454..d03bda10db 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_target.h +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_target.h @@ -6,8 +6,6 @@ #ifndef NANOFRAMEWORK_HARDWARE_PICO_NATIVE_TARGET_H #define NANOFRAMEWORK_HARDWARE_PICO_NATIVE_TARGET_H -// Maps a PIO block index to its register block, or nullptr for an invalid index. -// RP2040 exposes PIO0/PIO1; RP2350 adds PIO2. static inline PIO_TypeDef *PioFromIndex(int index) { switch (index) @@ -25,8 +23,6 @@ static inline PIO_TypeDef *PioFromIndex(int index) } } -// Releases a PIO block (and the IO/PAD banks) from reset on first use; idempotent. Defined in -// the PioBlock translation unit so the reset state is shared across all entry points. void PioEnsureOutOfReset(int blockIndex); #endif // NANOFRAMEWORK_HARDWARE_PICO_NATIVE_TARGET_H From 56568f889e3aab208b6b97ac95a207ec1cd561ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Fri, 24 Jul 2026 20:18:00 -0600 Subject: [PATCH 34/58] Refactor PIO native code for robustness and readability Introduce an `abortGuard` in DMA channel abort loops to prevent potential hangs if the channel fails to clear the abort flag. Update the PIO IRQ driver using modern C++ features like C++17 `if` initializers, `static_cast`, `const`, `constexpr`, and designated initializers for improved code style and type safety. --- ...work_hardware_pico_native_PioIrqDriver.cpp | 48 ++++++++----------- ...work_Hardware_Pico_Pio_PioStateMachine.cpp | 9 ++-- 2 files changed, 25 insertions(+), 32 deletions(-) diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_PioIrqDriver.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_PioIrqDriver.cpp index c3d9dd7ff2..ddeaa50736 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_PioIrqDriver.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_PioIrqDriver.cpp @@ -14,7 +14,6 @@ #endif #include "nanoFramework_hardware_pico_native_target.h" -// dispatcher context per block static CLR_RT_HeapBlock_NativeEventDispatcher *s_pioCtx[3] = {nullptr, nullptr, nullptr}; static int BlockOfContext(CLR_RT_HeapBlock_NativeEventDispatcher *pContext) @@ -30,7 +29,6 @@ static int BlockOfContext(CLR_RT_HeapBlock_NativeEventDispatcher *pContext) return -1; } -// Used only by the IRQ0->NVIC wiring, compiled out on RP_PIO_REQUIRED (Pico W). #if !defined(RP_PIO_REQUIRED) static int PioIrqVector(int block) { @@ -50,7 +48,6 @@ static int PioIrqVector(int block) } #endif -// Called from the block's IRQ0 ISR (PioIrqHandlers.c), hence extern "C". extern "C" void PioIrqServiceBlock(int block) { PIO_TypeDef *pio = PioFromIndex(block); @@ -59,23 +56,19 @@ extern "C" void PioIrqServiceBlock(int block) return; } - // SaveNativeEventToHALQueue touches the shared HAL queue, so take the ISR critical section like GPIO. NATIVE_INTERRUPT_START chSysLockFromISR(); - // SM irq flags -> IRQ0_INTS bits [11:8] - unsigned int flags = (pio->IRQ0_INTS >> 8) & 0x0Fu; - if (flags != 0) + if (const unsigned int flags = (pio->IRQ0_INTS >> 8) & 0x0Fu; flags != 0) { - CLR_RT_HeapBlock_NativeEventDispatcher *ctx = s_pioCtx[block]; - if (ctx != nullptr) + if (CLR_RT_HeapBlock_NativeEventDispatcher *ctx = s_pioCtx[block]; ctx != nullptr) { - CLR_UINT32 packed = ((CLR_UINT32)flags << 16) | ((CLR_UINT32)EVENT_CUSTOM << 8) | (CLR_UINT32)block; - SaveNativeEventToHALQueue(ctx, packed, (CLR_UINT32)flags); + const CLR_UINT32 packed = (static_cast(flags) << 16) | + (static_cast(EVENT_CUSTOM) << 8) | static_cast(block); + SaveNativeEventToHALQueue(ctx, packed, flags); } - // write-1-to-clear pio->IRQ = flags; } @@ -84,17 +77,14 @@ extern "C" void PioIrqServiceBlock(int block) NATIVE_INTERRUPT_END } -// ---- NativeEventDispatcher driver procs ------------------------------------- - static HRESULT PioIrqInitialize(CLR_RT_HeapBlock_NativeEventDispatcher *pContext, unsigned __int64 userData) { - int block = (int)(userData & 0xFF); + const int block = static_cast(userData & 0xFF); if (block < 0 || block > 2 || PioFromIndex(block) == nullptr) { return CLR_E_INVALID_PARAMETER; } - // one dispatcher per block if (s_pioCtx[block] != nullptr && s_pioCtx[block] != pContext) { return CLR_E_INVALID_OPERATION; @@ -106,7 +96,7 @@ static HRESULT PioIrqInitialize(CLR_RT_HeapBlock_NativeEventDispatcher *pContext static HRESULT PioIrqEnableDisable(CLR_RT_HeapBlock_NativeEventDispatcher *pContext, bool fEnable) { - int block = BlockOfContext(pContext); + const int block = BlockOfContext(pContext); PIO_TypeDef *pio = (block >= 0) ? PioFromIndex(block) : nullptr; if (pio == nullptr) { @@ -114,7 +104,7 @@ static HRESULT PioIrqEnableDisable(CLR_RT_HeapBlock_NativeEventDispatcher *pCont } #if !defined(RP_PIO_REQUIRED) - int vector = PioIrqVector(block); + const int vector = PioIrqVector(block); if (fEnable) { pio->IRQ0_INTE |= (0x0Fu << 8); @@ -136,12 +126,10 @@ static HRESULT PioIrqEnableDisable(CLR_RT_HeapBlock_NativeEventDispatcher *pCont static HRESULT PioIrqCleanup(CLR_RT_HeapBlock_NativeEventDispatcher *pContext) { - int block = BlockOfContext(pContext); - if (block >= 0) + if (const int block = BlockOfContext(pContext); block >= 0) { #if !defined(RP_PIO_REQUIRED) - PIO_TypeDef *pio = PioFromIndex(block); - if (pio != nullptr) + if (PIO_TypeDef *pio = PioFromIndex(block); pio != nullptr) { pio->IRQ0_INTE &= ~(0x0Fu << 8); nvicDisableVector(PioIrqVector(block)); @@ -154,11 +142,13 @@ static HRESULT PioIrqCleanup(CLR_RT_HeapBlock_NativeEventDispatcher *pContext) return S_OK; } -static const CLR_RT_DriverInterruptMethods g_PioIrqDriverMethods = { - PioIrqInitialize, - PioIrqEnableDisable, - PioIrqCleanup}; +static constexpr CLR_RT_DriverInterruptMethods g_PioIrqDriverMethods = { + .initProcessor = PioIrqInitialize, + .enableProcessor = PioIrqEnableDisable, + .cleanupProcessor = PioIrqCleanup}; -// looked up by name from `new NativeEventDispatcher("PioIrqDriver", block)` -extern const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Pico_PioIrqDriver = - {"PioIrqDriver", DRIVER_INTERRUPT_METHODS_CHECKSUM, &g_PioIrqDriverMethods, {1, 0, 0, 0}}; +extern const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Pico_PioIrqDriver = { + .m_szAssemblyName = "PioIrqDriver", + .m_checkSum = DRIVER_INTERRUPT_METHODS_CHECKSUM, + .m_pNativeMethods = &g_PioIrqDriverMethods, + .m_Version = {.iMajorVersion = 1, .iMinorVersion = 0, .iBuildNumber = 0, .iRevisionNumber = 0}}; diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp index 4be037d073..16d0535254 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp @@ -663,7 +663,9 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P { ch->channel->CTRL_TRIG &= ~DMA_CTRL_TRIG_EN; DMA->CHAN_ABORT = (1u << ch->chnidx); - while (DMA->CHAN_ABORT & (1u << ch->chnidx)) + + unsigned int abortGuard = PIO_FIFO_WAIT_LIMIT; + while (DMA->CHAN_ABORT & (1u << ch->chnidx) && --abortGuard) { } } @@ -789,12 +791,13 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P { const rp_dma_channel_t *ch = work->Channel; - // on timeout the channel is still busy; stop it so it can't read after we free the buffer if (dmaChannelIsBusyX(ch)) { ch->channel->CTRL_TRIG &= ~DMA_CTRL_TRIG_EN; DMA->CHAN_ABORT = (1u << ch->chnidx); - while (DMA->CHAN_ABORT & (1u << ch->chnidx)) + + unsigned int abortGuard = PIO_FIFO_WAIT_LIMIT; + while ((DMA->CHAN_ABORT & (1u << ch->chnidx)) && --abortGuard) { } } From c7afd20f4d2fde90afc4fbe82008f9596ccb5766 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Sat, 25 Jul 2026 04:39:26 -0600 Subject: [PATCH 35/58] Pico.PIO: Remove deprecated IRQ driver and handlers --- ...work_hardware_pico_native_PioIrqDriver.cpp | 154 ------------------ ...work_hardware_pico_native_PioIrqHandlers.c | 36 ---- 2 files changed, 190 deletions(-) delete mode 100644 targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_PioIrqDriver.cpp delete mode 100644 targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_PioIrqHandlers.c diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_PioIrqDriver.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_PioIrqDriver.cpp deleted file mode 100644 index ddeaa50736..0000000000 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_PioIrqDriver.cpp +++ /dev/null @@ -1,154 +0,0 @@ -// -// Copyright (c) .NET Foundation and Contributors -// See LICENSE file in the project root for full license information. -// - -#include "nanoFramework_hardware_pico_native.h" -#include -#include // chSysLockFromISR -#include // nvicEnableVector + RP_PIOx_IRQ_0_NUMBER -#if defined(RP2350) -#include "rp2350.h" -#else -#include "rp2040.h" -#endif -#include "nanoFramework_hardware_pico_native_target.h" - -static CLR_RT_HeapBlock_NativeEventDispatcher *s_pioCtx[3] = {nullptr, nullptr, nullptr}; - -static int BlockOfContext(CLR_RT_HeapBlock_NativeEventDispatcher *pContext) -{ - for (int b = 0; b < 3; b++) - { - if (s_pioCtx[b] == pContext) - { - return b; - } - } - - return -1; -} - -#if !defined(RP_PIO_REQUIRED) -static int PioIrqVector(int block) -{ - switch (block) - { - case 0: - return RP_PIO0_IRQ_0_NUMBER; - case 1: - return RP_PIO1_IRQ_0_NUMBER; -#if defined(RP2350) - case 2: - return RP_PIO2_IRQ_0_NUMBER; -#endif - default: - return -1; - } -} -#endif - -extern "C" void PioIrqServiceBlock(int block) -{ - PIO_TypeDef *pio = PioFromIndex(block); - if (pio == nullptr) - { - return; - } - - NATIVE_INTERRUPT_START - - chSysLockFromISR(); - - if (const unsigned int flags = (pio->IRQ0_INTS >> 8) & 0x0Fu; flags != 0) - { - if (CLR_RT_HeapBlock_NativeEventDispatcher *ctx = s_pioCtx[block]; ctx != nullptr) - { - const CLR_UINT32 packed = (static_cast(flags) << 16) | - (static_cast(EVENT_CUSTOM) << 8) | static_cast(block); - SaveNativeEventToHALQueue(ctx, packed, flags); - } - - pio->IRQ = flags; - } - - chSysUnlockFromISR(); - - NATIVE_INTERRUPT_END -} - -static HRESULT PioIrqInitialize(CLR_RT_HeapBlock_NativeEventDispatcher *pContext, unsigned __int64 userData) -{ - const int block = static_cast(userData & 0xFF); - if (block < 0 || block > 2 || PioFromIndex(block) == nullptr) - { - return CLR_E_INVALID_PARAMETER; - } - - if (s_pioCtx[block] != nullptr && s_pioCtx[block] != pContext) - { - return CLR_E_INVALID_OPERATION; - } - - s_pioCtx[block] = pContext; - return S_OK; -} - -static HRESULT PioIrqEnableDisable(CLR_RT_HeapBlock_NativeEventDispatcher *pContext, bool fEnable) -{ - const int block = BlockOfContext(pContext); - PIO_TypeDef *pio = (block >= 0) ? PioFromIndex(block) : nullptr; - if (pio == nullptr) - { - return CLR_E_INVALID_PARAMETER; - } - -#if !defined(RP_PIO_REQUIRED) - const int vector = PioIrqVector(block); - if (fEnable) - { - pio->IRQ0_INTE |= (0x0Fu << 8); - nvicEnableVector(vector, 3); // kernel-safe priority - } - else - { - pio->IRQ0_INTE &= ~(0x0Fu << 8); - nvicDisableVector(vector); - } -#else - // PIO IRQ0 is owned by the CYW43 driver on Pico W, so it can't reach managed code - (void)fEnable; - return CLR_E_NOT_SUPPORTED; -#endif - - return S_OK; -} - -static HRESULT PioIrqCleanup(CLR_RT_HeapBlock_NativeEventDispatcher *pContext) -{ - if (const int block = BlockOfContext(pContext); block >= 0) - { -#if !defined(RP_PIO_REQUIRED) - if (PIO_TypeDef *pio = PioFromIndex(block); pio != nullptr) - { - pio->IRQ0_INTE &= ~(0x0Fu << 8); - nvicDisableVector(PioIrqVector(block)); - } -#endif - s_pioCtx[block] = nullptr; - } - - CleanupNativeEventsFromHALQueue(pContext); - return S_OK; -} - -static constexpr CLR_RT_DriverInterruptMethods g_PioIrqDriverMethods = { - .initProcessor = PioIrqInitialize, - .enableProcessor = PioIrqEnableDisable, - .cleanupProcessor = PioIrqCleanup}; - -extern const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Pico_PioIrqDriver = { - .m_szAssemblyName = "PioIrqDriver", - .m_checkSum = DRIVER_INTERRUPT_METHODS_CHECKSUM, - .m_pNativeMethods = &g_PioIrqDriverMethods, - .m_Version = {.iMajorVersion = 1, .iMinorVersion = 0, .iBuildNumber = 0, .iRevisionNumber = 0}}; diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_PioIrqHandlers.c b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_PioIrqHandlers.c deleted file mode 100644 index bb11b57b0a..0000000000 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_PioIrqHandlers.c +++ /dev/null @@ -1,36 +0,0 @@ -// -// Copyright (c) .NET Foundation and Contributors -// See LICENSE file in the project root for full license information. -// - -#include - -// RP_PIO_REQUIRED -> ChibiOS rp_pio.c owns these vectors (Pico W / CYW43); skip ours to avoid a clash. -#if !defined(RP_PIO_REQUIRED) - -extern void PioIrqServiceBlock(int block); - -OSAL_IRQ_HANDLER(RP_PIO0_IRQ_0_HANDLER) -{ - OSAL_IRQ_PROLOGUE(); - PioIrqServiceBlock(0); - OSAL_IRQ_EPILOGUE(); -} - -OSAL_IRQ_HANDLER(RP_PIO1_IRQ_0_HANDLER) -{ - OSAL_IRQ_PROLOGUE(); - PioIrqServiceBlock(1); - OSAL_IRQ_EPILOGUE(); -} - -#if defined(RP2350) -OSAL_IRQ_HANDLER(RP_PIO2_IRQ_0_HANDLER) -{ - OSAL_IRQ_PROLOGUE(); - PioIrqServiceBlock(2); - OSAL_IRQ_EPILOGUE(); -} -#endif - -#endif // !RP_PIO_REQUIRED From 7c18610619bae3ba5a7d0d0fe7b1164004d4b204 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Sat, 25 Jul 2026 04:39:26 -0600 Subject: [PATCH 36/58] Pico.PIO: Add validation macros and remove legacy reset helper --- ...anoFramework_hardware_pico_native_target.h | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_target.h b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_target.h index d03bda10db..d67d33e395 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_target.h +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_target.h @@ -23,6 +23,34 @@ static inline PIO_TypeDef *PioFromIndex(int index) } } -void PioEnsureOutOfReset(int blockIndex); +#if defined(RP2350) +#define PIO_MAX_BLOCK 2 +#define PIO_MAX_PIN 47 +#else +#define PIO_MAX_BLOCK 1 +#define PIO_MAX_PIN 29 +#endif + +#if defined(RP_PIO_REQUIRED) +#define PIO_MIN_BLOCK 1 +#else +#define PIO_MIN_BLOCK 0 +#endif + +#define VALIDATE_PIO_BLOCK(block) \ + if ((block) < 0 || (block) > PIO_MAX_BLOCK) \ + { \ + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); \ + } \ + if ((block) < PIO_MIN_BLOCK) \ + { \ + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); \ + } + +#define VALIDATE_SM(sm) \ + if ((sm) < 0 || (sm) > 3) \ + { \ + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); \ + } #endif // NANOFRAMEWORK_HARDWARE_PICO_NATIVE_TARGET_H From e2d2f774e61e14d998ae29ac79b9b123d4431287 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Sat, 25 Jul 2026 04:39:26 -0600 Subject: [PATCH 37/58] Pico.PIO: Refactor native methods for common PIO HAL interaction --- ...noFramework_Hardware_Pico_Pio_PioBlock.cpp | 173 +++-------- ...work_Hardware_Pico_Pio_PioStateMachine.cpp | 276 +++++++++--------- 2 files changed, 187 insertions(+), 262 deletions(-) diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp index 8685b20b16..4a0edd9f0f 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp @@ -4,54 +4,23 @@ // #include "nanoFramework_hardware_pico_native.h" +#include "nanoFramework_hardware_pico_native_target.h" #if defined(RP2350) #include "rp2350.h" #else #include "rp2040.h" #endif -#include "nanoFramework_hardware_pico_native_target.h" -unsigned int g_PioInstrUsed[3] = {0, 0, 0}; -unsigned int g_PioClaimedSm[3] = {0, 0, 0}; +#define EVENT_TYPE_PIO 160 -static unsigned int PioSlotMask(int offset, int length) +static void PioChibiOSCallback(void *param, const uint32_t flags) { - if (length <= 0) - { - return 0u; - } - - unsigned int span = (length >= 32) ? 0xFFFFFFFFu : ((1u << length) - 1u); - return span << offset; -} - -#if defined(RP2350) -#define PIO_RESET_LSB 11u -#define IO_BANK0_RESET_BIT (1u << 6) -#define PADS_BANK0_RESET_BIT (1u << 9) -#else -#define PIO_RESET_LSB 10u -#define IO_BANK0_RESET_BIT (1u << 5) -#define PADS_BANK0_RESET_BIT (1u << 8) -#endif - -// PIO boots held in reset; release each block once, on first use of any entry point -static unsigned int g_PioOutOfReset = 0; + const int block = reinterpret_cast(param); -void PioEnsureOutOfReset(int blockIndex) -{ - if (g_PioOutOfReset & (1u << blockIndex)) - { - return; - } + PostManagedEvent(EVENT_PIO, EVENT_TYPE_PIO, static_cast(block), flags); - unsigned int bits = (1u << (PIO_RESET_LSB + (unsigned int)blockIndex)) | IO_BANK0_RESET_BIT | PADS_BANK0_RESET_BIT; - RESETS->CLR.RESET = bits; // atomic-clear alias - while ((RESETS->RESET_DONE & bits) != bits) - { - } - - g_PioOutOfReset |= (1u << blockIndex); + // Clear the flag in hardware to avoid an infinite loop of interrupts. + __rp_pio_blocks[block].pio->IRQ = flags; } HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock:: @@ -59,61 +28,30 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P { NANOCLR_HEADER(); - unsigned short *instr; + rp_pio_program_t prog; int offset; - bool relocate; const int block = stack.Arg0().NumericByRef().s4; CLR_RT_HeapBlock_Array *instrArray = stack.Arg1().DereferenceArray(); const int length = stack.Arg2().NumericByRef().s4; const int origin = stack.Arg3().NumericByRef().s4; - PIO_TypeDef *pio = PioFromIndex(block); + VALIDATE_PIO_BLOCK(block); - if (pio == nullptr || block < 0 || block > 2 || instrArray == nullptr || length <= 0 || length > 32 || - static_cast(instrArray->m_numOfElements) < length) + if (instrArray == nullptr || length <= 0 || length > 32 || static_cast(instrArray->m_numOfElements) < length) { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } - instr = reinterpret_cast(instrArray->GetFirstElement()); - PioEnsureOutOfReset(block); + prog.instructions = reinterpret_cast(instrArray->GetFirstElement()); + prog.length = length; + prog.origin = origin; - offset = -1; - if (origin >= 0) - { - if (origin <= 32 - length && (g_PioInstrUsed[block] & PioSlotMask(origin, length)) == 0) - { - offset = origin; - } - } - else - { - for (int candidate = 0; candidate + length <= 32; candidate++) - { - if ((g_PioInstrUsed[block] & PioSlotMask(candidate, length)) == 0) - { - offset = candidate; - break; - } - } - } + offset = pioProgramLoad(&__rp_pio_blocks[block], &prog); - if (offset >= 0) + if (offset < 0) { - relocate = origin < 0; - for (int i = 0; i < length; i++) - { - unsigned short w = instr[i]; - if (relocate && (w & 0xE000) == 0x0000) - { - const unsigned int target = - (static_cast(w & 0x1F) + static_cast(offset)) & 0x1F; - w = static_cast((w & ~0x1F) | target); - } - pio->INSTR_MEM[offset + i] = w; - } - g_PioInstrUsed[block] |= PioSlotMask(offset, length); + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); // No hay memoria } stack.SetResult_I4(offset); @@ -126,31 +64,18 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P { NANOCLR_HEADER(); - unsigned int mask; - const int block = stack.Arg0().NumericByRef().s4; const int length = stack.Arg1().NumericByRef().s4; const int offset = stack.Arg2().NumericByRef().s4; - PIO_TypeDef *pio = PioFromIndex(block); - if (pio == nullptr || offset < 0 || length <= 0 || length > 32 || offset > 32 - length) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } + VALIDATE_PIO_BLOCK(block); - mask = PioSlotMask(offset, length); - if ((g_PioInstrUsed[block] & mask) != mask) + if (offset < 0 || length <= 0 || length > 32 || offset > 32 - length) { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } - PioEnsureOutOfReset(block); - for (int i = 0; i < length; i++) - { - pio->INSTR_MEM[offset + i] = static_cast((offset + i) & 0x1F); - } - - g_PioInstrUsed[block] &= ~mask; + pioProgramUnload(&__rp_pio_blocks[block], offset, length); NANOCLR_NOCLEANUP(); } @@ -160,34 +85,28 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P { NANOCLR_HEADER(); - int claimed; - const int block = stack.Arg0().NumericByRef().s4; const bool required = stack.Arg1().NumericByRef().u1; - if (PioFromIndex(block) == nullptr) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } + VALIDATE_PIO_BLOCK(block); - claimed = -1; - for (int sm = 0; sm < 4; sm++) + if (const rp_pio_sm_t *sm = pioSmAlloc( + &__rp_pio_blocks[block], + RP_PIO_SM_ID_ANY, + 3, + PioChibiOSCallback, + reinterpret_cast(block)); + sm == nullptr) { - if ((g_PioClaimedSm[block] & (1u << sm)) == 0) - { - g_PioClaimedSm[block] |= (1u << sm); - claimed = sm; - break; - } + if (required) + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + stack.SetResult_I4(-1); } - - if (claimed < 0 && required) + else { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + stack.SetResult_I4(static_cast(sm->smidx)); } - stack.SetResult_I4(claimed); - NANOCLR_NOCLEANUP(); } @@ -196,21 +115,25 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P { NANOCLR_HEADER(); + uint32_t mode; + const int block = stack.Arg0().NumericByRef().s4; const int pin = stack.Arg1().NumericByRef().s4; -#if defined(RP2350) - if (block < 0 || block > 2 || pin < 0 || pin > 47) -#else - if (block < 0 || block > 1 || pin < 0 || pin > 29) -#endif + VALIDATE_PIO_BLOCK(block) + + if (pin < 0 || pin > PIO_MAX_PIN) { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } - PioEnsureOutOfReset(block); - IO_BANK0->GPIO[pin].CTRL = 6u + static_cast(block); - PADS_BANK0->GPIO[pin] = (PADS_BANK0->GPIO[pin] & ~0x180u) | 0x40u; + mode = (block == 0) ? PAL_MODE_ALTERNATE_PIO0 : PAL_MODE_ALTERNATE_PIO1; +#if defined(RP2350) + if (block == 2) + mode = PAL_MODE_ALTERNATE_PIO2; +#endif + + palSetPadMode(0, pin, mode); NANOCLR_NOCLEANUP(); } @@ -223,14 +146,14 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P const int block = stack.Arg0().NumericByRef().s4; const int irq = stack.Arg1().NumericByRef().s4; - PIO_TypeDef *pio = PioFromIndex(block); - if (pio == nullptr || irq < 0 || irq > 7) + VALIDATE_PIO_BLOCK(block); + + if (irq < 0 || irq > 7) { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } - PioEnsureOutOfReset(block); - pio->IRQ_FORCE = (1u << irq); + __rp_pio_blocks[block].pio->IRQ_FORCE = (1u << irq); NANOCLR_NOCLEANUP(); } diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp index 16d0535254..10b550f6c7 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp @@ -18,17 +18,16 @@ static constexpr unsigned int PIO_FIFO_WAIT_LIMIT = 0x4000000u; -// DMA bulk-read state, one slot per block/sm (Channel == nullptr when idle). The channel is a ChibiOS -// RP DMA descriptor so completion arrives via PioDmaCallback (no raw NVIC vector, no clash with the SPI DMA). +extern const rp_pio_sm_t *g_AllocatedSMs[3][4]; + struct PioDmaWork { const rp_dma_channel_t *Channel; unsigned int *Buffer; unsigned int Count; }; -static PioDmaWork g_PioDmaWork[3][4] = {}; -// Independent TX slots so a Write can run concurrently with a Read on the same state machine. +static PioDmaWork g_PioDmaWork[3][4] = {}; static PioDmaWork g_PioDmaWorkTx[3][4] = {}; // DMA completion callback (ChibiOS shared handler dispatches here); just wake the waiting thread @@ -78,27 +77,25 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P { NANOCLR_HEADER(); + PIO_TypeDef *pio; unsigned int *b; - unsigned int sidesetTotal; - unsigned int execCtrl; - unsigned int pushThresh; - unsigned int pullThresh; - // FJOIN: low 2 bits -> TX [30] / RX [31]; high 2 bits (PIO v1) -> RX_GET [14] / RX_PUT [15] - unsigned int join; + unsigned int sidesetTotal, execCtrl, pushThresh, pullThresh, join; const int block = stack.Arg0().NumericByRef().s4; const int sm = stack.Arg1().NumericByRef().s4; const int offset = stack.Arg2().NumericByRef().s4; CLR_RT_HeapBlock_Array *blobArray = stack.Arg3().DereferenceArray(); - PIO_TypeDef *pio = PioFromIndex(block); - if (pio == nullptr || sm < 0 || sm > 3 || offset < 0 || offset > 31 || blobArray == nullptr || + VALIDATE_PIO_BLOCK(block); + VALIDATE_SM(sm); + + if (offset < 0 || offset > 31 || blobArray == nullptr || static_cast(blobArray->m_numOfElements) < PIO_CFG_BLOB_LENGTH) { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } - PioEnsureOutOfReset(block); + pio = __rp_pio_blocks[block].pio; b = reinterpret_cast(blobArray->GetFirstElement()); // disable + restart before reconfigure @@ -141,11 +138,9 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P (pushThresh << 20) | (pullThresh << 25) | ((join & 3u) << 30) | (((join >> 2) & 3u) << 14); #if defined(RP2350) - // GPIOBASE is 0 or 16; CMSIS types it __I so write through a volatile pointer *reinterpret_cast(&pio->GPIOBASE) = (b[PIO_CFG_GPIO_BASE] == 16) ? 16u : 0u; #endif - // set PC via JMP (opcode 0) pio->SM[sm].INSTR = static_cast(offset & 0x1F); NANOCLR_NOCLEANUP(); @@ -160,20 +155,16 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P const int sm = stack.Arg1().NumericByRef().s4; const bool enabled = stack.Arg2().NumericByRef().u1; - PIO_TypeDef *pio = PioFromIndex(block); - if (pio == nullptr || sm < 0 || sm > 3) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } - PioEnsureOutOfReset(block); + VALIDATE_PIO_BLOCK(block); + VALIDATE_SM(sm); if (enabled) { - pio->CTRL |= (1u << sm); + __rp_pio_blocks[block].pio->CTRL |= (1u << sm); } else { - pio->CTRL &= ~(1u << sm); + __rp_pio_blocks[block].pio->CTRL &= ~(1u << sm); } NANOCLR_NOCLEANUP(); @@ -184,28 +175,29 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P { NANOCLR_HEADER(); + PIO_TypeDef *pio; unsigned int guard; const int block = stack.Arg0().NumericByRef().s4; const int sm = stack.Arg1().NumericByRef().s4; const unsigned int value = stack.Arg2().NumericByRef().u4; - PIO_TypeDef *pio = PioFromIndex(block); - if (pio == nullptr || sm < 0 || sm > 3) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } - PioEnsureOutOfReset(block); + VALIDATE_PIO_BLOCK(block); + VALIDATE_SM(sm); + + pio = __rp_pio_blocks[block].pio; // FSTAT TX_FULL = bits [19:16] guard = PIO_FIFO_WAIT_LIMIT; while ((pio->FSTAT & (1u << (PIO_FSTAT_TXFULL_LSB + sm))) && --guard) { } + if (guard == 0) { NANOCLR_SET_AND_LEAVE(CLR_E_TIMEOUT); } + pio->TXF[sm] = value; NANOCLR_NOCLEANUP(); @@ -216,27 +208,28 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P { NANOCLR_HEADER(); + const PIO_TypeDef *pio; unsigned int guard; const int block = stack.Arg0().NumericByRef().s4; const int sm = stack.Arg1().NumericByRef().s4; - const PIO_TypeDef *pio = PioFromIndex(block); - if (pio == nullptr || sm < 0 || sm > 3) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } - PioEnsureOutOfReset(block); + VALIDATE_PIO_BLOCK(block); + VALIDATE_SM(sm); + + pio = __rp_pio_blocks[block].pio; // FSTAT RX_EMPTY = bits [11:8] guard = PIO_FIFO_WAIT_LIMIT; while ((pio->FSTAT & (1u << (PIO_FSTAT_RXEMPTY_LSB + sm))) && --guard) { } + if (guard == 0) { NANOCLR_SET_AND_LEAVE(CLR_E_TIMEOUT); } + stack.SetResult_U4(pio->RXF[sm]); NANOCLR_NOCLEANUP(); @@ -247,15 +240,15 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P { NANOCLR_HEADER(); + const PIO_TypeDef *pio; + const int block = stack.Arg0().NumericByRef().s4; const int sm = stack.Arg1().NumericByRef().s4; - const PIO_TypeDef *pio = PioFromIndex(block); - if (pio == nullptr || sm < 0 || sm > 3) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } - PioEnsureOutOfReset(block); + VALIDATE_PIO_BLOCK(block); + VALIDATE_SM(sm); + + pio = __rp_pio_blocks[block].pio; stack.SetResult_Boolean((pio->FSTAT & (1u << (PIO_FSTAT_TXFULL_LSB + sm))) != 0); @@ -267,15 +260,15 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P { NANOCLR_HEADER(); + const PIO_TypeDef *pio; + const int block = stack.Arg0().NumericByRef().s4; const int sm = stack.Arg1().NumericByRef().s4; - const PIO_TypeDef *pio = PioFromIndex(block); - if (pio == nullptr || sm < 0 || sm > 3) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } - PioEnsureOutOfReset(block); + VALIDATE_PIO_BLOCK(block); + VALIDATE_SM(sm); + + pio = __rp_pio_blocks[block].pio; stack.SetResult_Boolean((pio->FSTAT & (1u << (PIO_FSTAT_RXEMPTY_LSB + sm))) != 0); @@ -290,16 +283,16 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P const int block = stack.Arg0().NumericByRef().s4; const int sm = stack.Arg1().NumericByRef().s4; - PIO_TypeDef *pio = PioFromIndex(block); - if (pio == nullptr || sm < 0 || sm > 3) + VALIDATE_PIO_BLOCK(block); + VALIDATE_SM(sm); + + __rp_pio_blocks[block].pio->CTRL &= ~(1u << sm); + + if (g_AllocatedSMs[block][sm] != nullptr) { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + pioSmFree(g_AllocatedSMs[block][sm]); + g_AllocatedSMs[block][sm] = nullptr; } - PioEnsureOutOfReset(block); - - // stop + release the claim - pio->CTRL &= ~(1u << sm); - g_PioClaimedSm[block] &= ~(1u << sm); NANOCLR_NOCLEANUP(); } @@ -309,8 +302,7 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P { NANOCLR_HEADER(); - int pin; - int remaining; + int pin, remaining, gpioBase; unsigned int savedPinCtrl; const int block = stack.Arg0().NumericByRef().s4; @@ -319,21 +311,25 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P const int count = stack.Arg3().NumericByRef().s4; const bool output = stack.Arg4().NumericByRef().u1; - PIO_TypeDef *pio = PioFromIndex(block); + PIO_TypeDef *pio; + + VALIDATE_PIO_BLOCK(block); + VALIDATE_SM(sm); + + pio = __rp_pio_blocks[block].pio; + #if defined(RP2350) - constexpr int maxPins = 48; - const int gpioBase = (pio != nullptr) ? (int)pio->GPIOBASE : 0; + gpioBase = static_cast(pio->GPIOBASE); #else - constexpr int maxPins = 30; - const int gpioBase = 0; + gpioBase = 0; #endif + // SET_BASE is 5-bit, relative to the SM's GPIO base, so reject pins outside the 32-pin window - if (pio == nullptr || sm < 0 || sm > 3 || count < 0 || count > 32 || basePin < gpioBase || - basePin - gpioBase > 32 - count || basePin > maxPins - count) + if (count < 0 || count > 32 || basePin < gpioBase || basePin - gpioBase > 32 - count || + basePin > PIO_MAX_PIN + 1 - count) { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } - PioEnsureOutOfReset(block); // up to 5 pins per "SET pindirs" exec, then restore PINCTRL pin = basePin; @@ -365,17 +361,16 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P { NANOCLR_HEADER(); + PIO_TypeDef *pio; unsigned int fjoinRx; const int block = stack.Arg0().NumericByRef().s4; const int sm = stack.Arg1().NumericByRef().s4; - PIO_TypeDef *pio = PioFromIndex(block); - if (pio == nullptr || sm < 0 || sm > 3) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } - PioEnsureOutOfReset(block); + VALIDATE_PIO_BLOCK(block); + VALIDATE_SM(sm); + + pio = __rp_pio_blocks[block].pio; // toggle FJOIN_RX (bit 31) twice to flush both FIFOs, SHIFTCTRL unchanged fjoinRx = (1u << 31); @@ -390,6 +385,7 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P { NANOCLR_HEADER(); + PIO_TypeDef *pio; unsigned int autopull; unsigned int instr; unsigned int guard; @@ -397,12 +393,10 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P const int block = stack.Arg0().NumericByRef().s4; const int sm = stack.Arg1().NumericByRef().s4; - PIO_TypeDef *pio = PioFromIndex(block); - if (pio == nullptr || sm < 0 || sm > 3) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } - PioEnsureOutOfReset(block); + VALIDATE_PIO_BLOCK(block); + VALIDATE_SM(sm); + + pio = __rp_pio_blocks[block].pio; // exec OUT NULL,32 (autopull) or PULL noblock until TX empty. FSTAT TX_EMPTY = bits [27:24] autopull = pio->SM[sm].SHIFTCTRL & (1u << 17); @@ -426,15 +420,15 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P { NANOCLR_HEADER(); + PIO_TypeDef *pio; + const int block = stack.Arg0().NumericByRef().s4; const int sm = stack.Arg1().NumericByRef().s4; - PIO_TypeDef *pio = PioFromIndex(block); - if (pio == nullptr || sm < 0 || sm > 3) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } - PioEnsureOutOfReset(block); + VALIDATE_PIO_BLOCK(block); + VALIDATE_SM(sm); + + pio = __rp_pio_blocks[block].pio; // SM_RESTART = bits [7:4] pio->CTRL |= (1u << (4 + sm)); @@ -447,15 +441,15 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P { NANOCLR_HEADER(); + PIO_TypeDef *pio; + const int block = stack.Arg0().NumericByRef().s4; const int sm = stack.Arg1().NumericByRef().s4; - PIO_TypeDef *pio = PioFromIndex(block); - if (pio == nullptr || sm < 0 || sm > 3) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } - PioEnsureOutOfReset(block); + VALIDATE_PIO_BLOCK(block); + VALIDATE_SM(sm); + + pio = __rp_pio_blocks[block].pio; // CLKDIV_RESTART = bits [11:8] pio->CTRL |= (1u << (8 + sm)); @@ -468,16 +462,16 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P { NANOCLR_HEADER(); + PIO_TypeDef *pio; + const int block = stack.Arg0().NumericByRef().s4; const int sm = stack.Arg1().NumericByRef().s4; const unsigned short instruction = stack.Arg2().NumericByRef().u2; - PIO_TypeDef *pio = PioFromIndex(block); - if (pio == nullptr || sm < 0 || sm > 3) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } - PioEnsureOutOfReset(block); + VALIDATE_PIO_BLOCK(block); + VALIDATE_SM(sm); + + pio = __rp_pio_blocks[block].pio; // exec out of band, PC unchanged pio->SM[sm].INSTR = static_cast(instruction); @@ -490,15 +484,15 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P { NANOCLR_HEADER(); + const PIO_TypeDef *pio; + const int block = stack.Arg0().NumericByRef().s4; const int sm = stack.Arg1().NumericByRef().s4; - const PIO_TypeDef *pio = PioFromIndex(block); - if (pio == nullptr || sm < 0 || sm > 3) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } - PioEnsureOutOfReset(block); + VALIDATE_PIO_BLOCK(block); + VALIDATE_SM(sm); + + pio = __rp_pio_blocks[block].pio; stack.SetResult_U4((pio->FLEVEL >> (8 * sm)) & 0xFu); @@ -510,15 +504,15 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P { NANOCLR_HEADER(); + const PIO_TypeDef *pio; + const int block = stack.Arg0().NumericByRef().s4; const int sm = stack.Arg1().NumericByRef().s4; - const PIO_TypeDef *pio = PioFromIndex(block); - if (pio == nullptr || sm < 0 || sm > 3) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } - PioEnsureOutOfReset(block); + VALIDATE_PIO_BLOCK(block); + VALIDATE_SM(sm); + + pio = __rp_pio_blocks[block].pio; stack.SetResult_U4((pio->FLEVEL >> (8 * sm + 4)) & 0xFu); @@ -530,15 +524,15 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P { NANOCLR_HEADER(); + const PIO_TypeDef *pio; + const int block = stack.Arg0().NumericByRef().s4; const int sm = stack.Arg1().NumericByRef().s4; - const PIO_TypeDef *pio = PioFromIndex(block); - if (pio == nullptr || sm < 0 || sm > 3) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } - PioEnsureOutOfReset(block); + VALIDATE_PIO_BLOCK(block); + VALIDATE_SM(sm); + + pio = __rp_pio_blocks[block].pio; stack.SetResult_U4(pio->SM[sm].ADDR & 0x1Fu); @@ -550,19 +544,22 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P { NANOCLR_HEADER(); + PIO_TypeDef *pio; + const int block = stack.Arg0().NumericByRef().s4; const int sm = stack.Arg1().NumericByRef().s4; const int clkDivInt = stack.Arg2().NumericByRef().s4; const int clkDivFrac = stack.Arg3().NumericByRef().s4; - PIO_TypeDef *pio = PioFromIndex(block); + VALIDATE_PIO_BLOCK(block); + VALIDATE_SM(sm); + + pio = PioFromIndex(block); // 16-bit int + 8-bit frac fields - if (pio == nullptr || sm < 0 || sm > 3 || clkDivInt < 0 || clkDivInt > 0xFFFF || clkDivFrac < 0 || - clkDivFrac > 0xFF) + if (clkDivInt < 0 || clkDivInt > 0xFFFF || clkDivFrac < 0 || clkDivFrac > 0xFF) { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } - PioEnsureOutOfReset(block); pio->SM[sm].CLKDIV = (static_cast(clkDivInt) << 16) | (static_cast(clkDivFrac) << 8); pio->CTRL |= (1u << (8 + sm)); @@ -580,6 +577,9 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P bool eventResult = true; int transferred = 0; + PIO_TypeDef *pio; + PioDmaWork *work; + const int block = stack.Arg0().NumericByRef().s4; const int sm = stack.Arg1().NumericByRef().s4; CLR_RT_HeapBlock_Array *arr = stack.Arg2().DereferenceArray(); @@ -587,8 +587,11 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P const int count = stack.Arg4().NumericByRef().s4; const int timeoutMs = stack.Arg5().NumericByRef().s4; - PIO_TypeDef *pio = PioFromIndex(block); - PioDmaWork *work = &g_PioDmaWork[block][sm]; + VALIDATE_PIO_BLOCK(block); + VALIDATE_SM(sm); + + pio = __rp_pio_blocks[block].pio; + work = &g_PioDmaWork[block][sm]; hbTimeout.SetInteger(static_cast(timeoutMs) * TIME_CONVERSION__TO_MILLISECONDS); NANOCLR_CHECK_HRESULT(stack.SetupTimeoutFromTicks(hbTimeout, timeoutTicks)); @@ -597,12 +600,7 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P if (stack.m_customState == 1) { // PIO RX DREQ is only mapped for PIO0/PIO1; PIO2 (RP2350) not wired yet - if (pio == nullptr || block > 1 || sm < 0 || sm > 3) - { - NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); - } - // native ownership check replaces the managed _disposed test - if ((g_PioClaimedSm[block] & (1u << sm)) == 0) + if (g_AllocatedSMs[block][sm] == nullptr) { NANOCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); } @@ -626,7 +624,8 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P } // read = SM RX FIFO (fixed), write = bounce buffer (incrementing), paced by the SM RX DREQ - const unsigned int dreq = (block == 0 ? 4u : 12u) + static_cast(sm); + const unsigned int dreq = (static_cast(block) * 8u) + 4u + static_cast(sm); + ch->channel->READ_ADDR = reinterpret_cast(&pio->RXF[sm]); ch->channel->WRITE_ADDR = reinterpret_cast(buf); ch->channel->TRANS_COUNT = static_cast(count); @@ -709,6 +708,9 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P bool eventResult = true; int transferred = 0; + PIO_TypeDef *pio; + PioDmaWork *work; + const int block = stack.Arg0().NumericByRef().s4; const int sm = stack.Arg1().NumericByRef().s4; CLR_RT_HeapBlock_Array *arr = stack.Arg2().DereferenceArray(); @@ -716,8 +718,11 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P const int count = stack.Arg4().NumericByRef().s4; const int timeoutMs = stack.Arg5().NumericByRef().s4; - PIO_TypeDef *pio = PioFromIndex(block); - PioDmaWork *work = &g_PioDmaWorkTx[block][sm]; + VALIDATE_PIO_BLOCK(block); + VALIDATE_SM(sm); + + pio = __rp_pio_blocks[block].pio; + work = &g_PioDmaWorkTx[block][sm]; hbTimeout.SetInteger(static_cast(timeoutMs) * TIME_CONVERSION__TO_MILLISECONDS); NANOCLR_CHECK_HRESULT(stack.SetupTimeoutFromTicks(hbTimeout, timeoutTicks)); @@ -726,15 +731,11 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P if (stack.m_customState == 1) { // PIO TX DREQ is only mapped for PIO0/PIO1; PIO2 (RP2350) not wired yet - if (pio == nullptr || block > 1 || sm < 0 || sm > 3) - { - NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); - } - // native ownership check replaces the managed _disposed test - if ((g_PioClaimedSm[block] & (1u << sm)) == 0) + if (g_AllocatedSMs[block][sm] == nullptr) { NANOCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); } + if (arr == nullptr || count <= 0 || work->Channel != nullptr || offset < 0 || (offset + count) > static_cast(arr->m_numOfElements)) { @@ -759,9 +760,10 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P memcpy(buf, arr->GetFirstElement() + static_cast(offset) * 4, static_cast(count) * 4); // read = bounce buffer (incrementing), write = SM TX FIFO (fixed), paced by the SM TX DREQ - unsigned int dreq = (block == 0 ? 0u : 8u) + static_cast(sm); - ch->channel->READ_ADDR = (unsigned int)reinterpret_cast(buf); - ch->channel->WRITE_ADDR = (unsigned int)reinterpret_cast(&pio->TXF[sm]); + const unsigned int dreq = (static_cast(block) * 8u) + static_cast(sm); + + ch->channel->READ_ADDR = reinterpret_cast(buf); + ch->channel->WRITE_ADDR = reinterpret_cast(&pio->TXF[sm]); ch->channel->TRANS_COUNT = static_cast(count); dmaChannelEnableInterruptX(ch); ch->channel->CTRL_TRIG = DMA_CTRL_TRIG_EN | DMA_CTRL_TRIG_DATA_SIZE_WORD | DMA_CTRL_TRIG_INCR_READ | From 4007ab36b97066addb2a25f5991d6a6cac3a48ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Sat, 25 Jul 2026 04:39:26 -0600 Subject: [PATCH 38/58] Pico.PIO: Implement managed IRQ eventing --- src/HAL/Include/nanoHAL_v2.h | 1 + .../nanoFramework_hardware_pico_native.cpp | 9 ++++++ .../nanoFramework_hardware_pico_native.h | 20 ++++++++++--- ...noFramework_Hardware_Pico_Pio_PioBlock.cpp | 30 ++++++++++++++++--- 4 files changed, 52 insertions(+), 8 deletions(-) diff --git a/src/HAL/Include/nanoHAL_v2.h b/src/HAL/Include/nanoHAL_v2.h index c59bf553ca..25bdb08dc1 100644 --- a/src/HAL/Include/nanoHAL_v2.h +++ b/src/HAL/Include/nanoHAL_v2.h @@ -116,6 +116,7 @@ typedef enum SLEEP_LEVEL #define EVENT_TOUCH 120 #define EVENT_GESTURE 130 #define EVENT_OPENTHREAD 140 +#define EVENT_PIO 160 #define PAL_EVENT_TOUCH 0x1 #define PAL_EVENT_KEY 0x2 diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp index b32992814e..3cdadd1641 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp @@ -90,6 +90,15 @@ static const CLR_RT_MethodHandler method_lookup[] = Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::NativeInitGpio___STATIC__VOID__I4__I4, Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::NativeForceIrq___STATIC__VOID__I4__I4, Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::NativeClearIrq___STATIC__VOID__I4__I4, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::NativeSetIrqEnabled___STATIC__VOID__I4__BOOLEAN, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, NULL, NULL, NULL, diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.h b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.h index f90d6e4a64..b842f52faa 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.h +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.h @@ -142,17 +142,29 @@ struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pi struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock { + static const int FIELD_STATIC__s_eventListener = 2; static const int FIELD___index = 1; - static const int FIELD___irqDispatcher = 2; - static const int FIELD___interruptCallbacks = 3; - static const int FIELD___irqLock = 4; - + static const int FIELD___interruptCallbacks = 2; + static const int FIELD___irqLock = 3; NANOCLR_NATIVE_DECLARE(NativeAddProgram___STATIC__I4__I4__SZARRAY_U2__I4__I4); NANOCLR_NATIVE_DECLARE(NativeRemoveProgram___STATIC__VOID__I4__I4__I4); NANOCLR_NATIVE_DECLARE(NativeClaimUnusedSm___STATIC__I4__I4__BOOLEAN); NANOCLR_NATIVE_DECLARE(NativeInitGpio___STATIC__VOID__I4__I4); NANOCLR_NATIVE_DECLARE(NativeForceIrq___STATIC__VOID__I4__I4); NANOCLR_NATIVE_DECLARE(NativeClearIrq___STATIC__VOID__I4__I4); + NANOCLR_NATIVE_DECLARE(NativeSetIrqEnabled___STATIC__VOID__I4__BOOLEAN); +}; + +struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioEvent +{ + static const int FIELD__BlockIndex = 3; + static const int FIELD__Flags = 4; +}; + +struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioEventListener +{ + static const int FIELD___pioMap = 1; + static const int FIELD___syncRoot = 2; }; struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioProgramOptions diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp index 4a0edd9f0f..4ffdc0820b 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp @@ -166,14 +166,36 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P const int block = stack.Arg0().NumericByRef().s4; const int irq = stack.Arg1().NumericByRef().s4; - PIO_TypeDef *pio = PioFromIndex(block); - if (pio == nullptr || irq < 0 || irq > 7) + VALIDATE_PIO_BLOCK(block); + + if (irq < 0 || irq > 7) { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } - PioEnsureOutOfReset(block); - pio->IRQ = (1u << irq); + __rp_pio_blocks[block].pio->IRQ = (1u << irq); + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock:: + NativeSetIrqEnabled___STATIC__VOID__I4__BOOLEAN(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + const int block = stack.Arg0().NumericByRef().s4; + const bool enabled = static_cast(stack.Arg1().NumericByRef().u1); + + VALIDATE_PIO_BLOCK(block); + + if (enabled) + { + __rp_pio_blocks[block].pio->IRQ0_INTE |= (0x0Fu << 8); + } + else + { + __rp_pio_blocks[block].pio->IRQ0_INTE &= ~(0x0Fu << 8); + } NANOCLR_NOCLEANUP(); } From ac05552ab73050106c4397d59f57dafb7d6c8ef2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Sat, 25 Jul 2026 04:39:26 -0600 Subject: [PATCH 39/58] Pico.PIO: Update assembly checksum --- .../nanoFramework_hardware_pico_native.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp index 3cdadd1641..0834058d3d 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp @@ -242,7 +242,10 @@ static const CLR_RT_MethodHandler method_lookup[] = const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Pico = { - "nanoFramework.Hardware.Pico",0x52CD0E56,method_lookup,{ 1, 0, 0, 0 } + "nanoFramework.Hardware.Pico", + 0x4AF39F9D, + method_lookup, + { 1, 0, 0, 0 } }; // clang-format on From 5bf0f3b4bc34526746a8ef4be183dae0ea8d9df2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Sat, 25 Jul 2026 15:03:52 -0600 Subject: [PATCH 40/58] Remove obsolete PioIrqDriver components These source files and their native assembly registration are no longer required following the refactoring of PIO native methods and the implementation of managed IRQ eventing. --- CMake/Modules/FindNF_NativeAssemblies.cmake | 5 +---- CMake/Modules/FindnanoFramework.Hardware.Pico.cmake | 2 -- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/CMake/Modules/FindNF_NativeAssemblies.cmake b/CMake/Modules/FindNF_NativeAssemblies.cmake index 23c2646ff9..c6c6ebdab9 100644 --- a/CMake/Modules/FindNF_NativeAssemblies.cmake +++ b/CMake/Modules/FindNF_NativeAssemblies.cmake @@ -1,4 +1,4 @@ -# +# # Copyright (c) .NET Foundation and Contributors # See LICENSE file in the project root for full license information. # @@ -275,9 +275,6 @@ endif() if(API_Hardware.Pico) ##### API name here (doted name) PerformSettingsForApiEntry("nanoFramework.Hardware.Pico") - - list(APPEND CLR_RT_NativeAssemblyDataList "extern const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Pico_PioIrqDriver;") - list(APPEND CLR_RT_NativeAssemblyDataTableEntriesList "&g_CLR_AssemblyNative_nanoFramework_Hardware_Pico_PioIrqDriver,") endif() # nanoFramework.Device.Can diff --git a/CMake/Modules/FindnanoFramework.Hardware.Pico.cmake b/CMake/Modules/FindnanoFramework.Hardware.Pico.cmake index bcda9a8feb..81619fea57 100644 --- a/CMake/Modules/FindnanoFramework.Hardware.Pico.cmake +++ b/CMake/Modules/FindnanoFramework.Hardware.Pico.cmake @@ -18,8 +18,6 @@ set(nanoFramework.Hardware.Pico_SRCS nanoFramework_hardware_pico_native.cpp nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp - nanoFramework_hardware_pico_native_PioIrqDriver.cpp - nanoFramework_hardware_pico_native_PioIrqHandlers.c ) foreach(SRC_FILE ${nanoFramework.Hardware.Pico_SRCS}) From ad1df21eba780dec79d16cc4dec1830f1e9c0ec7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Sat, 25 Jul 2026 15:06:31 -0600 Subject: [PATCH 41/58] Rename PIO event definitions to PICO_PIO --- src/HAL/Include/nanoHAL_v2.h | 2 +- ...e_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/HAL/Include/nanoHAL_v2.h b/src/HAL/Include/nanoHAL_v2.h index 25bdb08dc1..0ac96299fe 100644 --- a/src/HAL/Include/nanoHAL_v2.h +++ b/src/HAL/Include/nanoHAL_v2.h @@ -116,7 +116,7 @@ typedef enum SLEEP_LEVEL #define EVENT_TOUCH 120 #define EVENT_GESTURE 130 #define EVENT_OPENTHREAD 140 -#define EVENT_PIO 160 +#define EVENT_PICO_PIO 160 #define PAL_EVENT_TOUCH 0x1 #define PAL_EVENT_KEY 0x2 diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp index 4ffdc0820b..aea6984923 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp @@ -11,13 +11,13 @@ #include "rp2040.h" #endif -#define EVENT_TYPE_PIO 160 +#define EVENT_TYPE_PICO_PIO 160 static void PioChibiOSCallback(void *param, const uint32_t flags) { const int block = reinterpret_cast(param); - PostManagedEvent(EVENT_PIO, EVENT_TYPE_PIO, static_cast(block), flags); + PostManagedEvent(EVENT_PICO_PIO, EVENT_TYPE_PICO_PIO, static_cast(block), flags); // Clear the flag in hardware to avoid an infinite loop of interrupts. __rp_pio_blocks[block].pio->IRQ = flags; From 1327a40020e69a1d03f49218c07f8a01e8f93aed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Sat, 25 Jul 2026 15:53:46 -0600 Subject: [PATCH 42/58] Correctly extract state machine IRQ flags The callback's `flags` parameter includes all IRQ sources. Extracting only the state machine IRQ flags (IRQ0_INTS) ensures that managed events receive relevant information and that only the intended hardware IRQ bits are cleared, aligning with documentation. --- ...o_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp index aea6984923..8811d45701 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp @@ -17,10 +17,13 @@ static void PioChibiOSCallback(void *param, const uint32_t flags) { const int block = reinterpret_cast(param); - PostManagedEvent(EVENT_PICO_PIO, EVENT_TYPE_PICO_PIO, static_cast(block), flags); + // Align the flags to the PIO block - See IRQ0_INTS documentation + const uint32_t sm_flags = (flags >> 8) & 0x0F; + + PostManagedEvent(EVENT_PICO_PIO, EVENT_TYPE_PICO_PIO, static_cast(block), sm_flags); // Clear the flag in hardware to avoid an infinite loop of interrupts. - __rp_pio_blocks[block].pio->IRQ = flags; + __rp_pio_blocks[block].pio->IRQ = sm_flags; } HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock:: @@ -120,7 +123,7 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P const int block = stack.Arg0().NumericByRef().s4; const int pin = stack.Arg1().NumericByRef().s4; - VALIDATE_PIO_BLOCK(block) + VALIDATE_PIO_BLOCK(block); if (pin < 0 || pin > PIO_MAX_PIN) { From dea9b6b7f732807b57c3bcd836828c0338e69735 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Sat, 25 Jul 2026 19:29:40 -0600 Subject: [PATCH 43/58] Add VALIDATE_NOT_DISPOSED macro for nanoframework.Hardware.Pico --- .../nanoFramework_hardware_pico_native_target.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_target.h b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_target.h index d67d33e395..48eba622c0 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_target.h +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_target.h @@ -53,4 +53,14 @@ static inline PIO_TypeDef *PioFromIndex(int index) NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); \ } +#define VALIDATE_NOT_DISPOSED(stack) \ + { \ + CLR_RT_HeapBlock *pThis = (stack).This(); \ + FAULT_ON_NULL(pThis); \ + if (pThis[FIELD___disposed].NumericByRef().u1 != 0) \ + { \ + NANOCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); \ + } \ + } + #endif // NANOFRAMEWORK_HARDWARE_PICO_NATIVE_TARGET_H From c2f0a071121d67226cdb4307acf61fbe510e1570 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Sat, 25 Jul 2026 19:29:41 -0600 Subject: [PATCH 44/58] Remove unused PioFromIndex helper function --- .../nanoFramework_hardware_pico_native_target.h | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_target.h b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_target.h index 48eba622c0..dddef69156 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_target.h +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_target.h @@ -6,23 +6,6 @@ #ifndef NANOFRAMEWORK_HARDWARE_PICO_NATIVE_TARGET_H #define NANOFRAMEWORK_HARDWARE_PICO_NATIVE_TARGET_H -static inline PIO_TypeDef *PioFromIndex(int index) -{ - switch (index) - { - case 0: - return PIO0; - case 1: - return PIO1; -#if defined(RP2350) - case 2: - return PIO2; -#endif - default: - return nullptr; - } -} - #if defined(RP2350) #define PIO_MAX_BLOCK 2 #define PIO_MAX_PIN 47 From 69c857a26ac17373fc09e9a7c805e415cfdbe8bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Sat, 25 Jul 2026 19:29:41 -0600 Subject: [PATCH 45/58] Add PioInterruptFlags enum --- .../nanoFramework_hardware_pico_native.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.h b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.h index b842f52faa..1919d3013f 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.h +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.h @@ -46,6 +46,15 @@ typedef enum __nfpack PioFifoJoin PioFifoJoin_PutGet = 12, } PioFifoJoin; +typedef enum __nfpack PioInterruptFlags +{ + PioInterruptFlags_None = 0, + PioInterruptFlags_Sm0 = 1, + PioInterruptFlags_Sm1 = 2, + PioInterruptFlags_Sm2 = 4, + PioInterruptFlags_Sm3 = 8, +} PioInterruptFlags; + typedef enum __nfpack PioMovOp { PioMovOp_None = 0, From a1dac755e6154117a771aaaaf43f0b9f47904eea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Sat, 25 Jul 2026 19:29:41 -0600 Subject: [PATCH 46/58] Standardize method argument handling and add disposal checks for nanoframework.Hardware.Pico --- ...work_Hardware_Pico_Pio_PioStateMachine.cpp | 127 +++++++++++++----- 1 file changed, 90 insertions(+), 37 deletions(-) diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp index 10b550f6c7..394e3ccaec 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp @@ -78,13 +78,24 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NANOCLR_HEADER(); PIO_TypeDef *pio; + CLR_RT_HeapBlock_Array *blobArray; unsigned int *b; unsigned int sidesetTotal, execCtrl, pushThresh, pullThresh, join; + int block, sm, offset; - const int block = stack.Arg0().NumericByRef().s4; - const int sm = stack.Arg1().NumericByRef().s4; - const int offset = stack.Arg2().NumericByRef().s4; - CLR_RT_HeapBlock_Array *blobArray = stack.Arg3().DereferenceArray(); + VALIDATE_NOT_DISPOSED(stack); + + block = stack.Arg0().NumericByRef().s4; + sm = stack.Arg1().NumericByRef().s4; + offset = stack.Arg2().NumericByRef().s4; + blobArray = stack.Arg3().DereferenceArray(); + + FAULT_ON_NULL(blobArray); + + if (offset > 31) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } VALIDATE_PIO_BLOCK(block); VALIDATE_SM(sm); @@ -151,9 +162,14 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P { NANOCLR_HEADER(); - const int block = stack.Arg0().NumericByRef().s4; - const int sm = stack.Arg1().NumericByRef().s4; - const bool enabled = stack.Arg2().NumericByRef().u1; + int block, sm; + bool enabled; + + VALIDATE_NOT_DISPOSED(stack); + + block = stack.Arg0().NumericByRef().s4; + sm = stack.Arg1().NumericByRef().s4; + enabled = stack.Arg2().NumericByRef().u1; VALIDATE_PIO_BLOCK(block); VALIDATE_SM(sm); @@ -176,11 +192,14 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NANOCLR_HEADER(); PIO_TypeDef *pio; - unsigned int guard; + unsigned int guard, value; + int block, sm; - const int block = stack.Arg0().NumericByRef().s4; - const int sm = stack.Arg1().NumericByRef().s4; - const unsigned int value = stack.Arg2().NumericByRef().u4; + VALIDATE_NOT_DISPOSED(stack); + + block = stack.Arg0().NumericByRef().s4; + sm = stack.Arg1().NumericByRef().s4; + value = stack.Arg2().NumericByRef().u4; VALIDATE_PIO_BLOCK(block); VALIDATE_SM(sm); @@ -210,9 +229,12 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P const PIO_TypeDef *pio; unsigned int guard; + int block, sm; - const int block = stack.Arg0().NumericByRef().s4; - const int sm = stack.Arg1().NumericByRef().s4; + VALIDATE_NOT_DISPOSED(stack); + + block = stack.Arg0().NumericByRef().s4; + sm = stack.Arg1().NumericByRef().s4; VALIDATE_PIO_BLOCK(block); VALIDATE_SM(sm); @@ -241,9 +263,12 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NANOCLR_HEADER(); const PIO_TypeDef *pio; + int block, sm; - const int block = stack.Arg0().NumericByRef().s4; - const int sm = stack.Arg1().NumericByRef().s4; + VALIDATE_NOT_DISPOSED(stack); + + block = stack.Arg0().NumericByRef().s4; + sm = stack.Arg1().NumericByRef().s4; VALIDATE_PIO_BLOCK(block); VALIDATE_SM(sm); @@ -261,9 +286,12 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NANOCLR_HEADER(); const PIO_TypeDef *pio; + int block, sm; - const int block = stack.Arg0().NumericByRef().s4; - const int sm = stack.Arg1().NumericByRef().s4; + VALIDATE_NOT_DISPOSED(stack); + + block = stack.Arg0().NumericByRef().s4; + sm = stack.Arg1().NumericByRef().s4; VALIDATE_PIO_BLOCK(block); VALIDATE_SM(sm); @@ -363,9 +391,12 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P PIO_TypeDef *pio; unsigned int fjoinRx; + int block, sm; - const int block = stack.Arg0().NumericByRef().s4; - const int sm = stack.Arg1().NumericByRef().s4; + VALIDATE_NOT_DISPOSED(stack); + + block = stack.Arg0().NumericByRef().s4; + sm = stack.Arg1().NumericByRef().s4; VALIDATE_PIO_BLOCK(block); VALIDATE_SM(sm); @@ -386,12 +417,13 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NANOCLR_HEADER(); PIO_TypeDef *pio; - unsigned int autopull; - unsigned int instr; - unsigned int guard; + unsigned int autopull, instr, guard; + int block, sm; - const int block = stack.Arg0().NumericByRef().s4; - const int sm = stack.Arg1().NumericByRef().s4; + VALIDATE_NOT_DISPOSED(stack); + + block = stack.Arg0().NumericByRef().s4; + sm = stack.Arg1().NumericByRef().s4; VALIDATE_PIO_BLOCK(block); VALIDATE_SM(sm); @@ -421,9 +453,12 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NANOCLR_HEADER(); PIO_TypeDef *pio; + int block, sm; - const int block = stack.Arg0().NumericByRef().s4; - const int sm = stack.Arg1().NumericByRef().s4; + VALIDATE_NOT_DISPOSED(stack); + + block = stack.Arg0().NumericByRef().s4; + sm = stack.Arg1().NumericByRef().s4; VALIDATE_PIO_BLOCK(block); VALIDATE_SM(sm); @@ -442,9 +477,13 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NANOCLR_HEADER(); PIO_TypeDef *pio; + int block; + int sm; - const int block = stack.Arg0().NumericByRef().s4; - const int sm = stack.Arg1().NumericByRef().s4; + VALIDATE_NOT_DISPOSED(stack); + + block = stack.Arg0().NumericByRef().s4; + sm = stack.Arg1().NumericByRef().s4; VALIDATE_PIO_BLOCK(block); VALIDATE_SM(sm); @@ -463,10 +502,15 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NANOCLR_HEADER(); PIO_TypeDef *pio; + int block; + int sm; + unsigned short instruction; - const int block = stack.Arg0().NumericByRef().s4; - const int sm = stack.Arg1().NumericByRef().s4; - const unsigned short instruction = stack.Arg2().NumericByRef().u2; + VALIDATE_NOT_DISPOSED(stack); + + block = stack.Arg0().NumericByRef().s4; + sm = stack.Arg1().NumericByRef().s4; + instruction = stack.Arg2().NumericByRef().u2; VALIDATE_PIO_BLOCK(block); VALIDATE_SM(sm); @@ -485,9 +529,12 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NANOCLR_HEADER(); const PIO_TypeDef *pio; + int block, sm; - const int block = stack.Arg0().NumericByRef().s4; - const int sm = stack.Arg1().NumericByRef().s4; + VALIDATE_NOT_DISPOSED(stack); + + block = stack.Arg0().NumericByRef().s4; + sm = stack.Arg1().NumericByRef().s4; VALIDATE_PIO_BLOCK(block); VALIDATE_SM(sm); @@ -505,9 +552,12 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NANOCLR_HEADER(); const PIO_TypeDef *pio; + int block, sm; - const int block = stack.Arg0().NumericByRef().s4; - const int sm = stack.Arg1().NumericByRef().s4; + VALIDATE_NOT_DISPOSED(stack); + + block = stack.Arg0().NumericByRef().s4; + sm = stack.Arg1().NumericByRef().s4; VALIDATE_PIO_BLOCK(block); VALIDATE_SM(sm); @@ -525,9 +575,12 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NANOCLR_HEADER(); const PIO_TypeDef *pio; + int block, sm; - const int block = stack.Arg0().NumericByRef().s4; - const int sm = stack.Arg1().NumericByRef().s4; + VALIDATE_NOT_DISPOSED(stack); + + block = stack.Arg0().NumericByRef().s4; + sm = stack.Arg1().NumericByRef().s4; VALIDATE_PIO_BLOCK(block); VALIDATE_SM(sm); From 5f32931aca689aa9f28b4cbf1c7929da1d713aa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Sat, 25 Jul 2026 19:29:41 -0600 Subject: [PATCH 47/58] Improve pin configuration validation in NativeSetPinsConfig for Pico --- ...ework_Hardware_Pico_Pio_PioStateMachine.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp index 394e3ccaec..8d18f243d9 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp @@ -330,16 +330,18 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P { NANOCLR_HEADER(); + PIO_TypeDef *pio; int pin, remaining, gpioBase; + int block, sm, basePin, count, output; unsigned int savedPinCtrl; - const int block = stack.Arg0().NumericByRef().s4; - const int sm = stack.Arg1().NumericByRef().s4; - const int basePin = stack.Arg2().NumericByRef().s4; - const int count = stack.Arg3().NumericByRef().s4; - const bool output = stack.Arg4().NumericByRef().u1; + VALIDATE_NOT_DISPOSED(stack); - PIO_TypeDef *pio; + block = stack.Arg0().NumericByRef().s4; + sm = stack.Arg1().NumericByRef().s4; + basePin = stack.Arg2().NumericByRef().s4; + count = stack.Arg3().NumericByRef().s4; + output = stack.Arg4().NumericByRef().u1; VALIDATE_PIO_BLOCK(block); VALIDATE_SM(sm); @@ -353,8 +355,8 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P #endif // SET_BASE is 5-bit, relative to the SM's GPIO base, so reject pins outside the 32-pin window - if (count < 0 || count > 32 || basePin < gpioBase || basePin - gpioBase > 32 - count || - basePin > PIO_MAX_PIN + 1 - count) + if (basePin < 0 || basePin > PIO_MAX_PIN || count < 0 || count > 32 || (basePin + count) > (PIO_MAX_PIN + 1) || + basePin < gpioBase || (basePin - gpioBase + count) > 32) { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } From 19b27c92acf50c11b1766474a99429eed5326d9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Sat, 25 Jul 2026 19:29:41 -0600 Subject: [PATCH 48/58] Allow floating-point clock divisor for PIO state machine --- .../nanoFramework_hardware_pico_native.cpp | 2 +- .../nanoFramework_hardware_pico_native.h | 2 +- ...work_Hardware_Pico_Pio_PioStateMachine.cpp | 31 +++++++++++++------ 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp index 0834058d3d..78b98cb9e6 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp @@ -218,7 +218,7 @@ static const CLR_RT_MethodHandler method_lookup[] = Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeTxLevel___STATIC__U4__I4__I4, Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeRxLevel___STATIC__U4__I4__I4, Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeGetPc___STATIC__U4__I4__I4, - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeSetClockDivisor___STATIC__VOID__I4__I4__I4__I4, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeSetClockDivisor___STATIC__VOID__I4__I4__R4, NULL, NULL, NULL, diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.h b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.h index 1919d3013f..c066ab7a28 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.h +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.h @@ -235,7 +235,7 @@ struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pi NANOCLR_NATIVE_DECLARE(NativeTxLevel___STATIC__U4__I4__I4); NANOCLR_NATIVE_DECLARE(NativeRxLevel___STATIC__U4__I4__I4); NANOCLR_NATIVE_DECLARE(NativeGetPc___STATIC__U4__I4__I4); - NANOCLR_NATIVE_DECLARE(NativeSetClockDivisor___STATIC__VOID__I4__I4__I4__I4); + NANOCLR_NATIVE_DECLARE(NativeSetClockDivisor___STATIC__VOID__I4__I4__R4); }; struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachineConfig diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp index 8d18f243d9..2a916a758e 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp @@ -595,28 +595,41 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P } HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: - NativeSetClockDivisor___STATIC__VOID__I4__I4__I4__I4(CLR_RT_StackFrame &stack) + NativeSetClockDivisor___STATIC__VOID__I4__I4__R4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); PIO_TypeDef *pio; + int block, sm, intPart, frac; + float div; - const int block = stack.Arg0().NumericByRef().s4; - const int sm = stack.Arg1().NumericByRef().s4; - const int clkDivInt = stack.Arg2().NumericByRef().s4; - const int clkDivFrac = stack.Arg3().NumericByRef().s4; + VALIDATE_NOT_DISPOSED(stack); + + block = stack.Arg0().NumericByRef().s4; + sm = stack.Arg1().NumericByRef().s4; + div = stack.Arg2().NumericByRef().r4; VALIDATE_PIO_BLOCK(block); VALIDATE_SM(sm); - pio = PioFromIndex(block); - // 16-bit int + 8-bit frac fields - if (clkDivInt < 0 || clkDivInt > 0xFFFF || clkDivFrac < 0 || clkDivFrac > 0xFF) + if (!(div >= 1.0f && div <= 65536.0f)) { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } - pio->SM[sm].CLKDIV = (static_cast(clkDivInt) << 16) | (static_cast(clkDivFrac) << 8); + intPart = static_cast(div); + frac = static_cast(roundf((div - static_cast(intPart)) * 256.0f)); + if (frac > 255) + { + frac = 0; + intPart += 1; + } + + pio = __rp_pio_blocks[block].pio; + + pio->SM[sm].CLKDIV = + (static_cast(intPart >= 65536 ? 0 : intPart) << 16) | (static_cast(frac) << 8); + pio->CTRL |= (1u << (8 + sm)); NANOCLR_NOCLEANUP(); From 907d7194d744719bf2b142c9f0fce44b3a99beff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Sat, 25 Jul 2026 19:29:41 -0600 Subject: [PATCH 49/58] Add robust parameter validation to DMA Read/Write methods for Pico --- ...work_Hardware_Pico_Pio_PioStateMachine.cpp | 74 ++++++++++++++----- 1 file changed, 55 insertions(+), 19 deletions(-) diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp index 2a916a758e..f83a265169 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp @@ -642,18 +642,36 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P CLR_RT_HeapBlock hbTimeout{}; CLR_INT64 *timeoutTicks; + CLR_RT_HeapBlock_Array *buffer; bool eventResult = true; int transferred = 0; + int block, sm, offset, count, timeoutMs; PIO_TypeDef *pio; PioDmaWork *work; - const int block = stack.Arg0().NumericByRef().s4; - const int sm = stack.Arg1().NumericByRef().s4; - CLR_RT_HeapBlock_Array *arr = stack.Arg2().DereferenceArray(); - const int offset = stack.Arg3().NumericByRef().s4; - const int count = stack.Arg4().NumericByRef().s4; - const int timeoutMs = stack.Arg5().NumericByRef().s4; + VALIDATE_NOT_DISPOSED(stack); + + block = stack.Arg0().NumericByRef().s4; + sm = stack.Arg1().NumericByRef().s4; + buffer = stack.Arg2().DereferenceArray(); + offset = stack.Arg3().NumericByRef().s4; + count = stack.Arg4().NumericByRef().s4; + timeoutMs = stack.Arg5().NumericByRef().s4; + + FAULT_ON_NULL(buffer); + + if (offset < 0 || count < 0 || timeoutMs < 0 || count > static_cast(buffer->m_numOfElements) || + offset > static_cast(buffer->m_numOfElements) - count) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + if (count == 0) + { + stack.SetResult_I4(false); + NANOCLR_EXIT_ON_SUCCESS(S_OK); + } VALIDATE_PIO_BLOCK(block); VALIDATE_SM(sm); @@ -672,7 +690,7 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P { NANOCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); } - if (arr == nullptr || count <= 0 || work->Channel != nullptr) + if (buffer == nullptr || count <= 0 || work->Channel != nullptr) { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); } @@ -742,11 +760,11 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P { transferred = 0; } - if (arr != nullptr && offset >= 0 && transferred > 0 && - (offset + transferred) <= static_cast(arr->m_numOfElements)) + if (buffer != nullptr && offset >= 0 && transferred > 0 && + (offset + transferred) <= static_cast(buffer->m_numOfElements)) { memcpy( - arr->GetFirstElement() + static_cast(offset) * 4, + buffer->GetFirstElement() + static_cast(offset) * 4, work->Buffer, static_cast(transferred) * 4); } @@ -773,18 +791,36 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P CLR_RT_HeapBlock hbTimeout{}; CLR_INT64 *timeoutTicks; + CLR_RT_HeapBlock_Array *buffer = nullptr; bool eventResult = true; int transferred = 0; + int block, sm, offset, count, timeoutMs; PIO_TypeDef *pio; PioDmaWork *work; - const int block = stack.Arg0().NumericByRef().s4; - const int sm = stack.Arg1().NumericByRef().s4; - CLR_RT_HeapBlock_Array *arr = stack.Arg2().DereferenceArray(); - const int offset = stack.Arg3().NumericByRef().s4; - const int count = stack.Arg4().NumericByRef().s4; - const int timeoutMs = stack.Arg5().NumericByRef().s4; + VALIDATE_NOT_DISPOSED(stack); + + block = stack.Arg0().NumericByRef().s4; + sm = stack.Arg1().NumericByRef().s4; + buffer = stack.Arg2().DereferenceArray(); + offset = stack.Arg3().NumericByRef().s4; + count = stack.Arg4().NumericByRef().s4; + timeoutMs = stack.Arg5().NumericByRef().s4; + + FAULT_ON_NULL(buffer); + + if (offset < 0 || count < 0 || timeoutMs < 0 || count > static_cast(buffer->m_numOfElements) || + offset > static_cast(buffer->m_numOfElements) - count) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + if (count == 0) + { + stack.SetResult_I4(false); + NANOCLR_EXIT_ON_SUCCESS(S_OK); + } VALIDATE_PIO_BLOCK(block); VALIDATE_SM(sm); @@ -804,8 +840,8 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NANOCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); } - if (arr == nullptr || count <= 0 || work->Channel != nullptr || offset < 0 || - (offset + count) > static_cast(arr->m_numOfElements)) + if (buffer == nullptr || count <= 0 || work->Channel != nullptr || offset < 0 || + (offset + count) > static_cast(buffer->m_numOfElements)) { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); } @@ -825,7 +861,7 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P } // copy the words out into the bounce buffer before the DMA drains it into the TX FIFO - memcpy(buf, arr->GetFirstElement() + static_cast(offset) * 4, static_cast(count) * 4); + memcpy(buf, buffer->GetFirstElement() + static_cast(offset) * 4, static_cast(count) * 4); // read = bounce buffer (incrementing), write = SM TX FIFO (fixed), paced by the SM TX DREQ const unsigned int dreq = (static_cast(block) * 8u) + static_cast(sm); From 90e1f42dc5768bb8c5174232a944b954e082f8b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Sat, 25 Jul 2026 19:29:41 -0600 Subject: [PATCH 50/58] Update nanoFramework.Hardware.Pico native assembly GUID --- .../nanoFramework_hardware_pico_native.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp index 78b98cb9e6..c1e271c1de 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp @@ -243,7 +243,7 @@ static const CLR_RT_MethodHandler method_lookup[] = const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Pico = { "nanoFramework.Hardware.Pico", - 0x4AF39F9D, + 0x0AB1471F, method_lookup, { 1, 0, 0, 0 } }; From 36ee8f59114ce4a0d1e8d5683a89ae70bb2c7076 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Sat, 25 Jul 2026 22:48:03 -0600 Subject: [PATCH 51/58] Refactor PIO native methods to instance members Converts PIO native methods from static utility functions to instance methods on the PioBlock object. This improves the object-oriented design by associating operations directly with a PioBlock instance. Additionally, the Add/Remove Program methods now directly accept a PioProgram object, simplifying their usage. The native assembly GUID is updated as a result of these API changes. --- .../nanoFramework_hardware_pico_native.cpp | 19 ++-- .../nanoFramework_hardware_pico_native.h | 14 +-- ...noFramework_Hardware_Pico_Pio_PioBlock.cpp | 98 +++++++++++++++---- 3 files changed, 93 insertions(+), 38 deletions(-) diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp index c1e271c1de..9ffbf3e78e 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp @@ -73,24 +73,19 @@ static const CLR_RT_MethodHandler method_lookup[] = NULL, NULL, NULL, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::AddProgram___U4__nanoFrameworkHardwarePicoPioPioProgram, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::RemoveProgram___VOID__nanoFrameworkHardwarePicoPioPioProgram__U4, NULL, NULL, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::InitGpio___VOID__I4, NULL, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::ForceIrq___VOID__I4, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::ClearIrq___VOID__I4, NULL, NULL, NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::NativeAddProgram___STATIC__I4__I4__SZARRAY_U2__I4__I4, - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::NativeRemoveProgram___STATIC__VOID__I4__I4__I4, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::NativeSetIrqEnabled___VOID__BOOLEAN, Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::NativeClaimUnusedSm___STATIC__I4__I4__BOOLEAN, - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::NativeInitGpio___STATIC__VOID__I4__I4, - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::NativeForceIrq___STATIC__VOID__I4__I4, - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::NativeClearIrq___STATIC__VOID__I4__I4, - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::NativeSetIrqEnabled___STATIC__VOID__I4__BOOLEAN, NULL, NULL, NULL, @@ -243,7 +238,7 @@ static const CLR_RT_MethodHandler method_lookup[] = const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Pico = { "nanoFramework.Hardware.Pico", - 0x0AB1471F, + 0x89CEC596, method_lookup, { 1, 0, 0, 0 } }; diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.h b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.h index c066ab7a28..05649fb62e 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.h +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.h @@ -155,13 +155,15 @@ struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pi static const int FIELD___index = 1; static const int FIELD___interruptCallbacks = 2; static const int FIELD___irqLock = 3; - NANOCLR_NATIVE_DECLARE(NativeAddProgram___STATIC__I4__I4__SZARRAY_U2__I4__I4); - NANOCLR_NATIVE_DECLARE(NativeRemoveProgram___STATIC__VOID__I4__I4__I4); + + NANOCLR_NATIVE_DECLARE(AddProgram___U4__nanoFrameworkHardwarePicoPioPioProgram); + NANOCLR_NATIVE_DECLARE(RemoveProgram___VOID__nanoFrameworkHardwarePicoPioPioProgram__U4); + NANOCLR_NATIVE_DECLARE(InitGpio___VOID__I4); + NANOCLR_NATIVE_DECLARE(ForceIrq___VOID__I4); + NANOCLR_NATIVE_DECLARE(ClearIrq___VOID__I4); + NANOCLR_NATIVE_DECLARE(NativeSetIrqEnabled___VOID__BOOLEAN); NANOCLR_NATIVE_DECLARE(NativeClaimUnusedSm___STATIC__I4__I4__BOOLEAN); - NANOCLR_NATIVE_DECLARE(NativeInitGpio___STATIC__VOID__I4__I4); - NANOCLR_NATIVE_DECLARE(NativeForceIrq___STATIC__VOID__I4__I4); - NANOCLR_NATIVE_DECLARE(NativeClearIrq___STATIC__VOID__I4__I4); - NANOCLR_NATIVE_DECLARE(NativeSetIrqEnabled___STATIC__VOID__I4__BOOLEAN); + }; struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioEvent diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp index 8811d45701..679b247456 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp @@ -27,26 +27,44 @@ static void PioChibiOSCallback(void *param, const uint32_t flags) } HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock:: - NativeAddProgram___STATIC__I4__I4__SZARRAY_U2__I4__I4(CLR_RT_StackFrame &stack) + AddProgram___U4__nanoFrameworkHardwarePicoPioPioProgram(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); rp_pio_program_t prog; - int offset; + int offset, origin, length; + uint8_t block; + CLR_RT_HeapBlock_Array *program; - const int block = stack.Arg0().NumericByRef().s4; - CLR_RT_HeapBlock_Array *instrArray = stack.Arg1().DereferenceArray(); - const int length = stack.Arg2().NumericByRef().s4; - const int origin = stack.Arg3().NumericByRef().s4; + const CLR_RT_HeapBlock *pProgram = stack.Arg1().Dereference(); + + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + + block = pThis[FIELD___index].NumericByRef().s4; + + // Get the data from the PioProgram class passed as argument + program = + pProgram + [Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioProgram::FIELD__Instructions] + .DereferenceArray(); + + FAULT_ON_NULL(program); + + length = static_cast(program->m_numOfElements); + origin = + program[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioProgram::FIELD__Origin] + .NumericByRef() + .s4; VALIDATE_PIO_BLOCK(block); - if (instrArray == nullptr || length <= 0 || length > 32 || static_cast(instrArray->m_numOfElements) < length) + if (program == nullptr || length <= 0 || length > 32 || static_cast(program->m_numOfElements) < length) { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } - prog.instructions = reinterpret_cast(instrArray->GetFirstElement()); + prog.instructions = reinterpret_cast(program->GetFirstElement()); prog.length = length; prog.origin = origin; @@ -54,7 +72,7 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P if (offset < 0) { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); // No hay memoria + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); // No memory left } stack.SetResult_I4(offset); @@ -63,14 +81,31 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P } HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock:: - NativeRemoveProgram___STATIC__VOID__I4__I4__I4(CLR_RT_StackFrame &stack) + RemoveProgram___VOID__nanoFrameworkHardwarePicoPioPioProgram__U4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); - const int block = stack.Arg0().NumericByRef().s4; - const int length = stack.Arg1().NumericByRef().s4; + uint8_t block; + int length; + CLR_RT_HeapBlock_Array *program; + + const CLR_RT_HeapBlock *pProgram = stack.Arg1().Dereference(); const int offset = stack.Arg2().NumericByRef().s4; + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + + block = pThis[FIELD___index].NumericByRef().s4; + + program = + pProgram + [Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioProgram::FIELD__Instructions] + .DereferenceArray(); + + FAULT_ON_NULL(program); + + length = static_cast(program->m_numOfElements); + VALIDATE_PIO_BLOCK(block); if (offset < 0 || length <= 0 || length > 32 || offset > 32 - length) @@ -114,15 +149,20 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P } HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock:: - NativeInitGpio___STATIC__VOID__I4__I4(CLR_RT_StackFrame &stack) + InitGpio___VOID__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); uint32_t mode; + int block; - const int block = stack.Arg0().NumericByRef().s4; const int pin = stack.Arg1().NumericByRef().s4; + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + + block = pThis[FIELD___index].NumericByRef().s4; + VALIDATE_PIO_BLOCK(block); if (pin < 0 || pin > PIO_MAX_PIN) @@ -142,13 +182,19 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P } HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock:: - NativeForceIrq___STATIC__VOID__I4__I4(CLR_RT_StackFrame &stack) + ForceIrq___VOID__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); - const int block = stack.Arg0().NumericByRef().s4; + int block; + const int irq = stack.Arg1().NumericByRef().s4; + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + + block = pThis[FIELD___index].NumericByRef().s4; + VALIDATE_PIO_BLOCK(block); if (irq < 0 || irq > 7) @@ -162,13 +208,19 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P } HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock:: - NativeClearIrq___STATIC__VOID__I4__I4(CLR_RT_StackFrame &stack) + ClearIrq___VOID__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); - const int block = stack.Arg0().NumericByRef().s4; + int block; + const int irq = stack.Arg1().NumericByRef().s4; + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + + block = pThis[FIELD___index].NumericByRef().s4; + VALIDATE_PIO_BLOCK(block); if (irq < 0 || irq > 7) @@ -182,13 +234,19 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P } HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock:: - NativeSetIrqEnabled___STATIC__VOID__I4__BOOLEAN(CLR_RT_StackFrame &stack) + NativeSetIrqEnabled___VOID__BOOLEAN(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); - const int block = stack.Arg0().NumericByRef().s4; + int block; + const bool enabled = static_cast(stack.Arg1().NumericByRef().u1); + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + + block = pThis[FIELD___index].NumericByRef().s4; + VALIDATE_PIO_BLOCK(block); if (enabled) From 5268b108f4673b629db92609580f0a08185cd22b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Sun, 26 Jul 2026 00:33:39 -0600 Subject: [PATCH 52/58] Refactor PIO state machine native methods to instance members Converts `PioStateMachine` native methods from static functions, requiring explicit block and state machine indices, to instance methods. The block and state machine indices are now implicitly retrieved from the `PioStateMachine` object instance, simplifying the API and improving object-oriented design. The native assembly GUID is updated due to these API changes. --- .../nanoFramework_hardware_pico_native.cpp | 57 +-- .../nanoFramework_hardware_pico_native.h | 40 +- ...noFramework_Hardware_Pico_Pio_PioBlock.cpp | 16 +- ...work_Hardware_Pico_Pio_PioStateMachine.cpp | 395 +++++++++++++----- ...anoFramework_hardware_pico_native_target.h | 15 +- 5 files changed, 344 insertions(+), 179 deletions(-) diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp index 9ffbf3e78e..bd28fc2723 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp @@ -174,46 +174,31 @@ static const CLR_RT_MethodHandler method_lookup[] = NULL, NULL, NULL, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::get_Enabled___BOOLEAN, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::set_Enabled___VOID__BOOLEAN, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::get_IsTxFull___BOOLEAN, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::get_IsRxEmpty___BOOLEAN, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::get_TxLevel___U4, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::get_RxLevel___U4, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::get_ProgramCounter___U4, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::set_ClockDivisor___VOID__R4, NULL, NULL, NULL, NULL, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::ClearFifos___VOID, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::DrainTxFifo___VOID, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::Restart___VOID, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::ClockDivRestart___VOID, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::Exec___VOID__U2, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::SetConsecutivePinDirs___VOID__I4__I4__BOOLEAN, NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeRead___STATIC__I4__I4__I4__SZARRAY_U4__I4__I4__I4, - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeWrite___STATIC__I4__I4__I4__SZARRAY_U4__I4__I4__I4, - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeInit___STATIC__VOID__I4__I4__I4__SZARRAY_U4, - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeSetEnabled___STATIC__VOID__I4__I4__BOOLEAN, - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativePutBlocking___STATIC__VOID__I4__I4__U4, - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeGetBlocking___STATIC__U4__I4__I4, - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeTxFull___STATIC__BOOLEAN__I4__I4, - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeRxEmpty___STATIC__BOOLEAN__I4__I4, - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeUnclaim___STATIC__VOID__I4__I4, - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeSetConsecutivePinDirs___STATIC__VOID__I4__I4__I4__I4__BOOLEAN, - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeClearFifos___STATIC__VOID__I4__I4, - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeDrainTxFifo___STATIC__VOID__I4__I4, - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeRestart___STATIC__VOID__I4__I4, - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeClkDivRestart___STATIC__VOID__I4__I4, - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeExec___STATIC__VOID__I4__I4__U2, - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeTxLevel___STATIC__U4__I4__I4, - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeRxLevel___STATIC__U4__I4__I4, - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeGetPc___STATIC__U4__I4__I4, - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeSetClockDivisor___STATIC__VOID__I4__I4__R4, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::Read___I4__SZARRAY_U4__I4__I4__I4, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::Write___I4__SZARRAY_U4__I4__I4__I4, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeInit___VOID__I4__SZARRAY_U4, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativePutBlocking___VOID__U4, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeGetBlocking___U4, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeUnclaim___VOID, NULL, NULL, NULL, @@ -238,7 +223,7 @@ static const CLR_RT_MethodHandler method_lookup[] = const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Pico = { "nanoFramework.Hardware.Pico", - 0x89CEC596, + 0xB0752CBB, method_lookup, { 1, 0, 0, 0 } }; diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.h b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.h index 05649fb62e..882efad316 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.h +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.h @@ -163,7 +163,6 @@ struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pi NANOCLR_NATIVE_DECLARE(ClearIrq___VOID__I4); NANOCLR_NATIVE_DECLARE(NativeSetIrqEnabled___VOID__BOOLEAN); NANOCLR_NATIVE_DECLARE(NativeClaimUnusedSm___STATIC__I4__I4__BOOLEAN); - }; struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioEvent @@ -219,25 +218,26 @@ struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pi static const int FIELD___disposed = 4; static const int FIELD___enabled = 5; - NANOCLR_NATIVE_DECLARE(NativeRead___STATIC__I4__I4__I4__SZARRAY_U4__I4__I4__I4); - NANOCLR_NATIVE_DECLARE(NativeWrite___STATIC__I4__I4__I4__SZARRAY_U4__I4__I4__I4); - NANOCLR_NATIVE_DECLARE(NativeInit___STATIC__VOID__I4__I4__I4__SZARRAY_U4); - NANOCLR_NATIVE_DECLARE(NativeSetEnabled___STATIC__VOID__I4__I4__BOOLEAN); - NANOCLR_NATIVE_DECLARE(NativePutBlocking___STATIC__VOID__I4__I4__U4); - NANOCLR_NATIVE_DECLARE(NativeGetBlocking___STATIC__U4__I4__I4); - NANOCLR_NATIVE_DECLARE(NativeTxFull___STATIC__BOOLEAN__I4__I4); - NANOCLR_NATIVE_DECLARE(NativeRxEmpty___STATIC__BOOLEAN__I4__I4); - NANOCLR_NATIVE_DECLARE(NativeUnclaim___STATIC__VOID__I4__I4); - NANOCLR_NATIVE_DECLARE(NativeSetConsecutivePinDirs___STATIC__VOID__I4__I4__I4__I4__BOOLEAN); - NANOCLR_NATIVE_DECLARE(NativeClearFifos___STATIC__VOID__I4__I4); - NANOCLR_NATIVE_DECLARE(NativeDrainTxFifo___STATIC__VOID__I4__I4); - NANOCLR_NATIVE_DECLARE(NativeRestart___STATIC__VOID__I4__I4); - NANOCLR_NATIVE_DECLARE(NativeClkDivRestart___STATIC__VOID__I4__I4); - NANOCLR_NATIVE_DECLARE(NativeExec___STATIC__VOID__I4__I4__U2); - NANOCLR_NATIVE_DECLARE(NativeTxLevel___STATIC__U4__I4__I4); - NANOCLR_NATIVE_DECLARE(NativeRxLevel___STATIC__U4__I4__I4); - NANOCLR_NATIVE_DECLARE(NativeGetPc___STATIC__U4__I4__I4); - NANOCLR_NATIVE_DECLARE(NativeSetClockDivisor___STATIC__VOID__I4__I4__R4); + NANOCLR_NATIVE_DECLARE(get_Enabled___BOOLEAN); + NANOCLR_NATIVE_DECLARE(set_Enabled___VOID__BOOLEAN); + NANOCLR_NATIVE_DECLARE(get_IsTxFull___BOOLEAN); + NANOCLR_NATIVE_DECLARE(get_IsRxEmpty___BOOLEAN); + NANOCLR_NATIVE_DECLARE(get_TxLevel___U4); + NANOCLR_NATIVE_DECLARE(get_RxLevel___U4); + NANOCLR_NATIVE_DECLARE(get_ProgramCounter___U4); + NANOCLR_NATIVE_DECLARE(set_ClockDivisor___VOID__R4); + NANOCLR_NATIVE_DECLARE(ClearFifos___VOID); + NANOCLR_NATIVE_DECLARE(DrainTxFifo___VOID); + NANOCLR_NATIVE_DECLARE(Restart___VOID); + NANOCLR_NATIVE_DECLARE(ClockDivRestart___VOID); + NANOCLR_NATIVE_DECLARE(Exec___VOID__U2); + NANOCLR_NATIVE_DECLARE(SetConsecutivePinDirs___VOID__I4__I4__BOOLEAN); + NANOCLR_NATIVE_DECLARE(Read___I4__SZARRAY_U4__I4__I4__I4); + NANOCLR_NATIVE_DECLARE(Write___I4__SZARRAY_U4__I4__I4__I4); + NANOCLR_NATIVE_DECLARE(NativeInit___VOID__I4__SZARRAY_U4); + NANOCLR_NATIVE_DECLARE(NativePutBlocking___VOID__U4); + NANOCLR_NATIVE_DECLARE(NativeGetBlocking___U4); + NANOCLR_NATIVE_DECLARE(NativeUnclaim___VOID); }; struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachineConfig diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp index 679b247456..7288e2f74e 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp @@ -13,6 +13,8 @@ #define EVENT_TYPE_PICO_PIO 160 +const rp_pio_sm_t *g_AllocatedSMs[3][4] = {{nullptr}}; + static void PioChibiOSCallback(void *param, const uint32_t flags) { const int block = reinterpret_cast(param); @@ -142,14 +144,16 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P } else { + g_AllocatedSMs[block][sm->smidx] = sm; + stack.SetResult_I4(static_cast(sm->smidx)); } NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock:: - InitGpio___VOID__I4(CLR_RT_StackFrame &stack) +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::InitGpio___VOID__I4( + CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); @@ -181,8 +185,8 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock:: - ForceIrq___VOID__I4(CLR_RT_StackFrame &stack) +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::ForceIrq___VOID__I4( + CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); @@ -207,8 +211,8 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock:: - ClearIrq___VOID__I4(CLR_RT_StackFrame &stack) +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::ClearIrq___VOID__I4( + CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp index f83a265169..ff7599042f 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp @@ -18,8 +18,6 @@ static constexpr unsigned int PIO_FIFO_WAIT_LIMIT = 0x4000000u; -extern const rp_pio_sm_t *g_AllocatedSMs[3][4]; - struct PioDmaWork { const rp_dma_channel_t *Channel; @@ -73,22 +71,31 @@ enum PioCfgBlob extern unsigned int g_PioClaimedSm[3]; HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: - NativeInit___STATIC__VOID__I4__I4__I4__SZARRAY_U4(CLR_RT_StackFrame &stack) + NativeInit___VOID__I4__SZARRAY_U4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); PIO_TypeDef *pio; + CLR_RT_HeapBlock *pPioBlock; CLR_RT_HeapBlock_Array *blobArray; unsigned int *b; unsigned int sidesetTotal, execCtrl, pushThresh, pullThresh, join; int block, sm, offset; - VALIDATE_NOT_DISPOSED(stack); + CLR_RT_HeapBlock *pThis = stack.This(); + VALIDATE_NOT_DISPOSED(pThis); - block = stack.Arg0().NumericByRef().s4; - sm = stack.Arg1().NumericByRef().s4; - offset = stack.Arg2().NumericByRef().s4; - blobArray = stack.Arg3().DereferenceArray(); + offset = stack.Arg1().NumericByRef().s4; + blobArray = stack.Arg2().DereferenceArray(); + + pPioBlock = pThis[FIELD___block].Dereference(); + FAULT_ON_NULL(pPioBlock); + + block = + pPioBlock[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::FIELD___index] + .NumericByRef() + .s4; + sm = pPioBlock[FIELD___sm].NumericByRef().s4; FAULT_ON_NULL(blobArray); @@ -158,23 +165,47 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P } HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: - NativeSetEnabled___STATIC__VOID__I4__I4__BOOLEAN(CLR_RT_StackFrame &stack) + get_Enabled___BOOLEAN(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + CLR_RT_HeapBlock *pThis = stack.This(); + VALIDATE_NOT_DISPOSED(pThis); + + stack.SetResult_Boolean(pThis[FIELD___enabled].NumericByRef().u1); + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: + set_Enabled___VOID__BOOLEAN(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); + CLR_RT_HeapBlock *pPioBlock; int block, sm; - bool enabled; + bool value; + + CLR_RT_HeapBlock *pThis = stack.This(); + VALIDATE_NOT_DISPOSED(pThis); - VALIDATE_NOT_DISPOSED(stack); + value = stack.Arg1().NumericByRef().u1; - block = stack.Arg0().NumericByRef().s4; - sm = stack.Arg1().NumericByRef().s4; - enabled = stack.Arg2().NumericByRef().u1; + pPioBlock = pThis[FIELD___block].Dereference(); + FAULT_ON_NULL(pPioBlock); + + block = + pPioBlock[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::FIELD___index] + .NumericByRef() + .s4; + sm = pPioBlock[FIELD___sm].NumericByRef().s4; VALIDATE_PIO_BLOCK(block); VALIDATE_SM(sm); - if (enabled) + pThis[FIELD___enabled].NumericByRef().u1 = value; + + if (value) { __rp_pio_blocks[block].pio->CTRL |= (1u << sm); } @@ -187,20 +218,29 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P } HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: - NativePutBlocking___STATIC__VOID__I4__I4__U4(CLR_RT_StackFrame &stack) + NativePutBlocking___VOID__U4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); PIO_TypeDef *pio; + CLR_RT_HeapBlock *pPioBlock; unsigned int guard, value; int block, sm; - VALIDATE_NOT_DISPOSED(stack); + CLR_RT_HeapBlock *pThis = stack.This(); + VALIDATE_NOT_DISPOSED(pThis); - block = stack.Arg0().NumericByRef().s4; - sm = stack.Arg1().NumericByRef().s4; value = stack.Arg2().NumericByRef().u4; + pPioBlock = pThis[FIELD___block].Dereference(); + FAULT_ON_NULL(pPioBlock); + + block = + pPioBlock[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::FIELD___index] + .NumericByRef() + .s4; + sm = pPioBlock[FIELD___sm].NumericByRef().s4; + VALIDATE_PIO_BLOCK(block); VALIDATE_SM(sm); @@ -223,18 +263,26 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P } HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: - NativeGetBlocking___STATIC__U4__I4__I4(CLR_RT_StackFrame &stack) + NativeGetBlocking___U4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); const PIO_TypeDef *pio; + CLR_RT_HeapBlock *pPioBlock; unsigned int guard; int block, sm; - VALIDATE_NOT_DISPOSED(stack); + CLR_RT_HeapBlock *pThis = stack.This(); + VALIDATE_NOT_DISPOSED(pThis); - block = stack.Arg0().NumericByRef().s4; - sm = stack.Arg1().NumericByRef().s4; + pPioBlock = pThis[FIELD___block].Dereference(); + FAULT_ON_NULL(pPioBlock); + + block = + pPioBlock[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::FIELD___index] + .NumericByRef() + .s4; + sm = pPioBlock[FIELD___sm].NumericByRef().s4; VALIDATE_PIO_BLOCK(block); VALIDATE_SM(sm); @@ -258,17 +306,25 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P } HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: - NativeTxFull___STATIC__BOOLEAN__I4__I4(CLR_RT_StackFrame &stack) + get_IsTxFull___BOOLEAN(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); const PIO_TypeDef *pio; + CLR_RT_HeapBlock *pPioBlock; int block, sm; - VALIDATE_NOT_DISPOSED(stack); + CLR_RT_HeapBlock *pThis = stack.This(); + VALIDATE_NOT_DISPOSED(pThis); + + pPioBlock = pThis[FIELD___block].Dereference(); + FAULT_ON_NULL(pPioBlock); - block = stack.Arg0().NumericByRef().s4; - sm = stack.Arg1().NumericByRef().s4; + block = + pPioBlock[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::FIELD___index] + .NumericByRef() + .s4; + sm = pPioBlock[FIELD___sm].NumericByRef().s4; VALIDATE_PIO_BLOCK(block); VALIDATE_SM(sm); @@ -281,17 +337,25 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P } HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: - NativeRxEmpty___STATIC__BOOLEAN__I4__I4(CLR_RT_StackFrame &stack) + get_IsRxEmpty___BOOLEAN(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); const PIO_TypeDef *pio; + CLR_RT_HeapBlock *pPioBlock; int block, sm; - VALIDATE_NOT_DISPOSED(stack); + CLR_RT_HeapBlock *pThis = stack.This(); + VALIDATE_NOT_DISPOSED(pThis); + + pPioBlock = pThis[FIELD___block].Dereference(); + FAULT_ON_NULL(pPioBlock); - block = stack.Arg0().NumericByRef().s4; - sm = stack.Arg1().NumericByRef().s4; + block = + pPioBlock[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::FIELD___index] + .NumericByRef() + .s4; + sm = pPioBlock[FIELD___sm].NumericByRef().s4; VALIDATE_PIO_BLOCK(block); VALIDATE_SM(sm); @@ -304,12 +368,24 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P } HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: - NativeUnclaim___STATIC__VOID__I4__I4(CLR_RT_StackFrame &stack) + NativeUnclaim___VOID(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); - const int block = stack.Arg0().NumericByRef().s4; - const int sm = stack.Arg1().NumericByRef().s4; + CLR_RT_HeapBlock *pPioBlock; + int block, sm; + + CLR_RT_HeapBlock *pThis = stack.This(); + VALIDATE_NOT_DISPOSED(pThis); + + pPioBlock = pThis[FIELD___block].Dereference(); + FAULT_ON_NULL(pPioBlock); + + block = + pPioBlock[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::FIELD___index] + .NumericByRef() + .s4; + sm = pPioBlock[FIELD___sm].NumericByRef().s4; VALIDATE_PIO_BLOCK(block); VALIDATE_SM(sm); @@ -326,22 +402,31 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P } HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: - NativeSetConsecutivePinDirs___STATIC__VOID__I4__I4__I4__I4__BOOLEAN(CLR_RT_StackFrame &stack) + SetConsecutivePinDirs___VOID__I4__I4__BOOLEAN(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); PIO_TypeDef *pio; + CLR_RT_HeapBlock *pPioBlock; int pin, remaining, gpioBase; int block, sm, basePin, count, output; unsigned int savedPinCtrl; - VALIDATE_NOT_DISPOSED(stack); + CLR_RT_HeapBlock *pThis = stack.This(); + VALIDATE_NOT_DISPOSED(pThis); - block = stack.Arg0().NumericByRef().s4; - sm = stack.Arg1().NumericByRef().s4; - basePin = stack.Arg2().NumericByRef().s4; - count = stack.Arg3().NumericByRef().s4; - output = stack.Arg4().NumericByRef().u1; + basePin = stack.Arg1().NumericByRef().s4; + count = stack.Arg2().NumericByRef().s4; + output = stack.Arg3().NumericByRef().u1; + + pPioBlock = pThis[FIELD___block].Dereference(); + FAULT_ON_NULL(pPioBlock); + + block = + pPioBlock[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::FIELD___index] + .NumericByRef() + .s4; + sm = pPioBlock[FIELD___sm].NumericByRef().s4; VALIDATE_PIO_BLOCK(block); VALIDATE_SM(sm); @@ -386,19 +471,27 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: - NativeClearFifos___STATIC__VOID__I4__I4(CLR_RT_StackFrame &stack) +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::ClearFifos___VOID( + CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); PIO_TypeDef *pio; + CLR_RT_HeapBlock *pPioBlock; unsigned int fjoinRx; int block, sm; - VALIDATE_NOT_DISPOSED(stack); + CLR_RT_HeapBlock *pThis = stack.This(); + VALIDATE_NOT_DISPOSED(pThis); - block = stack.Arg0().NumericByRef().s4; - sm = stack.Arg1().NumericByRef().s4; + pPioBlock = pThis[FIELD___block].Dereference(); + FAULT_ON_NULL(pPioBlock); + + block = + pPioBlock[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::FIELD___index] + .NumericByRef() + .s4; + sm = pPioBlock[FIELD___sm].NumericByRef().s4; VALIDATE_PIO_BLOCK(block); VALIDATE_SM(sm); @@ -413,19 +506,27 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: - NativeDrainTxFifo___STATIC__VOID__I4__I4(CLR_RT_StackFrame &stack) +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::DrainTxFifo___VOID( + CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); PIO_TypeDef *pio; + CLR_RT_HeapBlock *pPioBlock; unsigned int autopull, instr, guard; int block, sm; - VALIDATE_NOT_DISPOSED(stack); + CLR_RT_HeapBlock *pThis = stack.This(); + VALIDATE_NOT_DISPOSED(pThis); - block = stack.Arg0().NumericByRef().s4; - sm = stack.Arg1().NumericByRef().s4; + pPioBlock = pThis[FIELD___block].Dereference(); + FAULT_ON_NULL(pPioBlock); + + block = + pPioBlock[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::FIELD___index] + .NumericByRef() + .s4; + sm = pPioBlock[FIELD___sm].NumericByRef().s4; VALIDATE_PIO_BLOCK(block); VALIDATE_SM(sm); @@ -449,18 +550,26 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: - NativeRestart___STATIC__VOID__I4__I4(CLR_RT_StackFrame &stack) +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::Restart___VOID( + CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); PIO_TypeDef *pio; + CLR_RT_HeapBlock *pPioBlock; int block, sm; - VALIDATE_NOT_DISPOSED(stack); + CLR_RT_HeapBlock *pThis = stack.This(); + VALIDATE_NOT_DISPOSED(pThis); + + pPioBlock = pThis[FIELD___block].Dereference(); + FAULT_ON_NULL(pPioBlock); - block = stack.Arg0().NumericByRef().s4; - sm = stack.Arg1().NumericByRef().s4; + block = + pPioBlock[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::FIELD___index] + .NumericByRef() + .s4; + sm = pPioBlock[FIELD___sm].NumericByRef().s4; VALIDATE_PIO_BLOCK(block); VALIDATE_SM(sm); @@ -474,18 +583,26 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P } HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: - NativeClkDivRestart___STATIC__VOID__I4__I4(CLR_RT_StackFrame &stack) + ClockDivRestart___VOID(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); PIO_TypeDef *pio; + CLR_RT_HeapBlock *pPioBlock; int block; int sm; - VALIDATE_NOT_DISPOSED(stack); + CLR_RT_HeapBlock *pThis = stack.This(); + VALIDATE_NOT_DISPOSED(pThis); - block = stack.Arg0().NumericByRef().s4; - sm = stack.Arg1().NumericByRef().s4; + pPioBlock = pThis[FIELD___block].Dereference(); + FAULT_ON_NULL(pPioBlock); + + block = + pPioBlock[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::FIELD___index] + .NumericByRef() + .s4; + sm = pPioBlock[FIELD___sm].NumericByRef().s4; VALIDATE_PIO_BLOCK(block); VALIDATE_SM(sm); @@ -498,21 +615,30 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: - NativeExec___STATIC__VOID__I4__I4__U2(CLR_RT_StackFrame &stack) +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::Exec___VOID__U2( + CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); PIO_TypeDef *pio; + CLR_RT_HeapBlock *pPioBlock; int block; int sm; unsigned short instruction; - VALIDATE_NOT_DISPOSED(stack); + CLR_RT_HeapBlock *pThis = stack.This(); + VALIDATE_NOT_DISPOSED(pThis); + + instruction = stack.Arg1().NumericByRef().u2; - block = stack.Arg0().NumericByRef().s4; - sm = stack.Arg1().NumericByRef().s4; - instruction = stack.Arg2().NumericByRef().u2; + pPioBlock = pThis[FIELD___block].Dereference(); + FAULT_ON_NULL(pPioBlock); + + block = + pPioBlock[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::FIELD___index] + .NumericByRef() + .s4; + sm = pPioBlock[FIELD___sm].NumericByRef().s4; VALIDATE_PIO_BLOCK(block); VALIDATE_SM(sm); @@ -525,18 +651,26 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: - NativeTxLevel___STATIC__U4__I4__I4(CLR_RT_StackFrame &stack) +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::get_TxLevel___U4( + CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); const PIO_TypeDef *pio; + CLR_RT_HeapBlock *pPioBlock; int block, sm; - VALIDATE_NOT_DISPOSED(stack); + CLR_RT_HeapBlock *pThis = stack.This(); + VALIDATE_NOT_DISPOSED(pThis); + + pPioBlock = pThis[FIELD___block].Dereference(); + FAULT_ON_NULL(pPioBlock); - block = stack.Arg0().NumericByRef().s4; - sm = stack.Arg1().NumericByRef().s4; + block = + pPioBlock[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::FIELD___index] + .NumericByRef() + .s4; + sm = pPioBlock[FIELD___sm].NumericByRef().s4; VALIDATE_PIO_BLOCK(block); VALIDATE_SM(sm); @@ -548,18 +682,26 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: - NativeRxLevel___STATIC__U4__I4__I4(CLR_RT_StackFrame &stack) +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::get_RxLevel___U4( + CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); const PIO_TypeDef *pio; + CLR_RT_HeapBlock *pPioBlock; int block, sm; - VALIDATE_NOT_DISPOSED(stack); + CLR_RT_HeapBlock *pThis = stack.This(); + VALIDATE_NOT_DISPOSED(pThis); + + pPioBlock = pThis[FIELD___block].Dereference(); + FAULT_ON_NULL(pPioBlock); - block = stack.Arg0().NumericByRef().s4; - sm = stack.Arg1().NumericByRef().s4; + block = + pPioBlock[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::FIELD___index] + .NumericByRef() + .s4; + sm = pPioBlock[FIELD___sm].NumericByRef().s4; VALIDATE_PIO_BLOCK(block); VALIDATE_SM(sm); @@ -572,17 +714,25 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P } HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: - NativeGetPc___STATIC__U4__I4__I4(CLR_RT_StackFrame &stack) + get_ProgramCounter___U4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); const PIO_TypeDef *pio; + CLR_RT_HeapBlock *pPioBlock; int block, sm; - VALIDATE_NOT_DISPOSED(stack); + CLR_RT_HeapBlock *pThis = stack.This(); + VALIDATE_NOT_DISPOSED(pThis); - block = stack.Arg0().NumericByRef().s4; - sm = stack.Arg1().NumericByRef().s4; + pPioBlock = pThis[FIELD___block].Dereference(); + FAULT_ON_NULL(pPioBlock); + + block = + pPioBlock[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::FIELD___index] + .NumericByRef() + .s4; + sm = pPioBlock[FIELD___sm].NumericByRef().s4; VALIDATE_PIO_BLOCK(block); VALIDATE_SM(sm); @@ -595,30 +745,39 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P } HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: - NativeSetClockDivisor___STATIC__VOID__I4__I4__R4(CLR_RT_StackFrame &stack) + set_ClockDivisor___VOID__R4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); PIO_TypeDef *pio; + CLR_RT_HeapBlock *pPioBlock; int block, sm, intPart, frac; - float div; + float value; + + CLR_RT_HeapBlock *pThis = stack.This(); + VALIDATE_NOT_DISPOSED(pThis); - VALIDATE_NOT_DISPOSED(stack); + pPioBlock = pThis[FIELD___block].Dereference(); + FAULT_ON_NULL(pPioBlock); - block = stack.Arg0().NumericByRef().s4; - sm = stack.Arg1().NumericByRef().s4; - div = stack.Arg2().NumericByRef().r4; + block = + pPioBlock[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::FIELD___index] + .NumericByRef() + .s4; + sm = pPioBlock[FIELD___sm].NumericByRef().s4; + + value = stack.Arg1().NumericByRef().r4; VALIDATE_PIO_BLOCK(block); VALIDATE_SM(sm); - if (!(div >= 1.0f && div <= 65536.0f)) + if (!(value >= 1.0f && value <= 65536.0f)) { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } - intPart = static_cast(div); - frac = static_cast(roundf((div - static_cast(intPart)) * 256.0f)); + intPart = static_cast(value); + frac = static_cast(roundf((value - static_cast(intPart)) * 256.0f)); if (frac > 255) { frac = 0; @@ -636,11 +795,12 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P } HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: - NativeRead___STATIC__I4__I4__I4__SZARRAY_U4__I4__I4__I4(CLR_RT_StackFrame &stack) + Read___I4__SZARRAY_U4__I4__I4__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); CLR_RT_HeapBlock hbTimeout{}; + CLR_RT_HeapBlock *pPioBlock; CLR_INT64 *timeoutTicks; CLR_RT_HeapBlock_Array *buffer; bool eventResult = true; @@ -650,14 +810,22 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P PIO_TypeDef *pio; PioDmaWork *work; - VALIDATE_NOT_DISPOSED(stack); + CLR_RT_HeapBlock *pThis = stack.This(); + VALIDATE_NOT_DISPOSED(pThis); - block = stack.Arg0().NumericByRef().s4; - sm = stack.Arg1().NumericByRef().s4; - buffer = stack.Arg2().DereferenceArray(); - offset = stack.Arg3().NumericByRef().s4; - count = stack.Arg4().NumericByRef().s4; - timeoutMs = stack.Arg5().NumericByRef().s4; + buffer = stack.Arg1().DereferenceArray(); + offset = stack.Arg2().NumericByRef().s4; + count = stack.Arg3().NumericByRef().s4; + timeoutMs = stack.Arg4().NumericByRef().s4; + + pPioBlock = pThis[FIELD___block].Dereference(); + FAULT_ON_NULL(pPioBlock); + + block = + pPioBlock[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::FIELD___index] + .NumericByRef() + .s4; + sm = pPioBlock[FIELD___sm].NumericByRef().s4; FAULT_ON_NULL(buffer); @@ -669,8 +837,8 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P if (count == 0) { - stack.SetResult_I4(false); - NANOCLR_EXIT_ON_SUCCESS(S_OK); + stack.SetResult_I4(0); + NANOCLR_SET_AND_LEAVE(S_OK); } VALIDATE_PIO_BLOCK(block); @@ -785,11 +953,12 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P } HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: - NativeWrite___STATIC__I4__I4__I4__SZARRAY_U4__I4__I4__I4(CLR_RT_StackFrame &stack) + Write___I4__SZARRAY_U4__I4__I4__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); CLR_RT_HeapBlock hbTimeout{}; + CLR_RT_HeapBlock *pPioBlock; CLR_INT64 *timeoutTicks; CLR_RT_HeapBlock_Array *buffer = nullptr; bool eventResult = true; @@ -799,14 +968,22 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P PIO_TypeDef *pio; PioDmaWork *work; - VALIDATE_NOT_DISPOSED(stack); + CLR_RT_HeapBlock *pThis = stack.This(); + VALIDATE_NOT_DISPOSED(pThis); + + buffer = stack.Arg1().DereferenceArray(); + offset = stack.Arg2().NumericByRef().s4; + count = stack.Arg3().NumericByRef().s4; + timeoutMs = stack.Arg4().NumericByRef().s4; + + pPioBlock = pThis[FIELD___block].Dereference(); + FAULT_ON_NULL(pPioBlock); - block = stack.Arg0().NumericByRef().s4; - sm = stack.Arg1().NumericByRef().s4; - buffer = stack.Arg2().DereferenceArray(); - offset = stack.Arg3().NumericByRef().s4; - count = stack.Arg4().NumericByRef().s4; - timeoutMs = stack.Arg5().NumericByRef().s4; + block = + pPioBlock[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::FIELD___index] + .NumericByRef() + .s4; + sm = pPioBlock[FIELD___sm].NumericByRef().s4; FAULT_ON_NULL(buffer); @@ -818,8 +995,8 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P if (count == 0) { - stack.SetResult_I4(false); - NANOCLR_EXIT_ON_SUCCESS(S_OK); + stack.SetResult_I4(0); + NANOCLR_SET_AND_LEAVE(S_OK); } VALIDATE_PIO_BLOCK(block); diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_target.h b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_target.h index dddef69156..3734a81dcf 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_target.h +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_target.h @@ -36,14 +36,13 @@ NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); \ } -#define VALIDATE_NOT_DISPOSED(stack) \ - { \ - CLR_RT_HeapBlock *pThis = (stack).This(); \ - FAULT_ON_NULL(pThis); \ - if (pThis[FIELD___disposed].NumericByRef().u1 != 0) \ - { \ - NANOCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); \ - } \ +#define VALIDATE_NOT_DISPOSED(pThis) \ + FAULT_ON_NULL(pThis); \ + if (pThis[FIELD___disposed].NumericByRef().u1 != 0) \ + { \ + NANOCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); \ } +extern const rp_pio_sm_t *g_AllocatedSMs[3][4]; + #endif // NANOFRAMEWORK_HARDWARE_PICO_NATIVE_TARGET_H From 28fc628bf0d50631f928b513515195746467cbe4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Sun, 26 Jul 2026 03:26:26 -0600 Subject: [PATCH 53/58] Add PIO Low-Level Driver for RP2040 and RP2350 targets Integrates the ChibiOS PIOv1 Low-Level Driver (LLD) into the nanoCLR build system for RP2040 and RP2350 devices. This enables PIO hardware support by adding required source files, include paths, and the `RP_PIO_REQUIRED` compilation definition. Refines the native `PioBlock.AddProgram` method to improve robustness when handling `PioProgram` objects, ensuring correct access to program instructions and origin. Updates the `PIO_MIN_BLOCK` definition logic to depend on `TARGET_HAS_WIFI`, reserving PIO block 0 only when WiFi is present on the target. --- targets/ChibiOS/PICO2_RP2350/CMakeLists.txt | 5 +++++ targets/ChibiOS/PICO_RP2040/CMakeLists.txt | 6 ++++++ ...noFramework_Hardware_Pico_Pio_PioBlock.cpp | 21 ++++++++++--------- ...anoFramework_hardware_pico_native_target.h | 2 +- 4 files changed, 23 insertions(+), 11 deletions(-) diff --git a/targets/ChibiOS/PICO2_RP2350/CMakeLists.txt b/targets/ChibiOS/PICO2_RP2350/CMakeLists.txt index eb45bed043..70de6f6efd 100644 --- a/targets/ChibiOS/PICO2_RP2350/CMakeLists.txt +++ b/targets/ChibiOS/PICO2_RP2350/CMakeLists.txt @@ -20,6 +20,10 @@ list(APPEND TARGET_CHIBIOS_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/Target_Bl list(APPEND TARGET_CHIBIOS_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/target_stubs.cpp") list(APPEND TARGET_CHIBIOS_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/target_core1_stubs.c") +# PIO LLD sources +list(APPEND TARGET_CHIBIOS_NANOCLR_INCLUDE_DIRS "${chibios_SOURCE_DIR}/os/hal/ports/RP/LLD/PIOv1") +list(APPEND TARGET_CHIBIOS_NANOCLR_SOURCES "${chibios_SOURCE_DIR}/os/hal/ports/RP/LLD/PIOv1/rp_pio.c") + nf_setup_target_build( HAS_NANOBOOTER @@ -31,6 +35,7 @@ nf_setup_target_build( CLR_EXTRA_COMPILE_DEFINITIONS -DRUNTIME_MEMORY_PROFILE__small=1 + -DRP_PIO_REQUIRED=1 # RP flash is XIP-mapped and shared with code execution; this flag enables # runtime handling that avoids USB/WP activity while XIP flash operations are in progress. -DTARGET_XIP_FLASH_BLOCKS_USB=1 diff --git a/targets/ChibiOS/PICO_RP2040/CMakeLists.txt b/targets/ChibiOS/PICO_RP2040/CMakeLists.txt index 2d1856cd7f..a5491de8ea 100644 --- a/targets/ChibiOS/PICO_RP2040/CMakeLists.txt +++ b/targets/ChibiOS/PICO_RP2040/CMakeLists.txt @@ -19,6 +19,11 @@ list(APPEND TARGET_CHIBIOS_COMMON_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/comm list(APPEND TARGET_CHIBIOS_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/Target_BlockStorage_RP2040FlashDriver.c") list(APPEND TARGET_CHIBIOS_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/target_stubs.cpp") + +# PIO LLD sources +list(APPEND TARGET_CHIBIOS_NANOCLR_INCLUDE_DIRS "${chibios_SOURCE_DIR}/os/hal/ports/RP/LLD/PIOv1") +list(APPEND TARGET_CHIBIOS_NANOCLR_SOURCES "${chibios_SOURCE_DIR}/os/hal/ports/RP/LLD/PIOv1/rp_pio.c") + nf_setup_target_build( HAS_NANOBOOTER @@ -31,6 +36,7 @@ nf_setup_target_build( CLR_EXTRA_COMPILE_DEFINITIONS -DRUNTIME_MEMORY_PROFILE__small=1 -DTARGET_XIP_FLASH_BLOCKS_USB=1 + -DRP_PIO_REQUIRED=1 LFS_CONFIG=lfs_config.h BOOTER_EXTRA_LINKMAP_PROPERTIES diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp index 7288e2f74e..2738b8bacb 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp @@ -36,37 +36,38 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P rp_pio_program_t prog; int offset, origin, length; uint8_t block; - CLR_RT_HeapBlock_Array *program; + CLR_RT_HeapBlock_Array *program_array; - const CLR_RT_HeapBlock *pProgram = stack.Arg1().Dereference(); + CLR_RT_HeapBlock *pProgram = stack.Arg1().Dereference(); CLR_RT_HeapBlock *pThis = stack.This(); FAULT_ON_NULL(pThis); block = pThis[FIELD___index].NumericByRef().s4; + VALIDATE_PIO_BLOCK(block); + // Get the data from the PioProgram class passed as argument - program = + program_array = pProgram [Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioProgram::FIELD__Instructions] .DereferenceArray(); - FAULT_ON_NULL(program); + FAULT_ON_NULL(program_array); - length = static_cast(program->m_numOfElements); + length = static_cast(program_array->m_numOfElements); origin = - program[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioProgram::FIELD__Origin] + pProgram[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioProgram::FIELD__Origin] .NumericByRef() .s4; - VALIDATE_PIO_BLOCK(block); - - if (program == nullptr || length <= 0 || length > 32 || static_cast(program->m_numOfElements) < length) + if (program_array == nullptr || length <= 0 || length > 32 || + static_cast(program_array->m_numOfElements) < length) { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } - prog.instructions = reinterpret_cast(program->GetFirstElement()); + prog.instructions = reinterpret_cast(program_array->GetFirstElement()); prog.length = length; prog.origin = origin; diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_target.h b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_target.h index 3734a81dcf..c4e3af1f0f 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_target.h +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_target.h @@ -14,7 +14,7 @@ #define PIO_MAX_PIN 29 #endif -#if defined(RP_PIO_REQUIRED) +#if defined(TARGET_HAS_WIFI) #define PIO_MIN_BLOCK 1 #else #define PIO_MIN_BLOCK 0 From 76d806ad87c16278555c8f4c414122ed23d05bc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Sun, 26 Jul 2026 12:46:46 -0600 Subject: [PATCH 54/58] Refactor PIO DMA channel disable logic Replaces manual DMA channel control register manipulation and abort logic with a call to the helper function `dmaChannelDisableX()`. This improves code readability and ensures a consistent approach to stopping DMA transfers in the PIO state machine. --- ...amework_Hardware_Pico_Pio_PioStateMachine.cpp | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp index ff7599042f..8a21e4093b 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp @@ -914,13 +914,7 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P // on timeout the channel is still busy; stop it so it can't write after we free the buffer if (dmaChannelIsBusyX(ch)) { - ch->channel->CTRL_TRIG &= ~DMA_CTRL_TRIG_EN; - DMA->CHAN_ABORT = (1u << ch->chnidx); - - unsigned int abortGuard = PIO_FIFO_WAIT_LIMIT; - while (DMA->CHAN_ABORT & (1u << ch->chnidx) && --abortGuard) - { - } + dmaChannelDisableX(ch); } transferred = static_cast(work->Count - ch->channel->TRANS_COUNT); @@ -1076,13 +1070,7 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P if (dmaChannelIsBusyX(ch)) { - ch->channel->CTRL_TRIG &= ~DMA_CTRL_TRIG_EN; - DMA->CHAN_ABORT = (1u << ch->chnidx); - - unsigned int abortGuard = PIO_FIFO_WAIT_LIMIT; - while ((DMA->CHAN_ABORT & (1u << ch->chnidx)) && --abortGuard) - { - } + dmaChannelDisableX(ch); } // data already went out to the TX FIFO -- nothing to copy back From 2ca62c62aff9f441919ef5c143f781c09577746e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Mon, 27 Jul 2026 00:21:10 -0600 Subject: [PATCH 55/58] Rewrite the PIO binding on top of the ChibiOS RP low level drivers The binding drove the RP2040/RP2350 registers by hand even though the PIOv1 and DMAv1 LLDs already expose the same operations with names, and the hand-written paths had accumulated real defects. It now calls the LLD for everything delicate -- the DMA abort sequence with the RP2040-E13 / RP2350-E5 workarounds, the state machine init order, the SET PINDIRS chunking, JMP relocation on program load -- and keeps only what belongs to this layer: turning a CLR_RT_StackFrame into a validated state machine handle, CLR event handling, and argument checks. PioStateMachine.cpp goes from 1102 to ~800 lines, and no raw register access is left outside the handful of documented LLD gaps in _target.h. Defects fixed along the way, verified in execution on the emulator unless noted: - the tree did not build: pioGetSmHandle() does not exist upstream. The handle now comes from g_AllocatedSMs, which also distinguishes claimed from released. - Read/Write leaked their DMA channel on any error exit: the eval stack deadline and the transfer are now released in the cleanup, guarded on CLR_E_THREAD_WAITING so a parked thread still resumes. A leak left the slot busy forever and every later transfer failed. - the transferred count was read AFTER the abort, which zeroes TRANS_COUNT, so a timed out transfer reported the full count and Read copied never-written bounce buffer. Measured: a 16 word Write into a stalled state machine now reports 4, the FIFO depth. - DrainTxFifo emitted PUSH (0x8000) where it meant PULL (0x8080), so without autopull it never drained and pushed the ISR into RX instead. Measured: TX goes 2 -> 0 words, RX stays at 0. - the PIO interrupt callback posted one managed event per claimed state machine, because ChibiOS broadcasts a block's interrupt to all of them. It is now idempotent on the live IRQ flags. - NativeUnclaim freed the state machine while a transfer was still writing into a bounce buffer it was about to release. - CTRL was driven with read-modify-write, which can lose a concurrent enable; the atomic SET/CLR aliases are used instead. - SetConsecutivePinDirs did not clear OUT_STICKY around the exec'd writes. - InitGpio only set FUNCSEL, leaving the pad untouched and, on the RP2350, the isolation latch set. - DMA error flags handed to the callback were discarded. - unbounded busy-wait in the blocking FIFO accessors. The teardown native tolerates an already-disposed instance, matching NativeDispose in the I2C binding: a prologue that rejects disposed objects cannot guard the one call whose whole purpose is to run at disposal. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_017y2cw98Pjsa3eMgsAHdYEu --- ...noFramework_Hardware_Pico_Pio_PioBlock.cpp | 44 +- ...work_Hardware_Pico_Pio_PioStateMachine.cpp | 1151 ++++++----------- ...anoFramework_hardware_pico_native_target.h | 304 +++++ 3 files changed, 716 insertions(+), 783 deletions(-) diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp index 2738b8bacb..5ad714788b 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp @@ -17,15 +17,20 @@ const rp_pio_sm_t *g_AllocatedSMs[3][4] = {{nullptr}}; static void PioChibiOSCallback(void *param, const uint32_t flags) { - const int block = reinterpret_cast(param); + const int block = reinterpret_cast(param); + PIO_TypeDef *pio = __rp_pio_blocks[block].pio; - // Align the flags to the PIO block - See IRQ0_INTS documentation - const uint32_t sm_flags = (flags >> 8) & 0x0F; + // IRQ0_INTS bits [11:8] are the SM-raised flags, IRQ holds the same flags live + const uint32_t smFlags = ((flags >> 8) & 0x0Fu) & pio->IRQ; - PostManagedEvent(EVENT_PICO_PIO, EVENT_TYPE_PICO_PIO, static_cast(block), sm_flags); + if (smFlags == 0u) + { + return; + } - // Clear the flag in hardware to avoid an infinite loop of interrupts. - __rp_pio_blocks[block].pio->IRQ = sm_flags; + pio->IRQ = smFlags; + + PostManagedEvent(EVENT_PICO_PIO, EVENT_TYPE_PICO_PIO, static_cast(block), smFlags); } HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock:: @@ -47,7 +52,6 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P VALIDATE_PIO_BLOCK(block); - // Get the data from the PioProgram class passed as argument program_array = pProgram [Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioProgram::FIELD__Instructions] @@ -75,7 +79,8 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P if (offset < 0) { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); // No memory left + // No memory left + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); } stack.SetResult_I4(offset); @@ -134,9 +139,9 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P if (const rp_pio_sm_t *sm = pioSmAlloc( &__rp_pio_blocks[block], RP_PIO_SM_ID_ANY, - 3, + NF_PICO_PIO_IRQ_PRIORITY, PioChibiOSCallback, - reinterpret_cast(block)); + reinterpret_cast(static_cast(block))); sm == nullptr) { if (required) @@ -158,7 +163,6 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P { NANOCLR_HEADER(); - uint32_t mode; int block; const int pin = stack.Arg1().NumericByRef().s4; @@ -175,13 +179,7 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } - mode = (block == 0) ? PAL_MODE_ALTERNATE_PIO0 : PAL_MODE_ALTERNATE_PIO1; -#if defined(RP2350) - if (block == 2) - mode = PAL_MODE_ALTERNATE_PIO2; -#endif - - palSetPadMode(0, pin, mode); + NfPioBlockGpioInit(&__rp_pio_blocks[block], static_cast(pin)); NANOCLR_NOCLEANUP(); } @@ -207,7 +205,7 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } - __rp_pio_blocks[block].pio->IRQ_FORCE = (1u << irq); + NfPioBlockForceIrq(&__rp_pio_blocks[block], static_cast(irq)); NANOCLR_NOCLEANUP(); } @@ -233,7 +231,7 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } - __rp_pio_blocks[block].pio->IRQ = (1u << irq); + NfPioBlockClearIrq(&__rp_pio_blocks[block], static_cast(irq)); NANOCLR_NOCLEANUP(); } @@ -245,6 +243,8 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P int block; + const uint32_t mask = PIO_IRQ_SM(0) | PIO_IRQ_SM(1) | PIO_IRQ_SM(2) | PIO_IRQ_SM(3); + const bool enabled = static_cast(stack.Arg1().NumericByRef().u1); CLR_RT_HeapBlock *pThis = stack.This(); @@ -256,11 +256,11 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P if (enabled) { - __rp_pio_blocks[block].pio->IRQ0_INTE |= (0x0Fu << 8); + NfPioBlockEnableInterrupt(&__rp_pio_blocks[block], mask); } else { - __rp_pio_blocks[block].pio->IRQ0_INTE &= ~(0x0Fu << 8); + NfPioBlockDisableInterrupt(&__rp_pio_blocks[block], mask); } NANOCLR_NOCLEANUP(); diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp index 8a21e4093b..ce31881d96 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp @@ -12,29 +12,8 @@ #include "nanoFramework_hardware_pico_native_target.h" #include #include - -#define PIO_FSTAT_RXEMPTY_LSB 8u -#define PIO_FSTAT_TXFULL_LSB 16u - -static constexpr unsigned int PIO_FIFO_WAIT_LIMIT = 0x4000000u; - -struct PioDmaWork -{ - const rp_dma_channel_t *Channel; - unsigned int *Buffer; - unsigned int Count; -}; - -static PioDmaWork g_PioDmaWork[3][4] = {}; -static PioDmaWork g_PioDmaWorkTx[3][4] = {}; - -// DMA completion callback (ChibiOS shared handler dispatches here); just wake the waiting thread -static void PioDmaCallback(void *p, uint32_t ct) -{ - (void)p; - (void)ct; - Events_Set(SYSTEM_EVENT_FLAG_PICOPIO); -} +#include +#include enum PioCfgBlob { @@ -68,98 +47,334 @@ enum PioCfgBlob PIO_CFG_BLOB_LENGTH = 27, }; -extern unsigned int g_PioClaimedSm[3]; +static inline unsigned int PioRelPin(unsigned int gpio, unsigned int gpioBase) +{ + return (gpio >= gpioBase && (gpio - gpioBase) < 32u) ? (gpio - gpioBase) : (gpio & 0x1Fu); +} -HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: - NativeInit___VOID__I4__SZARRAY_U4(CLR_RT_StackFrame &stack) +static inline unsigned int PioShiftThreshold(unsigned int threshold) { - NANOCLR_HEADER(); + return (threshold == 0u || threshold > 32u) ? 32u : threshold; +} - PIO_TypeDef *pio; - CLR_RT_HeapBlock *pPioBlock; - CLR_RT_HeapBlock_Array *blobArray; - unsigned int *b; - unsigned int sidesetTotal, execCtrl, pushThresh, pullThresh, join; - int block, sm, offset; +enum PioDmaDir +{ + PioDmaRx = 0, + PioDmaTx = 1, +}; - CLR_RT_HeapBlock *pThis = stack.This(); - VALIDATE_NOT_DISPOSED(pThis); +struct PioDmaWork +{ + const rp_dma_channel_t *Channel; + uint32_t *Buffer; + uint32_t Count; + uint32_t Status; +}; - offset = stack.Arg1().NumericByRef().s4; - blobArray = stack.Arg2().DereferenceArray(); +static PioDmaWork g_PioDmaWork[3][4][2] = {}; - pPioBlock = pThis[FIELD___block].Dereference(); - FAULT_ON_NULL(pPioBlock); +#define PIO_DMA_ERROR_MASK (DMA_CTRL_TRIG_AHB_ERROR | DMA_CTRL_TRIG_READ_ERROR | DMA_CTRL_TRIG_WRITE_ERROR) - block = - pPioBlock[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::FIELD___index] - .NumericByRef() - .s4; - sm = pPioBlock[FIELD___sm].NumericByRef().s4; +static void PioDmaCallback(void *p, const uint32_t ct) +{ - FAULT_ON_NULL(blobArray); + if (auto *work = static_cast(p); work != nullptr) + { + work->Status = ct & PIO_DMA_ERROR_MASK; + } + + Events_Set(SYSTEM_EVENT_FLAG_PICOPIO); +} + +// Stops a transfer and gives the channel and bounce buffer back. +static void PioDmaFinish(PioDmaWork *work) +{ + const rp_dma_channel_t *ch = work->Channel; - if (offset > 31) + if (ch == nullptr) { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + return; } - VALIDATE_PIO_BLOCK(block); - VALIDATE_SM(sm); + if (dmaChannelIsBusyX(ch)) + { + dmaChannelDisableX(ch); + } - if (offset < 0 || offset > 31 || blobArray == nullptr || - static_cast(blobArray->m_numOfElements) < PIO_CFG_BLOB_LENGTH) + (void)dmaChannelGetAndClearInterrupts(ch); + dmaChannelFree(ch); + + if (work->Buffer != nullptr) + { + platform_free(work->Buffer); + } + + work->Channel = nullptr; + work->Buffer = nullptr; + work->Count = 0; + work->Status = 0; +} + +// Aborts and releases both directions of a state machine. +void PioDmaReleaseSm(const int block, const int sm) +{ + PioDmaFinish(&g_PioDmaWork[block][sm][PioDmaRx]); + PioDmaFinish(&g_PioDmaWork[block][sm][PioDmaTx]); +} + +// Arms a channel to move count words between the state machine FIFO and the bounce buffer. +static void PioDmaArm( + const rp_dma_channel_t *ch, + const rp_pio_sm_t *smp, + const PioDmaDir dir, + uint32_t *buf, + const uint32_t count) +{ + if (dir == PioDmaRx) + { + dmaChannelSetSourceX(ch, reinterpret_cast(pioSmRxFifoAddrX(smp))); + dmaChannelSetDestinationX(ch, reinterpret_cast(buf)); + dmaChannelSetCounterX(ch, count); + dmaChannelSetModeX( + ch, + DMA_CTRL_TRIG_DATA_SIZE_WORD | DMA_CTRL_TRIG_INCR_WRITE | DMA_CTRL_TRIG_TREQ_SEL(pioSmRxDreqX(smp))); + } + else + { + dmaChannelSetSourceX(ch, reinterpret_cast(buf)); + dmaChannelSetDestinationX(ch, reinterpret_cast(pioSmTxFifoAddrX(smp))); + dmaChannelSetCounterX(ch, count); + dmaChannelSetModeX( + ch, + DMA_CTRL_TRIG_DATA_SIZE_WORD | DMA_CTRL_TRIG_INCR_READ | DMA_CTRL_TRIG_TREQ_SEL(pioSmTxDreqX(smp))); + } + dmaChannelEnableInterruptX(ch); + dmaChannelEnableX(ch); +} + +// Shared body of Read and Write. +static HRESULT PioDmaTransfer(CLR_RT_StackFrame &stack, const PioDmaDir dir) +{ + NANOCLR_HEADER(); + + PioSmContext ctx{}; + CLR_RT_HeapBlock hbTimeout{}; + CLR_INT64 *timeoutTicks; + CLR_RT_HeapBlock_Array *buffer; + PioDmaWork *work; + PioDmaWork *ownedWork = nullptr; + uint32_t dmaStatus = 0; + bool eventResult = true; + bool timeoutPushed = false; + int transferred = 0; + int offset, count, timeoutMs; + + NANOCLR_PIO_SM_PROLOGUE(ctx); + + buffer = stack.Arg1().DereferenceArray(); + offset = stack.Arg2().NumericByRef().s4; + count = stack.Arg3().NumericByRef().s4; + timeoutMs = stack.Arg4().NumericByRef().s4; + + FAULT_ON_NULL(buffer); + + if (offset < 0 || count < 0 || timeoutMs < 0 || count > static_cast(buffer->m_numOfElements) || + offset > static_cast(buffer->m_numOfElements) - count) { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } - pio = __rp_pio_blocks[block].pio; - b = reinterpret_cast(blobArray->GetFirstElement()); + if (count == 0) + { + stack.SetResult_I4(0); + NANOCLR_SET_AND_LEAVE(S_OK); + } + + work = &g_PioDmaWork[ctx.block][ctx.sm][dir]; + + if (stack.m_customState != 1) + { + ownedWork = work; + } + + hbTimeout.SetInteger(static_cast(timeoutMs) * TIME_CONVERSION__TO_MILLISECONDS); + NANOCLR_CHECK_HRESULT(stack.SetupTimeoutFromTicks(hbTimeout, timeoutTicks)); + timeoutPushed = true; + + if (stack.m_customState == 1) + { + if (work->Channel != nullptr) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + + const rp_dma_channel_t *ch = + dmaChannelAlloc(RP_DMA_CHANNEL_ID_ANY, NF_PICO_PIO_IRQ_PRIORITY, PioDmaCallback, work); + if (ch == nullptr) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + + const auto buf = static_cast(platform_malloc(static_cast(count) * sizeof(uint32_t))); + if (buf == nullptr) + { + dmaChannelFree(ch); + NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_MEMORY); + } + + if (dir == PioDmaTx) + { + memcpy( + buf, + buffer->GetFirstElement() + static_cast(offset) * sizeof(uint32_t), + static_cast(count) * sizeof(uint32_t)); + } + + work->Channel = ch; + work->Buffer = buf; + work->Count = static_cast(count); + work->Status = 0; + ownedWork = work; + + PioDmaArm(ch, ctx.smp, dir, buf, static_cast(count)); + + Events_Get(SYSTEM_EVENT_FLAG_PICOPIO); + stack.m_customState = 2; + } + + while (work->Channel != nullptr && dmaChannelIsBusyX(work->Channel)) + { + NANOCLR_CHECK_HRESULT( + g_CLR_RT_ExecutionEngine.WaitEvents(stack.m_owningThread, *timeoutTicks, Event_PicoPio, eventResult)); + + if (!eventResult) + { + break; + } + } + + if (work->Channel != nullptr) + { + const uint32_t remaining = NfDmaChannelGetCounter(work->Channel); - // disable + restart before reconfigure - pio->CTRL &= ~(1u << sm); - pio->CTRL |= (1u << (4 + sm)); // SM_RESTART + dmaStatus = work->Status; + transferred = static_cast(work->Count - (remaining > work->Count ? work->Count : remaining)); - // CLKDIV: int [31:16], frac [15:8] - pio->SM[sm].CLKDIV = ((b[PIO_CFG_CLKDIV_INT] & 0xFFFFu) << 16) | ((b[PIO_CFG_CLKDIV_FRAC] & 0xFFu) << 8); + if (dir == PioDmaRx && transferred > 0) + { + memcpy( + buffer->GetFirstElement() + static_cast(offset) * sizeof(uint32_t), + work->Buffer, + static_cast(transferred) * sizeof(uint32_t)); + } - // side-set count includes the opt enable bit; each field masked to its width - sidesetTotal = b[PIO_CFG_SIDESET_COUNT] + b[PIO_CFG_SIDESET_OPT]; - pio->SM[sm].PINCTRL = ((sidesetTotal & 0x7u) << 29) | ((b[PIO_CFG_SET_COUNT] & 0x7u) << 26) | - ((b[PIO_CFG_OUT_COUNT] & 0x3Fu) << 20) | ((b[PIO_CFG_IN_BASE] & 0x1Fu) << 15) | - ((b[PIO_CFG_SIDESET_BASE] & 0x1Fu) << 10) | ((b[PIO_CFG_SET_BASE] & 0x1Fu) << 5) | - (b[PIO_CFG_OUT_BASE] & 0x1Fu); + PioDmaFinish(work); + } - // EXECCTRL: wrap [16:12], wrap_target [11:7], side_en [30], side_pindir [29], jmp_pin [28:24] - execCtrl = ((b[PIO_CFG_WRAP] & 0x1Fu) << 12) | ((b[PIO_CFG_WRAP_TARGET] & 0x1Fu) << 7) | - ((b[PIO_CFG_JMP_PIN] & 0x1Fu) << 24) | ((b[PIO_CFG_MOV_STATUS_SEL] & 1u) << 4) | - (b[PIO_CFG_MOV_STATUS_N] & 0xFu) | ((b[PIO_CFG_OUT_STICKY] & 1u) << 17) | - ((b[PIO_CFG_INLINE_OUT_EN] & 1u) << 18) | ((b[PIO_CFG_OUT_EN_SEL] & 0x1Fu) << 19); + stack.PopValue(); + timeoutPushed = false; - if (b[PIO_CFG_SIDESET_OPT]) + if (dmaStatus != 0) { - execCtrl |= (1u << 30); + NANOCLR_SET_AND_LEAVE(CLR_E_FAIL); } - if (b[PIO_CFG_SIDESET_PINDIRS]) + + stack.SetResult_I4(transferred); + + NANOCLR_CLEANUP(); + + if (hr != CLR_E_THREAD_WAITING) + { + if (timeoutPushed) + { + stack.PopValue(); + } + + if (ownedWork != nullptr) + { + PioDmaFinish(ownedWork); + } + } + + NANOCLR_CLEANUP_END(); +} + +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: + NativeInit___VOID__I4__SZARRAY_U4(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + PioSmContext ctx{}; + rp_pio_sm_config_t cfg; + CLR_RT_HeapBlock_Array *blobArray; + const unsigned int *b; + unsigned int gpioBase; + int offset; + + NANOCLR_PIO_SM_PROLOGUE(ctx); + + offset = stack.Arg1().NumericByRef().s4; + blobArray = stack.Arg2().DereferenceArray(); + + FAULT_ON_NULL(blobArray); + + if (offset < 0 || offset >= static_cast(RP_PIO_NUM_INSTR_MEM) || + static_cast(blobArray->m_numOfElements) < PIO_CFG_BLOB_LENGTH) { - execCtrl |= (1u << 29); + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } - pio->SM[sm].EXECCTRL = execCtrl; - // a 32-bit threshold encodes as 0 in the 5-bit field - pushThresh = b[PIO_CFG_PUSH_THRESHOLD] & 0x1F; - pullThresh = b[PIO_CFG_PULL_THRESHOLD] & 0x1F; - // FJOIN: low 2 bits -> TX [30] / RX [31]; high 2 bits (PIO v1) -> RX_GET [14] / RX_PUT [15] - join = b[PIO_CFG_FIFO_JOIN]; - pio->SM[sm].SHIFTCTRL = ((b[PIO_CFG_IN_SHIFT_RIGHT] & 1u) << 18) | ((b[PIO_CFG_OUT_SHIFT_RIGHT] & 1u) << 19) | - ((b[PIO_CFG_AUTOPUSH] & 1u) << 16) | ((b[PIO_CFG_AUTOPULL] & 1u) << 17) | - (pushThresh << 20) | (pullThresh << 25) | ((join & 3u) << 30) | (((join >> 2) & 3u) << 14); + b = reinterpret_cast(blobArray->GetFirstElement()); #if defined(RP2350) - *reinterpret_cast(&pio->GPIOBASE) = (b[PIO_CFG_GPIO_BASE] == 16) ? 16u : 0u; + gpioBase = (b[PIO_CFG_GPIO_BASE] == 16) ? 16u : 0u; + ctx.smp->block->pio->GPIOBASE = gpioBase; +#else + gpioBase = 0; #endif - pio->SM[sm].INSTR = static_cast(offset & 0x1F); + pioSmConfigDefaultX(&cfg); + + pioSmConfigSetClkdivX(&cfg, b[PIO_CFG_CLKDIV_INT] & 0xFFFFu, b[PIO_CFG_CLKDIV_FRAC] & 0xFFu); + pioSmConfigSetWrapX(&cfg, b[PIO_CFG_WRAP_TARGET] & 0x1Fu, b[PIO_CFG_WRAP] & 0x1Fu); + + pioSmConfigSetOutPinsX(&cfg, PioRelPin(b[PIO_CFG_OUT_BASE], gpioBase), b[PIO_CFG_OUT_COUNT] & 0x3Fu); + pioSmConfigSetSetPinsX(&cfg, PioRelPin(b[PIO_CFG_SET_BASE], gpioBase), b[PIO_CFG_SET_COUNT] & 0x7u); + pioSmConfigSetInPinsX(&cfg, PioRelPin(b[PIO_CFG_IN_BASE], gpioBase)); + pioSmConfigSetJmpPinX(&cfg, PioRelPin(b[PIO_CFG_JMP_PIN], gpioBase)); + + pioSmConfigSetSidesetX( + &cfg, + (b[PIO_CFG_SIDESET_COUNT] + b[PIO_CFG_SIDESET_OPT]) & 0x7u, + b[PIO_CFG_SIDESET_OPT] != 0, + b[PIO_CFG_SIDESET_PINDIRS] != 0); + pioSmConfigSetSidesetPinsX(&cfg, PioRelPin(b[PIO_CFG_SIDESET_BASE], gpioBase)); + + pioSmConfigSetInShiftX( + &cfg, + b[PIO_CFG_IN_SHIFT_RIGHT] != 0, + b[PIO_CFG_AUTOPUSH] != 0, + PioShiftThreshold(b[PIO_CFG_PUSH_THRESHOLD])); + pioSmConfigSetOutShiftX( + &cfg, + b[PIO_CFG_OUT_SHIFT_RIGHT] != 0, + b[PIO_CFG_AUTOPULL] != 0, + PioShiftThreshold(b[PIO_CFG_PULL_THRESHOLD])); + + NfPioSmConfigSetFifoJoin(&cfg, b[PIO_CFG_FIFO_JOIN]); + + pioSmConfigSetMovStatusX( + &cfg, + static_cast(b[PIO_CFG_MOV_STATUS_SEL]), + b[PIO_CFG_MOV_STATUS_N] & (PIO_SM_EXECCTRL_STATUS_N_Msk >> PIO_SM_EXECCTRL_STATUS_N_Pos)); + + pioSmConfigSetOutSpecialX( + &cfg, + b[PIO_CFG_OUT_STICKY] != 0, + b[PIO_CFG_INLINE_OUT_EN] != 0, + b[PIO_CFG_OUT_EN_SEL] & 0x1Fu); + + pioSmInit(ctx.smp, static_cast(offset), &cfg); NANOCLR_NOCLEANUP(); } @@ -182,82 +397,69 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P { NANOCLR_HEADER(); - CLR_RT_HeapBlock *pPioBlock; - int block, sm; + PioSmContext ctx{}; bool value; - CLR_RT_HeapBlock *pThis = stack.This(); - VALIDATE_NOT_DISPOSED(pThis); + NANOCLR_PIO_SM_PROLOGUE(ctx); value = stack.Arg1().NumericByRef().u1; - pPioBlock = pThis[FIELD___block].Dereference(); - FAULT_ON_NULL(pPioBlock); - - block = - pPioBlock[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::FIELD___index] - .NumericByRef() - .s4; - sm = pPioBlock[FIELD___sm].NumericByRef().s4; - - VALIDATE_PIO_BLOCK(block); - VALIDATE_SM(sm); - - pThis[FIELD___enabled].NumericByRef().u1 = value; + stack.This()[FIELD___enabled].NumericByRef().u1 = value; if (value) { - __rp_pio_blocks[block].pio->CTRL |= (1u << sm); + pioSmEnableX(ctx.smp); } else { - __rp_pio_blocks[block].pio->CTRL &= ~(1u << sm); + pioSmDisableX(ctx.smp); } NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: - NativePutBlocking___VOID__U4(CLR_RT_StackFrame &stack) +template static bool PioSpinWhile(TCondition blocked) { - NANOCLR_HEADER(); + unsigned int spins = NF_PICO_PIO_FIFO_SPIN_LIMIT; + unsigned int sleeps = NF_PICO_PIO_FIFO_TIMEOUT_MS; - PIO_TypeDef *pio; - CLR_RT_HeapBlock *pPioBlock; - unsigned int guard, value; - int block, sm; + while (blocked()) + { + if (spins > 0u) + { + spins--; + continue; + } - CLR_RT_HeapBlock *pThis = stack.This(); - VALIDATE_NOT_DISPOSED(pThis); + if (sleeps-- == 0u) + { + return false; + } - value = stack.Arg2().NumericByRef().u4; + osalThreadSleepMilliseconds(1); + } - pPioBlock = pThis[FIELD___block].Dereference(); - FAULT_ON_NULL(pPioBlock); + return true; +} - block = - pPioBlock[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::FIELD___index] - .NumericByRef() - .s4; - sm = pPioBlock[FIELD___sm].NumericByRef().s4; +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: + NativePutBlocking___VOID__U4(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); - VALIDATE_PIO_BLOCK(block); - VALIDATE_SM(sm); + PioSmContext ctx{}; + unsigned int value; - pio = __rp_pio_blocks[block].pio; + NANOCLR_PIO_SM_PROLOGUE(ctx); - // FSTAT TX_FULL = bits [19:16] - guard = PIO_FIFO_WAIT_LIMIT; - while ((pio->FSTAT & (1u << (PIO_FSTAT_TXFULL_LSB + sm))) && --guard) - { - } + value = stack.Arg2().NumericByRef().u4; - if (guard == 0) + if (!PioSpinWhile([&ctx] { return pioSmIsTxFullX(ctx.smp); })) { NANOCLR_SET_AND_LEAVE(CLR_E_TIMEOUT); } - pio->TXF[sm] = value; + pioSmPutX(ctx.smp, value); NANOCLR_NOCLEANUP(); } @@ -267,40 +469,16 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P { NANOCLR_HEADER(); - const PIO_TypeDef *pio; - CLR_RT_HeapBlock *pPioBlock; - unsigned int guard; - int block, sm; - - CLR_RT_HeapBlock *pThis = stack.This(); - VALIDATE_NOT_DISPOSED(pThis); - - pPioBlock = pThis[FIELD___block].Dereference(); - FAULT_ON_NULL(pPioBlock); + PioSmContext ctx{}; - block = - pPioBlock[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::FIELD___index] - .NumericByRef() - .s4; - sm = pPioBlock[FIELD___sm].NumericByRef().s4; + NANOCLR_PIO_SM_PROLOGUE(ctx); - VALIDATE_PIO_BLOCK(block); - VALIDATE_SM(sm); - - pio = __rp_pio_blocks[block].pio; - - // FSTAT RX_EMPTY = bits [11:8] - guard = PIO_FIFO_WAIT_LIMIT; - while ((pio->FSTAT & (1u << (PIO_FSTAT_RXEMPTY_LSB + sm))) && --guard) - { - } - - if (guard == 0) + if (!PioSpinWhile([&ctx] { return pioSmIsRxEmptyX(ctx.smp); })) { NANOCLR_SET_AND_LEAVE(CLR_E_TIMEOUT); } - stack.SetResult_U4(pio->RXF[sm]); + stack.SetResult_U4(pioSmGetX(ctx.smp)); NANOCLR_NOCLEANUP(); } @@ -310,28 +488,11 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P { NANOCLR_HEADER(); - const PIO_TypeDef *pio; - CLR_RT_HeapBlock *pPioBlock; - int block, sm; - - CLR_RT_HeapBlock *pThis = stack.This(); - VALIDATE_NOT_DISPOSED(pThis); + PioSmContext ctx{}; - pPioBlock = pThis[FIELD___block].Dereference(); - FAULT_ON_NULL(pPioBlock); + NANOCLR_PIO_SM_PROLOGUE(ctx); - block = - pPioBlock[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::FIELD___index] - .NumericByRef() - .s4; - sm = pPioBlock[FIELD___sm].NumericByRef().s4; - - VALIDATE_PIO_BLOCK(block); - VALIDATE_SM(sm); - - pio = __rp_pio_blocks[block].pio; - - stack.SetResult_Boolean((pio->FSTAT & (1u << (PIO_FSTAT_TXFULL_LSB + sm))) != 0); + stack.SetResult_Boolean(pioSmIsTxFullX(ctx.smp)); NANOCLR_NOCLEANUP(); } @@ -341,28 +502,11 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P { NANOCLR_HEADER(); - const PIO_TypeDef *pio; - CLR_RT_HeapBlock *pPioBlock; - int block, sm; - - CLR_RT_HeapBlock *pThis = stack.This(); - VALIDATE_NOT_DISPOSED(pThis); - - pPioBlock = pThis[FIELD___block].Dereference(); - FAULT_ON_NULL(pPioBlock); + PioSmContext ctx{}; - block = - pPioBlock[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::FIELD___index] - .NumericByRef() - .s4; - sm = pPioBlock[FIELD___sm].NumericByRef().s4; + NANOCLR_PIO_SM_PROLOGUE(ctx); - VALIDATE_PIO_BLOCK(block); - VALIDATE_SM(sm); - - pio = __rp_pio_blocks[block].pio; - - stack.SetResult_Boolean((pio->FSTAT & (1u << (PIO_FSTAT_RXEMPTY_LSB + sm))) != 0); + stack.SetResult_Boolean(pioSmIsRxEmptyX(ctx.smp)); NANOCLR_NOCLEANUP(); } @@ -372,31 +516,14 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P { NANOCLR_HEADER(); - CLR_RT_HeapBlock *pPioBlock; - int block, sm; - - CLR_RT_HeapBlock *pThis = stack.This(); - VALIDATE_NOT_DISPOSED(pThis); - - pPioBlock = pThis[FIELD___block].Dereference(); - FAULT_ON_NULL(pPioBlock); + PioSmContext ctx{}; - block = - pPioBlock[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::FIELD___index] - .NumericByRef() - .s4; - sm = pPioBlock[FIELD___sm].NumericByRef().s4; + NANOCLR_PIO_SM_TEARDOWN_PROLOGUE(ctx); - VALIDATE_PIO_BLOCK(block); - VALIDATE_SM(sm); - - __rp_pio_blocks[block].pio->CTRL &= ~(1u << sm); - - if (g_AllocatedSMs[block][sm] != nullptr) - { - pioSmFree(g_AllocatedSMs[block][sm]); - g_AllocatedSMs[block][sm] = nullptr; - } + pioSmDisableX(ctx.smp); + PioDmaReleaseSm(ctx.block, ctx.sm); + pioSmFree(ctx.smp); + g_AllocatedSMs[ctx.block][ctx.sm] = nullptr; NANOCLR_NOCLEANUP(); } @@ -406,67 +533,34 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P { NANOCLR_HEADER(); - PIO_TypeDef *pio; - CLR_RT_HeapBlock *pPioBlock; - int pin, remaining, gpioBase; - int block, sm, basePin, count, output; - unsigned int savedPinCtrl; + PioSmContext ctx{}; + int basePin, count, gpioBase; + bool output; - CLR_RT_HeapBlock *pThis = stack.This(); - VALIDATE_NOT_DISPOSED(pThis); + NANOCLR_PIO_SM_PROLOGUE(ctx); basePin = stack.Arg1().NumericByRef().s4; count = stack.Arg2().NumericByRef().s4; - output = stack.Arg3().NumericByRef().u1; - - pPioBlock = pThis[FIELD___block].Dereference(); - FAULT_ON_NULL(pPioBlock); - - block = - pPioBlock[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::FIELD___index] - .NumericByRef() - .s4; - sm = pPioBlock[FIELD___sm].NumericByRef().s4; - - VALIDATE_PIO_BLOCK(block); - VALIDATE_SM(sm); + output = stack.Arg3().NumericByRef().u1 != 0; - pio = __rp_pio_blocks[block].pio; + if (count == 0) + { + NANOCLR_SET_AND_LEAVE(S_OK); + } #if defined(RP2350) - gpioBase = static_cast(pio->GPIOBASE); + gpioBase = static_cast(ctx.smp->block->pio->GPIOBASE); #else gpioBase = 0; #endif - // SET_BASE is 5-bit, relative to the SM's GPIO base, so reject pins outside the 32-pin window if (basePin < 0 || basePin > PIO_MAX_PIN || count < 0 || count > 32 || (basePin + count) > (PIO_MAX_PIN + 1) || basePin < gpioBase || (basePin - gpioBase + count) > 32) { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } - // up to 5 pins per "SET pindirs" exec, then restore PINCTRL - pin = basePin; - remaining = count; - savedPinCtrl = pio->SM[sm].PINCTRL; - - while (remaining > 0) - { - const int chunk = remaining < 5 ? remaining : 5; - const unsigned int dirs = output ? ((1u << chunk) - 1u) : 0u; - - // PINCTRL: SET_COUNT [28:26], SET_BASE [9:5] - pio->SM[sm].PINCTRL = - (static_cast(chunk) << 26) | ((static_cast(pin - gpioBase) & 0x1Fu) << 5); - // SET pindirs, dirs - pio->SM[sm].INSTR = 0xE000u | (4u << 5) | (dirs & 0x1Fu); - - remaining -= chunk; - pin += chunk; - } - - pio->SM[sm].PINCTRL = savedPinCtrl; + pioSmSetConsecutivePindirsX(ctx.smp, static_cast(basePin), static_cast(count), output); NANOCLR_NOCLEANUP(); } @@ -476,32 +570,11 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P { NANOCLR_HEADER(); - PIO_TypeDef *pio; - CLR_RT_HeapBlock *pPioBlock; - unsigned int fjoinRx; - int block, sm; - - CLR_RT_HeapBlock *pThis = stack.This(); - VALIDATE_NOT_DISPOSED(pThis); - - pPioBlock = pThis[FIELD___block].Dereference(); - FAULT_ON_NULL(pPioBlock); - - block = - pPioBlock[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::FIELD___index] - .NumericByRef() - .s4; - sm = pPioBlock[FIELD___sm].NumericByRef().s4; + PioSmContext ctx{}; - VALIDATE_PIO_BLOCK(block); - VALIDATE_SM(sm); + NANOCLR_PIO_SM_PROLOGUE(ctx); - pio = __rp_pio_blocks[block].pio; - - // toggle FJOIN_RX (bit 31) twice to flush both FIFOs, SHIFTCTRL unchanged - fjoinRx = (1u << 31); - pio->SM[sm].SHIFTCTRL ^= fjoinRx; - pio->SM[sm].SHIFTCTRL ^= fjoinRx; + pioSmClearFifosX(ctx.smp); NANOCLR_NOCLEANUP(); } @@ -511,38 +584,11 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P { NANOCLR_HEADER(); - PIO_TypeDef *pio; - CLR_RT_HeapBlock *pPioBlock; - unsigned int autopull, instr, guard; - int block, sm; - - CLR_RT_HeapBlock *pThis = stack.This(); - VALIDATE_NOT_DISPOSED(pThis); - - pPioBlock = pThis[FIELD___block].Dereference(); - FAULT_ON_NULL(pPioBlock); - - block = - pPioBlock[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::FIELD___index] - .NumericByRef() - .s4; - sm = pPioBlock[FIELD___sm].NumericByRef().s4; - - VALIDATE_PIO_BLOCK(block); - VALIDATE_SM(sm); - - pio = __rp_pio_blocks[block].pio; + PioSmContext ctx{}; - // exec OUT NULL,32 (autopull) or PULL noblock until TX empty. FSTAT TX_EMPTY = bits [27:24] - autopull = pio->SM[sm].SHIFTCTRL & (1u << 17); - instr = autopull ? 0x6060u : 0x8000u; - guard = PIO_FIFO_WAIT_LIMIT; + NANOCLR_PIO_SM_PROLOGUE(ctx); - while ((pio->FSTAT & (1u << (24 + sm))) == 0 && --guard) - { - pio->SM[sm].INSTR = instr; - } - if (guard == 0) + if (!NfPioSmDrainTxFifo(ctx.smp, NF_PICO_PIO_DRAIN_LIMIT)) { NANOCLR_SET_AND_LEAVE(CLR_E_TIMEOUT); } @@ -555,29 +601,11 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P { NANOCLR_HEADER(); - PIO_TypeDef *pio; - CLR_RT_HeapBlock *pPioBlock; - int block, sm; - - CLR_RT_HeapBlock *pThis = stack.This(); - VALIDATE_NOT_DISPOSED(pThis); - - pPioBlock = pThis[FIELD___block].Dereference(); - FAULT_ON_NULL(pPioBlock); - - block = - pPioBlock[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::FIELD___index] - .NumericByRef() - .s4; - sm = pPioBlock[FIELD___sm].NumericByRef().s4; - - VALIDATE_PIO_BLOCK(block); - VALIDATE_SM(sm); + PioSmContext ctx{}; - pio = __rp_pio_blocks[block].pio; + NANOCLR_PIO_SM_PROLOGUE(ctx); - // SM_RESTART = bits [7:4] - pio->CTRL |= (1u << (4 + sm)); + pioSmRestartX(ctx.smp); NANOCLR_NOCLEANUP(); } @@ -587,30 +615,11 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P { NANOCLR_HEADER(); - PIO_TypeDef *pio; - CLR_RT_HeapBlock *pPioBlock; - int block; - int sm; + PioSmContext ctx{}; - CLR_RT_HeapBlock *pThis = stack.This(); - VALIDATE_NOT_DISPOSED(pThis); - - pPioBlock = pThis[FIELD___block].Dereference(); - FAULT_ON_NULL(pPioBlock); - - block = - pPioBlock[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::FIELD___index] - .NumericByRef() - .s4; - sm = pPioBlock[FIELD___sm].NumericByRef().s4; + NANOCLR_PIO_SM_PROLOGUE(ctx); - VALIDATE_PIO_BLOCK(block); - VALIDATE_SM(sm); - - pio = __rp_pio_blocks[block].pio; - - // CLKDIV_RESTART = bits [11:8] - pio->CTRL |= (1u << (8 + sm)); + pioSmClkdivRestartX(ctx.smp); NANOCLR_NOCLEANUP(); } @@ -620,33 +629,11 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P { NANOCLR_HEADER(); - PIO_TypeDef *pio; - CLR_RT_HeapBlock *pPioBlock; - int block; - int sm; - unsigned short instruction; + PioSmContext ctx{}; - CLR_RT_HeapBlock *pThis = stack.This(); - VALIDATE_NOT_DISPOSED(pThis); + NANOCLR_PIO_SM_PROLOGUE(ctx); - instruction = stack.Arg1().NumericByRef().u2; - - pPioBlock = pThis[FIELD___block].Dereference(); - FAULT_ON_NULL(pPioBlock); - - block = - pPioBlock[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::FIELD___index] - .NumericByRef() - .s4; - sm = pPioBlock[FIELD___sm].NumericByRef().s4; - - VALIDATE_PIO_BLOCK(block); - VALIDATE_SM(sm); - - pio = __rp_pio_blocks[block].pio; - - // exec out of band, PC unchanged - pio->SM[sm].INSTR = static_cast(instruction); + pioSmExecX(ctx.smp, stack.Arg1().NumericByRef().u2); NANOCLR_NOCLEANUP(); } @@ -656,28 +643,11 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P { NANOCLR_HEADER(); - const PIO_TypeDef *pio; - CLR_RT_HeapBlock *pPioBlock; - int block, sm; - - CLR_RT_HeapBlock *pThis = stack.This(); - VALIDATE_NOT_DISPOSED(pThis); - - pPioBlock = pThis[FIELD___block].Dereference(); - FAULT_ON_NULL(pPioBlock); - - block = - pPioBlock[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::FIELD___index] - .NumericByRef() - .s4; - sm = pPioBlock[FIELD___sm].NumericByRef().s4; - - VALIDATE_PIO_BLOCK(block); - VALIDATE_SM(sm); + PioSmContext ctx{}; - pio = __rp_pio_blocks[block].pio; + NANOCLR_PIO_SM_PROLOGUE(ctx); - stack.SetResult_U4((pio->FLEVEL >> (8 * sm)) & 0xFu); + stack.SetResult_U4(pioSmTxFifoLevelX(ctx.smp)); NANOCLR_NOCLEANUP(); } @@ -687,28 +657,11 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P { NANOCLR_HEADER(); - const PIO_TypeDef *pio; - CLR_RT_HeapBlock *pPioBlock; - int block, sm; - - CLR_RT_HeapBlock *pThis = stack.This(); - VALIDATE_NOT_DISPOSED(pThis); - - pPioBlock = pThis[FIELD___block].Dereference(); - FAULT_ON_NULL(pPioBlock); + PioSmContext ctx{}; - block = - pPioBlock[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::FIELD___index] - .NumericByRef() - .s4; - sm = pPioBlock[FIELD___sm].NumericByRef().s4; + NANOCLR_PIO_SM_PROLOGUE(ctx); - VALIDATE_PIO_BLOCK(block); - VALIDATE_SM(sm); - - pio = __rp_pio_blocks[block].pio; - - stack.SetResult_U4((pio->FLEVEL >> (8 * sm + 4)) & 0xFu); + stack.SetResult_U4(pioSmRxFifoLevelX(ctx.smp)); NANOCLR_NOCLEANUP(); } @@ -718,28 +671,11 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P { NANOCLR_HEADER(); - const PIO_TypeDef *pio; - CLR_RT_HeapBlock *pPioBlock; - int block, sm; - - CLR_RT_HeapBlock *pThis = stack.This(); - VALIDATE_NOT_DISPOSED(pThis); - - pPioBlock = pThis[FIELD___block].Dereference(); - FAULT_ON_NULL(pPioBlock); - - block = - pPioBlock[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::FIELD___index] - .NumericByRef() - .s4; - sm = pPioBlock[FIELD___sm].NumericByRef().s4; - - VALIDATE_PIO_BLOCK(block); - VALIDATE_SM(sm); + PioSmContext ctx{}; - pio = __rp_pio_blocks[block].pio; + NANOCLR_PIO_SM_PROLOGUE(ctx); - stack.SetResult_U4(pio->SM[sm].ADDR & 0x1Fu); + stack.SetResult_U4(pioSmGetAddrX(ctx.smp) & 0x1Fu); NANOCLR_NOCLEANUP(); } @@ -749,28 +685,14 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P { NANOCLR_HEADER(); - PIO_TypeDef *pio; - CLR_RT_HeapBlock *pPioBlock; - int block, sm, intPart, frac; + PioSmContext ctx{}; + int intPart, frac; float value; - CLR_RT_HeapBlock *pThis = stack.This(); - VALIDATE_NOT_DISPOSED(pThis); - - pPioBlock = pThis[FIELD___block].Dereference(); - FAULT_ON_NULL(pPioBlock); - - block = - pPioBlock[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::FIELD___index] - .NumericByRef() - .s4; - sm = pPioBlock[FIELD___sm].NumericByRef().s4; + NANOCLR_PIO_SM_PROLOGUE(ctx); value = stack.Arg1().NumericByRef().r4; - VALIDATE_PIO_BLOCK(block); - VALIDATE_SM(sm); - if (!(value >= 1.0f && value <= 65536.0f)) { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); @@ -784,12 +706,8 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P intPart += 1; } - pio = __rp_pio_blocks[block].pio; - - pio->SM[sm].CLKDIV = - (static_cast(intPart >= 65536 ? 0 : intPart) << 16) | (static_cast(frac) << 8); - - pio->CTRL |= (1u << (8 + sm)); + pioSmSetClkdivX(ctx.smp, PIO_SM_CLKDIV(intPart >= 65536 ? 0 : intPart, frac)); + pioSmClkdivRestartX(ctx.smp); NANOCLR_NOCLEANUP(); } @@ -797,300 +715,11 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: Read___I4__SZARRAY_U4__I4__I4__I4(CLR_RT_StackFrame &stack) { - NANOCLR_HEADER(); - - CLR_RT_HeapBlock hbTimeout{}; - CLR_RT_HeapBlock *pPioBlock; - CLR_INT64 *timeoutTicks; - CLR_RT_HeapBlock_Array *buffer; - bool eventResult = true; - int transferred = 0; - int block, sm, offset, count, timeoutMs; - - PIO_TypeDef *pio; - PioDmaWork *work; - - CLR_RT_HeapBlock *pThis = stack.This(); - VALIDATE_NOT_DISPOSED(pThis); - - buffer = stack.Arg1().DereferenceArray(); - offset = stack.Arg2().NumericByRef().s4; - count = stack.Arg3().NumericByRef().s4; - timeoutMs = stack.Arg4().NumericByRef().s4; - - pPioBlock = pThis[FIELD___block].Dereference(); - FAULT_ON_NULL(pPioBlock); - - block = - pPioBlock[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::FIELD___index] - .NumericByRef() - .s4; - sm = pPioBlock[FIELD___sm].NumericByRef().s4; - - FAULT_ON_NULL(buffer); - - if (offset < 0 || count < 0 || timeoutMs < 0 || count > static_cast(buffer->m_numOfElements) || - offset > static_cast(buffer->m_numOfElements) - count) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } - - if (count == 0) - { - stack.SetResult_I4(0); - NANOCLR_SET_AND_LEAVE(S_OK); - } - - VALIDATE_PIO_BLOCK(block); - VALIDATE_SM(sm); - - pio = __rp_pio_blocks[block].pio; - work = &g_PioDmaWork[block][sm]; - - hbTimeout.SetInteger(static_cast(timeoutMs) * TIME_CONVERSION__TO_MILLISECONDS); - NANOCLR_CHECK_HRESULT(stack.SetupTimeoutFromTicks(hbTimeout, timeoutTicks)); - - // first call: validate + arm the DMA + park - if (stack.m_customState == 1) - { - // PIO RX DREQ is only mapped for PIO0/PIO1; PIO2 (RP2350) not wired yet - if (g_AllocatedSMs[block][sm] == nullptr) - { - NANOCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); - } - if (buffer == nullptr || count <= 0 || work->Channel != nullptr) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); - } - - // ChibiOS-owned DMA channel + completion callback (no raw vector, no clash with the SPI DMA) - const rp_dma_channel_t *ch = dmaChannelAlloc(RP_DMA_CHANNEL_ID_ANY, 3, PioDmaCallback, work); - if (ch == nullptr) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); - } - - unsigned int *buf = static_cast(platform_malloc(static_cast(count) * 4)); - if (buf == nullptr) - { - dmaChannelFree(ch); - NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_MEMORY); - } - - // read = SM RX FIFO (fixed), write = bounce buffer (incrementing), paced by the SM RX DREQ - const unsigned int dreq = (static_cast(block) * 8u) + 4u + static_cast(sm); - - ch->channel->READ_ADDR = reinterpret_cast(&pio->RXF[sm]); - ch->channel->WRITE_ADDR = reinterpret_cast(buf); - ch->channel->TRANS_COUNT = static_cast(count); - dmaChannelEnableInterruptX(ch); - ch->channel->CTRL_TRIG = DMA_CTRL_TRIG_EN | DMA_CTRL_TRIG_DATA_SIZE_WORD | DMA_CTRL_TRIG_INCR_WRITE | - DMA_CTRL_TRIG_TREQ_SEL(dreq) | DMA_CTRL_TRIG_CHAIN_TO(ch->chnidx); - - work->Channel = ch; - work->Buffer = buf; - work->Count = static_cast(count); - - Events_Get(SYSTEM_EVENT_FLAG_PICOPIO); - stack.m_customState = 2; - } - - // wait on the shared PICOPIO event; re-check OUR channel's busy bit each wake (shared-event safe) - while (work->Channel != nullptr && dmaChannelIsBusyX(work->Channel)) - { - NANOCLR_CHECK_HRESULT( - g_CLR_RT_ExecutionEngine.WaitEvents(stack.m_owningThread, *timeoutTicks, Event_PicoPio, eventResult)); - if (!eventResult) - { - // timed out; the finish path below aborts the channel - break; - } - } - - if (work->Channel != nullptr) - { - const rp_dma_channel_t *ch = work->Channel; - - // on timeout the channel is still busy; stop it so it can't write after we free the buffer - if (dmaChannelIsBusyX(ch)) - { - dmaChannelDisableX(ch); - } - - transferred = static_cast(work->Count - ch->channel->TRANS_COUNT); - if (transferred < 0) - { - transferred = 0; - } - if (buffer != nullptr && offset >= 0 && transferred > 0 && - (offset + transferred) <= static_cast(buffer->m_numOfElements)) - { - memcpy( - buffer->GetFirstElement() + static_cast(offset) * 4, - work->Buffer, - static_cast(transferred) * 4); - } - - (void)dmaChannelGetAndClearInterrupts(ch); - dmaChannelFree(ch); - platform_free(work->Buffer); - work->Channel = nullptr; - work->Buffer = nullptr; - work->Count = 0; - } - - // pop the timeout heap block and return the word count actually transferred - stack.PopValue(); - stack.SetResult_I4(transferred); - - NANOCLR_NOCLEANUP(); + return PioDmaTransfer(stack, PioDmaRx); } HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: Write___I4__SZARRAY_U4__I4__I4__I4(CLR_RT_StackFrame &stack) { - NANOCLR_HEADER(); - - CLR_RT_HeapBlock hbTimeout{}; - CLR_RT_HeapBlock *pPioBlock; - CLR_INT64 *timeoutTicks; - CLR_RT_HeapBlock_Array *buffer = nullptr; - bool eventResult = true; - int transferred = 0; - int block, sm, offset, count, timeoutMs; - - PIO_TypeDef *pio; - PioDmaWork *work; - - CLR_RT_HeapBlock *pThis = stack.This(); - VALIDATE_NOT_DISPOSED(pThis); - - buffer = stack.Arg1().DereferenceArray(); - offset = stack.Arg2().NumericByRef().s4; - count = stack.Arg3().NumericByRef().s4; - timeoutMs = stack.Arg4().NumericByRef().s4; - - pPioBlock = pThis[FIELD___block].Dereference(); - FAULT_ON_NULL(pPioBlock); - - block = - pPioBlock[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::FIELD___index] - .NumericByRef() - .s4; - sm = pPioBlock[FIELD___sm].NumericByRef().s4; - - FAULT_ON_NULL(buffer); - - if (offset < 0 || count < 0 || timeoutMs < 0 || count > static_cast(buffer->m_numOfElements) || - offset > static_cast(buffer->m_numOfElements) - count) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } - - if (count == 0) - { - stack.SetResult_I4(0); - NANOCLR_SET_AND_LEAVE(S_OK); - } - - VALIDATE_PIO_BLOCK(block); - VALIDATE_SM(sm); - - pio = __rp_pio_blocks[block].pio; - work = &g_PioDmaWorkTx[block][sm]; - - hbTimeout.SetInteger(static_cast(timeoutMs) * TIME_CONVERSION__TO_MILLISECONDS); - NANOCLR_CHECK_HRESULT(stack.SetupTimeoutFromTicks(hbTimeout, timeoutTicks)); - - // first call: validate + copy out + arm the DMA + park - if (stack.m_customState == 1) - { - // PIO TX DREQ is only mapped for PIO0/PIO1; PIO2 (RP2350) not wired yet - if (g_AllocatedSMs[block][sm] == nullptr) - { - NANOCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); - } - - if (buffer == nullptr || count <= 0 || work->Channel != nullptr || offset < 0 || - (offset + count) > static_cast(buffer->m_numOfElements)) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); - } - - // ChibiOS-owned DMA channel + completion callback (no raw vector, no clash with the SPI DMA) - const rp_dma_channel_t *ch = dmaChannelAlloc(RP_DMA_CHANNEL_ID_ANY, 3, PioDmaCallback, work); - if (ch == nullptr) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); - } - - unsigned int *buf = static_cast(platform_malloc(static_cast(count) * 4)); - if (buf == nullptr) - { - dmaChannelFree(ch); - NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_MEMORY); - } - - // copy the words out into the bounce buffer before the DMA drains it into the TX FIFO - memcpy(buf, buffer->GetFirstElement() + static_cast(offset) * 4, static_cast(count) * 4); - - // read = bounce buffer (incrementing), write = SM TX FIFO (fixed), paced by the SM TX DREQ - const unsigned int dreq = (static_cast(block) * 8u) + static_cast(sm); - - ch->channel->READ_ADDR = reinterpret_cast(buf); - ch->channel->WRITE_ADDR = reinterpret_cast(&pio->TXF[sm]); - ch->channel->TRANS_COUNT = static_cast(count); - dmaChannelEnableInterruptX(ch); - ch->channel->CTRL_TRIG = DMA_CTRL_TRIG_EN | DMA_CTRL_TRIG_DATA_SIZE_WORD | DMA_CTRL_TRIG_INCR_READ | - DMA_CTRL_TRIG_TREQ_SEL(dreq) | DMA_CTRL_TRIG_CHAIN_TO(ch->chnidx); - - work->Channel = ch; - work->Buffer = buf; - work->Count = static_cast(count); - - Events_Get(SYSTEM_EVENT_FLAG_PICOPIO); - stack.m_customState = 2; - } - - // wait on the shared PICOPIO event; re-check OUR channel's busy bit each wake (shared-event safe) - while (work->Channel != nullptr && dmaChannelIsBusyX(work->Channel)) - { - NANOCLR_CHECK_HRESULT( - g_CLR_RT_ExecutionEngine.WaitEvents(stack.m_owningThread, *timeoutTicks, Event_PicoPio, eventResult)); - if (!eventResult) - { - // timed out; the finish path below aborts the channel - break; - } - } - - if (work->Channel != nullptr) - { - const rp_dma_channel_t *ch = work->Channel; - - if (dmaChannelIsBusyX(ch)) - { - dmaChannelDisableX(ch); - } - - // data already went out to the TX FIFO -- nothing to copy back - transferred = static_cast(work->Count - ch->channel->TRANS_COUNT); - if (transferred < 0) - { - transferred = 0; - } - - (void)dmaChannelGetAndClearInterrupts(ch); - dmaChannelFree(ch); - platform_free(work->Buffer); - work->Channel = nullptr; - work->Buffer = nullptr; - work->Count = 0; - } - - // pop the timeout heap block and return the word count actually transferred - stack.PopValue(); - stack.SetResult_I4(transferred); - - NANOCLR_NOCLEANUP(); + return PioDmaTransfer(stack, PioDmaTx); } diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_target.h b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_target.h index c4e3af1f0f..f16c1ea91c 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_target.h +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_target.h @@ -6,6 +6,29 @@ #ifndef NANOFRAMEWORK_HARDWARE_PICO_NATIVE_TARGET_H #define NANOFRAMEWORK_HARDWARE_PICO_NATIVE_TARGET_H +#include +#include +#include +#include + +// +// Everything the PIO binding needs on top of the ChibiOS RP low level drivers, and nothing else: +// the boilerplate that turns a CLR_RT_StackFrame into a validated state machine handle, plus the +// handful of operations the LLD does not expose yet. +// +// Each of those is marked "LLD gap" and mirrors a change proposed upstream in the +// begeistert/chibios branches enhance-pico-pio-api / enhance-pico-dma-api. When one lands the +// workaround is deleted and the call is replaced by the LLD function of the same shape. +// +// What ChibiOS already does is called, never reimplemented: the DMA abort sequence with the +// RP2040-E13 / RP2350-E5 workarounds, the state machine init sequence, the SET PINDIRS chunking, +// JMP relocation on program load. +// + +// --------------------------------------------------------------------------- +// Target constants +// --------------------------------------------------------------------------- + #if defined(RP2350) #define PIO_MAX_BLOCK 2 #define PIO_MAX_PIN 47 @@ -20,6 +43,29 @@ #define PIO_MIN_BLOCK 0 #endif +// NVIC priority requested for the PIO and DMA shared vectors. +// +// Both pioSmAlloc() and dmaChannelAlloc() apply the priority only on the first allocation a core +// makes, and ignore it afterwards: for PIO that is per block, for DMA it is global. So this is +// the effective priority only if this binding is the first PIO/DMA consumer to start. On a WiFi +// target the CYW43 bus driver claims a PIO0 state machine with priority 0 first, which is why +// PIO_MIN_BLOCK keeps block 0 out of reach of managed code. +#define NF_PICO_PIO_IRQ_PRIORITY 3 + +// Budget for a blocking single word FIFO transfer: a tight spin first, because a state machine +// that is running usually frees a FIFO slot within a few cycles, then millisecond sleeps up to +// the timeout so a stalled state machine cannot hold the CLR thread indefinitely. +#define NF_PICO_PIO_FIFO_SPIN_LIMIT 256u +#define NF_PICO_PIO_FIFO_TIMEOUT_MS 1000u + +// Instructions DrainTxFifo executes before giving up. The loop only ends if the state machine +// consumes what is exec'd into it, so this bounds the case where it is stalled on something else. +#define NF_PICO_PIO_DRAIN_LIMIT 0x10000u + +// --------------------------------------------------------------------------- +// Argument validation +// --------------------------------------------------------------------------- + #define VALIDATE_PIO_BLOCK(block) \ if ((block) < 0 || (block) > PIO_MAX_BLOCK) \ { \ @@ -43,6 +89,264 @@ NANOCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); \ } +// --------------------------------------------------------------------------- +// Shared state +// --------------------------------------------------------------------------- + +// Handles returned by pioSmAlloc() at claim time, indexed [block][sm]. A null entry means the +// state machine is not claimed, so this doubles as the claim bookkeeping. extern const rp_pio_sm_t *g_AllocatedSMs[3][4]; +// Aborts and releases any DMA work in flight on a state machine. Defined in the PioStateMachine +// native so NativeUnclaim can stop the transfer before the state machine handle goes away. +void PioDmaReleaseSm(int block, int sm); + +// --------------------------------------------------------------------------- +// State machine context +// --------------------------------------------------------------------------- + +// Everything a native method needs about the state machine it was called on. +struct PioSmContext +{ + const rp_pio_sm_t *smp; + int block; + int sm; +}; + +// Resolves the PioBlock/sm fields of a PioStateMachine instance into a PioSmContext. +// +// Returns CLR_E_OBJECT_DISPOSED both for a disposed instance and for a state machine that is no +// longer claimed, which is what callers hit after Dispose(); every other failure is a bad field +// value and maps to CLR_E_INVALID_PARAMETER. +inline HRESULT PioGetSmContext(CLR_RT_HeapBlock *pThis, PioSmContext &ctx, bool allowDisposed = false) +{ + NANOCLR_HEADER(); + + CLR_RT_HeapBlock *pPioBlock; + + FAULT_ON_NULL(pThis); + + if (!allowDisposed && pThis[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: + FIELD___disposed] + .NumericByRef() + .u1 != 0) + { + NANOCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); + } + + pPioBlock = + pThis[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::FIELD___block] + .Dereference(); + FAULT_ON_NULL(pPioBlock); + + ctx.block = + pPioBlock[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::FIELD___index] + .NumericByRef() + .s4; + ctx.sm = + pThis[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::FIELD___sm] + .NumericByRef() + .s4; + + VALIDATE_PIO_BLOCK(ctx.block); + VALIDATE_SM(ctx.sm); + + ctx.smp = g_AllocatedSMs[ctx.block][ctx.sm]; + if (ctx.smp == nullptr) + { + NANOCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); + } + + NANOCLR_NOCLEANUP(); +} + +// Opens a PioStateMachine native method: rejects a disposed instance and resolves the context. +// +// The PioSmContext is declared by the caller alongside its other locals rather than here, so +// that the goto this macro can take never jumps over an initialization. +#define NANOCLR_PIO_SM_PROLOGUE(ctx) \ + { \ + NANOCLR_CHECK_HRESULT(PioGetSmContext(stack.This(), ctx)); \ + } + +#define NANOCLR_PIO_SM_TEARDOWN_PROLOGUE(ctx) \ + { \ + NANOCLR_CHECK_HRESULT(PioGetSmContext(stack.This(), ctx, true)); \ + } + +// --------------------------------------------------------------------------- +// LLD gap: PIO instruction encoding +// --------------------------------------------------------------------------- +// +// pioSmExecX() takes a raw 16-bit instruction and ChibiOS offers no way to build one, so every +// consumer ends up with bare literals -- the CYW43 bus driver grew its own set in +// targets/ChibiOS/_WiFi/cyw43/cyw43_bus_pio_spi.c:116-123. +// + +// OUT NULL, 32 -- discards a whole OSR word, used to drain a TX FIFO under autopull. +#define NF_PIO_INSTR_OUT_NULL_32 0x6060u +// PULL noblock -- discards a TX FIFO word when autopull is off. +// +// The PULL opcode is 0x8080: bit 7 is what distinguishes it from PUSH, which is 0x8000. This +// used to be encoded as 0x8000, so the non-autopull path of DrainTxFifo was executing PUSH +// noblock, pushing the ISR into the RX FIFO instead of discarding a TX FIFO word -- the TX FIFO +// never drained and the RX FIFO filled with garbage. +#define NF_PIO_INSTR_PULL_NOBLOCK 0x8080u + +// --------------------------------------------------------------------------- +// LLD gap: FIFO joining beyond the three modes ChibiOS models +// --------------------------------------------------------------------------- +// +// rp_pio_fifo_join_t only has NONE/TX/RX, so pioSmConfigSetFifoJoinX() cannot express the RP2350 +// RXF_PUTGET modes that live in SHIFTCTRL bits 14/15. The managed PioFifoJoin enum does expose +// them, so the low two bits go through the LLD builder and the high two are applied here. +// +// On the RP2040 those bits do not exist; writing them was harmless but wrong, so they are +// dropped rather than written through. +// + +#if defined(RP2350) +#define NF_PIO_SM_SHIFTCTRL_FJOIN_RX_GET (1u << 14) +#define NF_PIO_SM_SHIFTCTRL_FJOIN_RX_PUT (1u << 15) +#endif + +// Applies the managed PioFifoJoin value to a configuration image. +// +// Low two bits are the plain TX/RX joins, high two bits the RP2350 put/get variants. +inline void NfPioSmConfigSetFifoJoin(rp_pio_sm_config_t *cfgp, unsigned int join) +{ + pioSmConfigSetFifoJoinX(cfgp, static_cast(join & 3u)); + +#if defined(RP2350) + cfgp->shiftctrl &= ~(NF_PIO_SM_SHIFTCTRL_FJOIN_RX_GET | NF_PIO_SM_SHIFTCTRL_FJOIN_RX_PUT); + + if (join & 4u) + { + cfgp->shiftctrl |= NF_PIO_SM_SHIFTCTRL_FJOIN_RX_GET; + } + if (join & 8u) + { + cfgp->shiftctrl |= NF_PIO_SM_SHIFTCTRL_FJOIN_RX_PUT; + } +#endif +} + +// --------------------------------------------------------------------------- +// LLD gap: block level interrupt enables and IRQ flags +// --------------------------------------------------------------------------- +// +// The PIO_IRQ_SM(n) flags belong to the block, not to a state machine, but ChibiOS only offers +// pioSmEnableInterruptX()/pioSmDisableInterruptX(). These use the same atomic SET/CLR aliases and +// the same "enable on the current core, disable on both" convention. +// + +inline void NfPioBlockEnableInterrupt(const rp_pio_block_t *block, uint32_t mask) +{ + if (SIO->CPUID == 0u) + { + block->pio->SET.IRQ0_INTE = mask; + } + else + { + block->pio->SET.IRQ1_INTE = mask; + } +} + +inline void NfPioBlockDisableInterrupt(const rp_pio_block_t *block, uint32_t mask) +{ + block->pio->CLR.IRQ0_INTE = mask; + block->pio->CLR.IRQ1_INTE = mask; +} + +// Raises a PIO IRQ flag from the CPU side (IRQ_FORCE is write-only, one bit per flag). +inline void NfPioBlockForceIrq(const rp_pio_block_t *block, uint32_t irq) +{ + block->pio->IRQ_FORCE = 1u << irq; +} + +// Clears a PIO IRQ flag (the IRQ register is write-1-to-clear). +inline void NfPioBlockClearIrq(const rp_pio_block_t *block, uint32_t irq) +{ + block->pio->IRQ = 1u << irq; +} + +// --------------------------------------------------------------------------- +// LLD gap: routing a GPIO to a block that may have no claimed state machine +// --------------------------------------------------------------------------- +// +// FUNCSEL selects a PIO *block*, but pioGpioInitX() is keyed on a state machine handle. The +// managed InitGpio lives on PioBlock and can run before any SM is claimed, so the block variant +// is open coded here with the same glitch-free ordering pioGpioInitPadX() uses on the RP2350. +// + +inline void NfPioBlockGpioInit(const rp_pio_block_t *block, uint32_t gpio) +{ + // same table pioSmSetPinFunctionX() uses, keyed on the block instead of a state machine + static const uint32_t funcsels[] = { + RP_PIO_FUNCSEL_PIO0, + RP_PIO_FUNCSEL_PIO1, +#if RP_HAS_PIO2 == TRUE + RP_PIO_FUNCSEL_PIO2, +#endif + }; + + const uint32_t funcsel = funcsels[block->pioidx]; + +#if defined(RP2350) + // reprogram the pad while still isolated, drop the latch only once FUNCSEL points at the PIO + PADS_BANK0->GPIO[gpio] = RP_PIO_PAD_DEFAULT | RP_PIO_PAD_ISO; + IO_BANK0->GPIO[gpio].CTRL = funcsel; + PADS_BANK0->GPIO[gpio] = RP_PIO_PAD_DEFAULT; +#else + PADS_BANK0->GPIO[gpio] = RP_PIO_PAD_DEFAULT; + IO_BANK0->GPIO[gpio].CTRL = funcsel; +#endif +} + +// --------------------------------------------------------------------------- +// LLD gap: draining the TX FIFO +// --------------------------------------------------------------------------- +// +// The pico-sdk has pio_sm_drain_tx_fifo(); ChibiOS has nothing. Which instruction empties the +// FIFO depends on autopull, so this cannot be written correctly without reading SHIFTCTRL. +// +// Returns false if the FIFO did not drain within the spin budget, which means the state machine +// is stalled and not consuming. +// + +inline bool NfPioSmDrainTxFifo(const rp_pio_sm_t *smp, unsigned int spinLimit) +{ + const bool autopull = (smp->block->pio->SM[smp->smidx].SHIFTCTRL & PIO_SM_SHIFTCTRL_AUTOPULL) != 0u; + const uint16_t instr = autopull ? NF_PIO_INSTR_OUT_NULL_32 : NF_PIO_INSTR_PULL_NOBLOCK; + + while ((smp->block->pio->FSTAT & PIO_FSTAT_TXEMPTY(smp->smidx)) == 0u) + { + if (spinLimit-- == 0u) + { + return false; + } + + pioSmExecX(smp, instr); + } + + return true; +} + +// --------------------------------------------------------------------------- +// LLD gap: reading back a DMA transfer counter +// --------------------------------------------------------------------------- +// +// dmaChannelSetCounterX() exists but there is no getter, and on the RP2350 TRANS_COUNT[31:28] is +// the count MODE field, so a raw read has to be masked to get the remaining word count. +// + +inline uint32_t NfDmaChannelGetCounter(const rp_dma_channel_t *dmachp) +{ +#if defined(RP2350) + return dmachp->channel->TRANS_COUNT & ~DMA_TRANS_COUNT_MODE_Msk; +#else + return dmachp->channel->TRANS_COUNT; +#endif +} + #endif // NANOFRAMEWORK_HARDWARE_PICO_NATIVE_TARGET_H From 190a03dafbbc613b340bd9465372e6297cdff348 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Mon, 27 Jul 2026 00:21:24 -0600 Subject: [PATCH 56/58] Build the Pico binding at -O0 in Debug so gdb can inspect it The rest of the firmware stays at -Og, which makes gdb report "value has been optimized out" for locals in these files. Scoped to this folder to keep the image size unchanged elsewhere. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_017y2cw98Pjsa3eMgsAHdYEu --- CMake/Modules/FindnanoFramework.Hardware.Pico.cmake | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CMake/Modules/FindnanoFramework.Hardware.Pico.cmake b/CMake/Modules/FindnanoFramework.Hardware.Pico.cmake index 81619fea57..6714869f7e 100644 --- a/CMake/Modules/FindnanoFramework.Hardware.Pico.cmake +++ b/CMake/Modules/FindnanoFramework.Hardware.Pico.cmake @@ -37,6 +37,15 @@ foreach(SRC_FILE ${nanoFramework.Hardware.Pico_SRCS}) list(APPEND nanoFramework.Hardware.Pico_SOURCES ${nanoFramework.Hardware.Pico_SRC_FILE}) + # Debug-only: compile every native source of the Pico binding at -O0 so gdb can inspect + # locals/arguments across the whole binding. The rest of the firmware stays at -Og (see + # nf_set_optimization_options), which otherwise makes gdb report "value has been optimized + # out" for locals in these files. Scoped to just this folder (Option C) to keep the rest of + # the image at -Og and avoid overflowing flash. See docs/CLION_GDB.md §8. + set_source_files_properties( + ${nanoFramework.Hardware.Pico_SRC_FILE} + PROPERTIES COMPILE_OPTIONS "$<$:-O0>") + endforeach() From 5ecb3860742d598fee795839fdef469f1ca024cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Mon, 27 Jul 2026 03:21:16 -0600 Subject: [PATCH 57/58] Park the blocking FIFO calls instead of spinning, and claim state machines by index Put and Get held the CLR for up to a second. The native side waited with PioSpinWhile, which sleeps on the RTOS but never yields to the CLR scheduler, so every other managed thread stopped for the whole budget. They now follow the same re-entrant pattern the DMA transfers already use: arm the state machine's TXNFULL or RXNEMPTY interrupt, hand the thread back through WaitEvents with CLR_E_THREAD_WAITING, and finish the transfer when the interrupt brings it back. The block callback grew the FIFO half of the dispatch: it masks the asserted bits, which are level triggered and would otherwise storm, and posts the event. Read and Write are unchanged; the shared direction enum is renamed to PioFifoDir now that it describes both paths. Measured on the emulator with a probe that slows the state machine to about 2 kHz so the echo cannot be ready when Get looks: the callback fires, the call resumes, and a background thread ticks 25 times while Main sits in a Put that never completes -- with the spin it could not have ticked once. The same Put still gives up after the one second budget. Put, TryPut and TryGet read their first argument from Arg2, where an instance method keeps its second. The value written into the FIFO was whatever happened to sit in that slot, so a loopback round trip came back wrong; TryGet dereferenced the wrong slot for its byref. Left over from the move to instance members, when the block and state machine arguments went away and the indices were not shifted down. NativeClaimUnusedSm becomes NativeClaimSm, an instance method that takes the wanted index and reads the block from the object. Passing RP_PIO_SM_ID_ANY asks for whichever is free, so one native covers both pio_claim_unused_sm and pio_sm_claim, and the managed side no longer threads _index through every call. Anything that is neither ANY nor 0..3 is rejected before it reaches the allocator. Pio gains three statics that report what the firmware was built for -- the first block application code may use, how many exist, and the highest GPIO a block can drive -- so managed code stops hardcoding indices that differ between the RP2040, the RP2350 and the boards that reserve PIO0 for the radio. --- .../FindnanoFramework.Hardware.Pico.cmake | 1 + .../nanoFramework_hardware_pico_native.cpp | 18 +- .../nanoFramework_hardware_pico_native.h | 78 +++++++- ...ve_nanoFramework_Hardware_Pico_Pio_Pio.cpp | 37 ++++ ...noFramework_Hardware_Pico_Pio_PioBlock.cpp | 62 ++++--- ...work_Hardware_Pico_Pio_PioStateMachine.cpp | 168 +++++++++++++----- ...anoFramework_hardware_pico_native_target.h | 163 ++--------------- 7 files changed, 304 insertions(+), 223 deletions(-) create mode 100644 targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_Pio.cpp diff --git a/CMake/Modules/FindnanoFramework.Hardware.Pico.cmake b/CMake/Modules/FindnanoFramework.Hardware.Pico.cmake index 6714869f7e..14171c00c0 100644 --- a/CMake/Modules/FindnanoFramework.Hardware.Pico.cmake +++ b/CMake/Modules/FindnanoFramework.Hardware.Pico.cmake @@ -16,6 +16,7 @@ list(APPEND nanoFramework.Hardware.Pico_INCLUDE_DIRS "${BASE_PATH_FOR_THIS_MODUL set(nanoFramework.Hardware.Pico_SRCS nanoFramework_hardware_pico_native.cpp + nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_Pio.cpp nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp ) diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp index bd28fc2723..c7c7360448 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.cpp @@ -8,6 +8,9 @@ // clang-format off static const CLR_RT_MethodHandler method_lookup[] = { + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_Pio::get_MinIndex___STATIC__I4, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_Pio::get_BlockCount___STATIC__I4, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_Pio::get_MaxPin___STATIC__I4, NULL, NULL, NULL, @@ -76,7 +79,6 @@ static const CLR_RT_MethodHandler method_lookup[] = Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::AddProgram___U4__nanoFrameworkHardwarePicoPioPioProgram, Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::RemoveProgram___VOID__nanoFrameworkHardwarePicoPioPioProgram__U4, NULL, - NULL, Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::InitGpio___VOID__I4, NULL, Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::ForceIrq___VOID__I4, @@ -84,8 +86,8 @@ static const CLR_RT_MethodHandler method_lookup[] = NULL, NULL, NULL, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::NativeClaimSm___I4__I4, Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::NativeSetIrqEnabled___VOID__BOOLEAN, - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::NativeClaimUnusedSm___STATIC__I4__I4__BOOLEAN, NULL, NULL, NULL, @@ -182,10 +184,10 @@ static const CLR_RT_MethodHandler method_lookup[] = Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::get_RxLevel___U4, Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::get_ProgramCounter___U4, Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::set_ClockDivisor___VOID__R4, - NULL, - NULL, - NULL, - NULL, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::Put___VOID__U4, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::Get___U4, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::TryPut___BOOLEAN__U4, + Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::TryGet___BOOLEAN__BYREF_U4, Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::ClearFifos___VOID, Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::DrainTxFifo___VOID, Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::Restart___VOID, @@ -196,8 +198,6 @@ static const CLR_RT_MethodHandler method_lookup[] = Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::Read___I4__SZARRAY_U4__I4__I4__I4, Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::Write___I4__SZARRAY_U4__I4__I4__I4, Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeInit___VOID__I4__SZARRAY_U4, - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativePutBlocking___VOID__U4, - Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeGetBlocking___U4, Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::NativeUnclaim___VOID, NULL, NULL, @@ -223,7 +223,7 @@ static const CLR_RT_MethodHandler method_lookup[] = const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Pico = { "nanoFramework.Hardware.Pico", - 0xB0752CBB, + 0xD0D5FFA7, method_lookup, { 1, 0, 0, 0 } }; diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.h b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.h index 882efad316..fc873344e2 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.h +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native.h @@ -68,6 +68,15 @@ typedef enum __nfpack PioMovStatusSel PioMovStatusSel_RxLevel = 1, } PioMovStatusSel; +typedef enum __nfpack PioStateMachineIndex +{ + PioStateMachineIndex_Sm0 = 0, + PioStateMachineIndex_Sm1 = 1, + PioStateMachineIndex_Sm2 = 2, + PioStateMachineIndex_Sm3 = 3, + PioStateMachineIndex_Any = 4, +} PioStateMachineIndex; + typedef enum __nfpack PioVersion { PioVersion_Rp2040 = 0, @@ -102,27 +111,46 @@ struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pi { static const int FIELD_STATIC___blocks = 0; static const int FIELD_STATIC___lock = 1; + + NANOCLR_NATIVE_DECLARE(get_MinIndex___STATIC__I4); + NANOCLR_NATIVE_DECLARE(get_BlockCount___STATIC__I4); + NANOCLR_NATIVE_DECLARE(get_MaxPin___STATIC__I4); + + //--// }; struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioAssemblerOptions { + // renamed backing field 'k__BackingField' static const int FIELD__Version = 1; + // renamed backing field 'k__BackingField' static const int FIELD__SideSetCount = 2; + // renamed backing field 'k__BackingField' static const int FIELD__SideSetOption = 3; + // renamed backing field 'k__BackingField' static const int FIELD__SideSetPinDirs = 4; + + //--// }; struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioInstructionRef { static const int FIELD___owner = 1; static const int FIELD___index = 2; + + //--// }; struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioLabel { + // renamed backing field 'k__BackingField' static const int FIELD__Id = 1; + // renamed backing field 'k__BackingField' static const int FIELD__Owner = 2; + // renamed backing field '
k__BackingField' static const int FIELD__Address = 3; + + //--// }; struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioAssembler @@ -147,11 +175,14 @@ struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pi static const int FIELD___inShiftDir = 18; static const int FIELD___autoPush = 19; static const int FIELD___pushThreshold = 20; + + //--// }; struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock { static const int FIELD_STATIC__s_eventListener = 2; + static const int FIELD___index = 1; static const int FIELD___interruptCallbacks = 2; static const int FIELD___irqLock = 3; @@ -161,53 +192,88 @@ struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pi NANOCLR_NATIVE_DECLARE(InitGpio___VOID__I4); NANOCLR_NATIVE_DECLARE(ForceIrq___VOID__I4); NANOCLR_NATIVE_DECLARE(ClearIrq___VOID__I4); + NANOCLR_NATIVE_DECLARE(NativeClaimSm___I4__I4); NANOCLR_NATIVE_DECLARE(NativeSetIrqEnabled___VOID__BOOLEAN); - NANOCLR_NATIVE_DECLARE(NativeClaimUnusedSm___STATIC__I4__I4__BOOLEAN); + + //--// }; struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioEvent { static const int FIELD__BlockIndex = 3; static const int FIELD__Flags = 4; + + //--// }; struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioEventListener { static const int FIELD___pioMap = 1; static const int FIELD___syncRoot = 2; + + //--// }; struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioProgramOptions { + // renamed backing field 'k__BackingField' static const int FIELD__Version = 1; + // renamed backing field 'k__BackingField' static const int FIELD__Origin = 2; + // renamed backing field 'k__BackingField' static const int FIELD__SideSetCount = 3; + // renamed backing field 'k__BackingField' static const int FIELD__SideSetOptional = 4; + // renamed backing field 'k__BackingField' static const int FIELD__SideSetPinDirs = 5; + // renamed backing field 'k__BackingField' static const int FIELD__OutShiftDir = 6; + // renamed backing field 'k__BackingField' static const int FIELD__AutoPull = 7; + // renamed backing field 'k__BackingField' static const int FIELD__PullThreshold = 8; + // renamed backing field 'k__BackingField' static const int FIELD__InShiftDir = 9; + // renamed backing field 'k__BackingField' static const int FIELD__AutoPush = 10; + // renamed backing field 'k__BackingField' static const int FIELD__PushThreshold = 11; + + //--// }; struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioProgram { + // renamed backing field 'k__BackingField' static const int FIELD__Instructions = 1; + // renamed backing field 'k__BackingField' static const int FIELD__Wrap = 2; + // renamed backing field 'k__BackingField' static const int FIELD__WrapTarget = 3; + // renamed backing field 'k__BackingField' static const int FIELD__Origin = 4; + // renamed backing field 'k__BackingField' static const int FIELD__SideSetCount = 5; + // renamed backing field 'k__BackingField' static const int FIELD__SideSetOptional = 6; + // renamed backing field 'k__BackingField' static const int FIELD__SideSetPinDirs = 7; + // renamed backing field 'k__BackingField' static const int FIELD__OutShiftDir = 8; + // renamed backing field 'k__BackingField' static const int FIELD__AutoPull = 9; + // renamed backing field 'k__BackingField' static const int FIELD__PullThreshold = 10; + // renamed backing field 'k__BackingField' static const int FIELD__InShiftDir = 11; + // renamed backing field 'k__BackingField' static const int FIELD__AutoPush = 12; + // renamed backing field 'k__BackingField' static const int FIELD__PushThreshold = 13; + // renamed backing field 'k__BackingField' static const int FIELD__Version = 14; + + //--// }; struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine @@ -226,6 +292,10 @@ struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pi NANOCLR_NATIVE_DECLARE(get_RxLevel___U4); NANOCLR_NATIVE_DECLARE(get_ProgramCounter___U4); NANOCLR_NATIVE_DECLARE(set_ClockDivisor___VOID__R4); + NANOCLR_NATIVE_DECLARE(Put___VOID__U4); + NANOCLR_NATIVE_DECLARE(Get___U4); + NANOCLR_NATIVE_DECLARE(TryPut___BOOLEAN__U4); + NANOCLR_NATIVE_DECLARE(TryGet___BOOLEAN__BYREF_U4); NANOCLR_NATIVE_DECLARE(ClearFifos___VOID); NANOCLR_NATIVE_DECLARE(DrainTxFifo___VOID); NANOCLR_NATIVE_DECLARE(Restart___VOID); @@ -235,9 +305,9 @@ struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pi NANOCLR_NATIVE_DECLARE(Read___I4__SZARRAY_U4__I4__I4__I4); NANOCLR_NATIVE_DECLARE(Write___I4__SZARRAY_U4__I4__I4__I4); NANOCLR_NATIVE_DECLARE(NativeInit___VOID__I4__SZARRAY_U4); - NANOCLR_NATIVE_DECLARE(NativePutBlocking___VOID__U4); - NANOCLR_NATIVE_DECLARE(NativeGetBlocking___U4); NANOCLR_NATIVE_DECLARE(NativeUnclaim___VOID); + + //--// }; struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachineConfig @@ -271,6 +341,8 @@ struct Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pi static const int FIELD___outSticky = 27; static const int FIELD___inlineOutEn = 28; static const int FIELD___outEnSel = 29; + + //--// }; extern const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Pico; diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_Pio.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_Pio.cpp new file mode 100644 index 0000000000..de9b74e597 --- /dev/null +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_Pio.cpp @@ -0,0 +1,37 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include "nanoFramework_hardware_pico_native.h" +#include "nanoFramework_hardware_pico_native_target.h" + +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_Pio::get_MinIndex___STATIC__I4( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + stack.SetResult_I4(PIO_MIN_BLOCK); + + NANOCLR_NOCLEANUP_NOLABEL(); +} + +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_Pio::get_BlockCount___STATIC__I4( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + stack.SetResult_I4(PIO_MAX_BLOCK + 1); + + NANOCLR_NOCLEANUP_NOLABEL(); +} + +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_Pio::get_MaxPin___STATIC__I4( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + stack.SetResult_I4(PIO_MAX_PIN); + + NANOCLR_NOCLEANUP_NOLABEL(); +} diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp index 5ad714788b..2d0b028153 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock.cpp @@ -21,6 +21,13 @@ static void PioChibiOSCallback(void *param, const uint32_t flags) PIO_TypeDef *pio = __rp_pio_blocks[block].pio; // IRQ0_INTS bits [11:8] are the SM-raised flags, IRQ holds the same flags live + + if (const uint32_t fifoFlags = flags & 0xFFu; fifoFlags != 0u) + { + NfPioBlockDisableInterrupt(&__rp_pio_blocks[block], fifoFlags); + Events_Set(SYSTEM_EVENT_FLAG_PICOPIO); + } + const uint32_t smFlags = ((flags >> 8) & 0x0Fu) & pio->IRQ; if (smFlags == 0u) @@ -68,7 +75,7 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P if (program_array == nullptr || length <= 0 || length > 32 || static_cast(program_array->m_numOfElements) < length) { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE); } prog.instructions = reinterpret_cast(program_array->GetFirstElement()); @@ -118,7 +125,7 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P if (offset < 0 || length <= 0 || length > 32 || offset > 32 - length) { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE); } pioProgramUnload(&__rp_pio_blocks[block], offset, length); @@ -126,35 +133,44 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock:: - NativeClaimUnusedSm___STATIC__I4__I4__BOOLEAN(CLR_RT_StackFrame &stack) +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioBlock::NativeClaimSm___I4__I4( + CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); - const int block = stack.Arg0().NumericByRef().s4; - const bool required = stack.Arg1().NumericByRef().u1; + int block; + const rp_pio_sm_t *smp; + + const int wanted = stack.Arg1().NumericByRef().s4; + + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + + block = pThis[FIELD___index].NumericByRef().s4; VALIDATE_PIO_BLOCK(block); - if (const rp_pio_sm_t *sm = pioSmAlloc( - &__rp_pio_blocks[block], - RP_PIO_SM_ID_ANY, - NF_PICO_PIO_IRQ_PRIORITY, - PioChibiOSCallback, - reinterpret_cast(static_cast(block))); - sm == nullptr) + if (wanted != static_cast(RP_PIO_SM_ID_ANY)) { - if (required) - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); - stack.SetResult_I4(-1); + VALIDATE_SM(wanted); } - else - { - g_AllocatedSMs[block][sm->smidx] = sm; - stack.SetResult_I4(static_cast(sm->smidx)); + smp = pioSmAlloc( + &__rp_pio_blocks[block], + static_cast(wanted), + NF_PICO_PIO_IRQ_PRIORITY, + PioChibiOSCallback, + reinterpret_cast(static_cast(block))); + + if (smp == nullptr) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); } + g_AllocatedSMs[block][smp->smidx] = smp; + + stack.SetResult_I4(static_cast(smp->smidx)); + NANOCLR_NOCLEANUP(); } @@ -176,7 +192,7 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P if (pin < 0 || pin > PIO_MAX_PIN) { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE); } NfPioBlockGpioInit(&__rp_pio_blocks[block], static_cast(pin)); @@ -202,7 +218,7 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P if (irq < 0 || irq > 7) { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE); } NfPioBlockForceIrq(&__rp_pio_blocks[block], static_cast(irq)); @@ -228,7 +244,7 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P if (irq < 0 || irq > 7) { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE); } NfPioBlockClearIrq(&__rp_pio_blocks[block], static_cast(irq)); diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp index ce31881d96..a853a98bc9 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine.cpp @@ -12,8 +12,8 @@ #include "nanoFramework_hardware_pico_native_target.h" #include #include -#include -#include +#include +#include enum PioCfgBlob { @@ -57,10 +57,10 @@ static inline unsigned int PioShiftThreshold(unsigned int threshold) return (threshold == 0u || threshold > 32u) ? 32u : threshold; } -enum PioDmaDir +enum PioFifoDir { - PioDmaRx = 0, - PioDmaTx = 1, + PioFifoRx = 0, + PioFifoTx = 1, }; struct PioDmaWork @@ -118,19 +118,19 @@ static void PioDmaFinish(PioDmaWork *work) // Aborts and releases both directions of a state machine. void PioDmaReleaseSm(const int block, const int sm) { - PioDmaFinish(&g_PioDmaWork[block][sm][PioDmaRx]); - PioDmaFinish(&g_PioDmaWork[block][sm][PioDmaTx]); + PioDmaFinish(&g_PioDmaWork[block][sm][PioFifoRx]); + PioDmaFinish(&g_PioDmaWork[block][sm][PioFifoTx]); } // Arms a channel to move count words between the state machine FIFO and the bounce buffer. static void PioDmaArm( const rp_dma_channel_t *ch, const rp_pio_sm_t *smp, - const PioDmaDir dir, + const PioFifoDir dir, uint32_t *buf, const uint32_t count) { - if (dir == PioDmaRx) + if (dir == PioFifoRx) { dmaChannelSetSourceX(ch, reinterpret_cast(pioSmRxFifoAddrX(smp))); dmaChannelSetDestinationX(ch, reinterpret_cast(buf)); @@ -153,7 +153,7 @@ static void PioDmaArm( } // Shared body of Read and Write. -static HRESULT PioDmaTransfer(CLR_RT_StackFrame &stack, const PioDmaDir dir) +static HRESULT PioDmaTransfer(CLR_RT_StackFrame &stack, const PioFifoDir dir) { NANOCLR_HEADER(); @@ -181,7 +181,7 @@ static HRESULT PioDmaTransfer(CLR_RT_StackFrame &stack, const PioDmaDir dir) if (offset < 0 || count < 0 || timeoutMs < 0 || count > static_cast(buffer->m_numOfElements) || offset > static_cast(buffer->m_numOfElements) - count) { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE); } if (count == 0) @@ -222,7 +222,7 @@ static HRESULT PioDmaTransfer(CLR_RT_StackFrame &stack, const PioDmaDir dir) NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_MEMORY); } - if (dir == PioDmaTx) + if (dir == PioFifoTx) { memcpy( buf, @@ -260,7 +260,7 @@ static HRESULT PioDmaTransfer(CLR_RT_StackFrame &stack, const PioDmaDir dir) dmaStatus = work->Status; transferred = static_cast(work->Count - (remaining > work->Count ? work->Count : remaining)); - if (dir == PioDmaRx && transferred > 0) + if (dir == PioFifoRx && transferred > 0) { memcpy( buffer->GetFirstElement() + static_cast(offset) * sizeof(uint32_t), @@ -318,8 +318,12 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P FAULT_ON_NULL(blobArray); - if (offset < 0 || offset >= static_cast(RP_PIO_NUM_INSTR_MEM) || - static_cast(blobArray->m_numOfElements) < PIO_CFG_BLOB_LENGTH) + if (offset < 0 || offset >= static_cast(RP_PIO_NUM_INSTR_MEM)) + { + NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE); + } + + if (static_cast(blobArray->m_numOfElements) < PIO_CFG_BLOB_LENGTH) { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } @@ -418,67 +422,149 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P NANOCLR_NOCLEANUP(); } -template static bool PioSpinWhile(TCondition blocked) +static inline bool PioFifoBlocked(const rp_pio_sm_t *smp, const PioFifoDir dir) +{ + return (dir == PioFifoTx) ? pioSmIsTxFullX(smp) : pioSmIsRxEmptyX(smp); +} + +static HRESULT PioFifoTransfer(CLR_RT_StackFrame &stack, const PioFifoDir dir) { - unsigned int spins = NF_PICO_PIO_FIFO_SPIN_LIMIT; - unsigned int sleeps = NF_PICO_PIO_FIFO_TIMEOUT_MS; + NANOCLR_HEADER(); - while (blocked()) + PioSmContext ctx{}; + CLR_RT_HeapBlock hbTimeout{}; + CLR_INT64 *timeoutTicks; + const rp_pio_block_t *blockp = nullptr; + uint32_t inteMask = 0; + bool eventResult = true; + bool timeoutPushed = false; + bool interruptEnabled = false; + bool blocked; + + NANOCLR_PIO_SM_PROLOGUE(ctx); + + blockp = &__rp_pio_blocks[ctx.block]; + inteMask = (dir == PioFifoTx) ? PIO_IRQ_TXNFULL(ctx.sm) : PIO_IRQ_RXNEMPTY(ctx.sm); + + hbTimeout.SetInteger(static_cast(NF_PICO_PIO_FIFO_TIMEOUT_MS) * TIME_CONVERSION__TO_MILLISECONDS); + NANOCLR_CHECK_HRESULT(stack.SetupTimeoutFromTicks(hbTimeout, timeoutTicks)); + timeoutPushed = true; + + if (stack.m_customState == 1) { - if (spins > 0u) + Events_Get(SYSTEM_EVENT_FLAG_PICOPIO); + stack.m_customState = 2; + } + + while (PioFifoBlocked(ctx.smp, dir)) + { + NfPioBlockEnableInterrupt(blockp, inteMask); + interruptEnabled = true; + + NANOCLR_CHECK_HRESULT( + g_CLR_RT_ExecutionEngine.WaitEvents(stack.m_owningThread, *timeoutTicks, Event_PicoPio, eventResult)); + + if (!eventResult) { - spins--; - continue; + break; } + } - if (sleeps-- == 0u) + NfPioBlockDisableInterrupt(blockp, inteMask); + interruptEnabled = false; + + blocked = PioFifoBlocked(ctx.smp, dir); + + stack.PopValue(); + timeoutPushed = false; + + if (blocked) + { + NANOCLR_SET_AND_LEAVE(CLR_E_TIMEOUT); + } + + if (dir == PioFifoTx) + { + pioSmPutX(ctx.smp, stack.Arg1().NumericByRef().u4); + } + else + { + stack.SetResult_U4(pioSmGetX(ctx.smp)); + } + + NANOCLR_CLEANUP(); + + if (hr != CLR_E_THREAD_WAITING) + { + if (interruptEnabled) { - return false; + NfPioBlockDisableInterrupt(blockp, inteMask); } - osalThreadSleepMilliseconds(1); + if (timeoutPushed) + { + stack.PopValue(); + } } - return true; + NANOCLR_CLEANUP_END(); +} + +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::Put___VOID__U4( + CLR_RT_StackFrame &stack) +{ + return PioFifoTransfer(stack, PioFifoTx); +} + +HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine::Get___U4( + CLR_RT_StackFrame &stack) +{ + return PioFifoTransfer(stack, PioFifoRx); } HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: - NativePutBlocking___VOID__U4(CLR_RT_StackFrame &stack) + TryPut___BOOLEAN__U4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); PioSmContext ctx{}; - unsigned int value; NANOCLR_PIO_SM_PROLOGUE(ctx); - value = stack.Arg2().NumericByRef().u4; - - if (!PioSpinWhile([&ctx] { return pioSmIsTxFullX(ctx.smp); })) + if (pioSmIsTxFullX(ctx.smp)) { - NANOCLR_SET_AND_LEAVE(CLR_E_TIMEOUT); + stack.SetResult_Boolean(false); + NANOCLR_SET_AND_LEAVE(S_OK); } - pioSmPutX(ctx.smp, value); + pioSmPutX(ctx.smp, stack.Arg1().NumericByRef().u4); + stack.SetResult_Boolean(true); NANOCLR_NOCLEANUP(); } HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: - NativeGetBlocking___U4(CLR_RT_StackFrame &stack) + TryGet___BOOLEAN__BYREF_U4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); PioSmContext ctx{}; + CLR_RT_HeapBlock *value; NANOCLR_PIO_SM_PROLOGUE(ctx); - if (!PioSpinWhile([&ctx] { return pioSmIsRxEmptyX(ctx.smp); })) + value = stack.Arg1().Dereference(); + FAULT_ON_NULL(value); + + if (pioSmIsRxEmptyX(ctx.smp)) { - NANOCLR_SET_AND_LEAVE(CLR_E_TIMEOUT); + value->NumericByRef().u4 = 0; + stack.SetResult_Boolean(false); + NANOCLR_SET_AND_LEAVE(S_OK); } - stack.SetResult_U4(pioSmGetX(ctx.smp)); + value->NumericByRef().u4 = pioSmGetX(ctx.smp); + stack.SetResult_Boolean(true); NANOCLR_NOCLEANUP(); } @@ -557,7 +643,7 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P if (basePin < 0 || basePin > PIO_MAX_PIN || count < 0 || count > 32 || (basePin + count) > (PIO_MAX_PIN + 1) || basePin < gpioBase || (basePin - gpioBase + count) > 32) { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE); } pioSmSetConsecutivePindirsX(ctx.smp, static_cast(basePin), static_cast(count), output); @@ -695,7 +781,7 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P if (!(value >= 1.0f && value <= 65536.0f)) { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE); } intPart = static_cast(value); @@ -715,11 +801,11 @@ HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_P HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: Read___I4__SZARRAY_U4__I4__I4__I4(CLR_RT_StackFrame &stack) { - return PioDmaTransfer(stack, PioDmaRx); + return PioDmaTransfer(stack, PioFifoRx); } HRESULT Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: Write___I4__SZARRAY_U4__I4__I4__I4(CLR_RT_StackFrame &stack) { - return PioDmaTransfer(stack, PioDmaTx); + return PioDmaTransfer(stack, PioFifoTx); } diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_target.h b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_target.h index f16c1ea91c..90de0b7360 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_target.h +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Pico/nanoFramework_hardware_pico_native_target.h @@ -11,24 +11,6 @@ #include #include -// -// Everything the PIO binding needs on top of the ChibiOS RP low level drivers, and nothing else: -// the boilerplate that turns a CLR_RT_StackFrame into a validated state machine handle, plus the -// handful of operations the LLD does not expose yet. -// -// Each of those is marked "LLD gap" and mirrors a change proposed upstream in the -// begeistert/chibios branches enhance-pico-pio-api / enhance-pico-dma-api. When one lands the -// workaround is deleted and the call is replaced by the LLD function of the same shape. -// -// What ChibiOS already does is called, never reimplemented: the DMA abort sequence with the -// RP2040-E13 / RP2350-E5 workarounds, the state machine init sequence, the SET PINDIRS chunking, -// JMP relocation on program load. -// - -// --------------------------------------------------------------------------- -// Target constants -// --------------------------------------------------------------------------- - #if defined(RP2350) #define PIO_MAX_BLOCK 2 #define PIO_MAX_PIN 47 @@ -43,33 +25,14 @@ #define PIO_MIN_BLOCK 0 #endif -// NVIC priority requested for the PIO and DMA shared vectors. -// -// Both pioSmAlloc() and dmaChannelAlloc() apply the priority only on the first allocation a core -// makes, and ignore it afterwards: for PIO that is per block, for DMA it is global. So this is -// the effective priority only if this binding is the first PIO/DMA consumer to start. On a WiFi -// target the CYW43 bus driver claims a PIO0 state machine with priority 0 first, which is why -// PIO_MIN_BLOCK keeps block 0 out of reach of managed code. -#define NF_PICO_PIO_IRQ_PRIORITY 3 - -// Budget for a blocking single word FIFO transfer: a tight spin first, because a state machine -// that is running usually frees a FIFO slot within a few cycles, then millisecond sleeps up to -// the timeout so a stalled state machine cannot hold the CLR thread indefinitely. -#define NF_PICO_PIO_FIFO_SPIN_LIMIT 256u +#define NF_PICO_PIO_IRQ_PRIORITY 3 #define NF_PICO_PIO_FIFO_TIMEOUT_MS 1000u - -// Instructions DrainTxFifo executes before giving up. The loop only ends if the state machine -// consumes what is exec'd into it, so this bounds the case where it is stalled on something else. -#define NF_PICO_PIO_DRAIN_LIMIT 0x10000u - -// --------------------------------------------------------------------------- -// Argument validation -// --------------------------------------------------------------------------- +#define NF_PICO_PIO_DRAIN_LIMIT 0x10000u #define VALIDATE_PIO_BLOCK(block) \ if ((block) < 0 || (block) > PIO_MAX_BLOCK) \ { \ - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); \ + NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE); \ } \ if ((block) < PIO_MIN_BLOCK) \ { \ @@ -79,7 +42,7 @@ #define VALIDATE_SM(sm) \ if ((sm) < 0 || (sm) > 3) \ { \ - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); \ + NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE); \ } #define VALIDATE_NOT_DISPOSED(pThis) \ @@ -89,23 +52,9 @@ NANOCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); \ } -// --------------------------------------------------------------------------- -// Shared state -// --------------------------------------------------------------------------- - -// Handles returned by pioSmAlloc() at claim time, indexed [block][sm]. A null entry means the -// state machine is not claimed, so this doubles as the claim bookkeeping. extern const rp_pio_sm_t *g_AllocatedSMs[3][4]; - -// Aborts and releases any DMA work in flight on a state machine. Defined in the PioStateMachine -// native so NativeUnclaim can stop the transfer before the state machine handle goes away. void PioDmaReleaseSm(int block, int sm); -// --------------------------------------------------------------------------- -// State machine context -// --------------------------------------------------------------------------- - -// Everything a native method needs about the state machine it was called on. struct PioSmContext { const rp_pio_sm_t *smp; @@ -113,12 +62,7 @@ struct PioSmContext int sm; }; -// Resolves the PioBlock/sm fields of a PioStateMachine instance into a PioSmContext. -// -// Returns CLR_E_OBJECT_DISPOSED both for a disposed instance and for a state machine that is no -// longer claimed, which is what callers hit after Dispose(); every other failure is a bad field -// value and maps to CLR_E_INVALID_PARAMETER. -inline HRESULT PioGetSmContext(CLR_RT_HeapBlock *pThis, PioSmContext &ctx, bool allowDisposed = false) +inline HRESULT PioGetSmContext(CLR_RT_HeapBlock *pThis, PioSmContext &ctx, const bool allowDisposed = false) { NANOCLR_HEADER(); @@ -126,10 +70,11 @@ inline HRESULT PioGetSmContext(CLR_RT_HeapBlock *pThis, PioSmContext &ctx, bool FAULT_ON_NULL(pThis); - if (!allowDisposed && pThis[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: - FIELD___disposed] - .NumericByRef() - .u1 != 0) + if (!allowDisposed && + pThis[Library_nanoFramework_hardware_pico_native_nanoFramework_Hardware_Pico_Pio_PioStateMachine:: + FIELD___disposed] + .NumericByRef() + .u1 != 0) { NANOCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); } @@ -160,10 +105,6 @@ inline HRESULT PioGetSmContext(CLR_RT_HeapBlock *pThis, PioSmContext &ctx, bool NANOCLR_NOCLEANUP(); } -// Opens a PioStateMachine native method: rejects a disposed instance and resolves the context. -// -// The PioSmContext is declared by the caller alongside its other locals rather than here, so -// that the goto this macro can take never jumps over an initialization. #define NANOCLR_PIO_SM_PROLOGUE(ctx) \ { \ NANOCLR_CHECK_HRESULT(PioGetSmContext(stack.This(), ctx)); \ @@ -174,46 +115,15 @@ inline HRESULT PioGetSmContext(CLR_RT_HeapBlock *pThis, PioSmContext &ctx, bool NANOCLR_CHECK_HRESULT(PioGetSmContext(stack.This(), ctx, true)); \ } -// --------------------------------------------------------------------------- -// LLD gap: PIO instruction encoding -// --------------------------------------------------------------------------- -// -// pioSmExecX() takes a raw 16-bit instruction and ChibiOS offers no way to build one, so every -// consumer ends up with bare literals -- the CYW43 bus driver grew its own set in -// targets/ChibiOS/_WiFi/cyw43/cyw43_bus_pio_spi.c:116-123. -// - -// OUT NULL, 32 -- discards a whole OSR word, used to drain a TX FIFO under autopull. #define NF_PIO_INSTR_OUT_NULL_32 0x6060u -// PULL noblock -- discards a TX FIFO word when autopull is off. -// -// The PULL opcode is 0x8080: bit 7 is what distinguishes it from PUSH, which is 0x8000. This -// used to be encoded as 0x8000, so the non-autopull path of DrainTxFifo was executing PUSH -// noblock, pushing the ISR into the RX FIFO instead of discarding a TX FIFO word -- the TX FIFO -// never drained and the RX FIFO filled with garbage. #define NF_PIO_INSTR_PULL_NOBLOCK 0x8080u -// --------------------------------------------------------------------------- -// LLD gap: FIFO joining beyond the three modes ChibiOS models -// --------------------------------------------------------------------------- -// -// rp_pio_fifo_join_t only has NONE/TX/RX, so pioSmConfigSetFifoJoinX() cannot express the RP2350 -// RXF_PUTGET modes that live in SHIFTCTRL bits 14/15. The managed PioFifoJoin enum does expose -// them, so the low two bits go through the LLD builder and the high two are applied here. -// -// On the RP2040 those bits do not exist; writing them was harmless but wrong, so they are -// dropped rather than written through. -// - #if defined(RP2350) #define NF_PIO_SM_SHIFTCTRL_FJOIN_RX_GET (1u << 14) #define NF_PIO_SM_SHIFTCTRL_FJOIN_RX_PUT (1u << 15) #endif -// Applies the managed PioFifoJoin value to a configuration image. -// -// Low two bits are the plain TX/RX joins, high two bits the RP2350 put/get variants. -inline void NfPioSmConfigSetFifoJoin(rp_pio_sm_config_t *cfgp, unsigned int join) +inline void NfPioSmConfigSetFifoJoin(rp_pio_sm_config_t *cfgp, const unsigned int join) { pioSmConfigSetFifoJoinX(cfgp, static_cast(join & 3u)); @@ -231,16 +141,7 @@ inline void NfPioSmConfigSetFifoJoin(rp_pio_sm_config_t *cfgp, unsigned int join #endif } -// --------------------------------------------------------------------------- -// LLD gap: block level interrupt enables and IRQ flags -// --------------------------------------------------------------------------- -// -// The PIO_IRQ_SM(n) flags belong to the block, not to a state machine, but ChibiOS only offers -// pioSmEnableInterruptX()/pioSmDisableInterruptX(). These use the same atomic SET/CLR aliases and -// the same "enable on the current core, disable on both" convention. -// - -inline void NfPioBlockEnableInterrupt(const rp_pio_block_t *block, uint32_t mask) +inline void NfPioBlockEnableInterrupt(const rp_pio_block_t *block, const uint32_t mask) { if (SIO->CPUID == 0u) { @@ -252,37 +153,25 @@ inline void NfPioBlockEnableInterrupt(const rp_pio_block_t *block, uint32_t mask } } -inline void NfPioBlockDisableInterrupt(const rp_pio_block_t *block, uint32_t mask) +inline void NfPioBlockDisableInterrupt(const rp_pio_block_t *block, const uint32_t mask) { block->pio->CLR.IRQ0_INTE = mask; block->pio->CLR.IRQ1_INTE = mask; } -// Raises a PIO IRQ flag from the CPU side (IRQ_FORCE is write-only, one bit per flag). -inline void NfPioBlockForceIrq(const rp_pio_block_t *block, uint32_t irq) +inline void NfPioBlockForceIrq(const rp_pio_block_t *block, const uint32_t irq) { block->pio->IRQ_FORCE = 1u << irq; } -// Clears a PIO IRQ flag (the IRQ register is write-1-to-clear). -inline void NfPioBlockClearIrq(const rp_pio_block_t *block, uint32_t irq) +inline void NfPioBlockClearIrq(const rp_pio_block_t *block, const uint32_t irq) { block->pio->IRQ = 1u << irq; } -// --------------------------------------------------------------------------- -// LLD gap: routing a GPIO to a block that may have no claimed state machine -// --------------------------------------------------------------------------- -// -// FUNCSEL selects a PIO *block*, but pioGpioInitX() is keyed on a state machine handle. The -// managed InitGpio lives on PioBlock and can run before any SM is claimed, so the block variant -// is open coded here with the same glitch-free ordering pioGpioInitPadX() uses on the RP2350. -// - inline void NfPioBlockGpioInit(const rp_pio_block_t *block, uint32_t gpio) { - // same table pioSmSetPinFunctionX() uses, keyed on the block instead of a state machine - static const uint32_t funcsels[] = { + static constexpr uint32_t funcsels[] = { RP_PIO_FUNCSEL_PIO0, RP_PIO_FUNCSEL_PIO1, #if RP_HAS_PIO2 == TRUE @@ -293,7 +182,6 @@ inline void NfPioBlockGpioInit(const rp_pio_block_t *block, uint32_t gpio) const uint32_t funcsel = funcsels[block->pioidx]; #if defined(RP2350) - // reprogram the pad while still isolated, drop the latch only once FUNCSEL points at the PIO PADS_BANK0->GPIO[gpio] = RP_PIO_PAD_DEFAULT | RP_PIO_PAD_ISO; IO_BANK0->GPIO[gpio].CTRL = funcsel; PADS_BANK0->GPIO[gpio] = RP_PIO_PAD_DEFAULT; @@ -303,17 +191,6 @@ inline void NfPioBlockGpioInit(const rp_pio_block_t *block, uint32_t gpio) #endif } -// --------------------------------------------------------------------------- -// LLD gap: draining the TX FIFO -// --------------------------------------------------------------------------- -// -// The pico-sdk has pio_sm_drain_tx_fifo(); ChibiOS has nothing. Which instruction empties the -// FIFO depends on autopull, so this cannot be written correctly without reading SHIFTCTRL. -// -// Returns false if the FIFO did not drain within the spin budget, which means the state machine -// is stalled and not consuming. -// - inline bool NfPioSmDrainTxFifo(const rp_pio_sm_t *smp, unsigned int spinLimit) { const bool autopull = (smp->block->pio->SM[smp->smidx].SHIFTCTRL & PIO_SM_SHIFTCTRL_AUTOPULL) != 0u; @@ -332,14 +209,6 @@ inline bool NfPioSmDrainTxFifo(const rp_pio_sm_t *smp, unsigned int spinLimit) return true; } -// --------------------------------------------------------------------------- -// LLD gap: reading back a DMA transfer counter -// --------------------------------------------------------------------------- -// -// dmaChannelSetCounterX() exists but there is no getter, and on the RP2350 TRANS_COUNT[31:28] is -// the count MODE field, so a raw read has to be masked to get the remaining word count. -// - inline uint32_t NfDmaChannelGetCounter(const rp_dma_channel_t *dmachp) { #if defined(RP2350) From 8256fce1de27dad240667692e20f891715ceb1f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Montiel=20Cardona?= Date: Mon, 27 Jul 2026 03:28:39 -0600 Subject: [PATCH 58/58] Remove the changes from hardware.Pico to debug --- CMake/Modules/FindnanoFramework.Hardware.Pico.cmake | 9 --------- 1 file changed, 9 deletions(-) diff --git a/CMake/Modules/FindnanoFramework.Hardware.Pico.cmake b/CMake/Modules/FindnanoFramework.Hardware.Pico.cmake index 14171c00c0..a7d807a4b3 100644 --- a/CMake/Modules/FindnanoFramework.Hardware.Pico.cmake +++ b/CMake/Modules/FindnanoFramework.Hardware.Pico.cmake @@ -38,15 +38,6 @@ foreach(SRC_FILE ${nanoFramework.Hardware.Pico_SRCS}) list(APPEND nanoFramework.Hardware.Pico_SOURCES ${nanoFramework.Hardware.Pico_SRC_FILE}) - # Debug-only: compile every native source of the Pico binding at -O0 so gdb can inspect - # locals/arguments across the whole binding. The rest of the firmware stays at -Og (see - # nf_set_optimization_options), which otherwise makes gdb report "value has been optimized - # out" for locals in these files. Scoped to just this folder (Option C) to keep the rest of - # the image at -Og and avoid overflowing flash. See docs/CLION_GDB.md §8. - set_source_files_properties( - ${nanoFramework.Hardware.Pico_SRC_FILE} - PROPERTIES COMPILE_OPTIONS "$<$:-O0>") - endforeach()