Skip to content

Commit

Permalink
gpio: adds basic digital i/o support
Browse files Browse the repository at this point in the history
* Map gpios as D1,2,etc to their gpionum and pinNum as per arduino_nano_r3_connector.dtsi
* pulldown i/p mode gpio by default
* implements pinMode, digitalRead, Write, delay and delayMicroseconds
* Includes examples for push button LED and blink LED and hello world
* For a comprehensive commit history on GPIO refer: DhruvaG2000/Arduino-Core-Zephyr#4

Signed-off-by: Dhruva Gole <[email protected]>
  • Loading branch information
DhruvaG2000 committed Jul 1, 2022
1 parent 8f8544f commit 1fcf0cc
Show file tree
Hide file tree
Showing 24 changed files with 458 additions and 0 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
add_subdirectory(cores)
39 changes: 39 additions & 0 deletions Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#
# Copyright (c) 2020 Toita, Hiroshi
#
# SPDX-License-Identifier: Apache-2.0
#

config ARDUINO_API
bool "ARDUINO_API"
depends on CPLUSPLUS
default n

if ARDUINO_API

config ARDUINO_MAIN_LOOP
bool "ARDUINO_MAIN_LOOP"
default n

config ARDUINO_GPIO
bool "ARDUINO_API"
depends on GPIO
default y

config ARDUINO_QUERY_PIN_CONFIG
bool
depends on ARDUINO_GPIO
default n

config ARDUINO_UART
bool "ARDUINO_API"
depends on SERIAL
depends on UART_INTERRUPT_DRIVEN
default y

config QEMU_ICOUNT
bool "QEMU icount mode"
default n
depends on QEMU_TARGET

endif
1 change: 1 addition & 0 deletions cores/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
add_subdirectory(arduino)
6 changes: 6 additions & 0 deletions cores/arduino/Arduino.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#include "api/ArduinoAPI.h"

/* Zephyr libraries */
#include "arduino_nano_ble_sense_pinmap.h"
#include <zephyr/drivers/gpio.h>
#include <zephyr/zephyr.h>
10 changes: 10 additions & 0 deletions cores/arduino/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# SPDX-License-Identifier: Apache-2.0
zephyr_include_directories(.)

if(NOT DEFINED ARDUINO_BUILD_PATH)

zephyr_sources(zephyrCommon.cpp)
zephyr_sources(main.cpp)

endif()

29 changes: 29 additions & 0 deletions cores/arduino/arduino_nano_ble_sense_pinmap.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
All the pins that are 100 + x are gpio1 pins and < 100 are in gpio0
*/
#define LED_BUILTIN 13

enum digitalPins {
D0 = 103,
D1 = 110,
D2 = 111,
D3 = 112,
D4 = 115,
D5 = 113,
D6 = 114,
D7 = 9,
D8 = 10,
D9 = 27,
D10 = 102,
D11 = 101,
D12 = 108,
D13 = 13,
D14 = 4,
D15 = 5,
D16 = 30,
D17 = 29,
D18 = 14,
D19 = 15,
D20 = 28,
D21 = 103
};
11 changes: 11 additions & 0 deletions cores/arduino/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include "Arduino.h"

int main(void) {
setup();

for (;;) {
loop();
}

return 0;
}
59 changes: 59 additions & 0 deletions cores/arduino/zephyrCommon.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#include "Arduino.h"

void pinMode(pin_size_t pinNumber, PinMode pinMode) {
if (pinNumber >= 100) {
pinNumber -= 100;
if (pinMode == INPUT || pinMode == INPUT_PULLDOWN) {
gpio_pin_configure(DEVICE_DT_GET(DT_NODELABEL(gpio1)), pinNumber,
GPIO_INPUT | GPIO_ACTIVE_LOW);
} else {
gpio_pin_configure(DEVICE_DT_GET(DT_NODELABEL(gpio1)), pinNumber,
GPIO_OUTPUT);
}
} else if (pinNumber < 100) {
if (pinMode == INPUT || pinMode == INPUT_PULLDOWN) {
gpio_pin_configure(DEVICE_DT_GET(DT_NODELABEL(gpio0)), pinNumber,
GPIO_INPUT | GPIO_ACTIVE_LOW);
} else {
gpio_pin_configure(DEVICE_DT_GET(DT_NODELABEL(gpio0)), pinNumber,
GPIO_OUTPUT);
}
}
}

