From cecc6f63bc6d7283a2f2fd88472dcde1ca56778c Mon Sep 17 00:00:00 2001
From: DAsamhan <23522019@std.stei.itb.ac.id>
Date: Sun, 23 Jun 2024 16:20:55 +0700
Subject: [PATCH] implement ir, LED driver and logic

---
 .vscode/settings.json                         |  7 ++
 debug-app/CMakeLists.txt                      |  2 +-
 debug-app/boards/esp32.overlay                | 58 ++++++++++++-
 debug-app/drivers/CMakeLists.txt              |  4 +-
 debug-app/drivers/ir-driver/src/ir-driver.cpp | 26 +++++-
 .../drivers/led-driver/src/led-driver.cpp     | 12 ++-
 debug-app/include/ir-driver.h                 |  8 +-
 debug-app/include/led-driver.h                |  1 +
 debug-app/include/main-handler.h              |  1 +
 debug-app/include/utilities.h                 | 13 ++-
 .../module/driver-hook/src/driver-hook.cpp    | 33 ++++---
 .../handler/main-handler/src/main-handler.cpp | 86 ++++++++++++-------
 12 files changed, 199 insertions(+), 52 deletions(-)
 create mode 100644 .vscode/settings.json

diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..23e9642
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,7 @@
+{
+    "files.associations": {
+        "deque": "cpp",
+        "string": "cpp",
+        "vector": "cpp"
+    }
+}
\ No newline at end of file
diff --git a/debug-app/CMakeLists.txt b/debug-app/CMakeLists.txt
index 6c6e18d..6a5839b 100644
--- a/debug-app/CMakeLists.txt
+++ b/debug-app/CMakeLists.txt
@@ -1,4 +1,4 @@
 zephyr_include_directories(include)
 
 add_subdirectory(module)
-add_subdirectory(drivers)
\ No newline at end of file
+add_subdirectory_ifndef(CONFIG_SOC_POSIX drivers)
\ No newline at end of file
diff --git a/debug-app/boards/esp32.overlay b/debug-app/boards/esp32.overlay
index 5256637..c11897f 100644
--- a/debug-app/boards/esp32.overlay
+++ b/debug-app/boards/esp32.overlay
@@ -4,6 +4,62 @@
  * SPDX-License-Identifier: Apache-2.0
  */
 
