diff --git a/.devcontainer/Dockerfile.All b/.devcontainer/Dockerfile.All index c16cfff273..7908e25567 100644 --- a/.devcontainer/Dockerfile.All +++ b/.devcontainer/Dockerfile.All @@ -1 +1 @@ -FROM ghcr.io/nanoframework/dev-container-all:v2.29 +FROM ghcr.io/nanoframework/dev-container-all:v2.37 diff --git a/.devcontainer/Dockerfile.AzureRTOS b/.devcontainer/Dockerfile.AzureRTOS index 1eafa89cae..6dd56b668b 100644 --- a/.devcontainer/Dockerfile.AzureRTOS +++ b/.devcontainer/Dockerfile.AzureRTOS @@ -1 +1 @@ -FROM ghcr.io/nanoframework/dev-container-azure-rtos:v1.16 +FROM ghcr.io/nanoframework/dev-container-azure-rtos:v1.21 diff --git a/.devcontainer/Dockerfile.ChibiOS b/.devcontainer/Dockerfile.ChibiOS index 91d3f34f0f..cdda06df72 100644 --- a/.devcontainer/Dockerfile.ChibiOS +++ b/.devcontainer/Dockerfile.ChibiOS @@ -1 +1 @@ -FROM ghcr.io/nanoframework/dev-container-chibios:v1.16 +FROM ghcr.io/nanoframework/dev-container-chibios:v1.21 diff --git a/.devcontainer/Dockerfile.ESP32 b/.devcontainer/Dockerfile.ESP32 index 527836b2c3..5e651f365b 100644 --- a/.devcontainer/Dockerfile.ESP32 +++ b/.devcontainer/Dockerfile.ESP32 @@ -1 +1 @@ -FROM ghcr.io/nanoframework/dev-container-esp32:v2.24 +FROM ghcr.io/nanoframework/dev-container-esp32:v2.26 diff --git a/.devcontainer/Dockerfile.TI b/.devcontainer/Dockerfile.TI index 851d85f855..468acd6491 100644 --- a/.devcontainer/Dockerfile.TI +++ b/.devcontainer/Dockerfile.TI @@ -1 +1 @@ -FROM ghcr.io/nanoframework/dev-container-ti:v1.16 +FROM ghcr.io/nanoframework/dev-container-ti:v1.18 diff --git a/.devcontainer/README.md b/.devcontainer/README.md index 723c141096..92a186a354 100644 --- a/.devcontainer/README.md +++ b/.devcontainer/README.md @@ -22,3 +22,11 @@ To choose the dev container you want to use, adjust `devcontainer.json` and chan * `./sources/Dockerfile.ChibiOS` to build the container image from the source with all the elements to build ChibiOS based devices * `./sources/Dockerfile.ESP32` to build the container image from the source with all the elements to build ESP32 based devices * `./sources/Dockerfile.TI` to build the container image from the source with all the elements to build TI SimpleLink based devices + + +## Building and releasing Docker images in a fork + +Add a "repository variable" called `PUBLISH_DOCKER_IMAGE` with the value `true` in your forked repository +See: https://docs.github.com/en/actions/learn-github-actions/variables#creating-configuration-variables-for-a-repository for further help. + +**Note:** by default, the build and publish of the devcontainer docker images will still only happen when the docker source files change and are "pushed" to the `main` branch. diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 08996113d2..8b3b1617e4 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,42 +1,49 @@ { "name": "nanoFramework", - // Adjust this file to chose the platform you want using the prebuild containers + // Adjust this file to choose the platform you want using the prebuild containers: // - Dockerfile.All = you can build anything but it's a very large container // - Dockerfile.AzureRTOS = for AzureRTOS targets // - Dockerfile.ChibiOS = for ChibiOS based targets (ex: STM32, Netduino, Orgpal) // - Dockerfile.ESP32 = for ESP32 targets // - Dockerfile.TI = for TI targets - // If you prefer, you can use the source files and adjust them they are located, with the same names in ./sources. This will alow you to customize them and add anything you may need on top. - "dockerFile": "Dockerfile.ALL", + // If you prefer, you can use the source files and adjust them where they are located, + // To do this, prefix 'sources'. e.g. 'sources/Dockerfile.All'. + // This will allow you to customize and build the container source and add anything you may need on top. + "dockerFile": "Dockerfile.All", "context": ".", "mounts": [ + // Bind the Unix socket the Docker daemon listens on by default "source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind", - // Mount .azure folder for seamless az cli auth - "source=${env:HOME}${env:USERPROFILE}/.azure,target=/home/vscode/.azure,type=bind", // Keep command history "source=nano-bashhistory,target=/home/vscode/commandhistory,type=volume", + // OPTIONAL: Mount .azure folder for seamless az cli auth + // "source=${env:HOME}${env:USERPROFILE}/.azure,target=/home/vscode/.azure,type=bind" ], - // Set *default* container specific settings.json values on container create. - "settings": { - "cmake.preferredGenerators": [ - "Ninja" - ], - "cmake.generator": "Ninja", - "cmake.autoRestartBuild" : true, - "cmake.configureSettings": { - "CMAKE_MAKE_PROGRAM":"/usr/bin/ninja" - }, - "cmake.configureOnOpen": false - }, - // Add the IDs of extensions you want installed when the container is created. - "extensions": [ - "ms-vsliveshare.vsliveshare-pack", - "streetsidesoftware.code-spell-checker", - "twxs.cmake", - "ms-vscode.cmake-tools", - "xaver.clang-format" - ], - // You can pull all the repos with the latest changes, this is only valid if you are using the ./sources/Dockerfile.all containers + // Set the *default* container specific settings.json values on container create. + "customizations": { + "vscode": { + "settings": { + "cmake.preferredGenerators": [ + "Ninja" + ], + "cmake.generator": "Ninja", + "cmake.autoRestartBuild" : true, + "cmake.configureSettings": { + "CMAKE_MAKE_PROGRAM":"/usr/bin/ninja" + }, + "cmake.configureOnOpen": false + }, + // Add the IDs of extensions you want installed when the container is created. + "extensions": [ + "ms-vsliveshare.vsliveshare-pack", + "streetsidesoftware.code-spell-checker", + "twxs.cmake", + "ms-vscode.cmake-tools", + "xaver.clang-format" + ] + } + } + // You can pull all the repos with the latest changes, this is only valid if you are using the ./sources/Dockerfile.All containers // "postAttachCommand": "/usr/local/git-pull-repos.sh" // Use 'forwardPorts' to make a list of ports inside the container available locally. // "forwardPorts": [], @@ -44,4 +51,4 @@ // "postCreateCommand": "terraform --version", // Uncomment to connect as a non-root user. See https: //aka.ms/vscode-remote/containers/non-root. // ,"remoteUser": "vscode" -} \ No newline at end of file +} diff --git a/.devcontainer/scripts/git-pull-repos.sh b/.devcontainer/scripts/git-pull-repos.sh index 7097cab72d..e178973bfe 100644 --- a/.devcontainer/scripts/git-pull-repos.sh +++ b/.devcontainer/scripts/git-pull-repos.sh @@ -11,11 +11,11 @@ cd /sources/AzureRTOS git pull cd / rm -rf /sources/ChibiOs -git svn clone https://svn.osdn.net/svnroot/chibios/branches/stable_21.11.x -rHEAD /sources/ChibiOs +git svn clone http://svn.code.sf.net/p/chibios/code/branches/stable_21.11.x -rHEAD /sources/ChibiOs cd /sources/ChibiOs-Contrib git pull origin nanoframework cd /sources/mbedtls -git pull origin mbedtls-2.28.1 +git pull origin mbedtls-2.28.2 cd /sources/fatfs git pull origin R0.14b cd /sources/FreeRTOS diff --git a/.devcontainer/sources/Dockerfile.All b/.devcontainer/sources/Dockerfile.All index 78276ed359..c0136f9411 100644 --- a/.devcontainer/sources/Dockerfile.All +++ b/.devcontainer/sources/Dockerfile.All @@ -1,4 +1,4 @@ -FROM ghcr.io/linuxcontainers/debian-slim:latest AS downloader +FROM ubuntu:latest AS downloader RUN apt-get update \ && apt-get -y install --no-install-recommends apt-utils \ && apt-get install -y \ @@ -7,20 +7,20 @@ RUN apt-get update \ unzip \ wget -ARG GCC_URI=https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu/11.3.rel1/binrel/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi.tar.xz +ARG GCC_URI=https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu/12.3.rel1/binrel/arm-gnu-toolchain-12.3.rel1-x86_64-arm-none-eabi.tar.xz RUN mkdir -p /tmp/dc-downloads /tmp/dc-extracted/gcc \ && curl -o /tmp/dc-downloads/gcc-arm.tar.xz $GCC_URI \ && xz -d /tmp/dc-downloads/gcc-arm.tar.xz \ && tar -xvf /tmp/dc-downloads/gcc-arm.tar -C /tmp/dc-extracted/gcc --strip-components 1 \ && rm -rf /tmp/dc-extracted/gcc/share/doc/ /tmp/dc-extracted/gcc/share/gcc-arm-none-eabi/samples/ -# This is TI XDC tools for linux. Cheack all versions here: http://software-dl.ti.com/dsps/dsps_public_sw/sdo_sb/targetcontent/rtsc/index.html -ARG TI_TOOL_URL=http://software-dl.ti.com/dsps/dsps_public_sw/sdo_sb/targetcontent/rtsc/3_62_00_08/exports/xdccore/xdctools_3_62_00_08_core_linux.zip +# This is TI XDC tools for linux. Cheack all versions here: https://software-dl.ti.com/dsps/dsps_public_sw/sdo_sb/targetcontent/rtsc/index.html +ARG TI_TOOL_URL=https://software-dl.ti.com/dsps/dsps_public_sw/sdo_sb/targetcontent/rtsc/3_62_00_08/exports/xdccore/xdctools_3_62_00_08_core_linux.zip RUN mkdir -p /tmp/dc-extracted/titools \ && curl -o /tmp/dc-downloads/titools.zip $TI_TOOL_URL -L \ && unzip -d /tmp/dc-extracted/titools /tmp/dc-downloads/titools.zip -ARG CMAKE_SCRIPT=https://cmake.org/files/v3.24/cmake-3.24.0-linux-x86_64.sh +ARG CMAKE_SCRIPT=https://github.com/Kitware/CMake/releases/download/v3.27.6/cmake-3.27.6-linux-x86_64.sh RUN wget $CMAKE_SCRIPT \ -q -O /tmp/cmake-install.sh \ && chmod u+x /tmp/cmake-install.sh \ @@ -28,7 +28,7 @@ RUN wget $CMAKE_SCRIPT \ && /tmp/cmake-install.sh --skip-license --prefix=/tmp/dc-extracted/cmake \ && rm /tmp/cmake-install.sh -FROM ghcr.io/linuxcontainers/debian-slim:latest AS devcontainer +FROM ubuntu:latest AS devcontainer # Avoid warnings by switching to noninteractive ENV DEBIAN_FRONTEND=noninteractive @@ -50,11 +50,16 @@ RUN apt-get update \ curl \ ninja-build \ srecord \ - python3 \ - python3-pip \ nodejs \ libffi-dev +# Set Python 10 as the default version +RUN apt-get install -y software-properties-common \ + && add-apt-repository ppa:deadsnakes/ppa \ + && apt-get update \ + && apt-get install -y python3.10 \ + python3-pip + # Create needed directories RUN mkdir -p /usr/local/bin/gcc \ && mkdir -p /usr/local/bin/titools @@ -64,12 +69,12 @@ RUN git clone --branch nf-build https://github.com/nanoframework/STM32CubeL4.git && git clone --branch nf-build https://github.com/nanoframework/STM32CubeF7.git --depth 1 ./sources/STM32CubeF7 \ && git clone --branch nf-build https://github.com/nanoframework/STM32CubeF4.git --depth 1 ./sources/STM32CubeF4 \ && git clone --branch nf-build https://github.com/nanoframework/STM32CubeH7.git --depth 1 ./sources/STM32CubeH7 \ - && git clone --branch v6.1.12_rel --recursive https://github.com/azure-rtos/threadx.git --depth 1 ./sources/AzureRTOS \ - && git clone --branch v6.1.12_rel --recursive https://github.com/azure-rtos/netxduo.git --depth 1 ./sources/NextDuo \ - && git svn clone https://svn.osdn.net/svnroot/chibios/branches/stable_21.11.x -rHEAD ./sources/ChibiOs \ + && git clone --branch v6.2.0_rel --recursive https://github.com/azure-rtos/threadx.git --depth 1 ./sources/AzureRTOS \ + && git clone --branch v6.2.0_rel --recursive https://github.com/azure-rtos/netxduo.git --depth 1 ./sources/NetxDuo \ + && git svn clone http://svn.code.sf.net/p/chibios/code/branches/stable_21.11.x -rHEAD ./sources/ChibiOs \ && git clone --branch nanoframework https://github.com/nanoframework/ChibiOS-Contrib.git --depth 1 ./sources/ChibiOs-Contrib # Clone mbedtls and fatfs -RUN git clone --branch mbedtls-2.28.1 https://github.com/ARMmbed/mbedtls.git --depth 1 ./sources/mbedtls \ +RUN git clone --branch mbedtls-2.28.2 https://github.com/ARMmbed/mbedtls.git --depth 1 ./sources/mbedtls \ && git clone --branch R0.14b https://github.com/abbrev/fatfs.git --depth 1 ./sources/fatfs # Clone FreeRTOS and what is needed for ESP32 RUN git clone --branch V10.4.1-kernel-only https://github.com/FreeRTOS/FreeRTOS-Kernel.git --depth 1 ./sources/FreeRTOS \ @@ -82,7 +87,7 @@ RUN git clone --branch STABLE-2_0_3_RELEASE https://git.savannah.nongnu.org/git/ ENV GIT_SSL_NO_VERIFY=0 # Clone ESP-IDF -RUN git clone --branch v4.4.3 https://github.com/espressif/esp-idf --depth 1 --recursive ./sources/esp-idf +RUN git clone --branch v4.4.5 https://github.com/espressif/esp-idf --depth 1 --recursive ./sources/esp-idf # Clone what is needed for TI RUN git clone --branch 4.10.00.07 https://github.com/nanoframework/SimpleLink_CC32xx_SDK.git --depth 1 ./sources/SimpleLinkCC32 \ @@ -106,7 +111,7 @@ ENV PATH=/usr/bin/cmake/bin:${PATH} # Putting hex2dfu in the container ENV HEX2DFU_PATH=/usr/local/bin/hex2dfu -ARG HEX2DFU=https://github.com/nanoframework/hex2dfu/releases/download/v2.0.9/hex2dfu +ARG HEX2DFU=https://github.com/nanoframework/hex2dfu/releases/download/v3.0.2/hex2dfu RUN mkdir -p $HEX2DFU_PATH \ && curl -o $HEX2DFU_PATH/hex2dfu $HEX2DFU -L \ && chmod +x $HEX2DFU_PATH/hex2dfu @@ -118,10 +123,11 @@ RUN ln -fs /usr/bin/python3 /usr/bin/python \ # Install ESP-IDF ENV IDF_PATH=/sources/esp-idf ENV ESP_PATCH_VER=esp-2021r2-patch5-8.4.0 -RUN python -m pip install -r $IDF_PATH/requirements.txt +# This is now taking care in the following line +# RUN python -m pip install -r $IDF_PATH/requirements.txt RUN $IDF_PATH/install.sh -ENV PATH=$PATH:\ +ENV PATH=/root/.espressif/python_env/idf4.4_py3.10_env/bin:$PATH:\ $IDF_PATH/components/esptool_py/esptool:\ $IDF_PATH/components/espcoredump:\ $IDF_PATH/components/partition_table/:\ @@ -129,6 +135,7 @@ $IDF_PATH/tools/:\ $IDF_PATH/components/app_update:\ /root/.espressif/tools/xtensa-esp32-elf/$ESP_PATCH_VER/xtensa-esp32-elf/bin:\ /root/.espressif/tools/xtensa-esp32s2-elf/$ESP_PATCH_VER/xtensa-esp32s2-elf/bin:\ +/root/.espressif/tools/xtensa-esp32s3-elf/$ESP_PATCH_VER/xtensa-esp32s3-elf/bin:\ /root/.espressif/tools/riscv32-esp-elf/$ESP_PATCH_VER/riscv32-esp-elf/bin # Clean up downloaded files diff --git a/.devcontainer/sources/Dockerfile.AzureRTOS b/.devcontainer/sources/Dockerfile.AzureRTOS index f4b2aed7e6..d96a99a5aa 100644 --- a/.devcontainer/sources/Dockerfile.AzureRTOS +++ b/.devcontainer/sources/Dockerfile.AzureRTOS @@ -1,4 +1,4 @@ -FROM ghcr.io/linuxcontainers/debian-slim:latest AS downloader +FROM ubuntu:latest AS downloader RUN apt-get update \ && apt-get -y install --no-install-recommends apt-utils \ && apt-get install -y \ @@ -7,14 +7,14 @@ RUN apt-get update \ unzip \ wget -ARG GCC_URI=https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu/11.3.rel1/binrel/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi.tar.xz +ARG GCC_URI=https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu/12.3.rel1/binrel/arm-gnu-toolchain-12.3.rel1-x86_64-arm-none-eabi.tar.xz RUN mkdir -p /tmp/dc-downloads /tmp/dc-extracted/gcc \ && curl -o /tmp/dc-downloads/gcc-arm.tar.xz $GCC_URI \ && xz -d /tmp/dc-downloads/gcc-arm.tar.xz \ && tar -xvf /tmp/dc-downloads/gcc-arm.tar -C /tmp/dc-extracted/gcc --strip-components 1 \ && rm -rf /tmp/dc-extracted/gcc/share/doc/ /tmp/dc-extracted/gcc/share/gcc-arm-none-eabi/samples/ -ARG CMAKE_SCRIPT=https://cmake.org/files/v3.24/cmake-3.24.0-linux-x86_64.sh +ARG CMAKE_SCRIPT=https://github.com/Kitware/CMake/releases/download/v3.27.6/cmake-3.27.6-linux-x86_64.sh RUN wget $CMAKE_SCRIPT \ -q -O /tmp/cmake-install.sh \ && chmod u+x /tmp/cmake-install.sh \ @@ -22,7 +22,7 @@ RUN wget $CMAKE_SCRIPT \ && /tmp/cmake-install.sh --skip-license --prefix=/tmp/dc-extracted/cmake \ && rm /tmp/cmake-install.sh -FROM ghcr.io/linuxcontainers/debian-slim:latest AS devcontainer +FROM ubuntu:latest AS devcontainer # Avoid warnings by switching to noninteractive ENV DEBIAN_FRONTEND=noninteractive @@ -45,19 +45,19 @@ RUN apt-get update \ srecord # Create needed directories -RUN mkdir -p /usr/local/bin/gcc \ - && mkdir -p /usr/local/bin/xtensa +RUN mkdir -p /usr/local/bin/gcc # Clone repos for STM32 including AzureRTOS -RUN git clone --branch nf-build https://github.com/nanoframework/STM32CubeL4.git --depth 1 ./sources/STM32CubeL4 \ +RUN git svn clone http://svn.code.sf.net/p/chibios/code/branches/stable_21.11.x -rHEAD ./sources/ChibiOs \ + && git clone --branch nf-build https://github.com/nanoframework/STM32CubeL4.git --depth 1 ./sources/STM32CubeL4 \ && git clone --branch nf-build https://github.com/nanoframework/STM32CubeF7.git --depth 1 ./sources/STM32CubeF7 \ && git clone --branch nf-build https://github.com/nanoframework/STM32CubeF4.git --depth 1 ./sources/STM32CubeF4 \ && git clone --branch nf-build https://github.com/nanoframework/STM32CubeH7.git --depth 1 ./sources/STM32CubeH7 \ - && git svn clone https://svn.osdn.net/svnroot/chibios/branches/stable_21.11.x -rHEAD ./sources/ChibiOs \ - && git clone --branch v6.1.12_rel --recursive https://github.com/azure-rtos/threadx.git --depth 1 ./sources/AzureRTOS \ - && git clone --branch v6.1.12_rel --recursive https://github.com/azure-rtos/netxduo.git --depth 1 ./sources/NextDuo + && git clone --branch v6.2.0_rel --recursive https://github.com/azure-rtos/threadx.git --depth 1 ./sources/AzureRTOS \ + && git clone --branch v6.2.0_rel --recursive https://github.com/azure-rtos/netxduo.git --depth 1 ./sources/NetxDuo + # Clone mbedtls and fatfs -RUN git clone --branch mbedtls-2.28.1 https://github.com/ARMmbed/mbedtls.git --depth 1 ./sources/mbedtls \ +RUN git clone --branch mbedtls-2.28.2 https://github.com/ARMmbed/mbedtls.git --depth 1 ./sources/mbedtls \ && git clone --branch R0.14b https://github.com/abbrev/fatfs.git --depth 1 ./sources/fatfs \ && git clone --branch nf-build https://github.com/nanoframework/spiffs.git --depth 1 ./sources/spiffs @@ -74,7 +74,7 @@ ENV PATH=/usr/bin/cmake/bin:${PATH} # Putting hex2dfu in the container ENV HEX2DFU_PATH=/usr/local/bin/hex2dfu -ARG HEX2DFU=https://github.com/nanoframework/hex2dfu/releases/download/v2.0.9/hex2dfu +ARG HEX2DFU=https://github.com/nanoframework/hex2dfu/releases/download/v3.0.2/hex2dfu RUN mkdir -p $HEX2DFU_PATH \ && curl -o $HEX2DFU_PATH/hex2dfu $HEX2DFU -L \ && chmod +x $HEX2DFU_PATH/hex2dfu diff --git a/.devcontainer/sources/Dockerfile.ChibiOS b/.devcontainer/sources/Dockerfile.ChibiOS index 73f63d9ecc..fd17cd0bed 100644 --- a/.devcontainer/sources/Dockerfile.ChibiOS +++ b/.devcontainer/sources/Dockerfile.ChibiOS @@ -7,14 +7,14 @@ RUN apt-get update \ unzip \ wget -ARG GCC_URI=https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu/11.3.rel1/binrel/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi.tar.xz +ARG GCC_URI=https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu/12.3.rel1/binrel/arm-gnu-toolchain-12.3.rel1-x86_64-arm-none-eabi.tar.xz RUN mkdir -p /tmp/dc-downloads /tmp/dc-extracted/gcc \ && curl -o /tmp/dc-downloads/gcc-arm.tar.xz $GCC_URI \ && xz -d /tmp/dc-downloads/gcc-arm.tar.xz \ && tar -xvf /tmp/dc-downloads/gcc-arm.tar -C /tmp/dc-extracted/gcc --strip-components 1 \ && rm -rf /tmp/dc-extracted/gcc/share/doc/ /tmp/dc-extracted/gcc/share/gcc-arm-none-eabi/samples/ -ARG CMAKE_SCRIPT=https://cmake.org/files/v3.24/cmake-3.24.0-linux-x86_64.sh +ARG CMAKE_SCRIPT=https://github.com/Kitware/CMake/releases/download/v3.27.6/cmake-3.27.6-linux-x86_64.sh RUN wget $CMAKE_SCRIPT \ -q -O /tmp/cmake-install.sh \ && chmod u+x /tmp/cmake-install.sh \ @@ -54,10 +54,10 @@ RUN git clone --branch nf-build https://github.com/nanoframework/STM32CubeL4.git && git clone --branch nf-build https://github.com/nanoframework/STM32CubeF7.git --depth 1 ./sources/STM32CubeF7 \ && git clone --branch nf-build https://github.com/nanoframework/STM32CubeF4.git --depth 1 ./sources/STM32CubeF4 \ && git clone --branch nf-build https://github.com/nanoframework/STM32CubeH7.git --depth 1 ./sources/STM32CubeH7 \ - && git svn clone https://svn.osdn.net/svnroot/chibios/branches/stable_21.11.x -rHEAD ./sources/ChibiOs \ + && git svn clone https://svn.code.sf.net/p/chibios/code/branches/stable_21.11.x -rHEAD ./sources/ChibiOs \ && git clone --branch nanoframework https://github.com/nanoframework/ChibiOS-Contrib.git --depth 1 ./sources/ChibiOs-Contrib # Clone mbedtls and fatfs -RUN git clone --branch mbedtls-2.28.1 https://github.com/ARMmbed/mbedtls.git --depth 1 ./sources/mbedtls \ +RUN git clone --branch mbedtls-2.28.2 https://github.com/ARMmbed/mbedtls.git --depth 1 ./sources/mbedtls \ && git clone --branch R0.14b https://github.com/abbrev/fatfs.git --depth 1 ./sources/fatfs \ && git clone --branch nf-build https://github.com/nanoframework/spiffs.git --depth 1 ./sources/spiffs @@ -74,7 +74,7 @@ ENV PATH=/usr/bin/cmake/bin:${PATH} # Putting hex2dfu in the container ENV HEX2DFU_PATH=/usr/local/bin/hex2dfu -ARG HEX2DFU=https://github.com/nanoframework/hex2dfu/releases/download/v2.0.9/hex2dfu +ARG HEX2DFU=https://github.com/nanoframework/hex2dfu/releases/download/v3.0.2/hex2dfu RUN mkdir -p $HEX2DFU_PATH \ && curl -o $HEX2DFU_PATH/hex2dfu $HEX2DFU -L \ && chmod +x $HEX2DFU_PATH/hex2dfu diff --git a/.devcontainer/sources/Dockerfile.ESP32 b/.devcontainer/sources/Dockerfile.ESP32 index 631cceb451..08817007b8 100644 --- a/.devcontainer/sources/Dockerfile.ESP32 +++ b/.devcontainer/sources/Dockerfile.ESP32 @@ -1,4 +1,4 @@ -FROM ghcr.io/linuxcontainers/debian-slim:latest AS downloader +FROM ubuntu:latest AS downloader RUN apt-get update \ && apt-get -y install --no-install-recommends apt-utils \ && apt-get install -y \ @@ -9,7 +9,7 @@ RUN apt-get update \ RUN mkdir -p /tmp/dc-downloads /tmp/dc-extracted/gcc -ARG CMAKE_SCRIPT=https://cmake.org/files/v3.24/cmake-3.24.0-linux-x86_64.sh +ARG CMAKE_SCRIPT=https://github.com/Kitware/CMake/releases/download/v3.27.6/cmake-3.27.6-linux-x86_64.sh RUN wget $CMAKE_SCRIPT \ -q -O /tmp/cmake-install.sh \ && chmod u+x /tmp/cmake-install.sh \ @@ -17,7 +17,7 @@ RUN wget $CMAKE_SCRIPT \ && /tmp/cmake-install.sh --skip-license --prefix=/tmp/dc-extracted/cmake \ && rm /tmp/cmake-install.sh -FROM ghcr.io/linuxcontainers/debian-slim:latest AS devcontainer +FROM ubuntu:latest AS devcontainer # Avoid warnings by switching to noninteractive ENV DEBIAN_FRONTEND=noninteractive @@ -37,20 +37,24 @@ RUN apt-get update \ curl \ ninja-build \ srecord \ - python3 \ - python3-pip \ nodejs \ libffi-dev +# Set Python 10 as the default version +RUN apt-get install -y software-properties-common \ + && add-apt-repository ppa:deadsnakes/ppa \ + && apt-get update \ + && apt-get install -y python3.10 \ + python3-pip + # Create needed directories RUN mkdir -p /usr/local/bin/gcc -# Clone mbedtls and fatfs -RUN git clone --branch mbedtls-2.28.1 https://github.com/ARMmbed/mbedtls.git --depth 1 ./sources/mbedtls \ - && git clone --branch R0.14b https://github.com/abbrev/fatfs.git --depth 1 ./sources/fatfs +# Clone fatfs +RUN git clone --branch R0.14b https://github.com/abbrev/fatfs.git --depth 1 ./sources/fatfs # Clone ESP-IDF -RUN git clone --branch v4.4.3 https://github.com/espressif/esp-idf --depth 1 --recursive ./sources/esp-idf +RUN git clone --branch v4.4.5 https://github.com/espressif/esp-idf --depth 1 --recursive ./sources/esp-idf # Creating static link python for pyhton3 RUN ln -fs /usr/bin/python3 /usr/bin/python \ @@ -64,10 +68,11 @@ ENV PATH=/usr/bin/cmake/bin:${PATH} # Install ESP-IDF ENV IDF_PATH=/sources/esp-idf ENV ESP_PATCH_VER=esp-2021r2-patch5-8.4.0 -RUN python -m pip install -r $IDF_PATH/requirements.txt +# This is now taking care in the following line +# RUN python -m pip install -r $IDF_PATH/requirements.txt RUN $IDF_PATH/install.sh -ENV PATH=$PATH:\ +ENV PATH=/root/.espressif/python_env/idf4.4_py3.10_env/bin:$PATH:\ $IDF_PATH/components/esptool_py/esptool:\ $IDF_PATH/components/espcoredump:\ $IDF_PATH/components/partition_table/:\ @@ -75,6 +80,7 @@ $IDF_PATH/tools/:\ $IDF_PATH/components/app_update:\ /root/.espressif/tools/xtensa-esp32-elf/$ESP_PATCH_VER/xtensa-esp32-elf/bin:\ /root/.espressif/tools/xtensa-esp32s2-elf/$ESP_PATCH_VER/xtensa-esp32s2-elf/bin:\ +/root/.espressif/tools/xtensa-esp32s3-elf/$ESP_PATCH_VER/xtensa-esp32s3-elf/bin:\ /root/.espressif/tools/riscv32-esp-elf/$ESP_PATCH_VER/riscv32-esp-elf/bin # Clean up downloaded files diff --git a/.devcontainer/sources/Dockerfile.TI b/.devcontainer/sources/Dockerfile.TI index 66a2315462..c4942ce8b9 100644 --- a/.devcontainer/sources/Dockerfile.TI +++ b/.devcontainer/sources/Dockerfile.TI @@ -7,20 +7,20 @@ RUN apt-get update \ unzip \ wget -ARG GCC_URI=https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu/11.3.rel1/binrel/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi.tar.xz +ARG GCC_URI=https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu/12.3.rel1/binrel/arm-gnu-toolchain-12.3.rel1-x86_64-arm-none-eabi.tar.xz RUN mkdir -p /tmp/dc-downloads /tmp/dc-extracted/gcc \ && curl -o /tmp/dc-downloads/gcc-arm.tar.xz $GCC_URI \ && xz -d /tmp/dc-downloads/gcc-arm.tar.xz \ && tar -xvf /tmp/dc-downloads/gcc-arm.tar -C /tmp/dc-extracted/gcc --strip-components 1 \ && rm -rf /tmp/dc-extracted/gcc/share/doc/ /tmp/dc-extracted/gcc/share/gcc-arm-none-eabi/samples/ -# This is TI XDC tools for linux. Cheack all versions here: http://software-dl.ti.com/dsps/dsps_public_sw/sdo_sb/targetcontent/rtsc/index.html -ARG TI_TOOL_URL=http://software-dl.ti.com/dsps/dsps_public_sw/sdo_sb/targetcontent/rtsc/3_62_00_08/exports/xdccore/xdctools_3_62_00_08_core_linux.zip +# This is TI XDC tools for linux. Cheack all versions here: https://software-dl.ti.com/dsps/dsps_public_sw/sdo_sb/targetcontent/rtsc/index.html +ARG TI_TOOL_URL=https://software-dl.ti.com/dsps/dsps_public_sw/sdo_sb/targetcontent/rtsc/3_62_00_08/exports/xdccore/xdctools_3_62_00_08_core_linux.zip RUN mkdir -p /tmp/dc-extracted/titools \ && curl -o /tmp/dc-downloads/titools.zip $TI_TOOL_URL -L \ && unzip -d /tmp/dc-extracted/titools /tmp/dc-downloads/titools.zip -ARG CMAKE_SCRIPT=https://cmake.org/files/v3.24/cmake-3.24.0-linux-x86_64.sh +ARG CMAKE_SCRIPT=https://github.com/Kitware/CMake/releases/download/v3.27.6/cmake-3.27.6-linux-x86_64.sh RUN wget $CMAKE_SCRIPT \ -q -O /tmp/cmake-install.sh \ && chmod u+x /tmp/cmake-install.sh \ diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000..4b7caa2787 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +* text=auto eol=crlf +*.{sh,[sS][hH]} text eol=lf diff --git a/.github/workflows/devcontainer-all.yaml b/.github/workflows/devcontainer-all.yaml index cc21270ca8..18ed7639da 100644 --- a/.github/workflows/devcontainer-all.yaml +++ b/.github/workflows/devcontainer-all.yaml @@ -18,11 +18,12 @@ on: jobs: build: + if: ${{ vars.PUBLISH_DOCKER_IMAGE == 'true' }} runs-on: ubuntu-latest steps: - name: Checkout Repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Get container version run: | @@ -36,14 +37,14 @@ jobs: uses: docker/setup-buildx-action@v2 - name: Login to GitHub Container Registry - uses: docker/login-action@v1 + uses: docker/login-action@v2 with: registry: ghcr.io username: ${{ github.repository_owner }} password: ${{ secrets.CONTAINER_BUILD_TOKEN }} - name: Build and Push Docker Image - uses: docker/build-push-action@v3 + uses: docker/build-push-action@v4 with: file: ${{ env.GCR_FILE }} push: true # Will only build if this is not here diff --git a/.github/workflows/devcontainer-azurertos.yaml b/.github/workflows/devcontainer-azurertos.yaml index caa5623951..98990bd989 100644 --- a/.github/workflows/devcontainer-azurertos.yaml +++ b/.github/workflows/devcontainer-azurertos.yaml @@ -18,11 +18,12 @@ on: jobs: build: + if: ${{ vars.PUBLISH_DOCKER_IMAGE == 'true' }} runs-on: ubuntu-latest steps: - name: Checkout Repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Get container version run: | @@ -36,14 +37,14 @@ jobs: uses: docker/setup-buildx-action@v2 - name: Login to GitHub Container Registry - uses: docker/login-action@v1 + uses: docker/login-action@v2 with: registry: ghcr.io username: ${{ github.repository_owner }} password: ${{ secrets.CONTAINER_BUILD_TOKEN }} - name: Build and Push Docker Image - uses: docker/build-push-action@v3 + uses: docker/build-push-action@v4 with: file: ${{ env.GCR_FILE }} push: true # Will only build if this is not here diff --git a/.github/workflows/devcontainer-chibios.yaml b/.github/workflows/devcontainer-chibios.yaml index 243c2f6cd7..ac6058bf74 100644 --- a/.github/workflows/devcontainer-chibios.yaml +++ b/.github/workflows/devcontainer-chibios.yaml @@ -18,11 +18,12 @@ on: jobs: build: + if: ${{ vars.PUBLISH_DOCKER_IMAGE == 'true' }} runs-on: ubuntu-latest steps: - name: Checkout Repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Get container version run: | @@ -36,14 +37,14 @@ jobs: uses: docker/setup-buildx-action@v2 - name: Login to GitHub Container Registry - uses: docker/login-action@v1 + uses: docker/login-action@v2 with: registry: ghcr.io username: ${{ github.repository_owner }} password: ${{ secrets.CONTAINER_BUILD_TOKEN }} - name: Build and Push Docker Image - uses: docker/build-push-action@v3 + uses: docker/build-push-action@v4 with: file: ${{ env.GCR_FILE }} push: true # Will only build if this is not here diff --git a/.github/workflows/devcontainer-esp32.yml b/.github/workflows/devcontainer-esp32.yml index 9e5fbcf357..beec2de4dd 100644 --- a/.github/workflows/devcontainer-esp32.yml +++ b/.github/workflows/devcontainer-esp32.yml @@ -18,11 +18,12 @@ on: jobs: build: + if: ${{ vars.PUBLISH_DOCKER_IMAGE == 'true' }} runs-on: ubuntu-latest steps: - name: Checkout Repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Get container version run: | @@ -36,14 +37,14 @@ jobs: uses: docker/setup-buildx-action@v2 - name: Login to GitHub Container Registry - uses: docker/login-action@v1 + uses: docker/login-action@v2 with: registry: ghcr.io username: ${{ github.repository_owner }} password: ${{ secrets.CONTAINER_BUILD_TOKEN }} - name: Build and Push Docker Image - uses: docker/build-push-action@v3 + uses: docker/build-push-action@v4 with: file: ${{ env.GCR_FILE }} push: true # Will only build if this is not here diff --git a/.github/workflows/devcontainer-ti.yaml b/.github/workflows/devcontainer-ti.yaml index 62bf705fd0..3c935a1ea7 100644 --- a/.github/workflows/devcontainer-ti.yaml +++ b/.github/workflows/devcontainer-ti.yaml @@ -18,11 +18,12 @@ on: jobs: build: + if: ${{ vars.PUBLISH_DOCKER_IMAGE == 'true' }} runs-on: ubuntu-latest steps: - name: Checkout Repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Get container version run: | @@ -36,14 +37,14 @@ jobs: uses: docker/setup-buildx-action@v2 - name: Login to GitHub Container Registry - uses: docker/login-action@v1 + uses: docker/login-action@v2 with: registry: ghcr.io username: ${{ github.repository_owner }} password: ${{ secrets.CONTAINER_BUILD_TOKEN }} - name: Build and Push Docker Image - uses: docker/build-push-action@v3 + uses: docker/build-push-action@v4 with: file: ${{ env.GCR_FILE }} push: true # Will only build if this is not here diff --git a/.gitignore b/.gitignore index d47caf0d9d..9727ed1dc9 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,7 @@ /zips/ # ignore build folder -/build/ +/build**/ /out/ /build/.gitkeep @@ -376,5 +376,7 @@ ASALocalRun/ # ESP32 sdkconfig file sdkconfig -# CMake user presets +# CMake user presets and local presets CMakeUserPresets.json +config/user-tools-repos.json +config/user-prefs.json diff --git a/.gitmodules b/.gitmodules index 1682bdc6c1..fbfa44d313 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,5 @@ [submodule "targets-community"] path = targets-community - url = ../nf-Community-Targets.git + url = https://github.com/nanoframework/nf-Community-Targets.git + shallow = true + ignore = dirty diff --git a/.jlink/erase_gg11.jlink b/.jlink/erase_gg11.jlink new file mode 100644 index 0000000000..f859bf7395 --- /dev/null +++ b/.jlink/erase_gg11.jlink @@ -0,0 +1,3 @@ +speed auto +erase 0x0000000 0x001FF000 +Exit \ No newline at end of file diff --git a/.jlink/flash_gg11.jlink b/.jlink/flash_gg11.jlink new file mode 100644 index 0000000000..af9be891a8 --- /dev/null +++ b/.jlink/flash_gg11.jlink @@ -0,0 +1,6 @@ +speed auto +Halt +LoadFile nanobooter-nanoclr.bin,0 +Reset +Go +Exit \ No newline at end of file diff --git a/.vscode/tasks.TEMPLATE.json b/.vscode/tasks.TEMPLATE.json index 7341d3cac3..d8422dc05d 100644 --- a/.vscode/tasks.TEMPLATE.json +++ b/.vscode/tasks.TEMPLATE.json @@ -16,9 +16,9 @@ "command": "install-scripts\\install-nf-tools.ps1 -TargetSeries ${input:targetSeries} -Path '${input:toolsPath}' " }, { - "label": "Flash nanoCLR to ESP32/S2", + "label": "Flash nanoCLR to ESP32 | ESP32-S2", "type": "shell", - "command": "python ${env:IDF_PATH}/components/esptool_py/esptool/esptool.py --chip auto --port \"${input:comPort}\" --baud 1500000 --before \"default_reset\" --after \"hard_reset\" write_flash -z --flash_mode \"dio\" --flash_freq \"keep\" --flash_size detect 0x1000 ${workspaceFolder}/build/bootloader/bootloader.bin 0x10000 ${workspaceFolder}/build/nanoCLR.bin 0x8000 ${workspaceFolder}/build/partitions_${input:esp32Partitions}.bin", + "command": "python ${env:IDF_PATH}/components/esptool_py/esptool/esptool.py --chip auto --port \"${input:comPort}\" --baud 1500000 --before \"default_reset\" --after \"hard_reset\" write_flash -z --flash_size detect 0x1000 ${workspaceFolder}/build/bootloader/bootloader.bin 0x10000 ${workspaceFolder}/build/nanoCLR.bin 0x8000 ${workspaceFolder}/build/partitions_${input:esp32Partitions}.bin", "presentation": { "reveal": "always", "panel": "shared" @@ -26,9 +26,9 @@ "problemMatcher": [] }, { - "label": "Flash nanoCLR to ESP32-C3", + "label": "Flash nanoCLR to ESP32-C3 | ESP32-S3", "type": "shell", - "command": "python ${env:IDF_PATH}/components/esptool_py/esptool/esptool.py --chip auto --port \"${input:comPort}\" --baud 1500000 --before \"default_reset\" --after \"hard_reset\" write_flash -z --flash_mode \"dio\" --flash_freq \"keep\" --flash_size detect 0x0 ${workspaceFolder}/build/bootloader/bootloader.bin 0x10000 ${workspaceFolder}/build/nanoCLR.bin 0x8000 ${workspaceFolder}/build/partitions_${input:esp32Partitions}.bin", + "command": "python ${env:IDF_PATH}/components/esptool_py/esptool/esptool.py --chip auto --port \"${input:comPort}\" --baud 1500000 --before \"default_reset\" --after \"hard_reset\" write_flash -z --flash_size detect 0x0 ${workspaceFolder}/build/bootloader/bootloader.bin 0x10000 ${workspaceFolder}/build/nanoCLR.bin 0x8000 ${workspaceFolder}/build/partitions_${input:esp32Partitions}.bin", "presentation": { "reveal": "always", "panel": "shared" @@ -75,6 +75,22 @@ "panel": "dedicated" }, "problemMatcher": [] + }, + { + "label": "Erase flash Silabs GG11", + "type": "shell", + "command": "${env:JLINK_PATH}/Jlink.exe -device default -si swd -CommandFile ${workspaceRoot}/.jlink/erase_gg11.jlink", + "windows": { + "options": { + "shell": { + "executable": "cmd.exe", + "args": [ + "/c" + ] + } + } + }, + "problemMatcher": [] } ], "inputs": [ diff --git a/CMake/AzureRTOS_target_os.h.in b/CMake/AzureRTOS_target_os.h.in index 87c18a1249..0c70efc014 100644 --- a/CMake/AzureRTOS_target_os.h.in +++ b/CMake/AzureRTOS_target_os.h.in @@ -23,13 +23,17 @@ #define TARGETINFOSTRING "@CMAKE_BUILD_TYPE@ build with Azure RTOS v" STR(THREADX_MAJOR_VERSION) "." STR(THREADX_MINOR_VERSION) "." STR(THREADX_PATCH_VERSION) -#define NANOCLR_LIGHT_MATH @TARGET_LIGHT_MATH@ -#define DP_FLOATINGPOINT @TARGET_DP_FLOATINGPOINT@ -#define SUPPORT_ANY_BASE_CONVERSION @TARGET_SUPPORT_ANY_BASE_CONVERSION@ -#define HAS_CONFIG_BLOCK @TARGET_HAS_CONFIG_BLOCK@ -#define NANOCLR_REFLECTION @TARGET_NANOCLR_REFLECTION@ -#define NANOCLR_SYSTEM_COLLECTIONS @TARGET_SYSTEM_COLLECTIONS@ -#define TARGET_HAS_NANOBOOTER @TARGET_HAS_NANOBOOTER@ -#define TRACE_TO_STDIO @TARGET_TRACE_TO_STDIO@ +#define NANOCLR_LIGHT_MATH @TARGET_LIGHT_MATH@ +#define DP_FLOATINGPOINT @TARGET_DP_FLOATINGPOINT@ +#define SUPPORT_ANY_BASE_CONVERSION @TARGET_SUPPORT_ANY_BASE_CONVERSION@ +#define HAS_CONFIG_BLOCK @TARGET_HAS_CONFIG_BLOCK@ +#define NANOCLR_REFLECTION @TARGET_NANOCLR_REFLECTION@ +#define NANOCLR_SYSTEM_COLLECTIONS @TARGET_SYSTEM_COLLECTIONS@ +#define TARGET_HAS_NANOBOOTER @TARGET_HAS_NANOBOOTER@ +#define TRACE_TO_STDIO @TARGET_TRACE_TO_STDIO@ +#cmakedefine TARGET_SERIAL_BAUDRATE @TARGET_SERIAL_BAUDRATE@ +#cmakedefine NANOCLR_PROFILE_NEW_CALLS @NANOCLR_PROFILE_NEW_CALLS@ +#cmakedefine NANOCLR_PROFILE_NEW_ALLOCATIONS @NANOCLR_PROFILE_NEW_ALLOCATIONS@ +#cmakedefine NANOCLR_TRACE_MEMORY_STATS @NANOCLR_TRACE_MEMORY_STATS@ #endif // TARGET_OS_H diff --git a/CMake/ChibiOS_target_os.h.in b/CMake/ChibiOS_target_os.h.in index 6582ea327f..c368b5c909 100644 --- a/CMake/ChibiOS_target_os.h.in +++ b/CMake/ChibiOS_target_os.h.in @@ -23,13 +23,16 @@ #define TARGETINFOSTRING "@CMAKE_BUILD_TYPE@ build with ChibiOS v" CH_VERSION "." STR(CH_VERSION_MONTH) -#define NANOCLR_LIGHT_MATH @TARGET_LIGHT_MATH@ -#define DP_FLOATINGPOINT @TARGET_DP_FLOATINGPOINT@ -#define SUPPORT_ANY_BASE_CONVERSION @TARGET_SUPPORT_ANY_BASE_CONVERSION@ -#define HAS_CONFIG_BLOCK @TARGET_HAS_CONFIG_BLOCK@ -#define NANOCLR_REFLECTION @TARGET_NANOCLR_REFLECTION@ -#define NANOCLR_SYSTEM_COLLECTIONS @TARGET_SYSTEM_COLLECTIONS@ -#define TARGET_HAS_NANOBOOTER @TARGET_HAS_NANOBOOTER@ -#define TRACE_TO_STDIO @TARGET_TRACE_TO_STDIO@ +#define NANOCLR_LIGHT_MATH @TARGET_LIGHT_MATH@ +#define DP_FLOATINGPOINT @TARGET_DP_FLOATINGPOINT@ +#define SUPPORT_ANY_BASE_CONVERSION @TARGET_SUPPORT_ANY_BASE_CONVERSION@ +#define HAS_CONFIG_BLOCK @TARGET_HAS_CONFIG_BLOCK@ +#define NANOCLR_REFLECTION @TARGET_NANOCLR_REFLECTION@ +#define NANOCLR_SYSTEM_COLLECTIONS @TARGET_SYSTEM_COLLECTIONS@ +#define TARGET_HAS_NANOBOOTER @TARGET_HAS_NANOBOOTER@ +#define TRACE_TO_STDIO @TARGET_TRACE_TO_STDIO@ +#cmakedefine NANOCLR_PROFILE_NEW_CALLS @NANOCLR_PROFILE_NEW_CALLS@ +#cmakedefine NANOCLR_PROFILE_NEW_ALLOCATIONS @NANOCLR_PROFILE_NEW_ALLOCATIONS@ +#cmakedefine NANOCLR_TRACE_MEMORY_STATS @NANOCLR_TRACE_MEMORY_STATS@ #endif // TARGET_OS_H diff --git a/CMake/ESP32_target_os.h.in b/CMake/ESP32_target_os.h.in index d9bd397045..b71783e3ec 100644 --- a/CMake/ESP32_target_os.h.in +++ b/CMake/ESP32_target_os.h.in @@ -20,14 +20,17 @@ #define IDF_VER_FIXED "@IDF_VER_FIXED@" -#define NANOCLR_LIGHT_MATH @TARGET_LIGHT_MATH@ -#define DP_FLOATINGPOINT @TARGET_DP_FLOATINGPOINT@ -#define SUPPORT_ANY_BASE_CONVERSION @TARGET_SUPPORT_ANY_BASE_CONVERSION@ -#define HAS_CONFIG_BLOCK @TARGET_HAS_CONFIG_BLOCK@ -#define NANOCLR_REFLECTION @TARGET_NANOCLR_REFLECTION@ -#define NANOCLR_SYSTEM_COLLECTIONS @TARGET_SYSTEM_COLLECTIONS@ -#define TARGET_HAS_NANOBOOTER FALSE -#define TRACE_TO_STDIO @TARGET_TRACE_TO_STDIO@ -#cmakedefine TARGET_SERIAL_BAUDRATE @TARGET_SERIAL_BAUDRATE@ +#define NANOCLR_LIGHT_MATH @TARGET_LIGHT_MATH@ +#define DP_FLOATINGPOINT @TARGET_DP_FLOATINGPOINT@ +#define SUPPORT_ANY_BASE_CONVERSION @TARGET_SUPPORT_ANY_BASE_CONVERSION@ +#define HAS_CONFIG_BLOCK @TARGET_HAS_CONFIG_BLOCK@ +#define NANOCLR_REFLECTION @TARGET_NANOCLR_REFLECTION@ +#define NANOCLR_SYSTEM_COLLECTIONS @TARGET_SYSTEM_COLLECTIONS@ +#define TARGET_HAS_NANOBOOTER FALSE +#define TRACE_TO_STDIO @TARGET_TRACE_TO_STDIO@ +#cmakedefine TARGET_SERIAL_BAUDRATE @TARGET_SERIAL_BAUDRATE@ +#cmakedefine NANOCLR_PROFILE_NEW_CALLS @NANOCLR_PROFILE_NEW_CALLS@ +#cmakedefine NANOCLR_PROFILE_NEW_ALLOCATIONS @NANOCLR_PROFILE_NEW_ALLOCATIONS@ +#cmakedefine NANOCLR_TRACE_MEMORY_STATS @NANOCLR_TRACE_MEMORY_STATS@ #endif // TARGET_OS_H diff --git a/CMake/FreeRTOS_target_os.h.in b/CMake/FreeRTOS_target_os.h.in index e33be054d8..30c0693f91 100644 --- a/CMake/FreeRTOS_target_os.h.in +++ b/CMake/FreeRTOS_target_os.h.in @@ -21,13 +21,16 @@ #define TARGETINFOSTRING "@CMAKE_BUILD_TYPE@ build with FREERTOS @RTOS_VERSION@" -#define NANOCLR_LIGHT_MATH @TARGET_LIGHT_MATH@ -#define DP_FLOATINGPOINT @TARGET_DP_FLOATINGPOINT@ -#define SUPPORT_ANY_BASE_CONVERSION @TARGET_SUPPORT_ANY_BASE_CONVERSION@ -#define HAS_CONFIG_BLOCK @TARGET_HAS_CONFIG_BLOCK@ -#define NANOCLR_REFLECTION @TARGET_NANOCLR_REFLECTION@ -#define NANOCLR_SYSTEM_COLLECTIONS @TARGET_SYSTEM_COLLECTIONS@ -#define TARGET_HAS_NANOBOOTER @TARGET_HAS_NANOBOOTER@ -#define TRACE_TO_STDIO @TARGET_TRACE_TO_STDIO@ +#define NANOCLR_LIGHT_MATH @TARGET_LIGHT_MATH@ +#define DP_FLOATINGPOINT @TARGET_DP_FLOATINGPOINT@ +#define SUPPORT_ANY_BASE_CONVERSION @TARGET_SUPPORT_ANY_BASE_CONVERSION@ +#define HAS_CONFIG_BLOCK @TARGET_HAS_CONFIG_BLOCK@ +#define NANOCLR_REFLECTION @TARGET_NANOCLR_REFLECTION@ +#define NANOCLR_SYSTEM_COLLECTIONS @TARGET_SYSTEM_COLLECTIONS@ +#define TARGET_HAS_NANOBOOTER @TARGET_HAS_NANOBOOTER@ +#define TRACE_TO_STDIO @TARGET_TRACE_TO_STDIO@ +#cmakedefine NANOCLR_PROFILE_NEW_CALLS @NANOCLR_PROFILE_NEW_CALLS@ +#cmakedefine NANOCLR_PROFILE_NEW_ALLOCATIONS @NANOCLR_PROFILE_NEW_ALLOCATIONS@ +#cmakedefine NANOCLR_TRACE_MEMORY_STATS @NANOCLR_TRACE_MEMORY_STATS@ #endif // TARGET_OS_H diff --git a/CMake/Modules/AzureRTOS_EFM32GG11_GCC_options.cmake b/CMake/Modules/AzureRTOS_EFM32GG11_GCC_options.cmake new file mode 100644 index 0000000000..0963e9e016 --- /dev/null +++ b/CMake/Modules/AzureRTOS_EFM32GG11_GCC_options.cmake @@ -0,0 +1,80 @@ +# +# Copyright (c) .NET Foundation and Contributors +# See LICENSE file in the project root for full license information. +# + +################################################################# +# WHEN ADDING A NEW SERIES add the appropriate GCC options below +################################################################# + +# need to specify this for assembler +set(CMAKE_ASM_FLAGS " -gdwarf-2 -mthumb -mcpu=cortex-m4 -x assembler-with-cpp" CACHE INTERNAL "asm compiler flags") +set(CMAKE_C_FLAGS " -gdwarf-2 -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -mabi=aapcs -Wall -Wextra -Werror -ffunction-sections -fshort-wchar -falign-functions=16 -fdata-sections -fno-builtin -fno-common -fomit-frame-pointer -mlong-calls -fdollars-in-identifiers -fno-exceptions -fno-unroll-loops -frounding-math -fsignaling-nans -ffloat-store -fno-math-errno -ftree-vectorize -fcheck-new " CACHE INTERNAL "asm compiler flags") +set(CMAKE_CXX_FLAGS " -gdwarf-2 -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -mabi=aapcs -Wall -Wextra -Werror -Wno-maybe-uninitialized -ffunction-sections -fshort-wchar -falign-functions=16 -fdata-sections -fno-builtin -fno-common -fomit-frame-pointer -mlong-calls -fdollars-in-identifiers -fno-exceptions -fno-unroll-loops -frounding-math -fsignaling-nans -ffloat-store -fno-math-errno -ftree-vectorize -fcheck-new " CACHE INTERNAL "asm compiler flags") + +# need to specify linker flags here +set(CMAKE_EXE_LINKER_FLAGS " -Wl,--gc-sections -Wl,--no-wchar-size-warning -Wl,--print-memory-usage -gdwarf-2 -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -mabi=aapcs " CACHE INTERNAL "executable linker flags") + + +# TARGET parameter to set the target that's setting them for +# optional EXTRA_COMPILE_OPTIONS with compile options to be added +macro(nf_set_compile_options) + + # parse arguments + cmake_parse_arguments(NFSCO "" "TARGET" "EXTRA_COMPILE_OPTIONS" ${ARGN}) + + if(NOT NFSCO_TARGET OR "${NFSCO_TARGET}" STREQUAL "") + message(FATAL_ERROR "Need to set TARGET argument when calling nf_set_compile_options()") + endif() + + # include any extra options coming from any extra args? + # disabling -Wshadow for now as it's causing issues with TX_INTERRUPT_SAVE_AREA + target_compile_options(${NFSCO_TARGET} PUBLIC ${NFSCO_EXTRA_COMPILE_OPTIONS} -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -mabi=aapcs -Wall -Wextra -Werror -Wundef -Wimplicit-fallthrough -ffunction-sections -fshort-wchar -falign-functions=16 -fdata-sections -fno-builtin -fno-common -fomit-frame-pointer -mlong-calls -fdollars-in-identifiers -fno-exceptions -fno-unroll-loops -frounding-math -fsignaling-nans -ffloat-store -fno-math-errno -ftree-vectorize -fcheck-new ) + + # enable: + # - FPU + # - user TX file + target_compile_definitions(${NFSCO_TARGET} PUBLIC -DPLATFORM_ARM -DCORTEX_USE_FPU=FALSE -DUSE_FPU=FALSE -DTX_INCLUDE_USER_DEFINE_FILE ) + + if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") + target_compile_definitions(${NFSCO_TARGET} PUBLIC -DDEBUG_EFM=1) + endif() + + if(GECKO_DEVICE_CLASS_VENDOR_DESCRIPTION_LENGTH) + target_compile_definitions(${NFSCO_TARGET} PUBLIC -DGECKO_DEVICE_CLASS_VENDOR_DESCRIPTION_PROPERTY_LEN=${GECKO_DEVICE_CLASS_VENDOR_DESCRIPTION_LENGTH} ) + else() + target_compile_definitions(${NFSCO_TARGET} PUBLIC -DGECKO_DEVICE_CLASS_VENDOR_DESCRIPTION_PROPERTY_LEN=64 ) + endif() + +endmacro() + + +# TARGET parameter to set the target that's setting them for +# optional EXTRA_LINK_FLAGS with link flags to be added +macro(nf_set_link_options) + + # parse arguments + cmake_parse_arguments(NFSLO "" "TARGET;EXTRA_LINK_FLAGS" "" ${ARGN}) + + if(NOT NFSLO_TARGET OR "${NFSLO_TARGET}" STREQUAL "") + message(FATAL_ERROR "Need to set TARGET argument when calling nf_set_link_options()") + endif() + + # set optimization linker flags for RELEASE and MinSizeRel + if(CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "MinSizeRel") + set_property(TARGET ${NFSLO_TARGET} APPEND_STRING PROPERTY LINK_FLAGS " -Os -flto ") + endif() + + # request specs from newlib nano + set_property(TARGET ${NFSLO_TARGET} APPEND_STRING PROPERTY LINK_FLAGS " --specs=nano.specs --specs=nosys.specs ") + + # include libraries in build + nf_include_libraries_in_build(${NFSLO_TARGET}) + + # set extra linker flags + set_property(TARGET ${NFSLO_TARGET} APPEND_STRING PROPERTY LINK_FLAGS " ${NFSLO_EXTRA_LINK_FLAGS} ") + + # set optimization flags + nf_set_optimization_options(${NFSLO_TARGET}) + +endmacro() diff --git a/CMake/Modules/AzureRTOS_EFM32GG11_sources.cmake b/CMake/Modules/AzureRTOS_EFM32GG11_sources.cmake new file mode 100644 index 0000000000..c17262b642 --- /dev/null +++ b/CMake/Modules/AzureRTOS_EFM32GG11_sources.cmake @@ -0,0 +1,8 @@ +# +# Copyright (c) .NET Foundation and Contributors +# See LICENSE file in the project root for full license information. +# + +################################# +# This file is empty on purpose # +################################# diff --git a/CMake/Modules/AzureRTOS_MAX78000_GCC_options.cmake b/CMake/Modules/AzureRTOS_MAX78000_GCC_options.cmake index 5745ca58b8..271777d358 100644 --- a/CMake/Modules/AzureRTOS_MAX78000_GCC_options.cmake +++ b/CMake/Modules/AzureRTOS_MAX78000_GCC_options.cmake @@ -25,7 +25,7 @@ macro(nf_set_compile_options) # include any extra options coming from any extra args? # can't include -Wundef because of MAXIM SDK - target_compile_options(${NFSCO_TARGET} PUBLIC ${NFSCO__EXTRA_COMPILE_OPTIONS} -mthumb -mcpu=cortex-m4 -mfloat-abi=soft -mfpu=fpv4-sp-d16 -mfloat-abi=soft -Wa,-mimplicit-it=thumb -Wall -Wextra -Werror -Wshadow -Wimplicit-fallthrough -ffunction-sections -fshort-wchar -falign-functions=16 -fdata-sections -fno-builtin -fno-common -fomit-frame-pointer -mlong-calls -fdollars-in-identifiers -fno-exceptions -fno-unroll-loops -frounding-math -fsignaling-nans -ffloat-store -fno-math-errno -ftree-vectorize -fcheck-new ) + target_compile_options(${NFSCO_TARGET} PUBLIC ${NFSCO_EXTRA_COMPILE_OPTIONS} -mthumb -mcpu=cortex-m4 -mfloat-abi=soft -mfpu=fpv4-sp-d16 -mfloat-abi=soft -Wa,-mimplicit-it=thumb -Wall -Wextra -Werror -Wshadow -Wimplicit-fallthrough -ffunction-sections -fshort-wchar -falign-functions=16 -fdata-sections -fno-builtin -fno-common -fomit-frame-pointer -mlong-calls -fdollars-in-identifiers -fno-exceptions -fno-unroll-loops -frounding-math -fsignaling-nans -ffloat-store -fno-math-errno -ftree-vectorize -fcheck-new ) # enable: # - FPU @@ -59,7 +59,7 @@ macro(nf_set_link_options) nf_include_libraries_in_build(${NFSLO_TARGET}) # set extra linker flags - set_property(TARGET ${NFSLO_TARGET} APPEND_STRING PROPERTY LINK_FLAGS " ${NFSLO__EXTRA_LINK_FLAGS} ") + set_property(TARGET ${NFSLO_TARGET} APPEND_STRING PROPERTY LINK_FLAGS " ${NFSLO_EXTRA_LINK_FLAGS} ") # set optimization flags nf_set_optimization_options(${NFSLO_TARGET}) diff --git a/CMake/Modules/AzureRTOS_MICROBIT_GCC_options.cmake b/CMake/Modules/AzureRTOS_MICROBIT_GCC_options.cmake index 076a30f866..d77a158060 100644 --- a/CMake/Modules/AzureRTOS_MICROBIT_GCC_options.cmake +++ b/CMake/Modules/AzureRTOS_MICROBIT_GCC_options.cmake @@ -27,7 +27,7 @@ macro(nf_set_compile_options) endif() # include any extra options coming from any extra args? - target_compile_options(${NFSCO_TARGET} PUBLIC ${NFSCO__EXTRA_COMPILE_OPTIONS} -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mabi=aapcs -Wall -Wextra -Werror -Wundef -Wshadow -Wimplicit-fallthrough -ffunction-sections -fshort-wchar -falign-functions=16 -fdata-sections -fno-builtin -fno-common -fomit-frame-pointer -mlong-calls -fdollars-in-identifiers -fno-exceptions -fno-unroll-loops -frounding-math -fsignaling-nans -ffloat-store -fno-math-errno -ftree-vectorize -fcheck-new ) + target_compile_options(${NFSCO_TARGET} PUBLIC ${NFSCO_EXTRA_COMPILE_OPTIONS} -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mabi=aapcs -Wall -Wextra -Werror -Wundef -Wshadow -Wimplicit-fallthrough -ffunction-sections -fshort-wchar -falign-functions=16 -fdata-sections -fno-builtin -fno-common -fomit-frame-pointer -mlong-calls -fdollars-in-identifiers -fno-exceptions -fno-unroll-loops -frounding-math -fsignaling-nans -ffloat-store -fno-math-errno -ftree-vectorize -fcheck-new ) # enable: # - FPU @@ -60,7 +60,7 @@ macro(nf_set_link_options) nf_include_libraries_in_build(${NFSLO_TARGET}) # set extra linker flags - set_property(TARGET ${NFSLO_TARGET} APPEND_STRING PROPERTY LINK_FLAGS " ${NFSLO__EXTRA_LINK_FLAGS} ") + set_property(TARGET ${NFSLO_TARGET} APPEND_STRING PROPERTY LINK_FLAGS " ${NFSLO_EXTRA_LINK_FLAGS} ") # set optimization flags nf_set_optimization_options(${NFSLO_TARGET}) diff --git a/CMake/Modules/AzureRTOS_RP2040_GCC_options.cmake b/CMake/Modules/AzureRTOS_RP2040_GCC_options.cmake index 71117bd245..d0d4c7bbc9 100644 --- a/CMake/Modules/AzureRTOS_RP2040_GCC_options.cmake +++ b/CMake/Modules/AzureRTOS_RP2040_GCC_options.cmake @@ -25,7 +25,7 @@ macro(nf_set_compile_options) endif() # include any extra options coming from any extra args? - target_compile_options(${NFSCO_TARGET} PUBLIC ${NFSCO__EXTRA_COMPILE_OPTIONS} -mthumb -mcpu=cortex-m0plus -mtune=cortex-m0plus -nostdlib -Wall -Wextra -Werror -Wundef -Wshadow -Wimplicit-fallthrough -fshort-wchar -fno-builtin -fno-common -mno-long-calls -fno-exceptions -fcheck-new ) + target_compile_options(${NFSCO_TARGET} PUBLIC ${NFSCO_EXTRA_COMPILE_OPTIONS} -mthumb -mcpu=cortex-m0plus -mtune=cortex-m0plus -nostdlib -Wall -Wextra -Werror -Wundef -Wshadow -Wimplicit-fallthrough -fshort-wchar -fno-builtin -fno-common -mno-long-calls -fno-exceptions -fcheck-new ) # this series doesn't have FPU # enable: @@ -58,7 +58,7 @@ macro(nf_set_link_options) nf_include_libraries_in_build(${NFSLO_TARGET}) # set extra linker flags - set_property(TARGET ${NFSLO_TARGET} APPEND_STRING PROPERTY LINK_FLAGS " ${NFSLO__EXTRA_LINK_FLAGS} ") + set_property(TARGET ${NFSLO_TARGET} APPEND_STRING PROPERTY LINK_FLAGS " ${NFSLO_EXTRA_LINK_FLAGS} ") # set optimization flags nf_set_optimization_options(${NFSLO_TARGET}) diff --git a/CMake/Modules/AzureRTOS_STM32F7xx_GCC_options.cmake b/CMake/Modules/AzureRTOS_STM32F7xx_GCC_options.cmake index d824f4187e..2efe1f2fa2 100644 --- a/CMake/Modules/AzureRTOS_STM32F7xx_GCC_options.cmake +++ b/CMake/Modules/AzureRTOS_STM32F7xx_GCC_options.cmake @@ -30,7 +30,7 @@ macro(nf_set_compile_options) # include any extra options coming from any extra args? # STMF7 cores have SP and DP, the default is SP. DP can be set if developer realy needs that. # disabling -Wshadow for now as it's causing issues with TX_INTERRUPT_SAVE_AREA - target_compile_options(${NFSCO_TARGET} PUBLIC ${NFSCO__EXTRA_COMPILE_OPTIONS} -mthumb -mcpu=cortex-m7 -mfpu=fpv5-sp-d16 -mfloat-abi=hard -mabi=aapcs -Wall -Wextra -Werror -Wundef -Wimplicit-fallthrough -fshort-wchar -fno-builtin -fno-common -mno-long-calls -fno-exceptions -fcheck-new ) + target_compile_options(${NFSCO_TARGET} PUBLIC ${NFSCO_EXTRA_COMPILE_OPTIONS} -mthumb -mcpu=cortex-m7 -mfpu=fpv5-sp-d16 -mfloat-abi=hard -mabi=aapcs -Wall -Wextra -Werror -Wundef -Wimplicit-fallthrough -fshort-wchar -fno-builtin -fno-common -mno-long-calls -fno-exceptions -fcheck-new ) # enable: # - FPU @@ -64,7 +64,7 @@ macro(nf_set_link_options) nf_include_libraries_in_build(${NFSLO_TARGET}) # set extra linker flags - set_property(TARGET ${NFSLO_TARGET} APPEND_STRING PROPERTY LINK_FLAGS " ${NFSLO__EXTRA_LINK_FLAGS} ") + set_property(TARGET ${NFSLO_TARGET} APPEND_STRING PROPERTY LINK_FLAGS " ${NFSLO_EXTRA_LINK_FLAGS} ") # set optimization flags nf_set_optimization_options(${NFSLO_TARGET}) diff --git a/CMake/Modules/AzureRTOS_STM32L4xx_GCC_options.cmake b/CMake/Modules/AzureRTOS_STM32L4xx_GCC_options.cmake index 31bc17df1e..18bac5751b 100644 --- a/CMake/Modules/AzureRTOS_STM32L4xx_GCC_options.cmake +++ b/CMake/Modules/AzureRTOS_STM32L4xx_GCC_options.cmake @@ -9,8 +9,7 @@ # need to specify this for assembler set(CMAKE_ASM_FLAGS " -mthumb -mcpu=cortex-m4 -x assembler-with-cpp" CACHE INTERNAL "asm compiler flags") -# adding -Werror=maybe-uninitialized for now as it's causing issues (https://github.com/azure-rtos/netxduo/issues/121) -set(CMAKE_C_FLAGS " -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mabi=aapcs -Wall -Wextra -Werror -Wno-error=maybe-uninitialized -ffunction-sections -fshort-wchar -falign-functions=16 -fdata-sections -fno-builtin -fno-common -fomit-frame-pointer -mlong-calls -fdollars-in-identifiers -fno-exceptions -fno-unroll-loops -frounding-math -fsignaling-nans -ffloat-store -fno-math-errno -ftree-vectorize -fcheck-new " CACHE INTERNAL "asm compiler flags") +set(CMAKE_C_FLAGS " -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mabi=aapcs -Wall -Wextra -Werror -ffunction-sections -fshort-wchar -falign-functions=16 -fdata-sections -fno-builtin -fno-common -fomit-frame-pointer -mlong-calls -fdollars-in-identifiers -fno-exceptions -fno-unroll-loops -frounding-math -fsignaling-nans -ffloat-store -fno-math-errno -ftree-vectorize -fcheck-new " CACHE INTERNAL "asm compiler flags") set(CMAKE_CXX_FLAGS " -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mabi=aapcs -Wall -Wextra -Werror -ffunction-sections -fshort-wchar -falign-functions=16 -fdata-sections -fno-builtin -fno-common -fomit-frame-pointer -mlong-calls -fdollars-in-identifiers -fno-exceptions -fno-unroll-loops -frounding-math -fsignaling-nans -ffloat-store -fno-math-errno -ftree-vectorize -fcheck-new " CACHE INTERNAL "asm compiler flags") # need to specify linker flags here @@ -30,7 +29,7 @@ macro(nf_set_compile_options) # include any extra options coming from any extra args? # disabling -Wshadow for now as it's causing issues with TX_INTERRUPT_SAVE_AREA - target_compile_options(${NFSCO_TARGET} PUBLIC ${NFSCO__EXTRA_COMPILE_OPTIONS} -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mabi=aapcs -Wall -Wextra -Werror -Wundef -Wimplicit-fallthrough -ffunction-sections -fshort-wchar -falign-functions=16 -fdata-sections -fno-builtin -fno-common -fomit-frame-pointer -mlong-calls -fdollars-in-identifiers -fno-exceptions -fno-unroll-loops -frounding-math -fsignaling-nans -ffloat-store -fno-math-errno -ftree-vectorize -fcheck-new ) + target_compile_options(${NFSCO_TARGET} PUBLIC ${NFSCO_EXTRA_COMPILE_OPTIONS} -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mabi=aapcs -Wall -Wextra -Werror -Wundef -Wimplicit-fallthrough -ffunction-sections -fshort-wchar -falign-functions=16 -fdata-sections -fno-builtin -fno-common -fomit-frame-pointer -mlong-calls -fdollars-in-identifiers -fno-exceptions -fno-unroll-loops -frounding-math -fsignaling-nans -ffloat-store -fno-math-errno -ftree-vectorize -fcheck-new ) # enable: # - FPU @@ -64,7 +63,7 @@ macro(nf_set_link_options) nf_include_libraries_in_build(${NFSLO_TARGET}) # set extra linker flags - set_property(TARGET ${NFSLO_TARGET} APPEND_STRING PROPERTY LINK_FLAGS " ${NFSLO__EXTRA_LINK_FLAGS} ") + set_property(TARGET ${NFSLO_TARGET} APPEND_STRING PROPERTY LINK_FLAGS " ${NFSLO_EXTRA_LINK_FLAGS} ") # set optimization flags nf_set_optimization_options(${NFSLO_TARGET}) diff --git a/CMake/Modules/CHIBIOS_STM32F4xx_GCC_options.cmake b/CMake/Modules/CHIBIOS_STM32F4xx_GCC_options.cmake index 31ba37454b..2bc643746a 100644 --- a/CMake/Modules/CHIBIOS_STM32F4xx_GCC_options.cmake +++ b/CMake/Modules/CHIBIOS_STM32F4xx_GCC_options.cmake @@ -27,7 +27,7 @@ macro(nf_set_compile_options) # include any extra options coming from any extra args? - target_compile_options(${NFSCO_TARGET} PUBLIC ${NFSCO__EXTRA_COMPILE_OPTIONS} -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mabi=aapcs -nostdlib -Wall -Wextra -Werror -Wundef -Wshadow -Wimplicit-fallthrough -fshort-wchar -fno-builtin -fno-common -mno-long-calls -fno-exceptions -fcheck-new ) + target_compile_options(${NFSCO_TARGET} PUBLIC ${NFSCO_EXTRA_COMPILE_OPTIONS} -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mabi=aapcs -nostdlib -Wall -Wextra -Werror -Wundef -Wshadow -Wimplicit-fallthrough -fshort-wchar -fno-builtin -fno-common -mno-long-calls -fno-exceptions -fcheck-new ) # this series has FPU target_compile_definitions(${NFSCO_TARGET} PUBLIC -DPLATFORM_ARM -DCORTEX_USE_FPU=TRUE -DUSE_FPU=TRUE) diff --git a/CMake/Modules/CHIBIOS_STM32F7xx_GCC_options.cmake b/CMake/Modules/CHIBIOS_STM32F7xx_GCC_options.cmake index 07f331ab1d..5030f75624 100644 --- a/CMake/Modules/CHIBIOS_STM32F7xx_GCC_options.cmake +++ b/CMake/Modules/CHIBIOS_STM32F7xx_GCC_options.cmake @@ -27,7 +27,7 @@ macro(nf_set_compile_options) # include any extra options coming from any extra args? # STMF7 cores have SP and DP, the default is SP. DP can be set if developer realy needs that. - target_compile_options(${NFSCO_TARGET} PUBLIC ${NFSCO__EXTRA_COMPILE_OPTIONS} -mthumb -mcpu=cortex-m7 -mfpu=fpv5-sp-d16 -mfloat-abi=hard -mabi=aapcs -nostdlib -Wall -Wextra -Werror -Wundef -Wshadow -Wimplicit-fallthrough -fshort-wchar -fno-builtin -fno-common -mno-long-calls -fno-exceptions -fcheck-new ) + target_compile_options(${NFSCO_TARGET} PUBLIC ${NFSCO_EXTRA_COMPILE_OPTIONS} -mthumb -mcpu=cortex-m7 -mfpu=fpv5-sp-d16 -mfloat-abi=hard -mabi=aapcs -nostdlib -Wall -Wextra -Werror -Wundef -Wshadow -Wimplicit-fallthrough -fshort-wchar -fno-builtin -fno-common -mno-long-calls -fno-exceptions -fcheck-new ) # this series has FPU target_compile_definitions(${NFSCO_TARGET} PUBLIC -DPLATFORM_ARM -DCORTEX_USE_FPU=TRUE -DUSE_FPU=TRUE) diff --git a/CMake/Modules/CHIBIOS_STM32H7xx_GCC_options.cmake b/CMake/Modules/CHIBIOS_STM32H7xx_GCC_options.cmake index db5dc6088e..f6bc414f53 100644 --- a/CMake/Modules/CHIBIOS_STM32H7xx_GCC_options.cmake +++ b/CMake/Modules/CHIBIOS_STM32H7xx_GCC_options.cmake @@ -28,7 +28,7 @@ macro(nf_set_compile_options) # include any extra options coming from any extra args? # STMF7 cores have SP and DP, the default is SP. DP can be set if developer realy needs that. - target_compile_options(${NFSCO_TARGET} PUBLIC ${NFSCO__EXTRA_COMPILE_OPTIONS} -mthumb -mcpu=cortex-m7 -mfpu=fpv5-sp-d16 -mfloat-abi=hard -mabi=aapcs -nostdlib -Wall -Wextra -Werror -Wundef -Wshadow -Wimplicit-fallthrough -fshort-wchar -fno-builtin -fno-common -mno-long-calls -fno-exceptions -fcheck-new ) + target_compile_options(${NFSCO_TARGET} PUBLIC ${NFSCO_EXTRA_COMPILE_OPTIONS} -mthumb -mcpu=cortex-m7 -mfpu=fpv5-sp-d16 -mfloat-abi=hard -mabi=aapcs -nostdlib -Wall -Wextra -Werror -Wundef -Wshadow -Wimplicit-fallthrough -fshort-wchar -fno-builtin -fno-common -mno-long-calls -fno-exceptions -fcheck-new ) # this series has FPU target_compile_definitions(${NFSCO_TARGET} PUBLIC -DPLATFORM_ARM -DCORTEX_USE_FPU=TRUE -DUSE_FPU=TRUE) diff --git a/CMake/Modules/CHIBIOS_STM32L0xx_GCC_options.cmake b/CMake/Modules/CHIBIOS_STM32L0xx_GCC_options.cmake index f8473405f9..a6b244c7f4 100644 --- a/CMake/Modules/CHIBIOS_STM32L0xx_GCC_options.cmake +++ b/CMake/Modules/CHIBIOS_STM32L0xx_GCC_options.cmake @@ -31,7 +31,7 @@ macro(nf_set_compile_options) # include any extra options coming from any extra args? - target_compile_options(${NFSCO_TARGET} PUBLIC ${NFSCO__EXTRA_COMPILE_OPTIONS} -mthumb -mcpu=cortex-m0plus -mfloat-abi=soft -mabi=aapcs -mtune=cortex-m0plus -nostdlib -Wall -Wextra -Werror -Wundef -Wshadow -Wimplicit-fallthrough -fshort-wchar -fno-builtin -fno-common -mno-long-calls -fno-exceptions -fcheck-new ) + target_compile_options(${NFSCO_TARGET} PUBLIC ${NFSCO_EXTRA_COMPILE_OPTIONS} -mthumb -mcpu=cortex-m0plus -mfloat-abi=soft -mabi=aapcs -mtune=cortex-m0plus -nostdlib -Wall -Wextra -Werror -Wundef -Wshadow -Wimplicit-fallthrough -fshort-wchar -fno-builtin -fno-common -mno-long-calls -fno-exceptions -fcheck-new ) # this series doesn't have FPU target_compile_definitions(${NFSCO_TARGET} PUBLIC -DPLATFORM_ARM -DCORTEX_USE_FPU=FALSE -DUSE_FPU=TRUE) diff --git a/CMake/Modules/CHIBIOS_STM32L4xx_GCC_options.cmake b/CMake/Modules/CHIBIOS_STM32L4xx_GCC_options.cmake index d8664c7586..55bfa5e6fb 100644 --- a/CMake/Modules/CHIBIOS_STM32L4xx_GCC_options.cmake +++ b/CMake/Modules/CHIBIOS_STM32L4xx_GCC_options.cmake @@ -27,7 +27,7 @@ macro(nf_set_compile_options) # include any extra options coming from any extra args? - target_compile_options(${NFSCO_TARGET} PUBLIC ${NFSCO__EXTRA_COMPILE_OPTIONS} -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mabi=aapcs -nostdlib -Wall -Wextra -Werror -Wundef -Wshadow -Wimplicit-fallthrough -ffunction-sections -fshort-wchar -falign-functions=16 -fdata-sections -fno-builtin -fno-common -fomit-frame-pointer -mlong-calls -fdollars-in-identifiers -fno-exceptions -fno-unroll-loops -frounding-math -fsignaling-nans -ffloat-store -fno-math-errno -ftree-vectorize -fcheck-new ) + target_compile_options(${NFSCO_TARGET} PUBLIC ${NFSCO_EXTRA_COMPILE_OPTIONS} -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mabi=aapcs -nostdlib -Wall -Wextra -Werror -Wundef -Wshadow -Wimplicit-fallthrough -ffunction-sections -fshort-wchar -falign-functions=16 -fdata-sections -fno-builtin -fno-common -fomit-frame-pointer -mlong-calls -fdollars-in-identifiers -fno-exceptions -fno-unroll-loops -frounding-math -fsignaling-nans -ffloat-store -fno-math-errno -ftree-vectorize -fcheck-new ) # this series has FPU target_compile_definitions(${NFSCO_TARGET} PUBLIC -DPLATFORM_ARM -DCORTEX_USE_FPU=TRUE -DUSE_FPU=TRUE) diff --git a/CMake/Modules/ClrProfilerOptions.cmake b/CMake/Modules/ClrProfilerOptions.cmake new file mode 100644 index 0000000000..dfefc3523a --- /dev/null +++ b/CMake/Modules/ClrProfilerOptions.cmake @@ -0,0 +1,18 @@ +# +# Copyright (c) .NET Foundation and Contributors +# See LICENSE file in the project root for full license information. +# + +option(NF_PROFILE_NEW_CALLS "option to support profilling new function calls" OFF) +option(NF_PROFILE_NEW_ALLOCATIONS "option to support profilling new object allocations" OFF) +option(NF_TRACE_MEMORY_STATS "option to enable trace of memory stats" OFF) + +if(NF_PROFILE_NEW_CALLS) + set(NANOCLR_PROFILE_NEW_CALLS TRUE CACHE INTERNAL "option to support profilling new function calls") +endif() +if(NF_PROFILE_NEW_ALLOCATIONS) + set(NANOCLR_PROFILE_NEW_ALLOCATIONS TRUE CACHE INTERNAL "option to support profilling new object allocations") +endif() +if(NF_TRACE_MEMORY_STATS) + set(NANOCLR_TRACE_MEMORY_STATS TRUE CACHE INTERNAL "option to enable trace of memory stats") +endif() diff --git a/CMake/Modules/ESP32_C3_GCC_options.cmake b/CMake/Modules/ESP32_C3_GCC_options.cmake index 548fe0a151..de47e15ef7 100644 --- a/CMake/Modules/ESP32_C3_GCC_options.cmake +++ b/CMake/Modules/ESP32_C3_GCC_options.cmake @@ -18,7 +18,7 @@ macro(nf_set_compile_options) endif() # include any extra options coming from any extra args? - target_compile_options(${NFSCO_TARGET} PUBLIC ${NFSCO__EXTRA_COMPILE_OPTIONS} -Wall -Wextra -Werror -Wno-unused-parameter -Wshadow -Wimplicit-fallthrough -fshort-wchar -fno-builtin -fno-common -fno-exceptions -fcheck-new ) + target_compile_options(${NFSCO_TARGET} PUBLIC ${NFSCO_EXTRA_COMPILE_OPTIONS} -Wall -Wextra -Werror -Wno-sign-compare -Wno-unused-parameter -Wshadow -Wimplicit-fallthrough -fshort-wchar -fno-builtin -fno-common -fno-exceptions -fcheck-new ) # this series has FPU target_compile_definitions(${NFSCO_TARGET} PUBLIC -DTARGET=esp32c3 -DUSE_FPU=TRUE -DPLATFORM_ESP32) diff --git a/CMake/Modules/ESP32_GCC_options.cmake b/CMake/Modules/ESP32_GCC_options.cmake index 5e6b799382..bf37690511 100644 --- a/CMake/Modules/ESP32_GCC_options.cmake +++ b/CMake/Modules/ESP32_GCC_options.cmake @@ -19,7 +19,7 @@ macro(nf_set_compile_options) endif() # include any extra options coming from any extra args? - target_compile_options(${NFSCO_TARGET} PUBLIC ${NFSCO__EXTRA_COMPILE_OPTIONS} -Wall -Wextra -Werror -Wno-unused-parameter -Wshadow -Wimplicit-fallthrough -fshort-wchar -fno-builtin -fno-common -fno-exceptions -fcheck-new ) + target_compile_options(${NFSCO_TARGET} PUBLIC ${NFSCO_EXTRA_COMPILE_OPTIONS} -Wall -Wextra -Werror -Wno-sign-compare -Wno-unused-parameter -Wshadow -Wimplicit-fallthrough -fshort-wchar -fno-builtin -fno-common -fno-exceptions -fcheck-new ) # this series has FPU target_compile_definitions(${NFSCO_TARGET} PUBLIC -DTARGET=esp32 -DUSE_FPU=TRUE -DPLATFORM_ESP32) diff --git a/CMake/Modules/ESP32_S2_GCC_options.cmake b/CMake/Modules/ESP32_S2_GCC_options.cmake index 71c8c11f9d..b08180d0b2 100644 --- a/CMake/Modules/ESP32_S2_GCC_options.cmake +++ b/CMake/Modules/ESP32_S2_GCC_options.cmake @@ -18,7 +18,7 @@ macro(nf_set_compile_options) endif() # include any extra options coming from any extra args? - target_compile_options(${NFSCO_TARGET} PUBLIC ${NFSCO__EXTRA_COMPILE_OPTIONS} -Wall -Wextra -Werror -Wno-unused-parameter -Wshadow -Wimplicit-fallthrough -fshort-wchar -fno-builtin -fno-common -fno-exceptions -fcheck-new ) + target_compile_options(${NFSCO_TARGET} PUBLIC ${NFSCO_EXTRA_COMPILE_OPTIONS} -Wall -Wextra -Werror -Wno-sign-compare -Wno-unused-parameter -Wshadow -Wimplicit-fallthrough -fshort-wchar -fno-builtin -fno-common -fno-exceptions -fcheck-new ) # this series has FPU target_compile_definitions(${NFSCO_TARGET} PUBLIC -DTARGET=esp32s2 -DUSE_FPU=TRUE -DPLATFORM_ESP32) diff --git a/CMake/Modules/ESP32_S3_GCC_options.cmake b/CMake/Modules/ESP32_S3_GCC_options.cmake new file mode 100644 index 0000000000..ea647bef3a --- /dev/null +++ b/CMake/Modules/ESP32_S3_GCC_options.cmake @@ -0,0 +1,53 @@ +# +# Copyright (c) .NET Foundation and Contributors +# See LICENSE file in the project root for full license information. +# + +# need to specify linker flags here +set(CMAKE_EXE_LINKER_FLAGS " -Wl,--print-memory-usage " CACHE INTERNAL "executable linker flags") + +# TARGET parameter to set the target that's setting them for +# optional EXTRA_COMPILE_OPTIONS with compile options to be added +macro(nf_set_compile_options) + + # parse arguments + cmake_parse_arguments(NFSCO "" "TARGET" "EXTRA_COMPILE_OPTIONS" ${ARGN}) + + if(NOT NFSCO_TARGET OR "${NFSCO_TARGET}" STREQUAL "") + message(FATAL_ERROR "Need to set TARGET argument when calling nf_set_compile_options()") + endif() + + # include any extra options coming from any extra args? + target_compile_options(${NFSCO_TARGET} PUBLIC ${NFSCO_EXTRA_COMPILE_OPTIONS} -Wall -Wextra -Werror -Wno-sign-compare -Wno-unused-parameter -Wshadow -Wimplicit-fallthrough -fshort-wchar -fno-builtin -fno-common -fno-exceptions -fcheck-new ) + + # this series has FPU + target_compile_definitions(${NFSCO_TARGET} PUBLIC -DTARGET=esp32s3 -DUSE_FPU=TRUE -DPLATFORM_ESP32) + +endmacro() + +# TARGET parameter to set the target that's setting them for +# optional EXTRA_LINK_FLAGS with link flags to be added +macro(nf_set_link_options) + + # parse arguments + cmake_parse_arguments(NFSLO "" "TARGET;EXTRA_LINK_FLAGS" "" ${ARGN}) + + if(NOT NFSLO_TARGET OR "${NFSLO_TARGET}" STREQUAL "") + message(FATAL_ERROR "Need to set TARGET argument when calling nf_set_link_options()") + endif() + + # set optimization linker flags for RELEASE and MinSizeRel + if(CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "MinSizeRel") + set_property(TARGET ${NFSLO_TARGET} APPEND_STRING PROPERTY LINK_FLAGS " -Os ") + endif() + + # include libraries in build + nf_include_libraries_in_build(${NFSLO_TARGET}) + + # set extra linker flags + set_property(TARGET ${NFSLO_TARGET} APPEND_STRING PROPERTY LINK_FLAGS " ${NFSLO_EXTRA_LINK_FLAGS} ") + + # set optimization flags + nf_set_optimization_options(${NFSLO_TARGET}) + +endmacro() diff --git a/CMake/Modules/ESP32_S3_sources.cmake b/CMake/Modules/ESP32_S3_sources.cmake new file mode 100644 index 0000000000..0aa4fd139b --- /dev/null +++ b/CMake/Modules/ESP32_S3_sources.cmake @@ -0,0 +1,4 @@ +# +# Copyright (c) .NET Foundation and Contributors +# See LICENSE file in the project root for full license information. +# diff --git a/CMake/Modules/FindChibiOS.cmake b/CMake/Modules/FindChibiOS.cmake index f700e059b0..f2ae1f3f55 100644 --- a/CMake/Modules/FindChibiOS.cmake +++ b/CMake/Modules/FindChibiOS.cmake @@ -19,8 +19,8 @@ if(TARGET_SERIES_NAME_INDEX EQUAL -1) # series is NOT supported by STM message(FATAL_ERROR "\n\nSorry but the ${TARGET_SERIES} is not supported at this time...\nYou can wait for it to be added, or you might want to contribute by working on a PR for it.\n\n") else() - # series is supported by STM - set(TARGET_VENDOR "STM" CACHE INTERNAL "target vendor is STM") + # series is supported by ST + set(TARGET_VENDOR "ST" CACHE INTERNAL "target vendor is ST") endif() # store the package name for later use @@ -31,7 +31,9 @@ include(CHIBIOS_${TARGET_SERIES}_sources) # and here the GCC options tuned for the target series include(CHIBIOS_${TARGET_SERIES}_GCC_options) -# message("ChibiOS board series is ${TARGET_SERIES}") # debug helper +if (BUILD_VERBOSE) + message("ChibiOS board series is ${TARGET_SERIES}") +endif() # set include directories for ChibiOS list(APPEND CHIBIOS_INCLUDE_DIRS ${chibios_SOURCE_DIR}/os) @@ -51,7 +53,9 @@ list(APPEND CHIBIOS_INCLUDE_DIRS ${chibios_SOURCE_DIR}/os/common/ext/CMSIS/ST/${ # list(APPEND CHIBIOS_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/targets/ChibiOS/_nf-overlay/os/common/startup/ARMCMx/devices/${TARGET_SERIES}) - +list(APPEND CHIBIOS_INCLUDE_DIRS ${CMAKE_BINARY_DIR}/targets/ChibiOS/${TARGET_BOARD}/nanoBooter) +list(APPEND CHIBIOS_INCLUDE_DIRS ${CMAKE_BINARY_DIR}/targets/ChibiOS/${TARGET_BOARD}/nanoCLR) +list(APPEND CHIBIOS_INCLUDE_DIRS ${CMAKE_BINARY_DIR}/targets/ChibiOS/ST/${TARGET_BOARD}) # source files and GCC options according to target vendor and series diff --git a/CMake/Modules/FindESP32_IDF.cmake b/CMake/Modules/FindESP32_IDF.cmake index d07fba87cb..fe947108aa 100644 --- a/CMake/Modules/FindESP32_IDF.cmake +++ b/CMake/Modules/FindESP32_IDF.cmake @@ -16,6 +16,7 @@ list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/${ESP32_CP list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/${ESP32_CPU_TYPE}/${TARGET_SERIES_SHORT}/include) list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/driver/${TARGET_SERIES_SHORT}/include/driver) +list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/driver/${TARGET_SERIES_SHORT}/include) list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/hal/include) list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/hal/${TARGET_SERIES_SHORT}/include) list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/soc/${TARGET_SERIES_SHORT}/include) @@ -61,8 +62,8 @@ list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/esp_rom/in list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/esp_rom/include) list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/esp_rom/${TARGET_SERIES_SHORT}) -# includes specific to ESP32S2 -if(${TARGET_SERIES_SHORT} STREQUAL "esp32s2") +# includes specific to ESP32S2 and ESP32S3 +if(${TARGET_SERIES_SHORT} STREQUAL "esp32s2" OR ${TARGET_SERIES_SHORT} STREQUAL "esp32s3") list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/tinyusb/additions/include) list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/tinyusb/tinyusb/src) list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/freertos/include/freertos) diff --git a/CMake/Modules/FindFreeRTOS.cmake b/CMake/Modules/FindFreeRTOS.cmake index 832505ca81..8f9638db29 100644 --- a/CMake/Modules/FindFreeRTOS.cmake +++ b/CMake/Modules/FindFreeRTOS.cmake @@ -27,7 +27,9 @@ include(FreeRTOS_${TARGET_SERIES}_sources) # and here the GCC options tuned for the target series include(FreeRTOS_${TARGET_SERIES}_GCC_options) -# message("FreeRTOS board series is ${TARGET_SERIES}") # debug helper +if (BUILD_VERBOSE) + message("FreeRTOS board series is ${TARGET_SERIES}") +endif() # set include directories for FreeRTOS list(APPEND FreeRTOS_INCLUDE_DIRS ${freertos_SOURCE_DIR}/include) @@ -60,7 +62,7 @@ foreach(SRC_FILE ${FreeRTOS_SRCS}) ) if (BUILD_VERBOSE) - message("${SRC_FILE} >> ${FreeRTOS_SRC_FILE}") # debug helper + message("${SRC_FILE} >> ${FreeRTOS_SRC_FILE}") endif() list(APPEND FreeRTOS_SOURCES ${FreeRTOS_SRC_FILE}) diff --git a/CMake/Modules/FindGecko_SDK.cmake b/CMake/Modules/FindGecko_SDK.cmake new file mode 100644 index 0000000000..4bdd471b30 --- /dev/null +++ b/CMake/Modules/FindGecko_SDK.cmake @@ -0,0 +1,323 @@ +# +# Copyright (c) .NET Foundation and Contributors +# See LICENSE file in the project root for full license information. +# + +include(FetchContent) + +# include the Gecko HAL and CMSIS for the appropriate series +FetchContent_GetProperties(gecko_sdk) + +# set include directories + +# these are locations for SDK config headers +# the locations for the target need to come before the generic ones +list(APPEND Gecko_SDK_INCLUDE_DIRS ${TARGET_BASE_LOCATION}/autogen) +list(APPEND Gecko_SDK_INCLUDE_DIRS ${TARGET_BASE_LOCATION}/config) +# now the locations for the generic one (to be used in case there are none for the target) +list(APPEND Gecko_SDK_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/targets/AzureRTOS/SiliconLabs/_common/autogen) +list(APPEND Gecko_SDK_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/targets/AzureRTOS/SiliconLabs/_common/config) + +# now all the rest +list(APPEND Gecko_SDK_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/targets/AzureRTOS/SiliconLabs/_include) +list(APPEND Gecko_SDK_INCLUDE_DIRS ${CMAKE_BINARY_DIR}/targets/AzureRTOS) + +# include path to Gecko SDK BSP only if required +# to include Gecko BSP, set the variable GECKO_SDK_BSP in the target CMakeLists.txt +if(GECKO_SDK_BSP) + list(APPEND Gecko_SDK_INCLUDE_DIRS ${gecko_sdk_SOURCE_DIR}/hardware/kit/common/bsp) + list(APPEND Gecko_SDK_INCLUDE_DIRS ${gecko_sdk_SOURCE_DIR}/hardware/kit/${TARGET_BOARD_SHORT}_${TARGET_SERIES}/config) +endif() + +list(APPEND Gecko_SDK_INCLUDE_DIRS ${gecko_sdk_SOURCE_DIR}/platform/common/inc) +list(APPEND Gecko_SDK_INCLUDE_DIRS ${gecko_sdk_SOURCE_DIR}/platform/common/toolchain/inc) +list(APPEND Gecko_SDK_INCLUDE_DIRS ${gecko_sdk_SOURCE_DIR}/hardware/board/inc) +list(APPEND Gecko_SDK_INCLUDE_DIRS ${gecko_sdk_SOURCE_DIR}/platform/CMSIS/Core/Include) +list(APPEND Gecko_SDK_INCLUDE_DIRS ${gecko_sdk_SOURCE_DIR}/platform/CMSIS/RTOS2/Include) +list(APPEND Gecko_SDK_INCLUDE_DIRS ${gecko_sdk_SOURCE_DIR}/platform/service/device_init/inc) +list(APPEND Gecko_SDK_INCLUDE_DIRS ${gecko_sdk_SOURCE_DIR}/platform/emdrv/dmadrv/inc) +list(APPEND Gecko_SDK_INCLUDE_DIRS ${gecko_sdk_SOURCE_DIR}/platform/emdrv/common/inc) +list(APPEND Gecko_SDK_INCLUDE_DIRS ${gecko_sdk_SOURCE_DIR}/platform/emlib/inc) +list(APPEND Gecko_SDK_INCLUDE_DIRS ${gecko_sdk_SOURCE_DIR}/platform/emdrv/gpiointerrupt/inc) +list(APPEND Gecko_SDK_INCLUDE_DIRS ${gecko_sdk_SOURCE_DIR}/platform/service/iostream/inc) +list(APPEND Gecko_SDK_INCLUDE_DIRS ${gecko_sdk_SOURCE_DIR}/platform/service/power_manager/inc) +list(APPEND Gecko_SDK_INCLUDE_DIRS ${gecko_sdk_SOURCE_DIR}/platform/common/toolchain/inc) +list(APPEND Gecko_SDK_INCLUDE_DIRS ${gecko_sdk_SOURCE_DIR}/platform/service/system/inc) +list(APPEND Gecko_SDK_INCLUDE_DIRS ${gecko_sdk_SOURCE_DIR}/platform/service/sleeptimer/inc) +list(APPEND Gecko_SDK_INCLUDE_DIRS ${gecko_sdk_SOURCE_DIR}/platform/emdrv/uartdrv/inc) +list(APPEND Gecko_SDK_INCLUDE_DIRS ${gecko_sdk_SOURCE_DIR}/platform/service/udelay/inc) +list(APPEND Gecko_SDK_INCLUDE_DIRS ${gecko_sdk_SOURCE_DIR}/platform/driver/i2cspm/inc) + +if(GECKO_FEATURE_USBD_HID OR + HAL_WP_USE_USB_CDC OR + GECKO_FEATURE_USBD_WINUSB) + + list(APPEND Gecko_SDK_INCLUDE_DIRS ${gecko_sdk_SOURCE_DIR}/protocol/usb/inc) + list(APPEND Gecko_SDK_INCLUDE_DIRS ${gecko_sdk_SOURCE_DIR}/protocol/usb/src) + list(APPEND Gecko_SDK_INCLUDE_DIRS ${gecko_sdk_SOURCE_DIR}/util/silicon_labs/silabs_core/memory_manager) + list(APPEND Gecko_SDK_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/targets/AzureRTOS/SiliconLabs/_include) + list(APPEND Gecko_SDK_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/targets/AzureRTOS/_common/include) + +endif() + +# general files +set(gecko_sdk_srcs + sl_board_control_gpio.c + sl_board_init.c + sl_memory.c + sl_assert.c + + em_acmp.c + em_adc.c + em_cmu.c + em_core.c + em_cryotimer.c + em_csen.c + em_emu.c + em_ldma.c + em_gpcrc.c + em_gpio.c + em_i2c.c + # em_lcd.c + # em_leuart.c + # em_lesense.c + em_msc.c + em_prs.c + em_rmu.c + em_rtc.c + em_rtcc.c + em_system.c + em_timer.c + em_usart.c + em_vdac.c + em_wdog.c + + # emdrv + dmactrl.c + dmadrv.c + uartdrv.c + + sl_device_init_dcdc_s1.c + sl_device_init_emu_s1.c + sl_device_init_hfxo_s1.c + sl_device_init_hfrco.c + sl_device_init_lfxo_s1.c + sl_device_init_lfrco.c + sl_device_init_nvic.c + sl_power_manager.c + sl_power_manager_hal_s0_s1.c + sl_sleeptimer.c + sl_sleeptimer_hal_rtc.c + sl_sleeptimer_hal_rtcc.c + + sl_sleeptimer_.c + + sl_slist.c + sl_system_init.c + sl_system_kernel.c + sl_system_process_action.c + + sl_udelay.c + sl_udelay_armv6m_gcc.S + sl_uartdrv_init.c + + sl_device_init_clocks_default.c + sl_device_init_clocks.c + sl_event_handler_default.c + sl_event_handler.c + sl_board_default_init_stub.c + sl_i2cspm_init.c + # candidate for replacement with RTOS friendly version + sl_i2cspm.c + sl_string.c + + # nanoFramework implementations + # nano_sl_i2cspm.c + nf_gecko_spi_driver.cpp + + # autogen at target level +) + +#series specific files and includes +if("${TARGET_SERIES}" STREQUAL "EFM32GG11") + + list(APPEND Gecko_SDK_INCLUDE_DIRS ${gecko_sdk_SOURCE_DIR}/platform/Device/SiliconLabs/EFM32GG11B/Include) + + list(APPEND gecko_sdk_srcs system_efm32gg11b.c) + list(APPEND gecko_sdk_srcs startup_efm32gg11b.c) + + if(GECKO_FEATURE_USBD_HID) + + list(APPEND gecko_sdk_srcs sl_usbd_class_hid_azurertos.c) + list(APPEND gecko_sdk_srcs sl_usbd_class_hid_report.c) + list(APPEND gecko_sdk_srcs sl_usbd_class_hid.c) + list(APPEND gecko_sdk_srcs sl_usbd_core_ep.c) + list(APPEND gecko_sdk_srcs sl_usbd_core_azuretos.c) + list(APPEND gecko_sdk_srcs nano_sl_usbd_core.c) + list(APPEND gecko_sdk_srcs sl_usbd_driver_dwc_otg_fs.c) + list(APPEND gecko_sdk_srcs sl_usbd_class_hid_instances.c) + list(APPEND gecko_sdk_srcs sl_usbd_configuration_instances.c) + list(APPEND gecko_sdk_srcs sl_usbd_init.c) + list(APPEND gecko_sdk_srcs sl_malloc.c) + + endif() + + if(HAL_WP_USE_SERIAL OR HAL_USE_ONEWIRE_OPTION) + + list(APPEND gecko_sdk_srcs sl_iostream_usart.c) + list(APPEND gecko_sdk_srcs sl_iostream_uart.c) + list(APPEND gecko_sdk_srcs sl_iostream.c) + list(APPEND gecko_sdk_srcs sl_iostream_handles.c) + list(APPEND gecko_sdk_srcs sl_iostream_init_usart_instances.c) + + endif() + + if(HAL_WP_USE_USB_CDC) + + list(APPEND gecko_sdk_srcs sl_usbd_class_cdc_acm_instances.c) + list(APPEND gecko_sdk_srcs sl_usbd_configuration_instances.c) + list(APPEND gecko_sdk_srcs sl_usbd_driver_dwc_otg_fs.c) + list(APPEND gecko_sdk_srcs sl_usbd_class_cdc_acm.c) + list(APPEND gecko_sdk_srcs sl_usbd_class_cdc.c) + list(APPEND gecko_sdk_srcs sl_usbd_core_ep.c) + list(APPEND gecko_sdk_srcs sl_usbd_core_azuretos.c) + list(APPEND gecko_sdk_srcs nano_sl_usbd_core.c) + list(APPEND gecko_sdk_srcs sl_usbd_configuration_instances.c) + list(APPEND gecko_sdk_srcs sl_usbd_init.c) + list(APPEND gecko_sdk_srcs sl_malloc.c) + + endif() + + if(GECKO_FEATURE_USBD_WINUSB) + + list(APPEND gecko_sdk_srcs sl_usbd_class_vendor_instances.c) + list(APPEND gecko_sdk_srcs sl_usbd_configuration_instances.c) + list(APPEND gecko_sdk_srcs sl_usbd_driver_dwc_otg_fs.c) + list(APPEND gecko_sdk_srcs nano_sl_usbd_core.c) + list(APPEND gecko_sdk_srcs sl_usbd_core_ep.c) + list(APPEND gecko_sdk_srcs sl_usbd_core_azuretos.c) + list(APPEND gecko_sdk_srcs nano_sl_usbd_class_vendor.c) + list(APPEND gecko_sdk_srcs sl_usbd_configuration_instances.c) + list(APPEND gecko_sdk_srcs sl_usbd_init.c) + list(APPEND gecko_sdk_srcs sl_malloc.c) + + endif() + + foreach(src_file ${gecko_sdk_srcs}) + + set(gecko_sdk_src_file src_file-NOTFOUND) + + find_file(gecko_sdk_src_file ${src_file} + PATHS + + # common paths + ${gecko_sdk_SOURCE_DIR}/hardware/board/src + ${gecko_sdk_SOURCE_DIR}/platform/common/src + ${gecko_sdk_SOURCE_DIR}/platform/common/toolchain/src + ${gecko_sdk_SOURCE_DIR}/platform/emdrv/dmadrv/src + ${gecko_sdk_SOURCE_DIR}/platform/emdrv/gpiointerrupt/src + ${gecko_sdk_SOURCE_DIR}/platform/emdrv/uartdrv/src + ${gecko_sdk_SOURCE_DIR}/platform/emlib/src + ${gecko_sdk_SOURCE_DIR}/platform/service/device_init/src + ${gecko_sdk_SOURCE_DIR}/platform/service/iostream/src + ${gecko_sdk_SOURCE_DIR}/platform/service/power_manager/src + ${gecko_sdk_SOURCE_DIR}/platform/service/sleeptimer/src + ${gecko_sdk_SOURCE_DIR}/platform/service/system/src + ${gecko_sdk_SOURCE_DIR}/platform/service/udelay/src + ${gecko_sdk_SOURCE_DIR}/platform/driver/i2cspm/src + ${gecko_sdk_SOURCE_DIR}/util/silicon_labs/silabs_core/memory_manager + + # USBD HID + ${gecko_sdk_SOURCE_DIR}/protocol/usb/src + ${CMAKE_SOURCE_DIR}/targets/AzureRTOS/SiliconLabs/_common + + # device specific paths + ${CMAKE_SOURCE_DIR}/targets/AzureRTOS/SiliconLabs/_common/autogen + + # target series specific + ${gecko_sdk_SOURCE_DIR}/platform/Device/SiliconLabs/EFM32GG11B/Source + + # target specifics + ${TARGET_BASE_LOCATION}/autogen + ${TARGET_BASE_LOCATION}/config + + # nanoFramework implementations + ${CMAKE_SOURCE_DIR}/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.I2c + ${CMAKE_SOURCE_DIR}/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.Spi + + CMAKE_FIND_ROOT_PATH_BOTH + ) + + if (BUILD_VERBOSE) + message("${src_file} >> ${gecko_sdk_src_file}") + endif() + + list(APPEND Gecko_SDK_SOURCES ${gecko_sdk_src_file}) + + endforeach() + + # unset this warning as error required for this source file + set_source_files_properties(${gecko_sdk_SOURCE_DIR}/protocol/usb/src/sl_usbd_driver_dwc_otg_fs.c PROPERTIES COMPILE_FLAGS -Wno-undef) + + list(REMOVE_DUPLICATES Gecko_SDK_INCLUDE_DIRS) + +else() + # series is NOT supported + message(FATAL_ERROR "\n\nSorry but the ${TARGET_SERIES} is not supported at this time...\nYou can wait for it to be added, or you might want to contribute by working on a PR for it.\n\n") +endif() + +include(FindPackageHandleStandardArgs) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Gecko_SDK DEFAULT_MSG Gecko_SDK_INCLUDE_DIRS Gecko_SDK_SOURCES) + +# macro to be called from binutils to add Gecko SDK as a library +# optional EXTRA_INCLUDES with include paths to be added to the library +# optional EXTRA_COMPILE_DEFINITIONS with compiler definitions to be added to the library +macro(nf_add_gecko_sdk) + + # parse arguments + cmake_parse_arguments(NFGCKSDK "" "BUILD_TARGET" "EXTRA_INCLUDES;EXTRA_COMPILE_DEFINITIONS" ${ARGN}) + + if("${NFGCKSDK_BUILD_TARGET}" STREQUAL "${NANOBOOTER_PROJECT_NAME}") + set(CONFIG_FILES_PATH "${TARGET_BASE_LOCATION}/nanoBooter") + elseif("${NFGCKSDK_BUILD_TARGET}" STREQUAL "${NANOCLR_PROJECT_NAME}") + set(CONFIG_FILES_PATH "${TARGET_BASE_LOCATION}/nanoCLR") + endif() + + # add THESE has a library + set(LIB_NAME gecko_sdk_${NFGCKSDK_BUILD_TARGET}) + + add_library( + ${LIB_NAME} STATIC + ${Gecko_SDK_SOURCES} + ) + + target_include_directories( + ${LIB_NAME} PUBLIC + + ${Gecko_SDK_INCLUDE_DIRS} + ${NFGCKSDK_EXTRA_INCLUDES} + ) + + nf_set_compile_options(TARGET ${LIB_NAME} BUILD_TARGET ${NFGCKSDK_BUILD_TARGET}) + nf_set_compile_definitions(TARGET ${LIB_NAME} EXTRA_COMPILE_DEFINITIONS ${NFGCKSDK_EXTRA_COMPILE_DEFINITIONS} BUILD_TARGET ${NFGCKSDK_BUILD_TARGET}) + + # add compile definitions required for WinUSB + if(GECKO_FEATURE_USBD_WINUSB) + nf_set_compile_definitions( + TARGET ${LIB_NAME} + + EXTRA_COMPILE_DEFINITIONS + USBD_CFG_MS_OS_DESC_EN=1 + SL_USBD_VENDOR_MS_EXTENDED_PROPERTIES_QUANTITY=1 + + BUILD_TARGET ${NFGCKSDK_BUILD_TARGET} + ) + endif() + + nf_set_link_options(TARGET ${LIB_NAME}) + + # add alias + add_library("nano::${LIB_NAME}" ALIAS ${LIB_NAME}) + +endmacro() diff --git a/CMake/Modules/FindmbedTLS.cmake b/CMake/Modules/FindMbedTLS.cmake similarity index 90% rename from CMake/Modules/FindmbedTLS.cmake rename to CMake/Modules/FindMbedTLS.cmake index 14d6c33e90..28affd1673 100644 --- a/CMake/Modules/FindmbedTLS.cmake +++ b/CMake/Modules/FindMbedTLS.cmake @@ -7,7 +7,7 @@ include(FetchContent) FetchContent_GetProperties(mbedtls) FetchContent_GetProperties(esp32_idf) -# because of issues when passing the config file as a string when using ExternalProject_Add with mbedTLS +# because of issues when passing the config file as a string when using ExternalProject_Add with MbedTLS # we are replicating their CMakeList here. Actually this is more a simplified version... # List of the required include paths @@ -21,8 +21,8 @@ list(APPEND mbedTLS_INCLUDE_DIRS ${mbedtls_SOURCE_DIR}) list(APPEND mbedTLS_INCLUDE_DIRS ${mbedtls_SOURCE_DIR}/include) -option(USE_PKCS11_HELPER_LIBRARY "Build mbed TLS with the pkcs11-helper library." OFF) -option(ENABLE_ZLIB_SUPPORT "Build mbed TLS with zlib library." OFF) +option(USE_PKCS11_HELPER_LIBRARY "Build Mbed TLS with the pkcs11-helper library." OFF) +option(ENABLE_ZLIB_SUPPORT "Build Mbed TLS with zlib library." OFF) if(ENABLE_ZLIB_SUPPORT) find_package(ZLIB) @@ -123,10 +123,6 @@ if(RTOS_ESP32_CHECK) list(APPEND mbedTLS_SOURCES ${esp32_idf_SOURCE_DIR}/components/mbedtls/mbedtls/library/bignum.c) endif() -# unset this warning as error required for this source file -SET_SOURCE_FILES_PROPERTIES( ${mbedtls_SOURCE_DIR}/library/hmac_drbg.c PROPERTIES COMPILE_FLAGS -Wno-maybe-uninitialized) -SET_SOURCE_FILES_PROPERTIES( ${mbedtls_SOURCE_DIR}/library/x509_crt.c PROPERTIES COMPILE_FLAGS -Wno-maybe-uninitialized) - set(src_x509 certs.c pkcs11.c @@ -190,7 +186,7 @@ foreach(SRC_FILE ${src_tls}) endforeach() -# some sources need to be added from mbedTLS repo or ESP32 depending on build +# some sources need to be added from MbedTLS repo or ESP32 depending on build # check port files specific to ESP32 IDF here 'components/mbedtls/CMakeLists.txt' if(RTOS_ESP32_CHECK) @@ -277,4 +273,4 @@ endif() include(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(mbedTLS DEFAULT_MSG mbedTLS_INCLUDE_DIRS mbedTLS_SOURCES) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(MbedTLS DEFAULT_MSG mbedTLS_INCLUDE_DIRS mbedTLS_SOURCES) diff --git a/CMake/Modules/FindNF_CoreCLR.cmake b/CMake/Modules/FindNF_CoreCLR.cmake index d554e41a37..b9ebc802f3 100644 --- a/CMake/Modules/FindNF_CoreCLR.cmake +++ b/CMake/Modules/FindNF_CoreCLR.cmake @@ -24,14 +24,16 @@ list(APPEND NF_CoreCLR_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/CLR/Debugger) list(APPEND NF_CoreCLR_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/CLR/Helpers/NanoRingBuffer) list(APPEND NF_CoreCLR_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/CLR/Helpers/nanoprintf) list(APPEND NF_CoreCLR_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/CLR/Helpers/Base64) +list(APPEND NF_CoreCLR_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/nanoFramework.Runtime.Events) list(APPEND NF_CoreCLR_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/nanoFramework.Runtime.Native) list(APPEND NF_CoreCLR_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/nanoFramework.System.Collections) list(APPEND NF_CoreCLR_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/DeviceInterfaces/Networking.Sntp) list(APPEND NF_CoreCLR_INCLUDE_DIRS ${TARGET_BASE_LOCATION}) list(APPEND NF_CoreCLR_INCLUDE_DIRS ${TARGET_BASE_LOCATION}/nanoCLR) -list(APPEND NF_CoreCLR_INCLUDE_DIRS ${CMAKE_BINARY_DIR}/targets/${RTOS}/${TARGET_BOARD}) -list(APPEND NF_CoreCLR_INCLUDE_DIRS ${CMAKE_BINARY_DIR}/targets/${RTOS}/${TARGET_BOARD}/nanoCLR) +list(APPEND NF_CoreCLR_INCLUDE_DIRS ${CMAKE_BINARY_DIR}/targets/${RTOS}/${TARGET_VENDOR}) +list(APPEND NF_CoreCLR_INCLUDE_DIRS ${CMAKE_BINARY_DIR}/targets/${RTOS}/${TARGET_VENDOR}/${TARGET_BOARD}) +list(APPEND NF_CoreCLR_INCLUDE_DIRS ${CMAKE_BINARY_DIR}/targets/${RTOS}/${TARGET_VENDOR}/${TARGET_BOARD}/nanoCLR) # source files for nanoFramework Core, CoreLib and CLR startup set(NF_CoreCLR_SRCS @@ -138,10 +140,12 @@ set(NF_CoreCLR_SRCS # CLR stubs Debugger_stub.cpp - + Messaging_stub.cpp + # Helpers nanoprintf.c nanoRingBuffer.c + Info_Safeprintf.cpp # HAL nanoHAL_Time.cpp @@ -155,9 +159,14 @@ set(NF_CoreCLR_SRCS nanoPAL_PerformanceCounters_stubs.cpp # PAL stubs - Async_stubs.cpp COM_stubs.c GenericPort_stubs.c + + # other features + AsyncCompletions.cpp + NativeEventDispatcher.cpp + InterruptHandler.cpp + Hardware.cpp ) # append CRC32, if not already included with Wire Protocol @@ -254,6 +263,7 @@ foreach(SRC_FILE ${NF_CoreCLR_SRCS}) ${CMAKE_SOURCE_DIR}/src/CLR/Helpers/nanoprintf ${CMAKE_SOURCE_DIR}/src/CLR/Helpers/NanoRingBuffer ${CMAKE_SOURCE_DIR}/src/CLR/Helpers/Base64 + ${CMAKE_SOURCE_DIR}/src/CLR/Diagnostics # HAL ${CMAKE_SOURCE_DIR}/src/HAL @@ -326,7 +336,7 @@ macro(nf_add_lib_coreclr) ) else() - nf_set_compile_options(TARGET ${LIB_NAME} BUILD_TARGET ${NANOCLR_PROJECT_NAME}) + nf_set_compile_options(TARGET ${LIB_NAME}) nf_set_compile_definitions(TARGET ${LIB_NAME} EXTRA_COMPILE_DEFINITIONS ${NFALC_EXTRA_COMPILE_DEFINITIONS} BUILD_TARGET ${NANOCLR_PROJECT_NAME}) nf_set_link_options(TARGET ${LIB_NAME}) endif() diff --git a/CMake/Modules/FindNF_Debugger.cmake b/CMake/Modules/FindNF_Debugger.cmake index e96aeb5300..4e0a6f78b5 100644 --- a/CMake/Modules/FindNF_Debugger.cmake +++ b/CMake/Modules/FindNF_Debugger.cmake @@ -18,9 +18,9 @@ set(NF_Debugger_SRCS # add the debugger source file according to the build flavor if(NF_BUILD_RTM) - set(NF_Debugger_SRCS ${NF_Debugger_SRCS} Debugger_minimal.cpp) + list(APPEND NF_Debugger_SRCS ${NF_Debugger_SRCS} Debugger_minimal.cpp) else() - set(NF_Debugger_SRCS ${NF_Debugger_SRCS} Debugger_full.cpp) + list(APPEND NF_Debugger_SRCS ${NF_Debugger_SRCS} Debugger_full.cpp) endif() @@ -86,7 +86,7 @@ macro(nf_add_lib_debugger) ) else() - nf_set_compile_options(TARGET ${LIB_NAME} BUILD_TARGET ${NANOCLR_PROJECT_NAME}) + nf_set_compile_options(TARGET ${LIB_NAME}) nf_set_compile_definitions(TARGET ${LIB_NAME} EXTRA_COMPILE_DEFINITIONS ${NFALD_EXTRA_COMPILE_DEFINITIONS} BUILD_TARGET ${NANOCLR_PROJECT_NAME}) nf_set_link_options(TARGET ${LIB_NAME}) endif() diff --git a/CMake/Modules/FindNF_HALCore.cmake b/CMake/Modules/FindNF_HALCore.cmake index 88aefd149b..d7d597eb8f 100644 --- a/CMake/Modules/FindNF_HALCore.cmake +++ b/CMake/Modules/FindNF_HALCore.cmake @@ -30,7 +30,10 @@ set(NF_HALCore_SRCS ) -# message("BASE_PATH_FOR_PLATFORM >> ${BASE_PATH_FOR_PLATFORM}") # debug helper +if (BUILD_VERBOSE) + message("BASE_PATH_FOR_PLATFORM >> ${BASE_PATH_FOR_PLATFORM}") +endif() + foreach(SRC_FILE ${NF_HALCore_SRCS}) set(NF_HALCore_SRC_FILE SRC_FILE-NOTFOUND) diff --git a/CMake/Modules/FindNF_NativeAssemblies.cmake b/CMake/Modules/FindNF_NativeAssemblies.cmake index 517a0b4fb9..8bf82effc0 100644 --- a/CMake/Modules/FindNF_NativeAssemblies.cmake +++ b/CMake/Modules/FindNF_NativeAssemblies.cmake @@ -31,6 +31,7 @@ option(API_System.Runtime.Serialization "option for System.Runtime.Seria option(API_Windows.Storage "option for Windows.Storage") option(API_nanoFramework.Graphics "option for nanoFramework.Graphics") option(API_nanoFramework.Device.Bluetooth "option for nanoFramework.Device.Bluetooth") +option(API_System.Device.UsbStream "option for System.Device.UsbStream API") # Esp32 only option(API_Hardware.Esp32 "option for Hardware.Esp32") @@ -44,6 +45,10 @@ option(API_Hardware.Stm32 "option for Hardware.Stm32") option(API_nanoFramework.TI.EasyLink "option for nanoFramework.TI.EasyLink API") option(API_nanoFramework.Hardware.TI "option for nanoFramework.Hardware.TI API") +# Silabs Giant Gecko only +option(API_nanoFramework.GiantGecko.Adc "option for nanoFramework.GiantGecko.Adc") +option(API_Hardware.GiantGecko "option for Hardware.GiantGecko") + ################################################################# # macro to perform individual settings to add an API to the build macro(PerformSettingsForApiEntry apiNamespace) @@ -239,6 +244,18 @@ if(API_nanoFramework.Hardware.TI) PerformSettingsForApiEntry("nanoFramework.Hardware.TI") endif() +# nanoFramework.Hardware.TI +if(API_nanoFramework.GiantGecko.Adc) + ##### API name here (doted name) + PerformSettingsForApiEntry("nanoFramework.GiantGecko.Adc") +endif() + +# nanoFramework.Hardware.GiantGecko +if(API_Hardware.GiantGecko) + ##### API name here (doted name) + PerformSettingsForApiEntry("nanoFramework.Hardware.GiantGecko") +endif() + # nanoFramework.Runtime.Events if(API_nanoFramework.Runtime.Events) ##### API name here (doted name) @@ -331,6 +348,12 @@ if(API_System.Device.Wifi) PerformSettingsForApiEntry("System.Device.Wifi") endif() +# System.Device.UsbStream +if(API_System.Device.UsbStream) + ##### API name here (doted name) + PerformSettingsForApiEntry("System.Device.UsbStream") +endif() + # Windows.Storage if(API_Windows.Storage) ##### API name here (doted name) @@ -413,7 +436,7 @@ macro(nf_add_lib_native_assemblies) if(RTOS_ESP32_CHECK) # this is the only one different - nf_set_compile_options(TARGET ${LIB_NAME} BUILD_TARGET ${NANOCLR_PROJECT_NAME}) + nf_set_compile_options(TARGET ${LIB_NAME}) nf_set_compile_definitions( TARGET ${LIB_NAME} @@ -425,7 +448,7 @@ macro(nf_add_lib_native_assemblies) nf_set_link_options(TARGET ${LIB_NAME}) else() - nf_set_compile_options(TARGET ${LIB_NAME} BUILD_TARGET ${NANOCLR_PROJECT_NAME}) + nf_set_compile_options(TARGET ${LIB_NAME}) nf_set_compile_definitions(TARGET ${LIB_NAME} EXTRA_COMPILE_DEFINITIONS ${NFALNA_EXTRA_COMPILE_DEFINITIONS} BUILD_TARGET ${NANOCLR_PROJECT_NAME}) nf_set_link_options(TARGET ${LIB_NAME}) endif() diff --git a/CMake/Modules/FindNF_Network.cmake b/CMake/Modules/FindNF_Network.cmake index 968d99940a..0f503862cb 100644 --- a/CMake/Modules/FindNF_Network.cmake +++ b/CMake/Modules/FindNF_Network.cmake @@ -15,8 +15,9 @@ if(RTOS_AZURERTOS_CHECK) list(APPEND NF_Network_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/PAL/COM/sockets/ssl) list(APPEND NF_Network_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/targets/AzureRTOS/_common/NetX) list(APPEND NF_Network_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/targets/AzureRTOS/_common/include) + list(APPEND NF_Network_INCLUDE_DIRS ${CMAKE_BINARY_DIR}/targets/AzureRTOS/${TARGET_BOARD}) list(APPEND NF_Network_INCLUDE_DIRS ${CMAKE_BINARY_DIR}/targets/AzureRTOS) - + # source files for nanoFramework Networking set(NF_Network_SRCS @@ -187,7 +188,7 @@ if(RTOS_AZURERTOS_CHECK) # ${CMAKE_SOURCE_DIR}/src/PAL/COM/sockets ${CMAKE_SOURCE_DIR}/src/PAL/COM/sockets/ssl - # ${CMAKE_SOURCE_DIR}/src/PAL/COM/sockets/ssl/mbedTLS + # ${CMAKE_SOURCE_DIR}/src/PAL/COM/sockets/ssl/MbedTLS ${NX_THREAD_LOCATION} ${CMAKE_SOURCE_DIR}/targets/AzureRTOS/_common @@ -258,7 +259,7 @@ if(RTOS_AZURERTOS_CHECK) # PATHS # ${CMAKE_SOURCE_DIR}/src/PAL/COM/sockets/ssl - # ${CMAKE_SOURCE_DIR}/src/PAL/COM/sockets/ssl/mbedTLS + # ${CMAKE_SOURCE_DIR}/src/PAL/COM/sockets/ssl/MbedTLS # CMAKE_FIND_ROOT_PATH_BOTH # ) @@ -323,7 +324,7 @@ else() list(APPEND NF_Network_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/DeviceInterfaces/Networking.Sntp) if(USE_SECURITY_MBEDTLS_OPTION) - list(APPEND NF_Network_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/PAL/COM/sockets/ssl/mbedTLS) + list(APPEND NF_Network_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/PAL/COM/sockets/ssl/MbedTLS) list(APPEND NF_Network_INCLUDE_DIRS ${mbedtls_SOURCE_DIR}/include) endif() @@ -405,7 +406,7 @@ else() ${CMAKE_SOURCE_DIR}/src/PAL/COM/sockets ${CMAKE_SOURCE_DIR}/src/PAL/COM/sockets/ssl - ${CMAKE_SOURCE_DIR}/src/PAL/COM/sockets/ssl/mbedTLS + ${CMAKE_SOURCE_DIR}/src/PAL/COM/sockets/ssl/MbedTLS ${CMAKE_SOURCE_DIR}/src/PAL/Lwip ${CMAKE_SOURCE_DIR}/targets/${RTOS}/_common ${CMAKE_SOURCE_DIR}/targets/${RTOS}/_Network @@ -425,7 +426,7 @@ else() if(USE_SECURITY_MBEDTLS_OPTION) - set(NF_Security_Search_Path "${CMAKE_SOURCE_DIR}/src/PAL/COM/sockets/ssl/mbedTLS") + set(NF_Security_Search_Path "${CMAKE_SOURCE_DIR}/src/PAL/COM/sockets/ssl/MbedTLS") # 2nd pass: security files if option is selected foreach(SRC_FILE ${NF_Network_Security_SRCS}) @@ -521,7 +522,7 @@ macro(nf_add_lib_network) ) else() - nf_set_compile_options(TARGET ${LIB_NAME} EXTRA_COMPILE_OPTIONS ${NFALN_EXTRA_COMPILE_OPTIONS} BUILD_TARGET ${NFALN_BUILD_TARGET}) + nf_set_compile_options(TARGET ${LIB_NAME} EXTRA_COMPILE_OPTIONS ${NFALN_EXTRA_COMPILE_OPTIONS}) nf_set_compile_definitions(TARGET ${LIB_NAME} EXTRA_COMPILE_DEFINITIONS ${NFALN_EXTRA_COMPILE_DEFINITIONS} BUILD_TARGET ${NFALN_BUILD_TARGET}) nf_set_link_options(TARGET ${LIB_NAME}) endif() diff --git a/CMake/Modules/FindRPIPicoSdk.cmake b/CMake/Modules/FindRPIPicoSdk.cmake index 406943d537..6392a3d70e 100644 --- a/CMake/Modules/FindRPIPicoSdk.cmake +++ b/CMake/Modules/FindRPIPicoSdk.cmake @@ -20,7 +20,11 @@ foreach(SRC_FILE ${RPI_PICO_SKD_SRCS}) CMAKE_FIND_ROOT_PATH_BOTH ) - # message("${SRC_FILE} >> ${RPI_PICO_SKD_SRC_FILE}") # debug helper + + if (BUILD_VERBOSE) + message("${SRC_FILE} >> ${RPI_PICO_SKD_SRC_FILE}") + endif() + list(APPEND RPI_PICO_SKD_SOURCES ${RPI_PICO_SKD_SRC_FILE}) endforeach() diff --git a/CMake/Modules/FindSystem.Device.Adc.cmake b/CMake/Modules/FindSystem.Device.Adc.cmake index b1c30172a9..9b756bd98b 100644 --- a/CMake/Modules/FindSystem.Device.Adc.cmake +++ b/CMake/Modules/FindSystem.Device.Adc.cmake @@ -8,12 +8,12 @@ set(BASE_PATH_FOR_THIS_MODULE ${BASE_PATH_FOR_CLASS_LIBRARIES_MODULES}/System.De # set include directories -list(APPEND System.Device.Adc_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src/CLR/Core) -list(APPEND System.Device.Adc_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src/CLR/Include) -list(APPEND System.Device.Adc_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src/HAL/Include) -list(APPEND System.Device.Adc_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src/PAL/Include) +list(APPEND System.Device.Adc_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/CLR/Core) +list(APPEND System.Device.Adc_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/CLR/Include) +list(APPEND System.Device.Adc_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/HAL/Include) +list(APPEND System.Device.Adc_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/PAL/Include) list(APPEND System.Device.Adc_INCLUDE_DIRS ${BASE_PATH_FOR_THIS_MODULE}) -list(APPEND System.Device.Adc_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src/System.Device.Adc) +list(APPEND System.Device.Adc_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/System.Device.Adc) # source files set(System.Device.Adc_SRCS @@ -34,7 +34,7 @@ foreach(SRC_FILE ${System.Device.Adc_SRCS}) PATHS ${BASE_PATH_FOR_THIS_MODULE} ${TARGET_BASE_LOCATION} - ${PROJECT_SOURCE_DIR}/src/System.Device.Adc + ${CMAKE_SOURCE_DIR}/src/System.Device.Adc CMAKE_FIND_ROOT_PATH_BOTH ) diff --git a/CMake/Modules/FindSystem.Device.Gpio.cmake b/CMake/Modules/FindSystem.Device.Gpio.cmake index 58823a6542..0250603b8c 100644 --- a/CMake/Modules/FindSystem.Device.Gpio.cmake +++ b/CMake/Modules/FindSystem.Device.Gpio.cmake @@ -23,13 +23,7 @@ set(System.Device.Gpio_SRCS sys_dev_gpio_native_System_Device_Gpio_GpioController.cpp sys_dev_gpio_native_System_Device_Gpio_GpioPin.cpp - - # core source files - AsyncCompletions.cpp - AsyncContinuations.cpp - NativeEventDispatcher.cpp - InterruptHandler.cpp - Hardware.cpp + ) foreach(SRC_FILE ${System.Device.Gpio_SRCS}) @@ -42,12 +36,6 @@ foreach(SRC_FILE ${System.Device.Gpio_SRCS}) ${TARGET_BASE_LOCATION} ${CMAKE_SOURCE_DIR}/src/System.Device.Gpio - # core source files - ${CMAKE_SOURCE_DIR}/src/PAL/AsyncProcCall - ${CMAKE_SOURCE_DIR}/src/CLR/Core/NativeEventDispatcher - ${CMAKE_SOURCE_DIR}/src/CLR/Core/InterruptHandler - ${CMAKE_SOURCE_DIR}/src/CLR/Core/Hardware - CMAKE_FIND_ROOT_PATH_BOTH ) diff --git a/CMake/Modules/FindSystem.Device.Pwm.cmake b/CMake/Modules/FindSystem.Device.Pwm.cmake index c018c6434b..6b437d7538 100644 --- a/CMake/Modules/FindSystem.Device.Pwm.cmake +++ b/CMake/Modules/FindSystem.Device.Pwm.cmake @@ -8,12 +8,12 @@ set(BASE_PATH_FOR_THIS_MODULE ${BASE_PATH_FOR_CLASS_LIBRARIES_MODULES}/System.De # set include directories -list(APPEND System.Device.Pwm_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src/CLR/Core) -list(APPEND System.Device.Pwm_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src/CLR/Include) -list(APPEND System.Device.Pwm_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src/HAL/Include) -list(APPEND System.Device.Pwm_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src/PAL/Include) +list(APPEND System.Device.Pwm_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/CLR/Core) +list(APPEND System.Device.Pwm_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/CLR/Include) +list(APPEND System.Device.Pwm_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/HAL/Include) +list(APPEND System.Device.Pwm_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/PAL/Include) list(APPEND System.Device.Pwm_INCLUDE_DIRS ${BASE_PATH_FOR_THIS_MODULE}) -list(APPEND System.Device.Pwm_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src/System.Device.Pwm) +list(APPEND System.Device.Pwm_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/System.Device.Pwm) # source files set(System.Device.Pwm_SRCS @@ -22,7 +22,8 @@ set(System.Device.Pwm_SRCS sys_dev_pwm_native_System_Device_Pwm_PwmChannel.cpp - + + target_system_device_pwm_config.cpp ) foreach(SRC_FILE ${System.Device.Pwm_SRCS}) @@ -31,11 +32,15 @@ foreach(SRC_FILE ${System.Device.Pwm_SRCS}) PATHS ${BASE_PATH_FOR_THIS_MODULE} ${TARGET_BASE_LOCATION} - ${PROJECT_SOURCE_DIR}/src/System.Device.Pwm + ${CMAKE_SOURCE_DIR}/src/System.Device.Pwm CMAKE_FIND_ROOT_PATH_BOTH ) - # message("${SRC_FILE} >> ${System.Device.Pwm_SRC_FILE}") # debug helper + + if (BUILD_VERBOSE) + message("${SRC_FILE} >> ${System.Device.Pwm_SRC_FILE}") + endif() + list(APPEND System.Device.Pwm_SOURCES ${System.Device.Pwm_SRC_FILE}) endforeach() diff --git a/CMake/Modules/FindSystem.Device.Spi.cmake b/CMake/Modules/FindSystem.Device.Spi.cmake index bb83c8b92f..d5d47cd77e 100644 --- a/CMake/Modules/FindSystem.Device.Spi.cmake +++ b/CMake/Modules/FindSystem.Device.Spi.cmake @@ -35,7 +35,11 @@ foreach(SRC_FILE ${System.Device.Spi_SRCS}) CMAKE_FIND_ROOT_PATH_BOTH ) - # message("${SRC_FILE} >> ${System.Device.Spi_SRC_FILE}") # debug helper + + if (BUILD_VERBOSE) + message("${SRC_FILE} >> ${System.Device.Spi_SRC_FILE}") + endif() + list(APPEND System.Device.Spi_SOURCES ${System.Device.Spi_SRC_FILE}) endforeach() diff --git a/CMake/Modules/FindSystem.Device.UsbStream.cmake b/CMake/Modules/FindSystem.Device.UsbStream.cmake new file mode 100644 index 0000000000..c55694f60c --- /dev/null +++ b/CMake/Modules/FindSystem.Device.UsbStream.cmake @@ -0,0 +1,50 @@ +# +# 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}/System.Device.UsbStream) + + +# set include directories +list(APPEND System.Device.UsbStream_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src/CLR/Core) +list(APPEND System.Device.UsbStream_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src/CLR/Include) +list(APPEND System.Device.UsbStream_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src/HAL/Include) +list(APPEND System.Device.UsbStream_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src/PAL/Include) +list(APPEND System.Device.UsbStream_INCLUDE_DIRS ${BASE_PATH_FOR_THIS_MODULE}) +list(APPEND System.Device.UsbStream_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src/System.Device.UsbStream) + +# source files +set(System.Device.UsbStream_SRCS + + sys_dev_usbstream_native.cpp + + sys_dev_usbstream_native_System_Device_Usb_UsbStream.cpp + +) + +foreach(SRC_FILE ${System.Device.UsbStream_SRCS}) + + set(System.Device.UsbStream_SRC_FILE SRC_FILE-NOTFOUND) + + find_file(System.Device.UsbStream_SRC_FILE ${SRC_FILE} + PATHS + ${BASE_PATH_FOR_THIS_MODULE} + ${TARGET_BASE_LOCATION} + ${PROJECT_SOURCE_DIR}/src/System.Device.UsbStream + + CMAKE_FIND_ROOT_PATH_BOTH + ) + + if (BUILD_VERBOSE) + message("${SRC_FILE} >> ${System.Device.UsbStream_SRC_FILE}") + endif() + + list(APPEND System.Device.UsbStream_SOURCES ${System.Device.UsbStream_SRC_FILE}) + +endforeach() + +include(FindPackageHandleStandardArgs) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS(System.Device.UsbStream DEFAULT_MSG System.Device.UsbStream_INCLUDE_DIRS System.Device.UsbStream_SOURCES) diff --git a/CMake/Modules/FindSystem.Device.Wifi.cmake b/CMake/Modules/FindSystem.Device.Wifi.cmake index d11de30044..9de343a640 100644 --- a/CMake/Modules/FindSystem.Device.Wifi.cmake +++ b/CMake/Modules/FindSystem.Device.Wifi.cmake @@ -9,7 +9,7 @@ set(BASE_PATH_FOR_THIS_MODULE ${BASE_PATH_FOR_CLASS_LIBRARIES_MODULES}/System.De # set include directories list(APPEND System.Device.Wifi_INCLUDE_DIRS ${BASE_PATH_FOR_THIS_MODULE}) -list(APPEND System.Device.Wifi_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src/System.Device.Wifi) +list(APPEND System.Device.Wifi_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/System.Device.Wifi) # source files diff --git a/CMake/Modules/FindSystem.IO.FileSystem.cmake b/CMake/Modules/FindSystem.IO.FileSystem.cmake index 0fcd492c2c..20ced4843e 100644 --- a/CMake/Modules/FindSystem.IO.FileSystem.cmake +++ b/CMake/Modules/FindSystem.IO.FileSystem.cmake @@ -15,7 +15,7 @@ endif() # set include directories list(APPEND System.IO.FileSystem_INCLUDE_DIRS ${BASE_PATH_FOR_THIS_MODULE}) list(APPEND System.IO.FileSystem_INCLUDE_DIRS ${TARGET_BASE_LOCATION}/Include) -list(APPEND System.IO.FileSystem_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src/System.IO.FileSystem) +list(APPEND System.IO.FileSystem_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/System.IO.FileSystem) # source files set(System.IO.FileSystem_SRCS @@ -39,7 +39,7 @@ foreach(SRC_FILE ${System.IO.FileSystem_SRCS}) ${BASE_PATH_FOR_THIS_MODULE} ${TARGET_BASE_LOCATION} ${PROJECT_COMMON_PATH} - ${PROJECT_SOURCE_DIR}/src/System.IO.FileSystem + ${CMAKE_SOURCE_DIR}/src/System.IO.FileSystem CMAKE_FIND_ROOT_PATH_BOTH ) diff --git a/CMake/Modules/FindSystem.IO.Ports.cmake b/CMake/Modules/FindSystem.IO.Ports.cmake index 8aeaaeae39..5b39fc3546 100644 --- a/CMake/Modules/FindSystem.IO.Ports.cmake +++ b/CMake/Modules/FindSystem.IO.Ports.cmake @@ -8,12 +8,12 @@ set(BASE_PATH_FOR_THIS_MODULE ${BASE_PATH_FOR_CLASS_LIBRARIES_MODULES}/System.IO # set include directories -list(APPEND System.IO.Ports_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src/CLR/Core) -list(APPEND System.IO.Ports_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src/CLR/Include) -list(APPEND System.IO.Ports_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src/HAL/Include) -list(APPEND System.IO.Ports_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src/PAL/Include) +list(APPEND System.IO.Ports_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/CLR/Core) +list(APPEND System.IO.Ports_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/CLR/Include) +list(APPEND System.IO.Ports_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/HAL/Include) +list(APPEND System.IO.Ports_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/PAL/Include) list(APPEND System.IO.Ports_INCLUDE_DIRS ${BASE_PATH_FOR_THIS_MODULE}) -list(APPEND System.IO.Ports_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src/System.IO.Ports) +list(APPEND System.IO.Ports_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/System.IO.Ports) # source files set(System.IO.Ports_SRCS @@ -31,11 +31,15 @@ foreach(SRC_FILE ${System.IO.Ports_SRCS}) PATHS ${BASE_PATH_FOR_THIS_MODULE} ${TARGET_BASE_LOCATION} - ${PROJECT_SOURCE_DIR}/src/System.IO.Ports + ${CMAKE_SOURCE_DIR}/src/System.IO.Ports CMAKE_FIND_ROOT_PATH_BOTH ) - # message("${SRC_FILE} >> ${System.IO.Ports_SRC_FILE}") # debug helper + + if (BUILD_VERBOSE) + message("${SRC_FILE} >> ${System.IO.Ports_SRC_FILE}") + endif() + list(APPEND System.IO.Ports_SOURCES ${System.IO.Ports_SRC_FILE}) endforeach() diff --git a/CMake/Modules/FindSystem.Runtime.Serialization.cmake b/CMake/Modules/FindSystem.Runtime.Serialization.cmake index c9a2d1ce06..90d5dd9aa5 100644 --- a/CMake/Modules/FindSystem.Runtime.Serialization.cmake +++ b/CMake/Modules/FindSystem.Runtime.Serialization.cmake @@ -8,12 +8,12 @@ set(BASE_PATH_FOR_THIS_MODULE ${BASE_PATH_FOR_CLASS_LIBRARIES_MODULES}/System.Ru # set include directories -list(APPEND System.Runtime.Serialization_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src/CLR/Core) -list(APPEND System.Runtime.Serialization_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src/CLR/Include) -list(APPEND System.Runtime.Serialization_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src/HAL/Include) -list(APPEND System.Runtime.Serialization_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src/PAL/Include) +list(APPEND System.Runtime.Serialization_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/CLR/Core) +list(APPEND System.Runtime.Serialization_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/CLR/Include) +list(APPEND System.Runtime.Serialization_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/HAL/Include) +list(APPEND System.Runtime.Serialization_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/PAL/Include) list(APPEND System.Runtime.Serialization_INCLUDE_DIRS ${BASE_PATH_FOR_THIS_MODULE}) -list(APPEND System.Runtime.Serialization_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src/System.Runtime.Serialization) +list(APPEND System.Runtime.Serialization_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/System.Runtime.Serialization) # source files set(System.Runtime.Serialization_SRCS @@ -32,7 +32,7 @@ foreach(SRC_FILE ${System.Runtime.Serialization_SRCS}) PATHS ${BASE_PATH_FOR_THIS_MODULE} ${TARGET_BASE_LOCATION} - ${PROJECT_SOURCE_DIR}/src/System.Runtime.Serialization + ${CMAKE_SOURCE_DIR}/src/System.Runtime.Serialization CMAKE_FIND_ROOT_PATH_BOTH ) diff --git a/CMake/Modules/FindWireProtocol.cmake b/CMake/Modules/FindWireProtocol.cmake index 04cc13af71..88fc237788 100644 --- a/CMake/Modules/FindWireProtocol.cmake +++ b/CMake/Modules/FindWireProtocol.cmake @@ -31,7 +31,9 @@ if(NF_WP_TRACE_ALL) math(EXPR WP_TRACE_MASK "16 + 8 + 4 + 2 + 1") endif() -message(STATUS "Wire Protocol TRACE_MASK is '${WP_TRACE_MASK}'") # debug helper +if (BUILD_VERBOSE) + message(STATUS "Wire Protocol TRACE_MASK is '${WP_TRACE_MASK}'") +endif() # set include directories for Wire Protocol list(APPEND WireProtocol_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/CLR/Include) @@ -108,7 +110,7 @@ macro(nf_add_lib_wireprotocol) ) else() - nf_set_compile_options(TARGET ${LIB_NAME} BUILD_TARGET ${NANOCLR_PROJECT_NAME}) + nf_set_compile_options(TARGET ${LIB_NAME}) nf_set_compile_definitions(TARGET ${LIB_NAME} EXTRA_COMPILE_DEFINITIONS ${NFAWP_EXTRA_COMPILE_DEFINITIONS} BUILD_TARGET ${NANOCLR_PROJECT_NAME}) nf_set_link_options(TARGET ${LIB_NAME}) endif() diff --git a/CMake/Modules/FindnanoFramework.Device.Bluetooth.cmake b/CMake/Modules/FindnanoFramework.Device.Bluetooth.cmake index 2dbc5cf137..2afffb1b8c 100644 --- a/CMake/Modules/FindnanoFramework.Device.Bluetooth.cmake +++ b/CMake/Modules/FindnanoFramework.Device.Bluetooth.cmake @@ -7,10 +7,10 @@ set(BASE_PATH_FOR_THIS_MODULE ${BASE_PATH_FOR_CLASS_LIBRARIES_MODULES}/nanoFramework.Device.Bluetooth) # set include directories -list(APPEND nanoFramework.Device.Bluetooth_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src/CLR/Core) -list(APPEND nanoFramework.Device.Bluetooth_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src/CLR/Include) -list(APPEND nanoFramework.Device.Bluetooth_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src/HAL/Include) -list(APPEND nanoFramework.Device.Bluetooth_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src/PAL/Include) +list(APPEND nanoFramework.Device.Bluetooth_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/CLR/Core) +list(APPEND nanoFramework.Device.Bluetooth_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/CLR/Include) +list(APPEND nanoFramework.Device.Bluetooth_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/HAL/Include) +list(APPEND nanoFramework.Device.Bluetooth_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/PAL/Include) list(APPEND nanoFramework.Device.Bluetooth_INCLUDE_DIRS ${BASE_PATH_FOR_THIS_MODULE}) # set include directories for Esp32 IDF @@ -30,18 +30,19 @@ set(nanoFramework.Device.Bluetooth_SRCS sys_dev_ble_native.cpp - # Client + # Server sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttributeProfile_GattServiceProvider.cpp sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttributeProfile_GattReadRequest.cpp sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttributeProfile_GattWriteRequest.cpp sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttributeProfile_GattLocalCharacteristic.cpp sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothLEAdvertisementWatcher.cpp - # Central + # Client / Central sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothLEDevice.cpp sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothNanoDevice.cpp # Others + sys_dev_ble_native_nanoFramework_Device_Bluetooth_Security.cpp esp32_nimble.cpp nimble_utils.cpp ) @@ -52,11 +53,15 @@ foreach(SRC_FILE ${nanoFramework.Device.Bluetooth_SRCS}) PATHS ${BASE_PATH_FOR_THIS_MODULE} ${TARGET_BASE_LOCATION} - ${PROJECT_SOURCE_DIR}/src/nanoFramework.Device.Bluetooth + ${CMAKE_SOURCE_DIR}/src/nanoFramework.Device.Bluetooth CMAKE_FIND_ROOT_PATH_BOTH ) - # message("${SRC_FILE} >> ${nanoFramework.Device.Bluetooth_SRC_FILE}") # debug helper + + if (BUILD_VERBOSE) + message("${SRC_FILE} >> ${nanoFramework.Device.Bluetooth_SRC_FILE}") + endif() + list(APPEND nanoFramework.Device.Bluetooth_SOURCES ${nanoFramework.Device.Bluetooth_SRC_FILE}) endforeach() diff --git a/CMake/Modules/FindnanoFramework.GiantGecko.Adc.cmake b/CMake/Modules/FindnanoFramework.GiantGecko.Adc.cmake new file mode 100644 index 0000000000..7c51d1fe2a --- /dev/null +++ b/CMake/Modules/FindnanoFramework.GiantGecko.Adc.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.GiantGecko.Adc) + +# set include directories +list(APPEND nanoFramework.GiantGecko.Adc_INCLUDE_DIRS ${BASE_PATH_FOR_THIS_MODULE}) +list(APPEND nanoFramework.GiantGecko.Adc_INCLUDE_DIRS ${TARGET_BASE_LOCATION}) + +# source files +set(nanoFramework.GiantGecko.Adc_SRCS + + nano_gg_adc_native.cpp + + nano_gg_adc_native_nanoFramework_GiantGecko_Adc_AdcChannel.cpp + nano_gg_adc_native_nanoFramework_GiantGecko_Adc_AdcController.cpp + + target_nano_gg_adc_config.cpp +) + +foreach(SRC_FILE ${nanoFramework.GiantGecko.Adc_SRCS}) + + set(nanoFramework.GiantGecko.Adc_SRC_FILE SRC_FILE-NOTFOUND) + + find_file(nanoFramework.GiantGecko.Adc_SRC_FILE ${SRC_FILE} + PATHS + ${BASE_PATH_FOR_THIS_MODULE} + ${TARGET_BASE_LOCATION} + ${PROJECT_SOURCE_DIR}/src/nanoFramework.GiantGecko.Adc + + CMAKE_FIND_ROOT_PATH_BOTH + ) + + if (BUILD_VERBOSE) + message("${SRC_FILE} >> ${nanoFramework.GiantGecko.Adc_SRC_FILE}") + endif() + + list(APPEND nanoFramework.GiantGecko.Adc_SOURCES ${nanoFramework.GiantGecko.Adc_SRC_FILE}) + +endforeach() + +include(FindPackageHandleStandardArgs) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS(nanoFramework.GiantGecko.Adc DEFAULT_MSG nanoFramework.GiantGecko.Adc_INCLUDE_DIRS nanoFramework.GiantGecko.Adc_SOURCES) diff --git a/CMake/Modules/FindnanoFramework.Hardware.Esp32.cmake b/CMake/Modules/FindnanoFramework.Hardware.Esp32.cmake index b99e6056c9..c70c5d39e7 100644 --- a/CMake/Modules/FindnanoFramework.Hardware.Esp32.cmake +++ b/CMake/Modules/FindnanoFramework.Hardware.Esp32.cmake @@ -23,6 +23,8 @@ set(nanoFramework.Hardware.Esp32_SRCS nanoFramework_hardware_esp32_native_Hardware_Esp32_HighResTimer.cpp nanoFramework_hardware_esp32_native_Hardware_Esp32_Configuration.cpp nanoFramework_hardware_esp32_native_Hardware_Esp32_NativeMemory.cpp + nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad.cpp + nanoFramework_hardware_esp32_native_System_Device_Gpio_GpioPulseCounter.cpp ) foreach(SRC_FILE ${nanoFramework.Hardware.Esp32_SRCS}) diff --git a/CMake/Modules/FindnanoFramework.Hardware.GiantGecko.cmake b/CMake/Modules/FindnanoFramework.Hardware.GiantGecko.cmake new file mode 100644 index 0000000000..0f9d8d11b2 --- /dev/null +++ b/CMake/Modules/FindnanoFramework.Hardware.GiantGecko.cmake @@ -0,0 +1,46 @@ +# +# 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.GiantGecko) + + +# set include directories +list(APPEND nanoFramework.Hardware.GiantGecko_INCLUDE_DIRS ${BASE_PATH_FOR_THIS_MODULE}) + +# source files +set(nanoFramework.Hardware.GiantGecko_SRCS + + nf_hardware_giantgecko.cpp + + nf_hardware_giantgecko_nanoFramework_Hardware_GiantGecko_GpioConfiguration.cpp + nf_hardware_giantgecko_nanoFramework_Hardware_GiantGecko_Power.cpp + nf_hardware_giantgecko_nanoFramework_Hardware_GiantGecko_RTC.cpp + nf_hardware_giantgecko_nanoFramework_Hardware_GiantGecko_Utilities.cpp + +) + +foreach(SRC_FILE ${nanoFramework.Hardware.GiantGecko_SRCS}) + + set(nanoFramework.Hardware.GiantGecko_SRC_FILE SRC_FILE-NOTFOUND) + + find_file(nanoFramework.Hardware.GiantGecko_SRC_FILE ${SRC_FILE} + PATHS + ${BASE_PATH_FOR_THIS_MODULE} + + CMAKE_FIND_ROOT_PATH_BOTH + ) + + if (BUILD_VERBOSE) + message("${SRC_FILE} >> ${nanoFramework.Hardware.GiantGecko_SRC_FILE}") + endif() + + list(APPEND nanoFramework.Hardware.GiantGecko_SOURCES ${nanoFramework.Hardware.GiantGecko_SRC_FILE}) + +endforeach() + +include(FindPackageHandleStandardArgs) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS(nanoFramework.Hardware.GiantGecko DEFAULT_MSG nanoFramework.Hardware.GiantGecko_INCLUDE_DIRS nanoFramework.Hardware.GiantGecko_SOURCES) diff --git a/CMake/Modules/FindnanoFramework.Hardware.Stm32.cmake b/CMake/Modules/FindnanoFramework.Hardware.Stm32.cmake index d3ae7eaa57..ff9e5255c7 100644 --- a/CMake/Modules/FindnanoFramework.Hardware.Stm32.cmake +++ b/CMake/Modules/FindnanoFramework.Hardware.Stm32.cmake @@ -10,6 +10,8 @@ set(BASE_PATH_FOR_THIS_MODULE "${BASE_PATH_FOR_CLASS_LIBRARIES_MODULES}/nanoFram # set include directories list(APPEND nanoFramework.Hardware.Stm32_INCLUDE_DIRS "${BASE_PATH_FOR_THIS_MODULE}") +list(APPEND nanoFramework.Hardware.Stm32_INCLUDE_DIRS ${BASE_PATH_FOR_CLASS_LIBRARIES_MODULES}/System.Device.Adc) +list(APPEND nanoFramework.Hardware.Stm32_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/System.Device.Adc) # source files @@ -17,6 +19,7 @@ set(nanoFramework.Hardware.Stm32_SRCS nf_hardware_stm32_native.cpp nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_BackupMemory.cpp + nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_Configuration.cpp nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_Power.cpp nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_RTC.cpp nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_Utilities.cpp diff --git a/CMake/Modules/FindnanoFramework.Runtime.Events.cmake b/CMake/Modules/FindnanoFramework.Runtime.Events.cmake index e2cb9bebe9..8ce1b6ba0b 100644 --- a/CMake/Modules/FindnanoFramework.Runtime.Events.cmake +++ b/CMake/Modules/FindnanoFramework.Runtime.Events.cmake @@ -25,7 +25,6 @@ set(nanoFramework.Runtime.Events_SRCS nf_rt_events_native.cpp # source files - AsyncCompletions.cpp AsyncContinuations.cpp nanoPAL_Events_functions.cpp diff --git a/CMake/Modules/FreeRTOS_IMXRT10xx_GCC_options.cmake b/CMake/Modules/FreeRTOS_IMXRT10xx_GCC_options.cmake index 5f9e4d4443..26beb30156 100644 --- a/CMake/Modules/FreeRTOS_IMXRT10xx_GCC_options.cmake +++ b/CMake/Modules/FreeRTOS_IMXRT10xx_GCC_options.cmake @@ -28,7 +28,7 @@ macro(nf_set_compile_options) # include any extra options comming from any extra args? # TODO: removed -Wundef until fix with FatFS is merged (https://github.com/abbrev/fatfs/pull/8) - target_compile_options(${NFSCO_TARGET} PUBLIC ${NFSCO__EXTRA_COMPILE_OPTIONS} -mthumb -mcpu=cortex-m7 -mfpu=fpv5-sp-d16 -mfloat-abi=hard -mabi=aapcs -nostdlib -Wall -Wextra -Werror -ffunction-sections -fshort-wchar -falign-functions=16 -fdata-sections -fno-builtin -fno-common -fomit-frame-pointer -mlong-calls -fdollars-in-identifiers -fno-exceptions -fno-unroll-loops -frounding-math -fsignaling-nans -ffloat-store -fno-math-errno -ftree-vectorize -fcheck-new ) + target_compile_options(${NFSCO_TARGET} PUBLIC ${NFSCO_EXTRA_COMPILE_OPTIONS} -mthumb -mcpu=cortex-m7 -mfpu=fpv5-sp-d16 -mfloat-abi=hard -mabi=aapcs -nostdlib -Wall -Wextra -Werror -ffunction-sections -fshort-wchar -falign-functions=16 -fdata-sections -fno-builtin -fno-common -fomit-frame-pointer -mlong-calls -fdollars-in-identifiers -fno-exceptions -fno-unroll-loops -frounding-math -fsignaling-nans -ffloat-store -fno-math-errno -ftree-vectorize -fcheck-new ) # this series has FPU target_compile_definitions(${NFSCO_TARGET} PUBLIC -DPLATFORM_ARM -DCORTEX_USE_FPU=TRUE -DUSE_FPU=TRUE) diff --git a/CMake/Modules/Gecko_SDK.cmake b/CMake/Modules/Gecko_SDK.cmake new file mode 100644 index 0000000000..38d280f911 --- /dev/null +++ b/CMake/Modules/Gecko_SDK.cmake @@ -0,0 +1,16 @@ +# +# Copyright (c) .NET Foundation and Contributors +# See LICENSE file in the project root for full license information. +# + +include(FetchContent) + +macro(ProcessGSDKPackage) + + # process target name, which is in the format "SL_xxxxxxxx" + string(REPLACE "SL_" "SL" TARGET_BOARD_SHORT "${TARGET_BOARD}") + + # store the target name for later use + set(TARGET_BOARD_SHORT ${TARGET_BOARD_SHORT} CACHE INTERNAL "Gecko SDK board short name") + +endmacro() diff --git a/CMake/Modules/STM32_CubePackage.cmake b/CMake/Modules/STM32_CubePackage.cmake index 794d9bd158..dc2db2d65a 100644 --- a/CMake/Modules/STM32_CubePackage.cmake +++ b/CMake/Modules/STM32_CubePackage.cmake @@ -192,7 +192,7 @@ macro(nf_add_stm32_cube) ${NFSTMPKG_EXTRA_INCLUDES} ) - nf_set_compile_options(TARGET ${LIB_NAME} BUILD_TARGET ${NFSTMPKG_BUILD_TARGET}) + nf_set_compile_options(TARGET ${LIB_NAME}) nf_set_compile_definitions(TARGET ${LIB_NAME} EXTRA_COMPILE_DEFINITIONS ${NFSTMPKG_EXTRA_COMPILE_DEFINITIONS} BUILD_TARGET ${NFSTMPKG_BUILD_TARGET}) nf_set_link_options(TARGET ${LIB_NAME}) diff --git a/CMake/Modules/TI_SimpleLink_CC13X2_GCC_options.cmake b/CMake/Modules/TI_SimpleLink_CC13X2_GCC_options.cmake index 5b92f0e815..9da6872edf 100644 --- a/CMake/Modules/TI_SimpleLink_CC13X2_GCC_options.cmake +++ b/CMake/Modules/TI_SimpleLink_CC13X2_GCC_options.cmake @@ -30,7 +30,7 @@ macro(nf_set_compile_options) # include any extra options coming from any extra args? - target_compile_options(${NFSCO_TARGET} PUBLIC ${NFSCO__EXTRA_COMPILE_OPTIONS} -march=armv7e-m -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mabi=aapcs -gstrict-dwarf -nostdlib -Wall -Wextra -Werror -Wundef -Wshadow -Wimplicit-fallthrough -w -static -ffunction-sections -falign-functions=16 -fdata-sections -fno-builtin -fno-common -fsingle-precision-constant -fomit-frame-pointer -mlong-calls -fdollars-in-identifiers -fno-exceptions -fno-unroll-loops -ffast-math -ftree-vectorize -fcheck-new -fno-rtti -fno-use-cxa-atexit -fno-threadsafe-statics) + target_compile_options(${NFSCO_TARGET} PUBLIC ${NFSCO_EXTRA_COMPILE_OPTIONS} -march=armv7e-m -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mabi=aapcs -gstrict-dwarf -nostdlib -Wall -Wextra -Werror -Wundef -Wshadow -Wimplicit-fallthrough -w -static -ffunction-sections -falign-functions=16 -fdata-sections -fno-builtin -fno-common -fsingle-precision-constant -fomit-frame-pointer -mlong-calls -fdollars-in-identifiers -fno-exceptions -fno-unroll-loops -ffast-math -ftree-vectorize -fcheck-new -fno-rtti -fno-use-cxa-atexit -fno-threadsafe-statics) # this series has FPU target_compile_definitions(${NFSCO_TARGET} PUBLIC -DPLATFORM_ARM -DCORTEX_USE_FPU=TRUE -DUSE_FPU=TRUE) diff --git a/CMake/Modules/TI_SimpleLink_CC32xx_GCC_options.cmake b/CMake/Modules/TI_SimpleLink_CC32xx_GCC_options.cmake index fcdb5d8166..22b4eca30e 100644 --- a/CMake/Modules/TI_SimpleLink_CC32xx_GCC_options.cmake +++ b/CMake/Modules/TI_SimpleLink_CC32xx_GCC_options.cmake @@ -28,7 +28,7 @@ macro(nf_set_compile_options) # include any extra options coming from any extra args? - target_compile_options(${NFSCO_TARGET} PUBLIC ${NFSCO__EXTRA_COMPILE_OPTIONS} -march=armv7e-m -mthumb -mcpu=cortex-m4 -mfloat-abi=soft -mabi=aapcs -gstrict-dwarf -nostdlib -Wall -Wextra -Werror -Wundef -Wshadow -Wimplicit-fallthrough -w -static -ffunction-sections -falign-functions=16 -fdata-sections -fno-builtin -fno-common -fsingle-precision-constant -fomit-frame-pointer -mlong-calls -fdollars-in-identifiers -fno-exceptions -fno-unroll-loops -ffast-math -ftree-vectorize -fcheck-new -fno-rtti -fno-use-cxa-atexit -fno-threadsafe-statics) + target_compile_options(${NFSCO_TARGET} PUBLIC ${NFSCO_EXTRA_COMPILE_OPTIONS} -march=armv7e-m -mthumb -mcpu=cortex-m4 -mfloat-abi=soft -mabi=aapcs -gstrict-dwarf -nostdlib -Wall -Wextra -Werror -Wundef -Wshadow -Wimplicit-fallthrough -w -static -ffunction-sections -falign-functions=16 -fdata-sections -fno-builtin -fno-common -fsingle-precision-constant -fomit-frame-pointer -mlong-calls -fdollars-in-identifiers -fno-exceptions -fno-unroll-loops -ffast-math -ftree-vectorize -fcheck-new -fno-rtti -fno-use-cxa-atexit -fno-threadsafe-statics) # this series has FPU target_compile_definitions(${NFSCO_TARGET} PUBLIC -DPLATFORM_ARM -DCORTEX_USE_FPU=TRUE -DUSE_FPU=TRUE) diff --git a/CMake/TI_SimpleLink_target_os.h.in b/CMake/TI_SimpleLink_target_os.h.in index 3f5f601ada..26063d19e1 100644 --- a/CMake/TI_SimpleLink_target_os.h.in +++ b/CMake/TI_SimpleLink_target_os.h.in @@ -16,13 +16,16 @@ #define VERSION_BUILD @nanoFramework_VERSION_PATCH@U #define VERSION_REVISION @nanoFramework_VERSION_TWEAK@U -#define NANOCLR_LIGHT_MATH @TARGET_LIGHT_MATH@ -#define DP_FLOATINGPOINT @TARGET_DP_FLOATINGPOINT@ -#define SUPPORT_ANY_BASE_CONVERSION @TARGET_SUPPORT_ANY_BASE_CONVERSION@ -#define HAS_CONFIG_BLOCK @TARGET_HAS_CONFIG_BLOCK@ -#define NANOCLR_REFLECTION @TARGET_NANOCLR_REFLECTION@ -#define NANOCLR_SYSTEM_COLLECTIONS @TARGET_SYSTEM_COLLECTIONS@ -#define TARGET_HAS_NANOBOOTER FALSE -#define TRACE_TO_STDIO @TARGET_TRACE_TO_STDIO@ +#define NANOCLR_LIGHT_MATH @TARGET_LIGHT_MATH@ +#define DP_FLOATINGPOINT @TARGET_DP_FLOATINGPOINT@ +#define SUPPORT_ANY_BASE_CONVERSION @TARGET_SUPPORT_ANY_BASE_CONVERSION@ +#define HAS_CONFIG_BLOCK @TARGET_HAS_CONFIG_BLOCK@ +#define NANOCLR_REFLECTION @TARGET_NANOCLR_REFLECTION@ +#define NANOCLR_SYSTEM_COLLECTIONS @TARGET_SYSTEM_COLLECTIONS@ +#define TARGET_HAS_NANOBOOTER FALSE +#define TRACE_TO_STDIO @TARGET_TRACE_TO_STDIO@ +#cmakedefine NANOCLR_PROFILE_NEW_CALLS @NANOCLR_PROFILE_NEW_CALLS@ +#cmakedefine NANOCLR_PROFILE_NEW_ALLOCATIONS @NANOCLR_PROFILE_NEW_ALLOCATIONS@ +#cmakedefine NANOCLR_TRACE_MEMORY_STATS @NANOCLR_TRACE_MEMORY_STATS@ #endif // TARGET_OS_H diff --git a/CMake/arm-gcc.json b/CMake/arm-gcc.json new file mode 100644 index 0000000000..49c1947f22 --- /dev/null +++ b/CMake/arm-gcc.json @@ -0,0 +1,21 @@ +{ + "version": 4, + "include": [ + "base.json" + ], + "configurePresets": [ + { + "name": "arm-gcc-cortex-preset", + "description": "Preset for ARM GCC cortex-m0, cortex-m0+, cortex-m3, cortex-m4, cortex-m7, cortex-m33", + "hidden": true, + "inherits": "general-preset", + "cacheVariables": { + "CMAKE_TOOLCHAIN_FILE": { + "type": "FILEPATH", + "value": "${sourceDir}/CMake/toolchain.arm-none-eabi.cmake" + }, + "NF_INTEROP_ASSEMBLIES": null + } + } + ] +} diff --git a/CMake/base.json b/CMake/base.json new file mode 100644 index 0000000000..cb32ee5b42 --- /dev/null +++ b/CMake/base.json @@ -0,0 +1,27 @@ +{ + "version": 4, + "configurePresets": [ + { + "name": "general-preset", + "description": "Preset with general configurations common to all presets", + "hidden": true, + "generator": "Ninja", + "binaryDir": "${sourceDir}/build", + "architecture": { + "value": "unspecified", + "strategy": "external" + }, + "vendor": { + "microsoft.com/VisualStudioSettings/CMake/1.0": { + "intelliSenseMode": "linux-gcc-arm" + } + }, + "warnings": { + "deprecated": true, + "dev": true, + "uninitialized": false, + "unusedCli": false + } + } + ] +} diff --git a/CMake/binutils.AzureRTOS.cmake b/CMake/binutils.AzureRTOS.cmake index a0da5d660c..99aeb5fe04 100644 --- a/CMake/binutils.AzureRTOS.cmake +++ b/CMake/binutils.AzureRTOS.cmake @@ -9,10 +9,10 @@ include(binutils.common) function(nf_set_optimization_options target) target_compile_options(${target} PRIVATE - $<$:-Og -femit-class-debug-always -g3 -ggdb> - $<$:-O3> - $<$:-Os> - $<$:-Os -femit-class-debug-always -g3 -ggdb> + $<$:-Og -ggdb> + $<$:-O3 -flto -ffat-lto-objects> + $<$:-Os -flto -ffat-lto-objects> + $<$:-Os -femit-class-debug-always -ggdb> ) endfunction() @@ -27,11 +27,6 @@ endfunction() # sets network connectivity options according to the NetX driver choosen in build options WIFI_DRIVER and ETHERNET_DRIVER macro(nf_set_network_connectivity_options) - # sanity check - if(NOT DEFINED ETHERNET_DRIVER AND NOT DEFINED WIFI_DRIVER) - message(FATAL_ERROR "\n\nSorry but you must define either ETHERNET_DRIVER or WIFI_DRIVER build option...\n\n") - endif() - ############################ if(DEFINED WIFI_DRIVER) @@ -138,7 +133,11 @@ macro(nf_add_platform_packages) if(STM32_CUBE_PACKAGE_REQUIRED) find_package(${TARGET_STM32_CUBE_PACKAGE}_CubePackage REQUIRED QUIET) endif() - + + if(SILABS_GECKO_SDK_REQUIRED) + find_package(Gecko_SDK REQUIRED QUIET) + endif() + # packages specific for nanoBooter if(NFAPP_TARGET STREQUAL ${NANOBOOTER_PROJECT_NAME}) # no packages for booter @@ -158,7 +157,8 @@ macro(nf_add_platform_packages) # need to add ThreadX extension in order to use BSD if("${TARGET_SERIES}" STREQUAL "STM32F7xx") set(TX_PORT_FILE ${azure_rtos_SOURCE_DIR}/ports/cortex_m7/gnu/inc/tx_port.h) - elseif("${TARGET_SERIES}" STREQUAL "STM32L4xx") + elseif("${TARGET_SERIES}" STREQUAL "STM32L4xx" + OR "${TARGET_SERIES}" STREQUAL "EFM32GG11") set(TX_PORT_FILE ${azure_rtos_SOURCE_DIR}/ports/cortex_m4/gnu/inc/tx_port.h) else() message(FATAL_ERROR "Support for NetX Duo is not implemented for ${TARGET_SERIES}.") @@ -200,6 +200,7 @@ macro(nf_add_platform_dependencies target) ${NF_Network_INCLUDE_DIRS} ${CHIBIOS_CONTRIB_INCLUDE_DIRS} ${CHIBIOS_HAL_INCLUDE_DIRS} + ${Gecko_SDK_INCLUDE_DIRS} ${azure_rtos_SOURCE_DIR}/common/inc ${AZRTOS_INCLUDES} ) @@ -218,6 +219,7 @@ macro(nf_add_platform_dependencies target) ${TARGET_AZURERTOS_COMMON_INCLUDE_DIRS} ${CHIBIOS_CONTRIB_INCLUDE_DIRS} ${CHIBIOS_HAL_INCLUDE_DIRS} + ${Gecko_SDK_INCLUDE_DIRS} ${azure_rtos_SOURCE_DIR}/common/inc ${AZRTOS_INCLUDES} ) @@ -231,6 +233,7 @@ macro(nf_add_platform_dependencies target) ${TARGET_AZURERTOS_COMMON_INCLUDE_DIRS} ${CHIBIOS_CONTRIB_INCLUDE_DIRS} ${CHIBIOS_HAL_INCLUDE_DIRS} + ${Gecko_SDK_INCLUDE_DIRS} ${azure_rtos_SOURCE_DIR}/common/inc ${AZRTOS_INCLUDES} ) @@ -245,6 +248,7 @@ macro(nf_add_platform_dependencies target) ${ChibiOSnfOverlay_INCLUDE_DIRS} ${CHIBIOS_CONTRIB_INCLUDE_DIRS} ${CHIBIOS_HAL_INCLUDE_DIRS} + ${Gecko_SDK_INCLUDE_DIRS} ${azure_rtos_SOURCE_DIR}/common/inc ${NETXDUO_INCLUDES} ${TARGET_BASE_LOCATION} @@ -324,11 +328,17 @@ macro(nf_add_platform_include_directories target) ) endif() + if(SILABS_GECKO_SDK_REQUIRED) + target_include_directories(${target}.elf PUBLIC + ${Gecko_SDK_INCLUDE_DIRS} + ) + endif() + # includes specific to nanoBooter if(${target} STREQUAL ${NANOBOOTER_PROJECT_NAME}) target_include_directories(${target}.elf PUBLIC - ${TARGET_AZURERTOS_NANOBOOTER_INCLUDE_DIRS} + ${TARGET_AZURERTOS_NANOBOOTER_INCLUDE_DIRS} ) endif() @@ -350,7 +360,7 @@ macro(nf_add_platform_sources target) # add header files with common OS definitions and board definitions configure_file(${CMAKE_CURRENT_SOURCE_DIR}/target_common.h.in - ${CMAKE_BINARY_DIR}/targets/${RTOS}/${TARGET_BOARD}/target_common.h @ONLY) + ${CMAKE_BINARY_DIR}/targets/${RTOS}/${TARGET_VENDOR}/${TARGET_BOARD}/target_common.h @ONLY) # sources common to both builds target_sources(${target}.elf PUBLIC @@ -378,7 +388,7 @@ macro(nf_add_platform_sources target) # add header file for board definition configure_file(${CMAKE_CURRENT_SOURCE_DIR}/nanoBooter/target_board.h.in - ${CMAKE_BINARY_DIR}/targets/${RTOS}/${TARGET_BOARD}/nanoBooter/target_board.h @ONLY) + ${CMAKE_BINARY_DIR}/targets/${RTOS}/${TARGET_VENDOR}/${TARGET_BOARD}/nanoBooter/target_board.h @ONLY) target_sources(${target}.elf PUBLIC @@ -395,19 +405,27 @@ macro(nf_add_platform_sources target) if(${target} STREQUAL ${NANOCLR_PROJECT_NAME}) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/nanoCLR/target_board.h.in - ${CMAKE_BINARY_DIR}/targets/${RTOS}/${TARGET_BOARD}/nanoCLR/target_board.h @ONLY) + ${CMAKE_BINARY_DIR}/targets/${RTOS}/${TARGET_VENDOR}/${TARGET_BOARD}/nanoCLR/target_board.h @ONLY) target_sources(${target}.elf PUBLIC ${TARGET_AZURERTOS_NANOCLR_SOURCES} ) - if(AZURERTOS_NETXDUO_REQUIRED) + if(USE_NETWORKING_OPTION) target_link_libraries(${target}.elf nano::NF_Network azrtos::netxduo ) endif() + if(USBX_FEATURE_HID_OPTION) + target_link_libraries(${target}.elf + azrtos::netxduo + azrtos::filex + azrtos::usbx + ) + endif() + endif() if(STM32_CUBE_PACKAGE_REQUIRED) @@ -427,6 +445,26 @@ macro(nf_add_platform_sources target) endif() + if(SILABS_GECKO_SDK_REQUIRED) + + nf_add_gecko_sdk( + BUILD_TARGET + ${target} + EXTRA_INCLUDES + ${AZRTOS_INCLUDES} + ${NF_CoreCLR_INCLUDE_DIRS} + ) + + add_dependencies(${target}.elf nano::gecko_sdk_${target}) + + target_link_libraries(${target}.elf + -Wl,-whole-archive + nano::gecko_sdk_${target} + -Wl,-no-whole-archive + ) + + endif() + target_link_libraries(${target}.elf azrtos::threadx ) diff --git a/CMake/binutils.ChibiOS.cmake b/CMake/binutils.ChibiOS.cmake index 4c508a6dde..76279accee 100644 --- a/CMake/binutils.ChibiOS.cmake +++ b/CMake/binutils.ChibiOS.cmake @@ -197,7 +197,7 @@ macro(nf_add_platform_dependencies target) add_dependencies(${target}.elf nano::NF_Network) - # security provider is mbedTLS + # security provider is MbedTLS if(USE_SECURITY_MBEDTLS_OPTION) add_dependencies(NF_Network nano::NF_Network) endif() @@ -248,7 +248,7 @@ macro(nf_add_platform_include_directories target) if(USE_SECURITY_MBEDTLS_OPTION) - # need to add extra include directories for mbedTLS + # need to add extra include directories for MbedTLS target_include_directories( mbedcrypto PUBLIC ${CHIBIOS_HAL_INCLUDE_DIRS} diff --git a/CMake/binutils.ESP32.cmake b/CMake/binutils.ESP32.cmake index 1ecb8bad41..45bf1a244d 100644 --- a/CMake/binutils.ESP32.cmake +++ b/CMake/binutils.ESP32.cmake @@ -284,7 +284,7 @@ macro(nf_add_platform_dependencies target) add_dependencies(${target}.elf nano::NF_Network) - # security provider is mbedTLS + # security provider is MbedTLS if(USE_SECURITY_MBEDTLS_OPTION) add_dependencies(NF_Network mbedtls) endif() @@ -470,7 +470,7 @@ macro(nf_setup_partition_tables_generator) # create command line for partition table generator set(gen_partition_table "python" "${ESP32_PARTITION_TABLE_UTILITY}") - if(${TARGET_SERIES_SHORT} STREQUAL "esp32" OR ${TARGET_SERIES_SHORT} STREQUAL "esp32c3" OR ${TARGET_SERIES_SHORT} STREQUAL "esp32s2") + if(${TARGET_SERIES_SHORT} STREQUAL "esp32" OR ${TARGET_SERIES_SHORT} STREQUAL "esp32c3" OR ${TARGET_SERIES_SHORT} STREQUAL "esp32s2" OR ${TARGET_SERIES_SHORT} STREQUAL "esp32s3") add_custom_command( TARGET ${NANOCLR_PROJECT_NAME}.elf POST_BUILD COMMAND ${gen_partition_table} @@ -481,7 +481,7 @@ macro(nf_setup_partition_tables_generator) endif() - if(${TARGET_SERIES_SHORT} STREQUAL "esp32" OR ${TARGET_SERIES_SHORT} STREQUAL "esp32s2") + if(${TARGET_SERIES_SHORT} STREQUAL "esp32" OR ${TARGET_SERIES_SHORT} STREQUAL "esp32s2" OR ${TARGET_SERIES_SHORT} STREQUAL "esp32s3") add_custom_command( TARGET ${NANOCLR_PROJECT_NAME}.elf POST_BUILD COMMAND ${gen_partition_table} @@ -590,12 +590,12 @@ macro(nf_add_idf_as_library) list(APPEND IDF_LIBRARIES_TO_ADD idf::esp_eth) endif() - # handle specifics for ESP32S2 series - if(${TARGET_SERIES_SHORT} STREQUAL "esp32s2") + # handle specifics for ESP32S2/S3 series + if(${TARGET_SERIES_SHORT} STREQUAL "esp32s2" OR ${TARGET_SERIES_SHORT} STREQUAL "esp32s3") if(ESP32_USB_CDC) - # add IDF components specific to ESP32S2 series + # add IDF components specific to ESP32S2/S3 series list(APPEND IDF_COMPONENTS_TO_ADD tinyusb) list(APPEND IDF_LIBRARIES_TO_ADD idf::tinyusb) @@ -703,6 +703,7 @@ macro(nf_add_idf_as_library) add_executable( ${NANOCLR_PROJECT_NAME}.elf ${CMAKE_SOURCE_DIR}/targets/ESP32/_IDF/${TARGET_SERIES_SHORT}/app_main.c + ${CMAKE_SOURCE_DIR}/targets/ESP32/_IDF/project_elf_src_${TARGET_SERIES_SHORT}.c ) #Restore original sdkconfig back to defaults @@ -817,10 +818,12 @@ macro(nf_add_idf_as_library) # find out if there is support for PSRAM set(SPIRAM_SUPPORT_PRESENT -1) - if(TARGET_SERIES_SHORT STREQUAL "esp32" OR TARGET_SERIES_SHORT STREQUAL "esp32s2") + if(TARGET_SERIES_SHORT STREQUAL "esp32") string(FIND ${SDKCONFIG_DEFAULT_CONTENTS} "CONFIG_ESP32_SPIRAM_SUPPORT=y" SPIRAM_SUPPORT_PRESENT) elseif(TARGET_SERIES_SHORT STREQUAL "esp32s2") string(FIND ${SDKCONFIG_DEFAULT_CONTENTS} "CONFIG_ESP32S2_SPIRAM_SUPPORT=y" SPIRAM_SUPPORT_PRESENT) + elseif(TARGET_SERIES_SHORT STREQUAL "esp32s3") + string(FIND ${SDKCONFIG_DEFAULT_CONTENTS} "CONFIG_ESP32S3_SPIRAM_SUPPORT=y" SPIRAM_SUPPORT_PRESENT) endif() # set variable @@ -876,6 +879,24 @@ macro(nf_add_idf_as_library) set(BLE_INFO ", support for BLE") endif() + ############################################################ + # output component size summary for the nanoCLR executable # + # more on this here: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/performance/size.html#size-summary-idf-py-size + + # set the map file with the components + set(nanoCLRMapfile "${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}.map") + target_link_libraries(${NANOCLR_PROJECT_NAME}.elf "-Wl,--cref" "-Wl,--Map=\"${nanoCLRMapfile}\"") + + # setup the call to the python script to generate the size summary + set(ESP32_IDF_SIZE_UTILITY ${IDF_PATH_CMAKED}/tools/idf_size.py) + set(output_idf_size "python" "${ESP32_IDF_SIZE_UTILITY}") + + add_custom_command( + TARGET ${NANOCLR_PROJECT_NAME}.elf POST_BUILD + COMMAND ${output_idf_size} + --archives --target ${TARGET_SERIES_SHORT} ${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}.map + COMMENT "Ouptut IDF size summary") + endmacro() # macro to clear binary files related with nanoBooter from output diff --git a/CMake/binutils.FreeRTOS.cmake b/CMake/binutils.FreeRTOS.cmake index ceb63b169c..feee2643ef 100644 --- a/CMake/binutils.FreeRTOS.cmake +++ b/CMake/binutils.FreeRTOS.cmake @@ -193,6 +193,7 @@ macro(nf_add_platform_include_directories target) ${TARGET_NXP_NANOCLR_INCLUDE_DIRS} ${NANOCLR_PROJECT_INCLUDE_DIRS} + ${TARGET_FREERTOS_COMMON_INCLUDE_DIRS} ${TARGET_FREERTOS_NANOCLR_INCLUDE_DIRS} ${LWIP_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR} diff --git a/CMake/binutils.TI_SimpleLink.cmake b/CMake/binutils.TI_SimpleLink.cmake index 48a9c2b410..fbd61e5b21 100644 --- a/CMake/binutils.TI_SimpleLink.cmake +++ b/CMake/binutils.TI_SimpleLink.cmake @@ -55,20 +55,12 @@ endmacro() function(nf_check_radio_frequency) if(NOT DEFINED RADIO_FREQUENCY) - message(FATAL_ERROR "Radio frequncy NOT defined. Please set build option 'RADIO_FREQUENCY'. Valid values are 868 and 915.") + message(FATAL_ERROR "\nRadio frequency NOT defined!!\nPlease set the build option 'RADIO_FREQUENCY' in 'config\\user-prefs.json' or in the user CMake preset. Valid values are 868 and 915.\n") endif() - find_file( - SYS-CONFIG-FILE - *_${RADIO_FREQUENCY}.syscfg - - PATHS - ${TARGET_BASE_LOCATION} - ) - - # check if file was found - if(SYS-CONFIG-FILE-NOTFOUND) - message(FATAL_ERROR "Couldn't find a sysconfig file for radio frequency ${RADIO_FREQUENCY}. Valid values are 868 and 915.") + # check if file exists + if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${TARGET_BOARD}_${RADIO_FREQUENCY}.syscfg") + message(FATAL_ERROR "\nCouldn't find a sysconfig file for radio frequency ${RADIO_FREQUENCY}.\n") endif() endfunction() @@ -252,6 +244,8 @@ macro(nf_add_platform_sysconfig_steps ti_device ti_device_family) set(SYS_CONFIG_FILENAME ${TARGET_BOARD}_${RADIO_FREQUENCY}.syscfg) endif() + message(STATUS "Using sysconfig file: ${CMAKE_CURRENT_SOURCE_DIR}/${SYS_CONFIG_FILENAME}.") + # copy Sys Config file to build directory add_custom_command( TARGET diff --git a/CMake/binutils.arm-none-eabi.cmake b/CMake/binutils.arm-none-eabi.cmake index 66f593303d..75e7b37205 100644 --- a/CMake/binutils.arm-none-eabi.cmake +++ b/CMake/binutils.arm-none-eabi.cmake @@ -5,24 +5,6 @@ include(binutils.common) -function(nf_add_hex_bin_dump_targets target) - if(EXECUTABLE_OUTPUT_PATH) - set(FILENAME "${EXECUTABLE_OUTPUT_PATH}/${target}") - else() - set(FILENAME "${target}") - endif() - - #get_filename_component(FNSHORT ${FILENAME} NAME_WE) - string(REGEX REPLACE "\\.[^.]*$" "" FNSHORT ${FILENAME}) - - # add targets for HEX, BIN and S19 formats with no output so they will always be built - add_custom_target(${target}.hex DEPENDS ${target} COMMAND ${CMAKE_OBJCOPY} -Oihex ${FILENAME} ${FNSHORT}.hex) - add_custom_target(${target}.s19 DEPENDS ${target} COMMAND ${CMAKE_OBJCOPY} -Osrec ${FILENAME} ${FNSHORT}.s19) - add_custom_target(${target}.bin DEPENDS ${target} COMMAND ${CMAKE_OBJCOPY} -Obinary ${FILENAME} ${FNSHORT}.bin) - add_custom_target(${target}.dump DEPENDS ${target} COMMAND ${CMAKE_OBJDUMP} -d -EL -S ${FILENAME} ${FNSHORT}.dump) -endfunction() - - function(nf_print_target_size target) if(EXECUTABLE_OUTPUT_PATH) set(FILENAME "${EXECUTABLE_OUTPUT_PATH}/${target}") @@ -32,7 +14,6 @@ function(nf_print_target_size target) add_custom_command(TARGET ${target} POST_BUILD COMMAND ${CMAKE_SIZE_UTIL} -A -x ${FILENAME}) endfunction() - function(nf_set_linker_file target linker_file_name) # set linker file name diff --git a/CMake/binutils.common.cmake b/CMake/binutils.common.cmake index 1c9efaa4a6..bdf1b65d0d 100644 --- a/CMake/binutils.common.cmake +++ b/CMake/binutils.common.cmake @@ -49,7 +49,7 @@ macro(nf_common_compiler_definitions) endif() # build types that have debugging capabilities AND are NOT RTM have to have the define 'NANOCLR_ENABLE_SOURCELEVELDEBUGGING' - if((NOT NF_BUILD_RTM) OR NF_FEATURE_DEBUGGER) + if((NOT NF_BUILD_RTM) AND NF_FEATURE_DEBUGGER) target_compile_definitions(${NFCCF_TARGET} PUBLIC -DNANOCLR_ENABLE_SOURCELEVELDEBUGGING) endif() @@ -108,17 +108,17 @@ endmacro() # To be called from target CMakeList.txt macro(nf_add_common_dependencies target) + configure_file(${BASE_PATH_FOR_CLASS_LIBRARIES_MODULES}/target_platform.h.in + ${CMAKE_BINARY_DIR}/targets/${RTOS}/${TARGET_VENDOR}/${TARGET_BOARD}/target_platform.h @ONLY) + # dependencies specific to nanoBooter if("${target}" STREQUAL "${NANOBOOTER_PROJECT_NAME}") endif() - + # dependencies specific to nanoCLR if("${target}" STREQUAL "${NANOCLR_PROJECT_NAME}") - - configure_file(${BASE_PATH_FOR_CLASS_LIBRARIES_MODULES}/target_platform.h.in - ${CMAKE_BINARY_DIR}/targets/${RTOS}/${TARGET_BOARD}/target_platform.h @ONLY) - + endif() endmacro() @@ -221,12 +221,19 @@ macro(nf_add_common_sources) target_link_libraries(${NFACS_TARGET}.elf nano::NF_CoreCLR nano::NF_NativeAssemblies - nano::NF_Debugger nano::WireProtocol ${NFACS_EXTRA_LIBRARIES} ) + if(NF_FEATURE_DEBUGGER) + + target_link_libraries(${NFACS_TARGET}.elf + nano::NF_Debugger + ) + + endif() + target_sources(${NFACS_TARGET}.elf PUBLIC ${NANOCLR_PROJECT_SOURCES} @@ -298,7 +305,9 @@ function(nf_generate_bin_package file1 file2 offset outputfilename) ${file2} -Binary -offset 0x${offset} -o ${outputfilename} -Binary - WORKING_DIRECTORY ${TOOL_SRECORD_PREFIX} + WORKING_DIRECTORY ${TOOL_SRECORD_PREFIX} + + BYPRODUCTS ${CMAKE_BINARY_DIR}/${outputfilename} COMMENT "exporting hex files to one binary file" ) @@ -315,33 +324,32 @@ function(nf_generate_build_output_files target) string(SUBSTRING ${target} 0 ${TARGET_EXTENSION_DOT_INDEX} TARGET_SHORT) set(TARGET_HEX_FILE ${CMAKE_BINARY_DIR}/${TARGET_SHORT}.hex) - set(TARGET_S19_FILE ${CMAKE_BINARY_DIR}/${TARGET_SHORT}.s19) set(TARGET_BIN_FILE ${CMAKE_BINARY_DIR}/${TARGET_SHORT}.bin) set(TARGET_DUMP_FILE ${CMAKE_BINARY_DIR}/${TARGET_SHORT}.lst) - if(CMAKE_BUILD_TYPE EQUAL "Release" OR CMAKE_BUILD_TYPE EQUAL "MinSizeRel") + if(CMAKE_BUILD_TYPE MATCHES "Release" OR CMAKE_BUILD_TYPE MATCHES "MinSizeRel") add_custom_command(TARGET ${TARGET_SHORT}.elf POST_BUILD - # copy target image to other formats - COMMAND ${CMAKE_OBJCOPY} -Oihex $ ${TARGET_HEX_FILE} - COMMAND ${CMAKE_OBJCOPY} -Osrec $ ${TARGET_S19_FILE} - COMMAND ${CMAKE_OBJCOPY} -Obinary $ ${TARGET_BIN_FILE} + # copy target image to other formats + COMMAND ${CMAKE_OBJCOPY} $ ${CMAKE_BINARY_DIR}/${TARGET_SHORT}.elf + COMMAND ${CMAKE_OBJCOPY} -Oihex $ ${TARGET_HEX_FILE} + COMMAND ${CMAKE_OBJCOPY} -Obinary $ ${TARGET_BIN_FILE} - # copy target file to build folder (this is only useful for debugging in VS Code because of path in launch.json) - COMMAND ${CMAKE_OBJCOPY} $ ${CMAKE_SOURCE_DIR}/build/${TARGET_SHORT}.elf + BYPRODUCTS + ${TARGET_HEX_FILE} + ${TARGET_BIN_FILE} - COMMENT "Generate nanoBooter HEX and BIN files for deployment") + COMMENT "Generate nanoBooter HEX and BIN files for deployment") else() add_custom_command(TARGET ${TARGET_SHORT}.elf POST_BUILD # copy target image to other formats COMMAND ${CMAKE_OBJCOPY} -Oihex $ ${TARGET_HEX_FILE} - COMMAND ${CMAKE_OBJCOPY} -Osrec $ ${TARGET_S19_FILE} COMMAND ${CMAKE_OBJCOPY} -Obinary $ ${TARGET_BIN_FILE} # copy target file to build folder (this is only useful for debugging in VS Code because of path in launch.json) - COMMAND ${CMAKE_OBJCOPY} $ ${CMAKE_SOURCE_DIR}/build/${TARGET_SHORT}.elf + COMMAND ${CMAKE_OBJCOPY} $ ${CMAKE_BINARY_DIR}/${TARGET_SHORT}.elf # dump target image as source code listing # ONLY when DEBUG info is available, this is on 'Debug' and 'RelWithDebInfo' @@ -350,8 +358,6 @@ function(nf_generate_build_output_files target) COMMENT "Generate nanoBooter HEX and BIN files for deployment, LST file for debug") endif() - - nf_add_hex_bin_dump_targets(${target}) # add this to print the size of the output targets nf_print_target_size(${target}) @@ -578,10 +584,10 @@ macro(nf_setup_target_build_common) if(USE_SECURITY_MBEDTLS_OPTION AND NOT RTOS_ESP32_CHECK) - # mbedTLS requires setting a compiler definition in order to pass a config file - target_compile_definitions(mbedcrypto PUBLIC "-DMBEDTLS_CONFIG_FILE=\"${CMAKE_SOURCE_DIR}/src/PAL/COM/sockets/ssl/mbedTLS/nf_mbedtls_config.h\"") + # MbedTLS requires setting a compiler definition in order to pass a config file + target_compile_definitions(mbedcrypto PUBLIC "-DMBEDTLS_CONFIG_FILE=\"${CMAKE_SOURCE_DIR}/src/PAL/COM/sockets/ssl/MbedTLS/nf_mbedtls_config.h\"") - # need to add extra include directories for mbedTLS + # need to add extra include directories for MbedTLS target_include_directories( mbedcrypto PUBLIC ${CMAKE_SOURCE_DIR}/src/CLR/Include @@ -589,7 +595,7 @@ macro(nf_setup_target_build_common) ${CMAKE_SOURCE_DIR}/src/PAL ${CMAKE_SOURCE_DIR}/src/PAL/Include ${CMAKE_SOURCE_DIR}/src/PAL/COM/sockets - ${CMAKE_SOURCE_DIR}/src/PAL/COM/sockets/ssl/mbedTLS + ${CMAKE_SOURCE_DIR}/src/PAL/COM/sockets/ssl/MbedTLS ${CMAKE_SOURCE_DIR}/src/DeviceInterfaces/Networking.Sntp ${CMAKE_SOURCE_DIR}/targets/${RTOS}/_include ${TARGET_BASE_LOCATION}/nanoCLR @@ -598,9 +604,9 @@ macro(nf_setup_target_build_common) # platform implementation of hardware random provider target_sources(mbedcrypto PRIVATE ${BASE_PATH_FOR_CLASS_LIBRARIES_MODULES}/mbedtls_entropy_hardware_pool.c) - nf_set_compile_options(TARGET mbedcrypto BUILD_TARGET ${NANOCLR_PROJECT_NAME}) - nf_set_compile_options(TARGET mbedx509 BUILD_TARGET ${NANOCLR_PROJECT_NAME}) - nf_set_compile_options(TARGET mbedtls BUILD_TARGET ${NANOCLR_PROJECT_NAME}) + nf_set_compile_options(TARGET mbedcrypto) + nf_set_compile_options(TARGET mbedx509) + nf_set_compile_options(TARGET mbedtls) nf_set_compile_definitions(TARGET mbedcrypto BUILD_TARGET ${NANOCLR_PROJECT_NAME}) nf_set_compile_definitions(TARGET mbedx509 BUILD_TARGET ${NANOCLR_PROJECT_NAME}) nf_set_compile_definitions(TARGET mbedtls BUILD_TARGET ${NANOCLR_PROJECT_NAME}) diff --git a/CMake/toolchain.xtensa-esp32s3-elf.cmake b/CMake/toolchain.xtensa-esp32s3-elf.cmake new file mode 100644 index 0000000000..ca21876e32 --- /dev/null +++ b/CMake/toolchain.xtensa-esp32s3-elf.cmake @@ -0,0 +1,61 @@ +# +# Copyright (c) .NET Foundation and Contributors +# See LICENSE file in the project root for full license information. +# + +include(CMakeForceCompiler) + +# the name of the operating system for which CMake is to build +set(CMAKE_SYSTEM_NAME Generic) + +# macro to setup compilers +macro(nf_set_compiler_var var name) + find_program( + CMAKE_${var} + xtensa-esp32s3-elf-${name} + CMAKE_FIND_ROOT_PATH_BOTH + REQUIRED) +endmacro() + +# safer to have these here as a check if the toolchain are accessible in the PATH + +# setup C compiler +nf_set_compiler_var(C_COMPILER gcc) + +# setup C++ compiler +nf_set_compiler_var(CXX_COMPILER g++) + +# setup Assembler compiler +nf_set_compiler_var(ASM_COMPILER gcc) + +# other toolchain configurations +find_program( + CMAKE_OBJCOPY + xtensa-esp32s3-elf-objcopy + CMAKE_FIND_ROOT_PATH_BOTH) + +find_program( + CMAKE_OBJDUMP + xtensa-esp32s3-elf-objdump + CMAKE_FIND_ROOT_PATH_BOTH) + +find_program( + CMAKE_SIZE + xtensa-esp32s3-elf-size + CMAKE_FIND_ROOT_PATH_BOTH) + +set(CMAKE_C_FLAGS "-mlongcalls -Wno-frame-address" CACHE STRING "C Compiler Base Flags") +set(CMAKE_CXX_FLAGS "-mlongcalls -Wno-frame-address" CACHE STRING "C++ Compiler Base Flags") + +# root paths to search on the filesystem for cross-compiling +get_filename_component(CMAKE_FIND_ROOT_PATH ${CMAKE_C_COMPILER} DIRECTORY CACHE) +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + +# set required C and C++ standard for ALL targets +set(CMAKE_C_STANDARD 11 CACHE INTERNAL "C standard for all targets") +set(CMAKE_CXX_STANDARD 11 CACHE INTERNAL "C++ standard for all targets") + +# Perform compiler test with static library +set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) diff --git a/CMake/xtensa-esp32.json b/CMake/xtensa-esp32.json new file mode 100644 index 0000000000..6e361fdade --- /dev/null +++ b/CMake/xtensa-esp32.json @@ -0,0 +1,44 @@ +{ + "version": 4, + "include": [ + "base.json" + ], + "configurePresets": [ + { + "name": "xtensa-esp32-preset", + "description": "Preset for ESP32 series", + "hidden": true, + "inherits": "general-preset", + "cacheVariables": { + "CMAKE_TOOLCHAIN_FILE": { + "type": "FILEPATH", + "value": "${sourceDir}/CMake/toolchain.xtensa-esp32-elf.cmake" + }, + "NF_INTEROP_ASSEMBLIES": null, + "NF_TARGET_HAS_NANOBOOTER": "OFF", + "RTOS": "ESP32", + "TARGET_SERIES": "ESP32", + "TARGET_BOARD": "ESP32", + "NF_FEATURE_HAS_CONFIG_BLOCK": "ON", + "SUPPORT_ANY_BASE_CONVERSION": "ON", + "API_System.Net": "ON", + "API_System.Math": "ON", + "API_System.Device.Adc": "ON", + "API_System.Device.Dac": "ON", + "API_System.Device.Gpio": "ON", + "API_System.Device.I2c": "ON", + "API_System.Device.I2s": "ON", + "API_System.Device.Spi": "ON", + "API_System.Device.Pwm": "ON", + "API_System.Device.Wifi": "ON", + "API_System.IO.Ports": "ON", + "API_Hardware.Esp32": "ON", + "API_nanoFramework.Hardware.Esp32.Rmt": "ON", + "API_nanoFramework.ResourceManager": "ON", + "API_nanoFramework.System.Collections": "ON", + "API_nanoFramework.System.Text": "ON", + "ESP32_SPIRAM_FOR_IDF_ALLOCATION": "256 * 1024" + } + } + ] +} diff --git a/CMake/xtensa-esp32c3.json b/CMake/xtensa-esp32c3.json new file mode 100644 index 0000000000..bd8783fd14 --- /dev/null +++ b/CMake/xtensa-esp32c3.json @@ -0,0 +1,43 @@ +{ + "version": 4, + "include": [ + "base.json" + ], + "configurePresets": [ + { + "name": "xtensa-esp32c3-preset", + "description": "Preset for ESP32-C3 series", + "inherits": "general-preset", + "hidden": true, + "cacheVariables": { + "CMAKE_TOOLCHAIN_FILE": { + "type": "FILEPATH", + "value": "${sourceDir}/CMake/toolchain.riscv32-esp-elf.cmake" + }, + "NF_INTEROP_ASSEMBLIES": null, + "NF_TARGET_HAS_NANOBOOTER": "OFF", + "RTOS": "ESP32", + "TARGET_SERIES": "ESP32_C3", + "TARGET_BOARD": "ESP32_C3", + "NF_FEATURE_HAS_CONFIG_BLOCK": "ON", + "SUPPORT_ANY_BASE_CONVERSION": "ON", + "API_System.Net": "ON", + "API_System.Math": "ON", + "API_System.Device.Adc": "ON", + "API_System.Device.Dac": "OFF", + "API_System.Device.Gpio": "ON", + "API_System.Device.I2c": "ON", + "API_System.Device.I2s": "ON", + "API_System.Device.Spi": "ON", + "API_System.Device.Pwm": "ON", + "API_System.Device.Wifi": "ON", + "API_System.IO.Ports": "ON", + "API_Hardware.Esp32": "ON", + "API_nanoFramework.Hardware.Esp32.Rmt": "OFF", + "API_nanoFramework.ResourceManager": "ON", + "API_nanoFramework.System.Collections": "ON", + "API_nanoFramework.System.Text": "ON" + } + } + ] +} diff --git a/CMake/xtensa-esp32s2.json b/CMake/xtensa-esp32s2.json new file mode 100644 index 0000000000..c128abc201 --- /dev/null +++ b/CMake/xtensa-esp32s2.json @@ -0,0 +1,44 @@ +{ + "version": 4, + "include": [ + "base.json" + ], + "configurePresets": [ + { + "name": "xtensa-esp32s2-preset", + "description": "Preset for ESP32-S2 series", + "inherits": "general-preset", + "hidden": true, + "cacheVariables": { + "CMAKE_TOOLCHAIN_FILE": { + "type": "FILEPATH", + "value": "${sourceDir}/CMake/toolchain.xtensa-esp32s2-elf.cmake" + }, + "NF_INTEROP_ASSEMBLIES": null, + "NF_TARGET_HAS_NANOBOOTER": "OFF", + "RTOS": "ESP32", + "TARGET_SERIES": "ESP32_S2", + "TARGET_BOARD": "ESP32_S2", + "NF_FEATURE_HAS_CONFIG_BLOCK": "ON", + "SUPPORT_ANY_BASE_CONVERSION": "ON", + "API_System.Net": "ON", + "API_System.Math": "ON", + "API_System.Device.Adc": "ON", + "API_System.Device.Dac": "ON", + "API_System.Device.Gpio": "ON", + "API_System.Device.I2c": "ON", + "API_System.Device.I2s": "ON", + "API_System.Device.Spi": "ON", + "API_System.Device.Pwm": "ON", + "API_System.Device.Wifi": "ON", + "API_System.IO.Ports": "ON", + "API_Hardware.Esp32": "ON", + "API_nanoFramework.Hardware.Esp32.Rmt": "ON", + "API_nanoFramework.ResourceManager": "ON", + "API_nanoFramework.System.Collections": "ON", + "API_nanoFramework.System.Text": "ON", + "ESP32_SPIRAM_FOR_IDF_ALLOCATION": "256 * 1024" + } + } + ] +} diff --git a/CMake/xtensa-esp32s3.json b/CMake/xtensa-esp32s3.json new file mode 100644 index 0000000000..8eee652168 --- /dev/null +++ b/CMake/xtensa-esp32s3.json @@ -0,0 +1,45 @@ +{ + "version": 4, + "include": [ + "base.json" + ], + "configurePresets": [ + { + "name": "xtensa-esp32s3-preset", + "description": "Preset for ESP32-S3 series", + "inherits": "general-preset", + "hidden": true, + "cacheVariables": { + "CMAKE_TOOLCHAIN_FILE": { + "type": "FILEPATH", + "value": "${sourceDir}/CMake/toolchain.xtensa-esp32s3-elf.cmake" + }, + "NF_INTEROP_ASSEMBLIES": null, + "NF_TARGET_HAS_NANOBOOTER": "OFF", + "RTOS": "ESP32", + "TARGET_SERIES": "ESP32_S3", + "TARGET_BOARD": "ESP32_S3", + "NF_FEATURE_HAS_CONFIG_BLOCK": "ON", + "SUPPORT_ANY_BASE_CONVERSION": "ON", + "API_System.Net": "ON", + "API_System.Math": "ON", + "API_System.Device.Adc": "ON", + "API_System.Device.Gpio": "ON", + "API_System.Device.I2c": "ON", + "API_System.Device.I2s": "ON", + "API_System.Device.Spi": "ON", + "API_System.Device.Pwm": "ON", + "API_System.Device.Wifi": "ON", + "API_System.IO.Ports": "ON", + "API_System.IO.FileSystem": "ON", + "API_Hardware.Esp32": "ON", + "API_Windows.Storage": "ON", + "API_nanoFramework.Hardware.Esp32.Rmt": "ON", + "API_nanoFramework.ResourceManager": "ON", + "API_nanoFramework.System.Collections": "ON", + "API_nanoFramework.System.Text": "ON", + "ESP32_SPIRAM_FOR_IDF_ALLOCATION": "256 * 1024" + } + } + ] +} diff --git a/CMakeLists.txt b/CMakeLists.txt index f22f506338..a53924c387 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ # See LICENSE file in the project root for full license information. # -cmake_minimum_required(VERSION 3.20) +cmake_minimum_required(VERSION 3.24) include(CMakeToolsHelpers OPTIONAL) include(ExternalProject) @@ -43,6 +43,17 @@ nf_check_path_limits() # set build type to release if not specified otherwise if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Debug") +else() + + # validate valid build types + set(SUPPORTED_CMAKE_BUILD_TYPES "Debug" "Release" "MinSizeRel" "RelWithDebInfo" CACHE INTERNAL "supported CMake build types") + + list(FIND SUPPORTED_CMAKE_BUILD_TYPES ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_INDEX) + if(CMAKE_BUILD_TYPE_INDEX EQUAL -1) + # build type is NOT supported + message(FATAL_ERROR "\n\nSorry but the CMAKE_BUILD_TYPE set: '${CMAKE_BUILD_TYPE}' is not supported!\nPlease double check the CMAKE_BUILD_TYPE build configuration.\n\n") + endif() + endif() ###################################################### @@ -99,6 +110,10 @@ message(STATUS "Build directory is '${CMAKE_BINARY_DIR}'.") message(STATUS "") ####################### +##################################### +# include CLR Profiler build options +include(ClrProfilerOptions) +##################################### ################################################################# # ouput RTM build option @@ -431,8 +446,8 @@ endif() # (default is OFF so Networking is NOT supported) option(USE_NETWORKING_OPTION "option to use networking") -# (default is OFF so mbed TLS is NOT used) -option(NF_SECURITY_MBEDTLS "option to use mbed TLS as the network security provider" ON) +# (default is OFF so Mbed TLS is NOT used) +option(NF_SECURITY_MBEDTLS "option to use Mbed TLS as the network security provider" ON) # set default option for SNTP to ON option(NF_NETWORKING_SNTP "option to use add SNTP support, requires networking otherwise has no effect" ON) @@ -553,6 +568,14 @@ else() endif() +if(API_nanoFramework.GiantGecko.Adc) + # check if the standard ADC lib is already enabled + if(API_System.Device.Adc) + message(FATAL_ERROR "\n\nERROR:Can't enable simultaneously System.Device.Adc and GiantGecko.Adc APIs") + endif() +endif() + + if(API_System.Device.Dac) set(HAL_USE_DAC_OPTION TRUE CACHE INTERNAL "HAL DAC for System.Device.Dac") else() @@ -604,8 +627,10 @@ endif() if(API_nanoFramework.Device.OneWire) set(HAL_USE_STM32_ONEWIRE_OPTION TRUE CACHE INTERNAL "HAL STM32_ONEWIRE for nanoFramework.Device.OneWire") + set(HAL_USE_ONEWIRE_OPTION TRUE CACHE INTERNAL "HAL ONEWIRE for nanoFramework.Device.OneWire") else() set(HAL_USE_STM32_ONEWIRE_OPTION FALSE CACHE INTERNAL "HAL STM32_ONEWIRE for nanoFramework.Device.OneWire") + set(HAL_USE_ONEWIRE_OPTION FALSE CACHE INTERNAL "HAL ONEWIRE for nanoFramework.Device.OneWire") endif() ################################################################################# @@ -674,7 +699,7 @@ if(USE_NETWORKING_OPTION) endif() if(NF_SECURITY_MBEDTLS) - message(STATUS "Support for networking enabled with security from mbedTLS") + message(STATUS "Support for networking enabled with security from MbedTLS") elseif(RTOS_TI_SIMPLELINK_CHECK OR RTOS_AZURE_CHECK) # these platforms include their own TLS implementation, no need to add any build option message(STATUS "Support for networking enabled with security") @@ -738,9 +763,15 @@ endif() option(NF_FEATURE_WATCHDOG "option to use hardware watchdog" ON) if(NF_FEATURE_WATCHDOG) + + message(STATUS "Support for watchdog enabled") set(HAL_USE_WDG_OPTION TRUE CACHE INTERNAL "NF feature watchdog") -else() + +else() + + message(STATUS "Support for watchdog ** DISABLED **") set(HAL_USE_WDG_OPTION FALSE CACHE INTERNAL "NF feature watchdog") + endif() ################################################################# diff --git a/CMakePresets.json b/CMakePresets.json index 6ec6cdb8f4..babeb6dfc5 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -1,1515 +1,16 @@ { - "version": 3, - "configurePresets": [ - { - "name": "general-preset", - "description": "Preset with general configurations common to all presets", - "hidden": true, - "generator": "Ninja", - "binaryDir": "${sourceDir}/build", - "architecture": { - "value": "unspecified", - "strategy": "external" - }, - "vendor": { - "microsoft.com/VisualStudioSettings/CMake/1.0": { - "intelliSenseMode": "linux-gcc-arm" - } - } - }, - { - "name": "arm-gcc-cortex-preset", - "description": "Preset for ARM GCC cortex-m0, cortex-m0+, cortex-m3, cortex-m4, cortex-m7, cortex-m33", - "hidden": true, - "cacheVariables": { - "CMAKE_TOOLCHAIN_FILE": { - "type": "FILEPATH", - "value": "${sourceDir}/CMake/toolchain.arm-none-eabi.cmake" - } - } - }, - { - "name": "xtensa-esp32-preset", - "description": "Preset for ESP32 series", - "hidden": true, - "cacheVariables": { - "CMAKE_TOOLCHAIN_FILE": { - "type": "FILEPATH", - "value": "${sourceDir}/CMake/toolchain.xtensa-esp32-elf.cmake" - }, - "NF_TARGET_HAS_NANOBOOTER": "OFF", - "RTOS": "ESP32", - "TARGET_SERIES": "ESP32", - "TARGET_BOARD": "ESP32", - "NF_FEATURE_HAS_CONFIG_BLOCK": "ON", - "SUPPORT_ANY_BASE_CONVERSION": "ON", - "API_System.Net": "ON", - "API_System.Math": "ON", - "API_System.Device.Adc": "ON", - "API_System.Device.Dac": "ON", - "API_System.Device.Gpio": "ON", - "API_System.Device.I2c": "ON", - "API_System.Device.I2s": "ON", - "API_System.Device.Spi": "ON", - "API_System.Device.Pwm": "ON", - "API_System.Device.Wifi": "ON", - "API_System.IO.Ports": "ON", - "API_Hardware.Esp32": "ON", - "API_nanoFramework.Hardware.Esp32.Rmt": "ON", - "API_nanoFramework.ResourceManager": "ON", - "API_nanoFramework.System.Collections": "ON", - "API_nanoFramework.System.Text": "ON", - "ESP32_SPIRAM_FOR_IDF_ALLOCATION": "256 * 1024" - } - }, - { - "name": "xtensa-esp32s2-preset", - "description": "Preset for ESP32-S2 series", - "hidden": true, - "cacheVariables": { - "CMAKE_TOOLCHAIN_FILE": { - "type": "FILEPATH", - "value": "${sourceDir}/CMake/toolchain.xtensa-esp32s2-elf.cmake" - }, - "NF_TARGET_HAS_NANOBOOTER": "OFF", - "RTOS": "ESP32", - "TARGET_SERIES": "ESP32_S2", - "TARGET_BOARD": "ESP32_S2", - "NF_FEATURE_HAS_CONFIG_BLOCK": "ON", - "SUPPORT_ANY_BASE_CONVERSION": "ON", - "API_System.Net": "ON", - "API_System.Math": "ON", - "API_System.Device.Adc": "ON", - "API_System.Device.Dac": "ON", - "API_System.Device.Gpio": "ON", - "API_System.Device.I2c": "ON", - "API_System.Device.I2s": "ON", - "API_System.Device.Spi": "ON", - "API_System.Device.Pwm": "ON", - "API_System.Device.Wifi": "ON", - "API_System.IO.Ports": "ON", - "API_Hardware.Esp32": "ON", - "API_nanoFramework.Hardware.Esp32.Rmt": "ON", - "API_nanoFramework.ResourceManager": "ON", - "API_nanoFramework.System.Collections": "ON", - "API_nanoFramework.System.Text": "ON", - "ESP32_SPIRAM_FOR_IDF_ALLOCATION": "256 * 1024" - } - }, - { - "name": "xtensa-esp32c3-preset", - "description": "Preset for ESP32-C3 series", - "hidden": true, - "cacheVariables": { - "CMAKE_TOOLCHAIN_FILE": { - "type": "FILEPATH", - "value": "${sourceDir}/CMake/toolchain.riscv32-esp-elf.cmake" - }, - "NF_TARGET_HAS_NANOBOOTER": "OFF", - "RTOS": "ESP32", - "TARGET_SERIES": "ESP32_C3", - "TARGET_BOARD": "ESP32_C3", - "NF_FEATURE_HAS_CONFIG_BLOCK": "ON", - "SUPPORT_ANY_BASE_CONVERSION": "ON", - "API_System.Net": "ON", - "API_System.Math": "ON", - "API_System.Device.Adc": "ON", - "API_System.Device.Dac": "OFF", - "API_System.Device.Gpio": "ON", - "API_System.Device.I2c": "ON", - "API_System.Device.I2s": "OFF", - "API_System.Device.Spi": "ON", - "API_System.Device.Pwm": "ON", - "API_System.Device.Wifi": "ON", - "API_System.IO.Ports": "ON", - "API_Hardware.Esp32": "ON", - "API_nanoFramework.Hardware.Esp32.Rmt": "OFF", - "API_nanoFramework.ResourceManager": "ON", - "API_nanoFramework.System.Collections": "ON", - "API_nanoFramework.System.Text": "ON" - } - }, - { - "name": "ORGPAL_PALTHREE_preset", - "inherits": [ - "general-preset", - "arm-gcc-cortex-preset" - ], - "hidden": true, - "cacheVariables": { - "TARGET_SERIES": "STM32F7xx", - "RTOS": "ChibiOS", - "CHIBIOS_CONTRIB_REQUIRED": "ON", - "STM32_CUBE_PACKAGE_REQUIRED": "ON", - "SUPPORT_ANY_BASE_CONVERSION": "ON", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_RTC": "ON", - "NF_FEATURE_HAS_SDCARD": "ON", - "NF_FEATURE_HAS_CONFIG_BLOCK": "ON", - "NF_FEATURE_HAS_USB_MSD": "ON", - "NF_FEATURE_USE_SPIFFS": "ON", - "NF_BUILD_RTM": "OFF", - "API_System.Math": "ON", - "API_Hardware.Stm32": "ON", - "API_System.Device.Gpio": "ON", - "API_System.Device.Spi": "ON", - "API_System.Device.I2c": "ON", - "API_System.Device.Pwm": "ON", - "API_System.IO.Ports": "ON", - "API_System.Device.Adc": "ON", - "API_System.Device.Dac": "ON", - "API_System.Net": "ON", - "API_nanoFramework.ResourceManager": "ON", - "API_nanoFramework.System.Collections": "ON", - "API_nanoFramework.System.Text": "ON" - } - }, - { - "name": "ST_NUCLEO64_F091RC_preset", - "inherits": [ - "general-preset", - "arm-gcc-cortex-preset" - ], - "hidden": true, - "cacheVariables": { - "TARGET_SERIES": "STM32F0xx", - "RTOS": "ChibiOS", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_RTC": "ON", - "NF_PLATFORM_NO_CLR_TRACE": "ON", - "NF_CLR_NO_IL_INLINE": "ON", - "USE_RNG": "OFF", - "NF_BUILD_RTM": "OFF", - "API_Hardware.Stm32": "ON", - "API_System.Device.Gpio": "ON", - "API_System.Device.Spi": "ON", - "API_System.Device.I2c": "ON", - "API_System.Device.Pwm": "ON", - "API_System.IO.Ports": "ON", - "API_nanoFramework.System.Text": "ON", - "API_nanoFramework.ResourceManager": "ON", - "API_nanoFramework.System.Collections": "ON" - } - }, - { - "name": "ST_STM32F429I_DISCOVERY_preset", - "inherits": [ - "general-preset", - "arm-gcc-cortex-preset" - ], - "hidden": true, - "cacheVariables": { - "RTOS": "ChibiOS", - "TARGET_SERIES": "STM32F4xx", - "CHIBIOS_CONTRIB_REQUIRED": "OFF", - "STM32_CUBE_PACKAGE_REQUIRED": "OFF", - "SUPPORT_ANY_BASE_CONVERSION": "ON", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_RTC": "ON", - "SWO_OUTPUT": "OFF", - "NF_BUILD_RTM": "OFF", - "API_System.Math": "ON", - "API_Hardware.Stm32": "ON", - "API_System.Device.Gpio": "ON", - "API_System.Device.Spi": "ON", - "API_System.Device.I2c": "ON", - "API_System.Device.Pwm": "ON", - "API_System.IO.Ports": "ON", - "API_System.Device.Adc": "ON", - "API_nanoFramework.Device.OneWire": "ON", - "API_nanoFramework.Device.Can": "ON", - "API_nanoFramework.ResourceManager": "ON", - "API_nanoFramework.System.Collections": "ON", - "API_nanoFramework.System.Text": "ON" - } - }, - { - "name": "ST_STM32F769I_DISCOVERY_preset", - "inherits": [ - "general-preset", - "arm-gcc-cortex-preset" - ], - "hidden": true, - "cacheVariables": { - "RTOS": "ChibiOS", - "TARGET_SERIES": "STM32F7xx", - "CHIBIOS_CONTRIB_REQUIRED": "OFF", - "STM32_CUBE_PACKAGE_REQUIRED": "OFF", - "SUPPORT_ANY_BASE_CONVERSION": "ON", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_RTC": "ON", - "NF_FEATURE_HAS_SDCARD": "ON", - "NF_FEATURE_HAS_CONFIG_BLOCK": "ON", - "SWO_OUTPUT": "OFF", - "NF_BUILD_RTM": "OFF", - "API_System.Math": "ON", - "API_Hardware.Stm32": "ON", - "API_System.Device.Gpio": "ON", - "API_System.Device.Spi": "ON", - "API_System.Device.I2c": "ON", - "API_System.Device.Pwm": "ON", - "API_System.IO.Ports": "ON", - "API_System.Device.Adc": "ON", - "API_System.Device.Dac": "ON", - "API_System.Net": "ON", - "API_nanoFramework.Device.OneWire": "ON", - "API_nanoFramework.Device.Can": "ON", - "API_nanoFramework.ResourceManager": "ON", - "API_nanoFramework.System.Collections": "ON", - "API_nanoFramework.System.Text": "ON", - "API_Windows.Storage": "ON", - "API_nanoFramework.Graphics": "ON", - "GRAPHICS_MEMORY": "Graphics_Memory.cpp", - "GRAPHICS_DISPLAY": "Otm8009a_DSI_Video_Mode.cpp", - "GRAPHICS_DISPLAY_INTERFACE": "DSI_To_Display_Video_Mode.cpp", - "TOUCHPANEL_DEVICE": "ft6x06_I2C.cpp", - "TOUCHPANEL_INTERFACE": "I2C_To_TouchPanel.cpp" - } - }, - { - "name": "ST_B_L475E_IOT01A_preset", - "inherits": [ - "general-preset", - "arm-gcc-cortex-preset" - ], - "hidden": true, - "cacheVariables": { - "RTOS": "AzureRTOS", - "TARGET_SERIES": "STM32L4xx", - "CHIBIOS_CONTRIB_REQUIRED": "OFF", - "STM32_CUBE_PACKAGE_REQUIRED": "ON", - "CHIBIOS_HAL_REQUIRED": "ON", - "WIFI_DRIVER": "ISM43362", - "SUPPORT_ANY_BASE_CONVERSION": "OFF", - "NF_PLATFORM_NO_CLR_TRACE": "ON", - "NF_CLR_NO_IL_INLINE": "ON", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_RTC": "ON", - "NF_FEATURE_HAS_SDCARD": "OFF", - "NF_FEATURE_HAS_CONFIG_BLOCK": "ON", - "SWO_OUTPUT": "OFF", - "NF_BUILD_RTM": "OFF", - "API_System.Math": "OFF", - "API_Hardware.Stm32": "OFF", - "API_System.Device.Gpio": "ON", - "API_System.Device.Spi": "ON", - "API_System.Device.I2c": "OFF", - "API_System.Device.Pwm": "OFF", - "API_System.IO.Ports": "ON", - "API_System.Device.Adc": "OFF", - "API_System.Device.Dac": "OFF", - "API_System.Net": "ON", - "API_System.Device.Wifi": "ON", - "API_nanoFramework.Device.OneWire": "OFF", - "API_nanoFramework.Devices.Can": "OFF", - "API_nanoFramework.ResourceManager": "OFF", - "API_nanoFramework.System.Collections": "ON", - "API_nanoFramework.System.Text": "ON", - "API_Windows.Storage": "OFF", - "API_nanoFramework.Graphics": "OFF" - } - }, - { - "name": "ESP32_PSRAM_REV0_preset", - "inherits": [ - "general-preset", - "xtensa-esp32-preset" - ], - "hidden": true, - "cacheVariables": { - "SDK_CONFIG_FILE": "", - "NF_BUILD_RTM": "OFF", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_RTC": "ON", - "NF_FEATURE_HAS_SDCARD": "ON", - "API_System.IO.FileSystem": "ON", - "API_System.Math": "ON", - "API_System.Device.Adc": "ON", - "API_System.Device.Dac": "ON", - "API_System.Device.Gpio": "ON", - "API_System.Device.I2c": "ON", - "API_System.Device.Pwm": "ON", - "API_System.IO.Ports": "ON", - "API_System.Device.Spi": "ON", - "API_nanoFramework.Device.OneWire": "ON", - "API_nanoFramework.ResourceManager": "ON", - "API_nanoFramework.System.Collections": "ON", - "API_nanoFramework.System.Text": "ON" - } - }, - { - "name": "ESP32_PSRAM_REV3_preset", - "inherits": [ - "general-preset", - "xtensa-esp32-preset" - ], - "hidden": true, - "cacheVariables": { - "SDK_CONFIG_FILE": "sdkconfig.default_rev3.esp32", - "NF_BUILD_RTM": "OFF", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_RTC": "ON", - "NF_FEATURE_HAS_SDCARD": "ON", - "API_System.IO.FileSystem": "ON", - "API_nanoFramework.Device.OneWire": "ON", - "API_nanoFramework.ResourceManager": "ON", - "API_nanoFramework.System.Collections": "ON", - "API_nanoFramework.System.Text": "ON" - } - }, - { - "name": "ESP32_REV0_preset", - "inherits": [ - "general-preset", - "xtensa-esp32-preset" - ], - "hidden": true, - "cacheVariables": { - "SDK_CONFIG_FILE": "sdkconfig.default_nopsram.esp32", - "NF_BUILD_RTM": "OFF", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_RTC": "ON", - "NF_FEATURE_HAS_SDCARD": "ON", - "API_System.Net": "ON", - "API_System.IO.FileSystem": "ON", - "API_System.Math": "ON", - "API_System.Device.Adc": "ON", - "API_System.Device.Dac": "ON", - "API_System.Device.Gpio": "ON", - "API_System.Device.I2c": "ON", - "API_System.Device.Pwm": "ON", - "API_System.IO.Ports": "ON", - "API_System.Device.Spi": "ON", - "API_nanoFramework.Device.OneWire": "ON" - } - }, - { - "name": "ESP32_REV3_preset", - "inherits": [ - "general-preset", - "xtensa-esp32-preset" - ], - "hidden": true, - "cacheVariables": { - "SDK_CONFIG_FILE": "sdkconfig.default_nopsram_rev3.esp32", - "NF_BUILD_RTM": "OFF", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_RTC": "ON", - "NF_FEATURE_HAS_SDCARD": "ON", - "API_System.IO.FileSystem": "ON", - "API_nanoFramework.Device.OneWire": "ON" - } - }, - { - "name": "ESP32_PSRAM_XTAL26_REV0_preset", - "inherits": [ - "general-preset", - "xtensa-esp32-preset" - ], - "hidden": true, - "cacheVariables": { - "SDK_CONFIG_FILE": "", - "ESP32_XTAL_FREQ_26": "ON", - "NF_BUILD_RTM": "OFF", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_RTC": "ON", - "NF_FEATURE_HAS_SDCARD": "ON", - "API_System.IO.FileSystem": "ON", - "API_nanoFramework.Device.OneWire": "ON" - } - }, - { - "name": "ESP32_BLE_REV0_preset", - "inherits": [ - "general-preset", - "xtensa-esp32-preset" - ], - "hidden": true, - "cacheVariables": { - "SDK_CONFIG_FILE": "sdkconfig.default_nopsram_ble.esp32", - "NF_BUILD_RTM": "OFF", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_RTC": "ON", - "NF_FEATURE_HAS_SDCARD": "ON", - "API_System.IO.FileSystem": "ON", - "API_nanoFramework.Device.OneWire": "ON", - "API_nanoFramework.Device.Bluetooth": "ON" - } - }, - { - "name": "ESP32_BLE_REV3_preset", - "inherits": [ - "general-preset", - "xtensa-esp32-preset" - ], - "hidden": true, - "cacheVariables": { - "SDK_CONFIG_FILE": "sdkconfig.default_ble_rev3.esp32", - "NF_BUILD_RTM": "OFF", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_RTC": "ON", - "NF_FEATURE_HAS_SDCARD": "ON", - "API_System.IO.FileSystem": "ON", - "API_nanoFramework.Device.OneWire": "ON", - "API_nanoFramework.Device.Bluetooth": "ON" - } - }, - { - "name": "ESP32_PICO_preset", - "inherits": [ - "general-preset", - "xtensa-esp32-preset" - ], - "hidden": true, - "cacheVariables": { - "SDK_CONFIG_FILE": "sdkconfig.default_pico", - "TARGET_SERIAL_BAUDRATE": "115200", - "ESP32_RESERVED_RAM_FOR_IDF_ALLOCATION": "10", - "NF_BUILD_RTM": "OFF", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_RTC": "ON", - "NF_FEATURE_HAS_SDCARD": "ON", - "API_System.IO.FileSystem": "ON", - "API_nanoFramework.Device.OneWire": "ON", - "API_Windows.Storage": "ON" - } - }, - { - "name": "ESP_WROVER_KIT_preset", - "inherits": [ - "general-preset", - "xtensa-esp32-preset" - ], - "hidden": true, - "cacheVariables": { - "SDK_CONFIG_FILE": "", - "NF_BUILD_RTM": "OFF", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_RTC": "ON", - "NF_FEATURE_HAS_SDCARD": "ON", - "API_System.IO.FileSystem": "ON", - "API_Windows.Storage": "ON", - "API_nanoFramework.Graphics": "ON", - "API_nanoFramework.Device.OneWire": "ON", - "GRAPHICS_DISPLAY": "ILI9341_240x320_SPI.cpp", - "TOUCHPANEL_DEVICE": "XPT2046.cpp", - "GRAPHICS_DISPLAY_INTERFACE": "Spi_To_Display.cpp", - "TOUCHPANEL_INTERFACE": "Spi_To_TouchPanel.cpp" - } - }, - { - "name": "ESP32_C3_preset", - "inherits": [ - "general-preset", - "xtensa-esp32c3-preset" - ], - "hidden": true, - "cacheVariables": { - "SDK_CONFIG_FILE": "", - "NF_BUILD_RTM": "OFF", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_RTC": "ON", - "NF_FEATURE_HAS_SDCARD": "OFF", - "API_System.IO.FileSystem": "ON", - "API_Windows.Storage": "ON", - "API_nanoFramework.Device.OneWire": "OFF", - "ESP32_RESERVED_RAM_FOR_IDF_ALLOCATION": "100" - } - }, - { - "name": "M5Stack_preset", - "inherits": [ - "general-preset", - "xtensa-esp32-preset" - ], - "hidden": true, - "cacheVariables": { - "SDK_CONFIG_FILE": "sdkconfig.default_nopsram.esp32", - "NF_BUILD_RTM": "OFF", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_RTC": "ON", - "NF_FEATURE_HAS_SDCARD": "ON", - "API_System.IO.FileSystem": "ON", - "API_Windows.Storage": "ON", - "API_nanoFramework.Device.OneWire": "ON", - "API_nanoFramework.Device.Bluetooth": "OFF", - "API_nanoFramework.Graphics": "ON", - "GRAPHICS_DISPLAY": "ILI9341_240x320_SPI.cpp", - "TOUCHPANEL_DEVICE": "XPT2046.cpp", - "GRAPHICS_DISPLAY_INTERFACE": "Spi_To_Display.cpp", - "TOUCHPANEL_INTERFACE": "Spi_To_TouchPanel.cpp" - } - }, - { - "name": "M5Core_preset", - "inherits": [ - "general-preset", - "xtensa-esp32-preset" - ], - "hidden": true, - "cacheVariables": { - "SDK_CONFIG_FILE": "sdkconfig.default_nopsram.esp32", - "NF_BUILD_RTM": "OFF", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_RTC": "ON", - "NF_FEATURE_HAS_SDCARD": "ON", - "API_System.IO.FileSystem": "ON", - "API_Windows.Storage": "ON", - "API_nanoFramework.Device.OneWire": "ON", - "API_nanoFramework.Graphics": "ON", - "GRAPHICS_DISPLAY": "ILI9342_320x240_SPI.cpp", - "TOUCHPANEL_DEVICE": "XPT2046.cpp", - "GRAPHICS_DISPLAY_INTERFACE": "Spi_To_Display.cpp", - "TOUCHPANEL_INTERFACE": "Spi_To_TouchPanel.cpp" - } - }, - { - "name": "M5Core2_preset", - "inherits": [ - "general-preset", - "xtensa-esp32-preset" - ], - "hidden": true, - "cacheVariables": { - "SDK_CONFIG_FILE": "sdkconfig.default_ble_rev3.esp32", - "NF_BUILD_RTM": "OFF", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_RTC": "ON", - "NF_FEATURE_HAS_SDCARD": "ON", - "API_System.IO.FileSystem": "ON", - "API_Windows.Storage": "ON", - "API_nanoFramework.Device.OneWire": "ON", - "API_nanoFramework.Device.Bluetooth": "ON", - "API_nanoFramework.Graphics": "ON", - "GRAPHICS_DISPLAY": "ILI9342_320x240_SPI.cpp", - "TOUCHPANEL_DEVICE": "XPT2046.cpp", - "GRAPHICS_DISPLAY_INTERFACE": "Spi_To_Display.cpp", - "TOUCHPANEL_INTERFACE": "Spi_To_TouchPanel.cpp", - "ESP32_SPIRAM_FOR_IDF_ALLOCATION": "1024 * 1024" - } - }, - { - "name": "ESP32_LILYGO_preset", - "inherits": [ - "general-preset", - "xtensa-esp32-preset" - ], - "hidden": true, - "cacheVariables": { - "SDK_CONFIG_FILE": "", - "NF_BUILD_RTM": "OFF", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_RTC": "ON", - "NF_FEATURE_HAS_SDCARD": "ON", - "ESP32_ETHERNET_SUPPORT": "ON", - "ETH_PHY_RST_GPIO": "5", - "ETH_RMII_CLK_OUT_GPIO": "17", - "API_System.IO.FileSystem": "ON", - "API_nanoFramework.Device.OneWire": "ON" - } - }, - { - "name": "ESP32_OLIMEX_preset", - "inherits": [ - "general-preset", - "xtensa-esp32-preset" - ], - "hidden": true, - "cacheVariables": { - "SDK_CONFIG_FILE": "", - "ESP32_RESERVED_RAM_FOR_IDF_ALLOCATION": "10", - "NF_BUILD_RTM": "OFF", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_RTC": "ON", - "NF_FEATURE_HAS_SDCARD": "ON", - "ESP32_ETHERNET_SUPPORT": "ON", - "ETH_PHY_RST_GPIO": "12", - "ETH_RMII_CLK_OUT_GPIO": "17", - "API_System.IO.FileSystem": "ON", - "API_nanoFramework.Device.OneWire": "ON" - } - }, - { - "name": "LilygoTWatch2020_preset", - "inherits": [ - "general-preset", - "xtensa-esp32-preset" - ], - "hidden": true, - "cacheVariables": { - "SDK_CONFIG_FILE": "", - "NF_BUILD_RTM": "OFF", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_RTC": "ON", - "API_System.IO.FileSystem": "ON", - "API_nanoFramework.Device.OneWire": "ON", - "API_nanoFramework.Graphics": "ON", - "GRAPHICS_DISPLAY": "ST7789V_240x320_SPI.cpp", - "TOUCHPANEL_DEVICE": "XPT2046.cpp", - "GRAPHICS_DISPLAY_INTERFACE": "Spi_To_Display.cpp", - "TOUCHPANEL_INTERFACE": "Spi_To_TouchPanel.cpp" - } - }, - { - "name": "LilygoTWatch2021_preset", - "inherits": [ - "general-preset", - "xtensa-esp32-preset" - ], - "hidden": true, - "cacheVariables": { - "SDK_CONFIG_FILE": "sdkconfig.default_pico_ble_rev3", - "TARGET_SERIAL_BAUDRATE": "115200", - "NF_BUILD_RTM": "OFF", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_RTC": "OFF", - "NF_FEATURE_HAS_SDCARD": "OFF", - "API_System.IO.FileSystem": "OFF", - "API_nanoFramework.Graphics": "ON", - "API_nanoFramework.Device.OneWire": "OFF", - "API_nanoFramework.Device.Bluetooth": "ON", - "API_nanoFramework.Hardware.Esp32.Rmt": "OFF", - "GRAPHICS_DISPLAY": "GC9A01_240x240_SPI.cpp", - "GRAPHICS_DISPLAY_INTERFACE": "Spi_To_Display.cpp", - "TOUCHPANEL_DEVICE": "CST816S.cpp", - "TOUCHPANEL_INTERFACE": "Spi_To_TouchPanel.cpp" - } - }, - { - "name": "ESP32_ETHERNET_KIT_1.2_preset", - "inherits": [ - "general-preset", - "xtensa-esp32-preset" - ], - "hidden": true, - "cacheVariables": { - "SDK_CONFIG_FILE": "sdkconfig.default_ble_rev3.esp32", - "NF_BUILD_RTM": "OFF", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_RTC": "ON", - "NF_FEATURE_HAS_SDCARD": "ON", - "ESP32_ETHERNET_SUPPORT": "ON", - "ESP32_ETHERNET_INTERFACE": "IP101", - "ETH_PHY_RST_GPIO": "5", - "ETH_RMII_CLK_IN_GPIO": "0", - "ETH_PHY_ADDR": "1", - "API_System.IO.FileSystem": "ON", - "API_nanoFramework.Device.OneWire": "ON", - "API_nanoFramework.Device.Bluetooth": "ON" - } - }, - { - "name": "ESP32_WT32_ETH01_preset", - "inherits": [ - "general-preset", - "xtensa-esp32-preset" - ], - "hidden": true, - "cacheVariables": { - "SDK_CONFIG_FILE": "sdkconfig.default_nopsram.esp32", - "NF_BUILD_RTM": "OFF", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_RTC": "ON", - "NF_FEATURE_HAS_SDCARD": "ON", - "ESP32_ETHERNET_SUPPORT": "ON", - "ETH_RMII_CLK_IN_GPIO": "0", - "ETH_PHY_ADDR": "1", - "ETH_PHY_RST_GPIO": "16", - "API_System.IO.FileSystem": "ON", - "API_nanoFramework.Device.OneWire": "ON" - } - }, - { - "name": "ESP32_WESP32_preset", - "inherits": [ - "general-preset", - "xtensa-esp32-preset" - ], - "hidden": true, - "cacheVariables": { - "SDK_CONFIG_FILE": "", - "ESP32_RESERVED_RAM_FOR_IDF_ALLOCATION": "10", - "NF_BUILD_RTM": "OFF", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_RTC": "ON", - "NF_FEATURE_HAS_SDCARD": "ON", - "ESP32_ETHERNET_SUPPORT": "ON", - "ESP32_ETHERNET_INTERFACE": "RTL8201", - "ETH_RMII_CLK_IN_GPIO": "0", - "ETH_MDIO_GPIO": "17", - "ETH_MDC_GPIO": "16", - "API_System.IO.FileSystem": "ON", - "API_nanoFramework.Device.OneWire": "ON" - } - }, - { - "name": "M5StickC_preset", - "inherits": [ - "general-preset", - "xtensa-esp32-preset" - ], - "hidden": true, - "cacheVariables": { - "SDK_CONFIG_FILE": "sdkconfig.default_pico", - "ESP32_RESERVED_RAM_FOR_IDF_ALLOCATION": "10", - "NF_BUILD_RTM": "OFF", - "NF_FEATURE_DEBUGGER": "ON", - "TARGET_SERIAL_BAUDRATE": "115200", - "NF_FEATURE_RTC": "ON", - "API_System.IO.FileSystem": "ON", - "API_nanoFramework.Device.OneWire": "ON", - "API_nanoFramework.Graphics": "ON", - "GRAPHICS_DISPLAY": "ST7735S_SPI.cpp", - "TOUCHPANEL_DEVICE": "XPT2046.cpp", - "GRAPHICS_DISPLAY_INTERFACE": "Spi_To_Display.cpp", - "TOUCHPANEL_INTERFACE": "Spi_To_TouchPanel.cpp" - } - }, - { - "name": "M5StickCPlus_preset", - "inherits": [ - "general-preset", - "xtensa-esp32-preset" - ], - "hidden": true, - "cacheVariables": { - "SDK_CONFIG_FILE": "sdkconfig.default_nopsram.esp32", - "NF_BUILD_RTM": "OFF", - "NF_FEATURE_DEBUGGER": "ON", - "TARGET_SERIAL_BAUDRATE": "115200", - "NF_FEATURE_RTC": "ON", - "API_System.IO.FileSystem": "ON", - "API_nanoFramework.Device.OneWire": "ON", - "API_nanoFramework.Graphics": "ON", - "GRAPHICS_DISPLAY": "ST7789V_240x320_SPI.cpp", - "TOUCHPANEL_DEVICE": "XPT2046.cpp", - "GRAPHICS_DISPLAY_INTERFACE": "Spi_To_Display.cpp", - "TOUCHPANEL_INTERFACE": "Spi_To_TouchPanel.cpp" - } - }, - { - "name": "FEATHER_S2_preset", - "inherits": [ - "general-preset", - "xtensa-esp32s2-preset" - ], - "hidden": true, - "cacheVariables": { - "SDK_CONFIG_FILE": "sdkconfig.default.esp32s2", - "NF_BUILD_RTM": "OFF", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_RTC": "ON", - "NF_FEATURE_HAS_SDCARD": "OFF", - "ESP32_ETHERNET_SUPPORT": "OFF", - "ESP32_CONFIG_PIN_PHY_POWER": "", - "ESP32_CONFIG_PHY_CLOCK_MODE": "", - "ESP32_USB_CDC": "ON", - "API_nanoFramework.Device.OneWire": "OFF" - } - }, - { - "name": "KALUGA_1_preset", - "inherits": [ - "general-preset", - "xtensa-esp32s2-preset" - ], - "hidden": true, - "cacheVariables": { - "SDK_CONFIG_FILE": "sdkconfig.default.esp32s2", - "NF_BUILD_RTM": "OFF", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_RTC": "ON", - "API_nanoFramework.Graphics": "ON", - "GRAPHICS_DISPLAY": "ILI9341_240x320_SPI.cpp", - "TOUCHPANEL_DEVICE": "XPT2046.cpp", - "GRAPHICS_DISPLAY_INTERFACE": "Spi_To_Display.cpp", - "TOUCHPANEL_INTERFACE": "Spi_To_TouchPanel.cpp" - } - }, - { - "name": "NXP_MIMXRT1060_EVK_preset", - "inherits": [ - "general-preset", - "arm-gcc-cortex-preset" - ], - "hidden": true, - "cacheVariables": { - "TARGET_SERIES": "IMXRT10xx", - "SUPPORT_ANY_BASE_CONVERSION": "ON", - "RTOS": "FreeRTOS", - "RTOS_VERSION": "", - "CMSIS_VERSION": "", - "FATFS_VERSION": "", - "LWIP_VERSION": "", - "NF_BUILD_RTM": "OFF", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_HAS_SDCARD": "ON", - "NF_FEATURE_RTC": "ON", - "NF_FEATURE_HAS_CONFIG_BLOCK": "ON", - "NF_SECURITY_MBEDTLS": "OFF", - "API_System.Device.Gpio": "ON", - "API_System.Device.I2c": "OFF", - "API_System.Device.Adc": "OFF", - "API_System.IO.Ports": "ON", - "API_nanoFramework.ResourceManager": "ON", - "API_nanoFramework.System.Collections": "ON", - "API_System.Net": "ON", - "API_System.Math": "ON" - } - }, - { - "name": "TI_CC1352R1_LAUNCHXL_preset", - "inherits": [ - "general-preset", - "arm-gcc-cortex-preset" - ], - "hidden": true, - "cacheVariables": { - "RTOS": "TI_SimpleLink", - "TARGET_SERIES": "CC13X2", - "TARGET_BOARD": "TI_CC1352R1_LAUNCHXL", - "SUPPORT_ANY_BASE_CONVERSION": "OFF", - "NF_TARGET_HAS_NANOBOOTER": "OFF", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_WATCHDOG": "OFF", - "NF_FEATURE_RTC": "ON", - "NF_FEATURE_HAS_SDCARD": "OFF", - "NF_BUILD_RTM": "OFF", - "API_System.Math": "OFF", - "API_System.Device.Gpio": "ON", - "API_System.Device.Spi": "OFF", - "API_System.Device.I2c": "OFF", - "API_System.Device.Pwm": "OFF", - "API_System.Device.Adc": "ON", - "API_System.IO.Ports": "OFF", - "API_nanoFramework.ResourceManager": "OFF", - "API_nanoFramework.System.Collections": "OFF", - "API_nanoFramework.System.Text": "ON", - "API_nanoFramework.TI.EasyLink": "ON", - "API_nanoFramework.Hardware.TI": "ON" - } - }, - { - "name": "TI_CC3220SF_LAUNCHXL_preset", - "inherits": [ - "general-preset", - "arm-gcc-cortex-preset" - ], - "hidden": true, - "cacheVariables": { - "RTOS": "TI_SimpleLink", - "TARGET_SERIES": "CC32xx", - "TARGET_BOARD": "TI_CC3220SF_LAUNCHXL", - "SUPPORT_ANY_BASE_CONVERSION": "OFF", - "NF_TARGET_HAS_NANOBOOTER": "OFF", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_RTC": "ON", - "NF_FEATURE_WATCHDOG": "OFF", - "NF_FEATURE_HAS_SDCARD": "OFF", - "NF_FEATURE_HAS_CONFIG_BLOCK": "ON", - "NF_BUILD_RTM": "OFF", - "API_System.Math": "ON", - "API_System.Device.Gpio": "ON", - "API_System.Device.Spi": "ON", - "API_System.Device.I2c": "ON", - "API_System.Device.Pwm": "ON", - "API_System.IO.Ports": "OFF", - "API_System.Net": "ON", - "API_nanoFramework.ResourceManager": "OFF", - "API_nanoFramework.System.Collections": "ON", - "API_nanoFramework.System.Text": "ON" - } - }, - { - "name": "BrainPad2_preset", - "inherits": [ - "general-preset", - "arm-gcc-cortex-preset" - ], - "hidden": true, - "cacheVariables": { - "RTOS": "ChibiOS", - "TARGET_SERIES": "STM32F4xx", - "CHIBIOS_CONTRIB_REQUIRED": "OFF", - "STM32_CUBE_PACKAGE_REQUIRED": "OFF", - "SUPPORT_ANY_BASE_CONVERSION": "OFF", - "USE_RNG": "OFF", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_RTC": "ON", - "NF_FEATURE_HAS_SDCARD": "OFF", - "SWO_OUTPUT": "OFF", - "NF_BUILD_RTM": "OFF", - "API_System.Math": "ON", - "API_Hardware.Stm32": "ON", - "API_System.Device.Gpio": "ON", - "API_System.Device.Spi": "ON", - "API_System.Device.I2c": "ON", - "API_System.Device.Pwm": "ON", - "API_System.IO.Ports": "ON", - "API_System.Device.Adc": "ON", - "API_nanoFramework.Devices.OneWire": "OFF", - "API_nanoFramework.Device.Can": "OFF", - "API_nanoFramework.ResourceManager": "ON", - "API_nanoFramework.System.Collections": "ON", - "API_nanoFramework.System.Text": "ON" - } - }, - { - "name": "GHI_FEZ_CERB40_NF_preset", - "inherits": [ - "general-preset", - "arm-gcc-cortex-preset" - ], - "hidden": true, - "cacheVariables": { - "TARGET_SERIES": "STM32F4xx", - "USE_RNG": "ON", - "DP_FLOATINGPOINT": "OFF", - "SUPPORT_ANY_BASE_CONVERSION": "OFF", - "RTOS": "ChibiOS", - "SWO_OUTPUT": "OFF", - "NF_BUILD_RTM": "OFF", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_RTC": "ON", - "NF_FEATURE_HAS_CONFIG_BLOCK": "OFF", - "NF_FEATURE_USE_FILESYSTEM": "OFF", - "NF_NETWORKING_SNTP": "OFF", - "API_Hardware.Stm32": "ON", - "API_nanoFramework.Device.Can": "OFF", - "API_nanoFramework.Device.OneWire": "OFF", - "API_System.Math": "ON", - "API_System.Net": "OFF", - "API_System.Device.Adc": "ON", - "API_System.Device.Gpio": "ON", - "API_System.Device.Pwm": "ON", - "API_System.IO.Ports": "ON", - "API_System.Device.Spi": "ON", - "API_Windows.Storage": "OFF" - } - }, - { - "name": "I2M_ELECTRON_NF_preset", - "inherits": [ - "general-preset", - "arm-gcc-cortex-preset" - ], - "hidden": true, - "cacheVariables": { - "TARGET_SERIES": "STM32F4xx", - "USE_FPU": "ON", - "USE_RNG": "OFF", - "DP_FLOATINGPOINT": "OFF", - "SUPPORT_ANY_BASE_CONVERSION": "OFF", - "RTOS": "ChibiOS", - "CHIBIOS_CONTRIB_REQUIRED": "OFF", - "SWO_OUTPUT": "OFF", - "NF_BUILD_RTM": "OFF", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_RTC": "ON", - "NF_FEATURE_HAS_CONFIG_BLOCK": "OFF", - "NF_FEATURE_HAS_SDCARD": "OFF", - "NF_FEATURE_HAS_USB_MSD": "OFF", - "NF_NETWORKING_SNTP": "OFF", - "API_Hardware.Stm32": "ON", - "API_nanoFramework.Device.Can": "OFF", - "API_nanoFramework.Device.OneWire": "OFF", - "API_System.Math": "ON", - "API_System.Net": "OFF", - "API_System.Device.Adc": "ON", - "API_System.Devices.Dac": "OFF", - "API_System.Device.Gpio": "ON", - "API_System.Device.I2c": "ON", - "API_System.Device.Pwm": "ON", - "API_System.IO.Ports": "ON", - "API_System.Device.Spi": "ON", - "API_Windows.Storage": "OFF" - } - }, - { - "name": "I2M_OXYGEN_NF_preset", - "inherits": [ - "general-preset", - "arm-gcc-cortex-preset" - ], - "hidden": true, - "cacheVariables": { - "TARGET_SERIES": "STM32F4xx", - "USE_RNG": "OFF", - "DP_FLOATINGPOINT": "OFF", - "SUPPORT_ANY_BASE_CONVERSION": "OFF", - "RTOS": "ChibiOS", - "CHIBIOS_CONTRIB_REQUIRED": "OFF", - "SWO_OUTPUT": "OFF", - "NF_BUILD_RTM": "OFF", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_RTC": "ON", - "NF_FEATURE_HAS_CONFIG_BLOCK": "OFF", - "NF_FEATURE_HAS_SDCARD": "OFF", - "NF_FEATURE_HAS_USB_MSD": "OFF", - "NF_NETWORKING_SNTP": "OFF", - "API_Hardware.Stm32": "ON", - "API_nanoFramework.Device.Can": "OFF", - "API_nanoFramework.Device.OneWire": "OFF", - "API_System.Math": "ON", - "API_System.Net": "OFF", - "API_System.Device.Adc": "ON", - "API_System.Device.Gpio": "ON", - "API_System.Device.I2c": "ON", - "API_System.Device.Pwm": "ON", - "API_System.IO.Ports": "ON", - "API_System.Device.Spi": "ON", - "API_Windows.Storage": "OFF" - } - }, - { - "name": "MBN_QUAIL_preset", - "inherits": [ - "general-preset", - "arm-gcc-cortex-preset" - ], - "hidden": true, - "cacheVariables": { - "RTOS": "ChibiOS", - "TARGET_SERIES": "STM32F4xx", - "CHIBIOS_CONTRIB_REQUIRED": "OFF", - "STM32_CUBE_PACKAGE_REQUIRED": "OFF", - "SUPPORT_ANY_BASE_CONVERSION": "ON", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_RTC": "ON", - "NF_BUILD_RTM": "OFF", - "API_System.Math": "ON", - "API_Hardware.Stm32": "ON", - "API_System.Device.Gpio": "ON", - "API_System.Device.Spi": "ON", - "API_System.Device.I2c": "ON", - "API_System.Device.Pwm": "ON", - "API_System.IO.Ports": "ON", - "API_nanoFramework.Device.OneWire": "ON", - "API_nanoFramework.ResourceManager": "ON", - "API_nanoFramework.System.Collections": "ON", - "API_nanoFramework.System.Text": "ON" - } - }, - { - "name": "NETDUINO3_WIFI_preset", - "inherits": [ - "general-preset", - "arm-gcc-cortex-preset" - ], - "hidden": true, - "cacheVariables": { - "RTOS": "ChibiOS", - "TARGET_SERIES": "STM32F4xx", - "CHIBIOS_CONTRIB_REQUIRED": "OFF", - "STM32_CUBE_PACKAGE_REQUIRED": "OFF", - "SUPPORT_ANY_BASE_CONVERSION": "ON", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_RTC": "ON", - "NF_FEATURE_HAS_SDCARD": "ON", - "SWO_OUTPUT": "OFF", - "NF_BUILD_RTM": "OFF", - "API_System.Math": "ON", - "API_Hardware.Stm32": "ON", - "API_System.Device.Gpio": "ON", - "API_System.Device.Spi": "ON", - "API_System.Device.I2c": "ON", - "API_System.Device.Pwm": "ON", - "API_System.IO.Ports": "ON", - "API_System.Device.Adc": "ON", - "API_nanoFramework.Device.OneWire": "ON", - "API_nanoFramework.ResourceManager": "ON", - "API_nanoFramework.System.Collections": "ON", - "API_nanoFramework.System.Text": "ON" - } - }, - { - "name": "PybStick2x_preset", - "inherits": [ - "general-preset", - "arm-gcc-cortex-preset" - ], - "hidden": true, - "cacheVariables": { - "TARGET_SERIES": "STM32F4xx", - "USE_FPU": "ON", - "USE_RNG": "OFF", - "DP_FLOATINGPOINT": "OFF", - "SUPPORT_ANY_BASE_CONVERSION": "OFF", - "RTOS": "ChibiOS", - "CHIBIOS_CONTRIB_REQUIRED": "OFF", - "SWO_OUTPUT": "OFF", - "NF_BUILD_RTM": "OFF", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_RTC": "ON", - "NF_FEATURE_HAS_CONFIG_BLOCK": "OFF", - "NF_FEATURE_HAS_SDCARD": "ON", - "NF_FEATURE_HAS_USB_MSD": "OFF", - "NF_NETWORKING_SNTP": "OFF", - "API_Hardware.Stm32": "ON", - "API_nanoFramework.Device.Can": "OFF", - "API_nanoFramework.Device.OneWire": "OFF", - "API_System.Math": "ON", - "API_System.Net": "OFF", - "API_System.Devices.Dac": "OFF", - "API_System.Device.Gpio": "ON", - "API_System.Device.I2c": "ON", - "API_System.IO.Ports": "ON", - "API_System.Device.Spi": "ON", - "API_System.IO.FileSystem": "ON", - "API_Windows.Storage": "ON", - "API_nanoFramework.System.Text": "ON" - } - }, - { - "name": "ST_NUCLEO64_F401RE_NF_preset", - "inherits": [ - "general-preset", - "arm-gcc-cortex-preset" - ], - "hidden": true, - "cacheVariables": { - "TARGET_SERIES": "STM32F4xx", - "USE_RNG": "OFF", - "DP_FLOATINGPOINT": "OFF", - "SUPPORT_ANY_BASE_CONVERSION": "OFF", - "RTOS": "ChibiOS", - "CHIBIOS_CONTRIB_REQUIRED": "OFF", - "SWO_OUTPUT": "OFF", - "NF_BUILD_RTM": "OFF", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_RTC": "ON", - "NF_FEATURE_HAS_CONFIG_BLOCK": "OFF", - "NF_FEATURE_HAS_SDCARD": "OFF", - "NF_FEATURE_HAS_USB_MSD": "OFF", - "NF_NETWORKING_SNTP": "OFF", - "API_Hardware.Stm32": "ON", - "API_nanoFramework.Device.Can": "OFF", - "API_nanoFramework.Device.OneWire": "ON", - "API_System.Math": "ON", - "API_System.Net": "OFF", - "API_System.Device.Adc": "ON", - "API_System.Device.Gpio": "ON", - "API_System.Device.I2c": "ON", - "API_System.Device.Pwm": "ON", - "API_System.IO.Ports": "ON", - "API_System.Device.Spi": "ON", - "API_Windows.Storage": "OFF" - } - }, - { - "name": "ST_NUCLEO64_F411RE_NF_preset", - "inherits": [ - "general-preset", - "arm-gcc-cortex-preset" - ], - "hidden": true, - "cacheVariables": { - "RTOS": "ChibiOS", - "TARGET_SERIES": "STM32F4xx", - "CHIBIOS_CONTRIB_REQUIRED": "OFF", - "STM32_CUBE_PACKAGE_REQUIRED": "OFF", - "USE_RNG": "OFF", - "DP_FLOATINGPOINT": "OFF", - "SUPPORT_ANY_BASE_CONVERSION": "OFF", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_RTC": "ON", - "SWO_OUTPUT": "OFF", - "NF_BUILD_RTM": "OFF", - "API_System.Math": "ON", - "API_Hardware.Stm32": "ON", - "API_System.Device.Gpio": "ON", - "API_System.Device.Spi": "ON", - "API_System.Device.I2c": "ON", - "API_System.Device.Pwm": "ON", - "API_System.IO.Ports": "ON", - "API_System.Device.Adc": "ON", - "API_nanoFramework.Devices.OneWire": "OFF", - "API_nanoFramework.Device.Can": "OFF", - "API_nanoFramework.ResourceManager": "ON", - "API_nanoFramework.System.Collections": "ON", - "API_nanoFramework.System.Text": "ON" - } - }, - { - "name": "ST_NUCLEO144_F412ZG_NF_preset", - "inherits": [ - "general-preset", - "arm-gcc-cortex-preset" - ], - "hidden": true, - "cacheVariables": { - "TARGET_SERIES": "STM32F4xx", - "USE_RNG": "ON", - "DP_FLOATINGPOINT": "OFF", - "SUPPORT_ANY_BASE_CONVERSION": "OFF", - "RTOS": "ChibiOS", - "TARGET_BOARD": "ST_NUCLEO144_F412ZG_NF", - "SWO_OUTPUT": "OFF", - "NF_BUILD_RTM": "OFF", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_RTC": "ON", - "NF_FEATURE_USE_FILESYSTEM": "OFF", - "NF_NETWORKING_SNTP": "OFF", - "API_Hardware.Stm32": "ON", - "API_nanoFramework.Device.Can": "OFF", - "API_nanoFramework.Device.OneWire": "OFF", - "API_System.Math": "ON", - "API_System.Net": "OFF", - "API_System.Device.Adc": "ON", - "API_System.Device.Gpio": "ON", - "API_System.Device.I2c": "ON", - "API_System.Device.Pwm": "ON", - "API_System.IO.Ports": "ON", - "API_System.Device.Spi": "ON", - "API_windows.Storage": "OFF" - } - }, - { - "name": "ST_NUCLEO144_F439ZI_preset", - "inherits": [ - "general-preset", - "arm-gcc-cortex-preset" - ], - "hidden": true, - "cacheVariables": { - "TARGET_SERIES": "STM32F4xx", - "USE_RNG": "ON", - "DP_FLOATINGPOINT": "OFF", - "SUPPORT_ANY_BASE_CONVERSION": "OFF", - "RTOS": "ChibiOS", - "CHIBIOS_CONTRIB_REQUIRED": "OFF", - "SWO_OUTPUT": "OFF", - "NF_BUILD_RTM": "OFF", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_RTC": "ON", - "NF_FEATURE_HAS_CONFIG_BLOCK": "ON", - "NF_FEATURE_HAS_SDCARD": "OFF", - "NF_FEATURE_HAS_USB_MSD": "OFF", - "NF_NETWORKING_SNTP": "ON", - "API_Hardware.Stm32": "ON", - "API_nanoFramework.Device.Can": "OFF", - "API_nanoFramework.Device.OneWire": "OFF", - "API_System.Math": "OFF", - "API_System.Net": "ON", - "API_System.Device.Adc": "ON", - "API_System.Device.Gpio": "ON", - "API_System.Device.I2c": "ON", - "API_System.Device.Pwm": "ON", - "API_System.IO.Ports": "ON", - "API_System.Device.Spi": "ON", - "API_Windows.Storage": "OFF" - } - }, - { - "name": "ST_NUCLEO144_F746ZG_preset", - "inherits": [ - "general-preset", - "arm-gcc-cortex-preset" - ], - "hidden": true, - "cacheVariables": { - "TARGET_SERIES": "STM32F7xx", - "USE_RNG": "ON", - "DP_FLOATINGPOINT": "OFF", - "SUPPORT_ANY_BASE_CONVERSION": "OFF", - "RTOS": "ChibiOS", - "CHIBIOS_CONTRIB_REQUIRED": "OFF", - "STM32_CUBE_PACKAGE_REQUIRED": "OFF", - "SWO_OUTPUT": "OFF", - "FATFS_VERSION": "R0.14", - "NF_BUILD_RTM": "OFF", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_RTC": "ON", - "NF_FEATURE_HAS_CONFIG_BLOCK": "ON", - "NF_FEATURE_HAS_SDCARD": "OFF", - "NF_FEATURE_HAS_USB_MSD": "OFF", - "NF_FEATURE_USE_SPIFFS": "OFF", - "NF_NETWORKING_SNTP": "ON", - "API_Hardware.Stm32": "ON", - "API_nanoFramework.Device.Can": "OFF", - "API_nanoFramework.Device.OneWire": "ON", - "API_nanoFramework.ResourceManager": "ON", - "API_nanoFramework.System.Collections": "ON", - "API_nanoFramework.System.Text": "ON", - "API_System.Math": "ON", - "API_System.Net": "ON", - "API_System.Device.Adc": "ON", - "API_System.Device.Gpio": "ON", - "API_System.Device.I2c": "ON", - "API_System.Device.Pwm": "ON", - "API_System.IO.Ports": "ON", - "API_System.Device.Spi": "ON", - "API_Windows.Storage": "OFF" - } - }, - { - "name": "ST_STM32F4_DISCOVERY_preset", - "inherits": [ - "general-preset", - "arm-gcc-cortex-preset" - ], - "hidden": true, - "cacheVariables": { - "TARGET_SERIES": "STM32F4xx", - "USE_RNG": "ON", - "DP_FLOATINGPOINT": "OFF", - "SUPPORT_ANY_BASE_CONVERSION": "OFF", - "RTOS": "ChibiOS", - "SWO_OUTPUT": "OFF", - "NF_BUILD_RTM": "OFF", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_RTC": "ON", - "NF_FEATURE_HAS_CONFIG_BLOCK": "OFF", - "NF_FEATURE_USE_FILESYSTEM": "OFF", - "NF_NETWORKING_SNTP": "OFF", - "API_Hardware.Stm32": "ON", - "API_nanoFramework.Device.Can": "ON", - "API_nanoFramework.Device.OneWire": "ON", - "API_System.Math": "ON", - "API_System.Net": "OFF", - "API_System.Device.Adc": "ON", - "API_System.Device.Gpio": "ON", - "API_System.Device.I2c": "ON", - "API_System.Device.Pwm": "ON", - "API_System.IO.Ports": "ON", - "API_System.Device.Spi": "ON", - "API_Windows.Storage": "OFF" - } - }, - { - "name": "ST_STM32F411_DISCOVERY_preset", - "inherits": [ - "general-preset", - "arm-gcc-cortex-preset" - ], - "hidden": true, - "cacheVariables": { - "TARGET_SERIES": "STM32F4xx", - "USE_RNG": "OFF", - "DP_FLOATINGPOINT": "OFF", - "SUPPORT_ANY_BASE_CONVERSION": "OFF", - "RTOS": "ChibiOS", - "CHIBIOS_CONTRIB_REQUIRED": "OFF", - "SWO_OUTPUT": "OFF", - "NF_BUILD_RTM": "OFF", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_RTC": "ON", - "NF_FEATURE_HAS_CONFIG_BLOCK": "OFF", - "NF_FEATURE_HAS_SDCARD": "OFF", - "NF_FEATURE_HAS_USB_MSD": "OFF", - "NF_NETWORKING_SNTP": "OFF", - "API_Hardware.Stm32": "ON", - "API_nanoFramework.Device.Can": "OFF", - "API_nanoFramework.Device.OneWire": "OFF", - "API_nanoFramework.System.Collections": "ON", - "API_nanoFramework.System.Text": "ON", - "API_System.Math": "ON", - "API_System.Net": "OFF", - "API_System.Device.Adc": "ON", - "API_Windows.Devices.Dac": "OFF", - "API_System.Device.Gpio": "ON", - "API_System.Device.I2c": "ON", - "API_System.Device.Pwm": "ON", - "API_System.IO.Ports": "ON", - "API_System.Device.Spi": "ON", - "API_Windows.Storage": "OFF" - } - }, - { - "name": "WEACT_F411CE_preset", - "inherits": [ - "general-preset", - "arm-gcc-cortex-preset" - ], - "hidden": true, - "cacheVariables": { - "TARGET_SERIES": "STM32F4xx", - "USE_RNG": "OFF", - "DP_FLOATINGPOINT": "OFF", - "SUPPORT_ANY_BASE_CONVERSION": "OFF", - "RTOS": "CHIBIOS", - "CHIBIOS_CONTRIB_REQUIRED": "OFF", - "SWO_OUTPUT": "OFF", - "NF_BUILD_RTM": "OFF", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_RTC": "ON", - "NF_FEATURE_HAS_CONFIG_BLOCK": "OFF", - "NF_FEATURE_HAS_SDCARD": "OFF", - "NF_FEATURE_HAS_USB_MSD": "OFF", - "NF_NETWORKING_SNTP": "OFF", - "API_Hardware.Stm32": "ON", - "API_nanoFramework.Device.Can": "OFF", - "API_nanoFramework.Device.OneWire": "OFF", - "API_System.Math": "ON", - "API_System.Net": "OFF", - "API_System.Device.Adc": "ON", - "API_System.Device.Gpio": "ON", - "API_System.Device.I2c": "ON", - "API_System.Device.Pwm": "ON", - "API_System.IO.Ports": "ON", - "API_System.Device.Spi": "ON", - "API_Windows.Storage": "OFF" - } - }, - { - "name": "TI_CC1352P1_LAUNCHXL_preset", - "inherits": [ - "general-preset", - "arm-gcc-cortex-preset" - ], - "hidden": true, - "cacheVariables": { - "RTOS": "TI_SimpleLink", - "TARGET_SERIES": "CC13X2", - "SUPPORT_ANY_BASE_CONVERSION": "OFF", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_RTC": "ON", - "NF_FEATURE_HAS_SDCARD": "OFF", - "NF_BUILD_RTM": "OFF", - "API_System.Math": "ON", - "API_System.Device.Gpio": "ON", - "API_System.Device.Adc": "ON", - "API_nanoFramework.ResourceManager": "OFF", - "API_nanoFramework.System.Collections": "OFF", - "API_nanoFramework.System.Text": "ON", - "API_nanoFramework.TI.EasyLink": "ON", - "API_nanoFramework.Hardware.TI": "ON" - } - }, - { - "name": "ESP32_PSRAM_REV0_UI_preset", - "description": "", - "displayName": "", - "inherits": [ - "general-preset", - "xtensa-esp32-preset" - ], - "hidden": true, - "cacheVariables": { - "SDK_CONFIG_FILE": "", - "NF_BUILD_RTM": "OFF", - "NF_FEATURE_DEBUGGER": "ON", - "NF_FEATURE_RTC": "ON", - "NF_FEATURE_HAS_SDCARD": "ON", - "API_System.IO.FileSystem": "ON", - "API_System.Math": "ON", - "API_System.Device.Adc": "ON", - "API_System.Device.Dac": "ON", - "API_System.Device.Gpio": "ON", - "API_System.Device.I2c": "ON", - "API_System.Device.Pwm": "ON", - "API_System.IO.Ports": "ON", - "API_System.Device.Spi": "ON", - "API_nanoFramework.Device.OneWire": "ON", - "API_nanoFramework.ResourceManager": "ON", - "API_nanoFramework.System.Collections": "ON", - "API_nanoFramework.System.Text": "ON", - "API_nanoFramework.Graphics": "ON", - "GRAPHICS_DISPLAY": "ILI9341_XXXxYYY_SPI.cpp", - "GRAPHICS_DISPLAY_INTERFACE": "Spi_To_Display.cpp", - "TOUCHPANEL_DEVICE": "XPT2046.cpp", - "TOUCHPANEL_INTERFACE": "Spi_To_TouchPanel.cpp" - } - } + "version": 4, + "include": [ + "CMake/arm-gcc.json", + "CMake/xtensa-esp32.json", + "CMake/xtensa-esp32c3.json", + "CMake/xtensa-esp32s2.json", + "CMake/xtensa-esp32s3.json", + "targets/AzureRTOS/CMakePresets.json", + "targets/ChibiOS/CMakePresets.json", + "targets/ESP32/CMakePresets.json", + "targets/FreeRTOS/CMakePresets.json", + "targets/TI_SimpleLink/CMakePresets.json", + "targets-community/CMakePresets.json" ] } \ No newline at end of file diff --git a/CMakeUserPresets.TEMPLATE.json b/CMakeUserPresets.TEMPLATE.json deleted file mode 100644 index e756643063..0000000000 --- a/CMakeUserPresets.TEMPLATE.json +++ /dev/null @@ -1,997 +0,0 @@ -{ - "version": 3, - "configurePresets": [ - { - "name": "user-local-tools", - "description": "Cache variables with paths to local tools. Please replace with your own paths. Set to null to use build defaults or completly remove if your not building the concerned target.", - "hidden": true, - "cacheVariables": { - "TOOL_HEX2DFU_PREFIX": "", - "TOOL_SRECORD_PREFIX": "", - "CHIBIOS_SOURCE_FOLDER": "", - "FREERTOS_SOURCE_FOLDER": "", - "CHIBIOS_CONTRIB_SOURCE": "", - "CHIBIOS_HAL_SOURCE": "", - "STM32_CUBE_PACKAGE_SOURCE": "", - "MBEDTLS_SOURCE": "", - "FATFS_SOURCE": "", - "SPIFFS_SOURCE": "", - "ESP32_IDF_PATH": "", - "TI_SL_CC32xx_SDK_SOURCE": "", - "TI_SL_CC13xx_26xx_SDK_SOURCE": "", - "TI_XDCTOOLS_SOURCE": "", - "TI_SYSCONFIG_SOURCE": "" - } - }, - { - "name": "user-local-tools-container", - "description": "Cache variables with paths to local tools. Please replace with your own paths. Set to null to use build defaults or completly remove if your not building the concerned target.", - "hidden": true, - "cacheVariables": { - "TOOL_HEX2DFU_PREFIX": "/usr/local/bin/hex2dfu", - "TOOL_SRECORD_PREFIX": "/usr/bin", - "CHIBIOS_SOURCE_FOLDER": "/sources/ChibiOs", - "FREERTOS_SOURCE_FOLDER": "/sources/FreeRTOS", - "CHIBIOS_CONTRIB_SOURCE": "/sources/ChibiOs-Contrib", - "CHIBIOS_HAL_SOURCE": "/sources/ChibiOs", - "STM32_CUBE_PACKAGE_SOURCE": "/sources/STM32CubeL4", - "MBEDTLS_SOURCE": "/sources/mbedtls", - "FATFS_SOURCE": "/sources/fatfs", - "SPIFFS_SOURCE": "/sources/spiffs", - "ESP32_IDF_PATH": "/sources/esp-idf", - "TI_SL_CC32xx_SDK_SOURCE": "/sources/SimpleLinkCC32", - "TI_SL_CC13xx_26xx_SDK_SOURCE": "/sources/SimpleLinkCC13", - "TI_XDCTOOLS_SOURCE": "/usr/local/bin/titools", - "TI_SYSCONFIG_SOURCE": "/sources/TI_SysConfig", - "AZURERTOS_SOURCE_FOLDER": "/sources/AzureRTOS", - "NETXDUO_SOURCE_FOLDER": "/sources/NextDuo" - } - }, - { - "name": "user-prefs", - "description": "Cache variables with user preferences general to all builds and targets.", - "hidden": true, - "cacheVariables": { - "CMAKE_BUILD_TYPE": "Debug", - "BUILD_VERSION": "0.9.99.999", - "BUILD_VERBOSE": "OFF", - "NF_WP_TRACE_ERRORS": "OFF", - "NF_WP_TRACE_HEADERS": "OFF", - "NF_WP_TRACE_STATE": "OFF", - "NF_WP_TRACE_NODATA": "OFF", - "NF_WP_TRACE_ALL": "OFF", - "NF_WP_IMPLEMENTS_CRC32": "OFF", - "NF_PLATFORM_NO_CLR_TRACE": "OFF", - "NF_CLR_NO_IL_INLINE": "OFF", - "NF_FEATURE_WATCHDOG": "ON", - "SWO_OUTPUT": "OFF" - } - }, - { - "name": "user-local-tools-cloud", - "description": "Empty preset to be used in cloud builds", - "hidden": true - }, - { - "name": "ORGPAL_PALTHREE", - "inherits": [ - "user-local-tools", - "user-prefs", - "ORGPAL_PALTHREE_preset" - ], - "cacheVariables": { - "TARGET_BOARD": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null - } - }, - { - "name": "ST_NUCLEO64_F091RC", - "inherits": [ - "user-local-tools", - "user-prefs", - "ST_NUCLEO64_F091RC_preset" - ], - "cacheVariables": { - "TARGET_BOARD": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null, - "NF_FEATURE_BINARY_SERIALIZATION": "OFF" - } - }, - { - "name": "ST_STM32F429I_DISCOVERY", - "inherits": [ - "user-local-tools", - "user-prefs", - "ST_STM32F429I_DISCOVERY_preset" - ], - "cacheVariables": { - "TARGET_BOARD": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null - } - }, - { - "name": "ST_STM32F769I_DISCOVERY", - "inherits": [ - "user-local-tools", - "user-prefs", - "ST_STM32F769I_DISCOVERY_preset" - ], - "cacheVariables": { - "TARGET_BOARD": { - "type": "STRING", - "value": "${presetName}" - }, - "NF_INTEROP_ASSEMBLIES": null - } - }, - { - "name": "ST_B_L475E_IOT01A", - "inherits": [ - "user-local-tools", - "user-prefs", - "ST_B_L475E_IOT01A_preset" - ], - "cacheVariables": { - "TARGET_BOARD": { - "type": "STRING", - "value": "${presetName}" - }, - "NF_INTEROP_ASSEMBLIES": null - } - }, - { - "name": "ESP32_PSRAM_REV0", - "inherits": [ - "user-local-tools", - "user-prefs", - "ESP32_PSRAM_REV0_preset" - ], - "cacheVariables": { - "TARGET_NAME": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null - } - }, - { - "name": "ESP32_PSRAM_REV3", - "inherits": [ - "user-local-tools", - "user-prefs", - "ESP32_PSRAM_REV3_preset" - ], - "cacheVariables": { - "TARGET_NAME": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null - } - }, - { - "name": "ESP32_REV0", - "inherits": [ - "user-local-tools", - "user-prefs", - "ESP32_REV0_preset" - ], - "cacheVariables": { - "TARGET_NAME": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null - } - }, - { - "name": "ESP32_REV3", - "inherits": [ - "user-local-tools", - "user-prefs", - "ESP32_REV3_preset" - ], - "cacheVariables": { - "TARGET_NAME": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null - } - }, - { - "name": "ESP32_PSRAM_XTAL26_REV0", - "inherits": [ - "user-local-tools", - "user-prefs", - "ESP32_PSRAM_XTAL26_REV0_preset" - ], - "cacheVariables": { - "TARGET_NAME": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null - } - }, - { - "name": "ESP32_BLE_REV0", - "inherits": [ - "user-local-tools", - "user-prefs", - "ESP32_BLE_REV0_preset" - ], - "cacheVariables": { - "TARGET_NAME": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null - } - }, - { - "name": "ESP32_BLE_REV3", - "inherits": [ - "user-local-tools", - "user-prefs", - "ESP32_BLE_REV3_preset" - ], - "cacheVariables": { - "TARGET_NAME": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null - } - }, - { - "name": "ESP32_PICO", - "inherits": [ - "user-local-tools", - "user-prefs", - "ESP32_PICO_preset" - ], - "cacheVariables": { - "TARGET_NAME": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null - } - }, - { - "name": "ESP_WROVER_KIT", - "inherits": [ - "user-local-tools", - "user-prefs", - "ESP_WROVER_KIT_preset" - ], - "cacheVariables": { - "TARGET_NAME": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null - } - }, - { - "name": "ESP32_C3_REV2", - "inherits": [ - "user-local-tools", - "user-prefs", - "ESP32_C3_preset" - ], - "cacheVariables": { - "TARGET_NAME": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null - } - }, - { - "name": "ESP32_C3_REV3", - "inherits": [ - "user-local-tools", - "user-prefs", - "ESP32_C3_preset" - ], - "cacheVariables": { - "TARGET_NAME": "${presetName}", - "SDK_CONFIG_FILE": "sdkconfig.default_rev3.esp32c3", - "NF_INTEROP_ASSEMBLIES": null - } - }, - { - "name": "M5Stack", - "inherits": [ - "user-local-tools", - "user-prefs", - "M5Stack_preset" - ], - "cacheVariables": { - "TARGET_NAME": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null - } - }, - { - "name": "M5Core", - "inherits": [ - "user-local-tools", - "user-prefs", - "M5Core_preset" - ], - "cacheVariables": { - "TARGET_NAME": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null - } - }, - { - "name": "M5Core2", - "inherits": [ - "user-local-tools", - "user-prefs", - "M5Core2_preset" - ], - "cacheVariables": { - "TARGET_NAME": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null - } - }, - { - "name": "ESP32_LILYGO", - "inherits": [ - "user-local-tools", - "user-prefs", - "ESP32_LILYGO_preset" - ], - "cacheVariables": { - "TARGET_NAME": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null - } - }, - { - "name": "ESP32_LILYGO_BLE", - "inherits": [ - "user-local-tools", - "user-prefs", - "ESP32_LILYGO_preset" - ], - "cacheVariables": { - "TARGET_NAME": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null, - "SDK_CONFIG_FILE": "sdkconfig.default_nopsram_ble.esp32", - "API_nanoFramework.Device.Bluetooth": "ON" - } - }, - { - "name": "ESP32_OLIMEX", - "inherits": [ - "user-local-tools", - "user-prefs", - "ESP32_OLIMEX_preset" - ], - "cacheVariables": { - "TARGET_NAME": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null - } - }, - { - "name": "ESP32_OLIMEX_BLE", - "inherits": [ - "user-local-tools", - "user-prefs", - "ESP32_OLIMEX_preset" - ], - "cacheVariables": { - "TARGET_NAME": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null, - "SDK_CONFIG_FILE": "sdkconfig.default_nopsram_ble.esp32", - "API_nanoFramework.Device.Bluetooth": "ON" - } - }, - { - "name": "ESP32_ETHERNET_KIT_1.2", - "inherits": [ - "user-local-tools", - "user-prefs", - "ESP32_ETHERNET_KIT_1.2_preset" - ], - "cacheVariables": { - "TARGET_NAME": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null - } - }, - { - "name": "ESP32_WT32_ETH01", - "inherits": [ - "user-local-tools", - "user-prefs", - "ESP32_WT32_ETH01_preset" - ], - "cacheVariables": { - "TARGET_NAME": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null - } - }, - { - "name": "ESP32_WT32_ETH01_BLE", - "inherits": [ - "user-local-tools", - "user-prefs", - "ESP32_WT32_ETH01_preset" - ], - "cacheVariables": { - "TARGET_NAME": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null, - "SDK_CONFIG_FILE": "sdkconfig.default_nopsram_ble.esp32", - "API_nanoFramework.Device.Bluetooth": "ON" - } - }, - { - "name": "ESP32_WESP32", - "inherits": [ - "user-local-tools", - "user-prefs", - "ESP32_WESP32_preset" - ], - "cacheVariables": { - "TARGET_NAME": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null - } - }, - { - "name": "ESP32_WESP32_BLE", - "inherits": [ - "user-local-tools", - "user-prefs", - "ESP32_WESP32_preset" - ], - "cacheVariables": { - "TARGET_NAME": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null, - "SDK_CONFIG_FILE": "sdkconfig.default_nopsram_ble.esp32", - "API_nanoFramework.Device.Bluetooth": "ON" - } - }, - { - "name": "LilygoTWatch2020", - "inherits": [ - "user-local-tools", - "user-prefs", - "LilygoTWatch2020_preset" - ], - "cacheVariables": { - "TARGET_NAME": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null - } - }, - { - "name": "LilygoTWatch2021", - "inherits": [ - "user-local-tools", - "user-prefs", - "LilygoTWatch2021_preset" - ], - "cacheVariables": { - "TARGET_NAME": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null - } - }, - { - "name": "M5StickC", - "inherits": [ - "user-local-tools", - "user-prefs", - "M5StickC_preset" - ], - "cacheVariables": { - "TARGET_NAME": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null - } - }, - { - "name": "M5StickCPlus", - "inherits": [ - "user-local-tools", - "user-prefs", - "M5StickCPlus_preset" - ], - "cacheVariables": { - "TARGET_NAME": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null - } - }, - { - "name": "FEATHER_S2", - "inherits": [ - "user-local-tools", - "user-prefs", - "FEATHER_S2_preset" - ], - "cacheVariables": { - "TARGET_NAME": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null - } - }, - { - "name": "KALUGA_1", - "inherits": [ - "user-local-tools", - "user-prefs", - "KALUGA_1_preset" - ], - "cacheVariables": { - "TARGET_NAME": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null - } - }, - { - "name": "NXP_MIMXRT1060_EVK", - "inherits": [ - "user-local-tools", - "user-prefs", - "NXP_MIMXRT1060_EVK_preset" - ], - "cacheVariables": { - "TARGET_BOARD": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null - } - }, - { - "name": "TI_CC1352R1_LAUNCHXL", - "inherits": [ - "user-local-tools", - "user-prefs", - "TI_CC1352R1_LAUNCHXL_preset" - ], - "cacheVariables": { - "TARGET_BOARD": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null, - "RADIO_FREQUENCY": "CHANGE_ME_TO_A_VALID_VALUE_868_OR_915" - } - }, - { - "name": "TI_CC3220SF_LAUNCHXL", - "inherits": [ - "user-local-tools", - "user-prefs", - "TI_CC3220SF_LAUNCHXL_preset" - ], - "cacheVariables": { - "TARGET_BOARD": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null - } - }, - { - "name": "BrainPad2", - "inherits": [ - "user-local-tools", - "user-prefs", - "BrainPad2_preset" - ], - "cacheVariables": { - "TARGET_BOARD": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null - } - }, - { - "name": "GHI_FEZ_CERB40_NF", - "inherits": [ - "user-local-tools", - "user-prefs", - "GHI_FEZ_CERB40_NF_preset" - ], - "cacheVariables": { - "TARGET_BOARD": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null - } - }, - { - "name": "I2M_ELECTRON_NF", - "inherits": [ - "user-local-tools", - "user-prefs", - "I2M_ELECTRON_NF_preset" - ], - "cacheVariables": { - "TARGET_BOARD": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null - } - }, - { - "name": "I2M_OXYGEN_NF", - "inherits": [ - "user-local-tools", - "user-prefs", - "I2M_OXYGEN_NF_preset" - ], - "cacheVariables": { - "TARGET_BOARD": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null - } - }, - { - "name": "MBN_QUAIL", - "inherits": [ - "user-local-tools", - "user-prefs", - "MBN_QUAIL_preset" - ], - "cacheVariables": { - "TARGET_BOARD": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null - } - }, - { - "name": "NETDUINO3_WIFI", - "inherits": [ - "user-local-tools", - "user-prefs", - "NETDUINO3_WIFI_preset" - ], - "cacheVariables": { - "TARGET_BOARD": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null - } - }, - { - "name": "PybStick2x", - "inherits": [ - "user-local-tools", - "user-prefs", - "PybStick2x_preset" - ], - "cacheVariables": { - "TARGET_BOARD": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null - } - }, - { - "name": "ST_NUCLEO64_F401RE_NF", - "inherits": [ - "user-local-tools", - "user-prefs", - "ST_NUCLEO64_F401RE_NF_preset" - ], - "cacheVariables": { - "TARGET_BOARD": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null - } - }, - { - "name": "ST_NUCLEO64_F411RE_NF", - "inherits": [ - "user-local-tools", - "user-prefs", - "ST_NUCLEO64_F411RE_NF_preset" - ], - "cacheVariables": { - "TARGET_BOARD": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null - } - }, - { - "name": "ST_NUCLEO144_F412ZG_NF", - "inherits": [ - "user-local-tools", - "user-prefs", - "ST_NUCLEO144_F412ZG_NF_preset" - ], - "cacheVariables": { - "TARGET_BOARD": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null - } - }, - { - "name": "ST_NUCLEO144_F439ZI", - "inherits": [ - "user-local-tools", - "user-prefs", - "ST_NUCLEO144_F439ZI_preset" - ], - "cacheVariables": { - "TARGET_BOARD": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null - } - }, - { - "name": "ST_NUCLEO144_F746ZG", - "inherits": [ - "user-local-tools", - "user-prefs", - "ST_NUCLEO144_F746ZG_preset" - ], - "cacheVariables": { - "TARGET_BOARD": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null - } - }, - { - "name": "ST_STM32F4_DISCOVERY", - "inherits": [ - "user-local-tools", - "user-prefs", - "ST_STM32F4_DISCOVERY_preset" - ], - "cacheVariables": { - "TARGET_BOARD": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null - } - }, - { - "name": "ST_STM32F411_DISCOVERY", - "inherits": [ - "user-local-tools", - "user-prefs", - "ST_STM32F411_DISCOVERY_preset" - ], - "cacheVariables": { - "TARGET_BOARD": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null - } - }, - { - "name": "WEACT_F411CE", - "inherits": [ - "user-local-tools", - "user-prefs", - "WEACT_F411CE_preset" - ], - "cacheVariables": { - "TARGET_BOARD": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null - } - }, - { - "name": "TI_CC1352P1_LAUNCHXL", - "inherits": [ - "user-local-tools", - "user-prefs", - "TI_CC1352P1_LAUNCHXL_preset" - ], - "cacheVariables": { - "TARGET_BOARD": "${presetName}", - "NF_INTEROP_ASSEMBLIES": null, - "RADIO_FREQUENCY": "CHANGE_ME_TO_A_VALID_VALUE_868_OR_915" - } - } - ], - "buildPresets": [ - { - "name": "ORGPAL_PALTHREE", - "displayName": "ORGPAL_PALTHREE", - "configurePreset": "ORGPAL_PALTHREE" - }, - { - "name": "ST_NUCLEO64_F091RC", - "displayName": "ST_NUCLEO64_F091RC", - "configurePreset": "ST_NUCLEO64_F091RC" - }, - { - "name": "ST_STM32F429I_DISCOVERY", - "displayName": "ST_STM32F429I_DISCOVERY", - "configurePreset": "ST_STM32F429I_DISCOVERY" - }, - { - "name": "ST_STM32F769I_DISCOVERY", - "displayName": "ST_STM32F769I_DISCOVERY", - "configurePreset": "ST_STM32F769I_DISCOVERY" - }, - { - "name": "ST_B_L475E_IOT01A", - "displayName": "ST_B_L475E_IOT01A", - "configurePreset": "ST_B_L475E_IOT01A" - }, - { - "name": "ESP32_PSRAM_REV0", - "displayName": "ESP32_PSRAM_REV0", - "configurePreset": "ESP32_PSRAM_REV0" - }, - { - "name": "ESP32_PSRAM_REV3", - "displayName": "ESP32_PSRAM_REV3", - "configurePreset": "ESP32_PSRAM_REV3" - }, - { - "name": "ESP32_REV0", - "displayName": "ESP32_REV0", - "configurePreset": "ESP32_REV0" - }, - { - "name": "ESP32_REV3", - "displayName": "ESP32_REV3", - "configurePreset": "ESP32_REV3" - }, - { - "name": "ESP32_PSRAM_XTAL26_REV0", - "displayName": "ESP32_PSRAM_XTAL26_REV0", - "configurePreset": "ESP32_PSRAM_XTAL26_REV0" - }, - { - "name": "ESP32_BLE_REV0", - "displayName": "ESP32_BLE_REV0", - "configurePreset": "ESP32_BLE_REV0" - }, - { - "name": "ESP32_BLE_REV3", - "displayName": "ESP32_BLE_REV3", - "configurePreset": "ESP32_BLE_REV3" - }, - { - "name": "ESP32_PICO", - "displayName": "ESP32_PICO", - "configurePreset": "ESP32_PICO" - }, - { - "name": "ESP_WROVER_KIT", - "displayName": "ESP_WROVER_KIT", - "configurePreset": "ESP_WROVER_KIT" - }, - { - "name": "ESP32_C3_REV2", - "displayName": "ESP32_C3_REV2", - "configurePreset": "ESP32_C3_REV2" - }, - { - "name": "ESP32_C3_REV3", - "displayName": "ESP32_C3_REV3", - "configurePreset": "ESP32_C3_REV3" - }, - { - "name": "M5Stack", - "displayName": "M5Stack", - "configurePreset": "M5Stack" - }, - { - "name": "M5Core", - "displayName": "M5Core", - "configurePreset": "M5Core" - }, - { - "name": "M5Core2", - "displayName": "M5Core2", - "configurePreset": "M5Core2" - }, - { - "name": "ESP32_LILYGO", - "displayName": "ESP32_LILYGO", - "configurePreset": "ESP32_LILYGO" - }, - { - "name": "ESP32_LILYGO_BLE", - "displayName": "ESP32_LILYGO_BLE", - "configurePreset": "ESP32_LILYGO_BLE" - }, - { - "name": "ESP32_OLIMEX", - "displayName": "ESP32_OLIMEX", - "configurePreset": "ESP32_OLIMEX" - }, - { - "name": "ESP32_OLIMEX_BLE", - "displayName": "ESP32_OLIMEX_BLE", - "configurePreset": "ESP32_OLIMEX_BLE" - }, - { - "name": "ESP32_ETHERNET_KIT_1.2", - "displayName": "ESP32_ETHERNET_KIT_1.2", - "configurePreset": "ESP32_ETHERNET_KIT_1.2" - }, - { - "name": "ESP32_WT32_ETH01", - "displayName": "ESP32_WT32_ETH01", - "configurePreset": "ESP32_WT32_ETH01" - }, - { - "name": "ESP32_WT32_ETH01_BLE", - "displayName": "ESP32_WT32_ETH01_BLE", - "configurePreset": "ESP32_WT32_ETH01_BLE" - }, - { - "name": "ESP32_WESP32", - "displayName": "ESP32_WESP32", - "configurePreset": "ESP32_WESP32" - }, - { - "name": "ESP32_WESP32_BLE", - "displayName": "ESP32_WESP32_BLE", - "configurePreset": "ESP32_WESP32_BLE" - }, - { - "name": "LilygoTWatch2020", - "displayName": "LilygoTWatch2020", - "configurePreset": "LilygoTWatch2020" - }, - { - "name": "LilygoTWatch2021", - "displayName": "LilygoTWatch2021", - "configurePreset": "LilygoTWatch2021" - }, - { - "name": "M5StickC", - "displayName": "M5StickC", - "configurePreset": "M5StickC" - }, - { - "name": "M5StickCPlus", - "displayName": "M5StickCPlus", - "configurePreset": "M5StickCPlus" - }, - { - "name": "FEATHER_S2", - "displayName": "FEATHER_S2", - "configurePreset": "FEATHER_S2" - }, - { - "name": "KALUGA_1", - "displayName": "KALUGA_1", - "configurePreset": "KALUGA_1" - }, - { - "name": "NXP_MIMXRT1060_EVK", - "displayName": "NXP_MIMXRT1060_EVK", - "configurePreset": "NXP_MIMXRT1060_EVK" - }, - { - "name": "TI_CC1352R1_LAUNCHXL", - "displayName": "TI_CC1352R1_LAUNCHXL", - "configurePreset": "TI_CC1352R1_LAUNCHXL" - }, - { - "name": "TI_CC3220SF_LAUNCHXL", - "displayName": "TI_CC3220SF_LAUNCHXL", - "configurePreset": "TI_CC3220SF_LAUNCHXL" - }, - { - "name": "BrainPad2", - "displayName": "BrainPad2", - "configurePreset": "BrainPad2" - }, - { - "name": "GHI_FEZ_CERB40_NF", - "displayName": "GHI_FEZ_CERB40_NF", - "configurePreset": "GHI_FEZ_CERB40_NF" - }, - { - "name": "I2M_ELECTRON_NF", - "displayName": "I2M_ELECTRON_NF", - "configurePreset": "I2M_ELECTRON_NF" - }, - { - "name": "I2M_OXYGEN_NF", - "displayName": "I2M_OXYGEN_NF", - "configurePreset": "I2M_OXYGEN_NF" - }, - { - "name": "MBN_QUAIL", - "displayName": "MBN_QUAIL", - "configurePreset": "MBN_QUAIL" - }, - { - "name": "NETDUINO3_WIFI", - "displayName": "NETDUINO3_WIFI", - "configurePreset": "NETDUINO3_WIFI" - }, - { - "name": "PybStick2x", - "displayName": "PybStick2x", - "configurePreset": "PybStick2x" - }, - { - "name": "ST_NUCLEO64_F401RE_NF", - "displayName": "ST_NUCLEO64_F401RE_NF", - "configurePreset": "ST_NUCLEO64_F401RE_NF" - }, - { - "name": "ST_NUCLEO64_F411RE_NF", - "displayName": "ST_NUCLEO64_F411RE_NF", - "configurePreset": "ST_NUCLEO64_F411RE_NF" - }, - { - "name": "ST_NUCLEO144_F412ZG_NF", - "displayName": "ST_NUCLEO144_F412ZG_NF", - "configurePreset": "ST_NUCLEO144_F412ZG_NF" - }, - { - "name": "ST_NUCLEO144_F439ZI", - "displayName": "ST_NUCLEO144_F439ZI", - "configurePreset": "ST_NUCLEO144_F439ZI" - }, - { - "name": "ST_NUCLEO144_F746ZG", - "displayName": "ST_NUCLEO144_F746ZG", - "configurePreset": "ST_NUCLEO144_F746ZG" - }, - { - "name": "ST_STM32F4_DISCOVERY", - "displayName": "ST_STM32F4_DISCOVERY", - "configurePreset": "ST_STM32F4_DISCOVERY" - }, - { - "name": "ST_STM32F411_DISCOVERY", - "displayName": "ST_STM32F411_DISCOVERY", - "configurePreset": "ST_STM32F411_DISCOVERY" - }, - { - "name": "WEACT_F411CE", - "displayName": "WEACT_F411CE", - "configurePreset": "WEACT_F411CE" - }, - { - "name": "TI_CC1352P1_LAUNCHXL", - "displayName": "TI_CC1352P1_LAUNCHXL", - "configurePreset": "TI_CC1352P1_LAUNCHXL" - } - ] -} \ No newline at end of file diff --git a/README.md b/README.md index 46dc6fc247..a6a6769b84 100644 --- a/README.md +++ b/README.md @@ -39,9 +39,14 @@ We also have a [Community Targets](https://github.com/nanoframework/nf-Community | ESP32_LILYGO | [![Latest Version @ Cloudsmith](https://api-prd.cloudsmith.io/v1/badges/version/net-nanoframework/nanoframework-images/raw/ESP32_LILYGO/latest/x/?render=true)](https://cloudsmith.io/~net-nanoframework/repos/nanoframework-images/packages/detail/raw/ESP32_LILYGO/latest/) | | FEATHER_S2 | [![Latest Version @ Cloudsmith](https://api-prd.cloudsmith.io/v1/badges/version/net-nanoframework/nanoframework-images/raw/FEATHER_S2/latest/x/?render=true)](https://cloudsmith.io/~net-nanoframework/repos/nanoframework-images/packages/detail/raw/FEATHER_S2/latest/) | | KALUGA_1 | [![Latest Version @ Cloudsmith](https://api-prd.cloudsmith.io/v1/badges/version/net-nanoframework/nanoframework-images/raw/KALUGA_1/latest/x/?render=true)](https://cloudsmith.io/~net-nanoframework/repos/nanoframework-images/packages/detail/raw/KALUGA_1/latest/) | -| ESP32_C3_REV2 | [![Latest Version @ Cloudsmith](https://api-prd.cloudsmith.io/v1/badges/version/net-nanoframework/nanoframework-images/raw/ESP32_C3_REV2/latest/x/?render=true)](https://cloudsmith.io/~net-nanoframework/repos/nanoframework-images/packages/detail/raw/ESP32_C3_REV2/latest/) | +| ESP32_C3 | [![Latest Version @ Cloudsmith](https://api-prd.cloudsmith.io/v1/badges/version/net-nanoframework/nanoframework-images/raw/ESP32_C3/latest/x/?render=true)](https://cloudsmith.io/~net-nanoframework/repos/nanoframework-images/packages/detail/raw/ESP32_C3/latest/) | | ESP32_C3_REV3 | [![Latest Version @ Cloudsmith](https://api-prd.cloudsmith.io/v1/badges/version/net-nanoframework/nanoframework-images/raw/ESP32_C3_REV3/latest/x/?render=true)](https://cloudsmith.io/~net-nanoframework/repos/nanoframework-images/packages/detail/raw/ESP32_C3_REV3/latest/) | +| XIAO_ESP32C3 | [![Latest Version @ Cloudsmith](https://api-prd.cloudsmith.io/v1/badges/version/net-nanoframework/nanoframework-images/raw/XIAO_ESP32C3/latest/x/?render=true)](https://cloudsmith.io/~net-nanoframework/repos/nanoframework-images/packages/detail/raw/XIAO_ESP32C3/latest/) | | ESP32_OLIMEX | [![Latest Version @ Cloudsmith](https://api-prd.cloudsmith.io/v1/badges/version/net-nanoframework/nanoframework-images/raw/ESP32_OLIMEX/latest/x/?render=true)](https://cloudsmith.io/~net-nanoframework/repos/nanoframework-images/packages/detail/raw/ESP32_OLIMEX/latest/) | +| ESP32_GenericDisplay_REV0 | [![Latest Version @ Cloudsmith](https://api-prd.cloudsmith.io/v1/badges/version/net-nanoframework/nanoframework-images/raw/ESP32_GenericDisplay_REV0/latest/x/?render=true)](https://cloudsmith.io/~net-nanoframework/repos/nanoframework-images/packages/detail/raw/ESP32_GenericDisplay_REV0/latest/) | +| ESP32_PSRAM_BLE_GenericGraphic_REV3 | [![Latest Version @ Cloudsmith](https://api-prd.cloudsmith.io/v1/badges/version/net-nanoframework/nanoframework-images/raw/ESP32_PSRAM_BLE_GenericGraphic_REV3/latest/x/?render=true)](https://cloudsmith.io/~net-nanoframework/repos/nanoframework-images/packages/detail/raw/ESP32_PSRAM_BLE_GenericGraphic_REV3/latest/) | +| ESP32_S3 | [![Latest Version @ Cloudsmith](https://api-prd.cloudsmith.io/v1/badges/version/net-nanoframework/nanoframework-images/raw/ESP32_S3/latest/x/?render=true)](https://cloudsmith.io/~net-nanoframework/repos/nanoframework-images/packages/detail/raw/ESP32_S3/latest/) | +| ESP32_S3_BLE | [![Latest Version @ Cloudsmith](https://api-prd.cloudsmith.io/v1/badges/version/net-nanoframework/nanoframework-images/raw/ESP32_S3_BLE/latest/x/?render=true)](https://cloudsmith.io/~net-nanoframework/repos/nanoframework-images/packages/detail/raw/ESP32_S3_BLE/latest/) | ### M5Stack @@ -51,6 +56,7 @@ We also have a [Community Targets](https://github.com/nanoframework/nf-Community | [M5StickC](https://docs.m5stack.com/en/core/m5stickc) | [![Latest Version @ Cloudsmith](https://api-prd.cloudsmith.io/v1/badges/version/net-nanoframework/nanoframework-images/raw/M5StickC/latest/x/?render=true)](https://cloudsmith.io/~net-nanoframework/repos/nanoframework-images/packages/detail/raw/M5StickC/latest/) | | [M5StickCPlus](https://docs.m5stack.com/en/core/m5stickc_plus) | [![Latest Version @ Cloudsmith](https://api-prd.cloudsmith.io/v1/badges/version/net-nanoframework/nanoframework-images/raw/M5StickCPlus/latest/x/?render=true)](https://cloudsmith.io/~net-nanoframework/repos/nanoframework-images/packages/detail/raw/M5StickCPlus/latest/) | | [M5Core2](https://docs.m5stack.com/en/core/core2) | [![Latest Version @ Cloudsmith](https://api-prd.cloudsmith.io/v1/badges/version/net-nanoframework/nanoframework-images/raw/M5Core2/latest/x/?render=true)](https://cloudsmith.io/~net-nanoframework/repos/nanoframework-images/packages/detail/raw/M5Core2/latest/) | +| [AtomS3](https://docs.m5stack.com/en/core/AtomS3) | [![Latest Version @ Cloudsmith](https://api-prd.cloudsmith.io/v1/badges/version/net-nanoframework/nanoframework-images/raw/AtomS3/latest/x/?render=true)](https://cloudsmith.io/~net-nanoframework/repos/nanoframework-images/packages/detail/raw/AtomS3/latest/) | ### STM32 boards and chip based @@ -61,6 +67,13 @@ We also have a [Community Targets](https://github.com/nanoframework/nf-Community | ST_STM32F769I_DISCOVERY | [![Latest Version @ Cloudsmith](https://api-prd.cloudsmith.io/v1/badges/version/net-nanoframework/nanoframework-images/raw/ST_STM32F769I_DISCOVERY/latest/x/?render=true)](https://cloudsmith.io/~net-nanoframework/repos/nanoframework-images/packages/detail/raw/ST_STM32F769I_DISCOVERY/latest/) | | ORGPAL_PALTHREE | [![Latest Version @ Cloudsmith](https://api-prd.cloudsmith.io/v1/badges/version/net-nanoframework/nanoframework-images/raw/ORGPAL_PALTHREE/latest/x/?render=true)](https://cloudsmith.io/~net-nanoframework/repos/nanoframework-images/packages/detail/raw/ORGPAL_PALTHREE/latest/) | +### Silicon Labs Giant Gecko boards + +| Target | Version | +|:-|---| +| SL_STK3701A | [![Latest Version @ Cloudsmith](https://api-prd.cloudsmith.io/v1/badges/version/net-nanoframework/nanoframework-images/raw/SL_STK3701A/latest/x/?render=true)](https://cloudsmith.io/~net-nanoframework/repos/nanoframework-images/packages/detail/raw/SL_STK3701A/latest/) | +| SL_STK3701A_REVB | [![Latest Version @ Cloudsmith](https://api-prd.cloudsmith.io/v1/badges/version/net-nanoframework/nanoframework-images/raw/SL_STK3701A_REVB/latest/x/?render=true)](https://cloudsmith.io/~net-nanoframework/repos/nanoframework-images/packages/detail/raw/SL_STK3701A_REVB/latest/) | + ### NXP boards | Target | Version | @@ -95,15 +108,20 @@ The above .NET nanoFramework interpreter builds include support for the class li | FEATHER_S2 | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | :heavy_check_mark: | | | | | KALUGA_1 | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | :heavy_check_mark: | | | :heavy_check_mark: | | ESP32_C3 | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | :heavy_check_mark: | | | | + | XIAO_ESP32C3 | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | :heavy_check_mark: | | | | | ESP32_OLIMEX | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | :heavy_check_mark: | :heavy_check_mark: Wi-Fi + Ethernet | | :heavy_check_mark: | | | M5Core | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | :heavy_check_mark: | :heavy_check_mark: Wi-Fi | | :heavy_check_mark: | | | M5StickC | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | :heavy_check_mark: | :heavy_check_mark: Wi-Fi | | :heavy_check_mark: | | | M5StickCPlus | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | :heavy_check_mark: | :heavy_check_mark: Wi-Fi | | :heavy_check_mark: | | | M5Core2 | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | :heavy_check_mark: | :heavy_check_mark: Wi-Fi | | :heavy_check_mark: | | + | ESP32_GenericDisplay_REV0 | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | :heavy_check_mark: | :heavy_check_mark: Wi-Fi | | :heavy_check_mark: | | + | ESP32_PSRAM_BLE_GenericGraphic_REV3 | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | :heavy_check_mark: | :heavy_check_mark: Wi-Fi | | :heavy_check_mark: | | | ST_STM32F429I_DISCOVERY | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | | :heavy_check_mark: | | | ST_NUCLEO64_F091RC | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | | | | | ST_STM32F769I_DISCOVERY | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | :heavy_check_mark: | :heavy_check_mark: | | ORGPAL_PALTHREE | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | :heavy_check_mark: | | + | SL_STK3701A_REVB | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | :heavy_check_mark: | | :heavy_check_mark: | :heavy_check_mark: | | | | | + | SL_STK3701A | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | :heavy_check_mark: | | :heavy_check_mark: | :heavy_check_mark: | | | | | | TI_CC1352R1_LAUNCHXL | :heavy_check_mark: | | | | | | | | | | | | | | | TI_CC3220SF_LAUNCHXL | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | | | :heavy_check_mark: | | :heavy_check_mark: | | | | | NXP_MIMXRT1060_EVK | :heavy_check_mark: | | | | | | :heavy_check_mark: | | :heavy_check_mark: | | :heavy_check_mark: | | :heavy_check_mark: | | @@ -132,6 +150,8 @@ The above .NET nanoFramework interpreter builds include support for the class li * Target reference for FreeRTOS * [ESP32_REV0](targets/ESP32/ESP32_REV0) * [NXP_MIMXRT1060_EVK](targets/FreeRTOS/NXP/NXP_MIMXRT1060_EVK) + * Target references for Azure RTOS + * [Silabs Giant Gecko EVB](targets/AzureRTOS/Silabs/SL_STK3701A) * Target references for TI SimpleLink * [TI CC1352R1_LAUNCHXL](targets/TI_SimpleLink/TI_CC1352R1_LAUNCHXL) * [TI CC3220SF_LAUNCHXL](targets/TI_SimpleLink/TI_CC3220SF_LAUNCHXL) diff --git a/README.zh-cn.md b/README.zh-cn.md index 13f4c4cf15..550daa52f0 100644 --- a/README.zh-cn.md +++ b/README.zh-cn.md @@ -38,9 +38,14 @@ | ESP32_LILYGO | [![Latest Version @ Cloudsmith](https://api-prd.cloudsmith.io/v1/badges/version/net-nanoframework/nanoframework-images/raw/ESP32_LILYGO/latest/x/?render=true)](https://cloudsmith.io/~net-nanoframework/repos/nanoframework-images/packages/detail/raw/ESP32_LILYGO/latest/) | | FEATHER_S2 | [![Latest Version @ Cloudsmith](https://api-prd.cloudsmith.io/v1/badges/version/net-nanoframework/nanoframework-images/raw/FEATHER_S2/latest/x/?render=true)](https://cloudsmith.io/~net-nanoframework/repos/nanoframework-images/packages/detail/raw/FEATHER_S2/latest/) | | KALUGA_1 | [![Latest Version @ Cloudsmith](https://api-prd.cloudsmith.io/v1/badges/version/net-nanoframework/nanoframework-images/raw/KALUGA_1/latest/x/?render=true)](https://cloudsmith.io/~net-nanoframework/repos/nanoframework-images/packages/detail/raw/KALUGA_1/latest/) | -| ESP32_C3_REV2 | [![Latest Version @ Cloudsmith](https://api-prd.cloudsmith.io/v1/badges/version/net-nanoframework/nanoframework-images/raw/ESP32_C3_REV2/latest/x/?render=true)](https://cloudsmith.io/~net-nanoframework/repos/nanoframework-images/packages/detail/raw/ESP32_C3_REV2/latest/) | +| ESP32_C3 | [![Latest Version @ Cloudsmith](https://api-prd.cloudsmith.io/v1/badges/version/net-nanoframework/nanoframework-images/raw/ESP32_C3/latest/x/?render=true)](https://cloudsmith.io/~net-nanoframework/repos/nanoframework-images/packages/detail/raw/ESP32_C3/latest/) | | ESP32_C3_REV3 | [![Latest Version @ Cloudsmith](https://api-prd.cloudsmith.io/v1/badges/version/net-nanoframework/nanoframework-images/raw/ESP32_C3_REV3/latest/x/?render=true)](https://cloudsmith.io/~net-nanoframework/repos/nanoframework-images/packages/detail/raw/ESP32_C3_REV3/latest/) | +| XIAO_ESP32C3 | [![Latest Version @ Cloudsmith](https://api-prd.cloudsmith.io/v1/badges/version/net-nanoframework/nanoframework-images/raw/XIAO_ESP32C3/latest/x/?render=true)](https://cloudsmith.io/~net-nanoframework/repos/nanoframework-images/packages/detail/raw/XIAO_ESP32C3/latest/) | | ESP32_OLIMEX | [![Latest Version @ Cloudsmith](https://api-prd.cloudsmith.io/v1/badges/version/net-nanoframework/nanoframework-images/raw/ESP32_OLIMEX/latest/x/?render=true)](https://cloudsmith.io/~net-nanoframework/repos/nanoframework-images/packages/detail/raw/ESP32_OLIMEX/latest/) | +| ESP32_GenericDisplay_REV0 | [![Latest Version @ Cloudsmith](https://api-prd.cloudsmith.io/v1/badges/version/net-nanoframework/nanoframework-images/raw/ESP32_GenericDisplay_REV0/latest/x/?render=true)](https://cloudsmith.io/~net-nanoframework/repos/nanoframework-images/packages/detail/raw/ESP32_GenericDisplay_REV0/latest/) | +| ESP32_PSRAM_BLE_GenericGraphic_REV3 | [![Latest Version @ Cloudsmith](https://api-prd.cloudsmith.io/v1/badges/version/net-nanoframework/nanoframework-images/raw/ESP32_PSRAM_BLE_GenericGraphic_REV3/latest/x/?render=true)](https://cloudsmith.io/~net-nanoframework/repos/nanoframework-images/packages/detail/raw/ESP32_PSRAM_BLE_GenericGraphic_REV3/latest/) | +| ESP32_S3 | [![Latest Version @ Cloudsmith](https://api-prd.cloudsmith.io/v1/badges/version/net-nanoframework/nanoframework-images/raw/ESP32_S3/latest/x/?render=true)](https://cloudsmith.io/~net-nanoframework/repos/nanoframework-images/packages/detail/raw/ESP32_S3/latest/) | +| ESP32_S3_BLE | [![Latest Version @ Cloudsmith](https://api-prd.cloudsmith.io/v1/badges/version/net-nanoframework/nanoframework-images/raw/ESP32_S3_BLE/latest/x/?render=true)](https://cloudsmith.io/~net-nanoframework/repos/nanoframework-images/packages/detail/raw/ESP32_S3_BLE/latest/) | ### M5Stack @@ -50,6 +55,7 @@ | [M5StickC](https://docs.m5stack.com/en/core/m5stickc) | [![Latest Version @ Cloudsmith](https://api-prd.cloudsmith.io/v1/badges/version/net-nanoframework/nanoframework-images/raw/M5StickC/latest/x/?render=true)](https://cloudsmith.io/~net-nanoframework/repos/nanoframework-images/packages/detail/raw/M5StickC/latest/) | | [M5StickCPlus](https://docs.m5stack.com/en/core/m5stickc_plus) | [![Latest Version @ Cloudsmith](https://api-prd.cloudsmith.io/v1/badges/version/net-nanoframework/nanoframework-images/raw/M5StickCPlus/latest/x/?render=true)](https://cloudsmith.io/~net-nanoframework/repos/nanoframework-images/packages/detail/raw/M5StickCPlus/latest/) | | [M5Core2](https://docs.m5stack.com/en/core/core2) | [![Latest Version @ Cloudsmith](https://api-prd.cloudsmith.io/v1/badges/version/net-nanoframework/nanoframework-images/raw/M5Core2/latest/x/?render=true)](https://cloudsmith.io/~net-nanoframework/repos/nanoframework-images/packages/detail/raw/M5Core2/latest/) | +| [AtomS3](https://docs.m5stack.com/en/core/AtomS3) | [![Latest Version @ Cloudsmith](https://api-prd.cloudsmith.io/v1/badges/version/net-nanoframework/nanoframework-images/raw/AtomS3/latest/x/?render=true)](https://cloudsmith.io/~net-nanoframework/repos/nanoframework-images/packages/detail/raw/AtomS3/latest/) | ### STM32 boards and chip based @@ -60,6 +66,13 @@ | ST_STM32F769I_DISCOVERY | [![Latest Version @ Cloudsmith](https://api-prd.cloudsmith.io/v1/badges/version/net-nanoframework/nanoframework-images/raw/ST_STM32F769I_DISCOVERY/latest/x/?render=true)](https://cloudsmith.io/~net-nanoframework/repos/nanoframework-images/packages/detail/raw/ST_STM32F769I_DISCOVERY/latest/) | | ORGPAL_PALTHREE | [![Latest Version @ Cloudsmith](https://api-prd.cloudsmith.io/v1/badges/version/net-nanoframework/nanoframework-images/raw/ORGPAL_PALTHREE/latest/x/?render=true)](https://cloudsmith.io/~net-nanoframework/repos/nanoframework-images/packages/detail/raw/ORGPAL_PALTHREE/latest/) | +### Silicon Labs Giant Gecko boards + +| 目标 | 版本 | +|:-|---| +| SL_STK3701A | [![Latest Version @ Cloudsmith](https://api-prd.cloudsmith.io/v1/badges/version/net-nanoframework/nanoframework-images/raw/SL_STK3701A/latest/x/?render=true)](https://cloudsmith.io/~net-nanoframework/repos/nanoframework-images/packages/detail/raw/SL_STK3701A/latest/) | +| SL_STK3701A_REVB | [![Latest Version @ Cloudsmith](https://api-prd.cloudsmith.io/v1/badges/version/net-nanoframework/nanoframework-images/raw/SL_STK3701A_REVB/latest/x/?render=true)](https://cloudsmith.io/~net-nanoframework/repos/nanoframework-images/packages/detail/raw/SL_STK3701A_REVB/latest/) | + ### NXP boards | 目标 | 版本 | @@ -94,15 +107,20 @@ | FEATHER_S2 | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | :heavy_check_mark: | | | | | KALUGA_1 | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | :heavy_check_mark: | | | :heavy_check_mark: | | ESP32_C3 | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | :heavy_check_mark: | | | | + | XIAO_ESP32C3 | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | :heavy_check_mark: | | | | | ESP32_OLIMEX | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | :heavy_check_mark: | :heavy_check_mark: Wi-Fi + Ethernet | | :heavy_check_mark: | | | M5Core | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | :heavy_check_mark: | :heavy_check_mark: Wi-Fi | | :heavy_check_mark: | | | M5StickC | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | :heavy_check_mark: | :heavy_check_mark: Wi-Fi | | :heavy_check_mark: | | | M5StickCPlus | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | :heavy_check_mark: | :heavy_check_mark: Wi-Fi | | :heavy_check_mark: | | | M5Core2 | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | :heavy_check_mark: | :heavy_check_mark: Wi-Fi | | :heavy_check_mark: | | + | ESP32_GenericDisplay_REV0 | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | :heavy_check_mark: | :heavy_check_mark: Wi-Fi | | :heavy_check_mark: | | + | ESP32_PSRAM_BLE_GenericGraphic_REV3 | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | :heavy_check_mark: | :heavy_check_mark: Wi-Fi | | :heavy_check_mark: | | | ST_STM32F429I_DISCOVERY | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | | :heavy_check_mark: | | | ST_NUCLEO64_F091RC | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | | | | | ST_STM32F769I_DISCOVERY | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | :heavy_check_mark: | :heavy_check_mark: | | ORGPAL_PALTHREE | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | :heavy_check_mark: | | + | SL_STK3701A_REVB | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | :heavy_check_mark: | | :heavy_check_mark: | :heavy_check_mark: | | | | | + | SL_STK3701A | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | :heavy_check_mark: | | :heavy_check_mark: | :heavy_check_mark: | | | | | | TI_CC1352R1_LAUNCHXL | :heavy_check_mark: | | | | | | | | | | | | | | | TI_CC3220SF_LAUNCHXL | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | | | :heavy_check_mark: | | :heavy_check_mark: | | | | | NXP_MIMXRT1060_EVK | :heavy_check_mark: | | | | | | :heavy_check_mark: | | :heavy_check_mark: | | :heavy_check_mark: | | :heavy_check_mark: | | @@ -132,6 +150,8 @@ * FreeRTOS 移植 * [ESP32_REV0](targets/ESP32/ESP32_REV0) * [NXP_MIMXRT1060_EVK](targets/FreeRTOS/NXP/NXP_MIMXRT1060_EVK) + * Azure RTOS 移植 + * [Silabs Giant Gecko EVB](targets/AzureRTOS/Silabs/SL_STK3701A) * TI SimpleLink 移植 * [TI CC1352R1_LAUNCHXL](targets/TI_SimpleLink/TI_CC1352R1_LAUNCHXL) * [TI CC3220SF_LAUNCHXL](targets/TI_SimpleLink/TI_CC3220SF_LAUNCHXL) diff --git a/azure-pipelines-nightly.yml b/azure-pipelines-nightly.yml index e17bc0b952..6e63f0cbe2 100644 --- a/azure-pipelines-nightly.yml +++ b/azure-pipelines-nightly.yml @@ -14,7 +14,7 @@ resources: type: github name: espressif/esp-idf endpoint: nanoframework - ref: refs/tags/v4.4.3 + ref: refs/tags/v4.4.5 # scheduled build # the schedule is defined at the AZDO web interface because of inconsistencies with time zones @@ -43,17 +43,22 @@ jobs: # scheduled daily build: get commit date $commitDate = git show -s --format=%cd --date=short $commitDate = [DateTime]$commitDate + + "Last commit dated $commitDate" | Write-Host + + $yesterdayDate = [System.DateTime]::UtcNow.AddDays(-1).Date + "Comparing with $yesterdayDate" | Write-Host # shceduled build is at start of day, so check if commit date was from yesterday - if($commitDate -eq [System.DateTime]::UtcNow.AddDays(-1).Date) + if($commitDate -eq $yesterdayDate) { - # last commit is from today, build images + # last commit was yesterday, build images echo "##vso[task.setvariable variable=CHECK_CHANGES;isOutput=true]true" "**Commits from today. Go and check what changed.**" | Write-Host } else { - # last commit is older than today, skip build + # last commit is older than yesterday, skip build "***************************************************" | Write-Host "* Last commit is older than today, skipping build *" | Write-Host "***************************************************" | Write-Host @@ -83,126 +88,147 @@ jobs: git config --global user.email "nfbot" git config --global user.name "nanoframework@outlook.com" - $auth = "basic $([System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes(":$(GitHubToken)"))))" + $auth = "basic $([System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes(":$(GitHubToken)")))" $buildingPr = $env:System_PullRequest_PullRequestId -ne $null + # set default values + echo "##vso[task.setvariable variable=BUILD_CHIBIOS;isOutput=true]false" + echo "##vso[task.setvariable variable=BUILD_ESP32;isOutput=true]false" + echo "##vso[task.setvariable variable=BUILD_TI;isOutput=true]false" + echo "##vso[task.setvariable variable=BUILD_AZURERTOS;isOutput=true]false" + echo "##vso[task.setvariable variable=BUILD_ALL;isOutput=true]false" + if($env:StartReleaseCandidate -like "true") { # this is a release prep so NO build + Write-host "Start Release candidate build, don't build" } else { - if($buildingPr) + # check if this build was triggered by the pipeline itself + if($env:Build_Reason -eq "Manual") { - # get files changed in PR, if this is a PR - $commit = Invoke-RestMethod -Uri "https://api.github.com/repos/nanoframework/nf-interpreter/pulls/$env:System_PullRequest_PullRequestNumber/files" -Header @{"Authorization"="$auth"} -ContentType "application/json" -Method GET - - # filter removed files - $files = $commit.where{$_.status -ne 'removed'} - - # get file names only - $files = $files | % {$_.filename} + # this is a manual build, no need to check anything + Write-host "Manual build" } else { - # scheduled build, grab repo history for the last day - $commitHistory = git log --name-status --since=1.day --format= - - # filter removed files - $files = $commitHistory.where{$_[0] -ne 'D'} - - # get file names only - $files = $files | % {$_.SubString(2)} - } - - Write-host "Files changed:" - $files | % { Write-host $_ } - Write-host "" - - # set default values - echo "##vso[task.setvariable variable=BUILD_CHIBIOS;isOutput=true]false" - echo "##vso[task.setvariable variable=BUILD_ESP32;isOutput=true]false" - echo "##vso[task.setvariable variable=BUILD_TI;isOutput=true]false" - echo "##vso[task.setvariable variable=BUILD_ALL;isOutput=true]false" - - if( - (($files.where{$_.Contains('/')}).Count -eq 0) -Or - (($files.where{$_.StartsWith('azure-pipelines-templates')}).Count -gt 0) -Or - (($files.where{$_.StartsWith('CMake')}).Count -gt 0) -Or - (($files.where{$_.StartsWith('src')}).Count -gt 0) - ) - { - # files at: - # - repo root - # - azure-pipelines-templates - # - CMake - # - src - - if($buildingPr) - { - # ChibiOS targets are the only ones needing to be build on a global change - echo "##vso[task.setvariable variable=BUILD_CHIBIOS;isOutput=true]true" - Write-host "Building ChibiOS targets" - } - else - { - echo "##vso[task.setvariable variable=BUILD_ALL;isOutput=true]true" - Write-host "Building ALL targets" - } - } - - if($buildingPr) - { - if( - ($files.where{$_.Contains('targets/ChibiOS/_common')}).Count -gt 0 -Or - ($files.where{$_.Contains('targets/ChibiOS/_FatFS')}).Count -gt 0 -Or - ($files.where{$_.Contains('targets/ChibiOS/_include')}).Count -gt 0 -Or - ($files.where{$_.Contains('targets/ChibiOS/_Lwip')}).Count -gt 0 -Or - ($files.where{$_.Contains('targets/ChibiOS/_nanoBooter')}).Count -gt 0 -Or - ($files.where{$_.Contains('targets/ChibiOS/_nanoCLR')}).Count -gt 0 -Or - ($files.where{$_.Contains('targets/ChibiOS/_FatFS')}).Count -gt 0 -Or - ($files.where{$_.Contains('targets/ChibiOS/_nf-overlay')}).Count -gt 0 -Or - ($files.where{$_.Contains('targets/ChibiOS/_spiffs')}).Count -gt 0 -Or - ($files.where{$_.Contains('targets/ChibiOS/ORGPAL_PALTHREE')}).Count -gt 0 -Or - ($files.where{$_.Contains('targets/ChibiOS/ST_NUCLEO64_F091RC')}).Count -gt 0 - ) - { - # files at ChibiOS global folders or targets being built with this pipeline - echo "##vso[task.setvariable variable=BUILD_CHIBIOS;isOutput=true]true" - - Write-host "Building ChibiOS targets" - } - } - else - { - if( ($files.where{$_.Contains('targets/ChibiOS')}).Count -gt 0) - { - # files at ChibiOS folder - echo "##vso[task.setvariable variable=BUILD_CHIBIOS;isOutput=true]true" - - Write-host "Building ChibiOS targets" - } - } - - if( - !$buildingPr -And - ($files.where{$_.Contains('targets/ESP32')}).Count -gt 0) - { - # files at ESP32 folder - echo "##vso[task.setvariable variable=BUILD_ESP32;isOutput=true]true" - - Write-host "Building ESP32 targets" - } - - if( - !$buildingPr -And - ($files.where{$_.Contains('targets/TI_SimpleLink')}).Count -gt 0) - { - # files at TI_SimpleLink folder - echo "##vso[task.setvariable variable=BUILD_TI;isOutput=true]true" - - Write-host "Building TI SimpleLink targets" + if($buildingPr) + { + # get files changed in PR, if this is a PR + $commit = Invoke-RestMethod -Uri "https://api.github.com/repos/nanoframework/nf-interpreter/pulls/$env:System_PullRequest_PullRequestNumber/files" -Header @{"Authorization"="$auth"} -ContentType "application/json" -Method GET + + # filter removed files + $files = $commit.where{$_.status -ne 'removed'} + + # get file names only + $files = $files | % {$_.filename} + } + else + { + # scheduled build, grab repo history for the last day + $commitHistory = git log --name-status --since=1.day --format= + + # filter removed files + $files = $commitHistory.where{$_[0] -ne 'D'} + + # get file names only + $files = $files | % {$_.SubString(2)} + } + + Write-host "Files changed:" + $files | % { Write-host $_ } + Write-host "" + + if( + (($files.where{$_.Contains('/')}).Count -eq 0) -Or + (($files.where{$_.StartsWith('azure-pipelines-templates')}).Count -gt 0) -Or + (($files.where{$_.StartsWith('CMake')}).Count -gt 0) -Or + (($files.where{$_.StartsWith('src')}).Count -gt 0) + ) + { + # files at: + # - repo root + # - azure-pipelines-templates + # - CMake + # - src + + if($buildingPr) + { + # ChibiOS targets are the only ones needing to be build on a global change + echo "##vso[task.setvariable variable=BUILD_CHIBIOS;isOutput=true]true" + Write-host "Building ChibiOS targets" + } + else + { + echo "##vso[task.setvariable variable=BUILD_ALL;isOutput=true]true" + Write-host "Building ALL targets" + } + } + + if($buildingPr) + { + if( + ($files.where{$_.Contains('targets/ChibiOS/_common')}).Count -gt 0 -Or + ($files.where{$_.Contains('targets/ChibiOS/_FatFS')}).Count -gt 0 -Or + ($files.where{$_.Contains('targets/ChibiOS/_include')}).Count -gt 0 -Or + ($files.where{$_.Contains('targets/ChibiOS/_Lwip')}).Count -gt 0 -Or + ($files.where{$_.Contains('targets/ChibiOS/_nanoBooter')}).Count -gt 0 -Or + ($files.where{$_.Contains('targets/ChibiOS/_nanoCLR')}).Count -gt 0 -Or + ($files.where{$_.Contains('targets/ChibiOS/_FatFS')}).Count -gt 0 -Or + ($files.where{$_.Contains('targets/ChibiOS/_nf-overlay')}).Count -gt 0 -Or + ($files.where{$_.Contains('targets/ChibiOS/_spiffs')}).Count -gt 0 -Or + ($files.where{$_.Contains('targets/ChibiOS/ORGPAL_PALTHREE')}).Count -gt 0 -Or + ($files.where{$_.Contains('targets/ChibiOS/ST_NUCLEO64_F091RC')}).Count -gt 0 + ) + { + # files at ChibiOS global folders or targets being built with this pipeline + echo "##vso[task.setvariable variable=BUILD_CHIBIOS;isOutput=true]true" + + Write-host "Building ChibiOS targets" + } + } + else + { + if( ($files.where{$_.Contains('targets/ChibiOS')}).Count -gt 0) + { + # files at ChibiOS folder + echo "##vso[task.setvariable variable=BUILD_CHIBIOS;isOutput=true]true" + + Write-host "Building ChibiOS targets" + } + } + + if( + !$buildingPr -And + ($files.where{$_.Contains('targets/ESP32')}).Count -gt 0) + { + # files at ESP32 folder + echo "##vso[task.setvariable variable=BUILD_ESP32;isOutput=true]true" + + Write-host "Building ESP32 targets" + } + + if( + !$buildingPr -And + ($files.where{$_.Contains('targets/TI_SimpleLink')}).Count -gt 0) + { + # files at TI_SimpleLink folder + echo "##vso[task.setvariable variable=BUILD_TI;isOutput=true]true" + + Write-host "Building TI SimpleLink targets" + } + + if( + !$buildingPr -And + ($files.where{$_.Contains('targets/AzureRTOS')}).Count -gt 0) + { + # files at AzureRTOS folder + echo "##vso[task.setvariable variable=BUILD_AZURERTOS;isOutput=true]true" + + Write-host "Building Azure RTOS targets" + } } } @@ -210,46 +236,24 @@ jobs: displayName: Get targets to build condition: eq(variables['BuildOptions.CHECK_CHANGES'], 'True') -############################## -- job: Check_Code_Style - dependsOn: - - Check_Build_Options - - condition: >- - or( - eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_ALL'], 'true'), - eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_CHIBIOS'], 'true'), - eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_ESP32'], 'true'), - eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_TI'], 'true') - ) - - pool: - vmImage: 'windows-latest' - - steps: - - checkout: self - fetchDepth: 1 - - - template: azure-pipelines-templates/download-install-llvm.yml - - template: azure-pipelines-templates/check-code-style.yml - ################ # STM32 - job: Build_STM32_targets condition: >- - and( - succeeded('Check_Code_Style'), - or( - eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_ALL'], true), - eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_CHIBIOS'], true), - contains(dependencies.Check_Build_Options.outputs['GetCommitDetails.COMMIT_MESSAGE'], '***BUILD_ALL***'), - eq(variables['BUILD_ALL'], 'true'), - eq(variables['BUILD_CHIBIOS'], 'true') + or( + eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_ALL'], true), + eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_CHIBIOS'], true), + contains(dependencies.Check_Build_Options.outputs['GetCommitDetails.COMMIT_MESSAGE'], '***BUILD_ALL***'), + and( + eq(variables['Build.Reason'], 'Manual'), + or( + eq(variables['BUILD_ALL__'], 'true'), + eq(variables['BUILD_CHIBIOS__'], 'true') + ) ) ) dependsOn: - Check_Build_Options - - Check_Code_Style pool: vmImage: 'windows-latest' @@ -262,17 +266,20 @@ jobs: BuildOptions: NeedsDFU: true NeedsSRECORD: false + CMakePreset: ORGPAL_PALTHREE + ST_NUCLEO64_F091RC: TargetBoard: ST_NUCLEO64_F091RC TargetSeries: 'stm32f0xx' BuildOptions: NeedsDFU: false NeedsSRECORD: true + CMakePreset: ST_NUCLEO64_F091RC variables: DOTNET_NOLOGO: true # creates a counter and assigns it to the revision variable - REVISION: $[counter('STM32_1_8_0_versioncounter', 0)] + REVISION: $[counter('STM32_1_8_1_versioncounter', 0)] HelperPackageVersion: $[counter('HelperPackageVersioncounter', 0)] GccArm_Version: '' TargetPlatform: 'stm32' @@ -293,20 +300,21 @@ jobs: # ESP32 targets - job: Build_ESP32_targets condition: >- - and( - succeeded('Check_Code_Style'), - or( - eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_ALL'], true), - eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_ESP32'], true), - contains(dependencies.Check_Build_Options.outputs['GetCommitDetails.COMMIT_MESSAGE'], '***BUILD_ALL***'), - eq(variables['BUILD_ALL'], 'true'), - eq(variables['BUILD_ESP32'], 'true') + or( + eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_ALL'], true), + eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_ESP32'], true), + contains(dependencies.Check_Build_Options.outputs['GetCommitDetails.COMMIT_MESSAGE'], '***BUILD_ALL***'), + and( + eq(variables['Build.Reason'], 'Manual'), + or( + eq(variables['BUILD_ALL__'], 'true'), + eq(variables['BUILD_ESP32__'], 'true') + ) ) - ) + ) dependsOn: - Check_Build_Options - - Check_Code_Style pool: vmImage: 'windows-latest' @@ -321,6 +329,7 @@ jobs: IDF_Target: esp32 TargetName: ESP32 PackageName: ESP32_REV0 + CMakePreset: ESP32_REV0 ESP32_PSRAM_REV3: TargetBoard: ESP32 @@ -329,6 +338,7 @@ jobs: IDF_Target: esp32 TargetName: ESP32 PackageName: ESP32_PSRAM_REV3 + CMakePreset: ESP32_PSRAM_REV3 ESP32_PSRAM_XTAL26_REV0: TargetBoard: ESP32 @@ -337,6 +347,7 @@ jobs: IDF_Target: esp32 TargetName: ESP32 PackageName: ESP32_PSRAM_XTAL26_REV0 + CMakePreset: ESP32_PSRAM_XTAL26_REV0 ESP32_REV3: TargetBoard: ESP32 @@ -345,6 +356,7 @@ jobs: IDF_Target: esp32 TargetName: ESP32 PackageName: ESP32_REV3 + CMakePreset: ESP32_REV3 ESP32_PICO: TargetBoard: ESP32 @@ -353,6 +365,7 @@ jobs: IDF_Target: esp32 TargetName: ESP32_PICO PackageName: ESP32_PICO + CMakePreset: ESP32_PICO KALUGA_1: TargetBoard: ESP32_S2 @@ -361,6 +374,7 @@ jobs: IDF_Target: esp32s2 TargetName: KALUGA_1 PackageName: KALUGA_1 + CMakePreset: KALUGA_1 ESP32_BLE_REV3: TargetBoard: ESP32 @@ -369,6 +383,7 @@ jobs: IDF_Target: esp32 TargetName: ESP32 PackageName: ESP32_BLE_REV3 + CMakePreset: ESP32_BLE_REV3 ESP32_OLIMEX: TargetBoard: ESP32 @@ -377,6 +392,7 @@ jobs: IDF_Target: esp32 TargetName: ESP32_OLIMEX PackageName: ESP32_OLIMEX + CMakePreset: ESP32_OLIMEX M5StickC: TargetBoard: ESP32 @@ -386,6 +402,7 @@ jobs: IDF_Target: esp32 TargetName: M5StickC PackageName: M5StickC + CMakePreset: M5StickC M5StickCPlus: TargetBoard: ESP32 @@ -395,6 +412,7 @@ jobs: IDF_Target: esp32 TargetName: M5StickCPlus PackageName: M5StickCPlus + CMakePreset: M5StickCPlus M5Core: TargetBoard: ESP32 @@ -404,6 +422,7 @@ jobs: IDF_Target: esp32 TargetName: M5Core PackageName: M5Core + CMakePreset: M5Core M5Core2: TargetBoard: ESP32 @@ -413,6 +432,17 @@ jobs: IDF_Target: esp32 TargetName: M5Core2 PackageName: M5Core2 + CMakePreset: M5Core2 + + AtomS3: + TargetBoard: ESP32_S3 + TargetPlatform: 'esp32' + TargetSeries: 'esp32s3' + BuildOptions: + IDF_Target: esp32s3 + TargetName: AtomS3 + PackageName: AtomS3 + CMakePreset: AtomS3 ESP32_C3_REV3: TargetBoard: ESP32_C3 @@ -421,11 +451,50 @@ jobs: IDF_Target: esp32c3 TargetName: ESP32_C3_REV3 PackageName: ESP32_C3_REV3 + CMakePreset: ESP32_C3_REV3 + + ESP32_GenericDisplay_REV0: + TargetBoard: ESP32 + TargetPlatform: 'esp32' + TargetSeries: 'esp32' + BuildOptions: + IDF_Target: esp32 + TargetName: ESP32_GenericDisplay_REV0 + PackageName: ESP32_GenericDisplay_REV0 + CMakePreset: ESP32_GenericDisplay_REV0 + + ESP32_PSRAM_BLE_GenericGraphic_REV3: + TargetBoard: ESP32 + TargetPlatform: 'esp32' + TargetSeries: 'esp32' + BuildOptions: + IDF_Target: esp32 + TargetName: ESP32_PSRAM_BLE_GenericGraphic_REV3 + PackageName: ESP32_PSRAM_BLE_GenericGraphic_REV3 + CMakePreset: ESP32_PSRAM_BLE_GenericGraphic_REV3 + + XIAO_ESP32C3: + TargetBoard: ESP32_C3 + TargetSeries: 'esp32c3' + BuildOptions: + IDF_Target: esp32c3 + TargetName: XIAO_ESP32C3 + PackageName: XIAO_ESP32C3 + CMakePreset: XIAO_ESP32C3 + + ESP32_S3_BLE: + TargetBoard: ESP32_S3 + TargetSeries: 'esp32s3' + BuildOptions: + IDF_Target: esp32s3 + TargetName: ESP32_S3_BLE + PackageName: ESP32_S3_BLE + CMakePreset: ESP32_S3_BLE variables: DOTNET_NOLOGO: true # creates a counter and assigns it to the revision variable - REVISION: $[counter('ESP32_1_8_0_versioncounter', 0)] + REVISION: $[counter('ESP32_1_8_1_versioncounter', 0)] IDF_PATH: 'D:/a/1/s/esp-idf' PIP_CACHE_DIR: $(Pipeline.Workspace)/.pip TargetPlatform: 'esp32' @@ -436,6 +505,8 @@ jobs: fetchDepth: 1 - template: azure-pipelines-templates/build-preparations.yml + parameters: + repoDirectory: '$(Build.SourcesDirectory)\nf-interpreter' - template: azure-pipelines-templates/nb-gitversioning.yml parameters: repoDirectory: '$(Build.SourcesDirectory)\nf-interpreter' @@ -467,20 +538,21 @@ jobs: # TI SimpleLink - job: Build_TI_SimpleLink_targets condition: >- - and( - succeeded('Check_Code_Style'), - or( - eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_ALL'], true), - eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_TI'], true), - contains(dependencies.Check_Build_Options.outputs['GetCommitDetails.COMMIT_MESSAGE'], '***BUILD_ALL***'), - eq(variables['BUILD_ALL'], 'true'), - eq(variables['BUILD_TI'], 'true') + or( + eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_ALL'], true), + eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_TI'], true), + contains(dependencies.Check_Build_Options.outputs['GetCommitDetails.COMMIT_MESSAGE'], '***BUILD_ALL***'), + and( + eq(variables['Build.Reason'], 'Manual'), + or( + eq(variables['BUILD_ALL__'], 'true'), + eq(variables['BUILD_TI__'], 'true') + ) ) - ) + ) dependsOn: - Check_Build_Options - - Check_Code_Style pool: vmImage: 'windows-latest' @@ -490,30 +562,16 @@ jobs: TI_CC1352R1_LAUNCHXL_868: TargetBoard: TI_CC1352R1_LAUNCHXL PackageName: TI_CC1352R1_LAUNCHXL_868 - TargetSeries: 'cc13xx_26xx' + TargetSeries: 'CC13X2' BuildOptions: >- - -DTARGET_SERIES=CC13X2 - -DRTOS=TI_SimpleLink -DRADIO_FREQUENCY=868 - -DSUPPORT_ANY_BASE_CONVERSION=OFF - -DNF_FEATURE_DEBUGGER=ON - -DNF_FEATURE_RTC=ON - -DNF_FEATURE_WATCHDOG=OFF - -DAPI_System.Device.Gpio=ON - -DAPI_System.Device.Spi=OFF - -DAPI_System.Device.I2c=OFF - -DAPI_System.Device.Pwm=OFF - -DAPI_System.IO.Ports=OFF - -DAPI_System.Device.Adc=ON - -DAPI_nanoFramework.TI.EasyLink=ON - -DAPI_nanoFramework.Hardware.TI=ON - -DAPI_nanoFramework.System.Text=ON GccArm_Version: + CMakePreset: TI_CC1352R1_LAUNCHXL variables: DOTNET_NOLOGO: true # creates a counter and assigns it to the revision variable - REVISION: $[counter('TI_1_8_0_versioncounter', 0)] + REVISION: $[counter('TI_1_8_1_versioncounter', 0)] HelperPackageVersion: $[counter('HelperPackageVersioncounter', 0)] TargetPlatform: 'ti_simplelink' @@ -527,6 +585,61 @@ jobs: - template: azure-pipelines-templates/publish-cloudsmith.yml - template: azure-pipelines-templates/pack-publish-ti-sl-managed-helpers.yml +################# +# Azure RTOS +- job: Build_Azure_RTOS_targets + condition: >- + or( + eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_ALL'], true), + eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_AZURERTOS'], true), + contains(dependencies.Check_Build_Options.outputs['GetCommitDetails.COMMIT_MESSAGE'], '***BUILD_ALL***'), + and( + eq(variables['Build.Reason'], 'Manual'), + or( + eq(variables['BUILD_ALL__'], 'true'), + eq(variables['BUILD_AZURERTOS__'], 'true') + ) + ) + ) + + dependsOn: + - Check_Build_Options + + pool: + vmImage: 'windows-latest' + + strategy: + matrix: + + SL_STK3701A_REVB: + TargetBoard: SL_STK3701A_REVB + TargetSeries: 'efm32gg11' + BuildOptions: + GccArm_Version: + NeedsDFU: false + NeedsSRECORD: false + TargetName: SL_STK3701A_REVB + PackageName: SL_STK3701A_REVB + CMakePreset: SL_STK3701A_REVB + + variables: + # creates a counter and assigns it to the revision variable + REVISION: $[counter('AZURERTOS_1_8_1_versioncounter', 0)] + HelperPackageVersion: $[counter('HelperPackageVersioncounter', 0)] + TargetPlatform: 'azure_rtos' + + steps: + - template: azure-pipelines-templates/build-preparations.yml + - template: azure-pipelines-templates/nb-gitversioning.yml + - template: azure-pipelines-templates/download-install-arm-gcc-toolchain.yml + - template: azure-pipelines-templates/download-install-ninja.yml + - template: azure-pipelines-templates/download-hexdfu.yml + - template: azure-pipelines-templates/download-srecord.yml + - template: azure-pipelines-templates/build-azurertos-targets.yml + - template: azure-pipelines-templates/pack-publish-artifacts.yml + - template: azure-pipelines-templates/publish-cloudsmith.yml + - template: azure-pipelines-templates/pack-publish-managed-helpers.yml + ################################# # report build failure to Discord - job: Report_Build_Failure @@ -534,11 +647,13 @@ jobs: - Build_STM32_targets - Build_ESP32_targets - Build_TI_SimpleLink_targets + - Build_Azure_RTOS_targets condition: >- or( failed('Build_STM32_targets'), failed('Build_ESP32_targets'), - failed('Build_TI_SimpleLink_targets') + failed('Build_TI_SimpleLink_targets'), + failed('Build_Azure_RTOS_targets') ) pool: diff --git a/azure-pipelines-templates/build-azurertos-targets.yml b/azure-pipelines-templates/build-azurertos-targets.yml index 752bad546c..70a3d6b78c 100644 --- a/azure-pipelines-templates/build-azurertos-targets.yml +++ b/azure-pipelines-templates/build-azurertos-targets.yml @@ -16,32 +16,32 @@ steps: displayName: Setup CMake (DFU, no SRecord) condition: and(eq(variables['NeedsDFU'], true), eq(variables['NeedsSRECORD'], 'false')) inputs: - cmakeArgs: '--preset $(TargetBoard) -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_VERSION=$(NBGV_VersionMajor).$(NBGV_VersionMinor).$(NBGV_BuildNumber).$(TARGET_BUILD_COUNTER) -DTARGET_BOARD=$(TargetBoard) -DTARGET_NAME=$(TargetPublishName) -DTOOL_HEX2DFU_PREFIX=$(HEX2DFU_PATH) $(BuildOptions) ' + cmakeArgs: '--preset $(CMakePreset) -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_VERSION=$(NBGV_VersionMajor).$(NBGV_VersionMinor).$(NBGV_BuildNumber).$(TARGET_BUILD_COUNTER) -DTARGET_NAME=$(TargetPublishName) -DTOOL_HEX2DFU_PREFIX=$(HEX2DFU_PATH) $(BuildOptions) ' workingDirectory: ${{ parameters.repoDirectory }} - task: CMake@1 displayName: Setup CMake build (SRecord, no DFU) condition: and(eq(variables['NeedsSRECORD'], true), eq(variables['NeedsDFU'], false)) inputs: - cmakeArgs: ' --preset $(TargetBoard) -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_VERSION=$(NBGV_VersionMajor).$(NBGV_VersionMinor).$(NBGV_BuildNumber).$(TARGET_BUILD_COUNTER) -DTARGET_BOARD=$(TargetBoard) -DTARGET_NAME=$(TargetPublishName) -DTOOL_SRECORD_PREFIX=$(SRECORD_PATH)/srecord/ $(BuildOptions) ' + cmakeArgs: '--preset $(CMakePreset) -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_VERSION=$(NBGV_VersionMajor).$(NBGV_VersionMinor).$(NBGV_BuildNumber).$(TARGET_BUILD_COUNTER) -DTARGET_NAME=$(TargetPublishName) -DTOOL_SRECORD_PREFIX=$(SRECORD_PATH)/srecord/ $(BuildOptions) ' workingDirectory: ${{ parameters.repoDirectory }} - task: CMake@1 displayName: Setup CMake build (DFU and SRecord) condition: and(eq(variables['NeedsDFU'], true), eq(variables['NeedsSRECORD'], true)) inputs: - cmakeArgs: ' --preset $(TargetBoard) -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_VERSION=$(NBGV_VersionMajor).$(NBGV_VersionMinor).$(NBGV_BuildNumber).$(TARGET_BUILD_COUNTER) -DTARGET_BOARD=$(TargetBoard) -DTARGET_NAME=$(TargetPublishName) -DTOOL_HEX2DFU_PREFIX=$(HEX2DFU_PATH) -DTOOL_SRECORD_PREFIX=$(SRECORD_PATH)/srecord/ $(BuildOptions) ' + cmakeArgs: '--preset $(CMakePreset) -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_VERSION=$(NBGV_VersionMajor).$(NBGV_VersionMinor).$(NBGV_BuildNumber).$(TARGET_BUILD_COUNTER) -DTARGET_NAME=$(TargetPublishName) -DTOOL_HEX2DFU_PREFIX=$(HEX2DFU_PATH) -DTOOL_SRECORD_PREFIX=$(SRECORD_PATH)/srecord/ $(BuildOptions) ' workingDirectory: ${{ parameters.repoDirectory }} - task: CMake@1 displayName: Setup CMake build (no DFU, no SRecord) condition: and(eq(variables['NeedsDFU'], false), eq(variables['NeedsSRECORD'], false)) inputs: - cmakeArgs: ' --preset $(TargetBoard) -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_VERSION=$(NBGV_VersionMajor).$(NBGV_VersionMinor).$(NBGV_BuildNumber).$(TARGET_BUILD_COUNTER) -DTARGET_BOARD=$(TargetBoard) -DTARGET_NAME=$(TargetPublishName) $(BuildOptions) ' + cmakeArgs: '--preset $(CMakePreset) -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_VERSION=$(NBGV_VersionMajor).$(NBGV_VersionMinor).$(NBGV_BuildNumber).$(TARGET_BUILD_COUNTER) -DTARGET_NAME=$(TargetPublishName) $(BuildOptions) ' workingDirectory: ${{ parameters.repoDirectory }} - task: CMake@1 displayName: Build with CMake inputs: - cmakeArgs: '--build --preset $(TargetBoard) --target all --config MinSizeRel' + cmakeArgs: '--build --preset $(CMakePreset) --target all --config MinSizeRel' workingDirectory: ${{ parameters.repoDirectory }} diff --git a/azure-pipelines-templates/build-chibios-stm32-targets.yml b/azure-pipelines-templates/build-chibios-stm32-targets.yml index 752bad546c..70a3d6b78c 100644 --- a/azure-pipelines-templates/build-chibios-stm32-targets.yml +++ b/azure-pipelines-templates/build-chibios-stm32-targets.yml @@ -16,32 +16,32 @@ steps: displayName: Setup CMake (DFU, no SRecord) condition: and(eq(variables['NeedsDFU'], true), eq(variables['NeedsSRECORD'], 'false')) inputs: - cmakeArgs: '--preset $(TargetBoard) -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_VERSION=$(NBGV_VersionMajor).$(NBGV_VersionMinor).$(NBGV_BuildNumber).$(TARGET_BUILD_COUNTER) -DTARGET_BOARD=$(TargetBoard) -DTARGET_NAME=$(TargetPublishName) -DTOOL_HEX2DFU_PREFIX=$(HEX2DFU_PATH) $(BuildOptions) ' + cmakeArgs: '--preset $(CMakePreset) -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_VERSION=$(NBGV_VersionMajor).$(NBGV_VersionMinor).$(NBGV_BuildNumber).$(TARGET_BUILD_COUNTER) -DTARGET_NAME=$(TargetPublishName) -DTOOL_HEX2DFU_PREFIX=$(HEX2DFU_PATH) $(BuildOptions) ' workingDirectory: ${{ parameters.repoDirectory }} - task: CMake@1 displayName: Setup CMake build (SRecord, no DFU) condition: and(eq(variables['NeedsSRECORD'], true), eq(variables['NeedsDFU'], false)) inputs: - cmakeArgs: ' --preset $(TargetBoard) -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_VERSION=$(NBGV_VersionMajor).$(NBGV_VersionMinor).$(NBGV_BuildNumber).$(TARGET_BUILD_COUNTER) -DTARGET_BOARD=$(TargetBoard) -DTARGET_NAME=$(TargetPublishName) -DTOOL_SRECORD_PREFIX=$(SRECORD_PATH)/srecord/ $(BuildOptions) ' + cmakeArgs: '--preset $(CMakePreset) -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_VERSION=$(NBGV_VersionMajor).$(NBGV_VersionMinor).$(NBGV_BuildNumber).$(TARGET_BUILD_COUNTER) -DTARGET_NAME=$(TargetPublishName) -DTOOL_SRECORD_PREFIX=$(SRECORD_PATH)/srecord/ $(BuildOptions) ' workingDirectory: ${{ parameters.repoDirectory }} - task: CMake@1 displayName: Setup CMake build (DFU and SRecord) condition: and(eq(variables['NeedsDFU'], true), eq(variables['NeedsSRECORD'], true)) inputs: - cmakeArgs: ' --preset $(TargetBoard) -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_VERSION=$(NBGV_VersionMajor).$(NBGV_VersionMinor).$(NBGV_BuildNumber).$(TARGET_BUILD_COUNTER) -DTARGET_BOARD=$(TargetBoard) -DTARGET_NAME=$(TargetPublishName) -DTOOL_HEX2DFU_PREFIX=$(HEX2DFU_PATH) -DTOOL_SRECORD_PREFIX=$(SRECORD_PATH)/srecord/ $(BuildOptions) ' + cmakeArgs: '--preset $(CMakePreset) -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_VERSION=$(NBGV_VersionMajor).$(NBGV_VersionMinor).$(NBGV_BuildNumber).$(TARGET_BUILD_COUNTER) -DTARGET_NAME=$(TargetPublishName) -DTOOL_HEX2DFU_PREFIX=$(HEX2DFU_PATH) -DTOOL_SRECORD_PREFIX=$(SRECORD_PATH)/srecord/ $(BuildOptions) ' workingDirectory: ${{ parameters.repoDirectory }} - task: CMake@1 displayName: Setup CMake build (no DFU, no SRecord) condition: and(eq(variables['NeedsDFU'], false), eq(variables['NeedsSRECORD'], false)) inputs: - cmakeArgs: ' --preset $(TargetBoard) -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_VERSION=$(NBGV_VersionMajor).$(NBGV_VersionMinor).$(NBGV_BuildNumber).$(TARGET_BUILD_COUNTER) -DTARGET_BOARD=$(TargetBoard) -DTARGET_NAME=$(TargetPublishName) $(BuildOptions) ' + cmakeArgs: '--preset $(CMakePreset) -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_VERSION=$(NBGV_VersionMajor).$(NBGV_VersionMinor).$(NBGV_BuildNumber).$(TARGET_BUILD_COUNTER) -DTARGET_NAME=$(TargetPublishName) $(BuildOptions) ' workingDirectory: ${{ parameters.repoDirectory }} - task: CMake@1 displayName: Build with CMake inputs: - cmakeArgs: '--build --preset $(TargetBoard) --target all --config MinSizeRel' + cmakeArgs: '--build --preset $(CMakePreset) --target all --config MinSizeRel' workingDirectory: ${{ parameters.repoDirectory }} diff --git a/azure-pipelines-templates/build-espressif-esp32-targets.yml b/azure-pipelines-templates/build-espressif-esp32-targets.yml index 063442e407..e4ab7ecb60 100644 --- a/azure-pipelines-templates/build-espressif-esp32-targets.yml +++ b/azure-pipelines-templates/build-espressif-esp32-targets.yml @@ -19,20 +19,20 @@ steps: condition: succeeded() displayName: Setup build with CMake inputs: - cmakeArgs: ' --preset $(PackageName) -DESP32_IDF_PATH=$(IDF_PATH) -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_VERSION=$(NBGV_VersionMajor).$(NBGV_VersionMinor).$(NBGV_BuildNumber).$(TARGET_BUILD_COUNTER) -DTARGET_BOARD=$(TargetBoard) -DTARGET_NAME=$(TargetName) $(BuildOptions)' + cmakeArgs: '--preset $(CMakePreset) -DESP32_IDF_PATH=$(IDF_PATH) -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_VERSION=$(NBGV_VersionMajor).$(NBGV_VersionMinor).$(NBGV_BuildNumber).$(TARGET_BUILD_COUNTER) -DTARGET_NAME=$(TargetPublishName) $(BuildOptions)' workingDirectory: ${{ parameters.repoDirectory }} - task: CMake@1 displayName: Build with CMake condition: succeeded() inputs: - cmakeArgs: '--build --preset $(PackageName) --target all --config MinSizeRel ' + cmakeArgs: '--build --preset $(CMakePreset) --target all --config MinSizeRel' workingDirectory: ${{ parameters.repoDirectory }} # because of permission issues (the python script isn't allowed to write on the output folder) # we need to perform these steps by calling directly the python scripts - # 16MB partition table it's generated for ESP32 and ESP32_S2 only + # 16MB partition table it's generated for ESP32 and ESP32_C3 only - task: PythonScript@0 condition: >- and( diff --git a/azure-pipelines-templates/build-freertos-nxp-targets.yml b/azure-pipelines-templates/build-freertos-nxp-targets.yml index 2329f9426b..d5234dc469 100644 --- a/azure-pipelines-templates/build-freertos-nxp-targets.yml +++ b/azure-pipelines-templates/build-freertos-nxp-targets.yml @@ -14,12 +14,12 @@ steps: - task: CMake@1 inputs: - cmakeArgs: '--preset $(TargetBoard) -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_VERSION=$(NBGV_VersionMajor).$(NBGV_VersionMinor).$(NBGV_BuildNumber).$(TARGET_BUILD_COUNTER) -DTARGET_BOARD=$(TargetBoard) -DTARGET_NAME=$(TargetPublishName) -DTOOL_SRECORD_PREFIX=$(SRECORD_PATH)/srecord/ $(BuildOptions)' + cmakeArgs: '--preset $(CMakePreset) -DCMAKE_BUILD_TYPE=MinSizeRel -DBUILD_VERSION=$(NBGV_VersionMajor).$(NBGV_VersionMinor).$(NBGV_BuildNumber).$(TARGET_BUILD_COUNTER) -DTARGET_NAME=$(TargetPublishName) -DTOOL_SRECORD_PREFIX=$(SRECORD_PATH)/srecord/ $(BuildOptions)' workingDirectory: ${{ parameters.repoDirectory }} displayName: Setup build with CMake - task: CMake@1 inputs: - cmakeArgs: '--build --preset $(TargetBoard) --target all --config MinSizeRel' + cmakeArgs: '--build --preset $(CMakePreset) --target all --config MinSizeRel' workingDirectory: ${{ parameters.repoDirectory }} displayName: Build with CMake diff --git a/azure-pipelines-templates/build-preparations.yml b/azure-pipelines-templates/build-preparations.yml index 464e206e7c..1c2b279571 100644 --- a/azure-pipelines-templates/build-preparations.yml +++ b/azure-pipelines-templates/build-preparations.yml @@ -1,6 +1,11 @@ # Copyright (c) .NET Foundation and Contributors # See LICENSE file in the project root for full license information. +parameters: + - name: repoDirectory + type: string + default: $(Build.SourcesDirectory) + steps: - task: PowerShell@2 @@ -24,3 +29,12 @@ steps: inputs: targetType: 'inline' script: New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" -Name "LongPathsEnabled" -Value 1 -PropertyType DWORD -Force + + - task: PowerShell@2 + displayName: Add dummy cmake presets + condition: ne(variables['Build.Repository.Name'], 'nanoframework/nf-Community-Targets') + inputs: + workingDirectory: ${{ parameters.repoDirectory }}\targets-community + targetType: 'inline' + script: | + New-Item -Path . -Name "CMakePresets.json" -ItemType "file" -Value "{`n""version"": 4,`n""include"": []`n}" diff --git a/azure-pipelines-templates/check-code-style.yml b/azure-pipelines-templates/check-code-style.yml index af5fcda0fc..2c0d5f9ba3 100644 --- a/azure-pipelines-templates/check-code-style.yml +++ b/azure-pipelines-templates/check-code-style.yml @@ -16,7 +16,7 @@ steps: # compute authorization header in format "AUTHORIZATION: basic 'encoded token'" # 'encoded token' is the Base64 of the string "nfbot:personal-token" - $auth = "basic $([System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("nfbot:$(GitHubToken)"))))" + $auth = "basic $([System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("nfbot:$(GitHubToken)")))" git config --global gc.auto 0 git config --global user.name nfbot diff --git a/azure-pipelines-templates/download-hexdfu.yml b/azure-pipelines-templates/download-hexdfu.yml index c7b566c609..4223a29c4a 100644 --- a/azure-pipelines-templates/download-hexdfu.yml +++ b/azure-pipelines-templates/download-hexdfu.yml @@ -4,7 +4,7 @@ steps: - task: Cache@2 inputs: - key: '1-0 | hex2dfuKey' + key: '3-0 | hex2dfuKey' restoreKeys: hex2dfuKey path: $(Agent.TempDirectory)/hex2dfu cacheHitVar: HEX2DFU_CACHE_RESTORED diff --git a/azure-pipelines-templates/download-install-arm-gcc-toolchain.yml b/azure-pipelines-templates/download-install-arm-gcc-toolchain.yml index f8c1cd01b1..745d01cb6e 100644 --- a/azure-pipelines-templates/download-install-arm-gcc-toolchain.yml +++ b/azure-pipelines-templates/download-install-arm-gcc-toolchain.yml @@ -6,7 +6,7 @@ steps: condition: eq(variables.GccArm_Version, '') displayName: Cache latest ARM GCC toolchain inputs: - key: 'gcc-11_3_rel1 | gccUpdateKey' + key: 'gcc-12_3_rel1 | gccUpdateKey' restoreKeys: gccUpdateKey path: $(Agent.TempDirectory)\GNU_Tools_ARM_Embedded cacheHitVar: GCC_CACHE_RESTORED diff --git a/azure-pipelines-templates/download-install-esp32-build-components.yml b/azure-pipelines-templates/download-install-esp32-build-components.yml index c8dda3824c..9ed059bffa 100644 --- a/azure-pipelines-templates/download-install-esp32-build-components.yml +++ b/azure-pipelines-templates/download-install-esp32-build-components.yml @@ -7,8 +7,8 @@ steps: - task: Cache@2 displayName: Cache ESP32 tools inputs: - key: 'esp32_tools | 4_4_2' - restoreKeys: 4_4_2 + key: 'esp32_tools | 4_4_4' + restoreKeys: 4_4_4 path: $(UserProfile)\.espressif\tools cacheHitVar: ESP32_TOOLS_CACHE_RESTORED diff --git a/azure-pipelines-templates/download-install-llvm.yml b/azure-pipelines-templates/download-install-llvm.yml index 04a543f956..a8ae374f60 100644 --- a/azure-pipelines-templates/download-install-llvm.yml +++ b/azure-pipelines-templates/download-install-llvm.yml @@ -6,28 +6,36 @@ steps: condition: ne(variables['System.PullRequest.PullRequestId'], '') displayName: Cache LLVM inputs: - key: 'llvm_13_0_0_0 | llvmUpdateKey' + key: 'llvm_15_0_6_0 | llvmUpdateKey' restoreKeys: llvmUpdateKey path: $(Agent.TempDirectory)\llvm cacheHitVar: LLVM_CACHE_RESTORED - task: PowerShell@2 displayName: Downloading LLVM - condition: and(ne(variables['System.PullRequest.PullRequestId'], ''), ne(variables.LLVM_CACHE_RESTORED, 'true')) + condition: >- + and( + ne(variables['System.PullRequest.PullRequestId'], ''), + ne(variables.LLVM_CACHE_RESTORED, 'true') + ) inputs: - targetType: 'inline' - script: | - $url = "https://github.com/llvm/llvm-project/releases/download/llvmorg-13.0.0/LLVM-13.0.0-win64.exe" - $output = "$(Agent.TempDirectory)\LLVM-13.0.0-win64.exe" - (New-Object Net.WebClient).DownloadFile($url, $output) - errorActionPreference: 'stop' - failOnStderr: 'true' + targetType: 'inline' + script: | + $url = "https://github.com/llvm/llvm-project/releases/download/llvmorg-15.0.6/LLVM-15.0.6-win64.exe" + $output = "$(Agent.TempDirectory)\LLVM-15.0.6-win64.exe" + (New-Object Net.WebClient).DownloadFile($url, $output) + errorActionPreference: 'stop' + failOnStderr: 'true' - task: ExtractFiles@1 displayName: Install LLVM - condition: and(ne(variables['System.PullRequest.PullRequestId'], ''), ne(variables.LLVM_CACHE_RESTORED, 'true')) + condition: >- + and( + ne(variables['System.PullRequest.PullRequestId'], ''), + ne(variables.LLVM_CACHE_RESTORED, 'true') + ) inputs: - archiveFilePatterns: '$(Agent.TempDirectory)\LLVM-13.0.0-win64.exe' + archiveFilePatterns: '$(Agent.TempDirectory)\LLVM-15.0.6-win64.exe' destinationFolder: '$(Agent.TempDirectory)\llvm' - script: echo "##vso[task.prependpath]$(Agent.TempDirectory)\llvm\bin" diff --git a/azure-pipelines-templates/pack-publish-artifacts.yml b/azure-pipelines-templates/pack-publish-artifacts.yml index 5a7431dbdc..e3dc7641ea 100644 --- a/azure-pipelines-templates/pack-publish-artifacts.yml +++ b/azure-pipelines-templates/pack-publish-artifacts.yml @@ -15,7 +15,6 @@ steps: Contents: | *.bin *.hex - *.s19 *.dfu TargetFolder: '$(Build.ArtifactStagingDirectory)\$(TargetPublishName)' flattenFolders: true diff --git a/azure-pipelines-templates/pack-publish-managed-helpers.yml b/azure-pipelines-templates/pack-publish-managed-helpers.yml index 2cbe1bb158..6b24b08c98 100644 --- a/azure-pipelines-templates/pack-publish-managed-helpers.yml +++ b/azure-pipelines-templates/pack-publish-managed-helpers.yml @@ -8,7 +8,7 @@ steps: # git config --global user.email "nanoframework@outlook.com" # git config --global user.name "nfbot" - # $auth = "basic $([System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes(":$(GitHubToken)"))))" + # $auth = "basic $([System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes(":$(GitHubToken)")))" # $commit = Invoke-RestMethod -Uri "https://api.github.com/repos/nanoframework/nf-interpreter/commits/$(Build.SourceVersion)" -Header @{"Authorization"="$auth"} -ContentType "application/json" -Method GET # Write-host "Files changed:" diff --git a/azure-pipelines-templates/pack-publish-ti-sl-managed-helpers.yml b/azure-pipelines-templates/pack-publish-ti-sl-managed-helpers.yml index 6152f628b7..3da24a241c 100644 --- a/azure-pipelines-templates/pack-publish-ti-sl-managed-helpers.yml +++ b/azure-pipelines-templates/pack-publish-ti-sl-managed-helpers.yml @@ -8,7 +8,7 @@ steps: git config --global user.email "nanoframework@outlook.com" git config --global user.name "nfbot" - $auth = "basic $([System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes(":$(GitHubToken)"))))" + $auth = "basic $([System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes(":$(GitHubToken)")))" $commit = Invoke-RestMethod -Uri "https://api.github.com/repos/nanoframework/nf-interpreter/commits/$(Build.SourceVersion)" -Header @{"Authorization"="$auth"} -ContentType "application/json" -Method GET Write-host "Files changed:" diff --git a/azure-pipelines-templates/publish-cloudsmith.yml b/azure-pipelines-templates/publish-cloudsmith.yml index 73ab465cd5..a173df3fd3 100644 --- a/azure-pipelines-templates/publish-cloudsmith.yml +++ b/azure-pipelines-templates/publish-cloudsmith.yml @@ -52,7 +52,7 @@ steps: eq(variables['System.PullRequest.PullRequestId'], ''), or( eq(variables['ForceUpload'], true), - startsWith(variables['Build.SourceBranchName'], 'main') + startsWith(variables['Build.SourceBranchName'], 'develop') ) ) displayName: Zip binary files (preview) @@ -82,13 +82,13 @@ steps: flattenFolders: true ignoreMakeDirErrors: true - - task: PublishBuildArtifacts@1 + - task: PublishPipelineArtifact@1 condition: succeeded() displayName: Publish deployables artifacts inputs: - PathtoPublish: '$(Build.ArtifactStagingDirectory)\$(TargetPublishName)' - ArtifactName: $(TargetPublishName) - ArtifactType: Container + targetPath: '$(Build.ArtifactStagingDirectory)\$(TargetPublishName)' + artifactName: $(TargetPublishName) + artifactType: pipeline # execute on 'ForceUpload' parameter - task: PowerShell@2 @@ -107,6 +107,7 @@ steps: $repoName = $env:Build_Repository_Name $branchName = $env:Build_SourceBranchName + $forceUpload = $env:ForceUpload Write-Host "repo name is: $repoName" Write-Host "branch name is: $branchName" @@ -114,34 +115,45 @@ steps: if( $env:Build_Repository_Name -like "*nf-Community-Targets" ) { # this is a build for a community target - Write-Host "$("##vso[task.setvariable variable=CLOUDSMITH_REPO]")nanoframework-images-community-targets" + $cloudsmithRepo = "nanoframework-images-community-targets" # set publishing package name - Write-Host "$("##vso[task.setvariable variable=PUBLISHING_PACKAGE_NAME]")$(TargetPublishName)-$(NBGV_SimpleVersion).$(TARGET_BUILD_COUNTER)" + $publishingPackageName = "$(TargetPublishName)-$(NBGV_SimpleVersion).$(TARGET_BUILD_COUNTER)" # set version - Write-Host "$("##vso[task.setvariable variable=PACKAGE_VERSION]")$(NBGV_SimpleVersion).$(TARGET_BUILD_COUNTER)" + $packageVersion = "$(NBGV_SimpleVersion).$(TARGET_BUILD_COUNTER)" } else { - if( $env:Build_SourceBranchName -match "^develop*" -or - $env:Build_SourceBranchName -match "^release*" ) + if( $env:Build_SourceBranchName -match "develop" -or + $env:Build_SourceBranchName -match "^release*" -or + $env:ForceUpload -eq "true") { - # this a dev or release branch, publish to Cloudsmith dev repo - Write-Host "$("##vso[task.setvariable variable=CLOUDSMITH_REPO]")nanoframework-images-dev" + # this a dev, release branch or force upload, publish to Cloudsmith dev repo + $cloudsmithRepo = "nanoframework-images-dev" # set publishing package name - Write-Host "$("##vso[task.setvariable variable=PUBLISHING_PACKAGE_NAME]")$(TargetPublishName)-$(NBGV_SimpleVersion)-preview.$(TARGET_BUILD_COUNTER)" + $publishingPackageName = "$(TargetPublishName)-$(NBGV_SimpleVersion)-preview.$(TARGET_BUILD_COUNTER)" # set version - Write-Host "$("##vso[task.setvariable variable=PACKAGE_VERSION]")$(NBGV_SimpleVersion)-preview.$(TARGET_BUILD_COUNTER)" + $packageVersion = "$(NBGV_SimpleVersion)-preview.$(TARGET_BUILD_COUNTER)" } else { # this main branch, publish to Cloudsmith stable repo - Write-Host "$("##vso[task.setvariable variable=CLOUDSMITH_REPO]")nanoframework-images" + $cloudsmithRepo = "nanoframework-images" # set publishing package name - Write-Host "$("##vso[task.setvariable variable=PUBLISHING_PACKAGE_NAME]")$(TargetPublishName)-$(NBGV_SimpleVersion).$(TARGET_BUILD_COUNTER)" + $publishingPackageName = "$(TargetPublishName)-$(NBGV_SimpleVersion).$(TARGET_BUILD_COUNTER)" # set version - Write-Host "$("##vso[task.setvariable variable=PACKAGE_VERSION]")$(NBGV_SimpleVersion).$(TARGET_BUILD_COUNTER)" + $packageVersion = "$(NBGV_SimpleVersion).$(TARGET_BUILD_COUNTER)" } } + + Write-Host "$("##vso[task.setvariable variable=CLOUDSMITH_REPO]")$cloudsmithRepo" + Write-Host "$("##vso[task.setvariable variable=PUBLISHING_PACKAGE_NAME]")$publishingPackageName" + Write-Host "$("##vso[task.setvariable variable=PACKAGE_VERSION]")$packageVersion" + + Write-Host "Cloudsmith repo: $cloudsmithRepo" + Write-Host "Cloudsmith package: $publishingPackageName" + Write-Host "Cloudsmith package version: $packageVersion" + + errorActionPreference: 'stop' failOnStderr: 'true' @@ -165,7 +177,7 @@ steps: # install Cloudsmith CLI python -m pip install --upgrade cloudsmith-cli --quiet - Write-Host "Uploading $(PUBLISHING_PACKAGE_NAME) to v$(PACKAGE_VERSION)" + Write-Host "Uploading $(PUBLISHING_PACKAGE_NAME) v$(PACKAGE_VERSION) to $(CLOUDSMITH_REPO)" cloudsmith push raw net-nanoframework/$(CLOUDSMITH_REPO) $(Agent.TempDirectory)\$(PUBLISHING_PACKAGE_NAME).zip --name $(TargetPublishName) --version $(PACKAGE_VERSION) --tags $(TargetPlatform),$(TargetSeries) --republish -k $(CLOUDSMITH_KEY) diff --git a/azure-pipelines-templates/publish-nanoclr.yml b/azure-pipelines-templates/publish-nanoclr.yml index 47f2cf3e4e..08a5e6e086 100644 --- a/azure-pipelines-templates/publish-nanoclr.yml +++ b/azure-pipelines-templates/publish-nanoclr.yml @@ -22,14 +22,16 @@ steps: script: | $repoName = $env:Build_Repository_Name $branchName = $env:Build_SourceBranchName + $forceUpload = $env:ForceUpload Write-Host "repo name is: $repoName" Write-Host "branch name is: $branchName" - if( $env:Build_SourceBranchName -match "^develop*" -or - $env:Build_SourceBranchName -match "^release*" ) + if( $env:Build_SourceBranchName -match "develop" -or + $env:Build_SourceBranchName -match "^release*" -or + $forceUpload -eq "true") { - # this a dev or release branch, publish to Cloudsmith dev repo + # this a dev, release branch or force upload, publish to Cloudsmith dev repo Write-Host "$("##vso[task.setvariable variable=CLOUDSMITH_REPO]")nanoframework-images-dev" # set version Write-Host "$("##vso[task.setvariable variable=PACKAGE_VERSION]")$(NBGV_NuGetPackageVersion)" diff --git a/azure-pipelines-templates/publish-sdkconfig.yml b/azure-pipelines-templates/publish-sdkconfig.yml index d723754337..fe67b48eb2 100644 --- a/azure-pipelines-templates/publish-sdkconfig.yml +++ b/azure-pipelines-templates/publish-sdkconfig.yml @@ -2,10 +2,10 @@ # See LICENSE file in the project root for full license information. steps: - - task: PublishBuildArtifacts@1 + - task: PublishPipelineArtifact@1 condition: succeeded() displayName: Publish SDKCONFIG artifact inputs: - PathtoPublish: '$(Build.ArtifactStagingDirectory)\$(TargetPublishName)_sdkconfig' - ArtifactName: $(TargetPublishName)_sdkconfig - ArtifactType: Container + targetPath: '$(Build.ArtifactStagingDirectory)\$(TargetPublishName)_sdkconfig' + artifactName: $(TargetPublishName)_sdkconfig + artifactType: pipeline diff --git a/azure-pipelines-templates/setup-cmake-user-presets.yml b/azure-pipelines-templates/setup-cmake-user-presets.yml index 95418cb305..83f6c8c458 100644 --- a/azure-pipelines-templates/setup-cmake-user-presets.yml +++ b/azure-pipelines-templates/setup-cmake-user-presets.yml @@ -11,19 +11,20 @@ steps: - task: PowerShell@2 displayName: Compose CMakeUserPresets inputs: - workingDirectory: ${{ parameters.repoDirectory }} + workingDirectory: ${{ parameters.repoDirectory }}/config targetType: 'inline' script: | - $file = "CMakeUserPresets.json" + $file = "user-tools-repos.json" - Rename-Item -Path "CMakeUserPresets.TEMPLATE.json" -NewName $file + Rename-Item -Path "user-tools-repos.TEMPLATE.json" -NewName $file + + [regex]$pattern='user-tools-repos-cloud' + $pattern.replace([IO.File]::ReadAllText($file), 'user-tools-repos', 1) | Out-File $file -Encoding UTF8 + + $file = "user-prefs.json" + + Rename-Item -Path "user-prefs.TEMPLATE.json" -NewName $file $filecontent = Get-Content($file) attrib $file -r $filecontent -replace 'Debug', 'MinSizeRel' | Out-File $file -Encoding UTF8 - - [regex]$pattern='user-local-tools' - $pattern.replace([IO.File]::ReadAllText($file), 'user-local-tools-dummy', 1) | Out-File $file -Encoding UTF8 - - $filecontent = Get-Content($file) - $filecontent -replace 'user-local-tools-cloud', 'user-local-tools' | Out-File $file -Encoding UTF8 diff --git a/azure-pipelines.yml b/azure-pipelines.yml index ef5d6e7593..d38080e352 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -45,7 +45,11 @@ resources: type: github name: espressif/esp-idf endpoint: nanoframework - ref: refs/tags/v4.4.3 + ref: refs/tags/v4.4.5 + - repository: mscorlib + type: github + name: nanoframework/CoreLibrary + endpoint: nanoframework jobs: @@ -64,6 +68,9 @@ jobs: # get commit message - powershell: | + # set default values + echo "##vso[task.setvariable variable=RUN_MSCORLIB_TESTS;isOutput=true]false" + if($env:StartReleaseCandidate -like "true") { # this is a release prep so NO build @@ -88,6 +95,13 @@ jobs: { echo "##vso[task.setvariable variable=SKIP_BUILD;isOutput=true]false" } + + # check if Unit Tests for mscorlib should be run + if($commit.commit.message -like "*[run mscorlib tests]*") + { + echo "##vso[task.setvariable variable=RUN_MSCORLIB_TESTS;isOutput=true]true" + } + } else { @@ -105,14 +119,25 @@ jobs: git config --global user.email "nfbot" git config --global user.name "nanoframework@outlook.com" - $auth = "basic $([System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes(":$(GitHubToken)"))))" + $auth = "basic $([System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes(":$(GitHubToken)")))" if($env:StartReleaseCandidate -like "true") { # this is a release prep so NO build } + elseif($env:Build_Reason -eq "Manual") + { + # this is a manual build, no need to check anything + Write-host "Manual build" + } else { + # check if this build was triggered by the pipeline itself + if($env:Build_Reason -eq "Manual") + { + # this is a manual build, no need to check anything + Write-host "Manual build" + } if($env:System_PullRequest_PullRequestId -ne $null) { # get files changed in PR, if this is a PR @@ -246,7 +271,7 @@ jobs: # compute authorization header in format "AUTHORIZATION: basic 'encoded token'" # 'encoded token' is the Base64 of the string "nfbot:personal-token" - $auth = "basic $([System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("nfbot:$(GitHubToken)"))))" + $auth = "basic $([System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("nfbot:$(GitHubToken)")))" cd "$env:Agent_TempDirectory" > $null @@ -324,6 +349,7 @@ jobs: steps: - checkout: self fetchDepth: 1 + condition: ne(variables['System.PullRequest.PullRequestId'], '') - template: azure-pipelines-templates/download-install-llvm.yml - template: azure-pipelines-templates/check-code-style.yml @@ -332,12 +358,21 @@ jobs: # STM32 - job: Build_STM32_targets condition: >- - and( - succeeded('Check_Code_Style'), - ne( dependencies.Check_Build_Options.outputs['BuildOptions.SKIP_BUILD'], true ), - or( - eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_ALL'], true), - eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_CHIBIOS'], true) + or( + and( + succeeded('Check_Code_Style'), + ne( dependencies.Check_Build_Options.outputs['BuildOptions.SKIP_BUILD'], true ), + or( + eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_ALL'], true), + eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_CHIBIOS'], true) + ) + ), + and( + eq(variables['Build.Reason'], 'Manual'), + or( + eq(variables['BUILD_ALL__'], 'true'), + eq(variables['BUILD_CHIBIOS__'], 'true') + ) ) ) @@ -356,17 +391,20 @@ jobs: BuildOptions: NeedsDFU: false NeedsSRECORD: false + CMakePreset: ST_STM32F429I_DISCOVERY + ST_STM32F769I_DISCOVERY: TargetBoard: ST_STM32F769I_DISCOVERY TargetSeries: 'stm32f7xx' BuildOptions: NeedsDFU: false NeedsSRECORD: true + CMakePreset: ST_STM32F769I_DISCOVERY variables: DOTNET_NOLOGO: true # creates a counter and assigns it to the revision variable - REVISION: $[counter('STM32_1_8_0_versioncounter', 0)] + REVISION: $[counter('STM32_1_8_1_versioncounter', 0)] HelperPackageVersion: $[counter('HelperPackageVersioncounter', 0)] GccArm_Version: '' TargetPlatform: 'stm32' @@ -387,12 +425,21 @@ jobs: # ESP32 targets - job: Build_ESP32_targets condition: >- - and( - succeeded('Check_Code_Style'), - ne( dependencies.Check_Build_Options.outputs['BuildOptions.SKIP_BUILD'], true ), - or( - eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_ALL'], true), - eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_ESP32'], true) + or( + and( + succeeded('Check_Code_Style'), + ne( dependencies.Check_Build_Options.outputs['BuildOptions.SKIP_BUILD'], true ), + or( + eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_ALL'], true), + eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_ESP32'], true) + ) + ), + and( + eq(variables['Build.Reason'], 'Manual'), + or( + eq(variables['BUILD_ALL__'], 'true'), + eq(variables['BUILD_ESP32__'], 'true') + ) ) ) @@ -413,6 +460,8 @@ jobs: IDF_Target: esp32 TargetName: ESP32 PackageName: ESP32_PSRAM_REV0 + CMakePreset: ESP32_PSRAM_REV0 + ESP32_BLE_REV0: TargetBoard: ESP32 TargetSeries: 'esp32' @@ -420,6 +469,8 @@ jobs: IDF_Target: esp32 TargetName: ESP32 PackageName: ESP32_BLE_REV0 + CMakePreset: ESP32_BLE_REV0 + ESP_WROVER_KIT: TargetBoard: ESP32 TargetSeries: 'esp32' @@ -427,6 +478,8 @@ jobs: IDF_Target: esp32 TargetName: ESP_WROVER_KIT PackageName: ESP_WROVER_KIT + CMakePreset: ESP_WROVER_KIT + ESP32_LILYGO: TargetBoard: ESP32 TargetSeries: 'esp32' @@ -434,6 +487,8 @@ jobs: IDF_Target: esp32 TargetName: ESP32_LILYGO PackageName: ESP32_LILYGO + CMakePreset: ESP32_LILYGO + FEATHER_S2: TargetBoard: ESP32_S2 TargetSeries: 'esp32_s2' @@ -441,19 +496,30 @@ jobs: IDF_Target: esp32s2 TargetName: FEATHER_S2 PackageName: FEATHER_S2 + CMakePreset: FEATHER_S2 - ESP32_C3_REV2: + ESP32_C3: TargetBoard: ESP32_C3 TargetSeries: 'esp32c3' BuildOptions: IDF_Target: esp32c3 - TargetName: ESP32_C3_REV2 - PackageName: ESP32_C3_REV2 + TargetName: ESP32_C3 + PackageName: ESP32_C3 + CMakePreset: ESP32_C3 + ESP32_S3: + TargetBoard: ESP32_S3 + TargetSeries: 'esp32s3' + BuildOptions: + IDF_Target: esp32s3 + TargetName: ESP32_S3 + PackageName: ESP32_S3 + CMakePreset: ESP32_S3 + variables: DOTNET_NOLOGO: true # creates a counter and assigns it to the revision variable - REVISION: $[counter('ESP32_1_8_0_versioncounter', 0)] + REVISION: $[counter('ESP32_1_8_1_versioncounter', 0)] IDF_PATH: 'D:/a/1/s/esp-idf' PIP_CACHE_DIR: $(Pipeline.Workspace)/.pip TargetPlatform: 'esp32' @@ -464,6 +530,8 @@ jobs: fetchDepth: 1 - template: azure-pipelines-templates/build-preparations.yml + parameters: + repoDirectory: '$(Build.SourcesDirectory)\nf-interpreter' - template: azure-pipelines-templates/nb-gitversioning.yml parameters: repoDirectory: '$(Build.SourcesDirectory)\nf-interpreter' @@ -495,12 +563,21 @@ jobs: # NXP - job: Build_NXP_targets condition: >- - and( - succeeded('Check_Code_Style'), - ne( dependencies.Check_Build_Options.outputs['BuildOptions.SKIP_BUILD'], true ), - or( - eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_ALL'], true), - eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_FREERTOS'], true) + or( + and( + succeeded('Check_Code_Style'), + ne( dependencies.Check_Build_Options.outputs['BuildOptions.SKIP_BUILD'], true ), + or( + eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_ALL'], true), + eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_FREERTOS'], true) + ) + ), + and( + eq(variables['Build.Reason'], 'Manual'), + or( + eq(variables['BUILD_ALL__'], 'true'), + eq(variables['BUILD_NXP__'], 'true') + ) ) ) @@ -519,11 +596,12 @@ jobs: BuildOptions: GccArm_Version: NeedsSRECORD: true + CMakePreset: NXP_MIMXRT1060_EVK variables: DOTNET_NOLOGO: true # creates a counter and assigns it to the revision variable - REVISION: $[counter('NXP_1_8_0_versioncounter', 0)] + REVISION: $[counter('NXP_1_8_1_versioncounter', 0)] GIT_LFS_SKIP_SMUDGE: 1 TargetPlatform: 'freertos' @@ -542,13 +620,22 @@ jobs: # TI SimpleLink - job: Build_TI_SimpleLink_targets condition: >- - and( - succeeded('Check_Code_Style'), - ne( dependencies.Check_Build_Options.outputs['BuildOptions.SKIP_BUILD'], true ), - or( - eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_ALL'], true), - eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_TI'], true) - ) + or( + and( + succeeded('Check_Code_Style'), + ne( dependencies.Check_Build_Options.outputs['BuildOptions.SKIP_BUILD'], true ), + or( + eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_ALL'], true), + eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_TI'], true) + ) + ), + and( + eq(variables['Build.Reason'], 'Manual'), + or( + eq(variables['BUILD_ALL__'], 'true'), + eq(variables['BUILD_TI__'], 'true') + ) + ) ) dependsOn: @@ -589,11 +676,12 @@ jobs: BuildOptions: >- -DRADIO_FREQUENCY=915 GccArm_Version: + CMakePreset: TI_CC1352R1_LAUNCHXL variables: DOTNET_NOLOGO: true # creates a counter and assigns it to the revision variable - REVISION: $[counter('TI_1_8_0_versioncounter', 0)] + REVISION: $[counter('TI_1_8_1_versioncounter', 0)] HelperPackageVersion: $[counter('HelperPackageVersioncounter', 0)] TargetPlatform: 'ti_simplelink' @@ -611,12 +699,21 @@ jobs: # Azure RTOS - job: Build_Azure_RTOS_targets condition: >- - and( - succeeded('Check_Code_Style'), - ne( dependencies.Check_Build_Options.outputs['BuildOptions.SKIP_BUILD'], true ), - or( - eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_ALL'], true), - eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_AZURERTOS'], true) + or( + and( + succeeded('Check_Code_Style'), + ne( dependencies.Check_Build_Options.outputs['BuildOptions.SKIP_BUILD'], true ), + or( + eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_ALL'], true), + eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_AZURERTOS'], true) + ) + ), + and( + eq(variables['Build.Reason'], 'Manual'), + or( + eq(variables['BUILD_ALL__'], 'true'), + eq(variables['BUILD_AZURERTOS__'], 'true') + ) ) ) @@ -636,6 +733,7 @@ jobs: GccArm_Version: NeedsDFU: true NeedsSRECORD: false + CMakePreset: ST_B_L475E_IOT01A # ORGPAL_PALTHREE: # TargetBoard: ORGPAL_PALTHREE @@ -644,10 +742,20 @@ jobs: # GccArm_Version: # NeedsDFU: true # NeedsSRECORD: false + # CMakePreset: ORGPAL_PALTHREE + + SL_STK3701A: + TargetBoard: SL_STK3701A + TargetSeries: 'efm32gg11' + BuildOptions: + GccArm_Version: + NeedsDFU: false + NeedsSRECORD: false + CMakePreset: SL_STK3701A variables: # creates a counter and assigns it to the revision variable - REVISION: $[counter('AZURERTOS_1_8_0_versioncounter', 0)] + REVISION: $[counter('AZURERTOS_1_8_1_versioncounter', 0)] HelperPackageVersion: $[counter('HelperPackageVersioncounter', 0)] TargetPlatform: 'azure_rtos' @@ -667,13 +775,21 @@ jobs: # WIN32 executable - job: Build_WIN32_nanoCLR condition: >- - and( - succeeded('Check_Code_Style'), - ne( dependencies.Check_Build_Options.outputs['BuildOptions.SKIP_BUILD'], true ), - or( - eq(variables['BUILD_WINDOWS_NANOCLR__'], true), - eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_ALL'], true), - eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_WIN32'], true) + or( + and( + succeeded('Check_Code_Style'), + ne( dependencies.Check_Build_Options.outputs['BuildOptions.SKIP_BUILD'], true ), + or( + eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_ALL'], true), + eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_WIN32'], true) + ) + ), + and( + eq(variables['Build.Reason'], 'Manual'), + or( + eq(variables['BUILD_ALL__'], 'true'), + eq(variables['BUILD_WINDOWS_NANOCLR__'], 'true') + ) ) ) @@ -687,7 +803,7 @@ jobs: variables: DOTNET_NOLOGO: true # creates a counter and assigns it to the revision variable - REVISION: $[counter('WIN32_1_8_0__versioncounter', 400)] + REVISION: $[counter('WIN32_1_8_1_versioncounter', 0)] steps: - template: azure-pipelines-templates/nb-gitversioning.yml @@ -777,7 +893,7 @@ jobs: displayName: Pack nanoCLR WIN32 (stable) inputs: command: 'custom' - arguments: 'pack targets\win32\nanoFramework.nanoCLR.Win32.nuspec -Version $(NBGV_SimpleVersion).$(TARGET_BUILD_COUNTER)' + arguments: 'pack targets\win32\nanoFramework.nanoCLR.Win32.nuspec -Version $(NBGV_NuGetPackageVersion).$(TARGET_BUILD_COUNTER)' - task: NuGetCommand@2 condition: >- @@ -846,21 +962,25 @@ jobs: ) # publish artifacts - - task: PublishBuildArtifacts@1 + - task: PublishPipelineArtifact@1 condition: succeeded() displayName: Publish deployables artifacts inputs: - PathtoPublish: '$(Build.ArtifactStagingDirectory)' - ArtifactName: deployables - ArtifactType: Container + targetPath: '$(Build.ArtifactStagingDirectory)' + artifactName: nanoclr_win32 + artifactType: pipeline - # push NuGet packages to Azure Artifacts feed (always happens except on PR builds) + # push NuGet packages to Azure Artifacts feed (always happens when building from main, except on PR builds) - task: NuGetCommand@2 condition: >- and( succeeded(), - eq(variables['System.PullRequest.PullRequestId'], '') - ) + eq(variables['System.PullRequest.PullRequestId'], ''), + or( + eq(variables['ForceUpload'], true), + eq(variables['Build.SourceBranchName'], 'main') + ) + ) continueOnError: true displayName: Push NuGet packages to Azure Artifacts inputs: @@ -870,13 +990,17 @@ jobs: publishFeedCredentials: 'AzureArtifacts-nf-interpreter' allowPackageConflicts: true - # push NuGet packages to NuGet (always happens except on PR builds) + # push NuGet packages to NuGet (always happens when building from main, except on PR builds) - task: NuGetCommand@2 condition: >- and( succeeded(), - eq(variables['System.PullRequest.PullRequestId'], '') - ) + eq(variables['System.PullRequest.PullRequestId'], ''), + or( + eq(variables['ForceUpload'], true), + eq(variables['Build.SourceBranchName'], 'main') + ) + ) continueOnError: true displayName: Push NuGet packages to NuGet inputs: @@ -892,13 +1016,21 @@ jobs: # nanoCLR CLI tool - job: Build_nanoCLR_CLI condition: >- - and( - succeeded('Check_Code_Style'), - ne(dependencies.Check_Build_Options.outputs['BuildOptions.SKIP_BUILD'], true), - or( - eq(variables['BUILD_NANOCLR_CLI__'], true), - eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_ALL'], true), - eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_NANOCLR_CLI'], true) + or( + and( + succeeded('Check_Code_Style'), + ne(dependencies.Check_Build_Options.outputs['BuildOptions.SKIP_BUILD'], true), + or( + eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_ALL'], true), + eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_NANOCLR_CLI'], true) + ) + ), + and( + eq(variables['Build.Reason'], 'Manual'), + or( + eq(variables['BUILD_ALL__'], 'true'), + eq(variables['BUILD_NANOCLR_CLI__'], 'true') + ) ) ) @@ -1002,23 +1134,34 @@ jobs: succeeded(), eq(variables['System.PullRequest.PullRequestId'], '') ) - - # publish artifacts - - task: PublishBuildArtifacts@1 + + - task: CopyFiles@2 condition: succeeded() - displayName: Publish deployables artifacts + displayName: Copy nanoclr inputs: - PathtoPublish: '$(Build.ArtifactStagingDirectory)' - ArtifactName: deployables - ArtifactType: Container + SourceFolder: '$(Build.Repository.LocalPath)\build\bin\Release' + Contents: 'nanoFramework.nanoCLR.dll' + TargetFolder: '$(Build.ArtifactStagingDirectory)/nanoclr' - # push NuGet packages to Azure Artifacts feed (always happens except on PR builds) + - task: PublishPipelineArtifact@1 + condition: succeeded() + displayName: Publish nanoclr + inputs: + targetPath: '$(Build.ArtifactStagingDirectory)/nanoclr' + artifactName: nanoclr_cli + artifactType: pipeline + + # push NuGet packages to Azure Artifacts feed (always happens when building from main, except on PR builds) - task: NuGetCommand@2 condition: >- and( succeeded(), - eq(variables['System.PullRequest.PullRequestId'], '') - ) + eq(variables['System.PullRequest.PullRequestId'], ''), + or( + eq(variables['ForceUpload'], true), + eq(variables['Build.SourceBranchName'], 'main') + ) + ) continueOnError: true displayName: Push NuGet packages to Azure Artifacts inputs: @@ -1028,13 +1171,17 @@ jobs: publishFeedCredentials: 'AzureArtifacts-nf-interpreter' allowPackageConflicts: true - # push NuGet packages to NuGet (always happens except on PR builds) + # push NuGet packages to NuGet (always happens when building from main, except on PR builds) - task: NuGetCommand@2 condition: >- and( succeeded(), - eq(variables['System.PullRequest.PullRequestId'], '') - ) + eq(variables['System.PullRequest.PullRequestId'], ''), + or( + eq(variables['ForceUpload'], true), + eq(variables['Build.SourceBranchName'], 'main') + ) + ) continueOnError: true displayName: Push NuGet packages to NuGet inputs: @@ -1044,6 +1191,85 @@ jobs: packagesToPush: '$(Build.ArtifactStagingDirectory)/*.nupkg' publishFeedCredentials: 'NuGet-nf-interpreter' +######################### +# Run mscorlib Unit Tests + +- job: Run_UnitTests_mscorlib + condition: >- + and( + succeeded('Check_Code_Style'), + succeeded('Build_nanoCLR_CLI'), + ne(dependencies.Check_Build_Options.outputs['BuildOptions.SKIP_BUILD'], true), + or( + eq(variables['BUILD_NANOCLR_CLI__'], true), + eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_ALL'], true), + eq(dependencies.Check_Build_Options.outputs['TargetsToBuild.BUILD_NANOCLR_CLI'], true), + eq(dependencies.Check_Build_Options.outputs['BuildOptions.RUN_MSCORLIB_TESTS'], true) + ) + ) + + dependsOn: + - Build_nanoCLR_CLI + + pool: + vmImage: 'windows-latest' + + variables: + DOTNET_NOLOGO: true + solution: 'nanoFramework.CoreLibrary.sln' + buildPlatform: 'Any CPU' + buildConfiguration: 'Release' + + steps: + + - checkout: self + fetchDepth: 1 + - checkout: mscorlib + fetchDepth: 100 + submodules: true + + # Download nanoclr from build artifacts + - task: DownloadBuildArtifacts@1 + inputs: + buildType: 'current' + artifactName: 'nanoclr_cli' + downloadPath: '$(Agent.TempDirectory)/nanoclr_cli' + + # build mscorlib + + - task: InstallNanoMSBuildComponents@1 + condition: succeeded() + displayName: Install .NET nanoFramework MSBuild components + inputs: + GitHubToken: $(GitHubToken) + + - template: azure-pipelines-templates/install-nuget.yml@templates + + - task: NuGetCommand@2 + condition: succeeded() + displayName: NuGet restore + retryCountOnTaskFailure: 5 + inputs: + restoreSolution: '**/nanoFramework.CoreLibrary.sln' + feedsToUse: select + + - task: VSBuild@1 + condition: succeeded() + inputs: + solution: '**/nanoFramework.CoreLibrary.sln' + platform: 'Any CPU' + msbuildArgs: '/p:PublicRelease=true' + configuration: 'Release' + msbuildArchitecture: 'x64' + maximumCpuCount: true + + # run tests + - template: azure-pipelines-templates/run-unit-tests.yml@templates + parameters: + runUnitTests: true + unitTestRunsettings: '$(System.DefaultWorkingDirectory)\nf-interpreter\targets\netcore\pipeline_tests.runsettings' + packagesDirectory: '$(Build.SourcesDirectory)/CoreLibrary/packages' + ###################### # generate change log - job: Generate_change_log @@ -1132,7 +1358,7 @@ jobs: # compute authorization header in format "AUTHORIZATION: basic 'encoded token'" # 'encoded token' is the Base64 of the string "nfbot:personal-token" - $auth = "basic $([System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("nfbot:$(GitHubToken)"))))" + $auth = "basic $([System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("nfbot:$(GitHubToken)")))" git -c http.extraheader="AUTHORIZATION: $auth" push origin "HEAD:$(Build.SourceBranchName)" condition: >- diff --git a/config/user-prefs.TEMPLATE.json b/config/user-prefs.TEMPLATE.json new file mode 100644 index 0000000000..cfcd990a8d --- /dev/null +++ b/config/user-prefs.TEMPLATE.json @@ -0,0 +1,35 @@ +{ + "version": 4, + "configurePresets": [ + { + "name": "user-prefs", + "description": "Cache variables with user preferences general to all builds and targets.", + "hidden": true, + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "BUILD_VERSION": "0.9.99.999", + "BUILD_VERBOSE": "OFF", + "NF_WP_TRACE_ERRORS": "OFF", + "NF_WP_TRACE_HEADERS": "OFF", + "NF_WP_TRACE_STATE": "OFF", + "NF_WP_TRACE_NODATA": "OFF", + "NF_WP_TRACE_ALL": "OFF", + "NF_WP_IMPLEMENTS_CRC32": "OFF", + "NF_PLATFORM_NO_CLR_TRACE": "OFF", + "NF_CLR_NO_IL_INLINE": "OFF", + "NF_FEATURE_WATCHDOG": "ON", + "SWO_OUTPUT": "OFF", + "RADIO_FREQUENCY": "CHANGE_ME_TO_A_VALID_VALUE_868_OR_915" + } + } + ], + "buildPresets": [ + { + "cleanFirst": false, + "configuration": "Debug", + "hidden": true, + "name": "base-user", + "verbose": false + } + ] +} diff --git a/config/user-tools-repos.TEMPLATE.json b/config/user-tools-repos.TEMPLATE.json new file mode 100644 index 0000000000..abba81a858 --- /dev/null +++ b/config/user-tools-repos.TEMPLATE.json @@ -0,0 +1,56 @@ +{ + "version": 4, + "configurePresets": [ + { + "name": "user-tools-repos-local", + "description": "Cache variables with paths to local tools. Please replace with your own paths. Set to null to use build defaults or completly remove if your not building the concerned target.", + "hidden": true, + "cacheVariables": { + "TOOL_HEX2DFU_PREFIX": "", + "TOOL_SRECORD_PREFIX": "", + "CHIBIOS_SOURCE_FOLDER": "", + "FREERTOS_SOURCE_FOLDER": "", + "CHIBIOS_CONTRIB_SOURCE": "", + "CHIBIOS_HAL_SOURCE": "", + "STM32_CUBE_PACKAGE_SOURCE": "", + "MBEDTLS_SOURCE": "", + "FATFS_SOURCE": "", + "SPIFFS_SOURCE": "", + "ESP32_IDF_PATH": "", + "TI_SL_CC32xx_SDK_SOURCE": "", + "TI_SL_CC13xx_26xx_SDK_SOURCE": "", + "TI_XDCTOOLS_SOURCE": "", + "TI_SYSCONFIG_SOURCE": "" + } + }, + { + "name": "user-tools-repos-container", + "description": "Cache variables with paths to local tools. Please replace with your own paths. Set to null to use build defaults or completly remove if your not building the concerned target.", + "hidden": true, + "cacheVariables": { + "TOOL_HEX2DFU_PREFIX": "/usr/local/bin/hex2dfu", + "TOOL_SRECORD_PREFIX": "/usr/bin", + "CHIBIOS_SOURCE_FOLDER": "/sources/ChibiOs", + "FREERTOS_SOURCE_FOLDER": "/sources/FreeRTOS", + "CHIBIOS_CONTRIB_SOURCE": "/sources/ChibiOs-Contrib", + "CHIBIOS_HAL_SOURCE": "/sources/ChibiOs", + "STM32_CUBE_PACKAGE_SOURCE": "/sources/STM32CubeL4", + "MBEDTLS_SOURCE": "/sources/mbedtls", + "FATFS_SOURCE": "/sources/fatfs", + "SPIFFS_SOURCE": "/sources/spiffs", + "ESP32_IDF_PATH": "/sources/esp-idf", + "TI_SL_CC32xx_SDK_SOURCE": "/sources/SimpleLinkCC32", + "TI_SL_CC13xx_26xx_SDK_SOURCE": "/sources/SimpleLinkCC13", + "TI_XDCTOOLS_SOURCE": "/usr/local/bin/titools", + "TI_SYSCONFIG_SOURCE": "/sources/TI_SysConfig", + "AZURERTOS_SOURCE_FOLDER": "/sources/AzureRTOS", + "NETXDUO_SOURCE_FOLDER": "/sources/NetxDuo" + } + }, + { + "name": "user-tools-repos-cloud", + "description": "Empty preset to be used in cloud builds", + "hidden": true + } + ] +} \ No newline at end of file diff --git a/install-scripts/install-arm-gcc-toolchain.ps1 b/install-scripts/install-arm-gcc-toolchain.ps1 index f17dc9bd98..76d8d360d6 100644 --- a/install-scripts/install-arm-gcc-toolchain.ps1 +++ b/install-scripts/install-arm-gcc-toolchain.ps1 @@ -12,10 +12,9 @@ param ( # set default GNU GCC version if ([string]::IsNullOrEmpty($Version)) { - $Version = "11.3-rel1" + $Version = "12.3.rel1" } - # check if running on Azure Pipelines by looking at this two environment variables $IsAzurePipelines = $env:Agent_HomeDirectory -and $env:Build_BuildNumber @@ -105,10 +104,10 @@ if ($IsAzurePipelines -eq $False) { } # SIG # Begin signature block -# MIIoIAYJKoZIhvcNAQcCoIIoETCCKA0CAQExDzANBglghkgBZQMEAgEFADB5Bgor +# MIIoGgYJKoZIhvcNAQcCoIIoCzCCKAcCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG -# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCuG6CoYwdL/k0I -# YhVbytVtC1IjQZyJSQzgGIScxiCO5aCCDg8wggPFMIICraADAgECAhACrFwmagtA +# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBolWrlG9YycZTr +# a1brLKZJjcMiVxc2Fytsegsi7pLp4KCCDg8wggPFMIICraADAgECAhACrFwmagtA # m48LefKuRiV3MA0GCSqGSIb3DQEBBQUAMGwxCzAJBgNVBAYTAlVTMRUwEwYDVQQK # EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xKzApBgNV # BAMTIkRpZ2lDZXJ0IEhpZ2ggQXNzdXJhbmNlIEVWIFJvb3QgQ0EwHhcNMDYxMTEw @@ -183,141 +182,140 @@ if ($IsAzurePipelines -eq $False) { # fbrFicrII5VQXMus77/h7JfCAxMy4IKym0IOPEA+4wo1+mGNyGzsdTd4fqLibuUB # SFhQry8tS8JFAnil8J6F9WK3GvJn6gZhbavPZr442KUsb0EomhYmni25kaotNrmQ # D7Q+k2GMyx7DtgKF86uIbyfSoMavS4Yf9N7hVXmLeTeGrC5GqqcyDfe+reWOPDU6 -# EIEZMcWHkoyvJNRFXACjvNV4MK6u282mMjGCGWcwghljAgEBMG4wWjELMAkGA1UE +# EIEZMcWHkoyvJNRFXACjvNV4MK6u282mMjGCGWEwghldAgEBMG4wWjELMAkGA1UE # BhMCVVMxGDAWBgNVBAoTDy5ORVQgRm91bmRhdGlvbjExMC8GA1UEAxMoLk5FVCBG # b3VuZGF0aW9uIFByb2plY3RzIENvZGUgU2lnbmluZyBDQQIQDP8BdPDQJNgmxzG3 # FCJmOTANBglghkgBZQMEAgEFAKCBhDAYBgorBgEEAYI3AgEMMQowCKACgAChAoAA # MBkGCSqGSIb3DQEJAzEMBgorBgEEAYI3AgEEMBwGCisGAQQBgjcCAQsxDjAMBgor -# BgEEAYI3AgEVMC8GCSqGSIb3DQEJBDEiBCD+QkZQDXobm+IUa9Hk4mLhojqYVPTN -# qH4sgBvirLYzuzANBgkqhkiG9w0BAQEFAASCAQBCJxuCa+WggWotwbhbmC3h13MS -# M0Y8GmZYmOwfGePQ5w+89m6yWi81PIR5nSxqXy6imKOThQxj8m6V+vfYjlFcEVgT -# AuSXj7Ufm2DBPKuSclMnv4UbpGlyOyvDNYbOJ3zUDbIO3jh+PrPM/cC+6+s1l5tk -# RfcmpsJh8lAQ991+BlPHRW6TRavKWbinaY1hVpXfrswgiuk+5ne3PxLPFtWsyKXO -# irTXvHRRdSe6lyFfxX9109d98ok2+FlNepLkUfRihgW69t/J4DCsG8jwrtsucZkN -# ypkJ62dR5XaC/MXdRLQeH1tuzs2jqFd+dcBYhpB/HZxSETJ3aWWon52F2gdWoYIX -# QzCCFz8GCisGAQQBgjcDAwExghcvMIIXKwYJKoZIhvcNAQcCoIIXHDCCFxgCAQMx +# BgEEAYI3AgEVMC8GCSqGSIb3DQEJBDEiBCDTWM435p2pIZki9VMK10Va1h38Lmnb +# wdQAY+Xw5lWFNzANBgkqhkiG9w0BAQEFAASCAQA79FI6T3Pz0hEHMHgGrqZa0n0f +# Q0Imp/8yFAhdvCV+vHmwuAjixMJnVBTTVjEYT/oLoD01pWE09RMLaLBBNrQXfZhz +# iXQH8iAS9QXmHxuXwkYmLQLHJqoX+LfULRjbwaE8wQsBp74xv9pPlUH7u1D+erb4 +# w5VpSEdrJFy6KNZDb2fM4w/cMn7mShBxGCPXYAZd+ljjfSu7Ln0eNCVUiFeLhyS/ +# MP9JS5MpctmopbjycfBuNNl4hPx4DrJa4sWebW12QEdvZR5ei4YKZrxqlWrpYLHO +# a+PH/jLdu9yFAkvUTue/S0jZZQbM/umWvpCdPhBynzqFuW7lgGzrLTkUpIp6oYIX +# PTCCFzkGCisGAQQBgjcDAwExghcpMIIXJQYJKoZIhvcNAQcCoIIXFjCCFxICAQMx # DzANBglghkgBZQMEAgEFADB3BgsqhkiG9w0BCRABBKBoBGYwZAIBAQYJYIZIAYb9 -# bAcBMDEwDQYJYIZIAWUDBAIBBQAEIMJBFJIGm76rpWAooR61u6ic9WnE1Oymo6+J -# FAr4zsJYAhB4S+CgKCzdkW36e/QHhL6EGA8yMDIyMDgyNDE4MjEyMVqgghMNMIIG -# xjCCBK6gAwIBAgIQCnpKiJ7JmUKQBmM4TYaXnTANBgkqhkiG9w0BAQsFADBjMQsw +# bAcBMDEwDQYJYIZIAWUDBAIBBQAEIDtdufG7WlJbMGJC9p6g3XIKC93IOZRNn9Ur +# uhb2hhOMAhADsPQeN7IePv1jaNJJrdvyGA8yMDIzMDIxNTEzMzAxMVqgghMHMIIG +# wDCCBKigAwIBAgIQDE1pckuU+jwqSj0pB4A9WjANBgkqhkiG9w0BAQsFADBjMQsw # CQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xOzA5BgNVBAMTMkRp # Z2lDZXJ0IFRydXN0ZWQgRzQgUlNBNDA5NiBTSEEyNTYgVGltZVN0YW1waW5nIENB -# MB4XDTIyMDMyOTAwMDAwMFoXDTMzMDMxNDIzNTk1OVowTDELMAkGA1UEBhMCVVMx -# FzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMSQwIgYDVQQDExtEaWdpQ2VydCBUaW1l -# c3RhbXAgMjAyMiAtIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC5 -# KpYjply8X9ZJ8BWCGPQz7sxcbOPgJS7SMeQ8QK77q8TjeF1+XDbq9SWNQ6OB6zhj -# +TyIad480jBRDTEHukZu6aNLSOiJQX8Nstb5hPGYPgu/CoQScWyhYiYB087DbP2s -# O37cKhypvTDGFtjavOuy8YPRn80JxblBakVCI0Fa+GDTZSw+fl69lqfw/LH09CjP -# QnkfO8eTB2ho5UQ0Ul8PUN7UWSxEdMAyRxlb4pguj9DKP//GZ888k5VOhOl2GJiZ -# ERTFKwygM9tNJIXogpThLwPuf4UCyYbh1RgUtwRF8+A4vaK9enGY7BXn/S7s0psA -# iqwdjTuAaP7QWZgmzuDtrn8oLsKe4AtLyAjRMruD+iM82f/SjLv3QyPf58NaBWJ+ -# cCzlK7I9Y+rIroEga0OJyH5fsBrdGb2fdEEKr7mOCdN0oS+wVHbBkE+U7IZh/9sR -# L5IDMM4wt4sPXUSzQx0jUM2R1y+d+/zNscGnxA7E70A+GToC1DGpaaBJ+XXhm+ho -# 5GoMj+vksSF7hmdYfn8f6CvkFLIW1oGhytowkGvub3XAsDYmsgg7/72+f2wTGN/G -# baR5Sa2Lf2GHBWj31HDjQpXonrubS7LitkE956+nGijJrWGwoEEYGU7tR5thle0+ -# C2Fa6j56mJJRzT/JROeAiylCcvd5st2E6ifu/n16awIDAQABo4IBizCCAYcwDgYD -# VR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwFgYDVR0lAQH/BAwwCgYIKwYBBQUH -# AwgwIAYDVR0gBBkwFzAIBgZngQwBBAIwCwYJYIZIAYb9bAcBMB8GA1UdIwQYMBaA -# FLoW2W1NhS9zKXaaL3WMaiCPnshvMB0GA1UdDgQWBBSNZLeJIf5WWESEYafqbxw2 -# j92vDTBaBgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsMy5kaWdpY2VydC5jb20v -# RGlnaUNlcnRUcnVzdGVkRzRSU0E0MDk2U0hBMjU2VGltZVN0YW1waW5nQ0EuY3Js -# MIGQBggrBgEFBQcBAQSBgzCBgDAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGln -# aWNlcnQuY29tMFgGCCsGAQUFBzAChkxodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5j -# b20vRGlnaUNlcnRUcnVzdGVkRzRSU0E0MDk2U0hBMjU2VGltZVN0YW1waW5nQ0Eu -# Y3J0MA0GCSqGSIb3DQEBCwUAA4ICAQANLSN0ptH1+OpLmT8B5PYM5K8WndmzjJeC -# KZxDbwEtqzi1cBG/hBmLP13lhk++kzreKjlaOU7YhFmlvBuYquhs79FIaRk4W8+J -# OR1wcNlO3yMibNXf9lnLocLqTHbKodyhK5a4m1WpGmt90fUCCU+C1qVziMSYgN/u -# SZW3s8zFp+4O4e8eOIqf7xHJMUpYtt84fMv6XPfkU79uCnx+196Y1SlliQ+inMBl -# 9AEiZcfqXnSmWzWSUHz0F6aHZE8+RokWYyBry/J70DXjSnBIqbbnHWC9BCIVJXAG -# cqlEO2lHEdPu6cegPk8QuTA25POqaQmoi35komWUEftuMvH1uzitzcCTEdUyeEpL -# NypM81zctoXAu3AwVXjWmP5UbX9xqUgaeN1Gdy4besAzivhKKIwSqHPPLfnTI/Ke -# GeANlCig69saUaCVgo4oa6TOnXbeqXOqSGpZQ65f6vgPBkKd3wZolv4qoHRbY2be -# ayy4eKpNcG3wLPEHFX41tOa1DKKZpdcVazUOhdbgLMzgDCS4fFILHpl878jIxYxY -# aa+rPeHPzH0VrhS/inHfypex2EfqHIXgRU4SHBQpWMxv03/LvsEOSm8gnK7ZczJZ -# COctkqEaEf4ymKZdK5fgi9OczG21Da5HYzhHF1tvE9pqEG4fSbdEW7QICodaWQR2 -# EaGndwITHDCCBq4wggSWoAMCAQICEAc2N7ckVHzYR6z9KGYqXlswDQYJKoZIhvcN -# AQELBQAwYjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcG -# A1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgVHJ1c3Rl -# ZCBSb290IEc0MB4XDTIyMDMyMzAwMDAwMFoXDTM3MDMyMjIzNTk1OVowYzELMAkG -# A1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMTswOQYDVQQDEzJEaWdp -# Q2VydCBUcnVzdGVkIEc0IFJTQTQwOTYgU0hBMjU2IFRpbWVTdGFtcGluZyBDQTCC -# AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMaGNQZJs8E9cklRVcclA8Ty -# kTepl1Gh1tKD0Z5Mom2gsMyD+Vr2EaFEFUJfpIjzaPp985yJC3+dH54PMx9QEwsm -# c5Zt+FeoAn39Q7SE2hHxc7Gz7iuAhIoiGN/r2j3EF3+rGSs+QtxnjupRPfDWVtTn -# KC3r07G1decfBmWNlCnT2exp39mQh0YAe9tEQYncfGpXevA3eZ9drMvohGS0UvJ2 -# R/dhgxndX7RUCyFobjchu0CsX7LeSn3O9TkSZ+8OpWNs5KbFHc02DVzV5huowWR0 -# QKfAcsW6Th+xtVhNef7Xj3OTrCw54qVI1vCwMROpVymWJy71h6aPTnYVVSZwmCZ/ -# oBpHIEPjQ2OAe3VuJyWQmDo4EbP29p7mO1vsgd4iFNmCKseSv6De4z6ic/rnH1ps -# lPJSlRErWHRAKKtzQ87fSqEcazjFKfPKqpZzQmiftkaznTqj1QPgv/CiPMpC3BhI -# fxQ0z9JMq++bPf4OuGQq+nUoJEHtQr8FnGZJUlD0UfM2SU2LINIsVzV5K6jzRWC8 -# I41Y99xh3pP+OcD5sjClTNfpmEpYPtMDiP6zj9NeS3YSUZPJjAw7W4oiqMEmCPkU -# EBIDfV8ju2TjY+Cm4T72wnSyPx4JduyrXUZ14mCjWAkBKAAOhFTuzuldyF4wEr1G -# nrXTdrnSDmuZDNIztM2xAgMBAAGjggFdMIIBWTASBgNVHRMBAf8ECDAGAQH/AgEA -# MB0GA1UdDgQWBBS6FtltTYUvcyl2mi91jGogj57IbzAfBgNVHSMEGDAWgBTs1+OC -# 0nFdZEzfLmc/57qYrhwPTzAOBgNVHQ8BAf8EBAMCAYYwEwYDVR0lBAwwCgYIKwYB -# BQUHAwgwdwYIKwYBBQUHAQEEazBpMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5k -# aWdpY2VydC5jb20wQQYIKwYBBQUHMAKGNWh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0 -# LmNvbS9EaWdpQ2VydFRydXN0ZWRSb290RzQuY3J0MEMGA1UdHwQ8MDowOKA2oDSG -# Mmh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRSb290RzQu -# Y3JsMCAGA1UdIAQZMBcwCAYGZ4EMAQQCMAsGCWCGSAGG/WwHATANBgkqhkiG9w0B -# AQsFAAOCAgEAfVmOwJO2b5ipRCIBfmbW2CFC4bAYLhBNE88wU86/GPvHUF3iSyn7 -# cIoNqilp/GnBzx0H6T5gyNgL5Vxb122H+oQgJTQxZ822EpZvxFBMYh0MCIKoFr2p -# Vs8Vc40BIiXOlWk/R3f7cnQU1/+rT4osequFzUNf7WC2qk+RZp4snuCKrOX9jLxk -# Jodskr2dfNBwCnzvqLx1T7pa96kQsl3p/yhUifDVinF2ZdrM8HKjI/rAJ4JErpkn -# G6skHibBt94q6/aesXmZgaNWhqsKRcnfxI2g55j7+6adcq/Ex8HBanHZxhOACcS2 -# n82HhyS7T6NJuXdmkfFynOlLAlKnN36TU6w7HQhJD5TNOXrd/yVjmScsPT9rp/Fm -# w0HNT7ZAmyEhQNC3EyTN3B14OuSereU0cZLXJmvkOHOrpgFPvT87eK1MrfvElXvt -# Cl8zOYdBeHo46Zzh3SP9HSjTx/no8Zhf+yvYfvJGnXUsHicsJttvFXseGYs2uJPU -# 5vIXmVnKcPA3v5gA3yAWTyf7YGcWoWa63VXAOimGsJigK+2VQbc61RWYMbRiCQ8K -# vYHZE/6/pNHzV9m8BPqC3jLfBInwAM1dwvnQI38AC+R2AibZ8GV2QqYphwlHK+Z/ -# GqSFD/yYlvZVVCsfgPrA8g4r5db7qS9EFUrnEw4d2zc4GqEr9u3WfPwwggWNMIIE -# daADAgECAhAOmxiO+dAt5+/bUOIIQBhaMA0GCSqGSIb3DQEBDAUAMGUxCzAJBgNV -# BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp -# Y2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3VyZWQgSUQgUm9vdCBDQTAe -# Fw0yMjA4MDEwMDAwMDBaFw0zMTExMDkyMzU5NTlaMGIxCzAJBgNVBAYTAlVTMRUw -# EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x -# ITAfBgNVBAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBHNDCCAiIwDQYJKoZIhvcN -# AQEBBQADggIPADCCAgoCggIBAL/mkHNo3rvkXUo8MCIwaTPswqclLskhPfKK2FnC -# 4SmnPVirdprNrnsbhA3EMB/zG6Q4FutWxpdtHauyefLKEdLkX9YFPFIPUh/GnhWl -# fr6fqVcWWVVyr2iTcMKyunWZanMylNEQRBAu34LzB4TmdDttceItDBvuINXJIB1j -# KS3O7F5OyJP4IWGbNOsFxl7sWxq868nPzaw0QF+xembud8hIqGZXV59UWI4MK7dP -# pzDZVu7Ke13jrclPXuU15zHL2pNe3I6PgNq2kZhAkHnDeMe2scS1ahg4AxCN2NQ3 -# pC4FfYj1gj4QkXCrVYJBMtfbBHMqbpEBfCFM1LyuGwN1XXhm2ToxRJozQL8I11pJ -# pMLmqaBn3aQnvKFPObURWBf3JFxGj2T3wWmIdph2PVldQnaHiZdpekjw4KISG2aa -# dMreSx7nDmOu5tTvkpI6nj3cAORFJYm2mkQZK37AlLTSYW3rM9nF30sEAMx9HJXD -# j/chsrIRt7t/8tWMcCxBYKqxYxhElRp2Yn72gLD76GSmM9GJB+G9t+ZDpBi4pncB -# 4Q+UDCEdslQpJYls5Q5SUUd0viastkF13nqsX40/ybzTQRESW+UQUOsxxcpyFiIJ -# 33xMdT9j7CFfxCBRa2+xq4aLT8LWRV+dIPyhHsXAj6KxfgommfXkaS+YHS312amy -# HeUbAgMBAAGjggE6MIIBNjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTs1+OC -# 0nFdZEzfLmc/57qYrhwPTzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823I -# DzAOBgNVHQ8BAf8EBAMCAYYweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhho -# dHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNl -# cnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwRQYD -# VR0fBD4wPDA6oDigNoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0 -# QXNzdXJlZElEUm9vdENBLmNybDARBgNVHSAECjAIMAYGBFUdIAAwDQYJKoZIhvcN -# AQEMBQADggEBAHCgv0NcVec4X6CjdBs9thbX979XB72arKGHLOyFXqkauyL4hxpp -# VCLtpIh3bb0aFPQTSnovLbc47/T/gLn4offyct4kvFIDyE7QKt76LVbP+fT3rDB6 -# mouyXtTP0UNEm0Mh65ZyoUi0mcudT6cGAxN3J0TU53/oWajwvy8LpunyNDzs9wPH -# h6jSTEAZNUZqaVSwuKFWjuyk1T3osdz9HNj0d1pcVIxv76FQPfx2CWiEn2/K2yCN -# NWAcAgPLILCsWKAOQGPFmCLBsln1VWvPJ6tsds5vIy30fnFqI2si/xK4VC0nftg6 -# 2fC2h5b9W9FcrBjDTZ9ztwGpn1eqXijiuZQxggN2MIIDcgIBATB3MGMxCzAJBgNV -# BAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjE7MDkGA1UEAxMyRGlnaUNl -# cnQgVHJ1c3RlZCBHNCBSU0E0MDk2IFNIQTI1NiBUaW1lU3RhbXBpbmcgQ0ECEAp6 -# SoieyZlCkAZjOE2Gl50wDQYJYIZIAWUDBAIBBQCggdEwGgYJKoZIhvcNAQkDMQ0G -# CyqGSIb3DQEJEAEEMBwGCSqGSIb3DQEJBTEPFw0yMjA4MjQxODIxMjFaMCsGCyqG -# SIb3DQEJEAIMMRwwGjAYMBYEFIUI84ZRXLPTB322tLfAfxtKXkHeMC8GCSqGSIb3 -# DQEJBDEiBCCVPXW87DsZzYN/2CNJ8Dhw+HgEFP0LLlNz2d0G1l1GADA3BgsqhkiG -# 9w0BCRACLzEoMCYwJDAiBCCdppAVw0nGwYl4Rbo1gq1wyI+kKTvbar6cK9JTknnm -# OzANBgkqhkiG9w0BAQEFAASCAgBesMxK/z7PtURqNZ06RMKWmYcos+oTpEGJcKAM -# osFBo91R0huf1g2zBKT+CIec2o/ZISvpfCtoXK2NnsOr8Y3DfbPGbhyRD7I7DN1I -# huGTmwHzhtr67JPEoFLWlfgPfZQVYrMeiSwLe18dAXkj1aBdc5vTFELrKvu28KMh -# sDpJxZZYkErKANnnHoskifkMJ7/c/ICbQj2ZT8PIgJChtJjbhX/3qTq752XplIIL -# /OuumPA7nDFyOAJ55zknE41N8r05iXwYpoGmz9KYbNWVxg/0lq4JoPXVigc1Gd/g -# XtmCHh2tyKA97J8VTgNtXWcjSWcCXFwSCIYG4Dj5aUNMYVf3MNN6J4gyhvly7/rt -# 0czVQHhRMmWyUu0UvwLOhUUmNtleYGDK96hCLWZhw1poM9D8Vg6G2+O0Tv9izr1y -# r7PLC2zJOvrpnh6VNgOajajExSkQeesLkpdT02IivdDULXBrRgHOgkCSYs+RUL3I -# AS4ubb4NMqguuLltNq3YnftQwv71IYjCjXJgCk9X6gmD/a6iIXA4yTAURTanpBr4 -# WgIuuRPqtKiFhq6ThUYG0Wcb/Gs9H0WiOWeLzTyWQcelJK8zZie+8M4VjzmCztKY -# UMt9Di7YxThS4C6F7NzS14XCEUxyk9FPARht70sF5zuu6+Elcz+i46Tquh0MgmEY -# 7mCaKg== +# MB4XDTIyMDkyMTAwMDAwMFoXDTMzMTEyMTIzNTk1OVowRjELMAkGA1UEBhMCVVMx +# ETAPBgNVBAoTCERpZ2lDZXJ0MSQwIgYDVQQDExtEaWdpQ2VydCBUaW1lc3RhbXAg +# MjAyMiAtIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDP7KUmOsap +# 8mu7jcENmtuh6BSFdDMaJqzQHFUeHjZtvJJVDGH0nQl3PRWWCC9rZKT9BoMW15GS +# OBwxApb7crGXOlWvM+xhiummKNuQY1y9iVPgOi2Mh0KuJqTku3h4uXoW4VbGwLpk +# U7sqFudQSLuIaQyIxvG+4C99O7HKU41Agx7ny3JJKB5MgB6FVueF7fJhvKo6B332 +# q27lZt3iXPUv7Y3UTZWEaOOAy2p50dIQkUYp6z4m8rSMzUy5Zsi7qlA4DeWMlF0Z +# Wr/1e0BubxaompyVR4aFeT4MXmaMGgokvpyq0py2909ueMQoP6McD1AGN7oI2TWm +# tR7aeFgdOej4TJEQln5N4d3CraV++C0bH+wrRhijGfY59/XBT3EuiQMRoku7mL/6 +# T+R7Nu8GRORV/zbq5Xwx5/PCUsTmFntafqUlc9vAapkhLWPlWfVNL5AfJ7fSqxTl +# OGaHUQhr+1NDOdBk+lbP4PQK5hRtZHi7mP2Uw3Mh8y/CLiDXgazT8QfU4b3ZXUtu +# MZQpi+ZBpGWUwFjl5S4pkKa3YWT62SBsGFFguqaBDwklU/G/O+mrBw5qBzliGcnW +# hX8T2Y15z2LF7OF7ucxnEweawXjtxojIsG4yeccLWYONxu71LHx7jstkifGxxLjn +# U15fVdJ9GSlZA076XepFcxyEftfO4tQ6dwIDAQABo4IBizCCAYcwDgYDVR0PAQH/ +# BAQDAgeAMAwGA1UdEwEB/wQCMAAwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwIAYD +# VR0gBBkwFzAIBgZngQwBBAIwCwYJYIZIAYb9bAcBMB8GA1UdIwQYMBaAFLoW2W1N +# hS9zKXaaL3WMaiCPnshvMB0GA1UdDgQWBBRiit7QYfyPMRTtlwvNPSqUFN9SnDBa +# BgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNl +# cnRUcnVzdGVkRzRSU0E0MDk2U0hBMjU2VGltZVN0YW1waW5nQ0EuY3JsMIGQBggr +# BgEFBQcBAQSBgzCBgDAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu +# Y29tMFgGCCsGAQUFBzAChkxodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln +# aUNlcnRUcnVzdGVkRzRSU0E0MDk2U0hBMjU2VGltZVN0YW1waW5nQ0EuY3J0MA0G +# CSqGSIb3DQEBCwUAA4ICAQBVqioa80bzeFc3MPx140/WhSPx/PmVOZsl5vdyipjD +# d9Rk/BX7NsJJUSx4iGNVCUY5APxp1MqbKfujP8DJAJsTHbCYidx48s18hc1Tna9i +# 4mFmoxQqRYdKmEIrUPwbtZ4IMAn65C3XCYl5+QnmiM59G7hqopvBU2AJ6KO4ndet +# Hxy47JhB8PYOgPvk/9+dEKfrALpfSo8aOlK06r8JSRU1NlmaD1TSsht/fl4JrXZU +# inRtytIFZyt26/+YsiaVOBmIRBTlClmia+ciPkQh0j8cwJvtfEiy2JIMkU88ZpSv +# XQJT657inuTTH4YBZJwAwuladHUNPeF5iL8cAZfJGSOA1zZaX5YWsWMMxkZAO85d +# NdRZPkOaGK7DycvD+5sTX2q1x+DzBcNZ3ydiK95ByVO5/zQQZ/YmMph7/lxClIGU +# gp2sCovGSxVK05iQRWAzgOAj3vgDpPZFR+XOuANCR+hBNnF3rf2i6Jd0Ti7aHh2M +# WsgemtXC8MYiqE+bvdgcmlHEL5r2X6cnl7qWLoVXwGDneFZ/au/ClZpLEQLIgpzJ +# GgV8unG1TnqZbPTontRamMifv427GFxD9dAq6OJi7ngE273R+1sKqHB+8JeEeOMI +# A11HLGOoJTiXAdI/Otrl5fbmm9x+LMz/F0xNAKLY1gEOuIvu5uByVYksJxlh9ncB +# jDCCBq4wggSWoAMCAQICEAc2N7ckVHzYR6z9KGYqXlswDQYJKoZIhvcNAQELBQAw +# YjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ +# d3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgVHJ1c3RlZCBSb290 +# IEc0MB4XDTIyMDMyMzAwMDAwMFoXDTM3MDMyMjIzNTk1OVowYzELMAkGA1UEBhMC +# VVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMTswOQYDVQQDEzJEaWdpQ2VydCBU +# cnVzdGVkIEc0IFJTQTQwOTYgU0hBMjU2IFRpbWVTdGFtcGluZyBDQTCCAiIwDQYJ +# KoZIhvcNAQEBBQADggIPADCCAgoCggIBAMaGNQZJs8E9cklRVcclA8TykTepl1Gh +# 1tKD0Z5Mom2gsMyD+Vr2EaFEFUJfpIjzaPp985yJC3+dH54PMx9QEwsmc5Zt+Feo +# An39Q7SE2hHxc7Gz7iuAhIoiGN/r2j3EF3+rGSs+QtxnjupRPfDWVtTnKC3r07G1 +# decfBmWNlCnT2exp39mQh0YAe9tEQYncfGpXevA3eZ9drMvohGS0UvJ2R/dhgxnd +# X7RUCyFobjchu0CsX7LeSn3O9TkSZ+8OpWNs5KbFHc02DVzV5huowWR0QKfAcsW6 +# Th+xtVhNef7Xj3OTrCw54qVI1vCwMROpVymWJy71h6aPTnYVVSZwmCZ/oBpHIEPj +# Q2OAe3VuJyWQmDo4EbP29p7mO1vsgd4iFNmCKseSv6De4z6ic/rnH1pslPJSlREr +# WHRAKKtzQ87fSqEcazjFKfPKqpZzQmiftkaznTqj1QPgv/CiPMpC3BhIfxQ0z9JM +# q++bPf4OuGQq+nUoJEHtQr8FnGZJUlD0UfM2SU2LINIsVzV5K6jzRWC8I41Y99xh +# 3pP+OcD5sjClTNfpmEpYPtMDiP6zj9NeS3YSUZPJjAw7W4oiqMEmCPkUEBIDfV8j +# u2TjY+Cm4T72wnSyPx4JduyrXUZ14mCjWAkBKAAOhFTuzuldyF4wEr1GnrXTdrnS +# DmuZDNIztM2xAgMBAAGjggFdMIIBWTASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1Ud +# DgQWBBS6FtltTYUvcyl2mi91jGogj57IbzAfBgNVHSMEGDAWgBTs1+OC0nFdZEzf +# Lmc/57qYrhwPTzAOBgNVHQ8BAf8EBAMCAYYwEwYDVR0lBAwwCgYIKwYBBQUHAwgw +# dwYIKwYBBQUHAQEEazBpMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2Vy +# dC5jb20wQQYIKwYBBQUHMAKGNWh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9E +# aWdpQ2VydFRydXN0ZWRSb290RzQuY3J0MEMGA1UdHwQ8MDowOKA2oDSGMmh0dHA6 +# Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRSb290RzQuY3JsMCAG +# A1UdIAQZMBcwCAYGZ4EMAQQCMAsGCWCGSAGG/WwHATANBgkqhkiG9w0BAQsFAAOC +# AgEAfVmOwJO2b5ipRCIBfmbW2CFC4bAYLhBNE88wU86/GPvHUF3iSyn7cIoNqilp +# /GnBzx0H6T5gyNgL5Vxb122H+oQgJTQxZ822EpZvxFBMYh0MCIKoFr2pVs8Vc40B +# IiXOlWk/R3f7cnQU1/+rT4osequFzUNf7WC2qk+RZp4snuCKrOX9jLxkJodskr2d +# fNBwCnzvqLx1T7pa96kQsl3p/yhUifDVinF2ZdrM8HKjI/rAJ4JErpknG6skHibB +# t94q6/aesXmZgaNWhqsKRcnfxI2g55j7+6adcq/Ex8HBanHZxhOACcS2n82HhyS7 +# T6NJuXdmkfFynOlLAlKnN36TU6w7HQhJD5TNOXrd/yVjmScsPT9rp/Fmw0HNT7ZA +# myEhQNC3EyTN3B14OuSereU0cZLXJmvkOHOrpgFPvT87eK1MrfvElXvtCl8zOYdB +# eHo46Zzh3SP9HSjTx/no8Zhf+yvYfvJGnXUsHicsJttvFXseGYs2uJPU5vIXmVnK +# cPA3v5gA3yAWTyf7YGcWoWa63VXAOimGsJigK+2VQbc61RWYMbRiCQ8KvYHZE/6/ +# pNHzV9m8BPqC3jLfBInwAM1dwvnQI38AC+R2AibZ8GV2QqYphwlHK+Z/GqSFD/yY +# lvZVVCsfgPrA8g4r5db7qS9EFUrnEw4d2zc4GqEr9u3WfPwwggWNMIIEdaADAgEC +# AhAOmxiO+dAt5+/bUOIIQBhaMA0GCSqGSIb3DQEBDAUAMGUxCzAJBgNVBAYTAlVT +# MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +# b20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3VyZWQgSUQgUm9vdCBDQTAeFw0yMjA4 +# MDEwMDAwMDBaFw0zMTExMDkyMzU5NTlaMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQK +# EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNV +# BAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBHNDCCAiIwDQYJKoZIhvcNAQEBBQAD +# ggIPADCCAgoCggIBAL/mkHNo3rvkXUo8MCIwaTPswqclLskhPfKK2FnC4SmnPVir +# dprNrnsbhA3EMB/zG6Q4FutWxpdtHauyefLKEdLkX9YFPFIPUh/GnhWlfr6fqVcW +# WVVyr2iTcMKyunWZanMylNEQRBAu34LzB4TmdDttceItDBvuINXJIB1jKS3O7F5O +# yJP4IWGbNOsFxl7sWxq868nPzaw0QF+xembud8hIqGZXV59UWI4MK7dPpzDZVu7K +# e13jrclPXuU15zHL2pNe3I6PgNq2kZhAkHnDeMe2scS1ahg4AxCN2NQ3pC4FfYj1 +# gj4QkXCrVYJBMtfbBHMqbpEBfCFM1LyuGwN1XXhm2ToxRJozQL8I11pJpMLmqaBn +# 3aQnvKFPObURWBf3JFxGj2T3wWmIdph2PVldQnaHiZdpekjw4KISG2aadMreSx7n +# DmOu5tTvkpI6nj3cAORFJYm2mkQZK37AlLTSYW3rM9nF30sEAMx9HJXDj/chsrIR +# t7t/8tWMcCxBYKqxYxhElRp2Yn72gLD76GSmM9GJB+G9t+ZDpBi4pncB4Q+UDCEd +# slQpJYls5Q5SUUd0viastkF13nqsX40/ybzTQRESW+UQUOsxxcpyFiIJ33xMdT9j +# 7CFfxCBRa2+xq4aLT8LWRV+dIPyhHsXAj6KxfgommfXkaS+YHS312amyHeUbAgMB +# AAGjggE6MIIBNjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTs1+OC0nFdZEzf +# Lmc/57qYrhwPTzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzAOBgNV +# HQ8BAf8EBAMCAYYweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8v +# b2NzcC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRp +# Z2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwRQYDVR0fBD4w +# PDA6oDigNoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJl +# ZElEUm9vdENBLmNybDARBgNVHSAECjAIMAYGBFUdIAAwDQYJKoZIhvcNAQEMBQAD +# ggEBAHCgv0NcVec4X6CjdBs9thbX979XB72arKGHLOyFXqkauyL4hxppVCLtpIh3 +# bb0aFPQTSnovLbc47/T/gLn4offyct4kvFIDyE7QKt76LVbP+fT3rDB6mouyXtTP +# 0UNEm0Mh65ZyoUi0mcudT6cGAxN3J0TU53/oWajwvy8LpunyNDzs9wPHh6jSTEAZ +# NUZqaVSwuKFWjuyk1T3osdz9HNj0d1pcVIxv76FQPfx2CWiEn2/K2yCNNWAcAgPL +# ILCsWKAOQGPFmCLBsln1VWvPJ6tsds5vIy30fnFqI2si/xK4VC0nftg62fC2h5b9 +# W9FcrBjDTZ9ztwGpn1eqXijiuZQxggN2MIIDcgIBATB3MGMxCzAJBgNVBAYTAlVT +# MRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjE7MDkGA1UEAxMyRGlnaUNlcnQgVHJ1 +# c3RlZCBHNCBSU0E0MDk2IFNIQTI1NiBUaW1lU3RhbXBpbmcgQ0ECEAxNaXJLlPo8 +# Kko9KQeAPVowDQYJYIZIAWUDBAIBBQCggdEwGgYJKoZIhvcNAQkDMQ0GCyqGSIb3 +# DQEJEAEEMBwGCSqGSIb3DQEJBTEPFw0yMzAyMTUxMzMwMTFaMCsGCyqGSIb3DQEJ +# EAIMMRwwGjAYMBYEFPOHIk2GM4KSNamUvL2Plun+HHxzMC8GCSqGSIb3DQEJBDEi +# BCA7SrAWbQNkmbU9LjrRZ4LzQE7UYXLUcF6HW0DtRDdWNzA3BgsqhkiG9w0BCRAC +# LzEoMCYwJDAiBCDH9OG+MiiJIKviJjq+GsT8T+Z4HC1k0EyAdVegI7W2+jANBgkq +# hkiG9w0BAQEFAASCAgDCyTi3gdhrQbVlQKWElMp4NGEX0POnEJUhKUCT9A7a2UuP +# s8+B/Sr/wxxsLvnOQ4vBKPYrROBtT8zEdnGtiisdbmu3uyTMh4UxXFp60VZdOVK6 +# 7/d9v5JdcuU1Mz/h3t11HjxNNfzxJjsF2McbhE7LHK8gM2w1Um6hwvygqhl5atYm +# X+OioWotO5Zi6X4QgkDPaqxnfw68U+TI0XEjW28LoLl8yoPWgwJPGyJYGPW8Amag +# YhohidOeOXSCxLPAyzXZgPukvL4g0jIJGNXiBC2b7q8EmbY/wvH8DfZvD4j8FZmZ +# gMItvhdIWjk2qUMlQbjIRGrjHvLD6wx1u3XZ5oK4HVQ5ydg1UwQs66TIWhbnK0Z5 +# w0cbTxSxuVsedJ2+wG2FuARXnATEypHV4GAXhyQ4Vv3l4PafwZuzvy0LJiI3Qwld +# lNWzxnnohaySFSyceX/7wujYJ3Vp7tIVjYXKUS7EAXUIP+reyuXkUArViOGTHVdA +# vT8UwqWR5Rb0kB9tyetI8tCZY8C0iWJrkmLWMgtYmDs5xiI9a4A2TymDL2G0bLcq +# ktY+fM1RnMVCKtlwQrEvKyfQ6kSnjB339FsUHzW6l7FFFsN/g5zF5yqivVzdMlL2 +# TY0zGul+jVSgonTarjWPH+298OJjY9ENuv3uJyFJ0AqmyxD7ALa4ndU9z++Qlg== # SIG # End signature block diff --git a/nf.props b/nf.props index 5f82cb24f0..26be4d51d1 100644 --- a/nf.props +++ b/nf.props @@ -19,12 +19,11 @@ 99 999 9999 - 9.99.999.9999 - VIRTUAL_DEVICE;SUPPORT_ANY_BASE_CONVERSION;NANOCLR_REFLECTION=TRUE;NANOCLR_SYSTEM_COLLECTIONS=TRUE;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;VERSION_MAJOR=$(NBGV_VersionMajor);VERSION_MINOR=$(NBGV_VersionMinor);VERSION_BUILD=$(NBGV_BuildNumber);VERSION_REVISION=$(TARGET_BUILD_COUNTER);VERSION_STRING="$(WINCLR_AssemblyInformationalVersion)";PLATFORMNAMESTRING="WINDOWS"; + VIRTUAL_DEVICE;SUPPORT_ANY_BASE_CONVERSION;NANOCLR_REFLECTION=TRUE;NANOCLR_SYSTEM_COLLECTIONS=TRUE;_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING;VERSION_MAJOR=$(NBGV_VersionMajor);VERSION_MINOR=$(NBGV_VersionMinor);VERSION_BUILD=$(NBGV_BuildNumber);VERSION_REVISION=$(TARGET_BUILD_COUNTER);PLATFORMNAMESTRING="WINDOWS"; stdcpp20 stdc17 diff --git a/src/CLR/CorLib/corlib_native.cpp b/src/CLR/CorLib/corlib_native.cpp index 21148dcf0c..e9f461fce1 100644 --- a/src/CLR/CorLib/corlib_native.cpp +++ b/src/CLR/CorLib/corlib_native.cpp @@ -488,6 +488,7 @@ static const CLR_RT_MethodHandler method_lookup[] = NULL, NULL, NULL, + NULL, Library_corlib_native_System_Diagnostics_Debug::WriteLineNative___STATIC__VOID__STRING__BOOLEAN, Library_corlib_native_System_Diagnostics_Debugger::get_IsAttached___STATIC__BOOLEAN, Library_corlib_native_System_Diagnostics_Debugger::Break___STATIC__VOID, @@ -1233,6 +1234,7 @@ static const CLR_RT_MethodHandler method_lookup[] = NULL, NULL, NULL, + NULL, Library_corlib_native_System_Diagnostics_Debug::WriteLineNative___STATIC__VOID__STRING__BOOLEAN, Library_corlib_native_System_Diagnostics_Debugger::get_IsAttached___STATIC__BOOLEAN, Library_corlib_native_System_Diagnostics_Debugger::Break___STATIC__VOID, @@ -1481,18 +1483,18 @@ const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_mscorlib = #if (NANOCLR_REFLECTION == TRUE) - 0x004CF1CE, + 0xCCE8376E, #elif (NANOCLR_REFLECTION == FALSE) - 0x3F4EB772, + 0xF60D1B13, #else #error "NANOCLR_REFLECTION has to be define either TRUE or FALSE. Check the build options." #endif method_lookup, - { 100, 5, 0, 17 } + { 100, 5, 0, 18 } }; // clang-format on diff --git a/src/CLR/CorLib/corlib_native.h b/src/CLR/CorLib/corlib_native.h index eee37b0ed6..20523091e6 100644 --- a/src/CLR/CorLib/corlib_native.h +++ b/src/CLR/CorLib/corlib_native.h @@ -39,7 +39,7 @@ struct Library_corlib_native_System_Boolean static const int FIELD_STATIC__FalseString = 0; static const int FIELD_STATIC__TrueString = 1; - static const int FIELD___value = 1; + static const int FIELD__m_value = 1; //--// }; @@ -173,21 +173,21 @@ struct Library_corlib_native_System_Object struct Library_corlib_native_System_Int64 { - static const int FIELD___value = 1; + static const int FIELD__m_value = 1; //--// }; struct Library_corlib_native_System_Int32 { - static const int FIELD___value = 1; + static const int FIELD__m_value = 1; //--// }; struct Library_corlib_native_System_Char { - static const int FIELD___value = 1; + static const int FIELD__m_value = 1; //--// }; @@ -404,7 +404,8 @@ struct Library_corlib_native_System_BitConverter struct Library_corlib_native_System_Byte { - static const int FIELD___value = 1; + + static const int FIELD__m_value = 1; //--// }; @@ -413,6 +414,7 @@ struct Library_corlib_native_System_Collections_ArrayList { static const int FIELD___items = 1; static const int FIELD___size = 2; + static const int FIELD___syncRoot = 3; NANOCLR_NATIVE_DECLARE(get_Item___OBJECT__I4); NANOCLR_NATIVE_DECLARE(set_Item___VOID__I4__OBJECT); @@ -425,9 +427,17 @@ struct Library_corlib_native_System_Collections_ArrayList //--// }; +struct Library_corlib_native_System_ComponentModel_EditorBrowsableState +{ + + static const int FIELD__value__ = 1; + + //--// +}; struct Library_corlib_native_System_Double { - static const int FIELD___value = 1; + + static const int FIELD__m_value = 1; NANOCLR_NATIVE_DECLARE(CompareTo___STATIC__I4__R8__R8); NANOCLR_NATIVE_DECLARE(IsInfinity___STATIC__BOOLEAN__R8); @@ -551,7 +561,7 @@ struct Library_corlib_native_System_Diagnostics_DebuggerBrowsableAttribute struct Library_corlib_native_System_UInt16 { - static const int FIELD___value = 1; + static const int FIELD__m_value = 1; //--// }; @@ -606,14 +616,14 @@ struct Library_corlib_native_System_Globalization_DateTimeFormat struct Library_corlib_native_System_UInt32 { - static const int FIELD___value = 1; + static const int FIELD__m_value = 1; //--// }; struct Library_corlib_native_System_Int16 { - static const int FIELD___value = 1; + static const int FIELD__m_value = 1; //--// }; @@ -704,6 +714,7 @@ struct Library_corlib_native_System_Number char *decimalSeparator, char *numberGroupSeparator, CLR_RT_HeapBlock_Array *numberGroupSizes); + static int Format_E(char *buffer, CLR_RT_HeapBlock *value, int precision, char formatChar); }; struct Library_corlib_native_System_Random @@ -864,14 +875,14 @@ struct Library_corlib_native_System_RuntimeType struct Library_corlib_native_System_SByte { - static const int FIELD___value = 1; + static const int FIELD__m_value = 1; //--// }; struct Library_corlib_native_System_Single { - static const int FIELD___value = 1; + static const int FIELD__m_value = 1; //--// }; @@ -1016,7 +1027,7 @@ struct Library_corlib_native_System_Threading_WaitHandle struct Library_corlib_native_System_UInt64 { - static const int FIELD___value = 1; + static const int FIELD__m_value = 1; //--// }; diff --git a/src/CLR/CorLib/corlib_native_System_Convert.cpp b/src/CLR/CorLib/corlib_native_System_Convert.cpp index 8b5fe57b71..f48b69c30d 100644 --- a/src/CLR/CorLib/corlib_native_System_Convert.cpp +++ b/src/CLR/CorLib/corlib_native_System_Convert.cpp @@ -555,6 +555,12 @@ HRESULT Library_corlib_native_System_Convert::NativeToDateTime___STATIC__SystemD conversionResult = Nano_strptime(str, "%Y-%m-%dT%H:%M:%S.%f", &ticks); } + if (conversionResult == NULL) + { + // try 'o/O' Round Trip ISO 8601 compatible (yyyy-MM-ddTHH:mm:ss) + conversionResult = Nano_strptime(str, "%Y-%m-%dT%H:%M:%S", &ticks); + } + if (conversionResult == NULL) { // try 'r/R' RFC 1123 date (ddd, dd MMM yyyy HH:mm:ss) @@ -598,7 +604,7 @@ HRESULT Library_corlib_native_System_Convert::ToBase64String___STATIC__STRING__S char *outArray = NULL; char *outArrayWitLineBreak = NULL; uint8_t *inArrayPointer = NULL; - uint8_t lineBreakCount; + int32_t lineBreakCount; uint16_t offsetIndex = 0; uint8_t count = 0; uint16_t result; @@ -721,18 +727,18 @@ HRESULT Library_corlib_native_System_Convert::FromBase64String___STATIC__SZARRAY #if (SUPPORT_ANY_BASE_CONVERSION == TRUE) CLR_RT_HeapBlock_String *inString = NULL; - size_t outputLength; + uint32_t outputLength; char *outArray = NULL; CLR_UINT8 *returnArray; uint16_t result; - size_t length; + uint32_t length; inString = stack.Arg0().DereferenceString(); FAULT_ON_NULL(inString); FAULT_ON_NULL_ARG(inString->StringText()); - length = (size_t)hal_strlen_s(inString->StringText()); + length = hal_strlen_s(inString->StringText()); // estimate output length outputLength = length / 4 * 3; @@ -749,8 +755,8 @@ HRESULT Library_corlib_native_System_Convert::FromBase64String___STATIC__SZARRAY // need to tweak the parameter with the output length because it includes room for the terminator result = mbedtls_base64_decode( (unsigned char *)outArray, - (outputLength + 1), - &outputLength, + (size_t)(outputLength + 1), + (size_t *)&outputLength, (const unsigned char *)inString->StringText(), length); diff --git a/src/CLR/CorLib/corlib_native_System_Diagnostics_Debug.cpp b/src/CLR/CorLib/corlib_native_System_Diagnostics_Debug.cpp index 52f47a2a1f..0591383e8b 100644 --- a/src/CLR/CorLib/corlib_native_System_Diagnostics_Debug.cpp +++ b/src/CLR/CorLib/corlib_native_System_Diagnostics_Debug.cpp @@ -1,28 +1,29 @@ // // Copyright (c) .NET Foundation and Contributors -// Portions Copyright (c) Microsoft Corporation. All rights reserved. // See LICENSE file in the project root for full license information. // #include "CorLib.h" - -HRESULT Library_corlib_native_System_Diagnostics_Debug::WriteLineNative___STATIC__VOID__STRING__BOOLEAN( CLR_RT_StackFrame& stack ) +HRESULT Library_corlib_native_System_Diagnostics_Debug::WriteLineNative___STATIC__VOID__STRING__BOOLEAN( + CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); - const char * szText0 = stack.Arg0().RecoverString(); + const char *szText0 = stack.Arg0().RecoverString(); bool addLineFeed = (bool)stack.Arg1().NumericByRef().u1; - if(!szText0) szText0 = ""; + if (!szText0) + { + szText0 = ""; + } - CLR_Debug::Emit( szText0, -1 ); + CLR_Debug::Emit(szText0, -1); - if(addLineFeed) + if (addLineFeed) { - CLR_Debug::Emit( "\r\n" , -1 ); + CLR_Debug::Emit("\r\n", -1); } - + NANOCLR_NOCLEANUP_NOLABEL(); } - diff --git a/src/CLR/CorLib/corlib_native_System_Exception.cpp b/src/CLR/CorLib/corlib_native_System_Exception.cpp index 4cc1caff22..2c46fc15fc 100644 --- a/src/CLR/CorLib/corlib_native_System_Exception.cpp +++ b/src/CLR/CorLib/corlib_native_System_Exception.cpp @@ -175,56 +175,87 @@ HRESULT Library_corlib_native_System_Exception::SetStackTrace(CLR_RT_HeapBlock & NATIVE_PROFILE_CLR_CORE(); NANOCLR_HEADER(); + CLR_RT_HeapBlock *obj; + CLR_RT_HeapBlock_Array *array; + StackTrace *dst; + CLR_UINT32 depth = 0; + + obj = ref.Dereference(); + if (stack) { - CLR_RT_HeapBlock *obj; - CLR_RT_HeapBlock_Array *array; - StackTrace *dst; - CLR_UINT32 depth; - if (CLR_RT_ExecutionEngine::IsInstanceOf(ref, g_CLR_RT_WellKnownTypes.m_Exception) == false) - NANOCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE); - - //--// - - obj = ref.Dereference(); - depth = 0; - - NANOCLR_FOREACH_NODE_BACKWARD__DIRECT(CLR_RT_StackFrame, stackSub, stack) { - depth++; + NANOCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE); } - NANOCLR_FOREACH_NODE_BACKWARD_END(); - - //--// - NANOCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance( - obj[FIELD___stackTrace], - depth * sizeof(StackTrace), - g_CLR_RT_WellKnownTypes.m_UInt8)); +#if defined(NANOCLR_TRACE_EXCEPTIONS) - //--// - - array = obj[FIELD___stackTrace].DereferenceArray(); - dst = (StackTrace *)array->GetFirstElement(); - - NANOCLR_FOREACH_NODE_BACKWARD__DIRECT(CLR_RT_StackFrame, stackSub, stack) + if (CLR_EE_DBG_IS(NoStackTraceInExceptions)) { - dst->m_md = stackSub->m_call; - dst->m_IP = (CLR_UINT32)(stackSub->m_IP - stackSub->m_IPstart); + // stack trace is DISABLED + + (void)dst; + (void)array; - dst++; + // create an empty array for the stack trace + NANOCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance( + obj[FIELD___stackTrace], + depth, + g_CLR_RT_WellKnownTypes.m_UInt8)); } - NANOCLR_FOREACH_NODE_BACKWARD_END(); + else + { + // stack trace is enabled + + // crawl the stack to get the depth + NANOCLR_FOREACH_NODE_BACKWARD__DIRECT(CLR_RT_StackFrame, stackSub, stack) + { + depth++; + } + NANOCLR_FOREACH_NODE_BACKWARD_END(); + + NANOCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance( + obj[FIELD___stackTrace], + depth * sizeof(StackTrace), + g_CLR_RT_WellKnownTypes.m_UInt8)); + + // get a pointer to the array + array = obj[FIELD___stackTrace].DereferenceArray(); + dst = (StackTrace *)array->GetFirstElement(); + + // crawl the stack to get the stack trace + NANOCLR_FOREACH_NODE_BACKWARD__DIRECT(CLR_RT_StackFrame, stackSub, stack) + { + dst->m_md = stackSub->m_call; + dst->m_IP = (CLR_UINT32)(stackSub->m_IP - stackSub->m_IPstart); + + dst++; + } + NANOCLR_FOREACH_NODE_BACKWARD_END(); #if !defined(BUILD_RTM) - // shutting down the EE happens by Thread->Abort. These exceptions are by design, and - // don't need to be logged, or written to the console.... - if (!g_CLR_RT_ExecutionEngine.m_fShuttingDown) + // shutting down the EE happens by Thread->Abort. These exceptions are by design, and + // don't need to be logged, or written to the console.... + if (!g_CLR_RT_ExecutionEngine.m_fShuttingDown) #endif - { - CLR_RT_DUMP::EXCEPTION(*stack, ref); + { + if (CLR_EE_DBG_IS_NOT(NoStackTraceInExceptions)) + { + CLR_RT_DUMP::EXCEPTION(*stack, ref); + } + } } + +#else + (void)dst; + (void)array; + + // create an empty array for the stack trace + NANOCLR_CHECK_HRESULT( + CLR_RT_HeapBlock_Array::CreateInstance(obj[FIELD___stackTrace], depth, g_CLR_RT_WellKnownTypes.m_UInt8)); + +#endif } NANOCLR_NOCLEANUP(); diff --git a/src/CLR/CorLib/corlib_native_System_Number.cpp b/src/CLR/CorLib/corlib_native_System_Number.cpp index 7f18a4d786..4d9039e87e 100644 --- a/src/CLR/CorLib/corlib_native_System_Number.cpp +++ b/src/CLR/CorLib/corlib_native_System_Number.cpp @@ -52,43 +52,31 @@ bool Library_corlib_native_System_Number::ParseFormat(char *format, char *format bool Library_corlib_native_System_Number::ValidateFormatChar(char *formatChar, bool isInteger) { - bool ret = true; - switch (*formatChar) { - case 'g': - case 'G': - case 'n': - case 'N': - case 'f': - case 'F': - break; + // these need to be integers case 'x': case 'X': case 'd': case 'D': - if (!isInteger) - { - ret = false; - } - break; + return isInteger; + + // all the others shoudl be OK or will be caught afterwards default: - ret = false; + return true; } - - return ret; } bool Library_corlib_native_System_Number::GetFormatSpec(char *format, bool isInteger, char *formatChar, int *precision) { - bool ret = ParseFormat(format, formatChar, precision); - - if (ret) + if (ParseFormat(format, formatChar, precision)) { - ret = ValidateFormatChar(formatChar, isInteger); + return ValidateFormatChar(formatChar, isInteger); + } + else + { + return false; } - - return ret; } int Library_corlib_native_System_Number::DoPrintfOnDataType(char *buffer, char *formatStr, CLR_RT_HeapBlock *value) @@ -100,34 +88,36 @@ int Library_corlib_native_System_Number::DoPrintfOnDataType(char *buffer, char * switch (dataType) { case DATATYPE_I1: - ret = snprintf(buffer, FORMAT_RESULT_BUFFER_SIZE, formatStr, value->NumericByRef().s1); + ret = (int)snprintf(buffer, FORMAT_RESULT_BUFFER_SIZE, formatStr, value->NumericByRef().s1); break; case DATATYPE_U1: - ret = snprintf(buffer, FORMAT_RESULT_BUFFER_SIZE, formatStr, value->NumericByRef().u1); + ret = (int)snprintf(buffer, FORMAT_RESULT_BUFFER_SIZE, formatStr, value->NumericByRef().u1); break; case DATATYPE_I2: - ret = snprintf(buffer, FORMAT_RESULT_BUFFER_SIZE, formatStr, value->NumericByRef().s2); + ret = (int)snprintf(buffer, FORMAT_RESULT_BUFFER_SIZE, formatStr, value->NumericByRef().s2); break; case DATATYPE_U2: - ret = snprintf(buffer, FORMAT_RESULT_BUFFER_SIZE, formatStr, value->NumericByRef().u2); + ret = (int)snprintf(buffer, FORMAT_RESULT_BUFFER_SIZE, formatStr, value->NumericByRef().u2); break; case DATATYPE_I4: - ret = snprintf(buffer, FORMAT_RESULT_BUFFER_SIZE, formatStr, value->NumericByRef().s4); + ret = (int)snprintf(buffer, FORMAT_RESULT_BUFFER_SIZE, formatStr, value->NumericByRef().s4); break; case DATATYPE_U4: - ret = snprintf(buffer, FORMAT_RESULT_BUFFER_SIZE, formatStr, value->NumericByRef().u4); + ret = (int)snprintf(buffer, FORMAT_RESULT_BUFFER_SIZE, formatStr, value->NumericByRef().u4); break; case DATATYPE_I8: - ret = snprintf(buffer, FORMAT_RESULT_BUFFER_SIZE, formatStr, (CLR_INT64_TEMP_CAST)value->NumericByRef().s8); + ret = (int)(int) + snprintf(buffer, FORMAT_RESULT_BUFFER_SIZE, formatStr, (CLR_INT64_TEMP_CAST)value->NumericByRef().s8); break; case DATATYPE_U8: - ret = snprintf(buffer, FORMAT_RESULT_BUFFER_SIZE, formatStr, (CLR_INT64_TEMP_CAST)value->NumericByRef().s8); + ret = (int) + snprintf(buffer, FORMAT_RESULT_BUFFER_SIZE, formatStr, (CLR_UINT64_TEMP_CAST)value->NumericByRef().u8); break; case DATATYPE_R4: - ret = snprintf(buffer, FORMAT_RESULT_BUFFER_SIZE, formatStr, value->NumericByRef().r4); + ret = (int)snprintf(buffer, FORMAT_RESULT_BUFFER_SIZE, formatStr, value->NumericByRef().r4); break; case DATATYPE_R8: - ret = + ret = (int) snprintf(buffer, FORMAT_RESULT_BUFFER_SIZE, formatStr, (CLR_DOUBLE_TEMP_CAST)value->NumericByRef().r8); break; default: @@ -136,20 +126,20 @@ int Library_corlib_native_System_Number::DoPrintfOnDataType(char *buffer, char * // assure string valid even in cases when nothing was written if (ret >= 0) + { buffer[ret] = 0; + } return ret; } const char *Library_corlib_native_System_Number::GetPrintfLengthModifier(CLR_DataType dataType) { - const char *ret = (dataType == DATATYPE_I1 || dataType == DATATYPE_U1) - ? "hh" - : (dataType == DATATYPE_I2 || dataType == DATATYPE_U2) - ? "h" - : (dataType == DATATYPE_I4 || dataType == DATATYPE_U4) - ? "" - : (dataType == DATATYPE_I8 || dataType == DATATYPE_U8) ? "ll" : ""; + const char *ret = (dataType == DATATYPE_I1 || dataType == DATATYPE_U1) ? "" + : (dataType == DATATYPE_I2 || dataType == DATATYPE_U2) ? "" + : (dataType == DATATYPE_I4 || dataType == DATATYPE_U4) ? "" + : (dataType == DATATYPE_I8 || dataType == DATATYPE_U8) ? "ll" + : ""; return ret; } @@ -342,47 +332,66 @@ int Library_corlib_native_System_Number::Format_G( bool isIntegerDataType = IsIntegerDataType(dataType); + // set default precision for the conversion + int defaultPrecision = 0; + switch (dataType) + { + case DATATYPE_I1: + case DATATYPE_U1: + defaultPrecision = 3; + break; + case DATATYPE_I2: + case DATATYPE_U2: + defaultPrecision = 5; + break; + case DATATYPE_I4: + case DATATYPE_U4: + defaultPrecision = 10; + break; + case DATATYPE_I8: + defaultPrecision = 19; + break; + case DATATYPE_U8: + defaultPrecision = 20; + break; + case DATATYPE_R4: + // from .NET documentation: + // When used with a Single value, the "G9" format specifier ensures that the original Single value + // successfully round-trips. + defaultPrecision = 9; + break; + case DATATYPE_R8: + // from .NET documentation: + // When used with a Double value, the "G17" format specifier ensures that the original Double value + // successfully round-trips. + defaultPrecision = 17; + break; + default: + break; + } + + int requestedPrecision = precision; + if (precision == -1) { - switch (dataType) - { - case DATATYPE_I1: - case DATATYPE_U1: - precision = 3; - break; - case DATATYPE_I2: - case DATATYPE_U2: - precision = 5; - break; - case DATATYPE_I4: - case DATATYPE_U4: - precision = 10; - break; - case DATATYPE_I8: - precision = 19; - break; - case DATATYPE_U8: - precision = 20; - break; - case DATATYPE_R4: - precision = 7; - break; - case DATATYPE_R8: - precision = 15; - break; - default: - break; - } + // no precision specified, use default + precision = defaultPrecision; + } + + int precisionForConversion = precision; + + if (!isIntegerDataType) + { + precisionForConversion += 2; } if (precision > 0) { + // compose format string char nonIntegerPrecStr[FORMAT_FMTSTR_BUFFER_SIZE]; if (!isIntegerDataType) { - // value of incoming precision would be more than enough - // see diff between printf and ToString precision meaning below - snprintf(nonIntegerPrecStr, FORMAT_FMTSTR_BUFFER_SIZE, "0.%d", precision); + snprintf(nonIntegerPrecStr, FORMAT_FMTSTR_BUFFER_SIZE, "0.%d", precisionForConversion); } char formatStr[FORMAT_FMTSTR_BUFFER_SIZE]; @@ -392,9 +401,12 @@ int Library_corlib_native_System_Number::Format_G( "%%%s%s%c", (isIntegerDataType) ? "" : nonIntegerPrecStr, (isIntegerDataType) ? GetPrintfLengthModifier(dataType) : "", - (!isIntegerDataType) ? 'f' : (IsSignedIntegerDataType(dataType)) ? 'd' : 'u'); + (!isIntegerDataType) ? formatChar + : (IsSignedIntegerDataType(dataType)) ? 'd' + : 'u'); ret = DoPrintfOnDataType(buffer, formatStr, value); + if (ret > 0) { // printf and ToString differs on precision numbers: @@ -406,6 +418,25 @@ int Library_corlib_native_System_Number::Format_G( bool isNegative = (buffer[0] == '-'); int offsetBecauseOfNegativeSign = (isNegative ? 1 : 0); int savedResultLength = ret; + int exponent = 0; + + // find the exponent character, start with lower case + char *e = strchr(buffer, 'e'); + + if (!e) + { + // try upper case + e = strchr(buffer, 'E'); + } + + if (e) + { + // move past the exponent character + e++; + + // convert exponent to digits + exponent = atoi(e); + } if (ret > (precision + offsetBecauseOfNegativeSign)) { @@ -414,28 +445,64 @@ int Library_corlib_native_System_Number::Format_G( int numDigits = 0; // leave just the required amount of digits - for (int i = 0; i < ret; i++) + if (requestedPrecision <= defaultPrecision) { - if (buffer[i] >= '0' && buffer[i] <= '9') + // find the first digit after the dot + for (int i = 0; i < ret; i++) { - numDigits++; - if (numDigits == precision) + if (buffer[i] >= '0' && buffer[i] <= '9') { - ret = i + 1; - char first_lost_digit = buffer[ret]; - if (first_lost_digit == '.' && (ret + 1) < savedResultLength) - { - first_lost_digit = buffer[ret + 1]; - } - buffer[ret] = 0; - if (first_lost_digit >= '5') + numDigits++; + + if (numDigits == precision) { - int savedRet = ret; - RoundUpNumStr(buffer, &ret); - if (savedRet < ret) - dotIndex++; + ret = i + 1; + char first_lost_digit = buffer[ret]; + + // handle various situation, like rounding, exponent, rounding errors + if (first_lost_digit == '.' && (ret + 1) < savedResultLength) + { + first_lost_digit = buffer[ret + 1]; + buffer[ret] = 0; + } + else if (first_lost_digit == 'E' || first_lost_digit == 'e') + { + first_lost_digit = buffer[ret - 1]; + buffer[ret] = 0; + ret--; + } + else + { + buffer[ret] = 0; + } + + // drop last digit in case it's a rounding digit + // conditions are: + // - not an integer type + // - number of digits is at least 2 + // - number of digits is greater than the default precision (otherwise we could be + // mistaking a valid last fraction digit for a rounding digit) + if (!isIntegerDataType && numDigits >= 2 && numDigits >= defaultPrecision && + buffer[ret - 2] == '0') + { + buffer[ret - 1] = 0; + ret--; + + break; + } + + if (first_lost_digit >= '5') + { + int savedRet = ret; + RoundUpNumStr(buffer, &ret); + + if (savedRet < ret) + { + dotIndex++; + } + } + break; } - break; } } } @@ -449,9 +516,11 @@ int Library_corlib_native_System_Number::Format_G( { break; } + buffer[i] = 0; ret--; } + // strip trailing dot too if (ret == dotIndex + 1) { @@ -460,26 +529,35 @@ int Library_corlib_native_System_Number::Format_G( } } - if ((dotIndex == -1) || (dotIndex > (precision + offsetBecauseOfNegativeSign))) + if ((dotIndex == -1) || exponent != 0 || (dotIndex > (precision + offsetBecauseOfNegativeSign))) { - // insert '.' - memmove( - &buffer[2 + offsetBecauseOfNegativeSign], - &buffer[1 + offsetBecauseOfNegativeSign], - ret - 1); - buffer[1 + offsetBecauseOfNegativeSign] = '.'; - ret++; - - // append 'E+exp' - int exponent = (dotIndex == -1) ? savedResultLength - 1 : dotIndex - 1; - exponent -= offsetBecauseOfNegativeSign; + // insert '.', only if request precision requires it + // this is: requestedPrecision is specified and is more than 1 (taking into account the sign) + if (requestedPrecision > 0 && (ret - offsetBecauseOfNegativeSign) > 1) + { + memmove( + &buffer[2 + offsetBecauseOfNegativeSign], + &buffer[1 + offsetBecauseOfNegativeSign], + ret - 1); + buffer[1 + offsetBecauseOfNegativeSign] = '.'; + + ret++; + } + + // deal with 'E+exp' + if (exponent == 0) + { + exponent = (dotIndex == -1) ? savedResultLength - 1 : dotIndex - 1; + exponent -= offsetBecauseOfNegativeSign; + } + if (formatChar == 'g') { - ret += snprintf(&buffer[ret], FORMAT_RESULT_BUFFER_SIZE - ret, "e+%02d", exponent); + ret += (int)snprintf(&buffer[ret], FORMAT_RESULT_BUFFER_SIZE - ret, "e%+.2d", exponent); } else { - ret += snprintf(&buffer[ret], FORMAT_RESULT_BUFFER_SIZE - ret, "E+%02d", exponent); + ret += (int)snprintf(&buffer[ret], FORMAT_RESULT_BUFFER_SIZE - ret, "E%+.2d", exponent); } } } @@ -542,8 +620,35 @@ int Library_corlib_native_System_Number::Format_X(char *buffer, CLR_RT_HeapBlock { int ret = -1; + CLR_DataType dataType = value->DataType(); + + // set max width for the conversion + int maxWidth = 0; + switch (dataType) + { + case DATATYPE_I1: + case DATATYPE_U1: + maxWidth = 2; + break; + case DATATYPE_I2: + case DATATYPE_U2: + maxWidth = 4; + break; + case DATATYPE_I4: + case DATATYPE_U4: + maxWidth = 8; + break; + case DATATYPE_I8: + case DATATYPE_U8: + maxWidth = 16; + break; + default: + break; + } + if (precision == -1) { + // no precision specified precision = 0; } @@ -558,6 +663,15 @@ int Library_corlib_native_System_Number::Format_X(char *buffer, CLR_RT_HeapBlock ret = DoPrintfOnDataType(buffer, formatStr, value); + if (ret > maxWidth) + { + // we have more digits than the max width, so we need to strip the leading ones + memmove(&buffer[0], &buffer[ret - maxWidth], maxWidth); + + buffer[maxWidth] = 0; + ret = maxWidth; + } + return ret; } @@ -587,20 +701,47 @@ int Library_corlib_native_System_Number::Format_F( "%%0.%d%s%c", precision, (isIntegerDataType) ? GetPrintfLengthModifier(dataType) : "", - (!isIntegerDataType) ? 'f' : (IsSignedIntegerDataType(dataType)) ? 'd' : 'u'); + (!isIntegerDataType) ? 'f' + : (IsSignedIntegerDataType(dataType)) ? 'd' + : 'u'); ret = DoPrintfOnDataType(buffer, formatStr, value); - if (ret > 0) + + // this extra processing is only required for integer types + if (isIntegerDataType && ret > 0) { + bool isNegative = (buffer[0] == '-'); + int offsetBecauseOfNegativeSign = (isNegative ? 1 : 0); + + int dotIndex = GetDotIndex(buffer, ret); + + // if there is no dot, set the index to the end of the string + if (dotIndex == -1) + { + dotIndex = ret; + } + + // strip trailing zeros + while (buffer[offsetBecauseOfNegativeSign] != '.' && buffer[offsetBecauseOfNegativeSign] == '0' && ret > 1) + { + memmove(&buffer[offsetBecauseOfNegativeSign], &buffer[offsetBecauseOfNegativeSign + 1], ret); + + ret--; + }; + if (isIntegerDataType && (precision > 0)) { + // insert '.' and... buffer[ret++] = '.'; + + // ...fill with zeros for (int i = 0; i < precision; i++) { buffer[ret++] = '0'; } buffer[ret] = 0; } + ret = ReplaceNegativeSign(buffer, ret, negativeSign); ret = ReplaceDecimalSeparator(buffer, ret, decimalSeparator); } @@ -648,6 +789,152 @@ int Library_corlib_native_System_Number::Format_N( return ret; } +int Library_corlib_native_System_Number::Format_E(char *buffer, CLR_RT_HeapBlock *value, int precision, char formatChar) +{ + int ret = -1; + + if (precision == -1) + { + // default to 6 digits after the decimal point + precision = 6; + } + + int requestedPrecision = precision; + + // force extra precision to account for rounding errors + precision = requestedPrecision + 1; + + CLR_DataType dataType = value->DataType(); + + char formatStr[FORMAT_FMTSTR_BUFFER_SIZE]; + double copyValue = 0.0; + + // need to convert to double + switch (dataType) + { + case DATATYPE_I1: + copyValue = (double)value->NumericByRef().s1; + break; + case DATATYPE_U1: + copyValue = (double)value->NumericByRef().u1; + break; + case DATATYPE_I2: + copyValue = (double)value->NumericByRef().s2; + break; + case DATATYPE_U2: + copyValue = (double)value->NumericByRef().u2; + break; + case DATATYPE_I4: + copyValue = (double)value->NumericByRef().s4; + break; + case DATATYPE_U4: + copyValue = (double)value->NumericByRef().u4; + break; + case DATATYPE_I8: + copyValue = (double)value->NumericByRef().s8; + break; + case DATATYPE_U8: + copyValue = (double)value->NumericByRef().u8; + break; + case DATATYPE_R4: + copyValue = (double)value->NumericByRef().r4; + break; + case DATATYPE_R8: + copyValue = (double)value->NumericByRef().r8; + break; + default: + break; + } + + snprintf(formatStr, FORMAT_FMTSTR_BUFFER_SIZE, "%%.%d%c", precision, formatChar); + + ret = (int)snprintf(buffer, FORMAT_RESULT_BUFFER_SIZE, formatStr, copyValue); + + if (ret > 0) + { + int exponent = 0; + + // find the exponent character, start with lower case + char *e = strchr(buffer, 'e'); + + if (!e) + { + // try upper case + e = strchr(buffer, 'E'); + } + + if (e) + { + // move past the exponent character + e++; + + // convert exponent to digits + exponent = atoi(e); + } + + int numDigits = 0; + int savedResultLength = ret; + + int dotIndex = GetDotIndex(buffer, ret); + + // if there is no dot, set the index to the end of the string + if (dotIndex == -1) + { + dotIndex = ret; + } + + // leave just the required amount of digits + if (requestedPrecision <= precision) + { + // find the first digit after the dot + for (int i = 0; i < ret; i++) + { + if (buffer[i] >= '0' && buffer[i] <= '9') + { + numDigits++; + + if (numDigits == precision) + { + ret = i + 1; + char first_lost_digit = buffer[ret]; + + if (first_lost_digit == '.' && (ret + 1) < savedResultLength) + { + first_lost_digit = buffer[ret + 1]; + } + + buffer[ret] = 0; + + if (first_lost_digit >= '5') + { + int savedRet = ret; + RoundUpNumStr(buffer, &ret); + + if (savedRet < ret) + { + dotIndex++; + } + } + break; + } + } + } + } + + // now the exponent + if (formatChar == 'e') + { + snprintf(&buffer[ret], FORMAT_RESULT_BUFFER_SIZE, "e%+.3d", exponent); + } + else + { + snprintf(&buffer[ret], FORMAT_RESULT_BUFFER_SIZE, "E%+.3d", exponent); + } + } + + return ret; +} + HRESULT Library_corlib_native_System_Number:: FormatNative___STATIC__STRING__OBJECT__BOOLEAN__STRING__STRING__STRING__STRING__SZARRAY_I4(CLR_RT_StackFrame &stack) { @@ -684,165 +971,13 @@ HRESULT Library_corlib_native_System_Number:: char formatChar; int precision; + if (!GetFormatSpec(format, isInteger, &formatChar, &precision)) { ret = format; } else { - - /* - It looks this could be the most appropriate place where everybody looks when wants to track the current - implementation. So I put here my toughts how this code could be modified without regression :) - - Create an nf project in VS. - Add the following class to it: - - public static class ToStringAsserts - { - public static void Run() - { - //AssertToConsole("(123.456).ToString(\"C\"))","",(123.456).ToString("C")); - //AssertToConsole("(-123.456).ToString(\"C\"))","",(-123.456).ToString("C")); - //AssertToConsole("(123.456).ToString(\"C3\"))","",(123.456).ToString("C3")); - //AssertToConsole("(-123.456).ToString(\"C3\"))","",(-123.456).ToString("C3")); - AssertToConsole("(1).ToString(\"Da1x\")", "Da1x", (1).ToString("Da1x")); - AssertToConsole("(1).ToString(\"D\")", "1", (1).ToString("D")); - AssertToConsole("(-1).ToString(\"D\")", "-1", (-1).ToString("D")); - AssertToConsole("(1234).ToString(\"D\")", "1234", (1234).ToString("D")); - AssertToConsole("(-1234).ToString(\"D\")", "-1234", (-1234).ToString("D")); - AssertToConsole("(1234).ToString(\"D6\")", "001234", (1234).ToString("D6")); - AssertToConsole("(-1234).ToString(\"D6\")", "-001234", (-1234).ToString("D6")); - AssertToConsole("(Int32.MaxValue).ToString(\"D\")", "2147483647", (Int32.MaxValue).ToString("D")); - AssertToConsole("(Int32.MinValue).ToString(\"D\")", "-2147483648", (Int32.MinValue).ToString("D")); - AssertToConsole("(Int32.MaxValue).ToString(\"D21\")", "000000000002147483647", - (Int32.MaxValue).ToString("D21")); AssertToConsole("(Int32.MinValue).ToString(\"D21\")", - "-000000000002147483648", (Int32.MinValue).ToString("D21")); - AssertToConsole("(Int64.MaxValue).ToString(\"D\")", "9223372036854775807", - (Int64.MaxValue).ToString("D")); AssertToConsole("(Int64.MinValue).ToString(\"D\")", "-9223372036854775808", - (Int64.MinValue).ToString("D")); AssertToConsole("(Int64.MaxValue).ToString(\"D21\")", - "009223372036854775807", (Int64.MaxValue).ToString("D21")); - AssertToConsole("(Int64.MinValue).ToString(\"D21\")", "-009223372036854775808", - (Int64.MinValue).ToString("D21")); AssertToConsole("(Int32.MaxValue+100).ToString(\"D\")", "2147483747", - ((Int64)Int32.MaxValue + 100).ToString("D")); AssertToConsole("(Int32.MinValue-100).ToString(\"D\")", - "-2147483748", ((Int64)Int32.MinValue - 100).ToString("D")); - AssertToConsole("(Int32.MaxValue+100).ToString(\"D21\")", "000000000002147483747", - ((Int64)Int32.MaxValue + 100).ToString("D21")); AssertToConsole("(Int32.MinValue-100).ToString(\"D21\")", - "-000000000002147483748", ((Int64)Int32.MinValue - 100).ToString("D21")); - //AssertToConsole("(1052.0329112756).ToString(\"E\"))","",(1052.0329112756).ToString("E")); - //AssertToConsole("(-1052.0329112756).ToString(\"E\"))","",(-1052.0329112756).ToString("E")); - //AssertToConsole("(1052.0329112756).ToString(\"E2\"))","",(1052.0329112756).ToString("E2")); - //AssertToConsole("(-1052.0329112756).ToString(\"E2\"))","",(-1052.0329112756).ToString("E2")); - //AssertToConsole("(1052.0329112756).ToString(\"e\"))","",(1052.0329112756).ToString("e")); - //AssertToConsole("(-1052.0329112756).ToString(\"e\"))","",(-1052.0329112756).ToString("e")); - //AssertToConsole("(1052.0329112756).ToString(\"e2\"))","",(1052.0329112756).ToString("e2")); - //AssertToConsole("(-1052.0329112756).ToString(\"e2\"))","",(-1052.0329112756).ToString("e2")); - AssertToConsole("(1234.567).ToString(\"F\"))", "1234.57", (1234.567).ToString("F")); - AssertToConsole("(-1234.567).ToString(\"F\"))", "-1234.57", (-1234.567).ToString("F")); - AssertToConsole("(1234.567).ToString(\"F0\"))", "1235", (1234.567).ToString("F0")); - AssertToConsole("(-1234.567).ToString(\"F0\"))", "-1235", (-1234.567).ToString("F0")); - AssertToConsole("(1234).ToString(\"F1\"))", "1234.0", (1234).ToString("F1")); - AssertToConsole("(-1234).ToString(\"F1\"))", "-1234.0", (-1234).ToString("F1")); - AssertToConsole("(1234.56).ToString(\"F4\"))", "1234.5600", (1234.56).ToString("F4")); - AssertToConsole("(-1234.56).ToString(\"F4\"))", "-1234.5600", (-1234.56).ToString("F4")); - AssertToConsole("(1234.56).ToString(\"F1\"))", "1234.6", (1234.56).ToString("F1")); - AssertToConsole("(-1234.56).ToString(\"F1\"))", "-1234.6", (-1234.56).ToString("F1")); - AssertToConsole("(1234.0056).ToString(\"F1\"))", "1234.0", (1234.0056).ToString("F1")); - AssertToConsole("(-1234.0056).ToString(\"F1\"))", "-1234.0", (-1234.0056).ToString("F1")); - AssertToConsole("(1).ToString()", "1", (1).ToString()); - AssertToConsole("(1).ToString(null)", "1", (1).ToString((string)null)); - AssertToConsole("(1).ToString(String.Empty)", "1", (1).ToString(String.Empty)); - AssertToConsole("(1234.567).ToString())", "1234.567", (1234.567).ToString()); - AssertToConsole("(123.456).ToString(\"G\"))", "123.456", (123.456).ToString("G")); - AssertToConsole("(-123.456).ToString(\"G\"))", "-123.456", (-123.456).ToString("G")); - AssertToConsole("(123.4546).ToString(\"G2\"))", "1.2E+02", (123.4546).ToString("G2")); - AssertToConsole("(-123.4546).ToString(\"G2\"))", "-1.2E+02", (-123.4546).ToString("G2")); - AssertToConsole("(123.4546).ToString(\"G4\"))", "123.5", (123.4546).ToString("G4")); - AssertToConsole("(-123.4546).ToString(\"G4\"))", "-123.5", (-123.4546).ToString("G4")); - AssertToConsole("(123.4546).ToString(\"G10\"))", "123.4546", (123.4546).ToString("G10")); - AssertToConsole("(-123.4546).ToString(\"G10\"))", "-123.4546", (-123.4546).ToString("G10")); - AssertToConsole("(99.9999).ToString(\"G4\"))", "100", (99.9999).ToString("G4")); - AssertToConsole("(-99.9999).ToString(\"G4\"))", "-100", (-99.9999).ToString("G4")); - AssertToConsole("(1234567890).ToString(\"G\"))", "1234567890", (1234567890).ToString("G")); - AssertToConsole("(-1234567890).ToString(\"G\"))", "-1234567890", (-1234567890).ToString("G")); - AssertToConsole("(1234567890).ToString(\"G4\"))", "1.235E+09", (1234567890).ToString("G4")); - AssertToConsole("(-1234567890).ToString(\"G4\"))", "-1.235E+09", (-1234567890).ToString("G4")); - AssertToConsole("(9876543210).ToString(\"G4\"))", "9.877E+09", (9876543210).ToString("G4")); - AssertToConsole("(-9876543210).ToString(\"G4\"))", "-9.877E+09", (-9876543210).ToString("G4")); - AssertToConsole("(1234567890).ToString(\"G15\"))", "1234567890", (1234567890).ToString("G15")); - AssertToConsole("(-1234567890).ToString(\"G15\"))", "-1234567890", (-1234567890).ToString("G15")); - AssertToConsole("(1234.567).ToString(\"N\"))", "1,234.57", (1234.567).ToString("N")); - AssertToConsole("(-1234.567).ToString(\"N\"))", "-1,234.57", (-1234.567).ToString("N")); - AssertToConsole("(0).ToString(\"N0\"))", "0", (0).ToString("N0")); - AssertToConsole("(1234).ToString(\"N0\"))", "1,234", (1234).ToString("N0")); - AssertToConsole("(-1234).ToString(\"N0\"))", "-1,234", (-1234).ToString("N0")); - AssertToConsole("(12).ToString(\"N1\"))", "12.0", (12).ToString("N1")); - AssertToConsole("(-12).ToString(\"N1\"))", "-12.0", (-12).ToString("N1")); - AssertToConsole("(1234).ToString(\"N1\"))", "1,234.0", (1234).ToString("N1")); - AssertToConsole("(-1234).ToString(\"N1\"))", "-1,234.0", (-1234).ToString("N1")); - AssertToConsole("(1234.56).ToString(\"N3\"))", "1,234.560", (1234.56).ToString("N3")); - AssertToConsole("(-1234.56).ToString(\"N3\"))", "-1,234.560", (-1234.56).ToString("N3")); - AssertToConsole("(34561234.56).ToString(\"N3\"))", "34,561,234.560", (34561234.56).ToString("N3")); - AssertToConsole("(-34561234.56).ToString(\"N3\"))", "-34,561,234.560", (-34561234.56).ToString("N3")); - //AssertToConsole("(1).ToString(\"P\"))","",(1).ToString("P")); - //AssertToConsole("(-0.39678).ToString(\"P\"))","",(-0.39678).ToString("P")); - //AssertToConsole("(123456789.12345678).ToString(\"R\"))","",(123456789.12345678).ToString("R")); - //AssertToConsole("(-123456789.12345678).ToString(\"R\"))","",(-123456789.12345678).ToString("R")); - AssertToConsole("(255).ToString(\"X\"))", "FF", (255).ToString("X")); - AssertToConsole("((Int32)1).ToString(\"X\"))", "1", ((Int32)1).ToString("X")); - AssertToConsole("((Int32)(-1)).ToString(\"x\"))", "ffffffff", ((Int32)(-1)).ToString("x")); - AssertToConsole("((byte)1).ToString(\"x\"))", "1", (unchecked((byte)1)).ToString("x")); - AssertToConsole("((byte)(-1)).ToString(\"x\"))", "ff", (unchecked((byte)(-1))).ToString("x")); - AssertToConsole("((short)1).ToString(\"x\"))", "1", ((short)1).ToString("x")); - AssertToConsole("((short)1).ToString(\"x2\"))", "01", ((short)1).ToString("x2")); - AssertToConsole("((short)(-1)).ToString(\"x\"))", "ffff", ((short)(-1)).ToString("x")); - AssertToConsole("(255).ToString(\"x4\"))", "00ff", (255).ToString("x4")); - AssertToConsole("((Int32)(-1)).ToString(\"X4\"))", "FFFFFFFF", ((Int32)(-1)).ToString("X4")); - AssertToConsole("(Int64.MaxValue-10).ToString(\"x\"))", "7ffffffffffffff5", (Int64.MaxValue - - 10).ToString("x")); AssertToConsole("((Int64)10).ToString(\"x\"))", "a", ((Int64)10).ToString("x")); - AssertToConsole("((Int64)10).ToString(\"x5\"))", "0000a", ((Int64)10).ToString("x5")); - } - - private static void AssertToConsole(string lbl, string expected, string str) - { - if (str != expected) - { - Debug.WriteLine($"BAD: {lbl} expected: {expected} found: {str}"); - } - else - { - Debug.WriteLine($" OK: {lbl} expected: {expected}"); - } - } - } - - As you can see all the implemented formatters and some of their interesting deviances have a test case there. - Feel free to add others which contain a bug case, etc. - DONT FORGET TO MODIFY THIS COMMENT WITH UP-TO-DATE VERSION! - - From you Main() call this class: - ToStringAsserts.Run(); - - Add a second old-school (running on "official" .net environment, like a Windows Console app) project to your - solution. Call from it's main() the test class as above. Execute this second project. You will see how the - official implementation formats the various things. Adjust the "expected" strings to reflect the received - output. E.g. if you want to check how we format (255).ToString("X") then add the following line: - - AssertToConsole("(255).ToString(\"X\"))", "dunnoyet", (255).ToString("X")); - - Execute the old-school project and you will see this line: - BAD: (255).ToString("X")) expected: dunnoyet found: FF - - Now replace the "dunnoyet" with "FF" and the test case ready. - AGAIN: DONT FORGET TO MODIFY THIS COMMENT WITH UP-TO-DATE VERSION! - - Now execute the nf project and check what nanoCLR formats for you. - Implement, fix, etc. - But always check your test project results in OK on all lines! - - Thats all folks :) - */ - char result[FORMAT_RESULT_BUFFER_SIZE]; int resultLength; @@ -852,14 +987,17 @@ HRESULT Library_corlib_native_System_Number:: case 'G': resultLength = Format_G(result, value, formatChar, precision, negativeSign, numberDecimalSeparator); break; + case 'x': case 'X': resultLength = Format_X(result, value, formatChar, precision); break; + case 'f': case 'F': resultLength = Format_F(result, value, precision, negativeSign, numberDecimalSeparator); break; + case 'n': case 'N': resultLength = Format_N( @@ -871,10 +1009,17 @@ HRESULT Library_corlib_native_System_Number:: numberGroupSeparator, numberGroupSizes); break; + case 'd': case 'D': resultLength = Format_D(result, value, precision, negativeSign, numberDecimalSeparator); break; + + case 'e': + case 'E': + resultLength = Format_E(result, value, precision, formatChar); + break; + default: NANOCLR_SET_AND_LEAVE(stack.NotImplementedStub()); } diff --git a/src/CLR/Core/CLR_RT_HeapBlock.cpp b/src/CLR/Core/CLR_RT_HeapBlock.cpp index d18f948621..8fa3076abd 100644 --- a/src/CLR/Core/CLR_RT_HeapBlock.cpp +++ b/src/CLR/Core/CLR_RT_HeapBlock.cpp @@ -307,6 +307,7 @@ HRESULT CLR_RT_HeapBlock::SetObjectCls(const CLR_RT_TypeDef_Index &cls) } m_data.objectHeader.cls = cls; + m_data.objectHeader.lock = NULL; NANOCLR_NOCLEANUP(); @@ -1238,154 +1239,152 @@ bool CLR_RT_HeapBlock::ObjectsEqual( CLR_DataType leftDataType = pArgLeft.DataType(); CLR_DataType rightDataType = pArgRight.DataType(); - if (leftDataType == rightDataType) + switch (leftDataType) { - switch (leftDataType) - { - case DATATYPE_VALUETYPE: - if (pArgLeft.ObjectCls().m_data == pArgRight.ObjectCls().m_data) - { - const CLR_RT_HeapBlock *objLeft = &pArgLeft; - const CLR_RT_HeapBlock *objRight = &pArgRight; - CLR_UINT32 num = pArgLeft.DataSize(); - - while (--num) - { - if (ObjectsEqual(*++objLeft, *++objRight, false) == false) - return false; - } + case DATATYPE_VALUETYPE: + if (pArgLeft.ObjectCls().m_data == pArgRight.ObjectCls().m_data) + { + const CLR_RT_HeapBlock *objLeft = &pArgLeft; + const CLR_RT_HeapBlock *objRight = &pArgRight; + CLR_UINT32 num = pArgLeft.DataSize(); - return true; + while (--num) + { + if (ObjectsEqual(*++objLeft, *++objRight, false) == false) + return false; } - break; + + return true; + } + break; #if defined(NANOCLR_APPDOMAINS) - case DATATYPE_TRANSPARENT_PROXY: + case DATATYPE_TRANSPARENT_PROXY: #endif - case DATATYPE_OBJECT: + case DATATYPE_OBJECT: + { + CLR_RT_HeapBlock *objLeft = pArgLeft.Dereference(); + CLR_RT_HeapBlock *objRight = pArgRight.Dereference(); + + if (objLeft == objRight) { - CLR_RT_HeapBlock *objLeft = pArgLeft.Dereference(); - CLR_RT_HeapBlock *objRight = pArgRight.Dereference(); + return true; + } - if (objLeft == objRight) + if (objLeft && objRight) + { + if (!fSameReference || (objLeft->DataType() == DATATYPE_REFLECTION)) { - return true; + return ObjectsEqual(*objLeft, *objRight, false); } + } + } + break; + + case DATATYPE_SZARRAY: + if (fSameReference == false) + { + _ASSERTE(false); // can this code path ever be executed? - if (objLeft && objRight) + CLR_RT_HeapBlock_Array *objLeft = (CLR_RT_HeapBlock_Array *)&pArgLeft; + CLR_RT_HeapBlock_Array *objRight = (CLR_RT_HeapBlock_Array *)&pArgRight; + + if (objLeft->m_numOfElements == objRight->m_numOfElements && + objLeft->m_sizeOfElement == objRight->m_sizeOfElement && + objLeft->m_typeOfElement == objRight->m_typeOfElement) { - if (!fSameReference || (objLeft->DataType() == DATATYPE_REFLECTION)) + if (!objLeft->m_fReference) { - return ObjectsEqual(*objLeft, *objRight, false); + if (memcmp( + objLeft->GetFirstElement(), + objRight->GetFirstElement(), + objLeft->m_numOfElements * objLeft->m_sizeOfElement) == 0) + { + return true; + } } } } break; - case DATATYPE_SZARRAY: - if (fSameReference == false) + case DATATYPE_REFLECTION: + if (pArgLeft.SameHeader(pArgRight)) + { + return true; + } + break; + + case DATATYPE_STRING: + return Compare_Values(pArgLeft, pArgRight, false) == 0; + break; + + case DATATYPE_BYREF: + if (rightDataType == DATATYPE_OBJECT) + { + // this is to handle the special case for calls to callvirt with constrained type + // namely with Objects, ValueType and Enum. + // https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.constrained?view=net-6.0 + + CLR_RT_HeapBlock *leftObj = pArgLeft.Dereference(); + CLR_RT_HeapBlock *rightObj = pArgRight.Dereference(); + + if (rightObj->DataType() == DATATYPE_VALUETYPE) { - _ASSERTE(false); // can this code path ever be executed? + CLR_RT_TypeDef_Instance inst; + CLR_RT_HeapBlock *obj = NULL; - CLR_RT_HeapBlock_Array *objLeft = (CLR_RT_HeapBlock_Array *)&pArgLeft; - CLR_RT_HeapBlock_Array *objRight = (CLR_RT_HeapBlock_Array *)&pArgRight; + if (!inst.InitializeFromIndex(rightObj->ObjectCls())) + { + } - if (objLeft->m_numOfElements == objRight->m_numOfElements && - objLeft->m_sizeOfElement == objRight->m_sizeOfElement && - objLeft->m_typeOfElement == objRight->m_typeOfElement) + if (inst.m_target->dataType != DATATYPE_VALUETYPE) { - if (!objLeft->m_fReference) - { - if (memcmp( - objLeft->GetFirstElement(), - objRight->GetFirstElement(), - objLeft->m_numOfElements * objLeft->m_sizeOfElement) == 0) - { - return true; - } - } + // boxed primitive or enum type + obj = &rightObj[1]; + } + else + { + // boxed value type + obj = rightObj; } - } - break; - case DATATYPE_REFLECTION: - if (pArgLeft.SameHeader(pArgRight)) - { - return true; + return ObjectsEqual(*leftObj, *obj, false); } - break; - - case DATATYPE_STRING: - return Compare_Values(pArgLeft, pArgRight, false) == 0; - break; - - default: - if (fSameReference == false) + else { - const CLR_RT_DataTypeLookup &dtl = c_CLR_RT_DataTypeLookup[pArgLeft.DataType()]; - - if ((dtl.m_flags & CLR_RT_DataTypeLookup::c_Reference) == 0) + if (rightObj == NULL) { - CLR_UINT32 size = (dtl.m_sizeInBits + 7) / 8; - - if (memcmp(&pArgLeft.DataByRefConst(), &pArgRight.DataByRefConst(), size) == 0) - { - return true; - } + return false; + } + else + { + return ObjectsEqual(*leftObj, *rightObj, false); } } - break; - } - } - else - { - if ((leftDataType == DATATYPE_BYREF && rightDataType == DATATYPE_OBJECT)) - { - // this is to handle the special case for calls to callvirt with constrained type - // namely with Objects, ValueType and Enum. - // https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.constrained?view=net-6.0 + } + break; - CLR_RT_HeapBlock *leftObj = pArgLeft.Dereference(); - CLR_RT_HeapBlock *rightObj = pArgRight.Dereference(); + default: - if (rightObj->DataType() == DATATYPE_VALUETYPE) + if ((leftDataType == rightDataType) && fSameReference == false) { - CLR_RT_TypeDef_Instance inst; - CLR_RT_HeapBlock *obj = NULL; + const CLR_RT_DataTypeLookup &dtl = c_CLR_RT_DataTypeLookup[pArgLeft.DataType()]; - if (!inst.InitializeFromIndex(rightObj->ObjectCls())) + if ((dtl.m_flags & CLR_RT_DataTypeLookup::c_Reference) == 0) { - } + CLR_UINT32 size = (dtl.m_sizeInBits + 7) / 8; - if (inst.m_target->dataType != DATATYPE_VALUETYPE) - { - // boxed primitive or enum type - obj = &rightObj[1]; - } - else - { - // boxed value type - obj = rightObj; + if (memcmp(&pArgLeft.DataByRefConst(), &pArgRight.DataByRefConst(), size) == 0) + { + return true; + } } - - return ObjectsEqual(*leftObj, *obj, false); } else { - if (rightObj == NULL) - { - return false; - } - else - { - return ObjectsEqual(*leftObj, *rightObj, false); - } + _ASSERTE(false); } - } - else - { - _ASSERTE(false); - } + break; } return false; @@ -1770,10 +1769,12 @@ CLR_INT32 CLR_RT_HeapBlock::Compare_Values(const CLR_RT_HeapBlock &left, const C } else { +#if !defined(BUILD_RTM) CLR_Debug::Printf( "\r\n\r\nRUNTIME ERROR: comparing two values of different size: %d vs. %d!!!\r\n\r\n\r\n", leftDataType, rightDataType); +#endif // BUILD_RTM #if defined(NANOCLR_PROFILE_NEW) g_CLR_PRF_Profiler.DumpHeap(); #endif diff --git a/src/CLR/Core/CLR_RT_HeapBlock_String.cpp b/src/CLR/Core/CLR_RT_HeapBlock_String.cpp index e0638e84ed..84fda56ce3 100644 --- a/src/CLR/Core/CLR_RT_HeapBlock_String.cpp +++ b/src/CLR/Core/CLR_RT_HeapBlock_String.cpp @@ -75,11 +75,9 @@ HRESULT CLR_RT_HeapBlock_String::CreateInstance( CLR_RT_HeapBlock& reference, co reference.SetObjectReference( str ); #if defined(NANOCLR_NO_ASSEMBLY_STRINGS) - (void)szText; - (void)assm; - NANOCLR_CHECK_HRESULT( CLR_RT_HeapBlock_String::CreateInstance( reference, szText ) ); -#else + NANOCLR_CHECK_HRESULT(CLR_RT_HeapBlock_String::CreateInstance(reference, szText)); +#else str->SetStringText( szText, assm ); #endif diff --git a/src/CLR/Core/CLR_RT_HeapCluster.cpp b/src/CLR/Core/CLR_RT_HeapCluster.cpp index 8b87ad95f0..16e7bb4274 100644 --- a/src/CLR/Core/CLR_RT_HeapCluster.cpp +++ b/src/CLR/Core/CLR_RT_HeapCluster.cpp @@ -7,36 +7,32 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// -void CLR_RT_HeapCluster::HeapCluster_Initialize( CLR_UINT32 size, CLR_UINT32 blockSize ) +void CLR_RT_HeapCluster::HeapCluster_Initialize(CLR_UINT32 size, CLR_UINT32 blockSize) { NATIVE_PROFILE_CLR_CORE(); GenericNode_Initialize(); size = (size - sizeof(*this)) / sizeof(CLR_RT_HeapBlock); - m_freeList.DblLinkedList_Initialize(); // CLR_RT_DblLinkedList m_freeList; - m_payloadStart = (CLR_RT_HeapBlock_Node*)&this[ 1 ]; // CLR_RT_HeapBlock_Node* m_payloadStart; - m_payloadEnd = &m_payloadStart[ size ]; // CLR_RT_HeapBlock_Node* m_payloadEnd; + m_freeList.DblLinkedList_Initialize(); // CLR_RT_DblLinkedList m_freeList; + m_payloadStart = (CLR_RT_HeapBlock_Node *)&this[1]; // CLR_RT_HeapBlock_Node* m_payloadStart; + m_payloadEnd = &m_payloadStart[size]; // CLR_RT_HeapBlock_Node* m_payloadEnd; - // - // Scan memory looking for possible objects to salvage. This method returns false if HeapPersistence is stubbed - // which requires us to set up the free list. - // - // used to be CLR_RT_HeapBlock_WeakReference::PrepareForRecovery( CLR_RT_HeapBlock_Node* ptr, CLR_RT_HeapBlock_Node* end, CLR_UINT32 blockSize ) - - CLR_RT_HeapBlock_Node* ptr = m_payloadStart; - CLR_RT_HeapBlock_Node* end = m_payloadEnd; + // Scan memory looking for possible objects to salvage + CLR_RT_HeapBlock_Node *ptr = m_payloadStart; + CLR_RT_HeapBlock_Node *end = m_payloadEnd; - while(ptr < end) + while (ptr < end) { - if(ptr->DataType() == DATATYPE_WEAKCLASS) + if (ptr->DataType() == DATATYPE_WEAKCLASS) { - CLR_RT_HeapBlock_WeakReference* weak = (CLR_RT_HeapBlock_WeakReference*)ptr; + CLR_RT_HeapBlock_WeakReference *weak = (CLR_RT_HeapBlock_WeakReference *)ptr; - if(weak->DataSize() == CONVERTFROMSIZETOHEAPBLOCKS(sizeof(*weak)) && weak->m_targetSerialized != NULL && (weak->m_identity.m_flags & CLR_RT_HeapBlock_WeakReference::WR_SurviveBoot)) + if (weak->DataSize() == CONVERTFROMSIZETOHEAPBLOCKS(sizeof(*weak)) && weak->m_targetSerialized != NULL && + (weak->m_identity.m_flags & CLR_RT_HeapBlock_WeakReference::WR_SurviveBoot)) { - weak->SetNext( NULL ); - weak->SetPrev( NULL ); + weak->SetNext(NULL); + weak->SetPrev(NULL); weak->m_identity.m_flags &= ~CLR_RT_HeapBlock_WeakReference::WR_Persisted; @@ -48,15 +44,15 @@ void CLR_RT_HeapCluster::HeapCluster_Initialize( CLR_UINT32 size, CLR_UINT32 blo continue; } } - else if(ptr->DataType() == DATATYPE_SZARRAY) + else if (ptr->DataType() == DATATYPE_SZARRAY) { - CLR_RT_HeapBlock_Array* array = (CLR_RT_HeapBlock_Array*)ptr; + CLR_RT_HeapBlock_Array *array = (CLR_RT_HeapBlock_Array *)ptr; - if(array->m_typeOfElement == DATATYPE_U1 && array->m_fReference == 0) + if (array->m_typeOfElement == DATATYPE_U1 && array->m_fReference == 0) { CLR_UINT32 tot = sizeof(*array) + array->m_sizeOfElement * array->m_numOfElements; - if(array->DataSize() == CONVERTFROMSIZETOHEAPBLOCKS(tot) && (ptr + ptr->DataSize()) <= end) + if (array->DataSize() == CONVERTFROMSIZETOHEAPBLOCKS(tot) && (ptr + ptr->DataSize()) <= end) { array->MarkAlive(); @@ -66,23 +62,12 @@ void CLR_RT_HeapCluster::HeapCluster_Initialize( CLR_UINT32 size, CLR_UINT32 blo } } - if((unsigned int)(ptr + blockSize) > (unsigned int)end) + if ((unsigned int)(ptr + blockSize) > (unsigned int)end) { blockSize = (CLR_UINT32)(end - ptr); } - ptr->SetDataId( CLR_RT_HEAPBLOCK_RAW_ID(DATATYPE_FREEBLOCK,0,blockSize) ); - ptr += blockSize; - } - - while(ptr < m_payloadEnd) - { - if((unsigned int)(ptr + blockSize) > (unsigned int)m_payloadEnd) - { - blockSize = (CLR_UINT32)(m_payloadEnd - ptr); - } - - ptr->SetDataId( CLR_RT_HEAPBLOCK_RAW_ID(DATATYPE_FREEBLOCK,0,blockSize) ); + ptr->SetDataId(CLR_RT_HEAPBLOCK_RAW_ID(DATATYPE_FREEBLOCK, 0, blockSize)); ptr += blockSize; } @@ -91,21 +76,21 @@ void CLR_RT_HeapCluster::HeapCluster_Initialize( CLR_UINT32 size, CLR_UINT32 blo m_freeList.ValidateList(); } -CLR_RT_HeapBlock* CLR_RT_HeapCluster::ExtractBlocks( CLR_UINT32 dataType, CLR_UINT32 flags, CLR_UINT32 length ) +CLR_RT_HeapBlock *CLR_RT_HeapCluster::ExtractBlocks(CLR_UINT32 dataType, CLR_UINT32 flags, CLR_UINT32 length) { NATIVE_PROFILE_CLR_CORE(); - CLR_RT_HeapBlock_Node* res = NULL; - CLR_UINT32 available = 0; + CLR_RT_HeapBlock_Node *res = NULL; + CLR_UINT32 available = 0; m_freeList.ValidateList(); - if(flags & CLR_RT_HeapBlock::HB_Event) + if (flags & CLR_RT_HeapBlock::HB_Event) { - NANOCLR_FOREACH_NODE_BACKWARD(CLR_RT_HeapBlock_Node,ptr,m_freeList) + NANOCLR_FOREACH_NODE_BACKWARD(CLR_RT_HeapBlock_Node, ptr, m_freeList) { available = ptr->DataSize(); - if(available >= length) + if (available >= length) { res = ptr; break; @@ -115,11 +100,11 @@ CLR_RT_HeapBlock* CLR_RT_HeapCluster::ExtractBlocks( CLR_UINT32 dataType, CLR_UI } else { - NANOCLR_FOREACH_NODE(CLR_RT_HeapBlock_Node,ptr,m_freeList) + NANOCLR_FOREACH_NODE(CLR_RT_HeapBlock_Node, ptr, m_freeList) { available = ptr->DataSize(); - if(available >= length) + if (available >= length) { res = ptr; break; @@ -128,35 +113,35 @@ CLR_RT_HeapBlock* CLR_RT_HeapCluster::ExtractBlocks( CLR_UINT32 dataType, CLR_UI NANOCLR_FOREACH_NODE_END(); } - if(res) + if (res) { - CLR_RT_HeapBlock_Node* next = res->Next(); - CLR_RT_HeapBlock_Node* prev = res->Prev(); + CLR_RT_HeapBlock_Node *next = res->Next(); + CLR_RT_HeapBlock_Node *prev = res->Prev(); available -= length; - if(available != 0) + if (available != 0) { - if(flags & CLR_RT_HeapBlock::HB_Event) + if (flags & CLR_RT_HeapBlock::HB_Event) { - res->SetDataId( CLR_RT_HEAPBLOCK_RAW_ID(DATATYPE_FREEBLOCK,CLR_RT_HeapBlock::HB_Pinned,available) ); + res->SetDataId(CLR_RT_HEAPBLOCK_RAW_ID(DATATYPE_FREEBLOCK, CLR_RT_HeapBlock::HB_Pinned, available)); res += available; } else { - CLR_RT_HeapBlock_Node* ptr = &res[ length ]; + CLR_RT_HeapBlock_Node *ptr = &res[length]; // // Relink to the new free block. // - ptr->SetDataId( CLR_RT_HEAPBLOCK_RAW_ID(DATATYPE_FREEBLOCK,CLR_RT_HeapBlock::HB_Pinned,available) ); + ptr->SetDataId(CLR_RT_HEAPBLOCK_RAW_ID(DATATYPE_FREEBLOCK, CLR_RT_HeapBlock::HB_Pinned, available)); - ptr->SetNext( next ); - ptr->SetPrev( prev ); + ptr->SetNext(next); + ptr->SetPrev(prev); - prev->SetNext( ptr ); - next->SetPrev( ptr ); + prev->SetNext(ptr); + next->SetPrev(ptr); } } else @@ -164,19 +149,19 @@ CLR_RT_HeapBlock* CLR_RT_HeapCluster::ExtractBlocks( CLR_UINT32 dataType, CLR_UI // // Unlink the whole block. // - prev->SetNext( next ); - next->SetPrev( prev ); + prev->SetNext(next); + next->SetPrev(prev); } - res->SetDataId( CLR_RT_HEAPBLOCK_RAW_ID(dataType,flags,length) ); + res->SetDataId(CLR_RT_HEAPBLOCK_RAW_ID(dataType, flags, length)); - if(flags & CLR_RT_HeapBlock::HB_InitializeToZero) + if (flags & CLR_RT_HeapBlock::HB_InitializeToZero) { res->InitializeToZero(); } else { - res->Debug_ClearBlock( 0xCB ); + res->Debug_ClearBlock(0xCB); } } @@ -191,103 +176,119 @@ void CLR_RT_HeapCluster::RecoverFromGC() { NATIVE_PROFILE_CLR_CORE(); - CLR_RT_HeapBlock_Node* ptr = m_payloadStart; - CLR_RT_HeapBlock_Node* end = m_payloadEnd; + CLR_RT_HeapBlock_Node *ptr = m_payloadStart; + CLR_RT_HeapBlock_Node *end = m_payloadEnd; // // Open the free list. // - CLR_RT_HeapBlock_Node* last = m_freeList.Head(); last->SetPrev( NULL ); + CLR_RT_HeapBlock_Node *last = m_freeList.Head(); + last->SetPrev(NULL); - while(ptr < end) + while (ptr < end) { - ValidateBlock( ptr ); + ValidateBlock(ptr); - if(ptr->IsAlive() == false) + if (ptr->IsAlive() == false) { - CLR_RT_HeapBlock_Node* next = ptr; - CLR_UINT32 lenTot = 0; + CLR_RT_HeapBlock_Node *next = ptr; + CLR_UINT32 lenTot = 0; do { - ValidateBlock( next ); - -#if defined(NANOCLR_PROFILE_NEW_ALLOCATIONS) - g_CLR_PRF_Profiler.TrackObjectDeletion( next ); -#endif + ValidateBlock(next); NANOCLR_CHECK_EARLY_COLLECTION(next); int len = next->DataSize(); - next += len; + // length of the block can not be 0, so something very wrong happened + _ASSERTE(len > 0); + + next += len; lenTot += len; - } while(next < end && next->IsAlive() == false); + } while (next < end && next->IsAlive() == false); - ptr->SetDataId( CLR_RT_HEAPBLOCK_RAW_ID(DATATYPE_FREEBLOCK,CLR_RT_HeapBlock::HB_Pinned,lenTot) ); +#if defined(NANOCLR_PROFILE_NEW_ALLOCATIONS) + g_CLR_PRF_Profiler.TrackObjectDeletion(ptr); +#endif + ptr->SetDataId(CLR_RT_HEAPBLOCK_RAW_ID(DATATYPE_FREEBLOCK, CLR_RT_HeapBlock::HB_Pinned, lenTot)); // // Link to the free list. // - last->SetNext( ptr ); - ptr ->SetPrev( last ); + last->SetNext(ptr); + ptr->SetPrev(last); last = ptr; - ptr->Debug_ClearBlock( 0xDF ); + ptr->Debug_ClearBlock(0xDF); ptr = next; } else { - if(ptr->IsEvent() == false) ptr->MarkDead(); + if (ptr->IsEvent() == false) + { + ptr->MarkDead(); + } + + int len = ptr->DataSize(); + + // length of the block can not be 0, so something very wrong happened + _ASSERTE(len > 0); - ptr += ptr->DataSize(); + ptr += len; } } // // Close the free list. // - last ->SetNext( m_freeList.Tail() ); - m_freeList.Tail()->SetPrev( last ); - m_freeList.Tail()->SetNext( NULL ); + last->SetNext(m_freeList.Tail()); + m_freeList.Tail()->SetPrev(last); + m_freeList.Tail()->SetNext(NULL); } -CLR_RT_HeapBlock_Node* CLR_RT_HeapCluster::InsertInOrder( CLR_RT_HeapBlock_Node* node, CLR_UINT32 size ) +CLR_RT_HeapBlock_Node *CLR_RT_HeapCluster::InsertInOrder(CLR_RT_HeapBlock_Node *node, CLR_UINT32 size) { NATIVE_PROFILE_CLR_CORE(); - CLR_RT_HeapBlock_Node* ptr; + CLR_RT_HeapBlock_Node *ptr; - NANOCLR_FOREACH_NODE__NODECL(CLR_RT_HeapBlock_Node,ptr,m_freeList) + NANOCLR_FOREACH_NODE__NODECL(CLR_RT_HeapBlock_Node, ptr, m_freeList) { - if(ptr > node) break; + if (ptr > node) + break; } NANOCLR_FOREACH_NODE_END(); - node->ClearData(); m_freeList.InsertBeforeNode( ptr, node ); + node->ClearData(); + m_freeList.InsertBeforeNode(ptr, node); // // Try to coalesce with the following free block. // ptr = node->Next(); - if(ptr->Next() && (node + size) == ptr) + if (ptr->Next() && (node + size) == ptr) { - size += ptr->DataSize(); ptr->Unlink(); + size += ptr->DataSize(); + ptr->Unlink(); } // // Try to coalesce with the preceding free block. // ptr = node->Prev(); - if(ptr->Prev() && (ptr + ptr->DataSize()) == node) + if (ptr->Prev() && (ptr + ptr->DataSize()) == node) { - size += ptr->DataSize(); node->Unlink(); node = ptr; + size += ptr->DataSize(); + node->Unlink(); + node = ptr; } - node->SetDataId( CLR_RT_HEAPBLOCK_RAW_ID(DATATYPE_FREEBLOCK,CLR_RT_HeapBlock::HB_Pinned,size ) ); - node->Debug_ClearBlock( 0xCF ); + node->SetDataId(CLR_RT_HEAPBLOCK_RAW_ID(DATATYPE_FREEBLOCK, CLR_RT_HeapBlock::HB_Pinned, size)); + node->Debug_ClearBlock(0xCF); return node; } @@ -296,36 +297,58 @@ CLR_RT_HeapBlock_Node* CLR_RT_HeapCluster::InsertInOrder( CLR_RT_HeapBlock_Node* #if NANOCLR_VALIDATE_HEAP >= NANOCLR_VALIDATE_HEAP_1_HeapBlocksAndUnlink -void CLR_RT_HeapCluster::ValidateBlock( CLR_RT_HeapBlock* ptr ) +void CLR_RT_HeapCluster::ValidateBlock(CLR_RT_HeapBlock *ptr) { NATIVE_PROFILE_CLR_CORE(); - while(true) + while (true) { - if(ptr < m_payloadStart || ptr >= m_payloadEnd) + if (ptr < m_payloadStart || ptr >= m_payloadEnd) { - CLR_Debug::Printf( "Block beyond cluster limits: %08x [%08x : %08x-%08x]\r\n", (size_t)ptr, (size_t)this, (size_t)m_payloadStart, (size_t)m_payloadEnd ); + CLR_Debug::Printf( + "Block beyond cluster limits: %08x [%08x : %08x-%08x]\r\n", + (size_t)ptr, + (size_t)this, + (size_t)m_payloadStart, + (size_t)m_payloadEnd); break; } - if(ptr->DataType() >= DATATYPE_FIRST_INVALID) + if (ptr->DataType() >= DATATYPE_FIRST_INVALID) { - CLR_Debug::Printf( "Bad Block Type: %08x %02x [%08x : %08x-%08x]\r\n", (size_t)ptr, ptr->DataType(), (size_t)this, (size_t)m_payloadStart, (size_t)m_payloadEnd ); + CLR_Debug::Printf( + "Bad Block Type: %08x %02x [%08x : %08x-%08x]\r\n", + (size_t)ptr, + ptr->DataType(), + (size_t)this, + (size_t)m_payloadStart, + (size_t)m_payloadEnd); break; } - if(ptr->DataSize() == 0) + if (ptr->DataSize() == 0) { - CLR_Debug::Printf( "Bad Block null-size: %08x [%08x : %08x-%08x]\r\n", (size_t)ptr, (size_t)this, (size_t)m_payloadStart, (size_t)m_payloadEnd ); + CLR_Debug::Printf( + "Bad Block null-size: %08x [%08x : %08x-%08x]\r\n", + (size_t)ptr, + (size_t)this, + (size_t)m_payloadStart, + (size_t)m_payloadEnd); break; } - if(ptr + ptr->DataSize() > m_payloadEnd) + if (ptr + ptr->DataSize() > m_payloadEnd) { - CLR_Debug::Printf( "Bad Block size: %d %08x [%08x : %08x-%08x]\r\n", ptr->DataSize(), (size_t)ptr, (size_t)this, (size_t)m_payloadStart, (size_t)m_payloadEnd ); + CLR_Debug::Printf( + "Bad Block size: %d %08x [%08x : %08x-%08x]\r\n", + ptr->DataSize(), + (size_t)ptr, + (size_t)this, + (size_t)m_payloadStart, + (size_t)m_payloadEnd); break; } @@ -337,4 +360,3 @@ void CLR_RT_HeapCluster::ValidateBlock( CLR_RT_HeapBlock* ptr ) } #endif - diff --git a/src/CLR/Core/CLR_RT_Memory.cpp b/src/CLR/Core/CLR_RT_Memory.cpp index a64262515e..3412e74b00 100644 --- a/src/CLR/Core/CLR_RT_Memory.cpp +++ b/src/CLR/Core/CLR_RT_Memory.cpp @@ -13,7 +13,7 @@ static CLR_UINT32 s_TotalAllocated; CLR_RT_MemoryRange s_CLR_RT_Heap = {0, 0}; -static int s_PreHeapInitIndex = 0; +static size_t s_PreHeapInitIndex = 0; //////////////////////////////////////////////////////////// @@ -25,8 +25,8 @@ void CLR_RT_Memory::Reset() ::HeapLocation(s_CLR_RT_Heap.m_location, s_CLR_RT_Heap.m_size); // adjust GC thresholds - g_CLR_RT_GarbageCollector.c_memoryThreshold = s_CLR_RT_Heap.m_size * HEAP_SIZE_THRESHOLD_RATIO; - g_CLR_RT_GarbageCollector.c_memoryThreshold2 = s_CLR_RT_Heap.m_size * HEAP_SIZE_THRESHOLD_UPPER_RATIO; + g_CLR_RT_GarbageCollector.c_memoryThreshold = (CLR_UINT32)(s_CLR_RT_Heap.m_size * HEAP_SIZE_THRESHOLD_RATIO); + g_CLR_RT_GarbageCollector.c_memoryThreshold2 = (CLR_UINT32)(s_CLR_RT_Heap.m_size * HEAP_SIZE_THRESHOLD_UPPER_RATIO); #if defined(NANOCLR_TRACE_MALLOC) s_TotalAllocated = 0; diff --git a/src/CLR/Core/CLR_RT_RuntimeMemory.cpp b/src/CLR/Core/CLR_RT_RuntimeMemory.cpp index bc7937bef6..5d9f0ce59b 100644 --- a/src/CLR/Core/CLR_RT_RuntimeMemory.cpp +++ b/src/CLR/Core/CLR_RT_RuntimeMemory.cpp @@ -108,20 +108,20 @@ //--// -size_t LinkArraySize() +uint32_t LinkArraySize() { return (PLATFORM_DEPENDENT_ENTRY_SIZE + PLATFORM_DEPENDENT_HASH_TABLE_SIZE); } -size_t LinkMRUArraySize() +uint32_t LinkMRUArraySize() { return (PLATFORM_DEPENDENT_ENTRY_SIZE + 1); } -size_t PayloadArraySize() +uint32_t PayloadArraySize() { return PLATFORM_DEPENDENT_ENTRY_SIZE; } #ifndef NANOCLR_NO_IL_INLINE -size_t InlineBufferCount() +uint32_t InlineBufferCount() { return PLATFORM_DEPENDENT_INLINE_BUFFER_SIZE; } @@ -141,7 +141,7 @@ unsigned int //--// -size_t InterruptRecords() +uint32_t InterruptRecords() { return PLATFORM_DEPENDENT_INTERRUPT_RECORDS; } diff --git a/src/CLR/Core/Cache.cpp b/src/CLR/Core/Cache.cpp index 95707a2f63..53e7c0c3ba 100644 --- a/src/CLR/Core/Cache.cpp +++ b/src/CLR/Core/Cache.cpp @@ -449,7 +449,7 @@ void CLR_RT_EventCache::Append_Node(CLR_RT_HeapBlock *node) lst.m_blocks.LinkAtBack(ptr); #if defined(NANOCLR_PROFILE_NEW_ALLOCATIONS) - g_CLR_PRF_Profiler.TrackObjectDeletion(node); + g_CLR_PRF_Profiler.TrackObjectCreation(node); #endif } @@ -571,13 +571,28 @@ CLR_RT_HeapBlock *CLR_RT_EventCache::Extract_Node_Bytes(CLR_UINT32 dataType, CLR CLR_RT_HeapBlock *CLR_RT_EventCache::Extract_Node(CLR_UINT32 dataType, CLR_UINT32 flags, CLR_UINT32 blocks) { NATIVE_PROFILE_CLR_CORE(); + #if defined(NANOCLR_FORCE_GC_BEFORE_EVERY_ALLOCATION) return g_CLR_RT_ExecutionEngine.ExtractHeapBlocksForEvents(dataType, flags, blocks); #else - if (blocks > 0 && blocks < c_maxFastLists) - return Extract_Node_Fast(dataType, flags, blocks); + +#if !defined(BUILD_RTM) || defined(VIRTUAL_DEVICE) + if (g_CLR_RT_ExecutionEngine.m_fPerformGarbageCollection) + { + return g_CLR_RT_ExecutionEngine.ExtractHeapBlocksForEvents(dataType, flags, blocks); + } else - return Extract_Node_Slow(dataType, flags, blocks); +#endif + { + if (blocks > 0 && blocks < c_maxFastLists) + { + return Extract_Node_Fast(dataType, flags, blocks); + } + else + { + return Extract_Node_Slow(dataType, flags, blocks); + } + } #endif } diff --git a/src/CLR/Core/Core.vcxproj b/src/CLR/Core/Core.vcxproj index 7acf85a2c5..2352b21545 100644 --- a/src/CLR/Core/Core.vcxproj +++ b/src/CLR/Core/Core.vcxproj @@ -52,6 +52,7 @@ + @@ -163,7 +164,7 @@ NotUsing Level3 Disabled - _DEBUG;_LIB;VERSION_MAJOR=0;VERSION_MINOR=0;VERSION_BUILD=0;VERSION_REVISION=0;%(PreprocessorDefinitions) + _DEBUG;_LIB;%(PreprocessorDefinitions) ..\..\..\targets\win32\Include;..\Include;..\CorLib;..\..\HAL\Include;..\..\PAL\Include;..\..\nanoFramework.System.Collections @@ -175,7 +176,7 @@ NotUsing Level3 Disabled - _DEBUG;_LIB;VERSION_MAJOR=0;VERSION_MINOR=0;VERSION_BUILD=0;VERSION_REVISION=0;%(PreprocessorDefinitions) + _DEBUG;_LIB;%(PreprocessorDefinitions) ..\..\..\targets\win32\Include;..\Include;..\CorLib;..\..\HAL\Include;..\..\PAL\Include;..\..\nanoFramework.System.Collections @@ -189,7 +190,7 @@ MaxSpeed true true - NDEBUG;_LIB;VERSION_MAJOR=$(NBGV_VersionMajor);%(PreprocessorDefinitions) + NDEBUG;_LIB;%(PreprocessorDefinitions) ..\..\..\targets\win32\Include;..\Include;..\CorLib;..\..\HAL\Include;..\..\PAL\Include;..\..\nanoFramework.System.Collections @@ -205,7 +206,7 @@ MaxSpeed true true - NDEBUG;_LIB;VERSION_MAJOR=$(NBGV_VersionMajor);%(PreprocessorDefinitions) + NDEBUG;_LIB;%(PreprocessorDefinitions) ..\..\..\targets\win32\Include;..\Include;..\CorLib;..\..\HAL\Include;..\..\PAL\Include;..\..\nanoFramework.System.Collections diff --git a/src/CLR/Core/Core.vcxproj.filters b/src/CLR/Core/Core.vcxproj.filters index 68d53b16b9..486b2a7481 100644 --- a/src/CLR/Core/Core.vcxproj.filters +++ b/src/CLR/Core/Core.vcxproj.filters @@ -138,6 +138,9 @@ Source Files + + Source Files + @@ -215,4 +218,4 @@ Header Files - \ No newline at end of file + diff --git a/src/CLR/Core/Execution.cpp b/src/CLR/Core/Execution.cpp index bb6b2c9e40..a23ea14161 100644 --- a/src/CLR/Core/Execution.cpp +++ b/src/CLR/Core/Execution.cpp @@ -17,6 +17,26 @@ CLR_RT_ExecutionEngine::ExecutionConstraintCompensation CLR_RT_ExecutionEngine:: //--// +#if defined(VIRTUAL_DEVICE) + +HRESULT CLR_RT_ExecutionEngine::CreateInstance(CLR_SETTINGS params) +{ + NATIVE_PROFILE_CLR_CORE(); + NANOCLR_HEADER(); + + NANOCLR_CLEAR(g_CLR_RT_ExecutionEngine); + + // config from CLR settings + g_CLR_RT_ExecutionEngine.m_fPerformGarbageCollection = params.PerformGarbageCollection; + g_CLR_RT_ExecutionEngine.m_fPerformHeapCompaction = params.PerformHeapCompaction; + + NANOCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.ExecutionEngine_Initialize()); + + NANOCLR_NOCLEANUP(); +} + +#else + HRESULT CLR_RT_ExecutionEngine::CreateInstance() { NATIVE_PROFILE_CLR_CORE(); @@ -29,6 +49,8 @@ HRESULT CLR_RT_ExecutionEngine::CreateInstance() NANOCLR_NOCLEANUP(); } +#endif + //--// HRESULT CLR_RT_ExecutionEngine::ExecutionEngine_Initialize() @@ -77,7 +99,7 @@ HRESULT CLR_RT_ExecutionEngine::ExecutionEngine_Initialize() #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) m_scratchPadArray = NULL; // CLR_RT_HeapBlock_Array* m_scratchPadArray; -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) #if defined(NANOCLR_APPDOMAINS) m_appDomains.DblLinkedList_Initialize(); // CLR_RT_DblLinkedList m_appDomains; @@ -153,9 +175,16 @@ HRESULT CLR_RT_ExecutionEngine::AllocateHeaps() #if NANOCLR_VALIDATE_HEAP >= NANOCLR_VALIDATE_HEAP_1_HeapBlocksAndUnlink CLR_Debug::Printf("Heap Cluster information\r\n"); + +#ifdef _WIN64 + CLR_Debug::Printf("Start: 0x%I64X\r\n", (size_t)heapFirstFree); + CLR_Debug::Printf("Free: 0x%I64X\r\n", (size_t)heapFree); + CLR_Debug::Printf("Block size: %d\r\n", sizeof(CLR_RT_HeapBlock)); +#else CLR_Debug::Printf("Start: %08x\r\n", (size_t)heapFirstFree); CLR_Debug::Printf("Free: %08x\r\n", (size_t)heapFree); CLR_Debug::Printf("Block size: %d\r\n", sizeof(CLR_RT_HeapBlock)); +#endif #endif /// @@ -218,7 +247,7 @@ void CLR_RT_ExecutionEngine::ExecutionEngine_Cleanup() m_breakpointsNum = 0; CLR_DBG_Debugger::DeleteInstance(); -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) #if defined(NANOCLR_PROFILE_NEW) CLR_PRF_Profiler::DeleteInstance(); @@ -369,7 +398,9 @@ CLR_UINT32 CLR_RT_ExecutionEngine::PerformGarbageCollection() #if !defined(BUILD_RTM) || defined(VIRTUAL_DEVICE) if (m_fPerformHeapCompaction) + { CLR_EE_SET(Compaction_Pending); + } #endif g_CLR_RT_ExecutionEngine.SpawnFinalizer(); @@ -395,7 +426,7 @@ void CLR_RT_ExecutionEngine::Relocate() NATIVE_PROFILE_CLR_CORE(); #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) CLR_RT_GarbageCollector::Heap_Relocate((void **)&m_scratchPadArray); -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) #if !defined(NANOCLR_APPDOMAINS) CLR_RT_GarbageCollector::Heap_Relocate((void **)&m_globalLock); @@ -490,7 +521,7 @@ bool CLR_RT_ExecutionEngine::TryToUnloadAppDomains() SignalEvents(Event_AppDomain); #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) Breakpoint_Assemblies_Loaded(); -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) } return fAnyAppDomainsUnloaded; @@ -589,7 +620,7 @@ HRESULT CLR_RT_ExecutionEngine::Execute(wchar_t *entryPointArgs, int maxContextS #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) CLR_EE_DBG_SET_MASK(StateProgramRunning, StateMask); -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) NANOCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Delegate::CreateInstance(ref, g_CLR_RT_TypeSystem.m_entryPoint, NULL)); @@ -648,7 +679,7 @@ HRESULT CLR_RT_ExecutionEngine::Execute(wchar_t *entryPointArgs, int maxContextS CLR_RT_ExecutionEngine::ExecutionConstraint_Resume(); } -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) if (CLR_EE_IS(Compaction_Pending)) { @@ -1125,7 +1156,7 @@ HRESULT CLR_RT_ExecutionEngine::ScheduleThreads(int maxContextSwitch) { NANOCLR_SET_AND_LEAVE(CLR_S_NO_READY_THREADS); } -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) CLR_RT_Thread *th = NULL; @@ -1168,7 +1199,7 @@ HRESULT CLR_RT_ExecutionEngine::ScheduleThreads(int maxContextSwitch) { NANOCLR_SET_AND_LEAVE(CLR_S_NO_READY_THREADS); } -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) } // If there is ready thread - decrease m_executionCounter for this (th) thread. @@ -1577,6 +1608,16 @@ CLR_RT_HeapBlock *CLR_RT_ExecutionEngine::ExtractHeapBlocks( g_CLR_RT_EventCache.EventCache_Cleanup(); PerformGarbageCollection(); } +#else + +#if !defined(BUILD_RTM) || defined(VIRTUAL_DEVICE) + if (g_CLR_RT_ExecutionEngine.m_fPerformGarbageCollection) + { + g_CLR_RT_EventCache.EventCache_Cleanup(); + PerformGarbageCollection(); + } +#endif + #endif for (int phase = 0;; phase++) @@ -1617,7 +1658,7 @@ CLR_RT_HeapBlock *CLR_RT_ExecutionEngine::ExtractHeapBlocks( { if (phase != 0) { - CLR_Debug::Printf("ExtractHeapBlocks succeeded at phase %d\r\n", phase); + CLR_Debug::Printf("\r\n\r\nExtractHeapBlocks succeeded at phase %d\r\n", phase); } } #endif @@ -1638,12 +1679,14 @@ CLR_RT_HeapBlock *CLR_RT_ExecutionEngine::ExtractHeapBlocks( switch (phase) { + // perform garbage collection to try to free up some memory case 0: + #if defined(NANOCLR_GC_VERBOSE) if (s_CLR_RT_fTrace_Memory >= c_CLR_RT_Trace_Info) { CLR_Debug::Printf( - " Memory: ExtractHeapBlocks: %d bytes needed.\r\n", + "\r\n\r\n Memory: ExtractHeapBlocks: %d bytes needed.\r\n", length * sizeof(CLR_RT_HeapBlock)); } #endif @@ -1652,22 +1695,35 @@ CLR_RT_HeapBlock *CLR_RT_ExecutionEngine::ExtractHeapBlocks( break; - default: // Total failure... -#if !defined(BUILD_RTM) - CLR_Debug::Printf( - "Failed allocation for %d blocks, %d bytes\r\n\r\n", - length, - length * sizeof(CLR_RT_HeapBlock)); -#endif + // total failure on reclaiming enough memory + default: + if (g_CLR_RT_GarbageCollector.m_freeBytes >= (length * sizeof(CLR_RT_HeapBlock))) { - // A compaction probably would have saved this OOM // Compaction will occur for Bitmaps, Arrays, etc. if this function returns NULL, so lets not // through an assert here // Throw the OOM, and schedule a compaction at a safe point CLR_EE_SET(Compaction_Pending); + +#if !defined(BUILD_RTM) + CLR_Debug::Printf( + "\r\n\r\nFailed allocation for %d blocks, %d bytes.\r\nThere's enough free memory, heap " + "compaction scheduled.\r\n\r\n", + length, + length * sizeof(CLR_RT_HeapBlock)); +#endif + } + else + { + +#if !defined(BUILD_RTM) + CLR_Debug::Printf( + "\r\n\r\nFailed allocation for %d blocks, %d bytes\r\n\r\n", + length, + length * sizeof(CLR_RT_HeapBlock)); +#endif } return NULL; @@ -2406,6 +2462,7 @@ void CLR_RT_ExecutionEngine::ProcessHardware() { NATIVE_PROFILE_CLR_CORE(); Watchdog_Reset(); + RtosYield(); g_CLR_HW_Hardware.ProcessActivity(); } @@ -2578,7 +2635,7 @@ void CLR_RT_ExecutionEngine::CheckThreads(CLR_INT64 &timeoutMin, CLR_RT_DblLinke { continue; } -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) // // Check events. @@ -3591,7 +3648,7 @@ void CLR_RT_ExecutionEngine::Breakpoint_Exception_Intercepted(CLR_RT_StackFrame Breakpoint_System_Event(hit, event, NULL, stack, NULL); } -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/CLR/Core/GarbageCollector.cpp b/src/CLR/Core/GarbageCollector.cpp index 8910b55e9b..07cc46525d 100644 --- a/src/CLR/Core/GarbageCollector.cpp +++ b/src/CLR/Core/GarbageCollector.cpp @@ -144,7 +144,7 @@ CLR_UINT32 CLR_RT_GarbageCollector::ExecuteGarbageCollection() #if defined(NANOCLR_GC_VERBOSE) if (s_CLR_RT_fTrace_GC >= c_CLR_RT_Trace_Info) { - CLR_Debug::Printf(" Memory: Start %s\r\n", HAL_Time_CurrentDateTimeToString()); + CLR_Debug::Printf("\r\n\r\n Memory: Start %s\r\n", HAL_Time_CurrentDateTimeToString()); } #endif @@ -154,7 +154,7 @@ CLR_UINT32 CLR_RT_GarbageCollector::ExecuteGarbageCollection() #if defined(NANOCLR_TRACE_MEMORY_STATS) - CLR_UINT32 stats_start = HAL_Time_CurrentSysTicks(); + CLR_UINT64 stats_start = HAL_Time_CurrentSysTicks(); #endif @@ -176,7 +176,7 @@ CLR_UINT32 CLR_RT_GarbageCollector::ExecuteGarbageCollection() TIME_CONVERSION__TICKUNITS; CLR_Debug::Printf( - "GC: %dmsec %d bytes used, %d bytes available\r\n", + "\r\nGC: %dmsec %d bytes used, %d bytes available\r\n\r\n", milliSec, m_totalBytes - m_freeBytes, m_freeBytes); @@ -227,12 +227,14 @@ CLR_UINT32 CLR_RT_GarbageCollector::ExecuteGarbageCollection() } NANOCLR_FOREACH_NODE_END(); +#if defined(NANOCLR_GC_VERBOSE) + for (dt = DATATYPE_VOID; dt < DATATYPE_FIRST_INVALID; dt++) { if (countBlocks[dt]) { CLR_Debug::Printf( - "Type %02X (%-20s): %6d bytes\r\n", + "Type %02X (%-20s): %8d bytes\r\n", dt, c_CLR_RT_DataTypeLookup[dt].m_name, countBlocks[dt] * sizeof(CLR_RT_HeapBlock)); @@ -244,7 +246,7 @@ CLR_UINT32 CLR_RT_GarbageCollector::ExecuteGarbageCollection() if (countArryBlocks[dt2]) { CLR_Debug::Printf( - " Type %02X (%-17s): %6d bytes\r\n", + " Type %02X (%-17s): %8d bytes\r\n", dt2, c_CLR_RT_DataTypeLookup[dt2].m_name, countArryBlocks[dt2] * sizeof(CLR_RT_HeapBlock)); @@ -253,6 +255,8 @@ CLR_UINT32 CLR_RT_GarbageCollector::ExecuteGarbageCollection() } } } + +#endif } #endif @@ -265,7 +269,7 @@ CLR_UINT32 CLR_RT_GarbageCollector::ExecuteGarbageCollection() #if defined(NANOCLR_GC_VERBOSE) if (s_CLR_RT_fTrace_GC >= c_CLR_RT_Trace_Info) { - CLR_Debug::Printf(" Memory: End %s\r\n", HAL_Time_CurrentDateTimeToString()); + CLR_Debug::Printf("\r\n\r\n Memory: End %s\r\n", HAL_Time_CurrentDateTimeToString()); } #endif @@ -398,7 +402,7 @@ void CLR_RT_GarbageCollector::Mark() #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) CheckSingleBlock_Force(g_CLR_RT_ExecutionEngine.m_scratchPadArray); -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) if (m_fOutOfStackSpaceForGC) { diff --git a/src/CLR/Core/GarbageCollector_Compaction.cpp b/src/CLR/Core/GarbageCollector_Compaction.cpp index 7ecd94549c..eec86af611 100644 --- a/src/CLR/Core/GarbageCollector_Compaction.cpp +++ b/src/CLR/Core/GarbageCollector_Compaction.cpp @@ -13,11 +13,11 @@ CLR_UINT32 CLR_RT_GarbageCollector::ExecuteCompaction() #if defined(NANOCLR_PROFILE_NEW_ALLOCATIONS) g_CLR_PRF_Profiler.RecordHeapCompactionBegin(); #endif - + #if defined(NANOCLR_TRACE_MEMORY_STATS) - if(s_CLR_RT_fTrace_MemoryStats >= c_CLR_RT_Trace_Info) + if (s_CLR_RT_fTrace_MemoryStats >= c_CLR_RT_Trace_Info) { - CLR_Debug::Printf( "GC: performing heap compaction\r\n" ); + CLR_Debug::Printf("\r\nGC: performing heap compaction\r\n"); } #endif @@ -37,9 +37,9 @@ CLR_UINT32 CLR_RT_GarbageCollector::ExecuteCompaction() #endif #if defined(NANOCLR_TRACE_MEMORY_STATS) - if(s_CLR_RT_fTrace_MemoryStats >= c_CLR_RT_Trace_Info) + if (s_CLR_RT_fTrace_MemoryStats >= c_CLR_RT_Trace_Info) { - CLR_Debug::Printf( "GC: heap compaction completed\r\n" ); + CLR_Debug::Printf("\r\n\r\nGC: heap compaction completed\r\n"); } #endif @@ -56,151 +56,169 @@ void CLR_RT_GarbageCollector::Heap_Compact() //--// - RelocationRegion relocHelper[ c_minimumSpaceForCompact ]; - const size_t relocMax = ARRAYSIZE(relocHelper); + RelocationRegion relocHelper[c_minimumSpaceForCompact]; + const size_t relocMax = ARRAYSIZE(relocHelper); + + memset(relocHelper, 0, sizeof(relocHelper)); - Heap_Relocate_Prepare( relocHelper, relocMax ); + Heap_Relocate_Prepare(relocHelper, relocMax); - RelocationRegion* relocBlocks = relocHelper; - RelocationRegion* relocCurrent = relocBlocks; + RelocationRegion *relocBlocks = relocHelper; + RelocationRegion *relocCurrent = relocBlocks; //--// TestPointers_PopulateOld(); - - CLR_RT_HeapCluster* freeRegion_hc = NULL;; - CLR_RT_HeapBlock_Node* freeRegion = NULL; + CLR_RT_HeapCluster *freeRegion_hc = NULL; + + CLR_RT_HeapBlock_Node *freeRegion = NULL; - CLR_RT_HeapCluster* currentSource_hc = (CLR_RT_HeapCluster*)g_CLR_RT_ExecutionEngine.m_heap.FirstNode(); - while(currentSource_hc->Next()) + CLR_RT_HeapCluster *currentSource_hc = (CLR_RT_HeapCluster *)g_CLR_RT_ExecutionEngine.m_heap.FirstNode(); + while (currentSource_hc->Next()) { - CLR_RT_HeapBlock_Node* currentSource = currentSource_hc->m_payloadStart; - CLR_RT_HeapBlock_Node* currentSource_end = currentSource_hc->m_payloadEnd; + CLR_RT_HeapBlock_Node *currentSource = currentSource_hc->m_payloadStart; + CLR_RT_HeapBlock_Node *currentSource_end = currentSource_hc->m_payloadEnd; - if(!freeRegion) + if (!freeRegion) { // // Move to the next first free region. // - freeRegion_hc = (CLR_RT_HeapCluster*)g_CLR_RT_ExecutionEngine.m_heap.FirstNode(); - while(true) + freeRegion_hc = (CLR_RT_HeapCluster *)g_CLR_RT_ExecutionEngine.m_heap.FirstNode(); + while (true) { - CLR_RT_HeapCluster* freeRegion_hcNext = (CLR_RT_HeapCluster*)freeRegion_hc->Next(); if(!freeRegion_hcNext) break; + CLR_RT_HeapCluster *freeRegion_hcNext = (CLR_RT_HeapCluster *)freeRegion_hc->Next(); + if (!freeRegion_hcNext) + break; - freeRegion = freeRegion_hc->m_freeList.FirstNode(); if(freeRegion->Next()) break; + freeRegion = freeRegion_hc->m_freeList.FirstNode(); + if (freeRegion->Next()) + break; - freeRegion = NULL; + freeRegion = NULL; freeRegion_hc = freeRegion_hcNext; } - if(!freeRegion) break; + if (!freeRegion) + break; } - while(true) + while (true) { // // We can only move backward. // - if(currentSource < freeRegion) + if (currentSource < freeRegion) { - currentSource_hc = freeRegion_hc; - currentSource = freeRegion; + currentSource_hc = freeRegion_hc; + currentSource = freeRegion; currentSource_end = freeRegion_hc->m_payloadEnd; } - while(currentSource < currentSource_end && currentSource->IsFlagSet( CLR_RT_HeapBlock::HB_Unmovable )) + while (currentSource < currentSource_end && currentSource->IsFlagSet(CLR_RT_HeapBlock::HB_Unmovable)) { currentSource += currentSource->DataSize(); } - if(currentSource == currentSource_end) break; + if (currentSource == currentSource_end) + break; - ////////////////////////////////////////////////////// - // - // At this point, we have at least ONE movable block. - // - ////////////////////////////////////////////////////// + ////////////////////////////////////////////////////// + // + // At this point, we have at least ONE movable block. + // + ////////////////////////////////////////////////////// #if NANOCLR_VALIDATE_HEAP >= NANOCLR_VALIDATE_HEAP_4_CompactionPlus - if(IsBlockInFreeList( g_CLR_RT_ExecutionEngine.m_heap, freeRegion, true ) == false) + if (IsBlockInFreeList(g_CLR_RT_ExecutionEngine.m_heap, freeRegion, true) == false) { - CLR_Debug::Printf( "'freeRegion' is not in a free list!! %08x\r\n", freeRegion ); + CLR_Debug::Printf("'freeRegion' is not in a free list!! %08x\r\n", freeRegion); NANOCLR_DEBUG_STOP(); } - if(IsBlockInFreeList( g_CLR_RT_ExecutionEngine.m_heap, currentSource, false )) + if (IsBlockInFreeList(g_CLR_RT_ExecutionEngine.m_heap, currentSource, false)) { - CLR_Debug::Printf( "'currentSource' is in a free list!! %08x\r\n", currentSource ); + CLR_Debug::Printf("'currentSource' is in a free list!! %08x\r\n", currentSource); NANOCLR_DEBUG_STOP(); } #endif - if(m_relocCount >= relocMax) + if (m_relocCount >= relocMax) { - ValidateHeap( g_CLR_RT_ExecutionEngine.m_heap ); + ValidateHeap(g_CLR_RT_ExecutionEngine.m_heap); Heap_Relocate(); - ValidateHeap( g_CLR_RT_ExecutionEngine.m_heap ); + ValidateHeap(g_CLR_RT_ExecutionEngine.m_heap); - relocBlocks = m_relocBlocks; + relocBlocks = m_relocBlocks; relocCurrent = relocBlocks; TestPointers_PopulateOld(); } { - CLR_UINT32 move = 0; + CLR_UINT32 move = 0; CLR_UINT32 freeRegion_Size = freeRegion->DataSize(); - bool fSlide; + bool fSlide; - relocCurrent->m_destination = (CLR_UINT8*)freeRegion; - relocCurrent->m_start = (CLR_UINT8*)currentSource; - relocCurrent->m_offset = (CLR_UINT32)(relocCurrent->m_destination - relocCurrent->m_start); + relocCurrent->m_destination = (CLR_UINT8 *)freeRegion; + relocCurrent->m_start = (CLR_UINT8 *)currentSource; + + if (relocCurrent->m_destination < relocCurrent->m_start) + { + relocCurrent->m_offset = -(CLR_INT32)(relocCurrent->m_start - relocCurrent->m_destination); + } + else + { + relocCurrent->m_offset = (CLR_INT32)(relocCurrent->m_destination - relocCurrent->m_start); + } - // // Are the free block and the last moved block adjacent? // - if(currentSource == freeRegion + freeRegion_Size) + if (currentSource == freeRegion + freeRegion_Size) { - while(currentSource < currentSource_end && currentSource->IsFlagSet( CLR_RT_HeapBlock::HB_Unmovable ) == false) + while (currentSource < currentSource_end && + currentSource->IsFlagSet(CLR_RT_HeapBlock::HB_Unmovable) == false) { CLR_UINT32 len = currentSource->DataSize(); currentSource += len; - move += len; + move += len; } fSlide = true; } else { - while(freeRegion_Size && currentSource < currentSource_end && currentSource->IsFlagSet( CLR_RT_HeapBlock::HB_Unmovable ) == false) + while (freeRegion_Size && currentSource < currentSource_end && + currentSource->IsFlagSet(CLR_RT_HeapBlock::HB_Unmovable) == false) { CLR_UINT32 len = currentSource->DataSize(); - if(freeRegion_Size < len) + if (freeRegion_Size < len) { break; } freeRegion_Size -= len; - currentSource += len; - move += len; + currentSource += len; + move += len; } fSlide = false; } - if(move) + if (move) { // // Skip forward to the next movable block. // - while(currentSource < currentSource_end && currentSource->IsFlagSet( CLR_RT_HeapBlock::HB_Unmovable )) + while (currentSource < currentSource_end && + currentSource->IsFlagSet(CLR_RT_HeapBlock::HB_Unmovable)) { currentSource += currentSource->DataSize(); } @@ -215,37 +233,35 @@ void CLR_RT_GarbageCollector::Heap_Compact() // Remove the old free block, copy the data, recreate the new free block. // Merge with the following one if they are adjacent now. // - CLR_RT_HeapBlock_Node* freeRegionNext = freeRegion->Next(); + CLR_RT_HeapBlock_Node *freeRegionNext = freeRegion->Next(); freeRegion->Unlink(); - - memmove( relocCurrent->m_destination, relocCurrent->m_start, moveBytes ); - if(freeRegion_Size) - { + memmove(relocCurrent->m_destination, relocCurrent->m_start, moveBytes); - freeRegion = freeRegion_hc->InsertInOrder( freeRegion + move, freeRegion_Size ); + if (freeRegion_Size) + { + freeRegion = freeRegion_hc->InsertInOrder(freeRegion + move, freeRegion_Size); } else { freeRegion = freeRegionNext; - } - if(fSlide == false) + if (fSlide == false) { - CLR_RT_HeapBlock_Node* dst = currentSource_hc->InsertInOrder( (CLR_RT_HeapBlock_Node*)relocCurrent->m_start, move ); + CLR_RT_HeapBlock_Node *dst = + currentSource_hc->InsertInOrder((CLR_RT_HeapBlock_Node *)relocCurrent->m_start, move); - if(dst < freeRegion && freeRegion < (dst + dst->DataSize())) + if (dst < freeRegion && freeRegion < (dst + dst->DataSize())) { freeRegion = dst; } - } - CLR_RT_GarbageCollector::ValidateCluster( currentSource_hc ); - CLR_RT_GarbageCollector::ValidateCluster( freeRegion_hc ); + CLR_RT_GarbageCollector::ValidateCluster(currentSource_hc); + CLR_RT_GarbageCollector::ValidateCluster(freeRegion_hc); relocCurrent++; m_relocCount++; @@ -253,64 +269,76 @@ void CLR_RT_GarbageCollector::Heap_Compact() else { freeRegion = freeRegion->Next(); - } - if(freeRegion->Next() == NULL) + if (freeRegion->Next() == NULL) { - freeRegion = NULL; - freeRegion_hc = (CLR_RT_HeapCluster*)freeRegion_hc->Next(); - while(true) + freeRegion = NULL; + freeRegion_hc = (CLR_RT_HeapCluster *)freeRegion_hc->Next(); + + while (true) { - CLR_RT_HeapCluster* freeRegion_hcNext = (CLR_RT_HeapCluster*)freeRegion_hc->Next(); if(!freeRegion_hcNext) break; + CLR_RT_HeapCluster *freeRegion_hcNext = (CLR_RT_HeapCluster *)freeRegion_hc->Next(); + if (!freeRegion_hcNext) + { + break; + } - freeRegion = freeRegion_hc->m_freeList.FirstNode(); if(freeRegion->Next()) break; + freeRegion = freeRegion_hc->m_freeList.FirstNode(); - freeRegion = NULL; + if (freeRegion != NULL && freeRegion->Next()) + { + break; + } + + freeRegion = NULL; freeRegion_hc = freeRegion_hcNext; } - if(!freeRegion) break; + if (!freeRegion) + { + break; + } } } } - currentSource_hc = (CLR_RT_HeapCluster*)currentSource_hc->Next(); + currentSource_hc = (CLR_RT_HeapCluster *)currentSource_hc->Next(); } - if(m_relocCount) + if (m_relocCount) { - ValidateHeap( g_CLR_RT_ExecutionEngine.m_heap ); + ValidateHeap(g_CLR_RT_ExecutionEngine.m_heap); Heap_Relocate(); - ValidateHeap( g_CLR_RT_ExecutionEngine.m_heap ); + ValidateHeap(g_CLR_RT_ExecutionEngine.m_heap); } } -void CLR_RT_GarbageCollector::Heap_Relocate_Prepare( RelocationRegion* blocks, size_t total ) +void CLR_RT_GarbageCollector::Heap_Relocate_Prepare(RelocationRegion *blocks, size_t total) { NATIVE_PROFILE_CLR_CORE(); m_relocBlocks = blocks; - m_relocTotal = total; - m_relocCount = 0; + m_relocTotal = total; + m_relocCount = 0; } -void CLR_RT_GarbageCollector::Heap_Relocate_AddBlock( CLR_UINT8* dst, CLR_UINT8* src, CLR_UINT32 length ) +void CLR_RT_GarbageCollector::Heap_Relocate_AddBlock(CLR_UINT8 *dst, CLR_UINT8 *src, CLR_UINT32 length) { NATIVE_PROFILE_CLR_CORE(); - RelocationRegion* reloc = m_relocBlocks; - size_t count = m_relocCount; + RelocationRegion *reloc = m_relocBlocks; + size_t count = m_relocCount; - while(count) + while (count) { - if(reloc->m_start > src) + if (reloc->m_start > src) { // // Insert region, so they are sorted by start address. // - memmove( &reloc[ 1 ], &reloc[ 0 ], count * sizeof(*reloc) ); + memmove(&reloc[1], &reloc[0], count * sizeof(*reloc)); break; } @@ -318,12 +346,20 @@ void CLR_RT_GarbageCollector::Heap_Relocate_AddBlock( CLR_UINT8* dst, CLR_UINT8* count--; } - reloc->m_start = src; - reloc->m_end = &src[ length ]; - reloc->m_destination = dst; - reloc->m_offset = (CLR_UINT32)(dst - src); + reloc->m_start = src; + reloc->m_end = &src[length]; + reloc->m_destination = dst; - if(++m_relocCount == m_relocTotal) + if (reloc->m_destination < reloc->m_start) + { + reloc->m_offset = -(CLR_INT32)(reloc->m_start - reloc->m_destination); + } + else + { + reloc->m_offset = (CLR_INT32)(reloc->m_destination - reloc->m_start); + } + + if (++m_relocCount == m_relocTotal) { Heap_Relocate(); } @@ -332,17 +368,24 @@ void CLR_RT_GarbageCollector::Heap_Relocate_AddBlock( CLR_UINT8* dst, CLR_UINT8* void CLR_RT_GarbageCollector::Heap_Relocate() { NATIVE_PROFILE_CLR_CORE(); - if(m_relocCount) + if (m_relocCount) { - RelocationRegion* relocBlocks = m_relocBlocks; + RelocationRegion *relocBlocks = m_relocBlocks; - CLR_UINT8* relocMinimum = relocBlocks->m_start; - CLR_UINT8* relocMaximum = relocBlocks->m_end; + CLR_UINT8 *relocMinimum = relocBlocks->m_start; + CLR_UINT8 *relocMaximum = relocBlocks->m_end; - for(size_t i=0; i relocBlocks->m_start) relocMinimum = relocBlocks->m_start; - if(relocMaximum < relocBlocks->m_end ) relocMaximum = relocBlocks->m_end; + if (relocMinimum > relocBlocks->m_start) + { + relocMinimum = relocBlocks->m_start; + } + + if (relocMaximum < relocBlocks->m_end) + { + relocMaximum = relocBlocks->m_end; + } } m_relocMinimum = relocMinimum; @@ -350,7 +393,7 @@ void CLR_RT_GarbageCollector::Heap_Relocate() TestPointers_Remap(); - Heap_Relocate_Pass( NULL ); + Heap_Relocate_Pass(NULL); #if defined(NANOCLR_PROFILE_NEW_ALLOCATIONS) g_CLR_PRF_Profiler.TrackObjectRelocation(); @@ -364,23 +407,22 @@ void CLR_RT_GarbageCollector::Heap_Relocate() } } -void CLR_RT_GarbageCollector::Heap_Relocate_Pass( RelocateFtn ftn ) +void CLR_RT_GarbageCollector::Heap_Relocate_Pass(RelocateFtn ftn) { NATIVE_PROFILE_CLR_CORE(); - #if NANOCLR_VALIDATE_HEAP > NANOCLR_VALIDATE_HEAP_0_None +#if NANOCLR_VALIDATE_HEAP > NANOCLR_VALIDATE_HEAP_0_None m_relocWorker = ftn; - #else +#else (void)ftn; - #endif +#endif - NANOCLR_FOREACH_NODE(CLR_RT_HeapCluster,hc,g_CLR_RT_ExecutionEngine.m_heap) + NANOCLR_FOREACH_NODE(CLR_RT_HeapCluster, hc, g_CLR_RT_ExecutionEngine.m_heap) { - CLR_RT_HeapBlock_Node* ptr = hc->m_payloadStart; - CLR_RT_HeapBlock_Node* end = hc->m_payloadEnd; + CLR_RT_HeapBlock_Node *ptr = hc->m_payloadStart; + CLR_RT_HeapBlock_Node *end = hc->m_payloadEnd; - - while(ptr < end) + while (ptr < end) { CLR_RT_HEAPBLOCK_RELOCATE(ptr); @@ -394,10 +436,10 @@ void CLR_RT_GarbageCollector::Heap_Relocate_Pass( RelocateFtn ftn ) //--// -void CLR_RT_GarbageCollector::Heap_Relocate( CLR_RT_HeapBlock* lst, CLR_UINT32 len ) +void CLR_RT_GarbageCollector::Heap_Relocate(CLR_RT_HeapBlock *lst, CLR_UINT32 len) { NATIVE_PROFILE_CLR_CORE(); - while(len--) + while (len--) { CLR_RT_HEAPBLOCK_RELOCATE(lst); @@ -405,41 +447,49 @@ void CLR_RT_GarbageCollector::Heap_Relocate( CLR_RT_HeapBlock* lst, CLR_UINT32 l } } -void CLR_RT_GarbageCollector::Heap_Relocate( void** ref ) +void CLR_RT_GarbageCollector::Heap_Relocate(void **ref) { NATIVE_PROFILE_CLR_CORE(); - CLR_UINT8* dst = (CLR_UINT8*)*ref; + CLR_UINT8 *dst = (CLR_UINT8 *)*ref; + +#if NANOCLR_VALIDATE_HEAP == NANOCLR_VALIDATE_HEAP_0_None + void *destinationAddress; +#endif #if NANOCLR_VALIDATE_HEAP > NANOCLR_VALIDATE_HEAP_0_None - if(g_CLR_RT_GarbageCollector.m_relocWorker) + if (g_CLR_RT_GarbageCollector.m_relocWorker) { - g_CLR_RT_GarbageCollector.m_relocWorker( ref ); + g_CLR_RT_GarbageCollector.m_relocWorker(ref); } else #endif { - if(dst >= g_CLR_RT_GarbageCollector.m_relocMinimum && dst < g_CLR_RT_GarbageCollector.m_relocMaximum) + if (dst >= g_CLR_RT_GarbageCollector.m_relocMinimum && dst < g_CLR_RT_GarbageCollector.m_relocMaximum) { - RelocationRegion* relocBlocks = g_CLR_RT_GarbageCollector.m_relocBlocks; - size_t left = 0; - size_t right = g_CLR_RT_GarbageCollector.m_relocCount; + RelocationRegion *relocBlocks = g_CLR_RT_GarbageCollector.m_relocBlocks; + size_t left = 0; + size_t right = g_CLR_RT_GarbageCollector.m_relocCount; - while(left < right) + while (left < right) { - size_t center = (left + right) / 2; - RelocationRegion& relocCurrent = relocBlocks[ center ]; + size_t center = (left + right) / 2; + RelocationRegion &relocCurrent = relocBlocks[center]; - if(dst < relocCurrent.m_start) + if (dst < relocCurrent.m_start) { right = center; } - else if(dst >= relocCurrent.m_end) + else if (dst >= relocCurrent.m_end) { - left = center+1; + left = center + 1; } else { - *ref = (void*)(dst + relocCurrent.m_offset); + destinationAddress = (void *)(dst + relocCurrent.m_offset); + _ASSERTE(destinationAddress >= (void *)s_CLR_RT_Heap.m_location); + _ASSERTE(destinationAddress < (void *)(s_CLR_RT_Heap.m_location + s_CLR_RT_Heap.m_size)); + + *ref = destinationAddress; return; } @@ -450,18 +500,17 @@ void CLR_RT_GarbageCollector::Heap_Relocate( void** ref ) #if NANOCLR_VALIDATE_HEAP >= NANOCLR_VALIDATE_HEAP_3_Compaction -bool CLR_RT_GarbageCollector::Relocation_JustCheck( void** ref ) +bool CLR_RT_GarbageCollector::Relocation_JustCheck(void **ref) { NATIVE_PROFILE_CLR_CORE(); - CLR_UINT8* dst = (CLR_UINT8*)*ref; + CLR_UINT8 *dst = (CLR_UINT8 *)*ref; - if(dst) + if (dst) { - ValidateBlockNotInFreeList( g_CLR_RT_ExecutionEngine.m_heap, (CLR_RT_HeapBlock_Node*)dst ); + ValidateBlockNotInFreeList(g_CLR_RT_ExecutionEngine.m_heap, (CLR_RT_HeapBlock_Node *)dst); } return true; } #endif - diff --git a/src/CLR/Core/GarbageCollector_ComputeReachabilityGraph.cpp b/src/CLR/Core/GarbageCollector_ComputeReachabilityGraph.cpp index ad76c24d69..f3588e800b 100644 --- a/src/CLR/Core/GarbageCollector_ComputeReachabilityGraph.cpp +++ b/src/CLR/Core/GarbageCollector_ComputeReachabilityGraph.cpp @@ -3,17 +3,18 @@ // Portions Copyright (c) Microsoft Corporation. All rights reserved. // See LICENSE file in the project root for full license information. // + #include "Core.h" //--// -void CLR_RT_GarbageCollector::MarkStack::Initialize( MarkStackElement* ptr, size_t num ) +void CLR_RT_GarbageCollector::MarkStack::Initialize(MarkStackElement *ptr, size_t num) { NATIVE_PROFILE_CLR_CORE(); GenericNode_Initialize(); - m_last = &ptr[ num-1 ]; - m_top = ptr; + m_last = &ptr[num - 1]; + m_top = ptr; // // Empty element to act a sentinel. @@ -27,51 +28,58 @@ void CLR_RT_GarbageCollector::MarkStack::Initialize( MarkStackElement* ptr, size //--// -bool CLR_RT_GarbageCollector::ComputeReachabilityGraphForSingleBlock( CLR_RT_HeapBlock** ptr ) +bool CLR_RT_GarbageCollector::ComputeReachabilityGraphForSingleBlock(CLR_RT_HeapBlock **ptr) { NATIVE_PROFILE_CLR_CORE(); - CLR_RT_HeapBlock* obj = *ptr; if(obj == NULL || obj->IsAlive()) return true; + CLR_RT_HeapBlock *obj = *ptr; + if (obj == NULL || obj->IsAlive()) + return true; - return ComputeReachabilityGraphForMultipleBlocks( obj, 1 ); + return ComputeReachabilityGraphForMultipleBlocks(obj, 1); } - -bool CLR_RT_GarbageCollector::ComputeReachabilityGraphForMultipleBlocks( CLR_RT_HeapBlock* lst, CLR_UINT32 num ) +bool CLR_RT_GarbageCollector::ComputeReachabilityGraphForMultipleBlocks(CLR_RT_HeapBlock *lst, CLR_UINT32 num) { NATIVE_PROFILE_CLR_CORE(); - MarkStack * stackList; - MarkStackElement* stack; - MarkStackElement* stackLast; + MarkStack *stackList; + MarkStackElement *stack; + MarkStackElement *stackLast; -#define COMPUTEREACHABILITY_LOADSTATE() stackLast = g_CLR_RT_GarbageCollector.m_markStack->m_last; stack = g_CLR_RT_GarbageCollector.m_markStack->m_top; stackList = g_CLR_RT_GarbageCollector.m_markStack; -#define COMPUTEREACHABILITY_SAVESTATE() g_CLR_RT_GarbageCollector.m_markStack->m_last = stackLast; g_CLR_RT_GarbageCollector.m_markStack->m_top = stack; g_CLR_RT_GarbageCollector.m_markStack = stackList; +#define COMPUTEREACHABILITY_LOADSTATE() \ + stackLast = g_CLR_RT_GarbageCollector.m_markStack->m_last; \ + stack = g_CLR_RT_GarbageCollector.m_markStack->m_top; \ + stackList = g_CLR_RT_GarbageCollector.m_markStack; +#define COMPUTEREACHABILITY_SAVESTATE() \ + g_CLR_RT_GarbageCollector.m_markStack->m_last = stackLast; \ + g_CLR_RT_GarbageCollector.m_markStack->m_top = stack; \ + g_CLR_RT_GarbageCollector.m_markStack = stackList; COMPUTEREACHABILITY_LOADSTATE(); { - CLR_RT_HeapBlock* sub = NULL; + CLR_RT_HeapBlock *sub = NULL; - while(true) + while (true) { - CLR_RT_HeapBlock* ptr = lst; + CLR_RT_HeapBlock *ptr = lst; - if(num == 0) + if (num == 0) { - if(stack->num == 0) + if (stack->num == 0) { - MarkStack* stackNext = (MarkStack*)stackList->Prev(); + MarkStack *stackNext = (MarkStack *)stackList->Prev(); - //finished with this MarkStack - if(stackNext->Prev() == NULL) + // finished with this MarkStack + if (stackNext->Prev() == NULL) { - //finished marking + // finished marking break; } else { COMPUTEREACHABILITY_SAVESTATE(); - g_CLR_RT_GarbageCollector.m_markStack = stackNext; + g_CLR_RT_GarbageCollector.m_markStack = stackNext; COMPUTEREACHABILITY_LOADSTATE(); } } @@ -81,51 +89,57 @@ bool CLR_RT_GarbageCollector::ComputeReachabilityGraphForMultipleBlocks( CLR_RT_ stack->ptr++; stack->num--; - if(stack->num == 0) + if (stack->num == 0) { stack--; -#if defined(NANOCLR_VALIDATE_APPDOMAIN_ISOLATION) - (void)g_CLR_RT_ExecutionEngine.SetCurrentAppDomain( stack->appDomain ); +#if defined(NANOCLR_VALIDATE_APPDOMAIN_ISOLATION) + (void)g_CLR_RT_ExecutionEngine.SetCurrentAppDomain(stack->appDomain); #endif } } - else if(num > 1) + else if (num > 1) { - if(stack == stackLast) + if (stack == stackLast) { - MarkStack* stackNext = (MarkStack*)stackList->Next(); + MarkStack *stackNext = (MarkStack *)stackList->Next(); - if(stackNext->Next() != NULL) - { + if (stackNext->Next() != NULL) + { COMPUTEREACHABILITY_SAVESTATE(); g_CLR_RT_GarbageCollector.m_markStack = stackNext; COMPUTEREACHABILITY_LOADSTATE(); } else - { - //try to allocate another stack list... + { + // try to allocate another stack list... stackNext = NULL; - //If there was no space for GC last time, don't bother trying to allocate again - if(!g_CLR_RT_GarbageCollector.m_fOutOfStackSpaceForGC) + // If there was no space for GC last time, don't bother trying to allocate again + if (!g_CLR_RT_GarbageCollector.m_fOutOfStackSpaceForGC) { - for(int cElement = g_CLR_RT_GarbageCollector.c_minimumSpaceForGC; cElement >= 1; cElement /= 2) + // Try to allocate next stack for HeapBlock temporary storing. + // Allocate at least 2 elements. The first one will be used as a sentinel. HeapBlocks + // will be stored starting from the second element. + for (int cElement = g_CLR_RT_GarbageCollector.c_minimumSpaceForGC; cElement >= 2; + cElement /= 2) { CLR_UINT32 size = sizeof(MarkStack) + sizeof(MarkStackElement) * cElement; - stackNext = (MarkStack*)CLR_RT_Memory::Allocate( size, CLR_RT_HeapBlock::HB_SpecialGCAllocation ); + stackNext = (MarkStack *)CLR_RT_Memory::Allocate( + size, + CLR_RT_HeapBlock::HB_SpecialGCAllocation); - if(stackNext) + if (stackNext) { COMPUTEREACHABILITY_SAVESTATE(); - stackNext->Initialize( (MarkStackElement*)(&stackNext[ 1 ]), (size_t)cElement ); + stackNext->Initialize((MarkStackElement *)(&stackNext[1]), (size_t)cElement); + + g_CLR_RT_GarbageCollector.m_markStackList->LinkAtBack(stackNext); - g_CLR_RT_GarbageCollector.m_markStackList->LinkAtBack( stackNext ); - g_CLR_RT_GarbageCollector.m_markStack = stackNext; - + COMPUTEREACHABILITY_LOADSTATE(); break; @@ -133,14 +147,14 @@ bool CLR_RT_GarbageCollector::ComputeReachabilityGraphForMultipleBlocks( CLR_RT_ } } - if(stackNext == NULL) + if (stackNext == NULL) { - //Out of stack support space - //Set the failure flag and continue, ignoring lst, num - //The mark will complete later via MarkSlow + // Out of stack support space + // Set the failure flag and continue, ignoring lst, num + // The mark will complete later via MarkSlow g_CLR_RT_GarbageCollector.m_fOutOfStackSpaceForGC = true; - + lst = NULL; num = 0; continue; @@ -150,71 +164,70 @@ bool CLR_RT_GarbageCollector::ComputeReachabilityGraphForMultipleBlocks( CLR_RT_ stack++; - stack->ptr = lst+1; - stack->num = num-1; + stack->ptr = lst + 1; + stack->num = num - 1; -#if defined(NANOCLR_VALIDATE_APPDOMAIN_ISOLATION) +#if defined(NANOCLR_VALIDATE_APPDOMAIN_ISOLATION) stack->appDomain = g_CLR_RT_ExecutionEngine.GetCurrentAppDomain(); -#endif +#endif } - { lst = NULL; num = 0; - - CLR_RT_HeapBlock::Debug_CheckPointer( ptr ); + + CLR_RT_HeapBlock::Debug_CheckPointer(ptr); ptr->MarkAlive(); - switch(ptr->DataType()) + switch (ptr->DataType()) { case DATATYPE_OBJECT: case DATATYPE_BYREF: sub = ptr->Dereference(); break; - //--// + //--// - #if defined(NANOCLR_APPDOMAINS) +#if defined(NANOCLR_APPDOMAINS) case DATATYPE_TRANSPARENT_PROXY: - { - CLR_RT_AppDomain* appDomain = ptr->TransparentProxyAppDomain(); + { + CLR_RT_AppDomain *appDomain = ptr->TransparentProxyAppDomain(); - if(appDomain) + if (appDomain) + { + if (!appDomain->IsLoaded()) { - if(!appDomain->IsLoaded()) - { - //If the AppDomain is unloading, we no longer need to keep the reference around - ptr->SetTransparentProxyReference( NULL, NULL ); - } - else - { - #if defined(NANOCLR_VALIDATE_APPDOMAIN_ISOLATION) - (void)g_CLR_RT_ExecutionEngine.SetCurrentAppDomain( ptr->TransparentProxyAppDomain() ); - #endif - sub = ptr->TransparentProxyDereference(); - } - } + // If the AppDomain is unloading, we no longer need to keep the reference around + ptr->SetTransparentProxyReference(NULL, NULL); + } + else + { +#if defined(NANOCLR_VALIDATE_APPDOMAIN_ISOLATION) + (void)g_CLR_RT_ExecutionEngine.SetCurrentAppDomain(ptr->TransparentProxyAppDomain()); +#endif + sub = ptr->TransparentProxyDereference(); + } } - break; - #endif + } + break; +#endif - //--// + //--// case DATATYPE_ARRAY_BYREF: - sub = (CLR_RT_HeapBlock*)ptr->Array(); + sub = (CLR_RT_HeapBlock *)ptr->Array(); break; - //--// + //--// case DATATYPE_CLASS: case DATATYPE_VALUETYPE: // // This is the real object, mark all its fields. // - lst = ptr + 1; + lst = ptr + 1; num = ptr->DataSize() - 1; break; @@ -223,12 +236,12 @@ bool CLR_RT_GarbageCollector::ComputeReachabilityGraphForMultipleBlocks( CLR_RT_ // If the array is full of reference types, mark each of them. // { - CLR_RT_HeapBlock_Array* array = (CLR_RT_HeapBlock_Array*)ptr; + CLR_RT_HeapBlock_Array *array = (CLR_RT_HeapBlock_Array *)ptr; - if(array->m_fReference) + if (array->m_fReference) { - lst = (CLR_RT_HeapBlock*)array->GetFirstElement(); - num = array->m_numOfElements; + lst = (CLR_RT_HeapBlock *)array->GetFirstElement(); + num = array->m_numOfElements; } } break; @@ -237,48 +250,51 @@ bool CLR_RT_GarbageCollector::ComputeReachabilityGraphForMultipleBlocks( CLR_RT_ break; case DATATYPE_DELEGATE_HEAD: - { - CLR_RT_HeapBlock_Delegate* dlg = (CLR_RT_HeapBlock_Delegate*)ptr; + { + CLR_RT_HeapBlock_Delegate *dlg = (CLR_RT_HeapBlock_Delegate *)ptr; - lst = &dlg->m_object; - num = 1; - } - break; + lst = &dlg->m_object; + num = 1; + } + break; case DATATYPE_BINARY_BLOB_HEAD: - { - CLR_RT_HeapBlock_BinaryBlob* blob = (CLR_RT_HeapBlock_BinaryBlob*)ptr; - - _ASSERTE(blob->BinaryBlobMarkingHandler() == NULL); - } - break; + { + CLR_RT_HeapBlock_BinaryBlob *blob = (CLR_RT_HeapBlock_BinaryBlob *)ptr; +#ifdef BUILD_RTM + blob->BinaryBlobMarkingHandler(); +#else + _ASSERTE(blob->BinaryBlobMarkingHandler() == NULL); +#endif + } + break; case DATATYPE_DELEGATELIST_HEAD: - { - CLR_RT_HeapBlock_Delegate_List* dlgList = (CLR_RT_HeapBlock_Delegate_List*)ptr; + { + CLR_RT_HeapBlock_Delegate_List *dlgList = (CLR_RT_HeapBlock_Delegate_List *)ptr; - if(dlgList->m_flags & CLR_RT_HeapBlock_Delegate_List::c_Weak) - { - dlgList->ClearData(); + if (dlgList->m_flags & CLR_RT_HeapBlock_Delegate_List::c_Weak) + { + dlgList->ClearData(); - g_CLR_RT_GarbageCollector.m_weakDelegates_Reachable.LinkAtBack( dlgList ); - } - else - { - lst = dlgList->GetDelegates(); - num = dlgList->m_length; - } + g_CLR_RT_GarbageCollector.m_weakDelegates_Reachable.LinkAtBack(dlgList); } - break; + else + { + lst = dlgList->GetDelegates(); + num = dlgList->m_length; + } + } + break; default: // the remaining data types aren't to be handled - break; + break; } - - if(sub) + + if (sub) { - if(sub->IsAlive() == false) + if (sub->IsAlive() == false) { lst = sub; num = 1; @@ -286,7 +302,6 @@ bool CLR_RT_GarbageCollector::ComputeReachabilityGraphForMultipleBlocks( CLR_RT_ sub = NULL; } - } } } @@ -297,4 +312,3 @@ bool CLR_RT_GarbageCollector::ComputeReachabilityGraphForMultipleBlocks( CLR_RT_ } //--// - diff --git a/src/CLR/Core/GarbageCollector_Info.cpp b/src/CLR/Core/GarbageCollector_Info.cpp index ad88bb41bd..51ff270fa4 100644 --- a/src/CLR/Core/GarbageCollector_Info.cpp +++ b/src/CLR/Core/GarbageCollector_Info.cpp @@ -9,37 +9,41 @@ #if defined(NANOCLR_GC_VERBOSE) -void CLR_RT_GarbageCollector::GC_Stats( int& resNumberObjects, int& resSizeObjects, int& resNumberEvents, int& resSizeEvents ) +void CLR_RT_GarbageCollector::GC_Stats( + int &resNumberObjects, + int &resSizeObjects, + int &resNumberEvents, + int &resSizeEvents) { NATIVE_PROFILE_CLR_CORE(); resNumberObjects = 0; - resSizeObjects = 0; + resSizeObjects = 0; - resNumberEvents = 0; - resSizeEvents = 0; + resNumberEvents = 0; + resSizeEvents = 0; - NANOCLR_FOREACH_NODE(CLR_RT_HeapCluster,hc,g_CLR_RT_ExecutionEngine.m_heap) + NANOCLR_FOREACH_NODE(CLR_RT_HeapCluster, hc, g_CLR_RT_ExecutionEngine.m_heap) { - CLR_RT_HeapBlock_Node* ptr = hc->m_payloadStart; - CLR_RT_HeapBlock_Node* end = hc->m_payloadEnd; + CLR_RT_HeapBlock_Node *ptr = hc->m_payloadStart; + CLR_RT_HeapBlock_Node *end = hc->m_payloadEnd; - while(ptr < end) + while (ptr < end) { CLR_UINT16 size = ptr->DataSize(); - hc->ValidateBlock( ptr ); + hc->ValidateBlock(ptr); - if(ptr->DataType() != DATATYPE_FREEBLOCK) + if (ptr->DataType() != DATATYPE_FREEBLOCK) { - if(ptr->IsEvent()) + if (ptr->IsEvent()) { resNumberEvents += 1; - resSizeEvents += size * sizeof(CLR_RT_HeapBlock); + resSizeEvents += size * sizeof(CLR_RT_HeapBlock); } else { resNumberObjects += 1; - resSizeObjects += size * sizeof(CLR_RT_HeapBlock); + resSizeObjects += size * sizeof(CLR_RT_HeapBlock); } } @@ -49,40 +53,39 @@ void CLR_RT_GarbageCollector::GC_Stats( int& resNumberObjects, int& resSizeObjec NANOCLR_FOREACH_NODE_END(); } - -static void DumpTimeout( CLR_RT_Thread* th, CLR_INT64& t ) +static void DumpTimeout(CLR_RT_Thread *th, CLR_INT64 &t) { NATIVE_PROFILE_CLR_CORE(); - CLR_Debug::Printf( ": %d", th ? th->m_pid : -1 ); + CLR_Debug::Printf(": %d", th ? th->m_pid : -1); - if(t < TIMEOUT_INFINITE) + if (t < TIMEOUT_INFINITE) { t -= HAL_Time_CurrentTime(); - CLR_Debug::Printf( " %d", (int)t ); + CLR_Debug::Printf(" %d", (int)t); } else { - CLR_Debug::Printf( " INFINITE" ); + CLR_Debug::Printf(" INFINITE"); } } void CLR_RT_GarbageCollector::DumpThreads() { NATIVE_PROFILE_CLR_CORE(); - NANOCLR_FOREACH_NODE(CLR_RT_Thread,th,g_CLR_RT_ExecutionEngine.m_threadsReady) + NANOCLR_FOREACH_NODE(CLR_RT_Thread, th, g_CLR_RT_ExecutionEngine.m_threadsReady) { th->DumpStack(); } NANOCLR_FOREACH_NODE_END(); - NANOCLR_FOREACH_NODE(CLR_RT_Thread,th,g_CLR_RT_ExecutionEngine.m_threadsWaiting) + NANOCLR_FOREACH_NODE(CLR_RT_Thread, th, g_CLR_RT_ExecutionEngine.m_threadsWaiting) { th->DumpStack(); } NANOCLR_FOREACH_NODE_END(); - CLR_Debug::Printf( "\r\n" ); + CLR_Debug::Printf("\r\n"); } #endif @@ -90,42 +93,46 @@ void CLR_RT_GarbageCollector::DumpThreads() #if NANOCLR_VALIDATE_HEAP >= NANOCLR_VALIDATE_HEAP_3_Compaction -void CLR_RT_GarbageCollector::ValidateCluster( CLR_RT_HeapCluster* hc ) +void CLR_RT_GarbageCollector::ValidateCluster(CLR_RT_HeapCluster *hc) { NATIVE_PROFILE_CLR_CORE(); - CLR_RT_HeapBlock_Node* ptr = hc->m_payloadStart; - CLR_RT_HeapBlock_Node* end = hc->m_payloadEnd; + CLR_RT_HeapBlock_Node *ptr = hc->m_payloadStart; + CLR_RT_HeapBlock_Node *end = hc->m_payloadEnd; - while(ptr < end) + while (ptr < end) { - hc->ValidateBlock( ptr ); + hc->ValidateBlock(ptr); ptr += ptr->DataSize(); } } -void CLR_RT_GarbageCollector::ValidateHeap( CLR_RT_DblLinkedList& lst ) +void CLR_RT_GarbageCollector::ValidateHeap(CLR_RT_DblLinkedList &lst) { NATIVE_PROFILE_CLR_CORE(); - NANOCLR_FOREACH_NODE(CLR_RT_HeapCluster,hc,lst) + NANOCLR_FOREACH_NODE(CLR_RT_HeapCluster, hc, lst) { - ValidateCluster( hc ); + ValidateCluster(hc); } NANOCLR_FOREACH_NODE_END(); } -void CLR_RT_GarbageCollector::ValidateBlockNotInFreeList( CLR_RT_DblLinkedList& lst, CLR_RT_HeapBlock_Node* dst ) +void CLR_RT_GarbageCollector::ValidateBlockNotInFreeList(CLR_RT_DblLinkedList &lst, CLR_RT_HeapBlock_Node *dst) { NATIVE_PROFILE_CLR_CORE(); - NANOCLR_FOREACH_NODE(CLR_RT_HeapCluster,hc,lst) + NANOCLR_FOREACH_NODE(CLR_RT_HeapCluster, hc, lst) { - NANOCLR_FOREACH_NODE(CLR_RT_HeapBlock_Node,ptr,hc->m_freeList) + NANOCLR_FOREACH_NODE(CLR_RT_HeapBlock_Node, ptr, hc->m_freeList) { - CLR_RT_HeapBlock_Node* ptrEnd = ptr + ptr->DataSize(); + CLR_RT_HeapBlock_Node *ptrEnd = ptr + ptr->DataSize(); - if(ptr <= dst && dst < ptrEnd) + if (ptr <= dst && dst < ptrEnd) { - CLR_Debug::Printf( "Pointer into free list!! %08x %08x %08x\r\n", dst, ptr, ptrEnd ); +#ifdef _WIN64 + CLR_Debug::Printf("Pointer into free list!! %I64X %I64X %I64X\r\n", dst, ptr, ptrEnd); +#else + CLR_Debug::Printf("Pointer into free list!! %08x %08x %08x\r\n", dst, ptr, ptrEnd); +#endif NANOCLR_DEBUG_STOP(); } @@ -135,22 +142,24 @@ void CLR_RT_GarbageCollector::ValidateBlockNotInFreeList( CLR_RT_DblLinkedList& NANOCLR_FOREACH_NODE_END(); } -bool CLR_RT_GarbageCollector::IsBlockInFreeList( CLR_RT_DblLinkedList& lst, CLR_RT_HeapBlock_Node* dst, bool fExact ) +bool CLR_RT_GarbageCollector::IsBlockInFreeList(CLR_RT_DblLinkedList &lst, CLR_RT_HeapBlock_Node *dst, bool fExact) { NATIVE_PROFILE_CLR_CORE(); - NANOCLR_FOREACH_NODE(CLR_RT_HeapCluster,hc,lst) + NANOCLR_FOREACH_NODE(CLR_RT_HeapCluster, hc, lst) { - NANOCLR_FOREACH_NODE(CLR_RT_HeapBlock_Node,ptr,hc->m_freeList) + NANOCLR_FOREACH_NODE(CLR_RT_HeapBlock_Node, ptr, hc->m_freeList) { - if(fExact) + if (fExact) { - if(ptr == dst) return true; + if (ptr == dst) + return true; } else { - CLR_RT_HeapBlock_Node* ptrEnd = ptr + ptr->DataSize(); + CLR_RT_HeapBlock_Node *ptrEnd = ptr + ptr->DataSize(); - if(ptr <= dst && dst < ptrEnd) return true; + if (ptr <= dst && dst < ptrEnd) + return true; } } NANOCLR_FOREACH_NODE_END(); @@ -160,12 +169,13 @@ bool CLR_RT_GarbageCollector::IsBlockInFreeList( CLR_RT_DblLinkedList& lst, CLR_ return false; } -bool CLR_RT_GarbageCollector::IsBlockInHeap( CLR_RT_DblLinkedList& lst, CLR_RT_HeapBlock_Node* dst ) +bool CLR_RT_GarbageCollector::IsBlockInHeap(CLR_RT_DblLinkedList &lst, CLR_RT_HeapBlock_Node *dst) { NATIVE_PROFILE_CLR_CORE(); - NANOCLR_FOREACH_NODE(CLR_RT_HeapCluster,hc,lst) + NANOCLR_FOREACH_NODE(CLR_RT_HeapCluster, hc, lst) { - if(hc->m_payloadStart <= dst && dst < hc->m_payloadEnd) return true; + if (hc->m_payloadStart <= dst && dst < hc->m_payloadEnd) + return true; } NANOCLR_FOREACH_NODE_END(); @@ -179,46 +189,56 @@ bool CLR_RT_GarbageCollector::IsBlockInHeap( CLR_RT_DblLinkedList& lst, CLR_RT_H #if NANOCLR_VALIDATE_HEAP >= NANOCLR_VALIDATE_HEAP_4_CompactionPlus CLR_RT_GarbageCollector::Rel_List CLR_RT_GarbageCollector::s_lstRecords; -CLR_RT_GarbageCollector::Rel_Map CLR_RT_GarbageCollector::s_mapOldToRecord; -CLR_RT_GarbageCollector::Rel_Map CLR_RT_GarbageCollector::s_mapNewToRecord; +CLR_RT_GarbageCollector::Rel_Map CLR_RT_GarbageCollector::s_mapOldToRecord; +CLR_RT_GarbageCollector::Rel_Map CLR_RT_GarbageCollector::s_mapNewToRecord; //--// -bool CLR_RT_GarbageCollector::TestPointers_PopulateOld_Worker( void** ref ) +bool CLR_RT_GarbageCollector::TestPointers_PopulateOld_Worker(void **ref) { NATIVE_PROFILE_CLR_CORE(); - CLR_UINT32* dst = (CLR_UINT32*)*ref; + CLR_UINT32 *dst = (CLR_UINT32 *)*ref; - if(dst) + if (dst) { - RelocationRecord* ptr = new RelocationRecord(); + RelocationRecord *ptr = new RelocationRecord(); - s_lstRecords.push_back( ptr ); + s_lstRecords.push_back(ptr); - ptr->oldRef = ref; - ptr->oldPtr = dst; + ptr->oldRef = ref; + ptr->oldPtr = dst; - ptr->newRef = NULL; - ptr->newPtr = NULL; + ptr->newRef = NULL; + ptr->newPtr = NULL; - ptr->data = *dst; + ptr->data = *dst; - if(s_mapOldToRecord.find( ref ) != s_mapOldToRecord.end()) + if (s_mapOldToRecord.find(ref) != s_mapOldToRecord.end()) { - CLR_Debug::Printf( "Duplicate base OLD: %08x\r\n", ref ); +#ifdef _WIN64 + CLR_Debug::Printf("Duplicate base OLD: %I64X\r\n", ref); +#else + CLR_Debug::Printf("Duplicate base OLD: %08x\r\n", ref); +#endif + + NANOCLR_DEBUG_STOP(); } - s_mapOldToRecord[ ref ] = ptr; + s_mapOldToRecord[ref] = ptr; - if(IsBlockInFreeList( g_CLR_RT_ExecutionEngine.m_heap, (CLR_RT_HeapBlock_Node*)dst, false )) + if (IsBlockInFreeList(g_CLR_RT_ExecutionEngine.m_heap, (CLR_RT_HeapBlock_Node *)dst, false)) { - CLR_Debug::Printf( "Some data points into a free list: %08x\r\n", dst ); +#ifdef _WIN64 + CLR_Debug::Printf("Some data points into a free list: %I64X\r\n", dst); +#else + CLR_Debug::Printf("Some data points into a free list: %08x\r\n", dst); +#endif NANOCLR_DEBUG_STOP(); } } - return false; + return true; } void CLR_RT_GarbageCollector::TestPointers_PopulateOld() @@ -226,26 +246,27 @@ void CLR_RT_GarbageCollector::TestPointers_PopulateOld() NATIVE_PROFILE_CLR_CORE(); Rel_List_Iter itLst; - for(itLst = s_lstRecords.begin(); itLst != s_lstRecords.end(); itLst++) + for (itLst = s_lstRecords.begin(); itLst != s_lstRecords.end(); itLst++) { - RelocationRecord* ptr = *itLst; + RelocationRecord *ptr = *itLst; delete ptr; } - s_lstRecords .clear(); + s_lstRecords.clear(); s_mapOldToRecord.clear(); s_mapNewToRecord.clear(); //--// - Heap_Relocate_Pass( TestPointers_PopulateOld_Worker ); + Heap_Relocate_Pass(TestPointers_PopulateOld_Worker); } -void CLR_RT_GarbageCollector::Relocation_UpdatePointer(void** ref) +void CLR_RT_GarbageCollector::Relocation_UpdatePointer(void **ref) { + (void)ref; + NATIVE_PROFILE_CLR_CORE(); - } //--// @@ -255,18 +276,25 @@ void CLR_RT_GarbageCollector::TestPointers_Remap() NATIVE_PROFILE_CLR_CORE(); Rel_Map_Iter it; - for(it = s_mapOldToRecord.begin(); it != s_mapOldToRecord.end(); it++) + for (it = s_mapOldToRecord.begin(); it != s_mapOldToRecord.end(); it++) { - RelocationRecord* ptr = it->second; - void** ref = it->first ; CLR_RT_GarbageCollector::Relocation_UpdatePointer( (void**)&ref ); - CLR_UINT32* dst = ptr->oldPtr; CLR_RT_GarbageCollector::Relocation_UpdatePointer( (void**)&dst ); + RelocationRecord *ptr = it->second; + void **ref = it->first; + CLR_RT_GarbageCollector::Relocation_UpdatePointer((void **)&ref); + CLR_UINT32 *dst = ptr->oldPtr; + CLR_RT_GarbageCollector::Relocation_UpdatePointer((void **)&dst); - if(s_mapNewToRecord.find( ref ) != s_mapNewToRecord.end()) + if (s_mapNewToRecord.find(ref) != s_mapNewToRecord.end()) { - CLR_Debug::Printf( "Duplicate base NEW: %08x\r\n", ref ); +#ifdef _WIN64 + CLR_Debug::Printf("Duplicate base NEW: %I64X\r\n", ref); +#else + CLR_Debug::Printf("Duplicate base NEW: %08x\r\n", ref); +#endif + NANOCLR_DEBUG_STOP(); } - s_mapNewToRecord[ ref ] = ptr; + s_mapNewToRecord[ref] = ptr; ptr->newRef = ref; ptr->newPtr = dst; @@ -275,38 +303,61 @@ void CLR_RT_GarbageCollector::TestPointers_Remap() //--// -bool CLR_RT_GarbageCollector::TestPointers_PopulateNew_Worker( void** ref ) +bool CLR_RT_GarbageCollector::TestPointers_PopulateNew_Worker(void **ref) { NATIVE_PROFILE_CLR_CORE(); - CLR_UINT32* dst = (CLR_UINT32*)*ref; + CLR_UINT32 *dst = (CLR_UINT32 *)*ref; - if(dst) + if (dst) { - Rel_Map_Iter it = s_mapNewToRecord.find( ref ); + Rel_Map_Iter it = s_mapNewToRecord.find(ref); - if(it != s_mapNewToRecord.end()) + if (it != s_mapNewToRecord.end()) { - RelocationRecord* ptr = it->second; + RelocationRecord *ptr = it->second; - if(ptr->newPtr != dst) + if (ptr->newPtr != dst) { - CLR_Debug::Printf( "Bad pointer: %08x %08x\r\n", ptr->newPtr, dst ); +#ifdef _WIN64 + CLR_Debug::Printf("Bad pointer: %I64X %I64X\r\n", ptr->newPtr, dst); +#else + CLR_Debug::Printf("Bad pointer: %08x %08x\r\n", ptr->newPtr, dst); +#endif + NANOCLR_DEBUG_STOP(); } - else if(ptr->data != *dst) + else if (ptr->data != *dst) { - CLR_Debug::Printf( "Bad data: %08x %08x\r\n", ptr->data, *dst ); +#ifdef _WIN64 + CLR_Debug::Printf("Bad data: %I64X %I64X\r\n", ptr->data, *dst); +#else + CLR_Debug::Printf("Bad data: %08x %08x\r\n", ptr->data, *dst); +#endif + + NANOCLR_DEBUG_STOP(); } - if(IsBlockInFreeList( g_CLR_RT_ExecutionEngine.m_heap, (CLR_RT_HeapBlock_Node*)dst, false )) + if (IsBlockInFreeList(g_CLR_RT_ExecutionEngine.m_heap, (CLR_RT_HeapBlock_Node *)dst, false)) { - CLR_Debug::Printf( "Some data points into a free list: %08x\r\n", dst ); +#ifdef _WIN64 + CLR_Debug::Printf("Some data points into a free list: %I64X\r\n", dst); +#else + CLR_Debug::Printf("Some data points into a free list: %08x\r\n", dst); +#endif NANOCLR_DEBUG_STOP(); } + + return true; } else { - CLR_Debug::Printf( "Bad base: %08x\r\n", ref ); +#ifdef _WIN64 + CLR_Debug::Printf("Bad base: 0x%0I64X\r\n", ref); +#else + CLR_Debug::Printf("Bad base: 0x%08x\r\n", ref); +#endif + + NANOCLR_DEBUG_STOP(); } } @@ -316,7 +367,7 @@ bool CLR_RT_GarbageCollector::TestPointers_PopulateNew_Worker( void** ref ) void CLR_RT_GarbageCollector::TestPointers_PopulateNew() { NATIVE_PROFILE_CLR_CORE(); - Heap_Relocate_Pass( TestPointers_PopulateNew_Worker ); + Heap_Relocate_Pass(TestPointers_PopulateNew_Worker); } #endif diff --git a/src/CLR/Core/Hardware/Hardware.cpp b/src/CLR/Core/Hardware/Hardware.cpp index ce78baaa1e..51ada7e929 100644 --- a/src/CLR/Core/Hardware/Hardware.cpp +++ b/src/CLR/Core/Hardware/Hardware.cpp @@ -137,7 +137,7 @@ void CLR_HW_Hardware::ProcessActivity() if ((events & SYSTEM_EVENT_HW_INTERRUPT) #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) || (!CLR_EE_DBG_IS(Stopped) && !g_CLR_HW_Hardware.m_interruptData.m_applicationQueue.IsEmpty()) -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) ) { ProcessInterrupts(); @@ -183,6 +183,16 @@ void CLR_HW_Hardware::ProcessActivity() eventsCLR |= Event_Bluetooth; } + if (events & SYSTEM_EVENT_FLAG_USB_IN) + { + eventsCLR |= Event_UsbIn; + } + + if (events & SYSTEM_EVENT_FLAG_USB_OUT) + { + eventsCLR |= Event_UsbOut; + } + if (eventsCLR) { g_CLR_RT_ExecutionEngine.SignalEvents(eventsCLR); diff --git a/src/CLR/Core/Interpreter.cpp b/src/CLR/Core/Interpreter.cpp index ee6d267962..d37cf3838b 100644 --- a/src/CLR/Core/Interpreter.cpp +++ b/src/CLR/Core/Interpreter.cpp @@ -438,7 +438,7 @@ bool CLR_RT_Thread::FindEhBlock( // processed. #if defined(NANOCLR_TRACE_EXCEPTIONS) - if (s_CLR_RT_fTrace_Exceptions >= c_CLR_RT_Trace_Annoying) + if (CLR_EE_DBG_IS_NOT(NoStackTraceInExceptions) && s_CLR_RT_fTrace_Exceptions >= c_CLR_RT_Trace_Annoying) { if (!onlyFinallys || s_CLR_RT_fTrace_Exceptions >= c_CLR_RT_Trace_Obnoxious) { @@ -497,7 +497,7 @@ bool CLR_RT_Thread::FindEhBlock( } #if defined(NANOCLR_TRACE_EXCEPTIONS) - if (s_CLR_RT_fTrace_Exceptions >= c_CLR_RT_Trace_Annoying) + if (CLR_EE_DBG_IS_NOT(NoStackTraceInExceptions) && s_CLR_RT_fTrace_Exceptions >= c_CLR_RT_Trace_Annoying) { if (to == NULL || s_CLR_RT_fTrace_Exceptions >= c_CLR_RT_Trace_Obnoxious) { @@ -534,7 +534,8 @@ bool CLR_RT_Thread::FindEhBlock( if (ptrEhExt->IsFinally() && (!to || (to < ptrEhExt->m_tryStart || to >= ptrEhExt->m_tryEnd))) { #if defined(NANOCLR_TRACE_EXCEPTIONS) - if (s_CLR_RT_fTrace_Exceptions >= c_CLR_RT_Trace_Obnoxious) + if (CLR_EE_DBG_IS_NOT(NoStackTraceInExceptions) && + s_CLR_RT_fTrace_Exceptions >= c_CLR_RT_Trace_Obnoxious) { CLR_Debug::Printf("Found match for a 'finally'\r\n"); } @@ -549,7 +550,8 @@ bool CLR_RT_Thread::FindEhBlock( if (ptrEhExt->IsCatchAll()) { #if defined(NANOCLR_TRACE_EXCEPTIONS) - if (s_CLR_RT_fTrace_Exceptions >= c_CLR_RT_Trace_Annoying) + if (CLR_EE_DBG_IS_NOT(NoStackTraceInExceptions) && + s_CLR_RT_fTrace_Exceptions >= c_CLR_RT_Trace_Annoying) { CLR_Debug::Printf("Found match for a 'catch all'\r\n"); } @@ -564,7 +566,8 @@ bool CLR_RT_Thread::FindEhBlock( CLR_RT_ExecutionEngine::IsInstanceOf(m_currentException, ptrEhExt->m_typeFilter)) { #if defined(NANOCLR_TRACE_EXCEPTIONS) - if (s_CLR_RT_fTrace_Exceptions >= c_CLR_RT_Trace_Annoying) + if (CLR_EE_DBG_IS_NOT(NoStackTraceInExceptions) && + s_CLR_RT_fTrace_Exceptions >= c_CLR_RT_Trace_Annoying) { if (ptrEhExt->IsFilter()) { @@ -589,7 +592,7 @@ bool CLR_RT_Thread::FindEhBlock( } #if defined(NANOCLR_TRACE_EXCEPTIONS) - if (s_CLR_RT_fTrace_Exceptions >= c_CLR_RT_Trace_Annoying) + if (CLR_EE_DBG_IS_NOT(NoStackTraceInExceptions) && s_CLR_RT_fTrace_Exceptions >= c_CLR_RT_Trace_Annoying) { if (to == NULL || s_CLR_RT_fTrace_Exceptions >= c_CLR_RT_Trace_Obnoxious) { @@ -629,7 +632,7 @@ HRESULT CLR_RT_Thread::Execute() #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) _ASSERTE(!CLR_EE_DBG_IS(Stopped)); -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) ::Events_SetBoolTimer((bool *)&m_timeQuantumExpired, CLR_RT_Thread::c_TimeQuantum_Milliseconds); @@ -690,14 +693,14 @@ HRESULT CLR_RT_Thread::Execute() #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) if (CLR_EE_DBG_IS(Stopped)) break; -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) NANOCLR_CHECK_HRESULT(ProcessException()); #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) if (CLR_EE_DBG_IS(Stopped)) break; -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) if (m_currentException.Dereference() != NULL) { @@ -750,7 +753,7 @@ HRESULT CLR_RT_Thread::Execute_Inner() { NANOCLR_SET_AND_LEAVE(CLR_E_FAIL); } -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) // // Thread cannot run if a lock request is still pending... @@ -858,8 +861,12 @@ HRESULT CLR_RT_Thread::Execute_Inner() if (hr == CLR_E_OUT_OF_MEMORY && (stack->m_flags & CLR_RT_StackFrame::c_CompactAndRestartOnOutOfMemory)) { + // if we have an out of memory exception, perform a compaction and restart stack->m_flags &= ~CLR_RT_StackFrame::c_CompactAndRestartOnOutOfMemory; +#if defined(NANOCLR_GC_VERBOSE) + CLR_Debug::Printf("\r\nGoing for heap compaction and restart.\r\n\r\n"); +#endif g_CLR_RT_ExecutionEngine.PerformHeapCompaction(); } else @@ -1002,10 +1009,10 @@ HRESULT CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame &stackArg) { NANOCLR_SET_AND_LEAVE(CLR_S_QUANTUM_EXPIRED); } -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) #if defined(NANOCLR_TRACE_EXCEPTIONS) && defined(VIRTUAL_DEVICE) - if (s_CLR_RT_fTrace_Exceptions >= c_CLR_RT_Trace_Annoying) + if (CLR_EE_DBG_IS_NOT(NoStackTraceInExceptions) && s_CLR_RT_fTrace_Exceptions >= c_CLR_RT_Trace_Annoying) { CLR_PROF_HANDLER_SUSPEND_TIME(); @@ -2782,6 +2789,11 @@ HRESULT CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame &stackArg) // if we have an out of memory exception, perform a compaction and try again. if (hr == CLR_E_OUT_OF_MEMORY && pass == 0) { +#if defined(NANOCLR_GC_VERBOSE) + CLR_Debug::Printf( + "\r\nGoing for heap compaction and trying to create array again.\r\n\r\n"); +#endif + WRITEBACK(stack, evalPos, ip, fDirty); g_CLR_RT_ExecutionEngine.PerformHeapCompaction(); READCACHE(stack, evalPos, ip, fDirty); @@ -3424,7 +3436,7 @@ HRESULT CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame &stackArg) { g_CLR_RT_ExecutionEngine.Breakpoint_StackFrame_Step(stack, ip); } -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) continue; @@ -3506,7 +3518,7 @@ HRESULT CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame &stackArg) { g_CLR_RT_ExecutionEngine.Breakpoint_StackFrame_Step(stack, ip); } -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) continue; //--// @@ -3532,7 +3544,7 @@ HRESULT CLR_RT_Thread::Execute_IL(CLR_RT_StackFrame &stackArg) { g_CLR_RT_ExecutionEngine.Breakpoint_StackFrame_Step(stack, ip); } -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) if (th->m_timeQuantumExpired) { diff --git a/src/CLR/Core/NativeEventDispatcher/NativeEventDispatcher.cpp b/src/CLR/Core/NativeEventDispatcher/NativeEventDispatcher.cpp index bb3dca4e8d..58289fc881 100644 --- a/src/CLR/Core/NativeEventDispatcher/NativeEventDispatcher.cpp +++ b/src/CLR/Core/NativeEventDispatcher/NativeEventDispatcher.cpp @@ -9,7 +9,7 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// -CLR_RT_DblLinkedList CLR_RT_HeapBlock_NativeEventDispatcher::eventList; +CLR_RT_DblLinkedList CLR_RT_HeapBlock_NativeEventDispatcher::eventList; void CLR_RT_HeapBlock_NativeEventDispatcher::HandlerMethod_Initialize() { @@ -22,7 +22,10 @@ void CLR_RT_HeapBlock_NativeEventDispatcher::HandlerMethod_RecoverFromGC() { NATIVE_PROFILE_CLR_IOPORT(); - NANOCLR_FOREACH_NODE(CLR_RT_HeapBlock_NativeEventDispatcher, event, CLR_RT_HeapBlock_NativeEventDispatcher::eventList) + NANOCLR_FOREACH_NODE( + CLR_RT_HeapBlock_NativeEventDispatcher, + event, + CLR_RT_HeapBlock_NativeEventDispatcher::eventList) { event->RecoverFromGC(); } @@ -33,11 +36,12 @@ void CLR_RT_HeapBlock_NativeEventDispatcher::HandlerMethod_CleanUp() { NATIVE_PROFILE_CLR_IOPORT(); - CLR_RT_HeapBlock_NativeEventDispatcher* event; + CLR_RT_HeapBlock_NativeEventDispatcher *event; - while(NULL != (event = (CLR_RT_HeapBlock_NativeEventDispatcher*)CLR_RT_HeapBlock_NativeEventDispatcher::eventList.FirstValidNode())) + while (NULL != (event = (CLR_RT_HeapBlock_NativeEventDispatcher *) + CLR_RT_HeapBlock_NativeEventDispatcher::eventList.FirstValidNode())) { - if(event->driverMethods != NULL) + if (event->driverMethods != NULL) { event->driverMethods->cleanupProcessor(event); } @@ -47,37 +51,38 @@ void CLR_RT_HeapBlock_NativeEventDispatcher::HandlerMethod_CleanUp() } } -HRESULT CLR_RT_HeapBlock_NativeEventDispatcher::CreateInstance( CLR_RT_HeapBlock& owner, CLR_RT_HeapBlock& eventRef ) +HRESULT CLR_RT_HeapBlock_NativeEventDispatcher::CreateInstance(CLR_RT_HeapBlock &owner, CLR_RT_HeapBlock &eventRef) { NATIVE_PROFILE_CLR_IOPORT(); NANOCLR_HEADER(); - CLR_RT_HeapBlock_NativeEventDispatcher* event = NULL; - - event = EVENTCACHE_EXTRACT_NODE(g_CLR_RT_EventCache,CLR_RT_HeapBlock_NativeEventDispatcher,DATATYPE_IO_PORT); CHECK_ALLOCATION(event); - + CLR_RT_HeapBlock_NativeEventDispatcher *event = NULL; + + event = EVENTCACHE_EXTRACT_NODE(g_CLR_RT_EventCache, CLR_RT_HeapBlock_NativeEventDispatcher, DATATYPE_IO_PORT); + CHECK_ALLOCATION(event); + { - - CLR_RT_ProtectFromGC gc( *event ); - + + CLR_RT_ProtectFromGC gc(*event); + event->Initialize(); - eventList.LinkAtBack( event ); - - NANOCLR_CHECK_HRESULT(CLR_RT_ObjectToEvent_Source::CreateInstance( event, owner, eventRef )); - - } + eventList.LinkAtBack(event); + + NANOCLR_CHECK_HRESULT(CLR_RT_ObjectToEvent_Source::CreateInstance(event, owner, eventRef)); + } - // Set pointer to driver custom data to NULL. It initialized later by users of CLR_RT_HeapBlock_NativeEventDispatcher + // Set pointer to driver custom data to NULL. It initialized later by users of + // CLR_RT_HeapBlock_NativeEventDispatcher event->pDrvCustomData = NULL; // Set pointers to drivers methods to NULL. - event->driverMethods = NULL; + event->driverMethods = NULL; NANOCLR_CLEANUP(); - if(FAILED(hr)) + if (FAILED(hr)) { - if(event) + if (event) { event->ReleaseWhenDead(); } @@ -86,15 +91,18 @@ HRESULT CLR_RT_HeapBlock_NativeEventDispatcher::CreateInstance( CLR_RT_HeapBlock NANOCLR_CLEANUP_END(); } -HRESULT CLR_RT_HeapBlock_NativeEventDispatcher::ExtractInstance( CLR_RT_HeapBlock& ref, CLR_RT_HeapBlock_NativeEventDispatcher*& event ) +HRESULT CLR_RT_HeapBlock_NativeEventDispatcher::ExtractInstance( + CLR_RT_HeapBlock &ref, + CLR_RT_HeapBlock_NativeEventDispatcher *&event) { NATIVE_PROFILE_CLR_IOPORT(); NANOCLR_HEADER(); - CLR_RT_ObjectToEvent_Source* src = CLR_RT_ObjectToEvent_Source::ExtractInstance( ref ); FAULT_ON_NULL(src); + CLR_RT_ObjectToEvent_Source *src = CLR_RT_ObjectToEvent_Source::ExtractInstance(ref); + FAULT_ON_NULL(src); - event = (CLR_RT_HeapBlock_NativeEventDispatcher*)src->m_eventPtr; + event = (CLR_RT_HeapBlock_NativeEventDispatcher *)src->m_eventPtr; NANOCLR_NOCLEANUP(); } @@ -112,18 +120,19 @@ bool CLR_RT_HeapBlock_NativeEventDispatcher::ReleaseWhenDeadEx() { NATIVE_PROFILE_CLR_IOPORT(); - if(!IsReadyForRelease()) return false; + if (!IsReadyForRelease()) + return false; - //remove any queued interrupts for this event - NANOCLR_FOREACH_NODE(CLR_RT_ApplicationInterrupt,interrupt,g_CLR_HW_Hardware.m_interruptData.m_applicationQueue) + // remove any queued interrupts for this event + NANOCLR_FOREACH_NODE(CLR_RT_ApplicationInterrupt, interrupt, g_CLR_HW_Hardware.m_interruptData.m_applicationQueue) { - if(this == interrupt->m_interruptPortInterrupt.context) + if (this == interrupt->m_interruptPortInterrupt.context) { interrupt->Unlink(); --g_CLR_HW_Hardware.m_interruptData.m_queuedInterrupts; - ThreadTerminationCallback( interrupt ); + ThreadTerminationCallback(interrupt); } } NANOCLR_FOREACH_NODE_END(); @@ -141,94 +150,99 @@ void CLR_RT_HeapBlock_NativeEventDispatcher::RemoveFromHALQueue() { // Since we are going to analyze and update the queue we need to disable interrupts. // Interrupt service routines add records to this queue. - CLR_UINT32 elemCount = 0; - GLOBAL_LOCK(); + size_t elemCount = 0; + GLOBAL_LOCK(); + elemCount = g_CLR_HW_Hardware.m_interruptData.m_HalQueue.NumberOfElements(); GLOBAL_UNLOCK(); // For all elements in the queue - for ( CLR_UINT32 curElem = 0; curElem < elemCount; curElem++ ) + for (CLR_UINT32 curElem = 0; curElem < elemCount; curElem++) { // Retrieve the element ( actually remove it from the queue ) - CLR_HW_Hardware::HalInterruptRecord* testRec = NULL; + CLR_HW_Hardware::HalInterruptRecord *testRec = NULL; GLOBAL_LOCK(); testRec = g_CLR_HW_Hardware.m_interruptData.m_HalQueue.Pop(); GLOBAL_UNLOCK(); - + // Check if context of this record points to the instance of CLR_RT_HeapBlock_NativeEventDispatcher // If the "context" is the same as "this", then we skip the "Push" and record is removed. - if ( testRec->m_context != this ) + if (testRec->m_context != this) { // If it is different from this instance of CLR_RT_HeapBlock_NativeEventDispatcher, thin push it back - CLR_HW_Hardware::HalInterruptRecord* newRec = NULL; - GLOBAL_LOCK(); + CLR_HW_Hardware::HalInterruptRecord *newRec = NULL; + GLOBAL_LOCK(); newRec = g_CLR_HW_Hardware.m_interruptData.m_HalQueue.Push(); GLOBAL_UNLOCK(); - newRec->AssignFrom( *testRec ); + newRec->AssignFrom(*testRec); } } } -void CLR_RT_HeapBlock_NativeEventDispatcher::SaveToHALQueue( uint32_t data1, uint32_t data2 ) +void CLR_RT_HeapBlock_NativeEventDispatcher::SaveToHALQueue(uint32_t data1, uint32_t data2) { NATIVE_PROFILE_CLR_IOPORT(); - CLR_HW_Hardware::HalInterruptRecord* rec = g_CLR_HW_Hardware.m_interruptData.m_HalQueue.Push(); + CLR_HW_Hardware::HalInterruptRecord *rec = g_CLR_HW_Hardware.m_interruptData.m_HalQueue.Push(); - if(rec == NULL) + if (rec == NULL) { // remove the oldest interrupt to make room for the newest g_CLR_HW_Hardware.m_interruptData.m_HalQueue.Pop(); - + rec = g_CLR_HW_Hardware.m_interruptData.m_HalQueue.Push(); } - - if(rec) + + if (rec) { - rec->m_data1 = data1; - rec->m_data2 = data2; + rec->m_data1 = data1; + rec->m_data2 = data2; rec->m_context = this; - rec->m_time = HAL_Time_CurrentTime(); + rec->m_time = HAL_Time_CurrentTime(); } - ::Events_Set( SYSTEM_EVENT_HW_INTERRUPT ); + ::Events_Set(SYSTEM_EVENT_HW_INTERRUPT); } -void SaveNativeEventToHALQueue( CLR_RT_HeapBlock_NativeEventDispatcher *pContext, uint32_t data1, uint32_t data2 ) +void SaveNativeEventToHALQueue(CLR_RT_HeapBlock_NativeEventDispatcher *pContext, uint32_t data1, uint32_t data2) { - pContext->SaveToHALQueue( data1, data2 ); + pContext->SaveToHALQueue(data1, data2); } -void CleanupNativeEventsFromHALQueue( CLR_RT_HeapBlock_NativeEventDispatcher *pContext ) +void CleanupNativeEventsFromHALQueue(CLR_RT_HeapBlock_NativeEventDispatcher *pContext) { pContext->RemoveFromHALQueue(); } -HRESULT CLR_RT_HeapBlock_NativeEventDispatcher::StartDispatch( CLR_RT_ApplicationInterrupt* appInterrupt, CLR_RT_Thread* th ) +HRESULT CLR_RT_HeapBlock_NativeEventDispatcher::StartDispatch( + CLR_RT_ApplicationInterrupt *appInterrupt, + CLR_RT_Thread *th) { NATIVE_PROFILE_CLR_IOPORT(); NANOCLR_HEADER(); - CLR_RT_StackFrame* stackTop; - CLR_RT_HeapBlock* args; - CLR_RT_HeapBlock_Delegate* dlg; - CLR_RT_HeapBlock* event; + CLR_RT_StackFrame *stackTop; + CLR_RT_HeapBlock *args; + CLR_RT_HeapBlock_Delegate *dlg; + CLR_RT_HeapBlock *event; const CLR_UINT64 c_UTCMask = 0x8000000000000000ULL; - InterruptPortInterrupt& interrupt = appInterrupt->m_interruptPortInterrupt; + InterruptPortInterrupt &interrupt = appInterrupt->m_interruptPortInterrupt; - NANOCLR_CHECK_HRESULT(RecoverManagedObject( event )); - dlg = event[ Library_nf_rt_events_native_nanoFramework_Runtime_Events_NativeEventDispatcher::FIELD__threadSpawn ].DereferenceDelegate(); FAULT_ON_NULL(dlg); + NANOCLR_CHECK_HRESULT(RecoverManagedObject(event)); + dlg = event[Library_nf_rt_events_native_nanoFramework_Runtime_Events_NativeEventDispatcher::FIELD__threadSpawn] + .DereferenceDelegate(); + FAULT_ON_NULL(dlg); - NANOCLR_CHECK_HRESULT(th->PushThreadProcDelegate( dlg )); + NANOCLR_CHECK_HRESULT(th->PushThreadProcDelegate(dlg)); stackTop = th->CurrentFrame(); args = stackTop->m_arguments; - if((stackTop->m_call.m_target->flags & CLR_RECORD_METHODDEF::MD_Static) == 0) + if ((stackTop->m_call.m_target->flags & CLR_RECORD_METHODDEF::MD_Static) == 0) { ++args; } @@ -236,47 +250,48 @@ HRESULT CLR_RT_HeapBlock_NativeEventDispatcher::StartDispatch( CLR_RT_Applicatio // // set values for delegate arguments // - args[0].SetInteger ( interrupt.data1 ); - args[1].SetInteger ( interrupt.data2 ); - args[2].SetInteger ( (CLR_UINT64)interrupt.time | c_UTCMask ); - args[2].ChangeDataType( DATATYPE_DATETIME ); - - th->m_terminationCallback = CLR_RT_HeapBlock_NativeEventDispatcher::ThreadTerminationCallback; + args[0].SetInteger(interrupt.data1); + args[1].SetInteger(interrupt.data2); + args[2].SetInteger((CLR_UINT64)interrupt.time | c_UTCMask); + args[2].ChangeDataType(DATATYPE_DATETIME); + + th->m_terminationCallback = CLR_RT_HeapBlock_NativeEventDispatcher::ThreadTerminationCallback; th->m_terminationParameter = appInterrupt; NANOCLR_NOCLEANUP(); } -void CLR_RT_HeapBlock_NativeEventDispatcher::ThreadTerminationCallback( void* arg ) +void CLR_RT_HeapBlock_NativeEventDispatcher::ThreadTerminationCallback(void *arg) { NATIVE_PROFILE_CLR_IOPORT(); - CLR_RT_ApplicationInterrupt* appInterrupt = (CLR_RT_ApplicationInterrupt*)arg; - CLR_RT_HeapBlock_NativeEventDispatcher::InterruptPortInterrupt& interrupt = appInterrupt->m_interruptPortInterrupt; + CLR_RT_ApplicationInterrupt *appInterrupt = (CLR_RT_ApplicationInterrupt *)arg; + CLR_RT_HeapBlock_NativeEventDispatcher::InterruptPortInterrupt &interrupt = appInterrupt->m_interruptPortInterrupt; - FreeManagedEvent((interrupt.data1 >> 8) & 0xff, //category - (interrupt.data1 ) & 0xff, //subCategory - interrupt.data1 >> 16 , //data1 - interrupt.data2 ); + FreeManagedEvent( + (interrupt.data1 >> 8) & 0xff, // category + (interrupt.data1) & 0xff, // subCategory + interrupt.data1 >> 16, // data1 + interrupt.data2); interrupt.data1 = 0; interrupt.data2 = 0; - CLR_RT_Memory::Release( appInterrupt ); + CLR_RT_Memory::Release(appInterrupt); g_CLR_HW_Hardware.SpawnDispatcher(); } -HRESULT CLR_RT_HeapBlock_NativeEventDispatcher::RecoverManagedObject( CLR_RT_HeapBlock*& event ) +HRESULT CLR_RT_HeapBlock_NativeEventDispatcher::RecoverManagedObject(CLR_RT_HeapBlock *&event) { NATIVE_PROFILE_CLR_IOPORT(); NANOCLR_HEADER(); // recover the managed object - NANOCLR_FOREACH_NODE(CLR_RT_ObjectToEvent_Source,ref,this->m_references) + NANOCLR_FOREACH_NODE(CLR_RT_ObjectToEvent_Source, ref, this->m_references) { - if(ref->m_objectPtr) + if (ref->m_objectPtr) { event = ref->m_objectPtr; NANOCLR_SET_AND_LEAVE(S_OK); diff --git a/src/CLR/Core/Thread.cpp b/src/CLR/Core/Thread.cpp index 18c4fd4467..133bab8caa 100644 --- a/src/CLR/Core/Thread.cpp +++ b/src/CLR/Core/Thread.cpp @@ -249,7 +249,7 @@ HRESULT CLR_RT_Thread::CreateInstance(int pid, int priority, CLR_RT_Thread *&th, // If debugger creates managed thread for function evaluation, then m_realThread points to the thread that has // focus in debugger th->m_realThread = th; // CLR_RT_Thread* m_realThread -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) //--// @@ -263,7 +263,7 @@ HRESULT CLR_RT_Thread::CreateInstance(int pid, int priority, CLR_RT_Thread *&th, // g_CLR_RT_ExecutionEngine.Breakpoint_Thread_Created(th); } -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) } NANOCLR_NOCLEANUP(); @@ -449,7 +449,7 @@ void CLR_RT_Thread::OnThreadTerminated() { g_CLR_RT_ExecutionEngine.Breakpoint_Thread_Terminated(this); } -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) } void CLR_RT_Thread::Passivate() @@ -610,6 +610,10 @@ HRESULT CLR_RT_Thread::ProcessException_EndFilter() NATIVE_PROFILE_CLR_CORE(); NANOCLR_HEADER(); +#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) + bool fBreakpointsDisabledSav = false; +#endif + CLR_RT_StackFrame *stack = CurrentFrame(); CLR_INT32 choice = stack->PopValue().NumericByRef().s4; @@ -621,30 +625,37 @@ HRESULT CLR_RT_Thread::ProcessException_EndFilter() us.m_stack = NULL; #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) - // We don't want to send any breakpoints until after we set the IP appropriately - bool fBreakpointsDisabledSav = CLR_EE_DBG_IS(BreakpointsDisabled); - CLR_EE_DBG_SET(BreakpointsDisabled); -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) + if (CLR_EE_DBG_IS_NOT(NoStackTraceInExceptions)) + { + // We don't want to send any breakpoints until after we set the IP appropriately + fBreakpointsDisabledSav = CLR_EE_DBG_IS(BreakpointsDisabled); + CLR_EE_DBG_SET(BreakpointsDisabled); + } +#endif stack->Pop(); #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) - if (!fBreakpointsDisabledSav) + if (CLR_EE_DBG_IS_NOT(NoStackTraceInExceptions) && !fBreakpointsDisabledSav) { CLR_EE_DBG_CLR(BreakpointsDisabled); } -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif if (choice == 1) { // The filter signaled that it will handle this exception. Update the phase state us.SetPhase(UnwindStack::p_2_RunningFinallys_0); + #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) - g_CLR_RT_ExecutionEngine.Breakpoint_Exception( - us.m_handlerStack, - CLR_DBG_Commands::Debugging_Execution_BreakpointDef::c_DEPTH_EXCEPTION_HANDLER_FOUND, - us.m_handlerBlockStart); -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) + if (CLR_EE_DBG_IS_NOT(NoStackTraceInExceptions)) + { + g_CLR_RT_ExecutionEngine.Breakpoint_Exception( + us.m_handlerStack, + CLR_DBG_Commands::Debugging_Execution_BreakpointDef::c_DEPTH_EXCEPTION_HANDLER_FOUND, + us.m_handlerBlockStart); + } +#endif } else { @@ -657,13 +668,13 @@ HRESULT CLR_RT_Thread::ProcessException_EndFilter() #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) // We must stop if we sent out a Catch Handler found message. - if (CLR_EE_DBG_IS(Stopped)) + if (CLR_EE_DBG_IS_NOT(NoStackTraceInExceptions) && CLR_EE_DBG_IS(Stopped)) { // If the debugger stopped because of the messages we sent, then we should break out of Execute_IL, drop down, // and wait for the debugger to continue. m_currentException.SetObjectReference(us.m_exception); NANOCLR_SET_AND_LEAVE(CLR_E_PROCESS_EXCEPTION); } -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif (void)ProcessException(); @@ -718,11 +729,11 @@ HRESULT CLR_RT_Thread::ProcessException_EndFinally() } #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) - if (stack->m_flags & CLR_RT_StackFrame::c_HasBreakpoint) + if (CLR_EE_DBG_IS_NOT(NoStackTraceInExceptions) && stack->m_flags & CLR_RT_StackFrame::c_HasBreakpoint) { g_CLR_RT_ExecutionEngine.Breakpoint_StackFrame_Step(stack, stack->m_IP); } -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif NANOCLR_SET_AND_LEAVE(S_OK); } @@ -758,6 +769,10 @@ HRESULT CLR_RT_Thread::ProcessException_Phase1() NATIVE_PROFILE_CLR_CORE(); NANOCLR_HEADER(); +#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) + bool fBreakpointsDisabledSav = false; +#endif + // Load the UnwindStack entry to process, as created/loaded by ProcessException UnwindStack &us = m_nestedExceptions[m_nestedExceptionsPos - 1]; @@ -781,10 +796,12 @@ HRESULT CLR_RT_Thread::ProcessException_Phase1() // Search for a willing catch handler. while (stack->Caller() != NULL) { + #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) - if (g_CLR_RT_ExecutionEngine.m_breakpointsNum && + if (CLR_EE_DBG_IS_NOT(NoStackTraceInExceptions) && g_CLR_RT_ExecutionEngine.m_breakpointsNum && us.GetPhase() < UnwindStack::p_1_SearchingForHandler_2_SentUsersChance && stack->m_IP) - { // We have a debugger attached and we need to send some messages before we start searching. + { + // We have a debugger attached and we need to send some messages before we start searching. // These messages should only get sent when the search reaches managed code. Stack::Push sets m_IP to NULL // for native code, so therefore we need IP to be non-NULL @@ -821,7 +838,7 @@ HRESULT CLR_RT_Thread::ProcessException_Phase1() } } } -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) if (stack->m_call.m_target->flags & CLR_RECORD_METHODDEF::MD_HasExceptionHandlers) { @@ -869,19 +886,22 @@ HRESULT CLR_RT_Thread::ProcessException_Phase1() CLR_UINT8 numArgs = stack->m_call.m_target->numArgs; #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) - // We don't want to send any breakpoints until after we set the IP appropriately - bool fBreakpointsDisabledSav = CLR_EE_DBG_IS(BreakpointsDisabled); - CLR_EE_DBG_SET(BreakpointsDisabled); -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) + if (CLR_EE_DBG_IS_NOT(NoStackTraceInExceptions)) + { + // We don't want to send any breakpoints until after we set the IP appropriately + fBreakpointsDisabledSav = CLR_EE_DBG_IS(BreakpointsDisabled); + CLR_EE_DBG_SET(BreakpointsDisabled); + } +#endif hr = CLR_RT_StackFrame::Push(stack->m_owningThread, stack->m_call, numArgs); #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) - if (!fBreakpointsDisabledSav) + if (CLR_EE_DBG_IS_NOT(NoStackTraceInExceptions) && !fBreakpointsDisabledSav) { CLR_EE_DBG_CLR(BreakpointsDisabled); } -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif if (FAILED(hr)) { // We probably ran out of memory. In either case, don't run this handler. @@ -918,11 +938,13 @@ HRESULT CLR_RT_Thread::ProcessException_Phase1() m_currentException.SetObjectReference(NULL); #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) - g_CLR_RT_ExecutionEngine.Breakpoint_StackFrame_Push( - newStack, - CLR_DBG_Commands::Debugging_Execution_BreakpointDef::c_DEPTH_STEP_INTERCEPT); -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) - + if (CLR_EE_DBG_IS_NOT(NoStackTraceInExceptions)) + { + g_CLR_RT_ExecutionEngine.Breakpoint_StackFrame_Push( + newStack, + CLR_DBG_Commands::Debugging_Execution_BreakpointDef::c_DEPTH_STEP_INTERCEPT); + } +#endif // Return a success value to break out of ProcessException and to signal that execution of IL // can continue. NANOCLR_SET_AND_LEAVE(S_OK); @@ -933,7 +955,7 @@ HRESULT CLR_RT_Thread::ProcessException_Phase1() us.SetPhase(UnwindStack::p_2_RunningFinallys_0); #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) - if (g_CLR_RT_ExecutionEngine.m_breakpointsNum) + if (CLR_EE_DBG_IS_NOT(NoStackTraceInExceptions) && g_CLR_RT_ExecutionEngine.m_breakpointsNum) { g_CLR_RT_ExecutionEngine.Breakpoint_Exception( stack, @@ -944,7 +966,7 @@ HRESULT CLR_RT_Thread::ProcessException_Phase1() goto ContinueAndExit; } } -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // We want to continue running EH "goo" code so leave m_currentException set and return // PROCESS_EXCEPTION @@ -963,7 +985,7 @@ HRESULT CLR_RT_Thread::ProcessException_Phase1() us.SetPhase(UnwindStack::p_2_RunningFinallys_0); #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) - if (g_CLR_RT_ExecutionEngine.m_breakpointsNum) + if (CLR_EE_DBG_IS_NOT(NoStackTraceInExceptions) && g_CLR_RT_ExecutionEngine.m_breakpointsNum) { // Send the IP offset -1 for a catch handler in the case of an appdomain transition to mimic the // desktop. @@ -976,7 +998,7 @@ HRESULT CLR_RT_Thread::ProcessException_Phase1() goto ContinueAndExit; } } -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif NANOCLR_SET_AND_LEAVE(CLR_E_PROCESS_EXCEPTION); } @@ -1012,7 +1034,7 @@ HRESULT CLR_RT_Thread::ProcessException_Phase1() us.SetPhase(UnwindStack::p_2_RunningFinallys_0); #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) - if (g_CLR_RT_ExecutionEngine.m_breakpointsNum) + if (CLR_EE_DBG_IS_NOT(NoStackTraceInExceptions) && g_CLR_RT_ExecutionEngine.m_breakpointsNum) { g_CLR_RT_ExecutionEngine.Breakpoint_Exception_Uncaught(this); if (CLR_EE_DBG_IS(Stopped)) @@ -1020,14 +1042,14 @@ HRESULT CLR_RT_Thread::ProcessException_Phase1() goto ContinueAndExit; } } -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // We want to continue running EH "goo" code so leave m_currentException set and return PROCESS_EXCEPTION NANOCLR_SET_AND_LEAVE(CLR_E_PROCESS_EXCEPTION); #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) ContinueAndExit: -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) // There are multiple cases where we want to break out of this function, send debug messages, and then resume // exactly where we were. All of those cases jump to here. However, there are cases where we may be stopped but we @@ -1053,10 +1075,12 @@ HRESULT CLR_RT_Thread::ProcessException_Phase2() NATIVE_PROFILE_CLR_CORE(); NANOCLR_HEADER(); - /* - * Start running through the stack frames, running all finally handlers and popping them off until - * we hit our target catch handler, if any. - */ +#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) + bool fBreakpointsDisabledSav = false; +#endif + + // Start running through the stack frames, running all finally handlers and popping them off until we hit our target + // catch handler, if any. UnwindStack &us = m_nestedExceptions[m_nestedExceptionsPos - 1]; @@ -1067,9 +1091,10 @@ HRESULT CLR_RT_Thread::ProcessException_Phase2() // Unwind the stack, running finally's as we go while (iterStack->Caller() != NULL) { + #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) - if (g_CLR_RT_ExecutionEngine.m_breakpointsNum && iterStack == us.m_handlerStack && - (us.m_flags & UnwindStack::c_MagicCatchForInteceptedException) != 0) + if (CLR_EE_DBG_IS_NOT(NoStackTraceInExceptions) && g_CLR_RT_ExecutionEngine.m_breakpointsNum && + iterStack == us.m_handlerStack && (us.m_flags & UnwindStack::c_MagicCatchForInteceptedException) != 0) { // We've reached the frame we want to "handle" this exception. However, since the handler doesn't really // exist, we want to remove the UnwindStack entry. @@ -1089,11 +1114,12 @@ HRESULT CLR_RT_Thread::ProcessException_Phase2() NANOCLR_SET_AND_LEAVE(S_OK); } else -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif + { if (iterStack->m_call.m_target->flags & CLR_RECORD_METHODDEF::MD_HasExceptionHandlers) { - if (iterStack - ->m_IP) // No IP? Either out of memory during allocation of iterStack frame or native method. + // No IP? Either out of memory during allocation of iterStack frame or native method. + if (iterStack->m_IP) { // handlerBlockStart is used to not execute finally's who's protected blocks contain the handler // itself. NULL is used when we're not in the handler stack frame to make it work in the case of @@ -1120,13 +1146,16 @@ HRESULT CLR_RT_Thread::ProcessException_Phase2() iterStack->m_flags &= ~CLR_RT_StackFrame::c_InvalidIP; #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) + if (CLR_EE_DBG_IS_NOT(NoStackTraceInExceptions)) + { #ifndef NANOCLR_NO_IL_INLINE - if (iterStack->m_inlineFrame == NULL) + if (iterStack->m_inlineFrame == NULL) #endif - { - g_CLR_RT_ExecutionEngine.Breakpoint_StackFrame_Pop(iterStack, true); + { + g_CLR_RT_ExecutionEngine.Breakpoint_StackFrame_Pop(iterStack, true); + } } -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif NANOCLR_SET_AND_LEAVE(S_OK); } @@ -1157,13 +1186,16 @@ HRESULT CLR_RT_Thread::ProcessException_Phase2() m_currentException.SetObjectReference(NULL); #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) + if (CLR_EE_DBG_IS_NOT(NoStackTraceInExceptions)) + { #ifndef NANOCLR_NO_IL_INLINE - if (iterStack->m_inlineFrame == NULL) + if (iterStack->m_inlineFrame == NULL) #endif - { - g_CLR_RT_ExecutionEngine.Breakpoint_StackFrame_Pop(iterStack, true); + { + g_CLR_RT_ExecutionEngine.Breakpoint_StackFrame_Pop(iterStack, true); + } } -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // Return a success value to break out of ProcessException and to signal that execution of // IL can continue. @@ -1172,6 +1204,7 @@ HRESULT CLR_RT_Thread::ProcessException_Phase2() } } } + } // We didn't find a finally block at this level... // Check to see if we trickled up to a pseudoiterStack frame that we created to execute a filter handler: @@ -1196,19 +1229,22 @@ HRESULT CLR_RT_Thread::ProcessException_Phase2() otherUnwindStack.m_stack = NULL; // Prevent Pop from taking this handler off the stack. #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) - // We don't want to send any breakpoints until after we set the IP appropriately - bool fBreakpointsDisabledSav = CLR_EE_DBG_IS(BreakpointsDisabled); - CLR_EE_DBG_SET(BreakpointsDisabled); -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) + if (CLR_EE_DBG_IS_NOT(NoStackTraceInExceptions)) + { + // We don't want to send any breakpoints until after we set the IP appropriately + fBreakpointsDisabledSav = CLR_EE_DBG_IS(BreakpointsDisabled); + CLR_EE_DBG_SET(BreakpointsDisabled); + } +#endif iterStack->Pop(); // No finally's for the current ip in this method, pop to the next. #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) - if (!fBreakpointsDisabledSav) + if (CLR_EE_DBG_IS_NOT(NoStackTraceInExceptions) && !fBreakpointsDisabledSav) { CLR_EE_DBG_CLR(BreakpointsDisabled); } -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif m_currentException.SetObjectReference(otherUnwindStack.m_exception); // Drop current exception, use old one. @@ -1232,9 +1268,12 @@ HRESULT CLR_RT_Thread::ProcessException_Phase2() m_nestedExceptionsPos--; // Take off the pseudo-handler #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) - bool fBreakpointsDisabledSav = CLR_EE_DBG_IS(BreakpointsDisabled); - CLR_EE_DBG_SET(BreakpointsDisabled); -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) + if (CLR_EE_DBG_IS_NOT(NoStackTraceInExceptions)) + { + fBreakpointsDisabledSav = CLR_EE_DBG_IS(BreakpointsDisabled); + CLR_EE_DBG_SET(BreakpointsDisabled); + } +#endif #ifndef NANOCLR_NO_IL_INLINE if (iterStack->m_inlineFrame) @@ -1248,11 +1287,11 @@ HRESULT CLR_RT_Thread::ProcessException_Phase2() } #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) - if (!fBreakpointsDisabledSav) + if (CLR_EE_DBG_IS_NOT(NoStackTraceInExceptions) && !fBreakpointsDisabledSav) { CLR_EE_DBG_CLR(BreakpointsDisabled); } -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // We are not ready to execute IL yet so do NOT clear m_currentException flag. // There still remains hope for this thread so return S_OK so ProcessException can get called again via @@ -1264,10 +1303,13 @@ HRESULT CLR_RT_Thread::ProcessException_Phase2() us.m_stack = NULL; // Don't pop off the handler when we pop this stack frame #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) - // We don't want to send any breakpoints until after we set the IP appropriately - bool fBreakpointsDisabledSav = CLR_EE_DBG_IS(BreakpointsDisabled); - CLR_EE_DBG_SET(BreakpointsDisabled); -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) + if (CLR_EE_DBG_IS_NOT(NoStackTraceInExceptions)) + { + // We don't want to send any breakpoints until after we set the IP appropriately + fBreakpointsDisabledSav = CLR_EE_DBG_IS(BreakpointsDisabled); + CLR_EE_DBG_SET(BreakpointsDisabled); + } +#endif #ifndef NANOCLR_NO_IL_INLINE if (iterStack->m_inlineFrame) @@ -1282,11 +1324,11 @@ HRESULT CLR_RT_Thread::ProcessException_Phase2() iterStack = CurrentFrame(); #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) - if (!fBreakpointsDisabledSav) + if (CLR_EE_DBG_IS_NOT(NoStackTraceInExceptions) && !fBreakpointsDisabledSav) { CLR_EE_DBG_CLR(BreakpointsDisabled); } -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif } // If we reached this point, we've unwound the entire thread and have an unhandled exception. @@ -1295,19 +1337,25 @@ HRESULT CLR_RT_Thread::ProcessException_Phase2() // At this point, no hope remains. // m_currentException is still set, but we return PROCESS_EXCEPTION signalling that there is no hope for the thread, // which causes Thread::Execute to terminate it. + #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) -#if !defined(BUILD_RTM) - // special case thread abort exception - if ((this->m_flags & CLR_RT_Thread::TH_F_Aborted) == 0) + if (CLR_EE_DBG_IS_NOT(NoStackTraceInExceptions)) { - CLR_Debug::Printf(" Uncaught exception \r\n"); - // Perhaps some stronger notification is needed. Consider CLR 2.0's fail-fast work - // We could kill the application, and perhaps even store relevant data to dump to the user - // when they connect to the PC. Save the state so the debug API for the uncaught exception could be - // retrieved? + +#if !defined(BUILD_RTM) + // special case thread abort exception + if ((this->m_flags & CLR_RT_Thread::TH_F_Aborted) == 0) + { + CLR_Debug::Printf(" Uncaught exception \r\n"); + // Perhaps some stronger notification is needed. Consider CLR 2.0's fail-fast work + // We could kill the application, and perhaps even store relevant data to dump to the user + // when they connect to the PC. Save the state so the debug API for the uncaught exception could be + // retrieved? + } +#endif } -#endif //! BUILD_RTM -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif + NANOCLR_SET_AND_LEAVE(CLR_E_PROCESS_EXCEPTION); NANOCLR_NOCLEANUP(); } diff --git a/src/CLR/Core/TypeSystem.cpp b/src/CLR/Core/TypeSystem.cpp index fd7fa79fa5..87162b1711 100644 --- a/src/CLR/Core/TypeSystem.cpp +++ b/src/CLR/Core/TypeSystem.cpp @@ -32,11 +32,11 @@ int s_CLR_RT_fTrace_Exceptions = NANOCLR_TRACE_DEFAULT(c_CLR_RT_Trace_Info, c_CL #endif #if defined(NANOCLR_TRACE_INSTRUCTIONS) -int s_CLR_RT_fTrace_Instructions = NANOCLR_TRACE_DEFAULT(c_CLR_RT_Trace_None, c_CLR_RT_Trace_None); +int s_CLR_RT_fTrace_Instructions = NANOCLR_TRACE_DEFAULT(c_CLR_RT_Trace_Info, c_CLR_RT_Trace_None); #endif #if defined(NANOCLR_GC_VERBOSE) -int s_CLR_RT_fTrace_Memory = NANOCLR_TRACE_DEFAULT(c_CLR_RT_Trace_None, c_CLR_RT_Trace_None); +int s_CLR_RT_fTrace_Memory = NANOCLR_TRACE_DEFAULT(c_CLR_RT_Trace_Info, c_CLR_RT_Trace_None); #endif #if defined(NANOCLR_TRACE_MEMORY_STATS) @@ -44,7 +44,7 @@ int s_CLR_RT_fTrace_MemoryStats = NANOCLR_TRACE_DEFAULT(c_CLR_RT_Trace_Info, c_C #endif #if defined(NANOCLR_GC_VERBOSE) -int s_CLR_RT_fTrace_GC = NANOCLR_TRACE_DEFAULT(c_CLR_RT_Trace_None, c_CLR_RT_Trace_None); +int s_CLR_RT_fTrace_GC = NANOCLR_TRACE_DEFAULT(c_CLR_RT_Trace_Info, c_CLR_RT_Trace_None); #endif #if defined(VIRTUAL_DEVICE) @@ -1556,7 +1556,7 @@ void CLR_RT_Assembly::Assembly_Initialize(CLR_RT_Assembly::Offsets &offsets) memset(m_pDebuggingInfo_MethodDef, 0, offsets.iDebuggingInfoMethods); } -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) } HRESULT CLR_RT_Assembly::CreateInstance(const CLR_RECORD_ASSEMBLY *header, CLR_RT_Assembly *&assm) @@ -1650,7 +1650,7 @@ HRESULT CLR_RT_Assembly::CreateInstance(const CLR_RECORD_ASSEMBLY *header, CLR_R offsets.iDebuggingInfoMethods = ROUNDTOMULTIPLE( skeleton->m_pTablesSize[TBL_MethodDef] * sizeof(CLR_RT_MethodDef_DebuggingInfo), CLR_UINT32); -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) size_t iTotalRamSize = offsets.iBase + offsets.iAssemblyRef + offsets.iTypeRef + offsets.iFieldRef + offsets.iMethodRef + offsets.iTypeDef + offsets.iFieldDef + offsets.iMethodDef; @@ -1661,7 +1661,7 @@ HRESULT CLR_RT_Assembly::CreateInstance(const CLR_RECORD_ASSEMBLY *header, CLR_R #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) iTotalRamSize += offsets.iDebuggingInfoMethods; -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) //--// @@ -1799,6 +1799,10 @@ HRESULT CLR_RT_Assembly::CreateInstance( bool CLR_RT_Assembly::Resolve_AssemblyRef(bool fOutput) { +#ifdef BUILD_RTM + (void)fOutput; +#endif + NATIVE_PROFILE_CLR_CORE(); bool fGot = true; int i; @@ -2027,10 +2031,10 @@ HRESULT CLR_RT_Assembly::Resolve_MethodRef() { inst.InitializeFromIndex(m_pCrossReference_TypeRef[src->container].m_target); +#if !defined(BUILD_RTM) const CLR_RECORD_TYPEDEF *qTD = inst.m_target; CLR_RT_Assembly *qASSM = inst.m_assm; -#if !defined(BUILD_RTM) CLR_Debug::Printf( "Resolve: unknown method: %s.%s.%s\r\n", qASSM->GetString(qTD->nameSpace), @@ -3955,7 +3959,7 @@ HRESULT CLR_RT_TypeSystem::ResolveAll() offsets.iDebuggingInfoMethods += ROUNDTOMULTIPLE( pASSM->m_pTablesSize[TBL_MethodDef] * sizeof(CLR_RT_MethodDef_DebuggingInfo), CLR_UINT32); -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) iMetaData += pASSM->m_header->SizeOfTable(TBL_AssemblyRef) + pASSM->m_header->SizeOfTable(TBL_TypeRef) + pASSM->m_header->SizeOfTable(TBL_FieldRef) + pASSM->m_header->SizeOfTable(TBL_MethodRef) + @@ -4026,7 +4030,7 @@ HRESULT CLR_RT_TypeSystem::ResolveAll() #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) CLR_Debug::Printf(" DebuggingInfo = %8d bytes\r\n", offsets.iDebuggingInfoMethods); CLR_Debug::Printf("\r\n"); -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) CLR_Debug::Printf( " Attributes = %8d bytes (%8d elements)\r\n", @@ -4082,7 +4086,7 @@ HRESULT CLR_RT_TypeSystem::PrepareForExecution() #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) CLR_EE_DBG_SET(BreakpointsDisabled); -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) #if !defined(NANOCLR_APPDOMAINS) if (g_CLR_RT_ExecutionEngine.m_outOfMemoryException == NULL) @@ -4114,7 +4118,7 @@ HRESULT CLR_RT_TypeSystem::PrepareForExecution() CLR_EE_DBG_CLR(BreakpointsDisabled); g_CLR_RT_ExecutionEngine.Breakpoint_Assemblies_Loaded(); -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) NANOCLR_CLEANUP_END(); } diff --git a/src/CLR/Debugger/Debugger.cpp b/src/CLR/Debugger/Debugger.cpp index 8f56987162..8a77f9082c 100644 --- a/src/CLR/Debugger/Debugger.cpp +++ b/src/CLR/Debugger/Debugger.cpp @@ -352,7 +352,7 @@ HRESULT CLR_DBG_Debugger::CreateListOfCalls( NANOCLR_NOCLEANUP(); } -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -456,6 +456,7 @@ bool CLR_DBG_Debugger::Monitor_FlashSectorMap(WP_Message *msg) NATIVE_PROFILE_CLR_DEBUGGER(); BlockStorageDevice *storageDevices = NULL; + BlockStorageDevice *device = NULL; DeviceBlockInfo *devicesBlockInfos = NULL; Flash_BlockRegionInfo *pData = NULL; bool success = false; @@ -499,7 +500,8 @@ bool CLR_DBG_Debugger::Monitor_FlashSectorMap(WP_Message *msg) } // sanity check - if (&storageDevices[i] == NULL) + device = &storageDevices[i]; + if (device == NULL) { // failed goto cmd_executed; @@ -585,7 +587,7 @@ bool CLR_DBG_Debugger::Monitor_TargetInfo(WP_Message *msg) { Monitor_TargetInfo_Reply cmdReply; - bool fOK = nanoBooter_GetTargetInfo(&cmdReply.m_TargetInfo) == true; + bool fOK = (bool)nanoBooter_GetTargetInfo(&cmdReply.m_TargetInfo) == true; WP_ReplyToCommand(msg, fOK, false, &cmdReply, sizeof(Monitor_TargetInfo_Reply)); @@ -610,10 +612,6 @@ bool CLR_DBG_Debugger::CheckPermission(ByteAddress address, int mode) hasPermission = true; break; case AccessMemory_Read: -#if defined(BUILD_RTM) - if (!DebuggerPort_IsUsingSsl(HalSystemConfig.DebuggerPort)) - break; -#endif switch (range.RangeType) { // fall through @@ -632,10 +630,6 @@ bool CLR_DBG_Debugger::CheckPermission(ByteAddress address, int mode) } break; case AccessMemory_Write: -#if defined(BUILD_RTM) - if (!DebuggerPort_IsUsingSsl(HalSystemConfig.DebuggerPort)) - break; -#endif if (BlockRange_IsDeployment(range) || BlockRange_IsConfig(range)) { hasPermission = true; @@ -646,10 +640,6 @@ bool CLR_DBG_Debugger::CheckPermission(ByteAddress address, int mode) } break; case AccessMemory_Erase: -#if defined(BUILD_RTM) - if (!DebuggerPort_IsUsingSsl(HalSystemConfig.DebuggerPort)) - break; -#endif switch (range.RangeType) { case BlockRange_BLOCKTYPE_DEPLOYMENT: @@ -688,6 +678,7 @@ void CLR_DBG_Debugger::AccessMemory( //--// unsigned int iRegion, iRange; + uint32_t crc32 = 0; if (BlockStorageDevice_FindRegionFromAddress(m_deploymentStorageDevice, location, &iRegion, &iRange)) { @@ -757,8 +748,8 @@ void CLR_DBG_Debugger::AccessMemory( if (mode == AccessMemory_Check) { // compute CRC32 of the memory segment - *(CLR_DBG_Commands_Monitor_CheckMemory_Reply *)buf = - SUPPORT_ComputeCRC((const void *)accessAddress, NumOfBytes, 0); + crc32 = SUPPORT_ComputeCRC((const void *)accessAddress, NumOfBytes, crc32); + *(CLR_DBG_Commands_Monitor_CheckMemory_Reply *)buf = crc32; } else { @@ -825,8 +816,8 @@ void CLR_DBG_Debugger::AccessMemory( } // compute CRC32 of the memory segment - *(CLR_DBG_Commands_Monitor_CheckMemory_Reply *)buf = - SUPPORT_ComputeCRC(bufPtr, NumOfBytes, 0); + crc32 = SUPPORT_ComputeCRC((const void *)bufPtr, NumOfBytes, crc32); + *(CLR_DBG_Commands_Monitor_CheckMemory_Reply *)buf = crc32; // free buffer if allocated if (!isMemoryMapped) @@ -1075,7 +1066,7 @@ bool CLR_DBG_Debugger::Monitor_Reboot(WP_Message *msg) if (CLR_DBG_Commands::Monitor_Reboot::c_EnterNanoBooter == (cmd->m_flags & CLR_DBG_Commands::Monitor_Reboot::c_EnterNanoBooter)) { - success = RequestToLaunchNanoBooter(); + success = RequestToLaunchNanoBooter(0); } else if ( CLR_DBG_Commands::Monitor_Reboot::c_EnterProprietaryBooter == @@ -1781,14 +1772,14 @@ static bool FillValues( memset(dst, 0, sizeof(*dst)); - dst->m_referenceID = (reference != NULL) ? reference : ptr; + dst->m_referenceID = (CLR_UINT32)((reference != NULL) ? reference : ptr); dst->m_dt = ptr->DataType(); dst->m_flags = ptr->DataFlags(); dst->m_size = ptr->DataSize(); if (pTD != NULL) { - dst->m_td = *pTD; + dst->m_td.m_data = pTD->m_data; } else if (SUCCEEDED(desc.InitializeFromObject(*ptr))) { @@ -1827,7 +1818,7 @@ static bool FillValues( if (text != NULL) { - dst->m_charsInString = text; + dst->m_charsInString = (CLR_UINT32)text; dst->m_bytesInString = (CLR_UINT32)hal_strlen_s(text); hal_strncpy_s( @@ -1838,7 +1829,8 @@ static bool FillValues( } else { - dst->m_charsInString = NULL; + // equivalent to a null string + dst->m_charsInString = 0; dst->m_bytesInString = 0; dst->m_builtinValue[0] = 0; } @@ -1870,7 +1862,7 @@ static bool FillValues( break; case DATATYPE_ARRAY_BYREF: - dst->m_arrayref_referenceID = ptr->Array(); + dst->m_arrayref_referenceID = (CLR_UINT32)ptr->Array(); dst->m_arrayref_index = ptr->ArrayIndex(); break; @@ -2311,7 +2303,7 @@ bool CLR_DBG_Debugger::Debugging_Thread_Get(WP_Message *msg) // If we are a thread spawned by the debugger to perform evaluations, // return the thread object that correspond to thread that has focus in debugger. th = th->m_realThread; -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) // Find an existing managed thread, if it exists // making sure to only return the managed object association with the current appdomain @@ -3093,7 +3085,7 @@ bool CLR_DBG_Debugger::Debugging_Value_AllocateArray(WP_Message *msg) return true; } -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) #if defined(NANOCLR_PROFILE_NEW) bool CLR_DBG_Debugger::Profiling_Command(WP_Message *msg) @@ -3116,6 +3108,8 @@ bool CLR_DBG_Debugger::Profiling_Command(WP_Message *msg) default: return false; } + + return true; } bool CLR_DBG_Debugger::Profiling_ChangeConditions(WP_Message *msg) @@ -3158,7 +3152,7 @@ bool CLR_DBG_Debugger::Profiling_FlushStream(WP_Message *msg) return true; } -#endif //#if defined(NANOCLR_PROFILE_NEW) +#endif // #if defined(NANOCLR_PROFILE_NEW) #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) @@ -3549,7 +3543,7 @@ bool CLR_DBG_Debugger::Debugging_Resolve_Field(WP_Message *msg) CLR_RT_TypeDef_Instance instClass; instClass.InitializeFromField(inst); - cmdReply->m_td = instClass; + cmdReply->m_td.m_data = instClass.m_data; cmdReply->m_index = inst.CrossReference().m_offset; WP_ReplyToCommand(msg, true, false, cmdReply, sizeof(CLR_DBG_Commands::Debugging_Resolve_Field::Reply)); @@ -3595,7 +3589,7 @@ bool CLR_DBG_Debugger::Debugging_Resolve_Method(WP_Message *msg) char *szBuffer = cmdReply->m_method; size_t iBuffer = MAXSTRLEN(cmdReply->m_method); - cmdReply->m_td = instOwner; + cmdReply->m_td.m_data = instOwner.m_data; CLR_SafeSprintf(szBuffer, iBuffer, "%s", inst.m_assm->GetString(inst.m_target->name)); @@ -3637,7 +3631,7 @@ bool CLR_DBG_Debugger::Debugging_Resolve_VirtualMethod(WP_Message *msg) return true; } -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) //--// @@ -3805,4 +3799,4 @@ bool CLR_DBG_Debugger::Debugging_Info_SetJMC(WP_Message *msg) } } -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) diff --git a/src/CLR/Debugger/Debugger_minimal.cpp b/src/CLR/Debugger/Debugger_minimal.cpp index 16ea034f8b..8de4a0d9f4 100644 --- a/src/CLR/Debugger/Debugger_minimal.cpp +++ b/src/CLR/Debugger/Debugger_minimal.cpp @@ -17,22 +17,27 @@ } const CLR_Messaging_CommandHandlerLookup c_Debugger_Lookup_Request[] = { + DEFINE_CMD(Execution_QueryCLRCapabilities), DEFINE_CMD2(Ping), DEFINE_CMD2(Reboot), - DEFINE_CMD(Execution_QueryCLRCapabilities), DEFINE_CMD2(ReadMemory), DEFINE_CMD2(WriteMemory), + DEFINE_CMD2(CheckMemory), DEFINE_CMD2(EraseMemory), DEFINE_CMD2(QueryConfiguration), DEFINE_CMD2(UpdateConfiguration), // DEFINE_CMD2(Execute), + DEFINE_CMD2(Reboot), DEFINE_CMD2(MemoryMap), DEFINE_CMD2(FlashSectorMap), DEFINE_CMD2(TargetInfo), + DEFINE_CMD2(DeploymentMap), + // + DEFINE_CMD(Execution_ChangeConditions), + // DEFINE_CMD(UpgradeToSsl), - }; const CLR_Messaging_CommandHandlerLookup c_Debugger_Lookup_Reply[] = { diff --git a/src/CLR/Diagnostics/Diagnostics.vcxproj b/src/CLR/Diagnostics/Diagnostics.vcxproj index 3b0d689dba..158a66bb52 100644 --- a/src/CLR/Diagnostics/Diagnostics.vcxproj +++ b/src/CLR/Diagnostics/Diagnostics.vcxproj @@ -23,6 +23,7 @@ + diff --git a/src/CLR/Diagnostics/Diagnostics.vcxproj.filters b/src/CLR/Diagnostics/Diagnostics.vcxproj.filters index b221969501..88dc4025f8 100644 --- a/src/CLR/Diagnostics/Diagnostics.vcxproj.filters +++ b/src/CLR/Diagnostics/Diagnostics.vcxproj.filters @@ -29,5 +29,8 @@ Source Files + + Source Files + \ No newline at end of file diff --git a/src/CLR/Diagnostics/Info.cpp b/src/CLR/Diagnostics/Info.cpp index a7e023d0d0..4b54ef3721 100644 --- a/src/CLR/Diagnostics/Info.cpp +++ b/src/CLR/Diagnostics/Info.cpp @@ -27,7 +27,7 @@ void CLR_Debug::SaveMessage(std::string str) NATIVE_PROFILE_CLR_DIAGNOSTICS(); // clear LR & CR - int pos; + size_t pos; if ((pos = str.find('\n')) != std::string::npos) { str.erase(pos); @@ -89,40 +89,6 @@ HRESULT NANOCLR_DEBUG_PROCESS_EXCEPTION(HRESULT hr, const char *szFunc, const ch //--// -bool CLR_SafeSprintfV(char *&szBuffer, size_t &iBuffer, const char *format, va_list arg) -{ - NATIVE_PROFILE_CLR_DIAGNOSTICS(); - - int chars = vsnprintf(szBuffer, iBuffer, format, arg); - bool fRes = (chars >= 0); - - if (fRes == false) - chars = (int)iBuffer; - - szBuffer += chars; - szBuffer[0] = 0; - iBuffer -= chars; - - return fRes; -} - -bool CLR_SafeSprintf(char *&szBuffer, size_t &iBuffer, const char *format, ...) -{ - NATIVE_PROFILE_CLR_DIAGNOSTICS(); - va_list arg; - bool fRes; - - va_start(arg, format); - - fRes = CLR_SafeSprintfV(szBuffer, iBuffer, format, arg); - - va_end(arg); - - return fRes; -} - -//--// - void CLR_Debug::Flush() { NATIVE_PROFILE_CLR_DIAGNOSTICS(); @@ -272,7 +238,10 @@ int CLR_Debug::PrintfV(const char *format, va_list arg) int16_t bufferSize = c_BufferSize; #endif - bool fRes = CLR_SafeSprintfV(szBuffer, iBuffer, format, arg); +#if !defined(BUILD_RTM) + bool fRes = +#endif + CLR_SafeSprintfV(szBuffer, iBuffer, format, arg); _ASSERTE(fRes); diff --git a/src/CLR/Diagnostics/Info_Safeprintf.cpp b/src/CLR/Diagnostics/Info_Safeprintf.cpp new file mode 100644 index 0000000000..2da1afe71d --- /dev/null +++ b/src/CLR/Diagnostics/Info_Safeprintf.cpp @@ -0,0 +1,39 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Portions Copyright (c) Microsoft Corporation. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +#include + +bool CLR_SafeSprintfV(char *&szBuffer, size_t &iBuffer, const char *format, va_list arg) +{ + NATIVE_PROFILE_CLR_DIAGNOSTICS(); + + int chars = vsnprintf(szBuffer, iBuffer, format, arg); + bool fRes = (chars >= 0); + + if (fRes == false) + chars = (int)iBuffer; + + szBuffer += chars; + szBuffer[0] = 0; + iBuffer -= chars; + + return fRes; +} + +bool CLR_SafeSprintf(char *&szBuffer, size_t &iBuffer, const char *format, ...) +{ + NATIVE_PROFILE_CLR_DIAGNOSTICS(); + va_list arg; + bool fRes; + + va_start(arg, format); + + fRes = CLR_SafeSprintfV(szBuffer, iBuffer, format, arg); + + va_end(arg); + + return fRes; +} diff --git a/src/CLR/Diagnostics/Profiler.cpp b/src/CLR/Diagnostics/Profiler.cpp index fbaaec1e1d..f00c665cea 100644 --- a/src/CLR/Diagnostics/Profiler.cpp +++ b/src/CLR/Diagnostics/Profiler.cpp @@ -16,18 +16,24 @@ HRESULT CLR_PRF_Profiler::CreateInstance() g_CLR_PRF_Profiler.m_packetSeqId = 0; g_CLR_PRF_Profiler.m_stream = NULL; - g_CLR_PRF_Profiler.m_lastTimestamp = (CLR_UINT32)((CLR_UINT64)(HAL_Time_CurrentTime() + ((1ull << CLR_PRF_CMDS::Bits::TimestampShift) - 1)) - >> CLR_PRF_CMDS::Bits::TimestampShift); + g_CLR_PRF_Profiler.m_lastTimestamp = + (CLR_UINT32)((CLR_UINT64)(HAL_Time_CurrentTime() + ((1ull << CLR_PRF_CMDS::Bits::TimestampShift) - 1)) >> + CLR_PRF_CMDS::Bits::TimestampShift); g_CLR_PRF_Profiler.m_currentAssembly = 0; g_CLR_PRF_Profiler.m_currentThreadPID = 0; NANOCLR_CHECK_HRESULT(CLR_RT_HeapBlock_MemoryStream::CreateInstance(g_CLR_PRF_Profiler.m_stream, NULL, 0)); - + + g_CLR_PRF_Profiler.m_initialized = true; + NANOCLR_NOCLEANUP(); } HRESULT CLR_PRF_Profiler::DeleteInstance() { NATIVE_PROFILE_CLR_DIAGNOSTICS(); + + g_CLR_PRF_Profiler.m_initialized = false; + return g_CLR_PRF_Profiler.Profiler_Cleanup(); } @@ -41,10 +47,12 @@ HRESULT CLR_PRF_Profiler::Profiler_Cleanup() void CLR_PRF_Profiler::SendMemoryLayout() { NATIVE_PROFILE_CLR_DIAGNOSTICS(); - //Send Memory Layout - m_stream->WriteBits( CLR_PRF_CMDS::c_Profiling_Memory_Layout, CLR_PRF_CMDS::Bits::CommandHeader ); - PackAndWriteBits( 0 ); + + // Send Memory Layout + m_stream->WriteBits(CLR_PRF_CMDS::c_Profiling_Memory_Layout, CLR_PRF_CMDS::Bits::CommandHeader); + PackAndWriteBits((CLR_UINT32)s_CLR_RT_Heap.m_location); PackAndWriteBits(s_CLR_RT_Heap.m_size); + Stream_Send(); } @@ -57,45 +65,48 @@ HRESULT CLR_PRF_Profiler::DumpHeap() CLR_UINT32 heapSize = 0; - if(CLR_EE_PRF_IS_NOT(Enabled)) { NANOCLR_SET_AND_LEAVE(S_OK); } + if (CLR_EE_PRF_IS_NOT(Enabled)) + { + NANOCLR_SET_AND_LEAVE(S_OK); + } { - //Send HeapDump Begin Marker - m_stream->WriteBits( CLR_PRF_CMDS::c_Profiling_HeapDump_Start, CLR_PRF_CMDS::Bits::CommandHeader ); + // Send HeapDump Begin Marker + m_stream->WriteBits(CLR_PRF_CMDS::c_Profiling_HeapDump_Start, CLR_PRF_CMDS::Bits::CommandHeader); NANOCLR_CHECK_HRESULT(Stream_Send()); } DumpRoots(); - NANOCLR_FOREACH_NODE(CLR_RT_HeapCluster,hc,g_CLR_RT_ExecutionEngine.m_heap) + NANOCLR_FOREACH_NODE(CLR_RT_HeapCluster, hc, g_CLR_RT_ExecutionEngine.m_heap) { - CLR_RT_HeapBlock_Node* ptr; + CLR_RT_HeapBlock_Node *ptr; CLR_UINT32 size; - CLR_RT_HeapBlock_Node* end = hc->m_payloadEnd; + CLR_RT_HeapBlock_Node *end = hc->m_payloadEnd; - for(ptr = hc->m_payloadStart, size = ptr->DataSize(); ptr < end; ptr+= size, size = ptr->DataSize()) + for (ptr = hc->m_payloadStart, size = ptr->DataSize(); ptr < end; ptr += size, size = ptr->DataSize()) { - if(ptr->DataType() != DATATYPE_FREEBLOCK && ptr->DataType() != DATATYPE_CACHEDBLOCK) + if (ptr->DataType() != DATATYPE_FREEBLOCK && ptr->DataType() != DATATYPE_CACHEDBLOCK) { heapSize += ptr->DataSize(); } DumpObject(ptr); - //Don't let the stream get too big. + // Don't let the stream get too big. NANOCLR_CHECK_HRESULT(Stream_Send()); } } NANOCLR_FOREACH_NODE_END(); { - //Send HeapDump End Marker - m_stream->WriteBits( CLR_PRF_CMDS::c_Profiling_HeapDump_Stop, CLR_PRF_CMDS::Bits::CommandHeader ); - PackAndWriteBits( heapSize ); + // Send HeapDump End Marker + m_stream->WriteBits(CLR_PRF_CMDS::c_Profiling_HeapDump_Stop, CLR_PRF_CMDS::Bits::CommandHeader); + PackAndWriteBits(heapSize); NANOCLR_CHECK_HRESULT(Stream_Send()); } NANOCLR_CLEANUP(); - //Flush out all data we've collected. Stopping the device without informing the program is a bad idea. + // Flush out all data we've collected. Stopping the device without informing the program is a bad idea. Stream_Flush(); NANOCLR_CLEANUP_END(); @@ -106,14 +117,14 @@ HRESULT CLR_PRF_Profiler::DumpRoots() NATIVE_PROFILE_CLR_DIAGNOSTICS(); NANOCLR_HEADER(); - //Root proto: - //8bits: CLR_PRF_CMDS::c_Profiling_HeapDump_Root - //32bits: Address of Root - //3bits: Source of Root: Finalizer, AppDomain, Assembly, Thread, Stack? - //Only when source is Stack??: 32bits: CLR_RT_MethodDef_Index + // Root proto: + // 8bits: CLR_PRF_CMDS::c_Profiling_HeapDump_Root + // 32bits: Address of Root + // 3bits: Source of Root: Finalizer, AppDomain, Assembly, Thread, Stack? + // Only when source is Stack??: 32bits: CLR_RT_MethodDef_Index - //Iterate through all the finalizers - NANOCLR_FOREACH_NODE(CLR_RT_HeapBlock_Finalizer,fin,g_CLR_RT_ExecutionEngine.m_finalizersPending) + // Iterate through all the finalizers + NANOCLR_FOREACH_NODE(CLR_RT_HeapBlock_Finalizer, fin, g_CLR_RT_ExecutionEngine.m_finalizersPending) { _ASSERTE(fin->m_object); _ASSERTE(fin->m_object->DataType() != DATATYPE_FREEBLOCK); @@ -123,7 +134,7 @@ HRESULT CLR_PRF_Profiler::DumpRoots() } NANOCLR_FOREACH_NODE_END(); - NANOCLR_FOREACH_NODE(CLR_RT_HeapBlock_Finalizer,fin,g_CLR_RT_ExecutionEngine.m_finalizersAlive) + NANOCLR_FOREACH_NODE(CLR_RT_HeapBlock_Finalizer, fin, g_CLR_RT_ExecutionEngine.m_finalizersAlive) { _ASSERTE(fin->m_object); _ASSERTE(fin->m_object->DataType() != DATATYPE_FREEBLOCK); @@ -134,28 +145,30 @@ HRESULT CLR_PRF_Profiler::DumpRoots() NANOCLR_FOREACH_NODE_END(); #if defined(NANOCLR_APPDOMAINS) - //Iterate through all the appdomains - NANOCLR_FOREACH_NODE(CLR_RT_AppDomain,appDomain,g_CLR_RT_ExecutionEngine.m_appDomains) + // Iterate through all the appdomains + NANOCLR_FOREACH_NODE(CLR_RT_AppDomain, appDomain, g_CLR_RT_ExecutionEngine.m_appDomains) { DumpRoot(appDomain, CLR_PRF_CMDS::RootTypes::Root_AppDomain, 0, NULL); } NANOCLR_FOREACH_NODE_END(); #endif - //Iterate through all the assemblies. + // Iterate through all the assemblies. NANOCLR_FOREACH_ASSEMBLY(g_CLR_RT_TypeSystem) { - DumpRoot( pASSM, CLR_PRF_CMDS::RootTypes::Root_Assembly, 0, NULL ); + DumpRoot(pASSM, CLR_PRF_CMDS::RootTypes::Root_Assembly, 0, NULL); } NANOCLR_FOREACH_ASSEMBLY_END(); - { //Iterate through all threads. - CLR_RT_DblLinkedList* threadLists[ 2 ] = { &g_CLR_RT_ExecutionEngine.m_threadsReady, &g_CLR_RT_ExecutionEngine.m_threadsWaiting }; - for(int list = 0; list < 2; list++) + { // Iterate through all threads. + CLR_RT_DblLinkedList *threadLists[2] = { + &g_CLR_RT_ExecutionEngine.m_threadsReady, + &g_CLR_RT_ExecutionEngine.m_threadsWaiting}; + for (int list = 0; list < 2; list++) { - NANOCLR_FOREACH_NODE(CLR_RT_Thread,th,*threadLists[ list ]) + NANOCLR_FOREACH_NODE(CLR_RT_Thread, th, *threadLists[list]) { - DumpRoot( th, CLR_PRF_CMDS::RootTypes::Root_Thread, 0, NULL ); + DumpRoot(th, CLR_PRF_CMDS::RootTypes::Root_Thread, 0, NULL); } NANOCLR_FOREACH_NODE_END(); } @@ -166,50 +179,66 @@ HRESULT CLR_PRF_Profiler::DumpRoots() NANOCLR_NOCLEANUP(); } -void CLR_PRF_Profiler::DumpRoot( CLR_RT_HeapBlock* root, CLR_UINT32 type, CLR_UINT32 flags, CLR_RT_MethodDef_Index* source ) +void CLR_PRF_Profiler::DumpRoot( + CLR_RT_HeapBlock *root, + CLR_UINT32 type, + CLR_UINT32 flags, + CLR_RT_MethodDef_Index *source) { NATIVE_PROFILE_CLR_DIAGNOSTICS(); - m_stream->WriteBits( CLR_PRF_CMDS::c_Profiling_HeapDump_Root, CLR_PRF_CMDS::Bits::CommandHeader ); - DumpPointer( root ); - m_stream->WriteBits( type, CLR_PRF_CMDS::Bits::RootTypes ); + +#if defined(BUILD_RTM) + (void)flags; +#endif + + m_stream->WriteBits(CLR_PRF_CMDS::c_Profiling_HeapDump_Root, CLR_PRF_CMDS::Bits::CommandHeader); + + DumpPointer(root); + + m_stream->WriteBits(type, CLR_PRF_CMDS::Bits::RootTypes); _ASSERTE(!flags); - if(type == CLR_PRF_CMDS::RootTypes::Root_Stack) + + if (type == CLR_PRF_CMDS::RootTypes::Root_Stack) { PackAndWriteBits(*source); - } else { + } + else + { _ASSERTE(source == NULL); } } -void CLR_PRF_Profiler::DumpObject( CLR_RT_HeapBlock* ptr ) +void CLR_PRF_Profiler::DumpObject(CLR_RT_HeapBlock *ptr) { NATIVE_PROFILE_CLR_DIAGNOSTICS(); - //Object Proto: - // Free blocked and cached blocks are considered free memory and are not dumped. - // All other types: - // 8 bits - Profiling_HeapDump_Object - // 32 bit pointer - // 16 bit size - // 8 bit - DataType() const - // 32 bits are TypeDef info >>>> iff DataType == CLASSTYPE || DataType == VALUETYPE || DataType == SZARRAY <<<< - // 16 bits are Array Level info >>>> iff DataType == SZARRAY <<<< - // 1 bit - Reference Follows - // 0 - No more references. End of Packet - // 1 - 32-bit pointer to reference follows. Repeat. + // Object Proto: + // Free blocked and cached blocks are considered free memory and are not dumped. + // All other types: + // 8 bits - Profiling_HeapDump_Object + // 32 bit pointer + // 16 bit size + // 8 bit - DataType() const + // 32 bits are TypeDef info >>>> iff DataType == CLASSTYPE || DataType == VALUETYPE || DataType == SZARRAY <<<< + // 16 bits are Array Level info >>>> iff DataType == SZARRAY <<<< + // 1 bit - Reference Follows + // 0 - No more references. End of Packet + // 1 - 32-bit pointer to reference follows. Repeat. CLR_DataType dt = ptr->DataType(); _ASSERTE(dt < DATATYPE_FIRST_INVALID); - _ASSERTE(sizeof(CLR_RT_HeapBlock) == 12); //HeapBlockObjectPacket in ProfilerPackets.cs assumes sizeof(CLR_RT_HeapBlock) == 12 + _ASSERTE( + sizeof(CLR_RT_HeapBlock) == + 12); // HeapBlockObjectPacket in ProfilerPackets.cs assumes sizeof(CLR_RT_HeapBlock) == 12 - if(dt != DATATYPE_FREEBLOCK && dt != DATATYPE_CACHEDBLOCK) + if (dt != DATATYPE_FREEBLOCK && dt != DATATYPE_CACHEDBLOCK) { - m_stream->WriteBits( CLR_PRF_CMDS::c_Profiling_HeapDump_Object, CLR_PRF_CMDS::Bits::CommandHeader ); - DumpPointer( ptr ); - PackAndWriteBits( ptr->DataSize() ); - m_stream->WriteBits( (CLR_UINT32)dt,CLR_PRF_CMDS::Bits::DataType ); - - switch(dt) + m_stream->WriteBits(CLR_PRF_CMDS::c_Profiling_HeapDump_Object, CLR_PRF_CMDS::Bits::CommandHeader); + DumpPointer(ptr); + PackAndWriteBits(ptr->DataSize()); + m_stream->WriteBits((CLR_UINT32)dt, CLR_PRF_CMDS::Bits::DataType); + + switch (dt) { case DATATYPE_BOOLEAN: case DATATYPE_I1: @@ -226,23 +255,25 @@ void CLR_PRF_Profiler::DumpObject( CLR_RT_HeapBlock* ptr ) case DATATYPE_DATETIME: case DATATYPE_TIMESPAN: case DATATYPE_STRING: - //Boxed primitives.. All are non-pointer types -- no references. + // Boxed primitives.. All are non-pointer types -- no references. case DATATYPE_REFLECTION: - //Has a reference to an assembly, but it's unlikely to be the only thing keeping the assembly alive. + // Has a reference to an assembly, but it's unlikely to be the only thing keeping the assembly alive. case DATATYPE_BINARY_BLOB_HEAD: - //Unknown/unmanaged data-type. No references. + // Unknown/unmanaged data-type. No references. case DATATYPE_SUBTHREAD: - //Owned by a DATATYPE_THREAD; Don't dump back-reference. + // Owned by a DATATYPE_THREAD; Don't dump back-reference. case DATATYPE_MEMORY_STREAM_DATA: - //No references at all -- usually, and when not, its a pointer to an externally shown character buffer used for deserialization. + // No references at all -- usually, and when not, its a pointer to an externally shown character buffer + // used for deserialization. case DATATYPE_IO_PORT: - //No references for normal GPIO; there is a structure for interrupts, but that doesn't seem to be stored on the managed heap. + // No references for normal GPIO; there is a structure for interrupts, but that doesn't seem to be + // stored on the managed heap. case DATATYPE_TIMER_HEAD: case DATATYPE_LOCK_OWNER_HEAD: case DATATYPE_LOCK_REQUEST_HEAD: case DATATYPE_SERIALIZER_DUPLICATE: case DATATYPE_SERIALIZER_STATE: - //No unique forward-looking references. + // No unique forward-looking references. break; case DATATYPE_OBJECT: @@ -251,201 +282,215 @@ void CLR_PRF_Profiler::DumpObject( CLR_RT_HeapBlock* ptr ) #if defined(NANOCLR_APPDOMAINS) case DATATYPE_TRANSPARENT_PROXY: #endif - { - DumpSingleReference( ptr ); - break; - } + { + DumpSingleReference(ptr); + break; + } case DATATYPE_CLASS: case DATATYPE_VALUETYPE: - { - CLR_RT_TypeDef_Index idx = ptr->ObjectCls(); - _ASSERTE(NANOCLR_INDEX_IS_VALID(idx)); - PackAndWriteBits( idx ); - DumpSingleReference( ptr->ObjectLock() ); - DumpListOfReferences( ptr + 1, ptr->DataSize() - 1 ); //All items in list should have DataSize() == 1 therefore ptr->DataSize() - 1 == number of items in list. - break; - } + { + CLR_RT_TypeDef_Index idx = ptr->ObjectCls(); + _ASSERTE(NANOCLR_INDEX_IS_VALID(idx)); + PackAndWriteBits(idx); + DumpSingleReference(ptr->ObjectLock()); + DumpListOfReferences( + ptr + 1, + ptr->DataSize() - 1); // All items in list should have DataSize() == 1 therefore ptr->DataSize() - 1 + // == number of items in list. + break; + } case DATATYPE_SZARRAY: + { + // Special case needed to dump out array data type and levels. + CLR_RT_HeapBlock_Array *array = (CLR_RT_HeapBlock_Array *)ptr; + + PackAndWriteBits(array->ReflectionDataConst().m_data.m_type); + PackAndWriteBits(array->ReflectionDataConst().m_levels); + + if (array->m_fReference) { - //Special case needed to dump out array data type and levels. - CLR_RT_HeapBlock_Array* array = (CLR_RT_HeapBlock_Array*)ptr; - - PackAndWriteBits( array->ReflectionDataConst().m_data.m_type ); - PackAndWriteBits( array->ReflectionDataConst().m_levels ); - - if(array->m_fReference) - { - DumpListOfReferences( (CLR_RT_HeapBlock*)array->GetFirstElement(), array->m_numOfElements ); - } - break; + DumpListOfReferences((CLR_RT_HeapBlock *)array->GetFirstElement(), array->m_numOfElements); } + break; + } case DATATYPE_ASSEMBLY: - { - CLR_RT_Assembly* assembly = (CLR_RT_Assembly*)ptr; - DumpSingleReference( assembly->m_pFile ); + { + CLR_RT_Assembly *assembly = (CLR_RT_Assembly *)ptr; + DumpSingleReference(assembly->m_pFile); #if !defined(NANOCLR_APPDOMAINS) - DumpListOfReferences( assembly->m_pStaticFields, assembly->m_iStaticFields ); + DumpListOfReferences(assembly->m_pStaticFields, assembly->m_iStaticFields); #endif - break; - } + break; + } case DATATYPE_WEAKCLASS: - { - CLR_RT_HeapBlock_WeakReference* wr = (CLR_RT_HeapBlock_WeakReference*)ptr; - DumpSingleReference( wr->m_targetDirect ); - break; - } + { + CLR_RT_HeapBlock_WeakReference *wr = (CLR_RT_HeapBlock_WeakReference *)ptr; + DumpSingleReference(wr->m_targetDirect); + break; + } case DATATYPE_DELEGATE_HEAD: - { - CLR_RT_HeapBlock_Delegate* dlg = (CLR_RT_HeapBlock_Delegate*)ptr; - DumpSingleReference( &dlg->m_object ); - break; - } + { + CLR_RT_HeapBlock_Delegate *dlg = (CLR_RT_HeapBlock_Delegate *)ptr; + DumpSingleReference(&dlg->m_object); + break; + } case DATATYPE_DELEGATELIST_HEAD: - { - CLR_RT_HeapBlock_Delegate_List* dlgList = (CLR_RT_HeapBlock_Delegate_List*)ptr; - DumpListOfReferences( dlgList->GetDelegates(), dlgList->m_length ); - break; - } + { + CLR_RT_HeapBlock_Delegate_List *dlgList = (CLR_RT_HeapBlock_Delegate_List *)ptr; + DumpListOfReferences(dlgList->GetDelegates(), dlgList->m_length); + break; + } case DATATYPE_THREAD: + { + CLR_RT_Thread *th = (CLR_RT_Thread *)ptr; + + DumpSingleReference(th->m_dlg); + DumpSingleReference(th->m_currentException.Dereference()); + + for (int i = 0; i < th->m_nestedExceptionsPos; i++) { - CLR_RT_Thread* th = (CLR_RT_Thread*)ptr; - - DumpSingleReference( th->m_dlg ); - DumpSingleReference( th->m_currentException.Dereference() ); - - for(int i=0; im_nestedExceptionsPos; i++) - { - CLR_RT_HeapBlock* except = th->m_nestedExceptions[ i ].m_exception; - _ASSERTE(!except || except->DataType() == DATATYPE_CLASS || except->DataType() == DATATYPE_OBJECT); - DumpSingleReference( except ); - } - - DumpListOfReferences( th->m_locks); - DumpSingleReference ( th->m_waitForObject ); - DumpListOfReferences( th->m_stackFrames ); - DumpListOfReferences( th->m_subThreads ); - break; + CLR_RT_HeapBlock *except = th->m_nestedExceptions[i].m_exception; + _ASSERTE(!except || except->DataType() == DATATYPE_CLASS || except->DataType() == DATATYPE_OBJECT); + DumpSingleReference(except); } + DumpListOfReferences(th->m_locks); + DumpSingleReference(th->m_waitForObject); + DumpListOfReferences(th->m_stackFrames); + DumpListOfReferences(th->m_subThreads); + break; + } + case DATATYPE_STACK_FRAME: - { - CLR_RT_StackFrame* stack = (CLR_RT_StackFrame*)ptr; - DumpListOfReferences( stack->m_arguments, stack->m_call.m_target->numArgs ); - DumpListOfReferences( stack->m_locals , stack->m_call.m_target->numLocals ); - DumpListOfReferences( stack->m_evalStack, stack->TopValuePosition() ); - break; - } + { + CLR_RT_StackFrame *stack = (CLR_RT_StackFrame *)ptr; + DumpListOfReferences(stack->m_arguments, stack->m_call.m_target->numArgs); + DumpListOfReferences(stack->m_locals, stack->m_call.m_target->numLocals); + DumpListOfReferences(stack->m_evalStack, stack->TopValuePosition()); + break; + } case DATATYPE_OBJECT_TO_EVENT: - { - CLR_RT_ObjectToEvent_Source* otes = (CLR_RT_ObjectToEvent_Source*)ptr; - DumpSingleReference( otes->m_eventPtr ); //The managed object should reference this obj, which references the event. - break; - } + { + CLR_RT_ObjectToEvent_Source *otes = (CLR_RT_ObjectToEvent_Source *)ptr; + DumpSingleReference( + otes->m_eventPtr); // The managed object should reference this obj, which references the event. + break; + } case DATATYPE_LOCK_HEAD: - { - //Object points to Lock Head, Thread points to Lock Head, Lock Head points to list of lock owners and requests - CLR_RT_HeapBlock_Lock* lock = (CLR_RT_HeapBlock_Lock*)ptr; - DumpListOfReferences( lock->m_owners ); - DumpListOfReferences( lock->m_requests ); - break; - } + { + // Object points to Lock Head, Thread points to Lock Head, Lock Head points to list of lock owners and + // requests + CLR_RT_HeapBlock_Lock *lock = (CLR_RT_HeapBlock_Lock *)ptr; + DumpListOfReferences(lock->m_owners); + DumpListOfReferences(lock->m_requests); + break; + } case DATATYPE_ENDPOINT_HEAD: - { - CLR_RT_HeapBlock_EndPoint* ep = (CLR_RT_HeapBlock_EndPoint*)ptr; - DumpListOfReferences( ep->m_messages ); - break; - } + { + CLR_RT_HeapBlock_EndPoint *ep = (CLR_RT_HeapBlock_EndPoint *)ptr; + DumpListOfReferences(ep->m_messages); + break; + } case DATATYPE_WAIT_FOR_OBJECT_HEAD: - { - CLR_RT_HeapBlock_WaitForObject* wfo = (CLR_RT_HeapBlock_WaitForObject*)ptr; - DumpListOfReferences(wfo->GetWaitForObjects(), wfo->m_cObjects); - break; - } + { + CLR_RT_HeapBlock_WaitForObject *wfo = (CLR_RT_HeapBlock_WaitForObject *)ptr; + DumpListOfReferences(wfo->GetWaitForObjects(), wfo->m_cObjects); + break; + } case DATATYPE_FINALIZER_HEAD: - { - CLR_RT_HeapBlock_Finalizer* f = (CLR_RT_HeapBlock_Finalizer*)ptr; - DumpSingleReference( f->m_object ); - break; - } + { + CLR_RT_HeapBlock_Finalizer *f = (CLR_RT_HeapBlock_Finalizer *)ptr; + DumpSingleReference(f->m_object); + break; + } case DATATYPE_MEMORY_STREAM_HEAD: - { - CLR_RT_HeapBlock_MemoryStream* ms = (CLR_RT_HeapBlock_MemoryStream*)ptr; - DumpListOfReferences( ms->m_buffers ); - break; - } + { + CLR_RT_HeapBlock_MemoryStream *ms = (CLR_RT_HeapBlock_MemoryStream *)ptr; + DumpListOfReferences(ms->m_buffers); + break; + } case DATATYPE_SERIALIZER_HEAD: - { - CLR_RT_BinaryFormatter* bf = (CLR_RT_BinaryFormatter*)ptr; - DumpSingleReference ( bf->m_stream ); - DumpListOfReferences( bf->m_duplicates ); - DumpListOfReferences( bf->m_states ); - break; - } + { + CLR_RT_BinaryFormatter *bf = (CLR_RT_BinaryFormatter *)ptr; + DumpSingleReference(bf->m_stream); + DumpListOfReferences(bf->m_duplicates); + DumpListOfReferences(bf->m_states); + break; + } #if defined(NANOCLR_APPDOMAINS) - case DATATYPE_APPDOMAIN_HEAD: + case DATATYPE_APPDOMAIN_HEAD: { - CLR_RT_AppDomain* appDomain = (CLR_RT_AppDomain*)ptr; - DumpListOfReferences( appDomain->m_appDomainAssemblies ); - DumpSingleReference ( appDomain->m_globalLock ); - DumpSingleReference ( appDomain->m_strName ); - DumpSingleReference ( appDomain->m_outOfMemoryException ); + CLR_RT_AppDomain *appDomain = (CLR_RT_AppDomain *)ptr; + DumpListOfReferences(appDomain->m_appDomainAssemblies); + DumpSingleReference(appDomain->m_globalLock); + DumpSingleReference(appDomain->m_strName); + DumpSingleReference(appDomain->m_outOfMemoryException); break; } - case DATATYPE_APPDOMAIN_ASSEMBLY: + case DATATYPE_APPDOMAIN_ASSEMBLY: { - CLR_RT_AppDomainAssembly* appDomainAssembly = (CLR_RT_AppDomainAssembly*)ptr; - DumpListOfReferences( appDomainAssembly->m_pStaticFields, appDomainAssembly->m_assembly->m_iStaticFields ); + CLR_RT_AppDomainAssembly *appDomainAssembly = (CLR_RT_AppDomainAssembly *)ptr; + DumpListOfReferences( + appDomainAssembly->m_pStaticFields, + appDomainAssembly->m_assembly->m_iStaticFields); break; } #endif - default: + default: _ASSERTE(false); break; } DumpEndOfRefsList(); - } //if(dt != DATATYPE_FREEBLOCK && dt != DATATYPE_CACHEDBLOCK) + } // if(dt != DATATYPE_FREEBLOCK && dt != DATATYPE_CACHEDBLOCK) } -CLR_RT_HeapBlock* CLR_PRF_Profiler::FindReferencedObject(CLR_RT_HeapBlock* ref) +CLR_RT_HeapBlock *CLR_PRF_Profiler::FindReferencedObject(CLR_RT_HeapBlock *ref) { NATIVE_PROFILE_CLR_DIAGNOSTICS(); - while(ref) + + while (ref) { CLR_DataType dt = ref->DataType(); - switch(dt) + + switch (dt) { - case DATATYPE_BYREF: - case DATATYPE_OBJECT: - ref = ref->Dereference(); - break; + case DATATYPE_BYREF: + case DATATYPE_OBJECT: + ref = ref->Dereference(); + break; + #if defined(NANOCLR_APPDOMAINS) - case DATATYPE_TRANSPARENT_PROXY: - ref = ref->TransparentProxyDereference(); - break; + case DATATYPE_TRANSPARENT_PROXY: + ref = ref->TransparentProxyDereference(); + break; #endif - case DATATYPE_ARRAY_BYREF: - ref = ref->Array(); - default: - return ref; + + case DATATYPE_ARRAY_BYREF: + ref = ref->Array(); + return ref; + + default: + return ref; } } + return NULL; } @@ -455,34 +500,34 @@ void CLR_PRF_Profiler::DumpEndOfRefsList() SendFalse(); } -void CLR_PRF_Profiler::DumpPointer(void* ptr) +void CLR_PRF_Profiler::DumpPointer(void *ptr) { NATIVE_PROFILE_CLR_DIAGNOSTICS(); - PackAndWriteBits( (CLR_UINT32)((CLR_UINT8*)ptr - s_CLR_RT_Heap.m_location) ); + PackAndWriteBits((CLR_UINT32)((CLR_UINT8 *)ptr - s_CLR_RT_Heap.m_location)); } -void CLR_PRF_Profiler::DumpSingleReference(CLR_RT_HeapBlock* ptr) +void CLR_PRF_Profiler::DumpSingleReference(CLR_RT_HeapBlock *ptr) { NATIVE_PROFILE_CLR_DIAGNOSTICS(); ptr = FindReferencedObject(ptr); - if(ptr) + if (ptr) { SendTrue(); DumpPointer(ptr); } } -void CLR_PRF_Profiler::DumpListOfReferences(CLR_RT_HeapBlock* firstItem, CLR_UINT16 count) +void CLR_PRF_Profiler::DumpListOfReferences(CLR_RT_HeapBlock *firstItem, CLR_UINT16 count) { NATIVE_PROFILE_CLR_DIAGNOSTICS(); - CLR_RT_HeapBlock* ptr; - for(ptr = firstItem; count > 0; ptr += ptr->DataSize(), count--) + CLR_RT_HeapBlock *ptr; + for (ptr = firstItem; count > 0; ptr += ptr->DataSize(), count--) { DumpSingleReference(ptr); } } -void CLR_PRF_Profiler::DumpListOfReferences(CLR_RT_DblLinkedList& list) +void CLR_PRF_Profiler::DumpListOfReferences(CLR_RT_DblLinkedList &list) { NATIVE_PROFILE_CLR_DIAGNOSTICS(); NANOCLR_FOREACH_NODE(CLR_RT_HeapBlock_Node, ptr, list) @@ -497,10 +542,11 @@ void CLR_PRF_Profiler::DumpListOfReferences(CLR_RT_DblLinkedList& list) void CLR_PRF_Profiler::Timestamp() { NATIVE_PROFILE_CLR_DIAGNOSTICS(); - //Send Profiling Timestamp - CLR_UINT32 time = (CLR_UINT32)((HAL_Time_CurrentTime() + ((CLR_UINT64)((1ull << CLR_PRF_CMDS::Bits::TimestampShift) - 1))) - >> CLR_PRF_CMDS::Bits::TimestampShift); - if(time > m_lastTimestamp) + // Send Profiling Timestamp + CLR_UINT32 time = + (CLR_UINT32)((HAL_Time_CurrentTime() + ((CLR_UINT64)((1ull << CLR_PRF_CMDS::Bits::TimestampShift) - 1))) >> + CLR_PRF_CMDS::Bits::TimestampShift); + if (time > m_lastTimestamp) { m_stream->WriteBits(CLR_PRF_CMDS::c_Profiling_Timestamp, CLR_PRF_CMDS::Bits::CommandHeader); PackAndWriteBits(time - m_lastTimestamp); @@ -512,7 +558,7 @@ void CLR_PRF_Profiler::Timestamp() //--// #if defined(NANOCLR_PROFILE_NEW_CALLS) -HRESULT CLR_PRF_Profiler::RecordContextSwitch(CLR_RT_Thread* nextThread) +HRESULT CLR_PRF_Profiler::RecordContextSwitch(CLR_RT_Thread *nextThread) { NATIVE_PROFILE_CLR_DIAGNOSTICS(); NANOCLR_HEADER(); @@ -520,11 +566,15 @@ HRESULT CLR_PRF_Profiler::RecordContextSwitch(CLR_RT_Thread* nextThread) CLR_PROF_HANDLER_CALLCHAIN_VOID(perf); - if(CLR_EE_PRF_IS(Calls)) +#ifdef NANOCLR_FORCE_PROFILER_EXECUTION + if (g_CLR_PRF_Profiler.m_initialized) +#else + if (CLR_EE_PRF_IS(Calls)) +#endif { Timestamp(); - m_stream->WriteBits( CLR_PRF_CMDS::c_Profiling_Calls_CtxSwitch, CLR_PRF_CMDS::Bits::CommandHeader ); - PackAndWriteBits( nextThread->m_pid ); + m_stream->WriteBits(CLR_PRF_CMDS::c_Profiling_Calls_CtxSwitch, CLR_PRF_CMDS::Bits::CommandHeader); + PackAndWriteBits(nextThread->m_pid); m_currentThreadPID = nextThread->m_pid; NANOCLR_CHECK_HRESULT(Stream_Send()); } @@ -532,19 +582,23 @@ HRESULT CLR_PRF_Profiler::RecordContextSwitch(CLR_RT_Thread* nextThread) NANOCLR_NOCLEANUP(); } -HRESULT CLR_PRF_Profiler::RecordFunctionCall(CLR_RT_Thread* th, CLR_RT_MethodDef_Index md) +HRESULT CLR_PRF_Profiler::RecordFunctionCall(CLR_RT_Thread *th, CLR_RT_MethodDef_Index md) { NATIVE_PROFILE_CLR_DIAGNOSTICS(); NANOCLR_HEADER(); _ASSERTE(th); - if(CLR_EE_PRF_IS(Calls)) +#ifdef NANOCLR_FORCE_PROFILER_EXECUTION + if (g_CLR_PRF_Profiler.m_initialized) +#else + if (CLR_EE_PRF_IS(Calls)) +#endif { CLR_PROF_HANDLER_CALLCHAIN_VOID(perf); - if(th->m_pid != m_currentThreadPID) + if (th->m_pid != m_currentThreadPID) { - NANOCLR_CHECK_HRESULT(RecordContextSwitch( th )); + NANOCLR_CHECK_HRESULT(RecordContextSwitch(th)); } else { @@ -555,7 +609,7 @@ HRESULT CLR_PRF_Profiler::RecordFunctionCall(CLR_RT_Thread* th, CLR_RT_MethodDef m_stream->WriteBits(CLR_PRF_CMDS::c_Profiling_Calls_Call, CLR_PRF_CMDS::Bits::CommandHeader); - if(md.Assembly() == m_currentAssembly) + if (md.Assembly() == m_currentAssembly) { SendFalse(); } @@ -572,19 +626,23 @@ HRESULT CLR_PRF_Profiler::RecordFunctionCall(CLR_RT_Thread* th, CLR_RT_MethodDef NANOCLR_NOCLEANUP(); } -HRESULT CLR_PRF_Profiler::RecordFunctionReturn(CLR_RT_Thread* th, CLR_PROF_CounterCallChain& prof) +HRESULT CLR_PRF_Profiler::RecordFunctionReturn(CLR_RT_Thread *th, CLR_PROF_CounterCallChain &prof) { NATIVE_PROFILE_CLR_DIAGNOSTICS(); NANOCLR_HEADER(); _ASSERTE(th); - if(CLR_EE_PRF_IS(Calls)) +#ifdef NANOCLR_FORCE_PROFILER_EXECUTION + if (g_CLR_PRF_Profiler.m_initialized) +#else + if (CLR_EE_PRF_IS(Calls)) +#endif { CLR_PROF_HANDLER_CALLCHAIN_VOID(perf); - if(th->m_pid != m_currentThreadPID) + if (th->m_pid != m_currentThreadPID) { - NANOCLR_CHECK_HRESULT(RecordContextSwitch( th )); + NANOCLR_CHECK_HRESULT(RecordContextSwitch(th)); } else { @@ -606,76 +664,205 @@ HRESULT CLR_PRF_Profiler::RecordFunctionReturn(CLR_RT_Thread* th, CLR_PROF_Count #if defined(NANOCLR_PROFILE_NEW_ALLOCATIONS) -void CLR_PRF_Profiler::TrackObjectCreation( CLR_RT_HeapBlock* ptr ) +void CLR_PRF_Profiler::TrackObjectCreation(CLR_RT_HeapBlock *ptr) { NATIVE_PROFILE_CLR_DIAGNOSTICS(); _ASSERTE(ptr); - if(CLR_EE_PRF_IS(Allocations)) + +#ifdef NANOCLR_FORCE_PROFILER_EXECUTION + if (g_CLR_PRF_Profiler.m_initialized) +#else + if (CLR_EE_PRF_IS(Allocations)) +#endif { CLR_PROF_HANDLER_CALLCHAIN_VOID(perf); CLR_UINT8 dt = ptr->DataType(); - if(dt != DATATYPE_STACK_FRAME && dt != DATATYPE_BINARY_BLOB_HEAD) + + if (dt != DATATYPE_STACK_FRAME && dt != DATATYPE_BINARY_BLOB_HEAD) { Timestamp(); - m_stream->WriteBits( CLR_PRF_CMDS::c_Profiling_Allocs_Alloc, CLR_PRF_CMDS::Bits::CommandHeader ); - DumpPointer( ptr ); - PackAndWriteBits( ptr->DataSize() ); - m_stream->WriteBits( (CLR_UINT32)dt, CLR_PRF_CMDS::Bits::DataType ); - if(dt == DATATYPE_CLASS || dt == DATATYPE_VALUETYPE) + + m_stream->WriteBits(CLR_PRF_CMDS::c_Profiling_Allocs_Alloc, CLR_PRF_CMDS::Bits::CommandHeader); + + DumpPointer(ptr); + + CLR_UINT16 dataSize = ptr->DataSize(); + PackAndWriteBits(dataSize); + + m_stream->WriteBits((CLR_UINT32)dt, CLR_PRF_CMDS::Bits::DataType); + + if (dt == DATATYPE_CLASS || dt == DATATYPE_VALUETYPE) { - PackAndWriteBits( ptr->ObjectCls() ); + CLR_RT_TypeDef_Index idx = ptr->ObjectCls(); + PackAndWriteBits(idx); + +#ifdef NANOCLR_TRACE_PROFILER_MESSAGES + +#ifdef _WIN64 + CLR_Debug::Printf( + "\r\n Profiler info: ! (0x0x%I64X | %d) DT: %d %d bytes idx: %08x\r\n", + (size_t)((CLR_UINT8 *)ptr), + (CLR_UINT32)((size_t *)ptr - s_CLR_RT_Heap.m_location), + (CLR_UINT32)dt, + (dataSize * sizeof(CLR_RT_HeapBlock)), + idx.m_data); + +#else + CLR_Debug::Printf( + "\r\n Profiler info: ! (0x%08X | %d) DT: %d %d bytes idx: %08x\r\n", + (CLR_UINT32)((CLR_UINT8 *)ptr), + (CLR_UINT32)((CLR_UINT8 *)ptr - s_CLR_RT_Heap.m_location), + (CLR_UINT32)dt, + (dataSize * sizeof(CLR_RT_HeapBlock)), + idx.m_data); +#endif + +#endif // NANOCLR_TRACE_PROFILER_MESSAGES } - else if(dt == DATATYPE_SZARRAY) + else if (dt == DATATYPE_SZARRAY) { - CLR_RT_HeapBlock_Array* array = (CLR_RT_HeapBlock_Array*)ptr; - PackAndWriteBits( array->ReflectionDataConst().m_data.m_type ); - PackAndWriteBits( array->ReflectionDataConst().m_levels ); + CLR_RT_HeapBlock_Array *array = (CLR_RT_HeapBlock_Array *)ptr; + CLR_RT_TypeDef_Index elementIdx = array->ReflectionDataConst().m_data.m_type; + PackAndWriteBits(array->ReflectionDataConst().m_data.m_type); + PackAndWriteBits(array->ReflectionDataConst().m_levels); + +#ifdef NANOCLR_TRACE_PROFILER_MESSAGES + +#ifdef _WIN64 + CLR_Debug::Printf( + "\r\n Profiler info: ! (0x0x%I64X | %d) DT: %d [%08x] %d bytes\r\n", + (size_t)((CLR_UINT8 *)ptr), + (CLR_UINT32)((size_t *)ptr - s_CLR_RT_Heap.m_location), + (CLR_UINT32)dt, + elementIdx.m_data, + (dataSize * sizeof(CLR_RT_HeapBlock))); + +#else + CLR_Debug::Printf( + "\r\n Profiler info: ! (0x%08X | %d) DT: %d [%08x] %d bytes\r\n", + (CLR_UINT32)((CLR_UINT8 *)ptr), + (CLR_UINT32)((CLR_UINT8 *)ptr - s_CLR_RT_Heap.m_location), + (CLR_UINT32)dt, + elementIdx.m_data, + (dataSize * sizeof(CLR_RT_HeapBlock))); +#endif +#endif // NANOCLR_TRACE_PROFILER_MESSAGES } +#ifdef NANOCLR_TRACE_PROFILER_MESSAGES + else + { +#ifdef _WIN64 + CLR_Debug::Printf( + "\r\n Profiler info: ! (0x0x%I64X | %d) DT: %d %d bytes\r\n", + (size_t)((CLR_UINT8 *)ptr), + (CLR_UINT32)((size_t *)ptr - s_CLR_RT_Heap.m_location), + (CLR_UINT32)dt, + (dataSize * sizeof(CLR_RT_HeapBlock))); + +#else + CLR_Debug::Printf( + "\r\n Profiler info: ! (0x%08X | %d) DT: %d %d bytes\r\n", + (CLR_UINT32)((CLR_UINT8 *)ptr), + (CLR_UINT32)((CLR_UINT8 *)ptr - s_CLR_RT_Heap.m_location), + (CLR_UINT32)dt, + (dataSize * sizeof(CLR_RT_HeapBlock))); +#endif + } +#endif // NANOCLR_TRACE_PROFILER_MESSAGES + Stream_Send(); } } } -void CLR_PRF_Profiler::TrackObjectDeletion( CLR_RT_HeapBlock* ptr ) +void CLR_PRF_Profiler::TrackObjectDeletion(CLR_RT_HeapBlock *ptr) { NATIVE_PROFILE_CLR_DIAGNOSTICS(); _ASSERTE(ptr); - if(CLR_EE_PRF_IS(Allocations)) +#ifdef NANOCLR_FORCE_PROFILER_EXECUTION + if (g_CLR_PRF_Profiler.m_initialized) +#else + if (CLR_EE_PRF_IS(Allocations)) +#endif { CLR_PROF_HANDLER_CALLCHAIN_VOID(perf); CLR_UINT8 dt = ptr->DataType(); - if(dt != DATATYPE_STACK_FRAME && dt != DATATYPE_CACHEDBLOCK ) + if (dt != DATATYPE_STACK_FRAME && dt != DATATYPE_CACHEDBLOCK) { Timestamp(); - m_stream->WriteBits( CLR_PRF_CMDS::c_Profiling_Allocs_Delete, CLR_PRF_CMDS::Bits::CommandHeader ); - DumpPointer( ptr ); + m_stream->WriteBits(CLR_PRF_CMDS::c_Profiling_Allocs_Delete, CLR_PRF_CMDS::Bits::CommandHeader); + DumpPointer(ptr); Stream_Send(); } + +#ifdef NANOCLR_TRACE_PROFILER_MESSAGES + CLR_UINT16 dataSize = ptr->DataSize(); + +#ifdef _WIN64 + CLR_Debug::Printf( + "\r\n Profiler info: * (0x0x%I64X | %d) %d bytes\r\n", + (size_t)((CLR_UINT8 *)ptr), + (CLR_UINT32)((size_t *)ptr - s_CLR_RT_Heap.m_location), + (dataSize * sizeof(CLR_RT_HeapBlock))); + +#else + CLR_Debug::Printf( + "\r\n Profiler info: * (0x%08X | %d) %d bytes\r\n", + (CLR_UINT32)((CLR_UINT8 *)ptr), + (CLR_UINT32)((CLR_UINT8 *)ptr - s_CLR_RT_Heap.m_location), + (dataSize * sizeof(CLR_RT_HeapBlock))); +#endif + +#endif // NANOCLR_TRACE_PROFILER_MESSAGES } } void CLR_PRF_Profiler::TrackObjectRelocation() { NATIVE_PROFILE_CLR_DIAGNOSTICS(); - if(CLR_EE_PRF_IS(Allocations)) + +#ifdef NANOCLR_FORCE_PROFILER_EXECUTION + if (g_CLR_PRF_Profiler.m_initialized) +#else + if (CLR_EE_PRF_IS(Allocations)) +#endif { CLR_PROF_HANDLER_CALLCHAIN_VOID(perf); - CLR_RT_GarbageCollector::RelocationRegion* relocBlocks = g_CLR_RT_GarbageCollector.m_relocBlocks; + CLR_RT_GarbageCollector::RelocationRegion *relocBlocks = g_CLR_RT_GarbageCollector.m_relocBlocks; size_t relocCount = g_CLR_RT_GarbageCollector.m_relocCount; Timestamp(); m_stream->WriteBits(CLR_PRF_CMDS::c_Profiling_Allocs_Relloc, CLR_PRF_CMDS::Bits::CommandHeader); - PackAndWriteBits(( CLR_UINT32)relocCount ); + PackAndWriteBits((CLR_UINT32)relocCount); - for(size_t i = 0; i < relocCount; i++) + for (size_t i = 0; i < relocCount; i++) { - DumpPointer( relocBlocks[ i ].m_start); - DumpPointer( relocBlocks[ i ].m_end ); - PackAndWriteBits( relocBlocks[i].m_offset ); + DumpPointer(relocBlocks[i].m_start); + DumpPointer(relocBlocks[i].m_end); + PackAndWriteBits(relocBlocks[i].m_offset); + +#ifdef NANOCLR_TRACE_PROFILER_MESSAGES + +#ifdef _WIN64 + CLR_Debug::Printf( + "\r\n Profiler msg: u 0x%I64X 0x%I64X %d\r\n", + relocBlocks[i].m_start, + relocBlocks[i].m_start + relocBlocks[i].m_offset, + relocBlocks[i].m_end - relocBlocks[i].m_offset); + +#else + CLR_Debug::Printf( + "\r\n Profiler msg: u 0x%08x 0x%08x %d\r\n", + relocBlocks[i].m_start, + relocBlocks[i].m_start + relocBlocks[i].m_offset, + relocBlocks[i].m_end - relocBlocks[i].m_offset); +#endif + +#endif // NANOCLR_TRACE_PROFILER_MESSAGES } } } @@ -683,56 +870,164 @@ void CLR_PRF_Profiler::TrackObjectRelocation() void CLR_PRF_Profiler::RecordGarbageCollectionBegin() { NATIVE_PROFILE_CLR_DIAGNOSTICS(); - if(CLR_EE_PRF_IS(Allocations)) + +#ifdef NANOCLR_FORCE_PROFILER_EXECUTION + if (g_CLR_PRF_Profiler.m_initialized) +#else + if (CLR_EE_PRF_IS(Allocations)) +#endif { CLR_PROF_HANDLER_CALLCHAIN_VOID(perf); Timestamp(); - m_stream->WriteBits( CLR_PRF_CMDS::c_Profiling_GarbageCollect_Begin, CLR_PRF_CMDS::Bits::CommandHeader ); - PackAndWriteBits( g_CLR_RT_GarbageCollector.m_freeBytes ); + m_stream->WriteBits(CLR_PRF_CMDS::c_Profiling_GarbageCollect_Begin, CLR_PRF_CMDS::Bits::CommandHeader); + PackAndWriteBits(g_CLR_RT_GarbageCollector.m_freeBytes); Stream_Send(); + +#ifdef NANOCLR_TRACE_PROFILER_MESSAGES + +#ifdef _WIN64 + CLR_Debug::Printf( + "\r\n Profiler msg: b 1 0 0 0x%I64X 0x%I64X %d 0\r\n", + (CLR_UINT32)s_CLR_RT_Heap.m_location, + s_CLR_RT_Heap.m_size, + g_CLR_RT_GarbageCollector.m_totalBytes); + +#else + CLR_Debug::Printf( + "\r\n Profiler msg: b 1 0 0 0x%08x 0x%08x %d 0\r\n", + (CLR_UINT32)s_CLR_RT_Heap.m_location, + s_CLR_RT_Heap.m_size, + g_CLR_RT_GarbageCollector.m_totalBytes); +#endif + +#endif // NANOCLR_TRACE_PROFILER_MESSAGES } } void CLR_PRF_Profiler::RecordGarbageCollectionEnd() { NATIVE_PROFILE_CLR_DIAGNOSTICS(); - if(CLR_EE_PRF_IS(Allocations)) + +#ifdef NANOCLR_FORCE_PROFILER_EXECUTION + if (g_CLR_PRF_Profiler.m_initialized) +#else + if (CLR_EE_PRF_IS(Allocations)) +#endif { CLR_PROF_HANDLER_CALLCHAIN_VOID(perf); Timestamp(); - m_stream->WriteBits( CLR_PRF_CMDS::c_Profiling_GarbageCollect_End, CLR_PRF_CMDS::Bits::CommandHeader ); - PackAndWriteBits( g_CLR_RT_GarbageCollector.m_freeBytes ); + m_stream->WriteBits(CLR_PRF_CMDS::c_Profiling_GarbageCollect_End, CLR_PRF_CMDS::Bits::CommandHeader); + PackAndWriteBits(g_CLR_RT_GarbageCollector.m_freeBytes); Stream_Send(); + +#ifdef NANOCLR_TRACE_PROFILER_MESSAGES + +#ifdef _WIN64 + NANOCLR_FOREACH_NODE(CLR_RT_HeapCluster, hc, g_CLR_RT_ExecutionEngine.m_heap) + { + CLR_Debug::Printf("\r\n Profiler msg: v 0x%I64X 0\r\n", (CLR_UINT32)hc->m_payloadStart); + } + NANOCLR_FOREACH_NODE_END(); + + CLR_Debug::Printf( + "\r\n Profiler msg: b 0 0 0 0x%I64X 0x%I64X %d 0\r\n", + (CLR_UINT32)s_CLR_RT_Heap.m_location, + s_CLR_RT_Heap.m_size, + g_CLR_RT_GarbageCollector.m_totalBytes); + +#else + NANOCLR_FOREACH_NODE(CLR_RT_HeapCluster, hc, g_CLR_RT_ExecutionEngine.m_heap) + { + CLR_Debug::Printf("\r\n Profiler msg: v 0x%08x 0\r\n", (CLR_UINT32)hc->m_payloadStart); + } + NANOCLR_FOREACH_NODE_END(); + + CLR_Debug::Printf( + "\r\n Profiler msg: b 0 0 0 0x%08x 0x%08x %d 0\r\n", + (CLR_UINT32)s_CLR_RT_Heap.m_location, + s_CLR_RT_Heap.m_size, + g_CLR_RT_GarbageCollector.m_totalBytes); +#endif + +#endif // NANOCLR_TRACE_PROFILER_MESSAGES } } void CLR_PRF_Profiler::RecordHeapCompactionBegin() { NATIVE_PROFILE_CLR_DIAGNOSTICS(); - if(CLR_EE_PRF_IS(Allocations)) + +#ifdef NANOCLR_FORCE_PROFILER_EXECUTION + if (g_CLR_PRF_Profiler.m_initialized) +#else + if (CLR_EE_PRF_IS(Allocations)) +#endif { CLR_PROF_HANDLER_CALLCHAIN_VOID(perf); Timestamp(); - m_stream->WriteBits( CLR_PRF_CMDS::c_Profiling_HeapCompact_Begin, CLR_PRF_CMDS::Bits::CommandHeader ); - PackAndWriteBits( g_CLR_RT_GarbageCollector.m_freeBytes ); + m_stream->WriteBits(CLR_PRF_CMDS::c_Profiling_HeapCompact_Begin, CLR_PRF_CMDS::Bits::CommandHeader); + PackAndWriteBits(g_CLR_RT_GarbageCollector.m_freeBytes); Stream_Send(); + +#ifdef NANOCLR_TRACE_PROFILER_MESSAGES + +#ifdef _WIN64 + CLR_Debug::Printf( + "\r\n Profiler msg: b 1 0 0 0x%I64X 0x%I64X %d 0\r\n", + (CLR_UINT32)s_CLR_RT_Heap.m_location, + s_CLR_RT_Heap.m_size, + g_CLR_RT_GarbageCollector.m_totalBytes); + +#else + CLR_Debug::Printf( + "\r\n Profiler msg: b 1 0 0 0x%08x 0x%08x %d 0\r\n", + (CLR_UINT32)s_CLR_RT_Heap.m_location, + s_CLR_RT_Heap.m_size, + g_CLR_RT_GarbageCollector.m_totalBytes); +#endif + +#endif // NANOCLR_TRACE_PROFILER_MESSAGES } } void CLR_PRF_Profiler::RecordHeapCompactionEnd() { NATIVE_PROFILE_CLR_DIAGNOSTICS(); - if(CLR_EE_PRF_IS(Allocations)) + +#ifdef NANOCLR_FORCE_PROFILER_EXECUTION + if (g_CLR_PRF_Profiler.m_initialized) +#else + if (CLR_EE_PRF_IS(Allocations)) +#endif { CLR_PROF_HANDLER_CALLCHAIN_VOID(perf); Timestamp(); - m_stream->WriteBits( CLR_PRF_CMDS::c_Profiling_HeapCompact_End, CLR_PRF_CMDS::Bits::CommandHeader ); - PackAndWriteBits( g_CLR_RT_GarbageCollector.m_freeBytes ); + m_stream->WriteBits(CLR_PRF_CMDS::c_Profiling_HeapCompact_End, CLR_PRF_CMDS::Bits::CommandHeader); + PackAndWriteBits(g_CLR_RT_GarbageCollector.m_freeBytes); Stream_Send(); + +#ifdef NANOCLR_TRACE_PROFILER_MESSAGES + +#ifdef _WIN64 + CLR_Debug::Printf( + "\r\n Profiler msg: b 0 0 0 0x%I64X 0x%I64X %d 0\r\n", + (CLR_UINT32)s_CLR_RT_Heap.m_location, + s_CLR_RT_Heap.m_size, + g_CLR_RT_GarbageCollector.m_totalBytes); + +#else + CLR_Debug::Printf( + "\r\n Profiler msg: b 0 0 0 0x%08x 0x%08x %d 0\r\n", + (CLR_UINT32)s_CLR_RT_Heap.m_location, + s_CLR_RT_Heap.m_size, + g_CLR_RT_GarbageCollector.m_totalBytes); +#endif + +#endif // NANOCLR_TRACE_PROFILER_MESSAGES } } @@ -743,13 +1038,13 @@ void CLR_PRF_Profiler::RecordHeapCompactionEnd() void CLR_PRF_Profiler::SendTrue() { NATIVE_PROFILE_CLR_DIAGNOSTICS(); - m_stream->WriteBits( (CLR_UINT32)1, 1 ); + m_stream->WriteBits((CLR_UINT32)1, 1); } void CLR_PRF_Profiler::SendFalse() { NATIVE_PROFILE_CLR_DIAGNOSTICS(); - m_stream->WriteBits( (CLR_UINT32)0, 1 ); + m_stream->WriteBits((CLR_UINT32)0, 1); } void CLR_PRF_Profiler::PackAndWriteBits(CLR_UINT32 value) @@ -761,32 +1056,53 @@ void CLR_PRF_Profiler::PackAndWriteBits(CLR_UINT32 value) */ _ASSERTE(sizeof(CLR_UINT32) == 4); - const CLR_UINT32 SHIFT_PER_NIBBLE = 2; //2^2 = 4 bits per nibble + const CLR_UINT32 SHIFT_PER_NIBBLE = 2; // 2^2 = 4 bits per nibble CLR_UINT32 nibbles = 1; - if( value & 0xF0000000) { nibbles = 8; } - else if(value & 0x0F000000) { nibbles = 7; } - else if(value & 0x00F00000) { nibbles = 6; } - else if(value & 0x000F0000) { nibbles = 5; } - else if(value & 0x0000F000) { nibbles = 4; } - else if(value & 0x00000F00) { nibbles = 3; } - else if(value & 0x000000F0) { nibbles = 2; } + if (value & 0xF0000000) + { + nibbles = 8; + } + else if (value & 0x0F000000) + { + nibbles = 7; + } + else if (value & 0x00F00000) + { + nibbles = 6; + } + else if (value & 0x000F0000) + { + nibbles = 5; + } + else if (value & 0x0000F000) + { + nibbles = 4; + } + else if (value & 0x00000F00) + { + nibbles = 3; + } + else if (value & 0x000000F0) + { + nibbles = 2; + } - m_stream->WriteBits( nibbles - 1, CLR_PRF_CMDS::Bits::NibbleCount ); - m_stream->WriteBits( value, nibbles << SHIFT_PER_NIBBLE ); + m_stream->WriteBits(nibbles - 1, CLR_PRF_CMDS::Bits::NibbleCount); + m_stream->WriteBits(value, nibbles << SHIFT_PER_NIBBLE); } -void CLR_PRF_Profiler::PackAndWriteBits(const CLR_RT_TypeDef_Index& typeDef) +void CLR_PRF_Profiler::PackAndWriteBits(const CLR_RT_TypeDef_Index &typeDef) { NATIVE_PROFILE_CLR_DIAGNOSTICS(); - PackAndWriteBits( typeDef.Assembly() ); - PackAndWriteBits( typeDef.Type() ); + PackAndWriteBits(typeDef.Assembly()); + PackAndWriteBits(typeDef.Type()); } -void CLR_PRF_Profiler::PackAndWriteBits(const CLR_RT_MethodDef_Index& methodDef) +void CLR_PRF_Profiler::PackAndWriteBits(const CLR_RT_MethodDef_Index &methodDef) { NATIVE_PROFILE_CLR_DIAGNOSTICS(); - PackAndWriteBits( methodDef.Assembly() ); - PackAndWriteBits( methodDef.Method() ); + PackAndWriteBits(methodDef.Assembly()); + PackAndWriteBits(methodDef.Method()); } //--// @@ -797,13 +1113,13 @@ HRESULT CLR_PRF_Profiler::Stream_Send() NANOCLR_HEADER(); const int BUFFER_THRESHOLD_BYTES = CLR_RT_HeapBlock_MemoryStream::Buffer::c_PayloadSize * 2 / 3; - const int BUFFER_THRESHOLD_BITS = BUFFER_THRESHOLD_BYTES << 3; + const int BUFFER_THRESHOLD_BITS = BUFFER_THRESHOLD_BYTES << 3; - if(m_stream->BitsWritten() >= BUFFER_THRESHOLD_BITS) + if (m_stream->BitsWritten() >= BUFFER_THRESHOLD_BITS) { NANOCLR_CHECK_HRESULT(Stream_Flush()); - } - //else { Stream isn't above threshold; allow to cache. } + } + // else { Stream isn't above threshold; allow to cache. } NANOCLR_NOCLEANUP(); } @@ -813,39 +1129,43 @@ HRESULT CLR_PRF_Profiler::Stream_Flush() NATIVE_PROFILE_CLR_DIAGNOSTICS(); NANOCLR_HEADER(); - //These need to be paired; If this function is ever used to send multiple stream types, each should get their own packet sequence id. + // These need to be paired; If this function is ever used to send multiple stream types, each should get their own + // packet sequence id. const CLR_UINT32 messageType = CLR_DBG_Commands::c_Profiling_Stream; - CLR_UINT8 buffer[ 2*sizeof(CLR_UINT16) + CLR_RT_HeapBlock_MemoryStream::Buffer::c_PayloadSize ]; - CLR_DBG_Commands::Profiling_Stream* packet = (CLR_DBG_Commands::Profiling_Stream*)buffer; + CLR_UINT8 buffer[2 * sizeof(CLR_UINT16) + CLR_RT_HeapBlock_MemoryStream::Buffer::c_PayloadSize]; + CLR_DBG_Commands::Profiling_Stream *packet = (CLR_DBG_Commands::Profiling_Stream *)buffer; NANOCLR_FOREACH_NODE(CLR_RT_HeapBlock_MemoryStream::Buffer, ptr, m_stream->m_buffers) { int payloadLength = ptr->m_length; - if(payloadLength > 0) + if (payloadLength > 0) { _ASSERTE(sizeof(ptr->m_payload) == CLR_RT_HeapBlock_MemoryStream::Buffer::c_PayloadSize); int bitLength = payloadLength * 8; - if(ptr == m_stream->m_current) + if (ptr == m_stream->m_current) { bitLength -= m_stream->m_avail; } packet->m_bitLen = bitLength; packet->m_seqId = m_packetSeqId++; - memcpy(&packet[ 1 ], ptr->m_payload, payloadLength); + memcpy(&packet[1], ptr->m_payload, payloadLength); int packetLength = sizeof(CLR_DBG_Commands::Profiling_Stream) + payloadLength; - if(!CLR_EE_DBG_EVENT_SEND(messageType, packetLength, buffer, WP_Flags_c_NonCritical)) + if (!CLR_EE_DBG_EVENT_SEND(messageType, packetLength, buffer, WP_Flags_c_NonCritical)) { _ASSERTE(false); NANOCLR_SET_AND_LEAVE(CLR_E_FAIL); } } - //Don't go past the cursor. - if(ptr == m_stream->m_current) { break; } + // Don't go past the cursor. + if (ptr == m_stream->m_current) + { + break; + } } NANOCLR_FOREACH_NODE_END(); @@ -854,5 +1174,4 @@ HRESULT CLR_PRF_Profiler::Stream_Flush() NANOCLR_NOCLEANUP(); } -#endif //#if defined(NANOCLR_PROFILE_NEW) - +#endif // #if defined(NANOCLR_PROFILE_NEW) diff --git a/src/CLR/Helpers/Base64/base64.c b/src/CLR/Helpers/Base64/base64.c index f7741e09e1..179243d2de 100644 --- a/src/CLR/Helpers/Base64/base64.c +++ b/src/CLR/Helpers/Base64/base64.c @@ -5,8 +5,8 @@ // ////////////////////////////////////////////////////////////////////////////////////////////// -// we are using the function declarations matching the mbedTLS ones BUT with weak attribute // -// if the image includes the mbedTLS, these will be replaced by the strong ones from there // +// we are using the function declarations matching the MbedTLS ones BUT with weak attribute // +// if the image includes the MbedTLS, these will be replaced by the strong ones from there // // thus there will be no duplicate code // ////////////////////////////////////////////////////////////////////////////////////////////// @@ -18,7 +18,7 @@ #include "base64.h" -// from mbedTLS common.h +// from MbedTLS common.h #define MBEDTLS_BYTE_0( x ) ( (uint8_t) ( ( x ) & 0xff ) ) #define MBEDTLS_BYTE_1( x ) ( (uint8_t) ( ( ( x ) >> 8 ) & 0xff ) ) #define MBEDTLS_BYTE_2( x ) ( (uint8_t) ( ( ( x ) >> 16 ) & 0xff ) ) diff --git a/src/CLR/Helpers/Base64/base64.h b/src/CLR/Helpers/Base64/base64.h index dc8fc496c4..af7efd89c8 100644 --- a/src/CLR/Helpers/Base64/base64.h +++ b/src/CLR/Helpers/Base64/base64.h @@ -10,8 +10,8 @@ #include ////////////////////////////////////////////////////////////////////////////////////////////// -// we are using the function declarations matching the mbedTLS ones BUT with weak attribute // -// if the image includes the mbedTLS, these will be replaced by the strong ones from there // +// we are using the function declarations matching the MbedTLS ones BUT with weak attribute // +// if the image includes the MbedTLS, these will be replaced by the strong ones from there // // thus there will be no duplicate code // ////////////////////////////////////////////////////////////////////////////////////////////// @@ -44,4 +44,4 @@ extern "C" } #endif -#endif //BASE64_H +#endif // BASE64_H diff --git a/src/CLR/Helpers/nanoprintf/nanoprintf.c b/src/CLR/Helpers/nanoprintf/nanoprintf.c index ba4f970fe9..e003fe5f03 100644 --- a/src/CLR/Helpers/nanoprintf/nanoprintf.c +++ b/src/CLR/Helpers/nanoprintf/nanoprintf.c @@ -1,1066 +1,1243 @@ // // Copyright (c) .NET Foundation and Contributors -// Portions Copyright (c) 2001, 2002 Georges Menie. All rights reserved. -// Portions Copyright (c) 2009-2013 Daniel D Miller. All rights reserved. +// Portions Copyright (c) 2006 - 2021 Skirrid Systems. All rights reserved. // See LICENSE file in the project root for full license information. // -// Notes on this implementation: This is a small/fast implementation of printf variants -// for double (floating) numbers. It is a compromise of size and speed over capability. -// In general the algorithm used in this code can only format a small range of the possible -// values that can be fit in a double. A double can hold roughly +/-1e308, but the code in -// this program uses shifting of 64 bits, so a range of roughly +/-1e18 (2^63). The method -// npf_dsplit_abs supports this limitation and will return a value of "oor" (out-of-range) -// for numbers over 2^63. It will return zero for any numbers below 2^-63. -// -// See the information here: http://0x80.pl/notesen/2015-12-29-float-to-string.html -// -// Notes on this implementation: This is a small/fast implementation of printf variants -// for double (floating) numbers. It is a compromise of size and speed over capability. -// In general the algorithm used in this code can only format a small range of the possible -// values that can be fit in a double. A double can hold roughly +/-1e308, but the code in -// this program uses shifting of 64 bits, so a range of roughly +/-1e18 (2^63). The method -// npf_dsplit_abs supports this limitation and will return a value of "oor" (out-of-range) -// for numbers over 2^63. It will return zero for any numbers below 2^-63. -// -// See the information here: http://0x80.pl/notesen/2015-12-29-float-to-string.html -// -/* - The implementation of nanoprintf begins here, to be compiled only if - NANOPRINTF_IMPLEMENTATION is defined. In a multi-file library what follows - would be nanoprintf.c. -*/ +// clang-format off +// System and config header files are included by the parent stub file. +#include +#include #include "nanoprintf.h" +#include -#if NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS == 1 -#include +/* Define default macro to access the format string using a pointer. */ +#ifndef GET_FORMAT + #define GET_FORMAT(p) (*(p)) #endif -#if NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS == 1 -#ifdef _MSC_VER -#include -typedef SSIZE_T ssize_t; +/* Define default function for printf output. */ +#ifndef PUTCHAR_FUNC + #define PUTCHAR_FUNC putchar +#endif + +/* Renames the functions if they have been defined as macros in printf.h */ +#ifdef printf + #undef printf + #define printf _prntf +#endif + +#ifdef sprintf + #undef sprintf + #define sprintf _sprntf +#endif + +// Macro used to check presence of a feature flag. +// These are defined in print_cfg.h +#define FEATURE(flag) ((FEATURE_FLAGS) & (flag)) + +// Size of buffer for formatting numbers into. +// Use the smallest buffer we can get away with to conserve RAM. +#if FEATURE(USE_BINARY) + #if FEATURE(USE_LONG) + #define BUFMAX 32 + #elif FEATURE(USE_FLOAT) + #define BUFMAX 30 + #else + #define BUFMAX 16 + #endif #else -#include + #if FEATURE(USE_FLOAT) + #define BUFMAX 30 + #elif FEATURE(USE_LONG_LONG) + #define BUFMAX 22 + #else + #define BUFMAX 16 + #endif #endif + +// Bit definitions in the flags variable (integer and general) +#if FEATURE(USE_LEFT_JUST) + #define FL_LEFT_JUST (1<<0) +#else + #define FL_LEFT_JUST 0 +#endif +#define FL_ZERO_PAD (1<<1) +#define FL_SPECIAL (1<<2) +#define FL_PLUS (1<<3) +#define FL_SPACE (1<<4) +#define FL_NEG (1<<5) +#define FL_LONG (1<<6) +#define FL_FSTR (1<<7) + +// Bit definitions in the fflags variable (mostly floating point) +#define FF_UCASE (1<<0) +#define FF_ECVT (1<<1) +#define FF_FCVT (1<<2) +#define FF_GCVT (1<<3) +#define FF_NRND (1<<4) +#define FF_XLONG (1<<5) + +// Check whether integer or octal support is needed. +#define HEX_CONVERT_ONLY !(FEATURE(USE_SIGNED) || FEATURE(USE_SIGNED_I) || FEATURE(USE_UNSIGNED) || \ + FEATURE(USE_OCTAL) || FEATURE(USE_BINARY)) + +/***************************************************************************** +Floating point +******************************************************************************/ +#if FEATURE(USE_FLOAT) + +// Most compilers can support double precision +#ifndef NO_DOUBLE_PRECISION + #define DP_LIMIT 310 + #define MAX_POWER 256 +// [NF_CHANGE] + #define FLOAT_DIGITS 18 +// [END_NF_CHANGE] +#else + #define DP_LIMIT 40 + #define MAX_POWER 32 + #define FLOAT_DIGITS 8 +#endif + +#if !FEATURE(USE_SMALL_FLOAT) + // Floating point normalisation tables for fast normalisation. + // smalltable[] is used for value < 1.0 + static const double smalltable[] = { + #ifndef NO_DOUBLE_PRECISION + 1e-256, 1e-128, 1e-64, + #endif + 1e-32, 1e-16, 1e-8, 1e-4, 1e-2, 1e-1, 1.0 + }; + // large table[] is used for value >= 10.0 + static const double largetable[] = { + #ifndef NO_DOUBLE_PRECISION + 1e+256, 1e+128, 1e+64, + #endif + 1e+32, 1e+16, 1e+8, 1e+4, 1e+2, 1e+1 + }; +#endif + +#ifdef NO_DOUBLE_PRECISION + // Double precision not supported by compiler. + // Single precision numbers up to 10^38 require only 8-bit exponent. + typedef signed char flt_width_t; +#else + // Double precision numbers up to 10^308 require 16-bit exponents. + typedef signed short flt_width_t; #endif -#define NPF_MIN(x, y) ((x) < (y) ? (x) : (y)) -#define NPF_MAX(x, y) ((x) > (y) ? (x) : (y)) +// These define the maximum number of digits that can be output into the buffer. +// %f requires space for sign, point and rounding digit. +#define DIGITS_MAX_F (BUFMAX-3) +// %e requires space for sign, point and up to 3 digit exponent (E+123). +// Rounding happens in the place where the exponent will go. +#define DIGITS_MAX_E (BUFMAX-7) -int npf__parse_format_spec(char const *format, npf__format_spec_t *out_spec) +// Function to trim trailing zeros and DP in 'g' mode. +// Return pointer to new string terminator position. +static char *trim_zeros(char *p) { - char const *cur = format; + // Trim trailing 0's in 'g' mode. + while (*p == '0') + p--; + // If last non-zero is DP, trim that as well. + if (*p != '.') ++p; + return p; +} -#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 - out_spec->left_justified = 0; - out_spec->leading_zero_pad = 0; -#endif - out_spec->prepend_sign = 0; - out_spec->prepend_space = 0; - out_spec->alternative_form = 0; - out_spec->length_modifier = NPF_FMT_SPEC_LEN_MOD_NONE; +/* --------------------------------------------------------------------------- +Function: format_float() +Called from the main doprnt function to handle formatting of floating point +values. The general process is: +1. Check for non-numbers and just display the error code. +2. Convert number to positive form. +3. Normalise the number to lie in the range 1.0 <= number < 10.0 +4. Work out where the DP lies and optimum format. +5. Output the digits in reverse order. +--------------------------------------------------------------------------- */ +static char *format_float(double number, flt_width_t ndigits, flt_width_t width, + unsigned char flags, unsigned char fflags, char *buf) +{ + flt_width_t decpt; + flt_width_t nzero; + unsigned char i; + char *p = buf + 2; + char *pend; + +#ifndef NO_ISNAN_ISINF + // Handle special values which need no formatting + if (isinf(number)) + { + buf[0] = 'I'; + buf[1] = 'n'; + buf[2] = 'f'; + buf[3] = '\0'; + return buf; + } + if (isnan(number)) + { + buf[0] = 'N'; + buf[1] = 'a'; + buf[2] = 'N'; + buf[3] = '\0'; + return buf; + } +#endif - /* cur points at the leading '%' character */ - while (*++cur) + // Handle all numbers as if they were positive. + if (number < 0) { - /* Optional flags */ - switch (*cur) - { -#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 - case '-': - out_spec->left_justified = 1; - out_spec->leading_zero_pad = 0; - continue; - case '0': - out_spec->leading_zero_pad = !out_spec->left_justified; - continue; -#endif - case '+': - out_spec->prepend_sign = 1; - out_spec->prepend_space = 0; - continue; - case ' ': - out_spec->prepend_space = !out_spec->prepend_sign; - continue; - case '#': - out_spec->alternative_form = 1; - continue; - default: - break; - } - break; + number = -number; + flags |= FL_NEG; } -#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 - /* Minimum field width */ - out_spec->field_width_type = NPF_FMT_SPEC_FIELD_WIDTH_NONE; - if (*cur == '*') + if (fflags & FF_FCVT) { - /* '*' modifiers require more varargs */ - out_spec->field_width_type = NPF_FMT_SPEC_FIELD_WIDTH_STAR; - ++cur; + // Number of DP cannot be negative. + if (ndigits < 0) + ndigits = 0; } else { - out_spec->field_width = 0; - if ((*cur >= '0') && (*cur <= '9')) - { - out_spec->field_width_type = NPF_FMT_SPEC_FIELD_WIDTH_LITERAL; - } - while ((*cur >= '0') && (*cur <= '9')) - { - out_spec->field_width = (out_spec->field_width * 10) + (*cur++ - '0'); - } + // Significant digits must be at least 1. + if (ndigits < 1) + ndigits = 1; } -#endif -#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 - /* Precision */ - out_spec->precision_type = NPF_FMT_SPEC_PRECISION_NONE; - if (*cur == '.') + // Prefill buffer with zeros. + for (i = 0; i < BUFMAX; i++) + buf[i] = '0'; + + if (number == 0) { - ++cur; - if (*cur == '*') + // Special case to correct number of decimals, significant figures, + // and avoid printing 0E-00. + decpt = 1; + } + else + { + // Normalise the number such that it lies in the range 1 <= n < 10. +#if FEATURE(USE_SMALL_FLOAT) + /* Normalise using a linear search. This code is simple and uses + * least code space. It also eliminates the lookup tables which may + * otherwise take up RAM space. However, it can take many more operations + * to execute for the full range of floating point values, and may + * introduce rounding errors. Use only when space is critical. + */ + // First make small numbers bigger. + decpt = 1; + while (number < 1.0) { - out_spec->precision_type = NPF_FMT_SPEC_PRECISION_STAR; - ++cur; + number *= 10.0; + --decpt; } - else if (*cur == '-') + // Then make big numbers smaller. + while (number >= 10.0) { - /* ignore negative precision */ - out_spec->precision_type = NPF_FMT_SPEC_PRECISION_NONE; - ++cur; - while ((*cur >= '0') && (*cur <= '9')) + number /= 10.0; + ++decpt; +#ifdef NO_ISNAN_ISINF + // Avoid this loop hanging on infinity. + if (decpt > DP_LIMIT) { - ++cur; + buf[0] = 'I'; + buf[1] = 'n'; + buf[2] = 'f'; + buf[3] = '\0'; + return buf; } +#endif } - else +#else + flt_width_t power10 = MAX_POWER; + decpt = 1; + + if(number == DBL_MAX) { - out_spec->precision = 0; - out_spec->precision_type = NPF_FMT_SPEC_PRECISION_LITERAL; - while ((*cur >= '0') && (*cur <= '9')) - { - out_spec->precision = (out_spec->precision * 10) + (*cur++ - '0'); - } + number = 1.7976931348623157; + decpt = 309; } - } -#endif - - /* Length modifier */ - switch (*cur++) - { - case 'h': - if (*cur == 'h') - { - out_spec->length_modifier = NPF_FMT_SPEC_LEN_MOD_CHAR; - ++cur; - } - else + else if(number == DBL_MIN) + { + number = -1.7976931348623157; + decpt = -309; + } + else + { + /* Normalise using a binary search, making the largest possible + * adjustment first and getting progressively smaller. This gets + * to the answer in the fastest time, with the minimum number of + * operations to introduce rounding errors. + */ + // First make small numbers bigger. + + i = 0; + while (number < 1.0) { - out_spec->length_modifier = NPF_FMT_SPEC_LEN_MOD_SHORT; + while (number < smalltable[i + 1]) + { + number /= smalltable[i]; + decpt -= power10; + } + power10 >>= 1; + i++; } - break; - case 'l': -#if NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS == 1 - if (*cur == 'l') + // Then make big numbers smaller. + power10 = MAX_POWER; + i = 0; + while (number >= 10.0) { - out_spec->length_modifier = NPF_FMT_SPEC_LEN_MOD_LARGE_LONG_LONG; - ++cur; + while (number >= largetable[i]) + { + number /= largetable[i]; + decpt += power10; +#ifdef NO_ISNAN_ISINF + // Avoid this loop hanging on infinity. + if (decpt > DP_LIMIT) + { + buf[0] = 'I'; + buf[1] = 'n'; + buf[2] = 'f'; + buf[3] = '\0'; + return buf; + } +#endif + } + power10 >>= 1; + i++; } - else + } #endif - out_spec->length_modifier = NPF_FMT_SPEC_LEN_MOD_LONG; - break; -#if NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS == 1 - case 'L': - out_spec->length_modifier = NPF_FMT_SPEC_LEN_MOD_LONG_DOUBLE; - break; -#endif -#if NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS == 1 - case 'j': - out_spec->length_modifier = NPF_FMT_SPEC_LEN_MOD_LARGE_INTMAX; - break; - case 'z': - out_spec->length_modifier = NPF_FMT_SPEC_LEN_MOD_LARGE_SIZET; - break; - case 't': - out_spec->length_modifier = NPF_FMT_SPEC_LEN_MOD_LARGE_PTRDIFFT; - break; -#endif - default: - --cur; - break; } - - /* Conversion specifier */ - switch (*cur++) + + // For g conversions determine whether to use e or f mode. + if (fflags & FF_GCVT) { - case '%': - out_spec->conv_spec = NPF_FMT_SPEC_CONV_PERCENT; -#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 - out_spec->precision_type = NPF_FMT_SPEC_PRECISION_NONE; -#endif - break; - case 'c': - out_spec->conv_spec = NPF_FMT_SPEC_CONV_CHAR; -#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 - out_spec->precision_type = NPF_FMT_SPEC_PRECISION_NONE; -#endif - break; - case 's': - out_spec->conv_spec = NPF_FMT_SPEC_CONV_STRING; -#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 - out_spec->leading_zero_pad = 0; -#endif - break; - case 'i': - out_spec->conv_spec = NPF_FMT_SPEC_CONV_SIGNED_INT; - break; - case 'd': - out_spec->conv_spec = NPF_FMT_SPEC_CONV_SIGNED_INT; - break; - case 'o': - out_spec->conv_spec = NPF_FMT_SPEC_CONV_OCTAL; - break; - case 'x': - out_spec->conv_spec = NPF_FMT_SPEC_CONV_HEX_INT; - out_spec->conv_spec_case = NPF_FMT_SPEC_CONV_CASE_LOWER; - break; - case 'X': - out_spec->conv_spec = NPF_FMT_SPEC_CONV_HEX_INT; - out_spec->conv_spec_case = NPF_FMT_SPEC_CONV_CASE_UPPER; - break; - case 'u': - out_spec->conv_spec = NPF_FMT_SPEC_CONV_UNSIGNED_INT; - break; -#if NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS == 1 - case 'f': - out_spec->conv_spec = NPF_FMT_SPEC_CONV_FLOAT_DECIMAL; - out_spec->conv_spec_case = NPF_FMT_SPEC_CONV_CASE_LOWER; - break; - case 'F': - out_spec->conv_spec = NPF_FMT_SPEC_CONV_FLOAT_DECIMAL; - out_spec->conv_spec_case = NPF_FMT_SPEC_CONV_CASE_UPPER; - break; -#endif -#if NANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS == 1 - case 'n': - /* todo: reject string if flags or width or precision exist */ - out_spec->conv_spec = NPF_FMT_SPEC_CONV_WRITEBACK; -#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 - out_spec->precision_type = NPF_FMT_SPEC_PRECISION_NONE; -#endif - break; -#endif - case 'p': - out_spec->conv_spec = NPF_FMT_SPEC_CONV_POINTER; -#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 - out_spec->precision_type = NPF_FMT_SPEC_PRECISION_NONE; -#endif - break; - default: - return 0; + /* 'g' format uses 'f' notation where it can and + * 'e' notation where the exponent is more extreme. + * Some references indicate that it uses the more + * compact form but the ANSI standard give an explict + * definition: Use 'e' when the exponent is < -4 + * or where the exponent is >= ndigits. + * The exponent is equal to decpt - 1 so this translates + * to decpt <= -4 || decpt > ndigits + * http://www.acm.uiuc.edu/webmonkeys/book/c_guide/2.12.html#printf + * http://www.mkssoftware.com/docs/man3/printf.3.asp + */ + if (decpt > -4 && decpt <= ndigits) + fflags |= FF_FCVT; } - -#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 - if ((out_spec->precision_type == NPF_FMT_SPEC_PRECISION_NONE) || - (out_spec->precision_type == NPF_FMT_SPEC_PRECISION_STAR)) + + // Sanitise ndigits making sure it fits buffer space. + if (fflags & FF_FCVT) { - switch (out_spec->conv_spec) + if (!(fflags & FF_GCVT)) { - case NPF_FMT_SPEC_CONV_PERCENT: - case NPF_FMT_SPEC_CONV_CHAR: - case NPF_FMT_SPEC_CONV_STRING: - case NPF_FMT_SPEC_CONV_POINTER: -#if NANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS == 1 - case NPF_FMT_SPEC_CONV_WRITEBACK: -#endif - out_spec->precision = 0; - break; - case NPF_FMT_SPEC_CONV_SIGNED_INT: - case NPF_FMT_SPEC_CONV_OCTAL: - case NPF_FMT_SPEC_CONV_HEX_INT: - case NPF_FMT_SPEC_CONV_UNSIGNED_INT: - out_spec->precision = 1; - break; -#if NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS == 1 - case NPF_FMT_SPEC_CONV_FLOAT_DECIMAL: - out_spec->precision = 6; - break; -#endif - default: - break; + // For fcvt operation the number of digits is used to + // refer to decimal places rather than significant digits. + ndigits += decpt; + // When there are no significant digits, + // avoid printing too many 0's. + if (ndigits < 0) + { + decpt -= ndigits; + } + } + /* For 'f' conversions with positive DP value that would overflow + * the buffer space, there is no way to display this so fall back + * to 'e' format. 'f' conversion needs space for sign, point and + * rounding digit. The point may be forced using the special flag + * and the rounding digit may be included in the case of maximum + * overflow. + */ + if (decpt > DIGITS_MAX_F) + { + fflags &= ~FF_FCVT; } } -#endif - return (int)(cur - format); -} - -void npf__bufputc(int c, void *ctx) -{ - npf__bufputc_ctx_t *bpc = (npf__bufputc_ctx_t *)ctx; - if (bpc->cur < bpc->len - 1) + nzero = 0; + if (fflags & FF_FCVT) { - bpc->dst[bpc->cur++] = (char)c; - } -} - -void npf__bufputc_nop(int c, void *ctx) -{ - (void)c; - (void)ctx; -} - -int npf__itoa_rev(char *buf, npf__int_t i) -{ - char *dst = buf; - if (i == 0) - { - *dst++ = '0'; - } - else - { - int const neg = (i < 0) ? -1 : 1; - while (i) + if (decpt < 1) + { + // Values < 1 require leading zeros before the real digits. + nzero = 1 - decpt; + } + // Check for buffer fit. Zeros take precedence. + if (nzero > DIGITS_MAX_F) + { + nzero = DIGITS_MAX_F; + ndigits = -1; + } + if (ndigits < 0) { - *dst++ = (char)('0' + (neg * (i % 10))); - i /= 10; + // First significant digit is below rounding range. + fflags |= FF_NRND; + ndigits = 0; } + else if (ndigits + nzero > DIGITS_MAX_F) + { + ndigits = DIGITS_MAX_F - nzero; + } + p += nzero; } - return (int)(dst - buf); -} - -int npf__utoa_rev(char *buf, npf__uint_t i, unsigned base, npf__format_spec_conversion_case_t cc) -{ - char *dst = buf; - if (i == 0) + else { - *dst++ = '0'; + // Allow space for sign, point exponent. + if (ndigits > DIGITS_MAX_E) + ndigits = DIGITS_MAX_E; } - else + + // Format digits one-by-one into the output string. + // One extra digit is required for rounding. + for (i = 0; i <= ndigits; i++) { - unsigned const base_c = (cc == NPF_FMT_SPEC_CONV_CASE_LOWER) ? 'a' : 'A'; - while (i) + // Ignore digits beyond the supported precision. + if (i >= FLOAT_DIGITS) { - unsigned const d = (unsigned)(i % base); - i /= base; - *dst++ = (d < 10) ? (char)('0' + d) : (char)(base_c + (d - 10)); + *p++ = '0'; + } + else + { + // number is normalised to a positive value between 0 and 9. + int n = number; + *p++ = n + '0'; + number = (number - n) * 10; } } - return (int)(dst - buf); -} - -#if NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS == 1 -enum -{ - NPF_MANTISSA_BITS = 52, - NPF_EXPONENT_BITS = 11, - NPF_EXPONENT_BIAS = 1023, - NPF_FRACTION_BIN_DIGITS = 64, - NPF_MAX_FRACTION_DEC_DIGITS = 8 -}; - -int npf__dsplit_abs(double d, uint64_t *out_int_part, uint64_t *out_frac_part, int *out_frac_base10_neg_exp) -{ - /* conversion algorithm by Wojciech Muła (zdjęcia@garnek.pl) - http://0x80.pl/notesen/2015-12-29-float-to-string.html - grisu2 (https://bit.ly/2JgMggX) and ryu (https://bit.ly/2RLXSg0) - are fast + precise + round, but require large lookup tables. - */ - - /* union-cast is UB, so copy through char*, compiler can optimize. */ - uint64_t d_bits; + // Store a pointer to the last (rounding) digit. + pend = --p; + // Round the result directly in the string buffer. + // Only use the calculated digits, not trailing 0's. + if (i > FLOAT_DIGITS) { - char const *src = (char const *)&d; - char *dst = (char *)&d_bits; - *dst++ = *src++; - *dst++ = *src++; - *dst++ = *src++; - *dst++ = *src++; - *dst++ = *src++; - *dst++ = *src++; - *dst++ = *src++; - *dst++ = *src++; + p -= (i - FLOAT_DIGITS); } - - int const exponent = ((int)((d_bits >> NPF_MANTISSA_BITS) & ((1u << NPF_EXPONENT_BITS) - 1u)) - NPF_EXPONENT_BIAS) - - NPF_MANTISSA_BITS; - - /* value is out of range */ - if (exponent >= (64 - NPF_MANTISSA_BITS)) + if (!(fflags & FF_NRND) && *p >= '5') { - return 0; + for (;;) + { + if (i == 0) + { + // The rounding has rippled all the way through to + // the first digit. i.e. 9.999..9 -> 10.0 + // Just replace the first 0 with a 1 and shift the DP. + *p = '1'; + ++decpt; + // This increases the displayed digits for 'f' only. + if ((fflags & (FF_FCVT|FF_GCVT)) == FF_FCVT) + { + ++ndigits; + ++pend; + } + break; + } + // Previous digit was a rollover + *p-- = '0'; + // Increment next digit and break out unless there is a rollover. + if (*p != '9') + { + (*p)++; + break; + } + } } - uint64_t const implicit_one = ((uint64_t)1) << NPF_MANTISSA_BITS; - uint64_t const mantissa = d_bits & (implicit_one - 1); - uint64_t const mantissa_norm = mantissa | implicit_one; - - if (exponent > 0) + // Insert the decimal point + if (fflags & FF_FCVT) { - *out_int_part = (uint64_t)mantissa_norm << exponent; - } - else if (exponent < 0) - { - if (-exponent > NPF_MANTISSA_BITS) + flt_width_t num; + num = (decpt > 1) ? decpt : 1; + p = buf + 1; + for (i = 0; i < num; i++) { - *out_int_part = 0; + *p = *(p+1); + ++p; + } + if (p + 1 < pend || (flags & FL_SPECIAL)) + { + // There are digits after the DP or DP is forced. + *p = '.'; + // Trim trailing 0's in 'g' mode. + if ((fflags & FF_GCVT) && !(flags & FL_SPECIAL)) + { + pend = trim_zeros(pend - 1); + } } else { - *out_int_part = mantissa_norm >> -exponent; + // DP at end is not required. + --pend; } + // Leave p pointing to start of digit string. + p = buf + 1; } else { - *out_int_part = mantissa_norm; - } - - uint64_t frac; - { - int const shift = NPF_FRACTION_BIN_DIGITS + exponent - 4; - if ((shift >= (NPF_FRACTION_BIN_DIGITS - 4)) || (shift < 0)) + // Leave p pointing to start of digit string. + if (ndigits > 1 || (flags & FL_SPECIAL)) { - frac = 0; + // Decimal point is always after first digit. + // Shift digit and insert point. + buf[1] = buf[2]; + buf[2] = '.'; + p = buf + 1; } else { - frac = ((uint64_t)mantissa_norm) << shift; + // No decimal point needed. + p = buf + 2; } - /* multiply off the leading one's digit */ - frac &= 0x0fffffffffffffffllu; - frac *= 10; - } - - { - /* Count the number of 0s at the beginning of the fractional part. - */ - int frac_base10_neg_exp = 0; - while (frac && ((frac >> (NPF_FRACTION_BIN_DIGITS - 4))) == 0) + // Trim trailing 0's in 'g' mode. + if ((fflags & FF_GCVT) && !(flags & FL_SPECIAL)) + { + pend = trim_zeros(pend - 1); + } + // Add exponent + *pend++ = (fflags & FF_UCASE) ? 'E' : 'e'; + if (--decpt < 0) + { + *pend++ = '-'; + decpt = -decpt; + } + else + { + *pend++ = '+'; + } +#ifndef EXP_3_DIGIT + // Optional 3rd digit of exponent + if (decpt > 99) +#endif { - ++frac_base10_neg_exp; - frac &= 0x0fffffffffffffffllu; - frac *= 10; + *pend++ = decpt / 100 + '0'; + decpt %= 100; } - *out_frac_base10_neg_exp = frac_base10_neg_exp; + // Always print at least 2 digits of exponent. + *pend++ = decpt / 10 + '0'; + *pend++ = decpt % 10 + '0'; } + // Add the sign prefix. + if (flags & FL_NEG) *--p = '-'; +#if FEATURE(USE_PLUS_SIGN) + else if (flags & FL_PLUS) *--p = '+'; +#endif +#if FEATURE(USE_SPACE_SIGN) + else if (flags & FL_SPACE) *--p = ' '; +#endif + *pend = '\0'; // Add null terminator + +#if FEATURE(USE_ZERO_PAD) + if (flags & FL_ZERO_PAD) { - /* Convert the fractional part to base 10. */ - unsigned frac_part = 0; - for (int i = 0; frac && (i < NPF_MAX_FRACTION_DEC_DIGITS); ++i) + /* Implement leading zero padding by shifting the formatted buffer. + * This is not the most efficient but at any other point it is hard + * to know what the exact buffer length will be. The processing time + * pales into insignificance next to the floating point operations. + */ + flt_width_t fwidth = pend - p; + if (width > BUFMAX) + width = BUFMAX; + if (fwidth < width) { - frac_part *= 10; - frac_part += (unsigned)(frac >> (NPF_FRACTION_BIN_DIGITS - 4)); - frac &= 0x0fffffffffffffffllu; - frac *= 10; + // Set pointer to location after the new end point. + // It will be predecremented. + char *pnew = pend + width - fwidth + 1; + ++pend; + // Do not shift the sign/space if used. + if (flags & (FL_NEG | FL_PLUS | FL_SPACE)) + ++p; + // p now points to the last character to move. + // Shift the buffer rightwards + do *--pnew = *--pend; + while (pend != p); + // Fill the remainder with 0s. + do *--pnew = '0'; + while (pnew != p); + // Restore the former value of p. + if (flags & (FL_NEG | FL_PLUS | FL_SPACE)) + --p; } - *out_frac_part = frac_part; } - return 1; -} +#endif -int npf__dtoa_rev(char *buf, double d, unsigned base, npf__format_spec_conversion_case_t cc, int *out_frac_chars) + return p; // Start of string +} +#endif // End of floating point section + +/***************************************************************************** +Integer, character and string +******************************************************************************/ + +#if FEATURE(USE_SPACE_PAD) +/* --------------------------------------------------------------------------- +Function: p_len() +Helper function to find length of string. +This offers a small space saving over strlen and allows for reading strings +from flash where the micro uses different semantics to access program memory. +This is used on the AVR processor. +--------------------------------------------------------------------------- */ +#if FEATURE(USE_FSTRING) +static width_t p_len(char *p, unsigned char flags) +#else +static width_t p_len(char *p) +#endif { - char const case_c = (cc == NPF_FMT_SPEC_CONV_CASE_LOWER) ? 'a' - 'A' : 0; - - if (d != d) - { - *buf++ = (char)('N' + case_c); - *buf++ = (char)('A' + case_c); - *buf++ = (char)('N' + case_c); - return -3; - } - - if (d == INFINITY) - { - *buf++ = (char)('F' + case_c); - *buf++ = (char)('N' + case_c); - *buf++ = (char)('I' + case_c); - return -3; - } - - uint64_t int_part, frac_part; - int frac_base10_neg_exp; - - if (npf__dsplit_abs(d, &int_part, &frac_part, &frac_base10_neg_exp) == 0) - { - *buf++ = (char)('R' + case_c); - *buf++ = (char)('O' + case_c); - *buf++ = (char)('O' + case_c); - return -3; - } - - unsigned const base_c = (cc == NPF_FMT_SPEC_CONV_CASE_LOWER) ? 'a' : 'A'; - char *dst = buf; - - // write the fractional digits - while (frac_part) - { - unsigned const digit = (unsigned)(frac_part % base); - frac_part /= base; - *dst++ = (digit < 10) ? (char)('0' + digit) : (char)(base_c + (digit - 10)); - } - - // write the 0 digits between the . and the first fractional digit - while (frac_base10_neg_exp-- > 0) - { - *dst++ = '0'; - } - - *out_frac_chars = (int)(dst - buf); - - // write the decimal point - *dst++ = '.'; - - // write the integer digits - if (int_part == 0) + width_t len = 0; +#if FEATURE(USE_FSTRING) + if (flags & FL_FSTR) { - *dst++ = '0'; + while (GET_FORMAT(p)) + { + ++p; + ++len; + } } else +#endif { - while (int_part) - { - unsigned const digit = (unsigned)(int_part % base); - int_part /= base; - *dst++ = (digit < 10) ? (char)('0' + digit) : (char)(base_c + (digit - 10)); - } + while (*p++) ++len; } - - return (int)(dst - buf); + return len; } #endif -#define NPF_PUTC(VAL) \ - do \ - { \ - pc((VAL), pc_ctx); \ - ++n; \ - } while (0) - -#define NPF_EXTRACT(MOD, CAST_TO, EXTRACT_AS) \ - case NPF_FMT_SPEC_LEN_MOD_##MOD: \ - val = (CAST_TO)va_arg(vlist, EXTRACT_AS); \ - break - -#define NPF_WRITEBACK(MOD, TYPE) \ - case NPF_FMT_SPEC_LEN_MOD_##MOD: \ - *(va_arg(vlist, TYPE *)) = (TYPE)n; \ - break +#ifdef __GNUC__ +#pragma GCC diagnostic push +// -Wimplicit-fallthrough option was added in GCC 7 +#if (__GNUC__ >= 7) +#pragma GCC diagnostic ignored "-Wimplicit-fallthrough" +#endif +#endif -int npf_vpprintf(npf_putc pc, void *pc_ctx, char const *format, va_list vlist) +/* --------------------------------------------------------------------------- +Function: doprnt() +This is the main worker function which does all the formatting. +The output function must always be provided. +Unless BASIC_PRINTF is defined it also needs the context variable, +which tells the output function where to write. +--------------------------------------------------------------------------- */ +#ifdef BASIC_PRINTF_ONLY +static printf_t doprnt(void (*func)(char c), const char *fmt, va_list ap) +#else +static printf_t doprnt(void *context, void (*func)(char c, void *context), size_t n, const char *fmt, va_list ap) +#endif { - npf__format_spec_t fs = {0}; - char const *cur = format; - int n = 0, sign = 0, i; +#if FEATURE(USE_LONG_LONG) + unsigned long long uvalue; +#elif FEATURE(USE_LONG) + unsigned long uvalue; +#else + unsigned uvalue; +#endif +#if !HEX_CONVERT_ONLY + unsigned base; +#endif +#if FEATURE(USE_SPACE_PAD) || FEATURE(USE_ZERO_PAD) || FEATURE(USE_FLOAT) + width_t width; + width_t fwidth; +#endif +#if FEATURE(USE_PRECISION) || FEATURE(USE_FLOAT) + width_t precision; +#else + #define precision -1 +#endif + char convert, c; + char *p; + char buffer[BUFMAX+1]; +#ifdef PRINTF_T + printf_t count = 0; +#endif + unsigned char flags; +#if FEATURE(USE_FLOAT) || FEATURE(USE_LONG_LONG) + unsigned char fflags; +#endif +#if FEATURE(USE_FLOAT) + double fvalue; +#endif + + buffer[BUFMAX] = '\0'; - while (*cur) + for (;;) { - if (*cur != '%') + convert = GET_FORMAT(fmt); + if (convert == 0) break; + if (convert == '%') { - /* Non-format character, write directly */ - NPF_PUTC(*cur++); - } - else - { - /* Might be a format run, try to parse */ - int const fs_len = npf__parse_format_spec(cur, &fs); - if (fs_len == 0) - { - /* Invalid format specifier, write and continue */ - NPF_PUTC(*cur++); - } - else - { - /* Format specifier, convert and write argument */ - char cbuf_mem[32], *cbuf = cbuf_mem, sign_c; - int cbuf_len = 0; -#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 - int field_pad = 0; - char pad_c; + p = buffer + BUFMAX; +#if FEATURE(USE_PRECISION) || FEATURE(USE_FLOAT) + precision = -1; #endif -#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 - int prec_pad = 0; +#if FEATURE(USE_SPACE_PAD) || FEATURE(USE_ZERO_PAD) || FEATURE(USE_FLOAT) + width = 0; #endif -#if NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS == 1 - int frac_chars = 0, inf_or_nan = 0; +#if FEATURE(USE_FLOAT) || FEATURE(USE_LONG_LONG) + fflags = 0; #endif + flags = 0; -#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 - if (fs.field_width_type == NPF_FMT_SPEC_FIELD_WIDTH_STAR) + // Extract flag chars + for (;;) + { + convert = GET_FORMAT(++fmt); +#if FEATURE(USE_ZERO_PAD) + if (convert == '0') { - /* If '*' was used as field width, read it from args. */ - int const field_width = va_arg(vlist, int); - fs.field_width_type = NPF_FMT_SPEC_FIELD_WIDTH_LITERAL; - if (field_width >= 0) - { - fs.field_width = field_width; - } - else - { - /* Negative field width is left-justified. */ - fs.field_width = -field_width; - fs.left_justified = 1; - } + flags |= FL_ZERO_PAD; } + else #endif - -#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 - if (fs.precision_type == NPF_FMT_SPEC_PRECISION_STAR) +#if FEATURE(USE_PLUS_SIGN) + if (convert == '+') { - /* If '*' was used as precision, read from args. */ - int const precision = va_arg(vlist, int); - if (precision >= 0) - { - fs.precision_type = NPF_FMT_SPEC_PRECISION_LITERAL; - fs.precision = precision; - } - else - { - /* Negative precision is ignored. */ - fs.precision_type = NPF_FMT_SPEC_PRECISION_NONE; - } + flags |= FL_PLUS; } + else #endif - - /* Convert the argument to string and point cbuf at it */ - switch (fs.conv_spec) +#if FEATURE(USE_LEFT_JUST) + if (convert == '-') { - case NPF_FMT_SPEC_CONV_PERCENT: - *cbuf = '%'; - cbuf_len = 1; - break; - - case NPF_FMT_SPEC_CONV_CHAR: /* 'c' */ - *cbuf = (char)va_arg(vlist, int); - cbuf_len = 1; - break; - - case NPF_FMT_SPEC_CONV_STRING: - { /* 's' */ - char *s = va_arg(vlist, char *); - /* don't bother loading cbuf, just point to s */ - cbuf = s; - while (*s) - ++s; - cbuf_len = (int)(s - cbuf); -#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 - if (fs.precision_type == NPF_FMT_SPEC_PRECISION_LITERAL) - { - /* precision modifier truncates strings */ - cbuf_len = NPF_MIN(fs.precision, cbuf_len); - } -#endif - } - break; - - case NPF_FMT_SPEC_CONV_SIGNED_INT: - { /* 'i', 'd' */ - npf__int_t val = 0; - switch (fs.length_modifier) - { - NPF_EXTRACT(NONE, int, int); - NPF_EXTRACT(SHORT, short, int); - NPF_EXTRACT(LONG, long, long); - NPF_EXTRACT(LONG_DOUBLE, int, int); - NPF_EXTRACT(CHAR, signed char, int); -#if NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS == 1 - NPF_EXTRACT(LARGE_LONG_LONG, long long, long long); - NPF_EXTRACT(LARGE_INTMAX, intmax_t, intmax_t); - NPF_EXTRACT(LARGE_SIZET, ssize_t, ssize_t); - NPF_EXTRACT(LARGE_PTRDIFFT, ptrdiff_t, ptrdiff_t); -#endif - default: - break; - } - - sign = (val < 0) ? -1 : 1; - -#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 - /* special case, if prec and value are 0, skip */ - if (!val && !fs.precision && (fs.precision_type == NPF_FMT_SPEC_PRECISION_LITERAL)) - { - cbuf_len = 0; - } - else + flags |= FL_LEFT_JUST; + } + else #endif - { - /* print the number into cbuf */ - cbuf_len = npf__itoa_rev(cbuf, val); - } - } - break; - - case NPF_FMT_SPEC_CONV_OCTAL: /* 'o' */ - case NPF_FMT_SPEC_CONV_HEX_INT: /* 'x', 'X' */ - case NPF_FMT_SPEC_CONV_UNSIGNED_INT: - { /* 'u' */ - sign = 0; - unsigned const base = (fs.conv_spec == NPF_FMT_SPEC_CONV_OCTAL) - ? 8 - : ((fs.conv_spec == NPF_FMT_SPEC_CONV_HEX_INT) ? 16 : 10); - npf__uint_t val = 0; - switch (fs.length_modifier) - { - NPF_EXTRACT(NONE, unsigned, unsigned); - NPF_EXTRACT(SHORT, unsigned short, unsigned); - NPF_EXTRACT(LONG, unsigned long, unsigned long); - NPF_EXTRACT(LONG_DOUBLE, unsigned, unsigned); - NPF_EXTRACT(CHAR, unsigned char, unsigned); -#if NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS == 1 - NPF_EXTRACT(LARGE_LONG_LONG, unsigned long long, unsigned long long); - NPF_EXTRACT(LARGE_INTMAX, uintmax_t, uintmax_t); - NPF_EXTRACT(LARGE_SIZET, size_t, size_t); - NPF_EXTRACT(LARGE_PTRDIFFT, size_t, size_t); -#endif - default: - break; - } - -#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 - if (!val && !fs.precision) - { - if ((fs.conv_spec == NPF_FMT_SPEC_CONV_OCTAL) && fs.alternative_form) - { - /* octal special case, print a single '0' */ - fs.precision = 1; - } - else if (fs.precision_type == NPF_FMT_SPEC_PRECISION_LITERAL) - { - /* 0 value + 0 precision, print nothing */ - cbuf_len = 0; - } - } - else +#if FEATURE(USE_SPACE_SIGN) + if (convert == ' ') + { + flags |= FL_SPACE; + } + else #endif - { - /* print the number info cbuf */ - cbuf_len = npf__utoa_rev(cbuf, val, base, fs.conv_spec_case); - } - - /* alt form adds '0' octal or '0x' hex prefix */ - if (val && fs.alternative_form) - { - if (fs.conv_spec == NPF_FMT_SPEC_CONV_OCTAL) - { - cbuf[cbuf_len++] = '0'; - } - else if (fs.conv_spec == NPF_FMT_SPEC_CONV_HEX_INT) - { - cbuf[cbuf_len++] = (fs.conv_spec_case == NPF_FMT_SPEC_CONV_CASE_LOWER) ? 'x' : 'X'; - cbuf[cbuf_len++] = '0'; - } - } - } - break; - - case NPF_FMT_SPEC_CONV_POINTER: - { /* 'p' */ - cbuf_len = npf__utoa_rev( - cbuf, - (npf__uint_t)(uintptr_t)va_arg(vlist, void *), - 16, - NPF_FMT_SPEC_CONV_CASE_LOWER); - cbuf[cbuf_len++] = 'x'; - cbuf[cbuf_len++] = '0'; - } - break; - -#if NANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS == 1 - case NPF_FMT_SPEC_CONV_WRITEBACK: /* 'n' */ - switch (fs.length_modifier) - { - NPF_WRITEBACK(NONE, int); - NPF_WRITEBACK(SHORT, short); - NPF_WRITEBACK(LONG, long); - NPF_WRITEBACK(LONG_DOUBLE, double); - NPF_WRITEBACK(CHAR, signed char); -#if NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS == 1 - NPF_WRITEBACK(LARGE_LONG_LONG, long long); - NPF_WRITEBACK(LARGE_INTMAX, intmax_t); - NPF_WRITEBACK(LARGE_SIZET, size_t); - NPF_WRITEBACK(LARGE_PTRDIFFT, ptrdiff_t); -#endif - default: - break; - } - break; +#if FEATURE(USE_SPECIAL) + if (convert == '#') + { + flags |= FL_SPECIAL; + } + else #endif - -#if NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS == 1 - case NPF_FMT_SPEC_CONV_FLOAT_DECIMAL: - { /* 'f', 'F' */ - double val; - if (fs.length_modifier == NPF_FMT_SPEC_LEN_MOD_LONG_DOUBLE) - { - val = (double)va_arg(vlist, long double); - } - else - { - val = (double)va_arg(vlist, double); - } - sign = (val < 0) ? -1 : 1; - cbuf_len = npf__dtoa_rev(cbuf, val, 10, fs.conv_spec_case, &frac_chars); - if (cbuf_len < 0) - { - cbuf_len = -cbuf_len; - inf_or_nan = 1; - } - else - { - /* round lowest frac digits for precision */ - if (frac_chars > fs.precision) - { - int isPropagating = 0; - - for (i = 0; i < cbuf_len; i++) - { - int inLosingPart = (i <= (frac_chars - fs.precision - 1)); - - if (cbuf[i] >= '0' && cbuf[i] <= '9') - { - if (isPropagating) - { - cbuf[i] += 1; - if (cbuf[i] > '9') - { - cbuf[i] = '0'; - } - else - { - isPropagating = 0; - } - } - - if (inLosingPart && cbuf[i] > '5') - { - isPropagating = 1; - cbuf[i] = '0'; - } - } - - if (!isPropagating && !inLosingPart) - { - break; - } - } - - if (isPropagating) - { - cbuf[cbuf_len] = '1'; - cbuf_len++; - cbuf[cbuf_len] = 0; - } - - cbuf += (frac_chars - fs.precision); - cbuf_len -= (frac_chars - fs.precision); - frac_chars = fs.precision; - } - } - } break; + } +#if FEATURE(USE_SPACE_PAD) || FEATURE(USE_ZERO_PAD) + // Extract width + #if FEATURE(USE_INDIRECT) + if (convert == '*') + { + width = va_arg(ap, int); + convert = GET_FORMAT(++fmt); + } + else + #endif + // cppcheck-suppress knownConditionTrueFalse // False positive + while (convert >= '0' && convert <= '9') + { + width = width * 10 + convert - '0'; + convert = GET_FORMAT(++fmt); + } #endif - default: - break; +#if FEATURE(USE_PRECISION) + // Extract precision + if (convert == '.') + { + precision = 0; + convert = GET_FORMAT(++fmt); + #if FEATURE(USE_INDIRECT) + if (convert == '*') + { + precision = va_arg(ap, int); + convert = GET_FORMAT(++fmt); } - - /* Compute the leading symbol (+, -, ' ') */ - sign_c = 0; - if (sign == -1) + else + #endif + while (convert >= '0' && convert <= '9') { - sign_c = '-'; + precision = precision * 10 + convert - '0'; + convert = GET_FORMAT(++fmt); } - else if (sign == 1) + } +#endif +#if FEATURE(USE_LONG) + // Extract length modifier + if (convert == 'l') + { + convert = GET_FORMAT(++fmt); + #if FEATURE(USE_LONG_LONG) + if (convert == 'l') { - if (fs.prepend_sign) - { - sign_c = '+'; - } - else if (fs.prepend_space) - { - sign_c = ' '; - } + fflags |= FF_XLONG; + convert = GET_FORMAT(++fmt); } - -#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 - /* Compute the field width pad character */ - pad_c = 0; - if (fs.field_width_type == NPF_FMT_SPEC_FIELD_WIDTH_LITERAL) + else + #endif + flags |= FL_LONG; + } +#endif + switch (convert) + { +#if FEATURE(USE_CHAR) + case 'c': + #if FEATURE(USE_SPACE_PAD) + width = 0; + #endif + *--p = (char) va_arg(ap, int); + break; +#endif +#if FEATURE(USE_SIGNED) + case 'd': +#endif +#if FEATURE(USE_SIGNED_I) + case 'i': +#endif +#if FEATURE(USE_SIGNED) || FEATURE(USE_SIGNED_I) + flags |= FL_NEG; // Flag possible negative value, to be determined later + base = 10; + goto number; +#endif +#if FEATURE(USE_UNSIGNED) + case 'u': + base = 10; + goto number; +#endif +#if FEATURE(USE_OCTAL) + case 'o': + base = 8; + goto number; +#endif +#if FEATURE(USE_BINARY) + case 'b': + base = 2; + goto number; +#endif +#if FEATURE(USE_HEX_LOWER) + case 'x': +#endif +#if FEATURE(USE_HEX_UPPER) + case 'X': +#endif +#if FEATURE(USE_HEX_LOWER) || FEATURE(USE_HEX_UPPER) + #if !HEX_CONVERT_ONLY + base = 16; + #endif +#endif +#if !HEX_CONVERT_ONLY + number: +#endif + /* Using separate va_arg() calls for signed and unsigned types is expensive. + Instead, values are read as unsigned, regardless of signed/unsigned type. + Signed values then need to be sign-extended + and this is fixed after the check for negative numbers. + */ +#if FEATURE(USE_LONG) + #if FEATURE(USE_LONG_LONG) + if (fflags & FF_XLONG) + uvalue = va_arg(ap, unsigned long long); + else + #endif + if (flags & FL_LONG) + uvalue = va_arg(ap, unsigned long); + else +#endif + uvalue = va_arg(ap, unsigned int); +#if FEATURE(USE_SIGNED) || FEATURE(USE_SIGNED_I) + // FL_NEG was used temporarily to indicate signed type + if (flags & FL_NEG) { - if (fs.leading_zero_pad) + // Values may need to be sign extended if not the widest type. + #if FEATURE(USE_LONG) + #if FEATURE(USE_LONG_LONG) + if (!(fflags & FF_XLONG)) + { + if (!(flags & FL_LONG)) + uvalue = (int) uvalue; + else + uvalue = (long) uvalue; + } + #else + if (!(flags & FL_LONG)) + uvalue = (int) uvalue; + #endif + #endif + // Check whether this is a negative value + #if FEATURE(USE_LONG) + #if FEATURE(USE_LONG_LONG) + if ((long long) uvalue < 0) + #else + if ((long) uvalue < 0) + #endif + #else + if ((int) uvalue < 0) + #endif { - /* '0' flag is only legal with numeric types */ - if ((fs.conv_spec != NPF_FMT_SPEC_CONV_STRING) && (fs.conv_spec != NPF_FMT_SPEC_CONV_CHAR) && - (fs.conv_spec != NPF_FMT_SPEC_CONV_PERCENT)) - { - pad_c = '0'; - } + uvalue = -uvalue; // Yes, it's negative } else { - pad_c = ' '; + flags &= ~FL_NEG; // No, it's positive } } #endif - /* Compute the number of bytes to truncate or '0'-pad. */ - if (fs.conv_spec != NPF_FMT_SPEC_CONV_STRING) - { -#if NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS == 1 - if (!inf_or_nan) - { - /* float precision is after the decimal point */ - int const precision_start = - (fs.conv_spec == NPF_FMT_SPEC_CONV_FLOAT_DECIMAL) ? frac_chars : fs.precision; - // If not a float or decimal then the prec_pad has to end up as zero so we don't attempt any - // padding - prec_pad = NPF_MAX(0, fs.precision - precision_start); - } -#elif NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 - prec_pad = NPF_MAX(0, fs.precision - cbuf_len); +#if FEATURE(USE_PRECISION) + // Set default precision + if (precision == -1) precision = 1; #endif - } - -#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 - /* Given the full converted length, how many pad bytes? */ - field_pad = fs.field_width - cbuf_len - !!sign_c; -#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 - field_pad -= prec_pad; + // Make sure options are valid. +#if HEX_CONVERT_ONLY + #if FEATURE(USE_PLUS_SIGN) || FEATURE(USE_SPACE_SIGN) + flags &= ~(FL_PLUS|FL_SPACE); + #endif +#else + if (base != 10) flags &= ~(FL_PLUS|FL_NEG|FL_SPACE); + #if FEATURE(USE_SPECIAL) + else flags &= ~FL_SPECIAL; + #endif #endif - field_pad = NPF_MAX(0, field_pad); + // Generate the number without any prefix yet. +#if FEATURE(USE_ZERO_PAD) + fwidth = width; + // Avoid formatting buffer overflow. + if (fwidth > BUFMAX) fwidth = BUFMAX; #endif - -#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 - /* Apply right-justified field width if requested */ - if (!fs.left_justified && pad_c) +#if FEATURE(USE_LONG_LONG) && FEATURE(USE_BINARY) + // 64-bit binary output is impractical for reading and requires a huge buffer. + // Restrict to 32 bits in binary mode. + if ((base == 2) && (fflags & FF_XLONG)) { - /* If leading zeros pad, sign goes first. */ - if ((sign_c == '-' || sign_c == '+') && pad_c == '0') - { - NPF_PUTC(sign_c); - sign_c = 0; - } - while (field_pad-- > 0) - { - NPF_PUTC(pad_c); - } + uvalue = (unsigned long) uvalue; } #endif - /* Write the converted payload */ - if (fs.conv_spec == NPF_FMT_SPEC_CONV_STRING) +#if FEATURE(USE_PRECISION) + while (uvalue || precision > 0) +#else + if (uvalue == 0) { - /* Strings are not reversed, put directly */ - for (i = 0; i < cbuf_len; ++i) - { - NPF_PUTC(cbuf[i]); - } + // Avoid printing 0 as ' ' + *--p = '0'; + #if FEATURE(USE_ZERO_PAD) + --fwidth; + #endif } - else + while (uvalue) +#endif { - if (sign_c) +#if HEX_CONVERT_ONLY + c = (char) ((uvalue & 0x0f) + '0'); +#else + c = (char) ((uvalue % base) + '0'); +#endif +#if FEATURE(USE_HEX_LOWER) || FEATURE(USE_HEX_UPPER) + if (c > '9') { - NPF_PUTC(sign_c); + // Hex digits + #if FEATURE(USE_HEX_LOWER) && FEATURE(USE_HEX_UPPER) + if (convert == 'X') c += 'A' - '0' - 10; + else c += 'a' - '0' - 10; + #elif FEATURE(USE_HEX_UPPER) || FEATURE(USE_HEX_UPPER_L) + c += 'A' - '0' - 10; + #else + c += 'a' - '0' - 10; + #endif } -#if NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS == 1 - if (fs.conv_spec != NPF_FMT_SPEC_CONV_FLOAT_DECIMAL) - { #endif - -#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 - /* integral precision comes before the number. */ - while (prec_pad-- > 0) - { - NPF_PUTC('0'); - } + *--p = c; +#if HEX_CONVERT_ONLY + uvalue >>= 4; +#else + uvalue /= base; #endif - -#if NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS == 1 - } - else - { - /* if 0 precision, skip the fractional part and '.' - if 0 prec + alternative form, keep the '.' */ - if (fs.precision == 0) - { - cbuf += frac_chars + !fs.alternative_form; - cbuf_len -= frac_chars + !fs.alternative_form; - } - } +#if FEATURE(USE_ZERO_PAD) + --fwidth; #endif - /* *toa_rev leaves payloads reversed */ - while (cbuf_len-- > 0) - { - NPF_PUTC(cbuf[cbuf_len]); - } - -#if NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS == 1 - /* real precision comes after the number. */ - if ((fs.conv_spec == NPF_FMT_SPEC_CONV_FLOAT_DECIMAL) && !inf_or_nan) - { - while (prec_pad-- > 0) - { - NPF_PUTC('0'); - } - } +#if FEATURE(USE_PRECISION) + --precision; #endif } - -#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 - /* Apply left-justified field width if requested */ - if (fs.left_justified && pad_c) +#if FEATURE(USE_ZERO_PAD) + // Allocate space for the sign bit. + if (flags & (FL_PLUS|FL_NEG|FL_SPACE)) --fwidth; + #if FEATURE(USE_SPECIAL) + // Allocate space for special chars if required. + if (flags & FL_SPECIAL) + { + if (convert == 'o') fwidth -= 1; + else fwidth -= 2; + } + #endif + // Add leading zero padding if required. + if ((flags & FL_ZERO_PAD) && !(flags & FL_LEFT_JUST)) { - while (field_pad-- > 0) + while (fwidth > 0) { - NPF_PUTC(pad_c); + *--p = '0'; + --fwidth; } } #endif +#if FEATURE(USE_SPECIAL) + // Add special prefix if required. + if (flags & FL_SPECIAL) + { + if (convert != 'o') *--p = convert; + *--p = '0'; + } +#endif + // Add the sign prefix + if (flags & FL_NEG) *--p = '-'; +#if FEATURE(USE_PLUS_SIGN) + else if (flags & FL_PLUS) *--p = '+'; +#endif +#if FEATURE(USE_SPACE_SIGN) + else if (flags & FL_SPACE) *--p = ' '; +#endif +#if FEATURE(USE_PRECISION) + // Precision is not used to limit number output. + precision = -1; +#endif + break; +#if FEATURE(USE_FLOAT) + case 'f': + fflags = FF_FCVT; + goto fp_number; + case 'E': + fflags = FF_UCASE; + case 'e': + fflags |= FF_ECVT; + goto fp_number; + case 'G': + fflags = FF_UCASE; + case 'g': + fflags |= FF_GCVT; + fp_number: + // Set default precision + if (precision == -1) precision = 6; + // Need one extra digit precision in E mode + if (fflags & FF_ECVT) ++precision; + fvalue = va_arg(ap, double); + p = format_float(fvalue, precision, width, flags, fflags, buffer); + // Precision is not used to limit number output. + precision = -1; + break; +#endif +#if FEATURE(USE_STRING) + #if FEATURE(USE_FSTRING) + case 'S': + flags |= FL_FSTR; + // fall through + #endif + case 's': + p = va_arg(ap, char *); + break; +#endif + default: + *--p = convert; + break; + } + +#if FEATURE(USE_SPACE_PAD) + // Check width of formatted text. + #if FEATURE(USE_FSTRING) + fwidth = p_len(p, flags); + #else + fwidth = p_len(p); + #endif + // Copy formatted text with leading or trailing space. + // A positive value for precision will limit the length of p used. + for (;;) + { + #if FEATURE(USE_FSTRING) + if (flags & FL_FSTR) + c = GET_FORMAT(p); + else + #endif + c = *p; + if ((c == '\0' || precision == 0) && width <= 0) break; + if (((flags & FL_LEFT_JUST) || width <= fwidth) && c && precision != 0) ++p; + else c = ' '; + // for loop continues after #endif +#else + for (;;) + { + #if FEATURE(USE_FSTRING) + if (flags & FL_FSTR) + c = GET_FORMAT(p); + else + #endif + c = *p; + #if FEATURE(USE_PRECISION) + // A positive value for precision will limit the length of p used. + if (c == '\0' || precision == 0) break; + #else + if (c == '\0') break; + #endif + ++p; + // for loop continues after #endif +#endif + // for loop continues here from either of the USE_SPACE_PAD cases. +#ifdef BASIC_PRINTF_ONLY + func(c); // Basic output function. +#else + func(c, context); // Output function. +#endif +#ifdef PRINTF_T + ++count; + +// [NF_CHANGE] + if (count >= n) + { + break; + } +// [END NF_CHANGE] - cur += fs_len; +#endif +#if FEATURE(USE_SPACE_PAD) + --width; +#endif +#if FEATURE(USE_PRECISION) + if (precision > 0) --precision; +#endif } } + else + { +#ifdef BASIC_PRINTF_ONLY + func(convert); // Basic output function. +#else + func(convert, context); // Output function. +#endif +#ifdef PRINTF_T + ++count; +#endif + } + ++fmt; } - NPF_PUTC('\0'); - return n - 1; + +#ifdef PRINTF_T + return count; +#endif +} + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + +/* --------------------------------------------------------------------------- +Function: putout() +This is the output function used for printf. +The context is normally required, but is not used at present. It could be +extended to include streams or to avoid output mixing in multi-threaded use. +If using BASIC_PRINTF, context is not supported. +--------------------------------------------------------------------------- */ +#ifdef BASIC_PRINTF_ONLY +static void putout(char c) +{ +#else +static void putout(char c, void *context) +{ + (void) context; // Suppress compiler warning about unused argument. +#endif + PUTCHAR_FUNC(c); } -#undef NPF_PUTC -#undef NPF_EXTRACT -#undef NPF_WRITEBACK +/* --------------------------------------------------------------------------- +Function: printf() +Replacement for library printf - writes to output (normally serial) +It uses the output function putout() to update the serial output. +If PRINTF_T is defined then the number of characters generated is returned. +--------------------------------------------------------------------------- */ +printf_t printf_(const char *fmt, ...) +{ + va_list ap; +#ifdef PRINTF_T + int Count; +#endif + + va_start(ap, fmt); +#ifdef PRINTF_T + #ifdef BASIC_PRINTF_ONLY + Count = doprnt(putout, fmt, ap); + #else + Count = doprnt((void *)0, putout, BUFMAX, fmt, ap); + #endif +#else + #ifdef BASIC_PRINTF_ONLY + doprnt(putout, fmt, ap); + #else + doprnt((void *)0, putout, fmt, ap); + #endif +#endif + va_end(ap); + +#ifdef PRINTF_T + return Count; +#endif +} -int npf_pprintf(npf_putc pc, void *pc_ctx, char const *format, ...) +#ifndef BASIC_PRINTF_ONLY +/* --------------------------------------------------------------------------- +Function: putbuf() +This is the output function used for sprintf. +Here the context is a pointer to a pointer to the buffer. +Double indirection allows the function to increment the buffer pointer. +--------------------------------------------------------------------------- */ +static void putbuf(char c, void *context) { - va_list val; - int rv; - va_start(val, format); - rv = npf_vpprintf(pc, pc_ctx, format, val); - va_end(val); - return rv; + char *buf = *((char **) context); + *buf++ = c; + *((char **) context) = buf; } -int npf_snprintf(char *buffer, size_t bufsz, const char *format, ...) +/* --------------------------------------------------------------------------- +Function: sprintf() +Replacement for library sprintf - writes into buffer supplied. +Normally it uses the output function putout() to update the buffer. +sprintf is not supported when using BASIC_PRINTF +If PRINTF_T is defined then the number of characters generated is returned. +--------------------------------------------------------------------------- */ +printf_t sprintf_(char *buf, const char *fmt, ... ) { - va_list val; - int rv; - va_start(val, format); - rv = npf_vsnprintf(buffer, bufsz, format, val); - va_end(val); - return rv; + va_list ap; +#ifdef PRINTF_T + int Count; +#endif + + va_start(ap, fmt); +#ifdef PRINTF_T + Count = doprnt(&buf, putbuf, BUFMAX, fmt, ap); +#else + doprnt(&buf, putbuf, fmt, ap); +#endif + va_end(ap); + // Append null terminator. + *buf = '\0'; + +#ifdef PRINTF_T + return Count; +#endif +} +#endif + +// [NF_CHANGE] +printf_t snprintf_(char *buf, size_t n,const char *fmt, ... ) +{ + va_list ap; + int Count; + + va_start(ap, fmt); + Count = doprnt(&buf, putbuf, n, fmt, ap); + va_end(ap); + // Append null terminator. + *buf = '\0'; + + return Count; } +// [END_NF_CHANGE] -int npf_vsnprintf(char *buffer, size_t bufsz, char const *format, va_list vlist) +// [NF_CHANGE] +void putchar_(char character) { - npf__bufputc_ctx_t bufputc_ctx; - bufputc_ctx.dst = buffer; - bufputc_ctx.len = bufsz; - bufputc_ctx.cur = 0; - if (buffer && bufsz) - { - buffer[bufsz - 1] = 0; - } - return npf_vpprintf(buffer ? npf__bufputc : npf__bufputc_nop, &bufputc_ctx, format, vlist); + (void)character; } +// [END_NF_CHANGE] + +// clang-format on diff --git a/src/CLR/Helpers/nanoprintf/nanoprintf.h b/src/CLR/Helpers/nanoprintf/nanoprintf.h index d1f6b3d741..e4ba735966 100644 --- a/src/CLR/Helpers/nanoprintf/nanoprintf.h +++ b/src/CLR/Helpers/nanoprintf/nanoprintf.h @@ -1,36 +1,57 @@ // // Copyright (c) .NET Foundation and Contributors -// Portions Copyright (c) 2001, 2002 Georges Menie. All rights reserved. -// Portions Copyright (c) 2009-2013 Daniel D Miller. All rights reserved. +// Portions Copyright (c) 2006 - 2021 Skirrid Systems. All rights reserved. // See LICENSE file in the project root for full license information. // -/* - The interface of nanoprintf begins here, to be compiled only if - NANOPRINTF_IMPLEMENTATION is not defined. In a multi-file library what - follows would be the public-facing nanoprintf.h. -*/ - #ifndef NANOPRINTF_H #define NANOPRINTF_H #include -#include -/* Define this to fully sandbox nanoprintf inside of a translation unit. */ -#ifdef NANOPRINTF_VISIBILITY_STATIC -#define NPF_VISIBILITY static -#else -#define NPF_VISIBILITY extern -#endif +// clang-format off + +/************************************************************************* +Number of chars output + +Traditionally printf returns the number of chars output. If you are not +interested in that value you can leave PRINTF_T undefined. +On a small micro you can define the return type as unsigned char if you +are sure the total output width will never exceed 255, or unsigned short. +*************************************************************************/ + +#define PRINTF_T size_t + +/************************************************************************* +Memory access definitions + +Some micros such as the AVR can only support storing strings in flash +memory by wrapping the string in a macro. To make this transparent we can +define the printf function itself as a macro which performs the wrap and +calls a renamed version of printf with an _ suffix and no i. +*************************************************************************/ + +/* +Example for AVR micros using GCC toolchain from WinAVR or Atmel Studio + +#define sprintf(buf, format, args...) _sprntf(buf, PSTR(format), ## args) +#define printf(format, args...) _prntf(PSTR(format), ## args) + +extern printf_t _sprntf(char *, const char *, ...); +extern printf_t _prntf(const char *, ...); +*/ + +/************************************************************************* +End of customisations - Stop Editing! + +The remainder of this file contains the function declarations. +*************************************************************************/ -/* Compilers can warn when printf formatting strings are incorrect. */ -#if defined(__clang__) -#define NPF_PRINTF_ATTR(FORMAT_INDEX, VARGS_INDEX) __attribute__((__format__(__printf__, FORMAT_INDEX, VARGS_INDEX))) -#elif defined(__GNUC__) || defined(__GNUG__) -#define NPF_PRINTF_ATTR(FORMAT_INDEX, VARGS_INDEX) __attribute__((format(printf, FORMAT_INDEX, VARGS_INDEX))) +// Create a type definition for the return value +#ifndef PRINTF_T +typedef void printf_t; #else -#define NPF_PRINTF_ATTR(FORMAT_INDEX, VARGS_INDEX) +typedef PRINTF_T printf_t; #endif #ifdef __cplusplus @@ -38,208 +59,236 @@ extern "C" { #endif - /* Public API */ +// Function declarations, unless macros have been defined above +printf_t printf_(const char *, ...); +printf_t sprintf_(char *, const char *, ...); +printf_t snprintf_(char *, size_t n, const char *, ...); - NPF_VISIBILITY int npf_snprintf(char *buffer, size_t bufsz, const char *format, ...) NPF_PRINTF_ATTR(3, 4); +#ifdef __cplusplus +} +#endif - NPF_VISIBILITY int npf_vsnprintf(char *buffer, size_t bufsz, char const *format, va_list vlist) - NPF_PRINTF_ATTR(3, 0); + // from config - typedef void (*npf_putc)(int c, void *ctx); - NPF_VISIBILITY int npf_pprintf(npf_putc pc, void *pc_ctx, char const *format, ...) NPF_PRINTF_ATTR(3, 4); +/************************************************************************* +Basic printf only - NPF_VISIBILITY int npf_vpprintf(npf_putc pc, void *pc_ctx, char const *format, va_list vlist) NPF_PRINTF_ATTR(3, 0); +The code is designed to support a variety of printf-related functions. +If simple serial output is all you want then you can save some space by +defining BASIC_PRINTF_ONLY which allows the internal API to be simplified. +Note that sprintf will not be supported in this case. +*************************************************************************/ -/* Public Configuration */ +// #define BASIC_PRINTF_ONLY -/* Pick reasonable defaults if nothing's been configured. */ -#if !defined(NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS) && !defined(NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS) && \ - !defined(NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS) && !defined(NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS) && \ - !defined(NANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS) -#define NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS 1 -#define NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS 1 -#define NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS 1 -#define NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS 1 -#define NANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS 0 -#endif +/************************************************************************* +Memory access definitions -/* If anything's been configured, everything must be configured. */ -#ifndef NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS -#error NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS must be #defined to 0 or 1 -#endif +Some micros such as the AVR can only support storing and accessing strings +in flash memory using special macros and functions. This section can be +used to specify those methods. You may also need to modify printf.h +to get the compiler to place the format strings in flash memory. -#ifndef NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS -#error NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS must be #defined to 0 or 1 -#endif +The GET_FORMAT(ptr) macro is used to access a character in the printf +format string. By default this does a normal memory pointer access, but +you can configure it to access flash memory if needed. +*************************************************************************/ -#ifndef NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS -#error NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS must be #defined to 0 or 1 -#endif +/* +Example for AVR micros using GCC toolchain from WinAVR or Atmel Studio -#ifndef NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS -#error NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS must be #defined to 0 or 1 -#endif +#include +#include +#define GET_FORMAT(p) pgm_read_byte(p) +*/ -#ifndef NANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS -#error NANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS must be #defined to 0 or 1 -#endif +/************************************************************************* +Output configuration -/* Ensure flags are compatible. */ -#if (NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS == 1) && (NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 0) -#error Precision format specifiers must be enabled if float support is enabled. -#endif +By default printf will use the putchar function. If this is not defined +in your system you can set your own function here by defining +PUTCHAR_FUNC to be the name of that function. +*************************************************************************/ -/* intmax_t / uintmax_t require stdint from c99 / c++11 */ -#ifndef _MSC_VER -#ifdef __cplusplus -#if __cplusplus < 201103L -#error nanoprintf requires C++11 or later. -#endif -#else -#if __STDC_VERSION__ < 199409L -#error nanoprintf requires C99 or later. -#endif -#endif -#endif +void putchar_(char character); +#define PUTCHAR_FUNC putchar_ - /* Implementation Details (prototype / config helper functions) */ +/************************************************************************* +Compiler capability configuration -#include -#include +Set some options that the C pre-processor will not tell us about. +*************************************************************************/ -#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 - typedef enum - { - NPF_FMT_SPEC_FIELD_WIDTH_NONE, - NPF_FMT_SPEC_FIELD_WIDTH_STAR, - NPF_FMT_SPEC_FIELD_WIDTH_LITERAL - } npf__format_spec_field_width_t; -#endif +// Does the compiler support double precision or silently degrade to single? +//#define NO_DOUBLE_PRECISION -#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 - typedef enum - { - NPF_FMT_SPEC_PRECISION_NONE, - NPF_FMT_SPEC_PRECISION_STAR, - NPF_FMT_SPEC_PRECISION_LITERAL - } npf__format_spec_precision_t; -#endif +// Does the compiler support isnan and isinf floating point functions? +// #define NO_ISNAN_ISINF - typedef enum - { - NPF_FMT_SPEC_LEN_MOD_NONE, - NPF_FMT_SPEC_LEN_MOD_SHORT, /* 'h' */ - NPF_FMT_SPEC_LEN_MOD_LONG, /* 'l' */ - NPF_FMT_SPEC_LEN_MOD_LONG_DOUBLE, /* 'L' */ - NPF_FMT_SPEC_LEN_MOD_CHAR /* 'hh' */ -#if NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS == 1 - , - NPF_FMT_SPEC_LEN_MOD_LARGE_LONG_LONG, /* 'll' */ - NPF_FMT_SPEC_LEN_MOD_LARGE_INTMAX, /* 'j' */ - NPF_FMT_SPEC_LEN_MOD_LARGE_SIZET, /* 'z' */ - NPF_FMT_SPEC_LEN_MOD_LARGE_PTRDIFFT /* 't' */ -#endif - } npf__format_spec_length_modifier_t; - - typedef enum - { - NPF_FMT_SPEC_CONV_PERCENT, /* '%' */ - NPF_FMT_SPEC_CONV_CHAR, /* 'c' */ - NPF_FMT_SPEC_CONV_STRING, /* 's' */ - NPF_FMT_SPEC_CONV_SIGNED_INT, /* 'i', 'd' */ - NPF_FMT_SPEC_CONV_OCTAL, /* 'o' */ - NPF_FMT_SPEC_CONV_HEX_INT, /* 'x', 'X' */ - NPF_FMT_SPEC_CONV_UNSIGNED_INT, /* 'u' */ - NPF_FMT_SPEC_CONV_POINTER /* 'p' */ -#if NANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS == 1 - , - NPF_FMT_SPEC_CONV_WRITEBACK /* 'n' */ -#endif -#if NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS == 1 - , - NPF_FMT_SPEC_CONV_FLOAT_DECIMAL /* 'f', 'F' */ -#endif - } npf__format_spec_conversion_t; - - typedef enum - { - NPF_FMT_SPEC_CONV_CASE_LOWER, - NPF_FMT_SPEC_CONV_CASE_UPPER - } npf__format_spec_conversion_case_t; - - typedef struct - { - /* optional flags */ - char prepend_sign; /* '+' */ - char prepend_space; /* ' ' */ - char alternative_form; /* '#' */ - -#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 - /* field width */ - npf__format_spec_field_width_t field_width_type; - int field_width; - char left_justified; /* '-' */ - char leading_zero_pad; /* '0' */ -#endif +/************************************************************************* +Formatted item width -#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 - /* precision */ - npf__format_spec_precision_t precision_type; - int precision; -#endif +Since it is extremely unlikely that you will ever want to use a formatted +width for a single item of more than 127 chars (i.e. the expanded and +padded size of a single % expression), the width variables can normally +be restricted to 8 bits. On small micros this saves a lot of code and +variable space. On a 32-bit RISC it may increase code size due to type +conversions. Choose the variable type to suit your CPU. +Note that a signed type is required. +*************************************************************************/ - /* length modifier for specifying argument size */ - npf__format_spec_length_modifier_t length_modifier; +typedef signed char width_t; - /* conversion specifiers */ - npf__format_spec_conversion_t conv_spec; - npf__format_spec_conversion_case_t conv_spec_case; - } npf__format_spec_t; +/************************************************************************* +Feature configuration -#if NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS == 0 - typedef long npf__int_t; - typedef unsigned long npf__uint_t; -#else -typedef intmax_t npf__int_t; -typedef uintmax_t npf__uint_t; -#endif +This section defines the individual feature flags. +These are combined as needed to produce the FEATURE_FLAGS macro. +*************************************************************************/ - NPF_VISIBILITY int npf__parse_format_spec(char const *format, npf__format_spec_t *out_spec); - - typedef struct - { - char *dst; - size_t len; - size_t cur; - } npf__bufputc_ctx_t; - - NPF_VISIBILITY void npf__bufputc(int c, void *ctx); - NPF_VISIBILITY void npf__bufputc_nop(int c, void *ctx); - NPF_VISIBILITY int npf__itoa_rev(char *buf, npf__int_t i); - NPF_VISIBILITY int npf__utoa_rev(char *buf, npf__uint_t i, unsigned base, npf__format_spec_conversion_case_t cc); -#if NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS == 1 - NPF_VISIBILITY int npf__dsplit_abs( - double d, - uint64_t *out_int_part, - uint64_t *out_frac_part, - int *out_frac_base10_neg_e); - NPF_VISIBILITY int npf__dtoa_rev( - char *buf, - double d, - unsigned base, - npf__format_spec_conversion_case_t cc, - int *out_frac_chars); -#endif +// Include floating point number support +#define USE_FLOAT (1 << 0) -#ifdef __cplusplus -} -#endif +// Include support for long integers +#define USE_LONG (1 << 1) + +// Include support for octal formatting +#define USE_OCTAL (1 << 2) + +// Include support for %d decimal formatting +#define USE_SIGNED (1 << 3) + +// Include support for the %i synonym for %d +#define USE_SIGNED_I (1 << 4) + +// Include support for the %u unsigned decimal specifier +#define USE_UNSIGNED (1 << 5) + +// Include support for the %x hex specifier (lowercase output) +#define USE_HEX_LOWER (1 << 6) + +// Include support for the %X hex specifier (uppercase output) +#define USE_HEX_UPPER (1 << 7) + +// Force uppercase output with %x. +// Used in conjunction with USE_HEX_LOWER. +// Ignored if USE_HEX_UPPER is also set. +#define USE_HEX_UPPER_L (1 << 8) + +// Include support for %c single character +#define USE_CHAR (1 << 9) + +// Include support for %s string +#define USE_STRING (1 << 10) + +// Include support for %S string in flash memory +// Only needed for architectures which cannot access program memory using normal pointers. +// If you have not defined the GET_FORMAT() macro above then you don't need this option. +#define USE_FSTRING (1 << 11) + +// Include support for %b binary specifier +#define USE_BINARY (1 << 12) + +// Include precision support when floating point is not present. +// Precision is automatically enabled when floating point support is used. +#define USE_PRECISION (1UL << 16) + +// Allow use of leading zero padding e.g. "%03d" +#define USE_ZERO_PAD (1UL << 17) + +// Allow use of space padding e.g. "%3d" or "%12s" +#define USE_SPACE_PAD (1UL << 18) + +// Include indirect width/precision support e.g. "%*d" +#define USE_INDIRECT (1UL << 19) + +// Allow forcing a leading plus sign e.g. "%+3d" +#define USE_PLUS_SIGN (1UL << 20) + +// Allow forcing a leading space (instead of + or -) in front of zero e.g. "% 3d" +#define USE_SPACE_SIGN (1UL << 21) + +// Include support for the left-justify '-' flag. +#define USE_LEFT_JUST (1UL << 22) -// do not define sprintf, it is not safe -//#define sprintf snprintf(buff, ARRAYSIZE(buff), fmt, ##__VA_ARGS__) +// Include support for the special '#' flag. +#define USE_SPECIAL (1UL << 23) -// the defines below allow using the regular calls to *snprintf -#define snprintf npf_snprintf -#define vsnprintf npf_vsnprintf +// Use smaller but less efficient floating point normalisation. +// This is not recommended unless code space is critically low. +#define USE_SMALL_FLOAT (1UL << 24) + +// Include support for 64-bit integers e.g. "%lld" +#define USE_LONG_LONG (1UL << 25) + +/************************************************************************* +Pre-defined feature sets + +This section provides some commonly used combinations of features. +*************************************************************************/ + +// Lowercase hex integers only. This really is the bare minimum. +#define HEX_INT (USE_HEX_LOWER) + +// Decimal and lowercase hex only. +#define MINIMAL_INT (USE_SIGNED | USE_HEX_LOWER) + +// Signed and unsigned decimal, lower case hex, zero & space padding, plus char and string +#define BASIC_INT (USE_CHAR | USE_STRING | USE_SIGNED | USE_UNSIGNED | USE_HEX_LOWER | USE_ZERO_PAD | USE_SPACE_PAD) + +// All short integer features except octal, binary, %i, indirection and specials. +#define SHORT_INT \ + (USE_CHAR | USE_STRING | USE_SIGNED | USE_UNSIGNED | USE_HEX_LOWER | USE_HEX_UPPER | USE_PRECISION | \ + USE_ZERO_PAD | USE_SPACE_PAD | USE_PLUS_SIGN | USE_SPACE_SIGN | USE_LEFT_JUST) + +// As above, but also supports long integers. +#define LONG_INT (USE_LONG | SHORT_INT) + +// As above, but also supports long-long integers. +#define LONG_LONG_INT (USE_LONG_LONG | LONG_INT) + +// All possible integer features. +#define FULL_INT (USE_BINARY | USE_OCTAL | USE_SIGNED_I | USE_INDIRECT | USE_SPECIAL | LONG_LONG_INT) + +// All available features including floating point. +#define FULL_FLOAT (USE_FLOAT | FULL_INT) + +/************************************************************************* +Features included in your build of printf. Use only the features you need +to keep code size and execution time to a minimum. + +You can use the custom set, with anything you don't want commented out, +or you can use one of the pre-defined sets. + +Examples: + +#define FEATURE_FLAGS CUSTOM_SET +#define FEATURE_FLAGS SHORT_INT + +Features and pre-defined sets are set out in the following sections. +*************************************************************************/ + +// Custom feature set. Comment out features you don't want. +#define CUSTOM_SET \ + (0 | USE_FLOAT | USE_LONG | USE_BINARY | USE_OCTAL | USE_SIGNED | USE_SIGNED_I | USE_UNSIGNED | USE_HEX_LOWER | \ + USE_HEX_UPPER | USE_HEX_UPPER_L | USE_CHAR | USE_STRING | USE_FSTRING | USE_PRECISION | USE_ZERO_PAD | \ + USE_SPACE_PAD | USE_INDIRECT | USE_PLUS_SIGN | USE_SPACE_SIGN | USE_LEFT_JUST | USE_SPECIAL | USE_SMALL_FLOAT | \ + USE_LONG_LONG) + +#define FEATURE_FLAGS \ + (0 | USE_FLOAT | USE_LONG | USE_SIGNED | USE_UNSIGNED | USE_HEX_LOWER | \ + USE_HEX_UPPER | USE_HEX_UPPER_L | USE_CHAR | USE_STRING | USE_PRECISION | USE_ZERO_PAD | \ + USE_SPACE_PAD | USE_INDIRECT | USE_PLUS_SIGN | \ + USE_LONG_LONG) + +/************************************************************************* +End of customisations - Stop Editing! +*************************************************************************/ + +#define printf printf_ +#define sprintf sprintf_ +#define snprintf snprintf_ #endif // NANOPRINTF_H + +// clang-format on diff --git a/src/CLR/Include/nanoCLR_Application.h b/src/CLR/Include/nanoCLR_Application.h index 0f29db0566..44a68ae689 100644 --- a/src/CLR/Include/nanoCLR_Application.h +++ b/src/CLR/Include/nanoCLR_Application.h @@ -24,7 +24,14 @@ typedef struct CLR_SETTINGS // when building is set for RTM this configuration is ignored bool EnterDebuggerLoopAfterExit; + // Set this to TRUE if the device is to reboot to nanoBoother (or proprietary bootloader) in case the there is a + // fault in loading the application. + // This option is only available when building is set for RTM + bool RevertToBooterOnFault; + #if defined(VIRTUAL_DEVICE) + bool PerformGarbageCollection; + bool PerformHeapCompaction; CLR_RT_StringVector StartArgs; #endif diff --git a/src/CLR/Include/nanoCLR_Debugging.h b/src/CLR/Include/nanoCLR_Debugging.h index bc1b4ec08a..501cca1f76 100644 --- a/src/CLR/Include/nanoCLR_Debugging.h +++ b/src/CLR/Include/nanoCLR_Debugging.h @@ -550,7 +550,9 @@ struct CLR_DBG_Commands struct Debugging_Value { - CLR_RT_HeapBlock * m_referenceID; + // this is a CLR_RT_HeapBlock * + // has to be stored as CLR_UINT32 because CLR_RT_HeapBlock has different size on 32 and 64 bit platforms + CLR_UINT32 m_referenceID; CLR_UINT32 m_dt; // CLR_RT_HeapBlock::DataType () CLR_UINT32 m_flags; // CLR_RT_HeapBlock::DataFlags() CLR_UINT32 m_size; // CLR_RT_HeapBlock::DataSize () @@ -564,7 +566,9 @@ struct CLR_DBG_Commands // For DATATYPE_STRING // CLR_UINT32 m_bytesInString; - const char * m_charsInString; + // this is a const char * + // has to be stored as CLR_UINT32 because const char * has different size on 32 and 64 bit platforms + CLR_UINT32 m_charsInString; // // For DATATYPE_VALUETYPE or DATATYPE_CLASSTYPE @@ -581,7 +585,10 @@ struct CLR_DBG_Commands // // For values from an array. // - CLR_RT_HeapBlock_Array *m_arrayref_referenceID; + + // this is a CLR_RT_HeapBlock_Array * + // has to be stored as CLR_UINT32 because CLR_RT_HeapBlock_Array has different size on 32 and 64 bit platforms + CLR_UINT32 m_arrayref_referenceID; CLR_UINT32 m_arrayref_index; }; diff --git a/src/CLR/Include/nanoCLR_Hardware.h b/src/CLR/Include/nanoCLR_Hardware.h index c9b15d89a8..596c8b3736 100644 --- a/src/CLR/Include/nanoCLR_Hardware.h +++ b/src/CLR/Include/nanoCLR_Hardware.h @@ -22,10 +22,11 @@ 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_SYSTEM_TIMER | SYSTEM_EVENT_FLAG_SPI_MASTER | SYSTEM_EVENT_FLAG_I2C_MASTER | - 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_SYSTEM_TIMER | SYSTEM_EVENT_FLAG_USB_IN | SYSTEM_EVENT_FLAG_USB_OUT | + SYSTEM_EVENT_FLAG_SPI_MASTER | SYSTEM_EVENT_FLAG_I2C_MASTER | 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/src/CLR/Include/nanoCLR_PlatformDef.h b/src/CLR/Include/nanoCLR_PlatformDef.h index 3304e233e3..443f9bb5f3 100644 --- a/src/CLR/Include/nanoCLR_PlatformDef.h +++ b/src/CLR/Include/nanoCLR_PlatformDef.h @@ -34,8 +34,10 @@ #if defined(DEBUG) || defined(_DEBUG) #define NANOCLR_TRACE_STACK // enables rich eval stack tracing #endif -//#define TINYCLR_TRACE_INSTRUCTIONS 1 // enables tracing of instructions execution -//#define NANOCLR_TRACE_HRESULT // enable tracing of HRESULTS from interop libraries +// #define TINYCLR_TRACE_INSTRUCTIONS 1 // enables tracing of instructions execution +// #define NANOCLR_TRACE_HRESULT // enable tracing of HRESULTS from interop libraries +// #define NANOCLR_TRACE_PROFILER_MESSAGES // enable tracing of profiler messages +// #define NANOCLR_FORCE_PROFILER_EXECUTION // force Profiler execution //-o-//-o-//-o-//-o-//-o-//-o-// // PLATFORMS @@ -71,11 +73,11 @@ #define NANOCLR_PROFILE_NEW_ALLOCATIONS #if defined(DEBUG) || defined(_DEBUG) #define NANOCLR_VALIDATE_HEAP NANOCLR_VALIDATE_HEAP_2_DblLinkedList -//#define NANOCLR_TRACE_MALLOC +// #define NANOCLR_TRACE_MALLOC #define NANOCLR_FILL_MEMORY_WITH_DIRTY_PATTERN #define NANOCLR_TRACE_EARLYCOLLECTION #define NANOCLR_DELEGATE_PRESERVE_STACK -//#define NANOCLR_VALIDATE_APPDOMAIN_ISOLATION +// #define NANOCLR_VALIDATE_APPDOMAIN_ISOLATION #define NANOCLR_TRACE_HRESULT // enable tracing of HRESULTS from interop libraries #else // RELEASE #define NANOCLR_VALIDATE_HEAP NANOCLR_VALIDATE_HEAP_0_None @@ -137,6 +139,10 @@ #define NANOCLR_PROFILE_NEW #endif +#if defined(NANOCLR_FORCE_PROFILER_EXECUTION) && !defined(NANOCLR_PROFILE_NEW) +#undef NANOCLR_FORCE_PROFILER_EXECUTION +#endif + //-o-//-o-//-o-//-o-//-o-//-o-// // CODE //-o-//-o-//-o-//-o-//-o-//-o-// @@ -201,8 +207,6 @@ // INCLUDES #if defined(_WIN32) -#define _WIN32_WINNT 0x0501 - // Unsafe string functions be avoided, but there isn't a safe crt for the arm, so // a bunch of macros, cleanup code needs to be done first diff --git a/src/CLR/Include/nanoCLR_Profiling.h b/src/CLR/Include/nanoCLR_Profiling.h index dd248a2d92..df797be8ea 100644 --- a/src/CLR/Include/nanoCLR_Profiling.h +++ b/src/CLR/Include/nanoCLR_Profiling.h @@ -53,9 +53,9 @@ memory-layout-heap-length = int Contains heap layout information useful for showing memory usage statistics. heapdump = heapdump-start-packet *heapdump-root-packet *heapdump-object-packet heapdump-stop-packet - Heapdumps always occur in this form. All roots are listed before all objects, and both roots and objects fall between - a pair of 'start' and 'stop' packets. Heap dumps may be split up across stream-payload boundaries, but they may not be - nested, and packets may not be sent in any other order. + Heapdumps always occur in this form. All roots are listed before all objects, and both roots and objects fall +between a pair of 'start' and 'stop' packets. Heap dumps may be split up across stream-payload boundaries, but they may +not be nested, and packets may not be sent in any other order. heapdump-start-header = "00000011" heapdump-start-packet = heapdump-start-header @@ -94,7 +94,8 @@ heapdump-object-array-levels = short heapdump-object-special-cases = heapdump-object-classvaluetype-header / heapdump-object-array-header heapdump-object-other = datatype - datatype must not be one of ; If it is, the appropriate special case should be used instead. + datatype must not be one of ; If it is, the appropriate special case should be used +instead. heapdump-object-references = *heapdump-object-reference heapdump-object-end-of-references heapdump-object-reference = "1" pointer @@ -106,54 +107,55 @@ heapdump-stop-packet = heapdump-stop-header heapdump-stop-blocks-used heapdump-stop-header = "00000110" heapdump-stop-blocks-used = int - Reports how many heap-blocks were used by objects, including objects that might have been filtered out from reporting. + Reports how many heap-blocks were used by objects, including objects that might have been filtered out from +reporting. */ class CLR_PRF_CMDS { - public: - static const CLR_UINT32 c_Profiling_Timestamp = 0x01; - static const CLR_UINT32 c_Profiling_Memory_Layout = 0x02; + public: + static const CLR_UINT32 c_Profiling_Timestamp = 0x01; + static const CLR_UINT32 c_Profiling_Memory_Layout = 0x02; - static const CLR_UINT32 c_Profiling_HeapDump_Start = 0x03; - static const CLR_UINT32 c_Profiling_HeapDump_Root = 0x04; - static const CLR_UINT32 c_Profiling_HeapDump_Object = 0x05; - static const CLR_UINT32 c_Profiling_HeapDump_Stop = 0x06; + static const CLR_UINT32 c_Profiling_HeapDump_Start = 0x03; + static const CLR_UINT32 c_Profiling_HeapDump_Root = 0x04; + static const CLR_UINT32 c_Profiling_HeapDump_Object = 0x05; + static const CLR_UINT32 c_Profiling_HeapDump_Stop = 0x06; - static const CLR_UINT32 c_Profiling_Calls_Call = 0x07; - static const CLR_UINT32 c_Profiling_Calls_Return = 0x08; - static const CLR_UINT32 c_Profiling_Calls_CtxSwitch = 0x09; + static const CLR_UINT32 c_Profiling_Calls_Call = 0x07; + static const CLR_UINT32 c_Profiling_Calls_Return = 0x08; + static const CLR_UINT32 c_Profiling_Calls_CtxSwitch = 0x09; - static const CLR_UINT32 c_Profiling_Allocs_Alloc = 0x0a; - static const CLR_UINT32 c_Profiling_Allocs_Relloc = 0x0b; - static const CLR_UINT32 c_Profiling_Allocs_Delete = 0x0c; + static const CLR_UINT32 c_Profiling_Allocs_Alloc = 0x0a; + static const CLR_UINT32 c_Profiling_Allocs_Relloc = 0x0b; + static const CLR_UINT32 c_Profiling_Allocs_Delete = 0x0c; static const CLR_UINT32 c_Profiling_GarbageCollect_Begin = 0x0d; - static const CLR_UINT32 c_Profiling_GarbageCollect_End = 0x0e; + static const CLR_UINT32 c_Profiling_GarbageCollect_End = 0x0e; - static const CLR_UINT32 c_Profiling_HeapCompact_Begin = 0x0f; - static const CLR_UINT32 c_Profiling_HeapCompact_End = 0x10; + static const CLR_UINT32 c_Profiling_HeapCompact_Begin = 0x0f; + static const CLR_UINT32 c_Profiling_HeapCompact_End = 0x10; class Bits { - public: - static const CLR_UINT32 CommandHeader = 8; - static const CLR_UINT32 DataType = 8; - static const CLR_UINT32 NibbleCount = 3; - static const CLR_UINT32 RootTypes = 3; - static const CLR_UINT32 TimestampShift = 8; - static const CLR_UINT32 CallTimingShift = 4; + public: + static const CLR_UINT32 CommandHeader = 8; + static const CLR_UINT32 DataType = 8; + static const CLR_UINT32 NibbleCount = 3; + static const CLR_UINT32 RootTypes = 3; + static const CLR_UINT32 TimestampShift = 8; + static const CLR_UINT32 CallTimingShift = 4; }; class RootTypes { - public: + public: static const CLR_UINT32 Root_Finalizer = 0x01; static const CLR_UINT32 Root_AppDomain = 0x02; - static const CLR_UINT32 Root_Assembly = 0x03; - static const CLR_UINT32 Root_Thread = 0x04; - static const CLR_UINT32 Root_Stack = 0x05; + static const CLR_UINT32 Root_Assembly = 0x03; + static const CLR_UINT32 Root_Thread = 0x04; + static const CLR_UINT32 Root_Stack = 0x05; }; }; @@ -161,59 +163,59 @@ struct CLR_PRF_Profiler { // This is not implemented: // Write formatter functions to send only as many bits as needed for uint32,uint64 numbers, cast bytes, etc. - static HRESULT CreateInstance(); - static HRESULT DeleteInstance(); + static HRESULT CreateInstance(); + static HRESULT DeleteInstance(); - HRESULT Stream_Send(); - HRESULT Stream_Flush(); + HRESULT Stream_Send(); + HRESULT Stream_Flush(); - HRESULT Profiler_Cleanup(); - HRESULT DumpHeap(); + HRESULT Profiler_Cleanup(); + HRESULT DumpHeap(); #if defined(NANOCLR_PROFILE_NEW_CALLS) - HRESULT RecordContextSwitch( CLR_RT_Thread* nextThread ); - HRESULT RecordFunctionCall( CLR_RT_Thread* th, CLR_RT_MethodDef_Index md ); - HRESULT RecordFunctionReturn( CLR_RT_Thread* th, CLR_PROF_CounterCallChain& prof ); + HRESULT RecordContextSwitch(CLR_RT_Thread *nextThread); + HRESULT RecordFunctionCall(CLR_RT_Thread *th, CLR_RT_MethodDef_Index md); + HRESULT RecordFunctionReturn(CLR_RT_Thread *th, CLR_PROF_CounterCallChain &prof); #endif #if defined(NANOCLR_PROFILE_NEW_ALLOCATIONS) - void TrackObjectCreation( CLR_RT_HeapBlock* ptr ); - void TrackObjectDeletion( CLR_RT_HeapBlock* ptr ); - void TrackObjectRelocation(); - void RecordGarbageCollectionBegin(); - void RecordGarbageCollectionEnd(); - void RecordHeapCompactionBegin(); - void RecordHeapCompactionEnd(); + void TrackObjectCreation(CLR_RT_HeapBlock *ptr); + void TrackObjectDeletion(CLR_RT_HeapBlock *ptr); + void TrackObjectRelocation(); + void RecordGarbageCollectionBegin(); + void RecordGarbageCollectionEnd(); + void RecordHeapCompactionBegin(); + void RecordHeapCompactionEnd(); #endif - void SendMemoryLayout(); - -private: - void SendTrue(); - void SendFalse(); - void Timestamp(); - void PackAndWriteBits( CLR_UINT32 value ); - void PackAndWriteBits( const CLR_RT_TypeDef_Index& typeDef ); - void PackAndWriteBits( const CLR_RT_MethodDef_Index& methodDef ); - CLR_RT_HeapBlock* FindReferencedObject( CLR_RT_HeapBlock* ref ); - HRESULT DumpRoots(); - void DumpRoot( CLR_RT_HeapBlock* root, CLR_UINT32 type, CLR_UINT32 flags, CLR_RT_MethodDef_Index* source ); - void DumpObject( CLR_RT_HeapBlock* ptr ); - void DumpEndOfRefsList(); - void DumpPointer( void* ref ); - void DumpSingleReference( CLR_RT_HeapBlock* ptr ); - void DumpListOfReferences( CLR_RT_DblLinkedList& list ); - void DumpListOfReferences( CLR_RT_HeapBlock* firstItem, CLR_UINT16 count ); - - CLR_RT_HeapBlock_MemoryStream* m_stream; - CLR_UINT16 m_packetSeqId; - CLR_UINT32 m_lastTimestamp; - CLR_IDX m_currentAssembly; - int m_currentThreadPID; + void SendMemoryLayout(); + + private: + void SendTrue(); + void SendFalse(); + void Timestamp(); + void PackAndWriteBits(CLR_UINT32 value); + void PackAndWriteBits(const CLR_RT_TypeDef_Index &typeDef); + void PackAndWriteBits(const CLR_RT_MethodDef_Index &methodDef); + CLR_RT_HeapBlock *FindReferencedObject(CLR_RT_HeapBlock *ref); + HRESULT DumpRoots(); + void DumpRoot(CLR_RT_HeapBlock *root, CLR_UINT32 type, CLR_UINT32 flags, CLR_RT_MethodDef_Index *source); + void DumpObject(CLR_RT_HeapBlock *ptr); + void DumpEndOfRefsList(); + void DumpPointer(void *ref); + void DumpSingleReference(CLR_RT_HeapBlock *ptr); + void DumpListOfReferences(CLR_RT_DblLinkedList &list); + void DumpListOfReferences(CLR_RT_HeapBlock *firstItem, CLR_UINT16 count); + + CLR_RT_HeapBlock_MemoryStream *m_stream; + CLR_UINT16 m_packetSeqId; + CLR_UINT32 m_lastTimestamp; + CLR_IDX m_currentAssembly; + int m_currentThreadPID; + bool m_initialized; }; extern CLR_PRF_Profiler g_CLR_PRF_Profiler; -#endif //defined(NANOCLR_PROFILE_NEW) +#endif // defined(NANOCLR_PROFILE_NEW) #endif // NANOCLR_PROFILING_H - diff --git a/src/CLR/Include/nanoCLR_Runtime.h b/src/CLR/Include/nanoCLR_Runtime.h index 3086011eb8..9278f8054d 100644 --- a/src/CLR/Include/nanoCLR_Runtime.h +++ b/src/CLR/Include/nanoCLR_Runtime.h @@ -877,7 +877,7 @@ struct CLR_RT_MethodDef_DebuggingInfo } }; -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1133,7 +1133,7 @@ struct CLR_RT_Assembly : public CLR_RT_HeapBlock_Node // EVENT HEAP - NO RELOCAT #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) size_t iDebuggingInfoMethods; -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) }; //--// @@ -1188,7 +1188,7 @@ struct CLR_RT_Assembly : public CLR_RT_HeapBlock_Node // EVENT HEAP - NO RELOCAT #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) CLR_RT_MethodDef_DebuggingInfo *m_pDebuggingInfo_MethodDef; // EVENT HEAP - NO RELOCATION - (but the data they point to has to be relocated) -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) #if defined(NANOCLR_TRACE_STACK_HEAVY) && defined(VIRTUAL_DEVICE) int m_maxOpcodes; @@ -1965,7 +1965,7 @@ struct CLR_RT_MethodDef_Instance : public CLR_RT_MethodDef_Index { return m_assm->m_pDebuggingInfo_MethodDef[Method()]; } -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) }; //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -2242,7 +2242,7 @@ struct CLR_RT_StackFrame : public CLR_RT_HeapBlock_Node // EVENT HEAP - NO RELOC #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) CLR_UINT32 m_depth; -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) #if defined(NANOCLR_PROFILE_NEW_CALLS) CLR_PROF_CounterCallChain m_callchain; @@ -2600,7 +2600,7 @@ struct CLR_RT_GarbageCollector CLR_UINT8 *m_start; CLR_UINT8 *m_end; CLR_UINT8 *m_destination; - CLR_UINT32 m_offset; + CLR_INT32 m_offset; }; //--// @@ -3017,7 +3017,7 @@ struct CLR_RT_Thread : public CLR_RT_ObjectToEvent_Destination // EVENT HEAP - N // However, if this thread was spawned on behalf of the debugger to evaluate // a property or function call, it points to the object coresponding to the // thread that is currently selected in the debugger. -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) #if defined(ENABLE_NATIVE_PROFILER) bool m_fNativeProfiled; @@ -3161,12 +3161,12 @@ struct CLR_RT_Thread : public CLR_RT_ObjectToEvent_Destination // EVENT HEAP - N //////////////////////////////////////////////////////////////////////////////// -extern size_t LinkArraySize(); -extern size_t LinkMRUArraySize(); -extern size_t PayloadArraySize(); -extern size_t InterruptRecords(); +extern uint32_t LinkArraySize(); +extern uint32_t LinkMRUArraySize(); +extern uint32_t PayloadArraySize(); +extern uint32_t InterruptRecords(); #ifndef NANOCLR_NO_IL_INLINE -extern size_t InlineBufferCount(); +extern uint32_t InlineBufferCount(); #endif extern CLR_UINT32 g_scratchVirtualMethodTableLink[]; @@ -3388,7 +3388,8 @@ CT_ASSERT(sizeof(CLR_RT_EventCache::Payload) == 12) #include #include -//#include +#include +// #include //--// @@ -3441,10 +3442,9 @@ struct CLR_RT_ExecutionEngine static const int c_HeapState_Normal = 0x00000000; static const int c_HeapState_UnderGC = 0x00000001; - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // NEED TO KEEP THESE IN SYNC WITH Enum 'Commands.Debugging_Execution_ChangeConditions...' on debugger library code - // // - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // NEED TO KEEP THESE IN SYNC WITH Enum Commands.Debugging_Execution_ChangeConditions.. on debugger library code // + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// static const int c_fDebugger_StateInitialize = 0x00000000; static const int c_fDebugger_StateResolutionFailed = 0x00000001; @@ -3454,13 +3454,16 @@ struct CLR_RT_ExecutionEngine c_fDebugger_StateProgramRunning + c_fDebugger_StateProgramExited + c_fDebugger_StateResolutionFailed; // static const int c_fDebugger_BreakpointsDisabled = 0x00001000; - // - static const int c_fDebugger_Quiet = 0x00010000; // Do not spew debug text to the debugger + // Do not spew debug text to the debugger + static const int c_fDebugger_Quiet = 0x00010000; static const int c_fDebugger_ExitPending = 0x00020000; - // - static const int c_fDebugger_PauseTimers = - 0x04000000; // Threads associated with timers are created in "suspended" mode. - static const int c_fDebugger_NoCompaction = 0x08000000; // Don't perform compaction during execution. + + // Execution engine won't process stack trace when an exception occurs. + static const int c_fDebugger_NoStackTraceInExceptions = 0x02000000; + // Threads associated with timers are created in "suspended" mode. + static const int c_fDebugger_PauseTimers = 0x04000000; + // Don't perform compaction during execution. + static const int c_fDebugger_NoCompaction = 0x08000000; // static const int c_fDebugger_SourceLevelDebugging = 0x10000000; static const int c_fDebugger_RebootPending = 0x20000000; @@ -3506,7 +3509,7 @@ struct CLR_RT_ExecutionEngine CLR_DBG_Commands::Debugging_Execution_BreakpointDef *m_breakpoints; CLR_DBG_Commands::Debugging_Execution_BreakpointDef m_breakpointsActive[c_MaxBreakpointsActive]; size_t m_breakpointsActiveNum; -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) #if !defined(BUILD_RTM) || defined(VIRTUAL_DEVICE) bool m_fPerformGarbageCollection; // Should the EE do a GC every context switch @@ -3664,7 +3667,11 @@ struct CLR_RT_ExecutionEngine //--// +#if defined(VIRTUAL_DEVICE) + static HRESULT CreateInstance(CLR_SETTINGS params); +#else static HRESULT CreateInstance(); +#endif HRESULT ExecutionEngine_Initialize(); @@ -3800,7 +3807,7 @@ struct CLR_RT_ExecutionEngine void Breakpoint_Exception(CLR_RT_StackFrame *stack, CLR_UINT32 reason, CLR_PMETADATA ip); void Breakpoint_Exception_Intercepted(CLR_RT_StackFrame *stack); void Breakpoint_Exception_Uncaught(CLR_RT_Thread *th); -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) //--// diff --git a/src/CLR/Messaging/Messaging.cpp b/src/CLR/Messaging/Messaging.cpp index 2e2eca81de..0a2df9cbea 100644 --- a/src/CLR/Messaging/Messaging.cpp +++ b/src/CLR/Messaging/Messaging.cpp @@ -9,8 +9,6 @@ #include #include -CLR_Messaging g_CLR_Messaging; - //////////////////////////////////////////////////////////////////////////////////////////////////// //--// @@ -29,6 +27,8 @@ static const CLR_Messaging_CommandHandlerLookup c_Messaging_Lookup_Reply[] = { //--// +CLR_Messaging *g_CLR_Messaging; + bool CLR_Messaging::AllocateAndQueueMessage( CLR_UINT32 cmd, unsigned int length, @@ -92,7 +92,7 @@ bool CLR_Messaging::Messaging_Query__Reply(WP_Message *msg) CLR_Messaging_Commands::Messaging_Query::Reply *cmd = (CLR_Messaging_Commands::Messaging_Query::Reply *)msg->m_payload; - g_CLR_Messaging.AllocateAndQueueMessage( + g_CLR_Messaging->AllocateAndQueueMessage( CLR_Messaging_Commands::c_Messaging_Query, 0, NULL, @@ -115,7 +115,7 @@ bool CLR_Messaging::Messaging_Send(WP_Message *msg) len = msg->m_header.m_size - sizeof(cmd->m_addr); - fRes = g_CLR_Messaging.AllocateAndQueueMessage( + fRes = g_CLR_Messaging->AllocateAndQueueMessage( CLR_Messaging_Commands::c_Messaging_Send, len, cmd->m_data, @@ -154,7 +154,7 @@ bool CLR_Messaging::Messaging_Reply(WP_Message *msg) CLR_UINT32 len; len = msg->m_header.m_size - sizeof(cmd->m_addr); - fRes = g_CLR_Messaging.AllocateAndQueueMessage( + fRes = g_CLR_Messaging->AllocateAndQueueMessage( CLR_Messaging_Commands::c_Messaging_Reply, len, cmd->m_data, @@ -254,11 +254,18 @@ HRESULT CLR_Messaging::CreateInstance() NATIVE_PROFILE_CLR_MESSAGING(); NANOCLR_HEADER(); - NANOCLR_CLEAR(g_CLR_Messaging); + // alloc memory for Messaging + g_CLR_Messaging = (CLR_Messaging *)platform_malloc(sizeof(CLR_Messaging)); - g_CLR_Messaging.Initialize(NULL, 0, NULL, 0); + // sanity check... + FAULT_ON_NULL(g_CLR_Messaging); - NANOCLR_NOCLEANUP_NOLABEL(); + //... and clear memory + memset(g_CLR_Messaging, 0, sizeof(CLR_Messaging)); + + g_CLR_Messaging->Initialize(NULL, 0, NULL, 0); + + NANOCLR_NOCLEANUP(); } //--// @@ -296,7 +303,12 @@ HRESULT CLR_Messaging::DeleteInstance() NATIVE_PROFILE_CLR_MESSAGING(); NANOCLR_HEADER(); - g_CLR_Messaging.Cleanup(); + g_CLR_Messaging->Cleanup(); + + // free messaging + platform_free(g_CLR_Messaging); + + g_CLR_Messaging = NULL; NANOCLR_NOCLEANUP_NOLABEL(); } diff --git a/src/CLR/Messaging/Messaging_stub.cpp b/src/CLR/Messaging/Messaging_stub.cpp index cd50d16daa..2a02272de3 100644 --- a/src/CLR/Messaging/Messaging_stub.cpp +++ b/src/CLR/Messaging/Messaging_stub.cpp @@ -7,14 +7,9 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// -__nfweak CLR_Messaging *g_CLR_Messaging; - -__nfweak CLR_UINT32 g_scratchMessaging[sizeof(CLR_Messaging) ]; - __nfweak HRESULT CLR_Messaging::CreateInstance() { NATIVE_PROFILE_CLR_MESSAGING(); - g_CLR_Messaging = (CLR_Messaging*)&g_scratchMessaging[0]; NANOCLR_SYSTEM_STUB_RETURN(); } @@ -24,7 +19,11 @@ __nfweak HRESULT CLR_Messaging::DeleteInstance() NANOCLR_SYSTEM_STUB_RETURN(); } -__nfweak bool CLR_Messaging::SendEvent( unsigned int cmd, unsigned int payloadSize, unsigned char* payload, unsigned int flags ) +__nfweak bool CLR_Messaging::SendEvent( + unsigned int cmd, + unsigned int payloadSize, + unsigned char *payload, + unsigned int flags) { (void)cmd; (void)payloadSize; @@ -35,7 +34,11 @@ __nfweak bool CLR_Messaging::SendEvent( unsigned int cmd, unsigned int payloadSi return true; } -__nfweak void CLR_Messaging::Initialize(const CLR_Messaging_CommandHandlerLookup* requestLookup, const CLR_UINT32 requestLookupCount, const CLR_Messaging_CommandHandlerLookup* replyLookup, const CLR_UINT32 replyLookupCount ) +__nfweak void CLR_Messaging::Initialize( + const CLR_Messaging_CommandHandlerLookup *requestLookup, + const CLR_UINT32 requestLookupCount, + const CLR_Messaging_CommandHandlerLookup *replyLookup, + const CLR_UINT32 replyLookupCount) { (void)requestLookup; (void)requestLookupCount; diff --git a/src/CLR/Startup/CLRStartup.cpp b/src/CLR/Startup/CLRStartup.cpp index e7fc1f64bc..60343a29bd 100644 --- a/src/CLR/Startup/CLRStartup.cpp +++ b/src/CLR/Startup/CLRStartup.cpp @@ -82,6 +82,7 @@ struct Settings // First verify that check sum in assembly object matches hardcoded check sum. if (assm->m_header->nativeMethodsChecksum != pNativeAssmData->m_checkSum) { +#if !defined(BUILD_RTM) CLR_Debug::Printf( "\r\n\r\n***********************************************************************\r\n"); CLR_Debug::Printf("* *\r\n"); @@ -95,6 +96,7 @@ struct Settings pNativeAssmData->m_checkSum); CLR_Debug::Printf("* *\r\n"); CLR_Debug::Printf("***********************************************************************\r\n"); +#endif NANOCLR_SET_AND_LEAVE(CLR_E_ASSM_WRONG_CHECKSUM); } @@ -402,7 +404,7 @@ void ClrStartup(CLR_SETTINGS params) CLR_Debug::Printf("Ready.\r\n"); #endif - (void)g_CLR_RT_ExecutionEngine.Execute(NULL, params.MaxContextSwitches); + hr = g_CLR_RT_ExecutionEngine.Execute(NULL, params.MaxContextSwitches); #if !defined(BUILD_RTM) CLR_Debug::Printf("Done.\r\n"); @@ -422,14 +424,29 @@ void ClrStartup(CLR_SETTINGS params) #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) CLR_EE_DBG_SET_MASK(StateProgramExited, StateMask); CLR_EE_DBG_EVENT_BROADCAST(CLR_DBG_Commands_c_Monitor_ProgramExit, 0, NULL, WP_Flags_c_NonCritical); -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) + +#if defined(BUILD_RTM) + if (params.RevertToBooterOnFault) + { + // launch proprietary bootloader, if available + if (!RequestToLaunchProprietaryBootloader()) + { + // no proprietary bootloader available, launch nanoBooter + +#if (TARGET_HAS_NANOBOOTER == TRUE) + + RequestToLaunchNanoBooter(hr); + CPU_Reset(); +#endif // TARGET_HAS_NANOBOOTER + } + } +#endif -#if !defined(BUILD_RTM) if (params.EnterDebuggerLoopAfterExit) { CLR_DBG_Debugger::Debugger_WaitForCommands(); } -#endif } // DO NOT USE 'ELSE IF' here because the state can change in Debugger_WaitForCommands() call @@ -444,7 +461,7 @@ void ClrStartup(CLR_SETTINGS params) s_ClrSettings.Cleanup(); - nanoHAL_Uninitialize(); + nanoHAL_Uninitialize(false); // re-init the hal for the reboot (initially it is called in bootentry) nanoHAL_Initialize(); diff --git a/src/CLR/WireProtocol/WireProtocol.vcxproj b/src/CLR/WireProtocol/WireProtocol.vcxproj index da80571197..a335cf00db 100644 --- a/src/CLR/WireProtocol/WireProtocol.vcxproj +++ b/src/CLR/WireProtocol/WireProtocol.vcxproj @@ -130,7 +130,7 @@ MaxSpeed true true - NDEBUG;_LIB;VERSION_MAJOR=$(NBGV_VersionMajor);TARGETNAMESTRING="CLR_WIN32";TARGETINFOSTRING="CLR_WIN32";%(PreprocessorDefinitions) + NDEBUG;_LIB;VERSION_MAJOR=$(NBGV_VersionMajor);VERSION_MINOR=$(NBGV_VersionMinor);VERSION_BUILD=$(NBGV_BuildNumber);VERSION_REVISION=$(NBGV_RevisionNumber);TARGETNAMESTRING="CLR_WIN32";TARGETINFOSTRING="CLR_WIN32";%(PreprocessorDefinitions) ..\..\..\targets\win32\Include;..\Include;..\..\HAL\Include;..\..\PAL\Include @@ -147,7 +147,7 @@ MaxSpeed true true - NDEBUG;_LIB;VERSION_MAJOR=$(NBGV_VersionMajor);TARGETNAMESTRING="CLR_WIN32";TARGETINFOSTRING="CLR_WIN32";%(PreprocessorDefinitions) + NDEBUG;_LIB;VERSION_MAJOR=$(NBGV_VersionMajor);VERSION_MINOR=$(NBGV_VersionMinor);VERSION_BUILD=$(NBGV_BuildNumber);VERSION_REVISION=$(NBGV_RevisionNumber);TARGETNAMESTRING="CLR_WIN32";TARGETINFOSTRING="CLR_WIN32";%(PreprocessorDefinitions) ..\..\..\targets\win32\Include;..\Include;..\..\HAL\Include;..\..\PAL\Include diff --git a/src/CLR/WireProtocol/WireProtocol_Message.c b/src/CLR/WireProtocol/WireProtocol_Message.c index b23cc72b1a..5facf303ed 100644 --- a/src/CLR/WireProtocol/WireProtocol_Message.c +++ b/src/CLR/WireProtocol/WireProtocol_Message.c @@ -279,7 +279,7 @@ void WP_Message_Process() break; } - size_t lenCmp = min(len, sizeof(_inboundMessage.m_header.m_signature)); + size_t lenCmp = min(len, sizeof(((WP_Packet *)0)->m_signature)); if (memcmp(&_inboundMessage.m_header, MARKER_DEBUGGER_V1, lenCmp) == 0) { @@ -290,11 +290,8 @@ void WP_Message_Process() break; } - // move buffer 1 position down - memmove( - (uint8_t *)&(_inboundMessage.m_header), - ((uint8_t *)&(_inboundMessage.m_header) + 1), - len - 1); + // move buffer one position to the left + memmove((uint8_t *)&(_inboundMessage.m_header), ((uint8_t *)&(_inboundMessage.m_header) + 1), len); _pos--; _size++; @@ -458,12 +455,14 @@ void WP_PrepareAndSendProtocolMessage(uint32_t cmd, uint32_t payloadSize, uint8_ /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // weak implementations of the functions (to be replaced with _strong_ implementations if and when required) // +#if !defined(BUILD_RTM) __nfweak void debug_printf(const char *format, ...) { (void)format; return; } +#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/CLR/WireProtocol/targetHAL_time.cpp b/src/CLR/WireProtocol/targetHAL_time.cpp index 3397c00920..a336b485b1 100644 --- a/src/CLR/WireProtocol/targetHAL_time.cpp +++ b/src/CLR/WireProtocol/targetHAL_time.cpp @@ -10,7 +10,7 @@ extern "C" { - unsigned int HAL_Time_CurrentSysTicks() + uint64_t HAL_Time_CurrentSysTicks() { // TODO need to check if using the Win32 100ns ticks works return 0; // UNDONE: FIXME: EmulatorNative::GetITimeDriver()->CurrentTicks(); diff --git a/src/DeviceInterfaces/Network/Enc28j60/enc28j60_lwip.cpp b/src/DeviceInterfaces/Network/Enc28j60/enc28j60_lwip.cpp index e9d6b27777..8d3bb461e4 100644 --- a/src/DeviceInterfaces/Network/Enc28j60/enc28j60_lwip.cpp +++ b/src/DeviceInterfaces/Network/Enc28j60/enc28j60_lwip.cpp @@ -614,7 +614,7 @@ err_t enc28j60_lwip_xmit(struct netif *pNetIF, struct pbuf *pPBuf) } // CPU_SPI_nWrite8_nRead8(spiHandle, false, pTx, length+2, 0, 0, 0 ); - SPI_WRITE_READ_SETTINGS wrc{false, 0, false, 0}; + SPI_WRITE_READ_SETTINGS wrc{false, 0, false, 0, ENC28J60_CS, ENC28J60_CS_ACTIVE}; nanoSPI_Write_Read(spiHandle, wrc, pTx, length + 2, 0, 0); // FIXME @@ -925,9 +925,7 @@ void enc28j60_lwip_destroy_device() spiHandle, ENC28J60_SPI_BIT_FIELD_CLEAR_OPCODE, ENC28J60_EIE, - (uint8_t)( - (1 << ENC28J60_EIE_INTIE_BIT) | (1 << ENC28J60_EIE_PKTIE_BIT) | (1 << ENC28J60_EIE_TXIE_BIT) | - (1 << ENC28J60_EIE_TXERIE_BIT))); + (uint8_t)((1 << ENC28J60_EIE_INTIE_BIT) | (1 << ENC28J60_EIE_PKTIE_BIT) | (1 << ENC28J60_EIE_TXIE_BIT) | (1 << ENC28J60_EIE_TXERIE_BIT))); } /* @@ -1079,7 +1077,7 @@ void enc28j60_lwip_write_spi(uint32_t spiHandle, uint8_t opcode, uint8_t address commandWithData[1] = byteData; // CPU_SPI_nWrite8_nRead8 (spiHandle, false, commandWithData, 2, 0, 0, 0); - SPI_WRITE_READ_SETTINGS wrc{false, 0, false, 0}; + SPI_WRITE_READ_SETTINGS wrc{false, 0, false, 0, ENC28J60_CS, ENC28J60_CS_ACTIVE}; nanoSPI_Write_Read(spiHandle, wrc, commandWithData, 2, 0, 0); } @@ -1142,14 +1140,12 @@ void enc28j60_lwip_soft_reset(uint32_t spiHandle) spiHandle, ENC28J60_SPI_BIT_FIELD_CLEAR_OPCODE, ENC28J60_EIE, - (uint8_t)( - (1 << ENC28J60_EIE_INTIE_BIT) | (1 << ENC28J60_EIE_PKTIE_BIT) | (1 << ENC28J60_EIE_TXIE_BIT) | - (1 << ENC28J60_EIE_TXERIE_BIT))); + (uint8_t)((1 << ENC28J60_EIE_INTIE_BIT) | (1 << ENC28J60_EIE_PKTIE_BIT) | (1 << ENC28J60_EIE_TXIE_BIT) | (1 << ENC28J60_EIE_TXERIE_BIT))); /* Combine the command and the data */ byteData = (ENC28J60_SPI_SYSTEM_COMMAND_SOFT_RESET_OPCODE << 5) | ENC28J60_SPI_SYSTEM_COMMAND_SOFT_RESET_ARGUMENT; - SPI_WRITE_READ_SETTINGS wrc{false, 0, false, 0}; + SPI_WRITE_READ_SETTINGS wrc{false, 0, false, 0, ENC28J60_CS, ENC28J60_CS_ACTIVE}; nanoSPI_Write_Read(spiHandle, wrc, (uint8_t *)&byteData, 1, 0, 0); // Errata : After reset wait for 100 ms @@ -1195,7 +1191,7 @@ void enc28j60_lwip_read_spi( /* Write the command and read*/ // CPU_SPI_nWrite8_nRead8 (spiHandle, false, &opcodeArg, 1, byteData, numBytes+offset, offset+1); // Note uses offset on read data - SPI_WRITE_READ_SETTINGS wrc{false, offset, false, 0}; + SPI_WRITE_READ_SETTINGS wrc{false, offset, false, 0, ENC28J60_CS, ENC28J60_CS_ACTIVE}; nanoSPI_Write_Read(spiHandle, wrc, &opcodeArg, 1, byteData, numBytes); } diff --git a/src/DeviceInterfaces/Networking.Sntp/lwip_sntp_default_options.h b/src/DeviceInterfaces/Networking.Sntp/lwip_sntp_default_options.h index 4742c3b60c..a55419f165 100644 --- a/src/DeviceInterfaces/Networking.Sntp/lwip_sntp_default_options.h +++ b/src/DeviceInterfaces/Networking.Sntp/lwip_sntp_default_options.h @@ -13,10 +13,13 @@ #define SNTP_UPDATE_DELAY 3600000 #endif -// better have a startup delay because we can have DHCP enabled (default 15 seconds) -// value in milliseconds -#define SNTP_STARTUP_DELAY 15 * 1000 +// startup delay (default 2 seconds) +// (value in milliseconds) +// Remarks: because we could have DHCP enabled +// we allow time for the IP to be established +// but also need to take into account that NetworkHelper is likely to timeout +#define SNTP_STARTUP_DELAY 2000 // retry timeout (15 minutes) -// value in milliseconds +// (value in milliseconds) #define SNTP_RETRY_TIMEOUT 900000 diff --git a/src/HAL/Include/nanoHAL.h b/src/HAL/Include/nanoHAL.h index a995cadc51..9f778e2728 100644 --- a/src/HAL/Include/nanoHAL.h +++ b/src/HAL/Include/nanoHAL.h @@ -31,11 +31,11 @@ #include #include -//#if !defined(_WIN32) && !defined(FIQ_SAMPLING_PROFILER) && !defined(HAL_REDUCESIZE) && defined(PROFILE_BUILD) -//#define ENABLE_NATIVE_PROFILER -//#endif +// #if !defined(_WIN32) && !defined(FIQ_SAMPLING_PROFILER) && !defined(HAL_REDUCESIZE) && defined(PROFILE_BUILD) +// #define ENABLE_NATIVE_PROFILER +// #endif -//#include "..\pal\Diagnostics\Native_Profiler.h" +// #include "..\pal\Diagnostics\Native_Profiler.h" #define NATIVE_PROFILE_CLR_DEBUGGER() #define NATIVE_PROFILE_CLR_UTF8_DECODER() @@ -92,13 +92,13 @@ : 0) #define USART_TRANSPORT (1 << TRANSPORT_SHIFT) -//#define COM_NULL ((COM_HANDLE)(USART_TRANSPORT)) +// #define COM_NULL ((COM_HANDLE)(USART_TRANSPORT)) #define USB_TRANSPORT (2 << TRANSPORT_SHIFT) -//#define USB_CONTROLLER_SHIFT 5 -//#define USB_CONTROLLER_MASK 0xE0 -//#define USB_STREAM_MASK 0x00FF -//#define USB_STREAM_INDEX_MASK 0x001F +// #define USB_CONTROLLER_SHIFT 5 +// #define USB_CONTROLLER_MASK 0xE0 +// #define USB_STREAM_MASK 0x00FF +// #define USB_STREAM_INDEX_MASK 0x001F #define SOCKET_TRANSPORT (3 << TRANSPORT_SHIFT) #define COM_SOCKET_DBG ((COM_HANDLE)(SOCKET_TRANSPORT + 1)) @@ -793,14 +793,14 @@ template class HAL_RingBuffer //--// -//#include <..\Initialization\MasterConfig.h> +// #include <..\Initialization\MasterConfig.h> //--// // hal cleanup for CLR reboot void nanoHAL_Initialize(); -void nanoHAL_Uninitialize(); +void nanoHAL_Uninitialize(bool isPoweringDown); typedef void (*ON_SOFT_REBOOT_HANDLER)(void); @@ -820,7 +820,7 @@ extern bool g_fDoNotUninitializeDebuggerPort; #include #include -//#include +// #include ///////////////////////////////////////////////////////////////////// // @@ -828,18 +828,18 @@ extern bool g_fDoNotUninitializeDebuggerPort; // //// boot -//#include +// #include // //// Cache driver -//#include +// #include // //// Cache driver -//#include +// #include // //// Gp I/O driver -//#include +// #include // -// Gp I/O driver +// Gp I/O driver #include // @@ -848,32 +848,32 @@ extern bool g_fDoNotUninitializeDebuggerPort; // //// External bus interface driver -//#include +// #include // //// Power control unit -//#include +// #include // //// Clock management unit driver -//#include +// #include // //// DMA driver -//#include +// #include // -//#include +// #include // //// Virtual Key -//#include +// #include // //// Power API -//#include +// #include // // Chipset // ///////////////////////////////////////////////////////////////////// -//#include +// #include // platform_selector.h (from MasterConfig.h) diff --git a/src/HAL/Include/nanoHAL_Boot.h b/src/HAL/Include/nanoHAL_Boot.h index b73ddd38ad..69be53c3e2 100644 --- a/src/HAL/Include/nanoHAL_Boot.h +++ b/src/HAL/Include/nanoHAL_Boot.h @@ -42,7 +42,7 @@ typedef struct __nfpack BootClipboard BootRequest_Options BootRequest; uint32_t BootParameters; BootExecution_Options BootExecution; - uint32_t ErrorCode; + int32_t ErrorCode; VersionInfo BooterVersion; VersionInfo CLRVersion; @@ -73,9 +73,9 @@ extern "C" // Returns true if the there is a request to remain in nanoBooter bool IsToRemainInBooter(); - // Request to launch nanoBooter + // Request to launch nanoBooter and set an error code // Returns false in case it's not supported (which is considered the default). - bool RequestToLaunchNanoBooter(); + bool RequestToLaunchNanoBooter(int32_t errorCode); // Request to launch proprietary bootloader // Returns false in case it's not supported (which is considered the default). diff --git a/src/HAL/Include/nanoHAL_Rtos.h b/src/HAL/Include/nanoHAL_Rtos.h new file mode 100644 index 0000000000..1f7a89c0b1 --- /dev/null +++ b/src/HAL/Include/nanoHAL_Rtos.h @@ -0,0 +1,24 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#ifndef NANOHAL_RTOS_H +#define NANOHAL_RTOS_H + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** + * Function to call RTOS API that implements yield/sleep or equivalent allowing the RTOS to run threads other than + * the CLR. Implemented as weak so that it can be overridden by a platform specific implementation if required. + */ + void RtosYield(); + +#ifdef __cplusplus +} +#endif + +#endif // NANOHAL_RTOS_H diff --git a/src/HAL/Include/nanoHAL_Time.h b/src/HAL/Include/nanoHAL_Time.h index acc5c22582..bac5dd70e4 100644 --- a/src/HAL/Include/nanoHAL_Time.h +++ b/src/HAL/Include/nanoHAL_Time.h @@ -51,6 +51,8 @@ extern "C" /// exception if you are to create that date. To stay safe side 1/1/1601 is taken as origin, as was done for /// Windows. + // this function, because it is called VERY VERY often, is implemented as inlined on each platform + // in the targetHAL_Time.h file uint64_t HAL_Time_SysTicksToTime(uint64_t sysTicks); /// diff --git a/src/HAL/Include/nanoHAL_v2.h b/src/HAL/Include/nanoHAL_v2.h index b38f27f307..5f800f7e28 100644 --- a/src/HAL/Include/nanoHAL_v2.h +++ b/src/HAL/Include/nanoHAL_v2.h @@ -13,11 +13,11 @@ #include // defines to prevent use of malloc, free and realloc -// the platform implementations: platform_malloc(), platform_free and platform_realloc -// are the preferred calls to use as they ensure thread safety and RTOS integration -#define malloc YOU_SHALL_NOT_USE_malloc -#define free YOU_SHALL_NOT_USE_free -#define realloc YOU_SHALL_NOT_USE_realloc +// the platform implementations: platform_malloc(), platform_free() should be used instead. +// realloc should never be used. +// as these the preferred calls to use as they ensure thread safety and RTOS integration. +#define malloc YOU_SHALL_NOT_USE_malloc +#define free YOU_SHALL_NOT_USE_free #endif @@ -63,36 +63,36 @@ typedef enum SLEEP_LEVEL #define SYSTEM_EVENT_FLAG_SYSTEM_TIMER 0x00000010 #define SYSTEM_EVENT_FLAG_USB_IN 0x00000020 #define SYSTEM_EVENT_FLAG_USB_OUT 0x00000040 -//#define SYSTEM_EVENT_FLAG_TIMER1 0x00000020 -//#define SYSTEM_EVENT_FLAG_TIMER2 0x00000040 -//#define SYSTEM_EVENT_FLAG_BUTTON 0x00000080 +// #define SYSTEM_EVENT_FLAG_TIMER1 0x00000020 +// #define SYSTEM_EVENT_FLAG_TIMER2 0x00000040 +// #define SYSTEM_EVENT_FLAG_BUTTON 0x00000080 #define SYSTEM_EVENT_FLAG_GENERIC_PORT 0x00000100 -//#define SYSTEM_EVENT_FLAG_UNUSED_0x00000200 0x00000200 -//#define SYSTEM_EVENT_FLAG_UNUSED_0x00000400 0x00000400 +// #define SYSTEM_EVENT_FLAG_UNUSED_0x00000200 0x00000200 +// #define SYSTEM_EVENT_FLAG_UNUSED_0x00000400 0x00000400 #define SYSTEM_EVENT_FLAG_NETWORK 0x00000800 -//#define SYSTEM_EVENT_FLAG_TONE_COMPLETE 0x00001000 -//#define SYSTEM_EVENT_FLAG_TONE_BUFFER_EMPTY 0x00002000 +// #define SYSTEM_EVENT_FLAG_TONE_COMPLETE 0x00001000 +// #define SYSTEM_EVENT_FLAG_TONE_BUFFER_EMPTY 0x00002000 #define SYSTEM_EVENT_FLAG_SOCKET 0x00004000 #define SYSTEM_EVENT_FLAG_ONEWIRE_MASTER 0x00008000 #define SYSTEM_EVENT_FLAG_RADIO 0x00010000 #define SYSTEM_EVENT_FLAG_BLUETOOTH 0x00020000 -//#define SYSTEM_EVENT_FLAG_SPI 0x00008000 -//#define SYSTEM_EVENT_FLAG_OEM_RESERVED_1 0x00020000 -//#define SYSTEM_EVENT_FLAG_OEM_RESERVED_2 0x00040000 -//#define SYSTEM_EVENT_FLAG_UNUSED_0x00080000 0x00080000 -//#define SYSTEM_EVENT_FLAG_UNUSED_0x00100000 0x00100000 +// #define SYSTEM_EVENT_FLAG_SPI 0x00008000 +// #define SYSTEM_EVENT_FLAG_OEM_RESERVED_1 0x00020000 +// #define SYSTEM_EVENT_FLAG_OEM_RESERVED_2 0x00040000 +// #define SYSTEM_EVENT_FLAG_UNUSED_0x00080000 0x00080000 +// #define SYSTEM_EVENT_FLAG_UNUSED_0x00100000 0x00100000 -//#define SYSTEM_EVENT_FLAG_UNUSED_0x00200000 0x00200000 -//#define SYSTEM_EVENT_FLAG_UNUSED_0x00400000 0x00400000 -//#define SYSTEM_EVENT_FLAG_UNUSED_0x00800000 0x00800000 +// #define SYSTEM_EVENT_FLAG_UNUSED_0x00200000 0x00200000 +// #define SYSTEM_EVENT_FLAG_UNUSED_0x00400000 0x00400000 +// #define SYSTEM_EVENT_FLAG_UNUSED_0x00800000 0x00800000 #define SYSTEM_EVENT_FLAG_WIFI_STATION 0x01000000 #define SYSTEM_EVENT_FLAG_SPI_MASTER 0x02000000 #define SYSTEM_EVENT_FLAG_I2C_MASTER 0x04000000 #define SYSTEM_EVENT_HW_INTERRUPT 0x08000000 #define SYSTEM_EVENT_FLAG_DEBUGGER_ACTIVITY 0x20000000 #define SYSTEM_EVENT_FLAG_MESSAGING_ACTIVITY 0x40000000 -//#define SYSTEM_EVENT_FLAG_UNUSED_0x80000000 0x80000000 +// #define SYSTEM_EVENT_FLAG_UNUSED_0x80000000 0x80000000 #define SYSTEM_EVENT_FLAG_ALL 0xFFFFFFFF //////////////////////////////////////////////////////////////////////////////////////////// @@ -201,7 +201,7 @@ extern "C" #endif void nanoHAL_Initialize_C(); - void nanoHAL_Uninitialize_C(); + void nanoHAL_Uninitialize_C(bool isPoweringDown); void HeapLocation_C(unsigned char **baseAddress, unsigned int *sizeInBytes); // Call to the external memory configuration and initialization function @@ -220,6 +220,11 @@ extern "C" void CPU_Reset(); void CPU_Sleep(SLEEP_LEVEL_type level, uint64_t wakeEvents); void CPU_SetPowerMode(PowerLevel_type powerLevel); + // platform specific handler for power mode changes (may be empty) + void CPU_SetPowerModePlatform(PowerLevel_type powerLevel); + // target specific handler for power mode changes (may be empty) + void CPU_SetPowerModeTarget(PowerLevel_type powerLevel); + bool DebuggerIsConnected(); #ifdef __cplusplus } @@ -237,7 +242,6 @@ extern "C" void *platform_malloc(size_t size); void platform_free(void *ptr); - void *platform_realloc(void *ptr, size_t size); #ifdef __cplusplus } @@ -329,7 +333,7 @@ extern "C" #endif #ifndef _SIDE_ASSERTE -#define _SIDE_ASSERTE(expr) (expr) +#define _SIDE_ASSERTE(expr) (void)(expr) #endif #ifdef STATIC_ASSERT_SUPPORTED @@ -369,6 +373,7 @@ extern "C" __inline void debug_printf(const char *format, ...) { + (void)format; } #endif // !defined(BUILD_RTM) @@ -404,6 +409,7 @@ extern "C" // Watchdog driver #include +#include #include diff --git a/src/HAL/nanoHAL_Boot.c b/src/HAL/nanoHAL_Boot.c index 664b3c6243..73549508f8 100644 --- a/src/HAL/nanoHAL_Boot.c +++ b/src/HAL/nanoHAL_Boot.c @@ -61,14 +61,15 @@ inline bool IsToRemainInBooter() #endif } -// Request to launch nanoBooter +// Request to launch nanoBooter and report error code // Returns false in case it's not supported (which is considered the default). -inline bool RequestToLaunchNanoBooter() +inline bool RequestToLaunchNanoBooter(int32_t errorCode) { #if (TARGET_HAS_NANOBOOTER == TRUE) if (Target_HasNanoBooter()) { g_BootClipboard.BootRequest = BootRequest_NanoBooter; + g_BootClipboard.ErrorCode = errorCode; return true; } #endif diff --git a/src/HAL/nanoHAL_SystemInformation.cpp b/src/HAL/nanoHAL_SystemInformation.cpp index c7a1dde26e..4550ac7903 100644 --- a/src/HAL/nanoHAL_SystemInformation.cpp +++ b/src/HAL/nanoHAL_SystemInformation.cpp @@ -6,6 +6,9 @@ #include #include +#include + +extern CLR_RT_ExecutionEngine g_CLR_RT_ExecutionEngine; bool GetHalSystemInfo(HalSystemInfo &systemInfo) { @@ -59,3 +62,8 @@ bool Target_GetReleaseInfo(NFReleaseInfo &releaseInfo) hal_strlen_s(PLATFORMNAMESTRING)); return TRUE; // alternatively, return false if you didn't initialize the releaseInfo structure. } + +bool DebuggerIsConnected() +{ + return ((g_CLR_RT_ExecutionEngine.m_iDebugger_Conditions & CLR_RT_ExecutionEngine::c_fDebugger_Enabled) != 0); +} diff --git a/src/PAL/AsyncProcCall/AsyncCompletions.cpp b/src/PAL/AsyncProcCall/AsyncCompletions.cpp index 2bbd434590..4806bcec9a 100644 --- a/src/PAL/AsyncProcCall/AsyncCompletions.cpp +++ b/src/PAL/AsyncProcCall/AsyncCompletions.cpp @@ -14,157 +14,175 @@ HAL_DblLinkedList g_HAL_Completion_List; void HAL_COMPLETION::Execute() { - NATIVE_PROFILE_PAL_ASYNC_PROC_CALL(); + NATIVE_PROFILE_PAL_ASYNC_PROC_CALL(); #if defined(_DEBUG) - this->Start_RTC_Ticks = 0; + this->Start_RTC_Ticks = 0; #endif - if (this->ExecuteInISR) - { - HAL_CONTINUATION* cont = this; + if (this->ExecuteInISR) + { + HAL_CONTINUATION *cont = this; - cont->Execute(); - } - else - { - this->Enqueue(); - } + cont->Execute(); + } + else + { + this->Enqueue(); + } } //--// void HAL_COMPLETION::InitializeList() { - NATIVE_PROFILE_PAL_ASYNC_PROC_CALL(); - g_HAL_Completion_List.Initialize(); + NATIVE_PROFILE_PAL_ASYNC_PROC_CALL(); + g_HAL_Completion_List.Initialize(); } //--// void HAL_COMPLETION::DequeueAndExec() { - NATIVE_PROFILE_PAL_ASYNC_PROC_CALL(); + NATIVE_PROFILE_PAL_ASYNC_PROC_CALL(); - GLOBAL_LOCK(); + GLOBAL_LOCK(); - HAL_COMPLETION* ptr = (HAL_COMPLETION*)g_HAL_Completion_List.FirstNode(); + HAL_COMPLETION *ptr = (HAL_COMPLETION *)g_HAL_Completion_List.FirstNode(); - // waitforevents does not have an associated completion, therefore we need to verify - // than their is a next completion and that the current one has expired. - if (ptr->Next()) - { - // Current one expired ? - if (HAL_Time_CurrentTime() >= ptr->EventTimeTicks) - { - Events_Set(SYSTEM_EVENT_FLAG_SYSTEM_TIMER); + // waitforevents does not have an associated completion, therefore we need to verify + // than their is a next completion and that the current one has expired. + if (ptr->Next()) + { + // Current one expired ? + if (HAL_Time_CurrentTime() >= ptr->EventTimeTicks) + { + Events_Set(SYSTEM_EVENT_FLAG_SYSTEM_TIMER); - ptr->Unlink(); + ptr->Unlink(); #if defined(_DEBUG) - ptr->EventTimeTicks = 0; -#endif // defined(_DEBUG) + ptr->EventTimeTicks = 0; +#endif // defined(_DEBUG) - //// let the ISR turn on interrupts, if it needs to - ptr->Execute(); - } + //// let the ISR turn on interrupts, if it needs to + ptr->Execute(); + } - // - // Set the next timer to run otherwise set the next interrupt to be 356 years since last powerup (@25kHz). - Time_SetCompare(ptr->Next() ? ptr->EventTimeTicks : HAL_COMPLETION_IDLE_VALUE); - } + // + // Set the next timer to run otherwise set the next interrupt to be 356 years since last powerup (@25kHz). + Time_SetCompare(ptr->Next() ? ptr->EventTimeTicks : HAL_COMPLETION_IDLE_VALUE); + } - GLOBAL_UNLOCK(); + GLOBAL_UNLOCK(); } //--// void HAL_COMPLETION::EnqueueTicks(uint64_t eventTimeTicks) { - NATIVE_PROFILE_PAL_ASYNC_PROC_CALL(); - ASSERT(eventTimeTicks != 0); + NATIVE_PROFILE_PAL_ASYNC_PROC_CALL(); + ASSERT(eventTimeTicks != 0); - this->EventTimeTicks = eventTimeTicks; + this->EventTimeTicks = eventTimeTicks; #if defined(_DEBUG) - this->Start_RTC_Ticks = HAL_Time_CurrentSysTicks(); + this->Start_RTC_Ticks = HAL_Time_CurrentSysTicks(); #endif - GLOBAL_LOCK(); + GLOBAL_LOCK(); - HAL_COMPLETION* ptr = (HAL_COMPLETION*)g_HAL_Completion_List.FirstNode(); - HAL_COMPLETION* ptrNext; + HAL_COMPLETION *ptr = (HAL_COMPLETION *)g_HAL_Completion_List.FirstNode(); + HAL_COMPLETION *ptrNext; - // If not empty list the find position in Completion list based on time - // If empty just add at head. - if (!g_HAL_Completion_List.IsEmpty()) - { - do - { - ptrNext = (HAL_COMPLETION *)ptr->Next(); + // If not empty list the find position in Completion list based on time + // If empty just add at head. + if (!g_HAL_Completion_List.IsEmpty()) + { + do + { + ptrNext = (HAL_COMPLETION *)ptr->Next(); - if (eventTimeTicks < ptr->EventTimeTicks) - { - break; - } + if (eventTimeTicks < ptr->EventTimeTicks) + { + break; + } - ptr = ptrNext; - } while (ptr); - } + ptr = ptrNext; + } while (ptr); + } - g_HAL_Completion_List.InsertBeforeNode(ptr, this); + g_HAL_Completion_List.InsertBeforeNode(ptr, this); - if (this == g_HAL_Completion_List.FirstNode()) - { - Time_SetCompare(eventTimeTicks); - } + if (this == g_HAL_Completion_List.FirstNode()) + { + Time_SetCompare(eventTimeTicks); + } - GLOBAL_UNLOCK(); + GLOBAL_UNLOCK(); +} + +void HAL_COMPLETION::EnqueueDelta64(uint64_t uSecFromNow) +{ + NATIVE_PROFILE_PAL_ASYNC_PROC_CALL(); + + // grab time first to be closest to now as possible from when this function was called + uint64_t now = HAL_Time_CurrentSysTicks(); + uint64_t eventTimeTicks = CPU_MillisecondsToTicks(uSecFromNow * 1000); + + EnqueueTicks(now + eventTimeTicks); +} + +void HAL_COMPLETION::EnqueueDelta(uint32_t uSecFromNow) +{ + NATIVE_PROFILE_PAL_ASYNC_PROC_CALL(); + + EnqueueDelta64((uint64_t)uSecFromNow); } //--// void HAL_COMPLETION::Abort() { - NATIVE_PROFILE_PAL_ASYNC_PROC_CALL(); + NATIVE_PROFILE_PAL_ASYNC_PROC_CALL(); - GLOBAL_LOCK(); + GLOBAL_LOCK(); - HAL_COMPLETION* firstNode = (HAL_COMPLETION*)g_HAL_Completion_List.FirstNode(); + HAL_COMPLETION *firstNode = (HAL_COMPLETION *)g_HAL_Completion_List.FirstNode(); - this->Unlink(); + this->Unlink(); #if defined(_DEBUG) - this->Start_RTC_Ticks = 0; + this->Start_RTC_Ticks = 0; #endif - if (firstNode == this) - { - uint64_t nextTicks; - - if (g_HAL_Completion_List.IsEmpty()) - { - // - // In case there's no other request to serve, set the next interrupt to be 356 years since last powerup (@25kHz). - // - nextTicks = HAL_COMPLETION_IDLE_VALUE; - } - else - { - firstNode = (HAL_COMPLETION*)g_HAL_Completion_List.FirstNode(); - - nextTicks = firstNode->EventTimeTicks; - } - - Time_SetCompare(nextTicks); - } - - GLOBAL_UNLOCK(); + if (firstNode == this) + { + uint64_t nextTicks; + + if (g_HAL_Completion_List.IsEmpty()) + { + // + // In case there's no other request to serve, set the next interrupt to be 356 years since last powerup + // (@25kHz). + // + nextTicks = HAL_COMPLETION_IDLE_VALUE; + } + else + { + firstNode = (HAL_COMPLETION *)g_HAL_Completion_List.FirstNode(); + + nextTicks = firstNode->EventTimeTicks; + } + + Time_SetCompare(nextTicks); + } + + GLOBAL_UNLOCK(); } //--// - // // WaitForInterrupts for expireTimeInTicks time // @@ -172,68 +190,67 @@ void HAL_COMPLETION::Abort() // void HAL_COMPLETION::WaitForInterrupts(uint64_t expireTimeInTicks, uint32_t sleepLevel, uint64_t wakeEvents) { - NATIVE_PROFILE_PAL_ASYNC_PROC_CALL(); - - const int setCompare = 1; - const int resetCompare = 2; - const int nilCompare = 4; - - HAL_COMPLETION* ptr = (HAL_COMPLETION*)g_HAL_Completion_List.FirstNode(); - int state; - - // Any Completion events been Queued ? - if (ptr->Next() == NULL) - { - // No - state = setCompare | nilCompare; - } - // Is Queued event later than passed expire timeout - else if (ptr->EventTimeTicks > expireTimeInTicks) - { - // Yes - state = setCompare | resetCompare; - } - else - { - state = 0; - } - - if (state & setCompare) - { - // Set timer for expireTimeInTicks time - Time_SetCompare(expireTimeInTicks); - } - - // Wait for next interrupt ( timer etc) - CPU_Sleep((SLEEP_LEVEL_type)sleepLevel, wakeEvents); - - if (state & (resetCompare | nilCompare)) - { - // let's get the first node again - // it could have changed since CPU_Sleep re-enabled interrupts - ptr = (HAL_COMPLETION*)g_HAL_Completion_List.FirstNode(); - Time_SetCompare((state & resetCompare) ? ptr->EventTimeTicks : HAL_COMPLETION_IDLE_VALUE); - } + NATIVE_PROFILE_PAL_ASYNC_PROC_CALL(); + + const int setCompare = 1; + const int resetCompare = 2; + const int nilCompare = 4; + + HAL_COMPLETION *ptr = (HAL_COMPLETION *)g_HAL_Completion_List.FirstNode(); + int state; + + // Any Completion events been Queued ? + if (ptr->Next() == NULL) + { + // No + state = setCompare | nilCompare; + } + // Is Queued event later than passed expire timeout + else if (ptr->EventTimeTicks > expireTimeInTicks) + { + // Yes + state = setCompare | resetCompare; + } + else + { + state = 0; + } + + if (state & setCompare) + { + // Set timer for expireTimeInTicks time + Time_SetCompare(expireTimeInTicks); + } + + // Wait for next interrupt ( timer etc) + CPU_Sleep((SLEEP_LEVEL_type)sleepLevel, wakeEvents); + + if (state & (resetCompare | nilCompare)) + { + // let's get the first node again + // it could have changed since CPU_Sleep re-enabled interrupts + ptr = (HAL_COMPLETION *)g_HAL_Completion_List.FirstNode(); + Time_SetCompare((state & resetCompare) ? ptr->EventTimeTicks : HAL_COMPLETION_IDLE_VALUE); + } } void HAL_COMPLETION::Uninitialize() { - NATIVE_PROFILE_PAL_ASYNC_PROC_CALL(); - - HAL_COMPLETION* ptr; + NATIVE_PROFILE_PAL_ASYNC_PROC_CALL(); - GLOBAL_LOCK(); + HAL_COMPLETION *ptr; - while (TRUE) - { - ptr = (HAL_COMPLETION*)g_HAL_Completion_List.ExtractFirstNode(); + GLOBAL_LOCK(); - if (!ptr) - { - break; - } + while (TRUE) + { + ptr = (HAL_COMPLETION *)g_HAL_Completion_List.ExtractFirstNode(); - } + if (!ptr) + { + break; + } + } - GLOBAL_UNLOCK(); + GLOBAL_UNLOCK(); } diff --git a/src/PAL/COM/sockets/ssl/mbedTLS/mbedtls.h b/src/PAL/COM/sockets/ssl/MbedTLS/mbedtls.h similarity index 100% rename from src/PAL/COM/sockets/ssl/mbedTLS/mbedtls.h rename to src/PAL/COM/sockets/ssl/MbedTLS/mbedtls.h diff --git a/src/PAL/COM/sockets/ssl/mbedTLS/nf_mbedtls_config.h b/src/PAL/COM/sockets/ssl/MbedTLS/nf_mbedtls_config.h similarity index 96% rename from src/PAL/COM/sockets/ssl/mbedTLS/nf_mbedtls_config.h rename to src/PAL/COM/sockets/ssl/MbedTLS/nf_mbedtls_config.h index de2f73340f..df416c3c0b 100644 --- a/src/PAL/COM/sockets/ssl/mbedTLS/nf_mbedtls_config.h +++ b/src/PAL/COM/sockets/ssl/MbedTLS/nf_mbedtls_config.h @@ -12,7 +12,7 @@ #include #include -// need to declare this as external to be picked up by mbed TLS platform_time +// need to declare this as external to be picked up by Mbed TLS platform_time #ifdef __cplusplus extern "C" { @@ -36,7 +36,7 @@ extern "C" // need to define this as the alternative to standard time function #define MBEDTLS_PLATFORM_TIME_MACRO nf_get_unix_epoch -/* mbed TLS feature support */ +/* Mbed TLS feature support */ #define MBEDTLS_CIPHER_MODE_CBC #define MBEDTLS_CIPHER_MODE_CFB #define MBEDTLS_CIPHER_MODE_CTR @@ -102,7 +102,7 @@ extern "C" #define MBEDTLS_X509_RSASSA_PSS_SUPPORT #define MBEDTLS_CMAC_C -/* mbed TLS modules */ +/* Mbed TLS modules */ #define MBEDTLS_AESNI_C #define MBEDTLS_AES_C #define MBEDTLS_ASN1_PARSE_C @@ -175,7 +175,7 @@ extern "C" //////////////////////////////////////////////////////////////////////////// // This define depends on the platform having a hardware random generator. -// Requires that a function mbedtls_hardware_poll() exits as explained in mbed TLS documentation. +// Requires that a function mbedtls_hardware_poll() exits as explained in Mbed TLS documentation. // Because it's target dependent, the define PLATFORM_HAS_RNG belongs in the target_common header #if (PLATFORM_HAS_RNG == TRUE) #define MBEDTLS_ENTROPY_HARDWARE_ALT diff --git a/src/PAL/COM/sockets/ssl/mbedTLS/ssl_accept_internal.cpp b/src/PAL/COM/sockets/ssl/MbedTLS/ssl_accept_internal.cpp similarity index 53% rename from src/PAL/COM/sockets/ssl/mbedTLS/ssl_accept_internal.cpp rename to src/PAL/COM/sockets/ssl/MbedTLS/ssl_accept_internal.cpp index 946db5a6b2..44d00c44e3 100644 --- a/src/PAL/COM/sockets/ssl/mbedTLS/ssl_accept_internal.cpp +++ b/src/PAL/COM/sockets/ssl/MbedTLS/ssl_accept_internal.cpp @@ -6,26 +6,24 @@ #include #include "mbedtls.h" -int ssl_accept_internal( - int sd, - int contextHandle ) +int ssl_accept_internal(int sd, int contextHandle) { - mbedTLS_NFContext* context; + mbedTLS_NFContext *context; mbedtls_ssl_context *ssl; int nonblock = 0; int ret = SOCK_SOCKET_ERROR; // Check contextHandle range - if((contextHandle >= (int)ARRAYSIZE(g_SSL_Driver.ContextArray)) || (contextHandle < 0)) + if ((contextHandle >= (int)ARRAYSIZE(g_SSL_Driver.ContextArray)) || (contextHandle < 0)) { goto error; } - context = (mbedTLS_NFContext*)g_SSL_Driver.ContextArray[contextHandle].Context; + context = (mbedTLS_NFContext *)g_SSL_Driver.ContextArray[contextHandle].Context; ssl = context->ssl; // sanity check - if(ssl == NULL) + if (ssl == NULL) { return SOCK_SOCKET_ERROR; } @@ -34,31 +32,31 @@ int ssl_accept_internal( context->server_fd->fd = sd; // setup internal SSL context and calls to transport layer send, receive and receive with timeout - mbedtls_ssl_set_bio( context->ssl, context->server_fd, mbedtls_net_send, mbedtls_net_recv, mbedtls_net_recv_timeout ); + mbedtls_ssl_set_bio(context->ssl, context->server_fd, mbedtls_net_send, mbedtls_net_recv, mbedtls_net_recv_timeout); // Set non blocking socket SOCK_ioctl(sd, SOCK_FIONBIO, &nonblock); - // connection is set up now proceed to SSL handshake + // connection is set up now proceed to SSL handshake // perform SSL handshake - while( ( ret = mbedtls_ssl_handshake( context->ssl ) ) != 0 ) + while ((ret = mbedtls_ssl_handshake(context->ssl)) != 0) { - if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE ) + if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { // SSL handshake failed - //mbedtls_printf( " failed\n ! mbedtls_ssl_handshake returned -0x%x\n\n", -ret ); + // mbedtls_printf( " failed\n ! mbedtls_ssl_handshake returned -0x%x\n\n", -ret ); goto error; } } - + nonblock = 1; SOCK_ioctl(sd, SOCK_FIONBIO, &nonblock); // Save SSL context against socket - SOCKET_DRIVER.SetSocketSslData(sd, (void*)context); + SOCKET_DRIVER.SetSocketSslData(sd, (void *)context); error: - + return ret; } diff --git a/src/PAL/COM/sockets/ssl/mbedTLS/ssl_add_cert_auth_internal.cpp b/src/PAL/COM/sockets/ssl/MbedTLS/ssl_add_cert_auth_internal.cpp similarity index 100% rename from src/PAL/COM/sockets/ssl/mbedTLS/ssl_add_cert_auth_internal.cpp rename to src/PAL/COM/sockets/ssl/MbedTLS/ssl_add_cert_auth_internal.cpp diff --git a/src/PAL/COM/sockets/ssl/mbedTLS/ssl_available_internal.cpp b/src/PAL/COM/sockets/ssl/MbedTLS/ssl_available_internal.cpp similarity index 100% rename from src/PAL/COM/sockets/ssl/mbedTLS/ssl_available_internal.cpp rename to src/PAL/COM/sockets/ssl/MbedTLS/ssl_available_internal.cpp diff --git a/src/PAL/COM/sockets/ssl/mbedTLS/ssl_close_socket_internal.cpp b/src/PAL/COM/sockets/ssl/MbedTLS/ssl_close_socket_internal.cpp similarity index 71% rename from src/PAL/COM/sockets/ssl/mbedTLS/ssl_close_socket_internal.cpp rename to src/PAL/COM/sockets/ssl/MbedTLS/ssl_close_socket_internal.cpp index b7dd71aa3e..e69ced804b 100644 --- a/src/PAL/COM/sockets/ssl/mbedTLS/ssl_close_socket_internal.cpp +++ b/src/PAL/COM/sockets/ssl/MbedTLS/ssl_close_socket_internal.cpp @@ -6,12 +6,12 @@ #include #include "mbedtls.h" -int ssl_close_socket_internal( int sd ) +int ssl_close_socket_internal(int sd) { - mbedTLS_NFContext* context= (mbedTLS_NFContext*)SOCKET_DRIVER.GetSocketSslData(sd); + mbedTLS_NFContext *context = (mbedTLS_NFContext *)SOCKET_DRIVER.GetSocketSslData(sd); // sanity check - if(context != NULL) + if (context != NULL) { mbedtls_ssl_context *ssl = context->ssl; @@ -21,7 +21,7 @@ int ssl_close_socket_internal( int sd ) SOCKET_DRIVER.SetSocketSslData(sd, NULL); } - SOCK_close( sd ); + SOCK_close(sd); return 0; } diff --git a/src/PAL/COM/sockets/ssl/mbedTLS/ssl_connect_internal.cpp b/src/PAL/COM/sockets/ssl/MbedTLS/ssl_connect_internal.cpp similarity index 55% rename from src/PAL/COM/sockets/ssl/mbedTLS/ssl_connect_internal.cpp rename to src/PAL/COM/sockets/ssl/MbedTLS/ssl_connect_internal.cpp index 90914acf3e..8edb996c23 100644 --- a/src/PAL/COM/sockets/ssl/mbedTLS/ssl_connect_internal.cpp +++ b/src/PAL/COM/sockets/ssl/MbedTLS/ssl_connect_internal.cpp @@ -8,26 +8,23 @@ #include #include "mbedtls.h" -int ssl_connect_internal( - int sd, - const char* szTargetHost, - int contextHandle) +int ssl_connect_internal(int sd, const char *szTargetHost, int contextHandle) { - mbedTLS_NFContext* context; + mbedTLS_NFContext *context; int nonblock = 0; int ret = SOCK_SOCKET_ERROR; // Check contextHandle range - if((contextHandle >= (int)ARRAYSIZE(g_SSL_Driver.ContextArray)) || (contextHandle < 0)) + if ((contextHandle >= (int)ARRAYSIZE(g_SSL_Driver.ContextArray)) || (contextHandle < 0)) { goto error; } - - // Retrieve SSL struct from g_SSL_Driver + + // Retrieve SSL struct from g_SSL_Driver // sd should already have been created // Now do the SSL negotiation - context = (mbedTLS_NFContext*)g_SSL_Driver.ContextArray[contextHandle].Context; + context = (mbedTLS_NFContext *)g_SSL_Driver.ContextArray[contextHandle].Context; if (context == NULL) { return false; @@ -36,9 +33,9 @@ int ssl_connect_internal( // set socket in network context context->server_fd->fd = sd; - if(szTargetHost != NULL && szTargetHost[0] != 0) + if (szTargetHost != NULL && szTargetHost[0] != 0) { - if( (ret = mbedtls_ssl_set_hostname( context->ssl, szTargetHost )) != 0 ) + if ((ret = mbedtls_ssl_set_hostname(context->ssl, szTargetHost)) != 0) { // hostname_failed goto error; @@ -46,17 +43,17 @@ int ssl_connect_internal( } // setup internal SSL context and calls to transport layer send, receive and receive with timeout - mbedtls_ssl_set_bio( context->ssl, context->server_fd, mbedtls_net_send, mbedtls_net_recv, mbedtls_net_recv_timeout ); + mbedtls_ssl_set_bio(context->ssl, context->server_fd, mbedtls_net_send, mbedtls_net_recv, mbedtls_net_recv_timeout); SOCK_ioctl(sd, SOCK_FIONBIO, &nonblock); // perform SSL handshake - while( ( ret = mbedtls_ssl_handshake( context->ssl ) ) != 0 ) + while ((ret = mbedtls_ssl_handshake(context->ssl)) != 0) { - if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE ) + if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { // SSL handshake failed - //mbedtls_printf( " failed\n ! mbedtls_ssl_handshake returned -0x%x\n\n", -ret ); + // mbedtls_printf( " failed\n ! mbedtls_ssl_handshake returned -0x%x\n\n", -ret ); goto error; } } @@ -65,7 +62,7 @@ int ssl_connect_internal( SOCK_ioctl(sd, SOCK_FIONBIO, &nonblock); // store SSL context in sockets driver - SOCKET_DRIVER.SetSocketSslData(sd, (void*)context); + SOCKET_DRIVER.SetSocketSslData(sd, (void *)context); error: return ret; diff --git a/src/PAL/COM/sockets/ssl/mbedTLS/ssl_decode_private_key_internal.cpp b/src/PAL/COM/sockets/ssl/MbedTLS/ssl_decode_private_key_internal.cpp similarity index 70% rename from src/PAL/COM/sockets/ssl/mbedTLS/ssl_decode_private_key_internal.cpp rename to src/PAL/COM/sockets/ssl/MbedTLS/ssl_decode_private_key_internal.cpp index c6402456bc..3625e2dfd7 100644 --- a/src/PAL/COM/sockets/ssl/mbedTLS/ssl_decode_private_key_internal.cpp +++ b/src/PAL/COM/sockets/ssl/MbedTLS/ssl_decode_private_key_internal.cpp @@ -6,35 +6,29 @@ #include "mbedtls.h" -extern void SSL_GetCertDateTime_internal(DATE_TIME_INFO * dt, mbedtls_x509_time * mt ); +extern void SSL_GetCertDateTime_internal(DATE_TIME_INFO *dt, mbedtls_x509_time *mt); int ssl_decode_private_key_internal( - const unsigned char *key, - size_t keyLength, - const unsigned char *password, + const unsigned char *key, + size_t keyLength, + const unsigned char *password, size_t passwordLength) { mbedtls_pk_context pkey; - + int retCode; - mbedtls_pk_init( &pkey ); + mbedtls_pk_init(&pkey); ///////////////////////////////////////////////////////////////////////////////////////////////// // developer notes: // // this call parses certificates in both string and binary formats // // when the formart is a string it has to include the terminator otherwise the parse will fail // ///////////////////////////////////////////////////////////////////////////////////////////////// - retCode = mbedtls_pk_parse_key( - &pkey, - key, - keyLength, - password, - passwordLength); - + retCode = mbedtls_pk_parse_key(&pkey, key, keyLength, password, passwordLength); // need to free this here - mbedtls_pk_free( &pkey ); + mbedtls_pk_free(&pkey); return retCode; } diff --git a/src/PAL/COM/sockets/ssl/mbedTLS/ssl_exit_context_internal.cpp b/src/PAL/COM/sockets/ssl/MbedTLS/ssl_exit_context_internal.cpp similarity index 67% rename from src/PAL/COM/sockets/ssl/mbedTLS/ssl_exit_context_internal.cpp rename to src/PAL/COM/sockets/ssl/MbedTLS/ssl_exit_context_internal.cpp index b16a801571..c1735d89cf 100644 --- a/src/PAL/COM/sockets/ssl/mbedTLS/ssl_exit_context_internal.cpp +++ b/src/PAL/COM/sockets/ssl/MbedTLS/ssl_exit_context_internal.cpp @@ -5,31 +5,31 @@ // See LICENSE file in the project root for full license information. // -#include +#include #include "mbedtls.h" - -bool ssl_exit_context_internal( int contextHandle ) +bool ssl_exit_context_internal(int contextHandle) { - mbedTLS_NFContext* context; + mbedTLS_NFContext *context; // Check contextHandle range - if((contextHandle >= (int)ARRAYSIZE(g_SSL_Driver.ContextArray)) || (contextHandle < 0) || (g_SSL_Driver.ContextArray[contextHandle].Context == NULL)) + if ((contextHandle >= (int)ARRAYSIZE(g_SSL_Driver.ContextArray)) || (contextHandle < 0) || + (g_SSL_Driver.ContextArray[contextHandle].Context == NULL)) { return false; } - context = (mbedTLS_NFContext*)g_SSL_Driver.ContextArray[contextHandle].Context; + context = (mbedTLS_NFContext *)g_SSL_Driver.ContextArray[contextHandle].Context; if (context == NULL) { return false; } - + mbedtls_pk_free(context->pk); mbedtls_net_free(context->server_fd); - mbedtls_ctr_drbg_free( context->ctr_drbg ); - mbedtls_entropy_free( context->entropy ); - mbedtls_ssl_config_free( context->conf ); + mbedtls_ctr_drbg_free(context->ctr_drbg); + mbedtls_entropy_free(context->entropy); + mbedtls_ssl_config_free(context->conf); mbedtls_x509_crt_free(context->x509_crt); mbedtls_ssl_free(context->ssl); @@ -37,7 +37,7 @@ bool ssl_exit_context_internal( int contextHandle ) memset(context->ssl, 0, sizeof(mbedtls_ssl_context)); // free memory - if(context->pk != NULL) + if (context->pk != NULL) { platform_free(context->pk); } @@ -51,7 +51,7 @@ bool ssl_exit_context_internal( int contextHandle ) memset(&g_SSL_Driver.ContextArray[contextHandle], 0, sizeof(g_SSL_Driver.ContextArray[contextHandle])); - g_SSL_Driver.ContextCount --; + g_SSL_Driver.ContextCount--; return true; } diff --git a/src/PAL/COM/sockets/ssl/MbedTLS/ssl_generic.cpp b/src/PAL/COM/sockets/ssl/MbedTLS/ssl_generic.cpp new file mode 100644 index 0000000000..e050fd892d --- /dev/null +++ b/src/PAL/COM/sockets/ssl/MbedTLS/ssl_generic.cpp @@ -0,0 +1,212 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Portions Copyright (c) Microsoft Corporation. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +#include "mbedtls.h" + +#include "lwip/sockets.h" + +// this one lives in lwIPSocket.cpp +extern int errno; + +int sslRecv(void *ctx, unsigned char *buf, size_t len) +{ + (void)buf; + (void)len; + (void)ctx; + + // int sd = (int)ctx; + + // int ret = socket->recv(buf, len); + + // if (ret == NSAPI_ERROR_WOULD_BLOCK) + // ret = MBEDTLS_ERR_SSL_WANT_READ; + // else if (ret < 0) + // mbedtls_printf("socket.recv() returned %d\n", ret); + + // return ret; + return 0; +} + +// MbedTLS requires a function with this signature, so we are wrapping the call to our debug_printf here +void nf_debug(void *ctx, int level, const char *file, int line, const char *str) +{ + (void)level; + (void)ctx; + (void)file; + (void)line; + + // the following line outputs the source code file name and line number + // for verbose output SWO is overhelmed and output fails at some point + // debug_printf( "%s:%04d: %s", file, line, str ); + + // this is a lightheight version with just the debug messages + debug_printf("%s", str); +} + +int net_would_block(const mbedtls_net_context *ctx) +{ + /* + * Never return 'WOULD BLOCK' on a non-blocking socket + */ + int val = 0; + + if ((fcntl(ctx->fd, F_GETFL, val) & O_NONBLOCK) != O_NONBLOCK) + return (0); + + switch (errno) + { +#if defined EAGAIN + case EAGAIN: +#endif +#if defined EWOULDBLOCK && EWOULDBLOCK != EAGAIN + case EWOULDBLOCK: +#endif + return (1); + } + + return (0); +} + +int mbedtls_net_recv(void *ctx, unsigned char *buf, size_t len) +{ + int32_t ret; + int32_t fd = ((mbedtls_net_context *)ctx)->fd; + + if (fd < 0) + { + return MBEDTLS_ERR_NET_INVALID_CONTEXT; + } + + ret = (int32_t)read(fd, buf, len); + + if (ret < 0) + { + if (net_would_block((mbedtls_net_context *)ctx) != 0) + { + return MBEDTLS_ERR_SSL_WANT_READ; + } + + if (errno == EPIPE || errno == ECONNRESET) + { + return MBEDTLS_ERR_NET_CONN_RESET; + } + + if (errno == EINTR) + { + return MBEDTLS_ERR_SSL_WANT_READ; + } + + return MBEDTLS_ERR_NET_RECV_FAILED; + } + + return ret; +} + +int mbedtls_net_send(void *ctx, const unsigned char *buf, size_t len) +{ + int32_t ret; + int fd = ((mbedtls_net_context *)ctx)->fd; + + if (fd < 0) + { + return MBEDTLS_ERR_NET_INVALID_CONTEXT; + } + + ret = (int32_t)write(fd, buf, len); + + if (ret < 0) + { + if (net_would_block((mbedtls_net_context *)ctx) != 0) + { + return MBEDTLS_ERR_SSL_WANT_WRITE; + } + + if (errno == EPIPE || errno == ECONNRESET) + { + return MBEDTLS_ERR_NET_CONN_RESET; + } + + if (errno == EINTR) + { + return MBEDTLS_ERR_SSL_WANT_WRITE; + } + + return MBEDTLS_ERR_NET_SEND_FAILED; + } + + return ret; +} + +int mbedtls_net_recv_timeout(void *ctx, unsigned char *buf, size_t len, uint32_t timeout) +{ + int ret; + struct timeval tv; + fd_set read_fds; + int fd = ((mbedtls_net_context *)ctx)->fd; + + if (fd < 0) + return (MBEDTLS_ERR_NET_INVALID_CONTEXT); + + FD_ZERO(&read_fds); + FD_SET(fd, &read_fds); + + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout % 1000) * 1000; + + ret = select(fd + 1, &read_fds, NULL, NULL, timeout == 0 ? NULL : &tv); + + /* Zero fds ready means we timed out */ + if (ret == 0) + return (MBEDTLS_ERR_SSL_TIMEOUT); + + if (ret < 0) + { +#if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(EFIX64) && !defined(EFI32) + if (WSAGetLastError() == WSAEINTR) + return (MBEDTLS_ERR_SSL_WANT_READ); +#else + if (errno == EINTR) + return (MBEDTLS_ERR_SSL_WANT_READ); +#endif + + return (MBEDTLS_ERR_NET_RECV_FAILED); + } + + /* This call will not block */ + return (mbedtls_net_recv(ctx, buf, len)); +} + +// Gracefully closes the connection +void mbedtls_net_free(mbedtls_net_context *ctx) +{ + if (ctx->fd == -1) + return; + + shutdown(ctx->fd, 2); + close(ctx->fd); + + ctx->fd = -1; +} + +// get Unix Epoch time from HAL SystemTime +time_t nf_get_unix_epoch() +{ + struct tm time; + SYSTEMTIME systemTime; + + // get HAL time in SYSTEMTIME format + HAL_Time_ToSystemTime(HAL_Time_CurrentDateTime(false), &systemTime); + + // fill in the tm struct + time.tm_sec = systemTime.wSecond; + time.tm_min = systemTime.wMinute; + time.tm_hour = systemTime.wHour; + time.tm_mday = systemTime.wDay; + time.tm_mon = systemTime.wMonth - 1; + time.tm_year = systemTime.wYear - 1900; + + return mktime(&time); +} diff --git a/src/PAL/COM/sockets/ssl/mbedTLS/ssl_generic_init_internal.cpp b/src/PAL/COM/sockets/ssl/MbedTLS/ssl_generic_init_internal.cpp similarity index 93% rename from src/PAL/COM/sockets/ssl/mbedTLS/ssl_generic_init_internal.cpp rename to src/PAL/COM/sockets/ssl/MbedTLS/ssl_generic_init_internal.cpp index dad1c6d662..5a125ac356 100644 --- a/src/PAL/COM/sockets/ssl/mbedTLS/ssl_generic_init_internal.cpp +++ b/src/PAL/COM/sockets/ssl/MbedTLS/ssl_generic_init_internal.cpp @@ -8,6 +8,7 @@ #include #include "mbedtls.h" #include "mbedtls/debug.h" +#include bool ssl_generic_init_internal( int sslMode, @@ -22,8 +23,6 @@ bool ssl_generic_init_internal( bool useDeviceCertificate, bool isServer) { - (void)sslMode; - int minVersion = MBEDTLS_SSL_MINOR_VERSION_3; int maxVersion = MBEDTLS_SSL_MINOR_VERSION_1; int sslContexIndex = -1; @@ -50,7 +49,7 @@ bool ssl_generic_init_internal( if (sslContexIndex == -1) return FALSE; - // create and init mbedTLS nanoFramework context + // create and init MbedTLS nanoFramework context // this needs to be freed in ssl_exit_context_internal context = (mbedTLS_NFContext *)platform_malloc(sizeof(mbedTLS_NFContext)); if (context == NULL) @@ -58,6 +57,8 @@ bool ssl_generic_init_internal( goto error; } + memset(context, 0, sizeof(mbedTLS_NFContext)); + // allocate memory for net context context->server_fd = (mbedtls_net_context *)platform_malloc(sizeof(mbedtls_net_context)); if (context->server_fd == NULL) @@ -65,6 +66,8 @@ bool ssl_generic_init_internal( goto error; } + memset(context->server_fd, 0, sizeof(mbedtls_net_context)); + if (isServer) { endpoint = MBEDTLS_SSL_IS_SERVER; @@ -74,6 +77,16 @@ bool ssl_generic_init_internal( endpoint = MBEDTLS_SSL_IS_CLIENT; } + // create and init private key context + // this needs to be freed in ssl_exit_context_internal + context->pk = (mbedtls_pk_context *)platform_malloc(sizeof(mbedtls_pk_context)); + if (context->pk == NULL) + { + goto error; + } + + mbedtls_pk_init(context->pk); + // create and init CTR_DRBG // this needs to be freed in ssl_exit_context_internal context->ctr_drbg = (mbedtls_ctr_drbg_context *)platform_malloc(sizeof(mbedtls_ctr_drbg_context)); @@ -220,16 +233,6 @@ bool ssl_generic_init_internal( // parse "own" certificate if passed if (certificate != NULL && certLength > 0) { - // create and init private key context - // this needs to be freed in ssl_exit_context_internal - context->pk = (mbedtls_pk_context *)platform_malloc(sizeof(mbedtls_pk_context)); - if (context->pk == NULL) - { - goto error; - } - - mbedtls_pk_init(context->pk); - // is there a private key? if (privateKey != NULL && privateKeyLength > 0) { @@ -276,13 +279,15 @@ bool ssl_generic_init_internal( else { // no PK, need to set it to NULL + mbedtls_pk_free(context->pk); + platform_free(context->pk); context->pk = NULL; } mbedtls_ssl_conf_ca_chain(context->conf, context->x509_crt, NULL); // set certificate verification - // the current options provided by mbed TLS are only verify or don't verify + // the current options provided by Mbed TLS are only verify or don't verify if ((SslVerification)sslVerify == SslVerification_CertificateRequired) { authMode = MBEDTLS_SSL_VERIFY_REQUIRED; @@ -313,8 +318,17 @@ bool ssl_generic_init_internal( return true; error: - mbedtls_pk_free(context->pk); - mbedtls_net_free(context->server_fd); + + if (context->pk) + { + mbedtls_pk_free(context->pk); + } + + if (context->server_fd) + { + mbedtls_net_free(context->server_fd); + } + mbedtls_ctr_drbg_free(context->ctr_drbg); mbedtls_entropy_free(context->entropy); mbedtls_x509_crt_free(context->x509_crt); @@ -362,7 +376,7 @@ bool ssl_generic_init_internal( mbedtls_x509_crt_free(ownCertificate); platform_free(ownCertificate); } - if (context->pk) + if (context) { platform_free(context); } diff --git a/src/PAL/COM/sockets/ssl/mbedTLS/ssl_initialize_internal.cpp b/src/PAL/COM/sockets/ssl/MbedTLS/ssl_initialize_internal.cpp similarity index 95% rename from src/PAL/COM/sockets/ssl/mbedTLS/ssl_initialize_internal.cpp rename to src/PAL/COM/sockets/ssl/MbedTLS/ssl_initialize_internal.cpp index 72cdb7070b..53a116ed1e 100644 --- a/src/PAL/COM/sockets/ssl/mbedTLS/ssl_initialize_internal.cpp +++ b/src/PAL/COM/sockets/ssl/MbedTLS/ssl_initialize_internal.cpp @@ -5,7 +5,7 @@ // See LICENSE file in the project root for full license information. // -#include +#include #include "mbedtls.h" bool ssl_initialize_internal() diff --git a/src/PAL/COM/sockets/ssl/mbedTLS/ssl_parse_certificate_internal.cpp b/src/PAL/COM/sockets/ssl/MbedTLS/ssl_parse_certificate_internal.cpp similarity index 100% rename from src/PAL/COM/sockets/ssl/mbedTLS/ssl_parse_certificate_internal.cpp rename to src/PAL/COM/sockets/ssl/MbedTLS/ssl_parse_certificate_internal.cpp diff --git a/src/PAL/COM/sockets/ssl/mbedTLS/ssl_read_internal.cpp b/src/PAL/COM/sockets/ssl/MbedTLS/ssl_read_internal.cpp similarity index 65% rename from src/PAL/COM/sockets/ssl/mbedTLS/ssl_read_internal.cpp rename to src/PAL/COM/sockets/ssl/MbedTLS/ssl_read_internal.cpp index bc6ccca87b..8c62182537 100644 --- a/src/PAL/COM/sockets/ssl/mbedTLS/ssl_read_internal.cpp +++ b/src/PAL/COM/sockets/ssl/MbedTLS/ssl_read_internal.cpp @@ -6,22 +6,19 @@ #include #include "mbedtls.h" -int ssl_read_internal( - int sd, - char* data, - size_t size ) +int ssl_read_internal(int sd, char *data, size_t size) { - mbedTLS_NFContext* context= (mbedTLS_NFContext*)SOCKET_DRIVER.GetSocketSslData(sd); + mbedTLS_NFContext *context = (mbedTLS_NFContext *)SOCKET_DRIVER.GetSocketSslData(sd); mbedtls_ssl_context *ssl = context->ssl; // sanity check - if(ssl == NULL) + if (ssl == NULL) { return SOCK_SOCKET_ERROR; } - + int ret = mbedtls_ssl_read(ssl, (unsigned char *)(data), size); - if ( ret < 0 ) + if (ret < 0) { return 0; } diff --git a/src/PAL/COM/sockets/ssl/mbedTLS/ssl_uninitialize_internal.cpp b/src/PAL/COM/sockets/ssl/MbedTLS/ssl_uninitialize_internal.cpp similarity index 70% rename from src/PAL/COM/sockets/ssl/mbedTLS/ssl_uninitialize_internal.cpp rename to src/PAL/COM/sockets/ssl/MbedTLS/ssl_uninitialize_internal.cpp index 36657f5ae2..e13213b5ef 100644 --- a/src/PAL/COM/sockets/ssl/mbedTLS/ssl_uninitialize_internal.cpp +++ b/src/PAL/COM/sockets/ssl/MbedTLS/ssl_uninitialize_internal.cpp @@ -4,7 +4,7 @@ // See LICENSE file in the project root for full license information. // -#include +#include #include "mbedtls.h" // TODO if and when implementing store certificate @@ -13,15 +13,15 @@ bool ssl_uninitialize_internal() { bool result = true; - - for(uint32_t i = 0; i +#include #include "mbedtls.h" -int ssl_write_internal( - int sd, - const char* data, - size_t req_len) +int ssl_write_internal(int sd, const char *data, size_t req_len) { int ret; - mbedTLS_NFContext* context= (mbedTLS_NFContext*)SOCKET_DRIVER.GetSocketSslData(sd); + mbedTLS_NFContext *context = (mbedTLS_NFContext *)SOCKET_DRIVER.GetSocketSslData(sd); mbedtls_ssl_context *ssl = context->ssl; // sanity check - if(ssl == NULL) + if (ssl == NULL) { return SOCK_SOCKET_ERROR; } // Loop until all data has been sent or error size_t req_offset = 0; - do + do { - ret = mbedtls_ssl_write( ssl, (const unsigned char *)(data + req_offset), req_len - req_offset); + ret = mbedtls_ssl_write(ssl, (const unsigned char *)(data + req_offset), req_len - req_offset); if (ret > 0) { req_offset += static_cast(ret); } - } - while( req_offset < req_len && - (ret > 0 || - ret == MBEDTLS_ERR_SSL_WANT_WRITE || - ret == MBEDTLS_ERR_SSL_WANT_READ) ); + } while (req_offset < req_len && + (ret > 0 || ret == MBEDTLS_ERR_SSL_WANT_WRITE || ret == MBEDTLS_ERR_SSL_WANT_READ)); if (ret < 0) { - //mbedtls_printf("mbedtls_ssl_write() returned -0x%04X\n", -ret); + // mbedtls_printf("mbedtls_ssl_write() returned -0x%04X\n", -ret); return 0; - } + } return req_len; } diff --git a/src/PAL/COM/sockets/ssl/mbedTLS/ssl_generic.cpp b/src/PAL/COM/sockets/ssl/mbedTLS/ssl_generic.cpp deleted file mode 100644 index 226a578645..0000000000 --- a/src/PAL/COM/sockets/ssl/mbedTLS/ssl_generic.cpp +++ /dev/null @@ -1,231 +0,0 @@ -// -// Copyright (c) .NET Foundation and Contributors -// Portions Copyright (c) Microsoft Corporation. All rights reserved. -// See LICENSE file in the project root for full license information. -// - -#include "mbedtls.h" - -#include "lwip/sockets.h" - -// this one lives in lwIPSocket.cpp -extern int errno; - -int sslRecv( - void *ctx, - unsigned char *buf, - size_t len) -{ - (void)buf; - (void)len; - (void)ctx; - - //int sd = (int)ctx; - - // int ret = socket->recv(buf, len); - - // if (ret == NSAPI_ERROR_WOULD_BLOCK) - // ret = MBEDTLS_ERR_SSL_WANT_READ; - // else if (ret < 0) - // mbedtls_printf("socket.recv() returned %d\n", ret); - - // return ret; - return 0; -} - -// mbedTLS requires a function with this signature, so we are wrapping the call to our debug_printf here -void nf_debug( - void *ctx, - int level, - const char *file, - int line, - const char *str ) -{ - (void)level; - (void)ctx; - (void)file; - (void)line; - - // the following line outputs the source code file name and line number - // for verbose output SWO is overhelmed and output fails at some point - //debug_printf( "%s:%04d: %s", file, line, str ); - - // this is a lightheight version with just the debug messages - debug_printf( "%s", str ); -} - -int net_would_block( const mbedtls_net_context *ctx ) -{ - /* - * Never return 'WOULD BLOCK' on a non-blocking socket - */ - int val = 0; - - if( ( fcntl( ctx->fd, F_GETFL, val) & O_NONBLOCK ) != O_NONBLOCK ) - return( 0 ); - - switch( errno ) - { - #if defined EAGAIN - case EAGAIN: - #endif - #if defined EWOULDBLOCK && EWOULDBLOCK != EAGAIN - case EWOULDBLOCK: - #endif - return( 1 ); - } - - return( 0 ); -} - -int mbedtls_net_recv( - void *ctx, - unsigned char *buf, - size_t len ) -{ - int32_t ret; - int32_t fd = ((mbedtls_net_context *) ctx)->fd; - - if( fd < 0 ) - { - return MBEDTLS_ERR_NET_INVALID_CONTEXT; - } - - ret = (int32_t) read( fd, buf, len ); - - if( ret < 0 ) - { - if(net_would_block((mbedtls_net_context *)ctx) != 0) - { - return MBEDTLS_ERR_SSL_WANT_READ; - } - - if(errno == EPIPE || errno == ECONNRESET) - { - return MBEDTLS_ERR_NET_CONN_RESET; - } - - if(errno == EINTR) - { - return MBEDTLS_ERR_SSL_WANT_READ; - } - - return MBEDTLS_ERR_NET_RECV_FAILED; - } - - return ret; -} - -int mbedtls_net_send( - void *ctx, - const unsigned char *buf, - size_t len ) -{ - int32_t ret; - int fd = ((mbedtls_net_context *) ctx)->fd; - - if( fd < 0 ) - { - return MBEDTLS_ERR_NET_INVALID_CONTEXT; - } - - ret = (int32_t) write(fd, buf, len); - - if( ret < 0 ) - { - if(net_would_block((mbedtls_net_context *)ctx) != 0) - { - return MBEDTLS_ERR_SSL_WANT_WRITE; - } - - if(errno == EPIPE || errno == ECONNRESET) - { - return MBEDTLS_ERR_NET_CONN_RESET; - } - - if(errno == EINTR) - { - return MBEDTLS_ERR_SSL_WANT_WRITE; - } - - return MBEDTLS_ERR_NET_SEND_FAILED; - } - - return ret; -} - -int mbedtls_net_recv_timeout( - void *ctx, - unsigned char *buf, - size_t len, - uint32_t timeout ) -{ - int ret; - struct timeval tv; - fd_set read_fds; - int fd = ((mbedtls_net_context *) ctx)->fd; - - if( fd < 0 ) - return( MBEDTLS_ERR_NET_INVALID_CONTEXT ); - - FD_ZERO( &read_fds ); - FD_SET( fd, &read_fds ); - - tv.tv_sec = timeout / 1000; - tv.tv_usec = ( timeout % 1000 ) * 1000; - - ret = select( fd + 1, &read_fds, NULL, NULL, timeout == 0 ? NULL : &tv ); - - /* Zero fds ready means we timed out */ - if( ret == 0 ) - return( MBEDTLS_ERR_SSL_TIMEOUT ); - - if( ret < 0 ) - { - #if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ - !defined(EFI32) - if( WSAGetLastError() == WSAEINTR ) - return( MBEDTLS_ERR_SSL_WANT_READ ); - #else - if( errno == EINTR ) - return( MBEDTLS_ERR_SSL_WANT_READ ); - #endif - - return( MBEDTLS_ERR_NET_RECV_FAILED ); - } - - /* This call will not block */ - return( mbedtls_net_recv( ctx, buf, len ) ); -} - -// Gracefully closes the connection -void mbedtls_net_free( mbedtls_net_context *ctx ) -{ - if( ctx->fd == -1 ) - return; - - shutdown( ctx->fd, 2 ); - close( ctx->fd ); - - ctx->fd = -1; -} - -// get Unix Epoch time from HAL SystemTime -time_t nf_get_unix_epoch() -{ - struct tm time; - SYSTEMTIME systemTime; - - // get HAL time in SYSTEMTIME format - HAL_Time_ToSystemTime(HAL_Time_CurrentDateTime(false), &systemTime); - - // fill in the tm struct - time.tm_sec = systemTime.wSecond; - time.tm_min = systemTime.wMinute; - time.tm_hour = systemTime.wHour; - time.tm_mday = systemTime.wDay; - time.tm_mon = systemTime.wMonth - 1; - time.tm_year = systemTime.wYear - 1900; - - return mktime(&time); -} diff --git a/src/PAL/Include/CPU_SPI_decl.h b/src/PAL/Include/CPU_SPI_decl.h index 57e333f3bb..51134fe832 100644 --- a/src/PAL/Include/CPU_SPI_decl.h +++ b/src/PAL/Include/CPU_SPI_decl.h @@ -68,7 +68,7 @@ struct SPI_DEVICE_CONFIGURATION // GPIO pin used for device Chip select, if -1 it means the ChipSelect is handled manually int32_t DeviceChipSelect; // False = LOW active, True = HIGH active - bool ChipSelectActive; + bool ChipSelectActiveState; // SPI mode 0 -> 3 SpiMode Spi_Mode; // SPI bus Configuration (full-duplex is default) @@ -93,6 +93,10 @@ struct SPI_WRITE_READ_SETTINGS int readOffset; // Read offset on half duplex read ( from end of write ) bool Bits16ReadWrite; // True if a 16bit operation SPI_Callback callback; // NUll is operation is Synchronous + // GPIO pin used for device Chip select, if -1 it means the ChipSelect is handled manually + int32_t DeviceChipSelect; + // False = LOW active, True = HIGH active + bool ChipSelectActiveState; }; #define CPU_SPI_ERROR_PARAM -1 diff --git a/src/PAL/Include/nanoPAL_BlockStorage.h b/src/PAL/Include/nanoPAL_BlockStorage.h index d94c266bc4..abf563944d 100644 --- a/src/PAL/Include/nanoPAL_BlockStorage.h +++ b/src/PAL/Include/nanoPAL_BlockStorage.h @@ -179,6 +179,12 @@ typedef enum BlockRegionAttribute BlockRegionAttribute_ProgramWidthIs128bits = 0x0400, // Flash word size 256 bits BlockRegionAttribute_ProgramWidthIs256bits = 0x0800, + // Flash word size 512 bits + BlockRegionAttribute_ProgramWidthIs512bits = 0x1000, + // Flash word size 1024 bits + BlockRegionAttribute_ProgramWidthIs1024bits = 0x2000, + // Flash word size 2048 bits + BlockRegionAttribute_ProgramWidthIs2048bits = 0x4000 } BlockRegionAttribute; diff --git a/src/PAL/Lwip/lwIP_Sockets.cpp b/src/PAL/Lwip/lwIP_Sockets.cpp index 6d9587787d..971c0c5084 100644 --- a/src/PAL/Lwip/lwIP_Sockets.cpp +++ b/src/PAL/Lwip/lwIP_Sockets.cpp @@ -144,6 +144,10 @@ void LWIP_SOCKETS_Driver::Link_callback(struct netif *netif) #if LWIP_NETIF_STATUS_CALLBACK == 1 void LWIP_SOCKETS_Driver::Status_callback(struct netif *netif) { +#ifdef BUILD_RTM + (void)netif; +#endif + if (!PostAddressChangedContinuation.IsLinked()) PostAddressChangedContinuation.Enqueue(); @@ -235,7 +239,6 @@ bool LWIP_SOCKETS_Driver::Initialize() if (interfaceNumber == SOCK_SOCKET_ERROR) { DEBUG_HANDLE_SOCKET_ERROR("Network init", FALSE); - // FIXME debug_printf("SocketError: %d\n", errorCode); continue; } @@ -422,6 +425,64 @@ int LWIP_SOCKETS_Driver::Shutdown(SOCK_SOCKET socket, int how) return lwip_shutdown(socket, how); } +SOCK_addrinfo *CreateAddressRecord(u_long addr, short family, u_short port, char *canonname, const SOCK_addrinfo *hints) +{ + SOCK_addrinfo *ai; + SOCK_sockaddr_in *sa = NULL; + int total_size = sizeof(SOCK_addrinfo) + sizeof(SOCK_sockaddr_in); + int canonNameSize; + void *dummyPtr; + + // Allow for canon name if available + if (canonname != NULL) + { + // Size including terminator so we allocate name after SOCK_addrinfo + SOCK_sockaddr_in + canonNameSize = hal_strlen_s(canonname) + 1; + total_size += canonNameSize; + } + + ai = (SOCK_addrinfo *)mem_malloc(total_size); + if (ai == NULL) + { + // Out of memory + return NULL; + } + + memset(ai, 0, total_size); + sa = (SOCK_sockaddr_in *)((u8_t *)ai + sizeof(SOCK_addrinfo)); + + // set up sockaddr + sa->sin_addr.S_un.S_addr = addr; + sa->sin_family = family; + sa->sin_port = port; + + // set up addrinfo + ai->ai_family = family; + + if (hints != NULL) + { + // copy socktype & protocol from hints if specified + ai->ai_socktype = hints->ai_socktype; + ai->ai_protocol = hints->ai_protocol; + } + + // Copy in canon name if available + if (canonname != NULL) + { + ai->ai_canonname = (char *)ai + total_size - canonNameSize; + memcpy(ai->ai_canonname, canonname, canonNameSize); + } + + // need this to keep the compiler happy about the cast to SOCK_sockaddr + // which is intended and perfectly safe + dummyPtr = sa; + + ai->ai_addrlen = sizeof(SOCK_sockaddr_in); + ai->ai_addr = (SOCK_sockaddr *)dummyPtr; + + return ai; +} + int LWIP_SOCKETS_Driver::GetAddrInfo( const char *nodename, char *servname, @@ -431,113 +492,81 @@ int LWIP_SOCKETS_Driver::GetAddrInfo( #if LWIP_DNS NATIVE_PROFILE_PAL_NETWORK(); - SOCK_addrinfo *ai; - void *dummyPtr; - SOCK_sockaddr_in *sa = NULL; - int total_size = sizeof(SOCK_addrinfo) + sizeof(SOCK_sockaddr_in); + SOCK_addrinfo *ai = NULL; + SOCK_addrinfo *nextAi = NULL; struct addrinfo *lwipAddrinfo = {0}; - if (res == NULL) + if (res == NULL || nodename == NULL) { return SOCK_SOCKET_ERROR; } *res = NULL; - // if the nodename == "" then return the IP address of this device + // if the nodename == "" then return the IP addresses of this device if (nodename[0] == 0 && servname == NULL) { - struct netif *networkInterface = netif_find_interface(g_LWIP_SOCKETS_Driver.m_interfaces[0].m_interfaceNumber); - - if (networkInterface == NULL) - return -1; - - ai = (SOCK_addrinfo *)mem_malloc(total_size); - - if (ai == NULL) + // Work through all available Network Interfaces in reverse so link list ends up with lowest index first. + for (int i = g_TargetConfiguration.NetworkInterfaceConfigs->Count - 1; i >= 0; i--) { - return -1; - } + struct netif *networkInterface = + netif_find_interface(g_LWIP_SOCKETS_Driver.m_interfaces[i].m_interfaceNumber); - memset(ai, 0, total_size); - sa = (SOCK_sockaddr_in *)((u8_t *)ai + sizeof(SOCK_addrinfo)); + if (networkInterface == NULL) + { + continue; + } - /* set up sockaddr */ #if LWIP_IPV6 - sa->sin_addr.S_un.S_addr = networkInterface->ip_addr.u_addr.ip4.addr; + u_long addr = networkInterface->ip_addr.u_addr.ip4.addr; #else - sa->sin_addr.S_un.S_addr = networkInterface->ip_addr.addr; + u_long addr = networkInterface->ip_addr.addr; #endif + ai = CreateAddressRecord(addr, AF_INET, 0, NULL, hints); + if (ai == NULL) + { + // Out of memory ? + return SOCK_SOCKET_ERROR; + } - sa->sin_family = AF_INET; - sa->sin_port = 0; - - /* set up addrinfo */ - ai->ai_family = AF_INET; + // Link SOCK_addrinfo + records together + ai->ai_next = nextAi; + nextAi = ai; + } - if (hints != NULL) + if (ai == NULL) { - /* copy socktype & protocol from hints if specified */ - ai->ai_socktype = hints->ai_socktype; - ai->ai_protocol = hints->ai_protocol; + // No addresses to return + return -1; } - // need this to keep the compiler happy about the cast to SOCK_sockaddr - // which is intended and perfectly safe - dummyPtr = sa; - - ai->ai_addrlen = sizeof(SOCK_sockaddr_in); - ai->ai_addr = (SOCK_sockaddr *)dummyPtr; - *res = ai; return 0; } int err = lwip_getaddrinfo(nodename, servname, (addrinfo *)hints, &lwipAddrinfo); - if (err == 0) { /// /// Marshal addrinfo data /// - struct sockaddr_in *lwip_sockaddr_in; + struct sockaddr_in *lwip_sockaddr_in = ((struct sockaddr_in *)lwipAddrinfo->ai_addr); - ai = (SOCK_addrinfo *)mem_malloc(total_size); + ai = CreateAddressRecord( + lwip_sockaddr_in->sin_addr.s_addr, + lwip_sockaddr_in->sin_family, + lwip_sockaddr_in->sin_port, + lwipAddrinfo->ai_canonname, + hints); if (ai == NULL) { + // Out of memory lwip_freeaddrinfo(lwipAddrinfo); return -1; } - memset(ai, 0, total_size); - - lwip_sockaddr_in = ((struct sockaddr_in *)lwipAddrinfo->ai_addr); - - sa = (SOCK_sockaddr_in *)((u8_t *)ai + sizeof(SOCK_addrinfo)); - /* set up sockaddr */ - sa->sin_addr.S_un.S_addr = lwip_sockaddr_in->sin_addr.s_addr; - sa->sin_family = lwip_sockaddr_in->sin_family; - sa->sin_port = lwip_sockaddr_in->sin_port; - - /* set up addrinfo */ - ai->ai_family = lwipAddrinfo->ai_family; - - if (hints != NULL) - { - /* copy socktype & protocol from hints if specified */ - ai->ai_socktype = hints->ai_socktype; - ai->ai_protocol = hints->ai_protocol; - } - - // need this to keep the compiler happy about the cast to SOCK_sockaddr - // which is intended and perfectly safe - dummyPtr = sa; - - ai->ai_addrlen = sizeof(SOCK_sockaddr_in); - ai->ai_addr = (SOCK_sockaddr *)dummyPtr; - *res = ai; // free marshalled addrinfo @@ -657,24 +686,36 @@ int LWIP_SOCKETS_Driver::Select( fd_set *pW = (writefds != NULL) ? &write : NULL; fd_set *pE = (exceptfds != NULL) ? &excpt : NULL; - // If the network goes down then we should alert any pending socket actions + // If network down then we should alert any pending socket actions if (exceptfds != NULL && exceptfds->fd_count > 0) { - struct netif *networkInterface = netif_find_interface(g_LWIP_SOCKETS_Driver.m_interfaces[0].m_interfaceNumber); + bool networkInterfaceAvailable = false; - if (networkInterface != NULL) + // Check all network interfaces for a working connection + for (int i = 0; i < g_TargetConfiguration.NetworkInterfaceConfigs->Count; i++) { - if (!netif_is_up(networkInterface)) + struct netif *networkInterface = + netif_find_interface(g_LWIP_SOCKETS_Driver.m_interfaces[i].m_interfaceNumber); + if (networkInterface != NULL) { - if (readfds != NULL) - readfds->fd_count = 0; - if (writefds != NULL) - writefds->fd_count = 0; + if (netif_is_up(networkInterface)) + { + networkInterfaceAvailable = true; + break; + } + } + } + + if (!networkInterfaceAvailable) + { + if (readfds != NULL) + readfds->fd_count = 0; + if (writefds != NULL) + writefds->fd_count = 0; - errorCode = ENETDOWN; + errorCode = ENETDOWN; - return exceptfds->fd_count; - } + return exceptfds->fd_count; } } diff --git a/src/PAL/Lwip/lwIP_Sockets_functions.cpp b/src/PAL/Lwip/lwIP_Sockets_functions.cpp index 7bdf93ec79..af188b50b6 100644 --- a/src/PAL/Lwip/lwIP_Sockets_functions.cpp +++ b/src/PAL/Lwip/lwIP_Sockets_functions.cpp @@ -170,6 +170,10 @@ const char *HAL_SOCK_IPAddressToString(uint32_t address) void HAL_SOCK_EventsSet(uint32_t events) { +#ifdef BUILD_RTM + (void)events; +#endif + NATIVE_PROFILE_PAL_NETWORK(); ASSERT((events == SOCKET_EVENT_FLAG_SOCKET) || (events == SOCKET_EVENT_FLAG_SOCKETS_READY)); diff --git a/src/System.Device.I2c/sys_dev_i2c_native.cpp b/src/System.Device.I2c/sys_dev_i2c_native.cpp index fc15fee6e3..0bd51d2778 100644 --- a/src/System.Device.I2c/sys_dev_i2c_native.cpp +++ b/src/System.Device.I2c/sys_dev_i2c_native.cpp @@ -40,7 +40,7 @@ const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_System_Device_I2c = "System.Device.I2c", 0xFA806D33, method_lookup, - { 100, 0, 0, 1 } + { 100, 0, 0, 2 } }; // clang-format on diff --git a/src/System.Device.I2c/sys_dev_i2c_native.h b/src/System.Device.I2c/sys_dev_i2c_native.h index 8f1dbcc4ef..6749f4cca4 100644 --- a/src/System.Device.I2c/sys_dev_i2c_native.h +++ b/src/System.Device.I2c/sys_dev_i2c_native.h @@ -16,6 +16,7 @@ typedef enum __nfpack I2cBusSpeed { I2cBusSpeed_StandardMode = 0, I2cBusSpeed_FastMode = 1, + I2cBusSpeed_FastModePlus = 2, } I2cBusSpeed; typedef enum __nfpack I2cTransferStatus @@ -60,4 +61,4 @@ struct Library_sys_dev_i2c_native_System_Device_I2c_I2cDevice extern const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_System_Device_I2c; -#endif //SYS_DEV_I2C_NATIVE_H +#endif // SYS_DEV_I2C_NATIVE_H diff --git a/src/System.Device.I2s/sys_dev_I2s_native.cpp b/src/System.Device.I2s/sys_dev_i2s_native.cpp similarity index 100% rename from src/System.Device.I2s/sys_dev_I2s_native.cpp rename to src/System.Device.I2s/sys_dev_i2s_native.cpp diff --git a/src/System.Device.I2s/sys_dev_I2s_native.h b/src/System.Device.I2s/sys_dev_i2s_native.h similarity index 100% rename from src/System.Device.I2s/sys_dev_I2s_native.h rename to src/System.Device.I2s/sys_dev_i2s_native.h diff --git a/src/System.Device.Spi/nanoHAL_Spi.cpp b/src/System.Device.Spi/nanoHAL_Spi.cpp index 07150c0d88..7916eb5b8e 100644 --- a/src/System.Device.Spi/nanoHAL_Spi.cpp +++ b/src/System.Device.Spi/nanoHAL_Spi.cpp @@ -18,7 +18,9 @@ // Create a handle built from device type, SPI bus number and device index #define CreateSpiHandle(spiBusIndex, deviceIndex) ((CPU_DEVICE_TYPE_SPI << 16) + (spiBusIndex << 8) + deviceIndex) -#define GetBusFromHandle(handle) ((handle >> 8) & 0x00ff); +#define GetBusFromHandle(handle) ((handle >> 8) & 0x00ff); +#define GetTypeFromHandle(handle) ((handle >> 16) & 0x00ff); +#define GetDeviceFromHandle(handle) ((handle)&0x00ff); // Saved config for each available SPI bus nanoSPI_BusConfig spiconfig[NUM_SPI_BUSES]; @@ -80,6 +82,7 @@ __nfweak uint32_t CPU_SPI_PortsCount() } map >>= 1; } + return count; } @@ -99,13 +102,12 @@ __nfweak void CPU_SPI_GetPins(uint32_t spi_bus, GPIO_PIN &clockPin, GPIO_PIN &mi // return true = handle valid static bool getDevice(uint32_t handle, uint8_t &spiBus, int &deviceIndex) { - int type = handle >> 16 & 0x00ff; - deviceIndex = handle & 0x00ff; - + int type = GetTypeFromHandle(handle); + deviceIndex = GetDeviceFromHandle(handle); spiBus = GetBusFromHandle(handle); - // Validate type, bus, deviceIndex - if (type != CPU_DEVICE_TYPE_SPI || spiBus >= NUM_SPI_BUSES || deviceIndex >= NUM_SPI_BUSES) + // Validate type, bus, no need to check the device index as we're managing this manually + if (type != CPU_DEVICE_TYPE_SPI || spiBus >= NUM_SPI_BUSES) { return false; } @@ -123,6 +125,7 @@ static int FindFreeDeviceSlotSpi(int spiBus, int32_t cs) { return deviceIndex; } + // Check device chip select not already in use if (spiconfig[spiBus].deviceConfig[deviceIndex].DeviceChipSelect == cs) { @@ -146,6 +149,7 @@ bool nanoSPI_Initialize() spiconfig[spiBus].devicesInUse = 0; memset(&spiconfig[spiBus].deviceHandles, 0, sizeof(spiconfig[spiBus].deviceHandles)); } + return true; } @@ -354,8 +358,8 @@ HRESULT nanoSPI_OpenDeviceEx( // Add next Device - Copy device config, save handle, increment number devices on bus nanoSPI_BusConfig *pBusConfig = &spiconfig[spiDeviceConfig.Spi_Bus]; - pBusConfig->deviceConfig[spiDeviceConfig.Spi_Bus] = spiDeviceConfig; - pBusConfig->deviceHandles[spiDeviceConfig.Spi_Bus] = deviceHandle; + pBusConfig->deviceConfig[deviceIndex] = spiDeviceConfig; + pBusConfig->deviceHandles[deviceIndex] = deviceHandle; pBusConfig->devicesInUse++; @@ -447,7 +451,9 @@ HRESULT nanoSPI_Write_Read( int deviceIndex; if (!getDevice(handle, spiBus, deviceIndex)) + { return CLR_E_INVALID_PARAMETER; + } return CPU_SPI_nWrite_nRead( spiconfig[spiBus].deviceHandles[deviceIndex], diff --git a/src/System.Device.Spi/sys_dev_spi_native_System_Device_Spi_SpiDevice.cpp b/src/System.Device.Spi/sys_dev_spi_native_System_Device_Spi_SpiDevice.cpp index 68318579ec..1b462d40b5 100644 --- a/src/System.Device.Spi/sys_dev_spi_native_System_Device_Spi_SpiDevice.cpp +++ b/src/System.Device.Spi/sys_dev_spi_native_System_Device_Spi_SpiDevice.cpp @@ -92,6 +92,7 @@ HRESULT Library_sys_dev_spi_native_System_Device_Spi_SpiDevice::NativeTransfer( // get a pointer to the managed object instance and check that it's not NULL CLR_RT_HeapBlock *pThis = stack.This(); + CLR_RT_HeapBlock *connectionSettings; FAULT_ON_NULL(pThis); // get device handle saved on open @@ -179,7 +180,19 @@ HRESULT Library_sys_dev_spi_native_System_Device_Spi_SpiDevice::NativeTransfer( bool fullDuplex = (bool)stack.Arg3().NumericByRef().u1; // Set up read/write settings for SPI_Write_Read call - rws = {fullDuplex, 0, data16Bits, 0}; + // Gets the CS and active state + connectionSettings = + pThis[Library_sys_dev_spi_native_System_Device_Spi_SpiDevice::FIELD___connectionSettings].Dereference(); + int32_t chipSelect = + connectionSettings[Library_sys_dev_spi_native_System_Device_Spi_SpiConnectionSettings::FIELD___csLine] + .NumericByRef() + .s4; + bool chipSelectActiveState = + (bool)connectionSettings[Library_sys_dev_spi_native_System_Device_Spi_SpiConnectionSettings:: + FIELD___chipSelectLineActiveState] + .NumericByRef() + .u1; + rws = {fullDuplex, 0, data16Bits, 0, chipSelect, chipSelectActiveState}; // Check to see if we should run async so as not to hold up other tasks isLongRunningOperation = System_Device_IsLongRunningOperation( @@ -303,7 +316,7 @@ HRESULT Library_sys_dev_spi_native_System_Device_Spi_SpiDevice::NativeOpenDevice } // load CS active state from config (which is always PinValue.Low or PinValue.High - spiConfig.ChipSelectActive = + spiConfig.ChipSelectActiveState = (bool)config[SpiConnectionSettings::FIELD___chipSelectLineActiveState].NumericByRef().s4; spiConfig.Spi_Mode = (SpiMode)config[SpiConnectionSettings::FIELD___spiMode].NumericByRef().s4; diff --git a/src/System.Device.UsbStream/System.Device.UsbStream.filters b/src/System.Device.UsbStream/System.Device.UsbStream.filters new file mode 100644 index 0000000000..7f41043a0f --- /dev/null +++ b/src/System.Device.UsbStream/System.Device.UsbStream.filters @@ -0,0 +1,30 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + + + Header Files + + + \ No newline at end of file diff --git a/src/System.Device.UsbStream/System.Device.UsbStream.vcxproj b/src/System.Device.UsbStream/System.Device.UsbStream.vcxproj new file mode 100644 index 0000000000..90228ee520 --- /dev/null +++ b/src/System.Device.UsbStream/System.Device.UsbStream.vcxproj @@ -0,0 +1,162 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + {71fbf8bd-5386-4ea9-9e6b-ec36470fc021} + Win32Proj + System.Device.UsbStream + 10.0.19041.0 + + + + StaticLibrary + true + v142 + Unicode + + + StaticLibrary + false + v142 + true + Unicode + + + StaticLibrary + true + v142 + Unicode + + + StaticLibrary + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + $(BinDir) + $(IntDir) + + + $(BinDir) + $(IntDir) + + + $(BinDir) + $(IntDir) + + + $(BinDir) + $(IntDir) + + + + + + Level3 + Disabled + WIN32;_DEBUG;_LIB;NANOCLR_SYSTEM_COLLECTIONS=TRUE;%(PreprocessorDefinitions) + ..\..\targets\win32\Include;..\Include;..\CLR\Include;..\CorLib;..\HAL\Include;..\PAL\Include + + + Windows + + + + + + + Level3 + Disabled + _DEBUG;_LIB;NANOCLR_SYSTEM_COLLECTIONS=TRUE;%(PreprocessorDefinitions) + ..\Include;..\CorLib + + + Windows + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + ..\..\targets\win32\Include;..\Include;..\CLR\Include;..\CorLib;..\HAL\Include;..\PAL\Include + + + Windows + true + true + + + + + Level3 + + + MaxSpeed + true + true + NDEBUG;_LIB;%(PreprocessorDefinitions) + ..\Include;..\CorLib + + + Windows + true + true + + + + + + \ No newline at end of file diff --git a/src/System.Device.UsbStream/sys_dev_usbstream_native.cpp b/src/System.Device.UsbStream/sys_dev_usbstream_native.cpp new file mode 100644 index 0000000000..0340277c6f --- /dev/null +++ b/src/System.Device.UsbStream/sys_dev_usbstream_native.cpp @@ -0,0 +1,69 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include "sys_dev_usbstream_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, + Library_sys_dev_usbstream_native_System_Device_Usb_UsbStream::Read___I4__SZARRAY_U1__I4__I4, + NULL, + NULL, + NULL, + Library_sys_dev_usbstream_native_System_Device_Usb_UsbStream::Write___VOID__SZARRAY_U1__I4__I4, + NULL, + NULL, + Library_sys_dev_usbstream_native_System_Device_Usb_UsbStream::get_IsConnected___BOOLEAN, + NULL, + NULL, + NULL, + NULL, + Library_sys_dev_usbstream_native_System_Device_Usb_UsbStream::NativeClose___VOID, + Library_sys_dev_usbstream_native_System_Device_Usb_UsbStream::NativeOpen___I4__STRING__STRING, + NULL, +}; + +const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_System_Device_UsbStream = +{ + "System.Device.UsbStream", + 0x21BF24CB, + method_lookup, + { 100, 0, 0, 6 } +}; + +// clang-format on diff --git a/src/System.Device.UsbStream/sys_dev_usbstream_native.h b/src/System.Device.UsbStream/sys_dev_usbstream_native.h new file mode 100644 index 0000000000..aaae100c56 --- /dev/null +++ b/src/System.Device.UsbStream/sys_dev_usbstream_native.h @@ -0,0 +1,69 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#ifndef SYS_DEV_USBSTREAM_NATIVE_H +#define SYS_DEV_USBSTREAM_NATIVE_H + +#include +#include +#include +#include + +///////////////////////////////////////////////////////////////////////////////////////////////////////////// +// moved to targets\AzureRTOS\SiliconLabs\_common\autogen\sl_usbd_class_vendor_instances.h for convenience // +///////////////////////////////////////////////////////////////////////////////////////////////////////////// +// typedef enum __nfpack UsbEventType +// { +// UsbEventType_Invalid = 0, +// UsbEventType_DeviceConnected = 1, +// UsbEventType_DeviceDisconnected = 2, +// } UsbEventType; + +struct Library_sys_dev_usbstream_native_System_Device_Usb_DeviceConnectionEventArgs +{ + static const int FIELD___isConnected = 1; + + //--// +}; + +struct Library_sys_dev_usbstream_native_System_Device_Usb_UsbDeviceEvent +{ + static const int FIELD___eventType = 3; + static const int FIELD___eventData = 4; + static const int FIELD___interfaceIndex = 5; + + //--// +}; + +struct Library_sys_dev_usbstream_native_System_Device_Usb_UsbDeviceEventListener +{ + static const int FIELD___usbStream = 1; + + //--// +}; + +struct Library_sys_dev_usbstream_native_System_Device_Usb_UsbStream +{ + static const int FIELD_STATIC___streamCreated = 0; + + static const int FIELD___streamIndex = 1; + static const int FIELD___useDeviceEventListener = 2; + static const int FIELD___disposed = 3; + static const int FIELD___writeTimeout = 4; + static const int FIELD___readTimeout = 5; + static const int FIELD__UsbDeviceConnectionChanged = 6; + + NANOCLR_NATIVE_DECLARE(Read___I4__SZARRAY_U1__I4__I4); + NANOCLR_NATIVE_DECLARE(Write___VOID__SZARRAY_U1__I4__I4); + NANOCLR_NATIVE_DECLARE(get_IsConnected___BOOLEAN); + NANOCLR_NATIVE_DECLARE(NativeClose___VOID); + NANOCLR_NATIVE_DECLARE(NativeOpen___I4__STRING__STRING); + + //--// +}; + +extern const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_System_Device_UsbStream; + +#endif // SYS_DEV_USBSTREAM_NATIVE_H diff --git a/src/System.Device.UsbStream/sys_dev_usbstream_native_System_Device_Usb_UsbStream_stubs.cpp b/src/System.Device.UsbStream/sys_dev_usbstream_native_System_Device_Usb_UsbStream_stubs.cpp new file mode 100644 index 0000000000..839a3c7290 --- /dev/null +++ b/src/System.Device.UsbStream/sys_dev_usbstream_native_System_Device_Usb_UsbStream_stubs.cpp @@ -0,0 +1,51 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include + +HRESULT Library_sys_dev_usbstream_native_System_Device_Usb_UsbStream::Read___I4__SZARRAY_U1__I4__I4( CLR_RT_StackFrame &stack ) +{ + NANOCLR_HEADER(); + + NANOCLR_SET_AND_LEAVE(stack.NotImplementedStub()); + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_sys_dev_usbstream_native_System_Device_Usb_UsbStream::Write___VOID__SZARRAY_U1__I4__I4( CLR_RT_StackFrame &stack ) +{ + NANOCLR_HEADER(); + + NANOCLR_SET_AND_LEAVE(stack.NotImplementedStub()); + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_sys_dev_usbstream_native_System_Device_Usb_UsbStream::get_IsConnected___BOOLEAN( CLR_RT_StackFrame &stack ) +{ + NANOCLR_HEADER(); + + NANOCLR_SET_AND_LEAVE(stack.NotImplementedStub()); + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_sys_dev_usbstream_native_System_Device_Usb_UsbStream::NativeClose___VOID( CLR_RT_StackFrame &stack ) +{ + NANOCLR_HEADER(); + + NANOCLR_SET_AND_LEAVE(stack.NotImplementedStub()); + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_sys_dev_usbstream_native_System_Device_Usb_UsbStream::NativeOpen___I4__STRING__STRING( CLR_RT_StackFrame &stack ) +{ + NANOCLR_HEADER(); + + NANOCLR_SET_AND_LEAVE(stack.NotImplementedStub()); + + NANOCLR_NOCLEANUP(); +} diff --git a/src/System.Device.Wifi/sys_dev_wifi_native.cpp b/src/System.Device.Wifi/sys_dev_wifi_native.cpp index 081350697e..8c894e93d7 100644 --- a/src/System.Device.Wifi/sys_dev_wifi_native.cpp +++ b/src/System.Device.Wifi/sys_dev_wifi_native.cpp @@ -74,12 +74,14 @@ static const CLR_RT_MethodHandler method_lookup[] = NULL, NULL, NULL, + NULL, + NULL, }; const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_System_Device_Wifi = { "System.Device.Wifi", - 0x1C1D3214, + 0x00A058C6, method_lookup, { 100, 0, 6, 4 } }; diff --git a/src/System.Runtime.Serialization/nf_system_runtime_serialization_System_Runtime_Serialization_Formatters_Binary_BinaryFormatter.cpp b/src/System.Runtime.Serialization/nf_system_runtime_serialization_System_Runtime_Serialization_Formatters_Binary_BinaryFormatter.cpp index ca43054f76..2b40a2b8b6 100644 --- a/src/System.Runtime.Serialization/nf_system_runtime_serialization_System_Runtime_Serialization_Formatters_Binary_BinaryFormatter.cpp +++ b/src/System.Runtime.Serialization/nf_system_runtime_serialization_System_Runtime_Serialization_Formatters_Binary_BinaryFormatter.cpp @@ -26,7 +26,7 @@ HRESULT Library_nf_system_runtime_serialization_System_Runtime_Serialization_For NANOCLR_CLEANUP(); - if (hr == CLR_E_WRONG_TYPE && hash != 0) + if (hr != S_OK) { CLR_RT_HeapBlock &res = stack.m_owningThread->m_currentException; @@ -38,20 +38,25 @@ HRESULT Library_nf_system_runtime_serialization_System_Runtime_Serialization_For "System.Runtime.Serialization", serializationExceptionTypeDef); - if ((Library_corlib_native_System_Exception::CreateInstance( - res, - serializationExceptionTypeDef, - CLR_E_UNKNOWN_TYPE, - &stack)) == S_OK) + if ((Library_corlib_native_System_Exception::CreateInstance(res, serializationExceptionTypeDef, hr, &stack)) == + S_OK) { - CLR_RT_ReflectionDef_Index idx; - - idx.InitializeFromHash(hash); - - res.Dereference() - [Library_nf_system_runtime_serialization_System_Runtime_Serialization_SerializationException:: - FIELD__Type] - .SetReflection(idx); + if (hash != 0) + { + // if there is a hash, set the Type field ONLY IF the type is found + CLR_RT_ReflectionDef_Index idx; + CLR_RT_TypeDef_Instance inst; + + idx.InitializeFromHash(hash); + + if (inst.InitializeFromReflection(idx, NULL)) + { + res.Dereference() + [Library_nf_system_runtime_serialization_System_Runtime_Serialization_SerializationException:: + FIELD__Type] + .SetReflection(idx); + } + } } hr = CLR_E_PROCESS_EXCEPTION; diff --git a/src/nanoFramework.Graphics/Graphics/Core/Graphics.cpp b/src/nanoFramework.Graphics/Graphics/Core/Graphics.cpp index dd83b41712..e7d04dd1e3 100644 --- a/src/nanoFramework.Graphics/Graphics/Core/Graphics.cpp +++ b/src/nanoFramework.Graphics/Graphics/Core/Graphics.cpp @@ -420,7 +420,8 @@ CLR_UINT32 CLR_GFX_Bitmap::ConvertToNative16BppHelper(int x, int y, CLR_UINT32 f b |= 0x7; // Copy LSB myParam->srcCur16BppPixel++; opacity = PAL_GFX_Bitmap::c_OpacityOpaque; - return (r | g << 8 | b << 16); + + return (r << 16 | g << 8 | b); } CLR_UINT32 CLR_GFX_Bitmap::GetPixel(int xPos, int yPos) const diff --git a/src/nanoFramework.Graphics/Graphics/Core/Graphics.h b/src/nanoFramework.Graphics/Graphics/Core/Graphics.h index edb27491fb..3dc54c32c9 100644 --- a/src/nanoFramework.Graphics/Graphics/Core/Graphics.h +++ b/src/nanoFramework.Graphics/Graphics/Core/Graphics.h @@ -764,7 +764,7 @@ struct GraphicsDriver __inline static CLR_UINT8 ColorRValue(CLR_UINT32 color) { - return color & 0x0000FF; + return (color & 0xFF0000) >> 16; } __inline static CLR_UINT8 ColorGValue(CLR_UINT32 color) { @@ -772,7 +772,7 @@ struct GraphicsDriver } __inline static CLR_UINT8 ColorBValue(CLR_UINT32 color) { - return (color & 0xFF0000) >> 16; + return color & 0x0000FF; } __inline static CLR_UINT32 ColorFromRGB(CLR_UINT8 r, CLR_UINT8 g, CLR_UINT8 b) { diff --git a/src/nanoFramework.Graphics/Graphics/Core/Support/Gif/GifDecoder.cpp b/src/nanoFramework.Graphics/Graphics/Core/Support/Gif/GifDecoder.cpp index de00c0215f..0cff6f1ae6 100644 --- a/src/nanoFramework.Graphics/Graphics/Core/Support/Gif/GifDecoder.cpp +++ b/src/nanoFramework.Graphics/Graphics/Core/Support/Gif/GifDecoder.cpp @@ -8,6 +8,9 @@ #include "gif.h" #include "lzwread.h" +// Reverse 32bit RGB Color to 24bit BGR Color +#define REVERSECOLOR(n) ((n << 24) | (((n >> 16) << 24) >> 16) | (((n << 16) >> 24) << 16)) >> 8 + // Initialization routine for GifDecoder struct. When it's finished, // the header field would be loaded already. HRESULT GifDecoder::GifInitDecompress(const CLR_UINT8 *src, CLR_UINT32 srcSize) @@ -328,7 +331,7 @@ CLR_UINT32 GifDecoder::ProcessImageChunkHelper(int x, int y, CLR_UINT32 flags, C myParam->flushing = false; } - return color; + return REVERSECOLOR(color); } #pragma GCC diagnostic pop diff --git a/src/nanoFramework.Graphics/Graphics/Core/Support/Jpeg/Jpeg.cpp b/src/nanoFramework.Graphics/Graphics/Core/Support/Jpeg/Jpeg.cpp index eb71abe097..7638b535f2 100644 --- a/src/nanoFramework.Graphics/Graphics/Core/Support/Jpeg/Jpeg.cpp +++ b/src/nanoFramework.Graphics/Graphics/Core/Support/Jpeg/Jpeg.cpp @@ -18,39 +18,35 @@ extern "C" //////////////////////////////////////////////////////////////////////////////////////////////////// - // JPEG Error handling struct / routine struct JPEGErrorManager { jpeg_error_mgr pub; - int setjmpBuffer[32]; + jmp_buf setjmpBuffer; }; - - - void JPEGErrorHandler(j_common_ptr cinfo) { - JPEGErrorManager* errorManager = (JPEGErrorManager*)cinfo->err; + JPEGErrorManager *errorManager = (JPEGErrorManager *)cinfo->err; longjmp(errorManager->setjmpBuffer, 1); } struct CreateInstanceJpegHelperParam { - CLR_UINT8* curBuffer; - int index; + CLR_UINT8 *curBuffer; + int index; JSAMPARRAY buffer; - jpeg_decompress_struct* cinfo; + jpeg_decompress_struct *cinfo; }; -HRESULT CLR_GFX_Bitmap::CreateInstanceJpeg(CLR_RT_HeapBlock& ref, const CLR_UINT8* data, const CLR_UINT32 size) +HRESULT CLR_GFX_Bitmap::CreateInstanceJpeg(CLR_RT_HeapBlock &ref, const CLR_UINT8 *data, const CLR_UINT32 size) { NANOCLR_HEADER(); - jpeg_decompress_struct cinfo; - CLR_GFX_Bitmap* bitmap = NULL; + jpeg_decompress_struct cinfo; + CLR_GFX_Bitmap *bitmap = NULL; CreateInstanceJpegHelperParam param; - GFX_Rect rect; + GFX_Rect rect; param.curBuffer = NULL; @@ -73,7 +69,7 @@ HRESULT CLR_GFX_Bitmap::CreateInstanceJpeg(CLR_RT_HeapBlock& ref, const CLR_UINT // Create the decompression engine jpeg_create_decompress(&cinfo); - jpeg_byte_array_src(&cinfo, (CLR_UINT8*)data, size); + jpeg_byte_array_src(&cinfo, (CLR_UINT8 *)data, size); jpeg_read_header(&cinfo, TRUE); // Set output to 16bit 5-6-5 RGB format @@ -85,7 +81,10 @@ HRESULT CLR_GFX_Bitmap::CreateInstanceJpeg(CLR_RT_HeapBlock& ref, const CLR_UINT // At this point cinfo would have all the correct output dimension info CLR_GFX_BitmapDescription bm; - if (bm.BitmapDescription_Initialize(cinfo.output_width, cinfo.output_height, CLR_GFX_BitmapDescription::c_NativeBpp) == false) + if (bm.BitmapDescription_Initialize( + cinfo.output_width, + cinfo.output_height, + CLR_GFX_BitmapDescription::c_NativeBpp) == false) { // if the resulting bitmap doesn't match our constraints, stop the decompression NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); @@ -102,24 +101,30 @@ HRESULT CLR_GFX_Bitmap::CreateInstanceJpeg(CLR_RT_HeapBlock& ref, const CLR_UINT rect.right = cinfo.output_width - 1; rect.bottom = cinfo.output_height - 1; - param.curBuffer = (CLR_UINT8*)CLR_RT_Memory::Allocate(cinfo.output_width * 3); CHECK_ALLOCATION(param.curBuffer); + param.curBuffer = (CLR_UINT8 *)CLR_RT_Memory::Allocate(cinfo.output_width * 3); + CHECK_ALLOCATION(param.curBuffer); param.buffer = (JSAMPARRAY) & (param.curBuffer); param.cinfo = &cinfo; - bitmap->SetPixelsHelper(rect, PAL_GFX_Bitmap::c_SetPixelsConfig_NoClip | PAL_GFX_Bitmap::c_SetPixelsConfig_NoClipChecks, &CreateInstanceJpegHelper, ¶m); + bitmap->SetPixelsHelper( + rect, + PAL_GFX_Bitmap::c_SetPixelsConfig_NoClip | PAL_GFX_Bitmap::c_SetPixelsConfig_NoClipChecks, + &CreateInstanceJpegHelper, + ¶m); NANOCLR_CLEANUP(); - if (param.curBuffer) CLR_RT_Memory::Release(param.curBuffer); + if (param.curBuffer) + CLR_RT_Memory::Release(param.curBuffer); jpeg_destroy_decompress(&cinfo); NANOCLR_CLEANUP_END(); } #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" -CLR_UINT32 CLR_GFX_Bitmap::CreateInstanceJpegHelper(int x, int y, CLR_UINT32 flags, CLR_UINT16& opacity, void* param) +CLR_UINT32 CLR_GFX_Bitmap::CreateInstanceJpegHelper(int x, int y, CLR_UINT32 flags, CLR_UINT16 &opacity, void *param) { - CreateInstanceJpegHelperParam* myParam = (CreateInstanceJpegHelperParam*)param; + CreateInstanceJpegHelperParam *myParam = (CreateInstanceJpegHelperParam *)param; if (flags & PAL_GFX_Bitmap::c_SetPixels_NewRow) { @@ -136,6 +141,6 @@ CLR_UINT32 CLR_GFX_Bitmap::CreateInstanceJpegHelper(int x, int y, CLR_UINT32 fla myParam->index += 3; - return r | (g << 8) | (b << 16); + return (r << 16) | (g << 8) | b; } #pragma GCC diagnostic pop diff --git a/src/nanoFramework.Graphics/Graphics/Displays/Display.h b/src/nanoFramework.Graphics/Graphics/Displays/Display.h index f7efb39de5..d9086bc846 100644 --- a/src/nanoFramework.Graphics/Graphics/Displays/Display.h +++ b/src/nanoFramework.Graphics/Graphics/Displays/Display.h @@ -10,21 +10,38 @@ enum DisplayOrientation : CLR_INT16 { - PORTRAIT, - PORTRAIT180, - LANDSCAPE, - LANDSCAPE180 + DisplayOrientation_Portrait = 0, + DisplayOrientation_Portrait180 = 1, + DisplayOrientation_Landscape = 2, + DisplayOrientation_Landscape180 = 3, }; + +enum GraphicDriverCommandType : CLR_UINT8 +{ + GraphicDriverCommandType_Sleep = 0, + GraphicDriverCommandType_Command = 1, +}; + +enum SetWindowType : CLR_UINT8 +{ + SetWindowType_NoWindowing = 0, + SetWindowType_X8bitsY1Bit = 1, + SetWindowType_X8bitsY8Bits = 2, + SetWindowType_X16bitsY16Bit = 3, +}; + enum PixelFormat : CLR_UINT8 { FORMAT_RGB888 = 0, // Pixel format chosen is RGB888 : 24 bpp FORMAT_RBG565 = 2, // Pixel format chosen is RGB565 : 16 bpp }; + enum PowerSaveState : CLR_UINT8 { NORMAL = 0, SLEEP = 1 }; + struct DisplayAttributes { CLR_UINT8 *TransferBuffer = NULL; @@ -37,6 +54,7 @@ struct DisplayAttributes CLR_INT16 LongerSide; // Pixels CLR_INT16 ShorterSide; // Pixels }; + struct DisplayDriver { DisplayAttributes Attributes; diff --git a/src/nanoFramework.Graphics/Graphics/Displays/DisplayInterface.h b/src/nanoFramework.Graphics/Graphics/Displays/DisplayInterface.h index 9d67f53a9b..77263b00a5 100644 --- a/src/nanoFramework.Graphics/Graphics/Displays/DisplayInterface.h +++ b/src/nanoFramework.Graphics/Graphics/Displays/DisplayInterface.h @@ -7,6 +7,8 @@ #define DISPLAY_INTERFACE_H #include "nanoCLR_Types.h" +#include "nanoCLR_Interop.h" +#include "Core.h" // Display configuration struct DisplayInterfaceConfig @@ -34,6 +36,26 @@ struct DisplayInterfaceConfig CLR_UINT16 width; CLR_UINT16 height; } Screen; + struct + { + CLR_UINT32 Width; + CLR_UINT32 Height; + CLR_UINT8 BitsPerPixel; + CLR_RT_HeapBlock_Array *InitializationSequence; + CLR_UINT8 MemoryWrite; + CLR_UINT8 SetColumnAddress; + CLR_UINT8 SetRowAddress; + CLR_RT_HeapBlock_Array *PowerModeNormal; + CLR_RT_HeapBlock_Array *PowerModeSleep; + CLR_RT_HeapBlock_Array *OrientationPortrait; + CLR_RT_HeapBlock_Array *OrientationPortrait180; + CLR_RT_HeapBlock_Array *OrientationLandscape; + CLR_RT_HeapBlock_Array *OrientationLandscape180; + CLR_RT_HeapBlock_Array *Clear; + CLR_UINT8 Brightness; + CLR_UINT8 DefaultOrientation; + CLR_UINT8 SetWindowType; + } GenericDriverCommands; }; struct DisplayInterface diff --git a/src/nanoFramework.Graphics/Graphics/Displays/GC9A01_240x240_SPI.cpp b/src/nanoFramework.Graphics/Graphics/Displays/GC9A01_240x240_SPI.cpp index 1be4b8d8fe..c96f11b134 100644 --- a/src/nanoFramework.Graphics/Graphics/Displays/GC9A01_240x240_SPI.cpp +++ b/src/nanoFramework.Graphics/Graphics/Displays/GC9A01_240x240_SPI.cpp @@ -240,7 +240,7 @@ void DisplayDriver::PowerSave(PowerSaveState powerState) void DisplayDriver::SetDefaultOrientation() { - ChangeOrientation(LANDSCAPE); + ChangeOrientation(DisplayOrientation::DisplayOrientation_Landscape); } bool DisplayDriver::ChangeOrientation(DisplayOrientation orientation) @@ -248,16 +248,16 @@ bool DisplayDriver::ChangeOrientation(DisplayOrientation orientation) CLR_UINT8 orientationByte = GC9A01_MEMORY_ACCESS_CTRL::Portrait; switch (orientation) { - case DisplayOrientation::PORTRAIT: + case DisplayOrientation::DisplayOrientation_Portrait: orientationByte = GC9A01_MEMORY_ACCESS_CTRL::Portrait; break; - case DisplayOrientation::PORTRAIT180: + case DisplayOrientation::DisplayOrientation_Portrait180: orientationByte = GC9A01_MEMORY_ACCESS_CTRL::Portrait180; break; - case DisplayOrientation::LANDSCAPE: + case DisplayOrientation::DisplayOrientation_Landscape: orientationByte = GC9A01_MEMORY_ACCESS_CTRL::Landscape; break; - case DisplayOrientation::LANDSCAPE180: + case DisplayOrientation::DisplayOrientation_Landscape180: orientationByte = GC9A01_MEMORY_ACCESS_CTRL::Portrait180; break; } diff --git a/src/nanoFramework.Graphics/Graphics/Displays/Generic_SPI.cpp b/src/nanoFramework.Graphics/Graphics/Displays/Generic_SPI.cpp new file mode 100644 index 0000000000..0e72449eb5 --- /dev/null +++ b/src/nanoFramework.Graphics/Graphics/Displays/Generic_SPI.cpp @@ -0,0 +1,324 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Portions Copyright (c) Microsoft Corporation. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +#include "Graphics.h" +#include "DisplayInterface.h" +#include "Display.h" + +struct DisplayDriver g_DisplayDriver; +extern DisplayInterface g_DisplayInterface; +extern DisplayInterfaceConfig g_DisplayInterfaceConfig; + +// A pointer on the Set window function to make things faster +bool (*SetWindowPointer)(CLR_INT16 x1, CLR_INT16 y1, CLR_INT16 x2, CLR_INT16 y2); + +/* +Process command function to send commands or sleep. +*/ +void ProcessCommand(CLR_RT_HeapBlock_Array *array) +{ + CLR_UINT32 numberElements = array->m_numOfElements; + CLR_UINT32 inc = 0; + CLR_UINT8 *cmd; + CLR_UINT8 *size; + while (inc < numberElements) + { + cmd = array->GetElement(inc++); + size = array->GetElement(inc++); + // This is a sleep instruction + if (*cmd == GraphicDriverCommandType::GraphicDriverCommandType_Sleep) + { + OS_DELAY(*cmd * *size * 10); + } + // This is the normal command + else if (*cmd == GraphicDriverCommandType::GraphicDriverCommandType_Command) + { + // Send the command followed by the data, size is the all up size, so reduce by 1 + g_DisplayInterface.WriteToFrameBuffer(*array->GetElement(inc), array->GetElement(inc + 1), *size - 1, 0); + // increase the increment + inc += *size; + } + else + { + // Should no arrive, increment by 1 in case + inc++; + } + } +} + +/* +The next functions are the primitives depending on the driver set windowing behavior +*/ +bool SetWindowNoWindowing(CLR_INT16 x1, CLR_INT16 y1, CLR_INT16 x2, CLR_INT16 y2) +{ + // If no windowing, nothing is done here. + return true; +} + +bool SetWindowX8bitsY1Bit(CLR_INT16 x1, CLR_INT16 y1, CLR_INT16 x2, CLR_INT16 y2) +{ + // Start & End column address + g_DisplayInterface.SendCommand(3, g_DisplayInterfaceConfig.GenericDriverCommands.SetColumnAddress, x1, x2); + + // Start & End page address 0 to 7 + g_DisplayInterface.SendCommand(3, g_DisplayInterfaceConfig.GenericDriverCommands.SetRowAddress, (y1 / 8), (y2 / 8)); + + return true; +} + +bool SetWindowX8bitsY8Bits(CLR_INT16 x1, CLR_INT16 y1, CLR_INT16 x2, CLR_INT16 y2) +{ + // Start & End column address + g_DisplayInterface.SendCommand(3, g_DisplayInterfaceConfig.GenericDriverCommands.SetColumnAddress, x1, x2); + + // Start & End row address + g_DisplayInterface.SendCommand(3, g_DisplayInterfaceConfig.GenericDriverCommands.SetRowAddress, y1, y2); + + return true; +} + +bool SetWindowX16bitsY16Bit(CLR_INT16 x1, CLR_INT16 y1, CLR_INT16 x2, CLR_INT16 y2) +{ + CLR_UINT8 Column_Address_Set_Data[4]; + Column_Address_Set_Data[0] = ((x1 + g_DisplayInterfaceConfig.Screen.x) >> 8) & 0xFF; + Column_Address_Set_Data[1] = (x1 + g_DisplayInterfaceConfig.Screen.x) & 0xFF; + Column_Address_Set_Data[2] = ((x2 + g_DisplayInterfaceConfig.Screen.x) >> 8) & 0xFF; + Column_Address_Set_Data[3] = (x2 + g_DisplayInterfaceConfig.Screen.x) & 0xFF; + g_DisplayInterface.SendCommand( + 5, + g_DisplayInterfaceConfig.GenericDriverCommands.SetColumnAddress, + Column_Address_Set_Data[0], + Column_Address_Set_Data[1], + Column_Address_Set_Data[2], + Column_Address_Set_Data[3]); + + CLR_UINT8 Page_Address_Set_Data[4]; + Page_Address_Set_Data[0] = ((y1 + g_DisplayInterfaceConfig.Screen.y) >> 8) & 0xFF; + Page_Address_Set_Data[1] = (y1 + g_DisplayInterfaceConfig.Screen.y) & 0xFF; + Page_Address_Set_Data[2] = ((y2 + g_DisplayInterfaceConfig.Screen.y) >> 8) & 0xFF; + Page_Address_Set_Data[3] = (y2 + g_DisplayInterfaceConfig.Screen.y) & 0xFF; + g_DisplayInterface.SendCommand( + 5, + g_DisplayInterfaceConfig.GenericDriverCommands.SetRowAddress, + Page_Address_Set_Data[0], + Page_Address_Set_Data[1], + Page_Address_Set_Data[2], + Page_Address_Set_Data[3]); + return true; +} + +bool DisplayDriver::Initialize() +{ + // SetWindowPointer to the correct function + switch (g_DisplayInterfaceConfig.GenericDriverCommands.SetWindowType) + { + default: + case SetWindowType::SetWindowType_NoWindowing: + SetWindowPointer = &SetWindowNoWindowing; + break; + case SetWindowType::SetWindowType_X8bitsY1Bit: + SetWindowPointer = &SetWindowX8bitsY1Bit; + break; + case SetWindowType::SetWindowType_X8bitsY8Bits: + SetWindowPointer = &SetWindowX8bitsY8Bits; + break; + case SetWindowType::SetWindowType_X16bitsY16Bit: + SetWindowPointer = &SetWindowX16bitsY16Bit; + break; + } + + SetupDisplayAttributes(); + + ProcessCommand(g_DisplayInterfaceConfig.GenericDriverCommands.InitializationSequence); + + SetDefaultOrientation(); + + return true; +} + +void DisplayDriver::SetupDisplayAttributes() +{ + // Define the LCD/TFT resolution + if (g_DisplayInterfaceConfig.GenericDriverCommands.Width == 0) + { + Attributes.LongerSide = g_DisplayInterfaceConfig.Screen.width; + } + else + { + Attributes.LongerSide = g_DisplayInterfaceConfig.GenericDriverCommands.Width; + } + + if (g_DisplayInterfaceConfig.GenericDriverCommands.Height == 0) + { + Attributes.ShorterSide = g_DisplayInterfaceConfig.Screen.height; + ; + } + else + { + Attributes.LongerSide = g_DisplayInterfaceConfig.GenericDriverCommands.Height; + } + + Attributes.PowerSave = PowerSaveState::NORMAL; + if (g_DisplayInterfaceConfig.GenericDriverCommands.BitsPerPixel == 0) + { + Attributes.BitsPerPixel = 16; + } + else + { + Attributes.BitsPerPixel = g_DisplayInterfaceConfig.GenericDriverCommands.BitsPerPixel; + } + + g_DisplayInterface.GetTransferBuffer(Attributes.TransferBuffer, Attributes.TransferBufferSize); +} + +bool DisplayDriver::ChangeOrientation(DisplayOrientation orientation) +{ + switch (orientation) + { + case DisplayOrientation::DisplayOrientation_Portrait: + if (g_DisplayInterfaceConfig.GenericDriverCommands.OrientationPortrait != NULL) + { + Attributes.Height = Attributes.LongerSide; + Attributes.Width = Attributes.ShorterSide; + ProcessCommand(g_DisplayInterfaceConfig.GenericDriverCommands.OrientationPortrait); + return true; + } + + break; + case DisplayOrientation::DisplayOrientation_Portrait180: + if (g_DisplayInterfaceConfig.GenericDriverCommands.OrientationPortrait180 != NULL) + { + Attributes.Height = Attributes.LongerSide; + Attributes.Width = Attributes.ShorterSide; + ProcessCommand(g_DisplayInterfaceConfig.GenericDriverCommands.OrientationPortrait180); + return true; + } + + break; + case DisplayOrientation::DisplayOrientation_Landscape: + if (g_DisplayInterfaceConfig.GenericDriverCommands.OrientationLandscape != NULL) + { + Attributes.Height = Attributes.ShorterSide; + Attributes.Width = Attributes.LongerSide; + ProcessCommand(g_DisplayInterfaceConfig.GenericDriverCommands.OrientationLandscape); + return true; + } + + break; + case DisplayOrientation::DisplayOrientation_Landscape180: + if (g_DisplayInterfaceConfig.GenericDriverCommands.OrientationLandscape180 != NULL) + { + Attributes.Height = Attributes.ShorterSide; + Attributes.Width = Attributes.LongerSide; + ProcessCommand(g_DisplayInterfaceConfig.GenericDriverCommands.OrientationLandscape180); + return true; + } + + break; + } + + return false; +} + +void DisplayDriver::SetDefaultOrientation() +{ + ChangeOrientation((DisplayOrientation)g_DisplayInterfaceConfig.GenericDriverCommands.DefaultOrientation); +} + +void DisplayDriver::PowerSave(PowerSaveState powerState) +{ + switch (powerState) + { + default: + // Illegal fall through to Power on + case PowerSaveState::NORMAL: + if (g_DisplayInterfaceConfig.GenericDriverCommands.PowerModeNormal != NULL) + { + ProcessCommand(g_DisplayInterfaceConfig.GenericDriverCommands.PowerModeNormal); + } + + break; + case PowerSaveState::SLEEP: + if (g_DisplayInterfaceConfig.GenericDriverCommands.PowerModeSleep != NULL) + { + ProcessCommand(g_DisplayInterfaceConfig.GenericDriverCommands.PowerModeSleep); + } + + break; + } +} + +void DisplayDriver::Clear() +{ + // Default behavior + if (g_DisplayInterfaceConfig.GenericDriverCommands.Clear == NULL) + { + SetWindow(0, 0, Attributes.Width - 1, Attributes.Height - 1); + + g_DisplayInterface.SendCommand(1, g_DisplayInterfaceConfig.GenericDriverCommands.MemoryWrite); + + g_DisplayInterface.FillData16(0, Attributes.Width * Attributes.Height); + } + else + { + ProcessCommand(g_DisplayInterfaceConfig.GenericDriverCommands.Clear); + } +} + +void DisplayDriver::DisplayBrightness(CLR_INT16 brightness) +{ + _ASSERTE(brightness >= 0 && brightness <= 100); + g_DisplayInterface.SendCommand(2, g_DisplayInterfaceConfig.GenericDriverCommands.Brightness, (CLR_UINT8)brightness); +} + +bool DisplayDriver::SetWindow(CLR_INT16 x1, CLR_INT16 y1, CLR_INT16 x2, CLR_INT16 y2) +{ + return (*SetWindowPointer)(x1, y1, x2, y2); +} + +void DisplayDriver::BitBlt( + int srcX, + int srcY, + int width, + int height, + int stride, + int screenX, + int screenY, + CLR_UINT32 data[]) +{ + // 16 bit colour RRRRRGGGGGGBBBBB mode 565 + + ASSERT((screenX >= 0) && ((screenX + width) <= Attributes.Width)); + ASSERT((screenY >= 0) && ((screenY + height) <= Attributes.Height)); + + SetWindow(screenX, screenY, (screenX + width - 1), (screenY + height - 1)); + + g_DisplayInterface.SendCommand(1, g_DisplayInterfaceConfig.GenericDriverCommands.MemoryWrite); + + g_DisplayInterface.SendData16Windowed((CLR_UINT16 *)&data[0], srcX, srcY, width, height, stride, true); + + return; +} + +CLR_UINT32 DisplayDriver::PixelsPerWord() +{ + return (32 / Attributes.BitsPerPixel); +} + +CLR_UINT32 DisplayDriver::WidthInWords() +{ + return ((Attributes.Width + (PixelsPerWord() - 1)) / PixelsPerWord()); +} + +CLR_UINT32 DisplayDriver::SizeInWords() +{ + return (WidthInWords() * Attributes.Height); +} + +CLR_UINT32 DisplayDriver::SizeInBytes() +{ + return (SizeInWords() * sizeof(CLR_UINT32)); +} diff --git a/src/nanoFramework.Graphics/Graphics/Displays/ILI9341_240x320_SPI.cpp b/src/nanoFramework.Graphics/Graphics/Displays/ILI9341_240x320_SPI.cpp index 7909b17360..82b66593e7 100644 --- a/src/nanoFramework.Graphics/Graphics/Displays/ILI9341_240x320_SPI.cpp +++ b/src/nanoFramework.Graphics/Graphics/Displays/ILI9341_240x320_SPI.cpp @@ -165,6 +165,8 @@ bool DisplayDriver::Initialize() g_DisplayInterface.SendCommand(2, Entry_Mode_Set, 0x07); // Entry mode set g_DisplayInterface.SendCommand(5, Display_Function_Control, 0x0A, 0x82, 0x27, 0x00); + g_DisplayInterface.SendCommand(1, Sleep_Out); + OS_DELAY(20); // Send Sleep Out command to display : no parameter g_DisplayInterface.SendCommand(1, Normal_Display_On); OS_DELAY(10); g_DisplayInterface.SendCommand(1, Display_ON); @@ -192,18 +194,53 @@ bool DisplayDriver::ChangeOrientation(DisplayOrientation orientation) { switch (orientation) { - case PORTRAIT: - case PORTRAIT180: - return false; + case DisplayOrientation::DisplayOrientation_Portrait: + Attributes.Height = Attributes.ShorterSide; + Attributes.Width = Attributes.LongerSide; + g_DisplayInterface.SendCommand( + 2, + Memory_Access_Control, + (ILI9341_Orientation::MADCTL_MX | ILI9341_Orientation::MADCTL_BGR)); + OS_DELAY(20); + g_DisplayInterface.SendCommand(1, ILI9341_CMD::Memory_Write); + OS_DELAY(20); + break; + + case DisplayOrientation::DisplayOrientation_Portrait180: + Attributes.Height = Attributes.ShorterSide; + Attributes.Width = Attributes.LongerSide; + g_DisplayInterface.SendCommand( + 2, + Memory_Access_Control, + (ILI9341_Orientation::MADCTL_MY | ILI9341_Orientation::MADCTL_BGR)); + OS_DELAY(20); + g_DisplayInterface.SendCommand(1, ILI9341_CMD::Memory_Write); + OS_DELAY(20); + break; + + case DisplayOrientation::DisplayOrientation_Landscape: + Attributes.Height = Attributes.ShorterSide; + Attributes.Width = Attributes.LongerSide; + g_DisplayInterface.SendCommand( + 2, + Memory_Access_Control, + (ILI9341_Orientation::MADCTL_MV | ILI9341_Orientation::MADCTL_BGR)); + OS_DELAY(20); + g_DisplayInterface.SendCommand(1, ILI9341_CMD::Memory_Write); + OS_DELAY(20); + break; - case LANDSCAPE: - case LANDSCAPE180: + case DisplayOrientation::DisplayOrientation_Landscape180: Attributes.Height = Attributes.ShorterSide; Attributes.Width = Attributes.LongerSide; g_DisplayInterface.SendCommand( 2, Memory_Access_Control, - (MADCTL_MY | MADCTL_MX | MADCTL_MV | MADCTL_BGR)); // Landscape + BGR + (ILI9341_Orientation::MADCTL_MY | ILI9341_Orientation::MADCTL_MX | ILI9341_Orientation::MADCTL_MV | + ILI9341_Orientation::MADCTL_BGR)); + OS_DELAY(20); + g_DisplayInterface.SendCommand(1, ILI9341_CMD::Memory_Write); + OS_DELAY(20); break; } return true; @@ -211,7 +248,7 @@ bool DisplayDriver::ChangeOrientation(DisplayOrientation orientation) void DisplayDriver::SetDefaultOrientation() { - ChangeOrientation(LANDSCAPE); + ChangeOrientation(DisplayOrientation::DisplayOrientation_Landscape); } bool DisplayDriver::Uninitialize() diff --git a/src/nanoFramework.Graphics/Graphics/Displays/ILI9341_XXXxYYY_SPI.cpp b/src/nanoFramework.Graphics/Graphics/Displays/ILI9341_XXXxYYY_SPI.cpp index 7c821749a5..3e41b2692f 100644 --- a/src/nanoFramework.Graphics/Graphics/Displays/ILI9341_XXXxYYY_SPI.cpp +++ b/src/nanoFramework.Graphics/Graphics/Displays/ILI9341_XXXxYYY_SPI.cpp @@ -220,13 +220,13 @@ bool DisplayDriver::ChangeOrientation(DisplayOrientation orientation) // define logic resolution switch (orientation) { - case PORTRAIT: - case PORTRAIT180: + case DisplayOrientation::DisplayOrientation_Portrait: + case DisplayOrientation::DisplayOrientation_Portrait180: Attributes.Height = Attributes.LongerSide; Attributes.Width = Attributes.ShorterSide; break; - case LANDSCAPE: - case LANDSCAPE180: + case DisplayOrientation::DisplayOrientation_Landscape: + case DisplayOrientation::DisplayOrientation_Landscape180: Attributes.Height = Attributes.ShorterSide; Attributes.Width = Attributes.LongerSide; break; @@ -235,16 +235,16 @@ bool DisplayDriver::ChangeOrientation(DisplayOrientation orientation) // set physical resolution switch (orientation) { - case PORTRAIT: + case DisplayOrientation::DisplayOrientation_Portrait: dMAC |= dmac_PORTRAIT000; break; - case PORTRAIT180: + case DisplayOrientation::DisplayOrientation_Portrait180: dMAC |= dmac_PORTRAIT180; break; - case LANDSCAPE: + case DisplayOrientation::DisplayOrientation_Landscape: dMAC |= dmac_LANDSCAPE000; break; - case LANDSCAPE180: + case DisplayOrientation::DisplayOrientation_Landscape180: dMAC |= dmac_LANDSCAPE180; break; } @@ -261,8 +261,7 @@ bool DisplayDriver::ChangeOrientation(DisplayOrientation orientation) void DisplayDriver::SetDefaultOrientation() { // Change default orientation to display defaults - // ChangeOrientation(LANDSCAPE); - ChangeOrientation(PORTRAIT); + ChangeOrientation(DisplayOrientation::DisplayOrientation_Portrait); } bool DisplayDriver::Uninitialize() diff --git a/src/nanoFramework.Graphics/Graphics/Displays/ILI9342_320x240_SPI.cpp b/src/nanoFramework.Graphics/Graphics/Displays/ILI9342_320x240_SPI.cpp index e8ae2bfc24..38fa27a7da 100644 --- a/src/nanoFramework.Graphics/Graphics/Displays/ILI9342_320x240_SPI.cpp +++ b/src/nanoFramework.Graphics/Graphics/Displays/ILI9342_320x240_SPI.cpp @@ -174,8 +174,8 @@ bool DisplayDriver::ChangeOrientation(DisplayOrientation orientation) { switch (orientation) { - case PORTRAIT: - case PORTRAIT180: + case DisplayOrientation::DisplayOrientation_Portrait: + case DisplayOrientation::DisplayOrientation_Portrait180: Attributes.Height = Attributes.LongerSide; Attributes.Width = Attributes.ShorterSide; g_DisplayInterface.SendCommand( @@ -183,8 +183,8 @@ bool DisplayDriver::ChangeOrientation(DisplayOrientation orientation) Memory_Access_Control, (MADCTL_MY | MADCTL_MX | MADCTL_MV | MADCTL_BGR)); // Landscape + BGR break; - case LANDSCAPE: - case LANDSCAPE180: + case DisplayOrientation::DisplayOrientation_Landscape: + case DisplayOrientation::DisplayOrientation_Landscape180: Attributes.Height = Attributes.ShorterSide; Attributes.Width = Attributes.LongerSide; g_DisplayInterface.SendCommand(2, Memory_Access_Control, @@ -196,7 +196,7 @@ bool DisplayDriver::ChangeOrientation(DisplayOrientation orientation) void DisplayDriver::SetDefaultOrientation() { - ChangeOrientation(LANDSCAPE); + ChangeOrientation(DisplayOrientation::DisplayOrientation_Landscape); } bool DisplayDriver::Uninitialize() diff --git a/src/nanoFramework.Graphics/Graphics/Displays/ILI9488_480x320_SPI.cpp b/src/nanoFramework.Graphics/Graphics/Displays/ILI9488_480x320_SPI.cpp new file mode 100644 index 0000000000..c1a93634d0 --- /dev/null +++ b/src/nanoFramework.Graphics/Graphics/Displays/ILI9488_480x320_SPI.cpp @@ -0,0 +1,345 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Portions Copyright (c) Microsoft Corporation. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +#include "Graphics.h" +#include "DisplayInterface.h" +#include "Display.h" + +/* +IThe ILI9488 is a 16.7M single-chip SoC driver for a-Si TFT liquid crystal display panels with a resolution of +320(RGB) x 480 dots. The ILI9488 is comprised of a 960-channel source driver, a 480-channel gate driver, +345,600 bytes GRAM for graphic data of 320 (RGB) x 480 dots, and power supply circuit. +The ILI9488 supports parallel DBI Type B 8-/9-/16-/18-/24-bit data bus interfaces and DBI Type C 3-/4-line serial +peripheral interfaces (SPI) to input commands. The ILI9488 supports DPI (16-/18-/24-bit) data bus for video image +display. For MIPI*-DSI* high-speed interface mode, the ILI9488 also provides one data lane and one clock lane +that can support up to 500Mbps on MIPI-DSI link. +*/ + +/* + Using the default endian order for transferring bytes + Normal (MSB first, default) + */ + +#define CommandData(c) \ + c, (CLR_UINT8 *)(CLR_UINT8[c]) // Macro to simplify visualisation of passing pointer to parameters; + +// #define NUMBER_OF_LINES 8 +// #define SPI_MAX_TRANSFER_SIZE (480 * 3 * NUMBER_OF_LINES) // 480 pixels 3 words wide ( 24 bit colour) +// CLR_UINT8 dataBuffer[SPI_MAX_TRANSFER_SIZE]; + +struct DisplayDriver g_DisplayDriver; +extern DisplayInterface g_DisplayInterface; +extern DisplayInterfaceConfig g_DisplayInterfaceConfig; + +enum ILI9488_CMD : CLR_UINT8 +{ + NOP = 0x00, + SOFTWARE_RESET = 0x01, + POWER_STATE = 0x10, + Sleep_Out = 0x11, + Noron = 0x13, + Invert_On = 0x21, + Invert_Off = 0x20, + Gamma_Set = 0x26, + Display_OFF = 0x28, + Display_ON = 0x29, + Column_Address_Set = 0x2A, + Page_Address_Set = 0x2B, + Memory_Write = 0x2C, + Colour_Set = 0x2D, + Memory_Read = 0x2E, + Partial_Area = 0x30, + Memory_Access_Control = 0x36, + Pixel_Format_Set = 0x3A, + Memory_Write_Continue = 0x3C, + Write_Display_Brightness = 0x51, + Interface_Signal_Control = 0xB0, + Frame_Rate_Control_Normal = 0xB1, + Inversion_Control = 0xB4, + Display_Function_Control = 0xB6, + Entry_Mode_Set = 0xB7, + Power_Control_1 = 0xC0, + Power_Control_2 = 0xC1, + VCOM_Control_1 = 0xC5, + VCOM_Control_2 = 0xC7, + External_Command = 0xC8, + Power_Control_A = 0xCB, + Power_Control_B = 0xCF, + Positive_Gamma_Correction = 0xE0, + Negative_Gamma_Correction = 0XE1, + Driver_Timing_Control_A = 0xE8, + Driver_Timing_Control_B = 0xEA, + Set_Image_Function = 0xE9, + Power_On_Sequence = 0xED, + Enable_3G = 0xF2, + Interface_Control = 0xF6, + Pump_Ratio_Control = 0xF7 +}; + +enum ILI9488_Orientation : CLR_UINT8 +{ + MADCTL_MH = 0x04, // sets the Horizontal Refresh, 0=Left-Right and 1=Right-Left + MADCTL_ML = 0x10, // sets the Vertical Refresh, 0=Top-Bottom and 1=Bottom-Top + MADCTL_MV = 0x20, // sets the Row/Column Swap, 0=Normal and 1=Swapped + MADCTL_MX = 0x40, // sets the Column Order, 0=Left-Right and 1=Right-Left + MADCTL_MY = 0x80, // sets the Row Order, 0=Top-Bottom and 1=Bottom-Top + + MADCTL_BGR = 0x08, // Blue-Green-Red pixel order +}; + +bool DisplayDriver::Initialize() +{ + // Initialize ILI9488 registers + + SetupDisplayAttributes(); + + g_DisplayInterface.SendCommand( + 16, + Positive_Gamma_Correction, + 0x00, + 0x03, + 0x09, + 0x08, + 0x16, + 0x0A, + 0x3F, + 0x78, + 0x4C, + 0x09, + 0x0A, + 0x08, + 0x16, + 0x1A, + 0x0F); + g_DisplayInterface.SendCommand( + 16, + Negative_Gamma_Correction, + 0x00, + 0x16, + 0x19, + 0x03, + 0x0F, + 0x05, + 0x32, + 0x45, + 0x46, + 0x04, + 0x0E, + 0x0D, + 0x35, + 0x37, + 0x0F); + g_DisplayInterface.SendCommand(3, Power_Control_1, 0x17, 0x15); + g_DisplayInterface.SendCommand(2, Power_Control_2, 0x41); + g_DisplayInterface.SendCommand(4, VCOM_Control_1, 0x00, 0x12, 0x80); + g_DisplayInterface.SendCommand(2, Memory_Access_Control, 0x48); + g_DisplayInterface.SendCommand(2, Pixel_Format_Set, 0x66); // 18 bit for SPI + g_DisplayInterface.SendCommand(2, Interface_Signal_Control, 0x80); + g_DisplayInterface.SendCommand(2, Frame_Rate_Control_Normal, 0xA0); + g_DisplayInterface.SendCommand(2, Inversion_Control, 0x02); + g_DisplayInterface.SendCommand(3, Display_Function_Control, 0x02, 0x02, 0x3B); + g_DisplayInterface.SendCommand(2, Set_Image_Function, 0x00); + g_DisplayInterface.SendCommand(5, Pump_Ratio_Control, 0xA9, 0x51, 0x2C, 0x82); + g_DisplayInterface.SendCommand(1, Sleep_Out); + OS_DELAY(120); + g_DisplayInterface.SendCommand(1, Display_ON); + OS_DELAY(25); + + SetDefaultOrientation(); + + return true; +} + +void DisplayDriver::SetupDisplayAttributes() +{ + // Define the LCD/TFT resolution + Attributes.LongerSide = 480; + Attributes.ShorterSide = 320; + Attributes.PowerSave = PowerSaveState::NORMAL; + Attributes.BitsPerPixel = 18; + g_DisplayInterface.GetTransferBuffer(Attributes.TransferBuffer, Attributes.TransferBufferSize); + return; +} + +bool DisplayDriver::ChangeOrientation(DisplayOrientation orientation) +{ + switch (orientation) + { + case DisplayOrientation::DisplayOrientation_Portrait: + Attributes.Height = Attributes.LongerSide; + Attributes.Width = Attributes.ShorterSide; + g_DisplayInterface.SendCommand(2, Memory_Access_Control, + (MADCTL_MX | MADCTL_BGR)); // Portrait + BGR + break; + case DisplayOrientation::DisplayOrientation_Portrait180: + Attributes.Height = Attributes.LongerSide; + Attributes.Width = Attributes.ShorterSide; + g_DisplayInterface.SendCommand(2, Memory_Access_Control, + (MADCTL_MY | MADCTL_BGR)); // Portrait 180 + BGR + break; + case DisplayOrientation::DisplayOrientation_Landscape: + Attributes.Height = Attributes.ShorterSide; + Attributes.Width = Attributes.LongerSide; + g_DisplayInterface.SendCommand(2, Memory_Access_Control, + (MADCTL_MV | MADCTL_BGR)); // Landscape + BGR + break; + case DisplayOrientation::DisplayOrientation_Landscape180: + Attributes.Height = Attributes.ShorterSide; + Attributes.Width = Attributes.LongerSide; + g_DisplayInterface.SendCommand( + 2, + Memory_Access_Control, + (MADCTL_MX | MADCTL_MY | MADCTL_MV | MADCTL_BGR)); // Landscape 180 + BGR + break; + } + return true; +} + +void DisplayDriver::SetDefaultOrientation() +{ + ChangeOrientation(DisplayOrientation::DisplayOrientation_Landscape180); +} + +bool DisplayDriver::Uninitialize() +{ + Clear(); + + // Anything else to Uninitialize? + return TRUE; +} + +void DisplayDriver::PowerSave(PowerSaveState powerState) +{ + switch (powerState) + { + default: + // Illegal fall through to Power on + case PowerSaveState::NORMAL: + g_DisplayInterface.SendCommand(3, POWER_STATE, 0x00, 0x00); // leave sleep mode + break; + case PowerSaveState::SLEEP: + g_DisplayInterface.SendCommand(3, POWER_STATE, 0x00, 0x01); // enter sleep mode + break; + } + return; +} + +void DisplayDriver::Clear() +{ + SetWindow(0, 0, Attributes.Width - 1, Attributes.Height - 1); + + g_DisplayInterface.SendCommand(1, Memory_Write); + g_DisplayInterface.FillData16(0, Attributes.Width * Attributes.Height * 3 / 2); +} + +void DisplayDriver::DisplayBrightness(CLR_INT16 brightness) +{ + _ASSERTE(brightness >= 0 && brightness <= 100); + g_DisplayInterface.SendCommand(2, Write_Display_Brightness, (CLR_UINT8)brightness); +} + +bool DisplayDriver::SetWindow(CLR_INT16 x1, CLR_INT16 y1, CLR_INT16 x2, CLR_INT16 y2) +{ + CLR_UINT8 Column_Address_Set_Data[4]; + Column_Address_Set_Data[0] = ((x1 + g_DisplayInterfaceConfig.Screen.x) >> 8) & 0xFF; + Column_Address_Set_Data[1] = (x1 + g_DisplayInterfaceConfig.Screen.x) & 0xFF; + Column_Address_Set_Data[2] = ((x2 + g_DisplayInterfaceConfig.Screen.x) >> 8) & 0xFF; + Column_Address_Set_Data[3] = (x2 + g_DisplayInterfaceConfig.Screen.x) & 0xFF; + g_DisplayInterface.SendCommand( + 5, + Column_Address_Set, + Column_Address_Set_Data[0], + Column_Address_Set_Data[1], + Column_Address_Set_Data[2], + Column_Address_Set_Data[3]); + + CLR_UINT8 Page_Address_Set_Data[4]; + Page_Address_Set_Data[0] = ((y1 + g_DisplayInterfaceConfig.Screen.y) >> 8) & 0xFF; + Page_Address_Set_Data[1] = (y1 + g_DisplayInterfaceConfig.Screen.y) & 0xFF; + Page_Address_Set_Data[2] = ((y2 + g_DisplayInterfaceConfig.Screen.y) >> 8) & 0xFF; + Page_Address_Set_Data[3] = (y2 + g_DisplayInterfaceConfig.Screen.y) & 0xFF; + g_DisplayInterface.SendCommand( + 5, + Page_Address_Set, + Page_Address_Set_Data[0], + Page_Address_Set_Data[1], + Page_Address_Set_Data[2], + Page_Address_Set_Data[3]); + + return true; +} + +void DisplayDriver::BitBlt( + int srcX, + int srcY, + int width, + int height, + int stride, + int screenX, + int screenY, + CLR_UINT32 data[]) +{ + ASSERT((screenX >= 0) && ((screenX + width) <= Attributes.Width)); + ASSERT((screenY >= 0) && ((screenY + height) <= Attributes.Height)); + + SetWindow(screenX, screenY, (screenX + width - 1), (screenY + height - 1)); + + g_DisplayInterface.SendCommand(1, Memory_Write); + + uint32_t numPixels = width * height; + uint32_t count = 0; + + CLR_UINT8 *TransferBuffer = Attributes.TransferBuffer; + CLR_UINT32 TransferBufferSize = Attributes.TransferBufferSize; + + // only 18/24 bit is supported on SPI + for (uint32_t i = 0; i < numPixels; i++) + { + uint32_t element = data[i / 2]; // Each uint32 stores 2 pixels + uint16_t color = (i % 2 == 0) ? (element & 0xFFFF) : (element >> 16); + + uint8_t b = color & 0x1F; + uint8_t g = (color >> 5) & 0x3F; + uint8_t r = (color >> 11) & 0x1F; + + b = (b << 3) | (b >> 2); + g = (g << 2) | (g >> 4); + r = (r << 3) | (r >> 2); + + TransferBuffer[count++] = b; + TransferBuffer[count++] = g; + TransferBuffer[count++] = r; + + // can't fit another 3 bytes + if (count + 3 > TransferBufferSize - 1) + { + g_DisplayInterface.SendBytes(TransferBuffer, count); + count = 0; + } + } + g_DisplayInterface.SendBytes(TransferBuffer, count); + return; +} + +CLR_UINT32 DisplayDriver::PixelsPerWord() +{ + return (32 / Attributes.BitsPerPixel); +} + +CLR_UINT32 DisplayDriver::WidthInWords() +{ + return ((Attributes.Width + (PixelsPerWord() - 1)) / PixelsPerWord()); +} + +CLR_UINT32 DisplayDriver::SizeInWords() +{ + return (WidthInWords() * Attributes.Height); +} + +CLR_UINT32 DisplayDriver::SizeInBytes() +{ + return (SizeInWords() * sizeof(CLR_UINT32)); +} diff --git a/src/nanoFramework.Graphics/Graphics/Displays/Otm8009a_DSI_Video_Mode.cpp b/src/nanoFramework.Graphics/Graphics/Displays/Otm8009a_DSI_Video_Mode.cpp index cd80e714b0..7bba429461 100644 --- a/src/nanoFramework.Graphics/Graphics/Displays/Otm8009a_DSI_Video_Mode.cpp +++ b/src/nanoFramework.Graphics/Graphics/Displays/Otm8009a_DSI_Video_Mode.cpp @@ -464,7 +464,7 @@ bool DisplayDriver::ChangeOrientation(DisplayOrientation orientation) return false; // Landscape only at the moment - case LANDSCAPE: + case DisplayOrientation::DisplayOrientation_Landscape: Attributes.Height = Attributes.ShorterSide; Attributes.Width = Attributes.LongerSide; g_DisplayInterface.SendCommand(2, MADCTR, 0x60); @@ -475,7 +475,7 @@ bool DisplayDriver::ChangeOrientation(DisplayOrientation orientation) void DisplayDriver::SetDefaultOrientation() { - ChangeOrientation(LANDSCAPE); + ChangeOrientation(DisplayOrientation::DisplayOrientation_Landscape); } void DisplayDriver::Clear() diff --git a/src/nanoFramework.Graphics/Graphics/Displays/SSD1306_128x64.cpp b/src/nanoFramework.Graphics/Graphics/Displays/SSD1306_128x64.cpp index 336d933b82..74130ba00e 100644 --- a/src/nanoFramework.Graphics/Graphics/Displays/SSD1306_128x64.cpp +++ b/src/nanoFramework.Graphics/Graphics/Displays/SSD1306_128x64.cpp @@ -121,12 +121,12 @@ bool DisplayDriver::ChangeOrientation(DisplayOrientation orientation) { switch (orientation) { - case PORTRAIT: - case PORTRAIT180: + case DisplayOrientation::DisplayOrientation_Portrait: + case DisplayOrientation::DisplayOrientation_Portrait180: return false; - case LANDSCAPE: - case LANDSCAPE180: + case DisplayOrientation::DisplayOrientation_Landscape: + case DisplayOrientation::DisplayOrientation_Landscape180: Attributes.Height = Attributes.ShorterSide; Attributes.Width = Attributes.LongerSide; @@ -139,7 +139,7 @@ bool DisplayDriver::ChangeOrientation(DisplayOrientation orientation) void DisplayDriver::SetDefaultOrientation() { - ChangeOrientation(LANDSCAPE); + ChangeOrientation(DisplayOrientation::DisplayOrientation_Landscape); } bool DisplayDriver::SetWindow(CLR_INT16 x1, CLR_INT16 y1, CLR_INT16 x2, CLR_INT16 y2) diff --git a/src/nanoFramework.Graphics/Graphics/Displays/SSD1331_94x64_SPI.cpp b/src/nanoFramework.Graphics/Graphics/Displays/SSD1331_94x64_SPI.cpp index 28a3db3b38..635f5e0077 100644 --- a/src/nanoFramework.Graphics/Graphics/Displays/SSD1331_94x64_SPI.cpp +++ b/src/nanoFramework.Graphics/Graphics/Displays/SSD1331_94x64_SPI.cpp @@ -157,17 +157,17 @@ bool DisplayDriver::ChangeOrientation(DisplayOrientation orientation) switch (orientation) { - case PORTRAIT: - case PORTRAIT180: + case DisplayOrientation::DisplayOrientation_Portrait: + case DisplayOrientation::DisplayOrientation_Portrait180: return false; - case LANDSCAPE180: + case DisplayOrientation::DisplayOrientation_Landscape180: options |= 0x70; Attributes.Height = Attributes.ShorterSide; Attributes.Width = Attributes.LongerSide; break; - case LANDSCAPE: + case DisplayOrientation::DisplayOrientation_Landscape: options |= 0x72; Attributes.Height = Attributes.ShorterSide; Attributes.Width = Attributes.LongerSide; @@ -181,7 +181,7 @@ bool DisplayDriver::ChangeOrientation(DisplayOrientation orientation) void DisplayDriver::SetDefaultOrientation() { - ChangeOrientation(LANDSCAPE); + ChangeOrientation(DisplayOrientation::DisplayOrientation_Landscape); } bool DisplayDriver::SetWindow(CLR_INT16 x1, CLR_INT16 y1, CLR_INT16 x2, CLR_INT16 y2) diff --git a/src/nanoFramework.Graphics/Graphics/Displays/ST7735S_SPI.cpp b/src/nanoFramework.Graphics/Graphics/Displays/ST7735S_SPI.cpp index aee84f8965..9aa962e549 100644 --- a/src/nanoFramework.Graphics/Graphics/Displays/ST7735S_SPI.cpp +++ b/src/nanoFramework.Graphics/Graphics/Displays/ST7735S_SPI.cpp @@ -181,12 +181,12 @@ bool DisplayDriver::ChangeOrientation(DisplayOrientation orientation) { switch (orientation) { - case PORTRAIT: - case PORTRAIT180: + case DisplayOrientation::DisplayOrientation_Portrait: + case DisplayOrientation::DisplayOrientation_Portrait180: return false; - case LANDSCAPE: - case LANDSCAPE180: + case DisplayOrientation::DisplayOrientation_Landscape: + case DisplayOrientation::DisplayOrientation_Landscape180: Attributes.Height = Attributes.ShorterSide; Attributes.Width = Attributes.LongerSide; g_DisplayInterface.SendCommand( @@ -200,7 +200,7 @@ bool DisplayDriver::ChangeOrientation(DisplayOrientation orientation) void DisplayDriver::SetDefaultOrientation() { - ChangeOrientation(LANDSCAPE); + ChangeOrientation(DisplayOrientation::DisplayOrientation_Landscape); } bool DisplayDriver::Uninitialize() diff --git a/src/nanoFramework.Graphics/Graphics/Displays/ST7789V_240x320_SPI.cpp b/src/nanoFramework.Graphics/Graphics/Displays/ST7789V_240x320_SPI.cpp index 60e907d2fb..fe563bb3a2 100644 --- a/src/nanoFramework.Graphics/Graphics/Displays/ST7789V_240x320_SPI.cpp +++ b/src/nanoFramework.Graphics/Graphics/Displays/ST7789V_240x320_SPI.cpp @@ -162,12 +162,12 @@ bool DisplayDriver::ChangeOrientation(DisplayOrientation orientation) { switch (orientation) { - case PORTRAIT: - case PORTRAIT180: + case DisplayOrientation::DisplayOrientation_Portrait: + case DisplayOrientation::DisplayOrientation_Portrait180: return false; - case LANDSCAPE: - case LANDSCAPE180: + case DisplayOrientation::DisplayOrientation_Landscape: + case DisplayOrientation::DisplayOrientation_Landscape180: Attributes.Height = Attributes.ShorterSide; Attributes.Width = Attributes.LongerSide; g_DisplayInterface.SendCommand(2, Memory_Access_Control, @@ -179,7 +179,7 @@ bool DisplayDriver::ChangeOrientation(DisplayOrientation orientation) void DisplayDriver::SetDefaultOrientation() { - ChangeOrientation(LANDSCAPE); + ChangeOrientation(DisplayOrientation::DisplayOrientation_Landscape); } bool DisplayDriver::Uninitialize() diff --git a/src/nanoFramework.Graphics/Graphics/Displays/Spi_To_Display.cpp b/src/nanoFramework.Graphics/Graphics/Displays/Spi_To_Display.cpp index 134300774b..73cb34ff6d 100644 --- a/src/nanoFramework.Graphics/Graphics/Displays/Spi_To_Display.cpp +++ b/src/nanoFramework.Graphics/Graphics/Displays/Spi_To_Display.cpp @@ -23,7 +23,9 @@ CLR_INT16 lcdReset; CLR_INT16 lcdDC; CLR_INT16 lcdBacklight; -CLR_UINT32 spiDeviceHandle = 0; +uint32_t spiDeviceHandle = 0; +int spiChipSelect = 0; +bool spiChipSelectActiveState = false; CLR_INT16 outputBufferSize; CLR_UINT8 spiBuffer[SPI_MAX_TRANSFER_SIZE]; CLR_UINT8 spiBuffer2[SPI_MAX_TRANSFER_SIZE]; @@ -48,10 +50,13 @@ void DisplayInterface::Initialize(DisplayInterfaceConfig &config) spiConfig.BusMode = SpiBusMode::SpiBusMode_master; spiConfig.Spi_Bus = config.Spi.spiBus; spiConfig.DeviceChipSelect = config.Spi.chipSelect; - spiConfig.ChipSelectActive = false; + spiConfig.ChipSelectActiveState = false; spiConfig.Spi_Mode = SpiMode::SpiMode_Mode0; spiConfig.DataOrder16 = DataBitOrder::DataBitOrder_MSB; spiConfig.BusConfiguration = SpiBusConfiguration_FullDuplex; + // Store for internal usage + spiChipSelect = config.Spi.chipSelect; + spiChipSelectActiveState = false; spiConfig.Clock_RateHz = 40 * 1000 * 1000; // SPI clock speed. @@ -60,7 +65,6 @@ void DisplayInterface::Initialize(DisplayInterfaceConfig &config) bufferWritten = 0; HRESULT hr = nanoSPI_OpenDevice(spiConfig, spiDeviceHandle); - ASSERT(hr == ESP_OK); if (hr == S_OK) { // TODO Reserve Pins @@ -179,6 +183,7 @@ void DisplayInterface::DisplayBacklight(bool on) // true = on // Dummy callback to enable async spi writes void spi_callback(int busIndex) { + (void)busIndex; } void DisplayInterface::SendBytes(CLR_UINT8 *data, CLR_UINT32 length) @@ -197,6 +202,8 @@ void InternalSendBytes(CLR_UINT8 *data, CLR_UINT32 length, bool sendAsync) wrc.callback = sendAsync ? spi_callback : 0; wrc.fullDuplex = false; wrc.readOffset = 0; + wrc.DeviceChipSelect = spiChipSelect; + wrc.ChipSelectActiveState = spiChipSelectActiveState; nanoSPI_Write_Read(spiDeviceHandle, wrc, data, length, NULL, 0); diff --git a/src/nanoFramework.Graphics/Graphics/Native/nanoFramework_Graphics.cpp b/src/nanoFramework.Graphics/Graphics/Native/nanoFramework_Graphics.cpp index f05cc0c5ff..e4effa1ae2 100644 --- a/src/nanoFramework.Graphics/Graphics/Native/nanoFramework_Graphics.cpp +++ b/src/nanoFramework.Graphics/Graphics/Native/nanoFramework_Graphics.cpp @@ -116,37 +116,48 @@ static const CLR_RT_MethodHandler method_lookup[] = Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::Flush___VOID__I4__I4__I4__I4, Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::Flush___VOID__I4__I4__I4__I4__I4__I4, Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::Clear___VOID, - Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::DrawTextInRect___BOOLEAN__BYREF_STRING__BYREF_I4__BYREF_I4__I4__I4__I4__I4__U4__nanoFrameworkPresentationMediaColor__nanoFrameworkUIFont, NULL, - Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::DrawChar___VOID__U2__I4__I4__nanoFrameworkPresentationMediaColor__nanoFrameworkUIFont, + NULL, + NULL, Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::SetClippingRectangle___VOID__I4__I4__I4__I4, Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::get_Width___I4, Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::get_Height___I4, - Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::DrawEllipse___VOID__nanoFrameworkPresentationMediaColor__I4__I4__I4__I4__I4__nanoFrameworkPresentationMediaColor__I4__I4__nanoFrameworkPresentationMediaColor__I4__I4__U2, + NULL, NULL, NULL, Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::DrawImage___VOID__I4__I4__nanoFrameworkUIBitmap__I4__I4__I4__I4__U2, Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::RotateImage___VOID__I4__I4__I4__nanoFrameworkUIBitmap__I4__I4__I4__I4__U2, - Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::MakeTransparent___VOID__nanoFrameworkPresentationMediaColor, + NULL, Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::StretchImage___VOID__I4__I4__nanoFrameworkUIBitmap__I4__I4__U2, - Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::DrawLine___VOID__nanoFrameworkPresentationMediaColor__I4__I4__I4__I4__I4, - Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::DrawRectangle___VOID__I4__I4__I4__I4__I4__nanoFrameworkPresentationMediaColor, - Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::DrawRectangle___VOID__nanoFrameworkPresentationMediaColor__I4__I4__I4__I4__I4__I4__I4__nanoFrameworkPresentationMediaColor__I4__I4__nanoFrameworkPresentationMediaColor__I4__I4__U2, - Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::DrawRoundRectangle___VOID__I4__I4__I4__I4__I4__I4__I4__nanoFrameworkPresentationMediaColor, - Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::FillRectangle___VOID__I4__I4__I4__I4__nanoFrameworkPresentationMediaColor__U2, - Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::FillRoundRectangle___VOID__I4__I4__I4__I4__I4__I4__nanoFrameworkPresentationMediaColor__U2, - Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::FillGradientRectangle___VOID__I4__I4__I4__I4__nanoFrameworkPresentationMediaColor__I4__I4__nanoFrameworkPresentationMediaColor__I4__I4__U2, - Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::DrawText___VOID__STRING__nanoFrameworkUIFont__nanoFrameworkPresentationMediaColor__I4__I4, - Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::SetPixel___VOID__I4__I4__nanoFrameworkPresentationMediaColor, - Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::GetPixel___nanoFrameworkPresentationMediaColor__I4__I4, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::GetBitmap___SZARRAY_U1, Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::StretchImage___VOID__I4__I4__I4__I4__nanoFrameworkUIBitmap__I4__I4__I4__I4__U2, Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::TileImage___VOID__I4__I4__nanoFrameworkUIBitmap__I4__I4__U2, Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::Scale9Image___VOID__I4__I4__I4__I4__nanoFrameworkUIBitmap__I4__I4__I4__I4__U2, Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::Dispose___VOID__BOOLEAN, - NULL, - NULL, - NULL, + Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::DrawChar___VOID__U2__I4__I4__U4__nanoFrameworkUIFont, + Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::DrawEllipse___VOID__U4__I4__I4__I4__I4__I4__U4__I4__I4__U4__I4__I4__U2, + Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::MakeTransparent___VOID__U4, + Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::DrawLine___VOID__U4__I4__I4__I4__I4__I4, + Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::DrawRectangle___VOID__U4__I4__I4__I4__I4__I4__I4__I4__U4__I4__I4__U4__I4__I4__U2, + Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::DrawRectangle___VOID__I4__I4__I4__I4__I4__U4, + Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::FillGradientRectangle___VOID__I4__I4__I4__I4__U4__I4__I4__U4__I4__I4__U2, + Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::FillRectangle___VOID__I4__I4__I4__I4__U4__U2, + Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::DrawRoundRectangle___VOID__I4__I4__I4__I4__I4__I4__I4__U4, + Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::FillRoundRectangle___VOID__I4__I4__I4__I4__I4__I4__U4__U2, + Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::DrawText___VOID__STRING__nanoFrameworkUIFont__U4__I4__I4, + Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::SetPixel___VOID__I4__I4__U4, + Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::GetPixelInt___U4__I4__I4, + Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::DrawTextInRect___BOOLEAN__BYREF_STRING__BYREF_I4__BYREF_I4__I4__I4__I4__I4__U4__U4__nanoFrameworkUIFont, NULL, NULL, NULL, @@ -788,13 +799,51 @@ static const CLR_RT_MethodHandler method_lookup[] = Library_nanoFramework_Graphics_nanoFramework_UI_DisplayControl::get_Orientation___STATIC__nanoFrameworkUIDisplayOrientation, NULL, NULL, + NULL, Library_nanoFramework_Graphics_nanoFramework_UI_DisplayControl::Clear___STATIC__VOID, Library_nanoFramework_Graphics_nanoFramework_UI_DisplayControl::Write___STATIC__VOID__U2__U2__U2__U2__SZARRAY_U2, - Library_nanoFramework_Graphics_nanoFramework_UI_DisplayControl::Write___STATIC__VOID__STRING__U2__U2__U2__U2__nanoFrameworkUIFont__nanoFrameworkPresentationMediaColor__nanoFrameworkPresentationMediaColor, + NULL, + NULL, + Library_nanoFramework_Graphics_nanoFramework_UI_DisplayControl::Write___STATIC__VOID__STRING__U2__U2__U2__U2__nanoFrameworkUIFont__U4__U4, Library_nanoFramework_Graphics_nanoFramework_UI_DisplayControl::NativeChangeOrientation___STATIC__BOOLEAN__nanoFrameworkUIDisplayOrientation, Library_nanoFramework_Graphics_nanoFramework_UI_DisplayControl::NativeInitSpi___STATIC__U4__nanoFrameworkUISpiConfiguration__nanoFrameworkUIScreenConfiguration__U4, Library_nanoFramework_Graphics_nanoFramework_UI_DisplayControl::NativeInitI2c___STATIC__U4__nanoFrameworkUII2cConfiguration__nanoFrameworkUIScreenConfiguration__U4, NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + 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_Graphics_nanoFramework_UI_Ink::SetInkRegion___STATIC__VOID__U4__I4__I4__I4__I4__I4__I4__I4__nanoFrameworkUIBitmap, Library_nanoFramework_Graphics_nanoFramework_UI_Ink::ResetInkRegion___STATIC__VOID, NULL, @@ -983,9 +1032,9 @@ static const CLR_RT_MethodHandler method_lookup[] = const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Graphics = { "nanoFramework.Graphics", - 0x7BD8E418, + 0xC36AFE97, method_lookup, - { 100, 0, 0, 6 } + { 100, 0, 0, 9 } }; // clang-format on diff --git a/src/nanoFramework.Graphics/Graphics/Native/nanoFramework_Graphics.h b/src/nanoFramework.Graphics/Graphics/Native/nanoFramework_Graphics.h index edecd5bf4f..de18a800e0 100644 --- a/src/nanoFramework.Graphics/Graphics/Native/nanoFramework_Graphics.h +++ b/src/nanoFramework.Graphics/Graphics/Native/nanoFramework_Graphics.h @@ -8,10 +8,85 @@ #include #include +#include #include +// This is added as well from the copy/paste of the stub #include "Graphics.h" +typedef enum __nfpack UIElement_Flags +{ + UIElement_Flags_None = 0, + UIElement_Flags_IsSubtreeDirtyForRender = 2, + UIElement_Flags_IsDirtyForRender = 4, + UIElement_Flags_Enabled = 32, + UIElement_Flags_InvalidMeasure = 64, + UIElement_Flags_InvalidArrange = 128, + UIElement_Flags_MeasureInProgress = 256, + UIElement_Flags_ArrangeInProgress = 512, + UIElement_Flags_MeasureDuringArrange = 1024, + UIElement_Flags_NeverMeasured = 2048, + UIElement_Flags_NeverArranged = 4096, + UIElement_Flags_ShouldPostRender = 8192, + UIElement_Flags_IsLayoutSuspended = 16384, + UIElement_Flags_IsVisibleCache = 32768, +} UIElement_Flags; + +typedef enum __nfpack DrawTextOptions +{ + DrawTextOptions_None = 0, + DrawTextOptions_WordWrap = 1, + DrawTextOptions_TruncateAtBottom = 4, + DrawTextOptions_Ellipsis = 8, + DrawTextOptions_IgnoreHeight = 16, + DrawTextOptions_AlignmentLeft = 0, + DrawTextOptions_AlignmentCenter = 2, + DrawTextOptions_AlignmentRight = 32, + DrawTextOptions_AlignmentMask = 34, + DrawTextOptions_TrimmingNone = 0, + DrawTextOptions_TrimmingWordEllipsis = 8, + DrawTextOptions_TrimmingCharacterEllipsis = 64, + DrawTextOptions_TrimmingMask = 72, +} DrawTextOptions; + +/* moved to Display.h for convenience +typedef enum __nfpack GraphicDriverCommandType +{ + GraphicDriverCommandType_Sleep = 0, + GraphicDriverCommandType_Command = 1, +} GraphicDriverCommandType; +*/ + +typedef enum __nfpack TouchCaptureMode +{ + TouchCaptureMode_None = 0, + TouchCaptureMode_Element = 1, + TouchCaptureMode_SubTree = 2, +} TouchCaptureMode; + +/* +typedef enum __nfpack RoutedEventArgs_Flags +{ + RoutedEventArgs_Flags_Handled = 1, + RoutedEventArgs_Flags_InvokingHandler = 2, +} RoutedEventArgs_Flags; + +typedef enum __nfpack SetWindowType +{ + SetWindowType_NoWindowing = 0, + SetWindowType_X8bitsY1Bit = 1, + SetWindowType_X8bitsY8Bits = 2, + SetWindowType_X16bitsY16Bit = 3, +} SetWindowType; +*/ + +typedef enum __nfpack TouchCollectorConfiguration_TouchInput +{ + TouchCollectorConfiguration_TouchInput_LastTouchPoint = 2, + TouchCollectorConfiguration_TouchInput_SamplingDistance = 4, + TouchCollectorConfiguration_TouchInput_TouchMoveFrequency = 8, +} TouchCollectorConfiguration_TouchInput; + typedef enum __nfpack TouchInputFlags { TouchInputFlags_None = 0, @@ -32,16 +107,6 @@ struct Library_nanoFramework_Graphics_nanoFramework_UI_RoutedEvent //--// }; -struct Library_nanoFramework_Graphics_nanoFramework_UI_RoutedEventArgs -{ - static const int FIELD___routedEvent = 1; - static const int FIELD___source = 2; - static const int FIELD___originalSource = 3; - static const int FIELD___flags = 4; - - //--// -}; - struct Library_nanoFramework_Graphics_nanoFramework_UI_Input_ButtonEventArgs { static const int FIELD__Button = 7; @@ -89,20 +154,20 @@ struct Library_nanoFramework_Graphics_nanoFramework_UI_Threading_Dispatcher static const int FIELD_STATIC___dispatchers = 1; static const int FIELD_STATIC___possibleDispatcher = 2; - static const int FIELD__ShutdownStarted = 1; - static const int FIELD__ShutdownFinished = 2; - static const int FIELD___currentFrame = 3; - static const int FIELD___frameDepth = 4; - static const int FIELD___hasShutdownStarted = 5; - static const int FIELD___hasShutdownFinished = 6; - static const int FIELD___queue = 7; - static const int FIELD___event = 8; - static const int FIELD___instanceLock = 9; - static const int FIELD___thread = 10; - static const int FIELD___finalExceptionHandler = 11; - static const int FIELD___layoutManager = 12; - static const int FIELD___inputManager = 13; - static const int FIELD___mediaContext = 14; + static const int FIELD___currentFrame = 1; + static const int FIELD___frameDepth = 2; + static const int FIELD___hasShutdownStarted = 3; + static const int FIELD___hasShutdownFinished = 4; + static const int FIELD___queue = 5; + static const int FIELD___event = 6; + static const int FIELD___instanceLock = 7; + static const int FIELD___thread = 8; + static const int FIELD___finalExceptionHandler = 9; + static const int FIELD___layoutManager = 10; + static const int FIELD___inputManager = 11; + static const int FIELD___mediaContext = 12; + static const int FIELD__ShutdownStarted = 13; + static const int FIELD__ShutdownFinished = 14; //--// }; @@ -118,13 +183,13 @@ struct Library_nanoFramework_Graphics_nanoFramework_UI_Threading_DispatcherFrame struct Library_nanoFramework_Graphics_nanoFramework_UI_Threading_DispatcherOperation { - static const int FIELD__Aborted = 1; - static const int FIELD__Completed = 2; - static const int FIELD___dispatcher = 3; - static const int FIELD___method = 4; - static const int FIELD___args = 5; - static const int FIELD___result = 6; - static const int FIELD___status = 7; + static const int FIELD___dispatcher = 1; + static const int FIELD___method = 2; + static const int FIELD___args = 3; + static const int FIELD___result = 4; + static const int FIELD___status = 5; + static const int FIELD__Aborted = 6; + static const int FIELD__Completed = 7; //--// }; @@ -145,10 +210,10 @@ struct Library_nanoFramework_Graphics_nanoFramework_UI_Font NANOCLR_NATIVE_DECLARE(ComputeTextInRect___VOID__STRING__BYREF_I4__BYREF_I4__I4__I4__I4__I4__U4); //--// - //-- The Following was not generated // + // The Following was not generated // + // Update me every time you copy/paste this file // static HRESULT GetFont(CLR_RT_HeapBlock *pThis, CLR_GFX_Font *&font); static HRESULT GetFont(CLR_RT_StackFrame &stack, CLR_GFX_Font *&font); - //--// }; struct Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap @@ -166,35 +231,32 @@ struct Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap NANOCLR_NATIVE_DECLARE(Flush___VOID__I4__I4__I4__I4); NANOCLR_NATIVE_DECLARE(Flush___VOID__I4__I4__I4__I4__I4__I4); NANOCLR_NATIVE_DECLARE(Clear___VOID); - NANOCLR_NATIVE_DECLARE( - DrawTextInRect___BOOLEAN__BYREF_STRING__BYREF_I4__BYREF_I4__I4__I4__I4__I4__U4__nanoFrameworkPresentationMediaColor__nanoFrameworkUIFont); - NANOCLR_NATIVE_DECLARE(DrawChar___VOID__U2__I4__I4__nanoFrameworkPresentationMediaColor__nanoFrameworkUIFont); NANOCLR_NATIVE_DECLARE(SetClippingRectangle___VOID__I4__I4__I4__I4); NANOCLR_NATIVE_DECLARE(get_Width___I4); NANOCLR_NATIVE_DECLARE(get_Height___I4); - NANOCLR_NATIVE_DECLARE( - DrawEllipse___VOID__nanoFrameworkPresentationMediaColor__I4__I4__I4__I4__I4__nanoFrameworkPresentationMediaColor__I4__I4__nanoFrameworkPresentationMediaColor__I4__I4__U2); NANOCLR_NATIVE_DECLARE(DrawImage___VOID__I4__I4__nanoFrameworkUIBitmap__I4__I4__I4__I4__U2); NANOCLR_NATIVE_DECLARE(RotateImage___VOID__I4__I4__I4__nanoFrameworkUIBitmap__I4__I4__I4__I4__U2); - NANOCLR_NATIVE_DECLARE(MakeTransparent___VOID__nanoFrameworkPresentationMediaColor); NANOCLR_NATIVE_DECLARE(StretchImage___VOID__I4__I4__nanoFrameworkUIBitmap__I4__I4__U2); - NANOCLR_NATIVE_DECLARE(DrawLine___VOID__nanoFrameworkPresentationMediaColor__I4__I4__I4__I4__I4); - NANOCLR_NATIVE_DECLARE(DrawRectangle___VOID__I4__I4__I4__I4__I4__nanoFrameworkPresentationMediaColor); - NANOCLR_NATIVE_DECLARE( - DrawRectangle___VOID__nanoFrameworkPresentationMediaColor__I4__I4__I4__I4__I4__I4__I4__nanoFrameworkPresentationMediaColor__I4__I4__nanoFrameworkPresentationMediaColor__I4__I4__U2); - NANOCLR_NATIVE_DECLARE(DrawRoundRectangle___VOID__I4__I4__I4__I4__I4__I4__I4__nanoFrameworkPresentationMediaColor); - NANOCLR_NATIVE_DECLARE(FillRectangle___VOID__I4__I4__I4__I4__nanoFrameworkPresentationMediaColor__U2); - NANOCLR_NATIVE_DECLARE(FillRoundRectangle___VOID__I4__I4__I4__I4__I4__I4__nanoFrameworkPresentationMediaColor__U2); - NANOCLR_NATIVE_DECLARE( - FillGradientRectangle___VOID__I4__I4__I4__I4__nanoFrameworkPresentationMediaColor__I4__I4__nanoFrameworkPresentationMediaColor__I4__I4__U2); - NANOCLR_NATIVE_DECLARE(DrawText___VOID__STRING__nanoFrameworkUIFont__nanoFrameworkPresentationMediaColor__I4__I4); - NANOCLR_NATIVE_DECLARE(SetPixel___VOID__I4__I4__nanoFrameworkPresentationMediaColor); - NANOCLR_NATIVE_DECLARE(GetPixel___nanoFrameworkPresentationMediaColor__I4__I4); NANOCLR_NATIVE_DECLARE(GetBitmap___SZARRAY_U1); NANOCLR_NATIVE_DECLARE(StretchImage___VOID__I4__I4__I4__I4__nanoFrameworkUIBitmap__I4__I4__I4__I4__U2); NANOCLR_NATIVE_DECLARE(TileImage___VOID__I4__I4__nanoFrameworkUIBitmap__I4__I4__U2); NANOCLR_NATIVE_DECLARE(Scale9Image___VOID__I4__I4__I4__I4__nanoFrameworkUIBitmap__I4__I4__I4__I4__U2); NANOCLR_NATIVE_DECLARE(Dispose___VOID__BOOLEAN); + NANOCLR_NATIVE_DECLARE(DrawChar___VOID__U2__I4__I4__U4__nanoFrameworkUIFont); + NANOCLR_NATIVE_DECLARE(DrawEllipse___VOID__U4__I4__I4__I4__I4__I4__U4__I4__I4__U4__I4__I4__U2); + NANOCLR_NATIVE_DECLARE(MakeTransparent___VOID__U4); + NANOCLR_NATIVE_DECLARE(DrawLine___VOID__U4__I4__I4__I4__I4__I4); + NANOCLR_NATIVE_DECLARE(DrawRectangle___VOID__U4__I4__I4__I4__I4__I4__I4__I4__U4__I4__I4__U4__I4__I4__U2); + NANOCLR_NATIVE_DECLARE(DrawRectangle___VOID__I4__I4__I4__I4__I4__U4); + NANOCLR_NATIVE_DECLARE(FillGradientRectangle___VOID__I4__I4__I4__I4__U4__I4__I4__U4__I4__I4__U2); + NANOCLR_NATIVE_DECLARE(FillRectangle___VOID__I4__I4__I4__I4__U4__U2); + NANOCLR_NATIVE_DECLARE(DrawRoundRectangle___VOID__I4__I4__I4__I4__I4__I4__I4__U4); + NANOCLR_NATIVE_DECLARE(FillRoundRectangle___VOID__I4__I4__I4__I4__I4__I4__U4__U2); + NANOCLR_NATIVE_DECLARE(DrawText___VOID__STRING__nanoFrameworkUIFont__U4__I4__I4); + NANOCLR_NATIVE_DECLARE(SetPixel___VOID__I4__I4__U4); + NANOCLR_NATIVE_DECLARE(GetPixelInt___U4__I4__I4); + NANOCLR_NATIVE_DECLARE( + DrawTextInRect___BOOLEAN__BYREF_STRING__BYREF_I4__BYREF_I4__I4__I4__I4__I4__U4__U4__nanoFrameworkUIFont); //--// }; @@ -209,29 +271,29 @@ struct Library_nanoFramework_Graphics_nanoFramework_Presentation_Media_Pen struct Library_nanoFramework_Graphics_nanoFramework_Presentation_Media_DrawingContext { - static const int FIELD__EmptyClipRect = 2; - static const int FIELD___bitmap = 3; - static const int FIELD___x = 4; - static const int FIELD___y = 5; - static const int FIELD___clippingRectangles = 6; + static const int FIELD___bitmap = 2; + static const int FIELD___clippingRectangles = 3; + static const int FIELD__EmptyClipRect = 4; + static const int FIELD___x = 5; + static const int FIELD___y = 6; //--// }; struct Library_nanoFramework_Graphics_nanoFramework_Presentation_Media_MediaContext { - static const int FIELD___screenW = 2; - static const int FIELD___screenH = 3; - static const int FIELD___dirtyX0 = 4; - static const int FIELD___dirtyY0 = 5; - static const int FIELD___dirtyX1 = 6; - static const int FIELD___dirtyY1 = 7; - static const int FIELD___currentRenderOp = 8; - static const int FIELD___renderMessage = 9; - static const int FIELD___isRendering = 10; - static const int FIELD___invokeOnRenderCallbacks = 11; - static const int FIELD___target = 12; - static const int FIELD___screen = 13; + static const int FIELD___currentRenderOp = 2; + static const int FIELD___renderMessage = 3; + static const int FIELD___isRendering = 4; + static const int FIELD___invokeOnRenderCallbacks = 5; + static const int FIELD___target = 6; + static const int FIELD___screen = 7; + static const int FIELD___screenW = 8; + static const int FIELD___screenH = 9; + static const int FIELD___dirtyX0 = 10; + static const int FIELD___dirtyY0 = 11; + static const int FIELD___dirtyX1 = 12; + static const int FIELD___dirtyY1 = 13; //--// }; @@ -286,51 +348,8 @@ struct Library_nanoFramework_Graphics_nanoFramework_UI_RouteItem struct Library_nanoFramework_Graphics_nanoFramework_UI_EventRoute { - static const int FIELD__RoutedEvent = 1; - static const int FIELD___routeItemList = 2; - - //--// -}; - -struct Library_nanoFramework_Graphics_nanoFramework_Presentation_UIElement -{ - static const int FIELD_STATIC___classEventHandlersStore = 7; - - static const int FIELD__TouchDown = 2; - static const int FIELD__TouchUp = 3; - static const int FIELD__TouchMove = 4; - static const int FIELD__TouchGestureStart = 5; - static const int FIELD__TouchGestureChanged = 6; - static const int FIELD__TouchGestureEnd = 7; - static const int FIELD___parent = 8; - static const int FIELD___logicalChildren = 9; - static const int FIELD___flags = 10; - static const int FIELD___visibility = 11; - static const int FIELD___requestedSize = 12; - static const int FIELD___anchorInfo = 13; - static const int FIELD___marginLeft = 14; - static const int FIELD___marginTop = 15; - static const int FIELD___marginRight = 16; - static const int FIELD___marginBottom = 17; - static const int FIELD___horizontalAlignment = 18; - static const int FIELD___verticalAlignment = 19; - static const int FIELD___finalX = 20; - static const int FIELD___finalY = 21; - static const int FIELD___finalWidth = 22; - static const int FIELD___finalHeight = 23; - static const int FIELD___offsetX = 24; - static const int FIELD___offsetY = 25; - static const int FIELD___renderWidth = 26; - static const int FIELD___renderHeight = 27; - static const int FIELD___previousAvailableWidth = 28; - static const int FIELD___previousAvailableHeight = 29; - static const int FIELD___desiredWidth = 30; - static const int FIELD___desiredHeight = 31; - static const int FIELD___unclippedWidth = 32; - static const int FIELD___unclippedHeight = 33; - static const int FIELD___instanceEventHandlersStore = 34; - static const int FIELD___isEnabledChanged = 35; - static const int FIELD___isVisibleChanged = 36; + static const int FIELD___routeItemList = 1; + static const int FIELD__RoutedEvent = 2; //--// }; @@ -374,8 +393,8 @@ struct Library_nanoFramework_Graphics_nanoFramework_Presentation_Controls_Contro struct Library_nanoFramework_Graphics_nanoFramework_Presentation_Controls_DockPanel { - static const int FIELD_STATIC__DockPropertiesKeys = 8; - static const int FIELD_STATIC__DockPropertiesValues = 9; + static const int FIELD_STATIC__DockPropertiesKeys = 7; + static const int FIELD_STATIC__DockPropertiesValues = 8; static const int FIELD___lastChildFill = 37; @@ -663,7 +682,7 @@ struct Library_nanoFramework_Graphics_nanoFramework_Presentation_UIElementCollec struct Library_nanoFramework_Graphics_nanoFramework_Presentation_WindowManager { - static const int FIELD_STATIC__Instance = 10; + static const int FIELD_STATIC__Instance = 9; static const int FIELD___postRenderHandler = 37; @@ -717,8 +736,8 @@ struct Library_nanoFramework_Graphics_nanoFramework_UI_Input_InputReport struct Library_nanoFramework_Graphics_nanoFramework_UI_Input_InputManager { - static const int FIELD_STATIC__PreviewInputReportEvent = 11; - static const int FIELD_STATIC__InputReportEvent = 12; + static const int FIELD_STATIC__PreviewInputReportEvent = 10; + static const int FIELD_STATIC__InputReportEvent = 11; static const int FIELD___continueProcessingStagingAreaCallback = 2; static const int FIELD___frameStagingArea = 3; @@ -782,13 +801,13 @@ struct Library_nanoFramework_Graphics_nanoFramework_UI_Input_GenericDevice struct Library_nanoFramework_Graphics_nanoFramework_UI_Application { - static const int FIELD_STATIC___isShuttingDown = 13; - static const int FIELD_STATIC___appCreatedInThisAppDomain = 14; - static const int FIELD_STATIC___appInstance = 15; - static const int FIELD_STATIC___reportInputMethod = 16; - static const int FIELD_STATIC___inputManager = 17; - static const int FIELD_STATIC___stylusMaxX = 18; - static const int FIELD_STATIC___stylusMaxY = 19; + static const int FIELD_STATIC___isShuttingDown = 12; + static const int FIELD_STATIC___appCreatedInThisAppDomain = 13; + static const int FIELD_STATIC___appInstance = 14; + static const int FIELD_STATIC___reportInputMethod = 15; + static const int FIELD_STATIC___inputManager = 16; + static const int FIELD_STATIC___stylusMaxX = 17; + static const int FIELD_STATIC___stylusMaxY = 18; static const int FIELD___appWindowList = 2; static const int FIELD___nonAppWindowList = 3; @@ -835,6 +854,7 @@ struct Library_nanoFramework_Graphics_nanoFramework_UI_ScreenConfiguration static const int FIELD___y = 2; static const int FIELD___width = 3; static const int FIELD___height = 4; + static const int FIELD___graphicDriver = 5; //--// }; @@ -850,9 +870,9 @@ struct Library_nanoFramework_Graphics_nanoFramework_UI_I2cConfiguration struct Library_nanoFramework_Graphics_nanoFramework_UI_DisplayControl { - static const int FIELD_STATIC___maximumBufferSize = 20; - static const int FIELD_STATIC___fullScreen = 21; - static const int FIELD_STATIC___point = 22; + static const int FIELD_STATIC___maximumBufferSize = 19; + static const int FIELD_STATIC___fullScreen = 20; + static const int FIELD_STATIC___point = 21; NANOCLR_NATIVE_DECLARE(get_LongerSide___STATIC__I4); NANOCLR_NATIVE_DECLARE(get_ShorterSide___STATIC__I4); @@ -862,8 +882,7 @@ struct Library_nanoFramework_Graphics_nanoFramework_UI_DisplayControl NANOCLR_NATIVE_DECLARE(get_Orientation___STATIC__nanoFrameworkUIDisplayOrientation); NANOCLR_NATIVE_DECLARE(Clear___STATIC__VOID); NANOCLR_NATIVE_DECLARE(Write___STATIC__VOID__U2__U2__U2__U2__SZARRAY_U2); - NANOCLR_NATIVE_DECLARE( - Write___STATIC__VOID__STRING__U2__U2__U2__U2__nanoFrameworkUIFont__nanoFrameworkPresentationMediaColor__nanoFrameworkPresentationMediaColor); + NANOCLR_NATIVE_DECLARE(Write___STATIC__VOID__STRING__U2__U2__U2__U2__nanoFrameworkUIFont__U4__U4); NANOCLR_NATIVE_DECLARE(NativeChangeOrientation___STATIC__BOOLEAN__nanoFrameworkUIDisplayOrientation); NANOCLR_NATIVE_DECLARE( NativeInitSpi___STATIC__U4__nanoFrameworkUISpiConfiguration__nanoFrameworkUIScreenConfiguration__U4); @@ -873,6 +892,29 @@ struct Library_nanoFramework_Graphics_nanoFramework_UI_DisplayControl //--// }; +struct Library_nanoFramework_Graphics_nanoFramework_UI_GraphicDriver +{ + static const int FIELD___width = 1; + static const int FIELD___height = 2; + static const int FIELD___bitsPerPixel = 3; + static const int FIELD___initializationSequence = 4; + static const int FIELD___memoryWrite = 5; + static const int FIELD___setColumnAddress = 6; + static const int FIELD___setRowAddress = 7; + static const int FIELD___powerModeNormal = 8; + static const int FIELD___powerModeSleep = 9; + static const int FIELD___orientationPortrait = 10; + static const int FIELD___orientationPortrait180 = 11; + static const int FIELD___orientationLandscape = 12; + static const int FIELD___orientationLandscape180 = 13; + static const int FIELD___clear = 14; + static const int FIELD___brightness = 15; + static const int FIELD___defaultOrientation = 16; + static const int FIELD___setWindowType = 17; + + //--// +}; + struct Library_nanoFramework_Graphics_nanoFramework_UI_Ink { NANOCLR_NATIVE_DECLARE(SetInkRegion___STATIC__VOID__U4__I4__I4__I4__I4__I4__I4__I4__nanoFrameworkUIBitmap); @@ -906,19 +948,19 @@ struct Library_nanoFramework_Graphics_nanoFramework_UI_Input_ButtonDevice struct Library_nanoFramework_Graphics_nanoFramework_UI_Input_Buttons { - static const int FIELD_STATIC__PreviewButtonDownEvent = 23; - static const int FIELD_STATIC__PreviewButtonUpEvent = 24; - static const int FIELD_STATIC__ButtonDownEvent = 25; - static const int FIELD_STATIC__ButtonUpEvent = 26; - static const int FIELD_STATIC__GotFocusEvent = 27; - static const int FIELD_STATIC__LostFocusEvent = 28; + static const int FIELD_STATIC__PreviewButtonDownEvent = 22; + static const int FIELD_STATIC__PreviewButtonUpEvent = 23; + static const int FIELD_STATIC__ButtonDownEvent = 24; + static const int FIELD_STATIC__ButtonUpEvent = 25; + static const int FIELD_STATIC__GotFocusEvent = 26; + static const int FIELD_STATIC__LostFocusEvent = 27; //--// }; struct Library_nanoFramework_Graphics_nanoFramework_UI_Input_GenericEvents { - static const int FIELD_STATIC__GenericStandardEvent = 29; + static const int FIELD_STATIC__GenericStandardEvent = 28; //--// }; @@ -967,16 +1009,16 @@ struct Library_nanoFramework_Graphics_nanoFramework_UI_Input_RawTouchInputReport struct Library_nanoFramework_Graphics_nanoFramework_UI_Input_TouchCapture { - static const int FIELD_STATIC___captureElement = 30; + static const int FIELD_STATIC___captureElement = 29; //--// }; struct Library_nanoFramework_Graphics_nanoFramework_UI_Input_TouchEvents { - static const int FIELD_STATIC__TouchDownEvent = 31; - static const int FIELD_STATIC__TouchMoveEvent = 32; - static const int FIELD_STATIC__TouchUpEvent = 33; + static const int FIELD_STATIC__TouchDownEvent = 30; + static const int FIELD_STATIC__TouchMoveEvent = 31; + static const int FIELD_STATIC__TouchUpEvent = 32; //--// }; @@ -1008,39 +1050,39 @@ struct Library_nanoFramework_Graphics_nanoFramework_UI_Threading_DispatcherOpera struct Library_nanoFramework_Graphics_nanoFramework_UI_Threading_DispatcherTimer { - static const int FIELD__Tick = 1; - static const int FIELD___instanceLock = 2; - static const int FIELD___dispatcher = 3; - static const int FIELD___interval = 4; - static const int FIELD___tag = 5; - static const int FIELD___isEnabled = 6; - static const int FIELD___timer = 7; + static const int FIELD___instanceLock = 1; + static const int FIELD___dispatcher = 2; + static const int FIELD___interval = 3; + static const int FIELD___tag = 4; + static const int FIELD___isEnabled = 5; + static const int FIELD___timer = 6; + static const int FIELD__Tick = 7; //--// }; struct Library_nanoFramework_Graphics_nanoFramework_UI_Touch { - static const int FIELD_STATIC___initialized = 34; - static const int FIELD_STATIC___activeTouchPanel = 35; + static const int FIELD_STATIC___initialized = 33; + static const int FIELD_STATIC___activeTouchPanel = 34; //--// }; struct Library_nanoFramework_Graphics_nanoFramework_UI_TouchCollector { - static const int FIELD__lastTime = 1; - static const int FIELD___nativeBufferSize = 2; + static const int FIELD___nativeBufferSize = 1; + static const int FIELD__lastTime = 2; //--// }; struct Library_nanoFramework_Graphics_nanoFramework_UI_TouchCollectorConfiguration { - static const int FIELD_STATIC___collectionMode = 36; - static const int FIELD_STATIC___collectionMethod = 37; - static const int FIELD_STATIC___touchCollector = 38; - static const int FIELD_STATIC___collectionBufferSize = 39; + static const int FIELD_STATIC___collectionMode = 35; + static const int FIELD_STATIC___collectionMethod = 36; + static const int FIELD_STATIC___touchCollector = 37; + static const int FIELD_STATIC___collectionBufferSize = 38; NANOCLR_NATIVE_DECLARE(GetTouchPoints___STATIC__VOID__BYREF_I4__SZARRAY_I2__SZARRAY_I2); NANOCLR_NATIVE_DECLARE( diff --git a/src/nanoFramework.Graphics/Graphics/Native/nanoFramework_Graphics_nanoFramework_UI_Bitmap.cpp b/src/nanoFramework.Graphics/Graphics/Native/nanoFramework_Graphics_nanoFramework_UI_Bitmap.cpp index 82845de08b..3606a5dcc2 100644 --- a/src/nanoFramework.Graphics/Graphics/Native/nanoFramework_Graphics_nanoFramework_UI_Bitmap.cpp +++ b/src/nanoFramework.Graphics/Graphics/Native/nanoFramework_Graphics_nanoFramework_UI_Bitmap.cpp @@ -192,7 +192,7 @@ HRESULT Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::Clear___VOID(CLR } HRESULT Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap:: - DrawTextInRect___BOOLEAN__BYREF_STRING__BYREF_I4__BYREF_I4__I4__I4__I4__I4__U4__nanoFrameworkPresentationMediaColor__nanoFrameworkUIFont( + DrawTextInRect___BOOLEAN__BYREF_STRING__BYREF_I4__BYREF_I4__I4__I4__I4__I4__U4__U4__nanoFrameworkUIFont( CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); @@ -263,8 +263,8 @@ HRESULT Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap:: NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap:: - DrawChar___VOID__U2__I4__I4__nanoFrameworkPresentationMediaColor__nanoFrameworkUIFont(CLR_RT_StackFrame &stack) +HRESULT Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::DrawChar___VOID__U2__I4__I4__U4__nanoFrameworkUIFont( + CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); @@ -337,8 +337,7 @@ HRESULT Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::get_Height___I4( } HRESULT Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap:: - DrawEllipse___VOID__nanoFrameworkPresentationMediaColor__I4__I4__I4__I4__I4__nanoFrameworkPresentationMediaColor__I4__I4__nanoFrameworkPresentationMediaColor__I4__I4__U2( - CLR_RT_StackFrame &stack) + DrawEllipse___VOID__U4__I4__I4__I4__I4__I4__U4__I4__I4__U4__I4__I4__U2(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); @@ -456,8 +455,7 @@ HRESULT Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap:: NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap:: - MakeTransparent___VOID__nanoFrameworkPresentationMediaColor(CLR_RT_StackFrame &stack) +HRESULT Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::MakeTransparent___VOID__U4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); @@ -510,8 +508,8 @@ HRESULT Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap:: NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap:: - DrawLine___VOID__nanoFrameworkPresentationMediaColor__I4__I4__I4__I4__I4(CLR_RT_StackFrame &stack) +HRESULT Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::DrawLine___VOID__U4__I4__I4__I4__I4__I4( + CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); CLR_GFX_Bitmap *bitmap; @@ -534,8 +532,8 @@ HRESULT Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap:: NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap:: - DrawRectangle___VOID__I4__I4__I4__I4__I4__nanoFrameworkPresentationMediaColor(CLR_RT_StackFrame &stack) +HRESULT Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::DrawRectangle___VOID__I4__I4__I4__I4__I4__U4( + CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); @@ -566,7 +564,7 @@ HRESULT Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap:: } HRESULT Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap:: - DrawRoundRectangle___VOID__I4__I4__I4__I4__I4__I4__I4__nanoFrameworkPresentationMediaColor(CLR_RT_StackFrame &stack) + DrawRoundRectangle___VOID__I4__I4__I4__I4__I4__I4__I4__U4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); @@ -601,8 +599,8 @@ HRESULT Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap:: NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap:: - FillRectangle___VOID__I4__I4__I4__I4__nanoFrameworkPresentationMediaColor__U2(CLR_RT_StackFrame &stack) +HRESULT Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::FillRectangle___VOID__I4__I4__I4__I4__U4__U2( + CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); @@ -634,7 +632,7 @@ HRESULT Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap:: } HRESULT Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap:: - FillRoundRectangle___VOID__I4__I4__I4__I4__I4__I4__nanoFrameworkPresentationMediaColor__U2(CLR_RT_StackFrame &stack) + FillRoundRectangle___VOID__I4__I4__I4__I4__I4__I4__U4__U2(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); @@ -671,8 +669,7 @@ HRESULT Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap:: } HRESULT Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap:: - FillGradientRectangle___VOID__I4__I4__I4__I4__nanoFrameworkPresentationMediaColor__I4__I4__nanoFrameworkPresentationMediaColor__I4__I4__U2( - CLR_RT_StackFrame &stack) + FillGradientRectangle___VOID__I4__I4__I4__I4__U4__I4__I4__U4__I4__I4__U2(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); @@ -708,8 +705,7 @@ HRESULT Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap:: } HRESULT Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap:: - DrawRectangle___VOID__nanoFrameworkPresentationMediaColor__I4__I4__I4__I4__I4__I4__I4__nanoFrameworkPresentationMediaColor__I4__I4__nanoFrameworkPresentationMediaColor__I4__I4__U2( - CLR_RT_StackFrame &stack) + DrawRectangle___VOID__U4__I4__I4__I4__I4__I4__I4__I4__U4__I4__I4__U4__I4__I4__U2(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); CLR_RT_HeapBlock *pArgs; @@ -764,7 +760,7 @@ HRESULT Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap:: } HRESULT Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap:: - DrawText___VOID__STRING__nanoFrameworkUIFont__nanoFrameworkPresentationMediaColor__I4__I4(CLR_RT_StackFrame &stack) + DrawText___VOID__STRING__nanoFrameworkUIFont__U4__I4__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); CLR_RT_HeapBlock *pArgs; @@ -785,8 +781,7 @@ HRESULT Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap:: NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap:: - SetPixel___VOID__I4__I4__nanoFrameworkPresentationMediaColor(CLR_RT_StackFrame &stack) +HRESULT Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::SetPixel___VOID__I4__I4__U4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); CLR_GFX_Bitmap *bitmap; @@ -798,8 +793,7 @@ HRESULT Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap:: NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::GetPixel___nanoFrameworkPresentationMediaColor__I4__I4( - CLR_RT_StackFrame &stack) +HRESULT Library_nanoFramework_Graphics_nanoFramework_UI_Bitmap::GetPixelInt___U4__I4__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); CLR_GFX_Bitmap *bitmap; diff --git a/src/nanoFramework.Graphics/Graphics/Native/nanoFramework_Graphics_nanoFramework_UI_DisplayControl.cpp b/src/nanoFramework.Graphics/Graphics/Native/nanoFramework_Graphics_nanoFramework_UI_DisplayControl.cpp index 32dbbb90be..0a13c41555 100644 --- a/src/nanoFramework.Graphics/Graphics/Native/nanoFramework_Graphics_nanoFramework_UI_DisplayControl.cpp +++ b/src/nanoFramework.Graphics/Graphics/Native/nanoFramework_Graphics_nanoFramework_UI_DisplayControl.cpp @@ -10,6 +10,9 @@ #include "nanoHAL_Graphics.h" extern GraphicsDriver g_GraphicsDriver; +typedef Library_nanoFramework_Graphics_nanoFramework_UI_SpiConfiguration SpiConfiguration; +typedef Library_nanoFramework_Graphics_nanoFramework_UI_ScreenConfiguration ScreenConfiguration; +typedef Library_nanoFramework_Graphics_nanoFramework_UI_GraphicDriver GraphicDriver; HRESULT Library_nanoFramework_Graphics_nanoFramework_UI_DisplayControl::get_LongerSide___STATIC__I4( CLR_RT_StackFrame &stack) @@ -110,6 +113,7 @@ HRESULT Library_nanoFramework_Graphics_nanoFramework_UI_DisplayControl:: CLR_RT_HeapBlock *spiconfig; CLR_RT_HeapBlock *screenconfig; + CLR_RT_HeapBlock *graphicDriver; CLR_INT32 desired; // Initialise Graphics after devices initialised DisplayInterfaceConfig displayConfig; @@ -122,36 +126,53 @@ HRESULT Library_nanoFramework_Graphics_nanoFramework_UI_DisplayControl:: // Define SPI display configuration for the display // internally SPI bus ID is zero based, so better take care of that here - displayConfig.Spi.spiBus = - spiconfig[Library_nanoFramework_Graphics_nanoFramework_UI_SpiConfiguration::FIELD___spiBus].NumericByRef().u1 - - 1; - - displayConfig.Spi.chipSelect = - spiconfig[Library_nanoFramework_Graphics_nanoFramework_UI_SpiConfiguration::FIELD___chipSelect] - .NumericByRef() - .s4; - displayConfig.Spi.dataCommand = - spiconfig[Library_nanoFramework_Graphics_nanoFramework_UI_SpiConfiguration::FIELD___dataCommand] - .NumericByRef() - .s4; - displayConfig.Spi.reset = - spiconfig[Library_nanoFramework_Graphics_nanoFramework_UI_SpiConfiguration::FIELD___reset].NumericByRef().s4; - displayConfig.Spi.backLight = - spiconfig[Library_nanoFramework_Graphics_nanoFramework_UI_SpiConfiguration::FIELD___backLight] - .NumericByRef() - .s4; - displayConfig.Screen.x = - screenconfig[Library_nanoFramework_Graphics_nanoFramework_UI_ScreenConfiguration::FIELD___x].NumericByRef().u2; - displayConfig.Screen.y = - screenconfig[Library_nanoFramework_Graphics_nanoFramework_UI_ScreenConfiguration::FIELD___y].NumericByRef().u2; - displayConfig.Screen.width = - screenconfig[Library_nanoFramework_Graphics_nanoFramework_UI_ScreenConfiguration::FIELD___width] - .NumericByRef() - .u2; - displayConfig.Screen.height = - screenconfig[Library_nanoFramework_Graphics_nanoFramework_UI_ScreenConfiguration::FIELD___height] - .NumericByRef() - .u2; + displayConfig.Spi.spiBus = spiconfig[SpiConfiguration::FIELD___spiBus].NumericByRef().u1 - 1; + + displayConfig.Spi.chipSelect = spiconfig[SpiConfiguration::FIELD___chipSelect].NumericByRef().s4; + displayConfig.Spi.dataCommand = spiconfig[SpiConfiguration::FIELD___dataCommand].NumericByRef().s4; + displayConfig.Spi.reset = spiconfig[SpiConfiguration::FIELD___reset].NumericByRef().s4; + displayConfig.Spi.backLight = spiconfig[SpiConfiguration::FIELD___backLight].NumericByRef().s4; + displayConfig.Screen.x = screenconfig[ScreenConfiguration::FIELD___x].NumericByRef().u2; + displayConfig.Screen.y = screenconfig[ScreenConfiguration::FIELD___y].NumericByRef().u2; + displayConfig.Screen.width = screenconfig[ScreenConfiguration::FIELD___width].NumericByRef().u2; + displayConfig.Screen.height = screenconfig[ScreenConfiguration::FIELD___height].NumericByRef().u2; + graphicDriver = screenconfig[ScreenConfiguration::FIELD___graphicDriver].Dereference(); + + if (graphicDriver != NULL) + { + displayConfig.GenericDriverCommands.Width = graphicDriver[GraphicDriver::FIELD___width].NumericByRef().u4; + displayConfig.GenericDriverCommands.Height = graphicDriver[GraphicDriver::FIELD___height].NumericByRef().u4; + displayConfig.GenericDriverCommands.BitsPerPixel = + graphicDriver[GraphicDriver::FIELD___initializationSequence].NumericByRef().u1; + displayConfig.GenericDriverCommands.InitializationSequence = + graphicDriver[GraphicDriver::FIELD___initializationSequence].DereferenceArray(); + displayConfig.GenericDriverCommands.MemoryWrite = + graphicDriver[GraphicDriver::FIELD___memoryWrite].NumericByRef().u1; + displayConfig.GenericDriverCommands.SetColumnAddress = + graphicDriver[GraphicDriver::FIELD___setColumnAddress].NumericByRef().u1; + displayConfig.GenericDriverCommands.SetRowAddress = + graphicDriver[GraphicDriver::FIELD___setRowAddress].NumericByRef().u1; + displayConfig.GenericDriverCommands.PowerModeNormal = + graphicDriver[GraphicDriver::FIELD___powerModeNormal].DereferenceArray(); + displayConfig.GenericDriverCommands.PowerModeSleep = + graphicDriver[GraphicDriver::FIELD___powerModeSleep].DereferenceArray(); + displayConfig.GenericDriverCommands.OrientationPortrait = + graphicDriver[GraphicDriver::FIELD___orientationPortrait].DereferenceArray(); + displayConfig.GenericDriverCommands.OrientationPortrait180 = + graphicDriver[GraphicDriver::FIELD___orientationPortrait180].DereferenceArray(); + displayConfig.GenericDriverCommands.OrientationLandscape = + graphicDriver[GraphicDriver::FIELD___orientationLandscape].DereferenceArray(); + displayConfig.GenericDriverCommands.OrientationLandscape180 = + graphicDriver[GraphicDriver::FIELD___orientationLandscape180].DereferenceArray(); + displayConfig.GenericDriverCommands.Clear = graphicDriver[GraphicDriver::FIELD___clear].DereferenceArray(); + displayConfig.GenericDriverCommands.Brightness = + graphicDriver[GraphicDriver::FIELD___brightness].NumericByRef().u1; + displayConfig.GenericDriverCommands.DefaultOrientation = + (CLR_UINT8)graphicDriver[GraphicDriver::FIELD___defaultOrientation].NumericByRef().s4; + displayConfig.GenericDriverCommands.SetWindowType = + (CLR_UINT8)graphicDriver[GraphicDriver::FIELD___setWindowType].NumericByRef().s4; + } + g_DisplayInterface.Initialize(displayConfig); g_DisplayDriver.Initialize(); @@ -185,8 +206,7 @@ HRESULT Library_nanoFramework_Graphics_nanoFramework_UI_DisplayControl:: } HRESULT Library_nanoFramework_Graphics_nanoFramework_UI_DisplayControl:: - Write___STATIC__VOID__STRING__U2__U2__U2__U2__nanoFrameworkUIFont__nanoFrameworkPresentationMediaColor__nanoFrameworkPresentationMediaColor( - CLR_RT_StackFrame &stack) + Write___STATIC__VOID__STRING__U2__U2__U2__U2__nanoFrameworkUIFont__U4__U4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); { diff --git a/src/nanoFramework.Graphics/Graphics/Native/nanoFramework_Graphics_nanoFramework_UI_Font.cpp b/src/nanoFramework.Graphics/Graphics/Native/nanoFramework_Graphics_nanoFramework_UI_Font.cpp index f88b509284..1a4e57de72 100644 --- a/src/nanoFramework.Graphics/Graphics/Native/nanoFramework_Graphics_nanoFramework_UI_Font.cpp +++ b/src/nanoFramework.Graphics/Graphics/Native/nanoFramework_Graphics_nanoFramework_UI_Font.cpp @@ -7,6 +7,42 @@ #include "Graphics.h" #include "nanoFramework_Graphics.h" +// Used internally by DrawText and DrawTextInRect +HRESULT Library_nanoFramework_Graphics_nanoFramework_UI_Font::GetFont(CLR_RT_HeapBlock *pThis, CLR_GFX_Font *&font) +{ + NANOCLR_HEADER(); + + CLR_RT_HeapBlock_BinaryBlob *blob; + + if (pThis) + pThis = pThis->Dereference(); + FAULT_ON_NULL(pThis); + +#if defined(NANOCLR_APPDOMAINS) + if (pThis->DataType() == DATATYPE_TRANSPARENT_PROXY) + { + NANOCLR_CHECK_HRESULT(pThis->TransparentProxyValidate()); + pThis = pThis->TransparentProxyDereference(); + } +#endif + + blob = pThis[CLR_GFX_Font::FIELD__m_font].DereferenceBinaryBlob(); + + if (!blob || blob->DataType() != DATATYPE_BINARY_BLOB_HEAD) + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + + font = (CLR_GFX_Font *)blob->GetData(); + + NANOCLR_NOCLEANUP(); +} + +// TODO: ? Internally used by DrawTextInRect + +HRESULT Library_nanoFramework_Graphics_nanoFramework_UI_Font::GetFont(CLR_RT_StackFrame &stack, CLR_GFX_Font *&font) +{ + return GetFont(&stack.Arg0(), font); +} + HRESULT Library_nanoFramework_Graphics_nanoFramework_UI_Font::CharWidth___I4__CHAR(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); @@ -198,39 +234,3 @@ HRESULT Library_nanoFramework_Graphics_nanoFramework_UI_Font:: NANOCLR_NOCLEANUP(); } - -// Used internally by DrawText and DrawTextInRect -HRESULT Library_nanoFramework_Graphics_nanoFramework_UI_Font::GetFont(CLR_RT_HeapBlock *pThis, CLR_GFX_Font *&font) -{ - NANOCLR_HEADER(); - - CLR_RT_HeapBlock_BinaryBlob *blob; - - if (pThis) - pThis = pThis->Dereference(); - FAULT_ON_NULL(pThis); - -#if defined(NANOCLR_APPDOMAINS) - if (pThis->DataType() == DATATYPE_TRANSPARENT_PROXY) - { - NANOCLR_CHECK_HRESULT(pThis->TransparentProxyValidate()); - pThis = pThis->TransparentProxyDereference(); - } -#endif - - blob = pThis[CLR_GFX_Font::FIELD__m_font].DereferenceBinaryBlob(); - - if (!blob || blob->DataType() != DATATYPE_BINARY_BLOB_HEAD) - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - - font = (CLR_GFX_Font *)blob->GetData(); - - NANOCLR_NOCLEANUP(); -} - -// TODO: ? Internally used by DrawTextInRect - -HRESULT Library_nanoFramework_Graphics_nanoFramework_UI_Font::GetFont(CLR_RT_StackFrame &stack, CLR_GFX_Font *&font) -{ - return GetFont(&stack.Arg0(), font); -} diff --git a/src/nanoFramework.Graphics/TouchPanel/Devices/STMPE811QTR_I2C.cpp b/src/nanoFramework.Graphics/TouchPanel/Devices/STMPE811QTR_I2C.cpp new file mode 100644 index 0000000000..f89c1214b2 --- /dev/null +++ b/src/nanoFramework.Graphics/TouchPanel/Devices/STMPE811QTR_I2C.cpp @@ -0,0 +1,110 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Portions Copyright (c) Microsoft Corporation. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +// For a FT6206 by Focal Tech. ( Originally developed for the STM32F79iDiscovery board + +#ifndef stmpe811qtr_H +#define stmpe811qtr_H + +#include "TouchDevice.h" +#include "TouchInterface.h" + +struct TouchDevice g_TouchDevice; +extern TouchInterface g_TouchInterface; + +#define STMPE811QTR_ID_VALUE 0x11 +#define STMPE811QTR_CHIP_ID_REG 0xA8 + +#define STMPE811QTR_GMODE_REG (CLR_UINT8)0xA4 +#define STMPE811QTR_G_MODE_INTERRUPT_TRIGGER (CLR_UINT8)0x01 +#define STMPE811QTR_G_MODE_INTERRUPT_POLLING (CLR_UINT8)0x00 +#define STMPE811QTR_G_MODE_INTERRUPT_MASK (CLR_UINT8)0x03 +#define STMPE811QTR_G_MODE_INTERRUPT_SHIFT (CLR_UINT8)0x00 +#define STMPE811QTR_TD_STAT_REG (CLR_UINT8)0x02 +#define STMPE811QTR_TD_STAT_MASK (CLR_UINT8)0x0F +#define STMPE811QTR_MSB_MASK (CLR_UINT8)0x0F +#define STMPE811QTR_LSB_MASK (CLR_UINT8)0xFF + +#define STMPE811QTR_P1_XH_REG (CLR_UINT8)0x03 +#define STMPE811QTR_P2_XH_REG (CLR_UINT8)0x09 + +#define I2C_MEMADD_SIZE_8BIT (0x00000001U) + +bool TouchDevice::Initialize() +{ + /* + // Read the ID for confirmation + CLR_UINT8 chipIdRegister; + chipIdRegister = STMPE811QTR_CHIP_ID_REG; + CLR_UINT8 *id; + CLR_UINT16 numberValuesExpected = 1; + id = g_TouchInterface.Write_Read(&chipIdRegister, 1, numberValuesExpected); + bool result = (*id == STMPE811QTR_ID_VALUE); + return result; + */ + return false; +} + +bool TouchDevice::Enable(GPIO_INTERRUPT_SERVICE_ROUTINE touchIsrProc) +{ + (void)touchIsrProc; + + /* + // Connect the Interrupt Service routine to the interrupt pin + // G3# - PI13 ( GPIOI_LCD_INT ) + GPIO_PIN STMPE811QTR_Interrupt = GPIOI_LCD_INT; + PinMode driveMode = PinMode_Input; + GPIO_INT_EDGE IntEdge = GPIO_INT_EDGE_HIGH; + void *ISR_Param = NULL; + if (CPU_GPIO_ReservePin(GPIOI_LCD_INT, true)) + { + if (CPU_GPIO_EnableInputPin(STMPE811QTR_Interrupt, 0, touchIsrProc, ISR_Param, IntEdge, driveMode)) + { + // Configure the device to generate IT on given INT pin connected to MCU as EXTI. + uint8_t regValue = 0; + regValue = + (STMPE811QTR_G_MODE_INTERRUPT_TRIGGER & (STMPE811QTR_G_MODE_INTERRUPT_MASK >> + STMPE811QTR_G_MODE_INTERRUPT_SHIFT)) + << STMPE811QTR_G_MODE_INTERRUPT_SHIFT; + CLR_UINT8 values[2] = {STMPE811QTR_GMODE_REG, regValue}; + g_TouchInterface.Write_Read(values, 2, 0); + } + } + */ + return TRUE; +} + +bool TouchDevice::Disable() +{ + /* + // Configure the device to stop generating IT on the given INT pin connected to MCU as EXTI. + CLR_UINT8 regValue = + (STMPE811QTR_G_MODE_INTERRUPT_POLLING & (STMPE811QTR_G_MODE_INTERRUPT_MASK >> + STMPE811QTR_G_MODE_INTERRUPT_SHIFT)) + << STMPE811QTR_G_MODE_INTERRUPT_SHIFT; + CLR_UINT8 values[2] = {STMPE811QTR_GMODE_REG, regValue}; + g_TouchInterface.Write_Read(values, 2, 0); + */ + return true; +} + +TouchPointDevice TouchDevice::GetPoint() +{ + TouchPointDevice t; + /* + CLR_UINT8 regAddress; + regAddress = STMPE811QTR_P1_XH_REG; + CLR_UINT8 *dataxy; + CLR_UINT16 numberValuesExpected = 4; + + dataxy = g_TouchInterface.Write_Read(®Address, 1, numberValuesExpected); + t.x = ((dataxy[0] & STMPE811QTR_MSB_MASK) << 8) | (dataxy[1] & STMPE811QTR_LSB_MASK); + t.y = ((dataxy[2] & STMPE811QTR_MSB_MASK) << 8) | (dataxy[3] & STMPE811QTR_LSB_MASK); + */ + return t; +} + +#endif // stmpe811qtr_H diff --git a/targets-community b/targets-community index 23f0648625..3880275e02 160000 --- a/targets-community +++ b/targets-community @@ -1 +1 @@ -Subproject commit 23f0648625721cfdfb68294b5c2482d93249c0bb +Subproject commit 3880275e025fbe492573aae38247319a8ddf2444 diff --git a/targets/AzureRTOS/CMakeLists.txt b/targets/AzureRTOS/CMakeLists.txt index 3cd6188276..5ea7614fc2 100644 --- a/targets/AzureRTOS/CMakeLists.txt +++ b/targets/AzureRTOS/CMakeLists.txt @@ -14,6 +14,7 @@ option(AZURERTOS_USBX_REQUIRED "option to include Azure RTOS USBX") option(AZURERTOS_FILEX_REQUIRED "option to include Azure RTOS FileX") option(AZURERTOS_NETXDUO_REQUIRED "option to include Azure RTOS NetX Duo") option(USBX_FEATURE_CDC "option to use USBX CDC class") +option(USBX_FEATURE_HID "option to use USBX HID class") if(USBX_FEATURE_CDC) @@ -30,6 +31,21 @@ else() set(USBX_FEATURE_CDC_OPTION FALSE CACHE INTERNAL "USBX_FEATURE_CDC_OPTION for USBX_FEATURE_CDC") endif() +if(USBX_FEATURE_HID) + + set(USBX_FEATURE_HID_OPTION TRUE CACHE INTERNAL "USBX_FEATURE_HID_OPTION for USBX_FEATURE_HID") + # requires: + # AZURERTOS_USBX_REQUIRED + set(AZURERTOS_USBX_REQUIRED ON CACHE INTERNAL "AZURERTOS_USBX_REQUIRED for USBX_FEATURE_HID") + # AZURERTOS_FILEX_REQUIRED + set(AZURERTOS_FILEX_REQUIRED ON CACHE INTERNAL "AZURERTOS_FILEX_REQUIRED for USBX_FEATURE_HID") + # AZURERTOS_NETXDUO_REQUIRED + set(AZURERTOS_NETXDUO_REQUIRED ON CACHE INTERNAL "AZURERTOS_NETXDUO_REQUIRED for USBX_FEATURE_HID") + +else() + set(USBX_FEATURE_HID_OPTION FALSE CACHE INTERNAL "USBX_FEATURE_HID_OPTION for USBX_FEATURE_HID") +endif() + if(USE_NETWORKING_OPTION) set(AZURERTOS_NETXDUO_REQUIRED ON CACHE INTERNAL "AZURERTOS_NETXDUO_REQUIRED for Networking") endif() @@ -60,7 +76,8 @@ endif() # check if build was requested with a specifc AzureRTOS version if(RTOS_VERSION_EMPTY) # no AzureRTOS version actualy specified, must be empty which is fine, we'll default to a known good version - set(RTOS_VERSION "v6.1.12_rel") + # WHEN CHANGING THIS MAKE SURE TO UPDATE THE DEV CONTAINERS + set(RTOS_VERSION "v6.2.0_rel") endif() if(NO_AZURERTOS_SOURCE_FOLDER) @@ -83,7 +100,7 @@ else() FetchContent_Declare( azure_rtos - SOURCE_DIR $(AZURERTOS_SOURCE_FOLDER) + SOURCE_DIR ${AZURERTOS_SOURCE_FOLDER} ) else() @@ -129,7 +146,8 @@ if(AZURERTOS_USBX_REQUIRED) FetchContent_Declare( azure_rtos_usbx - SOURCE_DIR https://github.com/azure-rtos/usbx.git + GIT_REPOSITORY https://github.com/azure-rtos/usbx.git + GIT_TAG ${RTOS_VERSION} ) else() @@ -141,7 +159,7 @@ if(AZURERTOS_USBX_REQUIRED) FetchContent_Declare( azure_rtos_usbx - SOURCE_DIR $(USBX_SOURCE_FOLDER) + SOURCE_DIR ${USBX_SOURCE_FOLDER} ) else() @@ -202,7 +220,7 @@ if(AZURERTOS_FILEX_REQUIRED) FetchContent_Declare( azure_rtos_filex - SOURCE_DIR $(FILEX_SOURCE_FOLDER) + SOURCE_DIR ${FILEX_SOURCE_FOLDER} ) else() @@ -263,7 +281,7 @@ if(AZURERTOS_NETXDUO_REQUIRED) FetchContent_Declare( azure_rtos_netxduo - SOURCE_DIR $(NETXDUO_SOURCE_FOLDER) + SOURCE_DIR ${NETXDUO_SOURCE_FOLDER} ) else() @@ -360,6 +378,20 @@ elseif(EXISTS ${PROJECT_SOURCE_DIR}/targets/AzureRTOS/Maxim/${TARGET_BOARD}) set(TARGET_VENDOR Maxim) +# try to find SiliconLabs board in the targets folder +elseif(EXISTS ${PROJECT_SOURCE_DIR}/targets/AzureRTOS/SiliconLabs/${TARGET_BOARD}) + + # board found + message(STATUS "Support for target board '${TARGET_BOARD}' found") + + # Define base path for the class libraries + nf_set_base_path_for_libraries_modules(${PROJECT_SOURCE_DIR}/targets/AzureRTOS/SiliconLabs/_nanoCLR) + + # set target base location + set(TARGET_BASE_LOCATION ${PROJECT_SOURCE_DIR}/targets/AzureRTOS/SiliconLabs/${TARGET_BOARD}) + + set(TARGET_VENDOR SiliconLabs) + else() # try to find STM board in the Community targets folder diff --git a/targets/AzureRTOS/CMakePresets.json b/targets/AzureRTOS/CMakePresets.json new file mode 100644 index 0000000000..ab39adbdc8 --- /dev/null +++ b/targets/AzureRTOS/CMakePresets.json @@ -0,0 +1,8 @@ +{ + "version": 4, + "include": [ + "SiliconLabs/SL_STK3701A/CMakePresets.json", + "ST/ORGPAL_PALTHREE/CMakePresets.json", + "ST/ST_B_L475E_IOT01A/CMakePresets.json" + ] +} diff --git a/targets/AzureRTOS/ChibiOS/osal.h b/targets/AzureRTOS/ChibiOS/osal.h index 9f83e9fe7c..74d48ef57e 100644 --- a/targets/AzureRTOS/ChibiOS/osal.h +++ b/targets/AzureRTOS/ChibiOS/osal.h @@ -150,7 +150,7 @@ typedef int32_t msg_t; /** * @brief Type of system time counter. */ -typedef uint32_t systime_t; +typedef uint64_t systime_t; /** * @brief Type of system time interval. diff --git a/targets/AzureRTOS/Maxim/_nanoCLR/targetHAL.cpp b/targets/AzureRTOS/Maxim/_nanoCLR/targetHAL.cpp index cd924c21f7..3cd2dcfc2e 100644 --- a/targets/AzureRTOS/Maxim/_nanoCLR/targetHAL.cpp +++ b/targets/AzureRTOS/Maxim/_nanoCLR/targetHAL.cpp @@ -40,9 +40,9 @@ extern "C" nanoHAL_Initialize(); } - void nanoHAL_Uninitialize_C() + void nanoHAL_Uninitialize_C(bool isPoweringDown) { - nanoHAL_Uninitialize(); + nanoHAL_Uninitialize(isPoweringDown); } } @@ -161,8 +161,10 @@ void nanoHAL_Initialize() Network_Initialize(); } -void nanoHAL_Uninitialize() +void nanoHAL_Uninitialize(bool isPoweringDown) { + (void)isPoweringDown; + // release the global mutex, just in case it's locked somewhere // chMtxUnlock(&interpreterGlobalMutex); diff --git a/targets/AzureRTOS/Maxim/_nanoCLR/targetHAL_Power.c b/targets/AzureRTOS/Maxim/_nanoCLR/targetHAL_Power.c index 2a2faad818..007c416889 100644 --- a/targets/AzureRTOS/Maxim/_nanoCLR/targetHAL_Power.c +++ b/targets/AzureRTOS/Maxim/_nanoCLR/targetHAL_Power.c @@ -46,7 +46,7 @@ void CPU_SetPowerMode(PowerLevel_type powerLevel) // wdgStop(&WDGD1); // gracefully shutdown everything - nanoHAL_Uninitialize_C(); + nanoHAL_Uninitialize_C(true); // chSysDisable(); // disable interrupts @@ -59,9 +59,9 @@ void CPU_SetPowerMode(PowerLevel_type powerLevel) // set power control register to: power down deep sleep ///////////////////////////////////////////////////// - // TODO + // TODO // need review here to use ST HAL HAL_PWREx_EnterSTOP2Mode - + // set SLEEPDEEP bit of Cortex SCR SCB->SCR |= (uint32_t)SCB_SCR_SLEEPDEEP_Msk; diff --git a/targets/AzureRTOS/ST/CMakeLists.txt b/targets/AzureRTOS/ST/CMakeLists.txt index 854f66ed83..a0a49cfdcd 100644 --- a/targets/AzureRTOS/ST/CMakeLists.txt +++ b/targets/AzureRTOS/ST/CMakeLists.txt @@ -46,7 +46,7 @@ if(NO_CHIBIOS_HAL_SOURCE) FetchContent_Declare( chibios - SVN_REPOSITORY https://svn.osdn.net/svnroot/chibios/branches/${CHIBIOS_HAL_VERSION} + SVN_REPOSITORY http://svn.code.sf.net/p/chibios/code/branches/${CHIBIOS_HAL_VERSION} SVN_REVISION -rHEAD ) @@ -65,7 +65,7 @@ else() else() # running on *nix requires setting up a local git repo from SVN - # with git svn clone https://svn.osdn.net/svnroot/chibios/branches/${CHIBIOS_HAL_VERSION} -rHEAD + # with git svn clone http://svn.code.sf.net/p/chibios/code/branches/${CHIBIOS_HAL_VERSION} -rHEAD message(STATUS "ChibiOS HAL is: ${CHIBIOS_HAL_VERSION} (source from: ${CHIBIOS_HAL_SOURCE})") FetchContent_Declare( diff --git a/targets/AzureRTOS/ST/ORGPAL_PALTHREE/CMakePresets.json b/targets/AzureRTOS/ST/ORGPAL_PALTHREE/CMakePresets.json new file mode 100644 index 0000000000..b0323749d2 --- /dev/null +++ b/targets/AzureRTOS/ST/ORGPAL_PALTHREE/CMakePresets.json @@ -0,0 +1,55 @@ +{ + "version": 4, + "include": [ + "../../../../CMake/arm-gcc.json", + "../../../../config/user-tools-repos.json", + "../../../../config/user-prefs.json" + ], + "configurePresets": [ + { + "name": "ORGPAL_PALTHREE_AZRT", + "inherits": [ + "arm-gcc-cortex-preset", + "user-tools-repos", + "user-prefs" + ], + "hidden": false, + "cacheVariables": { + "TARGET_BOARD": "${presetName}", + "TARGET_SERIES": "STM32F7xx", + "RTOS": "AzureRTOS", + "STM32_CUBE_PACKAGE_REQUIRED": "ON", + "SUPPORT_ANY_BASE_CONVERSION": "ON", + "NF_FEATURE_DEBUGGER": "ON", + "NF_FEATURE_RTC": "ON", + "NF_FEATURE_HAS_SDCARD": "ON", + "NF_FEATURE_HAS_CONFIG_BLOCK": "ON", + "NF_FEATURE_HAS_USB_MSD": "OFF", + "NF_FEATURE_USE_SPIFFS": "OFF", + "NF_BUILD_RTM": "OFF", + "API_System.Math": "ON", + "API_Hardware.Stm32": "ON", + "API_System.Device.Gpio": "ON", + "API_System.Device.Spi": "ON", + "API_System.Device.I2c": "ON", + "API_System.Device.Pwm": "ON", + "API_System.IO.Ports": "ON", + "API_System.Device.Adc": "ON", + "API_System.Device.Dac": "ON", + "API_System.Net": "ON", + "API_nanoFramework.ResourceManager": "ON", + "API_nanoFramework.System.Collections": "ON", + "API_nanoFramework.System.Text": "ON", + "API_nanoFramework.Graphics": "OFF" + } + } + ], + "buildPresets": [ + { + "inherits": "base-user", + "name": "ORGPAL_PALTHREE_AZRT", + "displayName": "ORGPAL_PALTHREE_AZRT", + "configurePreset": "ORGPAL_PALTHREE_AZRT" + } + ] +} diff --git a/targets/AzureRTOS/ST/ORGPAL_PALTHREE/README.md b/targets/AzureRTOS/ST/ORGPAL_PALTHREE/README.md index 4da33eaf93..4edf49c1ae 100644 --- a/targets/AzureRTOS/ST/ORGPAL_PALTHREE/README.md +++ b/targets/AzureRTOS/ST/ORGPAL_PALTHREE/README.md @@ -1,33 +1,3 @@ -## Configuration of ChibiOS, HAL and MCU - -For a successful build the following changes are required: - -For memory maps, uuid etc. the reference document used was: http://www.st.com/content/ccc/resource/technical/document/reference_manual/group0/96/8b/0d/ec/16/22/43/71/DM00224583/files/DM00224583.pdf/jcr:content/translations/en.DM00224583.pdf - -In _halconf.g_ (in both nanoBooter and nanoCLR folders), when compared with a default file available from (https://github.com/ChibiOS/ChibiOS/tree/master/demos/STM32/RT-STM32F769I-DISCOVERY): -- HAL_USE_SERIAL_USB to TRUE -- HAL_USE_USB to TRUE -- SERIAL_DEFAULT_BITRATE to 921600 - -In _mcuconf.h_ (in both nanoBooter and nanoCLR folders), when compared with a default file available from (https://github.com/ChibiOS/ChibiOS/tree/master/demos/STM32/RT-STM32F769I-DISCOVERY): -- STM32_SERIAL_USE_USART2 to TRUE -- STM32_USB_USE_OTG1 to TRUE - -NOTE: this configuration was successfully tested in an ST_STM32F769I_DISCOVERY board using the Serial over USB connection on USB port 1 that creates a virtual COM port. - -## ADC configurations - -The following ADC channels (and respective GPIO pins) are available to the managed API, in the respective index: -- PA6, ADC1 IN6 -- PA4 ADC1 IN4 -- PC2 ADC1 IN12 -- PF10 ADC1 IN8 -- PF8 ADC3 IN6 -- PB8 ADC3 IN7 -- Temp Sensor ADC1 -- VrefInt ADC1 -- Vbatt ADC1 - ## Floating point The current build is set to add support for single-precision floating point. diff --git a/targets/AzureRTOS/ST/ORGPAL_PALTHREE/mbedtls_config.h b/targets/AzureRTOS/ST/ORGPAL_PALTHREE/mbedtls_config.h index 8e6da134b1..c4eefe58db 100644 --- a/targets/AzureRTOS/ST/ORGPAL_PALTHREE/mbedtls_config.h +++ b/targets/AzureRTOS/ST/ORGPAL_PALTHREE/mbedtls_config.h @@ -38,7 +38,7 @@ // uncomment the defines bellow to generate debug output // set below the threshold level for debug messages -// check mbed TLS mbedtls/debug.h header for details. +// check Mbed TLS mbedtls/debug.h header for details. // Debug levels: // 0 No debug // 1 Error diff --git a/targets/AzureRTOS/ST/ORGPAL_PALTHREE/nanoBooter/chconf.h b/targets/AzureRTOS/ST/ORGPAL_PALTHREE/nanoBooter/chconf.h index 7d04091405..f9a89f619c 100644 --- a/targets/AzureRTOS/ST/ORGPAL_PALTHREE/nanoBooter/chconf.h +++ b/targets/AzureRTOS/ST/ORGPAL_PALTHREE/nanoBooter/chconf.h @@ -70,7 +70,7 @@ * @note Allowed values are 16, 32 or 64 bits. */ #if !defined(CH_CFG_INTERVALS_SIZE) -#define CH_CFG_INTERVALS_SIZE 32 +#define CH_CFG_INTERVALS_SIZE 64 #endif /** @@ -178,7 +178,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_TIMESTAMP) -#define CH_CFG_USE_TIMESTAMP FALSE +#define CH_CFG_USE_TIMESTAMP TRUE #endif /** diff --git a/targets/AzureRTOS/ST/ORGPAL_PALTHREE/nanoBooter/halconf.h b/targets/AzureRTOS/ST/ORGPAL_PALTHREE/nanoBooter/halconf.h index 72a00564d8..ed9abd6601 100644 --- a/targets/AzureRTOS/ST/ORGPAL_PALTHREE/nanoBooter/halconf.h +++ b/targets/AzureRTOS/ST/ORGPAL_PALTHREE/nanoBooter/halconf.h @@ -21,7 +21,7 @@ #define HALCONF_H #define _CHIBIOS_HAL_CONF_ -#define _CHIBIOS_HAL_CONF_VER_8_0_ +#define _CHIBIOS_HAL_CONF_VER_8_4_ #include "mcuconf.h" diff --git a/targets/AzureRTOS/ST/ORGPAL_PALTHREE/nanoCLR/chconf.h b/targets/AzureRTOS/ST/ORGPAL_PALTHREE/nanoCLR/chconf.h index 0f0f0988cf..1b2c67d18e 100644 --- a/targets/AzureRTOS/ST/ORGPAL_PALTHREE/nanoCLR/chconf.h +++ b/targets/AzureRTOS/ST/ORGPAL_PALTHREE/nanoCLR/chconf.h @@ -70,7 +70,7 @@ * @note Allowed values are 16, 32 or 64 bits. */ #if !defined(CH_CFG_INTERVALS_SIZE) -#define CH_CFG_INTERVALS_SIZE 32 +#define CH_CFG_INTERVALS_SIZE 64 #endif /** @@ -178,7 +178,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_TIMESTAMP) -#define CH_CFG_USE_TIMESTAMP FALSE +#define CH_CFG_USE_TIMESTAMP TRUE #endif /** diff --git a/targets/AzureRTOS/ST/ORGPAL_PALTHREE/nanoCLR/halconf.h b/targets/AzureRTOS/ST/ORGPAL_PALTHREE/nanoCLR/halconf.h index d981c41e0d..5124644861 100644 --- a/targets/AzureRTOS/ST/ORGPAL_PALTHREE/nanoCLR/halconf.h +++ b/targets/AzureRTOS/ST/ORGPAL_PALTHREE/nanoCLR/halconf.h @@ -21,7 +21,7 @@ #define HALCONF_H #define _CHIBIOS_HAL_CONF_ -#define _CHIBIOS_HAL_CONF_VER_8_0_ +#define _CHIBIOS_HAL_CONF_VER_8_4_ #include #include "mcuconf.h" diff --git a/targets/AzureRTOS/ST/ORGPAL_PALTHREE/target_system_device_pwm_config.cpp b/targets/AzureRTOS/ST/ORGPAL_PALTHREE/target_system_device_pwm_config.cpp new file mode 100644 index 0000000000..73cc6666d3 --- /dev/null +++ b/targets/AzureRTOS/ST/ORGPAL_PALTHREE/target_system_device_pwm_config.cpp @@ -0,0 +1,9 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS BLANK ON PURPOSE BECAUSE THIS TARGET DOESN'T REQUIRE THIS SPECIFIC CONFIGURATION // +/////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/targets/AzureRTOS/ST/ST_B_L475E_IOT01A/CMakePresets.json b/targets/AzureRTOS/ST/ST_B_L475E_IOT01A/CMakePresets.json new file mode 100644 index 0000000000..e844ce1242 --- /dev/null +++ b/targets/AzureRTOS/ST/ST_B_L475E_IOT01A/CMakePresets.json @@ -0,0 +1,63 @@ +{ + "version": 4, + "include": [ + "../../../../CMake/arm-gcc.json", + "../../../../config/user-tools-repos.json", + "../../../../config/user-prefs.json" + ], + "configurePresets": [ + { + "name": "ST_B_L475E_IOT01A", + "inherits": [ + "arm-gcc-cortex-preset", + "user-tools-repos", + "user-prefs" + ], + "hidden": false, + "cacheVariables": { + "TARGET_BOARD": "${presetName}", + "RTOS": "AzureRTOS", + "TARGET_SERIES": "STM32L4xx", + "CHIBIOS_CONTRIB_REQUIRED": "OFF", + "STM32_CUBE_PACKAGE_REQUIRED": "ON", + "CHIBIOS_HAL_REQUIRED": "ON", + "WIFI_DRIVER": "ISM43362", + "SUPPORT_ANY_BASE_CONVERSION": "OFF", + "NF_PLATFORM_NO_CLR_TRACE": "ON", + "NF_CLR_NO_IL_INLINE": "ON", + "NF_FEATURE_DEBUGGER": "ON", + "NF_FEATURE_RTC": "ON", + "NF_FEATURE_HAS_SDCARD": "OFF", + "NF_FEATURE_HAS_CONFIG_BLOCK": "ON", + "SWO_OUTPUT": "OFF", + "NF_BUILD_RTM": "OFF", + "API_System.Math": "OFF", + "API_Hardware.Stm32": "OFF", + "API_System.Device.Gpio": "ON", + "API_System.Device.Spi": "ON", + "API_System.Device.I2c": "OFF", + "API_System.Device.Pwm": "OFF", + "API_System.IO.Ports": "ON", + "API_System.Device.Adc": "OFF", + "API_System.Device.Dac": "OFF", + "API_System.Net": "ON", + "API_System.Device.Wifi": "ON", + "API_nanoFramework.Device.OneWire": "OFF", + "API_nanoFramework.Devices.Can": "OFF", + "API_nanoFramework.ResourceManager": "OFF", + "API_nanoFramework.System.Collections": "ON", + "API_nanoFramework.System.Text": "ON", + "API_Windows.Storage": "OFF", + "API_nanoFramework.Graphics": "OFF" + } + } + ], + "buildPresets": [ + { + "inherits": "base-user", + "name": "ST_B_L475E_IOT01A", + "displayName": "ST_B_L475E_IOT01A", + "configurePreset": "ST_B_L475E_IOT01A" + } + ] +} diff --git a/targets/AzureRTOS/ST/ST_B_L475E_IOT01A/nanoBooter/halconf.h b/targets/AzureRTOS/ST/ST_B_L475E_IOT01A/nanoBooter/halconf.h index 707dcc675c..61d3576a8d 100644 --- a/targets/AzureRTOS/ST/ST_B_L475E_IOT01A/nanoBooter/halconf.h +++ b/targets/AzureRTOS/ST/ST_B_L475E_IOT01A/nanoBooter/halconf.h @@ -21,7 +21,7 @@ #define HALCONF_H #define _CHIBIOS_HAL_CONF_ -#define _CHIBIOS_HAL_CONF_VER_8_0_ +#define _CHIBIOS_HAL_CONF_VER_8_4_ #include "mcuconf.h" diff --git a/targets/AzureRTOS/ST/ST_B_L475E_IOT01A/nanoCLR/halconf.h b/targets/AzureRTOS/ST/ST_B_L475E_IOT01A/nanoCLR/halconf.h index 96d7c56ce5..1cc1d4b88b 100644 --- a/targets/AzureRTOS/ST/ST_B_L475E_IOT01A/nanoCLR/halconf.h +++ b/targets/AzureRTOS/ST/ST_B_L475E_IOT01A/nanoCLR/halconf.h @@ -21,7 +21,7 @@ #define HALCONF_H #define _CHIBIOS_HAL_CONF_ -#define _CHIBIOS_HAL_CONF_VER_8_0_ +#define _CHIBIOS_HAL_CONF_VER_8_4_ #include #include "mcuconf.h" diff --git a/targets/AzureRTOS/ST/ST_B_L475E_IOT01A/target_system_device_pwm_config.cpp b/targets/AzureRTOS/ST/ST_B_L475E_IOT01A/target_system_device_pwm_config.cpp new file mode 100644 index 0000000000..73cc6666d3 --- /dev/null +++ b/targets/AzureRTOS/ST/ST_B_L475E_IOT01A/target_system_device_pwm_config.cpp @@ -0,0 +1,9 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS BLANK ON PURPOSE BECAUSE THIS TARGET DOESN'T REQUIRE THIS SPECIFIC CONFIGURATION // +/////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/targets/AzureRTOS/ST/_common/LaunchCLR.c b/targets/AzureRTOS/ST/_common/LaunchCLR.c index fb660643d9..c8b3a44583 100644 --- a/targets/AzureRTOS/ST/_common/LaunchCLR.c +++ b/targets/AzureRTOS/ST/_common/LaunchCLR.c @@ -14,6 +14,9 @@ void LaunchCLR(uint32_t address) // function pointer to load nanoCLR ResetHandler address irq_vector_t JumpToNanoCLR; + // report successfull nanoBooter execution + ReportSuccessfullNanoBooter(); + // load nanoCLR vector table const vectors_t *nanoCLRVectorTable = (vectors_t *)address; diff --git a/targets/AzureRTOS/ST/_common/drivers/wifi/inventek/wifi.c b/targets/AzureRTOS/ST/_common/drivers/wifi/inventek/wifi.c index a064f8c8f0..d9557dca22 100644 --- a/targets/AzureRTOS/ST/_common/drivers/wifi/inventek/wifi.c +++ b/targets/AzureRTOS/ST/_common/drivers/wifi/inventek/wifi.c @@ -615,7 +615,7 @@ WIFI_Status_t WIFI_GetModuleFwRevision(char *rev) { WIFI_Status_t ret = WIFI_STATUS_ERROR; - if(EsWifiObj.FW_Rev != NULL) + if(EsWifiObj.FW_Rev[0] != 0) { strncpy(rev, (char *)EsWifiObj.FW_Rev, ES_WIFI_FW_REV_SIZE); ret = WIFI_STATUS_OK; @@ -632,7 +632,7 @@ WIFI_Status_t WIFI_GetModuleID(char *Id) { WIFI_Status_t ret = WIFI_STATUS_ERROR; - if(EsWifiObj.Product_ID != NULL) + if(EsWifiObj.Product_ID[0] != 0) { strncpy(Id, (char *)EsWifiObj.Product_ID, ES_WIFI_PRODUCT_ID_SIZE); ret = WIFI_STATUS_OK; @@ -649,7 +649,7 @@ WIFI_Status_t WIFI_GetModuleName(char *ModuleName) { WIFI_Status_t ret = WIFI_STATUS_ERROR; - if(EsWifiObj.Product_Name != NULL) + if(EsWifiObj.Product_Name[0] != 0) { strncpy(ModuleName, (char *)EsWifiObj.Product_Name, ES_WIFI_PRODUCT_NAME_SIZE); ret = WIFI_STATUS_OK; diff --git a/targets/AzureRTOS/ST/_common/rules_code.ld b/targets/AzureRTOS/ST/_common/rules_code.ld index 8f83284cc9..1234cf604b 100644 --- a/targets/AzureRTOS/ST/_common/rules_code.ld +++ b/targets/AzureRTOS/ST/_common/rules_code.ld @@ -22,7 +22,10 @@ SECTIONS { .vectors : ALIGN(1024) { + __textvectors_base__ = LOADADDR(.vectors); + __vectors_base__ = .; KEEP(*(.vectors)) + __vectors_end__ = .; } > VECTORS_FLASH AT > VECTORS_FLASH_LMA .xtors : ALIGN(4) diff --git a/targets/AzureRTOS/ST/_include/targetHAL_Time.h b/targets/AzureRTOS/ST/_include/targetHAL_Time.h index 604aa20859..e58e91a0b7 100644 --- a/targets/AzureRTOS/ST/_include/targetHAL_Time.h +++ b/targets/AzureRTOS/ST/_include/targetHAL_Time.h @@ -10,4 +10,26 @@ #define HAL_Time_CurrentSysTicks tx_time_get +#ifdef __cplusplus +extern "C" +{ +#endif + + // Converts CMSIS sysTicks to .NET ticks (100 nanoseconds) + inline __attribute__((always_inline)) uint64_t HAL_Time_SysTicksToTime(uint64_t sysTicks) + { + // need to convert Azure RTOS ticks to 100 nanoseconds + return sysTicks * TX_TIMER_TICKS_PER_SECOND * 10; + } + + // because HAL_Time_SysTicksToTime needs to be called from C we need a proxy to allow it to be called from 'C' code + inline __attribute__((always_inline)) uint64_t HAL_Time_SysTicksToTime_C(uint64_t sysTicks) + { + return sysTicks * TX_TIMER_TICKS_PER_SECOND * 10; + } + +#ifdef __cplusplus +} +#endif + #endif //_TARGET_HAL_TIME_H_ diff --git a/targets/AzureRTOS/ST/_nanoCLR/System.Device.Gpio/cpu_gpio.cpp b/targets/AzureRTOS/ST/_nanoCLR/System.Device.Gpio/cpu_gpio.cpp index e3e90eb37e..ffe810e216 100644 --- a/targets/AzureRTOS/ST/_nanoCLR/System.Device.Gpio/cpu_gpio.cpp +++ b/targets/AzureRTOS/ST/_nanoCLR/System.Device.Gpio/cpu_gpio.cpp @@ -9,20 +9,20 @@ #define GPIO_MAX_PIN 256 #define TOTAL_GPIO_PORTS ((GPIO_MAX_PIN + 15) / 16) -// Double linkedlist to hold the state of each Input pin +// Double linked list to hold the state of each Input pin struct gpio_input_state : public HAL_DblLinkedNode { - // Pin number + // pin number GPIO_PIN pinNumber; - // debounce timer for this Pin + // debounce timer for this pin TX_TIMER debounceTimer; - // Ptr to user ISR or null + // pointer to user ISR or null GPIO_INTERRUPT_SERVICE_ROUTINE isrPtr; - // debounce Millsecs, no debonce=0 + // debounce milliseconds, NO debounce set to 0 uint32_t debounceMs; // Interrupt mode uint8_t mode; - // Param to user isr call + // Param to user ISR call void *param; // Expected state for debounce handler bool expected; @@ -30,8 +30,10 @@ struct gpio_input_state : public HAL_DblLinkedNode bool waitingDebounce; }; -static HAL_DblLinkedList gpioInputList; // Double Linked list for GPIO input status -static uint16_t pinReserved[TOTAL_GPIO_PORTS]; // reserved - 1 bit per pin +// Double Linked list for GPIO input status +static HAL_DblLinkedList gpioInputList; +// reserved - 1 bit per pin +static uint16_t pinReserved[TOTAL_GPIO_PORTS]; // this is an utility function to get a ChibiOS PAL IoLine from our "encoded" pin number static ioline_t GetIoLine(int16_t pinNumber) @@ -52,6 +54,7 @@ bool IsValidGpioPin(GPIO_PIN pinNumber) gpio_input_state *GetGpioWithInterrupt(uint16_t gpioPin) { gpio_input_state *ptr = gpioInputList.FirstNode(); + while (ptr->Next() != NULL) { if (GPIO_PIN(ptr->pinNumber) == gpioPin) @@ -65,24 +68,20 @@ gpio_input_state *GetGpioWithInterrupt(uint16_t gpioPin) return NULL; } -static void DebounceTimerCallback(uint32_t id) +static void DebounceTimerCallback(ULONG pinState) { - gpio_input_state *pState = (gpio_input_state *)id; + gpio_input_state *pState = (gpio_input_state *)pinState; // get current pin state bool actual = palReadLine(GetIoLine(pState->pinNumber)); if (actual == pState->expected) { + // call ISR pState->isrPtr(pState->pinNumber, actual, pState->param); - if (pState->mode == GPIO_INT_EDGE_BOTH) - { - // both edges - // update expected state - pState->expected ^= 1; - } } + // reset flag pState->waitingDebounce = false; } @@ -96,30 +95,30 @@ void GpioEventCallback(void *arg) if (pGpio != NULL) { - // Ignore any pin changes during debounce - if (!pGpio->waitingDebounce) + if (pGpio->waitingDebounce) + { + // Ignore any pin changes during debounce + } + else { // check if there is a debounce time set if (pGpio->debounceMs > 0) { + // stop timer, just in case + tx_timer_deactivate(&pGpio->debounceTimer); // Set flag we are waiting for debounce on this pin pGpio->waitingDebounce = true; + // expecting same state as current one + pGpio->expected = CPU_GPIO_GetPinState(pGpio->pinNumber); + // setup timer - tx_timer_deactivate(&pGpio->debounceTimer); - tx_timer_change(&pGpio->debounceTimer, 0, pGpio->debounceMs / 10); + tx_timer_change(&pGpio->debounceTimer, TX_TICKS_PER_MILLISEC(pGpio->debounceMs), 0); tx_timer_activate(&pGpio->debounceTimer); } else { - // get IoLine from pin number - ioline_t ioLine = GetIoLine(pGpio->pinNumber); - - TX_RESTORE - - pGpio->isrPtr(pGpio->pinNumber, palReadLine(ioLine), pGpio->param); - - TX_DISABLE + pGpio->isrPtr(pGpio->pinNumber, CPU_GPIO_GetPinState(pGpio->pinNumber), pGpio->param); } } } @@ -168,9 +167,9 @@ gpio_input_state *AllocateGpioInputState(GPIO_PIN pinNumber) &ptr->debounceTimer, (char *)"GPIO debounce timer", DebounceTimerCallback, - 0, - 0, + (ULONG)ptr, 1, + 0, TX_NO_ACTIVATE); gpioInputList.LinkAtBack(ptr); diff --git a/targets/AzureRTOS/ST/_nanoCLR/System.Device.I2c/sys_dev_i2c_native_System_Device_I2c_I2cDevice.cpp b/targets/AzureRTOS/ST/_nanoCLR/System.Device.I2c/sys_dev_i2c_native_System_Device_I2c_I2cDevice.cpp index f1b78c5c15..c495e467f3 100644 --- a/targets/AzureRTOS/ST/_nanoCLR/System.Device.I2c/sys_dev_i2c_native_System_Device_I2c_I2cDevice.cpp +++ b/targets/AzureRTOS/ST/_nanoCLR/System.Device.I2c/sys_dev_i2c_native_System_Device_I2c_I2cDevice.cpp @@ -46,6 +46,7 @@ void GetI2cConfig(CLR_RT_HeapBlock *managedConfig, I2CConfig *llConfig) #if defined(STM32F1XX) || defined(STM32F4XX) || defined(STM32L1XX) llConfig->op_mode = OPMODE_I2C; + // No FastMode+ on those devices. llConfig->clock_speed = busSpeed == I2cBusSpeed_StandardMode ? 100000U : 400000U; llConfig->duty_cycle = busSpeed == I2cBusSpeed_StandardMode ? STD_DUTY_CYCLE : FAST_DUTY_CYCLE_2; @@ -58,6 +59,15 @@ void GetI2cConfig(CLR_RT_HeapBlock *managedConfig, I2CConfig *llConfig) llConfig->timingr = busSpeed == I2cBusSpeed_StandardMode ? 0x80201721 : 0x00B01B59; llConfig->cr1 = 0; llConfig->cr2 = 0; + // Todo: check if each series should get their own timing. From STM32CubeMX, with default clock values + // which were about 16MHz for APB, those were timing: + // Series Standard Fast Fast+ + // F0 0x00201D2B 0x0010020A 0x00100001 + // F3 0x00201D2B 0x0010020A 0x00100001 + // F7 0x00503D59 0x00300618 0x00200105 + // L0 0x00000608 0x00000000 + // L4 0x00100D14 0x00000102 0x00000000 + // H7 0x10B07DB7 0x00E03951 0x00A00F1B #else #error Your board is unimplemented. Please provide the needed information for the realtime OS as done above! diff --git a/targets/AzureRTOS/ST/_nanoCLR/System.Device.Spi/cpu_spi.cpp b/targets/AzureRTOS/ST/_nanoCLR/System.Device.Spi/cpu_spi.cpp index 99c6355ca7..906b208212 100644 --- a/targets/AzureRTOS/ST/_nanoCLR/System.Device.Spi/cpu_spi.cpp +++ b/targets/AzureRTOS/ST/_nanoCLR/System.Device.Spi/cpu_spi.cpp @@ -486,11 +486,12 @@ HRESULT CPU_SPI_nWrite_nRead( // just to satisfy the driver ceremony, no actual implementation for STM32 spiSelect(palSpi->Driver); + palSpi->ChipSelect = wrc.DeviceChipSelect; // if CS is to be controlled by the driver, set the GPIO - if (palSpi->ChipSelect >= 0) + if (wrc.DeviceChipSelect >= 0) { // assert pin based on CS active level - CPU_GPIO_SetPinState(palSpi->ChipSelect, (GpioPinValue)sdev.ChipSelectActive); + CPU_GPIO_SetPinState(wrc.DeviceChipSelect, (GpioPinValue)wrc.ChipSelectActiveState); } if (sync) @@ -562,10 +563,10 @@ HRESULT CPU_SPI_nWrite_nRead( CompleteTranfer(palSpi); // if CS is to be controlled by the driver, set the GPIO - if (palSpi->ChipSelect >= 0) + if (wrc.DeviceChipSelect >= 0) { // de-assert pin based on CS active level - CPU_GPIO_SetPinState(palSpi->ChipSelect, (GpioPinValue)sdev.ChipSelectActive); + CPU_GPIO_SetPinState(wrc.DeviceChipSelect, (GpioPinValue)wrc.ChipSelectActiveState); } } else @@ -575,10 +576,10 @@ HRESULT CPU_SPI_nWrite_nRead( // Completed on calling Spi Callback // if CS is to be controlled by the driver, set the GPIO - if (palSpi->ChipSelect >= 0) + if (wrc.DeviceChipSelect >= 0) { // assert pin based on CS active level - CPU_GPIO_SetPinState(palSpi->ChipSelect, (GpioPinValue)sdev.ChipSelectActive); + CPU_GPIO_SetPinState(wrc.DeviceChipSelect, (GpioPinValue)wrc.ChipSelectActiveState); } // this is a Async operation diff --git a/targets/AzureRTOS/ST/_nanoCLR/System.Device.Spi/sys_dev_spi_native_target.h b/targets/AzureRTOS/ST/_nanoCLR/System.Device.Spi/sys_dev_spi_native_target.h index 91ca40488a..f7f686ff4c 100644 --- a/targets/AzureRTOS/ST/_nanoCLR/System.Device.Spi/sys_dev_spi_native_target.h +++ b/targets/AzureRTOS/ST/_nanoCLR/System.Device.Spi/sys_dev_spi_native_target.h @@ -75,7 +75,7 @@ struct NF_PAL_SPI GPIO_PORT(spiDeviceConfig.DeviceChipSelect), \ spiDeviceConfig.DeviceChipSelect % 16, \ (PAL_STM32_OSPEED_HIGHEST | PAL_MODE_OUTPUT_PUSHPULL)); \ - if (spiDeviceConfig.ChipSelectActive) \ + if (spiDeviceConfig.ChipSelectActiveState) \ { \ palSetPad(GPIO_PORT(spiDeviceConfig.DeviceChipSelect), spiDeviceConfig.DeviceChipSelect % 16); \ } \ diff --git a/targets/AzureRTOS/ST/_nanoCLR/System.Device.Wifi/sys_dev_wifi_native_System_Device_WiFi_WiFiAdapter.cpp b/targets/AzureRTOS/ST/_nanoCLR/System.Device.Wifi/sys_dev_wifi_native_System_Device_Wifi_WifiAdapter.cpp similarity index 100% rename from targets/AzureRTOS/ST/_nanoCLR/System.Device.Wifi/sys_dev_wifi_native_System_Device_WiFi_WiFiAdapter.cpp rename to targets/AzureRTOS/ST/_nanoCLR/System.Device.Wifi/sys_dev_wifi_native_System_Device_Wifi_WifiAdapter.cpp diff --git a/targets/AzureRTOS/ST/_nanoCLR/System.IO.Ports/sys_io_ser_native_System_IO_Ports_SerialPort.cpp b/targets/AzureRTOS/ST/_nanoCLR/System.IO.Ports/sys_io_ser_native_System_IO_Ports_SerialPort.cpp index 856a3ada21..336443eaa3 100644 --- a/targets/AzureRTOS/ST/_nanoCLR/System.IO.Ports/sys_io_ser_native_System_IO_Ports_SerialPort.cpp +++ b/targets/AzureRTOS/ST/_nanoCLR/System.IO.Ports/sys_io_ser_native_System_IO_Ports_SerialPort.cpp @@ -1119,7 +1119,7 @@ HRESULT Library_sys_io_ser_native_System_IO_Ports_SerialPort::NativeWriteString_ bool isNewAllocation = false; char *buffer = NULL; - uint32_t bufferLength; + uint32_t bufferLength = 0; int32_t length = 0; // get a pointer to the managed object instance and check that it's not NULL diff --git a/targets/AzureRTOS/ST/_nanoCLR/nanoFramework.Runtime.Native/nf_rt_native_nanoFramework_Runtime_Native_Rtc.cpp b/targets/AzureRTOS/ST/_nanoCLR/nanoFramework.Runtime.Native/nf_rt_native_nanoFramework_Runtime_Native_Rtc.cpp index 364254a4b7..3507b23aeb 100644 --- a/targets/AzureRTOS/ST/_nanoCLR/nanoFramework.Runtime.Native/nf_rt_native_nanoFramework_Runtime_Native_Rtc.cpp +++ b/targets/AzureRTOS/ST/_nanoCLR/nanoFramework.Runtime.Native/nf_rt_native_nanoFramework_Runtime_Native_Rtc.cpp @@ -33,6 +33,8 @@ HRESULT Library_nf_rt_native_nanoFramework_Runtime_Native_Rtc:: ((((uint32_t)stack.Arg4().NumericByRef().u1 * 3600) + ((uint32_t)stack.Arg5().NumericByRef().u1 * 60) + (uint32_t)stack.Arg6().NumericByRef().u1) * 1000); + // no DST support, but still need to set this + newTime.dstflag = 0; // set RTC time rtcSetTime(&RTCD1, &newTime); diff --git a/targets/AzureRTOS/ST/_nanoCLR/targetHAL.cpp b/targets/AzureRTOS/ST/_nanoCLR/targetHAL.cpp index 89e790088f..9bb022b8bc 100644 --- a/targets/AzureRTOS/ST/_nanoCLR/targetHAL.cpp +++ b/targets/AzureRTOS/ST/_nanoCLR/targetHAL.cpp @@ -38,9 +38,9 @@ extern "C" nanoHAL_Initialize(); } - void nanoHAL_Uninitialize_C() + void nanoHAL_Uninitialize_C(bool isPoweringDown) { - nanoHAL_Uninitialize(); + nanoHAL_Uninitialize(isPoweringDown); } } @@ -157,8 +157,10 @@ void nanoHAL_Initialize() Network_Initialize(); } -void nanoHAL_Uninitialize() +void nanoHAL_Uninitialize(bool isPoweringDown) { + (void)isPoweringDown; + // release the global mutex, just in case it's locked somewhere // chMtxUnlock(&interpreterGlobalMutex); diff --git a/targets/AzureRTOS/ST/_nanoCLR/targetHAL_Power.c b/targets/AzureRTOS/ST/_nanoCLR/targetHAL_Power.c index 7fd00c3a42..f04798d181 100644 --- a/targets/AzureRTOS/ST/_nanoCLR/targetHAL_Power.c +++ b/targets/AzureRTOS/ST/_nanoCLR/targetHAL_Power.c @@ -70,7 +70,7 @@ void CPU_SetPowerMode(PowerLevel_type powerLevel) #endif #endif // gracefully shutdown everything - nanoHAL_Uninitialize_C(); + nanoHAL_Uninitialize_C(true); __disable_irq(); diff --git a/targets/AzureRTOS/SiliconLabs/CMakeLists.txt b/targets/AzureRTOS/SiliconLabs/CMakeLists.txt new file mode 100644 index 0000000000..740a9fa051 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/CMakeLists.txt @@ -0,0 +1,131 @@ +# +# Copyright (c) .NET Foundation and Contributors +# See LICENSE file in the project root for full license information. +# + +include(binutils.common) +include(Gecko_SDK) + +set(SILABS_GECKO_SDK_REQUIRED TRUE PARENT_SCOPE) + +option(GECKO_FEATURE_USBD_HID "option to use Gecko SDK HID class") +option(GECKO_FEATURE_USBD_WINUSB "option to use Gecko SDK USB vendor class for WinUSB") +option(GECKO_DEVICE_CLASS_VENDOR_DESCRIPTION_LENGTH "option to override Device Class Vendor description") + +################################################################# +# Options for Wire Protocol channel +option(HAL_WP_USE_SERIAL "option to use serial port (UART) to route Wire Protocol") +option(HAL_WP_USE_USB_CDC "option to use USB CDC to route Wire Protocol") + +if(HAL_WP_USE_SERIAL) + message(STATUS "Wire Protocol will use serial port (UART).") + set(HAL_WP_USE_SERIAL_OPTION TRUE CACHE INTERNAL "set HAL_WP_USE_SERIAL") + set(HAL_WP_USE_USB_CDC_OPTION FALSE CACHE INTERNAL "set HAL_WP_USE_USB_CDC") +elseif(HAL_WP_USE_USB_CDC) + message(STATUS "Wire Protocol will use USB CDC.") + set(HAL_WP_USE_USB_CDC_OPTION TRUE CACHE INTERNAL "set HAL_WP_USE_USB_CDC") + set(HAL_WP_USE_SERIAL_OPTION FALSE CACHE INTERNAL "set HAL_WP_USE_SERIAL") +else() + message(FATAL_ERROR "\n\nERROR: need to choose a channel for Wire Protocol. One of the build options HAL_WP_USE_SERIAL_OPTION or HAL_WP_USE_USB_CDC_OPTION have to be 'ON'.") +endif() + +ProcessGSDKPackage() + +if(GECKO_FEATURE_USBD_HID) + + set(GECKO_FEATURE_USBD_HID_OPTION TRUE CACHE INTERNAL "GECKO_FEATURE_USBD_HID for USBD HID") + +else() + set(GECKO_FEATURE_USBD_HID_OPTION FALSE CACHE INTERNAL "GECKO_FEATURE_USBD_HID for USBD HID") +endif() + +if(API_System.Device.UsbStream) + + set(GECKO_FEATURE_USBD_WINUSB_OPTION TRUE CACHE INTERNAL "GECKO_FEATURE_USBD_WINUSB for WinUSB") + set(GECKO_FEATURE_USBD_WINUSB ON PARENT_SCOPE) + +else() + set(GECKO_FEATURE_USBD_WINUSB_OPTION FALSE CACHE INTERNAL "GECKO_FEATURE_USBD_WINUSB for WinUSB") +endif() + + +# check if GECKO_SDK_SOURCE was specified or if it's empty (default is empty) +set(NO_GECKO_SDK_SOURCE TRUE) +if(GECKO_SDK_SOURCE) + if(NOT ${GECKO_SDK_SOURCE} STREQUAL "") + set(NO_GECKO_SDK_SOURCE FALSE) + endif() +endif() + +# Gecko SDK version +set(GECKO_SDK_VERSION_EMPTY TRUE) + +# check if build was requested with a specifc Gecko SDK version +if(DEFINED GECKO_SDK_VERSION) + if(NOT "${GECKO_SDK_VERSION}" STREQUAL "") + set(GECKO_SDK_VERSION_EMPTY FALSE) + endif() +endif() + +# check if build was requested with a specifc Gecko SDK version +if(GECKO_SDK_VERSION_EMPTY) + # no Gecko SDK version actualy specified, must be empty which is fine, we'll default to a known good version + # WHEN CHANGING THIS MAKE SURE TO UPDATE THE DEV CONTAINERS + set(GECKO_SDK_VERSION "v4.3.0") +endif() + +if(NO_GECKO_SDK_SOURCE) + # no Gecko SDK source specified, download it from it's repo + message(STATUS "Gecko SDK is: ${GECKO_SDK_VERSION} from official repo") + + FetchContent_Declare( + gecko_sdk + GIT_REPOSITORY https://github.com/SiliconLabs/gecko_sdk.git + GIT_TAG ${GECKO_SDK_VERSION} + GIT_SHALLOW 1 + ) + +else() + # Gecko SDK source was specified + + # sanity check is source path exists + if(EXISTS ${GECKO_SDK_SOURCE}/) + if(CMAKE_HOST_SYSTEM_NAME STREQUAL Windows) + + message(STATUS "Gecko SDK is: ${GECKO_SDK_VERSION} (source from: ${GECKO_SDK_SOURCE})") + FetchContent_Declare( + gecko_sdk + SOURCE_DIR ${GECKO_SDK_SOURCE} + ) + + else() + message(STATUS "Gecko SDK is: ${GECKO_SDK_VERSION} (source from: ${GECKO_SDK_SOURCE})") + + FetchContent_Declare( + gecko_sdk + SOURCE_DIR ${GECKO_SDK_SOURCE} + ) + + endif() + else() + message(FATAL_ERROR "Couldn't find Gecko SDK source at ${GECKO_SDK_SOURCE}/") + endif() + +endif() + +FetchContent_GetProperties(gecko_sdk) +FetchContent_Populate(gecko_sdk) + +# including here the CMake files for the source files specific to the target series +include(AzureRTOS_${TARGET_SERIES}_sources) + +list(APPEND TARGET_AZURERTOS_COMMON_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/_include) + +# make vars global +set(TARGET_AZURERTOS_COMMON_INCLUDE_DIRS ${TARGET_AZURERTOS_COMMON_INCLUDE_DIRS} CACHE INTERNAL "make global") + +# add platform dirs +add_subdirectory(_include) +add_subdirectory(_common) +add_subdirectory(_nanoBooter) +add_subdirectory(_nanoCLR) diff --git a/targets/AzureRTOS/SiliconLabs/README.md b/targets/AzureRTOS/SiliconLabs/README.md new file mode 100644 index 0000000000..9a57777d5b --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/README.md @@ -0,0 +1,31 @@ +# Silabs Gecko SDK + +## Configuration for USB devices and classes + +### USB serial number + +The USB serial number string is defined with `SL_USBD_DEVICE_SERIAL_NUMBER_STRING` in sl_usbd_device_config.h. +It can be hardcoded by setting it to a string like `"1234567890ABCDEF"`. +As an alternative it can be generated from the device unique ID. For this the define has to be set to `(const char *)&UsbSerialNumber` and the following declaration has to be added `extern char *UsbSerialNumber[];`. Please check the example [here](SL_STK3701A/config/sl_usbd_device_config.h). + +### WinUSB devices + +In order to add a WinUSB device configuration, the follow is required: + +1. Set build option `GECKO_FEATURE_USBD_WINUSB` to `ON`. As an alternative, if you plan to use the UsbStream # class, the latter is not required. Just set to `ON` the respective build option `API_System.Device.UsbStream`. + +1. Add the following files to the target folder (mind the location) + [sl_usbd_class_vendor_instances.c](SL_STK3701A/autogen/sl_usbd_class_vendor_instances.c) + + [sl_usbd_class_vendor_instances.h](SL_STK3701A/autogen/sl_usbd_class_vendor_instances.h) + + [sl_usbd_class_winusb_config.h](SL_STK3701A/config/sl_usbd_class_winusb_config.h) + +1. If defining the WinUSB device before compile time: define a GUID for the device class and set define `DEVICE_CLASS_GUID_PROPERTY` with it. Check [sl_usbd_class_winusb_config.h](SL_STK3701A/config/sl_usbd_class_winusb_config.h). +For details check [Microsoft documentation](https://learn.microsoft.com/en-us/windows-hardware/drivers/usbcon/automatic-installation-of-winusb#registering-a-device-interface-guid) about setting a WinUSB device that does not require an INF file to install. + +1. In case the `System.Device.UsbStream` is being used, the device description and class GUID are defined in the C# code, therefore no other configuration is required at build time. + +> **Warning** When performing a debug session from Visual Studio, if the deployment occurs on a blank device, when calling `UsbClient.CreateUsbStream()` despite the WinUSB device is added, it won't show up as no USB enumeration takes place. This will NOT happen on subsequent debug sessions nor on a device running the application standalone. The reason for this is that when that call is executed, a new USB interface and associated end points are added to the USB device configuration in order to add that new WinUSB device supporting the `UsbStream`. Following this, it would be expected that an USB re-enumeration would occur. This won't happen when there is a debugger connected in order to prevent the debug session from being abruptly interrupted. +There a limitation of the Gecko SDK as it doesn't allow adding a new interface after the USB device core is running. Stopping the USB device entirely to perform this action is not possible (or better, not desirable) because the CDC device on the same USB composite is being used to connect to Visual Studio. Stopping it would cease communication with Visual Studio, thus ending the debug session. +Because of this limitation the call to `UsbClient.CreateUsbStream()` has to be done **AS EARLY AS POSSIBLE** in the C# application. Preferably in the very first line of `Main()` thus ensuring that the descriptors are added to the USB configuration before the USB Core is initialized. diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/CMakeLists.txt b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/CMakeLists.txt new file mode 100644 index 0000000000..f48bb4d512 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/CMakeLists.txt @@ -0,0 +1,80 @@ + +include(FetchContent) +include(binutils.common) +include(binutils.AzureRTOS) +include(AzureRTOS_${TARGET_SERIES}_GCC_options) + +# Azure RTOS settings and inclusion of build system +set(THREADX_ARCH "cortex_m4" ) +set(THREADX_TOOLCHAIN "gnu" ) +# set(NX_USER_FILE ${TARGET_BASE_LOCATION}/target_nx_user.h CACHE STRING "Enable NX user configuration") +# set(NXD_ENABLE_FILE_SERVERS OFF CACHE BOOL "Disable fileX dependency by netxduo") + +set(SL_BOARD_NAME "BRD2204A" PARENT_SCOPE) +# include BSP from Gecko SDK +set(GECKO_SDK_BSP TRUE CACHE BOOL "Setting Gecko BSP flag ") + +add_subdirectory(${azure_rtos_SOURCE_DIR} threadx) +# add_subdirectory(${azure_rtos_filex_SOURCE_DIR} filex) +# add_subdirectory(${azure_rtos_netxduo_SOURCE_DIR} netxduo) +# add_subdirectory(${azure_rtos_usbx_SOURCE_DIR} usbx) + +nf_setup_target_build( + HAS_NANOBOOTER + + BOOTER_LINKER_FILE + efm32gg11b_booter + + CLR_LINKER_FILE + efm32gg11b_CLR + + BOOTER_EXTRA_COMPILE_DEFINITIONS + EFM32GG11B820F2048GL192=1 + SL_BOARD_NAME=\"BRD2204C\" + SL_BOARD_REV=\"A02\" + SL_COMPONENT_CATALOG_PRESENT=1 + _SILICON_LABS_32B_SERIES_2_CONFIG=0 + I2CSPM_TRANSFER_TIMEOUT=3000 + SL_STACK_SIZE=0x2000 + SL_HEAP_SIZE=0x2000 + + CLR_EXTRA_COMPILE_DEFINITIONS + EFM32GG11B820F2048GL192=1 + SL_BOARD_NAME=\"BRD2204C\" + SL_BOARD_REV=\"A02\" + SL_COMPONENT_CATALOG_PRESENT=1 + _SILICON_LABS_32B_SERIES_2_CONFIG=0 + I2CSPM_TRANSFER_TIMEOUT=3000 + SL_STACK_SIZE=0x7000 + SL_HEAP_SIZE=0x10000 + + BOOTER_EXTRA_LINKMAP_PROPERTIES + ",--library-path=${CMAKE_SOURCE_DIR}/targets/AzureRTOS/_common" + + CLR_EXTRA_LINKMAP_PROPERTIES + ",--library-path=${CMAKE_SOURCE_DIR}/targets/AzureRTOS/_common" +) + +# generate bin file for deployment +if(SRECORD_TOOL_AVAILABLE) + + ############################################################################################################ + ## when changing the linker file make sure to update the addresses below with the offset of the CLR image ## + ## DO NOT use the leading 0x notation, just the address in plain hexadecimal formating ## + ############################################################################################################ + + if(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES RelWithDebInfo) + nf_generate_bin_package( + ${CMAKE_SOURCE_DIR}/build/${NANOBOOTER_PROJECT_NAME}.bin + ${CMAKE_SOURCE_DIR}/build/${NANOCLR_PROJECT_NAME}.bin + 13000 + ${CMAKE_SOURCE_DIR}/build/nanobooter-nanoclr.bin) + else() + nf_generate_bin_package( + ${CMAKE_SOURCE_DIR}/build/${NANOBOOTER_PROJECT_NAME}.bin + ${CMAKE_SOURCE_DIR}/build/${NANOCLR_PROJECT_NAME}.bin + 0C000 + ${CMAKE_SOURCE_DIR}/build/nanobooter-nanoclr.bin) + endif() + +endif() diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/CMakePresets.json b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/CMakePresets.json new file mode 100644 index 0000000000..21e4dd0516 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/CMakePresets.json @@ -0,0 +1,84 @@ +{ + "version": 4, + "include": [ + "../../../../CMake/arm-gcc.json", + "../../../../config/user-tools-repos.json", + "../../../../config/user-prefs.json" + ], + "configurePresets": [ + { + "name": "SL_STK3701A", + "inherits": [ + "arm-gcc-cortex-preset", + "user-tools-repos", + "user-prefs" + ], + "hidden": false, + "cacheVariables": { + "TARGET_BOARD": "${presetName}", + "RTOS": "AzureRTOS", + "TARGET_SERIES": "EFM32GG11", + "SUPPORT_ANY_BASE_CONVERSION": "OFF", + "NF_FEATURE_DEBUGGER": "ON", + "NF_FEATURE_RTC": "ON", + "NF_FEATURE_HAS_SDCARD": "OFF", + "NF_FEATURE_HAS_CONFIG_BLOCK": "ON", + "SWO_OUTPUT": "OFF", + "NF_BUILD_RTM": "OFF", + "API_System.Math": "ON", + "API_Hardware.GiantGecko": "ON", + "API_System.Device.Gpio": "ON", + "API_System.Device.Spi": "ON", + "API_System.Device.I2c": "ON", + "API_System.Device.Pwm": "ON", + "API_System.IO.Ports": "ON", + "API_System.Device.Adc": "ON", + "API_System.Device.Dac": "OFF", + "API_System.Net": "OFF", + "API_nanoFramework.Device.OneWire": "OFF", + "API_nanoFramework.Devices.Can": "OFF", + "API_nanoFramework.ResourceManager": "ON", + "API_nanoFramework.System.Collections": "ON", + "API_nanoFramework.System.Text": "ON", + "API_nanoFramework.GiantGecko.Adc": "OFF", + "API_Windows.Storage": "OFF", + "API_nanoFramework.Graphics": "OFF", + "API_System.Device.UsbStream": "ON", + "HAL_WP_USE_SERIAL": "ON" + } + }, + { + "name": "SL_STK3701A_REVB", + "inherits": [ + "SL_STK3701A" + ], + "cacheVariables": { + "TARGET_BOARD": { + "type": "STRING", + "value": "SL_STK3701A" + }, + "TARGET_SERIAL_BAUDRATE": "115200", + "GECKO_FEATURE_USBD_HID": "OFF", + "HAL_WP_USE_SERIAL": "ON", + "HAL_WP_USE_USB_CDC": "OFF", + "API_System.Device.Adc": "ON", + "API_nanoFramework.GiantGecko.Adc": "OFF", + "API_System.Device.UsbStream": "ON" + } + } + ], + "buildPresets": [ + { + "inherits": "base-user", + "name": "SL_STK3701A", + "displayName": "SL_STK3701A", + "configurePreset": "SL_STK3701A" + }, + { + "inherits": "base-user", + "name": "SL_STK3701A_REVB", + "displayName": "SL_STK3701A_REVB", + "configurePreset": "SL_STK3701A_REVB" + } + ] +} diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/README.md b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/README.md new file mode 100644 index 0000000000..5a583087ed --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/README.md @@ -0,0 +1,59 @@ +# Silabs EFM32 Giant Gecko GG11 Starter Kit (revC hardware) + +This target is for revC hardware. This can be easily identified by the presence of a USB-C connector for JLink connection. +Opposed to revB which carries a micro USB connector instead. For revB user the firmware for target `SL_STK3701A_REVB`. + +## Setting the VCP baud rate to 921600 + +https://community.silabs.com/s/article/kba-bt-1208-using-virtual-com-port-vcom-x + +:warning: +Only possible for revC hardware. + +## ADC channels + +ADC has enabled the following channels: +0 - reading from PE11 (pin 6 on the expansion header) +1 - internal temperature +2 - VCC + +:warning: +Vref is 2.5V for all channels, except for VCC which is 5V. + +## PWM + +PWM has enabled the following GPIOs: +0 - PC1 (pin 15 on the expansion header) +1 - PI1 (through hole connector at bottom side) + +## I2C + +I2C0 (this is referenced as I2C1 in C#) +Available in EXP header +I2C0_SDA: PC0, EXP Header Pin 16 +I2C0_SCL: PC1, EXP Header Pin 15 + +I2C2 (this is referenced as I2C3 in C#) +Connected to the following devices on the GG11 board: +Si7021: Relative Humidity and Temperature Sensor +Si7210: Hall-Effect Sensor + +I2C2_SCL is: PI5 +I2C2_SDA is: PI4 + +## SPI + +SPI0 (this is referenced as SPI1 in C#) +Available in EXP header + +SPI0_SCK: PE12, EXP Header Pin 8 +SPI0_MOSI: PE10, EXP Header Pin 4 +SPI0_MISO: PE11, EXP Header Pin 6 +SPI0_CS: PE13, EXP Header Pin 10 + +SPI1 (this is referenced as SPI2 in C#) +Connected to board LCD module + +SPI1_SCK: PC15 +SPI1_MOSI: PA14 +SPI1_CS: PC14 diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/autogen/sl_device_init_clocks.c b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/autogen/sl_device_init_clocks.c new file mode 100644 index 0000000000..4501c16160 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/autogen/sl_device_init_clocks.c @@ -0,0 +1,8 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +/////////////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS BLANK ON PURPOSE BECAUSE THIS TARGET DOESN'T OVERRIDE THIS FUNCTIONS // +/////////////////////////////////////////////////////////////////////////////////////// diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/autogen/sl_event_handler.c b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/autogen/sl_event_handler.c new file mode 100644 index 0000000000..4501c16160 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/autogen/sl_event_handler.c @@ -0,0 +1,8 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +/////////////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS BLANK ON PURPOSE BECAUSE THIS TARGET DOESN'T OVERRIDE THIS FUNCTIONS // +/////////////////////////////////////////////////////////////////////////////////////// diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/autogen/sl_uartdrv_init.c b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/autogen/sl_uartdrv_init.c new file mode 100644 index 0000000000..ab0bb51bee --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/autogen/sl_uartdrv_init.c @@ -0,0 +1,91 @@ +#include "uartdrv.h" +#include "sl_uartdrv_instances.h" +#include + +#include "sl_uartdrv_usart_vcom_config.h" + +UARTDRV_HandleData_t sl_uartdrv_usart_vcom_handle_data; +UARTDRV_Handle_t sl_uartdrv_usart_vcom_handle = &sl_uartdrv_usart_vcom_handle_data; + +static UARTDRV_Handle_t sli_uartdrv_default_handle = NULL; + +/* If CTS and RTS not defined, define a default value to avoid errors */ +#ifndef SL_UARTDRV_USART_VCOM_CTS_PORT +#define SL_UARTDRV_USART_VCOM_CTS_PORT gpioPortA +#define SL_UARTDRV_USART_VCOM_CTS_PIN 0 +#if defined(_USART_ROUTELOC1_MASK) +#define SL_UARTDRV_USART_VCOM_CTS_LOC 0 +#endif +#endif + +#ifndef SL_UARTDRV_USART_VCOM_RTS_PORT +#define SL_UARTDRV_USART_VCOM_RTS_PORT gpioPortA +#define SL_UARTDRV_USART_VCOM_RTS_PIN 0 +#if defined(_USART_ROUTELOC1_MASK) +#define SL_UARTDRV_USART_VCOM_RTS_LOC 0 +#endif +#endif + + +/* Define RX and TX buffer queues */ +DEFINE_BUF_QUEUE(SL_UARTDRV_USART_VCOM_RX_BUFFER_SIZE, sl_uartdrv_usart_vcom_rx_buffer); +DEFINE_BUF_QUEUE(SL_UARTDRV_USART_VCOM_TX_BUFFER_SIZE, sl_uartdrv_usart_vcom_tx_buffer); + + +/* Create uartdrv initialization structs */ +UARTDRV_InitUart_t sl_uartdrv_usart_init_vcom = { + .port = SL_UARTDRV_USART_VCOM_PERIPHERAL, + .baudRate = SL_UARTDRV_USART_VCOM_BAUDRATE, +#if defined(_USART_ROUTELOC0_MASK) + .portLocationTx = SL_UARTDRV_USART_VCOM_TX_LOC, + .portLocationRx = SL_UARTDRV_USART_VCOM_RX_LOC, +#elif defined(_USART_ROUTE_MASK) + .portLocation = SL_UARTDRV_USART_VCOM_ROUTE_LOC, +#elif defined(_GPIO_USART_ROUTEEN_MASK) + .txPort = SL_UARTDRV_USART_VCOM_TX_PORT, + .rxPort = SL_UARTDRV_USART_VCOM_RX_PORT, + .txPin = SL_UARTDRV_USART_VCOM_TX_PIN, + .rxPin = SL_UARTDRV_USART_VCOM_RX_PIN, + .uartNum = SL_UARTDRV_USART_VCOM_PERIPHERAL_NO, +#endif + .stopBits = SL_UARTDRV_USART_VCOM_STOP_BITS, + .parity = SL_UARTDRV_USART_VCOM_PARITY, + .oversampling = SL_UARTDRV_USART_VCOM_OVERSAMPLING, +#if defined(USART_CTRL_MVDIS) + .mvdis = SL_UARTDRV_USART_VCOM_MVDIS, +#endif + .fcType = SL_UARTDRV_USART_VCOM_FLOW_CONTROL_TYPE, + .ctsPort = SL_UARTDRV_USART_VCOM_CTS_PORT, + .rtsPort = SL_UARTDRV_USART_VCOM_RTS_PORT, + .ctsPin = SL_UARTDRV_USART_VCOM_CTS_PIN, + .rtsPin = SL_UARTDRV_USART_VCOM_RTS_PIN, + .rxQueue = (UARTDRV_Buffer_FifoQueue_t *)&sl_uartdrv_usart_vcom_rx_buffer, + .txQueue = (UARTDRV_Buffer_FifoQueue_t *)&sl_uartdrv_usart_vcom_tx_buffer, +#if defined(_USART_ROUTELOC1_MASK) + .portLocationCts = SL_UARTDRV_USART_VCOM_CTS_LOC, + .portLocationRts = SL_UARTDRV_USART_VCOM_RTS_LOC, +#endif +}; + + +void sl_uartdrv_init_instances(void){ + UARTDRV_InitUart(sl_uartdrv_usart_vcom_handle, &sl_uartdrv_usart_init_vcom); + sl_uartdrv_set_default(sl_uartdrv_usart_vcom_handle); +} + +sl_status_t sl_uartdrv_set_default(UARTDRV_Handle_t handle) +{ + sl_status_t status = SL_STATUS_INVALID_HANDLE; + + if (handle != NULL) { + sli_uartdrv_default_handle = handle; + status = SL_STATUS_OK; + } + + return status; +} + +UARTDRV_Handle_t sl_uartdrv_get_default(void) +{ + return sli_uartdrv_default_handle; +} diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/autogen/sl_uartdrv_instances.h b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/autogen/sl_uartdrv_instances.h new file mode 100644 index 0000000000..894c73f803 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/autogen/sl_uartdrv_instances.h @@ -0,0 +1,35 @@ +#ifndef SL_UARTDRV_INSTANCES_H +#define SL_UARTDRV_INSTANCES_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "sl_status.h" +#include "uartdrv.h" + +extern UARTDRV_Handle_t sl_uartdrv_usart_vcom_handle; + +void sl_uartdrv_init_instances(void); + +/***************************************************************************//** + * Set the handle as the default UARTDRV handle. + * + * @param[in] handle UARTDRV handle to set as default. + * + * @return Status result + ******************************************************************************/ +sl_status_t sl_uartdrv_set_default(UARTDRV_Handle_t handle); + +/***************************************************************************//** + * Get the default UARTDRV handle configured. + * + * @return UARTDRV handle + ******************************************************************************/ +UARTDRV_Handle_t sl_uartdrv_get_default(void); + +#ifdef __cplusplus +} +#endif + +#endif // SL_UARTDRV_INSTANCES_H diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/autogen/sl_usbd_class_cdc_acm_instances.c b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/autogen/sl_usbd_class_cdc_acm_instances.c new file mode 100644 index 0000000000..12f715438d --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/autogen/sl_usbd_class_cdc_acm_instances.c @@ -0,0 +1,154 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Portions Copyright 2018 Silicon Laboratories Inc. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +//**************************************************************************** +// Includes. + +#include +#include +#include + +/* template headers */ +#include "sl_usbd_configuration_instances.h" +#include "sl_usbd_class_cdc_acm_instances.h" + +/* include config file for the instances */ + +#include + +//**************************************************************************** +// Function declarations. + +/* callback prototypes for acm0 instance */ + +void sli_usbd_cdc_acm_acm0_enable(uint8_t subclass_nbr); + +void sli_usbd_cdc_acm_acm0_disable(uint8_t subclass_nbr); + +void sli_usbd_cdc_acm_acm0_line_control_changed(uint8_t subclass_nbr, uint8_t event, uint8_t event_chngd); + +bool sli_usbd_cdc_acm_acm0_line_coding_changed(uint8_t subclass_nbr, sl_usbd_cdc_acm_line_coding_t *p_line_coding); + +//**************************************************************************** +// Global variables. + +/* variables for acm0 instance */ + +uint8_t sl_usbd_cdc_acm_acm0_number = 0; + +sl_usbd_cdc_acm_callbacks_t sli_usbd_cdc_acm_acm0_callbacks = { + sli_usbd_cdc_acm_acm0_enable, + sli_usbd_cdc_acm_acm0_disable, + sli_usbd_cdc_acm_acm0_line_control_changed, + sli_usbd_cdc_acm_acm0_line_coding_changed, +}; + +//**************************************************************************** +// Callback functions. + +/* callback functions for acm0 instance */ +void sli_usbd_cdc_acm_acm0_enable(uint8_t subclass_nbr) +{ + (void)&subclass_nbr; + sl_usbd_cdc_acm_acm0_on_enable_event(); + return; +} + +void sli_usbd_cdc_acm_acm0_disable(uint8_t subclass_nbr) +{ + (void)&subclass_nbr; + sl_usbd_cdc_acm_acm0_on_disable_event(); + return; +} + +void sli_usbd_cdc_acm_acm0_line_control_changed(uint8_t subclass_nbr, uint8_t event, uint8_t event_chngd) +{ + (void)&subclass_nbr; + (void)&event; + (void)&event_chngd; + sl_usbd_cdc_acm_acm0_on_line_control_event(); + return; +} + +bool sli_usbd_cdc_acm_acm0_line_coding_changed(uint8_t subclass_nbr, sl_usbd_cdc_acm_line_coding_t *p_line_coding) +{ + (void)&subclass_nbr; + (void)&p_line_coding; + sl_usbd_cdc_acm_acm0_on_line_coding_event(); + return true; +} + +//**************************************************************************** +// Global functions. + +/* initialize acm0 instance */ +void sli_usbd_cdc_acm_acm0_init() +{ + uint16_t interval = 0; + uint16_t capabilities = 0; + uint8_t class_number = 0; + uint8_t config_number = 0; + char *configs = NULL; + char *token = NULL; + + /* configs to attach the class instance to */ + configs = SL_USBD_CDC_ACM_ACM0_CONFIGURATIONS; + + /* line state notification interval for that instance */ + interval = SL_USBD_CDC_ACM_ACM0_NOTIFY_INTERVAL; + + /* call management capabilities */ + if (SL_USBD_CDC_ACM_ACM0_CALL_MGMT_ENABLE == 1) + { + capabilities |= SL_USBD_CDC_ACM_CALL_MGMT_DEV; + } + + /* call management DCI interface */ + if (SL_USBD_CDC_ACM_ACM0_CALL_MGMT_DCI == 1) + { + capabilities |= SL_USBD_CDC_ACM_CALL_MGMT_DATA_CCI_DCI; + } + + /* create CDC ACM instance */ + sl_usbd_cdc_acm_create_instance(interval, capabilities, &sli_usbd_cdc_acm_acm0_callbacks, &class_number); + + /* store class number globally */ + sl_usbd_cdc_acm_acm0_number = class_number; + + /* tokenize configs by "," and spaces */ + token = strtok(configs, ", "); + + /* loop over tokens */ + while (token != NULL) + { + + /* add to config0? */ + if (!strcmp(token, "config0") || !strcmp(token, "all")) + { + config_number = sl_usbd_configuration_config0_number; + sl_usbd_cdc_acm_add_to_configuration(class_number, config_number); + } + + /* next token */ + token = strtok(NULL, ", "); + } +} + +__WEAK void sl_usbd_cdc_acm_acm0_on_enable_event(void) +{ +} + +__WEAK void sl_usbd_cdc_acm_acm0_on_disable_event(void) +{ +} + +__WEAK void sl_usbd_cdc_acm_acm0_on_line_control_event(void) +{ +} + +__WEAK void sl_usbd_cdc_acm_acm0_on_line_coding_event(void) +{ +} diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/autogen/sl_usbd_class_cdc_acm_instances.h b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/autogen/sl_usbd_class_cdc_acm_instances.h new file mode 100644 index 0000000000..dd62731af5 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/autogen/sl_usbd_class_cdc_acm_instances.h @@ -0,0 +1,27 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Portions Copyright 2018 Silicon Laboratories Inc. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +#ifndef SL_USBD_CLASS_CDC_ACM_INSTANCES_INIT +#define SL_USBD_CLASS_CDC_ACM_INSTANCES_INIT + +#include + +/* class numbers assigned by the USB stack after init */ + +extern uint8_t sl_usbd_cdc_acm_acm0_number; + +/* event handlers for all CDC ACM instances */ + +__WEAK void sl_usbd_cdc_acm_acm0_on_enable_event(void); +__WEAK void sl_usbd_cdc_acm_acm0_on_disable_event(void); +__WEAK void sl_usbd_cdc_acm_acm0_on_line_control_event(void); +__WEAK void sl_usbd_cdc_acm_acm0_on_line_coding_event(void); + +/* init functions for all CDC ACM instances */ + +void sli_usbd_cdc_acm_acm0_init(void); + +#endif diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/autogen/sl_usbd_class_hid_instances.c b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/autogen/sl_usbd_class_hid_instances.c new file mode 100644 index 0000000000..2d2f895096 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/autogen/sl_usbd_class_hid_instances.c @@ -0,0 +1,277 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Portions Copyright 2018 Silicon Laboratories Inc. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +//**************************************************************************** +// Includes. + +#include +#include +#include + +/* template headers */ +#include +#include + +/* include config file for the instances */ + +#include + +//**************************************************************************** +// Function declarations. + +/* callback prototypes for hid0 instance */ +void sli_usbd_hid_hid0_enable(uint8_t class_nbr); + +void sli_usbd_hid_hid0_disable(uint8_t class_nbr); + +void sli_usbd_hid_hid0_get_report_desc(uint8_t class_nbr, const uint8_t **p_report_ptr, uint16_t *p_report_len); + +void sli_usbd_hid_hid0_get_phy_desc(uint8_t class_nbr, const uint8_t **p_report_ptr, uint16_t *p_report_len); + +void sli_usbd_hid_hid0_set_output_report( + uint8_t class_nbr, + uint8_t report_id, + uint8_t *p_report_buf, + uint16_t report_len); + +void sli_usbd_hid_hid0_get_feature_report( + uint8_t class_nbr, + uint8_t report_id, + uint8_t *p_report_buf, + uint16_t report_len); + +void sli_usbd_hid_hid0_set_feature_report( + uint8_t class_nbr, + uint8_t report_id, + uint8_t *p_report_buf, + uint16_t report_len); + +void sli_usbd_hid_hid0_get_protocol(uint8_t class_nbr, uint8_t *p_protocol); + +void sli_usbd_hid_hid0_set_protocol(uint8_t class_nbr, uint8_t protocol); + +//**************************************************************************** +// Global variables. + +/* variables for mouse0 instance */ + +uint8_t sl_usbd_hid_hid0_number = 0; + +uint8_t sl_usbd_hid_hid0_default_protocol = 0; + +static const uint8_t sli_usbd_hid_hid0_default_desc[] = { + SL_USBD_HID_GLOBAL_USAGE_PAGE + 1, SL_USBD_HID_USAGE_PAGE_GENERIC_DEVICE_CONTROLS, + SL_USBD_HID_LOCAL_USAGE + 1, 0x00, + SL_USBD_HID_MAIN_COLLECTION + 1, 0xFF, + SL_USBD_HID_LOCAL_USAGE + 1, 0x09, + SL_USBD_HID_MAIN_COLLECTION + 1, 0x01, + SL_USBD_HID_GLOBAL_USAGE_PAGE + 1, 0xA1, + SL_USBD_HID_LOCAL_USAGE_MIN + 1, 0x01, + SL_USBD_HID_LOCAL_USAGE_MAX + 1, 0x03, + SL_USBD_HID_GLOBAL_LOG_MIN + 1, 0x00, + SL_USBD_HID_GLOBAL_LOG_MAX + 1, 0x01, + SL_USBD_HID_GLOBAL_REPORT_COUNT + 1, 0x03, + SL_USBD_HID_GLOBAL_REPORT_SIZE + 1, 0x01, + SL_USBD_HID_MAIN_INPUT + 1, SL_USBD_HID_MAIN_DATA | SL_USBD_HID_MAIN_VARIABLE | SL_USBD_HID_MAIN_ABSOLUTE, + SL_USBD_HID_GLOBAL_REPORT_COUNT + 1, 0x01, + SL_USBD_HID_GLOBAL_REPORT_SIZE + 1, 0x0D, + SL_USBD_HID_MAIN_INPUT + 1, SL_USBD_HID_MAIN_CONSTANT, + SL_USBD_HID_GLOBAL_USAGE_PAGE + 1, SL_USBD_HID_USAGE_PAGE_GENERIC_DESKTOP_CONTROLS, + SL_USBD_HID_LOCAL_USAGE + 1, SL_USBD_HID_DV_X, + SL_USBD_HID_LOCAL_USAGE + 1, SL_USBD_HID_DV_Y, + SL_USBD_HID_GLOBAL_LOG_MIN + 1, 0x81, + SL_USBD_HID_GLOBAL_LOG_MAX + 1, 0x7F, + SL_USBD_HID_GLOBAL_REPORT_SIZE + 1, 0x08, + SL_USBD_HID_GLOBAL_REPORT_COUNT + 1, 0x02, + SL_USBD_HID_MAIN_INPUT + 1, SL_USBD_HID_MAIN_DATA | SL_USBD_HID_MAIN_VARIABLE | SL_USBD_HID_MAIN_RELATIVE, + SL_USBD_HID_MAIN_ENDCOLLECTION, SL_USBD_HID_MAIN_ENDCOLLECTION}; + +sl_usbd_hid_callbacks_t sli_usbd_hid_hid0_callbacks = { + sli_usbd_hid_hid0_enable, + sli_usbd_hid_hid0_disable, + sli_usbd_hid_hid0_get_report_desc, + sli_usbd_hid_hid0_get_phy_desc, + sli_usbd_hid_hid0_set_output_report, + sli_usbd_hid_hid0_get_feature_report, + sli_usbd_hid_hid0_set_feature_report, + sli_usbd_hid_hid0_get_protocol, + sli_usbd_hid_hid0_set_protocol, +}; + +//**************************************************************************** +// Callback functions. + +/* callback functions for mouse0 instance */ +void sli_usbd_hid_hid0_enable(uint8_t class_nbr) +{ + (void)&class_nbr; + + sl_usbd_hid_hid0_on_enable_event(); + + return; +} + +void sli_usbd_hid_hid0_disable(uint8_t class_nbr) +{ + (void)&class_nbr; + + sl_usbd_hid_hid0_on_disable_event(); + + return; +} + +void sli_usbd_hid_hid0_get_report_desc(uint8_t class_nbr, const uint8_t **p_report_ptr, uint16_t *p_report_len) +{ + (void)&class_nbr; + + *p_report_ptr = sli_usbd_hid_hid0_default_desc; + *p_report_len = sizeof(sli_usbd_hid_hid0_default_desc); + + sl_usbd_hid_hid0_on_get_report_desc_event(p_report_ptr, p_report_len); + + return; +} + +void sli_usbd_hid_hid0_get_phy_desc(uint8_t class_nbr, const uint8_t **p_report_ptr, uint16_t *p_report_len) +{ + (void)&class_nbr; + + *p_report_ptr = NULL; + *p_report_len = 0; + + sl_usbd_hid_hid0_on_get_phy_desc_event(p_report_ptr, p_report_len); + + return; +} + +void sli_usbd_hid_hid0_set_output_report( + uint8_t class_nbr, + uint8_t report_id, + uint8_t *p_report_buf, + uint16_t report_len) +{ + (void)&class_nbr; + + sl_usbd_hid_hid0_on_set_output_report_event(report_id, p_report_buf, report_len); + + return; +} + +void sli_usbd_hid_hid0_get_feature_report( + uint8_t class_nbr, + uint8_t report_id, + uint8_t *p_report_buf, + uint16_t report_len) +{ + (void)&class_nbr; + + memset(p_report_buf, 0, report_len); + + sl_usbd_hid_hid0_on_get_feature_report_event(report_id, p_report_buf, report_len); + + return; +} + +void sli_usbd_hid_hid0_set_feature_report( + uint8_t class_nbr, + uint8_t report_id, + uint8_t *p_report_buf, + uint16_t report_len) +{ + (void)&class_nbr; + + sl_usbd_hid_hid0_on_set_feature_report_event(report_id, p_report_buf, report_len); + + return; +} + +void sli_usbd_hid_hid0_get_protocol(uint8_t class_nbr, uint8_t *p_protocol) +{ + (void)&class_nbr; + + *p_protocol = sl_usbd_hid_hid0_default_protocol; + + sl_usbd_hid_hid0_on_get_protocol_event(p_protocol); + + return; +} + +void sli_usbd_hid_hid0_set_protocol(uint8_t class_nbr, uint8_t protocol) +{ + (void)&class_nbr; + + sl_usbd_hid_hid0_default_protocol = protocol; + + sl_usbd_hid_hid0_on_set_protocol_event(protocol); + + return; +} + +//**************************************************************************** +// Global functions. + +/* initialize hid0 instance */ +void sli_usbd_hid_hid0_init() +{ + sl_usbd_hid_country_code_t country = SL_USBD_HID_COUNTRY_CODE_NOT_SUPPORTED; + + uint8_t subclass = 0; + uint8_t protocol = 0; + + uint16_t interval_in = 0; + uint16_t interval_out = 0; + bool ctrl_rd_en = true; + + uint8_t class_number = 0; + uint8_t config_number = 0; + char *configs = NULL; + char *token = NULL; + + /* configs to attach the class instance to */ + configs = SL_USBD_HID_HID0_CONFIGURATIONS; + + /* read subclass, protocol, and country codes */ + subclass = SL_USBD_HID_HID0_SUBCLASS; + protocol = SL_USBD_HID_HID0_PROTOCOL; + country = SL_USBD_HID_HID0_COUNTRY_CODE; + + /* read endpoint parameters */ + interval_in = SL_USBD_HID_HID0_INTERVAL_IN; + interval_out = SL_USBD_HID_HID0_INTERVAL_OUT; + ctrl_rd_en = SL_USBD_HID_HID0_ENABLE_CTRL_RD; + + /* create HID instance */ + sl_usbd_hid_create_instance( + subclass, + protocol, + country, + interval_in, + interval_out, + ctrl_rd_en, + &sli_usbd_hid_hid0_callbacks, + &class_number); + + /* store class number globally */ + sl_usbd_hid_hid0_number = class_number; + + /* tokenize configs by "," and spaces */ + token = strtok(configs, ", "); + + /* loop over tokens */ + while (token != NULL) + { + + /* add to config0? */ + if (!strcmp(token, "config0") || !strcmp(token, "all")) + { + config_number = sl_usbd_configuration_config0_number; + sl_usbd_hid_add_to_configuration(class_number, config_number); + } + + /* next token */ + token = strtok(NULL, ", "); + } +} diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/autogen/sl_usbd_class_hid_instances.h b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/autogen/sl_usbd_class_hid_instances.h new file mode 100644 index 0000000000..fa9e5b853a --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/autogen/sl_usbd_class_hid_instances.h @@ -0,0 +1,32 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Portions Copyright 2018 Silicon Laboratories Inc. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +#ifndef SL_USBD_CLASS_HID_INSTANCES_INIT +#define SL_USBD_CLASS_HID_INSTANCES_INIT + +#include "sl_usbd_class_hid.h" + +/* class numbers assigned by the USB stack after init */ + +extern uint8_t sl_usbd_hid_hid0_number; + +/* event handlers for all HID instances */ + +__WEAK void sl_usbd_hid_hid0_on_enable_event(void); +__WEAK void sl_usbd_hid_hid0_on_disable_event(void); +__WEAK void sl_usbd_hid_hid0_on_get_report_desc_event(const uint8_t **p_report_ptr, uint16_t *p_report_len); +__WEAK void sl_usbd_hid_hid0_on_get_phy_desc_event(const uint8_t **p_report_ptr, uint16_t *p_report_len); +__WEAK void sl_usbd_hid_hid0_on_set_output_report_event(uint8_t report_id, uint8_t *p_report_buf, uint16_t report_len); +__WEAK void sl_usbd_hid_hid0_on_get_feature_report_event(uint8_t report_id, uint8_t *p_report_buf, uint16_t report_len); +__WEAK void sl_usbd_hid_hid0_on_set_feature_report_event(uint8_t report_id, uint8_t *p_report_buf, uint16_t report_len); +__WEAK void sl_usbd_hid_hid0_on_get_protocol_event(uint8_t *p_protocol); +__WEAK void sl_usbd_hid_hid0_on_set_protocol_event(uint8_t protocol); + +/* init functions for all HID instances */ + +void sli_usbd_hid_hid0_init(void); + +#endif diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/autogen/sl_usbd_configuration_instances.c b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/autogen/sl_usbd_configuration_instances.c new file mode 100644 index 0000000000..0a865bccfc --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/autogen/sl_usbd_configuration_instances.c @@ -0,0 +1,61 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Portions Copyright 2018 Silicon Laboratories Inc. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +//**************************************************************************** +// Includes. + +#include +#include + +/* template headers */ +#include "sl_usbd_configuration_instances.h" + +/* include config file for the instances */ + +#include + +//**************************************************************************** +// Global variables. + +/* configuration numbers assigned by the USB stack after init */ + +uint8_t sl_usbd_configuration_config0_number = 0; + +//**************************************************************************** +// Global functions. + +/* initialize config0 instance */ +void sli_usbd_configuration_config0_init() +{ + uint8_t attrib = 0; + uint16_t power = 0; + sl_usbd_device_speed_t speed = SL_USBD_DEVICE_SPEED_FULL; + const char *name = NULL; + uint8_t number = 0; + + /* configuration attributes */ +#if SL_USB_CONFIGURATION_CONFIG0_POWER_SOURCE == 1 + attrib |= SL_USBD_DEV_ATTRIB_SELF_POWERED; +#endif +#if SL_USB_CONFIGURATION_CONFIG0_REMOTE_WAKEUP == 1 + attrib |= SL_USBD_DEV_ATTRIB_REMOTE_WAKEUP; +#endif + + /* configuration maximum power (mA) */ + power = SL_USB_CONFIGURATION_CONFIG0_MAXIMUM_POWER; + + /* configuration speed */ + speed = SL_USBD_DEVICE_SPEED_FULL; + + /* configuration name */ + name = SL_USB_CONFIGURATION_CONFIG0_NAME; + + /* create the configuration descriptor */ + sl_usbd_core_add_configuration(attrib, power, speed, name, &number); + + /* store the configuration number globally */ + sl_usbd_configuration_config0_number = number; +} diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/autogen/sl_usbd_configuration_instances.h b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/autogen/sl_usbd_configuration_instances.h new file mode 100644 index 0000000000..07726e93fe --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/autogen/sl_usbd_configuration_instances.h @@ -0,0 +1,18 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Portions Copyright 2018 Silicon Laboratories Inc. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +#ifndef SL_USBD_CONFIGURATION_INSTANCES_INIT +#define SL_USBD_CONFIGURATION_INSTANCES_INIT + +/* configuration numbers assigned by the USB stack after init */ + +extern uint8_t sl_usbd_configuration_config0_number; + +/* init functions for all configuration instances */ + +void sli_usbd_configuration_config0_init(void); + +#endif diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/common/CMakeLists.txt b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/common/CMakeLists.txt new file mode 100644 index 0000000000..8ea7907f60 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/common/CMakeLists.txt @@ -0,0 +1,10 @@ +# +# Copyright (c) .NET Foundation and Contributors +# See LICENSE file in the project root for full license information. +# + +# append common source files +list(APPEND COMMON_PROJECT_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/Device_BlockStorage$<$,$>:-DEBUG>.c) + +# make var global +set(COMMON_PROJECT_SOURCES ${COMMON_PROJECT_SOURCES} CACHE INTERNAL "make global") diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/common/Device_BlockStorage-DEBUG.c b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/common/Device_BlockStorage-DEBUG.c new file mode 100644 index 0000000000..2b61b85671 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/common/Device_BlockStorage-DEBUG.c @@ -0,0 +1,123 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include +#include + +// 2kB blocks +const BlockRange BlockRange1[] = { + + // 00000000 nanoBooter + {BlockRange_BLOCKTYPE_BOOTSTRAP, 0, 18}, + + // 00013000 nanoCLR + {BlockRange_BLOCKTYPE_CODE, 19, 238}, + + // 000EF000 deployment + {BlockRange_BLOCKTYPE_DEPLOYMENT, 239, 510}, + + /////////////////////////////////////////////////////////////////////////////////////// + // because this target is using a configuration block need to add the + // configuration manager files to the CMake and call ConfigurationManager_Initialize() + // in nanoBooter so the configuration can be managed when in booter mode + /////////////////////////////////////////////////////////////////////////////////////// + // 001FF000 configuration block + {BlockRange_BLOCKTYPE_CONFIG, 511, 511}, + /////////////////////////////////////////////////////////////////////////////////////// +}; + +const BlockRegionInfo BlockRegions[] = { + { + (0), + + // start address for block region + 0x00000000, + + // total number of blocks in this region + 512, + + // total number of bytes per block + 0x1000, + + ARRAYSIZE_CONST_EXPR(BlockRange1), + BlockRange1, + }, +}; + +const DeviceBlockInfo Device_BlockInfo = { + + // GG11 flash memory is XIP + (MediaAttribute_SupportsXIP), + + // UINT32 BytesPerSector + 2, + + // UINT32 NumRegions; + ARRAYSIZE_CONST_EXPR(BlockRegions), + + // const BlockRegionInfo* pRegions; + (BlockRegionInfo *)BlockRegions, +}; + +MEMORY_MAPPED_NOR_BLOCK_CONFIG Device_BlockStorageConfig = { + { + // BLOCK_CONFIG + { + // GPIO_PIN Pin; + 0, + + // BOOL ActiveState + + false, + }, + + // BlockDeviceinfo + (DeviceBlockInfo *)&Device_BlockInfo, + }, + + { + // CPU_MEMORY_CONFIG + // UINT8 CPU_MEMORY_CONFIG::ChipSelect; + 0, + + // UINT8 CPU_MEMORY_CONFIG::ReadOnly; + true, + + // UINT32 CPU_MEMORY_CONFIG::WaitStates; + 0, + + // UINT32 CPU_MEMORY_CONFIG::ReleaseCounts; + 0, + + // UINT32 CPU_MEMORY_CONFIG::BitWidth; + 16, + + // UINT32 CPU_MEMORY_CONFIG::BaseAddress; + 0x08000000, + + // UINT32 CPU_MEMORY_CONFIG::SizeInBytes; + 0x00200000, + + // UINT8 CPU_MEMORY_CONFIG::XREADYEnable + 0, + + // UINT8 CPU_MEMORY_CONFIG::ByteSignalsForRead + 0, + + // UINT8 CPU_MEMORY_CONFIG::ExternalBufferEnable + 0, + }, + + // UINT32 ChipProtection; + 0, + + // UINT32 ManufacturerCode; + 0, + + // UINT32 DeviceCode; + 0, +}; + +BlockStorageDevice Device_BlockStorage; diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/common/Device_BlockStorage.c b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/common/Device_BlockStorage.c new file mode 100644 index 0000000000..9b93ac6cf1 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/common/Device_BlockStorage.c @@ -0,0 +1,123 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include +#include + +// 2kB blocks +const BlockRange BlockRange1[] = { + + // 00000000 nanoBooter + {BlockRange_BLOCKTYPE_BOOTSTRAP, 0, 11}, + + // 0000C000 nanoCLR + {BlockRange_BLOCKTYPE_CODE, 12, 158}, + + // 0009F000 deployment + {BlockRange_BLOCKTYPE_DEPLOYMENT, 159, 509}, + + /////////////////////////////////////////////////////////////////////////////////////// + // because this target is using a configuration block need to add the + // configuration manager files to the CMake and call ConfigurationManager_Initialize() + // in nanoBooter so the configuration can be managed when in booter mode + /////////////////////////////////////////////////////////////////////////////////////// + // 001FF000 configuration block + {BlockRange_BLOCKTYPE_CONFIG, 511, 511}, + /////////////////////////////////////////////////////////////////////////////////////// +}; + +const BlockRegionInfo BlockRegions[] = { + { + (0), + + // start address for block region + 0x00000000, + + // total number of blocks in this region + 512, + + // total number of bytes per block + 0x1000, + + ARRAYSIZE_CONST_EXPR(BlockRange1), + BlockRange1, + }, +}; + +const DeviceBlockInfo Device_BlockInfo = { + + // GG11 flash memory is XIP + (MediaAttribute_SupportsXIP), + + // UINT32 BytesPerSector + 2, + + // UINT32 NumRegions; + ARRAYSIZE_CONST_EXPR(BlockRegions), + + // const BlockRegionInfo* pRegions; + (BlockRegionInfo *)BlockRegions, +}; + +MEMORY_MAPPED_NOR_BLOCK_CONFIG Device_BlockStorageConfig = { + { + // BLOCK_CONFIG + { + // GPIO_PIN Pin; + 0, + + // BOOL ActiveState + + false, + }, + + // BlockDeviceinfo + (DeviceBlockInfo *)&Device_BlockInfo, + }, + + { + // CPU_MEMORY_CONFIG + // UINT8 CPU_MEMORY_CONFIG::ChipSelect; + 0, + + // UINT8 CPU_MEMORY_CONFIG::ReadOnly; + true, + + // UINT32 CPU_MEMORY_CONFIG::WaitStates; + 0, + + // UINT32 CPU_MEMORY_CONFIG::ReleaseCounts; + 0, + + // UINT32 CPU_MEMORY_CONFIG::BitWidth; + 16, + + // UINT32 CPU_MEMORY_CONFIG::BaseAddress; + 0x08000000, + + // UINT32 CPU_MEMORY_CONFIG::SizeInBytes; + 0x00200000, + + // UINT8 CPU_MEMORY_CONFIG::XREADYEnable + 0, + + // UINT8 CPU_MEMORY_CONFIG::ByteSignalsForRead + 0, + + // UINT8 CPU_MEMORY_CONFIG::ExternalBufferEnable + 0, + }, + + // UINT32 ChipProtection; + 0, + + // UINT32 ManufacturerCode; + 0, + + // UINT32 DeviceCode; + 0, +}; + +BlockStorageDevice Device_BlockStorage; diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/common/tx_initialize_low_level.S b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/common/tx_initialize_low_level.S new file mode 100644 index 0000000000..39ad790f18 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/common/tx_initialize_low_level.S @@ -0,0 +1,239 @@ +@/**************************************************************************/ +@/* */ +@/* Copyright (c) Microsoft Corporation. All rights reserved. */ +@/* */ +@/* This software is licensed under the Microsoft Software License */ +@/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +@/* and in the root directory of this software. */ +@/* */ +@/**************************************************************************/ +@ +@ +@/**************************************************************************/ +@/**************************************************************************/ +@/** */ +@/** ThreadX Component */ +@/** */ +@/** Initialize */ +@/** */ +@/**************************************************************************/ +@/**************************************************************************/ +@ +@#define TX_SOURCE_CODE +@ +@ +@/* Include necessary system files. */ +@ +@#include "tx_api.h" +@#include "tx_initialize.h" +@#include "tx_thread.h" +@#include "tx_timer.h" +@ +@ + .global _tx_thread_system_stack_ptr + .global _tx_initialize_unused_memory + .global __RAM_segment_used_end__ + .global _tx_timer_interrupt + .global __main + .global __tx_SVCallHandler + .global __tx_PendSVHandler + .global _vectors + .global __tx_NMIHandler @ NMI + .global __tx_BadHandler @ HardFault + .global __tx_SVCallHandler @ SVCall + .global __tx_DBGHandler @ Monitor + .global __tx_PendSVHandler @ PendSV + .global __tx_SysTickHandler @ SysTick + .global __tx_IntHandler @ Int 0 +@ +@ +SYSTEM_CLOCK = 38000000 +SYSTICK_CYCLES = ((SYSTEM_CLOCK / 1000) -1) + + .text 32 + .align 4 + .syntax unified +@/**************************************************************************/ +@/* */ +@/* FUNCTION RELEASE */ +@/* */ +@/* _tx_initialize_low_level Cortex-M7/GNU */ +@/* 6.0 */ +@/* AUTHOR */ +@/* */ +@/* William E. Lamie, Microsoft Corporation */ +@/* */ +@/* DESCRIPTION */ +@/* */ +@/* This function is responsible for any low-level processor */ +@/* initialization, including setting up interrupt vectors, setting */ +@/* up a periodic timer interrupt source, saving the system stack */ +@/* pointer for use in ISR processing later, and finding the first */ +@/* available RAM memory address for tx_application_define. */ +@/* */ +@/* INPUT */ +@/* */ +@/* None */ +@/* */ +@/* OUTPUT */ +@/* */ +@/* None */ +@/* */ +@/* CALLS */ +@/* */ +@/* None */ +@/* */ +@/* CALLED BY */ +@/* */ +@/* _tx_initialize_kernel_enter ThreadX entry function */ +@/* */ +@/* RELEASE HISTORY */ +@/* */ +@/* DATE NAME DESCRIPTION */ +@/* */ +@/* 05-19-2020 William E. Lamie Initial Version 6.0 */ +@/* */ +@/**************************************************************************/ +@VOID _tx_initialize_low_level(VOID) +@{ + .global _tx_initialize_low_level + .thumb_func +_tx_initialize_low_level: +@ +@ /* Disable interrupts during ThreadX initialization. */ +@ + CPSID i +@ +@ /* Set base of available memory to end of non-initialised RAM area. */ +@ + LDR r0, =_tx_initialize_unused_memory @ Build address of unused memory pointer + LDR r1, =__RAM_segment_used_end__ @ Build first free address + ADD r1, r1, #4 @ + STR r1, [r0] @ Setup first unused memory pointer +@ +@ /* Setup Vector Table Offset Register. */ +@ + MOV r0, #0xE000E000 @ Build address of NVIC registers + LDR r1, =__Vectors @ Pickup address of vector table + STR r1, [r0, #0xD08] @ Set vector table address +@ +@ /* Set system stack pointer from vector value. */ +@ + LDR r0, =_tx_thread_system_stack_ptr @ Build address of system stack pointer + LDR r1, =__Vectors @ Pickup address of vector table + LDR r1, [r1] @ Pickup reset stack pointer + STR r1, [r0] @ Save system stack pointer +@ +@ /* Enable the cycle count register. */ +@ + LDR r0, =0xE0001000 @ Build address of DWT register + LDR r1, [r0] @ Pickup the current value + ORR r1, r1, #1 @ Set the CYCCNTENA bit + STR r1, [r0] @ Enable the cycle count register +@ +@ /* Configure SysTick for 100Hz clock, or 16384 cycles if no reference. */ +@ + MOV r0, #0xE000E000 @ Build address of NVIC registers + LDR r1, =SYSTICK_CYCLES + STR r1, [r0, #0x14] @ Setup SysTick Reload Value + MOV r1, #0x7 @ Build SysTick Control Enable Value + STR r1, [r0, #0x10] @ Setup SysTick Control +@ +@ /* Configure handler priorities. */ +@ + LDR r1, =0x00000000 @ Rsrv, UsgF, BusF, MemM + STR r1, [r0, #0xD18] @ Setup System Handlers 4-7 Priority Registers + + LDR r1, =0xFF000000 @ SVCl, Rsrv, Rsrv, Rsrv + STR r1, [r0, #0xD1C] @ Setup System Handlers 8-11 Priority Registers + @ Note: SVC must be lowest priority, which is 0xFF + + LDR r1, =0x40FF0000 @ SysT, PnSV, Rsrv, DbgM + STR r1, [r0, #0xD20] @ Setup System Handlers 12-15 Priority Registers + @ Note: PnSV must be lowest priority, which is 0xFF + +@ +@ /* Return to caller. */ +@ + BX lr +@} +@ + +@/* Define shells for each of the unused vectors. */ +@ + .global __tx_BadHandler + .thumb_func +__tx_BadHandler: + B __tx_BadHandler + +@ /* added to catch the hardfault */ + + .global __tx_HardfaultHandler + .thumb_func +__tx_HardfaultHandler: + B __tx_HardfaultHandler + + +@ /* added to catch the SVC */ + + .global __tx_SVCallHandler + .thumb_func +__tx_SVCallHandler: + B __tx_SVCallHandler + + +@ /* Generic interrupt handler template */ + .global __tx_IntHandler + .thumb_func +__tx_IntHandler: +@ VOID InterruptHandler (VOID) +@ { + PUSH {r0, lr} +#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY + BL _tx_execution_isr_enter @ Call the ISR enter function +#endif + +@ /* Do interrupt handler work here */ +@ /* BL .... */ + +#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY + BL _tx_execution_isr_exit @ Call the ISR exit function +#endif + POP {r0, lr} + BX LR +@ } + +@ /* System Tick timer interrupt handler */ + .global __tx_SysTickHandler + .global SysTick_Handler + .thumb_func +__tx_SysTickHandler: + .thumb_func +SysTick_Handler: +@ VOID TimerInterruptHandler (VOID) +@ { +@ + PUSH {r0, lr} +#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY + BL _tx_execution_isr_enter @ Call the ISR enter function +#endif + BL _tx_timer_interrupt +#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY + BL _tx_execution_isr_exit @ Call the ISR exit function +#endif + POP {r0, lr} + BX LR +@ } + + +@ /* NMI, DBG handlers */ + .global __tx_NMIHandler + .thumb_func +__tx_NMIHandler: + B __tx_NMIHandler + + .global __tx_DBGHandler + .thumb_func +__tx_DBGHandler: + B __tx_DBGHandler diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/config/pin_config.h b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/config/pin_config.h new file mode 100644 index 0000000000..158edf847a --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/config/pin_config.h @@ -0,0 +1,259 @@ +#ifndef PIN_CONFIG_H +#define PIN_CONFIG_H + +// $[ACMP0] +// [ACMP0]$ + +// $[ACMP1] +// [ACMP1]$ + +// $[ACMP2] +// [ACMP2]$ + +// $[ACMP3] +// [ACMP3]$ + +// $[ADC0] +// [ADC0]$ + +// $[ADC1] +// [ADC1]$ + +// $[BU] +// [BU]$ + +// $[CAN0] +// [CAN0]$ + +// $[CAN1] +// [CAN1]$ + +// $[CMU] +// [CMU]$ + +// $[DBG] +// [DBG]$ + +// $[EBI] +// [EBI]$ + +// $[ETH] +// [ETH]$ + +// $[ETM] +// [ETM]$ + +// $[GPIO] +// [GPIO]$ + +// $[I2C0] +// [I2C0]$ + +// $[I2C1] +// [I2C1]$ + +// $[I2C2] +// [I2C2]$ + +// $[IDAC0] +// [IDAC0]$ + +// $[LCD] +// [LCD]$ + +// $[LESENSE] +// [LESENSE]$ + +// $[LETIMER0] +// [LETIMER0]$ + +// $[LETIMER1] +// [LETIMER1]$ + +// $[LEUART0] +// [LEUART0]$ + +// $[LEUART1] +// [LEUART1]$ + +// $[LFXO] +// [LFXO]$ + +// $[PCNT0] +// [PCNT0]$ + +// $[PCNT1] +// [PCNT1]$ + +// $[PCNT2] +// [PCNT2]$ + +// $[PRS.CH0] +// [PRS.CH0]$ + +// $[PRS.CH1] +// [PRS.CH1]$ + +// $[PRS.CH2] +// [PRS.CH2]$ + +// $[PRS.CH3] +// [PRS.CH3]$ + +// $[PRS.CH4] +// [PRS.CH4]$ + +// $[PRS.CH5] +// [PRS.CH5]$ + +// $[PRS.CH6] +// [PRS.CH6]$ + +// $[PRS.CH7] +// [PRS.CH7]$ + +// $[PRS.CH8] +// [PRS.CH8]$ + +// $[PRS.CH9] +// [PRS.CH9]$ + +// $[PRS.CH10] +// [PRS.CH10]$ + +// $[PRS.CH11] +// [PRS.CH11]$ + +// $[PRS.CH12] +// [PRS.CH12]$ + +// $[PRS.CH13] +// [PRS.CH13]$ + +// $[PRS.CH14] +// [PRS.CH14]$ + +// $[PRS.CH15] +// [PRS.CH15]$ + +// $[PRS.CH16] +// [PRS.CH16]$ + +// $[PRS.CH17] +// [PRS.CH17]$ + +// $[PRS.CH18] +// [PRS.CH18]$ + +// $[PRS.CH19] +// [PRS.CH19]$ + +// $[PRS.CH20] +// [PRS.CH20]$ + +// $[PRS.CH21] +// [PRS.CH21]$ + +// $[PRS.CH22] +// [PRS.CH22]$ + +// $[PRS.CH23] +// [PRS.CH23]$ + +// $[QSPI0] +// [QSPI0]$ + +// $[SDIO] +// [SDIO]$ + +// $[TIMER0] +// [TIMER0]$ + +// $[TIMER1] +// [TIMER1]$ + +// $[TIMER2] +// [TIMER2]$ + +// $[TIMER3] +// [TIMER3]$ + +// $[TIMER4] +// [TIMER4]$ + +// $[TIMER5] +// [TIMER5]$ + +// $[TIMER6] +// [TIMER6]$ + +// $[UART0] +// [UART0]$ + +// $[UART1] +// [UART1]$ + +// $[USART0] +// [USART0]$ + +// $[USART1] +// [USART1]$ + +// $[USART2] +// [USART2]$ + +// $[USART3] +// [USART3]$ + +// $[USART4] +// USART4 CTS on PH8 +#define USART4_CTS_PORT gpioPortH +#define USART4_CTS_PIN 8 +#define USART4_CTS_LOC 4 + +// USART4 RTS on PH9 +#define USART4_RTS_PORT gpioPortH +#define USART4_RTS_PIN 9 +#define USART4_RTS_LOC 4 + +// USART4 RX on PH5 +#define USART4_RX_PORT gpioPortH +#define USART4_RX_PIN 5 +#define USART4_RX_LOC 4 + +// USART4 TX on PH4 +#define USART4_TX_PORT gpioPortH +#define USART4_TX_PIN 4 +#define USART4_TX_LOC 4 + +// [USART4]$ + +// $[USART5] +// [USART5]$ + +// $[USB] +// [USB]$ + +// $[VDAC0] +// [VDAC0]$ + +// $[WFXO] +// [WFXO]$ + +// $[WTIMER0] +// [WTIMER0]$ + +// $[WTIMER1] +// [WTIMER1]$ + +// $[WTIMER2] +// [WTIMER2]$ + +// $[WTIMER3] +// [WTIMER3]$ + +// $[CUSTOM_PIN_NAME] +// [CUSTOM_PIN_NAME]$ + +#endif // PIN_CONFIG_H + diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/config/sl_board_control_config.h b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/config/sl_board_control_config.h new file mode 100644 index 0000000000..5796117234 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/config/sl_board_control_config.h @@ -0,0 +1,112 @@ +/***************************************************************************//** + * @file + * @brief Board Control + ******************************************************************************* + * # License + * Copyright 2022 Silicon Laboratories Inc. www.silabs.com + ******************************************************************************* + * + * SPDX-License-Identifier: Zlib + * + * The licensor of this software is Silicon Laboratories Inc. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + ******************************************************************************/ + +#ifndef SL_BOARD_CONTROL_CONFIG_H +#define SL_BOARD_CONTROL_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +// Enable Virtual COM UART +// Default: 0 +#define SL_BOARD_ENABLE_VCOM 1 + +// Enable Display +// Default: 0 +#define SL_BOARD_ENABLE_DISPLAY 1 + +// Enable Relative Humidity and Temperature sensor +// Default: 0 +#define SL_BOARD_ENABLE_SENSOR_RHT 1 + +// Enable Hall Effect sensor +// Default: 0 +#define SL_BOARD_ENABLE_SENSOR_HALL 0 + +// Enable Microphone +// Default: 0 +#define SL_BOARD_ENABLE_SENSOR_MICROPHONE 0 + +// Enable QSPI Flash +// Default: 0 +#define SL_BOARD_ENABLE_MEMORY_QSPI 0 + +// Enable SD Card +// Default: 0 +#define SL_BOARD_ENABLE_MEMORY_SDCARD 0 + +// <<< end of configuration section >>> + +// <<< sl:start pin_tool >>> + +// SL_BOARD_ENABLE_VCOM +// $[GPIO_SL_BOARD_ENABLE_VCOM] +#define SL_BOARD_ENABLE_VCOM_PORT gpioPortE +#define SL_BOARD_ENABLE_VCOM_PIN 1 +// [GPIO_SL_BOARD_ENABLE_VCOM]$ + +// SL_BOARD_ENABLE_DISPLAY +// $[GPIO_SL_BOARD_ENABLE_DISPLAY] +#define SL_BOARD_ENABLE_DISPLAY_PORT gpioPortA +#define SL_BOARD_ENABLE_DISPLAY_PIN 9 +// [GPIO_SL_BOARD_ENABLE_DISPLAY]$ + +// SL_BOARD_ENABLE_SENSOR_RHT +// $[GPIO_SL_BOARD_ENABLE_SENSOR_RHT] +#define SL_BOARD_ENABLE_SENSOR_RHT_PORT gpioPortB +#define SL_BOARD_ENABLE_SENSOR_RHT_PIN 3 +// [GPIO_SL_BOARD_ENABLE_SENSOR_RHT]$ + +// SL_BOARD_ENABLE_SENSOR_HALL +// $[GPIO_SL_BOARD_ENABLE_SENSOR_HALL] +#define SL_BOARD_ENABLE_SENSOR_HALL_PORT gpioPortB +#define SL_BOARD_ENABLE_SENSOR_HALL_PIN 3 +// [GPIO_SL_BOARD_ENABLE_SENSOR_HALL]$ + +// SL_BOARD_ENABLE_SENSOR_MICROPHONE +// $[GPIO_SL_BOARD_ENABLE_SENSOR_MICROPHONE] +#define SL_BOARD_ENABLE_SENSOR_MICROPHONE_PORT gpioPortD +#define SL_BOARD_ENABLE_SENSOR_MICROPHONE_PIN 0 +// [GPIO_SL_BOARD_ENABLE_SENSOR_MICROPHONE]$ + +// SL_BOARD_ENABLE_MEMORY_QSPI +// $[GPIO_SL_BOARD_ENABLE_MEMORY_QSPI] +#define SL_BOARD_ENABLE_MEMORY_QSPI_PORT gpioPortG +#define SL_BOARD_ENABLE_MEMORY_QSPI_PIN 13 +// [GPIO_SL_BOARD_ENABLE_MEMORY_QSPI]$ + +// SL_BOARD_ENABLE_MEMORY_SDCARD +// $[GPIO_SL_BOARD_ENABLE_MEMORY_SDCARD] +#define SL_BOARD_ENABLE_MEMORY_SDCARD_PORT gpioPortE +#define SL_BOARD_ENABLE_MEMORY_SDCARD_PIN 7 +// [GPIO_SL_BOARD_ENABLE_MEMORY_SDCARD]$ + +// <<< sl:end pin_tool >>> + +#endif // SL_BOARD_CONTROL_CONFIG_H diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/config/sl_iostream_usart_vcom_config.h b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/config/sl_iostream_usart_vcom_config.h new file mode 100644 index 0000000000..59d33b8885 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/config/sl_iostream_usart_vcom_config.h @@ -0,0 +1,112 @@ +/***************************************************************************//** + * @file + * @brief IOSTREAM_USART Config. + ******************************************************************************* + * # License + * Copyright 2020 Silicon Laboratories Inc. www.silabs.com + ******************************************************************************* + * + * SPDX-License-Identifier: Zlib + * + * The licensor of this software is Silicon Laboratories Inc. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + ******************************************************************************/ + +#ifndef SL_IOSTREAM_USART_VCOM_CONFIG_H +#define SL_IOSTREAM_USART_VCOM_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +// USART settings + +// Baud rate +// Default: 115200 +#define SL_IOSTREAM_USART_VCOM_BAUDRATE 921600 + +// Parity mode to use +// No Parity +// Even parity +// Odd parity +// Default: usartNoParity +#define SL_IOSTREAM_USART_VCOM_PARITY usartNoParity + +// Number of stop bits to use. +// 0.5 stop bits +// 1 stop bits +// 1.5 stop bits +// 2 stop bits +// Default: usartStopbits1 +#define SL_IOSTREAM_USART_VCOM_STOP_BITS usartStopbits1 + +// Flow control +// None +// CTS +// RTS +// CTS/RTS +// Software Flow control (XON/XOFF) +// Default: usartHwFlowControlNone +#define SL_IOSTREAM_USART_VCOM_FLOW_CONTROL_TYPE usartHwFlowControlNone + +// Receive buffer size +// Default: 32 +#define SL_IOSTREAM_USART_VCOM_RX_BUFFER_SIZE 512+32 + +// Convert \n to \r\n +// It can be changed at runtime using the C API. +// Default: 0 +#define SL_IOSTREAM_USART_VCOM_CONVERT_BY_DEFAULT_LF_TO_CRLF 0 + +// Restrict the energy mode to allow the reception. +// Default: 1 +// Limits the lowest energy mode the system can sleep to in order to keep the reception on. May cause higher power consumption. +#define SL_IOSTREAM_USART_VCOM_RESTRICT_ENERGY_MODE_TO_ALLOW_RECEPTION 1 + +// + +// <<< end of configuration section >>> + +// <<< sl:start pin_tool >>> +// SL_IOSTREAM_USART_VCOM +// $[USART_SL_IOSTREAM_USART_VCOM] +#define SL_IOSTREAM_USART_VCOM_PERIPHERAL USART4 +#define SL_IOSTREAM_USART_VCOM_PERIPHERAL_NO 4 + +// USART4 TX on PH4 +#define SL_IOSTREAM_USART_VCOM_TX_PORT gpioPortH +#define SL_IOSTREAM_USART_VCOM_TX_PIN 4 +#define SL_IOSTREAM_USART_VCOM_TX_LOC 4 + +// USART4 RX on PH5 +#define SL_IOSTREAM_USART_VCOM_RX_PORT gpioPortH +#define SL_IOSTREAM_USART_VCOM_RX_PIN 5 +#define SL_IOSTREAM_USART_VCOM_RX_LOC 4 + +// USART4 CTS on PH8 +#define SL_IOSTREAM_USART_VCOM_CTS_PORT gpioPortH +#define SL_IOSTREAM_USART_VCOM_CTS_PIN 8 +#define SL_IOSTREAM_USART_VCOM_CTS_LOC 4 + +// USART4 RTS on PH9 +#define SL_IOSTREAM_USART_VCOM_RTS_PORT gpioPortH +#define SL_IOSTREAM_USART_VCOM_RTS_PIN 9 +#define SL_IOSTREAM_USART_VCOM_RTS_LOC 4 +// [USART_SL_IOSTREAM_USART_VCOM]$ +// <<< sl:end pin_tool >>> + +#endif diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/config/sl_memory_config.h b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/config/sl_memory_config.h new file mode 100644 index 0000000000..4f20db4a24 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/config/sl_memory_config.h @@ -0,0 +1,13 @@ +#ifndef SL_MEMORY_CONFIG_H +#define SL_MEMORY_CONFIG_H + +// These parameters are meant to be set in the target CMakeLists.txt file +#ifndef SL_STACK_SIZE +#error "Missing compiler define for SL_STACK_SIZE in target CMakeLists.txt" +#endif + +#ifndef SL_HEAP_SIZE +#error "Missing compiler define for SL_HEAP_SIZE in target CMakeLists.txt" +#endif + +#endif diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/config/sl_uartdrv_usart_vcom_config.h b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/config/sl_uartdrv_usart_vcom_config.h new file mode 100644 index 0000000000..b9b92ff77c --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/config/sl_uartdrv_usart_vcom_config.h @@ -0,0 +1,85 @@ +#ifndef SL_UARTDRV_USART_VCOM_CONFIG_H +#define SL_UARTDRV_USART_VCOM_CONFIG_H + +#include "em_usart.h" +// <<< Use Configuration Wizard in Context Menu >>> + +// UART settings +// Baud rate +// Default: 115200 +#define SL_UARTDRV_USART_VCOM_BAUDRATE 115200 + +// Parity mode to use +// No Parity +// Even parity +// Odd parity +// Default: usartNoParity +#define SL_UARTDRV_USART_VCOM_PARITY usartNoParity + +// Number of stop bits to use. +// 0.5 stop bits +// 1 stop bits +// 1.5 stop bits +// 2 stop bits +// Default: usartStopbits1 +#define SL_UARTDRV_USART_VCOM_STOP_BITS usartStopbits1 + +// Flow control method +// None +// Software XON/XOFF +// nRTS/nCTS hardware handshake +// UART peripheral controls nRTS/nCTS +// Default: uartdrvFlowControlHw +#define SL_UARTDRV_USART_VCOM_FLOW_CONTROL_TYPE uartdrvFlowControlNone + +// Oversampling selection +// 16x oversampling +// 8x oversampling +// 6x oversampling +// 4x oversampling +// Default: usartOVS16 +#define SL_UARTDRV_USART_VCOM_OVERSAMPLING usartOVS4 + +// Majority vote disable for 16x, 8x and 6x oversampling modes +// True +// False +#define SL_UARTDRV_USART_VCOM_MVDIS false + +// Size of the receive operation queue +// Default: 6 +#define SL_UARTDRV_USART_VCOM_RX_BUFFER_SIZE 2 + +// Size of the transmit operation queue +// Default: 6 +#define SL_UARTDRV_USART_VCOM_TX_BUFFER_SIZE 2 +// +// <<< end of configuration section >>> + +// <<< sl:start pin_tool >>> +// SL_UARTDRV_USART_VCOM +// $[USART_SL_UARTDRV_USART_VCOM] +#define SL_UARTDRV_USART_VCOM_PERIPHERAL USART4 +#define SL_UARTDRV_USART_VCOM_PERIPHERAL_NO 4 + +// USART4 TX on PH4 +#define SL_UARTDRV_USART_VCOM_TX_PORT gpioPortH +#define SL_UARTDRV_USART_VCOM_TX_PIN 4 +#define SL_UARTDRV_USART_VCOM_TX_LOC 4 + +// USART4 RX on PH5 +#define SL_UARTDRV_USART_VCOM_RX_PORT gpioPortH +#define SL_UARTDRV_USART_VCOM_RX_PIN 5 +#define SL_UARTDRV_USART_VCOM_RX_LOC 4 + +// USART4 CTS on PH8 +#define SL_UARTDRV_USART_VCOM_CTS_PORT gpioPortH +#define SL_UARTDRV_USART_VCOM_CTS_PIN 8 +#define SL_UARTDRV_USART_VCOM_CTS_LOC 4 + +// USART4 RTS on PH9 +#define SL_UARTDRV_USART_VCOM_RTS_PORT gpioPortH +#define SL_UARTDRV_USART_VCOM_RTS_PIN 9 +#define SL_UARTDRV_USART_VCOM_RTS_LOC 4 +// [USART_SL_UARTDRV_USART_VCOM]$ +// <<< sl:end pin_tool >>> +#endif // SL_UARTDRV_USART_VCOM_CONFIG_H diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/config/sl_usbd_class_acm0_config.h b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/config/sl_usbd_class_acm0_config.h new file mode 100644 index 0000000000..9c1ac2d7b1 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/config/sl_usbd_class_acm0_config.h @@ -0,0 +1,53 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Portions Copyright 2018 Silicon Laboratories Inc. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +#ifndef SL_USBD_CDC_ACM_ACM0_CONFIG_H +#define SL_USBD_CDC_ACM_ACM0_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +// Class Configuration + +// Configuration(s) to add this class instance to +// Default: all +// Comma separated list of configuration instances (like inst0, inst1) +// that this CDC ACM class instance will be attached to. You can +// use "all" to attach the class to all configs, or use an empty +// string if you do not want to attach the interface to any configuration. +#define SL_USBD_CDC_ACM_ACM0_CONFIGURATIONS "all" + +// + +// Protocol Details + +// Line State Notification Interval (ms) +// Default: 64 +// Line State Notification Interval (ms). +#define SL_USBD_CDC_ACM_ACM0_NOTIFY_INTERVAL 64 + +// + +// Call Management + +// Enable call management +// Default: 1 +// If set to 1, the host is informed that this ACM instance +// has call management capabilities. +#define SL_USBD_CDC_ACM_ACM0_CALL_MGMT_ENABLE 1 + +// Call management interface +// <1=> Over DCI +// <0=> Over CCI +// Default: 1 +// If set to 1 (i.e. Over DCI), a dedicated DCI interface will be created +// along with the CCI interface. Otherwise, only the CCI will be created +// and it will be used for both data and call management. +#define SL_USBD_CDC_ACM_ACM0_CALL_MGMT_DCI 1 + +// + +// <<< end of configuration section >>> +#endif // SL_USBD_CDC_ACM_ACM0_CONFIG_H \ No newline at end of file diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/config/sl_usbd_class_hid0_config.h b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/config/sl_usbd_class_hid0_config.h new file mode 100644 index 0000000000..9e480375d0 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/config/sl_usbd_class_hid0_config.h @@ -0,0 +1,143 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Portions Copyright 2018 Silicon Laboratories Inc. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +#ifndef SL_USBD_HID_HID0_CONFIG_H +#define SL_USBD_HID_HID0_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +// Class Configuration + +// Configuration(s) to add this class instance to +// Default: all +// Comma separated list of configuration instances (like inst0, inst1) +// that this HID class instance will be attached to. You can +// use "all" to attach the class to all configs, or use an empty +// string if you do not want to attach the interface to any configuration. +#define SL_USBD_HID_HID0_CONFIGURATIONS "all" + +// + +// Type Codes + +// Subclass code +// None +// Boot +// Default: SL_USBD_HID_SUBCLASS_BOOT +// This defines the standard USB subclass code for this interface. +// For most use cases, you can just select "Boot". +#define SL_USBD_HID_HID0_SUBCLASS SL_USBD_HID_SUBCLASS_BOOT + +// Protocol code +// None +// Keyboard +// Mouse +// Default: SL_USBD_HID_PROTOCOL_MOUSE +// You can choose "Mouse" or "Keyboard" depending on what functionality +// this HID class instance will provide. +#define SL_USBD_HID_HID0_PROTOCOL SL_USBD_HID_PROTOCOL_NONE + +// Country code +// Not supported +// Arabic +// Belgian +// Canadian Multilingual +// Canadian French +// Czech Republic +// Danish +// Finnish +// French +// German +// Greek +// Hebrew +// Hungary +// International +// Italian +// Japan Katakana +// Korean +// Latin American +// Netherlands Dutch +// Norwegian +// Persian Farsi +// Poland +// Portuguese +// Russia +// Slovakia +// Spanish +// Swedish +// Swiss French +// Swiss German +// Switzerland +// Taiwan +// Turkish Q +// Turkish F +// United Kingdom +// United States +// Yugoslavia +// Default: SL_USBD_HID_COUNTRY_CODE_US +// If this instance is implementing a keyboard interface, this +// field helps the host operating system know which layout/language +// the keyboard is manufactured for, or which country/localization +// setting to use by default. +#define SL_USBD_HID_HID0_COUNTRY_CODE SL_USBD_HID_COUNTRY_CODE_US + +// + +// Protocol Details + +// IN polling interval +// <1=> 1ms +// <2=> 2ms +// <4=> 4ms +// <8=> 8ms +// <16=> 16ms +// <32=> 32ms +// <64=> 64ms +// <128=> 128ms +// <256=> 256ms +// <512=> 512ms +// <1024=> 1024ms +// <2048=> 2048ms +// <4096=> 4096ms +// <8192=> 8192ms +// <16384=> 16384ms +// <32768=> 32768ms +// Default: 2 +// Polling interval for input transfers, in milliseconds. +// It must be a power of 2. +#define SL_USBD_HID_HID0_INTERVAL_IN 2 + +// OUT polling interval +// <1=> 1ms +// <2=> 2ms +// <4=> 4ms +// <8=> 8ms +// <16=> 16ms +// <32=> 32ms +// <64=> 64ms +// <128=> 128ms +// <256=> 256ms +// <512=> 512ms +// <1024=> 1024ms +// <2048=> 2048ms +// <4096=> 4096ms +// <8192=> 8192ms +// <16384=> 16384ms +// <32768=> 32768ms +// Default: 2 +// Polling interval for input transfers, in milliseconds. +// It must be a power of 2. +#define SL_USBD_HID_HID0_INTERVAL_OUT 2 + +// Enable Control Read +// Default: 1 +// Enable read operations through the control transfers. +#define SL_USBD_HID_HID0_ENABLE_CTRL_RD 1 + +// + +// <<< end of configuration section >>> +#endif // SL_USBD_HID_HID0_CONFIG_H diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/config/sl_usbd_class_winusb_config.h b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/config/sl_usbd_class_winusb_config.h new file mode 100644 index 0000000000..4da7f4409b --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/config/sl_usbd_class_winusb_config.h @@ -0,0 +1,57 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Portions Copyright 2021 Silicon Laboratories Inc. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +#ifndef SL_USBD_VENDOR_WINUSB_CONFIG_H +#define SL_USBD_VENDOR_WINUSB_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +// Class Configuration + +// Configuration(s) to add this class instance to +// Default: all +// Comma separated list of configuration instances (like inst0, inst1) +// that this vendor class instance will be attached to. You can +// use "all" to attach the class to all configs, or use an empty +// string if you do not want to attach the interface to any configuration. +#define SL_USBD_VENDOR_WINUSB_CONFIGURATIONS "all" + +// + +// Protocol Details + +// Add interrupt endpoints +// Default: 0 +// Specifies whether we should add IN and OUT endpoints to this +// vendor class interface. +#define SL_USBD_VENDOR_WINUSB_INTERRUPT_ENDPOINTS 0 + +// Endpoint interval +// <1=> 1ms +// <2=> 2ms +// <4=> 4ms +// <8=> 8ms +// <16=> 16ms +// <32=> 32ms +// <64=> 64ms +// <128=> 128ms +// <256=> 256ms +// <512=> 512ms +// <1024=> 1024ms +// <2048=> 2048ms +// <4096=> 4096ms +// <8192=> 8192ms +// <16384=> 16384ms +// <32768=> 32768ms +// Default: 2 +// Polling interval for input/output transfers, in milliseconds. +// It must be a power of 2. +#define SL_USBD_VENDOR_WINUSB_INTERVAL 2 + +// + +// <<< end of configuration section >>> +#endif // SL_USBD_VENDOR_WINUSB_CONFIG_H diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/config/sl_usbd_config0_config.h b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/config/sl_usbd_config0_config.h new file mode 100644 index 0000000000..a70da59041 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/config/sl_usbd_config0_config.h @@ -0,0 +1,51 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Portions Copyright 2018 Silicon Laboratories Inc. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +#ifndef SL_USB_CONFIGURATION_CONFIG0_CONFIG_H +#define SL_USB_CONFIGURATION_CONFIG0_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +// Configuration Settings + +// Configuration Name +// Default: "Main Configuration" +// This creates a string descriptor that the USB host +// can use to retrieve the name of this USB configuration descriptor. +// It can be scanned with "sudo lsusb -vv" on Linux. It appears next +// to iConfiguration field. +#define SL_USB_CONFIGURATION_CONFIG0_NAME "Main Configuration" + +// Power Source +// <0=> Bus-Powered +// <1=> Self-Powered +// Default: 1 +// Indicates whether the device will be powered using USB bus or +// or using a self-power source (like battery or a debugger) +// if the host configures the device using this configuration. +#define SL_USB_CONFIGURATION_CONFIG0_POWER_SOURCE 1 + +// Enable Remote Wakeup +// Default: 0 +// Enables or disables remote wakeup feature. +#define SL_USB_CONFIGURATION_CONFIG0_REMOTE_WAKEUP 0 + +// Maximum Power (mA) +// <100=> 100 mA +// <500=> 500 mA +// Default: 100 +// Specifies the maximum current that the device will draw. +// Most USB devices consume 100mA at most, but the USB standard +// allows the device to consume up to 500mA. When the host +// operating system scans this value, it will configure the USB port +// on the host controller to allow the device to consume the +// configured current. +#define SL_USB_CONFIGURATION_CONFIG0_MAXIMUM_POWER 100 + +// + +// <<< end of configuration section >>> +#endif // SL_USB_CONFIGURATION_CONFIG0_CONFIG_H diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/config/sl_usbd_core_config.h b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/config/sl_usbd_core_config.h new file mode 100644 index 0000000000..15b7e41f94 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/config/sl_usbd_core_config.h @@ -0,0 +1,201 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Portions Copyright 2018 Silicon Laboratories Inc. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +#ifndef SL_USBD_CONFIG_H +#define SL_USBD_CONFIG_H + +extern char UsbClassVendorDescription[GECKO_DEVICE_CLASS_VENDOR_DESCRIPTION_PROPERTY_LEN + 1]; + +// <<< Use Configuration Wizard in Context Menu >>> + +// USB Configuration + +// Auto-start USB device +// Default: 1 +// If enabled, the USB device will be automatically started up, +// using sl_usbd_core_start_device(), by the core task (which starts +// running after kernel scheduler is ready) when the USB stack is all +// initialized. You can disable this config if you want to call +// sl_usbd_core_start_device() manually from your code. This might +// be helpful if you do not want USB to start anytime before all +// your initializations are complete, or if you want to enable/disable +// USB on demand. +#define SL_USBD_AUTO_START_USB_DEVICE 1 + +// Enable SCSI 64-Bit LBA +// Default: 0 +// MSC SCSI Configuration for enabling 64-bit LBA support. +#define SL_USBD_MSC_SCSI_64_BIT_LBA_EN 0 + +// + +// USB Core Configuration + +// Core Pools + +// Number of configurations <1-255> +// Default: 1 +// The total number of configurations. +#define SL_USBD_CONFIGURATION_QUANTITY 1 + +// Number of interfaces <1-255> +// Default: 10 +// The total number of interfaces (for all of your USB configurations). +#define SL_USBD_INTERFACE_QUANTITY 10 + +// Number of alternate interfaces <1-255> +// Default: 10 +// The total number of alternate interfaces (for all of your USB configurations). +// Must be equal to or bigger than SL_USBD_INTERFACE_QUANTITY +#define SL_USBD_ALT_INTERFACE_QUANTITY 10 + +// Number of interface groups <0-255> +// Default: 20 +// The total number of interface groups (for all of your USB configurations). +#define SL_USBD_INTERFACE_GROUP_QUANTITY 20 + +// Number of endpoint descriptors <1-255> +// Default: 20 +// The total number of endpoint descriptors (for all of your USB configurations). +#define SL_USBD_DESCRIPTOR_QUANTITY 20 + +// Number of strings <0-100> +// Default: 30 +// The total number of strings per device. +#define SL_USBD_STRING_QUANTITY 30 + +// Number of opened endpoints <2-255> +// Default: 20 +// The total number of opened endpoints per device. +#define SL_USBD_OPEN_ENDPOINTS_QUANTITY 20 + +// + +// Core Task + +// Stack size of USBD core task in bytes +// Default: 4096 +// Stack size in bytes of the USBD core task. +#define SL_USBD_TASK_STACK_SIZE 4096U + +// Priority of USBD core task +#define SL_USBD_TASK_PRIORITY 5 + +// USB CDC Configuration + +// CDC Pools + +// Number of class instances <1-255> +// Default: 2 +// Number of class instances. +#define SL_USBD_CDC_CLASS_INSTANCE_QUANTITY 2 + +// Number of configurations <1-255> +// Default: 1 +// Number of configurations. +#define SL_USBD_CDC_CONFIGURATION_QUANTITY 2 + +// Number of subclass instances <1-255> +// Default: 2 +// Number of subclass instances. +#define SL_USBD_CDC_ACM_SUBCLASS_INSTANCE_QUANTITY 2 + +// Number of data interfaces <1-255> +// Default: 2 +// Number of data interfaces. +#define SL_USBD_CDC_DATA_INTERFACE_QUANTITY 2 + +// + +// + +// USB HID Configuration + +// HID Pools + +// Number of class instances <1-255> +// Default: 2 +// Number of class instances. +#define SL_USBD_HID_CLASS_INSTANCE_QUANTITY 2 + +// Number of configurations <1-255> +// Default: 1 +// Number of configurations. +#define SL_USBD_HID_CONFIGURATION_QUANTITY 1 + +// Number of report ids <0-255> +// Default: 2 +// Number of report ids. +#define SL_USBD_HID_REPORT_ID_QUANTITY 2 + +// Number of push/pop items <0-255> +// Default: 0 +// Number of push/pop items. +#define SL_USBD_HID_PUSH_POP_ITEM_QUANTITY 0 + +// + +// HID Task + +// Stack size of USBD HID timer task in bytes +// Default: 2048 +// HID Timer task stack size in bytes. +#define SL_USBD_HID_TIMER_TASK_STACK_SIZE 2048 + +// Priority of USBD HID timer task +#define SL_USBD_HID_TIMER_TASK_PRIORITY 5 + +// USB MSC Configuration + +// MSC Pools + +// Number of class instances <1-255> +// Default: 2 +// Number of class instances. +#define SL_USBD_MSC_CLASS_INSTANCE_QUANTITY 2 + +// Number of configurations <1-255> +// Default: 1 +// Number of configurations. +#define SL_USBD_MSC_CONFIGURATION_QUANTITY 1 + +// Number of Logical Units per class instance <1-255> +// Default: 2 +// Number of Logical Units. +#define SL_USBD_MSC_LUN_QUANTITY 2 + +// Size of data buffer per class instance in bytes <1-4294967295> +// Default: 512 +// Size of data buffer in bytes. +#define SL_USBD_MSC_DATA_BUFFER_SIZE 512 + +// + +// + +// USB Vendor Configuration + +// Vendor Pools + +// Number of class instances <1-255> +// Default: 2 +// Number of class instances. +#define SL_USBD_VENDOR_CLASS_INSTANCE_QUANTITY 2 + +// Number of configurations <1-255> +// Default: 1 +// Number of configurations. +#define SL_USBD_VENDOR_CONFIGURATION_QUANTITY 2 + +// pointer to USB Class Vendor description +#define NANO_SL_USBD_CLASS_VENDOR_DESCRIPTION (const char *)&UsbClassVendorDescription + +// + +// + +// <<< end of configuration section >>> +#endif // SL_USBD_CONFIG_H diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/config/sl_usbd_device_config.h b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/config/sl_usbd_device_config.h new file mode 100644 index 0000000000..1e10f3f8a8 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/config/sl_usbd_device_config.h @@ -0,0 +1,65 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Portions Copyright 2018 Silicon Laboratories Inc. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +#ifndef SL_USBD_DEVICE_CONFIG_H +#define SL_USBD_DEVICE_CONFIG_H + +extern char *UsbSerialNumber[]; + +// <<< Use Configuration Wizard in Context Menu >>> + +// USB Device Configuration + +// Device Vendor ID +// Device vendor ID: Silabs. +#define SL_USBD_DEVICE_VENDOR_ID 0x10C4 + +// Device Product ID +// Device product ID. PID assigned to .NET nanoFramework +#define SL_USBD_DEVICE_PRODUCT_ID 0x8DAD + +// Device Release Number +// Default: 0x0100 +// Device release number. +#define SL_USBD_DEVICE_RELEASE_NUMBER 0x0100 + +// Device Manufacturer Name +// Default: "Silicon Labs" +// Device manufacturer string. +#define SL_USBD_DEVICE_MANUFACTURER_STRING "Silicon Labs" + +// Device Product Name +// Device product string. +// OK to have this one empty as it will be updated by the managed application when calling UsbStream::NativeOpen +#define SL_USBD_DEVICE_PRODUCT_STRING "" + +// Device Serial Number +// Device serial number string. +#define SL_USBD_DEVICE_SERIAL_NUMBER_STRING (const char *)&UsbSerialNumber + +// Device Language ID +// Arabic +// Chinese +// US English +// UK English +// French +// German +// Greek +// Italian +// Portuguese +// Sanskrit +// ID of language of strings of device. +// Default: USBD_LANG_ID_ENGLISH_US +#define SL_USBD_DEVICE_LANGUAGE_ID SL_USBD_LANG_ID_ENGLISH_US + +#define USBD_CFG_HS_EN 0 +#define USBD_CFG_EP_ISOC_EN 0 +#define USBD_CFG_OPTIMIZE_SPD 0 + +// + +// <<< end of configuration section >>> +#endif // SL_USBD_DEVICE_CONFIG_H diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/config/uartdrv_config.h b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/config/uartdrv_config.h new file mode 100644 index 0000000000..118a7c901a --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/config/uartdrv_config.h @@ -0,0 +1,114 @@ +/***************************************************************************//** + * @file + * @brief UARTDRV configuration file. + ******************************************************************************* + * # License + * Copyright 2018 Silicon Laboratories Inc. www.silabs.com + ******************************************************************************* + * + * SPDX-License-Identifier: Zlib + * + * The licensor of this software is Silicon Laboratories Inc. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + ******************************************************************************/ +#ifndef __SILICON_LABS_UARTDRV_CONFIG_H__ +#define __SILICON_LABS_UARTDRV_CONFIG_H__ + +/***************************************************************************//** + * @addtogroup uartdrv + * @{ + ******************************************************************************/ +/// Size of the receive operation queue. +/// @details +/// The maximum number of receive operations that can be queued up for one +/// driver instance before @ref UARTDRV_Receive() returns +/// @ref ECODE_EMDRV_UARTDRV_QUEUE_FULL. +/// @note +/// This macro is not used by the UARTDRV itself, but is intended to be used +/// with the @ref DEFINE_BUF_QUEUE macro by the user of the driver to allocate +/// instances of the @ref UARTDRV_Buffer_FifoQueue_t struct. +#if !defined(EMDRV_UARTDRV_MAX_CONCURRENT_RX_BUFS) +#define EMDRV_UARTDRV_MAX_CONCURRENT_RX_BUFS 2 +#endif + +/// Size of the transmit operation queue. +/// @details +/// The maximum number of transmit operations that can be queued up for one +/// driver instance before @ref UARTDRV_Transmit() returns +/// @ref ECODE_EMDRV_UARTDRV_QUEUE_FULL. +/// @note +/// This macro is not used by the UARTDRV itself, but is intended to be used +/// with the @ref DEFINE_BUF_QUEUE macro by the user of the driver to allocate +/// instances of the @ref UARTDRV_Buffer_FifoQueue_t struct. +#if !defined(EMDRV_UARTDRV_MAX_CONCURRENT_TX_BUFS) +#define EMDRV_UARTDRV_MAX_CONCURRENT_TX_BUFS 2 +#endif + +// <<< Use Configuration Wizard in Context Menu >>> +// UARTDRV Settings + +/// Set to 1 to include flow control support +#if !defined(EMDRV_UARTDRV_FLOW_CONTROL_ENABLE) +// Flow control support +// <1=> Enable +// <0=> Disable +// Default: 1 +#define EMDRV_UARTDRV_FLOW_CONTROL_ENABLE 0 +#endif + +/// Maximum number of driver instances. +#if !defined(EMDRV_UARTDRV_MAX_DRIVER_INSTANCES) +// Maximum number of driver instances +// This maximum only applies when UARTDRV_FLOW_CONTROL_ENABLE = 1 +// Default: 4 +#define EMDRV_UARTDRV_MAX_DRIVER_INSTANCES 4 +#endif + +/// UART software flow control code: request peer to start TX +#if !defined(UARTDRV_FC_SW_XON) +// UART software flow control code: request peer to start TX +// Default: 0x11 +#define UARTDRV_FC_SW_XON 0x11 +#endif + +/// UART software flow control code: request peer to stop TX +#if !defined(UARTDRV_FC_SW_XOFF) +// UART software flow control code: request peer to stop TX +// Default: 0x13 +#define UARTDRV_FC_SW_XOFF 0x13 +#endif + +/// UART enable reception when sleeping. +#if !defined(UARTDRV_RESTRICT_ENERGY_MODE_TO_ALLOW_RECEPTION) +// Enable reception when sleeping +// Enable reception when sleeping will use the power manager and add EM1 +// requirement during receive operations that use DMA. +// <1=> Enable +// <0=> Disable +// Default: 1 +#define UARTDRV_RESTRICT_ENERGY_MODE_TO_ALLOW_RECEPTION 0 +#endif + +// + +// <<< end of configuration section >>> + +/** @} (end addtogroup uartdrv) */ + +#endif /* __SILICON_LABS_UARTDRV_CONFIG_H__ */ diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/launch.json b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/launch.json new file mode 100644 index 0000000000..a4a945a94e --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/launch.json @@ -0,0 +1,83 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "SL_STK3701A nanoBooter", + "type": "cppdbg", + "request": "launch", + "miDebuggerPath": "/bin/arm-none-eabi-gdb.exe", + "program": "${workspaceRoot}/build/nanoBooter.elf", + "MIMode": "gdb", + "debugServerPath": "/JLinkGDBServerCL.exe", + "debugServerArgs": "-if swd -speed auto -endian little -device EFM32GG11B820F2048 -localhostonly 1 -timeout 0 -vd -halt -reset -singlerun -strict -nogui", + "stopAtEntry": false, + "serverStarted": "Connected to target", + "cwd": "${cwd}", + "setupCommands": [ + { + "text": "file \"E:/GitHub/nf-interpreter/build/nanoBooter.elf\" " + }, + { + "text": "target extended-remote localhost:2331" + }, + { + "text": "monitor halt" + }, + { + "text": "monitor reset" + }, + { + "text": "load" + } + ], + "launchCompleteCommand": "None", + "logging": { + "moduleLoad": false, + "trace": true, + "engineLogging": false, + "programOutput": false, + "traceResponse": false, + "exceptions": true + } + }, + { + "name": "SL_STK3701A nanoCLR", + "type": "cppdbg", + "request": "launch", + "miDebuggerPath": "/bin/arm-none-eabi-gdb.exe", + "program": "${workspaceRoot}/build/nanoCLR.elf", + "MIMode": "gdb", + "debugServerPath": "/JLinkGDBServerCL.exe", + "debugServerArgs": "-if swd -speed auto -endian little -device EFM32GG11B820F2048 -localhostonly 1 -timeout 0 -vd -halt -reset -singlerun -strict -nogui", + "stopAtEntry": false, + "serverStarted": "Connected to target", + "cwd": "${cwd}", + "setupCommands": [ + { + "text": "file \"E:/GitHub/nf-interpreter/build/nanoCLR.elf\" " + }, + { + "text": "target extended-remote localhost:2331" + }, + { + "text": "monitor halt" + }, + { + "text": "monitor reset" + }, + { + "text": "load" + } + ], + "launchCompleteCommand": "None", + "logging": { + "moduleLoad": false, + "trace": true, + "engineLogging": false, + "programOutput": false, + "traceResponse": false, + "exceptions": true + } + } + ] +} diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/nanoBooter/CMakeLists.txt b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/nanoBooter/CMakeLists.txt new file mode 100644 index 0000000000..0b7c048e56 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/nanoBooter/CMakeLists.txt @@ -0,0 +1,10 @@ +# +# Copyright (c) .NET Foundation and Contributors +# See LICENSE file in the project root for full license information. +# + +# append nanoBooter source files +list(APPEND NANOBOOTER_PROJECT_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/main.c) + +# make var global +set(NANOBOOTER_PROJECT_SOURCES ${NANOBOOTER_PROJECT_SOURCES} CACHE INTERNAL "make global") diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/nanoBooter/efm32gg11b_booter-DEBUG.ld b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/nanoBooter/efm32gg11b_booter-DEBUG.ld new file mode 100644 index 0000000000..8941c58e5c --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/nanoBooter/efm32gg11b_booter-DEBUG.ld @@ -0,0 +1,235 @@ +/***************************************************************************//** + * Linker script for Silicon Labs EFM32GG11B devices + ******************************************************************************* + * # License + * Copyright 2022 Silicon Laboratories Inc. www.silabs.com + ******************************************************************************* + * + * SPDX-License-Identifier: Zlib + * + * The licensor of this software is Silicon Laboratories Inc. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + ******************************************************************************/ + +/* Set the RAM segment used end for threadx */ +__RAM_segment_used_end__ = 0; + +MEMORY +{ + flash0 (rx) : org = 0x00000000, len = 76k /* space reserved for nanoBooter */ + deployment (rx) : org = 0x00013000, len = 0 /* space reserved for application deployment */ + config (rw) : org = 0x001FF000, len = 4k /* space reserved for configuration block */ + RAM (rwx): org = 0x20000000, len = 512k - 48 /* RAM */ + bootclpbrd (rwx): org = 0x2007FFD0, len = 48 /* boot clipboard area */ +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions flash0 and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapBase + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __Vectors_End + * __Vectors_Size + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + KEEP(*(.vectors)) + __Vectors_End = .; + __Vectors_Size = __Vectors_End - __Vectors; + __end__ = .; + + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > flash0 + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > flash0 + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash0 + __exidx_end = .; + + + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + + LONG (__etext) + LONG (__data_start__) + LONG ((__data_end__ - __data_start__) / 4) + __copy_table_end__ = .; + } > flash0 + + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + __zero_table_end__ = .; + } > flash0 + + /* + * + * Location counter can end up 2byte aligned with narrow Thumb code but + * __etext is assumed by startup code to be the LMA of a section in RAM + * which must be 4byte aligned + */ + __etext = ALIGN (4); + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + . = ALIGN (4); + PROVIDE (__ram_func_section_start = .); + *(.ram) + PROVIDE (__ram_func_section_end = .); + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss) + *(.bss.*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __HeapBase = .; + __end__ = .; + end = __end__; + _end = __end__; + KEEP(*(.heap*)) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + KEEP(*(.stack*)) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") + + /* Check if flash0 usage exceeds flash0 size */ + ASSERT( LENGTH(flash0) >= (__etext + SIZEOF(.data)), "flash0 memory overflowed !") +} + +/* RAM region to be used for the boot clipboard.*/ +REGION_ALIAS("SECTION_FOR_BOOTCLIPBOARD", bootclpbrd); + +/* Code rules inclusion.*/ +INCLUDE rules_code.ld + +/* boot clipboard rules inclusion.*/ +INCLUDE rules_bootclipboard.ld diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/nanoBooter/efm32gg11b_booter.ld b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/nanoBooter/efm32gg11b_booter.ld new file mode 100644 index 0000000000..98793699a7 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/nanoBooter/efm32gg11b_booter.ld @@ -0,0 +1,235 @@ +/***************************************************************************//** + * Linker script for Silicon Labs EFM32GG11B devices + ******************************************************************************* + * # License + * Copyright 2022 Silicon Laboratories Inc. www.silabs.com + ******************************************************************************* + * + * SPDX-License-Identifier: Zlib + * + * The licensor of this software is Silicon Laboratories Inc. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + ******************************************************************************/ + +/* Set the RAM segment used end for threadx */ +__RAM_segment_used_end__ = 0; + +MEMORY +{ + flash0 (rx) : org = 0x00000000, len = 48k /* space reserved for nanoBooter */ + deployment (rx) : org = 0x0000C000, len = 0 /* space reserved for application deployment */ + config (rw) : org = 0x001FF000, len = 4k /* space reserved for configuration block */ + RAM (rwx): org = 0x20000000, len = 512k - 48 /* RAM */ + bootclpbrd (rwx): org = 0x2007FFD0, len = 48 /* boot clipboard area */ +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions flash0 and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapBase + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __Vectors_End + * __Vectors_Size + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + KEEP(*(.vectors)) + __Vectors_End = .; + __Vectors_Size = __Vectors_End - __Vectors; + __end__ = .; + + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > flash0 + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > flash0 + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash0 + __exidx_end = .; + + + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + + LONG (__etext) + LONG (__data_start__) + LONG ((__data_end__ - __data_start__) / 4) + __copy_table_end__ = .; + } > flash0 + + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + __zero_table_end__ = .; + } > flash0 + + /* + * + * Location counter can end up 2byte aligned with narrow Thumb code but + * __etext is assumed by startup code to be the LMA of a section in RAM + * which must be 4byte aligned + */ + __etext = ALIGN (4); + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + . = ALIGN (4); + PROVIDE (__ram_func_section_start = .); + *(.ram) + PROVIDE (__ram_func_section_end = .); + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss) + *(.bss.*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __HeapBase = .; + __end__ = .; + end = __end__; + _end = __end__; + KEEP(*(.heap*)) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + KEEP(*(.stack*)) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") + + /* Check if flash0 usage exceeds flash0 size */ + ASSERT( LENGTH(flash0) >= (__etext + SIZEOF(.data)), "flash0 memory overflowed !") +} + +/* RAM region to be used for the boot clipboard.*/ +REGION_ALIAS("SECTION_FOR_BOOTCLIPBOARD", bootclpbrd); + +/* Code rules inclusion.*/ +INCLUDE rules_code.ld + +/* boot clipboard rules inclusion.*/ +INCLUDE rules_bootclipboard.ld diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/nanoBooter/main.c b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/nanoBooter/main.c new file mode 100644 index 0000000000..45b18d583c --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/nanoBooter/main.c @@ -0,0 +1,220 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include +// #include + +extern void sli_usbd_init(void); +extern void sli_usbd_configuration_config0_init(void); +extern void sli_usbd_cdc_acm_acm0_init(void); +extern void usb_device_cdc_acm_app_init(void); + +// flags for hardware events +TX_EVENT_FLAGS_GROUP nanoHardwareEvents; + +// byte pool configuration and definitions +#define DEFAULT_BYTE_POOL_SIZE 4096 +TX_BYTE_POOL byte_pool_0; +ALIGN_TYPE memory_area[DEFAULT_BYTE_POOL_SIZE / sizeof(ALIGN_TYPE)]; + +// threads definitions and configurations + +// receiver thread +#define RECEIVER_THREAD_STACK_SIZE 2048 +#define RECEIVER_THREAD_PRIORITY 5 + +TX_THREAD receiverThread; +ALIGN_TYPE receiverThreadStack[RECEIVER_THREAD_STACK_SIZE / sizeof(ALIGN_TYPE)]; +extern void ReceiverThread_entry(uint32_t parameter); + +// blink thread +#define BLINK_THREAD_STACK_SIZE 1024 +#define BLINK_THREAD_PRIORITY 5 + +TX_THREAD blinkThread; +ALIGN_TYPE blinkThreadStack[BLINK_THREAD_STACK_SIZE / sizeof(ALIGN_TYPE)]; +TX_THREAD blinkThread1; +ALIGN_TYPE blinkThread1Stack[BLINK_THREAD_STACK_SIZE / sizeof(ALIGN_TYPE)]; + +void BlinkThread_entry(uint32_t parameter) +{ + (void)parameter; + + while (1) + { + GPIO_PinOutToggle(BSP_GPIO_LED0_PORT, BSP_GPIO_LED0_PIN); + tx_thread_sleep(TX_TICKS_PER_MILLISEC(500)); + } +} + +void BlinkThread1_entry(uint32_t parameter) +{ + (void)parameter; + + while (1) + { + tx_thread_sleep(TX_TICKS_PER_MILLISEC(500)); + GPIO_PinOutToggle(BSP_GPIO_LED1_PORT, BSP_GPIO_LED1_PIN); + } +} + +void tx_application_define(void *first_unused_memory) +{ + (void)first_unused_memory; + uint16_t status; + + // Create a byte memory pool from which to allocate the thread stacks. + tx_byte_pool_create(&byte_pool_0, "byte pool 0", memory_area, DEFAULT_BYTE_POOL_SIZE); + + // #if (HAL_NF_USE_STM32_CRC == TRUE) + // // startup crc + // crcStart(NULL); + // #endif + + // initialize block storage list and devices + // in CLR this is called in nanoHAL_Initialize() + // for nanoBooter we have to init it in order to provide the flash map for Monitor_FlashSectorMap command + BlockStorageList_Initialize(); + BlockStorage_AddDevices(); + + // initialize configuration manager + // in CLR this is called in nanoHAL_Initialize() + // for nanoBooter we have to init it here to have access to network configuration blocks + // ConfigurationManager_Initialize(); + + // Create blink thread + status = tx_thread_create( + &blinkThread, + "Blink Thread", + BlinkThread_entry, + 0, + (uint8_t *)blinkThreadStack, + BLINK_THREAD_STACK_SIZE, + BLINK_THREAD_PRIORITY, + BLINK_THREAD_PRIORITY, + TX_NO_TIME_SLICE, + TX_AUTO_START); + + if (status != TX_SUCCESS) + { + while (1) + { + } + } + + // Create blink thread + status = tx_thread_create( + &blinkThread1, + "Blink Thread1", + BlinkThread1_entry, + 0, + (uint8_t *)blinkThread1Stack, + BLINK_THREAD_STACK_SIZE, + BLINK_THREAD_PRIORITY, + BLINK_THREAD_PRIORITY, + TX_NO_TIME_SLICE, + TX_AUTO_START); + + if (status != TX_SUCCESS) + { + while (1) + { + } + } + + // Create receiver thread + status = tx_thread_create( + &receiverThread, + "Receiver Thread", + ReceiverThread_entry, + 0, + receiverThreadStack, + RECEIVER_THREAD_STACK_SIZE, + RECEIVER_THREAD_PRIORITY, + RECEIVER_THREAD_PRIORITY, + TX_NO_TIME_SLICE, + TX_AUTO_START); + + if (status != TX_SUCCESS) + { + while (1) + { + } + } + + // create HW event group + status = tx_event_flags_create(&nanoHardwareEvents, ""); + if (status != TX_SUCCESS) + { + while (1) + { + } + } + +#if HAL_WP_USE_USB_CDC == TRUE + sli_usbd_init(); + sli_usbd_configuration_config0_init(); + sli_usbd_cdc_acm_acm0_init(); + usb_device_cdc_acm_app_init(); +#endif + + // report successfull nanoBooter execution + ReportSuccessfullNanoBooter(); +} + +// Application entry point. +int main(void) +{ + // Initialize the board + sl_system_init(); + + // Configure LED0 and LED1 as output + GPIO_PinModeSet(BSP_GPIO_LED0_PORT, BSP_GPIO_LED0_PIN, gpioModePushPull, 0); + GPIO_PinModeSet(BSP_GPIO_LED1_PORT, BSP_GPIO_LED1_PIN, gpioModePushPull, 0); + + // configure + GPIO_PinModeSet(BSP_GPIO_PB0_PORT, BSP_GPIO_PB0_PIN, gpioModeInput, 0); + + // init boot clipboard + InitBootClipboard(); + + // the following IF is not mandatory, it's just providing a way for a user to 'force' + // the board to remain in nanoBooter and not launching nanoCLR + + // check if there is a request to remain on nanoBooter + if (!IsToRemainInBooter()) + { + // if the BTN0 is pressed, skip the check for a valid CLR image and remain in booter + if (GPIO_PinInGet(BSP_GPIO_PB0_PORT, BSP_GPIO_PB0_PIN) != 0) + { + // check for valid CLR image + // we are checking for a valid image at the deployment address, which is pointing to the CLR address + if (CheckValidCLRImage((uint32_t)&__deployment_start__)) + { + // there seems to be a valid CLR image + + // need to change HF clock to internal RCO so the CLR can boot smoothly + CMU_CLOCK_SELECT_SET(HF, HFRCO); + + // launch nanoCLR + LaunchCLR((uint32_t)&__deployment_start__); + } + } + } + + // Enter the ThreadX kernel. Task(s) created in tx_application_define() will start running + sl_system_kernel_start(); +} diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/nanoBooter/target_board.h.in b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/nanoBooter/target_board.h.in new file mode 100644 index 0000000000..ec5e9be940 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/nanoBooter/target_board.h.in @@ -0,0 +1,18 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +////////////////////////////////////////////////////////////////////////////// +// This file was automatically generated by a tool. // +// Any changes you make here will be overwritten when it's generated again. // +////////////////////////////////////////////////////////////////////////////// + +#ifndef _TARGET_BOARD_NANOBOOTER_H_ +#define _TARGET_BOARD_NANOBOOTER_H_ + +#include + +#define OEMSYSTEMINFOSTRING "nanoBooter running @ @TARGET_NAME@" + +#endif // _TARGET_BOARD_NANOBOOTER_H_ diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/nanoCLR/CMakeLists.txt b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/nanoCLR/CMakeLists.txt new file mode 100644 index 0000000000..966b5a01c7 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/nanoCLR/CMakeLists.txt @@ -0,0 +1,15 @@ +# +# Copyright (c) .NET Foundation and Contributors +# See LICENSE file in the project root for full license information. +# + +# append nanoCLR source files +list(APPEND NANOCLR_PROJECT_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/main.c) +list(APPEND NANOCLR_PROJECT_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/nanoHAL.cpp) + +if(GECKO_FEATURE_USBD_HID) + list(APPEND NANOCLR_PROJECT_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/usb_hid_app.c) +endif() + +# make var global +set(NANOCLR_PROJECT_SOURCES ${NANOCLR_PROJECT_SOURCES} CACHE INTERNAL "make global") diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/nanoCLR/efm32gg11b_CLR-DEBUG.ld b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/nanoCLR/efm32gg11b_CLR-DEBUG.ld new file mode 100644 index 0000000000..3d3da6e9f2 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/nanoCLR/efm32gg11b_CLR-DEBUG.ld @@ -0,0 +1,249 @@ +/***************************************************************************//** + * Linker script for Silicon Labs EFM32GG11B devices + ******************************************************************************* + * # License + * Copyright 2022 Silicon Laboratories Inc. www.silabs.com + ******************************************************************************* + * + * SPDX-License-Identifier: Zlib + * + * The licensor of this software is Silicon Laboratories Inc. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + ******************************************************************************/ + +/* Set the RAM segment used end for threadx */ +__RAM_segment_used_end__ = 0; + +MEMORY +{ + flash0 (rx) : org = 0x00013000, len = 2M - 76k - 4k - 1088k /* flash size less the space reserved for nanoBooter, configuration block and application deployment*/ + deployment (rx) : org = 0x000EF000, len = 1088k /* space reserved for application deployment */ + config (rw) : org = 0x001FF000, len = 4k /* space reserved for configuration block */ + RAM (rwx): org = 0x20000000, len = 512k - 48 /* RAM */ + bootclpbrd (rwx): org = 0x2007FFD0, len = 48 /* boot clipboard area */ +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions flash0 and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapBase + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __Vectors_End + * __Vectors_Size + */ +ENTRY(Reset_Handler) + +/* RAM region to be used for the boot clipboard.*/ +REGION_ALIAS("SECTION_FOR_BOOTCLIPBOARD", bootclpbrd); + +/* RAM region to be used for the nanoFramework CLR managed heap.*/ +REGION_ALIAS("CLR_MANAGED_HEAP_RAM", RAM); + +SECTIONS +{ + .text : + { + KEEP(*(.vectors)) + __Vectors_End = .; + __Vectors_Size = __Vectors_End - __Vectors; + __end__ = .; + + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > flash0 + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > flash0 + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash0 + __exidx_end = .; + + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + + LONG (__etext) + LONG (__data_start__) + LONG ((__data_end__ - __data_start__) / 4) + __copy_table_end__ = .; + } > flash0 + + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + __zero_table_end__ = .; + } > flash0 + + /* + * + * Location counter can end up 2byte aligned with narrow Thumb code but + * __etext is assumed by startup code to be the LMA of a section in RAM + * which must be 4byte aligned + */ + __etext = ALIGN (4); + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + . = ALIGN (4); + PROVIDE (__ram_func_section_start = .); + *(.ram) + PROVIDE (__ram_func_section_end = .); + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss) + *(.bss.*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY) : + { + __HeapBase = .; + __end__ = .; + end = __end__; + _end = __end__; + KEEP(*(.heap*)) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + KEEP(*(.stack*)) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = .; + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* nanoFramework CLR managed heap section at the specified RAM section.*/ + .clr_managed_heap (NOLOAD) : + { + . = ALIGN(8); + __clr_managed_heap_base__ = .; + PROVIDE(HeapBegin = .); + . = ORIGIN(CLR_MANAGED_HEAP_RAM) + LENGTH(CLR_MANAGED_HEAP_RAM); + . = ALIGN(8); + __clr_managed_heap_end__ = .; + PROVIDE(HeapEnd = .); + } > CLR_MANAGED_HEAP_RAM + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") + + /* Check if flash0 usage exceeds flash0 size */ + ASSERT( LENGTH(flash0) >= (__etext + SIZEOF(.data)), "flash0 memory overflowed !") +} + +/* Code rules inclusion.*/ +INCLUDE rules_code.ld + +/* boot clipboard rules inclusion.*/ +INCLUDE rules_bootclipboard.ld diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/nanoCLR/efm32gg11b_CLR.ld b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/nanoCLR/efm32gg11b_CLR.ld new file mode 100644 index 0000000000..8c06c5e2fb --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/nanoCLR/efm32gg11b_CLR.ld @@ -0,0 +1,249 @@ +/***************************************************************************//** + * Linker script for Silicon Labs EFM32GG11B devices + ******************************************************************************* + * # License + * Copyright 2022 Silicon Laboratories Inc. www.silabs.com + ******************************************************************************* + * + * SPDX-License-Identifier: Zlib + * + * The licensor of this software is Silicon Laboratories Inc. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + ******************************************************************************/ + +/* Set the RAM segment used end for threadx */ +__RAM_segment_used_end__ = 0; + +MEMORY +{ + flash0 (rx) : org = 0x0000C000, len = 2M - 48k - 4k - 1404k /* flash size less the space reserved for nanoBooter, configuration block and application deployment*/ + deployment (rx) : org = 0x0009F000, len = 1404k /* space reserved for application deployment */ + config (rw) : org = 0x001FF000, len = 4k /* space reserved for configuration block */ + RAM (rwx): org = 0x20000000, len = 512k - 48 /* RAM */ + bootclpbrd (rwx): org = 0x2007FFD0, len = 48 /* boot clipboard area */ +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions flash0 and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapBase + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __Vectors_End + * __Vectors_Size + */ +ENTRY(Reset_Handler) + +/* RAM region to be used for the boot clipboard.*/ +REGION_ALIAS("SECTION_FOR_BOOTCLIPBOARD", bootclpbrd); + +/* RAM region to be used for the nanoFramework CLR managed heap.*/ +REGION_ALIAS("CLR_MANAGED_HEAP_RAM", RAM); + +SECTIONS +{ + .text : + { + KEEP(*(.vectors)) + __Vectors_End = .; + __Vectors_Size = __Vectors_End - __Vectors; + __end__ = .; + + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > flash0 + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > flash0 + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > flash0 + __exidx_end = .; + + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + + LONG (__etext) + LONG (__data_start__) + LONG ((__data_end__ - __data_start__) / 4) + __copy_table_end__ = .; + } > flash0 + + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + __zero_table_end__ = .; + } > flash0 + + /* + * + * Location counter can end up 2byte aligned with narrow Thumb code but + * __etext is assumed by startup code to be the LMA of a section in RAM + * which must be 4byte aligned + */ + __etext = ALIGN (4); + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + . = ALIGN (4); + PROVIDE (__ram_func_section_start = .); + *(.ram) + PROVIDE (__ram_func_section_end = .); + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss) + *(.bss.*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY) : + { + __HeapBase = .; + __end__ = .; + end = __end__; + _end = __end__; + KEEP(*(.heap*)) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + KEEP(*(.stack*)) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = .; + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* nanoFramework CLR managed heap section at the specified RAM section.*/ + .clr_managed_heap (NOLOAD) : + { + . = ALIGN(8); + __clr_managed_heap_base__ = .; + PROVIDE(HeapBegin = .); + . = ORIGIN(CLR_MANAGED_HEAP_RAM) + LENGTH(CLR_MANAGED_HEAP_RAM); + . = ALIGN(8); + __clr_managed_heap_end__ = .; + PROVIDE(HeapEnd = .); + } > CLR_MANAGED_HEAP_RAM + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") + + /* Check if flash0 usage exceeds flash0 size */ + ASSERT( LENGTH(flash0) >= (__etext + SIZEOF(.data)), "flash0 memory overflowed !") +} + +/* Code rules inclusion.*/ +INCLUDE rules_code.ld + +/* boot clipboard rules inclusion.*/ +INCLUDE rules_bootclipboard.ld diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/nanoCLR/main.c b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/nanoCLR/main.c new file mode 100644 index 0000000000..975c946002 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/nanoCLR/main.c @@ -0,0 +1,207 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include +// #include + +extern void usb_device_hid_app_init(void); +extern void sli_usbd_configuration_config0_init(void); +extern void sli_usbd_hid_hid0_init(void); +extern void sli_usbd_init(void); +extern void sli_usbd_configuration_config0_init(void); +extern void sli_usbd_cdc_acm_acm0_init(void); +extern void usb_device_cdc_acm_app_init(void); + +// flags for hardware events +TX_EVENT_FLAGS_GROUP nanoHardwareEvents; +extern CLR_SETTINGS clrSettings; + +// byte pool configuration and definitions +// need to be at least as big as the config sector +#define DEFAULT_BYTE_POOL_SIZE 0x2000 +TX_BYTE_POOL byte_pool_0; +uint8_t memory_area[DEFAULT_BYTE_POOL_SIZE]; + +// threads definitions and configurations +#define BLINK_THREAD_STACK_SIZE 1024 +#define BLINK_THREAD_PRIORITY 5 + +TX_THREAD blinkThread; +uint32_t blinkThreadStack[BLINK_THREAD_STACK_SIZE / sizeof(uint32_t)]; + +// receiver thread +#define RECEIVER_THREAD_STACK_SIZE 2048 +#define RECEIVER_THREAD_PRIORITY 5 + +TX_THREAD receiverThread; +uint32_t receiverThreadStack[RECEIVER_THREAD_STACK_SIZE / sizeof(uint32_t)]; +extern void ReceiverThread_entry(uint32_t parameter); + +// CLR thread +#define CLR_THREAD_STACK_SIZE 4092 +#define CLR_THREAD_PRIORITY 5 + +TX_THREAD clrStartupThread; +uint32_t clrStartupThreadStack[CLR_THREAD_STACK_SIZE / sizeof(uint32_t)]; +extern void ClrStartupThread_entry(uint32_t parameter); + +void BlinkThread_entry(uint32_t parameter) +{ + (void)parameter; + + while (1) + { + GPIO_PinOutToggle(BSP_GPIO_LED0_PORT, BSP_GPIO_LED0_PIN + 1); + tx_thread_sleep(TX_TICKS_PER_MILLISEC(250)); + } +} + +void tx_application_define(void *first_unused_memory) +{ + (void)first_unused_memory; + uint16_t status; + + // Create a byte memory pool from which to allocate the thread stacks. + tx_byte_pool_create(&byte_pool_0, "byte pool 0", memory_area, DEFAULT_BYTE_POOL_SIZE); + + // start watchdog + Watchdog_Init(); + + // #if (HAL_NF_USE_STM32_CRC == TRUE) + // // startup crc + // crcStart(NULL); + // #endif + +#if (TRACE_TO_STDIO == TRUE) + StdioPort_Init(); +#endif + + // Create blink thread + status = tx_thread_create( + &blinkThread, + "Blink Thread", + BlinkThread_entry, + 0, + blinkThreadStack, + BLINK_THREAD_STACK_SIZE, + BLINK_THREAD_PRIORITY, + BLINK_THREAD_PRIORITY, + TX_NO_TIME_SLICE, + TX_AUTO_START); + + if (status != TX_SUCCESS) + { + while (1) + { + } + } + + // Create receiver thread + status = tx_thread_create( + &receiverThread, + "Receiver Thread", + ReceiverThread_entry, + 0, + receiverThreadStack, + RECEIVER_THREAD_STACK_SIZE, + RECEIVER_THREAD_PRIORITY, + RECEIVER_THREAD_PRIORITY, + TX_NO_TIME_SLICE, + TX_AUTO_START); + + if (status != TX_SUCCESS) + { + while (1) + { + } + } + + // CLR settings to launch CLR thread + memset(&clrSettings, 0, sizeof(CLR_SETTINGS)); + + clrSettings.MaxContextSwitches = 50; + clrSettings.WaitForDebugger = false; + clrSettings.EnterDebuggerLoopAfterExit = true; + + // Create CLR startup thread + status = tx_thread_create( + &clrStartupThread, + "CLR Thread", + ClrStartupThread_entry, + (uint32_t)&clrSettings, + clrStartupThreadStack, + CLR_THREAD_STACK_SIZE, + CLR_THREAD_PRIORITY, + CLR_THREAD_PRIORITY, + TX_NO_TIME_SLICE, + TX_AUTO_START); + + if (status != TX_SUCCESS) + { + while (1) + { + } + } + + // create HW event group + status = tx_event_flags_create(&nanoHardwareEvents, ""); + if (status != TX_SUCCESS) + { + while (1) + { + } + } + +#if GECKO_FEATURE_USBD_HID == TRUE || HAL_WP_USE_USB_CDC == TRUE || GECKO_FEATURE_USBD_WINUSB == TRUE + // can't call USBD init twice + sli_usbd_init(); + sli_usbd_configuration_config0_init(); +#endif + +#if GECKO_FEATURE_USBD_HID == TRUE + sli_usbd_hid_hid0_init(); + usb_device_hid_app_init(); +#endif + +#if HAL_WP_USE_USB_CDC == TRUE + sli_usbd_cdc_acm_acm0_init(); + usb_device_cdc_acm_app_init(); +#endif +} + +// Application entry point. +int main(void) +{ + sl_system_init(); + + // Configure LED0 as output + GPIO_PinModeSet(BSP_GPIO_LED0_PORT, BSP_GPIO_LED0_PIN + 1, gpioModePushPull, 0); + + // turn off LEDs, just in case + GPIO_PinModeSet(BSP_GPIO_LED0_PORT, BSP_GPIO_LED0_PIN, gpioModeDisabled, 0); + GPIO_PinModeSet(BSP_GPIO_LED1_PORT, BSP_GPIO_LED1_PIN, gpioModeDisabled, 0); + + // enable display + GPIO_PinModeSet(BSP_DISP_ENABLE_PORT, BSP_DISP_ENABLE_PIN, gpioModePushPull, 0); + GPIO_PinOutSet(BSP_DISP_ENABLE_PORT, BSP_DISP_ENABLE_PIN); + + // init boot clipboard + InitBootClipboard(); + + // Enter the ThreadX kernel. Task(s) created in tx_application_define() will start running + sl_system_kernel_start(); +} diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/nanoCLR/nanoHAL.cpp b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/nanoCLR/nanoHAL.cpp new file mode 100644 index 0000000000..e754dd5f80 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/nanoCLR/nanoHAL.cpp @@ -0,0 +1,8 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include + +bool g_fDoNotUninitializeDebuggerPort = false; diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/nanoCLR/target_board.h.in b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/nanoCLR/target_board.h.in new file mode 100644 index 0000000000..be11ba01ad --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/nanoCLR/target_board.h.in @@ -0,0 +1,18 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +////////////////////////////////////////////////////////////////////////////// +// This file was automatically generated by a tool. // +// Any changes you make here will be overwritten when it's generated again. // +////////////////////////////////////////////////////////////////////////////// + +#ifndef _TARGET_BOARD_NANOCLR_H_ +#define _TARGET_BOARD_NANOCLR_H_ + +#include + +#define OEMSYSTEMINFOSTRING "nanoCLR running @ @TARGET_NAME@" + +#endif // _TARGET_BOARD_NANOCLR_H_ diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/nanoCLR/usb_hid_app.c b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/nanoCLR/usb_hid_app.c new file mode 100644 index 0000000000..719b80a958 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/nanoCLR/usb_hid_app.c @@ -0,0 +1,243 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Portions Copyright 2018 Silicon Laboratories Inc. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +#include +#include +#include + +#include +#include + +#include +#include "sl_usbd_class_hid.h" +#include + +// Task configuration +#define TASK_STACK_SIZE 512u +#define TASK_PRIO 5u +#define TASK_DELAY_MS 100u + +#define USB_HID_REPORT_LEN 4u + +// FreeRTOS Task handle +static TX_THREAD task_handle; +uint32_t hidThreadStack[TASK_STACK_SIZE / sizeof(uint32_t)]; + +// Mouse report buffer. +__ALIGNED(4) static uint8_t usb_hid_report_buffer[USB_HID_REPORT_LEN]; + +static void hid_task(uint32_t p_arg); + +// Initialize application. +void usb_device_hid_app_init(void) +{ + uint16_t status; + + // Create application task + status = tx_thread_create( + &task_handle, + "USB HID task", + hid_task, + (uint32_t)&sl_usbd_hid_hid0_number, + hidThreadStack, + TASK_STACK_SIZE, + TASK_PRIO, + TASK_PRIO, + TX_NO_TIME_SLICE, + TX_AUTO_START); + + _ASSERTE(status == TX_SUCCESS); +} + +// hid_task() +// Perform HID writes to host. +// @param p_arg Task argument pointer. Class number in this case. +static void hid_task(uint32_t p_arg) +{ + uint8_t class_nbr = *(uint8_t *)p_arg; + bool x_is_pos = true; + bool y_is_pos = true; + bool conn; + sl_status_t status; + uint32_t xfer_len = 0; + const uint32_t xDelay = TX_TICKS_PER_MILLISEC(TASK_DELAY_MS); + + usb_hid_report_buffer[0u] = 0u; + usb_hid_report_buffer[1u] = 0u; + + while (true) + { + + // Wait for device connection. + status = sl_usbd_hid_is_enabled(class_nbr, &conn); + _ASSERTE(status == SL_STATUS_OK); + + while (conn != true) + { + tx_thread_sleep(xDelay); + + status = sl_usbd_hid_is_enabled(class_nbr, &conn); + + _ASSERTE(status == SL_STATUS_OK); + } + + // Emulates back and fourth movement. + ((int8_t *)usb_hid_report_buffer)[2u] = (x_is_pos) ? 50 : -50; + ((int8_t *)usb_hid_report_buffer)[3u] = (y_is_pos) ? 50 : -50; + + x_is_pos = !x_is_pos; + y_is_pos = !y_is_pos; + + // Send report. + status = sl_usbd_hid_write_sync(class_nbr, usb_hid_report_buffer, USB_HID_REPORT_LEN, 0u, &xfer_len); + + // Delay Task + tx_thread_sleep(xDelay); + } +} + +// USB bus events. +void sl_usbd_on_bus_event(sl_usbd_bus_event_t event) +{ + switch (event) + { + case SL_USBD_EVENT_BUS_CONNECT: + // called when usb cable is inserted in a host controller + break; + + case SL_USBD_EVENT_BUS_DISCONNECT: + // called when usb cable is removed from a host controller + break; + + case SL_USBD_EVENT_BUS_RESET: + // called when the host sends reset command + break; + + case SL_USBD_EVENT_BUS_SUSPEND: + // called when the host sends suspend command + break; + + case SL_USBD_EVENT_BUS_RESUME: + // called when the host sends wake up command + break; + + default: + break; + } +} + +// USB configuration events. +void sl_usbd_on_config_event(sl_usbd_config_event_t event, uint8_t config_nbr) +{ + (void)config_nbr; + + switch (event) + { + case SL_USBD_EVENT_CONFIG_SET: + // called when the host sets a configuration after reset + break; + + case SL_USBD_EVENT_CONFIG_UNSET: + // called when a configuration is unset due to reset command + break; + + default: + break; + } +} + +// HID mouse0 instance Enable event. +void sl_usbd_hid_hid0_on_enable_event(void) +{ + // Called when the HID device is connected to the USB host and a + // RESET transfer succeeded. +} + +// HID mouse0 instance Disable event. +void sl_usbd_hid_hid0_on_disable_event(void) +{ + // Called when the HID device is disconnected to the USB host (cable removed). +} + +// Hook function to pass the HID descriptor of the mouse0 instance. +void sl_usbd_hid_hid0_on_get_report_desc_event(const uint8_t **p_report_ptr, uint16_t *p_report_len) +{ + // Called during the HID mouse0 instance initialization so the USB stack + // can retrieve its HID descriptor. + (void)p_report_ptr; + (void)p_report_len; +} + +// Hook function to pass the HID PHY descriptor. +void sl_usbd_hid_hid0_on_get_phy_desc_event(const uint8_t **p_report_ptr, uint16_t *p_report_len) +{ + // Called during the HID mouse0 instance initialization so the USB stack + // can retrieve the its HID physical descriptor. + (void)p_report_ptr; + (void)p_report_len; +} + +// Notification of a new set report received on control endpoint. +// @param report_id Report ID. +// @param p_report_buf Pointer to report buffer. +// @param report_len Length of report, in octets. +void sl_usbd_hid_hid0_on_set_output_report_event(uint8_t report_id, uint8_t *p_report_buf, uint16_t report_len) +{ + // This function is called when host issues a SetReport request. + // The application can take action in function of the report content. + + (void)report_id; + (void)p_report_buf; + (void)report_len; +} + +// Get HID feature report corresponding to report ID. +// @param report_id Report ID. +// @param p_report_buf Pointer to feature report buffer. +// @param report_len Length of report, in octets. +// @note (1) Report ID must not be written into the feature report buffer. +void sl_usbd_hid_hid0_on_get_feature_report_event(uint8_t report_id, uint8_t *p_report_buf, uint16_t report_len) +{ + // This function is called when host issues a GetReport(feature) request. + // The application can provide the report to send by copying it in p_report_buf. + + (void)report_id; + (void)p_report_buf; + (void)report_len; +} + +// Set HID feature report corresponding to report ID. +// @param report_id Report ID. +// @param p_report_buf Pointer to feature report buffer. +// @param report_len Length of report, in octets. +// @note (1) Report ID is not present in the feature report buffer. +void sl_usbd_hid_hid0_on_set_feature_report_event(uint8_t report_id, uint8_t *p_report_buf, uint16_t report_len) +{ + // This function is called when host issues a SetReport(Feature) request. + // The application can take action in function of the provided report in p_report_buf. + + (void)report_id; + (void)p_report_buf; + (void)report_len; +} + +// Retrieve active protocol: BOOT or REPORT protocol. +// @param p_protocol Pointer to variable that will receive the protocol type. +void sl_usbd_hid_hid0_on_get_protocol_event(uint8_t *p_protocol) +{ + // This function is called when host issues a GetProtocol request. + // The application should return the current protocol. + (void)p_protocol; +} + +// Store active protocol: BOOT or REPORT protocol. +// @param protocol Protocol. +void sl_usbd_hid_hid0_on_set_protocol_event(uint8_t protocol) +{ + // This function is called when host issues a SetProtocol request. + // The application should apply the new protocol. + (void)protocol; +} diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_BlockStorage.c b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_BlockStorage.c new file mode 100644 index 0000000000..ad32a4cff7 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_BlockStorage.c @@ -0,0 +1,19 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include + +extern struct BlockStorageDevice Device_BlockStorage; +extern struct MEMORY_MAPPED_NOR_BLOCK_CONFIG Device_BlockStorageConfig; +extern IBlockStorageDevice SL_MscFlash_BlockStorageInterface; + +void BlockStorage_AddDevices() +{ + BlockStorageList_AddDevice( + (BlockStorageDevice *)&Device_BlockStorage, + &SL_MscFlash_BlockStorageInterface, + &Device_BlockStorageConfig, + false); +} diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_BlockStorage.h b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_BlockStorage.h new file mode 100644 index 0000000000..0771bccc7b --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_BlockStorage.h @@ -0,0 +1,12 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#ifndef _TARGETPAL_BLOCKSTORAGE_H_ +#define _TARGETPAL_BLOCKSTORAGE_H_ 1 + +// this device has 1 block storage devices +#define TARGET_BLOCKSTORAGE_COUNT 1 + +#endif //_TARGETPAL_BLOCKSTORAGE_H_ diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_common.c b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_common.c new file mode 100644 index 0000000000..c2100dc5c5 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_common.c @@ -0,0 +1,27 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Portions Copyright (c) Microsoft Corporation. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +#include +#include "target_board.h" +#include +#include + +HAL_SYSTEM_CONFIG HalSystemConfig = { + {true}, // HAL_DRIVER_CONFIG_HEADER Header; + + 1, // ConvertCOM_DebugHandle(1), + 0, // ConvertCOM_DebugHandle(0), + 921600, + 0, // STDIO = COM2 or COM1 + + {RAM1_MEMORY_StartAddress, RAM1_MEMORY_Size}, + {FLASH1_MEMORY_StartAddress, FLASH1_MEMORY_Size}}; + +HAL_TARGET_CONFIGURATION g_TargetConfiguration; + +// this target can use J-Link for updates +inline GET_TARGET_CAPABILITIES(TargetCapabilities_JlinkUpdate); +inline TARGET_HAS_PROPRIETARY_BOOTER(false); diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_common.h.in b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_common.h.in new file mode 100644 index 0000000000..e5a3715d66 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_common.h.in @@ -0,0 +1,52 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +////////////////////////////////////////////////////////////////////////////// +// This file was automatically generated by a tool. // +// Any changes you make here will be overwritten when it's generated again. // +////////////////////////////////////////////////////////////////////////////// + +#ifndef _TARGET_COMMON_H_ +#define _TARGET_COMMON_H_ + +#include + +///////////////////////////////////////////////////////////////////////////////////////// +// The following addresses and sizes should be filled in according to the SoC data-sheet +// they also must be coherent with what's in the linker file for nanoBooter and nanoCLR + +// RAM base address +#define RAM1_MEMORY_StartAddress ((uint32_t)0x20000000) +// RAM size +#define RAM1_MEMORY_Size ((uint32_t)0x000080000) + +// FLASH base address +#define FLASH1_MEMORY_StartAddress ((uint32_t)0x00000000) +// FLASH size +#define FLASH1_MEMORY_Size ((uint32_t)0x00100000) + +///////////////////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////// +#define TARGETNAMESTRING "@TARGET_NAME@" +#define PLATFORMNAMESTRING "GGECKO_S1" +////////////////////////////////////////////// + +////////////////////////////////////////////// +// set Wire Protocol packet size +// valid sizes are 1024, 512, 256, 128 +// check Monitor_Ping_Source_Flags enum +#define WP_PACKET_SIZE 512U +////////////////////////////////////////////// + +///////////////////////////////////// +#define PLATFORM_HAS_RNG TRUE +///////////////////////////////////// + +///////////////////////////////////// +//#define EVENTS_HEART_BEAT +///////////////////////////////////// + +#endif // _TARGET_COMMON_H_ diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_nano_gg_adc_config.cpp b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_nano_gg_adc_config.cpp new file mode 100644 index 0000000000..b5bc402a83 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_nano_gg_adc_config.cpp @@ -0,0 +1,20 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include + +// PE11- ADC0 Port 4X Channel 11 (Expansion Header Pin 6) + +const NF_PAL_ADC_PORT_PIN_CHANNEL AdcPortPinConfig[] = { + + // ADC0 + {0, adcPosSelAPORT4XCH11}, + + // these are the internal sources + {0, adcPosSelTEMP}, + {0, adcPosSelAVDD}, +}; + +const int AdcChannelCount = ARRAYSIZE(AdcPortPinConfig); diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_nano_gg_adc_config.h b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_nano_gg_adc_config.h new file mode 100644 index 0000000000..9423e913ff --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_nano_gg_adc_config.h @@ -0,0 +1,6 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#define GECKO_USE_ADC0 TRUE diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_nf_dev_onewire_config.cpp b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_nf_dev_onewire_config.cpp new file mode 100644 index 0000000000..949567e829 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_nf_dev_onewire_config.cpp @@ -0,0 +1,8 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS BLANK ON PURPOSE BECAUSE THIS TARGET DOESN'T REQUIRE THIS SPECIFIC CONFIGURATION // +/////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_nf_dev_onewire_config.h b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_nf_dev_onewire_config.h new file mode 100644 index 0000000000..2c21c90446 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_nf_dev_onewire_config.h @@ -0,0 +1,11 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +/////////// +// UART0 // +/////////// + +// enable USART0 +#define GECKO_USE_USART0 TRUE diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_stdio_config.c b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_stdio_config.c new file mode 100644 index 0000000000..457394d46b --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_stdio_config.c @@ -0,0 +1,15 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Portions Copyright (c) Microsoft Corporation. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +#include + +// // pin configuration for stdio using UART4 +// // port for TX pin is: GPIOA +// // port for RX pin is: GPIOA +// // TX pin: is GPIOA_0 +// // RX pin: is GPIOA_1 +// // GPIO alternate pin function is 8 see alternate function mapping ST datasheet +// STDIO_UART_CONFIG_PINS(GPIOA, GPIOA, 0, 1, 8) diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_stdio_config.h b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_stdio_config.h new file mode 100644 index 0000000000..d5df942106 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_stdio_config.h @@ -0,0 +1,11 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Portions Copyright (c) Microsoft Corporation. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +// Select which STM32 uart/serial port used. +// If you change STDIO_SERIAL_DRIVER here to another UARTn, also +// edit mcuconf.h to set #define STM32_SERIAL_USE_UARTn TRUE +// and edit GPIO pins defined in target_stdio_config.c +// #define STDIO_SERIAL_DRIVER SD4 diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_system_device_adc_config.cpp b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_system_device_adc_config.cpp new file mode 100644 index 0000000000..e675ce5e97 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_system_device_adc_config.cpp @@ -0,0 +1,20 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include + +// PE11- ADC0 Port 4X Channel 11 (Expansion Header Pin 6) + +const NF_PAL_ADC_PORT_PIN_CHANNEL AdcPortPinConfig[] = { + + // ADC0 + {0, adcPosSelAPORT4XCH11}, + + // these are the internal sources + {0, adcPosSelTEMP}, + {0, adcPosSelAVDD}, +}; + +const int AdcChannelCount = ARRAYSIZE(AdcPortPinConfig); diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_system_device_adc_config.h b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_system_device_adc_config.h new file mode 100644 index 0000000000..9423e913ff --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_system_device_adc_config.h @@ -0,0 +1,6 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#define GECKO_USE_ADC0 TRUE diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_system_device_i2c_config.cpp b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_system_device_i2c_config.cpp new file mode 100644 index 0000000000..8c32bba8e1 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_system_device_i2c_config.cpp @@ -0,0 +1,33 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include + +////////// +// I2C0 // +////////// + +// pin configuration for I2C0 +// port for I2C0_SCL is: PC1 +// port for I2C0_SDA is: PC0 + +// GPIO alternate pin function is 4 for both pins (see Alternate Functionality mapping table in device datasheet) +I2C_CONFIG_PINS(0, gpioPortC, gpioPortC, 1, 0, 4, 4) + +////////// +// I2C2 // +////////// + +// Devices available in GG11 dev kit +// Modules | Description | +// Si7021 | Relative Humidity and Temperature Sensor | +// Si7210 | Hall-Effect Sensor | + +// pin configuration for I2C2 +// port for I2C2_SCL is: GPIOI_5 +// port for I2C2_SDA is: GPIOI_4 + +// GPIO alternate pin function is 7 for both pins (see Alternate Functionality mapping table in device datasheet) +I2C_CONFIG_PINS(2, gpioPortI, gpioPortI, 5, 4, 7, 7) diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_system_device_i2c_config.h b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_system_device_i2c_config.h new file mode 100644 index 0000000000..0e5a564e80 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_system_device_i2c_config.h @@ -0,0 +1,7 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#define GECKO_USE_I2C0 TRUE +#define GECKO_USE_I2C2 TRUE diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_system_device_pwm_config.cpp b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_system_device_pwm_config.cpp new file mode 100644 index 0000000000..7653e6d1c4 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_system_device_pwm_config.cpp @@ -0,0 +1,17 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include + +const NF_PAL_PWM_PORT_PIN_CONFIG PwmPortPinConfig[] = { + + // using WTIMER0, CC0, PC1, location 7 + {0, 0, gpioPortC, 1, 7}, + // using WTIMER1, CC2, PI1, location 5 + {1, 2, gpioPortI, 1, 5}, + +}; + +const int PwmConfigCount = ARRAYSIZE(PwmPortPinConfig); diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_system_device_spi_config.cpp b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_system_device_spi_config.cpp new file mode 100644 index 0000000000..e35066d900 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_system_device_spi_config.cpp @@ -0,0 +1,34 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include + +////////// +// SPI0 // +////////// + +// Note: on SL_STK3701A SPI0 is available at EXP connector + +// pin configuration for SPI0 (EMC encoded "port location") +// SPI0_SCK: PE12, location 0, EXP Header Pin 8 +// SPI0_MOSI: PE10, location 0, EXP Header Pin 4 +// SPI0_MISO: PE11, location 0, EXP Header Pin 6 +// CS: PE13, EXP Header Pin 10 + +INIT_SPI_CONFIG(0, 0, 0, 0) + +////////// +// SPI1 // +////////// + +// Note: on SL_STK3701A SPI1 connects to the LCD-TFT Display + +// pin configuration for SPI1 (EMC encoded "port location") +// SPI1_SCK: PC15, location 3 +// SPI1_MOSI: PA14, location 6 +// SPI1_MISO: (not used for LCD) +// CS: PC14 (not used in SPI configuration) + +INIT_SPI_CONFIG(1, 3, 6, 0) diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_system_device_spi_config.h b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_system_device_spi_config.h new file mode 100644 index 0000000000..6dfccbd22e --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_system_device_spi_config.h @@ -0,0 +1,7 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#define GECKO_USE_SPI0 TRUE +#define GECKO_USE_SPI1 TRUE diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_system_io_ports_config.cpp b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_system_io_ports_config.cpp new file mode 100644 index 0000000000..7bf6f18758 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_system_io_ports_config.cpp @@ -0,0 +1,24 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include "target_system_io_ports_config.h" +#include + +//////////// +// USART2 // +//////////// + +// GPIOs for USART2 are exposed in the J102 connector. + +// pin configuration for USART2 +// port for TX pin is: GPIOA +// port for RX pin is: GPIOA +// TX pin: is PF0 +// RX pin: is PF1 +// GPIO location is 5 +UART_INIT_CONFIG(2, gpioPortF, 0, 5, gpioPortF, 1, 5) + +// un-initialization for UART2 +UART_UNINIT(2, gpioPortF, 0, 5, gpioPortF, 1, 5) diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_system_io_ports_config.h b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_system_io_ports_config.h new file mode 100644 index 0000000000..782ecfe749 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_system_io_ports_config.h @@ -0,0 +1,11 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +//////////// +// USART2 // +//////////// + +// enable USART2 +#define GECKO_USE_USART2 TRUE \ No newline at end of file diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_tx_user.h b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_tx_user.h new file mode 100644 index 0000000000..40c92111ed --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_tx_user.h @@ -0,0 +1,206 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +/////////////////////////////////////////////////////////////////////////////////////////// +// At this time(Azure RTOS v6.1.7_rel) it's not possible to have a different tx_user file +// for nanoBooter and another for nanoCLR. +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef TX_USER_H +#define TX_USER_H + +#define TX_TIMER_TICKS_PER_SECOND 1000 + +/* Define various build options for the ThreadX port. The application should either make changes + here by commenting or un-commenting the conditional compilation defined OR supply the defines + though the compiler's equivalent of the -D option. + + For maximum speed, the following should be defined: + + TX_MAX_PRIORITIES 32 + TX_DISABLE_PREEMPTION_THRESHOLD + TX_DISABLE_REDUNDANT_CLEARING + TX_DISABLE_NOTIFY_CALLBACKS + TX_NOT_INTERRUPTABLE + TX_TIMER_PROCESS_IN_ISR + TX_REACTIVATE_INLINE + TX_DISABLE_STACK_FILLING + TX_INLINE_THREAD_RESUME_SUSPEND + + For minimum size, the following should be defined: + + TX_MAX_PRIORITIES 32 + TX_DISABLE_PREEMPTION_THRESHOLD + TX_DISABLE_REDUNDANT_CLEARING + TX_DISABLE_NOTIFY_CALLBACKS + TX_NOT_INTERRUPTABLE + TX_TIMER_PROCESS_IN_ISR + + Of course, many of these defines reduce functionality and/or change the behavior of the + system in ways that may not be worth the trade-off. For example, the TX_TIMER_PROCESS_IN_ISR + results in faster and smaller code, however, it increases the amount of processing in the ISR. + In addition, some services that are available in timers are not available from ISRs and will + therefore return an error if this option is used. This may or may not be desirable for a + given application. */ + +/* Override various options with default values already assigned in tx_port.h. Please also refer + to tx_port.h for descriptions on each of these options. */ + +/* +#define TX_MAX_PRIORITIES 32 +#define TX_MINIMUM_STACK ???? +#define TX_THREAD_USER_EXTENSION ???? +#define TX_TIMER_THREAD_STACK_SIZE ???? +#define TX_TIMER_THREAD_PRIORITY ???? +*/ + +/* Determine if timer expirations (application timers, timeouts, and tx_thread_sleep calls + should be processed within the a system timer thread or directly in the timer ISR. + By default, the timer thread is used. When the following is defined, the timer expiration + processing is done directly from the timer ISR, thereby eliminating the timer thread control + block, stack, and context switching to activate it. */ + +/* +#define TX_TIMER_PROCESS_IN_ISR +*/ + +/* Determine if in-line timer reactivation should be used within the timer expiration processing. + By default, this is disabled and a function call is used. When the following is defined, + reactivating is performed in-line resulting in faster timer processing but slightly larger + code size. */ + +#define TX_REACTIVATE_INLINE + +/* Determine is stack filling is enabled. By default, ThreadX stack filling is enabled, + which places an 0xEF pattern in each byte of each thread's stack. This is used by + debuggers with ThreadX-awareness and by the ThreadX run-time stack checking feature. */ + +/* +#define TX_DISABLE_STACK_FILLING +*/ + +/* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is + disabled. When the following is defined, ThreadX thread stack checking is enabled. If stack + checking is enabled (TX_ENABLE_STACK_CHECKING is defined), the TX_DISABLE_STACK_FILLING + define is negated, thereby forcing the stack fill which is necessary for the stack checking + logic. */ + +/* +#define TX_ENABLE_STACK_CHECKING +*/ + +/* Determine if preemption-threshold should be disabled. By default, preemption-threshold is + enabled. If the application does not use preemption-threshold, it may be disabled to reduce + code size and improve performance. */ + +/* +#define TX_DISABLE_PREEMPTION_THRESHOLD +*/ + +/* Determine if global ThreadX variables should be cleared. If the compiler startup code clears + the .bss section prior to ThreadX running, the define can be used to eliminate unnecessary + clearing of ThreadX global variables. */ + +#define TX_DISABLE_REDUNDANT_CLEARING + +/* Determine if no timer processing is required. This option will help eliminate the timer + processing when not needed. The user will also have to comment out the call to + tx_timer_interrupt, which is typically made from assembly language in + tx_initialize_low_level. Note: if TX_NO_TIMER is used, the define TX_TIMER_PROCESS_IN_ISR + must also be used. */ + +/* +#define TX_NO_TIMER +#ifndef TX_TIMER_PROCESS_IN_ISR +#define TX_TIMER_PROCESS_IN_ISR +#endif +*/ + +/* Determine if the notify callback option should be disabled. By default, notify callbacks are + enabled. If the application does not use notify callbacks, they may be disabled to reduce + code size and improve performance. */ + +#define TX_DISABLE_NOTIFY_CALLBACKS + +/* Determine if the tx_thread_resume and tx_thread_suspend services should have their internal + code in-line. This results in a larger image, but improves the performance of the thread + resume and suspend services. */ + +/* +#define TX_INLINE_THREAD_RESUME_SUSPEND +*/ + +/* Determine if the internal ThreadX code is non-interruptable. This results in smaller code + size and less processing overhead, but increases the interrupt lockout time. */ + +/* +#define TX_NOT_INTERRUPTABLE +*/ + +/* Determine if the trace event logging code should be enabled. This causes slight increases in + code size and overhead, but provides the ability to generate system trace information which + is available for viewing in TraceX. */ + +/* +#define TX_ENABLE_EVENT_TRACE +*/ + +/* Determine if block pool performance gathering is required by the application. When the following is + defined, ThreadX gathers various block pool performance information. */ + +/* +#define TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO +*/ + +/* Determine if byte pool performance gathering is required by the application. When the following is + defined, ThreadX gathers various byte pool performance information. */ + +/* +#define TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO +*/ + +/* Determine if event flags performance gathering is required by the application. When the following is + defined, ThreadX gathers various event flags performance information. */ + +/* +#define TX_EVENT_FLAGS_ENABLE_PERFORMANCE_INFO +*/ + +/* Determine if mutex performance gathering is required by the application. When the following is + defined, ThreadX gathers various mutex performance information. */ + +/* +#define TX_MUTEX_ENABLE_PERFORMANCE_INFO +*/ + +/* Determine if queue performance gathering is required by the application. When the following is + defined, ThreadX gathers various queue performance information. */ + +/* +#define TX_QUEUE_ENABLE_PERFORMANCE_INFO +*/ + +/* Determine if semaphore performance gathering is required by the application. When the following is + defined, ThreadX gathers various semaphore performance information. */ + +/* +#define TX_SEMAPHORE_ENABLE_PERFORMANCE_INFO +*/ + +/* Determine if thread performance gathering is required by the application. When the following is + defined, ThreadX gathers various thread performance information. */ + +/* +#define TX_THREAD_ENABLE_PERFORMANCE_INFO +*/ + +/* Determine if timer performance gathering is required by the application. When the following is + defined, ThreadX gathers various timer performance information. */ + +/* +#define TX_TIMER_ENABLE_PERFORMANCE_INFO +*/ + +#endif diff --git a/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_ux_user.h b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_ux_user.h new file mode 100644 index 0000000000..f655c33739 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/SL_STK3701A/target_ux_user.h @@ -0,0 +1,345 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +/////////////////////////////////////////////////////////////////////////////////////////// +// At this time(Azure RTOS v6.1.7_rel) it's not possible to have a different ux_user file +// for nanoBooter and another for nanoCLR. +/////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef UX_USER_H +#define UX_USER_H + +/* Define various build options for the USBX port. The application should either make changes + here by commenting or un-commenting the conditional compilation defined OR supply the defines + though the compiler's equivalent of the -D option. */ +/* #define UX_THREAD_STACK_SIZE (2 * 1024) */ + +/* Define USBX Host Enum Thread Stack Size. The default is to use UX_THREAD_STACK_SIZE */ +/* +#define UX_HOST_ENUM_THREAD_STACK_SIZE UX_THREAD_STACK_SIZE +*/ + + +/* Define USBX Host Thread Stack Size. The default is to use UX_THREAD_STACK_SIZE */ +/* +#define UX_HOST_HCD_THREAD_STACK_SIZE UX_THREAD_STACK_SIZE +*/ + +/* Define USBX Host HNP Polling Thread Stack Size. The default is to use UX_THREAD_STACK_SIZE */ +/* +#define UX_HOST_HNP_POLLING_THREAD_STACK UX_THREAD_STACK_SIZE +*/ + +/* Override various options with default values already assigned in ux_api.h or ux_port.h. Please + also refer to ux_port.h for descriptions on each of these options. */ + +/* Defined, this value represents how many ticks per seconds for a specific hardware platform. + The default is 1000 indicating 1 tick per millisecond. */ + +/* #define UX_PERIODIC_RATE 1000 +*/ +#define UX_PERIODIC_RATE (TX_TIMER_TICKS_PER_SECOND) + +/* Define control transfer timeout value in millisecond. + The default is 10000 milliseconds. */ +/* +#define UX_CONTROL_TRANSFER_TIMEOUT 10000 +*/ + +/* Define non control transfer timeout value in millisecond. + The default is 50000 milliseconds. */ +/* +#define UX_NON_CONTROL_TRANSFER_TIMEOUT 50000 +*/ + + +/* Defined, this value is the maximum number of classes that can be loaded by USBX. This value + represents the class container and not the number of instances of a class. For instance, if a + particular implementation of USBX needs the hub class, the printer class, and the storage + class, then the UX_MAX_CLASSES value can be set to 3 regardless of the number of devices + that belong to these classes. */ + +#define UX_MAX_CLASSES 1 + + +/* Defined, this value is the maximum number of classes in the device stack that can be loaded by + USBX. */ + +/* #define UX_MAX_SLAVE_CLASS_DRIVER 1 +*/ + +/* Defined, this value is the maximum number of interfaces in the device framework. */ + +/* #define UX_MAX_SLAVE_INTERFACES 16 +*/ + +/* Defined, this value represents the number of different host controllers available in the system. + For USB 1.1 support, this value will usually be 1. For USB 2.0 support, this value can be more + than 1. This value represents the number of concurrent host controllers running at the same time. + If for instance there are two instances of OHCI running, or one EHCI and one OHCI controller + running, the UX_MAX_HCD should be set to 2. */ + +/* #define UX_MAX_HCD 1 +*/ + + +/* Defined, this value represents the maximum number of devices that can be attached to the USB. + Normally, the theoretical maximum number on a single USB is 127 devices. This value can be + scaled down to conserve memory. Note that this value represents the total number of devices + regardless of the number of USB buses in the system. */ + +/* #define UX_MAX_DEVICES 127 +*/ + + +/* Defined, this value represents the current number of SCSI logical units represented in the device + storage class driver. */ + +/* #define UX_MAX_SLAVE_LUN 1 +*/ + + +/* Defined, this value represents the maximum number of SCSI logical units represented in the + host storage class driver. */ + +/* #define UX_MAX_HOST_LUN 1 +*/ + + +/* Defined, this value represents the maximum number of bytes received on a control endpoint in + the device stack. The default is 256 bytes but can be reduced in memory constrained environments. */ + +/* #define UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH 256 +*/ + + +/* Defined, this value represents the maximum number of bytes that can be received or transmitted + on any endpoint. This value cannot be less than the maximum packet size of any endpoint. The default + is 4096 bytes but can be reduced in memory constrained environments. For cd-rom support in the storage + class, this value cannot be less than 2048. */ + +#define UX_SLAVE_REQUEST_DATA_MAX_LENGTH (1024 * 2) + + +/* Defined, this value includes code to handle storage Multi-Media Commands (MMC). E.g., DVD-ROM. +*/ + +/* #define UX_SLAVE_CLASS_STORAGE_INCLUDE_MMC */ + + +/* Defined, this value represents the maximum number of bytes that a storage payload can send/receive. + The default is 8K bytes but can be reduced in memory constrained environments. */ +#define UX_HOST_CLASS_STORAGE_MEMORY_BUFFER_SIZE (1024 * 8) + +/* Define USBX Mass Storage Thread Stack Size. The default is to use UX_THREAD_STACK_SIZE. */ + +/* #define UX_HOST_CLASS_STORAGE_THREAD_STACK_SIZE UX_THREAD_STACK_SIZE + */ + +/* Defined, this value represents the maximum number of Ed, regular TDs and Isochronous TDs. These values + depend on the type of host controller and can be reduced in memory constrained environments. */ + +#define UX_MAX_ED 80 +#define UX_MAX_TD 128 +#define UX_MAX_ISO_TD 1 + +/* Defined, this value represents the maximum size of the HID decompressed buffer. This cannot be determined + in advance so we allocate a big block, usually 4K but for simple HID devices like keyboard and mouse + it can be reduced a lot. */ + +#define UX_HOST_CLASS_HID_DECOMPRESSION_BUFFER 1024 + +/* Defined, this value represents the maximum number of HID usages for a HID device. + Default is 2048 but for simple HID devices like keyboard and mouse it can be reduced a lot. */ + +#define UX_HOST_CLASS_HID_USAGES 512 + + +/* By default, each key in each HID report from the device is reported by ux_host_class_hid_keyboard_key_get + (a HID report from the device is received whenever there is a change in a key state i.e. when a key is pressed + or released. The report contains every key that is down). There are limitations to this method such as not being + able to determine when a key has been released. + + Defined, this value causes ux_host_class_hid_keyboard_key_get to only report key changes i.e. key presses + and key releases. */ + +/* #define UX_HOST_CLASS_HID_KEYBOARD_EVENTS_KEY_CHANGES_MODE */ + +/* Works when UX_HOST_CLASS_HID_KEYBOARD_EVENTS_KEY_CHANGES_MODE is defined. + + Defined, this value causes ux_host_class_hid_keyboard_key_get to only report key pressed/down changes; + key released/up changes are not reported. + */ + +/* #define UX_HOST_CLASS_HID_KEYBOARD_EVENTS_KEY_CHANGES_MODE_REPORT_KEY_DOWN_ONLY */ + +/* Works when UX_HOST_CLASS_HID_KEYBOARD_EVENTS_KEY_CHANGES_MODE is defined. + + Defined, this value causes ux_host_class_hid_keyboard_key_get to report lock key (CapsLock/NumLock/ScrollLock) changes. + */ + +/* #define UX_HOST_CLASS_HID_KEYBOARD_EVENTS_KEY_CHANGES_MODE_REPORT_LOCK_KEYS */ + +/* Works when UX_HOST_CLASS_HID_KEYBOARD_EVENTS_KEY_CHANGES_MODE is defined. + + Defined, this value causes ux_host_class_hid_keyboard_key_get to report modifier key (Ctrl/Alt/Shift/GUI) changes. + */ + +/* #define UX_HOST_CLASS_HID_KEYBOARD_EVENTS_KEY_CHANGES_MODE_REPORT_MODIFIER_KEYS */ + + +/* Defined, this value represents the maximum number of media for the host storage class. + Default is 8 but for memory constrained resource systems this can ne reduced to 1. */ + +#define UX_HOST_CLASS_STORAGE_MAX_MEDIA 2 + +/* Defined, this value includes code to handle storage devices that use the CB + or CBI protocol (such as floppy disks). It is off by default because these + protocols are obsolete, being superseded by the Bulk Only Transport (BOT) protocol + which virtually all modern storage devices use. +*/ + +/* #define UX_HOST_CLASS_STORAGE_INCLUDE_LEGACY_PROTOCOL_SUPPORT */ + +/* Defined, this value forces the memory allocation scheme to enforce alignment + of memory with the UX_SAFE_ALIGN field. +*/ + +/* #define UX_ENFORCE_SAFE_ALIGNMENT */ + +/* Defined, this value represents the number of packets in the CDC_ECM device class. + The default is 16. +*/ + +#define UX_DEVICE_CLASS_CDC_ECM_NX_PKPOOL_ENTRIES 4 + +/* Defined, this value represents the number of packets in the CDC_ECM host class. + The default is 16. +*/ + +/* #define UX_HOST_CLASS_CDC_ECM_NX_PKPOOL_ENTRIES 16 */ + +/* Defined, this value represents the number of milliseconds to wait for packet + allocation until invoking the application's error callback and retrying. + The default is 1000 milliseconds. +*/ + +/* #define UX_HOST_CLASS_CDC_ECM_PACKET_POOL_WAIT 10 */ + +/* Defined, this value represents the number of milliseconds to wait for packet + pool availability checking loop. + The default is 100 milliseconds. +*/ + +/* #define UX_HOST_CLASS_CDC_ECM_PACKET_POOL_INSTANCE_WAIT 10 */ + +/* Defined, this enables CDC ECM class to use the packet pool from NetX instance. */ + +/* #define UX_HOST_CLASS_CDC_ECM_USE_PACKET_POOL_FROM_NETX */ + +/* Defined, this value represents the number of milliseconds to wait for packet + allocation until invoking the application's error callback and retrying. +*/ + +/* #define UX_DEVICE_CLASS_CDC_ECM_PACKET_POOL_WAIT 10 */ + +/* Defined, this value represents the the maximum length of HID reports on the + device. + */ + +/* #define UX_DEVICE_CLASS_HID_EVENT_BUFFER_LENGTH 64 */ + +/* Defined, this value represents the the maximum number of HID events/reports + that can be queued at once. + */ + +/* #define UX_DEVICE_CLASS_HID_MAX_EVENTS_QUEUE 8 */ + + +/* Defined, this macro will disable DFU_UPLOAD support. */ + +/* #define UX_DEVICE_CLASS_DFU_UPLOAD_DISABLE */ + +/* Defined, this macro will enable DFU_GETSTATUS and DFU_GETSTATE in dfuERROR. */ + +/* #define UX_DEVICE_CLASS_DFU_ERROR_GET_ENABLE */ + +/* Defined, this macro will change status mode. + 0 - simple mode, + status is queried from application in dfuDNLOAD-SYNC and dfuMANIFEST-SYNC state, + no bwPollTimeout. + 1 - status is queried from application once requested, + b0-3 : media status + b4-7 : bStatus + b8-31: bwPollTimeout + bwPollTimeout supported. +*/ + +/* #define UX_DEVICE_CLASS_DFU_STATUS_MODE (1) */ + +/* Defined, this value represents the default DFU status bwPollTimeout. + The value is 3 bytes long (max 0xFFFFFFu). + By default the bwPollTimeout is 1 (means 1ms). + */ + +/* #define UX_DEVICE_CLASS_DFU_STATUS_POLLTIMEOUT (1) */ + +/* Defined, this macro will enable custom request process callback. */ + +/* #define UX_DEVICE_CLASS_DFU_CUSTOM_REQUEST_ENABLE */ + +/* Defined, this macro disables CDC ACM non-blocking transmission support. */ + +/* #define UX_DEVICE_CLASS_CDC_ACM_TRANSMISSION_DISABLE */ + +/* Defined, this macro enables device bi-directional-endpoint support. */ + +/* #define UX_DEVICE_BIDIRECTIONAL_ENDPOINT_SUPPORT */ + +/* Defined, this value will only enable the host side of usbx. */ +/* #define UX_HOST_SIDE_ONLY */ + +/* Defined, this value will only enable the device side of usbx. */ +/* #define UX_DEVICE_SIDE_ONLY */ + +/* Defined, this value will include the OTG polling thread. OTG can only be active if both host/device are present. +*/ + +#ifndef UX_HOST_SIDE_ONLY +#ifndef UX_DEVICE_SIDE_ONLY + +/* #define UX_OTG_SUPPORT */ + +#endif +#endif + +/* Defined, this value represents the maximum size of single tansfers for the SCSI data phase. +*/ + +#define UX_HOST_CLASS_STORAGE_MAX_TRANSFER_SIZE (1024 * 1) + +/* Defined, this value represents the size of the log pool. +*/ +#define UX_DEBUG_LOG_SIZE (1024 * 16) + + +/* Defined, this enables the assert checks inside usbx. */ +#define UX_ENABLE_ASSERT + +/* Defined, this defines the assert action taken when failure detected. By default + it halts without any output. */ +/* #define UX_ASSERT_FAIL for (;;) {tx_thread_sleep(UX_WAIT_FOREVER); } */ + + +/* DEBUG includes and macros for a specific platform go here. */ +#ifdef UX_INCLUDE_USER_DEFINE_BSP +#include "usb_bsp.h" +#include "usbh_hcs.h" +#include "usbh_stdreq.h" +#include "usbh_core.h" +#endif + +#endif + diff --git a/targets/AzureRTOS/SiliconLabs/_common/CMakeLists.txt b/targets/AzureRTOS/SiliconLabs/_common/CMakeLists.txt new file mode 100644 index 0000000000..86fbb3bc2c --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_common/CMakeLists.txt @@ -0,0 +1,44 @@ +# +# Copyright (c) .NET Foundation and Contributors +# See LICENSE file in the project root for full license information. +# + +# Azure RTOS ST specific file +list(APPEND TARGET_AZURERTOS_COMMON_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/Target_BlockStorage_SL_MscFlashDriver.c) +list(APPEND TARGET_AZURERTOS_COMMON_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/WireProtocol_HAL_Interface.c) +list(APPEND TARGET_AZURERTOS_COMMON_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/nanoSupport_CRC32.c) +list(APPEND TARGET_AZURERTOS_COMMON_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/sys_calls.c) + +# append Target files +list(APPEND TARGET_AZURERTOS_COMMON_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/platform_BlockStorage.c) +list(APPEND TARGET_AZURERTOS_COMMON_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/LaunchCLR.c) + +# include configuration manager file, if feature is enabled +if(NF_FEATURE_HAS_CONFIG_BLOCK) + list(APPEND TARGET_AZURERTOS_COMMON_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/targetHAL_ConfigurationManager.cpp) +endif() + +if(HAL_WP_USE_USB_CDC) + list(APPEND TARGET_AZURERTOS_COMMON_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/usb_cdc_acm_app.c) + list(APPEND TARGET_AZURERTOS_COMMON_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/WireProtocol_ReceiverThread_Platform.c) +endif() + +# if(NF_TRACE_TO_STDIO) +# list(APPEND TARGET_AZURERTOS_COMMON_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/Target_GenericPort_stdio.c) +# list(APPEND TARGET_AZURERTOS_COMMON_SOURCES ${TARGET_BASE_LOCATION}/target_stdio_config.c) +# endif() + +# if(USE_NETWORKING_OPTION) + +# configure_file(${CMAKE_CURRENT_SOURCE_DIR}/network_options.h.in +# ${CMAKE_BINARY_DIR}/targets/${RTOS}/${TARGET_BOARD}/network_options.h @ONLY) + +# endif() + +# append hard fault handler if the build type is to include debug info +if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") + list(APPEND TARGET_AZURERTOS_COMMON_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/hard_fault_handler.c) +endif() + +# make vars global +set(TARGET_AZURERTOS_COMMON_SOURCES ${TARGET_AZURERTOS_COMMON_SOURCES} CACHE INTERNAL "make global") diff --git a/targets/AzureRTOS/SiliconLabs/_common/LaunchCLR.c b/targets/AzureRTOS/SiliconLabs/_common/LaunchCLR.c new file mode 100644 index 0000000000..94dd0486f1 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_common/LaunchCLR.c @@ -0,0 +1,89 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include +#include +#include +#include + +#include + +void LaunchCLR(uint32_t address) +{ + // function pointer to load nanoCLR ResetHandler address + irq_vector_t JumpToNanoCLR; + + // report successfull nanoBooter execution + ReportSuccessfullNanoBooter(); + + // load nanoCLR vector table + const vectors_t *nanoCLRVectorTable = (vectors_t *)address; + + // load the jump address with the nanoCLR ResetHandler address + JumpToNanoCLR = nanoCLRVectorTable->ResetHandler; + + // disable all interrupts + __disable_irq(); + + // clear any pending interrupts to make sure we are jumping straight to nanoCLR ResetHandler + SCB->ICSR &= SCB_ICSR_PENDSVCLR_Msk; + + // need to set stack pointer from CLR vector table + __set_MSP((uint32_t)nanoCLRVectorTable->InitStack); + + // make the jump to nanoCLR, at last + JumpToNanoCLR(); +} + +bool CheckValidCLRImage(uint32_t address) +{ + uint32_t resetVectorAddress; + + // load nanoCLR vector table + const vectors_t *nanoCLRVectorTable = (vectors_t *)address; + + // 1st check: the flash content pointed by the address can't be all 0's neither all F's + // meaning that the Flash is neither 'all burnt' or erased + if ((uint32_t)(*(uint32_t **)((uint32_t *)address)) == 0xFFFFFFFF || + (uint32_t)(*(uint32_t **)((uint32_t *)address)) == 0x00000000) + { + // check failed, there is no valid CLR image + return false; + } + + // 2nd check: the content pointed by the reset vector has to be 0xB508 + // that's an assembly "push {r3, lr}" the very first one in the Reset_Handler function + // see platform\Device\SiliconLabs\EFM32GG11B\Source\GCC\startup_efm32gg11b.c + + // "regular" address mapping + resetVectorAddress = (uint32_t)((uint32_t *)nanoCLRVectorTable->ResetHandler); + + // sanity check for invalid address (out of flash range which causes a hard fault) + if (resetVectorAddress <= FLASH1_MEMORY_StartAddress || + resetVectorAddress >= (FLASH1_MEMORY_StartAddress + FLASH1_MEMORY_Size)) + { + // check failed, doesn't seem to be a valid CLR image + return false; + } + + // the linker can place this anywhere on the address space because of optimizations so we better check where the + // reset pointer points to + uint32_t opCodeAddress = (uint32_t)((uint32_t **)nanoCLRVectorTable->ResetHandler); + + // real address is -1 + opCodeAddress -= 1; + + uint32_t opCode = *((uint32_t *)opCodeAddress); + if ((uint16_t)opCode == 0xB508) + { + // check, there seems to be a valid CLR image + return true; + } + else + { + // got here so there isn't a valid CLR imaged flashed + return false; + } +} diff --git a/targets/AzureRTOS/SiliconLabs/_common/Target_BlockStorage_SL_MscFlashDriver.c b/targets/AzureRTOS/SiliconLabs/_common/Target_BlockStorage_SL_MscFlashDriver.c new file mode 100644 index 0000000000..fe0e003c71 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_common/Target_BlockStorage_SL_MscFlashDriver.c @@ -0,0 +1,100 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include + +#define FLASH_ERASED_WORD ((uint32_t)0xFFFFFFFF) + +bool SL_MscFlashDriver_InitializeDevice(void *context) +{ + (void)context; + + // Gecko SDK driver takes care of this, so always true + return true; +} + +bool SL_MscFlashDriver_UninitializeDevice(void *context) +{ + (void)context; + + // Gecko SDK driver takes care of this, so always true + return true; +} + +DeviceBlockInfo *SL_MscFlashDriver_GetDeviceInfo(void *context) +{ + + MEMORY_MAPPED_NOR_BLOCK_CONFIG *config = context; + + return config->BlockConfig.BlockDeviceInformation; +} + +bool SL_MscFlashDriver_Read(void *context, ByteAddress startAddress, unsigned int numBytes, unsigned char *buffer) +{ + (void)context; + + volatile uint8_t *cursor = (volatile uint8_t *)startAddress; + volatile uint8_t *endAddress = (volatile uint8_t *)(startAddress + numBytes); + + // copy contents from flash to buffer starting from the start address + while (cursor < endAddress) + { + *buffer++ = *cursor++; + } + + return true; +} + +bool SL_MscFlashDriver_Write( + void *context, + ByteAddress startAddress, + unsigned int numBytes, + unsigned char *buffer, + bool readModifyWrite) +{ + (void)context; + (void)readModifyWrite; + + MSC_Status_TypeDef mscReturn; + + MSC_Init(); + + mscReturn = MSC_WriteWord((uint32_t *)startAddress, (void const *)buffer, numBytes); + + MSC_Deinit(); + + return mscReturn == mscReturnOk; +} + +bool SL_MscFlashDriver_IsBlockErased(void *context, ByteAddress blockAddress, unsigned int length) +{ + (void)context; + (void)blockAddress; + (void)length; + + uint32_t *cursor = (uint32_t *)blockAddress; + uint32_t *endAddress = (uint32_t *)(blockAddress + length); + + // an erased flash address has to read FLASH_ERASED_WORD + // OK to check by word (32 bits) because the erase is performed by 'page' whose size is word multiple + while (cursor < endAddress) + { + if (*cursor++ != FLASH_ERASED_WORD) + { + // found an address with something other than FLASH_ERASED_WORD!! + return false; + } + } + + // reached here so the segment must be erased + return true; +} + +bool SL_MscFlashDriver_EraseBlock(void *context, ByteAddress address) +{ + (void)context; + + return MSC_ErasePage((uint32_t *)address) == mscReturnOk; +} diff --git a/targets/AzureRTOS/SiliconLabs/_common/WireProtocol_HAL_Interface.c b/targets/AzureRTOS/SiliconLabs/_common/WireProtocol_HAL_Interface.c new file mode 100644 index 0000000000..23ed570374 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_common/WireProtocol_HAL_Interface.c @@ -0,0 +1,121 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include + +#include +#include +#include + +#include +#include + +#if HAL_WP_USE_SERIAL == TRUE +#include +#include +#elif HAL_WP_USE_USB_CDC == TRUE + +#include +#include +#include +#include +#endif + +#if defined(TRACE_MASK) && (TRACE_MASK & TRACE_VERBOSE) != 0 +// used WP_Message_Process() and methods it calls to avoid flooding TRACE +extern uint32_t traceLoopCounter; +#endif + +void WP_ReceiveBytes(uint8_t **ptr, uint32_t *size) +{ + // save for later comparison + uint32_t requestedSize = *size; + sl_status_t requestResult; + +#if HAL_WP_USE_SERIAL == TRUE + size_t bytesRead; +#elif HAL_WP_USE_USB_CDC == TRUE + uint32_t bytesRead; +#endif + + // check for requests with 0 size + if (*size) + { +#if HAL_WP_USE_SERIAL == TRUE + // blocking receive as SL API does not support non-blocking + requestResult = sl_iostream_read(sl_iostream_vcom_handle, *ptr, requestedSize, &bytesRead); +#elif HAL_WP_USE_USB_CDC == TRUE + requestResult = sl_usbd_cdc_acm_read(sl_usbd_cdc_acm_acm0_number, *ptr, requestedSize, 200, &bytesRead); +#endif + + // Warning: Including TRACE_VERBOSE will NOT output the following TRACE on every loop of the statemachine to + // avoid flooding the trace. + TRACE_LIMIT(TRACE_VERBOSE, 100, "RXMSG: Expecting %d bytes, received %d.\n", requestedSize, read); + +#if HAL_WP_USE_SERIAL == TRUE + if (requestResult == SL_STATUS_EMPTY) + { + // hang here for a bit + tx_thread_sleep(10); + } + else +#endif + if (requestResult == SL_STATUS_OK) + { + // update pointer and size + *ptr += bytesRead; + *size -= bytesRead; + } + } + + return; +} + +uint8_t WP_TransmitMessage(WP_Message *message) +{ +#if HAL_WP_USE_USB_CDC == TRUE + uint32_t dummy = 0; +#endif + + TRACE_WP_HEADER(WP_TXMSG, message); + +#if HAL_WP_USE_SERIAL == TRUE + // non-blocking transmit + if (sl_iostream_write(sl_iostream_vcom_handle, (uint8_t *)&message->m_header, sizeof(message->m_header)) != + SL_STATUS_OK) +#elif HAL_WP_USE_USB_CDC == TRUE + if (sl_usbd_cdc_acm_write( + sl_usbd_cdc_acm_acm0_number, + (uint8_t *)&message->m_header, + sizeof(message->m_header), + 20, + &dummy) != SL_STATUS_OK) +#endif + + { + return false; + } + + // if there is anything on the payload send it to the output stream + if (message->m_header.m_size && message->m_payload) + { +#if HAL_WP_USE_SERIAL == TRUE + // non-blocking transmit + if (sl_iostream_write(sl_iostream_vcom_handle, message->m_payload, message->m_header.m_size) != SL_STATUS_OK) +#elif HAL_WP_USE_USB_CDC == TRUE + if (sl_usbd_cdc_acm_write( + sl_usbd_cdc_acm_acm0_number, + message->m_payload, + message->m_header.m_size, + 200, + &dummy) != SL_STATUS_OK) +#endif + { + return false; + } + } + + return true; +} diff --git a/targets/AzureRTOS/SiliconLabs/_common/WireProtocol_ReceiverThread_Platform.c b/targets/AzureRTOS/SiliconLabs/_common/WireProtocol_ReceiverThread_Platform.c new file mode 100644 index 0000000000..b9f543c678 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_common/WireProtocol_ReceiverThread_Platform.c @@ -0,0 +1,73 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#define TASK_DELAY_MS 250u + +__attribute__((noreturn)) void ReceiverThread_entry(uint32_t parameter) +{ + (void)parameter; + +#if HAL_WP_USE_USB_CDC == TRUE + +#if !defined(BUILD_RTM) + sl_status_t status = SL_STATUS_OK; +#endif + + bool conn = false; + + const uint32_t xDelay = TX_TICKS_PER_MILLISEC(TASK_DELAY_MS); +#endif + + tx_thread_sleep(50); + + WP_Message_PrepareReception(); + + // loop until thread receives a request to terminate + while (1) + { + +#if HAL_WP_USE_USB_CDC == TRUE + + // Wait until device is in configured state +#if !defined(BUILD_RTM) + status = +#endif + sl_usbd_cdc_acm_is_enabled(sl_usbd_cdc_acm_acm0_number, &conn); + _ASSERTE(status == SL_STATUS_OK); + + // while ((conn != true) || ((line_state & SL_USBD_CDC_ACM_CTRL_DTR) == 0)) + while ((conn != true)) + { + // Delay Task + tx_thread_sleep(xDelay); + +#if !defined(BUILD_RTM) + status = +#endif + sl_usbd_cdc_acm_is_enabled(sl_usbd_cdc_acm_acm0_number, &conn); + _ASSERTE(status == SL_STATUS_OK); + } +#endif + + WP_Message_Process(); + + // pass control to the OS + tx_thread_sleep(TX_TICKS_PER_MILLISEC(10)); + } + + // this function never returns +} diff --git a/targets/AzureRTOS/SiliconLabs/_common/autogen/RTE_Components.h b/targets/AzureRTOS/SiliconLabs/_common/autogen/RTE_Components.h new file mode 100644 index 0000000000..c62a617c82 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_common/autogen/RTE_Components.h @@ -0,0 +1,16 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Copyright 2020 Silicon Laboratories Inc. www.silabs.com +// See LICENSE file in the project root for full license information. +// + +#ifndef RTE_COMPONENTS_H +#define RTE_COMPONENTS_H + +/* standard device header from emlib */ +#define CMSIS_device_header "em_device.h" + +/* components are auto-generated here */ + + +#endif /* RTE_COMPONENTS_H */ diff --git a/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_board_default_init_stub.c b/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_board_default_init_stub.c new file mode 100644 index 0000000000..034a7d9f08 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_board_default_init_stub.c @@ -0,0 +1,13 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Copyright 2022 Silicon Laboratories Inc. www.silabs.com +// See LICENSE file in the project root for full license information. +// + +#include +#include + +// defined as weak to allow overriding at target level +__nfweak void sl_board_default_init(void) +{ +} diff --git a/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_component_catalog.h b/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_component_catalog.h new file mode 100644 index 0000000000..a0ee173be4 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_component_catalog.h @@ -0,0 +1,78 @@ +#ifndef SL_COMPONENT_CATALOG_H +#define SL_COMPONENT_CATALOG_H + +#include + +// APIs present in project +#define SL_CATALOG_DEVICE_INIT_NVIC_PRESENT +#define SL_CATALOG_EMLIB_CORE_DEBUG_CONFIG_PRESENT +#define SL_CATALOG_LED0_PRESENT +#define SL_CATALOG_LED1_PRESENT +#define SL_CATALOG_SIMPLE_LED_PRESENT +#define SL_CATALOG_SIMPLE_LED_LED0_PRESENT +#define SL_CATALOG_SLEEPTIMER_PRESENT + +#if HAL_WP_USE_SERIAL == TRUE + +#define SL_CATALOG_IOSTREAM_UART_COMMON_PRESENT +#define SL_CATALOG_IOSTREAM_USART_PRESENT + +#endif + +// TODO +// #define SL_CATALOG_KERNEL_PRESENT + +#if defined(I_AM_NANOCLR) && GECKO_FEATURE_USBD_HID == TRUE + +#define SL_CATALOG_USB_DEVICE_PRESENT +#define SL_CATALOG_USB_DEVICE_HID_PRESENT +#define SL_CATALOG_USB_DEVICE_CONFIGURATION_PRESENT +#define SL_CATALOG_USB_DEVICE_CORE_PRESENT +#define SL_CATALOG_USB_DEVICE_DRIVER_PRESENT + +#endif + +#if defined(I_AM_NANOCLR) && GECKO_FEATURE_USBD_WINUSB == TRUE + +#ifndef SL_CATALOG_USB_DEVICE_PRESENT +#define SL_CATALOG_USB_DEVICE_PRESENT +#endif + +#ifndef SL_CATALOG_USB_DEVICE_CONFIGURATION_PRESENT +#define SL_CATALOG_USB_DEVICE_CONFIGURATION_PRESENT +#endif + +#ifndef SL_CATALOG_USB_DEVICE_CORE_PRESENT +#define SL_CATALOG_USB_DEVICE_CORE_PRESENT +#endif + +#ifndef SL_CATALOG_USB_DEVICE_DRIVER_PRESENT +#define SL_CATALOG_USB_DEVICE_DRIVER_PRESENT +#endif + +#endif + +#if HAL_WP_USE_USB_CDC == TRUE + +#ifndef SL_CATALOG_USB_DEVICE_PRESENT +#define SL_CATALOG_USB_DEVICE_PRESENT +#endif + +#define SL_CATALOG_USB_DEVICE_CDC_PRESENT +#define SL_CATALOG_USB_DEVICE_CDC_ACM_PRESENT + +#ifndef SL_CATALOG_USB_DEVICE_CONFIGURATION_PRESENT +#define SL_CATALOG_USB_DEVICE_CONFIGURATION_PRESENT +#endif + +#ifndef SL_CATALOG_USB_DEVICE_CORE_PRESENT +#define SL_CATALOG_USB_DEVICE_CORE_PRESENT +#endif + +#ifndef SL_CATALOG_USB_DEVICE_DRIVER_PRESENT +#define SL_CATALOG_USB_DEVICE_DRIVER_PRESENT +#endif + +#endif + +#endif // SL_COMPONENT_CATALOG_H diff --git a/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_device_init_clocks_default.c b/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_device_init_clocks_default.c new file mode 100644 index 0000000000..cfde392023 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_device_init_clocks_default.c @@ -0,0 +1,30 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Copyright 2019 Silicon Laboratories Inc. www.silabs.com +// See LICENSE file in the project root for full license information. +// + +#include "sl_device_init_clocks.h" + +#include "em_cmu.h" +#include + +// implemented as weak function to allow overriding at platform level +__nfweak sl_status_t sl_device_init_clocks(void) +{ + CMU_ClockSelectSet(cmuClock_HF, cmuSelect_HFXO); + + CMU_ClockEnable(cmuClock_HFLE, true); + CMU_ClockEnable(cmuClock_HFPER, true); + CMU_ClockEnable(cmuClock_GPIO, true); + CMU_CLOCK_SELECT_SET(LFA, LFXO); + CMU_CLOCK_SELECT_SET(LFB, LFXO); +#if defined(_CMU_LFCCLKSEL_MASK) + CMU_CLOCK_SELECT_SET(LFC, LFXO); +#endif +#if defined(_CMU_LFECLKSEL_MASK) + CMU_CLOCK_SELECT_SET(LFE, LFXO); +#endif + + return SL_STATUS_OK; +} diff --git a/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_event_handler.h b/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_event_handler.h new file mode 100644 index 0000000000..508c65c203 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_event_handler.h @@ -0,0 +1,24 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Copyright 2020 Silicon Laboratories Inc. www.silabs.com +// See LICENSE file in the project root for full license information. +// + +#ifndef SL_EVENT_HANDLER_H +#define SL_EVENT_HANDLER_H + +void sl_platform_init(void); +void sl_kernel_start(void); +void sl_driver_init(void); +void sl_service_init(void); +void sl_stack_init(void); +void sl_internal_app_init(void); +void sl_platform_process_action(void); +void sl_service_process_action(void); +void sl_stack_process_action(void); +void sl_internal_app_process_action(void); +void sl_iostream_init_instances(void); +void sl_stack_init_target(void); +void sl_driver_init_target(void); + +#endif // SL_EVENT_HANDLER_H diff --git a/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_event_handler_default.c b/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_event_handler_default.c new file mode 100644 index 0000000000..faaf3ce4f5 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_event_handler_default.c @@ -0,0 +1,127 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Copyright 2020 Silicon Laboratories Inc. www.silabs.com +// See LICENSE file in the project root for full license information. +// + +#include "sl_event_handler.h" + +#include "em_chip.h" +#include "sl_device_init_nvic.h" +#include "sl_board_init.h" +#include "sl_device_init_dcdc.h" +#include "sl_device_init_hfxo.h" +#include "sl_device_init_lfxo.h" +#include "sl_device_init_hfrco.h" +#include "sl_device_init_lfrco.h" +#include "sl_device_init_clocks.h" +#include "sl_device_init_emu.h" +#include "sl_board_control.h" +#include "sl_sleeptimer.h" +#include "gpiointerrupt.h" +#include "sl_uartdrv_instances.h" +#include "sl_iostream_init_usart_instances.h" +#include "sl_iostream_init_instances.h" +#include "sl_i2cspm_instances.h" +#include "sl_power_manager.h" + +#include +#include + +extern void InitGpCrc(void); + +// implemented as weak function to allow overriding at platform level +// DEVELOPER NOTE: when implementing this function, make sure to call ALL the functions there +// except for the ones that aren't required for your target +__nfweak void sl_platform_init(void) +{ + CHIP_Init(); + sl_device_init_nvic(); + sl_board_preinit(); + sl_device_init_dcdc(); + sl_device_init_hfxo(); + sl_device_init_lfxo(); + sl_device_init_clocks(); + sl_device_init_emu(); + sl_board_init(); + sl_power_manager_init(); + InitGpCrc(); +} + +// implemented as weak function to allow overriding at platform level +__nfweak void sl_kernel_start(void) +{ + // Enter the ThreadX kernel. + tx_kernel_enter(); +} + +// implemented as weak function to allow overriding at platform level +__nfweak void sl_driver_init(void) +{ + sl_i2cspm_init_instances(); + +#if HAL_WP_USE_SERIAL == TRUE + sl_uartdrv_init_instances(); +#endif + + sl_driver_init_target(); +} + +// implemented as weak function to allow overriding at platform level +__nfweak void sl_service_init(void) +{ + sl_board_configure_vcom(); + sl_sleeptimer_init(); + +#if HAL_WP_USE_SERIAL == TRUE + sl_iostream_init_instances(); +#endif +} + +// implemented as weak function to allow overriding at platform level +__nfweak void sl_stack_init(void) +{ + sl_stack_init_target(); +} + +// implemented as weak function to allow overriding at platform level +__nfweak void sl_internal_app_init(void) +{ +} + +// implemented as weak function to allow overriding at platform level +__nfweak void sl_platform_process_action(void) +{ +} + +// implemented as weak function to allow overriding at platform level +__nfweak void sl_service_process_action(void) +{ +} + +void sl_stack_process_action(void) +{ +} + +// implemented as weak function to allow overriding at platform level +__nfweak void sl_internal_app_process_action(void) +{ +} + +// implemented as weak function to allow overriding at platform level +__nfweak void sl_iostream_init_instances(void) +{ +#if HAL_WP_USE_SERIAL == TRUE + sl_iostream_usart_init_instances(); +#endif +} + +// provided as weak so it can be replaced at target level +__nfweak void sl_stack_init_target(void) +{ +} + +// provided as weak so it can be replaced at target level +__nfweak void sl_driver_init_target(void) +{ +} diff --git a/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_i2cspm_init.c b/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_i2cspm_init.c new file mode 100644 index 0000000000..042abb18a8 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_i2cspm_init.c @@ -0,0 +1,41 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Copyright 2020 Silicon Laboratories Inc. www.silabs.com +// See LICENSE file in the project root for full license information. +// + +#include "sl_i2cspm.h" +#include "em_cmu.h" +// Include instance config +#include "sl_i2cspm_sensor_config.h" + +sl_i2cspm_t *sl_i2cspm_sensor = SL_I2CSPM_SENSOR_PERIPHERAL; + +#if SL_I2CSPM_SENSOR_SPEED_MODE == 0 +#define SL_I2CSPM_SENSOR_HLR i2cClockHLRStandard +#define SL_I2CSPM_SENSOR_MAX_FREQ I2C_FREQ_STANDARD_MAX +#elif SL_I2CSPM_SENSOR_SPEED_MODE == 1 +#define SL_I2CSPM_SENSOR_HLR i2cClockHLRAsymetric +#define SL_I2CSPM_SENSOR_MAX_FREQ I2C_FREQ_FAST_MAX +#elif SL_I2CSPM_SENSOR_SPEED_MODE == 2 +#define SL_I2CSPM_SENSOR_HLR i2cClockHLRFast +#define SL_I2CSPM_SENSOR_MAX_FREQ I2C_FREQ_FASTPLUS_MAX +#endif + +I2CSPM_Init_TypeDef init_sensor = { + .port = SL_I2CSPM_SENSOR_PERIPHERAL, + .sclPort = SL_I2CSPM_SENSOR_SCL_PORT, + .sclPin = SL_I2CSPM_SENSOR_SCL_PIN, + .sdaPort = SL_I2CSPM_SENSOR_SDA_PORT, + .sdaPin = SL_I2CSPM_SENSOR_SDA_PIN, + .portLocationScl = SL_I2CSPM_SENSOR_SCL_LOC, + .portLocationSda = SL_I2CSPM_SENSOR_SDA_LOC, + .i2cRefFreq = 0, + .i2cMaxFreq = SL_I2CSPM_SENSOR_MAX_FREQ, + .i2cClhr = SL_I2CSPM_SENSOR_HLR +}; + +void sl_i2cspm_init_instances(void) +{ + CMU_ClockEnable(cmuClock_GPIO, true); +} diff --git a/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_i2cspm_instances.h b/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_i2cspm_instances.h new file mode 100644 index 0000000000..dfcdd79f7e --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_i2cspm_instances.h @@ -0,0 +1,28 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Copyright 2020 Silicon Laboratories Inc. www.silabs.com +// See LICENSE file in the project root for full license information. +// + +#ifndef SL_I2CSPM_INSTANCES_H +#define SL_I2CSPM_INSTANCES_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "sl_i2cspm.h" + + +#define SL_I2CSPM_SENSOR_PRESENT + + +extern sl_i2cspm_t *sl_i2cspm_sensor; + +void sl_i2cspm_init_instances(void); + +#ifdef __cplusplus +} +#endif + +#endif // SL_I2CSPM_INSTANCES_H diff --git a/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_iostream_handles.c b/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_iostream_handles.c new file mode 100644 index 0000000000..b89c50f299 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_iostream_handles.c @@ -0,0 +1,34 @@ +#include "sl_iostream.h" +#include "sl_iostream_handles.h" +#include "string.h" +#include + +const sl_iostream_instance_info_t *sl_iostream_instances_info[] = { + +#if HAL_WP_USE_SERIAL == TRUE + &sl_iostream_instance_vcom_info, +#endif + +#if HAL_USE_ONEWIRE == TRUE + &sl_iostream_instance_onewire_info, +#endif + +}; + +const uint32_t sl_iostream_instances_count = sizeof(sl_iostream_instances_info) / sizeof(sl_iostream_instances_info[0]); + +/***************************************************************************//** + * Get iostream instance handle for a given name + * + * @return Instance handle if it exist, NULL otherwise. + ******************************************************************************/ +sl_iostream_t *sl_iostream_get_handle(char *name) +{ + for (uint32_t i = 0; i < sl_iostream_instances_count; i++) { + if (strcmp(sl_iostream_instances_info[i]->name, name) == 0) { + return sl_iostream_instances_info[i]->handle; + } + } + + return NULL; +} diff --git a/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_iostream_handles.h b/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_iostream_handles.h new file mode 100644 index 0000000000..0edcc71ed1 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_iostream_handles.h @@ -0,0 +1,20 @@ +#ifndef SL_IOSTREAM_HANDLES_H +#define SL_IOSTREAM_HANDLES_H +#include "sl_iostream.h" +#include "sl_iostream_init_usart_instances.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +extern const sl_iostream_instance_info_t *sl_iostream_instances_info[]; +extern const uint32_t sl_iostream_instances_count; + +sl_iostream_t *sl_iostream_get_handle(char *name); + +#ifdef __cplusplus +} +#endif + +#endif // SL_IOSTREAM_HANDLES_H diff --git a/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_iostream_init_instances.h b/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_iostream_init_instances.h new file mode 100644 index 0000000000..7bd47c07f2 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_iostream_init_instances.h @@ -0,0 +1,16 @@ +#ifndef SL_IOSTREAM_INIT_INSTANCES_H +#define SL_IOSTREAM_INIT_INSTANCES_H + +#include "sl_iostream.h" +#ifdef __cplusplus +extern "C" { +#endif + +// Initialize iostream component(s) / instance(s) +void sl_iostream_init_instances(void); + +#ifdef __cplusplus +} +#endif + +#endif // SL_IOSTREAM_INIT_INSTANCES_H diff --git a/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_iostream_init_usart_instances.c b/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_iostream_init_usart_instances.c new file mode 100644 index 0000000000..71e5e99c18 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_iostream_init_usart_instances.c @@ -0,0 +1,350 @@ +#if defined(SL_COMPONENT_CATALOG_PRESENT) +#include "sl_component_catalog.h" +#endif +#if defined(SL_CATALOG_POWER_MANAGER_PRESENT) +#include "sl_power_manager.h" +#endif +#include "em_device.h" +#include "sl_iostream.h" +#include "sl_iostream_uart.h" +#include "sl_iostream_usart.h" +#include + +// Include instance config +#if HAL_WP_USE_SERIAL == TRUE +#include "sl_iostream_usart_vcom_config.h" +#endif +#if HAL_USE_ONEWIRE == TRUE +#include "sl_iostream_usart_onewire_config.h" +#endif + +#include + +// need to define this here to avoid compiler warning (error) +#define usartHwFlowControlNone 0 + +//////////////////////////////////////////////////////////////// +// Baudrate for the serial port // +// Override default setting from board if build option is set // +//////////////////////////////////////////////////////////////// +#ifdef TARGET_SERIAL_BAUDRATE +#undef SL_IOSTREAM_USART_VCOM_BAUDRATE +#define SL_IOSTREAM_USART_VCOM_BAUDRATE TARGET_SERIAL_BAUDRATE +#endif + +// MACROs for generating name and IRQ handler function +#define SL_IOSTREAM_USART_CONCAT_PASTER(first, second, third) first##second##third + +#define SL_IOSTREAM_USART_TX_IRQ_NUMBER(periph_nbr) SL_IOSTREAM_USART_CONCAT_PASTER(USART, periph_nbr, _TX_IRQn) +#define SL_IOSTREAM_USART_RX_IRQ_NUMBER(periph_nbr) SL_IOSTREAM_USART_CONCAT_PASTER(USART, periph_nbr, _RX_IRQn) +#define SL_IOSTREAM_USART_TX_IRQ_HANDLER(periph_nbr) SL_IOSTREAM_USART_CONCAT_PASTER(USART, periph_nbr, _TX_IRQHandler) +#define SL_IOSTREAM_USART_RX_IRQ_HANDLER(periph_nbr) SL_IOSTREAM_USART_CONCAT_PASTER(USART, periph_nbr, _RX_IRQHandler) + +#define SL_IOSTREAM_USART_RX_DMA_SIGNAL(periph_nbr) \ + SL_IOSTREAM_USART_CONCAT_PASTER(dmadrvPeripheralSignal_USART, periph_nbr, _RXDATAV) + +#define SL_IOSTREAM_USART_CLOCK_REF(periph_nbr) SL_IOSTREAM_USART_CONCAT_PASTER(cmuClock_, USART, periph_nbr) + +// EM Events +#if defined(SL_CATALOG_POWER_MANAGER_PRESENT) +#if defined(_SILICON_LABS_32B_SERIES_2) +#define SLEEP_EM_EVENT_MASK \ + (SL_POWER_MANAGER_EVENT_TRANSITION_ENTERING_EM2 | SL_POWER_MANAGER_EVENT_TRANSITION_LEAVING_EM2 | \ + SL_POWER_MANAGER_EVENT_TRANSITION_ENTERING_EM3 | SL_POWER_MANAGER_EVENT_TRANSITION_LEAVING_EM3 | \ + SL_POWER_MANAGER_EVENT_TRANSITION_LEAVING_EM0) +#else +#define SLEEP_EM_EVENT_MASK (SL_POWER_MANAGER_EVENT_TRANSITION_LEAVING_EM0) +#endif // _SILICON_LABS_32B_SERIES_2 +static void events_handler(sl_power_manager_em_t from, sl_power_manager_em_t to); +static sl_power_manager_em_transition_event_info_t events_info = { + .event_mask = SLEEP_EM_EVENT_MASK, + .on_event = events_handler, +}; +static sl_power_manager_em_transition_event_handle_t events_handle; +#endif // SL_CATALOG_POWER_MANAGER_PRESENT + +// Instance(s) handle and context variable + +#if HAL_WP_USE_SERIAL == TRUE + +sl_status_t sl_iostream_usart_init_vcom(void); +static sl_iostream_uart_t sl_iostream_vcom; +sl_iostream_t *sl_iostream_vcom_handle = &sl_iostream_vcom.stream; +sl_iostream_uart_t *sl_iostream_uart_vcom_handle = &sl_iostream_vcom; +static sl_iostream_usart_context_t context_vcom; +static uint8_t rx_buffer_vcom[SL_IOSTREAM_USART_VCOM_RX_BUFFER_SIZE]; +sl_iostream_instance_info_t sl_iostream_instance_vcom_info = { + .handle = &sl_iostream_vcom.stream, + .name = "vcom", + .type = SL_IOSTREAM_TYPE_UART, + .periph_id = SL_IOSTREAM_USART_VCOM_PERIPHERAL_NO, + .init = sl_iostream_usart_init_vcom, +}; + +sl_status_t sl_iostream_usart_init_vcom(void) +{ + sl_status_t status; + USART_InitAsync_TypeDef init_vcom = USART_INITASYNC_DEFAULT; + init_vcom.baudrate = SL_IOSTREAM_USART_VCOM_BAUDRATE; + init_vcom.parity = SL_IOSTREAM_USART_VCOM_PARITY; + init_vcom.stopbits = SL_IOSTREAM_USART_VCOM_STOP_BITS; +#if (_SILICON_LABS_32B_SERIES > 0) + init_vcom.hwFlowControl = SL_IOSTREAM_USART_VCOM_FLOW_CONTROL_TYPE != uartFlowControlSoftware + ? SL_IOSTREAM_USART_VCOM_FLOW_CONTROL_TYPE + : usartHwFlowControlNone; +#endif + sl_iostream_usart_config_t config_vcom = { + .usart = SL_IOSTREAM_USART_VCOM_PERIPHERAL, + .clock = SL_IOSTREAM_USART_CLOCK_REF(SL_IOSTREAM_USART_VCOM_PERIPHERAL_NO), + .tx_port = SL_IOSTREAM_USART_VCOM_TX_PORT, + .tx_pin = SL_IOSTREAM_USART_VCOM_TX_PIN, + .rx_port = SL_IOSTREAM_USART_VCOM_RX_PORT, + .rx_pin = SL_IOSTREAM_USART_VCOM_RX_PIN, +#if (_SILICON_LABS_32B_SERIES > 0) +#if defined(SL_IOSTREAM_USART_VCOM_CTS_PORT) + .cts_port = SL_IOSTREAM_USART_VCOM_CTS_PORT, + .cts_pin = SL_IOSTREAM_USART_VCOM_CTS_PIN, +#endif +#if defined(SL_IOSTREAM_USART_VCOM_RTS_PORT) + .rts_port = SL_IOSTREAM_USART_VCOM_RTS_PORT, + .rts_pin = SL_IOSTREAM_USART_VCOM_RTS_PIN, +#endif +#endif +#if defined(GPIO_USART_ROUTEEN_TXPEN) + .usart_index = SL_IOSTREAM_USART_VCOM_PERIPHERAL_NO, +#elif defined(USART_ROUTEPEN_RXPEN) + .usart_tx_location = SL_IOSTREAM_USART_VCOM_TX_LOC, + .usart_rx_location = SL_IOSTREAM_USART_VCOM_RX_LOC, +#if defined(SL_IOSTREAM_USART_VCOM_CTS_PORT) + .usart_cts_location = SL_IOSTREAM_USART_VCOM_CTS_LOC, +#endif +#if defined(SL_IOSTREAM_USART_VCOM_RTS_PORT) + .usart_rts_location = SL_IOSTREAM_USART_VCOM_RTS_LOC, +#endif +#else + .usart_location = SL_IOSTREAM_USART_VCOM_ROUTE_LOC, +#endif + }; + + sl_iostream_dma_config_t dma_config_vcom = { + .src = (uint8_t *)&SL_IOSTREAM_USART_VCOM_PERIPHERAL->RXDATA, + .peripheral_signal = SL_IOSTREAM_USART_RX_DMA_SIGNAL(SL_IOSTREAM_USART_VCOM_PERIPHERAL_NO)}; + + sl_iostream_uart_config_t uart_config_vcom = { + .dma_cfg = dma_config_vcom, + .rx_buffer = rx_buffer_vcom, + .rx_buffer_length = SL_IOSTREAM_USART_VCOM_RX_BUFFER_SIZE, + .tx_irq_number = SL_IOSTREAM_USART_TX_IRQ_NUMBER(SL_IOSTREAM_USART_VCOM_PERIPHERAL_NO), + .rx_irq_number = SL_IOSTREAM_USART_RX_IRQ_NUMBER(SL_IOSTREAM_USART_VCOM_PERIPHERAL_NO), + .lf_to_crlf = SL_IOSTREAM_USART_VCOM_CONVERT_BY_DEFAULT_LF_TO_CRLF, + .rx_when_sleeping = SL_IOSTREAM_USART_VCOM_RESTRICT_ENERGY_MODE_TO_ALLOW_RECEPTION, + }; + uart_config_vcom.sw_flow_control = SL_IOSTREAM_USART_VCOM_FLOW_CONTROL_TYPE == uartFlowControlSoftware; + // Instantiate usart instance + status = sl_iostream_usart_init(&sl_iostream_vcom, &uart_config_vcom, &init_vcom, &config_vcom, &context_vcom); + EFM_ASSERT(status == SL_STATUS_OK); + + return status; +} + +#endif // HAL_WP_USE_SERIAL + +#if HAL_USE_ONEWIRE == TRUE + +sl_status_t sl_iostream_usart_init_onewire(void); +static sl_iostream_uart_t sl_iostream_onewire; +sl_iostream_t *sl_iostream_onewire_handle = &sl_iostream_onewire.stream; +sl_iostream_uart_t *sl_iostream_uart_onewire_handle = &sl_iostream_onewire; +static sl_iostream_usart_context_t context_onewire; +static uint8_t rx_buffer_onewire[SL_IOSTREAM_USART_ONEWIRE_RX_BUFFER_SIZE]; +sl_iostream_instance_info_t sl_iostream_instance_onewire_info = { + .handle = &sl_iostream_onewire.stream, + .name = "ONEWIRE", + .type = SL_IOSTREAM_TYPE_UART, + .periph_id = SL_IOSTREAM_USART_ONEWIRE_PERIPHERAL_NO, + .init = sl_iostream_usart_init_onewire, +}; + +sl_status_t sl_iostream_usart_init_onewire(void) +{ + sl_status_t status; + USART_InitAsync_TypeDef init_onewire = USART_INITASYNC_DEFAULT; + init_onewire.baudrate = SL_IOSTREAM_USART_ONEWIRE_BAUDRATE; + init_onewire.parity = SL_IOSTREAM_USART_ONEWIRE_PARITY; + init_onewire.stopbits = SL_IOSTREAM_USART_ONEWIRE_STOP_BITS; +#if (_SILICON_LABS_32B_SERIES > 0) + init_onewire.hwFlowControl = SL_IOSTREAM_USART_ONEWIRE_FLOW_CONTROL_TYPE != uartFlowControlSoftware + ? SL_IOSTREAM_USART_ONEWIRE_FLOW_CONTROL_TYPE + : usartHwFlowControlNone; +#endif + sl_iostream_usart_config_t config_onewire = { + .usart = SL_IOSTREAM_USART_ONEWIRE_PERIPHERAL, + .clock = SL_IOSTREAM_USART_CLOCK_REF(SL_IOSTREAM_USART_ONEWIRE_PERIPHERAL_NO), + .tx_port = SL_IOSTREAM_USART_ONEWIRE_TX_PORT, + .tx_pin = SL_IOSTREAM_USART_ONEWIRE_TX_PIN, + .rx_port = SL_IOSTREAM_USART_ONEWIRE_RX_PORT, + .rx_pin = SL_IOSTREAM_USART_ONEWIRE_RX_PIN, +#if (_SILICON_LABS_32B_SERIES > 0) +#if defined(SL_IOSTREAM_USART_ONEWIRE_CTS_PORT) + .cts_port = SL_IOSTREAM_USART_ONEWIRE_CTS_PORT, + .cts_pin = SL_IOSTREAM_USART_ONEWIRE_CTS_PIN, +#endif +#if defined(SL_IOSTREAM_USART_ONEWIRE_RTS_PORT) + .rts_port = SL_IOSTREAM_USART_ONEWIRE_RTS_PORT, + .rts_pin = SL_IOSTREAM_USART_ONEWIRE_RTS_PIN, +#endif +#endif +#if defined(GPIO_USART_ROUTEEN_TXPEN) + .usart_index = SL_IOSTREAM_USART_ONEWIRE_PERIPHERAL_NO, +#elif defined(USART_ROUTEPEN_RXPEN) + .usart_tx_location = SL_IOSTREAM_USART_ONEWIRE_TX_LOC, + .usart_rx_location = SL_IOSTREAM_USART_ONEWIRE_RX_LOC, +#if defined(SL_IOSTREAM_USART_ONEWIRE_CTS_PORT) + .usart_cts_location = SL_IOSTREAM_USART_ONEWIRE_CTS_LOC, +#endif +#if defined(SL_IOSTREAM_USART_ONEWIRE_RTS_PORT) + .usart_rts_location = SL_IOSTREAM_USART_ONEWIRE_RTS_LOC, +#endif +#else + .usart_location = SL_IOSTREAM_USART_ONEWIRE_ROUTE_LOC, +#endif + }; + + sl_iostream_dma_config_t dma_config_onewire = { + .src = (uint8_t *)&SL_IOSTREAM_USART_ONEWIRE_PERIPHERAL->RXDATA, + .peripheral_signal = SL_IOSTREAM_USART_RX_DMA_SIGNAL(SL_IOSTREAM_USART_ONEWIRE_PERIPHERAL_NO)}; + + sl_iostream_uart_config_t uart_config_onewire = { + .dma_cfg = dma_config_onewire, + .rx_buffer = rx_buffer_onewire, + .rx_buffer_length = SL_IOSTREAM_USART_ONEWIRE_RX_BUFFER_SIZE, + .tx_irq_number = SL_IOSTREAM_USART_TX_IRQ_NUMBER(SL_IOSTREAM_USART_ONEWIRE_PERIPHERAL_NO), + .rx_irq_number = SL_IOSTREAM_USART_RX_IRQ_NUMBER(SL_IOSTREAM_USART_ONEWIRE_PERIPHERAL_NO), + .lf_to_crlf = SL_IOSTREAM_USART_ONEWIRE_CONVERT_BY_DEFAULT_LF_TO_CRLF, + .rx_when_sleeping = SL_IOSTREAM_USART_ONEWIRE_RESTRICT_ENERGY_MODE_TO_ALLOW_RECEPTION, + }; + uart_config_onewire.sw_flow_control = SL_IOSTREAM_USART_ONEWIRE_FLOW_CONTROL_TYPE == uartFlowControlSoftware; + // Instantiate usart instance + status = sl_iostream_usart_init( + &sl_iostream_onewire, + &uart_config_onewire, + &init_onewire, + &config_onewire, + &context_onewire); + EFM_ASSERT(status == SL_STATUS_OK); + + return status; +} + +#endif // HAL_USE_ONEWIRE + +void sl_iostream_usart_init_instances(void) +{ +#if defined(SL_CATALOG_POWER_MANAGER_PRESENT) && defined(_SILICON_LABS_32B_SERIES_2) + // Enable power manager notifications + sl_power_manager_subscribe_em_transition_event(&events_handle, &events_info); +#endif + +// Instantiate usart instance(s) +#if HAL_WP_USE_SERIAL == TRUE + sl_status_t status = sl_iostream_usart_init_vcom(); + EFM_ASSERT(status == SL_STATUS_OK); +#endif +} + +#if HAL_WP_USE_SERIAL == TRUE + +// VCOM IRQ Handler +void SL_IOSTREAM_USART_TX_IRQ_HANDLER(SL_IOSTREAM_USART_VCOM_PERIPHERAL_NO)(void) +{ + sl_iostream_usart_irq_handler(&sl_iostream_vcom); +} + +void SL_IOSTREAM_USART_RX_IRQ_HANDLER(SL_IOSTREAM_USART_VCOM_PERIPHERAL_NO)(void) +{ + sl_iostream_usart_irq_handler(&sl_iostream_vcom); +} + +#endif // HAL_WP_USE_SERIAL + +#if HAL_USE_ONEWIRE == TRUE + +// ONEWIRE IRQ Handler +void SL_IOSTREAM_USART_TX_IRQ_HANDLER(SL_IOSTREAM_USART_ONEWIRE_PERIPHERAL_NO)(void) +{ + sl_iostream_usart_irq_handler(&sl_iostream_onewire); +} + +void SL_IOSTREAM_USART_RX_IRQ_HANDLER(SL_IOSTREAM_USART_ONEWIRE_PERIPHERAL_NO)(void) +{ + sl_iostream_usart_irq_handler(&sl_iostream_onewire); +} + +#endif // HAL_USE_ONEWIRE + +#if defined(SL_CATALOG_POWER_MANAGER_PRESENT) +#if !defined(SL_CATALOG_KERNEL_PRESENT) + +sl_power_manager_on_isr_exit_t sl_iostream_usart_vcom_sleep_on_isr_exit(void) +{ + return sl_iostream_uart_sleep_on_isr_exit(&sl_iostream_vcom); +} + +#endif + +static void events_handler(sl_power_manager_em_t from, sl_power_manager_em_t to) +{ + (void)from; +#if defined(_SILICON_LABS_32B_SERIES_2) + uint32_t out; + if (((from == SL_POWER_MANAGER_EM2) || (from == SL_POWER_MANAGER_EM3)) && + ((to == SL_POWER_MANAGER_EM1) || (to == SL_POWER_MANAGER_EM0))) + { + + // Wake the USART Tx pin back up + out = GPIO_PinOutGet(SL_IOSTREAM_USART_ONEWIRE_TX_PORT, SL_IOSTREAM_USART_ONEWIRE_TX_PIN); + GPIO_PinModeSet(SL_IOSTREAM_USART_ONEWIRE_TX_PORT, SL_IOSTREAM_USART_ONEWIRE_TX_PIN, gpioModePushPull, out); + + // Wake the USART Tx pin back up + out = GPIO_PinOutGet(SL_IOSTREAM_USART_VCOM_TX_PORT, SL_IOSTREAM_USART_VCOM_TX_PIN); + GPIO_PinModeSet(SL_IOSTREAM_USART_VCOM_TX_PORT, SL_IOSTREAM_USART_VCOM_TX_PIN, gpioModePushPull, out); + } + else if ( + ((to == SL_POWER_MANAGER_EM2) || (to == SL_POWER_MANAGER_EM3)) && + ((from == SL_POWER_MANAGER_EM1) || (from == SL_POWER_MANAGER_EM0))) + { + + // Sleep the USART Tx pin on series 2 devices to save energy + out = GPIO_PinOutGet(SL_IOSTREAM_USART_ONEWIRE_TX_PORT, SL_IOSTREAM_USART_ONEWIRE_TX_PIN); + GPIO_PinModeSet(SL_IOSTREAM_USART_ONEWIRE_TX_PORT, SL_IOSTREAM_USART_ONEWIRE_TX_PIN, gpioModeDisabled, out); + + // Sleep the USART Tx pin on series 2 devices to save energy + out = GPIO_PinOutGet(SL_IOSTREAM_USART_VCOM_TX_PORT, SL_IOSTREAM_USART_VCOM_TX_PIN); + GPIO_PinModeSet(SL_IOSTREAM_USART_VCOM_TX_PORT, SL_IOSTREAM_USART_VCOM_TX_PIN, gpioModeDisabled, out); + } +#endif // _SILICON_LABS_32B_SERIES_2 + // Enable next byte detect to wake from sleep + if (to < SL_POWER_MANAGER_EM2) + { + + // Enable next byte detection to wakeup from sleep on next byte + context_onewire.context.set_next_byte_detect(sl_iostream_onewire_handle->context, true); + + // Enable next byte detection to wakeup from sleep on next byte + context_vcom.context.set_next_byte_detect(sl_iostream_vcom_handle->context, true); + } +} +#endif // SL_CATALOG_POWER_MANAGER_PRESENT + +// implementation required (even if empty) to keep debugger happy +void sli_iostream_on_uart_rx(sl_iostream_t *handle) +{ + (void)handle; +} + +void sli_iostream_change_baudrate(sl_iostream_t *handle, uint32_t baudrate) +{ + sl_iostream_usart_context_t *usart_context = (sl_iostream_usart_context_t *)handle->context; + + USART_BaudrateAsyncSet(usart_context->usart, 0, baudrate, 0); +} diff --git a/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_iostream_init_usart_instances.h b/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_iostream_init_usart_instances.h new file mode 100644 index 0000000000..626aea1fde --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_iostream_init_usart_instances.h @@ -0,0 +1,49 @@ +#ifndef SL_IOSTREAM_INIT_USART_INSTANCES_H +#define SL_IOSTREAM_INIT_USART_INSTANCES_H +#if defined(SL_COMPONENT_CATALOG_PRESENT) +#include "sl_component_catalog.h" +#endif +#if defined(SL_CATALOG_POWER_MANAGER_PRESENT) +#include "sl_power_manager.h" +#endif +#include "sl_iostream.h" +#include "sl_iostream_uart.h" +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +#if HAL_WP_USE_SERIAL == TRUE + extern sl_iostream_t *sl_iostream_vcom_handle; + extern sl_iostream_uart_t *sl_iostream_uart_vcom_handle; + extern sl_iostream_instance_info_t sl_iostream_instance_vcom_info; +#endif +#if HAL_USE_ONEWIRE == TRUE + extern sl_iostream_t *sl_iostream_onewire_handle; + extern sl_iostream_uart_t *sl_iostream_uart_onewire_handle; + extern sl_iostream_instance_info_t sl_iostream_instance_onewire_info; +#endif + + // Initialize only iostream usart instance(s) + void sl_iostream_usart_init_instances(void); + +#if defined(SL_CATALOG_POWER_MANAGER_PRESENT) + +#if HAL_WP_USE_SERIAL == TRUE + sl_power_manager_on_isr_exit_t sl_iostream_usart_vcom_sleep_on_isr_exit(void); + bool sl_iostream_usart_vcom_is_ok_to_sleep(void); +#endif +#if HAL_USE_ONEWIRE == TRUE + sl_power_manager_on_isr_exit_t sl_iostream_usart_onewire_sleep_on_isr_exit(void); + bool sl_iostream_usart_onewire_is_ok_to_sleep(void); +#endif + +#endif + +#ifdef __cplusplus +} +#endif + +#endif // SL_IOSTREAM_INIT_USART_INSTANCES_H diff --git a/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_usbd_class_vendor_instances.c b/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_usbd_class_vendor_instances.c new file mode 100644 index 0000000000..8f7215bd57 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_usbd_class_vendor_instances.c @@ -0,0 +1,301 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Portions Copyright 2018 Silicon Laboratories Inc. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +//**************************************************************************** +// Includes. + +#include +#include +#include +#include +#include +#include + +// template headers +#include +#include +#include + +// include config file for the instances + +#include + +// need to declare this here as extern +extern void PostManagedEvent(uint8_t category, uint8_t subCategory, uint16_t data1, uint32_t data2); +extern sl_status_t sl_usbd_vendor_update_device_product_string(const char *product_string); + +// storage for USB class vendor description +char UsbClassVendorDescription[GECKO_DEVICE_CLASS_VENDOR_DESCRIPTION_PROPERTY_LEN + 1]; +char UsbClassVendorDeviceInterfaceGuid[DEVICE_CLASS_GUID_PROPERTY_LEN]; + +// flag for USB WinUSB intialized +static bool usbdVendorWinusbInited = false; + +//**************************************************************************** +// Function declarations. + +/* callback prototypes for winusb instance */ + +void sli_usbd_vendor_winusb_enable(uint8_t class_nbr); + +void sli_usbd_vendor_winusb_disable(uint8_t class_nbr); + +void sli_usbd_vendor_winusb_setup_req(uint8_t class_nbr, const sl_usbd_setup_req_t *p_setup_req); + +//**************************************************************************** +// Global variables. + +/* variables for winusb instance */ + +uint8_t sl_usbd_vendor_winusb_number = 0; + +sl_usbd_vendor_callbacks_t sli_usbd_vendor_winusb_callbacks = { + sli_usbd_vendor_winusb_enable, + sli_usbd_vendor_winusb_disable, + sli_usbd_vendor_winusb_setup_req, +}; + +//**************************************************************************** +// Callback functions. + +void sli_usbd_vendor_winusb_enable(uint8_t class_nbr) +{ + (void)&class_nbr; + + sl_usbd_vendor_winusb_on_enable_event(); + + return; +} + +void sli_usbd_vendor_winusb_disable(uint8_t class_nbr) +{ + (void)&class_nbr; + + sl_usbd_vendor_winusb_on_disable_event(); + + return; +} + +void sli_usbd_vendor_winusb_setup_req(uint8_t class_nbr, const sl_usbd_setup_req_t *p_setup_req) +{ + (void)&class_nbr; + + sl_usbd_vendor_winusb_on_setup_request_event(p_setup_req); + + return; +} + +//**************************************************************************** +// Global functions. + +/* initialize winusb instance */ +sl_status_t sli_usbd_vendor_winusb_init() +{ + bool intr_en = true; + uint16_t interval = 0; + + uint8_t class_number = 0; + uint8_t config_number = 0; + sl_usbd_device_state_t deviceState; + bool needToReinit = false; + sl_status_t returnStatus = SL_STATUS_OK; + + char *configs = NULL; + char *token = NULL; + + // check if already initialized + if (usbdVendorWinusbInited) + { + return SL_STATUS_OK; + } + + // get current device state + sl_usbd_core_get_device_state(&deviceState); + + if (deviceState > SL_USBD_DEVICE_STATE_INIT) + { + // device is already initialized, stop USB core, **ONLY** if there isn't a debugger connected + if (!DebuggerIsConnected()) + { + sl_usbd_core_stop_device(); + + // flag to reinit + needToReinit = true; + } + } + + /* configs to attach the class instance to */ + configs = SL_USBD_VENDOR_WINUSB_CONFIGURATIONS; + + /* read interrupt enable flag */ + intr_en = SL_USBD_VENDOR_WINUSB_INTERRUPT_ENDPOINTS; + + /* read interval */ + interval = SL_USBD_VENDOR_WINUSB_INTERVAL; + + /* create vendor instance */ + if (sl_usbd_vendor_create_instance(intr_en, interval, &sli_usbd_vendor_winusb_callbacks, &class_number) != + SL_STATUS_OK) + { + // error creating instance + returnStatus = SL_STATUS_FAIL; + + // done here + goto exit; + } + + /* store class number globally */ + sl_usbd_vendor_winusb_number = class_number; + + // even if not initialized, check if it's active + bool classIsEnabled; + + if (sl_usbd_vendor_is_enabled(class_number, &classIsEnabled) != SL_STATUS_OK) + { + // error getting class enabled status + returnStatus = SL_STATUS_FAIL; + + // done here + goto exit; + } + + if (classIsEnabled) + { + // already active, disable it to add new configuration + // sl_usbd_vendor_disable + // usbd_vendor_disable(sl_usbd_configuration_config0_number, void *p_if_class_arg) + } + + // tokenize configs by "," and spaces + token = strtok(configs, ", "); + + // loop over tokens + while (token != NULL) + { + + /* add to config0? */ + if (!strcmp(token, "config0") || !strcmp(token, "all")) + { + config_number = sl_usbd_configuration_config0_number; + if (sl_usbd_vendor_add_to_configuration(class_number, config_number) != SL_STATUS_OK) + { + // error adding class to configuration + returnStatus = SL_STATUS_FAIL; + + // done here + goto exit; + } + } + + /* next token */ + token = strtok(NULL, ", "); + } + +#if HAL_WP_USE_USB_CDC == FALSE + // no USB CDC so this won't be a composite device + // need to set the description here from USB Class vendor description + sl_usbd_vendor_update_device_product_string((const char *)UsbClassVendorDescription); + + // also need to adjust the class number for the Microsoft extend property + class_number--; +#endif + + // add device class GUID to WinUSB properties + if (sl_usbd_vendor_add_microsoft_ext_property( + class_number, + SL_USBD_MICROSOFT_PROPERTY_TYPE_REG_SZ, + (const uint8_t *)DEVICEINTERFACE_GUID_PROP_NAME, + DEVICEINTERFACE_GUID_PROP_NAME_LEN, + (const uint8_t *)UsbClassVendorDeviceInterfaceGuid, + sizeof(UsbClassVendorDeviceInterfaceGuid)) != SL_STATUS_OK) + { + // error adding GUID property + returnStatus = SL_STATUS_FAIL; + + // done here + goto exit; + } + else + { + // all good here, update flag + usbdVendorWinusbInited = true; + } + +exit: + + // reinit USB core if needed + if (needToReinit) + { + sl_usbd_core_start_device(); + } + + return returnStatus; +} + +void sl_usbd_vendor_winusb_on_enable_event(void) +{ +} + +void sl_usbd_vendor_winusb_on_disable_event(void) +{ +} + +void sl_usbd_vendor_winusb_on_setup_request_event(const sl_usbd_setup_req_t *p_setup_req) +{ + (void)p_setup_req; +} + +// USB bus events. +void sl_usbd_on_bus_event(sl_usbd_bus_event_t event) +{ + switch (event) + { + case SL_USBD_EVENT_BUS_CONNECT: + // called when usb cable is inserted in a host controller + PostManagedEvent(EVENT_USB, 0, UsbEventType_DeviceConnected, 0); + break; + + case SL_USBD_EVENT_BUS_DISCONNECT: + // called when usb cable is removed from a host controller + PostManagedEvent(EVENT_USB, 0, UsbEventType_DeviceDisconnected, 0); + break; + + case SL_USBD_EVENT_BUS_RESET: + // called when the host sends reset command + break; + + case SL_USBD_EVENT_BUS_SUSPEND: + // called when the host sends suspend command + break; + + case SL_USBD_EVENT_BUS_RESUME: + // called when the host sends wake up command + break; + + default: + break; + } +} + +// USB configuration events. +void sl_usbd_on_config_event(sl_usbd_config_event_t event, uint8_t config_nbr) +{ + (void)config_nbr; + + switch (event) + { + case SL_USBD_EVENT_CONFIG_SET: + // called when the host sets a configuration after reset + break; + + case SL_USBD_EVENT_CONFIG_UNSET: + // called when a configuration is unset due to reset command + break; + + default: + break; + } +} diff --git a/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_usbd_class_vendor_instances.h b/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_usbd_class_vendor_instances.h new file mode 100644 index 0000000000..0e763ef420 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_usbd_class_vendor_instances.h @@ -0,0 +1,51 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Portions Copyright 2018 Silicon Laboratories Inc. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +#ifndef SL_USBD_CLASS_VENDOR_INSTANCES_INIT +#define SL_USBD_CLASS_VENDOR_INSTANCES_INIT + +#include + +typedef enum __nfpack UsbEventType +{ + UsbEventType_Invalid = 0, + UsbEventType_DeviceConnected = 1, + UsbEventType_DeviceDisconnected = 2, +} UsbEventType; + +#define DEVICEINTERFACE_GUID_PROP_NAME L"DeviceInterfaceGUID" + +/// Length of GUID Property Name +#define DEVICEINTERFACE_GUID_PROP_NAME_LEN sizeof (DEVICEINTERFACE_GUID_PROP_NAME) + +// GUID for device class that will be reported to WinUSB (going into DeviceInterfaceGUID extended property) +#define DEVICE_CLASS_GUID_PROPERTY L"{00000000-0000-0000-0000-000000000000}" +#define DEVICE_CLASS_GUID_PROPERTY_LEN sizeof(DEVICE_CLASS_GUID_PROPERTY) + +/* class numbers assigned by the USB stack after init */ + +extern uint8_t sl_usbd_vendor_winusb_number; +extern char UsbClassVendorDeviceInterfaceGuid[DEVICE_CLASS_GUID_PROPERTY_LEN]; + +/* event handlers for all vendor instances */ + +__WEAK void sl_usbd_vendor_winusb_on_enable_event(void); +__WEAK void sl_usbd_vendor_winusb_on_disable_event(void); +__WEAK void sl_usbd_vendor_winusb_on_setup_request_event(const sl_usbd_setup_req_t *p_setup_req); + +/* init functions for all vendor instances */ + +#ifdef __cplusplus +extern "C" { +#endif + +sl_status_t sli_usbd_vendor_winusb_init(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_usbd_init.c b/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_usbd_init.c new file mode 100644 index 0000000000..1968eabb67 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_usbd_init.c @@ -0,0 +1,78 @@ +//**************************************************************************** +// Includes. + +#include + +#include "sl_status.h" +#include + +#if GECKO_FEATURE_USBD_HID == TRUE +#include "sl_usbd_class_hid.h" +#endif + +#if GECKO_FEATURE_USBD_WINUSB == TRUE +#include "sl_usbd_class_vendor.h" +#endif + +#if HAL_WP_USE_USB_CDC == TRUE +#include "sl_usbd_class_cdc.h" +#include "sl_usbd_class_cdc_acm.h" +#endif + +// need to fit 64bits as hex string +// Can be referenced from sl_usbd_device_config.h in the define SL_USBD_DEVICE_SERIAL_NUMBER_STRING +#define USB_SERIAL_NUMBER_LENGTH (8 * 2 + 1) +char UsbSerialNumber[USB_SERIAL_NUMBER_LENGTH]; + +//**************************************************************************** +// Global functions. + +// this function composes a string with the device Unique ID +void ComposeDeviceUID() +{ + // device Unique ID is 64 bits long + uint8_t deviceUID[8]; + + deviceUID[0] = DEVINFO->UNIQUEH >> 24; + deviceUID[1] = DEVINFO->UNIQUEH >> 16; + deviceUID[2] = DEVINFO->UNIQUEH >> 8; + deviceUID[3] = DEVINFO->UNIQUEH; + deviceUID[4] = DEVINFO->UNIQUEL >> 24; + deviceUID[5] = DEVINFO->UNIQUEL >> 16; + deviceUID[6] = DEVINFO->UNIQUEL >> 8; + deviceUID[7] = DEVINFO->UNIQUEL; + + snprintf( + UsbSerialNumber, + sizeof(UsbSerialNumber), + "%02X%02X%02X%02X%02X%02X%02X%02X", + deviceUID[0], + deviceUID[1], + deviceUID[2], + deviceUID[3], + deviceUID[4], + deviceUID[5], + deviceUID[6], + deviceUID[7]); +} + +/* USB initialization function */ +void sli_usbd_init(void) +{ + ComposeDeviceUID(); + + sl_usbd_core_init(); + +#if GECKO_FEATURE_USBD_HID == TRUE + sl_usbd_hid_init(); +#endif + +#if HAL_WP_USE_USB_CDC == TRUE + sl_usbd_cdc_init(); + sl_usbd_cdc_acm_init(); +#endif + +#if GECKO_FEATURE_USBD_WINUSB == TRUE + sl_usbd_vendor_init(); +#endif +} diff --git a/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_usbd_init.h b/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_usbd_init.h new file mode 100644 index 0000000000..b6fe5dc21c --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_common/autogen/sl_usbd_init.h @@ -0,0 +1,7 @@ +#ifndef SL_USBD_INIT +#define SL_USBD_INIT + +/* USB initialization function */ +void sli_usbd_init(void); + +#endif diff --git a/targets/AzureRTOS/SiliconLabs/_common/config/dmadrv_config.h b/targets/AzureRTOS/SiliconLabs/_common/config/dmadrv_config.h new file mode 100644 index 0000000000..fd584e666d --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_common/config/dmadrv_config.h @@ -0,0 +1,26 @@ +#ifndef DMADRV_CONFIG_H +#define DMADRV_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +// DMA interrupt priority <0-7> +// Priority of the DMA interrupt. Smaller number equals higher priority. +// Default: 4 +#define EMDRV_DMADRV_DMA_IRQ_PRIORITY 4 + +// Number of available channels <1-24> +// Number of DMA channels supported by the driver. A lower channel count +// will reduce RAM memory footprint. The default is to support all channels +// on the device. +// Default: 24 +#define EMDRV_DMADRV_DMA_CH_COUNT 24 + +// Number of fixed priority channels +// This will configure channels [0, CH_PRIORITY - 1] as fixed priority, +// and channels [CH_PRIORITY, CH_COUNT] as round-robin. +// Default: 0 +#define EMDRV_DMADRV_DMA_CH_PRIORITY 0 + +// <<< end of configuration section >>> + +#endif // DMADRV_CONFIG_H diff --git a/targets/AzureRTOS/SiliconLabs/_common/config/emlib_core_debug_config.h b/targets/AzureRTOS/SiliconLabs/_common/config/emlib_core_debug_config.h new file mode 100644 index 0000000000..50dbbed9bc --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_common/config/emlib_core_debug_config.h @@ -0,0 +1,46 @@ +/***************************************************************************//** + * @file + * @brief emlib_core Configuration + ******************************************************************************* + * # License + * Copyright 2019 Silicon Laboratories Inc. www.silabs.com + ******************************************************************************* + * + * SPDX-License-Identifier: Zlib + * + * The licensor of this software is Silicon Laboratories Inc. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + ******************************************************************************/ + +#ifndef EM_CORE_DEBUG_CONFIG_H +#define EM_CORE_DEBUG_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +// Core Configuration + +// Enables measuring of interrupt disable time for debugging purposes. +// Default: 0 +// If Enabled, either cycle_counter or systemview component must be added to project. +#define SL_EMLIB_CORE_ENABLE_INTERRUPT_DISABLED_TIMING 0 + +// + +// <<< end of configuration section >>> +#endif // EM_CORE_CONFIG_H diff --git a/targets/AzureRTOS/SiliconLabs/_common/config/sl_device_init_dcdc_config.h b/targets/AzureRTOS/SiliconLabs/_common/config/sl_device_init_dcdc_config.h new file mode 100644 index 0000000000..615e91cf20 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_common/config/sl_device_init_dcdc_config.h @@ -0,0 +1,28 @@ +#ifndef SL_DEVICE_INIT_DCDC_CONFIG_H +#define SL_DEVICE_INIT_DCDC_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +// Enable DC/DC Converter +// +// Default: 1 +#define SL_DEVICE_INIT_DCDC_ENABLE 1 + +// Set DC/DC Converter in Bypass Mode +// +// Default: 0 +#define SL_DEVICE_INIT_DCDC_BYPASS 0 + +// Override for DCDC PFMX Mode Peak Current Setting +// +// Default: 0 +#define SL_DEVICE_INIT_DCDC_PFMX_IPKVAL_OVERRIDE 0 + +// DCDC PFMX Mode Peak Current Setting <0-15> +// +// Default: DCDC_PFMXCTRL_IPKVAL_DEFAULT +#define SL_DEVICE_INIT_DCDC_PFMX_IPKVAL DCDC_PFMXCTRL_IPKVAL_DEFAULT + +// <<< end of configuration section >>> + +#endif // SL_DEVICE_INIT_DCDC_CONFIG_H diff --git a/targets/AzureRTOS/SiliconLabs/_common/config/sl_device_init_emu_config.h b/targets/AzureRTOS/SiliconLabs/_common/config/sl_device_init_emu_config.h new file mode 100644 index 0000000000..387abf94f4 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_common/config/sl_device_init_emu_config.h @@ -0,0 +1,68 @@ +/***************************************************************************//** + * @file + * @brief DEVICE_INIT_EMU Config + ******************************************************************************* + * # License + * Copyright 2019 Silicon Laboratories Inc. www.silabs.com + ******************************************************************************* + * + * SPDX-License-Identifier: Zlib + * + * The licensor of this software is Silicon Laboratories Inc. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + ******************************************************************************/ + +#ifndef SL_DEVICE_INIT_EMU_CONFIG_H +#define SL_DEVICE_INIT_EMU_CONFIG_H + +#include "em_emu.h" + +// <<< Use Configuration Wizard in Context Menu >>> + +// EM4H Voltage scaling level +// Fast-wakeup voltage level +// Low-power optimized voltage level +// Default: emuVScaleEM4H_LowPower +#define SL_DEVICE_INIT_EMU_EM4_VSCALE emuVScaleEM4H_LowPower + +// Retain LFXO in EM4 +#define SL_DEVICE_INIT_EMU_EM4_RETAIN_LFXO 0 + +// Retain LFRCO in EM4 +#define SL_DEVICE_INIT_EMU_EM4_RETAIN_LFRCO 0 + +// Retain ULFRCO in EM4S +#define SL_DEVICE_INIT_EMU_EM4_RETAIN_ULFRCO 0 + +// Hibernate or shutoff EM4 state +// EM4 Shutoff +// EM4 Hibernate +// Default: emuEM4Shutoff +#define SL_DEVICE_INIT_EMU_EM4_STATE emuEM4Shutoff + +// EM4 pin retention mode +// No Retention: Pads enter reset state when entering EM4. +// Retention through EM4: Pads enter reset state when exiting EM4. +// Retention through EM4 and wakeup. +// Default: emuPinRetentionDisable +#define SL_DEVICE_INIT_EMU_EM4_PIN_RETENTION_MODE emuPinRetentionDisable + +// <<< end of configuration section >>> + +#endif // SL_DEVICE_INIT_EMU_CONFIG_H diff --git a/targets/AzureRTOS/SiliconLabs/_common/config/sl_device_init_hfrco_config.h b/targets/AzureRTOS/SiliconLabs/_common/config/sl_device_init_hfrco_config.h new file mode 100644 index 0000000000..8ec8d17100 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_common/config/sl_device_init_hfrco_config.h @@ -0,0 +1,27 @@ +#ifndef SL_DEVICE_INIT_HFRCO_CONFIG_H +#define SL_DEVICE_INIT_HFRCO_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +// Frequency Band +// RC Oscillator Frequency Band +// 1 MHz +// 2 MHz +// 4 MHz +// 7 MHz +// 13 MHz +// 16 MHz +// 19 MHz +// 26 MHz +// 32 MHz +// 38 MHz +// 48 MHz +// 56 MHz +// 64 MHz +// 72 MHz +// Default: cmuHFRCOFreq_72M0Hz +#define SL_DEVICE_INIT_HFRCO_BAND cmuHFRCOFreq_48M0Hz + +// <<< end of configuration section >>> + +#endif // SL_DEVICE_INIT_HFRCO_CONFIG_H diff --git a/targets/AzureRTOS/SiliconLabs/_common/config/sl_device_init_hfxo_config.h b/targets/AzureRTOS/SiliconLabs/_common/config/sl_device_init_hfxo_config.h new file mode 100644 index 0000000000..33f46cf543 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_common/config/sl_device_init_hfxo_config.h @@ -0,0 +1,41 @@ +#ifndef SL_DEVICE_INIT_HFXO_CONFIG_H +#define SL_DEVICE_INIT_HFXO_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +// Mode +// +// Crystal oscillator +// AC-coupled buffer +// External digital clock +// Default: cmuOscMode_Crystal +#define SL_DEVICE_INIT_HFXO_MODE cmuOscMode_Crystal + +// Frequency <4000000-48000000> +// Default: 50000000 +#define SL_DEVICE_INIT_HFXO_FREQ 50000000 + +// HFXO precision in PPM <0-65535> +// Default: 500 +#define SL_DEVICE_INIT_HFXO_PRECISION 500 + +// CTUNE <0-511> +// Default: 360 +#define SL_DEVICE_INIT_HFXO_CTUNE 132 + +// Advanced Configurations +// Auto-start HFXO. This feature is incompatible with Power Manager and can only be +// enabled in applications that do not use Power Manager or a radio protocol stack. - DEPRECATED True +// False Default: false +#define SL_DEVICE_INIT_HFXO_AUTOSTART false + +// Auto-select HFXO. This feature is incompatible with Power Manager and can only be +// enabled in applications that do not use Power Manager or a radio protocol stack. - DEPRECATED True +// False Default: false +#define SL_DEVICE_INIT_HFXO_AUTOSELECT false + +// + +// <<< end of configuration section >>> + +#endif // SL_DEVICE_INIT_HFXO_CONFIG_H diff --git a/targets/AzureRTOS/SiliconLabs/_common/config/sl_device_init_lfrco_config.h b/targets/AzureRTOS/SiliconLabs/_common/config/sl_device_init_lfrco_config.h new file mode 100644 index 0000000000..79b1541af8 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_common/config/sl_device_init_lfrco_config.h @@ -0,0 +1,34 @@ +#ifndef SL_DEVICE_INIT_LFRCO_CONFIG_H +#define SL_DEVICE_INIT_LFRCO_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +// Enable Duty Cycling of Vref +// Default: 0 +// Setting this configuration to 1 puts the LFRCO in duty cycle mode by +// setting the ENVREF bit in CMU_LFRCOCTRL to 1 before starting the LFRCO. +// This helps reduce current consumption by ~100nA in EM2, but will result +// in slightly worse accuracy especially at high temperatures. +// To improve the average LFRCO frequency accuracy, make sure ENCHOP +// and ENDEM configs are also set. +#define SL_DEVICE_INIT_LFRCO_ENVREF 0 + +// Enable Comparator Chopping +// Default: 1 +// Setting this configuration to 1 enables LFRCO comparator chopping by +// setting the ENCHOP bit in CMU_LFRCOCTRL to 1 before starting the LFRCO. +// Setting this bit, along with ENDEM, helps improve the average LFRCO +// frequency accuracy. +#define SL_DEVICE_INIT_LFRCO_ENCHOP 1 + +// Enable Dynamic Element Matching +// Default: 1 +// Setting this configuration to 1 enables dynamic element matching by +// setting the ENDEM bit in CMU_LFRCOCTRL to 1 before starting the LFRCO. +// Setting this bit, along with ENCHOP, helps improve the average LFRCO +// frequency accuracy. +#define SL_DEVICE_INIT_LFRCO_ENDEM 1 + +// <<< end of configuration section >>> + +#endif // SL_DEVICE_INIT_LFRCO_CONFIG_H diff --git a/targets/AzureRTOS/SiliconLabs/_common/config/sl_device_init_lfxo_config.h b/targets/AzureRTOS/SiliconLabs/_common/config/sl_device_init_lfxo_config.h new file mode 100644 index 0000000000..46c38725c1 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_common/config/sl_device_init_lfxo_config.h @@ -0,0 +1,37 @@ +#ifndef SL_DEVICE_INIT_LFXO_CONFIG_H +#define SL_DEVICE_INIT_LFXO_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu >>> + +// Mode +// +// Crystal oscillator +// AC-coupled buffer +// External digital clock +// Default: cmuOscMode_Crystal +#define SL_DEVICE_INIT_LFXO_MODE cmuOscMode_Crystal + +// CTUNE <0-127> +// Default: 63 +#define SL_DEVICE_INIT_LFXO_CTUNE 70 + +// LFXO precision in PPM <0-65535> +// Default: 500 +#define SL_DEVICE_INIT_LFXO_PRECISION 100 + +// Startup Timeout Delay +// +// <_CMU_LFXOCTRL_TIMEOUT_2CYCLES=> 2 cycles +// <_CMU_LFXOCTRL_TIMEOUT_256CYCLES=> 256 cycles +// <_CMU_LFXOCTRL_TIMEOUT_1KCYCLES=> 1K cycles +// <_CMU_LFXOCTRL_TIMEOUT_2KCYCLES=> 2K cycles +// <_CMU_LFXOCTRL_TIMEOUT_4KCYCLES=> 4K cycles +// <_CMU_LFXOCTRL_TIMEOUT_8KCYCLES=> 8K cycles +// <_CMU_LFXOCTRL_TIMEOUT_16KCYCLES=> 16K cycles +// <_CMU_LFXOCTRL_TIMEOUT_32KCYCLES=> 32K cycles +// <_CMU_LFXOCTRL_TIMEOUT_DEFAULT=> Default +// Default: _CMU_LFXOCTRL_TIMEOUT_DEFAULT +#define SL_DEVICE_INIT_LFXO_TIMEOUT _CMU_LFXOCTRL_TIMEOUT_DEFAULT +// <<< end of configuration section >>> + +#endif // SL_DEVICE_INIT_LFXO_CONFIG_H diff --git a/targets/AzureRTOS/SiliconLabs/_common/config/sl_i2cspm_sensor_config.h b/targets/AzureRTOS/SiliconLabs/_common/config/sl_i2cspm_sensor_config.h new file mode 100644 index 0000000000..b90117722b --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_common/config/sl_i2cspm_sensor_config.h @@ -0,0 +1,59 @@ +/***************************************************************************//** + * @file + * @brief I2CSPM Config + ******************************************************************************* + * # License + * Copyright 2019 Silicon Laboratories Inc. www.silabs.com + ******************************************************************************* + * + * The licensor of this software is Silicon Laboratories Inc. Your use of this + * software is governed by the terms of Silicon Labs Master Software License + * Agreement (MSLA) available at + * www.silabs.com/about-us/legal/master-software-license-agreement. This + * software is distributed to you in Source Code format and is governed by the + * sections of the MSLA applicable to Source Code. + * + ******************************************************************************/ + +#ifndef SL_I2CSPM_SENSOR_CONFIG_H +#define SL_I2CSPM_SENSOR_CONFIG_H + +// <<< Use Configuration Wizard in Context Menu + +// I2CSPM settings + +// Reference clock frequency +// Frequency in Hz of the reference clock. +// Select 0 to use the frequency of the currently selected clock. +// Default: 0 +#define SL_I2CSPM_SENSOR_REFERENCE_CLOCK 0 + +// Speed mode +// <0=> Standard mode (100kbit/s) +// <1=> Fast mode (400kbit/s) +// <2=> Fast mode plus (1Mbit/s) +// Default: 0 +#define SL_I2CSPM_SENSOR_SPEED_MODE 0 +// end I2CSPM config + +// <<< end of configuration section >>> + +// <<< sl:start pin_tool >>> +// SL_I2CSPM_SENSOR +// $[I2C_SL_I2CSPM_SENSOR] +#define SL_I2CSPM_SENSOR_PERIPHERAL I2C0 +#define SL_I2CSPM_SENSOR_PERIPHERAL_NO 0 + +// I2C0 SCL on PC10 +#define SL_I2CSPM_SENSOR_SCL_PORT gpioPortC +#define SL_I2CSPM_SENSOR_SCL_PIN 10 +#define SL_I2CSPM_SENSOR_SCL_LOC 14 + +// I2C0 SDA on PC11 +#define SL_I2CSPM_SENSOR_SDA_PORT gpioPortC +#define SL_I2CSPM_SENSOR_SDA_PIN 11 +#define SL_I2CSPM_SENSOR_SDA_LOC 16 +// [I2C_SL_I2CSPM_SENSOR]$ +// <<< sl:end pin_tool >>> + +#endif // SL_I2CSPM_SENSOR_CONFIG_H diff --git a/targets/AzureRTOS/SiliconLabs/_common/config/sl_memlcd_usart_config.h b/targets/AzureRTOS/SiliconLabs/_common/config/sl_memlcd_usart_config.h new file mode 100644 index 0000000000..e535fd32f9 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_common/config/sl_memlcd_usart_config.h @@ -0,0 +1,35 @@ +#ifndef SL_MEMLCD_CONFIG_H +#define SL_MEMLCD_CONFIG_H + +// <<< sl:start pin_tool >>> +// SL_MEMLCD_SPI +// $[USART_SL_MEMLCD_SPI] +#define SL_MEMLCD_SPI_PERIPHERAL USART1 +#define SL_MEMLCD_SPI_PERIPHERAL_NO 1 + +// USART1 TX on PA14 +#define SL_MEMLCD_SPI_TX_PORT gpioPortA +#define SL_MEMLCD_SPI_TX_PIN 14 +#define SL_MEMLCD_SPI_TX_LOC 6 + +// USART1 CLK on PC15 +#define SL_MEMLCD_SPI_CLK_PORT gpioPortC +#define SL_MEMLCD_SPI_CLK_PIN 15 +#define SL_MEMLCD_SPI_CLK_LOC 3 +// [USART_SL_MEMLCD_SPI]$ + +// SL_MEMLCD_SPI_CS +// $[GPIO_SL_MEMLCD_SPI_CS] +#define SL_MEMLCD_SPI_CS_PORT gpioPortC +#define SL_MEMLCD_SPI_CS_PIN 14 +// [GPIO_SL_MEMLCD_SPI_CS]$ + +// SL_MEMLCD_EXTCOMIN +// $[GPIO_SL_MEMLCD_EXTCOMIN] +#define SL_MEMLCD_EXTCOMIN_PORT gpioPortA +#define SL_MEMLCD_EXTCOMIN_PIN 11 +// [GPIO_SL_MEMLCD_EXTCOMIN]$ + +// <<< sl:end pin_tool >>> + +#endif diff --git a/targets/AzureRTOS/SiliconLabs/_common/config/sl_memory_config.h b/targets/AzureRTOS/SiliconLabs/_common/config/sl_memory_config.h new file mode 100644 index 0000000000..d641ca4017 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_common/config/sl_memory_config.h @@ -0,0 +1,16 @@ +#ifndef SL_MEMORY_CONFIG_H +#define SL_MEMORY_CONFIG_H + +// Stack size for the application. +// This is set to a value that will blow up memory assignment to force this to be set at target level +#ifndef SL_STACK_SIZE + #define SL_STACK_SIZE 0xDEADBEEF +#endif + +// Minimum heap size for the application. +// This is set to a value that will blow up memory assignment to force this to be set at target level +#ifndef SL_HEAP_SIZE + #define SL_HEAP_SIZE 0xDEADBEEF +#endif + +#endif diff --git a/targets/AzureRTOS/SiliconLabs/_common/config/sl_power_manager_config.h b/targets/AzureRTOS/SiliconLabs/_common/config/sl_power_manager_config.h new file mode 100644 index 0000000000..735287ee7b --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_common/config/sl_power_manager_config.h @@ -0,0 +1,70 @@ +/***************************************************************************//** + * @file + * @brief Power Manager configuration file. + ******************************************************************************* + * # License + * Copyright 2020 Silicon Laboratories Inc. www.silabs.com + ******************************************************************************* + * + * SPDX-License-Identifier: Zlib + * + * The licensor of this software is Silicon Laboratories Inc. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + ******************************************************************************/ + +// <<< Use Configuration Wizard in Context Menu >>> + +#ifndef SL_POWER_MANAGER_CONFIG_H +#define SL_POWER_MANAGER_CONFIG_H + +// Power Manager Configuration + +// Enable custom IRQ handler for external HF oscillator. +// Enable if CMU_IRQHandler/HFXO0_IRQHandler is needed from your application. +// The function sl_power_manager_irq_handler() will have to be called from you custom handler if this is enabled. +// Default: 0 +#define SL_POWER_MANAGER_CUSTOM_HF_OSCILLATOR_IRQ_HANDLER 0 + +// Lowest Energy mode allowed +// <2=> EM2 +// <3=> EM3 +// Default: 2 +#define SL_POWER_MANAGER_LOWEST_EM_ALLOWED 2 + +// Enable fast wakeup (disable voltage scaling in EM2/3 mode) +// Enable or disable voltage scaling in EM2/3 modes (when available). This decreases wakeup time by about 30 us. +// Deprecated. It is replaced by the function sl_power_manager_em23_voltage_scaling_enable_fast_wakeup() +// Default: 0 +#define SL_POWER_MANAGER_CONFIG_VOLTAGE_SCALING_FAST_WAKEUP 0 + +// Enable debugging feature +// Enable or disable debugging features (trace the different modules that have requirements). +// Default: 0 +#define SL_POWER_MANAGER_DEBUG 0 + +// Maximum numbers of requirements that can be logged +// Default: 10 +#define SL_POWER_MANAGER_DEBUG_POOL_SIZE 10 +// + +// + +#endif /* SL_POWER_MANAGER_CONFIG_H */ + +// <<< end of configuration section >>> diff --git a/targets/AzureRTOS/SiliconLabs/_common/config/sl_sleeptimer_config.h b/targets/AzureRTOS/SiliconLabs/_common/config/sl_sleeptimer_config.h new file mode 100644 index 0000000000..846d37d608 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_common/config/sl_sleeptimer_config.h @@ -0,0 +1,72 @@ +/***************************************************************************//** + * @file + * @brief Sleep Timer configuration file. + ******************************************************************************* + * # License + * Copyright 2020 Silicon Laboratories Inc. www.silabs.com + ******************************************************************************* + * + * SPDX-License-Identifier: Zlib + * + * The licensor of this software is Silicon Laboratories Inc. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + ******************************************************************************/ + +// <<< Use Configuration Wizard in Context Menu >>> + +#ifndef SL_SLEEPTIMER_CONFIG_H +#define SL_SLEEPTIMER_CONFIG_H + +#define SL_SLEEPTIMER_PERIPHERAL_DEFAULT 0 +#define SL_SLEEPTIMER_PERIPHERAL_RTCC 1 +#define SL_SLEEPTIMER_PERIPHERAL_PRORTC 2 +#define SL_SLEEPTIMER_PERIPHERAL_RTC 3 +#define SL_SLEEPTIMER_PERIPHERAL_SYSRTC 4 +#define SL_SLEEPTIMER_PERIPHERAL_BURTC 5 + +// Timer Peripheral Used by Sleeptimer +// Default (auto select) +// RTCC +// Radio internal RTC (PRORTC) +// RTC +// SYSRTC +// Back-Up RTC (BURTC) +// Selection of the Timer Peripheral Used by the Sleeptimer +#define SL_SLEEPTIMER_PERIPHERAL SL_SLEEPTIMER_PERIPHERAL_DEFAULT + +// Enable wallclock functionality +// Enable or disable wallclock functionalities (get_time, get_date, etc). +// Default: 0 +#define SL_SLEEPTIMER_WALLCLOCK_CONFIG 0 + +// Timer frequency divider +// Default: 1 +#define SL_SLEEPTIMER_FREQ_DIVIDER 1 + +// If Radio internal RTC (PRORTC) HAL is used, determines if it owns the IRQ handler. Enable, if no wireless stack is used. +// Default: 0 +#define SL_SLEEPTIMER_PRORTC_HAL_OWNS_IRQ_HANDLER 0 + +// Enable DEBUGRUN functionality on hardware RTC. +// Default: 0 +#define SL_SLEEPTIMER_DEBUGRUN 0 + +#endif /* SLEEPTIMER_CONFIG_H */ + +// <<< end of configuration section >>> diff --git a/targets/AzureRTOS/SiliconLabs/_common/hard_fault_handler.c b/targets/AzureRTOS/SiliconLabs/_common/hard_fault_handler.c new file mode 100644 index 0000000000..a9f03e98e2 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_common/hard_fault_handler.c @@ -0,0 +1,184 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include +#include + +//See http://infocenter.arm.com/help/topic/com.arm.doc.dui0552a/BABBGBEC.html +typedef enum { + Reset = 1, + NMI = 2, + HardFault = 3, + MemManage = 4, + BusFault = 5, + UsageFault = 6, +} FaultType; + +// Generic ARM register +typedef void *regarm_t; + +// This structure represents the stack frame saved during an interrupt handler. +struct port_extctx { + regarm_t spsr_irq; + regarm_t lr_irq; + regarm_t r0; + regarm_t r1; + regarm_t r2; + regarm_t r3; + regarm_t r12; + regarm_t lr_usr; +}; + +void NMI_Handler(void) { + while(1); +} + +// dev note: on all the following the variables need to be declared as volatile so they don't get optimized out by the linker +// dev note: the pragma below is to ignore the warning because the variables aren't actually being used despite needing to remain there for debug + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wunused-but-set-variable" +#endif + +// hard fault handler for Cortex-M3 & M4 + +void HardFault_Handler(void) { + + //Copy to local variables (not pointers) to allow GDB "i loc" to directly show the info + struct port_extctx ctx; + + //Get thread context. Contains main registers including PC and LR + memcpy(&ctx, (void*)__get_PSP(), sizeof(struct port_extctx)); + (void)ctx; + + //Interrupt status register: Which interrupt have we encountered, e.g. HardFault? + volatile FaultType faultType = (FaultType)__get_IPSR(); + + // these are not available in all the STM32 series + + //Flags about hardfault / busfault + //See http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0552a/Cihdjcfc.html for reference + volatile bool isFaultPrecise = ((SCB->CFSR >> SCB_CFSR_BUSFAULTSR_Pos) & (1 << 1) ? true : false); + volatile bool isFaultImprecise = ((SCB->CFSR >> SCB_CFSR_BUSFAULTSR_Pos) & (1 << 2) ? true : false); + volatile bool isFaultOnUnstacking = ((SCB->CFSR >> SCB_CFSR_BUSFAULTSR_Pos) & (1 << 3) ? true : false); + volatile bool isFaultOnStacking = ((SCB->CFSR >> SCB_CFSR_BUSFAULTSR_Pos) & (1 << 4) ? true : false); + volatile bool isFaultAddressValid = ((SCB->CFSR >> SCB_CFSR_BUSFAULTSR_Pos) & (1 << 7) ? true : false); + + // Hard Fault Status Register + volatile unsigned long _HFSR = (*((volatile unsigned long *)(0xE000ED2C))) ; + + // Debug Fault Status Register + volatile unsigned long _DFSR = (*((volatile unsigned long *)(0xE000ED30))) ; + + // Auxiliary Fault Status Register + volatile unsigned long _AFSR = (*((volatile unsigned long *)(0xE000ED3C))) ; + + // Read the Fault Address Registers. These may not contain valid values. + // Check BFARVALID/MMARVALID to see if they are valid values + + // MemManage Fault Address Register + volatile unsigned long _MMAR = (*((volatile unsigned long *)(0xE000ED34))) ; + + //For HardFault/BusFault this is the address that was accessed causing the error + volatile uint32_t faultAddress = SCB->BFAR; + + // forces a breakpoint causing the debugger to stop + // if no debugger is attached this is ignored + __asm volatile("BKPT #0\n"); + + // If no debugger connected, just reset the board + NVIC_SystemReset(); +} + +void BusFault_Handler(void) __attribute__((alias("HardFault_Handler"))); + +void UsageFault_Handler(void) { + + //Copy to local variables (not pointers) to allow GDB "i loc" to directly show the info + //Get thread context. Contains main registers including PC and LR + struct port_extctx ctx; + memcpy(&ctx, (void*)__get_PSP(), sizeof(struct port_extctx)); + (void)ctx; + + //Interrupt status register: Which interrupt have we encountered, e.g. HardFault? + FaultType faultType = (FaultType)__get_IPSR(); + (void)faultType; + + // these are not available in all the STM32 series + #if defined(STM32L4XX_HAL_VERSION) + + //Flags about hardfault / busfault + //See http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0552a/Cihdjcfc.html for reference + volatile bool isUndefinedInstructionFault = ((SCB->CFSR >> SCB_CFSR_USGFAULTSR_Pos) & (1 << 0) ? true : false); + volatile bool isEPSRUsageFault = ((SCB->CFSR >> SCB_CFSR_USGFAULTSR_Pos) & (1 << 1) ? true : false); + volatile bool isInvalidPCFault = ((SCB->CFSR >> SCB_CFSR_USGFAULTSR_Pos) & (1 << 2) ? true : false); + volatile bool isNoCoprocessorFault = ((SCB->CFSR >> SCB_CFSR_USGFAULTSR_Pos) & (1 << 3) ? true : false); + volatile bool isUnalignedAccessFault = ((SCB->CFSR >> SCB_CFSR_USGFAULTSR_Pos) & (1 << 8) ? true : false); + volatile bool isDivideByZeroFault = ((SCB->CFSR >> SCB_CFSR_USGFAULTSR_Pos) & (1 << 9) ? true : false); + + #endif + + // forces a breakpoint causing the debugger to stop + // if no debugger is attached this is ignored + __asm volatile("BKPT #0\n"); + + // If no debugger connected, just reset the board + NVIC_SystemReset(); +} + +void MemManage_Handler(void) { + + //Copy to local variables (not pointers) to allow GDB "i loc" to directly show the info + //Get thread context. Contains main registers including PC and LR + struct port_extctx ctx; + memcpy(&ctx, (void*)__get_PSP(), sizeof(struct port_extctx)); + (void)ctx; + + //Interrupt status register: Which interrupt have we encountered, e.g. HardFault? + FaultType faultType = (FaultType)__get_IPSR(); + (void)faultType; + + // these are not available in all the STM32 series + #if defined(STM32L4XX_HAL_VERSION) + + //For HardFault/BusFault this is the address that was accessed causing the error + volatile uint32_t faultAddress = SCB->MMFAR; + + //Flags about hardfault / busfault + //See http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0552a/Cihdjcfc.html for reference + volatile bool isInstructionAccessViolation = ((SCB->CFSR >> SCB_CFSR_MEMFAULTSR_Pos) & (1 << 0) ? true : false); + volatile bool isDataAccessViolation = ((SCB->CFSR >> SCB_CFSR_MEMFAULTSR_Pos) & (1 << 1) ? true : false); + volatile bool isExceptionUnstackingFault = ((SCB->CFSR >> SCB_CFSR_MEMFAULTSR_Pos) & (1 << 3) ? true : false); + volatile bool isExceptionStackingFault = ((SCB->CFSR >> SCB_CFSR_MEMFAULTSR_Pos) & (1 << 4) ? true : false); + volatile bool isFaultAddressValid = ((SCB->CFSR >> SCB_CFSR_MEMFAULTSR_Pos) & (1 << 7) ? true : false); + + #endif + + // forces a breakpoint causing the debugger to stop + // if no debugger is attached this is ignored + __asm volatile("BKPT #0\n"); + + // If no debugger connected, just reset the board + NVIC_SystemReset(); +} + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + +/////////////////////////////////////////////////////////////////////////////////////////// +// Hard Fault test code. +// Call this to cause a hard fault by accessing a nonexistent memory address @ 0xCCCCCCCC. +void HardFaultTest() +{ + volatile uint32_t*p; + uint32_t n; + p = (uint32_t*)0xCCCCCCCC; + n = *p; + (void)n; +} +/////////////////////////////////////////////////////////////////////////////////////////// diff --git a/targets/AzureRTOS/SiliconLabs/_common/nanoSupport_CRC32.c b/targets/AzureRTOS/SiliconLabs/_common/nanoSupport_CRC32.c new file mode 100644 index 0000000000..bb084257c1 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_common/nanoSupport_CRC32.c @@ -0,0 +1,57 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include +#include +#include +#include +#include + +// strong implementation of this function specific Gecko targets +uint32_t SUPPORT_ComputeCRC(const void *rgBlock, const uint32_t nLength, const uint32_t crc) +{ + const uint8_t *ptr = (const uint8_t *)rgBlock; + + // anything to do here? + if (nLength == 0) + { + return crc; + } + + if(crc == 0) + { + // this is NOT continuing a previous CRC calculation + + // set intial value + GPCRC_InitValueSet(GPCRC, crc); + + // Prepare GPCRC_DATA for inputs + GPCRC_Start(GPCRC); + } + + for (uint32_t i = 0; i < nLength; i++) + { + GPCRC_InputU8(GPCRC, *ptr++); + } + + return GPCRC_DataReadBitReversed(GPCRC); +}; + +void InitGpCrc(void) +{ + // Enable clocks required + CMU_ClockEnable(cmuClock_GPCRC, true); + + // Declare init structs + GPCRC_Init_TypeDef init = GPCRC_INIT_DEFAULT; + + // reverse all bits of the incoming message + init.reverseBits = true; + // all buffers are treated as byte buffers + init.enableByteMode = true; + + // Initialize GPCRC + GPCRC_Init(GPCRC, &init); +} diff --git a/targets/AzureRTOS/SiliconLabs/_common/nano_sl_usbd_class_vendor.c b/targets/AzureRTOS/SiliconLabs/_common/nano_sl_usbd_class_vendor.c new file mode 100644 index 0000000000..5d13bb45fb --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_common/nano_sl_usbd_class_vendor.c @@ -0,0 +1,1388 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Portions Copyright 2021 Silicon Laboratories Inc. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +// This is an extension to the original file from Gecko SDK v4.1.1 +// Following Support Case #00293097 with Silabs, we where advised to add the missing +// APIs to our own implementation. In case these are ever made available in the +// official SDK, this file should be removed and the original one should be used. +// There is also a change to allow changing the USB Vendor Class description, by replacing +// the hardcoded "Vendor-specific class" with a custom one. Suggestion to improve this has +// been made to Silabs (Support Case #00292362). + +/******************************************************************************************************** + ******************************************************************************************************** + * INCLUDE FILES + ******************************************************************************************************** + *******************************************************************************************************/ + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include + +#include + +// clang-format off + +/******************************************************************************************************** + ******************************************************************************************************** + * LOCAL DEFINES + ******************************************************************************************************** + *******************************************************************************************************/ + +/******************************************************************************************************** + ******************************************************************************************************** + * LOCAL DATA TYPES + ******************************************************************************************************** + *******************************************************************************************************/ + +/******************************************************************************************************** + * FORWARD DECLARATIONS + *******************************************************************************************************/ + +typedef struct sli_usbd_vendor_ctrl sli_usbd_vendor_ctrl_t; + +/******************************************************************************************************** + * VENDOR CLASS STATES + *******************************************************************************************************/ + +SL_ENUM(sli_usbd_vendor_state_t) { + SLI_USBD_VENDOR_STATE_NONE = 0, + SLI_USBD_VENDOR_STATE_INIT, + SLI_USBD_VENDOR_STATE_CONFIG +}; + +/******************************************************************************************************** + * VENDOR CLASS EP REQUIREMENTS DATA TYPE + *******************************************************************************************************/ + +// Vendor class comm info +typedef struct { + // Ptr to ctrl info. + sli_usbd_vendor_ctrl_t *ctrl_ptr; + // Avail EP for comm: Bulk (and Intr) + uint8_t data_bulk_in_endpoint_address; + uint8_t data_bulk_out_endpoint_address; + uint8_t interrupt_in_endpoint_address; + uint8_t interrupt_out_endpoint_address; + + bool data_bulk_in_active_transfer; + bool data_bulk_out_active_transfer; + bool interrupt_in_active_transfer; + bool interrupt_out_active_transfer; +} sli_usbd_vendor_comm_t; + +// Vendor Class Ctrl Info +struct sli_usbd_vendor_ctrl { + sli_usbd_vendor_state_t state; ///< Vendor class state. + uint8_t class_nbr; ///< Vendor class instance nbr. + sli_usbd_vendor_comm_t *comm_ptr; ///< Vendor class comm info ptr. + bool interrupt_enable; ///< Intr IN & OUT EPs en/dis flag. + uint16_t interrupt_interval; ///< Polling interval for intr IN & OUT EPs. + sl_usbd_vendor_callbacks_t *callback_ptr; ///< Ptr to app callback for vendor-specific req. + sl_usbd_vendor_async_function_t bulk_read_async_function; ///< Ptr to callback used for async comm. + void *bulk_read_async_arg_ptr; ///< Ptr to extra arg used for async comm. + sl_usbd_vendor_async_function_t bulk_write_async_function; ///< Ptr to callback used for async comm. + void *bulk_write_async_arg_ptr; ///< Ptr to extra arg used for async comm. + sl_usbd_vendor_async_function_t interrupt_read_async_function; ///< Ptr to callback used for async comm. + void *interrupt_read_async_arg_ptr; ///< Ptr to extra arg used for async comm. + sl_usbd_vendor_async_function_t interrupt_write_async_function; ///< Ptr to callback used for async comm. + void *interrupt_write_async_arg_ptr; ///< Ptr to extra arg used for async comm. +#if (USBD_CFG_MS_OS_DESC_EN == 1) // Microsoft ext properties. + sl_usbd_microsoft_ext_property_t microsoft_ext_property_table[SL_USBD_VENDOR_MS_EXTENDED_PROPERTIES_QUANTITY]; + uint8_t interface_number; // Interface number associated with class instance + uint8_t microsoft_ext_property_next; +#endif +}; + +// Vendor Class Root Struct +typedef struct { + sli_usbd_vendor_ctrl_t ctrl_table[SL_USBD_VENDOR_CLASS_INSTANCE_QUANTITY]; ///< Vendor class ctrl array. + uint8_t ctrl_nbr_next; + sli_usbd_vendor_comm_t comm_tbl[SL_USBD_VENDOR_CLASS_INSTANCE_QUANTITY * SL_USBD_VENDOR_CONFIGURATION_QUANTITY]; ///< Vendor class comm array. + uint8_t comm_nbr_next; +} sli_usbd_vendor_t; + +/******************************************************************************************************** + ******************************************************************************************************** + * LOCAL CONSTANTS + ******************************************************************************************************** + *******************************************************************************************************/ + +/******************************************************************************************************** + ******************************************************************************************************** + * LOCAL GLOBAL VARIABLES + ******************************************************************************************************** + *******************************************************************************************************/ + +static sli_usbd_vendor_t usbd_vendor; + +/******************************************************************************************************** + ******************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + ******************************************************************************************************** + *******************************************************************************************************/ + +static void usbd_vendor_enable(uint8_t config_nbr, + void *p_if_class_arg); + +static void usbd_vendor_disable(uint8_t config_nbr, + void *p_if_class_arg); + +static bool usbd_vendor_request_handler(const sl_usbd_setup_req_t *p_setup_req, + void *p_if_class_arg); + +#if (USBD_CFG_MS_OS_DESC_EN == 1) +static uint8_t usbd_vendor_get_microsoft_compat_id(uint8_t *p_sub_compat_id_ix); + +static uint8_t usbd_vendor_get_microsoft_ext_property_table(sl_usbd_microsoft_ext_property_t **pp_ext_property_tbl, uint8_t if_no); +#endif + +static void usbd_vendor_read_bulk_async_complete(uint8_t ep_addr, + void *p_buf, + uint32_t buf_len, + uint32_t xfer_len, + void *p_arg, + sl_status_t status); + +static void usbd_vendor_write_bulk_async_complete(uint8_t ep_addr, + void *p_buf, + uint32_t buf_len, + uint32_t xfer_len, + void *p_arg, + sl_status_t status); + +static void usbd_vendor_read_interrupt_async_complete(uint8_t ep_addr, + void *p_buf, + uint32_t buf_len, + uint32_t xfer_len, + void *p_arg, + sl_status_t status); + +static void usbd_vendor_write_interrupt_async_complete(uint8_t ep_addr, + void *p_buf, + uint32_t buf_len, + uint32_t xfer_len, + void *p_arg, + sl_status_t status); + +/******************************************************************************************************** + * VENDOR CLASS DRIVER + *******************************************************************************************************/ + +static sl_usbd_class_driver_t usbd_vendor_driver = { + usbd_vendor_enable, + usbd_vendor_disable, + NULL, // Vendor does NOT use alternate interface(s). + NULL, + NULL, // Vendor does NOT use functional EP desc. + NULL, + NULL, // Vendor does NOT use functional IF desc. + NULL, + NULL, // Vendor does NOT handle std req with IF recipient. + NULL, // Vendor does NOT define class-specific req. + usbd_vendor_request_handler, + +#if (USBD_CFG_MS_OS_DESC_EN == 1) + usbd_vendor_get_microsoft_compat_id, + usbd_vendor_get_microsoft_ext_property_table, +#endif +}; + +/******************************************************************************************************** + ******************************************************************************************************** + * GLOBAL FUNCTIONS + ******************************************************************************************************** + *******************************************************************************************************/ + +/****************************************************************************************************//** + * Initializes the internal structures and variables used by the Vendor class + *******************************************************************************************************/ +sl_status_t sl_usbd_vendor_init(void) +{ + uint8_t ix; + sli_usbd_vendor_ctrl_t *p_ctrl; + sli_usbd_vendor_comm_t *p_comm; + + usbd_vendor.ctrl_nbr_next = SL_USBD_VENDOR_CLASS_INSTANCE_QUANTITY; + usbd_vendor.comm_nbr_next = SL_USBD_VENDOR_CLASS_INSTANCE_QUANTITY * SL_USBD_VENDOR_CONFIGURATION_QUANTITY; + + // Init vendor class struct. + for (ix = 0u; ix < usbd_vendor.ctrl_nbr_next; ix++) { + p_ctrl = &usbd_vendor.ctrl_table[ix]; + p_ctrl->state = SLI_USBD_VENDOR_STATE_NONE; + p_ctrl->class_nbr = SL_USBD_CLASS_NBR_NONE; + p_ctrl->comm_ptr = NULL; + p_ctrl->interrupt_enable = false; + p_ctrl->interrupt_interval = 0u; + p_ctrl->callback_ptr = NULL; + p_ctrl->bulk_read_async_function = NULL; + p_ctrl->bulk_read_async_arg_ptr = NULL; + p_ctrl->bulk_write_async_function = NULL; + p_ctrl->bulk_write_async_arg_ptr = NULL; + p_ctrl->interrupt_read_async_function = NULL; + p_ctrl->interrupt_read_async_arg_ptr = NULL; + p_ctrl->interrupt_write_async_function = NULL; + p_ctrl->interrupt_write_async_arg_ptr = NULL; + +#if (USBD_CFG_MS_OS_DESC_EN == 1) + p_ctrl->microsoft_ext_property_next = 0u; + + memset(p_ctrl->microsoft_ext_property_table, 0, sizeof(sl_usbd_microsoft_ext_property_t) * SL_USBD_VENDOR_MS_EXTENDED_PROPERTIES_QUANTITY); +#endif + } + + // Init vendor EP tbl. + for (ix = 0u; ix < usbd_vendor.comm_nbr_next; ix++) { + p_comm = &usbd_vendor.comm_tbl[ix]; + p_comm->ctrl_ptr = NULL; + p_comm->data_bulk_in_endpoint_address = SL_USBD_ENDPOINT_ADDR_NONE; + p_comm->data_bulk_out_endpoint_address = SL_USBD_ENDPOINT_ADDR_NONE; + p_comm->interrupt_in_endpoint_address = SL_USBD_ENDPOINT_ADDR_NONE; + p_comm->interrupt_out_endpoint_address = SL_USBD_ENDPOINT_ADDR_NONE; + + p_comm->data_bulk_in_active_transfer = false; + p_comm->data_bulk_out_active_transfer = false; + p_comm->interrupt_in_active_transfer = false; + p_comm->interrupt_out_active_transfer = false; + } + + return SL_STATUS_OK; +} + +/****************************************************************************************************//** + * Adds a new instance of the Vendor class + *******************************************************************************************************/ +sl_status_t sl_usbd_vendor_create_instance(bool intr_en, + uint16_t interval, + sl_usbd_vendor_callbacks_t *p_vendor_callbacks, + uint8_t *p_class_nbr) +{ + sli_usbd_vendor_ctrl_t *p_ctrl; + uint8_t vendor_class_nbr; + CORE_DECLARE_IRQ_STATE; + + if (p_class_nbr == NULL) { + return SL_STATUS_NULL_POINTER; + } + + if (intr_en == true) { + // interval must be a power of 2. + if (SLI_USBD_IS_PWR2(interval) != true) { + *p_class_nbr = SL_USBD_CLASS_NBR_NONE; + return SL_STATUS_INVALID_PARAMETER; + } + } + + CORE_ENTER_ATOMIC(); + // Chk if max nbr of instances reached. + if (usbd_vendor.ctrl_nbr_next == 0u) { + CORE_EXIT_ATOMIC(); + *p_class_nbr = SL_USBD_CLASS_NBR_NONE; + return SL_STATUS_ALLOCATION_FAILED; + } + + // Next avail vendor class instance nbr. + usbd_vendor.ctrl_nbr_next--; + // Alloc new vendor class instance nbr. + vendor_class_nbr = usbd_vendor.ctrl_nbr_next; + CORE_EXIT_ATOMIC(); + + p_ctrl = &usbd_vendor.ctrl_table[vendor_class_nbr]; // Get vendor class instance. + // Store vendor class instance info. + p_ctrl->interrupt_enable = intr_en; // Intr EPs en/dis. + p_ctrl->interrupt_interval = interval; // Polling interval for intr EPs. + p_ctrl->callback_ptr = p_vendor_callbacks; // App callback for vendor-specific req. + + *p_class_nbr = vendor_class_nbr; + return SL_STATUS_OK; +} + +/****************************************************************************************************//** + * Creates a new instance of the Vendor class + *******************************************************************************************************/ +sl_status_t sl_usbd_vendor_add_to_configuration(uint8_t class_nbr, + uint8_t config_nbr) +{ + sli_usbd_vendor_ctrl_t *p_ctrl; + sli_usbd_vendor_comm_t *p_comm; + uint8_t if_nbr; + uint8_t ep_addr; + uint16_t comm_nbr; + uint16_t intr_interval; + sl_status_t status; + CORE_DECLARE_IRQ_STATE; + + if (class_nbr >= SL_USBD_VENDOR_CLASS_INSTANCE_QUANTITY) { + return SL_STATUS_INVALID_PARAMETER; + } + + // Get vendor class instance. + p_ctrl = &usbd_vendor.ctrl_table[class_nbr]; + + CORE_ENTER_ATOMIC(); + + if (usbd_vendor.comm_nbr_next == 0u) { + CORE_EXIT_ATOMIC(); + return SL_STATUS_ALLOCATION_FAILED; + } + + // Alloc new vendor class comm info nbr. + comm_nbr = usbd_vendor.comm_nbr_next - 1u; + // Next avail vendor class comm info nbr. + usbd_vendor.comm_nbr_next--; + CORE_EXIT_ATOMIC(); + + // Get vendor class comm info. + p_comm = &usbd_vendor.comm_tbl[comm_nbr]; + + // Config Desc Construction + // See Note #2. + // Add vendor IF desc to config desc. + // .NET nanoFramework change: replace hardcoded USB Vendor Class description with one from the configuration + status = sl_usbd_core_add_interface(config_nbr, + &usbd_vendor_driver, + (void *)p_comm, + NULL, + SL_USBD_CLASS_CODE_VENDOR_SPECIFIC, + SL_USBD_SUBCLASS_CODE_VENDOR_SPECIFIC, + SL_USBD_PROTOCOL_CODE_VENDOR_SPECIFIC, + // [NF_CHANGE] + NANO_SL_USBD_CLASS_VENDOR_DESCRIPTION, + // [END_NF_CHANGE] + &if_nbr); + if (status != SL_STATUS_OK) { + return status; + } + + // Microsoft ext properties. +#if (USBD_CFG_MS_OS_DESC_EN == 1) + p_ctrl->interface_number = if_nbr; +#endif + + // Add bulk IN EP desc. + status = sl_usbd_core_add_bulk_endpoint(config_nbr, + if_nbr, + 0u, + true, + 0u, + &ep_addr); + if (status != SL_STATUS_OK) { + return status; + } + + // Store bulk IN EP addr. + p_comm->data_bulk_in_endpoint_address = ep_addr; + + // Add bulk OUT EP desc. + status = sl_usbd_core_add_bulk_endpoint(config_nbr, + if_nbr, + 0u, + false, + 0u, + &ep_addr); + if (status != SL_STATUS_OK) { + return status; + } + + // Store bulk OUT EP addr. + p_comm->data_bulk_out_endpoint_address = ep_addr; + + if (p_ctrl->interrupt_enable == true) { + if (SL_IS_BIT_CLEAR(config_nbr, SL_USBD_CONFIG_NBR_SPD_BIT) == true) { + // In FS, bInterval in frames. + intr_interval = p_ctrl->interrupt_interval; + } else { + // In HS, bInterval in microframes. + intr_interval = p_ctrl->interrupt_interval * 8u; + } + + // Add intr IN EP desc. + status = sl_usbd_core_add_interrupt_endpoint(config_nbr, + if_nbr, + 0u, + true, + 0u, + intr_interval, + &ep_addr); + if (status != SL_STATUS_OK) { + return status; + } + + // Store intr IN EP addr. + p_comm->interrupt_in_endpoint_address = ep_addr; + + // Add intr OUT EP desc. + status = sl_usbd_core_add_interrupt_endpoint(config_nbr, + if_nbr, + 0u, + false, + 0u, + intr_interval, + &ep_addr); + if (status != SL_STATUS_OK) { + return status; + } + + // Store intr OUT EP addr. + p_comm->interrupt_out_endpoint_address = ep_addr; + } + // Store vendor class instance info. + CORE_ENTER_ATOMIC(); + // Set class instance to init state. + p_ctrl->state = SLI_USBD_VENDOR_STATE_INIT; + p_ctrl->class_nbr = class_nbr; + p_ctrl->comm_ptr = NULL; + CORE_EXIT_ATOMIC(); + + // Save ref to vendor class instance ctrl struct. + p_comm->ctrl_ptr = p_ctrl; + + return SL_STATUS_OK; +} + +/****************************************************************************************************//** + * Gets the vendor class enable state + *******************************************************************************************************/ +sl_status_t sl_usbd_vendor_is_enabled(uint8_t class_nbr, + bool *p_enabled) +{ + sli_usbd_vendor_ctrl_t *p_ctrl; + sl_usbd_device_state_t state; + sl_status_t status; + + // TODO validate class_nbr + // Get Vendor class instance ctrl struct. + p_ctrl = &usbd_vendor.ctrl_table[class_nbr]; + // Get dev state. + status = sl_usbd_core_get_device_state(&state); + + if ((status == SL_STATUS_OK) + && (state == SL_USBD_DEVICE_STATE_CONFIGURED) + && (p_ctrl->state == SLI_USBD_VENDOR_STATE_CONFIG)) { + *p_enabled = true; + } else { + *p_enabled = false; + } + + return SL_STATUS_OK; +} + +/****************************************************************************************************//** + * Adds a Microsoft OS extended property to this vendor class instance + *******************************************************************************************************/ +#if (USBD_CFG_MS_OS_DESC_EN == 1) +sl_status_t sl_usbd_vendor_add_microsoft_ext_property(uint8_t class_nbr, + uint8_t property_type, + const uint8_t *p_property_name, + uint16_t property_name_len, + const uint8_t *p_property, + uint32_t property_len) +{ + uint8_t ext_property_nbr; + sli_usbd_vendor_ctrl_t *p_ctrl; + sl_usbd_microsoft_ext_property_t *p_ext_property; + CORE_DECLARE_IRQ_STATE; + + if (class_nbr >= SL_USBD_VENDOR_CLASS_INSTANCE_QUANTITY) { + return SL_STATUS_INVALID_PARAMETER; + } + + if (!((property_type == SL_USBD_MICROSOFT_PROPERTY_TYPE_REG_SZ) + || (property_type == SL_USBD_MICROSOFT_PROPERTY_TYPE_REG_EXPAND_SZ) + || (property_type == SL_USBD_MICROSOFT_PROPERTY_TYPE_REG_BINARY) + || (property_type == SL_USBD_MICROSOFT_PROPERTY_TYPE_REG_DWORD_LITTLE_ENDIAN) + || (property_type == SL_USBD_MICROSOFT_PROPERTY_TYPE_REG_DWORD_BIG_ENDIAN) + || (property_type == SL_USBD_MICROSOFT_PROPERTY_TYPE_REG_LINK) + || (property_type == SL_USBD_MICROSOFT_PROPERTY_TYPE_REG_MULTI_SZ))) { + return SL_STATUS_INVALID_PARAMETER; + } + + if ((p_property_name == NULL) && (property_name_len != 0u)) { + return SL_STATUS_NULL_POINTER; + } + + if ((p_property == NULL) && (property_len != 0u)) { + return SL_STATUS_NULL_POINTER; + } + + // Get Vendor class instance ctrl struct. + p_ctrl = &usbd_vendor.ctrl_table[class_nbr]; + + CORE_ENTER_ATOMIC(); + ext_property_nbr = p_ctrl->microsoft_ext_property_next; + +#if defined(RTOS_ARG_CHK_EXT_EN) && RTOS_ARG_CHK_EXT_EN == 1 + if (ext_property_nbr >= SL_USBD_VENDOR_MS_EXTENDED_PROPERTIES_QUANTITY) { + CORE_EXIT_ATOMIC(); + + return SL_STATUS_ALLOCATION_FAILED; + } +#endif + p_ctrl->microsoft_ext_property_next++; + + p_ext_property = &p_ctrl->microsoft_ext_property_table[ext_property_nbr]; + + p_ext_property->property_type = property_type; + p_ext_property->property_name_ptr = p_property_name; + p_ext_property->property_name_len = property_name_len; + p_ext_property->property_ptr = p_property; + p_ext_property->property_len = property_len; + CORE_EXIT_ATOMIC(); + + return SL_STATUS_OK; +} +#endif + +/****************************************************************************************************//** + * Receive the data from the host through the Bulk OUT endpoint + *******************************************************************************************************/ +sl_status_t sl_usbd_vendor_read_bulk_sync(uint8_t class_nbr, + void *p_buf, + uint32_t buf_len, + uint16_t timeout, + uint32_t *p_xfer_len) +{ + sli_usbd_vendor_ctrl_t *p_ctrl; + uint32_t xfer_len; + bool conn; + sl_status_t status; + + if (p_xfer_len == NULL) { + return SL_STATUS_NULL_POINTER; + } + + if ((p_buf == NULL) && (buf_len != 0u)) { + *p_xfer_len = 0; + return SL_STATUS_NULL_POINTER; + } + + if (class_nbr >= SL_USBD_VENDOR_CLASS_INSTANCE_QUANTITY) { + *p_xfer_len = 0; + return SL_STATUS_INVALID_PARAMETER; + } + + sl_usbd_vendor_is_enabled(class_nbr, &conn); + + // Chk class state. + if (conn != true) { + *p_xfer_len = 0; + return SL_STATUS_INVALID_STATE; + } + + // Get Vendor class instance ctrl struct. + p_ctrl = &usbd_vendor.ctrl_table[class_nbr]; + + status = sl_usbd_core_read_bulk_sync(p_ctrl->comm_ptr->data_bulk_out_endpoint_address, + p_buf, + buf_len, + timeout, + &xfer_len); + + if (status != SL_STATUS_OK) { + *p_xfer_len = 0; + return status; + } + + *p_xfer_len = xfer_len; + return SL_STATUS_OK; +} + +/****************************************************************************************************//** + * Sends the data to host through Bulk IN endpoint + *******************************************************************************************************/ +sl_status_t sl_usbd_vendor_write_bulk_sync(uint8_t class_nbr, + void *p_buf, + uint32_t buf_len, + uint16_t timeout, + bool end, + uint32_t *p_xfer_len) +{ + sli_usbd_vendor_ctrl_t *p_ctrl; + uint32_t xfer_len; + bool conn; + sl_status_t status; + + if (p_xfer_len == NULL) { + return SL_STATUS_NULL_POINTER; + } + + if ((p_buf == NULL) && (buf_len != 0u)) { + *p_xfer_len = 0; + return SL_STATUS_NULL_POINTER; + } + + if (class_nbr >= SL_USBD_VENDOR_CLASS_INSTANCE_QUANTITY) { + *p_xfer_len = 0; + return SL_STATUS_INVALID_PARAMETER; + } + + sl_usbd_vendor_is_enabled(class_nbr, &conn); + + // Chk class state. + if (conn != true) { + *p_xfer_len = 0; + return SL_STATUS_INVALID_STATE; + } + + // Get Vendor class instance ctrl struct. + p_ctrl = &usbd_vendor.ctrl_table[class_nbr]; + + status = sl_usbd_core_write_bulk_sync(p_ctrl->comm_ptr->data_bulk_in_endpoint_address, + p_buf, + buf_len, + timeout, + end, + &xfer_len); + + if (status != SL_STATUS_OK) { + *p_xfer_len = 0; + return status; + } + + *p_xfer_len = xfer_len; + return SL_STATUS_OK; +} + +/****************************************************************************************************//** + * Receive the data from the host through the Bulk OUT endpoint + *******************************************************************************************************/ +sl_status_t sl_usbd_vendor_read_bulk_async(uint8_t class_nbr, + void *p_buf, + uint32_t buf_len, + sl_usbd_vendor_async_function_t async_fnct, + void *p_async_arg) +{ + sli_usbd_vendor_ctrl_t *p_ctrl; + bool conn; + sl_status_t status; + + if ((p_buf == NULL) && (buf_len != 0u)) { + return SL_STATUS_NULL_POINTER; + } + + if (class_nbr >= SL_USBD_VENDOR_CLASS_INSTANCE_QUANTITY) { + return SL_STATUS_INVALID_PARAMETER; + } + + sl_usbd_vendor_is_enabled(class_nbr, &conn); + + // Chk class state. + if (conn != true) { + return SL_STATUS_INVALID_STATE; + } + + // Get Vendor class instance ctrl struct. + p_ctrl = &usbd_vendor.ctrl_table[class_nbr]; + + p_ctrl->bulk_read_async_function = async_fnct; + p_ctrl->bulk_read_async_arg_ptr = p_async_arg; + + // Check if another xfer is already in progress. + if (p_ctrl->comm_ptr->data_bulk_out_active_transfer == false) { + // Indicate that a xfer is in progress. + p_ctrl->comm_ptr->data_bulk_out_active_transfer = true; + status = sl_usbd_core_read_bulk_async(p_ctrl->comm_ptr->data_bulk_out_endpoint_address, + p_buf, + buf_len, + usbd_vendor_read_bulk_async_complete, + (void *)p_ctrl); + if (status != SL_STATUS_OK) { + p_ctrl->comm_ptr->data_bulk_out_active_transfer = false; + } + } else { + status = SL_STATUS_NOT_READY; + } + + return status; +} + +/****************************************************************************************************//** + * Sends the data to host through the Bulk IN endpoint + *******************************************************************************************************/ +sl_status_t sl_usbd_vendor_write_bulk_async(uint8_t class_nbr, + void *p_buf, + uint32_t buf_len, + sl_usbd_vendor_async_function_t async_fnct, + void *p_async_arg, + bool end) +{ + sli_usbd_vendor_ctrl_t *p_ctrl; + bool conn; + sl_status_t status; + + if ((p_buf == NULL) && (buf_len != 0u)) { + return SL_STATUS_NULL_POINTER; + } + + if (class_nbr >= SL_USBD_VENDOR_CLASS_INSTANCE_QUANTITY) { + return SL_STATUS_INVALID_PARAMETER; + } + + sl_usbd_vendor_is_enabled(class_nbr, &conn); + + // Chk class state. + if (conn != true) { + return SL_STATUS_INVALID_STATE; + } + + // Get Vendor class instance ctrl struct. + p_ctrl = &usbd_vendor.ctrl_table[class_nbr]; + + p_ctrl->bulk_write_async_function = async_fnct; + p_ctrl->bulk_write_async_arg_ptr = p_async_arg; + + // Check if another xfer is already in progress. + if (p_ctrl->comm_ptr->data_bulk_in_active_transfer == false) { + // Indicate that a xfer is in progress. + p_ctrl->comm_ptr->data_bulk_in_active_transfer = true; + status = sl_usbd_core_write_bulk_async(p_ctrl->comm_ptr->data_bulk_in_endpoint_address, + p_buf, + buf_len, + usbd_vendor_write_bulk_async_complete, + (void *)p_ctrl, + end); + if (status != SL_STATUS_OK) { + p_ctrl->comm_ptr->data_bulk_in_active_transfer = false; + } + } else { + status = SL_STATUS_NOT_READY; + } + + return status; +} + +/****************************************************************************************************//** + * Receives the data from the host through the Interrupt OUT endpoint + *******************************************************************************************************/ +sl_status_t sl_usbd_vendor_read_interrupt_sync(uint8_t class_nbr, + void *p_buf, + uint32_t buf_len, + uint16_t timeout, + uint32_t *p_xfer_len) +{ + sli_usbd_vendor_ctrl_t *p_ctrl; + uint32_t xfer_len; + bool conn; + sl_status_t status; + + if (p_xfer_len == NULL) { + return SL_STATUS_NULL_POINTER; + } + + if ((p_buf == NULL) && (buf_len != 0u)) { + *p_xfer_len = 0; + return SL_STATUS_NULL_POINTER; + } + + if (class_nbr >= SL_USBD_VENDOR_CLASS_INSTANCE_QUANTITY) { + *p_xfer_len = 0; + return SL_STATUS_INVALID_PARAMETER; + } + + sl_usbd_vendor_is_enabled(class_nbr, &conn); + + // Chk class state. + if (conn != true) { + *p_xfer_len = 0; + return SL_STATUS_INVALID_STATE; + } + + // Get Vendor class instance ctrl struct. + p_ctrl = &usbd_vendor.ctrl_table[class_nbr]; + + status = sl_usbd_core_read_interrupt_sync(p_ctrl->comm_ptr->interrupt_out_endpoint_address, + p_buf, + buf_len, + timeout, + &xfer_len); + + if (status != SL_STATUS_OK) { + *p_xfer_len = 0; + return status; + } + + *p_xfer_len = xfer_len; + return SL_STATUS_OK; +} + +/****************************************************************************************************//** + * Sends data to the host through the Interrupt IN endpoint + *******************************************************************************************************/ +sl_status_t sl_usbd_vendor_write_interrupt_sync(uint8_t class_nbr, + void *p_buf, + uint32_t buf_len, + uint16_t timeout, + bool end, + uint32_t *p_xfer_len) +{ + sli_usbd_vendor_ctrl_t *p_ctrl; + uint32_t xfer_len; + bool conn; + sl_status_t status; + + if (p_xfer_len == NULL) { + return SL_STATUS_NULL_POINTER; + } + + if ((p_buf == NULL) && (buf_len != 0u)) { + *p_xfer_len = 0; + return SL_STATUS_NULL_POINTER; + } + + if (class_nbr >= SL_USBD_VENDOR_CLASS_INSTANCE_QUANTITY) { + *p_xfer_len = 0; + return SL_STATUS_INVALID_PARAMETER; + } + + sl_usbd_vendor_is_enabled(class_nbr, &conn); + + // Chk class state. + if (conn != true) { + *p_xfer_len = 0; + return SL_STATUS_INVALID_STATE; + } + + // Get Vendor class instance ctrl struct. + p_ctrl = &usbd_vendor.ctrl_table[class_nbr]; + + status = sl_usbd_core_write_interrupt_sync(p_ctrl->comm_ptr->interrupt_in_endpoint_address, + p_buf, + buf_len, + timeout, + end, + &xfer_len); + + if (status != SL_STATUS_OK) { + *p_xfer_len = 0; + return status; + } + + *p_xfer_len = xfer_len; + return SL_STATUS_OK; +} + +/****************************************************************************************************//** + * Receives the data from the host through Interrupt OUT endpoint + *******************************************************************************************************/ +sl_status_t sl_usbd_vendor_read_interrupt_async(uint8_t class_nbr, + void *p_buf, + uint32_t buf_len, + sl_usbd_vendor_async_function_t async_fnct, + void *p_async_arg) +{ + sli_usbd_vendor_ctrl_t *p_ctrl; + bool conn; + sl_status_t status; + + if ((p_buf == NULL) && (buf_len != 0u)) { + return SL_STATUS_NULL_POINTER; + } + + if (class_nbr >= SL_USBD_VENDOR_CLASS_INSTANCE_QUANTITY) { + return SL_STATUS_INVALID_PARAMETER; + } + + sl_usbd_vendor_is_enabled(class_nbr, &conn); + + // Chk class state. + if (conn != true) { + return SL_STATUS_INVALID_STATE; + } + + // Get Vendor class instance ctrl struct. + p_ctrl = &usbd_vendor.ctrl_table[class_nbr]; + + p_ctrl->interrupt_read_async_function = async_fnct; + p_ctrl->interrupt_read_async_arg_ptr = p_async_arg; + + // Check if another xfer is already in progress. + if (p_ctrl->comm_ptr->interrupt_out_active_transfer == false) { + // Indicate that a xfer is in progres. + p_ctrl->comm_ptr->interrupt_out_active_transfer = true; + status = sl_usbd_core_read_interrupt_async(p_ctrl->comm_ptr->interrupt_out_endpoint_address, + p_buf, + buf_len, + usbd_vendor_read_interrupt_async_complete, + (void *)p_ctrl); + if (status != SL_STATUS_OK) { + p_ctrl->comm_ptr->interrupt_out_active_transfer = false; + } + } else { + status = SL_STATUS_NOT_READY; + } + + return status; +} + +/****************************************************************************************************//** + * Sends the data to the host through the Interrupt IN endpoint + *******************************************************************************************************/ +sl_status_t sl_usbd_vendor_write_interrupt_async(uint8_t class_nbr, + void *p_buf, + uint32_t buf_len, + sl_usbd_vendor_async_function_t async_fnct, + void *p_async_arg, + bool end) +{ + sli_usbd_vendor_ctrl_t *p_ctrl; + bool conn; + sl_status_t status; + + if ((p_buf == NULL) && (buf_len != 0u)) { + return SL_STATUS_NULL_POINTER; + } + + if (class_nbr >= SL_USBD_VENDOR_CLASS_INSTANCE_QUANTITY) { + return SL_STATUS_INVALID_PARAMETER; + } + + sl_usbd_vendor_is_enabled(class_nbr, &conn); + + // Chk class state. + if (conn != true) { + return SL_STATUS_INVALID_STATE; + } + + // Get Vendor class instance ctrl struct. + p_ctrl = &usbd_vendor.ctrl_table[class_nbr]; + + p_ctrl->interrupt_write_async_function = async_fnct; + p_ctrl->interrupt_write_async_arg_ptr = p_async_arg; + + // Check if another xfer is already in progress. + if (p_ctrl->comm_ptr->interrupt_in_active_transfer == false) { + // Indicate that a xfer is in progress. + p_ctrl->comm_ptr->interrupt_in_active_transfer = true; + status = sl_usbd_core_write_interrupt_async(p_ctrl->comm_ptr->interrupt_in_endpoint_address, + p_buf, + buf_len, + usbd_vendor_write_interrupt_async_complete, + (void *)p_ctrl, + end); + if (status != SL_STATUS_OK) { + p_ctrl->comm_ptr->interrupt_in_active_transfer = false; + } + } else { + status = SL_STATUS_NOT_READY; + } + + return status; +} + +/******************************************************************************************************** + ******************************************************************************************************** + * LOCAL FUNCTIONS + ******************************************************************************************************** + *******************************************************************************************************/ + +/****************************************************************************************************//** + * usbd_vendor_enable() + * + * @brief Notify class that configuration is active. + * + * @param config_nbr Configuration index to add the interface to. + * + * @param p_if_class_arg Pointer to class argument. + *******************************************************************************************************/ +static void usbd_vendor_enable(uint8_t config_nbr, + void *p_if_class_arg) +{ + sli_usbd_vendor_comm_t *p_comm; + sli_usbd_vendor_ctrl_t *p_ctrl; + CORE_DECLARE_IRQ_STATE; + + (void)&config_nbr; + + p_comm = (sli_usbd_vendor_comm_t *)p_if_class_arg; + p_ctrl = p_comm->ctrl_ptr; + + CORE_ENTER_ATOMIC(); + p_ctrl->comm_ptr = p_comm; + p_ctrl->state = SLI_USBD_VENDOR_STATE_CONFIG; + CORE_EXIT_ATOMIC(); + + if (p_ctrl->callback_ptr != NULL && p_ctrl->callback_ptr->enable != NULL) { + p_ctrl->callback_ptr->enable(p_ctrl->class_nbr); + } +} + +/****************************************************************************************************//** + * usbd_vendor_disable() + * + * @brief Notify class that configuration is not active. + * + * @param config_nbr Configuration index to add the interface. + * + * @param p_if_class_arg Pointer to class argument. + *******************************************************************************************************/ +static void usbd_vendor_disable(uint8_t config_nbr, + void *p_if_class_arg) +{ + sli_usbd_vendor_comm_t *p_comm; + sli_usbd_vendor_ctrl_t *p_ctrl; + CORE_DECLARE_IRQ_STATE; + + (void)&config_nbr; + + p_comm = (sli_usbd_vendor_comm_t *)p_if_class_arg; + p_ctrl = p_comm->ctrl_ptr; + + CORE_ENTER_ATOMIC(); + p_comm->ctrl_ptr->state = SLI_USBD_VENDOR_STATE_INIT; + CORE_EXIT_ATOMIC(); + + if (p_ctrl->callback_ptr != NULL && p_ctrl->callback_ptr->disable != NULL) { + p_ctrl->callback_ptr->disable(p_ctrl->class_nbr); + } +} + +/****************************************************************************************************//** + * usbd_vendor_request_handler() + * + * @brief Process vendor-specific request. + * + * @param p_setup_req Pointer to setup request structure. + * + * @param p_if_class_arg Pointer to class argument passed to sl_usbd_core_add_interface(). + * + * @return true, if vendor-specific request successfully processed. + * + * false, otherwise. + *******************************************************************************************************/ +static bool usbd_vendor_request_handler(const sl_usbd_setup_req_t *p_setup_req, + void *p_if_class_arg) +{ + sli_usbd_vendor_comm_t *p_comm; + sli_usbd_vendor_ctrl_t *p_ctrl; + bool valid; + + p_comm = (sli_usbd_vendor_comm_t *)p_if_class_arg; + p_ctrl = p_comm->ctrl_ptr; + + if (p_ctrl->callback_ptr != NULL && p_ctrl->callback_ptr->setup_req != NULL) { + p_ctrl->callback_ptr->setup_req(p_ctrl->class_nbr, p_setup_req); + valid = true; + } else { + valid = false; + } + + return (valid); +} + +/****************************************************************************************************//** + * usbd_vendor_get_microsoft_compat_id() + * + * @brief Returns Microsoft descriptor compatible id. + * + * @param p_sub_compat_id_ix Pointer to the variable that will receive subcompatible id. + * + * @return Compatible id. + * + * false, otherwise. + *******************************************************************************************************/ +#if (USBD_CFG_MS_OS_DESC_EN == 1) +static uint8_t usbd_vendor_get_microsoft_compat_id(uint8_t *p_sub_compat_id_ix) +{ + *p_sub_compat_id_ix = SL_USBD_MICROSOFT_SUBCOMPAT_ID_NULL; + + return (SL_USBD_MICROSOFT_COMPAT_ID_WINUSB); +} +#endif + +/****************************************************************************************************//** + * usbd_vendor_get_microsoft_ext_property_table() + * + * @brief Returns Microsoft descriptor extended properties table. + * + * @param pp_ext_property_tbl Pointer to the variable that will receive the Microsoft extended + * properties table. + * + * @param interface_number Interface number + * + * @return Number of Microsoft extended properties in table. + *******************************************************************************************************/ +#if (USBD_CFG_MS_OS_DESC_EN == 1) +static uint8_t usbd_vendor_get_microsoft_ext_property_table(sl_usbd_microsoft_ext_property_t **pp_ext_property_tbl, + uint8_t interface_number) +{ + sli_usbd_vendor_ctrl_t *p_ctrl; + + for (int i = 0; i < SL_USBD_VENDOR_CLASS_INSTANCE_QUANTITY; i++) { + // Get Vendor class instance ctrl struct. + p_ctrl = &usbd_vendor.ctrl_table[i]; + if (p_ctrl->interface_number == interface_number) { + *pp_ext_property_tbl = p_ctrl->microsoft_ext_property_table; + // Only one extended property (GUID) supported. + return (p_ctrl->microsoft_ext_property_next); + } + } + // no extended properties table has been set + return 0; +} +#endif + +/****************************************************************************************************//** + * usbd_vendor_read_bulk_async_complete() + * + * @brief Inform the application about the Bulk OUT transfer completion. + * + * @param ep_addr Endpoint address. + * + * @param p_buf Pointer to the receive buffer. + * + * @param buf_len Receive buffer length. + * + * @param xfer_len Number of octets received. + * + * @param p_arg Additional argument provided by application. + * + * @param status Transfer status: success or error. + *******************************************************************************************************/ +static void usbd_vendor_read_bulk_async_complete(uint8_t ep_addr, + void *p_buf, + uint32_t buf_len, + uint32_t xfer_len, + void *p_arg, + sl_status_t status) +{ + sli_usbd_vendor_ctrl_t *p_ctrl; + void *p_callback_arg; + + (void)&ep_addr; + + // Get Vendor class instance ctrl struct. + p_ctrl = (sli_usbd_vendor_ctrl_t *)p_arg; + p_callback_arg = p_ctrl->bulk_read_async_arg_ptr; + + // Xfer finished, no more active xfer. + p_ctrl->comm_ptr->data_bulk_out_active_transfer = false; + // Call app callback to inform about xfer completion. + p_ctrl->bulk_read_async_function(p_ctrl->class_nbr, + p_buf, + buf_len, + xfer_len, + p_callback_arg, + status); +} + +/****************************************************************************************************//** + * usbd_vendor_write_bulk_async_complete() + * + * @brief Inform the application about the Bulk IN transfer completion. + * + * @param ep_addr Endpoint address. + * + * @param p_buf Pointer to the transmit buffer. + * + * @param buf_len Transmit buffer length. + * + * @param xfer_len Number of octets sent. + * + * @param p_arg Additional argument provided by application. + * + * @param status Transfer status: success or error. + *******************************************************************************************************/ +static void usbd_vendor_write_bulk_async_complete(uint8_t ep_addr, + void *p_buf, + uint32_t buf_len, + uint32_t xfer_len, + void *p_arg, + sl_status_t status) +{ + sli_usbd_vendor_ctrl_t *p_ctrl; + void *p_callback_arg; + + (void)&ep_addr; + + // Get Vendor class instance ctrl struct. + p_ctrl = (sli_usbd_vendor_ctrl_t *)p_arg; + p_callback_arg = p_ctrl->bulk_write_async_arg_ptr; + + // Xfer finished, no more active xfer. + p_ctrl->comm_ptr->data_bulk_in_active_transfer = false; + // Call app callback to inform about xfer completion. + p_ctrl->bulk_write_async_function(p_ctrl->class_nbr, + p_buf, + buf_len, + xfer_len, + p_callback_arg, + status); +} + +/****************************************************************************************************//** + * usbd_vendor_read_interrupt_async_complete() + * + * @brief Inform the application about the Interrupt OUT transfer completion. + * + * @param ep_addr Endpoint address. + * + * @param p_buf Pointer to the receive buffer. + * + * @param buf_len Receive buffer length. + * + * @param xfer_len Number of octets received. + * + * @param p_arg Additional argument provided by application. + * + * @param status Transfer status: success or error. + *******************************************************************************************************/ +static void usbd_vendor_read_interrupt_async_complete(uint8_t ep_addr, + void *p_buf, + uint32_t buf_len, + uint32_t xfer_len, + void *p_arg, + sl_status_t status) +{ + sli_usbd_vendor_ctrl_t *p_ctrl; + void *p_callback_arg; + + (void)&ep_addr; + + // Get Vendor class instance ctrl struct. + p_ctrl = (sli_usbd_vendor_ctrl_t *)p_arg; + p_callback_arg = p_ctrl->interrupt_read_async_arg_ptr; + + // Xfer finished, no more active xfer. + p_ctrl->comm_ptr->interrupt_out_active_transfer = false; + // Call app callback to inform about xfer completion. + p_ctrl->interrupt_read_async_function(p_ctrl->class_nbr, + p_buf, + buf_len, + xfer_len, + p_callback_arg, + status); +} + +/****************************************************************************************************//** + * usbd_vendor_write_interrupt_async_complete() + * + * @brief Inform the application about the Interrupt IN transfer completion. + * + * @param ep_addr Endpoint address. + * + * @param p_buf Pointer to the transmit buffer. + * + * @param buf_len Transmit buffer length. + * + * @param xfer_len Number of octets sent. + * + * @param p_arg Additional argument provided by application. + * + * @param status Transfer status: success or error. + *******************************************************************************************************/ +static void usbd_vendor_write_interrupt_async_complete(uint8_t ep_addr, + void *p_buf, + uint32_t buf_len, + uint32_t xfer_len, + void *p_arg, + sl_status_t status) +{ + sli_usbd_vendor_ctrl_t *p_ctrl; + void *p_callback_arg; + + (void)&ep_addr; + + // Get Vendor class instance ctrl struct. + p_ctrl = (sli_usbd_vendor_ctrl_t *)p_arg; + p_callback_arg = p_ctrl->interrupt_write_async_arg_ptr; + + // Xfer finished, no more active xfer. + p_ctrl->comm_ptr->interrupt_in_active_transfer = false; + // Call app callback to inform about xfer completion. + p_ctrl->interrupt_write_async_function(p_ctrl->class_nbr, + p_buf, + buf_len, + xfer_len, + p_callback_arg, + status); +} + +// clang-format on + +// [NF_CHANGE] +sl_status_t sl_usbd_vendor_abort_read_bulk(uint8_t class_nbr) +{ + sli_usbd_vendor_ctrl_t *p_ctrl; + sl_status_t status; + + if (class_nbr >= SL_USBD_VENDOR_CLASS_INSTANCE_QUANTITY) + { + return SL_STATUS_INVALID_PARAMETER; + } + + // Get Vendor class instance ctrl struct. + p_ctrl = &usbd_vendor.ctrl_table[class_nbr]; + + // Check if a xfer is already in progress. + if (p_ctrl->comm_ptr->data_bulk_out_active_transfer) + { + status = sl_usbd_core_abort_endpoint(p_ctrl->comm_ptr->data_bulk_out_endpoint_address); + + if (status == SL_STATUS_OK) + { + p_ctrl->comm_ptr->data_bulk_out_active_transfer = false; + } + } + else + { + // No xfer in progress + status = SL_STATUS_NONE_WAITING; + } + + return status; +} + +sl_status_t sl_usbd_vendor_abort_write_bulk(uint8_t class_nbr) +{ + sli_usbd_vendor_ctrl_t *p_ctrl; + sl_status_t status; + + if (class_nbr >= SL_USBD_VENDOR_CLASS_INSTANCE_QUANTITY) + { + return SL_STATUS_INVALID_PARAMETER; + } + // Get Vendor class instance ctrl struct. + p_ctrl = &usbd_vendor.ctrl_table[class_nbr]; + + // Check if another xfer is already in progress. + if (p_ctrl->comm_ptr->data_bulk_in_active_transfer) + { + status = sl_usbd_core_abort_endpoint(p_ctrl->comm_ptr->data_bulk_in_endpoint_address); + + if (status == SL_STATUS_OK) + { + p_ctrl->comm_ptr->data_bulk_in_active_transfer = false; + } + } + else + { + // No xfer in progress + status = SL_STATUS_NONE_WAITING; + } + + return status; +} + +sl_status_t sl_usbd_vendor_update_device_product_string(const char *product_string) +{ + sli_usbd_device_t *p_dev; + p_dev = &usbd_ptr->device; + p_dev->device_config.product_str_ptr = product_string; + + return SL_STATUS_OK; +} + +// [END_NF_CHANGE] diff --git a/targets/AzureRTOS/SiliconLabs/_common/nano_sl_usbd_core.c b/targets/AzureRTOS/SiliconLabs/_common/nano_sl_usbd_core.c new file mode 100644 index 0000000000..a8742b5c7b --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_common/nano_sl_usbd_core.c @@ -0,0 +1,6142 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Portions Copyright 2018 Silicon Laboratories Inc. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +// This is an extension to the original file from Gecko SDK v4.3.0 +// Following +// https://community.silabs.com/s/question/0D58Y0000AGPoMDSQ1/how-to-add-a-new-usb-interface-when-the-device-is-already-started +// We have to hack our way into this. Stopping the USB core is not a decent solution because it momentarily interrupts +// the USB connection, thus causing a debug session to be lost. +// The workaround is to skip the check for the USB Core being started. +// It was found that, despite its started state, it's OK to add an interface to the USB Core. + +// clang-format off + +/******************************************************************************************************** + ******************************************************************************************************** + * INCLUDE FILES + ******************************************************************************************************** + *******************************************************************************************************/ + +#include +#include +#include +#include +#include + +#include "sl_bit.h" +#include "sl_status.h" +#include "sl_string.h" + +#include "em_core.h" + +#include "sl_usbd_device_config.h" +#include "sl_usbd_core_config.h" +#include "sl_usbd_core.h" + +#include "sli_usbd_core.h" +#include "sli_usbd_driver.h" + +#include + +/******************************************************************************************************** + ******************************************************************************************************** + * LOCAL DEFINES + ******************************************************************************************************** + *******************************************************************************************************/ + +#define SLI_USBD_LOG_BUS_CH (USBD, BUS) + +/******************************************************************************************************** + * OBJECTS TOTAL NUMBER DEFINES + *******************************************************************************************************/ + +#define SLI_USBD_CONFIG_NBR_TOT (255u - 1u) +#define SLI_USBD_INTERFACE_NBR_TOT (255u - 1u) +#define SLI_USBD_ALT_INTERFACE_NBR_TOT (255u - 1u) +#define SLI_USBD_INTERFACE_GROUP_NBR_TOT (255u - 1u) +#define SLI_USBD_ENDPOINT_NBR_TOT (255u - 1u) + +/******************************************************************************************************** + * PROTOCOL DEFINES + * + * Note(s) : (1) The descriptor buffer is used to send the device, configuration and string descriptors. + * + * (a) The size of the descriptor buffer is set to 64 which is the maximum packet size + * allowed by the USB specification for FS and HS devices. + * + * (2) USB spec 2.0 (section 9.6.3), table 9-10 specify the bitmap for the configuration + * attributes. + * + * D7 Reserved (set to one) + * D6 Self-powered + * D5 Remote Wakeup + * D4..0 Reserved (reset to zero) + *******************************************************************************************************/ + +#define SLI_USBD_DESC_BUF_LEN 64u // See Note #1a. +#define SLI_USBD_ENDPOINT_CTRL_ALLOC (0x01u | 0x02u) // (BIT_00 | BIT_01) + +#define SLI_USBD_CONFIG_DESC_SELF_POWERED 0x40u // BIT_06 See Note #2. +#define SLI_USBD_CONFIG_DESC_REMOTE_WAKEUP 0x20u // BIT_05 +#define SLI_USBD_CONFIG_DESC_RSVD_SET 0x80u // BIT_07 + +// Microsoft Desc Define +#define SLI_USBD_MICROSOFT_DESC_COMPAT_ID_HDR_VER_1_0 0x0010u +#define SLI_USBD_MICROSOFT_DESC_EXT_PROPERTIES_HDR_VER_1_0 0x000Au +#define SLI_USBD_MICROSOFT_DESC_VER_1_0 0x0100u + +#define SLI_USBD_MICROSOFT_STR_LEN 18u // Length of MS OS string. +#define SLI_USBD_MICROSOFT_STR_IX 0xEEu // Index of MS OS string. + +#define SLI_USBD_MICROSOFT_DESC_COMPAT_ID_HDR_LEN 16u +#define SLI_USBD_MICROSOFT_DESC_COMPAT_ID_SECTION_LEN 24u + +#define SLI_USBD_MICROSOFT_DESC_EXT_PROPERTIES_HDR_LEN 10u +#define SLI_USBD_MICROSOFT_DESC_EXT_PROPERTIES_SECTION_HDR_LEN 8u + +#define SLI_USBD_MICROSOFT_FEATURE_COMPAT_ID 0x0004u +#define SLI_USBD_MICROSOFT_FEATURE_EXT_PROPERTIES 0x0005u + +/******************************************************************************************************** + ******************************************************************************************************** + * LOCAL CONSTANTS + * + * Note(s) : (1) For more information, see "Extended Compat id OS Feature Descriptor Specification", + * Appendix A, available at http://msdn.microsoft.com/en-us/windows/hardware/gg463179.aspx. + ******************************************************************************************************** + *******************************************************************************************************/ + +/******************************************************************************************************** + * DEFAULT CONFIGURATIONS + *******************************************************************************************************/ + +#if (USBD_CFG_MS_OS_DESC_EN == 1) +// Signature used in MS OS string desc. +static const char usbd_microsoft_signature_str[] = "MSFT100"; + +static const char usbd_microsoft_compat_id[][8u] = { + { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { 'R', 'N', 'D', 'I', 'S', 0u, 0u, 0u }, + { 'P', 'T', 'P', 0u, 0u, 0u, 0u, 0u }, + { 'M', 'T', 'P', 0u, 0u, 0u, 0u, 0u }, + { 'X', 'U', 'S', 'B', '2', '0', 0u, 0u }, + { 'B', 'L', 'U', 'T', 'U', 'T', 'H', 0u }, + { 'W', 'I', 'N', 'U', 'S', 'B', 0u, 0u }, +}; + +static const char usbd_microsoft_subcompat_id[][8u] = { + { 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u }, + { '1', '1', 0u, 0u, 0u, 0u, 0u, 0u }, + { '1', '2', 0u, 0u, 0u, 0u, 0u, 0u }, + { 'E', 'D', 'R', 0u, 0u, 0u, 0u, 0u }, +}; +#endif + +/******************************************************************************************************** + ******************************************************************************************************** + * GLOBAL CONSTANTS + ******************************************************************************************************** + *******************************************************************************************************/ + +/******************************************************************************************************** + ******************************************************************************************************** + * LOCAL GLOBAL VARIABLES + ******************************************************************************************************** + *******************************************************************************************************/ + +static sli_usbd_t usb_device; + +static uint32_t descriptor_buffer[SLI_USBD_DESC_BUF_LEN / 4u] = { 0 }; +static uint32_t ctrl_status_buffer = 0; + +sli_usbd_t *usbd_ptr = NULL; + +#if (SLI_USBD_CFG_DBG_STATS_EN == 1) +sl_usbd_debug_device_stats_t usbd_debug_stats_device; +sl_usbd_debug_endpoint_stats_t usbd_debug_stats_endpoint_table[32u]; +#endif + +/******************************************************************************************************** + ******************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + ******************************************************************************************************** + *******************************************************************************************************/ + +static sl_status_t usbd_core_add_device(void); + +// Standard Request Handlers +static void usbd_core_stdreq_handler(sli_usbd_device_t *p_dev); + +static bool usbd_core_device_stdreq(sli_usbd_device_t *p_dev, + uint8_t request); + +static bool usbd_core_interface_stdreq(sli_usbd_device_t *p_dev, + uint8_t request); + +static bool usbd_core_endpoint_stdreq(const sli_usbd_device_t *p_dev, + uint8_t request); + +static bool usbd_core_class_stdreq(const sli_usbd_device_t *p_dev); + +static bool usbd_core_vendor_stdreq(const sli_usbd_device_t *p_dev); + +#if (USBD_CFG_MS_OS_DESC_EN == 1) +static bool usbd_core_microsoft_device_stdreq(const sli_usbd_device_t *p_dev); + +static bool usbd_core_microsoft_interface_stdreq(const sli_usbd_device_t *p_dev); + +static bool usbd_core_microsoft_ext_property_stdreq(const sli_usbd_device_t *p_dev, + sli_usbd_configuration_t *p_config, + uint8_t if_nbr, + uint16_t len); +#endif + +static bool usbd_core_get_descriptor_stdreq(sli_usbd_device_t *p_dev); + +static void usbd_core_unset_configuration(sli_usbd_device_t *p_dev); + +static sl_status_t usbd_core_set_configuration(sli_usbd_device_t *p_dev, + uint8_t config_nbr); + +static sl_status_t usbd_core_send_device_descriptor(sli_usbd_device_t *p_dev, + bool other, + uint16_t req_len); + +static sl_status_t usbd_core_send_configuration_descriptor(sli_usbd_device_t *p_dev, + uint8_t config_nbr, + bool other, + uint16_t req_len); + +#if (USBD_CFG_STR_EN == 1) +static sl_status_t usbd_core_send_string_descriptor(sli_usbd_device_t *p_dev, + uint8_t str_ix, + uint16_t req_len); + +static sl_status_t usbd_core_add_string(sli_usbd_device_t *p_dev, + const char *p_str); + +static uint8_t usbd_core_get_string_index(const sli_usbd_device_t *p_dev, + const char *p_str); + +static const char *usbd_core_get_string_descriptor(const sli_usbd_device_t *p_dev, + uint8_t str_nbr); +#endif + +static void usbd_core_start_descriptor_write(sli_usbd_device_t *p_dev, + uint16_t req_len); + +static sl_status_t usbd_core_stop_descriptor_write(sli_usbd_device_t *p_dev); + +static void usbd_core_write_08b_to_descriptor_buf(sli_usbd_device_t *p_dev, + uint8_t val); + +static void usbd_core_write_16b_to_descriptor_buf(sli_usbd_device_t *p_dev, + uint16_t val); + +static void usbd_core_write_to_descriptor_buf(sli_usbd_device_t *p_dev, + const uint8_t *p_buf, + uint16_t len); + +// USB Object Functions +static sli_usbd_configuration_t *usbd_core_get_configuration_structure(const sli_usbd_device_t *p_dev, + uint8_t config_nbr); + +static sli_usbd_interface_t *usbd_core_get_interface_structure(const sli_usbd_configuration_t *p_config, + uint8_t if_nbr); + +static sli_usbd_alt_interface_t *usbd_core_get_alt_interface_structure(const sli_usbd_interface_t *p_if, + uint8_t if_alt_nbr); + +static sl_status_t usbd_core_open_alt_interface(sli_usbd_device_t *p_dev, + uint8_t if_nbr, + const sli_usbd_alt_interface_t *p_if_alt); + +static void usbd_core_close_alt_interface(sli_usbd_device_t *p_dev, + const sli_usbd_alt_interface_t *p_if_alt); + +static sli_usbd_interface_group_t *usbd_core_get_interface_group_structure(const sli_usbd_configuration_t *p_config, + uint8_t if_grp_nbr); + +static void usbd_core_set_event(sli_usbd_event_code_t event); + +static void usbd_core_process_event(sli_usbd_device_t *p_dev, + sli_usbd_event_code_t event); + +static sl_status_t usbd_core_add_endpoint(uint8_t config_nbr, + uint8_t if_nbr, + uint8_t if_alt_nbr, + uint8_t attrib, + bool dir_in, + uint16_t max_pkt_len, + uint8_t interval, + uint8_t *p_ep_addr); + +static sl_status_t usbd_core_allocate_endpoint(sl_usbd_device_speed_t spd, + uint8_t type, + bool dir_in, + uint16_t max_pkt_len, + uint8_t if_alt_nbr, + sli_usbd_endpoint_info_t *p_ep, + uint32_t *p_alloc_bit_map, + bool *p_alloc); + +/******************************************************************************************************** + ******************************************************************************************************** + * GLOBAL FUNCTIONS + ******************************************************************************************************** + *******************************************************************************************************/ + +/****************************************************************************************************//** + * Initializes the USB device stack + *******************************************************************************************************/ +sl_status_t sl_usbd_core_init(void) +{ + sli_usbd_t *p_usbd; + sli_usbd_device_t *p_dev; + sli_usbd_configuration_t *p_config; + sli_usbd_interface_t *p_if; + sli_usbd_alt_interface_t *p_if_alt; + sli_usbd_interface_group_t *p_if_grp; + sli_usbd_endpoint_info_t *p_ep; + uint16_t tbl_ix; + sl_status_t status; + CORE_DECLARE_IRQ_STATE; + + p_usbd = &usb_device; + + p_usbd->config_nbr_next = SL_USBD_CONFIGURATION_QUANTITY; + p_usbd->interface_next = SL_USBD_INTERFACE_QUANTITY; + p_usbd->alt_interface_nbr_next = SL_USBD_ALT_INTERFACE_QUANTITY; +#if (SL_USBD_INTERFACE_GROUP_QUANTITY > 0) + p_usbd->interface_group_nbr_next = SL_USBD_INTERFACE_GROUP_QUANTITY; +#endif + p_usbd->endpoint_info_nbr_next = SL_USBD_DESCRIPTOR_QUANTITY; + p_usbd->std_req_timeout_ms = 5000u; + + CORE_ENTER_ATOMIC(); + usbd_ptr = p_usbd; + CORE_EXIT_ATOMIC(); + + // Device Initialization + p_dev = &usbd_ptr->device; + // Default dev addr. + p_dev->address = 0u; + p_dev->state = SL_USBD_DEVICE_STATE_NONE; + p_dev->state_prev = SL_USBD_DEVICE_STATE_NONE; + p_dev->conn_status = false; + p_dev->speed = SL_USBD_DEVICE_SPEED_INVALID; + +#if (USBD_CFG_OPTIMIZE_SPD == 1) + // Init HS & FS cfg list + memset(p_dev->config_fs_speed_table_ptrs, 0, sizeof(sli_usbd_configuration_t *) * SL_USBD_CONFIGURATION_QUANTITY); +#if (USBD_CFG_HS_EN == 1) + memset(p_dev->config_hs_speed_table_ptrs, 0, sizeof(sli_usbd_configuration_t *) * SL_USBD_CONFIGURATION_QUANTITY); +#endif + +#else + // linked-list implementation. + p_dev->config_fs_head_ptr = NULL; + p_dev->config_fs_tail_ptr = NULL; +#if (USBD_CFG_HS_EN == 1) + p_dev->config_hs_head_ptr = NULL; + p_dev->config_hs_tail_ptr = NULL; +#endif +#endif + + p_dev->config_cur_ptr = NULL; + p_dev->config_cur_nbr = SL_USBD_CONFIG_NBR_NONE; + p_dev->config_fs_total_nbr = 0u; +#if (USBD_CFG_HS_EN == 1) + p_dev->config_hs_total_nbr = 0u; +#endif + + memset(p_dev->endpoint_interface_table, 0, (SL_USBD_ENDPOINT_MAX_NBR * (sizeof(uint8_t)))); + + // Alloc desc buf from heap. + p_dev->desc_buf_ptr = (uint8_t *)descriptor_buffer; + if (p_dev->desc_buf_ptr == NULL) { + return SL_STATUS_ALLOCATION_FAILED; + } + memset(p_dev->desc_buf_ptr, 0, SLI_USBD_DESC_BUF_LEN); + + // Alloc ctrl status buf from heap. + p_dev->ctrl_status_buf_ptr = (uint8_t *)&ctrl_status_buffer; + if (p_dev->ctrl_status_buf_ptr == NULL) { + return SL_STATUS_ALLOCATION_FAILED; + } + + p_dev->actual_buf_ptr = p_dev->desc_buf_ptr; + p_dev->desc_buf_index = 0u; + p_dev->desc_buf_req_len = 0u; + p_dev->desc_buf_max_len = SLI_USBD_DESC_BUF_LEN; + p_dev->desc_buf_status_ptr = NULL; + +#if (SL_USBD_STRING_QUANTITY > 0) + memset(p_dev->str_descriptor_table, 0, SL_USBD_STRING_QUANTITY * sizeof(char *)); + p_dev->str_max_index = 0u; +#endif +#if (USBD_CFG_MS_OS_DESC_EN == 1) + p_dev->str_microsoft_vendor_code = 0u; +#endif + + memset(&p_dev->setup_req, 0, sizeof(sl_usbd_setup_req_t)); + + memset(&p_dev->setup_req_next, 0, sizeof(sl_usbd_setup_req_t)); + + p_dev->endpoint_max_ctrl_pkt_size = 0u; + p_dev->endpoint_max_phy_nbr = 0u; + + memset(p_dev->endpoint_interface_table, SL_USBD_INTERFACE_NBR_NONE, SL_USBD_ENDPOINT_MAX_NBR); + + p_dev->self_power = false; + p_dev->remote_wakeup = 0u; + + SLI_USBD_DBG_STATS_DEV_RESET(); + + // Configuration Table Initialization + for (tbl_ix = 0u; tbl_ix < SL_USBD_CONFIGURATION_QUANTITY; tbl_ix++) { + p_config = &usbd_ptr->config_table[tbl_ix]; + p_config->attrib = 0x00u; + p_config->max_power = 0u; + p_config->desc_len = 0u; + +#if (USBD_CFG_STR_EN == 1) + p_config->name_ptr = NULL; +#endif + +// Init IF list +#if (USBD_CFG_OPTIMIZE_SPD == 1) + // array implementation. + memset(p_config->interface_table_ptrs, 0, sizeof(sli_usbd_interface_t *) * SL_USBD_INTERFACE_QUANTITY); + +#if (SL_USBD_INTERFACE_GROUP_QUANTITY > 0u) + memset(p_config->interface_group_table_ptrs, 0, sizeof(sli_usbd_interface_group_t*) * SL_USBD_INTERFACE_GROUP_QUANTITY); +#endif +#else + // linked-list implementation. + p_config->interface_head_ptr = NULL; + p_config->interface_tail_ptr = NULL; + p_config->interface_group_head_ptr = NULL; + p_config->interface_group_tail_ptr = NULL; + p_config->next_ptr = NULL; +#endif + p_config->interface_nbr_total = 0u; + p_config->interface_group_nbr_total = 0u; + p_config->endpoint_alloc_map = 0x00u; +#if (USBD_CFG_HS_EN == 1) + p_config->config_other_speed = SL_USBD_CONFIG_NBR_NONE; +#endif + } + // Interface Table Initialization + for (tbl_ix = 0u; tbl_ix < SL_USBD_INTERFACE_QUANTITY; tbl_ix++) { + p_if = &usbd_ptr->interface_table[tbl_ix]; + p_if->class_code = SL_USBD_CLASS_CODE_USE_IF_DESC; + p_if->class_sub_code = SL_USBD_SUBCLASS_CODE_USE_IF_DESC; + p_if->class_protocol_code = SL_USBD_PROTOCOL_CODE_USE_IF_DESC; + p_if->class_driver_ptr = NULL; + p_if->class_arg_ptr = NULL; + +#if (USBD_CFG_OPTIMIZE_SPD == 1) + memset(p_if->alt_table_ptrs, 0, sizeof(sli_usbd_alt_interface_t *) * SL_USBD_ALT_INTERFACE_QUANTITY); +#else + p_if->alt_head_ptr = NULL; + p_if->alt_tail_ptr = NULL; +#endif + p_if->alt_cur_ptr = NULL; + p_if->alt_cur = SL_USBD_ALT_INTERFACE_NBR_NONE; + p_if->alt_nbr_total = 0u; + p_if->group_nbr = SL_USBD_INTERFACE_GROUP_NBR_NONE; + p_if->endpoint_alloc_map = 0x00u; +#if (USBD_CFG_OPTIMIZE_SPD == 0) + p_if->next_ptr = NULL; +#endif + } + // Alternate Settings Table Initialization + for (tbl_ix = 0u; tbl_ix < SL_USBD_ALT_INTERFACE_QUANTITY; tbl_ix++) { + p_if_alt = &usbd_ptr->alt_interface_table[tbl_ix]; + p_if_alt->class_arg_ptr = NULL; + p_if_alt->endpoint_alloc_map = 0x00u; + p_if_alt->endpoint_nbr_total = 0u; +#if (USBD_CFG_STR_EN == 1) + p_if_alt->name_ptr = NULL; +#endif +#if (USBD_CFG_OPTIMIZE_SPD == 0) + p_if_alt->next_ptr = NULL; +#endif +#if (USBD_CFG_OPTIMIZE_SPD == 1) + memset(p_if_alt->endpoint_table_ptrs, 0, SL_USBD_ENDPOINT_MAX_NBR * sizeof(sli_usbd_endpoint_info_t *)); + p_if_alt->endpoint_table_map = 0u; +#else + p_if_alt->endpoint_head_ptr = NULL; + p_if_alt->endpoint_tail_ptr = NULL; +#endif + } + +#if (SL_USBD_INTERFACE_GROUP_QUANTITY > 0u) + // Interface Group Table Initialization + for (tbl_ix = 0u; tbl_ix < SL_USBD_INTERFACE_GROUP_QUANTITY; tbl_ix++) { + p_if_grp = &usbd_ptr->interface_group_table[tbl_ix]; + p_if_grp->class_code = SL_USBD_CLASS_CODE_USE_IF_DESC; + p_if_grp->class_sub_code = SL_USBD_SUBCLASS_CODE_USE_IF_DESC; + p_if_grp->class_protocol_code = SL_USBD_PROTOCOL_CODE_USE_IF_DESC; + p_if_grp->interface_start = SL_USBD_INTERFACE_NBR_NONE; + p_if_grp->interface_count = 0u; +#if (USBD_CFG_STR_EN == 1) + p_if_grp->name_ptr = NULL; +#endif +#if (USBD_CFG_OPTIMIZE_SPD == 0) + p_if_grp->next_ptr = NULL; +#endif + } +#endif + + // Endpoint Information Table Initialization + for (tbl_ix = 0u; tbl_ix < SL_USBD_DESCRIPTOR_QUANTITY; tbl_ix++) { + p_ep = &usbd_ptr->endpoint_info_table[tbl_ix]; + p_ep->address = SL_USBD_ENDPOINT_NBR_NONE; + p_ep->attrib = 0x00u; + p_ep->interval = 0u; + // Default sync addr is zero. + p_ep->sync_addr = 0u; + // Default feedback rate exponent is zero. + p_ep->sync_refresh = 0u; +#if (USBD_CFG_OPTIMIZE_SPD == 0) + p_ep->next_ptr = NULL; +#endif + } + +#if (USBD_CFG_STR_EN == 1) + usbd_ptr->str_quantity_per_device = SL_USBD_STRING_QUANTITY; +#endif + + status = sli_usbd_core_init_endpoint(); + if (status != SL_STATUS_OK) { + return status; + } + + status = usbd_core_add_device(); + if (status != SL_STATUS_OK) { + return status; + } + + return SL_STATUS_OK; +} + +/****************************************************************************************************//** + * Starts the device stack + *******************************************************************************************************/ +sl_status_t sl_usbd_core_start_device(void) +{ + sli_usbd_device_t *p_dev; + bool init; + sl_status_t status; + CORE_DECLARE_IRQ_STATE; + + // Get dev struct. + p_dev = &usbd_ptr->device; + + // Chk curr dev state. + if ((p_dev->state != SL_USBD_DEVICE_STATE_NONE) + && (p_dev->state != SL_USBD_DEVICE_STATE_INIT)) { + return SL_STATUS_INVALID_STATE; + } + + init = false; + + // If dev not initialized, call dev drv 'Init()' function. + if (p_dev->state == SL_USBD_DEVICE_STATE_NONE) { + status = sli_usbd_driver_init(); + if (status != SL_STATUS_OK) { + return status; + } + + init = true; + } + + status = sli_usbd_driver_start(); + + if (init == true) { + CORE_ENTER_ATOMIC(); + p_dev->state = SL_USBD_DEVICE_STATE_INIT; + CORE_EXIT_ATOMIC(); + } + + return status; +} + +/****************************************************************************************************//** + * Stops the device stack + *******************************************************************************************************/ +sl_status_t sl_usbd_core_stop_device(void) +{ + sli_usbd_device_t *p_dev; + sl_status_t status; + CORE_DECLARE_IRQ_STATE; + + // Get dev struct. + p_dev = &usbd_ptr->device; + + if (p_dev->state == SL_USBD_DEVICE_STATE_NONE) { + return SL_STATUS_INVALID_STATE; + } + + // Close curr cfg. + usbd_core_unset_configuration(p_dev); + status = sli_usbd_driver_stop(); + + CORE_ENTER_ATOMIC(); + // Re-init dev stack to 'INIT' state. + p_dev->state = SL_USBD_DEVICE_STATE_INIT; + p_dev->state_prev = SL_USBD_DEVICE_STATE_INIT; + p_dev->conn_status = false; + CORE_EXIT_ATOMIC(); + + return status; +} + +/****************************************************************************************************//** + * Adds a configuration attribute to the device + *******************************************************************************************************/ +sl_status_t sl_usbd_core_add_configuration(uint8_t attrib, + uint16_t max_pwr, + sl_usbd_device_speed_t spd, + const char *p_name, + uint8_t *p_cfg_nbr) +{ + sli_usbd_device_t *p_dev; + sli_usbd_configuration_t *p_config; + uint8_t config_tbl_ix; + uint8_t config_nbr; + sl_usbd_device_speed_t drv_spd; + sl_status_t status; + CORE_DECLARE_IRQ_STATE; + +#if (USBD_CFG_HS_EN == 0) + (void)&spd; + (void)&drv_spd; +#endif + + if (p_cfg_nbr == NULL) { + return SL_STATUS_INVALID_PARAMETER; + } + + // Chk max pwr (see Note #1). + if (max_pwr > SL_USBD_MAX_BUS_PWR_LIMIT_mA) { + *p_cfg_nbr = SL_USBD_CONFIG_NBR_NONE; + return SL_STATUS_INVALID_PARAMETER; + } + + // Get dev struct. + p_dev = &usbd_ptr->device; + + // Chk curr dev state. + if ((p_dev->state != SL_USBD_DEVICE_STATE_NONE) + && (p_dev->state != SL_USBD_DEVICE_STATE_INIT)) { + *p_cfg_nbr = SL_USBD_CONFIG_NBR_NONE; + return SL_STATUS_INVALID_STATE; + } + +// Chk if dev supports high spd. +#if (USBD_CFG_HS_EN == 1) + sli_usbd_driver_get_speed(&drv_spd); + if ((drv_spd != SL_USBD_DEVICE_SPEED_HIGH) + && (spd == SL_USBD_DEVICE_SPEED_HIGH)) { + *p_cfg_nbr = SL_USBD_CONFIG_NBR_NONE; + return SL_STATUS_INVALID_PARAMETER; + } +#endif + + CORE_ENTER_ATOMIC(); + // Chk if cfg is avail. + if (usbd_ptr->config_nbr_next == 0u) { + CORE_EXIT_ATOMIC(); + *p_cfg_nbr = SL_USBD_CONFIG_NBR_NONE; + return SL_STATUS_ALLOCATION_FAILED; + } + config_tbl_ix = usbd_ptr->config_nbr_next - 1u; + +#if (USBD_CFG_HS_EN == 1) + // Add cfg to dev HS cfg. + if (spd == SL_USBD_DEVICE_SPEED_HIGH) { + config_nbr = p_dev->config_hs_total_nbr; + // Chk cfg limit. + if (config_nbr > SLI_USBD_CONFIG_NBR_TOT) { + CORE_EXIT_ATOMIC(); + *p_cfg_nbr = SL_USBD_CONFIG_NBR_NONE; + return SL_STATUS_ALLOCATION_FAILED; + } + p_dev->config_hs_total_nbr++; + } else { +#endif + // FS cfg. + config_nbr = p_dev->config_fs_total_nbr; + // Chk cfg limit. + if (config_nbr > SLI_USBD_CONFIG_NBR_TOT) { + CORE_EXIT_ATOMIC(); + *p_cfg_nbr = SL_USBD_CONFIG_NBR_NONE; + return SL_STATUS_ALLOCATION_FAILED; + } + p_dev->config_fs_total_nbr++; +#if (USBD_CFG_HS_EN == 1) +} +#endif + usbd_ptr->config_nbr_next--; + + // Configuration Structure Initialization + p_config = &usbd_ptr->config_table[config_tbl_ix]; + + // Link cfg into dev struct. +#if (USBD_CFG_OPTIMIZE_SPD == 1) + CORE_EXIT_ATOMIC(); + +#if (USBD_CFG_HS_EN == 1) + if (spd == SL_USBD_DEVICE_SPEED_HIGH) { + p_dev->config_hs_speed_table_ptrs[config_nbr] = p_config; + // Set spd bit in cfg nbr. + SL_SET_BIT(config_nbr, SL_USBD_CONFIG_NBR_SPD_BIT); + } else { +#endif + p_dev->config_fs_speed_table_ptrs[config_nbr] = p_config; +#if (USBD_CFG_HS_EN == 1) +} +#endif + +#else + p_config->next_ptr = NULL; + +#if (USBD_CFG_HS_EN == 1) + if (spd == SL_USBD_DEVICE_SPEED_HIGH) { + // Link cfg in HS list. + if (p_dev->config_hs_head_ptr == NULL) { + p_dev->config_hs_head_ptr = p_config; + p_dev->config_hs_tail_ptr = p_config; + } else { + p_dev->config_hs_tail_ptr->next_ptr = p_config; + p_dev->config_hs_tail_ptr = p_config; + } + // Set spd bit in cfg nbr. + SL_SET_BIT(config_nbr, SL_USBD_CONFIG_NBR_SPD_BIT); + } else { +#endif + // Link cfg in FS list. + if (p_dev->config_fs_head_ptr == NULL) { + p_dev->config_fs_head_ptr = p_config; + p_dev->config_fs_tail_ptr = p_config; + } else { + p_dev->config_fs_tail_ptr->next_ptr = p_config; + p_dev->config_fs_tail_ptr = p_config; + } +#if (USBD_CFG_HS_EN == 1) +} +#endif + CORE_EXIT_ATOMIC(); +#endif + +#if (USBD_CFG_STR_EN == 1) + p_config->name_ptr = p_name; +#endif + + p_config->attrib = attrib; + // Init EP alloc bitmap. + p_config->endpoint_alloc_map = SLI_USBD_ENDPOINT_CTRL_ALLOC; + p_config->max_power = max_pwr; + // Init cfg desc len. + p_config->desc_len = 0u; + +#if (USBD_CFG_STR_EN == 1) + // Add cfg string to dev. + status = usbd_core_add_string(p_dev, p_name); + if (status != SL_STATUS_OK) { + *p_cfg_nbr = SL_USBD_CONFIG_NBR_NONE; + return status; + } +#else + (void)&p_name; +#endif + + *p_cfg_nbr = config_nbr; + return SL_STATUS_OK; +} + +/****************************************************************************************************//** + * Associate a configuration with its alternative-speed counterpart + *******************************************************************************************************/ +#if (USBD_CFG_HS_EN == 1) +sl_status_t sl_usbd_core_associate_other_speed_configuration(uint8_t config_nbr, + uint8_t config_other) +{ + sli_usbd_device_t *p_dev; + sli_usbd_configuration_t *p_config; + sli_usbd_configuration_t *p_config_other; + + // Get dev struct. + p_dev = &usbd_ptr->device; + + // Chk curr dev state. + if ((p_dev->state != SL_USBD_DEVICE_STATE_NONE) + && (p_dev->state != SL_USBD_DEVICE_STATE_INIT)) { + return SL_STATUS_INVALID_STATE; + } + + // Chk if both cfg are from same spd. + if (((config_nbr & SL_USBD_CONFIG_NBR_SPD_BIT) ^ (config_other & SL_USBD_CONFIG_NBR_SPD_BIT)) != SL_USBD_CONFIG_NBR_SPD_BIT) { + return SL_STATUS_INVALID_PARAMETER; + } + + p_config = usbd_core_get_configuration_structure(p_dev, config_nbr); + + if (p_config == NULL) { + return SL_STATUS_INVALID_PARAMETER; + } + + p_config_other = usbd_core_get_configuration_structure(p_dev, config_other); + + if (p_config_other == NULL) { + return SL_STATUS_INVALID_PARAMETER; + } + + // Chk if cfg already associated. + if (!((p_config->config_other_speed == SL_USBD_CONFIG_NBR_NONE) + && (p_config_other->config_other_speed == SL_USBD_CONFIG_NBR_NONE))) { + return SL_STATUS_INVALID_PARAMETER; + } + + p_config->config_other_speed = config_other; + p_config_other->config_other_speed = config_nbr; + + return SL_STATUS_OK; +} +#endif + +/****************************************************************************************************//** + * Gets the current device state + *******************************************************************************************************/ +sl_status_t sl_usbd_core_get_device_state(sl_usbd_device_state_t *p_dev_state) +{ + sli_usbd_device_t *p_dev; + + if (p_dev_state == NULL) { + return SL_STATUS_INVALID_PARAMETER; + } + + // Get dev struct. + p_dev = &usbd_ptr->device; + + *p_dev_state = p_dev->state; + + return SL_STATUS_OK; +} + +/****************************************************************************************************//** + * Get device speed + *******************************************************************************************************/ +sl_status_t sl_usbd_core_get_device_speed(sl_usbd_device_speed_t *p_dev_speed) +{ + sli_usbd_device_t *p_dev; + + if (p_dev_speed == NULL) { + return SL_STATUS_INVALID_PARAMETER; + } + + // Get dev struct. + p_dev = &usbd_ptr->device; + + if (p_dev->state == SL_USBD_DEVICE_STATE_NONE) { + *p_dev_speed = SL_USBD_DEVICE_SPEED_INVALID; + return SL_STATUS_INVALID_STATE; + } + + *p_dev_speed = p_dev->speed; + + return SL_STATUS_OK; +} + +/****************************************************************************************************//** + * Sets the device's current power source + *******************************************************************************************************/ +sl_status_t sl_usbd_core_set_device_self_power(bool self_pwr) +{ + sli_usbd_device_t *p_dev; + CORE_DECLARE_IRQ_STATE; + + // Get dev struct. + p_dev = &usbd_ptr->device; + + CORE_ENTER_ATOMIC(); + p_dev->self_power = self_pwr; + CORE_EXIT_ATOMIC(); + + return SL_STATUS_OK; +} + +/****************************************************************************************************//** + * Set the device's Microsoft vendor code + *******************************************************************************************************/ +#if (USBD_CFG_MS_OS_DESC_EN == 1) +sl_status_t sl_usbd_core_set_device_microsoft_vendor_code(uint8_t vendor_code) +{ + sli_usbd_device_t *p_dev; + CORE_DECLARE_IRQ_STATE; + + // Get dev struct. + p_dev = &usbd_ptr->device; + + CORE_ENTER_ATOMIC(); + p_dev->str_microsoft_vendor_code = vendor_code; + CORE_EXIT_ATOMIC(); + + return SL_STATUS_OK; +} +#endif + +/****************************************************************************************************//** + * Get device configuration + *******************************************************************************************************/ +sl_status_t sl_usbd_core_get_device_configuration(sl_usbd_device_config_t **p_dev_cfg) +{ + sli_usbd_device_t *p_dev; + + if (p_dev_cfg == NULL) { + return SL_STATUS_INVALID_PARAMETER; + } + + // Get dev struct. + p_dev = &usbd_ptr->device; + + *p_dev_cfg = &p_dev->device_config; + + return SL_STATUS_OK; +} + +/****************************************************************************************************//** + * Gets the last frame number from the driver + *******************************************************************************************************/ +sl_status_t sl_usbd_core_get_device_frame_number(uint16_t *p_frame_nbr) +{ + sli_usbd_device_t *p_dev; + + if (p_frame_nbr == NULL) { + return SL_STATUS_INVALID_PARAMETER; + } + + // Get dev struct. + p_dev = &usbd_ptr->device; + + if (p_dev->state == SL_USBD_DEVICE_STATE_NONE) { + *p_frame_nbr = 0; + return SL_STATUS_INVALID_STATE; + } + + sli_usbd_driver_get_frame_number(p_frame_nbr); + + return SL_STATUS_OK; +} + +/****************************************************************************************************//** + * Adds an interface to a specific configuration + *******************************************************************************************************/ +sl_status_t sl_usbd_core_add_interface(uint8_t cfg_nbr, + sl_usbd_class_driver_t *p_class_drv, + void *p_if_class_arg, + void *p_if_alt_class_arg, + uint8_t class_code, + uint8_t class_sub_code, + uint8_t class_protocol_code, + const char *p_name, + uint8_t *p_if_nbr) +{ + uint8_t if_tbl_ix; + uint8_t if_nbr; + uint8_t if_alt_nbr; + sli_usbd_device_t *p_dev; + sli_usbd_configuration_t *p_config; + sli_usbd_interface_t *p_if; + sli_usbd_alt_interface_t *p_if_alt; + sl_status_t status; + CORE_DECLARE_IRQ_STATE; + + if (p_if_nbr == NULL) { + return SL_STATUS_NULL_POINTER; + } + + if (p_class_drv == NULL) { + *p_if_nbr = SL_USBD_INTERFACE_NBR_NONE; + return SL_STATUS_NULL_POINTER; + } + + // Chk if interface_descriptor() & interface_get_descriptor_size() are present or not. + if (!(((p_class_drv->interface_descriptor == NULL) && (p_class_drv->interface_get_descriptor_size == NULL)) + || ((p_class_drv->interface_descriptor != NULL) && (p_class_drv->interface_get_descriptor_size != NULL)))) { + *p_if_nbr = SL_USBD_INTERFACE_NBR_NONE; + return SL_STATUS_NULL_POINTER; + } + + // Chk if endpoint_descriptor() & endpoint_get_descriptor_size() are present or not. + if (!(((p_class_drv->endpoint_descriptor == NULL) && (p_class_drv->endpoint_get_descriptor_size == NULL)) + || ((p_class_drv->endpoint_descriptor != NULL) && (p_class_drv->endpoint_get_descriptor_size != NULL)))) { + *p_if_nbr = SL_USBD_INTERFACE_NBR_NONE; + return SL_STATUS_NULL_POINTER; + } + + // Get dev struct. + p_dev = &usbd_ptr->device; + +// [NF_CHANGE] +// Chk curr dev state. +// { +// if ((p_dev->state != SL_USBD_DEVICE_STATE_NONE) && (p_dev->state != SL_USBD_DEVICE_STATE_INIT)) { +// *p_if_nbr = SL_USBD_INTERFACE_NBR_NONE; +// return SL_STATUS_INVALID_STATE; +// } +// [END_NF_CHANGE] + + // Get cfg struct. + p_config = usbd_core_get_configuration_structure(p_dev, cfg_nbr); + + if (p_config == NULL) { + *p_if_nbr = SL_USBD_INTERFACE_NBR_NONE; + return SL_STATUS_INVALID_PARAMETER; + } + + CORE_ENTER_ATOMIC(); + // Chk if IF struct is avail. + if (usbd_ptr->interface_next == 0u) { + CORE_EXIT_ATOMIC(); + *p_if_nbr = SL_USBD_INTERFACE_NBR_NONE; + return SL_STATUS_ALLOCATION_FAILED; + } + if_tbl_ix = usbd_ptr->interface_next - 1u; + + // Chk if IF alt struct is avail. + if (usbd_ptr->alt_interface_nbr_next == 0u) { + CORE_EXIT_ATOMIC(); + *p_if_nbr = SL_USBD_INTERFACE_NBR_NONE; + return SL_STATUS_ALLOCATION_FAILED; + } + if_alt_nbr = usbd_ptr->alt_interface_nbr_next - 1u; + + // Get next IF nbr in cfg. + if_nbr = p_config->interface_nbr_total; + // Chk IF limit. + if (if_nbr > SLI_USBD_INTERFACE_NBR_TOT) { + CORE_EXIT_ATOMIC(); + *p_if_nbr = SL_USBD_INTERFACE_NBR_NONE; + return SL_STATUS_ALLOCATION_FAILED; + } + + usbd_ptr->interface_next--; + usbd_ptr->alt_interface_nbr_next--; + p_config->interface_nbr_total++; + + p_if = &usbd_ptr->interface_table[if_tbl_ix]; + // Get IF alt struct (see Note #1). + p_if_alt = &usbd_ptr->alt_interface_table[if_alt_nbr]; + + // Link IF and alt setting. +#if (USBD_CFG_OPTIMIZE_SPD == 1) + CORE_EXIT_ATOMIC(); + + p_config->interface_table_ptrs[if_nbr] = p_if; + p_if->alt_table_ptrs[0u] = p_if_alt; +#else + p_if->next_ptr = NULL; + p_if_alt->next_ptr = NULL; + p_if->alt_head_ptr = p_if_alt; + p_if->alt_tail_ptr = p_if_alt; + + if (p_config->interface_head_ptr == NULL) { + p_config->interface_head_ptr = p_if; + p_config->interface_tail_ptr = p_if; + } else { + p_config->interface_tail_ptr->next_ptr = p_if; + p_config->interface_tail_ptr = p_if; + } + CORE_EXIT_ATOMIC(); +#endif + + p_if->class_code = class_code; + p_if->class_sub_code = class_sub_code; + p_if->class_protocol_code = class_protocol_code; + p_if->class_driver_ptr = p_class_drv; + p_if->class_arg_ptr = p_if_class_arg; + p_if->endpoint_alloc_map = SLI_USBD_ENDPOINT_CTRL_ALLOC; + // Set curr alt setting. + p_if->alt_cur_ptr = p_if_alt; + p_if->alt_cur = 0u; + p_if->alt_nbr_total = 1u; + p_if_alt->endpoint_alloc_map = p_if->endpoint_alloc_map; + p_if_alt->class_arg_ptr = p_if_alt_class_arg; + +#if (USBD_CFG_STR_EN == 1) + p_if_alt->name_ptr = p_name; +#endif + + // Add IF string to dev. +#if (USBD_CFG_STR_EN == 1) + status = usbd_core_add_string(p_dev, p_name); + if (status != SL_STATUS_OK) { + *p_if_nbr = SL_USBD_INTERFACE_NBR_NONE; + return status; + } +#else + (void)&p_name; +#endif + + *p_if_nbr = if_nbr; + return SL_STATUS_OK; +} + +/****************************************************************************************************//** + * Adds an alternate setting to a specific interface + *******************************************************************************************************/ +sl_status_t sl_usbd_core_add_alt_interface(uint8_t config_nbr, + uint8_t if_nbr, + void *p_class_arg, + const char *p_name, + uint8_t *p_if_alt_nbr) +{ + sli_usbd_device_t *p_dev; + sli_usbd_configuration_t *p_config; + sli_usbd_interface_t *p_if; + sli_usbd_alt_interface_t *p_if_alt; + uint8_t if_alt_tbl_ix; + uint8_t if_alt_nbr; + sl_status_t status; + CORE_DECLARE_IRQ_STATE; + + if (p_if_alt_nbr == NULL) { + return SL_STATUS_NULL_POINTER; + } + + // Get Object References + + // Get dev struct. + p_dev = &usbd_ptr->device; + + // Get config struct. + p_config = usbd_core_get_configuration_structure(p_dev, config_nbr); + + if (p_config == NULL) { + *p_if_alt_nbr = SL_USBD_ALT_INTERFACE_NBR_NONE; + return SL_STATUS_INVALID_PARAMETER; + } + + // Get config struct. + p_if = usbd_core_get_interface_structure(p_config, if_nbr); + + if (p_if == NULL) { + *p_if_alt_nbr = SL_USBD_ALT_INTERFACE_NBR_NONE; + return SL_STATUS_INVALID_PARAMETER; + } + + CORE_ENTER_ATOMIC(); + // Chk if next alt setting is avail. + if (usbd_ptr->alt_interface_nbr_next == 0u) { + CORE_EXIT_ATOMIC(); + *p_if_alt_nbr = SL_USBD_ALT_INTERFACE_NBR_NONE; + return SL_STATUS_ALLOCATION_FAILED; + } + if_alt_tbl_ix = usbd_ptr->alt_interface_nbr_next - 1u; + + // Chk if alt setting is avail. + if_alt_nbr = p_if->alt_nbr_total; + if (if_alt_nbr > SLI_USBD_ALT_INTERFACE_NBR_TOT) { + CORE_EXIT_ATOMIC(); + *p_if_alt_nbr = SL_USBD_ALT_INTERFACE_NBR_NONE; + return SL_STATUS_ALLOCATION_FAILED; + } + + usbd_ptr->alt_interface_nbr_next--; + p_if->alt_nbr_total++; + + p_if_alt = &usbd_ptr->alt_interface_table[if_alt_tbl_ix]; + + // Add alt setting to IF. +#if (USBD_CFG_OPTIMIZE_SPD == 1) + CORE_EXIT_ATOMIC(); + + p_if->alt_table_ptrs[if_alt_nbr] = p_if_alt; +#else + p_if_alt->next_ptr = NULL; + + p_if->alt_tail_ptr->next_ptr = p_if_alt; + p_if->alt_tail_ptr = p_if_alt; + CORE_EXIT_ATOMIC(); +#endif + + p_if_alt->class_arg_ptr = p_class_arg; + p_if_alt->endpoint_alloc_map = SLI_USBD_ENDPOINT_CTRL_ALLOC; + +#if (USBD_CFG_STR_EN == 1) + p_if_alt->name_ptr = p_name; +#endif + + p_if_alt->endpoint_alloc_map &= ~p_if->endpoint_alloc_map; + p_if_alt->endpoint_alloc_map |= SLI_USBD_ENDPOINT_CTRL_ALLOC; + +#if (USBD_CFG_STR_EN == 1) + // Add alt setting string to dev. + status = usbd_core_add_string(p_dev, p_name); + if (status != SL_STATUS_OK) { + *p_if_alt_nbr = SL_USBD_ALT_INTERFACE_NBR_NONE; + return status; + } +#else + (void)&p_name; +#endif + + *p_if_alt_nbr = if_alt_nbr; + return SL_STATUS_OK; +} + +/****************************************************************************************************//** + * Creates an interface group + *******************************************************************************************************/ +sl_status_t sl_usbd_core_add_interface_group(uint8_t config_nbr, + uint8_t class_code, + uint8_t class_sub_code, + uint8_t class_protocol_code, + uint8_t if_start, + uint8_t if_cnt, + const char *p_name, + uint8_t *p_if_grp_num) +{ + sli_usbd_device_t *p_dev; + sli_usbd_configuration_t *p_config; + sli_usbd_interface_t *p_if; + sli_usbd_interface_group_t *p_if_grp; + uint8_t if_grp_tbl_ix; + uint8_t if_grp_nbr; + uint8_t if_nbr; + uint8_t if_end; + sl_status_t status; + CORE_DECLARE_IRQ_STATE; + + if (p_if_grp_num == NULL) { + return SL_STATUS_NULL_POINTER; + } + + if (((uint16_t)(if_start) + (uint16_t)(if_cnt)) > (uint16_t)SLI_USBD_INTERFACE_NBR_TOT) { + *p_if_grp_num = SL_USBD_INTERFACE_GROUP_NBR_NONE; + return SL_STATUS_INVALID_PARAMETER; + } + + // Get Object References + + // Get dev struct. + p_dev = &usbd_ptr->device; + + // Get cfg struct. + p_config = usbd_core_get_configuration_structure(p_dev, config_nbr); + + if (p_config == NULL) { + *p_if_grp_num = SL_USBD_INTERFACE_GROUP_NBR_NONE; + return SL_STATUS_INVALID_PARAMETER; + } + + // Verify that IFs do NOT belong to another group. + for (if_nbr = 0u; if_nbr < if_cnt; if_nbr++) { + p_if = usbd_core_get_interface_structure(p_config, if_nbr + if_start); + + if (p_if == NULL) { + *p_if_grp_num = SL_USBD_INTERFACE_GROUP_NBR_NONE; + return SL_STATUS_INVALID_PARAMETER; + } + + if (p_if->group_nbr != SL_USBD_INTERFACE_GROUP_NBR_NONE) { + *p_if_grp_num = SL_USBD_INTERFACE_GROUP_NBR_NONE; + return SL_STATUS_ALREADY_EXISTS; + } + } + + CORE_ENTER_ATOMIC(); + + // Chk if IF grp is avail. + if (usbd_ptr->interface_group_nbr_next == 0u) { + CORE_EXIT_ATOMIC(); + *p_if_grp_num = SL_USBD_INTERFACE_GROUP_NBR_NONE; + return SL_STATUS_ALLOCATION_FAILED; + } + usbd_ptr->interface_group_nbr_next--; + if_grp_tbl_ix = usbd_ptr->interface_group_nbr_next; + + p_if_grp = &usbd_ptr->interface_group_table[if_grp_tbl_ix]; + +#if (USBD_CFG_OPTIMIZE_SPD == 1) + if_grp_nbr = p_config->interface_group_nbr_total; + p_config->interface_group_nbr_total++; + CORE_EXIT_ATOMIC(); + + p_config->interface_group_table_ptrs[if_grp_nbr] = p_if_grp; +#else + p_if_grp->next_ptr = NULL; + + if_grp_nbr = p_config->interface_group_nbr_total; + p_config->interface_group_nbr_total++; + + if (if_grp_nbr == 0u) { + p_config->interface_group_head_ptr = p_if_grp; + p_config->interface_group_tail_ptr = p_if_grp; + } else { + p_config->interface_group_tail_ptr->next_ptr = p_if_grp; + p_config->interface_group_tail_ptr = p_if_grp; + } + CORE_EXIT_ATOMIC(); +#endif + + p_if_grp->class_code = class_code; + p_if_grp->class_sub_code = class_sub_code; + p_if_grp->class_protocol_code = class_protocol_code; + p_if_grp->interface_start = if_start; + p_if_grp->interface_count = if_cnt; + +#if (USBD_CFG_STR_EN == 1) + p_if_grp->name_ptr = p_name; +#endif + + if_end = if_cnt + if_start; + for (if_nbr = if_start; if_nbr < if_end; if_nbr++) { + p_if = usbd_core_get_interface_structure(p_config, if_nbr); + + if (p_if == NULL) { + *p_if_grp_num = SL_USBD_INTERFACE_GROUP_NBR_NONE; + return SL_STATUS_INVALID_PARAMETER; + } + + if (p_if->group_nbr != SL_USBD_INTERFACE_GROUP_NBR_NONE) { + *p_if_grp_num = SL_USBD_INTERFACE_GROUP_NBR_NONE; + return SL_STATUS_ALREADY_EXISTS; + } + + CORE_ENTER_ATOMIC(); + p_if->group_nbr = if_grp_nbr; + CORE_EXIT_ATOMIC(); + } + +#if (USBD_CFG_STR_EN == 1) + // Add IF grp string to dev. + status = usbd_core_add_string(p_dev, p_name); + if (status != SL_STATUS_OK) { + *p_if_grp_num = SL_USBD_INTERFACE_GROUP_NBR_NONE; + return status; + } +#else + (void)&p_name; +#endif + + *p_if_grp_num = if_grp_nbr; + return SL_STATUS_OK; +} + +/****************************************************************************************************//** + * Gets the device descriptor + *******************************************************************************************************/ +sl_status_t sl_usbd_core_get_device_descriptor(uint8_t *p_buf, + uint8_t max_len, + uint8_t *p_desc_len) +{ + sli_usbd_device_t *p_dev; + sl_status_t status; + sl_status_t local_status; + + local_status = SL_STATUS_OK; + + if (p_desc_len == NULL) { + return SL_STATUS_NULL_POINTER; + } + + if (p_buf == NULL) { + *p_desc_len = 0; + return SL_STATUS_NULL_POINTER; + } + + if (max_len == 0) { + *p_desc_len = 0; + return SL_STATUS_INVALID_PARAMETER; + } + + // Get dev struct. + p_dev = &usbd_ptr->device; + + if (p_dev->state != SL_USBD_DEVICE_STATE_NONE) { + *p_desc_len = 0; + return SL_STATUS_INVALID_STATE; + } + + p_dev->actual_buf_ptr = p_buf; + p_dev->desc_buf_max_len = max_len; + p_dev->desc_buf_status_ptr = &local_status; + + status = usbd_core_send_device_descriptor(p_dev, false, max_len); + + p_dev->desc_buf_status_ptr = NULL; + + *p_desc_len = p_dev->desc_buf_index; + return status; +} + +/****************************************************************************************************//** + * Gets a configuration descriptor + *******************************************************************************************************/ +sl_status_t sl_usbd_core_get_configuration_descriptor(uint8_t *p_buf, + uint16_t max_len, + uint8_t config_ix, + uint16_t *p_desc_len) +{ + sli_usbd_device_t *p_dev; + sl_status_t local_status; + sl_status_t status; + + local_status = SL_STATUS_OK; + + if (p_desc_len == NULL) { + return SL_STATUS_NULL_POINTER; + } + + if (p_buf == NULL) { + *p_desc_len = 0; + return SL_STATUS_NULL_POINTER; + } + + if (max_len == 0) { + *p_desc_len = 0; + return SL_STATUS_INVALID_PARAMETER; + } + + // Get dev struct. + p_dev = &usbd_ptr->device; + + if (p_dev->state != SL_USBD_DEVICE_STATE_NONE) { + *p_desc_len = 0; + return SL_STATUS_INVALID_STATE; + } + + p_dev->actual_buf_ptr = p_buf; + p_dev->desc_buf_max_len = max_len; + p_dev->desc_buf_status_ptr = &local_status; + + status = usbd_core_send_configuration_descriptor(p_dev, config_ix, false, max_len); + + p_dev->desc_buf_status_ptr = NULL; + + *p_desc_len = p_dev->desc_buf_index; + return status; +} + +/****************************************************************************************************//** + * Get a string descriptor + *******************************************************************************************************/ +#if (USBD_CFG_STR_EN == 1) +sl_status_t sl_usbd_core_get_string_descriptor(uint8_t *p_buf, + uint8_t max_len, + uint8_t str_ix, + uint8_t *p_desc_len) +{ + sli_usbd_device_t *p_dev; + sl_status_t local_status; + sl_status_t status; + + local_status = SL_STATUS_OK; + + if (p_desc_len == NULL) { + return SL_STATUS_NULL_POINTER; + } + + if (p_buf == NULL) { + *p_desc_len = 0; + return SL_STATUS_NULL_POINTER; + } + + if (max_len == 0) { + *p_desc_len = 0; + return SL_STATUS_INVALID_PARAMETER; + } + + // Get dev struct. + p_dev = &usbd_ptr->device; + + if (p_dev->state != SL_USBD_DEVICE_STATE_NONE) { + *p_desc_len = 0; + return SL_STATUS_INVALID_STATE; + } + + p_dev->actual_buf_ptr = p_buf; + p_dev->desc_buf_max_len = max_len; + p_dev->desc_buf_status_ptr = &local_status; + + status = usbd_core_send_string_descriptor(p_dev, str_ix, max_len); + + p_dev->desc_buf_status_ptr = NULL; + + *p_desc_len = p_dev->desc_buf_index; + return status; +} +#endif + +/****************************************************************************************************//** + * Add string to USB device + *******************************************************************************************************/ +#if (USBD_CFG_STR_EN == 1) +sl_status_t sl_usbd_core_add_string(const char *p_str) +{ + sli_usbd_device_t *p_dev; + + // Get dev struct. + p_dev = &usbd_ptr->device; + + // Chk curr dev state. + if ((p_dev->state != SL_USBD_DEVICE_STATE_NONE) + && (p_dev->state != SL_USBD_DEVICE_STATE_INIT)) { + return SL_STATUS_INVALID_STATE; + } + + return usbd_core_add_string(p_dev, p_str); +} +#endif + +/****************************************************************************************************//** + * Get string index corresponding to a given string + *******************************************************************************************************/ +#if (USBD_CFG_STR_EN == 1) +sl_status_t sl_usbd_core_get_string_index(const char *p_str, + uint8_t *p_str_ix) +{ + sli_usbd_device_t *p_dev; + + // Get dev struct. + p_dev = &usbd_ptr->device; + + *p_str_ix = usbd_core_get_string_index(p_dev, p_str); + + return SL_STATUS_OK; +} +#endif + +/****************************************************************************************************//** + * Writes an 8-bit value to the descriptor buffer + *******************************************************************************************************/ +sl_status_t sl_usbd_core_write_08b_to_descriptor_buf(uint8_t val) +{ + sli_usbd_device_t *p_dev; + sl_status_t status; + + // Get dev struct. + p_dev = &usbd_ptr->device; + + status = *(p_dev->desc_buf_status_ptr); + + if (status == SL_STATUS_OK) { + usbd_core_write_to_descriptor_buf(p_dev, &val, 1u); + } + + return status; +} + +/****************************************************************************************************//** + * Writes a 16-bit value in the descriptor buffer + *******************************************************************************************************/ +sl_status_t sl_usbd_core_write_16b_to_descriptor_buf(uint16_t val) +{ + sli_usbd_device_t *p_dev; + sl_status_t status; + + // Get dev struct. + p_dev = &usbd_ptr->device; + + status = *(p_dev->desc_buf_status_ptr); + + if (status == SL_STATUS_OK) { + uint8_t buf[2u]; + + buf[0u] = (uint8_t)(val & 0xFFu); + buf[1u] = (uint8_t)((val >> 8u) & 0xFFu); + + usbd_core_write_to_descriptor_buf(p_dev, &buf[0u], 2u); + } + + return status; +} + +/****************************************************************************************************//** + * Writes a 24-bit value to the descriptor buffer + *******************************************************************************************************/ +sl_status_t sl_usbd_core_write_24b_to_descriptor_buf(uint32_t val) +{ + sli_usbd_device_t *p_dev; + sl_status_t status; + + // Get dev struct. + p_dev = &usbd_ptr->device; + + status = *(p_dev->desc_buf_status_ptr); + + if (status == SL_STATUS_OK) { + uint8_t buf[3u]; + + buf[0u] = (uint8_t)(val & 0xFFu); + buf[1u] = (uint8_t)((val >> 8u) & 0xFFu); + buf[2u] = (uint8_t)((val >> 16u) & 0xFFu); + + usbd_core_write_to_descriptor_buf(p_dev, &buf[0u], 3u); + } + + return status; +} + +/****************************************************************************************************//** + * Writes a 24-bit value to the descriptor buffer + *******************************************************************************************************/ +sl_status_t sl_usbd_core_write_32b_to_descriptor_buf(uint32_t val) +{ + sli_usbd_device_t *p_dev; + sl_status_t status; + + // Get dev struct. + p_dev = &usbd_ptr->device; + + status = *(p_dev->desc_buf_status_ptr); + + if (status == SL_STATUS_OK) { + uint8_t buf[4u]; + + buf[0u] = (uint8_t)(val & 0xFFu); + buf[1u] = (uint8_t)((val >> 8u) & 0xFFu); + buf[2u] = (uint8_t)((val >> 16u) & 0xFFu); + buf[3u] = (uint8_t)((val >> 24u) & 0xFFu); + + usbd_core_write_to_descriptor_buf(p_dev, &buf[0u], 4u); + } + + return status; +} + +/****************************************************************************************************//** + * Writes a buffer into the descriptor buffer + *******************************************************************************************************/ +sl_status_t sl_usbd_core_write_buf_to_descriptor_buf(const uint8_t *p_buf, + uint16_t len) +{ + sli_usbd_device_t *p_dev; + sl_status_t status; + + // Get dev struct. + p_dev = &usbd_ptr->device; + + if ((p_buf == NULL) || (len == 0u)) { + return SL_STATUS_INVALID_PARAMETER; + } + + status = *(p_dev->desc_buf_status_ptr); + + if (status == SL_STATUS_OK) { + usbd_core_write_to_descriptor_buf(p_dev, p_buf, len); + } + + return status; +} + +/****************************************************************************************************//** + * Adds a bulk endpoint to alternate setting interface + *******************************************************************************************************/ +sl_status_t sl_usbd_core_add_bulk_endpoint(uint8_t config_nbr, + uint8_t if_nbr, + uint8_t if_alt_nbr, + bool dir_in, + uint16_t max_pkt_len, + uint8_t *p_ep_addr) +{ + if (p_ep_addr == NULL) { + return SL_STATUS_NULL_POINTER; + } + +#if (USBD_CFG_HS_EN == 1) + // Chk EP size. + // SL_USBD_CONFIG_NBR_SPD_BIT will always be clear in FS. + if (((max_pkt_len != 0u) && (max_pkt_len != 512u)) + && (SL_IS_BIT_SET(config_nbr, SL_USBD_CONFIG_NBR_SPD_BIT))) { + *p_ep_addr = SL_USBD_ENDPOINT_ADDR_NONE; + return SL_STATUS_INVALID_PARAMETER; + } +#endif + +#if (USBD_CFG_HS_EN == 1) + if (((max_pkt_len != 0u) + && (max_pkt_len != 8u) + && (max_pkt_len != 16u) + && (max_pkt_len != 32u) + && (max_pkt_len != 64u)) + && (SL_IS_BIT_CLEAR(config_nbr, SL_USBD_CONFIG_NBR_SPD_BIT) == true)) { +#else + if ( (max_pkt_len != 0u) + && (max_pkt_len != 8u) + && (max_pkt_len != 16u) + && (max_pkt_len != 32u) + && (max_pkt_len != 64u)) { +#endif + *p_ep_addr = SL_USBD_ENDPOINT_ADDR_NONE; + return SL_STATUS_INVALID_PARAMETER; + } + + return usbd_core_add_endpoint(config_nbr, + if_nbr, + if_alt_nbr, + SL_USBD_ENDPOINT_TYPE_BULK, + dir_in, + max_pkt_len, + 0u, + p_ep_addr); +} + +/****************************************************************************************************//** + * Adds an interrupt endpoint to an alternate setting interface + *******************************************************************************************************/ +sl_status_t sl_usbd_core_add_interrupt_endpoint(uint8_t config_nbr, + uint8_t if_nbr, + uint8_t if_alt_nbr, + bool dir_in, + uint16_t max_pkt_len, + uint16_t interval, + uint8_t *p_ep_addr) +{ + uint8_t interval_code; + + if (p_ep_addr == NULL) { + return SL_STATUS_NULL_POINTER; + } + + if (interval == 0u) { + *p_ep_addr = SL_USBD_ENDPOINT_NBR_NONE; + return SL_STATUS_INVALID_PARAMETER; + } + +#if (USBD_CFG_HS_EN == 1) + // Full spd validation. + // SL_USBD_CONFIG_NBR_SPD_BIT will always be clear in FS. + if (SL_IS_BIT_CLEAR(config_nbr, SL_USBD_CONFIG_NBR_SPD_BIT) == true) { +#endif + if (max_pkt_len > 64u) { + *p_ep_addr = SL_USBD_ENDPOINT_NBR_NONE; + return SL_STATUS_INVALID_PARAMETER; + } + + if (interval < 255u) { + interval_code = (uint8_t)interval; + } else { + *p_ep_addr = SL_USBD_ENDPOINT_NBR_NONE; + return SL_STATUS_INVALID_PARAMETER; + } +#if (USBD_CFG_HS_EN == 1) +} else { + // High spd validation. + if (((if_alt_nbr == 0u) && (max_pkt_len > 64u)) || (max_pkt_len > 1024u)) { + *p_ep_addr = SL_USBD_ENDPOINT_NBR_NONE; + return SL_STATUS_INVALID_PARAMETER; + } + + // See Note #2. + if (interval > SL_USBD_ENDPOINT_MAX_INTERVAL_VAL) { + *p_ep_addr = SL_USBD_ENDPOINT_NBR_NONE; + return SL_STATUS_INVALID_PARAMETER; + } + + // interval must be a power of 2. + if (SLI_USBD_IS_PWR2(interval) == false) { + *p_ep_addr = SL_USBD_ENDPOINT_NBR_NONE; + return SL_STATUS_INVALID_PARAMETER; + } + // Compute bInterval exponent in 2^(bInterval-1). + interval_code = (uint8_t)(32u - __CLZ(interval)); + + if (interval_code > 16u) { + *p_ep_addr = SL_USBD_ENDPOINT_NBR_NONE; + return SL_STATUS_INVALID_PARAMETER; + } +} +#endif + + return usbd_core_add_endpoint(config_nbr, + if_nbr, + if_alt_nbr, + SL_USBD_ENDPOINT_TYPE_INTR, + dir_in, + max_pkt_len, + interval_code, + p_ep_addr); +} + +/****************************************************************************************************//** + * Adds an isochronous endpoint to alternate setting interface + *******************************************************************************************************/ +#if (USBD_CFG_EP_ISOC_EN == 1) +sl_status_t sl_usbd_core_add_isochronous_endpoint(uint8_t config_nbr, + uint8_t if_nbr, + uint8_t if_alt_nbr, + bool dir_in, + uint8_t attrib, + uint16_t max_pkt_len, + uint8_t transaction_frame, + uint16_t interval, + uint8_t *p_ep_addr) +{ + uint16_t pkt_len; + uint8_t interval_code; + + if (p_ep_addr == NULL) { + return SL_STATUS_NULL_POINTER; + } + + // Chk if dflt IF setting with isoc EP max_pkt_len > 0. + if ((if_alt_nbr == 0u) && (max_pkt_len > 0u)) { + *p_ep_addr = SL_USBD_ENDPOINT_NBR_NONE; + return SL_STATUS_INVALID_PARAMETER; + } + + // Chk if sync & usage bits are used. + if ((attrib & (uint8_t)(~(SL_USBD_ENDPOINT_TYPE_SYNC_MASK | SL_USBD_ENDPOINT_TYPE_USAGE_MASK))) != 0u) { + *p_ep_addr = SL_USBD_ENDPOINT_NBR_NONE; + return SL_STATUS_INVALID_PARAMETER; + } + +#if (USBD_CFG_HS_EN == 1) + // Full spd validation. + // SL_USBD_CONFIG_NBR_SPD_BIT will always be clear in FS. + if (SL_IS_BIT_CLEAR(config_nbr, SL_USBD_CONFIG_NBR_SPD_BIT) == true) { +#endif + if (max_pkt_len > 1023u) { + *p_ep_addr = SL_USBD_ENDPOINT_NBR_NONE; + return SL_STATUS_INVALID_PARAMETER; + } + + if (transaction_frame != 1u) { + *p_ep_addr = SL_USBD_ENDPOINT_NBR_NONE; + return SL_STATUS_INVALID_PARAMETER; + } +#if (USBD_CFG_HS_EN == 1) +} else { + // High spd validation. + switch (transaction_frame) { + case 1u: + if (max_pkt_len > 1024u) { + *p_ep_addr = SL_USBD_ENDPOINT_NBR_NONE; + return SL_STATUS_INVALID_PARAMETER; + } + break; + + case 2u: + if ((max_pkt_len < 513u) || (max_pkt_len > 1024u)) { + *p_ep_addr = SL_USBD_ENDPOINT_NBR_NONE; + return SL_STATUS_INVALID_PARAMETER; + } + break; + + case 3u: + if ((max_pkt_len < 683u) || (max_pkt_len > 1024u)) { + *p_ep_addr = SL_USBD_ENDPOINT_NBR_NONE; + return SL_STATUS_INVALID_PARAMETER; + } + break; + + default: + *p_ep_addr = SL_USBD_ENDPOINT_NBR_NONE; + return SL_STATUS_INVALID_PARAMETER; + } +} +#endif + + // Explicit feedback EP must be set to no sync. + if (((attrib & SL_USBD_ENDPOINT_TYPE_USAGE_MASK) == SL_USBD_ENDPOINT_TYPE_USAGE_FEEDBACK) + && ((attrib & SL_USBD_ENDPOINT_TYPE_SYNC_MASK) != SL_USBD_ENDPOINT_TYPE_SYNC_NONE)) { + *p_ep_addr = SL_USBD_ENDPOINT_NBR_NONE; + return SL_STATUS_INVALID_PARAMETER; + } + + // See Note #3. + if (interval > SL_USBD_ENDPOINT_MAX_INTERVAL_VAL) { + *p_ep_addr = SL_USBD_ENDPOINT_NBR_NONE; + return SL_STATUS_INVALID_PARAMETER; + } + + // interval must be a power of 2. + if (SLI_USBD_IS_PWR2(interval) == false) { + *p_ep_addr = SL_USBD_ENDPOINT_NBR_NONE; + return SL_STATUS_INVALID_PARAMETER; + } + + // Compute bInterval exponent in 2^(bInterval-1). + interval_code = (uint8_t)(32u - __CLZ(interval)); + + if (interval_code > 16u) { + *p_ep_addr = SL_USBD_ENDPOINT_NBR_NONE; + return SL_STATUS_INVALID_PARAMETER; + } + + pkt_len = (transaction_frame - 1u) << 11u | max_pkt_len; + + return usbd_core_add_endpoint(config_nbr, + if_nbr, + if_alt_nbr, + SL_USBD_ENDPOINT_TYPE_ISOC | attrib, + dir_in, + pkt_len, + interval_code, + p_ep_addr); +} +#endif + +/****************************************************************************************************//** + * Set synchronization feedback rate on synchronization isochronous endpoint + *******************************************************************************************************/ +#if (USBD_CFG_EP_ISOC_EN == 1) +sl_status_t sl_usbd_core_set_isochronous_endpoint_refresh_rate(uint8_t config_nbr, + uint8_t if_nbr, + uint8_t if_alt_nbr, + uint8_t synch_ep_addr, + uint8_t sync_refresh) +{ + sli_usbd_device_t *p_dev; + sli_usbd_configuration_t *p_config; + sli_usbd_interface_t *p_if; + sli_usbd_alt_interface_t *p_if_alt; + sli_usbd_endpoint_info_t *p_ep; +#if (USBD_CFG_OPTIMIZE_SPD == 1) + uint32_t ep_alloc_map; +#endif + uint8_t ep_nbr; + bool found; + CORE_DECLARE_IRQ_STATE; + + // See Note #3. + if ((sync_refresh < 1u) || (sync_refresh > 9u)) { + return SL_STATUS_INVALID_PARAMETER; + } + + // Get Object References + + // Get dev struct. + p_dev = &usbd_ptr->device; + + // Chk curr dev state. + if ((p_dev->state != SL_USBD_DEVICE_STATE_NONE) + && (p_dev->state != SL_USBD_DEVICE_STATE_INIT)) { + return SL_STATUS_INVALID_STATE; + } + + // Get cfg struct. + p_config = usbd_core_get_configuration_structure(p_dev, config_nbr); + + if (p_config == NULL) { + return SL_STATUS_INVALID_PARAMETER; + } + + // Get IF struct. + p_if = usbd_core_get_interface_structure(p_config, if_nbr); + + if (p_if == NULL) { + return SL_STATUS_INVALID_PARAMETER; + } + + // Chk if audio class. + if (p_if->class_code != SL_USBD_CLASS_CODE_AUDIO) { + return SL_STATUS_INVALID_PARAMETER; + } + + // Chk if audio class, version 1.0. + if (p_if->class_protocol_code != 0u) { + return SL_STATUS_INVALID_PARAMETER; + } + + // Get IF alt setting struct. + p_if_alt = usbd_core_get_alt_interface_structure(p_if, if_alt_nbr); + + if (p_if_alt == NULL) { + return SL_STATUS_INVALID_PARAMETER; + } + + found = false; + p_ep = NULL; + +#if (USBD_CFG_OPTIMIZE_SPD == 1) + ep_alloc_map = p_if_alt->endpoint_table_map; + while ((ep_alloc_map != 0x00u) + && (found != true)) { + ep_nbr = (uint8_t)__CLZ(__RBIT(ep_alloc_map)); + p_ep = p_if_alt->endpoint_table_ptrs[ep_nbr]; + + if (p_ep->address == synch_ep_addr) { + found = true; + } + + SL_CLEAR_BIT(ep_alloc_map, SLI_USBD_SINGLE_BIT_MASK_32(ep_nbr)); + } +#else + p_ep = p_if_alt->endpoint_head_ptr; + + for (ep_nbr = 0u; ep_nbr < p_if_alt->endpoint_nbr_total; ep_nbr++) { + if (p_ep->address == synch_ep_addr) { + found = true; + break; + } + + p_ep = p_ep->next_ptr; + } +#endif + + if (found != true) { + return SL_STATUS_INVALID_HANDLE; + } + // Chk EP type attrib. + if ((p_ep->attrib & SL_USBD_ENDPOINT_TYPE_MASK) != SL_USBD_ENDPOINT_TYPE_ISOC) { + return SL_STATUS_INVALID_HANDLE; + } + + // Chk EP sync type attrib. + switch (p_ep->attrib & SL_USBD_ENDPOINT_TYPE_SYNC_MASK) { + case SL_USBD_ENDPOINT_TYPE_SYNC_NONE: + break; + + case SL_USBD_ENDPOINT_TYPE_SYNC_ASYNC: + case SL_USBD_ENDPOINT_TYPE_SYNC_ADAPTIVE: + case SL_USBD_ENDPOINT_TYPE_SYNC_SYNC: + default: + return SL_STATUS_INVALID_HANDLE; + } + + // Chk EP usage type attrib. + switch (p_ep->attrib & SL_USBD_ENDPOINT_TYPE_USAGE_MASK) { + case SL_USBD_ENDPOINT_TYPE_USAGE_FEEDBACK: + // See Note #4. + break; + + case SL_USBD_ENDPOINT_TYPE_USAGE_DATA: + case SL_USBD_ENDPOINT_TYPE_USAGE_IMPLICIT_FEEDBACK: + default: + return SL_STATUS_INVALID_HANDLE; + } + + // Chk associated sync EP addr. + if (p_ep->sync_addr != 0u) { + return SL_STATUS_INVALID_HANDLE; + } + + CORE_ENTER_ATOMIC(); + p_ep->sync_refresh = sync_refresh; + CORE_EXIT_ATOMIC(); + + return SL_STATUS_OK; +} +#endif + +/****************************************************************************************************//** + * Associates synchronization endpoint to isochronous endpoint + *******************************************************************************************************/ +#if (USBD_CFG_EP_ISOC_EN == 1) +sl_status_t sl_usbd_core_set_isochronous_endpoint_sync_address(uint8_t config_nbr, + uint8_t if_nbr, + uint8_t if_alt_nbr, + uint8_t data_ep_addr, + uint8_t sync_addr) +{ + sli_usbd_device_t *p_dev; + sli_usbd_configuration_t *p_config; + sli_usbd_interface_t *p_if; + sli_usbd_alt_interface_t *p_if_alt; + sli_usbd_endpoint_info_t *p_ep; + sli_usbd_endpoint_info_t *p_ep_isoc; +#if (USBD_CFG_OPTIMIZE_SPD == 1) + uint32_t ep_alloc_map; +#endif + uint8_t ep_nbr; + bool found_ep; + bool found_sync; + CORE_DECLARE_IRQ_STATE; + + // Get Object References + + // Get dev struct. + p_dev = &usbd_ptr->device; + + // Chk curr dev state. + if ((p_dev->state != SL_USBD_DEVICE_STATE_NONE) + && (p_dev->state != SL_USBD_DEVICE_STATE_INIT)) { + return SL_STATUS_INVALID_STATE; + } + + // Get cfg struct. + p_config = usbd_core_get_configuration_structure(p_dev, config_nbr); + + if (p_config == NULL) { + return SL_STATUS_INVALID_PARAMETER; + } + + // Get IF struct. + p_if = usbd_core_get_interface_structure(p_config, if_nbr); + + if (p_if == NULL) { + return SL_STATUS_INVALID_PARAMETER; + } + + // Chk if audio class. + if (p_if->class_code != SL_USBD_CLASS_CODE_AUDIO) { + return SL_STATUS_INVALID_PARAMETER; + } + + // Chk if audio class, version 1.0. + if (p_if->class_protocol_code != 0u) { + return SL_STATUS_INVALID_PARAMETER; + } + + // Get IF alt setting struct. + p_if_alt = usbd_core_get_alt_interface_structure(p_if, if_alt_nbr); + + if (p_if_alt == NULL) { + return SL_STATUS_INVALID_PARAMETER; + } + + found_ep = false; + found_sync = false; + p_ep_isoc = NULL; + +#if (USBD_CFG_OPTIMIZE_SPD == 1) + ep_alloc_map = p_if_alt->endpoint_table_map; + while ((ep_alloc_map != 0x00u) + && ((found_ep != true) + || (found_sync != true))) { + ep_nbr = (uint8_t)__CLZ(__RBIT(ep_alloc_map)); + p_ep = p_if_alt->endpoint_table_ptrs[ep_nbr]; + + if (p_ep->address == data_ep_addr) { + found_ep = true; + p_ep_isoc = p_ep; + } + + if (p_ep->address == sync_addr) { + found_sync = true; + } + + SL_CLEAR_BIT(ep_alloc_map, SLI_USBD_SINGLE_BIT_MASK_32(ep_nbr)); + } +#else + p_ep = p_if_alt->endpoint_head_ptr; + + for (ep_nbr = 0u; ep_nbr < p_if_alt->endpoint_nbr_total; ep_nbr++) { + if (p_ep->address == data_ep_addr) { + found_ep = true; + p_ep_isoc = p_ep; + } + + if (p_ep->address == sync_addr) { + found_sync = true; + } + + if ((found_ep == true) + && (found_sync == true)) { + break; + } + + p_ep = p_ep->next_ptr; + } +#endif + + if (found_ep != true) { + return SL_STATUS_INVALID_HANDLE; + } + + if (found_sync != true) { + return SL_STATUS_INVALID_PARAMETER; + } + // Chk EP type attrib. + if ((p_ep_isoc->attrib & SL_USBD_ENDPOINT_TYPE_MASK) != SL_USBD_ENDPOINT_TYPE_ISOC) { + return SL_STATUS_INVALID_HANDLE; + } + + // Chk EP sync type attrib. + switch (p_ep_isoc->attrib & SL_USBD_ENDPOINT_TYPE_SYNC_MASK) { + case SL_USBD_ENDPOINT_TYPE_SYNC_ASYNC: + if (SL_USBD_ENDPOINT_IS_IN(p_ep_isoc->address) == true) { + return SL_STATUS_INVALID_HANDLE; + } + break; + + case SL_USBD_ENDPOINT_TYPE_SYNC_ADAPTIVE: + if (SL_USBD_ENDPOINT_IS_IN(p_ep_isoc->address) == false) { + return SL_STATUS_INVALID_HANDLE; + } + break; + + case SL_USBD_ENDPOINT_TYPE_SYNC_NONE: + case SL_USBD_ENDPOINT_TYPE_SYNC_SYNC: + default: + return SL_STATUS_INVALID_HANDLE; + } + + // Chk EP usage type attrib. + switch (p_ep_isoc->attrib & SL_USBD_ENDPOINT_TYPE_USAGE_MASK) { + case SL_USBD_ENDPOINT_TYPE_USAGE_DATA: + break; + + case SL_USBD_ENDPOINT_TYPE_USAGE_FEEDBACK: + case SL_USBD_ENDPOINT_TYPE_USAGE_IMPLICIT_FEEDBACK: + default: + return SL_STATUS_INVALID_HANDLE; + } + + // Refresh interval must be set to zero. + if (p_ep_isoc->sync_refresh != 0u) { + return SL_STATUS_INVALID_HANDLE; + } + + CORE_ENTER_ATOMIC(); + p_ep_isoc->sync_addr = sync_addr; + CORE_EXIT_ATOMIC(); + + return SL_STATUS_OK; +} +#endif + +/****************************************************************************************************//** + * Gets the maximum physical endpoint number + *******************************************************************************************************/ +sl_status_t sl_usbd_core_get_max_phy_endpoint_number(uint8_t *p_ep_phy_nbr) +{ + sli_usbd_device_t *p_dev; + + if (p_ep_phy_nbr == NULL) { + return SL_STATUS_NULL_POINTER; + } + + // Get dev struct. + p_dev = &usbd_ptr->device; + + if (p_dev->endpoint_max_phy_nbr == 0u) { + *p_ep_phy_nbr = SL_USBD_ENDPOINT_PHY_NONE; + } else { + *p_ep_phy_nbr = p_dev->endpoint_max_phy_nbr - 1u; + } + + return SL_STATUS_OK; +} + +/******************************************************************************************************** + ******************************************************************************************************** + * INTERNAL FUNCTIONS + ******************************************************************************************************** + *******************************************************************************************************/ + +/****************************************************************************************************//** + * Notifies the USB connection bus events to the device stack + *******************************************************************************************************/ +sl_status_t sli_usbd_core_connect_event(void) +{ + usbd_core_set_event(SLI_USBD_EVENT_BUS_CONNECT); + return SL_STATUS_OK; +} + +/****************************************************************************************************//** + * Notifies the USB disconnection bus events to the device stack + *******************************************************************************************************/ +sl_status_t sli_usbd_core_disconnect_event(void) +{ + usbd_core_set_event(SLI_USBD_EVENT_BUS_DISCONNECT); + return SL_STATUS_OK; +} + +/****************************************************************************************************//** + * Notifies the USB High-Speed bus events to the device stack + *******************************************************************************************************/ +sl_status_t sli_usbd_core_high_speed_event(void) +{ + usbd_core_set_event(SLI_USBD_EVENT_BUS_HS); + return SL_STATUS_OK; +} + +/****************************************************************************************************//** + * Notifies the USB reset bus events to the device stack + *******************************************************************************************************/ +sl_status_t sli_usbd_core_reset_event(void) +{ + usbd_core_set_event(SLI_USBD_EVENT_BUS_RESET); + return SL_STATUS_OK; +} + +/****************************************************************************************************//** + * Notifies the USB suspend bus events to the device stack + *******************************************************************************************************/ +sl_status_t sli_usbd_core_suspend_event(void) +{ + usbd_core_set_event(SLI_USBD_EVENT_BUS_SUSPEND); + return SL_STATUS_OK; +} + +/****************************************************************************************************//** + * Notifies the USB resume bus events to the device stack + *******************************************************************************************************/ +sl_status_t sli_usbd_core_resume_event(void) +{ + usbd_core_set_event(SLI_USBD_EVENT_BUS_RESUME); + return SL_STATUS_OK; +} + +/****************************************************************************************************//** + * Sends a USB setup event to the core task + *******************************************************************************************************/ +sl_status_t sli_usbd_core_setup_event(void *p_buf) +{ + sli_usbd_device_t *p_dev; + sli_usbd_core_event_t core_event; + uint8_t *p_buf_08; + + // Get dev struct. + p_dev = &usbd_ptr->device; + + SLI_USBD_LOG_VRB(("USBD: Setup Pkt")); + + p_buf_08 = (uint8_t *)p_buf; + p_dev->setup_req_next.bmRequestType = p_buf_08[0u]; + p_dev->setup_req_next.bRequest = p_buf_08[1u]; + memcpy(&p_dev->setup_req_next.wValue, (p_buf_08 + 2u), 2u); + memcpy(&p_dev->setup_req_next.wIndex, (p_buf_08 + 4u), 2u); + memcpy(&p_dev->setup_req_next.wLength, (p_buf_08 + 6u), 2u); + + core_event.type = SLI_USBD_EVENT_SETUP; + + sli_usbd_core_os_put_core_event(&core_event); + + return SL_STATUS_OK; +} + +/****************************************************************************************************//** + * Sends a USB endpoint event to the core task + *******************************************************************************************************/ +sl_status_t sli_usbd_core_endpoint_event(uint8_t ep_addr, + sl_status_t status) +{ + sli_usbd_core_event_t core_event; + + core_event.type = SLI_USBD_EVENT_ENDPOINT; + core_event.endpoint_address = ep_addr; + core_event.status = status; + + // Queue core event. + sli_usbd_core_os_put_core_event(&core_event); + + return SL_STATUS_OK; +} + +/******************************************************************************************************** + ******************************************************************************************************** + * LOCAL FUNCTIONS + ******************************************************************************************************** + *******************************************************************************************************/ + +/****************************************************************************************************//** + * usbd_core_add_device() + * + * @brief Adds a device to the stack and creates the default control endpoints. + * + * @return Returns SL_STATUS_OK on success or another SL_STATUS code on failure. + *******************************************************************************************************/ +static sl_status_t usbd_core_add_device(void) +{ + sli_usbd_device_t *p_dev; + uint8_t ep_phy_nbr; + uint32_t ep_alloc_map; + sli_usbd_endpoint_info_t ep_info; + bool alloc; + sl_usbd_device_speed_t drv_spd; + sl_status_t status; + + sli_usbd_driver_get_speed(&drv_spd); + + // Initialize Device Structure + p_dev = &usbd_ptr->device; + p_dev->speed = drv_spd; + + // device configuration parameters from sl_usbd_device_config.h + p_dev->device_config.product_id = SL_USBD_DEVICE_PRODUCT_ID; + p_dev->device_config.vendor_id = SL_USBD_DEVICE_VENDOR_ID; + p_dev->device_config.device_bcd = SL_USBD_DEVICE_RELEASE_NUMBER; + p_dev->device_config.manufacturer_str_ptr = SL_USBD_DEVICE_MANUFACTURER_STRING; + p_dev->device_config.product_str_ptr = SL_USBD_DEVICE_PRODUCT_STRING; + p_dev->device_config.serial_nbr_str_ptr = SL_USBD_DEVICE_SERIAL_NUMBER_STRING; + p_dev->device_config.lang_id = SL_USBD_DEVICE_LANGUAGE_ID; + + ep_alloc_map = 0x00u; + + // Alloc physical EP for ctrl OUT. + usbd_core_allocate_endpoint(drv_spd, + SL_USBD_ENDPOINT_TYPE_CTRL, + false, + 0u, + 0u, + &ep_info, + &ep_alloc_map, + &alloc); + + if (alloc != true) { + return SL_STATUS_NOT_AVAILABLE; + } + + ep_phy_nbr = SL_USBD_ENDPOINT_ADDR_TO_PHY(ep_info.address); + ep_phy_nbr++; + + if (p_dev->endpoint_max_phy_nbr < ep_phy_nbr) { + p_dev->endpoint_max_phy_nbr = ep_phy_nbr; + } + + // Alloc physical EP for ctrl IN. + usbd_core_allocate_endpoint(drv_spd, + SL_USBD_ENDPOINT_TYPE_CTRL, + true, + 0u, + 0u, + &ep_info, + &ep_alloc_map, + &alloc); + + if (alloc != true) { + return SL_STATUS_NOT_AVAILABLE; + } + + p_dev->endpoint_max_ctrl_pkt_size = ep_info.max_pkt_size; + + ep_phy_nbr = SL_USBD_ENDPOINT_ADDR_TO_PHY(ep_info.address); + ep_phy_nbr++; + + if (p_dev->endpoint_max_phy_nbr < ep_phy_nbr) { + p_dev->endpoint_max_phy_nbr = ep_phy_nbr; + } + +#if (USBD_CFG_STR_EN == 1) + // Add device configuration strings: + + // Manufacturer string. + status = usbd_core_add_string(p_dev, + p_dev->device_config.manufacturer_str_ptr); + if (status != SL_STATUS_OK) { + return status; + } + + // Product string. + status = usbd_core_add_string(p_dev, + p_dev->device_config.product_str_ptr); + if (status != SL_STATUS_OK) { + return status; + } + + // Serial number string. + status = usbd_core_add_string(p_dev, + p_dev->device_config.serial_nbr_str_ptr); + if (status != SL_STATUS_OK) { + return status; + } +#endif + + status = sli_usbd_core_os_create_task(); + + return status; +} + +/****************************************************************************************************//** + * usbd_core_add_endpoint() + * + * @brief Add an endpoint to alternate setting interface. + * + * @param config_nbr Configuration number. + * + * @param if_nbr Interface number. + * + * @param if_alt_nbr Interface alternate setting number. + * + * @param attrib Endpoint's attributes. + * + * @param dir_in Endpoint Direction. + * + * @param max_pkt_len Endpoint maximum packet size. + * + * @param interval interval for polling data transfers. + * + * @param p_ep_addr Pointer to the variable that will receive endpoint address. + * + * @return Returns SL_STATUS_OK on success or another SL_STATUS code on failure. + * + *******************************************************************************************************/ +static sl_status_t usbd_core_add_endpoint(uint8_t config_nbr, + uint8_t if_nbr, + uint8_t if_alt_nbr, + uint8_t attrib, + bool dir_in, + uint16_t max_pkt_len, + uint8_t interval, + uint8_t *p_ep_addr) + +{ + sli_usbd_device_t *p_dev; + sli_usbd_configuration_t *p_config; + sli_usbd_interface_t *p_if; + sli_usbd_alt_interface_t *p_if_alt; + sli_usbd_endpoint_info_t *p_ep; + uint8_t ep_type; + uint32_t ep_alloc_map; + uint32_t ep_alloc_map_clr; + uint8_t ep_nbr; + uint8_t ep_phy_nbr; + sl_usbd_device_speed_t dev_spd; + bool alloc; + CORE_DECLARE_IRQ_STATE; + + // Get Object References + + // Get dev struct. + p_dev = &usbd_ptr->device; + + // Get cfg struct. + p_config = usbd_core_get_configuration_structure(p_dev, config_nbr); + + if (p_config == NULL) { + *p_ep_addr = SL_USBD_ENDPOINT_NBR_NONE; + return SL_STATUS_INVALID_PARAMETER; + } + + // Get IF struct. + p_if = usbd_core_get_interface_structure(p_config, if_nbr); + + if (p_if == NULL) { + *p_ep_addr = SL_USBD_ENDPOINT_NBR_NONE; + return SL_STATUS_INVALID_PARAMETER; + } + + // Get IF alt setting struct. + p_if_alt = usbd_core_get_alt_interface_structure(p_if, if_alt_nbr); + + if (p_if_alt == NULL) { + *p_ep_addr = SL_USBD_ENDPOINT_NBR_NONE; + return SL_STATUS_INVALID_PARAMETER; + } + + CORE_ENTER_ATOMIC(); + // Chk if EP is avail. + if (usbd_ptr->endpoint_info_nbr_next == 0u) { + CORE_EXIT_ATOMIC(); + *p_ep_addr = SL_USBD_ENDPOINT_NBR_NONE; + return SL_STATUS_ALLOCATION_FAILED; + } + usbd_ptr->endpoint_info_nbr_next--; + ep_nbr = usbd_ptr->endpoint_info_nbr_next; + CORE_EXIT_ATOMIC(); + + ep_type = attrib & SL_USBD_ENDPOINT_TYPE_MASK; +#if (USBD_CFG_HS_EN == 1) + if (SL_IS_BIT_SET(config_nbr, SL_USBD_CONFIG_NBR_SPD_BIT) == true) { + dev_spd = SL_USBD_DEVICE_SPEED_HIGH; + } else { +#endif + dev_spd = SL_USBD_DEVICE_SPEED_FULL; +#if (USBD_CFG_HS_EN == 1) +} +#endif + + p_ep = &usbd_ptr->endpoint_info_table[ep_nbr]; + p_ep->interval = interval; + p_ep->attrib = attrib; + // Default sync addr is zero. + p_ep->sync_addr = 0u; + // Default feedback rate exponent is zero. + p_ep->sync_refresh = 0u; + + CORE_ENTER_ATOMIC(); + // Get cfg EP alloc bit map. + ep_alloc_map = p_config->endpoint_alloc_map; + // Clr EP already alloc'd in the IF. + ep_alloc_map &= ~p_if->endpoint_alloc_map; + ep_alloc_map |= p_if_alt->endpoint_alloc_map; + + ep_alloc_map_clr = ep_alloc_map; + + // Alloc physical EP. + usbd_core_allocate_endpoint(dev_spd, + ep_type, + dir_in, + // Mask out transactions per microframe. + max_pkt_len & 0x7FF, + if_alt_nbr, + p_ep, + &ep_alloc_map, + &alloc); + + if (alloc != true) { + CORE_EXIT_ATOMIC(); + *p_ep_addr = SL_USBD_ENDPOINT_NBR_NONE; + return SL_STATUS_NOT_AVAILABLE; + } + + // Set transactions per microframe. + p_ep->max_pkt_size |= max_pkt_len & 0x1800; + + ep_phy_nbr = SL_USBD_ENDPOINT_ADDR_TO_PHY(p_ep->address); + ep_phy_nbr++; + + if (p_dev->endpoint_max_phy_nbr < ep_phy_nbr) { + p_dev->endpoint_max_phy_nbr = ep_phy_nbr; + } + + p_if_alt->endpoint_alloc_map |= ep_alloc_map & ~ep_alloc_map_clr; + p_if->endpoint_alloc_map |= p_if_alt->endpoint_alloc_map; + p_config->endpoint_alloc_map |= p_if->endpoint_alloc_map; + + p_if_alt->endpoint_nbr_total++; + +#if (USBD_CFG_OPTIMIZE_SPD == 1) + ep_nbr = SL_USBD_ENDPOINT_ADDR_TO_PHY(p_ep->address); + p_if_alt->endpoint_table_ptrs[ep_nbr] = p_ep; + SL_SET_BIT(p_if_alt->endpoint_table_map, SLI_USBD_SINGLE_BIT_MASK_32(ep_nbr)); +#else + p_ep->next_ptr = NULL; + if (p_if_alt->endpoint_head_ptr == NULL) { + p_if_alt->endpoint_head_ptr = p_ep; + p_if_alt->endpoint_tail_ptr = p_ep; + } else { + p_if_alt->endpoint_tail_ptr->next_ptr = p_ep; + p_if_alt->endpoint_tail_ptr = p_ep; + } +#endif + CORE_EXIT_ATOMIC(); + + *p_ep_addr = p_ep->address; + return SL_STATUS_OK; +} + +/****************************************************************************************************//** + * usbd_core_allocate_endpoint() + * + * @brief Allocate a physical endpoint from the device controller. + * + * @param spd Endpoint speed. + * - SL_USBD_DEVICE_SPEED_FULL Endpoint is full-speed. + * - SL_USBD_DEVICE_SPEED_HIGH Endpoint is high-speed. + * + * @param type Endpoint type. + * - SL_USBD_ENDPOINT_TYPE_CTRL Control endpoint. + * - SL_USBD_ENDPOINT_TYPE_ISOC Isochronous endpoint. + * - SL_USBD_ENDPOINT_TYPE_BULK Bulk endpoint. + * - SL_USBD_ENDPOINT_TYPE_INTR Interrupt endpoint. + * + * @param dir_in Endpoint direction. + * - true IN endpoint. + * - false OUT endpoint. + * + * @param max_pkt_len Endpoint maximum packet size length. + * + * @param if_alt_nbr Alternate interface number containing the endpoint. + * + * @param p_ep Pointer to the variable that will receive the endpoint parameters. + * + * @param ---- Argument validated in 'sl_usbd_core_add_device()' & 'usbd_core_add_endpoint()' + * + * @param p_alloc_bit_map Pointer to allocation table bit-map. + * + * @param --------------- Argument validated in 'sl_usbd_core_add_device()' & 'usbd_core_add_endpoint()' + * + * @param p_alloc Pointer to a boolean where function result will be returned. + * + * @return Returns SL_STATUS_OK on success or another SL_STATUS code on failure. + * + * @note (1) 'Universal Serial Bus Specification, Revision 2.0, April 27, 2000' Section 5.5.3 + * @n + * "An endpoint for control transfers specifies the maximum data payload size that + * the endpoint can accept from or transmit to the bus. The allowable maximum control + * transfer data payload sizes for full-speed devices is 8, 16, 32, or 64 bytes; for + * high-speed devices, it is 64 bytes and for low-speed devices, it is 8 bytes." + * @n + * "All Host Controllers are required to have support for 8-, 16-, 32-, and 64-byte + * maximum data payload sizes for full-speed control endpoints, only 8-byte maximum + * data payload sizes for low-speed control endpoints, and only 64-byte maximum data + * payload size for high-speed control endpoints" + *******************************************************************************************************/ +static sl_status_t usbd_core_allocate_endpoint(sl_usbd_device_speed_t spd, + uint8_t type, + bool dir_in, + uint16_t max_pkt_len, + uint8_t if_alt_nbr, + sli_usbd_endpoint_info_t *p_ep, + uint32_t *p_alloc_bit_map, + bool *p_alloc) +{ + sli_usbd_driver_endpoint_info_t *p_ep_tbl; + uint8_t ep_tbl_ix; + uint8_t ep_attrib; + uint8_t ep_attrib_srch; + uint8_t ep_max_pkt_bits; + uint16_t ep_max_pkt; + bool ep_found; + +#if (USBD_CFG_HS_EN == 0) + (void)&spd; + (void)&if_alt_nbr; +#endif + + if (dir_in == true) { + ep_attrib_srch = SL_USBD_ENDPOINT_INFO_DIR_IN; + } else { + ep_attrib_srch = SL_USBD_ENDPOINT_INFO_DIR_OUT; + } + + switch (type) { + case SL_USBD_ENDPOINT_TYPE_CTRL: + SL_SET_BIT(ep_attrib_srch, SL_USBD_ENDPOINT_INFO_TYPE_CTRL); + break; + + case SL_USBD_ENDPOINT_TYPE_ISOC: + SL_SET_BIT(ep_attrib_srch, SL_USBD_ENDPOINT_INFO_TYPE_ISOC); + break; + + case SL_USBD_ENDPOINT_TYPE_BULK: + SL_SET_BIT(ep_attrib_srch, SL_USBD_ENDPOINT_INFO_TYPE_BULK); + break; + + case SL_USBD_ENDPOINT_TYPE_INTR: + SL_SET_BIT(ep_attrib_srch, SL_USBD_ENDPOINT_INFO_TYPE_INTR); + break; + + default: + *p_alloc = false; + return SL_STATUS_OK; + } + + // Get ctrl EP info tbl. + sli_usbd_driver_get_endpoint_info(&p_ep_tbl); + // Get attrib for first entry. + ep_attrib = p_ep_tbl->attrib; + ep_tbl_ix = 0u; + ep_found = false; + + // Search until last entry or EP found. + while ((ep_attrib != 0x00u) + && (ep_found == false)) { + // Chk if EP not alloc'd and EP attrib match req'd attrib. + if ((SL_IS_BIT_CLEAR(*p_alloc_bit_map, SLI_USBD_SINGLE_BIT_MASK_32(ep_tbl_ix)) == true) + && (SL_IS_BIT_SET(ep_attrib, ep_attrib_srch) == true)) { + ep_max_pkt = p_ep_tbl[ep_tbl_ix].max_pkt_size; + + switch (type) { + // Chk ctrl transfer pkt size constrains. + case SL_USBD_ENDPOINT_TYPE_CTRL: + ep_max_pkt = SLI_USBD_GET_MIN(ep_max_pkt, 64u); + // Get next power of 2. + ep_max_pkt_bits = (uint8_t)(31u - __CLZ(ep_max_pkt)); + ep_max_pkt = SLI_USBD_SINGLE_BIT_MASK_16(ep_max_pkt_bits); +#if (USBD_CFG_HS_EN == 1) + if ((spd == SL_USBD_DEVICE_SPEED_HIGH) + && (ep_max_pkt != 64u)) { + break; + } + + if ((spd == SL_USBD_DEVICE_SPEED_HIGH) + && (ep_max_pkt < 8u)) { + break; + } +#endif + ep_found = true; + break; + + case SL_USBD_ENDPOINT_TYPE_BULK: +#if (USBD_CFG_HS_EN == 1) + // Max pkt size is 512 for bulk EP in HS. + ep_max_pkt = SLI_USBD_GET_MIN(ep_max_pkt, 512u); + if ((spd == SL_USBD_DEVICE_SPEED_HIGH) + && (ep_max_pkt == 512u)) { + ep_found = true; + break; + } +#endif + // Max pkt size is 64 for bulk EP in FS. + ep_max_pkt = SLI_USBD_GET_MIN(ep_max_pkt, 64u); + ep_max_pkt_bits = (uint8_t)(31u - __CLZ(ep_max_pkt)); + ep_max_pkt = SLI_USBD_SINGLE_BIT_MASK_16(ep_max_pkt_bits); +#if (USBD_CFG_HS_EN == 1) + if ((spd == SL_USBD_DEVICE_SPEED_HIGH) + && (ep_max_pkt >= 8u)) { + break; + } +#endif + ep_found = true; + break; + + case SL_USBD_ENDPOINT_TYPE_ISOC: +#if (USBD_CFG_HS_EN == 1) + if (spd == SL_USBD_DEVICE_SPEED_HIGH) { + ep_max_pkt = SLI_USBD_GET_MIN(ep_max_pkt, 1024u); + } else { +#endif + ep_max_pkt = SLI_USBD_GET_MIN(ep_max_pkt, 1023u); +#if (USBD_CFG_HS_EN == 1) + } +#endif + + if (max_pkt_len > 0u) { + ep_max_pkt = SLI_USBD_GET_MIN(ep_max_pkt, max_pkt_len); + } + + ep_found = true; + break; + + case SL_USBD_ENDPOINT_TYPE_INTR: +#if (USBD_CFG_HS_EN == 1) + if ((spd == SL_USBD_DEVICE_SPEED_HIGH) + && (if_alt_nbr != 0u)) { + // Dflt IF intr EP max pkt size limited to 64. + ep_max_pkt = SLI_USBD_GET_MIN(ep_max_pkt, 1024u); + } else { +#endif + ep_max_pkt = SLI_USBD_GET_MIN(ep_max_pkt, 64u); +#if (USBD_CFG_HS_EN == 1) + } +#endif + if (max_pkt_len > 0u) { + ep_max_pkt = SLI_USBD_GET_MIN(ep_max_pkt, max_pkt_len); + } + + ep_found = true; + break; + + default: + *p_alloc = false; + return SL_STATUS_OK; + } + + if ((ep_found == true) + && ((max_pkt_len == ep_max_pkt) + || (max_pkt_len == 0u))) { + p_ep->max_pkt_size = ep_max_pkt; + SL_SET_BIT(*p_alloc_bit_map, SLI_USBD_SINGLE_BIT_MASK_32(ep_tbl_ix)); + p_ep->address = p_ep_tbl[ep_tbl_ix].nbr; + if (dir_in == true) { + // Add dir bit (IN EP). + p_ep->address |= SL_USBD_ENDPOINT_DIR_IN; + } + } else { + ep_found = false; + ep_tbl_ix++; + ep_attrib = p_ep_tbl[ep_tbl_ix].attrib; + } + } else { + ep_tbl_ix++; + ep_attrib = p_ep_tbl[ep_tbl_ix].attrib; + } + } + + if (ep_found == false) { + *p_alloc = false; + return SL_STATUS_OK; + } + + *p_alloc = true; + return SL_STATUS_OK; +} + +/****************************************************************************************************//** + * usbd_core_stdreq_handler() + * + * @brief Standard request process. + * + * @param p_dev Pointer to USB device. + * + * @param ----- Argument validated in 'USBD_DevSetupPkt()' before posting the event to queue. + *******************************************************************************************************/ +static void usbd_core_stdreq_handler(sli_usbd_device_t *p_dev) +{ + uint8_t recipient; + uint8_t type; + uint8_t request; + bool valid; + bool dev_to_host; + sl_status_t local_status; + CORE_DECLARE_IRQ_STATE; + + local_status = SL_STATUS_OK; + +#if (USBD_CFG_MS_OS_DESC_EN != 1) + (void)&local_status; +#endif + + CORE_ENTER_ATOMIC(); + // Copy setup request. + p_dev->setup_req.bmRequestType = p_dev->setup_req_next.bmRequestType; + p_dev->setup_req.bRequest = p_dev->setup_req_next.bRequest; + p_dev->setup_req.wValue = p_dev->setup_req_next.wValue; + p_dev->setup_req.wIndex = p_dev->setup_req_next.wIndex; + p_dev->setup_req.wLength = p_dev->setup_req_next.wLength; + CORE_EXIT_ATOMIC(); + + recipient = p_dev->setup_req.bmRequestType & SL_USBD_REQ_RECIPIENT_MASK; + type = p_dev->setup_req.bmRequestType & SL_USBD_REQ_TYPE_MASK; + request = p_dev->setup_req.bRequest; + dev_to_host = SL_IS_BIT_SET(p_dev->setup_req.bmRequestType, SL_USBD_REQ_DIR_BIT); + valid = false; + + switch (type) { + case SL_USBD_REQ_TYPE_STANDARD: + // Select req recipient: + switch (recipient) { + case SL_USBD_REQ_RECIPIENT_DEVICE: + // Device. + valid = usbd_core_device_stdreq(p_dev, request); + break; + + case SL_USBD_REQ_RECIPIENT_INTERFACE: + // Interface. + valid = usbd_core_interface_stdreq(p_dev, request); + break; + + case SL_USBD_REQ_RECIPIENT_ENDPOINT: + // Endpoint. + valid = usbd_core_endpoint_stdreq(p_dev, request); + break; + + case SL_USBD_REQ_RECIPIENT_OTHER: + // Not supported. + default: + break; + } + break; + + case SL_USBD_REQ_TYPE_CLASS: + // Class-specific req. + switch (recipient) { + case SL_USBD_REQ_RECIPIENT_INTERFACE: + case SL_USBD_REQ_RECIPIENT_ENDPOINT: + // Class-specific req. + valid = usbd_core_class_stdreq(p_dev); + break; + + case SL_USBD_REQ_RECIPIENT_DEVICE: + case SL_USBD_REQ_RECIPIENT_OTHER: + default: + break; + } + break; + + case SL_USBD_REQ_TYPE_VENDOR: + switch (recipient) { + case SL_USBD_REQ_RECIPIENT_INTERFACE: +#if (USBD_CFG_MS_OS_DESC_EN == 1) + if (request == p_dev->str_microsoft_vendor_code) { + p_dev->desc_buf_status_ptr = &local_status; + // Microsoft OS descriptor req. + valid = usbd_core_microsoft_interface_stdreq(p_dev); + p_dev->desc_buf_status_ptr = NULL; + } else { + // Vendor-specific req. + valid = usbd_core_vendor_stdreq(p_dev); + } + break; +#endif + + case SL_USBD_REQ_RECIPIENT_ENDPOINT: + // Vendor-specific req. + valid = usbd_core_vendor_stdreq(p_dev); + break; + + case SL_USBD_REQ_RECIPIENT_DEVICE: +#if (USBD_CFG_MS_OS_DESC_EN == 1) + if (request == p_dev->str_microsoft_vendor_code) { + p_dev->desc_buf_status_ptr = &local_status; + // Microsoft OS descriptor req. + valid = usbd_core_microsoft_device_stdreq(p_dev); + p_dev->desc_buf_status_ptr = NULL; + } +#endif + break; + + case SL_USBD_REQ_RECIPIENT_OTHER: + default: + break; + } + break; + + case SL_USBD_REQ_TYPE_RESERVED: + default: + break; + } + + if (valid == false) { + SLI_USBD_LOG_DBG(("USBD: Request Error")); + sli_usbd_core_stall_control_endpoint(); + } else { + uint32_t std_req_timeout; + + CORE_ENTER_ATOMIC(); + std_req_timeout = usbd_ptr->std_req_timeout_ms; + CORE_EXIT_ATOMIC(); + + if (dev_to_host == true) { + SLI_USBD_LOG_VRB(("USBD: Rx Status")); + sli_usbd_core_get_control_rx_status(std_req_timeout); + } else { + SLI_USBD_LOG_VRB(("USBD: Tx Status")); + sli_usbd_core_get_control_tx_status(std_req_timeout); + } + } +} + +/****************************************************************************************************//** + * usbd_core_device_stdreq() + * + * @brief Process device standard request. + * + * @param p_dev Pointer to USB device. + * + * @param ----- Argument validated in 'USBD_DevSetupPkt()' before posting the event to queue. + * + * @param request USB device request. + * + * @return true, if no error(s) occurred and request is supported. + * false, if any errors are returned. + * + * @note (1) USB Spec 2.0, section 9.4.6 specifies the format of the SET_ADDRESS request. The + * SET_ADDRESS sets the device address for all future device access. + * - (a) The 'wValue' filed specify the device address to use for all subsequent accesses. + * - (b) If the specified device address is greater than 127 or if 'wIndex' or 'wLength' + * are non-zero, the behavior of the device is not specified. + * - (c) If the device is in the default state and the address specified is non-zero, + * the device shall enter the device address, otherwise the device remains in the + * default state' (this is not an error condition). + * - (d) If the device is in the address state and the address specified is zero, then + * the device shall enter the default state otherwise, the device remains in + * the address state but uses the newly-specified address. + * - (e) Device behavior when the SET_ADDRESS request is received while the device is not + * in the default or address state is not specified. + * - (f) USB Spec 2.0, section 9.2.6.3 specifies the maximum timeout for the SET_ADDRESS + * request: + * "After the reset/resume recovery interval, if a device receives a SetAddress() + * request, the device must be able to complete processing of the request and be + * able to successfully complete the Status stage of the request within 50 ms. In + * the case of the SetAddress() request, the Status stage successfully completes + * when the device sends the zero-length Status packet or when the device sees + * the ACK in response to the Status stage data packet." + * + * @note (2) USB Spec 2.0, section 9.4.7 specifies the format of the SET_CONFIGURATION request. + * - (a) The lower byte of 'wValue' field specifies the desired configuration. + * - (b) If 'wIndex', 'wLength', or the upper byte of wValue is non-zero, then the behavior + * of this request is not specified. + * - (c) The configuration value must be zero or match a configuration value from a + * configuration value from a configuration descriptor. If the configuration value + * is zero, the device is place in its address state. + * - (d) Device behavior when this request is received while the device is in the Default + * state is not specified. + * - (e) If device is in address state and the specified configuration value is zero, + * then the device remains in the Address state. If the specified configuration value + * matches the configuration value from a configuration descriptor, then that + * configuration is selected and the device enters the Configured state. Otherwise, + * the device responds with a Request Error. + * - (f) If the specified configuration value is zero, then the device enters the Address + * state. If the specified configuration value matches the configuration value from a + * configuration descriptor, then that configuration is selected and the device + * remains in the Configured state. Otherwise, the device responds with a Request + * Error. + * + * @note (3) USB Spec 2.0, section 9.4.2 specifies the format of the GET_CONFIGURATION request. + * - (a) If 'wValue' or 'wIndex' are non-zero or 'wLength' is not '1', then the device + * behavior is not specified. + * - (b) If the device is in default state, the device behavior is not specified. + * - (c) In address state a value of zero MUST be returned. + * - (d) In configured state, the non-zero bConfigurationValue of the current configuration + * must be returned. + * + * @note (4) USB Spec 2.0, section 9.4.5 specifies the format of the GET_STATUS request. + * - (a) If 'wValue' is non-zero or 'wLength is not equal to '2', or if wIndex is non-zero + * then the behavior of the device is not specified. + * - (b) USB Spec 2, 0, figure 9-4 shows the format of information returned by the device + * for a GET_STATUS request. + * @verbatim + * +====|====|====|====|====|====|====|========|=========+ + * | D0 | D1 | D2 | D3 | D4 | D3 | D2 | D1 | D0 | + * |----------------------------------|--------|---------| + * | RESERVED (RESET TO ZERO) | Remote | Self | + * | | Wakeup | Powered | + * +==================================|========|=========+ + * @endverbatim + * - (1) The Self Powered field indicates whether the device is currently self-powered. + * If D0 is reset to zero, the device is bus-powered. If D0 is set to one, the + * device is self-powered. The Self Powered field may not be changed by the + * SetFeature() or ClearFeature() requests. + * - (2) The Remote Wakeup field indicates whether the device is currently enabled to + * request remote wakeup. The default mode for devices that support remote wakeup + * is disabled. If D1 is reset to zero, the ability of the device to signal + * remote wakeup is disabled. If D1 is set to one, the ability of the device to + * signal remote wakeup is enabled. The Remote Wakeup field can be modified by + * the SetFeature() and ClearFeature() requests using the DEVICE_REMOTE_WAKEUP + * feature selector. This field is reset to zero when the device is reset. + * + * @note (5) USB Spec 2.0, section 9.4.1/9.4.9 specifies the format of the CLEAR_FEATURE/SET_FEATURE + * request. + * - (a) If 'wLength' or 'wIndex' are non-zero, then the device behavior is not specified. + * - (b) The device CLEAR_FEATURE request is only valid when the device is in the + * configured state. + *******************************************************************************************************/ +static bool usbd_core_device_stdreq(sli_usbd_device_t *p_dev, + uint8_t request) +{ + bool valid; + bool dev_to_host; + uint8_t dev_addr; + uint8_t cfg_nbr; + uint32_t std_req_timeout; + uint32_t xfer_len; + sl_status_t status; + CORE_DECLARE_IRQ_STATE; + + CORE_ENTER_ATOMIC(); + std_req_timeout = usbd_ptr->std_req_timeout_ms; + CORE_EXIT_ATOMIC(); + + SLI_USBD_DBG_STATS_DEV_INC(std_req_device_nbr); + + dev_to_host = SL_IS_BIT_SET(p_dev->setup_req.bmRequestType, SL_USBD_REQ_DIR_BIT); + valid = false; + + switch (request) { + case SL_USBD_REQ_GET_DESCRIPTOR: + if (dev_to_host != true) { + break; + } + + valid = usbd_core_get_descriptor_stdreq(p_dev); + break; + + case SL_USBD_REQ_SET_ADDRESS: + if (dev_to_host != false) { + break; + } + + SLI_USBD_DBG_STATS_DEV_INC(std_req_set_address_nbr); + + // Get dev addr (see Note #1a). + dev_addr = (uint8_t)(p_dev->setup_req.wValue + & 0xFFu); + + SLI_USBD_LOG_VRB(("USBD: Set Address to addr #", (u)dev_addr)); + + // Validate request values. (see Note #1b). + if ((dev_addr > 127u) + || (p_dev->setup_req.wIndex != 0u) + || (p_dev->setup_req.wLength != 0u)) { + break; + } + + switch (p_dev->state) { + case SL_USBD_DEVICE_STATE_DEFAULT: + if (dev_addr > 0u) { + // See Note #1c. + status = sli_usbd_driver_set_address(dev_addr); + if (status != SL_STATUS_OK) { + SLI_USBD_LOG_ERR(("USBD Set Address Failed")); + break; + } + + CORE_ENTER_ATOMIC(); + // Set dev in addressed state. + p_dev->address = dev_addr; + p_dev->state = SL_USBD_DEVICE_STATE_ADDRESSED; + CORE_EXIT_ATOMIC(); + + valid = true; + } + break; + + case SL_USBD_DEVICE_STATE_ADDRESSED: + if (dev_addr == 0u) { + // See Note #1c. If dev addr is zero set addr in dev drv. + status = sli_usbd_driver_set_address(0u); + if (status != SL_STATUS_OK) { + SLI_USBD_LOG_ERR(("USBD Set Address Failed")); + break; + } + + CORE_ENTER_ATOMIC(); + // Dev enters default state. + p_dev->address = 0u; + p_dev->state = SL_USBD_DEVICE_STATE_DEFAULT; + CORE_EXIT_ATOMIC(); + + valid = true; + } else { + // remains in addressed state and set new addr. + status = sli_usbd_driver_set_address(dev_addr); + if (status != SL_STATUS_OK) { + SLI_USBD_LOG_ERR(("USBD Set Address Failed")); + break; + } + + CORE_ENTER_ATOMIC(); + p_dev->address = dev_addr; + CORE_EXIT_ATOMIC(); + + valid = true; + } + break; + + case SL_USBD_DEVICE_STATE_NONE: + case SL_USBD_DEVICE_STATE_INIT: + case SL_USBD_DEVICE_STATE_ATTACHED: + case SL_USBD_DEVICE_STATE_CONFIGURED: + case SL_USBD_DEVICE_STATE_SUSPENDED: + default: + SLI_USBD_LOG_ERR(("USBD Set Address Failed due to invalid device state.")); + break; + } + break; + + case SL_USBD_REQ_SET_CONFIGURATION: + if (dev_to_host != false) { + break; + } + + SLI_USBD_DBG_STATS_DEV_INC(std_req_set_configuration_nbr); + + // Validate request values (see Note #2b). + if (((p_dev->setup_req.wValue & 0xFF00u) != 0u) + && (p_dev->setup_req.wIndex != 0u) + && (p_dev->setup_req.wLength != 0u)) { + break; + } + // Get cfg value. + cfg_nbr = (uint8_t)(p_dev->setup_req.wValue & 0xFFu); + SLI_USBD_LOG_VRB(("USBD: Set Configuration #", (u)cfg_nbr)); + +#if (USBD_CFG_HS_EN == 1) + // Cfg value MUST exists. + if ((cfg_nbr > p_dev->config_hs_total_nbr) + && (p_dev->speed == SL_USBD_DEVICE_SPEED_HIGH)) { + SLI_USBD_LOG_ERR((" Set Configuration Cfg Invalid nbr")); + break; + } +#endif + + if ((cfg_nbr > p_dev->config_fs_total_nbr) + && (p_dev->speed == SL_USBD_DEVICE_SPEED_FULL)) { + SLI_USBD_LOG_ERR((" Set Configuration Cfg Invalid nbr")); + break; + } + + switch (p_dev->state) { + case SL_USBD_DEVICE_STATE_ADDRESSED: + // See Note #2e. + if (cfg_nbr > 0u) { + // Open cfg. + status = usbd_core_set_configuration(p_dev, (cfg_nbr - 1u)); + + if (status != SL_STATUS_OK) { + SLI_USBD_LOG_ERR(("USBD Set Configuration Failed. status = ", status)); + break; + } + + valid = true; + } else { + // Remain in addressed state. + valid = true; + } + break; + + case SL_USBD_DEVICE_STATE_CONFIGURED: + // See Note #2f. + if (cfg_nbr > 0u) { + if (p_dev->config_cur_nbr == (cfg_nbr - 1u)) { + valid = true; + break; + } + + // Close curr cfg. + usbd_core_unset_configuration(p_dev); + + // Open cfg. + status = usbd_core_set_configuration(p_dev, (cfg_nbr - 1u)); + + if (status != SL_STATUS_OK) { + SLI_USBD_LOG_ERR(("USBD Set Configuration Failed. status = ", status)); + break; + } + + valid = true; + } else { + // Close curr cfg. + usbd_core_unset_configuration(p_dev); + + CORE_ENTER_ATOMIC(); + p_dev->state = SL_USBD_DEVICE_STATE_ADDRESSED; + CORE_EXIT_ATOMIC(); + + valid = true; + } + break; + + case SL_USBD_DEVICE_STATE_NONE: + case SL_USBD_DEVICE_STATE_INIT: + case SL_USBD_DEVICE_STATE_ATTACHED: + case SL_USBD_DEVICE_STATE_DEFAULT: + case SL_USBD_DEVICE_STATE_SUSPENDED: + default: + SLI_USBD_LOG_ERR(("USBD Set Configuration Failed due to invalid device state.")); + break; + } + break; + + case SL_USBD_REQ_GET_CONFIGURATION: + if (dev_to_host != true) { + break; + } + + // Validate request values (see Note #3a). + if ((p_dev->setup_req.wLength != 1u) + && (p_dev->setup_req.wIndex != 0u) + && (p_dev->setup_req.wValue != 0u)) { + break; + } + + switch (p_dev->state) { + case SL_USBD_DEVICE_STATE_ADDRESSED: + // See Note #3b. + cfg_nbr = 0u; + SLI_USBD_LOG_VRB(("USBD: Get Configuration #", (u)cfg_nbr)); + + // Uses Ctrl status buf to follow USB mem alignment. + p_dev->ctrl_status_buf_ptr[0u] = cfg_nbr; + + status = sl_usbd_core_write_control_sync((void *)&p_dev->ctrl_status_buf_ptr[0u], + 1u, + std_req_timeout, + false, + &xfer_len); + if (status != SL_STATUS_OK) { + break; + } + + valid = true; + break; + + case SL_USBD_DEVICE_STATE_CONFIGURED: + // See Note #3c. + if (p_dev->config_cur_ptr == NULL) { + break; + } + + cfg_nbr = p_dev->config_cur_nbr + 1u; + SLI_USBD_LOG_VRB(("USBD: Get Configuration #", (u)cfg_nbr)); + + // Uses Ctrl status buf to follow USB mem alignment. + p_dev->ctrl_status_buf_ptr[0u] = cfg_nbr; + + status = sl_usbd_core_write_control_sync((void *)&p_dev->ctrl_status_buf_ptr[0u], + 1u, + std_req_timeout, + false, + &xfer_len); + if (status != SL_STATUS_OK) { + break; + } + + valid = true; + break; + + case SL_USBD_DEVICE_STATE_NONE: + case SL_USBD_DEVICE_STATE_INIT: + case SL_USBD_DEVICE_STATE_ATTACHED: + case SL_USBD_DEVICE_STATE_DEFAULT: + case SL_USBD_DEVICE_STATE_SUSPENDED: + default: + SLI_USBD_LOG_ERR(("USBD Get Configuration Failed due to invalid device state.")); + break; + } + break; + + case SL_USBD_REQ_GET_STATUS: + if (dev_to_host != true) { + break; + } + + // Validate request values (see Note #4a). + if ((p_dev->setup_req.wLength != 2u) + && (p_dev->setup_req.wIndex != 0u) + && (p_dev->setup_req.wValue != 0u)) { + break; + } + + SLI_USBD_LOG_VRB(("USBD: Get Status (Device)")); + p_dev->ctrl_status_buf_ptr[0u] = 0x00u; + p_dev->ctrl_status_buf_ptr[1u] = 0x00u; + + switch (p_dev->state) { + case SL_USBD_DEVICE_STATE_ADDRESSED: + // See Note #4b. + if (p_dev->self_power == true) { + p_dev->ctrl_status_buf_ptr[0u] |= 0x01u; // BIT_00 + } + if (p_dev->remote_wakeup == true) { + p_dev->ctrl_status_buf_ptr[0u] |= 0x02u; // BIT_01 + } + + status = sl_usbd_core_write_control_sync((void *)&p_dev->ctrl_status_buf_ptr[0u], + 2u, + std_req_timeout, + false, + &xfer_len); + if (status != SL_STATUS_OK) { + break; + } + + valid = true; + break; + + case SL_USBD_DEVICE_STATE_CONFIGURED: + if (p_dev->config_cur_ptr != NULL) { + if (SL_IS_BIT_SET(p_dev->config_cur_ptr->attrib, SL_USBD_DEV_ATTRIB_SELF_POWERED)) { + p_dev->ctrl_status_buf_ptr[0u] |= 0x01u; // BIT_00 + } + if (SL_IS_BIT_SET(p_dev->config_cur_ptr->attrib, SL_USBD_DEV_ATTRIB_REMOTE_WAKEUP)) { + p_dev->ctrl_status_buf_ptr[0u] |= 0x02u; // BIT_01 + } + } + + status = sl_usbd_core_write_control_sync((void *)&p_dev->ctrl_status_buf_ptr[0u], + 2u, + std_req_timeout, + false, + &xfer_len); + if (status != SL_STATUS_OK) { + break; + } + + valid = true; + break; + + case SL_USBD_DEVICE_STATE_NONE: + case SL_USBD_DEVICE_STATE_INIT: + case SL_USBD_DEVICE_STATE_ATTACHED: + case SL_USBD_DEVICE_STATE_DEFAULT: + case SL_USBD_DEVICE_STATE_SUSPENDED: + default: + SLI_USBD_LOG_ERR(("USBD Get Status (Device) Failed due to invalid device state.")); + break; + } + break; + + case SL_USBD_REQ_CLEAR_FEATURE: + case SL_USBD_REQ_SET_FEATURE: + if (dev_to_host != false) { + break; + } + + // Validate request values. + if ((p_dev->setup_req.wLength != 0u) + && (p_dev->setup_req.wIndex != 0u)) { + break; + } + + if (request == SL_USBD_REQ_CLEAR_FEATURE) { + SLI_USBD_LOG_VRB(("USBD: Clear Feature (Device)")); + } else { + SLI_USBD_LOG_VRB(("USBD: Set Feature (Device)")); + } + + switch (p_dev->state) { + case SL_USBD_DEVICE_STATE_CONFIGURED: + if (p_dev->config_cur_ptr == NULL) { + break; + } + + if ((p_dev->setup_req.wValue == SL_USBD_FEATURE_SEL_DEVICE_REMOTE_WAKEUP) + && (SL_IS_BIT_SET(p_dev->config_cur_ptr->attrib, SL_USBD_DEV_ATTRIB_REMOTE_WAKEUP))) { + p_dev->remote_wakeup = (request == SL_USBD_REQ_CLEAR_FEATURE) ? 0u : 1u; + } + + valid = true; + break; + + case SL_USBD_DEVICE_STATE_NONE: + case SL_USBD_DEVICE_STATE_INIT: + case SL_USBD_DEVICE_STATE_ATTACHED: + case SL_USBD_DEVICE_STATE_DEFAULT: + case SL_USBD_DEVICE_STATE_ADDRESSED: + case SL_USBD_DEVICE_STATE_SUSPENDED: + default: + if (request == SL_USBD_REQ_CLEAR_FEATURE) { + SLI_USBD_LOG_ERR(("USBD Clear Feature (Device) Failed due to invalid device state.")); + } else { + SLI_USBD_LOG_ERR(("USBD Set Feature (Device) Failed due to invalid device state.")); + } + break; + } + break; + + default: + break; + } + + SLI_USBD_DBG_STATS_DEV_INC_IF_TRUE(std_req_device_stall_nbr, (valid == false)); + + return (valid); +} + +/****************************************************************************************************//** + * usbd_core_interface_stdreq() + * + * @brief Process device standard request (Interface). + * + * @param p_dev Pointer to USB device. + * + * @param ----- Argument validated in 'USBD_DevSetupPkt()' before posting the event to queue. + * + * @param request USB device request. + * + * @return true, if no error(s) occurred and request is supported. + * false, if any errors are returned. + * + * @note (1) USB Spec 2.0, section 9.4.10 specifies the format of the SET_INTERFACE request. + * This request allows the host to select an alternate setting for the specified + * interface: + * - (a) Some USB devices have configurations with interfaces that have mutually + * exclusive settings. This request allows the host to select the desired + * alternate setting. If a device only supports a default setting for the + * specified interface, then a STALL may be returned in the Status stage of + * the request. This request cannot be used to change the set of configured + * interfaces (the SetConfiguration() request must be used instead). + * - (2) USB Spec 2.0, section 9.4.4 specifies the format of the GET_INTERFACE request. + * This request returns the selected alternate setting for the specified interface. + * - (a) If 'wValue' is non-zero or 'wLength' is not '1', then the device behavior is + * not specified. + * - (b) The GET_INTERFACE request is only valid when the device is in the configured + * state. + *******************************************************************************************************/ +static bool usbd_core_interface_stdreq(sli_usbd_device_t *p_dev, + uint8_t request) +{ + uint32_t std_req_timeout; + sli_usbd_configuration_t *p_config; + sli_usbd_interface_t *p_if; + sli_usbd_alt_interface_t *p_if_alt; + sl_usbd_class_driver_t *p_class_drv; + uint8_t if_nbr; + uint8_t if_alt_nbr; + bool valid; + bool dev_to_host; + uint16_t req_len; + uint32_t xfer_len; + sl_status_t status; + sl_status_t local_status; + CORE_DECLARE_IRQ_STATE; + + local_status = SL_STATUS_OK; + + CORE_ENTER_ATOMIC(); + std_req_timeout = usbd_ptr->std_req_timeout_ms; + CORE_EXIT_ATOMIC(); + + SLI_USBD_DBG_STATS_DEV_INC(std_req_interface_nbr); + + p_config = p_dev->config_cur_ptr; + if (p_config == NULL) { + SLI_USBD_DBG_STATS_DEV_INC(std_req_interface_stall_nbr); + return (false); + } + + if_nbr = (uint8_t)(p_dev->setup_req.wIndex & 0xFFu); + p_if = usbd_core_get_interface_structure(p_config, if_nbr); + if (p_if == NULL) { + SLI_USBD_DBG_STATS_DEV_INC(std_req_interface_stall_nbr); + return (false); + } + + dev_to_host = SL_IS_BIT_SET(p_dev->setup_req.bmRequestType, SL_USBD_REQ_DIR_BIT); + valid = false; + + switch (request) { + case SL_USBD_REQ_GET_STATUS: + if (dev_to_host != true) { + break; + } + + SLI_USBD_LOG_VRB(("USBD: Get Status (Interface) IF ", (u)if_nbr)); + + if ((p_dev->state != SL_USBD_DEVICE_STATE_ADDRESSED) + && (p_dev->state != SL_USBD_DEVICE_STATE_CONFIGURED)) { + break; + } + + if ((p_dev->state == SL_USBD_DEVICE_STATE_ADDRESSED) + && (if_nbr != 0u)) { + break; + } + + p_dev->ctrl_status_buf_ptr[0u] = 0x00u; + + status = sl_usbd_core_write_control_sync((void *)&p_dev->ctrl_status_buf_ptr[0u], + 1u, + std_req_timeout, + false, + &xfer_len); + if (status != SL_STATUS_OK) { + break; + } + + valid = true; + break; + + case SL_USBD_REQ_CLEAR_FEATURE: + case SL_USBD_REQ_SET_FEATURE: + if (dev_to_host != false) { + break; + } + + if (request == SL_USBD_REQ_CLEAR_FEATURE) { + SLI_USBD_LOG_VRB(("USBD: Clear Feature (Interface) IF ", (u)if_nbr)); + } else { + SLI_USBD_LOG_VRB(("USBD: Set Feature (Interface) IF ", (u)if_nbr)); + } + + if ((p_dev->state != SL_USBD_DEVICE_STATE_ADDRESSED) + && (p_dev->state != SL_USBD_DEVICE_STATE_CONFIGURED)) { + break; + } + + if ((p_dev->state == SL_USBD_DEVICE_STATE_ADDRESSED) + && (if_nbr != 0u)) { + break; + } + + valid = true; + break; + + case SL_USBD_REQ_GET_DESCRIPTOR: + if (dev_to_host != true) { + break; + } + + SLI_USBD_LOG_VRB(("USBD: Get Descriptor (Interface) IF ", (u)if_nbr)); + + p_class_drv = p_if->class_driver_ptr; + if (p_class_drv->interface_req == NULL) { + break; + } + + req_len = p_dev->setup_req.wLength; + usbd_core_start_descriptor_write(p_dev, req_len); + + p_dev->desc_buf_status_ptr = &local_status; + + valid = p_class_drv->interface_req(&p_dev->setup_req, + p_if->class_arg_ptr); + if (valid == true) { + status = usbd_core_stop_descriptor_write(p_dev); + if (status != SL_STATUS_OK) { + valid = false; + } + } + p_dev->desc_buf_status_ptr = NULL; + break; + + case SL_USBD_REQ_GET_INTERFACE: + if (dev_to_host != true) { + break; + } + + if (p_dev->state != SL_USBD_DEVICE_STATE_CONFIGURED) { + break; + } + + p_dev->ctrl_status_buf_ptr[0u] = p_if->alt_cur; + + SLI_USBD_LOG_VRB(("USBD: Get Interface IF ", (u)if_nbr, " Alt ", (u)p_if->alt_cur)); + + status = sl_usbd_core_write_control_sync((void *)&p_dev->ctrl_status_buf_ptr[0u], + 1u, + std_req_timeout, + false, + &xfer_len); + if (status != SL_STATUS_OK) { + break; + } + + valid = true; + break; + + case SL_USBD_REQ_SET_INTERFACE: + if (dev_to_host != false) { + break; + } + + if (p_dev->state != SL_USBD_DEVICE_STATE_CONFIGURED) { + break; + } + // Get IF alt setting nbr. + if_alt_nbr = (uint8_t)(p_dev->setup_req.wValue & 0xFFu); + p_if_alt = usbd_core_get_alt_interface_structure(p_if, if_alt_nbr); + + SLI_USBD_LOG_VRB(("USBD: Set Interface IF ", (u)if_nbr, " Alt ", (u)if_alt_nbr)); + + if (p_if_alt == NULL) { + SLI_USBD_LOG_ERR(("USBD: Set Interface Invalid Alt IF")); + break; + } + + // If alt setting is the same as the cur one, no further processing is needed. + if (p_if_alt == p_if->alt_cur_ptr) { + valid = true; + break; + } + + // Close the cur alt setting. + usbd_core_close_alt_interface(p_dev, p_if->alt_cur_ptr); + + // Open the new alt setting. + status = usbd_core_open_alt_interface(p_dev, if_nbr, p_if_alt); + // Re-open curr IF alt setting, in case it fails. + if (status != SL_STATUS_OK) { + status = usbd_core_open_alt_interface(p_dev, p_if->alt_cur, p_if->alt_cur_ptr); + break; + } + + CORE_ENTER_ATOMIC(); + // Set IF alt setting. + p_if->alt_cur_ptr = p_if_alt; + p_if->alt_cur = if_alt_nbr; + CORE_EXIT_ATOMIC(); + + // Notify class that IF or alt IF has been updated. + if (p_if->class_driver_ptr->alt_settings_update != NULL) { + p_if->class_driver_ptr->alt_settings_update(p_dev->config_cur_nbr, + if_nbr, + if_alt_nbr, + p_if->class_arg_ptr, + p_if_alt->class_arg_ptr); + } + + valid = true; + break; + + default: + p_class_drv = p_if->class_driver_ptr; + if (p_class_drv->interface_req == NULL) { + break; + } + + valid = p_class_drv->interface_req(&p_dev->setup_req, + p_if->class_arg_ptr); + break; + } + + SLI_USBD_DBG_STATS_DEV_INC_IF_TRUE(std_req_interface_stall_nbr, (valid == false)); + + return (valid); +} + +/****************************************************************************************************//** + * usbd_core_endpoint_stdreq() + * + * @brief Process device standard request (Endpoint). + * + * @param p_dev Pointer to USB device. + * + * @param ----- Argument validated in 'USBD_DevSetupPkt()' before posting the event to queue. + * + * @param request USB device request. + * + * @return true, if no error(s) occurred and request is supported. + * false, if any errors are returned. + *******************************************************************************************************/ +static bool usbd_core_endpoint_stdreq(const sli_usbd_device_t *p_dev, + uint8_t request) +{ + uint32_t std_req_timeout; + sli_usbd_interface_t *p_if; + sli_usbd_alt_interface_t *p_alt_if; + bool ep_is_stall; + uint8_t if_nbr; + uint8_t ep_addr; + uint8_t ep_phy_nbr; + bool valid; + bool dev_to_host; + uint8_t feature; + uint32_t xfer_len; + sl_status_t status; + CORE_DECLARE_IRQ_STATE; + + CORE_ENTER_ATOMIC(); + std_req_timeout = usbd_ptr->std_req_timeout_ms; + CORE_EXIT_ATOMIC(); + + SLI_USBD_DBG_STATS_DEV_INC(std_req_endpoint_nbr); + + ep_addr = (uint8_t)(p_dev->setup_req.wIndex & 0xFFu); + feature = (uint8_t)(p_dev->setup_req.wValue & 0xFFu); + dev_to_host = SL_IS_BIT_SET(p_dev->setup_req.bmRequestType, SL_USBD_REQ_DIR_BIT); + valid = false; + + switch (request) { + case SL_USBD_REQ_CLEAR_FEATURE: + case SL_USBD_REQ_SET_FEATURE: + if (dev_to_host != false) { + break; + } + + switch (p_dev->state) { + case SL_USBD_DEVICE_STATE_ADDRESSED: + if (((ep_addr == 0x80u) + || (ep_addr == 0x00u)) + && (feature == SL_USBD_FEATURE_SEL_ENDPOINT_HALT)) { + if (request == SL_USBD_REQ_CLEAR_FEATURE) { + SLI_USBD_LOG_VRB(("USBD: Clear Feature (EP)(STALL) for EP 0x", (X)SL_USBD_ENDPOINT_ADDR_TO_LOG(ep_addr))); + + status = sl_usbd_core_stall_endpoint(ep_addr, false); + if (status != SL_STATUS_OK) { + break; + } + } else { + SLI_USBD_LOG_VRB(("USBD: Set Feature (EP)(STALL) for EP 0x", (X)SL_USBD_ENDPOINT_ADDR_TO_LOG(ep_addr))); + + status = sl_usbd_core_stall_endpoint(ep_addr, true); + if (status != SL_STATUS_OK) { + break; + } + } + + valid = true; + } + break; + + case SL_USBD_DEVICE_STATE_CONFIGURED: + if (feature == SL_USBD_FEATURE_SEL_ENDPOINT_HALT) { + if (request == SL_USBD_REQ_CLEAR_FEATURE) { + SLI_USBD_LOG_VRB(("USBD: Clear Feature (EP)(STALL) for EP 0x", (X)SL_USBD_ENDPOINT_ADDR_TO_LOG(ep_addr))); + + status = sl_usbd_core_stall_endpoint(ep_addr, false); + if (status != SL_STATUS_OK) { + break; + } + } else { + SLI_USBD_LOG_VRB(("USBD: Set Feature (EP)(STALL) for EP 0x", (X)SL_USBD_ENDPOINT_ADDR_TO_LOG(ep_addr))); + + status = sl_usbd_core_stall_endpoint(ep_addr, true); + if (status != SL_STATUS_OK) { + break; + } + } + + ep_phy_nbr = SL_USBD_ENDPOINT_ADDR_TO_PHY(ep_addr); + if_nbr = p_dev->endpoint_interface_table[ep_phy_nbr]; + p_if = usbd_core_get_interface_structure(p_dev->config_cur_ptr, if_nbr); + p_alt_if = p_if->alt_cur_ptr; + + // Notify class that EP state has been updated. + if (p_if->class_driver_ptr->endpoint_state_update != NULL) { + p_if->class_driver_ptr->endpoint_state_update(p_dev->config_cur_nbr, + if_nbr, + p_if->alt_cur, + ep_addr, + p_if->class_arg_ptr, + p_alt_if->class_arg_ptr); + } + + valid = true; + } + break; + + case SL_USBD_DEVICE_STATE_NONE: + case SL_USBD_DEVICE_STATE_INIT: + case SL_USBD_DEVICE_STATE_ATTACHED: + case SL_USBD_DEVICE_STATE_DEFAULT: + case SL_USBD_DEVICE_STATE_SUSPENDED: + default: + break; + } + break; + + case SL_USBD_REQ_GET_STATUS: + if (dev_to_host != true) { + break; + } + + p_dev->ctrl_status_buf_ptr[0u] = 0x00u; + p_dev->ctrl_status_buf_ptr[1u] = 0x00u; + + switch (p_dev->state) { + case SL_USBD_DEVICE_STATE_ADDRESSED: + if ((ep_addr == 0x80u) + || (ep_addr == 0x00u)) { + SLI_USBD_LOG_VRB(("USBD: Get Status (EP)(STALL) for EP 0x", (X)SL_USBD_ENDPOINT_ADDR_TO_LOG(ep_addr))); + sl_usbd_core_is_endpoint_stalled(ep_addr, &ep_is_stall); + if (ep_is_stall == true) { + p_dev->ctrl_status_buf_ptr[0u] = 0x01u; // BIT_00 + p_dev->ctrl_status_buf_ptr[1u] = 0x00u; + } + + status = sl_usbd_core_write_control_sync((void *)&p_dev->ctrl_status_buf_ptr[0u], + 2u, + std_req_timeout, + false, + &xfer_len); + if (status != SL_STATUS_OK) { + break; + } + + valid = true; + } + break; + + case SL_USBD_DEVICE_STATE_CONFIGURED: + SLI_USBD_LOG_VRB(("USBD: Get Status (EP)(STALL) for EP 0x", (X)SL_USBD_ENDPOINT_ADDR_TO_LOG(ep_addr))); + sl_usbd_core_is_endpoint_stalled(ep_addr, &ep_is_stall); + if (ep_is_stall == true) { + p_dev->ctrl_status_buf_ptr[0u] = 0x01u; // BIT_00 + p_dev->ctrl_status_buf_ptr[1u] = 0x00u; + } + + status = sl_usbd_core_write_control_sync((void *)&p_dev->ctrl_status_buf_ptr[0], + 2u, + std_req_timeout, + false, + &xfer_len); + if (status != SL_STATUS_OK) { + break; + } + + valid = true; + break; + + case SL_USBD_DEVICE_STATE_NONE: + case SL_USBD_DEVICE_STATE_INIT: + case SL_USBD_DEVICE_STATE_ATTACHED: + case SL_USBD_DEVICE_STATE_DEFAULT: + case SL_USBD_DEVICE_STATE_SUSPENDED: + default: + break; + } + break; + + default: + break; + } + + SLI_USBD_DBG_STATS_DEV_INC_IF_TRUE(std_req_endpoint_stall_nbr, (valid == false)); + + return (valid); +} + +/****************************************************************************************************//** + * usbd_core_class_stdreq() + * + * @brief Class standard request handler. + * + * @param p_dev Pointer to USB device. + * + * @param ----- Argument validated in 'USBD_DevSetupPkt()' before posting the event to queue. + * + * @return true, if no error(s) occurred and request is supported. + * false, if any errors are returned. + *******************************************************************************************************/ +static bool usbd_core_class_stdreq(const sli_usbd_device_t *p_dev) +{ + sli_usbd_configuration_t *p_config; + sli_usbd_interface_t *p_if; + sl_usbd_class_driver_t *p_class_drv; + uint8_t recipient; + uint8_t if_nbr; + uint8_t ep_addr; + uint8_t ep_phy_nbr; + bool valid; + + SLI_USBD_DBG_STATS_DEV_INC(std_req_class_nbr); + + p_config = p_dev->config_cur_ptr; + if (p_config == NULL) { + return (false); + } + + recipient = p_dev->setup_req.bmRequestType & SL_USBD_REQ_RECIPIENT_MASK; + + if (recipient == SL_USBD_REQ_RECIPIENT_INTERFACE) { + if_nbr = (uint8_t)(p_dev->setup_req.wIndex & 0xFFu); + } else { + ep_addr = (uint8_t)(p_dev->setup_req.wIndex & 0xFFu); + ep_phy_nbr = SL_USBD_ENDPOINT_ADDR_TO_PHY(ep_addr); + if_nbr = p_dev->endpoint_interface_table[ep_phy_nbr]; + } + + p_if = usbd_core_get_interface_structure(p_config, if_nbr); + if (p_if == NULL) { + SLI_USBD_DBG_STATS_DEV_INC(std_req_class_stall_nbr); + return (false); + } + + p_class_drv = p_if->class_driver_ptr; + if (p_class_drv->class_req == NULL) { + SLI_USBD_DBG_STATS_DEV_INC(std_req_class_stall_nbr); + return (false); + } + + valid = p_class_drv->class_req(&p_dev->setup_req, + p_if->class_arg_ptr); + + SLI_USBD_DBG_STATS_DEV_INC_IF_TRUE(std_req_class_stall_nbr, (valid == false)); + + return (valid); +} + +/****************************************************************************************************//** + * usbd_core_vendor_stdreq() + * + * @brief Vendor standard request handler. + * + * @param p_dev Pointer to USB device. + * + * @param ----- Argument validated in 'USBD_DevSetupPkt()' before posting the event to queue. + * + * @return true, if no error(s) occurred and request is supported. + * false, if any errors are returned. + *******************************************************************************************************/ +static bool usbd_core_vendor_stdreq(const sli_usbd_device_t *p_dev) +{ + sli_usbd_configuration_t *p_config; + sli_usbd_interface_t *p_if; + sl_usbd_class_driver_t *p_class_drv; + uint8_t recipient; + uint8_t if_nbr; + uint8_t ep_addr; + uint8_t ep_phy_nbr; + bool valid; + + p_config = p_dev->config_cur_ptr; + if (p_config == NULL) { + return (false); + } + + recipient = p_dev->setup_req.bmRequestType & SL_USBD_REQ_RECIPIENT_MASK; + + if (recipient == SL_USBD_REQ_RECIPIENT_INTERFACE) { + if_nbr = (uint8_t)(p_dev->setup_req.wIndex & 0xFFu); + } else { + ep_addr = (uint8_t)(p_dev->setup_req.wIndex & 0xFFu); + ep_phy_nbr = SL_USBD_ENDPOINT_ADDR_TO_PHY(ep_addr); + if_nbr = p_dev->endpoint_interface_table[ep_phy_nbr]; + } + + p_if = usbd_core_get_interface_structure(p_config, if_nbr); + if (p_if == NULL) { + return (false); + } + + p_class_drv = p_if->class_driver_ptr; + if (p_class_drv->vendor_req == NULL) { + return (false); + } + + valid = p_class_drv->vendor_req(&p_dev->setup_req, + p_if->class_arg_ptr); + + return (valid); +} + +/****************************************************************************************************//** + * usbd_core_microsoft_device_stdreq() + * + * @brief Microsoft descriptor request handler (when recipient is device). + * + * @param p_dev Pointer to USB device. + * + * @param ----- Argument validated in 'USBD_DevSetupPkt()' before posting the event to queue. + * + * @return true, if no error(s) occurred and request is supported. + * false, if any errors are returned. + * + * @note (1) For more information on Microsoft OS decriptors, see + * 'http://msdn.microsoft.com/en-us/library/windows/hardware/gg463179.aspx'. + * + * @note (2) Page feature is not supported so Microsoft OS descriptors have their length limited + * to 64Kbytes. + *******************************************************************************************************/ +#if (USBD_CFG_MS_OS_DESC_EN == 1) +static bool usbd_core_microsoft_device_stdreq(const sli_usbd_device_t *p_dev) +{ + bool valid; + uint8_t if_nbr; + uint8_t max_if; + uint8_t if_ix; + uint8_t compat_id_ix; + uint8_t subcompat_id_ix; + uint8_t section_cnt; + uint16_t feature; + uint16_t len; + uint8_t cfg_nbr = 0u; + uint32_t desc_len; + sli_usbd_configuration_t *p_config; + sli_usbd_interface_t *p_if; + sl_usbd_class_driver_t *p_class_drv; + sl_status_t status; + + valid = false; + feature = p_dev->setup_req.wIndex; + if_nbr = (uint8_t)(p_dev->setup_req.wValue & 0xFFu); + len = p_dev->setup_req.wLength; + + // Use 1st cfg as Microsoft doesn't specify cfg in setup pkt. +#if (USBD_CFG_HS_EN == 1) + if (p_dev->speed == SL_USBD_DEVICE_SPEED_HIGH) { + p_config = usbd_core_get_configuration_structure(p_dev, cfg_nbr | SL_USBD_CONFIG_NBR_SPD_BIT); + } else { +#endif + p_config = usbd_core_get_configuration_structure(p_dev, cfg_nbr); +#if (USBD_CFG_HS_EN == 1) +} +#endif + if (p_config == NULL) { + return (false); + } + + switch (feature) { + case SLI_USBD_MICROSOFT_FEATURE_COMPAT_ID: + // See note (1). + // Send Desc Header + // Compute length of descriptor. + desc_len = SLI_USBD_MICROSOFT_DESC_COMPAT_ID_HDR_LEN; + section_cnt = 0u; + if (if_nbr == 0u) { + // If req IF == 0, sends all dev compat IDs. + max_if = p_config->interface_nbr_total; + } else { + max_if = if_nbr + 1u; + } + + for (if_ix = if_nbr; if_ix < max_if; if_ix++) { + p_if = usbd_core_get_interface_structure(p_config, if_ix); + p_class_drv = p_if->class_driver_ptr; + if (p_class_drv->microsoft_get_compat_id != NULL) { + compat_id_ix = p_class_drv->microsoft_get_compat_id(&subcompat_id_ix); + if (compat_id_ix != SL_USBD_MICROSOFT_COMPAT_ID_NONE) { + desc_len += SLI_USBD_MICROSOFT_DESC_COMPAT_ID_SECTION_LEN; + section_cnt++; + } + } + } + + // Wr desc hdr. + usbd_core_start_descriptor_write((sli_usbd_device_t *)p_dev, desc_len); + + sl_usbd_core_write_32b_to_descriptor_buf(desc_len); + sl_usbd_core_write_16b_to_descriptor_buf(SLI_USBD_MICROSOFT_DESC_VER_1_0); + sl_usbd_core_write_16b_to_descriptor_buf(feature); + sl_usbd_core_write_08b_to_descriptor_buf(section_cnt); + // Add 7 null bytes (reserved). + sl_usbd_core_write_32b_to_descriptor_buf(0u); + sl_usbd_core_write_16b_to_descriptor_buf(0u); + sl_usbd_core_write_08b_to_descriptor_buf(0u); + + // Send Desc Sections + if (len != SLI_USBD_MICROSOFT_DESC_COMPAT_ID_HDR_VER_1_0) { + // If req len = version, only send desc hdr. + for (if_ix = if_nbr; if_ix < max_if; if_ix++) { + p_if = usbd_core_get_interface_structure(p_config, if_ix); + if (p_if->class_driver_ptr->microsoft_get_compat_id != NULL) { + compat_id_ix = p_if->class_driver_ptr->microsoft_get_compat_id(&subcompat_id_ix); + if (compat_id_ix != SL_USBD_MICROSOFT_COMPAT_ID_NONE) { + sl_usbd_core_write_08b_to_descriptor_buf(if_ix); + sl_usbd_core_write_08b_to_descriptor_buf(0x01u); + + sl_usbd_core_write_buf_to_descriptor_buf((uint8_t *)usbd_microsoft_compat_id[compat_id_ix], + 8u); + + sl_usbd_core_write_buf_to_descriptor_buf((uint8_t *)usbd_microsoft_subcompat_id[subcompat_id_ix], + 8u); + + // Add 6 null bytes (reserved). + sl_usbd_core_write_32b_to_descriptor_buf(0u); + sl_usbd_core_write_16b_to_descriptor_buf(0u); + } + } + } + } + + if (*(p_dev->desc_buf_status_ptr) == SL_STATUS_OK) { + status = usbd_core_stop_descriptor_write((sli_usbd_device_t *)p_dev); + *(p_dev->desc_buf_status_ptr) = status; + } + + if (*(p_dev->desc_buf_status_ptr) == SL_STATUS_OK) { + valid = true; + } + break; + + case SLI_USBD_MICROSOFT_FEATURE_EXT_PROPERTIES: + valid = usbd_core_microsoft_ext_property_stdreq(p_dev, + p_config, + if_nbr, + len); + break; + + default: + break; + } + + return (valid); +} +#endif + +/****************************************************************************************************//** + * usbd_core_microsoft_interface_stdreq() + * + * @brief Microsoft descriptor request handler (when recipient is interface). + * + * @param p_dev Pointer to USB device. + * + * @param ----- Argument validated in 'USBD_DevSetupPkt()' before posting the event to queue. + * + * @return true, if no error(s) occurred and request is supported. + * false, if any errors are returned. + * + * @note (1) For more information on Microsoft OS decriptors, see + * 'http://msdn.microsoft.com/en-us/library/windows/hardware/gg463179.aspx'. + * + * @note (2) Page feature is not supported so Microsoft OS descriptors have their length limited + * to 64Kbytes. + *******************************************************************************************************/ +#if (USBD_CFG_MS_OS_DESC_EN == 1) +static bool usbd_core_microsoft_interface_stdreq(const sli_usbd_device_t *p_dev) +{ + bool valid = false; + uint8_t if_nbr = (uint8_t)(p_dev->setup_req.wValue & 0xFFu); + uint16_t feature = p_dev->setup_req.wIndex; + uint16_t len = p_dev->setup_req.wLength; + sli_usbd_configuration_t *p_config; + + // Use 1st cfg as Microsoft doesn't specify cfg in setup pkt. +#if (USBD_CFG_HS_EN == 1) + if (p_dev->speed == SL_USBD_DEVICE_SPEED_HIGH) { + p_config = usbd_core_get_configuration_structure(p_dev, 0u | SL_USBD_CONFIG_NBR_SPD_BIT); + } else { +#endif + p_config = usbd_core_get_configuration_structure(p_dev, 0u); +#if (USBD_CFG_HS_EN == 1) +} +#endif + if (p_config == NULL) { + return (false); + } + + switch (feature) { + case SLI_USBD_MICROSOFT_FEATURE_EXT_PROPERTIES: + valid = usbd_core_microsoft_ext_property_stdreq(p_dev, + p_config, + if_nbr, + len); + break; + + default: + break; + } + + return (valid); +} +#endif + +/****************************************************************************************************//** + * usbd_core_microsoft_ext_property_stdreq() + * + * @brief Microsoft descriptor request handler (when recipient is interface). + * + * @param p_dev Pointer to USB device. + * + * @param ----- Argument validated in 'USBD_DevSetupPkt()' before posting the event to queue. + * + * @param if_nbr Interface number. + * + * @param ----- Argument validated in 'USBD_DevSetupPkt()' before posting the event to queue. + * + * @param len Length of descriptor as requested by host. + * + * @param ----- Argument validated in 'USBD_DevSetupPkt()' before posting the event to queue. + * + * @return true, if no error(s) occurred and request is supported. + * false, if any errors are returned. + * + * @note (1) For more information on Microsoft OS decriptors, see + * 'http://msdn.microsoft.com/en-us/library/windows/hardware/gg463179.aspx'. + * + * @note (2) Page feature is not supported so Microsoft OS descriptors have their length limited + * to 64Kbytes. + *******************************************************************************************************/ +#if (USBD_CFG_MS_OS_DESC_EN == 1) +static bool usbd_core_microsoft_ext_property_stdreq(const sli_usbd_device_t *p_dev, + sli_usbd_configuration_t *p_config, + uint8_t if_nbr, + uint16_t len) +{ + bool valid = false; + uint8_t section_cnt = 0u; + uint8_t ext_property_cnt; + uint8_t ext_property_ix; + uint32_t desc_len = SLI_USBD_MICROSOFT_DESC_EXT_PROPERTIES_HDR_LEN; + sli_usbd_interface_t *p_if; + sl_usbd_class_driver_t *p_class_drv; + sl_usbd_microsoft_ext_property_t *p_ext_property; + sl_status_t status; + + // Send Desc Header + // Compute length of descriptor. + p_if = usbd_core_get_interface_structure(p_config, if_nbr); + p_class_drv = p_if->class_driver_ptr; + + if (p_class_drv->microsoft_get_ext_property_table != NULL) { + ext_property_cnt = p_class_drv->microsoft_get_ext_property_table(&p_ext_property, if_nbr); + for (ext_property_ix = 0u; ext_property_ix < ext_property_cnt; ext_property_ix++) { + desc_len += SLI_USBD_MICROSOFT_DESC_EXT_PROPERTIES_SECTION_HDR_LEN; + desc_len += p_ext_property->property_name_len; + desc_len += p_ext_property->property_len; + desc_len += 6u; + + section_cnt++; + p_ext_property++; + } + } + + usbd_core_start_descriptor_write((sli_usbd_device_t *)p_dev, desc_len); + + sl_usbd_core_write_32b_to_descriptor_buf(desc_len); + sl_usbd_core_write_16b_to_descriptor_buf(SLI_USBD_MICROSOFT_DESC_VER_1_0); + sl_usbd_core_write_16b_to_descriptor_buf(SLI_USBD_MICROSOFT_FEATURE_EXT_PROPERTIES); + sl_usbd_core_write_16b_to_descriptor_buf(section_cnt); + + // Send Desc Sections + // If req len = version, only send desc hdr. + if ((len != SLI_USBD_MICROSOFT_DESC_EXT_PROPERTIES_HDR_VER_1_0) + && (p_class_drv->microsoft_get_ext_property_table != NULL)) { + ext_property_cnt = p_class_drv->microsoft_get_ext_property_table(&p_ext_property, if_nbr); + for (ext_property_ix = 0u; ext_property_ix < ext_property_cnt; ext_property_ix++) { + // Compute desc section len. + desc_len = SLI_USBD_MICROSOFT_DESC_EXT_PROPERTIES_SECTION_HDR_LEN; + desc_len += p_ext_property->property_name_len; + desc_len += p_ext_property->property_len; + desc_len += 6u; + + // Wr desc section. + sl_usbd_core_write_32b_to_descriptor_buf(desc_len); + sl_usbd_core_write_32b_to_descriptor_buf(p_ext_property->property_type); + + sl_usbd_core_write_16b_to_descriptor_buf(p_ext_property->property_name_len); + sl_usbd_core_write_buf_to_descriptor_buf((uint8_t *)p_ext_property->property_name_ptr, + p_ext_property->property_name_len); + + sl_usbd_core_write_32b_to_descriptor_buf(p_ext_property->property_len); + sl_usbd_core_write_buf_to_descriptor_buf((uint8_t *)p_ext_property->property_ptr, + p_ext_property->property_len); + + p_ext_property++; + } + } + + if (*(p_dev->desc_buf_status_ptr) == SL_STATUS_OK) { + status = usbd_core_stop_descriptor_write((sli_usbd_device_t *)p_dev); + *(p_dev->desc_buf_status_ptr) = status; + } + + if (*(p_dev->desc_buf_status_ptr) == SL_STATUS_OK) { + valid = true; + } + + return (valid); +} +#endif + +/****************************************************************************************************//** + * usbd_core_get_descriptor_stdreq() + * + * @brief GET_DESCRIPTOR standard request handler. + * + * @param p_dev Pointer to USB device. + * + * @param ----- Argument validated in 'USBD_DevSetupPkt()' before posting the event to queue. + * + * @return true, if no error(s) occurred and request is supported. + * false, if any errors are returned. + *******************************************************************************************************/ +static bool usbd_core_get_descriptor_stdreq(sli_usbd_device_t *p_dev) +{ + uint8_t desc_type; + uint8_t desc_ix; + uint16_t req_len; + bool valid; + sl_status_t local_status; + sl_status_t status; +#if (USBD_CFG_HS_EN == 1) + sl_usbd_device_speed_t drv_spd; +#endif + + local_status = SL_STATUS_OK; + + desc_type = (uint8_t)((p_dev->setup_req.wValue >> 8u) & 0xFFu); + desc_ix = (uint8_t)(p_dev->setup_req.wValue & 0xFFu); + valid = false; + req_len = p_dev->setup_req.wLength; + // Set the desc buf as the current buf. + p_dev->actual_buf_ptr = p_dev->desc_buf_ptr; + // Set the max len for the desc buf. + p_dev->desc_buf_max_len = SLI_USBD_DESC_BUF_LEN; + p_dev->desc_buf_status_ptr = &local_status; + + switch (desc_type) { + case SL_USBD_DESC_TYPE_DEVICE: + SLI_USBD_LOG_VRB(("USBD: Get Descriptor (Device)")); + status = usbd_core_send_device_descriptor(p_dev, false, req_len); + if (status == SL_STATUS_OK) { + valid = true; + } + break; + + case SL_USBD_DESC_TYPE_CONFIGURATION: + SLI_USBD_LOG_VRB(("USBD: Get Descriptor (Configuration) ix #", (u)desc_ix)); + status = usbd_core_send_configuration_descriptor(p_dev, desc_ix, false, req_len); + if (status != SL_STATUS_OK) { + SLI_USBD_LOG_ERR(("USBD Get Descriptor (Configuration) Failed. status = ", status)); + } else { + valid = true; + } + break; + + case SL_USBD_DESC_TYPE_STRING: + SLI_USBD_LOG_VRB(("USBD: Get Descriptor (String) ix #", (u)desc_ix)); +#if (USBD_CFG_STR_EN == 1) + status = usbd_core_send_string_descriptor(p_dev, desc_ix, req_len); + if (status == SL_STATUS_OK) { + valid = true; + } +#endif + break; + + case SL_USBD_DESC_TYPE_DEVICE_QUALIFIER: + SLI_USBD_LOG_VRB(("USBD: Get Descriptor (Device Qualifier)")); +#if (USBD_CFG_HS_EN == 1) + sli_usbd_driver_get_speed(&drv_spd); + + // Chk if dev only supports FS. + if (drv_spd == SL_USBD_DEVICE_SPEED_FULL) { + break; + } + + status = usbd_core_send_device_descriptor(p_dev, true, req_len); + + if (status == SL_STATUS_OK) { + valid = true; + } +#endif + break; + + case SL_USBD_DESC_TYPE_OTHER_SPEED_CONFIGURATION: + SLI_USBD_LOG_VRB(("USBD: Get Descriptor (Other Speed)")); +#if (USBD_CFG_HS_EN == 1) + sli_usbd_driver_get_speed(&drv_spd); + + if (drv_spd == SL_USBD_DEVICE_SPEED_FULL) { + break; + } + + status = usbd_core_send_configuration_descriptor(p_dev, desc_ix, true, req_len); + + if (status == SL_STATUS_OK) { + valid = true; + } +#endif + break; + + default: + break; + } + + p_dev->desc_buf_status_ptr = NULL; + return (valid); +} + +/****************************************************************************************************//** + * usbd_core_unset_configuration() + * + * @brief Close current device configuration. + * + * @param p_dev Pointer to USB device. + * + * @param ----- Argument validated in 'USBD_DevSetupPkt()' before posting the event to queue and + * 'sl_usbd_core_stop_device()' function. + *******************************************************************************************************/ +static void usbd_core_unset_configuration(sli_usbd_device_t *p_dev) +{ + sli_usbd_configuration_t *p_config; + sli_usbd_interface_t *p_if; + sli_usbd_alt_interface_t *p_if_alt; + uint8_t if_nbr; + CORE_DECLARE_IRQ_STATE; + + p_config = p_dev->config_cur_ptr; + if (p_config == NULL) { + return; + } + + // Notify app about clr cfg. + sl_usbd_on_config_event(SL_USBD_EVENT_CONFIG_UNSET, p_dev->config_cur_nbr); + + for (if_nbr = 0u; if_nbr < p_config->interface_nbr_total; if_nbr++) { + p_if = usbd_core_get_interface_structure(p_config, if_nbr); + if (p_if == NULL) { + return; + } + + p_if_alt = p_if->alt_cur_ptr; + if (p_if_alt == NULL) { + return; + } + + if (p_if->class_driver_ptr->disable != NULL) { + // Notify class that cfg is not active. + p_if->class_driver_ptr->disable(p_dev->config_cur_nbr, + p_if->class_arg_ptr); + } + } + + CORE_ENTER_ATOMIC(); + p_dev->state = SL_USBD_DEVICE_STATE_ADDRESSED; + CORE_EXIT_ATOMIC(); + + for (if_nbr = 0u; if_nbr < p_config->interface_nbr_total; if_nbr++) { + p_if = usbd_core_get_interface_structure(p_config, if_nbr); + if (p_if == NULL) { + return; + } + + p_if_alt = p_if->alt_cur_ptr; + if (p_if_alt == NULL) { + return; + } + + usbd_core_close_alt_interface(p_dev, p_if_alt); + + p_if_alt = usbd_core_get_alt_interface_structure(p_if, 0u); + + CORE_ENTER_ATOMIC(); + p_if->alt_cur_ptr = p_if_alt; + p_if->alt_cur = 0u; + CORE_EXIT_ATOMIC(); + } + + CORE_ENTER_ATOMIC(); + p_dev->config_cur_ptr = NULL; + p_dev->config_cur_nbr = SL_USBD_CONFIG_NBR_NONE; + CORE_EXIT_ATOMIC(); +} + +/****************************************************************************************************//** + * usbd_core_set_configuration() + * + * @brief Open specified configuration. + * + * @param p_dev Pointer to USB device. + * + * @param ----- Argument validated in 'USBD_DevSetupPkt()' before posting the event to queue. + * + * @param config_nbr Configuration number. + * + * @return Returns SL_STATUS_OK on success or another SL_STATUS code on failure. + *******************************************************************************************************/ +static sl_status_t usbd_core_set_configuration(sli_usbd_device_t *p_dev, + uint8_t config_nbr) + +{ + sli_usbd_configuration_t *p_config; + sli_usbd_interface_t *p_if; + sli_usbd_alt_interface_t *p_if_alt; + uint8_t if_nbr; + sl_status_t status; + CORE_DECLARE_IRQ_STATE; + +#if (USBD_CFG_HS_EN == 1) + if (p_dev->speed == SL_USBD_DEVICE_SPEED_HIGH) { + p_config = usbd_core_get_configuration_structure(p_dev, config_nbr | SL_USBD_CONFIG_NBR_SPD_BIT); + } else { +#endif + p_config = usbd_core_get_configuration_structure(p_dev, config_nbr); +#if (USBD_CFG_HS_EN == 1) +} +#endif + + if (p_config == NULL) { + return SL_STATUS_INVALID_PARAMETER; + } + + for (if_nbr = 0u; if_nbr < p_config->interface_nbr_total; if_nbr++) { + p_if = usbd_core_get_interface_structure(p_config, if_nbr); + if (p_if == NULL) { + return SL_STATUS_INVALID_PARAMETER; + } + + p_if_alt = p_if->alt_cur_ptr; + if (p_if_alt == NULL) { + return SL_STATUS_INVALID_PARAMETER; + } + + status = usbd_core_open_alt_interface(p_dev, if_nbr, p_if_alt); + + if (status != SL_STATUS_OK) { + return status; + } + } + + CORE_ENTER_ATOMIC(); + p_dev->config_cur_ptr = p_config; + p_dev->config_cur_nbr = config_nbr; + CORE_EXIT_ATOMIC(); + + CORE_ENTER_ATOMIC(); + p_dev->state = SL_USBD_DEVICE_STATE_CONFIGURED; + CORE_EXIT_ATOMIC(); + + for (if_nbr = 0u; if_nbr < p_config->interface_nbr_total; if_nbr++) { + p_if = usbd_core_get_interface_structure(p_config, if_nbr); + if (p_if == NULL) { + return SL_STATUS_INVALID_PARAMETER; + } else { + if (p_if->class_driver_ptr->enable != NULL) { + // Notify class that cfg is active. + p_if->class_driver_ptr->enable(config_nbr, + p_if->class_arg_ptr); + } + } + } + + // Notify app about set cfg. + sl_usbd_on_config_event(SL_USBD_EVENT_CONFIG_SET, config_nbr); + + return SL_STATUS_OK; +} + +/****************************************************************************************************//** + * usbd_core_send_device_descriptor() + * + * @brief Send device configuration descriptor. + * + * @param p_dev Pointer to USB device. + * + * @param ----- Argument validated in 'USBD_DevSetupPkt()' before posting the event to queue. + * + * @param other Other speed configuration : + * - true Current speed. + * - false Other operational speed. + * + * @param req_len Requested length by the host. + * + * @return Returns SL_STATUS_OK on success or another SL_STATUS code on failure. + * + * @note (1) USB Spec 2.0 table 9-8 describes the standard device descriptor. + * + * +--------+--------------------+-------+----------+-----------------------------------+ + * | Offset | Field | size | Value | Description | + * +--------+--------------------+-------+----------+-----------------------------------+ + * | 0 | bLength | 1 | Number | size of this descriptor | + * +--------+--------------------+-------+----------+-----------------------------------+ + * | 1 | bDescriptorType | 1 | Const | DEVICE Descriptor type | + * +--------+--------------------+-------+----------+-----------------------------------+ + * | 2 | bcdUSB | 2 | BCD USB | Specification release number | + * +--------+--------------------+-------+----------+-----------------------------------+ + * | 4 | bDeviceClass | 1 | Class | Class code. | + * +--------+--------------------+-------+----------+-----------------------------------+ + * | 5 | bDeviceSubClass | 1 | SubClass | Subclass code. | + * +--------+--------------------+-------+----------+-----------------------------------+ + * | 6 | bDeviceProtocol | 1 | protocol | protocol code. | + * +--------+--------------------+-------+----------+-----------------------------------+ + * | 7 | bMaxPacketSize0 | 1 | Number | Max packet size for EP zero | + * +--------+--------------------+-------+----------+-----------------------------------+ + * | 8 | idVendor | 2 | id | Vendor id | + * +--------+--------------------+-------+----------+-----------------------------------+ + * | 10 | idProduct | 2 | id | Product id | + * +--------+--------------------+-------+----------+-----------------------------------+ + * | 12 | bcdDevice | 2 | BCD | Dev release number in BCD format | + * +--------+--------------------+-------+----------+-----------------------------------+ + * | 14 | iManufacturer | 1 | Index | Index of manufacturer string | + * +--------+--------------------+-------+----------+-----------------------------------+ + * | 15 | iProduct | 1 | Index | Index of product string | + * +--------|--------------------|-------|----------|-----------------------------------+ + * | 16 | iSerialNumber | 1 | Index | Index of serial number string | + * +--------|--------------------|-------|----------|-----------------------------------+ + * | 17 | bNumConfigurations | 1 | Number | Number of possible configurations | + * +--------|--------------------|-------|----------|-----------------------------------+ + * + * ) To enable host to identify devices that use the Interface Association descriptor the + * device descriptor should contain the following values. + *******************************************************************************************************/ +static sl_status_t usbd_core_send_device_descriptor(sli_usbd_device_t *p_dev, + bool other, + uint16_t req_len) +{ + sli_usbd_configuration_t *p_config; + bool if_grp_en; + uint8_t cfg_nbr; + uint8_t cfg_nbr_spd; + uint8_t cfg_nbr_total; + sl_usbd_device_speed_t drv_spd; +#if (USBD_CFG_STR_EN == 1) + uint8_t str_ix; +#endif + +#if (USBD_CFG_HS_EN == 0) + (void)&other; + (void)&drv_spd; +#endif + + if_grp_en = false; + +#if (USBD_CFG_HS_EN == 1) + if (other == false) { +#endif + usbd_core_start_descriptor_write(p_dev, req_len); + // Desc len. + usbd_core_write_08b_to_descriptor_buf(p_dev, SL_USBD_DESC_LEN_DEV); + // Dev desc type. + usbd_core_write_08b_to_descriptor_buf(p_dev, SL_USBD_DESC_TYPE_DEVICE); + // USB spec release nbr in BCD fmt (2.00). + usbd_core_write_16b_to_descriptor_buf(p_dev, 0x200u); + +#if (USBD_CFG_HS_EN == 1) + if (p_dev->speed == SL_USBD_DEVICE_SPEED_FULL) { +#endif + cfg_nbr_spd = 0x00u; + cfg_nbr_total = p_dev->config_fs_total_nbr; +#if (USBD_CFG_HS_EN == 1) +} else { + cfg_nbr_spd = SL_USBD_CONFIG_NBR_SPD_BIT; + cfg_nbr_total = p_dev->config_hs_total_nbr; +} +#endif + + cfg_nbr = 0u; + while ((cfg_nbr < cfg_nbr_total) + && (if_grp_en == false)) { + p_config = usbd_core_get_configuration_structure(p_dev, cfg_nbr | cfg_nbr_spd); + if (p_config != NULL) { + if (p_config->interface_group_nbr_total > 0u) { + if_grp_en = true; + } + } + + cfg_nbr++; + } + + if (if_grp_en == false) { + // Dev class is specified in IF desc. + usbd_core_write_08b_to_descriptor_buf(p_dev, SL_USBD_CLASS_CODE_USE_IF_DESC); + usbd_core_write_08b_to_descriptor_buf(p_dev, SL_USBD_SUBCLASS_CODE_USE_IF_DESC); + usbd_core_write_08b_to_descriptor_buf(p_dev, SL_USBD_PROTOCOL_CODE_USE_IF_DESC); + } else { + // Multi-Interface function dev class. + usbd_core_write_08b_to_descriptor_buf(p_dev, SL_USBD_CLASS_CODE_MISCELLANEOUS); + usbd_core_write_08b_to_descriptor_buf(p_dev, SL_USBD_SUBCLASS_CODE_USE_COMMON_CLASS); + usbd_core_write_08b_to_descriptor_buf(p_dev, SL_USBD_PROTOCOL_CODE_USE_IAD); + } + // Set max pkt size for ctrl EP. + usbd_core_write_08b_to_descriptor_buf(p_dev, (uint8_t)p_dev->endpoint_max_ctrl_pkt_size); + // Set vendor id, product id and dev id. + usbd_core_write_16b_to_descriptor_buf(p_dev, p_dev->device_config.vendor_id); + usbd_core_write_16b_to_descriptor_buf(p_dev, p_dev->device_config.product_id); + usbd_core_write_16b_to_descriptor_buf(p_dev, p_dev->device_config.device_bcd); + +#if (USBD_CFG_STR_EN == 1) + str_ix = usbd_core_get_string_index(p_dev, p_dev->device_config.manufacturer_str_ptr); + usbd_core_write_08b_to_descriptor_buf(p_dev, str_ix); + str_ix = usbd_core_get_string_index(p_dev, p_dev->device_config.product_str_ptr); + usbd_core_write_08b_to_descriptor_buf(p_dev, str_ix); + str_ix = usbd_core_get_string_index(p_dev, p_dev->device_config.serial_nbr_str_ptr); + usbd_core_write_08b_to_descriptor_buf(p_dev, str_ix); +#else + usbd_core_write_08b_to_descriptor_buf(p_dev, 0u); + usbd_core_write_08b_to_descriptor_buf(p_dev, 0u); + usbd_core_write_08b_to_descriptor_buf(p_dev, 0u); +#endif + usbd_core_write_08b_to_descriptor_buf(p_dev, cfg_nbr_total); + +#if (USBD_CFG_HS_EN == 1) +} else { + sli_usbd_driver_get_speed(&drv_spd); + if (drv_spd != SL_USBD_DEVICE_SPEED_HIGH) { + return SL_STATUS_INVALID_PARAMETER; + } + usbd_core_start_descriptor_write(p_dev, req_len); + // Desc len. + usbd_core_write_08b_to_descriptor_buf(p_dev, SL_USBD_DESC_LEN_DEV_QUAL); + usbd_core_write_08b_to_descriptor_buf(p_dev, SL_USBD_DESC_TYPE_DEVICE_QUALIFIER); + // USB spec release nbr in BCD fmt (2.00). + usbd_core_write_16b_to_descriptor_buf(p_dev, 0x200u); + + if (p_dev->speed == SL_USBD_DEVICE_SPEED_HIGH) { + cfg_nbr_spd = 0x00u; + cfg_nbr_total = p_dev->config_fs_total_nbr; + } else { + cfg_nbr_spd = SL_USBD_CONFIG_NBR_SPD_BIT; + cfg_nbr_total = p_dev->config_hs_total_nbr; + } + + cfg_nbr = 0u; + while ((cfg_nbr < cfg_nbr_total) + && (if_grp_en == false)) { + p_config = usbd_core_get_configuration_structure(p_dev, cfg_nbr | cfg_nbr_spd); + if (p_config != NULL) { + if (p_config->interface_group_nbr_total > 0u) { + if_grp_en = true; + } + cfg_nbr++; + } + } + if (if_grp_en == false) { + // Dev class is specified in IF desc. + usbd_core_write_08b_to_descriptor_buf(p_dev, SL_USBD_CLASS_CODE_USE_IF_DESC); + usbd_core_write_08b_to_descriptor_buf(p_dev, SL_USBD_SUBCLASS_CODE_USE_IF_DESC); + usbd_core_write_08b_to_descriptor_buf(p_dev, SL_USBD_PROTOCOL_CODE_USE_IF_DESC); + } else { + // Multi-Interface function dev class. + usbd_core_write_08b_to_descriptor_buf(p_dev, SL_USBD_CLASS_CODE_MISCELLANEOUS); + usbd_core_write_08b_to_descriptor_buf(p_dev, SL_USBD_SUBCLASS_CODE_USE_COMMON_CLASS); + usbd_core_write_08b_to_descriptor_buf(p_dev, SL_USBD_PROTOCOL_CODE_USE_IAD); + } + // Set max pkt size for ctrl EP. + usbd_core_write_08b_to_descriptor_buf(p_dev, (uint8_t)p_dev->endpoint_max_ctrl_pkt_size); + usbd_core_write_08b_to_descriptor_buf(p_dev, cfg_nbr_total); + usbd_core_write_08b_to_descriptor_buf(p_dev, 0u); +} +#endif + + return usbd_core_stop_descriptor_write(p_dev); +} + +/****************************************************************************************************//** + * usbd_core_send_configuration_descriptor() + * + * @brief Send configuration descriptor. + * + * @param p_dev Pointer to device struct. + * + * @param ----- Argument validated in 'USBD_DevSetupPkt()' before posting the event to queue. + * + * @param cfg_nbr Configuration number. + * + * @param other Other speed configuration : + * false Descriptor is build for the current speed. + * true Descriptor is build for the other speed. + * + * @param req_len Requested length by the host. + * + * @return Returns SL_STATUS_OK on success or another SL_STATUS code on failure. + *******************************************************************************************************/ +static sl_status_t usbd_core_send_configuration_descriptor(sli_usbd_device_t *p_dev, + uint8_t config_nbr, + bool other, + uint16_t req_len) +{ + sli_usbd_configuration_t *p_config; + sli_usbd_interface_t *p_if; + sli_usbd_endpoint_info_t *p_ep; + sli_usbd_alt_interface_t *p_if_alt; + sli_usbd_interface_group_t *p_if_grp; + sl_usbd_class_driver_t *p_if_drv; + uint8_t cfg_nbr_cur; + uint8_t ep_nbr; + uint8_t if_nbr; + uint8_t if_total; + uint8_t if_grp_cur; + uint8_t if_alt_nbr; + uint8_t attrib; +#if (USBD_CFG_STR_EN == 1) + uint8_t str_ix; +#endif +#if (USBD_CFG_OPTIMIZE_SPD == 1) + uint32_t ep_alloc_map; +#endif + +#if (USBD_CFG_HS_EN == 1) + if (p_dev->speed == SL_USBD_DEVICE_SPEED_HIGH) { + cfg_nbr_cur = config_nbr | SL_USBD_CONFIG_NBR_SPD_BIT; + } else { +#endif + cfg_nbr_cur = config_nbr; +#if (USBD_CFG_HS_EN == 1) +} +#endif + + p_config = usbd_core_get_configuration_structure(p_dev, cfg_nbr_cur); + + if (p_config == NULL) { + return SL_STATUS_INVALID_PARAMETER; + } + +#if (USBD_CFG_HS_EN == 1) + // other will always be false when HS is disabled. + if (other == true) { + if (p_config->config_other_speed == SL_USBD_CONFIG_NBR_NONE) { + return SL_STATUS_INVALID_PARAMETER; + } + + cfg_nbr_cur = p_config->config_other_speed; + + // Retrieve cfg struct for other spd. + p_config = usbd_core_get_configuration_structure(p_dev, cfg_nbr_cur); + if (p_config == NULL) { + return SL_STATUS_INVALID_PARAMETER; + } + } +#endif + + // Init cfg desc len. + p_config->desc_len = SL_USBD_DESC_LEN_CFG; + + // Build Configuration Descriptor + usbd_core_start_descriptor_write(p_dev, req_len); + + // Desc len. + usbd_core_write_08b_to_descriptor_buf(p_dev, SL_USBD_DESC_LEN_CFG); + // Desc type. + if (other == true) { + usbd_core_write_08b_to_descriptor_buf(p_dev, SL_USBD_DESC_TYPE_OTHER_SPEED_CONFIGURATION); + } else { + usbd_core_write_08b_to_descriptor_buf(p_dev, SL_USBD_DESC_TYPE_CONFIGURATION); + } + + if_total = p_config->interface_nbr_total; + if_grp_cur = SL_USBD_INTERFACE_GROUP_NBR_NONE; + + for (if_nbr = 0u; if_nbr < if_total; if_nbr++) { + p_if = usbd_core_get_interface_structure(p_config, if_nbr); + p_if_drv = p_if->class_driver_ptr; + + if ((p_if->group_nbr != if_grp_cur) + && (p_if->group_nbr != SL_USBD_INTERFACE_GROUP_NBR_NONE)) { + // Add IF assoc desc len. + p_config->desc_len += SL_USBD_DESC_LEN_IF_ASSOCIATION; + if_grp_cur = p_if->group_nbr; + } + + p_config->desc_len += (SL_USBD_DESC_LEN_IF * p_if->alt_nbr_total); + + for (if_alt_nbr = 0u; if_alt_nbr < p_if->alt_nbr_total; if_alt_nbr++) { + p_if_alt = usbd_core_get_alt_interface_structure(p_if, if_alt_nbr); + p_config->desc_len += (SL_USBD_DESC_LEN_EP * p_if_alt->endpoint_nbr_total); + + // Add IF functional desc len. + if (p_if_drv->interface_get_descriptor_size != NULL) { + p_config->desc_len += p_if_drv->interface_get_descriptor_size(cfg_nbr_cur, + if_nbr, + if_alt_nbr, + p_if->class_arg_ptr, + p_if_alt->class_arg_ptr); + } + +#if (USBD_CFG_OPTIMIZE_SPD == 1) + ep_alloc_map = p_if_alt->endpoint_table_map; + while (ep_alloc_map != 0x00u) { + ep_nbr = (uint8_t)__CLZ(__RBIT(ep_alloc_map)); + p_ep = p_if_alt->endpoint_table_ptrs[ep_nbr]; + + // Add EP functional desc len. + if (p_if_drv->endpoint_get_descriptor_size != NULL) { + p_config->desc_len += p_if_drv->endpoint_get_descriptor_size(cfg_nbr_cur, + if_nbr, + if_alt_nbr, + p_ep->address, + p_if->class_arg_ptr, + p_if_alt->class_arg_ptr); + } + + if ((p_if->class_code == SL_USBD_CLASS_CODE_AUDIO) + && (p_if->class_protocol_code == 0u) + && (((p_ep->attrib & SL_USBD_ENDPOINT_TYPE_MASK) == SL_USBD_ENDPOINT_TYPE_ISOC) + || ((p_ep->attrib & SL_USBD_ENDPOINT_TYPE_MASK) == SL_USBD_ENDPOINT_TYPE_INTR))) { + // EP desc on audio class v1.0 has 2 additional fields. + p_config->desc_len += 2u; + } + + SL_CLEAR_BIT(ep_alloc_map, SLI_USBD_SINGLE_BIT_MASK_32(ep_nbr)); + } +#else + p_ep = p_if_alt->endpoint_head_ptr; + + for (ep_nbr = 0u; ep_nbr < p_if_alt->endpoint_nbr_total; ep_nbr++) { + if (p_if_drv->endpoint_get_descriptor_size != NULL) { + p_config->desc_len += p_if_drv->endpoint_get_descriptor_size(cfg_nbr_cur, + if_nbr, + if_alt_nbr, + p_ep->address, + p_if->class_arg_ptr, + p_if_alt->class_arg_ptr); + } + + if ((p_if->class_code == SL_USBD_CLASS_CODE_AUDIO) + && (p_if->class_protocol_code == 0u) + && (((p_ep->attrib & SL_USBD_ENDPOINT_TYPE_MASK) == SL_USBD_ENDPOINT_TYPE_ISOC) + || ((p_ep->attrib & SL_USBD_ENDPOINT_TYPE_MASK) == SL_USBD_ENDPOINT_TYPE_INTR))) { + // EP desc on audio class v1.0 has 2 additional fields. + p_config->desc_len += 2u; + } + + p_ep = p_ep->next_ptr; + } +#endif + } + } + + // Build Cfg Desc + // Desc len. + usbd_core_write_16b_to_descriptor_buf(p_dev, p_config->desc_len); + // nbr of IF. + usbd_core_write_08b_to_descriptor_buf(p_dev, p_config->interface_nbr_total); + // Cfg ix. + usbd_core_write_08b_to_descriptor_buf(p_dev, config_nbr + 1u); + +#if (USBD_CFG_STR_EN == 1) + // Add str ix. + str_ix = usbd_core_get_string_index(p_dev, p_config->name_ptr); + usbd_core_write_08b_to_descriptor_buf(p_dev, str_ix); +#else + usbd_core_write_08b_to_descriptor_buf(p_dev, 0u); +#endif + + attrib = SLI_USBD_CONFIG_DESC_RSVD_SET; + if (SL_IS_BIT_SET(p_config->attrib, SL_USBD_DEV_ATTRIB_SELF_POWERED)) { + SL_SET_BIT(attrib, SLI_USBD_CONFIG_DESC_SELF_POWERED); + } + if (SL_IS_BIT_SET(p_config->attrib, SL_USBD_DEV_ATTRIB_REMOTE_WAKEUP)) { + SL_SET_BIT(attrib, SLI_USBD_CONFIG_DESC_REMOTE_WAKEUP); + } + usbd_core_write_08b_to_descriptor_buf(p_dev, attrib); + usbd_core_write_08b_to_descriptor_buf(p_dev, (uint8_t)((p_config->max_power + 1u) / 2u)); + + // Build Interface Descriptor + if_total = p_config->interface_nbr_total; + if_grp_cur = SL_USBD_INTERFACE_GROUP_NBR_NONE; + + for (if_nbr = 0u; if_nbr < if_total; if_nbr++) { + p_if = usbd_core_get_interface_structure(p_config, if_nbr); + p_if_drv = p_if->class_driver_ptr; + + if ((p_if->group_nbr != if_grp_cur) + && (p_if->group_nbr != SL_USBD_INTERFACE_GROUP_NBR_NONE)) { + // Add IF assoc desc (IAD). + p_if_grp = usbd_core_get_interface_group_structure(p_config, p_if->group_nbr); + + usbd_core_write_08b_to_descriptor_buf(p_dev, SL_USBD_DESC_LEN_IF_ASSOCIATION); + usbd_core_write_08b_to_descriptor_buf(p_dev, SL_USBD_DESC_TYPE_IAD); + usbd_core_write_08b_to_descriptor_buf(p_dev, p_if_grp->interface_start); + usbd_core_write_08b_to_descriptor_buf(p_dev, p_if_grp->interface_count); + usbd_core_write_08b_to_descriptor_buf(p_dev, p_if_grp->class_code); + usbd_core_write_08b_to_descriptor_buf(p_dev, p_if_grp->class_sub_code); + usbd_core_write_08b_to_descriptor_buf(p_dev, p_if_grp->class_protocol_code); + +#if (USBD_CFG_STR_EN == 1) + str_ix = usbd_core_get_string_index(p_dev, p_if_grp->name_ptr); + usbd_core_write_08b_to_descriptor_buf(p_dev, str_ix); +#else + usbd_core_write_08b_to_descriptor_buf(p_dev, 0u); +#endif + + if_grp_cur = p_if->group_nbr; + } + // Add IF/alt settings desc. + for (if_alt_nbr = 0u; if_alt_nbr < p_if->alt_nbr_total; if_alt_nbr++) { + p_if_alt = usbd_core_get_alt_interface_structure(p_if, if_alt_nbr); + + usbd_core_write_08b_to_descriptor_buf(p_dev, SL_USBD_DESC_LEN_IF); + usbd_core_write_08b_to_descriptor_buf(p_dev, SL_USBD_DESC_TYPE_INTERFACE); + usbd_core_write_08b_to_descriptor_buf(p_dev, if_nbr); + usbd_core_write_08b_to_descriptor_buf(p_dev, if_alt_nbr); + usbd_core_write_08b_to_descriptor_buf(p_dev, p_if_alt->endpoint_nbr_total); + usbd_core_write_08b_to_descriptor_buf(p_dev, p_if->class_code); + usbd_core_write_08b_to_descriptor_buf(p_dev, p_if->class_sub_code); + usbd_core_write_08b_to_descriptor_buf(p_dev, p_if->class_protocol_code); + +#if (USBD_CFG_STR_EN == 1) + str_ix = usbd_core_get_string_index(p_dev, p_if_alt->name_ptr); + usbd_core_write_08b_to_descriptor_buf(p_dev, str_ix); +#else + usbd_core_write_08b_to_descriptor_buf(p_dev, 0u); +#endif + + if (p_if_drv->interface_descriptor != NULL) { + // Add class specific IF desc. + p_if_drv->interface_descriptor(cfg_nbr_cur, + if_nbr, + if_alt_nbr, + p_if->class_arg_ptr, + p_if_alt->class_arg_ptr); + } + // Build EP Desc +#if (USBD_CFG_OPTIMIZE_SPD == 1) + ep_alloc_map = p_if_alt->endpoint_table_map; + while (ep_alloc_map != 0x00u) { + ep_nbr = (uint8_t)__CLZ(__RBIT(ep_alloc_map)); + p_ep = p_if_alt->endpoint_table_ptrs[ep_nbr]; + + if ((p_if->class_code == SL_USBD_CLASS_CODE_AUDIO) + && (p_if->class_protocol_code == 0u) + && (((p_ep->attrib & SL_USBD_ENDPOINT_TYPE_MASK) == SL_USBD_ENDPOINT_TYPE_ISOC) + || ((p_ep->attrib & SL_USBD_ENDPOINT_TYPE_MASK) == SL_USBD_ENDPOINT_TYPE_INTR))) { + // EP desc on audio class v1.0 has 2 additional fields. + usbd_core_write_08b_to_descriptor_buf(p_dev, SL_USBD_DESC_LEN_EP + 2u); + } else { + usbd_core_write_08b_to_descriptor_buf(p_dev, SL_USBD_DESC_LEN_EP); + } + + usbd_core_write_08b_to_descriptor_buf(p_dev, SL_USBD_DESC_TYPE_ENDPOINT); + usbd_core_write_08b_to_descriptor_buf(p_dev, p_ep->address); + usbd_core_write_08b_to_descriptor_buf(p_dev, p_ep->attrib); + usbd_core_write_16b_to_descriptor_buf(p_dev, p_ep->max_pkt_size); + usbd_core_write_08b_to_descriptor_buf(p_dev, p_ep->interval); + + if ((p_if->class_code == SL_USBD_CLASS_CODE_AUDIO) + && (p_if->class_protocol_code == 0u) + && (((p_ep->attrib & SL_USBD_ENDPOINT_TYPE_MASK) == SL_USBD_ENDPOINT_TYPE_ISOC) + || ((p_ep->attrib & SL_USBD_ENDPOINT_TYPE_MASK) == SL_USBD_ENDPOINT_TYPE_INTR))) { + // EP desc on audio class v1.0 has 2 additional fields. + usbd_core_write_08b_to_descriptor_buf(p_dev, p_ep->sync_refresh); + usbd_core_write_08b_to_descriptor_buf(p_dev, p_ep->sync_addr); + } + + if (p_if_drv->endpoint_descriptor != NULL) { + // Add class specific EP desc. + p_if_drv->endpoint_descriptor(cfg_nbr_cur, + if_nbr, + if_alt_nbr, + p_ep->address, + p_if->class_arg_ptr, + p_if_alt->class_arg_ptr); + } + + SL_CLEAR_BIT(ep_alloc_map, SLI_USBD_SINGLE_BIT_MASK_32(ep_nbr)); + } +#else + p_ep = p_if_alt->endpoint_head_ptr; + + for (ep_nbr = 0u; ep_nbr < p_if_alt->endpoint_nbr_total; ep_nbr++) { + if ((p_if->class_code == SL_USBD_CLASS_CODE_AUDIO) + && (p_if->class_protocol_code == 0u) + && (((p_ep->attrib & SL_USBD_ENDPOINT_TYPE_MASK) == SL_USBD_ENDPOINT_TYPE_ISOC) + || ((p_ep->attrib & SL_USBD_ENDPOINT_TYPE_MASK) == SL_USBD_ENDPOINT_TYPE_INTR))) { + // EP desc on audio class v1.0 has 2 additional fields. + usbd_core_write_08b_to_descriptor_buf(p_dev, SL_USBD_DESC_LEN_EP + 2u); + } else { + usbd_core_write_08b_to_descriptor_buf(p_dev, SL_USBD_DESC_LEN_EP); + } + + usbd_core_write_08b_to_descriptor_buf(p_dev, SL_USBD_DESC_TYPE_ENDPOINT); + usbd_core_write_08b_to_descriptor_buf(p_dev, p_ep->address); + usbd_core_write_08b_to_descriptor_buf(p_dev, p_ep->attrib); + usbd_core_write_16b_to_descriptor_buf(p_dev, p_ep->max_pkt_size); + usbd_core_write_08b_to_descriptor_buf(p_dev, p_ep->interval); + + if ((p_if->class_code == SL_USBD_CLASS_CODE_AUDIO) + && (p_if->class_protocol_code == 0u) + && (((p_ep->attrib & SL_USBD_ENDPOINT_TYPE_MASK) == SL_USBD_ENDPOINT_TYPE_ISOC) + || ((p_ep->attrib & SL_USBD_ENDPOINT_TYPE_MASK) == SL_USBD_ENDPOINT_TYPE_INTR))) { + // EP desc on audio class v1.0 has 2 additional fields. + usbd_core_write_08b_to_descriptor_buf(p_dev, p_ep->sync_refresh); + usbd_core_write_08b_to_descriptor_buf(p_dev, p_ep->sync_addr); + } + + if (p_if_drv->endpoint_descriptor != NULL) { + // Add class specific EP desc. + p_if_drv->endpoint_descriptor(cfg_nbr_cur, + if_nbr, + if_alt_nbr, + p_ep->address, + p_if->class_arg_ptr, + p_if_alt->class_arg_ptr); + } + + p_ep = p_ep->next_ptr; + } +#endif + } + } + + return usbd_core_stop_descriptor_write(p_dev); +} + +/****************************************************************************************************//** + * usbd_core_send_string_descriptor() + * + * @brief Send string descriptor. + * + * @param p_dev Pointer to USB device. + * + * @param ----- Argument validated in 'USBD_DevSetupPkt()' before posting the event to queue. + * + * @param str_ix String index. + * + * @param req_len Requested length by the host. + * + * @return Returns SL_STATUS_OK on success or another SL_STATUS code on failure. + *******************************************************************************************************/ + +#if (USBD_CFG_STR_EN == 1) +static sl_status_t usbd_core_send_string_descriptor(sli_usbd_device_t *p_dev, + uint8_t str_ix, + uint16_t req_len) +{ + const char *p_str; + size_t len; +#if (USBD_CFG_MS_OS_DESC_EN == 1) + uint8_t ix; +#endif + + usbd_core_start_descriptor_write(p_dev, req_len); + + switch (str_ix) { + case 0u: + usbd_core_write_08b_to_descriptor_buf(p_dev, 4u); + usbd_core_write_08b_to_descriptor_buf(p_dev, SL_USBD_DESC_TYPE_STRING); + usbd_core_write_16b_to_descriptor_buf(p_dev, p_dev->device_config.lang_id); + break; + +#if (USBD_CFG_MS_OS_DESC_EN == 1) + case SLI_USBD_MICROSOFT_STR_IX: + usbd_core_write_08b_to_descriptor_buf(p_dev, SLI_USBD_MICROSOFT_STR_LEN); + usbd_core_write_08b_to_descriptor_buf(p_dev, SL_USBD_DESC_TYPE_STRING); + + for (ix = 0u; ix < 7u; ix++) { + usbd_core_write_08b_to_descriptor_buf(p_dev, (uint8_t)usbd_microsoft_signature_str[ix]); + usbd_core_write_08b_to_descriptor_buf(p_dev, 0u); + } + + usbd_core_write_08b_to_descriptor_buf(p_dev, p_dev->str_microsoft_vendor_code); + usbd_core_write_08b_to_descriptor_buf(p_dev, 0u); + break; +#endif + + default: + p_str = usbd_core_get_string_descriptor(p_dev, str_ix - 1u); + if (p_str != NULL) { + len = sl_strlen((char *)p_str); + len = (2u * len) + 2u; + len = SLI_USBD_GET_MIN(len, 255u); + len = len - (len % 2u); + + usbd_core_write_08b_to_descriptor_buf(p_dev, (uint8_t)len); + usbd_core_write_08b_to_descriptor_buf(p_dev, SL_USBD_DESC_TYPE_STRING); + + while (*p_str != '\0') { + usbd_core_write_08b_to_descriptor_buf(p_dev, (uint8_t)*p_str); + usbd_core_write_08b_to_descriptor_buf(p_dev, 0u); + + p_str++; + } + } else { + return SL_STATUS_NULL_POINTER; + } + break; + } + + return usbd_core_stop_descriptor_write(p_dev); +} +#endif + +/****************************************************************************************************//** + * usbd_core_start_descriptor_write() + * + * @brief Start write operation in the descriptor buffer. + * + * @param p_dev Pointer to USB device. + * + * @param ----- Argument validated in 'USBD_DevSetupPkt()' before posting the event to queue. + * + * @param req_len Requested length by the host. + *******************************************************************************************************/ +static void usbd_core_start_descriptor_write(sli_usbd_device_t *p_dev, + uint16_t req_len) +{ + CORE_DECLARE_IRQ_STATE; + + CORE_ENTER_ATOMIC(); + p_dev->desc_buf_index = 0u; + p_dev->desc_buf_req_len = req_len; + CORE_EXIT_ATOMIC(); +} + +/****************************************************************************************************//** + * usbd_core_stop_descriptor_write() + * + * @brief Stop write operation in the descriptor buffer. + * + * @param p_dev Pointer to USB device. + * + * @param ----- Argument validated in 'USBD_DevSetupPkt()' before posting the event to queue. + * + * @return Returns SL_STATUS_OK on success or another SL_STATUS code on failure. + * + * @note (1) This function might be called in two contexts: when a Get Descriptor standard request + * is received, or when a driver supporting standard request auto-reply queries the + * device, a configuration or a string descriptor. The descriptor needs to be sent on + * control endpoint 0 only if this function is called for a Get Descriptor standard + * request. If the function is called when a driver needs the descriptor, nothing has to + * be done. + *******************************************************************************************************/ +static sl_status_t usbd_core_stop_descriptor_write(sli_usbd_device_t *p_dev) +{ + uint32_t xfer_len; + sl_status_t status; + + status = SL_STATUS_OK; + + // See Note #1. + if (p_dev->actual_buf_ptr == p_dev->desc_buf_ptr) { + if (p_dev->desc_buf_index > 0u) { + uint32_t std_req_timeout; + CORE_DECLARE_IRQ_STATE; + + CORE_ENTER_ATOMIC(); + std_req_timeout = usbd_ptr->std_req_timeout_ms; + CORE_EXIT_ATOMIC(); + + status = sl_usbd_core_write_control_sync(&p_dev->desc_buf_ptr[0u], + (uint32_t)p_dev->desc_buf_index, + std_req_timeout, + (p_dev->desc_buf_req_len > 0u) ? true : false, + &xfer_len); + } + } + + return status; +} + +/****************************************************************************************************//** + * usbd_core_write_08b_to_descriptor_buf() + * + * @brief Write 8-bit value in the descriptor buffer. + * + * @param p_dev Pointer to device. + * + * @param val 8-bit value. + *******************************************************************************************************/ +static void usbd_core_write_08b_to_descriptor_buf(sli_usbd_device_t *p_dev, + uint8_t val) +{ + if (*(p_dev->desc_buf_status_ptr) == SL_STATUS_OK) { + usbd_core_write_to_descriptor_buf(p_dev, &val, 1u); + } +} + +/****************************************************************************************************//** + * sl_usbd_core_write_16b_to_descriptor_buf() + * + * @brief Write 16-bit value in the descriptor buffer. + * + * @param p_dev Pointer to device. + * + * @param val 16-bit value. + *******************************************************************************************************/ +static void usbd_core_write_16b_to_descriptor_buf(sli_usbd_device_t *p_dev, + uint16_t val) +{ + if (*(p_dev->desc_buf_status_ptr) == SL_STATUS_OK) { + uint8_t buf[2u]; + + buf[0u] = (uint8_t)(val & 0xFFu); + buf[1u] = (uint8_t)((val >> 8u) & 0xFFu); + + usbd_core_write_to_descriptor_buf(p_dev, &buf[0u], 2u); + } +} + +/****************************************************************************************************//** + * usbd_core_write_to_descriptor_buf() + * + * @brief USB device configuration write request. + * + * @param p_dev Pointer to device. + * + * @param p_buf Pointer to data buffer. + * + * @param len Buffer length. + * + * @note (1) This function might be called in two contexts: when a Get Descriptor standard request + * is received, or when a driver supporting standard request auto-reply queries the + * device, a configuration or a string descriptor. In the Get Descriptor standard + * request case, if the buffer is full, a transfer on control endpoint 0 is done, before + * resuming to fill the buffer. In the case of a driver supporting standard request + * auto-reply, if the buffer is full, an error is set and the function exits. + * + * @note (2) If an error is reported by sl_usbd_core_write_control_sync() during the construction of the descriptor, + * this pointer will store the error code, stop the rest of the data phase, skip the + * status phase and ensure that the control endpoint 0 is stalled to notify the host + * that an error has occurred. + *******************************************************************************************************/ +static void usbd_core_write_to_descriptor_buf(sli_usbd_device_t *p_dev, + const uint8_t *p_buf, + uint16_t len) +{ + uint8_t *p_desc; + uint8_t buf_cur_ix; + uint16_t len_req; + uint32_t xfer_len; + sl_status_t status; + CORE_DECLARE_IRQ_STATE; + + p_desc = p_dev->actual_buf_ptr; + buf_cur_ix = p_dev->desc_buf_index; + len_req = p_dev->desc_buf_req_len; + status = SL_STATUS_OK; + + while ((len_req != 0u) + && (len != 0u)) { + if (buf_cur_ix >= p_dev->desc_buf_max_len) { + // Send data in response to std req. See Note #1. + if (p_dev->actual_buf_ptr == p_dev->desc_buf_ptr) { + uint32_t std_req_timeout; + + CORE_ENTER_ATOMIC(); + std_req_timeout = usbd_ptr->std_req_timeout_ms; + CORE_EXIT_ATOMIC(); + + buf_cur_ix = 0u; + status = sl_usbd_core_write_control_sync(&p_dev->desc_buf_ptr[0u], + SLI_USBD_DESC_BUF_LEN, + std_req_timeout, + false, + &xfer_len); + if (status != SL_STATUS_OK) { + break; + } + } else { + // Buf provided by driver is too small. See Note #1. + len_req = 0u; + status = SL_STATUS_ALLOCATION_FAILED; + } + } else { + p_desc[buf_cur_ix] = *p_buf; + p_buf++; + len--; + len_req--; + buf_cur_ix++; + } + } + + CORE_ENTER_ATOMIC(); + p_dev->desc_buf_index = buf_cur_ix; + p_dev->desc_buf_req_len = len_req; + if (p_dev->desc_buf_status_ptr != NULL) { + // See Note #2. + *(p_dev->desc_buf_status_ptr) = status; + } + CORE_EXIT_ATOMIC(); +} + +/****************************************************************************************************//** + * usbd_core_get_configuration_structure() + * + * @brief Get configuration structure. + * + * @param p_dev Pointer to device struct. + * + * @param config_nbr Configuration number. + * + * @return Pointer to configuration structure, if no errors are returned. + * + * Pointer to NULL, if any errors are returned. + *******************************************************************************************************/ +static sli_usbd_configuration_t *usbd_core_get_configuration_structure(const sli_usbd_device_t *p_dev, + uint8_t config_nbr) +{ + sli_usbd_configuration_t *p_config; + uint8_t cfg_val; +#if (USBD_CFG_OPTIMIZE_SPD == 0) + uint8_t config_ix; +#endif + +#if (USBD_CFG_HS_EN == 1) + // SL_USBD_CONFIG_NBR_SPD_BIT will always be clear in FS. + cfg_val = config_nbr & (uint8_t)(~SL_USBD_CONFIG_NBR_SPD_BIT); +#else + cfg_val = config_nbr; +#endif + +#if (USBD_CFG_OPTIMIZE_SPD == 1) // Array implementation. +#if (USBD_CFG_HS_EN == 1) + if (SL_IS_BIT_SET(config_nbr, SL_USBD_CONFIG_NBR_SPD_BIT) == true) { + // Chk if cfg nbr is valid. + if (cfg_val >= p_dev->config_hs_total_nbr) { + return (NULL); + } + // Get HS cfg struct. + p_config = p_dev->config_hs_speed_table_ptrs[cfg_val]; + } else { +#endif + // Chk if cfg nbr is valid. + if (cfg_val >= p_dev->config_fs_total_nbr) { + return (NULL); + } + // Get FS cfg struct. + p_config = p_dev->config_fs_speed_table_ptrs[cfg_val]; +#if (USBD_CFG_HS_EN == 1) +} +#endif +#else // Linked-list implementation. +#if (USBD_CFG_HS_EN == 1) + if (SL_IS_BIT_SET(config_nbr, SL_USBD_CONFIG_NBR_SPD_BIT)) { + // Chk if cfg nbr is valid. + if (cfg_val >= p_dev->config_hs_total_nbr) { + return (NULL); + } + p_config = p_dev->config_hs_head_ptr; + } else { +#endif + // Chk if cfg nbr is valid. + if (cfg_val >= p_dev->config_fs_total_nbr) { + return (NULL); + } + p_config = p_dev->config_fs_head_ptr; +#if (USBD_CFG_HS_EN == 1) +} +#endif + + // Iterate thru list until to get cfg struct. + for (config_ix = 0u; config_ix < cfg_val; config_ix++) { + p_config = p_config->next_ptr; + } +#endif + + return (p_config); +} + +/****************************************************************************************************//** + * usbd_core_set_event() + * + * @brief Send an event to the core task. + * + * @param event Event code : + * SLI_USBD_EVENT_BUS_RESET reset. + * SLI_USBD_EVENT_BUS_SUSPEND suspend. + * SLI_USBD_EVENT_BUS_RESUME resume. + * SLI_USBD_EVENT_BUS_CONNECT Connect. + * SLI_USBD_EVENT_BUS_DISCONNECT Disconnect. + * SLI_USBD_EVENT_BUS_HS High speed. + * SLI_USBD_EVENT_ENDPOINT Endpoint. + * SLI_USBD_EVENT_SETUP Setup. + *******************************************************************************************************/ +static void usbd_core_set_event(sli_usbd_event_code_t event) +{ + sli_usbd_core_event_t core_event; + + core_event.type = event; + core_event.status = SL_STATUS_OK; + + sli_usbd_core_os_put_core_event(&core_event); +} + +/****************************************************************************************************//** + * Processes all core events and core operations + *******************************************************************************************************/ +void sli_usbd_core_task_handler(void) +{ + sli_usbd_core_event_t core_event; + sli_usbd_device_t *p_dev; + uint8_t ep_addr; + sli_usbd_event_code_t event; + sl_status_t xfer_status; + sl_status_t status; + +#if SL_USBD_AUTO_START_USB_DEVICE == 1 + sl_usbd_core_start_device(); +#endif + + // event loop + while (true) { + // Wait for an event. + status = sli_usbd_core_os_get_core_event((void *) &core_event); + if (status == SL_STATUS_OK) { + event = core_event.type; + p_dev = &usbd_ptr->device; + + // Decode event. + switch (event) { + // Bus Events + case SLI_USBD_EVENT_BUS_RESET: + case SLI_USBD_EVENT_BUS_RESUME: + case SLI_USBD_EVENT_BUS_CONNECT: + case SLI_USBD_EVENT_BUS_HS: + case SLI_USBD_EVENT_BUS_SUSPEND: + case SLI_USBD_EVENT_BUS_DISCONNECT: + usbd_core_process_event(p_dev, event); + break; + + // Endpoint Events + case SLI_USBD_EVENT_ENDPOINT: + if (p_dev->state == SL_USBD_DEVICE_STATE_SUSPENDED) { + p_dev->state = p_dev->state_prev; + } + ep_addr = core_event.endpoint_address; + xfer_status = core_event.status; + sl_usbd_core_endpoint_transfer_async(ep_addr, xfer_status); + break; + + // Setup Events + case SLI_USBD_EVENT_SETUP: + SLI_USBD_DBG_STATS_DEV_INC(device_setup_event_nbr); + if (p_dev->state == SL_USBD_DEVICE_STATE_SUSPENDED) { + p_dev->state = p_dev->state_prev; + } + usbd_core_stdreq_handler(p_dev); + break; + + default: + break; + } + } + } +} + +/****************************************************************************************************//** + * usbd_core_process_event() + * + * @brief Processes bus related events. + * + * @param p_dev Pointer to USB device. + * + * @param ----- Argument validated in 'USBD_DevSetupPkt()' before posting the event to queue. + * + * @param event Bus related events : + * SLI_USBD_EVENT_BUS_RESET reset. + * SLI_USBD_EVENT_BUS_SUSPEND suspend. + * SLI_USBD_EVENT_BUS_RESUME resume. + * SLI_USBD_EVENT_BUS_CONNECT Connect. + * SLI_USBD_EVENT_BUS_DISCONNECT Disconnect. + * SLI_USBD_EVENT_BUS_HS High speed. + * + * @note (1) This prevents a suspend event to overwrite the internal status with a suspend state in + * the case of multiple suspend events in a row. + * + * @note (2) USB Spec 2.0 section 9.1.1.6 states "When suspended, the USB device maintains any + * internal status, including its address and configuration." + * + * @note (3) A suspend event is usually followed by a resume event when the bus activity comes back. + * But in some cases, after a suspend event, a reset event can be notified to the Core + * before a resume event. Thus, the internal state of the device should not be changed + * to the previous one. + *******************************************************************************************************/ +static void usbd_core_process_event(sli_usbd_device_t *p_dev, + sli_usbd_event_code_t event) +{ + CORE_DECLARE_IRQ_STATE; + + switch (event) { + case SLI_USBD_EVENT_BUS_RESET: + SLI_USBD_DBG_STATS_DEV_INC(device_reset_event_nbr); + SLI_USBD_LOG_VRB_TO(SLI_USBD_LOG_BUS_CH, ("USBD Bus: reset")); + + CORE_ENTER_ATOMIC(); + if (p_dev->conn_status == false) { + p_dev->conn_status = true; + CORE_EXIT_ATOMIC(); + + // Call application connect callback. + sl_usbd_on_bus_event(SL_USBD_EVENT_BUS_CONNECT); + } else { + CORE_EXIT_ATOMIC(); + } + + // Close ctrl EP. + sli_usbd_core_close_control_endpoint(); + + if (p_dev->config_cur_nbr != SL_USBD_CONFIG_NBR_NONE) { + // Close curr cfg. + usbd_core_unset_configuration(p_dev); + } + + // Open ctrl EP. + sli_usbd_core_open_control_endpoint(p_dev->endpoint_max_ctrl_pkt_size); + + // Set dev in default state, reset dev speed. + CORE_ENTER_ATOMIC(); + p_dev->address = 0u; + p_dev->state = SL_USBD_DEVICE_STATE_DEFAULT; + p_dev->speed = SL_USBD_DEVICE_SPEED_FULL; + CORE_EXIT_ATOMIC(); + + // Call application reset callback. + sl_usbd_on_bus_event(SL_USBD_EVENT_BUS_RESET); + + break; + + case SLI_USBD_EVENT_BUS_SUSPEND: + SLI_USBD_DBG_STATS_DEV_INC(device_suspend_event_nbr); + SLI_USBD_LOG_VRB_TO(SLI_USBD_LOG_BUS_CH, ("USBD Bus: suspend")); + + CORE_ENTER_ATOMIC(); + // See Note #1. + if (p_dev->state != SL_USBD_DEVICE_STATE_SUSPENDED) { + // Save cur state (see Note #2). + p_dev->state_prev = p_dev->state; + } + // Set suspended state. + p_dev->state = SL_USBD_DEVICE_STATE_SUSPENDED; + CORE_EXIT_ATOMIC(); + + // Call application suspend callback. + sl_usbd_on_bus_event(SL_USBD_EVENT_BUS_SUSPEND); + break; + + case SLI_USBD_EVENT_BUS_RESUME: + SLI_USBD_DBG_STATS_DEV_INC(device_resume_event_nbr); + SLI_USBD_LOG_VRB_TO(SLI_USBD_LOG_BUS_CH, ("USBD Bus: resume")); + + CORE_ENTER_ATOMIC(); + // See Note #3. + if (p_dev->state == SL_USBD_DEVICE_STATE_SUSPENDED) { + // Restore prev state. + p_dev->state = p_dev->state_prev; + } + CORE_EXIT_ATOMIC(); + + // Call application resume callback. + sl_usbd_on_bus_event(SL_USBD_EVENT_BUS_RESUME); + + break; + + case SLI_USBD_EVENT_BUS_CONNECT: + SLI_USBD_DBG_STATS_DEV_INC(device_conn_event_nbr); + SLI_USBD_LOG_VRB_TO(SLI_USBD_LOG_BUS_CH, ("USBD Bus: Connect")); + + CORE_ENTER_ATOMIC(); + // Set attached state. + p_dev->state = SL_USBD_DEVICE_STATE_ATTACHED; + p_dev->conn_status = true; + CORE_EXIT_ATOMIC(); + + // Call application connect callback. + sl_usbd_on_bus_event(SL_USBD_EVENT_BUS_CONNECT); + + break; + + case SLI_USBD_EVENT_BUS_DISCONNECT: + SLI_USBD_DBG_STATS_DEV_INC(device_disconnect_event_nbr); + SLI_USBD_LOG_VRB_TO(SLI_USBD_LOG_BUS_CH, ("USBD Bus: Disconnect")); + + // Close ctrl EP. + sli_usbd_core_close_control_endpoint(); + + if (p_dev->config_cur_nbr != SL_USBD_CONFIG_NBR_NONE) { + // Close curr cfg. + usbd_core_unset_configuration(p_dev); + } + + CORE_ENTER_ATOMIC(); + // Set default address. + p_dev->address = 0u; + // Dev is not attached. + p_dev->state = SL_USBD_DEVICE_STATE_INIT; + // No active cfg. + p_dev->config_cur_nbr = SL_USBD_CONFIG_NBR_NONE; + p_dev->conn_status = false; + CORE_EXIT_ATOMIC(); + + // Call application disconnect callback. + sl_usbd_on_bus_event(SL_USBD_EVENT_BUS_DISCONNECT); + + break; + + case SLI_USBD_EVENT_BUS_HS: + SLI_USBD_LOG_VRB_TO(SLI_USBD_LOG_BUS_CH, ("USBD Bus: High Speed detection")); +#if (USBD_CFG_HS_EN == 1) + CORE_ENTER_ATOMIC(); + p_dev->speed = SL_USBD_DEVICE_SPEED_HIGH; + if (p_dev->state == SL_USBD_DEVICE_STATE_SUSPENDED) { + p_dev->state = p_dev->state_prev; + } + CORE_EXIT_ATOMIC(); +#endif + break; + + case SLI_USBD_EVENT_ENDPOINT: + case SLI_USBD_EVENT_SETUP: + default: + break; + } +} + +/****************************************************************************************************//** + * usbd_core_get_interface_structure() + * + * @brief Gets the interface structure. + * + * @param p_cfg Pointer to configuration structure. + * + * @param if_nbr Interface number. + * + * @return Pointer to interface structure, if no errors are returned. + * + * Pointer to NULL, if any errors are returned. + *******************************************************************************************************/ +static sli_usbd_interface_t *usbd_core_get_interface_structure(const sli_usbd_configuration_t *p_config, + uint8_t if_nbr) +{ + sli_usbd_interface_t *p_if; +#if (USBD_CFG_OPTIMIZE_SPD == 0) + uint8_t if_ix; +#endif + + // Chk if IF nbr is valid. + if (if_nbr >= p_config->interface_nbr_total) { + return (NULL); + } + + // Get IF struct. +#if (USBD_CFG_OPTIMIZE_SPD == 1) + p_if = p_config->interface_table_ptrs[if_nbr]; +#else + p_if = p_config->interface_head_ptr; + + for (if_ix = 0u; if_ix < if_nbr; if_ix++) { + p_if = p_if->next_ptr; + } +#endif + + return (p_if); +} + +/****************************************************************************************************//** + * usbd_core_get_alt_interface_structure() + * + * @brief Gets the alternate setting interface structure. + * + * @param p_if Pointer to interface structure. + * + * @param if_alt_nbr Alternate setting interface number. + * + * @return Pointer to alternate setting interface structure, if no errors are returned. + * + * Pointer to NULL, if any errors are returned. + *******************************************************************************************************/ +static sli_usbd_alt_interface_t *usbd_core_get_alt_interface_structure(const sli_usbd_interface_t *p_if, + uint8_t if_alt_nbr) +{ + sli_usbd_alt_interface_t *p_if_alt; +#if (USBD_CFG_OPTIMIZE_SPD == 0) + uint8_t if_alt_ix; +#endif + + // Chk alt setting nbr. + if (if_alt_nbr >= p_if->alt_nbr_total) { + return (NULL); + } + + // Get alt IF struct. +#if (USBD_CFG_OPTIMIZE_SPD == 1) + p_if_alt = p_if->alt_table_ptrs[if_alt_nbr]; +#else + p_if_alt = p_if->alt_head_ptr; + + for (if_alt_ix = 0u; if_alt_ix < if_alt_nbr; if_alt_ix++) { + p_if_alt = p_if_alt->next_ptr; + } +#endif + + return (p_if_alt); +} + +/****************************************************************************************************//** + * usbd_core_open_alt_interface() + * + * @brief Opens all endpoints from the specified alternate setting. + * + * @param p_dev Pointer to USB device. + * + * @param ----- Argument validated in 'USBD_DevSetupPkt()' before posting the event to queue. + * + * @param if_nbr Interface number. + * + * @param p_if_alt Pointer to alternate setting interface. + * + * @return Returns SL_STATUS_OK on success or another SL_STATUS code on failure. + *******************************************************************************************************/ +static sl_status_t usbd_core_open_alt_interface(sli_usbd_device_t *p_dev, + uint8_t if_nbr, + const sli_usbd_alt_interface_t *p_if_alt) +{ + uint8_t ep_nbr; + uint8_t ep_phy_nbr; + bool valid; + sli_usbd_endpoint_info_t *p_ep; +#if (USBD_CFG_OPTIMIZE_SPD == 1) + uint32_t ep_alloc_map; +#endif + sl_status_t status; + CORE_DECLARE_IRQ_STATE; + + valid = true; + +#if (USBD_CFG_OPTIMIZE_SPD == 1) + ep_alloc_map = p_if_alt->endpoint_table_map; + while (ep_alloc_map != 0x00u) { + ep_nbr = (uint8_t)__CLZ(__RBIT(ep_alloc_map)); + p_ep = p_if_alt->endpoint_table_ptrs[ep_nbr]; + ep_phy_nbr = SL_USBD_ENDPOINT_ADDR_TO_PHY(p_ep->address); + + CORE_ENTER_ATOMIC(); + p_dev->endpoint_interface_table[ep_phy_nbr] = if_nbr; + CORE_EXIT_ATOMIC(); + + status = sli_usbd_core_open_endpoint(p_ep->address, + p_ep->max_pkt_size, + p_ep->attrib, + p_ep->interval); + if (status != SL_STATUS_OK) { + valid = false; + break; + } + + SL_CLEAR_BIT(ep_alloc_map, SLI_USBD_SINGLE_BIT_MASK_32(ep_nbr)); + } +#else + p_ep = p_if_alt->endpoint_head_ptr; + + for (ep_nbr = 0u; ep_nbr < p_if_alt->endpoint_nbr_total; ep_nbr++) { + ep_phy_nbr = SL_USBD_ENDPOINT_ADDR_TO_PHY(p_ep->address); + + CORE_ENTER_ATOMIC(); + p_dev->endpoint_interface_table[ep_phy_nbr] = if_nbr; + CORE_EXIT_ATOMIC(); + + status = sli_usbd_core_open_endpoint(p_ep->address, + p_ep->max_pkt_size, + p_ep->attrib, + p_ep->interval); + if (status != SL_STATUS_OK) { + valid = false; + break; + } + + p_ep = p_ep->next_ptr; + } +#endif + + if (valid == true) { + status = SL_STATUS_OK; + } else { + usbd_core_close_alt_interface(p_dev, p_if_alt); + } + + return status; +} + +/****************************************************************************************************//** + * usbd_core_close_alt_interface() + * + * @brief Closes all endpoints from the specified alternate setting. + * + * @param p_dev Pointer to USB device. + * + * @param ----- Argument validated in 'USBD_DevSetupPkt()' before posting the event to queue. + * + * @param p_if_alt Pointer to alternate setting interface. + *******************************************************************************************************/ +static void usbd_core_close_alt_interface(sli_usbd_device_t *p_dev, + const sli_usbd_alt_interface_t *p_if_alt) +{ + uint8_t ep_nbr; + uint8_t ep_phy_nbr; + sli_usbd_endpoint_info_t *p_ep; +#if (USBD_CFG_OPTIMIZE_SPD == 1) + uint32_t ep_alloc_map; +#endif + CORE_DECLARE_IRQ_STATE; + +#if (USBD_CFG_OPTIMIZE_SPD == 1) + ep_alloc_map = p_if_alt->endpoint_table_map; + while (ep_alloc_map != 0x00u) { + ep_nbr = (uint8_t)__CLZ(__RBIT(ep_alloc_map)); + p_ep = p_if_alt->endpoint_table_ptrs[ep_nbr]; + ep_phy_nbr = SL_USBD_ENDPOINT_ADDR_TO_PHY(p_ep->address); + + CORE_ENTER_ATOMIC(); + p_dev->endpoint_interface_table[ep_phy_nbr] = SL_USBD_INTERFACE_NBR_NONE; + CORE_EXIT_ATOMIC(); + + sli_usbd_core_close_endpoint(p_ep->address); + + SL_CLEAR_BIT(ep_alloc_map, SLI_USBD_SINGLE_BIT_MASK_32(ep_nbr)); + } +#else + p_ep = p_if_alt->endpoint_head_ptr; + + for (ep_nbr = 0u; ep_nbr < p_if_alt->endpoint_nbr_total; ep_nbr++) { + ep_phy_nbr = SL_USBD_ENDPOINT_ADDR_TO_PHY(p_ep->address); + + CORE_ENTER_ATOMIC(); + p_dev->endpoint_interface_table[ep_phy_nbr] = SL_USBD_INTERFACE_NBR_NONE; + CORE_EXIT_ATOMIC(); + + sli_usbd_core_close_endpoint(p_ep->address); + + p_ep = p_ep->next_ptr; + } +#endif +} + +/****************************************************************************************************//** + * usbd_core_get_interface_group_structure() + * + * @brief Gets the interface group structure. + * + * @param p_cfg Pointer to configuration structure. + * + * @param if_grp_nbr Interface number. + * + * @return Pointer to interface group structure, if no errors are returned. + * + * Pointer to NULL, if any errors are returned. + *******************************************************************************************************/ +static sli_usbd_interface_group_t *usbd_core_get_interface_group_structure(const sli_usbd_configuration_t *p_config, + uint8_t if_grp_nbr) +{ + sli_usbd_interface_group_t *p_if_grp; +#if (USBD_CFG_OPTIMIZE_SPD == 0) + uint8_t if_grp_ix; +#endif + +#if (USBD_CFG_OPTIMIZE_SPD == 1) + p_if_grp = p_config->interface_group_table_ptrs[if_grp_nbr]; +#else + p_if_grp = p_config->interface_group_head_ptr; + + for (if_grp_ix = 0u; if_grp_ix < if_grp_nbr; if_grp_ix++) { + p_if_grp = p_if_grp->next_ptr; + } +#endif + + return (p_if_grp); +} + +/****************************************************************************************************//** + * usbd_core_add_string() + * + * @brief Adds the string to the USB device. + * + * @param p_dev Pointer to device structure. + * + * @param ----- Argument validated in the caller(s). + * + * @param p_str Pointer to string to add (see Note #1). + * + * @return Returns SL_STATUS_OK on success or another SL_STATUS code on failure. + * + * @note (1) USB spec 2.0 chapter 9.5 states "Where appropriate, descriptors contain references + * to string descriptors that provide displayable information describing a descriptor + * in human-readable form. The inclusion of string descriptors is optional. However, + * the reference fields within descriptors are mandatory. If a device does not support + * string descriptors, string reference fields must be reset to zero to indicate no + * string descriptor is available. + * + * Since string descriptors are optional, 'p_str' could be a NULL pointer. + *******************************************************************************************************/ + +#if (USBD_CFG_STR_EN == 1) +static sl_status_t usbd_core_add_string(sli_usbd_device_t *p_dev, + const char *p_str) +{ + uint8_t str_ix; + CORE_DECLARE_IRQ_STATE; + + // Return if NULL ptr. + if (p_str == NULL) { + return SL_STATUS_NULL_POINTER; + } + + for (str_ix = 0u; str_ix < p_dev->str_max_index; str_ix++) { + if (p_str == p_dev->str_descriptor_table[str_ix]) { + // Str already stored in tbl. + return SL_STATUS_OK; + } + } + + CORE_ENTER_ATOMIC(); + // Get curr str tbl ix. + str_ix = p_dev->str_max_index; + + // Chk if str can be stored in tbl. + if (str_ix >= usbd_ptr->str_quantity_per_device) { + CORE_EXIT_ATOMIC(); + return SL_STATUS_ALLOCATION_FAILED; + } + + p_dev->str_descriptor_table[str_ix] = (char *)p_str; + p_dev->str_max_index++; + CORE_EXIT_ATOMIC(); + + return SL_STATUS_OK; +} +#endif + +/****************************************************************************************************//** + * usbd_core_get_string_descriptor() + * + * @brief Gets the string pointer. + * + * @param p_dev Pointer to device. + * + * @param ----- Argument validate by the caller(s). + * + * @param str_nbr Number of the string to obtain. + * + * @return Pointer to requested string, if no errors are returned. + * + * Pointer to NULL, if any errors are returned. + *******************************************************************************************************/ + +#if (USBD_CFG_STR_EN == 1) +static const char *usbd_core_get_string_descriptor(const sli_usbd_device_t *p_dev, + uint8_t str_nbr) +{ + const char *p_str; + + if (str_nbr > p_dev->str_max_index) { + return (NULL); + } + + p_str = p_dev->str_descriptor_table[str_nbr]; + return (p_str); +} +#endif + +/****************************************************************************************************//** + * usbd_core_get_string_index() + * + * @brief Get string index. + * + * @param p_dev Pointer to device. + * + * @param ----- Argument validated in 'USBD_DevSetupPkt()' before posting the event to queue. + * + * @param p_str Pointer to string. + * + * @return String index. + *******************************************************************************************************/ + +#if (USBD_CFG_STR_EN == 1) +static uint8_t usbd_core_get_string_index(const sli_usbd_device_t *p_dev, + const char *p_str) +{ + uint8_t str_ix; + + // Return if a NULL pointer. + if (p_str == NULL) { + return (0u); + } + + for (str_ix = 0u; str_ix < p_dev->str_max_index; str_ix++) { + if (p_str == p_dev->str_descriptor_table[str_ix]) { + // Str already stored in tbl. + return (str_ix + 1u); + } + } + + return (0u); +} +#endif + +// clang-format on diff --git a/targets/AzureRTOS/SiliconLabs/_common/platform_BlockStorage.c b/targets/AzureRTOS/SiliconLabs/_common/platform_BlockStorage.c new file mode 100644 index 0000000000..f81dfb9356 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_common/platform_BlockStorage.c @@ -0,0 +1,22 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include +#include + +// map here the Block Storage Interface to the SL_Msc driver +IBlockStorageDevice SL_MscFlash_BlockStorageInterface = +{ + &SL_MscFlashDriver_InitializeDevice, + &SL_MscFlashDriver_UninitializeDevice, + &SL_MscFlashDriver_GetDeviceInfo, + &SL_MscFlashDriver_Read, + &SL_MscFlashDriver_Write, + NULL, + &SL_MscFlashDriver_IsBlockErased, + &SL_MscFlashDriver_EraseBlock, + NULL, + NULL +}; diff --git a/targets/AzureRTOS/SiliconLabs/_common/sl_sleeptimer_.c b/targets/AzureRTOS/SiliconLabs/_common/sl_sleeptimer_.c new file mode 100644 index 0000000000..5a21d6d920 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_common/sl_sleeptimer_.c @@ -0,0 +1,16 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Portions Copyright 2018 Silicon Laboratories Inc. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +// Need a strong implementation (despite empty) as this one is declared as WEAK in Gecko SDK which is causing +// issues when linking statically. +// Reported to Silabs here: +// (https://community.silabs.com/s/question/0D58Y0000AUTvt2SQD/declaration-of-slisleeptimersetpmemrequirement) + +#if !defined(SL_CATALOG_POWER_MANAGER_PRESENT) +void sli_sleeptimer_set_pm_em_requirement(void) +{ +} +#endif diff --git a/targets/AzureRTOS/SiliconLabs/_common/sl_usbd_class_hid_azurertos.c b/targets/AzureRTOS/SiliconLabs/_common/sl_usbd_class_hid_azurertos.c new file mode 100644 index 0000000000..ec6ea856d8 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_common/sl_usbd_class_hid_azurertos.c @@ -0,0 +1,385 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Portions Copyright 2018 Silicon Laboratories Inc. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +#include +#include +#include + +#include + +#include +#include +#include "sl_usbd_class_hid.h" +#include +#include + +// parameters for task +// static osThreadId_t timer_task_handle; +// static const osThreadAttr_t timer_task_attr = { +// .name = "HID Timer Thread", +// .attr_bits = 0, +// .stack_mem = NULL, +// .stack_size = (uint32_t)SL_USBD_HID_TIMER_TASK_STACK_SIZE, +// .cb_mem = NULL, +// .cb_size = 0, +// .priority = (osPriority_t)SL_USBD_HID_TIMER_TASK_PRIORITY}; +TX_THREAD timer_task_handle; +uint32_t timerThreadStack[SL_USBD_HID_TIMER_TASK_STACK_SIZE / sizeof(uint32_t)]; + +// parameters for event flags +// static osEventFlagsId_t input_eventflags_handle[SL_USBD_HID_CLASS_INSTANCE_QUANTITY]; +// static osEventFlagsAttr_t input_eventflags_attr[SL_USBD_HID_CLASS_INSTANCE_QUANTITY]; + +static TX_EVENT_FLAGS_GROUP input_eventflags_handle[SL_USBD_HID_CLASS_INSTANCE_QUANTITY]; + +// static osEventFlagsId_t output_eventflags_handle[SL_USBD_HID_CLASS_INSTANCE_QUANTITY]; +// static osEventFlagsAttr_t output_eventflags_attr[SL_USBD_HID_CLASS_INSTANCE_QUANTITY]; + +static TX_EVENT_FLAGS_GROUP output_eventflags_handle[SL_USBD_HID_CLASS_INSTANCE_QUANTITY]; + +#define EVENT_FLAG_COMPLETE 0x1 // signal posted +#define EVENT_FLAG_ABORT 0x2 // signal aborted + +// parameters for mutexes +// static osMutexId_t input_mutex_handle[SL_USBD_HID_CLASS_INSTANCE_QUANTITY]; +// static osMutexAttr_t input_mutex_attr[SL_USBD_HID_CLASS_INSTANCE_QUANTITY]; + +static TX_MUTEX input_mutex_handle[SL_USBD_HID_CLASS_INSTANCE_QUANTITY]; + +// static osMutexId_t output_mutex_handle[SL_USBD_HID_CLASS_INSTANCE_QUANTITY]; +// static osMutexAttr_t output_mutex_attr[SL_USBD_HID_CLASS_INSTANCE_QUANTITY]; + +static TX_MUTEX output_mutex_handle[SL_USBD_HID_CLASS_INSTANCE_QUANTITY]; + +// static osMutexId_t tx_mutex_handle[SL_USBD_HID_CLASS_INSTANCE_QUANTITY]; +// static osMutexAttr_t tx_mutex_attr[SL_USBD_HID_CLASS_INSTANCE_QUANTITY]; + +static TX_MUTEX tx_mutex_handle[SL_USBD_HID_CLASS_INSTANCE_QUANTITY]; + +static void usbd_hid_os_timer_task(uint32_t p_arg); + +static uint32_t usbd_hid_os_ms_to_ticks(uint32_t milliseconds); + +// Initialize HID OS interface +sl_status_t sli_usbd_hid_os_init(void) +{ + uint32_t class_nbr; + uint16_t status; + + for (class_nbr = 0u; class_nbr < SL_USBD_HID_CLASS_INSTANCE_QUANTITY; class_nbr++) + { + // tx_mutex_attr[class_nbr].name = "HID Tx mutex"; + // tx_mutex_attr[class_nbr].attr_bits = 0; + // tx_mutex_attr[class_nbr].cb_mem = NULL; + // tx_mutex_attr[class_nbr].cb_size = 0; + + // tx_mutex_handle[class_nbr] = osMutexNew(&tx_mutex_attr[class_nbr]); + + if (tx_mutex_create(&tx_mutex_handle[class_nbr], "HID Tx mutex", TX_NO_INHERIT) != TX_SUCCESS) + { + return SL_STATUS_FAIL; + } + + // output_mutex_attr[class_nbr].name = "HID Output mutex"; + // output_mutex_attr[class_nbr].attr_bits = 0; + // output_mutex_attr[class_nbr].cb_mem = NULL; + // output_mutex_attr[class_nbr].cb_size = 0; + + // output_mutex_handle[class_nbr] = osMutexNew(&output_mutex_attr[class_nbr]); + + if (tx_mutex_create(&output_mutex_handle[class_nbr], "HID Output mutex", TX_NO_INHERIT) != TX_SUCCESS) + { + return SL_STATUS_FAIL; + } + + // input_mutex_attr[class_nbr].name = "HID Input mutex"; + // input_mutex_attr[class_nbr].attr_bits = 0; + // input_mutex_attr[class_nbr].cb_mem = NULL; + // input_mutex_attr[class_nbr].cb_size = 0; + + // input_mutex_handle[class_nbr] = osMutexNew(&input_mutex_attr[class_nbr]); + + if (tx_mutex_create(&input_mutex_handle[class_nbr], "HID Input mutex", TX_NO_INHERIT) != TX_SUCCESS) + { + return SL_STATUS_FAIL; + } + + // input_eventflags_attr[class_nbr].name = "HID input events"; + // input_eventflags_attr[class_nbr].attr_bits = 0; + // input_eventflags_attr[class_nbr].cb_mem = NULL; + // input_eventflags_attr[class_nbr].cb_size = 0; + + // input_eventflags_handle[class_nbr] = osEventFlagsNew(&input_eventflags_attr[class_nbr]); + + if (tx_event_flags_create(&input_eventflags_handle[class_nbr], "HID input events") != TX_SUCCESS) + { + return SL_STATUS_FAIL; + } + + // output_eventflags_attr[class_nbr].name = "HID output events"; + // output_eventflags_attr[class_nbr].attr_bits = 0; + // output_eventflags_attr[class_nbr].cb_mem = NULL; + // output_eventflags_attr[class_nbr].cb_size = 0; + + // output_eventflags_handle[class_nbr] = osEventFlagsNew(&output_eventflags_attr[class_nbr]); + + if (tx_event_flags_create(&output_eventflags_handle[class_nbr], "HID output events") != TX_SUCCESS) + { + return SL_STATUS_FAIL; + } + } + + status = tx_thread_create( + &timer_task_handle, + "HID Timer Thread", + usbd_hid_os_timer_task, + 0, + timerThreadStack, + SL_USBD_HID_TIMER_TASK_STACK_SIZE, + SL_USBD_HID_TIMER_TASK_PRIORITY, + SL_USBD_HID_TIMER_TASK_PRIORITY, + TX_NO_TIME_SLICE, + TX_AUTO_START); + + if (status != TX_SUCCESS) + { + return SL_STATUS_FAIL; + } + + // timer_task_handle = osThreadNew(usbd_hid_os_timer_task, NULL, &timer_task_attr); + + // if (timer_task_handle == NULL) + // { + // return SL_STATUS_FAIL; + // } + + return SL_STATUS_OK; +} + +// Lock class input report +sl_status_t sli_usbd_hid_os_lock_input(uint8_t class_nbr) +{ + if (tx_mutex_get(&input_mutex_handle[class_nbr], TX_WAIT_FOREVER) != TX_SUCCESS) + { + return SL_STATUS_FAIL; + } + + return SL_STATUS_OK; +} + +// Unlock class input report +sl_status_t sli_usbd_hid_os_unlock_input(uint8_t class_nbr) +{ + if (tx_mutex_put(&input_mutex_handle[class_nbr]) != TX_SUCCESS) + { + return SL_STATUS_FAIL; + } + + return SL_STATUS_OK; +} + +// Abort class output report +sl_status_t sli_usbd_hid_os_pend_abort_output(uint8_t class_nbr) +{ + if (tx_event_flags_set(&output_eventflags_handle[class_nbr], EVENT_FLAG_ABORT, TX_OR) != TX_SUCCESS) + { + return SL_STATUS_FAIL; + } + + return SL_STATUS_OK; +} + +// Wait for output report data transfer to complete +sl_status_t sli_usbd_hid_os_pend_output(uint8_t class_nbr, uint16_t timeout_ms) +{ + uint32_t ticks; + uint32_t status; + uint32_t actual_events; + + if (timeout_ms == 0) + { + ticks = TX_WAIT_FOREVER; + } + else + { + ticks = usbd_hid_os_ms_to_ticks(timeout_ms); + } + + status = tx_event_flags_get( + &output_eventflags_handle[class_nbr], + EVENT_FLAG_COMPLETE | EVENT_FLAG_ABORT, + TX_OR_CLEAR, + &actual_events, + ticks); + + if (status == TX_NO_EVENTS) + { + return SL_STATUS_TIMEOUT; + } + + if (status != TX_SUCCESS) + { + return SL_STATUS_FAIL; + } + + if ((actual_events & EVENT_FLAG_ABORT) == EVENT_FLAG_ABORT) + { + return SL_STATUS_ABORT; + } + + return SL_STATUS_OK; +} + +// Signal that output report data is available +sl_status_t sli_usbd_hid_os_post_output(uint8_t class_nbr) +{ + if (tx_event_flags_set(&output_eventflags_handle[class_nbr], EVENT_FLAG_COMPLETE, TX_OR) != TX_SUCCESS) + { + return SL_STATUS_FAIL; + } + + return SL_STATUS_OK; +} + +// Lock class output report +sl_status_t sli_usbd_hid_os_lock_output(uint8_t class_nbr) +{ + if (tx_mutex_get(&output_mutex_handle[class_nbr], TX_WAIT_FOREVER) != TX_SUCCESS) + { + return SL_STATUS_FAIL; + } + + return SL_STATUS_OK; +} + +// Unlock class output report +sl_status_t sli_usbd_hid_os_unlock_output(uint8_t class_nbr) +{ + if (tx_mutex_put(&output_mutex_handle[class_nbr]) != TX_SUCCESS) + { + return SL_STATUS_FAIL; + } + + return SL_STATUS_OK; +} + +// Lock class transmit +sl_status_t sli_usbd_hid_os_lock_tx(uint8_t class_nbr) +{ + if (tx_mutex_get(&tx_mutex_handle[class_nbr], TX_WAIT_FOREVER) != TX_SUCCESS) + { + return SL_STATUS_FAIL; + } + + return SL_STATUS_OK; +} + +// Unlock class transmit +sl_status_t sli_usbd_hid_os_unlock_tx(uint8_t class_nbr) +{ + if (tx_mutex_put(&tx_mutex_handle[class_nbr]) != TX_SUCCESS) + { + return SL_STATUS_FAIL; + } + + return SL_STATUS_OK; +} + +// Wait for input report data transfer to complete +sl_status_t sli_usbd_hid_os_pend_input(uint8_t class_nbr, uint16_t timeout_ms) +{ + uint32_t ticks; + uint32_t status; + uint32_t actual_events; + + if (timeout_ms == 0) + { + ticks = TX_WAIT_FOREVER; + } + else + { + ticks = usbd_hid_os_ms_to_ticks(timeout_ms); + } + + status = tx_event_flags_get( + &input_eventflags_handle[class_nbr], + EVENT_FLAG_COMPLETE | EVENT_FLAG_ABORT, + TX_OR_CLEAR, + &actual_events, + ticks); + + if (status == TX_NO_EVENTS) + { + return SL_STATUS_TIMEOUT; + } + + if (status != TX_SUCCESS) + { + return SL_STATUS_FAIL; + } + + if ((actual_events & EVENT_FLAG_ABORT) == EVENT_FLAG_ABORT) + { + return SL_STATUS_ABORT; + } + + return SL_STATUS_OK; +} + +// Abort any operation on input report +sl_status_t sli_usbd_hid_os_pend_abort_input(uint8_t class_nbr) +{ + if (tx_event_flags_set(&input_eventflags_handle[class_nbr], EVENT_FLAG_ABORT, TX_OR) != TX_SUCCESS) + { + return SL_STATUS_FAIL; + } + + return SL_STATUS_OK; +} + +// Signal that input report data transfer has completed +sl_status_t sli_usbd_hid_os_post_input(uint8_t class_nbr) +{ + if (tx_event_flags_set(&input_eventflags_handle[class_nbr], EVENT_FLAG_COMPLETE, TX_OR) != TX_SUCCESS) + { + return SL_STATUS_FAIL; + } + + return SL_STATUS_OK; +} + +// usbd_hid_os_timer_task() +// OS - dependent shell task to process periodic HID input reports. +// **@param +// p_arg: Pointer to task initialization argument. +// @note(1) +// Assumes tick rate frequency is greater than or equal to 250 Hz. +// Otherwise, timer task scheduling rate will NOT be correct. +// @note(2) +// Timer task MUST delay without failure. +// (a)Failure to delay timer task will prevent some HID report task(s) operation(s) from functioning correctly. +// Thus, timer task is assumed to be successfully delayed since NO error handling *could be performed to counteract +// failure. +static void usbd_hid_os_timer_task(uint32_t p_arg) +{ + uint32_t dly_tick; + (void)p_arg; + + // Delay task at 4 ms rate (see Note #1). + dly_tick = usbd_hid_os_ms_to_ticks(4); + + while (true) + { + tx_thread_sleep(dly_tick); + sli_usbd_hid_report_timer_task_handler(); + } +} + +// Converts milliseconds to kernel ticks. +static uint32_t usbd_hid_os_ms_to_ticks(uint32_t milliseconds) +{ + return TX_TICKS_PER_MILLISEC(milliseconds); +} diff --git a/targets/AzureRTOS/SiliconLabs/_common/sl_usbd_core_azuretos.c b/targets/AzureRTOS/SiliconLabs/_common/sl_usbd_core_azuretos.c new file mode 100644 index 0000000000..b928784fe8 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_common/sl_usbd_core_azuretos.c @@ -0,0 +1,362 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Portions Copyright 2018 Silicon Laboratories Inc. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +TX_THREAD task_handle; +uint32_t usbdCoreThreadStack[SL_USBD_TASK_STACK_SIZE / sizeof(uint32_t)]; +uint8_t message_queue_storage[sizeof(sli_usbd_core_event_t) * SL_USBD_CORE_EVENT_BUS_NBR]; + +// // parameters for task +// static osThreadId_t task_handle; +// static const osThreadAttr_t task_attr = { +// .name = "USBD Thread", +// .attr_bits = 0, +// .stack_mem = NULL, +// .stack_size = (uint32_t)SL_USBD_TASK_STACK_SIZE, +// .cb_mem = NULL, +// .cb_size = 0, +// .priority = (osPriority_t)SL_USBD_TASK_PRIORITY +// }; + +// parameters for message queue +// static osMessageQueueId_t message_queue_handle; +// static const osMessageQueueAttr_t message_queue_attr = +// {.name = "USBD Queue", .attr_bits = 0, .cb_mem = NULL, .cb_size = 0, .mq_mem = NULL, .mq_size = 0}; + +static TX_QUEUE message_queue_handle; + +// parameters for event flags +// static osEventFlagsId_t eventflags_handle[SL_USBD_OPEN_ENDPOINTS_QUANTITY]; +// static osEventFlagsAttr_t eventflags_attr[SL_USBD_OPEN_ENDPOINTS_QUANTITY]; + +static TX_EVENT_FLAGS_GROUP eventflags_handle[SL_USBD_OPEN_ENDPOINTS_QUANTITY]; + +#define EVENT_FLAG_COMPLETE 0x1 // signal posted +#define EVENT_FLAG_ABORT 0x2 // signal aborted + +// parameters for mutex +// static osMutexId_t mutex_handle[SL_USBD_OPEN_ENDPOINTS_QUANTITY]; +// static osMutexAttr_t mutex_attr[SL_USBD_OPEN_ENDPOINTS_QUANTITY]; + +static TX_MUTEX mutex_handle[SL_USBD_OPEN_ENDPOINTS_QUANTITY]; + +/******************************************************************************************************** + ******************************************************************************************************** + * LOCAL FUNCTION PROTOTYPES + ******************************************************************************************************** + *******************************************************************************************************/ + +static void usbd_core_os_task_main(uint32_t p_arg); + +static uint32_t usbd_core_os_ms_to_ticks(uint32_t milliseconds); + +/******************************************************************************************************** + ******************************************************************************************************** + * INTERNAL FUNCTIONS + ******************************************************************************************************** + *******************************************************************************************************/ + +/******************************************************************************************************* + * Create task and queue for task to pend on + *******************************************************************************************************/ +sl_status_t sli_usbd_core_os_create_task(void) +{ + uint16_t status; + + status = tx_queue_create( + &message_queue_handle, + "USBD Queue", + sizeof(sli_usbd_core_event_t), + message_queue_storage, + sizeof(message_queue_storage)); + + // message_queue_handle = + // osMessageQueueNew(SL_USBD_CORE_EVENT_BUS_NBR, sizeof(sli_usbd_core_event_t), &message_queue_attr); + + if (status != TX_SUCCESS) + { + return SL_STATUS_FAIL; + } + + // Create USB device Core thread + status = tx_thread_create( + &task_handle, + "USBD Core Thread", + usbd_core_os_task_main, + 0, + usbdCoreThreadStack, + SL_USBD_TASK_STACK_SIZE, + SL_USBD_TASK_PRIORITY, + SL_USBD_TASK_PRIORITY, + TX_NO_TIME_SLICE, + TX_AUTO_START); + + if (status != TX_SUCCESS) + { + return SL_STATUS_FAIL; + } + + return SL_STATUS_OK; +} + +/******************************************************************************************************* + * Create an OS signal + *******************************************************************************************************/ +sl_status_t sli_usbd_core_os_create_endpoint_signal(uint8_t endpoint) +{ + if (endpoint >= SL_USBD_OPEN_ENDPOINTS_QUANTITY) + { + return SL_STATUS_FAIL; + } + + // eventflags_attr[endpoint].name = "USBD events"; + // eventflags_attr[endpoint].attr_bits = 0; + // eventflags_attr[endpoint].cb_mem = NULL; + // eventflags_attr[endpoint].cb_size = 0; + + // eventflags_handle[endpoint] = osEventFlagsNew(&eventflags_attr[endpoint]); + + if (tx_event_flags_create(&eventflags_handle[endpoint], "USBD events") != TX_SUCCESS) + { + return SL_STATUS_FAIL; + } + + return SL_STATUS_OK; +} + +/******************************************************************************************************* + * Delete an OS signal + *******************************************************************************************************/ +sl_status_t sli_usbd_core_os_delete_endpoint_signal(uint8_t endpoint) +{ + if (endpoint >= SL_USBD_OPEN_ENDPOINTS_QUANTITY) + { + return SL_STATUS_FAIL; + } + + if (tx_event_flags_delete(&eventflags_handle[endpoint]) != TX_SUCCESS) + { + return SL_STATUS_FAIL; + } + + return SL_STATUS_OK; +} + +/******************************************************************************************************* + * Wait for a signal to become available + *******************************************************************************************************/ +sl_status_t sli_usbd_core_os_pend_endpoint_signal(uint8_t endpoint, uint16_t timeout_ms) +{ + uint32_t ticks; + uint32_t status; + uint32_t actual_events; + + if (endpoint >= SL_USBD_OPEN_ENDPOINTS_QUANTITY) + { + return SL_STATUS_FAIL; + } + + if (timeout_ms == 0) + { + ticks = TX_WAIT_FOREVER; + } + else + { + ticks = usbd_core_os_ms_to_ticks(timeout_ms); + } + + status = tx_event_flags_get( + &eventflags_handle[endpoint], + EVENT_FLAG_COMPLETE | EVENT_FLAG_ABORT, + TX_OR_CLEAR, + &actual_events, + ticks); + + if (status == TX_NO_EVENTS) + { + return SL_STATUS_TIMEOUT; + } + + if (status != TX_SUCCESS) + { + return SL_STATUS_FAIL; + } + + if ((actual_events & EVENT_FLAG_ABORT) == EVENT_FLAG_ABORT) + { + return SL_STATUS_ABORT; + } + + return SL_STATUS_OK; +} + +/******************************************************************************************************* + * Abort any wait operation on signal + *******************************************************************************************************/ +sl_status_t sli_usbd_core_os_abort_endpoint_signal(uint8_t endpoint) +{ + if (endpoint >= SL_USBD_OPEN_ENDPOINTS_QUANTITY) + { + return SL_STATUS_FAIL; + } + + if (tx_event_flags_set(&eventflags_handle[endpoint], EVENT_FLAG_ABORT, TX_OR) != TX_SUCCESS) + { + return SL_STATUS_FAIL; + } + + return SL_STATUS_OK; +} + +/******************************************************************************************************* + * Make a signal available + *******************************************************************************************************/ +sl_status_t sli_usbd_core_os_post_endpoint_signal(uint8_t endpoint) +{ + if (endpoint >= SL_USBD_OPEN_ENDPOINTS_QUANTITY) + { + return SL_STATUS_FAIL; + } + + if (tx_event_flags_set(&eventflags_handle[endpoint], EVENT_FLAG_COMPLETE, TX_OR) != TX_SUCCESS) + { + return SL_STATUS_FAIL; + } + + return SL_STATUS_OK; +} + +/******************************************************************************************************* + * Create an OS resource to use as an endpoint lock + *******************************************************************************************************/ +sl_status_t sli_usbd_core_os_create_endpoint_lock(uint8_t endpoint) +{ + if (endpoint >= SL_USBD_OPEN_ENDPOINTS_QUANTITY) + { + return SL_STATUS_FAIL; + } + + if (tx_mutex_create(&mutex_handle[endpoint], "USBD mutex", TX_NO_INHERIT) != TX_SUCCESS) + { + return SL_STATUS_FAIL; + } + + return SL_STATUS_OK; +} + +/******************************************************************************************************* + * Delete the OS resource used as an endpoint lock + *******************************************************************************************************/ +sl_status_t sli_usbd_core_os_delete_endpoint_lock(uint8_t endpoint) +{ + if (endpoint >= SL_USBD_OPEN_ENDPOINTS_QUANTITY) + { + return SL_STATUS_FAIL; + } + + if (tx_mutex_delete(&mutex_handle[endpoint]) != TX_SUCCESS) + { + return SL_STATUS_FAIL; + } + + return SL_STATUS_OK; +} + +/******************************************************************************************************* + * Wait for an endpoint to become available and acquire its lock + *******************************************************************************************************/ +sl_status_t sli_usbd_core_os_acquire_endpoint_lock(uint8_t endpoint) +{ + if (endpoint >= SL_USBD_OPEN_ENDPOINTS_QUANTITY) + { + return SL_STATUS_FAIL; + } + + if (tx_mutex_get(&mutex_handle[endpoint], TX_WAIT_FOREVER) != TX_SUCCESS) + { + return SL_STATUS_FAIL; + } + + return SL_STATUS_OK; +} + +/******************************************************************************************************* + * Release an endpoint lock + *******************************************************************************************************/ +sl_status_t sli_usbd_core_os_release_endpoint_lock(uint8_t endpoint) +{ + if (endpoint >= SL_USBD_OPEN_ENDPOINTS_QUANTITY) + { + return SL_STATUS_FAIL; + } + + if (tx_mutex_put(&mutex_handle[endpoint]) != TX_SUCCESS) + { + return SL_STATUS_FAIL; + } + + return SL_STATUS_OK; +} + +/******************************************************************************************************* + * Wait until a core event is ready + *******************************************************************************************************/ +sl_status_t sli_usbd_core_os_get_core_event(void *p_event) +{ + if (tx_queue_receive(&message_queue_handle, p_event, TX_WAIT_FOREVER) != TX_SUCCESS) + { + return SL_STATUS_FAIL; + } + + return SL_STATUS_OK; +} + +/******************************************************************************************************* + * Queues core event + *******************************************************************************************************/ +sl_status_t sli_usbd_core_os_put_core_event(void *p_event) +{ + if (tx_queue_send(&message_queue_handle, p_event, TX_NO_WAIT) != TX_SUCCESS) + { + return SL_STATUS_FAIL; + } + + return SL_STATUS_OK; +} + +// usbd_core_os_task_main() +// OS-dependent shell task to process USB core events. +// @param p_arg: Pointer to task initialization argument +static void usbd_core_os_task_main(uint32_t p_arg) +{ + (void)p_arg; + + while (true) + { + sli_usbd_core_task_handler(); + } +} + +// usbd_core_os_ms_to_ticks() +// Converts milliseconds to kernel ticks +// @param milliseconds: milliseconds to convert to ticks +// @return Number of ticks +static uint32_t usbd_core_os_ms_to_ticks(uint32_t milliseconds) +{ + return TX_TICKS_PER_MILLISEC(milliseconds); +} diff --git a/targets/AzureRTOS/SiliconLabs/_common/sys_calls.c b/targets/AzureRTOS/SiliconLabs/_common/sys_calls.c new file mode 100644 index 0000000000..7a92128b64 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_common/sys_calls.c @@ -0,0 +1,80 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Portions Copyright 2018 Silicon Laboratories Inc. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +// dummy implementations for the newlib reentrant functions +// required to link with Gecko SDK as adding --specs=nosys.specs doesn't seem to work + +#include + +int _close(int file) +{ + (void)file; + return 0; +} + +void _exit(int status) +{ + (void)status; + while (1) + { + } /* Hang here forever... */ +} + +int _fstat(int file, struct stat *st) +{ + (void)file; + st->st_mode = S_IFCHR; + return 0; +} + +int _getpid(void) +{ + return 1; +} + +int _isatty(int file) +{ + (void)file; + return 1; +} + +int _kill(int pid, int sig) +{ + (void)pid; + (void)sig; + return -1; +} + +int _lseek(int file, int ptr, int dir) +{ + (void)file; + (void)ptr; + (void)dir; + return 0; +} + +int _read(int file, char *ptr, int len) +{ + (void)file; + (void)ptr; + (void)len; + + return -1; +} + +int _write(int file, const char *ptr, int len) +{ + int txCount; + + (void)file; + + for (txCount = 0; txCount < len; txCount++) + { + ptr++; + } + + return len; +} diff --git a/targets/AzureRTOS/SiliconLabs/_common/targetHAL_ConfigurationManager.cpp b/targets/AzureRTOS/SiliconLabs/_common/targetHAL_ConfigurationManager.cpp new file mode 100644 index 0000000000..238f9c3e83 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_common/targetHAL_ConfigurationManager.cpp @@ -0,0 +1,774 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include +#include +#include +//#include + +#if defined(WIFI_DRIVER_ISM43362) && defined(I_AM_NANOCLR) +#include +#endif + +uint8_t programWidth = 0; + +uint32_t GetExistingConfigSize() +{ + uint32_t currentConfigSize = 0; + + currentConfigSize = + g_TargetConfiguration.NetworkInterfaceConfigs->Count * sizeof(HAL_Configuration_NetworkInterface); + currentConfigSize += g_TargetConfiguration.Wireless80211Configs->Count * sizeof(HAL_Configuration_Wireless80211); + + return currentConfigSize; +} + +// initialization of configuration manager +// provided as weak so it can be replaced at target level, if required because of the target implementing the storage +// with a mechanism other then saving to flash +__nfweak void ConfigurationManager_Initialize() +{ + BlockStorageStream stream; + memset(&stream, 0, sizeof(BlockStorageStream)); + BlockStorageStream_Initialize(&stream, BlockUsage_CONFIG); + + BlockStorageDevice *device = BlockStorageList_GetFirstDevice(); + DeviceBlockInfo *deviceBlockInfo = BlockStorageDevice_GetDeviceInfo(device); + + if (deviceBlockInfo->Regions[stream.RegionIndex].Attributes & BlockRegionAttribute_ProgramWidthIs64bits) + { + programWidth = 64 / 8; + } + + // init g_TargetConfiguration + memset(&g_TargetConfiguration, 0, sizeof(HAL_TARGET_CONFIGURATION)); + + // enumerate the blocks + ConfigurationManager_EnumerateConfigurationBlocks(); +}; + +// Enumerates the configuration blocks from the configuration flash sector +// it's implemented with 'weak' attribute so it can be replaced at target level if a different persistance mechanism is +// used +__nfweak void ConfigurationManager_EnumerateConfigurationBlocks() +{ + // start checking if this device has config block + if (((uint32_t)&__nanoConfig_end__ - (uint32_t)&__nanoConfig_start__) > 0) + { + // find network configuration blocks + HAL_CONFIGURATION_NETWORK *networkConfigs = + (HAL_CONFIGURATION_NETWORK *)ConfigurationManager_FindNetworkConfigurationBlocks( + (uint32_t)&__nanoConfig_start__, + (uint32_t)&__nanoConfig_end__); + + // check network configs count + if (networkConfigs->Count == 0) + { + // there is no network config block available, get a default + HAL_Configuration_NetworkInterface *networkConfig = + (HAL_Configuration_NetworkInterface *)platform_malloc(sizeof(HAL_Configuration_NetworkInterface)); + + if (InitialiseNetworkDefaultConfig(networkConfig, 0)) + { + // config block created, store it + ConfigurationManager_StoreConfigurationBlock( + networkConfig, + DeviceConfigurationOption_Network, + 0, + sizeof(HAL_Configuration_NetworkInterface), + 0, + false); + + // have to enumerate again to pick it up + networkConfigs = (HAL_CONFIGURATION_NETWORK *)ConfigurationManager_FindNetworkConfigurationBlocks( + (uint32_t)&__nanoConfig_start__, + (uint32_t)&__nanoConfig_end__); + } + + platform_free(networkConfig); + } + + // find wireless 80211 network configuration blocks + HAL_CONFIGURATION_NETWORK_WIRELESS80211 *networkWirelessConfigs = + (HAL_CONFIGURATION_NETWORK_WIRELESS80211 *)ConfigurationManager_FindNetworkWireless80211ConfigurationBlocks( + (uint32_t)&__nanoConfig_start__, + (uint32_t)&__nanoConfig_end__); + +#if defined(TARGET_HAS_WIFI_SUPPORT) && (TARGET_HAS_WIFI_SUPPORT == 1) + + if (networkWirelessConfigs->Count == 0) + { + // there is no network config block available, get a default + HAL_Configuration_Wireless80211 *wirelessConfig = + (HAL_Configuration_Wireless80211 *)platform_malloc(sizeof(HAL_Configuration_Wireless80211)); + + InitialiseWirelessDefaultConfig(wirelessConfig, 0); + + // config block created, store it + ConfigurationManager_StoreConfigurationBlock( + wirelessConfig, + DeviceConfigurationOption_Wireless80211Network, + 0, + sizeof(HAL_Configuration_Wireless80211), + 0, + false); + + // have to enumerate again to pick it up + networkWirelessConfigs = (HAL_CONFIGURATION_NETWORK_WIRELESS80211 *) + ConfigurationManager_FindNetworkWireless80211ConfigurationBlocks( + (uint32_t)&__nanoConfig_start__, + (uint32_t)&__nanoConfig_end__); + + platform_free(wirelessConfig); + } + +#endif + + // find X509 certificate blocks + HAL_CONFIGURATION_X509_CERTIFICATE *certificateStore = + (HAL_CONFIGURATION_X509_CERTIFICATE *)ConfigurationManager_FindX509CertificateConfigurationBlocks( + (uint32_t)&__nanoConfig_start__, + (uint32_t)&__nanoConfig_end__); + + // find X509 device certificate blocks + HAL_CONFIGURATION_X509_DEVICE_CERTIFICATE *deviceCertificates = (HAL_CONFIGURATION_X509_DEVICE_CERTIFICATE *) + ConfigurationManager_FindX509DeviceCertificatesConfigurationBlocks( + (uint32_t)&__nanoConfig_start__, + (uint32_t)&__nanoConfig_end__); + + // alloc memory for g_TargetConfiguration + // because this is a struct of structs that use flexible members the memory has to be allocated from the heap + // the malloc size for each struct is computed separately + uint32_t sizeOfNetworkInterfaceConfigs = + offsetof(HAL_CONFIGURATION_NETWORK, Configs) + networkConfigs->Count * sizeof(networkConfigs->Configs[0]); + uint32_t sizeOfWireless80211Configs = + offsetof(HAL_CONFIGURATION_NETWORK_WIRELESS80211, Configs) + + networkWirelessConfigs->Count * sizeof(networkWirelessConfigs->Configs[0]); + uint32_t sizeOfWirelessAPConfigs = offsetof(HAL_CONFIGURATION_NETWORK_WIRELESSAP, Configs); + uint32_t sizeOfX509CertificateStore = offsetof(HAL_CONFIGURATION_X509_CERTIFICATE, Certificates) + + certificateStore->Count * sizeof(certificateStore->Certificates[0]); + uint32_t sizeOfX509DeviceCertificate = offsetof(HAL_CONFIGURATION_X509_DEVICE_CERTIFICATE, Certificates) + + deviceCertificates->Count * sizeof(deviceCertificates->Certificates[0]); + + g_TargetConfiguration.NetworkInterfaceConfigs = + (HAL_CONFIGURATION_NETWORK *)platform_malloc(sizeOfNetworkInterfaceConfigs); + g_TargetConfiguration.Wireless80211Configs = + (HAL_CONFIGURATION_NETWORK_WIRELESS80211 *)platform_malloc(sizeOfWireless80211Configs); + g_TargetConfiguration.WirelessAPConfigs = + (HAL_CONFIGURATION_NETWORK_WIRELESSAP *)platform_malloc(sizeOfWirelessAPConfigs); + g_TargetConfiguration.CertificateStore = + (HAL_CONFIGURATION_X509_CERTIFICATE *)platform_malloc(sizeOfX509CertificateStore); + g_TargetConfiguration.DeviceCertificates = + (HAL_CONFIGURATION_X509_DEVICE_CERTIFICATE *)platform_malloc(sizeOfX509DeviceCertificate); + + // copy structs to g_TargetConfiguration + memcpy( + (HAL_CONFIGURATION_NETWORK *)g_TargetConfiguration.NetworkInterfaceConfigs, + networkConfigs, + sizeOfNetworkInterfaceConfigs); + memcpy( + (HAL_CONFIGURATION_NETWORK_WIRELESS80211 *)g_TargetConfiguration.Wireless80211Configs, + networkWirelessConfigs, + sizeOfWireless80211Configs); + // memcpy( + // (HAL_CONFIGURATION_NETWORK_WIRELESSAP *)g_TargetConfiguration.WirelessAPConfigs, + // networkWirelessApConfigs, + // sizeOfWirelessAPConfigs); + g_TargetConfiguration.WirelessAPConfigs->Count = 0; + memcpy( + (HAL_CONFIGURATION_X509_CERTIFICATE *)g_TargetConfiguration.CertificateStore, + certificateStore, + sizeOfX509CertificateStore); + memcpy( + (HAL_CONFIGURATION_X509_DEVICE_CERTIFICATE *)g_TargetConfiguration.DeviceCertificates, + deviceCertificates, + sizeOfX509DeviceCertificate); + + // now free the memory of the original structs + platform_free(networkConfigs); + platform_free(networkWirelessConfigs); + platform_free(certificateStore); + platform_free(deviceCertificates); + } + else + { + // no config block + } +} + +// Gets the network configuration block from the configuration flash sector +// it's implemented with 'weak' attribute so it can be replaced at target level if a different persistance mechanism is +// used +__nfweak bool ConfigurationManager_GetConfigurationBlock( + void *configurationBlock, + DeviceConfigurationOption configuration, + uint32_t configurationIndex) +{ + int sizeOfBlock = 0; + uint8_t *blockAddress = NULL; + + // validate if the requested block exists + // Count has to be non zero + // requested Index has to exist (array index starts at zero, so need to add one) + if (configuration == DeviceConfigurationOption_Network) + { + if (g_TargetConfiguration.NetworkInterfaceConfigs->Count == 0 || + (configurationIndex + 1) > g_TargetConfiguration.NetworkInterfaceConfigs->Count) + { + // the requested config block is beyond the available count + return false; + } + + // set block size + sizeOfBlock = sizeof(HAL_Configuration_NetworkInterface); + + // get block address + blockAddress = (uint8_t *)g_TargetConfiguration.NetworkInterfaceConfigs->Configs[configurationIndex]; + } + else if (configuration == DeviceConfigurationOption_Wireless80211Network) + { + if (g_TargetConfiguration.Wireless80211Configs->Count == 0 || + (configurationIndex + 1) > g_TargetConfiguration.Wireless80211Configs->Count) + { + return FALSE; + } + + // set block size + sizeOfBlock = sizeof(HAL_Configuration_Wireless80211); + + // get block address + blockAddress = (uint8_t *)g_TargetConfiguration.Wireless80211Configs->Configs[configurationIndex]; + } + else if (configuration == DeviceConfigurationOption_X509CaRootBundle) + { + if (g_TargetConfiguration.CertificateStore->Count == 0 || + (configurationIndex + 1) > g_TargetConfiguration.CertificateStore->Count) + { + return FALSE; + } + + // get block address + blockAddress = (uint8_t *)g_TargetConfiguration.CertificateStore->Certificates[configurationIndex]; + + // set block size + // because X509 certificate has a variable length need to compute the block size in two steps + sizeOfBlock = offsetof(HAL_Configuration_X509CaRootBundle, Certificate); + sizeOfBlock += ((HAL_Configuration_X509CaRootBundle *)blockAddress)->CertificateSize; + } + else if (configuration == DeviceConfigurationOption_X509CaRootBundle) + { + if (g_TargetConfiguration.DeviceCertificates->Count == 0 || + (configurationIndex + 1) > g_TargetConfiguration.DeviceCertificates->Count) + { + return FALSE; + } + + // get block address + blockAddress = (uint8_t *)g_TargetConfiguration.DeviceCertificates->Certificates[configurationIndex]; + + // set block size + // because X509 certificate has a variable length need to compute the block size in two steps + sizeOfBlock = offsetof(HAL_Configuration_X509DeviceCertificate, Certificate); + sizeOfBlock += ((HAL_Configuration_X509DeviceCertificate *)blockAddress)->CertificateSize; + } + + // copy the config block content to the pointer in the argument + memcpy(configurationBlock, blockAddress, sizeOfBlock); + + return TRUE; +} + +// Stores the configuration block to the configuration flash sector +// NOTE: because inserting or removing a configuration block it's very 'RAM expensive' we choose not to support those +// operations the host debugger will have to be used to manage these operations on the device configuration collection +// it's implemented with 'weak' attribute so it can be replaced at target level if a different persistance mechanism is +// used +__nfweak bool ConfigurationManager_StoreConfigurationBlock( + void *configurationBlock, + DeviceConfigurationOption configuration, + uint32_t configurationIndex, + uint32_t blockSize, + uint32_t offset, + bool done) +{ + ByteAddress storageAddress = 0; + bool requiresEnumeration = FALSE; + bool success = FALSE; + + if (configuration == DeviceConfigurationOption_Network) + { + if (g_TargetConfiguration.NetworkInterfaceConfigs == NULL || + (g_TargetConfiguration.NetworkInterfaceConfigs->Count == 0 && configurationIndex == 0)) + { + // there is no network config block, we are storing the default one + // THIS IS THE FIRST CONFIG BLOCK THAT'S AUTO-CREATED + // OK to continue + // set storage address as the start of the flash configuration sector + storageAddress = (ByteAddress)&__nanoConfig_start__; + } + else + { + // the requested config block is beyond the available count + if ((configurationIndex + 1) > g_TargetConfiguration.NetworkInterfaceConfigs->Count) + { + return FALSE; + } + + // set storage address from block address, plus the requested offset + storageAddress = + (ByteAddress)g_TargetConfiguration.NetworkInterfaceConfigs->Configs[configurationIndex] + offset; + } + + // set block size, in case it's not already set + blockSize = sizeof(HAL_Configuration_NetworkInterface); + + // make sure the config block marker is set + memcpy(configurationBlock, c_MARKER_CONFIGURATION_NETWORK_V1, sizeof(c_MARKER_CONFIGURATION_NETWORK_V1)); + + _ASSERTE(((HAL_Configuration_NetworkInterface *)configurationBlock)->StartupAddressMode > 0); + } + else if (configuration == DeviceConfigurationOption_Wireless80211Network) + { + + // #if (TARGET_HAS_WIFI_SUPPORT == 1) + + // if (g_TargetConfiguration.Wireless80211Configs == NULL || + // (g_TargetConfiguration.Wireless80211Configs->Count == 0 && configurationIndex == 0)) + // { + // // there is no wireless 80211 config block, so we are storing the default one + // // THIS IS THE SECOND CONFIG BLOCK THAT'S AUTO-CREATED + // // OK to continue + // // set storage address contiguous to the network config block + // storageAddress = (uint32_t)&__nanoConfig_start__ + sizeof(HAL_Configuration_NetworkInterface); + + // // check programming width + // if(programWidth > 0) + // { + // // round address to the next valid programming width + // storageAddress += programWidth - storageAddress % programWidth; + // } + // } + // else + // { + // // the requested config block is beyond the available count + // if ((configurationIndex + 1) > g_TargetConfiguration.Wireless80211Configs->Count) + // { + // return FALSE; + // } + + // // set storage address from block address, plus the requested offset + // storageAddress = + // (ByteAddress)g_TargetConfiguration.Wireless80211Configs->Configs[configurationIndex] + + // offset; + // } + + // // set block size, in case it's not already set + // blockSize = sizeof(HAL_Configuration_Wireless80211); + + // // make sure the config block marker is set + // memcpy( + // configurationBlock, + // c_MARKER_CONFIGURATION_WIRELESS80211_V1, + // sizeof(c_MARKER_CONFIGURATION_WIRELESS80211_V1)); + + // #else + // // no support for WIFI in this STM32 build + // return FALSE; + // #endif + } + else if (configuration == DeviceConfigurationOption_X509CaRootBundle) + { + // compute block size + // because X509 certificate has a variable length need to compute the block size in two steps + blockSize = offsetof(HAL_Configuration_X509CaRootBundle, Certificate); + blockSize += ((HAL_Configuration_X509CaRootBundle *)configurationBlock)->CertificateSize; + + // + if (g_TargetConfiguration.CertificateStore->Count == 0) + { + // there is nothing at the certificate store + // find size of existing config blocks + storageAddress = (uint32_t)&__nanoConfig_start__ + GetExistingConfigSize(); + } + else + { + // set storage address from block address, plus the requested offset + storageAddress = + (ByteAddress)g_TargetConfiguration.CertificateStore->Certificates[configurationIndex] + offset; + } + + if (g_TargetConfiguration.CertificateStore == NULL || + (g_TargetConfiguration.CertificateStore->Count == 0 || + (configurationIndex + 1) > g_TargetConfiguration.CertificateStore->Count)) + { + // there is no block stored + // check if there is room for it + if (((uint32_t)&__nanoConfig_end__ - storageAddress) < blockSize) + { + // not enough room + return FALSE; + } + + // // now check if memory is erase, so the block can be stored + // if (!STM32FlashDriver_IsBlockErased(NULL, storageAddress, blockSize)) + // { + // // memory not erased, can't store + // return FALSE; + // } + } + + // make sure the config block marker is set, ONLY required on the 1st chunk + if (offset == 0) + { + memcpy( + configurationBlock, + c_MARKER_CONFIGURATION_X509CAROOTBUNDLE_V1, + sizeof(c_MARKER_CONFIGURATION_X509CAROOTBUNDLE_V1)); + } + } + else if (configuration == DeviceConfigurationOption_X509DeviceCertificates) + { + // compute block size + // because X509 certificate has a variable length need to compute the block size in two steps + blockSize = offsetof(HAL_Configuration_X509DeviceCertificate, Certificate); + blockSize += ((HAL_Configuration_X509DeviceCertificate *)configurationBlock)->CertificateSize; + + // + if (g_TargetConfiguration.DeviceCertificates->Count == 0) + { + // there is nothing at the certificate store + // find size of existing config blocks + storageAddress = (uint32_t)&__nanoConfig_start__ + GetExistingConfigSize(); + } + else + { + // set storage address from block address, plus the requested offset + storageAddress = + (ByteAddress)g_TargetConfiguration.DeviceCertificates->Certificates[configurationIndex] + offset; + } + + if (g_TargetConfiguration.DeviceCertificates == NULL || + (g_TargetConfiguration.DeviceCertificates->Count == 0 || + (configurationIndex + 1) > g_TargetConfiguration.DeviceCertificates->Count)) + { + // there is no block stored + // check if there is room for it + if (((uint32_t)&__nanoConfig_end__ - storageAddress) < blockSize) + { + // not enough room + return FALSE; + } + + // // now check if memory is erase, so the block can be stored + // if (!STM32FlashDriver_IsBlockErased(NULL, storageAddress, blockSize)) + // { + // // memory not erased, can't store + // return FALSE; + // } + } + + // make sure the config block marker is set, ONLY required on the 1st chunk + if (offset == 0) + { + memcpy( + configurationBlock, + c_MARKER_CONFIGURATION_X509DEVICECERTIFICATE_V1, + sizeof(c_MARKER_CONFIGURATION_X509DEVICECERTIFICATE_V1)); + } + } + else if (configuration == DeviceConfigurationOption_All) + { + // particular situation where we are receiving the full configuration block + + // set storage address as the start of the flash configuration sector, plus the requested offset + storageAddress = (ByteAddress)&__nanoConfig_start__ + offset; + + // for save all the block size has to be provided, check that + if (blockSize == 0) + { + return FALSE; + } + } + + // // copy the config block content to the config block storage + // success = STM32FlashDriver_Write(NULL, storageAddress, blockSize, (unsigned char *)configurationBlock, true); + + // enumeration is required after we are DONE with SUCCESSFULLY storing all the config chunks + requiresEnumeration = (success && done); + + if (requiresEnumeration) + { + // free the current allocation(s) + platform_free(g_TargetConfiguration.NetworkInterfaceConfigs); + platform_free(g_TargetConfiguration.Wireless80211Configs); + platform_free(g_TargetConfiguration.CertificateStore); + platform_free(g_TargetConfiguration.DeviceCertificates); + + // perform enumeration of configuration blocks + ConfigurationManager_EnumerateConfigurationBlocks(); + } + + return success; +} + +// Updates a configuration block in the configuration flash sector +// The flash sector has to be erased before writing the updated block +// it's implemented with 'weak' attribute so it can be replaced at target level if a different persistance mechanism is +// used +__nfweak bool ConfigurationManager_UpdateConfigurationBlock( + void *configurationBlock, + DeviceConfigurationOption configuration, + uint32_t configurationIndex) +{ + ByteAddress storageAddress; + (void)storageAddress; + // uint32_t blockOffset; + // uint8_t *blockAddressInCopy; + uint32_t blockSize; + bool success = FALSE; + + // config sector size + int sizeOfConfigSector = (uint32_t)&__nanoConfig_end__ - (uint32_t)&__nanoConfig_start__; + + // allocate memory from CRT heap + uint8_t *configSectorCopy = (uint8_t *)platform_malloc(sizeOfConfigSector); + + if (configSectorCopy != NULL) + { + // copy config sector from flash to RAM + memcpy(configSectorCopy, &__nanoConfig_start__, sizeOfConfigSector); + + // find out the address for the config block to update in the configSectorCopy + // because we are copying back the config block to flash and just replacing the config block content + // the addresses in g_TargetConfiguration will remain the same + // plus we can calculate the offset of the config block from g_TargetConfiguration + if (configuration == DeviceConfigurationOption_Network) + { + // make sure the config block marker is set + memcpy(configurationBlock, c_MARKER_CONFIGURATION_NETWORK_V1, sizeof(c_MARKER_CONFIGURATION_NETWORK_V1)); + + // check if the configuration block is the same + if (ConfigurationManager_CheckExistingConfigurationBlock( + g_TargetConfiguration.NetworkInterfaceConfigs->Configs[configurationIndex], + configurationBlock, + sizeof(HAL_Configuration_NetworkInterface), + sizeof(HAL_Configuration_NetworkInterface))) + { + // block is the same + // free memory + platform_free(configSectorCopy); + + // operation is successfull (nothing to update) + return TRUE; + } + + // get storage address from block address + storageAddress = (ByteAddress)g_TargetConfiguration.NetworkInterfaceConfigs->Configs[configurationIndex]; + + // set block size, in case it's not already set + blockSize = sizeof(HAL_Configuration_NetworkInterface); + + _ASSERTE(((HAL_Configuration_NetworkInterface *)configurationBlock)->StartupAddressMode > 0); + } + else if (configuration == DeviceConfigurationOption_Wireless80211Network) + { + // make sure the config block marker is set + memcpy( + configurationBlock, + c_MARKER_CONFIGURATION_WIRELESS80211_V1, + sizeof(c_MARKER_CONFIGURATION_WIRELESS80211_V1)); + + // check if the configuration block is the same + if (ConfigurationManager_CheckExistingConfigurationBlock( + g_TargetConfiguration.Wireless80211Configs->Configs[configurationIndex], + configurationBlock, + sizeof(HAL_Configuration_Wireless80211), + sizeof(HAL_Configuration_Wireless80211))) + { + // block is the same + // free memory + platform_free(configSectorCopy); + + // operation is successfull (nothing to update) + return TRUE; + } + + // storage address from block address + storageAddress = (ByteAddress)g_TargetConfiguration.Wireless80211Configs->Configs[configurationIndex]; + + // set block size, in case it's not already set + blockSize = sizeof(HAL_Configuration_Wireless80211); + } + else if (configuration == DeviceConfigurationOption_X509CaRootBundle) + { + // make sure the config block marker is set + memcpy( + configurationBlock, + c_MARKER_CONFIGURATION_X509CAROOTBUNDLE_V1, + sizeof(c_MARKER_CONFIGURATION_X509CAROOTBUNDLE_V1)); + + // check if certificate is the same + if (ConfigurationManager_CheckExistingConfigurationBlock( + g_TargetConfiguration.CertificateStore->Certificates[configurationIndex]->Certificate, + ((HAL_Configuration_X509CaRootBundle *)configurationBlock)->Certificate, + g_TargetConfiguration.CertificateStore->Certificates[configurationIndex]->CertificateSize, + ((HAL_Configuration_X509CaRootBundle *)configurationBlock)->CertificateSize)) + { + // block is the same + // free memory + platform_free(configSectorCopy); + + // operation is successfull (nothing to update) + return TRUE; + } + + // storage address from block address + storageAddress = (ByteAddress)g_TargetConfiguration.CertificateStore->Certificates[configurationIndex]; + + // set block size, in case it's not already set + // because X509 certificate has a variable length need to compute the block size in two steps + blockSize = offsetof(HAL_Configuration_X509CaRootBundle, Certificate); + blockSize += ((HAL_Configuration_X509CaRootBundle *)configurationBlock)->CertificateSize; + } + else if (configuration == DeviceConfigurationOption_X509DeviceCertificates) + { + // make sure the config block marker is set + memcpy( + configurationBlock, + c_MARKER_CONFIGURATION_X509DEVICECERTIFICATE_V1, + sizeof(c_MARKER_CONFIGURATION_X509DEVICECERTIFICATE_V1)); + + // check if certificate is the same + if (ConfigurationManager_CheckExistingConfigurationBlock( + g_TargetConfiguration.DeviceCertificates->Certificates[configurationIndex]->Certificate, + ((HAL_Configuration_X509DeviceCertificate *)configurationBlock)->Certificate, + g_TargetConfiguration.DeviceCertificates->Certificates[configurationIndex]->CertificateSize, + ((HAL_Configuration_X509DeviceCertificate *)configurationBlock)->CertificateSize)) + { + // block is the same + // free memory + platform_free(configSectorCopy); + + // operation is successfull (nothing to update) + return TRUE; + } + + // storage address from block address + storageAddress = (ByteAddress)g_TargetConfiguration.DeviceCertificates->Certificates[configurationIndex]; + + // set block size, in case it's not already set + // because X509 certificate has a variable length need to compute the block size in two steps + blockSize = offsetof(HAL_Configuration_X509DeviceCertificate, Certificate); + blockSize += ((HAL_Configuration_X509DeviceCertificate *)configurationBlock)->CertificateSize; + } + else + { + // this not a valid configuration option to update, quit + // free memory first + platform_free(configSectorCopy); + + return FALSE; + } + + // // erase config sector + // if (STM32FlashDriver_EraseBlock(NULL, (uint32_t)&__nanoConfig_start__) == TRUE) + // { + // // flash block is erased + + // // subtract the start address of config sector to get the offset + // blockOffset = storageAddress - (uint32_t)&__nanoConfig_start__; + + // // set pointer to block to udpate + // blockAddressInCopy = configSectorCopy + blockOffset; + + // // replace config block with new content by replacing memory + // memcpy(blockAddressInCopy, configurationBlock, blockSize); + + // // copy the config block copy back to the config block storage + // success = STM32FlashDriver_Write( + // NULL, + // (uint32_t)&__nanoConfig_start__, + // sizeOfConfigSector, + // (unsigned char *)configSectorCopy, + // true); + // } + + // free memory + platform_free(configSectorCopy); + } + + return success; +} + +// Default initialisation for wireless config block +// it's implemented with 'weak' attribute so it can be replaced at target level if different configurations are intended +__nfweak void InitialiseWirelessDefaultConfig(HAL_Configuration_Wireless80211 *config, uint32_t configurationIndex) +{ + memset(config, 0, sizeof(HAL_Configuration_Wireless80211)); + + // make sure the config block marker is set + memcpy(config, c_MARKER_CONFIGURATION_WIRELESS80211_V1, sizeof(c_MARKER_CONFIGURATION_WIRELESS80211_V1)); + + // Wireless station + config->Id = configurationIndex; + + config->Options = + (Wireless80211Configuration_ConfigurationOptions)(Wireless80211Configuration_ConfigurationOptions_AutoConnect | Wireless80211Configuration_ConfigurationOptions_Enable); +} + +// Default initialisation for Network interface config blocks +// it's implemented with 'weak' attribute so it can be replaced at target level if different configurations are intended +__nfweak bool InitialiseNetworkDefaultConfig(HAL_Configuration_NetworkInterface *config, uint32_t configurationIndex) +{ + (void)configurationIndex; + + // #if (TARGET_HAS_WIFI_SUPPORT == 1) + + // memset(config, 0, sizeof(HAL_Configuration_NetworkInterface)); + + // // make sure the config block marker is set + // memcpy(config->Marker, c_MARKER_CONFIGURATION_NETWORK_V1, sizeof(c_MARKER_CONFIGURATION_NETWORK_V1)); + + // // currently only Wireless station is supported + // config->InterfaceType = NetworkInterfaceType_Wireless80211; + // config->StartupAddressMode = AddressMode_DHCP; + // config->AutomaticDNS = 1; + // config->SpecificConfigId = 0; + + // // fill in MAX with 0xFF to allow it updating it later + // memset(config->MacAddress, 0xFF, sizeof(config->MacAddress)); + + // // get default MAC + // #if defined(WIFI_DRIVER_ISM43362) && defined(I_AM_NANOCLR) + // // OK to ignore the return value, no harm done if it fails + // WIFI_GetMAC_Address(config->MacAddress); + // #endif + + // return TRUE; + + // #else + + (void)config; + + // can't create a "default" network config because we are lacking definition of a MAC address + + return FALSE; + // #endif +} + +int32_t ConfigurationManager_FindNetworkConfigurationMatchingWirelessConfigurationFromId(uint32_t configurationId) +{ + // loop though all Network config blocks trying to find one that has this ID as its SpecificConfig ID + for (int index = 0; index < g_TargetConfiguration.NetworkInterfaceConfigs->Count; index++) + { + if (g_TargetConfiguration.NetworkInterfaceConfigs->Configs[index]->SpecificConfigId == configurationId) + { + return index; + } + } + + // not found + return -1; +} diff --git a/targets/AzureRTOS/SiliconLabs/_common/usb_cdc_acm_app.c b/targets/AzureRTOS/SiliconLabs/_common/usb_cdc_acm_app.c new file mode 100644 index 0000000000..56a70aaf88 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_common/usb_cdc_acm_app.c @@ -0,0 +1,86 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Portions Copyright 2018 Silicon Laboratories Inc. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +#include +#include +#include + +#include +#include +#include +#include "sl_usbd_class_cdc.h" +#include "sl_usbd_class_cdc_acm.h" + +#include "sl_usbd_class_cdc_acm_instances.h" + +// Task configuration +#define TASK_STACK_SIZE 512u +#define TASK_PRIO 24u + +// sl_usbd_on_bus_event() +// @brief USB bus events. +void sl_usbd_on_bus_event(sl_usbd_bus_event_t event) +{ + switch (event) + { + case SL_USBD_EVENT_BUS_CONNECT: + // called when usb cable is inserted in a host controller + break; + + case SL_USBD_EVENT_BUS_DISCONNECT: + // called when usb cable is removed from a host controller + break; + + case SL_USBD_EVENT_BUS_RESET: + // called when the host sends reset command + break; + + case SL_USBD_EVENT_BUS_SUSPEND: + // called when the host sends suspend command + break; + + case SL_USBD_EVENT_BUS_RESUME: + // called when the host sends wake up command + break; + + default: + break; + } +} + +// sl_usbd_on_config_event() +// @brief USB configuration events. +void sl_usbd_on_config_event(sl_usbd_config_event_t event, uint8_t config_nbr) +{ + (void)config_nbr; + + switch (event) + { + case SL_USBD_EVENT_CONFIG_SET: + // called when the host sets a configuration after reset + break; + + case SL_USBD_EVENT_CONFIG_UNSET: + // called when a configuration is unset due to reset command + break; + + default: + break; + } +} + +// Initialize application. +void usb_device_cdc_acm_app_init(void) +{ + // need to configure the CDC with the proper WP settings + sl_usbd_cdc_acm_line_coding_t codingBaudRate; + codingBaudRate.baudrate = 921600; + codingBaudRate.data_bits = 8; + codingBaudRate.parity = SL_USBD_CDC_ACM_PARITY_NONE; + codingBaudRate.stop_bits = SL_USBD_CDC_ACM_STOP_BIT_1; + + sl_usbd_cdc_acm_set_line_coding(sl_usbd_cdc_acm_acm0_number, &codingBaudRate); +} diff --git a/targets/AzureRTOS/SiliconLabs/_include/CMakeLists.txt b/targets/AzureRTOS/SiliconLabs/_include/CMakeLists.txt new file mode 100644 index 0000000000..a04b9c88fb --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_include/CMakeLists.txt @@ -0,0 +1,10 @@ +# +# Copyright (c) .NET Foundation and Contributors +# See LICENSE file in the project root for full license information. +# + +# append include directory for target Azure RTOS +list(APPEND TARGET_AZURERTOS_COMMON_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}) + +# make var global +set(TARGET_AZURERTOS_COMMON_INCLUDE_DIRS ${TARGET_AZURERTOS_COMMON_INCLUDE_DIRS} CACHE INTERNAL "make global") diff --git a/targets/AzureRTOS/SiliconLabs/_include/Target_BlockStorage_SL_MscFlashDriver.h b/targets/AzureRTOS/SiliconLabs/_include/Target_BlockStorage_SL_MscFlashDriver.h new file mode 100644 index 0000000000..5e80811b80 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_include/Target_BlockStorage_SL_MscFlashDriver.h @@ -0,0 +1,34 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#ifndef TARGET_SL_MSCFLASH_DRIVER_H +#define TARGET_SL_MSCFLASH_DRIVER_H + +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + + bool SL_MscFlashDriver_InitializeDevice(void *); + bool SL_MscFlashDriver_UninitializeDevice(void *); + DeviceBlockInfo *SL_MscFlashDriver_GetDeviceInfo(void *); + bool SL_MscFlashDriver_Read(void *, ByteAddress startAddress, unsigned int numBytes, unsigned char *buffer); + bool SL_MscFlashDriver_Write( + void *, + ByteAddress startAddress, + unsigned int numBytes, + unsigned char *buffer, + bool readModifyWrite); + bool SL_MscFlashDriver_IsBlockErased(void *, ByteAddress blockAddress, unsigned int length); + bool SL_MscFlashDriver_EraseBlock(void *, ByteAddress address); + +#ifdef __cplusplus +} +#endif + +#endif // TARGET_SL_MSCFLASH_DRIVER_H diff --git a/targets/AzureRTOS/SiliconLabs/_include/Target_GenericPort_stdio.h b/targets/AzureRTOS/SiliconLabs/_include/Target_GenericPort_stdio.h new file mode 100644 index 0000000000..e025c16e1e --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_include/Target_GenericPort_stdio.h @@ -0,0 +1,23 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#ifndef TARGET_GENERIC_PORT_STDIO_H +#define TARGET_GENERIC_PORT_STDIO_H + +#include +#include + +// // the following macro defines a function that configures the GPIO pins for a STM32 UART/USART +// // this is required because the UART/USART peripherals can use multiple GPIO configuration combinations +// #define STDIO_UART_CONFIG_PINS(gpio_port_tx, gpio_port_rx, tx_pin, rx_pin, alternate_function) \ +// void StdioConfigPins_UART() \ +// { \ +// palSetPadMode(gpio_port_tx, tx_pin, PAL_MODE_ALTERNATE(alternate_function)); \ +// palSetPadMode(gpio_port_rx, rx_pin, PAL_MODE_ALTERNATE(alternate_function)); \ +// } + +// void StdioConfigPins_UART(void); + +#endif // TARGET_GENERIC_PORT_STDIO_H diff --git a/targets/AzureRTOS/SiliconLabs/_include/nano_sl_usbd_class_vendor.h b/targets/AzureRTOS/SiliconLabs/_include/nano_sl_usbd_class_vendor.h new file mode 100644 index 0000000000..a7b7ebcadb --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_include/nano_sl_usbd_class_vendor.h @@ -0,0 +1,430 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Portions Copyright 2021 Silicon Laboratories Inc. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +// This is an extension to the original file from Gecko SDK v4.1.1 +// Following Support Case #00293097 with Silabs, we where advised to add the missing +// APIs to our own implementation. In case these are ever made available in the +// official SDK, this file should be removed and the original one should be used. + +// clang-format off + +#ifndef SL_USBD_CLASS_VENDOR_H +#define SL_USBD_CLASS_VENDOR_H + +/******************************************************************************************************** + ******************************************************************************************************** + * INCLUDE FILES + ******************************************************************************************************** + *******************************************************************************************************/ + +#include +#include + +#include + +/******************************************************************************************************** + ******************************************************************************************************** + * DATA TYPES + ******************************************************************************************************** + *******************************************************************************************************/ +/// Vendor callbacks +typedef const struct { + void (*enable)(uint8_t class_nbr); ///< Callback for enable event + + void (*disable)(uint8_t class_nbr); ///< Callback for disable event + + void (*setup_req)(uint8_t class_nbr, + const sl_usbd_setup_req_t *p_setup_req); ///< Callback for setup req event +} sl_usbd_vendor_callbacks_t; + +/// App callback used for async comm. +typedef void (*sl_usbd_vendor_async_function_t)(uint8_t class_nbr, + void *p_buf, + uint32_t buf_len, + uint32_t xfer_len, + void *p_callback_arg, + sl_status_t status); + +/******************************************************************************************************** + ******************************************************************************************************** + * FUNCTION PROTOTYPES + ******************************************************************************************************** + *******************************************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************************************** + * VENDOR FUNCTIONS + *******************************************************************************************************/ + +/****************************************************************************************************//** + * @brief Initialize the internal structures and variables used by the Vendor class. + * + * @return Returns SL_STATUS_OK on success or another SL_STATUS code on failure. + *******************************************************************************************************/ +sl_status_t sl_usbd_vendor_init(void); + +/****************************************************************************************************//** + * @brief Add a new instance of the Vendor class. + * + * @param intr_en Interrupt endpoints IN and OUT flag: + * - true Pair of interrupt endpoints added to interface. + * - false Pair of interrupt endpoints not added to interface. + * + * @param interval Endpoint interval in milliseconds (must be a power of 2). + * + * @param p_vendor_callbacks Pointer to vendor callback structure. + * [Content MUST be persistent] + * + * @param p_class_nbr Pointer to a variable that will receive class instance number, if no + * errors are returned, or SL_USBD_CLASS_NBR_NONE otherwise. + * + * @return Returns SL_STATUS_OK on success or another SL_STATUS code on failure. + *******************************************************************************************************/ +sl_status_t sl_usbd_vendor_create_instance(bool intr_en, + uint16_t interval, + sl_usbd_vendor_callbacks_t *p_vendor_callbacks, + uint8_t *p_class_nbr); + +/****************************************************************************************************//** + * @brief Add the Vendor class instance into the specified configuration (see Note #1). + * + * @param class_nbr Class instance number. + * + * @param config_nbr Configuration index to which to add the Vendor class instance. + * + * @return Returns SL_STATUS_OK on success or another SL_STATUS code on failure. + * + * @note (1) Called several times, it creates multiple instances and configurations. + * For instance, the following architecture could be created : + * @verbatim + * FS + * |-- Configuration 0 + * |-- Interface 0 (Vendor 0) + * |-- Configuration 1 + * |-- Interface 0 (Vendor 0) + * |-- Interface 1 (Vendor 1) + * @endverbatim + * In that example, there are two instances of Vendor class: 'Vendor 0' and '1', and two + * possible configurations: 'Configuration 0' and '1'. 'Configuration 1' is composed + * of two interfaces. Each class instance has an association with one of the interfaces. + * If 'Configuration 1' is activated by the host, it allows the host to access two + * different functionalities offered by the device. + * + * @note (2) Configuration Descriptor corresponding to a Vendor-specific device has the following + * format : + * @verbatim + * Configuration Descriptor + * |-- Interface Descriptor (Vendor class) + * |-- Endpoint Descriptor (Bulk OUT) + * |-- Endpoint Descriptor (Bulk IN) + * |-- Endpoint Descriptor (Interrupt OUT) - optional + * |-- Endpoint Descriptor (Interrupt IN) - optional + * @endverbatim + *******************************************************************************************************/ +sl_status_t sl_usbd_vendor_add_to_configuration(uint8_t class_nbr, + uint8_t config_nbr); + +/****************************************************************************************************//** + * @brief Get the vendor class enable state. + * + * @param class_nbr Class instance number. + * + * @param p_enabled Pointer to a variable that will receive the enable state. + * The variable is set to true, if the Vendor class is enabled, + * and is set to false if the Vendor class is NOT enabled. + * + * @return Returns SL_STATUS_OK on success or another SL_STATUS code on failure. + *******************************************************************************************************/ +sl_status_t sl_usbd_vendor_is_enabled(uint8_t class_nbr, + bool *p_enabled); + +/****************************************************************************************************//** + * @brief Add a Microsoft OS extended property to this vendor class instance. + * + * @param class_nbr Class instance number. + * + * @param property_type Property type (see Note #2). + * - OS_PROPERTY_TYPE_REG_SZ + * - OS_PROPERTY_TYPE_REG_EXPAND_SZ + * - OS_PROPERTY_TYPE_REG_BINARY + * - OS_PROPERTY_TYPE_REG_DWORD_LITTLE_ENDIAN + * - OS_PROPERTY_TYPE_REG_DWORD_BIG_ENDIAN + * - OS_PROPERTY_TYPE_REG_LINK + * - OS_PROPERTY_TYPE_REG_MULTI_SZ + * + * @param p_property_name Pointer to the buffer that contains the property name. + * ---- Buffer assumed to be persistent ---- + * + * @param property_name_len Length of the property name in octets. + * + * @param p_property Pointer to the buffer that contains the property name. + * ---- Buffer assumed to be persistent ---- + * + * @param property_len Length of the property in octets. + * + * @return Returns SL_STATUS_OK on success or another SL_STATUS code on failure. + * + * @note (1) For more information on Microsoft OS descriptors, see + * 'http://msdn.microsoft.com/en-us/library/windows/hardware/gg463179.aspx'. + * + * @note (2) For more information on property types, refer to "Table 3. Property Data Types" of + * "Extended Properties OS Feature Descriptor Specification" document provided by + * Microsoft available at + * 'http://msdn.microsoft.com/en-us/library/windows/hardware/gg463179.aspx'. + *******************************************************************************************************/ +#if (USBD_CFG_MS_OS_DESC_EN == 1) +sl_status_t sl_usbd_vendor_add_microsoft_ext_property(uint8_t class_nbr, + uint8_t property_type, + const uint8_t *p_property_name, + uint16_t property_name_len, + const uint8_t *p_property, + uint32_t property_len); +#endif + +/****************************************************************************************************//** + * @brief Receive the data from the host through the Bulk OUT endpoint. This function is blocking. + * + * @param class_nbr Class instance number. + * + * @param p_buf Pointer to the receive buffer. + * + * @param buf_len Receive the buffer length in octets. + * + * @param timeout Timeout in milliseconds. + * + * @param p_xfer_len Pointer to a variable that will receive transfer length. + * The variable is set to number of octets received, if no errors are returned, + * or is set to 0 if any errors are returned. + * + * @return Returns SL_STATUS_OK on success or another SL_STATUS code on failure. + *******************************************************************************************************/ +sl_status_t sl_usbd_vendor_read_bulk_sync(uint8_t class_nbr, + void *p_buf, + uint32_t buf_len, + uint16_t timeout, + uint32_t *p_xfer_len); + +/****************************************************************************************************//** + * @brief Send data to the host through Bulk IN endpoint. This function is blocking. + * + * @param class_nbr Class instance number. + * + * @param p_buf Pointer to the transmit buffer. + * + * @param buf_len Transmit the buffer length in octets. + * + * @param timeout Timeout in milliseconds. + * + * @param end End-of-transfer flag (see Note #1). + * + * @param p_xfer_len Pointer to a variable that will receive transfer length. + * The variable is set to number of octets received, if no errors are returned, + * or is set to 0 if any errors are returned. + * + * @return Returns SL_STATUS_OK on success or another SL_STATUS code on failure. + * + * @note (1) If the end-of-transfer is set and the transfer length is a multiple of the maximum + * packet size, a zero-length packet is transferred to signal the end of transfer to the host. + *******************************************************************************************************/ +sl_status_t sl_usbd_vendor_write_bulk_sync(uint8_t class_nbr, + void *p_buf, + uint32_t buf_len, + uint16_t timeout, + bool end, + uint32_t *p_xfer_len); + +/****************************************************************************************************//** + * @brief Receive data from the host through the Bulk OUT endpoint. This function is non-blocking + * are returns immediately after transfer preparation. Upon transfer completion, a callback + * provided by the application will be called to finalize the transfer. + * + * @param class_nbr Class instance number. + * + * @param p_buf Pointer to the receive buffer. + * + * @param buf_len Receive buffer length in octets. + * + * @param async_fnct Receive the the callback. + * + * @param p_async_arg Additional argument provided by the application for the receive callback. + * + * @return Returns SL_STATUS_OK on success or another SL_STATUS code on failure. + *******************************************************************************************************/ +sl_status_t sl_usbd_vendor_read_bulk_async(uint8_t class_nbr, + void *p_buf, + uint32_t buf_len, + sl_usbd_vendor_async_function_t async_fnct, + void *p_async_arg); + +/****************************************************************************************************//** + * @brief Send data to the host through the Bulk IN endpoint. This function is non-blocking + * and returns immediately after transfer preparation. Upon transfer completion, a + * callback provided by the application will be called to finalize the transfer. + * + * @param class_nbr Class instance number. + * + * @param p_buf Pointer to the transmit buffer. + * + * @param buf_len Transmit buffer length in octets. + * + * @param async_fnct Transmit the callback. + * + * @param p_async_arg Additional argument provided by the application for the transmit callback. + * + * @param end End-of-transfer flag (see Note #1). + * + * @return Returns SL_STATUS_OK on success or another SL_STATUS code on failure. + * + * @note (1) If the end-of-transfer is set and the transfer length is a multiple of the maximum + * packet size, a zero-length packet is transferred to signal the end of transfer to the host. + *******************************************************************************************************/ +sl_status_t sl_usbd_vendor_write_bulk_async(uint8_t class_nbr, + void *p_buf, + uint32_t buf_len, + sl_usbd_vendor_async_function_t async_fnct, + void *p_async_arg, + bool end); + +/****************************************************************************************************//** + * @brief Receive data from the the host through the Interrupt OUT endpoint. This function is blocking. + * + * @param class_nbr Class instance number. + * + * @param p_buf Pointer to the receive buffer. + * + * @param buf_len Receive buffer length in octets. + * + * @param timeout Timeout in milliseconds. + * + * @param p_xfer_len Pointer to a variable that will receive transfer length. + * The variable is set to number of octets received, if no errors are returned, + * or is set to 0 if any errors are returned. + * + * @return Returns SL_STATUS_OK on success or another SL_STATUS code on failure. + *******************************************************************************************************/ +sl_status_t sl_usbd_vendor_read_interrupt_sync(uint8_t class_nbr, + void *p_buf, + uint32_t buf_len, + uint16_t timeout, + uint32_t *p_xfer_len); + +/****************************************************************************************************//** + * @brief Send data to the host through the Interrupt IN endpoint. This function is blocking. + * + * @param class_nbr Class instance number. + * + * @param p_buf Pointer to the transmit buffer. + * + * @param buf_len Transmit buffer length in octets. + * + * @param timeout Timeout in milliseconds. + * + * @param end End-of-transfer flag (see Note #1). + * + * @param p_xfer_len Pointer to a variable that will receive transfer length. + * The variable is set to number of octets received, if no errors are returned, + * or is set to 0 if any errors are returned. + * + * @return Returns SL_STATUS_OK on success or another SL_STATUS code on failure. + * + * @note (1) If the end-of-transfer is set and the transfer length is a multiple of the maximum + * packet size, a zero-length packet is transferred to signal the end of transfer to the host. + *******************************************************************************************************/ +sl_status_t sl_usbd_vendor_write_interrupt_sync(uint8_t class_nbr, + void *p_buf, + uint32_t buf_len, + uint16_t timeout, + bool end, + uint32_t *p_xfer_len); + +/****************************************************************************************************//** + * @brief Receive data from the host through Interrupt OUT endpoint. This function is non-blocking + * and returns immediately after transfer preparation. Upon transfer completion, a callback + * provided by the application will be called to finalize the transfer. + * + * @param class_nbr Class instance number. + * + * @param p_buf Pointer to the receive buffer. + * + * @param buf_len Receive buffer length in octets. + * + * @param async_fnct Receive callback. + * + * @param p_async_arg Additional argument provided by application for the receive callback. + * + * @return Returns SL_STATUS_OK on success or another SL_STATUS code on failure. + *******************************************************************************************************/ +sl_status_t sl_usbd_vendor_read_interrupt_async(uint8_t class_nbr, + void *p_buf, + uint32_t buf_len, + sl_usbd_vendor_async_function_t async_fnct, + void *p_async_arg); + +/****************************************************************************************************//** + * @brief Send data to the host through the Interrupt IN endpoint. This function is non-blocking + * and returns immediately after transfer preparation. Upon transfer completion, a callback + * provided by the application will be called to finalize the transfer. + * + * @param class_nbr Class instance number. + * + * @param p_buf Pointer to the transmit buffer. + * + * @param buf_len Transmit buffer length in octets. + * + * @param async_fnct Transmit callback. + * + * @param p_async_arg Additional argument provided by the application for the transmit callback. + * + * @param end End-of-transfer flag (see Note #1). + * + * @return Returns SL_STATUS_OK on success or another SL_STATUS code on failure. + * + * @note (1) If the end-of-transfer is set and the transfer length is a multiple of the maximum + * packet size, a zero-length packet is transferred to signal the end of transfer to the host. + *******************************************************************************************************/ +sl_status_t sl_usbd_vendor_write_interrupt_async(uint8_t class_nbr, + void *p_buf, + uint32_t buf_len, + sl_usbd_vendor_async_function_t async_fnct, + void *p_async_arg, + bool end); + +// clang-format on + +// [NF_CHANGE] + +// Abort an ongoing async I/O transfer on the Bulk OUT endpoint. +// class_nbr Class instance number. +// Returns SL_STATUS_OK on success or another SL_STATUS code on failure. +sl_status_t sl_usbd_vendor_abort_read_bulk(uint8_t class_nbr); + +// Abort an ongoing async I/O transfer on the Bulk IN endpoint. +// param class_nbr Class instance number. +// Returns SL_STATUS_OK on success or another SL_STATUS code on failure. +sl_status_t sl_usbd_vendor_abort_write_bulk(uint8_t class_nbr); + +sl_status_t sl_usbd_vendor_update_device_product_string(const char *product_string); + +// [END_NF_CHANGE] + +#ifdef __cplusplus +} +#endif + +// clang-format off + +/****************************************************************************************************//** + ******************************************************************************************************** + * @} MODULE END + ******************************************************************************************************** + *******************************************************************************************************/ + +#endif + +// clang-format on diff --git a/targets/AzureRTOS/SiliconLabs/_include/platformHAL.h b/targets/AzureRTOS/SiliconLabs/_include/platformHAL.h new file mode 100644 index 0000000000..de17779923 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_include/platformHAL.h @@ -0,0 +1,14 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#ifndef _PLATFORM_HAL_TIME_H_ +#define _PLATFORM_HAL_TIME_H_ + +#define WIRE_PROTOCOL_UART_BUFFER_SIZE 32 + +// event flag for SPI transaction completed +#define NANO_HW_EVENTS_SPI_TRANSACTION_FLAG 0x00000001 + +#endif //_PLATFORM_HAL_TIME_H_ diff --git a/targets/AzureRTOS/SiliconLabs/_include/sli_usbd_class_hid_azurertos.h b/targets/AzureRTOS/SiliconLabs/_include/sli_usbd_class_hid_azurertos.h new file mode 100644 index 0000000000..caf93d1396 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_include/sli_usbd_class_hid_azurertos.h @@ -0,0 +1,196 @@ +/***************************************************************************//** + * @file + * @brief USB Device - USB Hid Class Operating System Layer + ******************************************************************************* + * # License + * Copyright 2018 Silicon Laboratories Inc. www.silabs.com + ******************************************************************************* + * + * The licensor of this software is Silicon Laboratories Inc. Your use of this + * software is governed by the terms of Silicon Labs Master Software License + * Agreement (MSLA) available at + * www.silabs.com/about-us/legal/master-software-license-agreement. + * The software is governed by the sections of the MSLA applicable to Micrium + * Software. + * + ******************************************************************************/ + +/******************************************************************************************************** + ******************************************************************************************************** + * MODULE + ******************************************************************************************************** + *******************************************************************************************************/ + +#ifndef SLI_USBD_CLASS_HID_OS_H +#define SLI_USBD_CLASS_HID_OS_H + +/******************************************************************************************************** + ******************************************************************************************************** + * INCLUDE FILES + ******************************************************************************************************** + *******************************************************************************************************/ + +#include + +#include "sl_usbd_core.h" + +/******************************************************************************************************** + ******************************************************************************************************** + * FUNCTION PROTOTYPES + ******************************************************************************************************** + *******************************************************************************************************/ + +/****************************************************************************************************//** + * sli_usbd_hid_os_init() + * + * @brief Initialize HID OS interface. + * + * @return Returns SL_STATUS_OK on success or another SL_STATUS code on failure. + *******************************************************************************************************/ +sl_status_t sli_usbd_hid_os_init(void); + +/****************************************************************************************************//** + * sli_usbd_hid_os_lock_input() + * + * @brief Lock class input report. + * + * @param class_nbr Class instance number. + * + * @return Returns SL_STATUS_OK on success or another SL_STATUS code on failure. + *******************************************************************************************************/ +sl_status_t sli_usbd_hid_os_lock_input(uint8_t class_nbr); + +/****************************************************************************************************//** + * sli_usbd_hid_os_unlock_input() + * + * @brief Unlock class input report. + * + * @param class_nbr Class instance number. + * + * @return Returns SL_STATUS_OK on success or another SL_STATUS code on failure. + *******************************************************************************************************/ +sl_status_t sli_usbd_hid_os_unlock_input(uint8_t class_nbr); + +/****************************************************************************************************//** + * sli_usbd_hid_os_pend_input() + * + * @brief Wait for input report data transfer to complete. + * + * @param class_nbr Class instance number. + * + * @param timeout_ms Signal wait timeout in milliseconds. + * + * @return Returns SL_STATUS_OK on success or another SL_STATUS code on failure. + *******************************************************************************************************/ +sl_status_t sli_usbd_hid_os_pend_input(uint8_t class_nbr, + uint16_t timeout_ms); + +/****************************************************************************************************//** + * sli_usbd_hid_os_pend_abort_input() + * + * @brief Abort any operation on input report. + * + * @param class_nbr Class instance number. + * + * @return Returns SL_STATUS_OK on success or another SL_STATUS code on failure. + *******************************************************************************************************/ +sl_status_t sli_usbd_hid_os_pend_abort_input(uint8_t class_nbr); + +/****************************************************************************************************//** + * sli_usbd_hid_os_post_input() + * + * @brief Signal that input report data transfer has completed. + * + * @param class_nbr Class instance number. + * + * @return Returns SL_STATUS_OK on success or another SL_STATUS code on failure. + *******************************************************************************************************/ +sl_status_t sli_usbd_hid_os_post_input(uint8_t class_nbr); + +/****************************************************************************************************//** + * sli_usbd_hid_os_lock_output() + * + * @brief Lock class output report. + * + * @param class_nbr Class instance number. + * + * @return Returns SL_STATUS_OK on success or another SL_STATUS code on failure. + *******************************************************************************************************/ +sl_status_t sli_usbd_hid_os_lock_output(uint8_t class_nbr); + +/****************************************************************************************************//** + * sli_usbd_hid_os_unlock_output() + * + * @brief Unlock class output report. + * + * @param class_nbr Class instance number. + * + * @return Returns SL_STATUS_OK on success or another SL_STATUS code on failure. + *******************************************************************************************************/ +sl_status_t sli_usbd_hid_os_unlock_output(uint8_t class_nbr); + +/****************************************************************************************************//** + * sli_usbd_hid_os_pend_abort_output() + * + * @brief Abort class output report. + * + * @param class_nbr Class instance number. + * + * @return Returns SL_STATUS_OK on success or another SL_STATUS code on failure. + *******************************************************************************************************/ +sl_status_t sli_usbd_hid_os_pend_abort_output(uint8_t class_nbr); + +/****************************************************************************************************//** + * sli_usbd_hid_os_pend_output() + * + * @brief Wait for output report data transfer to complete. + * + * @param class_nbr Class instance number. + * + * @param timeout_ms Signal wait timeout, in milliseconds. + * + * @return Returns SL_STATUS_OK on success or another SL_STATUS code on failure. + *******************************************************************************************************/ +sl_status_t sli_usbd_hid_os_pend_output(uint8_t class_nbr, + uint16_t timeout_ms); + +/****************************************************************************************************//** + * sli_usbd_hid_os_post_output() + * + * @brief Signal that output report data is available. + * + * @param class_nbr Class instance number. + * + * @return Returns SL_STATUS_OK on success or another SL_STATUS code on failure. + *******************************************************************************************************/ +sl_status_t sli_usbd_hid_os_post_output(uint8_t class_nbr); + +/****************************************************************************************************//** + * sli_usbd_hid_os_lock_tx() + * + * @brief Lock class transmit. + * + * @param class_nbr Class instance number. + * + * @return Returns SL_STATUS_OK on success or another SL_STATUS code on failure. + *******************************************************************************************************/ +sl_status_t sli_usbd_hid_os_lock_tx(uint8_t class_nbr); + +/****************************************************************************************************//** + * sli_usbd_hid_os_unlock_tx() + * + * @brief Unlock class transmit. + * + * @param class_nbr Class instance number. + * + * @return Returns SL_STATUS_OK on success or another SL_STATUS code on failure. + *******************************************************************************************************/ +sl_status_t sli_usbd_hid_os_unlock_tx(uint8_t class_nbr); + +/****************************************************************************************************//** + ******************************************************************************************************** + * MODULE END + ******************************************************************************************************** + *******************************************************************************************************/ + +#endif diff --git a/targets/AzureRTOS/SiliconLabs/_include/targetHAL_Time.h b/targets/AzureRTOS/SiliconLabs/_include/targetHAL_Time.h new file mode 100644 index 0000000000..e58e91a0b7 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_include/targetHAL_Time.h @@ -0,0 +1,35 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#ifndef _TARGET_HAL_TIME_H_ +#define _TARGET_HAL_TIME_H_ + +#include + +#define HAL_Time_CurrentSysTicks tx_time_get + +#ifdef __cplusplus +extern "C" +{ +#endif + + // Converts CMSIS sysTicks to .NET ticks (100 nanoseconds) + inline __attribute__((always_inline)) uint64_t HAL_Time_SysTicksToTime(uint64_t sysTicks) + { + // need to convert Azure RTOS ticks to 100 nanoseconds + return sysTicks * TX_TIMER_TICKS_PER_SECOND * 10; + } + + // because HAL_Time_SysTicksToTime needs to be called from C we need a proxy to allow it to be called from 'C' code + inline __attribute__((always_inline)) uint64_t HAL_Time_SysTicksToTime_C(uint64_t sysTicks) + { + return sysTicks * TX_TIMER_TICKS_PER_SECOND * 10; + } + +#ifdef __cplusplus +} +#endif + +#endif //_TARGET_HAL_TIME_H_ diff --git a/targets/AzureRTOS/SiliconLabs/_include/targetPAL.h b/targets/AzureRTOS/SiliconLabs/_include/targetPAL.h new file mode 100644 index 0000000000..16d37d6c40 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_include/targetPAL.h @@ -0,0 +1,12 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#ifndef TARGETPAL_H +#define TARGETPAL_H + +// Gets the GPIO port according to a pin number +#define GPIO_PORT(pin) ((GPIO_Port_TypeDef)(pin / 16)) + +#endif // TARGETPAL_H diff --git a/targets/AzureRTOS/SiliconLabs/_nanoBooter/CMakeLists.txt b/targets/AzureRTOS/SiliconLabs/_nanoBooter/CMakeLists.txt new file mode 100644 index 0000000000..8367e19c36 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_nanoBooter/CMakeLists.txt @@ -0,0 +1,9 @@ +# +# Copyright (c) .NET Foundation and Contributors +# See LICENSE file in the project root for full license information. +# + +list(APPEND TARGET_AZURERTOS_NANOBOOTER_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/WireProtocol_MonitorCommands.c) + +# make var global +set(TARGET_AZURERTOS_NANOBOOTER_SOURCES ${TARGET_AZURERTOS_NANOBOOTER_SOURCES} CACHE INTERNAL "make global") diff --git a/targets/AzureRTOS/SiliconLabs/_nanoBooter/WireProtocol_MonitorCommands.c b/targets/AzureRTOS/SiliconLabs/_nanoBooter/WireProtocol_MonitorCommands.c new file mode 100644 index 0000000000..28a62e2560 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_nanoBooter/WireProtocol_MonitorCommands.c @@ -0,0 +1,70 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Portions Copyright (c) Microsoft Corporation. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +#include +#include +#include +#include +#include +#include + +int AccessMemory(uint32_t location, uint32_t lengthInBytes, uint8_t *buffer, int32_t mode, uint32_t *errorCode) +{ + // reset error code + *errorCode = AccessMemoryErrorCode_NoError; + + switch (mode) + { + case AccessMemory_Write: + // use FLASH driver to perform write operation + return SL_MscFlashDriver_Write(NULL, location, lengthInBytes, buffer, true); + + case AccessMemory_Erase: + // erase using FLASH driver + return SL_MscFlashDriver_EraseBlock(NULL, location); + + case AccessMemory_Check: + // compute CRC32 of the memory segment + *(unsigned int *)buffer = SUPPORT_ComputeCRC((uint32_t *)location, lengthInBytes, 0); + // done here + return true; + + case AccessMemory_Read: + // use FLASH driver to perform read operation + SL_MscFlashDriver_Read(NULL, location, lengthInBytes, buffer); + return true; + + default: + // default return is FALSE + return false; + } +} + +//////////////////////////////////////////////////// + +int Monitor_Reboot(WP_Message *message) +{ + Monitor_Reboot_Command *cmd = (Monitor_Reboot_Command *)message->m_payload; + + WP_ReplyToCommand(message, true, false, NULL, 0); + + if (cmd != NULL) + { + if (Monitor_Reboot_c_EnterProprietaryBooter == (cmd->m_flags & Monitor_Reboot_c_EnterProprietaryBooter)) + { + // request to load proprietary bootloader + // OK to call directly as this will launch the bootloader only if the target has support for it + LaunchProprietaryBootloader(); + } + else + { + // RESET CPU to load nanoCLR + NVIC_SystemReset(); + } + } + + return true; +} diff --git a/targets/AzureRTOS/SiliconLabs/_nanoCLR/CMakeLists.txt b/targets/AzureRTOS/SiliconLabs/_nanoCLR/CMakeLists.txt new file mode 100644 index 0000000000..b8a66f3f18 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_nanoCLR/CMakeLists.txt @@ -0,0 +1,40 @@ +# +# Copyright (c) .NET Foundation and Contributors +# See LICENSE file in the project root for full license information. +# + +# append target Azure RTOS nanoCLR source files +list(APPEND TARGET_AZURERTOS_NANOCLR_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/targetHAL.cpp) +list(APPEND TARGET_AZURERTOS_NANOCLR_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/targetPAL.c) +list(APPEND TARGET_AZURERTOS_NANOCLR_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/targetHAL_Time.cpp) +list(APPEND TARGET_AZURERTOS_NANOCLR_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/targetHAL_Power.c) + +# append watchdog only if option is ON +if(HAL_USE_WDG_OPTION) + list(APPEND TARGET_AZURERTOS_NANOCLR_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/targetHAL_Watchdog.c) +endif() + +# make var global +set(TARGET_AZURERTOS_NANOCLR_SOURCES ${TARGET_AZURERTOS_NANOCLR_SOURCES} CACHE INTERNAL "make global") + +# append target nanoCLR include directories +list(APPEND TARGET_AZURERTOS_NANOCLR_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}) +list(APPEND TARGET_AZURERTOS_NANOCLR_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR}) +list(APPEND TARGET_AZURERTOS_NANOCLR_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/CLR/Core) + +# append PAL include directory +list(APPEND TARGET_AZURERTOS_NANOCLR_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/PAL/Include) + +# append Runtime.Native include directory +list(APPEND TARGET_AZURERTOS_NANOCLR_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/CLR/Runtime.Native) + +# append nano API includes +list(APPEND TARGET_AZURERTOS_NANOCLR_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src) + +# append includes +list(APPEND TARGET_AZURERTOS_NANOCLR_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}) +list(APPEND TARGET_AZURERTOS_NANOCLR_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR}) +list(APPEND TARGET_AZURERTOS_NANOCLR_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src) + +# make var global +set(TARGET_AZURERTOS_NANOCLR_INCLUDE_DIRS ${TARGET_AZURERTOS_NANOCLR_INCLUDE_DIRS} CACHE INTERNAL "make global") diff --git a/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.Adc/nano_gg_adc_native_target.h b/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.Adc/nano_gg_adc_native_target.h new file mode 100644 index 0000000000..c032386018 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.Adc/nano_gg_adc_native_target.h @@ -0,0 +1,6 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +// need to have this here to keep the includes happy diff --git a/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.Adc/sys_dev_adc_native_System_Device_Adc_AdcChannel.cpp b/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.Adc/sys_dev_adc_native_System_Device_Adc_AdcChannel.cpp new file mode 100644 index 0000000000..803a491ac7 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.Adc/sys_dev_adc_native_System_Device_Adc_AdcChannel.cpp @@ -0,0 +1,97 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Portions Copyright (c) Microsoft Corporation. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +#include "sys_dev_adc_native_target.h" + +HRESULT Library_sys_dev_adc_native_System_Device_Adc_AdcChannel::NativeReadValue___I4(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + int channelNumber; + NF_PAL_ADC_PORT_PIN_CHANNEL adcDefinition; + ADC_InitSingle_TypeDef adcInitSingle; + + // ADC related variables + adcInitSingle = ADC_INITSINGLE_DEFAULT; + uint32_t sample; + ADC_TypeDef *adcDriver = NULL; + + // get a pointer to the managed object instance and check that it's not NULL + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + + // Get channel from _channelNumber field + channelNumber = pThis[FIELD___channelNumber].NumericByRef().s4; + + adcDefinition = AdcPortPinConfig[channelNumber]; + + // we should remove form the build the ADC options that aren't implemented + // plus we have to use the default to catch invalid ADC Ids + switch (adcDefinition.adcIndex) + { + +#if GECKO_USE_ADC0 + case 0: + adcDriver = ADC0; + break; +#endif + +#if GECKO_USE_ADC1 + case 1: + adcDriver = ADC1; + break; +#endif + + default: + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + if (adcDefinition.posSel == adcPosSelAVDD) + { + // Ref is 5V to measure VDD + adcInitSingle.reference = adcRef2V5; + } + else + { + // Ref is internal 2.5V for all the others, including the internal signals + adcInitSingle.reference = adcRef2V5; + } + + // single ended + adcInitSingle.diff = false; + // set acquisition time to meet minimum requirement + adcInitSingle.acqTime = adcAcqTime4; + // set pos + adcInitSingle.posSel = adcDefinition.posSel; + + ADC_InitSingle(adcDriver, &adcInitSingle); + + // Start ADC conversion + ADC_Start(adcDriver, adcStartSingle); + + // Wait for conversion to be complete + while (!(ADC0->STATUS & _ADC_STATUS_SINGLEDV_MASK)) + ; + + // perform the conversion + sample = ADC_DataSingleGet(adcDriver); + + // set the return result with the conversion value from the array + stack.SetResult_I4(sample); + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_sys_dev_adc_native_System_Device_Adc_AdcChannel::NativeDisposeChannel___VOID(CLR_RT_StackFrame &stack) +{ + (void)stack; + + NANOCLR_HEADER(); + + // left empty on purpose, nothing to do here + + NANOCLR_NOCLEANUP_NOLABEL(); +} diff --git a/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.Adc/sys_dev_adc_native_System_Device_Adc_AdcController.cpp b/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.Adc/sys_dev_adc_native_System_Device_Adc_AdcController.cpp new file mode 100644 index 0000000000..a451e4dd8b --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.Adc/sys_dev_adc_native_System_Device_Adc_AdcController.cpp @@ -0,0 +1,132 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Portions Copyright (c) Microsoft Corporation. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +#include "sys_dev_adc_native_target.h" + +#define ADC_FREQ 16000000 + +HRESULT Library_sys_dev_adc_native_System_Device_Adc_AdcController::NativeOpenChannel___VOID__I4( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + int channel; + NF_PAL_ADC_PORT_PIN_CHANNEL adcDefinition; + ADC_Init_TypeDef adcInit; + CMU_Clock_TypeDef adcClock; + ADC_TypeDef *adcDriver = NULL; + + adcInit = ADC_INIT_DEFAULT; + + // get a pointer to the managed object instance and check that it's not NULL + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + + // Get channel from argument + channel = stack.Arg1().NumericByRef().s4; + + adcDefinition = AdcPortPinConfig[channel]; + + // we should remove from the build the ADC options that aren't implemented + // plus we have to use the default to catch invalid ADC Ids + switch (adcDefinition.adcIndex) + { + +#if GECKO_USE_ADC0 + case 0: + adcDriver = ADC0; + adcClock = cmuClock_ADC0; + break; +#endif + +#if GECKO_USE_ADC1 + case 1: + adcDriver = ADC1; + adcClock = cmuClock_ADC1; + break; +#endif + + default: + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + // Enable ADC clock + CMU_ClockEnable(cmuClock_HFPER, true); + CMU_ClockEnable(adcClock, true); + + // Init to max ADC clock for Series 1 + adcInit.prescale = ADC_PrescaleCalc(ADC_FREQ, 0); + adcInit.timebase = ADC_TimebaseCalc(0); + + // start ADC + ADC_Init(adcDriver, &adcInit); + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_sys_dev_adc_native_System_Device_Adc_AdcController::NativeGetChannelCount___I4(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + // Return value to the managed application + stack.SetResult_I4(AdcChannelCount); + + NANOCLR_NOCLEANUP_NOLABEL(); +} + +HRESULT Library_sys_dev_adc_native_System_Device_Adc_AdcController::NativeGetMaxValue___I4(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + // Currently fixed at 12 bit so return 4095 = ((2^12) - 1) + stack.SetResult_I4(4095); + + NANOCLR_NOCLEANUP_NOLABEL(); +} + +HRESULT Library_sys_dev_adc_native_System_Device_Adc_AdcController::NativeGetMinValue___I4(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + stack.SetResult_I4(0); + + NANOCLR_NOCLEANUP_NOLABEL(); +} + +HRESULT Library_sys_dev_adc_native_System_Device_Adc_AdcController::NativeIsChannelModeSupported___BOOLEAN__I4( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + int mode = stack.Arg1().NumericByRef().s4; + + // Only support Single ended mode for now + stack.SetResult_Boolean((mode == (int)AdcChannelMode_SingleEnded)); + + NANOCLR_NOCLEANUP_NOLABEL(); +} + +HRESULT Library_sys_dev_adc_native_System_Device_Adc_AdcController::NativeGetResolutionInBits___I4( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + // Fixed at 12 bit + stack.SetResult_I4(12); + + NANOCLR_NOCLEANUP_NOLABEL(); +} + +HRESULT Library_sys_dev_adc_native_System_Device_Adc_AdcController::NativeInit___VOID(CLR_RT_StackFrame &stack) +{ + (void)stack; + + NANOCLR_HEADER(); + + // all required initialization for ADC is already handled in OpenChannel call + + NANOCLR_NOCLEANUP_NOLABEL(); +} diff --git a/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.Adc/sys_dev_adc_native_target.h b/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.Adc/sys_dev_adc_native_target.h new file mode 100644 index 0000000000..eb39c07f6d --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.Adc/sys_dev_adc_native_target.h @@ -0,0 +1,39 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#ifndef SYS_DEV_ADC_NATIVE_TARGET_H +#define SYS_DEV_ADC_NATIVE_TARGET_H + +#include +#include +#include +#include "em_cmu.h" + +#include + +// set missing defines +#ifndef GECKO_USE_ADC0 +#define GECKO_USE_ADC0 FALSE +#endif +#ifndef GECKO_USE_ADC1 +#define GECKO_USE_ADC1 FALSE +#endif +#ifndef GECKO_USE_ADC2 +#define GECKO_USE_ADC2 FALSE +#endif +#ifndef GECKO_USE_ADC3 +#define GECKO_USE_ADC3 FALSE +#endif + +typedef struct +{ + uint8_t adcIndex; + ADC_PosSel_TypeDef posSel; +} NF_PAL_ADC_PORT_PIN_CHANNEL; + +extern const NF_PAL_ADC_PORT_PIN_CHANNEL AdcPortPinConfig[]; +extern const int AdcChannelCount; + +#endif // SYS_DEV_ADC_NATIVE_TARGET_H diff --git a/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.Gpio/cpu_gpio.cpp b/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.Gpio/cpu_gpio.cpp new file mode 100644 index 0000000000..06aecd1ffc --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.Gpio/cpu_gpio.cpp @@ -0,0 +1,648 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include +#include "sys_dev_gpio_native_target.h" + +#define _GPIOINT_IF_EVEN_MASK ((_GPIO_IF_MASK)&0x55555555UL) +#define _GPIOINT_IF_ODD_MASK ((_GPIO_IF_MASK)&0xAAAAAAAAUL) +#define INTERRUPT_UNAVAILABLE (0xFF) + +#define GPIO_MAX_PIN \ + _GPIO_PORT_A_PIN_COUNT + _GPIO_PORT_B_PIN_COUNT + _GPIO_PORT_C_PIN_COUNT + _GPIO_PORT_D_PIN_COUNT + \ + _GPIO_PORT_E_PIN_COUNT + _GPIO_PORT_F_PIN_COUNT + _GPIO_PORT_G_PIN_COUNT + _GPIO_PORT_H_PIN_COUNT + \ + _GPIO_PORT_I_PIN_COUNT + _GPIO_PORT_J_PIN_COUNT + _GPIO_PORT_K_PIN_COUNT + +// Double linked list to hold the state of each Input pin +struct gpio_input_state : public HAL_DblLinkedNode +{ + // pin number + GPIO_PIN pinNumber; + // debounce timer for this pin + TX_TIMER debounceTimer; + // pointer to user ISR or null + GPIO_INTERRUPT_SERVICE_ROUTINE isrPtr; + // debounce milliseconds, NO debounce set to 0 + uint32_t debounceMs; + // Interrupt mode + uint8_t mode; + // Param to user ISR call + void *param; + // Expected state for debounce handler + bool expected; + // True if waiting for debounce timer to complete + bool waitingDebounce; +}; + +// Double Linked list for GPIO input status +static HAL_DblLinkedList gpioInputList; +// reserved - 1 bit per pin +static uint16_t pinReserved[GPIO_PORT_MAX]; + +// Array of user callbacks. One for each pin interrupt number. +static gpio_input_state *gpioCallbacks[32]; + +// this is an utility function to get a Gecko API port and pin from our "encoded" pin number +void GetIoLine(int16_t pinNumber, GPIO_Port_TypeDef *port, uint32_t *portPin) +{ + *port = GPIO_PORT(pinNumber); + *portPin = pinNumber % 16; +} + +bool IsValidGpioPin(GPIO_PIN pinNumber) +{ + return (pinNumber <= GPIO_MAX_PIN); +} + +// Register (or unregister) ISR for a pin +// send NULL in pinState to unregister callback +unsigned int CallbackRegisterExt(uint8_t pin, gpio_input_state *pinState) +{ + uint16_t intNo = INTERRUPT_UNAVAILABLE; + + TX_DISABLE + +#if defined(_GPIO_EXTIPINSELL_MASK) + uint32_t intToCheck; + uint32_t intGroupStart = (pin & 0xFFC); + uint32_t intsEnabled = GPIO_EnabledIntGet(); + + // loop through the interrupt group, starting + // from the pin number, and take + // the first available + for (uint8_t i = 0; i < 4; i++) + { + intToCheck = intGroupStart + ((pin + i) & 0x3); // modulo 4 + if (((intsEnabled >> intToCheck) & 0x1) == 0) + { + intNo = (unsigned int)intToCheck; + break; + } + } +#else + if (gpioCallbacks[pin] == NULL) + { + intNo = (unsigned int)pin; + } +#endif + + if (intNo != INTERRUPT_UNAVAILABLE) + { + gpioCallbacks[intNo] = pinState; + } + + TX_RESTORE + + return intNo; +} + +// Get pointer to gpio_input_state for GPIO pin +// return NULL if not found +gpio_input_state *GetGpioWithInterrupt(uint16_t gpioPin) +{ + gpio_input_state *ptr = gpioInputList.FirstNode(); + + while (ptr->Next() != NULL) + { + if (GPIO_PIN(ptr->pinNumber) == gpioPin) + { + return ptr; + } + + ptr = ptr->Next(); + } + + return NULL; +} + +static void DebounceTimerCallback(ULONG pinState) +{ + gpio_input_state *pState = (gpio_input_state *)pinState; + + GPIO_Port_TypeDef port; + uint32_t portPin; + GetIoLine(pState->pinNumber, &port, &portPin); + + // get current pin state + bool actual = GPIO_PinInGet(port, portPin); + + if (actual == pState->expected) + { + // call ISR + pState->isrPtr(pState->pinNumber, actual, pState->param); + } + + // reset flag + pState->waitingDebounce = false; +} + +static void GpioEventCallback(uint32_t intFlags) +{ + uint32_t irqIdx; + gpio_input_state *pGpio; + + NATIVE_INTERRUPT_START + + TX_DISABLE + + // check for all flags set in IF register + while (intFlags != 0U) + { + irqIdx = SL_CTZ(intFlags); + + /* clear flag*/ + intFlags &= ~(1UL << irqIdx); + + pGpio = gpioCallbacks[irqIdx]; + + if (pGpio != NULL) + { + if (pGpio->waitingDebounce) + { + // Ignore any pin changes during debounce + continue; + } + else + { + // check if there is a debounce time set + if (pGpio->debounceMs > 0) + { + // stop timer, just in case + tx_timer_deactivate(&pGpio->debounceTimer); + + // Set flag we are waiting for debounce on this pin + pGpio->waitingDebounce = true; + + // expecting same state as current one + pGpio->expected = CPU_GPIO_GetPinState(pGpio->pinNumber); + + // setup timer + tx_timer_change(&pGpio->debounceTimer, TX_TICKS_PER_MILLISEC(pGpio->debounceMs), 0); + tx_timer_activate(&pGpio->debounceTimer); + } + else + { + pGpio->isrPtr(pGpio->pinNumber, CPU_GPIO_GetPinState(pGpio->pinNumber), pGpio->param); + } + } + } + } + + TX_RESTORE + + NATIVE_INTERRUPT_END +} + +// Get pointer to gpio_input_state for GPIO pin +// return NULL if not found +gpio_input_state *GetInputState(GPIO_PIN pinNumber) +{ + gpio_input_state *ptr = gpioInputList.FirstNode(); + + while (ptr->Next() != NULL) + { + if (ptr->pinNumber == pinNumber) + { + return ptr; + } + + ptr = ptr->Next(); + } + + return NULL; +} + +// Allocate a new gpio_input_state and add to end of list +// if already exist then just return current ptr +gpio_input_state *AllocateGpioInputState(GPIO_PIN pinNumber) +{ + gpio_input_state *ptr = GetInputState(pinNumber); + + if (ptr == NULL) + { + ptr = (gpio_input_state *)platform_malloc(sizeof(gpio_input_state)); + + // sanity check + if (ptr != NULL) + { + memset(ptr, 0, sizeof(gpio_input_state)); + ptr->pinNumber = pinNumber; + + tx_timer_create( + &ptr->debounceTimer, + (char *)"GPIO debounce timer", + DebounceTimerCallback, + (ULONG)ptr, + 1, + 0, + TX_NO_ACTIVATE); + + gpioInputList.LinkAtBack(ptr); + } + } + + return ptr; +} + +void UnlinkInputState(gpio_input_state *pState) +{ + tx_timer_delete(&pState->debounceTimer); + + GPIO_Port_TypeDef port; + uint32_t portPin; + GetIoLine(pState->pinNumber, &port, &portPin); + + // disable the EXT interrupt channel + // it's OK to do always this, no matter if it's enabled or not + CallbackRegisterExt(portPin, NULL); + + pState->Unlink(); + + platform_free(pState); +} + +// Delete gpio_input_state from List and tidy up ( Timer & ISR handler ) +void DeleteInputState(GPIO_PIN pinNumber) +{ + gpio_input_state *pState = GetInputState(pinNumber); + + if (pState) + { + UnlinkInputState(pState); + } +} + +bool CPU_GPIO_Initialize() +{ + // Initialise Double linked list for input pin states + gpioInputList.Initialize(); + + // Make sure all pins are not reserved + memset(pinReserved, 0, sizeof(pinReserved)); + + // "free" all GPIO interrupts + memset(gpioCallbacks, 0x0, sizeof(gpioCallbacks)); + + // enable the interrupt handler for all GPIOs + if (CORE_NvicIRQDisabled(GPIO_ODD_IRQn)) + { + NVIC_ClearPendingIRQ(GPIO_ODD_IRQn); + NVIC_EnableIRQ(GPIO_ODD_IRQn); + } + if (CORE_NvicIRQDisabled(GPIO_EVEN_IRQn)) + { + NVIC_ClearPendingIRQ(GPIO_EVEN_IRQn); + NVIC_EnableIRQ(GPIO_EVEN_IRQn); + } + + return true; +} + +bool CPU_GPIO_Uninitialize() +{ + NANOCLR_FOREACH_NODE(gpio_input_state, pGpio, gpioInputList) + { + UnlinkInputState(pGpio); + } + NANOCLR_FOREACH_NODE_END(); + + return true; +} + +// Set/reset reserved state of pin +bool CPU_GPIO_ReservePin(GPIO_PIN pinNumber, bool fReserve) +{ + // Check if valid pin number + if (!IsValidGpioPin(pinNumber)) + { + return false; + } + + int port = pinNumber >> 4, bit = 1 << (pinNumber & 0x0F); + bool ret = true; + GLOBAL_LOCK(); + + if (fReserve) + { + if (pinReserved[port] & bit) + { + // already reserved + ret = false; + } + else + { + pinReserved[port] |= bit; + } + } + else + { + pinReserved[port] &= ~bit; + } + + GLOBAL_UNLOCK(); + return ret; +} + +// Return if Pin is reserved +bool CPU_GPIO_PinIsBusy(GPIO_PIN pinNumber) +{ + // Check if valid pin number + if (!IsValidGpioPin(pinNumber)) + { + return false; + } + + int port = pinNumber >> 4, sh = pinNumber & 0x0F; + + return (pinReserved[port] >> sh) & 1; +} + +// Return maximum number of pins +int32_t CPU_GPIO_GetPinCount() +{ + return GPIO_MAX_PIN; +} + +// Get current state of pin +GpioPinValue CPU_GPIO_GetPinState(GPIO_PIN pin) +{ + GPIO_Port_TypeDef port; + uint32_t portPin; + GetIoLine(pin, &port, &portPin); + + return (GpioPinValue)GPIO_PinInGet(port, portPin); +} + +// Set Pin state +void CPU_GPIO_SetPinState(GPIO_PIN pin, GpioPinValue pinState) +{ + GPIO_Port_TypeDef port; + uint32_t portPin; + GetIoLine(pin, &port, &portPin); + + if (pinState == GpioPinValue_High) + { + GPIO_PinOutSet(port, portPin); + } + else + { + GPIO_PinOutClear(port, portPin); + } +} + +void CPU_GPIO_TogglePinState(GPIO_PIN pin) +{ + GPIO_Port_TypeDef port; + uint32_t portPin; + GetIoLine(pin, &port, &portPin); + + GPIO_PinOutToggle(port, portPin); +} + +bool CPU_GPIO_EnableInputPin( + GPIO_PIN pinNumber, + uint32_t debounceTimeMilliseconds, + GPIO_INTERRUPT_SERVICE_ROUTINE pinISR, + void *isrParam, + GPIO_INT_EDGE intEdge, + PinMode driveMode) +{ + gpio_input_state *pState; + + // Check Input drive mode + if (driveMode >= (int)PinMode_Output) + { + return false; + } + + // Set as Input GPIO_INT_EDGE intEdge, GPIO_RESISTOR ResistorState + if (!CPU_GPIO_SetDriveMode(pinNumber, driveMode)) + { + return false; + } + + pState = AllocateGpioInputState(pinNumber); + + GPIO_Port_TypeDef port; + uint32_t portPin; + int interruptId; + GetIoLine(pinNumber, &port, &portPin); + + // Link ISR ptr supplied and not already set up + // CPU_GPIO_EnableInputPin could be called a 2nd time with changed parameters + if (pinISR != NULL && (pState->isrPtr == NULL)) + { + // register nanoFramework callback and store associated interrupt ID + interruptId = CallbackRegisterExt(portPin, pState); + + // there are callbacks registered and... + // the drive mode is input so need to setup the interrupt + // need to use the interrupt ID to setup the interrupt + GPIO_ExtIntConfig(port, portPin, interruptId, 1, 1, true); + + // store parameters & configs + pState->isrPtr = pinISR; + pState->mode = intEdge; + pState->param = (void *)isrParam; + pState->debounceMs = (uint32_t)(debounceTimeMilliseconds); + + switch (intEdge) + { + case GPIO_INT_EDGE_LOW: + case GPIO_INT_LEVEL_LOW: + pState->expected = 1; + break; + + case GPIO_INT_EDGE_HIGH: + case GPIO_INT_LEVEL_HIGH: + pState->expected = 0; + break; + + case GPIO_INT_EDGE_BOTH: + pState->expected = !CPU_GPIO_GetPinState(pinNumber); // expected NOT current state + break; + + default: + break; + } + } + else if (pinISR == NULL && (pState->isrPtr != NULL)) + { + // there is no managed handler setup anymore + + // disable the EXT interrupt channel + // it's OK to do always this, no matter if it's enabled or not + CallbackRegisterExt(portPin, NULL); + + // clear parameters & configs + pState->isrPtr = NULL; + pState->mode = GPIO_INT_NONE; + pState->param = NULL; + pState->debounceMs = 0; + } + + return true; +} + +// Enable an output pin +// +// pinNumber - Gpio pin number +// InitialState - Initial state of pin +// driveMode - Drive mode and resistors +// return - True if successful, false invalid pin, pin not output, invalid drive mode for output +// +bool CPU_GPIO_EnableOutputPin(GPIO_PIN pinNumber, GpioPinValue InitialState, PinMode driveMode) +{ + // check not an output drive mode + if (driveMode < (int)PinMode_Output) + { + return false; + } + + // If this is currently an input pin then clean up + DeleteInputState(pinNumber); + + if (CPU_GPIO_SetDriveMode(pinNumber, driveMode) == false) + { + return false; + } + + CPU_GPIO_SetPinState(pinNumber, InitialState); + + return true; +} + +void CPU_GPIO_DisablePin(GPIO_PIN pinNumber, PinMode driveMode, uint32_t alternateFunction) +{ + DeleteInputState(pinNumber); + + GLOBAL_LOCK(); + + CPU_GPIO_SetDriveMode(pinNumber, driveMode); + + GPIO_Port_TypeDef port; + uint32_t portPin; + GetIoLine(pinNumber, &port, &portPin); + + GPIO_PinModeSet(port, portPin, (GPIO_Mode_TypeDef)alternateFunction, 0); + + GLOBAL_UNLOCK(); + + CPU_GPIO_ReservePin(pinNumber, false); +} + +// Validate pin and set drive mode +// return true if ok +bool CPU_GPIO_SetDriveMode(GPIO_PIN pinNumber, PinMode driveMode) +{ + GPIO_Port_TypeDef port; + uint32_t portPin; + GetIoLine(pinNumber, &port, &portPin); + + switch (driveMode) + { + case PinMode_Input: + GPIO_PinModeSet(port, portPin, gpioModeInput, 0); + break; + + case PinMode_InputPullDown: + GPIO_PinModeSet(port, portPin, gpioModeInputPull, 0); + break; + + case PinMode_InputPullUp: + GPIO_PinModeSet(port, portPin, gpioModeInputPull, 1); + break; + + case PinMode_Output: + GPIO_PinModeSet(port, portPin, gpioModePushPull, 0); + + break; + + case PinMode_OutputOpenDrain: + GPIO_PinModeSet(port, portPin, gpioModeWiredAnd, 1); + break; + + default: + // all other modes are NOT supported + return false; + } + + return true; +} + +bool CPU_GPIO_DriveModeSupported(GPIO_PIN pinNumber, PinMode driveMode) +{ + (void)pinNumber; + + bool driveModeSupported = false; + + // check if the requested drive mode is support by ChibiOS config + if ((driveMode == PinMode_Input) || (driveMode == PinMode_InputPullDown) || (driveMode == PinMode_InputPullUp) || + (driveMode == PinMode_Output) || (driveMode == PinMode_OutputOpenDrain)) + { + driveModeSupported = true; + } + + return driveModeSupported; +} + +uint32_t CPU_GPIO_GetPinDebounce(GPIO_PIN pinNumber) +{ + gpio_input_state *ptr = GetInputState(pinNumber); + + if (ptr) + { + return ptr->debounceMs; + } + + return 0; +} + +bool CPU_GPIO_SetPinDebounce(GPIO_PIN pinNumber, uint32_t debounceTimeMilliseconds) +{ + gpio_input_state *ptr = GetInputState(pinNumber); + + if (ptr) + { + ptr->debounceMs = debounceTimeMilliseconds; + return true; + } + + return false; +} + +void GPIO_EVEN_IRQHandler(void) +{ + NATIVE_INTERRUPT_START + + uint32_t intFlags; + + // Get all even interrupts + intFlags = GPIO_IntGetEnabled() & _GPIOINT_IF_EVEN_MASK; + + // Clean only even interrupts + GPIO_IntClear(intFlags); + + GpioEventCallback(intFlags); + + NATIVE_INTERRUPT_END +} + +void GPIO_ODD_IRQHandler(void) +{ + NATIVE_INTERRUPT_START + + uint32_t intFlags; + + // Get all odd interrupts + intFlags = GPIO_IntGetEnabled() & _GPIOINT_IF_ODD_MASK; + + // Clean only odd interrupts + GPIO_IntClear(intFlags); + + GpioEventCallback(intFlags); + + NATIVE_INTERRUPT_END +} diff --git a/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.Gpio/sys_dev_gpio_native_target.h b/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.Gpio/sys_dev_gpio_native_target.h new file mode 100644 index 0000000000..58299b78e1 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.Gpio/sys_dev_gpio_native_target.h @@ -0,0 +1,17 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#ifndef SYS_DEV_GPIO_NATIVE_TARGET_H +#define SYS_DEV_GPIO_NATIVE_TARGET_H + +#include +#include + +#include +#include + +#include + +#endif // SYS_DEV_GPIO_NATIVE_TARGET_H diff --git a/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.I2c/nano_sl_i2cspm.c b/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.I2c/nano_sl_i2cspm.c new file mode 100644 index 0000000000..65a575de4d --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.I2c/nano_sl_i2cspm.c @@ -0,0 +1,158 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Portions Copyright 2020 Silicon Laboratories Inc. www.silabs.com +// See LICENSE file in the project root for full license information. +// + +#include +#include "em_cmu.h" +#include "em_gpio.h" +#include "sl_assert.h" +#include "sl_i2cspm.h" +#include "sl_udelay.h" + +#include + +/* transfer timeout (how many polls) */ +#ifndef I2CSPM_TRANSFER_TIMEOUT +#define I2CSPM_TRANSFER_TIMEOUT 300 +#endif + +/* SCL hold time (in initialization function) in microseconds */ +#ifndef SL_I2CSPM_SCL_HOLD_TIME_US +#define SL_I2CSPM_SCL_HOLD_TIME_US 100 +#endif + +/******************************************************************************* + * Initalize I2C peripheral + ******************************************************************************/ +void I2CSPM_Init(I2CSPM_Init_TypeDef *init) +{ + int i; + CMU_Clock_TypeDef i2cClock; + I2C_Init_TypeDef i2cInit; + + EFM_ASSERT(init != NULL); + +#if defined(_CMU_HFPERCLKEN0_MASK) + CMU_ClockEnable(cmuClock_HFPER, true); +#endif + + /* Select I2C peripheral clock */ + if (false) + { +#if defined(I2C0) + } + else if (init->port == I2C0) + { + i2cClock = cmuClock_I2C0; +#endif +#if defined(I2C1) + } + else if (init->port == I2C1) + { + i2cClock = cmuClock_I2C1; +#endif +#if defined(I2C2) + } + else if (init->port == I2C2) + { + i2cClock = cmuClock_I2C2; +#endif + } + else + { + /* I2C clock is not defined */ + EFM_ASSERT(false); + return; + } + CMU_ClockEnable(i2cClock, true); + + /* Output value must be set to 1 to not drive lines low. Set + SCL first, to ensure it is high before changing SDA. */ + GPIO_PinModeSet(init->sclPort, init->sclPin, gpioModeWiredAndPullUp, 1); + GPIO_PinModeSet(init->sdaPort, init->sdaPin, gpioModeWiredAndPullUp, 1); + + /* In some situations, after a reset during an I2C transfer, the slave + device may be left in an unknown state. Send 9 clock pulses to + set slave in a defined state. */ + for (i = 0; i < 9; i++) + { + GPIO_PinOutClear(init->sclPort, init->sclPin); + sl_udelay_wait(SL_I2CSPM_SCL_HOLD_TIME_US); + GPIO_PinOutSet(init->sclPort, init->sclPin); + sl_udelay_wait(SL_I2CSPM_SCL_HOLD_TIME_US); + } + + /* Enable pins and set location */ +#if defined(_I2C_ROUTEPEN_MASK) + init->port->ROUTEPEN = I2C_ROUTEPEN_SDAPEN | I2C_ROUTEPEN_SCLPEN; + init->port->ROUTELOC0 = + (uint32_t)((init->portLocationSda << _I2C_ROUTELOC0_SDALOC_SHIFT) | (init->portLocationScl << _I2C_ROUTELOC0_SCLLOC_SHIFT)); +#elif defined(_I2C_ROUTE_MASK) + init->port->ROUTE = I2C_ROUTE_SDAPEN | I2C_ROUTE_SCLPEN | (init->portLocation << _I2C_ROUTE_LOCATION_SHIFT); +#else +#if defined(I2C0) + if (init->port == I2C0) + { + GPIO->I2CROUTE[0].ROUTEEN = GPIO_I2C_ROUTEEN_SDAPEN | GPIO_I2C_ROUTEEN_SCLPEN; + GPIO->I2CROUTE[0].SCLROUTE = + (uint32_t)((init->sclPin << _GPIO_I2C_SCLROUTE_PIN_SHIFT) | (init->sclPort << _GPIO_I2C_SCLROUTE_PORT_SHIFT)); + GPIO->I2CROUTE[0].SDAROUTE = + (uint32_t)((init->sdaPin << _GPIO_I2C_SDAROUTE_PIN_SHIFT) | (init->sdaPort << _GPIO_I2C_SDAROUTE_PORT_SHIFT)); + } +#endif +#if defined(I2C1) + if (init->port == I2C1) + { + GPIO->I2CROUTE[1].ROUTEEN = GPIO_I2C_ROUTEEN_SDAPEN | GPIO_I2C_ROUTEEN_SCLPEN; + GPIO->I2CROUTE[1].SCLROUTE = + (uint32_t)((init->sclPin << _GPIO_I2C_SCLROUTE_PIN_SHIFT) | (init->sclPort << _GPIO_I2C_SCLROUTE_PORT_SHIFT)); + GPIO->I2CROUTE[1].SDAROUTE = + (uint32_t)((init->sdaPin << _GPIO_I2C_SDAROUTE_PIN_SHIFT) | (init->sdaPort << _GPIO_I2C_SDAROUTE_PORT_SHIFT)); + } +#endif +#if defined(I2C2) + if (init->port == I2C2) + { + GPIO->I2CROUTE[2].ROUTEEN = GPIO_I2C_ROUTEEN_SDAPEN | GPIO_I2C_ROUTEEN_SCLPEN; + GPIO->I2CROUTE[2].SCLROUTE = + (uint32_t)((init->sclPin << _GPIO_I2C_SCLROUTE_PIN_SHIFT) | (init->sclPort << _GPIO_I2C_SCLROUTE_PORT_SHIFT)); + GPIO->I2CROUTE[2].SDAROUTE = + (uint32_t)((init->sdaPin << _GPIO_I2C_SDAROUTE_PIN_SHIFT) | (init->sdaPort << _GPIO_I2C_SDAROUTE_PORT_SHIFT)); + } +#endif +#endif + + /* Set emlib init parameters */ + i2cInit.enable = true; + i2cInit.master = true; /* master mode only */ + i2cInit.freq = init->i2cMaxFreq; + i2cInit.refFreq = init->i2cRefFreq; + i2cInit.clhr = init->i2cClhr; + + I2C_Init(init->port, &i2cInit); +} + +/******************************************************************************* + * Perform I2C transfer + ******************************************************************************/ +I2C_TransferReturn_TypeDef I2CSPM_Transfer(I2C_TypeDef *i2c, I2C_TransferSeq_TypeDef *seq) +{ + I2C_TransferReturn_TypeDef ret; + uint32_t timeout = I2CSPM_TRANSFER_TIMEOUT; + + // Do a polled transfer + ret = I2C_TransferInit(i2c, seq); + + while (ret == i2cTransferInProgress && timeout--) + { + + ret = I2C_Transfer(i2c); + + // allow other tasks to run + tx_thread_sleep(10); + } + + return ret; +} diff --git a/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.I2c/sys_dev_i2c_native_System_Device_I2c_I2cDevice.cpp b/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.I2c/sys_dev_i2c_native_System_Device_I2c_I2cDevice.cpp new file mode 100644 index 0000000000..db71c47a14 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.I2c/sys_dev_i2c_native_System_Device_I2c_I2cDevice.cpp @@ -0,0 +1,731 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include "sys_dev_i2c_native_target.h" + +typedef Library_sys_dev_i2c_native_System_Device_I2c_I2cConnectionSettings I2cConnectionSettings; +typedef Library_sys_dev_i2c_native_System_Device_I2c_I2cTransferResult I2cTransferResult; +typedef Library_corlib_native_System_SpanByte SpanByte; + +//////////////////////////////////////////// +// declaration of the the I2C PAL structs // +//////////////////////////////////////////// +#if defined(I2C0) && (GECKO_USE_I2C0 == TRUE) +NF_PAL_I2C I2C0_PAL; +#endif +#if defined(I2C1) && (GECKO_USE_I2C1 == TRUE) +NF_PAL_I2C I2C1_PAL; +#endif +#if defined(I2C2) && (GECKO_USE_I2C2 == TRUE) +NF_PAL_I2C I2C2_PAL; +#endif + +#if defined(I2C0) && (GECKO_USE_I2C0 == TRUE) +uint8_t I2C0_DeviceCounter = 0; +#endif +#if defined(I2C1) && (GECKO_USE_I2C1 == TRUE) +uint8_t I2C1_DeviceCounter = 0; +#endif +#if defined(I2C2) && (GECKO_USE_I2C2 == TRUE) +uint8_t I2C2_DeviceCounter = 0; +#endif + +void GetI2cConfig(CLR_RT_HeapBlock *managedConfig, I2CSPM_Init_TypeDef *llConfig) +{ + I2cBusSpeed busSpeed = (I2cBusSpeed)managedConfig[I2cConnectionSettings::FIELD___busSpeed].NumericByRef().s4; + + if (busSpeed == I2cBusSpeed::I2cBusSpeed_FastModePlus) + { + llConfig->i2cMaxFreq = I2C_FREQ_FASTPLUS_MAX; + llConfig->i2cClhr = i2cClockHLRStandard; + } + else if (busSpeed == I2cBusSpeed::I2cBusSpeed_FastMode) + { + llConfig->i2cMaxFreq = I2C_FREQ_FAST_MAX; + llConfig->i2cClhr = i2cClockHLRAsymetric; + } + else + { + // Default is standard mode + llConfig->i2cMaxFreq = I2C_FREQ_STANDARD_MAX; + llConfig->i2cClhr = i2cClockHLRStandard; + } +} + +// estimate the time required to perform the I2C transaction +bool IsLongRunningOperation( + uint16_t writeSize, + uint16_t readSize, + float byteTime, + uint32_t &estimatedDurationMiliseconds) +{ + // add an extra byte to account for the address + estimatedDurationMiliseconds = byteTime * (writeSize + readSize + 1); + + if (estimatedDurationMiliseconds > CLR_RT_Thread::c_TimeQuantum_Milliseconds) + { + // total operation time will exceed thread quantum, so this is a long running operation + return true; + } + else + { + return false; + } +} + +// ThreadX I2C Working thread +static void I2CWorkingThread_entry(uint32_t arg) +{ + NF_PAL_I2C *palI2c = (NF_PAL_I2C *)arg; + I2C_TransferSeq_TypeDef i2cTransfer; + + if (palI2c->ReadSize != 0 && palI2c->WriteSize != 0) + { + // this is a Write/Read transaction + i2cTransfer.flags = I2C_FLAG_WRITE_READ; + + i2cTransfer.buf[0].data = palI2c->WriteBuffer; + i2cTransfer.buf[0].len = palI2c->WriteSize; + i2cTransfer.buf[1].data = palI2c->ReadBuffer; + i2cTransfer.buf[1].len = palI2c->ReadSize; + + // Perform the transfer and return status from the transfer + palI2c->TransactionResult = I2CSPM_Transfer(palI2c->Configuration->port, &i2cTransfer); + } + else + { + if (palI2c->ReadSize == 0) + { + // this is Write only transaction + i2cTransfer.flags = I2C_FLAG_WRITE; + + i2cTransfer.buf[0].data = palI2c->WriteBuffer; + i2cTransfer.buf[0].len = palI2c->WriteSize; + + // Perform the transfer and return status from the transfer + palI2c->TransactionResult = I2CSPM_Transfer(palI2c->Configuration->port, &i2cTransfer); + } + else + { + // this is a Read only transaction + i2cTransfer.flags = I2C_FLAG_READ; + i2cTransfer.buf[0].data = palI2c->ReadBuffer; + i2cTransfer.buf[0].len = palI2c->ReadSize; + + // Perform the transfer and return status from the transfer + palI2c->TransactionResult = I2CSPM_Transfer(palI2c->Configuration->port, &i2cTransfer); + } + } + + // fire event for I2C transaction complete + Events_Set(SYSTEM_EVENT_FLAG_I2C_MASTER); + + // terminate this thread + tx_thread_terminate(palI2c->WorkingThread); +} + +HRESULT Library_sys_dev_i2c_native_System_Device_I2c_I2cDevice::NativeInit___VOID(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + NF_PAL_I2C *palI2c = NULL; + CLR_RT_HeapBlock *connectionSettings; + uint8_t busIndex; + I2CSPM_Init_TypeDef i2cInit = { + NULL, + 0, + 0, + 0, + 0, +#if defined(_SILICON_LABS_32B_SERIES_0) + 0, +#elif defined(_SILICON_LABS_32B_SERIES_1) + 0, + 0, +#endif + 0, + I2C_FREQ_STANDARD_MAX, + i2cClockHLRStandard, + }; + + // get a pointer to the managed object instance and check that it's not NULL + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + + // get a pointer to the managed I2C connectionSettings object instance + connectionSettings = pThis[FIELD___connectionSettings].Dereference(); + + // get bus index + busIndex = (uint8_t)connectionSettings[I2cConnectionSettings::FIELD___busId].NumericByRef().s4; + + // config GPIO pins used by the I2C peripheral + // init the PAL struct for this I2C bus and assign the respective driver + // all this occurs if not already done + // why do we need to check if this is already done? because several I2cDevice objects can be created associated to + // the same bus just using different addresses + switch (busIndex) + { + + //////////////////////////////////// + // Gecko I2C bus index is 0 based // + //////////////////////////////////// + +#if defined(I2C0) && (GECKO_USE_I2C0 == TRUE) + case 1: + if (I2C0_PAL.Configuration == NULL) + { + I2C0_PAL.Configuration = (I2CSPM_Init_TypeDef *)platform_malloc(sizeof(I2CSPM_Init_TypeDef)); + + if (I2C0_PAL.Configuration == NULL) + { + NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_MEMORY); + } + + // copy init struct + memcpy(I2C0_PAL.Configuration, &i2cInit, sizeof(I2CSPM_Init_TypeDef)); + + ConfigPins_I2C0(); + + I2C0_PAL.Configuration->port = I2C0; + palI2c = &I2C0_PAL; + + // increase device counter + I2C0_DeviceCounter++; + } + break; +#endif + +#if defined(I2C1) && (GECKO_USE_I2C1 == TRUE) + case 2: + if (I2C1_PAL.Configuration == NULL) + { + I2C1_PAL.Configuration = (I2CSPM_Init_TypeDef *)platform_malloc(sizeof(I2CSPM_Init_TypeDef)); + + if (I2C1_PAL.Configuration == NULL) + { + NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_MEMORY); + } + + // copy init struct + memcpy(I2C1_PAL.Configuration, &i2cInit, sizeof(I2CSPM_Init_TypeDef)); + + ConfigPins_I2C1(); + + I2C1_PAL.Configuration->port = I2C1; + palI2c = &I2C1_PAL; + + // increase device counter + I2C1_DeviceCounter++; + } + break; +#endif + +#if defined(I2C2) && (GECKO_USE_I2C2 == TRUE) + case 3: + if (I2C2_PAL.Configuration == NULL) + { + I2C2_PAL.Configuration = (I2CSPM_Init_TypeDef *)platform_malloc(sizeof(I2CSPM_Init_TypeDef)); + + if (I2C2_PAL.Configuration == NULL) + { + NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_MEMORY); + } + + // copy init struct + memcpy(I2C2_PAL.Configuration, &i2cInit, sizeof(I2CSPM_Init_TypeDef)); + + ConfigPins_I2C2(); + + I2C2_PAL.Configuration->port = I2C2; + palI2c = &I2C2_PAL; + + // increase device counter + I2C2_DeviceCounter++; + } + + break; +#endif + + default: + // this I2C bus is not valid + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + break; + } + + // Get a general low-level I2C configuration, depending on user's managed parameters + GetI2cConfig(connectionSettings, palI2c->Configuration); + + I2CSPM_Init(palI2c->Configuration); + + // compute rough estimate on the time to tx/rx a byte (in milliseconds) + if ((I2cBusSpeed)connectionSettings[I2cConnectionSettings::FIELD___busSpeed].NumericByRef().s4 == + I2cBusSpeed_StandardMode) + { + // 100kbit/s: this is roughly 0.10ms per byte, give or take + palI2c->ByteTime = 0.1; + } + else + { + // 400kbit/s: this is roughly 0.02ms per byte, give or take + palI2c->ByteTime = 0.02; + } + + // clear pointer to working thread + palI2c->WorkingThread = NULL; + palI2c->WorkingThreadStack = NULL; + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_sys_dev_i2c_native_System_Device_I2c_I2cDevice::NativeDispose___VOID(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + uint8_t busIndex; + NF_PAL_I2C *palI2c = NULL; + + CLR_RT_HeapBlock *connectionSettings; + + // get a pointer to the managed object instance and check that it's not NULL + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + + // get a pointer to the managed I2C connectionSettings object instance + connectionSettings = pThis[FIELD___connectionSettings].Dereference(); + + // get bus index + busIndex = (uint8_t)connectionSettings[I2cConnectionSettings::FIELD___busId].NumericByRef().s4; + + // get the driver for the I2C bus + // Gecko I2C bus index is 0 based + switch (busIndex) + { + //////////////////////////////////// + // Gecko I2C bus index is 0 based // + //////////////////////////////////// + +#if defined(I2C0) && (GECKO_USE_I2C0 == TRUE) + case 1: + palI2c = &I2C0_PAL; + + // remove device + I2C0_DeviceCounter--; + + if (I2C0_DeviceCounter == 0) + { + // no more devices on the bus + + // free memory + platform_free(I2C0_PAL.Configuration); + + // clears configuration + I2C0_PAL.Configuration = NULL; + } + + break; +#endif + +#if defined(I2C1) && (GECKO_USE_I2C1 == TRUE) + case 2: + palI2c = &I2C1_PAL; + + // remove device + I2C1_DeviceCounter--; + + if (I2C1_DeviceCounter == 0) + { + // no more devices on the bus + + // free memory + platform_free(I2C1_PAL.Configuration); + + // clears configuration + I2C1_PAL.Configuration = NULL; + } + + break; +#endif + +#if defined(I2C2) && (GECKO_USE_I2C2 == TRUE) + case 3: + palI2c = &I2C2_PAL; + + // remove device + I2C2_DeviceCounter--; + + if (I2C2_DeviceCounter == 0) + { + // no more devices on the bus + + // free memory + platform_free(I2C2_PAL.Configuration); + + // clears configuration + I2C2_PAL.Configuration = NULL; + } + + break; +#endif + + default: + // the requested I2C bus is not valid + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + break; + } + + // stop working thread, if it's running + if (palI2c->WorkingThread != NULL) + { + // delete thread + tx_thread_delete(palI2c->WorkingThread); + + // free stack memory + platform_free(palI2c->WorkingThreadStack); + + // clear pointers + palI2c->WorkingThread = NULL; + palI2c->WorkingThreadStack = NULL; + } + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_sys_dev_i2c_native_System_Device_I2c_I2cDevice:: + NativeTransmit___SystemDeviceI2cI2cTransferResult__SystemSpanByte__SystemSpanByte(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + { + uint8_t busIndex; + NF_PAL_I2C *palI2c = NULL; + bool isLongRunningOperation = false; + + CLR_RT_HeapBlock hbTimeout; + CLR_INT64 *timeout; + bool eventResult = true; + uint32_t estimatedDurationMiliseconds; + + CLR_RT_HeapBlock *result; + CLR_RT_HeapBlock *writeSpanByte; + CLR_RT_HeapBlock *readSpanByte; + CLR_RT_HeapBlock_Array *writeBuffer = NULL; + CLR_RT_HeapBlock_Array *readBuffer = NULL; + int readOffset = 0; + int writeOffset = 0; + I2C_TransferSeq_TypeDef i2cTransfer; + I2C_TransferReturn_TypeDef transactionResult = i2cTransferInProgress; + + // get a pointer to the managed object instance and check that it's not NULL + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + + // get pointer to connection settings field + CLR_RT_HeapBlock *connectionSettings = pThis[FIELD___connectionSettings].Dereference(); + + // get bus index + busIndex = (uint8_t)connectionSettings[I2cConnectionSettings::FIELD___busId].NumericByRef().s4; + + // get the driver for the I2C bus + switch (busIndex) + { + //////////////////////////////////// + // Gecko I2C bus index is 0 based // + //////////////////////////////////// + +#if defined(I2C0) && (GECKO_USE_I2C0 == TRUE) + case 1: + palI2c = &I2C0_PAL; + break; +#endif + +#if defined(I2C1) && (GECKO_USE_I2C1 == TRUE) + case 2: + palI2c = &I2C1_PAL; + break; +#endif + +#if defined(I2C2) && (GECKO_USE_I2C2 == TRUE) + case 3: + palI2c = &I2C2_PAL; + break; +#endif + + default: + // the requested I2C bus is not valid + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + break; + } + + // dereference the write and read SpanByte from the arguments + writeSpanByte = stack.Arg1().Dereference(); + + if (writeSpanByte != NULL) + { + // get buffer + writeBuffer = writeSpanByte[SpanByte::FIELD___array].DereferenceArray(); + + if (writeBuffer != NULL) + { + // Get the write offset, only the elements defined by the span must be written, not the whole array + writeOffset = writeSpanByte[SpanByte::FIELD___start].NumericByRef().s4; + + // use the span length as write size, only the elements defined by the span must be written + palI2c->WriteSize = writeSpanByte[SpanByte::FIELD___length].NumericByRef().s4; + } + } + + if (writeBuffer == NULL) + { + // nothing to write, have to zero this + palI2c->WriteSize = 0; + } + + readSpanByte = stack.Arg2().Dereference(); + + if (readSpanByte != NULL) + { + // get buffer + readBuffer = readSpanByte[SpanByte::FIELD___array].DereferenceArray(); + + if (readBuffer != NULL) + { + // Get the read offset, only the elements defined by the span must be read, not the whole array + readOffset = readSpanByte[SpanByte::FIELD___start].NumericByRef().s4; + + // use the span length as read size, only the elements defined by the span must be read + palI2c->ReadSize = readSpanByte[SpanByte::FIELD___length].NumericByRef().s4; + } + } + + if (readBuffer == NULL) + { + // nothing to read, have to zero this + palI2c->ReadSize = 0; + } + + // check if this is a long running operation + isLongRunningOperation = IsLongRunningOperation( + palI2c->WriteSize, + palI2c->ReadSize, + palI2c->ByteTime, + (uint32_t &)estimatedDurationMiliseconds); + + if (isLongRunningOperation) + { + // if this is a long running operation, set a timeout equal to the estimated transaction duration in + // milliseconds this value has to be in ticks to be properly loaded by SetupTimeoutFromTicks() below + hbTimeout.SetInteger((CLR_INT64)estimatedDurationMiliseconds * TIME_CONVERSION__TO_MILLISECONDS); + + NANOCLR_CHECK_HRESULT(stack.SetupTimeoutFromTicks(hbTimeout, timeout)); + + // protect the buffers from GC so DMA can find them where they are supposed to be + CLR_RT_ProtectFromGC gcWriteBuffer(*writeBuffer); + CLR_RT_ProtectFromGC gcReadBuffer(*readBuffer); + } + + // this is going to be used to check for the right event in case of simultaneous I2C transaction + if (!isLongRunningOperation || stack.m_customState == 1) + { + + // get slave address from connection settings field + i2cTransfer.addr = + (uint16_t)connectionSettings[I2cConnectionSettings::FIELD___deviceAddress].NumericByRef().s4 << 1; + + if (writeBuffer != NULL) + { + // grab the pointer to the array by starting and the offset specified in the span + palI2c->WriteBuffer = (uint8_t *)writeBuffer->GetElement(writeOffset); + } + + if (readBuffer != NULL) + { + // grab the pointer to the array by starting and the offset specified in the span + palI2c->ReadBuffer = (uint8_t *)readBuffer->GetElement(readOffset); + } + } + + if (isLongRunningOperation) + { + // this is a long running operation and hasn't started yet + // perform I2C transaction using driver's ASYNC API which is launching a thread to perform it + if (stack.m_customState == 1) + { + // spawn working thread to perform the I2C transaction + + // 1. allocate memory for I2C thread + palI2c->WorkingThreadStack = (uint32_t *)platform_malloc(I2C_THREAD_STACK_SIZE); + + if (palI2c->WorkingThreadStack == NULL) + { + NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_MEMORY); + } + + // 2. create thread + uint16_t status = tx_thread_create( + palI2c->WorkingThread, +#if !defined(BUILD_RTM) + (CHAR *)"I2C Thread", +#else + NULL, +#endif + I2CWorkingThread_entry, + (uint32_t)palI2c, + palI2c->WorkingThreadStack, + I2C_THREAD_STACK_SIZE, + I2C_THREAD_PRIORITY, + I2C_THREAD_PRIORITY, + TX_NO_TIME_SLICE, + TX_AUTO_START); + + if (status != TX_SUCCESS) + { + NANOCLR_SET_AND_LEAVE(CLR_E_PROCESS_EXCEPTION); + } + + // bump custom state + stack.m_customState = 2; + } + } + else + { + // this is NOT a long running operation + // perform I2C transaction + + if (palI2c->ReadSize != 0 && palI2c->WriteSize != 0) + { + // this is a Write/Read transaction + i2cTransfer.flags = I2C_FLAG_WRITE_READ; + + i2cTransfer.buf[0].data = palI2c->WriteBuffer; + i2cTransfer.buf[0].len = palI2c->WriteSize; + i2cTransfer.buf[1].data = palI2c->ReadBuffer; + i2cTransfer.buf[1].len = palI2c->ReadSize; + + // Perform the transfer and return status from the transfer + transactionResult = I2CSPM_Transfer(palI2c->Configuration->port, &i2cTransfer); + } + else + { + if (palI2c->ReadSize == 0) + { + // this is Write only transaction + i2cTransfer.flags = I2C_FLAG_WRITE; + + i2cTransfer.buf[0].data = palI2c->WriteBuffer; + i2cTransfer.buf[0].len = palI2c->WriteSize; + + // Perform the transfer and return status from the transfer + transactionResult = I2CSPM_Transfer(palI2c->Configuration->port, &i2cTransfer); + } + else + { + // this is a Read only transaction + i2cTransfer.flags = I2C_FLAG_READ; + i2cTransfer.buf[0].data = palI2c->ReadBuffer; + i2cTransfer.buf[0].len = palI2c->ReadSize; + + // Perform the transfer and return status from the transfer + transactionResult = I2CSPM_Transfer(palI2c->Configuration->port, &i2cTransfer); + } + } + } + + while (eventResult) + { + if (!isLongRunningOperation) + { + // this is not a long running operation so nothing to do here + break; + } + + if (palI2c->WorkingThread->tx_thread_state == TX_TERMINATED) + { + // I2C working thread is now complete + break; + } + + // non-blocking wait allowing other threads to run while we wait for the I2C transaction to complete + NANOCLR_CHECK_HRESULT( + g_CLR_RT_ExecutionEngine.WaitEvents(stack.m_owningThread, *timeout, Event_I2cMaster, eventResult)); + } + + if (isLongRunningOperation) + { + // pop timeout heap block from stack + stack.PopValue(); + } + + if (eventResult || !isLongRunningOperation) + { + // event occurred + // OR this is NOT a long running operation + + // create the return object (I2cTransferResult) + // only at this point we are sure that there will be a return from this thread so it's OK to use the + // managed stack + CLR_RT_HeapBlock &top = stack.PushValueAndClear(); + NANOCLR_CHECK_HRESULT( + g_CLR_RT_ExecutionEngine.NewObjectFromIndex(top, g_CLR_RT_WellKnownTypes.m_I2cTransferResult)); + result = top.Dereference(); + FAULT_ON_NULL(result); + + if (isLongRunningOperation) + { + // get transaction result from I2C struct + transactionResult = palI2c->TransactionResult; + + // delete thread + tx_thread_delete(palI2c->WorkingThread); + + // free stack memory + platform_free(palI2c->WorkingThreadStack); + + // clear pointers + palI2c->WorkingThread = NULL; + palI2c->WorkingThreadStack = NULL; + } + + // get the result from the working thread execution + if (transactionResult != i2cTransferDone) + { + // figure out what was the error and set the status field + switch (transactionResult) + { + case i2cTransferNack: + result[I2cTransferResult::FIELD___status].SetInteger( + (CLR_UINT32)I2cTransferStatus_SlaveAddressNotAcknowledged); + break; + + case i2cTransferBusErr: + case i2cTransferArbLost: + case i2cTransferUsageFault: + case i2cTransferSwFault: + result[I2cTransferResult::FIELD___status].SetInteger( + (CLR_UINT32)I2cTransferStatus_ClockStretchTimeout); + break; + + default: + result[I2cTransferResult::FIELD___status].SetInteger( + (CLR_UINT32)I2cTransferStatus_UnknownError); + } + + // set the bytes transferred count to 0 because we don't have a way to know how many bytes were + // actually sent/received + result[I2cTransferResult::FIELD___bytesTransferred].SetInteger(0); + } + else + { + // successful transaction + // set the result field + result[I2cTransferResult::FIELD___status].SetInteger((CLR_UINT32)I2cTransferStatus_FullTransfer); + + // set the bytes transferred field + result[I2cTransferResult::FIELD___bytesTransferred].SetInteger( + (CLR_UINT32)(palI2c->WriteSize + palI2c->ReadSize)); + } + } + } + + NANOCLR_NOCLEANUP(); +} diff --git a/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.I2c/sys_dev_i2c_native_target.h b/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.I2c/sys_dev_i2c_native_target.h new file mode 100644 index 0000000000..01989f1fe3 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.I2c/sys_dev_i2c_native_target.h @@ -0,0 +1,91 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#ifndef SYS_DEV_I2C_NATIVE_TARGET_H +#define SYS_DEV_I2C_NATIVE_TARGET_H + +#include +#include + +#include +#include +#include +#include + +// receiver thread +#define I2C_THREAD_STACK_SIZE 256 +#define I2C_THREAD_PRIORITY 5 + +// set missing defines +#ifndef GECKO_USE_I2C0 +#define GECKO_USE_I2C0 FALSE +#endif +#ifndef GECKO_USE_I2C1 +#define GECKO_USE_I2C1 FALSE +#endif +#ifndef GECKO_USE_I2C2 +#define GECKO_USE_I2C2 FALSE +#endif + +// struct representing the I2C +typedef struct NF_PAL_I2C +{ + I2CSPM_Init_TypeDef *Configuration; + TX_THREAD *WorkingThread; + uint32_t *WorkingThreadStack; + I2C_TransferReturn_TypeDef TransactionResult; + uint16_t Address; + float ByteTime; + + uint8_t *WriteBuffer; + uint8_t WriteSize; + + uint8_t *ReadBuffer; + uint8_t ReadSize; +} NF_PAL_I2C; + +//////////////////////////////////////////// +// declaration of the the I2C PAL structs // +//////////////////////////////////////////// +#if defined(I2C0) && (GECKO_USE_I2C0 == TRUE) +extern NF_PAL_I2C I2C0_PAL; +#endif +#if defined(I2C1) && (GECKO_USE_I2C1 == TRUE) +extern NF_PAL_I2C I2C1_PAL; +#endif +#if defined(I2C2) && (GECKO_USE_I2C2 == TRUE) +extern NF_PAL_I2C I2C2_PAL; +#endif + +#if defined(_SILICON_LABS_32B_SERIES_1) + +// the following macro defines a function that configures the GPIO pins for a Gecko I2C peripheral +// it gets called in the System_Device_I2c_I2cDevice::NativeInit function +// this is required because the I2C peripherals can use multiple GPIO configuration combinations +#define I2C_CONFIG_PINS(num, gpio_port_scl, gpio_port_sda, scl_pin, sda_pin, scl_port_location, sda_port_location) \ + void ConfigPins_I2C##num() \ + { \ + I2C##num##_PAL.Configuration->sclPort = gpio_port_scl; \ + I2C##num##_PAL.Configuration->sdaPort = gpio_port_sda; \ + I2C##num##_PAL.Configuration->sclPin = scl_pin; \ + I2C##num##_PAL.Configuration->sdaPin = sda_pin; \ + I2C##num##_PAL.Configuration->portLocationScl = scl_port_location; \ + I2C##num##_PAL.Configuration->portLocationSda = sda_port_location; \ + } + +#else +#error \ + "Only _SILICON_LABS_32B_SERIES_1 is supported at this time. To add support for other series declaration above has to be updated" +#endif + +////////////////////////////////////////////////////////////////////////////////////////////// +// when an I2C is defined the declarations below will have the real function/configuration // +// in the target folder @ target_windows_devices_i2c_config.cpp // +////////////////////////////////////////////////////////////////////////////////////////////// +void ConfigPins_I2C0(); +void ConfigPins_I2C1(); +void ConfigPins_I2C2(); + +#endif // SYS_DEV_I2C_NATIVE_TARGET_H diff --git a/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.Pwm/sys_dev_pwm_native_System_Device_Pwm_PwmChannel.cpp b/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.Pwm/sys_dev_pwm_native_System_Device_Pwm_PwmChannel.cpp new file mode 100644 index 0000000000..c49e1820d4 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.Pwm/sys_dev_pwm_native_System_Device_Pwm_PwmChannel.cpp @@ -0,0 +1,441 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include + +#define CAP_COMPARE_CHANNELS_COUNT 4 + +// flag to prevent duplicate initialization +static bool DcRegulatorInit = false; + +NF_PAL_PWM_INSTANCE PwmInstances[PWM_TIMERS_COUNT] = { + {false, false, {255, 255, 255}}, + {false, false, {255, 255, 255}}, + {false, false, {255, 255, 255}}}; + +uint32_t ComputeDutyCycle(uint32_t currentCount, uint32_t dutyCycle) +{ + // Return a duty cycle in the range of the current timer duty resolution + uint32_t dutyCycleValue = + currentCount * dutyCycle / Library_sys_dev_pwm_native_System_Device_Pwm_PwmChannel::CONST_DutyCycleFactor; + + return dutyCycleValue; +} + +int32_t GetPwmConfigFromPin(int pin) +{ + if (pin >= -1) + { + for (int i = 0; i < PwmConfigCount; i++) + { + if (GET_ENCODED_PWM_PORT_PIN(PwmPortPinConfig[i]) == pin) + { + return i; + } + } + } + + return -1; +} + +int32_t GetPwmConfigFromTimeAndChannel(int timerId, int channelId) +{ + for (int i = 0; i < PwmConfigCount; i++) + { + if (PwmPortPinConfig[i].wtimerIndex == timerId && PwmPortPinConfig[i].capCompIndex == channelId) + { + return i; + } + } + + return -1; +} + +int32_t GetPwmConfig(int pinNumber, int timerId, int channelId) +{ + int32_t configIndex = -1; + + if (pinNumber != -1) + { + configIndex = GetPwmConfigFromPin(pinNumber); + } + + if (configIndex == -1) + { + configIndex = GetPwmConfigFromTimeAndChannel(timerId, channelId); + } + + return configIndex; +} + +TIMER_TypeDef *GetPwmTimer(int timerId) +{ + switch (timerId) + { + + case 0: + return WTIMER0; + + case 1: + return WTIMER1; + + case 2: + return WTIMER2; + + default: + return NULL; + } +} + +CMU_Clock_TypeDef_enum GetPwmClock(int timerId) +{ + switch (timerId) + { + + case 0: + return cmuClock_WTIMER0; + + case 1: + return cmuClock_WTIMER1; + + case 2: + return cmuClock_WTIMER1; + + default: + return (CMU_Clock_TypeDef_enum)-1; + } +} + +void StopChannel(int32_t configIndex) +{ + bool okToDisable; + const NF_PAL_PWM_PORT_PIN_CONFIG *pwmConfig; + + // grab PWM config + pwmConfig = &PwmPortPinConfig[configIndex]; + + // Stops PWM output on the channel associated with the selected pin + // disable CC route pin + GetPwmTimer(pwmConfig->wtimerIndex)->ROUTEPEN &= ~(TIMER_ROUTEPEN_CC0PEN << pwmConfig->capCompIndex); + + // reset GPIO + GPIO_PinModeSet(pwmConfig->gpioPort, pwmConfig->portPin, gpioModeDisabled, 0); + + // free channel + PwmInstances[pwmConfig->wtimerIndex].ChannelArray[pwmConfig->capCompIndex] = 255; + + // check if we can disable the timer + okToDisable = true; + for (int i = 0; i < PWM_CHANNEL_COUNT; i++) + { + if (PwmInstances[pwmConfig->wtimerIndex].ChannelArray[i] != 255) + { + // we can't disable the timer yet + okToDisable = false; + break; + } + } + + if (okToDisable) + { + // disable timer + TIMER_Reset(GetPwmTimer(pwmConfig->wtimerIndex)); + + // disable clock for WTIMER module + CMU_ClockEnable(GetPwmClock(pwmConfig->wtimerIndex), false); + + // lower flag about time being configured + PwmInstances[pwmConfig->wtimerIndex].IsConfigured = false; + } +} + +void DeInitPwm() +{ + for (int i = 0; i < PWM_TIMERS_COUNT; i++) + { + for (int j = 0; j < PWM_CHANNEL_COUNT; j++) + { + if (PwmInstances[i].ChannelArray[j] != 255) + { + StopChannel(GetPwmConfigFromPin(PwmInstances[i].ChannelArray[j])); + } + } + } +} + +HRESULT Library_sys_dev_pwm_native_System_Device_Pwm_PwmChannel::NativeInit___VOID(CLR_RT_StackFrame &stack) +{ + int32_t timerId; + int32_t pinNumber; + int32_t channelId; + int32_t configIndex; + int32_t desiredFrequency; + PwmPulsePolarity polarity; + // int32_t routeLocationBit; + TIMER_InitCC_TypeDef timerCCInit; + const NF_PAL_PWM_PORT_PIN_CONFIG *pwmConfig; + + NANOCLR_HEADER(); + + // get a pointer to the managed object instance and check that it's not NULL + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + + // reset config for NOT FOUND + configIndex = -1; + + if (!DcRegulatorInit) + { + // init DCDC regulator with kit specific parameters + EMU_DCDCInit_TypeDef dcdcInit = EMU_DCDCINIT_DEFAULT; + EMU_DCDCInit(&dcdcInit); + } + + timerId = pThis[FIELD___pwmTimer].NumericByRef().s4; + pinNumber = pThis[FIELD___pinNumber].NumericByRef().s4; + channelId = pThis[FIELD___channelNumber].NumericByRef().s4; + desiredFrequency = pThis[FIELD___frequency].NumericByRef().s4; + polarity = (PwmPulsePolarity)(pThis[Library_sys_dev_pwm_native_System_Device_Pwm_PwmChannel::FIELD___polarity] + .NumericByRef() + .u4); + + // try to find config + configIndex = GetPwmConfig(pinNumber, timerId, channelId); + + if (configIndex == -1) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + // grab PWM config + pwmConfig = &PwmPortPinConfig[configIndex]; + + // check if this channel is already in use + if (PwmInstances[pwmConfig->wtimerIndex].ChannelArray[pwmConfig->capCompIndex] != 255) + { + NANOCLR_SET_AND_LEAVE(CLR_E_PIN_UNAVAILABLE); + } + + // store encoded GPIO port and pin number + pThis[FIELD___pinNumber].NumericByRef().s4 = GET_ENCODED_PWM_PORT_PIN(PwmPortPinConfig[configIndex]); + PwmInstances[pwmConfig->wtimerIndex].ChannelArray[pwmConfig->capCompIndex] = + pThis[FIELD___pinNumber].NumericByRef().s4; + + // check if timer needs to be initialized + if (!PwmInstances[pwmConfig->wtimerIndex].IsConfigured) + { + // timer is not configured, configure it + + // Enable clock for WTIMER module + CMU_ClockEnable(GetPwmClock(timerId), true); + + // set top value to max PWM_FREQ frequency + TIMER_TopSet(GetPwmTimer(timerId), CMU_ClockFreqGet(GetPwmClock(timerId)) / desiredFrequency); + + // set duty cycle to 100% + TIMER_CompareSet(WTIMER0, 0, TIMER_TopGet(WTIMER0) - 1); + + // Initialize the timer + TIMER_Init_TypeDef timerInit = TIMER_INIT_DEFAULT; + TIMER_Init(GetPwmTimer(pwmConfig->wtimerIndex), &timerInit); + + // set flag to indicate that timer is configured + PwmInstances[pwmConfig->wtimerIndex].IsConfigured = true; + } + + // config GPIO + GPIO_PinModeSet(pwmConfig->gpioPort, pwmConfig->portPin, gpioModePushPull, polarity); + + // Route WTIMER CC to location + GetPwmTimer(pwmConfig->wtimerIndex)->ROUTELOC0 |= pwmConfig->capCompLocation << pwmConfig->capCompIndex * 8; + + // Configure WTIMER Compare/Capture for output compare + // Use PWM mode and config polarity too + timerCCInit = TIMER_INITCC_DEFAULT; + timerCCInit.mode = timerCCModePWM; + timerCCInit.outInvert = (polarity == PwmPulsePolarity_ActiveLow); + TIMER_InitCC(GetPwmTimer(pwmConfig->wtimerIndex), pwmConfig->capCompIndex, &timerCCInit); + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_sys_dev_pwm_native_System_Device_Pwm_PwmChannel::NativeSetDesiredFrequency___VOID__I4( + CLR_RT_StackFrame &stack) +{ + uint32_t timerId; + int32_t desiredFrequency; + + NANOCLR_HEADER(); + + // get a pointer to the managed object instance and check that it's not NULL + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + + timerId = pThis[FIELD___pwmTimer].NumericByRef().s4; + desiredFrequency = stack.Arg1().NumericByRef().s4; + + // parameter check + if (desiredFrequency < 0) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + // Set top value to overflow at the desired PWM_FREQ frequency + TIMER_TopSet(GetPwmTimer(timerId), (CMU_ClockFreqGet(GetPwmClock(timerId)) / desiredFrequency) - 1); + + // store the frequency + pThis[FIELD___frequency].NumericByRef().s4 = desiredFrequency; + + stack.SetResult_R8((double)desiredFrequency); + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_sys_dev_pwm_native_System_Device_Pwm_PwmChannel::NativeSetActiveDutyCyclePercentage___VOID__R8( + CLR_RT_StackFrame &stack) +{ + uint32_t pinNumber; + int32_t configIndex; + uint32_t dutyCycle; + const NF_PAL_PWM_PORT_PIN_CONFIG *pwmConfig; + + NANOCLR_HEADER(); + + // get a pointer to the managed object instance and check that it's not NULL + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + + // parameter check + if (stack.Arg1().NumericByRef().r8 < 0 || stack.Arg1().NumericByRef().r8 > 1.0) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + pinNumber = pThis[FIELD___pinNumber].NumericByRef().s4; + + // try to find config + configIndex = GetPwmConfigFromPin(pinNumber); + + // grab PWM config + pwmConfig = &PwmPortPinConfig[configIndex]; + + dutyCycle = (uint32_t)(stack.Arg1().NumericByRef().r8 * CONST_DutyCycleFactor); + + // set compare value for initial duty cycle + TIMER_CompareSet( + GetPwmTimer(pwmConfig->wtimerIndex), + pwmConfig->capCompIndex, + ComputeDutyCycle(TIMER_TopGet(GetPwmTimer(pwmConfig->wtimerIndex)), dutyCycle)); + + // store the new duty cycle + pThis[FIELD___dutyCycle].NumericByRef().u4 = dutyCycle; + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_sys_dev_pwm_native_System_Device_Pwm_PwmChannel::NativeStart___VOID(CLR_RT_StackFrame &stack) +{ + uint32_t pinNumber; + int32_t configIndex; + const NF_PAL_PWM_PORT_PIN_CONFIG *pwmConfig; + + NANOCLR_HEADER(); + + // get a pointer to the managed object instance and check that it's not NULL + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + + pinNumber = pThis[FIELD___pinNumber].NumericByRef().s4; + + // try to find config + configIndex = GetPwmConfigFromPin(pinNumber); + + // grab PWM config + pwmConfig = &PwmPortPinConfig[configIndex]; + + // enable CC route pin so the GPIO get driven by the timer + GetPwmTimer(pwmConfig->wtimerIndex)->ROUTEPEN |= TIMER_ROUTEPEN_CC0PEN << pwmConfig->capCompIndex; + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_sys_dev_pwm_native_System_Device_Pwm_PwmChannel::NativeStop___VOID(CLR_RT_StackFrame &stack) +{ + uint32_t pinNumber; + int32_t configIndex; + + NANOCLR_HEADER(); + + // get a pointer to the managed object instance and check that it's not NULL + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + + pinNumber = pThis[FIELD___pinNumber].NumericByRef().s4; + + // try to find config + configIndex = GetPwmConfigFromPin(pinNumber); + + StopChannel(configIndex); + + // "dispose" pin number + pThis[FIELD___pinNumber].NumericByRef().s4 = -1; + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_sys_dev_pwm_native_System_Device_Pwm_PwmChannel::DisposeNative___VOID(CLR_RT_StackFrame &stack) +{ + uint32_t pinNumber; + int32_t configIndex; + + NANOCLR_HEADER(); + + // get a pointer to the managed object instance and check that it's not NULL + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + + pinNumber = pThis[FIELD___pinNumber].NumericByRef().s4; + + // try to find config + configIndex = GetPwmConfigFromPin(pinNumber); + + if (configIndex > -1) + { + // hasn't been disposed yet, so stop the channel + StopChannel(configIndex); + } + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_sys_dev_pwm_native_System_Device_Pwm_PwmChannel::GetChannel___STATIC__I4__I4__I4( + CLR_RT_StackFrame &stack) +{ + int32_t configIndex; + const NF_PAL_PWM_PORT_PIN_CONFIG *pwmConfig; + + NANOCLR_HEADER(); + + // Get pin and potential TIM + int pinNumber = stack.Arg0().NumericByRef().s4; + + // try to find config + configIndex = GetPwmConfigFromPin(pinNumber); + + if (configIndex > -1) + { + // grab PWM config + pwmConfig = &PwmPortPinConfig[configIndex]; + + // Check if the combination is ok and set the result + stack.SetResult_I4(pwmConfig->capCompIndex); + } + else + { + stack.SetResult_I4(-1); + } + + NANOCLR_NOCLEANUP_NOLABEL(); +} diff --git a/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.Pwm/sys_dev_pwm_native_target.h b/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.Pwm/sys_dev_pwm_native_target.h new file mode 100644 index 0000000000..b85767bd8d --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.Pwm/sys_dev_pwm_native_target.h @@ -0,0 +1,45 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#ifndef SYS_DEV_PWM_NATIVE_TARGET_H +#define SYS_DEV_PWM_NATIVE_TARGET_H + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#define GET_ENCODED_PWM_PORT_PIN(pwmPPConfig) (int)pwmPPConfig.gpioPort * 16 + pwmPPConfig.portPin +#define PWM_CHANNEL_COUNT (3) +#define PWM_TIMERS_COUNT (3) + +typedef struct +{ + bool IsRunning; + bool IsConfigured; + uint8_t ChannelArray[PWM_CHANNEL_COUNT]; +} NF_PAL_PWM_INSTANCE; + +typedef struct +{ + uint8_t wtimerIndex; + uint8_t capCompIndex; + GPIO_Port_TypeDef gpioPort; + uint8_t portPin; + uint8_t capCompLocation; +} NF_PAL_PWM_PORT_PIN_CONFIG; + +extern const NF_PAL_PWM_PORT_PIN_CONFIG PwmPortPinConfig[]; +extern const int PwmConfigCount; +// using the 1st three WTIMER instances for PWM +extern NF_PAL_PWM_INSTANCE PwmInstances[PWM_TIMERS_COUNT]; + +#endif // SYS_DEV_PWM_NATIVE_TARGET_H diff --git a/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.Spi/cpu_spi.cpp b/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.Spi/cpu_spi.cpp new file mode 100644 index 0000000000..0ccec5c4f7 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.Spi/cpu_spi.cpp @@ -0,0 +1,781 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include + +///////////////////////////////////////////////////// +// SPI PAL strucs declared in sys_dev_spi_native.h // +///////////////////////////////////////////////////// +#if GECKO_USE_SPI0 == TRUE +NF_PAL_SPI SPI0_PAL; +#endif +#if GECKO_USE_SPI1 == TRUE +NF_PAL_SPI SPI1_PAL; +#endif +#if GECKO_USE_SPI2 == TRUE +NF_PAL_SPI SPI2_PAL; +#endif +#if GECKO_USE_SPI3 == TRUE +NF_PAL_SPI SPI3_PAL; +#endif +#if GECKO_USE_SPI4 == TRUE +NF_PAL_SPI SPI4_PAL; +#endif +#if GECKO_USE_SPI5 == TRUE +NF_PAL_SPI SPI5_PAL; +#endif + +#if defined(EUSART_PRESENT) +#error "Only USART type is supported. Driver can't handle EUSART." +#endif + +extern void GetIoLine(int16_t pinNumber, GPIO_Port_TypeDef *port, uint32_t *portPin); + +static USART_TypeDef *GetUsartFromHandle(NF_SpiDriver_Handle_t handle) +{ + return handle->peripheral.usartPort; +} + +static void CompleteTransfer(NF_SpiDriver_Handle_t handle) +{ + (void)handle; + // SpiRelease(driver); +} + +// Callback used when a async transfer operation completes +void SpiTransferCompleteCallback(NF_SpiDriver_Handle_t handle, Ecode_t transferStatus, int itemsTransferred) +{ + (void)transferStatus; + (void)itemsTransferred; + + NATIVE_INTERRUPT_START + + NF_PAL_SPI *palSpi = NULL; + + // Find the NF_PAL_SPI* for handle +#if GECKO_USE_SPI0 == TRUE + if (GetUsartFromHandle(handle) == USART0) + { + palSpi = &SPI0_PAL; + } +#endif + +#if GECKO_USE_SPI1 == TRUE + if (GetUsartFromHandle(handle) == USART1) + { + palSpi = &SPI1_PAL; + } +#endif + +#if GECKO_USE_SPI2 == TRUE + if (GetUsartFromHandle(handle) == USART2) + { + palSpi = &SPI2_PAL; + } +#endif + +#if GECKO_USE_SPI3 == TRUE + if (GetUsartFromHandle(handle) == USART3) + { + palSpi = &SPI3_PAL; + } +#endif + +#if GECKO_USE_SPI4 == TRUE + if (GetUsartFromHandle(handle) == USART4) + { + palSpi = &SPI4_PAL; + } +#endif + +#if GECKO_USE_SPI5 == TRUE + if (GetUsartFromHandle(handle) == USART5) + { + palSpi = &SPI5_PAL; + } +#endif + + // check if there is any Rx operation due + if (palSpi->SequentialTxRx) + { + // yes there is! + // clear flag and... + palSpi->SequentialTxRx = false; + + // ... start it + // TODO + // if (palSpi->busConfiguration) + // { + // // half duplex operation, clear output enable bit + // palSpi->Handle->spi->CR1 &= ~SPI_CR1_BIDIOE; + // } + NF_SpiDriver_Receive(palSpi->Handle, palSpi->ReadBuffer, palSpi->ReadSize, SpiTransferCompleteCallback); + } + else + { + // all done here! + + // if CS is to be controlled by the driver, set the GPIO + if (palSpi->ChipSelect >= 0) + { + // de-assert pin based on CS active level + CPU_GPIO_TogglePinState(palSpi->ChipSelect); + } + + // fire callback for SPI transaction complete + // only if callback set + if (palSpi->Callback) + { + palSpi->Callback(palSpi->BusIndex); + } + } + + NATIVE_INTERRUPT_END +}; + +// Return the NF_PAL structure for busIndex +// Return NULL is invalid bus +NF_PAL_SPI *GetNfPalfromBusIndex(uint8_t busIndex) +{ + NF_PAL_SPI *palSpi = NULL; + + // get the PAL struct for the SPI bus + switch (busIndex) + { +#if GECKO_USE_SPI0 == TRUE + case 0: + palSpi = &SPI0_PAL; + break; +#endif + +#if GECKO_USE_SPI1 == TRUE + case 1: + palSpi = &SPI1_PAL; + break; +#endif + +#if GECKO_USE_SPI2 == TRUE + case 2: + palSpi = &SPI2_PAL; + break; +#endif + +#if GECKO_USE_SPI3 == TRUE + case 3: + palSpi = &SPI3_PAL; + break; +#endif + +#if GECKO_USE_SPI4 == TRUE + case 4: + palSpi = &SPI4_PAL; + break; +#endif + +#if GECKO_USE_SPI5 == TRUE + case 5: + palSpi = &SPI5_PAL; + break; +#endif + + default: + // the requested SPI bus is not valid + break; + } + + return palSpi; +} + +// Give a complete low-level SPI configuration from passed SPI_DEVICE_CONFIGURATION +void GetSpiConfig(const SPI_DEVICE_CONFIGURATION &config, NF_SpiDriver_Init_t &initSpiData) +{ + // SPI mode (matches SPIDRV_ClockMode_t) + initSpiData.bitRate = config.Clock_RateHz; + + switch (config.Spi_Mode) + { + case SpiMode_Mode0: + initSpiData.clockMode = spidrvClockMode0; + break; + + case SpiMode_Mode1: + initSpiData.clockMode = spidrvClockMode1; + break; + + case SpiMode_Mode2: + initSpiData.clockMode = spidrvClockMode2; + break; + + case SpiMode_Mode3: + initSpiData.clockMode = spidrvClockMode3; + break; + + default: + ASSERT(false); + break; + } + +#if defined(SPI_CS_CONTROL) + initSpiData.csControl = SPI_CS_CONTROL; +#else + initSpiData.csControl = spidrvCsControlApplication; +#endif + initSpiData.dummyTxValue = 0; + // Sets the order of bytes transmission : MSB first or LSB first + initSpiData.bitOrder = config.DataOrder16 == DataBitOrder_MSB ? spidrvBitOrderMsbFirst : spidrvBitOrderLsbFirst; + initSpiData.frameLength = config.DataIs16bits ? 16 : 8; + initSpiData.isHalfDuplex = config.BusConfiguration == SpiBusConfiguration_HalfDuplex ? true : false; +} + +// Performs a read/write operation on 8-bit word data. +// +// Parameters +// deviceHandle +// Device handle from add_device +// sdev +// reference to SPI_DEVICE_CONFIGURATION +// wrc +// reference to SPI_WRITE_READ_SETTINGS +// writeData +// A pointer to the buffer from which the data is to be written to the device. +// writeSize +// The number of elements(8 or 16) to be written. +// readData +// A pointer to the buffer into which the data is to be read from the device. +// readSize +// The number of elements(8 or 16) to be read. +// +// return S_OK=Successful, Async started=CLR_BUSY, Error=CLR_E_OUT_OF_MEMORY, CLR_E_INVALID_PARAMETER, CLR_E_FAIL +// +HRESULT CPU_SPI_nWrite_nRead( + uint32_t deviceHandle, + SPI_DEVICE_CONFIGURATION &sdev, + SPI_WRITE_READ_SETTINGS &wrc, + uint8_t *writeBuffer, + int32_t writeSize, + uint8_t *readBuffer, + int32_t readSize) +{ + NANOCLR_HEADER(); + { + bool busConfigIsHalfDuplex; + + NF_PAL_SPI *palSpi = (NF_PAL_SPI *)deviceHandle; + + // If callback then use aync operation + bool sync = (wrc.callback == 0); + + // Save width of transfer + palSpi->BufferIs16bits = wrc.Bits16ReadWrite; + + // Callback sync / async + palSpi->Callback = wrc.callback; + + if (writeBuffer != NULL) + { + palSpi->WriteSize = writeSize; + } + + if (readBuffer != NULL) + { + palSpi->ReadSize = readSize; + } + + // === Setup the operation and init buffers === + palSpi->BusIndex = sdev.Spi_Bus; + + // adjust the bus index to match the PAL struct + NF_SpiDriver_SetFramelength(palSpi->Handle, wrc.Bits16ReadWrite ? 16 : 8); + + // set bus config flag + busConfigIsHalfDuplex = (palSpi->BusConfiguration == SpiBusConfiguration_HalfDuplex); + + if (writeBuffer != NULL) + { + // set the pointer to the write buffer as BYTE + palSpi->WriteBuffer = (uint8_t *)writeBuffer; + } + + if (readBuffer != NULL) + { + // set DMA read buffer + if (palSpi->ReadSize > 0) + { + palSpi->ReadBuffer = (uint8_t *)readBuffer; + } + } + + // if CS is to be controlled by the driver, set the GPIO + if (palSpi->ChipSelect >= 0) + { + // assert pin based on CS active level + CPU_GPIO_SetPinState(palSpi->ChipSelect, (GpioPinValue)sdev.ChipSelectActiveState); + } + + if (sync) + { + // Sync operation + // perform SPI operation using driver's SYNC API + if (palSpi->WriteSize != 0 && palSpi->ReadSize != 0) + { + // Transmit+Receive + if (wrc.fullDuplex) + { + // Full duplex + // Uses the largest buffer size as transfer size + NF_SpiDriver_TransferBlocking( + palSpi->Handle, + palSpi->WriteBuffer, + palSpi->ReadBuffer, + palSpi->WriteSize > palSpi->ReadSize ? palSpi->WriteSize : palSpi->ReadSize); + } + else + { + // send operation + // TODO + // if (busConfigIsHalfDuplex) + // { + // // half duplex operation, set output enable + // palSpi->Handle->spi->CR1 |= SPI_CR1_BIDIOE; + // } + NF_SpiDriver_TransmitBlocking(palSpi->Handle, palSpi->WriteBuffer, palSpi->WriteSize); + + // receive operation + // TODO + // if (busConfigIsHalfDuplex) + // { + // // half duplex operation, set output enable + // palSpi->Handle->spi->CR1 &= ~SPI_CR1_BIDIOE; + // } + NF_SpiDriver_ReceiveBlocking(palSpi->Handle, palSpi->ReadBuffer, palSpi->ReadSize); + } + } + else + { + // Transmit only or Receive only + if (palSpi->ReadSize != 0) + { + // receive + // TODO + // if (busConfigIsHalfDuplex) + // { + // // half duplex operation, set output enable + // palSpi->Handle->spi->CR1 &= ~SPI_CR1_BIDIOE; + // } + NF_SpiDriver_ReceiveBlocking(palSpi->Handle, palSpi->ReadBuffer, palSpi->ReadSize); + } + else + { + // send + // TODO + if (busConfigIsHalfDuplex) + { + // half duplex operation, set output enable + // palSpi->Handle->spi->CR1 |= SPI_CR1_BIDIOE; + } + NF_SpiDriver_TransmitBlocking(palSpi->Handle, palSpi->WriteBuffer, palSpi->WriteSize); + } + } + + CompleteTransfer(palSpi->Handle); + + // if CS is to be controlled by the driver, set the GPIO + if (palSpi->ChipSelect >= 0) + { + // de-assert pin based on CS active level + CPU_GPIO_TogglePinState(palSpi->ChipSelect); + } + } + else + { + // Start an Asyncronous SPI transfer + // perform SPI operation using driver's ASYNC API + // Completed on calling SPI Callback + + // if CS is to be controlled by the driver, set the GPIO + if (palSpi->ChipSelect >= 0) + { + // assert pin based on CS active level + CPU_GPIO_SetPinState(palSpi->ChipSelect, (GpioPinValue)sdev.ChipSelectActiveState); + } + + // this is a Async operation + // perform SPI operation using driver's ASYNC API + if (palSpi->WriteSize != 0 && palSpi->ReadSize != 0) + { + // Transmit+Receive + if (wrc.fullDuplex) + { + // Full duplex + // single operation, clear flag + palSpi->SequentialTxRx = false; + + // Uses the largest buffer size as transfer size + NF_SpiDriver_Transfer( + palSpi->Handle, + palSpi->WriteBuffer, + palSpi->ReadBuffer, + palSpi->WriteSize > palSpi->ReadSize ? palSpi->WriteSize : palSpi->ReadSize, + SpiTransferCompleteCallback); + } + else + { + // flag that an Rx is required after the Tx operation completes + palSpi->SequentialTxRx = true; + + // start send operation + if (busConfigIsHalfDuplex) + { + // // half duplex operation, set output enable + // palSpi->Handle->spi->CR1 |= SPI_CR1_BIDIOE; + } + + // receive operation will be started in the callback after the above completes + NF_SpiDriver_Transmit( + palSpi->Handle, + palSpi->WriteBuffer, + palSpi->WriteSize, + SpiTransferCompleteCallback); + } + } + else + { + // Transmit only or Receive only + if (palSpi->ReadSize != 0) + { + // single operation, clear flag + palSpi->SequentialTxRx = false; + + // start receive + NF_SpiDriver_Receive( + palSpi->Handle, + palSpi->ReadBuffer, + palSpi->ReadSize, + SpiTransferCompleteCallback); + } + else + { + // single operation, clear flag + palSpi->SequentialTxRx = false; + + // start send + NF_SpiDriver_Transmit( + palSpi->Handle, + palSpi->WriteBuffer, + palSpi->WriteSize, + SpiTransferCompleteCallback); + } + } + + // Inform caller async operation started + NANOCLR_SET_AND_LEAVE(CLR_E_BUSY); + } + } + + NANOCLR_NOCLEANUP(); +} + +// this is exposing the extended call that allow for re-configuration of SPI +bool CPU_SPI_Initialize_Extended(uint8_t busIndex, const SPI_DEVICE_CONFIGURATION &busConfiguration, bool reconfigure) +{ +#if !defined(BUILD_RTM) + Ecode_t configResult; +#endif + + GPIO_Port_TypeDef port; + uint32_t portPin; + NF_PAL_SPI *palSpi = NULL; + void (*initSpiConfig)(NF_SpiDriver_Init_t &, bool) = NULL; + + // init the PAL struct for this SPI bus and assign the respective driver + // all this occurs if not already done + // why do we need this? because several SPIDevice objects can be created associated to the same bus + switch (busIndex) + { +#if GECKO_USE_SPI0 == TRUE + case 0: + palSpi = &SPI0_PAL; + initSpiConfig = &InitSpiConfig0; + break; +#endif + +#if GECKO_USE_SPI1 == TRUE + case 1: + palSpi = &SPI1_PAL; + initSpiConfig = &InitSpiConfig1; + break; +#endif + +#if GECKO_USE_SPI2 == TRUE + case 2: + palSpi = &SPI2_PAL; + initSpiConfig = &InitSpiConfig2; + + break; +#endif + +#if GECKO_USE_SPI3 == TRUE + case 3: + palSpi = &SPI3_PAL; + initSpiConfig = &InitSpiConfig3; + break; +#endif + +#if GECKO_USE_SPI4 == TRUE + case 4: + palSpi = &SPI4_PAL; + initSpiConfig = &InitSpiConfig4; + break; +#endif + +#if GECKO_USE_SPI5 == TRUE + case 5: + palSpi = &SPI5_PAL; + initSpiConfig = &InitSpiConfig5; + break; +#endif + + default: + // this SPI bus is not valid + return false; + } + + if (palSpi->Handle == NULL) + { + // allocate memory for the USART_InitSync_TypeDef + palSpi->Handle = (NF_SpiDriver_Handle_t)platform_malloc(sizeof(NF_SpiDriver_HandleData_t)); + + // sanity check allocation + if (palSpi->Handle == NULL) + { + return false; + } + + memset(palSpi->Handle, 0, sizeof(NF_SpiDriver_HandleData_t)); + + // allocate memory for the NF_SpiDriver_Init_t + palSpi->InitSpiData = (NF_SpiDriver_Init_t *)platform_malloc(sizeof(NF_SpiDriver_Init_t)); + + // sanity check allocation + if (palSpi->InitSpiData == NULL) + { + platform_free(palSpi->Handle); + + return false; + } + + memset(palSpi->InitSpiData, 0, sizeof(NF_SpiDriver_Init_t)); + + // call handler to configure pins + initSpiConfig(*palSpi->InitSpiData, busConfiguration.BusConfiguration == SpiBusConfiguration_HalfDuplex); + + jump_to_init: + + // get the SPI configuration + GetSpiConfig(busConfiguration, *palSpi->InitSpiData); + +#if !defined(BUILD_RTM) + configResult = +#endif + NF_SpiDriver_Init(palSpi->Handle, palSpi->InitSpiData); + _ASSERTE(configResult == ECODE_OK); + + palSpi->ChipSelect = busConfiguration.DeviceChipSelect; + + // setup GPIO for CS + if (busConfiguration.DeviceChipSelect >= 0) + { + GetIoLine(busConfiguration.DeviceChipSelect, &port, &portPin); + GPIO_PinModeSet(port, portPin, gpioModePushPull, busConfiguration.ChipSelectActiveState ? 0 : 1); + } + } + else + { + // there's already a handle, check if we need to re-configure the SPI bus + if (reconfigure) + { + // deinitalize the SPI bus + NF_SpiDriver_DeInit(palSpi->Handle); + + // jump straight to init + goto jump_to_init; + } + } + + return true; +} + +// this is exposing the "standard" call +bool CPU_SPI_Initialize(uint8_t busIndex, const SPI_DEVICE_CONFIGURATION &busConfiguration) +{ + return CPU_SPI_Initialize_Extended(busIndex, busConfiguration, false); +} + +bool CPU_SPI_Uninitialize(uint8_t busIndex) +{ + NF_PAL_SPI *palSpi = NULL; + GPIO_Port_TypeDef port; + uint32_t portPin; + + // get the PAL struct for the SPI bus + switch (busIndex) + { +#if GECKO_USE_SPI0 == TRUE + case 0: + palSpi = &SPI0_PAL; + + break; +#endif + +#if GECKO_USE_SPI1 == TRUE + case 1: + palSpi = &SPI1_PAL; + + break; +#endif + +#if GECKO_USE_SPI2 == TRUE + case 2: + palSpi = &SPI2_PAL; + + break; +#endif + +#if GECKO_USE_SPI3 == TRUE + case 3: + palSpi = &SPI3_PAL; + + break; +#endif + +#if GECKO_USE_SPI4 == TRUE + case 4: + palSpi = &SPI4_PAL; + break; +#endif + +#if GECKO_USE_SPI5 == TRUE + case 5: + palSpi = &SPI5_PAL; + + break; +#endif + + default: + // the requested SPI bus is not valid + return false; + } + + // reset GPIO for CS + if (palSpi->ChipSelect >= 0) + { + GetIoLine(palSpi->ChipSelect, &port, &portPin); + GPIO_PinModeSet(port, portPin, gpioModeInputPull, 0); + } + + NF_SpiDriver_DeInit(palSpi->Handle); + + // free memory + platform_free(palSpi->Handle->initData); + platform_free(palSpi->Handle); + + palSpi->Handle = NULL; + + return true; +} + +// return Map of available SPI ports +uint32_t CPU_SPI_PortsMap() +{ + uint32_t map = 0; + +#if GECKO_USE_SPI0 == TRUE + map |= 0x01; +#endif + +#if GECKO_USE_SPI1 == TRUE + map |= 0x02; +#endif + +#if GECKO_USE_SPI2 == TRUE + map |= 0x04; +#endif + +#if GECKO_USE_SPI3 == TRUE + map |= 0x08; +#endif + +#if GECKO_USE_SPI4 == TRUE + map |= 0x10; +#endif + +#if GECKO_USE_SPI5 == TRUE + map |= 0x20; +#endif + + return map; +} + +// Add a device to SPi Bus (Optional) +// Returns a device handle. Returns 0 if error +HRESULT CPU_SPI_Add_Device(const SPI_DEVICE_CONFIGURATION &spiDeviceConfig, uint32_t &handle) +{ + // check supported bus configuration: all valid except simplex + if (spiDeviceConfig.BusConfiguration == SpiBusConfiguration_Simplex) + { + return CLR_E_NOT_SUPPORTED; + } + + handle = (uint32_t)GetNfPalfromBusIndex(spiDeviceConfig.Spi_Bus); + + return S_OK; +} + +// Return pins used for SPI bus +void CPU_SPI_GetPins(uint32_t spi_bus, GPIO_PIN &clk, GPIO_PIN &miso, GPIO_PIN &mosi) +{ + (void)spi_bus; + + clk = (GPIO_PIN)-1; + miso = (GPIO_PIN)-1; + mosi = (GPIO_PIN)-1; +} + +// Minimum and Maximum clock frequency available based on bus and configured pins +HRESULT CPU_SPI_MinClockFrequency(uint32_t spiBus, int32_t *frequency) +{ + if (spiBus - 1 >= NUM_SPI_BUSES) + { + return CLR_E_INVALID_PARAMETER; + } + + // Max prescaler value = 256 + // SPI3 or SPI4 are on APB1, so divide max frequency by four. + *frequency = (spiBus == 2 or spiBus == 3) ? SystemCoreClock >>= 9 : SystemCoreClock >> 8; + + return S_OK; +} + +HRESULT CPU_SPI_MaxClockFrequency(uint32_t spiBus, int32_t *frequency) +{ + if (spiBus - 1 >= NUM_SPI_BUSES) + { + return CLR_E_INVALID_PARAMETER; + } + + // According to STM : "At a minimum, the clock frequency should be twice the required communication frequency." + // So maximum useable frequency is CoreClock / 2. + // SPI3 or SPI4 are on APB1, so divide max frequency by four. + *frequency = (spiBus == 2 or spiBus == 3) ? SystemCoreClock >>= 2 : SystemCoreClock >> 1; + + return S_OK; +} + +// Maximum number of SPI devices that can be opened on a bus +uint32_t CPU_SPI_ChipSelectLineCount(uint32_t spi_bus) +{ + (void)spi_bus; + return 10; +} diff --git a/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.Spi/nf_gecko_spi_driver.cpp b/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.Spi/nf_gecko_spi_driver.cpp new file mode 100644 index 0000000000..63da94ffc6 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.Spi/nf_gecko_spi_driver.cpp @@ -0,0 +1,1520 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include "nf_gecko_spi_driver.h" + +#if defined(EUSART_PRESENT) +#error "Only USART type is supported. Drivar can't driver EUSART." +#endif + +#if defined(SL_COMPONENT_CATALOG_PRESENT) +#include "sl_component_catalog.h" +#endif +#include "em_device.h" +#include "em_gpio.h" +#include "em_core.h" +#include "em_usart.h" +#include "dmadrv.h" +#include "nf_gecko_spi_driver.h" +#if defined(SL_CATALOG_POWER_MANAGER_PRESENT) +#include "sl_power_manager.h" +#endif +#include + +#if defined(DMA_PRESENT) && (DMA_COUNT == 1) +#define SPI_DMA_IRQ DMA_IRQn + +#elif defined(LDMA_PRESENT) && (LDMA_COUNT == 1) +#define SPI_DMA_IRQ LDMA_IRQn + +#else +#error "No valid SPIDRV DMA engine defined." +#endif + +#define EMDRV_SPIDRV_USART_FRAMELENGTH_REGVALUE_OFFSET (3U) +#define EMDRV_SPIDRV_EUSART_FRAMELENGTH_REGVALUE_OFFSET (6U) + +// SPI Pins structure used when mapping from location to gpio port+pin. +typedef struct +{ + uint8_t mosiPort; + uint8_t mosiPin; + uint8_t misoPort; + uint8_t misoPin; + uint8_t clkPort; + uint8_t clkPin; + uint8_t csPort; + uint8_t csPin; +} SPI_Pins_t; + +static bool spidrvIsInitialized = false; + +static Ecode_t NF_SpiDriver_InitUsart(NF_SpiDriver_Handle_t handle, NF_SpiDriver_Init_t *initData); + +static void BlockingComplete(NF_SpiDriver_Handle_t handle, Ecode_t transferStatus, int itemsTransferred); + +static Ecode_t ConfigGPIO(NF_SpiDriver_Handle_t handle, bool enable); + +static bool RxDMAComplete(unsigned int channel, unsigned int sequenceNo, void *userParam); + +static void StartReceiveDMA(NF_SpiDriver_Handle_t handle, void *buffer, int count, NF_SpiDriver_Callback_t callback); + +static void StartTransferDMA( + NF_SpiDriver_Handle_t handle, + const void *txBuffer, + void *rxBuffer, + int count, + NF_SpiDriver_Callback_t callback); + +static void StartTransmitDMA( + NF_SpiDriver_Handle_t handle, + const void *buffer, + int count, + NF_SpiDriver_Callback_t callback); + +static Ecode_t TransferApiPrologue(NF_SpiDriver_Handle_t handle, void *buffer, int count); + +static Ecode_t TransferApiBlockingPrologue(NF_SpiDriver_Handle_t handle, void *buffer, int count); + +static void WaitForTransferCompletion(NF_SpiDriver_Handle_t handle); + +// +// Power management functions. +// +static void em1RequestAdd(NF_SpiDriver_Handle_t handle) +{ +#if defined(SL_CATALOG_POWER_MANAGER_PRESENT) + CORE_DECLARE_IRQ_STATE; + + CORE_ENTER_ATOMIC(); + if (handle->em1RequestCount == 0) + { + sl_power_manager_add_em_requirement(SL_POWER_MANAGER_EM1); + } + handle->em1RequestCount++; + CORE_EXIT_ATOMIC(); +#else + handle->em1RequestCount++; +#endif +} + +static void em1RequestRemove(NF_SpiDriver_Handle_t handle) +{ + EFM_ASSERT(handle->em1RequestCount > 0); +#if defined(SL_CATALOG_POWER_MANAGER_PRESENT) + CORE_DECLARE_IRQ_STATE; + + CORE_ENTER_ATOMIC(); + handle->em1RequestCount--; + if (handle->em1RequestCount == 0) + { + sl_power_manager_remove_em_requirement(SL_POWER_MANAGER_EM1); + } + CORE_EXIT_ATOMIC(); +#else + handle->em1RequestCount--; +#endif +} + +static void emRequestInit(NF_SpiDriver_Handle_t handle) +{ + handle->em1RequestCount = 0; +} + +static void emRequestDeinit(NF_SpiDriver_Handle_t handle) +{ + if (handle->em1RequestCount > 0) + { + handle->em1RequestCount = 1; + em1RequestRemove(handle); + } +} + +// +// +// Initialize an SPI driver instance. +// +// @param[out] handle Pointer to an SPI driver handle; refer to @ref +// NF_SpiDriver_Handle_t. +// @param[in] initData Pointer to an initialization data structure; +// refer to @ref NF_SpiDriver_Init. +// @return +// @ref ECODE_EMDRV_SPIDRV_OK on success. On failure, an appropriate +// SPIDRV @ref Ecode_t is returned. +// +Ecode_t NF_SpiDriver_Init(NF_SpiDriver_Handle_t handle, NF_SpiDriver_Init_t *initData) +{ + return NF_SpiDriver_InitUsart(handle, initData); +} + +// +// +// Initialize an SPI driver usart instance. +// +// @param[out] handle Pointer to an SPI driver handle; refer to @ref +// NF_SpiDriver_Handle_t. +// +// @param[in] initData Pointer to an initialization data structure; +// refer to @ref NF_SpiDriver_Init. +// +// @return +// @ref ECODE_EMDRV_SPIDRV_OK on success. On failure, an appropriate +// SPIDRV @ref Ecode_t is returned. +// +static Ecode_t NF_SpiDriver_InitUsart(NF_SpiDriver_Handle_t handle, NF_SpiDriver_Init_t *initData) +{ + Ecode_t retVal; + CORE_DECLARE_IRQ_STATE; + USART_InitSync_TypeDef usartInit = USART_INITSYNC_DEFAULT; +#if defined(_SILICON_LABS_32B_SERIES_2) + int8_t spiPortNum = -1; +#endif + + if (handle == NULL) + { + return ECODE_EMDRV_SPIDRV_ILLEGAL_HANDLE; + } + + if (initData == NULL) + { + return ECODE_EMDRV_SPIDRV_PARAM_ERROR; + } + + memset(handle, 0, sizeof(NF_SpiDriver_HandleData_t)); + emRequestInit(handle); + + if (0) + { +#if defined(USART0) + } + else if ((USART_TypeDef *)initData->port == USART0) + { + handle->usartClock = cmuClock_USART0; + handle->txDMASignal = dmadrvPeripheralSignal_USART0_TXBL; +#if defined(_SILICON_LABS_32B_SERIES_2) + handle->rxDMASignal = dmadrvPeripheralSignal_USART0_RXDATAV; + spiPortNum = 0; +#else + handle->rxDMASignal = dmadrvPeripheralSignal_USART0_RXDATAV; +#endif +#endif +#if defined(USART1) + } + else if ((USART_TypeDef *)initData->port == USART1) + { + handle->usartClock = cmuClock_USART1; + handle->txDMASignal = dmadrvPeripheralSignal_USART1_TXBL; +#if defined(_SILICON_LABS_32B_SERIES_2) + handle->rxDMASignal = dmadrvPeripheralSignal_USART1_RXDATAV; + spiPortNum = 1; +#else + handle->rxDMASignal = dmadrvPeripheralSignal_USART1_RXDATAV; +#endif +#endif +#if defined(USART2) + } + else if ((USART_TypeDef *)initData->port == USART2) + { + handle->usartClock = cmuClock_USART2; + handle->txDMASignal = dmadrvPeripheralSignal_USART2_TXBL; +#if defined(_SILICON_LABS_32B_SERIES_2) + handle->rxDMASignal = dmadrvPeripheralSignal_USART2_RXDATAV; + spiPortNum = 2; +#else + handle->rxDMASignal = dmadrvPeripheralSignal_USART2_RXDATAV; +#endif +#endif +#if defined(USART3) + } + else if ((USART_TypeDef *)initData->port == USART3) + { + handle->usartClock = cmuClock_USART3; + handle->txDMASignal = dmadrvPeripheralSignal_USART3_TXBL; + handle->rxDMASignal = dmadrvPeripheralSignal_USART3_RXDATAV; +#if defined(_SILICON_LABS_32B_SERIES_2) + spiPortNum = 3; +#endif +#endif +#if defined(USART4) + } + else if ((USART_TypeDef *)initData->port == USART4) + { + handle->usartClock = cmuClock_USART4; + handle->txDMASignal = dmadrvPeripheralSignal_USART4_TXBL; + handle->rxDMASignal = dmadrvPeripheralSignal_USART4_RXDATAV; +#if defined(_SILICON_LABS_32B_SERIES_2) + spiPortNum = 4; +#endif +#endif +#if defined(USART5) + } + else if ((USART_TypeDef *)initData->port == USART5) + { + handle->usartClock = cmuClock_USART5; + handle->txDMASignal = dmadrvPeripheralSignal_USART5_TXBL; + handle->rxDMASignal = dmadrvPeripheralSignal_USART5_RXDATAV; +#if defined(_SILICON_LABS_32B_SERIES_2) + spiPortNum = 5; +#endif +#endif +#if defined(USARTRF0) + } + else if ((USART_TypeDef *)initData->port == USARTRF0) + { + handle->usartClock = cmuClock_USARTRF0; + handle->txDMASignal = dmadrvPeripheralSignal_USARTRF0_TXBL; + handle->rxDMASignal = dmadrvPeripheralSignal_USARTRF0_RXDATAV; +#endif +#if defined(USARTRF1) + } + else if ((USART_TypeDef *)initData->port == USARTRF1) + { + handle->usartClock = cmuClock_USARTRF1; + handle->txDMASignal = dmadrvPeripheralSignal_USARTRF1_TXBL; + handle->rxDMASignal = dmadrvPeripheralSignal_USARTRF1_RXDATAV; +#endif + } + else + { + return ECODE_EMDRV_SPIDRV_PARAM_ERROR; + } + + handle->peripheral.usartPort = (USART_TypeDef *)initData->port; + handle->peripheralType = spidrvPeripheralTypeUsart; + handle->initData = initData; + + if (initData->bitOrder == spidrvBitOrderMsbFirst) + { + usartInit.msbf = true; + } + + if (initData->clockMode == spidrvClockMode0) + { + usartInit.clockMode = usartClockMode0; + } + else if (initData->clockMode == spidrvClockMode1) + { + usartInit.clockMode = usartClockMode1; + } + else if (initData->clockMode == spidrvClockMode2) + { + usartInit.clockMode = usartClockMode2; + } + else if (initData->clockMode == spidrvClockMode3) + { + usartInit.clockMode = usartClockMode3; + } + else + { + return ECODE_EMDRV_SPIDRV_PARAM_ERROR; + } + + usartInit.master = true; + usartInit.baudrate = initData->bitRate; + +#if defined(_CMU_HFPERCLKEN0_MASK) + CMU_ClockEnable(cmuClock_HFPER, true); +#endif + CMU_ClockEnable(cmuClock_GPIO, true); + CMU_ClockEnable(handle->usartClock, true); + + if ((initData->frameLength < 4U) || (initData->frameLength > 16U)) + { + return ECODE_EMDRV_SPIDRV_PARAM_ERROR; + } + uint32_t databits = initData->frameLength - 4U + _USART_FRAME_DATABITS_FOUR; + usartInit.databits = (USART_Databits_TypeDef)databits; + + USART_InitSync((USART_TypeDef *)initData->port, &usartInit); + + if (initData->csControl == spidrvCsControlAuto) + { + handle->peripheral.usartPort->CTRL |= USART_CTRL_AUTOCS; + } + + if (initData->isHalfDuplex) + { + handle->peripheral.usartPort->CTRL |= USART_CTRL_LOOPBK; + } + + if (initData->csControl == spidrvCsControlAuto) + { +#if defined(USART_ROUTEPEN_TXPEN) + handle->peripheral.usartPort->ROUTELOC0 = + (handle->peripheral.usartPort->ROUTELOC0 & ~(_USART_ROUTELOC0_TXLOC_MASK | _USART_ROUTELOC0_RXLOC_MASK | + _USART_ROUTELOC0_CLKLOC_MASK | _USART_ROUTELOC0_CSLOC_MASK)) | + (initData->portLocationTx << _USART_ROUTELOC0_TXLOC_SHIFT) | + (initData->portLocationRx << _USART_ROUTELOC0_RXLOC_SHIFT) | + (initData->portLocationClk << _USART_ROUTELOC0_CLKLOC_SHIFT) | + (initData->portLocationCs << _USART_ROUTELOC0_CSLOC_SHIFT); + + handle->peripheral.usartPort->ROUTEPEN = + USART_ROUTEPEN_TXPEN | USART_ROUTEPEN_RXPEN | USART_ROUTEPEN_CLKPEN | USART_ROUTEPEN_CSPEN; +#elif defined(_GPIO_USART_ROUTEEN_MASK) + GPIO->USARTROUTE[spiPortNum].ROUTEEN = + GPIO_USART_ROUTEEN_TXPEN | GPIO_USART_ROUTEEN_RXPEN | GPIO_USART_ROUTEEN_CLKPEN | GPIO_USART_ROUTEEN_CSPEN; + + GPIO->USARTROUTE[spiPortNum].TXROUTE = ((uint32_t)initData->portTx << _GPIO_USART_TXROUTE_PORT_SHIFT) | + ((uint32_t)initData->pinTx << _GPIO_USART_TXROUTE_PIN_SHIFT); + + GPIO->USARTROUTE[spiPortNum].RXROUTE = ((uint32_t)initData->portRx << _GPIO_USART_RXROUTE_PORT_SHIFT) | + ((uint32_t)initData->pinRx << _GPIO_USART_RXROUTE_PIN_SHIFT); + + GPIO->USARTROUTE[spiPortNum].CLKROUTE = ((uint32_t)initData->portClk << _GPIO_USART_CLKROUTE_PORT_SHIFT) | + ((uint32_t)initData->pinClk << _GPIO_USART_CLKROUTE_PIN_SHIFT); + + GPIO->USARTROUTE[spiPortNum].CSROUTE = ((uint32_t)initData->portCs << _GPIO_USART_CSROUTE_PORT_SHIFT) | + ((uint32_t)initData->pinCs << _GPIO_USART_CSROUTE_PIN_SHIFT); +#else + handle->peripheral.usartPort->ROUTE = USART_ROUTE_TXPEN | USART_ROUTE_RXPEN | USART_ROUTE_CLKPEN | + USART_ROUTE_CSPEN | + (initData->portLocation << _USART_ROUTE_LOCATION_SHIFT); +#endif + } + else + { +#if defined(USART_ROUTEPEN_TXPEN) + handle->peripheral.usartPort->ROUTELOC0 = + (handle->peripheral.usartPort->ROUTELOC0 & + ~(_USART_ROUTELOC0_TXLOC_MASK | _USART_ROUTELOC0_RXLOC_MASK | _USART_ROUTELOC0_CLKLOC_MASK)) | + (initData->portLocationTx << _USART_ROUTELOC0_TXLOC_SHIFT) | + (initData->portLocationRx << _USART_ROUTELOC0_RXLOC_SHIFT) | + (initData->portLocationClk << _USART_ROUTELOC0_CLKLOC_SHIFT); + + handle->peripheral.usartPort->ROUTEPEN = USART_ROUTEPEN_TXPEN | USART_ROUTEPEN_RXPEN | USART_ROUTEPEN_CLKPEN; +#elif defined(GPIO_USART_ROUTEEN_TXPEN) + GPIO->USARTROUTE[spiPortNum].ROUTEEN = + GPIO_USART_ROUTEEN_TXPEN | GPIO_USART_ROUTEEN_RXPEN | GPIO_USART_ROUTEEN_CLKPEN; + + GPIO->USARTROUTE[spiPortNum].TXROUTE = ((uint32_t)initData->portTx << _GPIO_USART_TXROUTE_PORT_SHIFT) | + ((uint32_t)initData->pinTx << _GPIO_USART_TXROUTE_PIN_SHIFT); + + GPIO->USARTROUTE[spiPortNum].RXROUTE = ((uint32_t)initData->portRx << _GPIO_USART_RXROUTE_PORT_SHIFT) | + ((uint32_t)initData->pinRx << _GPIO_USART_RXROUTE_PIN_SHIFT); + + GPIO->USARTROUTE[spiPortNum].CLKROUTE = ((uint32_t)initData->portClk << _GPIO_USART_CLKROUTE_PORT_SHIFT) | + ((uint32_t)initData->pinClk << _GPIO_USART_CLKROUTE_PIN_SHIFT); +#else + handle->peripheral.usartPort->ROUTE = USART_ROUTE_TXPEN | USART_ROUTE_RXPEN | USART_ROUTE_CLKPEN | + (initData->portLocation << _USART_ROUTE_LOCATION_SHIFT); +#endif + } + + if ((retVal = ConfigGPIO(handle, true)) != ECODE_EMDRV_SPIDRV_OK) + { + return retVal; + } + + CORE_ENTER_ATOMIC(); + if (!spidrvIsInitialized) + { + spidrvIsInitialized = true; + CORE_EXIT_ATOMIC(); + } + else + { + CORE_EXIT_ATOMIC(); + } + + // Initialize DMA. + DMADRV_Init(); + + if (DMADRV_AllocateChannel(&handle->txDMACh, NULL) != ECODE_EMDRV_DMADRV_OK) + { + return ECODE_EMDRV_SPIDRV_DMA_ALLOC_ERROR; + } + + if (DMADRV_AllocateChannel(&handle->rxDMACh, NULL) != ECODE_EMDRV_DMADRV_OK) + { + return ECODE_EMDRV_SPIDRV_DMA_ALLOC_ERROR; + } + + return ECODE_EMDRV_SPIDRV_OK; +} + +// +// +// Deinitialize an SPI driver instance. +// +// This function should only be called with an initialized spidrv instance handle. +// +// @param[in] handle Pointer to an SPI driver handle. +// +// @return +// @ref ECODE_EMDRV_SPIDRV_OK on success. On failure, an appropriate +// SPIDRV @ref Ecode_t is returned. +// +Ecode_t NF_SpiDriver_DeInit(NF_SpiDriver_Handle_t handle) +{ + if (handle == NULL) + { + return ECODE_EMDRV_SPIDRV_ILLEGAL_HANDLE; + } + + // Stop DMAs. + DMADRV_StopTransfer(handle->rxDMACh); + DMADRV_StopTransfer(handle->txDMACh); + + ConfigGPIO(handle, false); + + if (0) + { + } + else if (handle->peripheralType == spidrvPeripheralTypeUsart) + { + USART_Reset(handle->peripheral.usartPort); + } + + CMU_ClockEnable(handle->usartClock, false); + + DMADRV_FreeChannel(handle->txDMACh); + DMADRV_FreeChannel(handle->rxDMACh); + DMADRV_DeInit(); + emRequestDeinit(handle); + + return ECODE_EMDRV_SPIDRV_OK; +} + +// +// +// Abort an ongoing SPI transfer. +// @param[in] handle Pointer to an SPI driver handle. +// +// @return +// @ref ECODE_EMDRV_SPIDRV_OK on success, @ref ECODE_EMDRV_SPIDRV_IDLE if +// SPI is idle. On failure, an appropriate SPIDRV @ref Ecode_t is returned. +// +Ecode_t NF_SpiDriver_AbortTransfer(NF_SpiDriver_Handle_t handle) +{ + CORE_DECLARE_IRQ_STATE; + + if (handle == NULL) + { + return ECODE_EMDRV_SPIDRV_ILLEGAL_HANDLE; + } + + CORE_ENTER_ATOMIC(); + if (handle->state == spidrvStateIdle) + { + CORE_EXIT_ATOMIC(); + return ECODE_EMDRV_SPIDRV_IDLE; + } + + // Stop DMA's. + DMADRV_StopTransfer(handle->rxDMACh); + DMADRV_StopTransfer(handle->txDMACh); + DMADRV_TransferRemainingCount(handle->rxDMACh, &handle->remaining); + handle->transferStatus = ECODE_EMDRV_SPIDRV_ABORTED; + handle->state = spidrvStateIdle; + handle->transferStatus = ECODE_EMDRV_SPIDRV_ABORTED; + handle->blockingCompleted = true; + // signal RTOS event + tx_event_flags_set(&nanoHardwareEvents, NANO_HW_EVENTS_SPI_TRANSACTION_FLAG, TX_OR); + + em1RequestRemove(handle); + + if (handle->userCallback != NULL) + { + handle->userCallback(handle, ECODE_EMDRV_SPIDRV_ABORTED, handle->transferCount - handle->remaining); + } + CORE_EXIT_ATOMIC(); + + return ECODE_EMDRV_SPIDRV_OK; +} + +// +// +// Get current SPI bus bitrate. +// +// @param[in] handle Pointer to an SPI driver handle. +// +// @param[out] bitRate Current SPI bus bitrate. +// +// @return +// @ref ECODE_EMDRV_SPIDRV_OK on success. On failure, an appropriate SPIDRV +// @ref Ecode_t is returned. +// +Ecode_t NF_SpiDriver_GetBitrate(NF_SpiDriver_Handle_t handle, uint32_t *bitRate) +{ + if (handle == NULL) + { + return ECODE_EMDRV_SPIDRV_ILLEGAL_HANDLE; + } + + if (bitRate == NULL) + { + return ECODE_EMDRV_SPIDRV_PARAM_ERROR; + } + + if (0) + { + } + else if (handle->peripheralType == spidrvPeripheralTypeUsart) + { + *bitRate = USART_BaudrateGet(handle->peripheral.usartPort); + } + + return ECODE_EMDRV_SPIDRV_OK; +} + +// +// +// Get current SPI framelength. +// +// @param[in] handle Pointer to an SPI driver handle. +// +// @param[out] frameLength Current SPI bus framelength. +// +// @return +// @ref ECODE_EMDRV_SPIDRV_OK on success. On failure, an appropriate SPIDRV +// @ref Ecode_t is returned. +// +Ecode_t NF_SpiDriver_GetFramelength(NF_SpiDriver_Handle_t handle, uint32_t *frameLength) +{ + if (handle == NULL) + { + return ECODE_EMDRV_SPIDRV_ILLEGAL_HANDLE; + } + + if (frameLength == NULL) + { + return ECODE_EMDRV_SPIDRV_PARAM_ERROR; + } + + *frameLength = handle->initData->frameLength; + + return ECODE_EMDRV_SPIDRV_OK; +} + +// +// +// Get the status of an SPI transfer. +// +// @details +// Returns status of an ongoing transfer. If no transfer is in progress, +// the status of the last transfer is reported. +// +// @param[in] handle Pointer to an SPI driver handle. +// +// @param[out] itemsTransferred Number of items (frames) transferred. +// +// @param[out] itemsRemaining Number of items (frames) remaining. +// +// @return +// @ref ECODE_EMDRV_SPIDRV_OK on success. On failure, an appropriate SPIDRV +// @ref Ecode_t is returned. +// +Ecode_t NF_SpiDriver_GetTransferStatus(NF_SpiDriver_Handle_t handle, int *itemsTransferred, int *itemsRemaining) +{ + int remaining; + + if (handle == NULL) + { + return ECODE_EMDRV_SPIDRV_ILLEGAL_HANDLE; + } + + if ((itemsTransferred == NULL) || (itemsRemaining == NULL)) + { + return ECODE_EMDRV_SPIDRV_PARAM_ERROR; + } + + CORE_ATOMIC_SECTION( + if (handle->state == spidrvStateIdle) { remaining = handle->remaining; } else { + DMADRV_TransferRemainingCount(handle->rxDMACh, &remaining); + }) + + // itemsTransferred = (handle->transferCount - remaining); + *itemsRemaining = remaining; + + return ECODE_EMDRV_SPIDRV_OK; +} + +// +// +// Start an SPI master receive transfer. +// +// @note +// The MOSI wire will transmit @ref SPIDRV_Init.dummyTxValue. +// +// @param[in] handle Pointer to an SPI driver handle. +// +// @param[out] buffer Receive data buffer. +// +// @param[in] count Number of bytes in transfer. +// +// @param[in] callback Transfer completion callback. +// +// @return +// @ref ECODE_EMDRV_SPIDRV_OK on success. On failure, an appropriate SPIDRV +// @ref Ecode_t is returned. +// +Ecode_t NF_SpiDriver_Receive(NF_SpiDriver_Handle_t handle, void *buffer, int count, NF_SpiDriver_Callback_t callback) +{ + Ecode_t retVal; + + if ((retVal = TransferApiPrologue(handle, buffer, count)) != ECODE_EMDRV_SPIDRV_OK) + { + return retVal; + } + + StartReceiveDMA(handle, buffer, count, callback); + + return ECODE_EMDRV_SPIDRV_OK; +} + +// +// +// Start an SPI master blocking receive transfer. +// +// @note +// The MOSI wire will transmit @ref SPIDRV_Init.dummyTxValue. +// @n This function is blocking and returns when the transfer is complete +// or when @ref SPIDRV_AbortTransfer() is called. +// +// @param[in] handle Pointer to an SPI driver handle. +// +// @param[out] buffer Receive data buffer. +// +// @param[in] count Number of bytes in transfer. +// +// @return +// @ref ECODE_EMDRV_SPIDRV_OK on success or @ref ECODE_EMDRV_SPIDRV_ABORTED +// if @ref SPIDRV_AbortTransfer() has been called. On failure, an appropriate +// SPIDRV @ref Ecode_t is returned. +// +Ecode_t NF_SpiDriver_ReceiveBlocking(NF_SpiDriver_Handle_t handle, void *buffer, int count) +{ + Ecode_t retVal; + + if ((retVal = TransferApiBlockingPrologue(handle, buffer, count)) != ECODE_EMDRV_SPIDRV_OK) + { + return retVal; + } + + StartReceiveDMA(handle, buffer, count, BlockingComplete); + + WaitForTransferCompletion(handle); + + return handle->transferStatus; +} + +// +// +// Start an SPI master transfer. +// +// @param[in] handle Pointer to an SPI driver handle. +// +// @param[in] txBuffer Transmit data buffer. +// +// @param[out] rxBuffer Receive data buffer. +// +// @param[in] count Number of bytes in transfer. +// +// @param[in] callback Transfer completion callback. +// +// @return +// @ref ECODE_EMDRV_SPIDRV_OK on success. On failure, an appropriate SPIDRV +// @ref Ecode_t is returned. +// +Ecode_t NF_SpiDriver_Transfer( + NF_SpiDriver_Handle_t handle, + const void *txBuffer, + void *rxBuffer, + int count, + NF_SpiDriver_Callback_t callback) +{ + Ecode_t retVal; + + if ((retVal = TransferApiPrologue(handle, (void *)txBuffer, count)) != ECODE_EMDRV_SPIDRV_OK) + { + return retVal; + } + + if (rxBuffer == NULL) + { + return ECODE_EMDRV_SPIDRV_PARAM_ERROR; + } + + StartTransferDMA(handle, txBuffer, rxBuffer, count, callback); + + return ECODE_EMDRV_SPIDRV_OK; +} + +// +// +// Start an SPI master blocking transfer. +// +// @note +// This function is blocking and returns when the transfer is complete +// or when @ref SPIDRV_AbortTransfer() is called. +// +// @param[in] handle Pointer to an SPI driver handle. +// +// @param[in] txBuffer Transmit data buffer. +// +// @param[out] rxBuffer Receive data buffer. +// +// @param[in] count Number of bytes in transfer. +// +// @return +// @ref ECODE_EMDRV_SPIDRV_OK on success or @ref ECODE_EMDRV_SPIDRV_ABORTED +// if @ref SPIDRV_AbortTransfer() has been called. On failure, an appropriate +// SPIDRV @ref Ecode_t is returned. +// +Ecode_t NF_SpiDriver_TransferBlocking(NF_SpiDriver_Handle_t handle, const void *txBuffer, void *rxBuffer, int count) +{ + Ecode_t retVal; + + if ((retVal = TransferApiBlockingPrologue(handle, (void *)txBuffer, count)) != ECODE_EMDRV_SPIDRV_OK) + { + return retVal; + } + + if (rxBuffer == NULL) + { + return ECODE_EMDRV_SPIDRV_PARAM_ERROR; + } + + StartTransferDMA(handle, txBuffer, rxBuffer, count, BlockingComplete); + + WaitForTransferCompletion(handle); + + return handle->transferStatus; +} + +// +// +// Start an SPI master transmit transfer. +// +// @note +// The data received on the MISO wire is discarded. +// +// @param[in] handle Pointer to an SPI driver handle. +// +// @param[in] buffer Transmit data buffer. +// +// @param[in] count Number of bytes in transfer. +// +// @param[in] callback Transfer completion callback. +// +// @return +// @ref ECODE_EMDRV_SPIDRV_OK on success. On failure, an appropriate SPIDRV +// @ref Ecode_t is returned. +// +Ecode_t NF_SpiDriver_Transmit( + NF_SpiDriver_Handle_t handle, + const void *buffer, + int count, + NF_SpiDriver_Callback_t callback) +{ + Ecode_t retVal; + + if ((retVal = TransferApiPrologue(handle, (void *)buffer, count)) != ECODE_EMDRV_SPIDRV_OK) + { + return retVal; + } + + StartTransmitDMA(handle, buffer, count, callback); + + return ECODE_EMDRV_SPIDRV_OK; +} + +// +// +// Start an SPI master blocking transmit transfer. +// +// @note +// The data received on the MISO wire is discarded. +// @n This function is blocking and returns when the transfer is complete. +// +// @param[in] handle Pointer to an SPI driver handle. +// +// @param[in] buffer Transmit data buffer. +// +// @param[in] count Number of bytes in transfer. +// +// @return +// @ref ECODE_EMDRV_SPIDRV_OK on success or @ref ECODE_EMDRV_SPIDRV_ABORTED +// if @ref SPIDRV_AbortTransfer() has been called. On failure, an appropriate +// SPIDRV @ref Ecode_t is returned. +// +Ecode_t NF_SpiDriver_TransmitBlocking(NF_SpiDriver_Handle_t handle, const void *buffer, int count) +{ + Ecode_t retVal; + + if ((retVal = TransferApiBlockingPrologue(handle, (void *)buffer, count)) != ECODE_EMDRV_SPIDRV_OK) + { + return retVal; + } + + StartTransmitDMA(handle, buffer, count, BlockingComplete); + + WaitForTransferCompletion(handle); + + return handle->transferStatus; +} + +// +// +// Set SPI bus bitrate. +// +// @param[in] handle Pointer to an SPI driver handle. +// +// @param[in] bitRate New SPI bus bitrate. +// +// @return +// @ref ECODE_EMDRV_SPIDRV_OK on success. On failure, an appropriate SPIDRV +// @ref Ecode_t is returned. +// +Ecode_t NF_SpiDriver_SetBitrate(NF_SpiDriver_Handle_t handle, uint32_t bitRate) +{ + CORE_DECLARE_IRQ_STATE; + + if (handle == NULL) + { + return ECODE_EMDRV_SPIDRV_ILLEGAL_HANDLE; + } + + CORE_ENTER_ATOMIC(); + if (handle->state != spidrvStateIdle) + { + CORE_EXIT_ATOMIC(); + return ECODE_EMDRV_SPIDRV_BUSY; + } + + handle->initData->bitRate = bitRate; + + if (0) + { + } + else if (handle->peripheralType == spidrvPeripheralTypeUsart) + { + USART_BaudrateSyncSet(handle->peripheral.usartPort, 0, bitRate); + } + CORE_EXIT_ATOMIC(); + + return ECODE_EMDRV_SPIDRV_OK; +} + +// +// +// Set SPI framelength. +// +// @param[in] handle Pointer to an SPI driver handle. +// +// @param[in] frameLength New SPI bus framelength. +// +// @return +// @ref ECODE_EMDRV_SPIDRV_OK on success. On failure, an appropriate SPIDRV +// @ref Ecode_t is returned. +// +Ecode_t NF_SpiDriver_SetFramelength(NF_SpiDriver_Handle_t handle, uint32_t frameLength) +{ + CORE_DECLARE_IRQ_STATE; + + if (handle == NULL) + { + return ECODE_EMDRV_SPIDRV_ILLEGAL_HANDLE; + } + + if (0) + { + } + else if (handle->peripheralType == spidrvPeripheralTypeUsart) + { + frameLength -= EMDRV_SPIDRV_USART_FRAMELENGTH_REGVALUE_OFFSET; + + if ((frameLength < _USART_FRAME_DATABITS_FOUR) || (frameLength > _USART_FRAME_DATABITS_SIXTEEN)) + { + return ECODE_EMDRV_SPIDRV_PARAM_ERROR; + } + } + + CORE_ENTER_ATOMIC(); + if (handle->state != spidrvStateIdle) + { + CORE_EXIT_ATOMIC(); + return ECODE_EMDRV_SPIDRV_BUSY; + } + + if (0) + { + } + else if (handle->peripheralType == spidrvPeripheralTypeUsart) + { + handle->initData->frameLength = frameLength + EMDRV_SPIDRV_USART_FRAMELENGTH_REGVALUE_OFFSET; + + handle->peripheral.usartPort->FRAME = (handle->peripheral.usartPort->FRAME & ~_USART_FRAME_DATABITS_MASK) | + (frameLength << _USART_FRAME_DATABITS_SHIFT); + } + CORE_EXIT_ATOMIC(); + + return ECODE_EMDRV_SPIDRV_OK; +} + +// +// +// Transfer complete callback function used by blocking transfer API +// functions. Called by DMA interrupt handler, timer timeout handler +// or @ref SPIDRV_AbortTransfer() function. +// +static void BlockingComplete(NF_SpiDriver_Handle_t handle, Ecode_t transferStatus, int itemsTransferred) +{ + (void)itemsTransferred; + + handle->transferStatus = transferStatus; + handle->blockingCompleted = true; + // signal RTOS event + tx_event_flags_set(&nanoHardwareEvents, NANO_HW_EVENTS_SPI_TRANSACTION_FLAG, TX_OR); +} + +#if defined(_SILICON_LABS_32B_SERIES_1) +// +// Get SPI pins for Series 1 devices. +// +static Ecode_t GetSpiPins(NF_SpiDriver_Handle_t handle, SPI_Pins_t *pins) +{ + if (0) + { +#if defined(USART0) + } + else if (handle->peripheral.usartPort == USART0) + { + pins->mosiPort = AF_USART0_TX_PORT(handle->initData->portLocationTx); + pins->misoPort = AF_USART0_RX_PORT(handle->initData->portLocationRx); + pins->clkPort = AF_USART0_CLK_PORT(handle->initData->portLocationClk); + pins->csPort = AF_USART0_CS_PORT(handle->initData->portLocationCs); + pins->mosiPin = AF_USART0_TX_PIN(handle->initData->portLocationTx); + pins->misoPin = AF_USART0_RX_PIN(handle->initData->portLocationRx); + pins->clkPin = AF_USART0_CLK_PIN(handle->initData->portLocationClk); + pins->csPin = AF_USART0_CS_PIN(handle->initData->portLocationCs); +#endif +#if defined(USART1) + } + else if (handle->peripheral.usartPort == USART1) + { + pins->mosiPort = AF_USART1_TX_PORT(handle->initData->portLocationTx); + pins->misoPort = AF_USART1_RX_PORT(handle->initData->portLocationRx); + pins->clkPort = AF_USART1_CLK_PORT(handle->initData->portLocationClk); + pins->csPort = AF_USART1_CS_PORT(handle->initData->portLocationCs); + pins->mosiPin = AF_USART1_TX_PIN(handle->initData->portLocationTx); + pins->misoPin = AF_USART1_RX_PIN(handle->initData->portLocationRx); + pins->clkPin = AF_USART1_CLK_PIN(handle->initData->portLocationClk); + pins->csPin = AF_USART1_CS_PIN(handle->initData->portLocationCs); +#endif +#if defined(USART2) + } + else if (handle->peripheral.usartPort == USART2) + { + pins->mosiPort = AF_USART2_TX_PORT(handle->initData->portLocationTx); + pins->misoPort = AF_USART2_RX_PORT(handle->initData->portLocationRx); + pins->clkPort = AF_USART2_CLK_PORT(handle->initData->portLocationClk); + pins->csPort = AF_USART2_CS_PORT(handle->initData->portLocationCs); + pins->mosiPin = AF_USART2_TX_PIN(handle->initData->portLocationTx); + pins->misoPin = AF_USART2_RX_PIN(handle->initData->portLocationRx); + pins->clkPin = AF_USART2_CLK_PIN(handle->initData->portLocationClk); + pins->csPin = AF_USART2_CS_PIN(handle->initData->portLocationCs); +#endif +#if defined(USART3) + } + else if (handle->peripheral.usartPort == USART3) + { + pins->mosiPort = AF_USART3_TX_PORT(handle->initData->portLocationTx); + pins->misoPort = AF_USART3_RX_PORT(handle->initData->portLocationRx); + pins->clkPort = AF_USART3_CLK_PORT(handle->initData->portLocationClk); + pins->csPort = AF_USART3_CS_PORT(handle->initData->portLocationCs); + pins->mosiPin = AF_USART3_TX_PIN(handle->initData->portLocationTx); + pins->misoPin = AF_USART3_RX_PIN(handle->initData->portLocationRx); + pins->clkPin = AF_USART3_CLK_PIN(handle->initData->portLocationClk); + pins->csPin = AF_USART3_CS_PIN(handle->initData->portLocationCs); +#endif +#if defined(USART4) + } + else if (handle->peripheral.usartPort == USART4) + { + pins->mosiPort = AF_USART4_TX_PORT(handle->initData->portLocationTx); + pins->misoPort = AF_USART4_RX_PORT(handle->initData->portLocationRx); + pins->clkPort = AF_USART4_CLK_PORT(handle->initData->portLocationClk); + pins->csPort = AF_USART4_CS_PORT(handle->initData->portLocationCs); + pins->mosiPin = AF_USART4_TX_PIN(handle->initData->portLocationTx); + pins->misoPin = AF_USART4_RX_PIN(handle->initData->portLocationRx); + pins->clkPin = AF_USART4_CLK_PIN(handle->initData->portLocationClk); + pins->csPin = AF_USART4_CS_PIN(handle->initData->portLocationCs); +#endif +#if defined(USART5) + } + else if (handle->peripheral.usartPort == USART5) + { + pins->mosiPort = AF_USART5_TX_PORT(handle->initData->portLocationTx); + pins->misoPort = AF_USART5_RX_PORT(handle->initData->portLocationRx); + pins->clkPort = AF_USART5_CLK_PORT(handle->initData->portLocationClk); + pins->csPort = AF_USART5_CS_PORT(handle->initData->portLocationCs); + pins->mosiPin = AF_USART5_TX_PIN(handle->initData->portLocationTx); + pins->misoPin = AF_USART5_RX_PIN(handle->initData->portLocationRx); + pins->clkPin = AF_USART5_CLK_PIN(handle->initData->portLocationClk); + pins->csPin = AF_USART5_CS_PIN(handle->initData->portLocationCs); +#endif + } + else + { + return ECODE_EMDRV_SPIDRV_PARAM_ERROR; + } + return ECODE_EMDRV_SPIDRV_OK; +} +#endif + +#if defined(_SILICON_LABS_32B_SERIES_2) +// +// Get SPI pins for Series 2 devices. +// +static Ecode_t GetSpiPins(NF_SpiDriver_Handle_t handle, SPI_Pins_t// pins) +{ + pins->mosiPort = handle->initData->portTx; + pins->misoPort = handle->initData->portRx; + pins->clkPort = handle->initData->portClk; + pins->csPort = handle->initData->portCs; + pins->mosiPin = handle->initData->pinTx; + pins->misoPin = handle->initData->pinRx; + pins->clkPin = handle->initData->pinClk; + pins->csPin = handle->initData->pinCs; + + return ECODE_EMDRV_SPIDRV_OK; +} +#endif + +// +// Configure/deconfigure SPI GPIO pins. +// +static Ecode_t ConfigGPIO(NF_SpiDriver_Handle_t handle, bool enable) +{ + SPI_Pins_t pins; + Ecode_t ret; + + ret = GetSpiPins(handle, &pins); + if (ret != ECODE_EMDRV_SPIDRV_OK) + { + return ret; + } + handle->portCs = (GPIO_Port_TypeDef)pins.csPort; + handle->pinCs = pins.csPin; + + if (enable) + { + GPIO_PinModeSet((GPIO_Port_TypeDef)pins.mosiPort, pins.mosiPin, gpioModePushPull, 0); + GPIO_PinModeSet((GPIO_Port_TypeDef)pins.misoPort, pins.misoPin, gpioModeInput, 0); + + if ((handle->initData->clockMode == spidrvClockMode0) || (handle->initData->clockMode == spidrvClockMode1)) + { + GPIO_PinModeSet((GPIO_Port_TypeDef)pins.clkPort, pins.clkPin, gpioModePushPull, 0); + } + else + { + GPIO_PinModeSet((GPIO_Port_TypeDef)pins.clkPort, pins.clkPin, gpioModePushPull, 1); + } + + if (handle->initData->csControl == spidrvCsControlAuto) + { + GPIO_PinModeSet((GPIO_Port_TypeDef)handle->portCs, handle->pinCs, gpioModePushPull, 1); + } + } + else + { + GPIO_PinModeSet((GPIO_Port_TypeDef)pins.mosiPort, pins.mosiPin, gpioModeInputPull, 0); + GPIO_PinModeSet((GPIO_Port_TypeDef)pins.misoPort, pins.misoPin, gpioModeInputPull, 0); + + if ((handle->initData->clockMode == spidrvClockMode0) || (handle->initData->clockMode == spidrvClockMode1)) + { + GPIO_PinModeSet((GPIO_Port_TypeDef)pins.clkPort, pins.clkPin, gpioModeInputPull, 0); + } + else + { + GPIO_PinModeSet((GPIO_Port_TypeDef)pins.clkPort, pins.clkPin, gpioModeInputPull, 1); + } + + if (handle->initData->csControl == spidrvCsControlAuto) + { + GPIO_PinModeSet((GPIO_Port_TypeDef)handle->portCs, handle->pinCs, gpioModeDisabled, 0); + } + } + + return ECODE_EMDRV_SPIDRV_OK; +} + +// +// DMA transfer completion callback. Called by the DMA interrupt handler. +// +static bool RxDMAComplete(unsigned int channel, + unsigned int sequenceNo, + void *userParam) +{ + CORE_DECLARE_IRQ_STATE; + NF_SpiDriver_Handle_t handle; + (void)channel; + (void)sequenceNo; + + CORE_ENTER_ATOMIC(); + + handle = (NF_SpiDriver_Handle_t)userParam; + + if (handle->initData->isHalfDuplex) + { + // Turn off TX tri-stating + handle->peripheral.usartPort->CMD = USART_CMD_TXTRIDIS; + } + + handle->transferStatus = ECODE_EMDRV_SPIDRV_OK; + handle->state = spidrvStateIdle; + handle->remaining = 0; + + if (handle->userCallback != NULL) + { + handle->userCallback(handle, ECODE_EMDRV_SPIDRV_OK, handle->transferCount); + } + + CORE_EXIT_ATOMIC(); + em1RequestRemove(handle); + + return true; +} + +// +// Start an SPI receive DMA. +// +static void StartReceiveDMA(NF_SpiDriver_Handle_t handle, + void *buffer, + int count, + NF_SpiDriver_Callback_t callback) +{ + void *rxPort, *txPort; + DMADRV_DataSize_t size; + + handle->blockingCompleted = false; + handle->transferCount = count; + handle->userCallback = callback; + + if (0) + { + } + else if (handle->peripheralType == spidrvPeripheralTypeUsart) + { + handle->peripheral.usartPort->CMD = USART_CMD_CLEARRX | USART_CMD_CLEARTX; + + if (handle->initData->isHalfDuplex) + { + // Block RX while sending from master + handle->peripheral.usartPort->CMD = USART_CMD_RXBLOCKEN; + } + + if (handle->initData->frameLength > 9) + { + rxPort = (void *)&(handle->peripheral.usartPort->RXDOUBLE); + txPort = (void *)&(handle->peripheral.usartPort->TXDOUBLE); + } + else if (handle->initData->frameLength == 9) + { + rxPort = (void *)&(handle->peripheral.usartPort->RXDATAX); + txPort = (void *)&(handle->peripheral.usartPort->TXDATAX); + } + else + { + rxPort = (void *)&(handle->peripheral.usartPort->RXDATA); + txPort = (void *)&(handle->peripheral.usartPort->TXDATA); + } + } + else + { + return; + } + + if (handle->initData->frameLength > 8) + { + size = dmadrvDataSize2; + } + else + { + size = dmadrvDataSize1; + } + + em1RequestAdd(handle); + + // Start receive DMA. + DMADRV_PeripheralMemory( + handle->rxDMACh, + handle->rxDMASignal, + (void *)buffer, + rxPort, + true, + count, + size, + RxDMAComplete, + handle); + + // Start transmit DMA. + DMADRV_MemoryPeripheral( + handle->txDMACh, + handle->txDMASignal, + txPort, + (void *)&(handle->initData->dummyTxValue), + false, + count, + size, + NULL, + NULL); +} + +// +// Start an SPI transmit/receive DMA. +// +static void StartTransferDMA(NF_SpiDriver_Handle_t handle, + const void *txBuffer, + void *rxBuffer, + int count, + NF_SpiDriver_Callback_t callback) +{ + void *rxPort, *txPort; + DMADRV_DataSize_t size; + + handle->blockingCompleted = false; + handle->transferCount = count; + handle->userCallback = callback; + + if (0) + { + } + else if (handle->peripheralType == spidrvPeripheralTypeUsart) + { + handle->peripheral.usartPort->CMD = USART_CMD_CLEARRX | USART_CMD_CLEARTX; + + if (handle->initData->frameLength > 9) + { + rxPort = (void *)&(handle->peripheral.usartPort->RXDOUBLE); + txPort = (void *)&(handle->peripheral.usartPort->TXDOUBLE); + } + else if (handle->initData->frameLength == 9) + { + rxPort = (void *)&(handle->peripheral.usartPort->RXDATAX); + txPort = (void *)&(handle->peripheral.usartPort->TXDATAX); + } + else + { + rxPort = (void *)&(handle->peripheral.usartPort->RXDATA); + txPort = (void *)&(handle->peripheral.usartPort->TXDATA); + } + } + else + { + return; + } + + if (handle->initData->frameLength > 8) + { + size = dmadrvDataSize2; + } + else + { + size = dmadrvDataSize1; + } + + em1RequestAdd(handle); + + // Start receive DMA. + DMADRV_PeripheralMemory( + handle->rxDMACh, + handle->rxDMASignal, + rxBuffer, + rxPort, + true, + count, + size, + RxDMAComplete, + handle); + + // Start transmit DMA. + DMADRV_MemoryPeripheral( + handle->txDMACh, + handle->txDMASignal, + txPort, + (void *)txBuffer, + true, + count, + size, + NULL, + NULL); +} + +// +// Start an SPI transmit DMA. +// +static void StartTransmitDMA(NF_SpiDriver_Handle_t handle, + const void *buffer, + int count, + NF_SpiDriver_Callback_t callback) +{ + void *rxPort, *txPort; + DMADRV_DataSize_t size; + + handle->blockingCompleted = false; + handle->transferCount = count; + handle->userCallback = callback; + + if (0) + { + } + else if (handle->peripheralType == spidrvPeripheralTypeUsart) + { + handle->peripheral.usartPort->CMD = USART_CMD_CLEARRX | USART_CMD_CLEARTX; + + if (handle->initData->frameLength > 9) + { + rxPort = (void *)&(handle->peripheral.usartPort->RXDOUBLE); + txPort = (void *)&(handle->peripheral.usartPort->TXDOUBLE); + } + else if (handle->initData->frameLength == 9) + { + rxPort = (void *)&(handle->peripheral.usartPort->RXDATAX); + txPort = (void *)&(handle->peripheral.usartPort->TXDATAX); + } + else + { + rxPort = (void *)&(handle->peripheral.usartPort->RXDATA); + txPort = (void *)&(handle->peripheral.usartPort->TXDATA); + } + } + else + { + return; + } + + if (handle->initData->frameLength > 8) + { + size = dmadrvDataSize2; + } + else + { + size = dmadrvDataSize1; + } + + em1RequestAdd(handle); + + // Receive DMA runs only to get precise numbers for SPIDRV_GetTransferStatus() + // Start receive DMA. + DMADRV_PeripheralMemory( + handle->rxDMACh, + handle->rxDMASignal, + &(handle->dummyRx), + rxPort, + false, + count, + size, + RxDMAComplete, + handle); + + // Start transmit DMA. + DMADRV_MemoryPeripheral( + handle->txDMACh, + handle->txDMASignal, + txPort, + (void *)buffer, + true, + count, + size, + NULL, + NULL); +} + +// +// Parameter checking function for blocking transfer API functions. +// +static Ecode_t TransferApiBlockingPrologue(NF_SpiDriver_Handle_t handle, + void *buffer, + int count) +{ + CORE_DECLARE_IRQ_STATE; + + if (handle == NULL) + { + return ECODE_EMDRV_SPIDRV_ILLEGAL_HANDLE; + } + + if ((buffer == NULL) || (count == 0) || (count > DMADRV_MAX_XFER_COUNT)) + { + return ECODE_EMDRV_SPIDRV_PARAM_ERROR; + } + + CORE_ENTER_ATOMIC(); + if (handle->state != spidrvStateIdle) + { + CORE_EXIT_ATOMIC(); + return ECODE_EMDRV_SPIDRV_BUSY; + } + handle->state = spidrvStateTransferring; + CORE_EXIT_ATOMIC(); + + return ECODE_EMDRV_SPIDRV_OK; +} + +// +// Parameter checking function for non-blocking transfer API functions. +// +static Ecode_t TransferApiPrologue(NF_SpiDriver_Handle_t handle, + void *buffer, + int count) +{ + CORE_DECLARE_IRQ_STATE; + + if (handle == NULL) + { + return ECODE_EMDRV_SPIDRV_ILLEGAL_HANDLE; + } + + if ((buffer == NULL) || (count == 0) || (count > DMADRV_MAX_XFER_COUNT)) + { + return ECODE_EMDRV_SPIDRV_PARAM_ERROR; + } + + CORE_ENTER_ATOMIC(); + if (handle->state != spidrvStateIdle) + { + CORE_EXIT_ATOMIC(); + return ECODE_EMDRV_SPIDRV_BUSY; + } + handle->state = spidrvStateTransferring; + CORE_EXIT_ATOMIC(); + + return ECODE_EMDRV_SPIDRV_OK; +} + +// +// @brief Wait for transfer completion. +// +static void WaitForTransferCompletion(NF_SpiDriver_Handle_t handle) +{ + uint32_t dummy; + + if (CORE_IrqIsBlocked(SPI_DMA_IRQ)) + { + // Poll for completion by calling IRQ handler. + while (handle->blockingCompleted == false) + { +#if defined(DMA_PRESENT) && (DMA_COUNT == 1) + DMA_IRQHandler(); +#elif defined(LDMA_PRESENT) && (LDMA_COUNT == 1) + LDMA_IRQHandler(); +#else +#error "No valid SPIDRV DMA engine defined." +#endif + } + } + else + { + // wait forever for the SPI event + tx_event_flags_get( + &nanoHardwareEvents, + NANO_HW_EVENTS_SPI_TRANSACTION_FLAG, + TX_OR_CLEAR, + &dummy, + TX_WAIT_FOREVER); + } +} diff --git a/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.Spi/nf_gecko_spi_driver.h b/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.Spi/nf_gecko_spi_driver.h new file mode 100644 index 0000000000..39e17cbaf9 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.Spi/nf_gecko_spi_driver.h @@ -0,0 +1,214 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#ifndef NF_GECKO_SPI_DRIVER_H +#define NF_GECKO_SPI_DRIVER_H + +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#if defined(DMA_PRESENT) && (DMA_COUNT == 1) +#define SPI_DMA_IRQ DMA_IRQn + +#elif defined(LDMA_PRESENT) && (LDMA_COUNT == 1) +#define SPI_DMA_IRQ LDMA_IRQn + +#else +#error "No valid SPIDRV DMA engine defined." +#endif + +// flags for hardware events +extern TX_EVENT_FLAGS_GROUP nanoHardwareEvents; + +#ifdef __cplusplus +extern "C" +{ +#endif + + // clang-format off + +#define ECODE_EMDRV_SPIDRV_OK (ECODE_OK) ///< A successful return value. +#define ECODE_EMDRV_SPIDRV_ILLEGAL_HANDLE (ECODE_EMDRV_SPIDRV_BASE | 0x00000001) ///< An illegal SPI handle. +#define ECODE_EMDRV_SPIDRV_PARAM_ERROR (ECODE_EMDRV_SPIDRV_BASE | 0x00000002) ///< An illegal input parameter. +#define ECODE_EMDRV_SPIDRV_BUSY (ECODE_EMDRV_SPIDRV_BASE | 0x00000003) ///< The SPI port is busy. +#define ECODE_EMDRV_SPIDRV_TIMER_ALLOC_ERROR (ECODE_EMDRV_SPIDRV_BASE | 0x00000004) ///< Unable to allocate timeout timer. +#define ECODE_EMDRV_SPIDRV_TIMEOUT (ECODE_EMDRV_SPIDRV_BASE | 0x00000005) ///< An SPI transfer timeout. +#define ECODE_EMDRV_SPIDRV_IDLE (ECODE_EMDRV_SPIDRV_BASE | 0x00000006) ///< No SPI transfer in progress. +#define ECODE_EMDRV_SPIDRV_ABORTED (ECODE_EMDRV_SPIDRV_BASE | 0x00000007) ///< An SPI transfer has been aborted. +#define ECODE_EMDRV_SPIDRV_MODE_ERROR (ECODE_EMDRV_SPIDRV_BASE | 0x00000008) ///< SPI master used slave API or vice versa. +#define ECODE_EMDRV_SPIDRV_DMA_ALLOC_ERROR (ECODE_EMDRV_SPIDRV_BASE | 0x00000009) ///< Unable to allocate DMA channels. + + // clang-format on + + /// SPI driver instance type. + SL_ENUM(NF_SpiDriver_Type_t){ + spidrvMaster = 0, ///< Act as an SPI master. + }; + + /// SPI bus bit order. + SL_ENUM(NF_SpiDriver_BitOrder_t){ + spidrvBitOrderLsbFirst = 0, ///< LSB bit is transmitted first. + spidrvBitOrderMsbFirst = 1 ///< MSB bit is transmitted first. + }; + + /// SPI clock mode (clock polarity and phase). + SL_ENUM(NF_SpiDriver_ClockMode_t){ + spidrvClockMode0 = 0, ///< SPI mode 0: CLKPOL=0, CLKPHA=0. + spidrvClockMode1 = 1, ///< SPI mode 1: CLKPOL=0, CLKPHA=1. + spidrvClockMode2 = 2, ///< SPI mode 2: CLKPOL=1, CLKPHA=0. + spidrvClockMode3 = 3 ///< SPI mode 3: CLKPOL=1, CLKPHA=1. + }; + + /// SPI master chip select (CS) control scheme. + SL_ENUM(NF_SpiDriver_CsControl_t){ + spidrvCsControlAuto = 0, ///< CS controlled by the SPI driver. + spidrvCsControlApplication = 1 ///< CS controlled by the application. + }; + + /// SPI slave transfer start scheme. + SL_ENUM(NF_SpiDriver_SlaveStart_t){ + spidrvSlaveStartImmediate = 0, ///< Transfer starts immediately. + spidrvSlaveStartDelayed = 1 ///< Transfer starts when the bus is idle (CS deasserted). + }; + + /// Type of a USART peripheral + SL_ENUM(NF_SpiDriver_PeripheralType_t) + { + spidrvPeripheralTypeUsart = 0, ///< USART peripheral + }; + + SL_ENUM(NF_SpiDriver_State_t){spidrvStateIdle = 0, spidrvStateTransferring = 1}; + + struct NF_SpiDriver_HandleData; + + /* + * @brief + * NF_SpiDriver transfer completion callback function. + * + * @details + * Called when a transfer is complete. An + * application should check the transferStatus and itemsTransferred values. + * + * @param[in] handle + * The NF_SpiDriver device handle used to start the transfer. + * + * @param[in] transferStatus + * A number of bytes actually transferred. + * + * @param[in] itemsTransferred + * A number of bytes transferred. + * + * @return + * @ref ECODE_EMDRV_SPIDRV_OK on success, @ref ECODE_EMDRV_SPIDRV_TIMEOUT + * on timeout. Timeouts are only relevant for slave mode transfers. + */ + typedef void (*NF_SpiDriver_Callback_t)(struct NF_SpiDriver_HandleData *handle, Ecode_t transferStatus, int itemsTransferred); + + /// An SPI driver instance initialization structure. + /// Contains a number of SPIDRV configuration options. + /// This structure is passed to @ref NF_SpiDriver_Init() when initializing a SPIDRV + /// instance. Some common initialization data sets are predefined in + /// @ref spidrv_init_structs + typedef struct NF_SpiDriver_Init + { + void *port; ///< The USART used for SPI. + uint8_t portLocationTx; ///< A location number for the SPI Tx pin. + uint8_t portLocationRx; ///< A location number for the SPI Rx pin. + uint8_t portLocationClk; ///< A location number for the SPI Clk pin. + uint8_t portLocationCs; ///< A location number for the SPI Cs pin. + uint32_t bitRate; ///< An SPI bitrate. + uint32_t frameLength; ///< An SPI framelength, valid numbers are 4..16 + uint32_t dummyTxValue; ///< The value to transmit when using SPI receive API functions. + NF_SpiDriver_BitOrder_t bitOrder; ///< A bit order on the SPI bus, MSB or LSB first. + NF_SpiDriver_ClockMode_t clockMode; ///< SPI mode, CLKPOL/CLKPHASE setting. + NF_SpiDriver_CsControl_t csControl; ///< A select master mode chip select (CS) control scheme. + bool isHalfDuplex; ///< True if the SPI is half duplex. + } NF_SpiDriver_Init_t; + + /// An SPI driver instance handle data structure. + /// The handle is allocated by the application using the SPIDRV. + /// Several concurrent driver instances can exist in an application. The application is + /// neither supposed to write or read the contents of the handle. + typedef struct NF_SpiDriver_HandleData + { + union { + USART_TypeDef *usartPort; + void *__reserved_space; + } peripheral; + NF_SpiDriver_Init_t *initData; + unsigned int txDMACh; + unsigned int rxDMACh; + DMADRV_PeripheralSignal_t txDMASignal; + DMADRV_PeripheralSignal_t rxDMASignal; + NF_SpiDriver_Callback_t userCallback; + uint32_t dummyRx; + int transferCount; + int remaining; + GPIO_Port_TypeDef portCs; + uint8_t pinCs; + Ecode_t transferStatus; + volatile NF_SpiDriver_State_t state; + CMU_Clock_TypeDef usartClock; + volatile bool blockingCompleted; + int em1RequestCount; + NF_SpiDriver_PeripheralType_t peripheralType; + sl_sleeptimer_timer_handle_t timer; + sl_slist_node_t node; + } NF_SpiDriver_HandleData_t; + + /// An SPI driver instance handle. + typedef NF_SpiDriver_HandleData_t *NF_SpiDriver_Handle_t; + + Ecode_t NF_SpiDriver_AbortTransfer(NF_SpiDriver_Handle_t handle); + + Ecode_t NF_SpiDriver_DeInit(NF_SpiDriver_Handle_t handle); + + Ecode_t NF_SpiDriver_GetBitrate(NF_SpiDriver_Handle_t handle, uint32_t *bitRate); + + Ecode_t NF_SpiDriver_GetFramelength(NF_SpiDriver_Handle_t handle, uint32_t *frameLength); + + Ecode_t NF_SpiDriver_GetTransferStatus(NF_SpiDriver_Handle_t handle, int *itemsTransferred, int *itemsRemaining); + + Ecode_t NF_SpiDriver_Init(NF_SpiDriver_Handle_t handle, NF_SpiDriver_Init_t *initData); + + Ecode_t NF_SpiDriver_Receive(NF_SpiDriver_Handle_t handle, void *buffer, int count, NF_SpiDriver_Callback_t callback); + + Ecode_t NF_SpiDriver_ReceiveBlocking(NF_SpiDriver_Handle_t handle, void *buffer, int count); + + Ecode_t NF_SpiDriver_Transfer( + NF_SpiDriver_Handle_t handle, + const void *txBuffer, + void *rxBuffer, + int count, + NF_SpiDriver_Callback_t callback); + + Ecode_t NF_SpiDriver_TransferBlocking(NF_SpiDriver_Handle_t handle, const void *txBuffer, void *rxBuffer, int count); + + Ecode_t NF_SpiDriver_Transmit(NF_SpiDriver_Handle_t handle, const void *buffer, int count, NF_SpiDriver_Callback_t callback); + + Ecode_t NF_SpiDriver_TransmitBlocking(NF_SpiDriver_Handle_t handle, const void *buffer, int count); + + Ecode_t NF_SpiDriver_SetBitrate(NF_SpiDriver_Handle_t handle, uint32_t bitRate); + + Ecode_t NF_SpiDriver_SetFramelength(NF_SpiDriver_Handle_t handle, uint32_t frameLength); + +#ifdef __cplusplus +} +#endif + +#endif // NF_GECKO_SPI_DRIVER_H diff --git a/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.Spi/sys_dev_spi_native_target.h b/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.Spi/sys_dev_spi_native_target.h new file mode 100644 index 0000000000..f8e45eb333 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.Spi/sys_dev_spi_native_target.h @@ -0,0 +1,150 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#ifndef SYS_DEV_SPI_NATIVE_TARGET_H +#define SYS_DEV_SPI_NATIVE_TARGET_H + +#include +#include +#include + +#include +#include +#include + +// set missing defines +#if defined(USART0) +#ifndef GECKO_USE_SPI0 +#define GECKO_USE_SPI0 FALSE +#endif +#else +#define GECKO_USE_SPI0 FALSE +#endif + +#if defined(USART1) +#ifndef GECKO_USE_SPI1 +#define GECKO_USE_SPI1 FALSE +#endif +#else +#define GECKO_USE_SPI1 FALSE +#endif + +#if defined(USART2) +#ifndef GECKO_USE_SPI2 +#define GECKO_USE_SPI2 FALSE +#endif +#else +#define GECKO_USE_SPI2 FALSE +#endif + +#if defined(USART3) +#ifndef GECKO_USE_SPI3 +#define GECKO_USE_SPI3 FALSE +#endif +#else +#define GECKO_USE_SPI3 FALSE +#endif + +#if defined(USART4) +#ifndef GECKO_USE_SPI4 +#define GECKO_USE_SPI4 FALSE +#endif +#else +#define GECKO_USE_SPI4 FALSE +#endif + +#if defined(USART5) +#ifndef GECKO_USE_SPI5 +#define GECKO_USE_SPI5 FALSE +#endif +#else +#define GECKO_USE_SPI5 FALSE +#endif + +// adjust number of buses +#if defined(NUM_SPI_BUSES) +#undef NUM_SPI_BUSES +#endif +#define NUM_SPI_BUSES 6 + +// struct representing the SPI bus +struct NF_PAL_SPI +{ + int BusIndex; + SpiBusConfiguration BusConfiguration; + + SPI_Callback Callback; + + bool SequentialTxRx; + bool BufferIs16bits; + + uint8_t *WriteBuffer; + uint16_t WriteSize; + + uint8_t *ReadBuffer; + uint16_t ReadSize; + + // -1 = Chip Select is not handled | >0 Chip Select is to be controlled with this GPIO + int32_t ChipSelect; + + NF_SpiDriver_Handle_t Handle; + NF_SpiDriver_Init_t *InitSpiData; +}; + +//////////////////////////////////////////// +// declaration of the the SPI PAL structs // +//////////////////////////////////////////// +#if GECKO_USE_SPI0 == TRUE +extern NF_PAL_SPI SPI0_PAL; +#endif +#if GECKO_USE_SPI1 == TRUE +extern NF_PAL_SPI SPI1_PAL; +#endif +#if GECKO_USE_SPI2 == TRUE +extern NF_PAL_SPI SPI2_PAL; +#endif +#if GECKO_USE_SPI3 == TRUE +extern NF_PAL_SPI SPI3_PAL; +#endif +#if GECKO_USE_SPI4 == TRUE +extern NF_PAL_SPI SPI4_PAL; +#endif +#if GECKO_USE_SPI5 == TRUE +extern NF_PAL_SPI SPI5_PAL; +#endif + +#if defined(_USART_ROUTELOC0_MASK) + +// the following macro defines a function that configures the GPIO pins for an Gecko SPI peripheral +// it gets called in the System_Device_SPi_SPiDevice::NativeInit function +// this is required because the SPI peripherals can use multiple GPIO configuration combinations +#define INIT_SPI_CONFIG(num, sck_port_location, mosi_port_location, miso_port_location) \ + void InitSpiConfig##num(NF_SpiDriver_Init_t &initSpiData, bool isHalfDuplex) \ + { \ + initSpiData.port = USART##num; \ + initSpiData.portLocationTx = mosi_port_location; \ + initSpiData.portLocationClk = sck_port_location; \ + if (!isHalfDuplex) \ + { \ + initSpiData.portLocationRx = miso_port_location; \ + } \ + } + +#else +#error "This routing configuration is not supported. Need to have _USART_ROUTELOC0_MASK." +#endif + +////////////////////////////////////////////////////////////////////////////////////////////// +// when an SPI is defined the declarations below will have the real function/configuration // +// in the target folder @ target_windows_devices_spi_config.cpp // +////////////////////////////////////////////////////////////////////////////////////////////// +void InitSpiConfig0(NF_SpiDriver_Init_t &initSpiData, bool isHalfDuplex); +void InitSpiConfig1(NF_SpiDriver_Init_t &initSpiData, bool isHalfDuplex); +void InitSpiConfig2(NF_SpiDriver_Init_t &initSpiData, bool isHalfDuplex); +void InitSpiConfig3(NF_SpiDriver_Init_t &initSpiData, bool isHalfDuplex); +void InitSpiConfig4(NF_SpiDriver_Init_t &initSpiData, bool isHalfDuplex); +void InitSpiConfig5(NF_SpiDriver_Init_t &initSpiData, bool isHalfDuplex); + +#endif // SYS_DEV_SPI_NATIVE_TARGET_H diff --git a/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.UsbStream/sys_dev_usbstream_native_System_Device_Usb_UsbStream.cpp b/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.UsbStream/sys_dev_usbstream_native_System_Device_Usb_UsbStream.cpp new file mode 100644 index 0000000000..7344734546 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.UsbStream/sys_dev_usbstream_native_System_Device_Usb_UsbStream.cpp @@ -0,0 +1,430 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include +#include "sys_dev_usbstream_native_target.h" + +NF_PAL_USB UsbStream_PAL; + +static void UsbAsyncWriteCompleted( + uint8_t class_nbr, + void *p_buf, + uint32_t buf_len, + uint32_t xfer_len, + void *p_callback_arg, + sl_status_t status) +{ + (void)class_nbr; + (void)p_buf; + (void)buf_len; + (void)status; + + NATIVE_INTERRUPT_START + + NF_PAL_USB *usbPal = (NF_PAL_USB *)p_callback_arg; + + // process this only IF the operation wasn't aborted + // AND we're expecting an event + if (status != SL_STATUS_ABORT && usbPal->WaitingForTxEvent) + { + // store TX count + usbPal->TxBytesSent = xfer_len; + + Events_Set(SYSTEM_EVENT_FLAG_USB_OUT); + } + + // clear the flag + usbPal->WaitingForTxEvent = false; + + NATIVE_INTERRUPT_END +} + +static void UsbAsyncReadCompleted( + uint8_t class_nbr, + void *p_buf, + uint32_t buf_len, + uint32_t xfer_len, + void *p_callback_arg, + sl_status_t status) +{ + (void)class_nbr; + (void)p_buf; + (void)buf_len; + + NATIVE_INTERRUPT_START + + NF_PAL_USB *usbPal = (NF_PAL_USB *)p_callback_arg; + + // process this only IF the operation wasn't aborted + // AND we're expecting an event + if (status != SL_STATUS_ABORT && usbPal->WaitingForRxEvent) + { + // store RX count + usbPal->RxBytesReceived = xfer_len; + + Events_Set(SYSTEM_EVENT_FLAG_USB_IN); + } + + // clear the flag + usbPal->WaitingForRxEvent = false; + + NATIVE_INTERRUPT_END +} + +// -- // + +HRESULT Library_sys_dev_usbstream_native_System_Device_Usb_UsbStream::Read___I4__SZARRAY_U1__I4__I4( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + CLR_RT_HeapBlock_Array *dataBuffer; + CLR_RT_HeapBlock hbTimeout; + int64_t *timeoutTicks; + bool eventResult = true; + + uint8_t *data; + uint32_t length = 0; + uint32_t count = 0; + uint32_t offset = 0; + sl_status_t reqStatus; + + // get a pointer to the managed object instance and check that it's not NULL + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + + if ((bool)pThis[FIELD___disposed].NumericByRef().u1) + { + NANOCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); + } + + // perform parameter validation and setup TX operation + + // dereference the data buffer from the argument + dataBuffer = stack.Arg1().DereferenceArray(); + FAULT_ON_NULL_ARG(dataBuffer); + + offset = stack.Arg2().NumericByRef().s4; + count = stack.Arg3().NumericByRef().s4; + + // get the size of the buffer + length = dataBuffer->m_numOfElements; + + // check parameters + if ((offset > length) || (count > length)) + { + NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE); + } + + if (offset + count > length) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + // get a the pointer to the array by using the offset + data = dataBuffer->GetElement(offset); + + // setup timeout from managed property + hbTimeout.SetInteger((CLR_INT64)pThis[FIELD___readTimeout].NumericByRef().s4 * TIME_CONVERSION__TO_MILLISECONDS); + NANOCLR_CHECK_HRESULT(stack.SetupTimeoutFromTicks(hbTimeout, timeoutTicks)); + + // this is a long running operation... + if (stack.m_customState == 1) + { + // ... and hasn't started yet + + // bump custom state + stack.m_customState = 2; + + // clear RX counter + UsbStream_PAL.RxBytesReceived = 0; + + // set event flag + UsbStream_PAL.WaitingForRxEvent = true; + + // start read operation with async API + reqStatus = sl_usbd_vendor_read_bulk_async( + sl_usbd_vendor_winusb_number, + (void *)data, + count, + UsbAsyncReadCompleted, + &UsbStream_PAL); + + if (reqStatus == SL_STATUS_INVALID_STATE) + { + // device is not connected, return exception + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + else if (reqStatus == SL_STATUS_NOT_READY) + { + // transfer already in progress, return exception + NANOCLR_SET_AND_LEAVE(CLR_E_FILE_IO); + } + } + + while (eventResult) + { + // non-blocking wait allowing other threads to run while we wait for the USB operation to complete + NANOCLR_CHECK_HRESULT( + g_CLR_RT_ExecutionEngine.WaitEvents(stack.m_owningThread, *timeoutTicks, Event_UsbIn, eventResult)); + + if (eventResult) + { + // if different than expected, abort anyway + if (UsbStream_PAL.RxBytesReceived != count) + { + // cancel the async operation... + sl_usbd_vendor_abort_read_bulk(sl_usbd_vendor_winusb_number); + } + + // done here + break; + } + else + { + // timeout has expired + // cancel the async operation... + sl_usbd_vendor_abort_read_bulk(sl_usbd_vendor_winusb_number); + + // ... return exception + NANOCLR_SET_AND_LEAVE(CLR_E_TIMEOUT); + } + } + + // pop timeout heap block from stack + stack.PopValue(); + + // set result with count of bytes received + stack.SetResult_I4(UsbStream_PAL.RxBytesReceived); + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_sys_dev_usbstream_native_System_Device_Usb_UsbStream::Write___VOID__SZARRAY_U1__I4__I4( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + CLR_RT_HeapBlock_Array *dataBuffer; + CLR_RT_HeapBlock hbTimeout; + int64_t *timeoutTicks; + int16_t timeoutMiliseconds = 0; + bool eventResult = true; + + uint8_t *data; + uint32_t length = 0; + uint32_t count = 0; + uint32_t offset = 0; + sl_status_t reqStatus; + uint32_t xfer_len = 0; + bool isLongRunning = false; + + // get a pointer to the managed object instance and check that it's not NULL + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + + if ((bool)pThis[FIELD___disposed].NumericByRef().u1) + { + NANOCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); + } + + // perform parameter validation and setup TX operation + + // dereference the data buffer from the argument + dataBuffer = stack.Arg1().DereferenceArray(); + FAULT_ON_NULL_ARG(dataBuffer); + + offset = stack.Arg2().NumericByRef().s4; + count = stack.Arg3().NumericByRef().s4; + + // get the size of the buffer + length = dataBuffer->m_numOfElements; + + // check parameters + FAULT_ON_NULL_ARG(dataBuffer); + + if ((offset > length) || (count > length)) + { + NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE); + } + + if (offset + count > length) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + // get a the pointer to the array by using the offset + data = dataBuffer->GetElement(offset); + + // setup timeout from managed property + hbTimeout.SetInteger((CLR_INT64)pThis[FIELD___writeTimeout].NumericByRef().s4 * TIME_CONVERSION__TO_MILLISECONDS); + NANOCLR_CHECK_HRESULT(stack.SetupTimeoutFromTicks(hbTimeout, timeoutTicks)); + + // check if it's worth to use async API + if (count > 64) + { + isLongRunning = true; + } + + // this is a long running operation... + if (isLongRunning && stack.m_customState == 1) + { + // ... and hasn't started yet + + // bump custom state + stack.m_customState = 2; + + // clear TX counter + UsbStream_PAL.TxBytesSent = 0; + + // set event flag + UsbStream_PAL.WaitingForTxEvent = true; + + // start write operation with async API + // requesting handling of "End-of-transfer" + reqStatus = sl_usbd_vendor_write_bulk_async( + sl_usbd_vendor_winusb_number, + (void *)data, + count, + UsbAsyncWriteCompleted, + &UsbStream_PAL, + false); + + if (reqStatus == SL_STATUS_INVALID_STATE) + { + // device is not connected, return exception + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + else if (reqStatus == SL_STATUS_NOT_READY) + { + // transfer already in progress, return exception + NANOCLR_SET_AND_LEAVE(CLR_E_FILE_IO); + } + } + else + { + if (*timeoutTicks != TIMEOUT_INFINITE) + { + // convert from ticks to milliseconds + timeoutMiliseconds = (int16_t)pThis[FIELD___writeTimeout].NumericByRef().s4; + } + + // start write operation with async API + // requesting handling of "End-of-transfer" + reqStatus = sl_usbd_vendor_write_bulk_sync( + sl_usbd_vendor_winusb_number, + (void *)data, + count, + timeoutMiliseconds, + false, + &xfer_len); + } + + while (isLongRunning && eventResult) + { + // non-blocking wait allowing other threads to run while we wait for the USB operation to complete + NANOCLR_CHECK_HRESULT( + g_CLR_RT_ExecutionEngine.WaitEvents(stack.m_owningThread, *timeoutTicks, Event_UsbOut, eventResult)); + + if (eventResult) + { + // done here + break; + } + else + { + // timeout has expired + // cancel the async operation... + sl_usbd_vendor_abort_write_bulk(sl_usbd_vendor_winusb_number); + + // ... return exception + NANOCLR_SET_AND_LEAVE(CLR_E_TIMEOUT); + } + } + + // pop timeout heap block from stack + stack.PopValue(); + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_sys_dev_usbstream_native_System_Device_Usb_UsbStream::get_IsConnected___BOOLEAN( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + // default to false + bool conn = false; + + // don't care about return value as we'll just return false if the connection state can't be determined + sl_usbd_vendor_is_enabled(sl_usbd_vendor_winusb_number, &conn); + stack.SetResult_Boolean(conn); + + NANOCLR_NOCLEANUP_NOLABEL(); +} + +HRESULT Library_sys_dev_usbstream_native_System_Device_Usb_UsbStream::NativeClose___VOID(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + (void)stack; + + // abort any transfer in progress, just in case + sl_usbd_vendor_abort_write_bulk(sl_usbd_vendor_winusb_number); + sl_usbd_vendor_abort_read_bulk(sl_usbd_vendor_winusb_number); + + NANOCLR_NOCLEANUP_NOLABEL(); +} + +HRESULT Library_sys_dev_usbstream_native_System_Device_Usb_UsbStream::NativeOpen___I4__STRING__STRING( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + const char *deviceDescription; + const char *deviceClassGuid; + + // int32_t bufferSize; + + // get a pointer to the managed object instance and check that it's not NULL + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + + // get device class GUID + deviceClassGuid = stack.Arg1().RecoverString(); + + // clear destination + memset(UsbClassVendorDeviceInterfaceGuid, 0, sizeof(UsbClassVendorDeviceInterfaceGuid)); + + for (uint16_t i = 0; i < sizeof(UsbClassVendorDeviceInterfaceGuid); i += 2) + { + UsbClassVendorDeviceInterfaceGuid[i] = *deviceClassGuid++; + } + + // get description + deviceDescription = stack.Arg2().RecoverString(); + FAULT_ON_NULL(deviceDescription); + + // validate device description length + if (hal_strlen_s(deviceDescription) > sizeof(UsbClassVendorDescription) - 1) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + // store device description + hal_strcpy_s(UsbClassVendorDescription, sizeof(UsbClassVendorDescription), deviceDescription); + + // also update USB device product string + sl_usbd_vendor_update_device_product_string((const char *)UsbClassVendorDescription); + + if (sli_usbd_vendor_winusb_init() != SL_STATUS_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_FAIL); + } + + stack.SetResult_I4(sl_usbd_vendor_winusb_number); + + NANOCLR_NOCLEANUP(); +} diff --git a/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.UsbStream/sys_dev_usbstream_native_target.h b/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.UsbStream/sys_dev_usbstream_native_target.h new file mode 100644 index 0000000000..53691a1f82 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.Device.UsbStream/sys_dev_usbstream_native_target.h @@ -0,0 +1,26 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include + +// need these declared here as they are scattered throughout Gecko SDK and config files +extern char UsbClassVendorDescription[GECKO_DEVICE_CLASS_VENDOR_DESCRIPTION_PROPERTY_LEN + 1]; +extern char UsbClassVendorDeviceInterfaceGuid[38 * 2 + 2]; +extern uint8_t sl_usbd_vendor_winusb_number; +extern "C" sl_status_t sli_usbd_vendor_winusb_init(void); + +// struct representing the UART +typedef struct +{ + uint16_t RxBytesReceived; + + uint16_t TxBytesSent; + + bool WaitingForRxEvent; + bool WaitingForTxEvent; + +} NF_PAL_USB; + +extern NF_PAL_USB UsbStream_PAL; diff --git a/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.IO.Ports/sys_io_ser_native_System_IO_Ports_SerialPort.cpp b/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.IO.Ports/sys_io_ser_native_System_IO_Ports_SerialPort.cpp new file mode 100644 index 0000000000..960b79c02e --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.IO.Ports/sys_io_ser_native_System_IO_Ports_SerialPort.cpp @@ -0,0 +1,1185 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include "sys_io_ser_native_target.h" +#include + +#if defined(GECKO_USE_USART0) && (GECKO_USE_USART0 == TRUE) +NF_PAL_UART Uart0_PAL; +#endif +#if defined(GECKO_USE_USART1) && (GECKO_USE_USART1 == TRUE) +NF_PAL_UART Uart1_PAL; +#endif +#if defined(GECKO_USE_USART2) && (GECKO_USE_USART2 == TRUE) +NF_PAL_UART Uart2_PAL; +#endif +#if defined(GECKO_USE_USART3) && (GECKO_USE_USART3 == TRUE) +NF_PAL_UART Uart3_PAL; +#endif +#if (HAL_WP_USE_SERIAL == FALSE) && defined(GECKO_USE_USART4) && (GECKO_USE_USART4 == TRUE) +NF_PAL_UART Uart4_PAL; +#endif +#if defined(GECKO_USE_USART5) && (GECKO_USE_USART5 == TRUE) +NF_PAL_UART Uart5_PAL; +#endif + +static NF_PAL_UART *GetUartPAL(uint8_t index) +{ + // Choose the driver for this SerialDevice + switch (index) + { + ////////////////////////////////// + // Gecko USART index is 0 based // + ////////////////////////////////// + +#if defined(GECKO_USE_USART0) && (GECKO_USE_USART0 == TRUE) + case 1: + return &Uart0_PAL; +#endif + +#if defined(GECKO_USE_USART1) && (GECKO_USE_USART1 == TRUE) + case 2: + return &Uart1_PAL; +#endif + +#if defined(GECKO_USE_USART2) && (GECKO_USE_USART2 == TRUE) + case 3: + return &Uart2_PAL; +#endif + +#if defined(GECKO_USE_USART3) && (GECKO_USE_USART3 == TRUE) + case 4: + return &Uart3_PAL; +#endif + +#if (HAL_WP_USE_SERIAL == FALSE) && defined(GECKO_USE_USART4) && (GECKO_USE_USART4 == TRUE) + case 5: + return &Uart4_PAL; +#endif + +#if defined(GECKO_USE_USART5) && (GECKO_USE_USART5 == TRUE) + case 6: + return &Uart5_PAL; +#endif + + default: + return NULL; + } +} + +// This handler is invoked when a byte has been transmitted by the USART. +static void UsartTxHandler(uint8_t index) +{ + NATIVE_INTERRUPT_START + + NF_PAL_UART *palUart = GetUartPAL(index); + + if (palUart->TxOngoingCount > 0) + { + // load the next byte + palUart->Usart->TXDATA = *palUart->TxBuffer; + + // update pointer + palUart->TxBuffer++; + + // update counter + palUart->TxOngoingCount--; + } + else + { + // no more bytes to send + Events_Set(SYSTEM_EVENT_FLAG_COM_OUT); + } + + NATIVE_INTERRUPT_END +} + +// This callback is invoked when a character is received +static void UsartRxHandler(uint8_t index) +{ + NATIVE_INTERRUPT_START + + NF_PAL_UART *palUart = GetUartPAL(index); + + uint8_t newChar = (uint8_t)palUart->Usart->RXDATA; + + // store this into the UART Rx buffer + // don't care about the success of the operation, if it's full we are droping the char anyway + palUart->RxRingBuffer.Push(newChar); + + // is there a read operation going on? + if (palUart->RxBytesToRead > 0) + { + // yes + // check if the requested bytes are available in the buffer... + //... or if the watch char was received + if ((palUart->RxRingBuffer.Length() >= palUart->RxBytesToRead) || (newChar == palUart->WatchChar)) + { + // reset Rx bytes to read count + palUart->RxBytesToRead = 0; + + // fire event for Rx buffer complete + Events_Set(SYSTEM_EVENT_FLAG_COM_IN); + } + } + else if (palUart->NewLineChar > 0 && newChar == palUart->NewLineChar) + { + // fire event for new line char found + Events_Set(SYSTEM_EVENT_FLAG_COM_IN); + } + else + { + // no read operation ongoing, so fire an event, if the available bytes are above the threshold + if (palUart->RxRingBuffer.Length() >= palUart->ReceivedBytesThreshold) + { + // post a managed event with the port index and event code (check if this is the watch char or just another + // char) + // TODO: check if callbacks are registered so this is called only if there is anyone listening otherwise + PostManagedEvent( + EVENT_SERIAL, + 0, + index, + (newChar == palUart->WatchChar) ? SerialData_WatchChar : SerialData_Chars); + } + } + + NATIVE_INTERRUPT_END +} + +HRESULT Library_sys_io_ser_native_System_IO_Ports_SerialPort::get_BytesToRead___I4(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + NF_PAL_UART *palUart; + + // get a pointer to the managed object instance and check that it's not NULL + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + + // Choose the driver for this SerialDevice + palUart = GetUartPAL((int)pThis[FIELD___portIndex].NumericByRef().s4); + if (palUart == NULL) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + // get length of Rx ring buffer + stack.SetResult_U4(palUart->RxRingBuffer.Length()); + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_sys_io_ser_native_System_IO_Ports_SerialPort::get_InvertSignalLevels___BOOLEAN(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + (void)stack; + + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_sys_io_ser_native_System_IO_Ports_SerialPort::set_InvertSignalLevels___VOID__BOOLEAN( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + (void)stack; + + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_sys_io_ser_native_System_IO_Ports_SerialPort::Read___I4__SZARRAY_U1__I4__I4(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + CLR_RT_HeapBlock hbTimeout; + CLR_RT_HeapBlock_Array *dataBuffer; + NF_PAL_UART *palUart = NULL; + + uint8_t *data; + + uint32_t length; + uint32_t count = 0; + uint32_t bytesRead = 0; + uint32_t offset = 0; + uint32_t bytesToRead = 0; + + int64_t *timeoutTicks; + bool eventResult = true; + + // get a pointer to the managed object instance and check that it's not NULL + 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); + } + + // setup timeout + hbTimeout.SetInteger((CLR_INT64)pThis[FIELD___readTimeout].NumericByRef().s4 * TIME_CONVERSION__TO_MILLISECONDS); + NANOCLR_CHECK_HRESULT(stack.SetupTimeoutFromTicks(hbTimeout, timeoutTicks)); + + // dereference the data buffer from the argument + dataBuffer = stack.Arg1().DereferenceArray(); + offset = stack.Arg2().NumericByRef().s4; + count = stack.Arg3().NumericByRef().s4; + + // perform parameter validation (only on initial call) + if (stack.m_customState == 1) + { + // get the size of the buffer + length = dataBuffer->m_numOfElements; + + // check parameters + FAULT_ON_NULL_ARG(dataBuffer); + + if ((offset > length) || (count > length)) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + + if (offset + count > length) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + } + + // get a the pointer to the array by using the offset + data = dataBuffer->GetElement(offset); + + // Choose the driver for this SerialDevice + palUart = GetUartPAL((int)pThis[FIELD___portIndex].NumericByRef().s4); + if (palUart == NULL) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + // figure out what's available in the Rx ring buffer + if (palUart->RxRingBuffer.Length() >= count) + { + // read from Rx ring buffer + bytesToRead = count; + + // we have enough bytes, skip wait for event + eventResult = false; + + // clear event by getting it + Events_Get(SYSTEM_EVENT_FLAG_COM_IN); + } + else + { + if (stack.m_customState == 1) + { + // not enough bytes available, have to read from UART + palUart->RxBytesToRead = count; + + // clear event by getting it + Events_Get(SYSTEM_EVENT_FLAG_COM_IN); + + // don't read anything from the buffer yet + bytesToRead = 0; + } + } + + while (eventResult) + { + if (stack.m_customState == 1) + { + if (bytesToRead > 0) + { + // enough bytes available + eventResult = false; + } + else + { + // need to read from the UART + // update custom state + stack.m_customState = 2; + } + } + else + { + // wait for event + NANOCLR_CHECK_HRESULT( + g_CLR_RT_ExecutionEngine + .WaitEvents(stack.m_owningThread, *timeoutTicks, Event_SerialPortIn, eventResult)); + + if (!eventResult) + { + // event timeout + NANOCLR_SET_AND_LEAVE(CLR_E_TIMEOUT); + } + } + } + + if (bytesToRead > 0) + { + // pop the requested bytes from the ring buffer + bytesRead = palUart->RxRingBuffer.Pop(data, bytesToRead); + } + + // pop "hbTimeout" heap block from stack + stack.PopValue(); + + // return how many bytes were read + stack.SetResult_U4(bytesRead); + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_sys_io_ser_native_System_IO_Ports_SerialPort::ReadExisting___STRING(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + NF_PAL_UART *palUart = NULL; + + uint8_t *buffer = NULL; + uint32_t bufferLength; + + CLR_RT_HeapBlock &top = stack.PushValue(); + + // get a pointer to the managed object instance and check that it's not NULL + 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); + } + + // Choose the driver for this SerialDevice + palUart = GetUartPAL((int)pThis[FIELD___portIndex].NumericByRef().s4); + if (palUart == NULL) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + bufferLength = palUart->RxRingBuffer.Length(); + + if (bufferLength) + { + // there are bytes available in the Rx buffer + // setup read buffer + buffer = (uint8_t *)platform_malloc(bufferLength); + + // sanity check + if (buffer == NULL) + { + NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_MEMORY); + } + + // fill data buffer from Rx buffer + palUart->RxRingBuffer.Pop(buffer, bufferLength); + + NANOCLR_CHECK_HRESULT(CLR_RT_HeapBlock_String::CreateInstance(top, (const char *)buffer, bufferLength)); + } + else + { + // create an empty + NANOCLR_CHECK_HRESULT(CLR_RT_HeapBlock_String::CreateInstance(top, (const char *)NULL)); + } + + NANOCLR_CLEANUP(); + + if (buffer != NULL) + { + platform_free(buffer); + } + + NANOCLR_CLEANUP_END(); +} + +HRESULT Library_sys_io_ser_native_System_IO_Ports_SerialPort::ReadLine___STRING(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + CLR_RT_HeapBlock hbTimeout; + NF_PAL_UART *palUart = NULL; + + uint8_t *line = NULL; + const char *newLine; + uint32_t newLineLength; + + int64_t *timeoutTicks; + bool eventResult = true; + + // get a pointer to the managed object instance and check that it's not NULL + 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); + } + + // setup timeout + hbTimeout.SetInteger((CLR_INT64)pThis[FIELD___readTimeout].NumericByRef().s4 * TIME_CONVERSION__TO_MILLISECONDS); + NANOCLR_CHECK_HRESULT(stack.SetupTimeoutFromTicks(hbTimeout, timeoutTicks)); + + // Choose the driver for this SerialDevice + palUart = GetUartPAL((int)pThis[FIELD___portIndex].NumericByRef().s4); + if (palUart == NULL) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + if (stack.m_customState == 1) + { + // check if there is a full line available to read + if (GetLineFromRxBuffer(pThis, &(palUart->RxRingBuffer), line)) + { + // got one! + eventResult = false; + } + else + { + // get new line from field + newLine = pThis[FIELD___newLine].RecoverString(); + newLineLength = hal_strlen_s(newLine); + // need to subtract one because we are 0 indexed + newLineLength--; + + // set new line char as the last one in the string + // only if this one is found it will have a chance of the others being there + palUart->NewLineChar = newLine[newLineLength]; + + stack.m_customState = 2; + } + } + + while (eventResult) + { + // wait for event + NANOCLR_CHECK_HRESULT( + g_CLR_RT_ExecutionEngine.WaitEvents(stack.m_owningThread, *timeoutTicks, Event_SerialPortIn, eventResult)); + + // clear the new line watch char + palUart->NewLineChar = 0; + + if (eventResult) + { + GetLineFromRxBuffer(pThis, &(palUart->RxRingBuffer), line); + + // done here + break; + } + else + { + // event timeout + NANOCLR_SET_AND_LEAVE(CLR_E_TIMEOUT); + } + } + + // pop "hbTimeout" heap block from stack + stack.PopValue(); + + // return how many bytes were read + stack.SetResult_String((const char *)line); + + // free memory, if needed + if (line != NULL) + { + platform_free(line); + } + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_sys_io_ser_native_System_IO_Ports_SerialPort::Write___VOID__SZARRAY_U1__I4__I4(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + NF_PAL_UART *palUart = NULL; + + CLR_RT_HeapBlock_Array *dataBuffer; + CLR_RT_HeapBlock hbTimeout; + int64_t *timeoutTicks; + bool eventResult = true; + + uint8_t *data; + int32_t length = 0; + int32_t count = 0; + int32_t offset = 0; + + // get a pointer to the managed object instance and check that it's not NULL + 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); + } + + // Choose the driver for this SerialDevice + palUart = GetUartPAL((int)pThis[FIELD___portIndex].NumericByRef().s4); + if (palUart == NULL) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + // setup timeout + hbTimeout.SetInteger((CLR_INT64)pThis[FIELD___writeTimeout].NumericByRef().s4 * TIME_CONVERSION__TO_MILLISECONDS); + NANOCLR_CHECK_HRESULT(stack.SetupTimeoutFromTicks(hbTimeout, timeoutTicks)); + + // perform parameter validation and setup TX operation + if (stack.m_customState == 1) + { + // dereference the data buffer from the argument + dataBuffer = stack.Arg1().DereferenceArray(); + offset = stack.Arg2().NumericByRef().s4; + count = stack.Arg3().NumericByRef().s4; + + // get the size of the buffer + length = dataBuffer->m_numOfElements; + + // check parameters + FAULT_ON_NULL_ARG(dataBuffer); + + if ((offset > length) || (count > length)) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + + if (offset + count > length) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + // get a the pointer to the array by using the offset + data = dataBuffer->GetElement(offset); + + // push onto the eval stack how many bytes are being pushed to the UART + stack.PushValueI4(count); + + // store pointer + palUart->TxBuffer = data; + + // set TX ongoing count + palUart->TxOngoingCount = count; + + // decrease count for the char we're about to send + palUart->TxOngoingCount--; + + // start sending data + // this will trigger the TX interrupt + palUart->Usart->TXDATA = *palUart->TxBuffer; + + // update buffer pointer + palUart->TxBuffer++; + + // bump custom state + stack.m_customState = 2; + } + + while (eventResult) + { + // non-blocking wait allowing other threads to run while we wait for the Tx operation to complete + NANOCLR_CHECK_HRESULT( + g_CLR_RT_ExecutionEngine.WaitEvents(stack.m_owningThread, *timeoutTicks, Event_SerialPortOut, eventResult)); + + if (eventResult) + { + // event occurred + // get from the eval stack how many bytes were buffered to Tx + count = stack.m_evalStack[1].NumericByRef().s4; + + // done here + break; + } + else + { + NANOCLR_SET_AND_LEAVE(CLR_E_TIMEOUT); + } + } + + // pop "count" heap block from stack + stack.PopValue(); + + // pop "hbTimeout" heap block from stack + stack.PopValue(); + + stack.SetResult_U4(count); + + // null pointers and vars + pThis = NULL; + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_sys_io_ser_native_System_IO_Ports_SerialPort::NativeDispose___VOID(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + // get a pointer to the managed object instance and check that it's not NULL + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + + // Choose the driver for this SerialDevice + switch ((int)pThis[FIELD___portIndex].NumericByRef().s4) + { + ////////////////////////////////// + // Gecko USART index is 0 based // + ////////////////////////////////// + +#if defined(GECKO_USE_USART0) && (GECKO_USE_USART0 == TRUE) + case 1: + UnInit_UART0(); + break; +#endif + +#if defined(GECKO_USE_USART1) && (GECKO_USE_USART1 == TRUE) + case 2: + UnInit_UART1(); + break; +#endif + +#if defined(GECKO_USE_USART2) && (GECKO_USE_USART2 == TRUE) + case 3: + UnInit_UART2(); + break; +#endif + +#if defined(GECKO_USE_USART3) && (GECKO_USE_USART3 == TRUE) + case 4: + UnInit_UART3(); + break; +#endif + +#if (HAL_WP_USE_SERIAL == FALSE) && defined(GECKO_USE_USART4) && (GECKO_USE_USART4 == TRUE) + case 5: + UnInit_UART4(); + break; +#endif + +#if defined(GECKO_USE_USART5) && (GECKO_USE_USART5 == TRUE) + case 6: + UnInit_UART5(); + break; +#endif + + default: + // this COM port is not valid + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + break; + } + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_sys_io_ser_native_System_IO_Ports_SerialPort::NativeInit___VOID(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + NF_PAL_UART *palUart; + int32_t bufferSize; + uint8_t watchChar; + + // get a pointer to the managed object instance and check that it's not NULL + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + + // Choose the driver for this SerialDevice + switch ((int)pThis[FIELD___portIndex].NumericByRef().s4) + { + ////////////////////////////////// + // Gecko USART index is 0 based // + ////////////////////////////////// + +#if defined(GECKO_USE_USART0) && (GECKO_USE_USART0 == TRUE) + case 1: + palUart = &Uart0_PAL; + break; +#endif +#if defined(GECKO_USE_USART1) && (GECKO_USE_USART1 == TRUE) + case 2: + InitConfig_USART1(); + palUart = &Uart1_PAL; + break; +#endif +#if defined(GECKO_USE_USART2) && (GECKO_USE_USART2 == TRUE) + case 3: + palUart = &Uart2_PAL; + break; +#endif +#if defined(GECKO_USE_USART3) && (GECKO_USE_USART3 == TRUE) + case 4: + palUart = &Uart3_PAL; + break; +#endif +#if (HAL_WP_USE_SERIAL == FALSE) && defined(GECKO_USE_USART4) && (GECKO_USE_USART4 == TRUE) + case 5: + palUart = &Uart4_PAL; + break; +#endif +#if defined(GECKO_USE_USART5) && (GECKO_USE_USART5 == TRUE) + case 6: + palUart = &Uart5_PAL; + break; +#endif + default: + // this COM port is not valid + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + break; + } + + // alloc buffer memory + bufferSize = pThis[FIELD___bufferSize].NumericByRef().s4; + palUart->RxBuffer = (uint8_t *)platform_malloc(bufferSize); + + // sanity check + if (palUart->RxBuffer == NULL) + { + NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_MEMORY); + } + + // init buffer + palUart->RxRingBuffer.Initialize(palUart->RxBuffer, bufferSize); + + // get watch character + watchChar = pThis[FIELD___watchChar].NumericByRef().u1; + + // set watch char, if set + if (watchChar != 0) + { + palUart->WatchChar = watchChar; + } + + // call the configure + return NativeConfig___VOID(stack); + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_sys_io_ser_native_System_IO_Ports_SerialPort::NativeConfig___VOID(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + NF_PAL_UART *palUart = NULL; + + // get a pointer to the managed object instance and check that it's not NULL + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + + // Choose the driver for this SerialDevice + palUart = GetUartPAL((int)pThis[FIELD___portIndex].NumericByRef().s4); + if (palUart == NULL) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + // setup configuration + palUart->UsartInit = USART_INITASYNC_DEFAULT; + + // data bits + // TODO + + // parity + // TODO + + // Check RS485 mode is not selected as currently not supported + if ((SerialMode)pThis[FIELD___mode].NumericByRef().s4 != SerialMode_Normal) + { + NANOCLR_SET_AND_LEAVE(CLR_E_NOTIMPL); + } + + // stop bits + + switch ((StopBits)pThis[FIELD___stopBits].NumericByRef().s4) + { + case StopBits_One: + // already set with the above + break; + case StopBits_OnePointFive: + palUart->UsartInit.stopbits = usartStopbits1p5; + break; + case StopBits_Two: + palUart->UsartInit.stopbits = usartStopbits2; + break; + } + + // configure TX, RX signal levels + if (palUart->SignalLevelsInverted) + { + // this driver doesn't support inverted signal levels + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); + } + + // baud rate + palUart->UsartInit.baudrate = (int)pThis[FIELD___baudRate].NumericByRef().s4; + + // stop UART, better do this before changing configuration + USART_Reset(palUart->Usart); + + // get pointer to PAL UART + switch ((int)pThis[FIELD___portIndex].NumericByRef().s4) + { + ////////////////////////////////// + // Gecko USART index is 0 based // + ////////////////////////////////// + +#if defined(GECKO_USE_USART0) && (GECKO_USE_USART0 == TRUE) + case 1: + InitConfig_USART0(); + break; +#endif +#if defined(GECKO_USE_USART1) && (GECKO_USE_USART1 == TRUE) + case 2: + InitConfig_USART1(); + break; +#endif +#if defined(GECKO_USE_USART2) && (GECKO_USE_USART2 == TRUE) + case 3: + InitConfig_USART2(); + + break; +#endif +#if defined(GECKO_USE_USART3) && (GECKO_USE_USART3 == TRUE) + case 4: + InitConfig_USART3(); + + break; +#endif +#if (HAL_WP_USE_SERIAL == FALSE) && defined(GECKO_USE_USART4) && (GECKO_USE_USART4 == TRUE) + case 5: + InitConfig_USART4(); + break; +#endif +#if defined(GECKO_USE_USART5) && (GECKO_USE_USART5 == TRUE) + case 6: + InitConfig_USART5(); + break; +#endif + } + + // null pointers and vars + pThis = NULL; + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_sys_io_ser_native_System_IO_Ports_SerialPort::NativeSetWatchChar___VOID(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + NF_PAL_UART *palUart; + + // get a pointer to the managed object instance and check that it's not NULL + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + + // Choose the driver for this SerialDevice + palUart = GetUartPAL((int)pThis[FIELD___portIndex].NumericByRef().s4); + if (palUart == NULL) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + // set watch char + palUart->WatchChar = (uint8_t)pThis[FIELD___watchChar].NumericByRef().u1; + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_sys_io_ser_native_System_IO_Ports_SerialPort::NativeWriteString___VOID__STRING__BOOLEAN( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + NF_PAL_UART *palUart = NULL; + + CLR_RT_HeapBlock hbTimeout; + int64_t *timeoutTicks; + bool eventResult = true; + + bool isNewAllocation = false; + char *buffer = NULL; + uint32_t bufferLength = 0; + int32_t length = 0; + + // get a pointer to the managed object instance and check that it's not NULL + 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); + } + + if (stack.Arg1().RecoverString() == NULL) + { + // text string it's empty so there is noting to do here + stack.SetResult_U4(0); + NANOCLR_SET_AND_LEAVE(S_OK); + } + + // Choose the driver for this SerialDevice + palUart = GetUartPAL((int)pThis[FIELD___portIndex].NumericByRef().s4); + if (palUart == NULL) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + // setup timeout + hbTimeout.SetInteger((CLR_INT64)pThis[FIELD___writeTimeout].NumericByRef().s4 * TIME_CONVERSION__TO_MILLISECONDS); + NANOCLR_CHECK_HRESULT(stack.SetupTimeoutFromTicks(hbTimeout, timeoutTicks)); + + // perform parameter validation and setup TX operation + if (stack.m_customState == 1) + { + // get buffer to output + NANOCLR_CHECK_HRESULT(SetupWriteLine(stack, &buffer, &bufferLength, &isNewAllocation)); + + // push onto the eval stack how many bytes are being pushed to the UART + stack.PushValueI4(bufferLength); + + // store pointer + palUart->TxBuffer = (uint8_t *)buffer; + + // set TX ongoing count + palUart->TxOngoingCount = bufferLength; + + // decrease count for the char we're about to send + palUart->TxOngoingCount--; + + // start sending data + // this will trigger the TX interrupt + palUart->Usart->TXDATA = *palUart->TxBuffer; + + // update buffer pointer + palUart->TxBuffer++; + + // bump custom state + stack.m_customState = 2; + } + + while (eventResult) + { + // non-blocking wait allowing other threads to run while we wait for the Tx operation to complete + NANOCLR_CHECK_HRESULT( + g_CLR_RT_ExecutionEngine.WaitEvents(stack.m_owningThread, *timeoutTicks, Event_SerialPortOut, eventResult)); + + if (eventResult) + { + // event occurred + // get from the eval stack how many bytes were buffered to Tx + length = stack.m_evalStack[1].NumericByRef().s4; + + // done here + break; + } + else + { + NANOCLR_SET_AND_LEAVE(CLR_E_TIMEOUT); + } + } + + // pop "length" heap block from stack + stack.PopValue(); + + // pop "hbTimeout" heap block from stack + stack.PopValue(); + + stack.SetResult_U4(length); + + // free memory, if it was allocated + if (isNewAllocation && buffer) + { + platform_free(buffer); + } + + // null pointers and vars + pThis = NULL; + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_sys_io_ser_native_System_IO_Ports_SerialPort::NativeReceivedBytesThreshold___VOID__I4( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + NF_PAL_UART *palUart; + int32_t threshold; + uint8_t portIndex; + + // get a pointer to the managed object instance and check that it's not NULL + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + + // check if threshold is valid + threshold = (int32_t)stack.Arg1().NumericByRef().s4; + + if (threshold <= 0) + { + NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE); + } + + portIndex = (int)pThis[FIELD___portIndex].NumericByRef().s4; + + // Choose the driver for this SerialDevice + palUart = GetUartPAL(portIndex); + if (palUart == NULL) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + // update field + pThis[FIELD___receivedBytesThreshold].NumericByRef().s4 = threshold; + + // update threshold value + palUart->ReceivedBytesThreshold = threshold; + + // fake call to event handler in case port is open and the new threshold was set + // to a value lower than the bytes that are already available + if (pThis[FIELD___opened].NumericByRef().u1 && (uint32_t)threshold <= palUart->RxRingBuffer.Length()) + { + ////////////////////////////////// + // Gecko USART index is 0 based // + ////////////////////////////////// + PostManagedEvent(EVENT_SERIAL, 0, portIndex + 1, SerialData_Chars); + } + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_sys_io_ser_native_System_IO_Ports_SerialPort::GetDeviceSelector___STATIC__STRING( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + // declare the device selector string whose max size is "COM1,COM2,COM3,COM4,COM5,COM6,COM7,COM8," + terminator + // and init with the terminator + static char deviceSelectorString[] = + +#if defined(GECKO_USE_USART0) && (GECKO_USE_USART0 == TRUE) + "COM1," +#endif +#if defined(GECKO_USE_USART1) && (GECKO_USE_USART1 == TRUE) + "COM2," +#endif +#if defined(GECKO_USE_USART2) && (GECKO_USE_USART2 == TRUE) + "COM3," +#endif +#if defined(GECKO_USE_USART3) && (GECKO_USE_USART3 == TRUE) + "COM4," +#endif + +#if (HAL_WP_USE_SERIAL == FALSE) && defined(GECKO_USE_USART4) && (GECKO_USE_USART4 == TRUE) + "COM5," +#endif + +#if defined(GECKO_USE_USART5) && (GECKO_USE_USART5 == TRUE) + "COM6," +#endif + ; + + // replace the last comma with a terminator + if (deviceSelectorString[hal_strlen_s(deviceSelectorString) - 1] == ',') + { + deviceSelectorString[hal_strlen_s(deviceSelectorString) - 1] = '\0'; + } + + // because the caller is expecting a result to be returned + // we need set a return result in the stack argument using the appropriate SetResult according to the variable + // type (a string here) + stack.SetResult_String(deviceSelectorString); + + NANOCLR_NOCLEANUP_NOLABEL(); +} + +#if defined(GECKO_USE_USART0) && (GECKO_USE_USART0 == TRUE) +void USART0_RX_IRQHandler(void) +{ + // Gecko USART index is 0 based + // need to follow the same index as in the PAL struct + UsartRxHandler(1); +} +void USART0_TX_IRQHandler(void) +{ + // Gecko USART index is 0 based + // need to follow the same index as in the PAL struct + UsartTxHandler(1); +} +#endif + +#if defined(GECKO_USE_USART1) && (GECKO_USE_USART1 == TRUE) +void USART1_RX_IRQHandler(void) +{ + // Gecko USART index is 0 based + // need to follow the same index as in the PAL struct + UsartRxHandler(2); +} +void USART1_TX_IRQHandler(void) +{ + // Gecko USART index is 0 based + // need to follow the same index as in the PAL struct + UsartTxHandler(2); +} +#endif + +#if defined(GECKO_USE_USART2) && (GECKO_USE_USART2 == TRUE) +void USART2_RX_IRQHandler(void) +{ + // Gecko USART index is 0 based + // need to follow the same index as in the PAL struct + UsartRxHandler(3); +} +void USART2_TX_IRQHandler(void) +{ + // Gecko USART index is 0 based + // need to follow the same index as in the PAL struct + UsartTxHandler(3); +} +#endif + +#if defined(GECKO_USE_USART3) && (GECKO_USE_USART3 == TRUE) +void USART3_RX_IRQHandler(void) +{ + // Gecko USART index is 0 based + // need to follow the same index as in the PAL struct + UsartRxHandler(4); +} +void USART3_TX_IRQHandler(void) +{ + // Gecko USART index is 0 based + // need to follow the same index as in the PAL struct + UsartTxHandler(4); +} +#endif + +#if (HAL_WP_USE_SERIAL == FALSE) && defined(GECKO_USE_USART4) && (GECKO_USE_USART4 == TRUE) +void USART4_RX_IRQHandler(void) +{ + // Gecko USART index is 0 based + // need to follow the same index as in the PAL struct + UsartRxHandler(5); +} +void USART4_TX_IRQHandler(void) +{ + // Gecko USART index is 0 based + // need to follow the same index as in the PAL struct + UsartTxHandler(5); +} +#endif + +#if defined(GECKO_USE_USART5) && (GECKO_USE_USART5 == TRUE) +void USART5_RX_IRQHandler(void) +{ + // Gecko USART index is 0 based + // need to follow the same index as in the PAL struct + UsartRxHandler(6); +} +void USART5_TX_IRQHandler(void) +{ + // Gecko USART index is 0 based + // need to follow the same index as in the PAL struct + UsartTxHandler(6); +} +#endif diff --git a/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.IO.Ports/sys_io_ser_native_target.h b/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.IO.Ports/sys_io_ser_native_target.h new file mode 100644 index 0000000000..e6952c319c --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_nanoCLR/System.IO.Ports/sys_io_ser_native_target.h @@ -0,0 +1,169 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#ifndef SYS_IO_SER_NATIVE_TARGET_H +#define SYS_IO_SER_NATIVE_TARGET_H + +#include +#include + +#include +#include +#include + +// set missing defines +#if defined(USART0) +#ifndef GECKO_USE_USART0 +#define GECKO_USE_USART0 FALSE +#endif +#else +#define GECKO_USE_USART0 FALSE +#endif + +#if defined(USART1) +#ifndef GECKO_USE_USART1 +#define GECKO_USE_USART1 FALSE +#endif +#else +#define GECKO_USE_USART1 FALSE +#endif + +#if defined(USART2) +#ifndef GECKO_USE_USART2 +#define GECKO_USE_USART2 FALSE +#endif +#else +#define GECKO_USE_USART2 FALSE +#endif + +#if defined(USART3) +#ifndef GECKO_USE_USART3 +#define GECKO_USE_USART3 FALSE +#endif +#else +#define GECKO_USE_USART3 FALSE +#endif + +#if defined(USART4) +#ifndef GECKO_USE_USART4 +#define GECKO_USE_USART4 FALSE +#endif +#else +#define GECKO_USE_USART4 FALSE +#endif + +#if defined(USART5) +#ifndef GECKO_USE_USART5 +#define GECKO_USE_USART5 FALSE +#endif +#else +#define GECKO_USE_USART5 FALSE +#endif + +// struct representing the UART +typedef struct +{ + USART_TypeDef *Usart; + USART_InitAsync_TypeDef UsartInit; + + uint8_t *TxBuffer; + uint16_t TxOngoingCount; + + HAL_RingBuffer RxRingBuffer; + uint8_t *RxBuffer; + uint16_t RxBytesToRead; + + uint8_t WatchChar; + uint8_t NewLineChar; + uint32_t ReceivedBytesThreshold; + + bool SignalLevelsInverted; + +} NF_PAL_UART; + +//////////////////////////////////////////// +// declaration of the the UART PAL strucs // +//////////////////////////////////////////// +#if defined(GECKO_USE_USART0) && (GECKO_USE_USART0 == TRUE) +extern NF_PAL_UART Uart0_PAL; +#endif +#if defined(GECKO_USE_USART1) && (GECKO_USE_USART1 == TRUE) +extern NF_PAL_UART Uart1_PAL; +#endif +#if defined(GECKO_USE_USART2) && (GECKO_USE_USART2 == TRUE) +extern NF_PAL_UART Uart2_PAL; +#endif +#if defined(GECKO_USE_USART3) && (GECKO_USE_USART3 == TRUE) +extern NF_PAL_UART Uart3_PAL; +#endif +#if defined(GECKO_USE_USART_UART4) && (GECKO_USE_USART_UART4 == TRUE) +extern NF_PAL_UART Uart4_PAL; +#endif +#if defined(GECKO_USE_USART_UART5) && (GECKO_USE_USART_UART5 == TRUE) +extern NF_PAL_UART Uart5_PAL; +#endif + +// the following macro defines a function that configures the GPIO pins for a Gecko USART +// it gets called in the System_IO_Ports_SerialPort::NativeConfig function +// this is required because the UART/USART peripherals can use multiple GPIO configuration combinations +#define UART_INIT_CONFIG(num, gpio_port_tx, tx_pin, tx_location, gpio_port_rx, rx_pin, rx_location) \ + void InitConfig_USART##num() \ + { \ + CMU_ClockEnable(cmuClock_USART##num, true); \ + GPIO_PinModeSet(gpio_port_rx, rx_pin, gpioModeInput, 0); \ + GPIO_PinModeSet(gpio_port_tx, tx_pin, gpioModePushPull, 1); \ + USART_InitAsync(USART##num, &Uart##num##_PAL.UsartInit); \ + NVIC_ClearPendingIRQ(USART##num##_RX_IRQn); \ + NVIC_EnableIRQ(USART##num##_RX_IRQn); \ + NVIC_ClearPendingIRQ(USART##num##_TX_IRQn); \ + NVIC_EnableIRQ(USART##num##_TX_IRQn); \ + Uart##num##_PAL.Usart = USART##num; \ + USART##num->ROUTELOC0 = rx_location | tx_location; \ + USART##num->ROUTEPEN |= USART_ROUTEPEN_TXPEN | USART_ROUTEPEN_RXPEN; \ + Uart##num##_PAL.TxBuffer = NULL; \ + Uart##num##_PAL.TxOngoingCount = 0; \ + Uart##num##_PAL.RxBuffer = NULL; \ + Uart##num##_PAL.WatchChar = 0; \ + Uart##num##_PAL.NewLineChar = 0; \ + Uart##num##_PAL.SignalLevelsInverted = false; \ + } + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// when a UART/USART is defined the declarations below will have the real function/configuration +// in the target folder @ target_system_io_ports_config.cpp +/////////////////////////////////////////////////////////////////////////////////////////////////// +void InitConfig_USART0(); +void InitConfig_USART1(); +void InitConfig_USART2(); +void InitConfig_USART3(); +void InitConfig_USART4(); +void InitConfig_USART5(); + +// the following macro defines a function that un initializes an UART struct +// it gets called in the System_IO_Ports_SerialPort::NativeDispose function +#define UART_UNINIT(num, gpio_port_tx, tx_pin, tx_location, gpio_port_rx, rx_pin, rx_location) \ + void UnInit_UART##num() \ + { \ + USART_Reset(USART##num); \ + GPIO_PinModeSet(gpio_port_rx, rx_pin, gpioModeDisabled, 0); \ + GPIO_PinModeSet(gpio_port_tx, tx_pin, gpioModeDisabled, 0); \ + CMU_ClockEnable(cmuClock_USART##num, false); \ + platform_free(Uart##num##_PAL.RxBuffer); \ + Uart##num##_PAL.TxBuffer = NULL; \ + Uart##num##_PAL.RxBuffer = NULL; \ + Uart##num##_PAL.Usart = NULL; \ + return; \ + } + +// when a UART/USART is defined the declarations below will have the real function/configuration +// in the target folder @ target_system_io_ports_config.cpp +void UnInit_UART0(); +void UnInit_UART1(); +void UnInit_UART2(); +void UnInit_UART3(); +void UnInit_UART4(); +void UnInit_UART5(); + +#endif // SYS_IO_SER_NATIVE_TARGET_H diff --git a/targets/AzureRTOS/SiliconLabs/_nanoCLR/nanoFramework.Device.OneWire/nf_dev_onewire_nanoFramework_Device_OneWire_OneWireHost.cpp b/targets/AzureRTOS/SiliconLabs/_nanoCLR/nanoFramework.Device.OneWire/nf_dev_onewire_nanoFramework_Device_OneWire_OneWireHost.cpp new file mode 100644 index 0000000000..5f6a5e0a37 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_nanoCLR/nanoFramework.Device.OneWire/nf_dev_onewire_nanoFramework_Device_OneWire_OneWireHost.cpp @@ -0,0 +1,623 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include "nf_dev_onewire_target.h" + +///////////////////// +// 1-Wire API code // +///////////////////// + +#define ONEWIRE_THREAD_STACK_SIZE 256 +#define ONEWIRE_THREAD_PRIORITY 5 + +// struct for working threads +static OneWireFindStruct FindStruct; +static bool OneWireOperationResult; +static TX_THREAD *WaitingTask; +static uint32_t *workingThreadStack; +static uint8_t LastDiscrepancy; +static uint8_t LastFamilyDiscrepancy; +static uint8_t LastDevice; +static uint8_t SerialNum[8]; + +typedef Library_nf_dev_onewire_nanoFramework_Device_OneWire_OneWireHost OneWireHost; + +extern "C" void sli_iostream_change_baudrate(sl_iostream_t *handle, uint32_t baudrate); +extern sl_iostream_t *sl_iostream_onewire_handle; + +// Driver state. +static oneWireState DriverState = ONEWIRE_UNINIT; + +void oneWireStop() +{ + // stop UART + // TODO + // uart_driver_delete(NF_ONEWIRE_ESP32_UART_NUM); + + // driver is stopped + DriverState = ONEWIRE_STOP; +} + +HRESULT oneWireInit() +{ + DriverState = ONEWIRE_STOP; + + sl_iostream_usart_init_onewire(); + + DriverState = ONEWIRE_READY; + + return S_OK; +} + +uint8_t oneWireTouchReset(void) +{ + char reset = 0xF0; + uint8_t presence; + size_t bytesRead; + + // flush DMA buffer to ensure cache coherency + // TODO uart_flush(NF_ONEWIRE_ESP32_UART_NUM); + + // set UART baud rate to 9600bps (required to send the RESET condition to the 1-Wire bus) + sli_iostream_change_baudrate(sl_iostream_onewire_handle, 9600); + + sl_iostream_write(sl_iostream_onewire_handle, (uint8_t *)&reset, 1); + sl_iostream_read(sl_iostream_onewire_handle, &presence, 1, &bytesRead); + + // set UART baud rate to 115200bps (normal comm is performed at this baud rate) + sli_iostream_change_baudrate(sl_iostream_onewire_handle, 115200); + + // check for presence pulse + return (presence != reset); +} + +bool oneWireTouchBit(bool sendbit) +{ + // need to send 1-Wire write 1 or 0 according to sendbit + char write = sendbit ? IWIRE_WR1 : IWIRE_WR0; + uint8_t reply; + size_t bytesRead; + + // flush DMA buffer to ensure cache coherency + // TODO uart_flush(NF_ONEWIRE_ESP32_UART_NUM); + + sl_iostream_write(sl_iostream_onewire_handle, (uint8_t *)&write, 1); + sl_iostream_read(sl_iostream_onewire_handle, &reply, 1, &bytesRead); + + // interpret 1-Wire reply + return (reply == IWIRE_RD); +} + +uint8_t oneWireTouchByte(uint8_t sendbyte) +{ + uint8_t send_mask = 0x01, result = 0; + uint8_t i = 0; + char writeBuffer[8]; + uint8_t readBuffer[8]; + size_t bytesRead; + + // send byte + while (send_mask) + { + writeBuffer[i] = (sendbyte & send_mask) ? IWIRE_WR1 : IWIRE_WR0; + i++; + // rotates the position mask transmit bit + send_mask <<= 1; + }; + + // flush DMA buffer to ensure cache coherency + // TODO uart_flush(NF_ONEWIRE_ESP32_UART_NUM); + + sl_iostream_write(sl_iostream_onewire_handle, (uint8_t *)&writeBuffer, 8); + sl_iostream_read(sl_iostream_onewire_handle, &readBuffer, 8, &bytesRead); + + // reset send mask to interpret the reply + send_mask = 0x01; + + for (i = 0; i < 8; i++) + { + if (readBuffer[i] == IWIRE_RD) + { + result |= send_mask; + } + + send_mask <<= 1; + } + + return result; +} + +void oneWireAquire() +{ +} + +void oneWireRelease() +{ +} + +// compute CRC8 using running algorithm (slower but saves FLASH) +uint8_t doCrc8(uint8_t oldCrc, uint8_t x) +{ + uint8_t crc = oldCrc; + + for (uint8_t i = 8; i; i--) + { + uint8_t mix = (crc ^ x) & 0x01; + crc >>= 1; + if (mix) + crc ^= 0x8C; + x >>= 1; + } + + return crc; +} + +/******************************************************************************* +** NAME: oneWireSerialNum ************************************************** +******************************************************************************** + +DESCRIPTION: + // The 'oneWireSerialNum' function either reads or sets the SerialNum buffer + // that is used in the search functions 'owFirst' and 'owNext'. + // This function contains two parameters, 'serialnum_buf' is a pointer + // to a buffer provided by the caller. 'serialnum_buf' should point to + // an array of 8 unsigned chars. The second parameter is a flag called + // 'do_read' that is TRUE (1) if the operation is to read and FALSE + // (0) if the operation is to set the internal SerialNum buffer from + // the data in the provided buffer. + // + // 'serialnum_buf' - buffer to that contains the serial number to set + // when do_read = FALSE (0) and buffer to get the serial + // number when do_read = TRUE (1). + // 'do_read' - flag to indicate reading (1) or setting (0) the current + // serial number. + // + +USAGE EXAMPLES: + +AUTHOR: jassimoes + +COMMENTS: + +*******************************************************************************/ +void oneWireSerialNum(uint8_t *serialnum_buf, uint8_t do_read) +{ + uint8_t i; + + //-------------------------------------------------// + // read the internal buffer and place in 'serialnum_buf' + if (do_read) + { + for (i = 0; i < 8; i++) + { + serialnum_buf[i] = SerialNum[i]; + } + } + // set the internal buffer from the data in 'serialnum_buf' + else + { + for (i = 0; i < 8; i++) + { + SerialNum[i] = serialnum_buf[i]; + } + } +} + +/******************************************************************************* +** NAME: oneWireFindNext ******************************************************* +********************************************************************************/ +// The 'oneWireFindNext' function does a general search. +// This function continues from the previos search state. The search state +// can be reset by using the 'oneWireFindFirst' function. +// This function contains one parameter 'alarmOnly'. +// When 'alarmOnly' is TRUE (1) the find alarm command +// 0xEC is sent instead of the normal search command 0xF0. +// Using the find alarm command 0xEC will limit the search to only +// 1-Wire devices that are in an 'alarm' state. +// +// 'doReset' - TRUE (1) perform reset before search, FALSE (0) do not +// perform reset before search. +// 'alarmOnly' - TRUE (1) the find alarm command 0xEC is +// sent instead of the normal search command 0xF0 +// +// Returns: TRUE (1) : when a 1-Wire device was found and it's +// Serial Number placed in the global SerialNum +// FALSE (0): when no new device was found. Either the +// last search was the last device or there +// are no devices on the 1-Wire Net. +bool oneWireFindNext(bool doReset, bool alarmOnly) +{ + uint8_t romBitIndex = 1; + uint8_t romByteIndex = 0; + uint8_t bitMask = 1; + uint8_t attempt = 0; + uint8_t discrepMarker = 0; + bool outBit = 0; + bool result = FALSE; + uint8_t lastcrc8 = 0; + + // if the last call was the last one + if (LastDevice) + { + // reset the search + LastDiscrepancy = 0; + LastDevice = FALSE; + LastFamilyDiscrepancy = 0; + + return FALSE; + } + + // check if reset bus was requested + if (doReset) + { + // reset the 1-Wire bus + // if there is no presence pulse there is nothing to do here, return FALSE + if (!oneWireTouchReset()) + { + // reset the search + LastDiscrepancy = 0; + LastFamilyDiscrepancy = 0; + return FALSE; + } + } + + // send search command + if (alarmOnly) + { + // conditional search command (devices in alarm condition) + oneWireTouchByte(COND_SEARCH_ROM); + } + else + { + // ROM search command + oneWireTouchByte(SEARCH_ROM); + } + + do + { + attempt = 0; + + if (oneWireTouchBit(TRUE) == 1) + { + attempt = 2; + } + + if (oneWireTouchBit(TRUE) == 1) + { + attempt |= 1; + } + + if (attempt == 3) + { + // no devices present, done here + break; + } + else + { + if (attempt > 0) + { + // all connected devices reply with 0 or 1 + // write bit to perform search + outBit = attempt >> 1; + } + else + { + if (romBitIndex < LastDiscrepancy) + { + outBit = ((SerialNum[romByteIndex] & bitMask) > 0); + } + else + { + // set to 1 if it's the same, otherwise 0 + outBit = (romBitIndex == LastDiscrepancy); + } + + // on 0 record position on bitMask + if (outBit == 0) + { + discrepMarker = romBitIndex; + } + } + + // isolate bit in ROM[n] with bitMask + if (outBit == 1) + { + SerialNum[romByteIndex] |= bitMask; + } + else + { + SerialNum[romByteIndex] &= ~bitMask; + } + + // ROM search write + oneWireTouchBit(outBit); + + romBitIndex++; + + bitMask = bitMask << 1; + + // if the mask has reached 0 then go for a new ROM + if (bitMask == 0) + { + // reset mask and perform CRC8 + lastcrc8 = doCrc8(lastcrc8, SerialNum[romByteIndex]); + + romByteIndex++; + bitMask++; + } + } + + } while (romByteIndex < 8); // loop until we have all ROM bytes + + if ((romBitIndex < 65) || (lastcrc8 != 0)) + { + // search was unsuccessful reset the last discrepancy + LastDiscrepancy = 0; + } + else + { + // search was successful: set last discrepancy, device and result + LastDiscrepancy = discrepMarker; + LastDevice = (LastDiscrepancy == 0); + + // search isn't completed there are more devices present in the bus + result = TRUE; + } + + return result; +} + +/******************************************************************************* +** NAME: oneWireFindFirst ****************************************************** +********************************************************************************/ +// The 'oneWireFindFirst' finds the first device on the 1-Wire Net. +// This function contains one parameter 'alarmOnly'. When +// 'alarmOnly' is TRUE (1) the find alarm command 0xEC is +// sent instead of the normal search command 0xF0. +// Using the find alarm command 0xEC will limit the search to only +// 1-Wire devices that are in an 'alarm' state. +// +// 'portnum' - number 0 to MAX_PORTNUM-1. This number is provided to +// indicate the symbolic port number. +// 'doReset' - TRUE (1) perform reset before search, FALSE (0) do not +// perform reset before search. +// 'alarmOnly' - TRUE (1) the find alarm command 0xEC is +// sent instead of the normal search command 0xF0 +// +// Returns: TRUE (1) : when a 1-Wire device was found and it's +// Serial Number placed in the global SerialNum +// FALSE (0): There are no devices on the 1-Wire Net. +bool oneWireFindFirst(bool doReset, bool alarmOnly) +{ + // reset the search state + LastDiscrepancy = 0; + LastDevice = FALSE; + LastFamilyDiscrepancy = 0; + + // clear serial number buffer for new search + memset(SerialNum, 0, 8); + + // Call Next and return it's return value; + return oneWireFindNext(doReset, alarmOnly); +} + +// OneWire Find First/Next working thread +static void OneWireFindWorkingThread_entry(uint32_t arg) +{ + OneWireFindStruct *findStruct = (OneWireFindStruct *)arg; + + OneWireOperationResult = findStruct->FindFirst ? oneWireFindFirst(findStruct->DoReset, findStruct->AlarmOnly) + : oneWireFindNext(findStruct->DoReset, findStruct->AlarmOnly); + + // fire event for 1-Wire operarion completed + Events_Set(SYSTEM_EVENT_FLAG_ONEWIRE_MASTER); + + // terminate this thread + tx_thread_terminate(WaitingTask); +} + +HRESULT FindOneDevice(CLR_RT_StackFrame &stack, bool findFirst) +{ + NANOCLR_HEADER(); + + uint8_t *serialNumberPointer; + CLR_RT_HeapBlock hbTimeout; + CLR_INT64 *timeout; + bool eventResult = true; + + // set an infinite timeout to wait forever for the operation to complete + // this value has to be in ticks to be properly loaded by SetupTimeoutFromTicks() below + hbTimeout.SetInteger((CLR_INT64)-1); + NANOCLR_CHECK_HRESULT(stack.SetupTimeoutFromTicks(hbTimeout, timeout)); + + // this is going to be used to check for the right event in case of simultaneous 1-Wire operations + if (stack.m_customState == 1) + { + FindStruct.DoReset = stack.Arg1().NumericByRefConst().u1 != 0; + FindStruct.AlarmOnly = stack.Arg2().NumericByRefConst().u1 != 0; + FindStruct.FindFirst = findFirst; + + // because the 1-Wire bus is shared, acquire the module + oneWireAquire(); + + // spawn working thread to perform the 1-Wire operations + + // 1. allocate memory for thread stack + workingThreadStack = (uint32_t *)platform_malloc(ONEWIRE_THREAD_STACK_SIZE); + + if (workingThreadStack == NULL) + { + NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_MEMORY); + } + + // 2. create thread + uint16_t status = tx_thread_create( + WaitingTask, +#if !defined(BUILD_RTM) + (CHAR *)"1-Wire Thread", +#else + NULL, +#endif + OneWireFindWorkingThread_entry, + (uint32_t)&FindStruct, + workingThreadStack, + ONEWIRE_THREAD_STACK_SIZE, + ONEWIRE_THREAD_PRIORITY, + ONEWIRE_THREAD_PRIORITY, + TX_NO_TIME_SLICE, + TX_AUTO_START); + + if (status != TX_SUCCESS) + { + NANOCLR_SET_AND_LEAVE(CLR_E_PROCESS_EXCEPTION); + } + + // bump custom state + stack.m_customState = 2; + } + + while (eventResult) + { + if (WaitingTask->tx_thread_state == TX_TERMINATED) + { + // ONEWIRE working thread is now complete + break; + } + + // non-blocking wait allowing other threads to run while we wait for the 1-Wire operations to complete + NANOCLR_CHECK_HRESULT( + g_CLR_RT_ExecutionEngine.WaitEvents(stack.m_owningThread, *timeout, Event_OneWireHost, eventResult)); + } + + if (eventResult) + { + // event occurred + + oneWireRelease(); + + // get the result from the working thread execution + if (OneWireOperationResult) + { + // update serialNumber field + + // get a pointer to the managed object instance and check that it's not NULL + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + + // get a pointer to the serial number field in the OneWireController instance + CLR_RT_HeapBlock_Array *serialNumberField = pThis[OneWireHost::FIELD___serialNumber].DereferenceArray(); + + _ASSERTE(serialNumberField->m_numOfElements == 8); + + // get a pointer to the first element of the byte array + serialNumberPointer = (uint8_t *)serialNumberField->GetFirstElement(); + + oneWireSerialNum(serialNumberPointer, TRUE); + } + } + + // pop timeout heap block from stack + stack.PopValue(); + + // set result + stack.SetResult_Boolean(OneWireOperationResult); + + NANOCLR_NOCLEANUP(); +} + +////////////////////////// +// managed library code // +////////////////////////// + +HRESULT Library_nf_dev_onewire_nanoFramework_Device_OneWire_OneWireHost::TouchReset___BOOLEAN(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + stack.SetResult_Boolean(oneWireTouchReset()); + + NANOCLR_NOCLEANUP_NOLABEL(); +} + +HRESULT Library_nf_dev_onewire_nanoFramework_Device_OneWire_OneWireHost::TouchBit___BOOLEAN__BOOLEAN( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + stack.SetResult_Boolean(oneWireTouchBit(stack.Arg1().NumericByRefConst().u1 != 0)); + + NANOCLR_NOCLEANUP_NOLABEL(); +} + +HRESULT Library_nf_dev_onewire_nanoFramework_Device_OneWire_OneWireHost::TouchByte___U1__U1(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + stack.SetResult_U1(oneWireTouchByte((uint8_t)stack.Arg1().NumericByRefConst().u1)); + + NANOCLR_NOCLEANUP_NOLABEL(); +} + +HRESULT Library_nf_dev_onewire_nanoFramework_Device_OneWire_OneWireHost::WriteByte___U1__U1(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + uint8_t sendbyte; + + sendbyte = (uint8_t)stack.Arg1().NumericByRefConst().u1; + stack.SetResult_U1(oneWireTouchByte(sendbyte) == sendbyte ? TRUE : FALSE); + + NANOCLR_NOCLEANUP_NOLABEL(); +} + +HRESULT Library_nf_dev_onewire_nanoFramework_Device_OneWire_OneWireHost::ReadByte___U1(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + stack.SetResult_U1(oneWireTouchByte(0xFF)); + + NANOCLR_NOCLEANUP_NOLABEL(); +} + +HRESULT Library_nf_dev_onewire_nanoFramework_Device_OneWire_OneWireHost::FindFirstDevice___BOOLEAN__BOOLEAN__BOOLEAN( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + NANOCLR_CHECK_HRESULT(FindOneDevice(stack, true)); + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nf_dev_onewire_nanoFramework_Device_OneWire_OneWireHost::FindNextDevice___BOOLEAN__BOOLEAN__BOOLEAN( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + NANOCLR_CHECK_HRESULT(FindOneDevice(stack, false)); + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nf_dev_onewire_nanoFramework_Device_OneWire_OneWireHost::NativeDispose___VOID(CLR_RT_StackFrame &stack) +{ + (void)stack; + + NANOCLR_HEADER(); + + oneWireStop(); + + NANOCLR_NOCLEANUP_NOLABEL(); +} + +HRESULT Library_nf_dev_onewire_nanoFramework_Device_OneWire_OneWireHost::NativeInit___VOID(CLR_RT_StackFrame &stack) +{ + (void)stack; + + NANOCLR_HEADER(); + + NANOCLR_CHECK_HRESULT(oneWireInit()); + + NANOCLR_NOCLEANUP(); +} diff --git a/targets/AzureRTOS/SiliconLabs/_nanoCLR/nanoFramework.Device.OneWire/nf_dev_onewire_target.h b/targets/AzureRTOS/SiliconLabs/_nanoCLR/nanoFramework.Device.OneWire/nf_dev_onewire_target.h new file mode 100644 index 0000000000..56f110502a --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_nanoCLR/nanoFramework.Device.OneWire/nf_dev_onewire_target.h @@ -0,0 +1,111 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#ifndef _NF_DEV_ONEWIRE_TARGET_H_ +#define _NF_DEV_ONEWIRE_TARGET_H_ + +#include +#include +#include + +#include + +// set missing defines +#if defined(USART0) +#ifndef NF_ONEWIRE_USE_USART0 +#define NF_ONEWIRE_USE_USART0 FALSE +#endif +#else +#define NF_ONEWIRE_USE_USART0 FALSE +#endif + +#if defined(USART1) +#ifndef NF_ONEWIRE_USE_USART1 +#define NF_ONEWIRE_USE_USART1 FALSE +#endif +#else +#define NF_ONEWIRE_USE_USART1 FALSE +#endif + +#if defined(USART2) +#ifndef NF_ONEWIRE_USE_USART2 +#define NF_ONEWIRE_USE_USART2 FALSE +#endif +#else +#define NF_ONEWIRE_USE_USART2 FALSE +#endif + +#if defined(USART3) +#ifndef NF_ONEWIRE_USE_USART3 +#define NF_ONEWIRE_USE_USART3 FALSE +#endif +#else +#define NF_ONEWIRE_USE_USART3 FALSE +#endif + +#if defined(USART4) +#ifndef NF_ONEWIRE_USE_USART4 +#define NF_ONEWIRE_USE_USART4 FALSE +#endif +#else +#define NF_ONEWIRE_USE_USART4 FALSE +#endif + +#if defined(USART5) +#ifndef NF_ONEWIRE_USE_USART5 +#define NF_ONEWIRE_USE_USART5 FALSE +#endif +#else +#define NF_ONEWIRE_USE_USART5 FALSE +#endif + +// struct with parameters for 1-Wire working thread +struct OneWireFindStruct +{ + bool DoReset; + bool AlarmOnly; + bool FindFirst; +}; + +// @brief Driver state machine possible states. +typedef enum +{ + // Not initialized. + ONEWIRE_UNINIT, + // Stopped. + ONEWIRE_STOP, + // Ready. + ONEWIRE_READY, + // Generating random number. + ONEWIRE_ACTIVE +} oneWireState; + + +// character to send on the UART to mimic 1-Wire bus signals +// 1-Wire write 0 time slot +#define IWIRE_WR0 0x00 +// 1-Wire write 1 time slot +#define IWIRE_WR1 0xFF +// 1-Wire read time slot +#define IWIRE_RD 0xFF + +// ROM commands +// search ROM +#define SEARCH_ROM 0xF0 +// conditional search ROM +#define COND_SEARCH_ROM 0xEC + +#include "sl_iostream.h" +#ifdef __cplusplus +extern "C" { +#endif + +sl_status_t sl_iostream_usart_init_onewire(void); + +#ifdef __cplusplus +} +#endif + +#endif // _NF_DEV_ONEWIRE_TARGET_H_ diff --git a/targets/AzureRTOS/SiliconLabs/_nanoCLR/nanoFramework.GiantGecko.Adc/nano_gg_adc_native.cpp b/targets/AzureRTOS/SiliconLabs/_nanoCLR/nanoFramework.GiantGecko.Adc/nano_gg_adc_native.cpp new file mode 100644 index 0000000000..c47bf51e93 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_nanoCLR/nanoFramework.GiantGecko.Adc/nano_gg_adc_native.cpp @@ -0,0 +1,88 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include "nano_gg_adc_native.h" + +// clang-format off + +static const CLR_RT_MethodHandler method_lookup[] = +{ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + Library_nano_gg_adc_native_nanoFramework_GiantGecko_Adc_AdcChannel::NativeReadValue___I4__I4, + Library_nano_gg_adc_native_nanoFramework_GiantGecko_Adc_AdcChannel::NativeDisposeChannel___VOID, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + 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_nano_gg_adc_native_nanoFramework_GiantGecko_Adc_AdcController::NativeInit___VOID, + Library_nano_gg_adc_native_nanoFramework_GiantGecko_Adc_AdcController::NativeOpenChannel___VOID__I4, + Library_nano_gg_adc_native_nanoFramework_GiantGecko_Adc_AdcController::NativeGetChannelCount___I4, + Library_nano_gg_adc_native_nanoFramework_GiantGecko_Adc_AdcController::NativeIsChannelModeSupported___BOOLEAN__I4, + Library_nano_gg_adc_native_nanoFramework_GiantGecko_Adc_AdcController::NativeGetSupportedResolutionsInBits___SZARRAY_nanoFrameworkGiantGeckoAdcSampleResolution, + Library_nano_gg_adc_native_nanoFramework_GiantGecko_Adc_AdcController::NativeStartContinuousConversion___VOID__SZARRAY_I4__I4, + Library_nano_gg_adc_native_nanoFramework_GiantGecko_Adc_AdcController::NativeStopContinuousConversion___VOID, + Library_nano_gg_adc_native_nanoFramework_GiantGecko_Adc_AdcController::NativeGetLastContinuousSamples___SZARRAY_I4, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, +}; + +const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_GiantGecko_Adc = +{ + "nanoFramework.GiantGecko.Adc", + 0x0516D85F, + method_lookup, + { 100, 1, 0, 0 } +}; + +// clang-format on diff --git a/targets/AzureRTOS/SiliconLabs/_nanoCLR/nanoFramework.GiantGecko.Adc/nano_gg_adc_native.h b/targets/AzureRTOS/SiliconLabs/_nanoCLR/nanoFramework.GiantGecko.Adc/nano_gg_adc_native.h new file mode 100644 index 0000000000..d93c33bf22 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_nanoCLR/nanoFramework.GiantGecko.Adc/nano_gg_adc_native.h @@ -0,0 +1,197 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#ifndef NANO_GG_ADC_NATIVE_H +#define NANO_GG_ADC_NATIVE_H + +#include +#include +#include +#include + +typedef enum __nfpack AdcChannelMode +{ + AdcChannelMode_SingleEnded = 0, + AdcChannelMode_Differential = 1, +} AdcChannelMode; + +typedef enum __nfpack AquisitionTime +{ + AquisitionTime__1Cyle = 1, + AquisitionTime__2Cyles = 2, + AquisitionTime__3Cyles = 3, + AquisitionTime__4Cyles = 4, + AquisitionTime__8Cyles = 5, + AquisitionTime__16Cyles = 6, + AquisitionTime__32Cyles = 7, + AquisitionTime__64Cyles = 8, + AquisitionTime__128Cyles = 9, + AquisitionTime__256Cyles = 10, +} AquisitionTime; + +typedef enum __nfpack LowpassFilterMode +{ + LowpassFilterMode_Bypass = 0, + LowpassFilterMode_RcFilter = 1, + LowpassFilterMode_DecouplingCapacitor = 2, +} LowpassFilterMode; + +typedef enum __nfpack OversampleRate +{ + OversampleRate__2Samples = 0, + OversampleRate__4Samples = 1, + OversampleRate__8Samples = 2, + OversampleRate__16Samples = 3, + OversampleRate__32Samples = 4, + OversampleRate__64Samples = 5, + OversampleRate__128Samples = 6, + OversampleRate__256Samples = 7, + OversampleRate__512Samples = 8, + OversampleRate__1024Samples = 9, + OversampleRate__2048Samples = 10, + OversampleRate__4096Samples = 11, +} OversampleRate; + +typedef enum __nfpack PrsSampleTrigger +{ + PrsSampleTrigger_Disabled = -1, + PrsSampleTrigger_PrsChannel0 = 0, + PrsSampleTrigger_PrsChannel1 = 1, + PrsSampleTrigger_PrsChannel2 = 2, + PrsSampleTrigger_PrsChannel3 = 3, + PrsSampleTrigger_PrsChannel4 = 4, + PrsSampleTrigger_PrsChannel5 = 5, + PrsSampleTrigger_PrsChannel6 = 6, + PrsSampleTrigger_PrsChannel7 = 7, + PrsSampleTrigger_PrsChannel8 = 8, + PrsSampleTrigger_PrsChannel9 = 9, + PrsSampleTrigger_PrsChannel10 = 10, + PrsSampleTrigger_PrsChannel11 = 11, +} PrsSampleTrigger; + +typedef enum __nfpack ReferenceVoltage +{ + ReferenceVoltage_Internal1_25V = 0, + ReferenceVoltage_Internal2_5V = 1, + ReferenceVoltage_BufferedVdd = 2, + ReferenceVoltage_InternalDifferencial_5V = 3, + ReferenceVoltage_SingleEndedExternalPin6 = 4, + ReferenceVoltage_DiffExternalPin6And7 = 5, + ReferenceVoltage_Unbuffered2Vdd = 6, + ReferenceVoltage_InternalBandgap = 128, + ReferenceVoltage_ScaledAvdd = 129, + ReferenceVoltage_ScaledSingleEndedExternalPin6 = 130, + ReferenceVoltage_RawSingleEndedExternalPin6 = 131, + ReferenceVoltage_EntropyGeneration = 132, + ReferenceVoltage_ScaledExternalPin6And7 = 133, + ReferenceVoltage_RawExternalPin6And7 = 134, +} ReferenceVoltage; + +typedef enum __nfpack SampleResolution +{ + SampleResolution__12bits = 0, + SampleResolution__8bit = 1, + SampleResolution__6bit = 2, + SampleResolution_Oversampling = 3, +} SampleResolution; + +typedef enum __nfpack SingleSampleInput +{ + SingleSampleInput_Channel0 = 0, + SingleSampleInput_Channel1 = 1, + SingleSampleInput_Channel2 = 2, + SingleSampleInput_Channel3 = 3, + SingleSampleInput_Channel4 = 4, + SingleSampleInput_Channel5 = 5, + SingleSampleInput_Channel6 = 6, + SingleSampleInput_Channel7 = 7, + SingleSampleInput_TemperatureReference = 8, + SingleSampleInput_VddDiv3 = 9, + SingleSampleInput_Vdd = 10, + SingleSampleInput_Vss = 11, + SingleSampleInput_VrefDiv2 = 12, + SingleSampleInput_DacOutput0 = 13, + SingleSampleInput_DacOutput1 = 14, + SingleSampleInput_Atest = 15, + SingleSampleInput_Positive0Negative1 = 16, + SingleSampleInput_Positive2Negative3 = 17, + SingleSampleInput_Positive4Negative5 = 18, + SingleSampleInput_Positive6Negative7 = 19, + SingleSampleInput_Differential0 = 20, +} SingleSampleInput; + +typedef enum __nfpack WarmUpMode +{ + WarmUpMode_Normal = 0, + WarmUpMode_WarmupFastBG = 1, + WarmUpMode_KeepScanRefWarm = 2, + WarmUpMode_KeepAdcWarm = 3, +} WarmUpMode; + +struct Library_nano_gg_adc_native_nanoFramework_GiantGecko_Adc_AdcChannel +{ + static const int FIELD___syncLock = 2; + static const int FIELD___disposed = 3; + static const int FIELD___channelNumber = 4; + static const int FIELD___adcChannelConfiguration = 5; + + NANOCLR_NATIVE_DECLARE(NativeReadValue___I4__I4); + NANOCLR_NATIVE_DECLARE(NativeDisposeChannel___VOID); + + //--// +}; + +struct Library_nano_gg_adc_native_nanoFramework_GiantGecko_Adc_AdcChannelConfiguration +{ + static const int FIELD___prsSampleTrigger = 1; + static const int FIELD___aquisitionTime = 2; + static const int FIELD___referenceVoltage = 3; + static const int FIELD___sampleResolution = 4; + static const int FIELD___channelMode = 5; + + //--// +}; + +struct Library_nano_gg_adc_native_nanoFramework_GiantGecko_Adc_AdcConfiguration +{ + static const int FIELD___oversampleRate = 1; + static const int FIELD___lowpassFilterMode = 2; + static const int FIELD___warmUpMode = 3; + static const int FIELD___warnupTimeBase = 4; + static const int FIELD___prescale = 5; + static const int FIELD___tailgating = 6; + + //--// +}; + +struct Library_nano_gg_adc_native_nanoFramework_GiantGecko_Adc_AdcController +{ + static const int FIELD___syncLock = 1; + static const int FIELD___continuousSamplingStarted = 2; + static const int FIELD___adcConfiguration = 3; + static const int FIELD___adcChannelConfiguration = 4; + + NANOCLR_NATIVE_DECLARE(NativeInit___VOID); + NANOCLR_NATIVE_DECLARE(NativeOpenChannel___VOID__I4); + NANOCLR_NATIVE_DECLARE(NativeGetChannelCount___I4); + NANOCLR_NATIVE_DECLARE(NativeIsChannelModeSupported___BOOLEAN__I4); + NANOCLR_NATIVE_DECLARE(NativeGetSupportedResolutionsInBits___SZARRAY_nanoFrameworkGiantGeckoAdcSampleResolution); + NANOCLR_NATIVE_DECLARE(NativeStartContinuousConversion___VOID__SZARRAY_I4__I4); + NANOCLR_NATIVE_DECLARE(NativeStopContinuousConversion___VOID); + NANOCLR_NATIVE_DECLARE(NativeGetLastContinuousSamples___SZARRAY_I4); + + //--// +}; + +struct Library_nano_gg_adc_native_System_Device_Adc_AdcChannelBase +{ + static const int FIELD___adcController = 1; + + //--// +}; + +extern const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_GiantGecko_Adc; + +#endif // NANO_GG_ADC_NATIVE_H diff --git a/targets/AzureRTOS/SiliconLabs/_nanoCLR/nanoFramework.GiantGecko.Adc/nano_gg_adc_native_nanoFramework_GiantGecko_Adc_AdcChannel.cpp b/targets/AzureRTOS/SiliconLabs/_nanoCLR/nanoFramework.GiantGecko.Adc/nano_gg_adc_native_nanoFramework_GiantGecko_Adc_AdcChannel.cpp new file mode 100644 index 0000000000..feaf0eab9a --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_nanoCLR/nanoFramework.GiantGecko.Adc/nano_gg_adc_native_nanoFramework_GiantGecko_Adc_AdcChannel.cpp @@ -0,0 +1,140 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Portions Copyright (c) Microsoft Corporation. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +#include "nano_gg_adc_native.h" +#include "nano_gg_adc_native_target.h" + +// add typedef for AdcChannelConfiguration to ease access and improve readability +typedef Library_nano_gg_adc_native_nanoFramework_GiantGecko_Adc_AdcChannelConfiguration AdcChannelConfiguration; + +void ParseAdcChannelConfig(CLR_RT_HeapBlock *channelConfiguration, void *adcInit) +{ + ADC_InitSingle_TypeDef channelInitSingle = ADC_INITSINGLE_DEFAULT; + // ADC_InitScan_TypeDef channelInitScan = ADC_INITSCAN_DEFAULT; + + // now map the AdcChannelConfiguration object to the native structure + + // handle PRS differently because it's a C# enum and -1 is the disabled value + // if PRS is disabled, use the default value + int32_t prsSel = channelConfiguration[AdcChannelConfiguration::FIELD___prsSampleTrigger].NumericByRef().s4; + channelInitSingle.prsSel = prsSel == -1 ? adcPRSSELCh0 : (ADC_PRSSEL_TypeDef)prsSel; + + channelInitSingle.acqTime = + (ADC_AcqTime_TypeDef)channelConfiguration[AdcChannelConfiguration::FIELD___aquisitionTime].NumericByRef().s4; + channelInitSingle.reference = + (ADC_Ref_TypeDef)channelConfiguration[AdcChannelConfiguration::FIELD___referenceVoltage].NumericByRef().s4; + channelInitSingle.resolution = + (ADC_Res_TypeDef)channelConfiguration[AdcChannelConfiguration::FIELD___sampleResolution].NumericByRef().s4; + channelInitSingle.diff = + (AdcChannelMode)channelConfiguration[AdcChannelConfiguration::FIELD___channelMode].NumericByRef().s4 == + AdcChannelMode_Differential + ? true + : false; + + memcpy(adcInit, &channelInitSingle, sizeof(ADC_InitSingle_TypeDef)); +} + +HRESULT Library_nano_gg_adc_native_nanoFramework_GiantGecko_Adc_AdcChannel::NativeReadValue___I4__I4( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + int32_t channelNumber; + NF_PAL_ADC_PORT_PIN_CHANNEL adcDefinition; + + // ADC related variables + ADC_TypeDef *adcDriver = NULL; + ADC_InitSingle_TypeDef channelInitSingle; + uint64_t samplesAccumulator = 0; + int32_t averageCount; + int32_t samplesCount; + + // get a pointer to the managed object instance and check that it's not NULL + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + + // Get channel from _channelNumber field + channelNumber = pThis[FIELD___channelNumber].NumericByRef().s4; + + // OK to skip validation here because the channelNumber has been validated in the constructor + adcDefinition = AdcPortPinConfig[channelNumber]; + + // we should remove form the build the ADC options that aren't implemented + // plus we have to use the default to catch invalid ADC Ids + switch (adcDefinition.adcIndex) + { + +#if GECKO_USE_ADC0 + case 0: + adcDriver = ADC0; + break; +#endif + +#if GECKO_USE_ADC1 + case 1: + adcDriver = ADC1; + break; +#endif + + default: + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + // get the average counter + averageCount = stack.Arg1().NumericByRef().s4; + + // sanity check (need to take at least one sample) + if (averageCount < 1) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + samplesCount = averageCount; + + // get a pointer to the channel AdcChannelConfiguration object instance + ParseAdcChannelConfig(pThis[FIELD___adcChannelConfiguration].Dereference(), &channelInitSingle); + + // sanity check (only support single ended mode at this time) + if (channelInitSingle.diff) + { + NANOCLR_SET_AND_LEAVE(CLR_E_NOTIMPL); + } + + // select positive input + channelInitSingle.posSel = (ADC_PosSel_TypeDef)adcDefinition.posSel; + + ADC_InitSingle(adcDriver, &channelInitSingle); + + while (samplesCount--) + { + // start the conversion + ADC_Start(adcDriver, adcStartSingle); + + // Wait for conversion to complete + while (ADC0->STATUS & ADC_STATUS_SINGLEACT) + ; + + // store sample + samplesAccumulator += ADC_DataSingleGet(adcDriver); + } + + // set the return result with the conversion value averaged from the accumulator + stack.SetResult_I4(samplesAccumulator / averageCount); + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nano_gg_adc_native_nanoFramework_GiantGecko_Adc_AdcChannel::NativeDisposeChannel___VOID( + CLR_RT_StackFrame &stack) +{ + (void)stack; + + NANOCLR_HEADER(); + + // left empty on purpose, nothing to do here + + NANOCLR_NOCLEANUP_NOLABEL(); +} diff --git a/targets/AzureRTOS/SiliconLabs/_nanoCLR/nanoFramework.GiantGecko.Adc/nano_gg_adc_native_nanoFramework_GiantGecko_Adc_AdcController.cpp b/targets/AzureRTOS/SiliconLabs/_nanoCLR/nanoFramework.GiantGecko.Adc/nano_gg_adc_native_nanoFramework_GiantGecko_Adc_AdcController.cpp new file mode 100644 index 0000000000..ff93141af5 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_nanoCLR/nanoFramework.GiantGecko.Adc/nano_gg_adc_native_nanoFramework_GiantGecko_Adc_AdcController.cpp @@ -0,0 +1,473 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Portions Copyright (c) Microsoft Corporation. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +#include "nano_gg_adc_native.h" +#include "nano_gg_adc_native_target.h" + +#define ADC_IMPOSSIBLE_CLOCK 90000000UL + +#if GECKO_USE_ADC0 +ADC_Init_TypeDef adc0Init; +bool adc0Initialized = false; +#endif +#if GECKO_USE_ADC1 +ADC_Init_TypeDef adc1Init; +bool adc1Initialized = false; +#endif + +NF_PAL_GECKO_ADC_CONTINUOUS_SCAN *ContinuousScanOperation; + +// add typedef for AdcConfiguration to ease access and improve readability +typedef Library_nano_gg_adc_native_nanoFramework_GiantGecko_Adc_AdcConfiguration AdcConfiguration; + +extern void ParseAdcChannelConfig(CLR_RT_HeapBlock *channelConfiguration, void *adcInit); + +// helper function to take care of init and config ADC, if not already done +HRESULT OpenAdcChannel(int32_t channelNumber, CLR_RT_HeapBlock *adcConfiguration, ADC_TypeDef *adcDriver) +{ + NANOCLR_HEADER(); + + NF_PAL_ADC_PORT_PIN_CHANNEL adcChannelDefinition; + CMU_Clock_TypeDef adcClock; + ADC_Init_TypeDef *adcInit = NULL; + bool *adcInitialized = NULL; + + // sanity check for existing configuration + if (channelNumber >= AdcChannelCount) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + // grab ADC channel definition + adcChannelDefinition = AdcPortPinConfig[channelNumber]; + + // we should remove from the build the ADC options that aren't implemented + // plus we have to use the default to catch invalid ADC Ids + switch (adcChannelDefinition.adcIndex) + { + +#if GECKO_USE_ADC0 + case 0: + adcDriver = ADC0; + adcClock = cmuClock_ADC0; + adcInit = &adc0Init; + adcInitialized = &adc0Initialized; + break; +#endif + +#if GECKO_USE_ADC1 + case 1: + adcDriver = ADC1; + adcClock = cmuClock_ADC1; + adcInit = &adc1Init; + adcInitialized = &adc1Initialized; + break; +#endif + + default: + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + // is this ADC already initialized? + if ( +#if GECKO_USE_ADC0 + (adcDriver == ADC0 && !*adcInitialized) +#endif +#if GECKO_USE_ADC0 && GECKO_USE_ADC1 + || +#endif +#if GECKO_USE_ADC1 + (adcDriver == ADC1 && !*adcInitialized) +#endif + ) + { + // init with default values + *adcInit = ADC_INIT_DEFAULT; + + // now map the AdcConfiguration object to the native structure + adcInit->ovsRateSel = + (ADC_OvsRateSel_TypeDef)adcConfiguration[AdcConfiguration::FIELD___oversampleRate].NumericByRef().s4; + +#if defined(_ADC_CTRL_LPFMODE_MASK) + adcInit->lpfMode = + (ADC_LPFilter_TypeDef)adcConfiguration[AdcConfiguration::FIELD___lowpassFilterMode].NumericByRef().s4; +#endif + + adcInit->warmUpMode = + (ADC_Warmup_TypeDef)adcConfiguration[AdcConfiguration::FIELD___warmUpMode].NumericByRef().s4; + adcInit->tailgate = (bool)adcConfiguration[AdcConfiguration::FIELD___tailgating].NumericByRef().u1; + + // Enable ADC clock + CMU_ClockEnable(adcClock, true); + + // init to max possible ADC clock + adcInit->prescale = ADC_PrescaleCalc(ADC_IMPOSSIBLE_CLOCK, 0); + // let the drivers compute the appropriate value for the reference clock + adcInit->timebase = ADC_TimebaseCalc(0); + +#if defined(_ADC_CTRL_ADCCLKMODE_MASK) + adcInit->em2ClockConfig = adcEm2Disabled; +#endif + + ADC_Reset(adcDriver); + + // init ADC + ADC_Init(adcDriver, adcInit); + + // set ADC initialized flag + *adcInitialized = true; + } + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nano_gg_adc_native_nanoFramework_GiantGecko_Adc_AdcController::NativeInit___VOID( + CLR_RT_StackFrame &stack) +{ + (void)stack; + + NANOCLR_HEADER(); + + // all required initialization for ADC is handled in OpenChannel call + + NANOCLR_NOCLEANUP_NOLABEL(); +} + +HRESULT Library_nano_gg_adc_native_nanoFramework_GiantGecko_Adc_AdcController::NativeOpenChannel___VOID__I4( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + CLR_RT_HeapBlock *adcConfiguration; + int32_t channelNumber; + ADC_TypeDef *adcDriver; + + // get a pointer to the managed object instance and check that it's not NULL + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + + // get a pointer to the managed AdcConfiguration object instance + adcConfiguration = pThis[FIELD___adcConfiguration].Dereference(); + + // Get channel from argument + channelNumber = stack.Arg1().NumericByRef().s4; + + // take care of configuring ADC, if not already done + NANOCLR_CHECK_HRESULT(OpenAdcChannel(channelNumber, adcConfiguration, adcDriver)); + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nano_gg_adc_native_nanoFramework_GiantGecko_Adc_AdcController::NativeGetChannelCount___I4( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + // Return value to the managed application + stack.SetResult_I4(AdcChannelCount); + + NANOCLR_NOCLEANUP_NOLABEL(); +} + +HRESULT Library_nano_gg_adc_native_nanoFramework_GiantGecko_Adc_AdcController:: + NativeIsChannelModeSupported___BOOLEAN__I4(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + int mode = stack.Arg1().NumericByRef().s4; + + // Only support Single ended mode for now + stack.SetResult_Boolean((mode == (int)AdcChannelMode_SingleEnded)); + + NANOCLR_NOCLEANUP_NOLABEL(); +} + +HRESULT Library_nano_gg_adc_native_nanoFramework_GiantGecko_Adc_AdcController:: + NativeGetSupportedResolutionsInBits___SZARRAY_nanoFrameworkGiantGeckoAdcSampleResolution(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + CLR_RT_TypeDef_Index adcSampleResolutionTypeDef; + CLR_RT_HeapBlock_Array *supportedResolutions; + CLR_INT32 *resolution = NULL; + + uint16_t resolutionsCount = 0; + +#if defined(_ADC_SINGLECTRL_RES_12BIT) + resolutionsCount++; +#endif +#if defined(_ADC_SINGLECTRL_RES_8BIT) + resolutionsCount++; +#endif +#if defined(_ADC_SINGLECTRL_RES_6BIT) + resolutionsCount++; +#endif +#if defined(_ADC_SINGLECTRL_RES_OVS) + resolutionsCount++; +#endif + + // start composing the reply + // find type definition, don't bother checking the result as it exists for sure + g_CLR_RT_TypeSystem.FindTypeDef("SampleResolution", "nanoFramework.GiantGecko.Adc", adcSampleResolutionTypeDef); + + // create an array of + NANOCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance( + stack.PushValueAndClear(), + resolutionsCount, + adcSampleResolutionTypeDef)); + + // the code below is assigning INT32 values to the elements, which aren't exactly the same as the enum values + // but the enum values are the same as the INT32 values, so it's ok + + if (resolutionsCount > 0) + { + supportedResolutions = stack.TopValue().DereferenceArray(); + +#if defined(_ADC_SINGLECTRL_RES_12BIT) + resolution = (CLR_INT32 *)supportedResolutions->GetElement(--resolutionsCount); + *resolution = adcRes12Bit; +#endif + +#if defined(_ADC_SINGLECTRL_RES_8BIT) + resolution = (CLR_INT32 *)supportedResolutions->GetElement(--resolutionsCount); + *resolution = adcRes8Bit; +#endif + +#if defined(_ADC_SINGLECTRL_RES_6BIT) + resolution = (CLR_INT32 *)supportedResolutions->GetElement(--resolutionsCount); + *resolution = adcRes6Bit; +#endif + +#if defined(_ADC_SINGLECTRL_RES_OVS) + resolution = (CLR_INT32 *)supportedResolutions->GetElement(--resolutionsCount); + *resolution = adcResOVS; +#endif + } + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nano_gg_adc_native_nanoFramework_GiantGecko_Adc_AdcController:: + NativeStartContinuousConversion___VOID__SZARRAY_I4__I4(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + uint32_t averageCount; + uint32_t channelIndex = 0; + int32_t channelNumber; + ADC_InitScan_TypeDef channelInitScan = ADC_INITSCAN_DEFAULT; + ADC_TypeDef *adcDriver = NULL; + + NF_PAL_ADC_PORT_PIN_CHANNEL adcChannelDefinition; + + CLR_RT_HeapBlock_Array *adcChannelsToScan; + CLR_RT_HeapBlock *adcConfiguration; + + // get a pointer to the managed object instance and check that it's not NULL + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + + // get the average count + averageCount = stack.Arg2().NumericByRef().s4; + + // sanity check (need to take at least one sample) + if (averageCount < 1) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + // get a pointer to the AdcChannelConfiguration object instance + ParseAdcChannelConfig(pThis[FIELD___adcChannelConfiguration].Dereference(), &channelInitScan); + // enable FIFO overflow to overwrite old data + channelInitScan.fifoOverwrite = true; + + // get a pointer to the managed AdcConfiguration object instance + adcConfiguration = pThis[FIELD___adcConfiguration].Dereference(); + + // loop through all channels + adcChannelsToScan = (CLR_RT_HeapBlock_Array *)stack.Arg1().DereferenceArray(); + + // sanity check (need to have at least one channel) + if (adcChannelsToScan->m_numOfElements < 1) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + // alloc memory for the scan operation + ContinuousScanOperation = + (NF_PAL_GECKO_ADC_CONTINUOUS_SCAN *)platform_malloc(sizeof(NF_PAL_GECKO_ADC_CONTINUOUS_SCAN)); + + // sanity check + if (ContinuousScanOperation == NULL) + { + NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_MEMORY); + } + + // alloc memory for the data buffer + ContinuousScanOperation->dataBuffer = + (uint32_t *)platform_malloc(adcChannelsToScan->m_numOfElements * averageCount * sizeof(uint32_t)); + + // sanity check + if (ContinuousScanOperation->dataBuffer == NULL) + { + NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_MEMORY); + } + + // clear the data buffer + memset( + ContinuousScanOperation->dataBuffer, + 0, + adcChannelsToScan->m_numOfElements * averageCount * sizeof(uint32_t)); + + // store the number of channels + ContinuousScanOperation->channelCount = adcChannelsToScan->m_numOfElements; + // store the average count + ContinuousScanOperation->averageCount = averageCount; + + while (channelIndex < ContinuousScanOperation->channelCount) + { + channelNumber = ((CLR_RT_HeapBlock *)adcChannelsToScan->GetElement(channelIndex++))->NumericByRefConst().s4; + + // take care of configuring ADC, if not already done + NANOCLR_CHECK_HRESULT(OpenAdcChannel(channelNumber, adcConfiguration, adcDriver)); + + // grab ADC channel definition + adcChannelDefinition = AdcPortPinConfig[channelNumber]; + + // select ADC input + ADC_ScanSingleEndedInputAdd(&channelInitScan, adcScanInputGroup0, adcChannelDefinition.posSel); + } + + // set scan data valid level (DVL) to 2 + adcDriver->SCANCTRLX |= (ContinuousScanOperation->channelCount - 1) << _ADC_SCANCTRLX_DVL_SHIFT; + + // clear ADC Scan FIFO + adcDriver->SCANFIFOCLEAR = ADC_SCANFIFOCLEAR_SCANFIFOCLEAR; + + // start ADC scan + ADC_InitScan(adcDriver, &channelInitScan); + + // clearn and enable Scan interrupts + ADC_IntClear(adcDriver, ADC_IEN_SCAN); + ADC_IntEnable(adcDriver, ADC_IEN_SCAN); + + // Enable ADC Interrupts + NVIC_ClearPendingIRQ(ADC0_IRQn); + NVIC_EnableIRQ(ADC0_IRQn); + + // done here: update flag + pThis[FIELD___continuousSamplingStarted].NumericByRef().u1 = (CLR_UINT8) true; + + NANOCLR_CLEANUP(); + + // clean up if needed + if (FAILED(hr)) + { + // free memory for the scan operation + if (ContinuousScanOperation != NULL) + { + if (ContinuousScanOperation->dataBuffer != NULL) + { + platform_free(ContinuousScanOperation->dataBuffer); + } + + platform_free(ContinuousScanOperation); + + ContinuousScanOperation = NULL; + } + } + + NANOCLR_CLEANUP_END(); +} + +HRESULT Library_nano_gg_adc_native_nanoFramework_GiantGecko_Adc_AdcController::NativeStopContinuousConversion___VOID( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + // get a pointer to the managed object instance and check that it's not NULL + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + + // disable ADC Interrupt + NVIC_DisableIRQ(ADC0_IRQn); + + // clear memory for the scan operation + platform_free(ContinuousScanOperation->dataBuffer); + platform_free(ContinuousScanOperation); + ContinuousScanOperation = NULL; + + // all good, update flag + pThis[FIELD___continuousSamplingStarted].NumericByRef().u1 = (CLR_UINT8) false; + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nano_gg_adc_native_nanoFramework_GiantGecko_Adc_AdcController:: + NativeGetLastContinuousSamples___SZARRAY_I4(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + CLR_INT32 *sample = NULL; + // assuming that, at 12 bits resolution, this will be enough to hold the average + uint64_t samplesAccumulator = 0; + + CLR_RT_HeapBlock_Array *sampleArray; + + // create an array of + NANOCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance( + stack.PushValueAndClear(), + ContinuousScanOperation->channelCount, + g_CLR_RT_WellKnownTypes.m_Int32)); + + sampleArray = stack.TopValue().DereferenceArray(); + + for (uint32_t channelIndex = 0; channelIndex < ContinuousScanOperation->channelCount; channelIndex++) + { + // compute average + // 1. accumulate samples + for (uint32_t sampleIndex = 0; sampleIndex < ContinuousScanOperation->averageCount; sampleIndex++) + { + samplesAccumulator += + ContinuousScanOperation->dataBuffer[channelIndex * ContinuousScanOperation->averageCount + sampleIndex]; + } + + // 2. set array element with the average + sample = ((CLR_INT32 *)sampleArray->GetElement(channelIndex)); + *sample = (CLR_INT32)(samplesAccumulator / ContinuousScanOperation->averageCount); + } + + NANOCLR_NOCLEANUP(); +} + +// IRQ handler for ADC0 +void ADC0_IRQHandler(void) +{ + uint32_t data, i, scanId; + + // Get ADC results + for (i = 0; i < ContinuousScanOperation->channelCount; i++) + { + // Read data from ADC + data = ADC_DataIdScanGet(ADC0, &scanId); + + ContinuousScanOperation + ->dataBuffer[i * ContinuousScanOperation->averageCount + ContinuousScanOperation->currentIndex] = data; + } + + // increment the index + ContinuousScanOperation->currentIndex++; + + // check index + if (ContinuousScanOperation->currentIndex == ContinuousScanOperation->averageCount) + { + // reset index + ContinuousScanOperation->currentIndex = 0; + } + + // Start next ADC conversion + ADC_Start(ADC0, adcStartScan); +} diff --git a/targets/AzureRTOS/SiliconLabs/_nanoCLR/nanoFramework.GiantGecko.Adc/nano_gg_adc_native_target.h b/targets/AzureRTOS/SiliconLabs/_nanoCLR/nanoFramework.GiantGecko.Adc/nano_gg_adc_native_target.h new file mode 100644 index 0000000000..adba03e347 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_nanoCLR/nanoFramework.GiantGecko.Adc/nano_gg_adc_native_target.h @@ -0,0 +1,59 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#ifndef NANO_GG_ADC_NATIVE_TARGET_H +#define NANO_GG_ADC_NATIVE_TARGET_H + +#include +#include +#include "em_cmu.h" + +#include "nano_gg_adc_native.h" +#include + +// set missing defines +#ifndef GECKO_USE_ADC0 +#define GECKO_USE_ADC0 FALSE +#endif +#ifndef GECKO_USE_ADC1 +#define GECKO_USE_ADC1 FALSE +#endif +#ifndef GECKO_USE_ADC2 +#define GECKO_USE_ADC2 FALSE +#endif +#ifndef GECKO_USE_ADC3 +#define GECKO_USE_ADC3 FALSE +#endif + +typedef struct +{ + uint8_t adcIndex; + ADC_PosSel_TypeDef posSel; +} NF_PAL_ADC_PORT_PIN_CHANNEL; + +typedef struct +{ + uint8_t channelCount; + uint32_t *dataBuffer; + uint32_t averageCount; + uint32_t currentIndex; +} NF_PAL_GECKO_ADC_CONTINUOUS_SCAN; + + +extern const NF_PAL_ADC_PORT_PIN_CHANNEL AdcPortPinConfig[]; +extern const int AdcChannelCount; +extern NF_PAL_GECKO_ADC_CONTINUOUS_SCAN* ContinuousScanOperation; + +#if GECKO_USE_ADC0 +extern ADC_Init_TypeDef adc0Init; +extern bool adc0Initialized; +#endif +#if GECKO_USE_ADC1 +extern ADC_Init_TypeDef adc1Init; +extern bool adc1Initialized; +#endif + + +#endif // NANO_GG_ADC_NATIVE_TARGET_H diff --git a/targets/AzureRTOS/SiliconLabs/_nanoCLR/nanoFramework.GiantGecko.Adc/sys_dev_adc_native_target.h b/targets/AzureRTOS/SiliconLabs/_nanoCLR/nanoFramework.GiantGecko.Adc/sys_dev_adc_native_target.h new file mode 100644 index 0000000000..c032386018 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_nanoCLR/nanoFramework.GiantGecko.Adc/sys_dev_adc_native_target.h @@ -0,0 +1,6 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +// need to have this here to keep the includes happy diff --git a/targets/AzureRTOS/SiliconLabs/_nanoCLR/nanoFramework.Hardware.GiantGecko/nf_hardware_giantgecko.cpp b/targets/AzureRTOS/SiliconLabs/_nanoCLR/nanoFramework.Hardware.GiantGecko/nf_hardware_giantgecko.cpp new file mode 100644 index 0000000000..4b350620f1 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_nanoCLR/nanoFramework.Hardware.GiantGecko/nf_hardware_giantgecko.cpp @@ -0,0 +1,42 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include "nf_hardware_giantgecko.h" + +// clang-format off + +static const CLR_RT_MethodHandler method_lookup[] = +{ + Library_nf_hardware_giantgecko_nanoFramework_Hardware_GiantGecko_GpioConfiguration::SetSlewRate___STATIC__VOID__I4__U1, + Library_nf_hardware_giantgecko_nanoFramework_Hardware_GiantGecko_GpioConfiguration::SetSlewRateAlternate___STATIC__VOID__I4__U1, + Library_nf_hardware_giantgecko_nanoFramework_Hardware_GiantGecko_GpioConfiguration::SetDriveStrenght___STATIC__VOID__I4__nanoFrameworkHardwareGiantGeckoGpioConfigurationDriveStrenght, + Library_nf_hardware_giantgecko_nanoFramework_Hardware_GiantGecko_GpioConfiguration::SetDriveStrenghtAlternate___STATIC__VOID__I4__nanoFrameworkHardwareGiantGeckoGpioConfigurationDriveStrenght, + NULL, + NULL, + Library_nf_hardware_giantgecko_nanoFramework_Hardware_GiantGecko_Power::NativeEnterHibernateMode___STATIC__VOID, + Library_nf_hardware_giantgecko_nanoFramework_Hardware_GiantGecko_Power::NativeEnterShutoffMode___STATIC__VOID, + NULL, + Library_nf_hardware_giantgecko_nanoFramework_Hardware_GiantGecko_Rtc::GetAlarm___STATIC__SystemDateTime, + Library_nf_hardware_giantgecko_nanoFramework_Hardware_GiantGecko_Rtc::NativeRtcSetAlarm___STATIC__VOID__I4__U1__U1__U1__U1__U1, + NULL, + NULL, + NULL, + NULL, + NULL, + Library_nf_hardware_giantgecko_nanoFramework_Hardware_GiantGecko_Utilities::NativeGetDeviceUniqueId___STATIC__VOID__SZARRAY_U1, + Library_nf_hardware_giantgecko_nanoFramework_Hardware_GiantGecko_Utilities::NativeGetProductionRevision___STATIC__U1, + Library_nf_hardware_giantgecko_nanoFramework_Hardware_GiantGecko_Utilities::NativeGetDeviceFamily___STATIC__U1, + Library_nf_hardware_giantgecko_nanoFramework_Hardware_GiantGecko_Utilities::NativeGetDeviceNumber___STATIC__U1, +}; + +const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_GiantGecko = +{ + "nanoFramework.Hardware.GiantGecko", + 0xF42EF338, + method_lookup, + { 100, 0, 0, 2 } +}; + +// clang-format on diff --git a/targets/AzureRTOS/SiliconLabs/_nanoCLR/nanoFramework.Hardware.GiantGecko/nf_hardware_giantgecko.h b/targets/AzureRTOS/SiliconLabs/_nanoCLR/nanoFramework.Hardware.GiantGecko/nf_hardware_giantgecko.h new file mode 100644 index 0000000000..470e245529 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_nanoCLR/nanoFramework.Hardware.GiantGecko/nf_hardware_giantgecko.h @@ -0,0 +1,67 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#ifndef NF_HARDWARE_GIANTGECKO_H +#define NF_HARDWARE_GIANTGECKO_H + +#include +#include +#include +#include + +typedef enum __nfpack GpioConfiguration_DriveStrenght +{ + GpioConfiguration_DriveStrenght_Strong = 0, + GpioConfiguration_DriveStrenght_Weak = 1, +} GpioConfiguration_DriveStrenght; + +struct Library_nf_hardware_giantgecko_nanoFramework_Hardware_GiantGecko_GpioConfiguration +{ + NANOCLR_NATIVE_DECLARE(SetSlewRate___STATIC__VOID__I4__U1); + NANOCLR_NATIVE_DECLARE(SetSlewRateAlternate___STATIC__VOID__I4__U1); + NANOCLR_NATIVE_DECLARE( + SetDriveStrenght___STATIC__VOID__I4__nanoFrameworkHardwareGiantGeckoGpioConfigurationDriveStrenght); + NANOCLR_NATIVE_DECLARE( + SetDriveStrenghtAlternate___STATIC__VOID__I4__nanoFrameworkHardwareGiantGeckoGpioConfigurationDriveStrenght); + + //--// + static HRESULT SetSlewRate(CLR_RT_StackFrame &stack, bool isAlternate); + static HRESULT SetDriveStrenght(CLR_RT_StackFrame &stack, bool isAlternate); +}; + +struct Library_nf_hardware_giantgecko_nanoFramework_Hardware_GiantGecko_Power +{ + NANOCLR_NATIVE_DECLARE(NativeEnterHibernateMode___STATIC__VOID); + NANOCLR_NATIVE_DECLARE(NativeEnterShutoffMode___STATIC__VOID); + + //--// +}; + +struct Library_nf_hardware_giantgecko_nanoFramework_Hardware_GiantGecko_Rtc +{ + NANOCLR_NATIVE_DECLARE(GetAlarm___STATIC__SystemDateTime); + NANOCLR_NATIVE_DECLARE(NativeRtcSetAlarm___STATIC__VOID__I4__U1__U1__U1__U1__U1); + + //--// +}; + +struct Library_nf_hardware_giantgecko_nanoFramework_Hardware_GiantGecko_Utilities +{ + static const int FIELD_STATIC___deviceUniqueId = 0; + static const int FIELD_STATIC___productionRevision = 1; + static const int FIELD_STATIC___deviceFamily = 2; + static const int FIELD_STATIC___deviceNumber = 3; + + NANOCLR_NATIVE_DECLARE(NativeGetDeviceUniqueId___STATIC__VOID__SZARRAY_U1); + NANOCLR_NATIVE_DECLARE(NativeGetProductionRevision___STATIC__U1); + NANOCLR_NATIVE_DECLARE(NativeGetDeviceFamily___STATIC__U1); + NANOCLR_NATIVE_DECLARE(NativeGetDeviceNumber___STATIC__U1); + + //--// +}; + +extern const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_GiantGecko; + +#endif // NF_HARDWARE_GIANTGECKO_H diff --git a/targets/AzureRTOS/SiliconLabs/_nanoCLR/nanoFramework.Hardware.GiantGecko/nf_hardware_giantgecko_nanoFramework_Hardware_GiantGecko_GpioConfiguration.cpp b/targets/AzureRTOS/SiliconLabs/_nanoCLR/nanoFramework.Hardware.GiantGecko/nf_hardware_giantgecko_nanoFramework_Hardware_GiantGecko_GpioConfiguration.cpp new file mode 100644 index 0000000000..97faf74814 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_nanoCLR/nanoFramework.Hardware.GiantGecko/nf_hardware_giantgecko_nanoFramework_Hardware_GiantGecko_GpioConfiguration.cpp @@ -0,0 +1,146 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include "nf_hardware_giantgecko.h" +#include +#include +#include +#include + +// need these declared as extern here because they belong to GPIO driver +extern bool CPU_GPIO_PinIsBusy(GPIO_PIN pinNumber); +extern void GetIoLine(int16_t pinNumber, GPIO_Port_TypeDef *port, uint32_t *portPin); + +HRESULT Library_nf_hardware_giantgecko_nanoFramework_Hardware_GiantGecko_GpioConfiguration:: + SetSlewRate___STATIC__VOID__I4__U1(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + NANOCLR_CHECK_HRESULT(SetSlewRate(stack, false)); + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nf_hardware_giantgecko_nanoFramework_Hardware_GiantGecko_GpioConfiguration:: + SetSlewRateAlternate___STATIC__VOID__I4__U1(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + NANOCLR_CHECK_HRESULT(SetSlewRate(stack, true)); + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nf_hardware_giantgecko_nanoFramework_Hardware_GiantGecko_GpioConfiguration:: + SetDriveStrenght___STATIC__VOID__I4__nanoFrameworkHardwareGiantGeckoGpioConfigurationDriveStrenght( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + NANOCLR_CHECK_HRESULT(SetDriveStrenght(stack, false)); + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nf_hardware_giantgecko_nanoFramework_Hardware_GiantGecko_GpioConfiguration:: + SetDriveStrenghtAlternate___STATIC__VOID__I4__nanoFrameworkHardwareGiantGeckoGpioConfigurationDriveStrenght( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + NANOCLR_CHECK_HRESULT(SetDriveStrenght(stack, true)); + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nf_hardware_giantgecko_nanoFramework_Hardware_GiantGecko_GpioConfiguration::SetSlewRate( + CLR_RT_StackFrame &stack, + bool isAlternate) +{ + NANOCLR_HEADER(); + + GPIO_PIN pinNumber; + uint8_t slewRate; + GPIO_Port_TypeDef *port; + uint32_t *portPin; + + // get the pin number + pinNumber = (GPIO_PIN)stack.Arg0().NumericByRef().s4; + + // check if this is a valid GPIO pin + if (!CPU_GPIO_PinIsBusy(pinNumber)) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + + // get the slew rate + slewRate = (uint8_t)stack.Arg1().NumericByRef().u1; + + // check if the slew rate is valid + // OK to use the NON alternate mask here because the value is the same for both + if (slewRate > (_GPIO_P_CTRL_SLEWRATE_MASK >> _GPIO_P_CTRL_SLEWRATE_SHIFT)) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + // get the port and pin + GetIoLine(pinNumber, port, portPin); + + // replicate the code from the Gecko SDK + if (isAlternate) + { + GPIO->P[*port].CTRL = + (GPIO->P[*port].CTRL & ~(_GPIO_P_CTRL_SLEWRATEALT_MASK)) | (slewRate << _GPIO_P_CTRL_SLEWRATEALT_SHIFT); + } + else + { + GPIO->P[*port].CTRL = + (GPIO->P[*port].CTRL & ~(_GPIO_P_CTRL_SLEWRATE_MASK)) | (slewRate << _GPIO_P_CTRL_SLEWRATE_SHIFT); + } + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nf_hardware_giantgecko_nanoFramework_Hardware_GiantGecko_GpioConfiguration::SetDriveStrenght( + CLR_RT_StackFrame &stack, + bool isAlternate) +{ + NANOCLR_HEADER(); + + GPIO_PIN pinNumber; + GPIO_DriveStrength_TypeDef strength; + GPIO_Port_TypeDef *port; + uint32_t *portPin; + + // get the pin number + pinNumber = (GPIO_PIN)stack.Arg0().NumericByRef().s4; + + // check if this is a valid GPIO pin + if (!CPU_GPIO_PinIsBusy(pinNumber)) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + + // get the drive strenght + strength = (GPIO_DriveStrength_TypeDef)stack.Arg1().NumericByRef().u1; + + // get the port and pin + GetIoLine(pinNumber, port, portPin); + + // replicate the code from the Gecko SDK + if (isAlternate) + { + BUS_RegMaskedWrite( + &GPIO->P[*port].CTRL, + _GPIO_P_CTRL_DRIVESTRENGTHALT_MASK, + strength << _GPIO_P_CTRL_DRIVESTRENGTHALT_SHIFT); + } + else + { + BUS_RegMaskedWrite(&GPIO->P[*port].CTRL, _GPIO_P_CTRL_DRIVESTRENGTH_MASK, strength); + } + + NANOCLR_NOCLEANUP(); +} diff --git a/targets/AzureRTOS/SiliconLabs/_nanoCLR/nanoFramework.Hardware.GiantGecko/nf_hardware_giantgecko_nanoFramework_Hardware_GiantGecko_Power.cpp b/targets/AzureRTOS/SiliconLabs/_nanoCLR/nanoFramework.Hardware.GiantGecko/nf_hardware_giantgecko_nanoFramework_Hardware_GiantGecko_Power.cpp new file mode 100644 index 0000000000..9ac69f5a51 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_nanoCLR/nanoFramework.Hardware.GiantGecko/nf_hardware_giantgecko_nanoFramework_Hardware_GiantGecko_Power.cpp @@ -0,0 +1,25 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include "nf_hardware_giantgecko.h" + + +HRESULT Library_nf_hardware_giantgecko_nanoFramework_Hardware_GiantGecko_Power::NativeEnterHibernateMode___STATIC__VOID( CLR_RT_StackFrame &stack ) +{ + NANOCLR_HEADER(); + + NANOCLR_SET_AND_LEAVE(stack.NotImplementedStub()); + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nf_hardware_giantgecko_nanoFramework_Hardware_GiantGecko_Power::NativeEnterShutoffMode___STATIC__VOID( CLR_RT_StackFrame &stack ) +{ + NANOCLR_HEADER(); + + NANOCLR_SET_AND_LEAVE(stack.NotImplementedStub()); + + NANOCLR_NOCLEANUP(); +} diff --git a/targets/AzureRTOS/SiliconLabs/_nanoCLR/nanoFramework.Hardware.GiantGecko/nf_hardware_giantgecko_nanoFramework_Hardware_GiantGecko_RTC.cpp b/targets/AzureRTOS/SiliconLabs/_nanoCLR/nanoFramework.Hardware.GiantGecko/nf_hardware_giantgecko_nanoFramework_Hardware_GiantGecko_RTC.cpp new file mode 100644 index 0000000000..86509d49e1 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_nanoCLR/nanoFramework.Hardware.GiantGecko/nf_hardware_giantgecko_nanoFramework_Hardware_GiantGecko_RTC.cpp @@ -0,0 +1,25 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include "nf_hardware_giantgecko.h" + + +HRESULT Library_nf_hardware_giantgecko_nanoFramework_Hardware_GiantGecko_Rtc::GetAlarm___STATIC__SystemDateTime( CLR_RT_StackFrame &stack ) +{ + NANOCLR_HEADER(); + + NANOCLR_SET_AND_LEAVE(stack.NotImplementedStub()); + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nf_hardware_giantgecko_nanoFramework_Hardware_GiantGecko_Rtc::NativeRtcSetAlarm___STATIC__VOID__I4__U1__U1__U1__U1__U1( CLR_RT_StackFrame &stack ) +{ + NANOCLR_HEADER(); + + NANOCLR_SET_AND_LEAVE(stack.NotImplementedStub()); + + NANOCLR_NOCLEANUP(); +} diff --git a/targets/AzureRTOS/SiliconLabs/_nanoCLR/nanoFramework.Hardware.GiantGecko/nf_hardware_giantgecko_nanoFramework_Hardware_GiantGecko_Utilities.cpp b/targets/AzureRTOS/SiliconLabs/_nanoCLR/nanoFramework.Hardware.GiantGecko/nf_hardware_giantgecko_nanoFramework_Hardware_GiantGecko_Utilities.cpp new file mode 100644 index 0000000000..117a661441 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_nanoCLR/nanoFramework.Hardware.GiantGecko/nf_hardware_giantgecko_nanoFramework_Hardware_GiantGecko_Utilities.cpp @@ -0,0 +1,83 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include "nf_hardware_giantgecko.h" +#include + +HRESULT Library_nf_hardware_giantgecko_nanoFramework_Hardware_GiantGecko_Utilities:: + NativeGetDeviceUniqueId___STATIC__VOID__SZARRAY_U1(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + // device Unique ID is 64 bits long + uint8_t deviceUID[8]; + + // high 32 bits + uint32_t rawId = DEVINFO->UNIQUEH; + + deviceUID[3] = rawId; + rawId >>= 8; + deviceUID[2] = rawId; + rawId >>= 8; + deviceUID[1] = rawId; + rawId >>= 8; + deviceUID[0] = rawId; + + // low 32 bits + rawId = DEVINFO->UNIQUEL; + + deviceUID[7] = rawId; + rawId >>= 8; + deviceUID[6] = rawId; + rawId >>= 8; + deviceUID[5] = rawId; + rawId >>= 8; + deviceUID[4] = rawId; + + // dereference the data buffer from the argument + CLR_RT_HeapBlock_Array *buffer = stack.Arg0().DereferenceArray(); + + // get a the pointer to the byffer by using the first element of the array + uint8_t *data = buffer->GetFirstElement(); + + // 64 bit unique device ID => 16 bytes + // memory copy from the address pointed by deviceUID + memcpy(data, deviceUID, 8); + + NANOCLR_NOCLEANUP_NOLABEL(); +} + +HRESULT Library_nf_hardware_giantgecko_nanoFramework_Hardware_GiantGecko_Utilities:: + NativeGetProductionRevision___STATIC__U1(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + // read PROD_REV from 31:24 bits + stack.SetResult_U1(DEVINFO->PART >> 24); + + NANOCLR_NOCLEANUP_NOLABEL(); +} + +HRESULT Library_nf_hardware_giantgecko_nanoFramework_Hardware_GiantGecko_Utilities::NativeGetDeviceFamily___STATIC__U1( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + // read DEVICE_FAMILY from 23:16 bits + stack.SetResult_U1(DEVINFO->PART >> 16); + + NANOCLR_NOCLEANUP_NOLABEL(); +} + +HRESULT Library_nf_hardware_giantgecko_nanoFramework_Hardware_GiantGecko_Utilities::NativeGetDeviceNumber___STATIC__U1( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + // read DEVICE_NUMBER from 15:0 bits + stack.SetResult_U4((uint16_t)DEVINFO->PART); + + NANOCLR_NOCLEANUP_NOLABEL(); +} diff --git a/targets/AzureRTOS/SiliconLabs/_nanoCLR/targetHAL.cpp b/targets/AzureRTOS/SiliconLabs/_nanoCLR/targetHAL.cpp new file mode 100644 index 0000000000..701868f4b9 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_nanoCLR/targetHAL.cpp @@ -0,0 +1,345 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +// #if (HAL_USE_CAN == TRUE) +// #include +// #endif +#include +#include +// #if (HAL_USE_UART == TRUE) +// #include +// #endif + +#if (HAL_USE_PWM == TRUE) +extern void DeInitPwm(); +#endif + +#if (GECKO_USE_ADC0 == TRUE) || (GECKO_USE_ADC1 == TRUE) +#include +#include +#endif + +#if GECKO_FEATURE_USBD_WINUSB == TRUE +#include +#endif + +// +// Reboot handlers clean up on reboot +// +static ON_SOFT_REBOOT_HANDLER s_rebootHandlers[16] = + {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; + +void HAL_AddSoftRebootHandler(ON_SOFT_REBOOT_HANDLER handler) +{ + for (size_t i = 0; i < ARRAYSIZE(s_rebootHandlers); i++) + { + if (s_rebootHandlers[i] == NULL) + { + s_rebootHandlers[i] = handler; + return; + } + else if (s_rebootHandlers[i] == handler) + { + return; + } + } +} + +// because nanoHAL_Initialize/Uninitialize needs to be called in both C and C++ we need a proxy to allow it to be called +// in 'C' +extern "C" +{ + + void nanoHAL_Initialize_C() + { + nanoHAL_Initialize(); + } + + void nanoHAL_Uninitialize_C(bool isPoweringDown) + { + nanoHAL_Uninitialize(isPoweringDown); + } +} + +void nanoHAL_Initialize() +{ + HAL_CONTINUATION::InitializeList(); + HAL_COMPLETION ::InitializeList(); + + BlockStorageList_Initialize(); + + // initialize block storage devices + BlockStorage_AddDevices(); + + BlockStorageList_InitializeDevices(); + + // clear managed heap region + unsigned char *heapStart = NULL; + unsigned int heapSize = 0; + + ::HeapLocation(heapStart, heapSize); + memset(heapStart, 0, heapSize); + +#if (NANOCLR_GRAPHICS == TRUE) + g_GraphicsMemoryHeap.Initialize(); +#endif + + ConfigurationManager_Initialize(); + + Events_Initialize(); + + CPU_GPIO_Initialize(); + + // #if (HAL_USE_CAN == TRUE) + + // #if defined(STM32_CAN_USE_CAN1) && (STM32_CAN_USE_CAN1 == TRUE) + // Can1_PAL.Driver = NULL; + // #endif + // #if (STM32_CAN_USE_CAN2) && (STM32_CAN_USE_CAN2 == TRUE) + // Can2_PAL.Driver = NULL; + // #endif + // #if (STM32_CAN_USE_CAN3) && (STM32_CAN_USE_CAN3 == TRUE) + // Can3_PAL.Driver = NULL; + // #endif + + // #endif + +#if defined(I2C0) && (GECKO_USE_I2C0 == TRUE) + memset(&I2C0_PAL, 0, sizeof(NF_PAL_I2C)); +#endif +#if defined(I2C1) && (GECKO_USE_I2C1 == TRUE) + memset(&I2C1_PAL, 0, sizeof(NF_PAL_I2C)); +#endif +#if defined(I2C2) && (GECKO_USE_I2C2 == TRUE) + memset(&I2C2_PAL, 0, sizeof(NF_PAL_I2C)); +#endif + +#if (HAL_USE_SPI == TRUE) + nanoSPI_Initialize(); + +#if (GECKO_USE_SPI0 == TRUE) + memset(&SPI0_PAL, 0, sizeof(NF_PAL_SPI)); +#endif +#if (GECKO_USE_SPI1 == TRUE) + memset(&SPI1_PAL, 0, sizeof(NF_PAL_SPI)); +#endif +#if (GECKO_USE_SPI2 == TRUE) + memset(&SPI2_PAL, 0, sizeof(NF_PAL_SPI)); +#endif +#if (GECKO_USE_SPI3 == TRUE) + memset(&SPI3_PAL, 0, sizeof(NF_PAL_SPI)); +#endif +#if (GECKO_USE_SPI4 == TRUE) + memset(&SPI4_PAL, 0, sizeof(NF_PAL_SPI)); +#endif +#if (GECKO_USE_SPI5 == TRUE) + memset(&SPI5_PAL, 0, sizeof(NF_PAL_SPI)); +#endif + +#endif + +#if (GECKO_USE_ADC0 == TRUE) && defined(NANO_GG_ADC_NATIVE_TARGET_H) + adc0Initialized = false; +#endif +#if (GECKO_USE_ADC1 == TRUE) && defined(NANO_GG_ADC_NATIVE_TARGET_H) + adc1Initialized = false; +#endif + +#if GECKO_FEATURE_USBD_WINUSB == TRUE + memset(&UsbStream_PAL, 0, sizeof(UsbStream_PAL)); +#endif + +#if defined(GECKO_USE_USART0) && (GECKO_USE_USART0 == TRUE) + Usart0_PAL = {0}; +#endif +#if defined(GECKO_USE_USART1) && (GECKO_USE_USART1 == TRUE) + Usart1_PAL = {0}; +#endif +#if defined(GECKO_USE_USART2) && (GECKO_USE_USART2 == TRUE) + Usart2_PAL = {0}; +#endif +#if defined(GECKO_USE_USART3) && (GECKO_USE_USART3 == TRUE) + Usart3_PAL = {0}; +#endif +#if defined(GECKO_USE_USART_UART4) && (GECKO_USE_USART_UART4 == TRUE) + Usart4_PAL = {0}; +#endif +#if defined(GECKO_USE_USART_UART5) && (GECKO_USE_USART_UART5 == TRUE) + Usart5_PAL = {0}; +#endif + +#if (NANOCLR_GRAPHICS == TRUE) + DisplayInterfaceConfig config; // not used for DSI display + g_DisplayInterface.Initialize(config); + g_DisplayDriver.Initialize(); + + // g_TouchInterface.Initialize(); + // g_TouchDevice.Initialize(); + + // PalEvent_Initialize(); + // Gesture_Initialize(); + // Ink_Initialize(); +#endif + + // init DMA driver (don't bother check return value as if it's already started it won't fail)v + DMADRV_Init(); + + // Initialise Network Stack + Network_Initialize(); +} + +void nanoHAL_Uninitialize(bool isPoweringDown) +{ + (void)isPoweringDown; + + // process Reboot Handlers + for (size_t i = 0; i < ARRAYSIZE(s_rebootHandlers); i++) + { + if (s_rebootHandlers[i] != NULL) + { + s_rebootHandlers[i](); + } + else + { + break; + } + } + + DMADRV_DeInit(); + + // TODO + SOCKETS_CloseConnections(); + +#if !defined(HAL_REDUCESIZE) + // TODO need to call this but it's preventing the debug session from starting + Network_Uninitialize(); +#endif + + BlockStorageList_UnInitializeDevices(); + + // need to be sure that: + // - all mutexes for drivers that use them are released + // - all drivers are stopped + + // #if (HAL_USE_CAN == TRUE) + + // #if defined(STM32_CAN_USE_CAN1) && (STM32_CAN_USE_CAN1 == TRUE) + // canStop(&CAND1); + // #endif + // #if (STM32_CAN_USE_CAN2) && (STM32_CAN_USE_CAN2 == TRUE) + // canStop(&CAND2); + // #endif + // #if (STM32_CAN_USE_CAN3) && (STM32_CAN_USE_CAN3 == TRUE) + // canStop(&CAND3); + // #endif + + // #endif + +#if defined(I2C0) && (GECKO_USE_I2C0 == TRUE) + if (I2C0_PAL.Configuration != NULL) + { + platform_free(I2C0_PAL.Configuration); + I2C0_PAL.Configuration = NULL; + } + I2C_Reset(I2C0); +#endif +#if defined(I2C1) && (GECKO_USE_I2C1 == TRUE) + if (I2C1_PAL.Configuration != NULL) + { + platform_free(I2C1_PAL.Configuration); + I2C1_PAL.Configuration = NULL; + } + I2C_Reset(I2C1); +#endif +#if defined(I2C2) && (GECKO_USE_I2C2 == TRUE) + if (I2C2_PAL.Configuration != NULL) + { + platform_free(I2C2_PAL.Configuration); + I2C2_PAL.Configuration = NULL; + } + I2C_Reset(I2C2); +#endif + +#if (HAL_USE_SPI == TRUE) + nanoSPI_Uninitialize(); +#endif + +#if (GECKO_USE_ADC0 == TRUE) && defined(NANO_GG_ADC_NATIVE_TARGET_H) + ADC_Reset(ADC0); + adc0Initialized = false; +#endif +#if (GECKO_USE_ADC1 == TRUE) && defined(NANO_GG_ADC_NATIVE_TARGET_H) + ADC_Reset(ADC1); + adc1Initialized = false; +#endif + +#if GECKO_FEATURE_USBD_WINUSB == TRUE + + // abort any transfer in progress, just in case + sl_usbd_vendor_abort_write_bulk(sl_usbd_vendor_winusb_number); + sl_usbd_vendor_abort_read_bulk(sl_usbd_vendor_winusb_number); + +#endif + +#if defined(GECKO_USE_USART0) && (GECKO_USE_USART0 == TRUE) + if (Usart0_PAL.Usart != NULL) + { + UnInit_UART0(); + } +#endif +#if defined(GECKO_USE_USART1) && (GECKO_USE_USART1 == TRUE) + if (Usart1_PAL.Usart != NULL) + { + UnInit_UART1(); + } +#endif +#if defined(GECKO_USE_USART2) && (GECKO_USE_USART2 == TRUE) + if (Usart2_PAL.Usart != NULL) + { + UnInit_UART2(); + } +#endif +#if defined(GECKO_USE_USART3) && (GECKO_USE_USART3 == TRUE) + if (Usart3_PAL.Usart != NULL) + { + UnInit_UART3(); + } +#endif +#if defined(GECKO_USE_USART_UART4) && (GECKO_USE_USART_UART4 == TRUE) + if (Usart4_PAL.Usart != NULL) + { + UnInit_UART4(); + } +#endif +#if defined(GECKO_USE_USART_UART5) && (GECKO_USE_USART_UART5 == TRUE) + if (Usart5_PAL.Usart != NULL) + { + UnInit_UART5(); + } +#endif + +#if (HAL_USE_PWM == TRUE) + DeInitPwm(); +#endif + + CPU_GPIO_Uninitialize(); + + Events_Uninitialize(); + + HAL_CONTINUATION::Uninitialize(); + HAL_COMPLETION ::Uninitialize(); +} diff --git a/targets/AzureRTOS/SiliconLabs/_nanoCLR/targetHAL_Power.c b/targets/AzureRTOS/SiliconLabs/_nanoCLR/targetHAL_Power.c new file mode 100644 index 0000000000..936a301cdf --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_nanoCLR/targetHAL_Power.c @@ -0,0 +1,133 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include +#include +#include +#include +#include +#include + +#ifdef HAL_RTC_MODULE_ENABLED +extern RTC_HandleTypeDef RtcHandle; +#endif + +// uint32_t WakeupReasonStore; + +inline void CPU_Reset() +{ + NVIC_SystemReset(); +}; + +inline bool CPU_IsSoftRebootSupported() +{ + return true; +}; + +// CPU sleep is not currently implemented in this target +inline void CPU_Sleep(SLEEP_LEVEL_type level, uint64_t wakeEvents) +{ + (void)level; + (void)wakeEvents; +}; + +void CPU_SetPowerMode(PowerLevel_type powerLevel) +{ + // default to false + // bool success = false; + + switch (powerLevel) + { + case PowerLevel__Off: + // stop watchdog + WDOGn_Enable(DEFAULT_WDOG, false); + + // gracefully shutdown everything + nanoHAL_Uninitialize_C(true); + + __disable_irq(); + + // ///////////////////////////////////////////////////////////////////////// + // // stop the idependent watchdog, for series where the option is available + // #if defined(STM32L4XX) + + // (void)success; + // // TODO FIXME this code needs to follow the same workflow as the STM32F7 + // CLEAR_BIT(FLASH->OPTR, FLASH_OPTR_IWDG_STDBY); + // #elif defined(STM32F7XX) + + // // only need to change this option bit if not already done + // if ((FLASH->OPTCR & FLASH_OPTCR_IWDG_STDBY)) + // { + // // developer notes: + // // follow workflow recommended @ 3.4.2 Option bytes programming (from programming manual) + // // Authorizes the Option Byte register programming + // FLASH->OPTKEYR = FLASH_OPT_KEY1; + // FLASH->OPTKEYR = FLASH_OPT_KEY2; + + // // wait 500ms for any flash operation to be completed + // success = FLASH_WaitForLastOperation(500); + + // if (success) + // { + // // write option value (clear the FLASH_OPTCR_IWDG_STDBY) + // CLEAR_BIT(FLASH->OPTCR, FLASH_OPTCR_IWDG_STDBY); + + // // set the option start bit + // FLASH->OPTCR |= FLASH_OPTCR_OPTSTRT; + + // // Data synchronous Barrier, forcing the CPU to respect the sequence of instruction + // without + // // optimization + // __DSB(); + + // // wait 100ms for the flash operation to be completed + // success = FLASH_WaitForLastOperation(100); + // } + + // // Set the OPTLOCK Bit to lock the FLASH Option Byte Registers access + // FLASH->OPTCR |= FLASH_OPTCR_OPTLOCK; + // } + + // (void)success; + + // #endif + + // ///////////////////////////////////////////////////// + // // set alarm interrupt enable + // // set power control register to: power down deep sleep + // ///////////////////////////////////////////////////// + + // // TODO + // //__HAL_RTC_ALARMA_ENABLE(&RtcHandle); + // //__HAL_RTC_ALARM_ENABLE_IT(&RtcHandle, RTC_IT_ALRA); + + // // TODO + // // need review here to use ST HAL HAL_PWREx_EnterSTOP2Mode + + // #if defined(STM32F7XX) + + // ////////////////////////////////////////////////////////////////////////////////////////////////////// + // // workaround recommended in section 2.2.2 at STM32F77xxx errata document (DM00257543 - + // ES0334 Rev 5) // PWR->CSR1 |= PWR_CSR1_EIWUP; + // ////////////////////////////////////////////////////////////////////////////////////////////////////// + + // SET_BIT(PWR->CR1, PWR_CR1_PDDS); + + // #endif + + // set SLEEPDEEP bit of Cortex SCR + SCB->SCR &= SCB_SCR_SLEEPDEEP_Msk; + + // wait for interrupt, and the execution dies here + __WFI(); + + break; + + default: + // all the other power modes are unsupported here + break; + } +} diff --git a/targets/AzureRTOS/SiliconLabs/_nanoCLR/targetHAL_Time.cpp b/targets/AzureRTOS/SiliconLabs/_nanoCLR/targetHAL_Time.cpp new file mode 100644 index 0000000000..2ac221bf24 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_nanoCLR/targetHAL_Time.cpp @@ -0,0 +1,190 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include +#include +#include +#include +#include + +#include + +// Returns the current date time from the RTC +uint64_t HAL_Time_CurrentDateTime(bool datePartOnly) +{ + (void)datePartOnly; + + return 0; +// #if (HAL_USE_RTC == TRUE) + +// // use RTC to get date time +// SYSTEMTIME st; +// RTCDateTime _dateTime; + +// rtcGetTime(&RTCD1, &_dateTime); + +// st.wDay = (unsigned short)_dateTime.day; +// st.wMonth = (unsigned short)_dateTime.month; +// st.wYear = (unsigned short)(_dateTime.year + 1980); // ChibiOS is counting years since 1980 +// st.wDayOfWeek = (unsigned short)_dateTime.dayofweek; + +// // zero 'time' fields if date part only is required +// if (datePartOnly) +// { +// st.wMilliseconds = 0; +// st.wSecond = 0; +// st.wMinute = 0; +// st.wHour = 0; +// } +// else +// { +// // full date&time required, fill in 'time' fields too + +// st.wMilliseconds = (unsigned short)(_dateTime.millisecond % 1000); +// _dateTime.millisecond /= 1000; +// st.wSecond = (unsigned short)(_dateTime.millisecond % 60); +// _dateTime.millisecond /= 60; +// st.wMinute = (unsigned short)(_dateTime.millisecond % 60); +// _dateTime.millisecond /= 60; +// st.wHour = (unsigned short)(_dateTime.millisecond % 24); +// } + +// return HAL_Time_ConvertFromSystemTime(&st); + +// #else + +// if (datePartOnly) +// { +// SYSTEMTIME st; +// HAL_Time_ToSystemTime(HAL_Time_CurrentTime(), &st); + +// st.wHour = 0; +// st.wMinute = 0; +// st.wSecond = 0; +// st.wMilliseconds = 0; + +// return HAL_Time_ConvertFromSystemTime(&st); +// } +// else +// { +// return HAL_Time_CurrentTime(); +// } + +// #endif +}; + +void HAL_Time_SetUtcTime(uint64_t utcTime) +{ + (void)utcTime; + +// SYSTEMTIME systemTime; + +// HAL_Time_ToSystemTime(utcTime, &systemTime); + +// #if (HAL_USE_RTC == TRUE) + +// // set RTC +// RTCDateTime newTime; + +// newTime.year = systemTime.wYear - 1980; // ChibiOS time base is 1980-01-01 +// newTime.month = systemTime.wMonth; +// newTime.day = systemTime.wDay; +// newTime.dayofweek = systemTime.wDayOfWeek; +// newTime.millisecond = +// ((((uint32_t)systemTime.wHour * 3600) + ((uint32_t)systemTime.wMinute * 60) + (uint32_t)systemTime.wSecond) * +// 1000); + +// // set RTC time +// rtcSetTime(&RTCD1, &newTime); + +// #else + +// // TODO FIXME +// // need to add implementation when RTC is not being used +// // can't mess with the systicks because the scheduling can fail + +// #endif +} + +bool HAL_Time_TimeSpanToStringEx(const int64_t &ticks, char *&buf, size_t &len) +{ + uint64_t ticksAbs; + uint64_t rest; + + if (ticks < 0) + { + ticksAbs = -ticks; + + CLR_SafeSprintf(buf, len, "-"); + } + else + { + ticksAbs = ticks; + } + + rest = ticksAbs % (1000 * TIME_CONVERSION__TICKUNITS); + ticksAbs = ticksAbs / (1000 * TIME_CONVERSION__TICKUNITS); // Convert to seconds. + + if (ticksAbs > TIME_CONVERSION__ONEDAY) // More than one day. + { + CLR_SafeSprintf(buf, len, "%d.", (int32_t)(ticksAbs / TIME_CONVERSION__ONEDAY)); + ticksAbs %= TIME_CONVERSION__ONEDAY; + } + + CLR_SafeSprintf(buf, len, "%02d:", (int32_t)(ticksAbs / TIME_CONVERSION__ONEHOUR)); + ticksAbs %= TIME_CONVERSION__ONEHOUR; + CLR_SafeSprintf(buf, len, "%02d:", (int32_t)(ticksAbs / TIME_CONVERSION__ONEMINUTE)); + ticksAbs %= TIME_CONVERSION__ONEMINUTE; + CLR_SafeSprintf(buf, len, "%02d", (int32_t)(ticksAbs / TIME_CONVERSION__ONESECOND)); + ticksAbs %= TIME_CONVERSION__ONESECOND; + + ticksAbs = (uint32_t)rest; + if (ticksAbs) + { + CLR_SafeSprintf(buf, len, ".%07d", (uint32_t)ticksAbs); + } + + return len != 0; +} + +bool DateTimeToString(const int64_t &time, char *&buf, size_t &len) +{ + SYSTEMTIME st; + + HAL_Time_ToSystemTime(time, &st); + + return CLR_SafeSprintf( + buf, + len, + "%4d/%02d/%02d %02d:%02d:%02d.%03d", + st.wYear, + st.wMonth, + st.wDay, + st.wHour, + st.wMinute, + st.wSecond, + st.wMilliseconds); +} + +char *DateTimeToString(const int64_t &time) +{ + static char rgBuffer[128]; + char *szBuffer = rgBuffer; + size_t iBuffer = ARRAYSIZE(rgBuffer); + + DateTimeToString(time, szBuffer, iBuffer); + + return rgBuffer; +} + +const char *HAL_Time_CurrentDateTimeToString() +{ + return DateTimeToString(HAL_Time_CurrentDateTime(false)); +} + +uint64_t CPU_MillisecondsToTicks(uint64_t ticks) +{ + return ((ticks * (uint64_t)TX_TIMER_TICKS_PER_SECOND) / 1000); +} diff --git a/targets/AzureRTOS/SiliconLabs/_nanoCLR/targetHAL_Watchdog.c b/targets/AzureRTOS/SiliconLabs/_nanoCLR/targetHAL_Watchdog.c new file mode 100644 index 0000000000..9e452dfeb8 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_nanoCLR/targetHAL_Watchdog.c @@ -0,0 +1,28 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include + +#include + +// Method to initialize the watchdog. +void Watchdog_Init() +{ + // Watchdog Initialize settings + // 8193 clock cycles of a 1kHz clock ~8 seconds period + WDOG_Init_TypeDef wdogInit = WDOG_INIT_DEFAULT; + wdogInit.clkSel = wdogClkSelULFRCO; + wdogInit.perSel = wdogPeriod_8k; + + // Initializing watchdog with chosen settings + WDOGn_Init(DEFAULT_WDOG, &wdogInit); +} + +// Reset the watchdog. If not done within the timout period, +// the watchdog will trigger and MCU will reset +void Watchdog_Reset() +{ + WDOGn_Feed(DEFAULT_WDOG); +} diff --git a/targets/AzureRTOS/SiliconLabs/_nanoCLR/targetPAL.c b/targets/AzureRTOS/SiliconLabs/_nanoCLR/targetPAL.c new file mode 100644 index 0000000000..9043c3db0f --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_nanoCLR/targetPAL.c @@ -0,0 +1,10 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include +#include + +// required for Azure RTOS TX_INTERRUPT_SAVE_AREA implementation at platform level +unsigned int interrupt_save; diff --git a/targets/AzureRTOS/SiliconLabs/_nanoCLR/target_platform.h.in b/targets/AzureRTOS/SiliconLabs/_nanoCLR/target_platform.h.in new file mode 100644 index 0000000000..cb67b7f7f3 --- /dev/null +++ b/targets/AzureRTOS/SiliconLabs/_nanoCLR/target_platform.h.in @@ -0,0 +1,40 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +////////////////////////////////////////////////////////////////////////////// +// This file was automatically generated by a tool. // +// Any changes you make here will be overwritten when it's generated again. // +////////////////////////////////////////////////////////////////////////////// + +#ifndef TARGET_PLATFORM_H +#define TARGET_PLATFORM_H + +#include + +#define NANOCLR_GRAPHICS @NANOCLR_GRAPHICS@ +#define NF_FEATURE_USE_SPIFFS @NF_FEATURE_USE_SPIFFS_OPTION@ +#define HAL_USE_RTC @HAL_USE_RTC_OPTION@ + +// takes care of enabling the HAL subsystems required for API options +#define HAL_USE_SPI @HAL_USE_SPI_OPTION@ +#define HAL_USE_I2C @HAL_USE_I2C_OPTION@ +#define HAL_USE_PWM @HAL_USE_PWM_OPTION@ +#define HAL_USE_ADC @HAL_USE_ADC_OPTION@ +#define HAL_USE_DAC @HAL_USE_DAC_OPTION@ +#define HAL_USE_UART @HAL_USE_UART_OPTION@ +// #define HAL_USE_SDC @HAL_USE_SDC_OPTION@ +#define HAL_USE_WDG @HAL_USE_WDG_OPTION@ +// #define HAL_USE_CAN @HAL_USE_CAN_OPTION@ +// #define HAL_NF_USE_STM32_CRC TRUE +#define HAL_USE_ONEWIRE @HAL_USE_ONEWIRE_OPTION@ +// #define HAL_USBH_USE_MSD @HAL_USBH_USE_MSD_OPTION@ +// #define USBX_FEATURE_CDC @USBX_FEATURE_CDC_OPTION@ +#define USBX_FEATURE_HID @USBX_FEATURE_HID_OPTION@ +#define GECKO_FEATURE_USBD_HID @GECKO_FEATURE_USBD_HID_OPTION@ +#define GECKO_FEATURE_USBD_WINUSB @GECKO_FEATURE_USBD_WINUSB_OPTION@ +#define HAL_WP_USE_SERIAL @HAL_WP_USE_SERIAL_OPTION@ +#define HAL_WP_USE_USB_CDC @HAL_WP_USE_USB_CDC_OPTION@ + +#endif // TARGET_PLATFORM_H diff --git a/targets/AzureRTOS/_common/CMakeLists.txt b/targets/AzureRTOS/_common/CMakeLists.txt index b344007613..3469a59de8 100644 --- a/targets/AzureRTOS/_common/CMakeLists.txt +++ b/targets/AzureRTOS/_common/CMakeLists.txt @@ -21,6 +21,7 @@ list(APPEND TARGET_AZURERTOS_COMMON_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/WireProt # append nanoHAL list(APPEND TARGET_AZURERTOS_COMMON_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/targetHAL.c) list(APPEND TARGET_AZURERTOS_COMMON_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/targetHAL_Time.cpp) +list(APPEND TARGET_AZURERTOS_COMMON_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/targetHAL_Rtos.c) # append low level initialization list(APPEND TARGET_AZURERTOS_COMMON_SOURCES ${TARGET_BASE_LOCATION}/common/tx_initialize_low_level.S) diff --git a/targets/AzureRTOS/_common/WireProtocol_ReceiverThread.c b/targets/AzureRTOS/_common/WireProtocol_ReceiverThread.c index 5d589c81dd..1b97f9dd58 100644 --- a/targets/AzureRTOS/_common/WireProtocol_ReceiverThread.c +++ b/targets/AzureRTOS/_common/WireProtocol_ReceiverThread.c @@ -6,7 +6,8 @@ #include #include -__attribute__((noreturn)) void ReceiverThread_entry(uint32_t parameter) +// defined as weak so it can be replaced with platform specific one +__nfweak __attribute__((noreturn)) void ReceiverThread_entry(uint32_t parameter) { (void)parameter; @@ -20,7 +21,7 @@ __attribute__((noreturn)) void ReceiverThread_entry(uint32_t parameter) WP_Message_Process(); // pass control to the OS - tx_thread_sleep(TX_TICKS_PER_MILLISEC(1)); + tx_thread_sleep(TX_TICKS_PER_MILLISEC(10)); } // this function never returns diff --git a/targets/AzureRTOS/_common/include/LaunchCLR.h b/targets/AzureRTOS/_common/include/LaunchCLR.h index a82dcb6f91..1c90bf5ae6 100644 --- a/targets/AzureRTOS/_common/include/LaunchCLR.h +++ b/targets/AzureRTOS/_common/include/LaunchCLR.h @@ -6,6 +6,8 @@ #ifndef LAUNCHCLR_H #define LAUNCHCLR_H +#include + void LaunchCLR(uint32_t address); bool CheckValidCLRImage(uint32_t address); diff --git a/targets/AzureRTOS/_common/include/platform_target_capabilities.h b/targets/AzureRTOS/_common/include/platform_target_capabilities.h index 49e7d72a00..b56c182d4a 100644 --- a/targets/AzureRTOS/_common/include/platform_target_capabilities.h +++ b/targets/AzureRTOS/_common/include/platform_target_capabilities.h @@ -26,6 +26,9 @@ extern "C" // using Debugging_Execution_QueryCLRCapabilities::c_CapabilityFlags_TargetCapability_1 TargetCapabilities_DfuUpdate = 0x20000000, + // J-Link update capable + TargetCapabilities_JlinkUpdate = 0x30000000, + } TargetCapabilities; #ifdef __cplusplus diff --git a/targets/AzureRTOS/_common/nanoCLR/nanoCRT.cpp b/targets/AzureRTOS/_common/nanoCLR/nanoCRT.cpp index a6ea8201b9..58e758e9a9 100644 --- a/targets/AzureRTOS/_common/nanoCLR/nanoCRT.cpp +++ b/targets/AzureRTOS/_common/nanoCLR/nanoCRT.cpp @@ -127,10 +127,6 @@ extern "C" va_end(arg_ptr); } -#else - __inline void debug_printf(const char *format, ...) - { - } #endif // !defined(BUILD_RTM) } diff --git a/targets/AzureRTOS/_common/nanoCLR/targetPAL_Events.cpp b/targets/AzureRTOS/_common/nanoCLR/targetPAL_Events.cpp index 6188ea35f7..551806fe7b 100644 --- a/targets/AzureRTOS/_common/nanoCLR/targetPAL_Events.cpp +++ b/targets/AzureRTOS/_common/nanoCLR/targetPAL_Events.cpp @@ -51,7 +51,7 @@ void Events_SetBoolTimer(bool *timerCompleteFlag, uint32_t millisecondsFromNow) // need to stop the timer first tx_timer_deactivate(&boolEventsTimer); - tx_timer_change(&boolEventsTimer, 0, TX_TICKS_PER_MILLISEC(millisecondsFromNow)); + tx_timer_change(&boolEventsTimer, TX_TICKS_PER_MILLISEC(millisecondsFromNow), 0); tx_timer_activate(&boolEventsTimer); } } @@ -100,7 +100,7 @@ uint32_t Events_WaitForEvents(uint32_t powerLevel, uint32_t wakeupSystemEvents, } // no events, pass control to the OS - tx_thread_sleep(TX_TICKS_PER_MILLISEC(100)); + tx_thread_sleep(TX_TICKS_PER_MILLISEC(1)); // check if reboot or exit flags were set when the other OS threads executed if (CLR_EE_DBG_IS(RebootPending) || CLR_EE_DBG_IS(ExitPending)) diff --git a/targets/AzureRTOS/_common/platform_heap.c b/targets/AzureRTOS/_common/platform_heap.c index 24832093ce..2037a99818 100644 --- a/targets/AzureRTOS/_common/platform_heap.c +++ b/targets/AzureRTOS/_common/platform_heap.c @@ -13,21 +13,23 @@ void *platform_malloc(size_t size) { uint8_t *pointer = TX_NULL; +#ifdef BUILD_RTM + tx_byte_allocate(&byte_pool_0, (VOID **)&pointer, size, TX_NO_WAIT); +#else uint32_t allocStatus = tx_byte_allocate(&byte_pool_0, (VOID **)&pointer, size, TX_NO_WAIT); ASSERT(allocStatus == TX_SUCCESS); +#endif return pointer; } void platform_free(void *ptr) { + +#ifdef BUILD_RTM + tx_byte_release(ptr); +#else uint32_t freeStatus = tx_byte_release(ptr); ASSERT(freeStatus == TX_SUCCESS); -} - -void *platform_realloc(void *ptr, size_t size) -{ - (void)size; - - return ptr; +#endif } diff --git a/targets/AzureRTOS/_common/targetHAL_Rtos.c b/targets/AzureRTOS/_common/targetHAL_Rtos.c new file mode 100644 index 0000000000..b27f42613a --- /dev/null +++ b/targets/AzureRTOS/_common/targetHAL_Rtos.c @@ -0,0 +1,13 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include +#include + +void RtosYield() +{ + // OK to call relinquish here despite it will only execute threads with same or higher priority + tx_thread_relinquish(); +} diff --git a/targets/AzureRTOS/_common/targetHAL_Time.cpp b/targets/AzureRTOS/_common/targetHAL_Time.cpp index 15ba707ae1..5699cf2748 100644 --- a/targets/AzureRTOS/_common/targetHAL_Time.cpp +++ b/targets/AzureRTOS/_common/targetHAL_Time.cpp @@ -5,21 +5,6 @@ #include -// Converts CMSIS sysTicks to .NET ticks (100 nanoseconds) -uint64_t HAL_Time_SysTicksToTime(uint64_t sysTicks) -{ - // need to convert Azure RTOS ticks to 100 nanoseconds - return (((int64_t)sysTicks * (int64_t)1000000 + (int64_t)TX_TIMER_TICKS_PER_SECOND - 1) / - (int64_t)TX_TIMER_TICKS_PER_SECOND) * - 10; -} - -// because HAL_Time_SysTicksToTime needs to be called from C we need a proxy to allow it to be called from 'C' code -extern "C" -{ - - uint64_t HAL_Time_SysTicksToTime_C(uint64_t sysTicks) - { - return HAL_Time_SysTicksToTime(sysTicks); - } -} +/////////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS BLANK ON PURPOSE HAS THERE IS NO GENERIC IMPLEMENTATION REQUIRED // +/////////////////////////////////////////////////////////////////////////////////// diff --git a/targets/ChibiOS/CMakeLists.txt b/targets/ChibiOS/CMakeLists.txt index ba15cbaaed..22b4a5d815 100644 --- a/targets/ChibiOS/CMakeLists.txt +++ b/targets/ChibiOS/CMakeLists.txt @@ -85,7 +85,7 @@ if(NO_CHIBIOS_SOURCE_FOLDER) FetchContent_Declare( chibios - SVN_REPOSITORY https://svn.osdn.net/svnroot/chibios/branches/${RTOS_VERSION} + SVN_REPOSITORY http://svn.code.sf.net/p/chibios/code/branches/${RTOS_VERSION} SVN_REVISION -rHEAD ) @@ -209,7 +209,7 @@ if(NF_FEATURE_HAS_SDCARD OR NF_FEATURE_HAS_USB_MSD) endif() -# if mbed TLS is enabled add it to the build +# if Mbed TLS is enabled add it to the build if(USE_SECURITY_MBEDTLS_OPTION) # check if MBEDTLS_SOURCE was specified or if it's empty (default is empty) @@ -223,14 +223,14 @@ if(USE_SECURITY_MBEDTLS_OPTION) # set tag for currently supported version # WHEN CHANGING THIS MAKE SURE TO UPDATE THE DEV CONTAINERS - set(MBEDTLS_GIT_TAG "mbedtls-2.28.1") + set(MBEDTLS_GIT_TAG "mbedtls-2.28.2") - # set options for mbed TLS - option(ENABLE_TESTING "no testing when building mbed TLS." OFF) + # set options for Mbed TLS + option(ENABLE_TESTING "no testing when building Mbed TLS." OFF) if(NO_MBEDTLS_SOURCE) - # no mbed TLS source specified, download it from it's repo - message(STATUS "mbedTLS ${MBEDTLS_GIT_TAG} from GitHub repo") + # no Mbed TLS source specified, download it from it's repo + message(STATUS "MbedTLS ${MBEDTLS_GIT_TAG} from GitHub repo") FetchContent_Declare( mbedtls @@ -239,9 +239,9 @@ if(USE_SECURITY_MBEDTLS_OPTION) ) else() - # mbedTLS source was specified + # MbedTLS source was specified - message(STATUS "mbedTLS ${MBEDTLS_GIT_TAG} (source from: ${MBEDTLS_SOURCE})") + message(STATUS "MbedTLS ${MBEDTLS_GIT_TAG} (source from: ${MBEDTLS_SOURCE})") FetchContent_Declare( mbedtls diff --git a/targets/ChibiOS/CMakePresets.json b/targets/ChibiOS/CMakePresets.json new file mode 100644 index 0000000000..a604509f8a --- /dev/null +++ b/targets/ChibiOS/CMakePresets.json @@ -0,0 +1,9 @@ +{ + "version": 4, + "include": [ + "ORGPAL_PALTHREE/CMakePresets.json", + "ST_NUCLEO64_F091RC/CMakePresets.json", + "ST_STM32F429I_DISCOVERY/CMakePresets.json", + "ST_STM32F769I_DISCOVERY/CMakePresets.json" + ] +} diff --git a/targets/ChibiOS/ORGPAL_PALTHREE/CMakePresets.json b/targets/ChibiOS/ORGPAL_PALTHREE/CMakePresets.json new file mode 100644 index 0000000000..bce72fa557 --- /dev/null +++ b/targets/ChibiOS/ORGPAL_PALTHREE/CMakePresets.json @@ -0,0 +1,55 @@ +{ + "version": 4, + "include": [ + "../../../CMake/arm-gcc.json", + "../../../config/user-tools-repos.json", + "../../../config/user-prefs.json" + ], + "configurePresets": [ + { + "name": "ORGPAL_PALTHREE", + "inherits": [ + "arm-gcc-cortex-preset", + "user-tools-repos", + "user-prefs" + ], + "hidden": false, + "cacheVariables": { + "TARGET_BOARD": "ORGPAL_PALTHREE", + "TARGET_SERIES": "STM32F7xx", + "RTOS": "ChibiOS", + "CHIBIOS_CONTRIB_REQUIRED": "ON", + "STM32_CUBE_PACKAGE_REQUIRED": "ON", + "SUPPORT_ANY_BASE_CONVERSION": "ON", + "NF_FEATURE_DEBUGGER": "ON", + "NF_FEATURE_RTC": "ON", + "NF_FEATURE_HAS_SDCARD": "ON", + "NF_FEATURE_HAS_CONFIG_BLOCK": "ON", + "NF_FEATURE_HAS_USB_MSD": "ON", + "NF_FEATURE_USE_SPIFFS": "ON", + "NF_BUILD_RTM": "OFF", + "API_System.Math": "ON", + "API_Hardware.Stm32": "ON", + "API_System.Device.Gpio": "ON", + "API_System.Device.Spi": "ON", + "API_System.Device.I2c": "ON", + "API_System.Device.Pwm": "ON", + "API_System.IO.Ports": "ON", + "API_System.Device.Adc": "ON", + "API_System.Device.Dac": "ON", + "API_System.Net": "ON", + "API_nanoFramework.ResourceManager": "ON", + "API_nanoFramework.System.Collections": "ON", + "API_nanoFramework.System.Text": "ON" + } + } + ], + "buildPresets": [ + { + "inherits": "base-user", + "name": "ORGPAL_PALTHREE", + "displayName": "ORGPAL_PALTHREE", + "configurePreset": "ORGPAL_PALTHREE" + } + ] +} diff --git a/targets/ChibiOS/ORGPAL_PALTHREE/mbedtls_config.h b/targets/ChibiOS/ORGPAL_PALTHREE/mbedtls_config.h index 8e6da134b1..c4eefe58db 100644 --- a/targets/ChibiOS/ORGPAL_PALTHREE/mbedtls_config.h +++ b/targets/ChibiOS/ORGPAL_PALTHREE/mbedtls_config.h @@ -38,7 +38,7 @@ // uncomment the defines bellow to generate debug output // set below the threshold level for debug messages -// check mbed TLS mbedtls/debug.h header for details. +// check Mbed TLS mbedtls/debug.h header for details. // Debug levels: // 0 No debug // 1 Error diff --git a/targets/ChibiOS/ORGPAL_PALTHREE/nanoBooter/chconf.h b/targets/ChibiOS/ORGPAL_PALTHREE/nanoBooter/chconf.h index 7d04091405..f9a89f619c 100644 --- a/targets/ChibiOS/ORGPAL_PALTHREE/nanoBooter/chconf.h +++ b/targets/ChibiOS/ORGPAL_PALTHREE/nanoBooter/chconf.h @@ -70,7 +70,7 @@ * @note Allowed values are 16, 32 or 64 bits. */ #if !defined(CH_CFG_INTERVALS_SIZE) -#define CH_CFG_INTERVALS_SIZE 32 +#define CH_CFG_INTERVALS_SIZE 64 #endif /** @@ -178,7 +178,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_TIMESTAMP) -#define CH_CFG_USE_TIMESTAMP FALSE +#define CH_CFG_USE_TIMESTAMP TRUE #endif /** diff --git a/targets/ChibiOS/ORGPAL_PALTHREE/nanoBooter/halconf.h b/targets/ChibiOS/ORGPAL_PALTHREE/nanoBooter/halconf.h index 72a00564d8..ed9abd6601 100644 --- a/targets/ChibiOS/ORGPAL_PALTHREE/nanoBooter/halconf.h +++ b/targets/ChibiOS/ORGPAL_PALTHREE/nanoBooter/halconf.h @@ -21,7 +21,7 @@ #define HALCONF_H #define _CHIBIOS_HAL_CONF_ -#define _CHIBIOS_HAL_CONF_VER_8_0_ +#define _CHIBIOS_HAL_CONF_VER_8_4_ #include "mcuconf.h" diff --git a/targets/ChibiOS/ORGPAL_PALTHREE/nanoBooter/mcuconf.h b/targets/ChibiOS/ORGPAL_PALTHREE/nanoBooter/mcuconf.h index 9ed3334f02..71a955b95e 100644 --- a/targets/ChibiOS/ORGPAL_PALTHREE/nanoBooter/mcuconf.h +++ b/targets/ChibiOS/ORGPAL_PALTHREE/nanoBooter/mcuconf.h @@ -7,6 +7,8 @@ #ifndef MCUCONF_H #define MCUCONF_H +// clang-format off + /* * STM32F7xx drivers configuration. * The following settings override the default settings present in @@ -24,6 +26,14 @@ #define STM32F7xx_MCUCONF #define STM32F769_MCUCONF +/* + * Memory attributes settings. + */ +#define STM32_NOCACHE_ENABLE FALSE +// #define STM32_NOCACHE_MPU_REGION MPU_REGION_6 +// #define STM32_NOCACHE_RBAR 0x2004C000U +// #define STM32_NOCACHE_RASR MPU_RASR_SIZE_16K + /* * HAL driver system settings. */ @@ -428,3 +438,5 @@ #include "mcuconf_nf.h" #endif /* MCUCONF_H */ + +// clang-format on diff --git a/targets/ChibiOS/ORGPAL_PALTHREE/nanoCLR/chconf.h b/targets/ChibiOS/ORGPAL_PALTHREE/nanoCLR/chconf.h index 0f0f0988cf..1b2c67d18e 100644 --- a/targets/ChibiOS/ORGPAL_PALTHREE/nanoCLR/chconf.h +++ b/targets/ChibiOS/ORGPAL_PALTHREE/nanoCLR/chconf.h @@ -70,7 +70,7 @@ * @note Allowed values are 16, 32 or 64 bits. */ #if !defined(CH_CFG_INTERVALS_SIZE) -#define CH_CFG_INTERVALS_SIZE 32 +#define CH_CFG_INTERVALS_SIZE 64 #endif /** @@ -178,7 +178,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_TIMESTAMP) -#define CH_CFG_USE_TIMESTAMP FALSE +#define CH_CFG_USE_TIMESTAMP TRUE #endif /** diff --git a/targets/ChibiOS/ORGPAL_PALTHREE/nanoCLR/halconf.h b/targets/ChibiOS/ORGPAL_PALTHREE/nanoCLR/halconf.h index 3222a6e002..9a0d030c27 100644 --- a/targets/ChibiOS/ORGPAL_PALTHREE/nanoCLR/halconf.h +++ b/targets/ChibiOS/ORGPAL_PALTHREE/nanoCLR/halconf.h @@ -21,7 +21,7 @@ #define HALCONF_H #define _CHIBIOS_HAL_CONF_ -#define _CHIBIOS_HAL_CONF_VER_8_0_ +#define _CHIBIOS_HAL_CONF_VER_8_4_ #include #include "mcuconf.h" diff --git a/targets/ChibiOS/ORGPAL_PALTHREE/nanoCLR/mcuconf.h b/targets/ChibiOS/ORGPAL_PALTHREE/nanoCLR/mcuconf.h index 126a26cae4..17f8d41b78 100644 --- a/targets/ChibiOS/ORGPAL_PALTHREE/nanoCLR/mcuconf.h +++ b/targets/ChibiOS/ORGPAL_PALTHREE/nanoCLR/mcuconf.h @@ -7,6 +7,8 @@ #ifndef MCUCONF_H #define MCUCONF_H +// clang-format off + /* * STM32F7xx drivers configuration. * The following settings override the default settings present in @@ -24,6 +26,14 @@ #define STM32F7xx_MCUCONF #define STM32F769_MCUCONF +/* + * Memory attributes settings. + */ +#define STM32_NOCACHE_ENABLE FALSE +// #define STM32_NOCACHE_MPU_REGION MPU_REGION_6 +// #define STM32_NOCACHE_RBAR 0x2004C000U +// #define STM32_NOCACHE_RASR MPU_RASR_SIZE_16K + /* * HAL driver system settings. */ @@ -429,3 +439,5 @@ #include "mcuconf_community.h" #endif /* MCUCONF_H */ + +// clang-format on diff --git a/targets/ChibiOS/ORGPAL_PALTHREE/target_system_device_pwm_config.cpp b/targets/ChibiOS/ORGPAL_PALTHREE/target_system_device_pwm_config.cpp new file mode 100644 index 0000000000..73cc6666d3 --- /dev/null +++ b/targets/ChibiOS/ORGPAL_PALTHREE/target_system_device_pwm_config.cpp @@ -0,0 +1,9 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS BLANK ON PURPOSE BECAUSE THIS TARGET DOESN'T REQUIRE THIS SPECIFIC CONFIGURATION // +/////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/targets/ChibiOS/ST_NUCLEO64_F091RC/CMakePresets.json b/targets/ChibiOS/ST_NUCLEO64_F091RC/CMakePresets.json new file mode 100644 index 0000000000..89a3c9cced --- /dev/null +++ b/targets/ChibiOS/ST_NUCLEO64_F091RC/CMakePresets.json @@ -0,0 +1,48 @@ +{ + "version": 4, + "include": [ + "../../../CMake/arm-gcc.json", + "../../../config/user-tools-repos.json", + "../../../config/user-prefs.json" + ], + "configurePresets": [ + { + "name": "ST_NUCLEO64_F091RC", + "inherits": [ + "arm-gcc-cortex-preset", + "user-tools-repos", + "user-prefs" + ], + "hidden": false, + "cacheVariables": { + "TARGET_BOARD": "${presetName}", + "TARGET_SERIES": "STM32F0xx", + "RTOS": "ChibiOS", + "NF_FEATURE_DEBUGGER": "ON", + "NF_FEATURE_RTC": "ON", + "NF_PLATFORM_NO_CLR_TRACE": "ON", + "NF_CLR_NO_IL_INLINE": "ON", + "NF_FEATURE_BINARY_SERIALIZATION": "OFF", + "USE_RNG": "OFF", + "NF_BUILD_RTM": "OFF", + "API_Hardware.Stm32": "ON", + "API_System.Device.Gpio": "ON", + "API_System.Device.Spi": "ON", + "API_System.Device.I2c": "ON", + "API_System.Device.Pwm": "ON", + "API_System.IO.Ports": "ON", + "API_nanoFramework.System.Text": "ON", + "API_nanoFramework.ResourceManager": "ON", + "API_nanoFramework.System.Collections": "ON" + } + } + ], + "buildPresets": [ + { + "inherits": "base-user", + "name": "ST_NUCLEO64_F091RC", + "displayName": "ST_NUCLEO64_F091RC", + "configurePreset": "ST_NUCLEO64_F091RC" + } + ] +} diff --git a/targets/ChibiOS/ST_NUCLEO64_F091RC/nanoBooter/chconf.h b/targets/ChibiOS/ST_NUCLEO64_F091RC/nanoBooter/chconf.h index f7d416dbc7..4704b0d29b 100644 --- a/targets/ChibiOS/ST_NUCLEO64_F091RC/nanoBooter/chconf.h +++ b/targets/ChibiOS/ST_NUCLEO64_F091RC/nanoBooter/chconf.h @@ -36,7 +36,7 @@ * direct interactions are handled by the OS. */ #if !defined(CH_CFG_SMP_MODE) -#define CH_CFG_SMP_MODE FALSE +#define CH_CFG_SMP_MODE FALSE #endif /** @} */ @@ -70,7 +70,7 @@ * @note Allowed values are 16, 32 or 64 bits. */ #if !defined(CH_CFG_INTERVALS_SIZE) -#define CH_CFG_INTERVALS_SIZE 32 +#define CH_CFG_INTERVALS_SIZE 64 #endif /** @@ -178,7 +178,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_TIMESTAMP) -#define CH_CFG_USE_TIMESTAMP FALSE +#define CH_CFG_USE_TIMESTAMP TRUE #endif /** @@ -651,40 +651,39 @@ * @brief System structure extension. * @details User fields added to the end of the @p ch_system_t structure. */ -#define CH_CFG_SYSTEM_EXTRA_FIELDS \ - /* Add system custom fields here.*/ +#define CH_CFG_SYSTEM_EXTRA_FIELDS /* Add system custom fields here.*/ /** * @brief System initialization hook. * @details User initialization code added to the @p chSysInit() function * just before interrupts are enabled globally. */ -#define CH_CFG_SYSTEM_INIT_HOOK() { \ - /* Add system initialization code here.*/ \ -} +#define CH_CFG_SYSTEM_INIT_HOOK() \ + { \ + /* Add system initialization code here.*/ \ + } /** * @brief OS instance structure extension. * @details User fields added to the end of the @p os_instance_t structure. */ -#define CH_CFG_OS_INSTANCE_EXTRA_FIELDS \ - /* Add OS instance custom fields here.*/ +#define CH_CFG_OS_INSTANCE_EXTRA_FIELDS /* Add OS instance custom fields here.*/ /** * @brief OS instance initialization hook. * * @param[in] oip pointer to the @p os_instance_t structure */ -#define CH_CFG_OS_INSTANCE_INIT_HOOK(oip) { \ - /* Add OS instance initialization code here.*/ \ -} +#define CH_CFG_OS_INSTANCE_INIT_HOOK(oip) \ + { \ + /* Add OS instance initialization code here.*/ \ + } /** * @brief Threads descriptor structure extension. * @details User fields added to the end of the @p thread_t structure. */ -#define CH_CFG_THREAD_EXTRA_FIELDS \ - /* Add threads custom fields here.*/ +#define CH_CFG_THREAD_EXTRA_FIELDS /* Add threads custom fields here.*/ /** * @brief Threads initialization hook. @@ -695,9 +694,10 @@ * * @param[in] tp pointer to the @p thread_t structure */ -#define CH_CFG_THREAD_INIT_HOOK(tp) { \ - /* Add threads initialization code here.*/ \ -} +#define CH_CFG_THREAD_INIT_HOOK(tp) \ + { \ + /* Add threads initialization code here.*/ \ + } /** * @brief Threads finalization hook. @@ -705,9 +705,10 @@ * * @param[in] tp pointer to the @p thread_t structure */ -#define CH_CFG_THREAD_EXIT_HOOK(tp) { \ - /* Add threads finalization code here.*/ \ -} +#define CH_CFG_THREAD_EXIT_HOOK(tp) \ + { \ + /* Add threads finalization code here.*/ \ + } /** * @brief Context switch hook. @@ -716,23 +717,26 @@ * @param[in] ntp thread being switched in * @param[in] otp thread being switched out */ -#define CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) { \ - /* Context switch code here.*/ \ -} +#define CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) \ + { \ + /* Context switch code here.*/ \ + } /** * @brief ISR enter hook. */ -#define CH_CFG_IRQ_PROLOGUE_HOOK() { \ - /* IRQ prologue code here.*/ \ -} +#define CH_CFG_IRQ_PROLOGUE_HOOK() \ + { \ + /* IRQ prologue code here.*/ \ + } /** * @brief ISR exit hook. */ -#define CH_CFG_IRQ_EPILOGUE_HOOK() { \ - /* IRQ epilogue code here.*/ \ -} +#define CH_CFG_IRQ_EPILOGUE_HOOK() \ + { \ + /* IRQ epilogue code here.*/ \ + } /** * @brief Idle thread enter hook. @@ -740,9 +744,10 @@ * should be invoked from here. * @note This macro can be used to activate a power saving mode. */ -#define CH_CFG_IDLE_ENTER_HOOK() { \ - /* Idle-enter code here.*/ \ -} +#define CH_CFG_IDLE_ENTER_HOOK() \ + { \ + /* Idle-enter code here.*/ \ + } /** * @brief Idle thread leave hook. @@ -750,52 +755,58 @@ * should be invoked from here. * @note This macro can be used to deactivate a power saving mode. */ -#define CH_CFG_IDLE_LEAVE_HOOK() { \ - /* Idle-leave code here.*/ \ -} +#define CH_CFG_IDLE_LEAVE_HOOK() \ + { \ + /* Idle-leave code here.*/ \ + } /** * @brief Idle Loop hook. * @details This hook is continuously invoked by the idle thread loop. */ -#define CH_CFG_IDLE_LOOP_HOOK() { \ - /* Idle loop code here.*/ \ -} +#define CH_CFG_IDLE_LOOP_HOOK() \ + { \ + /* Idle loop code here.*/ \ + } /** * @brief System tick event hook. * @details This hook is invoked in the system tick handler immediately * after processing the virtual timers queue. */ -#define CH_CFG_SYSTEM_TICK_HOOK() { \ - /* System tick event code here.*/ \ -} +#define CH_CFG_SYSTEM_TICK_HOOK() \ + { \ + /* System tick event code here.*/ \ + } /** * @brief System halt hook. * @details This hook is invoked in case to a system halting error before * the system is halted. */ -#define CH_CFG_SYSTEM_HALT_HOOK(reason) { \ - /* System halt code here.*/ \ -} +#define CH_CFG_SYSTEM_HALT_HOOK(reason) \ + { \ + /* System halt code here.*/ \ + } /** * @brief Trace hook. * @details This hook is invoked each time a new record is written in the * trace buffer. */ -#define CH_CFG_TRACE_HOOK(tep) { \ - /* Trace code here.*/ \ -} +#define CH_CFG_TRACE_HOOK(tep) \ + { \ + /* Trace code here.*/ \ + } /** * @brief Runtime Faults Collection Unit hook. * @details This hook is invoked each time new faults are collected and stored. */ -#define CH_CFG_RUNTIME_FAULTS_HOOK(mask) { \ - /* Faults handling code here.*/ \ -} +#define CH_CFG_RUNTIME_FAULTS_HOOK(mask) \ + { \ + /* Faults handling code here.*/ \ + } /** @} */ diff --git a/targets/ChibiOS/ST_NUCLEO64_F091RC/nanoBooter/halconf.h b/targets/ChibiOS/ST_NUCLEO64_F091RC/nanoBooter/halconf.h index 9135774e96..380a4ffeea 100644 --- a/targets/ChibiOS/ST_NUCLEO64_F091RC/nanoBooter/halconf.h +++ b/targets/ChibiOS/ST_NUCLEO64_F091RC/nanoBooter/halconf.h @@ -21,7 +21,7 @@ #define HALCONF_H #define _CHIBIOS_HAL_CONF_ -#define _CHIBIOS_HAL_CONF_VER_8_0_ +#define _CHIBIOS_HAL_CONF_VER_8_4_ #include "mcuconf.h" diff --git a/targets/ChibiOS/ST_NUCLEO64_F091RC/nanoCLR/chconf.h b/targets/ChibiOS/ST_NUCLEO64_F091RC/nanoCLR/chconf.h index d1e23c9050..c559f9a8b8 100644 --- a/targets/ChibiOS/ST_NUCLEO64_F091RC/nanoCLR/chconf.h +++ b/targets/ChibiOS/ST_NUCLEO64_F091RC/nanoCLR/chconf.h @@ -36,7 +36,7 @@ * direct interactions are handled by the OS. */ #if !defined(CH_CFG_SMP_MODE) -#define CH_CFG_SMP_MODE FALSE +#define CH_CFG_SMP_MODE FALSE #endif /** @} */ @@ -53,7 +53,7 @@ * @note Allowed values are 16, 32 or 64 bits. */ #if !defined(CH_CFG_ST_RESOLUTION) -#define CH_CFG_ST_RESOLUTION 32 +#define CH_CFG_ST_RESOLUTION 32 #endif /** @@ -62,7 +62,7 @@ * setting also defines the system tick time unit. */ #if !defined(CH_CFG_ST_FREQUENCY) -#define CH_CFG_ST_FREQUENCY 1000 // this is 1 millisecond +#define CH_CFG_ST_FREQUENCY 1000 // this is 1 millisecond #endif /** @@ -70,7 +70,7 @@ * @note Allowed values are 16, 32 or 64 bits. */ #if !defined(CH_CFG_INTERVALS_SIZE) -#define CH_CFG_INTERVALS_SIZE 32 +#define CH_CFG_INTERVALS_SIZE 32 #endif /** @@ -78,7 +78,7 @@ * @note Allowed values are 16 or 32 bits. */ #if !defined(CH_CFG_TIME_TYPES_SIZE) -#define CH_CFG_TIME_TYPES_SIZE 32 +#define CH_CFG_TIME_TYPES_SIZE 32 #endif /** @@ -90,7 +90,7 @@ * this value. */ #if !defined(CH_CFG_ST_TIMEDELTA) -#define CH_CFG_ST_TIMEDELTA 2 +#define CH_CFG_ST_TIMEDELTA 2 #endif /** @} */ @@ -115,7 +115,7 @@ * must be set to zero in that case. */ #if !defined(CH_CFG_TIME_QUANTUM) -#define CH_CFG_TIME_QUANTUM 0 +#define CH_CFG_TIME_QUANTUM 0 #endif /** @@ -126,7 +126,7 @@ * infinite loop. */ #if !defined(CH_CFG_NO_IDLE_THREAD) -#define CH_CFG_NO_IDLE_THREAD FALSE +#define CH_CFG_NO_IDLE_THREAD FALSE #endif /** @} */ @@ -147,7 +147,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_OPTIMIZE_SPEED) -#define CH_CFG_OPTIMIZE_SPEED TRUE +#define CH_CFG_OPTIMIZE_SPEED TRUE #endif /** @} */ @@ -167,7 +167,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_TM) -#define CH_CFG_USE_TM FALSE +#define CH_CFG_USE_TM FALSE #endif /** @@ -178,7 +178,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_TIMESTAMP) -#define CH_CFG_USE_TIMESTAMP FALSE +#define CH_CFG_USE_TIMESTAMP TRUE #endif /** @@ -188,7 +188,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_REGISTRY) -#define CH_CFG_USE_REGISTRY TRUE +#define CH_CFG_USE_REGISTRY TRUE #endif /** @@ -199,7 +199,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_WAITEXIT) -#define CH_CFG_USE_WAITEXIT TRUE +#define CH_CFG_USE_WAITEXIT TRUE #endif /** @@ -209,7 +209,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_SEMAPHORES) -#define CH_CFG_USE_SEMAPHORES TRUE +#define CH_CFG_USE_SEMAPHORES TRUE #endif /** @@ -222,7 +222,7 @@ * @note Requires @p CH_CFG_USE_SEMAPHORES. */ #if !defined(CH_CFG_USE_SEMAPHORES_PRIORITY) -#define CH_CFG_USE_SEMAPHORES_PRIORITY FALSE +#define CH_CFG_USE_SEMAPHORES_PRIORITY FALSE #endif /** @@ -232,7 +232,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_MUTEXES) -#define CH_CFG_USE_MUTEXES TRUE +#define CH_CFG_USE_MUTEXES TRUE #endif /** @@ -244,7 +244,7 @@ * @note Requires @p CH_CFG_USE_MUTEXES. */ #if !defined(CH_CFG_USE_MUTEXES_RECURSIVE) -#define CH_CFG_USE_MUTEXES_RECURSIVE FALSE +#define CH_CFG_USE_MUTEXES_RECURSIVE FALSE #endif /** @@ -256,7 +256,7 @@ * @note Requires @p CH_CFG_USE_MUTEXES. */ #if !defined(CH_CFG_USE_CONDVARS) -#define CH_CFG_USE_CONDVARS TRUE +#define CH_CFG_USE_CONDVARS TRUE #endif /** @@ -268,7 +268,7 @@ * @note Requires @p CH_CFG_USE_CONDVARS. */ #if !defined(CH_CFG_USE_CONDVARS_TIMEOUT) -#define CH_CFG_USE_CONDVARS_TIMEOUT TRUE +#define CH_CFG_USE_CONDVARS_TIMEOUT TRUE #endif /** @@ -278,7 +278,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_EVENTS) -#define CH_CFG_USE_EVENTS TRUE +#define CH_CFG_USE_EVENTS TRUE #endif /** @@ -290,7 +290,7 @@ * @note Requires @p CH_CFG_USE_EVENTS. */ #if !defined(CH_CFG_USE_EVENTS_TIMEOUT) -#define CH_CFG_USE_EVENTS_TIMEOUT TRUE +#define CH_CFG_USE_EVENTS_TIMEOUT TRUE #endif /** @@ -301,7 +301,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_MESSAGES) -#define CH_CFG_USE_MESSAGES TRUE +#define CH_CFG_USE_MESSAGES TRUE #endif /** @@ -314,7 +314,7 @@ * @note Requires @p CH_CFG_USE_MESSAGES. */ #if !defined(CH_CFG_USE_MESSAGES_PRIORITY) -#define CH_CFG_USE_MESSAGES_PRIORITY FALSE +#define CH_CFG_USE_MESSAGES_PRIORITY FALSE #endif /** @@ -327,7 +327,7 @@ * @note Requires @p CH_CFG_USE_HEAP and/or @p CH_CFG_USE_MEMPOOLS. */ #if !defined(CH_CFG_USE_DYNAMIC) -#define CH_CFG_USE_DYNAMIC TRUE +#define CH_CFG_USE_DYNAMIC TRUE #endif /** @} */ @@ -348,7 +348,7 @@ * @note Requires @p CH_CFG_USE_SEMAPHORES. */ #if !defined(CH_CFG_USE_MAILBOXES) -#define CH_CFG_USE_MAILBOXES TRUE +#define CH_CFG_USE_MAILBOXES TRUE #endif /** @@ -359,7 +359,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_MEMCORE) -#define CH_CFG_USE_MEMCORE TRUE +#define CH_CFG_USE_MEMCORE TRUE #endif /** @@ -374,7 +374,7 @@ * @note Requires @p CH_CFG_USE_MEMCORE. */ #if !defined(CH_CFG_MEMCORE_SIZE) -#define CH_CFG_MEMCORE_SIZE 0 +#define CH_CFG_MEMCORE_SIZE 0 #endif /** @@ -388,7 +388,7 @@ * @note Mutexes are recommended. */ #if !defined(CH_CFG_USE_HEAP) -#define CH_CFG_USE_HEAP TRUE +#define CH_CFG_USE_HEAP TRUE #endif /** @@ -399,7 +399,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_MEMPOOLS) -#define CH_CFG_USE_MEMPOOLS TRUE +#define CH_CFG_USE_MEMPOOLS TRUE #endif /** @@ -410,7 +410,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_OBJ_FIFOS) -#define CH_CFG_USE_OBJ_FIFOS TRUE +#define CH_CFG_USE_OBJ_FIFOS TRUE #endif /** @@ -421,7 +421,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_PIPES) -#define CH_CFG_USE_PIPES TRUE +#define CH_CFG_USE_PIPES TRUE #endif /** @@ -432,7 +432,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_OBJ_CACHES) -#define CH_CFG_USE_OBJ_CACHES FALSE +#define CH_CFG_USE_OBJ_CACHES FALSE #endif /** @@ -443,7 +443,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_DELEGATES) -#define CH_CFG_USE_DELEGATES FALSE +#define CH_CFG_USE_DELEGATES FALSE #endif /** @@ -454,7 +454,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_JOBS) -#define CH_CFG_USE_JOBS FALSE +#define CH_CFG_USE_JOBS FALSE #endif /** @} */ @@ -474,7 +474,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_CFG_USE_FACTORY) -#define CH_CFG_USE_FACTORY FALSE +#define CH_CFG_USE_FACTORY FALSE #endif /** @@ -483,49 +483,49 @@ * pointer but this could have unintended side effects. */ #if !defined(CH_CFG_FACTORY_MAX_NAMES_LENGTH) -#define CH_CFG_FACTORY_MAX_NAMES_LENGTH 8 +#define CH_CFG_FACTORY_MAX_NAMES_LENGTH 8 #endif /** * @brief Enables the registry of generic objects. */ #if !defined(CH_CFG_FACTORY_OBJECTS_REGISTRY) -#define CH_CFG_FACTORY_OBJECTS_REGISTRY TRUE +#define CH_CFG_FACTORY_OBJECTS_REGISTRY TRUE #endif /** * @brief Enables factory for generic buffers. */ #if !defined(CH_CFG_FACTORY_GENERIC_BUFFERS) -#define CH_CFG_FACTORY_GENERIC_BUFFERS TRUE +#define CH_CFG_FACTORY_GENERIC_BUFFERS TRUE #endif /** * @brief Enables factory for semaphores. */ #if !defined(CH_CFG_FACTORY_SEMAPHORES) -#define CH_CFG_FACTORY_SEMAPHORES TRUE +#define CH_CFG_FACTORY_SEMAPHORES TRUE #endif /** * @brief Enables factory for mailboxes. */ #if !defined(CH_CFG_FACTORY_MAILBOXES) -#define CH_CFG_FACTORY_MAILBOXES TRUE +#define CH_CFG_FACTORY_MAILBOXES TRUE #endif /** * @brief Enables factory for objects FIFOs. */ #if !defined(CH_CFG_FACTORY_OBJ_FIFOS) -#define CH_CFG_FACTORY_OBJ_FIFOS TRUE +#define CH_CFG_FACTORY_OBJ_FIFOS TRUE #endif /** * @brief Enables factory for Pipes. */ #if !defined(CH_CFG_FACTORY_PIPES) || defined(__DOXYGEN__) -#define CH_CFG_FACTORY_PIPES TRUE +#define CH_CFG_FACTORY_PIPES TRUE #endif /** @} */ @@ -543,7 +543,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_STATISTICS) -#define CH_DBG_STATISTICS FALSE +#define CH_DBG_STATISTICS FALSE #endif /** @@ -554,7 +554,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_SYSTEM_STATE_CHECK) -#define CH_DBG_SYSTEM_STATE_CHECK FALSE +#define CH_DBG_SYSTEM_STATE_CHECK FALSE #endif /** @@ -565,7 +565,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_ENABLE_CHECKS) -#define CH_DBG_ENABLE_CHECKS FALSE +#define CH_DBG_ENABLE_CHECKS FALSE #endif /** @@ -577,7 +577,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_ENABLE_ASSERTS) -#define CH_DBG_ENABLE_ASSERTS FALSE +#define CH_DBG_ENABLE_ASSERTS FALSE #endif /** @@ -587,7 +587,7 @@ * @note The default is @p CH_DBG_TRACE_MASK_DISABLED. */ #if !defined(CH_DBG_TRACE_MASK) -#define CH_DBG_TRACE_MASK CH_DBG_TRACE_MASK_DISABLED +#define CH_DBG_TRACE_MASK CH_DBG_TRACE_MASK_DISABLED #endif /** @@ -596,7 +596,7 @@ * different from @p CH_DBG_TRACE_MASK_DISABLED. */ #if !defined(CH_DBG_TRACE_BUFFER_SIZE) -#define CH_DBG_TRACE_BUFFER_SIZE 128 +#define CH_DBG_TRACE_BUFFER_SIZE 128 #endif /** @@ -610,7 +610,7 @@ * @p panic_msg variable set to @p NULL. */ #if !defined(CH_DBG_ENABLE_STACK_CHECK) -#define CH_DBG_ENABLE_STACK_CHECK FALSE +#define CH_DBG_ENABLE_STACK_CHECK FALSE #endif /** @@ -622,7 +622,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_FILL_THREADS) -#define CH_DBG_FILL_THREADS FALSE +#define CH_DBG_FILL_THREADS FALSE #endif /** @@ -635,7 +635,7 @@ * tickless mode. */ #if !defined(CH_DBG_THREADS_PROFILING) -#define CH_DBG_THREADS_PROFILING FALSE +#define CH_DBG_THREADS_PROFILING FALSE #endif /** @} */ @@ -651,40 +651,39 @@ * @brief System structure extension. * @details User fields added to the end of the @p ch_system_t structure. */ -#define CH_CFG_SYSTEM_EXTRA_FIELDS \ - /* Add system custom fields here.*/ +#define CH_CFG_SYSTEM_EXTRA_FIELDS /* Add system custom fields here.*/ /** * @brief System initialization hook. * @details User initialization code added to the @p chSysInit() function * just before interrupts are enabled globally. */ -#define CH_CFG_SYSTEM_INIT_HOOK() { \ - /* Add system initialization code here.*/ \ -} +#define CH_CFG_SYSTEM_INIT_HOOK() \ + { \ + /* Add system initialization code here.*/ \ + } /** * @brief OS instance structure extension. * @details User fields added to the end of the @p os_instance_t structure. */ -#define CH_CFG_OS_INSTANCE_EXTRA_FIELDS \ - /* Add OS instance custom fields here.*/ +#define CH_CFG_OS_INSTANCE_EXTRA_FIELDS /* Add OS instance custom fields here.*/ /** * @brief OS instance initialization hook. * * @param[in] oip pointer to the @p os_instance_t structure */ -#define CH_CFG_OS_INSTANCE_INIT_HOOK(oip) { \ - /* Add OS instance initialization code here.*/ \ -} +#define CH_CFG_OS_INSTANCE_INIT_HOOK(oip) \ + { \ + /* Add OS instance initialization code here.*/ \ + } /** * @brief Threads descriptor structure extension. * @details User fields added to the end of the @p thread_t structure. */ -#define CH_CFG_THREAD_EXTRA_FIELDS \ - /* Add threads custom fields here.*/ +#define CH_CFG_THREAD_EXTRA_FIELDS /* Add threads custom fields here.*/ /** * @brief Threads initialization hook. @@ -695,9 +694,10 @@ * * @param[in] tp pointer to the @p thread_t structure */ -#define CH_CFG_THREAD_INIT_HOOK(tp) { \ - /* Add threads initialization code here.*/ \ -} +#define CH_CFG_THREAD_INIT_HOOK(tp) \ + { \ + /* Add threads initialization code here.*/ \ + } /** * @brief Threads finalization hook. @@ -705,9 +705,10 @@ * * @param[in] tp pointer to the @p thread_t structure */ -#define CH_CFG_THREAD_EXIT_HOOK(tp) { \ - /* Add threads finalization code here.*/ \ -} +#define CH_CFG_THREAD_EXIT_HOOK(tp) \ + { \ + /* Add threads finalization code here.*/ \ + } /** * @brief Context switch hook. @@ -716,23 +717,26 @@ * @param[in] ntp thread being switched in * @param[in] otp thread being switched out */ -#define CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) { \ - /* Context switch code here.*/ \ -} +#define CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) \ + { \ + /* Context switch code here.*/ \ + } /** * @brief ISR enter hook. */ -#define CH_CFG_IRQ_PROLOGUE_HOOK() { \ - /* IRQ prologue code here.*/ \ -} +#define CH_CFG_IRQ_PROLOGUE_HOOK() \ + { \ + /* IRQ prologue code here.*/ \ + } /** * @brief ISR exit hook. */ -#define CH_CFG_IRQ_EPILOGUE_HOOK() { \ - /* IRQ epilogue code here.*/ \ -} +#define CH_CFG_IRQ_EPILOGUE_HOOK() \ + { \ + /* IRQ epilogue code here.*/ \ + } /** * @brief Idle thread enter hook. @@ -740,9 +744,10 @@ * should be invoked from here. * @note This macro can be used to activate a power saving mode. */ -#define CH_CFG_IDLE_ENTER_HOOK() { \ - /* Idle-enter code here.*/ \ -} +#define CH_CFG_IDLE_ENTER_HOOK() \ + { \ + /* Idle-enter code here.*/ \ + } /** * @brief Idle thread leave hook. @@ -750,52 +755,58 @@ * should be invoked from here. * @note This macro can be used to deactivate a power saving mode. */ -#define CH_CFG_IDLE_LEAVE_HOOK() { \ - /* Idle-leave code here.*/ \ -} +#define CH_CFG_IDLE_LEAVE_HOOK() \ + { \ + /* Idle-leave code here.*/ \ + } /** * @brief Idle Loop hook. * @details This hook is continuously invoked by the idle thread loop. */ -#define CH_CFG_IDLE_LOOP_HOOK() { \ - /* Idle loop code here.*/ \ -} +#define CH_CFG_IDLE_LOOP_HOOK() \ + { \ + /* Idle loop code here.*/ \ + } /** * @brief System tick event hook. * @details This hook is invoked in the system tick handler immediately * after processing the virtual timers queue. */ -#define CH_CFG_SYSTEM_TICK_HOOK() { \ - /* System tick event code here.*/ \ -} +#define CH_CFG_SYSTEM_TICK_HOOK() \ + { \ + /* System tick event code here.*/ \ + } /** * @brief System halt hook. * @details This hook is invoked in case to a system halting error before * the system is halted. */ -#define CH_CFG_SYSTEM_HALT_HOOK(reason) { \ - /* System halt code here.*/ \ -} +#define CH_CFG_SYSTEM_HALT_HOOK(reason) \ + { \ + /* System halt code here.*/ \ + } /** * @brief Trace hook. * @details This hook is invoked each time a new record is written in the * trace buffer. */ -#define CH_CFG_TRACE_HOOK(tep) { \ - /* Trace code here.*/ \ -} +#define CH_CFG_TRACE_HOOK(tep) \ + { \ + /* Trace code here.*/ \ + } /** * @brief Runtime Faults Collection Unit hook. * @details This hook is invoked each time new faults are collected and stored. */ -#define CH_CFG_RUNTIME_FAULTS_HOOK(mask) { \ - /* Faults handling code here.*/ \ -} +#define CH_CFG_RUNTIME_FAULTS_HOOK(mask) \ + { \ + /* Faults handling code here.*/ \ + } /** @} */ @@ -803,6 +814,6 @@ /* Port-specific settings (override port settings defaulted in chcore.h). */ /*===========================================================================*/ -#endif /* CHCONF_H */ +#endif /* CHCONF_H */ /** @} */ diff --git a/targets/ChibiOS/ST_NUCLEO64_F091RC/nanoCLR/halconf.h b/targets/ChibiOS/ST_NUCLEO64_F091RC/nanoCLR/halconf.h index c9ae8ff6ba..1ba0b44164 100644 --- a/targets/ChibiOS/ST_NUCLEO64_F091RC/nanoCLR/halconf.h +++ b/targets/ChibiOS/ST_NUCLEO64_F091RC/nanoCLR/halconf.h @@ -21,7 +21,7 @@ #define HALCONF_H #define _CHIBIOS_HAL_CONF_ -#define _CHIBIOS_HAL_CONF_VER_8_0_ +#define _CHIBIOS_HAL_CONF_VER_8_4_ #include #include "mcuconf.h" diff --git a/targets/ChibiOS/ST_NUCLEO64_F091RC/target_system_device_pwm_config.cpp b/targets/ChibiOS/ST_NUCLEO64_F091RC/target_system_device_pwm_config.cpp new file mode 100644 index 0000000000..73cc6666d3 --- /dev/null +++ b/targets/ChibiOS/ST_NUCLEO64_F091RC/target_system_device_pwm_config.cpp @@ -0,0 +1,9 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS BLANK ON PURPOSE BECAUSE THIS TARGET DOESN'T REQUIRE THIS SPECIFIC CONFIGURATION // +/////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/targets/ChibiOS/ST_STM32F429I_DISCOVERY/CMakePresets.json b/targets/ChibiOS/ST_STM32F429I_DISCOVERY/CMakePresets.json new file mode 100644 index 0000000000..90f4cc87bb --- /dev/null +++ b/targets/ChibiOS/ST_STM32F429I_DISCOVERY/CMakePresets.json @@ -0,0 +1,58 @@ +{ + "version": 4, + "include": [ + "../../../CMake/arm-gcc.json", + "../../../config/user-tools-repos.json", + "../../../config/user-prefs.json" + ], + "configurePresets": [ + { + "name": "ST_STM32F429I_DISCOVERY", + "inherits": [ + "arm-gcc-cortex-preset", + "user-tools-repos", + "user-prefs" + ], + "hidden": false, + "cacheVariables": { + "TARGET_BOARD": "${presetName}", + "RTOS": "ChibiOS", + "TARGET_SERIES": "STM32F4xx", + "CHIBIOS_CONTRIB_REQUIRED": "OFF", + "STM32_CUBE_PACKAGE_REQUIRED": "OFF", + "SUPPORT_ANY_BASE_CONVERSION": "ON", + "NF_FEATURE_DEBUGGER": "ON", + "NF_FEATURE_RTC": "ON", + "SWO_OUTPUT": "OFF", + "NF_BUILD_RTM": "OFF", + "API_System.Math": "ON", + "API_Hardware.Stm32": "ON", + "API_System.Device.Gpio": "ON", + "API_System.Device.Spi": "ON", + "API_System.Device.I2c": "ON", + "API_System.Device.Pwm": "ON", + "API_System.IO.Ports": "ON", + "API_System.Device.Adc": "ON", + "API_nanoFramework.Device.OneWire": "ON", + "API_nanoFramework.Device.Can": "ON", + "API_nanoFramework.ResourceManager": "ON", + "API_nanoFramework.System.Collections": "ON", + "API_nanoFramework.System.Text": "ON", + "API_nanoFramework.Graphics": "ON", + "GRAPHICS_MEMORY": "Graphics_Memory.cpp", + "GRAPHICS_DISPLAY": "ILI9341_240x320_SPI.cpp", + "GRAPHICS_DISPLAY_INTERFACE": "Spi_To_Display.cpp", + "TOUCHPANEL_DEVICE": "STMPE811QTR_I2C.cpp", + "TOUCHPANEL_INTERFACE": "I2C_To_TouchPanel.cpp" + } + } + ], + "buildPresets": [ + { + "inherits": "base-user", + "name": "ST_STM32F429I_DISCOVERY", + "displayName": "ST_STM32F429I_DISCOVERY", + "configurePreset": "ST_STM32F429I_DISCOVERY" + } + ] +} diff --git a/targets/ChibiOS/ST_STM32F429I_DISCOVERY/nanoBooter/chconf.h b/targets/ChibiOS/ST_STM32F429I_DISCOVERY/nanoBooter/chconf.h index 8b7e15a07a..64b2ae4411 100644 --- a/targets/ChibiOS/ST_STM32F429I_DISCOVERY/nanoBooter/chconf.h +++ b/targets/ChibiOS/ST_STM32F429I_DISCOVERY/nanoBooter/chconf.h @@ -36,7 +36,7 @@ * direct interactions are handled by the OS. */ #if !defined(CH_CFG_SMP_MODE) -#define CH_CFG_SMP_MODE FALSE +#define CH_CFG_SMP_MODE FALSE #endif /** @} */ @@ -53,7 +53,7 @@ * @note Allowed values are 16, 32 or 64 bits. */ #if !defined(CH_CFG_ST_RESOLUTION) -#define CH_CFG_ST_RESOLUTION 32 +#define CH_CFG_ST_RESOLUTION 32 #endif /** @@ -62,7 +62,7 @@ * setting also defines the system tick time unit. */ #if !defined(CH_CFG_ST_FREQUENCY) -#define CH_CFG_ST_FREQUENCY 1000 // this is 1 millisecond +#define CH_CFG_ST_FREQUENCY 1000 // this is 1 millisecond #endif /** @@ -70,7 +70,7 @@ * @note Allowed values are 16, 32 or 64 bits. */ #if !defined(CH_CFG_INTERVALS_SIZE) -#define CH_CFG_INTERVALS_SIZE 32 +#define CH_CFG_INTERVALS_SIZE 32 #endif /** @@ -78,7 +78,7 @@ * @note Allowed values are 16 or 32 bits. */ #if !defined(CH_CFG_TIME_TYPES_SIZE) -#define CH_CFG_TIME_TYPES_SIZE 32 +#define CH_CFG_TIME_TYPES_SIZE 32 #endif /** @@ -90,7 +90,7 @@ * this value. */ #if !defined(CH_CFG_ST_TIMEDELTA) -#define CH_CFG_ST_TIMEDELTA 2 +#define CH_CFG_ST_TIMEDELTA 2 #endif /** @} */ @@ -115,7 +115,7 @@ * must be set to zero in that case. */ #if !defined(CH_CFG_TIME_QUANTUM) -#define CH_CFG_TIME_QUANTUM 0 +#define CH_CFG_TIME_QUANTUM 0 #endif /** @@ -126,7 +126,7 @@ * infinite loop. */ #if !defined(CH_CFG_NO_IDLE_THREAD) -#define CH_CFG_NO_IDLE_THREAD FALSE +#define CH_CFG_NO_IDLE_THREAD FALSE #endif /** @} */ @@ -147,7 +147,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_OPTIMIZE_SPEED) -#define CH_CFG_OPTIMIZE_SPEED TRUE +#define CH_CFG_OPTIMIZE_SPEED TRUE #endif /** @} */ @@ -167,7 +167,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_TM) -#define CH_CFG_USE_TM FALSE +#define CH_CFG_USE_TM FALSE #endif /** @@ -178,7 +178,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_TIMESTAMP) -#define CH_CFG_USE_TIMESTAMP FALSE +#define CH_CFG_USE_TIMESTAMP TRUE #endif /** @@ -188,7 +188,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_REGISTRY) -#define CH_CFG_USE_REGISTRY TRUE +#define CH_CFG_USE_REGISTRY TRUE #endif /** @@ -199,7 +199,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_WAITEXIT) -#define CH_CFG_USE_WAITEXIT TRUE +#define CH_CFG_USE_WAITEXIT TRUE #endif /** @@ -209,7 +209,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_SEMAPHORES) -#define CH_CFG_USE_SEMAPHORES TRUE +#define CH_CFG_USE_SEMAPHORES TRUE #endif /** @@ -222,7 +222,7 @@ * @note Requires @p CH_CFG_USE_SEMAPHORES. */ #if !defined(CH_CFG_USE_SEMAPHORES_PRIORITY) -#define CH_CFG_USE_SEMAPHORES_PRIORITY FALSE +#define CH_CFG_USE_SEMAPHORES_PRIORITY FALSE #endif /** @@ -232,7 +232,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_MUTEXES) -#define CH_CFG_USE_MUTEXES FALSE +#define CH_CFG_USE_MUTEXES FALSE #endif /** @@ -244,7 +244,7 @@ * @note Requires @p CH_CFG_USE_MUTEXES. */ #if !defined(CH_CFG_USE_MUTEXES_RECURSIVE) -#define CH_CFG_USE_MUTEXES_RECURSIVE FALSE +#define CH_CFG_USE_MUTEXES_RECURSIVE FALSE #endif /** @@ -256,7 +256,7 @@ * @note Requires @p CH_CFG_USE_MUTEXES. */ #if !defined(CH_CFG_USE_CONDVARS) -#define CH_CFG_USE_CONDVARS FALSE +#define CH_CFG_USE_CONDVARS FALSE #endif /** @@ -268,7 +268,7 @@ * @note Requires @p CH_CFG_USE_CONDVARS. */ #if !defined(CH_CFG_USE_CONDVARS_TIMEOUT) -#define CH_CFG_USE_CONDVARS_TIMEOUT FALSE +#define CH_CFG_USE_CONDVARS_TIMEOUT FALSE #endif /** @@ -278,7 +278,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_EVENTS) -#define CH_CFG_USE_EVENTS TRUE +#define CH_CFG_USE_EVENTS TRUE #endif /** @@ -290,7 +290,7 @@ * @note Requires @p CH_CFG_USE_EVENTS. */ #if !defined(CH_CFG_USE_EVENTS_TIMEOUT) -#define CH_CFG_USE_EVENTS_TIMEOUT TRUE +#define CH_CFG_USE_EVENTS_TIMEOUT TRUE #endif /** @@ -301,7 +301,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_MESSAGES) -#define CH_CFG_USE_MESSAGES FALSE +#define CH_CFG_USE_MESSAGES FALSE #endif /** @@ -314,7 +314,7 @@ * @note Requires @p CH_CFG_USE_MESSAGES. */ #if !defined(CH_CFG_USE_MESSAGES_PRIORITY) -#define CH_CFG_USE_MESSAGES_PRIORITY FALSE +#define CH_CFG_USE_MESSAGES_PRIORITY FALSE #endif /** @@ -327,7 +327,7 @@ * @note Requires @p CH_CFG_USE_HEAP and/or @p CH_CFG_USE_MEMPOOLS. */ #if !defined(CH_CFG_USE_DYNAMIC) -#define CH_CFG_USE_DYNAMIC TRUE +#define CH_CFG_USE_DYNAMIC TRUE #endif /** @} */ @@ -348,7 +348,7 @@ * @note Requires @p CH_CFG_USE_SEMAPHORES. */ #if !defined(CH_CFG_USE_MAILBOXES) -#define CH_CFG_USE_MAILBOXES TRUE +#define CH_CFG_USE_MAILBOXES TRUE #endif /** @@ -359,7 +359,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_MEMCORE) -#define CH_CFG_USE_MEMCORE TRUE +#define CH_CFG_USE_MEMCORE TRUE #endif /** @@ -374,7 +374,7 @@ * @note Requires @p CH_CFG_USE_MEMCORE. */ #if !defined(CH_CFG_MEMCORE_SIZE) -#define CH_CFG_MEMCORE_SIZE 0 +#define CH_CFG_MEMCORE_SIZE 0 #endif /** @@ -388,7 +388,7 @@ * @note Mutexes are recommended. */ #if !defined(CH_CFG_USE_HEAP) -#define CH_CFG_USE_HEAP TRUE +#define CH_CFG_USE_HEAP TRUE #endif /** @@ -399,7 +399,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_MEMPOOLS) -#define CH_CFG_USE_MEMPOOLS TRUE +#define CH_CFG_USE_MEMPOOLS TRUE #endif /** @@ -410,7 +410,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_OBJ_FIFOS) -#define CH_CFG_USE_OBJ_FIFOS TRUE +#define CH_CFG_USE_OBJ_FIFOS TRUE #endif /** @@ -421,7 +421,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_PIPES) -#define CH_CFG_USE_PIPES TRUE +#define CH_CFG_USE_PIPES TRUE #endif /** @@ -432,7 +432,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_OBJ_CACHES) -#define CH_CFG_USE_OBJ_CACHES FALSE +#define CH_CFG_USE_OBJ_CACHES FALSE #endif /** @@ -443,7 +443,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_DELEGATES) -#define CH_CFG_USE_DELEGATES FALSE +#define CH_CFG_USE_DELEGATES FALSE #endif /** @@ -454,7 +454,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_JOBS) -#define CH_CFG_USE_JOBS FALSE +#define CH_CFG_USE_JOBS FALSE #endif /** @} */ @@ -474,7 +474,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_CFG_USE_FACTORY) -#define CH_CFG_USE_FACTORY FALSE +#define CH_CFG_USE_FACTORY FALSE #endif /** @@ -483,49 +483,49 @@ * pointer but this could have unintended side effects. */ #if !defined(CH_CFG_FACTORY_MAX_NAMES_LENGTH) -#define CH_CFG_FACTORY_MAX_NAMES_LENGTH 8 +#define CH_CFG_FACTORY_MAX_NAMES_LENGTH 8 #endif /** * @brief Enables the registry of generic objects. */ #if !defined(CH_CFG_FACTORY_OBJECTS_REGISTRY) -#define CH_CFG_FACTORY_OBJECTS_REGISTRY TRUE +#define CH_CFG_FACTORY_OBJECTS_REGISTRY TRUE #endif /** * @brief Enables factory for generic buffers. */ #if !defined(CH_CFG_FACTORY_GENERIC_BUFFERS) -#define CH_CFG_FACTORY_GENERIC_BUFFERS TRUE +#define CH_CFG_FACTORY_GENERIC_BUFFERS TRUE #endif /** * @brief Enables factory for semaphores. */ #if !defined(CH_CFG_FACTORY_SEMAPHORES) -#define CH_CFG_FACTORY_SEMAPHORES TRUE +#define CH_CFG_FACTORY_SEMAPHORES TRUE #endif /** * @brief Enables factory for mailboxes. */ #if !defined(CH_CFG_FACTORY_MAILBOXES) -#define CH_CFG_FACTORY_MAILBOXES TRUE +#define CH_CFG_FACTORY_MAILBOXES TRUE #endif /** * @brief Enables factory for objects FIFOs. */ #if !defined(CH_CFG_FACTORY_OBJ_FIFOS) -#define CH_CFG_FACTORY_OBJ_FIFOS TRUE +#define CH_CFG_FACTORY_OBJ_FIFOS TRUE #endif /** * @brief Enables factory for Pipes. */ #if !defined(CH_CFG_FACTORY_PIPES) || defined(__DOXYGEN__) -#define CH_CFG_FACTORY_PIPES TRUE +#define CH_CFG_FACTORY_PIPES TRUE #endif /** @} */ @@ -543,7 +543,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_STATISTICS) -#define CH_DBG_STATISTICS FALSE +#define CH_DBG_STATISTICS FALSE #endif /** @@ -554,7 +554,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_SYSTEM_STATE_CHECK) -#define CH_DBG_SYSTEM_STATE_CHECK FALSE +#define CH_DBG_SYSTEM_STATE_CHECK FALSE #endif /** @@ -565,7 +565,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_ENABLE_CHECKS) -#define CH_DBG_ENABLE_CHECKS FALSE +#define CH_DBG_ENABLE_CHECKS FALSE #endif /** @@ -577,7 +577,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_ENABLE_ASSERTS) -#define CH_DBG_ENABLE_ASSERTS FALSE +#define CH_DBG_ENABLE_ASSERTS FALSE #endif /** @@ -587,7 +587,7 @@ * @note The default is @p CH_DBG_TRACE_MASK_DISABLED. */ #if !defined(CH_DBG_TRACE_MASK) -#define CH_DBG_TRACE_MASK CH_DBG_TRACE_MASK_DISABLED +#define CH_DBG_TRACE_MASK CH_DBG_TRACE_MASK_DISABLED #endif /** @@ -596,7 +596,7 @@ * different from @p CH_DBG_TRACE_MASK_DISABLED. */ #if !defined(CH_DBG_TRACE_BUFFER_SIZE) -#define CH_DBG_TRACE_BUFFER_SIZE 128 +#define CH_DBG_TRACE_BUFFER_SIZE 128 #endif /** @@ -610,7 +610,7 @@ * @p panic_msg variable set to @p NULL. */ #if !defined(CH_DBG_ENABLE_STACK_CHECK) -#define CH_DBG_ENABLE_STACK_CHECK FALSE +#define CH_DBG_ENABLE_STACK_CHECK FALSE #endif /** @@ -622,7 +622,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_FILL_THREADS) -#define CH_DBG_FILL_THREADS FALSE +#define CH_DBG_FILL_THREADS FALSE #endif /** @@ -635,7 +635,7 @@ * tickless mode. */ #if !defined(CH_DBG_THREADS_PROFILING) -#define CH_DBG_THREADS_PROFILING FALSE +#define CH_DBG_THREADS_PROFILING FALSE #endif /** @} */ @@ -651,40 +651,39 @@ * @brief System structure extension. * @details User fields added to the end of the @p ch_system_t structure. */ -#define CH_CFG_SYSTEM_EXTRA_FIELDS \ - /* Add system custom fields here.*/ +#define CH_CFG_SYSTEM_EXTRA_FIELDS /* Add system custom fields here.*/ /** * @brief System initialization hook. * @details User initialization code added to the @p chSysInit() function * just before interrupts are enabled globally. */ -#define CH_CFG_SYSTEM_INIT_HOOK() { \ - /* Add system initialization code here.*/ \ -} +#define CH_CFG_SYSTEM_INIT_HOOK() \ + { \ + /* Add system initialization code here.*/ \ + } /** * @brief OS instance structure extension. * @details User fields added to the end of the @p os_instance_t structure. */ -#define CH_CFG_OS_INSTANCE_EXTRA_FIELDS \ - /* Add OS instance custom fields here.*/ +#define CH_CFG_OS_INSTANCE_EXTRA_FIELDS /* Add OS instance custom fields here.*/ /** * @brief OS instance initialization hook. * * @param[in] oip pointer to the @p os_instance_t structure */ -#define CH_CFG_OS_INSTANCE_INIT_HOOK(oip) { \ - /* Add OS instance initialization code here.*/ \ -} +#define CH_CFG_OS_INSTANCE_INIT_HOOK(oip) \ + { \ + /* Add OS instance initialization code here.*/ \ + } /** * @brief Threads descriptor structure extension. * @details User fields added to the end of the @p thread_t structure. */ -#define CH_CFG_THREAD_EXTRA_FIELDS \ - /* Add threads custom fields here.*/ +#define CH_CFG_THREAD_EXTRA_FIELDS /* Add threads custom fields here.*/ /** * @brief Threads initialization hook. @@ -695,9 +694,10 @@ * * @param[in] tp pointer to the @p thread_t structure */ -#define CH_CFG_THREAD_INIT_HOOK(tp) { \ - /* Add threads initialization code here.*/ \ -} +#define CH_CFG_THREAD_INIT_HOOK(tp) \ + { \ + /* Add threads initialization code here.*/ \ + } /** * @brief Threads finalization hook. @@ -705,9 +705,10 @@ * * @param[in] tp pointer to the @p thread_t structure */ -#define CH_CFG_THREAD_EXIT_HOOK(tp) { \ - /* Add threads finalization code here.*/ \ -} +#define CH_CFG_THREAD_EXIT_HOOK(tp) \ + { \ + /* Add threads finalization code here.*/ \ + } /** * @brief Context switch hook. @@ -716,23 +717,26 @@ * @param[in] ntp thread being switched in * @param[in] otp thread being switched out */ -#define CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) { \ - /* Context switch code here.*/ \ -} +#define CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) \ + { \ + /* Context switch code here.*/ \ + } /** * @brief ISR enter hook. */ -#define CH_CFG_IRQ_PROLOGUE_HOOK() { \ - /* IRQ prologue code here.*/ \ -} +#define CH_CFG_IRQ_PROLOGUE_HOOK() \ + { \ + /* IRQ prologue code here.*/ \ + } /** * @brief ISR exit hook. */ -#define CH_CFG_IRQ_EPILOGUE_HOOK() { \ - /* IRQ epilogue code here.*/ \ -} +#define CH_CFG_IRQ_EPILOGUE_HOOK() \ + { \ + /* IRQ epilogue code here.*/ \ + } /** * @brief Idle thread enter hook. @@ -740,9 +744,10 @@ * should be invoked from here. * @note This macro can be used to activate a power saving mode. */ -#define CH_CFG_IDLE_ENTER_HOOK() { \ - /* Idle-enter code here.*/ \ -} +#define CH_CFG_IDLE_ENTER_HOOK() \ + { \ + /* Idle-enter code here.*/ \ + } /** * @brief Idle thread leave hook. @@ -750,52 +755,58 @@ * should be invoked from here. * @note This macro can be used to deactivate a power saving mode. */ -#define CH_CFG_IDLE_LEAVE_HOOK() { \ - /* Idle-leave code here.*/ \ -} +#define CH_CFG_IDLE_LEAVE_HOOK() \ + { \ + /* Idle-leave code here.*/ \ + } /** * @brief Idle Loop hook. * @details This hook is continuously invoked by the idle thread loop. */ -#define CH_CFG_IDLE_LOOP_HOOK() { \ - /* Idle loop code here.*/ \ -} +#define CH_CFG_IDLE_LOOP_HOOK() \ + { \ + /* Idle loop code here.*/ \ + } /** * @brief System tick event hook. * @details This hook is invoked in the system tick handler immediately * after processing the virtual timers queue. */ -#define CH_CFG_SYSTEM_TICK_HOOK() { \ - /* System tick event code here.*/ \ -} +#define CH_CFG_SYSTEM_TICK_HOOK() \ + { \ + /* System tick event code here.*/ \ + } /** * @brief System halt hook. * @details This hook is invoked in case to a system halting error before * the system is halted. */ -#define CH_CFG_SYSTEM_HALT_HOOK(reason) { \ - /* System halt code here.*/ \ -} +#define CH_CFG_SYSTEM_HALT_HOOK(reason) \ + { \ + /* System halt code here.*/ \ + } /** * @brief Trace hook. * @details This hook is invoked each time a new record is written in the * trace buffer. */ -#define CH_CFG_TRACE_HOOK(tep) { \ - /* Trace code here.*/ \ -} +#define CH_CFG_TRACE_HOOK(tep) \ + { \ + /* Trace code here.*/ \ + } /** * @brief Runtime Faults Collection Unit hook. * @details This hook is invoked each time new faults are collected and stored. */ -#define CH_CFG_RUNTIME_FAULTS_HOOK(mask) { \ - /* Faults handling code here.*/ \ -} +#define CH_CFG_RUNTIME_FAULTS_HOOK(mask) \ + { \ + /* Faults handling code here.*/ \ + } /** @} */ @@ -803,6 +814,6 @@ /* Port-specific settings (override port settings defaulted in chcore.h). */ /*===========================================================================*/ -#endif /* CHCONF_H */ +#endif /* CHCONF_H */ /** @} */ diff --git a/targets/ChibiOS/ST_STM32F429I_DISCOVERY/nanoBooter/halconf.h b/targets/ChibiOS/ST_STM32F429I_DISCOVERY/nanoBooter/halconf.h index 5e4c2b89a4..39141b7ec8 100644 --- a/targets/ChibiOS/ST_STM32F429I_DISCOVERY/nanoBooter/halconf.h +++ b/targets/ChibiOS/ST_STM32F429I_DISCOVERY/nanoBooter/halconf.h @@ -21,7 +21,7 @@ #define HALCONF_H #define _CHIBIOS_HAL_CONF_ -#define _CHIBIOS_HAL_CONF_VER_8_0_ +#define _CHIBIOS_HAL_CONF_VER_8_4_ #include "mcuconf.h" @@ -327,15 +327,18 @@ /*===========================================================================*/ /** - * @brief Delays insertions. - * @details If enabled this options inserts delays into the MMC waiting - * routines releasing some extra CPU time for the threads with - * lower priority, this may slow down the driver a bit however. - * This option is recommended also if the SPI driver does not - * use a DMA channel and heavily loads the CPU. + * @brief Timeout before assuming a failure while waiting for card idle. + * @note Time is in milliseconds. + */ +#if !defined(MMC_IDLE_TIMEOUT_MS) || defined(__DOXYGEN__) +#define MMC_IDLE_TIMEOUT_MS 1000 +#endif + +/** + * @brief Mutual exclusion on the SPI bus. */ -#if !defined(MMC_NICE_WAITING) || defined(__DOXYGEN__) -#define MMC_NICE_WAITING TRUE +#if !defined(MMC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define MMC_USE_MUTUAL_EXCLUSION TRUE #endif /*===========================================================================*/ @@ -393,7 +396,7 @@ * default configuration. */ #if !defined(SERIAL_DEFAULT_BITRATE) || defined(__DOXYGEN__) -#define SERIAL_DEFAULT_BITRATE 921600 +#define SERIAL_DEFAULT_BITRATE 38400 #endif /** @@ -439,7 +442,7 @@ * buffers. */ #if !defined(SERIAL_USB_BUFFERS_SIZE) || defined(__DOXYGEN__) -#define SERIAL_USB_BUFFERS_SIZE 64 +#define SERIAL_USB_BUFFERS_SIZE 256 #endif /** @@ -447,7 +450,7 @@ * @note The default is 2 buffers. */ #if !defined(SERIAL_USB_BUFFERS_NUMBER) || defined(__DOXYGEN__) -#define SERIAL_USB_BUFFERS_NUMBER 1 +#define SERIAL_USB_BUFFERS_NUMBER 2 #endif /*===========================================================================*/ diff --git a/targets/ChibiOS/ST_STM32F429I_DISCOVERY/nanoCLR/STM32F429xI_CLR-DEBUG.ld b/targets/ChibiOS/ST_STM32F429I_DISCOVERY/nanoCLR/STM32F429xI_CLR-DEBUG.ld index 7534f45841..5bde1fb9f1 100644 --- a/targets/ChibiOS/ST_STM32F429I_DISCOVERY/nanoCLR/STM32F429xI_CLR-DEBUG.ld +++ b/targets/ChibiOS/ST_STM32F429I_DISCOVERY/nanoCLR/STM32F429xI_CLR-DEBUG.ld @@ -32,6 +32,8 @@ MEMORY ram6 (wx) : org = 0x00000000, len = 0 ram7 (wx) : org = 0x00000000, len = 0 ext_ram (wx) : org = 0xD0000000, len = 8M /* external SDRAM */ + graphics_ram (wx) : org = 0xD0D00000, len = 2377728 /* external graphics ram for frame buffer and bitmaps*/ + graphics_vfb (wx) : org = 0xD0F44800, len = 153600 /* Frame buffer for video output mode 240*320*2 bytes ( 16 bits RGB565 )*/ bootclpbrd (wx) : org = 0x20000000, len = 48 /* boot clipboard area */ } @@ -82,6 +84,15 @@ REGION_ALIAS("HEAP_RAM", ram4); /* RAM region to be used for the nanoFramework CLR managed heap.*/ REGION_ALIAS("CLR_MANAGED_HEAP_RAM", ext_ram); +/* RAM region to be used for the nanoFramework graphics heap.*/ +REGION_ALIAS("GRAPHICS_HEAP_RAM", graphics_ram); + +/* RAM region to be used for the nanoFramework graphics heap.*/ +REGION_ALIAS("GRAPHICS_VIDEO_FRAME_BUFFER", graphics_vfb); + +/* Graphics rules inclusion.*/ +INCLUDE rules_graphics.ld + /* RAM region to be used for the boot clipboard.*/ REGION_ALIAS("SECTION_FOR_BOOTCLIPBOARD", bootclpbrd); diff --git a/targets/ChibiOS/ST_STM32F429I_DISCOVERY/nanoCLR/STM32F429xI_CLR.ld b/targets/ChibiOS/ST_STM32F429I_DISCOVERY/nanoCLR/STM32F429xI_CLR.ld index 7a145228f0..0141d7dd82 100644 --- a/targets/ChibiOS/ST_STM32F429I_DISCOVERY/nanoCLR/STM32F429xI_CLR.ld +++ b/targets/ChibiOS/ST_STM32F429I_DISCOVERY/nanoCLR/STM32F429xI_CLR.ld @@ -32,6 +32,8 @@ MEMORY ram6 (wx) : org = 0x00000000, len = 0 ram7 (wx) : org = 0x00000000, len = 0 ext_ram (wx) : org = 0xD0000000, len = 8M /* external SDRAM */ + graphics_ram (wx) : org = 0xD0D00000, len = 2377728 /* external graphics ram for frame buffer and bitmaps*/ + graphics_vfb (wx) : org = 0xD0F44800, len = 153600 /* Frame buffer for video output mode 240*320*2 bytes ( 16 bits RGB565 )*/ bootclpbrd (wx) : org = 0x20000000, len = 48 /* boot clipboard area */ } @@ -82,6 +84,15 @@ REGION_ALIAS("HEAP_RAM", ram4); /* RAM region to be used for the nanoFramework CLR managed heap.*/ REGION_ALIAS("CLR_MANAGED_HEAP_RAM", ext_ram); +/* RAM region to be used for the nanoFramework graphics heap.*/ +REGION_ALIAS("GRAPHICS_HEAP_RAM", graphics_ram); + +/* RAM region to be used for the nanoFramework graphics heap.*/ +REGION_ALIAS("GRAPHICS_VIDEO_FRAME_BUFFER", graphics_vfb); + +/* Graphics rules inclusion.*/ +INCLUDE rules_graphics.ld + /* RAM region to be used for the boot clipboard.*/ REGION_ALIAS("SECTION_FOR_BOOTCLIPBOARD", bootclpbrd); diff --git a/targets/ChibiOS/ST_STM32F429I_DISCOVERY/nanoCLR/chconf.h b/targets/ChibiOS/ST_STM32F429I_DISCOVERY/nanoCLR/chconf.h index d1e23c9050..c559f9a8b8 100644 --- a/targets/ChibiOS/ST_STM32F429I_DISCOVERY/nanoCLR/chconf.h +++ b/targets/ChibiOS/ST_STM32F429I_DISCOVERY/nanoCLR/chconf.h @@ -36,7 +36,7 @@ * direct interactions are handled by the OS. */ #if !defined(CH_CFG_SMP_MODE) -#define CH_CFG_SMP_MODE FALSE +#define CH_CFG_SMP_MODE FALSE #endif /** @} */ @@ -53,7 +53,7 @@ * @note Allowed values are 16, 32 or 64 bits. */ #if !defined(CH_CFG_ST_RESOLUTION) -#define CH_CFG_ST_RESOLUTION 32 +#define CH_CFG_ST_RESOLUTION 32 #endif /** @@ -62,7 +62,7 @@ * setting also defines the system tick time unit. */ #if !defined(CH_CFG_ST_FREQUENCY) -#define CH_CFG_ST_FREQUENCY 1000 // this is 1 millisecond +#define CH_CFG_ST_FREQUENCY 1000 // this is 1 millisecond #endif /** @@ -70,7 +70,7 @@ * @note Allowed values are 16, 32 or 64 bits. */ #if !defined(CH_CFG_INTERVALS_SIZE) -#define CH_CFG_INTERVALS_SIZE 32 +#define CH_CFG_INTERVALS_SIZE 32 #endif /** @@ -78,7 +78,7 @@ * @note Allowed values are 16 or 32 bits. */ #if !defined(CH_CFG_TIME_TYPES_SIZE) -#define CH_CFG_TIME_TYPES_SIZE 32 +#define CH_CFG_TIME_TYPES_SIZE 32 #endif /** @@ -90,7 +90,7 @@ * this value. */ #if !defined(CH_CFG_ST_TIMEDELTA) -#define CH_CFG_ST_TIMEDELTA 2 +#define CH_CFG_ST_TIMEDELTA 2 #endif /** @} */ @@ -115,7 +115,7 @@ * must be set to zero in that case. */ #if !defined(CH_CFG_TIME_QUANTUM) -#define CH_CFG_TIME_QUANTUM 0 +#define CH_CFG_TIME_QUANTUM 0 #endif /** @@ -126,7 +126,7 @@ * infinite loop. */ #if !defined(CH_CFG_NO_IDLE_THREAD) -#define CH_CFG_NO_IDLE_THREAD FALSE +#define CH_CFG_NO_IDLE_THREAD FALSE #endif /** @} */ @@ -147,7 +147,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_OPTIMIZE_SPEED) -#define CH_CFG_OPTIMIZE_SPEED TRUE +#define CH_CFG_OPTIMIZE_SPEED TRUE #endif /** @} */ @@ -167,7 +167,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_TM) -#define CH_CFG_USE_TM FALSE +#define CH_CFG_USE_TM FALSE #endif /** @@ -178,7 +178,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_TIMESTAMP) -#define CH_CFG_USE_TIMESTAMP FALSE +#define CH_CFG_USE_TIMESTAMP TRUE #endif /** @@ -188,7 +188,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_REGISTRY) -#define CH_CFG_USE_REGISTRY TRUE +#define CH_CFG_USE_REGISTRY TRUE #endif /** @@ -199,7 +199,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_WAITEXIT) -#define CH_CFG_USE_WAITEXIT TRUE +#define CH_CFG_USE_WAITEXIT TRUE #endif /** @@ -209,7 +209,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_SEMAPHORES) -#define CH_CFG_USE_SEMAPHORES TRUE +#define CH_CFG_USE_SEMAPHORES TRUE #endif /** @@ -222,7 +222,7 @@ * @note Requires @p CH_CFG_USE_SEMAPHORES. */ #if !defined(CH_CFG_USE_SEMAPHORES_PRIORITY) -#define CH_CFG_USE_SEMAPHORES_PRIORITY FALSE +#define CH_CFG_USE_SEMAPHORES_PRIORITY FALSE #endif /** @@ -232,7 +232,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_MUTEXES) -#define CH_CFG_USE_MUTEXES TRUE +#define CH_CFG_USE_MUTEXES TRUE #endif /** @@ -244,7 +244,7 @@ * @note Requires @p CH_CFG_USE_MUTEXES. */ #if !defined(CH_CFG_USE_MUTEXES_RECURSIVE) -#define CH_CFG_USE_MUTEXES_RECURSIVE FALSE +#define CH_CFG_USE_MUTEXES_RECURSIVE FALSE #endif /** @@ -256,7 +256,7 @@ * @note Requires @p CH_CFG_USE_MUTEXES. */ #if !defined(CH_CFG_USE_CONDVARS) -#define CH_CFG_USE_CONDVARS TRUE +#define CH_CFG_USE_CONDVARS TRUE #endif /** @@ -268,7 +268,7 @@ * @note Requires @p CH_CFG_USE_CONDVARS. */ #if !defined(CH_CFG_USE_CONDVARS_TIMEOUT) -#define CH_CFG_USE_CONDVARS_TIMEOUT TRUE +#define CH_CFG_USE_CONDVARS_TIMEOUT TRUE #endif /** @@ -278,7 +278,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_EVENTS) -#define CH_CFG_USE_EVENTS TRUE +#define CH_CFG_USE_EVENTS TRUE #endif /** @@ -290,7 +290,7 @@ * @note Requires @p CH_CFG_USE_EVENTS. */ #if !defined(CH_CFG_USE_EVENTS_TIMEOUT) -#define CH_CFG_USE_EVENTS_TIMEOUT TRUE +#define CH_CFG_USE_EVENTS_TIMEOUT TRUE #endif /** @@ -301,7 +301,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_MESSAGES) -#define CH_CFG_USE_MESSAGES TRUE +#define CH_CFG_USE_MESSAGES TRUE #endif /** @@ -314,7 +314,7 @@ * @note Requires @p CH_CFG_USE_MESSAGES. */ #if !defined(CH_CFG_USE_MESSAGES_PRIORITY) -#define CH_CFG_USE_MESSAGES_PRIORITY FALSE +#define CH_CFG_USE_MESSAGES_PRIORITY FALSE #endif /** @@ -327,7 +327,7 @@ * @note Requires @p CH_CFG_USE_HEAP and/or @p CH_CFG_USE_MEMPOOLS. */ #if !defined(CH_CFG_USE_DYNAMIC) -#define CH_CFG_USE_DYNAMIC TRUE +#define CH_CFG_USE_DYNAMIC TRUE #endif /** @} */ @@ -348,7 +348,7 @@ * @note Requires @p CH_CFG_USE_SEMAPHORES. */ #if !defined(CH_CFG_USE_MAILBOXES) -#define CH_CFG_USE_MAILBOXES TRUE +#define CH_CFG_USE_MAILBOXES TRUE #endif /** @@ -359,7 +359,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_MEMCORE) -#define CH_CFG_USE_MEMCORE TRUE +#define CH_CFG_USE_MEMCORE TRUE #endif /** @@ -374,7 +374,7 @@ * @note Requires @p CH_CFG_USE_MEMCORE. */ #if !defined(CH_CFG_MEMCORE_SIZE) -#define CH_CFG_MEMCORE_SIZE 0 +#define CH_CFG_MEMCORE_SIZE 0 #endif /** @@ -388,7 +388,7 @@ * @note Mutexes are recommended. */ #if !defined(CH_CFG_USE_HEAP) -#define CH_CFG_USE_HEAP TRUE +#define CH_CFG_USE_HEAP TRUE #endif /** @@ -399,7 +399,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_MEMPOOLS) -#define CH_CFG_USE_MEMPOOLS TRUE +#define CH_CFG_USE_MEMPOOLS TRUE #endif /** @@ -410,7 +410,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_OBJ_FIFOS) -#define CH_CFG_USE_OBJ_FIFOS TRUE +#define CH_CFG_USE_OBJ_FIFOS TRUE #endif /** @@ -421,7 +421,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_PIPES) -#define CH_CFG_USE_PIPES TRUE +#define CH_CFG_USE_PIPES TRUE #endif /** @@ -432,7 +432,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_OBJ_CACHES) -#define CH_CFG_USE_OBJ_CACHES FALSE +#define CH_CFG_USE_OBJ_CACHES FALSE #endif /** @@ -443,7 +443,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_DELEGATES) -#define CH_CFG_USE_DELEGATES FALSE +#define CH_CFG_USE_DELEGATES FALSE #endif /** @@ -454,7 +454,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_JOBS) -#define CH_CFG_USE_JOBS FALSE +#define CH_CFG_USE_JOBS FALSE #endif /** @} */ @@ -474,7 +474,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_CFG_USE_FACTORY) -#define CH_CFG_USE_FACTORY FALSE +#define CH_CFG_USE_FACTORY FALSE #endif /** @@ -483,49 +483,49 @@ * pointer but this could have unintended side effects. */ #if !defined(CH_CFG_FACTORY_MAX_NAMES_LENGTH) -#define CH_CFG_FACTORY_MAX_NAMES_LENGTH 8 +#define CH_CFG_FACTORY_MAX_NAMES_LENGTH 8 #endif /** * @brief Enables the registry of generic objects. */ #if !defined(CH_CFG_FACTORY_OBJECTS_REGISTRY) -#define CH_CFG_FACTORY_OBJECTS_REGISTRY TRUE +#define CH_CFG_FACTORY_OBJECTS_REGISTRY TRUE #endif /** * @brief Enables factory for generic buffers. */ #if !defined(CH_CFG_FACTORY_GENERIC_BUFFERS) -#define CH_CFG_FACTORY_GENERIC_BUFFERS TRUE +#define CH_CFG_FACTORY_GENERIC_BUFFERS TRUE #endif /** * @brief Enables factory for semaphores. */ #if !defined(CH_CFG_FACTORY_SEMAPHORES) -#define CH_CFG_FACTORY_SEMAPHORES TRUE +#define CH_CFG_FACTORY_SEMAPHORES TRUE #endif /** * @brief Enables factory for mailboxes. */ #if !defined(CH_CFG_FACTORY_MAILBOXES) -#define CH_CFG_FACTORY_MAILBOXES TRUE +#define CH_CFG_FACTORY_MAILBOXES TRUE #endif /** * @brief Enables factory for objects FIFOs. */ #if !defined(CH_CFG_FACTORY_OBJ_FIFOS) -#define CH_CFG_FACTORY_OBJ_FIFOS TRUE +#define CH_CFG_FACTORY_OBJ_FIFOS TRUE #endif /** * @brief Enables factory for Pipes. */ #if !defined(CH_CFG_FACTORY_PIPES) || defined(__DOXYGEN__) -#define CH_CFG_FACTORY_PIPES TRUE +#define CH_CFG_FACTORY_PIPES TRUE #endif /** @} */ @@ -543,7 +543,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_STATISTICS) -#define CH_DBG_STATISTICS FALSE +#define CH_DBG_STATISTICS FALSE #endif /** @@ -554,7 +554,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_SYSTEM_STATE_CHECK) -#define CH_DBG_SYSTEM_STATE_CHECK FALSE +#define CH_DBG_SYSTEM_STATE_CHECK FALSE #endif /** @@ -565,7 +565,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_ENABLE_CHECKS) -#define CH_DBG_ENABLE_CHECKS FALSE +#define CH_DBG_ENABLE_CHECKS FALSE #endif /** @@ -577,7 +577,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_ENABLE_ASSERTS) -#define CH_DBG_ENABLE_ASSERTS FALSE +#define CH_DBG_ENABLE_ASSERTS FALSE #endif /** @@ -587,7 +587,7 @@ * @note The default is @p CH_DBG_TRACE_MASK_DISABLED. */ #if !defined(CH_DBG_TRACE_MASK) -#define CH_DBG_TRACE_MASK CH_DBG_TRACE_MASK_DISABLED +#define CH_DBG_TRACE_MASK CH_DBG_TRACE_MASK_DISABLED #endif /** @@ -596,7 +596,7 @@ * different from @p CH_DBG_TRACE_MASK_DISABLED. */ #if !defined(CH_DBG_TRACE_BUFFER_SIZE) -#define CH_DBG_TRACE_BUFFER_SIZE 128 +#define CH_DBG_TRACE_BUFFER_SIZE 128 #endif /** @@ -610,7 +610,7 @@ * @p panic_msg variable set to @p NULL. */ #if !defined(CH_DBG_ENABLE_STACK_CHECK) -#define CH_DBG_ENABLE_STACK_CHECK FALSE +#define CH_DBG_ENABLE_STACK_CHECK FALSE #endif /** @@ -622,7 +622,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_FILL_THREADS) -#define CH_DBG_FILL_THREADS FALSE +#define CH_DBG_FILL_THREADS FALSE #endif /** @@ -635,7 +635,7 @@ * tickless mode. */ #if !defined(CH_DBG_THREADS_PROFILING) -#define CH_DBG_THREADS_PROFILING FALSE +#define CH_DBG_THREADS_PROFILING FALSE #endif /** @} */ @@ -651,40 +651,39 @@ * @brief System structure extension. * @details User fields added to the end of the @p ch_system_t structure. */ -#define CH_CFG_SYSTEM_EXTRA_FIELDS \ - /* Add system custom fields here.*/ +#define CH_CFG_SYSTEM_EXTRA_FIELDS /* Add system custom fields here.*/ /** * @brief System initialization hook. * @details User initialization code added to the @p chSysInit() function * just before interrupts are enabled globally. */ -#define CH_CFG_SYSTEM_INIT_HOOK() { \ - /* Add system initialization code here.*/ \ -} +#define CH_CFG_SYSTEM_INIT_HOOK() \ + { \ + /* Add system initialization code here.*/ \ + } /** * @brief OS instance structure extension. * @details User fields added to the end of the @p os_instance_t structure. */ -#define CH_CFG_OS_INSTANCE_EXTRA_FIELDS \ - /* Add OS instance custom fields here.*/ +#define CH_CFG_OS_INSTANCE_EXTRA_FIELDS /* Add OS instance custom fields here.*/ /** * @brief OS instance initialization hook. * * @param[in] oip pointer to the @p os_instance_t structure */ -#define CH_CFG_OS_INSTANCE_INIT_HOOK(oip) { \ - /* Add OS instance initialization code here.*/ \ -} +#define CH_CFG_OS_INSTANCE_INIT_HOOK(oip) \ + { \ + /* Add OS instance initialization code here.*/ \ + } /** * @brief Threads descriptor structure extension. * @details User fields added to the end of the @p thread_t structure. */ -#define CH_CFG_THREAD_EXTRA_FIELDS \ - /* Add threads custom fields here.*/ +#define CH_CFG_THREAD_EXTRA_FIELDS /* Add threads custom fields here.*/ /** * @brief Threads initialization hook. @@ -695,9 +694,10 @@ * * @param[in] tp pointer to the @p thread_t structure */ -#define CH_CFG_THREAD_INIT_HOOK(tp) { \ - /* Add threads initialization code here.*/ \ -} +#define CH_CFG_THREAD_INIT_HOOK(tp) \ + { \ + /* Add threads initialization code here.*/ \ + } /** * @brief Threads finalization hook. @@ -705,9 +705,10 @@ * * @param[in] tp pointer to the @p thread_t structure */ -#define CH_CFG_THREAD_EXIT_HOOK(tp) { \ - /* Add threads finalization code here.*/ \ -} +#define CH_CFG_THREAD_EXIT_HOOK(tp) \ + { \ + /* Add threads finalization code here.*/ \ + } /** * @brief Context switch hook. @@ -716,23 +717,26 @@ * @param[in] ntp thread being switched in * @param[in] otp thread being switched out */ -#define CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) { \ - /* Context switch code here.*/ \ -} +#define CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) \ + { \ + /* Context switch code here.*/ \ + } /** * @brief ISR enter hook. */ -#define CH_CFG_IRQ_PROLOGUE_HOOK() { \ - /* IRQ prologue code here.*/ \ -} +#define CH_CFG_IRQ_PROLOGUE_HOOK() \ + { \ + /* IRQ prologue code here.*/ \ + } /** * @brief ISR exit hook. */ -#define CH_CFG_IRQ_EPILOGUE_HOOK() { \ - /* IRQ epilogue code here.*/ \ -} +#define CH_CFG_IRQ_EPILOGUE_HOOK() \ + { \ + /* IRQ epilogue code here.*/ \ + } /** * @brief Idle thread enter hook. @@ -740,9 +744,10 @@ * should be invoked from here. * @note This macro can be used to activate a power saving mode. */ -#define CH_CFG_IDLE_ENTER_HOOK() { \ - /* Idle-enter code here.*/ \ -} +#define CH_CFG_IDLE_ENTER_HOOK() \ + { \ + /* Idle-enter code here.*/ \ + } /** * @brief Idle thread leave hook. @@ -750,52 +755,58 @@ * should be invoked from here. * @note This macro can be used to deactivate a power saving mode. */ -#define CH_CFG_IDLE_LEAVE_HOOK() { \ - /* Idle-leave code here.*/ \ -} +#define CH_CFG_IDLE_LEAVE_HOOK() \ + { \ + /* Idle-leave code here.*/ \ + } /** * @brief Idle Loop hook. * @details This hook is continuously invoked by the idle thread loop. */ -#define CH_CFG_IDLE_LOOP_HOOK() { \ - /* Idle loop code here.*/ \ -} +#define CH_CFG_IDLE_LOOP_HOOK() \ + { \ + /* Idle loop code here.*/ \ + } /** * @brief System tick event hook. * @details This hook is invoked in the system tick handler immediately * after processing the virtual timers queue. */ -#define CH_CFG_SYSTEM_TICK_HOOK() { \ - /* System tick event code here.*/ \ -} +#define CH_CFG_SYSTEM_TICK_HOOK() \ + { \ + /* System tick event code here.*/ \ + } /** * @brief System halt hook. * @details This hook is invoked in case to a system halting error before * the system is halted. */ -#define CH_CFG_SYSTEM_HALT_HOOK(reason) { \ - /* System halt code here.*/ \ -} +#define CH_CFG_SYSTEM_HALT_HOOK(reason) \ + { \ + /* System halt code here.*/ \ + } /** * @brief Trace hook. * @details This hook is invoked each time a new record is written in the * trace buffer. */ -#define CH_CFG_TRACE_HOOK(tep) { \ - /* Trace code here.*/ \ -} +#define CH_CFG_TRACE_HOOK(tep) \ + { \ + /* Trace code here.*/ \ + } /** * @brief Runtime Faults Collection Unit hook. * @details This hook is invoked each time new faults are collected and stored. */ -#define CH_CFG_RUNTIME_FAULTS_HOOK(mask) { \ - /* Faults handling code here.*/ \ -} +#define CH_CFG_RUNTIME_FAULTS_HOOK(mask) \ + { \ + /* Faults handling code here.*/ \ + } /** @} */ @@ -803,6 +814,6 @@ /* Port-specific settings (override port settings defaulted in chcore.h). */ /*===========================================================================*/ -#endif /* CHCONF_H */ +#endif /* CHCONF_H */ /** @} */ diff --git a/targets/ChibiOS/ST_STM32F429I_DISCOVERY/nanoCLR/halconf.h b/targets/ChibiOS/ST_STM32F429I_DISCOVERY/nanoCLR/halconf.h index 53143f76fc..519648fb1d 100644 --- a/targets/ChibiOS/ST_STM32F429I_DISCOVERY/nanoCLR/halconf.h +++ b/targets/ChibiOS/ST_STM32F429I_DISCOVERY/nanoCLR/halconf.h @@ -21,7 +21,7 @@ #define HALCONF_H #define _CHIBIOS_HAL_CONF_ -#define _CHIBIOS_HAL_CONF_VER_8_0_ +#define _CHIBIOS_HAL_CONF_VER_8_4_ #include #include "mcuconf.h" @@ -339,15 +339,18 @@ /*===========================================================================*/ /** - * @brief Delays insertions. - * @details If enabled this options inserts delays into the MMC waiting - * routines releasing some extra CPU time for the threads with - * lower priority, this may slow down the driver a bit however. - * This option is recommended also if the SPI driver does not - * use a DMA channel and heavily loads the CPU. + * @brief Timeout before assuming a failure while waiting for card idle. + * @note Time is in milliseconds. + */ +#if !defined(MMC_IDLE_TIMEOUT_MS) || defined(__DOXYGEN__) +#define MMC_IDLE_TIMEOUT_MS 1000 +#endif + +/** + * @brief Mutual exclusion on the SPI bus. */ -#if !defined(MMC_NICE_WAITING) || defined(__DOXYGEN__) -#define MMC_NICE_WAITING TRUE +#if !defined(MMC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define MMC_USE_MUTUAL_EXCLUSION TRUE #endif /*===========================================================================*/ diff --git a/targets/ChibiOS/ST_STM32F429I_DISCOVERY/nanoCLR/halconf_nf.h b/targets/ChibiOS/ST_STM32F429I_DISCOVERY/nanoCLR/halconf_nf.h index f83199d6bf..b0acfd6096 100644 --- a/targets/ChibiOS/ST_STM32F429I_DISCOVERY/nanoCLR/halconf_nf.h +++ b/targets/ChibiOS/ST_STM32F429I_DISCOVERY/nanoCLR/halconf_nf.h @@ -7,13 +7,17 @@ #define HALCONF_NF_H // enables STM32 Flash driver -#if !defined(HAL_NF_USE_STM32_FLASH) -#define HAL_NF_USE_STM32_FLASH TRUE +#if !defined(HAL_NF_USE_STM32_FLASH) +#define HAL_NF_USE_STM32_FLASH TRUE #endif // Enables the FSMC subsystem. #if !defined(HAL_NF_USE_FSMC) -#define HAL_NF_USE_FSMC TRUE +#define HAL_NF_USE_FSMC TRUE +#endif + +#if !defined(HAL_LTDC_MODULE_ENABLED) +#define HAL_LTDC_MODULE_ENABLED TRUE #endif #endif // HALCONF_NF_H diff --git a/targets/ChibiOS/ST_STM32F429I_DISCOVERY/nanoCLR/nanoFramework.Graphics/Graphics_Memory.cpp b/targets/ChibiOS/ST_STM32F429I_DISCOVERY/nanoCLR/nanoFramework.Graphics/Graphics_Memory.cpp new file mode 100644 index 0000000000..6f55a67548 --- /dev/null +++ b/targets/ChibiOS/ST_STM32F429I_DISCOVERY/nanoCLR/nanoFramework.Graphics/Graphics_Memory.cpp @@ -0,0 +1,26 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#ifndef GRAPHICS_MEMORY_SETUP_ +#define GRAPHICS_MEMORY_SETUP_ + +#include "nanoCLR_Types.h" +#include "GraphicsMemoryHeap.h" + +struct GraphicsMemory g_GraphicsMemory; + +extern CLR_UINT32 GraphicsHeapBegin; +extern CLR_UINT32 GraphicsHeapEnd; +bool GraphicsMemory::GraphicsHeapLocation( + CLR_UINT32 requested, + CLR_UINT8 *&graphicsStartingAddress, + CLR_UINT8 *&graphicsEndingAddress) +{ + (void)requested; + graphicsStartingAddress = (CLR_UINT8 *)&GraphicsHeapBegin; + graphicsEndingAddress = (CLR_UINT8 *)&GraphicsHeapEnd; + return true; +} +#endif // GRAPHICS_MEMORY_SETUP diff --git a/targets/ChibiOS/ST_STM32F429I_DISCOVERY/nanoCLR/nanoFramework.Graphics/I2C_To_TouchPanel.cpp b/targets/ChibiOS/ST_STM32F429I_DISCOVERY/nanoCLR/nanoFramework.Graphics/I2C_To_TouchPanel.cpp new file mode 100644 index 0000000000..f2142e09ed --- /dev/null +++ b/targets/ChibiOS/ST_STM32F429I_DISCOVERY/nanoCLR/nanoFramework.Graphics/I2C_To_TouchPanel.cpp @@ -0,0 +1,50 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#ifndef I2C_TO_TOUCHPANEL_H +#define I2C_TO_TOUCHPANEL_H + +#include +#include +#include +#include + +// This code module is written for a STM32F429I DISCOVERY board with display 240x320 TFT and touch screen +// The touch screen driver IC is a STMPE811QTR +#define STMPE811QTR_I2C_Address 0x41 + +extern I2CDriver touchDriver; +static CLR_UINT16 I2C_Address; + +bool TouchInterface::Initialize() +{ + // The FT6206 is connected to I2C4 of the STM32F769. + // This is already configured by the chibios system in the file + // mcuconf.h + + // #define STM32_I2C_USE_I2C4 TRUE + + I2C_Address = STMPE811QTR_I2C_Address; + + return true; +} +CLR_UINT8 *TouchInterface::Write_Read( + CLR_UINT8 *valuesToSend, + CLR_UINT16 numberOfValuesToSend, + CLR_UINT16 numberValuesExpected) +{ + // TO BE DEVELOPED + (void)valuesToSend; + (void)numberOfValuesToSend; + (void)numberValuesExpected; + + // CLR_UINT8* receivedValues = NULL; + // msg_t result = i2cMasterTransmitTimeout(&touchDriver, I2C_Address, valuesToSend, numberOfValuesToSend, + // receivedValues, numberValuesExpected, TIME_MS2I(20)); return receivedValues; + + return 0U; +} + +#endif // I2C_TO_TOUCHPANEL_H diff --git a/targets/ChibiOS/ST_STM32F429I_DISCOVERY/nanoCLR/nanoFramework.Graphics/Spi_To_TouchPanel.cpp b/targets/ChibiOS/ST_STM32F429I_DISCOVERY/nanoCLR/nanoFramework.Graphics/Spi_To_TouchPanel.cpp new file mode 100644 index 0000000000..c497b5b503 --- /dev/null +++ b/targets/ChibiOS/ST_STM32F429I_DISCOVERY/nanoCLR/nanoFramework.Graphics/Spi_To_TouchPanel.cpp @@ -0,0 +1,34 @@ +// +// Copyright (c) 2017 The nanoFramework project contributors +// See LICENSE file in the project root for full license information. +// + +#ifndef SPI_TO_TOUCHPANEL_H +#define SPI_TO_TOUCHPANEL_H + +#include +#include +#include +#include + +bool TouchInterface::Initialize() +{ + // Setup SPI configuration + + return true; +} + +CLR_UINT8 *TouchInterface::Write_Read( + CLR_UINT8 *valuesToSend, + CLR_UINT16 numberOfValuesToSend, + CLR_UINT16 numberValuesExpected) +{ + + (void)valuesToSend; + (void)numberOfValuesToSend; + (void)numberValuesExpected; + + return 0; +} + +#endif // SPI_TO_TOUCHPANEL_H diff --git a/targets/ChibiOS/ST_STM32F429I_DISCOVERY/target_system_device_pwm_config.cpp b/targets/ChibiOS/ST_STM32F429I_DISCOVERY/target_system_device_pwm_config.cpp new file mode 100644 index 0000000000..73cc6666d3 --- /dev/null +++ b/targets/ChibiOS/ST_STM32F429I_DISCOVERY/target_system_device_pwm_config.cpp @@ -0,0 +1,9 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS BLANK ON PURPOSE BECAUSE THIS TARGET DOESN'T REQUIRE THIS SPECIFIC CONFIGURATION // +/////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/targets/ChibiOS/ST_STM32F769I_DISCOVERY/CMakePresets.json b/targets/ChibiOS/ST_STM32F769I_DISCOVERY/CMakePresets.json new file mode 100644 index 0000000000..a3f035e6d0 --- /dev/null +++ b/targets/ChibiOS/ST_STM32F769I_DISCOVERY/CMakePresets.json @@ -0,0 +1,63 @@ +{ + "version": 4, + "include": [ + "../../../CMake/arm-gcc.json", + "../../../config/user-tools-repos.json", + "../../../config/user-prefs.json" + ], + "configurePresets": [ + { + "name": "ST_STM32F769I_DISCOVERY", + "inherits": [ + "arm-gcc-cortex-preset", + "user-tools-repos", + "user-prefs" + ], + "hidden": false, + "cacheVariables": { + "TARGET_BOARD": "${presetName}", + "RTOS": "ChibiOS", + "TARGET_SERIES": "STM32F7xx", + "CHIBIOS_CONTRIB_REQUIRED": "OFF", + "STM32_CUBE_PACKAGE_REQUIRED": "OFF", + "SUPPORT_ANY_BASE_CONVERSION": "ON", + "NF_FEATURE_DEBUGGER": "ON", + "NF_FEATURE_RTC": "ON", + "NF_FEATURE_HAS_SDCARD": "ON", + "NF_FEATURE_HAS_CONFIG_BLOCK": "ON", + "SWO_OUTPUT": "OFF", + "NF_BUILD_RTM": "OFF", + "API_System.Math": "ON", + "API_Hardware.Stm32": "ON", + "API_System.Device.Gpio": "ON", + "API_System.Device.Spi": "ON", + "API_System.Device.I2c": "ON", + "API_System.Device.Pwm": "ON", + "API_System.IO.Ports": "ON", + "API_System.Device.Adc": "ON", + "API_System.Device.Dac": "ON", + "API_System.Net": "ON", + "API_nanoFramework.Device.OneWire": "ON", + "API_nanoFramework.Device.Can": "ON", + "API_nanoFramework.ResourceManager": "ON", + "API_nanoFramework.System.Collections": "ON", + "API_nanoFramework.System.Text": "ON", + "API_Windows.Storage": "ON", + "API_nanoFramework.Graphics": "ON", + "GRAPHICS_MEMORY": "Graphics_Memory.cpp", + "GRAPHICS_DISPLAY": "Otm8009a_DSI_Video_Mode.cpp", + "GRAPHICS_DISPLAY_INTERFACE": "DSI_To_Display_Video_Mode.cpp", + "TOUCHPANEL_DEVICE": "ft6x06_I2C.cpp", + "TOUCHPANEL_INTERFACE": "I2C_To_TouchPanel.cpp" + } + } + ], + "buildPresets": [ + { + "inherits": "base-user", + "name": "ST_STM32F769I_DISCOVERY", + "displayName": "ST_STM32F769I_DISCOVERY", + "configurePreset": "ST_STM32F769I_DISCOVERY" + } + ] +} diff --git a/targets/ChibiOS/ST_STM32F769I_DISCOVERY/README.md b/targets/ChibiOS/ST_STM32F769I_DISCOVERY/README.md index f39844f135..5e6f15e70d 100644 --- a/targets/ChibiOS/ST_STM32F769I_DISCOVERY/README.md +++ b/targets/ChibiOS/ST_STM32F769I_DISCOVERY/README.md @@ -11,7 +11,7 @@ In _halconf.g_ (in both nanoBooter and nanoCLR folders), when compared with a de In _mcuconf.h_ (in both nanoBooter and nanoCLR folders), when compared with a default file available from (https://github.com/ChibiOS/ChibiOS/tree/master/demos/STM32/RT-STM32F769I-DISCOVERY): - STM32_SERIAL_USE_USART1 to TRUE -NOTE: this configuration was successfully tested in an ST_STM32F769I_DISCOVERY board using the Serial port through the onboard 7ST Link USB connection. +NOTE: this configuration was successfully tested in an ST_STM32F769I_DISCOVERY board using the Serial port through the onboard ST Link USB connection. ## ADC configurations diff --git a/targets/ChibiOS/ST_STM32F769I_DISCOVERY/common/Device_BlockStorage-DEBUG.c b/targets/ChibiOS/ST_STM32F769I_DISCOVERY/common/Device_BlockStorage-DEBUG.c index 0ff4f316ec..05c8653805 100644 --- a/targets/ChibiOS/ST_STM32F769I_DISCOVERY/common/Device_BlockStorage-DEBUG.c +++ b/targets/ChibiOS/ST_STM32F769I_DISCOVERY/common/Device_BlockStorage-DEBUG.c @@ -31,8 +31,8 @@ const BlockRange BlockRange2[] = // 256kB blocks const BlockRange BlockRange3[] = { - { BlockRange_BLOCKTYPE_CODE , 0, 1 }, // 08040000 nanoCLR - { BlockRange_BLOCKTYPE_DEPLOYMENT, 2, 6 } // 080C0000 deployment + { BlockRange_BLOCKTYPE_CODE , 0, 2 }, // 08040000 nanoCLR + { BlockRange_BLOCKTYPE_DEPLOYMENT, 3, 6 } // 08100000 deployment }; const BlockRegionInfo BlockRegions[] = diff --git a/targets/ChibiOS/ST_STM32F769I_DISCOVERY/mbedtls_config.h b/targets/ChibiOS/ST_STM32F769I_DISCOVERY/mbedtls_config.h index 6cf360ae36..f70dd41e40 100644 --- a/targets/ChibiOS/ST_STM32F769I_DISCOVERY/mbedtls_config.h +++ b/targets/ChibiOS/ST_STM32F769I_DISCOVERY/mbedtls_config.h @@ -37,7 +37,7 @@ // uncomment the defines bellow to generate debug output // set below the threshold level for debug messages -// check mbed TLS mbedtls/debug.h header for details. +// check Mbed TLS mbedtls/debug.h header for details. // Debug levels: // 0 No debug // 1 Error diff --git a/targets/ChibiOS/ST_STM32F769I_DISCOVERY/nanoBooter/chconf.h b/targets/ChibiOS/ST_STM32F769I_DISCOVERY/nanoBooter/chconf.h index 67e6f1156d..d24abc78a9 100644 --- a/targets/ChibiOS/ST_STM32F769I_DISCOVERY/nanoBooter/chconf.h +++ b/targets/ChibiOS/ST_STM32F769I_DISCOVERY/nanoBooter/chconf.h @@ -36,7 +36,7 @@ * direct interactions are handled by the OS. */ #if !defined(CH_CFG_SMP_MODE) -#define CH_CFG_SMP_MODE FALSE +#define CH_CFG_SMP_MODE FALSE #endif /** @} */ @@ -53,7 +53,7 @@ * @note Allowed values are 16, 32 or 64 bits. */ #if !defined(CH_CFG_ST_RESOLUTION) -#define CH_CFG_ST_RESOLUTION 32 +#define CH_CFG_ST_RESOLUTION 32 #endif /** @@ -62,7 +62,7 @@ * setting also defines the system tick time unit. */ #if !defined(CH_CFG_ST_FREQUENCY) -#define CH_CFG_ST_FREQUENCY 10000 +#define CH_CFG_ST_FREQUENCY 10000 #endif /** @@ -70,7 +70,7 @@ * @note Allowed values are 16, 32 or 64 bits. */ #if !defined(CH_CFG_INTERVALS_SIZE) -#define CH_CFG_INTERVALS_SIZE 32 +#define CH_CFG_INTERVALS_SIZE 32 #endif /** @@ -78,7 +78,7 @@ * @note Allowed values are 16 or 32 bits. */ #if !defined(CH_CFG_TIME_TYPES_SIZE) -#define CH_CFG_TIME_TYPES_SIZE 32 +#define CH_CFG_TIME_TYPES_SIZE 32 #endif /** @@ -90,7 +90,7 @@ * this value. */ #if !defined(CH_CFG_ST_TIMEDELTA) -#define CH_CFG_ST_TIMEDELTA 2 +#define CH_CFG_ST_TIMEDELTA 2 #endif /** @} */ @@ -115,7 +115,7 @@ * must be set to zero in that case. */ #if !defined(CH_CFG_TIME_QUANTUM) -#define CH_CFG_TIME_QUANTUM 0 +#define CH_CFG_TIME_QUANTUM 0 #endif /** @@ -126,7 +126,7 @@ * infinite loop. */ #if !defined(CH_CFG_NO_IDLE_THREAD) -#define CH_CFG_NO_IDLE_THREAD FALSE +#define CH_CFG_NO_IDLE_THREAD FALSE #endif /** @} */ @@ -147,7 +147,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_OPTIMIZE_SPEED) -#define CH_CFG_OPTIMIZE_SPEED TRUE +#define CH_CFG_OPTIMIZE_SPEED TRUE #endif /** @} */ @@ -167,7 +167,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_TM) -#define CH_CFG_USE_TM FALSE +#define CH_CFG_USE_TM FALSE #endif /** @@ -178,7 +178,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_TIMESTAMP) -#define CH_CFG_USE_TIMESTAMP FALSE +#define CH_CFG_USE_TIMESTAMP TRUE #endif /** @@ -188,7 +188,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_REGISTRY) -#define CH_CFG_USE_REGISTRY TRUE +#define CH_CFG_USE_REGISTRY TRUE #endif /** @@ -199,7 +199,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_WAITEXIT) -#define CH_CFG_USE_WAITEXIT TRUE +#define CH_CFG_USE_WAITEXIT TRUE #endif /** @@ -209,7 +209,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_SEMAPHORES) -#define CH_CFG_USE_SEMAPHORES TRUE +#define CH_CFG_USE_SEMAPHORES TRUE #endif /** @@ -222,7 +222,7 @@ * @note Requires @p CH_CFG_USE_SEMAPHORES. */ #if !defined(CH_CFG_USE_SEMAPHORES_PRIORITY) -#define CH_CFG_USE_SEMAPHORES_PRIORITY FALSE +#define CH_CFG_USE_SEMAPHORES_PRIORITY FALSE #endif /** @@ -232,7 +232,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_MUTEXES) -#define CH_CFG_USE_MUTEXES FALSE +#define CH_CFG_USE_MUTEXES FALSE #endif /** @@ -244,7 +244,7 @@ * @note Requires @p CH_CFG_USE_MUTEXES. */ #if !defined(CH_CFG_USE_MUTEXES_RECURSIVE) -#define CH_CFG_USE_MUTEXES_RECURSIVE FALSE +#define CH_CFG_USE_MUTEXES_RECURSIVE FALSE #endif /** @@ -256,7 +256,7 @@ * @note Requires @p CH_CFG_USE_MUTEXES. */ #if !defined(CH_CFG_USE_CONDVARS) -#define CH_CFG_USE_CONDVARS FALSE +#define CH_CFG_USE_CONDVARS FALSE #endif /** @@ -268,7 +268,7 @@ * @note Requires @p CH_CFG_USE_CONDVARS. */ #if !defined(CH_CFG_USE_CONDVARS_TIMEOUT) -#define CH_CFG_USE_CONDVARS_TIMEOUT FALSE +#define CH_CFG_USE_CONDVARS_TIMEOUT FALSE #endif /** @@ -278,7 +278,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_EVENTS) -#define CH_CFG_USE_EVENTS TRUE +#define CH_CFG_USE_EVENTS TRUE #endif /** @@ -290,7 +290,7 @@ * @note Requires @p CH_CFG_USE_EVENTS. */ #if !defined(CH_CFG_USE_EVENTS_TIMEOUT) -#define CH_CFG_USE_EVENTS_TIMEOUT TRUE +#define CH_CFG_USE_EVENTS_TIMEOUT TRUE #endif /** @@ -301,7 +301,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_MESSAGES) -#define CH_CFG_USE_MESSAGES FALSE +#define CH_CFG_USE_MESSAGES FALSE #endif /** @@ -314,7 +314,7 @@ * @note Requires @p CH_CFG_USE_MESSAGES. */ #if !defined(CH_CFG_USE_MESSAGES_PRIORITY) -#define CH_CFG_USE_MESSAGES_PRIORITY FALSE +#define CH_CFG_USE_MESSAGES_PRIORITY FALSE #endif /** @@ -327,7 +327,7 @@ * @note Requires @p CH_CFG_USE_HEAP and/or @p CH_CFG_USE_MEMPOOLS. */ #if !defined(CH_CFG_USE_DYNAMIC) -#define CH_CFG_USE_DYNAMIC TRUE +#define CH_CFG_USE_DYNAMIC TRUE #endif /** @} */ @@ -348,7 +348,7 @@ * @note Requires @p CH_CFG_USE_SEMAPHORES. */ #if !defined(CH_CFG_USE_MAILBOXES) -#define CH_CFG_USE_MAILBOXES TRUE +#define CH_CFG_USE_MAILBOXES TRUE #endif /** @@ -359,7 +359,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_MEMCORE) -#define CH_CFG_USE_MEMCORE TRUE +#define CH_CFG_USE_MEMCORE TRUE #endif /** @@ -374,7 +374,7 @@ * @note Requires @p CH_CFG_USE_MEMCORE. */ #if !defined(CH_CFG_MEMCORE_SIZE) -#define CH_CFG_MEMCORE_SIZE 0 +#define CH_CFG_MEMCORE_SIZE 0 #endif /** @@ -388,7 +388,7 @@ * @note Mutexes are recommended. */ #if !defined(CH_CFG_USE_HEAP) -#define CH_CFG_USE_HEAP TRUE +#define CH_CFG_USE_HEAP TRUE #endif /** @@ -399,7 +399,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_MEMPOOLS) -#define CH_CFG_USE_MEMPOOLS TRUE +#define CH_CFG_USE_MEMPOOLS TRUE #endif /** @@ -410,7 +410,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_OBJ_FIFOS) -#define CH_CFG_USE_OBJ_FIFOS TRUE +#define CH_CFG_USE_OBJ_FIFOS TRUE #endif /** @@ -421,7 +421,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_PIPES) -#define CH_CFG_USE_PIPES TRUE +#define CH_CFG_USE_PIPES TRUE #endif /** @@ -432,7 +432,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_OBJ_CACHES) -#define CH_CFG_USE_OBJ_CACHES FALSE +#define CH_CFG_USE_OBJ_CACHES FALSE #endif /** @@ -443,7 +443,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_DELEGATES) -#define CH_CFG_USE_DELEGATES FALSE +#define CH_CFG_USE_DELEGATES FALSE #endif /** @@ -454,7 +454,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_JOBS) -#define CH_CFG_USE_JOBS FALSE +#define CH_CFG_USE_JOBS FALSE #endif /** @} */ @@ -474,7 +474,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_CFG_USE_FACTORY) -#define CH_CFG_USE_FACTORY FALSE +#define CH_CFG_USE_FACTORY FALSE #endif /** @@ -483,49 +483,49 @@ * pointer but this could have unintended side effects. */ #if !defined(CH_CFG_FACTORY_MAX_NAMES_LENGTH) -#define CH_CFG_FACTORY_MAX_NAMES_LENGTH 8 +#define CH_CFG_FACTORY_MAX_NAMES_LENGTH 8 #endif /** * @brief Enables the registry of generic objects. */ #if !defined(CH_CFG_FACTORY_OBJECTS_REGISTRY) -#define CH_CFG_FACTORY_OBJECTS_REGISTRY TRUE +#define CH_CFG_FACTORY_OBJECTS_REGISTRY TRUE #endif /** * @brief Enables factory for generic buffers. */ #if !defined(CH_CFG_FACTORY_GENERIC_BUFFERS) -#define CH_CFG_FACTORY_GENERIC_BUFFERS TRUE +#define CH_CFG_FACTORY_GENERIC_BUFFERS TRUE #endif /** * @brief Enables factory for semaphores. */ #if !defined(CH_CFG_FACTORY_SEMAPHORES) -#define CH_CFG_FACTORY_SEMAPHORES TRUE +#define CH_CFG_FACTORY_SEMAPHORES TRUE #endif /** * @brief Enables factory for mailboxes. */ #if !defined(CH_CFG_FACTORY_MAILBOXES) -#define CH_CFG_FACTORY_MAILBOXES TRUE +#define CH_CFG_FACTORY_MAILBOXES TRUE #endif /** * @brief Enables factory for objects FIFOs. */ #if !defined(CH_CFG_FACTORY_OBJ_FIFOS) -#define CH_CFG_FACTORY_OBJ_FIFOS TRUE +#define CH_CFG_FACTORY_OBJ_FIFOS TRUE #endif /** * @brief Enables factory for Pipes. */ #if !defined(CH_CFG_FACTORY_PIPES) || defined(__DOXYGEN__) -#define CH_CFG_FACTORY_PIPES TRUE +#define CH_CFG_FACTORY_PIPES TRUE #endif /** @} */ @@ -543,7 +543,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_STATISTICS) -#define CH_DBG_STATISTICS FALSE +#define CH_DBG_STATISTICS FALSE #endif /** @@ -554,7 +554,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_SYSTEM_STATE_CHECK) -#define CH_DBG_SYSTEM_STATE_CHECK FALSE +#define CH_DBG_SYSTEM_STATE_CHECK FALSE #endif /** @@ -565,7 +565,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_ENABLE_CHECKS) -#define CH_DBG_ENABLE_CHECKS FALSE +#define CH_DBG_ENABLE_CHECKS FALSE #endif /** @@ -577,7 +577,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_ENABLE_ASSERTS) -#define CH_DBG_ENABLE_ASSERTS FALSE +#define CH_DBG_ENABLE_ASSERTS FALSE #endif /** @@ -587,7 +587,7 @@ * @note The default is @p CH_DBG_TRACE_MASK_DISABLED. */ #if !defined(CH_DBG_TRACE_MASK) -#define CH_DBG_TRACE_MASK CH_DBG_TRACE_MASK_DISABLED +#define CH_DBG_TRACE_MASK CH_DBG_TRACE_MASK_DISABLED #endif /** @@ -596,7 +596,7 @@ * different from @p CH_DBG_TRACE_MASK_DISABLED. */ #if !defined(CH_DBG_TRACE_BUFFER_SIZE) -#define CH_DBG_TRACE_BUFFER_SIZE 128 +#define CH_DBG_TRACE_BUFFER_SIZE 128 #endif /** @@ -610,7 +610,7 @@ * @p panic_msg variable set to @p NULL. */ #if !defined(CH_DBG_ENABLE_STACK_CHECK) -#define CH_DBG_ENABLE_STACK_CHECK FALSE +#define CH_DBG_ENABLE_STACK_CHECK FALSE #endif /** @@ -622,7 +622,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_FILL_THREADS) -#define CH_DBG_FILL_THREADS FALSE +#define CH_DBG_FILL_THREADS FALSE #endif /** @@ -635,7 +635,7 @@ * tickless mode. */ #if !defined(CH_DBG_THREADS_PROFILING) -#define CH_DBG_THREADS_PROFILING FALSE +#define CH_DBG_THREADS_PROFILING FALSE #endif /** @} */ @@ -651,40 +651,39 @@ * @brief System structure extension. * @details User fields added to the end of the @p ch_system_t structure. */ -#define CH_CFG_SYSTEM_EXTRA_FIELDS \ - /* Add system custom fields here.*/ +#define CH_CFG_SYSTEM_EXTRA_FIELDS /* Add system custom fields here.*/ /** * @brief System initialization hook. * @details User initialization code added to the @p chSysInit() function * just before interrupts are enabled globally. */ -#define CH_CFG_SYSTEM_INIT_HOOK() { \ - /* Add system initialization code here.*/ \ -} +#define CH_CFG_SYSTEM_INIT_HOOK() \ + { \ + /* Add system initialization code here.*/ \ + } /** * @brief OS instance structure extension. * @details User fields added to the end of the @p os_instance_t structure. */ -#define CH_CFG_OS_INSTANCE_EXTRA_FIELDS \ - /* Add OS instance custom fields here.*/ +#define CH_CFG_OS_INSTANCE_EXTRA_FIELDS /* Add OS instance custom fields here.*/ /** * @brief OS instance initialization hook. * * @param[in] oip pointer to the @p os_instance_t structure */ -#define CH_CFG_OS_INSTANCE_INIT_HOOK(oip) { \ - /* Add OS instance initialization code here.*/ \ -} +#define CH_CFG_OS_INSTANCE_INIT_HOOK(oip) \ + { \ + /* Add OS instance initialization code here.*/ \ + } /** * @brief Threads descriptor structure extension. * @details User fields added to the end of the @p thread_t structure. */ -#define CH_CFG_THREAD_EXTRA_FIELDS \ - /* Add threads custom fields here.*/ +#define CH_CFG_THREAD_EXTRA_FIELDS /* Add threads custom fields here.*/ /** * @brief Threads initialization hook. @@ -695,9 +694,10 @@ * * @param[in] tp pointer to the @p thread_t structure */ -#define CH_CFG_THREAD_INIT_HOOK(tp) { \ - /* Add threads initialization code here.*/ \ -} +#define CH_CFG_THREAD_INIT_HOOK(tp) \ + { \ + /* Add threads initialization code here.*/ \ + } /** * @brief Threads finalization hook. @@ -705,9 +705,10 @@ * * @param[in] tp pointer to the @p thread_t structure */ -#define CH_CFG_THREAD_EXIT_HOOK(tp) { \ - /* Add threads finalization code here.*/ \ -} +#define CH_CFG_THREAD_EXIT_HOOK(tp) \ + { \ + /* Add threads finalization code here.*/ \ + } /** * @brief Context switch hook. @@ -716,23 +717,26 @@ * @param[in] ntp thread being switched in * @param[in] otp thread being switched out */ -#define CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) { \ - /* Context switch code here.*/ \ -} +#define CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) \ + { \ + /* Context switch code here.*/ \ + } /** * @brief ISR enter hook. */ -#define CH_CFG_IRQ_PROLOGUE_HOOK() { \ - /* IRQ prologue code here.*/ \ -} +#define CH_CFG_IRQ_PROLOGUE_HOOK() \ + { \ + /* IRQ prologue code here.*/ \ + } /** * @brief ISR exit hook. */ -#define CH_CFG_IRQ_EPILOGUE_HOOK() { \ - /* IRQ epilogue code here.*/ \ -} +#define CH_CFG_IRQ_EPILOGUE_HOOK() \ + { \ + /* IRQ epilogue code here.*/ \ + } /** * @brief Idle thread enter hook. @@ -740,9 +744,10 @@ * should be invoked from here. * @note This macro can be used to activate a power saving mode. */ -#define CH_CFG_IDLE_ENTER_HOOK() { \ - /* Idle-enter code here.*/ \ -} +#define CH_CFG_IDLE_ENTER_HOOK() \ + { \ + /* Idle-enter code here.*/ \ + } /** * @brief Idle thread leave hook. @@ -750,52 +755,58 @@ * should be invoked from here. * @note This macro can be used to deactivate a power saving mode. */ -#define CH_CFG_IDLE_LEAVE_HOOK() { \ - /* Idle-leave code here.*/ \ -} +#define CH_CFG_IDLE_LEAVE_HOOK() \ + { \ + /* Idle-leave code here.*/ \ + } /** * @brief Idle Loop hook. * @details This hook is continuously invoked by the idle thread loop. */ -#define CH_CFG_IDLE_LOOP_HOOK() { \ - /* Idle loop code here.*/ \ -} +#define CH_CFG_IDLE_LOOP_HOOK() \ + { \ + /* Idle loop code here.*/ \ + } /** * @brief System tick event hook. * @details This hook is invoked in the system tick handler immediately * after processing the virtual timers queue. */ -#define CH_CFG_SYSTEM_TICK_HOOK() { \ - /* System tick event code here.*/ \ -} +#define CH_CFG_SYSTEM_TICK_HOOK() \ + { \ + /* System tick event code here.*/ \ + } /** * @brief System halt hook. * @details This hook is invoked in case to a system halting error before * the system is halted. */ -#define CH_CFG_SYSTEM_HALT_HOOK(reason) { \ - /* System halt code here.*/ \ -} +#define CH_CFG_SYSTEM_HALT_HOOK(reason) \ + { \ + /* System halt code here.*/ \ + } /** * @brief Trace hook. * @details This hook is invoked each time a new record is written in the * trace buffer. */ -#define CH_CFG_TRACE_HOOK(tep) { \ - /* Trace code here.*/ \ -} +#define CH_CFG_TRACE_HOOK(tep) \ + { \ + /* Trace code here.*/ \ + } /** * @brief Runtime Faults Collection Unit hook. * @details This hook is invoked each time new faults are collected and stored. */ -#define CH_CFG_RUNTIME_FAULTS_HOOK(mask) { \ - /* Faults handling code here.*/ \ -} +#define CH_CFG_RUNTIME_FAULTS_HOOK(mask) \ + { \ + /* Faults handling code here.*/ \ + } /** @} */ @@ -803,6 +814,6 @@ /* Port-specific settings (override port settings defaulted in chcore.h). */ /*===========================================================================*/ -#endif /* CHCONF_H */ +#endif /* CHCONF_H */ /** @} */ diff --git a/targets/ChibiOS/ST_STM32F769I_DISCOVERY/nanoBooter/halconf.h b/targets/ChibiOS/ST_STM32F769I_DISCOVERY/nanoBooter/halconf.h index 84caec5529..22b723bec1 100644 --- a/targets/ChibiOS/ST_STM32F769I_DISCOVERY/nanoBooter/halconf.h +++ b/targets/ChibiOS/ST_STM32F769I_DISCOVERY/nanoBooter/halconf.h @@ -21,7 +21,7 @@ #define HALCONF_H #define _CHIBIOS_HAL_CONF_ -#define _CHIBIOS_HAL_CONF_VER_8_0_ +#define _CHIBIOS_HAL_CONF_VER_8_4_ #include "mcuconf.h" diff --git a/targets/ChibiOS/ST_STM32F769I_DISCOVERY/nanoBooter/mcuconf.h b/targets/ChibiOS/ST_STM32F769I_DISCOVERY/nanoBooter/mcuconf.h index fb3770006f..8ba2bbec15 100644 --- a/targets/ChibiOS/ST_STM32F769I_DISCOVERY/nanoBooter/mcuconf.h +++ b/targets/ChibiOS/ST_STM32F769I_DISCOVERY/nanoBooter/mcuconf.h @@ -7,6 +7,8 @@ #ifndef MCUCONF_H #define MCUCONF_H +// clang-format off + /* * STM32F7xx drivers configuration. * The following settings override the default settings present in @@ -22,11 +24,15 @@ */ #define STM32F7xx_MCUCONF -//#define STM32F765_MCUCONF -//#define STM32F767_MCUCONF -//#define STM32F777_MCUCONF #define STM32F769_MCUCONF -//#define STM32F779_MCUCONF + +/* + * Memory attributes settings. + */ +#define STM32_NOCACHE_ENABLE FALSE +// #define STM32_NOCACHE_MPU_REGION MPU_REGION_6 +// #define STM32_NOCACHE_RBAR 0x2004C000U +// #define STM32_NOCACHE_RASR MPU_RASR_SIZE_16K /* * HAL driver system settings. @@ -255,7 +261,7 @@ /* * PWM driver system settings. */ -#define STM32_PWM_USE_ADVANCED FALSE +#define STM32_PWM_USE_ADVANCED FALSE //NOT IN LATEST VERSION, KEEPING JUST INCASE #define STM32_PWM_USE_TIM1 FALSE #define STM32_PWM_USE_TIM2 FALSE #define STM32_PWM_USE_TIM3 FALSE @@ -429,3 +435,5 @@ #define STM32_WSPI_QUADSPI1_PRESCALER_VALUE 2 #endif /* MCUCONF_H */ + +// clang-format on diff --git a/targets/ChibiOS/ST_STM32F769I_DISCOVERY/nanoCLR/STM32F76xx_CLR-DEBUG.ld b/targets/ChibiOS/ST_STM32F769I_DISCOVERY/nanoCLR/STM32F76xx_CLR-DEBUG.ld index b067340e01..81a1ad82e7 100644 --- a/targets/ChibiOS/ST_STM32F769I_DISCOVERY/nanoCLR/STM32F76xx_CLR-DEBUG.ld +++ b/targets/ChibiOS/ST_STM32F769I_DISCOVERY/nanoCLR/STM32F76xx_CLR-DEBUG.ld @@ -18,8 +18,8 @@ */ MEMORY { - flash0 (rx) : org = 0x08010000, len = 2M - 32k - 32k - 1280k /* flash size less the space reserved for nanoBooter, configuration block and application deployment*/ - flash1 (rx) : org = 0x00210000, len = 2M - 32k - 32k - 1280k + flash0 (rx) : org = 0x08010000, len = 2M - 32k - 32k - 1024k /* flash size less the space reserved for nanoBooter, configuration block and application deployment*/ + flash1 (rx) : org = 0x00210000, len = 2M - 32k - 32k - 1024k flash2 (rx) : org = 0x00000000, len = 0 flash3 (rx) : org = 0x00000000, len = 0 flash4 (rx) : org = 0x00000000, len = 0 @@ -27,7 +27,7 @@ MEMORY flash6 (rx) : org = 0x00000000, len = 0 flash7 (rx) : org = 0x00000000, len = 0 config (rw) : org = 0x08008000, len = 32k /* space reserved for configuration block */ - deployment (rx) : org = 0x080C0000, len = 1280k /* space reserved for application deployment */ + deployment (rx) : org = 0x08100000, len = 1024k /* space reserved for application deployment */ ramvt (wx) : org = 0x00000000, len = 0 /* initial RAM address is reserved for a copy of the vector table */ ram0 (wx) : org = 0x20020000, len = 384k /* SRAM1 + SRAM2 */ ram1 (wx) : org = 0x20020000, len = 368k /* SRAM1 */ diff --git a/targets/ChibiOS/ST_STM32F769I_DISCOVERY/nanoCLR/chconf.h b/targets/ChibiOS/ST_STM32F769I_DISCOVERY/nanoCLR/chconf.h index cc4d2a81a6..2cbe763aa7 100644 --- a/targets/ChibiOS/ST_STM32F769I_DISCOVERY/nanoCLR/chconf.h +++ b/targets/ChibiOS/ST_STM32F769I_DISCOVERY/nanoCLR/chconf.h @@ -36,7 +36,7 @@ * direct interactions are handled by the OS. */ #if !defined(CH_CFG_SMP_MODE) -#define CH_CFG_SMP_MODE FALSE +#define CH_CFG_SMP_MODE FALSE #endif /** @} */ @@ -53,7 +53,7 @@ * @note Allowed values are 16, 32 or 64 bits. */ #if !defined(CH_CFG_ST_RESOLUTION) -#define CH_CFG_ST_RESOLUTION 32 +#define CH_CFG_ST_RESOLUTION 32 #endif /** @@ -62,7 +62,7 @@ * setting also defines the system tick time unit. */ #if !defined(CH_CFG_ST_FREQUENCY) -#define CH_CFG_ST_FREQUENCY 10000 +#define CH_CFG_ST_FREQUENCY 10000 #endif /** @@ -70,7 +70,7 @@ * @note Allowed values are 16, 32 or 64 bits. */ #if !defined(CH_CFG_INTERVALS_SIZE) -#define CH_CFG_INTERVALS_SIZE 32 +#define CH_CFG_INTERVALS_SIZE 32 #endif /** @@ -78,7 +78,7 @@ * @note Allowed values are 16 or 32 bits. */ #if !defined(CH_CFG_TIME_TYPES_SIZE) -#define CH_CFG_TIME_TYPES_SIZE 32 +#define CH_CFG_TIME_TYPES_SIZE 32 #endif /** @@ -90,7 +90,7 @@ * this value. */ #if !defined(CH_CFG_ST_TIMEDELTA) -#define CH_CFG_ST_TIMEDELTA 2 +#define CH_CFG_ST_TIMEDELTA 2 #endif /** @} */ @@ -115,7 +115,7 @@ * must be set to zero in that case. */ #if !defined(CH_CFG_TIME_QUANTUM) -#define CH_CFG_TIME_QUANTUM 0 +#define CH_CFG_TIME_QUANTUM 0 #endif /** @@ -126,7 +126,7 @@ * infinite loop. */ #if !defined(CH_CFG_NO_IDLE_THREAD) -#define CH_CFG_NO_IDLE_THREAD FALSE +#define CH_CFG_NO_IDLE_THREAD FALSE #endif /** @} */ @@ -147,7 +147,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_OPTIMIZE_SPEED) -#define CH_CFG_OPTIMIZE_SPEED TRUE +#define CH_CFG_OPTIMIZE_SPEED TRUE #endif /** @} */ @@ -167,7 +167,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_TM) -#define CH_CFG_USE_TM FALSE +#define CH_CFG_USE_TM FALSE #endif /** @@ -178,7 +178,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_TIMESTAMP) -#define CH_CFG_USE_TIMESTAMP FALSE +#define CH_CFG_USE_TIMESTAMP TRUE #endif /** @@ -188,7 +188,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_REGISTRY) -#define CH_CFG_USE_REGISTRY TRUE +#define CH_CFG_USE_REGISTRY TRUE #endif /** @@ -199,7 +199,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_WAITEXIT) -#define CH_CFG_USE_WAITEXIT TRUE +#define CH_CFG_USE_WAITEXIT TRUE #endif /** @@ -209,7 +209,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_SEMAPHORES) -#define CH_CFG_USE_SEMAPHORES TRUE +#define CH_CFG_USE_SEMAPHORES TRUE #endif /** @@ -222,7 +222,7 @@ * @note Requires @p CH_CFG_USE_SEMAPHORES. */ #if !defined(CH_CFG_USE_SEMAPHORES_PRIORITY) -#define CH_CFG_USE_SEMAPHORES_PRIORITY FALSE +#define CH_CFG_USE_SEMAPHORES_PRIORITY FALSE #endif /** @@ -232,7 +232,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_MUTEXES) -#define CH_CFG_USE_MUTEXES TRUE +#define CH_CFG_USE_MUTEXES TRUE #endif /** @@ -244,7 +244,7 @@ * @note Requires @p CH_CFG_USE_MUTEXES. */ #if !defined(CH_CFG_USE_MUTEXES_RECURSIVE) -#define CH_CFG_USE_MUTEXES_RECURSIVE FALSE +#define CH_CFG_USE_MUTEXES_RECURSIVE FALSE #endif /** @@ -256,7 +256,7 @@ * @note Requires @p CH_CFG_USE_MUTEXES. */ #if !defined(CH_CFG_USE_CONDVARS) -#define CH_CFG_USE_CONDVARS TRUE +#define CH_CFG_USE_CONDVARS TRUE #endif /** @@ -268,7 +268,7 @@ * @note Requires @p CH_CFG_USE_CONDVARS. */ #if !defined(CH_CFG_USE_CONDVARS_TIMEOUT) -#define CH_CFG_USE_CONDVARS_TIMEOUT TRUE +#define CH_CFG_USE_CONDVARS_TIMEOUT TRUE #endif /** @@ -278,7 +278,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_EVENTS) -#define CH_CFG_USE_EVENTS TRUE +#define CH_CFG_USE_EVENTS TRUE #endif /** @@ -290,7 +290,7 @@ * @note Requires @p CH_CFG_USE_EVENTS. */ #if !defined(CH_CFG_USE_EVENTS_TIMEOUT) -#define CH_CFG_USE_EVENTS_TIMEOUT TRUE +#define CH_CFG_USE_EVENTS_TIMEOUT TRUE #endif /** @@ -301,7 +301,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_MESSAGES) -#define CH_CFG_USE_MESSAGES TRUE +#define CH_CFG_USE_MESSAGES TRUE #endif /** @@ -314,7 +314,7 @@ * @note Requires @p CH_CFG_USE_MESSAGES. */ #if !defined(CH_CFG_USE_MESSAGES_PRIORITY) -#define CH_CFG_USE_MESSAGES_PRIORITY FALSE +#define CH_CFG_USE_MESSAGES_PRIORITY FALSE #endif /** @@ -327,7 +327,7 @@ * @note Requires @p CH_CFG_USE_HEAP and/or @p CH_CFG_USE_MEMPOOLS. */ #if !defined(CH_CFG_USE_DYNAMIC) -#define CH_CFG_USE_DYNAMIC TRUE +#define CH_CFG_USE_DYNAMIC TRUE #endif /** @} */ @@ -348,7 +348,7 @@ * @note Requires @p CH_CFG_USE_SEMAPHORES. */ #if !defined(CH_CFG_USE_MAILBOXES) -#define CH_CFG_USE_MAILBOXES TRUE +#define CH_CFG_USE_MAILBOXES TRUE #endif /** @@ -359,7 +359,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_MEMCORE) -#define CH_CFG_USE_MEMCORE TRUE +#define CH_CFG_USE_MEMCORE TRUE #endif /** @@ -374,7 +374,7 @@ * @note Requires @p CH_CFG_USE_MEMCORE. */ #if !defined(CH_CFG_MEMCORE_SIZE) -#define CH_CFG_MEMCORE_SIZE 0 +#define CH_CFG_MEMCORE_SIZE 0 #endif /** @@ -388,7 +388,7 @@ * @note Mutexes are recommended. */ #if !defined(CH_CFG_USE_HEAP) -#define CH_CFG_USE_HEAP TRUE +#define CH_CFG_USE_HEAP TRUE #endif /** @@ -399,7 +399,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_MEMPOOLS) -#define CH_CFG_USE_MEMPOOLS TRUE +#define CH_CFG_USE_MEMPOOLS TRUE #endif /** @@ -410,7 +410,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_OBJ_FIFOS) -#define CH_CFG_USE_OBJ_FIFOS TRUE +#define CH_CFG_USE_OBJ_FIFOS TRUE #endif /** @@ -421,7 +421,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_PIPES) -#define CH_CFG_USE_PIPES TRUE +#define CH_CFG_USE_PIPES TRUE #endif /** @@ -432,7 +432,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_OBJ_CACHES) -#define CH_CFG_USE_OBJ_CACHES FALSE +#define CH_CFG_USE_OBJ_CACHES FALSE #endif /** @@ -443,7 +443,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_DELEGATES) -#define CH_CFG_USE_DELEGATES FALSE +#define CH_CFG_USE_DELEGATES FALSE #endif /** @@ -454,7 +454,7 @@ * @note The default is @p TRUE. */ #if !defined(CH_CFG_USE_JOBS) -#define CH_CFG_USE_JOBS FALSE +#define CH_CFG_USE_JOBS FALSE #endif /** @} */ @@ -474,7 +474,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_CFG_USE_FACTORY) -#define CH_CFG_USE_FACTORY FALSE +#define CH_CFG_USE_FACTORY FALSE #endif /** @@ -483,49 +483,49 @@ * pointer but this could have unintended side effects. */ #if !defined(CH_CFG_FACTORY_MAX_NAMES_LENGTH) -#define CH_CFG_FACTORY_MAX_NAMES_LENGTH 8 +#define CH_CFG_FACTORY_MAX_NAMES_LENGTH 8 #endif /** * @brief Enables the registry of generic objects. */ #if !defined(CH_CFG_FACTORY_OBJECTS_REGISTRY) -#define CH_CFG_FACTORY_OBJECTS_REGISTRY TRUE +#define CH_CFG_FACTORY_OBJECTS_REGISTRY TRUE #endif /** * @brief Enables factory for generic buffers. */ #if !defined(CH_CFG_FACTORY_GENERIC_BUFFERS) -#define CH_CFG_FACTORY_GENERIC_BUFFERS TRUE +#define CH_CFG_FACTORY_GENERIC_BUFFERS TRUE #endif /** * @brief Enables factory for semaphores. */ #if !defined(CH_CFG_FACTORY_SEMAPHORES) -#define CH_CFG_FACTORY_SEMAPHORES TRUE +#define CH_CFG_FACTORY_SEMAPHORES TRUE #endif /** * @brief Enables factory for mailboxes. */ #if !defined(CH_CFG_FACTORY_MAILBOXES) -#define CH_CFG_FACTORY_MAILBOXES TRUE +#define CH_CFG_FACTORY_MAILBOXES TRUE #endif /** * @brief Enables factory for objects FIFOs. */ #if !defined(CH_CFG_FACTORY_OBJ_FIFOS) -#define CH_CFG_FACTORY_OBJ_FIFOS TRUE +#define CH_CFG_FACTORY_OBJ_FIFOS TRUE #endif /** * @brief Enables factory for Pipes. */ #if !defined(CH_CFG_FACTORY_PIPES) || defined(__DOXYGEN__) -#define CH_CFG_FACTORY_PIPES TRUE +#define CH_CFG_FACTORY_PIPES TRUE #endif /** @} */ @@ -543,7 +543,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_STATISTICS) -#define CH_DBG_STATISTICS FALSE +#define CH_DBG_STATISTICS FALSE #endif /** @@ -554,7 +554,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_SYSTEM_STATE_CHECK) -#define CH_DBG_SYSTEM_STATE_CHECK FALSE +#define CH_DBG_SYSTEM_STATE_CHECK FALSE #endif /** @@ -565,7 +565,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_ENABLE_CHECKS) -#define CH_DBG_ENABLE_CHECKS FALSE +#define CH_DBG_ENABLE_CHECKS FALSE #endif /** @@ -577,7 +577,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_ENABLE_ASSERTS) -#define CH_DBG_ENABLE_ASSERTS FALSE +#define CH_DBG_ENABLE_ASSERTS FALSE #endif /** @@ -587,7 +587,7 @@ * @note The default is @p CH_DBG_TRACE_MASK_DISABLED. */ #if !defined(CH_DBG_TRACE_MASK) -#define CH_DBG_TRACE_MASK CH_DBG_TRACE_MASK_DISABLED +#define CH_DBG_TRACE_MASK CH_DBG_TRACE_MASK_DISABLED #endif /** @@ -596,7 +596,7 @@ * different from @p CH_DBG_TRACE_MASK_DISABLED. */ #if !defined(CH_DBG_TRACE_BUFFER_SIZE) -#define CH_DBG_TRACE_BUFFER_SIZE 128 +#define CH_DBG_TRACE_BUFFER_SIZE 128 #endif /** @@ -610,7 +610,7 @@ * @p panic_msg variable set to @p NULL. */ #if !defined(CH_DBG_ENABLE_STACK_CHECK) -#define CH_DBG_ENABLE_STACK_CHECK FALSE +#define CH_DBG_ENABLE_STACK_CHECK FALSE #endif /** @@ -622,7 +622,7 @@ * @note The default is @p FALSE. */ #if !defined(CH_DBG_FILL_THREADS) -#define CH_DBG_FILL_THREADS FALSE +#define CH_DBG_FILL_THREADS FALSE #endif /** @@ -635,7 +635,7 @@ * tickless mode. */ #if !defined(CH_DBG_THREADS_PROFILING) -#define CH_DBG_THREADS_PROFILING FALSE +#define CH_DBG_THREADS_PROFILING FALSE #endif /** @} */ @@ -651,40 +651,39 @@ * @brief System structure extension. * @details User fields added to the end of the @p ch_system_t structure. */ -#define CH_CFG_SYSTEM_EXTRA_FIELDS \ - /* Add system custom fields here.*/ +#define CH_CFG_SYSTEM_EXTRA_FIELDS /* Add system custom fields here.*/ /** * @brief System initialization hook. * @details User initialization code added to the @p chSysInit() function * just before interrupts are enabled globally. */ -#define CH_CFG_SYSTEM_INIT_HOOK() { \ - /* Add system initialization code here.*/ \ -} +#define CH_CFG_SYSTEM_INIT_HOOK() \ + { \ + /* Add system initialization code here.*/ \ + } /** * @brief OS instance structure extension. * @details User fields added to the end of the @p os_instance_t structure. */ -#define CH_CFG_OS_INSTANCE_EXTRA_FIELDS \ - /* Add OS instance custom fields here.*/ +#define CH_CFG_OS_INSTANCE_EXTRA_FIELDS /* Add OS instance custom fields here.*/ /** * @brief OS instance initialization hook. * * @param[in] oip pointer to the @p os_instance_t structure */ -#define CH_CFG_OS_INSTANCE_INIT_HOOK(oip) { \ - /* Add OS instance initialization code here.*/ \ -} +#define CH_CFG_OS_INSTANCE_INIT_HOOK(oip) \ + { \ + /* Add OS instance initialization code here.*/ \ + } /** * @brief Threads descriptor structure extension. * @details User fields added to the end of the @p thread_t structure. */ -#define CH_CFG_THREAD_EXTRA_FIELDS \ - /* Add threads custom fields here.*/ +#define CH_CFG_THREAD_EXTRA_FIELDS /* Add threads custom fields here.*/ /** * @brief Threads initialization hook. @@ -695,9 +694,10 @@ * * @param[in] tp pointer to the @p thread_t structure */ -#define CH_CFG_THREAD_INIT_HOOK(tp) { \ - /* Add threads initialization code here.*/ \ -} +#define CH_CFG_THREAD_INIT_HOOK(tp) \ + { \ + /* Add threads initialization code here.*/ \ + } /** * @brief Threads finalization hook. @@ -705,9 +705,10 @@ * * @param[in] tp pointer to the @p thread_t structure */ -#define CH_CFG_THREAD_EXIT_HOOK(tp) { \ - /* Add threads finalization code here.*/ \ -} +#define CH_CFG_THREAD_EXIT_HOOK(tp) \ + { \ + /* Add threads finalization code here.*/ \ + } /** * @brief Context switch hook. @@ -716,23 +717,26 @@ * @param[in] ntp thread being switched in * @param[in] otp thread being switched out */ -#define CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) { \ - /* Context switch code here.*/ \ -} +#define CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) \ + { \ + /* Context switch code here.*/ \ + } /** * @brief ISR enter hook. */ -#define CH_CFG_IRQ_PROLOGUE_HOOK() { \ - /* IRQ prologue code here.*/ \ -} +#define CH_CFG_IRQ_PROLOGUE_HOOK() \ + { \ + /* IRQ prologue code here.*/ \ + } /** * @brief ISR exit hook. */ -#define CH_CFG_IRQ_EPILOGUE_HOOK() { \ - /* IRQ epilogue code here.*/ \ -} +#define CH_CFG_IRQ_EPILOGUE_HOOK() \ + { \ + /* IRQ epilogue code here.*/ \ + } /** * @brief Idle thread enter hook. @@ -740,9 +744,10 @@ * should be invoked from here. * @note This macro can be used to activate a power saving mode. */ -#define CH_CFG_IDLE_ENTER_HOOK() { \ - /* Idle-enter code here.*/ \ -} +#define CH_CFG_IDLE_ENTER_HOOK() \ + { \ + /* Idle-enter code here.*/ \ + } /** * @brief Idle thread leave hook. @@ -750,52 +755,58 @@ * should be invoked from here. * @note This macro can be used to deactivate a power saving mode. */ -#define CH_CFG_IDLE_LEAVE_HOOK() { \ - /* Idle-leave code here.*/ \ -} +#define CH_CFG_IDLE_LEAVE_HOOK() \ + { \ + /* Idle-leave code here.*/ \ + } /** * @brief Idle Loop hook. * @details This hook is continuously invoked by the idle thread loop. */ -#define CH_CFG_IDLE_LOOP_HOOK() { \ - /* Idle loop code here.*/ \ -} +#define CH_CFG_IDLE_LOOP_HOOK() \ + { \ + /* Idle loop code here.*/ \ + } /** * @brief System tick event hook. * @details This hook is invoked in the system tick handler immediately * after processing the virtual timers queue. */ -#define CH_CFG_SYSTEM_TICK_HOOK() { \ - /* System tick event code here.*/ \ -} +#define CH_CFG_SYSTEM_TICK_HOOK() \ + { \ + /* System tick event code here.*/ \ + } /** * @brief System halt hook. * @details This hook is invoked in case to a system halting error before * the system is halted. */ -#define CH_CFG_SYSTEM_HALT_HOOK(reason) { \ - /* System halt code here.*/ \ -} +#define CH_CFG_SYSTEM_HALT_HOOK(reason) \ + { \ + /* System halt code here.*/ \ + } /** * @brief Trace hook. * @details This hook is invoked each time a new record is written in the * trace buffer. */ -#define CH_CFG_TRACE_HOOK(tep) { \ - /* Trace code here.*/ \ -} +#define CH_CFG_TRACE_HOOK(tep) \ + { \ + /* Trace code here.*/ \ + } /** * @brief Runtime Faults Collection Unit hook. * @details This hook is invoked each time new faults are collected and stored. */ -#define CH_CFG_RUNTIME_FAULTS_HOOK(mask) { \ - /* Faults handling code here.*/ \ -} +#define CH_CFG_RUNTIME_FAULTS_HOOK(mask) \ + { \ + /* Faults handling code here.*/ \ + } /** @} */ @@ -803,6 +814,6 @@ /* Port-specific settings (override port settings defaulted in chcore.h). */ /*===========================================================================*/ -#endif /* CHCONF_H */ +#endif /* CHCONF_H */ /** @} */ diff --git a/targets/ChibiOS/ST_STM32F769I_DISCOVERY/nanoCLR/halconf.h b/targets/ChibiOS/ST_STM32F769I_DISCOVERY/nanoCLR/halconf.h index 455df847f7..5df08fc9ba 100644 --- a/targets/ChibiOS/ST_STM32F769I_DISCOVERY/nanoCLR/halconf.h +++ b/targets/ChibiOS/ST_STM32F769I_DISCOVERY/nanoCLR/halconf.h @@ -21,7 +21,7 @@ #define HALCONF_H #define _CHIBIOS_HAL_CONF_ -#define _CHIBIOS_HAL_CONF_VER_8_0_ +#define _CHIBIOS_HAL_CONF_VER_8_4_ #include #include "mcuconf.h" diff --git a/targets/ChibiOS/ST_STM32F769I_DISCOVERY/nanoCLR/mcuconf.h b/targets/ChibiOS/ST_STM32F769I_DISCOVERY/nanoCLR/mcuconf.h index 12b65367ba..28231717e5 100644 --- a/targets/ChibiOS/ST_STM32F769I_DISCOVERY/nanoCLR/mcuconf.h +++ b/targets/ChibiOS/ST_STM32F769I_DISCOVERY/nanoCLR/mcuconf.h @@ -7,6 +7,8 @@ #ifndef MCUCONF_H #define MCUCONF_H +// clang-format off + /* * STM32F7xx drivers configuration. * The following settings override the default settings present in @@ -22,11 +24,15 @@ */ #define STM32F7xx_MCUCONF -//#define STM32F765_MCUCONF -//#define STM32F767_MCUCONF -//#define STM32F777_MCUCONF #define STM32F769_MCUCONF -//#define STM32F779_MCUCONF + +/* + * Memory attributes settings. + */ +#define STM32_NOCACHE_ENABLE FALSE +// #define STM32_NOCACHE_MPU_REGION MPU_REGION_6 +// #define STM32_NOCACHE_RBAR 0x2004C000U +// #define STM32_NOCACHE_RASR MPU_RASR_SIZE_16K /* * HAL driver system settings. @@ -433,3 +439,5 @@ #include "mcuconf_nf.h" #endif /* MCUCONF_H */ + +// clang-format on diff --git a/targets/ChibiOS/ST_STM32F769I_DISCOVERY/target_system_device_pwm_config.cpp b/targets/ChibiOS/ST_STM32F769I_DISCOVERY/target_system_device_pwm_config.cpp new file mode 100644 index 0000000000..73cc6666d3 --- /dev/null +++ b/targets/ChibiOS/ST_STM32F769I_DISCOVERY/target_system_device_pwm_config.cpp @@ -0,0 +1,9 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS BLANK ON PURPOSE BECAUSE THIS TARGET DOESN'T REQUIRE THIS SPECIFIC CONFIGURATION // +/////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/targets/ChibiOS/_Lwip/nf_lwipthread.c b/targets/ChibiOS/_Lwip/nf_lwipthread.c index 4123cd2d30..da66ac9978 100644 --- a/targets/ChibiOS/_Lwip/nf_lwipthread.c +++ b/targets/ChibiOS/_Lwip/nf_lwipthread.c @@ -56,7 +56,7 @@ static void low_level_init(struct netif *netif) /* device capabilities */ /* don't set NETIF_FLAG_ETHARP if this device is not an Ethernet one */ - netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP; + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP; /* Do whatever else is needed to initialize interface. */ } @@ -92,7 +92,7 @@ static err_t low_level_output(struct netif *netif, struct pbuf *p) /* Iterates through the pbuf chain. */ for (q = p; q != NULL; q = q->next) macWriteTransmitDescriptor(&td, (uint8_t *)q->payload, (size_t)q->len); - macReleaseTransmitDescriptor(&td); + macReleaseTransmitDescriptorX(&td); MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p->tot_len); if (((u8_t *)p->payload)[0] & 1) @@ -156,7 +156,7 @@ static bool low_level_input(struct netif *netif, struct pbuf **pbuf) /* Iterates through the pbuf chain. */ for (q = *pbuf; q != NULL; q = q->next) macReadReceiveDescriptor(&rd, (uint8_t *)q->payload, (size_t)q->len); - macReleaseReceiveDescriptor(&rd); + macReleaseReceiveDescriptorX(&rd); MIB2_STATS_NETIF_ADD(netif, ifinoctets, (*pbuf)->tot_len); @@ -179,7 +179,7 @@ static bool low_level_input(struct netif *netif, struct pbuf **pbuf) } else { - macReleaseReceiveDescriptor(&rd); // Drop packet + macReleaseReceiveDescriptorX(&rd); // Drop packet LINK_STATS_INC(link.memerr); LINK_STATS_INC(link.drop); MIB2_STATS_NETIF_INC(netif, ifindiscards); @@ -389,7 +389,7 @@ static THD_FUNCTION(lwip_thread, p) evtObjectInit(&evt, LWIP_LINK_POLL_INTERVAL); evtStart(&evt); chEvtRegisterMask(&evt.et_es, &el0, PERIODIC_TIMER_ID); - chEvtRegisterMask(macGetReceiveEventSource(ÐD1), &el1, FRAME_RECEIVED_ID); + chEvtRegisterMaskWithFlags(macGetEventSource(ÐD1), &el1, FRAME_RECEIVED_ID, MAC_FLAGS_RX); chEvtAddEvents(PERIODIC_TIMER_ID | FRAME_RECEIVED_ID); /* Resumes the caller and goes to the final priority.*/ diff --git a/targets/ChibiOS/_common/CMakeLists.txt b/targets/ChibiOS/_common/CMakeLists.txt index 616ff884a8..fdb1d6231f 100644 --- a/targets/ChibiOS/_common/CMakeLists.txt +++ b/targets/ChibiOS/_common/CMakeLists.txt @@ -22,6 +22,7 @@ endif() # append nanoHAL list(APPEND TARGET_CHIBIOS_COMMON_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/targetHAL.c) list(APPEND TARGET_CHIBIOS_COMMON_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/targetHAL_Time.cpp) +list(APPEND TARGET_CHIBIOS_COMMON_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/targetHAL_Rtos.c) # append hard fault handler if the build type is to include debug info if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") diff --git a/targets/ChibiOS/_common/LaunchCLR.c b/targets/ChibiOS/_common/LaunchCLR.c index bb941b47a7..ba8c2cebaf 100644 --- a/targets/ChibiOS/_common/LaunchCLR.c +++ b/targets/ChibiOS/_common/LaunchCLR.c @@ -8,14 +8,18 @@ #include #include #include +#include void LaunchCLR(uint32_t address) { // function pointer to load nanoCLR ResetHandler address irq_vector_t JumpToNanoCLR; + // report successfull nanoBooter execution + ReportSuccessfullNanoBooter(); + // load nanoCLR vector table - const vectors_t* nanoCLRVectorTable = (vectors_t*) address; + const vectors_t *nanoCLRVectorTable = (vectors_t *)address; // load the jump address with the nanoCLR ResetHandler address JumpToNanoCLR = nanoCLRVectorTable->reset_handler; @@ -38,55 +42,55 @@ bool CheckValidCLRImage(uint32_t address) uint32_t resetVectorAddress; // load nanoCLR vector table - const vectors_t* nanoCLRVectorTable = (vectors_t*) address; + const vectors_t *nanoCLRVectorTable = (vectors_t *)address; // 1st check: the flash content pointed by the address can't be all 0's neither all F's // meaning that the Flash is neither 'all burnt' or erased - if( (uint32_t)(*(uint32_t**)((uint32_t*)address)) == 0xFFFFFFFF || - (uint32_t)(*(uint32_t**)((uint32_t*)address)) == 0x00000000 ) + if ((uint32_t)(*(uint32_t **)((uint32_t *)address)) == 0xFFFFFFFF || + (uint32_t)(*(uint32_t **)((uint32_t *)address)) == 0x00000000) { // check failed, there is no valid CLR image return false; } - - // 2nd check: the content pointed by the reset vector has to be 0xE002 - // that's an assembly "b.n" (branch instruction) the very first one in the Reset_Handler function - // see os\common\startup\ARMCMx\compilers\GCC\vectors.S +// 2nd check: the content pointed by the reset vector has to be 0xE002 +// that's an assembly "b.n" (branch instruction) the very first one in the Reset_Handler function +// see os\common\startup\ARMCMx\compilers\GCC\vectors.S + +// for series that have ART Accelerator the handlers addresses stored in the vector table are for ITCM access +// need to parsed them to reach the equivalent address in AXI access +#ifdef FLASHITCM_BASE - // for series that have ART Accelerator the handlers addresses stored in the vector table are for ITCM access - // need to parsed them to reach the equivalent address in AXI access - #ifdef FLASHITCM_BASE - // read address (ITCM) - resetVectorAddress = (uint32_t)((uint32_t*)nanoCLRVectorTable->reset_handler); + resetVectorAddress = (uint32_t)((uint32_t *)nanoCLRVectorTable->reset_handler); // parse it to get the address in the AXI range resetVectorAddress -= FLASHITCM_BASE; resetVectorAddress += FLASHAXI_BASE; - #else - +#else + // "regular" address mapping - resetVectorAddress = (uint32_t)((uint32_t*)nanoCLRVectorTable->reset_handler); - - #endif + resetVectorAddress = (uint32_t)((uint32_t *)nanoCLRVectorTable->reset_handler); + +#endif // sanity check for invalid address (out of flash range which causes a hard fault) - if( resetVectorAddress <= FLASH1_MEMORY_StartAddress || - resetVectorAddress >= (FLASH1_MEMORY_StartAddress + FLASH1_MEMORY_Size) ) + if (resetVectorAddress <= FLASH1_MEMORY_StartAddress || + resetVectorAddress >= (FLASH1_MEMORY_StartAddress + FLASH1_MEMORY_Size)) { // check failed, doesn't seem to be a valid CLR image return false; } - // the linker can place this anywhere on the address space because of optimizations so we better check where the reset pointer points to - uint32_t opCodeAddress = (uint32_t)((uint32_t**)nanoCLRVectorTable->reset_handler); + // the linker can place this anywhere on the address space because of optimizations so we better check where the + // reset pointer points to + uint32_t opCodeAddress = (uint32_t)((uint32_t **)nanoCLRVectorTable->reset_handler); // real address is -1 opCodeAddress -= 1; - uint32_t opCode = *((uint32_t*)opCodeAddress); - if((uint16_t)opCode == 0xE002) + uint32_t opCode = *((uint32_t *)opCodeAddress); + if ((uint16_t)opCode == 0xE002) { // check, there seems to be a valid CLR image return true; diff --git a/targets/ChibiOS/_common/platform_heap.c b/targets/ChibiOS/_common/platform_heap.c index 0f273189f3..dc8b4af1ea 100644 --- a/targets/ChibiOS/_common/platform_heap.c +++ b/targets/ChibiOS/_common/platform_heap.c @@ -29,10 +29,3 @@ void platform_free(void *ptr) // define back #define free YOU_SHALL_NOT_USE_free } - -void *platform_realloc(void *ptr, size_t size) -{ - (void)size; - - return ptr; -} diff --git a/targets/ChibiOS/_common/rules_code.ld b/targets/ChibiOS/_common/rules_code.ld index 8f83284cc9..1234cf604b 100644 --- a/targets/ChibiOS/_common/rules_code.ld +++ b/targets/ChibiOS/_common/rules_code.ld @@ -22,7 +22,10 @@ SECTIONS { .vectors : ALIGN(1024) { + __textvectors_base__ = LOADADDR(.vectors); + __vectors_base__ = .; KEEP(*(.vectors)) + __vectors_end__ = .; } > VECTORS_FLASH AT > VECTORS_FLASH_LMA .xtors : ALIGN(4) diff --git a/targets/ChibiOS/_common/targetHAL_Rtos.c b/targets/ChibiOS/_common/targetHAL_Rtos.c new file mode 100644 index 0000000000..c2b4498871 --- /dev/null +++ b/targets/ChibiOS/_common/targetHAL_Rtos.c @@ -0,0 +1,12 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include +#include + +void RtosYield() +{ + osThreadYield(); +} diff --git a/targets/ChibiOS/_common/targetHAL_Time.cpp b/targets/ChibiOS/_common/targetHAL_Time.cpp index fa9246f774..4cc4eb73af 100644 --- a/targets/ChibiOS/_common/targetHAL_Time.cpp +++ b/targets/ChibiOS/_common/targetHAL_Time.cpp @@ -13,15 +13,6 @@ extern "C" } #endif -// Converts CMSIS sysTicks to .NET ticks (100 nanoseconds) -uint64_t HAL_Time_SysTicksToTime(uint64_t sysTicks) -{ - // convert to microseconds from CMSIS SysTicks - // this is a rewrite of ChibiOS TIME_I2US(n) macro because it will overflow if doing the math using uint32_t - // need to convert from microseconds to 100 nanoseconds - return (((sysTicks * (uint64_t)1000000) + (int64_t)CH_CFG_ST_FREQUENCY - 1) / (int64_t)CH_CFG_ST_FREQUENCY) * 10; -} - // implementation required for STM Cube package // Provides a tick value in millisecond. uint32_t HAL_GetTick(void) diff --git a/targets/ChibiOS/_include/targetHAL_Time.h b/targets/ChibiOS/_include/targetHAL_Time.h index e422c66fa1..a5741b9116 100644 --- a/targets/ChibiOS/_include/targetHAL_Time.h +++ b/targets/ChibiOS/_include/targetHAL_Time.h @@ -8,6 +8,25 @@ #include -#define HAL_Time_CurrentSysTicks osKernelSysTick +#define HAL_Time_CurrentSysTicks chVTGetTimeStamp -#endif //TARGET_HAL_TIME_H +#ifdef __cplusplus +extern "C" +{ +#endif + + // Converts CMSIS sysTicks to .NET ticks (100 nanoseconds) + inline __attribute__((always_inline)) uint64_t HAL_Time_SysTicksToTime(uint64_t sysTicks) + { + // convert to microseconds from CMSIS SysTicks + // this is a rewrite of ChibiOS TIME_I2US(n) macro because it will overflow if doing the math using uint32_t + // need to convert from microseconds to 100 nanoseconds + return (((sysTicks * (uint64_t)1000000) + (int64_t)CH_CFG_ST_FREQUENCY - 1) / (int64_t)CH_CFG_ST_FREQUENCY) * + 10; + } + +#ifdef __cplusplus +} +#endif + +#endif // TARGET_HAL_TIME_H diff --git a/targets/ChibiOS/_nanoCLR/System.Device.Adc/sys_dev_adc_native_System_Device_Adc_AdcChannel.cpp b/targets/ChibiOS/_nanoCLR/System.Device.Adc/sys_dev_adc_native_System_Device_Adc_AdcChannel.cpp index 6fc35260a2..dc28629d83 100644 --- a/targets/ChibiOS/_nanoCLR/System.Device.Adc/sys_dev_adc_native_System_Device_Adc_AdcChannel.cpp +++ b/targets/ChibiOS/_nanoCLR/System.Device.Adc/sys_dev_adc_native_System_Device_Adc_AdcChannel.cpp @@ -43,7 +43,19 @@ HRESULT Library_sys_dev_adc_native_System_Device_Adc_AdcChannel::NativeReadValue // Get channel from _channelNumber field channelNumber = pThis[FIELD___channelNumber].NumericByRef().s4; - adcDefinition = AdcPortPinConfig[channelNumber]; + // channel is static? + if (channelNumber < AdcChannelCount) + { + adcDefinition = AdcPortPinConfig[channelNumber]; + } + else if (channelNumber < AdcChannelCount + RuntimeAdcChannelCount) + { + adcDefinition = RuntimeAdcPortPinConfig[channelNumber - AdcChannelCount]; + } + else + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } // we should remove form the build the ADC options that aren't implemented // plus we have to use the default to catch invalid ADC Ids diff --git a/targets/ChibiOS/_nanoCLR/System.Device.Adc/sys_dev_adc_native_System_Device_Adc_AdcController.cpp b/targets/ChibiOS/_nanoCLR/System.Device.Adc/sys_dev_adc_native_System_Device_Adc_AdcController.cpp index 8a61639045..ada26de852 100644 --- a/targets/ChibiOS/_nanoCLR/System.Device.Adc/sys_dev_adc_native_System_Device_Adc_AdcController.cpp +++ b/targets/ChibiOS/_nanoCLR/System.Device.Adc/sys_dev_adc_native_System_Device_Adc_AdcController.cpp @@ -23,7 +23,19 @@ HRESULT Library_sys_dev_adc_native_System_Device_Adc_AdcController::NativeOpenCh // Get channel from argument channel = stack.Arg1().NumericByRef().s4; - adcDefinition = AdcPortPinConfig[channel]; + // channel is static? + if (channel < AdcChannelCount) + { + adcDefinition = AdcPortPinConfig[channel]; + } + else if (channel < AdcChannelCount + RuntimeAdcChannelCount) + { + adcDefinition = RuntimeAdcPortPinConfig[channel - AdcChannelCount]; + } + else + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } // we should remove from the build the ADC options that aren't implemented // plus we have to use the default to catch invalid ADC Ids @@ -66,7 +78,7 @@ HRESULT Library_sys_dev_adc_native_System_Device_Adc_AdcController::NativeGetCha NANOCLR_HEADER(); // Return value to the managed application - stack.SetResult_I4(AdcChannelCount); + stack.SetResult_I4(AdcChannelCount + RuntimeAdcChannelCount); NANOCLR_NOCLEANUP_NOLABEL(); } diff --git a/targets/ChibiOS/_nanoCLR/System.Device.Adc/sys_dev_adc_native_target.h b/targets/ChibiOS/_nanoCLR/System.Device.Adc/sys_dev_adc_native_target.h index 8a6bb64ccf..b1f5ca5740 100644 --- a/targets/ChibiOS/_nanoCLR/System.Device.Adc/sys_dev_adc_native_target.h +++ b/targets/ChibiOS/_nanoCLR/System.Device.Adc/sys_dev_adc_native_target.h @@ -20,4 +20,7 @@ typedef struct extern const NF_PAL_ADC_PORT_PIN_CHANNEL AdcPortPinConfig[]; extern const int AdcChannelCount; +extern NF_PAL_ADC_PORT_PIN_CHANNEL *RuntimeAdcPortPinConfig; +extern uint8_t RuntimeAdcChannelCount; + #endif // SYS_DEV_ADC_NATIVE_TARGET_H diff --git a/targets/ChibiOS/_nanoCLR/System.Device.Spi/cpu_spi.cpp b/targets/ChibiOS/_nanoCLR/System.Device.Spi/cpu_spi.cpp index b6ad738e2f..c2d9d17f28 100644 --- a/targets/ChibiOS/_nanoCLR/System.Device.Spi/cpu_spi.cpp +++ b/targets/ChibiOS/_nanoCLR/System.Device.Spi/cpu_spi.cpp @@ -474,11 +474,12 @@ HRESULT CPU_SPI_nWrite_nRead( // just to satisfy the driver ceremony, no actual implementation for STM32 spiSelect(palSpi->Driver); + palSpi->ChipSelect = wrc.DeviceChipSelect; // if CS is to be controlled by the driver, set the GPIO - if (palSpi->ChipSelect >= 0) + if (wrc.DeviceChipSelect >= 0) { // assert pin based on CS active level - CPU_GPIO_SetPinState(palSpi->ChipSelect, (GpioPinValue)sdev.ChipSelectActive); + CPU_GPIO_SetPinState(wrc.DeviceChipSelect, (GpioPinValue)wrc.ChipSelectActiveState); } if (sync) @@ -550,10 +551,10 @@ HRESULT CPU_SPI_nWrite_nRead( CompleteTranfer(palSpi); // if CS is to be controlled by the driver, set the GPIO - if (palSpi->ChipSelect >= 0) + if (wrc.DeviceChipSelect >= 0) { // de-assert pin based on CS active level - CPU_GPIO_SetPinState(palSpi->ChipSelect, (GpioPinValue)sdev.ChipSelectActive); + CPU_GPIO_SetPinState(wrc.DeviceChipSelect, (GpioPinValue)wrc.ChipSelectActiveState); } } else @@ -563,10 +564,10 @@ HRESULT CPU_SPI_nWrite_nRead( // Completed on calling Spi Callback // if CS is to be controlled by the driver, set the GPIO - if (palSpi->ChipSelect >= 0) + if (wrc.DeviceChipSelect >= 0) { // assert pin based on CS active level - CPU_GPIO_SetPinState(palSpi->ChipSelect, (GpioPinValue)sdev.ChipSelectActive); + CPU_GPIO_SetPinState(wrc.DeviceChipSelect, (GpioPinValue)wrc.ChipSelectActiveState); } // this is a Async operation diff --git a/targets/ChibiOS/_nanoCLR/System.Device.Spi/sys_dev_spi_native_target.h b/targets/ChibiOS/_nanoCLR/System.Device.Spi/sys_dev_spi_native_target.h index 91ca40488a..f7f686ff4c 100644 --- a/targets/ChibiOS/_nanoCLR/System.Device.Spi/sys_dev_spi_native_target.h +++ b/targets/ChibiOS/_nanoCLR/System.Device.Spi/sys_dev_spi_native_target.h @@ -75,7 +75,7 @@ struct NF_PAL_SPI GPIO_PORT(spiDeviceConfig.DeviceChipSelect), \ spiDeviceConfig.DeviceChipSelect % 16, \ (PAL_STM32_OSPEED_HIGHEST | PAL_MODE_OUTPUT_PUSHPULL)); \ - if (spiDeviceConfig.ChipSelectActive) \ + if (spiDeviceConfig.ChipSelectActiveState) \ { \ palSetPad(GPIO_PORT(spiDeviceConfig.DeviceChipSelect), spiDeviceConfig.DeviceChipSelect % 16); \ } \ diff --git a/targets/ChibiOS/_nanoCLR/System.IO.Ports/sys_io_ser_native_System_IO_Ports_SerialPort.cpp b/targets/ChibiOS/_nanoCLR/System.IO.Ports/sys_io_ser_native_System_IO_Ports_SerialPort.cpp index 68e5d13610..463f10704d 100644 --- a/targets/ChibiOS/_nanoCLR/System.IO.Ports/sys_io_ser_native_System_IO_Ports_SerialPort.cpp +++ b/targets/ChibiOS/_nanoCLR/System.IO.Ports/sys_io_ser_native_System_IO_Ports_SerialPort.cpp @@ -216,8 +216,8 @@ static void RxChar(UARTDriver *uartp, uint16_t c) // store this into the UART Rx buffer - // push char to ring buffer - // don't care about the success of the operation, if it's full we are droping the char anyway + // push char to the ring buffer + // ignore the success of the operation, if it's full we are dropping the char anyway. palUart->RxRingBuffer.Push((uint8_t)c); // is there a read operation going on? @@ -245,11 +245,12 @@ static void RxChar(UARTDriver *uartp, uint16_t c) // no read operation ongoing, so fire an event, if the available bytes are above the threshold if (palUart->RxRingBuffer.Length() >= palUart->ReceivedBytesThreshold) { - // post a managed event with the port index and event code (check if this is the watch char or just another - // another) - // TODO: check if callbacks are registered so this is called only if there is anyone listening otherwise - // don't bother for that to happen ChibiOS callback has to accept arg which we would passing the GpioPin - // CLR_RT_HeapBlock (see Gpio handler) check http://www.chibios.com/forum/viewtopic.php?f=36&t=4798 + // Post a managed event with the port index and event code (check if there is a watch + // char in the buffer or just any char) + // FIXME: check if callbacks are registered so this is called only if there is anyone listening otherwise + // don't bother. + // TODO: For that to happen ChibiOS callback has to accept arg which we would passing the GpioPin + // Notes: CLR_RT_HeapBlock (Gpio handler) See: http://www.chibios.com/forum/viewtopic.php?f=36&t=4798 PostManagedEvent( EVENT_SERIAL, 0, diff --git a/targets/ChibiOS/_nanoCLR/nanoCRT.cpp b/targets/ChibiOS/_nanoCLR/nanoCRT.cpp index 6e4189e2f8..ec2ab722f4 100644 --- a/targets/ChibiOS/_nanoCLR/nanoCRT.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoCRT.cpp @@ -12,11 +12,10 @@ #if !defined(BUILD_RTM) -void hal_fprintf_SetLoggingCallback( LOGGING_CALLBACK fpn ) +void hal_fprintf_SetLoggingCallback(LOGGING_CALLBACK fpn) { (void)fpn; NATIVE_PROFILE_PAL_CRT(); - } #endif @@ -25,61 +24,64 @@ void hal_fprintf_SetLoggingCallback( LOGGING_CALLBACK fpn ) #if defined(PLATFORM_EMULATED_FLOATINGPOINT) -// no floating point, fixed point +// no floating point, fixed point -int hal_snprintf_float( char* buffer, size_t len, const char* format, int32_t f ) +int hal_snprintf_float(char *buffer, size_t len, const char *format, int32_t f) { NATIVE_PROFILE_PAL_CRT(); - uint32_t i ; - uint32_t dec; + uint32_t i; + uint32_t dec; - if ( f < 0 ) + if (f < 0) { // negative number - i = (uint32_t) -f ; - dec = i & (( 1<>HAL_FLOAT_SHIFT); - - if (dec !=0) dec = (dec * (uint32_t)HAL_FLOAT_PRECISION + (1<< (HAL_FLOAT_SHIFT-1))) >>HAL_FLOAT_SHIFT; + i = (uint32_t)-f; + dec = i & ((1 << HAL_FLOAT_SHIFT) - 1); + i = (i >> HAL_FLOAT_SHIFT); - return hal_snprintf( buffer, len, "-%d.%03u", i, (uint32_t)dec); + if (dec != 0) + dec = (dec * (uint32_t)HAL_FLOAT_PRECISION + (1 << (HAL_FLOAT_SHIFT - 1))) >> HAL_FLOAT_SHIFT; + return hal_snprintf(buffer, len, "-%d.%03u", i, (uint32_t)dec); } else { // positive number - i = (uint32_t) f ; - dec = f & (( 1<>HAL_FLOAT_SHIFT); + i = (uint32_t)f; + dec = f & ((1 << HAL_FLOAT_SHIFT) - 1); + i = (uint32_t)(i >> HAL_FLOAT_SHIFT); - if (dec !=0) dec = (dec * (uint32_t)HAL_FLOAT_PRECISION + (1<< (HAL_FLOAT_SHIFT-1))) >>HAL_FLOAT_SHIFT; + if (dec != 0) + dec = (dec * (uint32_t)HAL_FLOAT_PRECISION + (1 << (HAL_FLOAT_SHIFT - 1))) >> HAL_FLOAT_SHIFT; - return hal_snprintf( buffer, len, "%d.%03u", i, (uint32_t)dec); + return hal_snprintf(buffer, len, "%d.%03u", i, (uint32_t)dec); } } -int hal_snprintf_double( char* buffer, size_t len, const char* format, int64_t& d ) +int hal_snprintf_double(char *buffer, size_t len, const char *format, int64_t &d) { NATIVE_PROFILE_PAL_CRT(); uint64_t i; - uint32_t dec; // 32 bit is enough for decimal part + uint32_t dec; // 32 bit is enough for decimal part - if ( d < 0 ) + if (d < 0) { // negative number i = (uint64_t)-d; - - i += ((1 << (HAL_DOUBLE_SHIFT-1)) / HAL_DOUBLE_PRECISION); // add broad part of rounding increment before split - dec = i & (( 1<> HAL_DOUBLE_SHIFT ; + i += + ((1 << (HAL_DOUBLE_SHIFT - 1)) / HAL_DOUBLE_PRECISION); // add broad part of rounding increment before split - if (dec !=0) dec = (dec * HAL_DOUBLE_PRECISION + ((1 << (HAL_DOUBLE_SHIFT-1)) % HAL_DOUBLE_PRECISION)) >> HAL_DOUBLE_SHIFT; + dec = i & ((1 << HAL_DOUBLE_SHIFT) - 1); + i = i >> HAL_DOUBLE_SHIFT; - return hal_snprintf( buffer, len, "-%lld.%04u", (int64_t)i, (uint32_t)dec); + if (dec != 0) + dec = (dec * HAL_DOUBLE_PRECISION + ((1 << (HAL_DOUBLE_SHIFT - 1)) % HAL_DOUBLE_PRECISION)) >> + HAL_DOUBLE_SHIFT; + return hal_snprintf(buffer, len, "-%lld.%04u", (int64_t)i, (uint32_t)dec); } else { @@ -87,14 +89,17 @@ int hal_snprintf_double( char* buffer, size_t len, const char* format, int64_t& // positive number i = (uint64_t)d; - i += ((1 << (HAL_DOUBLE_SHIFT-1)) / HAL_DOUBLE_PRECISION); // add broad part of rounding increment before split + i += + ((1 << (HAL_DOUBLE_SHIFT - 1)) / HAL_DOUBLE_PRECISION); // add broad part of rounding increment before split - dec = i & (( 1<> HAL_DOUBLE_SHIFT; - - if (dec !=0) dec = (dec * HAL_DOUBLE_PRECISION + ((1 << (HAL_DOUBLE_SHIFT-1)) % HAL_DOUBLE_PRECISION)) >> HAL_DOUBLE_SHIFT; - return hal_snprintf( buffer, len, "%lld.%04u", (int64_t)i, (uint32_t)dec); + if (dec != 0) + dec = (dec * HAL_DOUBLE_PRECISION + ((1 << (HAL_DOUBLE_SHIFT - 1)) % HAL_DOUBLE_PRECISION)) >> + HAL_DOUBLE_SHIFT; + + return hal_snprintf(buffer, len, "%lld.%04u", (int64_t)i, (uint32_t)dec); } } @@ -103,52 +108,63 @@ int hal_snprintf_double( char* buffer, size_t len, const char* format, int64_t& #endif // because debug_printf needs to be called in both C and C++ we need a proxy to allow it to be called in 'C' -extern "C" { +extern "C" +{ #if !defined(BUILD_RTM) - - void debug_printf(const char* format, ...) + + void debug_printf(const char *format, ...) { char buffer[256]; va_list arg_ptr; - - va_start( arg_ptr, format ); - - int len = vsnprintf( buffer, sizeof(buffer)-1, format, arg_ptr ); - - DebuggerPort_Write( HalSystemConfig.stdio, buffer, len, 0 ); // skip null terminator - - va_end( arg_ptr ); + + va_start(arg_ptr, format); + + int len = vsnprintf(buffer, sizeof(buffer) - 1, format, arg_ptr); + + DebuggerPort_Write(HalSystemConfig.stdio, buffer, len, 0); // skip null terminator + + va_end(arg_ptr); } -#else - __inline void debug_printf( const char *format, ... ) {} -#endif // !defined(BUILD_RTM) +#endif // !defined(BUILD_RTM) } -int hal_strcpy_s ( char* strDst, size_t sizeInBytes, const char* strSrc ) +int hal_strcpy_s(char *strDst, size_t sizeInBytes, const char *strSrc) { NATIVE_PROFILE_PAL_CRT(); #undef strcpy size_t len; - if(strDst == NULL || strSrc == NULL || sizeInBytes == 0) {_ASSERTE(FALSE); return 1;} - + if (strDst == NULL || strSrc == NULL || sizeInBytes == 0) + { + _ASSERTE(FALSE); + return 1; + } + len = hal_strlen_s(strSrc); - if(sizeInBytes < len + 1) {_ASSERTE(FALSE); return 1;} + if (sizeInBytes < len + 1) + { + _ASSERTE(FALSE); + return 1; + } - strcpy( strDst, strSrc ); + strcpy(strDst, strSrc); return 0; -#define strcpy DoNotUse_*strcpy [] +#define strcpy DoNotUse_ *strcpy[] } -int hal_strncpy_s ( char* strDst, size_t sizeInBytes, const char* strSrc, size_t count ) +int hal_strncpy_s(char *strDst, size_t sizeInBytes, const char *strSrc, size_t count) { NATIVE_PROFILE_PAL_CRT(); #undef strncpy - if(strDst == NULL || strSrc == NULL || sizeInBytes == 0) {_ASSERTE(FALSE); return 1;} - + if (strDst == NULL || strSrc == NULL || sizeInBytes == 0) + { + _ASSERTE(FALSE); + return 1; + } + if (sizeInBytes < count + 1) { _ASSERTE(FALSE); @@ -157,49 +173,53 @@ int hal_strncpy_s ( char* strDst, size_t sizeInBytes, const char* strSrc, size_t } strDst[count] = 0; - strncpy( strDst, strSrc, count ); + strncpy(strDst, strSrc, count); return 0; -#define strncpy DoNotUse_*strncpy [] +#define strncpy DoNotUse_ *strncpy[] } -size_t hal_strlen_s (const char * str) +size_t hal_strlen_s(const char *str) { NATIVE_PROFILE_PAL_CRT(); const char *eos = str; - while( *eos++ ) ; - return( eos - str - 1 ); + while (*eos++) + ; + return (eos - str - 1); } -int hal_strncmp_s ( const char* str1, const char* str2, size_t num ) +int hal_strncmp_s(const char *str1, const char *str2, size_t num) { NATIVE_PROFILE_PAL_CRT(); #undef strncmp - if(str1 == NULL || str2 == NULL) {_ASSERTE(FALSE); return 1;} - - return strncmp( str1, str2, num ); + if (str1 == NULL || str2 == NULL) + { + _ASSERTE(FALSE); + return 1; + } + + return strncmp(str1, str2, num); -#define strncmp DoNotUse_*strncmp [] +#define strncmp DoNotUse_ *strncmp[] } // Compares 2 ASCII strings case insensitive. Does not take locale into account. -int hal_stricmp( const char * dst, const char * src ) +int hal_stricmp(const char *dst, const char *src) { int f = 0, l = 0; do { - if ( ((f = (unsigned char)(*(dst++))) >= 'A') && (f <= 'Z') ) + if (((f = (unsigned char)(*(dst++))) >= 'A') && (f <= 'Z')) { f -= 'A' - 'a'; } - if ( ((l = (unsigned char)(*(src++))) >= 'A') && (l <= 'Z') ) + if (((l = (unsigned char)(*(src++))) >= 'A') && (l <= 'Z')) { l -= 'A' - 'a'; } - } - while ( f && (f == l) ); + } while (f && (f == l)); - return(f - l); + return (f - l); } diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Device.Can/nf_device_can_native_nanoFramework_Device_Can_CanController.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Device.Can/nf_device_can_native_nanoFramework_Device_Can_CanController.cpp index 7368e94e60..ab6d38883e 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Device.Can/nf_device_can_native_nanoFramework_Device_Can_CanController.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Device.Can/nf_device_can_native_nanoFramework_Device_Can_CanController.cpp @@ -249,18 +249,15 @@ HRESULT Library_nf_device_can_native_nanoFramework_Device_Can_CanController:: *id = canFrame.EID; } - // get data if any - if (canFrame.data8) - { - CLR_RT_HeapBlock &dataArrayField = canMessage[ManagedCanMessage::FIELD___message]; - // create an array of - NANOCLR_CHECK_HRESULT( - CLR_RT_HeapBlock_Array::CreateInstance(dataArrayField, 8, g_CLR_RT_WellKnownTypes.m_UInt8)); - - // get a pointer to the first object in the array - CLR_UINT8 *dataBuffer = (CLR_UINT8 *)(dataArrayField.DereferenceArray()->GetFirstElement()); - memcpy(dataBuffer, &canFrame.data8[0], 8); - } + // grab data and copy over to managed array + CLR_RT_HeapBlock &dataArrayField = canMessage[ManagedCanMessage::FIELD___message]; + // create an array of + NANOCLR_CHECK_HRESULT( + CLR_RT_HeapBlock_Array::CreateInstance(dataArrayField, 8, g_CLR_RT_WellKnownTypes.m_UInt8)); + + // get a pointer to the first object in the array + CLR_UINT8 *dataBuffer = (CLR_UINT8 *)(dataArrayField.DereferenceArray()->GetFirstElement()); + memcpy(dataBuffer, &canFrame.data8[0], 8); } else { diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Stm32/nf_hardware_stm32_native.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Stm32/nf_hardware_stm32_native.cpp index b2d2f64596..6fa2ac9f7d 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Stm32/nf_hardware_stm32_native.cpp +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Stm32/nf_hardware_stm32_native.cpp @@ -37,6 +37,18 @@ static const CLR_RT_MethodHandler method_lookup[] = Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_BackupMemory::ReadBytes___STATIC__VOID__U4__SZARRAY_U1, Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_BackupMemory::WriteBytes___STATIC__VOID__U4__SZARRAY_U1, Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_BackupMemory::GetSize___STATIC__I4, + Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_Configuration::ConfigurePin___STATIC__VOID__I4__nanoFrameworkHardwareStm32GpioConfiguration, + Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_Configuration::AddAdcChannel___STATIC__U4__U4__U4__U4, + Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_Configuration::RemoveAdcChannel___STATIC__VOID__U4, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, NULL, Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_Power::get_WakeupReason___STATIC__nanoFrameworkHardwareStm32PowerWakeupReasonType, Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_Power::DisableWakeupPin___STATIC__VOID__nanoFrameworkHardwareStm32PowerWakeupPin, @@ -56,9 +68,9 @@ static const CLR_RT_MethodHandler method_lookup[] = const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Stm32 = { "nanoFramework.Hardware.Stm32", - 0x0874B6FE, + 0xFE16F347, method_lookup, - { 100, 0, 4, 4 } + { 100, 0, 5, 1 } }; // clang-format on diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Stm32/nf_hardware_stm32_native.h b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Stm32/nf_hardware_stm32_native.h index 76da2527fe..a35058b8c5 100644 --- a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Stm32/nf_hardware_stm32_native.h +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Stm32/nf_hardware_stm32_native.h @@ -10,6 +10,31 @@ #include #include +typedef enum __nfpack GpioConfiguration_IOMode +{ + GpioConfiguration_IOMode_Input = 0, + GpioConfiguration_IOMode_Output = 1, + GpioConfiguration_IOMode_AlternateFunction = 2, + GpioConfiguration_IOMode_Analog = 4, + GpioConfiguration_IOMode_OutputPushPull = 1, + GpioConfiguration_IOMode_OutputOpenDrain = 17, +} GpioConfiguration_IOMode; + +typedef enum __nfpack GpioConfiguration_PullUpDownActivation +{ + GpioConfiguration_PullUpDownActivation_None = 0, + GpioConfiguration_PullUpDownActivation_PullUp = 1, + GpioConfiguration_PullUpDownActivation_PullDown = 2, +} GpioConfiguration_PullUpDownActivation; + +typedef enum __nfpack GpioConfiguration_Speed +{ + GpioConfiguration_Speed_Low = 0, + GpioConfiguration_Speed_Medium = 1, + GpioConfiguration_Speed_High = 2, + GpioConfiguration_Speed_VeryHigh = 3, +} GpioConfiguration_Speed; + struct Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_BackupMemory { static const int FIELD_STATIC___size = 0; @@ -25,6 +50,25 @@ struct Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_BackupMemor static const int BACKUP_SIZE = RTC_BKP_NUMBER * sizeof(RTC_BKP0R_Msk); }; +struct Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_Configuration +{ + NANOCLR_NATIVE_DECLARE(ConfigurePin___STATIC__VOID__I4__nanoFrameworkHardwareStm32GpioConfiguration); + NANOCLR_NATIVE_DECLARE(AddAdcChannel___STATIC__U4__U4__U4__U4); + NANOCLR_NATIVE_DECLARE(RemoveAdcChannel___STATIC__VOID__U4); + + //--// +}; + +struct Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_GpioConfiguration +{ + static const int FIELD___mode = 1; + static const int FIELD___pullUpDown = 2; + static const int FIELD___speed = 3; + static const int FIELD___alternateFunction = 4; + + //--// +}; + struct Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_Power { NANOCLR_NATIVE_DECLARE(get_WakeupReason___STATIC__nanoFrameworkHardwareStm32PowerWakeupReasonType); @@ -33,7 +77,6 @@ struct Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_Power NANOCLR_NATIVE_DECLARE(NativeEnterStandbyMode___STATIC__VOID); //--// - }; struct Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_RTC @@ -42,7 +85,6 @@ struct Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_RTC NANOCLR_NATIVE_DECLARE(Native_RTC_SetAlarm___STATIC__VOID__U1__U1__U1__U1); //--// - }; struct Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_Utilities @@ -56,7 +98,6 @@ struct Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_Utilities NANOCLR_NATIVE_DECLARE(NativeGetDeviceRevisionId___STATIC__U4); //--// - }; extern const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Stm32; diff --git a/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Stm32/nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_Configuration.cpp b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Stm32/nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_Configuration.cpp new file mode 100644 index 0000000000..2b377d076c --- /dev/null +++ b/targets/ChibiOS/_nanoCLR/nanoFramework.Hardware.Stm32/nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_Configuration.cpp @@ -0,0 +1,249 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include "nf_hardware_stm32_native.h" +#include + +#if defined(HAL_USE_ADC) && (HAL_USE_ADC == TRUE) +#include + +NF_PAL_ADC_PORT_PIN_CHANNEL *RuntimeAdcPortPinConfig = NULL; +uint8_t RuntimeAdcChannelCount = 0; + +int8_t GetNextFreeAdcChannel(NF_PAL_ADC_PORT_PIN_CHANNEL *&newChannel); + +#endif + +typedef Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_GpioConfiguration GpioConfiguration; + +HRESULT Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_Configuration:: + ConfigurePin___STATIC__VOID__I4__nanoFrameworkHardwareStm32GpioConfiguration(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + GpioConfiguration_IOMode mode; + GpioConfiguration_PullUpDownActivation pullUpDown; + GpioConfiguration_Speed speed; + uint8_t alternateFunction; + uint8_t pinNumber; + stm32_gpio_t *port; + int16_t pad; + + CLR_RT_HeapBlock *gpioConfiguration; + + pinNumber = (uint8_t)stack.Arg0().NumericByRef().s4; + + // decode pin number to get a ChibiOS PAL IoLine from our "encoded" pin number + port = GPIO_PORT(pinNumber); + pad = pinNumber % 16; + + // get a pointer to the managed GPIO configuration object instance + gpioConfiguration = stack.Arg1().Dereference(); + + // grab all the fields from the managed object + mode = (GpioConfiguration_IOMode)gpioConfiguration[GpioConfiguration::FIELD___mode].NumericByRef().s4; + pullUpDown = (GpioConfiguration_PullUpDownActivation)gpioConfiguration[GpioConfiguration::FIELD___pullUpDown] + .NumericByRef() + .s4; + // ChibiOS encoding differs from STM32 HAL encoding + pullUpDown = (GpioConfiguration_PullUpDownActivation)(pullUpDown << 5); + + speed = (GpioConfiguration_Speed)gpioConfiguration[GpioConfiguration::FIELD___speed].NumericByRef().s4; + // ChibiOS encoding differs from STM32 HAL encoding + speed = (GpioConfiguration_Speed)(speed << 3); + + alternateFunction = (uint8_t)gpioConfiguration[GpioConfiguration::FIELD___alternateFunction].NumericByRef().s4; + + // configure the pin + palSetPadMode(port, pad, mode | pullUpDown | speed | (PAL_MODE_ALTERNATE(alternateFunction))); + + NANOCLR_NOCLEANUP_NOLABEL(); +} + +HRESULT Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_Configuration:: + AddAdcChannel___STATIC__U4__U4__U4__U4(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +#if defined(HAL_USE_ADC) && (HAL_USE_ADC == TRUE) + + uint8_t adc; + uint8_t adcChannel; + uint8_t pinNumber; + int8_t newChannelIndex; + NF_PAL_ADC_PORT_PIN_CHANNEL *newChannel; + + // grab arguments + adc = (uint8_t)stack.Arg0().NumericByRef().u4; + adcChannel = (uint8_t)stack.Arg1().NumericByRef().u4; + pinNumber = (uint8_t)stack.Arg2().NumericByRef().u4; + + // validate arguments + switch (adc) + { +#if STM32_ADC_USE_ADC1 + case 1: + // all good + break; +#endif + +#if STM32_ADC_USE_ADC2 + case 2: + // all good + break; +#endif + +#if STM32_ADC_USE_ADC3 + case 3: + // all good + break; +#endif + + default: + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + if (adcChannel > 15) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + // add channel to the list + newChannelIndex = GetNextFreeAdcChannel(newChannel); + + // sanity check + if (newChannelIndex < 0) + { + NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_MEMORY); + } + + // copy channel definition + newChannel->adcIndex = adc; + newChannel->adcChannel = adcChannel; + newChannel->portId = GPIO_PORT(pinNumber); + newChannel->pin = pinNumber % 16; + + // need to adjust channel index to account for the ones declared in the build + newChannelIndex += AdcChannelCount; + + // return the index of the channel + stack.SetResult_U4(newChannelIndex); + +#else + (void)stack; + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); +#endif + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_Configuration:: + RemoveAdcChannel___STATIC__VOID__U4(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +#if defined(HAL_USE_ADC) && (HAL_USE_ADC == TRUE) + uint8_t channel; + + // grab arguments + channel = (uint8_t)stack.Arg0().NumericByRef().u4; + + // need to adjust channel index to account for the ones declared in the build + channel -= AdcChannelCount; + + // check if this channel definition is valid + if (channel >= RuntimeAdcChannelCount) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + // cler the channel definition + memset(&RuntimeAdcPortPinConfig[channel], 0, sizeof(NF_PAL_ADC_PORT_PIN_CHANNEL)); + +#else + (void)stack; + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); +#endif + + NANOCLR_NOCLEANUP(); +} + +#if defined(HAL_USE_ADC) && (HAL_USE_ADC == TRUE) + +/// @brief Creates a new ADC channel definition and adds it to the list of channels +/// @param newChannel Pointer to the new channel definition +/// @return Index of the new channel definition. -1 if no more channels can be added. +int8_t GetNextFreeAdcChannel(NF_PAL_ADC_PORT_PIN_CHANNEL *&newChannel) +{ + int8_t channelIndex = -1; + newChannel = NULL; + + if (RuntimeAdcPortPinConfig == NULL) + { + RuntimeAdcPortPinConfig = (NF_PAL_ADC_PORT_PIN_CHANNEL *)platform_malloc(sizeof(NF_PAL_ADC_PORT_PIN_CHANNEL)); + + // sanity check + if (RuntimeAdcPortPinConfig != NULL) + { + // clear memory + memset(RuntimeAdcPortPinConfig, 0, sizeof(NF_PAL_ADC_PORT_PIN_CHANNEL)); + + // update the number of channels + RuntimeAdcChannelCount = 1; + } + } + + // find the first free channel + for (int8_t i = 0; i < RuntimeAdcChannelCount; i++) + { + if (RuntimeAdcPortPinConfig[i].adcIndex == 0) + { + // found a free channel + channelIndex = i; + newChannel = &RuntimeAdcPortPinConfig[i]; + } + } + + if (channelIndex == -1) + { + // need to reallocate memory + + // allocate new memory block + NF_PAL_ADC_PORT_PIN_CHANNEL *newRuntimeAdcPortPinConfig = (NF_PAL_ADC_PORT_PIN_CHANNEL *)platform_malloc( + (RuntimeAdcChannelCount + 1) * sizeof(NF_PAL_ADC_PORT_PIN_CHANNEL)); + + // sanity check + if (RuntimeAdcPortPinConfig != NULL) + { + // update the number of channels + RuntimeAdcChannelCount++; + + // copy the old channels to the new memory block + memcpy( + newRuntimeAdcPortPinConfig, + RuntimeAdcPortPinConfig, + RuntimeAdcChannelCount * sizeof(NF_PAL_ADC_PORT_PIN_CHANNEL)); + + // free the old memory block + platform_free(RuntimeAdcPortPinConfig); + + // set the new memory block + RuntimeAdcPortPinConfig = newRuntimeAdcPortPinConfig; + + // clear the new channel + memset(&RuntimeAdcPortPinConfig[RuntimeAdcChannelCount - 1], 0, sizeof(NF_PAL_ADC_PORT_PIN_CHANNEL)); + + // set pointer to the new channel + newChannel = &RuntimeAdcPortPinConfig[RuntimeAdcChannelCount - 1]; + + // set the index of the new channel + channelIndex = RuntimeAdcChannelCount - 1; + } + } + + return channelIndex; +} + +#endif diff --git a/targets/ChibiOS/_nanoCLR/targetHAL.cpp b/targets/ChibiOS/_nanoCLR/targetHAL.cpp index b0109bd703..8fb59b3253 100644 --- a/targets/ChibiOS/_nanoCLR/targetHAL.cpp +++ b/targets/ChibiOS/_nanoCLR/targetHAL.cpp @@ -40,9 +40,9 @@ extern "C" nanoHAL_Initialize(); } - void nanoHAL_Uninitialize_C() + void nanoHAL_Uninitialize_C(bool isPoweringDown) { - nanoHAL_Uninitialize(); + nanoHAL_Uninitialize(isPoweringDown); } } @@ -155,8 +155,10 @@ void nanoHAL_Initialize() Network_Initialize(); } -void nanoHAL_Uninitialize() +void nanoHAL_Uninitialize(bool isPoweringDown) { + (void)isPoweringDown; + // release the global mutex, just in case it's locked somewhere // chMtxUnlock(&interpreterGlobalMutex); diff --git a/targets/ChibiOS/_nanoCLR/targetHAL_Power.c b/targets/ChibiOS/_nanoCLR/targetHAL_Power.c index f360143a20..87ecb08657 100644 --- a/targets/ChibiOS/_nanoCLR/targetHAL_Power.c +++ b/targets/ChibiOS/_nanoCLR/targetHAL_Power.c @@ -11,6 +11,7 @@ #include #include #include +#include #if (STM32_USE_FSMC_SDRAM == TRUE) #include @@ -46,8 +47,11 @@ void CPU_SetPowerMode(PowerLevel_type powerLevel) switch (powerLevel) { case PowerLevel__Off: + +#if (HAL_USE_WDG == TRUE) // stop watchdog wdgStop(&WDGD1); +#endif // shutdown memory #if (STM32_USE_FSMC_SDRAM == TRUE) @@ -69,7 +73,7 @@ void CPU_SetPowerMode(PowerLevel_type powerLevel) #endif // gracefully shutdown everything - nanoHAL_Uninitialize_C(); + nanoHAL_Uninitialize_C(true); chSysDisable(); diff --git a/targets/ESP32/CMakeLists.txt b/targets/ESP32/CMakeLists.txt index e7ed034807..e576975c99 100644 --- a/targets/ESP32/CMakeLists.txt +++ b/targets/ESP32/CMakeLists.txt @@ -9,9 +9,21 @@ include(binutils.ESP32) # Set target series in lower case nf_set_esp32_target_series() -# checking unsupported features -if(${TARGET_SERIES_SHORT} STREQUAL "esp32c3" AND ${API_nanoFramework.Hardware.Esp32.Rmt}) - message(FATAL_ERROR "Currently RMT is not supported for ESP32-C3 builds") +# Options for Wire Protocol channel +option(HAL_WP_USE_SERIAL "option to use serial port (UART) to route Wire Protocol") +option(HAL_WP_USE_USB_CDC "option to use USB CDC to route Wire Protocol") + +if(HAL_WP_USE_SERIAL) + message(STATUS "Wire Protocol will use serial port (UART).") + set(HAL_WP_USE_SERIAL_OPTION TRUE CACHE INTERNAL "set HAL_WP_USE_SERIAL") + set(HAL_WP_USE_USB_CDC_OPTION FALSE CACHE INTERNAL "set HAL_WP_USE_USB_CDC") +elseif(HAL_WP_USE_USB_CDC) + message(STATUS "Wire Protocol will use USB CDC.") + set(HAL_WP_USE_SERIAL_OPTION FALSE CACHE INTERNAL "set HAL_WP_USE_SERIAL") + set(HAL_WP_USE_USB_CDC_OPTION TRUE CACHE INTERNAL "set HAL_WP_USE_USB_CDC") +else() + set(HAL_WP_USE_SERIAL_OPTION FALSE CACHE INTERNAL "set HAL_WP_USE_SERIAL") + set(HAL_WP_USE_USB_CDC_OPTION FALSE CACHE INTERNAL "set HAL_WP_USE_USB_CDC") endif() # option to reserve RAM for IDF allocator @@ -48,7 +60,7 @@ endif() # WHEN CHANGING THIS MAKE SURE TO UPDATE: # 1. the dev containers # 2. ref in AZDO pipeline yaml in Community Targets repo -set(ESP32_IDF_TAG "4.4.3" CACHE INTERNAL "ESP32 IDF tag") +set(ESP32_IDF_TAG "4.4.5" CACHE INTERNAL "ESP32 IDF tag") if(NO_ESP32_IDF_PATH) # no ESP32 IDF source specified, download it from official repo @@ -85,9 +97,12 @@ list(APPEND CMAKE_MODULE_PATH ${esp32_idf_SOURCE_DIR}/CMake) # parse IDF path to allow proper comparison with environment variable string(REPLACE "\\" "/" IDF_SOURCE_DIR_PATH "$ENV{IDF_PATH}") +# need to lowercase both paths to compare them +string(TOLOWER "${IDF_SOURCE_DIR_PATH}" IDF_SOURCE_DIR_PATH_LOWER ) +string(TOLOWER "${esp32_idf_SOURCE_DIR}" esp32_idf_SOURCE_DIR_LOWER ) + # check IDF_PATH environment variable -if(NOT "${IDF_SOURCE_DIR_PATH}" STREQUAL "${esp32_idf_SOURCE_DIR}") - +if(NOT "${IDF_SOURCE_DIR_PATH_LOWER}" STREQUAL "${esp32_idf_SOURCE_DIR_LOWER}") # variable is set and it's different from the current location # can't continue @@ -96,7 +111,15 @@ if(NOT "${IDF_SOURCE_DIR_PATH}" STREQUAL "${esp32_idf_SOURCE_DIR}") else() message(STATUS "\n-- IDF_PATH is '${IDF_SOURCE_DIR_PATH}'\r") + # on Windows need to make sure the path has the same case as the actual path + if(CMAKE_HOST_WIN32) + if(NOT "${IDF_SOURCE_DIR_PATH}" STREQUAL "${esp32_idf_SOURCE_DIR}") + message(FATAL_ERROR "ESP32_IDF_PATH var is '${esp32_idf_SOURCE_DIR}'. It's using a different case than the actual path. Please fix this.") + endif() + endif() + set(IDF_PATH_CMAKED ${IDF_SOURCE_DIR_PATH} CACHE INTERNAL "CMake formated IDF path") + endif() # if using FatFS need to remove IDF ffconfig.h so it can pick ours @@ -106,15 +129,17 @@ if(NF_FEATURE_HAS_SDCARD) ) else() # if not using FatFS need to check if IDF ffconfig.h exists - if(NOT(IS_ABSOLUTE ${esp32_idf_SOURCE_DIR}/components/fatfs/src/ffconf.h)) - message(FATAL_ERROR "'${esp32_idf_SOURCE_DIR}/components/fatfs/src/ffconf.h' file is missing from IDF\rIf this was deleted on a previous build using SDCard, just revert the change and restore the file.") + if(EXISTS ${esp32_idf_SOURCE_DIR}/components/fatfs/src/ffconf.h) + # all good, ffconf.h still there + else() + message(FATAL_ERROR "\r\n*******************************************************************\r\n'${esp32_idf_SOURCE_DIR}/components/fatfs/src/ffconf.h' file is missing from IDF\r\nIf this was deleted on a previous build using SDCard, just revert the change and restore the file.\r\n*******************************************************************\r\n") endif() endif() # target folder was added in main CMakeList # force this to ON -set(NF_SECURITY_MBEDTLS ON CACHE INTERNAL "mbedTLS must be ON for IDF build") +set(NF_SECURITY_MBEDTLS ON CACHE INTERNAL "MbedTLS must be ON for IDF build") # add platform dirs add_subdirectory(_common) diff --git a/targets/ESP32/CMakePresets.json b/targets/ESP32/CMakePresets.json new file mode 100644 index 0000000000..1e4be33350 --- /dev/null +++ b/targets/ESP32/CMakePresets.json @@ -0,0 +1,934 @@ +{ + "version": 4, + "include": [ + "../../CMake/xtensa-esp32.json", + "../../CMake/xtensa-esp32c3.json", + "../../CMake/xtensa-esp32s2.json", + "../../CMake/xtensa-esp32s3.json", + "../../config/user-tools-repos.json", + "../../config/user-prefs.json" + ], + "configurePresets": [ + { + "name": "ESP32_PSRAM_REV0", + "inherits": [ + "xtensa-esp32-preset", + "user-tools-repos", + "user-prefs" + ], + "hidden": false, + "cacheVariables": { + "SDK_CONFIG_FILE": "", + "NF_BUILD_RTM": "OFF", + "NF_FEATURE_DEBUGGER": "ON", + "NF_FEATURE_RTC": "ON", + "NF_FEATURE_HAS_SDCARD": "ON", + "API_System.IO.FileSystem": "ON", + "API_System.Math": "ON", + "API_System.Device.Adc": "ON", + "API_System.Device.Dac": "ON", + "API_System.Device.Gpio": "ON", + "API_System.Device.I2c": "ON", + "API_System.Device.Pwm": "ON", + "API_System.IO.Ports": "ON", + "API_System.Device.Spi": "ON", + "API_nanoFramework.Device.OneWire": "ON", + "API_nanoFramework.ResourceManager": "ON", + "API_nanoFramework.System.Collections": "ON", + "API_nanoFramework.System.Text": "ON" + } + }, + { + "name": "ESP32_PSRAM_REV3", + "inherits": [ + "xtensa-esp32-preset", + "user-tools-repos", + "user-prefs" + ], + "hidden": false, + "cacheVariables": { + "TARGET_NAME": "${presetName}", + "SDK_CONFIG_FILE": "sdkconfig.default_rev3.esp32", + "NF_BUILD_RTM": "OFF", + "NF_FEATURE_DEBUGGER": "ON", + "NF_FEATURE_RTC": "ON", + "NF_FEATURE_HAS_SDCARD": "ON", + "API_System.IO.FileSystem": "ON", + "API_nanoFramework.Device.OneWire": "ON", + "API_nanoFramework.ResourceManager": "ON", + "API_nanoFramework.System.Collections": "ON", + "API_nanoFramework.System.Text": "ON" + } + }, + { + "name": "ESP32_REV0", + "inherits": [ + "xtensa-esp32-preset", + "user-tools-repos", + "user-prefs" + ], + "hidden": false, + "cacheVariables": { + "TARGET_NAME": "${presetName}", + "SDK_CONFIG_FILE": "sdkconfig.default_nopsram.esp32", + "NF_BUILD_RTM": "OFF", + "NF_FEATURE_DEBUGGER": "ON", + "NF_FEATURE_RTC": "ON", + "NF_FEATURE_HAS_SDCARD": "ON", + "API_System.Net": "ON", + "API_System.IO.FileSystem": "ON", + "API_System.Math": "ON", + "API_System.Device.Adc": "ON", + "API_System.Device.Dac": "ON", + "API_System.Device.Gpio": "ON", + "API_System.Device.I2c": "ON", + "API_System.Device.Pwm": "ON", + "API_System.IO.Ports": "ON", + "API_System.Device.Spi": "ON", + "API_nanoFramework.Device.OneWire": "ON" + } + }, + { + "name": "ESP32_REV3", + "inherits": [ + "xtensa-esp32-preset", + "user-tools-repos", + "user-prefs" + ], + "hidden": false, + "cacheVariables": { + "TARGET_NAME": "${presetName}", + "SDK_CONFIG_FILE": "sdkconfig.default_nopsram_rev3.esp32", + "NF_BUILD_RTM": "OFF", + "NF_FEATURE_DEBUGGER": "ON", + "NF_FEATURE_RTC": "ON", + "NF_FEATURE_HAS_SDCARD": "ON", + "API_System.IO.FileSystem": "ON", + "API_nanoFramework.Device.OneWire": "ON" + } + }, + { + "name": "ESP32_PSRAM_XTAL26_REV0", + "inherits": [ + "xtensa-esp32-preset", + "user-tools-repos", + "user-prefs" + ], + "hidden": false, + "cacheVariables": { + "TARGET_NAME": "${presetName}", + "SDK_CONFIG_FILE": "", + "ESP32_XTAL_FREQ_26": "ON", + "NF_BUILD_RTM": "OFF", + "NF_FEATURE_DEBUGGER": "ON", + "NF_FEATURE_RTC": "ON", + "NF_FEATURE_HAS_SDCARD": "ON", + "API_System.IO.FileSystem": "ON", + "API_nanoFramework.Device.OneWire": "ON" + } + }, + { + "name": "ESP32_BLE_REV0", + "inherits": [ + "xtensa-esp32-preset", + "user-tools-repos", + "user-prefs" + ], + "hidden": false, + "cacheVariables": { + "TARGET_NAME": "${presetName}", + "SDK_CONFIG_FILE": "sdkconfig.default_nopsram_ble.esp32", + "NF_BUILD_RTM": "OFF", + "NF_FEATURE_DEBUGGER": "ON", + "NF_FEATURE_RTC": "ON", + "NF_FEATURE_HAS_SDCARD": "ON", + "API_System.IO.FileSystem": "ON", + "API_nanoFramework.Device.OneWire": "ON", + "API_nanoFramework.Device.Bluetooth": "ON" + } + }, + { + "name": "ESP32_BLE_REV3", + "inherits": [ + "xtensa-esp32-preset", + "user-tools-repos", + "user-prefs" + ], + "hidden": false, + "cacheVariables": { + "TARGET_NAME": "${presetName}", + "SDK_CONFIG_FILE": "sdkconfig.default_ble_rev3.esp32", + "NF_BUILD_RTM": "OFF", + "NF_FEATURE_DEBUGGER": "ON", + "NF_FEATURE_RTC": "ON", + "NF_FEATURE_HAS_SDCARD": "ON", + "API_System.IO.FileSystem": "ON", + "API_nanoFramework.Device.OneWire": "ON", + "API_nanoFramework.Device.Bluetooth": "ON" + } + }, + { + "name": "ESP32_PICO", + "inherits": [ + "xtensa-esp32-preset", + "user-tools-repos", + "user-prefs" + ], + "hidden": false, + "cacheVariables": { + "TARGET_NAME": "${presetName}", + "SDK_CONFIG_FILE": "sdkconfig.default_pico", + "TARGET_SERIAL_BAUDRATE": "115200", + "ESP32_SPIRAM_FOR_IDF_ALLOCATION": "0", + "ESP32_RESERVED_RAM_FOR_IDF_ALLOCATION": "15", + "NF_BUILD_RTM": "OFF", + "NF_FEATURE_DEBUGGER": "ON", + "NF_FEATURE_RTC": "ON", + "NF_FEATURE_HAS_SDCARD": "OFF", + "API_System.IO.FileSystem": "ON", + "API_Windows.Storage": "ON", + "API_System.Device.I2s": "OFF" + } + }, + { + "name": "ESP_WROVER_KIT", + "inherits": [ + "xtensa-esp32-preset", + "user-tools-repos", + "user-prefs" + ], + "hidden": false, + "cacheVariables": { + "TARGET_NAME": "${presetName}", + "SDK_CONFIG_FILE": "", + "NF_BUILD_RTM": "OFF", + "NF_FEATURE_DEBUGGER": "ON", + "NF_FEATURE_RTC": "ON", + "NF_FEATURE_HAS_SDCARD": "ON", + "API_System.IO.FileSystem": "ON", + "API_Windows.Storage": "ON", + "API_nanoFramework.Graphics": "ON", + "API_nanoFramework.Device.OneWire": "ON", + "GRAPHICS_DISPLAY": "ILI9341_240x320_SPI.cpp", + "TOUCHPANEL_DEVICE": "XPT2046.cpp", + "GRAPHICS_DISPLAY_INTERFACE": "Spi_To_Display.cpp", + "TOUCHPANEL_INTERFACE": "Spi_To_TouchPanel.cpp" + } + }, + { + "name": "ESP32_C3", + "inherits": [ + "xtensa-esp32c3-preset", + "user-tools-repos", + "user-prefs" + ], + "hidden": false, + "cacheVariables": { + "TARGET_NAME": "${presetName}", + "SDK_CONFIG_FILE": "", + "NF_BUILD_RTM": "OFF", + "NF_FEATURE_DEBUGGER": "ON", + "NF_FEATURE_RTC": "ON", + "NF_FEATURE_HAS_SDCARD": "OFF", + "API_System.IO.FileSystem": "ON", + "API_Windows.Storage": "ON", + "API_nanoFramework.Device.OneWire": "OFF", + "API_nanoFramework.Hardware.Esp32.Rmt": "ON", + "ESP32_RESERVED_RAM_FOR_IDF_ALLOCATION": "100" + } + }, + { + "name": "ESP32_C3_REV3", + "inherits": [ + "xtensa-esp32c3-preset", + "user-tools-repos", + "user-prefs" + ], + "hidden": false, + "cacheVariables": { + "TARGET_NAME": "${presetName}", + "SDK_CONFIG_FILE": "sdkconfig.default_rev3.esp32c3", + "NF_BUILD_RTM": "OFF", + "NF_FEATURE_DEBUGGER": "ON", + "NF_FEATURE_RTC": "ON", + "NF_FEATURE_HAS_SDCARD": "OFF", + "API_System.IO.FileSystem": "ON", + "API_Windows.Storage": "ON", + "API_nanoFramework.Device.OneWire": "OFF", + "API_nanoFramework.Hardware.Esp32.Rmt": "ON", + "ESP32_RESERVED_RAM_FOR_IDF_ALLOCATION": "100" + } + }, + { + "name": "ESP32_S3", + "inherits": [ + "xtensa-esp32s3-preset", + "user-tools-repos", + "user-prefs" + ], + "hidden": false, + "cacheVariables": { + "TARGET_NAME": "${presetName}", + "SDK_CONFIG_FILE": "sdkconfig.default.esp32s3", + "NF_BUILD_RTM": "OFF", + "NF_FEATURE_DEBUGGER": "ON", + "NF_FEATURE_RTC": "ON", + "NF_FEATURE_HAS_SDCARD": "ON", + "ESP32_USB_CDC": "ON", + "ESP32_RESERVED_RAM_FOR_IDF_ALLOCATION": "150" + } + }, + { + "name": "ESP32_S3_BLE", + "inherits": [ + "xtensa-esp32s3-preset", + "user-tools-repos", + "user-prefs" + ], + "hidden": false, + "cacheVariables": { + "TARGET_NAME": "${presetName}", + "SDK_CONFIG_FILE": "sdkconfig.default_ble.esp32s3", + "NF_BUILD_RTM": "OFF", + "NF_FEATURE_DEBUGGER": "ON", + "NF_FEATURE_RTC": "ON", + "NF_FEATURE_HAS_SDCARD": "ON", + "ESP32_USB_CDC": "ON", + "API_nanoFramework.Device.Bluetooth": "ON", + "ESP32_RESERVED_RAM_FOR_IDF_ALLOCATION": "180" + } + }, + { + "name": "XIAO_ESP32C3", + "inherits": [ + "xtensa-esp32c3-preset", + "user-tools-repos", + "user-prefs" + ], + "hidden": false, + "cacheVariables": { + "TARGET_NAME": "${presetName}", + "SDK_CONFIG_FILE": "sdkconfig.default_rev3_noconsole.esp32c3", + "NF_BUILD_RTM": "OFF", + "NF_FEATURE_DEBUGGER": "ON", + "NF_FEATURE_RTC": "ON", + "NF_FEATURE_HAS_SDCARD": "OFF", + "HAL_WP_USE_SERIAL": "OFF", + "HAL_WP_USE_USB_CDC": "ON", + "API_System.IO.FileSystem": "ON", + "API_Windows.Storage": "ON", + "API_nanoFramework.Device.OneWire": "OFF", + "ESP32_RESERVED_RAM_FOR_IDF_ALLOCATION": "100" + } + }, + { + "name": "M5Stack", + "inherits": [ + "xtensa-esp32-preset", + "user-tools-repos", + "user-prefs" + ], + "hidden": false, + "cacheVariables": { + "TARGET_NAME": "${presetName}", + "SDK_CONFIG_FILE": "sdkconfig.default_nopsram.esp32", + "NF_BUILD_RTM": "OFF", + "NF_FEATURE_DEBUGGER": "ON", + "NF_FEATURE_RTC": "ON", + "NF_FEATURE_HAS_SDCARD": "ON", + "API_System.IO.FileSystem": "ON", + "API_Windows.Storage": "ON", + "API_nanoFramework.Device.OneWire": "ON", + "API_nanoFramework.Device.Bluetooth": "OFF", + "API_nanoFramework.Graphics": "ON", + "GRAPHICS_DISPLAY": "ILI9341_240x320_SPI.cpp", + "TOUCHPANEL_DEVICE": "XPT2046.cpp", + "GRAPHICS_DISPLAY_INTERFACE": "Spi_To_Display.cpp", + "TOUCHPANEL_INTERFACE": "Spi_To_TouchPanel.cpp" + } + }, + { + "name": "M5Core", + "inherits": [ + "xtensa-esp32-preset", + "user-tools-repos", + "user-prefs" + ], + "hidden": false, + "cacheVariables": { + "TARGET_NAME": "${presetName}", + "SDK_CONFIG_FILE": "sdkconfig.default_nopsram.esp32", + "NF_BUILD_RTM": "OFF", + "NF_FEATURE_DEBUGGER": "ON", + "NF_FEATURE_RTC": "ON", + "NF_FEATURE_HAS_SDCARD": "ON", + "API_System.IO.FileSystem": "ON", + "API_Windows.Storage": "ON", + "API_nanoFramework.Device.OneWire": "ON", + "API_nanoFramework.Graphics": "ON", + "GRAPHICS_DISPLAY": "ILI9342_320x240_SPI.cpp", + "TOUCHPANEL_DEVICE": "XPT2046.cpp", + "GRAPHICS_DISPLAY_INTERFACE": "Spi_To_Display.cpp", + "TOUCHPANEL_INTERFACE": "Spi_To_TouchPanel.cpp", + "ESP32_RESERVED_RAM_FOR_IDF_ALLOCATION": "50" + } + }, + { + "name": "M5Core2", + "inherits": [ + "xtensa-esp32-preset", + "user-tools-repos", + "user-prefs" + ], + "hidden": false, + "cacheVariables": { + "TARGET_NAME": "${presetName}", + "SDK_CONFIG_FILE": "sdkconfig.default_ble_rev3.esp32", + "NF_BUILD_RTM": "OFF", + "NF_FEATURE_DEBUGGER": "ON", + "NF_FEATURE_RTC": "ON", + "NF_FEATURE_HAS_SDCARD": "ON", + "API_System.IO.FileSystem": "ON", + "API_Windows.Storage": "ON", + "API_nanoFramework.Device.OneWire": "ON", + "API_nanoFramework.Device.Bluetooth": "ON", + "API_nanoFramework.Graphics": "ON", + "GRAPHICS_DISPLAY": "ILI9342_320x240_SPI.cpp", + "TOUCHPANEL_DEVICE": "XPT2046.cpp", + "GRAPHICS_DISPLAY_INTERFACE": "Spi_To_Display.cpp", + "TOUCHPANEL_INTERFACE": "Spi_To_TouchPanel.cpp", + "ESP32_SPIRAM_FOR_IDF_ALLOCATION": "1024 * 1024", + "ESP32_RESERVED_RAM_FOR_IDF_ALLOCATION": "50" + } + }, + { + "name": "AtomS3", + "inherits": [ + "xtensa-esp32s3-preset", + "user-tools-repos", + "user-prefs" + ], + "hidden": false, + "cacheVariables": { + "TARGET_NAME": "${presetName}", + "SDK_CONFIG_FILE": "sdkconfig.default.esp32s3", + "NF_BUILD_RTM": "OFF", + "NF_FEATURE_DEBUGGER": "ON", + "NF_FEATURE_RTC": "ON", + "NF_FEATURE_HAS_SDCARD": "OFF", + "ESP32_USB_CDC": "ON", + "API_System.IO.FileSystem": "ON", + "API_Windows.Storage": "ON", + "API_nanoFramework.Device.OneWire": "OFF", + "API_nanoFramework.Device.Bluetooth": "OFF", + "API_nanoFramework.Graphics": "OFF" + } + }, + { + "name": "ESP32_GenericDisplay_REV0", + "inherits": [ + "xtensa-esp32-preset", + "user-tools-repos", + "user-prefs" + ], + "hidden": false, + "cacheVariables": { + "TARGET_NAME": "${presetName}", + "SDK_CONFIG_FILE": "sdkconfig.default_nopsram.esp32", + "NF_BUILD_RTM": "OFF", + "NF_FEATURE_DEBUGGER": "ON", + "NF_FEATURE_RTC": "ON", + "NF_FEATURE_HAS_SDCARD": "ON", + "API_System.IO.FileSystem": "ON", + "API_Windows.Storage": "ON", + "API_nanoFramework.Device.OneWire": "ON", + "API_nanoFramework.Graphics": "ON", + "GRAPHICS_DISPLAY": "Generic_SPI.cpp", + "TOUCHPANEL_DEVICE": "XPT2046.cpp", + "GRAPHICS_DISPLAY_INTERFACE": "Spi_To_Display.cpp", + "TOUCHPANEL_INTERFACE": "Spi_To_TouchPanel.cpp", + "ESP32_RESERVED_RAM_FOR_IDF_ALLOCATION": "50" + } + }, + { + "name": "ESP32_PSRAM_BLE_GenericGraphic_REV3", + "inherits": [ + "xtensa-esp32-preset", + "user-tools-repos", + "user-prefs" + ], + "hidden": false, + "cacheVariables": { + "TARGET_NAME": "${presetName}", + "SDK_CONFIG_FILE": "sdkconfig.default_ble_rev3.esp32", + "NF_BUILD_RTM": "OFF", + "NF_FEATURE_DEBUGGER": "ON", + "NF_FEATURE_RTC": "ON", + "NF_FEATURE_HAS_SDCARD": "ON", + "API_System.IO.FileSystem": "ON", + "API_Windows.Storage": "ON", + "API_nanoFramework.Device.OneWire": "ON", + "API_nanoFramework.Device.Bluetooth": "ON", + "API_nanoFramework.Graphics": "ON", + "GRAPHICS_DISPLAY": "Generic_SPI.cpp", + "TOUCHPANEL_DEVICE": "XPT2046.cpp", + "GRAPHICS_DISPLAY_INTERFACE": "Spi_To_Display.cpp", + "TOUCHPANEL_INTERFACE": "Spi_To_TouchPanel.cpp", + "ESP32_SPIRAM_FOR_IDF_ALLOCATION": "1024 * 1024", + "ESP32_RESERVED_RAM_FOR_IDF_ALLOCATION": "50" + } + }, + { + "name": "ESP32_LILYGO", + "inherits": [ + "xtensa-esp32-preset", + "user-tools-repos", + "user-prefs" + ], + "hidden": false, + "cacheVariables": { + "TARGET_NAME": "${presetName}", + "SDK_CONFIG_FILE": "", + "NF_BUILD_RTM": "OFF", + "NF_FEATURE_DEBUGGER": "ON", + "NF_FEATURE_RTC": "ON", + "NF_FEATURE_HAS_SDCARD": "ON", + "ESP32_ETHERNET_SUPPORT": "ON", + "ETH_PHY_RST_GPIO": "5", + "ETH_RMII_CLK_OUT_GPIO": "17", + "API_System.IO.FileSystem": "ON", + "API_nanoFramework.Device.OneWire": "ON" + } + }, + { + "name": "ESP32_OLIMEX", + "inherits": [ + "xtensa-esp32-preset", + "user-tools-repos", + "user-prefs" + ], + "hidden": false, + "cacheVariables": { + "TARGET_NAME": "${presetName}", + "SDK_CONFIG_FILE": "", + "ESP32_RESERVED_RAM_FOR_IDF_ALLOCATION": "10", + "NF_BUILD_RTM": "OFF", + "NF_FEATURE_DEBUGGER": "ON", + "NF_FEATURE_RTC": "ON", + "NF_FEATURE_HAS_SDCARD": "ON", + "ESP32_ETHERNET_SUPPORT": "ON", + "ETH_PHY_RST_GPIO": "12", + "ETH_RMII_CLK_OUT_GPIO": "17", + "API_System.IO.FileSystem": "ON", + "API_nanoFramework.Device.OneWire": "ON" + } + }, + { + "name": "LilygoTWatch2020", + "inherits": [ + "xtensa-esp32-preset", + "user-tools-repos", + "user-prefs" + ], + "hidden": false, + "cacheVariables": { + "TARGET_NAME": "${presetName}", + "SDK_CONFIG_FILE": "", + "NF_BUILD_RTM": "OFF", + "NF_FEATURE_DEBUGGER": "ON", + "NF_FEATURE_RTC": "ON", + "API_System.IO.FileSystem": "ON", + "API_nanoFramework.Device.OneWire": "ON", + "API_nanoFramework.Graphics": "ON", + "GRAPHICS_DISPLAY": "ST7789V_240x320_SPI.cpp", + "TOUCHPANEL_DEVICE": "XPT2046.cpp", + "GRAPHICS_DISPLAY_INTERFACE": "Spi_To_Display.cpp", + "TOUCHPANEL_INTERFACE": "Spi_To_TouchPanel.cpp" + } + }, + { + "name": "LilygoTWatch2021", + "inherits": [ + "xtensa-esp32-preset", + "user-tools-repos", + "user-prefs" + ], + "hidden": false, + "cacheVariables": { + "TARGET_NAME": "${presetName}", + "SDK_CONFIG_FILE": "sdkconfig.default_pico_ble_rev3", + "TARGET_SERIAL_BAUDRATE": "115200", + "NF_BUILD_RTM": "OFF", + "NF_FEATURE_DEBUGGER": "ON", + "NF_FEATURE_RTC": "OFF", + "NF_FEATURE_HAS_SDCARD": "OFF", + "API_System.IO.FileSystem": "OFF", + "API_nanoFramework.Graphics": "ON", + "API_nanoFramework.Device.OneWire": "OFF", + "API_nanoFramework.Device.Bluetooth": "ON", + "API_nanoFramework.Hardware.Esp32.Rmt": "OFF", + "GRAPHICS_DISPLAY": "GC9A01_240x240_SPI.cpp", + "GRAPHICS_DISPLAY_INTERFACE": "Spi_To_Display.cpp", + "TOUCHPANEL_DEVICE": "CST816S.cpp", + "TOUCHPANEL_INTERFACE": "Spi_To_TouchPanel.cpp" + } + }, + { + "name": "ESP32_ETHERNET_KIT_1.2", + "inherits": [ + "xtensa-esp32-preset", + "user-tools-repos", + "user-prefs" + ], + "hidden": false, + "cacheVariables": { + "TARGET_NAME": "${presetName}", + "SDK_CONFIG_FILE": "sdkconfig.default_ble_rev3.esp32", + "NF_BUILD_RTM": "OFF", + "NF_FEATURE_DEBUGGER": "ON", + "NF_FEATURE_RTC": "ON", + "NF_FEATURE_HAS_SDCARD": "ON", + "ESP32_ETHERNET_SUPPORT": "ON", + "ESP32_ETHERNET_INTERFACE": "IP101", + "ETH_PHY_RST_GPIO": "5", + "ETH_RMII_CLK_IN_GPIO": "0", + "ETH_PHY_ADDR": "1", + "API_System.IO.FileSystem": "ON", + "API_nanoFramework.Device.OneWire": "ON", + "API_nanoFramework.Device.Bluetooth": "ON" + } + }, + { + "name": "ESP32_WT32_ETH01", + "inherits": [ + "xtensa-esp32-preset", + "user-tools-repos", + "user-prefs" + ], + "hidden": false, + "cacheVariables": { + "TARGET_NAME": "${presetName}", + "SDK_CONFIG_FILE": "sdkconfig.default_nopsram.esp32", + "NF_BUILD_RTM": "OFF", + "NF_FEATURE_DEBUGGER": "ON", + "NF_FEATURE_RTC": "ON", + "NF_FEATURE_HAS_SDCARD": "ON", + "ESP32_ETHERNET_SUPPORT": "ON", + "ETH_RMII_CLK_IN_GPIO": "0", + "ETH_PHY_ADDR": "1", + "ETH_PHY_RST_GPIO": "16", + "API_System.IO.FileSystem": "ON", + "API_nanoFramework.Device.OneWire": "ON" + } + }, + { + "name": "ESP32_WESP32", + "inherits": [ + "xtensa-esp32-preset", + "user-tools-repos", + "user-prefs" + ], + "hidden": false, + "cacheVariables": { + "TARGET_NAME": "${presetName}", + "SDK_CONFIG_FILE": "", + "ESP32_RESERVED_RAM_FOR_IDF_ALLOCATION": "10", + "NF_BUILD_RTM": "OFF", + "NF_FEATURE_DEBUGGER": "ON", + "NF_FEATURE_RTC": "ON", + "NF_FEATURE_HAS_SDCARD": "ON", + "ESP32_ETHERNET_SUPPORT": "ON", + "ESP32_ETHERNET_INTERFACE": "RTL8201", + "ETH_RMII_CLK_IN_GPIO": "0", + "ETH_MDIO_GPIO": "17", + "ETH_MDC_GPIO": "16", + "API_System.IO.FileSystem": "ON", + "API_nanoFramework.Device.OneWire": "ON" + } + }, + { + "name": "M5StickC", + "inherits": [ + "xtensa-esp32-preset", + "user-tools-repos", + "user-prefs" + ], + "hidden": false, + "cacheVariables": { + "TARGET_NAME": "${presetName}", + "SDK_CONFIG_FILE": "sdkconfig.default_pico", + "ESP32_SPIRAM_FOR_IDF_ALLOCATION": "0", + "ESP32_RESERVED_RAM_FOR_IDF_ALLOCATION": "15", + "NF_BUILD_RTM": "OFF", + "NF_FEATURE_DEBUGGER": "ON", + "TARGET_SERIAL_BAUDRATE": "115200", + "NF_FEATURE_RTC": "ON", + "API_System.IO.FileSystem": "ON", + "API_nanoFramework.Device.OneWire": "ON", + "API_nanoFramework.Graphics": "ON", + "GRAPHICS_DISPLAY": "ST7735S_SPI.cpp", + "TOUCHPANEL_DEVICE": "XPT2046.cpp", + "GRAPHICS_DISPLAY_INTERFACE": "Spi_To_Display.cpp", + "TOUCHPANEL_INTERFACE": "Spi_To_TouchPanel.cpp" + } + }, + { + "name": "M5StickCPlus", + "inherits": [ + "xtensa-esp32-preset", + "user-tools-repos", + "user-prefs" + ], + "hidden": false, + "cacheVariables": { + "TARGET_NAME": "${presetName}", + "SDK_CONFIG_FILE": "sdkconfig.default_nopsram.esp32", + "ESP32_RESERVED_RAM_FOR_IDF_ALLOCATION": "50", + "NF_BUILD_RTM": "OFF", + "NF_FEATURE_DEBUGGER": "ON", + "TARGET_SERIAL_BAUDRATE": "115200", + "NF_FEATURE_RTC": "ON", + "API_System.IO.FileSystem": "ON", + "API_nanoFramework.Device.OneWire": "ON", + "API_nanoFramework.Graphics": "ON", + "GRAPHICS_DISPLAY": "ST7789V_240x320_SPI.cpp", + "TOUCHPANEL_DEVICE": "XPT2046.cpp", + "GRAPHICS_DISPLAY_INTERFACE": "Spi_To_Display.cpp", + "TOUCHPANEL_INTERFACE": "Spi_To_TouchPanel.cpp" + } + }, + { + "name": "FEATHER_S2", + "inherits": [ + "xtensa-esp32s2-preset", + "user-tools-repos", + "user-prefs" + ], + "hidden": false, + "cacheVariables": { + "TARGET_NAME": "${presetName}", + "SDK_CONFIG_FILE": "sdkconfig.default.esp32s2", + "NF_BUILD_RTM": "OFF", + "NF_FEATURE_DEBUGGER": "ON", + "NF_FEATURE_RTC": "ON", + "NF_FEATURE_HAS_SDCARD": "OFF", + "API_System.IO.FileSystem": "ON", + "ESP32_ETHERNET_SUPPORT": "OFF", + "ESP32_CONFIG_PIN_PHY_POWER": "", + "ESP32_CONFIG_PHY_CLOCK_MODE": "", + "ESP32_USB_CDC": "ON", + "API_nanoFramework.Device.OneWire": "OFF" + } + }, + { + "name": "KALUGA_1", + "inherits": [ + "xtensa-esp32s2-preset", + "user-tools-repos", + "user-prefs" + ], + "hidden": false, + "cacheVariables": { + "TARGET_NAME": "${presetName}", + "SDK_CONFIG_FILE": "sdkconfig.default.esp32s2", + "NF_BUILD_RTM": "OFF", + "NF_FEATURE_DEBUGGER": "ON", + "NF_FEATURE_RTC": "ON", + "API_System.IO.FileSystem": "ON", + "API_nanoFramework.Graphics": "ON", + "GRAPHICS_DISPLAY": "ILI9341_240x320_SPI.cpp", + "TOUCHPANEL_DEVICE": "XPT2046.cpp", + "GRAPHICS_DISPLAY_INTERFACE": "Spi_To_Display.cpp", + "TOUCHPANEL_INTERFACE": "Spi_To_TouchPanel.cpp" + } + } + ], + "buildPresets": [ + { + "inherits": "base-user", + "name": "ESP32_PSRAM_REV0", + "displayName": "ESP32_PSRAM_REV0", + "configurePreset": "ESP32_PSRAM_REV0" + }, + { + "inherits": "base-user", + "name": "ESP32_PSRAM_REV3", + "displayName": "ESP32_PSRAM_REV3", + "configurePreset": "ESP32_PSRAM_REV3" + }, + { + "inherits": "base-user", + "name": "ESP32_REV0", + "displayName": "ESP32_REV0", + "configurePreset": "ESP32_REV0" + }, + { + "inherits": "base-user", + "name": "ESP32_REV3", + "displayName": "ESP32_REV3", + "configurePreset": "ESP32_REV3" + }, + { + "inherits": "base-user", + "name": "ESP32_PSRAM_XTAL26_REV0", + "displayName": "ESP32_PSRAM_XTAL26_REV0", + "configurePreset": "ESP32_PSRAM_XTAL26_REV0" + }, + { + "inherits": "base-user", + "name": "ESP32_BLE_REV0", + "displayName": "ESP32_BLE_REV0", + "configurePreset": "ESP32_BLE_REV0" + }, + { + "inherits": "base-user", + "name": "ESP32_BLE_REV3", + "displayName": "ESP32_BLE_REV3", + "configurePreset": "ESP32_BLE_REV3" + }, + { + "inherits": "base-user", + "name": "ESP32_PICO", + "displayName": "ESP32_PICO", + "configurePreset": "ESP32_PICO" + }, + { + "inherits": "base-user", + "name": "ESP_WROVER_KIT", + "displayName": "ESP_WROVER_KIT", + "configurePreset": "ESP_WROVER_KIT" + }, + { + "inherits": "base-user", + "name": "ESP32_C3", + "displayName": "ESP32_C3", + "configurePreset": "ESP32_C3" + }, + { + "inherits": "base-user", + "name": "ESP32_C3_REV3", + "displayName": "ESP32_C3_REV3", + "configurePreset": "ESP32_C3_REV3" + }, + { + "inherits": "base-user", + "name": "ESP32_S3", + "displayName": "ESP32_S3", + "configurePreset": "ESP32_S3" + }, + { + "inherits": "base-user", + "name": "ESP32_S3_BLE", + "displayName": "ESP32_S3_BLE", + "configurePreset": "ESP32_S3_BLE" + }, + { + "inherits": "base-user", + "name": "XIAO_ESP32C3", + "displayName": "XIAO_ESP32C3", + "configurePreset": "XIAO_ESP32C3" + }, + { + "inherits": "base-user", + "name": "M5Stack", + "displayName": "M5Stack", + "configurePreset": "M5Stack" + }, + { + "inherits": "base-user", + "name": "M5Core", + "displayName": "M5Core", + "configurePreset": "M5Core" + }, + { + "inherits": "base-user", + "name": "M5Core2", + "displayName": "M5Core2", + "configurePreset": "M5Core2" + }, + { + "inherits": "base-user", + "name": "AtomS3", + "displayName": "AtomS3", + "configurePreset": "AtomS3" + }, + { + "inherits": "base-user", + "name": "ESP32_GenericDisplay_REV0", + "displayName": "ESP32_GenericDisplay_REV0", + "configurePreset": "ESP32_GenericDisplay_REV0" + }, + { + "inherits": "base-user", + "name": "ESP32_PSRAM_BLE_GenericGraphic_REV3", + "displayName": "ESP32_PSRAM_BLE_GenericGraphic_REV3", + "configurePreset": "ESP32_PSRAM_BLE_GenericGraphic_REV3" + }, + { + "inherits": "base-user", + "name": "ESP32_LILYGO", + "displayName": "ESP32_LILYGO", + "configurePreset": "ESP32_LILYGO" + }, + { + "inherits": "base-user", + "name": "ESP32_OLIMEX", + "displayName": "ESP32_OLIMEX", + "configurePreset": "ESP32_OLIMEX" + }, + { + "inherits": "base-user", + "name": "ESP32_ETHERNET_KIT_1.2", + "displayName": "ESP32_ETHERNET_KIT_1.2", + "configurePreset": "ESP32_ETHERNET_KIT_1.2" + }, + { + "inherits": "base-user", + "name": "ESP32_WT32_ETH01", + "displayName": "ESP32_WT32_ETH01", + "configurePreset": "ESP32_WT32_ETH01" + }, + { + "inherits": "base-user", + "name": "ESP32_WESP32", + "displayName": "ESP32_WESP32", + "configurePreset": "ESP32_WESP32" + }, + { + "inherits": "base-user", + "name": "LilygoTWatch2020", + "displayName": "LilygoTWatch2020", + "configurePreset": "LilygoTWatch2020" + }, + { + "inherits": "base-user", + "name": "LilygoTWatch2021", + "displayName": "LilygoTWatch2021", + "configurePreset": "LilygoTWatch2021" + }, + { + "inherits": "base-user", + "name": "M5StickC", + "displayName": "M5StickC", + "configurePreset": "M5StickC" + }, + { + "inherits": "base-user", + "name": "M5StickCPlus", + "displayName": "M5StickCPlus", + "configurePreset": "M5StickCPlus" + }, + { + "inherits": "base-user", + "name": "FEATHER_S2", + "displayName": "FEATHER_S2", + "configurePreset": "FEATHER_S2" + }, + { + "inherits": "base-user", + "name": "KALUGA_1", + "displayName": "KALUGA_1", + "configurePreset": "KALUGA_1" + } + ] +} \ No newline at end of file diff --git a/targets/ESP32/ESP32/target_system_device_pwm_config.cpp b/targets/ESP32/ESP32/target_system_device_pwm_config.cpp new file mode 100644 index 0000000000..73cc6666d3 --- /dev/null +++ b/targets/ESP32/ESP32/target_system_device_pwm_config.cpp @@ -0,0 +1,9 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS BLANK ON PURPOSE BECAUSE THIS TARGET DOESN'T REQUIRE THIS SPECIFIC CONFIGURATION // +/////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/targets/ESP32/ESP32_C3/target_system_device_pwm_config.cpp b/targets/ESP32/ESP32_C3/target_system_device_pwm_config.cpp new file mode 100644 index 0000000000..73cc6666d3 --- /dev/null +++ b/targets/ESP32/ESP32_C3/target_system_device_pwm_config.cpp @@ -0,0 +1,9 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS BLANK ON PURPOSE BECAUSE THIS TARGET DOESN'T REQUIRE THIS SPECIFIC CONFIGURATION // +/////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/targets/ESP32/ESP32_S2/target_system_device_pwm_config.cpp b/targets/ESP32/ESP32_S2/target_system_device_pwm_config.cpp new file mode 100644 index 0000000000..73cc6666d3 --- /dev/null +++ b/targets/ESP32/ESP32_S2/target_system_device_pwm_config.cpp @@ -0,0 +1,9 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS BLANK ON PURPOSE BECAUSE THIS TARGET DOESN'T REQUIRE THIS SPECIFIC CONFIGURATION // +/////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/targets/ESP32/ESP32_S3/CMakeLists.txt b/targets/ESP32/ESP32_S3/CMakeLists.txt new file mode 100644 index 0000000000..2bffbbbc64 --- /dev/null +++ b/targets/ESP32/ESP32_S3/CMakeLists.txt @@ -0,0 +1,10 @@ +# +# Copyright (c) .NET Foundation and Contributors +# See LICENSE file in the project root for full license information. +# + +include(binutils.ESP32) + +############################## + +nf_setup_target_build() diff --git a/targets/ESP32/ESP32_S3/README.md b/targets/ESP32/ESP32_S3/README.md new file mode 100644 index 0000000000..0c384f6da4 --- /dev/null +++ b/targets/ESP32/ESP32_S3/README.md @@ -0,0 +1,10 @@ +# ESP32-S3 + +This reference target _fits_ all ESP32 boards carrying an ESP32-S3 chip. + +Check the details at the documentation website [here](http://docs.nanoframework.net/content/reference-targets/esp32-s3.html) + +Getting started guides and build instructions can also be found at the documentation website: + +- [Build instructions](https://docs.nanoframework.net/content/building/build-esp32.html) +- [Getting started with managed code (C#)](https://docs.nanoframework.net/content/getting-started-guides/getting-started-managed.html) diff --git a/targets/ESP32/ESP32_S3/common/CMakeLists.txt b/targets/ESP32/ESP32_S3/common/CMakeLists.txt new file mode 100644 index 0000000000..0aa4fd139b --- /dev/null +++ b/targets/ESP32/ESP32_S3/common/CMakeLists.txt @@ -0,0 +1,4 @@ +# +# Copyright (c) .NET Foundation and Contributors +# See LICENSE file in the project root for full license information. +# diff --git a/targets/ESP32/ESP32_S3/ffconf.h b/targets/ESP32/ESP32_S3/ffconf.h new file mode 100644 index 0000000000..0dbd625ead --- /dev/null +++ b/targets/ESP32/ESP32_S3/ffconf.h @@ -0,0 +1,342 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Portions Copyright (c) 2018, ChaN, all right reserved. +// See LICENSE file in the project root for full license information. +// + +// clang-format off + +#include +#include +#include + +#if (HAL_USE_SDC != TRUE) +// need this include here when not using SDCARD so it can load the one from IDF +#include +#endif + +/*---------------------------------------------------------------------------/ +/ FatFs Functional Configurations +/---------------------------------------------------------------------------*/ + +#define FFCONF_DEF 86604 /* Revision ID */ + +/*---------------------------------------------------------------------------/ +/ Function Configurations +/---------------------------------------------------------------------------*/ + +#define FF_FS_READONLY 0 +/* This option switches read-only configuration. (0:Read/Write or 1:Read-only) +/ Read-only configuration removes writing API functions, f_write(), f_sync(), +/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree() +/ and optional writing functions as well. */ + + +#define FF_FS_MINIMIZE 0 +/* This option defines minimization level to remove some basic API functions. +/ +/ 0: Basic functions are fully enabled. +/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename() +/ are removed. +/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1. +/ 3: f_lseek() function is removed in addition to 2. */ + + +#define FF_USE_STRFUNC 0 +/* This option switches string functions, f_gets(), f_putc(), f_puts() and f_printf(). +/ +/ 0: Disable string functions. +/ 1: Enable without LF-CRLF conversion. +/ 2: Enable with LF-CRLF conversion. */ + + +#define FF_USE_FIND 1 +/* This option switches filtered directory read functions, f_findfirst() and +/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */ + + +#define FF_USE_MKFS 1 +/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */ + + +#define FF_USE_FASTSEEK CONFIG_FATFS_USE_FASTSEEK +/* This option switches fast seek function. (0:Disable or 1:Enable) */ + + +#define FF_USE_EXPAND 0 +/* This option switches f_expand function. (0:Disable or 1:Enable) */ + + +#define FF_USE_CHMOD 1 +/* This option switches attribute manipulation functions, f_chmod() and f_utime(). +/ (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */ + + +#define FF_USE_LABEL 0 +/* This option switches volume label functions, f_getlabel() and f_setlabel(). +/ (0:Disable or 1:Enable) */ + + +#define FF_USE_FORWARD 0 +/* This option switches f_forward() function. (0:Disable or 1:Enable) */ + + +/*---------------------------------------------------------------------------/ +/ Locale and Namespace Configurations +/---------------------------------------------------------------------------*/ + +#define FF_CODE_PAGE CONFIG_FATFS_CODEPAGE +/* This option specifies the OEM code page to be used on the target system. +/ Incorrect code page setting can cause a file open failure. +/ +/ 437 - U.S. +/ 720 - Arabic +/ 737 - Greek +/ 771 - KBL +/ 775 - Baltic +/ 850 - Latin 1 +/ 852 - Latin 2 +/ 855 - Cyrillic +/ 857 - Turkish +/ 860 - Portuguese +/ 861 - Icelandic +/ 862 - Hebrew +/ 863 - Canadian French +/ 864 - Arabic +/ 865 - Nordic +/ 866 - Russian +/ 869 - Greek 2 +/ 932 - Japanese (DBCS) +/ 936 - Simplified Chinese (DBCS) +/ 949 - Korean (DBCS) +/ 950 - Traditional Chinese (DBCS) +/ 0 - Include all code pages above and configured by f_setcp() +*/ + + +#if defined(CONFIG_FATFS_LFN_STACK) +#define FF_USE_LFN 2 +#elif defined(CONFIG_FATFS_LFN_HEAP) +#define FF_USE_LFN 3 +#else /* CONFIG_FATFS_LFN_NONE */ +#define FF_USE_LFN 0 +#endif + +#ifdef CONFIG_FATFS_MAX_LFN +#define FF_MAX_LFN CONFIG_FATFS_MAX_LFN +#endif + +/* The FF_USE_LFN switches the support for LFN (long file name). +/ +/ 0: Disable LFN. FF_MAX_LFN has no effect. +/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe. +/ 2: Enable LFN with dynamic working buffer on the STACK. +/ 3: Enable LFN with dynamic working buffer on the HEAP. +/ +/ To enable the LFN, ffunicode.c needs to be added to the project. The LFN function +/ requiers certain internal working buffer occupies (FF_MAX_LFN + 1) * 2 bytes and +/ additional (FF_MAX_LFN + 44) / 15 * 32 bytes when exFAT is enabled. +/ The FF_MAX_LFN defines size of the working buffer in UTF-16 code unit and it can +/ be in range of 12 to 255. It is recommended to be set 255 to fully support LFN +/ specification. +/ When use stack for the working buffer, take care on stack overflow. When use heap +/ memory for the working buffer, memory management functions, ff_memalloc() and +/ ff_memfree() in ffsystem.c, need to be added to the project. */ + + +#ifdef CONFIG_FATFS_API_ENCODING_UTF_8 +#define FF_LFN_UNICODE 2 +#elif defined(CONFIG_FATFS_API_ENCODING_UTF_16) +#define FF_LFN_UNICODE 1 +#else /* CONFIG_FATFS_API_ENCODING_ANSI_OEM */ +#define FF_LFN_UNICODE 0 +#endif +/* This option switches the character encoding on the API when LFN is enabled. +/ +/ 0: ANSI/OEM in current CP (TCHAR = char) +/ 1: Unicode in UTF-16 (TCHAR = WCHAR) +/ 2: Unicode in UTF-8 (TCHAR = char) +/ 3: Unicode in UTF-32 (TCHAR = DWORD) +/ +/ Also behavior of string I/O functions will be affected by this option. +/ When LFN is not enabled, this option has no effect. */ + + +#define FF_LFN_BUF 255 +#define FF_SFN_BUF 12 +/* This set of options defines size of file name members in the FILINFO structure +/ which is used to read out directory items. These values should be suffcient for +/ the file names to read. The maximum possible length of the read file name depends +/ on character encoding. When LFN is not enabled, these options have no effect. */ + + +#define FF_STRF_ENCODE 3 +/* When FF_LFN_UNICODE >= 1 with LFN enabled, string I/O functions, f_gets(), +/ f_putc(), f_puts and f_printf() convert the character encoding in it. +/ This option selects assumption of character encoding ON THE FILE to be +/ read/written via those functions. +/ +/ 0: ANSI/OEM in current CP +/ 1: Unicode in UTF-16LE +/ 2: Unicode in UTF-16BE +/ 3: Unicode in UTF-8 +*/ + + +#define FF_FS_RPATH 2 +/* This option configures support for relative path. +/ +/ 0: Disable relative path and remove related functions. +/ 1: Enable relative path. f_chdir() and f_chdrive() are available. +/ 2: f_getcwd() function is available in addition to 1. +*/ + + +/*---------------------------------------------------------------------------/ +/ Drive/Volume Configurations +/---------------------------------------------------------------------------*/ + +#define FF_VOLUMES 3 +/* Number of volumes (logical drives) to be used. (1-10) */ + + +#define FF_STR_VOLUME_ID 1 +#define FF_VOLUME_STRS "D", "E", "F" +/* FF_STR_VOLUME_ID switches support for volume ID in arbitrary strings. +/ When FF_STR_VOLUME_ID is set to 1 or 2, arbitrary strings can be used as drive +/ number in the path name. FF_VOLUME_STRS defines the volume ID strings for each +/ logical drives. Number of items must not be less than FF_VOLUMES. Valid +/ characters for the volume ID strings are A-Z, a-z and 0-9, however, they are +/ compared in case-insensitive. If FF_STR_VOLUME_ID >= 1 and FF_VOLUME_STRS is +/ not defined, a user defined volume string table needs to be defined as: +/ +/ const char* VolumeStr[FF_VOLUMES] = {"ram","flash","sd","usb",... +*/ + + +#define FF_MULTI_PARTITION 1 +/* This option switches support for multiple volumes on the physical drive. +/ By default (0), each logical drive number is bound to the same physical drive +/ number and only an FAT volume found on the physical drive will be mounted. +/ When this function is enabled (1), each logical drive number can be bound to +/ arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk() +/ funciton will be available. */ + +/* SD card sector size */ +#define FF_SS_SDCARD 512 +/* wear_levelling library sector size */ +#define FF_SS_WL CONFIG_WL_SECTOR_SIZE + +#define FF_MIN_SS MIN(FF_SS_SDCARD, FF_SS_WL) +#define FF_MAX_SS MAX(FF_SS_SDCARD, FF_SS_WL) +/* This set of options configures the range of sector size to be supported. (512, +/ 1024, 2048 or 4096) Always set both 512 for most systems, generic memory card and +/ harddisk. But a larger value may be required for on-board flash memory and some +/ type of optical media. When FF_MAX_SS is larger than FF_MIN_SS, FatFs is configured +/ for variable sector size mode and disk_ioctl() function needs to implement +/ GET_SECTOR_SIZE command. */ + + +#define FF_USE_TRIM 0 +/* This option switches support for ATA-TRIM. (0:Disable or 1:Enable) +/ To enable Trim function, also CTRL_TRIM command should be implemented to the +/ disk_ioctl() function. */ + + +#define FF_FS_NOFSINFO 0 +/* If you need to know correct free space on the FAT32 volume, set bit 0 of this +/ option, and f_getfree() function at first time after volume mount will force +/ a full FAT scan. Bit 1 controls the use of last allocated cluster number. +/ +/ bit0=0: Use free cluster count in the FSINFO if available. +/ bit0=1: Do not trust free cluster count in the FSINFO. +/ bit1=0: Use last allocated cluster number in the FSINFO if available. +/ bit1=1: Do not trust last allocated cluster number in the FSINFO. +*/ + + + +/*---------------------------------------------------------------------------/ +/ System Configurations +/---------------------------------------------------------------------------*/ + +#define FF_FS_TINY (!CONFIG_FATFS_PER_FILE_CACHE) +/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny) +/ At the tiny configuration, size of file object (FIL) is shrinked FF_MAX_SS bytes. +/ Instead of private sector buffer eliminated from the file object, common sector +/ buffer in the filesystem object (FATFS) is used for the file data transfer. */ + + +#define FF_FS_EXFAT 0 +/* This option switches support for exFAT filesystem. (0:Disable or 1:Enable) +/ To enable exFAT, also LFN needs to be enabled. (FF_USE_LFN >= 1) +/ Note that enabling exFAT discards ANSI C (C89) compatibility. */ + + +#define FF_FS_NORTC 0 +#define FF_NORTC_MON 1 +#define FF_NORTC_MDAY 1 +#define FF_NORTC_YEAR 2018 +/* The option FF_FS_NORTC switches timestamp functiton. If the system does not have +/ any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable +/ the timestamp function. Every object modified by FatFs will have a fixed timestamp +/ defined by FF_NORTC_MON, FF_NORTC_MDAY and FF_NORTC_YEAR in local time. +/ To enable timestamp function (FF_FS_NORTC = 0), get_fattime() function need to be +/ added to the project to read current time form real-time clock. FF_NORTC_MON, +/ FF_NORTC_MDAY and FF_NORTC_YEAR have no effect. +/ These options have no effect at read-only configuration (FF_FS_READONLY = 1). */ + + +#define FF_FS_LOCK CONFIG_FATFS_FS_LOCK +/* The option FF_FS_LOCK switches file lock function to control duplicated file open +/ and illegal operation to open objects. This option must be 0 when FF_FS_READONLY +/ is 1. +/ +/ 0: Disable file lock function. To avoid volume corruption, application program +/ should avoid illegal open, remove and rename to the open objects. +/ >0: Enable file lock function. The value defines how many files/sub-directories +/ can be opened simultaneously under file lock control. Note that the file +/ lock control is independent of re-entrancy. */ + + +#define FF_FS_REENTRANT 1 +#define FF_FS_TIMEOUT (CONFIG_FATFS_TIMEOUT_MS / portTICK_PERIOD_MS) +#define FF_SYNC_t SemaphoreHandle_t +/* The option FF_FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs +/ module itself. Note that regardless of this option, file access to different +/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs() +/ and f_fdisk() function, are always not re-entrant. Only file/directory access +/ to the same volume is under control of this function. +/ +/ 0: Disable re-entrancy. FF_FS_TIMEOUT and FF_SYNC_t have no effect. +/ 1: Enable re-entrancy. Also user provided synchronization handlers, +/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj() +/ function, must be added to the project. Samples are available in +/ option/syscall.c. +/ +/ The FF_FS_TIMEOUT defines timeout period in unit of time tick. +/ The FF_SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*, +/ SemaphoreHandle_t and etc. A header file for O/S definitions needs to be +/ included somewhere in the scope of ff.h. */ + +#include +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" + +/* Some memory allocation functions are declared here in addition to ff.h, so that + they can be used also by external code when LFN feature is disabled. + */ +void* ff_memalloc (unsigned msize); +void ff_memfree(void*); + + +/*--- End of configuration options ---*/ + +/* Redefine names of disk IO functions to prevent name collisions */ +#define disk_initialize ff_disk_initialize +#define disk_status ff_disk_status +#define disk_read ff_disk_read +#define disk_write ff_disk_write +#define disk_ioctl ff_disk_ioctl + +// clang-format on diff --git a/targets/ESP32/ESP32_S3/launch.json b/targets/ESP32/ESP32_S3/launch.json new file mode 100644 index 0000000000..ad48bced71 --- /dev/null +++ b/targets/ESP32/ESP32_S3/launch.json @@ -0,0 +1,146 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "ESP32_S3", + "type": "cppdbg", + "request": "launch", + "MIMode": "gdb", + "miDebuggerPath": "/xtensa-esp32s3-elf/bin/xtensa-esp32-elf-gdb.exe", + "stopAtEntry": true, + "program": "${workspaceFolder}/build/nanoCLR.elf", + "setupCommands": [ + { + "description": "", + "text": "set logging on" + }, + { + "description": "", + "text": "target extended-remote localhost:3333" + }, + { + "description": "", + "text": "file ${workspaceFolder}/build/nanoCLR.elf" + }, + { + "description": "", + "text": "monitor reset halt" + }, + { + "description": "", + "text": "thb app_main" + }, + { + "description": "", + "text": "x $a1=0" + } + ], + "launchCompleteCommand": "exec-run", + "debugServerPath": "/bin/openocd.exe", + "debugServerArgs": "-s \"/share/openocd/scripts/\" -f board/esp32-solo-1.cfg", + "serverStarted": "Info : .*Tensilica.*0x1.", + "filterStderr": true, + "externalConsole": true, + "cwd": "${cwd}", + "logging": { + "trace": true, + "traceResponse": true, + "engineLogging": true, + "programOutput": true, + "exceptions": true, + "moduleLoad": true + } + }, + { + "name": "ESP32_WROOM_32 - OLimex OCD-H", + "type": "cppdbg", + "request": "launch", + "MIMode": "gdb", + "miDebuggerPath": "/xtensa-esp32-elf/bin/xtensa-esp32-elf-gdb.exe", + "stopAtEntry": true, + "program": "${workspaceFolder}/build/nanoCLR.elf", + "setupCommands": [ + { + "description": "", + "text": "set logging on" + }, + { + "description": "", + "text": "target extended-remote localhost:3333" + }, + { + "description": "", + "text": "file ${workspaceFolder}/build/nanoCLR.elf" + }, + { + "description": "", + "text": "monitor reset halt" + }, + { + "description": "", + "text": "thb app_main" + }, + { + "description": "", + "text": "x $a1=0" + } + ], + "launchCompleteCommand": "exec-run", + "debugServerPath": "/bin/openocd.exe", + "debugServerArgs": "-s \"/share/openocd/scripts/\" -f interface/ftdi/olimex-arm-usb-ocd-h.cfg -f target/esp32.cfg -c \"adapter_khz 3000\" ", + "serverStarted": "Info : .*Tensilica.*0x1.", + "filterStderr": true, + "externalConsole": true, + "cwd": "${cwd}", + "logging": { + "trace": false, + "traceResponse": false, + "engineLogging": false, + "programOutput": true, + "exceptions": true, + "moduleLoad": false + } + }, + { + "name": "ESP32_WROOM_32 - Segger JLink", + "type": "cppdbg", + "request": "launch", + "MIMode": "gdb", + "miDebuggerPath": "/xtensa-esp32-elf/bin/xtensa-esp32-elf-gdb.exe", + "stopAtEntry": true, + "program": "${workspaceFolder}/build/nanoCLR.elf", + "setupCommands": [ + { + "text": "set logging on" + }, + { + "text": "target extended-remote localhost:3333" + }, + { + "text": "file ${workspaceFolder}/build/nanoCLR.elf" + }, + { + "text": "monitor reset halt" + }, + { + "text": "x $a1=0" + } + ], + "launchCompleteCommand": "exec-run", + "debugServerPath": "/bin/openocd.exe", + "debugServerArgs": "-s \"/share/openocd/scripts/\" -f interface/jlink.cfg -f target/esp32.cfg -c \"adapter_khz 3000\" ", + "serverStarted": "Info : .*Tensilica.*0x1.", + "filterStderr": true, + "externalConsole": true, + "cwd": "${cwd}", + "logging": { + "trace": false, + "traceResponse": false, + "engineLogging": false, + "programOutput": true, + "exceptions": true, + "moduleLoad": false + } + } + ] +} diff --git a/targets/ESP32/ESP32_S3/nanoCLR/System.Device.Pwm/sys_dev_pwm_native_System_Device_Pwm_PwmChannel.cpp b/targets/ESP32/ESP32_S3/nanoCLR/System.Device.Pwm/sys_dev_pwm_native_System_Device_Pwm_PwmChannel.cpp new file mode 100644 index 0000000000..1ac27069fa --- /dev/null +++ b/targets/ESP32/ESP32_S3/nanoCLR/System.Device.Pwm/sys_dev_pwm_native_System_Device_Pwm_PwmChannel.cpp @@ -0,0 +1,415 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include "sys_dev_pwm_native.h" +#include +#include "Esp32_DeviceMapping.h" + +// Used to map a PWM channel number to a pin number for High and low speed channels +static char HighSpeedPinMap[8] = {255, 255, 255, 255, 255, 255, 255, 255}; +static char LowSpeedPinMap[8] = {255, 255, 255, 255, 255, 255, 255, 255}; +// Pin functions from PWM1 to PWM16 +static int PwmMapping[16] = { + 262400, + 262656, + 262912, + 263168, + 263424, + 263680, + 263936, + 264192, + 264448, + 264704, + 264960, + 265216, + 265472, + 265728, + 265984, + 266240}; + +#define GetSpeedMode(timer) (ledc_mode_t)((timer > 3) ? LEDC_LOW_SPEED_MODE : LEDC_HIGH_SPEED_MODE) +#define IDF_ERROR(result) \ + if (result != ESP_OK) \ + { \ + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); \ + } + +namespace sys_dev_pwm_native_System_Device_Pwm_PwmChannelHelpers +{ +uint32_t PwmController_Timer_resolution[8]; + +int GetChannel(int pin, int timerId, bool create); +uint32_t CalculateDuty(int timerId, uint32_t dutyCycle, PwmPulsePolarity polarity); +HRESULT ConfigureAndStart(CLR_RT_HeapBlock *pThis, bool create, bool noStart); +} // namespace sys_dev_pwm_native_System_Device_Pwm_PwmChannelHelpers + +using namespace sys_dev_pwm_native_System_Device_Pwm_PwmChannelHelpers; + +// +// Look up Pin number to find channel, if create true and not present then add pin +// return channel number or -1 if error +// +int sys_dev_pwm_native_System_Device_Pwm_PwmChannelHelpers::GetChannel(int pin, int timerId, bool create) +{ + int channel = -1; // Return if not found + + // Select map depending if high or low speed timers + char *pMap = (timerId > 3) ? LowSpeedPinMap : HighSpeedPinMap; + char *pMap2 = pMap; + + // look for pin in map + for (int index = 0; index < 8; index++, pMap++) + { + if (*pMap == pin) + { + channel = index; + break; + } + } + + if (create && channel == -1) + { + // if pin/channel not found then allocate one + for (int index = 0; index < 8; index++, pMap2++) + { + if (*pMap2 == 255) + { + channel = index; + *pMap2 = pin; + break; + } + } + } + + return channel; +} + +// +// Work out the duty Cycle for the current duty resolution and polarity +// +uint32_t sys_dev_pwm_native_System_Device_Pwm_PwmChannelHelpers::CalculateDuty( + int timerId, + uint32_t dutyCycle, + PwmPulsePolarity polarity) +{ + // if polarity Active low then reverse duty cycle + if (polarity == PwmPulsePolarity::PwmPulsePolarity_ActiveLow) + { + dutyCycle = 10000 - dutyCycle; + } + + // Return a duty cycle in the range of the current timer duty resolution + uint32_t calculatedDuty = PwmController_Timer_resolution[timerId] * dutyCycle / 10000; + return calculatedDuty; +} + +HRESULT sys_dev_pwm_native_System_Device_Pwm_PwmChannelHelpers::ConfigureAndStart( + CLR_RT_HeapBlock *pThis, + bool create, + bool noStart) +{ + int32_t timerId; + int32_t pinNumber; + uint32_t dutyCycle; + + PwmPulsePolarity polarity; + + ledc_mode_t mode; + ledc_channel_t channel; + ledc_timer_t timer_sel; + ledc_channel_config_t ledc_conf; + + NANOCLR_HEADER(); + + // Retrieves the needed parameters from private class properties or method parameters + timerId = pThis[Library_sys_dev_pwm_native_System_Device_Pwm_PwmChannel::FIELD___pwmTimer].NumericByRef().s4; + pinNumber = pThis[Library_sys_dev_pwm_native_System_Device_Pwm_PwmChannel::FIELD___pinNumber].NumericByRef().s4; + dutyCycle = pThis[Library_sys_dev_pwm_native_System_Device_Pwm_PwmChannel::FIELD___dutyCycle].NumericByRef().u4; + polarity = (PwmPulsePolarity)(pThis[Library_sys_dev_pwm_native_System_Device_Pwm_PwmChannel::FIELD___polarity] + .NumericByRef() + .u4); + + // Configure channel + mode = GetSpeedMode(timerId); + channel = (ledc_channel_t)GetChannel(pinNumber, timerId, create); + + if (channel == -1) + { + // Unable to create a new channel, all channels used up ? + NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE); + } + + timer_sel = (ledc_timer_t)(timerId & 0x03); + + // Work out the duty Cycle for the current duty resolution + dutyCycle = CalculateDuty(timerId, dutyCycle, polarity); + + ledc_conf = {pinNumber, mode, channel, LEDC_INTR_DISABLE, timer_sel, dutyCycle, 0}; + + // Configure Channel which will also start it + IDF_ERROR(ledc_channel_config(&ledc_conf)); + + // Because it is started from the configure we optionally stop it and set idle level based on polarity + if (noStart) + { + ledc_stop(mode, channel, polarity); + } + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_sys_dev_pwm_native_System_Device_Pwm_PwmChannel::NativeInit___VOID(CLR_RT_StackFrame &stack) +{ + int32_t pinNumber; + + NANOCLR_HEADER(); + + // get a pointer to the managed object instance and check that it's not NULL + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + + // Check pin number is a valid for output + pinNumber = pThis[FIELD___pinNumber].NumericByRef().s4; + + if (!GPIO_IS_VALID_OUTPUT_GPIO(pinNumber)) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + // Create a new entry in channel table and configure channel which will also start channel + NANOCLR_CHECK_HRESULT(ConfigureAndStart(pThis, true, true)); + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_sys_dev_pwm_native_System_Device_Pwm_PwmChannel::NativeSetDesiredFrequency___VOID__I4( + CLR_RT_StackFrame &stack) +{ + int32_t timerId; + int32_t desiredFrequency; + int32_t optimumDutyResolution; + uint32_t precision; + uint64_t divParam; + esp_err_t result; + + ledc_timer_t timer; + ledc_mode_t mode; + ledc_timer_bit_t duty_res; + ledc_timer_config_t timer_conf; + + NANOCLR_HEADER(); + + // get a pointer to the managed object instance and check that it's not NULL + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + + // Retrieves the needed parameters from private class properties ( 0 - 7 ) + timerId = pThis[FIELD___pwmTimer].NumericByRef().s4; + desiredFrequency = stack.Arg1().NumericByRef().s4; + + // parameter check + if (desiredFrequency < 0) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + timer = (ledc_timer_t)(timerId & 0x03); + mode = (timerId <= 4) ? LEDC_HIGH_SPEED_MODE : LEDC_LOW_SPEED_MODE; + + // Work out the optimal duty resolution based on current frequency, default to 1 if not found + // Working from 15 bit duty resolution down until we have a valid divisor + optimumDutyResolution = 1; + + for (int dutyResolution = 15; dutyResolution > 0; dutyResolution--) + { + precision = (0x1 << dutyResolution); // 2**depth + + divParam = ((uint64_t)LEDC_APB_CLK_HZ << 8) / desiredFrequency / precision; + + if (divParam > 256) + { + optimumDutyResolution = dutyResolution; + break; + } + } + + duty_res = (ledc_timer_bit_t)optimumDutyResolution; + + // Save resolution for working out values for percent duty cycle + PwmController_Timer_resolution[timerId] = (0x1 << optimumDutyResolution); + + timer_conf = {mode, duty_res, timer, (uint32_t)desiredFrequency, LEDC_AUTO_CLK}; + + result = ledc_timer_config(&timer_conf); + if (result != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + // store the frequency + pThis[FIELD___frequency].NumericByRef().s4 = desiredFrequency; + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_sys_dev_pwm_native_System_Device_Pwm_PwmChannel::NativeSetActiveDutyCyclePercentage___VOID__R8( + CLR_RT_StackFrame &stack) +{ + int32_t timerId; + int32_t pinNumber; + uint32_t dutyCycle; + + ledc_channel_t channel; + + PwmPulsePolarity polarity; + ledc_mode_t speed_mode; + + NANOCLR_HEADER(); + + // get a pointer to the managed object instance and check that it's not NULL + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + + // Retrieves the needed parameters from private class properties or method parameters + timerId = pThis[FIELD___pwmTimer].NumericByRef().s4; + pinNumber = pThis[FIELD___pinNumber].NumericByRef().s4; + polarity = (PwmPulsePolarity)(pThis[FIELD___polarity].NumericByRef().u4); + + // parameter check + if (stack.Arg1().NumericByRef().r8 < 0 || stack.Arg1().NumericByRef().r8 > 1.0) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + // retrieve percentage as 0 to 10000 (0% to 100%) + dutyCycle = (uint32_t)(stack.Arg1().NumericByRef().r8 * CONST_DutyCycleFactor); + + // Get channel number used for this pinNumber + // FIXME check result + channel = (ledc_channel_t)GetChannel(pinNumber, timerId, false); + + // Get speed mode based on Timer used + speed_mode = GetSpeedMode(timerId); + + // Work out the duty Cycle for the current duty resolution + dutyCycle = CalculateDuty(timerId, dutyCycle, polarity); + + // Update duty on channel + IDF_ERROR(ledc_set_duty(speed_mode, channel, dutyCycle)); + + // Activate duty on channel + IDF_ERROR(ledc_update_duty(speed_mode, channel)); + + // store the new duty cycle + pThis[FIELD___dutyCycle].NumericByRef().u4 = dutyCycle; + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_sys_dev_pwm_native_System_Device_Pwm_PwmChannel::NativeStart___VOID(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + // get a pointer to the managed object instance and check that it's not NULL + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + + // Call configure to start PWM channel + NANOCLR_CHECK_HRESULT(ConfigureAndStart(pThis, false, false)); + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_sys_dev_pwm_native_System_Device_Pwm_PwmChannel::NativeStop___VOID(CLR_RT_StackFrame &stack) +{ + int32_t timerId; + int32_t pinNumber; + int32_t polarity; + + ledc_mode_t speed_mode; + ledc_channel_t channel; + + NANOCLR_HEADER(); + + // get a pointer to the managed object instance and check that it's not NULL + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + + // Retrieves the needed parameters from private class properties or method parameters + timerId = pThis[FIELD___pwmTimer].NumericByRef().s4; + pinNumber = pThis[FIELD___pinNumber].NumericByRef().s4; + polarity = pThis[FIELD___polarity].NumericByRef().s4; + + speed_mode = GetSpeedMode(timerId); + + // FIX ME check result + channel = (ledc_channel_t)GetChannel(pinNumber, timerId, false); + + ledc_stop(speed_mode, channel, (uint32_t)polarity); + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_sys_dev_pwm_native_System_Device_Pwm_PwmChannel::DisposeNative___VOID(CLR_RT_StackFrame &stack) +{ + int32_t timerId; + int32_t pinNumber; + char *pMap; + + NANOCLR_HEADER(); + + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + + // Retrieves the needed parameters from private class properties or method parameters + timerId = pThis[FIELD___pwmTimer].NumericByRef().s4; + pinNumber = pThis[FIELD___pinNumber].NumericByRef().s4; + + // Remove pin from pin/channel Map + pMap = (timerId > 3) ? LowSpeedPinMap : HighSpeedPinMap; + + for (int index = 0; index < 8; index++, pMap++) + { + if (*pMap == pinNumber) + { + *pMap = 255; + break; + } + } + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_sys_dev_pwm_native_System_Device_Pwm_PwmChannel::GetChannel___STATIC__I4__I4__I4( + CLR_RT_StackFrame &stack) +{ + int32_t pinSetup; + + NANOCLR_HEADER(); + + int pin = stack.Arg0().NumericByRef().s4; + int timerId = stack.Arg1().NumericByRef().s4; + int pwm = 0; + + // Check if the combination is ok and set the result + for (pwm = timerId * 2; pwm < timerId * 2 + 2; pwm++) + { + pinSetup = (int32_t)Esp32_GetMappedDevicePinsWithFunction(PwmMapping[pwm]); + + if (pinSetup == pin) + { + // The channel is actually the pin number + stack.SetResult_I4(pin); + break; + } + } + + if (pwm == timerId * 2 + 2) + { + stack.SetResult_I4(-1); + } + + NANOCLR_NOCLEANUP_NOLABEL(); +} diff --git a/targets/ESP32/ESP32_S3/nanoCLR/nanoFramework.Graphics/Graphics_Memory.cpp b/targets/ESP32/ESP32_S3/nanoCLR/nanoFramework.Graphics/Graphics_Memory.cpp new file mode 100644 index 0000000000..06f08993c5 --- /dev/null +++ b/targets/ESP32/ESP32_S3/nanoCLR/nanoFramework.Graphics/Graphics_Memory.cpp @@ -0,0 +1,81 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#ifndef GRAPHICS_MEMORY_SETUP_ +#define GRAPHICS_MEMORY_SETUP_ + +#include +#include +#include +#include +#include + +struct GraphicsMemory g_GraphicsMemory; + +// Choosing Integrate RAM into ESP32 memory map from CONFIG_SPIRAM_USE. +// This is the most basic option for external SPI RAM integration +// During the ESP IDF start-up, external RAM is mapped into the data address space, +// starting at address 0x3F800000 (byte - accessible). +// The length of this region is the same as the SPI RAM size(up to the limit of 4 MB). + +// Applications can manually place data in external memory by creating pointers to this region. +// So if an application uses external memory, it is responsible for all management of the external SPI RAM. +// coordinating buffer usage, preventing corruption, etc. + +static CLR_UINT8 *heapStartingAddress = 0; +static CLR_UINT8 *heapEndingAddress = 0; + +bool GraphicsMemory::GraphicsHeapLocation( + CLR_UINT32 requested, + CLR_UINT8 *&graphicsStartingAddress, + CLR_UINT8 *&graphicsEndingAddress) +{ + // requesting 2MB + CLR_INT32 graphicsMemoryBlockSize = 2 * 1024 * 1024; + + CLR_INT32 memoryCaps = MALLOC_CAP_8BIT | MALLOC_CAP_32BIT | MALLOC_CAP_SPIRAM; + + if (heapStartingAddress != 0) + { + graphicsStartingAddress = heapStartingAddress; + graphicsEndingAddress = heapEndingAddress; + return true; + } + + // We don't want to allocate upfront + if (requested == 0) + { + // We don't allocate anything here + return false; + } + + // Get Largest free block in SPIRam + CLR_INT32 spiramMaxSize = heap_caps_get_largest_free_block(memoryCaps); + if (spiramMaxSize == 0) + { + // No SPIRAM, try and allocate small block in normal ram to keep allocator happy for + // people trying to run graphics on boards without SPIRAM + // Should be able to use with small screens + memoryCaps ^= MALLOC_CAP_SPIRAM; + + spiramMaxSize = requested; + } + + if (spiramMaxSize < graphicsMemoryBlockSize) // limit the size to what is available + { + graphicsMemoryBlockSize = spiramMaxSize; + } + graphicsStartingAddress = (CLR_UINT8 *)heap_caps_malloc(graphicsMemoryBlockSize, memoryCaps); + ASSERT(graphicsStartingAddress != NULL); + graphicsEndingAddress = (CLR_UINT8 *)(graphicsStartingAddress + graphicsMemoryBlockSize); + + // Save where we allocated it for restarts + heapStartingAddress = graphicsStartingAddress; + heapEndingAddress = graphicsEndingAddress; + + return true; +} + +#endif // GRAPHICS_MEMORY_SETUP_ diff --git a/targets/ESP32/ESP32_S3/nanoCLR/nanoFramework.Graphics/Spi_To_TouchPanel.cpp b/targets/ESP32/ESP32_S3/nanoCLR/nanoFramework.Graphics/Spi_To_TouchPanel.cpp new file mode 100644 index 0000000000..16854ecf98 --- /dev/null +++ b/targets/ESP32/ESP32_S3/nanoCLR/nanoFramework.Graphics/Spi_To_TouchPanel.cpp @@ -0,0 +1,38 @@ +// +// Copyright (c) 2017 The nanoFramework project contributors +// See LICENSE file in the project root for full license information. +// + +#define UNUSED(x) (void)x + +#ifndef SPI_TO_TOUCHPANEL_H +#define SPI_TO_TOUCHPANEL_H + +#include "nanoCLR_Types.h" +#include +#include +#include + +#include "TouchInterface.h" + +bool TouchInterface::Initialize() +{ + // Setup SPI configuration + + return true; +} + +CLR_UINT8 *TouchInterface::Write_Read( + CLR_UINT8 *valuesToSend, + CLR_UINT16 numberOfValuesToSend, + CLR_UINT16 numberValuesExpected) +{ + + UNUSED(valuesToSend); + UNUSED(numberOfValuesToSend); + UNUSED(numberValuesExpected); + + return 0; +} + +#endif // SPI_TO_TOUCHPANEL_H diff --git a/targets/ESP32/ESP32_S3/nanoCLR/nanoHAL.cpp b/targets/ESP32/ESP32_S3/nanoCLR/nanoHAL.cpp new file mode 100644 index 0000000000..e754dd5f80 --- /dev/null +++ b/targets/ESP32/ESP32_S3/nanoCLR/nanoHAL.cpp @@ -0,0 +1,8 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include + +bool g_fDoNotUninitializeDebuggerPort = false; diff --git a/targets/ESP32/ESP32_S3/nanoCLR/target_board.h.in b/targets/ESP32/ESP32_S3/nanoCLR/target_board.h.in new file mode 100644 index 0000000000..4d14660a1b --- /dev/null +++ b/targets/ESP32/ESP32_S3/nanoCLR/target_board.h.in @@ -0,0 +1,18 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +////////////////////////////////////////////////////////////////////////////// +// This file was automatically generated by a tool. // +// Any changes you make here will be overwritten when it's generated again. // +////////////////////////////////////////////////////////////////////////////// + +#ifndef TARGET_BOARD_NANOCLR_H +#define TARGET_BOARD_NANOCLR_H + +#include + +#define OEMSYSTEMINFOSTRING "nanoCLR running @ @TARGET_BOARD@ built with ESP-IDF @IDF_VER@" + +#endif // TARGET_BOARD_NANOCLR_H diff --git a/targets/ESP32/ESP32_S3/target_BlockStorage.c b/targets/ESP32/ESP32_S3/target_BlockStorage.c new file mode 100644 index 0000000000..708823cdb7 --- /dev/null +++ b/targets/ESP32/ESP32_S3/target_BlockStorage.c @@ -0,0 +1,23 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include +#include +#include + +extern struct BlockStorageDevice Device_BlockStorage; +extern struct MEMORY_MAPPED_NOR_BLOCK_CONFIG Device_BlockStorageConfig; +extern IBlockStorageDevice ESP32Flash_BlockStorageInterface; + +void BlockStorage_AddDevices() +{ + // add device AND request initialization + // required to setup flash partitions memory mapping + BlockStorageList_AddDevice( + (BlockStorageDevice *)&Device_BlockStorage, + &ESP32Flash_BlockStorageInterface, + &Device_BlockStorageConfig, + true); +} diff --git a/targets/ESP32/ESP32_S3/target_BlockStorage.h b/targets/ESP32/ESP32_S3/target_BlockStorage.h new file mode 100644 index 0000000000..658820a8f3 --- /dev/null +++ b/targets/ESP32/ESP32_S3/target_BlockStorage.h @@ -0,0 +1,12 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#ifndef TARGETPAL_BLOCKSTORAGE_H +#define TARGETPAL_BLOCKSTORAGE_H + +// this device has 1 block storage devices +#define TARGET_BLOCKSTORAGE_COUNT 1 + +#endif // TARGETPAL_BLOCKSTORAGE_H diff --git a/targets/ESP32/ESP32_S3/target_common.c b/targets/ESP32/ESP32_S3/target_common.c new file mode 100644 index 0000000000..de8b0d020a --- /dev/null +++ b/targets/ESP32/ESP32_S3/target_common.c @@ -0,0 +1,29 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Portions Copyright (c) Microsoft Corporation. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +#include +#include "target_board.h" +#include "target_common.h" + +#include + +HAL_SYSTEM_CONFIG HalSystemConfig = { + {true}, // HAL_DRIVER_CONFIG_HEADER Header; + + 1, // ConvertCOM_DebugHandle(1), + 0, // ConvertCOM_DebugHandle(0), + 921600, + 0, // STDIO = COM2 or COM1 + + {RAM1_MEMORY_StartAddress, RAM1_MEMORY_Size}, + {FLASH1_MEMORY_StartAddress, FLASH1_MEMORY_Size}}; + +HAL_TARGET_CONFIGURATION g_TargetConfiguration; + +void FixUpHalSystemConfig() +{ + HalSystemConfig.FLASH1.Size = g_rom_flashchip.chip_size; +} diff --git a/targets/ESP32/ESP32_S3/target_common.h.in b/targets/ESP32/ESP32_S3/target_common.h.in new file mode 100644 index 0000000000..6794119b58 --- /dev/null +++ b/targets/ESP32/ESP32_S3/target_common.h.in @@ -0,0 +1,49 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +////////////////////////////////////////////////////////////////////////////// +// This file was automatically generated by a tool. // +// Any changes you make here will be overwritten when it's generated again. // +////////////////////////////////////////////////////////////////////////////// + +#ifndef TARGET_COMMON_H +#define TARGET_COMMON_H + +#include + +/////////////////////////////////////////////////////////////////////// +// RAM start address and size is filled @ HeapLocation() during boot // +/////////////////////////////////////////////////////////////////////// + +// RAM base address +#define RAM1_MEMORY_StartAddress (0x0) +// RAM size +#define RAM1_MEMORY_Size (0x0) + +///////////////////////////////////////////////////////////////////////////////// +// FLASH start address and size is filled @ FixUpHalSystemConfig() during boot // +///////////////////////////////////////////////////////////////////////////////// + +// FLASH base address +#define FLASH1_MEMORY_StartAddress (0x0) +// FLASH size +#define FLASH1_MEMORY_Size (0x0) + +///////////////////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////// +#define TARGETNAMESTRING "@TARGET_NAME@" +#define PLATFORMNAMESTRING "ESP32" +////////////////////////////////////////////// + +///////////////////////////////////// +#define PLATFORM_HAS_RNG TRUE +///////////////////////////////////// + +///////////////////////////////////// +// #define EVENTS_HEART_BEAT +///////////////////////////////////// + +#endif // TARGET_COMMON_H diff --git a/targets/ESP32/ESP32_S3/target_lwip_sntp_opts.h b/targets/ESP32/ESP32_S3/target_lwip_sntp_opts.h new file mode 100644 index 0000000000..c4d09f1f1a --- /dev/null +++ b/targets/ESP32/ESP32_S3/target_lwip_sntp_opts.h @@ -0,0 +1,8 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +////////////////////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS BLANK ON PURPOSE BECAUSE THIS TARGET DOESN'T OVERRIDE ANY lwIP SNTP OPTIONS // +////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/targets/ESP32/ESP32_S3/target_lwipopts.h b/targets/ESP32/ESP32_S3/target_lwipopts.h new file mode 100644 index 0000000000..ca1a0b4465 --- /dev/null +++ b/targets/ESP32/ESP32_S3/target_lwipopts.h @@ -0,0 +1,8 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +///////////////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS BLANK ON PURPOSE BECAUSE THIS TARGET DOESN'T OVERRIDE ANY lwIP OPTIONS // +///////////////////////////////////////////////////////////////////////////////////////// diff --git a/targets/ESP32/ESP32_S3/target_nf_dev_onewire_config.cpp b/targets/ESP32/ESP32_S3/target_nf_dev_onewire_config.cpp new file mode 100644 index 0000000000..949567e829 --- /dev/null +++ b/targets/ESP32/ESP32_S3/target_nf_dev_onewire_config.cpp @@ -0,0 +1,8 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS BLANK ON PURPOSE BECAUSE THIS TARGET DOESN'T REQUIRE THIS SPECIFIC CONFIGURATION // +/////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/targets/ESP32/ESP32_S3/target_nf_dev_onewire_config.h b/targets/ESP32/ESP32_S3/target_nf_dev_onewire_config.h new file mode 100644 index 0000000000..167ba490d6 --- /dev/null +++ b/targets/ESP32/ESP32_S3/target_nf_dev_onewire_config.h @@ -0,0 +1,10 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +// use UART 2 for the 1-wire interface +#define NF_ONEWIRE_ESP32_UART_NUM UART_NUM_2 +// use GPIO port 16 for RX and 17 for TX +#define NF_ONEWIRE_ESP32_UART_RX_PIN UART_NUM_2_RXD_DIRECT_GPIO_NUM +#define NF_ONEWIRE_ESP32_UART_TX_PIN UART_NUM_2_TXD_DIRECT_GPIO_NUM diff --git a/targets/ESP32/ESP32_S3/target_system_device_adc_config.cpp b/targets/ESP32/ESP32_S3/target_system_device_adc_config.cpp new file mode 100644 index 0000000000..949567e829 --- /dev/null +++ b/targets/ESP32/ESP32_S3/target_system_device_adc_config.cpp @@ -0,0 +1,8 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS BLANK ON PURPOSE BECAUSE THIS TARGET DOESN'T REQUIRE THIS SPECIFIC CONFIGURATION // +/////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/targets/ESP32/ESP32_S3/target_system_device_dac_config.cpp b/targets/ESP32/ESP32_S3/target_system_device_dac_config.cpp new file mode 100644 index 0000000000..949567e829 --- /dev/null +++ b/targets/ESP32/ESP32_S3/target_system_device_dac_config.cpp @@ -0,0 +1,8 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS BLANK ON PURPOSE BECAUSE THIS TARGET DOESN'T REQUIRE THIS SPECIFIC CONFIGURATION // +/////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/targets/ESP32/ESP32_S3/target_system_device_i2c_config.cpp b/targets/ESP32/ESP32_S3/target_system_device_i2c_config.cpp new file mode 100644 index 0000000000..949567e829 --- /dev/null +++ b/targets/ESP32/ESP32_S3/target_system_device_i2c_config.cpp @@ -0,0 +1,8 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS BLANK ON PURPOSE BECAUSE THIS TARGET DOESN'T REQUIRE THIS SPECIFIC CONFIGURATION // +/////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/targets/ESP32/ESP32_S3/target_system_device_i2s_config.cpp b/targets/ESP32/ESP32_S3/target_system_device_i2s_config.cpp new file mode 100644 index 0000000000..949567e829 --- /dev/null +++ b/targets/ESP32/ESP32_S3/target_system_device_i2s_config.cpp @@ -0,0 +1,8 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS BLANK ON PURPOSE BECAUSE THIS TARGET DOESN'T REQUIRE THIS SPECIFIC CONFIGURATION // +/////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/targets/ESP32/ESP32_S3/target_system_device_pwm_config.cpp b/targets/ESP32/ESP32_S3/target_system_device_pwm_config.cpp new file mode 100644 index 0000000000..73cc6666d3 --- /dev/null +++ b/targets/ESP32/ESP32_S3/target_system_device_pwm_config.cpp @@ -0,0 +1,9 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS BLANK ON PURPOSE BECAUSE THIS TARGET DOESN'T REQUIRE THIS SPECIFIC CONFIGURATION // +/////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/targets/ESP32/ESP32_S3/target_system_device_spi_config.cpp b/targets/ESP32/ESP32_S3/target_system_device_spi_config.cpp new file mode 100644 index 0000000000..949567e829 --- /dev/null +++ b/targets/ESP32/ESP32_S3/target_system_device_spi_config.cpp @@ -0,0 +1,8 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS BLANK ON PURPOSE BECAUSE THIS TARGET DOESN'T REQUIRE THIS SPECIFIC CONFIGURATION // +/////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/targets/ESP32/ESP32_S3/target_system_devices_dac_config.cpp b/targets/ESP32/ESP32_S3/target_system_devices_dac_config.cpp new file mode 100644 index 0000000000..949567e829 --- /dev/null +++ b/targets/ESP32/ESP32_S3/target_system_devices_dac_config.cpp @@ -0,0 +1,8 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS BLANK ON PURPOSE BECAUSE THIS TARGET DOESN'T REQUIRE THIS SPECIFIC CONFIGURATION // +/////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/targets/ESP32/ESP32_S3/target_system_io_ports_config.cpp b/targets/ESP32/ESP32_S3/target_system_io_ports_config.cpp new file mode 100644 index 0000000000..949567e829 --- /dev/null +++ b/targets/ESP32/ESP32_S3/target_system_io_ports_config.cpp @@ -0,0 +1,8 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS BLANK ON PURPOSE BECAUSE THIS TARGET DOESN'T REQUIRE THIS SPECIFIC CONFIGURATION // +/////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/targets/ESP32/ESP32_S3/target_windows_storage_config.h b/targets/ESP32/ESP32_S3/target_windows_storage_config.h new file mode 100644 index 0000000000..b2d2dec961 --- /dev/null +++ b/targets/ESP32/ESP32_S3/target_windows_storage_config.h @@ -0,0 +1,5 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + diff --git a/targets/ESP32/_IDF/esp32s3/app_main.c b/targets/ESP32/_IDF/esp32s3/app_main.c new file mode 100644 index 0000000000..1447d834f9 --- /dev/null +++ b/targets/ESP32/_IDF/esp32s3/app_main.c @@ -0,0 +1,69 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include +#include +#include +#include +#include +#include + +extern void CLRStartupThread(void const *argument); +TaskHandle_t ReceiverTask; + +void receiver_task(void *pvParameter) +{ + (void)pvParameter; + + ReceiverThread(0); + + vTaskDelete(NULL); +} + +// Main task start point +void main_task(void *pvParameter) +{ + (void)pvParameter; + + // CLR settings to launch CLR thread + CLR_SETTINGS clrSettings; + (void)memset(&clrSettings, 0, sizeof(CLR_SETTINGS)); + + clrSettings.MaxContextSwitches = 50; + clrSettings.WaitForDebugger = false; + clrSettings.EnterDebuggerLoopAfterExit = true; + + CLRStartupThread(&clrSettings); + + vTaskDelete(NULL); +} + +// Dummy defauly log method to stop output from ESP32 IDF +int dummyLog(const char *format, va_list arg) +{ + (void)format; + (void)arg; + return 1; +} + +// App_main +// Called from Esp32 IDF start up code before scheduler starts +void app_main() +{ + // Switch off logging so as not to interfere with WireProtocol over Uart0 + esp_log_level_set("*", ESP_LOG_NONE); + + // Stop any logging being directed to VS connection, was an issue with Nimble, outputting on Uart0 + // TODO : redirect these to debugger controlled from nanoframework.Hardware.Esp32 + esp_log_set_vprintf(dummyLog); + + ESP_ERROR_CHECK(nvs_flash_init()); + + // start receiver task + xTaskCreatePinnedToCore(&receiver_task, "ReceiverThread", 3072, NULL, 5, &ReceiverTask, 0); + + // start the CLR main task + xTaskCreatePinnedToCore(&main_task, "main_task", 15000, NULL, 5, NULL, 0); +} diff --git a/targets/ESP32/_IDF/esp32s3/partitions_nanoclr_16mb.csv b/targets/ESP32/_IDF/esp32s3/partitions_nanoclr_16mb.csv new file mode 100644 index 0000000000..f633548c1e --- /dev/null +++ b/targets/ESP32/_IDF/esp32s3/partitions_nanoclr_16mb.csv @@ -0,0 +1,17 @@ +################################################ +# ESP-IDF Partition Table for .NET nanoFramework +# Name, Type, SubType, Offset, Size, +############################################################################################################################### +# if you change the partitions here, make sure to update the BlockRegions array in the device BlockStorage configuration file # +############################################################################################################################### +nvs, data, nvs, 0x9000, 0x6000, +phy_init, data, phy, 0xf000, 0x1000, +# Factory area for NanoCLR - 1664k +factory, app, factory, 0x10000, 0x1A0000, +# Deployment area for Managed code 2944k, Mapping issues with deployment areas over 3.5Mb, see issue #691 +deploy, data, 0x84, 0x1B0000, 0x2E0000, +# Config data for Network, Wireless, certificates, user data 3MB +config, data, spiffs, 0x490000, 0x300000, +########################################## +# total size has to be 0x1000000 or less # +########################################## diff --git a/targets/ESP32/_IDF/esp32s3/partitions_nanoclr_4mb.csv b/targets/ESP32/_IDF/esp32s3/partitions_nanoclr_4mb.csv new file mode 100644 index 0000000000..80a38190b2 --- /dev/null +++ b/targets/ESP32/_IDF/esp32s3/partitions_nanoclr_4mb.csv @@ -0,0 +1,17 @@ +################################################ +# ESP-IDF Partition Table for .NET nanoFramework +# Name, Type, SubType, Offset, Size, +############################################################################################################################### +# if you change the partitions here, make sure to update the BlockRegions array in the device BlockStorage configuration file # +############################################################################################################################### +nvs, data, nvs, 0x9000, 0x6000, +phy_init, data, phy, 0xf000, 0x1000, +# Factory area for NanoCLR - 1664k +factory, app, factory, 0x10000, 0x1A0000, +# Deployment area for Managed code 1984k +deploy, data, 0x84, 0x1B0000, 0x1F0000, +# Config data for Network, Wireless, certificates, user data 256k +config, data, spiffs, 0x3C0000, 0x40000, +################################# +# total size has to be 0x400000 # +################################# diff --git a/targets/ESP32/_IDF/esp32s3/partitions_nanoclr_8mb.csv b/targets/ESP32/_IDF/esp32s3/partitions_nanoclr_8mb.csv new file mode 100644 index 0000000000..6c1fffde8d --- /dev/null +++ b/targets/ESP32/_IDF/esp32s3/partitions_nanoclr_8mb.csv @@ -0,0 +1,17 @@ +################################################ +# ESP-IDF Partition Table for .NET nanoFramework +# Name, Type, SubType, Offset, Size, +############################################################################################################################### +# if you change the partitions here, make sure to update the BlockRegions array in the device BlockStorage configuration file # +############################################################################################################################### +nvs, data, nvs, 0x9000, 0x6000, +phy_init, data, phy, 0xf000, 0x1000, +# Factory area for NanoCLR - 1664k +factory, app, factory, 0x10000, 0x1A0000, +# Deployment area for Managed code 2944k, Mapping issues with deployment areas over 3.5Mb, see issue #691 +deploy, data, 0x84, 0x1B0000, 0x2E0000, +# Config data for Network, Wireless, certificates, user data 2Mb +config, data, spiffs, 0x490000, 0x200000, +########################################## +# total size has to be 0x800000 or less # +########################################## diff --git a/targets/ESP32/_IDF/project_elf_src_esp32.c b/targets/ESP32/_IDF/project_elf_src_esp32.c new file mode 100644 index 0000000000..c19b2ff9b4 --- /dev/null +++ b/targets/ESP32/_IDF/project_elf_src_esp32.c @@ -0,0 +1,8 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +/////////////////////////////////// +// THIS FILE IS BLANK ON PURPOSE // +/////////////////////////////////// diff --git a/targets/ESP32/_IDF/project_elf_src_esp32c3.c b/targets/ESP32/_IDF/project_elf_src_esp32c3.c new file mode 100644 index 0000000000..c19b2ff9b4 --- /dev/null +++ b/targets/ESP32/_IDF/project_elf_src_esp32c3.c @@ -0,0 +1,8 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +/////////////////////////////////// +// THIS FILE IS BLANK ON PURPOSE // +/////////////////////////////////// diff --git a/targets/ESP32/_IDF/project_elf_src_esp32s2.c b/targets/ESP32/_IDF/project_elf_src_esp32s2.c new file mode 100644 index 0000000000..c19b2ff9b4 --- /dev/null +++ b/targets/ESP32/_IDF/project_elf_src_esp32s2.c @@ -0,0 +1,8 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +/////////////////////////////////// +// THIS FILE IS BLANK ON PURPOSE // +/////////////////////////////////// diff --git a/targets/ESP32/_IDF/project_elf_src_esp32s3.c b/targets/ESP32/_IDF/project_elf_src_esp32s3.c new file mode 100644 index 0000000000..c19b2ff9b4 --- /dev/null +++ b/targets/ESP32/_IDF/project_elf_src_esp32s3.c @@ -0,0 +1,8 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +/////////////////////////////////// +// THIS FILE IS BLANK ON PURPOSE // +/////////////////////////////////// diff --git a/targets/ESP32/_IDF/sdkconfig.debug_nopsram_ble.esp32 b/targets/ESP32/_IDF/sdkconfig.debug_nopsram_ble.esp32 index 4e0d7449b0..6b77761b74 100644 --- a/targets/ESP32/_IDF/sdkconfig.debug_nopsram_ble.esp32 +++ b/targets/ESP32/_IDF/sdkconfig.debug_nopsram_ble.esp32 @@ -597,9 +597,8 @@ CONFIG_ESP_TIMER_IMPL_TG0_LAC=y CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE=y CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 -CONFIG_ESP32_WIFI_STATIC_TX_BUFFER=y -# CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER is not set -CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=0 +# CONFIG_ESP32_WIFI_STATIC_TX_BUFFER is not set +CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y CONFIG_ESP32_WIFI_STATIC_TX_BUFFER_NUM=16 # CONFIG_ESP32_WIFI_CSI_ENABLED is not set CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y @@ -939,12 +938,14 @@ CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384 CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 CONFIG_MBEDTLS_DYNAMIC_BUFFER=y +CONFIG_MBEDTLS_DYNAMIC_FREE_PEER_CERT=y # CONFIG_MBEDTLS_DEBUG is not set # # Certificate Bundle # -# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE is not set +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE=y # end of Certificate Bundle # CONFIG_MBEDTLS_ECP_RESTARTABLE is not set @@ -1160,8 +1161,8 @@ CONFIG_SPIFFS_CACHE_WR=y CONFIG_SPIFFS_PAGE_CHECK=y CONFIG_SPIFFS_GC_MAX_RUNS=10 # CONFIG_SPIFFS_GC_STATS is not set -CONFIG_SPIFFS_PAGE_SIZE=256 -CONFIG_SPIFFS_OBJ_NAME_LEN=32 +CONFIG_SPIFFS_PAGE_SIZE=512 +CONFIG_SPIFFS_OBJ_NAME_LEN=256 # CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set CONFIG_SPIFFS_USE_MAGIC=y CONFIG_SPIFFS_USE_MAGIC_LENGTH=y diff --git a/targets/ESP32/_IDF/sdkconfig.default b/targets/ESP32/_IDF/sdkconfig.default index 7695d623bf..24df5cf913 100644 --- a/targets/ESP32/_IDF/sdkconfig.default +++ b/targets/ESP32/_IDF/sdkconfig.default @@ -385,7 +385,6 @@ CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 CONFIG_ESP32_WIFI_STATIC_TX_BUFFER=y # CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER is not set -CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 # CONFIG_ESP32_WIFI_CSI_ENABLED is not set CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y @@ -712,6 +711,7 @@ CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 CONFIG_MBEDTLS_DYNAMIC_BUFFER=y # CONFIG_MBEDTLS_DEBUG is not set CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH=y +CONFIG_MBEDTLS_DYNAMIC_FREE_PEER_CERT=y # CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is not set # @@ -720,7 +720,8 @@ CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH=y # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE is not set # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL is not set # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set -# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE=y # CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set # end of Certificate Bundle @@ -935,8 +936,8 @@ CONFIG_SPIFFS_CACHE_WR=y CONFIG_SPIFFS_PAGE_CHECK=y CONFIG_SPIFFS_GC_MAX_RUNS=10 # CONFIG_SPIFFS_GC_STATS is not set -CONFIG_SPIFFS_PAGE_SIZE=256 -CONFIG_SPIFFS_OBJ_NAME_LEN=32 +CONFIG_SPIFFS_PAGE_SIZE=512 +CONFIG_SPIFFS_OBJ_NAME_LEN=256 # CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set CONFIG_SPIFFS_USE_MAGIC=y CONFIG_SPIFFS_USE_MAGIC_LENGTH=y diff --git a/targets/ESP32/_IDF/sdkconfig.default.esp32 b/targets/ESP32/_IDF/sdkconfig.default.esp32 index 2bcf7a813a..4223d5aa7b 100644 --- a/targets/ESP32/_IDF/sdkconfig.default.esp32 +++ b/targets/ESP32/_IDF/sdkconfig.default.esp32 @@ -480,7 +480,6 @@ CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 CONFIG_ESP32_WIFI_STATIC_TX_BUFFER=y # CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER is not set -CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 # CONFIG_ESP32_WIFI_CSI_ENABLED is not set CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y @@ -806,6 +805,7 @@ CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384 CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 CONFIG_MBEDTLS_DYNAMIC_BUFFER=y CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH=y +CONFIG_MBEDTLS_DYNAMIC_FREE_PEER_CERT=y # CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is not set # @@ -814,7 +814,8 @@ CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH=y # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE is not set # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL is not set # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set -# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE=y # CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set # end of Certificate Bundle @@ -1029,8 +1030,8 @@ CONFIG_SPIFFS_CACHE_WR=y CONFIG_SPIFFS_PAGE_CHECK=y CONFIG_SPIFFS_GC_MAX_RUNS=10 # CONFIG_SPIFFS_GC_STATS is not set -CONFIG_SPIFFS_PAGE_SIZE=256 -CONFIG_SPIFFS_OBJ_NAME_LEN=32 +CONFIG_SPIFFS_PAGE_SIZE=512 +CONFIG_SPIFFS_OBJ_NAME_LEN=256 # CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set CONFIG_SPIFFS_USE_MAGIC=y CONFIG_SPIFFS_USE_MAGIC_LENGTH=y diff --git a/targets/ESP32/_IDF/sdkconfig.default.esp32c3 b/targets/ESP32/_IDF/sdkconfig.default.esp32c3 index 3544616c05..f1bad37023 100644 --- a/targets/ESP32/_IDF/sdkconfig.default.esp32c3 +++ b/targets/ESP32/_IDF/sdkconfig.default.esp32c3 @@ -306,22 +306,6 @@ CONFIG_ESP32C3_RTC_CLK_CAL_CYCLES=1024 # CONFIG_ESP32C3_NO_BLOBS is not set # end of ESP32C3-Specific -# -# Cache config -# -CONFIG_ESP32S2_INSTRUCTION_CACHE_8KB=y -# CONFIG_ESP32S2_INSTRUCTION_CACHE_16KB is not set -# CONFIG_ESP32S2_INSTRUCTION_CACHE_LINE_16B is not set -CONFIG_ESP32S2_INSTRUCTION_CACHE_LINE_32B=y -CONFIG_ESP32S2_DATA_CACHE_0KB=y -# CONFIG_ESP32S2_DATA_CACHE_8KB is not set -# CONFIG_ESP32S2_DATA_CACHE_16KB is not set -# CONFIG_ESP32S2_DATA_CACHE_LINE_16B is not set -CONFIG_ESP32S2_DATA_CACHE_LINE_32B=y -# CONFIG_ESP32S2_INSTRUCTION_CACHE_WRAP is not set -# CONFIG_ESP32S2_DATA_CACHE_WRAP is not set -# end of Cache config - CONFIG_ESP32S2_SPIRAM_SUPPORT=y # CONFIG_ESP32S2_TRAX is not set CONFIG_ESP32S2_TRACEMEM_RESERVE_DRAM=0x0 @@ -516,7 +500,6 @@ CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 # CONFIG_ESP32_WIFI_STATIC_TX_BUFFER=y # CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER is not set -CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 # CONFIG_ESP32_WIFI_CSI_ENABLED is not set CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y @@ -840,8 +823,9 @@ CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384 CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 CONFIG_MBEDTLS_DYNAMIC_BUFFER=y -CONFIG_MBEDTLS_DEBUG=y +# CONFIG_MBEDTLS_DEBUG=y CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH=y +CONFIG_MBEDTLS_DYNAMIC_FREE_PEER_CERT=y # CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is not set # @@ -850,7 +834,8 @@ CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH=y # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE is not set # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL is not set # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set -# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE=y # CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set # end of Certificate Bundle @@ -1065,8 +1050,8 @@ CONFIG_SPIFFS_CACHE_WR=y CONFIG_SPIFFS_PAGE_CHECK=y CONFIG_SPIFFS_GC_MAX_RUNS=10 # CONFIG_SPIFFS_GC_STATS is not set -CONFIG_SPIFFS_PAGE_SIZE=256 -CONFIG_SPIFFS_OBJ_NAME_LEN=32 +CONFIG_SPIFFS_PAGE_SIZE=512 +CONFIG_SPIFFS_OBJ_NAME_LEN=256 # CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set CONFIG_SPIFFS_USE_MAGIC=y CONFIG_SPIFFS_USE_MAGIC_LENGTH=y diff --git a/targets/ESP32/_IDF/sdkconfig.default.esp32s2 b/targets/ESP32/_IDF/sdkconfig.default.esp32s2 index c84b7f744c..20c3c166af 100644 --- a/targets/ESP32/_IDF/sdkconfig.default.esp32s2 +++ b/targets/ESP32/_IDF/sdkconfig.default.esp32s2 @@ -488,7 +488,6 @@ CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 # CONFIG_ESP32_WIFI_STATIC_TX_BUFFER=y # CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER is not set -CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 # CONFIG_ESP32_WIFI_CSI_ENABLED is not set CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y @@ -814,6 +813,7 @@ CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 CONFIG_MBEDTLS_DYNAMIC_BUFFER=y # CONFIG_MBEDTLS_DEBUG is not set CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH=y +CONFIG_MBEDTLS_DYNAMIC_FREE_PEER_CERT=y # CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is not set # @@ -822,7 +822,8 @@ CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH=y # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE is not set # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL is not set # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set -# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE=y # CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set # end of Certificate Bundle @@ -1037,8 +1038,8 @@ CONFIG_SPIFFS_CACHE_WR=y CONFIG_SPIFFS_PAGE_CHECK=y CONFIG_SPIFFS_GC_MAX_RUNS=10 # CONFIG_SPIFFS_GC_STATS is not set -CONFIG_SPIFFS_PAGE_SIZE=256 -CONFIG_SPIFFS_OBJ_NAME_LEN=32 +CONFIG_SPIFFS_PAGE_SIZE=512 +CONFIG_SPIFFS_OBJ_NAME_LEN=256 # CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set CONFIG_SPIFFS_USE_MAGIC=y CONFIG_SPIFFS_USE_MAGIC_LENGTH=y diff --git a/targets/ESP32/_IDF/sdkconfig.default.esp32s3 b/targets/ESP32/_IDF/sdkconfig.default.esp32s3 new file mode 100644 index 0000000000..6dd553ba23 --- /dev/null +++ b/targets/ESP32/_IDF/sdkconfig.default.esp32s3 @@ -0,0 +1,1112 @@ +# +# Automatically generated file. DO NOT EDIT. +# Espressif IoT Development Framework (ESP-IDF) Project Configuration +# +CONFIG_IDF_CMAKE=y +CONFIG_IDF_TARGET_ARCH_XTENSA=y +CONFIG_IDF_TARGET="esp32s3" +CONFIG_IDF_TARGET_ESP32S3=y +CONFIG_IDF_FIRMWARE_CHIP_ID=0x0009 + +# +# SDK tool configuration +# +CONFIG_SDK_TOOLPREFIX="xtensa-esp32s3-elf-" +# CONFIG_SDK_TOOLCHAIN_SUPPORTS_TIME_WIDE_64_BITS is not set +# end of SDK tool configuration + +# +# Build type +# +CONFIG_APP_BUILD_TYPE_APP_2NDBOOT=y +# CONFIG_APP_BUILD_TYPE_ELF_RAM is not set +CONFIG_APP_BUILD_GENERATE_BINARIES=y +CONFIG_APP_BUILD_BOOTLOADER=y +CONFIG_APP_BUILD_USE_FLASH_SECTIONS=y +# end of Build type + +# +# Application manager +# +CONFIG_APP_COMPILE_TIME_DATE=y +# CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set +# CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set +# CONFIG_APP_PROJECT_VER_FROM_CONFIG is not set +CONFIG_APP_RETRIEVE_LEN_ELF_SHA=16 +# end of Application manager + +# +# Bootloader config +# +CONFIG_BOOTLOADER_OFFSET_IN_FLASH=0x0000 +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG=y +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set +CONFIG_BOOTLOADER_LOG_LEVEL_INFO=y +# CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set +CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y +# CONFIG_BOOTLOADER_FACTORY_RESET is not set +# CONFIG_BOOTLOADER_APP_TEST is not set +CONFIG_BOOTLOADER_WDT_ENABLE=y +# CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE is not set +CONFIG_BOOTLOADER_WDT_TIME_MS=9000 +# CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS is not set +CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 +# CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC is not set +# end of Bootloader config + +# +# Security features +# +CONFIG_SECURE_BOOT_SUPPORTS_RSA=y +CONFIG_SECURE_TARGET_HAS_SECURE_ROM_DL_MODE=y +# CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set +# CONFIG_SECURE_BOOT is not set +# CONFIG_SECURE_FLASH_ENC_ENABLED is not set +# CONFIG_SECURE_BOOT_ALLOW_JTAG is not set +# end of Security features + +# +# Serial flasher config +# +CONFIG_ESPTOOLPY_BAUD_OTHER_VAL=115200 +# CONFIG_ESPTOOLPY_NO_STUB is not set +# CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set +# CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set +# CONFIG_ESPTOOLPY_FLASHMODE_DIO is not set +# CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set +# CONFIG_ESPTOOLPY_FLASHFREQ_40M is not set +# CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set +# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set +# CONFIG_ESPTOOLPY_FLASHFREQ_80M is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y +CONFIG_ESPTOOLPY_FLASHSIZE="8MB" +CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y +CONFIG_ESPTOOLPY_BEFORE_RESET=y +# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set +CONFIG_ESPTOOLPY_BEFORE="default_reset" +CONFIG_ESPTOOLPY_AFTER_RESET=y +# CONFIG_ESPTOOLPY_AFTER_NORESET is not set +CONFIG_ESPTOOLPY_AFTER="hard_reset" +# CONFIG_ESPTOOLPY_MONITOR_BAUD_CONSOLE is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_9600B is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_57600B is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_115200B is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_230400B is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_921600B=y +# CONFIG_ESPTOOLPY_MONITOR_BAUD_2MB is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_OTHER is not set +CONFIG_ESPTOOLPY_MONITOR_BAUD_OTHER_VAL=115200 +CONFIG_ESPTOOLPY_MONITOR_BAUD=921600 +# end of Serial flasher config + +# +# Partition Table +# +CONFIG_PARTITION_TABLE_SINGLE_APP=y +# CONFIG_PARTITION_TABLE_TWO_OTA is not set +CONFIG_PARTITION_TABLE_CUSTOM=y +# default to 8mb partition table for nanoCLR +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="targets/ESP32/_IDF/esp32s3/partitions_nanoclr_8mb.csv" +# CONFIG_PARTITION_TABLE_FILENAME is not set +CONFIG_PARTITION_TABLE_OFFSET=0x8000 +CONFIG_PARTITION_TABLE_MD5=y +# end of Partition Table + +# +# Compiler options +# +# CONFIG_COMPILER_OPTIMIZATION_DEFAULT=y +CONFIG_COMPILER_OPTIMIZATION_SIZE=y +# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE=y +# CONFIG_COMPILER_CXX_EXCEPTIONS is not set +# CONFIG_COMPILER_CXX_RTTI is not set +CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y +# CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set +# CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set +# CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set +# CONFIG_COMPILER_WARN_WRITE_STRINGS is not set +# CONFIG_COMPILER_DISABLE_GCC8_WARNINGS is not set +# CONFIG_COMPILER_DUMP_RTL_FILES is not set +# end of Compiler options + +# +# Component config +# + +# +# Application Level Tracing +# +# CONFIG_APPTRACE_DEST_TRAX is not set +CONFIG_APPTRACE_DEST_NONE=y +CONFIG_APPTRACE_LOCK_ENABLE=y +# end of Application Level Tracing + +# +# ESP-ASIO +# +# CONFIG_ASIO_SSL_SUPPORT is not set +# end of ESP-ASIO + +CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 +CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 +CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 +CONFIG_BTDM_CTRL_BLE_MAX_CONN_EFF=0 +CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN_EFF=0 +CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF=0 +CONFIG_BTDM_CTRL_PINNED_TO_CORE=0 +CONFIG_BTDM_BLE_SLEEP_CLOCK_ACCURACY_INDEX_EFF=1 +CONFIG_BT_CTRL_MODE_EFF=1 +CONFIG_BT_CTRL_BLE_MAX_ACT=10 +CONFIG_BT_CTRL_BLE_MAX_ACT_EFF=10 +CONFIG_BT_CTRL_BLE_STATIC_ACL_TX_BUF_NB=0 +CONFIG_BT_CTRL_PINNED_TO_CORE=0 +CONFIG_BT_CTRL_HCI_TL=1 +CONFIG_BT_CTRL_ADV_DUP_FILT_MAX=30 +CONFIG_BT_CTRL_HW_CCA_EFF=0 +CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_EFF=0 +CONFIG_BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y +CONFIG_BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 +CONFIG_BT_CTRL_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 +CONFIG_BT_CTRL_BLE_SCAN_DUPL=y +CONFIG_BT_CTRL_SCAN_DUPL_TYPE=0 +CONFIG_BT_CTRL_SCAN_DUPL_CACHE_SIZE=100 +CONFIG_BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM_EFF=0 +CONFIG_BT_CTRL_SLEEP_MODE_EFF=0 +CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 +CONFIG_BT_CTRL_HCI_TL_EFF=1 +CONFIG_BT_RESERVE_DRAM=0 +CONFIG_BT_NIMBLE_USE_ESP_TIMER=y + +# +# CoAP Configuration +# +CONFIG_COAP_MBEDTLS_PSK=y +# CONFIG_COAP_MBEDTLS_PKI is not set +# CONFIG_COAP_MBEDTLS_DEBUG is not set +CONFIG_COAP_LOG_DEFAULT_LEVEL=0 +# end of CoAP Configuration + +# +# Driver configurations +# + +# +# ADC configuration +# +# CONFIG_ADC_FORCE_XPD_FSM is not set +CONFIG_ADC_DISABLE_DAC=y +# end of ADC configuration + +# +# SPI configuration +# +# CONFIG_SPI_MASTER_IN_IRAM is not set +CONFIG_SPI_MASTER_ISR_IN_IRAM=y +# CONFIG_SPI_SLAVE_IN_IRAM is not set +CONFIG_SPI_SLAVE_ISR_IN_IRAM=y +# end of SPI configuration + +# +# TWAI configuration +# +# CONFIG_TWAI_ISR_IN_IRAM is not set +# end of TWAI configuration + +# +# UART configuration +# +CONFIG_UART_ISR_IN_IRAM=y +# end of UART configuration +# end of Driver configurations + +# +# eFuse Bit Manager +# +# CONFIG_EFUSE_CUSTOM_TABLE is not set +# CONFIG_EFUSE_VIRTUAL is not set +CONFIG_EFUSE_MAX_BLK_LEN=256 +# end of eFuse Bit Manager + +# +# SPI RAM config +# +CONFIG_SPIRAM_BOOT_INIT=y +CONFIG_SPIRAM_IGNORE_NOTFOUND=y +CONFIG_SPIRAM_USE_MEMMAP=n +CONFIG_SPIRAM_USE_CAPS_ALLOC=n +CONFIG_SPIRAM_USE_MALLOC=y +CONFIG_SPIRAM_TYPE_AUTO=y +CONFIG_SPIRAM_TYPE_ESPPSRAM32=n +CONFIG_SPIRAM_TYPE_ESPPSRAM64=n +CONFIG_SPIRAM_SIZE=-1 +CONFIG_SPIRAM_SPEED_40M=y +# CONFIG_SPIRAM_MEMTEST is not set +CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=16384 +CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=n +CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=32768 +CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=n +CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=n +CONFIG_ESP32S3_SPIRAM_SUPPORT=y +CONFIG_SPIRAM_MODE_QUAD=y + +# +# ESP-TLS +# +CONFIG_ESP_TLS_USING_MBEDTLS=y +CONFIG_ESP_TLS_USE_DS_PERIPHERAL=y +# CONFIG_ESP_TLS_SERVER is not set +# CONFIG_ESP_TLS_PSK_VERIFICATION is not set +# CONFIG_ESP_TLS_INSECURE is not set +# end of ESP-TLS + + +# +# ESP32S3-Specific +# +CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240=y +CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ=240 +CONFIG_ESP32S3_DEBUG_OCDAWARE=y +CONFIG_ESP32S3_BROWNOUT_DET=y +CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_7=y +# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_2 is not set +CONFIG_ESP32S3_BROWNOUT_DET_LVL=7 +CONFIG_ESP32S3_TIME_SYSCALL_USE_RTC_SYSTIMER=y +# CONFIG_ESP32S3_TIME_SYSCALL_USE_RTC is not set +# CONFIG_ESP32S3_TIME_SYSCALL_USE_SYSTIMER is not set +# CONFIG_ESP32S3_TIME_SYSCALL_USE_NONE is not set +CONFIG_ESP32S3_RTC_CLK_SRC_INT_RC=y +# CONFIG_ESP32S3_RTC_CLK_SRC_EXT_CRYS is not set +# CONFIG_ESP32S3_RTC_CLK_SRC_EXT_OSC is not set +# CONFIG_ESP32S3_RTC_CLK_SRC_INT_8MD256 is not set +CONFIG_ESP32S3_RTC_CLK_CAL_CYCLES=1024 +# CONFIG_ESP32S3_NO_BLOBS is not set +# end of ESP32S3-Specific + +# +# ADC-Calibration +# +# end of ADC-Calibration + +# config for XTAL freq +# adding it here, so it can be overriden by our CMake +CONFIG_ESP32_XTAL_FREQ_40=y + +# +# Common ESP-related +# +CONFIG_ESP_ERR_TO_NAME_LOOKUP=y +CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 +CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=3584 +CONFIG_ESP_IPC_TASK_STACK_SIZE=1024 +CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048 +CONFIG_ESP_CONSOLE_UART_DEFAULT= +# CONFIG_ESP_CONSOLE_UART_CUSTOM is not set +# CONFIG_ESP_CONSOLE_NONE is not set +CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG=y +CONFIG_ESP_CONSOLE_UART=y +CONFIG_ESP_CONSOLE_MULTIPLE_UART=y +CONFIG_ESP_CONSOLE_UART_NUM=0 +CONFIG_ESP_CONSOLE_UART_BAUDRATE=921600 +CONFIG_ESP_INT_WDT=y +CONFIG_ESP_INT_WDT_TIMEOUT_MS=300 +# CONFIG_ESP_TASK_WDT is not set +# CONFIG_ESP_TASK_WDT_PANIC is not set +# CONFIG_ESP_TASK_WDT_TIMEOUT_S is not set +# CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0 is not set +# CONFIG_ESP_PANIC_HANDLER_IRAM is not set +CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_STA=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_AP=y +# end of Common ESP-related + +# +# Ethernet +# +# Parameters configured in binutils.ESP32.CMAKE +# +CONFIG_ETH_ENABLED=y +CONFIG_ETH_USE_ESP32_EMAC=y + +CONFIG_ETH_PHY_INTERFACE_RMII=y +# CONFIG_ETH_PHY_INTERFACE_MII is not set + +#CONFIG_ETH_RMII_CLK_OUTPUT=y +#CONFIG_ETH_RMII_CLK_OUT_GPIO=17 +#CONFIG_ETH_RMII_CLK_INPUT=y +#CONFIG_ETH_RMII_CLK_IN_GPIO=n + +CONFIG_ETH_DMA_BUFFER_SIZE=512 +CONFIG_ETH_DMA_RX_BUFFER_NUM=10 +CONFIG_ETH_DMA_TX_BUFFER_NUM=10 + +# Include SPI drivers in case used in build +CONFIG_ETH_USE_SPI_ETHERNET=y +#CONFIG_ETH_SPI_ETHERNET_DM9051=y +#CONFIG_ETH_SPI_ETHERNET_W5500=y +#CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL=y +#CONFIG_ETH_USE_OPENETH=n +# end of Ethernet + +# +# Event Loop Library +# +# CONFIG_ESP_EVENT_LOOP_PROFILING is not set +CONFIG_ESP_EVENT_POST_FROM_ISR=y +CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y +# end of Event Loop Library + +# +# GDB Stub +# +# end of GDB Stub + +# +# ESP HTTP client +# +CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y +# CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set +# end of ESP HTTP client + +# +# HTTP Server +# +CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 +CONFIG_HTTPD_MAX_URI_LEN=512 +CONFIG_HTTPD_ERR_RESP_NO_DELAY=y +CONFIG_HTTPD_PURGE_BUF_LEN=32 +# CONFIG_HTTPD_LOG_PURGE_DATA is not set +# CONFIG_HTTPD_WS_SUPPORT is not set +# end of HTTP Server + +# +# ESP HTTPS OTA +# +# CONFIG_OTA_ALLOW_HTTP is not set +# end of ESP HTTPS OTA + +# +# ESP HTTPS server +# +# CONFIG_ESP_HTTPS_SERVER_ENABLE is not set +# end of ESP HTTPS server + +# +# ESP NETIF Adapter +# +CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 +CONFIG_ESP_NETIF_TCPIP_LWIP=y +# CONFIG_ESP_NETIF_LOOPBACK is not set +# CONFIG_ESP_NETIF_TCPIP_ADAPTER_COMPATIBLE_LAYER is not set +# end of ESP NETIF Adapter + +# +# Power Management +# +CONFIG_PM_ENABLE=y +# end of Power Management + +# +# ESP System Settings +# +# CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT is not set +CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y +# CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set +# CONFIG_ESP_SYSTEM_PANIC_GDBSTUB is not set +CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE=y +CONFIG_ESP_SYSTEM_RTC_FAST_MEM_AS_HEAP_DEPCHECK=y +CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP=y +CONFIG_ESP_SLEEP_POWER_DOWN_FLASH=y + +# +# Memory protection +# +CONFIG_ESP_SYSTEM_MEMPROT_FEATURE=y +CONFIG_ESP_SYSTEM_MEMPROT_FEATURE_LOCK=y +# end of Memory protection +# end of ESP System Settings + +# +# High resolution timer (esp_timer) +# +# CONFIG_ESP_TIMER_PROFILING is not set +CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y +CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y +CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584 +CONFIG_ESP_TIMER_IMPL_SYSTIMER=y +# end of High resolution timer (esp_timer) + +# +# Wi-Fi +# +CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 +CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 +# CONFIG_ESP32_WIFI_STATIC_TX_BUFFER is not set +# CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER is not set +# CONFIG_ESP32_WIFI_TX_BUFFER_TYPE is not set +CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 +# CONFIG_ESP32_WIFI_CSI_ENABLED is not set +CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y +CONFIG_ESP32_WIFI_TX_BA_WIN=6 +CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y +CONFIG_ESP32_WIFI_RX_BA_WIN=6 +CONFIG_ESP32_WIFI_NVS_ENABLED=y +CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 +CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 +# CONFIG_WIFI_LOG_DEFAULT_LEVEL_NONE is not set +# CONFIG_WIFI_LOG_DEFAULT_LEVEL_ERROR is not set +# CONFIG_WIFI_LOG_DEFAULT_LEVEL_WARN is not set +CONFIG_WIFI_LOG_DEFAULT_LEVEL_INFO=y +# CONFIG_WIFI_LOG_DEFAULT_LEVEL_DEBUG is not set +# CONFIG_WIFI_LOG_DEFAULT_LEVEL_VERBOSE is not set +CONFIG_ESP32_WIFI_IRAM_OPT=y +CONFIG_ESP32_WIFI_RX_IRAM_OPT=y +CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y +# CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set +# CONFIG_ESP_WIFI_FTM_ENABLE is not set +# CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE is not set +# end of Wi-Fi + +# +# PHY +# +CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y +# CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set +CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=20 +CONFIG_ESP_PHY_MAX_TX_POWER=20 +# end of PHY + +# +# Core dump +# +# CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH is not set +# CONFIG_ESP_COREDUMP_ENABLE_TO_UART is not set +CONFIG_ESP_COREDUMP_ENABLE_TO_NONE=y +# end of Core dump + +# +# FAT Filesystem support +# +# CONFIG_FATFS_CODEPAGE_DYNAMIC is not set +CONFIG_FATFS_CODEPAGE_437=y +# CONFIG_FATFS_CODEPAGE_720 is not set +# CONFIG_FATFS_CODEPAGE_737 is not set +# CONFIG_FATFS_CODEPAGE_771 is not set +# CONFIG_FATFS_CODEPAGE_775 is not set +# CONFIG_FATFS_CODEPAGE_850 is not set +# CONFIG_FATFS_CODEPAGE_852 is not set +# CONFIG_FATFS_CODEPAGE_855 is not set +# CONFIG_FATFS_CODEPAGE_857 is not set +# CONFIG_FATFS_CODEPAGE_860 is not set +# CONFIG_FATFS_CODEPAGE_861 is not set +# CONFIG_FATFS_CODEPAGE_862 is not set +# CONFIG_FATFS_CODEPAGE_863 is not set +# CONFIG_FATFS_CODEPAGE_864 is not set +# CONFIG_FATFS_CODEPAGE_865 is not set +# CONFIG_FATFS_CODEPAGE_866 is not set +# CONFIG_FATFS_CODEPAGE_869 is not set +# CONFIG_FATFS_CODEPAGE_932 is not set +# CONFIG_FATFS_CODEPAGE_936 is not set +# CONFIG_FATFS_CODEPAGE_949 is not set +# CONFIG_FATFS_CODEPAGE_950 is not set +CONFIG_FATFS_CODEPAGE=437 +# CONFIG_FATFS_LFN_NONE is not set +CONFIG_FATFS_LFN_HEAP=y +# CONFIG_FATFS_LFN_STACK is not set +CONFIG_FATFS_FS_LOCK=0 +CONFIG_FATFS_TIMEOUT_MS=10000 +CONFIG_FATFS_PER_FILE_CACHE=y +# CONFIG_FATFS_USE_FASTSEEK is not set +# end of FAT Filesystem support + +# +# Modbus configuration +# +CONFIG_FMB_COMM_MODE_TCP_EN=y +CONFIG_FMB_TCP_PORT_DEFAULT=502 +CONFIG_FMB_TCP_PORT_MAX_CONN=5 +CONFIG_FMB_TCP_CONNECTION_TOUT_SEC=20 +CONFIG_FMB_COMM_MODE_RTU_EN=y +CONFIG_FMB_COMM_MODE_ASCII_EN=y +CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND=150 +CONFIG_FMB_MASTER_DELAY_MS_CONVERT=200 +CONFIG_FMB_QUEUE_LENGTH=20 +CONFIG_FMB_PORT_TASK_STACK_SIZE=4096 +CONFIG_FMB_SERIAL_BUF_SIZE=256 +CONFIG_FMB_SERIAL_ASCII_BITS_PER_SYMB=8 +CONFIG_FMB_SERIAL_ASCII_TIMEOUT_RESPOND_MS=1000 +CONFIG_FMB_PORT_TASK_PRIO=10 +CONFIG_FMB_CONTROLLER_SLAVE_ID_SUPPORT=y +CONFIG_FMB_CONTROLLER_SLAVE_ID=0x00112233 +CONFIG_FMB_CONTROLLER_NOTIFY_TIMEOUT=20 +CONFIG_FMB_CONTROLLER_NOTIFY_QUEUE_SIZE=20 +CONFIG_FMB_CONTROLLER_STACK_SIZE=4096 +CONFIG_FMB_EVENT_QUEUE_TIMEOUT=20 +CONFIG_FMB_TIMER_PORT_ENABLED=y +CONFIG_FMB_TIMER_GROUP=0 +CONFIG_FMB_TIMER_INDEX=0 +# CONFIG_FMB_TIMER_ISR_IN_IRAM is not set +# end of Modbus configuration + +# +# FreeRTOS +# +# CONFIG_FREERTOS_UNICORE is not set +CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF +CONFIG_FREERTOS_CORETIMER_0=y +# CONFIG_FREERTOS_CORETIMER_1 is not set +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=100 +CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION=y +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set +CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y +# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set +CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_ASSERT_FAIL_ABORT=y +# CONFIG_FREERTOS_ASSERT_FAIL_PRINT_CONTINUE is not set +# CONFIG_FREERTOS_ASSERT_DISABLE is not set +CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=2304 +CONFIG_FREERTOS_ISR_STACKSIZE=1536 +# CONFIG_FREERTOS_LEGACY_HOOKS is not set +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 +CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y +# CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=5 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_USE_TICKLESS_IDLE=y +# CONFIG_FREERTOS_USE_TRACE_FACILITY is not set +# CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set +CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER=y +CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y +# CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set +# CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set +CONFIG_FREERTOS_DEBUG_OCDAWARE=y +# end of FreeRTOS + +# +# Heap memory debugging +# +CONFIG_HEAP_POISONING_DISABLED=y +# CONFIG_HEAP_POISONING_LIGHT is not set +# CONFIG_HEAP_POISONING_COMPREHENSIVE is not set +CONFIG_HEAP_TRACING_OFF=y +# CONFIG_HEAP_TRACING_STANDALONE is not set +# CONFIG_HEAP_TRACING_TOHOST is not set +# CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS is not set +# end of Heap memory debugging + +# +# jsmn +# +# CONFIG_JSMN_PARENT_LINKS is not set +# CONFIG_JSMN_STRICT is not set +# end of jsmn + +# +# libsodium +# +# end of libsodium + +# +# Log output +# +# CONFIG_LOG_DEFAULT_LEVEL_NONE is not set +# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set +# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set +CONFIG_LOG_DEFAULT_LEVEL_NONE=y +# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set +# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set +CONFIG_LOG_DEFAULT_LEVEL=0 +CONFIG_LOG_COLORS=y +CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y +# CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set +# end of Log output + +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="nanodevice" +CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y +# CONFIG_LWIP_L2_TO_L3_COPY is not set +# CONFIG_LWIP_IRAM_OPTIMIZATION is not set +CONFIG_LWIP_TIMERS_ONDEMAND=y +CONFIG_LWIP_MAX_SOCKETS=16 +# CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set +CONFIG_LWIP_SO_LINGER=y +CONFIG_LWIP_SO_REUSE=y +CONFIG_LWIP_SO_REUSE_RXTOALL=y +CONFIG_LWIP_SO_RCVBUF=y +# CONFIG_LWIP_NETBUF_RECVINFO is not set +CONFIG_LWIP_IP4_FRAG=y +CONFIG_LWIP_IP6_FRAG=y +# CONFIG_LWIP_IP4_REASSEMBLY is not set +# CONFIG_LWIP_IP6_REASSEMBLY is not set +# CONFIG_LWIP_IP_FORWARD is not set +# CONFIG_LWIP_STATS is not set +# CONFIG_LWIP_ETHARP_TRUST_IP_MAC is not set +CONFIG_LWIP_ESP_GRATUITOUS_ARP=y +CONFIG_LWIP_GARP_TMR_INTERVAL=60 +CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 +CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y +# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set +# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set +CONFIG_LWIP_DHCP_OPTIONS_LEN=80 + +# +# DHCP server +# +# CONFIG_LWIP_DHCPS is not set +CONFIG_LWIP_DHCPS_LEASE_UNIT=60 +CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8 +# end of DHCP server + +# CONFIG_LWIP_AUTOIP is not set +# CONFIG_LWIP_IPV6 is not set +# CONFIG_LWIP_IPV6_AUTOCONFIG is not set +CONFIG_LWIP_NETIF_LOOPBACK=y +CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 + +# +# TCP +# +CONFIG_LWIP_MAX_ACTIVE_TCP=16 +CONFIG_LWIP_MAX_LISTENING_TCP=8 +CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y +CONFIG_LWIP_TCP_MAXRTX=12 +CONFIG_LWIP_TCP_SYNMAXRTX=12 +CONFIG_LWIP_TCP_MSS=1440 +CONFIG_LWIP_TCP_TMR_INTERVAL=250 +CONFIG_LWIP_TCP_MSL=60000 +CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 +CONFIG_LWIP_TCP_WND_DEFAULT=5744 +CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 +CONFIG_LWIP_TCP_QUEUE_OOSEQ=y +# CONFIG_LWIP_TCP_SACK_OUT is not set +# CONFIG_LWIP_TCP_KEEP_CONNECTION_WHEN_IP_CHANGES is not set +CONFIG_LWIP_TCP_OVERSIZE_MSS=y +# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set +CONFIG_LWIP_TCP_RTO_TIME=1500 +# end of TCP + +# +# UDP +# +CONFIG_LWIP_MAX_UDP_PCBS=16 +CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 +# end of UDP + +# +# Checksums +# +# CONFIG_LWIP_CHECKSUM_CHECK_IP is not set +# CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set +CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y +# end of Checksums + +CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y +# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set +CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF +# CONFIG_LWIP_PPP_SUPPORT is not set +CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 +CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 +# CONFIG_LWIP_SLIP_SUPPORT is not set + +# +# ICMP +# +CONFIG_LWIP_ICMP=y +# CONFIG_LWIP_MULTICAST_PING is not set +# CONFIG_LWIP_BROADCAST_PING is not set +# end of ICMP + +# +# LWIP RAW API +# +CONFIG_LWIP_MAX_RAW_PCBS=16 +# end of LWIP RAW API + +# +# SNTP +# +CONFIG_LWIP_DHCP_MAX_NTP_SERVERS=1 +CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 +# end of SNTP + +CONFIG_LWIP_ESP_LWIP_ASSERT=y + +# +# Hooks +# +# CONFIG_LWIP_HOOK_TCP_ISN_NONE is not set +CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT=y +# CONFIG_LWIP_HOOK_TCP_ISN_CUSTOM is not set +CONFIG_LWIP_HOOK_IP6_ROUTE_NONE=y +# CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT is not set +# CONFIG_LWIP_HOOK_IP6_ROUTE_CUSTOM is not set +CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_NONE=y +# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT is not set +# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_CUSTOM is not set +# end of Hooks + +# CONFIG_LWIP_DEBUG is not set +# end of LWIP + +# +# mbedTLS +# +# CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC is not set +CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC=y +# CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set +CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y +CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384 +CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 +CONFIG_MBEDTLS_DYNAMIC_BUFFER=y +# CONFIG_MBEDTLS_DEBUG is not set +CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH=y +CONFIG_MBEDTLS_DYNAMIC_FREE_PEER_CERT=y +# CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is not set + +# +# Certificate Bundle +# +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE is not set +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL is not set +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE=y +# CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set +# end of Certificate Bundle + +# CONFIG_MBEDTLS_ECP_RESTARTABLE is not set +CONFIG_MBEDTLS_CMAC_C=y +CONFIG_MBEDTLS_HARDWARE_AES=y +CONFIG_MBEDTLS_AES_USE_INTERRUPT=y +CONFIG_MBEDTLS_HARDWARE_GCM=y +CONFIG_MBEDTLS_HARDWARE_MPI=y +CONFIG_MBEDTLS_HARDWARE_SHA=y +CONFIG_MBEDTLS_ROM_MD5=y +# CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN is not set +# CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY is not set +CONFIG_MBEDTLS_HAVE_TIME=y +CONFIG_MBEDTLS_HAVE_TIME_DATE=y +CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y +CONFIG_MBEDTLS_SHA512_C=y +CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y +# CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set +# CONFIG_MBEDTLS_TLS_CLIENT_ONLY is not set +# CONFIG_MBEDTLS_TLS_DISABLED is not set +CONFIG_MBEDTLS_TLS_SERVER=y +CONFIG_MBEDTLS_TLS_CLIENT=y +CONFIG_MBEDTLS_TLS_ENABLED=y + +# +# TLS Key Exchange Methods +# +# CONFIG_MBEDTLS_PSK_MODES is not set +CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y +# end of TLS Key Exchange Methods + +CONFIG_MBEDTLS_SSL_RENEGOTIATION=y +# CONFIG_MBEDTLS_SSL_PROTO_SSL3 is not set +CONFIG_MBEDTLS_SSL_PROTO_TLS1=y +CONFIG_MBEDTLS_SSL_PROTO_TLS1_1=y +CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y +CONFIG_MBEDTLS_SSL_PROTO_DTLS=y +CONFIG_MBEDTLS_SSL_ALPN=y +# CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS is not set +CONFIG_MBEDTLS_X509_CHECK_KEY_USAGE=y +CONFIG_MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE=y +CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y + +# +# Symmetric Ciphers +# +CONFIG_MBEDTLS_AES_C=y +# CONFIG_MBEDTLS_CAMELLIA_C is not set +CONFIG_MBEDTLS_DES_C=y +CONFIG_MBEDTLS_RC4_DISABLED=y +# CONFIG_MBEDTLS_RC4_ENABLED_NO_DEFAULT is not set +# CONFIG_MBEDTLS_RC4_ENABLED is not set +# CONFIG_MBEDTLS_BLOWFISH_C is not set +CONFIG_MBEDTLS_XTEA_C=y +CONFIG_MBEDTLS_CCM_C=y +CONFIG_MBEDTLS_GCM_C=y +# CONFIG_MBEDTLS_NIST_KW_C is not set +# end of Symmetric Ciphers + +# CONFIG_MBEDTLS_RIPEMD160_C=y + +# +# Certificates +# +CONFIG_MBEDTLS_PEM_PARSE_C=y +# CONFIG_MBEDTLS_PEM_WRITE_C is not set +CONFIG_MBEDTLS_X509_CRL_PARSE_C=y +CONFIG_MBEDTLS_X509_CSR_PARSE_C=y +# end of Certificates + +CONFIG_MBEDTLS_ECP_C=y +CONFIG_MBEDTLS_ECDH_C=y +CONFIG_MBEDTLS_ECDSA_C=y +# CONFIG_MBEDTLS_ECJPAKE_C is not set +CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y +CONFIG_MBEDTLS_ECP_NIST_OPTIM=y +# CONFIG_MBEDTLS_POLY1305_C is not set +# CONFIG_MBEDTLS_CHACHA20_C is not set +# CONFIG_MBEDTLS_HKDF_C is not set +# CONFIG_MBEDTLS_THREADING_C is not set +# CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI is not set +# CONFIG_MBEDTLS_SECURITY_RISKS is not set +# end of mbedTLS + +# +# mDNS +# +CONFIG_MDNS_MAX_SERVICES=10 +CONFIG_MDNS_TASK_PRIORITY=1 +CONFIG_MDNS_TASK_STACK_SIZE=4096 +# CONFIG_MDNS_TASK_AFFINITY_NO_AFFINITY is not set +CONFIG_MDNS_TASK_AFFINITY_CPU0=y +CONFIG_MDNS_TASK_AFFINITY=0x0 +CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS=2000 +# CONFIG_MDNS_STRICT_MODE is not set +CONFIG_MDNS_TIMER_PERIOD_MS=100 +# end of mDNS + +# +# ESP-MQTT Configurations +# +CONFIG_MQTT_PROTOCOL_311=y +CONFIG_MQTT_TRANSPORT_SSL=y +CONFIG_MQTT_TRANSPORT_WEBSOCKET=y +CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE=y +# CONFIG_MQTT_MSG_ID_INCREMENTAL is not set +# CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set +# CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set +# CONFIG_MQTT_USE_CUSTOM_CONFIG is not set +# CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set +# CONFIG_MQTT_CUSTOM_OUTBOX is not set +# end of ESP-MQTT Configurations + +# +# Newlib +# +CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF is not set +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set +CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y +# CONFIG_NEWLIB_NANO_FORMAT is not set +# end of Newlib + +# +# NVS +# +# end of NVS + +# +# OpenSSL +# +# CONFIG_OPENSSL_DEBUG is not set +CONFIG_OPENSSL_ERROR_STACK=y +# CONFIG_OPENSSL_ASSERT_DO_NOTHING is not set +CONFIG_OPENSSL_ASSERT_EXIT=y +# end of OpenSSL + +# +# PThreads +# +CONFIG_PTHREAD_TASK_PRIO_DEFAULT=5 +CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 +CONFIG_PTHREAD_STACK_MIN=768 +CONFIG_PTHREAD_TASK_CORE_DEFAULT=-1 +CONFIG_PTHREAD_TASK_NAME_DEFAULT="pthread" +# end of PThreads + +# +# SPI Flash driver +# +# CONFIG_SPI_FLASH_VERIFY_WRITE is not set +# CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set +CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y +CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS=y +# CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS is not set +# CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED is not set +# CONFIG_SPI_FLASH_USE_LEGACY_IMPL is not set +# CONFIG_SPI_FLASH_BYPASS_BLOCK_ERASE is not set +CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y +CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS=20 +CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1 +CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE=8192 +# CONFIG_SPI_FLASH_SIZE_OVERRIDE is not set +# CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED is not set + +# +# Auto-detect flash chips +# +CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP=y +# end of Auto-detect flash chips + +CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE=y +# end of SPI Flash driver + +# +# SPIFFS Configuration +# +CONFIG_SPIFFS_MAX_PARTITIONS=3 + +# +# SPIFFS Cache Configuration +# +CONFIG_SPIFFS_CACHE=y +CONFIG_SPIFFS_CACHE_WR=y +# CONFIG_SPIFFS_CACHE_STATS is not set +# end of SPIFFS Cache Configuration + +CONFIG_SPIFFS_PAGE_CHECK=y +CONFIG_SPIFFS_GC_MAX_RUNS=10 +# CONFIG_SPIFFS_GC_STATS is not set +CONFIG_SPIFFS_PAGE_SIZE=512 +CONFIG_SPIFFS_OBJ_NAME_LEN=256 +# CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set +CONFIG_SPIFFS_USE_MAGIC=y +CONFIG_SPIFFS_USE_MAGIC_LENGTH=y +CONFIG_SPIFFS_META_LENGTH=4 +CONFIG_SPIFFS_USE_MTIME=y + +# +# Debug Configuration +# +# CONFIG_SPIFFS_DBG is not set +# CONFIG_SPIFFS_API_DBG is not set +# CONFIG_SPIFFS_GC_DBG is not set +# CONFIG_SPIFFS_CACHE_DBG is not set +# CONFIG_SPIFFS_CHECK_DBG is not set +# CONFIG_SPIFFS_TEST_VISUALISATION is not set +# end of Debug Configuration +# end of SPIFFS Configuration + +# +# TCP Transport +# + +# +# Websocket +# +CONFIG_WS_TRANSPORT=y +CONFIG_WS_BUFFER_SIZE=1024 +# end of Websocket +# end of TCP Transport + +# +# TinyUSB +# +CONFIG_USB_ENABLED=y +CONFIG_USB_CDC_ENABLED=y +CONFIG_USB_DESC_CDC_STRING=".NET nanoFramework device" +CONFIG_USB_DESC_PRODUCT_STRING=".NET nanoFramework device" +CONFIG_USB_CDC_RX_BUFSIZE=64 +# setting this to WP packet size +CONFIG_USB_CDC_TX_BUFSIZE=2048 +# end of TinyUSB + +# +# Unity unit testing library +# +CONFIG_UNITY_ENABLE_FLOAT=y +CONFIG_UNITY_ENABLE_DOUBLE=y +# CONFIG_UNITY_ENABLE_COLOR is not set +CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y +# CONFIG_UNITY_ENABLE_FIXTURE is not set +# CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set +# end of Unity unit testing library + +# +# Virtual file system +# +CONFIG_VFS_SUPPORT_IO=y +CONFIG_VFS_SUPPORT_DIR=y +CONFIG_VFS_SUPPORT_SELECT=y +CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y +CONFIG_VFS_SUPPORT_TERMIOS=y + +# +# Host File System I/O (Semihosting) +# +CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS=1 +CONFIG_VFS_SEMIHOSTFS_HOST_PATH_MAX_LEN=128 +# end of Host File System I/O (Semihosting) +# end of Virtual file system + +# +# Wear Levelling +# +# CONFIG_WL_SECTOR_SIZE_512 is not set +CONFIG_WL_SECTOR_SIZE_4096=y +CONFIG_WL_SECTOR_SIZE=4096 +# end of Wear Levelling + +# +# Wi-Fi Provisioning Manager +# +CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 +CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 +# end of Wi-Fi Provisioning Manager + +# +# Supplicant +# +CONFIG_WPA_MBEDTLS_CRYPTO=y +# CONFIG_WPA_WAPI_PSK is not set +# CONFIG_WPA_DEBUG_PRINT is not set +# CONFIG_WPA_TESTING_OPTIONS is not set +# CONFIG_WPA_WPS_STRICT is not set +# CONFIG_WPA_11KV_SUPPORT is not set +# end of Supplicant +# end of Component config diff --git a/targets/ESP32/_IDF/sdkconfig.default_ble.esp32 b/targets/ESP32/_IDF/sdkconfig.default_ble.esp32 index 08fc3ab971..1e44275195 100644 --- a/targets/ESP32/_IDF/sdkconfig.default_ble.esp32 +++ b/targets/ESP32/_IDF/sdkconfig.default_ble.esp32 @@ -483,7 +483,6 @@ CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 CONFIG_ESP32_WIFI_STATIC_TX_BUFFER=y # CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER is not set -CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 # CONFIG_ESP32_WIFI_CSI_ENABLED is not set CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y @@ -810,6 +809,7 @@ CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 CONFIG_MBEDTLS_DYNAMIC_BUFFER=y # CONFIG_MBEDTLS_DEBUG is not set CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH=y +CONFIG_MBEDTLS_DYNAMIC_FREE_PEER_CERT=y # CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is not set # @@ -818,7 +818,8 @@ CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH=y # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE is not set # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL is not set # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set -# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE=y # CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set # end of Certificate Bundle @@ -1033,8 +1034,8 @@ CONFIG_SPIFFS_CACHE_WR=y CONFIG_SPIFFS_PAGE_CHECK=y CONFIG_SPIFFS_GC_MAX_RUNS=10 # CONFIG_SPIFFS_GC_STATS is not set -CONFIG_SPIFFS_PAGE_SIZE=256 -CONFIG_SPIFFS_OBJ_NAME_LEN=32 +CONFIG_SPIFFS_PAGE_SIZE=512 +CONFIG_SPIFFS_OBJ_NAME_LEN=256 # CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set CONFIG_SPIFFS_USE_MAGIC=y CONFIG_SPIFFS_USE_MAGIC_LENGTH=y diff --git a/targets/ESP32/_IDF/sdkconfig.default_ble.esp32s3 b/targets/ESP32/_IDF/sdkconfig.default_ble.esp32s3 new file mode 100644 index 0000000000..17bda54aec --- /dev/null +++ b/targets/ESP32/_IDF/sdkconfig.default_ble.esp32s3 @@ -0,0 +1,1162 @@ +# +# Automatically generated file. DO NOT EDIT. +# Espressif IoT Development Framework (ESP-IDF) Project Configuration +# +CONFIG_IDF_CMAKE=y +CONFIG_IDF_TARGET_ARCH_XTENSA=y +CONFIG_IDF_TARGET="esp32s3" +CONFIG_IDF_TARGET_ESP32S3=y +CONFIG_IDF_FIRMWARE_CHIP_ID=0x0009 + +# +# SDK tool configuration +# +CONFIG_SDK_TOOLPREFIX="xtensa-esp32s3-elf-" +# CONFIG_SDK_TOOLCHAIN_SUPPORTS_TIME_WIDE_64_BITS is not set +# end of SDK tool configuration + +# +# Build type +# +CONFIG_APP_BUILD_TYPE_APP_2NDBOOT=y +# CONFIG_APP_BUILD_TYPE_ELF_RAM is not set +CONFIG_APP_BUILD_GENERATE_BINARIES=y +CONFIG_APP_BUILD_BOOTLOADER=y +CONFIG_APP_BUILD_USE_FLASH_SECTIONS=y +# end of Build type + +# +# Application manager +# +CONFIG_APP_COMPILE_TIME_DATE=y +# CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set +# CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set +# CONFIG_APP_PROJECT_VER_FROM_CONFIG is not set +CONFIG_APP_RETRIEVE_LEN_ELF_SHA=16 +# end of Application manager + +# +# Bootloader config +# +CONFIG_BOOTLOADER_OFFSET_IN_FLASH=0x0000 +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG=y +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set +CONFIG_BOOTLOADER_LOG_LEVEL_INFO=y +# CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set +CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y +# CONFIG_BOOTLOADER_FACTORY_RESET is not set +# CONFIG_BOOTLOADER_APP_TEST is not set +CONFIG_BOOTLOADER_WDT_ENABLE=y +# CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE is not set +CONFIG_BOOTLOADER_WDT_TIME_MS=9000 +# CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS is not set +CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 +# CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC is not set +# end of Bootloader config + +# +# Security features +# +CONFIG_SECURE_BOOT_SUPPORTS_RSA=y +CONFIG_SECURE_TARGET_HAS_SECURE_ROM_DL_MODE=y +# CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set +# CONFIG_SECURE_BOOT is not set +# CONFIG_SECURE_FLASH_ENC_ENABLED is not set +# CONFIG_SECURE_BOOT_ALLOW_JTAG is not set +# end of Security features + +# +# Serial flasher config +# +CONFIG_ESPTOOLPY_BAUD_OTHER_VAL=115200 +# CONFIG_ESPTOOLPY_NO_STUB is not set +# CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set +# CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set +# CONFIG_ESPTOOLPY_FLASHMODE_DIO is not set +# CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set +# CONFIG_ESPTOOLPY_FLASHFREQ_40M is not set +# CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set +# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set +# CONFIG_ESPTOOLPY_FLASHFREQ_80M is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y +CONFIG_ESPTOOLPY_FLASHSIZE="8MB" +CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y +CONFIG_ESPTOOLPY_BEFORE_RESET=y +# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set +CONFIG_ESPTOOLPY_BEFORE="default_reset" +CONFIG_ESPTOOLPY_AFTER_RESET=y +# CONFIG_ESPTOOLPY_AFTER_NORESET is not set +CONFIG_ESPTOOLPY_AFTER="hard_reset" +# CONFIG_ESPTOOLPY_MONITOR_BAUD_CONSOLE is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_9600B is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_57600B is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_115200B is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_230400B is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_921600B=y +# CONFIG_ESPTOOLPY_MONITOR_BAUD_2MB is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_OTHER is not set +CONFIG_ESPTOOLPY_MONITOR_BAUD_OTHER_VAL=115200 +CONFIG_ESPTOOLPY_MONITOR_BAUD=921600 +# end of Serial flasher config + +# +# Partition Table +# +CONFIG_PARTITION_TABLE_SINGLE_APP=y +# CONFIG_PARTITION_TABLE_TWO_OTA is not set +CONFIG_PARTITION_TABLE_CUSTOM=y +# default to 8mb partition table for nanoCLR +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="targets/ESP32/_IDF/esp32s3/partitions_nanoclr_8mb.csv" +# CONFIG_PARTITION_TABLE_FILENAME is not set +CONFIG_PARTITION_TABLE_OFFSET=0x8000 +CONFIG_PARTITION_TABLE_MD5=y +# end of Partition Table + +# +# Compiler options +# +# CONFIG_COMPILER_OPTIMIZATION_DEFAULT=y +CONFIG_COMPILER_OPTIMIZATION_SIZE=y +# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE=y +# CONFIG_COMPILER_CXX_EXCEPTIONS is not set +# CONFIG_COMPILER_CXX_RTTI is not set +CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y +# CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set +# CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set +# CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set +# CONFIG_COMPILER_WARN_WRITE_STRINGS is not set +# CONFIG_COMPILER_DISABLE_GCC8_WARNINGS is not set +# CONFIG_COMPILER_DUMP_RTL_FILES is not set +# end of Compiler options + +# +# Component config +# + +# +# Application Level Tracing +# +# CONFIG_APPTRACE_DEST_TRAX is not set +CONFIG_APPTRACE_DEST_NONE=y +CONFIG_APPTRACE_LOCK_ENABLE=y +# end of Application Level Tracing + +# +# ESP-ASIO +# +# CONFIG_ASIO_SSL_SUPPORT is not set +# end of ESP-ASIO + +CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 +CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 +CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 +CONFIG_BTDM_CTRL_BLE_MAX_CONN_EFF=0 +CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN_EFF=0 +CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF=0 +CONFIG_BTDM_CTRL_PINNED_TO_CORE=0 +CONFIG_BTDM_BLE_SLEEP_CLOCK_ACCURACY_INDEX_EFF=1 +CONFIG_BT_CTRL_MODE_EFF=1 +CONFIG_BT_CTRL_BLE_MAX_ACT=10 +CONFIG_BT_CTRL_BLE_MAX_ACT_EFF=10 +CONFIG_BT_CTRL_BLE_STATIC_ACL_TX_BUF_NB=0 +CONFIG_BT_CTRL_PINNED_TO_CORE=0 +CONFIG_BT_CTRL_HCI_TL=1 +CONFIG_BT_CTRL_ADV_DUP_FILT_MAX=30 +CONFIG_BT_CTRL_HW_CCA_EFF=0 +CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_EFF=0 +CONFIG_BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y +CONFIG_BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 +CONFIG_BT_CTRL_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 +CONFIG_BT_CTRL_BLE_SCAN_DUPL=y +CONFIG_BT_CTRL_SCAN_DUPL_TYPE=0 +CONFIG_BT_CTRL_SCAN_DUPL_CACHE_SIZE=100 +CONFIG_BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM_EFF=0 +CONFIG_BT_CTRL_SLEEP_MODE_EFF=0 +CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 +CONFIG_BT_CTRL_HCI_TL_EFF=1 +CONFIG_BT_RESERVE_DRAM=0 +CONFIG_BT_NIMBLE_USE_ESP_TIMER=y + +# +# CoAP Configuration +# +CONFIG_COAP_MBEDTLS_PSK=y +# CONFIG_COAP_MBEDTLS_PKI is not set +# CONFIG_COAP_MBEDTLS_DEBUG is not set +CONFIG_COAP_LOG_DEFAULT_LEVEL=0 +# end of CoAP Configuration + +# +# Driver configurations +# + +# +# ADC configuration +# +# CONFIG_ADC_FORCE_XPD_FSM is not set +CONFIG_ADC_DISABLE_DAC=y +# end of ADC configuration + +# +# SPI configuration +# +# CONFIG_SPI_MASTER_IN_IRAM is not set +CONFIG_SPI_MASTER_ISR_IN_IRAM=y +# CONFIG_SPI_SLAVE_IN_IRAM is not set +CONFIG_SPI_SLAVE_ISR_IN_IRAM=y +# end of SPI configuration + +# +# TWAI configuration +# +# CONFIG_TWAI_ISR_IN_IRAM is not set +# end of TWAI configuration + +# +# UART configuration +# +CONFIG_UART_ISR_IN_IRAM=y +# end of UART configuration +# end of Driver configurations + +# +# eFuse Bit Manager +# +# CONFIG_EFUSE_CUSTOM_TABLE is not set +# CONFIG_EFUSE_VIRTUAL is not set +CONFIG_EFUSE_MAX_BLK_LEN=256 +# end of eFuse Bit Manager + +# +# SPI RAM config +# +CONFIG_SPIRAM_BOOT_INIT=y +CONFIG_SPIRAM_IGNORE_NOTFOUND=y +CONFIG_SPIRAM_USE_MEMMAP=n +CONFIG_SPIRAM_USE_CAPS_ALLOC=n +CONFIG_SPIRAM_USE_MALLOC=y +CONFIG_SPIRAM_TYPE_AUTO=y +CONFIG_SPIRAM_TYPE_ESPPSRAM32=n +CONFIG_SPIRAM_TYPE_ESPPSRAM64=n +CONFIG_SPIRAM_SIZE=-1 +CONFIG_SPIRAM_SPEED_40M=y +# CONFIG_SPIRAM_MEMTEST is not set +CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=16384 +CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y +CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=32768 +CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=n +CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=n +CONFIG_ESP32S3_SPIRAM_SUPPORT=y +CONFIG_SPIRAM_MODE_QUAD=y + +# +# ESP-TLS +# +CONFIG_ESP_TLS_USING_MBEDTLS=y +CONFIG_ESP_TLS_USE_DS_PERIPHERAL=y +# CONFIG_ESP_TLS_SERVER is not set +# CONFIG_ESP_TLS_PSK_VERIFICATION is not set +# CONFIG_ESP_TLS_INSECURE is not set +# end of ESP-TLS + + +# +# ESP32S3-Specific +# +CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240=y +CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ=240 +CONFIG_ESP32S3_DEBUG_OCDAWARE=y +CONFIG_ESP32S3_BROWNOUT_DET=y +CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_7=y +# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_2 is not set +CONFIG_ESP32S3_BROWNOUT_DET_LVL=7 +CONFIG_ESP32S3_TIME_SYSCALL_USE_RTC_SYSTIMER=y +# CONFIG_ESP32S3_TIME_SYSCALL_USE_RTC is not set +# CONFIG_ESP32S3_TIME_SYSCALL_USE_SYSTIMER is not set +# CONFIG_ESP32S3_TIME_SYSCALL_USE_NONE is not set +CONFIG_ESP32S3_RTC_CLK_SRC_INT_RC=y +# CONFIG_ESP32S3_RTC_CLK_SRC_EXT_CRYS is not set +# CONFIG_ESP32S3_RTC_CLK_SRC_EXT_OSC is not set +# CONFIG_ESP32S3_RTC_CLK_SRC_INT_8MD256 is not set +CONFIG_ESP32S3_RTC_CLK_CAL_CYCLES=1024 +# CONFIG_ESP32S3_NO_BLOBS is not set +# end of ESP32S3-Specific + +# +# ADC-Calibration +# +# end of ADC-Calibration + +# config for XTAL freq +# adding it here, so it can be overriden by our CMake +CONFIG_ESP32_XTAL_FREQ_40=y + +# +# Common ESP-related +# +CONFIG_ESP_ERR_TO_NAME_LOOKUP=y +CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 +CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=3584 +CONFIG_ESP_IPC_TASK_STACK_SIZE=1024 +CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048 +CONFIG_ESP_CONSOLE_UART_DEFAULT= +# CONFIG_ESP_CONSOLE_UART_CUSTOM is not set +# CONFIG_ESP_CONSOLE_NONE is not set +CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG=y +CONFIG_ESP_CONSOLE_UART=y +CONFIG_ESP_CONSOLE_MULTIPLE_UART=y +CONFIG_ESP_CONSOLE_UART_NUM=0 +CONFIG_ESP_CONSOLE_UART_BAUDRATE=921600 +CONFIG_ESP_INT_WDT=y +CONFIG_ESP_INT_WDT_TIMEOUT_MS=300 +# CONFIG_ESP_TASK_WDT is not set +# CONFIG_ESP_TASK_WDT_PANIC is not set +# CONFIG_ESP_TASK_WDT_TIMEOUT_S is not set +# CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0 is not set +# CONFIG_ESP_PANIC_HANDLER_IRAM is not set +CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_STA=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_AP=y +# end of Common ESP-related + +# +# Ethernet +# +# Parameters configured in binutils.ESP32.CMAKE +# +CONFIG_ETH_ENABLED=y +CONFIG_ETH_USE_ESP32_EMAC=y + +CONFIG_ETH_PHY_INTERFACE_RMII=y +# CONFIG_ETH_PHY_INTERFACE_MII is not set + +#CONFIG_ETH_RMII_CLK_OUTPUT=y +#CONFIG_ETH_RMII_CLK_OUT_GPIO=17 +#CONFIG_ETH_RMII_CLK_INPUT=y +#CONFIG_ETH_RMII_CLK_IN_GPIO=n + +CONFIG_ETH_DMA_BUFFER_SIZE=512 +CONFIG_ETH_DMA_RX_BUFFER_NUM=10 +CONFIG_ETH_DMA_TX_BUFFER_NUM=10 + +# Include SPI drivers in case used in build +CONFIG_ETH_USE_SPI_ETHERNET=y +#CONFIG_ETH_SPI_ETHERNET_DM9051=y +#CONFIG_ETH_SPI_ETHERNET_W5500=y +#CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL=y +#CONFIG_ETH_USE_OPENETH=n +# end of Ethernet + +# +# Event Loop Library +# +# CONFIG_ESP_EVENT_LOOP_PROFILING is not set +CONFIG_ESP_EVENT_POST_FROM_ISR=y +CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y +# end of Event Loop Library + +# +# GDB Stub +# +# end of GDB Stub + +# +# ESP HTTP client +# +CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y +# CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set +# end of ESP HTTP client + +# +# HTTP Server +# +CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 +CONFIG_HTTPD_MAX_URI_LEN=512 +CONFIG_HTTPD_ERR_RESP_NO_DELAY=y +CONFIG_HTTPD_PURGE_BUF_LEN=32 +# CONFIG_HTTPD_LOG_PURGE_DATA is not set +# CONFIG_HTTPD_WS_SUPPORT is not set +# end of HTTP Server + +# +# ESP HTTPS OTA +# +# CONFIG_OTA_ALLOW_HTTP is not set +# end of ESP HTTPS OTA + +# +# ESP HTTPS server +# +# CONFIG_ESP_HTTPS_SERVER_ENABLE is not set +# end of ESP HTTPS server + +# +# ESP NETIF Adapter +# +CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 +CONFIG_ESP_NETIF_TCPIP_LWIP=y +# CONFIG_ESP_NETIF_LOOPBACK is not set +# CONFIG_ESP_NETIF_TCPIP_ADAPTER_COMPATIBLE_LAYER is not set +# end of ESP NETIF Adapter + +# +# Power Management +# +CONFIG_PM_ENABLE=y +# end of Power Management + +# +# ESP System Settings +# +# CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT is not set +CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y +# CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set +# CONFIG_ESP_SYSTEM_PANIC_GDBSTUB is not set +CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE=y +CONFIG_ESP_SYSTEM_RTC_FAST_MEM_AS_HEAP_DEPCHECK=y +CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP=y +CONFIG_ESP_SLEEP_POWER_DOWN_FLASH=y + +# +# Memory protection +# +CONFIG_ESP_SYSTEM_MEMPROT_FEATURE=y +CONFIG_ESP_SYSTEM_MEMPROT_FEATURE_LOCK=y +# end of Memory protection +# end of ESP System Settings + +# +# High resolution timer (esp_timer) +# +# CONFIG_ESP_TIMER_PROFILING is not set +CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y +CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y +CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584 +CONFIG_ESP_TIMER_IMPL_SYSTIMER=y +# end of High resolution timer (esp_timer) + +# +# Wi-Fi +# +CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 +CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 +# CONFIG_ESP32_WIFI_STATIC_TX_BUFFER is not set +# CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER is not set +# CONFIG_ESP32_WIFI_TX_BUFFER_TYPE is not set +CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 +# CONFIG_ESP32_WIFI_CSI_ENABLED is not set +CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y +CONFIG_ESP32_WIFI_TX_BA_WIN=6 +CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y +CONFIG_ESP32_WIFI_RX_BA_WIN=6 +CONFIG_ESP32_WIFI_NVS_ENABLED=y +CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 +CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 +# CONFIG_WIFI_LOG_DEFAULT_LEVEL_NONE is not set +# CONFIG_WIFI_LOG_DEFAULT_LEVEL_ERROR is not set +# CONFIG_WIFI_LOG_DEFAULT_LEVEL_WARN is not set +CONFIG_WIFI_LOG_DEFAULT_LEVEL_INFO=y +# CONFIG_WIFI_LOG_DEFAULT_LEVEL_DEBUG is not set +# CONFIG_WIFI_LOG_DEFAULT_LEVEL_VERBOSE is not set +CONFIG_ESP32_WIFI_IRAM_OPT=y +CONFIG_ESP32_WIFI_RX_IRAM_OPT=y +CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y +# CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set +# CONFIG_ESP_WIFI_FTM_ENABLE is not set +# CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE is not set +# end of Wi-Fi + +# +# PHY +# +CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y +# CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set +CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=20 +CONFIG_ESP_PHY_MAX_TX_POWER=20 +# end of PHY + +# +# Core dump +# +# CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH is not set +# CONFIG_ESP_COREDUMP_ENABLE_TO_UART is not set +CONFIG_ESP_COREDUMP_ENABLE_TO_NONE=y +# end of Core dump + +# +# FAT Filesystem support +# +# CONFIG_FATFS_CODEPAGE_DYNAMIC is not set +CONFIG_FATFS_CODEPAGE_437=y +# CONFIG_FATFS_CODEPAGE_720 is not set +# CONFIG_FATFS_CODEPAGE_737 is not set +# CONFIG_FATFS_CODEPAGE_771 is not set +# CONFIG_FATFS_CODEPAGE_775 is not set +# CONFIG_FATFS_CODEPAGE_850 is not set +# CONFIG_FATFS_CODEPAGE_852 is not set +# CONFIG_FATFS_CODEPAGE_855 is not set +# CONFIG_FATFS_CODEPAGE_857 is not set +# CONFIG_FATFS_CODEPAGE_860 is not set +# CONFIG_FATFS_CODEPAGE_861 is not set +# CONFIG_FATFS_CODEPAGE_862 is not set +# CONFIG_FATFS_CODEPAGE_863 is not set +# CONFIG_FATFS_CODEPAGE_864 is not set +# CONFIG_FATFS_CODEPAGE_865 is not set +# CONFIG_FATFS_CODEPAGE_866 is not set +# CONFIG_FATFS_CODEPAGE_869 is not set +# CONFIG_FATFS_CODEPAGE_932 is not set +# CONFIG_FATFS_CODEPAGE_936 is not set +# CONFIG_FATFS_CODEPAGE_949 is not set +# CONFIG_FATFS_CODEPAGE_950 is not set +CONFIG_FATFS_CODEPAGE=437 +# CONFIG_FATFS_LFN_NONE is not set +CONFIG_FATFS_LFN_HEAP=y +# CONFIG_FATFS_LFN_STACK is not set +CONFIG_FATFS_FS_LOCK=0 +CONFIG_FATFS_TIMEOUT_MS=10000 +CONFIG_FATFS_PER_FILE_CACHE=y +# CONFIG_FATFS_USE_FASTSEEK is not set +# end of FAT Filesystem support + +# +# Modbus configuration +# +CONFIG_FMB_COMM_MODE_TCP_EN=y +CONFIG_FMB_TCP_PORT_DEFAULT=502 +CONFIG_FMB_TCP_PORT_MAX_CONN=5 +CONFIG_FMB_TCP_CONNECTION_TOUT_SEC=20 +CONFIG_FMB_COMM_MODE_RTU_EN=y +CONFIG_FMB_COMM_MODE_ASCII_EN=y +CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND=150 +CONFIG_FMB_MASTER_DELAY_MS_CONVERT=200 +CONFIG_FMB_QUEUE_LENGTH=20 +CONFIG_FMB_PORT_TASK_STACK_SIZE=4096 +CONFIG_FMB_SERIAL_BUF_SIZE=256 +CONFIG_FMB_SERIAL_ASCII_BITS_PER_SYMB=8 +CONFIG_FMB_SERIAL_ASCII_TIMEOUT_RESPOND_MS=1000 +CONFIG_FMB_PORT_TASK_PRIO=10 +CONFIG_FMB_CONTROLLER_SLAVE_ID_SUPPORT=y +CONFIG_FMB_CONTROLLER_SLAVE_ID=0x00112233 +CONFIG_FMB_CONTROLLER_NOTIFY_TIMEOUT=20 +CONFIG_FMB_CONTROLLER_NOTIFY_QUEUE_SIZE=20 +CONFIG_FMB_CONTROLLER_STACK_SIZE=4096 +CONFIG_FMB_EVENT_QUEUE_TIMEOUT=20 +CONFIG_FMB_TIMER_PORT_ENABLED=y +CONFIG_FMB_TIMER_GROUP=0 +CONFIG_FMB_TIMER_INDEX=0 +# CONFIG_FMB_TIMER_ISR_IN_IRAM is not set +# end of Modbus configuration + +# +# FreeRTOS +# +# CONFIG_FREERTOS_UNICORE is not set +CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF +CONFIG_FREERTOS_CORETIMER_0=y +# CONFIG_FREERTOS_CORETIMER_1 is not set +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=100 +CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION=y +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set +CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y +# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set +CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_ASSERT_FAIL_ABORT=y +# CONFIG_FREERTOS_ASSERT_FAIL_PRINT_CONTINUE is not set +# CONFIG_FREERTOS_ASSERT_DISABLE is not set +CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=2304 +CONFIG_FREERTOS_ISR_STACKSIZE=1536 +# CONFIG_FREERTOS_LEGACY_HOOKS is not set +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 +CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y +# CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=5 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_USE_TICKLESS_IDLE=y +# CONFIG_FREERTOS_USE_TRACE_FACILITY is not set +# CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set +CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER=y +CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y +# CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set +# CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set +CONFIG_FREERTOS_DEBUG_OCDAWARE=y +# end of FreeRTOS + +# +# Heap memory debugging +# +CONFIG_HEAP_POISONING_DISABLED=y +# CONFIG_HEAP_POISONING_LIGHT is not set +# CONFIG_HEAP_POISONING_COMPREHENSIVE is not set +CONFIG_HEAP_TRACING_OFF=y +# CONFIG_HEAP_TRACING_STANDALONE is not set +# CONFIG_HEAP_TRACING_TOHOST is not set +# CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS is not set +# end of Heap memory debugging + +# +# jsmn +# +# CONFIG_JSMN_PARENT_LINKS is not set +# CONFIG_JSMN_STRICT is not set +# end of jsmn + +# +# libsodium +# +# end of libsodium + +# +# Log output +# +# CONFIG_LOG_DEFAULT_LEVEL_NONE is not set +# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set +# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set +CONFIG_LOG_DEFAULT_LEVEL_NONE=y +# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set +# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set +CONFIG_LOG_DEFAULT_LEVEL=0 +CONFIG_LOG_COLORS=y +CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y +# CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set +# end of Log output + +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="nanodevice" +CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y +# CONFIG_LWIP_L2_TO_L3_COPY is not set +# CONFIG_LWIP_IRAM_OPTIMIZATION is not set +CONFIG_LWIP_TIMERS_ONDEMAND=y +CONFIG_LWIP_MAX_SOCKETS=16 +# CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set +CONFIG_LWIP_SO_LINGER=y +CONFIG_LWIP_SO_REUSE=y +CONFIG_LWIP_SO_REUSE_RXTOALL=y +CONFIG_LWIP_SO_RCVBUF=y +# CONFIG_LWIP_NETBUF_RECVINFO is not set +CONFIG_LWIP_IP4_FRAG=y +CONFIG_LWIP_IP6_FRAG=y +# CONFIG_LWIP_IP4_REASSEMBLY is not set +# CONFIG_LWIP_IP6_REASSEMBLY is not set +# CONFIG_LWIP_IP_FORWARD is not set +# CONFIG_LWIP_STATS is not set +# CONFIG_LWIP_ETHARP_TRUST_IP_MAC is not set +CONFIG_LWIP_ESP_GRATUITOUS_ARP=y +CONFIG_LWIP_GARP_TMR_INTERVAL=60 +CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 +CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y +# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set +# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set +CONFIG_LWIP_DHCP_OPTIONS_LEN=80 + +# +# DHCP server +# +# CONFIG_LWIP_DHCPS is not set +CONFIG_LWIP_DHCPS_LEASE_UNIT=60 +CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8 +# end of DHCP server + +# CONFIG_LWIP_AUTOIP is not set +# CONFIG_LWIP_IPV6 is not set +# CONFIG_LWIP_IPV6_AUTOCONFIG is not set +CONFIG_LWIP_NETIF_LOOPBACK=y +CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 + +# +# TCP +# +CONFIG_LWIP_MAX_ACTIVE_TCP=16 +CONFIG_LWIP_MAX_LISTENING_TCP=8 +CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y +CONFIG_LWIP_TCP_MAXRTX=12 +CONFIG_LWIP_TCP_SYNMAXRTX=12 +CONFIG_LWIP_TCP_MSS=1440 +CONFIG_LWIP_TCP_TMR_INTERVAL=250 +CONFIG_LWIP_TCP_MSL=60000 +CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 +CONFIG_LWIP_TCP_WND_DEFAULT=5744 +CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 +CONFIG_LWIP_TCP_QUEUE_OOSEQ=y +# CONFIG_LWIP_TCP_SACK_OUT is not set +# CONFIG_LWIP_TCP_KEEP_CONNECTION_WHEN_IP_CHANGES is not set +CONFIG_LWIP_TCP_OVERSIZE_MSS=y +# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set +CONFIG_LWIP_TCP_RTO_TIME=1500 +# end of TCP + +# +# UDP +# +CONFIG_LWIP_MAX_UDP_PCBS=16 +CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 +# end of UDP + +# +# Checksums +# +# CONFIG_LWIP_CHECKSUM_CHECK_IP is not set +# CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set +CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y +# end of Checksums + +CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y +# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set +CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF +# CONFIG_LWIP_PPP_SUPPORT is not set +CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 +CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 +# CONFIG_LWIP_SLIP_SUPPORT is not set + +# +# ICMP +# +CONFIG_LWIP_ICMP=y +# CONFIG_LWIP_MULTICAST_PING is not set +# CONFIG_LWIP_BROADCAST_PING is not set +# end of ICMP + +# +# LWIP RAW API +# +CONFIG_LWIP_MAX_RAW_PCBS=16 +# end of LWIP RAW API + +# +# SNTP +# +CONFIG_LWIP_DHCP_MAX_NTP_SERVERS=1 +CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 +# end of SNTP + +CONFIG_LWIP_ESP_LWIP_ASSERT=y + +# +# Hooks +# +# CONFIG_LWIP_HOOK_TCP_ISN_NONE is not set +CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT=y +# CONFIG_LWIP_HOOK_TCP_ISN_CUSTOM is not set +CONFIG_LWIP_HOOK_IP6_ROUTE_NONE=y +# CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT is not set +# CONFIG_LWIP_HOOK_IP6_ROUTE_CUSTOM is not set +CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_NONE=y +# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT is not set +# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_CUSTOM is not set +# end of Hooks + +# CONFIG_LWIP_DEBUG is not set +# end of LWIP + +# +# mbedTLS +# +# CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC is not set +CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC=y +# CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set +CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y +CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384 +CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 +CONFIG_MBEDTLS_DYNAMIC_BUFFER=y +# CONFIG_MBEDTLS_DEBUG is not set +CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH=y +CONFIG_MBEDTLS_DYNAMIC_FREE_PEER_CERT=y +# CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is not set + +# +# Certificate Bundle +# +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE is not set +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL is not set +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE=y +# CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set +# end of Certificate Bundle + +# CONFIG_MBEDTLS_ECP_RESTARTABLE is not set +CONFIG_MBEDTLS_CMAC_C=y +CONFIG_MBEDTLS_HARDWARE_AES=y +CONFIG_MBEDTLS_AES_USE_INTERRUPT=y +CONFIG_MBEDTLS_HARDWARE_GCM=y +CONFIG_MBEDTLS_HARDWARE_MPI=y +CONFIG_MBEDTLS_HARDWARE_SHA=y +CONFIG_MBEDTLS_ROM_MD5=y +# CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN is not set +# CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY is not set +CONFIG_MBEDTLS_HAVE_TIME=y +CONFIG_MBEDTLS_HAVE_TIME_DATE=y +CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y +CONFIG_MBEDTLS_SHA512_C=y +CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y +# CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set +# CONFIG_MBEDTLS_TLS_CLIENT_ONLY is not set +# CONFIG_MBEDTLS_TLS_DISABLED is not set +CONFIG_MBEDTLS_TLS_SERVER=y +CONFIG_MBEDTLS_TLS_CLIENT=y +CONFIG_MBEDTLS_TLS_ENABLED=y + +# +# TLS Key Exchange Methods +# +# CONFIG_MBEDTLS_PSK_MODES is not set +CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y +# end of TLS Key Exchange Methods + +CONFIG_MBEDTLS_SSL_RENEGOTIATION=y +# CONFIG_MBEDTLS_SSL_PROTO_SSL3 is not set +CONFIG_MBEDTLS_SSL_PROTO_TLS1=y +CONFIG_MBEDTLS_SSL_PROTO_TLS1_1=y +CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y +CONFIG_MBEDTLS_SSL_PROTO_DTLS=y +CONFIG_MBEDTLS_SSL_ALPN=y +# CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS is not set +CONFIG_MBEDTLS_X509_CHECK_KEY_USAGE=y +CONFIG_MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE=y +CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y + +# +# Symmetric Ciphers +# +CONFIG_MBEDTLS_AES_C=y +# CONFIG_MBEDTLS_CAMELLIA_C is not set +CONFIG_MBEDTLS_DES_C=y +CONFIG_MBEDTLS_RC4_DISABLED=y +# CONFIG_MBEDTLS_RC4_ENABLED_NO_DEFAULT is not set +# CONFIG_MBEDTLS_RC4_ENABLED is not set +# CONFIG_MBEDTLS_BLOWFISH_C is not set +CONFIG_MBEDTLS_XTEA_C=y +CONFIG_MBEDTLS_CCM_C=y +CONFIG_MBEDTLS_GCM_C=y +# CONFIG_MBEDTLS_NIST_KW_C is not set +# end of Symmetric Ciphers + +# CONFIG_MBEDTLS_RIPEMD160_C=y + +# +# Certificates +# +CONFIG_MBEDTLS_PEM_PARSE_C=y +# CONFIG_MBEDTLS_PEM_WRITE_C is not set +CONFIG_MBEDTLS_X509_CRL_PARSE_C=y +CONFIG_MBEDTLS_X509_CSR_PARSE_C=y +# end of Certificates + +CONFIG_MBEDTLS_ECP_C=y +CONFIG_MBEDTLS_ECDH_C=y +CONFIG_MBEDTLS_ECDSA_C=y +# CONFIG_MBEDTLS_ECJPAKE_C is not set +CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y +CONFIG_MBEDTLS_ECP_NIST_OPTIM=y +# CONFIG_MBEDTLS_POLY1305_C is not set +# CONFIG_MBEDTLS_CHACHA20_C is not set +# CONFIG_MBEDTLS_HKDF_C is not set +# CONFIG_MBEDTLS_THREADING_C is not set +# CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI is not set +# CONFIG_MBEDTLS_SECURITY_RISKS is not set +# end of mbedTLS + +# +# mDNS +# +CONFIG_MDNS_MAX_SERVICES=10 +CONFIG_MDNS_TASK_PRIORITY=1 +CONFIG_MDNS_TASK_STACK_SIZE=4096 +# CONFIG_MDNS_TASK_AFFINITY_NO_AFFINITY is not set +CONFIG_MDNS_TASK_AFFINITY_CPU0=y +CONFIG_MDNS_TASK_AFFINITY=0x0 +CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS=2000 +# CONFIG_MDNS_STRICT_MODE is not set +CONFIG_MDNS_TIMER_PERIOD_MS=100 +# end of mDNS + +# +# ESP-MQTT Configurations +# +CONFIG_MQTT_PROTOCOL_311=y +CONFIG_MQTT_TRANSPORT_SSL=y +CONFIG_MQTT_TRANSPORT_WEBSOCKET=y +CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE=y +# CONFIG_MQTT_MSG_ID_INCREMENTAL is not set +# CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set +# CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set +# CONFIG_MQTT_USE_CUSTOM_CONFIG is not set +# CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set +# CONFIG_MQTT_CUSTOM_OUTBOX is not set +# end of ESP-MQTT Configurations + +# +# Newlib +# +CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF is not set +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set +CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y +# CONFIG_NEWLIB_NANO_FORMAT is not set +# end of Newlib + +# +# NVS +# +# end of NVS + +# +# OpenSSL +# +# CONFIG_OPENSSL_DEBUG is not set +CONFIG_OPENSSL_ERROR_STACK=y +# CONFIG_OPENSSL_ASSERT_DO_NOTHING is not set +CONFIG_OPENSSL_ASSERT_EXIT=y +# end of OpenSSL + +# +# PThreads +# +CONFIG_PTHREAD_TASK_PRIO_DEFAULT=5 +CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 +CONFIG_PTHREAD_STACK_MIN=768 +CONFIG_PTHREAD_TASK_CORE_DEFAULT=-1 +CONFIG_PTHREAD_TASK_NAME_DEFAULT="pthread" +# end of PThreads + +# +# SPI Flash driver +# +# CONFIG_SPI_FLASH_VERIFY_WRITE is not set +# CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set +CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y +CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS=y +# CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS is not set +# CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED is not set +# CONFIG_SPI_FLASH_USE_LEGACY_IMPL is not set +# CONFIG_SPI_FLASH_BYPASS_BLOCK_ERASE is not set +CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y +CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS=20 +CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1 +CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE=8192 +# CONFIG_SPI_FLASH_SIZE_OVERRIDE is not set +# CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED is not set + +# +# Auto-detect flash chips +# +CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP=y +# end of Auto-detect flash chips + +CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE=y +# end of SPI Flash driver + +# +# SPIFFS Configuration +# +CONFIG_SPIFFS_MAX_PARTITIONS=3 + +# +# SPIFFS Cache Configuration +# +CONFIG_SPIFFS_CACHE=y +CONFIG_SPIFFS_CACHE_WR=y +# CONFIG_SPIFFS_CACHE_STATS is not set +# end of SPIFFS Cache Configuration + +CONFIG_SPIFFS_PAGE_CHECK=y +CONFIG_SPIFFS_GC_MAX_RUNS=10 +# CONFIG_SPIFFS_GC_STATS is not set +CONFIG_SPIFFS_PAGE_SIZE=512 +CONFIG_SPIFFS_OBJ_NAME_LEN=256 +# CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set +CONFIG_SPIFFS_USE_MAGIC=y +CONFIG_SPIFFS_USE_MAGIC_LENGTH=y +CONFIG_SPIFFS_META_LENGTH=4 +CONFIG_SPIFFS_USE_MTIME=y + +# +# Debug Configuration +# +# CONFIG_SPIFFS_DBG is not set +# CONFIG_SPIFFS_API_DBG is not set +# CONFIG_SPIFFS_GC_DBG is not set +# CONFIG_SPIFFS_CACHE_DBG is not set +# CONFIG_SPIFFS_CHECK_DBG is not set +# CONFIG_SPIFFS_TEST_VISUALISATION is not set +# end of Debug Configuration +# end of SPIFFS Configuration + +# +# TCP Transport +# + +# +# Websocket +# +CONFIG_WS_TRANSPORT=y +CONFIG_WS_BUFFER_SIZE=1024 +# end of Websocket +# end of TCP Transport + +# +# TinyUSB +# +CONFIG_USB_ENABLED=y +CONFIG_USB_CDC_ENABLED=y +CONFIG_USB_DESC_CDC_STRING=".NET nanoFramework device" +CONFIG_USB_DESC_PRODUCT_STRING=".NET nanoFramework device" +CONFIG_USB_CDC_RX_BUFSIZE=64 +# setting this to WP packet size +CONFIG_USB_CDC_TX_BUFSIZE=2048 +# end of TinyUSB + +# +# Unity unit testing library +# +CONFIG_UNITY_ENABLE_FLOAT=y +CONFIG_UNITY_ENABLE_DOUBLE=y +# CONFIG_UNITY_ENABLE_COLOR is not set +CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y +# CONFIG_UNITY_ENABLE_FIXTURE is not set +# CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set +# end of Unity unit testing library + +# +# Virtual file system +# +CONFIG_VFS_SUPPORT_IO=y +CONFIG_VFS_SUPPORT_DIR=y +CONFIG_VFS_SUPPORT_SELECT=y +CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y +CONFIG_VFS_SUPPORT_TERMIOS=y + +# +# Host File System I/O (Semihosting) +# +CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS=1 +CONFIG_VFS_SEMIHOSTFS_HOST_PATH_MAX_LEN=128 +# end of Host File System I/O (Semihosting) +# end of Virtual file system + +# +# Wear Levelling +# +# CONFIG_WL_SECTOR_SIZE_512 is not set +CONFIG_WL_SECTOR_SIZE_4096=y +CONFIG_WL_SECTOR_SIZE=4096 +# end of Wear Levelling + +# +# Wi-Fi Provisioning Manager +# +CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 +CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 +# end of Wi-Fi Provisioning Manager + +# +# Supplicant +# +CONFIG_WPA_MBEDTLS_CRYPTO=y +# CONFIG_WPA_WAPI_PSK is not set +# CONFIG_WPA_DEBUG_PRINT is not set +# CONFIG_WPA_TESTING_OPTIONS is not set +# CONFIG_WPA_WPS_STRICT is not set +# CONFIG_WPA_11KV_SUPPORT is not set +# end of Supplicant +# end of Component config +# +# Bluetooth +# +CONFIG_BT_ENABLED=y +CONFIG_BT_NIMBLE_ENABLED=y +CONFIG_BT_BLUEDROID_ENABLED=n + +# +# Bluetooth controller +# +CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y +CONFIG_BTDM_CTRL_BLE_MAX_CONN_EFF=3 +CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n +CONFIG_BTDM_CTRL_MODE_BTDM=n + +# +# NimBLE +# +CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_INTERNAL=y +CONFIG_BT_NIMBLE_PINNED_TO_CORE=0 +CONFIG_BT_NIMBLE_PINNED_TO_CORE_0=y +CONFIG_BT_NIMBLE_MAX_CONNECTIONS=3 +CONFIG_BT_NIMBLE_MAX_BONDS=3 +CONFIG_BT_NIMBLE_MAX_CCCDS=8 +CONFIG_BT_NIMBLE_L2CAP_COC_MAX_NUM=0 +CONFIG_BT_NIMBLE_TASK_STACK_SIZE=4096 +CONFIG_BT_NIMBLE_ROLE_CENTRAL=y +CONFIG_BT_NIMBLE_ROLE_PERIPHERAL=y +CONFIG_BT_NIMBLE_ROLE_BROADCASTER=y +CONFIG_BT_NIMBLE_ROLE_OBSERVER=y +CONFIG_BT_NIMBLE_SM_LEGACY=y +CONFIG_BT_NIMBLE_SM_SC=y +CONFIG_BT_NIMBLE_SVC_GAP_DEVICE_NAME="nanoBLE" +CONFIG_BT_NIMBLE_GAP_DEVICE_NAME_MAX_LEN=31 +CONFIG_BT_NIMBLE_ATT_PREFERRED_MTU=256 +CONFIG_BT_NIMBLE_SVC_GAP_APPEARANCE=0 +CONFIG_BT_NIMBLE_ACL_BUF_COUNT=10 +CONFIG_BT_NIMBLE_ACL_BUF_SIZE=255 +CONFIG_BT_NIMBLE_HCI_EVT_BUF_SIZE=70 +CONFIG_BT_NIMBLE_HCI_EVT_HI_BUF_COUNT=20 +CONFIG_BT_NIMBLE_HCI_EVT_LO_BUF_COUNT=8 +CONFIG_BT_NIMBLE_MSYS1_BLOCK_COUNT=12 +CONFIG_BT_NIMBLE_HS_FLOW_CTRL=y +CONFIG_BT_NIMBLE_HS_FLOW_CTRL_ITVL=1000 +CONFIG_BT_NIMBLE_HS_FLOW_CTRL_THRESH=2 +CONFIG_BT_NIMBLE_HS_FLOW_CTRL_TX_ON_DISCONNECT=y +CONFIG_BT_NIMBLE_RPA_TIMEOUT=900 +CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS=y +CONFIG_BT_NIMBLE_HS_STOP_TIMEOUT_MS=2000 +CONFIG_BT_NIMBLE_USE_ESP_TIMER=y diff --git a/targets/ESP32/_IDF/sdkconfig.default_ble_rev3.esp32 b/targets/ESP32/_IDF/sdkconfig.default_ble_rev3.esp32 index d811572b6e..1d0a6b5318 100644 --- a/targets/ESP32/_IDF/sdkconfig.default_ble_rev3.esp32 +++ b/targets/ESP32/_IDF/sdkconfig.default_ble_rev3.esp32 @@ -482,7 +482,6 @@ CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 CONFIG_ESP32_WIFI_STATIC_TX_BUFFER=y # CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER is not set -CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 # CONFIG_ESP32_WIFI_CSI_ENABLED is not set CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y @@ -809,6 +808,7 @@ CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 CONFIG_MBEDTLS_DYNAMIC_BUFFER=y # CONFIG_MBEDTLS_DEBUG is not set CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH=y +CONFIG_MBEDTLS_DYNAMIC_FREE_PEER_CERT=y # CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is not set # @@ -817,7 +817,8 @@ CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH=y # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE is not set # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL is not set # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set -# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE=y # CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set # end of Certificate Bundle @@ -1032,8 +1033,8 @@ CONFIG_SPIFFS_CACHE_WR=y CONFIG_SPIFFS_PAGE_CHECK=y CONFIG_SPIFFS_GC_MAX_RUNS=10 # CONFIG_SPIFFS_GC_STATS is not set -CONFIG_SPIFFS_PAGE_SIZE=256 -CONFIG_SPIFFS_OBJ_NAME_LEN=32 +CONFIG_SPIFFS_PAGE_SIZE=512 +CONFIG_SPIFFS_OBJ_NAME_LEN=256 # CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set CONFIG_SPIFFS_USE_MAGIC=y CONFIG_SPIFFS_USE_MAGIC_LENGTH=y diff --git a/targets/ESP32/_IDF/sdkconfig.default_nopsram.esp32 b/targets/ESP32/_IDF/sdkconfig.default_nopsram.esp32 index 3735228791..aaf41709fd 100644 --- a/targets/ESP32/_IDF/sdkconfig.default_nopsram.esp32 +++ b/targets/ESP32/_IDF/sdkconfig.default_nopsram.esp32 @@ -457,7 +457,6 @@ CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 # CONFIG_ESP32_WIFI_STATIC_TX_BUFFER is not set CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y -CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 # CONFIG_ESP32_WIFI_CSI_ENABLED is not set CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y @@ -784,6 +783,7 @@ CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 CONFIG_MBEDTLS_DYNAMIC_BUFFER=y # CONFIG_MBEDTLS_DEBUG is not set CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH=y +CONFIG_MBEDTLS_DYNAMIC_FREE_PEER_CERT=y # CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is not set # @@ -792,7 +792,8 @@ CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH=y # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE is not set # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL is not set # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set -# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE=y # CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set # end of Certificate Bundle @@ -1007,8 +1008,8 @@ CONFIG_SPIFFS_CACHE_WR=y CONFIG_SPIFFS_PAGE_CHECK=y CONFIG_SPIFFS_GC_MAX_RUNS=10 # CONFIG_SPIFFS_GC_STATS is not set -CONFIG_SPIFFS_PAGE_SIZE=256 -CONFIG_SPIFFS_OBJ_NAME_LEN=32 +CONFIG_SPIFFS_PAGE_SIZE=512 +CONFIG_SPIFFS_OBJ_NAME_LEN=256 # CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set CONFIG_SPIFFS_USE_MAGIC=y CONFIG_SPIFFS_USE_MAGIC_LENGTH=y diff --git a/targets/ESP32/_IDF/sdkconfig.default_nopsram_ble.esp32 b/targets/ESP32/_IDF/sdkconfig.default_nopsram_ble.esp32 index 7c47dd7da0..b9f22b8482 100644 --- a/targets/ESP32/_IDF/sdkconfig.default_nopsram_ble.esp32 +++ b/targets/ESP32/_IDF/sdkconfig.default_nopsram_ble.esp32 @@ -597,9 +597,8 @@ CONFIG_ESP_TIMER_IMPL_TG0_LAC=y CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE=y CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 -CONFIG_ESP32_WIFI_STATIC_TX_BUFFER=y -# CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER is not set -CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=0 +# CONFIG_ESP32_WIFI_STATIC_TX_BUFFER is not set +CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y CONFIG_ESP32_WIFI_STATIC_TX_BUFFER_NUM=16 # CONFIG_ESP32_WIFI_CSI_ENABLED is not set CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y @@ -618,7 +617,7 @@ CONFIG_WIFI_LOG_DEFAULT_LEVEL_INFO=y # CONFIG_WIFI_LOG_DEFAULT_LEVEL_DEBUG is not set # CONFIG_WIFI_LOG_DEFAULT_LEVEL_VERBOSE is not set CONFIG_ESP32_WIFI_IRAM_OPT=y -CONFIG_ESP32_WIFI_RX_IRAM_OPT=y +CONFIG_ESP32_WIFI_RX_IRAM_OPT=n CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y # CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set # CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE is not set @@ -928,12 +927,14 @@ CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 CONFIG_MBEDTLS_DYNAMIC_BUFFER=y # CONFIG_MBEDTLS_DEBUG is not set CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH=y +CONFIG_MBEDTLS_DYNAMIC_FREE_PEER_CERT=y # CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is not set # # Certificate Bundle # -# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE is not set +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE=y # end of Certificate Bundle # CONFIG_MBEDTLS_ECP_RESTARTABLE is not set @@ -1149,8 +1150,8 @@ CONFIG_SPIFFS_CACHE_WR=y CONFIG_SPIFFS_PAGE_CHECK=y CONFIG_SPIFFS_GC_MAX_RUNS=10 # CONFIG_SPIFFS_GC_STATS is not set -CONFIG_SPIFFS_PAGE_SIZE=256 -CONFIG_SPIFFS_OBJ_NAME_LEN=32 +CONFIG_SPIFFS_PAGE_SIZE=512 +CONFIG_SPIFFS_OBJ_NAME_LEN=256 # CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set CONFIG_SPIFFS_USE_MAGIC=y CONFIG_SPIFFS_USE_MAGIC_LENGTH=y diff --git a/targets/ESP32/_IDF/sdkconfig.default_nopsram_rev3.esp32 b/targets/ESP32/_IDF/sdkconfig.default_nopsram_rev3.esp32 index 1377b3c21d..e051c82217 100644 --- a/targets/ESP32/_IDF/sdkconfig.default_nopsram_rev3.esp32 +++ b/targets/ESP32/_IDF/sdkconfig.default_nopsram_rev3.esp32 @@ -458,7 +458,6 @@ CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 # CONFIG_ESP32_WIFI_STATIC_TX_BUFFER is not set CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y -CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 # CONFIG_ESP32_WIFI_CSI_ENABLED is not set CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y @@ -785,6 +784,7 @@ CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 CONFIG_MBEDTLS_DYNAMIC_BUFFER=y # CONFIG_MBEDTLS_DEBUG is not set CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH=y +CONFIG_MBEDTLS_DYNAMIC_FREE_PEER_CERT=y # CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is not set # @@ -793,8 +793,8 @@ CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH=y # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE is not set # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL is not set # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set -# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set -# CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE=y # end of Certificate Bundle # CONFIG_MBEDTLS_ECP_RESTARTABLE is not set @@ -1008,8 +1008,8 @@ CONFIG_SPIFFS_CACHE_WR=y CONFIG_SPIFFS_PAGE_CHECK=y CONFIG_SPIFFS_GC_MAX_RUNS=10 # CONFIG_SPIFFS_GC_STATS is not set -CONFIG_SPIFFS_PAGE_SIZE=256 -CONFIG_SPIFFS_OBJ_NAME_LEN=32 +CONFIG_SPIFFS_PAGE_SIZE=512 +CONFIG_SPIFFS_OBJ_NAME_LEN=256 # CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set CONFIG_SPIFFS_USE_MAGIC=y CONFIG_SPIFFS_USE_MAGIC_LENGTH=y diff --git a/targets/ESP32/_IDF/sdkconfig.default_pico b/targets/ESP32/_IDF/sdkconfig.default_pico index c5bd92d0db..0732474c13 100644 --- a/targets/ESP32/_IDF/sdkconfig.default_pico +++ b/targets/ESP32/_IDF/sdkconfig.default_pico @@ -243,30 +243,7 @@ CONFIG_EFUSE_MAX_BLK_LEN=256 # CONFIG_ESP32_REV_MIN_1=y CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y -CONFIG_ESP32_SPIRAM_SUPPORT=y - -# -# SPI RAM config -# -CONFIG_SPIRAM_BOOT_INIT=y -CONFIG_SPIRAM_IGNORE_NOTFOUND=y -CONFIG_SPIRAM_USE_MEMMAP=n -CONFIG_SPIRAM_USE_CAPS_ALLOC=n -CONFIG_SPIRAM_USE_MALLOC=y -CONFIG_SPIRAM_TYPE_AUTO=y -CONFIG_SPIRAM_TYPE_ESPPSRAM32=n -CONFIG_SPIRAM_TYPE_ESPPSRAM64=n -CONFIG_SPIRAM_SIZE=-1 -CONFIG_SPIRAM_SPEED_40M=y -# CONFIG_SPIRAM_MEMTEST is not set -CONFIG_SPIRAM_CACHE_WORKAROUND=y -CONFIG_SPIRAM_BANKSWITCH_ENABLE=y -CONFIG_SPIRAM_BANKSWITCH_RESERVE=8 -CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=16384 -CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y -CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=32768 -CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=n -CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=n +CONFIG_ESP32_SPIRAM_SUPPORT=n # # ESP-TLS @@ -278,56 +255,6 @@ CONFIG_ESP_TLS_USE_DS_PERIPHERAL=y # CONFIG_ESP_TLS_INSECURE is not set # end of ESP-TLS -# -# Cache config -# -CONFIG_ESP32S2_INSTRUCTION_CACHE_8KB=y -# CONFIG_ESP32S2_INSTRUCTION_CACHE_16KB is not set -# CONFIG_ESP32S2_INSTRUCTION_CACHE_LINE_16B is not set -CONFIG_ESP32S2_INSTRUCTION_CACHE_LINE_32B=y -CONFIG_ESP32S2_DATA_CACHE_0KB=y -# CONFIG_ESP32S2_DATA_CACHE_8KB is not set -# CONFIG_ESP32S2_DATA_CACHE_16KB is not set -# CONFIG_ESP32S2_DATA_CACHE_LINE_16B is not set -CONFIG_ESP32S2_DATA_CACHE_LINE_32B=y -# CONFIG_ESP32S2_INSTRUCTION_CACHE_WRAP is not set -# CONFIG_ESP32S2_DATA_CACHE_WRAP is not set -# end of Cache config - -# CONFIG_ESP32S2_SPIRAM_SUPPORT is not set -# CONFIG_ESP32S2_TRAX is not set -CONFIG_ESP32S2_TRACEMEM_RESERVE_DRAM=0x0 -# CONFIG_ESP32S2_UNIVERSAL_MAC_ADDRESSES_ONE is not set -CONFIG_ESP32S2_UNIVERSAL_MAC_ADDRESSES_TWO=y -CONFIG_ESP32S2_UNIVERSAL_MAC_ADDRESSES=2 -# CONFIG_ESP32S2_ULP_COPROC_ENABLED is not set -CONFIG_ESP32S2_ULP_COPROC_RESERVE_MEM=0 -CONFIG_ESP32S2_DEBUG_OCDAWARE=y -# CONFIG_ESP32S2_DEBUG_STUBS_ENABLE is not set -CONFIG_ESP32S2_BROWNOUT_DET=y -CONFIG_ESP32S2_BROWNOUT_DET_LVL_SEL_7=y -# CONFIG_ESP32S2_BROWNOUT_DET_LVL_SEL_6 is not set -# CONFIG_ESP32S2_BROWNOUT_DET_LVL_SEL_5 is not set -# CONFIG_ESP32S2_BROWNOUT_DET_LVL_SEL_4 is not set -# CONFIG_ESP32S2_BROWNOUT_DET_LVL_SEL_3 is not set -# CONFIG_ESP32S2_BROWNOUT_DET_LVL_SEL_2 is not set -# CONFIG_ESP32S2_BROWNOUT_DET_LVL_SEL_1 is not set -CONFIG_ESP32S2_BROWNOUT_DET_LVL=7 -CONFIG_ESP32S2_TIME_SYSCALL_USE_RTC_FRC1=y -# CONFIG_ESP32S2_TIME_SYSCALL_USE_RTC is not set -# CONFIG_ESP32S2_TIME_SYSCALL_USE_FRC1 is not set -# CONFIG_ESP32S2_TIME_SYSCALL_USE_NONE is not set -CONFIG_ESP32S2_RTC_CLK_SRC_INT_RC=y -# CONFIG_ESP32S2_RTC_CLK_SRC_EXT_CRYS is not set -# CONFIG_ESP32S2_RTC_CLK_SRC_EXT_OSC is not set -# CONFIG_ESP32S2_RTC_CLK_SRC_INT_8MD256 is not set -CONFIG_ESP32S2_RTC_CLK_CAL_CYCLES=576 -# CONFIG_ESP32S2_NO_BLOBS is not set -# CONFIG_ESP32S2_KEEP_USB_ALIVE is not set -# CONFIG_ESP32S2_RTCDATA_IN_FAST_MEM is not set -# CONFIG_ESP32S2_USE_FIXED_STATIC_RAM_SIZE is not set -# end of ESP32S2-specific - # # ADC-Calibration # @@ -458,7 +385,6 @@ CONFIG_PM_ENABLE=y CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y # CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set # CONFIG_ESP_SYSTEM_PANIC_GDBSTUB is not set -CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE=n CONFIG_ESP_SYSTEM_RTC_FAST_MEM_AS_HEAP_DEPCHECK=y CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP=y CONFIG_ESP_SLEEP_POWER_DOWN_FLASH=y @@ -477,10 +403,9 @@ CONFIG_ESP_TIMER_IMPL_SYSTIMER=y # Wi-Fi # CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 -CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 +CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=10 # CONFIG_ESP32_WIFI_STATIC_TX_BUFFER is not set CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y -CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 # CONFIG_ESP32_WIFI_CSI_ENABLED is not set CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y @@ -491,14 +416,14 @@ CONFIG_ESP32_WIFI_NVS_ENABLED=y CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1=y CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 -# CONFIG_WIFI_LOG_DEFAULT_LEVEL_NONE is not set +CONFIG_WIFI_LOG_DEFAULT_LEVEL_NONE=y # CONFIG_WIFI_LOG_DEFAULT_LEVEL_ERROR is not set # CONFIG_WIFI_LOG_DEFAULT_LEVEL_WARN is not set -CONFIG_WIFI_LOG_DEFAULT_LEVEL_INFO=y +# CONFIG_WIFI_LOG_DEFAULT_LEVEL_INFO is not set # CONFIG_WIFI_LOG_DEFAULT_LEVEL_DEBUG is not set # CONFIG_WIFI_LOG_DEFAULT_LEVEL_VERBOSE is not set -CONFIG_ESP32_WIFI_IRAM_OPT=y -CONFIG_ESP32_WIFI_RX_IRAM_OPT=y +CONFIG_ESP32_WIFI_IRAM_OPT=n +CONFIG_ESP32_WIFI_RX_IRAM_OPT=n CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y # CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set # CONFIG_ESP_WIFI_FTM_ENABLE is not set @@ -807,6 +732,7 @@ CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 CONFIG_MBEDTLS_DYNAMIC_BUFFER=y # CONFIG_MBEDTLS_DEBUG is not set CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH=y +CONFIG_MBEDTLS_DYNAMIC_FREE_PEER_CERT=y # CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is not set # @@ -815,8 +741,8 @@ CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH=y # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE is not set # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL is not set # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set -# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set -# CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE=y # end of Certificate Bundle # CONFIG_MBEDTLS_ECP_RESTARTABLE is not set @@ -1030,8 +956,8 @@ CONFIG_SPIFFS_CACHE_WR=y CONFIG_SPIFFS_PAGE_CHECK=y CONFIG_SPIFFS_GC_MAX_RUNS=10 # CONFIG_SPIFFS_GC_STATS is not set -CONFIG_SPIFFS_PAGE_SIZE=256 -CONFIG_SPIFFS_OBJ_NAME_LEN=32 +CONFIG_SPIFFS_PAGE_SIZE=512 +CONFIG_SPIFFS_OBJ_NAME_LEN=256 # CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set CONFIG_SPIFFS_USE_MAGIC=y CONFIG_SPIFFS_USE_MAGIC_LENGTH=y @@ -1062,12 +988,6 @@ CONFIG_WS_BUFFER_SIZE=1024 # end of Websocket # end of TCP Transport -# -# TinyUSB -# -# CONFIG_USB_ENABLED is not set -# end of TinyUSB - # # Unity unit testing library # diff --git a/targets/ESP32/_IDF/sdkconfig.default_pico_ble_rev3 b/targets/ESP32/_IDF/sdkconfig.default_pico_ble_rev3 index 815d87d763..dc12aec2a8 100644 --- a/targets/ESP32/_IDF/sdkconfig.default_pico_ble_rev3 +++ b/targets/ESP32/_IDF/sdkconfig.default_pico_ble_rev3 @@ -483,7 +483,6 @@ CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 CONFIG_ESP32_WIFI_STATIC_TX_BUFFER=y # CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER is not set -CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 # CONFIG_ESP32_WIFI_CSI_ENABLED is not set CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y @@ -501,7 +500,7 @@ CONFIG_WIFI_LOG_DEFAULT_LEVEL_INFO=y # CONFIG_WIFI_LOG_DEFAULT_LEVEL_DEBUG is not set # CONFIG_WIFI_LOG_DEFAULT_LEVEL_VERBOSE is not set CONFIG_ESP32_WIFI_IRAM_OPT=y -CONFIG_ESP32_WIFI_RX_IRAM_OPT=y +CONFIG_ESP32_WIFI_RX_IRAM_OPT=n CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y # CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set # CONFIG_ESP_WIFI_FTM_ENABLE is not set @@ -810,6 +809,7 @@ CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 CONFIG_MBEDTLS_DYNAMIC_BUFFER=y # CONFIG_MBEDTLS_DEBUG is not set CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH=y +CONFIG_MBEDTLS_DYNAMIC_FREE_PEER_CERT=y # CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is not set # @@ -818,7 +818,8 @@ CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH=y # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE is not set # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL is not set # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set -# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE=y # CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set # end of Certificate Bundle @@ -1033,8 +1034,8 @@ CONFIG_SPIFFS_CACHE_WR=y CONFIG_SPIFFS_PAGE_CHECK=y CONFIG_SPIFFS_GC_MAX_RUNS=10 # CONFIG_SPIFFS_GC_STATS is not set -CONFIG_SPIFFS_PAGE_SIZE=256 -CONFIG_SPIFFS_OBJ_NAME_LEN=32 +CONFIG_SPIFFS_PAGE_SIZE=512 +CONFIG_SPIFFS_OBJ_NAME_LEN=256 # CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set CONFIG_SPIFFS_USE_MAGIC=y CONFIG_SPIFFS_USE_MAGIC_LENGTH=y diff --git a/targets/ESP32/_IDF/sdkconfig.default_rev3.esp32 b/targets/ESP32/_IDF/sdkconfig.default_rev3.esp32 index b6a3f74490..2d82af59c1 100644 --- a/targets/ESP32/_IDF/sdkconfig.default_rev3.esp32 +++ b/targets/ESP32/_IDF/sdkconfig.default_rev3.esp32 @@ -482,7 +482,6 @@ CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 CONFIG_ESP32_WIFI_STATIC_TX_BUFFER=y # CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER is not set -CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 # CONFIG_ESP32_WIFI_CSI_ENABLED is not set CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y @@ -809,6 +808,7 @@ CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 CONFIG_MBEDTLS_DYNAMIC_BUFFER=y # CONFIG_MBEDTLS_DEBUG is not set CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH=y +CONFIG_MBEDTLS_DYNAMIC_FREE_PEER_CERT=y # CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is not set # @@ -817,7 +817,8 @@ CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH=y # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE is not set # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL is not set # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set -# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE=y # CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set # end of Certificate Bundle @@ -1032,8 +1033,8 @@ CONFIG_SPIFFS_CACHE_WR=y CONFIG_SPIFFS_PAGE_CHECK=y CONFIG_SPIFFS_GC_MAX_RUNS=10 # CONFIG_SPIFFS_GC_STATS is not set -CONFIG_SPIFFS_PAGE_SIZE=256 -CONFIG_SPIFFS_OBJ_NAME_LEN=32 +CONFIG_SPIFFS_PAGE_SIZE=512 +CONFIG_SPIFFS_OBJ_NAME_LEN=256 # CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set CONFIG_SPIFFS_USE_MAGIC=y CONFIG_SPIFFS_USE_MAGIC_LENGTH=y diff --git a/targets/ESP32/_IDF/sdkconfig.default_rev3.esp32c3 b/targets/ESP32/_IDF/sdkconfig.default_rev3.esp32c3 index 2c2ecb6a28..93f70a9628 100644 --- a/targets/ESP32/_IDF/sdkconfig.default_rev3.esp32c3 +++ b/targets/ESP32/_IDF/sdkconfig.default_rev3.esp32c3 @@ -516,7 +516,6 @@ CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 # CONFIG_ESP32_WIFI_STATIC_TX_BUFFER=y # CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER is not set -CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 # CONFIG_ESP32_WIFI_CSI_ENABLED is not set CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y @@ -842,6 +841,7 @@ CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 CONFIG_MBEDTLS_DYNAMIC_BUFFER=y # CONFIG_MBEDTLS_DEBUG=y CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH=y +CONFIG_MBEDTLS_DYNAMIC_FREE_PEER_CERT=y # CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is not set # @@ -850,7 +850,8 @@ CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH=y # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE is not set # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL is not set # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set -# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE=y # CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set # end of Certificate Bundle @@ -1065,8 +1066,8 @@ CONFIG_SPIFFS_CACHE_WR=y CONFIG_SPIFFS_PAGE_CHECK=y CONFIG_SPIFFS_GC_MAX_RUNS=10 # CONFIG_SPIFFS_GC_STATS is not set -CONFIG_SPIFFS_PAGE_SIZE=256 -CONFIG_SPIFFS_OBJ_NAME_LEN=32 +CONFIG_SPIFFS_PAGE_SIZE=512 +CONFIG_SPIFFS_OBJ_NAME_LEN=256 # CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set CONFIG_SPIFFS_USE_MAGIC=y CONFIG_SPIFFS_USE_MAGIC_LENGTH=y diff --git a/targets/ESP32/_IDF/sdkconfig.default_rev3_noconsole.esp32c3 b/targets/ESP32/_IDF/sdkconfig.default_rev3_noconsole.esp32c3 new file mode 100644 index 0000000000..5cb37cc1a5 --- /dev/null +++ b/targets/ESP32/_IDF/sdkconfig.default_rev3_noconsole.esp32c3 @@ -0,0 +1,1163 @@ +# +# Automatically generated file. DO NOT EDIT. +# Espressif IoT Development Framework (ESP-IDF) Project Configuration +# +CONFIG_IDF_CMAKE=y +CONFIG_IDF_TARGET_ARCH_RISCV=y +CONFIG_IDF_TARGET="esp32c3" +CONFIG_IDF_TARGET_ESP32C3=y +CONFIG_IDF_FIRMWARE_CHIP_ID=0x0005 + +# +# SDK tool configuration +# +CONFIG_SDK_TOOLPREFIX="riscv32-esp-elf-" +# CONFIG_SDK_TOOLCHAIN_SUPPORTS_TIME_WIDE_64_BITS is not set +# end of SDK tool configuration + +# +# Build type +# +CONFIG_APP_BUILD_TYPE_APP_2NDBOOT=y +# CONFIG_APP_BUILD_TYPE_ELF_RAM is not set +CONFIG_APP_BUILD_GENERATE_BINARIES=y +CONFIG_APP_BUILD_BOOTLOADER=y +CONFIG_APP_BUILD_USE_FLASH_SECTIONS=y +# end of Build type + +# +# Application manager +# +CONFIG_APP_COMPILE_TIME_DATE=y +# CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set +# CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set +# CONFIG_APP_PROJECT_VER_FROM_CONFIG is not set +CONFIG_APP_RETRIEVE_LEN_ELF_SHA=16 +# end of Application manager + +# +# Bootloader config +# +CONFIG_BOOTLOADER_OFFSET_IN_FLASH=0x1000 +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG=y +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set +CONFIG_BOOTLOADER_LOG_LEVEL_NONE=y +# CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_INFO is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set +CONFIG_BOOTLOADER_LOG_LEVEL=0 +CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y +# CONFIG_BOOTLOADER_FACTORY_RESET is not set +# CONFIG_BOOTLOADER_APP_TEST is not set +CONFIG_BOOTLOADER_WDT_ENABLE=y +# CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE is not set +CONFIG_BOOTLOADER_WDT_TIME_MS=9000 +# CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS is not set +CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 +# CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC is not set +# end of Bootloader config + +# +# Security features +# +CONFIG_SECURE_BOOT_SUPPORTS_RSA=y +CONFIG_SECURE_TARGET_HAS_SECURE_ROM_DL_MODE=y +# CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set +# CONFIG_SECURE_BOOT is not set +# CONFIG_SECURE_FLASH_ENC_ENABLED is not set +# CONFIG_SECURE_BOOT_ALLOW_JTAG is not set +# end of Security features + +# +# Serial flasher config +# +CONFIG_ESPTOOLPY_BAUD_OTHER_VAL=115200 +# CONFIG_ESPTOOLPY_NO_STUB is not set +# CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set +# CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set +CONFIG_ESPTOOLPY_FLASHMODE_DIO=y +# CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set +CONFIG_ESPTOOLPY_FLASHMODE="dio" +CONFIG_ESPTOOLPY_FLASHFREQ_80M=y +# CONFIG_ESPTOOLPY_FLASHFREQ_40M is not set +# CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set +# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set +CONFIG_ESPTOOLPY_FLASHFREQ="80m" +# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE="2MB" +CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y +CONFIG_ESPTOOLPY_BEFORE_RESET=y +# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set +CONFIG_ESPTOOLPY_BEFORE="default_reset" +CONFIG_ESPTOOLPY_AFTER_RESET=y +# CONFIG_ESPTOOLPY_AFTER_NORESET is not set +CONFIG_ESPTOOLPY_AFTER="hard_reset" +# CONFIG_ESPTOOLPY_MONITOR_BAUD_CONSOLE is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_9600B is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_57600B is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_115200B is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_230400B is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_921600B=y +# CONFIG_ESPTOOLPY_MONITOR_BAUD_2MB is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_OTHER is not set +CONFIG_ESPTOOLPY_MONITOR_BAUD_OTHER_VAL=115200 +CONFIG_ESPTOOLPY_MONITOR_BAUD=921600 +# end of Serial flasher config + +# +# Partition Table +# +CONFIG_PARTITION_TABLE_SINGLE_APP=y +# CONFIG_PARTITION_TABLE_TWO_OTA is not set +CONFIG_PARTITION_TABLE_CUSTOM=y +# default to 4mb partition table for nanoCLR +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="targets/ESP32/_IDF/${TARGET_SERIES_SHORT}/partitions_nanoclr_4mb.csv" +# CONFIG_PARTITION_TABLE_FILENAME is not set +CONFIG_PARTITION_TABLE_OFFSET=0x8000 +CONFIG_PARTITION_TABLE_MD5=y +# end of Partition Table + +# +# Compiler options +# +# CONFIG_COMPILER_OPTIMIZATION_DEFAULT=y +CONFIG_COMPILER_OPTIMIZATION_SIZE=y +# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE=y +# CONFIG_COMPILER_CXX_EXCEPTIONS is not set +# CONFIG_COMPILER_CXX_RTTI is not set +CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y +# CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set +# CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set +# CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set +# CONFIG_COMPILER_WARN_WRITE_STRINGS is not set +# CONFIG_COMPILER_DISABLE_GCC8_WARNINGS is not set +# CONFIG_COMPILER_DUMP_RTL_FILES is not set +# end of Compiler options + +# +# Component config +# + +# +# Application Level Tracing +# +# CONFIG_APPTRACE_DEST_TRAX is not set +CONFIG_APPTRACE_DEST_NONE=y +CONFIG_APPTRACE_LOCK_ENABLE=y +# end of Application Level Tracing + +# +# ESP-ASIO +# +# CONFIG_ASIO_SSL_SUPPORT is not set +# end of ESP-ASIO + +CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 +CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 +CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 +CONFIG_BTDM_CTRL_BLE_MAX_CONN_EFF=0 +CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN_EFF=0 +CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF=0 +CONFIG_BTDM_CTRL_PINNED_TO_CORE=0 +CONFIG_BTDM_BLE_SLEEP_CLOCK_ACCURACY_INDEX_EFF=1 +CONFIG_BT_CTRL_MODE_EFF=1 +CONFIG_BT_CTRL_BLE_MAX_ACT=10 +CONFIG_BT_CTRL_BLE_MAX_ACT_EFF=10 +CONFIG_BT_CTRL_BLE_STATIC_ACL_TX_BUF_NB=0 +CONFIG_BT_CTRL_PINNED_TO_CORE=0 +CONFIG_BT_CTRL_HCI_TL=1 +CONFIG_BT_CTRL_ADV_DUP_FILT_MAX=30 +CONFIG_BT_CTRL_HW_CCA_EFF=0 +CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_EFF=0 +CONFIG_BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y +CONFIG_BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 +CONFIG_BT_CTRL_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 +CONFIG_BT_CTRL_BLE_SCAN_DUPL=y +CONFIG_BT_CTRL_SCAN_DUPL_TYPE=0 +CONFIG_BT_CTRL_SCAN_DUPL_CACHE_SIZE=100 +CONFIG_BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM_EFF=0 +CONFIG_BT_CTRL_SLEEP_MODE_EFF=0 +CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 +CONFIG_BT_CTRL_HCI_TL_EFF=1 +CONFIG_BT_RESERVE_DRAM=0 +CONFIG_BT_NIMBLE_USE_ESP_TIMER=y + +# +# CoAP Configuration +# +CONFIG_COAP_MBEDTLS_PSK=y +# CONFIG_COAP_MBEDTLS_PKI is not set +# CONFIG_COAP_MBEDTLS_DEBUG is not set +CONFIG_COAP_LOG_DEFAULT_LEVEL=0 +# end of CoAP Configuration + +# +# Driver configurations +# + +# +# ADC configuration +# +# CONFIG_ADC_FORCE_XPD_FSM is not set +CONFIG_ADC_DISABLE_DAC=y +# end of ADC configuration + +# +# SPI configuration +# +# CONFIG_SPI_MASTER_IN_IRAM is not set +CONFIG_SPI_MASTER_ISR_IN_IRAM=y +# CONFIG_SPI_SLAVE_IN_IRAM is not set +CONFIG_SPI_SLAVE_ISR_IN_IRAM=y +# end of SPI configuration + +# +# TWAI configuration +# +# CONFIG_TWAI_ISR_IN_IRAM is not set +# end of TWAI configuration + +# +# UART configuration +# +CONFIG_UART_ISR_IN_IRAM=y +# end of UART configuration +# end of Driver configurations + +# +# eFuse Bit Manager +# +# CONFIG_EFUSE_CUSTOM_TABLE is not set +# CONFIG_EFUSE_VIRTUAL is not set +CONFIG_EFUSE_MAX_BLK_LEN=256 +# end of eFuse Bit Manager + +# +# SPI RAM config +# +CONFIG_SPIRAM_BOOT_INIT=y +CONFIG_SPIRAM_IGNORE_NOTFOUND=y +CONFIG_SPIRAM_USE_MEMMAP=n +CONFIG_SPIRAM_USE_CAPS_ALLOC=n +CONFIG_SPIRAM_USE_MALLOC=y +CONFIG_SPIRAM_TYPE_AUTO=y +CONFIG_SPIRAM_TYPE_ESPPSRAM32=n +CONFIG_SPIRAM_TYPE_ESPPSRAM64=n +CONFIG_SPIRAM_SIZE=-1 +CONFIG_SPIRAM_SPEED_40M=y +# CONFIG_SPIRAM_MEMTEST is not set +CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=16384 +CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y +CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=32768 +CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=n +CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=n + +# +# ESP-TLS +# +CONFIG_ESP_TLS_USING_MBEDTLS=y +CONFIG_ESP_TLS_USE_DS_PERIPHERAL=y +# CONFIG_ESP_TLS_SERVER is not set +# CONFIG_ESP_TLS_PSK_VERIFICATION is not set +# CONFIG_ESP_TLS_INSECURE is not set +# end of ESP-TLS + + +# +# ESP32C3-Specific +# +CONFIG_ESP32C3_DEFAULT_CPU_FREQ_160=y +CONFIG_ESP32C3_DEFAULT_CPU_FREQ_MHZ=160 +# CONFIG_ESP32C3_REV_MIN_0 is not set +# CONFIG_ESP32C3_REV_MIN_1 is not set +# CONFIG_ESP32C3_REV_MIN_2 is not set +CONFIG_ESP32C3_REV_MIN_3=y +# CONFIG_ESP32C3_REV_MIN_4 is not set +CONFIG_ESP32C3_REV_MIN=3 +CONFIG_ESP32C3_DEBUG_OCDAWARE=y +CONFIG_ESP32C3_BROWNOUT_DET=y +CONFIG_ESP32C3_BROWNOUT_DET_LVL_SEL_7=y +# CONFIG_ESP32C3_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_ESP32C3_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_ESP32C3_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_ESP32C3_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_ESP32C3_BROWNOUT_DET_LVL_SEL_2 is not set +CONFIG_ESP32C3_BROWNOUT_DET_LVL=7 +CONFIG_ESP32C3_TIME_SYSCALL_USE_RTC_SYSTIMER=y +# CONFIG_ESP32C3_TIME_SYSCALL_USE_RTC is not set +# CONFIG_ESP32C3_TIME_SYSCALL_USE_SYSTIMER is not set +# CONFIG_ESP32C3_TIME_SYSCALL_USE_NONE is not set +CONFIG_ESP32C3_RTC_CLK_SRC_INT_RC=y +# CONFIG_ESP32C3_RTC_CLK_SRC_EXT_CRYS is not set +# CONFIG_ESP32C3_RTC_CLK_SRC_EXT_OSC is not set +# CONFIG_ESP32C3_RTC_CLK_SRC_INT_8MD256 is not set +CONFIG_ESP32C3_RTC_CLK_CAL_CYCLES=1024 +# CONFIG_ESP32C3_NO_BLOBS is not set +# end of ESP32C3-Specific + +# +# Cache config +# +CONFIG_ESP32S2_INSTRUCTION_CACHE_8KB=y +# CONFIG_ESP32S2_INSTRUCTION_CACHE_16KB is not set +# CONFIG_ESP32S2_INSTRUCTION_CACHE_LINE_16B is not set +CONFIG_ESP32S2_INSTRUCTION_CACHE_LINE_32B=y +CONFIG_ESP32S2_DATA_CACHE_0KB=y +# CONFIG_ESP32S2_DATA_CACHE_8KB is not set +# CONFIG_ESP32S2_DATA_CACHE_16KB is not set +# CONFIG_ESP32S2_DATA_CACHE_LINE_16B is not set +CONFIG_ESP32S2_DATA_CACHE_LINE_32B=y +# CONFIG_ESP32S2_INSTRUCTION_CACHE_WRAP is not set +# CONFIG_ESP32S2_DATA_CACHE_WRAP is not set +# end of Cache config + +CONFIG_ESP32S2_SPIRAM_SUPPORT=y +# CONFIG_ESP32S2_TRAX is not set +CONFIG_ESP32S2_TRACEMEM_RESERVE_DRAM=0x0 +# CONFIG_ESP32S2_UNIVERSAL_MAC_ADDRESSES_ONE is not set +CONFIG_ESP32S2_UNIVERSAL_MAC_ADDRESSES_TWO=y +CONFIG_ESP32S2_UNIVERSAL_MAC_ADDRESSES=2 +# CONFIG_ESP32S2_ULP_COPROC_ENABLED is not set +CONFIG_ESP32S2_ULP_COPROC_RESERVE_MEM=0 +CONFIG_ESP32S2_DEBUG_OCDAWARE=y +# CONFIG_ESP32S2_DEBUG_STUBS_ENABLE is not set +CONFIG_ESP32S2_BROWNOUT_DET=y +CONFIG_ESP32S2_BROWNOUT_DET_LVL_SEL_7=y +# CONFIG_ESP32S2_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_ESP32S2_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_ESP32S2_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_ESP32S2_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_ESP32S2_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_ESP32S2_BROWNOUT_DET_LVL_SEL_1 is not set +CONFIG_ESP32S2_BROWNOUT_DET_LVL=7 +CONFIG_ESP32S2_TIME_SYSCALL_USE_RTC_FRC1=y +# CONFIG_ESP32S2_TIME_SYSCALL_USE_RTC is not set +# CONFIG_ESP32S2_TIME_SYSCALL_USE_FRC1 is not set +# CONFIG_ESP32S2_TIME_SYSCALL_USE_NONE is not set +CONFIG_ESP32S2_RTC_CLK_SRC_INT_RC=y +# CONFIG_ESP32S2_RTC_CLK_SRC_EXT_CRYS is not set +# CONFIG_ESP32S2_RTC_CLK_SRC_EXT_OSC is not set +# CONFIG_ESP32S2_RTC_CLK_SRC_INT_8MD256 is not set +CONFIG_ESP32S2_RTC_CLK_CAL_CYCLES=576 +# CONFIG_ESP32S2_NO_BLOBS is not set +# CONFIG_ESP32S2_KEEP_USB_ALIVE is not set +# CONFIG_ESP32S2_RTCDATA_IN_FAST_MEM is not set +# CONFIG_ESP32S2_USE_FIXED_STATIC_RAM_SIZE is not set +# end of ESP32S2-specific + +# +# ADC-Calibration +# +# end of ADC-Calibration + +# config for XTAL freq +# adding it here, so it can be overriden by our CMake +CONFIG_ESP32_XTAL_FREQ_40=y + +# +# Common ESP-related +# +CONFIG_ESP_ERR_TO_NAME_LOOKUP=y +CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 +CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=3584 +CONFIG_ESP_IPC_TASK_STACK_SIZE=1024 +CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048 +CONFIG_ESP_CONSOLE_UART_DEFAULT=y +# CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG is not set +# CONFIG_ESP_CONSOLE_UART_CUSTOM is not set +# CONFIG_ESP_CONSOLE_NONE is not set +CONFIG_ESP_CONSOLE_SECONDARY_NONE=y +# CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG is not set +CONFIG_ESP_CONSOLE_UART=y +CONFIG_ESP_CONSOLE_UART_NUM=0 +CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 +CONFIG_ESP_INT_WDT=y +CONFIG_ESP_INT_WDT_TIMEOUT_MS=300 +# CONFIG_ESP_TASK_WDT is not set +# CONFIG_ESP_TASK_WDT_PANIC is not set +# CONFIG_ESP_TASK_WDT_TIMEOUT_S is not set +# CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0 is not set +# CONFIG_ESP_PANIC_HANDLER_IRAM is not set +CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_STA=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_AP=y +# end of Common ESP-related + +# +# Ethernet +# +# Parameters configured in binutils.ESP32.CMAKE +# +CONFIG_ETH_ENABLED=y +CONFIG_ETH_USE_ESP32_EMAC=y + +CONFIG_ETH_PHY_INTERFACE_RMII=y +# CONFIG_ETH_PHY_INTERFACE_MII is not set + +#CONFIG_ETH_RMII_CLK_OUTPUT=y +#CONFIG_ETH_RMII_CLK_OUT_GPIO=17 +#CONFIG_ETH_RMII_CLK_INPUT=y +#CONFIG_ETH_RMII_CLK_IN_GPIO=n + +CONFIG_ETH_DMA_BUFFER_SIZE=512 +CONFIG_ETH_DMA_RX_BUFFER_NUM=10 +CONFIG_ETH_DMA_TX_BUFFER_NUM=10 + +# Include SPI drivers in case used in build +CONFIG_ETH_USE_SPI_ETHERNET=y +#CONFIG_ETH_SPI_ETHERNET_DM9051=y +#CONFIG_ETH_SPI_ETHERNET_W5500=y +#CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL=y +#CONFIG_ETH_USE_OPENETH=n +# end of Ethernet + +# +# Event Loop Library +# +# CONFIG_ESP_EVENT_LOOP_PROFILING is not set +CONFIG_ESP_EVENT_POST_FROM_ISR=y +CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y +# end of Event Loop Library + +# +# GDB Stub +# +# end of GDB Stub + +# +# ESP HTTP client +# +CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y +# CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set +# end of ESP HTTP client + +# +# HTTP Server +# +CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 +CONFIG_HTTPD_MAX_URI_LEN=512 +CONFIG_HTTPD_ERR_RESP_NO_DELAY=y +CONFIG_HTTPD_PURGE_BUF_LEN=32 +# CONFIG_HTTPD_LOG_PURGE_DATA is not set +# CONFIG_HTTPD_WS_SUPPORT is not set +# end of HTTP Server + +# +# ESP HTTPS OTA +# +# CONFIG_OTA_ALLOW_HTTP is not set +# end of ESP HTTPS OTA + +# +# ESP HTTPS server +# +# CONFIG_ESP_HTTPS_SERVER_ENABLE is not set +# end of ESP HTTPS server + +# +# ESP NETIF Adapter +# +CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 +CONFIG_ESP_NETIF_TCPIP_LWIP=y +# CONFIG_ESP_NETIF_LOOPBACK is not set +# CONFIG_ESP_NETIF_TCPIP_ADAPTER_COMPATIBLE_LAYER is not set +# end of ESP NETIF Adapter + +# +# Power Management +# +CONFIG_PM_ENABLE=y +# end of Power Management + +# +# ESP System Settings +# +# CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT is not set +CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y +# CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set +# CONFIG_ESP_SYSTEM_PANIC_GDBSTUB is not set +CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE=y +CONFIG_ESP_SYSTEM_RTC_FAST_MEM_AS_HEAP_DEPCHECK=y +CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP=y +CONFIG_ESP_SLEEP_POWER_DOWN_FLASH=y + +# +# Memory protection +# +CONFIG_ESP_SYSTEM_MEMPROT_FEATURE=y +CONFIG_ESP_SYSTEM_MEMPROT_FEATURE_LOCK=y +# end of Memory protection +# end of ESP System Settings + +# +# High resolution timer (esp_timer) +# +# CONFIG_ESP_TIMER_PROFILING is not set +CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y +CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y +CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584 +CONFIG_ESP_TIMER_IMPL_SYSTIMER=y +# end of High resolution timer (esp_timer) + +# +# Wi-Fi +# +CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 +CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 +# CONFIG_ESP32_WIFI_STATIC_TX_BUFFER=y +# CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER is not set +CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 +# CONFIG_ESP32_WIFI_CSI_ENABLED is not set +CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y +CONFIG_ESP32_WIFI_TX_BA_WIN=6 +CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y +CONFIG_ESP32_WIFI_RX_BA_WIN=6 +CONFIG_ESP32_WIFI_NVS_ENABLED=y +CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 +CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 +# CONFIG_WIFI_LOG_DEFAULT_LEVEL_NONE is not set +# CONFIG_WIFI_LOG_DEFAULT_LEVEL_ERROR is not set +# CONFIG_WIFI_LOG_DEFAULT_LEVEL_WARN is not set +CONFIG_WIFI_LOG_DEFAULT_LEVEL_INFO=y +# CONFIG_WIFI_LOG_DEFAULT_LEVEL_DEBUG is not set +# CONFIG_WIFI_LOG_DEFAULT_LEVEL_VERBOSE is not set +CONFIG_ESP32_WIFI_IRAM_OPT=y +CONFIG_ESP32_WIFI_RX_IRAM_OPT=y +CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y +# CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set +# CONFIG_ESP_WIFI_FTM_ENABLE is not set +# CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE is not set +# end of Wi-Fi + +# +# PHY +# +CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y +# CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set +CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=20 +CONFIG_ESP_PHY_MAX_TX_POWER=20 +# end of PHY + +# +# Core dump +# +# CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH is not set +# CONFIG_ESP_COREDUMP_ENABLE_TO_UART is not set +CONFIG_ESP_COREDUMP_ENABLE_TO_NONE=y +# end of Core dump + +# +# FAT Filesystem support +# +# CONFIG_FATFS_CODEPAGE_DYNAMIC is not set +CONFIG_FATFS_CODEPAGE_437=y +# CONFIG_FATFS_CODEPAGE_720 is not set +# CONFIG_FATFS_CODEPAGE_737 is not set +# CONFIG_FATFS_CODEPAGE_771 is not set +# CONFIG_FATFS_CODEPAGE_775 is not set +# CONFIG_FATFS_CODEPAGE_850 is not set +# CONFIG_FATFS_CODEPAGE_852 is not set +# CONFIG_FATFS_CODEPAGE_855 is not set +# CONFIG_FATFS_CODEPAGE_857 is not set +# CONFIG_FATFS_CODEPAGE_860 is not set +# CONFIG_FATFS_CODEPAGE_861 is not set +# CONFIG_FATFS_CODEPAGE_862 is not set +# CONFIG_FATFS_CODEPAGE_863 is not set +# CONFIG_FATFS_CODEPAGE_864 is not set +# CONFIG_FATFS_CODEPAGE_865 is not set +# CONFIG_FATFS_CODEPAGE_866 is not set +# CONFIG_FATFS_CODEPAGE_869 is not set +# CONFIG_FATFS_CODEPAGE_932 is not set +# CONFIG_FATFS_CODEPAGE_936 is not set +# CONFIG_FATFS_CODEPAGE_949 is not set +# CONFIG_FATFS_CODEPAGE_950 is not set +CONFIG_FATFS_CODEPAGE=437 +# CONFIG_FATFS_LFN_NONE is not set +CONFIG_FATFS_LFN_HEAP=y +# CONFIG_FATFS_LFN_STACK is not set +CONFIG_FATFS_FS_LOCK=0 +CONFIG_FATFS_TIMEOUT_MS=10000 +CONFIG_FATFS_PER_FILE_CACHE=y +# CONFIG_FATFS_USE_FASTSEEK is not set +# end of FAT Filesystem support + +# +# Modbus configuration +# +CONFIG_FMB_COMM_MODE_TCP_EN=y +CONFIG_FMB_TCP_PORT_DEFAULT=502 +CONFIG_FMB_TCP_PORT_MAX_CONN=5 +CONFIG_FMB_TCP_CONNECTION_TOUT_SEC=20 +CONFIG_FMB_COMM_MODE_RTU_EN=y +CONFIG_FMB_COMM_MODE_ASCII_EN=y +CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND=150 +CONFIG_FMB_MASTER_DELAY_MS_CONVERT=200 +CONFIG_FMB_QUEUE_LENGTH=20 +CONFIG_FMB_PORT_TASK_STACK_SIZE=4096 +CONFIG_FMB_SERIAL_BUF_SIZE=256 +CONFIG_FMB_SERIAL_ASCII_BITS_PER_SYMB=8 +CONFIG_FMB_SERIAL_ASCII_TIMEOUT_RESPOND_MS=1000 +CONFIG_FMB_PORT_TASK_PRIO=10 +CONFIG_FMB_CONTROLLER_SLAVE_ID_SUPPORT=y +CONFIG_FMB_CONTROLLER_SLAVE_ID=0x00112233 +CONFIG_FMB_CONTROLLER_NOTIFY_TIMEOUT=20 +CONFIG_FMB_CONTROLLER_NOTIFY_QUEUE_SIZE=20 +CONFIG_FMB_CONTROLLER_STACK_SIZE=4096 +CONFIG_FMB_EVENT_QUEUE_TIMEOUT=20 +CONFIG_FMB_TIMER_PORT_ENABLED=y +CONFIG_FMB_TIMER_GROUP=0 +CONFIG_FMB_TIMER_INDEX=0 +# CONFIG_FMB_TIMER_ISR_IN_IRAM is not set +# end of Modbus configuration + +# +# FreeRTOS +# +# CONFIG_FREERTOS_UNICORE is not set +CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF +CONFIG_FREERTOS_CORETIMER_0=y +# CONFIG_FREERTOS_CORETIMER_1 is not set +CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y +CONFIG_FREERTOS_HZ=100 +CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION=y +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set +CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y +# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set +CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_ASSERT_FAIL_ABORT=y +# CONFIG_FREERTOS_ASSERT_FAIL_PRINT_CONTINUE is not set +# CONFIG_FREERTOS_ASSERT_DISABLE is not set +CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=2304 +CONFIG_FREERTOS_ISR_STACKSIZE=1536 +# CONFIG_FREERTOS_LEGACY_HOOKS is not set +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 +CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y +# CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=5 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_USE_TICKLESS_IDLE=y +# CONFIG_FREERTOS_USE_TRACE_FACILITY is not set +# CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set +CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER=y +CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y +# CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set +# CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set +CONFIG_FREERTOS_DEBUG_OCDAWARE=y +# end of FreeRTOS + +# +# Heap memory debugging +# +CONFIG_HEAP_POISONING_DISABLED=y +# CONFIG_HEAP_POISONING_LIGHT is not set +# CONFIG_HEAP_POISONING_COMPREHENSIVE is not set +CONFIG_HEAP_TRACING_OFF=y +# CONFIG_HEAP_TRACING_STANDALONE is not set +# CONFIG_HEAP_TRACING_TOHOST is not set +# CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS is not set +# end of Heap memory debugging + +# +# jsmn +# +# CONFIG_JSMN_PARENT_LINKS is not set +# CONFIG_JSMN_STRICT is not set +# end of jsmn + +# +# libsodium +# +# end of libsodium + +# +# Log output +# +CONFIG_LOG_DEFAULT_LEVEL_NONE=y +# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set +# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set +# CONFIG_LOG_DEFAULT_LEVEL_INFO is not set +# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set +# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set +CONFIG_LOG_DEFAULT_LEVEL=0 +# CONFIG_LOG_MAXIMUM_EQUALS_DEFAULT is not set +# CONFIG_LOG_MAXIMUM_LEVEL_ERROR is not set +# CONFIG_LOG_MAXIMUM_LEVEL_WARN is not set +CONFIG_LOG_MAXIMUM_LEVEL_INFO=y +# CONFIG_LOG_MAXIMUM_LEVEL_DEBUG is not set +# CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE is not set +CONFIG_LOG_MAXIMUM_LEVEL=3 +CONFIG_LOG_COLORS=y +CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y +# CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set +# end of Log output + +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="nanodevice" +CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y +# CONFIG_LWIP_L2_TO_L3_COPY is not set +# CONFIG_LWIP_IRAM_OPTIMIZATION is not set +CONFIG_LWIP_TIMERS_ONDEMAND=y +CONFIG_LWIP_MAX_SOCKETS=16 +# CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set +CONFIG_LWIP_SO_LINGER=y +CONFIG_LWIP_SO_REUSE=y +CONFIG_LWIP_SO_REUSE_RXTOALL=y +CONFIG_LWIP_SO_RCVBUF=y +# CONFIG_LWIP_NETBUF_RECVINFO is not set +CONFIG_LWIP_IP4_FRAG=y +CONFIG_LWIP_IP6_FRAG=y +# CONFIG_LWIP_IP4_REASSEMBLY is not set +# CONFIG_LWIP_IP6_REASSEMBLY is not set +# CONFIG_LWIP_IP_FORWARD is not set +# CONFIG_LWIP_STATS is not set +# CONFIG_LWIP_ETHARP_TRUST_IP_MAC is not set +CONFIG_LWIP_ESP_GRATUITOUS_ARP=y +CONFIG_LWIP_GARP_TMR_INTERVAL=60 +CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 +CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y +# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set +# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set +CONFIG_LWIP_DHCP_OPTIONS_LEN=80 + +# +# DHCP server +# +# CONFIG_LWIP_DHCPS is not set +CONFIG_LWIP_DHCPS_LEASE_UNIT=60 +CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8 +# end of DHCP server + +# CONFIG_LWIP_AUTOIP is not set +# CONFIG_LWIP_IPV6 is not set +# CONFIG_LWIP_IPV6_AUTOCONFIG is not set +CONFIG_LWIP_NETIF_LOOPBACK=y +CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 + +# +# TCP +# +CONFIG_LWIP_MAX_ACTIVE_TCP=16 +CONFIG_LWIP_MAX_LISTENING_TCP=8 +CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y +CONFIG_LWIP_TCP_MAXRTX=12 +CONFIG_LWIP_TCP_SYNMAXRTX=12 +CONFIG_LWIP_TCP_MSS=1440 +CONFIG_LWIP_TCP_TMR_INTERVAL=250 +CONFIG_LWIP_TCP_MSL=60000 +CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 +CONFIG_LWIP_TCP_WND_DEFAULT=5744 +CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 +CONFIG_LWIP_TCP_QUEUE_OOSEQ=y +# CONFIG_LWIP_TCP_SACK_OUT is not set +# CONFIG_LWIP_TCP_KEEP_CONNECTION_WHEN_IP_CHANGES is not set +CONFIG_LWIP_TCP_OVERSIZE_MSS=y +# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set +CONFIG_LWIP_TCP_RTO_TIME=1500 +# end of TCP + +# +# UDP +# +CONFIG_LWIP_MAX_UDP_PCBS=16 +CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 +# end of UDP + +# +# Checksums +# +# CONFIG_LWIP_CHECKSUM_CHECK_IP is not set +# CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set +CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y +# end of Checksums + +CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y +# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set +CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF +# CONFIG_LWIP_PPP_SUPPORT is not set +CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 +CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 +# CONFIG_LWIP_SLIP_SUPPORT is not set + +# +# ICMP +# +CONFIG_LWIP_ICMP=y +# CONFIG_LWIP_MULTICAST_PING is not set +# CONFIG_LWIP_BROADCAST_PING is not set +# end of ICMP + +# +# LWIP RAW API +# +CONFIG_LWIP_MAX_RAW_PCBS=16 +# end of LWIP RAW API + +# +# SNTP +# +CONFIG_LWIP_DHCP_MAX_NTP_SERVERS=1 +CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 +# end of SNTP + +CONFIG_LWIP_ESP_LWIP_ASSERT=y + +# +# Hooks +# +# CONFIG_LWIP_HOOK_TCP_ISN_NONE is not set +CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT=y +# CONFIG_LWIP_HOOK_TCP_ISN_CUSTOM is not set +CONFIG_LWIP_HOOK_IP6_ROUTE_NONE=y +# CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT is not set +# CONFIG_LWIP_HOOK_IP6_ROUTE_CUSTOM is not set +CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_NONE=y +# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT is not set +# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_CUSTOM is not set +# end of Hooks + +# CONFIG_LWIP_DEBUG is not set +# end of LWIP + +# +# mbedTLS +# +# CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC is not set +CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC=y +# CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set +CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y +CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384 +CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 +CONFIG_MBEDTLS_DYNAMIC_BUFFER=y +# CONFIG_MBEDTLS_DEBUG=y +CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH=y +CONFIG_MBEDTLS_DYNAMIC_FREE_PEER_CERT=y +# CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE is not set + +# +# Certificate Bundle +# +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE is not set +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL is not set +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=n +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE=y +# CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set +# end of Certificate Bundle + +# CONFIG_MBEDTLS_ECP_RESTARTABLE is not set +CONFIG_MBEDTLS_CMAC_C=y +CONFIG_MBEDTLS_HARDWARE_AES=y +CONFIG_MBEDTLS_AES_USE_INTERRUPT=y +CONFIG_MBEDTLS_HARDWARE_GCM=y +CONFIG_MBEDTLS_HARDWARE_MPI=y +CONFIG_MBEDTLS_HARDWARE_SHA=y +CONFIG_MBEDTLS_ROM_MD5=y +# CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN is not set +# CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY is not set +CONFIG_MBEDTLS_HAVE_TIME=y +CONFIG_MBEDTLS_HAVE_TIME_DATE=y +CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y +CONFIG_MBEDTLS_SHA512_C=y +CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y +# CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set +# CONFIG_MBEDTLS_TLS_CLIENT_ONLY is not set +# CONFIG_MBEDTLS_TLS_DISABLED is not set +CONFIG_MBEDTLS_TLS_SERVER=y +CONFIG_MBEDTLS_TLS_CLIENT=y +CONFIG_MBEDTLS_TLS_ENABLED=y + +# +# TLS Key Exchange Methods +# +# CONFIG_MBEDTLS_PSK_MODES is not set +CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y +# end of TLS Key Exchange Methods + +CONFIG_MBEDTLS_SSL_RENEGOTIATION=y +# CONFIG_MBEDTLS_SSL_PROTO_SSL3 is not set +CONFIG_MBEDTLS_SSL_PROTO_TLS1=y +CONFIG_MBEDTLS_SSL_PROTO_TLS1_1=y +CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y +# CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set +CONFIG_MBEDTLS_SSL_ALPN=y +# CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS is not set +CONFIG_MBEDTLS_X509_CHECK_KEY_USAGE=y +CONFIG_MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE=y +CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y + +# +# Symmetric Ciphers +# +CONFIG_MBEDTLS_AES_C=y +# CONFIG_MBEDTLS_CAMELLIA_C is not set +CONFIG_MBEDTLS_DES_C=y +CONFIG_MBEDTLS_RC4_DISABLED=y +# CONFIG_MBEDTLS_RC4_ENABLED_NO_DEFAULT is not set +# CONFIG_MBEDTLS_RC4_ENABLED is not set +# CONFIG_MBEDTLS_BLOWFISH_C is not set +CONFIG_MBEDTLS_XTEA_C=y +CONFIG_MBEDTLS_CCM_C=y +CONFIG_MBEDTLS_GCM_C=y +# CONFIG_MBEDTLS_NIST_KW_C is not set +# end of Symmetric Ciphers + +# CONFIG_MBEDTLS_RIPEMD160_C=y + +# +# Certificates +# +CONFIG_MBEDTLS_PEM_PARSE_C=y +# CONFIG_MBEDTLS_PEM_WRITE_C is not set +CONFIG_MBEDTLS_X509_CRL_PARSE_C=y +CONFIG_MBEDTLS_X509_CSR_PARSE_C=y +# end of Certificates + +CONFIG_MBEDTLS_ECP_C=y +CONFIG_MBEDTLS_ECDH_C=y +CONFIG_MBEDTLS_ECDSA_C=y +# CONFIG_MBEDTLS_ECJPAKE_C is not set +CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y +CONFIG_MBEDTLS_ECP_NIST_OPTIM=y +# CONFIG_MBEDTLS_POLY1305_C is not set +# CONFIG_MBEDTLS_CHACHA20_C is not set +# CONFIG_MBEDTLS_HKDF_C is not set +# CONFIG_MBEDTLS_THREADING_C is not set +# CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI is not set +# CONFIG_MBEDTLS_SECURITY_RISKS is not set +# end of mbedTLS + +# +# mDNS +# +CONFIG_MDNS_MAX_SERVICES=10 +CONFIG_MDNS_TASK_PRIORITY=1 +CONFIG_MDNS_TASK_STACK_SIZE=4096 +# CONFIG_MDNS_TASK_AFFINITY_NO_AFFINITY is not set +CONFIG_MDNS_TASK_AFFINITY_CPU0=y +CONFIG_MDNS_TASK_AFFINITY=0x0 +CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS=2000 +# CONFIG_MDNS_STRICT_MODE is not set +CONFIG_MDNS_TIMER_PERIOD_MS=100 +# end of mDNS + +# +# ESP-MQTT Configurations +# +CONFIG_MQTT_PROTOCOL_311=y +CONFIG_MQTT_TRANSPORT_SSL=y +CONFIG_MQTT_TRANSPORT_WEBSOCKET=y +CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE=y +# CONFIG_MQTT_MSG_ID_INCREMENTAL is not set +# CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set +# CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set +# CONFIG_MQTT_USE_CUSTOM_CONFIG is not set +# CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set +# CONFIG_MQTT_CUSTOM_OUTBOX is not set +# end of ESP-MQTT Configurations + +# +# Newlib +# +CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF is not set +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set +CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y +# CONFIG_NEWLIB_NANO_FORMAT is not set +# end of Newlib + +# +# NVS +# +# end of NVS + +# +# OpenSSL +# +# CONFIG_OPENSSL_DEBUG is not set +CONFIG_OPENSSL_ERROR_STACK=y +# CONFIG_OPENSSL_ASSERT_DO_NOTHING is not set +CONFIG_OPENSSL_ASSERT_EXIT=y +# end of OpenSSL + +# +# PThreads +# +CONFIG_PTHREAD_TASK_PRIO_DEFAULT=5 +CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 +CONFIG_PTHREAD_STACK_MIN=768 +CONFIG_PTHREAD_TASK_CORE_DEFAULT=-1 +CONFIG_PTHREAD_TASK_NAME_DEFAULT="pthread" +# end of PThreads + +# +# SPI Flash driver +# +# CONFIG_SPI_FLASH_VERIFY_WRITE is not set +# CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set +CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y +CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS=y +# CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS is not set +# CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED is not set +# CONFIG_SPI_FLASH_USE_LEGACY_IMPL is not set +# CONFIG_SPI_FLASH_BYPASS_BLOCK_ERASE is not set +CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y +CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS=20 +CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1 +CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE=8192 +# CONFIG_SPI_FLASH_SIZE_OVERRIDE is not set +# CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED is not set + +# +# Auto-detect flash chips +# +CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP=y +# end of Auto-detect flash chips + +CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE=y +# end of SPI Flash driver + +# +# SPIFFS Configuration +# +CONFIG_SPIFFS_MAX_PARTITIONS=3 + +# +# SPIFFS Cache Configuration +# +CONFIG_SPIFFS_CACHE=y +CONFIG_SPIFFS_CACHE_WR=y +# CONFIG_SPIFFS_CACHE_STATS is not set +# end of SPIFFS Cache Configuration + +CONFIG_SPIFFS_PAGE_CHECK=y +CONFIG_SPIFFS_GC_MAX_RUNS=10 +# CONFIG_SPIFFS_GC_STATS is not set +CONFIG_SPIFFS_PAGE_SIZE=512 +CONFIG_SPIFFS_OBJ_NAME_LEN=256 +# CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set +CONFIG_SPIFFS_USE_MAGIC=y +CONFIG_SPIFFS_USE_MAGIC_LENGTH=y +CONFIG_SPIFFS_META_LENGTH=4 +CONFIG_SPIFFS_USE_MTIME=y + +# +# Debug Configuration +# +# CONFIG_SPIFFS_DBG is not set +# CONFIG_SPIFFS_API_DBG is not set +# CONFIG_SPIFFS_GC_DBG is not set +# CONFIG_SPIFFS_CACHE_DBG is not set +# CONFIG_SPIFFS_CHECK_DBG is not set +# CONFIG_SPIFFS_TEST_VISUALISATION is not set +# end of Debug Configuration +# end of SPIFFS Configuration + +# +# TCP Transport +# + +# +# Websocket +# +CONFIG_WS_TRANSPORT=y +CONFIG_WS_BUFFER_SIZE=1024 +# end of Websocket +# end of TCP Transport + +# +# Unity unit testing library +# +CONFIG_UNITY_ENABLE_FLOAT=y +CONFIG_UNITY_ENABLE_DOUBLE=y +# CONFIG_UNITY_ENABLE_COLOR is not set +CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y +# CONFIG_UNITY_ENABLE_FIXTURE is not set +# CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set +# end of Unity unit testing library + +# +# Virtual file system +# +CONFIG_VFS_SUPPORT_IO=y +CONFIG_VFS_SUPPORT_DIR=y +CONFIG_VFS_SUPPORT_SELECT=y +CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y +CONFIG_VFS_SUPPORT_TERMIOS=y + +# +# Host File System I/O (Semihosting) +# +CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS=1 +CONFIG_VFS_SEMIHOSTFS_HOST_PATH_MAX_LEN=128 +# end of Host File System I/O (Semihosting) +# end of Virtual file system + +# +# Wear Levelling +# +# CONFIG_WL_SECTOR_SIZE_512 is not set +CONFIG_WL_SECTOR_SIZE_4096=y +CONFIG_WL_SECTOR_SIZE=4096 +# end of Wear Levelling + +# +# Wi-Fi Provisioning Manager +# +CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 +CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 +# end of Wi-Fi Provisioning Manager + +# +# Supplicant +# +CONFIG_WPA_MBEDTLS_CRYPTO=y +# CONFIG_WPA_WAPI_PSK is not set +# CONFIG_WPA_DEBUG_PRINT is not set +# CONFIG_WPA_TESTING_OPTIONS is not set +# CONFIG_WPA_WPS_STRICT is not set +# CONFIG_WPA_11KV_SUPPORT is not set +# end of Supplicant +# end of Component config diff --git a/targets/ESP32/_Network/NF_ESP32_Ethernet.cpp b/targets/ESP32/_Network/NF_ESP32_Ethernet.cpp index e7e8bc7b3a..3985697d53 100644 --- a/targets/ESP32/_Network/NF_ESP32_Ethernet.cpp +++ b/targets/ESP32/_Network/NF_ESP32_Ethernet.cpp @@ -55,6 +55,7 @@ esp_err_t NF_ESP32_InitialiseEthernet(uint8_t *pMacAdr) #ifdef ETH_PHY_RST_GPIO phy_config.reset_gpio_num = ETH_PHY_RST_GPIO; + CPU_GPIO_ReservePin(ETH_PHY_RST_GPIO, true); // Reset_N #else phy_config.reset_gpio_num = -1; #endif @@ -76,10 +77,16 @@ esp_err_t NF_ESP32_InitialiseEthernet(uint8_t *pMacAdr) mac_config.clock_config.rmii.clock_mode = EMAC_CLK_OUT; mac_config.clock_config.rmii.clock_gpio = (emac_rmii_clock_gpio_t)ETH_RMII_CLK_OUT_GPIO; // always 16 or 17 ESP_LOGI(TAG, "Ethernet clock_config OUT gpio %d\n", ETH_RMII_CLK_OUT_GPIO); + + CPU_GPIO_ReservePin(EMAC_CLK_OUT, true); // REF_CLK OUT + CPU_GPIO_ReservePin(ETH_RMII_CLK_OUT_GPIO, true); // REF_CLK OUT #else mac_config.clock_config.rmii.clock_mode = EMAC_CLK_EXT_IN; mac_config.clock_config.rmii.clock_gpio = EMAC_CLK_IN_GPIO; // always 0 ESP_LOGI(TAG, "Ethernet clock_config IN gpio 0\n"); + + CPU_GPIO_ReservePin(EMAC_CLK_EXT_IN, true); // REF_CLK EXT + CPU_GPIO_ReservePin(EMAC_CLK_IN_GPIO, true); // REF_CLK IN #endif mac_config.smi_mdc_gpio_num = ETH_MDC_GPIO; @@ -88,6 +95,16 @@ esp_err_t NF_ESP32_InitialiseEthernet(uint8_t *pMacAdr) ESP_LOGI(TAG, "Ethernet mdio %d mdc %d\n", ETH_MDIO_GPIO, ETH_MDC_GPIO); + // Reserve all pins used by ethernet interface + CPU_GPIO_ReservePin(ETH_MDIO_GPIO, true); // MDIO (18) + CPU_GPIO_ReservePin(19, true); // TXD0 + CPU_GPIO_ReservePin(21, true); // TX_EN + CPU_GPIO_ReservePin(22, true); // TXD1 + CPU_GPIO_ReservePin(ETH_MDC_GPIO, true); // MDC (23) + CPU_GPIO_ReservePin(25, true); // RXD0 + CPU_GPIO_ReservePin(26, true); // RXD1 + CPU_GPIO_ReservePin(27, true); // CRS_DV + // Define PHY to use with internal Ethernet #ifdef ESP32_ETHERNET_PHY_IP101 ESP_LOGI(TAG, "Ethernet IP101 phy\n"); diff --git a/targets/ESP32/_common/CMakeLists.txt b/targets/ESP32/_common/CMakeLists.txt index 4a272be448..d1acee08a8 100644 --- a/targets/ESP32/_common/CMakeLists.txt +++ b/targets/ESP32/_common/CMakeLists.txt @@ -11,6 +11,7 @@ list(APPEND TARGET_ESP32_IDF_COMMON_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/platform list(APPEND TARGET_ESP32_IDF_COMMON_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/Target_BlockStorage_ESP32FlashDriver.c) list(APPEND TARGET_ESP32_IDF_COMMON_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/targetHAL.c) list(APPEND TARGET_ESP32_IDF_COMMON_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/targetHAL_Time.cpp) +list(APPEND TARGET_ESP32_IDF_COMMON_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/targetHAL_Rtos.c) list(APPEND TARGET_ESP32_IDF_COMMON_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/WireProtocol_HAL_Interface.c) list(APPEND TARGET_ESP32_IDF_COMMON_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/WireProtocol_ReceiverThread.c) diff --git a/targets/ESP32/_common/DeviceMapping_common.cpp b/targets/ESP32/_common/DeviceMapping_common.cpp index 0230f0ad6f..43c035604c 100644 --- a/targets/ESP32/_common/DeviceMapping_common.cpp +++ b/targets/ESP32/_common/DeviceMapping_common.cpp @@ -49,7 +49,7 @@ int Esp32_GetMappedDevicePins(Esp32_MapDeviceType deviceType, int busIndex, int case DEV_TYPE_ADC: return (int)Esp32_ADC_DevicePinMap[pinIndex]; -#if !defined(CONFIG_IDF_TARGET_ESP32C3) +#if !(defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3)) case DEV_TYPE_DAC: return (int)Esp32_DAC_DevicePinMap[pinIndex]; #endif @@ -90,7 +90,7 @@ void Esp32_SetMappedDevicePins(Esp32_MapDeviceType deviceType, int busIndex, int Esp32_ADC_DevicePinMap[pinIndex] = ioPinNumber; break; -#if !defined(CONFIG_IDF_TARGET_ESP32C3) +#if !(defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3)) case DEV_TYPE_DAC: Esp32_DAC_DevicePinMap[pinIndex] = ioPinNumber; break; diff --git a/targets/ESP32/_common/ESP32_S3_DeviceMapping.cpp b/targets/ESP32/_common/ESP32_S3_DeviceMapping.cpp new file mode 100644 index 0000000000..b352b7c43e --- /dev/null +++ b/targets/ESP32/_common/ESP32_S3_DeviceMapping.cpp @@ -0,0 +1,71 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include +#include +#include + +// SPI +// 2 devices +// Map pins mosi, miso, clock +// +int8_t Esp32_SPI_DevicePinMap[MAX_SPI_DEVICES][Esp32SpiPin_Max] = {{-1, -1, -1}, {-1, -1, -1}}; + +// Serial +// 2 devices COM1,COM2 ( UART_NUM_0, UART_NUM_1 ) +// Map pins Tx, RX, RTS, CTS +// Set pins to default for UART_NUM_0 +// others assign as NONE because the default pins can be shared with serial flash and PSRAM +int8_t Esp32_SERIAL_DevicePinMap[UART_NUM_MAX][Esp32SerialPin_Max] = { + // COM 1 - pins 21, 20 + {UART_NUM_0_TXD_DIRECT_GPIO_NUM, + UART_NUM_0_RXD_DIRECT_GPIO_NUM, + UART_NUM_0_RTS_DIRECT_GPIO_NUM, + UART_NUM_0_CTS_DIRECT_GPIO_NUM}, + +#if defined(UART_NUM_2) + // COM 2 - all set to UART_PIN_NO_CHANGE + {UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE}, +#endif +}; + +// ============================================= +// I2C +// 2 devices I2C1 +int8_t Esp32_I2C_DevicePinMap[I2C_NUM_MAX][2] = {{-1, -1}, {-1, -1}}; + +// ============================================= +// LED PWM +// 16 channels LED1 to LED16 or PWM1 to PWM16 +// Map pins Data & Clock +int8_t Esp32_LED_DevicePinMap[8] = { + // Channels ( non assigned ) + -1, // 1 + -1, // 2 + -1, // 3 + -1, // 4 + -1, // 5 + -1, // 6 + -1, // 7 + -1, // 8 +}; + +// Mapped to ESP32 controllers +// ESP32 ADC1 channels 0 - 9 +// ADC2 channels 10 - 19 +int8_t Esp32_ADC_DevicePinMap[20] = { + ADC1_CHANNEL_0_GPIO_NUM, ADC1_CHANNEL_1_GPIO_NUM, ADC1_CHANNEL_2_GPIO_NUM, ADC1_CHANNEL_3_GPIO_NUM, + ADC1_CHANNEL_4_GPIO_NUM, ADC1_CHANNEL_5_GPIO_NUM, ADC1_CHANNEL_6_GPIO_NUM, ADC1_CHANNEL_7_GPIO_NUM, + ADC1_CHANNEL_8_GPIO_NUM, ADC1_CHANNEL_9_GPIO_NUM, ADC2_CHANNEL_0_GPIO_NUM, ADC2_CHANNEL_1_GPIO_NUM, + ADC2_CHANNEL_2_GPIO_NUM, ADC2_CHANNEL_3_GPIO_NUM, ADC2_CHANNEL_4_GPIO_NUM, ADC2_CHANNEL_5_GPIO_NUM, + ADC2_CHANNEL_6_GPIO_NUM, ADC2_CHANNEL_7_GPIO_NUM, ADC2_CHANNEL_8_GPIO_NUM, ADC2_CHANNEL_9_GPIO_NUM}; + +// I2S +// 2 device I2S1 +// Map pins various pins. If not used, I2S_PIN_NO_CHANGE is used +// No pin pre configured +int8_t Esp32_I2S_DevicePinMap[I2S_NUM_MAX][5] = { + {I2S_PIN_NO_CHANGE, I2S_PIN_NO_CHANGE, I2S_PIN_NO_CHANGE, I2S_PIN_NO_CHANGE, I2S_PIN_NO_CHANGE}, + {I2S_PIN_NO_CHANGE, I2S_PIN_NO_CHANGE, I2S_PIN_NO_CHANGE, I2S_PIN_NO_CHANGE, I2S_PIN_NO_CHANGE}}; diff --git a/targets/ESP32/_common/Target_Windows_Storage.c b/targets/ESP32/_common/Target_Windows_Storage.c index b2224850f4..1a275260a2 100644 --- a/targets/ESP32/_common/Target_Windows_Storage.c +++ b/targets/ESP32/_common/Target_Windows_Storage.c @@ -155,7 +155,11 @@ bool Storage_MountSpi(int spiBus, uint32_t csPin, int driveIndex) ESP_LOGI(TAG, "Initializing SPI SD card"); sdmmc_host_t host = SDSPI_HOST_DEFAULT(); +#if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3) + host.slot = spiBus; +#else host.slot = spiBus + HSPI_HOST; +#endif esp_vfs_fat_sdmmc_mount_config_t mount_config = { .format_if_mount_failed = false, diff --git a/targets/ESP32/_common/WireProtocol_HAL_Interface.c b/targets/ESP32/_common/WireProtocol_HAL_Interface.c index 26ffad51ba..6a008baf73 100644 --- a/targets/ESP32/_common/WireProtocol_HAL_Interface.c +++ b/targets/ESP32/_common/WireProtocol_HAL_Interface.c @@ -2,6 +2,7 @@ // Copyright (c) .NET Foundation and Contributors // See LICENSE file in the project root for full license information. // +#include #include #include @@ -17,8 +18,6 @@ #define TARGET_SERIAL_BAUDRATE 921600 #endif -static bool WP_Port_Intitialised = false; - #ifdef CONFIG_IDF_TARGET_ESP32 // WP uses UART0 @@ -52,10 +51,17 @@ static uart_port_t ESP32_WP_UART = UART_NUM_0; #elif CONFIG_IDF_TARGET_ESP32S3 -#error "NOT IMPLEMENTED (YET)" +static uart_port_t ESP32_WP_UART = UART_NUM_0; -#elif CONFIG_IDF_TARGET_ESP32C3 +// UART pins for ESP32-S3 +// U0RXD GPIO44 +// U0TXD GPIO43 +// U1RXD GPIO24 +// U1TXD GPIO23 +#define ESP32_WP_RX_PIN UART_NUM_0_RXD_DIRECT_GPIO_NUM +#define ESP32_WP_TX_PIN UART_NUM_0_TXD_DIRECT_GPIO_NUM +#elif CONFIG_IDF_TARGET_ESP32C3 // WP uses UART0 static uart_port_t ESP32_WP_UART = UART_NUM_0; @@ -69,22 +75,140 @@ static uart_port_t ESP32_WP_UART = UART_NUM_0; #endif -#if CONFIG_USB_CDC_ENABLED +#if CONFIG_IDF_TARGET_ESP32C3 && HAL_WP_USE_USB_CDC + +#include + +static size_t UsbSerialWrite(const uint8_t *data, size_t dataSize, TickType_t xTicksToWait) +{ + ASSERT(data); + ASSERT(dataSize >= 1); + + const TickType_t startTicks = xTaskGetTickCount(); + + size_t writtenTotalSize = 0; + do + { + if (usb_serial_jtag_ll_txfifo_writable()) + { + const size_t writtenSize = usb_serial_jtag_ll_write_txfifo(data, dataSize); + usb_serial_jtag_ll_txfifo_flush(); + ASSERT(writtenSize <= dataSize); + + data += writtenSize; + dataSize -= writtenSize; + writtenTotalSize += writtenSize; + + if (dataSize <= 0) + { + break; + } + } + else + { + taskYIELD(); + } + + } while (xTaskGetTickCount() - startTicks < xTicksToWait); + + return writtenTotalSize; +} + +static size_t UsbSerialRead(uint8_t *data, size_t dataSize, TickType_t xTicksToWait) +{ + ASSERT(data); + ASSERT(dataSize >= 1); -extern TaskHandle_t ReceiverTask; + const TickType_t startTicks = xTaskGetTickCount(); + + size_t readTotalSize = 0; + do + { + if (usb_serial_jtag_ll_rxfifo_data_available()) + { + const size_t readSize = usb_serial_jtag_ll_read_rxfifo(data, dataSize); + ASSERT(readSize <= dataSize); + + data += readSize; + dataSize -= readSize; + readTotalSize += readSize; + + if (dataSize <= 0) + { + break; + } + } + else + { + taskYIELD(); + } -void WP_Cdc_Rx_Callback(int itf, cdcacm_event_t *event) + } while (xTaskGetTickCount() - startTicks < xTicksToWait); + + return readTotalSize; +} + +void WP_ReceiveBytes(uint8_t **ptr, uint32_t *size) +{ + (void)ESP32_WP_UART; + + ASSERT(size); + ASSERT(ptr); + ASSERT(*ptr); + + if (*size == 0) + { + return; + } + + const size_t read = UsbSerialRead(*ptr, *size, pdMS_TO_TICKS(250)); + ASSERT(read <= *size); + + *ptr += read; + *size -= read; +} + +uint8_t WP_TransmitMessage(WP_Message *message) +{ + (void)ESP32_WP_UART; + + ASSERT(message); + + if (UsbSerialWrite((const uint8_t *)&message->m_header, sizeof(message->m_header), pdMS_TO_TICKS(250)) != + sizeof(message->m_header)) + { + return false; + } + + if (message->m_header.m_size && message->m_payload) + { + if (UsbSerialWrite(message->m_payload, message->m_header.m_size, pdMS_TO_TICKS(250)) != + message->m_header.m_size) + { + return false; + } + } + + return true; +} + +#elif (CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3) && CONFIG_USB_CDC_ENABLED + +static bool WP_Port_Intitialised = false; + +static void WP_Cdc_Rx_Callback(int itf, cdcacm_event_t *event) { BaseType_t shouldWakeHigherPriorityTask = pdFALSE; // signal data received + extern TaskHandle_t ReceiverTask; vTaskNotifyGiveFromISR(ReceiverTask, &shouldWakeHigherPriorityTask); portYIELD_FROM_ISR(shouldWakeHigherPriorityTask); } // WP using embedded USB CDC -bool WP_Initialise(COM_HANDLE port) +static bool WP_Initialise(COM_HANDLE port) { (void)port; @@ -109,10 +233,68 @@ bool WP_Initialise(COM_HANDLE port) return true; } +void WP_ReceiveBytes(uint8_t **ptr, uint32_t *size) +{ + // TODO: Initialise Port if not already done, Wire Protocol should be calling this directly at startup + if (!WP_Port_Intitialised) + { + WP_Initialise(ESP32_WP_UART); + } + + // save for later comparison + uint32_t requestedSize = *size; + + // check for request with 0 size + if (*size) + { + // reset read count + size_t read = 0; + + // wait to try reading from CDC buffer + ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(100)); + + tinyusb_cdcacm_read(TINYUSB_CDC_ACM_0, *ptr, requestedSize, &read); + + *ptr += read; + *size -= read; + } +} + +uint8_t WP_TransmitMessage(WP_Message *message) +{ + if (!WP_Port_Intitialised) + { + WP_Initialise(ESP32_WP_UART); + } + + // write header to output stream + if (tinyusb_cdcacm_write_queue(TINYUSB_CDC_ACM_0, (uint8_t *)&message->m_header, sizeof(message->m_header)) != + sizeof(message->m_header)) + { + return false; + } + + // if there is anything on the payload send it to the output stream + if (message->m_header.m_size && message->m_payload) + { + if (tinyusb_cdcacm_write_queue(TINYUSB_CDC_ACM_0, (uint8_t *)message->m_payload, message->m_header.m_size) != + message->m_header.m_size) + { + return false; + } + } + + tinyusb_cdcacm_write_flush(TINYUSB_CDC_ACM_0, 0); + + return true; +} + #else +static bool WP_Port_Intitialised = false; + // WP using UART -bool WP_Initialise(COM_HANDLE port) +static bool WP_Initialise(COM_HANDLE port) { (void)port; @@ -145,8 +327,6 @@ bool WP_Initialise(COM_HANDLE port) return true; } -#endif // CONFIG_USB_CDC_ENABLED - void WP_ReceiveBytes(uint8_t **ptr, uint32_t *size) { // TODO: Initialise Port if not already done, Wire Protocol should be calling this directly at startup @@ -161,21 +341,8 @@ void WP_ReceiveBytes(uint8_t **ptr, uint32_t *size) // check for request with 0 size if (*size) { - -#if CONFIG_USB_CDC_ENABLED - - // reset read count - size_t read = 0; - - // wait to try reading from CDC buffer - ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(100)); - - tinyusb_cdcacm_read(TINYUSB_CDC_ACM_0, *ptr, requestedSize, &read); - -#else // non blocking read from serial port with 100ms timeout size_t read = uart_read_bytes(ESP32_WP_UART, *ptr, (uint32_t)requestedSize, pdMS_TO_TICKS(250)); -#endif *ptr += read; *size -= read; @@ -189,29 +356,6 @@ uint8_t WP_TransmitMessage(WP_Message *message) WP_Initialise(ESP32_WP_UART); } -#if CONFIG_USB_CDC_ENABLED - - // write header to output stream - if (tinyusb_cdcacm_write_queue(TINYUSB_CDC_ACM_0, (uint8_t *)&message->m_header, sizeof(message->m_header)) != - sizeof(message->m_header)) - { - return false; - } - - // if there is anything on the payload send it to the output stream - if (message->m_header.m_size && message->m_payload) - { - if (tinyusb_cdcacm_write_queue(TINYUSB_CDC_ACM_0, (uint8_t *)message->m_payload, message->m_header.m_size) != - message->m_header.m_size) - { - return false; - } - } - - tinyusb_cdcacm_write_flush(TINYUSB_CDC_ACM_0, 0); - -#else - // TODO Check if timeout required // write header to output stream if (uart_write_bytes(ESP32_WP_UART, (const char *)&message->m_header, sizeof(message->m_header)) != @@ -230,7 +374,7 @@ uint8_t WP_TransmitMessage(WP_Message *message) } } -#endif - return true; } + +#endif diff --git a/targets/ESP32/_common/nanoSupport_CRC32.c b/targets/ESP32/_common/nanoSupport_CRC32.c index fcbfc6987f..0fcee339b8 100644 --- a/targets/ESP32/_common/nanoSupport_CRC32.c +++ b/targets/ESP32/_common/nanoSupport_CRC32.c @@ -22,13 +22,18 @@ uint32_t SUPPORT_ComputeCRC(const void *rgBlock, const uint32_t nLength, const u // this series has ROM support for CRC32 - // IDF CRC32 polinomial required this tweak + // IDF CRC32 polinomial requires this tweak if (crc == 0) { + // initialize CRC32 if initial value is 0 newCrc = 0xFFFFFFFF; + newCrc = ~esp_rom_crc32_be(newCrc, ptr, lenght); + } + else + { + // need to invert the CRC32 value + newCrc = ~esp_rom_crc32_be(~newCrc, ptr, lenght); } - - newCrc = ~esp_rom_crc32_be(newCrc, ptr, lenght); #else diff --git a/targets/ESP32/_common/platform_heap.c b/targets/ESP32/_common/platform_heap.c index 4d11e3922e..60aa40ab3b 100644 --- a/targets/ESP32/_common/platform_heap.c +++ b/targets/ESP32/_common/platform_heap.c @@ -18,8 +18,3 @@ void platform_free(void *ptr) { heap_caps_free(ptr); } - -void *platform_realloc(void *ptr, size_t size) -{ - return heap_caps_realloc(ptr, size, DEFAULT_MALLOC_CAPS); -} diff --git a/targets/ESP32/_common/targetHAL_ConfigurationManager.cpp b/targets/ESP32/_common/targetHAL_ConfigurationManager.cpp index 8c8a9caac9..552f5552e3 100644 --- a/targets/ESP32/_common/targetHAL_ConfigurationManager.cpp +++ b/targets/ESP32/_common/targetHAL_ConfigurationManager.cpp @@ -342,6 +342,9 @@ bool InitialiseNetworkDefaultConfig(HAL_Configuration_NetworkInterface *config, config->StartupAddressMode = AddressMode_DHCP; config->AutomaticDNS = 1; config->SpecificConfigId = 0; + + // get default MAC for interface + esp_read_mac(config->MacAddress, ESP_MAC_WIFI_STA); break; case 1: // Wireless AP @@ -352,18 +355,21 @@ bool InitialiseNetworkDefaultConfig(HAL_Configuration_NetworkInterface *config, // config->IPv4Address // config->IPv4NetMask // config->IPv4GatewayAddress + + // get default MAC for interface + esp_read_mac(config->MacAddress, ESP_MAC_WIFI_SOFTAP); break; case 2: // Ethernet config->InterfaceType = NetworkInterfaceType_Ethernet; config->StartupAddressMode = AddressMode_DHCP; config->AutomaticDNS = 1; + + // get default MAC for interface + esp_read_mac(config->MacAddress, ESP_MAC_ETH); break; } - // get default MAC - esp_efuse_mac_get_default(config->MacAddress); - // always good return TRUE; } diff --git a/targets/ESP32/_common/targetHAL_Network.cpp b/targets/ESP32/_common/targetHAL_Network.cpp index d743ac1be6..c9d1ca6408 100644 --- a/targets/ESP32/_common/targetHAL_Network.cpp +++ b/targets/ESP32/_common/targetHAL_Network.cpp @@ -15,7 +15,7 @@ extern "C" void set_signal_sock_function(void (*funcPtr)()); #define WIFI_EVENT_TYPE_SCAN_COMPLETE 1 -//#define PRINT_NET_EVENT 1 +// #define PRINT_NET_EVENT 1 // buffer with host name char hostName[18] = "nanodevice_"; @@ -34,18 +34,27 @@ __nfweak void InitialiseEthernet() { } +static void SignalSocketEvent() +{ + Events_Set(SYSTEM_EVENT_FLAG_SOCKET); + Events_Set(SYSTEM_EVENT_FLAG_NETWORK); +} + static void PostAddressChanged(uint netIndex) { + SignalSocketEvent(); Network_PostEvent(NetworkChange_NetworkEventType_AddressChanged, 0, netIndex); } static void PostAvailabilityOn(uint netIndex) { + SignalSocketEvent(); Network_PostEvent(NetworkChange_NetworkEventType_AvailabilityChanged, 1, netIndex); } static void PostAvailabilityOff(uint netIndex) { + SignalSocketEvent(); Network_PostEvent(NetworkChange_NetworkEventType_AvailabilityChanged, 0, netIndex); } @@ -56,6 +65,7 @@ static void PostScanComplete(uint netIndex) static void PostAPStationChanged(uint connect, uint netInfo) { + SignalSocketEvent(); Network_PostEvent(NetworkChange_NetworkEventType_APStationChanged, connect, netInfo); } diff --git a/targets/ESP32/_common/targetHAL_Rtos.c b/targets/ESP32/_common/targetHAL_Rtos.c new file mode 100644 index 0000000000..f5e0a8dd28 --- /dev/null +++ b/targets/ESP32/_common/targetHAL_Rtos.c @@ -0,0 +1,12 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include +#include + +void RtosYield() +{ + taskYIELD(); +} diff --git a/targets/ESP32/_common/targetHAL_Time.cpp b/targets/ESP32/_common/targetHAL_Time.cpp index e8461b18bd..35d4aa02a7 100644 --- a/targets/ESP32/_common/targetHAL_Time.cpp +++ b/targets/ESP32/_common/targetHAL_Time.cpp @@ -3,15 +3,6 @@ // See LICENSE file in the project root for full license information. // -#include -#include -#include -#include -#include - -// Converts FreeRTOS Tickcount to .NET ticks (100 nanoseconds) -uint64_t HAL_Time_SysTicksToTime(uint64_t sysTicks) -{ - return (((int64_t)sysTicks * (int64_t)1000000 + (int64_t)configTICK_RATE_HZ - 1) / (int64_t)configTICK_RATE_HZ) * - 10; -} +//////////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS BLANK ON PURPOSE HAS THERE IS NO PLATFORM IMPLEMENTATION REQUIRED // +//////////////////////////////////////////////////////////////////////////////////// diff --git a/targets/ESP32/_include/Esp32_DeviceMapping.h b/targets/ESP32/_include/Esp32_DeviceMapping.h index 0a92700063..3e89192399 100644 --- a/targets/ESP32/_include/Esp32_DeviceMapping.h +++ b/targets/ESP32/_include/Esp32_DeviceMapping.h @@ -54,13 +54,17 @@ extern int8_t Esp32_SPI_DevicePinMap[MAX_SPI_DEVICES][Esp32SpiPin_Max]; extern int8_t Esp32_I2C_DevicePinMap[I2C_NUM_MAX][2]; extern int8_t Esp32_I2S_DevicePinMap[I2S_NUM_MAX][5]; extern int8_t Esp32_SERIAL_DevicePinMap[UART_NUM_MAX][Esp32SerialPin_Max]; -extern int8_t Esp32_LED_DevicePinMap[16]; -extern int8_t Esp32_DAC_DevicePinMap[2]; #if defined(CONFIG_IDF_TARGET_ESP32C3) extern int8_t Esp32_ADC_DevicePinMap[6]; +extern int8_t Esp32_LED_DevicePinMap[16]; +#elif defined(CONFIG_IDF_TARGET_ESP32S3) +extern int8_t Esp32_ADC_DevicePinMap[20]; +extern int8_t Esp32_LED_DevicePinMap[8]; #else +extern int8_t Esp32_DAC_DevicePinMap[2]; extern int8_t Esp32_ADC_DevicePinMap[20]; +extern int8_t Esp32_LED_DevicePinMap[16]; #endif void Esp32_DecodeAlternateFunction( diff --git a/targets/ESP32/_include/esp32_idf.h b/targets/ESP32/_include/esp32_idf.h index a9b1cbc332..4f30d9d30b 100644 --- a/targets/ESP32/_include/esp32_idf.h +++ b/targets/ESP32/_include/esp32_idf.h @@ -6,8 +6,8 @@ #ifndef ESP32_IDF_H #define ESP32_IDF_H -#include -#include +#include + #include #include @@ -70,6 +70,12 @@ #include #include +// Touch pad supported only on those platforms +#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) +#include +#include +#endif + // includes specific for TinyUSB and CDC #if CONFIG_USB_CDC_ENABLED #include @@ -81,6 +87,6 @@ #endif // Uncomment to support Ethernet -//#define ESP32_ETHERNET_SUPPORT +// #define ESP32_ETHERNET_SUPPORT #endif // ESP32_IDF_H \ No newline at end of file diff --git a/targets/ESP32/_include/targetHAL.h b/targets/ESP32/_include/targetHAL.h index c7eed6663e..786c20dad2 100644 --- a/targets/ESP32/_include/targetHAL.h +++ b/targets/ESP32/_include/targetHAL.h @@ -43,6 +43,10 @@ extern portMUX_TYPE globalLockMutex; #endif // !defined(BUILD_RTM) +#ifndef HARD_BREAKPOINT +#define HARD_BREAKPOINT() +#endif // HARD_BREAKPOINT + #define NANOCLR_STOP() HARD_BREAKPOINT() ///////////////////////////////////////////////////////////////////////////////////////////////////// @@ -59,4 +63,4 @@ extern portMUX_TYPE globalLockMutex; #endif // EVENTS_HEART_BEAT #endif -#endif //TARGET_HAL_H +#endif // TARGET_HAL_H diff --git a/targets/ESP32/_include/targetHAL_Time.h b/targets/ESP32/_include/targetHAL_Time.h index f31f46818c..b9248f5c7f 100644 --- a/targets/ESP32/_include/targetHAL_Time.h +++ b/targets/ESP32/_include/targetHAL_Time.h @@ -10,6 +10,22 @@ #include #define HAL_Time_CurrentSysTicks xTaskGetTickCount -#define ESP32_TICKS_PER_MS(x) ((x * (uint64_t)configTICK_RATE_HZ) / 1000) -#endif //TARGET_HAL_TIME_H +#ifdef __cplusplus +extern "C" +{ +#endif + + // Converts FreeRTOS Tickcount to .NET ticks (100 nanoseconds) + inline __attribute__((always_inline)) uint64_t HAL_Time_SysTicksToTime(uint64_t sysTicks) + { + return sysTicks * configTICK_RATE_HZ * 1000; + } + +#ifdef __cplusplus +} +#endif + +#define ESP32_TICKS_PER_MS(x) ((x * (uint64_t)configTICK_RATE_HZ) / 1000) + +#endif // TARGET_HAL_TIME_H diff --git a/targets/ESP32/_lwIP/nf_sys_arch.c b/targets/ESP32/_lwIP/nf_sys_arch.c index 6ae5adba7b..352170a430 100644 --- a/targets/ESP32/_lwIP/nf_sys_arch.c +++ b/targets/ESP32/_lwIP/nf_sys_arch.c @@ -15,6 +15,8 @@ #include "esp_log.h" #include "esp_compiler.h" +// clang-format off + static const char* TAG = "lwip_arch"; static sys_mutex_t g_lwip_protect_mutex = NULL; @@ -53,6 +55,7 @@ void sys_mutex_lock(sys_mutex_t *pxMutex) { BaseType_t ret = xSemaphoreTake(*pxMutex, portMAX_DELAY); + (void)ret; LWIP_ASSERT("failed to take the mutex", ret == pdTRUE); } @@ -66,6 +69,7 @@ void sys_mutex_unlock(sys_mutex_t *pxMutex) { BaseType_t ret = xSemaphoreGive(*pxMutex); + (void)ret; LWIP_ASSERT("failed to give the mutex", ret == pdTRUE); } @@ -106,6 +110,8 @@ sys_sem_new(sys_sem_t *sem, u8_t count) if (count == 1) { BaseType_t ret = xSemaphoreGive(*sem); + (void)ret; + LWIP_ASSERT("sys_sem_new: initial give failed", ret == pdTRUE); } @@ -121,6 +127,8 @@ void sys_sem_signal(sys_sem_t *sem) { BaseType_t ret = xSemaphoreGive(*sem); + (void)ret; + /* queue full is OK, this is a signal only... */ LWIP_ASSERT("sys_sem_signal: sane return value", (ret == pdTRUE) || (ret == errQUEUE_FULL)); @@ -219,6 +227,8 @@ void sys_mbox_post(sys_mbox_t *mbox, void *msg) { BaseType_t ret = xQueueSendToBack((*mbox)->os_mbox, &msg, portMAX_DELAY); + (void)ret; + LWIP_ASSERT("mbox post failed", ret == pdTRUE); } @@ -354,6 +364,8 @@ sys_mbox_free(sys_mbox_t *mbox) return; } UBaseType_t msgs_waiting = uxQueueMessagesWaiting((*mbox)->os_mbox); + (void)msgs_waiting; + LWIP_ASSERT("mbox quence not empty", msgs_waiting == 0); vQueueDelete((*mbox)->os_mbox); @@ -527,6 +539,39 @@ sys_delay_ms(uint32_t ms) vTaskDelay(ms / portTICK_PERIOD_MS); } +bool +sys_thread_tcpip(sys_thread_core_lock_t type) +{ + static sys_thread_t lwip_task = NULL; +#if LWIP_TCPIP_CORE_LOCKING + static sys_thread_t core_lock_holder = NULL; +#endif + switch (type) { + default: + return false; + case LWIP_CORE_IS_TCPIP_INITIALIZED: + return lwip_task != NULL; + case LWIP_CORE_MARK_TCPIP_TASK: + LWIP_ASSERT("LWIP_CORE_MARK_TCPIP_TASK: lwip_task == NULL", (lwip_task == NULL)); + lwip_task = (sys_thread_t) xTaskGetCurrentTaskHandle(); + return true; +#if LWIP_TCPIP_CORE_LOCKING + case LWIP_CORE_LOCK_QUERY_HOLDER: + return lwip_task ? core_lock_holder == (sys_thread_t) xTaskGetCurrentTaskHandle() : true; + case LWIP_CORE_LOCK_MARK_HOLDER: + core_lock_holder = (sys_thread_t) xTaskGetCurrentTaskHandle(); + return true; + case LWIP_CORE_LOCK_UNMARK_HOLDER: + core_lock_holder = NULL; + return true; +#else + case LWIP_CORE_LOCK_QUERY_HOLDER: + return lwip_task == NULL || lwip_task == (sys_thread_t) xTaskGetCurrentTaskHandle(); +#endif /* LWIP_TCPIP_CORE_LOCKING */ + } + return true; +} + // [NF_CHANGE] //////////////////////////////////////////////////// // nanoFramework "hack" extending LwIP original code @@ -546,3 +591,5 @@ void sys_signal_sock_event() } } // [END_NF_CHANGE] + +// clang-format on diff --git a/targets/ESP32/_nanoCLR/System.Device.I2c/sys_dev_i2c_native_System_Device_I2c_I2cDevice.cpp b/targets/ESP32/_nanoCLR/System.Device.I2c/sys_dev_i2c_native_System_Device_I2c_I2cDevice.cpp index 0a0efb4f27..b8cb704284 100644 --- a/targets/ESP32/_nanoCLR/System.Device.I2c/sys_dev_i2c_native_System_Device_I2c_I2cDevice.cpp +++ b/targets/ESP32/_nanoCLR/System.Device.I2c/sys_dev_i2c_native_System_Device_I2c_I2cDevice.cpp @@ -49,7 +49,20 @@ bool SetConfig(i2c_port_t bus, CLR_RT_HeapBlock *config) conf.sda_pullup_en = GPIO_PULLUP_ENABLE; conf.scl_io_num = ClockPin; conf.scl_pullup_en = GPIO_PULLUP_ENABLE; - conf.master.clk_speed = (busSpeed == 0) ? 100000 : 400000; + if (I2cBusSpeed::I2cBusSpeed_FastModePlus == busSpeed) + { + conf.master.clk_speed = 1000000; + } + else if (I2cBusSpeed::I2cBusSpeed_FastMode == busSpeed) + { + conf.master.clk_speed = 400000; + } + else + { + // Default is standard 100 KHz + conf.master.clk_speed = 100000; + } + conf.clk_flags = I2C_SCLK_SRC_FLAG_FOR_NOMAL; esp_err_t err = i2c_param_config(bus, &conf); diff --git a/targets/ESP32/_nanoCLR/System.Device.I2s/sys_dev_i2s_native_System_Device_I2s_I2sDevice.cpp b/targets/ESP32/_nanoCLR/System.Device.I2s/sys_dev_i2s_native_System_Device_I2s_I2sDevice.cpp index 4bc4933614..95b6d9ae7c 100644 --- a/targets/ESP32/_nanoCLR/System.Device.I2s/sys_dev_i2s_native_System_Device_I2s_I2sDevice.cpp +++ b/targets/ESP32/_nanoCLR/System.Device.I2s/sys_dev_i2s_native_System_Device_I2s_I2sDevice.cpp @@ -30,6 +30,10 @@ static char Esp_I2S_Initialised_Flag[I2S_NUM_MAX] = { #endif }; +#if SOC_I2S_SUPPORTS_ADC +static bool Adc_Mode_Enabled = false; +#endif + void swap_32_bit_stereo_channels(unsigned char *buffer, int length) { uint32_t swap_sample; @@ -51,6 +55,14 @@ void Esp32_I2s_UnitializeAll() if (Esp_I2S_Initialised_Flag[c]) { // Delete bus driver + +#if SOC_I2S_SUPPORTS_ADC + if (Adc_Mode_Enabled && c == I2S_NUM_0) + { + i2s_adc_disable((i2s_port_t)c); + Adc_Mode_Enabled = false; + } +#endif i2s_driver_uninstall((i2s_port_t)c); Esp_I2S_Initialised_Flag[c] = 0; } @@ -59,6 +71,13 @@ void Esp32_I2s_UnitializeAll() i2s_bits_per_sample_t get_dma_bits(uint8_t mode, i2s_bits_per_sample_t bits) { +#if SOC_I2S_SUPPORTS_ADC + if (mode & I2S_MODE_ADC_BUILT_IN) + { + return bits; + } +#endif + if (mode == (I2S_MODE_MASTER | I2S_MODE_TX)) { return bits; @@ -181,6 +200,13 @@ HRESULT SetI2sConfig(i2s_port_t bus, CLR_RT_HeapBlock *config) (i2s_bits_per_sample_t)config[I2sConnectionSettings::FIELD___sampleRate].NumericByRef().s4; int bufferSize = config[I2sConnectionSettings::FIELD___bufferSize].NumericByRef().s4; +#if !(SOC_I2S_SUPPORTS_ADC) + if (mode & I2sMode_AdcBuiltIn) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } +#endif + conf.communication_format = get_i2s_commformat(commformat); conf.mode = mode; conf.bits_per_sample = get_dma_bits(mode, bits); @@ -207,22 +233,91 @@ HRESULT SetI2sConfig(i2s_port_t bus, CLR_RT_HeapBlock *config) NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } +#if SOC_I2S_SUPPORTS_ADC + + // Configure ADC Mode + if (mode & I2S_MODE_ADC_BUILT_IN) + { + // TODO - make attenuation configurable? + adc_atten_t atten = ADC_ATTEN_DB_11; + + // TODO Re-use logic in ADC? + int channelNumber = -1; + + // Find out ADC Channel for pin configured as I2S_DATAIN + for (unsigned int i = 0; i < sizeof(Esp32_ADC_DevicePinMap) / sizeof(int8_t); i++) + { + if (Esp32_ADC_DevicePinMap[i] == pin_config.data_in_num) + { + channelNumber = i; + break; + } + } + if (channelNumber < 0) + { + NANOCLR_SET_AND_LEAVE(CLR_E_PIN_UNAVAILABLE); + } + + int adcUnit = channelNumber <= 9 ? 1 : 2; + switch (adcUnit) + { + case 1: + // Normal channel 0-7 ? + if (channelNumber <= 7) + { + // TODO - Make ADC Resolution configurable? + // adc1_config_width(width_bit); + + if (adc1_config_channel_atten((adc1_channel_t)channelNumber, atten) != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_PIN_UNAVAILABLE); + } + + if (i2s_set_adc_mode(ADC_UNIT_1, (adc1_channel_t)channelNumber) != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + } + break; + + case 2: + // Adjust for ADC2 + channelNumber -= 10; + + // TODO - Make ADC Resolution configurable? + // adc2_config_width(width_bit); + + if (adc2_config_channel_atten((adc2_channel_t)channelNumber, atten) != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_PIN_UNAVAILABLE); + } + + if (i2s_set_adc_mode(ADC_UNIT_2, (adc1_channel_t)channelNumber) != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + + break; + } + + if (i2s_adc_enable(bus) != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + } +#endif + // Ensure driver gets unitialized during soft reboot HAL_AddSoftRebootHandler(Esp32_I2s_UnitializeAll); Esp_I2S_Initialised_Flag[bus]++; - } - -// apply low-level workaround for bug in some ESP-IDF versions that swap -// the left and right channels -// https://github.com/espressif/esp-idf/issues/6625 -#if CONFIG_IDF_TARGET_ESP32S3 - REG_SET_BIT(I2S_TX_CONF_REG(bus), I2S_TX_MSB_SHIFT); - REG_SET_BIT(I2S_TX_CONF_REG(bus), I2S_RX_MSB_SHIFT); -#else - REG_SET_BIT(I2S_CONF_REG(bus), I2S_TX_MSB_RIGHT); - REG_SET_BIT(I2S_CONF_REG(bus), I2S_RX_MSB_RIGHT); +#if SOC_I2S_SUPPORTS_ADC + if (mode & I2S_MODE_ADC_BUILT_IN) + { + Adc_Mode_Enabled = true; + } #endif + } #if (ESP_IDF_VERSION_MAJOR == 4) && (ESP_IDF_VERSION_MINOR >= 4) pin_config.mck_io_num = I2S_PIN_NO_CHANGE; @@ -467,6 +562,15 @@ HRESULT Library_sys_dev_i2s_native_System_Device_I2s_I2sDevice::NativeInit___VOI NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } +#if SOC_I2S_SUPPORTS_ADC + i2s_mode_t mode = (i2s_mode_t)(pConfig[I2sConnectionSettings::FIELD___i2sMode].NumericByRef().s4); + + if (mode & I2S_MODE_ADC_BUILT_IN && bus != I2S_NUM_0) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } +#endif + // Set the Bus parameters NANOCLR_CHECK_HRESULT(SetI2sConfig(bus, pConfig)); } @@ -494,6 +598,14 @@ HRESULT Library_sys_dev_i2s_native_System_Device_I2s_I2sDevice::NativeDispose___ if (Esp_I2S_Initialised_Flag[bus] <= 0) { +#if SOC_I2S_SUPPORTS_ADC + i2s_mode_t mode = (i2s_mode_t)(pConfig[I2sConnectionSettings::FIELD___i2sMode].NumericByRef().s4); + if (mode & I2S_MODE_ADC_BUILT_IN) + { + i2s_adc_disable(bus); + } +#endif + i2s_driver_uninstall(bus); Esp_I2S_Initialised_Flag[bus] = 0; diff --git a/targets/ESP32/_nanoCLR/System.Device.Pwm/sys_dev_pwm_native_System_Device_Pwm_PwmChannel.cpp b/targets/ESP32/_nanoCLR/System.Device.Pwm/sys_dev_pwm_native_System_Device_Pwm_PwmChannel.cpp index 38ca4aaee5..17fd618c1c 100644 --- a/targets/ESP32/_nanoCLR/System.Device.Pwm/sys_dev_pwm_native_System_Device_Pwm_PwmChannel.cpp +++ b/targets/ESP32/_nanoCLR/System.Device.Pwm/sys_dev_pwm_native_System_Device_Pwm_PwmChannel.cpp @@ -233,7 +233,7 @@ HRESULT Library_sys_dev_pwm_native_System_Device_Pwm_PwmChannel::NativeSetDesire // Working from 15 bit duty resolution down until we have a valid divisor optimumDutyResolution = 1; - for (int dutyResolution = 15; dutyResolution > 0; dutyResolution--) + for (int dutyResolution = SOC_LEDC_TIMER_BIT_WIDE_NUM - 1; dutyResolution > 0; dutyResolution--) { precision = (0x1 << dutyResolution); // 2**depth diff --git a/targets/ESP32/_nanoCLR/System.Device.Spi/cpu_spi.cpp b/targets/ESP32/_nanoCLR/System.Device.Spi/cpu_spi.cpp index fa351358a5..260e0da772 100644 --- a/targets/ESP32/_nanoCLR/System.Device.Spi/cpu_spi.cpp +++ b/targets/ESP32/_nanoCLR/System.Device.Spi/cpu_spi.cpp @@ -46,6 +46,8 @@ #include #include +#include + // Max frequency over GPIO mux pins, full duplex #define MAX_CLOCK_FREQUENCY_GPIO_FULL 26000000 // Max frequency over GPIO mux pins, half duplex @@ -73,6 +75,11 @@ struct NF_PAL_SPI unsigned char *originalReadData; unsigned char *readDataBuffer; unsigned char *writeDataBuffer; + + // -1 = Chip Select is not handled | >0 Chip Select is to be controlled with this GPIO + int32_t CurrentChipSelect; + int32_t NumberSpiDeviceInUse; + uint32_t Handle; }; NF_PAL_SPI nf_pal_spi[2]; @@ -82,7 +89,30 @@ bool haveAsyncTrans[2]; // return true of OK, false = error bool CPU_SPI_Remove_Device(uint32_t deviceHandle) { - return spi_bus_remove_device((spi_device_handle_t)deviceHandle) != ESP_OK; + // Find the bus + int spiBus = -1; + if (nf_pal_spi[0].Handle == deviceHandle) + { + spiBus = 0; + } + else if (nf_pal_spi[1].Handle == deviceHandle) + { + spiBus = 1; + } + + if (spiBus == -1) + { + return false; + } + + // We remove only if it's the last device + nf_pal_spi[spiBus].NumberSpiDeviceInUse--; + if (nf_pal_spi[spiBus].NumberSpiDeviceInUse == 0) + { + return spi_bus_remove_device((spi_device_handle_t)deviceHandle) != ESP_OK; + } + + return true; } // Initialise the physical SPI bus @@ -90,6 +120,12 @@ bool CPU_SPI_Remove_Device(uint32_t deviceHandle) // return true of successful, false if error bool CPU_SPI_Initialize(uint8_t busIndex, const SPI_DEVICE_CONFIGURATION &spiDeviceConfig) { + // Do we already initialized the SPI bus? + if (nf_pal_spi[busIndex].NumberSpiDeviceInUse > 0) + { + return true; + } + GPIO_PIN clockPin, misoPin, mosiPin; // Get pins used by SPI bus @@ -141,17 +177,18 @@ bool CPU_SPI_Initialize(uint8_t busIndex, const SPI_DEVICE_CONFIGURATION &spiDev intr_flags : ESP_INTR_FLAG_IRAM }; - // First available bus on ESP32 is HSPI_HOST(1) // Try with DMA first -#if defined(CONFIG_IDF_TARGET_ESP32C3) - esp_err_t ret = spi_bus_initialize((spi_host_device_t)(busIndex), &bus_config, SPI_DMA_CH_AUTO); +#if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3) + // First available bus on ESP32_C3/S3 is SPI2_HOST + esp_err_t ret = spi_bus_initialize((spi_host_device_t)(busIndex + SPI2_HOST), &bus_config, SPI_DMA_CH_AUTO); #else + // First available bus on ESP32 is HSPI_HOST(1) esp_err_t ret = spi_bus_initialize((spi_host_device_t)(busIndex + HSPI_HOST), &bus_config, SPI_DMA_CH_AUTO); #endif if (ret != ESP_OK) { -#if defined(CONFIG_IDF_TARGET_ESP32C3) +#if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3) ESP_LOGE(TAG, "Unable to init SPI bus %d esp_err %d", busIndex, ret); #else ESP_LOGE(TAG, "Unable to init SPI bus %d esp_err %d", busIndex + HSPI_HOST, ret); @@ -170,7 +207,7 @@ bool CPU_SPI_Initialize(uint8_t busIndex, const SPI_DEVICE_CONFIGURATION &spiDev // Uninitialise the bus bool CPU_SPI_Uninitialize(uint8_t busIndex) { -#if defined(CONFIG_IDF_TARGET_ESP32C3) +#if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3) esp_err_t ret = spi_bus_free((spi_host_device_t)(busIndex)); #else esp_err_t ret = spi_bus_free((spi_host_device_t)(busIndex + HSPI_HOST)); @@ -178,7 +215,7 @@ bool CPU_SPI_Uninitialize(uint8_t busIndex) if (ret != ESP_OK) { -#if defined(CONFIG_IDF_TARGET_ESP32C3) +#if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3) ESP_LOGE(TAG, "spi_bus_free bus %d esp_err %d", busIndex, ret); #else ESP_LOGE(TAG, "spi_bus_free bus %d esp_err %d", busIndex + HSPI_HOST, ret); @@ -186,7 +223,6 @@ bool CPU_SPI_Uninitialize(uint8_t busIndex) return false; } - return true; } @@ -217,6 +253,13 @@ static void IRAM_ATTR spi_trans_ready(spi_transaction_t *trans) } } + // if CS is to be controlled by the driver, set the GPIO + if (pnf_pal_spi->CurrentChipSelect >= 0) + { + // de-assert pin based on CS active level + CPU_GPIO_TogglePinState(pnf_pal_spi->CurrentChipSelect); + } + // fire callback for SPI transaction complete // only if callback set SPI_Callback callback = (SPI_Callback)pnf_pal_spi->callback; @@ -231,7 +274,6 @@ static void IRAM_ATTR spi_trans_ready(spi_transaction_t *trans) // Convert from SPI_DEVICE_CONFIGURATION to spi_device_interface_config_t used for ESP33 spi_device_interface_config_t GetConfig(const SPI_DEVICE_CONFIGURATION &spiDeviceConfig) { - int csPin = spiDeviceConfig.DeviceChipSelect; uint8_t spiMode = spiDeviceConfig.Spi_Mode; int32_t clockHz = spiDeviceConfig.Clock_RateHz; @@ -246,12 +288,6 @@ spi_device_interface_config_t GetConfig(const SPI_DEVICE_CONFIGURATION &spiDevic flags |= SPI_DEVICE_NO_DUMMY; - // Positive Chip Select for Active - if (spiDeviceConfig.ChipSelectActive) - { - flags |= SPI_DEVICE_POSITIVE_CS; - } - // check for half duplex if (spiDeviceConfig.BusConfiguration == SpiBusConfiguration_HalfDuplex) { @@ -269,7 +305,7 @@ spi_device_interface_config_t GetConfig(const SPI_DEVICE_CONFIGURATION &spiDevic 0, // cs_ena_posttrans clockHz, // Clock speed in Hz 0, // Input_delay_ns - csPin, // Chip select + -1, // Chip select, we will use manual chip select flags, // SPI_DEVICE flags 1, // Queue size 0, // Callback before @@ -288,32 +324,57 @@ HRESULT CPU_SPI_Add_Device(const SPI_DEVICE_CONFIGURATION &spiDeviceConfig, uint // First available bus on ESP32 is HSPI_HOST(1), so add one spi_device_interface_config_t dev_config = GetConfig(spiDeviceConfig); + // If the CS is low, then initial value is high and vice versa + int initialPinValue = 0; + if (spiDeviceConfig.ChipSelectActiveState == 0) + { + initialPinValue = 1; + } + + // Sets the CS pin as output + if (spiDeviceConfig.DeviceChipSelect >= 0) + { + // pinmode output + CPU_GPIO_EnableOutputPin(spiDeviceConfig.DeviceChipSelect, (GpioPinValue)initialPinValue, PinMode_Output); + } + // check supported bus configuration: all valid except simplex if (spiDeviceConfig.BusConfiguration == SpiBusConfiguration_Simplex) { return CLR_E_NOT_SUPPORTED; } - // Add device to bus - spi_device_handle_t deviceHandle; + if (nf_pal_spi[spiDeviceConfig.Spi_Bus].NumberSpiDeviceInUse == 0) + { + // Add device to bus + spi_device_handle_t deviceHandle; - // First available bus on ESP32 is HSPI_HOST(1) -#if defined(CONFIG_IDF_TARGET_ESP32C3) - esp_err_t ret = spi_bus_add_device((spi_host_device_t)(spiDeviceConfig.Spi_Bus), &dev_config, &deviceHandle); +#if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3) + // First available bus on ESP32_C3/S3 is SPI2_HOST + esp_err_t ret = + spi_bus_add_device((spi_host_device_t)(spiDeviceConfig.Spi_Bus + SPI2_HOST), &dev_config, &deviceHandle); #else - esp_err_t ret = - spi_bus_add_device((spi_host_device_t)(spiDeviceConfig.Spi_Bus + HSPI_HOST), &dev_config, &deviceHandle); + // First available bus on ESP32 is HSPI_HOST(1) + esp_err_t ret = + spi_bus_add_device((spi_host_device_t)(spiDeviceConfig.Spi_Bus + HSPI_HOST), &dev_config, &deviceHandle); #endif - if (ret != ESP_OK) - { - ESP_LOGE(TAG, "Unable to init SPI device, esp_err %d", ret); + if (ret != ESP_OK) + { + ESP_LOGE(TAG, "Unable to init SPI device, esp_err %d", ret); - return S_FALSE; - } + return S_FALSE; + } - handle = (uint32_t)deviceHandle; + handle = (uint32_t)deviceHandle; + nf_pal_spi[spiDeviceConfig.Spi_Bus].Handle = (uint32_t)deviceHandle; + } + else + { + handle = nf_pal_spi[spiDeviceConfig.Spi_Bus].Handle; + } + nf_pal_spi[spiDeviceConfig.Spi_Bus].NumberSpiDeviceInUse++; return S_OK; } @@ -428,6 +489,7 @@ HRESULT CPU_SPI_nWrite_nRead( pnf_pal_spi->fullDuplex = wrc.fullDuplex; pnf_pal_spi->readOffset = wrc.readOffset; // dummy bytes between write & read on half duplex pnf_pal_spi->callback = wrc.callback; + pnf_pal_spi->CurrentChipSelect = wrc.DeviceChipSelect; // Wait for any previously queued async transfer CPU_SPI_Wait_Busy(deviceHandle, sdev); @@ -448,6 +510,13 @@ HRESULT CPU_SPI_nWrite_nRead( pTrans->tx_buffer = writeData; pTrans->rx_buffer = readDataBuffer; + // if CS is to be controlled by the driver, set the GPIO + if (wrc.DeviceChipSelect >= 0) + { + // assert pin based on CS active level + CPU_GPIO_SetPinState(wrc.DeviceChipSelect, (GpioPinValue)wrc.ChipSelectActiveState); + } + // Start asynchronous SPI transaction if (async) { diff --git a/targets/ESP32/_nanoCLR/System.Device.Spi/sys_dev_spi_native_target.h b/targets/ESP32/_nanoCLR/System.Device.Spi/sys_dev_spi_native_target.h index 3261b4ec0d..5747b5ba7b 100644 --- a/targets/ESP32/_nanoCLR/System.Device.Spi/sys_dev_spi_native_target.h +++ b/targets/ESP32/_nanoCLR/System.Device.Spi/sys_dev_spi_native_target.h @@ -7,5 +7,6 @@ #define SYS_DEV_SPI_NATIVE_TARGET_H #include +#include -#endif //SYS_DEV_SPI_NATIVE_TARGET_H +#endif // SYS_DEV_SPI_NATIVE_TARGET_H diff --git a/targets/ESP32/_nanoCLR/System.IO.FileSystem/nf_sys_io_filesystem_System_IO_FileStream.cpp b/targets/ESP32/_nanoCLR/System.IO.FileSystem/nf_sys_io_filesystem_System_IO_FileStream.cpp index 25fe01c911..de56a9d271 100644 --- a/targets/ESP32/_nanoCLR/System.IO.FileSystem/nf_sys_io_filesystem_System_IO_FileStream.cpp +++ b/targets/ESP32/_nanoCLR/System.IO.FileSystem/nf_sys_io_filesystem_System_IO_FileStream.cpp @@ -334,8 +334,8 @@ HRESULT Library_nf_sys_io_filesystem_System_IO_FileStream::WriteNative___VOID__S // Convert to ESP32 VFS path vfsPath = ConvertToVfsPath(filePath); - // open file for write / read - file = fopen(vfsPath, "a+"); + // open file for read / update + file = fopen(vfsPath, "r+"); if (file != NULL) { // Change to actual position in file to start write diff --git a/targets/ESP32/_nanoCLR/nanoCRT.cpp b/targets/ESP32/_nanoCLR/nanoCRT.cpp index 24eea2d1cf..3bdc81db78 100644 --- a/targets/ESP32/_nanoCLR/nanoCRT.cpp +++ b/targets/ESP32/_nanoCLR/nanoCRT.cpp @@ -13,11 +13,10 @@ #if !defined(BUILD_RTM) -void hal_fprintf_SetLoggingCallback( LOGGING_CALLBACK fpn ) +void hal_fprintf_SetLoggingCallback(LOGGING_CALLBACK fpn) { (void)fpn; NATIVE_PROFILE_PAL_CRT(); - } #endif @@ -26,61 +25,64 @@ void hal_fprintf_SetLoggingCallback( LOGGING_CALLBACK fpn ) #if defined(PLATFORM_EMULATED_FLOATINGPOINT) -// no floating point, fixed point +// no floating point, fixed point -int hal_snprintf_float( char* buffer, size_t len, const char* format, int32_t f ) +int hal_snprintf_float(char *buffer, size_t len, const char *format, int32_t f) { NATIVE_PROFILE_PAL_CRT(); - uint32_t i ; - uint32_t dec; + uint32_t i; + uint32_t dec; - if ( f < 0 ) + if (f < 0) { // negative number - i = (uint32_t) -f ; - dec = i & (( 1<>HAL_FLOAT_SHIFT); - - if (dec !=0) dec = (dec * (uint32_t)HAL_FLOAT_PRECISION + (1<< (HAL_FLOAT_SHIFT-1))) >>HAL_FLOAT_SHIFT; + i = (uint32_t)-f; + dec = i & ((1 << HAL_FLOAT_SHIFT) - 1); + i = (i >> HAL_FLOAT_SHIFT); - return hal_snprintf( buffer, len, "-%d.%03u", i, (uint32_t)dec); + if (dec != 0) + dec = (dec * (uint32_t)HAL_FLOAT_PRECISION + (1 << (HAL_FLOAT_SHIFT - 1))) >> HAL_FLOAT_SHIFT; + return hal_snprintf(buffer, len, "-%d.%03u", i, (uint32_t)dec); } else { // positive number - i = (uint32_t) f ; - dec = f & (( 1<>HAL_FLOAT_SHIFT); + i = (uint32_t)f; + dec = f & ((1 << HAL_FLOAT_SHIFT) - 1); + i = (uint32_t)(i >> HAL_FLOAT_SHIFT); - if (dec !=0) dec = (dec * (uint32_t)HAL_FLOAT_PRECISION + (1<< (HAL_FLOAT_SHIFT-1))) >>HAL_FLOAT_SHIFT; + if (dec != 0) + dec = (dec * (uint32_t)HAL_FLOAT_PRECISION + (1 << (HAL_FLOAT_SHIFT - 1))) >> HAL_FLOAT_SHIFT; - return hal_snprintf( buffer, len, "%d.%03u", i, (uint32_t)dec); + return hal_snprintf(buffer, len, "%d.%03u", i, (uint32_t)dec); } } -int hal_snprintf_double( char* buffer, size_t len, const char* format, int64_t& d ) +int hal_snprintf_double(char *buffer, size_t len, const char *format, int64_t &d) { NATIVE_PROFILE_PAL_CRT(); uint64_t i; - uint32_t dec; // 32 bit is enough for decimal part + uint32_t dec; // 32 bit is enough for decimal part - if ( d < 0 ) + if (d < 0) { // negative number i = (uint64_t)-d; - - i += ((1 << (HAL_DOUBLE_SHIFT-1)) / HAL_DOUBLE_PRECISION); // add broad part of rounding increment before split - dec = i & (( 1<> HAL_DOUBLE_SHIFT ; + i += + ((1 << (HAL_DOUBLE_SHIFT - 1)) / HAL_DOUBLE_PRECISION); // add broad part of rounding increment before split - if (dec !=0) dec = (dec * HAL_DOUBLE_PRECISION + ((1 << (HAL_DOUBLE_SHIFT-1)) % HAL_DOUBLE_PRECISION)) >> HAL_DOUBLE_SHIFT; + dec = i & ((1 << HAL_DOUBLE_SHIFT) - 1); + i = i >> HAL_DOUBLE_SHIFT; - return hal_snprintf( buffer, len, "-%lld.%04u", (int64_t)i, (uint32_t)dec); + if (dec != 0) + dec = (dec * HAL_DOUBLE_PRECISION + ((1 << (HAL_DOUBLE_SHIFT - 1)) % HAL_DOUBLE_PRECISION)) >> + HAL_DOUBLE_SHIFT; + return hal_snprintf(buffer, len, "-%lld.%04u", (int64_t)i, (uint32_t)dec); } else { @@ -88,14 +90,17 @@ int hal_snprintf_double( char* buffer, size_t len, const char* format, int64_t& // positive number i = (uint64_t)d; - i += ((1 << (HAL_DOUBLE_SHIFT-1)) / HAL_DOUBLE_PRECISION); // add broad part of rounding increment before split + i += + ((1 << (HAL_DOUBLE_SHIFT - 1)) / HAL_DOUBLE_PRECISION); // add broad part of rounding increment before split - dec = i & (( 1<> HAL_DOUBLE_SHIFT; - - if (dec !=0) dec = (dec * HAL_DOUBLE_PRECISION + ((1 << (HAL_DOUBLE_SHIFT-1)) % HAL_DOUBLE_PRECISION)) >> HAL_DOUBLE_SHIFT; - return hal_snprintf( buffer, len, "%lld.%04u", (int64_t)i, (uint32_t)dec); + if (dec != 0) + dec = (dec * HAL_DOUBLE_PRECISION + ((1 << (HAL_DOUBLE_SHIFT - 1)) % HAL_DOUBLE_PRECISION)) >> + HAL_DOUBLE_SHIFT; + + return hal_snprintf(buffer, len, "%lld.%04u", (int64_t)i, (uint32_t)dec); } } @@ -104,52 +109,63 @@ int hal_snprintf_double( char* buffer, size_t len, const char* format, int64_t& #endif // because debug_printf needs to be called in both C and C++ we need a proxy to allow it to be called in 'C' -extern "C" { +extern "C" +{ #if !defined(BUILD_RTM) - - void debug_printf(const char* format, ...) + + void debug_printf(const char *format, ...) { char buffer[256]; va_list arg_ptr; - - va_start( arg_ptr, format ); - - int len = vsnprintf( buffer, sizeof(buffer)-1, format, arg_ptr ); - - DebuggerPort_Write( HalSystemConfig.stdio, buffer, len, 0 ); // skip null terminator - - va_end( arg_ptr ); + + va_start(arg_ptr, format); + + int len = vsnprintf(buffer, sizeof(buffer) - 1, format, arg_ptr); + + DebuggerPort_Write(HalSystemConfig.stdio, buffer, len, 0); // skip null terminator + + va_end(arg_ptr); } -#else - __inline void debug_printf( const char *format, ... ) {} -#endif // !defined(BUILD_RTM) +#endif // !defined(BUILD_RTM) } -int hal_strcpy_s ( char* strDst, size_t sizeInBytes, const char* strSrc ) +int hal_strcpy_s(char *strDst, size_t sizeInBytes, const char *strSrc) { NATIVE_PROFILE_PAL_CRT(); #undef strcpy size_t len; - if(strDst == NULL || strSrc == NULL || sizeInBytes == 0) {_ASSERTE(FALSE); return 1;} - + if (strDst == NULL || strSrc == NULL || sizeInBytes == 0) + { + _ASSERTE(FALSE); + return 1; + } + len = hal_strlen_s(strSrc); - if(sizeInBytes < len + 1) {_ASSERTE(FALSE); return 1;} + if (sizeInBytes < len + 1) + { + _ASSERTE(FALSE); + return 1; + } - strcpy( strDst, strSrc ); + strcpy(strDst, strSrc); return 0; -#define strcpy DoNotUse_*strcpy [] +#define strcpy DoNotUse_ *strcpy[] } -int hal_strncpy_s ( char* strDst, size_t sizeInBytes, const char* strSrc, size_t count ) +int hal_strncpy_s(char *strDst, size_t sizeInBytes, const char *strSrc, size_t count) { NATIVE_PROFILE_PAL_CRT(); #undef strncpy - if(strDst == NULL || strSrc == NULL || sizeInBytes == 0) {_ASSERTE(FALSE); return 1;} - + if (strDst == NULL || strSrc == NULL || sizeInBytes == 0) + { + _ASSERTE(FALSE); + return 1; + } + if (sizeInBytes < count + 1) { _ASSERTE(FALSE); @@ -158,49 +174,53 @@ int hal_strncpy_s ( char* strDst, size_t sizeInBytes, const char* strSrc, size_t } strDst[count] = 0; - strncpy( strDst, strSrc, count ); + strncpy(strDst, strSrc, count); return 0; -#define strncpy DoNotUse_*strncpy [] +#define strncpy DoNotUse_ *strncpy[] } -size_t hal_strlen_s (const char * str) +size_t hal_strlen_s(const char *str) { NATIVE_PROFILE_PAL_CRT(); const char *eos = str; - while( *eos++ ) ; - return( eos - str - 1 ); + while (*eos++) + ; + return (eos - str - 1); } -int hal_strncmp_s ( const char* str1, const char* str2, size_t num ) +int hal_strncmp_s(const char *str1, const char *str2, size_t num) { NATIVE_PROFILE_PAL_CRT(); #undef strncmp - if(str1 == NULL || str2 == NULL) {_ASSERTE(FALSE); return 1;} - - return strncmp( str1, str2, num ); + if (str1 == NULL || str2 == NULL) + { + _ASSERTE(FALSE); + return 1; + } + + return strncmp(str1, str2, num); -#define strncmp DoNotUse_*strncmp [] +#define strncmp DoNotUse_ *strncmp[] } // Compares 2 ASCII strings case insensitive. Does not take locale into account. -int hal_stricmp( const char * dst, const char * src ) +int hal_stricmp(const char *dst, const char *src) { int f = 0, l = 0; do { - if ( ((f = (unsigned char)(*(dst++))) >= 'A') && (f <= 'Z') ) + if (((f = (unsigned char)(*(dst++))) >= 'A') && (f <= 'Z')) { f -= 'A' - 'a'; } - if ( ((l = (unsigned char)(*(src++))) >= 'A') && (l <= 'Z') ) + if (((l = (unsigned char)(*(src++))) >= 'A') && (l <= 'Z')) { l -= 'A' - 'a'; } - } - while ( f && (f == l) ); + } while (f && (f == l)); - return(f - l); + return (f - l); } diff --git a/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/esp32_nimble.cpp b/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/esp32_nimble.cpp index 3bc8b783cd..9cb375453d 100644 --- a/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/esp32_nimble.cpp +++ b/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/esp32_nimble.cpp @@ -12,8 +12,9 @@ static const char *tag = "BLE"; static uint8_t esp32_addr_type; -void Esp32BleStartAdvertise(bleServicesContext *context); +bool Esp32BleStartAdvertise(bleServicesContext *context); void BleCentralStartScan(); +void ble_store_config_init(); uint16_t ble_event_next_id = 1; device_ble_event_data ble_event_data; @@ -128,6 +129,8 @@ int Esp32GapEvent(struct ble_gap_event *event, void *arg) { bleServicesContext *con = (bleServicesContext *)arg; + BLE_DEBUG_PRINTF("Esp32GapEvent type %d \n", event->type); + switch (event->type) { // @@ -142,7 +145,9 @@ int Esp32GapEvent(struct ble_gap_event *event, void *arg) ble_event_data.result = -1; BLE_DEBUG_PRINTF( - "BLE_GAP_EVENT_DISC event type:%d adr:%X rssi:%d\n", + "BLE_GAP_EVENT_DISC event id:%d event:%X event type:%d adr:%X rssi:%d\n", + ble_event_data.eventId, + ble_event_data.gapEvent, event->disc.event_type, (unsigned int)event->disc.addr.val, event->disc.rssi); @@ -153,7 +158,7 @@ int Esp32GapEvent(struct ble_gap_event *event, void *arg) if (PostAndWaitManagedGapEvent(BluetoothEventType_AdvertisementDiscovered, 0, ble_event_data.eventId)) { // Handled - BLE_DEBUG_PRINTF("disc handled"); + BLE_DEBUG_PRINTF("disc handled\n"); } BLE_DEBUG_PRINTF("adv2 adr:%x rssi:%d\n", &event->disc.addr, event->disc.rssi); @@ -165,7 +170,7 @@ int Esp32GapEvent(struct ble_gap_event *event, void *arg) // Discovery Scan complete // case BLE_GAP_EVENT_DISC_COMPLETE: - MODLOG_DFLT(INFO, "discovery complete; reason=%d\n", event->disc_complete.reason); + BLE_DEBUG_PRINTF("Discovery complete; reason=%d\n", event->disc_complete.reason); // Post event to managed code PostManagedEvent(EVENT_BLUETOOTH, BluetoothEventType_ScanningComplete, event->disc_complete.reason, 0); @@ -174,23 +179,37 @@ int Esp32GapEvent(struct ble_gap_event *event, void *arg) case BLE_GAP_EVENT_CONNECT: // A new connection was established or a connection attempt failed - ESP_LOGI( - tag, - "connection %s; status=%d\n", + BLE_DEBUG_PRINTF( + "Connection %s; status=%d handle %d\n", event->connect.status == 0 ? "established" : "failed", - event->connect.status); + event->connect.status, + event->connect.conn_handle); + if (event->connect.status == 0) + { + PostManagedEvent( + EVENT_BLUETOOTH, + BluetoothEventType_ClientConnected, + event->connect.conn_handle, + event->connect.status); + } break; case BLE_GAP_EVENT_DISCONNECT: - ESP_LOGI(tag, "BLE_GAP_EVENT_DISCONNECT; reason=%d\n", event->disconnect.reason); + BLE_DEBUG_PRINTF("BLE_GAP_EVENT_DISCONNECT; reason=%d\n", event->disconnect.reason); + + PostManagedEvent( + EVENT_BLUETOOTH, + BluetoothEventType_ClientDisconnected, + event->disconnect.conn.conn_handle, + event->disconnect.reason); // Connection terminated; resume advertising Esp32BleStartAdvertise(con); break; case BLE_GAP_EVENT_ADV_COMPLETE: - ESP_LOGI(tag, "BLE_GAP_EVENT_ADV_COMPLETE adv complete"); + BLE_DEBUG_PRINTF("BLE_GAP_EVENT_ADV_COMPLETE adv complete"); break; case BLE_GAP_EVENT_SUBSCRIBE: @@ -200,8 +219,7 @@ int Esp32GapEvent(struct ble_gap_event *event, void *arg) // Find characteristicId from attr_handle uint16_t characteristicId = FindIdFromHandle(con, event->subscribe.attr_handle); - ESP_LOGI( - tag, + BLE_DEBUG_PRINTF( "BLE_GAP_EVENT_SUBSCRIBE conn_handle=%d attr_handle=%d " "reason=%d prevn=%d curn=%d previ=%d curi=%d arg=%d\n", event->subscribe.conn_handle, @@ -262,129 +280,178 @@ int Esp32GapEvent(struct ble_gap_event *event, void *arg) break; case BLE_GAP_EVENT_MTU: - ESP_LOGI( - tag, - "BLE_GAP_EVENT_MTU mtu update event; conn_handle=%d mtu=%d\n", + BLE_DEBUG_PRINTF( + "BLE_GAP_EVENT_MTU mtu update event; conn_handle=%d channel id=%d mtu=%d\n", event->mtu.conn_handle, + event->mtu.channel_id, event->mtu.value); + + PostManagedEvent( + EVENT_BLUETOOTH, + BluetoothEventType_ClientSessionChanged, + event->mtu.conn_handle, + (event->mtu.value << 16) + event->mtu.channel_id); + break; + + case BLE_GAP_EVENT_ENC_CHANGE: + { + struct ble_gap_conn_desc desc; + + int rc = ble_gap_conn_find(event->enc_change.conn_handle, &desc); + if (rc != 0) + { + return BLE_ATT_ERR_INVALID_HANDLE; + } + + uint16_t securityState = 0; + securityState += desc.sec_state.encrypted ? 1 : 0; + securityState += desc.sec_state.authenticated ? 2 : 0; + securityState += desc.sec_state.bonded ? 4 : 0; + + DevicePairingResultStatus pairingStatus = MapNimbleErrorToStatus(event->enc_change.status); + + BLE_DEBUG_PRINTF( + "Srv BLE_GAP_EVENT_ENC_CHANGE conn_handle=%d status=%d security=%X pairingStatus = %d\n", + event->enc_change.conn_handle, + event->enc_change.status, + securityState, + pairingStatus); + + PostManagedEvent( + EVENT_BLUETOOTH, + BluetoothEventType_AuthenticationComplete, + event->enc_change.conn_handle, + (securityState << 16) + pairingStatus); + } + break; + + case BLE_GAP_EVENT_PASSKEY_ACTION: + { + BLE_DEBUG_PRINTF( + "Srv BLE_GAP_EVENT_PASSKEY_ACTION conn_handle=%d action=%d\n", + event->passkey.conn_handle, + event->passkey.params.action); + + if (event->passkey.params.action == BLE_SM_IOACT_NUMCMP) + { + // As BLE_SM_IOACT_NUMCMP action we use unique BluetoothEventType_PassKeyActions_numcmp so we can pass + // pin instead of action + if (PostAndWaitManagedGapEvent( + BluetoothEventType_PassKeyActionsNumericComparison, + event->passkey.conn_handle, + event->passkey.params.numcmp)) + { + BLE_DEBUG_PRINTF(" BluetoothEventType_PassKeyActions NUMCMP handled"); + return 0; + } + } + else + { + if (PostAndWaitManagedGapEvent( + BluetoothEventType_PassKeyActions, + event->passkey.conn_handle, + PairingActionToDevicePairingKinds(event->passkey.params.action) << 16)) + { + BLE_DEBUG_PRINTF(" BluetoothEventType_PassKeyActions handled"); + return 0; + } + } + + return 1; + } + break; + + case BLE_GAP_EVENT_CONN_UPDATE: + { + BLE_DEBUG_PRINTF( + "BLE_GAP_EVENT_CONN_UPDATE conn_handle=%d status=%d\n", + event->conn_update.conn_handle, + event->conn_update.status); + } + break; + + case BLE_GAP_EVENT_CONN_UPDATE_REQ: + { + // Peer updating connection params. + BLE_DEBUG_PRINTF("BLE_GAP_EVENT_CONN_UPDATE_REQ conn_handle=%d\n", event->conn_update_req.conn_handle); + BLE_DEBUG_PRINTF( + "BLE_GAP_EVENT_CONN_UPDATE_REQ conn_handle=%d\n", + "Min Interval: %d, Max Interval: %d, Timeout: %d, Latency: %d ", + event->conn_update_req.peer_params->itvl_min, + event->conn_update_req.peer_params->itvl_max, + event->conn_update_req.peer_params->supervision_timeout, + event->conn_update_req.peer_params->latency); + // do nothing for now + } + break; + + case BLE_GAP_EVENT_REPEAT_PAIRING: + { + ble_gap_conn_desc out_desc; + + BLE_DEBUG_PRINTF( + "BLE_GAP_EVENT_REPEAT_PAIRING conn_handle=%d cur_authenticated=%d\n", + event->repeat_pairing.conn_handle, + event->repeat_pairing.cur_authenticated); + + // For now just delete old bond so we can continue with pairing + + // Delete the old bond + int rc = ble_gap_conn_find(event->repeat_pairing.conn_handle, &out_desc); + if (rc != 0) + { + return BLE_GAP_REPEAT_PAIRING_IGNORE; + } + + ble_store_util_delete_peer(&out_desc.peer_id_addr); + + // Host to continue with the pairing operation. + return BLE_GAP_REPEAT_PAIRING_RETRY; + } } return 0; } // -// Enables advertising with parameters: -// o General discoverable mode -// o Undirected connectable mode +// Enables advertising with parameters from context. // -void Esp32BleStartAdvertise(bleServicesContext *context) +bool Esp32BleStartAdvertise(bleServicesContext *context) { - struct ble_gap_adv_params adv_params; - struct ble_hs_adv_fields fields; - struct ble_hs_adv_fields scanResp; - bool useScanResponse = false; int rc; + bool result = true; + struct ble_gap_adv_params adv_params; - // - // Set the advertisement data included in our advertisements: - // o Flags (indicates advertisement type and other general info) - // o Advertising tx power - // o Device name - // - // What doesn't fit in primary advert packet we add to scanData for Scan response - // - memset(&fields, 0, sizeof(fields)); - memset(&scanResp, 0, sizeof(scanResp)); - - // - // Advertise two flags: - // o Discoverability in forthcoming advertisement (general) - // o BLE-only (BR/EDR unsupported) - // - fields.flags = BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP; - - // - // Indicate that the TX power level field should be included; have the - // stack fill this value automatically. This is done by assigning the - // special value BLE_HS_ADV_TX_PWR_LVL_AUTO. - // - fields.tx_pwr_lvl_is_present = 1; - fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO; - - fields.name = (uint8_t *)context->pDeviceName; - fields.name_len = hal_strlen_s(context->pDeviceName); - fields.name_is_complete = 1; - - // Only advertise first Service UUID for now. - // if 16 or 32 add to advert fields. - // 128 uuid probably won't fix so add to scan response. - switch (context->gatt_service_def->uuid->type) - { - case BLE_UUID_TYPE_16: - fields.uuids16 = (ble_uuid16_t *)context->gatt_service_def->uuid; - fields.num_uuids16 = 1; - fields.uuids16_is_complete = 1; - break; - - case BLE_UUID_TYPE_32: - fields.uuids32 = (ble_uuid32_t *)context->gatt_service_def->uuid; - fields.num_uuids32 = 1; - fields.uuids32_is_complete = 1; - break; - - case BLE_UUID_TYPE_128: - scanResp.uuids128 = (ble_uuid128_t *)platform_malloc(sizeof(ble_uuid128_t)); - memcpy((void *)scanResp.uuids128, context->gatt_service_def->uuid, sizeof(ble_uuid128_t)); - scanResp.num_uuids128 = 1; - scanResp.uuids128_is_complete = 1; - useScanResponse = true; - break; - } - - rc = ble_gap_adv_set_fields(&fields); + rc = ble_gap_adv_set_data((const uint8_t *)context->advertData, context->advertDataLen); if (rc != 0) { - BLE_DEBUG_PRINTF("error setting advertisement data; rc=%d\n", rc); + BLE_DEBUG_PRINTF("ble_gap_adv_set_data; rc=%d\n", rc); } - if (useScanResponse) + if (context->scanResponseLen > 0) { - rc = ble_gap_adv_rsp_set_fields(&scanResp); + rc = ble_gap_adv_rsp_set_data((const uint8_t *)context->scanResponse, context->scanResponseLen); if (rc != 0) { - BLE_DEBUG_PRINTF("setting scan response data; rc=%d\n", rc); + BLE_DEBUG_PRINTF("ble_gap_adv_rsp_set_data; rc=%d\n", rc); } } - // Free any allocated memory - if (scanResp.uuids128 != 0) - { - platform_free((void *)scanResp.uuids128); - } - - if (rc != 0) - { - return; - } - // Begin advertising memset(&adv_params, 0, sizeof(adv_params)); - if (context->isConnectable) - { - adv_params.conn_mode |= BLE_GAP_CONN_MODE_UND; - } - if (context->isDiscoverable) - { - adv_params.conn_mode |= BLE_GAP_DISC_MODE_GEN; - } - rc = ble_gap_adv_start(esp32_addr_type, NULL, BLE_HS_FOREVER, &adv_params, Esp32GapEvent, (void *)&bleContext); + adv_params.conn_mode = bleContext.isConnectable ? BLE_GAP_CONN_MODE_UND : BLE_GAP_CONN_MODE_NON; + adv_params.disc_mode = bleContext.isDiscoverable ? BLE_GAP_DISC_MODE_GEN : BLE_GAP_DISC_MODE_NON; + + rc = ble_gap_adv_start(BLE_OWN_ADDR_PUBLIC, NULL, BLE_HS_FOREVER, &adv_params, Esp32GapEvent, (void *)&bleContext); if (rc != 0) { BLE_DEBUG_PRINTF("error enabling advertisement; rc=%d\n", rc); - return; + result = false; } + + return result; } static void Esp32BleOnSync(void) @@ -421,9 +488,7 @@ static void Esp32BleOnSync(void) switch (ble_operatingMode) { case BluetoothNanoDevice_Mode_Server: - // Begin advertising - Esp32BleStartAdvertise(&bleContext); - BLE_DEBUG_PRINTF("Server advertise started\n"); + BLE_DEBUG_PRINTF("Server mode started\n"); break; case BluetoothNanoDevice_Mode_Client: @@ -473,15 +538,69 @@ void Device_ble_dispose() BLE_DEBUG_PRINTF("nimble_port_stop failed %d\n", rc); } - BLE_DEBUG_PRINTF("delete mutexs\n"); - vEventGroupDelete(ble_event_waitgroup); - vSemaphoreDelete(ble_event_data.mutex); + BLE_DEBUG_PRINTF("delete event & mutexs\n"); + + LockEventMutex(); + + ble_event_data.eventId = 0; // block any further callbacks + + ReleaseEventMutex(); + + if (ble_event_waitgroup) + { + vEventGroupDelete(ble_event_waitgroup); + } + if (ble_event_data.mutex) + { + vSemaphoreDelete(ble_event_data.mutex); + } + + ble_event_waitgroup = NULL; + ble_event_data.mutex = NULL; ble_initialized = false; BLE_DEBUG_PRINTF("Device_ble_dispose exit %d\n", ble_initialized); } +void SetSecuritySettings( + DevicePairingIOCapabilities IOCaps, + DevicePairingProtectionLevel protectionLevel, + bool allowBonding, + bool allowOob) +{ + ble_hs_cfg.sm_io_cap = IOCaps; + + switch (protectionLevel) + { + case DevicePairingProtectionLevel_Encryption: + ble_hs_cfg.sm_sc = 1; + break; + + case DevicePairingProtectionLevel_EncryptionAndAuthentication: + ble_hs_cfg.sm_sc = 1; + ble_hs_cfg.sm_mitm = 1; + break; + + default: + ble_hs_cfg.sm_sc = 0; + ble_hs_cfg.sm_mitm = 0; + break; + } + + ble_hs_cfg.sm_bonding = allowBonding ? 1 : 0; + + ble_hs_cfg.sm_oob_data_flag = allowOob ? 1 : 0; + + ble_hs_cfg.store_status_cb = ble_store_util_status_rr; + + BLE_DEBUG_PRINTF( + "SetSecuritySettings sc=%d mitm=%d bonding %d\n", + ble_hs_cfg.sm_sc, + ble_hs_cfg.sm_mitm, + ble_hs_cfg.sm_bonding); +} + bool DeviceBleInit() { esp_err_t err; @@ -507,18 +626,27 @@ bool DeviceBleInit() ble_event_waitgroup = xEventGroupCreate(); ble_event_data.mutex = xSemaphoreCreateMutex(); + if (!ble_event_waitgroup || !ble_event_data.mutex) + { + BLE_DEBUG_PRINTF("Ble Event Wait Group or mutex is null\n"); + return false; + } + nimble_port_init(); // Initialize the NimBLE host configuration ble_hs_cfg.sync_cb = Esp32BleOnSync; ble_hs_cfg.reset_cb = Esp32BleOnReset; + // Initialise default security/pairing settings + SetSecuritySettings(DevicePairingIOCapabilities_NoInputNoOutput, DevicePairingProtectionLevel_Default, true, false); + ble_initialized = true; return true; } -void StartBleTask(char *deviceName) +void StartBleTask(char *deviceName, uint16_t appearance) { int rc; @@ -528,40 +656,13 @@ void StartBleTask(char *deviceName) rc = ble_svc_gap_device_name_set(deviceName); assert(rc == 0); + rc = ble_svc_gap_device_appearance_set(appearance); + assert(rc == 0); + // Start the BLE task nimble_port_freertos_init(esp32_ble_host_task); } -int DeviceBleStart(bleServicesContext &con) -{ - int rc; - ble_gatt_svc_def *gatt_svr_svcs = con.gatt_service_def; - - BLE_DEBUG_PRINTF("DeviceBleStart\n"); - - ble_svc_gap_init(); - ble_svc_gatt_init(); - - rc = ble_gatts_count_cfg(gatt_svr_svcs); - if (rc != 0) - { - BLE_DEBUG_PRINTF("ble_gatts_count_cfg failed %d\n", rc); - return rc; - } - - rc = ble_gatts_add_svcs(gatt_svr_svcs); - if (rc != 0) - { - BLE_DEBUG_PRINTF("ble_gatts_add_svcs failed %d\n", rc); - return rc; - } - - // Set device name & start BLE task - StartBleTask(con.pDeviceName); - - return 0; -} - // // Callback from Nimble for characteristic events // These are posted to Managed code and if not handled within 500ms an error is reported to Nimble back to client diff --git a/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/nimble_utils.cpp b/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/nimble_utils.cpp index 393fa4773a..a56c398bab 100644 --- a/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/nimble_utils.cpp +++ b/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/nimble_utils.cpp @@ -209,11 +209,21 @@ HRESULT PushEmptyBufferToStack(CLR_RT_StackFrame &stack) bool LockEventMutex() { + if (ble_event_data.mutex == NULL) + { + return false; + } + return xSemaphoreTake(ble_event_data.mutex, (TickType_t)(1000 / portTICK_PERIOD_MS)); } void ReleaseEventMutex() { + if (ble_event_data.mutex == NULL) + { + return; + } + xSemaphoreGive(ble_event_data.mutex); } @@ -235,20 +245,102 @@ bool WaitForBleStackStart(int waitMs) return false; } -void StartStack(char *devicename) +bool StartBleStack(char *devicename, uint16_t appearance) { // Ignore if already started if (ble_hs_is_enabled()) { - return; + return false; } // Initialise BLE stack DeviceBleInit(); // Start BLE host task running - StartBleTask(devicename); + StartBleTask(devicename, appearance); // Wait for stack to be ready (Sync fired) - WaitForBleStackStart(5000); + WaitForBleStackStart(10000); + + return true; +} + +bool StopBleStack() +{ + // Not running + if (!ble_hs_is_enabled()) + { + return false; + } + + Device_ble_dispose(); + return true; +} + +// Map nimble error code to pairing status +DevicePairingResultStatus MapNimbleErrorToStatus(int errorCode) +{ + DevicePairingResultStatus pairingStatus = DevicePairingResultStatus_Paired; + + // ble_error_codes + switch (errorCode) + { + case 0: + pairingStatus = DevicePairingResultStatus_Paired; + break; + + case BLE_ERR_HW_FAIL: + pairingStatus = DevicePairingResultStatus_HardwareFailure; + break; + + case (BLE_HS_ERR_HCI_BASE + BLE_ERR_NO_PAIRING): // Pairing not allowed + pairingStatus = DevicePairingResultStatus_NotPaired; + break; + + default: + pairingStatus = DevicePairingResultStatus_Failed; + break; + } + return pairingStatus; +} + +// Pairing action to DevicePairingKinds conversion +DevicePairingKinds PairingActionToDevicePairingKinds(int action) +{ + switch (action) + { + default: + case BLE_SM_IOACT_NONE: + case BLE_SM_IOACT_OOB: + return DevicePairingKinds_None; + + case BLE_SM_IOACT_INPUT: + return DevicePairingKinds_ProvidePin; + + case BLE_SM_IOACT_DISP: + return DevicePairingKinds_DisplayPin; + + case BLE_SM_IOACT_NUMCMP: + return DevicePairingKinds_ConfirmPinMatch; + } +} + +// DevicePairingKinds to pairing action conversion +int DevicePairingKindsToPairingAction(DevicePairingKinds kinds) +{ + switch (kinds) + { + default: + case DevicePairingKinds_None: + return BLE_SM_IOACT_NONE; + + case DevicePairingKinds_ProvidePin: + return BLE_SM_IOACT_INPUT; + + case DevicePairingKinds_DisplayPin: + return BLE_SM_IOACT_DISP; + + case DevicePairingKinds_ConfirmPinMatch: + return BLE_SM_IOACT_NUMCMP; + } } diff --git a/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/nimble_utils.h b/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/nimble_utils.h index 7b61e2cb94..639f484171 100644 --- a/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/nimble_utils.h +++ b/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/nimble_utils.h @@ -8,7 +8,7 @@ #define NIMBLE_UTIL_H // Uncomment to enable BLE diagnostic debug messages -//#define NANO_BLE_DEBUG +// #define NANO_BLE_DEBUG #if defined(NANO_BLE_DEBUG) #define BLE_DEBUG_PRINTF(format, ...) \ @@ -39,7 +39,12 @@ HRESULT PushEmptyBufferToStack(CLR_RT_StackFrame &stack); bool LockEventMutex(); void ReleaseEventMutex(); -void StartStack(char *devicename); +bool StartBleStack(char *devicename, uint16_t appearance); +bool StopBleStack(); bool WaitForBleStackStart(int waitMs); -#endif \ No newline at end of file +DevicePairingResultStatus MapNimbleErrorToStatus(int errorCode); +DevicePairingKinds PairingActionToDevicePairingKinds(int action); +int DevicePairingKindsToPairingAction(DevicePairingKinds kinds); + +#endif // NIMBLE_UTIL_H diff --git a/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/sys_ble.h b/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/sys_ble.h index d23647462a..05493b3b14 100644 --- a/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/sys_ble.h +++ b/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/sys_ble.h @@ -71,6 +71,17 @@ struct bleServicesContext // The device name char *pDeviceName; + // True if using extended advertisements (Bluetooth 5.0) + bool useExtendedAdvert; + + // Ptr & length of advertisement packet + int advertDataLen; + uint8_t *advertData; + + // Ptr & length of scanresponse packet (Legacy) + int scanResponseLen; + uint8_t *scanResponse; + // Number of services in service definition int serviceCount; @@ -81,11 +92,16 @@ struct bleServicesContext ble_context *bleSrvContexts; }; -void StartBleTask(char *deviceName); +void StartBleTask(char *deviceName, uint16_t appearance); bool DeviceBleInit(); void Device_ble_dispose(); int Esp32GapEvent(struct ble_gap_event *event, void *arg); int ConnectionCount(); +void SetSecuritySettings( + DevicePairingIOCapabilities IOCaps, + DevicePairingProtectionLevel protectionLevel, + bool allowBonding, + bool allowOob); extern bleServicesContext bleContext; extern device_ble_event_data ble_event_data; diff --git a/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/sys_dev_ble_native.cpp b/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/sys_dev_ble_native.cpp index 316ec6c448..52ccdda32c 100644 --- a/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/sys_dev_ble_native.cpp +++ b/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/sys_dev_ble_native.cpp @@ -44,7 +44,66 @@ static const CLR_RT_MethodHandler method_lookup[] = NULL, NULL, NULL, - Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_Advertisement_BluetoothLEAdvertisementReceivedEventArgs::NativeCreateFromEvent___BOOLEAN__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, + Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothNanoDevice::NativeInitilise___STATIC__VOID, + Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothNanoDevice::NativeSetOperationMode___STATIC__VOID__nanoFrameworkDeviceBluetoothBluetoothNanoDeviceMode__STRING__U2, + NULL, + NULL, NULL, NULL, NULL, @@ -116,6 +175,14 @@ static const CLR_RT_MethodHandler method_lookup[] = NULL, NULL, NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttributeProfile_GattWriteRequest::NativeWriteGetData___SZARRAY_U1__U2, Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttributeProfile_GattWriteRequest::NativeWriteRespond___VOID__U2, Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttributeProfile_GattWriteRequest::NativeWriteRespondWithProtocolError___VOID__U2__U1, @@ -151,8 +218,6 @@ static const CLR_RT_MethodHandler method_lookup[] = NULL, NULL, NULL, - Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothNanoDevice::NativeInitilise___STATIC__VOID, - Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothNanoDevice::NativeSetOperationMode___STATIC__VOID__nanoFrameworkDeviceBluetoothBluetoothNanoDeviceMode__STRING, NULL, NULL, NULL, @@ -163,6 +228,94 @@ static const CLR_RT_MethodHandler method_lookup[] = NULL, NULL, NULL, + Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_DevicePairingRequestedEventArgs::NativeAcceptYesNo___U2__U2__nanoFrameworkDeviceBluetoothDevicePairingKinds__I4, + Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_DevicePairingRequestedEventArgs::NativeAcceptPasskey___U2__U2__nanoFrameworkDeviceBluetoothDevicePairingKinds__I4, + Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_DevicePairingRequestedEventArgs::NativeAcceptCredentials___U2__U2__nanoFrameworkDeviceBluetoothDevicePairingKinds__SZARRAY_U1__SZARRAY_U1, + NULL, + 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_sys_dev_ble_native_nanoFramework_Device_Bluetooth_DevicePairing::NativeStartPair___U2__U2, + Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_DevicePairing::NativeSetPairAttributes___VOID, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + 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_sys_dev_ble_native_nanoFramework_Device_Bluetooth_Advertisement_BluetoothLEAdvertisementPublisher::NativeStartLegacyAdvertising___BOOLEAN__SZARRAY_U1__SZARRAY_U1, + Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_Advertisement_BluetoothLEAdvertisementPublisher::NativeStartExtendedAdvertising___BOOLEAN__I2__SZARRAY_U1, + Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_Advertisement_BluetoothLEAdvertisementPublisher::NativeStopAdvertising___VOID, + Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_Advertisement_BluetoothLEAdvertisementPublisher::NativeIsExtendedAdvertisingAvailable___BOOLEAN, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_Advertisement_BluetoothLEAdvertisementReceivedEventArgs::NativeCreateFromEvent___BOOLEAN__I4, + NULL, + NULL, NULL, NULL, NULL, @@ -272,6 +425,11 @@ static const CLR_RT_MethodHandler method_lookup[] = NULL, NULL, NULL, + NULL, + NULL, + NULL, + NULL, + NULL, Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothLEDevice::NativeConnect___U2__U8__nanoFrameworkDeviceBluetoothBluetoothAddressType__U2, Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothLEDevice::NativeDisconnect___VOID__U2, Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothLEDevice::NativeDispose___VOID__U2, @@ -317,6 +475,22 @@ static const CLR_RT_MethodHandler method_lookup[] = NULL, NULL, NULL, + Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothLEAdvertisementWatcher::NativeStartAdvertisementWatcher___VOID__I4, + Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothLEAdvertisementWatcher::NativeStopAdvertisementWatcher___VOID, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, NULL, NULL, NULL, @@ -333,8 +507,6 @@ static const CLR_RT_MethodHandler method_lookup[] = NULL, NULL, NULL, - Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothLEAdvertisementWatcher::NativeStartAdvertisementWatcher___VOID__I4, - Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothLEAdvertisementWatcher::NativeStopAdvertisementWatcher___VOID, NULL, NULL, NULL, @@ -568,13 +740,12 @@ static const CLR_RT_MethodHandler method_lookup[] = NULL, NULL, NULL, + Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttributeProfile_GattServiceProvider::NativeInitializeServiceConfig___BOOLEAN__SystemCollectionsArrayList, + Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttributeProfile_GattServiceProvider::NativeDisposeServiceConfig___VOID, NULL, NULL, NULL, NULL, - Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttributeProfile_GattServiceProvider::NativeInitService___BOOLEAN, - Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttributeProfile_GattServiceProvider::NativeStartAdvertising___BOOLEAN, - Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttributeProfile_GattServiceProvider::NativeStopAdvertising___VOID, NULL, NULL, NULL, @@ -609,6 +780,11 @@ static const CLR_RT_MethodHandler method_lookup[] = NULL, NULL, NULL, + Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_Security_DeviceBonding::IsBonded___STATIC__BOOLEAN__U8, + Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_Security_DeviceBonding::DeleteAllBonds___STATIC__VOID, + Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_Security_DeviceBonding::DeleteBondForPeer___STATIC__VOID__U8__nanoFrameworkDeviceBluetoothBluetoothAddressType, + Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_Security_DeviceBonding::Count___STATIC__I4, + Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_Security_DeviceBonding::GetBondInformationAt___STATIC__U8__I4, NULL, NULL, NULL, @@ -647,9 +823,9 @@ static const CLR_RT_MethodHandler method_lookup[] = const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Device_Bluetooth = { "nanoFramework.Device.Bluetooth", - 0x066AC1EC, + 0xD163A9D5, method_lookup, - { 100, 0, 2, 0 } + { 100, 0, 5, 0 } }; // clang-format on diff --git a/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/sys_dev_ble_native.h b/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/sys_dev_ble_native.h index b1d8c18a7b..c9dd13d224 100644 --- a/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/sys_dev_ble_native.h +++ b/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/sys_dev_ble_native.h @@ -13,7 +13,31 @@ #include -#include "sys_ble.h" +typedef enum __nfpack BluetoothLEAdvertisementDataSectionType +{ + BluetoothLEAdvertisementDataSectionType_AdvertisingInterval = 26, + BluetoothLEAdvertisementDataSectionType_Appearance = 25, + BluetoothLEAdvertisementDataSectionType_CompleteLocalName = 9, + BluetoothLEAdvertisementDataSectionType_CompleteList128uuid = 7, + BluetoothLEAdvertisementDataSectionType_CompleteList16uuid = 3, + BluetoothLEAdvertisementDataSectionType_CompleteList32uuid = 5, + BluetoothLEAdvertisementDataSectionType_Flags = 1, + BluetoothLEAdvertisementDataSectionType_IncompleteList128uuid = 6, + BluetoothLEAdvertisementDataSectionType_IncompleteList16uuid = 2, + BluetoothLEAdvertisementDataSectionType_IncompleteList32uuid = 4, + BluetoothLEAdvertisementDataSectionType_ManufacturerSpecificData = 255, + BluetoothLEAdvertisementDataSectionType_PeripheralConnectionIntervalRange = 18, + BluetoothLEAdvertisementDataSectionType_PublicTargetAddress = 23, + BluetoothLEAdvertisementDataSectionType_RandomTargetAddress = 24, + BluetoothLEAdvertisementDataSectionType_ServiceData128bitUuid = 33, + BluetoothLEAdvertisementDataSectionType_ServiceData16bitUuid = 22, + BluetoothLEAdvertisementDataSectionType_ServiceData32bitUuid = 32, + BluetoothLEAdvertisementDataSectionType_ServiceSolicitation128BitUuids = 21, + BluetoothLEAdvertisementDataSectionType_ServiceSolicitation16BitUuids = 20, + BluetoothLEAdvertisementDataSectionType_ServiceSolicitation32BitUuids = 31, + BluetoothLEAdvertisementDataSectionType_ShortenedLocalName = 8, + BluetoothLEAdvertisementDataSectionType_TxPowerLevel = 10, +} BluetoothLEAdvertisementDataSectionType; typedef enum __nfpack BluetoothLEAdvertisementFlags { @@ -25,6 +49,16 @@ typedef enum __nfpack BluetoothLEAdvertisementFlags BluetoothLEAdvertisementFlags_DualModeHostCapable = 16, } BluetoothLEAdvertisementFlags; +typedef enum __nfpack BluetoothLEAdvertisementPublisherStatus +{ + BluetoothLEAdvertisementPublisherStatus_Created = 0, + BluetoothLEAdvertisementPublisherStatus_Waiting = 1, + BluetoothLEAdvertisementPublisherStatus_Started = 2, + BluetoothLEAdvertisementPublisherStatus_Stopping = 3, + BluetoothLEAdvertisementPublisherStatus_Stopped = 4, + BluetoothLEAdvertisementPublisherStatus_Aborted = 5, +} BluetoothLEAdvertisementPublisherStatus; + typedef enum __nfpack BluetoothLEAdvertisementType { BluetoothLEAdvertisementType_ConnectableUndirected = 0, @@ -86,6 +120,12 @@ typedef enum __nfpack BluetoothEventType BluetoothEventType_AttributeReadValueComplete = 14, BluetoothEventType_AttributeWriteValueComplete = 15, BluetoothEventType_AttributeValueChanged = 16, + BluetoothEventType_ClientConnected = 17, + BluetoothEventType_ClientDisconnected = 18, + BluetoothEventType_ClientSessionChanged = 19, + BluetoothEventType_PassKeyActions = 20, + BluetoothEventType_PassKeyActionsNumericComparison = 21, + BluetoothEventType_AuthenticationComplete = 22, } BluetoothEventType; typedef enum __nfpack BluetoothLEAdvertisementWatcherStatus @@ -97,6 +137,13 @@ typedef enum __nfpack BluetoothLEAdvertisementWatcherStatus BluetoothLEAdvertisementWatcherStatus_Aborted = 4, } BluetoothLEAdvertisementWatcherStatus; +typedef enum __nfpack BluetoothLEDevice_readWriteValueResult +{ + BluetoothLEDevice_readWriteValueResult_success = 0, + BluetoothLEDevice_readWriteValueResult_acessDenied = 1, + BluetoothLEDevice_readWriteValueResult_failure = 2, +} BluetoothLEDevice_readWriteValueResult; + typedef enum __nfpack BluetoothNanoDevice_Mode { BluetoothNanoDevice_Mode_NotRunning = 0, @@ -104,6 +151,65 @@ typedef enum __nfpack BluetoothNanoDevice_Mode BluetoothNanoDevice_Mode_Client = 2, } BluetoothNanoDevice_Mode; +typedef enum __nfpack DevicePairingIOCapabilities +{ + DevicePairingIOCapabilities_DisplayOnly = 0, + DevicePairingIOCapabilities_DisplayYesNo = 1, + DevicePairingIOCapabilities_KeyboardOnly = 2, + DevicePairingIOCapabilities_NoInputNoOutput = 3, + DevicePairingIOCapabilities_KeyboardDisplay = 4, +} DevicePairingIOCapabilities; + +typedef enum __nfpack DevicePairingKinds +{ + DevicePairingKinds_None = 0, + DevicePairingKinds_ConfirmOnly = 1, + DevicePairingKinds_DisplayPin = 2, + DevicePairingKinds_ProvidePin = 4, + DevicePairingKinds_ConfirmPinMatch = 8, +} DevicePairingKinds; + +typedef enum __nfpack DevicePairingProtectionLevel +{ + DevicePairingProtectionLevel_Default = 0, + DevicePairingProtectionLevel_None = 1, + DevicePairingProtectionLevel_Encryption = 2, + DevicePairingProtectionLevel_EncryptionAndAuthentication = 3, +} DevicePairingProtectionLevel; + +typedef enum __nfpack DevicePairingResultStatus +{ + DevicePairingResultStatus_Paired = 0, + DevicePairingResultStatus_NotReadyToPair = 1, + DevicePairingResultStatus_NotPaired = 2, + DevicePairingResultStatus_AlreadyPaired = 3, + DevicePairingResultStatus_ConnectionRejected = 4, + DevicePairingResultStatus_TooManyConnections = 5, + DevicePairingResultStatus_HardwareFailure = 6, + DevicePairingResultStatus_AuthenticationTimeout = 7, + DevicePairingResultStatus_AuthenticationNotAllowed = 8, + DevicePairingResultStatus_AuthenticationFailure = 9, + DevicePairingResultStatus_NoSupportedProfiles = 10, + DevicePairingResultStatus_ProtectionLevelCouldNotBeMet = 11, + DevicePairingResultStatus_AccessDenied = 12, + DevicePairingResultStatus_InvalidCeremonyData = 13, + DevicePairingResultStatus_PairingCanceled = 14, + DevicePairingResultStatus_OperationAlreadyInProgress = 15, + DevicePairingResultStatus_RequiredHandlerNotRegistered = 16, + DevicePairingResultStatus_RejectedByHandler = 17, + DevicePairingResultStatus_RemoteDeviceHasAssociation = 18, + DevicePairingResultStatus_Failed = 19, +} DevicePairingResultStatus; + +typedef enum __nfpack DeviceUnpairingResultStatus +{ + DeviceUnpairingResultStatus_Unpaired = 0, + DeviceUnpairingResultStatus_AlreadyUnpaired = 1, + DeviceUnpairingResultStatus_OperationAlreadyInProgress = 2, + DeviceUnpairingResultStatus_AccessDenied = 3, + DeviceUnpairingResultStatus_Failed = 4, +} DeviceUnpairingResultStatus; + typedef enum __nfpack GattCharacteristicProperties { GattCharacteristicProperties_None = 0, @@ -182,6 +288,13 @@ typedef enum __nfpack Utilities_GattNativeDescriptorUuid Utilities_GattNativeDescriptorUuid_TimeTriggerSetting = 10510, } Utilities_GattNativeDescriptorUuid; +typedef enum __nfpack Utilities_UuidType +{ + Utilities_UuidType_Uuid16 = 0, + Utilities_UuidType_Uuid32 = 1, + Utilities_UuidType_Uuid128 = 2, +} Utilities_UuidType; + struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_Buffer { static const int FIELD___buffer = 1; @@ -190,6 +303,22 @@ struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_Buffer //--// }; +struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_Advertisement_BluetoothLEAdvertisementDataSection +{ + static const int FIELD___dataType = 1; + static const int FIELD___buffer = 2; + + //--// +}; + +struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_DataReader +{ + static const int FIELD___buffer = 1; + static const int FIELD___currentReadPosition = 2; + + //--// +}; + struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_Advertisement_BluetoothLEAdvertisement { static const int FIELD___flags = 1; @@ -197,46 +326,48 @@ struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_Advertisement_B static const int FIELD___serviceUuids = 3; static const int FIELD___dataSections = 4; static const int FIELD___manufacturerData = 5; - static const int FIELD___rawUuids = 6; - static const int FIELD___rawManufacturerData = 7; + static const int FIELD___isConnectable = 6; + static const int FIELD___isDiscovable = 7; //--// }; -struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_Advertisement_BluetoothLEAdvertisementDataSection +struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_Advertisement_BluetoothLEAdvertisementBytePattern { static const int FIELD___dataType = 1; - static const int FIELD___buffer = 2; + static const int FIELD___data = 2; + static const int FIELD___offset = 3; //--// }; -struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_Advertisement_BluetoothLEAdvertisementReceivedEventArgs +struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_Advertisement_BluetoothLEAdvertisementFilter { - static const int FIELD___bluetoothAddress = 1; - static const int FIELD___bluetoothAddressType = 2; - static const int FIELD___advertisement = 3; - static const int FIELD___advertisementType = 4; - static const int FIELD___rawSignalStrengthInDBm = 5; - static const int FIELD___timestamp = 6; - - NANOCLR_NATIVE_DECLARE(NativeCreateFromEvent___BOOLEAN__I4); + static const int FIELD___advertisement = 1; + static const int FIELD___bytePatterns = 2; //--// }; struct - Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_Advertisement_BluetoothLEAdvertisementWatcherStoppedEventArgs + Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_Advertisement_BluetoothLEAdvertisementPublisherStatusChangedEventArgs { static const int FIELD___error = 1; + static const int FIELD___status = 2; + static const int FIELD___selectedTransmitPowerLevelInDBm = 3; //--// }; -struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_Advertisement_BluetoothLEManufacturerData +struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothNanoDevice { - static const int FIELD___data = 1; - static const int FIELD___companyId = 2; + static const int FIELD_STATIC___deviceName = 0; + static const int FIELD_STATIC___appearance = 1; + static const int FIELD_STATIC___mode = 2; + + NANOCLR_NATIVE_DECLARE(NativeInitilise___STATIC__VOID); + NANOCLR_NATIVE_DECLARE( + NativeSetOperationMode___STATIC__VOID__nanoFrameworkDeviceBluetoothBluetoothNanoDeviceMode__STRING__U2); //--// }; @@ -248,23 +379,15 @@ struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothDevice //--// }; -struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothEventCentral -{ - static const int FIELD__type = 3; - static const int FIELD__connectionHandle = 4; - static const int FIELD__status = 5; - static const int FIELD__serviceHandle = 6; - static const int FIELD__characteristicHandle = 7; - - //--// -}; - -struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothEventClient +struct + Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttributeProfile_GattLocalCharacteristicParameters { - static const int FIELD__type = 3; - static const int FIELD__id = 4; - static const int FIELD__characteristicId = 5; - static const int FIELD__descriptorId = 6; + static const int FIELD___writeProtectionLevel = 1; + static const int FIELD___readProtectionLevel = 2; + static const int FIELD___userDescription = 3; + static const int FIELD___properties = 4; + static const int FIELD___staticValue = 5; + static const int FIELD___presentationFormats = 6; //--// }; @@ -347,9 +470,21 @@ struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttribut //--// }; +struct + Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttributeProfile_GattSessionStatusChangedEventArgs +{ + static const int FIELD___status = 1; + static const int FIELD___bluetoothError = 2; + + //--// +}; + struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttributeProfile_GattSession { static const int FIELD___deviceId = 1; + static const int FIELD___maxMtuSize = 2; + static const int FIELD__SessionStatusChanged = 3; + static const int FIELD__MaxPduSizeChanged = 4; //--// }; @@ -370,7 +505,7 @@ struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttribut struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttributeProfile_GattLocalCharacteristic { - static const int FIELD_STATIC__GattLocalCharacteristicIndex = 0; + static const int FIELD_STATIC__GattLocalCharacteristicIndex = 3; static const int FIELD___characteristicId = 1; static const int FIELD___descriptorNextID = 2; @@ -394,14 +529,160 @@ struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttribut //--// }; -struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothNanoDevice +struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttributeProfile_GattLocalService { - static const int FIELD_STATIC___deviceName = 1; - static const int FIELD_STATIC___mode = 2; + static const int FIELD___serviceUuid = 1; + static const int FIELD___characteristics = 2; - NANOCLR_NATIVE_DECLARE(NativeInitilise___STATIC__VOID); + //--// +}; + +struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_DevicePairingResult +{ + static const int FIELD___protectionLevelUsed = 1; + static const int FIELD___status = 2; + + //--// +}; + +struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothEventSesssion +{ + static const int FIELD__type = 3; + static const int FIELD__connectionHandle = 4; + static const int FIELD__status = 5; + static const int FIELD__data = 6; + static const int FIELD__data32 = 7; + + //--// +}; + +struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_DevicePairingEventArgs +{ + static const int FIELD___connectionHandle = 1; + static const int FIELD___status = 2; + + //--// +}; + +struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_DevicePairingRequestedEventArgs +{ + static const int FIELD___pairing = 1; + static const int FIELD___connectionHandle = 2; + static const int FIELD___kind = 3; + static const int FIELD___pin = 4; + + NANOCLR_NATIVE_DECLARE(NativeAcceptYesNo___U2__U2__nanoFrameworkDeviceBluetoothDevicePairingKinds__I4); + NANOCLR_NATIVE_DECLARE(NativeAcceptPasskey___U2__U2__nanoFrameworkDeviceBluetoothDevicePairingKinds__I4); NANOCLR_NATIVE_DECLARE( - NativeSetOperationMode___STATIC__VOID__nanoFrameworkDeviceBluetoothBluetoothNanoDeviceMode__STRING); + NativeAcceptCredentials___U2__U2__nanoFrameworkDeviceBluetoothDevicePairingKinds__SZARRAY_U1__SZARRAY_U1); + + //--// +}; + +struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_DevicePairing +{ + static const int FIELD___device = 1; + static const int FIELD___server = 2; + static const int FIELD___completedEvent = 3; + static const int FIELD___canPair = 4; + static const int FIELD___isPaired = 5; + static const int FIELD___isAuthenticated = 6; + static const int FIELD___isSecure = 7; + static const int FIELD___ioCapabilities = 8; + static const int FIELD___protectionLevel = 9; + static const int FIELD___bondingAllowed = 10; + static const int FIELD___pairingStatus = 11; + static const int FIELD___outOfBand = 12; + static const int FIELD__PairingRequested = 13; + static const int FIELD__PairingComplete = 14; + + NANOCLR_NATIVE_DECLARE(NativeStartPair___U2__U2); + NANOCLR_NATIVE_DECLARE(NativeSetPairAttributes___VOID); + + //--// +}; + +struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothLEServer +{ + static const int FIELD_STATIC___instance = 4; + static const int FIELD_STATIC___lock = 5; + static const int FIELD_STATIC___bluetoothEventManager = 6; + static const int FIELD_STATIC___services = 7; + + static const int FIELD___disposedValue = 1; + static const int FIELD___pairing = 2; + static const int FIELD___session = 3; + + //--// +}; + +struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_Advertisement_BluetoothLEAdvertisementPublisher +{ + static const int FIELD_STATIC___advertisementInstance = 8; + + static const int FIELD___advertisement = 1; + static const int FIELD___status = 2; + static const int FIELD___useExtendedAdvertisement = 3; + static const int FIELD___includeTransmitPowerLevel = 4; + static const int FIELD___isAnonymous = 5; + static const int FIELD___preferredTransmitPowerLevelInDBm = 6; + static const int FIELD___dataNotFitInAdvertisement = 7; + static const int FIELD__StatusChanged = 8; + + NANOCLR_NATIVE_DECLARE(NativeStartLegacyAdvertising___BOOLEAN__SZARRAY_U1__SZARRAY_U1); + NANOCLR_NATIVE_DECLARE(NativeStartExtendedAdvertising___BOOLEAN__I2__SZARRAY_U1); + NANOCLR_NATIVE_DECLARE(NativeStopAdvertising___VOID); + NANOCLR_NATIVE_DECLARE(NativeIsExtendedAdvertisingAvailable___BOOLEAN); + + //--// +}; + +struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_Advertisement_BluetoothLEAdvertisementReceivedEventArgs +{ + static const int FIELD___bluetoothAddress = 1; + static const int FIELD___bluetoothAddressType = 2; + static const int FIELD___advertisement = 3; + static const int FIELD___advertisementType = 4; + static const int FIELD___rawSignalStrengthInDBm = 5; + static const int FIELD___timestamp = 6; + static const int FIELD___rawAdvertData = 7; + + NANOCLR_NATIVE_DECLARE(NativeCreateFromEvent___BOOLEAN__I4); + + //--// +}; + +struct + Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_Advertisement_BluetoothLEAdvertisementWatcherStoppedEventArgs +{ + static const int FIELD___error = 1; + + //--// +}; + +struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_Advertisement_BluetoothLEManufacturerData +{ + static const int FIELD___data = 1; + static const int FIELD___companyId = 2; + + //--// +}; + +struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothAddress +{ + static const int FIELD___address = 1; + static const int FIELD___addressType = 2; + + //--// +}; + +struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothEventCentral +{ + static const int FIELD__type = 3; + static const int FIELD__connectionHandle = 4; + static const int FIELD__status = 5; + static const int FIELD__serviceHandle = 6; + static const int FIELD__characteristicHandle = 7; //--// }; @@ -441,14 +722,6 @@ struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttribut //--// }; -struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_DataReader -{ - static const int FIELD___buffer = 1; - static const int FIELD___currentReadPosition = 2; - - //--// -}; - struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttributeProfile_GattDescriptorsResult { static const int FIELD___protocolError = 1; @@ -518,23 +791,26 @@ struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttribut struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothLEDevice { - static const int FIELD_STATIC___routingHandle = 3; + static const int FIELD_STATIC___routingHandle = 9; static const int FIELD___connectionStatus = 1; static const int FIELD___bluetoothAddress = 2; static const int FIELD___addressType = 3; static const int FIELD___name = 4; - static const int FIELD___connectionHandle = 5; - static const int FIELD___services = 6; - static const int FIELD___attributes = 7; - static const int FIELD___disposed = 8; - static const int FIELD___eventComplete = 9; - static const int FIELD___completedEvent = 10; - static const int FIELD__lockObj = 11; - static const int FIELD___eventValue = 12; - static const int FIELD___eventStatus = 13; - static const int FIELD__ConnectionStatusChanged = 14; - static const int FIELD__GattServicesChanged = 15; + static const int FIELD___appearance = 5; + static const int FIELD___connectionHandle = 6; + static const int FIELD___genericAccessRead = 7; + static const int FIELD___services = 8; + static const int FIELD___attributes = 9; + static const int FIELD___pairing = 10; + static const int FIELD___disposed = 11; + static const int FIELD___eventComplete = 12; + static const int FIELD___completedEvent = 13; + static const int FIELD__lockObj = 14; + static const int FIELD___eventValue = 15; + static const int FIELD___eventStatus = 16; + static const int FIELD__ConnectionStatusChanged = 17; + static const int FIELD__GattServicesChanged = 18; NANOCLR_NATIVE_DECLARE(NativeConnect___U2__U8__nanoFrameworkDeviceBluetoothBluetoothAddressType__U2); NANOCLR_NATIVE_DECLARE(NativeDisconnect___VOID__U2); @@ -549,39 +825,42 @@ struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothLEDevi //--// }; -struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothEventScan +struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothEventServer { static const int FIELD__type = 3; static const int FIELD__id = 4; + static const int FIELD__characteristicId = 5; + static const int FIELD__descriptorId = 6; //--// }; -struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothEventListener +struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothEventScan { - static const int FIELD_STATIC___characteristicMap = 4; - static const int FIELD_STATIC___leDeviceMap = 5; - static const int FIELD_STATIC___watcher = 6; - static const int FIELD_STATIC___watcherEvent = 7; - static const int FIELD_STATIC___watcherQueue = 8; + static const int FIELD__type = 3; + static const int FIELD__id = 4; //--// }; -struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothSignalStrengthFilter +struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothSignalStrengthFilter__ScanItem { - static const int FIELD___inRangeThresholdInDBm = 1; - static const int FIELD___outOfRangeThresholdInDBm = 2; - static const int FIELD___outOfRangeTimeout = 3; + static const int FIELD__Rssi = 1; + static const int FIELD__InRange = 2; + static const int FIELD__OutRangeTime = 3; + static const int FIELD__Active = 4; //--// }; -struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothLEAdvertisementWatcher__ScanItem +struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothSignalStrengthFilter { - static const int FIELD__rssi = 1; - static const int FIELD__inRange = 2; - static const int FIELD__outRangeTime = 3; + static const int FIELD___inRangeThresholdInDBm = 1; + static const int FIELD___outOfRangeThresholdInDBm = 2; + static const int FIELD___outOfRangeTimeout = 3; + static const int FIELD___scanCheck = 4; + static const int FIELD___scanResults = 5; + static const int FIELD___scanResultsLock = 6; //--// }; @@ -592,9 +871,8 @@ struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothLEAdve static const int FIELD___scanningMode = 2; static const int FIELD___advertisementFilter = 3; static const int FIELD___signalStrengthFilter = 4; - static const int FIELD___scanResults = 5; - static const int FIELD__Received = 6; - static const int FIELD__Stopped = 7; + static const int FIELD__Received = 5; + static const int FIELD__Stopped = 6; NANOCLR_NATIVE_DECLARE(NativeStartAdvertisementWatcher___VOID__I4); NANOCLR_NATIVE_DECLARE(NativeStopAdvertisementWatcher___VOID); @@ -602,15 +880,21 @@ struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothLEAdve //--// }; -struct - Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttributeProfile_GattLocalCharacteristicParameters +struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothEventListener { - static const int FIELD___writeProtectionLevel = 1; - static const int FIELD___readProtectionLevel = 2; - static const int FIELD___userDescription = 3; - static const int FIELD___properties = 4; - static const int FIELD___staticValue = 5; - static const int FIELD___presentationFormats = 6; + static const int FIELD_STATIC___server = 10; + static const int FIELD_STATIC___characteristicMap = 11; + static const int FIELD_STATIC___leDeviceMap = 12; + static const int FIELD_STATIC___watcher = 13; + static const int FIELD_STATIC___watcherEvent = 14; + static const int FIELD_STATIC___watcherQueue = 15; + + //--// +}; + +struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_DeviceUnpairingResult +{ + static const int FIELD___status = 1; //--// }; @@ -631,14 +915,6 @@ struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttribut //--// }; -struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttributeProfile_GattLocalService -{ - static const int FIELD___serviceUuid = 1; - static const int FIELD___characteristics = 2; - - //--// -}; - struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttributeProfile_GattReadClientCharacteristicConfigurationDescriptorResult { @@ -652,28 +928,30 @@ struct struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttributeProfile_GattServiceProviderAdvertisingParameters { - static const int FIELD___deviceName = 1; - static const int FIELD___isDiscoverable = 2; - static const int FIELD___isConnectable = 3; - static const int FIELD___serviceData = 4; + static const int FIELD___isDiscoverable = 1; + static const int FIELD___isConnectable = 2; + static const int FIELD___serviceData = 3; + static const int FIELD___advertisement = 4; + static const int FIELD___customAdvertisement = 5; //--// }; -struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttributeProfile_GattServiceProvider +struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_Utilities { - static const int FIELD_STATIC___bluetoothEventManager = 9; + static const int FIELD_STATIC__baseUuid = 16; - static const int FIELD___services = 1; - static const int FIELD___status = 2; - static const int FIELD___deviceName = 3; - static const int FIELD___isDiscoverable = 4; - static const int FIELD___isConnectable = 5; - static const int FIELD___serviceData = 6; + //--// +}; - NANOCLR_NATIVE_DECLARE(NativeInitService___BOOLEAN); - NANOCLR_NATIVE_DECLARE(NativeStartAdvertising___BOOLEAN); - NANOCLR_NATIVE_DECLARE(NativeStopAdvertising___VOID); +struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttributeProfile_GattServiceProvider +{ + static const int FIELD___status = 1; + static const int FIELD___service = 2; + static const int FIELD___publisher = 3; + + NANOCLR_NATIVE_DECLARE(NativeInitializeServiceConfig___BOOLEAN__SystemCollectionsArrayList); + NANOCLR_NATIVE_DECLARE(NativeDisposeServiceConfig___VOID); //--// }; @@ -686,6 +964,25 @@ struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttribut //--// }; +struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_PasswordCredential +{ + static const int FIELD___username = 1; + static const int FIELD___password = 2; + + //--// +}; + +struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_Security_DeviceBonding +{ + NANOCLR_NATIVE_DECLARE(IsBonded___STATIC__BOOLEAN__U8); + NANOCLR_NATIVE_DECLARE(DeleteAllBonds___STATIC__VOID); + NANOCLR_NATIVE_DECLARE(DeleteBondForPeer___STATIC__VOID__U8__nanoFrameworkDeviceBluetoothBluetoothAddressType); + NANOCLR_NATIVE_DECLARE(Count___STATIC__I4); + NANOCLR_NATIVE_DECLARE(GetBondInformationAt___STATIC__U8__I4); + + //--// +}; + struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_Spp_SppReceivedDataEventArgs { static const int FIELD___data = 1; @@ -709,11 +1006,15 @@ struct Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_Spp_NordicSpp struct Library_sys_dev_ble_native_ThisAssembly { - static const int FIELD_STATIC__GitCommitDate = 10; + static const int FIELD_STATIC__GitCommitDate = 17; //--// }; extern const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Device_Bluetooth; +#include "sys_ble.h" + +// clang-format on + #endif //_SYS_DEV_BLE_NATIVE_H_ diff --git a/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothLEAdvertisementWatcher.cpp b/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothLEAdvertisementWatcher.cpp index b0981d1fa9..81b1357ee3 100644 --- a/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothLEAdvertisementWatcher.cpp +++ b/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothLEAdvertisementWatcher.cpp @@ -5,7 +5,6 @@ // #include "sys_dev_ble_native.h" -//#include "ble_gap.h" #define BluetoothLEAdvertisement \ Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_Advertisement_BluetoothLEAdvertisement @@ -21,7 +20,7 @@ void BleCentralStartScan() struct ble_gap_disc_params disc_params; int rc; - /* Figure out address to use while advertising (no privacy for now) */ + // Figure out address to use while advertising (no privacy for now) rc = ble_hs_id_infer_auto(0, &own_addr_type); if (rc != 0) { @@ -35,16 +34,16 @@ void BleCentralStartScan() // Perform an active or passive scan disc_params.passive = bleScanActive ? 0 : 1; + disc_params.passive = 0; + // Use defaults for the rest of the parameters. - disc_params.itvl = 0; - disc_params.window = 0; - disc_params.filter_policy = 0; + disc_params.itvl = 0; // defaults to BLE_GAP_SCAN_FAST_INTERVAL_MIN(30ms) + disc_params.window = 0; // defaults to BLE_GAP_SCAN_FAST_WINDOW(30ms) + disc_params.filter_policy = BLE_HCI_SCAN_FILT_NO_WL; disc_params.limited = 0; rc = ble_gap_disc(own_addr_type, BLE_HS_FOREVER, &disc_params, Esp32GapEvent, NULL); - BLE_DEBUG_PRINTF("ble_gap_disc; reason=%d active %d\n", rc, ble_gap_disc_active()); - if (rc != 0) { BLE_DEBUG_PRINTF("Error initiating GAP discovery procedure; rc=%d\n", rc); @@ -95,164 +94,55 @@ Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_Advertisement_Bluetoot { bool result = false; CLR_UINT8 *buffer; - int uuidIndex; // ptr to BluetoothLEAdvertisementReceivedEventArgs object CLR_RT_HeapBlock *pThis = stack.This(); - CLR_RT_HeapBlock *pAdvert; FAULT_ON_NULL(pThis); // Eventid CLR_INT32 eventID = stack.Arg1().NumericByRef().s4; + BLE_DEBUG_PRINTF( + "NativeCreateFromEvent eventid::%d ble_event:%d event:%X\n", + eventID, + ble_event_data.eventId, + ble_event_data.gapEvent); + // Get access to Event data if (LockEventMutex()) { + // Event ID correct if (ble_event_data.eventId == eventID) { - - // Event ID correct - int rc; - ble_hs_adv_fields fields; struct ble_gap_event *gEvent = ble_event_data.gapEvent; - rc = ble_hs_adv_parse_fields(&fields, gEvent->disc.data, gEvent->disc.length_data); - if (rc == 0) - { - // Fill in BluetoothLEAdvertisementReceivedEventArgs fields from event data - BLE_DEBUG_PRINTF("Watch rssi:%d type:%d adr:", gEvent->disc.rssi, gEvent->disc.addr.type); - PrintBytes(gEvent->disc.addr.val, 6); - BLE_DEBUG_PRINTF("\n"); - - pThis[FIELD___bluetoothAddress].NumericByRef().u8 = BleAddressToUlong(gEvent->disc.addr.val); - pThis[FIELD___bluetoothAddressType].NumericByRef().u1 = gEvent->disc.addr.type; - - pThis[FIELD___advertisementType].NumericByRef().s4 = (int)gEvent->disc.event_type; - pThis[FIELD___rawSignalStrengthInDBm].NumericByRef().s2 = (int16_t)gEvent->disc.rssi; - - // Get reference to BluetoothLEAdvertisement object - pAdvert = pThis[FIELD___advertisement].Dereference(); - - // Fill in BluetoothLEAdvertisement fields - // Set localname - if (fields.name != 0) - { - // Create a null terminated string - char *pname = (char *)platform_malloc(fields.name_len + 1); - memcpy(pname, fields.name, fields.name_len); - pname[fields.name_len] = 0; - - NANOCLR_CHECK_HRESULT(CLR_RT_HeapBlock_String::CreateInstance( - pAdvert[BluetoothLEAdvertisement::FIELD___localName], - (const char *)pname)); - - platform_free(pname); - } - BLE_DEBUG_PRINTF("local Name %X len %d", fields.name, fields.name_len); - - // == Service UUIDs ==== - // Create Array of all UUID 16bit, UUID 32 bit & UUID 128bit as 16 byte GUID in byte buffer - // Create array byte the correct size to hold all service UUID in advert. - uuidIndex = (fields.num_uuids16 + fields.num_uuids32 + fields.num_uuids128) * 16; + BLE_DEBUG_PRINTF("Advert data length:%d ", (int)gEvent->disc.length_data); + PrintBytes((uint8_t *)gEvent->disc.data, gEvent->disc.length_data); + BLE_DEBUG_PRINTF("\n"); - NANOCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance( - pAdvert[BluetoothLEAdvertisement::FIELD___rawUuids], - uuidIndex, - g_CLR_RT_WellKnownTypes.m_UInt8)); - buffer = pAdvert[BluetoothLEAdvertisement::FIELD___rawUuids].DereferenceArray()->GetFirstElement(); + // Fill in BluetoothLEAdvertisementReceivedEventArgs fields from event data + BLE_DEBUG_PRINTF("Watch rssi:%d type:%d adr:", gEvent->disc.rssi, gEvent->disc.addr.type); + PrintBytes(gEvent->disc.addr.val, 6); + BLE_DEBUG_PRINTF("\n"); - // Add UUID 16 bit to buffer - uuidIndex = fields.num_uuids16; - ble_uuid16_t *uuid16 = (ble_uuid16_t *)fields.uuids16; - while (uuidIndex) - { - BLE_DEBUG_PRINTF("adv uuid16 %X \n", uuid16->value); - // Convert to 128 bit UUID (16 byte) - NimbleUUID16ToGuid(uuid16, buffer); + pThis[FIELD___bluetoothAddress].NumericByRef().u8 = BleAddressToUlong(gEvent->disc.addr.val); + pThis[FIELD___bluetoothAddressType].NumericByRef().u1 = gEvent->disc.addr.type; -#if defined(NANO_BLE_DEBUG) - BLE_DEBUG_PRINTF("adv guuid\n"); - for (int i = 0; i <= 15; i++) - { - BLE_DEBUG_PRINTF("%X ", buffer[i]); - } - BLE_DEBUG_PRINTF("\n"); -#endif - // Next UUID 16 - uuidIndex--; - uuid16++; - buffer += 16; - } + pThis[FIELD___advertisementType].NumericByRef().s4 = (int)gEvent->disc.event_type; + pThis[FIELD___rawSignalStrengthInDBm].NumericByRef().s2 = (int16_t)gEvent->disc.rssi; - // Add UUID 32 bit to buffer - uuidIndex = fields.num_uuids32; - ble_uuid32_t *uuid32 = (ble_uuid32_t *)fields.uuids32; - while (uuidIndex) - { - BLE_DEBUG_PRINTF("adv uuid32 %X \n", uuid32->value); - // Convert to 128 bit UUID (16 byte) - NimbleUUID32ToGuid(uuid32, buffer); + // Return raw advert data bytes in _rawAdvertData field + NANOCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance( + pThis[FIELD___rawAdvertData], + gEvent->disc.length_data, + g_CLR_RT_WellKnownTypes.m_UInt8)); - BLE_DEBUG_PRINTF("adv guuid\n"); - for (int i = 0; i <= 15; i++) - { - BLE_DEBUG_PRINTF("%X ", buffer[i]); - } - BLE_DEBUG_PRINTF("\n"); + buffer = pThis[FIELD___rawAdvertData].DereferenceArray()->GetFirstElement(); + memcpy(buffer, gEvent->disc.data, gEvent->disc.length_data); + result = true; - // Next UUID 32 - uuidIndex--; - uuid32++; - buffer += 16; - } - - // Add UUID 128 bit to buffer - uuidIndex = fields.num_uuids128; - ble_uuid128_t *uu128 = (ble_uuid128_t *)fields.uuids128; - while (uuidIndex) - { - BLE_DEBUG_PRINTF("adv uuid128 \n"); - - for (int i = 0; i <= 15; i++) - { - BLE_DEBUG_PRINTF("%X ", uu128->value[i]); - } - BLE_DEBUG_PRINTF("\n"); - - // Copy 128 bit UUID (16 byte) - NimbleUUID128ToGuid(uu128, buffer); - - BLE_DEBUG_PRINTF("adv guuid\n"); - for (int i = 0; i <= 15; i++) - { - BLE_DEBUG_PRINTF("%X ", buffer[i]); - } - BLE_DEBUG_PRINTF("\n"); - - // Next UUID 128 - uu128++; - uuidIndex--; - buffer += 16; - } - - // ==== Manufacturer Data ==== - NANOCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance( - pAdvert[BluetoothLEAdvertisement::FIELD___rawManufacturerData], - fields.mfg_data_len, - g_CLR_RT_WellKnownTypes.m_UInt8)); - - buffer = pAdvert[BluetoothLEAdvertisement::FIELD___rawManufacturerData] - .DereferenceArray() - ->GetFirstElement(); - memcpy(buffer, fields.mfg_data, fields.mfg_data_len); - - BLE_DEBUG_PRINTF("Manufacturer data %X len %d\n", fields.mfg_data, fields.mfg_data_len); - - result = true; - - // Signal BLE callback, event complete - xEventGroupSetBits(ble_event_waitgroup, N_BLE_EVENT_HANDLED); - } + // Signal BLE callback, event complete + xEventGroupSetBits(ble_event_waitgroup, N_BLE_EVENT_HANDLED); } ReleaseEventMutex(); @@ -261,4 +151,4 @@ Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_Advertisement_Bluetoot stack.SetResult_Boolean(result); } NANOCLR_NOCLEANUP(); -} +} \ No newline at end of file diff --git a/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothLEDevice.cpp b/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothLEDevice.cpp index 754b5ec777..8c970bfda6 100644 --- a/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothLEDevice.cpp +++ b/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothLEDevice.cpp @@ -255,6 +255,54 @@ int CentralGapEvent(struct ble_gap_event *event, void *arg) } break; + case BLE_GAP_EVENT_ENC_CHANGE: + { + struct ble_gap_conn_desc desc; + + int rc = ble_gap_conn_find(event->enc_change.conn_handle, &desc); + if (rc != 0) + { + return BLE_ATT_ERR_INVALID_HANDLE; + } + + uint16_t securityState = 0; + securityState += desc.sec_state.encrypted ? 1 : 0; + securityState += desc.sec_state.authenticated ? 2 : 0; + securityState += desc.sec_state.bonded ? 4 : 0; + + DevicePairingResultStatus pairingStatus = MapNimbleErrorToStatus(event->enc_change.status); + + BLE_DEBUG_PRINTF( + "BLE_GAP_EVENT_ENC_CHANGE conn_handle=%d status=%d security=%X\n", + event->enc_change.conn_handle, + event->enc_change.status, + securityState); + + PostManagedEvent( + EVENT_BLUETOOTH, + BluetoothEventType_AuthenticationComplete, + event->enc_change.conn_handle, + (securityState << 16) + pairingStatus); + } + break; + + case BLE_GAP_EVENT_PASSKEY_ACTION: + { + BLE_DEBUG_PRINTF( + "BLE_GAP_EVENT_PASSKEY_ACTION conn_handle=%d action=%d\n", + event->passkey.conn_handle, + event->passkey.params.action); + + if (PostAndWaitManagedGapEvent( + BluetoothEventType_PassKeyActions, + event->passkey.conn_handle, + PairingActionToDevicePairingKinds(event->passkey.params.action) << 16)) + { + BLE_DEBUG_PRINTF(" BluetoothEventType_PassKeyActions handled"); + } + } + break; + default: break; } @@ -406,6 +454,7 @@ HRESULT Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothLEDev } NANOCLR_NOCLEANUP_NOLABEL(); } + // ======== Services ================ // @@ -657,7 +706,10 @@ HRESULT Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttribu uint8_t *guid = chrUuidArray->GetFirstElement(); NimbleUUIDToGuid(&characteristic->uuid, guid); +#if defined(NANO_BLE_DEBUG) + PrintUuid((const ble_uuid_t *)&characteristic->uuid); BLE_DEBUG_PRINTF("NativeUpdateCharacteristic update complete\n"); +#endif // Signal BLE callback, event complete xEventGroupSetBits(ble_event_waitgroup, N_BLE_EVENT_HANDLED); @@ -665,6 +717,19 @@ HRESULT Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttribu NANOCLR_NOCLEANUP(); } +uint16_t ConvertReadWriteStatus(uint16_t status) +{ + switch (status) + { + case 0: + return BluetoothLEDevice_readWriteValueResult_success; + case 5: + return BluetoothLEDevice_readWriteValueResult_acessDenied; + default: + return BluetoothLEDevice_readWriteValueResult_failure; + } +} + static int ReadCharCallback( uint16_t conn_handle, const struct ble_gatt_error *error, @@ -672,18 +737,20 @@ static int ReadCharCallback( void *arg) { central_context *con = (central_context *)arg; + uint16_t result = ConvertReadWriteStatus(error->status); if (error->status == 0) { BLE_DEBUG_PRINTF( - "Read complete; status=%d conn_handle=%d handle:%d\n", + "Read complete; status=%d conn_handle=%d handle:%d result=%d\n", error->status, conn_handle, - attr->handle); + attr->handle, + result); } else { - BLE_DEBUG_PRINTF("Read complete; status=%d conn_handle=%d\n", error->status, conn_handle); + BLE_DEBUG_PRINTF("Read complete; status=%d conn_handle=%d result=%d\n", error->status, conn_handle, result); } // Save ble_gatt_attr for use in NativeReadValue @@ -698,22 +765,16 @@ static int ReadCharCallback( if (PostAndWaitCentralEvent( BluetoothEventType_AttributeReadValueComplete, conn_handle, - error->status, + result, con->serviceHandle, attr->handle)) { - // TODO ? BLE_DEBUG_PRINTF("Read complete handled\n"); } } else { - PostCentralEvent( - BluetoothEventType_AttributeReadValueComplete, - conn_handle, - error->status, - con->serviceHandle, - 0); + PostCentralEvent(BluetoothEventType_AttributeReadValueComplete, conn_handle, result, con->serviceHandle, 0); } return 0; @@ -747,7 +808,7 @@ HRESULT Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothLEDev } } - stack.SetResult_U2(rc); + stack.SetResult_U2(ConvertReadWriteStatus(rc)); } NANOCLR_NOCLEANUP_NOLABEL(); } @@ -789,19 +850,20 @@ static int WriteCharWithResponseCallback( struct ble_gatt_attr *attr, void *arg) { - central_context *con = (central_context *)arg; + uint16_t result = ConvertReadWriteStatus(error->status); BLE_DEBUG_PRINTF( - "Write complete; status=%d conn_handle=%d attr_handle=%d\n", + "Write complete; status=%d conn_handle=%d attr_handle=%d result=%d\n", error->status, conn_handle, - attr->handle); + attr->handle, + result); PostCentralEvent( BluetoothEventType_AttributeWriteValueComplete, conn_handle, - error->status, + result, con->serviceHandle, attr->handle); diff --git a/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothNanoDevice.cpp b/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothNanoDevice.cpp index 807acba542..753ff7055e 100644 --- a/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothNanoDevice.cpp +++ b/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothNanoDevice.cpp @@ -9,7 +9,21 @@ BluetoothNanoDevice_Mode ble_operatingMode = BluetoothNanoDevice_Mode_NotRunning char *bleDeviceName = NULL; -void SetDeviceName(char *deviceName) +void UpdateNameInContext() +{ + if (bleContext.pDeviceName) + { + platform_free((void *)bleContext.pDeviceName); + } + + size_t nlen = hal_strlen_s(bleDeviceName); + + bleContext.pDeviceName = (char *)platform_malloc(nlen + 1); + memcpy(bleContext.pDeviceName, bleDeviceName, nlen); + bleContext.pDeviceName[nlen] = 0; +} + +void SetDeviceName(const char *deviceName) { if (bleDeviceName) { @@ -21,6 +35,8 @@ void SetDeviceName(char *deviceName) bleDeviceName = (char *)platform_malloc(nlen + 1); hal_strcpy_s(bleDeviceName, nlen + 1, deviceName); + + UpdateNameInContext(); } HRESULT Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothNanoDevice::NativeInitilise___STATIC__VOID( @@ -33,45 +49,59 @@ HRESULT Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothNanoD // Set default device name SetDeviceName((char *)defaultName); + if (ble_operatingMode != BluetoothNanoDevice_Mode_NotRunning) + { + StopBleStack(); + ble_operatingMode = BluetoothNanoDevice_Mode_NotRunning; + } + NANOCLR_NOCLEANUP_NOLABEL(); } HRESULT Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_BluetoothNanoDevice:: - NativeSetOperationMode___STATIC__VOID__nanoFrameworkDeviceBluetoothBluetoothNanoDeviceMode__STRING( + NativeSetOperationMode___STATIC__VOID__nanoFrameworkDeviceBluetoothBluetoothNanoDeviceMode__STRING__U2( CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); { + bool result = false; +#if defined(NANO_BLE_DEBUG) BluetoothNanoDevice_Mode last_operatingMode = ble_operatingMode; +#endif BluetoothNanoDevice_Mode newRunMode = (BluetoothNanoDevice_Mode)stack.Arg0().NumericByRef().u4; - char *deviceName = (char *)stack.Arg1().RecoverString(); + uint16_t appearance = stack.Arg2().NumericByRef().u2; SetDeviceName(deviceName); - ble_operatingMode = newRunMode; - - BLE_DEBUG_PRINTF("run mode %d/%d device name %s\n", ble_operatingMode, last_operatingMode, bleDeviceName); - - switch (ble_operatingMode) + if (ble_operatingMode != newRunMode) { - case BluetoothNanoDevice_Mode_NotRunning: - if (last_operatingMode == BluetoothNanoDevice_Mode_Client) - { - // Only close stack when running in CLient mode - Device_ble_dispose(); - } - break; - - case BluetoothNanoDevice_Mode_Server: - // Stack started in Servic provider , start advertising - break; - - case BluetoothNanoDevice_Mode_Client: - StartStack(deviceName); - break; + ble_operatingMode = newRunMode; + + BLE_DEBUG_PRINTF("run mode %d/%d device name %s\n", ble_operatingMode, last_operatingMode, bleDeviceName); + switch (ble_operatingMode) + { + case BluetoothNanoDevice_Mode_NotRunning: + result = StopBleStack(); + break; + + case BluetoothNanoDevice_Mode_Server: + case BluetoothNanoDevice_Mode_Client: + result = StartBleStack(deviceName, appearance); + break; + } + + if (!result) + { + BLE_DEBUG_PRINTF( + "run mode %d/%d device name %s\n", + ble_operatingMode, + last_operatingMode, + bleDeviceName); + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } } } - NANOCLR_NOCLEANUP_NOLABEL(); -} + NANOCLR_NOCLEANUP(); +} \ No newline at end of file diff --git a/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttributeProfile_GattLocalCharacteristic.cpp b/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttributeProfile_GattLocalCharacteristic.cpp index eddfb63b8f..245e6d960d 100644 --- a/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttributeProfile_GattLocalCharacteristic.cpp +++ b/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttributeProfile_GattLocalCharacteristic.cpp @@ -49,4 +49,4 @@ HRESULT Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttribu stack.SetResult_I4(rc); } NANOCLR_NOCLEANUP(); -} +} \ No newline at end of file diff --git a/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttributeProfile_GattReadRequest.cpp b/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttributeProfile_GattReadRequest.cpp index 2c7ab1d976..390273bd56 100644 --- a/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttributeProfile_GattReadRequest.cpp +++ b/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttributeProfile_GattReadRequest.cpp @@ -68,4 +68,4 @@ HRESULT Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttribu } } NANOCLR_NOCLEANUP_NOLABEL(); -} +} \ No newline at end of file diff --git a/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttributeProfile_GattServiceProvider.cpp b/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttributeProfile_GattServiceProvider.cpp index 353c70abcc..fb23ac49d4 100644 --- a/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttributeProfile_GattServiceProvider.cpp +++ b/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttributeProfile_GattServiceProvider.cpp @@ -8,10 +8,14 @@ extern bool DeviceBleInit(); extern void Device_ble_dispose(); -extern int DeviceBleStart(bleServicesContext &context); extern int DeviceBleCallback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg); - -extern void Esp32BleStartAdvertise(bleServicesContext *context); +extern void SetSecuritySettings( + DevicePairingIOCapabilities IOCaps, + DevicePairingProtectionLevel protectionLevel, + bool allowBonding, + bool allowOob); +extern bool Esp32BleStartAdvertise(bleServicesContext *context); +extern void UpdateNameInContext(); extern const struct ble_gatt_chr_def gatt_char_device_info[]; @@ -25,6 +29,10 @@ typedef Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttribu GattPresentationFormat; typedef Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttributeProfile_GattLocalDescriptor GattLocalDescriptor; +typedef Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_Advertisement_BluetoothLEAdvertisement + BluetoothLEAdvertisement; +typedef Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_Advertisement_BluetoothLEAdvertisementPublisher + BluetoothLEAdvertisementPublisher; bleServicesContext bleContext; @@ -35,6 +43,18 @@ static void InitContext(bleServicesContext *context) static void FreeContext(bleServicesContext &srvContext) { + if (srvContext.advertData) + { + platform_free((void *)srvContext.advertData); + srvContext.advertData = NULL; + } + + if (srvContext.scanResponse) + { + platform_free((void *)srvContext.scanResponse); + srvContext.scanResponse = NULL; + } + if (srvContext.pDeviceName) { platform_free((void *)srvContext.pDeviceName); @@ -88,6 +108,8 @@ static void FreeContext(bleServicesContext &srvContext) } } + srvContext.serviceCount = 0; + if (srvContext.bleSrvContexts) { platform_free((void *)srvContext.bleSrvContexts); @@ -95,30 +117,6 @@ static void FreeContext(bleServicesContext &srvContext) } } -HRESULT Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttributeProfile_GattServiceProvider:: - NativeInitService___BOOLEAN(CLR_RT_StackFrame &stack) -{ - (void)stack; - - NANOCLR_HEADER(); - { - InitContext(&bleContext); - - stack.SetResult_Boolean(true); - } - NANOCLR_NOCLEANUP_NOLABEL(); -} - -/* -ble_uuid_t *Ble_uuid16_declare(uint16_t id16) -{ - ble_uuid16_t *pU16 = (ble_uuid16_t *)platform_malloc(sizeof(ble_uuid16_t)); - pU16->u.type = BLE_UUID_TYPE_16; - pU16->value = id16; - return (ble_uuid_t *)pU16; -} -*/ - // Assumes UUID is 16 bytes length void BuildUUID(uint8_t *pUuid, ble_uuid_any_t *pUany) { @@ -394,13 +392,13 @@ bool ParseAndBuildNimbleDefinition(ble_context &context, CLR_RT_HeapBlock *pGatt // Allocate tables context.descriptorDefs = (ble_gatt_dsc_def *)platform_malloc(sizeof(ble_gatt_dsc_def) * descriptorCount); - if (context.descriptorDefs == NULL) + if (context.descriptorDefs == NULL && descriptorCount != 0) { // Out of memory return false; } context.descriptorUuids = (ble_uuid_any_t *)platform_malloc(sizeof(ble_uuid_any_t) * descriptorCount); - if (context.descriptorUuids == NULL) + if (context.descriptorUuids == NULL && descriptorCount != 0) { // Out of memory return false; @@ -637,37 +635,24 @@ void PrintSvrDefs(ble_gatt_svc_def *svcDef) #endif HRESULT Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttributeProfile_GattServiceProvider:: - NativeStartAdvertising___BOOLEAN(CLR_RT_StackFrame &stack) + NativeInitializeServiceConfig___BOOLEAN__SystemCollectionsArrayList(CLR_RT_StackFrame &stack) { - bool result = false; + bool result = true; NANOCLR_HEADER(); { - CLR_RT_HeapBlock_ArrayList *pArrayServices; - int deviceNameLen; - + CLR_RT_HeapBlock_ArrayList *pArrayServiceProviders; CLR_RT_HeapBlock *pThis = stack.This(); // ptr to GattServiceProvider FAULT_ON_NULL(pThis); - // Save Discoverable & Connectable flags in context - bool isDiscoverable = pThis[GattServiceProvider::FIELD___isDiscoverable].NumericByRef().s4 != 0; - bool isConnectable = pThis[GattServiceProvider::FIELD___isConnectable].NumericByRef().s4 != 0; - - bleContext.isDiscoverable = isDiscoverable; - bleContext.isConnectable = isConnectable; - - // Save Device name in context - CLR_RT_HeapBlock_Array *pDeviceNameField = - (CLR_RT_HeapBlock_Array *)pThis[GattServiceProvider::FIELD___deviceName].Array(); - char *pDeviceName = (char *)pDeviceNameField->GetFirstElement(); - deviceNameLen = pDeviceNameField->m_numOfElements; + InitContext(&bleContext); - bleContext.pDeviceName = (char *)platform_malloc(deviceNameLen + 1); - memcpy(bleContext.pDeviceName, pDeviceName, deviceNameLen); - bleContext.pDeviceName[deviceNameLen] = 0; + UpdateNameInContext(); - pArrayServices = (CLR_RT_HeapBlock_ArrayList *)pThis[GattServiceProvider::FIELD___services].Dereference(); - bleContext.serviceCount = pArrayServices->GetSize(); + // Pick up passed ArrayList of Services and get service count + pArrayServiceProviders = (CLR_RT_HeapBlock_ArrayList *)stack.Arg1().Dereference(); + FAULT_ON_NULL_ARG(pArrayServiceProviders); + bleContext.serviceCount = pArrayServiceProviders->GetSize(); // Allocate contexts for all service definitions size_t bleContextSize = sizeof(ble_context) * bleContext.serviceCount; @@ -680,12 +665,17 @@ HRESULT Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttribu memset(bleContext.bleSrvContexts, 0, bleContextSize); // Foreach Service set up the Nimble definitions - CLR_RT_HeapBlock *serviceItem; + CLR_RT_HeapBlock *serviceProviderItem; + CLR_RT_HeapBlock *localServiceItem; for (int i = 0; i < bleContext.serviceCount; i++) { - if (SUCCEEDED(pArrayServices->GetItem(i, serviceItem))) + // Get serviceProvider by index + if (SUCCEEDED(pArrayServiceProviders->GetItem(i, serviceProviderItem))) { - if (!ParseAndBuildNimbleDefinition(bleContext.bleSrvContexts[i], serviceItem)) + // Get associatted local server object + localServiceItem = serviceProviderItem[GattServiceProvider::FIELD___service].Dereference(); + + if (!ParseAndBuildNimbleDefinition(bleContext.bleSrvContexts[i], localServiceItem)) { NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_MEMORY); } @@ -706,19 +696,34 @@ HRESULT Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttribu #ifdef NANO_BLE_DEBUG // PrintSvrDefs(bleContext.gatt_service_def); #endif - result = DeviceBleInit(); - if (!result) - { - NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_MEMORY); - } - result = (DeviceBleStart(bleContext) == 0); + // Set Service definitions in nimble + ble_svc_gap_init(); + ble_svc_gatt_init(); - // Wait for stack to start - // Otherwise you will have problems if Stop is called straight away before stack has started - if (WaitForBleStackStart(5000)) + int rc = ble_gatts_count_cfg(bleContext.gatt_service_def); + BLE_DEBUG_PRINTF("ble_gatts_count_cfg -> %d\n", rc); + if (rc != 0) { - BLE_DEBUG_PRINTF("Stack start signaled\n"); + BLE_DEBUG_PRINTF("ble_gatts_count_cfg failed %d\n", rc); + result = false; + } + else + { + rc = ble_gatts_add_svcs(bleContext.gatt_service_def); + BLE_DEBUG_PRINTF("ble_gatts_add_svcs -> %d\n", rc); + if (rc != 0) + { + BLE_DEBUG_PRINTF("ble_gatts_add_svcs failed %d\n", rc); + result = false; + } + + rc = ble_gatts_start(); + if (rc != 0) + { + BLE_DEBUG_PRINTF("ble_gatts_start failed %d\n", rc); + result = false; + } } stack.SetResult_Boolean(result); @@ -728,7 +733,6 @@ HRESULT Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttribu if (!result) { - Device_ble_dispose(); FreeContext(bleContext); } @@ -736,19 +740,107 @@ HRESULT Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttribu } HRESULT Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttributeProfile_GattServiceProvider:: - NativeStopAdvertising___VOID(CLR_RT_StackFrame &stack) + NativeDisposeServiceConfig___VOID(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + { + BLE_DEBUG_PRINTF("GattServiceProvider: NativeDisposeServiceConfig context:%X\n", bleContext); + FreeContext(bleContext); + } + NANOCLR_NOCLEANUP_NOLABEL(); +} + +HRESULT Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_Advertisement_BluetoothLEAdvertisementPublisher:: + NativeStartLegacyAdvertising___BOOLEAN__SZARRAY_U1__SZARRAY_U1(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + { + uint8_t *advertData; + uint8_t *scanResponse; + + CLR_RT_HeapBlock *pThis = stack.This(); // ptr to BluetoothLEAdvertisementPublisher object + FAULT_ON_NULL(pThis); + + CLR_RT_HeapBlock *pAdvert = pThis[BluetoothLEAdvertisementPublisher::FIELD___advertisement].Dereference(); + FAULT_ON_NULL(pAdvert); + + bleContext.isConnectable = (bool)pAdvert[BluetoothLEAdvertisement::FIELD___isConnectable].NumericByRef().u1; + bleContext.isDiscoverable = (bool)pAdvert[BluetoothLEAdvertisement::FIELD___isDiscovable].NumericByRef().u1; + BLE_DEBUG_PRINTF( + "NativeStartLegacyAdvertising isConnectable=%d isDiscoverable=%d\n", + bleContext.isConnectable, + bleContext.isDiscoverable); + + CLR_RT_HeapBlock_Array *pAdvertData = stack.Arg1().DereferenceArray(); + FAULT_ON_NULL(pAdvertData); + CLR_RT_HeapBlock_Array *pScanResonse = stack.Arg2().DereferenceArray(); + FAULT_ON_NULL(pScanResonse); + + advertData = pAdvertData->GetElement(0); + bleContext.advertDataLen = pAdvertData->m_numOfElements; + scanResponse = pScanResonse->GetElement(0); + bleContext.scanResponseLen = pScanResonse->m_numOfElements; + + if (bleContext.advertDataLen) + { + bleContext.advertData = (uint8_t *)platform_malloc(bleContext.advertDataLen); + memcpy(bleContext.advertData, advertData, bleContext.advertDataLen); + } + + if (bleContext.scanResponseLen) + { + bleContext.scanResponse = (uint8_t *)platform_malloc(bleContext.scanResponseLen); + memcpy(bleContext.scanResponse, scanResponse, bleContext.scanResponseLen); + } + + bleContext.useExtendedAdvert = + (bool)pThis[BluetoothLEAdvertisementPublisher::FIELD___useExtendedAdvertisement].NumericByRef().u1; + + // Start advertisement using bleContext + stack.SetResult_Boolean(Esp32BleStartAdvertise(&bleContext)); + } + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_Advertisement_BluetoothLEAdvertisementPublisher:: + NativeStartExtendedAdvertising___BOOLEAN__I2__SZARRAY_U1(CLR_RT_StackFrame &stack) { - (void)stack; + NANOCLR_HEADER(); + + // TODO - Will implement with ESP32 Bluetooth 5.0 targets + NANOCLR_SET_AND_LEAVE(stack.NotImplementedStub()); + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_Advertisement_BluetoothLEAdvertisementPublisher:: + NativeStopAdvertising___VOID(CLR_RT_StackFrame &stack) +{ NANOCLR_HEADER(); { - BLE_DEBUG_PRINTF("Server: Stop Advertising\n"); + BLE_DEBUG_PRINTF("Server: Stop Advertising context:%X\n", bleContext); ble_gap_adv_stop(); - Device_ble_dispose(); - FreeContext(bleContext); } NANOCLR_NOCLEANUP_NOLABEL(); } + +HRESULT Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_Advertisement_BluetoothLEAdvertisementPublisher:: + NativeIsExtendedAdvertisingAvailable___BOOLEAN(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + { + bool result = false; + +// return true if running on Bluetooth 5 capable platform ESP32-C3 / ESP32-S3 etc +// with extended advertisement support +#ifdef CONFIG_BT_NIMBLE_EXT_ADV + result = true; +#endif + + stack.SetResult_Boolean(result); + } + NANOCLR_NOCLEANUP_NOLABEL(); +} \ No newline at end of file diff --git a/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttributeProfile_GattWriteRequest.cpp b/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttributeProfile_GattWriteRequest.cpp index 9ae00570fa..c1251e40c5 100644 --- a/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttributeProfile_GattWriteRequest.cpp +++ b/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttributeProfile_GattWriteRequest.cpp @@ -105,4 +105,4 @@ HRESULT Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_GenericAttribu } } NANOCLR_NOCLEANUP_NOLABEL(); -} +} \ No newline at end of file diff --git a/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/sys_dev_ble_native_nanoFramework_Device_Bluetooth_Security.cpp b/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/sys_dev_ble_native_nanoFramework_Device_Bluetooth_Security.cpp new file mode 100644 index 0000000000..8e9fcfcd09 --- /dev/null +++ b/targets/ESP32/_nanoCLR/nanoFramework.Device.Bluetooth/sys_dev_ble_native_nanoFramework_Device_Bluetooth_Security.cpp @@ -0,0 +1,282 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Portions Copyright (c) Microsoft Corporation. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +#include "sys_dev_ble_native.h" + +HRESULT Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_DevicePairing::NativeStartPair___U2__U2( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + { + BLE_DEBUG_PRINTF("NativeStartPair\n"); + + ushort conn_handle = stack.Arg1().NumericByRef().u2; + + BLE_DEBUG_PRINTF( + "NativeStartPair security iocaps:%d sc:%d mi:%d bd:%d ob:%d\n", + ble_hs_cfg.sm_io_cap, + ble_hs_cfg.sm_sc, + ble_hs_cfg.sm_mitm, + ble_hs_cfg.sm_bonding, + ble_hs_cfg.sm_oob_data_flag); + + int rc = ble_gap_security_initiate(conn_handle); + + BLE_DEBUG_PRINTF("NativeStartPair conn:%d %d\n", conn_handle, rc); + + stack.SetResult_U2((ushort)rc); + } + NANOCLR_NOCLEANUP_NOLABEL(); +} + +HRESULT Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_DevicePairing::NativeSetPairAttributes___VOID( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + { + CLR_RT_HeapBlock *pThis = stack.This(); // ptr to DevicePairing + FAULT_ON_NULL(pThis); + + DevicePairingIOCapabilities IOCaps = + (DevicePairingIOCapabilities) + pThis[Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_DevicePairing::FIELD___ioCapabilities] + .NumericByRef() + .s4; + DevicePairingProtectionLevel protectionLevel = + (DevicePairingProtectionLevel) + pThis[Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_DevicePairing::FIELD___protectionLevel] + .NumericByRef() + .s4; + bool allowBonding = + pThis[Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_DevicePairing::FIELD___bondingAllowed] + .NumericByRef() + .s4 != 0; + bool allowOob = + pThis[Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_DevicePairing::FIELD___outOfBand] + .NumericByRef() + .s4 != 0; + + SetSecuritySettings(IOCaps, protectionLevel, allowBonding, allowOob); + } + NANOCLR_NOCLEANUP(); +} + +void AcceptHelper(CLR_RT_StackFrame &stack, bool passkey) +{ + struct ble_sm_io pkey = {0, 0}; + + ushort conn_handle = stack.Arg1().NumericByRef().u2; + pkey.action = DevicePairingKindsToPairingAction((DevicePairingKinds)stack.Arg2().NumericByRef().s4); + uint32_t arg3 = stack.Arg3().NumericByRef().s4; + + if (passkey) + { + pkey.passkey = arg3; + } + else + { + pkey.numcmp_accept = (uint8_t)arg3; + } + + int rc = ble_sm_inject_io(conn_handle, &pkey); + + BLE_DEBUG_PRINTF( + "NativeAccept con=%d DevicePairingKinds=%d => action=%d rc=%d)\n", + conn_handle, + stack.Arg2().NumericByRef().s4, + pkey.action, + rc); + if (passkey) + { + BLE_DEBUG_PRINTF("NativeAcceptPasskey passkey=%d)\n", pkey.passkey); + } + + stack.SetResult_U2((ushort)rc); + + // Signal BLE callback, event complete + xEventGroupSetBits(ble_event_waitgroup, N_BLE_EVENT_HANDLED); +} + +HRESULT Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_DevicePairingRequestedEventArgs:: + NativeAcceptYesNo___U2__U2__nanoFrameworkDeviceBluetoothDevicePairingKinds__I4(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + { + AcceptHelper(stack, false); + } + NANOCLR_NOCLEANUP_NOLABEL(); +} + +HRESULT Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_DevicePairingRequestedEventArgs:: + NativeAcceptPasskey___U2__U2__nanoFrameworkDeviceBluetoothDevicePairingKinds__I4(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + { + AcceptHelper(stack, true); + } + NANOCLR_NOCLEANUP_NOLABEL(); +} + +HRESULT Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_DevicePairingRequestedEventArgs:: + NativeAcceptCredentials___U2__U2__nanoFrameworkDeviceBluetoothDevicePairingKinds__SZARRAY_U1__SZARRAY_U1( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + { + struct ble_sm_io pkey = {0, 0}; + + ushort conn_handle = stack.Arg1().NumericByRef().u2; + pkey.action = stack.Arg2().NumericByRef().s4; + + int rc = ble_sm_inject_io(conn_handle, &pkey); + + BLE_DEBUG_PRINTF( + "NativeAccept OBB con=%d action=%d passKey=%d rc=%d)\n", + conn_handle, + pkey.action, + pkey.passkey, + rc); + + stack.SetResult_U2((ushort)rc); + } + NANOCLR_NOCLEANUP_NOLABEL(); +} + +// Static Bonding methods +HRESULT Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_Security_DeviceBonding:: + IsBonded___STATIC__BOOLEAN__U8(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + int numPeers; + int rc; + int maxBonds = MYNEWT_VAL(BLE_STORE_MAX_BONDS); + ble_addr_t peer_id_addrs[maxBonds]; + bool result = false; + + uint64_t myaddr = stack.Arg0().NumericByRef().u8; + int mytype = stack.Arg1().NumericByRef().s4; + + if (!ble_hs_is_enabled()) + { + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); + } + + rc = ble_store_util_bonded_peers(peer_id_addrs, &numPeers, maxBonds); + if (rc != 0) + { + NANOCLR_SET_AND_LEAVE(CLR_E_FAIL); + } + + for (int index = 0; index < numPeers; index++) + { + u64_t addr = BleAddressToUlong(peer_id_addrs[index].val); + + if (myaddr == addr && peer_id_addrs[index].type == mytype) + { + result = true; + break; + } + } + + stack.SetResult_Boolean(result); + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_Security_DeviceBonding::DeleteAllBonds___STATIC__VOID( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + if (!ble_hs_is_enabled()) + { + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); + } + + ble_store_clear(); + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_Security_DeviceBonding:: + DeleteBondForPeer___STATIC__VOID__U8__nanoFrameworkDeviceBluetoothBluetoothAddressType(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + ble_addr_t bleDelAddr = {0, 0}; + int rc; + + uint64_t addr = stack.Arg0().NumericByRef().u8; + UlongToBleAddress(addr, 0, bleDelAddr); + + if (!ble_hs_is_enabled()) + { + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); + } + + rc = ble_gap_unpair(&bleDelAddr); + if (rc != 0) + { + NANOCLR_SET_AND_LEAVE(CLR_E_FAIL); + } + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_Security_DeviceBonding::Count___STATIC__I4( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + int outCount = 0; + + if (!ble_hs_is_enabled()) + { + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); + } + + ble_store_util_count(BLE_STORE_OBJ_TYPE_PEER_SEC, &outCount); + + stack.SetResult_I4(outCount); + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_sys_dev_ble_native_nanoFramework_Device_Bluetooth_Security_DeviceBonding:: + GetBondInformationAt___STATIC__U8__I4(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + int numPeers; + int rc; + u64_t addr; + int maxBonds = MYNEWT_VAL(BLE_STORE_MAX_BONDS); + ble_addr_t peer_id_addrs[maxBonds]; + + int index = stack.Arg0().NumericByRef().s4; + + if (!ble_hs_is_enabled()) + { + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); + } + + if (index < 0 || index >= maxBonds) + { + NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE); + } + + rc = ble_store_util_bonded_peers(peer_id_addrs, &numPeers, maxBonds); + if (rc != 0) + { + NANOCLR_SET_AND_LEAVE(CLR_E_FAIL); + } + + addr = BleAddressToUlong(peer_id_addrs[index].val); + stack.SetResult_U8(addr); + + NANOCLR_NOCLEANUP(); +} \ No newline at end of file diff --git a/targets/ESP32/_nanoCLR/nanoFramework.Hardware.ESP32/nanoFramework_hardware_esp32_native.cpp b/targets/ESP32/_nanoCLR/nanoFramework.Hardware.ESP32/nanoFramework_hardware_esp32_native.cpp index 219a66e9e4..ff25869992 100644 --- a/targets/ESP32/_nanoCLR/nanoFramework.Hardware.ESP32/nanoFramework_hardware_esp32_native.cpp +++ b/targets/ESP32/_nanoCLR/nanoFramework.Hardware.ESP32/nanoFramework_hardware_esp32_native.cpp @@ -1,4 +1,4 @@ -// +// // Copyright (c) .NET Foundation and Contributors // Portions Copyright (c) Microsoft Corporation. All rights reserved. // See LICENSE file in the project root for full license information. @@ -13,6 +13,7 @@ static const CLR_RT_MethodHandler method_lookup[] = NULL, NULL, NULL, + NULL, Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Configuration::NativeSetPinFunction___STATIC__VOID__I4__I4, Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Configuration::NativeGetPinFunction___STATIC__I4__I4, NULL, @@ -63,23 +64,147 @@ static const CLR_RT_MethodHandler method_lookup[] = NULL, NULL, NULL, + NULL, Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeEnableWakeupByTimer___STATIC__nanoFrameworkHardwareEsp32EspNativeError__U8, Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeEnableWakeupByPin___STATIC__nanoFrameworkHardwareEsp32EspNativeError__nanoFrameworkHardwareEsp32SleepWakeupGpioPin__I4, Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeEnableWakeupByMultiPins___STATIC__nanoFrameworkHardwareEsp32EspNativeError__nanoFrameworkHardwareEsp32SleepWakeupGpioPin__nanoFrameworkHardwareEsp32SleepWakeupMode, - Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeEnableWakeupByTouchPad___STATIC__nanoFrameworkHardwareEsp32EspNativeError, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeEnableWakeupByTouchPad___STATIC__nanoFrameworkHardwareEsp32EspNativeError__I4__I4__U1, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeEnableWakeupByUart___STATIC__nanoFrameworkHardwareEsp32EspNativeError__nanoFrameworkHardwareEsp32SleepWakeUpPort__I4, Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeStartLightSleep___STATIC__nanoFrameworkHardwareEsp32EspNativeError, Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeStartDeepSleep___STATIC__nanoFrameworkHardwareEsp32EspNativeError, Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeGetWakeupCause___STATIC__nanoFrameworkHardwareEsp32SleepWakeupCause, Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeGetWakeupGpioPin___STATIC__nanoFrameworkHardwareEsp32SleepWakeupGpioPin, - Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeGetWakeupTouchpad___STATIC__nanoFrameworkHardwareEsp32SleepTouchPad, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeGetWakeupTouchpad___STATIC__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, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeInit___VOID, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeDeinit___VOID, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeRead___U4, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeGetThreshold___U4, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeSetThreshold___VOID__U4, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeGetTouchSpeed___VOID__BYREF_I4__BYREF_I4, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeSetChargeSpeed___VOID__I4__I4, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeCalibrate___I4__I4, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeGetGpioNumberFromTouchNumber___STATIC__I4__I4, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeGetTriggerMode___STATIC__nanoFrameworkHardwareEsp32TouchTouchTriggerMode, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeSetTriggerMode___STATIC__VOID__nanoFrameworkHardwareEsp32TouchTouchTriggerMode, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeGetTriggerSource___STATIC__nanoFrameworkHardwareEsp32TouchWakeUpSource, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeSetTriggerSource___STATIC__VOID__nanoFrameworkHardwareEsp32TouchWakeUpSource, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeGetMeasurementMode___STATIC__nanoFrameworkHardwareEsp32TouchMeasurementMode, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeSetMeasurementMode___STATIC__VOID__nanoFrameworkHardwareEsp32TouchMeasurementMode, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeSetVoltage___STATIC__VOID__nanoFrameworkHardwareEsp32TouchTouchHighVoltage__nanoFrameworkHardwareEsp32TouchTouchLowVoltage__nanoFrameworkHardwareEsp32TouchTouchHighVoltageAttenuation, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeGetVoltage___STATIC__VOID__BYREF_nanoFrameworkHardwareEsp32TouchTouchHighVoltage__BYREF_nanoFrameworkHardwareEsp32TouchTouchLowVoltage__BYREF_nanoFrameworkHardwareEsp32TouchTouchHighVoltageAttenuation, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeStartFilter___STATIC__VOID__nanoFrameworkHardwareEsp32TouchIFilterSetting, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeStopFilter___STATIC__VOID, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeSetMeasurementTime___STATIC__VOID__U2__U2, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeGetMeasurementTime___STATIC__VOID__BYREF_U2__BYREF_U2, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeGetDenoise___STATIC__VOID__nanoFrameworkHardwareEsp32TouchDenoiseSetting, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeSetDenoise___STATIC__VOID__nanoFrameworkHardwareEsp32TouchDenoiseSetting, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeDenoiseEnabled___STATIC__VOID__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, + Library_nanoFramework_hardware_esp32_native_System_Device_Gpio_GpioPulseCounter::NativeInit___VOID, + Library_nanoFramework_hardware_esp32_native_System_Device_Gpio_GpioPulseCounter::NativeRead___SystemDeviceGpioGpioPulseCount__BOOLEAN, + Library_nanoFramework_hardware_esp32_native_System_Device_Gpio_GpioPulseCounter::NativeStart___VOID, + Library_nanoFramework_hardware_esp32_native_System_Device_Gpio_GpioPulseCounter::NativeStop___VOID, + Library_nanoFramework_hardware_esp32_native_System_Device_Gpio_GpioPulseCounter::NativeDispose___VOID, + NULL, }; const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Esp32 = { "nanoFramework.Hardware.Esp32", - 0xBE7FF253, + 0x6A20A689, method_lookup, - { 100, 0, 7, 3 } + { 100, 0, 10, 0 } }; // clang-format on diff --git a/targets/ESP32/_nanoCLR/nanoFramework.Hardware.ESP32/nanoFramework_hardware_esp32_native.h b/targets/ESP32/_nanoCLR/nanoFramework.Hardware.ESP32/nanoFramework_hardware_esp32_native.h index 24c31ada59..38a6264495 100644 --- a/targets/ESP32/_nanoCLR/nanoFramework.Hardware.ESP32/nanoFramework_hardware_esp32_native.h +++ b/targets/ESP32/_nanoCLR/nanoFramework.Hardware.ESP32/nanoFramework_hardware_esp32_native.h @@ -9,9 +9,42 @@ #include #include -#include +#include #include +typedef enum __nfpack EspNativeError +{ + EspNativeError_OK = 0, + EspNativeError_FAIL = -1, + EspNativeError_NO_MEM = 257, + EspNativeError_INVALID_ARG = 258, + EspNativeError_INVALID_STATE = 259, + EspNativeError_INVALID_SIZE = 260, + EspNativeError_NOT_FOUND = 261, + EspNativeError_NOT_SUPPORTED = 262, + EspNativeError_TIMEOUT = 263, + EspNativeError_INVALID_RESPONSE = 264, + EspNativeError_INVALID_CRC = 265, + EspNativeError_INVALID_VERSION = 266, + EspNativeError_INVALID_MAC = 267, + EspNativeError_WIFI_BASE = 12288, +} EspNativeError; + +typedef enum __nfpack HighResTimerEventType +{ + HighResTimerEventType_TimerExpired = 101, +} HighResTimerEventType; + +typedef enum __nfpack Logging_LogLevel +{ + Logging_LogLevel_LOG_LEVEL_NONE = 0, + Logging_LogLevel_LOG_LEVEL_ERROR = 1, + Logging_LogLevel_LOG_LEVEL_WARN = 2, + Logging_LogLevel_LOG_LEVEL_INFO = 3, + Logging_LogLevel_LOG_LEVEL_DEBUG = 4, + Logging_LogLevel_LOG_LEVEL_VERBOSE = 5, +} Logging_LogLevel; + typedef enum __nfpack NativeMemory_MemoryType { NativeMemory_MemoryType_All = 0, @@ -19,6 +52,187 @@ typedef enum __nfpack NativeMemory_MemoryType NativeMemory_MemoryType_SpiRam = 2, } NativeMemory_MemoryType; +typedef enum __nfpack Sleep_WakeupCause +{ + Sleep_WakeupCause_Undefined = 0, + Sleep_WakeupCause_Ext0 = 2, + Sleep_WakeupCause_Ext1 = 3, + Sleep_WakeupCause_Timer = 4, + Sleep_WakeupCause_TouchPad = 5, + Sleep_WakeupCause_Ulp = 6, + Sleep_WakeupCause_Gpio = 7, + Sleep_WakeupCause_Uart = 8, +} Sleep_WakeupCause; + +typedef enum __nfpack Sleep_WakeupGpioPin +{ + Sleep_WakeupGpioPin_None = 0, + Sleep_WakeupGpioPin_Pin0 = 1, + Sleep_WakeupGpioPin_Pin2 = 4, + Sleep_WakeupGpioPin_Pin4 = 16, + Sleep_WakeupGpioPin_Pin12 = 4096, + Sleep_WakeupGpioPin_Pin13 = 8192, + Sleep_WakeupGpioPin_Pin14 = 16384, + Sleep_WakeupGpioPin_Pin15 = 32768, + Sleep_WakeupGpioPin_Pin25 = 33554432, + Sleep_WakeupGpioPin_Pin26 = 67108864, + Sleep_WakeupGpioPin_Pin27 = 134217728, + Sleep_WakeupGpioPin_Pin32 = 4294967296, + Sleep_WakeupGpioPin_Pin33 = 8589934592, + Sleep_WakeupGpioPin_Pin34 = 17179869184, + Sleep_WakeupGpioPin_Pin35 = 34359738368, + Sleep_WakeupGpioPin_Pin36 = 68719476736, + Sleep_WakeupGpioPin_Pin37 = 137438953472, + Sleep_WakeupGpioPin_Pin38 = 274877906944, + Sleep_WakeupGpioPin_Pin39 = 549755813888, +} Sleep_WakeupGpioPin; + +typedef enum __nfpack Sleep_WakeupMode +{ + Sleep_WakeupMode_AllLow = 0, + Sleep_WakeupMode_AnyHigh = 1, +} Sleep_WakeupMode; + +typedef enum __nfpack Sleep_WakeUpPort +{ + Sleep_WakeUpPort_COM1 = 0, + Sleep_WakeUpPort_COM2 = 1, +} Sleep_WakeUpPort; + +typedef enum __nfpack DenoiseCapacitance +{ + DenoiseCapacitance_Cap5pf = 0, + DenoiseCapacitance_Cap6pf4 = 1, + DenoiseCapacitance_Cap7pf8 = 2, + DenoiseCapacitance_Cap9pf2 = 3, + DenoiseCapacitance_Cap10pf6 = 4, + DenoiseCapacitance_Cap12pf0 = 5, + DenoiseCapacitance_Cap13pf4 = 6, + DenoiseCapacitance_Cap14pf8 = 7, +} DenoiseCapacitance; + +typedef enum __nfpack DenoiseRange +{ + DenoiseRange_Bit12 = 0, + DenoiseRange_Bit10 = 1, + DenoiseRange_Bit8 = 2, + DenoiseRange_Bit4 = 3, +} DenoiseRange; + +typedef enum __nfpack FilterSettingDebounce +{ + FilterSettingDebounce_NoDebounce = 0, + FilterSettingDebounce_One = 1, + FilterSettingDebounce_Two = 2, + FilterSettingDebounce_Three = 3, + FilterSettingDebounce_Four = 4, + FilterSettingDebounce_Five = 5, + FilterSettingDebounce_Six = 6, + FilterSettingDebounce_Seven = 7, +} FilterSettingDebounce; + +typedef enum __nfpack FilterSettingMode +{ + FilterSettingMode_Iir4 = 0, + FilterSettingMode_Iir8 = 1, + FilterSettingMode_Iir16 = 2, + FilterSettingMode_Iir32 = 3, + FilterSettingMode_Iir64 = 4, + FilterSettingMode_Iir128 = 5, + FilterSettingMode_Iir256 = 6, + FilterSettingMode_IirJitter = 7, +} FilterSettingMode; + +typedef enum __nfpack FilterSettingNoiseThreshold +{ + FilterSettingNoiseThreshold_Low = 0, + FilterSettingNoiseThreshold_Mediumlow = 1, + FilterSettingNoiseThreshold_MediumHigh = 2, + FilterSettingNoiseThreshold_High = 3, +} FilterSettingNoiseThreshold; + +typedef enum __nfpack FilterSettingSmoothMode +{ + FilterSettingSmoothMode_Off = 0, + FilterSettingSmoothMode_Iir2 = 1, + FilterSettingSmoothMode_Iir4 = 2, + FilterSettingSmoothMode_Iir8 = 3, +} FilterSettingSmoothMode; + +typedef enum __nfpack MeasurementMode +{ + MeasurementMode_Timer = 0, + MeasurementMode_Software = 1, +} MeasurementMode; + +typedef enum __nfpack TouchChargeSpeed_ChargeSpeed +{ + TouchChargeSpeed_ChargeSpeed_Zero = 0, + TouchChargeSpeed_ChargeSpeed_Slowest = 1, + TouchChargeSpeed_ChargeSpeed_Speed2 = 2, + TouchChargeSpeed_ChargeSpeed_Speed3 = 3, + TouchChargeSpeed_ChargeSpeed_Speed4 = 4, + TouchChargeSpeed_ChargeSpeed_Speed5 = 5, + TouchChargeSpeed_ChargeSpeed_Speed6 = 6, + TouchChargeSpeed_ChargeSpeed_Fastest = 7, +} TouchChargeSpeed_ChargeSpeed; + +typedef enum __nfpack TouchChargeSpeed_InitialCharge +{ + TouchChargeSpeed_InitialCharge_Low = 0, + TouchChargeSpeed_InitialCharge_High = 1, +} TouchChargeSpeed_InitialCharge; + +typedef enum __nfpack TouchHighVoltage +{ + TouchHighVoltage_Volt2V4 = 0, + TouchHighVoltage_Volt2V5 = 1, + TouchHighVoltage_Volt2V6 = 2, + TouchHighVoltage_Volt2V7 = 3, +} TouchHighVoltage; + +typedef enum __nfpack TouchHighVoltageAttenuation +{ + TouchHighVoltageAttenuation_Volt1V5 = 0, + TouchHighVoltageAttenuation_Volt1V0 = 1, + TouchHighVoltageAttenuation_Volt0V5 = 2, + TouchHighVoltageAttenuation_Volt0V0 = 3, +} TouchHighVoltageAttenuation; + +typedef enum __nfpack TouchLowVoltage +{ + TouchLowVoltage_Volt0V5 = 0, + TouchLowVoltage_Volt0V6 = 1, + TouchLowVoltage_Volt0V7 = 2, + TouchLowVoltage_Volt0V8 = 3, +} TouchLowVoltage; + +typedef enum __nfpack TouchTriggerMode +{ + TouchTriggerMode_BellowThreshold = 0, + TouchTriggerMode_AboveThreshold = 1, +} TouchTriggerMode; + +typedef enum __nfpack WakeUpSource +{ + WakeUpSource_BothSet1AndSet2 = 0, + WakeUpSource_OnlySet1 = 1, +} WakeUpSource; + +typedef enum __nfpack ValueTypes +{ + ValueTypes_Index = 0, + ValueTypes_DeviceIndex = 256, + ValueTypes_DeviceType = 65536, +} ValueTypes; + +typedef enum __nfpack GpioChangePolarity +{ + GpioChangePolarity_Both = 0, + GpioChangePolarity_Falling = 1, + GpioChangePolarity_Rising = 2, +} GpioChangePolarity; + struct Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Configuration { NANOCLR_NATIVE_DECLARE(NativeSetPinFunction___STATIC__VOID__I4__I4); @@ -84,12 +298,151 @@ struct Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_ NativeEnableWakeupByPin___STATIC__nanoFrameworkHardwareEsp32EspNativeError__nanoFrameworkHardwareEsp32SleepWakeupGpioPin__I4); NANOCLR_NATIVE_DECLARE( NativeEnableWakeupByMultiPins___STATIC__nanoFrameworkHardwareEsp32EspNativeError__nanoFrameworkHardwareEsp32SleepWakeupGpioPin__nanoFrameworkHardwareEsp32SleepWakeupMode); - NANOCLR_NATIVE_DECLARE(NativeEnableWakeupByTouchPad___STATIC__nanoFrameworkHardwareEsp32EspNativeError); + NANOCLR_NATIVE_DECLARE(NativeEnableWakeupByTouchPad___STATIC__nanoFrameworkHardwareEsp32EspNativeError__I4__I4__U1); + NANOCLR_NATIVE_DECLARE( + NativeEnableWakeupByUart___STATIC__nanoFrameworkHardwareEsp32EspNativeError__nanoFrameworkHardwareEsp32SleepWakeUpPort__I4); NANOCLR_NATIVE_DECLARE(NativeStartLightSleep___STATIC__nanoFrameworkHardwareEsp32EspNativeError); NANOCLR_NATIVE_DECLARE(NativeStartDeepSleep___STATIC__nanoFrameworkHardwareEsp32EspNativeError); NANOCLR_NATIVE_DECLARE(NativeGetWakeupCause___STATIC__nanoFrameworkHardwareEsp32SleepWakeupCause); NANOCLR_NATIVE_DECLARE(NativeGetWakeupGpioPin___STATIC__nanoFrameworkHardwareEsp32SleepWakeupGpioPin); - NANOCLR_NATIVE_DECLARE(NativeGetWakeupTouchpad___STATIC__nanoFrameworkHardwareEsp32SleepTouchPad); + NANOCLR_NATIVE_DECLARE(NativeGetWakeupTouchpad___STATIC__I4); + + //--// +}; + +struct Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_DenoiseSetting +{ + static const int FIELD___denoiseCapacitance = 1; + static const int FIELD___denoiseRange = 2; + + //--// +}; + +struct Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_Esp32FilterSetting +{ + static const int FIELD___period = 1; + + //--// +}; +/* +struct Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_MeasurementTime +{ + static const int FIELD__k__BackingField = 1; + static const int FIELD__k__BackingField = 2; + + //--// +}; +*/ +struct Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_S2S3FilterSetting +{ + static const int FIELD___periodeSettingMode = 1; + static const int FIELD___filterSettingDebounce = 2; + static const int FIELD___filterSettingNoiseThreshold = 3; + static const int FIELD___jitterSize = 4; + static const int FIELD___filterSettingSmoothMode = 5; + + //--// +}; +/* +struct Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchChargeSpeed +{ + static const int FIELD__k__BackingField = 1; + static const int FIELD__k__BackingField = 2; + + //--// +}; + +struct Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPadEventArgs +{ + static const int FIELD__k__BackingField = 3; + static const int FIELD__k__BackingField = 4; + + //--// +}; +*/ +struct Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad +{ + static const int FIELD_STATIC___touchHighVoltage = 1; + static const int FIELD_STATIC___touchLowVoltage = 2; + static const int FIELD_STATIC___touchHighVoltageAttenuation = 3; + static const int FIELD_STATIC___isFilterOn = 4; + static const int FIELD_STATIC___denoiseEnabled = 5; + static const int FIELD_STATIC___touchPadEventHandler = 6; + + static const int FIELD___calibrationData = 1; + static const int FIELD___callbacks = 2; + static const int FIELD___syncLock = 3; + static const int FIELD___disposedValue = 4; + static const int FIELD___touchPadNumber = 5; + + NANOCLR_NATIVE_DECLARE(NativeInit___VOID); + NANOCLR_NATIVE_DECLARE(NativeDeinit___VOID); + NANOCLR_NATIVE_DECLARE(NativeRead___U4); + NANOCLR_NATIVE_DECLARE(NativeGetThreshold___U4); + NANOCLR_NATIVE_DECLARE(NativeSetThreshold___VOID__U4); + NANOCLR_NATIVE_DECLARE(NativeGetTouchSpeed___VOID__BYREF_I4__BYREF_I4); + NANOCLR_NATIVE_DECLARE(NativeSetChargeSpeed___VOID__I4__I4); + NANOCLR_NATIVE_DECLARE(NativeCalibrate___I4__I4); + NANOCLR_NATIVE_DECLARE(NativeGetGpioNumberFromTouchNumber___STATIC__I4__I4); + NANOCLR_NATIVE_DECLARE(NativeGetTriggerMode___STATIC__nanoFrameworkHardwareEsp32TouchTouchTriggerMode); + NANOCLR_NATIVE_DECLARE(NativeSetTriggerMode___STATIC__VOID__nanoFrameworkHardwareEsp32TouchTouchTriggerMode); + NANOCLR_NATIVE_DECLARE(NativeGetTriggerSource___STATIC__nanoFrameworkHardwareEsp32TouchWakeUpSource); + NANOCLR_NATIVE_DECLARE(NativeSetTriggerSource___STATIC__VOID__nanoFrameworkHardwareEsp32TouchWakeUpSource); + NANOCLR_NATIVE_DECLARE(NativeGetMeasurementMode___STATIC__nanoFrameworkHardwareEsp32TouchMeasurementMode); + NANOCLR_NATIVE_DECLARE(NativeSetMeasurementMode___STATIC__VOID__nanoFrameworkHardwareEsp32TouchMeasurementMode); + NANOCLR_NATIVE_DECLARE( + NativeSetVoltage___STATIC__VOID__nanoFrameworkHardwareEsp32TouchTouchHighVoltage__nanoFrameworkHardwareEsp32TouchTouchLowVoltage__nanoFrameworkHardwareEsp32TouchTouchHighVoltageAttenuation); + NANOCLR_NATIVE_DECLARE( + NativeGetVoltage___STATIC__VOID__BYREF_nanoFrameworkHardwareEsp32TouchTouchHighVoltage__BYREF_nanoFrameworkHardwareEsp32TouchTouchLowVoltage__BYREF_nanoFrameworkHardwareEsp32TouchTouchHighVoltageAttenuation); + NANOCLR_NATIVE_DECLARE(NativeStartFilter___STATIC__VOID__nanoFrameworkHardwareEsp32TouchIFilterSetting); + NANOCLR_NATIVE_DECLARE(NativeStopFilter___STATIC__VOID); + NANOCLR_NATIVE_DECLARE(NativeSetMeasurementTime___STATIC__VOID__U2__U2); + NANOCLR_NATIVE_DECLARE(NativeGetMeasurementTime___STATIC__VOID__BYREF_U2__BYREF_U2); + NANOCLR_NATIVE_DECLARE(NativeGetDenoise___STATIC__VOID__nanoFrameworkHardwareEsp32TouchDenoiseSetting); + NANOCLR_NATIVE_DECLARE(NativeSetDenoise___STATIC__VOID__nanoFrameworkHardwareEsp32TouchDenoiseSetting); + NANOCLR_NATIVE_DECLARE(NativeDenoiseEnabled___STATIC__VOID__BOOLEAN); + + //--// +}; + +struct Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPadEvent +{ + static const int FIELD__TouchPadNumber = 3; + static const int FIELD__Touched = 4; + + //--// +}; + +struct Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPadEventHandler +{ + static const int FIELD___pinMap = 1; + + //--// +}; + +struct Library_nanoFramework_hardware_esp32_native_System_Device_Gpio_GpioPulseCount +{ + static const int FIELD__Count = 1; + static const int FIELD__RelativeTime = 2; + + //--// +}; + +struct Library_nanoFramework_hardware_esp32_native_System_Device_Gpio_GpioPulseCounter +{ + static const int FIELD___pinNumberA = 1; + static const int FIELD___pinNumberB = 2; + static const int FIELD___polarity = 3; + static const int FIELD___countActive = 4; + static const int FIELD___filter = 5; + static const int FIELD___syncLock = 6; + static const int FIELD___disposedValue = 7; + + NANOCLR_NATIVE_DECLARE(NativeInit___VOID); + NANOCLR_NATIVE_DECLARE(NativeRead___SystemDeviceGpioGpioPulseCount__BOOLEAN); + NANOCLR_NATIVE_DECLARE(NativeStart___VOID); + NANOCLR_NATIVE_DECLARE(NativeStop___VOID); + NANOCLR_NATIVE_DECLARE(NativeDispose___VOID); //--// }; diff --git a/targets/ESP32/_nanoCLR/nanoFramework.Hardware.ESP32/nanoFramework_hardware_esp32_native_Hardware_Esp32_HighResTimer.cpp b/targets/ESP32/_nanoCLR/nanoFramework.Hardware.ESP32/nanoFramework_hardware_esp32_native_Hardware_Esp32_HighResTimer.cpp index 3f8385effa..a4791733ea 100644 --- a/targets/ESP32/_nanoCLR/nanoFramework.Hardware.ESP32/nanoFramework_hardware_esp32_native_Hardware_Esp32_HighResTimer.cpp +++ b/targets/ESP32/_nanoCLR/nanoFramework.Hardware.ESP32/nanoFramework_hardware_esp32_native_Hardware_Esp32_HighResTimer.cpp @@ -10,15 +10,6 @@ esp_timer_handle_t hrtimers[MAX_HRTIMERS] = {}; -////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// !!! KEEP IN SYNC WITH nanoFramework.Hardware.Esp32.HighResTimerEventType (in managed code) !!! // -////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -enum HighResTimerEventType -{ - TimerExpired = 101 -}; - static int FindNextTimerIndex() { for (int index = 0; index < MAX_HRTIMERS; index++) @@ -33,7 +24,7 @@ static int FindNextTimerIndex() static void HRtimer_callback(void *arg) { esp_timer_handle_t timer_handle = hrtimers[(int)arg]; - PostManagedEvent(EVENT_HIGH_RESOLUTION_TIMER, HighResTimerEventType::TimerExpired, 0, (uint32_t)timer_handle); + PostManagedEvent(EVENT_HIGH_RESOLUTION_TIMER, HighResTimerEventType_TimerExpired, 0, (uint32_t)timer_handle); } HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_HighResTimer:: diff --git a/targets/ESP32/_nanoCLR/nanoFramework.Hardware.ESP32/nanoFramework_hardware_esp32_native_Hardware_Esp32_Sleep.cpp b/targets/ESP32/_nanoCLR/nanoFramework.Hardware.ESP32/nanoFramework_hardware_esp32_native_Hardware_Esp32_Sleep.cpp index dec5882ac7..8de46a1917 100644 --- a/targets/ESP32/_nanoCLR/nanoFramework.Hardware.ESP32/nanoFramework_hardware_esp32_native_Hardware_Esp32_Sleep.cpp +++ b/targets/ESP32/_nanoCLR/nanoFramework.Hardware.ESP32/nanoFramework_hardware_esp32_native_Hardware_Esp32_Sleep.cpp @@ -10,6 +10,10 @@ #include "nanoFramework_hardware_esp32_native.h" +#if defined(CONFIG_IDF_TARGET_ESP32) +static bool CalibrateEspTouchPad(touch_pad_t pad, int calibrationCount, int coefficient); +#endif + HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep:: NativeEnableWakeupByTimer___STATIC__nanoFrameworkHardwareEsp32EspNativeError__U8(CLR_RT_StackFrame &stack) { @@ -98,26 +102,156 @@ HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32 } HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep:: - NativeEnableWakeupByTouchPad___STATIC__nanoFrameworkHardwareEsp32EspNativeError(CLR_RT_StackFrame &stack) + NativeEnableWakeupByTouchPad___STATIC__nanoFrameworkHardwareEsp32EspNativeError__I4__I4__U1( + CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); #if SOC_PM_SUPPORT_EXT_WAKEUP + esp_err_t err; + int pad1; + int coefficient; - esp_err_t err = esp_sleep_enable_touchpad_wakeup(); +#if defined(CONFIG_IDF_TARGET_ESP32) + int pad2; + // Setup the sleep mode + touch_pad_init(); + touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER); - // Return err to the managed application - stack.SetResult_I4((int)err); + pad1 = stack.Arg0().NumericByRef().s4; + pad2 = stack.Arg1().NumericByRef().s4; + coefficient = stack.Arg2().NumericByRef().u1; - NANOCLR_NOCLEANUP_NOLABEL(); + // Check that the configuration is correct + if ((pad1 < 0) && (pad2 < 0)) + { + // We can't have both pads negative + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + else if ((pad1 >= TOUCH_PAD_MAX) || (pad2 >= TOUCH_PAD_MAX)) + { + // We can't have any pad more than the maximum pad number + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + else if (pad1 < 0) + { + // If we have pad1 negative but pad 2 positive, swap them + int padTmp = pad2; + pad2 = pad1; + pad1 = padTmp; + // Set the source on 1 pad only + touch_pad_set_trigger_source(TOUCH_TRIGGER_SOURCE_SET1); + } + else + { + // Both positives, both in the norm, then both sources + touch_pad_set_trigger_source(TOUCH_TRIGGER_SOURCE_BOTH); + } + + // Set pad 1 and calibrate it + touch_pad_config((touch_pad_t)pad1, 0); + if (!CalibrateEspTouchPad((touch_pad_t)pad1, 20, coefficient)) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + + if (pad2 >= 0) + { + // Set pad 2 and calibrate it if it's a valid one + touch_pad_config((touch_pad_t)pad2, 0); + if (!CalibrateEspTouchPad((touch_pad_t)pad2, 20, coefficient)) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + } #else + touch_pad_denoise_t denoise; + touch_filter_config_t filterInfo; + uint32_t touchValue; + uint32_t wakeThreshold; + + touch_pad_init(); + pad1 = stack.Arg0().NumericByRef().s4; + if (pad1 <= 0) + { + // We can't have both pads negative + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + touch_pad_config((touch_pad_t)pad1); + // Denoise setting at TouchSensor 0. + denoise = { + // The bits to be cancelled are determined according to the noise level. + .grade = TOUCH_PAD_DENOISE_BIT4, + .cap_level = TOUCH_PAD_DENOISE_CAP_L4, + }; + touch_pad_denoise_set_config(&denoise); + touch_pad_denoise_enable(); + + // Filter setting + filterInfo = { + .mode = TOUCH_PAD_FILTER_IIR_16, + .debounce_cnt = 1, // 1 time count. + .noise_thr = 0, // 50% + .jitter_step = 4, // use for jitter mode. + .smh_lvl = TOUCH_PAD_SMOOTH_IIR_2, + }; + touch_pad_filter_set_config(&filterInfo); + touch_pad_filter_enable(); + + // Set sleep touch pad. No proximity + touch_pad_sleep_channel_enable((touch_pad_t)pad1, true); + touch_pad_sleep_channel_enable_proximity((touch_pad_t)pad1, false); + // Reducing the operating frequency can effectively reduce power consumption. + touch_pad_sleep_channel_set_work_time(1000, TOUCH_PAD_MEASURE_CYCLE_DEFAULT); + // Enable touch sensor clock. Work mode is "timer trigger". + touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER); + touch_pad_fsm_start(); + // Giving time for measurements + vTaskDelay(100 / portTICK_RATE_MS); + + coefficient = stack.Arg2().NumericByRef().u1; + + touch_pad_sleep_channel_read_smooth((touch_pad_t)pad1, &touchValue); + // wakeup when touch sensor crosses % of background level + wakeThreshold = touchValue * (100 - coefficient) / 100.0; + touch_pad_sleep_set_threshold((touch_pad_t)pad1, wakeThreshold); +#endif + err = esp_sleep_enable_touchpad_wakeup(); + esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON); + + // Return err to the managed application + stack.SetResult_I4((int)err); + +#else NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); +#endif NANOCLR_NOCLEANUP(); +} -#endif +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep:: + NativeEnableWakeupByUart___STATIC__nanoFrameworkHardwareEsp32EspNativeError__nanoFrameworkHardwareEsp32SleepWakeUpPort__I4( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + { + esp_err_t err; + int uartNum; + int threshold; + + // Static arguments starts at 0 + uartNum = stack.Arg0().NumericByRef().s4; + threshold = stack.Arg1().NumericByRef().s4; + uart_set_wakeup_threshold(uartNum, threshold); + err = esp_sleep_enable_uart_wakeup(uartNum); + + // Return err to the managed application + stack.SetResult_I4((int)err); + } + NANOCLR_NOCLEANUP_NOLABEL(); } HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep:: @@ -208,16 +342,22 @@ HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32 } HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep:: - NativeGetWakeupTouchpad___STATIC__nanoFrameworkHardwareEsp32SleepTouchPad(CLR_RT_StackFrame &stack) + NativeGetWakeupTouchpad___STATIC__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); #if SOC_PM_SUPPORT_EXT_WAKEUP touch_pad_t touch_pad = esp_sleep_get_touchpad_wakeup_status(); + int retValue = (int)touch_pad; + // We have to remap this enum. + if (touch_pad == TOUCH_PAD_MAX) + { + retValue = -1; + } // Return value to the managed application - stack.SetResult_I4((int)touch_pad); + stack.SetResult_I4(retValue); NANOCLR_NOCLEANUP_NOLABEL(); @@ -229,3 +369,30 @@ HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32 #endif } + +#if defined(CONFIG_IDF_TARGET_ESP32) +static bool CalibrateEspTouchPad(touch_pad_t pad, int calibrationCount, int coefficient) +{ + double avg = 0; + const int minReading = 300; + uint16_t val; + for (int i = 0; i < calibrationCount; i++) + { + touch_pad_read(pad, &val); + avg = (avg * i + val) / (i + 1); + } + + if (avg < minReading) + { + touch_pad_config(pad, 0); + return false; + } + else + { + int threshold = avg * coefficient / 100; + touch_pad_config(pad, threshold); + } + + return true; +} +#endif \ No newline at end of file diff --git a/targets/ESP32/_nanoCLR/nanoFramework.Hardware.ESP32/nanoFramework_hardware_esp32_native_System_Device_Gpio_GpioPulseCounter.cpp b/targets/ESP32/_nanoCLR/nanoFramework.Hardware.ESP32/nanoFramework_hardware_esp32_native_System_Device_Gpio_GpioPulseCounter.cpp new file mode 100644 index 0000000000..26e4bb924c --- /dev/null +++ b/targets/ESP32/_nanoCLR/nanoFramework.Hardware.ESP32/nanoFramework_hardware_esp32_native_System_Device_Gpio_GpioPulseCounter.cpp @@ -0,0 +1,451 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Portions Copyright (c) Microsoft Corporation. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +#include "nanoFramework_hardware_esp32_native.h" +#include + +#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + +#include "pcnt.h" + +typedef Library_nanoFramework_hardware_esp32_native_System_Device_Gpio_GpioPulseCount GpioPulseCount; +typedef Library_nanoFramework_hardware_esp32_native_System_Device_Gpio_GpioPulseCounter GpioPulseCounter; +typedef Library_corlib_native_System_TimeSpan TimeSpan; + +// Map Gpio pin number to 1 of 8 ESP32 counters, -1 = not mapped +// Each pulse counter is a 16 bit signed value. +// The managed code requires a 64 bit counter so we accumulate the overflows in an interrupt when count gets to 0x7fff + +static bool isrInstalled = false; +static int8_t gpioCounterMap[PCNT_UNIT_MAX]; +static int64_t overflowCount[PCNT_UNIT_MAX]; +static int8_t numberCounterUsed = 0; + +#define MAX_COUNTER_VALUE 0x7fff + +// Interrupt routine used to catch overflows so we can have a 64 bit counter +static void IRAM_ATTR pcnt_intr_handler(void *arg) +{ + int counterIndex = (int)arg; + + uint32_t status; + pcnt_get_event_status((pcnt_unit_t)counterIndex, &status); + + if (status & PCNT_EVT_H_LIM) + { + overflowCount[counterIndex] += MAX_COUNTER_VALUE; + } + + if (status & PCNT_EVT_L_LIM) + { + overflowCount[counterIndex] -= MAX_COUNTER_VALUE; + } +} + +// Find an unused counter, returns counter index or -1 if not found +static int FindFreeCounter(int gpioPin) +{ + int counterIndex; + + for (counterIndex = 0; counterIndex < 8; counterIndex++) + { + if (gpioCounterMap[counterIndex] == -1) + { + gpioCounterMap[counterIndex] = gpioPin; + numberCounterUsed++; + return counterIndex; + } + } + + return -1; +} + +// Find the index of counter for a gpio pin, returns index or -1 if not found +static int FindCounterForGpio(int gpioPin) +{ + int counterIndex; + + for (counterIndex = 0; counterIndex < PCNT_UNIT_MAX; counterIndex++) + { + if (gpioCounterMap[counterIndex] == gpioPin) + { + return counterIndex; + } + } + + return -1; +} + +// Initalise the ESP32 counter +// return true if ok +static bool InitialiseCounter(int counterIndex, int gpioNumA, int gpioNumB, bool countRising, bool countFalling) +{ + esp_err_t ec; + + // Prepare configuration for the PCNT unit */ + pcnt_config_t pcnt_config; + + // Set PCNT input signal and control GPIOs + pcnt_config.pulse_gpio_num = gpioNumA; + pcnt_config.ctrl_gpio_num = gpioNumB; + + pcnt_config.channel = PCNT_CHANNEL_0; + pcnt_config.unit = (pcnt_unit_t)counterIndex; + + if (gpioNumB >= 0) + { + pcnt_config.pos_mode = PCNT_COUNT_DEC; + pcnt_config.neg_mode = PCNT_COUNT_INC; + } + else + { + // What to do on the positive / negative edge of pulse input? + pcnt_config.pos_mode = countRising ? PCNT_COUNT_INC : PCNT_COUNT_DIS; // positive edge count ? + pcnt_config.neg_mode = countFalling ? PCNT_COUNT_INC : PCNT_COUNT_DIS; // falling edge count ? + } + + // What to do when control input is low or high? + pcnt_config.lctrl_mode = gpioNumB < 0 ? PCNT_MODE_KEEP : PCNT_MODE_REVERSE; // Keep the primary counter mode if low + pcnt_config.hctrl_mode = PCNT_MODE_KEEP; // Keep the primary counter mode if high + + // Set the maximum and minimum limit values to watch + pcnt_config.counter_h_lim = MAX_COUNTER_VALUE; + pcnt_config.counter_l_lim = -MAX_COUNTER_VALUE; + + //* Initialize PCNT unit + ec = pcnt_unit_config(&pcnt_config); + + if (gpioNumB >= 0) + { + pcnt_config.pulse_gpio_num = gpioNumB; + pcnt_config.ctrl_gpio_num = gpioNumA; + pcnt_config.channel = PCNT_CHANNEL_1; + // Setup reverse behavior on second counter + pcnt_config.pos_mode = PCNT_COUNT_INC; + pcnt_config.neg_mode = PCNT_COUNT_DEC; + ec |= pcnt_unit_config(&pcnt_config); + } + + if ((gpioNumB < 0) && (gpioNumA < 0)) + { + pcnt_config.pulse_gpio_num = gpioNumB; + pcnt_config.ctrl_gpio_num = gpioNumA; + pcnt_config.channel = PCNT_CHANNEL_1; + pcnt_config.pos_mode = PCNT_COUNT_DIS; + pcnt_config.neg_mode = PCNT_COUNT_DIS; + ec |= pcnt_unit_config(&pcnt_config); + } + + return ec == ESP_OK; +} + +void PulseCountUninitialize() +{ + if (isrInstalled) + { + pcnt_isr_service_uninstall(); + isrInstalled = false; + numberCounterUsed = 0; + } +} + +#endif + +HRESULT Library_nanoFramework_hardware_esp32_native_System_Device_Gpio_GpioPulseCounter::NativeInit___VOID( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + { +#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + + int16_t pinNumberA; + int16_t pinNumberB; + CLR_RT_HeapBlock *pThis = stack.This(); + + FAULT_ON_NULL(pThis); + + if (numberCounterUsed == 0) + { + HAL_AddSoftRebootHandler(PulseCountUninitialize); + + // We need to initialize the array if it's the first one + for (int i = 0; i < PCNT_UNIT_MAX; i++) + { + gpioCounterMap[i] = -1; + } + } + + pinNumberA = pThis[FIELD___pinNumberA].NumericByRefConst().s4; + pinNumberB = pThis[FIELD___pinNumberB].NumericByRefConst().s4; + if (pinNumberB < 0) + { + pinNumberB = PCNT_PIN_NOT_USED; + } + + int index = FindFreeCounter(pinNumberA); + if (index == -1) + { + // No free counters + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); + } + + overflowCount[index] = 0; + // Reserve pin for Counter use + CPU_GPIO_ReservePin(pinNumberA, true); + if (pinNumberB >= 0) + { + CPU_GPIO_ReservePin(pinNumberB, true); + } + +#else + NANOCLR_SET_AND_LEAVE(stack.NotImplementedStub()); +#endif + } + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_hardware_esp32_native_System_Device_Gpio_GpioPulseCounter:: + NativeRead___SystemDeviceGpioGpioPulseCount__BOOLEAN(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + { +#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + + CLR_RT_TypeDef_Index gpioPulseCountTypeDef; + CLR_RT_HeapBlock *gpioPulseCount; + + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + + // check if object has been disposed + if (pThis[FIELD___disposedValue].NumericByRef().u1 != 0) + { + NANOCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); + } + + int pinNumberA = pThis[FIELD___pinNumberA].NumericByRefConst().s4; + + int counterIndex = FindCounterForGpio(pinNumberA); + + if (counterIndex == -1) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + bool resetAfterRead = (bool)stack.Arg1().NumericByRef().u1; + + int16_t counter; + + pcnt_get_counter_value((pcnt_unit_t)counterIndex, &counter); + + // relativeTime Read Time, Number of micro seconds since boot + int64_t relativeTime = esp_timer_get_time(); + + // Combine to make a 64 bit value + uint64_t totalCount = overflowCount[counterIndex] + (uint64_t)counter; + + if (resetAfterRead) + { + pcnt_counter_clear((pcnt_unit_t)counterIndex); + overflowCount[counterIndex] = 0; + } + + // push return value to stack + CLR_RT_HeapBlock &top = stack.PushValue(); + + // find type definition, don't bother checking the result as it exists for sure + g_CLR_RT_TypeSystem.FindTypeDef("GpioPulseCount", "System.Device.Gpio", gpioPulseCountTypeDef); + + // create an instance of in the stack + NANOCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.NewObjectFromIndex(top, gpioPulseCountTypeDef)); + + // dereference the object in order to reach its fields + gpioPulseCount = top.Dereference(); + + // set fields + + gpioPulseCount[GpioPulseCount::FIELD__Count].NumericByRef().s8 = totalCount; + + // relative time is a TimeSpan, so needs to be access through a pointer + CLR_INT64 *val = TimeSpan::GetValuePtr(gpioPulseCount[GpioPulseCount::FIELD__RelativeTime]); + + // timespan in milliseconds, but... + *val = (CLR_UINT64)relativeTime; + // ... need to convert to ticks with this + *val *= TIME_CONVERSION__TICKUNITS; + +#else + NANOCLR_SET_AND_LEAVE(stack.NotImplementedStub()); +#endif + } + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_hardware_esp32_native_System_Device_Gpio_GpioPulseCounter::NativeStart___VOID( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + { +#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + + bool countRising = false; + bool countFalling = false; + + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + + // check if object has been disposed + if (pThis[GpioPulseCounter::FIELD___disposedValue].NumericByRef().u1 != 0) + { + NANOCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); + } + + int pinNumberA = pThis[FIELD___pinNumberA].NumericByRefConst().s4; + int pinNumberB = pThis[FIELD___pinNumberB].NumericByRefConst().s4; + + int counterIndex = FindCounterForGpio(pinNumberA); + if (counterIndex == -1) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + GpioChangePolarity polarity = (GpioChangePolarity)pThis[FIELD___polarity].NumericByRefConst().s4; + + switch (polarity) + { + case GpioChangePolarity_Both: + countRising = true; + countFalling = true; + break; + + case GpioChangePolarity_Rising: + countRising = true; + countFalling = false; + break; + + case GpioChangePolarity_Falling: + countRising = false; + countFalling = true; + break; + } + + if (!InitialiseCounter(counterIndex, pinNumberA, pinNumberB, countRising, countFalling)) + { + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); + } + + // Apply filter. + uint16_t filter = pThis[GpioPulseCounter::FIELD___filter].NumericByRef().u2; + pcnt_set_filter_value((pcnt_unit_t)counterIndex, filter); + pcnt_filter_enable((pcnt_unit_t)counterIndex); + + pcnt_event_enable((pcnt_unit_t)counterIndex, PCNT_EVT_H_LIM); + pcnt_event_enable((pcnt_unit_t)counterIndex, PCNT_EVT_L_LIM); + + pcnt_counter_pause((pcnt_unit_t)counterIndex); + + pcnt_counter_clear((pcnt_unit_t)counterIndex); + overflowCount[counterIndex] = 0; + + // Register ISR handler and enable interrupts for PCNT unit */ + if (isrInstalled == false) + { + pcnt_isr_service_install(0); + isrInstalled = true; + } + + pcnt_isr_handler_add((pcnt_unit_t)counterIndex, pcnt_intr_handler, (void *)counterIndex); + + // enable interrupts for PCNT unit + pcnt_intr_enable((pcnt_unit_t)counterIndex); + + pcnt_counter_resume((pcnt_unit_t)counterIndex); + +#else + NANOCLR_SET_AND_LEAVE(stack.NotImplementedStub()); +#endif + } + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_hardware_esp32_native_System_Device_Gpio_GpioPulseCounter::NativeStop___VOID( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + { +#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + + // check if object has been disposed + if (pThis[GpioPulseCounter::FIELD___disposedValue].NumericByRef().u1 != 0) + { + NANOCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); + } + + int pinNumberA = pThis[FIELD___pinNumberA].NumericByRefConst().s4; + + int counterIndex = FindCounterForGpio(pinNumberA); + if (counterIndex == -1) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + pcnt_counter_pause((pcnt_unit_t)counterIndex); + +#else + NANOCLR_SET_AND_LEAVE(stack.NotImplementedStub()); +#endif + } + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_hardware_esp32_native_System_Device_Gpio_GpioPulseCounter::NativeDispose___VOID( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + { +#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + + int pinNumberA = pThis[FIELD___pinNumberA].NumericByRefConst().s4; + int pinNumberB = pThis[FIELD___pinNumberB].NumericByRefConst().s4; + + int counterIndex = FindCounterForGpio(pinNumberA); + if (counterIndex == -1) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + numberCounterUsed--; + pcnt_isr_handler_remove((pcnt_unit_t)counterIndex); + if (numberCounterUsed == 0) + { + pcnt_isr_service_uninstall(); + isrInstalled = false; + } + + // Disable counter, remove gpio pin + InitialiseCounter(counterIndex, PCNT_PIN_NOT_USED, PCNT_PIN_NOT_USED, false, false); + + // Clear counter / gpio mapping + gpioCounterMap[counterIndex] = -1; + + CPU_GPIO_ReservePin(pinNumberA, false); + if (pinNumberB >= 0) + { + CPU_GPIO_ReservePin(pinNumberB, false); + } + +#else + NANOCLR_SET_AND_LEAVE(stack.NotImplementedStub()); +#endif + } + NANOCLR_NOCLEANUP(); +} diff --git a/targets/ESP32/_nanoCLR/nanoFramework.Hardware.ESP32/nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad.cpp b/targets/ESP32/_nanoCLR/nanoFramework.Hardware.ESP32/nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad.cpp new file mode 100644 index 0000000000..8496ad381b --- /dev/null +++ b/targets/ESP32/_nanoCLR/nanoFramework.Hardware.ESP32/nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad.cpp @@ -0,0 +1,1149 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Portions Copyright (c) Microsoft Corporation. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +#include "nanoFramework_hardware_esp32_native.h" +#include +#include + +#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + +static int numberInitialzed = 0; +static bool isTouchInitialized = false; +static bool isTouchPadUsed[TOUCH_PAD_MAX]; +static bool isFilterOn = false; +static TaskHandle_t handleReadTask = NULL; +static bool isTouched[TOUCH_PAD_MAX]; +static uint32_t thresholds[TOUCH_PAD_MAX]; +static bool isTimeModeOn = false; +static uint32_t lastTouchValues[TOUCH_PAD_MAX]; +static touch_fsm_mode_t measurementMode; +static touch_trigger_mode_t triggerMode; + +/* + * + * Shared functions between ESP32 and ESP32S2 and for all the functions. + * + */ + +/* +Function used for all the interruption in the touch pad. +*/ +static void IsrCallBack(void *arg) +{ + bool val; + uint32_t padIntr = touch_pad_get_status(); +#if defined(CONFIG_IDF_TARGET_ESP32) + touch_pad_intr_clear(); +#else + touch_pad_intr_clear(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE | TOUCH_PAD_INTR_MASK_TIMEOUT); +#endif + for (int i = 0; i < TOUCH_PAD_MAX; i++) + { + val = (padIntr >> i) & 0x01; + // Check if we have a change and raise an even if yes + if (val != isTouched[i]) + { + PostManagedEvent(EVENT_TOUCH, 0, i, val); + } + + isTouched[i] = val; + } +} + +/* +Resources need to be cleaned and the driver uninstalled in case of a soft reboot. +*/ +static void TouchPad_Uninitialize() +{ + // stop the task + if (handleReadTask != NULL) + { + vTaskDelete(handleReadTask); + } + + handleReadTask = NULL; + isTimeModeOn = false; + + // Clean the isr registration +#if defined(CONFIG_IDF_TARGET_ESP32) + touch_pad_intr_disable(); +#else + touch_pad_intr_disable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE | TOUCH_PAD_INTR_MASK_TIMEOUT); +#endif + touch_pad_isr_deregister(IsrCallBack, NULL); + // Clean filter and uninstall the driver +#if defined(CONFIG_IDF_TARGET_ESP32) + touch_pad_filter_stop(); + touch_pad_filter_delete(); +#else + touch_pad_filter_disable(); +#endif + + // Deinitialize and clean the touch pad driver + touch_pad_deinit(); + + isFilterOn = false; + isTouchInitialized = false; + // Make sure all pins are not reserved + memset(isTouchPadUsed, 0, sizeof(isTouchPadUsed)); + // Clear the pin values + memset(isTouched, 0, sizeof(isTouched)); + memset(thresholds, 0, sizeof(thresholds)); + memset(lastTouchValues, 0, sizeof(lastTouchValues)); +} + +/* +This function ensure that the driver is installed for static functions. +It does initialize as well the pins table and register for the soft reboot call back. +*/ +static void MakeSureTouchIsInitialized() +{ + if (!isTouchInitialized) + { + isTouchInitialized = true; + touch_pad_init(); + + // We setup software trigger mode because the FSM one + // is not properly working on ESP32 and we will manage a read loop + // in a task. + touch_pad_set_fsm_mode(TOUCH_FSM_MODE_SW); + + // Make sure all pins are not reserved + memset(isTouchPadUsed, 0, sizeof(isTouchPadUsed)); + // Clear the pin values + memset(isTouched, 0, sizeof(isTouched)); + memset(thresholds, 0, sizeof(thresholds)); + memset(lastTouchValues, 0, sizeof(lastTouchValues)); + + HAL_AddSoftRebootHandler(TouchPad_Uninitialize); + + // The ISR is not really working properly, leaving this code in case new functions +#if defined(CONFIG_IDF_TARGET_ESP32) + // and features will be added in the future. + // touch_pad_intr_enable(); + // touch_pad_isr_register(IsrCallBack, NULL); +#else + // touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE | + // TOUCH_PAD_INTR_MASK_TIMEOUT); touch_pad_isr_register(IsrCallBack, NULL, TOUCH_PAD_INTR_MASK_ALL); +#endif + } +} + +/* +This function reads the sensor value. It does return the last read if running in timer mode. +Otherwise returns the value read directly on the sensors. +*/ +static uint32_t TouchPadRead(touch_pad_t padNumber) +{ +#if defined(CONFIG_IDF_TARGET_ESP32) + uint16_t touchValue; +#else + uint32_t touchValue; +#endif + // Start a manual measurement if software mode + touch_pad_sw_start(); + + // We're waiting to get the data ready + while (!touch_pad_meas_is_done()) + { + vTaskDelay(1); + } + + // If we are filtering, the function to call to read the data is different + if (isFilterOn) + { +#if defined(CONFIG_IDF_TARGET_ESP32) + touch_pad_read_filtered(padNumber, &touchValue); +#else + touch_pad_filter_read_smooth(padNumber, &touchValue); +#endif + } + else + { +#if defined(CONFIG_IDF_TARGET_ESP32) + touch_pad_read(padNumber, &touchValue); +#else + touch_pad_read_raw_data(padNumber, &touchValue); +#endif + } + + // Do we have an event? + if (triggerMode == TOUCH_TRIGGER_ABOVE) + { + if (touchValue < thresholds[padNumber] && isTouched[padNumber]) + { + // Released + PostManagedEvent(EVENT_TOUCH, 0, padNumber, 0); + isTouched[padNumber] = false; + } + else if (touchValue > thresholds[padNumber] && !isTouched[padNumber]) + { + // Touched + PostManagedEvent(EVENT_TOUCH, 0, padNumber, 1); + isTouched[padNumber] = true; + } + } + else + { + if (touchValue > thresholds[padNumber] && !isTouched[padNumber]) + { + // Touched + PostManagedEvent(EVENT_TOUCH, 0, padNumber, 1); + isTouched[padNumber] = true; + } + else if (touchValue < thresholds[padNumber] && isTouched[padNumber]) + { + // Released + PostManagedEvent(EVENT_TOUCH, 0, padNumber, 0); + isTouched[padNumber] = false; + } + } + + lastTouchValues[padNumber] = touchValue; + + return touchValue; +} + +/* +This task is run when the timer mode is used. +*/ +static void ReadTask(void *pvParameter) +{ + while (isTimeModeOn) + { + for (int i = 0; i < TOUCH_PAD_MAX; i++) + { + if (isTouchPadUsed[i]) + { + TouchPadRead((touch_pad_t)i); + } + } + + // Wait the measurement time, 20 milliseconds + // So we are aligning on the nano Thread + vTaskDelay(20 / portTICK_PERIOD_MS); + } +} + +#endif + +typedef Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad TouchPad; +typedef Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_Esp32FilterSetting + Esp32FilterSetting; +typedef Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_DenoiseSetting DenoiseSetting; + +#if defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) +typedef Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_S2S3FilterSetting + S2S3FilterSetting; +#endif + +HRESULT GetAndCheckTouchPadNumber(CLR_RT_StackFrame &stack, touch_pad_t *padNumber) +{ + NANOCLR_HEADER(); + +#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + + // Get the stack + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + *padNumber = (touch_pad_t)(pThis[TouchPad::FIELD___touchPadNumber].NumericByRef().s4); + + // Let's make sure it's a proper pin + if ((*padNumber < 0) || (*padNumber >= TOUCH_PAD_MAX)) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); +#endif + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeInit___VOID( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + + touch_pad_t padNumber; + NANOCLR_CHECK_HRESULT(GetAndCheckTouchPadNumber(stack, &padNumber)); + + // We make sure the pin is not yet open + if (isTouchPadUsed[padNumber]) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + // We initalize the pin + MakeSureTouchIsInitialized(); + if (touch_pad_io_init(padNumber) != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + +#if defined(CONFIG_IDF_TARGET_ESP32) + if (touch_pad_config(padNumber, 0) != ESP_OK) +#else + if (touch_pad_config(padNumber) != ESP_OK) +#endif + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + + // And we increase the number and mark the pin as open + numberInitialzed++; + isTouchPadUsed[padNumber] = true; + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); +#endif + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeDeinit___VOID( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + + if (numberInitialzed == 1) + { + touch_pad_deinit(); + isTouchInitialized = false; + } + + touch_pad_t padNumber; + NANOCLR_CHECK_HRESULT(GetAndCheckTouchPadNumber(stack, &padNumber)); + + // Decrease the counter and make sure we mark this one as not used anymore + numberInitialzed--; + isTouchPadUsed[padNumber] = false; + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); +#endif + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeRead___U4( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + + touch_pad_t padNumber; + uint32_t touchValue; + NANOCLR_CHECK_HRESULT(GetAndCheckTouchPadNumber(stack, &padNumber)); + + // If we already have the background task running + if (isTimeModeOn) + { + touchValue = lastTouchValues[padNumber]; + } + else + { + touchValue = TouchPadRead(padNumber); + } + + stack.SetResult_U4(touchValue); + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); +#endif + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad:: + NativeGetThreshold___U4(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + + touch_pad_t padNumber; + NANOCLR_CHECK_HRESULT(GetAndCheckTouchPadNumber(stack, &padNumber)); + +#if defined(CONFIG_IDF_TARGET_ESP32) + uint16_t threshold; +#else + uint32_t threshold; +#endif + if (touch_pad_get_thresh(padNumber, &threshold) != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + + // Make sure we store it for later usage + thresholds[padNumber] = threshold; + stack.SetResult_U4(threshold); + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); +#endif + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad:: + NativeSetThreshold___VOID__U4(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + + touch_pad_t padNumber; + NANOCLR_CHECK_HRESULT(GetAndCheckTouchPadNumber(stack, &padNumber)); + +#if defined(CONFIG_IDF_TARGET_ESP32) + uint16_t threshold; + // Non static function, Arg1 is the first argument + threshold = (uint16_t)stack.Arg1().NumericByRef().u4; +#else + uint32_t threshold; + // Non static function, Arg1 is the first argument + threshold = (uint32_t)stack.Arg1().NumericByRef().u4; + +#endif + if (touch_pad_set_thresh(padNumber, threshold) != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + + // Make sure we store it for later usage + thresholds[padNumber] = threshold; + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); +#endif + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad:: + NativeGetTouchSpeed___VOID__BYREF_I4__BYREF_I4(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + + touch_pad_t padNumber; + touch_cnt_slope_t slope; + touch_tie_opt_t opt; + + NANOCLR_CHECK_HRESULT(GetAndCheckTouchPadNumber(stack, &padNumber)); + if (touch_pad_get_cnt_mode(padNumber, &slope, &opt) != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + + // Arg1 as we are in a non static function. + CLR_RT_HeapBlock bhSlope; + CLR_RT_HeapBlock bhOpt; + bhSlope.SetInteger(slope); + NANOCLR_CHECK_HRESULT(bhSlope.StoreToReference(stack.Arg1(), 0)); + bhOpt.SetInteger(opt); + NANOCLR_CHECK_HRESULT(bhOpt.StoreToReference(stack.Arg2(), 0)); + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); +#endif + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad:: + NativeSetChargeSpeed___VOID__I4__I4(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + + touch_pad_t padNumber; + touch_cnt_slope_t slope; + touch_tie_opt_t opt; + + NANOCLR_CHECK_HRESULT(GetAndCheckTouchPadNumber(stack, &padNumber)); + // Non static function, Arg1 is the first argument + slope = (touch_cnt_slope_t)stack.Arg1().NumericByRef().u4; + opt = (touch_tie_opt_t)stack.Arg2().NumericByRef().u4; + if (touch_pad_set_cnt_mode(padNumber, slope, opt) != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); +#endif + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad:: + NativeCalibrate___I4__I4(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + + touch_pad_t padNumber; + uint32_t count; + double average = 0; + + NANOCLR_CHECK_HRESULT(GetAndCheckTouchPadNumber(stack, &padNumber)); + // In theory, this part is for ESP32 because S2/S3 works differently + // #if defined(CONFIG_IDF_TARGET_ESP32) + + // Non static function, Arg1 is the first argument + count = (uint32_t)stack.Arg1().NumericByRef().s4; + + // We will read the values and make an average + for (uint32_t i = 0; i < count; i++) + { + average = (average * i + TouchPadRead(padNumber)) / (i + 1); + } + + // Practically, we will do the same as it's the only way to do have it working + // #else + // touch_pad_reset_benchmark(padNumber); + // vTaskDelay(10 * count / portTICK_PERIOD_MS); + // touch_pad_read_benchmark(padNumber, &count); + // average = count; + // #endif + + // And we return the average + stack.SetResult_I4((int)average); + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); +#endif + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad:: + NativeGetGpioNumberFromTouchNumber___STATIC__I4__I4(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + + int padNumber = (int)(stack.Arg0().NumericByRef().u4); + int gpioNumber = -1; + + // Let's make sure it's a proper pin + if ((padNumber < 0) || (padNumber >= TOUCH_PAD_MAX)) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + /*!< Touch pad channel 0 is GPIO4(ESP32) */ + /*!< Touch pad channel 1 is GPIO0(ESP32) / GPIO1(ESP32-S2) */ + /*!< Touch pad channel 2 is GPIO2(ESP32) / GPIO2(ESP32-S2) */ + /*!< Touch pad channel 3 is GPIO15(ESP32) / GPIO3(ESP32-S2) */ + /*!< Touch pad channel 4 is GPIO13(ESP32) / GPIO4(ESP32-S2) */ + /*!< Touch pad channel 5 is GPIO12(ESP32) / GPIO5(ESP32-S2) */ + /*!< Touch pad channel 6 is GPIO14(ESP32) / GPIO6(ESP32-S2) */ + /*!< Touch pad channel 7 is GPIO27(ESP32) / GPIO7(ESP32-S2) */ + /*!< Touch pad channel 8 is GPIO33(ESP32) / GPIO8(ESP32-S2) */ + /*!< Touch pad channel 9 is GPIO32(ESP32) / GPIO9(ESP32-S2) */ + /*!< Touch channel 10 is GPIO10(ESP32-S2) */ + /*!< Touch channel 11 is GPIO11(ESP32-S2) */ + /*!< Touch channel 12 is GPIO12(ESP32-S2) */ + /*!< Touch channel 13 is GPIO13(ESP32-S2) */ + /*!< Touch channel 14 is GPIO14(ESP32-S2) */ + + // This is the ESP32-S2 series + if (SOC_TOUCH_SENSOR_NUM > 10) + { + // In this case it's simple + if (padNumber > 0) + { + gpioNumber = padNumber; + } + } + else + { + // This is traditional ESP32 + switch (padNumber) + { + case TOUCH_PAD_NUM0: + gpioNumber = 4; + break; + + case TOUCH_PAD_NUM1: + gpioNumber = 0; + break; + + case TOUCH_PAD_NUM2: + gpioNumber = 2; + break; + + case TOUCH_PAD_NUM3: + gpioNumber = 15; + break; + + case TOUCH_PAD_NUM4: + gpioNumber = 13; + break; + + case TOUCH_PAD_NUM5: + gpioNumber = 12; + break; + + case TOUCH_PAD_NUM6: + gpioNumber = 14; + break; + + case TOUCH_PAD_NUM7: + gpioNumber = 27; + break; + + case TOUCH_PAD_NUM8: + gpioNumber = 33; + break; + + case TOUCH_PAD_NUM9: + gpioNumber = 32; + break; + } + } + + stack.SetResult_I4(gpioNumber); + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); +#endif + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad:: + NativeGetTriggerMode___STATIC__nanoFrameworkHardwareEsp32TouchTouchTriggerMode(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +#if defined(CONFIG_IDF_TARGET_ESP32) + + // For static functions, we need to make sure that we have the touch pad initialized + MakeSureTouchIsInitialized(); + + if (touch_pad_get_trigger_mode(&triggerMode) != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + + stack.SetResult_I4(triggerMode); + NANOCLR_NOCLEANUP(); + +#elif defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + + stack.SetResult_I4(triggerMode); + NANOCLR_NOCLEANUP_NOLABEL(); + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); + NANOCLR_NOCLEANUP(); +#endif +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad:: + NativeSetTriggerMode___STATIC__VOID__nanoFrameworkHardwareEsp32TouchTouchTriggerMode(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +#if defined(CONFIG_IDF_TARGET_ESP32) + + // For static functions, we need to make sure that we have the touch pad initialized + MakeSureTouchIsInitialized(); + triggerMode = (touch_trigger_mode_t)stack.Arg0().NumericByRef().s4; + if (touch_pad_set_trigger_mode(triggerMode) != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + + NANOCLR_NOCLEANUP(); + +#elif defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + + triggerMode = (touch_trigger_mode_t)stack.Arg0().NumericByRef().s4; + NANOCLR_NOCLEANUP_NOLABEL(); + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); + NANOCLR_NOCLEANUP(); +#endif +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad:: + NativeGetTriggerSource___STATIC__nanoFrameworkHardwareEsp32TouchWakeUpSource(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +// Not implemented in this IDF version on the S2/S3 || +// defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) +#if defined(CONFIG_IDF_TARGET_ESP32) + + // For static functions, we need to make sure that we have the touch pad initialized + MakeSureTouchIsInitialized(); + touch_trigger_src_t triggerSource; + + if (touch_pad_get_trigger_source(&triggerSource) != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + + stack.SetResult_I4(triggerSource); + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); +#endif + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad:: + NativeSetTriggerSource___STATIC__VOID__nanoFrameworkHardwareEsp32TouchWakeUpSource(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +// Not implemented in this IDF version on the S2/S3 || +// defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) +#if defined(CONFIG_IDF_TARGET_ESP32) + + // For static functions, we need to make sure that we have the touch pad initialized + MakeSureTouchIsInitialized(); + touch_trigger_src_t triggerSource = (touch_trigger_src_t)stack.Arg0().NumericByRef().s4; + if (touch_pad_set_trigger_source(triggerSource) != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); +#endif + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad:: + NativeGetMeasurementMode___STATIC__nanoFrameworkHardwareEsp32TouchMeasurementMode(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + + // For static functions, we need to make sure that we have the touch pad initialized + MakeSureTouchIsInitialized(); + + stack.SetResult_I4(measurementMode); + + NANOCLR_NOCLEANUP_NOLABEL(); + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); + NANOCLR_NOCLEANUP(); +#endif +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad:: + NativeSetMeasurementMode___STATIC__VOID__nanoFrameworkHardwareEsp32TouchMeasurementMode(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + + // For static functions, we need to make sure that we have the touch pad initialized + MakeSureTouchIsInitialized(); + measurementMode = (touch_fsm_mode_t)stack.Arg0().NumericByRef().s4; + + // TODO: once we'll use IDF 5.0 or a version where the FSM start is present for ESP32 + // One fixed, you may try: if defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + // if (measurementMode == TOUCH_FSM_MODE_TIMER) + // { + // if (touch_pad_fsm_start() != ESP_OK) + // { + // NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + // } + // } + // else + // { + // if (touch_pad_fsm_stop() != ESP_OK) + // { + // NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + // } + // } + // endif + + // Do we need to stop the task? + if (measurementMode == TOUCH_FSM_MODE_SW) + { + isTimeModeOn = false; + // If we just switch mode, we have to wait for the task to exit + // So killing it + if (handleReadTask != NULL) + { + vTaskDelete(handleReadTask); + } + + // Waiting a bit to make sure the task is properly deleted + vTaskDelay(20 / portTICK_PERIOD_MS); + handleReadTask = NULL; + } + + // We are starting a task when on timer mode. + if (measurementMode == TOUCH_FSM_MODE_TIMER) + { + if (!isTimeModeOn) + { + isTimeModeOn = true; + // Start a task to show what pads have been touched + xTaskCreate(&ReadTask, "ReadTask", 4096, NULL, 5, &handleReadTask); + } + } + + NANOCLR_NOCLEANUP_NOLABEL(); + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); + NANOCLR_NOCLEANUP(); +#endif +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad:: + NativeSetVoltage___STATIC__VOID__nanoFrameworkHardwareEsp32TouchTouchHighVoltage__nanoFrameworkHardwareEsp32TouchTouchLowVoltage__nanoFrameworkHardwareEsp32TouchTouchHighVoltageAttenuation( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + + // For static functions, we need to make sure that we have the touch pad initialized + MakeSureTouchIsInitialized(); + touch_high_volt_t refh = (touch_high_volt_t)stack.Arg0().NumericByRef().s4; + touch_low_volt_t refl = (touch_low_volt_t)stack.Arg1().NumericByRef().s4; + touch_volt_atten_t atten = (touch_volt_atten_t)stack.Arg2().NumericByRef().s4; + + if (touch_pad_set_voltage(refh, refl, atten) != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); +#endif + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad:: + NativeGetVoltage___STATIC__VOID__BYREF_nanoFrameworkHardwareEsp32TouchTouchHighVoltage__BYREF_nanoFrameworkHardwareEsp32TouchTouchLowVoltage__BYREF_nanoFrameworkHardwareEsp32TouchTouchHighVoltageAttenuation( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + + touch_high_volt_t refh; + touch_low_volt_t refl; + touch_volt_atten_t atten; + + // Get the voltage + if (touch_pad_get_voltage(&refh, &refl, &atten) != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + + CLR_RT_HeapBlock bhRefh; + CLR_RT_HeapBlock bhRefl; + CLR_RT_HeapBlock bhAtten; + bhRefh.SetInteger(refh); + NANOCLR_CHECK_HRESULT(bhRefh.StoreToReference(stack.Arg0(), 0)); + bhRefl.SetInteger(refl); + NANOCLR_CHECK_HRESULT(bhRefl.StoreToReference(stack.Arg1(), 0)); + bhAtten.SetInteger(atten); + NANOCLR_CHECK_HRESULT(bhAtten.StoreToReference(stack.Arg2(), 0)); + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); +#endif + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad:: + NativeStartFilter___STATIC__VOID__nanoFrameworkHardwareEsp32TouchIFilterSetting(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + CLR_RT_TypeDescriptor typeParamType; + CLR_RT_HeapBlock *bhPeriodeSetting; + + // Static function, argument 0 is the first argument + bhPeriodeSetting = stack.Arg0().Dereference(); + + // get type descriptor for parameter + NANOCLR_CHECK_HRESULT(typeParamType.InitializeFromObject(*bhPeriodeSetting)); + +#if defined(CONFIG_IDF_TARGET_ESP32) + uint32_t period; + esp_err_t err; + CLR_RT_TypeDef_Index esp32FilteringTypeDef; + CLR_RT_TypeDescriptor esp32FilteringType; + + // init types to compare with bhPeriodeSetting parameter + g_CLR_RT_TypeSystem.FindTypeDef("Esp32FilterSetting", "nanoFramework.Hardware.Esp32.Touch", esp32FilteringTypeDef); + esp32FilteringType.InitializeFromType(esp32FilteringTypeDef); + + // sanity check for parameter type + if (!CLR_RT_ExecutionEngine::IsInstanceOf(typeParamType, esp32FilteringType, false)) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + period = (uint32_t)bhPeriodeSetting[Esp32FilterSetting::FIELD___period].NumericByRef().u4; + + err = touch_pad_filter_start(period); + if (err != ESP_OK) + { + if (err == ESP_ERR_INVALID_ARG) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + else + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + } + + isFilterOn = true; + +#elif defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + touch_filter_config_t filterConfig; + esp_err_t err; + CLR_RT_TypeDef_Index s2s3FilteringTypeDef; + CLR_RT_TypeDescriptor s2s3FilteringType; + + // init types to compare with bhPeriodeSetting parameter + g_CLR_RT_TypeSystem.FindTypeDef("S2S3FilterSetting", "nanoFramework.Hardware.Esp32.Touch", s2s3FilteringTypeDef); + s2s3FilteringType.InitializeFromType(s2s3FilteringTypeDef); + + // sanity check for parameter type + if (!CLR_RT_ExecutionEngine::IsInstanceOf(typeParamType, s2s3FilteringType, false)) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + filterConfig.mode = + (touch_filter_mode_t)bhPeriodeSetting[S2S3FilterSetting::FIELD___periodeSettingMode].NumericByRef().s4; + filterConfig.debounce_cnt = + (uint32_t)bhPeriodeSetting[S2S3FilterSetting::FIELD___filterSettingDebounce].NumericByRef().s4; + filterConfig.noise_thr = + (uint32_t)bhPeriodeSetting[S2S3FilterSetting::FIELD___filterSettingNoiseThreshold].NumericByRef().s4; + filterConfig.jitter_step = (uint32_t)bhPeriodeSetting[S2S3FilterSetting::FIELD___jitterSize].NumericByRef().u1; + filterConfig.smh_lvl = + (touch_smooth_mode_t)bhPeriodeSetting[S2S3FilterSetting::FIELD___filterSettingSmoothMode].NumericByRef().s4; + + err = touch_pad_filter_set_config(&filterConfig); + if (err != ESP_OK) + { + if (err == ESP_ERR_INVALID_ARG) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + else + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + } + + if (touch_pad_filter_enable() != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + + isFilterOn = true; +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); +#endif + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad:: + NativeStopFilter___STATIC__VOID(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + +#if defined(CONFIG_IDF_TARGET_ESP32) + touch_pad_filter_stop(); +#else + touch_pad_filter_disable(); +#endif + + isFilterOn = false; + NANOCLR_NOCLEANUP_NOLABEL(); + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); + NANOCLR_NOCLEANUP(); +#endif +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad:: + NativeSetMeasurementTime___STATIC__VOID__U2__U2(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + + // Static function, argument 0 is the first argument + uint16_t sleep = (uint16_t)stack.Arg0().NumericByRef().u2; + uint16_t meas = (uint16_t)stack.Arg1().NumericByRef().u2; + + if (touch_pad_set_meas_time(sleep, meas) != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); +#endif + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad:: + NativeGetMeasurementTime___STATIC__VOID__BYREF_U2__BYREF_U2(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + + // Static function, argument 0 is the first argument + uint16_t sleep; + uint16_t meas; + + if (touch_pad_get_meas_time(&sleep, &meas) != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + + // Arg0 as we are in a non static function. + CLR_RT_HeapBlock bhSleep; + CLR_RT_HeapBlock bhMeas; + bhSleep.SetInteger(sleep); + NANOCLR_CHECK_HRESULT(bhSleep.StoreToReference(stack.Arg0(), 0)); + bhMeas.SetInteger(meas); + NANOCLR_CHECK_HRESULT(bhMeas.StoreToReference(stack.Arg1(), 0)); + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); +#endif + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad:: + NativeGetDenoise___STATIC__VOID__nanoFrameworkHardwareEsp32TouchDenoiseSetting(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +// Not supported on defined(CONFIG_IDF_TARGET_ESP32) || +#if defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + + CLR_RT_HeapBlock *bhDenoiseSetting; + touch_pad_denoise_t denoise; + bhDenoiseSetting = stack.Arg0().Dereference(); + + if (touch_pad_denoise_get_config(&denoise) != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + + bhDenoiseSetting[DenoiseSetting::FIELD___denoiseCapacitance].NumericByRef().s4 = denoise.cap_level; + bhDenoiseSetting[DenoiseSetting::FIELD___denoiseRange].NumericByRef().s4 = denoise.grade; + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); +#endif + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad:: + NativeDenoiseEnabled___STATIC__VOID__BOOLEAN(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +#if defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + // For static functions, first argument is 0 + bool denoiseEnabled = stack.Arg0().NumericByRef().u4; + + if (denoiseEnabled) + { + if (touch_pad_denoise_enable() != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + } + else + { + if (touch_pad_denoise_disable() != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + } + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); +#endif + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad:: + NativeSetDenoise___STATIC__VOID__nanoFrameworkHardwareEsp32TouchDenoiseSetting(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +// Not supported on defined(CONFIG_IDF_TARGET_ESP32) || +#if defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + + CLR_RT_HeapBlock *bhDenoiseSetting; + touch_pad_denoise_t denoise; + touch_pad_denoise_grade_t grade; + touch_pad_denoise_cap_t capLevel; + bhDenoiseSetting = stack.Arg0().Dereference(); + + grade = (touch_pad_denoise_grade_t)bhDenoiseSetting[DenoiseSetting::FIELD___denoiseRange].NumericByRef().s4; + capLevel = (touch_pad_denoise_cap_t)bhDenoiseSetting[DenoiseSetting::FIELD___denoiseCapacitance].NumericByRef().s4; + + denoise = { + /* The bits to be cancelled are determined according to the noise level. */ + .grade = grade, + .cap_level = capLevel, + }; + + if (touch_pad_denoise_set_config(&denoise) != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); +#endif + + NANOCLR_NOCLEANUP(); +} diff --git a/targets/ESP32/_nanoCLR/nanoFramework.Hardware.Esp32.Rmt/nanoFramework_hardware_esp32_rmt_native.cpp b/targets/ESP32/_nanoCLR/nanoFramework.Hardware.Esp32.Rmt/nanoFramework_hardware_esp32_rmt_native.cpp index 47db6dba12..77d31e9703 100644 --- a/targets/ESP32/_nanoCLR/nanoFramework.Hardware.Esp32.Rmt/nanoFramework_hardware_esp32_rmt_native.cpp +++ b/targets/ESP32/_nanoCLR/nanoFramework.Hardware.Esp32.Rmt/nanoFramework_hardware_esp32_rmt_native.cpp @@ -30,7 +30,25 @@ static const CLR_RT_MethodHandler method_lookup[] = NULL, NULL, NULL, - Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_ReceiverChannel::NativeRxInit___I4__I4__I4, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_ReceiverChannel::NativeRxInit___I4, Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_ReceiverChannel::NativeRxStart___VOID__BOOLEAN, Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_ReceiverChannel::NativeRxStop___VOID, Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_ReceiverChannel::NativeRxGetRingBufferCount___I4, @@ -44,7 +62,46 @@ 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, + Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_RmtChannel::NativeSetGpioPin___VOID__I4__U1__I4__BOOLEAN, Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_RmtChannel::NativeSetClockDivider___VOID__U1, + Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_RmtChannel::NativeSetNumberOfMemoryBlocks___VOID__U1, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, NULL, NULL, NULL, @@ -71,24 +128,22 @@ static const CLR_RT_MethodHandler method_lookup[] = NULL, NULL, NULL, - Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_TransmitterChannel::NativeInit___VOID__I4, - Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_TransmitterChannel::NativeGetIdleLevel___BOOLEAN, - Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_TransmitterChannel::NativeGetIsChannelIdle___BOOLEAN, - Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_TransmitterChannel::NativeSetIsChannelIdle___VOID__BOOLEAN, - Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_TransmitterChannel::NativeSetIdleLevel___VOID__BOOLEAN, - Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_TransmitterChannel::NativeSetCarrierMode___VOID, - Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_TransmitterChannel::NativeWriteItems___U4__SZARRAY_U1__BOOLEAN, - Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_TransmitterChannel::NativeWaitTxDone___U4__I4, - Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_TransmitterChannel::NativeDispose___VOID, - Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_TransmitterChannel::NativeGetSourceClock___BOOLEAN, + Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_TransmitterChannel::NativeTxInit___I4, + Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_TransmitterChannel::NativeTxGetIsChannelIdle___BOOLEAN, + Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_TransmitterChannel::NativeTxSetLoopingMode___VOID__BOOLEAN, + Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_TransmitterChannel::NativeTxSetLoopCount___VOID__I4, + Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_TransmitterChannel::NativeTxSetCarrierMode___VOID, + Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_TransmitterChannel::NativeTxSetIdleLevel___VOID__BOOLEAN, + Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_TransmitterChannel::NativeTxWriteItems___U4__SZARRAY_U1__BOOLEAN, + Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_TransmitterChannel::NativeTxDispose___VOID, }; const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Esp32_Rmt = { "nanoFramework.Hardware.Esp32.Rmt", - 0x0A915860, + 0x608C5658, method_lookup, - { 100, 0, 3, 0 } + { 100, 0, 4, 0 } }; // clang-format on diff --git a/targets/ESP32/_nanoCLR/nanoFramework.Hardware.Esp32.Rmt/nanoFramework_hardware_esp32_rmt_native.h b/targets/ESP32/_nanoCLR/nanoFramework.Hardware.Esp32.Rmt/nanoFramework_hardware_esp32_rmt_native.h index 6835bc4ae2..3cb6fd8f7d 100644 --- a/targets/ESP32/_nanoCLR/nanoFramework.Hardware.Esp32.Rmt/nanoFramework_hardware_esp32_rmt_native.h +++ b/targets/ESP32/_nanoCLR/nanoFramework.Hardware.Esp32.Rmt/nanoFramework_hardware_esp32_rmt_native.h @@ -17,9 +17,13 @@ #include // Reduce line lengths -#define ManagedRmtCommand Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_RmtCommand -#define RmtChannel Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_RmtChannel -#define CHANNEL(channel) static_cast(channel) +#define CHANNEL(channel) static_cast(channel) + +typedef enum __nfpack ChannelMode +{ + ChannelMode_Receive = 0, + ChannelMode_Transmit = 1, +} ChannelMode; typedef enum __nfpack SourceClock { @@ -39,9 +43,9 @@ struct Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Es struct Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_ReceiverChannel { - static const int FIELD___receiveTimeout = 4; + static const int FIELD___receiverChannelSettings = 2; - NANOCLR_NATIVE_DECLARE(NativeRxInit___I4__I4__I4); + NANOCLR_NATIVE_DECLARE(NativeRxInit___I4); NANOCLR_NATIVE_DECLARE(NativeRxStart___VOID__BOOLEAN); NANOCLR_NATIVE_DECLARE(NativeRxStop___VOID); NANOCLR_NATIVE_DECLARE(NativeRxGetRingBufferCount___I4); @@ -52,26 +56,41 @@ struct Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Es //--// + static rmt_config_t GetNewRmtRxConfig(gpio_num_t pin, rmt_channel_t channel); + static HRESULT CreateRmtArrayOnStack( CLR_RT_StackFrame &stack, CLR_INT32 numItems, CLR_RT_TypeDef_Index &rmtCommandTypeDef, CLR_RT_HeapBlock **arrayDataPtr); + static HRESULT CreateRmtElement( rmt_item32_t *rmtItem, CLR_RT_HeapBlock *returnArray, CLR_RT_TypeDef_Index &rmtCommandTypeDef); +}; - static esp_err_t InitRxChannel(rmt_channel_t channel, gpio_num_t gpio, int32_t rmtBufferSize, int32_t clockDiv); +struct Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_ReceiverChannelSettings +{ + static const int FIELD___idleThreshold = 7; + static const int FIELD___enableFilter = 8; + static const int FIELD___filterThreshold = 9; + static const int FIELD___receiveTimeout = 10; + static const int FIELD___enableDemodulation = 11; + static const int FIELD___carrierWaveFrequency = 12; + static const int FIELD___carrierWaveDutyPercentage = 13; + static const int FIELD___carrierLevel = 14; + + //--// }; struct Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_RmtChannel { - static const int FIELD___channel = 1; - static const int FIELD___clockDivider = 2; - static const int FIELD___sourceClock = 3; + static const int FIELD___settings = 1; + NANOCLR_NATIVE_DECLARE(NativeSetGpioPin___VOID__I4__U1__I4__BOOLEAN); NANOCLR_NATIVE_DECLARE(NativeSetClockDivider___VOID__U1); + NANOCLR_NATIVE_DECLARE(NativeSetNumberOfMemoryBlocks___VOID__U1); //--// @@ -81,28 +100,49 @@ struct Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Es static CLR_INT32 FindNextChannel(); }; +struct Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_RmtChannelSettings +{ + static const int FIELD___channel = 1; + static const int FIELD___pinNumber = 2; + static const int FIELD___clockDivider = 3; + static const int FIELD___numberOfMemoryBlocks = 4; + static const int FIELD___bufferSize = 5; + static const int FIELD___signalInverterEnabled = 6; + + //--// +}; + +struct Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_TransmitChannelSettings +{ + static const int FIELD___enableCarrierWave = 7; + static const int FIELD___carrierLevel = 8; + static const int FIELD___carrierWaveFrequency = 9; + static const int FIELD___carrierWaveDutyPercentage = 10; + static const int FIELD___enableLooping = 11; + static const int FIELD___loopCount = 12; + static const int FIELD___enableIdleLevelOutput = 13; + static const int FIELD___idleLevel = 14; + + //--// +}; + struct Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_TransmitterChannel { - static const int FIELD___carrierEnabled = 4; - static const int FIELD___carrierHighDuration = 5; - static const int FIELD___carrierLowDuration = 6; - static const int FIELD___carrierLevel = 7; - static const int FIELD___commands = 8; - - NANOCLR_NATIVE_DECLARE(NativeInit___VOID__I4); - NANOCLR_NATIVE_DECLARE(NativeGetIdleLevel___BOOLEAN); - NANOCLR_NATIVE_DECLARE(NativeGetIsChannelIdle___BOOLEAN); - NANOCLR_NATIVE_DECLARE(NativeSetIsChannelIdle___VOID__BOOLEAN); - NANOCLR_NATIVE_DECLARE(NativeSetIdleLevel___VOID__BOOLEAN); - NANOCLR_NATIVE_DECLARE(NativeSetCarrierMode___VOID); - NANOCLR_NATIVE_DECLARE(NativeWriteItems___U4__SZARRAY_U1__BOOLEAN); - NANOCLR_NATIVE_DECLARE(NativeWaitTxDone___U4__I4); - NANOCLR_NATIVE_DECLARE(NativeDispose___VOID); - NANOCLR_NATIVE_DECLARE(NativeGetSourceClock___BOOLEAN); + static const int FIELD___transmitterChannelSettings = 2; + static const int FIELD___commands = 3; + + NANOCLR_NATIVE_DECLARE(NativeTxInit___I4); + NANOCLR_NATIVE_DECLARE(NativeTxGetIsChannelIdle___BOOLEAN); + NANOCLR_NATIVE_DECLARE(NativeTxSetLoopingMode___VOID__BOOLEAN); + NANOCLR_NATIVE_DECLARE(NativeTxSetLoopCount___VOID__I4); + NANOCLR_NATIVE_DECLARE(NativeTxSetCarrierMode___VOID); + NANOCLR_NATIVE_DECLARE(NativeTxSetIdleLevel___VOID__BOOLEAN); + NANOCLR_NATIVE_DECLARE(NativeTxWriteItems___U4__SZARRAY_U1__BOOLEAN); + NANOCLR_NATIVE_DECLARE(NativeTxDispose___VOID); //--// - static esp_err_t InitTxChannel(rmt_channel_t channel, gpio_num_t gpio); + static rmt_config_t GetNewRmtTxConfig(gpio_num_t pin, rmt_channel_t channel); }; extern const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Esp32_Rmt; diff --git a/targets/ESP32/_nanoCLR/nanoFramework.Hardware.Esp32.Rmt/nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_ReceiverChannel.cpp b/targets/ESP32/_nanoCLR/nanoFramework.Hardware.Esp32.Rmt/nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_ReceiverChannel.cpp index 58a6e50e6c..0aac0e0919 100644 --- a/targets/ESP32/_nanoCLR/nanoFramework.Hardware.Esp32.Rmt/nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_ReceiverChannel.cpp +++ b/targets/ESP32/_nanoCLR/nanoFramework.Hardware.Esp32.Rmt/nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_ReceiverChannel.cpp @@ -5,30 +5,97 @@ #include "nanoFramework_hardware_esp32_rmt_native.h" +// typedefs for manged types to improve readability +typedef Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_RmtChannelSettings + RmtChannelSettings; +typedef Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_ReceiverChannelSettings + ReceiverChannelSettings; +typedef Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_RmtChannel RmtChannel; +typedef Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_RmtCommand ManagedRmtCommand; + +//--// + HRESULT Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_ReceiverChannel:: - NativeRxInit___I4__I4__I4(CLR_RT_StackFrame &stack) + NativeRxInit___I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); - gpio_num_t gpio_number; - CLR_INT32 channel; - CLR_INT32 bufferSizeRmtItems; - CLR_INT32 clockDiv = 80; // Default - gpio_number = (gpio_num_t)stack.Arg1().NumericByRef().s1; - bufferSizeRmtItems = (CLR_INT32)stack.Arg2().NumericByRef().s4; + int32_t channel; + int32_t pin_number = 0; + int32_t ring_buff_size; + esp_err_t err; + + CLR_RT_HeapBlock *receiver_channel_settings; + + // get a pointer to the managed object instance and check that it's not NULL + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + + // get a reference to the configs in the managed code instance + receiver_channel_settings = pThis[FIELD___receiverChannelSettings].Dereference(); + + channel = receiver_channel_settings[RmtChannelSettings::FIELD___channel].NumericByRef().s4; + pin_number = receiver_channel_settings[RmtChannelSettings::FIELD___pinNumber].NumericByRef().s4; - channel = RmtChannel::FindNextChannel(); if (channel < 0) { - NANOCLR_SET_AND_LEAVE(CLR_E_DRIVER_NOT_REGISTERED); + channel = RmtChannel::FindNextChannel(); + if (channel < 0) + { + NANOCLR_SET_AND_LEAVE(CLR_E_DRIVER_NOT_REGISTERED); + } } - if (InitRxChannel((rmt_channel_t)channel, gpio_number, bufferSizeRmtItems, clockDiv) != ESP_OK) + { + rmt_config_t rmt_rx_config = GetNewRmtRxConfig((gpio_num_t)pin_number, (rmt_channel_t)channel); + + rmt_rx_config.clk_div = receiver_channel_settings[RmtChannelSettings::FIELD___clockDivider].NumericByRef().u1; + rmt_rx_config.mem_block_num = + receiver_channel_settings[RmtChannelSettings::FIELD___numberOfMemoryBlocks].NumericByRef().u1; + rmt_rx_config.rx_config.idle_threshold = + receiver_channel_settings[ReceiverChannelSettings::FIELD___idleThreshold].NumericByRef().u2; + rmt_rx_config.rx_config.filter_en = + receiver_channel_settings[ReceiverChannelSettings::FIELD___enableFilter].NumericByRef().u1 != 0; + rmt_rx_config.rx_config.filter_ticks_thresh = + receiver_channel_settings[ReceiverChannelSettings::FIELD___filterThreshold].NumericByRef().u1; + +#if SOC_RMT_SUPPORT_RX_DEMODULATION + + rmt_rx_config.rx_config.rm_carrier = + receiver_channel_settings[ReceiverChannelSettings::FIELD___enableDemodulation].NumericByRef().u1 != 0; + rmt_rx_config.rx_config.carrier_freq_hz = + receiver_channel_settings[ReceiverChannelSettings::FIELD___carrierWaveFrequency].NumericByRef().u4; + rmt_rx_config.rx_config.carrier_duty_percent = + receiver_channel_settings[ReceiverChannelSettings::FIELD___carrierWaveDutyPercentage].NumericByRef().u1; + rmt_rx_config.rx_config.carrier_level = + (bool)receiver_channel_settings[ReceiverChannelSettings::FIELD___carrierLevel].NumericByRef().u1 + ? RMT_CARRIER_LEVEL_HIGH + : RMT_CARRIER_LEVEL_LOW; + +#endif + + err = rmt_config(&rmt_rx_config); + if (err != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_DRIVER_NOT_REGISTERED); + } + } + + ring_buff_size = receiver_channel_settings[RmtChannelSettings::FIELD___bufferSize].NumericByRef().s4; + ring_buff_size *= sizeof(rmt_item32_t); + + err = rmt_driver_install((rmt_channel_t)channel, ring_buff_size, 0); + if (err != ESP_OK) { NANOCLR_SET_AND_LEAVE(CLR_E_DRIVER_NOT_REGISTERED); } - stack.SetResult_I4(channel); + RmtChannel::registredChannels.emplace( + std::piecewise_construct, + std::forward_as_tuple((rmt_channel_t)channel), + std::forward_as_tuple()); + + stack.SetResult_I4((CLR_INT32)channel); NANOCLR_NOCLEANUP(); } @@ -37,42 +104,49 @@ HRESULT Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_E NativeRxStart___VOID__BOOLEAN(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); - { - CLR_INT32 channel; - bool clearBuffer; - CLR_RT_HeapBlock *pThis = stack.This(); - FAULT_ON_NULL(pThis); + CLR_RT_HeapBlock *receiver_channel_settings = NULL; + CLR_INT32 channel; + bool clearBuffer; + esp_err_t err; - clearBuffer = stack.Arg1().NumericByRefConst().u1 != 0; + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); - channel = pThis[RmtChannel::FIELD___channel].NumericByRef().s4; + // get a reference to the configs in the managed code instance + receiver_channel_settings = pThis[FIELD___receiverChannelSettings].Dereference(); - if (clearBuffer) - { - RingbufHandle_t ringbufHandle; - auto err = rmt_get_ringbuf_handle((rmt_channel_t)channel, &ringbufHandle); - if (err != ESP_OK) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } + channel = receiver_channel_settings[RmtChannelSettings::FIELD___channel].NumericByRef().s4; - // Clear ring buffer - size_t length = 0; - rmt_item32_t *rmtItems; - while ((rmtItems = (rmt_item32_t *)xRingbufferReceive(ringbufHandle, &length, 0)) != NULL) - { - // Release items back to Ringbuffer - vRingbufferReturnItem(ringbufHandle, (void *)rmtItems); - }; - } + clearBuffer = stack.Arg1().NumericByRefConst().u1 != 0; - auto err = rmt_rx_start((rmt_channel_t)channel, clearBuffer); + if (clearBuffer) + { + RingbufHandle_t ringbufHandle; + + err = rmt_get_ringbuf_handle((rmt_channel_t)channel, &ringbufHandle); if (err != ESP_OK) { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } + + // Clear ring buffer + size_t length = 0; + rmt_item32_t *rmtItems; + + while ((rmtItems = (rmt_item32_t *)xRingbufferReceive(ringbufHandle, &length, 0)) != NULL) + { + // Release items back to Ringbuffer + vRingbufferReturnItem(ringbufHandle, (void *)rmtItems); + }; + } + + err = rmt_rx_start((rmt_channel_t)channel, clearBuffer); + if (err != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); } + NANOCLR_NOCLEANUP(); } @@ -80,20 +154,24 @@ HRESULT Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_E NativeRxStop___VOID(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); - { - CLR_INT32 channel; - CLR_RT_HeapBlock *pThis = stack.This(); - FAULT_ON_NULL(pThis); + CLR_RT_HeapBlock *receiver_channel_settings = NULL; + CLR_INT32 channel; + esp_err_t err; - channel = pThis[RmtChannel::FIELD___channel].NumericByRef().s4; + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); - auto err = rmt_rx_stop((rmt_channel_t)channel); - if (err != ESP_OK) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); - } + // get a reference to the configs in the managed code instance + receiver_channel_settings = pThis[FIELD___receiverChannelSettings].Dereference(); + channel = receiver_channel_settings[RmtChannelSettings::FIELD___channel].NumericByRef().s4; + + err = rmt_rx_stop((rmt_channel_t)channel); + if (err != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); } + NANOCLR_NOCLEANUP(); } @@ -101,37 +179,43 @@ HRESULT Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_E NativeRxGetRingBufferCount___I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); - { - CLR_INT32 channel; - esp_err_t err; - RingbufHandle_t ringbufHandle; - CLR_RT_HeapBlock *pThis = stack.This(); - FAULT_ON_NULL(pThis); + CLR_INT32 channel; + esp_err_t err; + RingbufHandle_t ringbufHandle; + UBaseType_t uxItemsWaiting; - channel = pThis[RmtChannel::FIELD___channel].NumericByRef().s4; + CLR_RT_HeapBlock *receiver_channel_settings = NULL; - err = rmt_get_ringbuf_handle((rmt_channel_t)channel, &ringbufHandle); - if (err != ESP_OK) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); - UBaseType_t uxItemsWaiting; - vRingbufferGetInfo(ringbufHandle, NULL, NULL, NULL, NULL, &uxItemsWaiting); + // get a reference to the configs in the managed code instance + receiver_channel_settings = pThis[FIELD___receiverChannelSettings].Dereference(); + channel = receiver_channel_settings[RmtChannelSettings::FIELD___channel].NumericByRef().s4; - stack.SetResult_I4(uxItemsWaiting); + err = rmt_get_ringbuf_handle((rmt_channel_t)channel, &ringbufHandle); + if (err != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } + + vRingbufferGetInfo(ringbufHandle, NULL, NULL, NULL, NULL, &uxItemsWaiting); + + stack.SetResult_I4(uxItemsWaiting); + NANOCLR_NOCLEANUP(); } HRESULT Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_ReceiverChannel:: CreateRmtElement(rmt_item32_t *rmtItem, CLR_RT_HeapBlock *returnArray, CLR_RT_TypeDef_Index &rmtCommandTypeDef) { - NANOCLR_HEADER(); + HRESULT hr = S_OK; + + // create a new RmtCommand object and put it on the return array + hr = g_CLR_RT_ExecutionEngine.NewObjectFromIndex(*returnArray, rmtCommandTypeDef); + if (hr == S_OK) { - // create a new RmtCommand object and put it on the return array - NANOCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.NewObjectFromIndex(*returnArray, rmtCommandTypeDef)); // Set each value in the struct from the rmt_item32_t data CLR_RT_HeapBlock *dref = returnArray->Dereference(); @@ -152,7 +236,8 @@ HRESULT Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_E int32_t *l1 = (int32_t *)&level1FieldRef.NumericByRef().u1; *l1 = rmtItem->level1; } - NANOCLR_NOCLEANUP(); + + return hr; } HRESULT Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_ReceiverChannel:: @@ -162,94 +247,99 @@ HRESULT Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_E CLR_RT_TypeDef_Index &rmtCommandTypeDef, CLR_RT_HeapBlock **arrayDataPtr) { - NANOCLR_HEADER(); + HRESULT hr = S_OK; + + if (!g_CLR_RT_TypeSystem.FindTypeDef("RmtCommand", "nanoFramework.Hardware.Esp32.Rmt", rmtCommandTypeDef)) { - if (!g_CLR_RT_TypeSystem.FindTypeDef("RmtCommand", "nanoFramework.Hardware.Esp32.Rmt", rmtCommandTypeDef)) - { - // Type not defined, build problem - NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); - } + // Type not defined, build problem + return CLR_E_NOT_SUPPORTED; + } - // Create Array on top of stackof type "RmtCommand" - NANOCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance( - stack.PushValue(), - numItems, - rmtCommandTypeDef)); // g_CLR_RT_WellKnownTypes.m_Object )); + // Create Array on top of stackof type "RmtCommand" + hr = CLR_RT_HeapBlock_Array::CreateInstance(stack.PushValue(), numItems, rmtCommandTypeDef); + if (hr == S_OK) + { // Get reference to Array CLR_RT_HeapBlock_Array *array = stack.TopValue().DereferenceArray(); // Get start of array data, array of CLR_RT_HeapBlock * to RmtCommand structs *arrayDataPtr = (CLR_RT_HeapBlock *)array->GetFirstElement(); } - NANOCLR_NOCLEANUP(); + + return hr; } HRESULT Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_ReceiverChannel:: NativeRxGetAllItems___SZARRAY_nanoFrameworkHardwareEsp32RmtRmtCommand(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); - { - CLR_INT32 channel; - // CLR_RT_HeapBlock *pRetVal = NULL; - esp_err_t err; - RingbufHandle_t ringbufHandle; - CLR_INT32 waitMs; - rmt_item32_t *rmtItems = NULL; - CLR_RT_HeapBlock *pThis = stack.This(); - FAULT_ON_NULL(pThis); + CLR_INT32 channel; + esp_err_t err; + RingbufHandle_t ringbufHandle; + CLR_INT32 waitMs; + CLR_INT64 *timespan; + size_t length = 0; + rmt_item32_t *rmtItems = NULL; - channel = pThis[RmtChannel::FIELD___channel].NumericByRef().s4; + CLR_RT_HeapBlock *receiver_channel_settings = NULL; - err = rmt_get_ringbuf_handle((rmt_channel_t)channel, &ringbufHandle); - if (err != ESP_OK) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); - // Timespan in 100ns ticks - CLR_INT64 *timespan = Library_corlib_native_System_TimeSpan::GetValuePtr(pThis[FIELD___receiveTimeout]); - // Convert to milli-secs for wait - waitMs = (CLR_INT32)(*timespan / TIME_CONVERSION__TO_MILLISECONDS); + // get a reference to the configs in the managed code instance + receiver_channel_settings = pThis[FIELD___receiverChannelSettings].Dereference(); + channel = receiver_channel_settings[RmtChannelSettings::FIELD___channel].NumericByRef().s4; - // Get next Rmt item from ring buffer - size_t length = 0; - rmtItems = (rmt_item32_t *)xRingbufferReceive(ringbufHandle, &length, pdMS_TO_TICKS(waitMs)); - if (rmtItems) + err = rmt_get_ringbuf_handle((rmt_channel_t)channel, &ringbufHandle); + if (err != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + // Timespan in 100ns ticks + timespan = Library_corlib_native_System_TimeSpan::GetValuePtr( + receiver_channel_settings[ReceiverChannelSettings::FIELD___receiveTimeout]); + // Convert to milli-secs for wait + waitMs = (CLR_INT32)(*timespan / TIME_CONVERSION__TO_MILLISECONDS); + + // Get next Rmt item from ring buffer + rmtItems = (rmt_item32_t *)xRingbufferReceive(ringbufHandle, &length, pdMS_TO_TICKS(waitMs)); + if (rmtItems) + { + if (length > 0) { - if (length > 0) - { - CLR_RT_HeapBlock *arrayDataPtr; - CLR_RT_TypeDef_Index rmtCommandTypeDef; + CLR_RT_HeapBlock *arrayDataPtr; + CLR_RT_TypeDef_Index rmtCommandTypeDef; - int numItems = length / sizeof(rmt_item32_t); + int numItems = length / sizeof(rmt_item32_t); - // Build Header block for Array of RmtCommands objects on top of stack - // Returns the rmtCommand type and pointer to first data ptr in array - NANOCLR_CHECK_HRESULT(CreateRmtArrayOnStack(stack, numItems, rmtCommandTypeDef, &arrayDataPtr)); + // Build Header block for Array of RmtCommands objects on top of stack + // Returns the rmtCommand type and pointer to first data ptr in array + NANOCLR_CHECK_HRESULT(CreateRmtArrayOnStack(stack, numItems, rmtCommandTypeDef, &arrayDataPtr)); - rmt_item32_t *pData = rmtItems; - while (numItems-- > 0) - { - // Add RMT item to managed array - NANOCLR_CHECK_HRESULT(CreateRmtElement(pData, arrayDataPtr, rmtCommandTypeDef)); + rmt_item32_t *pData = rmtItems; + while (numItems-- > 0) + { + // Add RMT item to managed array + NANOCLR_CHECK_HRESULT(CreateRmtElement(pData, arrayDataPtr, rmtCommandTypeDef)); - // Next item - pData++; - arrayDataPtr++; - } + // Next item + pData++; + arrayDataPtr++; } - - // Release items back to Ringbuffer - vRingbufferReturnItem(ringbufHandle, (void *)rmtItems); } - if (length == 0) - { - stack.SetResult_Object(NULL); - } + // Release items back to Ringbuffer + vRingbufferReturnItem(ringbufHandle, (void *)rmtItems); + } + + if (length == 0) + { + stack.SetResult_Object(NULL); } + NANOCLR_NOCLEANUP(); } @@ -257,21 +347,30 @@ HRESULT Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_E NativeRxEnableFilter___VOID__BOOLEAN__U1(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); - { - CLR_RT_HeapBlock *pThis = stack.This(); - FAULT_ON_NULL(pThis); - bool enableFilter = stack.Arg1().NumericByRefConst().u1 != 0; - uint8_t threshold = stack.Arg2().NumericByRefConst().u1; + CLR_INT32 channel; + bool enableFilter; + uint8_t threshold; + esp_err_t err; - CLR_INT32 channel = pThis[RmtChannel::FIELD___channel].NumericByRef().s4; + CLR_RT_HeapBlock *receiver_channel_settings = NULL; - esp_err_t err = rmt_set_rx_filter((rmt_channel_t)channel, enableFilter, threshold); - if (err != ESP_OK) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); - } + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + + enableFilter = stack.Arg1().NumericByRefConst().u1 != 0; + threshold = stack.Arg2().NumericByRefConst().u1; + + // get a reference to the configs in the managed code instance + receiver_channel_settings = pThis[FIELD___receiverChannelSettings].Dereference(); + channel = receiver_channel_settings[RmtChannelSettings::FIELD___channel].NumericByRef().s4; + + err = rmt_set_rx_filter((rmt_channel_t)channel, enableFilter, threshold); + if (err != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); } + NANOCLR_NOCLEANUP(); } @@ -279,20 +378,29 @@ HRESULT Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_E NativeRxSetIdleThresold___VOID__U2(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); - { - CLR_RT_HeapBlock *pThis = stack.This(); - FAULT_ON_NULL(pThis); - uint16_t threshold = stack.Arg1().NumericByRefConst().u2; + uint16_t threshold; + CLR_INT32 channel; + esp_err_t err; + + CLR_RT_HeapBlock *receiver_channel_settings = NULL; - CLR_INT32 channel = pThis[RmtChannel::FIELD___channel].NumericByRef().s4; + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); - esp_err_t err = rmt_set_rx_idle_thresh((rmt_channel_t)channel, threshold); - if (err != ESP_OK) - { - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - } + threshold = stack.Arg1().NumericByRefConst().u2; + + // get a reference to the configs in the managed code instance + receiver_channel_settings = pThis[FIELD___receiverChannelSettings].Dereference(); + + channel = receiver_channel_settings[RmtChannelSettings::FIELD___channel].NumericByRef().s4; + + err = rmt_set_rx_idle_thresh((rmt_channel_t)channel, threshold); + if (err != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } + NANOCLR_NOCLEANUP(); } @@ -300,55 +408,56 @@ HRESULT Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_E NativeRxDispose___VOID(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); - { - CLR_RT_HeapBlock *pThis = stack.This(); - FAULT_ON_NULL(pThis); - CLR_INT32 channel = pThis[RmtChannel::FIELD___channel].NumericByRef().s4; + CLR_INT32 channel; - if (RmtChannel::registredChannels.find((rmt_channel_t)channel) == RmtChannel::registredChannels.end()) - { - NANOCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); - } + CLR_RT_HeapBlock *receiver_channel_settings = NULL; - if (rmt_driver_uninstall((rmt_channel_t)channel) != ESP_OK) - { - hr = CLR_E_PROCESS_EXCEPTION; - } + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); - RmtChannel::registredChannels.erase((rmt_channel_t)channel); + // get a reference to the configs in the managed code instance + receiver_channel_settings = pThis[FIELD___receiverChannelSettings].Dereference(); + channel = receiver_channel_settings[RmtChannelSettings::FIELD___channel].NumericByRef().s4; + + if (RmtChannel::registredChannels.find((rmt_channel_t)channel) == RmtChannel::registredChannels.end()) + { + NANOCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); } - NANOCLR_NOCLEANUP(); -} -esp_err_t Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_ReceiverChannel:: - InitRxChannel(rmt_channel_t channel, gpio_num_t gpio, int32_t bufferSizeRmtItems, int32_t clockDiv) -{ - rmt_config_t rmt_rxconfig{}; - - rmt_rxconfig.rmt_mode = RMT_MODE_RX; // Channel mode - rmt_rxconfig.channel = channel; // Channel - rmt_rxconfig.clk_div = clockDiv; // Channel counter divider - // 80,000,000 / 80 = 1,000,000 or 1us tick - rmt_rxconfig.gpio_num = gpio; // GPIO number - rmt_rxconfig.mem_block_num = 1; // number of memory blocks - - rmt_rxconfig.rx_config.filter_en = false; // No filter or theshold - rmt_rxconfig.rx_config.filter_ticks_thresh = 0; - rmt_rxconfig.rx_config.idle_threshold = 0; - auto err = rmt_config(&rmt_rxconfig); - if (err != ESP_OK) - return err; + if (rmt_driver_uninstall((rmt_channel_t)channel) != ESP_OK) + { + hr = CLR_E_PROCESS_EXCEPTION; + } - int32_t ringBufferSize = bufferSizeRmtItems * sizeof(rmt_item32_t); - err = rmt_driver_install(channel, ringBufferSize, 0); - if (err != ESP_OK) - return err; + RmtChannel::registredChannels.erase((rmt_channel_t)channel); - RmtChannel::registredChannels.emplace( - std::piecewise_construct, - std::forward_as_tuple(channel), - std::forward_as_tuple()); + NANOCLR_NOCLEANUP(); +} - return ESP_OK; +rmt_config_t Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_ReceiverChannel:: + GetNewRmtRxConfig(gpio_num_t pin, rmt_channel_t channel) +{ + rmt_config_t config = rmt_config_t(); + + config.rmt_mode = RMT_MODE_RX; + config.channel = channel; + config.gpio_num = pin; + config.clk_div = 80; + config.mem_block_num = 1; + config.flags = 0; + + config.rx_config = rmt_rx_config_t(); + config.rx_config.idle_threshold = 12000; + config.rx_config.filter_ticks_thresh = 100; + config.rx_config.filter_en = true; + +#if SOC_RMT_SUPPORT_RX_DEMODULATION + config.rx_config.rm_carrier = true; + config.rx_config.carrier_freq_hz = 38000; + config.rx_config.carrier_duty_percent = 33; + config.rx_config.carrier_level = RMT_CARRIER_LEVEL_HIGH; +#endif + + return config; } diff --git a/targets/ESP32/_nanoCLR/nanoFramework.Hardware.Esp32.Rmt/nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_RmtChannel.cpp b/targets/ESP32/_nanoCLR/nanoFramework.Hardware.Esp32.Rmt/nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_RmtChannel.cpp index a5576e14c4..f2f74ee047 100644 --- a/targets/ESP32/_nanoCLR/nanoFramework.Hardware.Esp32.Rmt/nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_RmtChannel.cpp +++ b/targets/ESP32/_nanoCLR/nanoFramework.Hardware.Esp32.Rmt/nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_RmtChannel.cpp @@ -8,18 +8,54 @@ std::map> Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_RmtChannel::registredChannels; +typedef Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_RmtChannelSettings + RmtChannelSettings; + +HRESULT Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_RmtChannel:: + NativeSetGpioPin___VOID__I4__U1__I4__BOOLEAN(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + rmt_channel_t channel = CHANNEL(stack.Arg1().NumericByRef().s4); + uint8_t mode = stack.Arg2().NumericByRef().u1; + int32_t pin = stack.Arg3().NumericByRef().s4; + bool invert_signal = (bool)stack.Arg4().NumericByRef().u1; + + rmt_mode_t rmt_mode; + if (mode == 0x00) + { + rmt_mode = RMT_MODE_RX; + } + else + { + rmt_mode = RMT_MODE_TX; + } + + auto err = rmt_set_gpio(channel, rmt_mode, (gpio_num_t)pin, invert_signal); + if (err != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(stack.NotImplementedStub()); + } + + NANOCLR_NOCLEANUP(); +} + HRESULT Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_RmtChannel:: NativeSetClockDivider___VOID__U1(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); + CLR_RT_HeapBlock *channel_settings = NULL; int32_t channel; uint8_t clockdiv = (uint8_t)stack.Arg1().NumericByRef().u1; CLR_RT_HeapBlock *pThis = stack.This(); FAULT_ON_NULL(pThis); - channel = (int32_t)pThis[FIELD___channel].NumericByRef().s4; + // get a reference to the configs in the managed code instance + channel_settings = pThis[FIELD___settings].Dereference(); + channel = channel_settings[RmtChannelSettings::FIELD___channel].NumericByRef().s4; + if (!CheckChannel(channel)) { NANOCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); @@ -30,6 +66,37 @@ HRESULT Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_E NANOCLR_NOCLEANUP(); } +HRESULT Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_RmtChannel:: + NativeSetNumberOfMemoryBlocks___VOID__U1(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + { + CLR_RT_HeapBlock *channel_settings = NULL; + int32_t channel; + uint8_t rmt_mem_num; + + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + + // get a reference to the configs in the managed code instance + channel_settings = pThis[FIELD___settings].Dereference(); + channel = channel_settings[RmtChannelSettings::FIELD___channel].NumericByRef().s4; + + if (!CheckChannel(channel)) + { + NANOCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); + } + + rmt_mem_num = (uint8_t)channel_settings[RmtChannelSettings::FIELD___numberOfMemoryBlocks].NumericByRef().u1; + auto err = rmt_set_mem_block_num((rmt_channel_t)channel, rmt_mem_num); + if (err != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + } + NANOCLR_NOCLEANUP(); +} + // // Search map for next free Channel and return channel number. // return -1 if no free channels. diff --git a/targets/ESP32/_nanoCLR/nanoFramework.Hardware.Esp32.Rmt/nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_TransmitterChannel.cpp b/targets/ESP32/_nanoCLR/nanoFramework.Hardware.Esp32.Rmt/nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_TransmitterChannel.cpp index db8ba568fb..6d0883522d 100644 --- a/targets/ESP32/_nanoCLR/nanoFramework.Hardware.Esp32.Rmt/nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_TransmitterChannel.cpp +++ b/targets/ESP32/_nanoCLR/nanoFramework.Hardware.Esp32.Rmt/nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_TransmitterChannel.cpp @@ -6,61 +6,128 @@ #include #include "nanoFramework_hardware_esp32_rmt_native.h" -#define DEFAULT_DIVIDER 4 +typedef Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_RmtChannel RmtChannel; +typedef Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_RmtChannelSettings + RmtChannelSettings; +typedef Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_TransmitChannelSettings + TransmitterChannelSettings; HRESULT Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_TransmitterChannel:: - NativeInit___VOID__I4(CLR_RT_StackFrame &stack) + NativeTxInit___I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); - uint8_t gpio_number; - CLR_INT32 channel; + { + CLR_RT_HeapBlock *transmitter_channel_settings = NULL; + int32_t channel; + int32_t pin_number; - CLR_RT_HeapBlock *pThis = stack.This(); - FAULT_ON_NULL(pThis); + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); - gpio_number = (uint8_t)stack.Arg1().NumericByRef().s1; + // get a reference to the configs in the managed code instance + transmitter_channel_settings = pThis[FIELD___transmitterChannelSettings].Dereference(); - channel = RmtChannel::FindNextChannel(); + channel = transmitter_channel_settings[RmtChannelSettings::FIELD___channel].NumericByRef().s4; + pin_number = transmitter_channel_settings[RmtChannelSettings::FIELD___pinNumber].NumericByRef().s4; - if (channel < 0) - { - hr = CLR_E_DRIVER_NOT_REGISTERED; - NANOCLR_LEAVE(); - } + if (channel < 0) + { + channel = RmtChannel::FindNextChannel(); + if (channel < 0) + { + NANOCLR_SET_AND_LEAVE(CLR_E_DRIVER_NOT_REGISTERED); + } + } - // this is always true, as we are currently only supporting this clock mode - ::RMT.conf_ch[(rmt_channel_t)channel].conf1.ref_always_on = true; + rmt_config_t rmt_tx_config = GetNewRmtTxConfig((gpio_num_t)pin_number, (rmt_channel_t)channel); + rmt_tx_config.clk_div = + transmitter_channel_settings[RmtChannelSettings::FIELD___clockDivider].NumericByRef().u1; + rmt_tx_config.mem_block_num = + transmitter_channel_settings[RmtChannelSettings::FIELD___numberOfMemoryBlocks].NumericByRef().u1; + rmt_tx_config.tx_config.carrier_en = + (bool)transmitter_channel_settings[TransmitterChannelSettings::FIELD___enableCarrierWave].NumericByRef().u1; + rmt_tx_config.tx_config.carrier_freq_hz = + transmitter_channel_settings[TransmitterChannelSettings::FIELD___carrierWaveFrequency].NumericByRef().u4; - if (InitTxChannel((rmt_channel_t)channel, (gpio_num_t)gpio_number) != ESP_OK) - { - hr = CLR_E_DRIVER_NOT_REGISTERED; - NANOCLR_LEAVE(); - } + bool carrier_level = + (bool)transmitter_channel_settings[TransmitterChannelSettings::FIELD___carrierLevel].NumericByRef().u1; + rmt_tx_config.tx_config.carrier_level = carrier_level ? RMT_CARRIER_LEVEL_HIGH : RMT_CARRIER_LEVEL_LOW; + + rmt_tx_config.tx_config.carrier_duty_percent = + transmitter_channel_settings[TransmitterChannelSettings::FIELD___carrierWaveDutyPercentage] + .NumericByRef() + .u1; + rmt_tx_config.tx_config.loop_en = + (bool)transmitter_channel_settings[TransmitterChannelSettings::FIELD___enableLooping].NumericByRef().u1; + +#if SOC_RMT_SUPPORT_TX_LOOP_COUNT + + rmt_tx_config.tx_config.loop_count = + transmitter_channel_settings[TransmitterChannelSettings::FIELD___loopCount].NumericByRef().u4; + +#endif + + rmt_tx_config.tx_config.idle_output_en = + (bool)transmitter_channel_settings[TransmitterChannelSettings::FIELD___enableIdleLevelOutput] + .NumericByRef() + .u1; + + bool idle_level = + (bool)transmitter_channel_settings[TransmitterChannelSettings::FIELD___idleLevel].NumericByRef().u1; + rmt_tx_config.tx_config.idle_level = idle_level ? RMT_IDLE_LEVEL_HIGH : RMT_IDLE_LEVEL_LOW; + + bool invert_signal = + (bool)transmitter_channel_settings[RmtChannelSettings::FIELD___signalInverterEnabled].NumericByRef().u1; + if (invert_signal) + { + rmt_tx_config.flags = RMT_CHANNEL_FLAGS_INVERT_SIG; + } + + auto err = rmt_config(&rmt_tx_config); + if (err != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_DRIVER_NOT_REGISTERED); + } + + err = rmt_driver_install((rmt_channel_t)channel, 0, 0); // no ring buffer needed + if (err != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_DRIVER_NOT_REGISTERED); + } - pThis[RmtChannel::FIELD___channel].NumericByRef().s4 = channel; + RmtChannel::registredChannels.emplace( + std::piecewise_construct, + std::forward_as_tuple((rmt_channel_t)channel), + std::forward_as_tuple()); + stack.SetResult_I4((CLR_INT32)channel); + } NANOCLR_NOCLEANUP(); } HRESULT Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_TransmitterChannel:: - NativeGetIdleLevel___BOOLEAN(CLR_RT_StackFrame &stack) + NativeTxGetIsChannelIdle___BOOLEAN(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); + CLR_RT_HeapBlock *transmitter_channel_settings = NULL; int32_t channel; bool retVal = 0; + rmt_idle_level_t level; CLR_RT_HeapBlock *pThis = stack.This(); FAULT_ON_NULL(pThis); - channel = (int32_t)pThis[RmtChannel::FIELD___channel].NumericByRef().s4; + // get a reference to the configs in the managed code instance + transmitter_channel_settings = pThis[FIELD___transmitterChannelSettings].Dereference(); + channel = transmitter_channel_settings[RmtChannelSettings::FIELD___channel].NumericByRef().s4; if (!RmtChannel::CheckChannel(channel)) { NANOCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); } - retVal = ::RMT.conf_ch[(rmt_channel_t)channel].conf1.idle_out_lv; + rmt_get_idle_level((rmt_channel_t)channel, &retVal, &level); stack.SetResult_Boolean(retVal); @@ -68,125 +135,181 @@ HRESULT Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_E } HRESULT Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_TransmitterChannel:: - NativeGetIsChannelIdle___BOOLEAN(CLR_RT_StackFrame &stack) + NativeTxSetLoopingMode___VOID__BOOLEAN(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); + CLR_RT_HeapBlock *transmitter_channel_settings = NULL; int32_t channel; - bool retVal = 0; + bool enabled; + esp_err_t err; CLR_RT_HeapBlock *pThis = stack.This(); FAULT_ON_NULL(pThis); - channel = (int32_t)pThis[RmtChannel::FIELD___channel].NumericByRef().s4; + // get a reference to the configs in the managed code instance + transmitter_channel_settings = pThis[FIELD___transmitterChannelSettings].Dereference(); + channel = transmitter_channel_settings[RmtChannelSettings::FIELD___channel].NumericByRef().s4; + enabled = (bool)transmitter_channel_settings[TransmitterChannelSettings::FIELD___enableLooping].NumericByRef().u1; if (!RmtChannel::CheckChannel(channel)) { NANOCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); } - retVal = ::RMT.conf_ch[(rmt_channel_t)channel].conf1.idle_out_en; - - stack.SetResult_Boolean(retVal); + err = rmt_set_tx_loop_mode((rmt_channel_t)channel, enabled); + if (err != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } NANOCLR_NOCLEANUP(); } HRESULT Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_TransmitterChannel:: - NativeSetIsChannelIdle___VOID__BOOLEAN(CLR_RT_StackFrame &stack) + NativeTxSetLoopCount___VOID__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); +#if SOC_RMT_SUPPORT_TX_LOOP_COUNT + + CLR_RT_HeapBlock *transmitter_channel_settings = NULL; int32_t channel; - bool enabled; + uint32_t count; + esp_err_t err; CLR_RT_HeapBlock *pThis = stack.This(); FAULT_ON_NULL(pThis); - channel = (int32_t)pThis[RmtChannel::FIELD___channel].NumericByRef().s4; - enabled = (bool)stack.Arg1().NumericByRef().u1; + // get a reference to the configs in the managed code instance + transmitter_channel_settings = pThis[FIELD___transmitterChannelSettings].Dereference(); + channel = transmitter_channel_settings[RmtChannelSettings::FIELD___channel].NumericByRef().s4; + count = (bool)transmitter_channel_settings[TransmitterChannelSettings::FIELD___enableLooping].NumericByRef().u4; if (!RmtChannel::CheckChannel(channel)) { NANOCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); } - ::RMT.conf_ch[(rmt_channel_t)channel].conf1.idle_out_en = enabled; + err = rmt_set_tx_loop_count((rmt_channel_t)channel, count); + if (err != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + +#else + + NANOCLR_SET_AND_LEAVE(stack.NotImplementedStub()); + +#endif NANOCLR_NOCLEANUP(); } HRESULT Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_TransmitterChannel:: - NativeSetIdleLevel___VOID__BOOLEAN(CLR_RT_StackFrame &stack) + NativeTxSetCarrierMode___VOID(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); int32_t channel; - bool idle_lvl; + bool carrier_en; + uint32_t carrier_freq_hz; + uint8_t carrier_duty_percent; + bool carrier_level; + esp_err_t err; + + CLR_RT_HeapBlock *transmitter_channel_settings = NULL; CLR_RT_HeapBlock *pThis = stack.This(); FAULT_ON_NULL(pThis); - channel = (int32_t)pThis[RmtChannel::FIELD___channel].NumericByRef().s4; - idle_lvl = (bool)stack.Arg1().NumericByRef().u1; + // get a reference to the configs in the managed code instance + transmitter_channel_settings = pThis[FIELD___transmitterChannelSettings].Dereference(); + channel = transmitter_channel_settings[RmtChannelSettings::FIELD___channel].NumericByRef().s4; + carrier_en = + (bool)transmitter_channel_settings[TransmitterChannelSettings::FIELD___enableCarrierWave].NumericByRef().u1; + carrier_freq_hz = + transmitter_channel_settings[TransmitterChannelSettings::FIELD___carrierWaveFrequency].NumericByRef().u4; + carrier_duty_percent = + transmitter_channel_settings[TransmitterChannelSettings::FIELD___carrierWaveDutyPercentage].NumericByRef().u1; + carrier_level = + (bool)transmitter_channel_settings[TransmitterChannelSettings::FIELD___carrierLevel].NumericByRef().u1; if (!RmtChannel::CheckChannel(channel)) { NANOCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); } - ::RMT.conf_ch[(rmt_channel_t)channel].conf1.idle_out_lv = idle_lvl; + uint32_t rmt_source_clk_hz, duty_div, duty_h, duty_l; + rmt_source_clk_hz = APB_CLK_FREQ; // only APB bus clock is supported + duty_div = rmt_source_clk_hz / carrier_freq_hz; + duty_h = duty_div * carrier_duty_percent / 100; + duty_l = duty_div - duty_h; + + err = rmt_set_tx_carrier( + (rmt_channel_t)channel, + carrier_en, + duty_h, + duty_l, + carrier_level ? RMT_CARRIER_LEVEL_HIGH : RMT_CARRIER_LEVEL_LOW); + if (err != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } NANOCLR_NOCLEANUP(); } HRESULT Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_TransmitterChannel:: - NativeSetCarrierMode___VOID(CLR_RT_StackFrame &stack) + NativeTxSetIdleLevel___VOID__BOOLEAN(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); - int32_t channel; - bool carier_en; - uint16_t high_lvl; - uint16_t low_level; - bool carier_lvl; + rmt_channel_t channel; + bool idle_out_en; + bool idle_level; + esp_err_t err; + + CLR_RT_HeapBlock *transmitter_channel_settings = NULL; CLR_RT_HeapBlock *pThis = stack.This(); FAULT_ON_NULL(pThis); - channel = (int32_t)pThis[RmtChannel::FIELD___channel].NumericByRefConst().s4; - carier_en = (bool)pThis[FIELD___carrierEnabled].NumericByRefConst().u1; - high_lvl = (uint16_t)pThis[FIELD___carrierHighDuration].NumericByRefConst().s2; - low_level = (uint16_t)pThis[FIELD___carrierLowDuration].NumericByRefConst().s2; - carier_lvl = (bool)pThis[FIELD___carrierLevel].NumericByRefConst().u1; + // get a reference to the configs in the managed code instance + transmitter_channel_settings = pThis[FIELD___transmitterChannelSettings].Dereference(); + channel = (rmt_channel_t)transmitter_channel_settings[RmtChannelSettings::FIELD___channel].NumericByRef().s4; + idle_out_en = + (bool)transmitter_channel_settings[TransmitterChannelSettings::FIELD___enableIdleLevelOutput].NumericByRef().u1; + idle_level = (bool)transmitter_channel_settings[TransmitterChannelSettings::FIELD___idleLevel].NumericByRef().u1; if (!RmtChannel::CheckChannel(channel)) { NANOCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); } + err = rmt_set_idle_level(channel, idle_out_en, idle_level ? RMT_IDLE_LEVEL_HIGH : RMT_IDLE_LEVEL_LOW); + if (err != ESP_OK) { - auto &ch = ::RMT.conf_ch[(rmt_channel_t)channel]; - ch.conf0.carrier_en = carier_en; - ch.conf0.carrier_out_lv = (uint32_t)carier_lvl; - auto &cdc = ::RMT.carrier_duty_ch[(rmt_channel_t)channel]; - cdc.high = high_lvl; - cdc.low = low_level; + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); } NANOCLR_NOCLEANUP(); } HRESULT Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_TransmitterChannel:: - NativeWriteItems___U4__SZARRAY_U1__BOOLEAN(CLR_RT_StackFrame &stack) + NativeTxWriteItems___U4__SZARRAY_U1__BOOLEAN(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); + CLR_RT_HeapBlock *transmitter_channel_settings = NULL; CLR_RT_HeapBlock *pThis = stack.This(); FAULT_ON_NULL(pThis); + // get a reference to the configs in the managed code instance + transmitter_channel_settings = pThis[FIELD___transmitterChannelSettings].Dereference(); + { - int32_t channel = (int32_t)pThis[RmtChannel::FIELD___channel].NumericByRef().s4; + int32_t channel = transmitter_channel_settings[RmtChannelSettings::FIELD___channel].NumericByRef().s4; bool wait_tx_done = (bool)stack.Arg2().NumericByRef().u1; CLR_RT_HeapBlock_Array *data = stack.Arg1().DereferenceArray(); @@ -217,43 +340,19 @@ HRESULT Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_E } HRESULT Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_TransmitterChannel:: - NativeWaitTxDone___U4__I4(CLR_RT_StackFrame &stack) + NativeTxDispose___VOID(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); - int result = ESP_ERR_TIMEOUT; - + CLR_RT_HeapBlock *transmitter_channel_settings = NULL; int32_t channel; - int32_t wait_time = (int32_t)stack.Arg1().NumericByRef().s4; CLR_RT_HeapBlock *pThis = stack.This(); FAULT_ON_NULL(pThis); - channel = (int32_t)pThis[RmtChannel::FIELD___channel].NumericByRef().s4; - - if (!RmtChannel::CheckChannel(channel)) - { - NANOCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); - } - - result = rmt_wait_tx_done((rmt_channel_t)channel, wait_time); - - stack.SetResult_U4(result); - - NANOCLR_NOCLEANUP(); -} - -HRESULT Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_TransmitterChannel:: - NativeDispose___VOID(CLR_RT_StackFrame &stack) -{ - NANOCLR_HEADER(); - - int32_t channel; - - CLR_RT_HeapBlock *pThis = stack.This(); - FAULT_ON_NULL(pThis); - - channel = (int32_t)pThis[RmtChannel::FIELD___channel].NumericByRef().s4; + // get a reference to the configs in the managed code instance + transmitter_channel_settings = pThis[FIELD___transmitterChannelSettings].Dereference(); + channel = (int32_t)transmitter_channel_settings[RmtChannelSettings::FIELD___channel].NumericByRef().s4; if (!RmtChannel::CheckChannel(channel)) { @@ -270,58 +369,31 @@ HRESULT Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_E NANOCLR_NOCLEANUP(); } -HRESULT Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_TransmitterChannel:: - NativeGetSourceClock___BOOLEAN(CLR_RT_StackFrame &stack) +rmt_config_t Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_TransmitterChannel:: + GetNewRmtTxConfig(gpio_num_t pin, rmt_channel_t channel) { - NANOCLR_HEADER(); - - bool retVal = false; - - int32_t channel; - - CLR_RT_HeapBlock *pThis = stack.This(); - FAULT_ON_NULL(pThis); - - channel = (int32_t)stack.Arg0().NumericByRef().s4; - - if (!RmtChannel::CheckChannel(channel)) - { - NANOCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); - } - - retVal = ::RMT.conf_ch[(rmt_channel_t)channel].conf1.ref_always_on; - - stack.SetResult_Boolean(retVal); - - NANOCLR_NOCLEANUP(); -} - -#ifdef __GNUC__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wmissing-field-initializers" + rmt_config_t config = rmt_config_t(); + + config.rmt_mode = RMT_MODE_TX; + config.channel = channel; + config.gpio_num = pin; + config.clk_div = 80; + config.mem_block_num = 1; + config.flags = 0; + + config.tx_config = rmt_tx_config_t(); + config.tx_config.carrier_freq_hz = 38000; + config.tx_config.carrier_level = RMT_CARRIER_LEVEL_HIGH; + config.tx_config.idle_level = RMT_IDLE_LEVEL_LOW; + config.tx_config.carrier_duty_percent = 33; + config.tx_config.carrier_en = false; + config.tx_config.loop_en = false; + +#if SOC_RMT_SUPPORT_TX_LOOP_COUNT + config.tx_config.loop_count = 1; #endif -esp_err_t Library_nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_TransmitterChannel:: - InitTxChannel(rmt_channel_t channel, gpio_num_t gpio) -{ - // TODO check replaced code - rmt_config_t rmt_tx = RMT_DEFAULT_CONFIG_TX(gpio, channel); - - auto err = rmt_config(&rmt_tx); - if (err != ESP_OK) - return err; - - err = rmt_driver_install(channel, 0, 0); - if (err != ESP_OK) - return err; - - RmtChannel::registredChannels.emplace( - std::piecewise_construct, - std::forward_as_tuple(channel), - std::forward_as_tuple()); - return ESP_OK; -} + config.tx_config.idle_output_en = true; -#ifdef __GNUC__ -#pragma GCC diagnostic pop -#endif \ No newline at end of file + return config; +} \ No newline at end of file diff --git a/targets/ESP32/_nanoCLR/targetHAL.cpp b/targets/ESP32/_nanoCLR/targetHAL.cpp index 4a8f647955..9cfa579c06 100644 --- a/targets/ESP32/_nanoCLR/targetHAL.cpp +++ b/targets/ESP32/_nanoCLR/targetHAL.cpp @@ -55,9 +55,9 @@ extern "C" nanoHAL_Initialize(); } - void nanoHAL_Uninitialize_C() + void nanoHAL_Uninitialize_C(bool isPoweringDown) { - nanoHAL_Uninitialize(); + nanoHAL_Uninitialize(isPoweringDown); } } @@ -112,8 +112,10 @@ void nanoHAL_Initialize() #endif } -void nanoHAL_Uninitialize() +void nanoHAL_Uninitialize(bool isPoweringDown) { + (void)isPoweringDown; + // check for s_rebootHandlers for (unsigned int i = 0; i < ARRAYSIZE(s_rebootHandlers); i++) { diff --git a/targets/ESP32/_nanoCLR/targetHAL_Power.c b/targets/ESP32/_nanoCLR/targetHAL_Power.c index e8a9381fc4..6c15593168 100644 --- a/targets/ESP32/_nanoCLR/targetHAL_Power.c +++ b/targets/ESP32/_nanoCLR/targetHAL_Power.c @@ -3,34 +3,42 @@ // See LICENSE file in the project root for full license information. // +#include #include #include +#include inline void CPU_Reset() -{ - esp_restart(); +{ +#if CONFIG_IDF_TARGET_ESP32C3 && HAL_WP_USE_USB_CDC + SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_SYS_RST); + while (true) + { + } +#else + esp_restart(); +#endif }; // CPU sleep is not currently implemented in this target inline void CPU_Sleep(SLEEP_LEVEL_type level, uint64_t wakeEvents) -{ +{ (void)level; (void)wakeEvents; - }; inline bool CPU_IsSoftRebootSupported() -{ +{ return true; }; void CPU_SetPowerMode(PowerLevel_type powerLevel) { - switch(powerLevel) + switch (powerLevel) { case PowerLevel__Off: // gracefully shutdown everything - nanoHAL_Uninitialize_C(); + nanoHAL_Uninitialize_C(true); esp_deep_sleep_start(); diff --git a/targets/ESP32/_nanoCLR/target_platform.h.in b/targets/ESP32/_nanoCLR/target_platform.h.in index 5d63884561..511a1f9dc8 100644 --- a/targets/ESP32/_nanoCLR/target_platform.h.in +++ b/targets/ESP32/_nanoCLR/target_platform.h.in @@ -14,6 +14,8 @@ #define HAL_USE_SPI @HAL_USE_SPI_OPTION@ #define HAL_USE_SDC @HAL_USE_SDC_OPTION@ #define HAL_USE_BLE @HAL_USE_BLE_OPTION@ +#define HAL_WP_USE_SERIAL @HAL_WP_USE_SERIAL_OPTION@ +#define HAL_WP_USE_USB_CDC @HAL_WP_USE_USB_CDC_OPTION@ #if (HAL_USE_SDC == TRUE) #define SDC_MAX_OPEN_FILES 5 diff --git a/targets/FreeRTOS/CMakePresets.json b/targets/FreeRTOS/CMakePresets.json new file mode 100644 index 0000000000..65b5526753 --- /dev/null +++ b/targets/FreeRTOS/CMakePresets.json @@ -0,0 +1,6 @@ +{ + "version": 4, + "include": [ + "NXP/NXP_MIMXRT1060_EVK/CMakePresets.json" + ] +} diff --git a/targets/FreeRTOS/NXP/CMakeLists.txt b/targets/FreeRTOS/NXP/CMakeLists.txt index d2c47e6fc0..29d834d26f 100644 --- a/targets/FreeRTOS/NXP/CMakeLists.txt +++ b/targets/FreeRTOS/NXP/CMakeLists.txt @@ -137,7 +137,7 @@ if(USE_NETWORKING_OPTION) list(APPEND NANOCLR_PROJECT_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/_LwIP) - # append mbed TLS entropy generator, if hardware has it + # append Mbed TLS entropy generator, if hardware has it # if(NF_SECURITY_MBEDTLS AND USE_RNG) # list(APPEND NANOCLR_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/mbedtls_entropy_hardware_pool.c") # endif() diff --git a/targets/FreeRTOS/NXP/NXP_MIMXRT1060_EVK/CMakePresets.json b/targets/FreeRTOS/NXP/NXP_MIMXRT1060_EVK/CMakePresets.json new file mode 100644 index 0000000000..307bbfaac0 --- /dev/null +++ b/targets/FreeRTOS/NXP/NXP_MIMXRT1060_EVK/CMakePresets.json @@ -0,0 +1,51 @@ +{ + "version": 4, + "include": [ + "../../../../CMake/arm-gcc.json", + "../../../../config/user-tools-repos.json", + "../../../../config/user-prefs.json" + ], + "configurePresets": [ + { + "name": "NXP_MIMXRT1060_EVK", + "inherits": [ + "arm-gcc-cortex-preset", + "user-tools-repos", + "user-prefs" + ], + "hidden": false, + "cacheVariables": { + "TARGET_BOARD": "${presetName}", + "TARGET_SERIES": "IMXRT10xx", + "SUPPORT_ANY_BASE_CONVERSION": "ON", + "RTOS": "FreeRTOS", + "RTOS_VERSION": "", + "CMSIS_VERSION": "", + "FATFS_VERSION": "", + "LWIP_VERSION": "", + "NF_BUILD_RTM": "OFF", + "NF_FEATURE_DEBUGGER": "ON", + "NF_FEATURE_HAS_SDCARD": "ON", + "NF_FEATURE_RTC": "ON", + "NF_FEATURE_HAS_CONFIG_BLOCK": "ON", + "NF_SECURITY_MBEDTLS": "OFF", + "API_System.Device.Gpio": "ON", + "API_System.Device.I2c": "OFF", + "API_System.Device.Adc": "OFF", + "API_System.IO.Ports": "ON", + "API_nanoFramework.ResourceManager": "ON", + "API_nanoFramework.System.Collections": "ON", + "API_System.Net": "ON", + "API_System.Math": "ON" + } + } + ], + "buildPresets": [ + { + "inherits": "base-user", + "name": "NXP_MIMXRT1060_EVK", + "displayName": "NXP_MIMXRT1060_EVK", + "configurePreset": "NXP_MIMXRT1060_EVK" + } + ] +} diff --git a/targets/FreeRTOS/NXP/NXP_MIMXRT1060_EVK/target_system_device_pwm_config.cpp b/targets/FreeRTOS/NXP/NXP_MIMXRT1060_EVK/target_system_device_pwm_config.cpp new file mode 100644 index 0000000000..73cc6666d3 --- /dev/null +++ b/targets/FreeRTOS/NXP/NXP_MIMXRT1060_EVK/target_system_device_pwm_config.cpp @@ -0,0 +1,9 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS BLANK ON PURPOSE BECAUSE THIS TARGET DOESN'T REQUIRE THIS SPECIFIC CONFIGURATION // +/////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/targets/FreeRTOS/NXP/_nanoCLR/targetHAL.cpp b/targets/FreeRTOS/NXP/_nanoCLR/targetHAL.cpp index df8c633cac..6fc1eb748e 100644 --- a/targets/FreeRTOS/NXP/_nanoCLR/targetHAL.cpp +++ b/targets/FreeRTOS/NXP/_nanoCLR/targetHAL.cpp @@ -42,9 +42,9 @@ extern "C" nanoHAL_Initialize(); } - void nanoHAL_Uninitialize_C() + void nanoHAL_Uninitialize_C(bool isPoweringDown) { - nanoHAL_Uninitialize(); + nanoHAL_Uninitialize(isPoweringDown); } } @@ -83,8 +83,10 @@ void nanoHAL_Initialize() // SOCKETS_DbgInitialize( 0 ); } -void nanoHAL_Uninitialize() +void nanoHAL_Uninitialize(bool isPoweringDown) { + (void)isPoweringDown; + // check for s_rebootHandlers for (unsigned int i = 0; i < ARRAYSIZE(s_rebootHandlers); i++) { diff --git a/targets/FreeRTOS/_common/CMakeLists.txt b/targets/FreeRTOS/_common/CMakeLists.txt index d035a27759..8a595bc578 100644 --- a/targets/FreeRTOS/_common/CMakeLists.txt +++ b/targets/FreeRTOS/_common/CMakeLists.txt @@ -18,6 +18,7 @@ list(APPEND TARGET_FREERTOS_COMMON_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/platform_ # append nanoHAL list(APPEND TARGET_FREERTOS_COMMON_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/targetHAL.c) list(APPEND TARGET_FREERTOS_COMMON_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/targetHAL_Time.cpp) +list(APPEND TARGET_FREERTOS_COMMON_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/targetHAL_Rtos.c) list(APPEND TARGET_FREERTOS_COMMON_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/WireProtocol_ReceiverThread.c) diff --git a/targets/FreeRTOS/_common/include/targetHAL_Time.h b/targets/FreeRTOS/_common/include/targetHAL_Time.h index c9789268ea..6d8b1ccba8 100644 --- a/targets/FreeRTOS/_common/include/targetHAL_Time.h +++ b/targets/FreeRTOS/_common/include/targetHAL_Time.h @@ -6,9 +6,30 @@ #ifndef TARGET_HAL_TIME_H #define TARGET_HAL_TIME_H -#include "FreeRTOS.h" -#include "task.h" +#include +#include -#define HAL_Time_CurrentSysTicks xTaskGetTickCount +#define HAL_Time_CurrentSysTicks xTaskGetTickCount -#endif //TARGET_HAL_TIME_H +// because HAL_Time_SysTicksToTime needs to be called from C we need a proxy to allow it to be called from 'C' code +#ifdef __cplusplus +extern "C" +{ +#endif + + // Converts FreeRTOS Tickcount to .NET ticks (100 nanoseconds) + inline __attribute__((always_inline)) uint64_t HAL_Time_SysTicksToTime(uint64_t sysTicks) + { + return sysTicks * configTICK_RATE_HZ * 1000; + } + + inline __attribute__((always_inline)) uint64_t HAL_Time_SysTicksToTime_C(uint64_t sysTicks) + { + return sysTicks * configTICK_RATE_HZ * 1000; + } + +#ifdef __cplusplus +} +#endif + +#endif // TARGET_HAL_TIME_H diff --git a/targets/FreeRTOS/_common/include/targetPAL_Time.h b/targets/FreeRTOS/_common/include/targetPAL_Time.h index f315c94637..bcce0d6f4a 100644 --- a/targets/FreeRTOS/_common/include/targetPAL_Time.h +++ b/targets/FreeRTOS/_common/include/targetPAL_Time.h @@ -6,5 +6,4 @@ #ifndef TARGET_PAL_TIME_H #define TARGET_PAL_TIME_H - -#endif //TARGET_PAL_TIME_H +#endif // TARGET_PAL_TIME_H diff --git a/targets/FreeRTOS/_common/nanoCLR/nanoCRT.cpp b/targets/FreeRTOS/_common/nanoCLR/nanoCRT.cpp index 3fcee4d9cd..ec2ab722f4 100644 --- a/targets/FreeRTOS/_common/nanoCLR/nanoCRT.cpp +++ b/targets/FreeRTOS/_common/nanoCLR/nanoCRT.cpp @@ -12,11 +12,10 @@ #if !defined(BUILD_RTM) -void hal_fprintf_SetLoggingCallback( LOGGING_CALLBACK fpn ) +void hal_fprintf_SetLoggingCallback(LOGGING_CALLBACK fpn) { (void)fpn; NATIVE_PROFILE_PAL_CRT(); - } #endif @@ -25,61 +24,64 @@ void hal_fprintf_SetLoggingCallback( LOGGING_CALLBACK fpn ) #if defined(PLATFORM_EMULATED_FLOATINGPOINT) -// no floating point, fixed point +// no floating point, fixed point -int hal_snprintf_float( char* buffer, size_t len, const char* format, int32_t f ) +int hal_snprintf_float(char *buffer, size_t len, const char *format, int32_t f) { NATIVE_PROFILE_PAL_CRT(); - uint32_t i ; - uint32_t dec; + uint32_t i; + uint32_t dec; - if ( f < 0 ) + if (f < 0) { // negative number - i = (uint32_t) -f ; - dec = i & (( 1<>HAL_FLOAT_SHIFT); - - if (dec !=0) dec = (dec * (uint32_t)HAL_FLOAT_PRECISION + (1<< (HAL_FLOAT_SHIFT-1))) >>HAL_FLOAT_SHIFT; + i = (uint32_t)-f; + dec = i & ((1 << HAL_FLOAT_SHIFT) - 1); + i = (i >> HAL_FLOAT_SHIFT); - return hal_snprintf( buffer, len, "-%d.%03u", i, (uint32_t)dec); + if (dec != 0) + dec = (dec * (uint32_t)HAL_FLOAT_PRECISION + (1 << (HAL_FLOAT_SHIFT - 1))) >> HAL_FLOAT_SHIFT; + return hal_snprintf(buffer, len, "-%d.%03u", i, (uint32_t)dec); } else { // positive number - i = (uint32_t) f ; - dec = f & (( 1<>HAL_FLOAT_SHIFT); + i = (uint32_t)f; + dec = f & ((1 << HAL_FLOAT_SHIFT) - 1); + i = (uint32_t)(i >> HAL_FLOAT_SHIFT); - if (dec !=0) dec = (dec * (uint32_t)HAL_FLOAT_PRECISION + (1<< (HAL_FLOAT_SHIFT-1))) >>HAL_FLOAT_SHIFT; + if (dec != 0) + dec = (dec * (uint32_t)HAL_FLOAT_PRECISION + (1 << (HAL_FLOAT_SHIFT - 1))) >> HAL_FLOAT_SHIFT; - return hal_snprintf( buffer, len, "%d.%03u", i, (uint32_t)dec); + return hal_snprintf(buffer, len, "%d.%03u", i, (uint32_t)dec); } } -int hal_snprintf_double( char* buffer, size_t len, const char* format, int64_t& d ) +int hal_snprintf_double(char *buffer, size_t len, const char *format, int64_t &d) { NATIVE_PROFILE_PAL_CRT(); uint64_t i; - uint32_t dec; // 32 bit is enough for decimal part + uint32_t dec; // 32 bit is enough for decimal part - if ( d < 0 ) + if (d < 0) { // negative number i = (uint64_t)-d; - - i += ((1 << (HAL_DOUBLE_SHIFT-1)) / HAL_DOUBLE_PRECISION); // add broad part of rounding increment before split - dec = i & (( 1<> HAL_DOUBLE_SHIFT ; + i += + ((1 << (HAL_DOUBLE_SHIFT - 1)) / HAL_DOUBLE_PRECISION); // add broad part of rounding increment before split - if (dec !=0) dec = (dec * HAL_DOUBLE_PRECISION + ((1 << (HAL_DOUBLE_SHIFT-1)) % HAL_DOUBLE_PRECISION)) >> HAL_DOUBLE_SHIFT; + dec = i & ((1 << HAL_DOUBLE_SHIFT) - 1); + i = i >> HAL_DOUBLE_SHIFT; - return hal_snprintf( buffer, len, "-%lld.%04u", (int64_t)i, (uint32_t)dec); + if (dec != 0) + dec = (dec * HAL_DOUBLE_PRECISION + ((1 << (HAL_DOUBLE_SHIFT - 1)) % HAL_DOUBLE_PRECISION)) >> + HAL_DOUBLE_SHIFT; + return hal_snprintf(buffer, len, "-%lld.%04u", (int64_t)i, (uint32_t)dec); } else { @@ -87,14 +89,17 @@ int hal_snprintf_double( char* buffer, size_t len, const char* format, int64_t& // positive number i = (uint64_t)d; - i += ((1 << (HAL_DOUBLE_SHIFT-1)) / HAL_DOUBLE_PRECISION); // add broad part of rounding increment before split + i += + ((1 << (HAL_DOUBLE_SHIFT - 1)) / HAL_DOUBLE_PRECISION); // add broad part of rounding increment before split - dec = i & (( 1<> HAL_DOUBLE_SHIFT; - - if (dec !=0) dec = (dec * HAL_DOUBLE_PRECISION + ((1 << (HAL_DOUBLE_SHIFT-1)) % HAL_DOUBLE_PRECISION)) >> HAL_DOUBLE_SHIFT; - return hal_snprintf( buffer, len, "%lld.%04u", (int64_t)i, (uint32_t)dec); + if (dec != 0) + dec = (dec * HAL_DOUBLE_PRECISION + ((1 << (HAL_DOUBLE_SHIFT - 1)) % HAL_DOUBLE_PRECISION)) >> + HAL_DOUBLE_SHIFT; + + return hal_snprintf(buffer, len, "%lld.%04u", (int64_t)i, (uint32_t)dec); } } @@ -103,52 +108,63 @@ int hal_snprintf_double( char* buffer, size_t len, const char* format, int64_t& #endif // because debug_printf needs to be called in both C and C++ we need a proxy to allow it to be called in 'C' -extern "C" { +extern "C" +{ #if !defined(BUILD_RTM) - - void debug_printf(const char* format, ...) + + void debug_printf(const char *format, ...) { char buffer[256]; va_list arg_ptr; - - va_start( arg_ptr, format ); - - int len = vsnprintf( buffer, sizeof(buffer)-1, format, arg_ptr ); - - DebuggerPort_Write( HalSystemConfig.stdio, buffer, len, 0 ); // skip null terminator - - va_end( arg_ptr ); + + va_start(arg_ptr, format); + + int len = vsnprintf(buffer, sizeof(buffer) - 1, format, arg_ptr); + + DebuggerPort_Write(HalSystemConfig.stdio, buffer, len, 0); // skip null terminator + + va_end(arg_ptr); } -#else - __inline void debug_printf( const char *format, ... ) {} -#endif // !defined(BUILD_RTM) +#endif // !defined(BUILD_RTM) } -int hal_strcpy_s ( char* strDst, size_t sizeInBytes, const char* strSrc ) +int hal_strcpy_s(char *strDst, size_t sizeInBytes, const char *strSrc) { NATIVE_PROFILE_PAL_CRT(); #undef strcpy size_t len; - if(strDst == NULL || strSrc == NULL || sizeInBytes == 0) {_ASSERTE(FALSE); return 1;} - + if (strDst == NULL || strSrc == NULL || sizeInBytes == 0) + { + _ASSERTE(FALSE); + return 1; + } + len = hal_strlen_s(strSrc); - if(sizeInBytes < len + 1) {_ASSERTE(FALSE); return 1;} + if (sizeInBytes < len + 1) + { + _ASSERTE(FALSE); + return 1; + } - strcpy( strDst, strSrc ); + strcpy(strDst, strSrc); return 0; -#define strcpy DoNotUse_*strcpy [] +#define strcpy DoNotUse_ *strcpy[] } -int hal_strncpy_s ( char* strDst, size_t sizeInBytes, const char* strSrc, size_t count ) +int hal_strncpy_s(char *strDst, size_t sizeInBytes, const char *strSrc, size_t count) { NATIVE_PROFILE_PAL_CRT(); #undef strncpy - if(strDst == NULL || strSrc == NULL || sizeInBytes == 0) {_ASSERTE(FALSE); return 1;} - + if (strDst == NULL || strSrc == NULL || sizeInBytes == 0) + { + _ASSERTE(FALSE); + return 1; + } + if (sizeInBytes < count + 1) { _ASSERTE(FALSE); @@ -157,49 +173,53 @@ int hal_strncpy_s ( char* strDst, size_t sizeInBytes, const char* strSrc, size_t } strDst[count] = 0; - strncpy( strDst, strSrc, count ); + strncpy(strDst, strSrc, count); return 0; -#define strncpy DoNotUse_*strncpy [] +#define strncpy DoNotUse_ *strncpy[] } -size_t hal_strlen_s (const char * str) +size_t hal_strlen_s(const char *str) { NATIVE_PROFILE_PAL_CRT(); const char *eos = str; - while( *eos++ ) ; - return( eos - str - 1 ); + while (*eos++) + ; + return (eos - str - 1); } -int hal_strncmp_s ( const char* str1, const char* str2, size_t num ) +int hal_strncmp_s(const char *str1, const char *str2, size_t num) { NATIVE_PROFILE_PAL_CRT(); #undef strncmp - if(str1 == NULL || str2 == NULL) {_ASSERTE(FALSE); return 1;} - - return strncmp( str1, str2, num ); + if (str1 == NULL || str2 == NULL) + { + _ASSERTE(FALSE); + return 1; + } + + return strncmp(str1, str2, num); -#define strncmp DoNotUse_*strncmp [] +#define strncmp DoNotUse_ *strncmp[] } // Compares 2 ASCII strings case insensitive. Does not take locale into account. -int hal_stricmp( const char * dst, const char * src ) +int hal_stricmp(const char *dst, const char *src) { int f = 0, l = 0; do { - if ( ((f = (unsigned char)(*(dst++))) >= 'A') && (f <= 'Z') ) + if (((f = (unsigned char)(*(dst++))) >= 'A') && (f <= 'Z')) { f -= 'A' - 'a'; } - if ( ((l = (unsigned char)(*(src++))) >= 'A') && (l <= 'Z') ) + if (((l = (unsigned char)(*(src++))) >= 'A') && (l <= 'Z')) { l -= 'A' - 'a'; } - } - while ( f && (f == l) ); + } while (f && (f == l)); - return(f - l); + return (f - l); } diff --git a/targets/FreeRTOS/_common/platform_heap.c b/targets/FreeRTOS/_common/platform_heap.c index f5d6c663b2..f7c4c09d7d 100644 --- a/targets/FreeRTOS/_common/platform_heap.c +++ b/targets/FreeRTOS/_common/platform_heap.c @@ -15,59 +15,3 @@ void platform_free(void *ptr) { vPortFree(ptr); } - -typedef struct A_BLOCK_LINK -{ - struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */ - size_t xBlockSize; /*<< The size of the free block. */ -} BlockLink_t; - -#define heapBITS_PER_BYTE ((size_t)8) -static const size_t xHeapStructSize = - (sizeof(BlockLink_t) + ((size_t)(portBYTE_ALIGNMENT - 1))) & ~((size_t)portBYTE_ALIGNMENT_MASK); -static size_t xBlockAllocatedBit = ((size_t)1) << ((sizeof(size_t) * heapBITS_PER_BYTE) - 1); - -static size_t mem_size(void *pv) -{ - uint8_t *puc = (uint8_t *)pv; - BlockLink_t *pxLink; - - if (pv != NULL) - { - /* The memory being freed will have an BlockLink_t structure immediately - before it. */ - puc -= xHeapStructSize; - - /* This casting is to keep the compiler from issuing warnings. */ - pxLink = (void *)puc; - - return pxLink->xBlockSize & ~xBlockAllocatedBit; - } - - return 0; -} - -void *platform_realloc(void *ptr, size_t size) -{ - void *newPtr; - size_t curSize; - - if (ptr == 0) - { - return pvPortMalloc(size); - } - - curSize = mem_size(ptr); - - if (size <= curSize) - { - return ptr; - } - - newPtr = pvPortMalloc(size); - - memcpy(ptr, newPtr, size); - - vPortFree(ptr); - return newPtr; -} diff --git a/targets/FreeRTOS/_common/targetHAL_Rtos.c b/targets/FreeRTOS/_common/targetHAL_Rtos.c new file mode 100644 index 0000000000..0eb6ecb4e9 --- /dev/null +++ b/targets/FreeRTOS/_common/targetHAL_Rtos.c @@ -0,0 +1,12 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include +#include + +void RtosYield() +{ + taskYIELD(); +} diff --git a/targets/FreeRTOS/_common/targetHAL_Time.cpp b/targets/FreeRTOS/_common/targetHAL_Time.cpp index caa7095d2c..35d4aa02a7 100644 --- a/targets/FreeRTOS/_common/targetHAL_Time.cpp +++ b/targets/FreeRTOS/_common/targetHAL_Time.cpp @@ -3,25 +3,6 @@ // See LICENSE file in the project root for full license information. // -#include -#include -#include "FreeRTOS.h" -#include "time.h" -#include - -// Converts FreeRTOS Tickcount to .NET ticks (100 nanoseconds) -uint64_t HAL_Time_SysTicksToTime(uint64_t sysTicks) -{ - return (((int64_t)sysTicks * (int64_t)1000000 + (int64_t)configTICK_RATE_HZ - 1) / (int64_t)configTICK_RATE_HZ) * - 10; -} - -// because HAL_Time_SysTicksToTime needs to be called from C we need a proxy to allow it to be called from 'C' code -extern "C" -{ - - uint64_t HAL_Time_SysTicksToTime_C(uint64_t sysTicks) - { - return HAL_Time_SysTicksToTime(sysTicks); - } -} +//////////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS BLANK ON PURPOSE HAS THERE IS NO PLATFORM IMPLEMENTATION REQUIRED // +//////////////////////////////////////////////////////////////////////////////////// diff --git a/targets/TI_SimpleLink/CMakePresets.json b/targets/TI_SimpleLink/CMakePresets.json new file mode 100644 index 0000000000..6474c6ee05 --- /dev/null +++ b/targets/TI_SimpleLink/CMakePresets.json @@ -0,0 +1,7 @@ +{ + "version": 4, + "include": [ + "TI_CC1352R1_LAUNCHXL/CMakePresets.json", + "TI_CC3220SF_LAUNCHXL/CMakePresets.json" + ] +} diff --git a/targets/TI_SimpleLink/TI_CC1352R1_LAUNCHXL/CMakePresets.json b/targets/TI_SimpleLink/TI_CC1352R1_LAUNCHXL/CMakePresets.json new file mode 100644 index 0000000000..225af374c1 --- /dev/null +++ b/targets/TI_SimpleLink/TI_CC1352R1_LAUNCHXL/CMakePresets.json @@ -0,0 +1,51 @@ +{ + "version": 4, + "include": [ + "../../../CMake/arm-gcc.json", + "../../../config/user-tools-repos.json", + "../../../config/user-prefs.json" + ], + "configurePresets": [ + { + "name": "TI_CC1352R1_LAUNCHXL", + "inherits": [ + "arm-gcc-cortex-preset", + "user-tools-repos", + "user-prefs" + ], + "hidden": false, + "cacheVariables": { + "TARGET_BOARD": "${presetName}", + "RTOS": "TI_SimpleLink", + "TARGET_SERIES": "CC13X2", + "SUPPORT_ANY_BASE_CONVERSION": "OFF", + "NF_TARGET_HAS_NANOBOOTER": "OFF", + "NF_FEATURE_DEBUGGER": "ON", + "NF_FEATURE_WATCHDOG": "OFF", + "NF_FEATURE_RTC": "ON", + "NF_FEATURE_HAS_SDCARD": "OFF", + "NF_BUILD_RTM": "OFF", + "API_System.Math": "OFF", + "API_System.Device.Gpio": "ON", + "API_System.Device.Spi": "OFF", + "API_System.Device.I2c": "OFF", + "API_System.Device.Pwm": "OFF", + "API_System.Device.Adc": "ON", + "API_System.IO.Ports": "OFF", + "API_nanoFramework.ResourceManager": "OFF", + "API_nanoFramework.System.Collections": "OFF", + "API_nanoFramework.System.Text": "ON", + "API_nanoFramework.TI.EasyLink": "ON", + "API_nanoFramework.Hardware.TI": "ON" + } + } + ], + "buildPresets": [ + { + "inherits": "base-user", + "name": "TI_CC1352R1_LAUNCHXL", + "displayName": "TI_CC1352R1_LAUNCHXL", + "configurePreset": "TI_CC1352R1_LAUNCHXL" + } + ] +} diff --git a/targets/TI_SimpleLink/TI_CC1352R1_LAUNCHXL/TI_CC1352R1_LAUNCHXL_868.syscfg b/targets/TI_SimpleLink/TI_CC1352R1_LAUNCHXL/TI_CC1352R1_LAUNCHXL_868.syscfg index 5d1147cd28..221049f3e6 100644 --- a/targets/TI_SimpleLink/TI_CC1352R1_LAUNCHXL/TI_CC1352R1_LAUNCHXL_868.syscfg +++ b/targets/TI_SimpleLink/TI_CC1352R1_LAUNCHXL/TI_CC1352R1_LAUNCHXL_868.syscfg @@ -12,10 +12,6 @@ const CCFG = scripting.addModule("/ti/devices/CCFG"); const ADC = scripting.addModule("/ti/drivers/ADC", {}, false); const ADC1 = ADC.addInstance(); const GPIO = scripting.addModule("/ti/drivers/GPIO", {}, false); -const GPIO2 = GPIO.addInstance(); -const GPIO3 = GPIO.addInstance(); -const GPIO4 = GPIO.addInstance(); -const GPIO5 = GPIO.addInstance(); const UART2 = scripting.addModule("/ti/drivers/UART2", {}, false); const UART21 = UART2.addInstance(); const easylink = scripting.addModule("/ti/easylink/easylink"); @@ -29,28 +25,21 @@ CCFG.ccfgTemplate.$name = "ti_devices_CCFGTemplate0"; ADC1.$name = "ADC_0"; ADC1.samplingDuration = "170 us"; -GPIO2.$name = "CONFIG_GPIO_0"; -GPIO2.$hardware = system.deviceData.board.components.LED_RED; - -GPIO3.$name = "CONFIG_GPIO_1"; -GPIO3.$hardware = system.deviceData.board.components.LED_GREEN; - -GPIO4.$name = "CONFIG_GPIO_2"; -GPIO4.$hardware = system.deviceData.board.components["BTN-1"]; - -GPIO5.$name = "CONFIG_GPIO_3"; -GPIO5.$hardware = system.deviceData.board.components["BTN-2"]; - -UART21.$name = "UART0"; -UART21.$hardware = system.deviceData.board.components.XDS110UART; +UART21.$name = "UART0"; +UART21.$hardware = system.deviceData.board.components.XDS110UART; +UART21.rxRingBufferSize = 256; easylink.EasyLink_Phy_50kbps2gfsk = true; easylink.EasyLink_Phy_5kbpsSlLr = true; easylink.EasyLink_Phy_200kbps2gfsk = true; easylink.enableAddrFilter = false; +easylink.radioConfigEasylinkPhyCustom.carrierFrequency = 868.0000; easylink.radioConfigEasylinkPhyCustom.codeExportConfig.$name = "ti_devices_radioconfig_code_export_param0"; +easylink.radioConfigEasylinkPhy50kbps2gfsk.carrierFrequency = 868.0000; easylink.radioConfigEasylinkPhy50kbps2gfsk.codeExportConfig.$name = "ti_devices_radioconfig_code_export_param1"; +easylink.radioConfigEasylinkPhy5kbpssllr.carrierFrequency = 868.0000; easylink.radioConfigEasylinkPhy5kbpssllr.codeExportConfig.$name = "ti_devices_radioconfig_code_export_param2"; +easylink.radioConfigEasylinkPhy200kbps2gfsk.carrierFrequency = 868.0000; easylink.radioConfigEasylinkPhy200kbps2gfsk.codeExportConfig.$name = "ti_devices_radioconfig_code_export_param3"; /** @@ -60,10 +49,6 @@ easylink.radioConfigEasylinkPhy200kbps2gfsk.codeExportConfig.$name = "ti_devices */ ADC1.adc.$suggestSolution = "ADC0"; ADC1.adc.adcPin.$suggestSolution = "boosterpack.2"; -GPIO2.gpioPin.$suggestSolution = "boosterpack.39"; -GPIO3.gpioPin.$suggestSolution = "boosterpack.40"; -GPIO4.gpioPin.$suggestSolution = "boosterpack.13"; -GPIO5.gpioPin.$suggestSolution = "boosterpack.12"; UART21.uart.$suggestSolution = "UART0"; UART21.uart.txPin.$suggestSolution = "boosterpack.4"; UART21.uart.rxPin.$suggestSolution = "boosterpack.3"; diff --git a/targets/TI_SimpleLink/TI_CC1352R1_LAUNCHXL/TI_CC1352R1_LAUNCHXL_915.syscfg b/targets/TI_SimpleLink/TI_CC1352R1_LAUNCHXL/TI_CC1352R1_LAUNCHXL_915.syscfg index cfa102f7c1..f26cf6855f 100644 --- a/targets/TI_SimpleLink/TI_CC1352R1_LAUNCHXL/TI_CC1352R1_LAUNCHXL_915.syscfg +++ b/targets/TI_SimpleLink/TI_CC1352R1_LAUNCHXL/TI_CC1352R1_LAUNCHXL_915.syscfg @@ -12,10 +12,6 @@ const CCFG = scripting.addModule("/ti/devices/CCFG"); const ADC = scripting.addModule("/ti/drivers/ADC", {}, false); const ADC1 = ADC.addInstance(); const GPIO = scripting.addModule("/ti/drivers/GPIO", {}, false); -const GPIO2 = GPIO.addInstance(); -const GPIO3 = GPIO.addInstance(); -const GPIO4 = GPIO.addInstance(); -const GPIO5 = GPIO.addInstance(); const UART2 = scripting.addModule("/ti/drivers/UART2", {}, false); const UART21 = UART2.addInstance(); const easylink = scripting.addModule("/ti/easylink/easylink"); @@ -29,20 +25,9 @@ CCFG.ccfgTemplate.$name = "ti_devices_CCFGTemplate0"; ADC1.$name = "ADC_0"; ADC1.samplingDuration = "170 us"; -GPIO2.$name = "CONFIG_GPIO_0"; -GPIO2.$hardware = system.deviceData.board.components.LED_RED; - -GPIO3.$name = "CONFIG_GPIO_1"; -GPIO3.$hardware = system.deviceData.board.components.LED_GREEN; - -GPIO4.$name = "CONFIG_GPIO_2"; -GPIO4.$hardware = system.deviceData.board.components["BTN-1"]; - -GPIO5.$name = "CONFIG_GPIO_3"; -GPIO5.$hardware = system.deviceData.board.components["BTN-2"]; - -UART21.$name = "UART0"; -UART21.$hardware = system.deviceData.board.components.XDS110UART; +UART21.$name = "UART0"; +UART21.$hardware = system.deviceData.board.components.XDS110UART; +UART21.rxRingBufferSize = 256; easylink.EasyLink_Phy_50kbps2gfsk = true; easylink.EasyLink_Phy_5kbpsSlLr = true; @@ -64,10 +49,6 @@ easylink.radioConfigEasylinkPhy200kbps2gfsk.codeExportConfig.$name = "ti_devices */ ADC1.adc.$suggestSolution = "ADC0"; ADC1.adc.adcPin.$suggestSolution = "boosterpack.2"; -GPIO2.gpioPin.$suggestSolution = "boosterpack.39"; -GPIO3.gpioPin.$suggestSolution = "boosterpack.40"; -GPIO4.gpioPin.$suggestSolution = "boosterpack.13"; -GPIO5.gpioPin.$suggestSolution = "boosterpack.12"; UART21.uart.$suggestSolution = "UART0"; UART21.uart.txPin.$suggestSolution = "boosterpack.4"; UART21.uart.rxPin.$suggestSolution = "boosterpack.3"; diff --git a/targets/TI_SimpleLink/TI_CC1352R1_LAUNCHXL/common/Device_BlockStorage-DEBUG.c b/targets/TI_SimpleLink/TI_CC1352R1_LAUNCHXL/common/Device_BlockStorage-DEBUG.c index e3949c44f8..95886ddf09 100644 --- a/targets/TI_SimpleLink/TI_CC1352R1_LAUNCHXL/common/Device_BlockStorage-DEBUG.c +++ b/targets/TI_SimpleLink/TI_CC1352R1_LAUNCHXL/common/Device_BlockStorage-DEBUG.c @@ -10,8 +10,8 @@ const BlockRange BlockRange1[] = { // the last block is reserved for Customer Configuration Area and Bootloader Backdoor configuration // so we don't take it into account for the map - {BlockRange_BLOCKTYPE_CODE, 0, 31}, // 0x00000000 nanoCLR - {BlockRange_BLOCKTYPE_DEPLOYMENT, 32, 42}, // 0x00041000 deployment + {BlockRange_BLOCKTYPE_CODE, 0, 32}, // 0x00000000 nanoCLR + {BlockRange_BLOCKTYPE_DEPLOYMENT, 33, 42}, // 0x00042000 deployment }; const BlockRegionInfo BlockRegions[] = {{ diff --git a/targets/TI_SimpleLink/TI_CC1352R1_LAUNCHXL/nanoCLR/CC13x2_26x2_CLR-DEBUG.ld b/targets/TI_SimpleLink/TI_CC1352R1_LAUNCHXL/nanoCLR/CC13x2_26x2_CLR-DEBUG.ld index dca2e4ba0b..81c92824a9 100644 --- a/targets/TI_SimpleLink/TI_CC1352R1_LAUNCHXL/nanoCLR/CC13x2_26x2_CLR-DEBUG.ld +++ b/targets/TI_SimpleLink/TI_CC1352R1_LAUNCHXL/nanoCLR/CC13x2_26x2_CLR-DEBUG.ld @@ -40,7 +40,7 @@ HEAPSIZE = 0x3000; /* Size of heap buffer used by HeapMem */ MEMORY { /* original flash LENGTH was 0x00057fa8 */ - FLASH (RX) : ORIGIN = 0x00000000, LENGTH = 0x00041000 + FLASH (RX) : ORIGIN = 0x00000000, LENGTH = 0x00042000 /* * Customer Configuration Area and Bootloader Backdoor configuration in * flash, 40 bytes diff --git a/targets/TI_SimpleLink/TI_CC1352R1_LAUNCHXL/target_system_device_pwm_config.cpp b/targets/TI_SimpleLink/TI_CC1352R1_LAUNCHXL/target_system_device_pwm_config.cpp new file mode 100644 index 0000000000..73cc6666d3 --- /dev/null +++ b/targets/TI_SimpleLink/TI_CC1352R1_LAUNCHXL/target_system_device_pwm_config.cpp @@ -0,0 +1,9 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS BLANK ON PURPOSE BECAUSE THIS TARGET DOESN'T REQUIRE THIS SPECIFIC CONFIGURATION // +/////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/targets/TI_SimpleLink/TI_CC3220SF_LAUNCHXL/CMakePresets.json b/targets/TI_SimpleLink/TI_CC3220SF_LAUNCHXL/CMakePresets.json new file mode 100644 index 0000000000..3305e0bc2f --- /dev/null +++ b/targets/TI_SimpleLink/TI_CC3220SF_LAUNCHXL/CMakePresets.json @@ -0,0 +1,50 @@ +{ + "version": 4, + "include": [ + "../../../CMake/arm-gcc.json", + "../../../config/user-tools-repos.json", + "../../../config/user-prefs.json" + ], + "configurePresets": [ + { + "name": "TI_CC3220SF_LAUNCHXL", + "inherits": [ + "arm-gcc-cortex-preset", + "user-tools-repos", + "user-prefs" + ], + "hidden": false, + "cacheVariables": { + "TARGET_BOARD": "${presetName}", + "RTOS": "TI_SimpleLink", + "TARGET_SERIES": "CC32xx", + "SUPPORT_ANY_BASE_CONVERSION": "OFF", + "NF_TARGET_HAS_NANOBOOTER": "OFF", + "NF_FEATURE_DEBUGGER": "ON", + "NF_FEATURE_RTC": "ON", + "NF_FEATURE_WATCHDOG": "OFF", + "NF_FEATURE_HAS_SDCARD": "OFF", + "NF_FEATURE_HAS_CONFIG_BLOCK": "ON", + "NF_BUILD_RTM": "OFF", + "API_System.Math": "ON", + "API_System.Device.Gpio": "ON", + "API_System.Device.Spi": "ON", + "API_System.Device.I2c": "ON", + "API_System.Device.Pwm": "ON", + "API_System.IO.Ports": "OFF", + "API_System.Net": "ON", + "API_nanoFramework.ResourceManager": "OFF", + "API_nanoFramework.System.Collections": "ON", + "API_nanoFramework.System.Text": "ON" + } + } + ], + "buildPresets": [ + { + "inherits": "base-user", + "name": "TI_CC3220SF_LAUNCHXL", + "displayName": "TI_CC3220SF_LAUNCHXL", + "configurePreset": "TI_CC3220SF_LAUNCHXL" + } + ] +} diff --git a/targets/TI_SimpleLink/TI_CC3220SF_LAUNCHXL/target_sntp_opts.h b/targets/TI_SimpleLink/TI_CC3220SF_LAUNCHXL/target_sntp_opts.h index 3da72e29c1..46d625ace8 100644 --- a/targets/TI_SimpleLink/TI_CC3220SF_LAUNCHXL/target_sntp_opts.h +++ b/targets/TI_SimpleLink/TI_CC3220SF_LAUNCHXL/target_sntp_opts.h @@ -14,12 +14,12 @@ // Must wait at least 15 sec to retry NTP server (RFC 4330) #define SNTP_UPDATE_DELAY (60 * 60) -// no startup delay for SNTP +// better have a startup delay because we can have DHCP enabled (default 2 seconds) // value in seconds -#define SNTP_STARTUP_DELAY (0) +#define SNTP_STARTUP_DELAY (2) -// retry timeout +// retry timeout (15 minutes) // value in seconds -#define SNTP_RETRY_TIMEOUT (10) +#define SNTP_RETRY_TIMEOUT (15 * 60) #endif // TARGET_SNTP_OPTS_H diff --git a/targets/TI_SimpleLink/TI_CC3220SF_LAUNCHXL/target_system_device_pwm_config.cpp b/targets/TI_SimpleLink/TI_CC3220SF_LAUNCHXL/target_system_device_pwm_config.cpp new file mode 100644 index 0000000000..73cc6666d3 --- /dev/null +++ b/targets/TI_SimpleLink/TI_CC3220SF_LAUNCHXL/target_system_device_pwm_config.cpp @@ -0,0 +1,9 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS BLANK ON PURPOSE BECAUSE THIS TARGET DOESN'T REQUIRE THIS SPECIFIC CONFIGURATION // +/////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/targets/TI_SimpleLink/_common/CMakeLists.txt b/targets/TI_SimpleLink/_common/CMakeLists.txt index aaa83b4a09..f2c63dda25 100644 --- a/targets/TI_SimpleLink/_common/CMakeLists.txt +++ b/targets/TI_SimpleLink/_common/CMakeLists.txt @@ -15,6 +15,7 @@ list(APPEND TARGET_TI_SimpleLink_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/sys # append nanoHAL list(APPEND TARGET_TI_SimpleLink_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/platformHAL.c") list(APPEND TARGET_TI_SimpleLink_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/platformHAL_Time.cpp") +list(APPEND TARGET_TI_SimpleLink_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/targetHAL_Rtos.c") # append configuration manager according to target if("${TARGET_SERIES}" STREQUAL "CC32xx") diff --git a/targets/TI_SimpleLink/_common/platformHAL_Time.cpp b/targets/TI_SimpleLink/_common/platformHAL_Time.cpp index ccb210cf9c..35d4aa02a7 100644 --- a/targets/TI_SimpleLink/_common/platformHAL_Time.cpp +++ b/targets/TI_SimpleLink/_common/platformHAL_Time.cpp @@ -3,12 +3,6 @@ // See LICENSE file in the project root for full license information. // -#include - -#include - -// Converts TI RTOS clock tick period to .NET ticks (100 nanoseconds) -uint64_t HAL_Time_SysTicksToTime(uint64_t sysTicks) -{ - return ((int64_t)sysTicks * (int64_t)Clock_tickPeriod) * 10; -} +//////////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS BLANK ON PURPOSE HAS THERE IS NO PLATFORM IMPLEMENTATION REQUIRED // +//////////////////////////////////////////////////////////////////////////////////// diff --git a/targets/TI_SimpleLink/_common/platform_heap.c b/targets/TI_SimpleLink/_common/platform_heap.c index 894418e76d..66606db879 100644 --- a/targets/TI_SimpleLink/_common/platform_heap.c +++ b/targets/TI_SimpleLink/_common/platform_heap.c @@ -28,15 +28,3 @@ void platform_free(void *ptr) // define back #define malloc YOU_SHALL_NOT_USE_free } - -void *platform_realloc(void *ptr, size_t size) -{ - -// need to undef in order to call the real function -#undef realloc - - return realloc(ptr, size); - - // define back -#define realloc YOU_SHALL_NOT_USE_realloc -} diff --git a/targets/TI_SimpleLink/_common/ssl_simplelink.cpp b/targets/TI_SimpleLink/_common/ssl_simplelink.cpp index f05e72aa92..28423250cd 100644 --- a/targets/TI_SimpleLink/_common/ssl_simplelink.cpp +++ b/targets/TI_SimpleLink/_common/ssl_simplelink.cpp @@ -129,7 +129,7 @@ bool ssl_generic_init_internal( } // create security attribute - // this is the equivalent of SSL context in mbedTLS + // this is the equivalent of SSL context in MbedTLS // it needs to be freed in ssl_exit_context_internal context->SecurityAttributes = SlNetSock_secAttribCreate(); if (context->SecurityAttributes == NULL) diff --git a/targets/TI_SimpleLink/_common/targetHAL_Rtos.c b/targets/TI_SimpleLink/_common/targetHAL_Rtos.c new file mode 100644 index 0000000000..295507bc7a --- /dev/null +++ b/targets/TI_SimpleLink/_common/targetHAL_Rtos.c @@ -0,0 +1,12 @@ +// +// Copyright (c) .NET Foundation and Contributors +// See LICENSE file in the project root for full license information. +// + +#include +#include + +void RtosYield() +{ + Task_yield(); +} diff --git a/targets/TI_SimpleLink/_include/targetHAL_Time.h b/targets/TI_SimpleLink/_include/targetHAL_Time.h index a6d85aae61..b413877089 100644 --- a/targets/TI_SimpleLink/_include/targetHAL_Time.h +++ b/targets/TI_SimpleLink/_include/targetHAL_Time.h @@ -8,6 +8,21 @@ #include -#define HAL_Time_CurrentSysTicks Clock_getTicks +#define HAL_Time_CurrentSysTicks Clock_getTicks -#endif //TARGET_HAL_TIME_H +#ifdef __cplusplus +extern "C" +{ +#endif + + // Converts TI RTOS clock tick period to .NET ticks (100 nanoseconds) + inline __attribute__((always_inline)) uint64_t HAL_Time_SysTicksToTime(uint64_t sysTicks) + { + return ((int64_t)sysTicks * (int64_t)Clock_tickPeriod) * 10; + } + +#ifdef __cplusplus +} +#endif + +#endif // TARGET_HAL_TIME_H diff --git a/targets/TI_SimpleLink/_include/targetSimpleLinkCC32xx_Sntp.h b/targets/TI_SimpleLink/_include/targetSimpleLinkCC32xx_Sntp.h index ab2ec682b8..bd98f24e6c 100644 --- a/targets/TI_SimpleLink/_include/targetSimpleLinkCC32xx_Sntp.h +++ b/targets/TI_SimpleLink/_include/targetSimpleLinkCC32xx_Sntp.h @@ -25,10 +25,10 @@ #define SNTP_UPDATE_DELAY (15) #endif -// better have a startup delay because we can have DHCP enabled (default 30 seconds) +// better have a startup delay because we can have DHCP enabled (default 2 seconds) // value in seconds #ifndef SNTP_STARTUP_DELAY -#define SNTP_STARTUP_DELAY (30) +#define SNTP_STARTUP_DELAY (2) #endif // retry timeout (15 minutes) @@ -152,4 +152,4 @@ extern "C" } #endif -#endif //TARGET_SNTP_H +#endif // TARGET_SNTP_H diff --git a/targets/TI_SimpleLink/_nanoCLR/System.Device.Gpio/cpu_gpio.cpp b/targets/TI_SimpleLink/_nanoCLR/System.Device.Gpio/cpu_gpio.cpp index 1b143c22ab..b82d86609e 100644 --- a/targets/TI_SimpleLink/_nanoCLR/System.Device.Gpio/cpu_gpio.cpp +++ b/targets/TI_SimpleLink/_nanoCLR/System.Device.Gpio/cpu_gpio.cpp @@ -98,37 +98,6 @@ gpio_input_state *GetInputStateByConfigIndex(uint8_t pinConfigIndex) return NULL; } -// find a free slot in the pin config array -int8_t FindFreePinConfig() -{ - for (uint8_t index = 0; index < GPIO_pinUpperBound + 1; index++) - { - if ((uint16_t)gpioPinConfigs[index] == GPIO_CFG_NO_DIR) - { - // found a free slot! - return index; - } - } - - return -1; -} - -// find a pin number in the pin config array -int8_t FindPinConfig(GPIO_PIN pinNumber) -{ - for (uint8_t index = 0; index < GPIO_pinUpperBound + 1; index++) - { - // need to mask the gpioPinConfigs item to get only the 8 LSbits where the pin number is stored - if ((uint8_t)gpioPinConfigs[index] == pinNumber) - { - // found a free slot! - return index; - } - } - - return -1; -} - // Allocate a new gpio_input_state and add to end of list // if already exist then just return current ptr gpio_input_state *AllocateGpioInputState(GPIO_PIN pinNumber) @@ -164,13 +133,12 @@ void UnlinkInputState(gpio_input_state *pState) // Remove interrupt associated with pin // it's OK to do always this, no matter if interrupts are enabled or not - GPIO_disableInt(pState->pinConfigIndex); - // disable pin - GPIO_setConfig(pState->pinConfigIndex, GPIO_CFG_IN_NOPULL); + // clear pin config array + gpioPinConfigs[pState->pinConfigIndex] = GPIO_CFG_NO_DIR; - // remove callback - gpioCallbackFunctions[pState->pinConfigIndex] = NULL; + // reset pin + GPIO_resetConfig(pState->pinConfigIndex); // unlink from list pState->Unlink(); @@ -264,11 +232,18 @@ bool CPU_GPIO_Initialize() // clear GPIO pin configs for (uint8_t index = 0; index < GPIO_pinUpperBound + 1; index++) { + // except if the pin is NOT available... + // ... or it's reserved for Wire Protocol UART + if (gpioPinConfigs[index] == 0 || index == CONFIG_GPIO_UART0_TX_CONST || index == CONFIG_GPIO_UART0_RX_CONST) + { + continue; + } + gpioPinConfigs[index] == GPIO_CFG_NO_DIR; } // clear callbacks - memset(gpioCallbackFunctions, 0, (GPIO_pinUpperBound + 1) * sizeof(GPIO_CallbackFxn)); + memset(&gpioCallbackFunctions[0], 0, (GPIO_pinUpperBound + 1) * sizeof(GPIO_CallbackFxn)); return true; } @@ -281,6 +256,23 @@ bool CPU_GPIO_Uninitialize() } NANOCLR_FOREACH_NODE_END(); + // clear GPIO pin configs + for (uint8_t index = 0; index < GPIO_pinUpperBound + 1; index++) + { + // except if the pin is NOT available... + // ... or it's reserved for Wire Protocol UART + if (gpioPinConfigs[index] == 0 || index == CONFIG_GPIO_UART0_TX_CONST || index == CONFIG_GPIO_UART0_RX_CONST) + { + continue; + } + + // store config + gpioPinConfigs[index] = GPIO_CFG_NO_DIR; + + // reset pin + GPIO_resetConfig(index); + } + return true; } @@ -293,43 +285,16 @@ bool CPU_GPIO_ReservePin(GPIO_PIN pinNumber, bool fReserve) return false; } - GLOBAL_LOCK(); - - uint8_t index = FindPinConfig(pinNumber); - - if (fReserve) - { - if (index < 0) - { - // pin already in use - - GLOBAL_UNLOCK(); - - return false; - } - else - { - // pin not being used, get the next free slot - index = FindFreePinConfig(); - - // reserve pin - gpioPinConfigs[index] = pinNumber; - } - } - else - { - gpioPinConfigs[index] == GPIO_CFG_NO_DIR; - } - - GLOBAL_UNLOCK(); - - return true; + return !CPU_GPIO_PinIsBusy(pinNumber); } // Return if Pin is reserved bool CPU_GPIO_PinIsBusy(GPIO_PIN pinNumber) { - return (FindPinConfig(pinNumber) >= 0); + uint32_t noDirConfig = GPIO_CFG_NO_DIR; + uint32_t currentConfig = gpioPinConfigs[pinNumber]; + + return currentConfig > 0 && currentConfig != noDirConfig; } // Return maximum number of pins @@ -341,36 +306,19 @@ int32_t CPU_GPIO_GetPinCount() // Get current state of pin GpioPinValue CPU_GPIO_GetPinState(GPIO_PIN pinNumber) { - // get index of pin in config array - uint8_t pinConfigIndex = FindPinConfig(pinNumber); - - if (pinConfigIndex >= 0) - { - return (GpioPinValue)GPIO_read(pinConfigIndex); - } + return (GpioPinValue)GPIO_read(pinNumber); } // Set Pin state void CPU_GPIO_SetPinState(GPIO_PIN pinNumber, GpioPinValue pinState) { - // get index of pin in config array - uint8_t pinConfigIndex = FindPinConfig(pinNumber); - - if (pinConfigIndex >= 0) - { - GPIO_write(pinConfigIndex, pinState); - } + GPIO_write(pinNumber, pinState); } // Toggle pin state void CPU_GPIO_TogglePinState(GPIO_PIN pinNumber) { - uint8_t pinConfigIndex = FindPinConfig(pinNumber); - - if (pinConfigIndex >= 0) - { - GPIO_toggle(pinConfigIndex); - } + GPIO_toggle(pinNumber); } // Enable gpio pin for input @@ -392,13 +340,13 @@ bool CPU_GPIO_EnableInputPin( pState = AllocateGpioInputState(pinNumber); - // get the index of this GPIO in pin config array - // and store it - pState->pinConfigIndex = FindPinConfig(pinNumber); + // store index of this GPIO + pState->pinConfigIndex = pinNumber; // set default input config for GPIO pin - gpioPinConfigs[pState->pinConfigIndex] |= - GPIO_CFG_INPUT_INTERNAL | GPIO_CFG_IN_INT_NONE | GPIO_CFG_PULL_NONE_INTERNAL; + gpioPinConfigs[pState->pinConfigIndex] = GPIO_CFG_INPUT | GPIO_CFG_IN_INT_NONE; + + GPIO_setConfig(pState->pinConfigIndex, gpioPinConfigs[pState->pinConfigIndex]); if (!CPU_GPIO_SetDriveMode(pState->pinConfigIndex, driveMode)) { @@ -409,16 +357,11 @@ bool CPU_GPIO_EnableInputPin( // CPU_GPIO_EnableInputPin could be called a 2nd time with changed parameters if (pinISR != NULL && (pState->isrPtr == NULL)) { - // get current config - GPIO_PinConfig currentPinConfig; - GPIO_getConfig(pState->pinConfigIndex, ¤tPinConfig); - - // set interrupt on both edges - GPIO_setConfig(pState->pinConfigIndex, currentPinConfig | GPIO_CFG_IN_INT_BOTH_EDGES); // set callback GPIO_setCallback(pState->pinConfigIndex, GpioEventCallback); - // enable INT - GPIO_enableInt(pState->pinConfigIndex); + + // set interrupt on both edges and enable interrupt + GPIO_setInterruptConfig(pState->pinConfigIndex, GPIO_CFG_IN_INT_BOTH_EDGES | GPIO_CFG_INT_ENABLE); // store parameters & configs pState->isrPtr = pinISR; @@ -473,16 +416,10 @@ bool CPU_GPIO_EnableInputPin( // there is no managed handler setup anymore // remove INT handler - // get current config - GPIO_PinConfig currentPinConfig; - GPIO_getConfig(pState->pinConfigIndex, ¤tPinConfig); - // disable interrupt GPIO_disableInt(pState->pinConfigIndex); // remove callback GPIO_setCallback(pState->pinConfigIndex, NULL); - // remove interrupt config - GPIO_setConfig(pState->pinConfigIndex, currentPinConfig | GPIO_CFG_IN_INT_NONE); // clear parameters & configs pState->isrPtr = NULL; @@ -509,16 +446,20 @@ bool CPU_GPIO_EnableOutputPin(GPIO_PIN pinNumber, GpioPinValue InitialState, Pin return false; } + // check if pin is already in use + if (CPU_GPIO_PinIsBusy(pinNumber)) + { + return false; + } // If this is currently an input pin then clean up DeleteGpioInputState(pinNumber); - // get free slot in pin config array - uint8_t pinConfigIndex = FindPinConfig(pinNumber); - // set the GPIO pin as output - gpioPinConfigs[pinConfigIndex] |= GPIO_CFG_OUT_STD; + gpioPinConfigs[pinNumber] = GPIO_CFG_OUT_STD; + + GPIO_setConfig(pinNumber, gpioPinConfigs[pinNumber]); - if (CPU_GPIO_SetDriveMode(pinConfigIndex, driveMode) == false) + if (CPU_GPIO_SetDriveMode(pinNumber, driveMode) == false) { return false; } @@ -532,62 +473,58 @@ void CPU_GPIO_DisablePin(GPIO_PIN pinNumber, PinMode driveMode, uint32_t alterna { GLOBAL_LOCK(); - uint8_t pinConfigIndex = FindPinConfig(pinNumber); - - if (pinConfigIndex >= 0) - { - DeleteGpioInputState(pinNumber); + DeleteGpioInputState(pinNumber); - CPU_GPIO_SetDriveMode(pinConfigIndex, driveMode); + CPU_GPIO_SetDriveMode(pinNumber, driveMode); - if (alternateFunction) - { - GPIO_setConfig(pinConfigIndex, alternateFunction); - } + if (alternateFunction) + { + GPIO_setConfig(pinNumber, alternateFunction); + } - GLOBAL_UNLOCK(); + GLOBAL_UNLOCK(); - CPU_GPIO_ReservePin(pinNumber, false); - } + // clear pin config + gpioPinConfigs[pinNumber] = GPIO_CFG_NO_DIR; } // Set drive mode // pinNumber is the index of the corresponding PIN config in array // return true if ok -bool CPU_GPIO_SetDriveMode(GPIO_PIN pinConfigIndex, PinMode driveMode) +bool CPU_GPIO_SetDriveMode(GPIO_PIN pinNumber, PinMode driveMode) { // get current config GPIO_PinConfig currentPinConfig; - GPIO_getConfig(pinConfigIndex, ¤tPinConfig); + GPIO_getConfig(pinNumber, ¤tPinConfig); switch (driveMode) { case PinMode_Input: - GPIO_setConfig(pinConfigIndex, currentPinConfig | GPIO_CFG_IN_NOPULL); + GPIO_setConfig(pinNumber, currentPinConfig | GPIO_CFG_IN_NOPULL); break; case PinMode_InputPullDown: - GPIO_setConfig(pinConfigIndex, currentPinConfig | GPIO_CFG_IN_PD); + GPIO_setConfig(pinNumber, currentPinConfig | GPIO_CFG_IN_PD); break; case PinMode_InputPullUp: - GPIO_setConfig(pinConfigIndex, currentPinConfig | GPIO_CFG_IN_PU); + GPIO_setConfig(pinNumber, currentPinConfig | GPIO_CFG_IN_PU); break; case PinMode_Output: - GPIO_setConfig(pinConfigIndex, currentPinConfig | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_MED); + GPIO_setConfig(pinNumber, currentPinConfig | GPIO_CFG_OUT_STD | GPIO_CFG_OUT_STR_MED); break; case PinMode_OutputOpenDrain: - GPIO_setConfig(pinConfigIndex, currentPinConfig | GPIO_CFG_OUT_OD_NOPULL); + GPIO_setConfig(pinNumber, currentPinConfig | GPIO_CFG_OUT_OD_NOPULL); break; case PinMode_OutputOpenDrainPullUp: - GPIO_setConfig(pinConfigIndex, currentPinConfig | GPIO_CFG_OUT_OD_PU); + GPIO_setConfig(pinNumber, currentPinConfig | GPIO_CFG_OUT_OD_PU); break; case PinMode_OutputOpenSourcePullDown: - GPIO_setConfig(pinConfigIndex, currentPinConfig | GPIO_CFG_OUT_OD_PD); + GPIO_setConfig(pinNumber, currentPinConfig | GPIO_CFG_OUT_OD_PD); break; default: diff --git a/targets/TI_SimpleLink/_nanoCLR/System.Device.I2c/sys_dev_i2c_native_System_Device_I2c_I2cDevice.cpp b/targets/TI_SimpleLink/_nanoCLR/System.Device.I2c/sys_dev_i2c_native_System_Device_I2c_I2cDevice.cpp index e2037ca58e..b48ddf46ec 100644 --- a/targets/TI_SimpleLink/_nanoCLR/System.Device.I2c/sys_dev_i2c_native_System_Device_I2c_I2cDevice.cpp +++ b/targets/TI_SimpleLink/_nanoCLR/System.Device.I2c/sys_dev_i2c_native_System_Device_I2c_I2cDevice.cpp @@ -31,6 +31,7 @@ HRESULT Library_sys_dev_i2c_native_System_Device_I2c_I2cDevice::NativeInit___VOI NANOCLR_HEADER(); { NF_PAL_I2C *palI2c = NULL; + I2cBusSpeed busSpeed; // get a pointer to the managed object instance and check that it's not NULL CLR_RT_HeapBlock *pThis = stack.This(); @@ -68,10 +69,21 @@ HRESULT Library_sys_dev_i2c_native_System_Device_I2c_I2cDevice::NativeInit___VOI // Create I2C for usage I2C_Params_init(&palI2c->i2cParams); - palI2c->i2cParams.bitRate = - (I2cBusSpeed)pConfig[I2cConnectionSettings::FIELD___busSpeed].NumericByRef().s4 == I2cBusSpeed_StandardMode - ? I2C_100kHz - : I2C_400kHz; + busSpeed = (I2cBusSpeed)pConfig[I2cConnectionSettings::FIELD___busSpeed].NumericByRef().s4; + if (busSpeed == I2cBusSpeed::I2cBusSpeed_FastModePlus) + { + palI2c->i2cParams.bitRate = I2C_1000kHz; + } + else if (busSpeed == I2cBusSpeed::I2cBusSpeed_FastMode) + { + palI2c->i2cParams.bitRate = I2C_400kHz; + } + else + { + // Default mode is standard + palI2c->i2cParams.bitRate = I2C_100kHz; + } + palI2c->i2cParams.transferMode = I2C_MODE_CALLBACK; palI2c->i2cParams.transferCallbackFxn = HostI2C_CallbackFxn; palI2c->i2c = I2C_open(Board_I2C0, &palI2c->i2cParams); diff --git a/targets/TI_SimpleLink/_nanoCLR/System.IO.Ports/sys_io_ser_native_System_IO_Ports_SerialPort.cpp b/targets/TI_SimpleLink/_nanoCLR/System.IO.Ports/sys_io_ser_native_System_IO_Ports_SerialPort.cpp index 73e2f510d8..5907ffbb24 100644 --- a/targets/TI_SimpleLink/_nanoCLR/System.IO.Ports/sys_io_ser_native_System_IO_Ports_SerialPort.cpp +++ b/targets/TI_SimpleLink/_nanoCLR/System.IO.Ports/sys_io_ser_native_System_IO_Ports_SerialPort.cpp @@ -1055,7 +1055,7 @@ HRESULT Library_sys_io_ser_native_System_IO_Ports_SerialPort::NativeReceivedByte portIndex = (int)pThis[FIELD___portIndex].NumericByRef().s4; // Choose the driver for this SerialDevice - palUart = GetUartPAL(portIndex); + palUart = GetPalUartFromUartNum(portIndex); if (palUart == NULL) { NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); @@ -1085,11 +1085,11 @@ HRESULT Library_sys_io_ser_native_System_IO_Ports_SerialPort::GetDeviceSelector_ // declare the device selector string whose max size is "COM2," + terminator // and init with the terminator static char deviceSelectorString[] = - #if defined(NF_SERIAL_COMM_TI_USE_UART1) && (NF_SERIAL_COMM_TI_USE_UART1 == TRUE) - "COM2," + "COM2,"; +#else + ","; #endif - ; // replace the last comma with a terminator if (deviceSelectorString[hal_strlen_s(deviceSelectorString) - 1] == ',') diff --git a/targets/TI_SimpleLink/_nanoCLR/nanoCRT.cpp b/targets/TI_SimpleLink/_nanoCLR/nanoCRT.cpp index 3fcee4d9cd..ec2ab722f4 100644 --- a/targets/TI_SimpleLink/_nanoCLR/nanoCRT.cpp +++ b/targets/TI_SimpleLink/_nanoCLR/nanoCRT.cpp @@ -12,11 +12,10 @@ #if !defined(BUILD_RTM) -void hal_fprintf_SetLoggingCallback( LOGGING_CALLBACK fpn ) +void hal_fprintf_SetLoggingCallback(LOGGING_CALLBACK fpn) { (void)fpn; NATIVE_PROFILE_PAL_CRT(); - } #endif @@ -25,61 +24,64 @@ void hal_fprintf_SetLoggingCallback( LOGGING_CALLBACK fpn ) #if defined(PLATFORM_EMULATED_FLOATINGPOINT) -// no floating point, fixed point +// no floating point, fixed point -int hal_snprintf_float( char* buffer, size_t len, const char* format, int32_t f ) +int hal_snprintf_float(char *buffer, size_t len, const char *format, int32_t f) { NATIVE_PROFILE_PAL_CRT(); - uint32_t i ; - uint32_t dec; + uint32_t i; + uint32_t dec; - if ( f < 0 ) + if (f < 0) { // negative number - i = (uint32_t) -f ; - dec = i & (( 1<>HAL_FLOAT_SHIFT); - - if (dec !=0) dec = (dec * (uint32_t)HAL_FLOAT_PRECISION + (1<< (HAL_FLOAT_SHIFT-1))) >>HAL_FLOAT_SHIFT; + i = (uint32_t)-f; + dec = i & ((1 << HAL_FLOAT_SHIFT) - 1); + i = (i >> HAL_FLOAT_SHIFT); - return hal_snprintf( buffer, len, "-%d.%03u", i, (uint32_t)dec); + if (dec != 0) + dec = (dec * (uint32_t)HAL_FLOAT_PRECISION + (1 << (HAL_FLOAT_SHIFT - 1))) >> HAL_FLOAT_SHIFT; + return hal_snprintf(buffer, len, "-%d.%03u", i, (uint32_t)dec); } else { // positive number - i = (uint32_t) f ; - dec = f & (( 1<>HAL_FLOAT_SHIFT); + i = (uint32_t)f; + dec = f & ((1 << HAL_FLOAT_SHIFT) - 1); + i = (uint32_t)(i >> HAL_FLOAT_SHIFT); - if (dec !=0) dec = (dec * (uint32_t)HAL_FLOAT_PRECISION + (1<< (HAL_FLOAT_SHIFT-1))) >>HAL_FLOAT_SHIFT; + if (dec != 0) + dec = (dec * (uint32_t)HAL_FLOAT_PRECISION + (1 << (HAL_FLOAT_SHIFT - 1))) >> HAL_FLOAT_SHIFT; - return hal_snprintf( buffer, len, "%d.%03u", i, (uint32_t)dec); + return hal_snprintf(buffer, len, "%d.%03u", i, (uint32_t)dec); } } -int hal_snprintf_double( char* buffer, size_t len, const char* format, int64_t& d ) +int hal_snprintf_double(char *buffer, size_t len, const char *format, int64_t &d) { NATIVE_PROFILE_PAL_CRT(); uint64_t i; - uint32_t dec; // 32 bit is enough for decimal part + uint32_t dec; // 32 bit is enough for decimal part - if ( d < 0 ) + if (d < 0) { // negative number i = (uint64_t)-d; - - i += ((1 << (HAL_DOUBLE_SHIFT-1)) / HAL_DOUBLE_PRECISION); // add broad part of rounding increment before split - dec = i & (( 1<> HAL_DOUBLE_SHIFT ; + i += + ((1 << (HAL_DOUBLE_SHIFT - 1)) / HAL_DOUBLE_PRECISION); // add broad part of rounding increment before split - if (dec !=0) dec = (dec * HAL_DOUBLE_PRECISION + ((1 << (HAL_DOUBLE_SHIFT-1)) % HAL_DOUBLE_PRECISION)) >> HAL_DOUBLE_SHIFT; + dec = i & ((1 << HAL_DOUBLE_SHIFT) - 1); + i = i >> HAL_DOUBLE_SHIFT; - return hal_snprintf( buffer, len, "-%lld.%04u", (int64_t)i, (uint32_t)dec); + if (dec != 0) + dec = (dec * HAL_DOUBLE_PRECISION + ((1 << (HAL_DOUBLE_SHIFT - 1)) % HAL_DOUBLE_PRECISION)) >> + HAL_DOUBLE_SHIFT; + return hal_snprintf(buffer, len, "-%lld.%04u", (int64_t)i, (uint32_t)dec); } else { @@ -87,14 +89,17 @@ int hal_snprintf_double( char* buffer, size_t len, const char* format, int64_t& // positive number i = (uint64_t)d; - i += ((1 << (HAL_DOUBLE_SHIFT-1)) / HAL_DOUBLE_PRECISION); // add broad part of rounding increment before split + i += + ((1 << (HAL_DOUBLE_SHIFT - 1)) / HAL_DOUBLE_PRECISION); // add broad part of rounding increment before split - dec = i & (( 1<> HAL_DOUBLE_SHIFT; - - if (dec !=0) dec = (dec * HAL_DOUBLE_PRECISION + ((1 << (HAL_DOUBLE_SHIFT-1)) % HAL_DOUBLE_PRECISION)) >> HAL_DOUBLE_SHIFT; - return hal_snprintf( buffer, len, "%lld.%04u", (int64_t)i, (uint32_t)dec); + if (dec != 0) + dec = (dec * HAL_DOUBLE_PRECISION + ((1 << (HAL_DOUBLE_SHIFT - 1)) % HAL_DOUBLE_PRECISION)) >> + HAL_DOUBLE_SHIFT; + + return hal_snprintf(buffer, len, "%lld.%04u", (int64_t)i, (uint32_t)dec); } } @@ -103,52 +108,63 @@ int hal_snprintf_double( char* buffer, size_t len, const char* format, int64_t& #endif // because debug_printf needs to be called in both C and C++ we need a proxy to allow it to be called in 'C' -extern "C" { +extern "C" +{ #if !defined(BUILD_RTM) - - void debug_printf(const char* format, ...) + + void debug_printf(const char *format, ...) { char buffer[256]; va_list arg_ptr; - - va_start( arg_ptr, format ); - - int len = vsnprintf( buffer, sizeof(buffer)-1, format, arg_ptr ); - - DebuggerPort_Write( HalSystemConfig.stdio, buffer, len, 0 ); // skip null terminator - - va_end( arg_ptr ); + + va_start(arg_ptr, format); + + int len = vsnprintf(buffer, sizeof(buffer) - 1, format, arg_ptr); + + DebuggerPort_Write(HalSystemConfig.stdio, buffer, len, 0); // skip null terminator + + va_end(arg_ptr); } -#else - __inline void debug_printf( const char *format, ... ) {} -#endif // !defined(BUILD_RTM) +#endif // !defined(BUILD_RTM) } -int hal_strcpy_s ( char* strDst, size_t sizeInBytes, const char* strSrc ) +int hal_strcpy_s(char *strDst, size_t sizeInBytes, const char *strSrc) { NATIVE_PROFILE_PAL_CRT(); #undef strcpy size_t len; - if(strDst == NULL || strSrc == NULL || sizeInBytes == 0) {_ASSERTE(FALSE); return 1;} - + if (strDst == NULL || strSrc == NULL || sizeInBytes == 0) + { + _ASSERTE(FALSE); + return 1; + } + len = hal_strlen_s(strSrc); - if(sizeInBytes < len + 1) {_ASSERTE(FALSE); return 1;} + if (sizeInBytes < len + 1) + { + _ASSERTE(FALSE); + return 1; + } - strcpy( strDst, strSrc ); + strcpy(strDst, strSrc); return 0; -#define strcpy DoNotUse_*strcpy [] +#define strcpy DoNotUse_ *strcpy[] } -int hal_strncpy_s ( char* strDst, size_t sizeInBytes, const char* strSrc, size_t count ) +int hal_strncpy_s(char *strDst, size_t sizeInBytes, const char *strSrc, size_t count) { NATIVE_PROFILE_PAL_CRT(); #undef strncpy - if(strDst == NULL || strSrc == NULL || sizeInBytes == 0) {_ASSERTE(FALSE); return 1;} - + if (strDst == NULL || strSrc == NULL || sizeInBytes == 0) + { + _ASSERTE(FALSE); + return 1; + } + if (sizeInBytes < count + 1) { _ASSERTE(FALSE); @@ -157,49 +173,53 @@ int hal_strncpy_s ( char* strDst, size_t sizeInBytes, const char* strSrc, size_t } strDst[count] = 0; - strncpy( strDst, strSrc, count ); + strncpy(strDst, strSrc, count); return 0; -#define strncpy DoNotUse_*strncpy [] +#define strncpy DoNotUse_ *strncpy[] } -size_t hal_strlen_s (const char * str) +size_t hal_strlen_s(const char *str) { NATIVE_PROFILE_PAL_CRT(); const char *eos = str; - while( *eos++ ) ; - return( eos - str - 1 ); + while (*eos++) + ; + return (eos - str - 1); } -int hal_strncmp_s ( const char* str1, const char* str2, size_t num ) +int hal_strncmp_s(const char *str1, const char *str2, size_t num) { NATIVE_PROFILE_PAL_CRT(); #undef strncmp - if(str1 == NULL || str2 == NULL) {_ASSERTE(FALSE); return 1;} - - return strncmp( str1, str2, num ); + if (str1 == NULL || str2 == NULL) + { + _ASSERTE(FALSE); + return 1; + } + + return strncmp(str1, str2, num); -#define strncmp DoNotUse_*strncmp [] +#define strncmp DoNotUse_ *strncmp[] } // Compares 2 ASCII strings case insensitive. Does not take locale into account. -int hal_stricmp( const char * dst, const char * src ) +int hal_stricmp(const char *dst, const char *src) { int f = 0, l = 0; do { - if ( ((f = (unsigned char)(*(dst++))) >= 'A') && (f <= 'Z') ) + if (((f = (unsigned char)(*(dst++))) >= 'A') && (f <= 'Z')) { f -= 'A' - 'a'; } - if ( ((l = (unsigned char)(*(src++))) >= 'A') && (l <= 'Z') ) + if (((l = (unsigned char)(*(src++))) >= 'A') && (l <= 'Z')) { l -= 'A' - 'a'; } - } - while ( f && (f == l) ); + } while (f && (f == l)); - return(f - l); + return (f - l); } diff --git a/targets/TI_SimpleLink/_nanoCLR/targetHAL.cpp b/targets/TI_SimpleLink/_nanoCLR/targetHAL.cpp index 0479202c5d..5133a4baa1 100644 --- a/targets/TI_SimpleLink/_nanoCLR/targetHAL.cpp +++ b/targets/TI_SimpleLink/_nanoCLR/targetHAL.cpp @@ -57,9 +57,9 @@ extern "C" nanoHAL_Initialize(); } - void nanoHAL_Uninitialize_C() + void nanoHAL_Uninitialize_C(bool isPoweringDown) { - nanoHAL_Uninitialize(); + nanoHAL_Uninitialize(isPoweringDown); } } @@ -110,8 +110,10 @@ void nanoHAL_Initialize() // SOCKETS_DbgInitialize( 0 ); } -void nanoHAL_Uninitialize() +void nanoHAL_Uninitialize(bool isPoweringDown) { + (void)isPoweringDown; + // check for s_rebootHandlers for (unsigned int i = 0; i < ARRAYSIZE(s_rebootHandlers); i++) { @@ -136,7 +138,10 @@ void nanoHAL_Uninitialize() nanoSPI_Uninitialize(); #endif - CPU_GPIO_Uninitialize(); + if (!isPoweringDown) + { + CPU_GPIO_Uninitialize(); + } #if (HAL_USE_I2C_OPTION == TRUE) I2C_close(I2C1_PAL.i2c); @@ -150,15 +155,6 @@ void nanoHAL_Uninitialize() EasyLink_abort(); #endif - // disable UART pins and ADC - PIN_Config BoardGpioInitTable[] = { - 12 | PIN_INPUT_EN | PIN_NOPULL | PIN_IRQ_DIS, - 13 | PIN_INPUT_EN | PIN_NOPULL | PIN_IRQ_DIS, - 24 | PIN_INPUT_EN | PIN_NOPULL | PIN_IRQ_DIS, - PIN_TERMINATE}; - - PIN_init(BoardGpioInitTable); - Events_Uninitialize(); HAL_CONTINUATION::Uninitialize(); diff --git a/targets/TI_SimpleLink/_nanoCLR/targetHAL_Power.c b/targets/TI_SimpleLink/_nanoCLR/targetHAL_Power.c index 2efefb72ad..aadf8e2e9c 100644 --- a/targets/TI_SimpleLink/_nanoCLR/targetHAL_Power.c +++ b/targets/TI_SimpleLink/_nanoCLR/targetHAL_Power.c @@ -25,7 +25,10 @@ void CPU_SetPowerMode(PowerLevel_type powerLevel) { case PowerLevel__Off: // gracefully shutdown everything - nanoHAL_Uninitialize_C(); + nanoHAL_Uninitialize_C(true); + + // take care of platform and target specific taks for powering down + CPU_SetPowerModePlatform(powerLevel); // now let's go with shutdown Power_shutdown(0, 0); @@ -37,3 +40,15 @@ void CPU_SetPowerMode(PowerLevel_type powerLevel) break; } } + +void CPU_SetPowerModePlatform(PowerLevel_type powerLevel) +{ + // call target specific implementation + CPU_SetPowerModeTarget(powerLevel); +} + +// implemented as weak symbol to be overridden by target implementation +__nfweak void CPU_SetPowerModeTarget(PowerLevel_type powerLevel) +{ + (void)powerLevel; +} diff --git a/targets/netcore/nanoFramework.nanoCLR.CLI/ClrInstanceOperationsOptions.cs b/targets/netcore/nanoFramework.nanoCLR.CLI/ClrInstanceOperationsOptions.cs index 15089cc8f7..bcf7631135 100644 --- a/targets/netcore/nanoFramework.nanoCLR.CLI/ClrInstanceOperationsOptions.cs +++ b/targets/netcore/nanoFramework.nanoCLR.CLI/ClrInstanceOperationsOptions.cs @@ -50,7 +50,7 @@ public class ClrInstanceOperationsOptions 'v', "verbosity", Required = false, - Default = "d", + Default = "n", HelpText = "Sets the verbosity level of the command. Allowed values are q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic]. Not supported in every command; see specific command page to determine if this option is available.")] public string Verbosity { get; set; } } diff --git a/targets/netcore/nanoFramework.nanoCLR.CLI/ClrInstanceOperationsProcessor.cs b/targets/netcore/nanoFramework.nanoCLR.CLI/ClrInstanceOperationsProcessor.cs index 42a247b3d0..aa1be231e6 100644 --- a/targets/netcore/nanoFramework.nanoCLR.CLI/ClrInstanceOperationsProcessor.cs +++ b/targets/netcore/nanoFramework.nanoCLR.CLI/ClrInstanceOperationsProcessor.cs @@ -20,12 +20,13 @@ public static class ClrInstanceOperationsProcessor private const string _cloudSmithApiUrl = "https://api.cloudsmith.io/v1/packages/net-nanoframework/"; private static HttpClient _httpClient = new HttpClient(); - public static int ProcessVerb( - ClrInstanceOperationsOptions options, - nanoCLRHostBuilder hostBuilder) + public static int ProcessVerb(ClrInstanceOperationsOptions options) { Program.ProcessVerbosityOptions(options.Verbosity); + nanoCLRHostBuilder hostBuilder = nanoCLRHost.CreateBuilder(); + hostBuilder.UseConsoleDebugPrint(); + if (options.UpdateCLR) { return (int)UpdateNanoCLRAsync( @@ -35,6 +36,11 @@ public static int ProcessVerb( } else if (options.GetCLRVersion) { + if (Program.VerbosityLevel > VerbosityLevel.Normal) + { + hostBuilder.OutputNanoClrDllInfo(); + } + Console.WriteLine($"nanoCLR version: {hostBuilder.GetCLRVersion()}"); return (int)ExitCode.OK; @@ -52,10 +58,18 @@ private static async Task UpdateNanoCLRAsync( { // compose current version // need to get rid of git hub has, in case it has one - currentVersion = currentVersion.Substring(0, currentVersion.IndexOf("+") < 0 ? currentVersion.Length : currentVersion.IndexOf("+")); + if (string.IsNullOrEmpty(currentVersion)) + { + currentVersion = "0.0.0.0"; + } + else + { + currentVersion = currentVersion.Substring(0, currentVersion.IndexOf("+") < 0 ? currentVersion.Length : currentVersion.IndexOf("+")); + } + Version version = Version.Parse(currentVersion); - string nanoClrDllLocation = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "nanoFramework.nanoCLR.dll"); + string nanoClrDllLocation = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "NanoCLR", "nanoFramework.nanoCLR.dll"); _httpClient.BaseAddress = new Uri(_cloudSmithApiUrl); _httpClient.DefaultRequestHeaders.Add("Accept", "*/*"); @@ -81,8 +95,12 @@ private static async Task UpdateNanoCLRAsync( { Version latestFwVersion = Version.Parse(packageInfo.ElementAt(0).Version); - if (latestFwVersion > version - || (!string.IsNullOrEmpty(targetVersion) + if (latestFwVersion < version) + { + Console.WriteLine($"Current version {version} lower than available version {packageInfo.ElementAt(0).Version}"); + } + else if (latestFwVersion > version + || (!string.IsNullOrEmpty(targetVersion) && (Version.Parse(targetVersion) > Version.Parse(currentVersion)))) { response = await _httpClient.GetAsync(packageInfo.ElementAt(0).DownloadUrl); diff --git a/targets/netcore/nanoFramework.nanoCLR.CLI/ExecuteCommandLineOptions.cs b/targets/netcore/nanoFramework.nanoCLR.CLI/ExecuteCommandLineOptions.cs index 513636e974..60d6f75872 100644 --- a/targets/netcore/nanoFramework.nanoCLR.CLI/ExecuteCommandLineOptions.cs +++ b/targets/netcore/nanoFramework.nanoCLR.CLI/ExecuteCommandLineOptions.cs @@ -3,8 +3,8 @@ // See LICENSE file in the project root for full license information. // -using System.Collections.Generic; using CommandLine; +using System.Collections.Generic; namespace nanoFramework.nanoCLR.CLI { @@ -89,10 +89,32 @@ public class ExecuteCommandLineOptions [Option( "loopafterexit", Required = false, - Default = true, + Default = false, HelpText = "Option to remain in loop waiting for a debugger connection after the program exits.")] public bool EnterDebuggerLoopAfterExit { get; set; } + [Option( + "forcegc", + Required = false, + Default = false, + HelpText = "Option to force GC before each allocation.")] + public bool PerformGarbageCollection { get; set; } + + [Option( + "compactionaftergc", + Required = false, + Default = false, + HelpText = "Option to force heap compaction after each GC run.")] + public bool PerformHeapCompaction { get; set; } + + [Option( + "localinstance", + Required = false, + Default = null, + Hidden = true, + HelpText = "Path to a local instance of the nanoCLR.")] + public string LocalInstance { get; set; } + /// /// Allowed values: /// q[uiet] @@ -105,7 +127,7 @@ public class ExecuteCommandLineOptions 'v', "verbosity", Required = false, - Default = "d", + Default = "n", HelpText = "Sets the verbosity level of the command. Allowed values are q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic]. Not supported in every command; see specific command page to determine if this option is available.")] public string Verbosity { get; set; } } diff --git a/targets/netcore/nanoFramework.nanoCLR.CLI/ExecuteCommandProcessor.cs b/targets/netcore/nanoFramework.nanoCLR.CLI/ExecuteCommandProcessor.cs index 029520e74d..ffef757d27 100644 --- a/targets/netcore/nanoFramework.nanoCLR.CLI/ExecuteCommandProcessor.cs +++ b/targets/netcore/nanoFramework.nanoCLR.CLI/ExecuteCommandProcessor.cs @@ -7,6 +7,7 @@ using nanoFramework.nanoCLR.Host.Port.TcpIp; using System; using System.Diagnostics; +using System.IO; using System.Linq; using System.Runtime.Versioning; @@ -17,11 +18,30 @@ internal static class ExecuteCommandProcessor [SupportedOSPlatform("windows")] public static int ProcessVerb( ExecuteCommandLineOptions options, - nanoCLRHostBuilder hostBuilder, VirtualSerialDeviceManager virtualBridgeManager) { Program.ProcessVerbosityOptions(options.Verbosity); + nanoCLRHostBuilder hostBuilder; + + // are we to use a local DLL? + if (options.LocalInstance != null) + { + // check if path exists + if (!File.Exists(options.LocalInstance)) + { + throw new CLIException(ExitCode.E9009); + } + + hostBuilder = nanoCLRHost.CreateBuilder(Path.GetDirectoryName(options.LocalInstance)); + } + else + { + hostBuilder = nanoCLRHost.CreateBuilder(); + } + + hostBuilder.UseConsoleDebugPrint(); + // flag to signal that the intenal serial port has already been configured bool internalSerialPortConfig = false; @@ -71,6 +91,11 @@ public static int ProcessVerb( } } + if (Program.VerbosityLevel > VerbosityLevel.Normal) + { + hostBuilder.OutputNanoClrDllInfo(); + } + if (options.AssembliesToLoad.Any()) { hostBuilder.LoadAssemblies(options.AssembliesToLoad); @@ -104,7 +129,8 @@ public static int ProcessVerb( hostBuilder.WaitForDebugger = options.WaitForDebugger; hostBuilder.EnterDebuggerLoopAfterExit = options.EnterDebuggerLoopAfterExit; - + hostBuilder.PerformGarbageCollection = options.PerformGarbageCollection; + hostBuilder.PerformHeapCompaction = options.PerformHeapCompaction; if (options.MonitorParentPid != null) { diff --git a/targets/netcore/nanoFramework.nanoCLR.CLI/ExitCode.cs b/targets/netcore/nanoFramework.nanoCLR.CLI/ExitCode.cs index 3c489b1137..2ecb232c00 100644 --- a/targets/netcore/nanoFramework.nanoCLR.CLI/ExitCode.cs +++ b/targets/netcore/nanoFramework.nanoCLR.CLI/ExitCode.cs @@ -100,5 +100,11 @@ public enum ExitCode /// [Display(Name = "Unknown error when starting the virtual device instance.")] E9008 = 9008, + + /// + /// Specified nanoCLR DLL file does not exist. + /// + [Display(Name = " Specified nanoCLR DLL file does not exist.")] + E9009 = 9009, } } diff --git a/targets/netcore/nanoFramework.nanoCLR.CLI/Program.cs b/targets/netcore/nanoFramework.nanoCLR.CLI/Program.cs index cc51f80d43..ecf5d31e1f 100644 --- a/targets/netcore/nanoFramework.nanoCLR.CLI/Program.cs +++ b/targets/netcore/nanoFramework.nanoCLR.CLI/Program.cs @@ -5,15 +5,17 @@ using CommandLine; using CommandLine.Text; -using nanoFramework.nanoCLR.Host; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.IO; using System.Linq; using System.Reflection; +using System.Runtime.InteropServices; using System.Runtime.Versioning; +[assembly: DefaultDllImportSearchPaths(DllImportSearchPath.UserDirectories | DllImportSearchPath.UseDllDirectoryForDependencies)] + namespace nanoFramework.nanoCLR.CLI { internal class Program @@ -55,6 +57,7 @@ static int Main(string[] args) // because of short-comings in CommandLine parsing // need to customize the output to provide a consistent output var parser = new Parser(config => config.HelpWriter = null); + var result = parser.ParseArguments(new[] { "", "" }); var helpText = new HelpText( @@ -90,8 +93,8 @@ static int Main(string[] args) VirtualSerialDeviceManager virtualSerialBridgeManager = new(); virtualSerialBridgeManager.Initialize(); - nanoCLRHostBuilder hostBuilder = nanoCLRHost.CreateBuilder(); - hostBuilder.UseConsoleDebugPrint(); + // need to set DLL directory to HHD interop DLL + SetDllDirectory(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Vendor")); var parsedArguments = Parser.Default.ParseArguments(args); @@ -101,17 +104,34 @@ static int Main(string[] args) (ExecuteCommandLineOptions opts) => ExecuteCommandProcessor.ProcessVerb( opts, - hostBuilder, virtualSerialBridgeManager), (ClrInstanceOperationsOptions opts) => ClrInstanceOperationsProcessor.ProcessVerb( - opts, - hostBuilder), + opts), (VirtualSerialDeviceCommandLineOptions opts) => VirtualSerialDeviceCommandProcessor.ProcessVerb( opts, virtualSerialBridgeManager), (IEnumerable errors) => HandleErrors(errors)); + + // do we need to show version? + if (parsedArguments.Errors.Any(error => error is VersionRequestedError)) + { + // output version + var versionAtt = Attribute.GetCustomAttribute( + Assembly.GetEntryAssembly()!, + typeof(AssemblyFileVersionAttribute)) as AssemblyFileVersionAttribute; + + var version = new Version(versionAtt.Version); + + Console.WriteLine(version.ToString(3)); + } + else if (parsedArguments.Errors.Any(error => error is HelpVerbRequestedError) + || parsedArguments.Errors.Any(error => error is HelpRequestedError)) + { + // output help + return; + } }); if (_verbosityLevel > VerbosityLevel.Quiet) @@ -147,7 +167,16 @@ internal static void ProcessVerbosityOptions(string verbosityLevel) private static int HandleErrors(IEnumerable errors) { - _exitCode = ExitCode.E9000; + if (errors.Any(error => error is VersionRequestedError) + || errors.Any(error => error is HelpRequestedError) + || errors.Any(error => error is HelpVerbRequestedError)) + { + // we're good here + } + else + { + _exitCode = ExitCode.E9000; + } return (int)_exitCode; } @@ -210,5 +239,9 @@ private static void LogErrors(Action scope) Console.WriteLine($"Error: {e.Message}"); } } + + [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] + public static extern bool SetDllDirectory(string lpPathName); + } } diff --git a/targets/netcore/nanoFramework.nanoCLR.CLI/nanoFramework.nanoCLR.CLI.csproj b/targets/netcore/nanoFramework.nanoCLR.CLI/nanoFramework.nanoCLR.CLI.csproj index 28c0da1171..5d61572b23 100644 --- a/targets/netcore/nanoFramework.nanoCLR.CLI/nanoFramework.nanoCLR.CLI.csproj +++ b/targets/netcore/nanoFramework.nanoCLR.CLI/nanoFramework.nanoCLR.CLI.csproj @@ -34,9 +34,9 @@ - + True - tools\net6.0\any + tools\net6.0\any\NanoCLR PreserveNewest @@ -85,5 +85,8 @@ Always - + + + + diff --git a/targets/netcore/nanoFramework.nanoCLR.CLI/version.json b/targets/netcore/nanoFramework.nanoCLR.CLI/version.json index 1c88d67169..b974f609a7 100644 --- a/targets/netcore/nanoFramework.nanoCLR.CLI/version.json +++ b/targets/netcore/nanoFramework.nanoCLR.CLI/version.json @@ -4,6 +4,7 @@ "assemblyVersion": { "precision": "minor" }, + "buildNumberOffset": 60, "nuGetPackageVersion": { "semVer": 2.0 }, diff --git a/targets/netcore/nanoFramework.nanoCLR.Host/Interop/nanoCLR.cs b/targets/netcore/nanoFramework.nanoCLR.Host/Interop/nanoCLR.cs index 6639400241..b434f393ca 100644 --- a/targets/netcore/nanoFramework.nanoCLR.Host/Interop/nanoCLR.cs +++ b/targets/netcore/nanoFramework.nanoCLR.Host/Interop/nanoCLR.cs @@ -4,6 +4,7 @@ // using System; +using System.IO; using System.Runtime.InteropServices; namespace nanoFramework.nanoCLR.Host.Interop @@ -13,6 +14,21 @@ internal class nanoCLR internal const uint ClrOk = 0; internal const uint ClrErrorFail = 0xFF000000; private const string NativeLibraryName = "nanoFramework.nanoCLR"; + private const string _nanoClrDllName = "nanoFramework.nanoCLR.dll"; + private static string _dllPath; + + internal static string DllPath + { + get => _dllPath; + + set + { + _dllPath = value; + + // set path to search nanoCLR DLL + _ = SetDllDirectory(_dllPath); + } + } internal delegate uint ConfigureDelegate(); @@ -77,11 +93,13 @@ internal static extern void nanoCLR_SetWireProtocolTransmitCallback( [DllImport("kernel32", SetLastError = true)] private static extern bool FreeLibrary(IntPtr hModule); - public static void UnloadNanoClrImageDll(string path) + public static void UnloadNanoClrImageDll() { + string nanoClrDllLocation = Path.Combine(DllPath, _nanoClrDllName); + foreach (System.Diagnostics.ProcessModule mod in System.Diagnostics.Process.GetCurrentProcess().Modules) { - if (mod.FileName.Equals(path, StringComparison.OrdinalIgnoreCase)) + if (mod.FileName.Equals(nanoClrDllLocation, StringComparison.OrdinalIgnoreCase)) { FreeLibrary(mod.BaseAddress); @@ -90,5 +108,25 @@ public static void UnloadNanoClrImageDll(string path) } } } + + public static string FindNanoClrDll() + { + // perform dummy call to load DLL, in case it's not loaded + _ = nanoCLR_GetVersion(); + + // sweep processes and look for a DLL with the nanoCLR namme + foreach (System.Diagnostics.ProcessModule mod in System.Diagnostics.Process.GetCurrentProcess().Modules) + { + if (mod.FileName.EndsWith(_nanoClrDllName, StringComparison.OrdinalIgnoreCase)) + { + return mod.FileName; + } + } + + return ""; + } + + [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] + public static extern bool SetDllDirectory(string lpPathName); } } diff --git a/targets/netcore/nanoFramework.nanoCLR.Host/NanoClrHost.cs b/targets/netcore/nanoFramework.nanoCLR.Host/NanoClrHost.cs index 820398e7b2..90b47a3c5b 100644 --- a/targets/netcore/nanoFramework.nanoCLR.Host/NanoClrHost.cs +++ b/targets/netcore/nanoFramework.nanoCLR.Host/NanoClrHost.cs @@ -21,6 +21,7 @@ public class nanoCLRHost internal nanoCLRHost() { + } public void Run() @@ -65,7 +66,9 @@ private uint ConfigureRuntime() return Interop.nanoCLR.ClrOk; } - public static nanoCLRHostBuilder CreateBuilder() => new nanoCLRHostBuilder { }; + public static nanoCLRHostBuilder CreateBuilder() => new nanoCLRHostBuilder() { }; + + public static nanoCLRHostBuilder CreateBuilder(string dllPath) => new nanoCLRHostBuilder(dllPath) { }; public void Shutdown() { diff --git a/targets/netcore/nanoFramework.nanoCLR.Host/NanoClrHostBuilder.cs b/targets/netcore/nanoFramework.nanoCLR.Host/NanoClrHostBuilder.cs index 3ab18b935a..e23a4497e5 100644 --- a/targets/netcore/nanoFramework.nanoCLR.Host/NanoClrHostBuilder.cs +++ b/targets/netcore/nanoFramework.nanoCLR.Host/NanoClrHostBuilder.cs @@ -26,6 +26,20 @@ public class nanoCLRHostBuilder public bool WaitForDebugger { get; set; } = false; public bool EnterDebuggerLoopAfterExit { get; set; } = false; + public bool PerformGarbageCollection { get; set; } = false; + + public bool PerformHeapCompaction { get; set; } = false; + + public nanoCLRHostBuilder() + { + Interop.nanoCLR.DllPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "NanoCLR"); + } + + public nanoCLRHostBuilder(string dllPath) + { + Interop.nanoCLR.DllPath = dllPath; + } + public nanoCLRHostBuilder LoadAssembly(string name, byte[] data) { _configureSteps.Add(() => Interop.nanoCLR.nanoCLR_LoadAssembly(name, data, data.Length)); @@ -108,7 +122,9 @@ public nanoCLRHost Build() { MaxContextSwitches = (ushort)MaxContextSwitches, WaitForDebugger = WaitForDebugger, - EnterDebuggerLoopAfterExit = EnterDebuggerLoopAfterExit + EnterDebuggerLoopAfterExit = EnterDebuggerLoopAfterExit, + PerformGarbageCollection = PerformGarbageCollection, + PerformHeapCompaction = PerformHeapCompaction }; return s_nanoClrHost; @@ -116,9 +132,12 @@ public nanoCLRHost Build() public void UnloadNanoClrDll() { - string nanoClrDllLocation = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "nanoFramework.nanoCLR.dll"); + Interop.nanoCLR.UnloadNanoClrImageDll(); + } - Interop.nanoCLR.UnloadNanoClrImageDll(nanoClrDllLocation); + public void OutputNanoClrDllInfo() + { + Console.WriteLine($"nanoCLR loaded from '{Interop.nanoCLR.FindNanoClrDll()}'"); } } } diff --git a/targets/netcore/nanoFramework.nanoCLR.Host/NanoClrSettings.cs b/targets/netcore/nanoFramework.nanoCLR.Host/NanoClrSettings.cs index dcd4f72689..ee349c7eaf 100644 --- a/targets/netcore/nanoFramework.nanoCLR.Host/NanoClrSettings.cs +++ b/targets/netcore/nanoFramework.nanoCLR.Host/NanoClrSettings.cs @@ -16,11 +16,17 @@ internal struct nanoCLRSettings public bool EnterDebuggerLoopAfterExit { get; set; } + public bool PerformGarbageCollection { get; set; } + + public bool PerformHeapCompaction { get; set; } + public static nanoCLRSettings Default = new() { MaxContextSwitches = 50, WaitForDebugger = false, EnterDebuggerLoopAfterExit = false, + PerformGarbageCollection = false, + PerformHeapCompaction = false, }; } } diff --git a/targets/netcore/nanoFramework.nanoCLR/CLRStartup.cpp b/targets/netcore/nanoFramework.nanoCLR/CLRStartup.cpp index 506929dff6..c5aa5e6476 100644 --- a/targets/netcore/nanoFramework.nanoCLR/CLRStartup.cpp +++ b/targets/netcore/nanoFramework.nanoCLR/CLRStartup.cpp @@ -31,8 +31,6 @@ struct Settings m_clrOptions = params; #if defined(PLATFORM_WINDOWS_EMULATOR) - g_CLR_RT_ExecutionEngine.m_fPerformGarbageCollection = params.PerformGarbageCollection; - g_CLR_RT_ExecutionEngine.m_fPerformHeapCompaction = params.PerformHeapCompaction; CLR_UINT32 clockFrequencyBaseline = 27000000; CLR_UINT32 clockFrequency = CPU_SystemClock(); @@ -50,7 +48,7 @@ struct Settings g_HAL_Configuration_Windows.GraphHeapEnabled = false; #endif - NANOCLR_CHECK_HRESULT(CLR_RT_ExecutionEngine::CreateInstance()); + NANOCLR_CHECK_HRESULT(CLR_RT_ExecutionEngine::CreateInstance(params)); #if !defined(BUILD_RTM) CLR_Debug::Printf("Created EE.\r\n"); #endif @@ -437,7 +435,7 @@ struct Settings if (!m_fInitialized) { - CLR_RT_ExecutionEngine::CreateInstance(); + CLR_RT_ExecutionEngine::CreateInstance(m_clrOptions); } { @@ -630,7 +628,7 @@ void ClrStartup(CLR_SETTINGS params) s_ClrSettings.Cleanup(); - nanoHAL_Uninitialize(); + nanoHAL_Uninitialize(false); // re-init the hal for the reboot (initially it is called in bootentry) nanoHAL_Initialize(); diff --git a/targets/netcore/nanoFramework.nanoCLR/nanoCLR_native.cpp b/targets/netcore/nanoFramework.nanoCLR/nanoCLR_native.cpp index 92f87f34ad..d0e10d61c3 100644 --- a/targets/netcore/nanoFramework.nanoCLR/nanoCLR_native.cpp +++ b/targets/netcore/nanoFramework.nanoCLR/nanoCLR_native.cpp @@ -9,6 +9,7 @@ #include #include #include +#include // // UNDONE: Feature configuration @@ -83,7 +84,19 @@ bool Target_GetReleaseInfo(NFReleaseInfo &releaseInfo) void nanoCLR_Run(NANO_CLR_SETTINGS nanoClrSettings) { - CLR_Debug::Printf("\r\nLoading nanoCLR v%s\r\n...", VERSION_STRING); + +#if _DEBUG + // only show this in debug build + DWORD pid = GetCurrentProcessId(); + CLR_Debug::Printf("Process ID: %d\r\n", pid); +#endif + + CLR_Debug::Printf( + "\r\nLoading nanoCLR v%d.%d.%d.%d\r\n...", + VERSION_MAJOR, + VERSION_MINOR, + VERSION_BUILD, + VERSION_REVISION); // initialize nanoHAL nanoHAL_Initialize(); @@ -99,6 +112,8 @@ void nanoCLR_Run(NANO_CLR_SETTINGS nanoClrSettings) clrSettings.MaxContextSwitches = nanoClrSettings.MaxContextSwitches; clrSettings.WaitForDebugger = nanoClrSettings.WaitForDebugger; clrSettings.EnterDebuggerLoopAfterExit = nanoClrSettings.EnterDebuggerLoopAfterExit; + clrSettings.PerformGarbageCollection = nanoClrSettings.PerformGarbageCollection; + clrSettings.PerformHeapCompaction = nanoClrSettings.PerformHeapCompaction; ClrStartup(clrSettings); @@ -143,9 +158,29 @@ void nanoCLR_WireProtocolClose() _wireProtocolStopProcess = true; } -char *nanoCLR_GetVersion() +const char *nanoCLR_GetVersion() { - char *pszVersion = (char *)CoTaskMemAlloc(sizeof(VERSION_STRING)); - std::memcpy(pszVersion, VERSION_STRING, sizeof(VERSION_STRING)); + char buffer[128]; + + char *pszVersion = nullptr; + pszVersion = (char *)CoTaskMemAlloc(std::size(buffer)); + + if (pszVersion != nullptr) + { + const auto result = std::format_to_n( + buffer, + std::size(buffer) - 1, + "{}.{}.{}.{}", + VERSION_MAJOR, + VERSION_MINOR, + VERSION_BUILD, + VERSION_REVISION); + *result.out = '\0'; + + const std::string_view str{buffer, result.out}; + + std::memcpy(pszVersion, buffer, result.size); + } + return pszVersion; } diff --git a/targets/netcore/nanoFramework.nanoCLR/nanoCLR_native.h b/targets/netcore/nanoFramework.nanoCLR/nanoCLR_native.h index 45b4b576ef..33354894dd 100644 --- a/targets/netcore/nanoFramework.nanoCLR/nanoCLR_native.h +++ b/targets/netcore/nanoFramework.nanoCLR/nanoCLR_native.h @@ -25,6 +25,13 @@ typedef struct NANO_CLR_SETTINGS // this is required for launching a debug session in Visual Studio // when building is set for RTM this configuration is ignored BOOL EnterDebuggerLoopAfterExit; + + // set this to TRUE if execution engine is to performa GC before each allocation + BOOL PerformGarbageCollection; + + // set this to TRUE if execution engine is to performa heap compaction after each GC run + BOOL PerformHeapCompaction; + } NANO_CLR_SETTINGS; typedef HRESULT(__stdcall *ConfigureRuntimeCallback)(); @@ -59,4 +66,4 @@ extern "C" NANOCLRNATIVE_API void nanoCLR_SetWireProtocolTransmitCallback(WireTr extern "C" NANOCLRNATIVE_API void nanoCLR_WireProtocolProcess(); -extern "C" NANOCLRNATIVE_API char *nanoCLR_GetVersion(); +extern "C" NANOCLRNATIVE_API const char *nanoCLR_GetVersion(); diff --git a/targets/netcore/pipeline_tests.runsettings b/targets/netcore/pipeline_tests.runsettings new file mode 100644 index 0000000000..9949dd43d8 --- /dev/null +++ b/targets/netcore/pipeline_tests.runsettings @@ -0,0 +1,16 @@ + + + + + 1 + .\TestResults + 1200000 + net48 + x64 + + + Verbose + False + D:\a\_temp\nanoclr_cli\nanoFramework.nanoCLR.dll + + \ No newline at end of file diff --git a/targets/win32/Include/targetHAL.h b/targets/win32/Include/targetHAL.h index dc55a0b8dc..cd5248f844 100644 --- a/targets/win32/Include/targetHAL.h +++ b/targets/win32/Include/targetHAL.h @@ -83,8 +83,10 @@ inline bool RequestToLaunchProprietaryBootloader() return false; }; -inline bool RequestToLaunchNanoBooter() +inline bool RequestToLaunchNanoBooter(int32_t errorCode) { + (void)errorCode; + return false; }; diff --git a/targets/win32/nanoCLR/CLRStartup.cpp b/targets/win32/nanoCLR/CLRStartup.cpp index e4af6cd8c4..7c3d0a3bf4 100644 --- a/targets/win32/nanoCLR/CLRStartup.cpp +++ b/targets/win32/nanoCLR/CLRStartup.cpp @@ -45,7 +45,7 @@ struct Settings : CLR_RT_ParseOptions g_HAL_Configuration_Windows.GraphHeapEnabled = false; #endif - NANOCLR_CHECK_HRESULT(CLR_RT_ExecutionEngine::CreateInstance()); + NANOCLR_CHECK_HRESULT(CLR_RT_ExecutionEngine::CreateInstance(params)); #if !defined(BUILD_RTM) CLR_Debug::Printf("Created EE.\r\n"); #endif @@ -465,7 +465,7 @@ struct Settings : CLR_RT_ParseOptions if (!m_fInitialized) { - CLR_RT_ExecutionEngine::CreateInstance(); + CLR_RT_ExecutionEngine::CreateInstance(m_clrOptions); } { @@ -562,7 +562,7 @@ struct Settings : CLR_RT_ParseOptions NANOCLR_NOCLEANUP(); } -#endif //#if defined(VIRTUAL_DEVICE) +#endif // #if defined(VIRTUAL_DEVICE) }; static Settings s_ClrSettings; @@ -641,7 +641,7 @@ void ClrStartup(CLR_SETTINGS params) #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) CLR_EE_DBG_SET_MASK(StateProgramExited, StateMask); CLR_EE_DBG_EVENT_BROADCAST(CLR_DBG_Commands::c_Monitor_ProgramExit, 0, NULL, WP_Flags_c_NonCritical); -#endif //#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) +#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING) if (params.EnterDebuggerLoopAfterExit) { diff --git a/targets/win32/nanoCLR/Various.cpp b/targets/win32/nanoCLR/Various.cpp index 6296eee545..79ed22021e 100644 --- a/targets/win32/nanoCLR/Various.cpp +++ b/targets/win32/nanoCLR/Various.cpp @@ -154,8 +154,10 @@ void __cdecl nanoHAL_Initialize(void) Events_Initialize(); } -void __cdecl nanoHAL_Uninitialize(void) +void __cdecl nanoHAL_Uninitialize(bool isPoweringDown) { + (void)isPoweringDown; + int i; // UNDONE: FIXME: CPU_GPIO_Uninitialize(); @@ -172,15 +174,15 @@ void __cdecl nanoHAL_Uninitialize(void) //////////////////////////////////////////////////////////////////////////////////////////////////// -//#if !defined(BUILD_RTM) -// void __cdecl HARD_Breakpoint() +// #if !defined(BUILD_RTM) +// void __cdecl HARD_Breakpoint() //{ -// if(::IsDebuggerPresent()) -// { -// ::DebugBreak(); -// } -//} -//#endif +// if(::IsDebuggerPresent()) +// { +// ::DebugBreak(); +// } +// } +// #endif //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -451,3 +453,7 @@ void WP_Message_PrepareReception_Platform() { // empty on purpose, nothing to configure } + +void RtosYield() +{ +} diff --git a/targets/win32/nanoCLR/base64.cpp b/targets/win32/nanoCLR/base64.cpp index 405fde804e..06a7d25680 100644 --- a/targets/win32/nanoCLR/base64.cpp +++ b/targets/win32/nanoCLR/base64.cpp @@ -5,8 +5,8 @@ // ////////////////////////////////////////////////////////////////////////////////////////////// -// we are using the function declarations matching the mbedTLS ones BUT with weak attribute // -// if the image includes the mbedTLS, these will be replaced by the strong ones from there // +// we are using the function declarations matching the MbedTLS ones BUT with weak attribute // +// if the image includes the MbedTLS, these will be replaced by the strong ones from there // // thus there will be no duplicate code // ////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/targets/win32/nanoCLR/nanoCLR.vcxproj b/targets/win32/nanoCLR/nanoCLR.vcxproj index 031060cfdd..523aa01d04 100644 --- a/targets/win32/nanoCLR/nanoCLR.vcxproj +++ b/targets/win32/nanoCLR/nanoCLR.vcxproj @@ -107,7 +107,7 @@ Use Level3 Disabled - _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _DEBUG;_CONSOLE;VERSION_STRING="$(WINCLR_AssemblyInformationalVersion)";%(PreprocessorDefinitions) ..\..\..\src\CLR\Core;..\..\..\src\CLR\CorLib;..\..\..\src\CLR\Helpers\Base64;.;..\Include;..\..\..\src\CLR\Include;..\..\..\src\HAL\Include;..\..\..\src\PAL\Include;..\..\..\src\nanoFramework.Runtime.Events @@ -120,7 +120,7 @@ Use Level3 Disabled - _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + _DEBUG;_CONSOLE;VERSION_STRING="$(WINCLR_AssemblyInformationalVersion)";%(PreprocessorDefinitions) ..\..\..\src\CLR\Core;..\..\..\src\CLR\CorLib;..\..\..\src\CLR\Helpers\Base64;.;..\Include;..\..\..\src\CLR\Include;..\..\..\src\HAL\Include;..\..\..\src\PAL\Include;..\..\..\src\nanoFramework.Runtime.Events @@ -135,7 +135,7 @@ MaxSpeed true true - NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + NDEBUG;_CONSOLE;VERSION_STRING="$(WINCLR_AssemblyInformationalVersion)";%(PreprocessorDefinitions) ..\..\..\src\CLR\Core;..\..\..\src\CLR\CorLib;..\..\..\src\CLR\Helpers\Base64;.;..\Include;..\..\..\src\CLR\Include;..\..\..\src\HAL\Include;..\..\..\src\PAL\Include;..\..\..\src\nanoFramework.Runtime.Events @@ -152,7 +152,7 @@ MaxSpeed true true - NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + NDEBUG;_CONSOLE;VERSION_STRING="$(WINCLR_AssemblyInformationalVersion)";%(PreprocessorDefinitions) ..\..\..\src\CLR\Core;..\..\..\src\CLR\CorLib;..\..\..\src\CLR\Helpers\Base64;.;..\Include;..\..\..\src\CLR\Include;..\..\..\src\HAL\Include;..\..\..\src\PAL\Include;..\..\..\src\nanoFramework.Runtime.Events diff --git a/targets/win32/nanoCLR/platform_heap.cpp b/targets/win32/nanoCLR/platform_heap.cpp index d895eb7327..89ab1c9ade 100644 --- a/targets/win32/nanoCLR/platform_heap.cpp +++ b/targets/win32/nanoCLR/platform_heap.cpp @@ -30,15 +30,3 @@ void platform_free(void *ptr) // define back #define free YOU_SHALL_NOT_USE_free } - -void *platform_realloc(void *ptr, size_t size) -{ - -// need to undef in order to call the real function -#undef realloc - - return realloc(ptr, size); - - // define back -#define realloc YOU_SHALL_NOT_USE_realloc -} diff --git a/version.json b/version.json index 6bc62c460e..4fc57a2d43 100644 --- a/version.json +++ b/version.json @@ -1,6 +1,6 @@ { "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", - "version": "1.8.0", + "version": "1.8.1", "assemblyVersion": { "precision": "revision" },