//-----------------------------------------------------------------
// Date: 2022-12-28
// Author: RSP @KMUTNB
//-----------------------------------------------------------------
#include <Arduino_FreeRTOS.h>
#include <task.h>
#include <queue.h>
// Declare a global variable to be used for task communication
QueueHandle_t queue;
// Task function prototypes
void task1(void *pvParameters);
void task2(void *pvParameters);
TaskHandle_t task1Handle;
TaskHandle_t task2Handle;
// Note: configMINIMAL_STACK_SIZE is set to 192 (default).
#define TASK_STACK_SIZE  (configMINIMAL_STACK_SIZE+16)
const int BUTTON_PIN = 2; // use either D2 or D3 pin
// ISR for the button press
void btn_isr() {
  uint32_t ts = millis();
  detachInterrupt( digitalPinToInterrupt(BUTTON_PIN) );
  // Send a message to the queue to notify task2
  xQueueSendToBackFromISR(queue, &ts, NULL);
}
void enable_btn_isr() {
  // Set up the external interrupt on the button pin
  attachInterrupt(
    digitalPinToInterrupt(BUTTON_PIN), 
    btn_isr, FALLING );
}
// task1 function: waits for a button press and notifies task2
void task1(void *pvParameters) {
  (void) pvParameters;  // parameters not used
  // Enable the external interrupt for the push button
  enable_btn_isr();
  while (true) {
    uint32_t ts;
    // Wait indefinitely for a message in the queue
    xQueueReceive(queue, &ts, portMAX_DELAY);
    Serial.print("Button press time [ms]: " );
    Serial.println( ts );
    // Button press event has occurred, notify task2
    xTaskNotifyGive(task2Handle);
    // Wait for stable input to avoid button bouncing
    uint8_t cnt = 5;
    while (true) {
      if (digitalRead(BUTTON_PIN)==HIGH) {
        if (cnt > 0) {
          cnt--;
        } else {
          break;
        }
      } else {
        cnt = 5;
      }
      vTaskDelay(1);
    }
    // Re-enable the external interrupt for the push button.
    enable_btn_isr();
  }
}
// task2 function: waits for notification from task1
void task2(void *pvParameters) {
  (void) pvParameters;  // parameters not used
  uint8_t count = 0;    // button press count
  while (true) {
    // Wait for notification from task1
    ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
    Serial.print("Button press count: " );
    Serial.println( ++count );
  }
}
void setup() {
  // Initialize Serial
  Serial.begin(115200);
  // Configure button pin as an input pin with pull-up resistor
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  // Create a queue of integers, with queue length of 1
  queue = xQueueCreate(1, sizeof(uint32_t));
  // Create task1 and task2 (with task priority set to 1)
  xTaskCreate(task1, "Task1", TASK_STACK_SIZE, NULL, 1, &task1Handle);
  xTaskCreate(task2, "Task2", TASK_STACK_SIZE, NULL, 1, &task2Handle);
}
void loop() {
  // empty
}
//-----------------------------------------------------------------