//WS2812
#include "ws2812.h"
#include "esp32-hal.h"
//BlueTooth
#include "esp_bt_main.h"
#include "esp_bt.h"
#include "esp_sleep.h"
#include "driver/rtc_io.h"

/*
   name: board_sleep

   传参：
   uint64_t time_in_s: 设置睡眠时间(s)

   功能：
   设置睡眠

   注：
   若设置为0，则不会自动唤醒，需要断电或者复位重启。
   睡眠期间关闭蓝牙，WiFi以及RTC外设电源。
*/

const int WAKEUP_PINS[] = {7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 21};

uint64_t getWakeUpPinsMask() {
  uint64_t mask = 0;
  for (int i = 0; i < sizeof(WAKEUP_PINS) / sizeof(WAKEUP_PINS[0]); ++i) {
    mask |= ((uint64_t)1 << WAKEUP_PINS[i]);
  }
  return mask;
}

void board_sleep()
{
  rtc_gpio_init(GPIO_NUM_1);
  rtc_gpio_init(GPIO_NUM_2);
  rtc_gpio_init(GPIO_NUM_3);
  rtc_gpio_init(GPIO_NUM_4);
  rtc_gpio_init(GPIO_NUM_5);
  rtc_gpio_init(GPIO_NUM_6);
  rtc_gpio_init(GPIO_NUM_7);
  rtc_gpio_init(GPIO_NUM_8);
  rtc_gpio_init(GPIO_NUM_9);
  rtc_gpio_init(GPIO_NUM_10);
  rtc_gpio_init(GPIO_NUM_11);
  rtc_gpio_init(GPIO_NUM_12);
  rtc_gpio_init(GPIO_NUM_13);
  rtc_gpio_init(GPIO_NUM_14);
  rtc_gpio_init(GPIO_NUM_15);
  rtc_gpio_init(GPIO_NUM_16);
  rtc_gpio_init(GPIO_NUM_17);
  rtc_gpio_init(GPIO_NUM_18);
  rtc_gpio_init(GPIO_NUM_21);
  rtc_gpio_set_direction_in_sleep(GPIO_NUM_1, RTC_GPIO_MODE_OUTPUT_ONLY);
  rtc_gpio_set_direction_in_sleep(GPIO_NUM_2, RTC_GPIO_MODE_OUTPUT_ONLY);
  rtc_gpio_set_direction_in_sleep(GPIO_NUM_3, RTC_GPIO_MODE_OUTPUT_ONLY);
  rtc_gpio_set_direction_in_sleep(GPIO_NUM_4, RTC_GPIO_MODE_OUTPUT_ONLY);
  rtc_gpio_set_direction_in_sleep(GPIO_NUM_5, RTC_GPIO_MODE_OUTPUT_ONLY);
  rtc_gpio_set_direction_in_sleep(GPIO_NUM_6, RTC_GPIO_MODE_OUTPUT_ONLY);
  rtc_gpio_set_direction_in_sleep(GPIO_NUM_7, RTC_GPIO_MODE_INPUT_ONLY);
  rtc_gpio_set_direction_in_sleep(GPIO_NUM_8, RTC_GPIO_MODE_INPUT_ONLY);
  rtc_gpio_set_direction_in_sleep(GPIO_NUM_9, RTC_GPIO_MODE_INPUT_ONLY);
  rtc_gpio_set_direction_in_sleep(GPIO_NUM_10, RTC_GPIO_MODE_INPUT_ONLY);
  rtc_gpio_set_direction_in_sleep(GPIO_NUM_11, RTC_GPIO_MODE_INPUT_ONLY);
  rtc_gpio_set_direction_in_sleep(GPIO_NUM_12, RTC_GPIO_MODE_INPUT_ONLY);
  rtc_gpio_set_direction_in_sleep(GPIO_NUM_13, RTC_GPIO_MODE_INPUT_ONLY);
  rtc_gpio_set_direction_in_sleep(GPIO_NUM_14, RTC_GPIO_MODE_INPUT_ONLY);
  rtc_gpio_set_direction_in_sleep(GPIO_NUM_15, RTC_GPIO_MODE_INPUT_ONLY);
  rtc_gpio_set_direction_in_sleep(GPIO_NUM_16, RTC_GPIO_MODE_INPUT_ONLY);
  rtc_gpio_set_direction_in_sleep(GPIO_NUM_17, RTC_GPIO_MODE_INPUT_ONLY);
  rtc_gpio_set_direction_in_sleep(GPIO_NUM_18, RTC_GPIO_MODE_INPUT_ONLY);
  rtc_gpio_set_direction_in_sleep(GPIO_NUM_21, RTC_GPIO_MODE_INPUT_ONLY);
  rtc_gpio_set_level(GPIO_NUM_1, 1);
  rtc_gpio_set_level(GPIO_NUM_2, 1);
  rtc_gpio_set_level(GPIO_NUM_3, 1);
  rtc_gpio_set_level(GPIO_NUM_4, 1);
  rtc_gpio_set_level(GPIO_NUM_5, 1);
  rtc_gpio_set_level(GPIO_NUM_6, 1);
  rtc_gpio_hold_en(GPIO_NUM_1);
  rtc_gpio_hold_en(GPIO_NUM_2);
  rtc_gpio_hold_en(GPIO_NUM_3);
  rtc_gpio_hold_en(GPIO_NUM_4);
  rtc_gpio_hold_en(GPIO_NUM_5);
  rtc_gpio_hold_en(GPIO_NUM_6);
  esp_sleep_enable_ext1_wakeup(getWakeUpPinsMask(), ESP_EXT1_WAKEUP_ANY_HIGH);
  set_light_mode(0); 
  delay(1000);
  clean_led();      
  delay(3000);
  clean_led();
  vTaskDelay(100);
#ifdef DEBUG_K
  Serial.println("Entering deep sleep");
#endif
  esp_deep_sleep_start();
}
