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

#define pinServo 22
int duty;


void Servo_clockWise() {
  /* First configure the timer of the LEDC */
  ledc_timer_config_t ledc_timer = {
    .speed_mode       = LEDC_LOW_SPEED_MODE,
    .timer_num        = LEDC_TIMER_0,
    .duty_resolution  = LEDC_TIMER_13_BIT,
    .freq_hz          = 50,
    .clk_cfg          = LEDC_AUTO_CLK
  };
  ledc_timer_config(&ledc_timer);

  /* Second configure the channel of the LEDC */
  ledc_channel_config_t ledc_channel = {
    .speed_mode     = LEDC_LOW_SPEED_MODE,
    .channel        = LEDC_CHANNEL_0,
    .timer_sel      = LEDC_TIMER_0,
    .intr_type      = LEDC_INTR_DISABLE,
    .gpio_num       = pinServo,
    .duty           = 0,
    .hpoint         = 0
  };
  ledc_channel_config(&ledc_channel);
  /* Finally, set and update the duty of the LEDC */
  for (int i = 200; i <= 1000; i += 50)
  {
    duty = i;
    printf(" duty -> %d\n", duty);
    ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, duty);
    ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0);
    vTaskDelay( 1000 / portTICK_PERIOD_MS );
    ledc_stop(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, 0);
  }

}

// Repeat in the inverse direction of the LEDC duty
void servo_Anti_clockWise() {
  ledc_timer_config_t ledc_timer = {
    .speed_mode       = LEDC_LOW_SPEED_MODE,
    .timer_num        = LEDC_TIMER_0,
    .duty_resolution  = LEDC_TIMER_13_BIT,
    .freq_hz          = 50,
    .clk_cfg          = LEDC_AUTO_CLK
  };
  ledc_timer_config(&ledc_timer);
  ledc_channel_config_t ledc_channel = {
    .speed_mode     = LEDC_LOW_SPEED_MODE,
    .channel        = LEDC_CHANNEL_0,
    .timer_sel      = LEDC_TIMER_0,
    .intr_type      = LEDC_INTR_DISABLE,
    .gpio_num       = pinServo,
    .duty           = 0,
    .hpoint         = 0
  };
  ledc_channel_config(&ledc_channel);
  for (int i = 950; i >= 250; i -= 50)
  {
    duty = i;
    printf(" duty -> %d\n", duty);
    ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, duty);
    ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0);
    vTaskDelay( 1000 / portTICK_PERIOD_MS );
    ledc_stop(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, 0);
  }

}

void Servo_control()
{
  Servo_clockWise();
  servo_Anti_clockWise();
}

void app_main(void)
{
  printf("Tutorial : LEDC&Servo Motor\n");
  while (1) {
    Servo_control();
  }
}