void digitalWrite(pin_size_t pinNumber, PinStatus status) {
if (pinNumber >= 100) {
pinNumber -= 100;
if (status == HIGH) {
gpio_pin_set(DEVICE_DT_GET(DT_NODELABEL(gpio1)), pinNumber,
GPIO_ACTIVE_HIGH);
} else if (status == LOW) {
gpio_pin_set(DEVICE_DT_GET(DT_NODELABEL(gpio1)), pinNumber,
GPIO_ACTIVE_LOW);
}
} else if (pinNumber < 100) {
if (status == HIGH) {
gpio_pin_set(DEVICE_DT_GET(DT_NODELABEL(gpio0)), pinNumber,
GPIO_ACTIVE_HIGH);
} else if (status == LOW) {
gpio_pin_set(DEVICE_DT_GET(DT_NODELABEL(gpio0)), pinNumber,
GPIO_ACTIVE_LOW);
}
}
}

PinStatus digitalRead(pin_size_t pinNumber) {
if (pinNumber >= 100) {
pinNumber -= 100;
return (gpio_pin_get(DEVICE_DT_GET(DT_NODELABEL(gpio1)), pinNumber) == 1)
? HIGH
: LOW;
}
return (gpio_pin_get(DEVICE_DT_GET(DT_NODELABEL(gpio0)), pinNumber) == 1)
? HIGH
: LOW;
}

void delay(unsigned long ms) { k_sleep(K_MSEC(ms)); }

void delayMicroseconds(unsigned int us) { k_sleep(K_USEC(us)); }
7 changes: 7 additions & 0 deletions examples/blinky_arduino/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(blinky)

target_sources(app PRIVATE src/main.cpp)
71 changes: 71 additions & 0 deletions examples/blinky_arduino/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
.. _blinky-sample:

Blinky
######

Overview
********

This Arduino Blinky sample blinks an LED forever using the `ArduinoAPI`.

Requirements
************

Your board must:

#. Have an LED connected via a GPIO pin (these are called "User LEDs" on many of
Zephyr's :ref:`boards`).
#. Have the LED configured using the ``led0`` devicetree alias.

Building and Running
********************

Build and flash Blinky as follows,

```sh
$> west build -p -b arduino_nano_33_ble samples/basic/arduino-blinky/ -DZEPHYR_EXTRA_MODULES=/home/$USER/zephyrproject/modules/lib/Arduino-Core-Zephyr
$> west flash --bossac=/home/$USER/.arduino15/packages/arduino/tools/bossac/1.9.1-arduino2/bossac
```

After flashing, the LED starts to blink. If a runtime error occurs, the sample
exits without printing to the console.

Adding board support
********************

To add support for your board, add something like this to your devicetree:

.. code-block:: DTS
/ {
aliases {
led0 = &myled0;
};
leds {
compatible = "gpio-leds";
myled0: led_0 {
gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
};
};
};
The above sets your board's ``led0`` alias to use pin 13 on GPIO controller
``gpio0``. The pin flags :c:macro:`GPIO_ACTIVE_HIGH` mean the LED is on when
the pin is set to its high state, and off when the pin is in its low state.

Tips:

- See :dtcompatible:`gpio-leds` for more information on defining GPIO-based LEDs
in devicetree.

- If you're not sure what to do, check the devicetrees for supported boards which
use the same SoC as your target. See :ref:`get-devicetree-outputs` for details.

- See :zephyr_file:`include/zephyr/dt-bindings/gpio/gpio.h` for the flags you can use
in devicetree.