- &wifi {
+/{
+	aliases {
+		pwm-0 = &ledc0;
+		pwm-led0 = &pwm_led_blue;
+	};
+
+	gpio_in{
+		compatible = "gpio-keys";
+		ir_Sensor: ir_sensor{
+			gpios = <&gpio0 25 GPIO_ACTIVE_HIGH>;
+			label = "ir sensor interrupt";
+			status = "okay";
+		};
+	};
+
+	gpio_out{
+		compatible = "gpio-leds";
+		led_pin: led_pin{
+			gpios = <&gpio0 26 GPIO_ACTIVE_HIGH>;
+			label = "led pin";
+			status = "okay";
+		
+		};
+	};
+
+	pwmServo {
+		compatible = "pwm-leds";
+		pwm_led_blue: pwm_led_gpio0_2 {
+			label = "PWM SERVO";
+			pwms = <&ledc0 0 1000 PWM_POLARITY_NORMAL>;
+		};
+	};
+};
+
+
+&pinctrl {
+	ledc0_default: ledc0_default {
+		group1 {
+			pinmux = <LEDC_CH0_GPIO2>;
+			output-enable;
+		};
+	};
+};
+
+&ledc0 {
+	pinctrl-0 = <&ledc0_default>;
+	pinctrl-names = "default";
+	status = "okay";
+	#address-cells = <1>;
+	#size-cells = <0>;
+	channel0@0 {
+		reg = <0x0>;
+		timer = <0>;
+	};
+};
+
+&wifi {
 	status = "okay";
 };
\ No newline at end of file
diff --git a/debug-app/drivers/CMakeLists.txt b/debug-app/drivers/CMakeLists.txt
index 176ae59..6f943b6 100644
--- a/debug-app/drivers/CMakeLists.txt
+++ b/debug-app/drivers/CMakeLists.txt
@@ -1,5 +1,5 @@
-add_subdirectory_ifndef(CONFIG_SOC_POSIX ble-scanner)
-add_subdirectory_ifndef(CONFIG_SOC_POSIX wifi-controller)
+add_subdirectory(ble-scanner)
+add_subdirectory(wifi-controller)
 add_subdirectory(ir-driver)
 add_subdirectory(servo-driver)
 add_subdirectory(led-driver)
\ No newline at end of file
diff --git a/debug-app/drivers/ir-driver/src/ir-driver.cpp b/debug-app/drivers/ir-driver/src/ir-driver.cpp
index db8cefb..97104ae 100644
--- a/debug-app/drivers/ir-driver/src/ir-driver.cpp
+++ b/debug-app/drivers/ir-driver/src/ir-driver.cpp
@@ -1,7 +1,21 @@
 #include "ir-driver.h"
+#include <zephyr/drivers/gpio.h>
+
+#define IRSENSOR_PIN DT_NODELABEL(ir_sensor)
+
+struct gpio_dt_spec irSensorNode = GPIO_DT_SPEC_GET(IRSENSOR_PIN, gpios);
+struct gpio_callback irSensorCb;
+
+static IrDriver *context;
 
 IrDriver::IrDriver(){
+    context = this;
+    int err = gpio_pin_configure_dt(&irSensorNode, GPIO_INPUT);
+    gpio_pin_interrupt_configure_dt(&irSensorNode, GPIO_INT_EDGE_BOTH);
+    gpio_init_callback(&irSensorCb, InterruptCallback, BIT(irSensorNode.pin));
+	gpio_add_callback(irSensorNode.port, &irSensorCb);
 
+    k_work_init(&work, InterruptHandler);
 }
 
 IrDriver::~IrDriver(){
@@ -10,9 +24,19 @@ IrDriver::~IrDriver(){
 
 bool IrDriver::GetState(){
 
-    return true;
+    return gpio_pin_get_dt(&irSensorNode);
 }
 
 void IrDriver::RegisterInterrupt(void (*callback)(uint8_t)){
     registeredCallback = callback;
+}
+
+void IrDriver::InterruptCallback(const struct device *dev, struct gpio_callback *cb, uint32_t pins){
+    k_work_submit(&context->work);
+}
+
+void IrDriver::InterruptHandler(struct k_work *item){
+    if(context->registeredCallback != NULL){
+        context->registeredCallback(gpio_pin_get_dt(&irSensorNode));
+    }
 }
\ No newline at end of file
diff --git a/debug-app/drivers/led-driver/src/led-driver.cpp b/debug-app/drivers/led-driver/src/led-driver.cpp
index 3e6b3ba..03a1e09 100644
--- a/debug-app/drivers/led-driver/src/led-driver.cpp
+++ b/debug-app/drivers/led-driver/src/led-driver.cpp
@@ -1,7 +1,12 @@
 #include "led-driver.h"
+#include <zephyr/drivers/gpio.h>
 
-LedDriver::LedDriver(){
+#define LED_PIN DT_NODELABEL(led_pin)
+
+struct gpio_dt_spec ledPinNode = GPIO_DT_SPEC_GET(LED_PIN, gpios);
 
+LedDriver::LedDriver(){
+    int err = gpio_pin_configure_dt(&ledPinNode, GPIO_OUTPUT_INACTIVE);
 }
 
 LedDriver::~LedDriver(){
@@ -9,9 +14,10 @@ LedDriver::~LedDriver(){
 }
 
 void LedDriver::SetState(bool enable){
-
+    gpio_pin_set_dt(&ledPinNode, enable);
+    currentState = enable;
 }
 
 bool LedDriver::GetState(){
-    return true;
+    return currentState;
 }
\ No newline at end of file
diff --git a/debug-app/include/ir-driver.h b/debug-app/include/ir-driver.h
index 9b036d0..a0ca7b6 100644
--- a/debug-app/include/ir-driver.h
+++ b/debug-app/include/ir-driver.h
@@ -5,6 +5,9 @@
 
 class IrDriver {
 public:
+    void (*registeredCallback)(uint8_t) = NULL;
+    struct k_work work;
+
     /** Constructor.
      *
      **/
@@ -20,5 +23,8 @@ public:
     void RegisterInterrupt(void (*callback)(uint8_t));
 
 private: 
-    void (*registeredCallback)(uint8_t) = NULL;
+
+    static void InterruptCallback(const struct device *dev, struct gpio_callback *cb, uint32_t pins);
+
+    static void InterruptHandler(struct k_work *item);
 };
\ No newline at end of file
diff --git a/debug-app/include/led-driver.h b/debug-app/include/led-driver.h
index a57cd47..4e90eaf 100644
--- a/debug-app/include/led-driver.h
+++ b/debug-app/include/led-driver.h
@@ -20,4 +20,5 @@ public:
     bool GetState();
 
 private: 
+    bool currentState;
 };
\ No newline at end of file
diff --git a/debug-app/include/main-handler.h b/debug-app/include/main-handler.h
index 93574b0..284806c 100644
--- a/debug-app/include/main-handler.h
+++ b/debug-app/include/main-handler.h
@@ -33,6 +33,7 @@ private:
 
     DriverNumb_e requestedResponse;
     DriverMessage_t driverResponse_g;
+    uint8_t currentState;
 
     static void MainThread(MainHandler *context);
     bool DriverRequest(DriverMessage_t *sentMessage, DriverMessage_t *driverResponse, k_timeout_t timeout);
diff --git a/debug-app/include/utilities.h b/debug-app/include/utilities.h
index 9fcaaac..85902fc 100644
--- a/debug-app/include/utilities.h
+++ b/debug-app/include/utilities.h
@@ -8,8 +8,9 @@ typedef enum DriverNumb{
     SENSOR_2,
     SENSOR_3,
     BLUETOOTH,
-    WINDOW,
-    LAMP
+    SERVO,
+    LED,
+    IR_DRIVER
 } DriverNumb_e;
 
 typedef enum StateFlag{
@@ -18,8 +19,16 @@ typedef enum StateFlag{
     DATA_2
 } StateFlag_e;
 
+typedef enum ExchangeType{
+    REQUEST_GET,
+    REQUEST_SET,
+    RESPONSE_GET,
+    RESPONSE_SET
+} ExchangeType_e;
+
 typedef struct DriverMessage {
     DriverNumb_e number;
+    ExchangeType_e type;
     std::vector<uint8_t> value;
 } DriverMessage_t;
 
diff --git a/debug-app/module/driver-hook/src/driver-hook.cpp b/debug-app/module/driver-hook/src/driver-hook.cpp
index 118975f..8704d5f 100644
--- a/debug-app/module/driver-hook/src/driver-hook.cpp
+++ b/debug-app/module/driver-hook/src/driver-hook.cpp
@@ -56,25 +56,36 @@ void DriverHook::DriverRequestListener(const struct zbus_channel *chan){
 
     DriverMessage_t sentMessage = {
         .number = msg->number,
-        .value = msg->value
+        .type = msg->type,
     };
 
     switch (msg->number)
     {
-    case SENSOR_1:
-        LOG_INF("Sensor %d", msg->number);
-        break;
-
-    case SENSOR_2:
-        LOG_INF("Sensor %d", msg->number);
+    case BLUETOOTH:
+        if(msg->type == REQUEST_SET){
+            context->bleScanner->SetScan(msg->value[0]);
+            sentMessage.value.push_back(0);
+        }
         break;
 
-    case SENSOR_3:
-        LOG_INF("Sensor %d", msg->number);
+    case LED:
+        if(msg->type == REQUEST_SET){
+            context->ledDriver->SetState(msg->value[0]);
+        }
+        else if(msg->type == REQUEST_GET){
+            bool ledState = context->ledDriver->GetState();
+            sentMessage.value.push_back(ledState);
+        }
         break;
 
-    case BLUETOOTH:
-        
+    case SERVO:
+        if(msg->type == REQUEST_SET){
+            context->servoDriver->SetPwm(msg->value[0]);
+        }
+        else if(msg->type == REQUEST_GET){
+            uint8_t servoPwm = context->servoDriver->GetPwm();
+            sentMessage.value.push_back(servoPwm);
+        }
         break;
     
     default:
diff --git a/debug-app/module/handler/main-handler/src/main-handler.cpp b/debug-app/module/handler/main-handler/src/main-handler.cpp
index 21cdaf1..5a1a44d 100644
--- a/debug-app/module/handler/main-handler/src/main-handler.cpp
+++ b/debug-app/module/handler/main-handler/src/main-handler.cpp
@@ -53,7 +53,6 @@ int MainHandler::Deinit(){
 
 void MainHandler::MainThread(MainHandler *context){
 	// const struct zbus_channel *chan;
-	uint8_t currentState = 1;
 	uint8_t stateCounter = 0;
 	// while (!zbus_sub_wait(&stateSubs, &chan, K_MSEC(200))) {
 	// 		StateMessage_t state;
@@ -69,54 +68,63 @@ void MainHandler::MainThread(MainHandler *context){
 	{
 		LOG_INF("main thread run");
 		std::vector<uint8_t> stateVec;
-		stateVec.push_back(currentState);
+		stateVec.push_back(context->currentState);
 		StateMessage_t stateMsg{
 			.flag = STATE,
 			.value = stateVec
 		};
+		DriverMessage_t configVector, responseVector;
 		zbus_chan_pub(&stateChannel, &stateMsg, K_MSEC(200));
 
-		switch (currentState)
+		switch (context->currentState)
 		{
 		case STANDBY:{
-			LOG_INF("entering state 1");
-			DriverMessage_t configVector, responseVector;
-			configVector.number = SENSOR_1;
-			configVector.value.push_back(stateCounter);
-			if(context->DriverRequest(&configVector, &responseVector, K_MSEC(200))){
-				if(responseVector.value.size() > 0){
-					LOG_INF("get sensor data %d", responseVector.value[0]);
-				}
+			LOG_INF("Standby");
+
+			configVector.number = LED;
+			configVector.type = REQUEST_SET;
+			configVector.value.push_back(0);
+			context->DriverRequest(&configVector, &responseVector, K_MSEC(200));
+
+			configVector.number = SERVO;
+			configVector.type = REQUEST_SET;
+			configVector.value.push_back(0);
+			context->DriverRequest(&configVector, &responseVector, K_MSEC(200));
 
-			}
-			else{
-				LOG_INF("fail");
-			}
-			k_msleep(500);
-			stateCounter++;
-			if(stateCounter > 10){
-				stateCounter = 0;
-				currentState = SCANNING;
-			}
 			break;
 		}
 
 		case SCANNING:
-			LOG_INF("entering state 2");
-			k_msleep(500);
-			stateCounter++;
-			if(stateCounter > 10){
-				stateCounter = 0;
-				currentState = 1;
-			}
+			configVector.number = BLUETOOTH;
+			configVector.type = REQUEST_SET;
+			configVector.value.push_back(1);
+			context->DriverRequest(&configVector, &responseVector, K_MSEC(200));
 			break;
 		
 		case USER_1:
-			/* code */
+			configVector.number = LED;
+			configVector.type = REQUEST_SET;
+			configVector.value.push_back(1);
+			context->DriverRequest(&configVector, &responseVector, K_MSEC(200));
+
+			configVector.number = SERVO;
+			configVector.type = REQUEST_SET;
+			configVector.value.push_back(0);
+			context->DriverRequest(&configVector, &responseVector, K_MSEC(200));
 			break;
 
 		case USER_2:
-			/* code */
+			configVector.number = LED;
+			configVector.type = REQUEST_SET;
+			configVector.value.push_back(0);
+			context->DriverRequest(&configVector, &responseVector, K_MSEC(200));
+
+			configVector.number = SERVO;
+			configVector.type = REQUEST_SET;
+			configVector.value.push_back(100);
+			context->DriverRequest(&configVector, &responseVector, K_MSEC(200));
+
+
 			break;		
 		default:
 			break;
@@ -130,6 +138,24 @@ void MainHandler::DriverResponseListener(const struct zbus_channel *chan){
 	if (&driverResponseChannel == chan) {
 			driver = (DriverMessage_t *)zbus_chan_const_msg(chan); // Direct message access
 			context->driverResponse_g = *driver;
+
+		if(driver->number == BLUETOOTH){
+			if(driver->value[0] == 1){
+				context->currentState = USER_1;
+			}
+			else if(driver->value[0] == 2){
+				context->currentState = USER_2;
+			}
+		}
+
+		if(driver->number == IR_DRIVER){
+			if(driver->value[0] == 0){
+				context->currentState = STANDBY;
+			}
+			else if(driver->value[0] == 1){
+				context->currentState = SCANNING;
+			}
+		}
 	}
 }
 
-- 
GitLab