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

//PROTÓTIPO DE FUNÇÕES===================================================
void app_main(void);
void Task_bitwise(void *pvParameter);

//DEFINIÇÕES E CONSTATNTES
#define delay(value) vTaskDelay(value/portTICK_PERIOD_MS)
#define LED_0 GPIO_NUM_22
#define LED_1 GPIO_NUM_4
#define LED_2 GPIO_NUM_2
#define LED_3 GPIO_NUM_15
#define BOTAO GPIO_NUM_13

#define GPIO_OUTPUT_PIN_SEL ((1<<LED_0) | (1<<LED_1) | (1<<LED_2) | (1<<LED_3))//bit_mask

//VARIÁVEIS
uint8_t statusLeds=0;


void Task_bitwise(void *pvParameter){

	//CONFIGURANDO SAÍDAS
	gpio_config_t output_config = {};//variável descritora
	output_config.intr_type = GPIO_INTR_DISABLE;//desabilita interrupção externa
	output_config.mode = GPIO_MODE_OUTPUT;//configura GPIO como saídas
	output_config.pin_bit_mask = GPIO_OUTPUT_PIN_SEL;//carrega GPIOs configuradas
	output_config.pull_up_en = 0;//desativa pull_up
	output_config.pull_down_en = 0;//desativa pull_down 
	gpio_config(&output_config);//configura GPIO conforme descritor

	//CONFIGURANDO ENTRADA
	gpio_config_t input_config = {};//variável descritora
	input_config.intr_type = GPIO_INTR_DISABLE;//desabilita interrupção externa
	input_config.mode = GPIO_MODE_INPUT;//configura GPIO como saídas
	input_config.pin_bit_mask = (1 << BOTAO);
	input_config.pull_up_en = 1;//ativa pull_up
	input_config.pull_down_en = 0;//desativa pull_down
	gpio_config(&input_config);//configura GPIO conforme descritor


	gpio_set_level(LED_0, 0);
	gpio_set_level(LED_1, 0);
	gpio_set_level(LED_2, 0);
	gpio_set_level(LED_3, 0);
	delay(100);

	while(1){
		printf("============================================================\n");
		printf("Status LED: %d\n", statusLeds);
		if(statusLeds & 1<<0){
			gpio_set_level(LED_0, 1);
		}
		if(statusLeds & 1<<1){
			gpio_set_level(LED_1, 1);
		}
		if(statusLeds & 1<<2){
			gpio_set_level(LED_2, 1);
		}
		if(statusLeds & 1<<3){
			gpio_set_level(LED_3, 1);
		}

		while(gpio_get_level(BOTAO) == 0){
			printf("============================================================\n");
			printf("Botão pressionado\n");
			gpio_set_level(LED_0, 0);
			gpio_set_level(LED_1, 0);
			gpio_set_level(LED_2, 0);
			gpio_set_level(LED_3, 0);
			statusLeds++;
			if(statusLeds==16){
				statusLeds=0;
			}
			delay(500);

		}		
	}
}

void app_main(void){
    xTaskCreate(Task_bitwise, " BITWISE ", 2048, NULL, 2, NULL);
}