From 74974de7d793e4528d1c35e83f9fbcb86546d168 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Cl=C3=A9ment=20Foucher?= <cfoucher@laas.fr>
Date: Thu, 29 Sep 2022 17:07:30 +0000
Subject: [PATCH] Define an API for GPIO easy handling.

---
 .../owntech_gpio_api/zephyr/CMakeLists.txt    |  10 ++
 .../modules/owntech_gpio_api/zephyr/Kconfig   |   3 +
 .../owntech_gpio_api/zephyr/module.yml        |   4 +
 .../zephyr/public_api/GpioApi.cpp             | 112 +++++++++++++++
 .../zephyr/public_api/GpioApi.h               | 134 ++++++++++++++++++
 zephyr/prj.conf                               |   1 +
 6 files changed, 264 insertions(+)
 create mode 100644 zephyr/modules/owntech_gpio_api/zephyr/CMakeLists.txt
 create mode 100644 zephyr/modules/owntech_gpio_api/zephyr/Kconfig
 create mode 100644 zephyr/modules/owntech_gpio_api/zephyr/module.yml
 create mode 100644 zephyr/modules/owntech_gpio_api/zephyr/public_api/GpioApi.cpp
 create mode 100644 zephyr/modules/owntech_gpio_api/zephyr/public_api/GpioApi.h

