PCNT Detection: Pulse countRange: 80 MHz / 2 ≈ 40 MHzPractical limit: 20 MHz (24.576 MHz = OK)Detects: Positive / Negative edges RMT Detection: Pulse widthRange: ~80 MHzPractical limit: 20 MHzDetects: Edges, waveform characteristics, jitter
ESP Timer Type: FreeRTOS software timerCount: Unlimited (software)Precision: High jitterFlexibility: Very high GP Timer Type: General‑purpose hardware timerCount: 4 unitsPrecision: Low jitterFlexibility: Limited (*) Timer Group Type: Legacy hardware timerPrecision: Low jitter
void init_monitor(void) { esp_err_t ret; ESP_LOGI(TAG, "init_monitor enter"); // Output I2S0 MCLK to GPIO25 //gpio_matrix_out(PIN_MCK, I2S0_MCLK_OUT_IDX, false, false); //gpio_set_direction(PIN_MCK, GPIO_MODE_OUTPUT); // PCNT configuration pcnt_config_t pcnt_config = { .pulse_gpio_num = PIN_MCK, // MCKを入力 .ctrl_gpio_num = PCNT_PIN_NOT_USED, .channel = PCNT_CHANNEL_0, .unit = SYNCLK_PCNT_UNIT, .pos_mode = PCNT_COUNT_INC, .neg_mode = /*PCNT_COUNT_INC*/PCNT_COUNT_DIS, // Disable negative-edge count to avoid phase‑dependent errors .lctrl_mode = PCNT_MODE_KEEP, .hctrl_mode = PCNT_MODE_KEEP, .counter_h_lim = INT16_MAX, // INT16_MAX .counter_l_lim = 0, }; pcnt_unit_config(&pcnt_config); // Explicitly disable filter pcnt_set_filter_value(SYNCLK_PCNT_UNIT, 0); pcnt_filter_disable(SYNCLK_PCNT_UNIT); // Clear counter only during initialization pcnt_counter_pause(SYNCLK_PCNT_UNIT); pcnt_counter_clear(SYNCLK_PCNT_UNIT); pcnt_counter_resume(SYNCLK_PCNT_UNIT); // Register ESPTimer const esp_timer_create_args_t timer_args = { .callback = &monitor_task_esp, .name = "monitor_task_esp", .dispatch_method = ESP_TIMER_TASK, }; ret = esp_timer_create(&timer_args, &g_esptimer); ESP_LOGI(TAG, "%s to create %s", ret == ESP_OK?"Succeeded":"Failed", "monitor_task_esp"); ret = esp_timer_start_periodic(g_esptimer, 1000); // 1 ms interval ESP_LOGI(TAG, "%s to start monitor_task_esp per=%dus", ret == ESP_OK?"Succeeded":"Failed", 1000);}
void app_main(void) {・・・ // Initialize monitor BEFORE I2S // The I2S STD driver monopolizes IO_MUX, // so PCNT must be configured before i2s_init() init_monitor(); // Init I2S before USB for stable output clocking i2s_init();・・・}
if (uac_as_quality.sample_rate > 96000) std_cfg.clk_cfg.mclk_multiple = I2S_MCLK_MULTIPLE_128; else std_cfg.clk_cfg.mclk_multiple = I2S_MCLK_MULTIPLE_256;