#include <stdio.h>
#include <stdbool.h>
#include <unistd.h>

#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "driver/mcpwm_prelude.h"

static const char *TAG = "MCPWM"; 

void app_main(void)
{
  mcpwm_timer_handle_t timer = NULL;
  mcpwm_timer_config_t timer_config = {
      .group_id = 0,
      .clk_src = MCPWM_TIMER_CLK_SRC_DEFAULT,
      .resolution_hz = 1000000,
      .period_ticks = 200,
      .count_mode = MCPWM_TIMER_COUNT_MODE_UP,
  };
  mcpwm_new_timer(&timer_config, &timer);
  
  mcpwm_oper_handle_t oper = NULL;
  mcpwm_operator_config_t operator_config = {
      .group_id = 0,
  };
  mcpwm_new_operator(&operator_config, &oper);
  mcpwm_operator_connect_timer(oper, timer);
  mcpwm_gen_handle_t generator = NULL;
  mcpwm_generator_config_t generator_config = {
      .gen_gpio_num = 0,
  };
  mcpwm_new_generator(oper, &generator_config, 
                                      &generator);
  mcpwm_gen_timer_event_action_t event_action = {
    .direction = MCPWM_TIMER_DIRECTION_UP,
    .event = MCPWM_TIMER_EVENT_EMPTY,
    .action = MCPWM_GEN_ACTION_TOGGLE, // MCPWM_GEN_ACTION_HIGH, 
  };
  mcpwm_generator_set_action_on_timer_event(generator, 
  MCPWM_GEN_TIMER_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP,
     MCPWM_TIMER_EVENT_FULL, MCPWM_GEN_ACTION_TOGGLE));           // MCPWM_GEN_ACTION_HIGH, MCPWM_GEN_ACTION_LOW, MCPWM_GEN_ACTION_KEEP, MCPWM_GEN_ACTION_TOGGLE
  
  
  // ADD Comparator
  mcpwm_cmpr_handle_t comparator;
  mcpwm_comparator_config_t compare_config = {
     .flags.update_cmp_on_tez = true,
  };
  ESP_ERROR_CHECK(mcpwm_new_comparator(oper, &compare_config, &comparator));
  ESP_ERROR_CHECK(mcpwm_comparator_set_compare_value(comparator, 50));
  ESP_ERROR_CHECK(mcpwm_generator_set_action_on_compare_event(generator,
                                                            // when compare event happens, and timer is counting up, set output to low
                                                            MCPWM_GEN_COMPARE_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, comparator, MCPWM_GEN_ACTION_LOW)));  
  
  
  
  mcpwm_timer_enable(timer);
  mcpwm_timer_start_stop(timer, 
                        MCPWM_TIMER_START_NO_STOP);

//    // 2. Inicializace MCPWM konfigurace
//    mcpwm_config_t pwm_config;
//    pwm_config.frequency = 1000;    // Frekvence PWM: 1 kHz
//    pwm_config.cmpr_a = 50.0;       // Počáteční střída: 50%
//    pwm_config.cmpr_b = 0.0;        // Nepoužívá se
//    pwm_config.counter_mode = MCPWM_UP_COUNTER;
//    pwm_config.duty_mode = MCPWM_DUTY_MODE_0;
//    mcpwm_init(MCPWM_UNIT_0, MCPWM_TIMER_0, &pwm_config);
    
    // Add Carrier Filling
    ESP_LOGI(TAG, "Apply carrier filling for GPIO_CARRIER_OUT");
    mcpwm_carrier_config_t carrier_config = {
        .clk_src = MCPWM_TIMER_CLK_SRC_DEFAULT,
        .first_pulse_duration_us = 1, 	  // First pulse 1 us
        .frequency_hz = 1000000,          // Frekvence carrieru 1 MHz
//        .flags.invert_before_modulate = true,
        .duty_cycle = 30,               	// 30% duty cycle
    };
    ESP_ERROR_CHECK(mcpwm_operator_apply_carrier(oper, &carrier_config));
    
    while (1) {
        ESP_LOGI(TAG, "MCPWM running with carrier filling...");
        vTaskDelay(pdMS_TO_TICKS(1000));
    }                        
}