- If the LED is built in to your board hardware, the alias should be defined in
your :ref:`BOARD.dts file <devicetree-in-out-files>`. Otherwise, you can
define one in a :ref:`devicetree overlay <set-devicetree-overlays>`.
3 changes: 3 additions & 0 deletions examples/blinky_arduino/prj.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
CONFIG_GPIO=y
CONFIG_CPLUSPLUS=y
CONFIG_ARDUINO_API=y
10 changes: 10 additions & 0 deletions examples/blinky_arduino/sample.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
sample:
name: Blinky Sample
tests:
sample.basic.blinky:
tags: LED gpio
filter: dt_enabled_alias_with_parent_compat("led0", "gpio-leds")
depends_on: gpio
harness: led
integration_platforms:
- frdm_k64f
15 changes: 15 additions & 0 deletions examples/blinky_arduino/src/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/* Blink inbuilt LED example */

#include <Arduino.h>

/* 1000 msec = 1 sec */
#define SLEEP_TIME_MS 1000

void setup() { pinMode(LED_BUILTIN, OUTPUT); }

void loop() {
digitalWrite(LED_BUILTIN, HIGH);
delay(SLEEP_TIME_MS);
digitalWrite(LED_BUILTIN, LOW);
delay(SLEEP_TIME_MS);
}
7 changes: 7 additions & 0 deletions examples/button_press_led/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(blinky)

target_sources(app PRIVATE src/main.cpp)
67 changes: 67 additions & 0 deletions examples/button_press_led/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
Button press LED
######

Overview
********

This Arduino sample turns ON an LED if button pressed using the `ArduinoAPI`.

Requirements
************

Your board must:

#. Have an LED connected via a GPIO pin (these are called "User LEDs" on many of
Zephyr's :ref:`boards`).
#. Have the LED configured using the ``led0`` devicetree alias.
#. Have a button connected to pin `D9` of the arduino externally (pulled down by default)

Building and Running
********************

Build and flash as follows,

```sh
$> west build -p -b arduino_nano_33_ble samples/button_press_led -DZEPHYR_EXTRA_MODULES=/home/$USER/zephyrproject/modules/lib/Arduino-Core-Zephyr
$> west flash --bossac=/home/$USER/.arduino15/packages/arduino/tools/bossac/1.9.1-arduino2/bossac
```

Adding board support
********************

To add support for your board, add something like this to your devicetree:

.. code-block:: DTS
/ {
aliases {
led0 = &myled0;
};
leds {
compatible = "gpio-leds";
myled0: led_0 {
gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
};
};
};
The above sets your board's ``led0`` alias to use pin 13 on GPIO controller
``gpio0``. The pin flags :c:macro:`GPIO_ACTIVE_HIGH` mean the LED is on when
the pin is set to its high state, and off when the pin is in its low state.

Tips:

- See :dtcompatible:`gpio-leds` for more information on defining GPIO-based LEDs
in devicetree.

- If you're not sure what to do, check the devicetrees for supported boards which
use the same SoC as your target. See :ref:`get-devicetree-outputs` for details.

- See :zephyr_file:`include/zephyr/dt-bindings/gpio/gpio.h` for the flags you can use
in devicetree.

- If the LED is built in to your board hardware, the alias should be defined in
your :ref:`BOARD.dts file <devicetree-in-out-files>`. Otherwise, you can
define one in a :ref:`devicetree overlay <set-devicetree-overlays>`.
3 changes: 3 additions & 0 deletions examples/button_press_led/prj.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
CONFIG_GPIO=y
CONFIG_CPLUSPLUS=y
CONFIG_ARDUINO_API=y
10 changes: 10 additions & 0 deletions examples/button_press_led/sample.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
sample:
name: Blinky Sample
tests:
sample.basic.blinky:
tags: LED gpio
filter: dt_enabled_alias_with_parent_compat("led0", "gpio-leds")
depends_on: gpio
harness: led
integration_platforms:
- frdm_k64f
Loading

0 comments on commit 1fcf0cc

Please sign in to comment.