diff --git a/zephyr/modules/owntech_gpio_api/zephyr/CMakeLists.txt b/zephyr/modules/owntech_gpio_api/zephyr/CMakeLists.txt
new file mode 100644
index 0000000..5b7a7f9
--- /dev/null
+++ b/zephyr/modules/owntech_gpio_api/zephyr/CMakeLists.txt
@@ -0,0 +1,10 @@
+if(CONFIG_OWNTECH_GPIO_API)
+  # Select directory to add to the include path
+  zephyr_include_directories(./public_api)
+  # Define the current folder as a Zephyr library
+  zephyr_library()
+  # Select source files to be compiled
+  zephyr_library_sources(
+    public_api/GpioApi.cpp
+    )
+endif()
diff --git a/zephyr/modules/owntech_gpio_api/zephyr/Kconfig b/zephyr/modules/owntech_gpio_api/zephyr/Kconfig
new file mode 100644
index 0000000..fa7dc79
--- /dev/null
+++ b/zephyr/modules/owntech_gpio_api/zephyr/Kconfig
@@ -0,0 +1,3 @@
+config OWNTECH_GPIO_API
+	bool "Enable OwnTech GPIO API"
+	default y
diff --git a/zephyr/modules/owntech_gpio_api/zephyr/module.yml b/zephyr/modules/owntech_gpio_api/zephyr/module.yml
new file mode 100644
index 0000000..e29ada4
--- /dev/null
+++ b/zephyr/modules/owntech_gpio_api/zephyr/module.yml
@@ -0,0 +1,4 @@
+name: owntech_gpio_api
+build:
+  cmake: zephyr
+  kconfig: zephyr/Kconfig
diff --git a/zephyr/modules/owntech_gpio_api/zephyr/public_api/GpioApi.cpp b/zephyr/modules/owntech_gpio_api/zephyr/public_api/GpioApi.cpp
new file mode 100644
index 0000000..c534d71
--- /dev/null
+++ b/zephyr/modules/owntech_gpio_api/zephyr/public_api/GpioApi.cpp
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2022 LAAS-CNRS
+ *
+ *   This program is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU Lesser General Public License as published by
+ *   the Free Software Foundation, either version 2.1 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU Lesser General Public License for more details.
+ *
+ *   You should have received a copy of the GNU Lesser General Public License
+ *   along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: LGLPV2.1
+ */
+
+/**
+ * @brief  Owntech GPIO API
+ * @date   2022
+ *
+ * @author Clément Foucher <clement.foucher@laas.fr>
+ */
+
+
+#include "GpioApi.h"
+
+GpioApi gpio;
+
+const struct device* const GPIO_A = DEVICE_DT_GET(DT_NODELABEL(gpioa));
+const struct device* const GPIO_B = DEVICE_DT_GET(DT_NODELABEL(gpiob));
+const struct device* const GPIO_C = DEVICE_DT_GET(DT_NODELABEL(gpioc));
+const struct device* const GPIO_D = DEVICE_DT_GET(DT_NODELABEL(gpiod));
+
+void GpioApi::configurePin(pin_t pin, gpio_flags_t flags)
+{
+	gpio_pin_t pin_number = this->getPinNumber(pin);
+	const struct device* port = this->getGpioDevice(pin);
+	if (port != nullptr)
+	{
+		gpio_pin_configure(port, pin_number, flags);
+	}
+}
+
+void GpioApi::setPin(pin_t pin)
+{
+	gpio_pin_t pin_number = this->getPinNumber(pin);
+	const struct device* port = this->getGpioDevice(pin);
+	if (port != nullptr)
+	{
+		gpio_pin_set(port, pin_number, 1);
+	}
+}
+
+void GpioApi::resetPin(pin_t pin)
+{
+	gpio_pin_t pin_number = this->getPinNumber(pin);
+	const struct device* port = this->getGpioDevice(pin);
+	if (port != nullptr)
+	{
+		gpio_pin_set(port, pin_number, 0);
+	}
+}
+
+void GpioApi::togglePin(pin_t pin)
+{
+	gpio_pin_t pin_number = this->getPinNumber(pin);
+	const struct device* port = this->getGpioDevice(pin);
+	if (port != nullptr)
+	{
+		gpio_pin_toggle(port, pin_number);
+	}
+}
+
+void GpioApi::writePin(pin_t pin, uint8_t value)
+{
+	gpio_pin_t pin_number = this->getPinNumber(pin);
+	const struct device* port = this->getGpioDevice(pin);
+	if (port != nullptr)
+	{
+		gpio_pin_set(port, pin_number, value);
+	}
+}
+
+gpio_pin_t GpioApi::getPinNumber(pin_t pin)
+{
+	return (((uint8_t)pin) & 0x0F) + 1;
+}
+
+const struct device* GpioApi::getGpioDevice(pin_t pin)
+{
+	uint8_t deviceNumber = ((uint8_t)pin) & 0xF0;
+	switch (deviceNumber)
+	{
+		case PA:
+			return GPIO_A;
+			break;
+		case PB:
+			return GPIO_B;
+			break;
+		case PC:
+			return GPIO_C;
+			break;
+		case PD:
+			return GPIO_D;
+			break;
+	}
+
+	return nullptr;
+}
diff --git a/zephyr/modules/owntech_gpio_api/zephyr/public_api/GpioApi.h b/zephyr/modules/owntech_gpio_api/zephyr/public_api/GpioApi.h
new file mode 100644
index 0000000..388c49c
--- /dev/null
+++ b/zephyr/modules/owntech_gpio_api/zephyr/public_api/GpioApi.h
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2022 LAAS-CNRS
+ *
+ *   This program is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU Lesser General Public License as published by
+ *   the Free Software Foundation, either version 2.1 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU Lesser General Public License for more details.
+ *
+ *   You should have received a copy of the GNU Lesser General Public License
+ *   along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: LGLPV2.1
+ */
+
+/**
+ * @brief  Owntech GPIO API
+ * @date   2022
+ *
+ * @author Clément Foucher <clement.foucher@laas.fr>
+ */
+
+#ifndef GPIOAPI_H_
+#define GPIOAPI_H_
+
+#include <drivers/gpio.h>
+
+extern const struct device* const GPIO_A;
+extern const struct device* const GPIO_B;
+extern const struct device* const GPIO_C;
+extern const struct device* const GPIO_D;
+
+const gpio_flags_t INPUT        = GPIO_INPUT;
+const gpio_flags_t INPUT_PULLUP = GPIO_INPUT | GPIO_PULL_UP;
+const gpio_flags_t OUTPUT       = GPIO_OUTPUT;
+
+const uint8_t PA = 0x00;
+const uint8_t PB = 0x10;
+const uint8_t PC = 0x20;
+const uint8_t PD = 0x30;
+
+const uint8_t P1  = 0x0;
+const uint8_t P2  = 0x1;
+const uint8_t P3  = 0x2;
+const uint8_t P4  = 0x3;
+const uint8_t P5  = 0x4;
+const uint8_t P6  = 0x5;
+const uint8_t P7  = 0x6;
+const uint8_t P8  = 0x7;
+const uint8_t P9  = 0x8;
+const uint8_t P10 = 0x9;
+const uint8_t P11 = 0xA;
+const uint8_t P12 = 0xB;
+const uint8_t P13 = 0xC;
+const uint8_t P14 = 0xD;
+const uint8_t P15 = 0xE;
+const uint8_t P16 = 0xF;
+
+typedef enum
+{
+	PA1  = PA | P1,
+	PA2  = PA | P2,
+	PA3  = PA | P3,
+	PA4  = PA | P4,
+	PA5  = PA | P5,
+	PA6  = PA | P6,
+	PA7  = PA | P7,
+	PA8  = PA | P8,
+	PA9  = PA | P9,
+	PA10 = PA | P10,
+	PA11 = PA | P11,
+	PA12 = PA | P12,
+	PA13 = PA | P13,
+	PA14 = PA | P14,
+	PA15 = PA | P15,
+	PA16 = PA | P16,
+	PB1  = PB | P1,
+	PB2  = PB | P2,
+	PB3  = PB | P3,
+	PB4  = PB | P4,
+	PB5  = PB | P5,
+	PB6  = PB | P6,
+	PB7  = PB | P7,
+	PB8  = PB | P8,
+	PB9  = PB | P9,
+	PB10 = PB | P10,
+	PB11 = PB | P11,
+	PB12 = PB | P12,
+	PB13 = PB | P13,
+	PB14 = PB | P14,
+	PB15 = PB | P15,
+	PB16 = PB | P16,
+	PC1  = PC | P1,
+	PC2  = PC | P2,
+	PC3  = PC | P3,
+	PC4  = PC | P4,
+	PC5  = PC | P5,
+	PC6  = PC | P6,
+	PC7  = PC | P7,
+	PC8  = PC | P8,
+	PC9  = PC | P9,
+	PC10 = PC | P10,
+	PC11 = PC | P11,
+	PC12 = PC | P12,
+	PC13 = PC | P13,
+	PC14 = PC | P14,
+	PC15 = PC | P15,
+	PC16 = PC | P16,
+	PD1  = PD | P1,
+	PD2  = PD | P2,
+	PD3  = PD | P3
+} pin_t;
+
+class GpioApi
+{
+public:
+	void configurePin(pin_t pin, gpio_flags_t flags);
+	void setPin(pin_t pin);
+	void resetPin(pin_t pin);
+	void togglePin(pin_t pin);
+	void writePin(pin_t pin, uint8_t value);
+
+private:
+	gpio_pin_t getPinNumber(pin_t pin);
+	const struct device* getGpioDevice(pin_t pin);
+};
+
+extern GpioApi gpio;
+
+#endif // GPIOAPI_H_
diff --git a/zephyr/prj.conf b/zephyr/prj.conf
index 9ce0fc6..233e66d 100644
--- a/zephyr/prj.conf
+++ b/zephyr/prj.conf
@@ -48,6 +48,7 @@ CONFIG_ASSERT=y
 #CONFIG_OWNTECH_DATA_ACQUISITION=n
 #CONFIG_OWNTECH_HARDWARE_CONFIGURATION=n
 #CONFIG_OWNTECH_SCHEDULING=n
+#CONFIG_OWNTECH_GPIO_API=n
 
 # Opt-in modules: uncomment a line to include a feature
 
-- 
GitLab