#include <Arduino_FreeRTOS.h>
#include <semphr.h>

// Khai báo semaphore nhị phân
SemaphoreHandle_t interruptSemaphore;

void setup() {
  Serial.begin(9600); // Khởi tạo Serial Monitor
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(2, INPUT_PULLUP); // Sử dụng nút nhấn trên chân số 2

  // Tạo task cho việc bật và tắt đèn LED
  xTaskCreate(TaskLedOn, "LedOn", 128, NULL, 1, NULL);
  xTaskCreate(TaskLedOff, "LedOff", 128, NULL, 1, NULL);

  // Tạo semaphore nhị phân
  interruptSemaphore = xSemaphoreCreateBinary();
  if (interruptSemaphore != NULL) {
    // Gắn ngắt ngoài cho chân số 2
    attachInterrupt(digitalPinToInterrupt(2), interruptHandler, FALLING);
  }  
}

void loop() {
  // Không cần làm gì trong hàm loop
}

// Hàm xử lý ngắt
void interruptHandler() {
  Serial.println("Semaphore is given");
  BaseType_t xHigherPriorityTaskWoken = pdFALSE;
  xSemaphoreGiveFromISR(interruptSemaphore, &xHigherPriorityTaskWoken);
  portYIELD(); // Chỉ cần gọi portYIELD() trong ISR
}

// Task bật đèn LED
void TaskLedOn(void *pvParameters) {
  (void) pvParameters;

  for (;;) {
    // Chờ semaphore
    if (xSemaphoreTake(interruptSemaphore, portMAX_DELAY) == pdPASS) {
      Serial.println("TaskLedOn Received Semaphore");
      digitalWrite(LED_BUILTIN, HIGH); // Bật đèn LED
    }
  }
}

// Task tắt đèn LED
void TaskLedOff(void *pvParameters) {
  (void) pvParameters;

  for (;;) {
    // Chờ semaphore
    if (xSemaphoreTake(interruptSemaphore, portMAX_DELAY) == pdPASS) {
      Serial.println("TaskLedOff Received Semaphore");
      digitalWrite(LED_BUILTIN, LOW); // Tắt đèn LED
    }
  }
}