├── .gitignore ├── samples ├── attach_interrupt │ ├── prj.conf │ ├── CMakeLists.txt │ ├── src │ │ └── main.cpp │ └── README.rst ├── hello_arduino │ ├── prj.conf │ ├── CMakeLists.txt │ ├── README.rst │ └── src │ │ └── app.cpp ├── serial_event │ ├── prj.conf │ ├── src │ │ └── app.cpp │ ├── README.rst │ └── CMakeLists.txt ├── fade │ ├── prj.conf │ ├── CMakeLists.txt │ ├── README.rst │ └── src │ │ └── app.cpp ├── analog_input │ ├── prj.conf │ ├── CMakeLists.txt │ ├── README.rst │ └── src │ │ └── main.cpp ├── blinky_arduino │ ├── prj.conf │ ├── src │ │ └── main.cpp │ ├── CMakeLists.txt │ └── README.rst ├── button_press_led │ ├── prj.conf │ ├── CMakeLists.txt │ ├── src │ │ └── main.cpp │ └── README.rst ├── threads_arduino │ ├── prj.conf │ ├── CMakeLists.txt │ ├── src │ │ └── main.cpp │ └── README.rst ├── i2cdemo │ ├── prj.conf │ ├── CMakeLists.txt │ ├── README.rst │ └── src │ │ └── main.cpp └── spi_controller │ ├── prj.conf │ ├── README.rst │ ├── CMakeLists.txt │ └── src │ └── app.cpp ├── cores ├── CMakeLists.txt └── arduino │ ├── main.cpp │ ├── zephyrInternal.h │ ├── CMakeLists.txt │ ├── apiCommon.cpp │ ├── zephyrPrint.cpp │ ├── zephyrSerial.h │ ├── Arduino.h │ ├── zephyrPrint.h │ ├── zephyrSerial.cpp │ └── zephyrCommon.cpp ├── zephyr └── module.yml ├── libraries ├── CMakeLists.txt ├── Wire │ ├── CMakeLists.txt │ ├── Wire.h │ └── Wire.cpp └── SPI │ ├── CMakeLists.txt │ ├── SPI.h │ └── SPI.cpp ├── variants ├── nrf52840dk_nrf52840 │ ├── variant.h │ └── nrf52840dk_nrf52840.overlay ├── rpi_pico_rp2040 │ ├── variant.h │ └── rpi_pico_rp2040.overlay ├── arduino_mkrzero_samd21g18a │ ├── variant.h │ └── arduino_mkrzero_samd21g18a.overlay ├── arduino_nano_33_ble_nrf52840 │ ├── variant.h │ └── arduino_nano_33_ble_nrf52840.overlay ├── arduino_nano_33_iot_samd21g18a │ ├── variant.h │ └── arduino_nano_33_iot_samd21g18a.overlay ├── arduino_nano_33_ble_nrf52840_sense │ ├── variant.h │ └── arduino_nano_33_ble_nrf52840_sense.overlay ├── pocketbeagle_2_am6254_a53 │ ├── variant.h │ └── pocketbeagle_2_am6254_a53.overlay ├── beagleconnect_freedom_cc1352p7 │ ├── variant.h │ └── beagleconnect_freedom_cc1352p7.overlay ├── cc3220sf_launchxl_cc3220sf │ ├── variant.h │ └── cc3220sf_launchxl_cc3220sf.overlay └── nrf9160dk_nrf9160 │ ├── variant.h │ └── nrf9160dk_nrf9160.overlay ├── rust ├── Cargo.toml └── src │ ├── lib.rs │ └── common.rs ├── CODEOWNERS ├── .checkpatch.conf ├── .github ├── license_config.yml └── workflows │ ├── license_check.yml │ ├── checkpatch.yml │ └── build.yml ├── Kconfig ├── west.yml ├── install.sh ├── documentation ├── arduino_libs.md └── variants.md ├── README.md ├── CMakeLists.txt ├── CODE_OF_CONDUCT.md └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | rust/Cargo.lock 2 | -------------------------------------------------------------------------------- /samples/attach_interrupt/prj.conf: -------------------------------------------------------------------------------- 1 | CONFIG_ARDUINO_API=y 2 | -------------------------------------------------------------------------------- /samples/hello_arduino/prj.conf: -------------------------------------------------------------------------------- 1 | CONFIG_ARDUINO_API=y 2 | -------------------------------------------------------------------------------- /samples/serial_event/prj.conf: -------------------------------------------------------------------------------- 1 | CONFIG_ARDUINO_API=y 2 | -------------------------------------------------------------------------------- /samples/fade/prj.conf: -------------------------------------------------------------------------------- 1 | CONFIG_ARDUINO_API=y 2 | CONFIG_PWM=y 3 | -------------------------------------------------------------------------------- /samples/analog_input/prj.conf: -------------------------------------------------------------------------------- 1 | CONFIG_ADC=y 2 | CONFIG_ARDUINO_API=y 3 | -------------------------------------------------------------------------------- /samples/blinky_arduino/prj.conf: -------------------------------------------------------------------------------- 1 | CONFIG_GPIO=y 2 | CONFIG_ARDUINO_API=y 3 | -------------------------------------------------------------------------------- /samples/button_press_led/prj.conf: -------------------------------------------------------------------------------- 1 | CONFIG_GPIO=y 2 | CONFIG_ARDUINO_API=y 3 | -------------------------------------------------------------------------------- /cores/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | 3 | add_subdirectory(arduino) -------------------------------------------------------------------------------- /samples/threads_arduino/prj.conf: -------------------------------------------------------------------------------- 1 | CONFIG_HEAP_MEM_POOL_SIZE=256 2 | CONFIG_GPIO=y 3 | CONFIG_ARDUINO_API=y 4 | -------------------------------------------------------------------------------- /zephyr/module.yml: -------------------------------------------------------------------------------- 1 | name: arduino-api 2 | 3 | build: 4 | cmake: . 5 | kconfig: Kconfig 6 | samples: 7 | - samples 8 | -------------------------------------------------------------------------------- /libraries/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | 3 | add_subdirectory(Wire) 4 | add_subdirectory(SPI) 5 | -------------------------------------------------------------------------------- /variants/nrf52840dk_nrf52840/variant.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Mike Szczys 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | -------------------------------------------------------------------------------- /variants/rpi_pico_rp2040/variant.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024 TOKITA Hiroshi 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | -------------------------------------------------------------------------------- /variants/arduino_mkrzero_samd21g18a/variant.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Dhruva Gole 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | -------------------------------------------------------------------------------- /variants/arduino_nano_33_ble_nrf52840/variant.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Dhruva Gole 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | -------------------------------------------------------------------------------- /variants/arduino_nano_33_iot_samd21g18a/variant.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Dhruva Gole 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | -------------------------------------------------------------------------------- /variants/arduino_nano_33_ble_nrf52840_sense/variant.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Dhruva Gole 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | -------------------------------------------------------------------------------- /samples/i2cdemo/prj.conf: -------------------------------------------------------------------------------- 1 | CONFIG_GPIO=y 2 | CONFIG_ARDUINO_API=y 3 | CONFIG_I2C=y 4 | CONFIG_NEWLIB_LIBC=y 5 | CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y 6 | CONFIG_RING_BUFFER=y 7 | -------------------------------------------------------------------------------- /samples/spi_controller/prj.conf: -------------------------------------------------------------------------------- 1 | CONFIG_CPLUSPLUS=y 2 | CONFIG_ARDUINO_API=y 3 | CONFIG_SPI=y 4 | CONFIG_LOG=y 5 | CONFIG_LOG_OUTPUT=y 6 | CONFIG_LOG_MODE_IMMEDIATE=y 7 | -------------------------------------------------------------------------------- /rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "arduinocore_api_rust" 3 | version = "0.1.0" 4 | edition = "2024" 5 | license = "Apache-2.0" 6 | 7 | [lib] 8 | crate-type = ["staticlib"] 9 | -------------------------------------------------------------------------------- /variants/pocketbeagle_2_am6254_a53/variant.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ayush Singh 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #pragma once 8 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | # CODEOWNERS for autoreview assigning in github 2 | 3 | # https://help.github.com/en/articles/about-code-owners#codeowners-syntax 4 | 5 | /* @DhruvaG2000 @szczys @beriberikix @soburi 6 | -------------------------------------------------------------------------------- /libraries/Wire/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | zephyr_include_directories(.) 3 | 4 | if(NOT DEFINED ARDUINO_BUILD_PATH) 5 | 6 | zephyr_sources(Wire.cpp) 7 | 8 | endif() 9 | -------------------------------------------------------------------------------- /libraries/SPI/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | zephyr_include_directories(.) 3 | 4 | if(NOT DEFINED ARDUINO_BUILD_PATH) 5 | zephyr_sources_ifdef(CONFIG_SPI SPI.cpp) 6 | endif() 7 | -------------------------------------------------------------------------------- /samples/spi_controller/README.rst: -------------------------------------------------------------------------------- 1 | .. _spi_controller: 2 | 3 | SPI Controller 4 | ############### 5 | 6 | Overview 7 | ******** 8 | 9 | A simple sample that sends incrementing byte to SPI peripheral. 10 | -------------------------------------------------------------------------------- /.checkpatch.conf: -------------------------------------------------------------------------------- 1 | # This isn't actually a Linux kernel tree 2 | --no-tree 3 | 4 | --ignore FILE_PATH_CHANGES 5 | --ignore COMPLEX_MACRO 6 | --ignore NEW_TYPEDEFS 7 | --ignore CONST_STRUCT 8 | --ignore SPDX_LICENSE_TAG 9 | -------------------------------------------------------------------------------- /variants/beagleconnect_freedom_cc1352p7/variant.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024 Ayush Singh 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | #pragma once 7 | 8 | #define PIN_WIRE_SCL D12 9 | #define PIN_WIRE_SDA D11 10 | -------------------------------------------------------------------------------- /rust/src/lib.rs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 TOKITA Hiroshi 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | #![no_std] 5 | 6 | mod common; 7 | pub use common::*; 8 | 9 | use core::panic::PanicInfo; 10 | 11 | #[panic_handler] 12 | fn panic(_panic: &PanicInfo<'_>) -> ! { 13 | loop {} 14 | } 15 | -------------------------------------------------------------------------------- /.github/license_config.yml: -------------------------------------------------------------------------------- 1 | license: 2 | main: apache-2.0 3 | report_missing: true 4 | category: Permissive 5 | copyright: 6 | check: true 7 | exclude: 8 | extensions: 9 | - yml 10 | - yaml 11 | - html 12 | - rst 13 | - conf 14 | - cfg 15 | langs: 16 | - HTML 17 | -------------------------------------------------------------------------------- /cores/arduino/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Dhruva Gole 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include "Arduino.h" 8 | 9 | int main(void) { 10 | setup(); 11 | 12 | for (;;) { 13 | loop(); 14 | if (arduino::serialEventRun) arduino::serialEventRun(); 15 | } 16 | 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /variants/cc3220sf_launchxl_cc3220sf/variant.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Dhruva Gole 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /* All the pins that are 100 + x are gpio1 pins and < 100 are in gpio0 */ 8 | #pragma once 9 | 10 | #define LED_BUILTIN 4 11 | #define YELLOW_LED 3 12 | #define GREEN_LED 4 13 | #define RED_LED 19 14 | 15 | -------------------------------------------------------------------------------- /cores/arduino/zephyrInternal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024 Ayush Singh 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | void enableInterrupt(pin_size_t); 16 | void disableInterrupt(pin_size_t); 17 | 18 | #ifdef __cplusplus 19 | } // extern "C" 20 | #endif 21 | -------------------------------------------------------------------------------- /samples/serial_event/src/app.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 TOKITA Hiroshi 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include 8 | 9 | void setup() { 10 | Serial.begin(115200); 11 | } 12 | 13 | void loop() { 14 | } 15 | 16 | void serialEvent() { 17 | while(Serial.available()) { 18 | Serial.print((char)Serial.read()); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /samples/blinky_arduino/src/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | */ 4 | 5 | /* Blink inbuilt LED example */ 6 | 7 | #include 8 | 9 | /* 1000 msec = 1 sec */ 10 | #define SLEEP_TIME_MS 1000 11 | 12 | void setup() { pinMode(LED_BUILTIN, OUTPUT); } 13 | 14 | void loop() { 15 | digitalWrite(LED_BUILTIN, HIGH); 16 | delay(SLEEP_TIME_MS); 17 | digitalWrite(LED_BUILTIN, LOW); 18 | delay(SLEEP_TIME_MS); 19 | } -------------------------------------------------------------------------------- /samples/serial_event/README.rst: -------------------------------------------------------------------------------- 1 | .. _serial_event: 2 | 3 | Serial Event 4 | ############ 5 | 6 | Overview 7 | ******** 8 | 9 | The serial_event sample echo back serial input data. 10 | 11 | Building and Running 12 | ******************** 13 | 14 | Build and flash serial_event sample as follows, 15 | 16 | ```sh 17 | $> west build -p -b arduino_nano_33_ble sample/serial_event/ 18 | 19 | $> west flash --bossac=/home/$USER/.arduino15/packages/arduino/tools/bossac/1.9.1-arduino2/bossac 20 | ``` 21 | -------------------------------------------------------------------------------- /samples/fade/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | 3 | cmake_minimum_required(VERSION 3.20.0) 4 | 5 | # get value of NORMALIZED_BOARD_TARGET early 6 | find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE} COMPONENTS yaml boards) 7 | 8 | set(DTC_OVERLAY_FILE ${CMAKE_CURRENT_LIST_DIR}/../../variants/${NORMALIZED_BOARD_TARGET}/${NORMALIZED_BOARD_TARGET}.overlay) 9 | 10 | find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) 11 | project(fade) 12 | 13 | target_sources(app PRIVATE src/app.cpp) 14 | 15 | zephyr_compile_options(-Wno-unused-variable -Wno-comment) 16 | -------------------------------------------------------------------------------- /samples/i2cdemo/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | 3 | cmake_minimum_required(VERSION 3.20.0) 4 | 5 | # get value of NORMALIZED_BOARD_TARGET early 6 | find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE} COMPONENTS yaml boards) 7 | 8 | set(DTC_OVERLAY_FILE ${CMAKE_CURRENT_LIST_DIR}/../../variants/${NORMALIZED_BOARD_TARGET}/${NORMALIZED_BOARD_TARGET}.overlay) 9 | 10 | find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) 11 | project(i2cdemo) 12 | 13 | target_sources(app PRIVATE src/main.cpp) 14 | 15 | zephyr_compile_options(-Wno-unused-variable -Wno-comment) 16 | -------------------------------------------------------------------------------- /samples/analog_input/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | 3 | cmake_minimum_required(VERSION 3.20.0) 4 | 5 | # get value of NORMALIZED_BOARD_TARGET early 6 | find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE} COMPONENTS yaml boards) 7 | 8 | set(DTC_OVERLAY_FILE ${CMAKE_CURRENT_LIST_DIR}/../../variants/${NORMALIZED_BOARD_TARGET}/${NORMALIZED_BOARD_TARGET}.overlay) 9 | 10 | find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) 11 | project(analog_input) 12 | 13 | target_sources(app PRIVATE src/main.cpp) 14 | zephyr_compile_options(-Wno-unused-variable -Wno-comment) 15 | -------------------------------------------------------------------------------- /samples/blinky_arduino/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | 3 | cmake_minimum_required(VERSION 3.20.0) 4 | 5 | # get value of NORMALIZED_BOARD_TARGET early 6 | find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE} COMPONENTS yaml boards) 7 | 8 | set(DTC_OVERLAY_FILE ${CMAKE_CURRENT_LIST_DIR}/../../variants/${NORMALIZED_BOARD_TARGET}/${NORMALIZED_BOARD_TARGET}.overlay) 9 | 10 | find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) 11 | project(blinky) 12 | 13 | target_sources(app PRIVATE src/main.cpp) 14 | 15 | zephyr_compile_options(-Wno-unused-variable -Wno-comment) 16 | -------------------------------------------------------------------------------- /samples/hello_arduino/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | 3 | cmake_minimum_required(VERSION 3.20.0) 4 | 5 | # get value of NORMALIZED_BOARD_TARGET early 6 | find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE} COMPONENTS yaml boards) 7 | 8 | set(DTC_OVERLAY_FILE ${CMAKE_CURRENT_LIST_DIR}/../../variants/${NORMALIZED_BOARD_TARGET}/${NORMALIZED_BOARD_TARGET}.overlay) 9 | 10 | find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) 11 | project(hello_world) 12 | 13 | target_sources(app PRIVATE src/app.cpp) 14 | 15 | zephyr_compile_options(-Wno-unused-variable -Wno-comment) 16 | -------------------------------------------------------------------------------- /samples/serial_event/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | 3 | cmake_minimum_required(VERSION 3.20.0) 4 | 5 | # get value of NORMALIZED_BOARD_TARGET early 6 | find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE} COMPONENTS yaml boards) 7 | 8 | set(DTC_OVERLAY_FILE ${CMAKE_CURRENT_LIST_DIR}/../../variants/${NORMALIZED_BOARD_TARGET}/${NORMALIZED_BOARD_TARGET}.overlay) 9 | 10 | find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) 11 | project(serial_event) 12 | 13 | target_sources(app PRIVATE src/app.cpp) 14 | 15 | zephyr_compile_options(-Wno-unused-variable -Wno-comment) 16 | -------------------------------------------------------------------------------- /samples/threads_arduino/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | 3 | cmake_minimum_required(VERSION 3.20.0) 4 | 5 | # get value of NORMALIZED_BOARD_TARGET early 6 | find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE} COMPONENTS yaml boards) 7 | 8 | set(DTC_OVERLAY_FILE ${CMAKE_CURRENT_LIST_DIR}/../../variants/${NORMALIZED_BOARD_TARGET}/${NORMALIZED_BOARD_TARGET}.overlay) 9 | 10 | find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) 11 | project(threads) 12 | 13 | target_sources(app PRIVATE src/main.cpp) 14 | 15 | zephyr_compile_options(-Wno-unused-variable -Wno-comment) 16 | -------------------------------------------------------------------------------- /samples/spi_controller/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | 3 | cmake_minimum_required(VERSION 3.20.0) 4 | 5 | # get value of NORMALIZED_BOARD_TARGET early 6 | find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE} COMPONENTS yaml boards) 7 | 8 | set(DTC_OVERLAY_FILE ${CMAKE_CURRENT_LIST_DIR}/../../variants/${NORMALIZED_BOARD_TARGET}/${NORMALIZED_BOARD_TARGET}.overlay) 9 | 10 | find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) 11 | project(spi_controller) 12 | 13 | target_sources(app PRIVATE src/app.cpp) 14 | 15 | zephyr_compile_options(-Wno-unused-variable -Wno-comment) 16 | -------------------------------------------------------------------------------- /samples/attach_interrupt/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | 3 | cmake_minimum_required(VERSION 3.20.0) 4 | 5 | # get value of NORMALIZED_BOARD_TARGET early 6 | find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE} COMPONENTS yaml boards) 7 | 8 | set(DTC_OVERLAY_FILE ${CMAKE_CURRENT_LIST_DIR}/../../variants/${NORMALIZED_BOARD_TARGET}/${NORMALIZED_BOARD_TARGET}.overlay) 9 | 10 | find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) 11 | project(attach_interrupt) 12 | 13 | target_sources(app PRIVATE src/main.cpp) 14 | 15 | zephyr_compile_options(-Wno-unused-variable -Wno-comment) 16 | -------------------------------------------------------------------------------- /samples/button_press_led/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | 3 | cmake_minimum_required(VERSION 3.20.0) 4 | 5 | # get value of NORMALIZED_BOARD_TARGET early 6 | find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE} COMPONENTS yaml boards) 7 | 8 | set(DTC_OVERLAY_FILE ${CMAKE_CURRENT_LIST_DIR}/../../variants/${NORMALIZED_BOARD_TARGET}/${NORMALIZED_BOARD_TARGET}.overlay) 9 | 10 | find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) 11 | project(button_press_led) 12 | 13 | target_sources(app PRIVATE src/main.cpp) 14 | 15 | zephyr_compile_options(-Wno-unused-variable -Wno-comment) 16 | -------------------------------------------------------------------------------- /samples/attach_interrupt/src/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 TOKITA Hiroshi 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include 8 | 9 | const pin_size_t ledPin = LED_BUILTIN; 10 | const pin_size_t interruptPin = 2; 11 | PinStatus state = LOW; 12 | 13 | void blink() { 14 | state = (state == LOW) ? HIGH : LOW; 15 | digitalWrite(ledPin, state); 16 | } 17 | 18 | void setup() { 19 | pinMode(ledPin, OUTPUT); 20 | pinMode(interruptPin, INPUT_PULLUP); 21 | attachInterrupt(interruptPin, blink, CHANGE); 22 | } 23 | 24 | void loop() { 25 | } 26 | -------------------------------------------------------------------------------- /samples/fade/README.rst: -------------------------------------------------------------------------------- 1 | .. _fade: 2 | 3 | Fade 4 | #### 5 | 6 | Overview 7 | ******** 8 | 9 | The Fade sample gradually increases/decreases the voltage of the output pin. 10 | When connecting the LED to the output pin, the LED blinks gradually. 11 | 12 | Building and Running 13 | ******************** 14 | 15 | Build and flash Fade sample as follows, 16 | 17 | ```sh 18 | $> west build -p -b arduino_nano_33_ble samples/basic/fade/ -DZEPHYR_EXTRA_MODULES=/home/$USER/zephyrproject/modules/lib/Arduino-Core-Zephyr 19 | 20 | $> west flash --bossac=/home/$USER/.arduino15/packages/arduino/tools/bossac/1.9.1-arduino2/bossac 21 | ``` 22 | -------------------------------------------------------------------------------- /samples/spi_controller/src/app.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024 Ayush Singh 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include "SPI.h" 8 | #include 9 | 10 | #define CHIPSELECT 3 11 | 12 | static uint8_t data = 0; 13 | 14 | void setup() { 15 | SPI.begin(); 16 | pinMode(CHIPSELECT, OUTPUT); 17 | digitalWrite(CHIPSELECT, HIGH); 18 | } 19 | 20 | void loop() { 21 | SPI.beginTransaction(SPISettings(2000000, MSBFIRST, SPI_MODE0)); 22 | digitalWrite(CHIPSELECT, LOW); 23 | SPI.transfer(data++); 24 | digitalWrite(CHIPSELECT, HIGH); 25 | SPI.endTransaction(); 26 | delay(1000); 27 | } 28 | -------------------------------------------------------------------------------- /cores/arduino/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | 3 | # This line ensures that cores/arduino/zephyr/api is loaded ahead of 4 | # cores/arduino/api. 5 | if(CONFIG_USE_ARDUINO_API_RUST_IMPLEMENTATION) 6 | zephyr_include_directories(zephyr) 7 | endif() 8 | 9 | zephyr_include_directories(.) 10 | zephyr_include_directories(../../variants) 11 | 12 | if(NOT DEFINED ARDUINO_BUILD_PATH) 13 | 14 | zephyr_sources(zephyrPrint.cpp) 15 | zephyr_sources(zephyrSerial.cpp) 16 | zephyr_sources(zephyrCommon.cpp) 17 | zephyr_sources(apiCommon.cpp) 18 | 19 | if(DEFINED CONFIG_ARDUINO_ENTRY) 20 | zephyr_sources(main.cpp) 21 | endif() 22 | 23 | endif() 24 | 25 | -------------------------------------------------------------------------------- /samples/analog_input/README.rst: -------------------------------------------------------------------------------- 1 | .. _analog_input: 2 | 3 | Analog Input 4 | ############ 5 | 6 | Overview 7 | ******** 8 | 9 | The analog_input sample blinks the LED with control of the period 10 | by the voltage of the input pin. 11 | Inputting high voltage to blink the LED slowly. 12 | Blink the LED fast on input voltage is low. 13 | When the input is 0V, LED light. 14 | 15 | Building and Running 16 | ******************** 17 | 18 | Build and flash analog_input sample as follows, 19 | 20 | ```sh 21 | $> west build -p -b arduino_nano_33_ble sample/analog_input/ 22 | 23 | $> west flash --bossac=/home/$USER/.arduino15/packages/arduino/tools/bossac/1.9.1-arduino2/bossac 24 | ``` 25 | -------------------------------------------------------------------------------- /samples/attach_interrupt/README.rst: -------------------------------------------------------------------------------- 1 | .. _attach_interrupt-sample: 2 | 3 | AttachInterrupt 4 | ###### 5 | 6 | Overview 7 | ******** 8 | 9 | This sample demonstrates how to use attachInterrupt API. 10 | 11 | Building and Running 12 | ******************** 13 | 14 | Build and flash attachInterrupt sample as follows, 15 | 16 | ```sh 17 | $> west build -p -b arduino_nano_33_ble samples/basic/attach_interrupt/ -DZEPHYR_EXTRA_MODULES=/home/$USER/zephyrproject/modules/lib/Arduino-Core-Zephyr 18 | 19 | $> west flash --bossac=/home/$USER/.arduino15/packages/arduino/tools/bossac/1.9.1-arduino2/bossac 20 | ``` 21 | 22 | Turn on the LED by detecting interrupts. And Turn off the next interrupt. 23 | -------------------------------------------------------------------------------- /cores/arduino/apiCommon.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 TOKITA Hiroshi 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include 8 | #include "zephyrInternal.h" 9 | 10 | extern "C" { 11 | int32_t map_i32(int32_t x, int32_t in_min, int32_t in_max, int32_t out_min, int32_t out_max); 12 | uint16_t makeWord_w(uint16_t w); 13 | uint16_t makeWord_hl(byte h, byte l); 14 | } 15 | 16 | long map(long x, long in_min, long in_max, long out_min, long out_max) 17 | { 18 | return map_i32(x, in_min, in_max, out_min, out_max); 19 | } 20 | 21 | uint16_t makeWord(uint16_t w) { 22 | return makeWord_w(w); 23 | } 24 | uint16_t makeWord(byte h, byte l) { 25 | return makeWord_hl(h, l); 26 | } 27 | -------------------------------------------------------------------------------- /variants/nrf9160dk_nrf9160/variant.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Dejan Deletic 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #ifndef INCLUDE_NRF1960DK_NRF1960_PINMAP_H 8 | #define INCLUDE_NRF1960DK_NRF1960_PINMAP_H 9 | 10 | #define NRF9160DK_LED_1 D2 // P0.02 11 | #define NRF9160DK_LED_2 D3 // P0.03 12 | #define NRF9160DK_LED_3 D4 // P0.04 13 | #define NRF9160DK_LED_4 D5 // P0.05 14 | 15 | #define NRF9160DK_SWITCH_1 D6 // P0.08 16 | #define NRF9160DK_SWITCH_2 D7 // P0.09 17 | #define NRF9160DK_BUTTON_1 D8 // P0.06 18 | #define NRF9160DK_BUTTON_2 D9 // P0.07 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /rust/src/common.rs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 TOKITA Hiroshi 2 | // SPDX-License-Identifier: Apache-2.0 3 | 4 | #[unsafe(no_mangle)] 5 | pub extern "C" fn map_i32( 6 | x: i32, in_min: i32, in_max: i32, out_min: i32, out_max: i32 7 | ) -> i32 { 8 | let num = x.wrapping_sub(in_min).wrapping_mul(out_max.wrapping_sub(out_min)); 9 | let den = in_max.wrapping_sub(in_min); 10 | // Note: To keep compatibility, the panic when den=0 is left as is. 11 | num / den.wrapping_add(out_min) 12 | } 13 | 14 | #[unsafe(no_mangle)] 15 | pub extern "C" fn makeWord_w(w: u16) -> u16 { 16 | w 17 | } 18 | 19 | #[unsafe(no_mangle)] 20 | pub extern "C" fn makeWord_hl(h: u8, l: u8) -> u16 { 21 | ((h as u16) << 8) | (l as u16) 22 | } 23 | -------------------------------------------------------------------------------- /samples/fade/src/app.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 TOKITA Hiroshi 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include 8 | 9 | const int led = 3; // PWM output pin. 10 | const int increments = 5; 11 | const int wait_ms = 10; 12 | 13 | void setup() { 14 | /* Pin that use as the PWM output need not be configured by pinMode() */ 15 | } 16 | 17 | void loop() { 18 | int value = 0; 19 | while (value < 256) { 20 | analogWrite(led, value); 21 | value += increments; 22 | delay(wait_ms); 23 | } 24 | 25 | value = 255; 26 | while (value >= 0) { 27 | analogWrite(led, value); 28 | value -= increments; 29 | delay(wait_ms); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /samples/i2cdemo/README.rst: -------------------------------------------------------------------------------- 1 | i2c demo 2 | ###### 3 | 4 | Overview 5 | ******** 6 | 7 | This Arduino i2c sample gets data from an ADXL345 sensor connected over `i2c0`. 8 | 9 | Requirements 10 | ************ 11 | 12 | Your board must: 13 | 14 | #. Have atleast 1 i2c port. 15 | #. Have the ADXL345 sensor connected to the I2C port. 16 | 17 | Building and Running 18 | ******************** 19 | 20 | Build and flash Blinky as follows, 21 | 22 | ```sh 23 | $> west build -p -b arduino_nano_33_ble samples/i2cdemo 24 | 25 | $> west flash --bossac=/home/$USER/.arduino15/packages/arduino/tools/bossac/1.9.1-arduino2/bossac 26 | ``` 27 | 28 | After flashing, probe the UART pin (TX) and you should be able to see X, Y and Z values if everything goes well. 29 | -------------------------------------------------------------------------------- /samples/analog_input/src/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 TOKITA Hiroshi 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include 8 | 9 | const int analog_input = A0; // select the input pin for the potentiometer 10 | const int ledPin = LED_BUILTIN; // select the pin for the LED 11 | const float wait_factor = 1.f; 12 | 13 | void setup() { 14 | pinMode(ledPin, OUTPUT); 15 | } 16 | 17 | void loop() { 18 | int value = 0; 19 | 20 | value = analogRead(analog_input); 21 | 22 | /* Blinks slowly when the input voltage is high */ 23 | 24 | digitalWrite(ledPin, HIGH); 25 | delay(value * wait_factor); 26 | 27 | digitalWrite(ledPin, LOW); 28 | delay(value * wait_factor); 29 | } 30 | -------------------------------------------------------------------------------- /samples/hello_arduino/README.rst: -------------------------------------------------------------------------------- 1 | .. _hello_world: 2 | 3 | Hello World 4 | ########### 5 | 6 | Overview 7 | ******** 8 | 9 | A simple sample that can be used with any :ref:`supported board ` and 10 | prints "Hello World" to the console. 11 | 12 | Building and Running 13 | ******************** 14 | 15 | This application can be built and executed on QEMU as follows: 16 | 17 | .. zephyr-app-commands:: 18 | :zephyr-app: samples/hello_world 19 | :host-os: unix 20 | :board: qemu_x86 21 | :goals: run 22 | :compact: 23 | 24 | To build for another board, change "qemu_x86" above to that board's name. 25 | 26 | Sample Output 27 | ============= 28 | 29 | .. code-block:: console 30 | 31 | Hello World! x86 32 | 33 | Exit QEMU by pressing :kbd:`CTRL+A` :kbd:`x`. 34 | -------------------------------------------------------------------------------- /Kconfig: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2022 Dhruva Gole 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | # 6 | 7 | config ARDUINO_API 8 | bool "ARDUINO_API" 9 | imply CPP 10 | imply GPIO 11 | imply I2C 12 | imply NEWLIB_LIBC_FLOAT_PRINTF 13 | imply CBPRINTF_FP_SUPPORT 14 | imply RING_BUFFER 15 | select UART_INTERRUPT_DRIVEN 16 | default n 17 | 18 | if ARDUINO_API 19 | 20 | config USE_ARDUINO_API_RUST_IMPLEMENTATION 21 | bool "Use Rust implementation API core" 22 | select RUST 23 | 24 | config QEMU_ICOUNT 25 | bool "QEMU icount mode" 26 | default n 27 | depends on QEMU_TARGET 28 | 29 | config ARDUINO_API_SERIAL_BUFFER_SIZE 30 | int "Buffer size for Arduino Serial API" 31 | default 64 32 | 33 | config ARDUINO_ENTRY 34 | bool "Provide arduino setup and loop entry points" 35 | default y 36 | 37 | endif 38 | -------------------------------------------------------------------------------- /west.yml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2022 Dhruva Gole 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | # NOTE: This is created to be used for CI/CD workflow. So use it only 5 | # if you are in the zephyrproject directory or else things may break. 6 | 7 | manifest: 8 | self: 9 | path: modules/lib/Arduino-Zephyr-API 10 | 11 | remotes: 12 | - name: zephyrproject-rtos 13 | url-base: https://github.com/zephyrproject-rtos 14 | 15 | projects: 16 | - name: zephyr 17 | remote: zephyrproject-rtos 18 | revision: main 19 | import: 20 | name-allowlist: 21 | - cmsis # required by the ARM port 22 | - cmsis_6 # required by the ARM port 23 | - hal_nordic # required by the custom_plank board (Nordic based) 24 | - hal_ti 25 | -------------------------------------------------------------------------------- /samples/hello_arduino/src/app.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | */ 4 | 5 | #include 6 | #include "zephyrSerial.h" 7 | 8 | 9 | void setup() { 10 | // put your setup code here, to run once: 11 | Serial.begin(115200); // dummy as of now, need to study and refer https://docs.zephyrproject.org/latest/hardware/peripherals/uart.html 12 | } 13 | void loop() { 14 | char c = 'D'; 15 | size_t ret1; 16 | size_t ret2; 17 | ret1 = Serial.print(c); 18 | ret2 = Serial.println("Hello, World!"); 19 | printk("Sizes: %d %d\n", ret1, ret2); 20 | Serial.println(); 21 | ret1 = Serial.print("My letter is: "); 22 | ret2 = Serial.println(c); 23 | printk("Sizes: %d %d\n", ret1, ret2); 24 | Serial.println(); 25 | char myString[] = "Will it print?"; 26 | ret1 = Serial.println(myString); 27 | printk("Size: %d \n\n\n", ret1); 28 | delay(1000); // 1 second delay 29 | } 30 | -------------------------------------------------------------------------------- /samples/button_press_led/src/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-License-Identifier: Apache-2.0 3 | */ 4 | 5 | /* Button Press turns on inbuilt LED example */ 6 | 7 | #include 8 | 9 | const int buttonPin = D9; // the number of the pushbutton pin 10 | const int ledPin = 13; // the number of the LED pin 11 | 12 | // variables will change: 13 | int buttonState = 0; // variable for reading the pushbutton status 14 | 15 | void setup() { 16 | // initialize the LED pin as an output: 17 | pinMode(ledPin, OUTPUT); 18 | // initialize the pushbutton pin as an input: 19 | pinMode(buttonPin, INPUT); 20 | } 21 | 22 | void loop() { 23 | // read the state of the pushbutton value: 24 | buttonState = digitalRead(buttonPin); 25 | 26 | // check if the pushbutton is pressed. If it is, the buttonState is HIGH: 27 | if (buttonState == HIGH) { 28 | // turn LED on: 29 | digitalWrite(ledPin, HIGH); 30 | } else { 31 | // turn LED off: 32 | digitalWrite(ledPin, LOW); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e; 3 | 4 | printf '%s\n' "Before running this script, make sure of the following:" 5 | printf '%s\n' "1. You have zephyr installed properly on your system." 6 | printf '%s\n' "2. Updated west.yml in zephyr and run west update to pull this module in proper location." 7 | printf '%s\n' "If you meet the above criteria, please enter [yY]Yes and if not, then [nN]No." 8 | read answer; 9 | 10 | if [ "$answer" != "${answer#[Yy]}" ] ;then 11 | printf '%s\n' "Yes"; 12 | else 13 | printf '%s\n' "No"; 14 | exit 1; 15 | fi 16 | 17 | API_FOLDER=~/.ArduinoCore-API 18 | if [ ! -d "$API_FOLDER" ] ; then 19 | printf '%s\n' "Cloning ArduinoCore API in $API_FOLDER"; 20 | git clone git@github.com:arduino/ArduinoCore-API ~/.ArduinoCore-API; 21 | else 22 | printf '%s\n' "API Folder already exists, skipping clone..."; 23 | fi 24 | 25 | printf '%s\n' "Linking..."; 26 | ln -sf ~/.ArduinoCore-API/api cores/arduino/. ; 27 | 28 | printf '%s\n' "Module Successfully setup..."; 29 | 30 | -------------------------------------------------------------------------------- /documentation/arduino_libs.md: -------------------------------------------------------------------------------- 1 | # Using external Arduino Libraries 2 | 3 | A sample has been provided here using [ADXL345: ArduinoCore-Demo](https://github.com/DhruvaG2000/ArduinoCore-Demo). 4 | 5 | Let's assume the structure of your application for simplicity to be, 6 | 7 | ```tree 8 | ├── blinky_arduino 9 | │   ├── CMakeLists.txt 10 | │   ├── prj.conf 11 | │   ├── README.rst 12 | │   └── src 13 | │   └── main.cpp 14 | ``` 15 | 16 | 17 | ## Update contents of src folder 18 | Paste your library's source files like ``ADXL345.h`` and ``ADXL345.cpp`` in your project's src folder. 19 | 20 | ## Update CMakeLists 21 | As we can see, there is a Top-level CMakelists which needs to be updated with your external library's source files. 22 | For example, we add `target_sources(app PRIVATE src/ADXL345.cpp)` to CMakeLists.txt. 23 | 24 | ## Update main.cpp 25 | Finally, paste your required code using the library in ``main.c`` and include that library's header using 26 | ```c 27 | #include "ADXL345.h" 28 | ``` 29 | -------------------------------------------------------------------------------- /.github/workflows/license_check.yml: -------------------------------------------------------------------------------- 1 | name: Scancode 2 | 3 | on: [pull_request] 4 | 5 | permissions: 6 | contents: read 7 | 8 | jobs: 9 | scancode_job: 10 | runs-on: ubuntu-24.04 11 | name: Scan code for licenses 12 | steps: 13 | - name: Checkout the code 14 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 15 | with: 16 | fetch-depth: 0 17 | - name: Scan the code 18 | id: scancode 19 | uses: zephyrproject-rtos/action_scancode@23ef91ce31cd4b954366a7b71eea47520da9b380 # v4 20 | with: 21 | directory-to-scan: 'scan/' 22 | - name: Artifact Upload 23 | uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 24 | with: 25 | name: scancode 26 | path: ./artifacts 27 | 28 | - name: Verify 29 | run: | 30 | if [ -s ./artifacts/report.txt ]; then 31 | report=$(cat ./artifacts/report.txt) 32 | report="${report//'%'/'%25'}" 33 | report="${report//$'\n'/'%0A'}" 34 | report="${report//$'\r'/'%0D'}" 35 | echo "::error file=./artifacts/report.txt::$report" 36 | exit 1 37 | fi 38 | -------------------------------------------------------------------------------- /samples/threads_arduino/src/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Dhruva Gole 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include 8 | 9 | /* size of stack area used by each thread */ 10 | #define STACKSIZE 1024 11 | 12 | /* scheduling priority used by each thread */ 13 | #define PRIORITY 7 14 | 15 | void blink0(void) 16 | { 17 | while (1) { 18 | digitalWrite(LED_BUILTIN, HIGH); 19 | delay(100); 20 | digitalWrite(LED_BUILTIN, LOW); 21 | delay(100); 22 | } 23 | } 24 | 25 | void blink1(void) 26 | { 27 | while (1) { 28 | digitalWrite(D11, HIGH); 29 | delay(1000); 30 | digitalWrite(D11, LOW); 31 | delay(1000); 32 | } 33 | } 34 | 35 | K_THREAD_DEFINE(blink0_id, STACKSIZE, blink0, NULL, NULL, NULL, PRIORITY, 0, 0); 36 | K_THREAD_DEFINE(blink1_id, STACKSIZE, blink1, NULL, NULL, NULL, PRIORITY, 0, 0); 37 | K_THREAD_DEFINE(blink2_id, STACKSIZE, loop, NULL, NULL, NULL, PRIORITY, 0, 0); 38 | 39 | void setup() 40 | { 41 | pinMode(LED_BUILTIN, OUTPUT); 42 | pinMode(D11, OUTPUT); 43 | pinMode(D10, OUTPUT); 44 | } 45 | void loop() 46 | { 47 | digitalWrite(D10, HIGH); 48 | delay(300); 49 | digitalWrite(D10, LOW); 50 | delay(300); 51 | } 52 | -------------------------------------------------------------------------------- /.github/workflows/checkpatch.yml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow to help you get started with Actions 2 | 3 | name: checkpatch review 4 | 5 | # Controls when the workflow will run 6 | on: 7 | # Triggers the workflow on push or pull request events but only for the "main" branch 8 | push: 9 | branches: [ "main", "next" ] 10 | pull_request: 11 | branches: [ "main", "next" ] 12 | 13 | # Allows you to run this workflow manually from the Actions tab 14 | workflow_dispatch: 15 | 16 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 17 | jobs: 18 | my_review: 19 | name: checkpatch review 20 | runs-on: ubuntu-latest 21 | steps: 22 | - name: 'Calculate PR commits + 1' 23 | run: | 24 | echo "PR_FETCH_DEPTH=$(( ${{ github.event.pull_request.commits }} + 1 ))" >> $GITHUB_ENV 25 | wget https://raw.githubusercontent.com/zephyrproject-rtos/zephyr/refs/heads/main/scripts/checkpatch.pl 26 | - uses: actions/checkout@v4 27 | with: 28 | ref: ${{ github.event.pull_request.head.sha }} 29 | fetch-depth: ${{ env.PR_FETCH_DEPTH }} 30 | - name: Run checkpatch review 31 | uses: webispy/checkpatch-action@v9 32 | env: 33 | CHECKPATCH_COMMAND: perl ./checkpatch.pl 34 | 35 | -------------------------------------------------------------------------------- /variants/pocketbeagle_2_am6254_a53/pocketbeagle_2_am6254_a53.overlay: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2025 Ayush Singh 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | / { 8 | zephyr,user { 9 | digital-pin-gpios = 10 | <&main_gpio0 6 GPIO_ACTIVE_HIGH>, /* D0 - LED 1 */ 11 | <&main_gpio0 5 GPIO_ACTIVE_HIGH>, /* D1 - LED 2 */ 12 | <&main_gpio0 4 GPIO_ACTIVE_HIGH>, /* D2 - LED 3 */ 13 | <&main_gpio0 3 GPIO_ACTIVE_HIGH>, /* D3 - LED 4 */ 14 | <&main_gpio1 12 GPIO_ACTIVE_HIGH>, /* D4 - P1.04 */ 15 | <&main_gpio0 50 GPIO_ACTIVE_HIGH>, /* D5 - P1.20 */ 16 | <&main_gpio1 2 GPIO_ACTIVE_HIGH>, /* D6 - P1.34 */ 17 | <&main_gpio0 53 GPIO_ACTIVE_HIGH>, /* D7 - P2.18 */ 18 | <&main_gpio0 49 GPIO_ACTIVE_HIGH>, /* D8 - P2.20 */ 19 | <&main_gpio0 63 GPIO_ACTIVE_HIGH>, /* D9 - P2.22 */ 20 | <&main_gpio0 51 GPIO_ACTIVE_HIGH>, /* D10 - P2.24 */ 21 | <&main_gpio0 52 GPIO_ACTIVE_HIGH>; /* D11 - P2.33 */ 22 | 23 | builtin-led-gpios = 24 | <&main_gpio0 6 GPIO_ACTIVE_HIGH>, /* LED 1 */ 25 | <&main_gpio0 5 GPIO_ACTIVE_HIGH>, /* LED 2 */ 26 | <&main_gpio0 4 GPIO_ACTIVE_HIGH>, /* LED 3 */ 27 | <&main_gpio0 3 GPIO_ACTIVE_HIGH>; /* LED 4 */ 28 | 29 | serials = <&main_uart0 &main_uart5>; 30 | i2cs = <&main_i2c2 &main_i2c3>; 31 | }; 32 | }; 33 | -------------------------------------------------------------------------------- /variants/cc3220sf_launchxl_cc3220sf/cc3220sf_launchxl_cc3220sf.overlay: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Dhruva Gole 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | / { 8 | zephyr,user { 9 | digital-pin-gpios = <&boosterpack_header 4 0>, /* GPIO_12 */ 10 | <&boosterpack_header 5 0>, /* GPIO_06 */ 11 | <&boosterpack_header 7 0>, /* GPIO_14 */ 12 | <&boosterpack_header 9 0>, /* I2C_SCL | YELLOW_LED */ 13 | <&boosterpack_header 10 0>, /* I2C_SDA | GREEN_LED */ 14 | <&boosterpack_header 11 0>, /* GPIO_22 */ 15 | <&boosterpack_header 12 0>, /* GPIO_01 */ 16 | <&boosterpack_header 13 0>, /* GPIO_25 */ 17 | <&boosterpack_header 14 0>, /* GPIO_15 */ 18 | <&boosterpack_header 15 0>, /* GPIO_16 */ 19 | <&boosterpack_header 17 0>, /* GPIO_31 */ 20 | <&boosterpack_header 18 0>, /* GPIO_17 */ 21 | <&boosterpack_header 19 0>, /* GPIO_28 */ 22 | <&boosterpack_header 23 0>, /* GPIO_02 | AIN0 */ 23 | <&boosterpack_header 24 0>, /* GPIO_05 | AIN3 */ 24 | <&boosterpack_header 25 0>, /* GPIO_03 | AIN1 */ 25 | <&boosterpack_header 26 0>, /* GPIO_04 | AIN2 */ 26 | <&boosterpack_header 27 0>, /* GPIO_08 */ 27 | <&boosterpack_header 28 0>, /* GPIO_30 */ 28 | <&boosterpack_header 29 0>, /* GPIO_09 | RED_LED | I2S_DOUT*/ 29 | <&boosterpack_header 30 0>, /* GPIO_00 */ 30 | <&boosterpack_header 31 0>, /* GPIO_24 */ 31 | <&boosterpack_header 32 0>; /* GPIO_23 */ 32 | builtin-led-gpios = <&boosterpack_header 10 0>; /* GREEN_LED */ 33 | serials = <&boosterpack_serial>; 34 | i2cs = <&boosterpack_i2c>; 35 | }; 36 | }; 37 | -------------------------------------------------------------------------------- /samples/threads_arduino/README.rst: -------------------------------------------------------------------------------- 1 | .. _arduino_nano_33_ble_multi_thread_blinky: 2 | 3 | Basic Thread Example 4 | #################### 5 | 6 | Overview 7 | ******** 8 | 9 | This example demonstrates spawning multiple threads using 10 | :c:func:`K_THREAD_DEFINE`. It spawns three threads. Each thread is then defined 11 | at compile time using `K_THREAD_DEFINE`. 12 | 13 | These three each control an LED. These LEDs, ``LED_BUILTIN``, ``D10`` and ``D11``, have 14 | loop control and timing logic controlled by separate functions. 15 | 16 | - ``blink0()`` controls ``LED_BUILTIN`` and has a 100ms sleep cycle 17 | - ``blink1()`` controls ``D11`` and has a 1000ms sleep cycle 18 | - ``loop()`` controls ``D10`` and has a 300ms sleep cycle 19 | 20 | Requirements 21 | ************ 22 | 23 | The board must have two LEDs connected via GPIO pins and one builtin LED. These are called "User 24 | LEDs" on many of Zephyr's :ref:`boards`. The LEDs must be mapped using the `` 25 | ``LED_BUILTIN``, ``D10`` and ``D11`` to the :ref:`devicetree ` aliases, in the 26 | variants folder. 27 | 28 | You will see one of these errors if you try to build this sample for an 29 | unsupported board: 30 | 31 | .. code-block:: none 32 | 33 | Unsupported board: LED_BUILTIN devicetree alias is not defined 34 | Unsupported board: D11 devicetree alias is not defined 35 | 36 | Building 37 | ******** 38 | 39 | For example, to build this sample for :ref:`arduino_nano_33_ble`: 40 | 41 | .. zephyr-app-commands:: 42 | :zephyr-app: samples/basic/arduino-threads 43 | :board: arduino_nano_33_ble 44 | :goals: build flash 45 | :compact: 46 | 47 | Change ``arduino_nano_33_ble`` appropriately for other supported boards. 48 | -------------------------------------------------------------------------------- /samples/button_press_led/README.rst: -------------------------------------------------------------------------------- 1 | Button press LED 2 | ###### 3 | 4 | Overview 5 | ******** 6 | 7 | This Arduino sample turns ON an LED if button pressed using the `ArduinoAPI`. 8 | 9 | Requirements 10 | ************ 11 | 12 | Your board must: 13 | 14 | #. Have an LED connected via a GPIO pin (these are called "User LEDs" on many of 15 | Zephyr's :ref:`boards`). 16 | #. Have the LED configured using the ``led0`` devicetree alias. 17 | #. Have a button connected to pin `D9` of the arduino externally (pulled down by default) 18 | 19 | Building and Running 20 | ******************** 21 | 22 | Build and flash as follows, 23 | 24 | ```sh 25 | $> west build -p -b arduino_nano_33_ble samples/button_press_led -DZEPHYR_EXTRA_MODULES=/home/$USER/zephyrproject/modules/lib/Arduino-Core-Zephyr 26 | 27 | $> west flash --bossac=/home/$USER/.arduino15/packages/arduino/tools/bossac/1.9.1-arduino2/bossac 28 | ``` 29 | 30 | Adding board support 31 | ******************** 32 | 33 | To add support for your board, add something like this to your devicetree: 34 | 35 | .. code-block:: DTS 36 | 37 | / { 38 | aliases { 39 | led0 = &myled0; 40 | }; 41 | 42 | leds { 43 | compatible = "gpio-leds"; 44 | myled0: led_0 { 45 | gpios = <&gpio0 13 GPIO_ACTIVE_LOW>; 46 | }; 47 | }; 48 | }; 49 | 50 | The above sets your board's ``led0`` alias to use pin 13 on GPIO controller 51 | ``gpio0``. The pin flags :c:macro:`GPIO_ACTIVE_HIGH` mean the LED is on when 52 | the pin is set to its high state, and off when the pin is in its low state. 53 | 54 | Tips: 55 | 56 | - See :dtcompatible:`gpio-leds` for more information on defining GPIO-based LEDs 57 | in devicetree. 58 | 59 | - If you're not sure what to do, check the devicetrees for supported boards which 60 | use the same SoC as your target. See :ref:`get-devicetree-outputs` for details. 61 | 62 | - See :zephyr_file:`include/zephyr/dt-bindings/gpio/gpio.h` for the flags you can use 63 | in devicetree. 64 | 65 | - If the LED is built in to your board hardware, the alias should be defined in 66 | your :ref:`BOARD.dts file `. Otherwise, you can 67 | define one in a :ref:`devicetree overlay `. 68 | -------------------------------------------------------------------------------- /samples/blinky_arduino/README.rst: -------------------------------------------------------------------------------- 1 | .. _blinky-sample: 2 | 3 | Blinky 4 | ###### 5 | 6 | Overview 7 | ******** 8 | 9 | This Arduino Blinky sample blinks an LED forever using the `ArduinoAPI`. 10 | 11 | Requirements 12 | ************ 13 | 14 | Your board must: 15 | 16 | #. Have an LED connected via a GPIO pin (these are called "User LEDs" on many of 17 | Zephyr's :ref:`boards`). 18 | #. Have the LED configured using the ``led0`` devicetree alias. 19 | 20 | Building and Running 21 | ******************** 22 | 23 | Build and flash Blinky as follows, 24 | 25 | ```sh 26 | $> west build -p -b arduino_nano_33_ble samples/basic/arduino-blinky/ -DZEPHYR_EXTRA_MODULES=/home/$USER/zephyrproject/modules/lib/Arduino-Core-Zephyr 27 | 28 | $> west flash --bossac=/home/$USER/.arduino15/packages/arduino/tools/bossac/1.9.1-arduino2/bossac 29 | ``` 30 | 31 | After flashing, the LED starts to blink. If a runtime error occurs, the sample 32 | exits without printing to the console. 33 | 34 | Adding board support 35 | ******************** 36 | 37 | To add support for your board, add something like this to your devicetree: 38 | 39 | .. code-block:: DTS 40 | 41 | / { 42 | aliases { 43 | led0 = &myled0; 44 | }; 45 | 46 | leds { 47 | compatible = "gpio-leds"; 48 | myled0: led_0 { 49 | gpios = <&gpio0 13 GPIO_ACTIVE_LOW>; 50 | }; 51 | }; 52 | }; 53 | 54 | The above sets your board's ``led0`` alias to use pin 13 on GPIO controller 55 | ``gpio0``. The pin flags :c:macro:`GPIO_ACTIVE_HIGH` mean the LED is on when 56 | the pin is set to its high state, and off when the pin is in its low state. 57 | 58 | Tips: 59 | 60 | - See :dtcompatible:`gpio-leds` for more information on defining GPIO-based LEDs 61 | in devicetree. 62 | 63 | - If you're not sure what to do, check the devicetrees for supported boards which 64 | use the same SoC as your target. See :ref:`get-devicetree-outputs` for details. 65 | 66 | - See :zephyr_file:`include/zephyr/dt-bindings/gpio/gpio.h` for the flags you can use 67 | in devicetree. 68 | 69 | - If the LED is built in to your board hardware, the alias should be defined in 70 | your :ref:`BOARD.dts file `. Otherwise, you can 71 | define one in a :ref:`devicetree overlay `. 72 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | name: Build Arduino-API Zephyr samples 8 | runs-on: ubuntu-latest 9 | container: zephyrprojectrtos/ci-base:latest 10 | env: 11 | CMAKE_PREFIX_PATH: /opt/toolchains 12 | CCACHE_IGNOREOPTIONS: -specs=* 13 | MODULE_PATH: ../modules/lib/Arduino-Zephyr-API 14 | 15 | steps: 16 | - name: Checkout 17 | uses: actions/checkout@v4 18 | with: 19 | fetch-depth: 0 20 | persist-credentials: false 21 | path: subfolder 22 | 23 | - name: Fix module path, list needed HALs 24 | run: | 25 | mkdir -p $(dirname $MODULE_PATH) && mv subfolder $MODULE_PATH 26 | 27 | - name: Setup Zephyr project 28 | uses: zephyrproject-rtos/action-zephyr-setup@v1 29 | with: 30 | toolchains: arm-zephyr-eabi 31 | manifest-file-name: ${{ env.MODULE_PATH }}/west.yml 32 | enable-ccache: false 33 | 34 | - name: Add manifest path as module 35 | run: | 36 | echo EXTRA_ZEPHYR_MODULES="$(pwd)/$MODULE_PATH" >> $GITHUB_ENV 37 | 38 | - name: Initialize 39 | run: | 40 | git clone https://github.com/arduino/ArduinoCore-API.git $MODULE_PATH/../ArduinoCore-API 41 | cp -rfp $MODULE_PATH/../ArduinoCore-API/api $MODULE_PATH/cores/arduino/ 42 | 43 | - name: Setup Rust toolchain 44 | run: | 45 | wget https://sh.rustup.rs 46 | mv index.html rustup_install.sh 47 | bash rustup_install.sh -y 48 | /root/.cargo/bin/rustup default stable 49 | /root/.cargo/bin/rustup target add thumbv6m-none-eabi thumbv7em-none-eabihf thumbv7em-none-eabi thumbv7m-none-eabi 50 | echo "/root/.cargo/bin" >> $GITHUB_PATH 51 | 52 | - name: Build fade 53 | run: | 54 | west build -p -b arduino_nano_33_ble/nrf52840/sense $MODULE_PATH/samples/fade 55 | 56 | - name: Build i2cdemo 57 | run: | 58 | west build -p -b arduino_nano_33_ble/nrf52840/sense $MODULE_PATH/samples/i2cdemo 59 | 60 | - name: Build adc 61 | run: | 62 | west build -p -b beagleconnect_freedom/cc1352p7 $MODULE_PATH/samples/analog_input 63 | 64 | - name: Archive firmware 65 | uses: actions/upload-artifact@v4 66 | with: 67 | name: firmware 68 | path: Arduino-Zephyr-API/build/zephyr/zephyr.* 69 | -------------------------------------------------------------------------------- /libraries/Wire/Wire.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Dhruva Gole 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | typedef void (*voidFuncPtrParamInt)(int); 15 | 16 | namespace arduino { 17 | 18 | class ZephyrI2C : public HardwareI2C { 19 | public: 20 | ZephyrI2C(const struct device* i2c); 21 | 22 | virtual void begin(); 23 | virtual void end(); 24 | virtual void begin(uint8_t address); 25 | virtual void setClock(uint32_t freq); 26 | 27 | virtual void beginTransmission(uint8_t address); 28 | virtual uint8_t endTransmission(bool stopBit); 29 | virtual uint8_t endTransmission(void); 30 | 31 | virtual size_t requestFrom(uint8_t address, size_t len, bool stopBit); 32 | virtual size_t requestFrom(uint8_t address, size_t len); 33 | 34 | virtual void onReceive(void (*)(int)); 35 | virtual void onRequest(void (*)(void)); 36 | 37 | virtual size_t write(uint8_t data); 38 | virtual size_t write(int data) { return write((uint8_t)data); }; 39 | virtual size_t write(const uint8_t *buffer, size_t size); 40 | using Print::write; 41 | virtual int read(); 42 | virtual int peek(); 43 | virtual void flush(); 44 | virtual int available(); 45 | 46 | private: 47 | int _address; 48 | uint8_t txBuffer[256]; 49 | uint32_t usedTxBuffer; 50 | struct rx_ring_buf{ 51 | struct ring_buf rb; 52 | uint8_t buffer[256]; 53 | }; 54 | struct rx_ring_buf rxRingBuffer; 55 | const struct device* i2c_dev; 56 | }; 57 | 58 | } // namespace arduino 59 | 60 | #if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), i2cs) && (DT_PROP_LEN(DT_PATH(zephyr_user), i2cs) > 1) 61 | #define ARDUINO_WIRE_DEFINED_0 1 62 | #define DECL_EXTERN_WIRE_0(i) extern arduino::ZephyrI2C Wire; 63 | #define DECL_EXTERN_WIRE_N(i) extern arduino::ZephyrI2C Wire##i; 64 | #define DECLARE_EXTERN_WIRE_N(n, p, i) \ 65 | COND_CODE_1(ARDUINO_WIRE_DEFINED_##i, (DECL_EXTERN_WIRE_0(i)), (DECL_EXTERN_WIRE_N(i))) 66 | 67 | /* Declare Wire, Wire1, Wire2, ... */ 68 | DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user), i2cs, DECLARE_EXTERN_WIRE_N) 69 | 70 | #undef DECLARE_EXTERN_WIRE_N 71 | #undef DECL_EXTERN_WIRE_N 72 | #undef DECL_EXTERN_WIRE_0 73 | #undef ARDUINO_WIRE_DEFINED_0 74 | #else 75 | extern arduino::ZephyrI2C Wire; 76 | #endif 77 | 78 | typedef arduino::ZephyrI2C TwoWire; 79 | -------------------------------------------------------------------------------- /cores/arduino/zephyrPrint.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 TOKITA Hiroshi 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | namespace arduino 13 | { 14 | namespace zephyr 15 | { 16 | 17 | int cbprintf_callback(int c, void *ctx) 18 | { 19 | return reinterpret_cast(ctx)->write((unsigned char)c); 20 | } 21 | 22 | size_t wrap_cbprintf(void *ctx, const char *format, ...) 23 | { 24 | va_list ap; 25 | int rc; 26 | 27 | va_start(ap, format); 28 | rc = cbvprintf(reinterpret_cast(cbprintf_callback), ctx, format, ap); 29 | va_end(ap); 30 | 31 | return static_cast(rc > 0 ? rc : 0); 32 | } 33 | 34 | size_t print_number_base_any(void *ctx, unsigned long long ull, int base) 35 | { 36 | arduino::Print &print = *reinterpret_cast(ctx); 37 | char string[sizeof(unsigned long long) * 8] = {0}; 38 | size_t digit = 0; 39 | unsigned value; 40 | 41 | if (base < 2 || base > ('~' - 'A' + 10)) { 42 | base = 10; 43 | } 44 | 45 | while (ull != 0) { 46 | value = ull % base; 47 | if (value < 10) { 48 | string[sizeof(string) - digit] = '0' + value; 49 | } else { 50 | string[sizeof(string) - digit] = 'A' + (value- 10); 51 | } 52 | 53 | digit++; 54 | ull /= base; 55 | } 56 | 57 | return print.write(string + (sizeof(string) - digit), digit + 1); 58 | } 59 | 60 | size_t print_number_base_pow2(void *ctx, unsigned long long ull, unsigned bits) 61 | { 62 | arduino::Print &print = *reinterpret_cast(ctx); 63 | const unsigned long long mask = (1 << bits) - 1; 64 | int digit = (((sizeof(unsigned long long) * 8) + bits) / bits); 65 | int output_count = -1; 66 | unsigned value; 67 | 68 | while (digit >= 0) { 69 | value = (ull & (mask << (digit * bits))) >> (digit * bits); 70 | if (value != 0 && output_count < 0) { 71 | output_count = 0; 72 | } 73 | 74 | if (output_count >= 0) { 75 | if (value < 10) { 76 | print.write('0' + value); 77 | } else { 78 | print.write('A' + (value- 10)); 79 | } 80 | output_count++; 81 | } 82 | digit--; 83 | } 84 | 85 | return output_count; 86 | } 87 | 88 | } // namespace zephyr 89 | } // namespace arduino 90 | 91 | /* 92 | * This is the default implementation. 93 | * It will be overridden by subclassese. 94 | */ 95 | size_t arduino::Print::write(const uint8_t *buffer, size_t size) 96 | { 97 | size_t i; 98 | for (i=0; i 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #define SPR0 0 14 | #define SPR1 1 15 | #define CPHA 2 16 | #define CPOL 3 17 | #define MSTR 4 18 | #define DORD 5 19 | #define SPE 6 20 | #define SPIE 7 21 | 22 | /* Count the number of GPIOs for limit of number of interrupts */ 23 | #define INTERRUPT_HELPER(n, p, i) 1 24 | #define INTERRUPT_COUNT \ 25 | DT_FOREACH_PROP_ELEM_SEP(DT_PATH(zephyr_user), digital_pin_gpios, \ 26 | INTERRUPT_HELPER, (+)) 27 | 28 | namespace arduino { 29 | class ZephyrSPI : public HardwareSPI { 30 | public: 31 | ZephyrSPI(const struct device *spi); 32 | 33 | virtual uint8_t transfer(uint8_t data); 34 | virtual uint16_t transfer16(uint16_t data); 35 | virtual void transfer(void *buf, size_t count); 36 | 37 | // Transaction Functions 38 | virtual void usingInterrupt(int interruptNumber); 39 | virtual void notUsingInterrupt(int interruptNumber); 40 | virtual void beginTransaction(SPISettings settings); 41 | virtual void endTransaction(void); 42 | 43 | // SPI Configuration methods 44 | virtual void attachInterrupt(); 45 | virtual void detachInterrupt(); 46 | 47 | virtual void begin(); 48 | virtual void end(); 49 | 50 | private: 51 | const struct device *spi_dev; 52 | struct spi_config config; 53 | int interrupt[INTERRUPT_COUNT]; 54 | size_t interrupt_pos = 0; 55 | }; 56 | 57 | } // namespace arduino 58 | 59 | #if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), spis) && (DT_PROP_LEN(DT_PATH(zephyr_user), spis) > 1) 60 | #define ARDUINO_SPI_DEFINED_0 1 61 | #define DECL_EXTERN_SPI_0(i) extern arduino::ZephyrSPI SPI 62 | #define DECL_EXTERN_SPI_N(i) extern arduino::ZephyrSPI SPI##i 63 | #define DECLARE_EXTERN_SPI_N(n, p, i) \ 64 | COND_CODE_1(ARDUINO_SPI_DEFINED_##i, (DECL_EXTERN_SPI_0(i);), (DECL_EXTERN_SPI_N(i);)) 65 | 66 | /* Declare SPI, SPI1, SPI2, ... */ 67 | DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user), spis, DECLARE_EXTERN_SPI_N) 68 | 69 | #undef DECLARE_EXTERN_SPI_N 70 | #undef DECL_EXTERN_SPI_N 71 | #undef DECL_EXTERN_SPI_0 72 | #undef ARDUINO_SPI_DEFINED_0 73 | #else 74 | extern arduino::ZephyrSPI SPI; 75 | #endif 76 | 77 | /* Serial Peripheral Control Register */ 78 | extern uint8_t SPCR; 79 | 80 | using arduino::SPI_MODE0; 81 | using arduino::SPI_MODE1; 82 | using arduino::SPI_MODE2; 83 | using arduino::SPI_MODE3; 84 | using arduino::SPISettings; 85 | -------------------------------------------------------------------------------- /cores/arduino/zephyrSerial.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Dhruva Gole 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | namespace arduino { 15 | 16 | class ZephyrSerialStub : public HardwareSerial 17 | { 18 | public: 19 | void begin(unsigned long baudRate) { } 20 | void begin(unsigned long baudrate, uint16_t config) { } 21 | void end() { } 22 | int available() { return 0; } 23 | int peek() { return 0; } 24 | int read() { return 0; } 25 | void flush() { } 26 | size_t write(const uint8_t data) 27 | { 28 | printk("%c", static_cast(data)); 29 | return 1; 30 | } 31 | 32 | operator bool() { return true; } 33 | }; 34 | 35 | class ZephyrSerial : public HardwareSerial 36 | { 37 | public: 38 | template 39 | class ZephyrSerialBuffer 40 | { 41 | friend arduino::ZephyrSerial; 42 | struct ring_buf ringbuf; 43 | uint8_t buffer[SZ]; 44 | struct k_sem sem; 45 | 46 | ZephyrSerialBuffer() 47 | { 48 | k_sem_init(&sem, 1, 1); 49 | ring_buf_init(&ringbuf, sizeof(buffer), buffer); 50 | } 51 | }; 52 | 53 | ZephyrSerial(const struct device *dev) : uart(dev) { } 54 | void begin(unsigned long baudrate, uint16_t config); 55 | void begin(unsigned long baudrate) { begin(baudrate, SERIAL_8N1); } 56 | void flush() { } 57 | void end() { } 58 | size_t write(const uint8_t *buffer, size_t size); 59 | size_t write(const uint8_t data) { return write(&data, 1); } 60 | int available(); 61 | int peek(); 62 | int read(); 63 | 64 | operator bool() 65 | { 66 | return true; 67 | } 68 | 69 | protected: 70 | void IrqHandler(); 71 | static void IrqDispatch(const struct device *dev, void *data); 72 | 73 | const struct device *uart; 74 | ZephyrSerialBuffer tx; 75 | ZephyrSerialBuffer rx; 76 | }; 77 | 78 | 79 | } // namespace arduino 80 | 81 | #if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), serials) 82 | extern arduino::ZephyrSerial Serial; 83 | #if (DT_PROP_LEN(DT_PATH(zephyr_user), serials) > 1) 84 | #define SERIAL_DEFINED_0 1 85 | #define EXTERN_SERIAL_N(i) extern arduino::ZephyrSerial Serial##i; 86 | #define DECLARE_EXTERN_SERIAL_N(n, p, i) COND_CODE_1(SERIAL_DEFINED_##i, (), (EXTERN_SERIAL_N(i))) 87 | 88 | /* Declare Serial1, Serial2, ... */ 89 | DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user), serials, DECLARE_EXTERN_SERIAL_N) 90 | 91 | #undef DECLARE_EXTERN_SERIAL_N 92 | #undef EXTERN_SERIAL_N 93 | #undef SERIAL_DEFINED_0 94 | #endif 95 | #elif DT_NODE_HAS_STATUS(DT_NODELABEL(arduino_serial), okay) 96 | extern arduino::ZephyrSerial Serial; 97 | #else 98 | extern arduino::ZephyrSerialStub Serial; 99 | #endif 100 | -------------------------------------------------------------------------------- /samples/i2cdemo/src/main.cpp: -------------------------------------------------------------------------------- 1 | /* Blink inbuilt LED example */ 2 | 3 | #include 4 | #include "Wire.h" 5 | 6 | void setup() 7 | { 8 | printf("\n\nSetup begins\n"); 9 | Wire.begin(); 10 | // initialize the LED pin as an output: 11 | 12 | // initialize the pushbutton pin as an input: 13 | // pinMode(buttonPin, INPUT); 14 | // pinMode(ledPin, OUTPUT); 15 | Wire.beginTransmission(0x53); 16 | Wire.write(0x2C); 17 | Wire.write(0x08); 18 | Wire.endTransmission(); 19 | 20 | Wire.beginTransmission(0x53); 21 | Wire.write(0x31); 22 | Wire.write(0x08); 23 | Wire.endTransmission(); 24 | 25 | Wire.beginTransmission(0x53); 26 | Wire.write(0x2D); 27 | Wire.write(0x08); 28 | Wire.endTransmission(); 29 | printf("\n\nSetup COMPLETE\n\n\n"); 30 | } 31 | 32 | void loop() 33 | { 34 | Wire.beginTransmission(0x53); 35 | Wire.write(0x32); 36 | Wire.endTransmission(); 37 | // printf("\n\nrequesting from 53\n\n\n"); 38 | Wire.requestFrom(0x53, 1); 39 | byte x0 = Wire.read(); 40 | 41 | Wire.beginTransmission(0x53); 42 | Wire.write(0x33); 43 | Wire.endTransmission(); 44 | Wire.requestFrom(0x53, 1); 45 | byte x1 = Wire.read(); 46 | x1 = x1 & 0x03; 47 | 48 | uint16_t x = (x1 << 8) + x0; 49 | int16_t xf = x; 50 | if(xf > 511) 51 | { 52 | xf = xf - 1024; 53 | } 54 | float xa = xf * 0.004; 55 | printf("\n\nX = %f\n",xa); 56 | // Serial.print("X = "); 57 | // Serial.print(xa); 58 | // Serial.print(" g"); 59 | // Serial.println(); 60 | 61 | 62 | Wire.beginTransmission(0x53); 63 | Wire.write(0x34); 64 | Wire.endTransmission(); 65 | Wire.requestFrom(0x53, 1); 66 | byte y0 = Wire.read(); 67 | 68 | Wire.beginTransmission(0x53); 69 | Wire.write(0x35); 70 | Wire.endTransmission(); 71 | Wire.requestFrom(0x53, 1); 72 | byte y1 = Wire.read(); 73 | y1 = y1 & 0x03; 74 | 75 | uint16_t y = (y1 << 8) + y0; 76 | int16_t yf = y; 77 | if(yf > 511) 78 | { 79 | yf = yf - 1024; 80 | } 81 | float ya = yf * 0.004; 82 | // printk("Y = %f\n",ya); 83 | printf("Y = %f\n",ya); 84 | // printf("\n\nYa = %f\n\n\n",ya); 85 | // Serial.print("Y = "); 86 | // Serial.print(ya); 87 | // Serial.print(" g"); 88 | // Serial.println(); 89 | 90 | Wire.beginTransmission(0x53); 91 | Wire.write(0x36); 92 | Wire.endTransmission(); 93 | Wire.requestFrom(0x53, 1); 94 | byte z0 = Wire.read(); 95 | 96 | Wire.beginTransmission(0x53); 97 | Wire.write(0x37); 98 | Wire.endTransmission(); 99 | Wire.requestFrom(0x53, 1); 100 | byte z1 = Wire.read(); 101 | z1 = z1 & 0x03; 102 | 103 | uint16_t z = (z1 << 8) + z0; 104 | int16_t zf = z; 105 | if(zf > 511) 106 | { 107 | zf = zf - 1024; 108 | } 109 | float za = zf * 0.004; 110 | printf("Z = %f\n\n",za); 111 | // Serial.print("Z = "); 112 | // Serial.print(za); 113 | // Serial.print(" g"); 114 | // Serial.println(); 115 | // Serial.println(); 116 | delay(500); 117 | 118 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GSoC 2022 Project: Arduino Core API module for Zephyr 2 | 3 | ![](https://dhruvag2000.github.io/Blog-GSoC22/assets/images/website_header.png) 4 | 5 | The **Arduino Core API** module for zephyr leverages the power of Zephyr under an Arduino-C++ style abtraction layer thus helping zephyr new-comers to start using it without worrying about learning about new APIs and libraries. See the project documentation folder for detailed documentation on these topics: 6 | 7 | * [Using external Arduino Libraries](/documentation/arduino_libs.md) 8 | * [Adding custom boards/ variants](/documentation/variants.md) 9 | 10 | ## Adding Arduino Core API to Zephyr 11 | 12 | * **Pre requisites:** It is assumed that you have zephyrproject configured and installed on your system as per the official [Get Started Guide](https://docs.zephyrproject.org/latest/develop/getting_started/index.html). The recommended path to install is `~/zephyrproject` as specified in the guide. If you have zephyr installed in a custom path you may need to make changes to the CMakeLists.txt file in the sample code directory when building these samples. 13 | 14 | * Add following entry to `west.yml` file in `manifest/projects` subtree of Zephyr: 15 | ``` 16 | # Arduino API repository. 17 | - name: Arduino-Core-Zephyr 18 | path: modules/lib/Arduino-Zephyr-API 19 | revision: main 20 | url: https://github.com/zephyrproject-rtos/gsoc-2022-arduino-core 21 | ``` 22 | 23 | * Then, clone the repository by running 24 | 25 | ```sh 26 | west update 27 | ``` 28 | 29 | * **Note:** For ***Linux users only*** there exists an ``install.sh`` script in this project that can be run to quickly link the ArduinoCore-API to this module. 30 | If you are able to run that script successfully then you can skip the next steps. 31 | 32 | * To "complete" the core you need to copy or symlink the api folder from the [ArduinoCore-API](https://github.com/arduino/ArduinoCore-API.git) repo to the target's ``cores/arduino`` folder: 33 | ```sh 34 | $ git clone git@github.com:arduino/ArduinoCore-API # Any location 35 | $ ln -s ///ArduinoCore-API/api cores/arduino/. 36 | ``` 37 | The `cores` folder can be found at `~/zephyrproject/modules/lib/Arduino-Zephyr-API/cores`. 38 | 39 | **Known Bug(s):** 40 | 41 | __NOTE:__ You can skip this step as well if you ran ``install.sh``. 42 | 43 | **Maintainers**: 44 | - [DhruvaG2000](https://github.com/DhruvaG2000) 45 | - [soburi](https://github.com/soburi) 46 | - [szczys](https://github.com/szczys) 47 | - [beriberikix](https://github.com/beriberikix) 48 | - [alvarowolfx](https://github.com/alvarowolfx) 49 | 50 | ## License 51 | Please note that the current license is Apache 2. Previously it was LGPL 2.1 but after careful review it was determined that no LGPL code or derivates was used and the more permissive license was chosen. 52 | 53 | **Additional Links** 54 | * [Official Project Blog](https://dhruvag2000.github.io/Blog-GSoC22/) 55 | * Golioth's Article: [Zephyr + Arduino: a Google Summer of Code story](https://blog.golioth.io/zephyr-arduino-a-google-summer-of-code-story/) 56 | -------------------------------------------------------------------------------- /variants/beagleconnect_freedom_cc1352p7/beagleconnect_freedom_cc1352p7.overlay: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024 Ayush Singh 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | / { 8 | zephyr,user { 9 | digital-pin-gpios = 10 | <&gpio0 16 GPIO_ACTIVE_HIGH>, /* D0 - MB1 INT */ 11 | <&gpio0 20 GPIO_ACTIVE_HIGH>, /* D1 - MB2 INT */ 12 | <&gpio0 17 GPIO_ACTIVE_HIGH>, /* D2 - MB1 PWM */ 13 | <&gpio0 28 GPIO_ACTIVE_HIGH>, /* D3 - MB1 CS - A5 */ 14 | <&gpio0 21 GPIO_ACTIVE_HIGH>, /* D4 - MB2 UART1 RX */ 15 | <&gpio0 22 GPIO_ACTIVE_HIGH>, /* D5 - MB2 UART1 TX */ 16 | <&gpio0 19 GPIO_ACTIVE_HIGH>, /* D6 - MB2 PWM */ 17 | <&gpio0 27 GPIO_ACTIVE_HIGH>, /* D7 - MB2 CS - A4 */ 18 | <&gpio0 9 GPIO_ACTIVE_HIGH>, /* D8 - MB1/2 PICO */ 19 | <&gpio0 10 GPIO_ACTIVE_HIGH>, /* D9 - MB1/2 SCK */ 20 | <&gpio0 11 GPIO_ACTIVE_HIGH>, /* D10 - MB1/2 POCI */ 21 | <&gpio0 26 GPIO_ACTIVE_HIGH>, /* D11 - MB1/2 SDA - A2 */ 22 | <&gpio0 25 GPIO_ACTIVE_HIGH>, /* D12 - MB1/2 SCL - A3 */ 23 | <&gpio0 12 GPIO_ACTIVE_HIGH>, /* D13 - MB1 UART0 RX */ 24 | <&gpio0 13 GPIO_ACTIVE_HIGH>, /* D14 - MB1 UART0 TX */ 25 | <&gpio0 23 GPIO_ACTIVE_HIGH>, /* D15 - MB1 AN - A0 */ 26 | <&gpio0 24 GPIO_ACTIVE_HIGH>, /* D16 - MB2 AN - A1 */ 27 | <&gpio0 5 GPIO_ACTIVE_HIGH>, /* D17 - MB2 RST */ 28 | <&gpio0 6 GPIO_ACTIVE_HIGH>, /* D18 - MB1 RST */ 29 | <&gpio0 7 GPIO_ACTIVE_HIGH>, /* D19 - on-board sensor INT */ 30 | <&gpio0 8 GPIO_ACTIVE_HIGH>, /* D20 - flash CS */ 31 | <&gpio0 14 GPIO_ACTIVE_HIGH>, /* D21 - on-board sensor I2C enable */ 32 | <&gpio0 15 GPIO_ACTIVE_HIGH>, /* D22 - BOOT button */ 33 | <&gpio0 18 GPIO_ACTIVE_HIGH>; /* D23 - LINK LED */ 34 | 35 | pwm-pin-gpios = 36 | <&gpio0 17 GPIO_ACTIVE_HIGH>, /* D2 - MB1 PWM */ 37 | <&gpio0 19 GPIO_ACTIVE_HIGH>; /* D6 - MB2 PWM */ 38 | 39 | pwms = <&pwm0 0 255 PWM_POLARITY_NORMAL>, 40 | <&pwm1 0 255 PWM_POLARITY_NORMAL>; 41 | 42 | adc-pin-gpios = 43 | <&gpio0 23 GPIO_ACTIVE_HIGH>, /* D15 - MB1 AN - A0 */ 44 | <&gpio0 24 GPIO_ACTIVE_HIGH>, /* D16 - MB2 AN - A1 */ 45 | <&gpio0 26 GPIO_ACTIVE_HIGH>, /* D11 - MB1/2 SDA - A2 */ 46 | <&gpio0 25 GPIO_ACTIVE_HIGH>, /* D12 - MB1/2 SCL - A3 */ 47 | <&gpio0 27 GPIO_ACTIVE_HIGH>, /* D7 - MB2 CS - A4 */ 48 | <&gpio0 28 GPIO_ACTIVE_HIGH>; /* D3 - MB1 CS - A5 */ 49 | 50 | io-channels = <&adc0 0x09>, <&adc0 0x0a>, <&adc0 0x0b>, <&adc0 0x0c>, <&adc0 0x0d>, <&adc0 0x0e>; 51 | 52 | adc-pin-gpios = 53 | <&gpio0 23 GPIO_ACTIVE_HIGH>, /* D15 - MB1 AN - A0 */ 54 | <&gpio0 24 GPIO_ACTIVE_HIGH>, /* D16 - MB2 AN - A1 */ 55 | <&gpio0 26 GPIO_ACTIVE_HIGH>, /* D11 - MB1/2 SDA - A2 */ 56 | <&gpio0 25 GPIO_ACTIVE_HIGH>, /* D12 - MB1/2 SCL - A3 */ 57 | <&gpio0 27 GPIO_ACTIVE_HIGH>, /* D7 - MB2 CS - A4 */ 58 | <&gpio0 28 GPIO_ACTIVE_HIGH>; /* D3 - MB1 CS - A5 */ 59 | 60 | builtin-led-gpios = <&gpio0 18 GPIO_ACTIVE_HIGH>; /* 2.4GHz TX/RX */ 61 | serials = <&uart0 &uart1>; 62 | i2cs = <&i2c0>; 63 | spis = <&spi0>; 64 | }; 65 | }; 66 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | 3 | if (CONFIG_ARDUINO_API) 4 | if (IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/variants/${BOARD}${NORMALIZED_BOARD_QUALIFIERS}) 5 | set(variant_dir variants/${BOARD}${NORMALIZED_BOARD_QUALIFIERS}) 6 | else() 7 | message(FATAL_ERROR "Variant dir not found: variants/${BOARD}${NORMALIZED_BOARD_QUALIFIERS}") 8 | endif() 9 | 10 | add_subdirectory(cores) 11 | add_subdirectory(libraries) 12 | zephyr_include_directories(${variant_dir}) 13 | 14 | if (CONFIG_USE_ARDUINO_API_RUST_IMPLEMENTATION) 15 | # quote from https://github.com/zephyrproject-rtos/zephyr-lang-rust/blob/main/CMakeLists.txt 16 | function (rust_target_arch RUST_TARGET) 17 | # Map Zephyr targets to LLVM targets. 18 | if(CONFIG_CPU_CORTEX_M) 19 | if(CONFIG_CPU_CORTEX_M0 OR CONFIG_CPU_CORTEX_M0PLUS OR CONFIG_CPU_CORTEX_M1) 20 | set(${RUST_TARGET} "thumbv6m-none-eabi" PARENT_SCOPE) 21 | elseif(CONFIG_CPU_CORTEX_M3) 22 | set(${RUST_TARGET} "thumbv7m-none-eabi" PARENT_SCOPE) 23 | elseif(CONFIG_CPU_CORTEX_M4 OR CONFIG_CPU_CORTEX_M7) 24 | if(CONFIG_FP_HARDABI OR FORCE_FP_HARDABI) 25 | set(${RUST_TARGET} "thumbv7em-none-eabihf" PARENT_SCOPE) 26 | else() 27 | set(${RUST_TARGET} "thumbv7em-none-eabi" PARENT_SCOPE) 28 | endif() 29 | elseif(CONFIG_CPU_CORTEX_M23) 30 | set(${RUST_TARGET} "thumbv8m.base-none-eabi" PARENT_SCOPE) 31 | elseif(CONFIG_CPU_CORTEX_M33 OR CONFIG_CPU_CORTEX_M55) 32 | # Not a typo, Zephyr, uses ARMV7_M_ARMV8_M_FP to select the FP even on v8m. 33 | if(CONFIG_FP_HARDABI OR FORCE_FP_HARDABI) 34 | set(${RUST_TARGET} "thumbv8m.main-none-eabihf" PARENT_SCOPE) 35 | else() 36 | set(${RUST_TARGET} "thumbv8m.main-none-eabi" PARENT_SCOPE) 37 | endif() 38 | 39 | # Todo: The M55 is thumbv8.1m.main-none-eabi, which can be added when Rust 40 | # gain support for this target. 41 | else() 42 | message(FATAL_ERROR "Unknown Cortex-M target.") 43 | endif() 44 | elseif(CONFIG_RISCV) 45 | if(CONFIG_RISCV_ISA_RV64I) 46 | # TODO: Should fail if the extensions don't match. 47 | set(${RUST_TARGET} "riscv64imac-unknown-none-elf" PARENT_SCOPE) 48 | elseif(CONFIG_RISCV_ISA_RV32I) 49 | # TODO: We have multiple choices, try to pick the best. 50 | set(${RUST_TARGET} "riscv32i-unknown-none-elf" PARENT_SCOPE) 51 | else() 52 | message(FATAL_ERROR "Rust: Unsupported riscv ISA") 53 | endif() 54 | elseif(CONFIG_ARCH_POSIX AND CONFIG_64BIT AND (${CMAKE_HOST_SYSTEM_PROCESSOR} MATCHES "x86_64")) 55 | set(${RUST_TARGET} "x86_64-unknown-none" PARENT_SCOPE) 56 | elseif(CONFIG_ARCH_POSIX AND CONFIG_64BIT AND (${CMAKE_HOST_SYSTEM_PROCESSOR} MATCHES "aarch64")) 57 | set(${RUST_TARGET} "aarch64-unknown-none" PARENT_SCOPE) 58 | else() 59 | message(FATAL_ERROR "Rust: Add support for other target") 60 | endif() 61 | endfunction() 62 | 63 | rust_target_arch(RUST_TARGET_TRIPLE) 64 | 65 | set(RUST_CRATE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/rust) 66 | set(RUST_OUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/rust) 67 | set(RUST_LIB ${RUST_OUT_DIR}/target/${RUST_TARGET_TRIPLE}/release/libarduinocore_api_rust.a) 68 | 69 | add_custom_command( 70 | OUTPUT ${RUST_LIB} 71 | COMMAND ${CMAKE_COMMAND} -E env CARGO_TARGET_DIR=${RUST_OUT_DIR}/target 72 | cargo build --manifest-path ${RUST_CRATE_DIR}/Cargo.toml 73 | --target ${RUST_TARGET_TRIPLE} --release 74 | WORKING_DIRECTORY ${RUST_CRATE_DIR} 75 | COMMENT "Building Rust staticlib for ${RUST_TARGET}" 76 | VERBATIM 77 | ) 78 | 79 | add_custom_target(arduinocore_api_rust_build ALL DEPENDS ${RUST_LIB}) 80 | add_library(arduinocore_api_rust STATIC IMPORTED GLOBAL) 81 | set_target_properties(arduinocore_api_rust PROPERTIES IMPORTED_LOCATION ${RUST_LIB}) 82 | zephyr_link_libraries(arduinocore_api_rust) 83 | endif() 84 | 85 | endif() 86 | -------------------------------------------------------------------------------- /libraries/Wire/Wire.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Dhruva Gole 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | arduino::ZephyrI2C::ZephyrI2C(const struct device *i2c) : i2c_dev(i2c) 11 | { 12 | } 13 | 14 | void arduino::ZephyrI2C::begin() { 15 | ring_buf_init(&rxRingBuffer.rb, sizeof(rxRingBuffer.buffer), rxRingBuffer.buffer); 16 | } 17 | 18 | void arduino::ZephyrI2C::begin(uint8_t slaveAddr) { 19 | 20 | } 21 | 22 | void arduino::ZephyrI2C::end() {} 23 | 24 | void arduino::ZephyrI2C::setClock(uint32_t freq) {} 25 | 26 | void arduino::ZephyrI2C::beginTransmission(uint8_t address) { // TODO for ADS1115 27 | _address = address; 28 | usedTxBuffer = 0; 29 | } 30 | 31 | uint8_t arduino::ZephyrI2C::endTransmission(bool stopBit) { 32 | int ret = i2c_write(i2c_dev, txBuffer, usedTxBuffer, _address); 33 | if (ret) { 34 | return 1; // fail 35 | } 36 | return 0; 37 | } 38 | 39 | uint8_t arduino::ZephyrI2C::endTransmission(void) { // TODO for ADS1115 40 | return endTransmission(true); 41 | } 42 | 43 | size_t arduino::ZephyrI2C::requestFrom(uint8_t address, size_t len, 44 | bool stopBit) { 45 | int ret = i2c_read(i2c_dev, rxRingBuffer.buffer, len, address); 46 | if (ret != 0) 47 | { 48 | printk("\n\nERR: i2c burst read fails\n\n\n"); 49 | return 0; 50 | } 51 | ret = ring_buf_put(&rxRingBuffer.rb, rxRingBuffer.buffer, len); 52 | if (ret == 0) 53 | { 54 | printk("\n\nERR: buff put fails\n\n\n"); 55 | return 0; 56 | } 57 | return len; 58 | } 59 | 60 | size_t arduino::ZephyrI2C::requestFrom(uint8_t address, size_t len) { // TODO for ADS1115 61 | return requestFrom(address, len, true); 62 | } 63 | 64 | size_t arduino::ZephyrI2C::write(uint8_t data) { // TODO for ADS1115 65 | txBuffer[usedTxBuffer++] = data; 66 | return 1; 67 | } 68 | 69 | size_t arduino::ZephyrI2C::write(const uint8_t *buffer, size_t size) { 70 | if (usedTxBuffer + size > 256) { 71 | size = 256 - usedTxBuffer; 72 | } 73 | memcpy(txBuffer + usedTxBuffer, buffer, size); 74 | usedTxBuffer += size; 75 | return size; 76 | } 77 | 78 | int arduino::ZephyrI2C::read() { 79 | uint8_t buf[1]; 80 | if (ring_buf_peek(&rxRingBuffer.rb, buf, 1) > 0) { 81 | int ret = ring_buf_get(&rxRingBuffer.rb, buf, 1); 82 | if (ret == 0) { 83 | printk("\n\nERR: buff empty\n\n\n"); 84 | return 0; 85 | } 86 | return (int)buf[0]; 87 | } 88 | return EXIT_FAILURE; 89 | } 90 | 91 | int arduino::ZephyrI2C::available() { // TODO for ADS1115 92 | return !ring_buf_is_empty(&rxRingBuffer.rb); // ret 0 if empty 93 | } 94 | 95 | int arduino::ZephyrI2C::peek() { 96 | uint8_t buf[1]; 97 | int bytes_read = ring_buf_peek(&rxRingBuffer.rb, buf, 1); 98 | if (bytes_read == 0){ 99 | return 0; 100 | } 101 | return (int)buf[0]; 102 | } 103 | 104 | void arduino::ZephyrI2C::flush() {} 105 | 106 | void arduino::ZephyrI2C::onReceive(voidFuncPtrParamInt cb) {} 107 | void arduino::ZephyrI2C::onRequest(voidFuncPtr cb) {} 108 | 109 | #if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), i2cs) 110 | #if (DT_PROP_LEN(DT_PATH(zephyr_user), i2cs) > 1) 111 | #define ARDUINO_WIRE_DEFINED_0 1 112 | #define DECL_WIRE_0(n, p, i) arduino::ZephyrI2C Wire(DEVICE_DT_GET(DT_PHANDLE_BY_IDX(n, p, i))); 113 | #define DECL_WIRE_N(n, p, i) arduino::ZephyrI2C Wire##i(DEVICE_DT_GET(DT_PHANDLE_BY_IDX(n, p, i))); 114 | #define DECLARE_WIRE_N(n, p, i) \ 115 | COND_CODE_1(ARDUINO_WIRE_DEFINED_##i, (DECL_WIRE_0(n, p, i)), (DECL_WIRE_N(n, p, i))) 116 | 117 | /* Declare Wire, Wire1, Wire2, ... */ 118 | DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user), i2cs, DECLARE_WIRE_N) 119 | 120 | #undef DECLARE_WIRE_N 121 | #undef DECL_WIRE_N 122 | #undef DECL_WIRE_0 123 | #undef ARDUINO_WIRE_DEFINED_0 124 | #else // PROP_LEN(i2cs) > 1 125 | /* When PROP_LEN(i2cs) == 1, DT_FOREACH_PROP_ELEM work not correctly. */ 126 | arduino::ZephyrI2C Wire(DEVICE_DT_GET(DT_PHANDLE_BY_IDX(DT_PATH(zephyr_user), i2cs, 0))); 127 | #endif // HAS_PORP(i2cs) 128 | /* If i2cs node is not defined, tries to use arduino_i2c */ 129 | #elif DT_NODE_EXISTS(DT_NODELABEL(arduino_i2c)) 130 | arduino::ZephyrI2C Wire(DEVICE_DT_GET(DT_NODELABEL(arduino_i2c))); 131 | #endif 132 | -------------------------------------------------------------------------------- /variants/arduino_mkrzero_samd21g18a/arduino_mkrzero_samd21g18a.overlay: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Dhruva Gole 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include 8 | 9 | / { 10 | zephyr,user { 11 | digital-pin-gpios = <&arduino_mkr_header 0 0>, 12 | <&arduino_mkr_header 1 0>, 13 | <&arduino_mkr_header 2 0>, 14 | <&arduino_mkr_header 3 0>, 15 | <&arduino_mkr_header 4 0>, 16 | <&arduino_mkr_header 5 0>, 17 | <&arduino_mkr_header 6 0>, 18 | <&arduino_mkr_header 7 0>, 19 | <&arduino_mkr_header 8 0>, 20 | <&arduino_mkr_header 9 0>, 21 | <&arduino_mkr_header 10 0>, 22 | <&arduino_mkr_header 11 0>, 23 | <&arduino_mkr_header 12 0>, 24 | <&arduino_mkr_header 13 0>, 25 | <&arduino_mkr_header 14 0>, /* D14 / A0 */ 26 | <&arduino_mkr_header 15 0>, 27 | <&arduino_mkr_header 16 0>, 28 | <&arduino_mkr_header 17 0>, 29 | <&arduino_mkr_header 18 0>, /* D18 / A4 / I2C-SDA */ 30 | <&arduino_mkr_header 19 0>, /* D19 / A5 / I2C-SCL */ 31 | <&arduino_mkr_header 20 0>, 32 | <&arduino_mkr_header 21 0>, 33 | <&portb 8 0>; 34 | 35 | pwm-pin-gpios = <&arduino_mkr_header 2 0>, 36 | <&arduino_mkr_header 3 0>; 37 | 38 | adc-pin-gpios = <&arduino_mkr_header 15 0>, 39 | <&arduino_mkr_header 16 0>, 40 | <&arduino_mkr_header 17 0>, 41 | <&arduino_mkr_header 18 0>, 42 | <&arduino_mkr_header 19 0>, 43 | <&arduino_mkr_header 20 0>, 44 | <&arduino_mkr_header 21 0>; 45 | 46 | pwms = <&tcc0 2 255>, 47 | <&tcc0 3 255>; 48 | 49 | io-channels = <&adc 0>, 50 | <&adc 10>, 51 | <&adc 11>, 52 | <&adc 4>, 53 | <&adc 5>, 54 | <&adc 6>, 55 | <&adc 7>; 56 | 57 | serials = <&sercom5>; 58 | i2cs = <&sercom0>; 59 | }; 60 | }; 61 | 62 | &pinctrl { 63 | pwm_default: pwm_default { 64 | group1 { 65 | pinmux = , 66 | ; 67 | }; 68 | }; 69 | 70 | adc_default: adc_default { 71 | group1 { 72 | pinmux = , 73 | , 74 | , 75 | , 76 | , 77 | , 78 | ; 79 | }; 80 | }; 81 | }; 82 | 83 | &tcc0 { 84 | status = "okay"; 85 | compatible = "atmel,sam0-tcc-pwm"; 86 | prescaler = <2>; 87 | #pwm-cells = <2>; 88 | 89 | pinctrl-0 = <&pwm_default>; 90 | pinctrl-names = "default"; 91 | }; 92 | 93 | &adc { 94 | status = "okay"; 95 | pinctrl-0 = <&adc_default>; 96 | pinctrl-names = "default"; 97 | 98 | #address-cells = <1>; 99 | #size-cells = <0>; 100 | 101 | channel@0 { 102 | reg = <0x0>; 103 | zephyr,gain = "ADC_GAIN_1"; 104 | zephyr,reference = "ADC_REF_INTERNAL"; 105 | zephyr,acquisition-time = ; 106 | zephyr,resolution = <10>; 107 | zephyr,input-positive = <0>; 108 | }; 109 | 110 | channel@4 { 111 | reg = <0x4>; 112 | zephyr,gain = "ADC_GAIN_1"; 113 | zephyr,reference = "ADC_REF_INTERNAL"; 114 | zephyr,acquisition-time = ; 115 | zephyr,resolution = <10>; 116 | zephyr,input-positive = <4>; 117 | }; 118 | 119 | channel@5 { 120 | reg = <0x5>; 121 | zephyr,gain = "ADC_GAIN_1"; 122 | zephyr,reference = "ADC_REF_INTERNAL"; 123 | zephyr,acquisition-time = ; 124 | zephyr,resolution = <10>; 125 | zephyr,input-positive = <5>; 126 | }; 127 | 128 | channel@6 { 129 | reg = <0x6>; 130 | zephyr,gain = "ADC_GAIN_1"; 131 | zephyr,reference = "ADC_REF_INTERNAL"; 132 | zephyr,acquisition-time = ; 133 | zephyr,resolution = <10>; 134 | zephyr,input-positive = <6>; 135 | }; 136 | 137 | channel@7 { 138 | reg = <0x7>; 139 | zephyr,gain = "ADC_GAIN_1"; 140 | zephyr,reference = "ADC_REF_INTERNAL"; 141 | zephyr,acquisition-time = ; 142 | zephyr,resolution = <10>; 143 | zephyr,input-positive = <7>; 144 | }; 145 | 146 | channel@a { 147 | reg = <0xa>; 148 | zephyr,gain = "ADC_GAIN_1"; 149 | zephyr,reference = "ADC_REF_INTERNAL"; 150 | zephyr,acquisition-time = ; 151 | zephyr,resolution = <10>; 152 | zephyr,input-positive = <10>; 153 | }; 154 | 155 | channel@b { 156 | reg = <0xb>; 157 | zephyr,gain = "ADC_GAIN_1"; 158 | zephyr,reference = "ADC_REF_INTERNAL"; 159 | zephyr,acquisition-time = ; 160 | zephyr,resolution = <10>; 161 | zephyr,input-positive = <11>; 162 | }; 163 | }; 164 | -------------------------------------------------------------------------------- /libraries/SPI/SPI.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024 Ayush Singh 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include "SPI.h" 8 | #include "zephyrInternal.h" 9 | #include 10 | 11 | /* Serial Peripheral Control Register */ 12 | uint8_t SPCR; 13 | 14 | arduino::ZephyrSPI::ZephyrSPI(const struct device *spi) : spi_dev(spi) {} 15 | 16 | uint8_t arduino::ZephyrSPI::transfer(uint8_t data) { 17 | int ret; 18 | uint8_t rx; 19 | const struct spi_buf tx_buf = {.buf = &data, .len = sizeof(data)}; 20 | const struct spi_buf_set tx_buf_set = { 21 | .buffers = &tx_buf, 22 | .count = 1, 23 | }; 24 | const struct spi_buf rx_buf = {.buf = &rx, .len = sizeof(rx)}; 25 | const struct spi_buf_set rx_buf_set = { 26 | .buffers = &rx_buf, 27 | .count = 1, 28 | }; 29 | 30 | ret = spi_transceive(spi_dev, &config, &tx_buf_set, &rx_buf_set); 31 | if (ret < 0) { 32 | return 0; 33 | } 34 | 35 | return rx; 36 | } 37 | 38 | uint16_t arduino::ZephyrSPI::transfer16(uint16_t data) { 39 | int ret; 40 | uint16_t rx; 41 | const struct spi_buf tx_buf = {.buf = &data, .len = sizeof(data)}; 42 | const struct spi_buf_set tx_buf_set = { 43 | .buffers = &tx_buf, 44 | .count = 1, 45 | }; 46 | const struct spi_buf rx_buf = {.buf = &rx, .len = sizeof(rx)}; 47 | const struct spi_buf_set rx_buf_set = { 48 | .buffers = &rx_buf, 49 | .count = 1, 50 | }; 51 | 52 | ret = spi_transceive(spi_dev, &config, &tx_buf_set, &rx_buf_set); 53 | if (ret < 0) { 54 | return 0; 55 | } 56 | 57 | return rx; 58 | } 59 | 60 | void arduino::ZephyrSPI::transfer(void *buf, size_t count) { 61 | int ret; 62 | const struct spi_buf tx_buf = {.buf = buf, .len = count}; 63 | const struct spi_buf_set tx_buf_set = { 64 | .buffers = &tx_buf, 65 | .count = 1, 66 | }; 67 | 68 | ret = spi_write(spi_dev, &config, &tx_buf_set); 69 | if (ret < 0) { 70 | return; 71 | } 72 | 73 | ret = spi_read(spi_dev, &config, &tx_buf_set); 74 | if (ret < 0) { 75 | return; 76 | } 77 | } 78 | 79 | void arduino::ZephyrSPI::usingInterrupt(int interruptNumber) { 80 | interrupt[interrupt_pos++] = interruptNumber; 81 | } 82 | 83 | void arduino::ZephyrSPI::notUsingInterrupt(int interruptNumber) { 84 | for (size_t i = 0; i < interrupt_pos; ++i) { 85 | if (interrupt[i] == interruptNumber) { 86 | memmove(&interrupt[i], &interrupt[i + 1], interrupt_pos - i - 1); 87 | interrupt_pos--; 88 | break; 89 | } 90 | } 91 | } 92 | 93 | void arduino::ZephyrSPI::beginTransaction(SPISettings settings) { 94 | memset(&config, 0, sizeof(config)); 95 | config.frequency = settings.getClockFreq(); 96 | config.operation = ((settings.getBitOrder() ^ 1) << 4) | 97 | (settings.getDataMode() << 1) | ((SPCR >> MSTR) & 1) | 98 | SPI_WORD_SET(8); 99 | 100 | detachInterrupt(); 101 | } 102 | 103 | void arduino::ZephyrSPI::endTransaction(void) { 104 | spi_release(spi_dev, &config); 105 | attachInterrupt(); 106 | } 107 | 108 | void arduino::ZephyrSPI::attachInterrupt() { 109 | for (size_t i = 0; i < interrupt_pos; ++i) { 110 | enableInterrupt(interrupt[i]); 111 | } 112 | } 113 | 114 | void arduino::ZephyrSPI::detachInterrupt() { 115 | for (size_t i = 0; i < interrupt_pos; ++i) { 116 | disableInterrupt(interrupt[i]); 117 | } 118 | } 119 | 120 | void arduino::ZephyrSPI::begin() {} 121 | 122 | void arduino::ZephyrSPI::end() {} 123 | 124 | #if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), spis) 125 | #if (DT_PROP_LEN(DT_PATH(zephyr_user), spis) > 1) 126 | #define ARDUINO_SPI_DEFINED_0 1 127 | #define DECL_SPI_0(n, p, i) arduino::ZephyrSPI SPI(DEVICE_DT_GET(DT_PHANDLE_BY_IDX(n, p, i))); 128 | #define DECL_SPI_N(n, p, i) arduino::ZephyrSPI SPI##i(DEVICE_DT_GET(DT_PHANDLE_BY_IDX(n, p, i))); 129 | #define DECLARE_SPI_N(n, p, i) \ 130 | COND_CODE_1(ARDUINO_SPI_DEFINED_##i, (DECL_SPI_0(n, p, i)), (DECL_SPI_N(n, p, i))) 131 | 132 | /* Declare SPI, SPI1, SPI2, ... */ 133 | DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user), spis, DECLARE_SPI_N) 134 | 135 | #undef DECLARE_SPI_N 136 | #undef DECL_SPI_N 137 | #undef DECL_SPI_0 138 | #undef ARDUINO_SPI_DEFINED_0 139 | #else // PROP_LEN(spis) > 1 140 | /* When PROP_LEN(spis) == 1, DT_FOREACH_PROP_ELEM work not correctly. */ 141 | arduino::ZephyrSPI SPI(DEVICE_DT_GET(DT_PHANDLE_BY_IDX(DT_PATH(zephyr_user), spis, 0))); 142 | #endif // HAS_PORP(spis) 143 | /* If spis node is not defined, tries to use arduino_spi */ 144 | #elif DT_NODE_EXISTS(DT_NODELABEL(arduino_spi)) 145 | arduino::ZephyrSPI SPI(DEVICE_DT_GET(DT_NODELABEL(arduino_spi))); 146 | #endif 147 | -------------------------------------------------------------------------------- /cores/arduino/Arduino.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Dhruva Gole 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #define DIGITAL_PIN_EXISTS(n, p, i, dev, num) \ 18 | (((dev == DT_REG_ADDR(DT_PHANDLE_BY_IDX(n, p, i))) && \ 19 | (num == DT_PHA_BY_IDX(n, p, i, pin))) \ 20 | ? 1 \ 21 | : 0) 22 | 23 | /* Check all pins are defined only once */ 24 | #define DIGITAL_PIN_CHECK_UNIQUE(i, _) \ 25 | ((DT_FOREACH_PROP_ELEM_SEP_VARGS( \ 26 | DT_PATH(zephyr_user), digital_pin_gpios, DIGITAL_PIN_EXISTS, (+), \ 27 | DT_REG_ADDR(DT_PHANDLE_BY_IDX(DT_PATH(zephyr_user), digital_pin_gpios, i)), \ 28 | DT_PHA_BY_IDX(DT_PATH(zephyr_user), digital_pin_gpios, i, pin))) == 1) 29 | 30 | #if !LISTIFY(DT_PROP_LEN(DT_PATH(zephyr_user), digital_pin_gpios), DIGITAL_PIN_CHECK_UNIQUE, (&&)) 31 | #error "digital_pin_gpios has duplicate definition" 32 | #endif 33 | 34 | #undef DIGITAL_PIN_CHECK_UNIQUE 35 | 36 | #ifndef LED_BUILTIN 37 | 38 | /* Return the index of it if matched, oterwise return 0 */ 39 | #define LED_BUILTIN_INDEX_BY_REG_AND_PINNUM(n, p, i, dev, num) \ 40 | (DIGITAL_PIN_EXISTS(n, p, i, dev, num) ? i : 0) 41 | 42 | /* Only matched pin returns non-zero value, so the sum is matched pin's index */ 43 | #define DIGITAL_PIN_GPIOS_FIND_PIN(dev, pin) \ 44 | DT_FOREACH_PROP_ELEM_SEP_VARGS(DT_PATH(zephyr_user), digital_pin_gpios, \ 45 | LED_BUILTIN_INDEX_BY_REG_AND_PINNUM, (+), dev, pin) 46 | 47 | #if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), builtin_led_gpios) && \ 48 | (DT_PROP_LEN(DT_PATH(zephyr_user), builtin_led_gpios) > 0) 49 | 50 | #if !(DT_FOREACH_PROP_ELEM_SEP_VARGS( \ 51 | DT_PATH(zephyr_user), digital_pin_gpios, DIGITAL_PIN_EXISTS, (+), \ 52 | DT_REG_ADDR(DT_PHANDLE_BY_IDX(DT_PATH(zephyr_user), builtin_led_gpios, 0)), \ 53 | DT_PHA_BY_IDX(DT_PATH(zephyr_user), builtin_led_gpios, 0, pin)) > 0) 54 | #warning "pin not found in digital_pin_gpios" 55 | #else 56 | #define LED_BUILTIN \ 57 | DIGITAL_PIN_GPIOS_FIND_PIN( \ 58 | DT_REG_ADDR(DT_PHANDLE_BY_IDX(DT_PATH(zephyr_user), builtin_led_gpios, 0)), \ 59 | DT_PHA_BY_IDX(DT_PATH(zephyr_user), builtin_led_gpios, 0, pin)) 60 | #endif 61 | 62 | /* If digital-pin-gpios is not defined, tries to use the led0 alias */ 63 | #elif DT_NODE_EXISTS(DT_ALIAS(led0)) 64 | 65 | #if !(DT_FOREACH_PROP_ELEM_SEP_VARGS(DT_PATH(zephyr_user), digital_pin_gpios, DIGITAL_PIN_EXISTS, \ 66 | (+), DT_REG_ADDR(DT_PHANDLE_BY_IDX(DT_ALIAS(led0), gpios, 0)), \ 67 | DT_PHA_BY_IDX(DT_ALIAS(led0), gpios, 0, pin)) > 0) 68 | #warning "pin not found in digital_pin_gpios" 69 | #else 70 | #define LED_BUILTIN \ 71 | DIGITAL_PIN_GPIOS_FIND_PIN(DT_REG_ADDR(DT_PHANDLE_BY_IDX(DT_ALIAS(led0), gpios, 0)), \ 72 | DT_PHA_BY_IDX(DT_ALIAS(led0), gpios, 0, pin)) 73 | #endif 74 | 75 | #endif // builtin_led_gpios 76 | 77 | #endif // LED_BUILTIN 78 | 79 | #define DN_ENUMS(n, p, i) D##i = i 80 | 81 | /* 82 | * expand as 83 | * enum digitalPins { D0, D1, ... LED... NUM_OF_DIGITAL_PINS }; 84 | */ 85 | enum digitalPins { 86 | DT_FOREACH_PROP_ELEM_SEP(DT_PATH(zephyr_user), digital_pin_gpios, DN_ENUMS, (, )), 87 | NUM_OF_DIGITAL_PINS 88 | }; 89 | 90 | #ifdef CONFIG_ADC 91 | 92 | #define AN_ENUMS(n, p, i) A ## i = DIGITAL_PIN_GPIOS_FIND_PIN( \ 93 | DT_REG_ADDR(DT_PHANDLE_BY_IDX(DT_PATH(zephyr_user), p, i)), \ 94 | DT_PHA_BY_IDX(DT_PATH(zephyr_user), p, i, pin)), 95 | enum analogPins { DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user), 96 | adc_pin_gpios, AN_ENUMS) }; 97 | 98 | #endif 99 | 100 | void interrupts(void); 101 | void noInterrupts(void); 102 | 103 | int digitalPinToInterrupt(pin_size_t pin); 104 | 105 | #include 106 | #ifdef __cplusplus 107 | #include 108 | #include 109 | #endif // __cplusplus 110 | -------------------------------------------------------------------------------- /variants/rpi_pico_rp2040/rpi_pico_rp2040.overlay: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024 TOKITA Hiroshi 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include 8 | 9 | / { 10 | zephyr,user { 11 | digital-pin-gpios = <&pico_header 0 0>, 12 | <&pico_header 1 0>, 13 | <&pico_header 2 0>, 14 | <&pico_header 3 0>, 15 | <&pico_header 4 0>, 16 | <&pico_header 5 0>, 17 | <&pico_header 6 0>, 18 | <&pico_header 7 0>, 19 | <&pico_header 8 0>, 20 | <&pico_header 9 0>, 21 | <&pico_header 10 0>, 22 | <&pico_header 11 0>, 23 | <&pico_header 12 0>, 24 | <&pico_header 13 0>, 25 | <&pico_header 14 0>, 26 | <&pico_header 15 0>, 27 | <&pico_header 16 0>, 28 | <&pico_header 17 0>, 29 | <&pico_header 18 0>, 30 | <&pico_header 19 0>, 31 | <&pico_header 20 0>, 32 | <&pico_header 21 0>, 33 | <&pico_header 22 0>, 34 | <&gpio0 23 0>, 35 | <&gpio0 24 0>, 36 | <&gpio0 25 0>, 37 | <&pico_header 26 0>, 38 | <&pico_header 27 0>, 39 | <&pico_header 28 0>; 40 | 41 | builtin-led-gpios = <&gpio0 25 0>; 42 | 43 | pwm-pin-gpios = <&pico_header 2 0>, 44 | <&pico_header 3 0>, 45 | <&pico_header 7 0>, 46 | <&pico_header 8 0>, 47 | <&pico_header 10 0>, 48 | <&pico_header 11 0>, 49 | <&pico_header 12 0>, 50 | <&pico_header 13 0>, 51 | <&pico_header 14 0>, 52 | <&pico_header 15 0>, 53 | <&pico_header 20 0>, 54 | <&pico_header 21 0>, 55 | <&pico_header 22 0>, 56 | <&gpio0 25 0>; 57 | 58 | adc-pin-gpios = <&pico_header 26 0>, 59 | <&pico_header 27 0>, 60 | <&pico_header 28 0>; 61 | 62 | pwms = <&pwm 2 255 PWM_POLARITY_NORMAL>, 63 | <&pwm 3 255 PWM_POLARITY_NORMAL>, 64 | <&pwm 7 255 PWM_POLARITY_NORMAL>, 65 | <&pwm 8 255 PWM_POLARITY_NORMAL>, 66 | <&pwm 10 255 PWM_POLARITY_NORMAL>, 67 | <&pwm 11 255 PWM_POLARITY_NORMAL>, 68 | <&pwm 12 255 PWM_POLARITY_NORMAL>, 69 | <&pwm 13 255 PWM_POLARITY_NORMAL>, 70 | <&pwm 14 255 PWM_POLARITY_NORMAL>, 71 | <&pwm 15 255 PWM_POLARITY_NORMAL>, 72 | <&pwm 4 255 PWM_POLARITY_NORMAL>, 73 | <&pwm 5 255 PWM_POLARITY_NORMAL>, 74 | <&pwm 6 255 PWM_POLARITY_NORMAL>, 75 | <&pwm 9 255 PWM_POLARITY_NORMAL>; 76 | 77 | io-channels = <&adc 0>, 78 | <&adc 1>, 79 | <&adc 2>; 80 | 81 | serials = <&pico_serial>; 82 | i2cs = <&pico_i2c0>; 83 | spis = <&pico_spi>; 84 | }; 85 | }; 86 | 87 | &pinctrl { 88 | pwm_ch1a_default: pwm_ch1a_default { 89 | group1 { 90 | pinmux = ; 91 | }; 92 | }; 93 | 94 | pwm_ch1b_default: pwm_ch1b_default { 95 | group1 { 96 | pinmux = ; 97 | }; 98 | }; 99 | 100 | pwm_ch2a_default: pwm_ch2a_default { 101 | group1 { 102 | pinmux = ; 103 | }; 104 | }; 105 | 106 | pwm_ch2b_default: pwm_ch2b_default { 107 | group1 { 108 | pinmux = ; 109 | }; 110 | }; 111 | 112 | pwm_ch3a_default: pwm_ch3a_default { 113 | group1 { 114 | pinmux = ; 115 | }; 116 | }; 117 | 118 | pwm_ch3b_default: pwm_ch3b_default { 119 | group1 { 120 | pinmux = ; 121 | }; 122 | }; 123 | 124 | pwm_ch4a_default: pwm_ch4a_default { 125 | group1 { 126 | pinmux = ; 127 | }; 128 | }; 129 | 130 | pwm_ch5a_default: pwm_ch5a_default { 131 | group1 { 132 | pinmux = ; 133 | }; 134 | }; 135 | 136 | pwm_ch5b_default: pwm_ch5b_default { 137 | group1 { 138 | pinmux = ; 139 | }; 140 | }; 141 | 142 | pwm_ch6a_default: pwm_ch6a_default { 143 | group1 { 144 | pinmux = ; 145 | }; 146 | }; 147 | 148 | pwm_ch6b_default: pwm_ch6b_default { 149 | group1 { 150 | pinmux = ; 151 | }; 152 | }; 153 | 154 | pwm_ch7a_default: pwm_ch7a_default { 155 | group1 { 156 | pinmux = ; 157 | }; 158 | }; 159 | 160 | pwm_ch7b_default: pwm_ch7b_default { 161 | group1 { 162 | pinmux = ; 163 | }; 164 | }; 165 | }; 166 | 167 | &pwm { 168 | status = "okay"; 169 | divider-frac-4 = <15>; 170 | divider-int-4 = <255>; 171 | }; 172 | 173 | &adc { 174 | #address-cells = <1>; 175 | #size-cells = <0>; 176 | 177 | channel@0 { 178 | reg = <0>; 179 | zephyr,gain = "ADC_GAIN_1"; 180 | zephyr,reference = "ADC_REF_INTERNAL"; 181 | zephyr,acquisition-time = ; 182 | zephyr,resolution = <12>; 183 | }; 184 | 185 | channel@1 { 186 | reg = <1>; 187 | zephyr,gain = "ADC_GAIN_1"; 188 | zephyr,reference = "ADC_REF_INTERNAL"; 189 | zephyr,acquisition-time = ; 190 | zephyr,resolution = <12>; 191 | }; 192 | 193 | channel@2 { 194 | reg = <2>; 195 | zephyr,gain = "ADC_GAIN_1"; 196 | zephyr,reference = "ADC_REF_INTERNAL"; 197 | zephyr,acquisition-time = ; 198 | zephyr,resolution = <12>; 199 | }; 200 | }; 201 | -------------------------------------------------------------------------------- /variants/arduino_nano_33_iot_samd21g18a/arduino_nano_33_iot_samd21g18a.overlay: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | / { 4 | zephyr,user { 5 | digital-pin-gpios = <&arduino_nano_header 0 0>, 6 | <&arduino_nano_header 1 0>, 7 | <&arduino_nano_header 2 0>, 8 | <&arduino_nano_header 3 0>, 9 | <&arduino_nano_header 4 0>, 10 | <&arduino_nano_header 5 0>, 11 | <&arduino_nano_header 6 0>, 12 | <&arduino_nano_header 7 0>, 13 | <&arduino_nano_header 8 0>, 14 | <&arduino_nano_header 9 0>, 15 | <&arduino_nano_header 10 0>, 16 | <&arduino_nano_header 11 0>, 17 | <&arduino_nano_header 12 0>, 18 | <&arduino_nano_header 13 0>, 19 | <&arduino_nano_header 14 0>, /* D14 / A0 */ 20 | <&arduino_nano_header 15 0>, 21 | <&arduino_nano_header 16 0>, 22 | <&arduino_nano_header 17 0>, 23 | <&arduino_nano_header 18 0>, /* D18 / A4 / I2C-SDA */ 24 | <&arduino_nano_header 19 0>, /* D19 / A5 / I2C-SCL */ 25 | <&arduino_nano_header 20 0>, 26 | <&arduino_nano_header 21 0>; 27 | 28 | pwm-pin-gpios = <&arduino_nano_header 6 0>, 29 | <&arduino_nano_header 5 0>, 30 | <&arduino_nano_header 17 0>, 31 | <&arduino_nano_header 12 0>, 32 | <&arduino_nano_header 2 0>, 33 | <&arduino_nano_header 3 0>, 34 | <&arduino_nano_header 9 0>, 35 | <&arduino_nano_header 10 0>; 36 | 37 | adc-pin-gpios = <&arduino_nano_header 14 0>, 38 | <&arduino_nano_header 15 0>, 39 | <&arduino_nano_header 16 0>, 40 | <&arduino_nano_header 17 0>, 41 | <&arduino_nano_header 18 0>, 42 | <&arduino_nano_header 19 0>, 43 | <&arduino_nano_header 20 0>, 44 | <&arduino_nano_header 21 0>; 45 | 46 | pwms = <&tcc0 0 255>, 47 | <&tcc0 1 255>, 48 | <&tcc0 2 255>, 49 | <&tcc0 3 255>, 50 | <&tcc0 4 255>, 51 | <&tcc0 5 255>, 52 | <&tcc0 6 255>, 53 | <&tcc0 7 255>; 54 | 55 | io-channels = <&adc 0>, 56 | <&adc 10>, 57 | <&adc 11>, 58 | <&adc 4>, 59 | <&adc 5>, 60 | <&adc 6>, 61 | <&adc 7>; 62 | 63 | serials = <&sercom5>; 64 | i2cs = <&arduino_nano_i2c>; 65 | }; 66 | }; 67 | 68 | &pinctrl { 69 | pwm_default: pwm_default { 70 | group1 { 71 | pinmux = , 72 | , 73 | , 74 | , 75 | , 76 | , 77 | , 78 | ; 79 | }; 80 | }; 81 | 82 | adc_default: adc_default { 83 | group1 { 84 | pinmux = , 85 | , 86 | , 87 | , 88 | , 89 | , 90 | , 91 | ; 92 | }; 93 | }; 94 | }; 95 | 96 | &tcc0 { 97 | status = "okay"; 98 | compatible = "atmel,sam0-tcc-pwm"; 99 | prescaler = <2>; 100 | #pwm-cells = <2>; 101 | 102 | pinctrl-0 = <&pwm_default>; 103 | pinctrl-names = "default"; 104 | }; 105 | 106 | &adc { 107 | status = "okay"; 108 | pinctrl-0 = <&adc_default>; 109 | pinctrl-names = "default"; 110 | 111 | #address-cells = <1>; 112 | #size-cells = <0>; 113 | 114 | channel@0 { 115 | reg = <0x0>; 116 | zephyr,gain = "ADC_GAIN_1"; 117 | zephyr,reference = "ADC_REF_INTERNAL"; 118 | zephyr,acquisition-time = ; 119 | zephyr,resolution = <10>; 120 | zephyr,input-positive = <0>; 121 | }; 122 | 123 | channel@2 { 124 | reg = <0x2>; 125 | zephyr,gain = "ADC_GAIN_1"; 126 | zephyr,reference = "ADC_REF_INTERNAL"; 127 | zephyr,acquisition-time = ; 128 | zephyr,resolution = <10>; 129 | zephyr,input-positive = <2>; 130 | }; 131 | 132 | channel@3 { 133 | reg = <0x3>; 134 | zephyr,gain = "ADC_GAIN_1"; 135 | zephyr,reference = "ADC_REF_INTERNAL"; 136 | zephyr,acquisition-time = ; 137 | zephyr,resolution = <10>; 138 | zephyr,input-positive = <3>; 139 | }; 140 | 141 | channel@a { 142 | reg = <0xa>; 143 | zephyr,gain = "ADC_GAIN_1"; 144 | zephyr,reference = "ADC_REF_INTERNAL"; 145 | zephyr,acquisition-time = ; 146 | zephyr,resolution = <10>; 147 | zephyr,input-positive = <10>; 148 | }; 149 | 150 | channel@b { 151 | reg = <0xb>; 152 | zephyr,gain = "ADC_GAIN_1"; 153 | zephyr,reference = "ADC_REF_INTERNAL"; 154 | zephyr,acquisition-time = ; 155 | zephyr,resolution = <10>; 156 | zephyr,input-positive = <11>; 157 | }; 158 | 159 | channel@12 { 160 | reg = <0x12>; 161 | zephyr,gain = "ADC_GAIN_1"; 162 | zephyr,reference = "ADC_REF_INTERNAL"; 163 | zephyr,acquisition-time = ; 164 | zephyr,resolution = <10>; 165 | zephyr,input-positive = <18>; 166 | }; 167 | 168 | channel@13 { 169 | reg = <0x13>; 170 | zephyr,gain = "ADC_GAIN_1"; 171 | zephyr,reference = "ADC_REF_INTERNAL"; 172 | zephyr,acquisition-time = ; 173 | zephyr,resolution = <10>; 174 | zephyr,input-positive = <19>; 175 | }; 176 | }; 177 | -------------------------------------------------------------------------------- /variants/nrf9160dk_nrf9160/nrf9160dk_nrf9160.overlay: -------------------------------------------------------------------------------- 1 | / { 2 | zephyr,user { 3 | digital-pin-gpios = 4 | <&arduino_header 6 0>, /* Digital */ 5 | <&arduino_header 7 0>, 6 | <&arduino_header 8 0>, 7 | <&arduino_header 9 0>, 8 | <&arduino_header 10 0>, 9 | <&arduino_header 11 0>, 10 | <&arduino_header 12 0>, 11 | <&arduino_header 13 0>, 12 | <&arduino_header 14 0>, 13 | <&arduino_header 15 0>, 14 | <&arduino_header 16 0>, 15 | <&arduino_header 17 0>, 16 | <&arduino_header 18 0>, 17 | <&arduino_header 19 0>, 18 | <&arduino_header 20 0>, 19 | <&arduino_header 21 0>, 20 | <&arduino_header 0 0>, /* Analog */ 21 | <&arduino_header 1 0>, 22 | <&arduino_header 2 0>, 23 | <&arduino_header 3 0>, 24 | <&arduino_header 4 0>, 25 | <&arduino_header 5 0>, 26 | <&gpio0 13 GPIO_ACTIVE_LOW>; 27 | 28 | pwm-pin-gpios = 29 | <&gpio0 13 GPIO_ACTIVE_LOW>, 30 | <&arduino_header 9 0>, 31 | <&arduino_header 11 0>, 32 | <&arduino_header 12 0>, 33 | <&arduino_header 15 0>, 34 | <&arduino_header 16 0>, 35 | <&arduino_header 17 0>; 36 | 37 | adc-pin-gpios = 38 | <&arduino_header 0 0>, 39 | <&arduino_header 1 0>, 40 | <&arduino_header 2 0>, 41 | <&arduino_header 3 0>, 42 | <&arduino_header 4 0>, 43 | <&arduino_header 5 0>; 44 | 45 | pwms = 46 | <&pwm0 1 255 PWM_POLARITY_NORMAL>, 47 | <&pwm0 2 255 PWM_POLARITY_NORMAL>, 48 | <&pwm0 3 255 PWM_POLARITY_NORMAL>, 49 | <&pwm1 0 255 PWM_POLARITY_NORMAL>, 50 | <&pwm1 1 255 PWM_POLARITY_NORMAL>, 51 | <&pwm1 2 255 PWM_POLARITY_NORMAL>; 52 | 53 | io-channels = 54 | <&arduino_adc 0>, 55 | <&arduino_adc 1>, 56 | <&arduino_adc 2>, 57 | <&arduino_adc 3>, 58 | <&arduino_adc 4>, 59 | <&arduino_adc 5>; 60 | }; 61 | }; 62 | 63 | &adc { 64 | #address-cells = <1>; 65 | #size-cells = <0>; 66 | 67 | channel@0 { 68 | reg = <0>; 69 | zephyr,gain = "ADC_GAIN_1_6"; 70 | zephyr,reference = "ADC_REF_INTERNAL"; 71 | zephyr,acquisition-time = ; 72 | zephyr,input-positive = ; /* P0.02 */ 73 | zephyr,resolution = <10>; 74 | }; 75 | 76 | channel@1 { 77 | reg = <1>; 78 | zephyr,gain = "ADC_GAIN_1_6"; 79 | zephyr,reference = "ADC_REF_INTERNAL"; 80 | zephyr,acquisition-time = ; 81 | zephyr,input-positive = ; /* P0.03 */ 82 | zephyr,resolution = <10>; 83 | }; 84 | 85 | channel@2 { 86 | reg = <2>; 87 | zephyr,gain = "ADC_GAIN_1_6"; 88 | zephyr,reference = "ADC_REF_INTERNAL"; 89 | zephyr,acquisition-time = ; 90 | zephyr,input-positive = ; /* P0.04 */ 91 | zephyr,resolution = <10>; 92 | }; 93 | 94 | channel@3 { 95 | reg = <3>; 96 | zephyr,gain = "ADC_GAIN_1_6"; 97 | zephyr,reference = "ADC_REF_INTERNAL"; 98 | zephyr,acquisition-time = ; 99 | zephyr,input-positive = ; /* P0.05 */ 100 | zephyr,resolution = <10>; 101 | }; 102 | 103 | channel@4 { 104 | reg = <4>; 105 | zephyr,gain = "ADC_GAIN_1_6"; 106 | zephyr,reference = "ADC_REF_INTERNAL"; 107 | zephyr,acquisition-time = ; 108 | zephyr,input-positive = ; /* P0.28 */ 109 | zephyr,resolution = <10>; 110 | }; 111 | 112 | channel@5 { 113 | reg = <5>; 114 | zephyr,gain = "ADC_GAIN_1_6"; 115 | zephyr,reference = "ADC_REF_INTERNAL"; 116 | zephyr,acquisition-time = ; 117 | zephyr,input-positive = ; /* P0.29 */ 118 | zephyr,resolution = <10>; 119 | }; 120 | 121 | channel@6 { 122 | reg = <6>; 123 | zephyr,gain = "ADC_GAIN_1_6"; 124 | zephyr,reference = "ADC_REF_INTERNAL"; 125 | zephyr,acquisition-time = ; 126 | zephyr,input-positive = ; /* P0.30 */ 127 | zephyr,resolution = <10>; 128 | }; 129 | 130 | channel@7 { 131 | reg = <7>; 132 | zephyr,gain = "ADC_GAIN_1_6"; 133 | zephyr,reference = "ADC_REF_INTERNAL"; 134 | zephyr,acquisition-time = ; 135 | zephyr,input-positive = ; /* P0.31 */ 136 | zephyr,resolution = <10>; 137 | }; 138 | }; 139 | 140 | &pinctrl { 141 | pwm0_default: pwm0_default { 142 | group1 { 143 | psels = , /* keep original config */ 144 | , 145 | , 146 | ; 147 | nordic,invert; 148 | }; 149 | }; 150 | 151 | pwm0_sleep: pwm0_sleep { 152 | group1 { 153 | psels = , /* keep original config */ 154 | , 155 | , 156 | ; 157 | low-power-enable; 158 | }; 159 | }; 160 | 161 | pwm1_default: pwm1_default { 162 | group1 { 163 | psels = , 164 | , 165 | ; 166 | nordic,invert; 167 | }; 168 | }; 169 | 170 | pwm1_sleep: pwm1_sleep { 171 | group1 { 172 | psels = , 173 | , 174 | ; 175 | low-power-enable; 176 | }; 177 | }; 178 | }; 179 | 180 | &pwm0 { 181 | status = "okay"; 182 | pinctrl-0 = <&pwm0_default>; 183 | pinctrl-1 = <&pwm0_sleep>; 184 | pinctrl-names = "default", "sleep"; 185 | }; 186 | 187 | &pwm1 { 188 | status = "okay"; 189 | pinctrl-0 = <&pwm1_default>; 190 | pinctrl-1 = <&pwm1_sleep>; 191 | pinctrl-names = "default", "sleep"; 192 | }; 193 | -------------------------------------------------------------------------------- /cores/arduino/zephyrPrint.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 TOKITA Hiroshi 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | namespace arduino 15 | { 16 | namespace zephyr 17 | { 18 | 19 | int cbprintf_callback(int c, void *ctx); 20 | size_t wrap_cbprintf(void *ctx, const char *format, ...); 21 | size_t print_number_base_any(void *ctx, unsigned long long ull, int base); 22 | size_t print_number_base_pow2(void *ctx, unsigned long long ull, unsigned bits); 23 | 24 | template size_t print_number(void *ctx, Number n, const int base, const char *decfmt) 25 | { 26 | if (base == 0) { 27 | return reinterpret_cast(ctx)->write((char)n); 28 | } else if (base == 2) { 29 | return arduino::zephyr::print_number_base_pow2(ctx, n, 1); 30 | } else if (base == 4) { 31 | return arduino::zephyr::print_number_base_pow2(ctx, n, 2); 32 | } else if (base == 8) { 33 | return arduino::zephyr::print_number_base_pow2(ctx, n, 3); 34 | } else if (base == 10) { 35 | return arduino::zephyr::wrap_cbprintf(ctx, decfmt, n); 36 | } else if (base == 16) { 37 | return arduino::zephyr::print_number_base_pow2(ctx, n, 4); 38 | } else if (base == 32) { 39 | return arduino::zephyr::print_number_base_pow2(ctx, n, 5); 40 | } else { 41 | return arduino::zephyr::print_number_base_any(ctx, n, base); 42 | } 43 | } 44 | 45 | } // namespace zephyr 46 | 47 | } // namespace arduino 48 | 49 | inline size_t arduino::Print::print(const __FlashStringHelper *fsh) 50 | { 51 | return write(reinterpret_cast(fsh)); 52 | } 53 | 54 | inline size_t arduino::Print::print(const String &s) 55 | { 56 | return write(s.c_str(), s.length()); 57 | } 58 | 59 | inline size_t arduino::Print::print(const char str[]) 60 | { 61 | return write(str); 62 | } 63 | 64 | inline size_t arduino::Print::print(char c) 65 | { 66 | return write(c); 67 | } 68 | 69 | inline size_t arduino::Print::print(unsigned char n, int base) 70 | { 71 | return arduino::zephyr::print_number(this, n, base, "%hhu"); 72 | } 73 | 74 | inline size_t arduino::Print::print(int n, int base) 75 | { 76 | return arduino::zephyr::print_number(this, n, base, "%d"); 77 | } 78 | 79 | inline size_t arduino::Print::print(unsigned int n, int base) 80 | { 81 | return arduino::zephyr::print_number(this, n, base, "%u"); 82 | } 83 | 84 | inline size_t arduino::Print::print(long n, int base) 85 | { 86 | return arduino::zephyr::print_number(this, n, base, "%ld"); 87 | } 88 | 89 | inline size_t arduino::Print::print(unsigned long n, int base) 90 | { 91 | return arduino::zephyr::print_number(this, n, base, "%lu"); 92 | } 93 | 94 | inline size_t arduino::Print::print(long long n, int base) 95 | { 96 | return arduino::zephyr::print_number(this, n, base, "%lld"); 97 | } 98 | 99 | inline size_t arduino::Print::print(unsigned long long n, int base) 100 | { 101 | return arduino::zephyr::print_number(this, n, base, "%llu"); 102 | } 103 | 104 | inline size_t arduino::Print::print(double n, int perception) 105 | { 106 | if (perception < 10) { 107 | const char ch_perception = static_cast('0' + perception); 108 | const char format[] = {'%', '.', ch_perception, 'f', '\0'}; 109 | return arduino::zephyr::wrap_cbprintf(this, format, n); 110 | } else { 111 | const char ch_perception = static_cast('0' + (perception % 10)); 112 | const char format[] = {'%', '.', '1', ch_perception, 'f', '\0'}; 113 | return arduino::zephyr::wrap_cbprintf(this, format, n); 114 | } 115 | } 116 | 117 | inline size_t arduino::Print::print(const Printable &printable) 118 | { 119 | return printable.printTo(*this); 120 | } 121 | 122 | inline size_t arduino::Print::println(const __FlashStringHelper *fsh) 123 | { 124 | return print(fsh) + println(); 125 | } 126 | 127 | inline size_t arduino::Print::println(const String &s) 128 | { 129 | return print(s) + println(); 130 | } 131 | 132 | inline size_t arduino::Print::println(const char str[]) 133 | { 134 | return print(str) + println(); 135 | } 136 | 137 | inline size_t arduino::Print::println(char c) 138 | { 139 | return print(c) + println(); 140 | } 141 | 142 | inline size_t arduino::Print::println(unsigned char uc, int base) 143 | { 144 | return print(uc, base) + println(); 145 | } 146 | 147 | inline size_t arduino::Print::println(int i, int base) 148 | { 149 | return print(i, base) + println(); 150 | } 151 | 152 | inline size_t arduino::Print::println(unsigned int ui, int base) 153 | { 154 | return print(ui, base) + println(); 155 | } 156 | 157 | inline size_t arduino::Print::println(long l, int base) 158 | { 159 | return print(l, base) + println(); 160 | } 161 | 162 | inline size_t arduino::Print::println(unsigned long ul, int base) 163 | { 164 | return print(ul, base) + println(); 165 | } 166 | 167 | inline size_t arduino::Print::println(long long ll, int base) 168 | { 169 | return print(ll, base) + println(); 170 | } 171 | 172 | inline size_t arduino::Print::println(unsigned long long ull, int base) 173 | { 174 | return print(ull, base) + println(); 175 | } 176 | 177 | inline size_t arduino::Print::println(double d, int perception) 178 | { 179 | return print(d, perception) + println(); 180 | } 181 | 182 | inline size_t arduino::Print::println(const Printable &printable) 183 | { 184 | return print(printable) + println(); 185 | } 186 | 187 | inline size_t arduino::Print::println(void) 188 | { 189 | return write("\r\n", 2); 190 | } 191 | -------------------------------------------------------------------------------- /variants/nrf52840dk_nrf52840/nrf52840dk_nrf52840.overlay: -------------------------------------------------------------------------------- 1 | / { 2 | zephyr,user { 3 | digital-pin-gpios = <&arduino_header 6 0>, /* Digital */ 4 | <&arduino_header 7 0>, 5 | <&arduino_header 8 0>, 6 | <&arduino_header 9 0>, 7 | <&arduino_header 10 0>, 8 | <&arduino_header 11 0>, 9 | <&arduino_header 12 0>, 10 | <&arduino_header 13 0>, 11 | <&arduino_header 14 0>, 12 | <&arduino_header 15 0>, 13 | <&arduino_header 16 0>, 14 | <&arduino_header 17 0>, 15 | <&arduino_header 18 0>, 16 | <&arduino_header 19 0>, 17 | <&arduino_header 20 0>, 18 | <&arduino_header 21 0>, 19 | <&arduino_header 0 0>, /* Analog */ 20 | <&arduino_header 1 0>, 21 | <&arduino_header 2 0>, 22 | <&arduino_header 3 0>, 23 | <&arduino_header 4 0>, 24 | <&arduino_header 5 0>, 25 | <&gpio0 13 GPIO_ACTIVE_LOW>; 26 | 27 | pwm-pin-gpios = <&gpio0 13 GPIO_ACTIVE_LOW>, 28 | <&arduino_header 9 0>, 29 | <&arduino_header 11 0>, 30 | <&arduino_header 12 0>, 31 | <&arduino_header 15 0>, 32 | <&arduino_header 16 0>, 33 | <&arduino_header 17 0>; 34 | 35 | adc-pin-gpios = <&arduino_header 0 0>, 36 | <&arduino_header 1 0>, 37 | <&arduino_header 2 0>, 38 | <&arduino_header 3 0>, 39 | <&arduino_header 4 0>, 40 | <&arduino_header 5 0>; 41 | 42 | pwms = <&pwm0 1 255 PWM_POLARITY_NORMAL>, 43 | <&pwm0 2 255 PWM_POLARITY_NORMAL>, 44 | <&pwm0 3 255 PWM_POLARITY_NORMAL>, 45 | <&pwm1 0 255 PWM_POLARITY_NORMAL>, 46 | <&pwm1 1 255 PWM_POLARITY_NORMAL>, 47 | <&pwm1 2 255 PWM_POLARITY_NORMAL>; 48 | 49 | io-channels = <&arduino_adc 0>, 50 | <&arduino_adc 1>, 51 | <&arduino_adc 2>, 52 | <&arduino_adc 3>, 53 | <&arduino_adc 4>, 54 | <&arduino_adc 5>; 55 | }; 56 | }; 57 | 58 | &adc { 59 | #address-cells = <1>; 60 | #size-cells = <0>; 61 | 62 | channel@0 { 63 | reg = <0>; 64 | zephyr,gain = "ADC_GAIN_1_6"; 65 | zephyr,reference = "ADC_REF_INTERNAL"; 66 | zephyr,acquisition-time = ; 67 | zephyr,input-positive = ; /* P0.02 */ 68 | zephyr,resolution = <10>; 69 | }; 70 | 71 | channel@1 { 72 | reg = <1>; 73 | zephyr,gain = "ADC_GAIN_1_6"; 74 | zephyr,reference = "ADC_REF_INTERNAL"; 75 | zephyr,acquisition-time = ; 76 | zephyr,input-positive = ; /* P0.03 */ 77 | zephyr,resolution = <10>; 78 | }; 79 | 80 | channel@2 { 81 | reg = <2>; 82 | zephyr,gain = "ADC_GAIN_1_6"; 83 | zephyr,reference = "ADC_REF_INTERNAL"; 84 | zephyr,acquisition-time = ; 85 | zephyr,input-positive = ; /* P0.04 */ 86 | zephyr,resolution = <10>; 87 | }; 88 | 89 | channel@3 { 90 | reg = <3>; 91 | zephyr,gain = "ADC_GAIN_1_6"; 92 | zephyr,reference = "ADC_REF_INTERNAL"; 93 | zephyr,acquisition-time = ; 94 | zephyr,input-positive = ; /* P0.05 */ 95 | zephyr,resolution = <10>; 96 | }; 97 | 98 | channel@4 { 99 | reg = <4>; 100 | zephyr,gain = "ADC_GAIN_1_6"; 101 | zephyr,reference = "ADC_REF_INTERNAL"; 102 | zephyr,acquisition-time = ; 103 | zephyr,input-positive = ; /* P0.28 */ 104 | zephyr,resolution = <10>; 105 | }; 106 | 107 | channel@5 { 108 | reg = <5>; 109 | zephyr,gain = "ADC_GAIN_1_6"; 110 | zephyr,reference = "ADC_REF_INTERNAL"; 111 | zephyr,acquisition-time = ; 112 | zephyr,input-positive = ; /* P0.29 */ 113 | zephyr,resolution = <10>; 114 | }; 115 | 116 | channel@6 { 117 | reg = <6>; 118 | zephyr,gain = "ADC_GAIN_1_6"; 119 | zephyr,reference = "ADC_REF_INTERNAL"; 120 | zephyr,acquisition-time = ; 121 | zephyr,input-positive = ; /* P0.30 */ 122 | zephyr,resolution = <10>; 123 | }; 124 | 125 | channel@7 { 126 | reg = <7>; 127 | zephyr,gain = "ADC_GAIN_1_6"; 128 | zephyr,reference = "ADC_REF_INTERNAL"; 129 | zephyr,acquisition-time = ; 130 | zephyr,input-positive = ; /* P0.31 */ 131 | zephyr,resolution = <10>; 132 | }; 133 | }; 134 | 135 | &pinctrl { 136 | pwm0_default: pwm0_default { 137 | group1 { 138 | psels = , /* keep original config */ 139 | , 140 | , 141 | ; 142 | nordic,invert; 143 | }; 144 | }; 145 | 146 | pwm0_sleep: pwm0_sleep { 147 | group1 { 148 | psels = , /* keep original config */ 149 | , 150 | , 151 | ; 152 | low-power-enable; 153 | }; 154 | }; 155 | 156 | pwm1_default: pwm1_default { 157 | group1 { 158 | psels = , 159 | , 160 | ; 161 | nordic,invert; 162 | }; 163 | }; 164 | 165 | pwm1_sleep: pwm1_sleep { 166 | group1 { 167 | psels = , 168 | , 169 | ; 170 | low-power-enable; 171 | }; 172 | }; 173 | }; 174 | 175 | &pwm0 { 176 | status = "okay"; 177 | pinctrl-0 = <&pwm0_default>; 178 | pinctrl-1 = <&pwm0_sleep>; 179 | pinctrl-names = "default", "sleep"; 180 | }; 181 | 182 | &pwm1 { 183 | status = "okay"; 184 | pinctrl-0 = <&pwm1_default>; 185 | pinctrl-1 = <&pwm1_sleep>; 186 | pinctrl-names = "default", "sleep"; 187 | }; 188 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | conduct@zephyrproject.org. 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.0, available at 119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 120 | 121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 122 | enforcement ladder](https://github.com/mozilla/diversity). 123 | 124 | [homepage]: https://www.contributor-covenant.org 125 | 126 | For answers to common questions about this code of conduct, see the FAQ at 127 | https://www.contributor-covenant.org/faq. Translations are available at 128 | https://www.contributor-covenant.org/translations. 129 | -------------------------------------------------------------------------------- /variants/arduino_nano_33_ble_nrf52840/arduino_nano_33_ble_nrf52840.overlay: -------------------------------------------------------------------------------- 1 | / { 2 | zephyr,user { 3 | digital-pin-gpios = <&arduino_nano_header 0 0>, 4 | <&arduino_nano_header 1 0>, 5 | <&arduino_nano_header 2 0>, 6 | <&arduino_nano_header 3 0>, 7 | <&arduino_nano_header 4 0>, 8 | <&arduino_nano_header 5 0>, 9 | <&arduino_nano_header 6 0>, 10 | <&arduino_nano_header 7 0>, 11 | <&arduino_nano_header 8 0>, 12 | <&arduino_nano_header 9 0>, 13 | <&arduino_nano_header 10 0>, 14 | <&arduino_nano_header 11 0>, 15 | <&arduino_nano_header 12 0>, 16 | <&arduino_nano_header 13 0>, 17 | <&arduino_nano_header 14 0>, /* D14 / A0 */ 18 | <&arduino_nano_header 15 0>, 19 | <&arduino_nano_header 16 0>, 20 | <&arduino_nano_header 17 0>, 21 | <&arduino_nano_header 18 0>, /* D18 / A4 / I2C-SDA */ 22 | <&arduino_nano_header 19 0>, /* D19 / A5 / I2C-SCL */ 23 | <&arduino_nano_header 20 0>, 24 | <&arduino_nano_header 21 0>; 25 | 26 | pwm-pin-gpios = <&arduino_nano_header 3 0>, 27 | <&arduino_nano_header 5 0>, 28 | <&arduino_nano_header 6 0>, 29 | <&arduino_nano_header 13 0>, 30 | <&arduino_nano_header 9 0>, 31 | <&arduino_nano_header 10 0>, 32 | <&arduino_nano_header 11 0>; 33 | 34 | adc-pin-gpios = <&arduino_nano_header 14 0>, 35 | <&arduino_nano_header 15 0>, 36 | <&arduino_nano_header 16 0>, 37 | <&arduino_nano_header 17 0>, 38 | <&arduino_nano_header 18 0>, 39 | <&arduino_nano_header 19 0>, 40 | <&arduino_nano_header 20 0>, 41 | <&arduino_nano_header 21 0>; 42 | 43 | builtin-led-gpios = <&arduino_nano_header 13 0>; 44 | 45 | pwms = <&pwm1 1 255 PWM_POLARITY_NORMAL>, 46 | <&pwm1 2 255 PWM_POLARITY_NORMAL>, 47 | <&pwm1 3 255 PWM_POLARITY_NORMAL>, 48 | <&pwm2 0 255 PWM_POLARITY_NORMAL>, 49 | <&pwm2 1 255 PWM_POLARITY_NORMAL>, 50 | <&pwm2 2 255 PWM_POLARITY_NORMAL>, 51 | <&pwm2 3 255 PWM_POLARITY_NORMAL>; 52 | 53 | io-channels = <&adc 2>, 54 | <&adc 3>, 55 | <&adc 6>, 56 | <&adc 5>, 57 | <&adc 7>, 58 | <&adc 0>, 59 | <&adc 4>, 60 | <&adc 1>; 61 | 62 | serials = <&uart0>; 63 | i2cs = <&arduino_nano_i2c>; 64 | }; 65 | }; 66 | 67 | &adc { 68 | #address-cells = <1>; 69 | #size-cells = <0>; 70 | 71 | channel@0 { 72 | reg = <0>; 73 | zephyr,gain = "ADC_GAIN_1_6"; 74 | zephyr,reference = "ADC_REF_INTERNAL"; 75 | zephyr,acquisition-time = ; 76 | zephyr,input-positive = ; /* P0.02 */ 77 | zephyr,resolution = <10>; 78 | }; 79 | 80 | channel@1 { 81 | reg = <1>; 82 | zephyr,gain = "ADC_GAIN_1_6"; 83 | zephyr,reference = "ADC_REF_INTERNAL"; 84 | zephyr,acquisition-time = ; 85 | zephyr,input-positive = ; /* P0.03 */ 86 | zephyr,resolution = <10>; 87 | }; 88 | 89 | channel@2 { 90 | reg = <2>; 91 | zephyr,gain = "ADC_GAIN_1_6"; 92 | zephyr,reference = "ADC_REF_INTERNAL"; 93 | zephyr,acquisition-time = ; 94 | zephyr,input-positive = ; /* P0.04 */ 95 | zephyr,resolution = <10>; 96 | }; 97 | 98 | channel@3 { 99 | reg = <3>; 100 | zephyr,gain = "ADC_GAIN_1_6"; 101 | zephyr,reference = "ADC_REF_INTERNAL"; 102 | zephyr,acquisition-time = ; 103 | zephyr,input-positive = ; /* P0.05 */ 104 | zephyr,resolution = <10>; 105 | }; 106 | 107 | channel@4 { 108 | reg = <4>; 109 | zephyr,gain = "ADC_GAIN_1_6"; 110 | zephyr,reference = "ADC_REF_INTERNAL"; 111 | zephyr,acquisition-time = ; 112 | zephyr,input-positive = ; /* P0.28 */ 113 | zephyr,resolution = <10>; 114 | }; 115 | 116 | channel@5 { 117 | reg = <5>; 118 | zephyr,gain = "ADC_GAIN_1_6"; 119 | zephyr,reference = "ADC_REF_INTERNAL"; 120 | zephyr,acquisition-time = ; 121 | zephyr,input-positive = ; /* P0.29 */ 122 | zephyr,resolution = <10>; 123 | }; 124 | 125 | channel@6 { 126 | reg = <6>; 127 | zephyr,gain = "ADC_GAIN_1_6"; 128 | zephyr,reference = "ADC_REF_INTERNAL"; 129 | zephyr,acquisition-time = ; 130 | zephyr,input-positive = ; /* P0.30 */ 131 | zephyr,resolution = <10>; 132 | }; 133 | 134 | channel@7 { 135 | reg = <7>; 136 | zephyr,gain = "ADC_GAIN_1_6"; 137 | zephyr,reference = "ADC_REF_INTERNAL"; 138 | zephyr,acquisition-time = ; 139 | zephyr,input-positive = ; /* P0.31 */ 140 | zephyr,resolution = <10>; 141 | }; 142 | }; 143 | 144 | &pinctrl { 145 | pwm1_default: pwm1_default { 146 | group1 { 147 | psels = , /* keep original config */ 148 | , 149 | , 150 | ; 151 | nordic,invert; 152 | }; 153 | }; 154 | 155 | pwm1_sleep: pwm1_sleep { 156 | group1 { 157 | psels = , /* keep original config */ 158 | , 159 | , 160 | ; 161 | low-power-enable; 162 | }; 163 | }; 164 | 165 | pwm2_default: pwm2_default { 166 | group1 { 167 | psels = , /* keep original config */ 168 | , 169 | , 170 | ; 171 | nordic,invert; 172 | }; 173 | }; 174 | 175 | pwm2_sleep: pwm2_sleep { 176 | group1 { 177 | psels = , /* keep original config */ 178 | , 179 | , 180 | ; 181 | low-power-enable; 182 | }; 183 | }; 184 | }; 185 | 186 | &pwm1 { 187 | status = "okay"; 188 | pinctrl-0 = <&pwm1_default>; 189 | pinctrl-1 = <&pwm1_sleep>; 190 | pinctrl-names = "default", "sleep"; 191 | }; 192 | 193 | &pwm2 { 194 | status = "okay"; 195 | pinctrl-0 = <&pwm2_default>; 196 | pinctrl-1 = <&pwm2_sleep>; 197 | pinctrl-names = "default", "sleep"; 198 | }; 199 | -------------------------------------------------------------------------------- /variants/arduino_nano_33_ble_nrf52840_sense/arduino_nano_33_ble_nrf52840_sense.overlay: -------------------------------------------------------------------------------- 1 | / { 2 | zephyr,user { 3 | digital-pin-gpios = <&arduino_nano_header 0 0>, 4 | <&arduino_nano_header 1 0>, 5 | <&arduino_nano_header 2 0>, 6 | <&arduino_nano_header 3 0>, 7 | <&arduino_nano_header 4 0>, 8 | <&arduino_nano_header 5 0>, 9 | <&arduino_nano_header 6 0>, 10 | <&arduino_nano_header 7 0>, 11 | <&arduino_nano_header 8 0>, 12 | <&arduino_nano_header 9 0>, 13 | <&arduino_nano_header 10 0>, 14 | <&arduino_nano_header 11 0>, 15 | <&arduino_nano_header 12 0>, 16 | <&arduino_nano_header 13 0>, 17 | <&arduino_nano_header 14 0>, /* D14 / A0 */ 18 | <&arduino_nano_header 15 0>, 19 | <&arduino_nano_header 16 0>, 20 | <&arduino_nano_header 17 0>, 21 | <&arduino_nano_header 18 0>, /* D18 / A4 / I2C-SDA */ 22 | <&arduino_nano_header 19 0>, /* D19 / A5 / I2C-SCL */ 23 | <&arduino_nano_header 20 0>, 24 | <&arduino_nano_header 21 0>; 25 | 26 | pwm-pin-gpios = <&arduino_nano_header 3 0>, 27 | <&arduino_nano_header 5 0>, 28 | <&arduino_nano_header 6 0>, 29 | <&arduino_nano_header 13 0>, 30 | <&arduino_nano_header 9 0>, 31 | <&arduino_nano_header 10 0>, 32 | <&arduino_nano_header 11 0>; 33 | 34 | adc-pin-gpios = <&arduino_nano_header 14 0>, 35 | <&arduino_nano_header 15 0>, 36 | <&arduino_nano_header 16 0>, 37 | <&arduino_nano_header 17 0>, 38 | <&arduino_nano_header 18 0>, 39 | <&arduino_nano_header 19 0>, 40 | <&arduino_nano_header 20 0>, 41 | <&arduino_nano_header 21 0>; 42 | 43 | builtin-led-gpios = <&arduino_nano_header 13 0>; 44 | 45 | pwms = <&pwm1 1 255 PWM_POLARITY_NORMAL>, 46 | <&pwm1 2 255 PWM_POLARITY_NORMAL>, 47 | <&pwm1 3 255 PWM_POLARITY_NORMAL>, 48 | <&pwm2 0 255 PWM_POLARITY_NORMAL>, 49 | <&pwm2 1 255 PWM_POLARITY_NORMAL>, 50 | <&pwm2 2 255 PWM_POLARITY_NORMAL>, 51 | <&pwm2 3 255 PWM_POLARITY_NORMAL>; 52 | 53 | io-channels = <&adc 2>, 54 | <&adc 3>, 55 | <&adc 6>, 56 | <&adc 5>, 57 | <&adc 7>, 58 | <&adc 0>, 59 | <&adc 4>, 60 | <&adc 1>; 61 | 62 | serials = <&uart0>; 63 | i2cs = <&arduino_nano_i2c>; 64 | }; 65 | }; 66 | 67 | &adc { 68 | #address-cells = <1>; 69 | #size-cells = <0>; 70 | 71 | channel@0 { 72 | reg = <0>; 73 | zephyr,gain = "ADC_GAIN_1_6"; 74 | zephyr,reference = "ADC_REF_INTERNAL"; 75 | zephyr,acquisition-time = ; 76 | zephyr,input-positive = ; /* P0.02 */ 77 | zephyr,resolution = <10>; 78 | }; 79 | 80 | channel@1 { 81 | reg = <1>; 82 | zephyr,gain = "ADC_GAIN_1_6"; 83 | zephyr,reference = "ADC_REF_INTERNAL"; 84 | zephyr,acquisition-time = ; 85 | zephyr,input-positive = ; /* P0.03 */ 86 | zephyr,resolution = <10>; 87 | }; 88 | 89 | channel@2 { 90 | reg = <2>; 91 | zephyr,gain = "ADC_GAIN_1_6"; 92 | zephyr,reference = "ADC_REF_INTERNAL"; 93 | zephyr,acquisition-time = ; 94 | zephyr,input-positive = ; /* P0.04 */ 95 | zephyr,resolution = <10>; 96 | }; 97 | 98 | channel@3 { 99 | reg = <3>; 100 | zephyr,gain = "ADC_GAIN_1_6"; 101 | zephyr,reference = "ADC_REF_INTERNAL"; 102 | zephyr,acquisition-time = ; 103 | zephyr,input-positive = ; /* P0.05 */ 104 | zephyr,resolution = <10>; 105 | }; 106 | 107 | channel@4 { 108 | reg = <4>; 109 | zephyr,gain = "ADC_GAIN_1_6"; 110 | zephyr,reference = "ADC_REF_INTERNAL"; 111 | zephyr,acquisition-time = ; 112 | zephyr,input-positive = ; /* P0.28 */ 113 | zephyr,resolution = <10>; 114 | }; 115 | 116 | channel@5 { 117 | reg = <5>; 118 | zephyr,gain = "ADC_GAIN_1_6"; 119 | zephyr,reference = "ADC_REF_INTERNAL"; 120 | zephyr,acquisition-time = ; 121 | zephyr,input-positive = ; /* P0.29 */ 122 | zephyr,resolution = <10>; 123 | }; 124 | 125 | channel@6 { 126 | reg = <6>; 127 | zephyr,gain = "ADC_GAIN_1_6"; 128 | zephyr,reference = "ADC_REF_INTERNAL"; 129 | zephyr,acquisition-time = ; 130 | zephyr,input-positive = ; /* P0.30 */ 131 | zephyr,resolution = <10>; 132 | }; 133 | 134 | channel@7 { 135 | reg = <7>; 136 | zephyr,gain = "ADC_GAIN_1_6"; 137 | zephyr,reference = "ADC_REF_INTERNAL"; 138 | zephyr,acquisition-time = ; 139 | zephyr,input-positive = ; /* P0.31 */ 140 | zephyr,resolution = <10>; 141 | }; 142 | }; 143 | 144 | &pinctrl { 145 | pwm1_default: pwm1_default { 146 | group1 { 147 | psels = , /* keep original config */ 148 | , 149 | , 150 | ; 151 | nordic,invert; 152 | }; 153 | }; 154 | 155 | pwm1_sleep: pwm1_sleep { 156 | group1 { 157 | psels = , /* keep original config */ 158 | , 159 | , 160 | ; 161 | low-power-enable; 162 | }; 163 | }; 164 | 165 | pwm2_default: pwm2_default { 166 | group1 { 167 | psels = , /* keep original config */ 168 | , 169 | , 170 | ; 171 | nordic,invert; 172 | }; 173 | }; 174 | 175 | pwm2_sleep: pwm2_sleep { 176 | group1 { 177 | psels = , /* keep original config */ 178 | , 179 | , 180 | ; 181 | low-power-enable; 182 | }; 183 | }; 184 | }; 185 | 186 | &pwm1 { 187 | status = "okay"; 188 | pinctrl-0 = <&pwm1_default>; 189 | pinctrl-1 = <&pwm1_sleep>; 190 | pinctrl-names = "default", "sleep"; 191 | }; 192 | 193 | &pwm2 { 194 | status = "okay"; 195 | pinctrl-0 = <&pwm2_default>; 196 | pinctrl-1 = <&pwm2_sleep>; 197 | pinctrl-names = "default", "sleep"; 198 | }; 199 | -------------------------------------------------------------------------------- /cores/arduino/zephyrSerial.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Dhruva Gole 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | namespace 14 | { 15 | 16 | enum uart_config_parity conf_parity(uint16_t conf) 17 | { 18 | switch (conf & SERIAL_PARITY_MASK) { 19 | case SERIAL_PARITY_EVEN: 20 | return UART_CFG_PARITY_EVEN; 21 | case SERIAL_PARITY_ODD: 22 | return UART_CFG_PARITY_ODD; 23 | default: 24 | return UART_CFG_PARITY_NONE; 25 | } 26 | } 27 | 28 | enum uart_config_stop_bits conf_stop_bits(uint16_t conf) 29 | { 30 | switch (conf & SERIAL_STOP_BIT_MASK) { 31 | case SERIAL_STOP_BIT_1_5: 32 | return UART_CFG_STOP_BITS_1_5; 33 | case SERIAL_STOP_BIT_2: 34 | return UART_CFG_STOP_BITS_2; 35 | default: 36 | return UART_CFG_STOP_BITS_1; 37 | } 38 | } 39 | 40 | enum uart_config_data_bits conf_data_bits(uint16_t conf) 41 | { 42 | switch (conf & SERIAL_DATA_MASK) { 43 | case SERIAL_DATA_5: 44 | return UART_CFG_DATA_BITS_5; 45 | case SERIAL_DATA_6: 46 | return UART_CFG_DATA_BITS_6; 47 | case SERIAL_DATA_7: 48 | return UART_CFG_DATA_BITS_7; 49 | default: 50 | return UART_CFG_DATA_BITS_8; 51 | } 52 | } 53 | 54 | } // anonymous namespace 55 | 56 | void arduino::ZephyrSerial::begin(unsigned long baud, uint16_t conf) 57 | { 58 | struct uart_config config = { 59 | .baudrate = baud, 60 | .parity = conf_parity(conf), 61 | .stop_bits = conf_stop_bits(conf), 62 | .data_bits = conf_data_bits(conf), 63 | .flow_ctrl = UART_CFG_FLOW_CTRL_NONE, 64 | }; 65 | 66 | uart_configure(uart, &config); 67 | uart_irq_callback_user_data_set(uart, arduino::ZephyrSerial::IrqDispatch, this); 68 | uart_irq_rx_enable(uart); 69 | } 70 | 71 | void arduino::ZephyrSerial::IrqHandler() 72 | { 73 | uint8_t buf[8]; 74 | int length; 75 | int ret = 0; 76 | 77 | if (!uart_irq_update(uart)) { 78 | return; 79 | } 80 | 81 | if (ring_buf_size_get(&tx.ringbuf) == 0) { 82 | uart_irq_tx_disable(uart); 83 | } 84 | 85 | k_sem_take(&rx.sem, K_NO_WAIT); 86 | while (uart_irq_rx_ready(uart) && ((length = uart_fifo_read(uart, buf, sizeof(buf))) > 0)) { 87 | length = min(sizeof(buf), static_cast(length)); 88 | ret = ring_buf_put(&rx.ringbuf, &buf[0], length); 89 | 90 | if (ret < 0) { 91 | break; 92 | } 93 | } 94 | k_sem_give(&rx.sem); 95 | 96 | k_sem_take(&tx.sem, K_NO_WAIT); 97 | while (uart_irq_tx_ready(uart) && ((length = ring_buf_size_get(&tx.ringbuf)) > 0)) { 98 | length = min(sizeof(buf), static_cast(length)); 99 | ring_buf_peek(&tx.ringbuf, &buf[0], length); 100 | 101 | ret = uart_fifo_fill(uart, &buf[0], length); 102 | if (ret < 0) { 103 | break; 104 | } else { 105 | ring_buf_get(&tx.ringbuf, &buf[0], ret); 106 | } 107 | } 108 | k_sem_give(&tx.sem); 109 | } 110 | 111 | void arduino::ZephyrSerial::IrqDispatch(const struct device *dev, void *data) 112 | { 113 | reinterpret_cast(data)->IrqHandler(); 114 | } 115 | 116 | int arduino::ZephyrSerial::available() 117 | { 118 | int ret; 119 | 120 | k_sem_take(&rx.sem, K_FOREVER); 121 | ret = ring_buf_size_get(&rx.ringbuf); 122 | k_sem_give(&rx.sem); 123 | 124 | return ret; 125 | } 126 | 127 | int arduino::ZephyrSerial::peek() 128 | { 129 | uint8_t data; 130 | 131 | k_sem_take(&rx.sem, K_FOREVER); 132 | ring_buf_peek(&rx.ringbuf, &data, 1); 133 | k_sem_give(&rx.sem); 134 | 135 | return data; 136 | } 137 | 138 | int arduino::ZephyrSerial::read() 139 | { 140 | uint8_t data; 141 | 142 | k_sem_take(&rx.sem, K_FOREVER); 143 | ring_buf_get(&rx.ringbuf, &data, 1); 144 | k_sem_give(&rx.sem); 145 | 146 | return data; 147 | } 148 | 149 | size_t arduino::ZephyrSerial::write(const uint8_t *buffer, size_t size) 150 | { 151 | int ret; 152 | 153 | k_sem_take(&tx.sem, K_FOREVER); 154 | ret = ring_buf_put(&tx.ringbuf, buffer, size); 155 | k_sem_give(&tx.sem); 156 | 157 | if (ret < 0) { 158 | return 0; 159 | } 160 | 161 | uart_irq_tx_enable(uart); 162 | 163 | return ret; 164 | } 165 | 166 | #if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), serials) 167 | arduino::ZephyrSerial Serial(DEVICE_DT_GET(DT_PHANDLE_BY_IDX(DT_PATH(zephyr_user), serials, 0))); 168 | #if (DT_PROP_LEN(DT_PATH(zephyr_user), serials) > 1) 169 | #define ARDUINO_SERIAL_DEFINED_0 1 170 | 171 | #define DECL_SERIAL_0(n, p, i) 172 | #define DECL_SERIAL_N(n, p, i) \ 173 | arduino::ZephyrSerial Serial##i(DEVICE_DT_GET(DT_PHANDLE_BY_IDX(n, p, i))); 174 | #define DECLARE_SERIAL_N(n, p, i) \ 175 | COND_CODE_1(ARDUINO_SERIAL_DEFINED_##i, (DECL_SERIAL_0(n, p, i)), (DECL_SERIAL_N(n, p, i))) 176 | 177 | #define CALL_EVENT_0(n, p, i) 178 | #define CALL_EVENT_N(n, p, i) if (_CONCAT(Serial, i).available()) _CONCAT(_CONCAT(serial, i), Event)(); 179 | #define CALL_SERIALEVENT_N(n, p, i) \ 180 | COND_CODE_1(ARDUINO_SERIAL_DEFINED_##i, (CALL_EVENT_0(n, p, i)), (CALL_EVENT_N(n, p, i))); 181 | 182 | #define DECL_EVENT_0(n, p, i) 183 | #define DECL_EVENT_N(n, p, i) __attribute__((weak)) void serial##i##Event() { } 184 | #define DECLARE_SERIALEVENT_N(n, p, i) \ 185 | COND_CODE_1(ARDUINO_SERIAL_DEFINED_##i, (DECL_EVENT_0(n, p, i)), (DECL_EVENT_N(n, p, i))); 186 | 187 | DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user), serials, DECLARE_SERIAL_N) 188 | #endif // PROP_LEN(serials) > 1 189 | #elif DT_NODE_HAS_STATUS(DT_NODELABEL(arduino_serial), okay) 190 | /* If serials node is not defined, tries to use arduino_serial */ 191 | arduino::ZephyrSerial Serial(DEVICE_DT_GET(DT_NODELABEL(arduino_serial))); 192 | #else 193 | arduino::ZephyrSerialStub Serial; 194 | #endif 195 | 196 | 197 | __attribute__((weak)) void serialEvent() { } 198 | #if (DT_PROP_LEN(DT_PATH(zephyr_user), serials) > 1) 199 | DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user), serials, DECLARE_SERIALEVENT_N) 200 | #endif 201 | 202 | void arduino::serialEventRun(void) 203 | { 204 | if (Serial.available()) serialEvent(); 205 | #if (DT_PROP_LEN(DT_PATH(zephyr_user), serials) > 1) 206 | DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user), serials, CALL_SERIALEVENT_N) 207 | #endif 208 | } 209 | -------------------------------------------------------------------------------- /documentation/variants.md: -------------------------------------------------------------------------------- 1 | # Adding custom boards/ variants 2 | 3 | - Boards already supported by Zephyr can be added to the variants folder as outlined in this documentation. 4 | - Custom boards can first by added by following the [official Zephyr porting guide](https://docs.zephyrproject.org/latest/hardware/porting/board_porting.html). 5 | Once completed, continue here by adding a variant for your custom board. 6 | 7 | ## Suppored Boards/variants 8 | 9 | - [X] Arduino Nano ble sense 33 10 | - [X] Arduino Nano ble 33 11 | - [X] Arduino Nano 33 iot 12 | - [X] Beagleconnect Freedom 13 | 14 | ## Planned Support: (TODO) 15 | - [ ] Particle Xenon 16 | - [ ] Arduino mkrzero 17 | - [ ] TI-CC3220SF LaunchXL 18 | - [ ] nrf52840dk_nrf52840 19 | 20 | ## How to add board variants 21 | 22 | This module uses the board name (supplied at build time by the `-b 23 | arduino_nano_33_ble` flag) to correctly map Arduino pin names/numbers to the 24 | target board. To add board support: 25 | 26 | 1. This project is structured in a way so as to isolate the variants from the core API. Thus, whenever a new board 27 | needs to be added it needs to be done in the `variants/` folder. 28 | Add a folder inside of the variants folder that matches the name of your board. 29 | 2. Add an overlay file and a pinmap header file that match the name of the board. 30 | 3. Add your new headerfile to an `#ifdef` statement in the variant.h file. 31 | 32 | An example of this structure is shown below. 33 | 34 | ```tree 35 | variants/ 36 | ├── arduino_nano_33_ble 37 | │   ├── arduino_nano_33_ble.overlay 38 | │   └── arduino_nano_33_ble_pinmap.h 39 | ├── CMakeLists.txt 40 | └── variant.h 41 | 42 | ``` 43 | 44 | - The top level consists of `CMakeLists.txt`, `variant.h` and the `` folder. Each of these files have a specific role to play. 45 | - The `Cmakelists` help the compiler locate the proper directory to help find the proper header files that are board specific. You need to add the name using `zephyr_include_directories(BOARD_NAME)` to this file. Do note that this `BOARD_NAME` is the same as the name of your board's directory. 46 | - `variant.h` contains the necessary `#includes` inorder to tell the source code about your board's pinmap. 47 | - The `` folder is where the overlay and pinmap file resides. Inorder to understand how to write DT overlays, lookup `Documentation/overlays.md`. To understand the `` file, go through the existing `variants/ARDUINO_NANO33BLE/arduino_nano_ble_sense_pinmap.h` which shows how to use the overlay nodes inside our C programs using zephyr macros like `GPIO_DT_SPEC_GET`. The zephyr-project documentation on this is pretty extensive as well and worth reading. 48 | 49 | ## Guide to Writing Overlays 50 | 51 | ### DeviceTree Overlay files for Arduino boards 52 | 53 | The Arduino API requires pin mapping definitions to use Arduino-style pin numbers 54 | (pin numbers printed on the board, not GPIO numbers). 55 | The pin-mapping node is under the `zephyr,user` node of DTS. 56 | `digital-pin-gpios` defines digital input/output pins that is D0, D1, .., 57 | `adc-pin-gpios` defines analog input pins that is A0, A1, ... . 58 | `pwm-pin-gpios` defines PWM pins. 59 | Each pin specifies in the form of a GPIO cell. 60 | Usually, it is in the form of `<[port] [pin-number] [flag]>`. 61 | You can also use the Arduino header node definition here. 62 | 63 | ### Overlays using previously-defined Arduino headers 64 | 65 | When an Arduino header exists in a board's in-tree DTS file it can easily be 66 | used to create the necessary overlay file. Assign the relevant mapping using the 67 | Arduino header label (usually either `&arduino_header` or `&arduino_nano_header` 68 | and the `gpio_map` number. The second number is used to add GPIO flags and may 69 | safely be left as zero. 70 | 71 | For example, creating an overlay file for the Nordic nRF52840 Development Kit 72 | uses [the Arduino header definitions](https://github.com/zephyrproject-rtos/zephyr/blob/6f8ee2cdf7dd4d746de58909204ea0ce156d5bb4/boards/arm/nrf52840dk_nrf52840/nrf52840dk_nrf52840.dts#L74-L101), beginning with the first digital pin: 73 | 74 | ``` 75 | / { 76 | zephyr,user { 77 | digital-pin-gpios = <&arduino_header 6 0>, /* Digital */ 78 | <&arduino_header 7 0>; 79 | ... 80 | <&arduino_header 19 0>; 81 | <&arduino_header 0 0>; /* Analog */ 82 | <&arduino_header 1 0>; 83 | ... 84 | <&arduino_header 5 0>; 85 | <&arduino_header 20 0>; /* SDA */ 86 | <&arduino_header 21 0>; /* SCL */ 87 | <&gpio0 13 GPIO_ACTIVE_LOW>; /* LED0 */ 88 | }; 89 | }; 90 | }; 91 | ``` 92 | 93 | ### Configure Serial devices 94 | 95 | The `serials` node defines the Serial devices to use. 96 | It instantiate the `Serial` with the UART device that contained in the node. 97 | Also instantiate as `Serial1`, `Serial2`, .. `SerialN` with the devices that is 98 | after the second in the case of the array contains plural devices. 99 | 100 | If the `serials` node is not defined, Use the node labeled `arduino-serial`. 101 | Boards with Arduino-shield style connectors usually label `arduino-serial` for 102 | UART port exposed in header or frequently used UART port. 103 | 104 | If even 'arduino_serial' does not define, it uses the stub implementation 105 | that redirects to printk(). 106 | 107 | The following example instantiates `Serial` and `Serial1` with each `uart0` and `uart1`. 108 | 109 | ``` 110 | / { 111 | zephyr,user { 112 | serials = <&uart0, &uart1>; 113 | }; 114 | }; 115 | ``` 116 | 117 | ### Configure I2C devices 118 | 119 | The `i2cs` node defines the I2C devices to use. 120 | It instantiate the `Wire` with the i2c device that contained in the node. 121 | Also instantiate as `Wire1`, `Wire2`, .. `WireN` with the devices 122 | that is after the second in the case of the array contains plural devices. 123 | 124 | If the `i2cs` node is not defined, Use the node labeled `arduino-i2c`. 125 | Boards with Arduino-shield style connectors usually label `arduino-i2c` 126 | to i2c exposed in the connector. 127 | 128 | The following example instantiates `Wire` and `Wire2` with each `i2c0` and `i2c1`. 129 | 130 | ``` 131 | / { 132 | zephyr,user { 133 | i2cs = <&i2c0, &i2c1>; 134 | }; 135 | }; 136 | ``` 137 | 138 | ### Configure Builtin-LED 139 | 140 | The `builtin-led-gpios` node defines the Builtin-LED. 141 | This node defines the `LED_BUILTIN` value by looking up the `digital-pin-gpios` 142 | array to find the index of the pin. 143 | 144 | The node is phandle-array, which uses the format same as `digital-pin-gpios`. 145 | 146 | It set the digital pin number to the `LED_BUILTIN` if found the pin 147 | that defined in `builtin-led-gpios` from `digital-pin-gpios`. 148 | 149 | If the `builtin-led-gpios` is not defined, Use the node aliased as `led0` 150 | to define `LED_BUILTIN`. 151 | 152 | The `LED_BUILTIN` does not define here if it has not found both nodes or 153 | defined `LED_BUILTIN` already. 154 | 155 | For example, in the case of the 13th digital pins connected to the onboard LED, 156 | define `builtin-led-gpios` as follows. 157 | 158 | ``` 159 | / { 160 | zephyr,user { 161 | builtin-led-gpios = <&arduino_nano_header 13 0>; 162 | }; 163 | }; 164 | ``` 165 | 166 | ### Overlays from scratch 167 | 168 | You can see in the example above that there is no mapping for `LED0` in the 169 | board's Arduino header definition so it has been added using the Zephyr `gpios` 170 | syntax (port, pin, flags). When creating an overlay file that doesn't have an 171 | Arduino header defined, you should follow this syntax for adding all pins 172 | 173 | ### You control the pin mapping 174 | 175 | Zephyr [chooses to map Arduino headers beginning with the Analog 176 | pins](https://docs.zephyrproject.org/latest/build/dts/api/bindings/gpio/arduino-header-r3.html), 177 | but the overlay file example above begins with the digital pins. This is to 178 | match user 179 | expectation that issuing `pinMode(0,OUTPUT);` should control digital pin 0 (and 180 | not pin 6). In the same way, the Analog 0 pin was mapped to D14 as this is 181 | likely what a shield made for the Arduino Uno R3 header would expect. 182 | 183 | Ultimately the mapping is completely up to you and should match the needs of the 184 | sketch you will be compiling. 185 | 186 | ## Creating the pinmap header file 187 | 188 | It is recommended that you copy an existing pinmap file from one of the board 189 | folders inside of the variants folder. For the most part, this header file will 190 | not change from board to board. 191 | 192 | One example of a change that you may find useful is mapping additional pins. For 193 | example, the LEDs on the nRF52840 are not connected to any of the Arduino header 194 | pins. To define a built-in LED for this board, a 22nd pin definition was added. 195 | 196 | Your pinmap header file must be added to the variant.h file by adding three 197 | lines using this format: 198 | 199 | ```c 200 | #ifdef CONFIG_BOARD_NRF52840DK_NRF52840 201 | #include "nrf52840dk_nrf52840.h" 202 | #endif // CONFIG_BOARD_NRF52840DK_NRF52840 203 | ``` 204 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /cores/arduino/zephyrCommon.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2022 Dhruva Gole 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include 8 | #include "zephyrInternal.h" 9 | 10 | static const struct gpio_dt_spec arduino_pins[] = {DT_FOREACH_PROP_ELEM_SEP( 11 | DT_PATH(zephyr_user), digital_pin_gpios, GPIO_DT_SPEC_GET_BY_IDX, (, ))}; 12 | 13 | namespace { 14 | 15 | /* 16 | * Calculate GPIO ports/pins number statically from devicetree configuration 17 | */ 18 | 19 | template constexpr const N sum_of_list(const N sum, const Head &head) 20 | { 21 | return sum + head; 22 | } 23 | 24 | template 25 | constexpr const N sum_of_list(const N sum, const Head &head, const Tail &...tail) 26 | { 27 | return sum_of_list(sum + head, tail...); 28 | } 29 | 30 | template constexpr const N max_in_list(const N max, const Head &head) 31 | { 32 | return (max >= head) ? max : head; 33 | } 34 | 35 | template 36 | constexpr const N max_in_list(const N max, const Head &head, const Tail &...tail) 37 | { 38 | return max_in_list((max >= head) ? max : head, tail...); 39 | } 40 | 41 | template 42 | constexpr const size_t is_first_appearance(const size_t &idx, const size_t &at, const size_t &found, 43 | const Query &query, const Head &head) 44 | { 45 | return ((found == ((size_t)-1)) && (query == head) && (idx == at)) ? 1 : 0; 46 | } 47 | 48 | template 49 | constexpr const size_t is_first_appearance(const size_t &idx, const size_t &at, const size_t &found, 50 | const Query &query, const Head &head, 51 | const Tail &...tail) 52 | { 53 | return ((found == ((size_t)-1)) && (query == head) && (idx == at)) 54 | ? 1 55 | : is_first_appearance(idx + 1, at, (query == head ? idx : found), query, 56 | tail...); 57 | } 58 | 59 | #define GET_DEVICE_VARGS(n, p, i, _) DEVICE_DT_GET(DT_GPIO_CTLR_BY_IDX(n, p, i)) 60 | #define FIRST_APPEARANCE(n, p, i) \ 61 | is_first_appearance(0, i, ((size_t)-1), DEVICE_DT_GET(DT_GPIO_CTLR_BY_IDX(n, p, i)), \ 62 | DT_FOREACH_PROP_ELEM_SEP_VARGS(n, p, GET_DEVICE_VARGS, (, ), 0)) 63 | const int port_num = 64 | sum_of_list(0, DT_FOREACH_PROP_ELEM_SEP(DT_PATH(zephyr_user), digital_pin_gpios, 65 | FIRST_APPEARANCE, (, ))); 66 | 67 | #define GPIO_NGPIOS(n, p, i) DT_PROP(DT_GPIO_CTLR_BY_IDX(n, p, i), ngpios) 68 | const int max_ngpios = max_in_list( 69 | 0, DT_FOREACH_PROP_ELEM_SEP(DT_PATH(zephyr_user), digital_pin_gpios, GPIO_NGPIOS, (, ))); 70 | 71 | /* 72 | * GPIO callback implementation 73 | */ 74 | 75 | struct arduino_callback { 76 | voidFuncPtr handler; 77 | bool enabled; 78 | }; 79 | 80 | struct gpio_port_callback { 81 | struct gpio_callback callback; 82 | struct arduino_callback handlers[max_ngpios]; 83 | gpio_port_pins_t pins; 84 | const struct device *dev; 85 | } port_callback[port_num] = {0}; 86 | 87 | struct gpio_port_callback *find_gpio_port_callback(const struct device *dev) 88 | { 89 | for (size_t i = 0; i < ARRAY_SIZE(port_callback); i++) { 90 | if (port_callback[i].dev == dev) { 91 | return &port_callback[i]; 92 | } 93 | if (port_callback[i].dev == nullptr) { 94 | port_callback[i].dev = dev; 95 | return &port_callback[i]; 96 | } 97 | } 98 | 99 | return nullptr; 100 | } 101 | 102 | void setInterruptHandler(pin_size_t pinNumber, voidFuncPtr func) 103 | { 104 | struct gpio_port_callback *pcb = find_gpio_port_callback(arduino_pins[pinNumber].port); 105 | 106 | if (pcb) { 107 | pcb->handlers[arduino_pins[pinNumber].pin].handler = func; 108 | } 109 | } 110 | 111 | void handleGpioCallback(const struct device *port, struct gpio_callback *cb, uint32_t pins) 112 | { 113 | struct gpio_port_callback *pcb = (struct gpio_port_callback *)cb; 114 | 115 | for (uint32_t i = 0; i < max_ngpios; i++) { 116 | if (pins & BIT(i) && pcb->handlers[i].enabled) { 117 | pcb->handlers[i].handler(); 118 | } 119 | } 120 | } 121 | 122 | #ifdef CONFIG_PWM 123 | 124 | #define PWM_DT_SPEC(n,p,i) PWM_DT_SPEC_GET_BY_IDX(n, i), 125 | #define PWM_PINS(n, p, i) \ 126 | DIGITAL_PIN_GPIOS_FIND_PIN( \ 127 | DT_REG_ADDR(DT_PHANDLE_BY_IDX(DT_PATH(zephyr_user), p, i)), \ 128 | DT_PHA_BY_IDX(DT_PATH(zephyr_user), p, i, pin)), 129 | 130 | const struct pwm_dt_spec arduino_pwm[] = 131 | { DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user), pwms, PWM_DT_SPEC) }; 132 | 133 | /* pwm-pins node provides a mapping digital pin numbers to pwm channels */ 134 | const pin_size_t arduino_pwm_pins[] = 135 | { DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user), pwm_pin_gpios, PWM_PINS) }; 136 | 137 | size_t pwm_pin_index(pin_size_t pinNumber) { 138 | for(size_t i=0; ipin]; 231 | 232 | if (pt->count == 0) { 233 | k_timer_stop(timer); 234 | gpio_pin_set_dt(spec, 0); 235 | } else { 236 | gpio_pin_toggle_dt(spec); 237 | if (!pt->infinity) { 238 | pt->count--; 239 | } 240 | } 241 | } 242 | 243 | void tone(pin_size_t pinNumber, unsigned int frequency, 244 | unsigned long duration) { 245 | const struct gpio_dt_spec *spec = &arduino_pins[pinNumber]; 246 | struct k_timer *timer; 247 | k_timeout_t timeout; 248 | 249 | if (pinNumber >= MAX_TONE_PINS) { 250 | return; 251 | } 252 | 253 | timer = &arduino_pin_timers[pinNumber].timer; 254 | 255 | pinMode(pinNumber, OUTPUT); 256 | k_timer_stop(&arduino_pin_timers[pinNumber].timer); 257 | 258 | if (frequency == 0) { 259 | gpio_pin_set_dt(spec, 0); 260 | return; 261 | } 262 | 263 | timeout = K_NSEC(NSEC_PER_SEC / (TOGGLES_PER_CYCLE * frequency)); 264 | if (timeout.ticks == 0) { 265 | timeout.ticks = 1; 266 | } 267 | 268 | arduino_pin_timers[pinNumber].infinity = (duration == 0); 269 | arduino_pin_timers[pinNumber].count = (uint64_t)duration * frequency * 270 | (MSEC_PER_SEC / TOGGLES_PER_CYCLE); 271 | arduino_pin_timers[pinNumber].pin = pinNumber; 272 | k_timer_init(timer, tone_expiry_cb, NULL); 273 | 274 | gpio_pin_set_dt(spec, 0); 275 | k_timer_start(timer, timeout, timeout); 276 | } 277 | 278 | void noTone(pin_size_t pinNumber) { 279 | const struct gpio_dt_spec *spec = &arduino_pins[pinNumber]; 280 | 281 | k_timer_stop(&arduino_pin_timers[pinNumber].timer); 282 | gpio_pin_set_dt(spec, 0); 283 | } 284 | 285 | void delay(unsigned long ms) { 286 | k_sleep(K_MSEC(ms)); 287 | } 288 | 289 | void delayMicroseconds(unsigned int us) { 290 | k_busy_wait(us); 291 | } 292 | 293 | unsigned long micros(void) { 294 | return k_cyc_to_us_floor32(k_cycle_get_32()); 295 | } 296 | 297 | unsigned long millis(void) { 298 | return k_uptime_get_32(); 299 | } 300 | 301 | #ifdef CONFIG_PWM 302 | 303 | void analogWrite(pin_size_t pinNumber, int value) 304 | { 305 | size_t idx = pwm_pin_index(pinNumber); 306 | 307 | if (idx >= ARRAY_SIZE(arduino_pwm)) { 308 | return; 309 | } 310 | 311 | if (!pwm_is_ready_dt(&arduino_pwm[idx])) { 312 | return; 313 | } 314 | 315 | if (((uint32_t)value) > arduino_pwm[idx].period) { 316 | value = arduino_pwm[idx].period; 317 | } else if (value < 0) { 318 | value = 0; 319 | } 320 | 321 | /* 322 | * A duty ratio determines by the period value defined in dts 323 | * and the value arguments. So usually the period value sets as 255. 324 | */ 325 | (void)pwm_set_pulse_dt(&arduino_pwm[idx], value); 326 | } 327 | 328 | #endif 329 | 330 | #ifdef CONFIG_ADC 331 | 332 | void analogReference(uint8_t mode) 333 | { 334 | /* 335 | * The Arduino API not clearly defined what means of 336 | * the mode argument of analogReference(). 337 | * Treat the value as equivalent to zephyr's adc_reference. 338 | */ 339 | for (size_t i=0; i(mode); 341 | } 342 | } 343 | 344 | int analogRead(pin_size_t pinNumber) 345 | { 346 | int err; 347 | int16_t buf; 348 | struct adc_sequence seq = { .buffer = &buf, .buffer_size = sizeof(buf) }; 349 | size_t idx = analog_pin_index(pinNumber); 350 | 351 | if (idx >= ARRAY_SIZE(arduino_adc) ) { 352 | return -EINVAL; 353 | } 354 | 355 | /* 356 | * ADC that is on MCU supported by Zephyr exists 357 | * only 16bit resolution, currently. 358 | */ 359 | if (arduino_adc[idx].resolution > 16) { 360 | return -ENOTSUP; 361 | } 362 | 363 | err = adc_channel_setup(arduino_adc[idx].dev, &arduino_adc[idx].channel_cfg); 364 | if (err < 0) { 365 | return err; 366 | } 367 | 368 | seq.channels = BIT(arduino_adc[idx].channel_id); 369 | seq.resolution = arduino_adc[idx].resolution; 370 | seq.oversampling = arduino_adc[idx].oversampling; 371 | 372 | err = adc_read(arduino_adc[idx].dev, &seq); 373 | if (err < 0) { 374 | return err; 375 | } 376 | 377 | return buf; 378 | } 379 | 380 | #endif 381 | 382 | void attachInterrupt(pin_size_t pinNumber, voidFuncPtr callback, PinStatus pinStatus) 383 | { 384 | struct gpio_port_callback *pcb; 385 | gpio_flags_t intmode = 0; 386 | 387 | if (!callback) { 388 | return; 389 | } 390 | 391 | if (pinStatus == LOW) { 392 | intmode |= GPIO_INT_LEVEL_LOW; 393 | } else if (pinStatus == HIGH) { 394 | intmode |= GPIO_INT_LEVEL_HIGH; 395 | } else if (pinStatus == CHANGE) { 396 | intmode |= GPIO_INT_EDGE_BOTH; 397 | } else if (pinStatus == FALLING) { 398 | intmode |= GPIO_INT_EDGE_FALLING; 399 | } else if (pinStatus == RISING) { 400 | intmode |= GPIO_INT_EDGE_RISING; 401 | } else { 402 | return; 403 | } 404 | 405 | pcb = find_gpio_port_callback(arduino_pins[pinNumber].port); 406 | __ASSERT(pcb != nullptr, "gpio_port_callback not found"); 407 | 408 | pcb->pins |= BIT(arduino_pins[pinNumber].pin); 409 | setInterruptHandler(pinNumber, callback); 410 | enableInterrupt(pinNumber); 411 | 412 | gpio_pin_interrupt_configure(arduino_pins[pinNumber].port, arduino_pins[pinNumber].pin, intmode); 413 | gpio_init_callback(&pcb->callback, handleGpioCallback, pcb->pins); 414 | gpio_add_callback(arduino_pins[pinNumber].port, &pcb->callback); 415 | } 416 | 417 | void detachInterrupt(pin_size_t pinNumber) 418 | { 419 | setInterruptHandler(pinNumber, nullptr); 420 | disableInterrupt(pinNumber); 421 | } 422 | 423 | #ifndef CONFIG_MINIMAL_LIBC_RAND 424 | 425 | #include 426 | 427 | void randomSeed(unsigned long seed) { 428 | srand(seed); 429 | } 430 | 431 | long random(long min, long max) { 432 | return rand() % (max - min) + min; 433 | } 434 | 435 | long random(long max) { 436 | return rand() % max; 437 | } 438 | 439 | #endif 440 | 441 | unsigned long pulseIn(pin_size_t pinNumber, uint8_t state, unsigned long timeout) { 442 | struct k_timer timer; 443 | int64_t start, end, delta = 0; 444 | const struct gpio_dt_spec *spec = &arduino_pins[pinNumber]; 445 | 446 | if (!gpio_is_ready_dt(spec)) { 447 | return 0; 448 | } 449 | 450 | k_timer_init(&timer, NULL, NULL); 451 | k_timer_start(&timer, K_MSEC(timeout), K_NO_WAIT); 452 | 453 | while(gpio_pin_get_dt(spec) == state && k_timer_status_get(&timer) == 0); 454 | if (k_timer_status_get(&timer) > 0) { 455 | goto cleanup; 456 | } 457 | 458 | while(gpio_pin_get_dt(spec) != state && k_timer_status_get(&timer) == 0); 459 | if (k_timer_status_get(&timer) > 0) { 460 | goto cleanup; 461 | } 462 | 463 | start = k_uptime_ticks(); 464 | while(gpio_pin_get_dt(spec) == state && k_timer_status_get(&timer) == 0); 465 | if (k_timer_status_get(&timer) > 0) { 466 | goto cleanup; 467 | } 468 | end = k_uptime_ticks(); 469 | 470 | delta = k_ticks_to_us_floor64(end - start); 471 | 472 | cleanup: 473 | k_timer_stop(&timer); 474 | return (unsigned long)delta; 475 | } 476 | 477 | void enableInterrupt(pin_size_t pinNumber) { 478 | struct gpio_port_callback *pcb = find_gpio_port_callback(arduino_pins[pinNumber].port); 479 | 480 | if (pcb) { 481 | pcb->handlers[arduino_pins[pinNumber].pin].enabled = true; 482 | } 483 | } 484 | 485 | void disableInterrupt(pin_size_t pinNumber) { 486 | struct gpio_port_callback *pcb = find_gpio_port_callback(arduino_pins[pinNumber].port); 487 | 488 | if (pcb) { 489 | pcb->handlers[arduino_pins[pinNumber].pin].enabled = false; 490 | } 491 | } 492 | 493 | void interrupts(void) { 494 | if (interrupts_disabled) { 495 | irq_unlock(irq_key); 496 | interrupts_disabled = false; 497 | } 498 | } 499 | 500 | void noInterrupts(void) { 501 | if (!interrupts_disabled) { 502 | irq_key = irq_lock(); 503 | interrupts_disabled = true; 504 | } 505 | } 506 | 507 | int digitalPinToInterrupt(pin_size_t pin) { 508 | struct gpio_port_callback *pcb = 509 | find_gpio_port_callback(arduino_pins[pin].port); 510 | 511 | return (pcb) ? pin : -1; 512 | } 513 | --------------------------------------------------------------------------------