
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"


#define LED_RED GPIO_NUM_5
#define LED_GREEN GPIO_NUM_2
#define PushButton GPIO_NUM_14
#define LED_BLUE GPIO_NUM_4 
#define LED_YELLOW GPIO_NUM_22

SemaphoreHandle_t binSem ;

// hardware interrupt , 

static void IRAM_ATTR intrHandlePushButton(void *args){
  //vPrintString("inside interrupt service routine");
  BaseType_t xHigherPriorityTaskWoken ;
  xHigherPriorityTaskWoken = pdFALSE;

  gpio_set_level(LED_GREEN,1);
  xSemaphoreGiveFromISR(binSem , &xHigherPriorityTaskWoken);
  if (xHigherPriorityTaskWoken){
    gpio_set_level(LED_GREEN,0);
     portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
  }
  else{
  gpio_set_level(LED_GREEN,0);
  }
}

static void IRAM_ATTR intrHandleLEDYELLOW(void *args){
  //vPrintString("inside interrupt service routine");
  
  gpio_set_level(LED_YELLOW,1);
  gpio_set_level(LED_YELLOW,0);
  
}



void led_task_Red(void *pvParameter)
{
  while (1) {
    gpio_set_level(LED_RED, 1);
    gpio_set_level(LED_RED, 0);
    printf("inside LED routine \n");
    vTaskDelay(1);
    
 
}
 vTaskDelete( NULL );
}

void led_task_Intr(void *pvParameter)
{
  while (1) {
    xSemaphoreTake(binSem,portMAX_DELAY);
    gpio_set_level(LED_BLUE, 1);
    gpio_set_level(LED_BLUE, 0);
    printf("inside ISR routine\n");
    vTaskDelay(1);
}
 vTaskDelete( NULL );
}


extern "C" void app_main() {

  //printf("\n%d",xPortGetCoreID());
  
  //setup GPIO to input and Output

  gpio_set_direction(LED_RED, GPIO_MODE_OUTPUT);
  gpio_set_direction(LED_GREEN,GPIO_MODE_OUTPUT);
  gpio_set_direction(LED_BLUE,GPIO_MODE_OUTPUT);
  gpio_set_direction(LED_YELLOW,GPIO_MODE_OUTPUT);
  gpio_set_direction(PushButton , GPIO_MODE_INPUT);
  gpio_set_level(PushButton,0);
  gpio_set_level(LED_RED,0);
  gpio_set_level(LED_GREEN,0);
  gpio_set_level(LED_BLUE,0);
  gpio_set_level(LED_YELLOW,0);
  
   
   //attach GPIO to interrupt
  gpio_set_intr_type(LED_RED,GPIO_INTR_POSEDGE);
  gpio_install_isr_service(0);
  gpio_isr_handler_add(LED_RED,intrHandlePushButton,NULL);
  
  gpio_set_intr_type(LED_GREEN,GPIO_INTR_POSEDGE);
  gpio_install_isr_service(1);
  gpio_isr_handler_add(LED_GREEN,intrHandleLEDYELLOW,NULL);
  
  
  binSem =  xSemaphoreCreateBinary();
  if (binSem != NULL){
            
      xTaskCreate(
      &led_task_Red, // task function
      "red_led_task", // task name
      2048, // stack size in words
      NULL, // pointer to parameters
      1, // priority
      NULL); // out pointer to task handle
       xTaskCreate(
      &led_task_Intr, // task function
      "Intr_led_task", // task name
      2048, // stack size in words
      NULL, // pointer to parameters
      3, // priority
      NULL); // out pointer to task handle

  }
    

  }

  

