diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..a0e6042 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,35 @@ +name: Build + +on: + push: + pull_request: + schedule: + - cron: "0 0 * * *" + +jobs: + build: + runs-on: ubuntu-22.04 + container: ghcr.io/zephyrproject-rtos/ci:v0.26.2 + env: + CMAKE_PREFIX_PATH: /opt/toolchains + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + path: example-application + + - name: Initialize + working-directory: example-application + run: | + west init -l . + west update -o=--depth=1 -n + + - name: Build firmware + working-directory: example-application + run: | + west twister -T app -v --inline-logs --integration + + - name: Twister Tests + working-directory: example-application + run: | + west twister -T tests --integration diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..014d594 --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +# editors +.vscode +*.swp +*~ + +# python +.venv + +# build +/build* +/twister-out* + +__pycache__/ diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..b8b7f59 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,10 @@ +# Copyright (c) 2021 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 +# +# This CMake file is picked by the Zephyr build system because it is defined +# as the module CMake entry point (see zephyr/module.yml). + +zephyr_include_directories(include) + +add_subdirectory(drivers) +add_subdirectory(lib) diff --git a/Kconfig b/Kconfig new file mode 100644 index 0000000..3bd03f2 --- /dev/null +++ b/Kconfig @@ -0,0 +1,9 @@ +# Copyright (c) 2021 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 +# +# This Kconfig file is picked by the Zephyr build system because it is defined +# as the module Kconfig entry point (see zephyr/module.yml). You can browse +# module options by going to Zephyr -> Modules in Kconfig. + +rsource "drivers/Kconfig" +rsource "lib/Kconfig" diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md new file mode 100644 index 0000000..1263fb7 --- /dev/null +++ b/README.md @@ -0,0 +1,79 @@ +# nRF Connect SDK example application + +This repository contains an nRF Connect SDK example application. The main +purpose of this repository is to serve as a reference on how to structure nRF Connect +SDK based applications. Some of the features demonstrated in this example are: + +- Basic [Zephyr application][app_dev] skeleton +- [Zephyr workspace applications][workspace_app] +- [Zephyr modules][modules] +- [West T2 topology][west_t2] +- [Custom boards][board_porting] +- Custom [devicetree bindings][bindings] +- Out-of-tree [drivers][drivers] +- Out-of-tree libraries +- Example CI configuration (using Github Actions) +- Custom [west extension][west_ext] + +This repository is versioned together with the [nRF Connect SDK main tree][sdk-nrf]. This +means that every time that nRF Connect SDK is tagged, this repository is tagged as well +with the same version number, and the [manifest](west.yml) entry for `zephyr` +will point to the corresponding nRF Connect SDK tag. For example, the `ncs-example-application` +v2.5.0 will point to nRF Connect SDK v2.5.0. Note that the `main` branch always +points to the development branch of nRF Connect SDK, also `main`. + +[app_dev]: https://docs.zephyrproject.org/latest/develop/application/index.html +[workspace_app]: https://docs.zephyrproject.org/latest/develop/application/index.html#zephyr-workspace-app +[modules]: https://docs.zephyrproject.org/latest/develop/modules.html +[west_t2]: https://docs.zephyrproject.org/latest/develop/west/workspaces.html#west-t2 +[board_porting]: https://docs.zephyrproject.org/latest/guides/porting/board_porting.html +[bindings]: https://docs.zephyrproject.org/latest/guides/dts/bindings.html +[drivers]: https://docs.zephyrproject.org/latest/reference/drivers/index.html +[sdk-nrf]: https://github.com/nrfconnect/sdk-nrf +[west_ext]: https://docs.zephyrproject.org/latest/develop/west/extensions.html + +## Getting started + +Before getting started, make sure you have a proper nRF Connect SDK development environment. +Follow the official +[Installation guide](https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrf/getting_started.html). + +### Initialization + +The first step is to initialize the workspace folder (``my-workspace``) where +the ``example-application`` and all nRF Connect SDK modules will be cloned. Run the following +command: + +```shell +# initialize my-workspace for the ncs-example-application (main branch) +west init -m https://github.com/nrfconnect/ncs-example-application --mr main my-workspace +# update nRF Connect SDK modules +cd my-workspace +west update +``` + +### Building and running + +To build the application, run the following command: + +```shell +west build -b $BOARD app +``` + +where `$BOARD` is the target board. + +You can use the `custom_plank` board found in this repository. Note that you can use +Zephyr and nRF Connect SDK sample boards if an appropriate overlay is provided (see `app/boards`). + +A sample debug configuration is also provided. To apply it, run the following +command: + +```shell +west build -b $BOARD app -- -DOVERLAY_CONFIG=debug.conf +``` + +Once you have built the application, run the following command to flash it: + +```shell +west flash +``` diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt new file mode 100644 index 0000000..a59bf06 --- /dev/null +++ b/app/CMakeLists.txt @@ -0,0 +1,12 @@ +#------------------------------------------------------------------------------- +# Zephyr Example Application +# +# Copyright (c) 2021 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.13.1) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) + +project(app LANGUAGES C) + +target_sources(app PRIVATE src/main.c) diff --git a/app/Kconfig b/app/Kconfig new file mode 100644 index 0000000..140eaaf --- /dev/null +++ b/app/Kconfig @@ -0,0 +1,15 @@ +# Copyright (c) 2021 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 +# +# This file is the application Kconfig entry point. All application Kconfig +# options can be defined here or included via other application Kconfig files. +# You can browse these options using the west targets menuconfig (terminal) or +# guiconfig (GUI). + +menu "Zephyr" +source "Kconfig.zephyr" +endmenu + +module = APP +module-str = APP +source "subsys/logging/Kconfig.template.log_config" diff --git a/app/VERSION b/app/VERSION new file mode 100644 index 0000000..16a1373 --- /dev/null +++ b/app/VERSION @@ -0,0 +1,5 @@ +VERSION_MAJOR = 1 +VERSION_MINOR = 0 +PATCHLEVEL = 0 +VERSION_TWEAK = 0 +EXTRAVERSION = diff --git a/app/debug.conf b/app/debug.conf new file mode 100644 index 0000000..885971f --- /dev/null +++ b/app/debug.conf @@ -0,0 +1,19 @@ +# Copyright (c) 2021 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 +# +# This is a Kconfig fragment which can be used to enable debug-related options +# in the application. See the README for more details. + +# compiler +CONFIG_DEBUG_OPTIMIZATIONS=y + +# console +CONFIG_CONSOLE=y + +# UART console +CONFIG_SERIAL=y +CONFIG_UART_CONSOLE=y + +# logging +CONFIG_LOG=y +CONFIG_APP_LOG_LEVEL_DBG=y diff --git a/app/prj.conf b/app/prj.conf new file mode 100644 index 0000000..e7a3bfa --- /dev/null +++ b/app/prj.conf @@ -0,0 +1,6 @@ +# Copyright (c) 2021 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 +# +# This file contains selected Kconfig options for the application. + +CONFIG_SENSOR=y diff --git a/app/sample.yaml b/app/sample.yaml new file mode 100644 index 0000000..e1b6126 --- /dev/null +++ b/app/sample.yaml @@ -0,0 +1,15 @@ +# This file is provided so that the application can be compiled using Twister, +# the Zephyr testing tool. In this file, multiple combinations can be specified, +# so that you can easily test all of them locally or in CI. +sample: + description: Example application + name: example-application +common: + build_only: true + integration_platforms: + - custom_plank +tests: + app.default: {} + app.debug: + extra_overlay_confs: + - debug.conf diff --git a/app/src/main.c b/app/src/main.c new file mode 100644 index 0000000..0bf9b67 --- /dev/null +++ b/app/src/main.c @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include +LOG_MODULE_REGISTER(main, CONFIG_APP_LOG_LEVEL); + +int main(void) +{ + int ret; + const struct device *sensor; + + printk("Zephyr Example Application %s\n", APP_VERSION_STRING); + + sensor = DEVICE_DT_GET(DT_NODELABEL(examplesensor0)); + if (!device_is_ready(sensor)) { + LOG_ERR("Sensor not ready"); + return 0; + } + + while (1) { + struct sensor_value val; + + ret = sensor_sample_fetch(sensor); + if (ret < 0) { + LOG_ERR("Could not fetch sample (%d)", ret); + return 0; + } + + ret = sensor_channel_get(sensor, SENSOR_CHAN_PROX, &val); + if (ret < 0) { + LOG_ERR("Could not get sample (%d)", ret); + return 0; + } + + printk("Sensor value: %d\n", val.val1); + + k_sleep(K_MSEC(1000)); + } + + return 0; +} + diff --git a/boards/arm/custom_plank/Kconfig b/boards/arm/custom_plank/Kconfig new file mode 100644 index 0000000..8cd0b55 --- /dev/null +++ b/boards/arm/custom_plank/Kconfig @@ -0,0 +1,8 @@ +# Copyright (c) 2021 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_ENABLE_DCDC + bool "Enable DCDC mode" + select SOC_DCDC_NRF52X + default y + depends on BOARD_CUSTOM_PLANK diff --git a/boards/arm/custom_plank/Kconfig.board b/boards/arm/custom_plank/Kconfig.board new file mode 100644 index 0000000..51cdc50 --- /dev/null +++ b/boards/arm/custom_plank/Kconfig.board @@ -0,0 +1,6 @@ +# Copyright (c) 2021 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_CUSTOM_PLANK + bool "Custom Plank Board" + depends on SOC_NRF52840_QIAA diff --git a/boards/arm/custom_plank/Kconfig.defconfig b/boards/arm/custom_plank/Kconfig.defconfig new file mode 100644 index 0000000..114f0ee --- /dev/null +++ b/boards/arm/custom_plank/Kconfig.defconfig @@ -0,0 +1,9 @@ +# Copyright (c) 2021 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_CUSTOM_PLANK + +config BOARD + default "custom_plank" + +endif # BOARD_CUSTOM_PLANK diff --git a/boards/arm/custom_plank/README.md b/boards/arm/custom_plank/README.md new file mode 100644 index 0000000..f4b868b --- /dev/null +++ b/boards/arm/custom_plank/README.md @@ -0,0 +1,6 @@ +# Custom Plank Board + +`custom_plank` board is used to demonstrate how to create custom boards. It is +in fact a simplified version of the nRF52840-DK board, so the +`example-application` can be run on that development kit when using +`custom_plank`. diff --git a/boards/arm/custom_plank/board.cmake b/boards/arm/custom_plank/board.cmake new file mode 100644 index 0000000..5c6b531 --- /dev/null +++ b/boards/arm/custom_plank/board.cmake @@ -0,0 +1,12 @@ +# Copyright (c) 2021 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=nrf52" "--speed=4000") +board_runner_args(pyocd "--target=nrf52840" "--frequency=4000000") + +set(OPENOCD_NRF5_SUBFAMILY "nrf52") + +include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/openocd-nrf5.board.cmake) diff --git a/boards/arm/custom_plank/custom_plank-pinctrl.dtsi b/boards/arm/custom_plank/custom_plank-pinctrl.dtsi new file mode 100644 index 0000000..4da31cb --- /dev/null +++ b/boards/arm/custom_plank/custom_plank-pinctrl.dtsi @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + uart0_default: uart0_default { + group1 { + psels = , + , + , + ; + }; + }; + + uart0_sleep: uart0_sleep { + group1 { + psels = , + , + , + ; + low-power-enable; + }; + }; + +}; diff --git a/boards/arm/custom_plank/custom_plank.dts b/boards/arm/custom_plank/custom_plank.dts new file mode 100644 index 0000000..dee804d --- /dev/null +++ b/boards/arm/custom_plank/custom_plank.dts @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include +#include "custom_plank-pinctrl.dtsi" + +/ { + model = "Custom Plank Board"; + compatible = "vendor,custom-plank"; + + chosen { + zephyr,console = &uart0; + zephyr,sram = &sram0; + zephyr,flash = &flash0; + }; + + examplesensor0: examplesensor_0 { + compatible = "zephyr,examplesensor"; + input-gpios = <&gpio0 11 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + }; +}; + +&gpio0 { + status = "okay"; +}; + +&uart0 { + compatible = "nordic,nrf-uarte"; + status = "okay"; + + current-speed = <115200>; + pinctrl-0 = <&uart0_default>; + pinctrl-1 = <&uart0_sleep>; + pinctrl-names = "default", "sleep"; +}; diff --git a/boards/arm/custom_plank/custom_plank.yaml b/boards/arm/custom_plank/custom_plank.yaml new file mode 100644 index 0000000..071ba3d --- /dev/null +++ b/boards/arm/custom_plank/custom_plank.yaml @@ -0,0 +1,15 @@ +# Copyright (c) 2021 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +identifier: custom_plank +name: Custom-Plank +type: mcu +arch: arm +ram: 256 +flash: 1024 +toolchain: + - zephyr + - gnuarmemb + - xtools +supported: + - gpio diff --git a/boards/arm/custom_plank/custom_plank_defconfig b/boards/arm/custom_plank/custom_plank_defconfig new file mode 100644 index 0000000..4a5558a --- /dev/null +++ b/boards/arm/custom_plank/custom_plank_defconfig @@ -0,0 +1,14 @@ +# Copyright (c) 2021 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_SERIES_NRF52X=y +CONFIG_SOC_NRF52840_QIAA=y +CONFIG_BOARD_CUSTOM_PLANK=y + +CONFIG_ARM_MPU=y +CONFIG_HW_STACK_PROTECTION=y + +CONFIG_GPIO=y +CONFIG_GPIO_AS_PINRESET=y + +CONFIG_PINCTRL=y diff --git a/drivers/CMakeLists.txt b/drivers/CMakeLists.txt new file mode 100644 index 0000000..183462e --- /dev/null +++ b/drivers/CMakeLists.txt @@ -0,0 +1,4 @@ +# Copyright (c) 2021 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +add_subdirectory_ifdef(CONFIG_SENSOR sensor) diff --git a/drivers/Kconfig b/drivers/Kconfig new file mode 100644 index 0000000..550329c --- /dev/null +++ b/drivers/Kconfig @@ -0,0 +1,6 @@ +# Copyright (c) 2021 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +menu "Drivers" +rsource "sensor/Kconfig" +endmenu diff --git a/drivers/sensor/CMakeLists.txt b/drivers/sensor/CMakeLists.txt new file mode 100644 index 0000000..fbb6b45 --- /dev/null +++ b/drivers/sensor/CMakeLists.txt @@ -0,0 +1,4 @@ +# Copyright (c) 2021 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +add_subdirectory_ifdef(CONFIG_EXAMPLESENSOR examplesensor) diff --git a/drivers/sensor/Kconfig b/drivers/sensor/Kconfig new file mode 100644 index 0000000..23c1966 --- /dev/null +++ b/drivers/sensor/Kconfig @@ -0,0 +1,6 @@ +# Copyright (c) 2021 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if SENSOR +rsource "examplesensor/Kconfig" +endif # SENSOR diff --git a/drivers/sensor/examplesensor/CMakeLists.txt b/drivers/sensor/examplesensor/CMakeLists.txt new file mode 100644 index 0000000..ff3266e --- /dev/null +++ b/drivers/sensor/examplesensor/CMakeLists.txt @@ -0,0 +1,5 @@ +# Copyright (c) 2021 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() +zephyr_library_sources(examplesensor.c) diff --git a/drivers/sensor/examplesensor/Kconfig b/drivers/sensor/examplesensor/Kconfig new file mode 100644 index 0000000..a8ab99a --- /dev/null +++ b/drivers/sensor/examplesensor/Kconfig @@ -0,0 +1,10 @@ +# Copyright (c) 2021 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config EXAMPLESENSOR + bool "Example sensor" + default y + depends on DT_HAS_ZEPHYR_EXAMPLESENSOR_ENABLED + select GPIO + help + Enable example sensor diff --git a/drivers/sensor/examplesensor/examplesensor.c b/drivers/sensor/examplesensor/examplesensor.c new file mode 100644 index 0000000..0e35e20 --- /dev/null +++ b/drivers/sensor/examplesensor/examplesensor.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT zephyr_examplesensor + +#include +#include +#include + +#include +LOG_MODULE_REGISTER(examplesensor, CONFIG_SENSOR_LOG_LEVEL); + +struct examplesensor_data { + int state; +}; + +struct examplesensor_config { + struct gpio_dt_spec input; +}; + +static int examplesensor_sample_fetch(const struct device *dev, + enum sensor_channel chan) +{ + const struct examplesensor_config *config = dev->config; + struct examplesensor_data *data = dev->data; + + data->state = gpio_pin_get_dt(&config->input); + + return 0; +} + +static int examplesensor_channel_get(const struct device *dev, + enum sensor_channel chan, + struct sensor_value *val) +{ + struct examplesensor_data *data = dev->data; + + if (chan != SENSOR_CHAN_PROX) { + return -ENOTSUP; + } + + val->val1 = data->state; + + return 0; +} + +static const struct sensor_driver_api examplesensor_api = { + .sample_fetch = &examplesensor_sample_fetch, + .channel_get = &examplesensor_channel_get, +}; + +static int examplesensor_init(const struct device *dev) +{ + const struct examplesensor_config *config = dev->config; + + int ret; + + if (!device_is_ready(config->input.port)) { + LOG_ERR("Input GPIO not ready"); + return -ENODEV; + } + + ret = gpio_pin_configure_dt(&config->input, GPIO_INPUT); + if (ret < 0) { + LOG_ERR("Could not configure input GPIO (%d)", ret); + return ret; + } + + return 0; +} + +#define EXAMPLESENSOR_INIT(i) \ + static struct examplesensor_data examplesensor_data_##i; \ + \ + static const struct examplesensor_config examplesensor_config_##i = { \ + .input = GPIO_DT_SPEC_INST_GET(i, input_gpios), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(i, examplesensor_init, NULL, \ + &examplesensor_data_##i, \ + &examplesensor_config_##i, POST_KERNEL, \ + CONFIG_SENSOR_INIT_PRIORITY, &examplesensor_api); + +DT_INST_FOREACH_STATUS_OKAY(EXAMPLESENSOR_INIT) diff --git a/dts/bindings/sensor/zephyr,examplesensor.yaml b/dts/bindings/sensor/zephyr,examplesensor.yaml new file mode 100644 index 0000000..41f9d9e --- /dev/null +++ b/dts/bindings/sensor/zephyr,examplesensor.yaml @@ -0,0 +1,23 @@ +# Copyright (c) 2021 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: | + An example sensor that reads the GPIO level defined in input-gpios. The + purpose of this sensor is to demonstrate how to create out-of-tree drivers. + + Example definition in devicetree: + + examplesensor { + compatible = "zephyr,examplesensor"; + input-gpios = <&gpio0 0 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + }; + +compatible: "zephyr,examplesensor" + +include: base.yaml + +properties: + input-gpios: + type: phandle-array + required: true + description: Input GPIO to be sensed. diff --git a/include/custom_lib/custom_lib.h b/include/custom_lib/custom_lib.h new file mode 100644 index 0000000..9d285d0 --- /dev/null +++ b/include/custom_lib/custom_lib.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2021, Legrand North America, LLC. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef EXAMPLE_APPLICATION_INCLUDE_CUSTOM_LIB_CUSTOM_LIB_H_ +#define EXAMPLE_APPLICATION_INCLUDE_CUSTOM_LIB_CUSTOM_LIB_H_ + +/** + * @brief Return parameter if non-zero, or Kconfig-controlled default + * + * Function returns the provided value if non-zero, or a Kconfig-controlled + * default value if the parameter is zero. This trivial function is + * provided in order to have a library interface example that is trivial + * to test. + * + * @param return_value_if_nonzero Value to return if non-zero + * @returns return_value_if_nonzero when the parameter is non-zero + * @returns CONFIG_CUSTOM_LIB_GET_VALUE_DEFAULT if parameter is zero + */ +int custom_lib_get_value(int return_value_if_nonzero); + +#endif /* EXAMPLE_APPLICATION_INCLUDE_CUSTOM_LIB_CUSTOM_LIB_H_ */ diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt new file mode 100644 index 0000000..d24bef0 --- /dev/null +++ b/lib/CMakeLists.txt @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: Apache-2.0 + +add_subdirectory_ifdef(CONFIG_CUSTOM_LIB custom_lib) diff --git a/lib/Kconfig b/lib/Kconfig new file mode 100644 index 0000000..5fd3678 --- /dev/null +++ b/lib/Kconfig @@ -0,0 +1,8 @@ +# Copyright (c) 2021 Legrand North America, LLC. +# SPDX-License-Identifier: Apache-2.0 + +menu "Libraries" + +rsource "custom_lib/Kconfig" + +endmenu diff --git a/lib/custom_lib/CMakeLists.txt b/lib/custom_lib/CMakeLists.txt new file mode 100644 index 0000000..d683936 --- /dev/null +++ b/lib/custom_lib/CMakeLists.txt @@ -0,0 +1,5 @@ +# Copyright (c) 2021, Legrand North America, LLC. +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() +zephyr_library_sources(custom_lib.c) diff --git a/lib/custom_lib/Kconfig b/lib/custom_lib/Kconfig new file mode 100644 index 0000000..14cc9eb --- /dev/null +++ b/lib/custom_lib/Kconfig @@ -0,0 +1,19 @@ +# Copyright (c) 2021, Legrand North America, LLC. +# SPDX-License-Identifier: Apache-2.0 + +config CUSTOM_LIB + bool "custom_lib Support" + help + This option enables the custom_lib library + +config CUSTOM_LIB_GET_VALUE_DEFAULT + int "custom_lib_get_value() default return value" + depends on CUSTOM_LIB + default 0 + help + This option primarily exists as an example of a library Kconfig + setting. + + This option specifies the value for custom_lib_get_value() + to return when the input parameter is zero. (Otherwise + the function returns the input parameter value.) diff --git a/lib/custom_lib/custom_lib.c b/lib/custom_lib/custom_lib.c new file mode 100644 index 0000000..6711cc4 --- /dev/null +++ b/lib/custom_lib/custom_lib.c @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2021, Legrand North America, LLC. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +int custom_lib_get_value(int return_value_if_nonzero) +{ + return (return_value_if_nonzero != 0) ? return_value_if_nonzero + : CONFIG_CUSTOM_LIB_GET_VALUE_DEFAULT; +} diff --git a/scripts/example_west_command.py b/scripts/example_west_command.py new file mode 100644 index 0000000..7f68d7f --- /dev/null +++ b/scripts/example_west_command.py @@ -0,0 +1,49 @@ +# Copyright (c) 2019 Foundries.io +# Copyright (c) 2022 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +'''example_west_command.py + +Example of a west extension in the example-application repository.''' + +from west.commands import WestCommand # your extension must subclass this +from west import log # use this for user output + +class ExampleWestCommand(WestCommand): + + def __init__(self): + super().__init__( + 'example-west-command', # gets stored as self.name + 'an example west extension command', # self.help + # self.description: + '''\ +A multi-line description of example-west-command. + +You can split this up into multiple paragraphs and they'll get +reflowed for you. You can also pass +formatter_class=argparse.RawDescriptionHelpFormatter when calling +parser_adder.add_parser() below if you want to keep your line +endings.''') + + def do_add_parser(self, parser_adder): + # This is a bit of boilerplate, which allows you full control over the + # type of argparse handling you want. The "parser_adder" argument is + # the return value of an argparse.ArgumentParser.add_subparsers() call. + parser = parser_adder.add_parser(self.name, + help=self.help, + description=self.description) + + # Add some example options using the standard argparse module API. + parser.add_argument('-o', '--optional', help='an optional argument') + parser.add_argument('required', help='a required argument') + + return parser # gets stored as self.parser + + def do_run(self, args, unknown_args): + # This gets called when the user runs the command, e.g.: + # + # $ west my-command-name -o FOO BAR + # --optional is FOO + # required is BAR + log.inf('--optional is', args.optional) + log.inf('required is', args.required) diff --git a/scripts/west-commands.yml b/scripts/west-commands.yml new file mode 100644 index 0000000..e32692a --- /dev/null +++ b/scripts/west-commands.yml @@ -0,0 +1,6 @@ +west-commands: + - file: scripts/example_west_command.py + commands: + - name: example-west-command + class: ExampleWestCommand + help: an example west extension command diff --git a/tests/lib/custom_lib/CMakeLists.txt b/tests/lib/custom_lib/CMakeLists.txt new file mode 100644 index 0000000..0541490 --- /dev/null +++ b/tests/lib/custom_lib/CMakeLists.txt @@ -0,0 +1,9 @@ +# Copyright (c) 2021, Legrand North America, LLC. +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(custom_lib) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/lib/custom_lib/prj.conf b/tests/lib/custom_lib/prj.conf new file mode 100644 index 0000000..b0d275a --- /dev/null +++ b/tests/lib/custom_lib/prj.conf @@ -0,0 +1,3 @@ +CONFIG_ZTEST=y +CONFIG_ZTEST_NEW_API=y +CONFIG_CUSTOM_LIB=y diff --git a/tests/lib/custom_lib/src/main.c b/tests/lib/custom_lib/src/main.c new file mode 100644 index 0000000..e3a4695 --- /dev/null +++ b/tests/lib/custom_lib/src/main.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2021 Legrand North America, LLC. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * @file test custom_lib library + * + * This suite verifies that the methods provided with the custom_lib + * library works correctly. + */ + +#include + +#include + +#include + +ZTEST(custom_lib, test_get_value) +{ + /* Verify standard behavior */ + zassert_equal(custom_lib_get_value(INT_MIN), INT_MIN, + "get_value failed input of INT_MIN"); + zassert_equal(custom_lib_get_value(INT_MIN + 1), INT_MIN + 1, + "get_value failed input of INT_MIN + 1"); + zassert_equal(custom_lib_get_value(-1), -1, + "get_value failed input of -1"); + zassert_equal(custom_lib_get_value(1), 1, + "get_value failed input of 1"); + zassert_equal(custom_lib_get_value(INT_MAX - 1), INT_MAX - 1, + "get_value failed input of INT_MAX - 1"); + zassert_equal(custom_lib_get_value(INT_MAX), INT_MAX, + "get_value failed input of INT_MAX"); + + /* Verify override behavior */ + zassert_equal(custom_lib_get_value(0), + CONFIG_CUSTOM_LIB_GET_VALUE_DEFAULT, + "get_value failed input of 0"); +} + +ZTEST_SUITE(custom_lib, NULL, NULL, NULL, NULL, NULL); diff --git a/tests/lib/custom_lib/testcase.yaml b/tests/lib/custom_lib/testcase.yaml new file mode 100644 index 0000000..9055f67 --- /dev/null +++ b/tests/lib/custom_lib/testcase.yaml @@ -0,0 +1,9 @@ +common: + tags: extensibility + integration_platforms: + - custom_plank + - qemu_cortex_m0 +tests: + lib.custom_lib: {} + lib.custom_lib.non_default: + extra_args: CONFIG_CUSTOM_LIB_GET_VALUE_DEFAULT=6 diff --git a/west.yml b/west.yml new file mode 100644 index 0000000..18b85f9 --- /dev/null +++ b/west.yml @@ -0,0 +1,17 @@ +# Copyright (c) 2021 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +manifest: + self: + west-commands: scripts/west-commands.yml + + remotes: + - name: ncs + url-base: https://github.com/nrfconnect + + projects: + - name: nrf + remote: ncs + repo-path: sdk-nrf + revision: main + import: true diff --git a/zephyr/module.yml b/zephyr/module.yml new file mode 100644 index 0000000..047032a --- /dev/null +++ b/zephyr/module.yml @@ -0,0 +1,20 @@ +# Copyright (c) 2021 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +build: + # Path to the Kconfig file that will be sourced into Zephyr Kconfig tree under + # Zephyr > Modules > example-application. Path is relative from root of this + # repository. + kconfig: Kconfig + # Path to the folder that contains the CMakeLists.txt file to be included by + # Zephyr build system. The `.` is the root of this repository. + cmake: . + settings: + # Additional roots for boards and DTS files. Zephyr will use the + # `/boards` for additional boards. The `.` is the root of this + # repository. + board_root: . + # Zephyr will use the `/dts` for additional dts files and + # `/dts/bindings` for additional dts binding files. The `.` is + # the root of this repository. + dts_root: .