forked from espressif/esp-idf
refactor(mcpwm): refactor gpio mode config in mcpwm
Deprecate io_loop_back flag. Use capture timer to test generator and dead time.
This commit is contained in:
@ -145,8 +145,7 @@ typedef struct {
|
|||||||
uint32_t pull_down: 1; /*!< Whether to pull down internally */
|
uint32_t pull_down: 1; /*!< Whether to pull down internally */
|
||||||
uint32_t invert_cap_signal: 1; /*!< Invert the input capture signal */
|
uint32_t invert_cap_signal: 1; /*!< Invert the input capture signal */
|
||||||
uint32_t io_loop_back: 1; /*!< For debug/test, the signal output from the GPIO will be fed to the input path as well */
|
uint32_t io_loop_back: 1; /*!< For debug/test, the signal output from the GPIO will be fed to the input path as well */
|
||||||
uint32_t keep_io_conf_at_exit: 1; /*!< For debug/test, whether to keep the GPIO configuration when capture channel is deleted.
|
uint32_t keep_io_conf_at_exit: 1 __attribute__((deprecated)); /*!< Deprecated. Driver won't change the GPIO configuration in deinilization. */
|
||||||
By default, driver will reset the GPIO pin at exit. */
|
|
||||||
} flags; /*!< Extra configuration flags for capture channel */
|
} flags; /*!< Extra configuration flags for capture channel */
|
||||||
} mcpwm_capture_channel_config_t;
|
} mcpwm_capture_channel_config_t;
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@ -24,9 +24,11 @@
|
|||||||
#include "soc/soc_caps.h"
|
#include "soc/soc_caps.h"
|
||||||
#include "soc/mcpwm_periph.h"
|
#include "soc/mcpwm_periph.h"
|
||||||
#include "hal/mcpwm_ll.h"
|
#include "hal/mcpwm_ll.h"
|
||||||
|
#include "hal/gpio_hal.h"
|
||||||
#include "driver/mcpwm_cap.h"
|
#include "driver/mcpwm_cap.h"
|
||||||
#include "driver/gpio.h"
|
#include "driver/gpio.h"
|
||||||
#include "mcpwm_private.h"
|
#include "mcpwm_private.h"
|
||||||
|
#include "esp_private/gpio.h"
|
||||||
|
|
||||||
static const char *TAG = "mcpwm";
|
static const char *TAG = "mcpwm";
|
||||||
|
|
||||||
@ -289,20 +291,25 @@ esp_err_t mcpwm_new_capture_channel(mcpwm_cap_timer_handle_t cap_timer, const mc
|
|||||||
|
|
||||||
if (config->gpio_num >= 0) {
|
if (config->gpio_num >= 0) {
|
||||||
// GPIO configuration
|
// GPIO configuration
|
||||||
gpio_config_t gpio_conf = {
|
gpio_func_sel(config->gpio_num, PIN_FUNC_GPIO);
|
||||||
.intr_type = GPIO_INTR_DISABLE,
|
gpio_input_enable(config->gpio_num);
|
||||||
.mode = GPIO_MODE_INPUT | (config->flags.io_loop_back ? GPIO_MODE_OUTPUT : 0), // also enable the output path if `io_loop_back` is enabled
|
|
||||||
.pin_bit_mask = (1ULL << config->gpio_num),
|
|
||||||
.pull_down_en = config->flags.pull_down,
|
|
||||||
.pull_up_en = config->flags.pull_up,
|
|
||||||
};
|
|
||||||
ESP_GOTO_ON_ERROR(gpio_config(&gpio_conf), err, TAG, "config capture GPIO failed");
|
|
||||||
esp_rom_gpio_connect_in_signal(config->gpio_num, mcpwm_periph_signals.groups[group->group_id].captures[cap_chan_id].cap_sig, 0);
|
esp_rom_gpio_connect_in_signal(config->gpio_num, mcpwm_periph_signals.groups[group->group_id].captures[cap_chan_id].cap_sig, 0);
|
||||||
|
if (config->flags.pull_down) {
|
||||||
|
gpio_pulldown_en(config->gpio_num);
|
||||||
|
}
|
||||||
|
if (config->flags.pull_up) {
|
||||||
|
gpio_pullup_en(config->gpio_num);
|
||||||
|
}
|
||||||
|
|
||||||
|
// deprecated, to be removed in in esp-idf v6.0
|
||||||
|
if (config->flags.io_loop_back) {
|
||||||
|
gpio_ll_output_enable(&GPIO, config->gpio_num);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cap_chan->gpio_num = config->gpio_num;
|
cap_chan->gpio_num = config->gpio_num;
|
||||||
cap_chan->fsm = MCPWM_CAP_CHAN_FSM_INIT;
|
cap_chan->fsm = MCPWM_CAP_CHAN_FSM_INIT;
|
||||||
cap_chan->flags.reset_io_at_exit = !config->flags.keep_io_conf_at_exit && config->gpio_num >= 0;
|
|
||||||
*ret_cap_channel = cap_chan;
|
*ret_cap_channel = cap_chan;
|
||||||
ESP_LOGD(TAG, "new capture channel (%d,%d) at %p", group->group_id, cap_chan_id, cap_chan);
|
ESP_LOGD(TAG, "new capture channel (%d,%d) at %p", group->group_id, cap_chan_id, cap_chan);
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
@ -323,15 +330,16 @@ esp_err_t mcpwm_del_capture_channel(mcpwm_cap_channel_handle_t cap_channel)
|
|||||||
int cap_chan_id = cap_channel->cap_chan_id;
|
int cap_chan_id = cap_channel->cap_chan_id;
|
||||||
|
|
||||||
ESP_LOGD(TAG, "del capture channel (%d,%d)", group->group_id, cap_channel->cap_chan_id);
|
ESP_LOGD(TAG, "del capture channel (%d,%d)", group->group_id, cap_channel->cap_chan_id);
|
||||||
if (cap_channel->flags.reset_io_at_exit) {
|
|
||||||
gpio_reset_pin(cap_channel->gpio_num);
|
|
||||||
}
|
|
||||||
|
|
||||||
portENTER_CRITICAL(&group->spinlock);
|
portENTER_CRITICAL(&group->spinlock);
|
||||||
mcpwm_ll_intr_enable(hal->dev, MCPWM_LL_EVENT_CAPTURE(cap_chan_id), false);
|
mcpwm_ll_intr_enable(hal->dev, MCPWM_LL_EVENT_CAPTURE(cap_chan_id), false);
|
||||||
mcpwm_ll_intr_clear_status(hal->dev, MCPWM_LL_EVENT_CAPTURE(cap_chan_id));
|
mcpwm_ll_intr_clear_status(hal->dev, MCPWM_LL_EVENT_CAPTURE(cap_chan_id));
|
||||||
portEXIT_CRITICAL(&group->spinlock);
|
portEXIT_CRITICAL(&group->spinlock);
|
||||||
|
|
||||||
|
// disconnect signal from the GPIO pin
|
||||||
|
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ZERO_INPUT,
|
||||||
|
mcpwm_periph_signals.groups[group->group_id].captures[cap_chan_id].cap_sig, 0);
|
||||||
|
|
||||||
// recycle memory resource
|
// recycle memory resource
|
||||||
ESP_RETURN_ON_ERROR(mcpwm_capture_channel_destroy(cap_channel), TAG, "destroy capture channel failed");
|
ESP_RETURN_ON_ERROR(mcpwm_capture_channel_destroy(cap_channel), TAG, "destroy capture channel failed");
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@ -22,9 +22,11 @@
|
|||||||
#include "soc/soc_caps.h"
|
#include "soc/soc_caps.h"
|
||||||
#include "soc/mcpwm_periph.h"
|
#include "soc/mcpwm_periph.h"
|
||||||
#include "hal/mcpwm_ll.h"
|
#include "hal/mcpwm_ll.h"
|
||||||
|
#include "hal/gpio_hal.h"
|
||||||
#include "driver/mcpwm_fault.h"
|
#include "driver/mcpwm_fault.h"
|
||||||
#include "driver/gpio.h"
|
#include "driver/gpio.h"
|
||||||
#include "mcpwm_private.h"
|
#include "mcpwm_private.h"
|
||||||
|
#include "esp_private/gpio.h"
|
||||||
|
|
||||||
static const char *TAG = "mcpwm";
|
static const char *TAG = "mcpwm";
|
||||||
|
|
||||||
@ -112,16 +114,22 @@ esp_err_t mcpwm_new_gpio_fault(const mcpwm_gpio_fault_config_t *config, mcpwm_fa
|
|||||||
ESP_GOTO_ON_ERROR(mcpwm_check_intr_priority(group, config->intr_priority), err, TAG, "set group interrupt priority failed");
|
ESP_GOTO_ON_ERROR(mcpwm_check_intr_priority(group, config->intr_priority), err, TAG, "set group interrupt priority failed");
|
||||||
|
|
||||||
// GPIO configuration
|
// GPIO configuration
|
||||||
gpio_config_t gpio_conf = {
|
gpio_func_sel(config->gpio_num, PIN_FUNC_GPIO);
|
||||||
.intr_type = GPIO_INTR_DISABLE,
|
gpio_input_enable(config->gpio_num);
|
||||||
.mode = GPIO_MODE_INPUT | (config->flags.io_loop_back ? GPIO_MODE_OUTPUT : 0), // also enable the output path if `io_loop_back` is enabled
|
|
||||||
.pin_bit_mask = (1ULL << config->gpio_num),
|
|
||||||
.pull_down_en = config->flags.pull_down,
|
|
||||||
.pull_up_en = config->flags.pull_up,
|
|
||||||
};
|
|
||||||
ESP_GOTO_ON_ERROR(gpio_config(&gpio_conf), err, TAG, "config fault GPIO failed");
|
|
||||||
esp_rom_gpio_connect_in_signal(config->gpio_num, mcpwm_periph_signals.groups[group_id].gpio_faults[fault_id].fault_sig, 0);
|
esp_rom_gpio_connect_in_signal(config->gpio_num, mcpwm_periph_signals.groups[group_id].gpio_faults[fault_id].fault_sig, 0);
|
||||||
|
|
||||||
|
if (config->flags.pull_down) {
|
||||||
|
gpio_pulldown_en(config->gpio_num);
|
||||||
|
}
|
||||||
|
if (config->flags.pull_up) {
|
||||||
|
gpio_pullup_en(config->gpio_num);
|
||||||
|
}
|
||||||
|
|
||||||
|
// deprecated, to be removed in in esp-idf v6.0
|
||||||
|
if (config->flags.io_loop_back) {
|
||||||
|
gpio_ll_output_enable(&GPIO, config->gpio_num);
|
||||||
|
}
|
||||||
|
|
||||||
// set fault detection polarity
|
// set fault detection polarity
|
||||||
// different gpio faults share the same config register, using a group level spin lock
|
// different gpio faults share the same config register, using a group level spin lock
|
||||||
portENTER_CRITICAL(&group->spinlock);
|
portENTER_CRITICAL(&group->spinlock);
|
||||||
@ -151,10 +159,10 @@ static esp_err_t mcpwm_del_gpio_fault(mcpwm_fault_handle_t fault)
|
|||||||
mcpwm_gpio_fault_t *gpio_fault = __containerof(fault, mcpwm_gpio_fault_t, base);
|
mcpwm_gpio_fault_t *gpio_fault = __containerof(fault, mcpwm_gpio_fault_t, base);
|
||||||
mcpwm_group_t *group = fault->group;
|
mcpwm_group_t *group = fault->group;
|
||||||
mcpwm_hal_context_t *hal = &group->hal;
|
mcpwm_hal_context_t *hal = &group->hal;
|
||||||
|
int group_id = group->group_id;
|
||||||
int fault_id = gpio_fault->fault_id;
|
int fault_id = gpio_fault->fault_id;
|
||||||
|
|
||||||
ESP_LOGD(TAG, "del GPIO fault (%d,%d)", group->group_id, fault_id);
|
ESP_LOGD(TAG, "del GPIO fault (%d,%d)", group->group_id, fault_id);
|
||||||
gpio_reset_pin(gpio_fault->gpio_num);
|
|
||||||
|
|
||||||
portENTER_CRITICAL(&group->spinlock);
|
portENTER_CRITICAL(&group->spinlock);
|
||||||
mcpwm_ll_intr_enable(hal->dev, MCPWM_LL_EVENT_FAULT_MASK(fault_id), false);
|
mcpwm_ll_intr_enable(hal->dev, MCPWM_LL_EVENT_FAULT_MASK(fault_id), false);
|
||||||
@ -164,6 +172,10 @@ static esp_err_t mcpwm_del_gpio_fault(mcpwm_fault_handle_t fault)
|
|||||||
// disable fault detection
|
// disable fault detection
|
||||||
mcpwm_ll_fault_enable_detection(hal->dev, fault_id, false);
|
mcpwm_ll_fault_enable_detection(hal->dev, fault_id, false);
|
||||||
|
|
||||||
|
// disconnect signal from the GPIO pin
|
||||||
|
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ZERO_INPUT,
|
||||||
|
mcpwm_periph_signals.groups[group_id].gpio_faults[fault_id].fault_sig, 0);
|
||||||
|
|
||||||
// recycle memory resource
|
// recycle memory resource
|
||||||
ESP_RETURN_ON_ERROR(mcpwm_gpio_fault_destroy(gpio_fault), TAG, "destroy GPIO fault failed");
|
ESP_RETURN_ON_ERROR(mcpwm_gpio_fault_destroy(gpio_fault), TAG, "destroy GPIO fault failed");
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
|
@ -21,10 +21,12 @@
|
|||||||
#include "soc/soc_caps.h"
|
#include "soc/soc_caps.h"
|
||||||
#include "soc/mcpwm_periph.h"
|
#include "soc/mcpwm_periph.h"
|
||||||
#include "hal/mcpwm_ll.h"
|
#include "hal/mcpwm_ll.h"
|
||||||
|
#include "hal/gpio_hal.h"
|
||||||
#include "driver/gpio.h"
|
#include "driver/gpio.h"
|
||||||
#include "driver/mcpwm_gen.h"
|
#include "driver/mcpwm_gen.h"
|
||||||
#include "mcpwm_private.h"
|
#include "mcpwm_private.h"
|
||||||
#include "esp_private/esp_gpio_reserve.h"
|
#include "esp_private/esp_gpio_reserve.h"
|
||||||
|
#include "esp_private/gpio.h"
|
||||||
|
|
||||||
static const char *TAG = "mcpwm";
|
static const char *TAG = "mcpwm";
|
||||||
|
|
||||||
@ -84,27 +86,29 @@ esp_err_t mcpwm_new_generator(mcpwm_oper_handle_t oper, const mcpwm_generator_co
|
|||||||
// reset generator
|
// reset generator
|
||||||
mcpwm_hal_generator_reset(hal, oper_id, gen_id);
|
mcpwm_hal_generator_reset(hal, oper_id, gen_id);
|
||||||
|
|
||||||
// GPIO configuration
|
|
||||||
gen->gen_gpio_num = -1; // gpio not initialized yet
|
gen->gen_gpio_num = -1; // gpio not initialized yet
|
||||||
gpio_config_t gpio_conf = {
|
|
||||||
.intr_type = GPIO_INTR_DISABLE,
|
|
||||||
// also enable the input path if `io_loop_back` is enabled
|
|
||||||
.mode = (config->flags.io_od_mode ? GPIO_MODE_OUTPUT_OD : GPIO_MODE_OUTPUT) | (config->flags.io_loop_back ? GPIO_MODE_INPUT : 0),
|
|
||||||
.pin_bit_mask = (1ULL << config->gen_gpio_num),
|
|
||||||
.pull_down_en = config->flags.pull_down,
|
|
||||||
.pull_up_en = config->flags.pull_up,
|
|
||||||
};
|
|
||||||
ESP_GOTO_ON_ERROR(gpio_config(&gpio_conf), err, TAG, "config gen GPIO failed");
|
|
||||||
// reserve the GPIO output path, because we don't expect another peripheral to signal to the same GPIO
|
// reserve the GPIO output path, because we don't expect another peripheral to signal to the same GPIO
|
||||||
uint64_t old_gpio_rsv_mask = esp_gpio_reserve(BIT64(config->gen_gpio_num));
|
uint64_t old_gpio_rsv_mask = esp_gpio_reserve(BIT64(config->gen_gpio_num));
|
||||||
// check if the GPIO is already used by others
|
// check if the GPIO is already used by others
|
||||||
if (old_gpio_rsv_mask & BIT64(config->gen_gpio_num)) {
|
if (old_gpio_rsv_mask & BIT64(config->gen_gpio_num)) {
|
||||||
ESP_LOGW(TAG, "GPIO %d is not usable, maybe conflict with others", config->gen_gpio_num);
|
ESP_LOGW(TAG, "GPIO %d is not usable, maybe conflict with others", config->gen_gpio_num);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GPIO Matrix/MUX configuration
|
||||||
|
gpio_func_sel(config->gen_gpio_num, PIN_FUNC_GPIO);
|
||||||
|
// connect the signal to the GPIO by matrix, it will also enable the output path properly
|
||||||
esp_rom_gpio_connect_out_signal(config->gen_gpio_num,
|
esp_rom_gpio_connect_out_signal(config->gen_gpio_num,
|
||||||
mcpwm_periph_signals.groups[group->group_id].operators[oper_id].generators[gen_id].pwm_sig,
|
mcpwm_periph_signals.groups[group->group_id].operators[oper_id].generators[gen_id].pwm_sig,
|
||||||
config->flags.invert_pwm, 0);
|
config->flags.invert_pwm, 0);
|
||||||
|
|
||||||
|
// deprecated, to be removed in in esp-idf v6.0
|
||||||
|
if (config->flags.io_loop_back) {
|
||||||
|
gpio_ll_input_enable(&GPIO, config->gen_gpio_num);
|
||||||
|
}
|
||||||
|
if (config->flags.io_od_mode) {
|
||||||
|
gpio_ll_od_enable(&GPIO, config->gen_gpio_num);
|
||||||
|
}
|
||||||
|
|
||||||
// fill in other generator members
|
// fill in other generator members
|
||||||
gen->gen_gpio_num = config->gen_gpio_num;
|
gen->gen_gpio_num = config->gen_gpio_num;
|
||||||
gen->spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED;
|
gen->spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED;
|
||||||
@ -126,9 +130,9 @@ esp_err_t mcpwm_del_generator(mcpwm_gen_handle_t gen)
|
|||||||
mcpwm_group_t *group = oper->group;
|
mcpwm_group_t *group = oper->group;
|
||||||
|
|
||||||
ESP_LOGD(TAG, "del generator (%d,%d,%d)", group->group_id, oper->oper_id, gen->gen_id);
|
ESP_LOGD(TAG, "del generator (%d,%d,%d)", group->group_id, oper->oper_id, gen->gen_id);
|
||||||
// reset GPIO
|
// disable GPIO output
|
||||||
if (gen->gen_gpio_num >= 0) {
|
if (gen->gen_gpio_num >= 0) {
|
||||||
gpio_reset_pin(gen->gen_gpio_num);
|
gpio_output_disable(gen->gen_gpio_num);
|
||||||
esp_gpio_revoke(BIT64(gen->gen_gpio_num));
|
esp_gpio_revoke(BIT64(gen->gen_gpio_num));
|
||||||
}
|
}
|
||||||
// recycle memory resource
|
// recycle memory resource
|
||||||
|
@ -250,9 +250,6 @@ struct mcpwm_cap_channel_t {
|
|||||||
intr_handle_t intr; // Interrupt handle
|
intr_handle_t intr; // Interrupt handle
|
||||||
mcpwm_capture_event_cb_t on_cap; // Callback function which would be invoked in capture interrupt routine
|
mcpwm_capture_event_cb_t on_cap; // Callback function which would be invoked in capture interrupt routine
|
||||||
void *user_data; // user data which would be passed to the capture callback
|
void *user_data; // user data which would be passed to the capture callback
|
||||||
struct {
|
|
||||||
uint32_t reset_io_at_exit: 1; // Whether to reset the GPIO configuration when capture channel is deleted
|
|
||||||
} flags;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
mcpwm_group_t *mcpwm_acquire_group_handle(int group_id);
|
mcpwm_group_t *mcpwm_acquire_group_handle(int group_id);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@ -22,9 +22,11 @@
|
|||||||
#include "soc/soc_caps.h"
|
#include "soc/soc_caps.h"
|
||||||
#include "soc/mcpwm_periph.h"
|
#include "soc/mcpwm_periph.h"
|
||||||
#include "hal/mcpwm_ll.h"
|
#include "hal/mcpwm_ll.h"
|
||||||
|
#include "hal/gpio_hal.h"
|
||||||
#include "driver/mcpwm_sync.h"
|
#include "driver/mcpwm_sync.h"
|
||||||
#include "driver/gpio.h"
|
#include "driver/gpio.h"
|
||||||
#include "mcpwm_private.h"
|
#include "mcpwm_private.h"
|
||||||
|
#include "esp_private/gpio.h"
|
||||||
|
|
||||||
static const char *TAG = "mcpwm";
|
static const char *TAG = "mcpwm";
|
||||||
|
|
||||||
@ -192,16 +194,23 @@ esp_err_t mcpwm_new_gpio_sync_src(const mcpwm_gpio_sync_src_config_t *config, mc
|
|||||||
int sync_id = gpio_sync_src->sync_id;
|
int sync_id = gpio_sync_src->sync_id;
|
||||||
|
|
||||||
// GPIO configuration
|
// GPIO configuration
|
||||||
gpio_config_t gpio_conf = {
|
gpio_func_sel(config->gpio_num, PIN_FUNC_GPIO);
|
||||||
.intr_type = GPIO_INTR_DISABLE,
|
gpio_input_enable(config->gpio_num);
|
||||||
.mode = GPIO_MODE_INPUT | (config->flags.io_loop_back ? GPIO_MODE_OUTPUT : 0), // also enable the output path if `io_loop_back` is enabled
|
|
||||||
.pin_bit_mask = (1ULL << config->gpio_num),
|
|
||||||
.pull_down_en = config->flags.pull_down,
|
|
||||||
.pull_up_en = config->flags.pull_up,
|
|
||||||
};
|
|
||||||
ESP_GOTO_ON_ERROR(gpio_config(&gpio_conf), err, TAG, "config sync GPIO failed");
|
|
||||||
esp_rom_gpio_connect_in_signal(config->gpio_num, mcpwm_periph_signals.groups[group_id].gpio_synchros[sync_id].sync_sig, 0);
|
esp_rom_gpio_connect_in_signal(config->gpio_num, mcpwm_periph_signals.groups[group_id].gpio_synchros[sync_id].sync_sig, 0);
|
||||||
|
|
||||||
|
if (config->flags.pull_down) {
|
||||||
|
gpio_pulldown_en(config->gpio_num);
|
||||||
|
}
|
||||||
|
if (config->flags.pull_up) {
|
||||||
|
gpio_pullup_en(config->gpio_num);
|
||||||
|
}
|
||||||
|
|
||||||
|
// deprecated, to be removed in in esp-idf v6.0
|
||||||
|
if (config->flags.io_loop_back) {
|
||||||
|
gpio_ll_output_enable(&GPIO, config->gpio_num);
|
||||||
|
}
|
||||||
|
|
||||||
// different ext sync share the same config register, using a group level spin lock
|
// different ext sync share the same config register, using a group level spin lock
|
||||||
portENTER_CRITICAL(&group->spinlock);
|
portENTER_CRITICAL(&group->spinlock);
|
||||||
mcpwm_ll_invert_gpio_sync_input(group->hal.dev, sync_id, config->flags.active_neg);
|
mcpwm_ll_invert_gpio_sync_input(group->hal.dev, sync_id, config->flags.active_neg);
|
||||||
@ -226,9 +235,11 @@ static esp_err_t mcpwm_del_gpio_sync_src(mcpwm_sync_t *sync_src)
|
|||||||
{
|
{
|
||||||
mcpwm_gpio_sync_src_t *gpio_sync_src = __containerof(sync_src, mcpwm_gpio_sync_src_t, base);
|
mcpwm_gpio_sync_src_t *gpio_sync_src = __containerof(sync_src, mcpwm_gpio_sync_src_t, base);
|
||||||
mcpwm_group_t *group = sync_src->group;
|
mcpwm_group_t *group = sync_src->group;
|
||||||
|
int group_id = group->group_id;
|
||||||
|
int sync_id = gpio_sync_src->sync_id;
|
||||||
|
|
||||||
ESP_LOGD(TAG, "del gpio sync_src (%d,%d)", group->group_id, gpio_sync_src->sync_id);
|
ESP_LOGD(TAG, "del gpio sync_src (%d,%d)", group->group_id, gpio_sync_src->sync_id);
|
||||||
gpio_reset_pin(gpio_sync_src->gpio_num);
|
esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ZERO_INPUT, mcpwm_periph_signals.groups[group_id].gpio_synchros[sync_id].sync_sig, 0);
|
||||||
|
|
||||||
// recycle memory resource
|
// recycle memory resource
|
||||||
ESP_RETURN_ON_ERROR(mcpwm_gpio_sync_src_destroy(gpio_sync_src), TAG, "destroy GPIO sync_src failed");
|
ESP_RETURN_ON_ERROR(mcpwm_gpio_sync_src_destroy(gpio_sync_src), TAG, "destroy GPIO sync_src failed");
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@ -71,6 +71,14 @@ static bool test_capture_callback(mcpwm_cap_channel_handle_t cap_channel, const
|
|||||||
|
|
||||||
TEST_CASE("mcpwm_capture_ext_gpio", "[mcpwm]")
|
TEST_CASE("mcpwm_capture_ext_gpio", "[mcpwm]")
|
||||||
{
|
{
|
||||||
|
printf("init a gpio to simulate the external capture signal\r\n");
|
||||||
|
const int cap_gpio = TEST_CAP_GPIO;
|
||||||
|
gpio_config_t ext_gpio_conf = {
|
||||||
|
.mode = GPIO_MODE_OUTPUT,
|
||||||
|
.pin_bit_mask = BIT(cap_gpio),
|
||||||
|
};
|
||||||
|
TEST_ESP_OK(gpio_config(&ext_gpio_conf));
|
||||||
|
|
||||||
printf("install mcpwm capture timer\r\n");
|
printf("install mcpwm capture timer\r\n");
|
||||||
mcpwm_cap_timer_handle_t cap_timer = NULL;
|
mcpwm_cap_timer_handle_t cap_timer = NULL;
|
||||||
mcpwm_capture_timer_config_t cap_timer_config = {
|
mcpwm_capture_timer_config_t cap_timer_config = {
|
||||||
@ -80,7 +88,6 @@ TEST_CASE("mcpwm_capture_ext_gpio", "[mcpwm]")
|
|||||||
};
|
};
|
||||||
TEST_ESP_OK(mcpwm_new_capture_timer(&cap_timer_config, &cap_timer));
|
TEST_ESP_OK(mcpwm_new_capture_timer(&cap_timer_config, &cap_timer));
|
||||||
|
|
||||||
const int cap_gpio = TEST_CAP_GPIO;
|
|
||||||
// put the GPIO into a preset state
|
// put the GPIO into a preset state
|
||||||
gpio_set_level(cap_gpio, 0);
|
gpio_set_level(cap_gpio, 0);
|
||||||
|
|
||||||
@ -91,7 +98,6 @@ TEST_CASE("mcpwm_capture_ext_gpio", "[mcpwm]")
|
|||||||
.prescale = 1,
|
.prescale = 1,
|
||||||
.flags.pos_edge = true,
|
.flags.pos_edge = true,
|
||||||
.flags.neg_edge = true,
|
.flags.neg_edge = true,
|
||||||
.flags.io_loop_back = true, // so we can use GPIO functions to simulate the external capture signal
|
|
||||||
.flags.pull_up = true,
|
.flags.pull_up = true,
|
||||||
};
|
};
|
||||||
TEST_ESP_OK(mcpwm_new_capture_channel(cap_timer, &cap_chan_config, &pps_channel));
|
TEST_ESP_OK(mcpwm_new_capture_channel(cap_timer, &cap_chan_config, &pps_channel));
|
||||||
@ -127,6 +133,7 @@ TEST_CASE("mcpwm_capture_ext_gpio", "[mcpwm]")
|
|||||||
TEST_ESP_OK(mcpwm_del_capture_channel(pps_channel));
|
TEST_ESP_OK(mcpwm_del_capture_channel(pps_channel));
|
||||||
TEST_ESP_OK(mcpwm_capture_timer_disable(cap_timer));
|
TEST_ESP_OK(mcpwm_capture_timer_disable(cap_timer));
|
||||||
TEST_ESP_OK(mcpwm_del_capture_timer(cap_timer));
|
TEST_ESP_OK(mcpwm_del_capture_timer(cap_timer));
|
||||||
|
TEST_ESP_OK(gpio_reset_pin(cap_gpio));
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -58,15 +58,21 @@ static bool IRAM_ATTR test_fault_exit_callback(mcpwm_fault_handle_t detector, co
|
|||||||
|
|
||||||
TEST_CASE("mcpwm_gpio_fault_event_callbacks", "[mcpwm]")
|
TEST_CASE("mcpwm_gpio_fault_event_callbacks", "[mcpwm]")
|
||||||
{
|
{
|
||||||
printf("create gpio fault\r\n");
|
printf("init a gpio to simulate the fault signal\r\n");
|
||||||
const int fault_gpio = TEST_FAULT_GPIO;
|
const int fault_gpio = TEST_FAULT_GPIO;
|
||||||
|
gpio_config_t fault_gpio_conf = {
|
||||||
|
.mode = GPIO_MODE_OUTPUT,
|
||||||
|
.pin_bit_mask = BIT(fault_gpio),
|
||||||
|
};
|
||||||
|
TEST_ESP_OK(gpio_config(&fault_gpio_conf));
|
||||||
|
|
||||||
|
printf("create gpio fault\r\n");
|
||||||
mcpwm_fault_handle_t fault = NULL;
|
mcpwm_fault_handle_t fault = NULL;
|
||||||
mcpwm_gpio_fault_config_t gpio_fault_config = {
|
mcpwm_gpio_fault_config_t gpio_fault_config = {
|
||||||
.group_id = 0,
|
.group_id = 0,
|
||||||
.gpio_num = fault_gpio,
|
.gpio_num = fault_gpio,
|
||||||
.flags.active_level = true, // active on high level
|
.flags.active_level = true, // active on high level
|
||||||
.flags.pull_down = true,
|
.flags.pull_down = true,
|
||||||
.flags.io_loop_back = true, // for debug, so that we can use gpio_set_level to mimic a fault source
|
|
||||||
};
|
};
|
||||||
TEST_ESP_OK(mcpwm_new_gpio_fault(&gpio_fault_config, &fault));
|
TEST_ESP_OK(mcpwm_new_gpio_fault(&gpio_fault_config, &fault));
|
||||||
|
|
||||||
@ -80,7 +86,7 @@ TEST_CASE("mcpwm_gpio_fault_event_callbacks", "[mcpwm]")
|
|||||||
};
|
};
|
||||||
TaskHandle_t task_to_notify = xTaskGetCurrentTaskHandle();
|
TaskHandle_t task_to_notify = xTaskGetCurrentTaskHandle();
|
||||||
TEST_ESP_OK(mcpwm_fault_register_event_callbacks(fault, &cbs, task_to_notify));
|
TEST_ESP_OK(mcpwm_fault_register_event_callbacks(fault, &cbs, task_to_notify));
|
||||||
TEST_ASSERT_EQUAL(0, ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(1000)));
|
TEST_ASSERT_EQUAL(0, ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(100)));
|
||||||
|
|
||||||
printf("trigget a fault event\r\n");
|
printf("trigget a fault event\r\n");
|
||||||
gpio_set_level(fault_gpio, 1);
|
gpio_set_level(fault_gpio, 1);
|
||||||
@ -91,4 +97,5 @@ TEST_CASE("mcpwm_gpio_fault_event_callbacks", "[mcpwm]")
|
|||||||
TEST_ASSERT_NOT_EQUAL(0, ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(10)));
|
TEST_ASSERT_NOT_EQUAL(0, ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(10)));
|
||||||
|
|
||||||
TEST_ESP_OK(mcpwm_del_fault(fault));
|
TEST_ESP_OK(mcpwm_del_fault(fault));
|
||||||
|
TEST_ESP_OK(gpio_reset_pin(fault_gpio));
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
#include "unity.h"
|
#include "unity.h"
|
||||||
#include "soc/soc_caps.h"
|
#include "soc/soc_caps.h"
|
||||||
|
#include "driver/mcpwm_cap.h"
|
||||||
#include "driver/mcpwm_timer.h"
|
#include "driver/mcpwm_timer.h"
|
||||||
#include "driver/mcpwm_oper.h"
|
#include "driver/mcpwm_oper.h"
|
||||||
#include "driver/mcpwm_cmpr.h"
|
#include "driver/mcpwm_cmpr.h"
|
||||||
@ -15,6 +16,7 @@
|
|||||||
#include "driver/mcpwm_sync.h"
|
#include "driver/mcpwm_sync.h"
|
||||||
#include "driver/gpio.h"
|
#include "driver/gpio.h"
|
||||||
#include "test_mcpwm_utils.h"
|
#include "test_mcpwm_utils.h"
|
||||||
|
#include "esp_clk_tree.h"
|
||||||
|
|
||||||
TEST_CASE("mcpwm_generator_install_uninstall", "[mcpwm]")
|
TEST_CASE("mcpwm_generator_install_uninstall", "[mcpwm]")
|
||||||
{
|
{
|
||||||
@ -46,6 +48,14 @@ TEST_CASE("mcpwm_generator_install_uninstall", "[mcpwm]")
|
|||||||
|
|
||||||
TEST_CASE("mcpwm_generator_force_level_hold_on", "[mcpwm]")
|
TEST_CASE("mcpwm_generator_force_level_hold_on", "[mcpwm]")
|
||||||
{
|
{
|
||||||
|
const int gen_gpio = TEST_PWMA_GPIO;
|
||||||
|
printf("init a gpio to read generator output\r\n");
|
||||||
|
gpio_config_t gen_gpio_conf = {
|
||||||
|
.mode = GPIO_MODE_INPUT,
|
||||||
|
.pin_bit_mask = BIT(gen_gpio),
|
||||||
|
};
|
||||||
|
TEST_ESP_OK(gpio_config(&gen_gpio_conf));
|
||||||
|
|
||||||
// The operator can even work without the timer
|
// The operator can even work without the timer
|
||||||
printf("create operator and generator\r\n");
|
printf("create operator and generator\r\n");
|
||||||
mcpwm_oper_handle_t oper = NULL;
|
mcpwm_oper_handle_t oper = NULL;
|
||||||
@ -55,10 +65,8 @@ TEST_CASE("mcpwm_generator_force_level_hold_on", "[mcpwm]")
|
|||||||
TEST_ESP_OK(mcpwm_new_operator(&operator_config, &oper));
|
TEST_ESP_OK(mcpwm_new_operator(&operator_config, &oper));
|
||||||
|
|
||||||
mcpwm_gen_handle_t generator = NULL;
|
mcpwm_gen_handle_t generator = NULL;
|
||||||
const int gen_gpio = TEST_PWMA_GPIO;
|
|
||||||
mcpwm_generator_config_t generator_config = {
|
mcpwm_generator_config_t generator_config = {
|
||||||
.gen_gpio_num = gen_gpio,
|
.gen_gpio_num = gen_gpio,
|
||||||
.flags.io_loop_back = true, // loop back for test
|
|
||||||
};
|
};
|
||||||
TEST_ESP_OK(mcpwm_new_generator(oper, &generator_config, &generator));
|
TEST_ESP_OK(mcpwm_new_generator(oper, &generator_config, &generator));
|
||||||
|
|
||||||
@ -78,12 +86,22 @@ TEST_CASE("mcpwm_generator_force_level_hold_on", "[mcpwm]")
|
|||||||
printf("delete generator and operator\r\n");
|
printf("delete generator and operator\r\n");
|
||||||
TEST_ESP_OK(mcpwm_del_generator(generator));
|
TEST_ESP_OK(mcpwm_del_generator(generator));
|
||||||
TEST_ESP_OK(mcpwm_del_operator(oper));
|
TEST_ESP_OK(mcpwm_del_operator(oper));
|
||||||
|
TEST_ESP_OK(gpio_reset_pin(gen_gpio));
|
||||||
}
|
}
|
||||||
|
|
||||||
// mcpwm_generator_set_force_level acts before the dead time module
|
// mcpwm_generator_set_force_level acts before the dead time module
|
||||||
// so the value output on the generator is a combined result
|
// so the value output on the generator is a combined result
|
||||||
TEST_CASE("mcpwm_force_level_and_dead_time", "[mcpwm]")
|
TEST_CASE("mcpwm_force_level_and_dead_time", "[mcpwm]")
|
||||||
{
|
{
|
||||||
|
const int gen_a_gpio = TEST_PWMA_GPIO;
|
||||||
|
const int gen_b_gpio = TEST_PWMB_GPIO;
|
||||||
|
printf("init gpios to read generator output\r\n");
|
||||||
|
gpio_config_t gen_gpio_conf = {
|
||||||
|
.mode = GPIO_MODE_INPUT,
|
||||||
|
.pin_bit_mask = BIT(gen_a_gpio) | BIT(gen_b_gpio),
|
||||||
|
};
|
||||||
|
TEST_ESP_OK(gpio_config(&gen_gpio_conf));
|
||||||
|
|
||||||
printf("create operator and generators\r\n");
|
printf("create operator and generators\r\n");
|
||||||
mcpwm_oper_handle_t oper = NULL;
|
mcpwm_oper_handle_t oper = NULL;
|
||||||
mcpwm_operator_config_t operator_config = {
|
mcpwm_operator_config_t operator_config = {
|
||||||
@ -93,11 +111,8 @@ TEST_CASE("mcpwm_force_level_and_dead_time", "[mcpwm]")
|
|||||||
|
|
||||||
mcpwm_gen_handle_t gen_a = NULL;
|
mcpwm_gen_handle_t gen_a = NULL;
|
||||||
mcpwm_gen_handle_t gen_b = NULL;
|
mcpwm_gen_handle_t gen_b = NULL;
|
||||||
const int gen_a_gpio = TEST_PWMA_GPIO;
|
|
||||||
const int gen_b_gpio = TEST_PWMB_GPIO;
|
|
||||||
mcpwm_generator_config_t generator_config = {
|
mcpwm_generator_config_t generator_config = {
|
||||||
.gen_gpio_num = gen_a_gpio,
|
.gen_gpio_num = gen_a_gpio,
|
||||||
.flags.io_loop_back = true, // loop back for test
|
|
||||||
};
|
};
|
||||||
TEST_ESP_OK(mcpwm_new_generator(oper, &generator_config, &gen_a));
|
TEST_ESP_OK(mcpwm_new_generator(oper, &generator_config, &gen_a));
|
||||||
generator_config.gen_gpio_num = gen_b_gpio;
|
generator_config.gen_gpio_num = gen_b_gpio;
|
||||||
@ -128,10 +143,20 @@ TEST_CASE("mcpwm_force_level_and_dead_time", "[mcpwm]")
|
|||||||
TEST_ESP_OK(mcpwm_del_generator(gen_a));
|
TEST_ESP_OK(mcpwm_del_generator(gen_a));
|
||||||
TEST_ESP_OK(mcpwm_del_generator(gen_b));
|
TEST_ESP_OK(mcpwm_del_generator(gen_b));
|
||||||
TEST_ESP_OK(mcpwm_del_operator(oper));
|
TEST_ESP_OK(mcpwm_del_operator(oper));
|
||||||
|
TEST_ESP_OK(gpio_reset_pin(gen_a_gpio));
|
||||||
|
TEST_ESP_OK(gpio_reset_pin(gen_b_gpio));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("mcpwm_generator_force_level_recovery", "[mcpwm]")
|
TEST_CASE("mcpwm_generator_force_level_recovery", "[mcpwm]")
|
||||||
{
|
{
|
||||||
|
const int gen_gpio = TEST_PWMA_GPIO;
|
||||||
|
printf("init a gpio to read generator output\r\n");
|
||||||
|
gpio_config_t gen_gpio_conf = {
|
||||||
|
.mode = GPIO_MODE_INPUT,
|
||||||
|
.pin_bit_mask = BIT(gen_gpio),
|
||||||
|
};
|
||||||
|
TEST_ESP_OK(gpio_config(&gen_gpio_conf));
|
||||||
|
|
||||||
printf("create mcpwm timer\r\n");
|
printf("create mcpwm timer\r\n");
|
||||||
mcpwm_timer_config_t timer_config = {
|
mcpwm_timer_config_t timer_config = {
|
||||||
.group_id = 0,
|
.group_id = 0,
|
||||||
@ -155,10 +180,8 @@ TEST_CASE("mcpwm_generator_force_level_recovery", "[mcpwm]")
|
|||||||
|
|
||||||
printf("create generator\r\n");
|
printf("create generator\r\n");
|
||||||
mcpwm_gen_handle_t generator = NULL;
|
mcpwm_gen_handle_t generator = NULL;
|
||||||
const int gen_gpio = TEST_PWMA_GPIO;
|
|
||||||
mcpwm_generator_config_t generator_config = {
|
mcpwm_generator_config_t generator_config = {
|
||||||
.gen_gpio_num = gen_gpio,
|
.gen_gpio_num = gen_gpio,
|
||||||
.flags.io_loop_back = true, // loop back for test
|
|
||||||
};
|
};
|
||||||
TEST_ESP_OK(mcpwm_new_generator(oper, &generator_config, &generator));
|
TEST_ESP_OK(mcpwm_new_generator(oper, &generator_config, &generator));
|
||||||
|
|
||||||
@ -195,11 +218,19 @@ TEST_CASE("mcpwm_generator_force_level_recovery", "[mcpwm]")
|
|||||||
TEST_ESP_OK(mcpwm_del_generator(generator));
|
TEST_ESP_OK(mcpwm_del_generator(generator));
|
||||||
TEST_ESP_OK(mcpwm_del_operator(oper));
|
TEST_ESP_OK(mcpwm_del_operator(oper));
|
||||||
TEST_ESP_OK(mcpwm_del_timer(timer));
|
TEST_ESP_OK(mcpwm_del_timer(timer));
|
||||||
|
TEST_ESP_OK(gpio_reset_pin(gen_gpio));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("mcpwm_generator_action_on_timer_event", "[mcpwm]")
|
TEST_CASE("mcpwm_generator_action_on_timer_event", "[mcpwm]")
|
||||||
{
|
{
|
||||||
const int generator_gpio = TEST_PWMA_GPIO;
|
const int generator_gpio = TEST_PWMA_GPIO;
|
||||||
|
printf("init a gpio to read generator output\r\n");
|
||||||
|
gpio_config_t gen_gpio_conf = {
|
||||||
|
.mode = GPIO_MODE_INPUT,
|
||||||
|
.pin_bit_mask = BIT(generator_gpio),
|
||||||
|
};
|
||||||
|
TEST_ESP_OK(gpio_config(&gen_gpio_conf));
|
||||||
|
|
||||||
printf("create timer and operator\r\n");
|
printf("create timer and operator\r\n");
|
||||||
mcpwm_timer_config_t timer_config = {
|
mcpwm_timer_config_t timer_config = {
|
||||||
.group_id = 0,
|
.group_id = 0,
|
||||||
@ -224,7 +255,6 @@ TEST_CASE("mcpwm_generator_action_on_timer_event", "[mcpwm]")
|
|||||||
printf("create generator\r\n");
|
printf("create generator\r\n");
|
||||||
mcpwm_generator_config_t gen_config = {
|
mcpwm_generator_config_t gen_config = {
|
||||||
.gen_gpio_num = generator_gpio,
|
.gen_gpio_num = generator_gpio,
|
||||||
.flags.io_loop_back = 1, // so that we can read the GPIO value by GPIO driver
|
|
||||||
};
|
};
|
||||||
mcpwm_gen_handle_t gen = NULL;
|
mcpwm_gen_handle_t gen = NULL;
|
||||||
TEST_ESP_OK(mcpwm_new_generator(oper, &gen_config, &gen));
|
TEST_ESP_OK(mcpwm_new_generator(oper, &gen_config, &gen));
|
||||||
@ -258,12 +288,26 @@ TEST_CASE("mcpwm_generator_action_on_timer_event", "[mcpwm]")
|
|||||||
TEST_ESP_OK(mcpwm_del_generator(gen));
|
TEST_ESP_OK(mcpwm_del_generator(gen));
|
||||||
TEST_ESP_OK(mcpwm_del_operator(oper));
|
TEST_ESP_OK(mcpwm_del_operator(oper));
|
||||||
TEST_ESP_OK(mcpwm_del_timer(timer));
|
TEST_ESP_OK(mcpwm_del_timer(timer));
|
||||||
|
TEST_ESP_OK(gpio_reset_pin(generator_gpio));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_MCPWM_CALLBACK_ATTR
|
||||||
|
static bool test_capture_callback(mcpwm_cap_channel_handle_t cap_channel, const mcpwm_capture_event_data_t *edata, void *user_data)
|
||||||
|
{
|
||||||
|
uint32_t *cap_value = (uint32_t *)user_data;
|
||||||
|
if (edata->cap_edge == MCPWM_CAP_EDGE_NEG) {
|
||||||
|
cap_value[1] = edata->cap_value;
|
||||||
|
} else {
|
||||||
|
cap_value[0] = edata->cap_value;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef void (*set_gen_actions_cb_t)(mcpwm_gen_handle_t gena, mcpwm_gen_handle_t genb, mcpwm_cmpr_handle_t cmpa, mcpwm_cmpr_handle_t cmpb);
|
typedef void (*set_gen_actions_cb_t)(mcpwm_gen_handle_t gena, mcpwm_gen_handle_t genb, mcpwm_cmpr_handle_t cmpa, mcpwm_cmpr_handle_t cmpb);
|
||||||
|
|
||||||
static void mcpwm_gen_action_test_template(uint32_t timer_resolution, uint32_t period, mcpwm_timer_count_mode_t count_mode,
|
static void mcpwm_gen_action_test_template(uint32_t timer_resolution, uint32_t period, mcpwm_timer_count_mode_t count_mode,
|
||||||
uint32_t cmpa, uint32_t cmpb, int gpioa, int gpiob, set_gen_actions_cb_t set_generator_actions)
|
uint32_t cmpa, uint32_t cmpb, int gpioa, int gpiob, set_gen_actions_cb_t set_generator_actions,
|
||||||
|
uint32_t *ret_capa, uint32_t *ret_capb)
|
||||||
{
|
{
|
||||||
mcpwm_timer_config_t timer_config = {
|
mcpwm_timer_config_t timer_config = {
|
||||||
.group_id = 0,
|
.group_id = 0,
|
||||||
@ -305,10 +349,72 @@ static void mcpwm_gen_action_test_template(uint32_t timer_resolution, uint32_t p
|
|||||||
|
|
||||||
set_generator_actions(generator_a, generator_b, comparator_a, comparator_b);
|
set_generator_actions(generator_a, generator_b, comparator_a, comparator_b);
|
||||||
|
|
||||||
|
// install mcpwm capture timer
|
||||||
|
mcpwm_cap_timer_handle_t cap_timer = NULL;
|
||||||
|
uint32_t clk_src_freq_hz;
|
||||||
|
esp_clk_tree_src_get_freq_hz(MCPWM_CAPTURE_CLK_SRC_DEFAULT, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clk_src_freq_hz);
|
||||||
|
mcpwm_capture_timer_config_t cap_timer_config = {
|
||||||
|
.clk_src = MCPWM_CAPTURE_CLK_SRC_DEFAULT,
|
||||||
|
.group_id = 0,
|
||||||
|
.resolution_hz = clk_src_freq_hz / 2,
|
||||||
|
};
|
||||||
|
TEST_ESP_OK(mcpwm_new_capture_timer(&cap_timer_config, &cap_timer));
|
||||||
|
|
||||||
|
// install mcpwm capture channel
|
||||||
|
mcpwm_cap_channel_handle_t cap_channel_a;
|
||||||
|
mcpwm_cap_channel_handle_t cap_channel_b;
|
||||||
|
mcpwm_capture_channel_config_t cap_chan_config = {
|
||||||
|
.gpio_num = gpioa,
|
||||||
|
.prescale = 1,
|
||||||
|
.flags.pos_edge = true,
|
||||||
|
.flags.neg_edge = true,
|
||||||
|
};
|
||||||
|
TEST_ESP_OK(mcpwm_new_capture_channel(cap_timer, &cap_chan_config, &cap_channel_a));
|
||||||
|
cap_chan_config.gpio_num = gpiob;
|
||||||
|
TEST_ESP_OK(mcpwm_new_capture_channel(cap_timer, &cap_chan_config, &cap_channel_b));
|
||||||
|
|
||||||
|
// install callback for capture channel
|
||||||
|
mcpwm_capture_event_callbacks_t cbs = {
|
||||||
|
.on_cap = test_capture_callback,
|
||||||
|
};
|
||||||
|
uint32_t cap_value_a[2] = {0};
|
||||||
|
uint32_t cap_value_b[2] = {0};
|
||||||
|
TEST_ESP_OK(mcpwm_capture_channel_register_event_callbacks(cap_channel_a, &cbs, cap_value_a));
|
||||||
|
TEST_ESP_OK(mcpwm_capture_channel_register_event_callbacks(cap_channel_b, &cbs, cap_value_b));
|
||||||
|
|
||||||
|
// enable capture channel and timer
|
||||||
|
TEST_ESP_OK(mcpwm_capture_channel_enable(cap_channel_a));
|
||||||
|
TEST_ESP_OK(mcpwm_capture_channel_enable(cap_channel_b));
|
||||||
|
TEST_ESP_OK(mcpwm_capture_timer_enable(cap_timer));
|
||||||
|
|
||||||
|
// start timer and capture timer
|
||||||
TEST_ESP_OK(mcpwm_timer_start_stop(timer, MCPWM_TIMER_START_NO_STOP));
|
TEST_ESP_OK(mcpwm_timer_start_stop(timer, MCPWM_TIMER_START_NO_STOP));
|
||||||
|
TEST_ESP_OK(mcpwm_capture_timer_start(cap_timer));
|
||||||
vTaskDelay(pdMS_TO_TICKS(100));
|
vTaskDelay(pdMS_TO_TICKS(100));
|
||||||
TEST_ESP_OK(mcpwm_timer_start_stop(timer, MCPWM_TIMER_STOP_EMPTY));
|
TEST_ESP_OK(mcpwm_timer_start_stop(timer, MCPWM_TIMER_STOP_EMPTY));
|
||||||
vTaskDelay(pdMS_TO_TICKS(10));
|
vTaskDelay(pdMS_TO_TICKS(10));
|
||||||
|
TEST_ESP_OK(mcpwm_capture_timer_stop(cap_timer));
|
||||||
|
|
||||||
|
// calculate the actual capture time
|
||||||
|
uint32_t clk_src_res;
|
||||||
|
TEST_ESP_OK(mcpwm_capture_timer_get_resolution(cap_timer, &clk_src_res));
|
||||||
|
clk_src_res /= 1000; // convert to kHz
|
||||||
|
|
||||||
|
if (cap_value_a[1] > cap_value_a[0]) {
|
||||||
|
// generator end with low level, calculate the high level time
|
||||||
|
*ret_capa = (cap_value_a[1] - cap_value_a[0]) * 1000 / clk_src_res;
|
||||||
|
} else {
|
||||||
|
// generator end with high level, calculate the low level time
|
||||||
|
*ret_capa = (cap_value_a[0] - cap_value_a[1]) * 1000 / clk_src_res;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cap_value_b[1] > cap_value_b[0]) {
|
||||||
|
// generator end with low level, calculate the high level time
|
||||||
|
*ret_capb = (cap_value_b[1] - cap_value_b[0]) * 1000 / clk_src_res;
|
||||||
|
} else {
|
||||||
|
// generator end with high level, calculate the low level time
|
||||||
|
*ret_capb = (cap_value_b[0] - cap_value_b[1]) * 1000 / clk_src_res;
|
||||||
|
}
|
||||||
|
|
||||||
TEST_ESP_OK(mcpwm_timer_disable(timer));
|
TEST_ESP_OK(mcpwm_timer_disable(timer));
|
||||||
TEST_ESP_OK(mcpwm_del_generator(generator_a));
|
TEST_ESP_OK(mcpwm_del_generator(generator_a));
|
||||||
@ -317,6 +423,12 @@ static void mcpwm_gen_action_test_template(uint32_t timer_resolution, uint32_t p
|
|||||||
TEST_ESP_OK(mcpwm_del_comparator(comparator_b));
|
TEST_ESP_OK(mcpwm_del_comparator(comparator_b));
|
||||||
TEST_ESP_OK(mcpwm_del_operator(oper));
|
TEST_ESP_OK(mcpwm_del_operator(oper));
|
||||||
TEST_ESP_OK(mcpwm_del_timer(timer));
|
TEST_ESP_OK(mcpwm_del_timer(timer));
|
||||||
|
TEST_ESP_OK(mcpwm_capture_channel_disable(cap_channel_a));
|
||||||
|
TEST_ESP_OK(mcpwm_del_capture_channel(cap_channel_a));
|
||||||
|
TEST_ESP_OK(mcpwm_capture_channel_disable(cap_channel_b));
|
||||||
|
TEST_ESP_OK(mcpwm_del_capture_channel(cap_channel_b));
|
||||||
|
TEST_ESP_OK(mcpwm_capture_timer_disable(cap_timer));
|
||||||
|
TEST_ESP_OK(mcpwm_del_capture_timer(cap_timer));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void single_edge_active_high(mcpwm_gen_handle_t gena, mcpwm_gen_handle_t genb, mcpwm_cmpr_handle_t cmpa, mcpwm_cmpr_handle_t cmpb)
|
static void single_edge_active_high(mcpwm_gen_handle_t gena, mcpwm_gen_handle_t genb, mcpwm_cmpr_handle_t cmpa, mcpwm_cmpr_handle_t cmpb)
|
||||||
@ -392,41 +504,55 @@ static void dual_edge_complementary(mcpwm_gen_handle_t gena, mcpwm_gen_handle_t
|
|||||||
|
|
||||||
TEST_CASE("mcpwm_generator_action_on_compare_event", "[mcpwm]")
|
TEST_CASE("mcpwm_generator_action_on_compare_event", "[mcpwm]")
|
||||||
{
|
{
|
||||||
|
uint32_t capa, capb;
|
||||||
printf("[Asymmetric, SingleEdge, ActiveHigh]\r\n");
|
printf("[Asymmetric, SingleEdge, ActiveHigh]\r\n");
|
||||||
// PWMA: high = [1->350], low = [351->499,0]
|
// PWMA: high = [1->350], low = [351->499,0]
|
||||||
// PWMB: high = [1->200], low = [201->499,0]
|
// PWMB: high = [1->200], low = [201->499,0]
|
||||||
mcpwm_gen_action_test_template(1000000, 500, MCPWM_TIMER_COUNT_MODE_UP, 350, 200, TEST_PWMA_GPIO, TEST_PWMB_GPIO, single_edge_active_high);
|
mcpwm_gen_action_test_template(1000000, 500, MCPWM_TIMER_COUNT_MODE_UP, 350, 200, TEST_PWMA_GPIO, TEST_PWMB_GPIO, single_edge_active_high, &capa, &capb);
|
||||||
|
TEST_ASSERT_UINT_WITHIN(2, 150, capa);
|
||||||
|
TEST_ASSERT_UINT_WITHIN(2, 300, capb);
|
||||||
|
|
||||||
printf("[Asymmetric, SingleEdge, ActiveLow]\r\n");
|
printf("[Asymmetric, SingleEdge, ActiveLow]\r\n");
|
||||||
// PWMA: low = [0->300], high = [301->499]
|
// PWMA: low = [0->300], high = [301->499]
|
||||||
// PWMB: low = [0->150], high = [151->499]
|
// PWMB: low = [0->150], high = [151->499]
|
||||||
mcpwm_gen_action_test_template(1000000, 500, MCPWM_TIMER_COUNT_MODE_UP, 300, 150, TEST_PWMA_GPIO, TEST_PWMB_GPIO, single_edge_active_low);
|
mcpwm_gen_action_test_template(1000000, 500, MCPWM_TIMER_COUNT_MODE_UP, 300, 150, TEST_PWMA_GPIO, TEST_PWMB_GPIO, single_edge_active_low, &capa, &capb);
|
||||||
|
TEST_ASSERT_UINT_WITHIN(2, 200, capa);
|
||||||
|
TEST_ASSERT_UINT_WITHIN(2, 350, capb);
|
||||||
|
|
||||||
printf("[Asymmetric, PulsePlacement]\r\n");
|
printf("[Asymmetric, PulsePlacement]\r\n");
|
||||||
// PWMA: low = [0->200], high = [201->400], low = [401->599]
|
// PWMA: low = [0->200], high = [201->400], low = [401->599]
|
||||||
// PWMB: high = [0->599], low = [0->599]
|
// PWMB: high = [0->599], low = [0->599]
|
||||||
mcpwm_gen_action_test_template(1000000, 600, MCPWM_TIMER_COUNT_MODE_UP, 200, 400, TEST_PWMA_GPIO, TEST_PWMB_GPIO, pulse_placement);
|
mcpwm_gen_action_test_template(1000000, 600, MCPWM_TIMER_COUNT_MODE_UP, 200, 400, TEST_PWMA_GPIO, TEST_PWMB_GPIO, pulse_placement, &capa, &capb);
|
||||||
|
TEST_ASSERT_UINT_WITHIN(2, 200, capa);
|
||||||
|
TEST_ASSERT_UINT_WITHIN(2, 600, capb);
|
||||||
|
|
||||||
printf("[Asymmetric, DualEdge, ActiveLow]\r\n");
|
printf("[Asymmetric, DualEdge, ActiveLow]\r\n");
|
||||||
// PWMA: low = [0->250], high = [251->599, 600->450], low = [451->1]
|
// PWMA: low = [0->250], high = [251->599, 600->450], low = [451->1]
|
||||||
// PWMB: low = [0->599], low = [600->1]
|
// PWMB: low = [0->599], low = [600->1]
|
||||||
mcpwm_gen_action_test_template(1000000, 1200, MCPWM_TIMER_COUNT_MODE_UP_DOWN, 250, 450, TEST_PWMA_GPIO, TEST_PWMB_GPIO, dual_edge_active_low_asym);
|
mcpwm_gen_action_test_template(1000000, 1200, MCPWM_TIMER_COUNT_MODE_UP_DOWN, 250, 450, TEST_PWMA_GPIO, TEST_PWMB_GPIO, dual_edge_active_low_asym, &capa, &capb);
|
||||||
|
TEST_ASSERT_UINT_WITHIN(2, 500, capa);
|
||||||
|
TEST_ASSERT_UINT_WITHIN(2, 600, capb);
|
||||||
|
|
||||||
printf("[Symmetric, DualEdge, ActiveLow]\r\n");
|
printf("[Symmetric, DualEdge, ActiveLow]\r\n");
|
||||||
// PWMA: low = [0->400], high = [401->599, 600->400], low = [399->1]
|
// PWMA: low = [0->400], high = [401->599, 600->400], low = [399->1]
|
||||||
// PWMB: low = [0->500], high = [501->599, 600->500], low = [499->1]
|
// PWMB: low = [0->500], high = [501->599, 600->500], low = [499->1]
|
||||||
mcpwm_gen_action_test_template(1000000, 1200, MCPWM_TIMER_COUNT_MODE_UP_DOWN, 400, 500, TEST_PWMA_GPIO, TEST_PWMB_GPIO, dual_edge_active_low_sym);
|
mcpwm_gen_action_test_template(1000000, 1200, MCPWM_TIMER_COUNT_MODE_UP_DOWN, 400, 500, TEST_PWMA_GPIO, TEST_PWMB_GPIO, dual_edge_active_low_sym, &capa, &capb);
|
||||||
|
TEST_ASSERT_UINT_WITHIN(2, 400, capa);
|
||||||
|
TEST_ASSERT_UINT_WITHIN(2, 200, capb);
|
||||||
|
|
||||||
printf("[Symmetric, DualEdge, Complementary]\r\n");
|
printf("[Symmetric, DualEdge, Complementary]\r\n");
|
||||||
// PWMA: low = [0->350], high = [351->599, 600->350], low = [349->1]
|
// PWMA: low = [0->350], high = [351->599, 600->350], low = [349->1]
|
||||||
// PWMB: low = [0->400], high = [401->599, 600->400], low = [399->1]
|
// PWMB: low = [0->400], high = [401->599, 600->400], low = [399->1]
|
||||||
mcpwm_gen_action_test_template(1000000, 1200, MCPWM_TIMER_COUNT_MODE_UP_DOWN, 350, 400, TEST_PWMA_GPIO, TEST_PWMB_GPIO, dual_edge_complementary);
|
mcpwm_gen_action_test_template(1000000, 1200, MCPWM_TIMER_COUNT_MODE_UP_DOWN, 350, 400, TEST_PWMA_GPIO, TEST_PWMB_GPIO, dual_edge_complementary, &capa, &capb);
|
||||||
|
TEST_ASSERT_UINT_WITHIN(2, 500, capa);
|
||||||
|
TEST_ASSERT_UINT_WITHIN(2, 400, capb);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef void (*set_dead_time_cb_t)(mcpwm_gen_handle_t gena, mcpwm_gen_handle_t genb);
|
typedef void (*set_dead_time_cb_t)(mcpwm_gen_handle_t gena, mcpwm_gen_handle_t genb);
|
||||||
|
|
||||||
static void mcpwm_deadtime_test_template(uint32_t timer_resolution, uint32_t period, uint32_t cmpa, uint32_t cmpb, int gpioa, int gpiob,
|
static void mcpwm_deadtime_test_template(uint32_t timer_resolution, uint32_t period, uint32_t cmpa, uint32_t cmpb, int gpioa, int gpiob,
|
||||||
set_gen_actions_cb_t set_generator_actions, set_dead_time_cb_t set_dead_time)
|
set_gen_actions_cb_t set_generator_actions, set_dead_time_cb_t set_dead_time,
|
||||||
|
uint32_t ret_capa[2], uint32_t ret_capb[2])
|
||||||
{
|
{
|
||||||
mcpwm_timer_config_t timer_config = {
|
mcpwm_timer_config_t timer_config = {
|
||||||
.group_id = 0,
|
.group_id = 0,
|
||||||
@ -469,10 +595,61 @@ static void mcpwm_deadtime_test_template(uint32_t timer_resolution, uint32_t per
|
|||||||
set_generator_actions(generator_a, generator_b, comparator_a, comparator_b);
|
set_generator_actions(generator_a, generator_b, comparator_a, comparator_b);
|
||||||
set_dead_time(generator_a, generator_b);
|
set_dead_time(generator_a, generator_b);
|
||||||
|
|
||||||
|
// install mcpwm capture timer
|
||||||
|
mcpwm_cap_timer_handle_t cap_timer = NULL;
|
||||||
|
uint32_t clk_src_freq_hz;
|
||||||
|
esp_clk_tree_src_get_freq_hz(MCPWM_CAPTURE_CLK_SRC_DEFAULT, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clk_src_freq_hz);
|
||||||
|
mcpwm_capture_timer_config_t cap_timer_config = {
|
||||||
|
.clk_src = MCPWM_CAPTURE_CLK_SRC_DEFAULT,
|
||||||
|
.group_id = 0,
|
||||||
|
.resolution_hz = clk_src_freq_hz / 2,
|
||||||
|
};
|
||||||
|
TEST_ESP_OK(mcpwm_new_capture_timer(&cap_timer_config, &cap_timer));
|
||||||
|
|
||||||
|
// install mcpwm capture channel
|
||||||
|
mcpwm_cap_channel_handle_t cap_channel_a;
|
||||||
|
mcpwm_cap_channel_handle_t cap_channel_b;
|
||||||
|
mcpwm_capture_channel_config_t cap_chan_config = {
|
||||||
|
.gpio_num = gpioa,
|
||||||
|
.prescale = 1,
|
||||||
|
.flags.pos_edge = true,
|
||||||
|
.flags.neg_edge = true,
|
||||||
|
};
|
||||||
|
TEST_ESP_OK(mcpwm_new_capture_channel(cap_timer, &cap_chan_config, &cap_channel_a));
|
||||||
|
cap_chan_config.gpio_num = gpiob;
|
||||||
|
TEST_ESP_OK(mcpwm_new_capture_channel(cap_timer, &cap_chan_config, &cap_channel_b));
|
||||||
|
|
||||||
|
// install callback for capture channel
|
||||||
|
mcpwm_capture_event_callbacks_t cbs = {
|
||||||
|
.on_cap = test_capture_callback,
|
||||||
|
};
|
||||||
|
uint32_t cap_value_a[2] = {0};
|
||||||
|
uint32_t cap_value_b[2] = {0};
|
||||||
|
TEST_ESP_OK(mcpwm_capture_channel_register_event_callbacks(cap_channel_a, &cbs, cap_value_a));
|
||||||
|
TEST_ESP_OK(mcpwm_capture_channel_register_event_callbacks(cap_channel_b, &cbs, cap_value_b));
|
||||||
|
|
||||||
|
// enable capture channel and timer
|
||||||
|
TEST_ESP_OK(mcpwm_capture_channel_enable(cap_channel_a));
|
||||||
|
TEST_ESP_OK(mcpwm_capture_channel_enable(cap_channel_b));
|
||||||
|
TEST_ESP_OK(mcpwm_capture_timer_enable(cap_timer));
|
||||||
|
|
||||||
|
// start timer and capture timer
|
||||||
TEST_ESP_OK(mcpwm_timer_start_stop(timer, MCPWM_TIMER_START_NO_STOP));
|
TEST_ESP_OK(mcpwm_timer_start_stop(timer, MCPWM_TIMER_START_NO_STOP));
|
||||||
|
TEST_ESP_OK(mcpwm_capture_timer_start(cap_timer));
|
||||||
vTaskDelay(pdMS_TO_TICKS(100));
|
vTaskDelay(pdMS_TO_TICKS(100));
|
||||||
TEST_ESP_OK(mcpwm_timer_start_stop(timer, MCPWM_TIMER_STOP_EMPTY));
|
TEST_ESP_OK(mcpwm_timer_start_stop(timer, MCPWM_TIMER_STOP_FULL));
|
||||||
vTaskDelay(pdMS_TO_TICKS(10));
|
vTaskDelay(pdMS_TO_TICKS(10));
|
||||||
|
TEST_ESP_OK(mcpwm_capture_timer_stop(cap_timer));
|
||||||
|
|
||||||
|
// calculate the actual capture time
|
||||||
|
uint32_t clk_src_res;
|
||||||
|
TEST_ESP_OK(mcpwm_capture_timer_get_resolution(cap_timer, &clk_src_res));
|
||||||
|
clk_src_res /= 1000; // convert to kHz
|
||||||
|
|
||||||
|
ret_capa[0] = cap_value_a[0] * 1000 / clk_src_res;
|
||||||
|
ret_capa[1] = cap_value_a[1] * 1000 / clk_src_res;
|
||||||
|
ret_capb[0] = cap_value_b[0] * 1000 / clk_src_res;
|
||||||
|
ret_capb[1] = cap_value_b[1] * 1000 / clk_src_res;
|
||||||
|
|
||||||
TEST_ESP_OK(mcpwm_timer_disable(timer));
|
TEST_ESP_OK(mcpwm_timer_disable(timer));
|
||||||
TEST_ESP_OK(mcpwm_del_generator(generator_a));
|
TEST_ESP_OK(mcpwm_del_generator(generator_a));
|
||||||
@ -481,6 +658,12 @@ static void mcpwm_deadtime_test_template(uint32_t timer_resolution, uint32_t per
|
|||||||
TEST_ESP_OK(mcpwm_del_comparator(comparator_b));
|
TEST_ESP_OK(mcpwm_del_comparator(comparator_b));
|
||||||
TEST_ESP_OK(mcpwm_del_operator(oper));
|
TEST_ESP_OK(mcpwm_del_operator(oper));
|
||||||
TEST_ESP_OK(mcpwm_del_timer(timer));
|
TEST_ESP_OK(mcpwm_del_timer(timer));
|
||||||
|
TEST_ESP_OK(mcpwm_capture_channel_disable(cap_channel_a));
|
||||||
|
TEST_ESP_OK(mcpwm_del_capture_channel(cap_channel_a));
|
||||||
|
TEST_ESP_OK(mcpwm_capture_channel_disable(cap_channel_b));
|
||||||
|
TEST_ESP_OK(mcpwm_del_capture_channel(cap_channel_b));
|
||||||
|
TEST_ESP_OK(mcpwm_capture_timer_disable(cap_timer));
|
||||||
|
TEST_ESP_OK(mcpwm_del_capture_timer(cap_timer));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ahc_set_generator_actions(mcpwm_gen_handle_t gena, mcpwm_gen_handle_t genb, mcpwm_cmpr_handle_t cmpa, mcpwm_cmpr_handle_t cmpb)
|
static void ahc_set_generator_actions(mcpwm_gen_handle_t gena, mcpwm_gen_handle_t genb, mcpwm_cmpr_handle_t cmpa, mcpwm_cmpr_handle_t cmpb)
|
||||||
@ -663,34 +846,58 @@ static void invalid_reda_redb_set_dead_time(mcpwm_gen_handle_t gena, mcpwm_gen_h
|
|||||||
|
|
||||||
TEST_CASE("mcpwm_generator_deadtime_classical_configuration", "[mcpwm]")
|
TEST_CASE("mcpwm_generator_deadtime_classical_configuration", "[mcpwm]")
|
||||||
{
|
{
|
||||||
|
uint32_t capa[2], capb[2];
|
||||||
printf("Active High Complementary\r\n");
|
printf("Active High Complementary\r\n");
|
||||||
mcpwm_deadtime_test_template(1000000, 600, 200, 400, TEST_PWMA_GPIO, TEST_PWMB_GPIO, ahc_set_generator_actions, ahc_set_dead_time);
|
mcpwm_deadtime_test_template(1000000, 600, 200, 400, TEST_PWMA_GPIO, TEST_PWMB_GPIO, ahc_set_generator_actions, ahc_set_dead_time, capa, capb);
|
||||||
|
TEST_ASSERT_UINT_WITHIN(2, 50, capa[0] - capb[1]);
|
||||||
|
TEST_ASSERT_UINT_WITHIN(2, 100, capb[0] - capa[1]);
|
||||||
|
|
||||||
printf("Active Low Complementary\r\n");
|
printf("Active Low Complementary\r\n");
|
||||||
mcpwm_deadtime_test_template(1000000, 600, 200, 400, TEST_PWMA_GPIO, TEST_PWMB_GPIO, alc_set_generator_actions, alc_set_dead_time);
|
mcpwm_deadtime_test_template(1000000, 600, 200, 400, TEST_PWMA_GPIO, TEST_PWMB_GPIO, alc_set_generator_actions, alc_set_dead_time, capa, capb);
|
||||||
|
TEST_ASSERT_UINT_WITHIN(2, 50, capa[1] - capb[0]);
|
||||||
|
TEST_ASSERT_UINT_WITHIN(2, 100, capb[1] - capa[0]);
|
||||||
|
|
||||||
printf("Active High\r\n");
|
printf("Active High\r\n");
|
||||||
mcpwm_deadtime_test_template(1000000, 600, 200, 400, TEST_PWMA_GPIO, TEST_PWMB_GPIO, ah_set_generator_actions, ah_set_dead_time);
|
mcpwm_deadtime_test_template(1000000, 600, 200, 400, TEST_PWMA_GPIO, TEST_PWMB_GPIO, ah_set_generator_actions, ah_set_dead_time, capa, capb);
|
||||||
|
TEST_ASSERT_UINT_WITHIN(2, 50, capa[0] - capb[0]);
|
||||||
|
TEST_ASSERT_UINT_WITHIN(2, 100, capb[1] - capa[1]);
|
||||||
|
|
||||||
printf("Active Low\r\n");
|
printf("Active Low\r\n");
|
||||||
mcpwm_deadtime_test_template(1000000, 600, 200, 400, TEST_PWMA_GPIO, TEST_PWMB_GPIO, al_set_generator_actions, al_set_dead_time);
|
mcpwm_deadtime_test_template(1000000, 600, 200, 400, TEST_PWMA_GPIO, TEST_PWMB_GPIO, al_set_generator_actions, al_set_dead_time, capa, capb);
|
||||||
|
TEST_ASSERT_UINT_WITHIN(2, 50, capa[1] - capb[1]);
|
||||||
|
TEST_ASSERT_UINT_WITHIN(2, 100, capb[0] - capa[0]);
|
||||||
|
|
||||||
printf("RED on A, Bypass B\r\n");
|
printf("RED on A, Bypass B\r\n");
|
||||||
mcpwm_deadtime_test_template(1000000, 500, 350, 350, TEST_PWMA_GPIO, TEST_PWMB_GPIO, reda_only_set_generator_actions, reda_only_set_dead_time);
|
mcpwm_deadtime_test_template(1000000, 500, 350, 350, TEST_PWMA_GPIO, TEST_PWMB_GPIO, reda_only_set_generator_actions, reda_only_set_dead_time, capa, capb);
|
||||||
|
TEST_ASSERT_UINT_WITHIN(2, 50, capa[0] - capb[0]);
|
||||||
|
TEST_ASSERT_UINT_WITHIN(2, 0, capb[1] - capa[1]);
|
||||||
|
|
||||||
printf("Bypass A, FED on B\r\n");
|
printf("Bypass A, FED on B\r\n");
|
||||||
mcpwm_deadtime_test_template(1000000, 500, 350, 350, TEST_PWMA_GPIO, TEST_PWMB_GPIO, fedb_only_set_generator_actions, fedb_only_set_dead_time);
|
mcpwm_deadtime_test_template(1000000, 500, 350, 350, TEST_PWMA_GPIO, TEST_PWMB_GPIO, fedb_only_set_generator_actions, fedb_only_set_dead_time, capa, capb);
|
||||||
|
TEST_ASSERT_UINT_WITHIN(2, 50, capb[1] - capa[1]);
|
||||||
|
TEST_ASSERT_UINT_WITHIN(2, 0, capb[0] - capa[0]);
|
||||||
|
|
||||||
printf("Bypass A, RED + FED on B\r\n");
|
printf("Bypass A, RED + FED on B\r\n");
|
||||||
mcpwm_deadtime_test_template(1000000, 500, 350, 350, TEST_PWMA_GPIO, TEST_PWMB_GPIO, redfedb_only_set_generator_actions, redfedb_only_set_dead_time);
|
mcpwm_deadtime_test_template(1000000, 500, 350, 350, TEST_PWMA_GPIO, TEST_PWMB_GPIO, redfedb_only_set_generator_actions, redfedb_only_set_dead_time, capa, capb);
|
||||||
|
TEST_ASSERT_UINT_WITHIN(2, 50, capb[0] - capa[0]);
|
||||||
|
TEST_ASSERT_UINT_WITHIN(2, 50, capb[1] - capa[1]);
|
||||||
|
|
||||||
printf("Can't apply one delay module to multiple generators\r\n");
|
printf("Can't apply one delay module to multiple generators\r\n");
|
||||||
mcpwm_deadtime_test_template(1000000, 500, 350, 350, TEST_PWMA_GPIO, TEST_PWMB_GPIO, redfedb_only_set_generator_actions, invalid_reda_redb_set_dead_time);
|
mcpwm_deadtime_test_template(1000000, 500, 350, 350, TEST_PWMA_GPIO, TEST_PWMB_GPIO, redfedb_only_set_generator_actions, invalid_reda_redb_set_dead_time, capa, capb);
|
||||||
|
TEST_ASSERT_UINT_WITHIN(2, 0, capa[0] - capb[0]);
|
||||||
|
TEST_ASSERT_UINT_WITHIN(2, 0, capa[1] - capb[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("mcpwm_duty_empty_full", "[mcpwm]")
|
TEST_CASE("mcpwm_duty_empty_full", "[mcpwm]")
|
||||||
{
|
{
|
||||||
const int gen_gpio_num = TEST_PWMA_GPIO;
|
const int gen_gpio_num = TEST_PWMA_GPIO;
|
||||||
|
printf("init a gpio to read generator output\r\n");
|
||||||
|
gpio_config_t gen_gpio_conf = {
|
||||||
|
.mode = GPIO_MODE_INPUT,
|
||||||
|
.pin_bit_mask = BIT(gen_gpio_num),
|
||||||
|
};
|
||||||
|
TEST_ESP_OK(gpio_config(&gen_gpio_conf));
|
||||||
|
|
||||||
mcpwm_timer_handle_t timer;
|
mcpwm_timer_handle_t timer;
|
||||||
mcpwm_oper_handle_t oper;
|
mcpwm_oper_handle_t oper;
|
||||||
mcpwm_cmpr_handle_t comparator;
|
mcpwm_cmpr_handle_t comparator;
|
||||||
@ -722,7 +929,6 @@ TEST_CASE("mcpwm_duty_empty_full", "[mcpwm]")
|
|||||||
printf("install MCPWM generator\r\n");
|
printf("install MCPWM generator\r\n");
|
||||||
mcpwm_generator_config_t gen_config = {
|
mcpwm_generator_config_t gen_config = {
|
||||||
.gen_gpio_num = gen_gpio_num,
|
.gen_gpio_num = gen_gpio_num,
|
||||||
.flags.io_loop_back = true, // we want to read the output level as well
|
|
||||||
};
|
};
|
||||||
TEST_ESP_OK(mcpwm_new_generator(oper, &gen_config, &gen));
|
TEST_ESP_OK(mcpwm_new_generator(oper, &gen_config, &gen));
|
||||||
|
|
||||||
@ -763,12 +969,30 @@ TEST_CASE("mcpwm_duty_empty_full", "[mcpwm]")
|
|||||||
TEST_ESP_OK(mcpwm_del_comparator(comparator));
|
TEST_ESP_OK(mcpwm_del_comparator(comparator));
|
||||||
TEST_ESP_OK(mcpwm_del_operator(oper));
|
TEST_ESP_OK(mcpwm_del_operator(oper));
|
||||||
TEST_ESP_OK(mcpwm_del_timer(timer));
|
TEST_ESP_OK(mcpwm_del_timer(timer));
|
||||||
|
TEST_ESP_OK(gpio_reset_pin(gen_gpio_num));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("mcpwm_generator_action_on_fault_trigger_event", "[mcpwm]")
|
TEST_CASE("mcpwm_generator_action_on_fault_trigger_event", "[mcpwm]")
|
||||||
{
|
{
|
||||||
const int generator_gpio = TEST_PWMA_GPIO;
|
const int generator_gpio = TEST_PWMA_GPIO;
|
||||||
const int fault_gpio_num[3] = {TEST_FAULT_GPIO0, TEST_FAULT_GPIO1, TEST_FAULT_GPIO2};
|
const int fault_gpio_num[3] = {TEST_FAULT_GPIO0, TEST_FAULT_GPIO1, TEST_FAULT_GPIO2};
|
||||||
|
|
||||||
|
printf("init a gpio to read generator output and simulate fault signal\r\n");
|
||||||
|
gpio_config_t generator_gpio_conf = {
|
||||||
|
.mode = GPIO_MODE_INPUT,
|
||||||
|
.pin_bit_mask = BIT(generator_gpio),
|
||||||
|
};
|
||||||
|
TEST_ESP_OK(gpio_config(&generator_gpio_conf));
|
||||||
|
|
||||||
|
gpio_config_t fault_gpio_conf = {
|
||||||
|
.mode = GPIO_MODE_OUTPUT,
|
||||||
|
.pin_bit_mask = 0,
|
||||||
|
};
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
fault_gpio_conf.pin_bit_mask |= BIT(fault_gpio_num[i]);
|
||||||
|
}
|
||||||
|
TEST_ESP_OK(gpio_config(&fault_gpio_conf));
|
||||||
|
|
||||||
printf("create timer and operator\r\n");
|
printf("create timer and operator\r\n");
|
||||||
mcpwm_timer_config_t timer_config = {
|
mcpwm_timer_config_t timer_config = {
|
||||||
.group_id = 0,
|
.group_id = 0,
|
||||||
@ -796,7 +1020,6 @@ TEST_CASE("mcpwm_generator_action_on_fault_trigger_event", "[mcpwm]")
|
|||||||
.flags.active_level = 1,
|
.flags.active_level = 1,
|
||||||
.flags.pull_down = 1,
|
.flags.pull_down = 1,
|
||||||
.flags.pull_up = 0,
|
.flags.pull_up = 0,
|
||||||
.flags.io_loop_back = 1, // so that we can write the GPIO value by GPIO driver
|
|
||||||
};
|
};
|
||||||
for (int i = 0 ; i < 3; i++) {
|
for (int i = 0 ; i < 3; i++) {
|
||||||
gpio_trigger_config.gpio_num = fault_gpio_num[i];
|
gpio_trigger_config.gpio_num = fault_gpio_num[i];
|
||||||
@ -806,7 +1029,6 @@ TEST_CASE("mcpwm_generator_action_on_fault_trigger_event", "[mcpwm]")
|
|||||||
printf("create generator\r\n");
|
printf("create generator\r\n");
|
||||||
mcpwm_generator_config_t gen_config = {
|
mcpwm_generator_config_t gen_config = {
|
||||||
.gen_gpio_num = generator_gpio,
|
.gen_gpio_num = generator_gpio,
|
||||||
.flags.io_loop_back = 1, // so that we can read the GPIO value by GPIO driver
|
|
||||||
};
|
};
|
||||||
mcpwm_gen_handle_t gen = NULL;
|
mcpwm_gen_handle_t gen = NULL;
|
||||||
TEST_ESP_OK(mcpwm_new_generator(oper, &gen_config, &gen));
|
TEST_ESP_OK(mcpwm_new_generator(oper, &gen_config, &gen));
|
||||||
@ -839,11 +1061,22 @@ TEST_CASE("mcpwm_generator_action_on_fault_trigger_event", "[mcpwm]")
|
|||||||
TEST_ESP_OK(mcpwm_del_generator(gen));
|
TEST_ESP_OK(mcpwm_del_generator(gen));
|
||||||
TEST_ESP_OK(mcpwm_del_operator(oper));
|
TEST_ESP_OK(mcpwm_del_operator(oper));
|
||||||
TEST_ESP_OK(mcpwm_del_timer(timer));
|
TEST_ESP_OK(mcpwm_del_timer(timer));
|
||||||
|
TEST_ESP_OK(gpio_reset_pin(generator_gpio));
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
TEST_ESP_OK(gpio_reset_pin(fault_gpio_num[i]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("mcpwm_generator_action_on_soft_sync_trigger_event", "[mcpwm]")
|
TEST_CASE("mcpwm_generator_action_on_soft_sync_trigger_event", "[mcpwm]")
|
||||||
{
|
{
|
||||||
const int generator_gpio = TEST_PWMA_GPIO;
|
const int generator_gpio = TEST_PWMA_GPIO;
|
||||||
|
printf("init a gpio to read generator output\r\n");
|
||||||
|
gpio_config_t generator_gpio_conf = {
|
||||||
|
.mode = GPIO_MODE_INPUT,
|
||||||
|
.pin_bit_mask = BIT(generator_gpio),
|
||||||
|
};
|
||||||
|
TEST_ESP_OK(gpio_config(&generator_gpio_conf));
|
||||||
|
|
||||||
printf("create timer and operator\r\n");
|
printf("create timer and operator\r\n");
|
||||||
mcpwm_timer_config_t timer_config = {
|
mcpwm_timer_config_t timer_config = {
|
||||||
.group_id = 0,
|
.group_id = 0,
|
||||||
@ -879,7 +1112,6 @@ TEST_CASE("mcpwm_generator_action_on_soft_sync_trigger_event", "[mcpwm]")
|
|||||||
printf("create generator\r\n");
|
printf("create generator\r\n");
|
||||||
mcpwm_generator_config_t gen_config = {
|
mcpwm_generator_config_t gen_config = {
|
||||||
.gen_gpio_num = generator_gpio,
|
.gen_gpio_num = generator_gpio,
|
||||||
.flags.io_loop_back = 1, // so that we can read the GPIO value by GPIO driver
|
|
||||||
};
|
};
|
||||||
mcpwm_gen_handle_t gen = NULL;
|
mcpwm_gen_handle_t gen = NULL;
|
||||||
TEST_ESP_OK(mcpwm_new_generator(oper, &gen_config, &gen));
|
TEST_ESP_OK(mcpwm_new_generator(oper, &gen_config, &gen));
|
||||||
@ -905,11 +1137,19 @@ TEST_CASE("mcpwm_generator_action_on_soft_sync_trigger_event", "[mcpwm]")
|
|||||||
TEST_ESP_OK(mcpwm_del_generator(gen));
|
TEST_ESP_OK(mcpwm_del_generator(gen));
|
||||||
TEST_ESP_OK(mcpwm_del_operator(oper));
|
TEST_ESP_OK(mcpwm_del_operator(oper));
|
||||||
TEST_ESP_OK(mcpwm_del_timer(timer));
|
TEST_ESP_OK(mcpwm_del_timer(timer));
|
||||||
|
TEST_ESP_OK(gpio_reset_pin(generator_gpio));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("mcpwm_generator_action_on_timer_sync_trigger_event", "[mcpwm]")
|
TEST_CASE("mcpwm_generator_action_on_timer_sync_trigger_event", "[mcpwm]")
|
||||||
{
|
{
|
||||||
const int generator_gpio = TEST_PWMA_GPIO;
|
const int generator_gpio = TEST_PWMA_GPIO;
|
||||||
|
printf("init a gpio to read generator output\r\n");
|
||||||
|
gpio_config_t generator_gpio_conf = {
|
||||||
|
.mode = GPIO_MODE_INPUT,
|
||||||
|
.pin_bit_mask = BIT(generator_gpio),
|
||||||
|
};
|
||||||
|
TEST_ESP_OK(gpio_config(&generator_gpio_conf));
|
||||||
|
|
||||||
printf("create timer and operator\r\n");
|
printf("create timer and operator\r\n");
|
||||||
mcpwm_timer_config_t timer_config = {
|
mcpwm_timer_config_t timer_config = {
|
||||||
.group_id = 0,
|
.group_id = 0,
|
||||||
@ -948,7 +1188,6 @@ TEST_CASE("mcpwm_generator_action_on_timer_sync_trigger_event", "[mcpwm]")
|
|||||||
printf("create generator\r\n");
|
printf("create generator\r\n");
|
||||||
mcpwm_generator_config_t gen_config = {
|
mcpwm_generator_config_t gen_config = {
|
||||||
.gen_gpio_num = generator_gpio,
|
.gen_gpio_num = generator_gpio,
|
||||||
.flags.io_loop_back = 1, // so that we can read the GPIO value by GPIO driver
|
|
||||||
};
|
};
|
||||||
mcpwm_gen_handle_t gen = NULL;
|
mcpwm_gen_handle_t gen = NULL;
|
||||||
TEST_ESP_OK(mcpwm_new_generator(oper, &gen_config, &gen));
|
TEST_ESP_OK(mcpwm_new_generator(oper, &gen_config, &gen));
|
||||||
@ -970,11 +1209,25 @@ TEST_CASE("mcpwm_generator_action_on_timer_sync_trigger_event", "[mcpwm]")
|
|||||||
TEST_ESP_OK(mcpwm_del_generator(gen));
|
TEST_ESP_OK(mcpwm_del_generator(gen));
|
||||||
TEST_ESP_OK(mcpwm_del_operator(oper));
|
TEST_ESP_OK(mcpwm_del_operator(oper));
|
||||||
TEST_ESP_OK(mcpwm_del_timer(timer));
|
TEST_ESP_OK(mcpwm_del_timer(timer));
|
||||||
|
TEST_ESP_OK(gpio_reset_pin(generator_gpio));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("mcpwm_generator_action_on_gpio_sync_trigger_event", "[mcpwm]")
|
TEST_CASE("mcpwm_generator_action_on_gpio_sync_trigger_event", "[mcpwm]")
|
||||||
{
|
{
|
||||||
const int generator_gpio = TEST_PWMA_GPIO;
|
const int generator_gpio = TEST_PWMA_GPIO;
|
||||||
|
const int sync_gpio = TEST_SYNC_GPIO;
|
||||||
|
printf("init a gpio to read generator output and simulate sync signal\r\n");
|
||||||
|
gpio_config_t generator_gpio_conf = {
|
||||||
|
.mode = GPIO_MODE_INPUT,
|
||||||
|
.pin_bit_mask = BIT(generator_gpio),
|
||||||
|
};
|
||||||
|
TEST_ESP_OK(gpio_config(&generator_gpio_conf));
|
||||||
|
gpio_config_t sync_gpio_conf = {
|
||||||
|
.mode = GPIO_MODE_OUTPUT,
|
||||||
|
.pin_bit_mask = BIT(sync_gpio),
|
||||||
|
};
|
||||||
|
TEST_ESP_OK(gpio_config(&sync_gpio_conf));
|
||||||
|
|
||||||
printf("create timer and operator\r\n");
|
printf("create timer and operator\r\n");
|
||||||
mcpwm_timer_config_t timer_config = {
|
mcpwm_timer_config_t timer_config = {
|
||||||
.group_id = 0,
|
.group_id = 0,
|
||||||
@ -999,14 +1252,13 @@ TEST_CASE("mcpwm_generator_action_on_gpio_sync_trigger_event", "[mcpwm]")
|
|||||||
mcpwm_sync_handle_t gpio_sync = NULL;
|
mcpwm_sync_handle_t gpio_sync = NULL;
|
||||||
mcpwm_gpio_sync_src_config_t gpio_sync_config = {
|
mcpwm_gpio_sync_src_config_t gpio_sync_config = {
|
||||||
.group_id = 0,
|
.group_id = 0,
|
||||||
.gpio_num = TEST_SYNC_GPIO,
|
.gpio_num = sync_gpio,
|
||||||
.flags.io_loop_back = true, // so that we can use gpio driver to simulate the sync signal
|
|
||||||
.flags.pull_down = true, // internally pull down
|
.flags.pull_down = true, // internally pull down
|
||||||
};
|
};
|
||||||
TEST_ESP_OK(mcpwm_new_gpio_sync_src(&gpio_sync_config, &gpio_sync));
|
TEST_ESP_OK(mcpwm_new_gpio_sync_src(&gpio_sync_config, &gpio_sync));
|
||||||
|
|
||||||
// put the GPIO into initial state
|
// put the GPIO into initial state
|
||||||
gpio_set_level(gpio_sync_config.gpio_num, 0);
|
gpio_set_level(sync_gpio, 0);
|
||||||
|
|
||||||
mcpwm_timer_sync_phase_config_t sync_phase_config = {
|
mcpwm_timer_sync_phase_config_t sync_phase_config = {
|
||||||
.count_value = 0,
|
.count_value = 0,
|
||||||
@ -1018,7 +1270,6 @@ TEST_CASE("mcpwm_generator_action_on_gpio_sync_trigger_event", "[mcpwm]")
|
|||||||
printf("create generator\r\n");
|
printf("create generator\r\n");
|
||||||
mcpwm_generator_config_t gen_config = {
|
mcpwm_generator_config_t gen_config = {
|
||||||
.gen_gpio_num = generator_gpio,
|
.gen_gpio_num = generator_gpio,
|
||||||
.flags.io_loop_back = 1, // so that we can read the GPIO value by GPIO driver
|
|
||||||
};
|
};
|
||||||
mcpwm_gen_handle_t gen = NULL;
|
mcpwm_gen_handle_t gen = NULL;
|
||||||
TEST_ESP_OK(mcpwm_new_generator(oper, &gen_config, &gen));
|
TEST_ESP_OK(mcpwm_new_generator(oper, &gen_config, &gen));
|
||||||
@ -1028,8 +1279,8 @@ TEST_CASE("mcpwm_generator_action_on_gpio_sync_trigger_event", "[mcpwm]")
|
|||||||
MCPWM_GEN_SYNC_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, gpio_sync, MCPWM_GEN_ACTION_HIGH)));
|
MCPWM_GEN_SYNC_EVENT_ACTION(MCPWM_TIMER_DIRECTION_UP, gpio_sync, MCPWM_GEN_ACTION_HIGH)));
|
||||||
|
|
||||||
TEST_ASSERT_EQUAL(0, gpio_get_level(generator_gpio));
|
TEST_ASSERT_EQUAL(0, gpio_get_level(generator_gpio));
|
||||||
gpio_set_level(gpio_sync_config.gpio_num, 1);
|
gpio_set_level(sync_gpio, 1);
|
||||||
gpio_set_level(gpio_sync_config.gpio_num, 0);
|
gpio_set_level(sync_gpio, 0);
|
||||||
TEST_ASSERT_EQUAL(1, gpio_get_level(generator_gpio));
|
TEST_ASSERT_EQUAL(1, gpio_get_level(generator_gpio));
|
||||||
vTaskDelay(pdMS_TO_TICKS(10));
|
vTaskDelay(pdMS_TO_TICKS(10));
|
||||||
|
|
||||||
@ -1038,4 +1289,6 @@ TEST_CASE("mcpwm_generator_action_on_gpio_sync_trigger_event", "[mcpwm]")
|
|||||||
TEST_ESP_OK(mcpwm_del_generator(gen));
|
TEST_ESP_OK(mcpwm_del_generator(gen));
|
||||||
TEST_ESP_OK(mcpwm_del_operator(oper));
|
TEST_ESP_OK(mcpwm_del_operator(oper));
|
||||||
TEST_ESP_OK(mcpwm_del_timer(timer));
|
TEST_ESP_OK(mcpwm_del_timer(timer));
|
||||||
|
TEST_ESP_OK(gpio_reset_pin(generator_gpio));
|
||||||
|
TEST_ESP_OK(gpio_reset_pin(sync_gpio));
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@ -46,6 +46,13 @@ TEST_CASE("mcpwm_capture_iram_safe", "[mcpwm]")
|
|||||||
TEST_ESP_OK(mcpwm_new_capture_timer(&cap_timer_config, &cap_timer));
|
TEST_ESP_OK(mcpwm_new_capture_timer(&cap_timer_config, &cap_timer));
|
||||||
|
|
||||||
const int cap_gpio = TEST_CAP_GPIO;
|
const int cap_gpio = TEST_CAP_GPIO;
|
||||||
|
printf("init a gpio to simulate the external capture signal\r\n");
|
||||||
|
gpio_config_t cap_gpio_conf = {
|
||||||
|
.mode = GPIO_MODE_OUTPUT,
|
||||||
|
.pin_bit_mask = BIT(cap_gpio),
|
||||||
|
};
|
||||||
|
TEST_ESP_OK(gpio_config(&cap_gpio_conf));
|
||||||
|
|
||||||
// put the GPIO into a preset state
|
// put the GPIO into a preset state
|
||||||
gpio_set_level(cap_gpio, 0);
|
gpio_set_level(cap_gpio, 0);
|
||||||
|
|
||||||
@ -56,7 +63,6 @@ TEST_CASE("mcpwm_capture_iram_safe", "[mcpwm]")
|
|||||||
.prescale = 1,
|
.prescale = 1,
|
||||||
.flags.pos_edge = true,
|
.flags.pos_edge = true,
|
||||||
.flags.neg_edge = true,
|
.flags.neg_edge = true,
|
||||||
.flags.io_loop_back = true, // so we can use GPIO functions to simulate the external capture signal
|
|
||||||
.flags.pull_up = true,
|
.flags.pull_up = true,
|
||||||
};
|
};
|
||||||
TEST_ESP_OK(mcpwm_new_capture_channel(cap_timer, &cap_chan_config, &pps_channel));
|
TEST_ESP_OK(mcpwm_new_capture_channel(cap_timer, &cap_chan_config, &pps_channel));
|
||||||
@ -89,6 +95,7 @@ TEST_CASE("mcpwm_capture_iram_safe", "[mcpwm]")
|
|||||||
TEST_ESP_OK(mcpwm_del_capture_channel(pps_channel));
|
TEST_ESP_OK(mcpwm_del_capture_channel(pps_channel));
|
||||||
TEST_ESP_OK(mcpwm_capture_timer_disable(cap_timer));
|
TEST_ESP_OK(mcpwm_capture_timer_disable(cap_timer));
|
||||||
TEST_ESP_OK(mcpwm_del_capture_timer(cap_timer));
|
TEST_ESP_OK(mcpwm_del_capture_timer(cap_timer));
|
||||||
|
TEST_ESP_OK(gpio_reset_pin(cap_gpio));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool IRAM_ATTR test_compare_on_reach(mcpwm_cmpr_handle_t cmpr, const mcpwm_compare_event_data_t *ev_data, void *user_data)
|
static bool IRAM_ATTR test_compare_on_reach(mcpwm_cmpr_handle_t cmpr, const mcpwm_compare_event_data_t *ev_data, void *user_data)
|
||||||
|
@ -121,6 +121,22 @@ static bool IRAM_ATTR test_ost_brake_on_gpio_fault_callback(mcpwm_oper_handle_t
|
|||||||
|
|
||||||
TEST_CASE("mcpwm_operator_brake_on_gpio_fault", "[mcpwm]")
|
TEST_CASE("mcpwm_operator_brake_on_gpio_fault", "[mcpwm]")
|
||||||
{
|
{
|
||||||
|
const int cbc_fault_gpio = TEST_FAULT_GPIO1;
|
||||||
|
const int ost_fault_gpio = TEST_FAULT_GPIO2;
|
||||||
|
const int gen_a_gpio = TEST_PWMA_GPIO;
|
||||||
|
const int gen_b_gpio = TEST_PWMB_GPIO;
|
||||||
|
printf("init gpios to read generator output and simulate fault signal\r\n");
|
||||||
|
gpio_config_t fault_gpio_conf = {
|
||||||
|
.mode = GPIO_MODE_OUTPUT,
|
||||||
|
.pin_bit_mask = BIT(cbc_fault_gpio) | BIT(ost_fault_gpio),
|
||||||
|
};
|
||||||
|
TEST_ESP_OK(gpio_config(&fault_gpio_conf));
|
||||||
|
gpio_config_t gen_gpio_conf = {
|
||||||
|
.mode = GPIO_MODE_INPUT,
|
||||||
|
.pin_bit_mask = BIT(gen_a_gpio) | BIT(gen_b_gpio),
|
||||||
|
};
|
||||||
|
TEST_ESP_OK(gpio_config(&gen_gpio_conf));
|
||||||
|
|
||||||
printf("install timer\r\n");
|
printf("install timer\r\n");
|
||||||
mcpwm_timer_config_t timer_config = {
|
mcpwm_timer_config_t timer_config = {
|
||||||
.clk_src = MCPWM_TIMER_CLK_SRC_DEFAULT,
|
.clk_src = MCPWM_TIMER_CLK_SRC_DEFAULT,
|
||||||
@ -151,13 +167,10 @@ TEST_CASE("mcpwm_operator_brake_on_gpio_fault", "[mcpwm]")
|
|||||||
mcpwm_gpio_fault_config_t gpio_fault_config = {
|
mcpwm_gpio_fault_config_t gpio_fault_config = {
|
||||||
.group_id = 0,
|
.group_id = 0,
|
||||||
.flags.active_level = 1,
|
.flags.active_level = 1,
|
||||||
.flags.io_loop_back = true,
|
|
||||||
.flags.pull_down = true,
|
.flags.pull_down = true,
|
||||||
};
|
};
|
||||||
mcpwm_fault_handle_t gpio_cbc_fault = NULL;
|
mcpwm_fault_handle_t gpio_cbc_fault = NULL;
|
||||||
mcpwm_fault_handle_t gpio_ost_fault = NULL;
|
mcpwm_fault_handle_t gpio_ost_fault = NULL;
|
||||||
const int cbc_fault_gpio = TEST_FAULT_GPIO1;
|
|
||||||
const int ost_fault_gpio = TEST_FAULT_GPIO2;
|
|
||||||
|
|
||||||
gpio_fault_config.gpio_num = cbc_fault_gpio;
|
gpio_fault_config.gpio_num = cbc_fault_gpio;
|
||||||
TEST_ESP_OK(mcpwm_new_gpio_fault(&gpio_fault_config, &gpio_cbc_fault));
|
TEST_ESP_OK(mcpwm_new_gpio_fault(&gpio_fault_config, &gpio_cbc_fault));
|
||||||
@ -180,14 +193,12 @@ TEST_CASE("mcpwm_operator_brake_on_gpio_fault", "[mcpwm]")
|
|||||||
TEST_ESP_OK(mcpwm_operator_set_brake_on_fault(oper, &brake_config));
|
TEST_ESP_OK(mcpwm_operator_set_brake_on_fault(oper, &brake_config));
|
||||||
|
|
||||||
printf("create generators\r\n");
|
printf("create generators\r\n");
|
||||||
const int gen_a_gpio = TEST_PWMA_GPIO;
|
|
||||||
const int gen_b_gpio = TEST_PWMB_GPIO;
|
|
||||||
mcpwm_gen_handle_t gen_a = NULL;
|
mcpwm_gen_handle_t gen_a = NULL;
|
||||||
mcpwm_gen_handle_t gen_b = NULL;
|
mcpwm_gen_handle_t gen_b = NULL;
|
||||||
mcpwm_generator_config_t generator_config = {
|
mcpwm_generator_config_t generator_config = {
|
||||||
.flags.io_loop_back = true,
|
.gen_gpio_num = gen_a_gpio,
|
||||||
};
|
};
|
||||||
generator_config.gen_gpio_num = gen_a_gpio;
|
|
||||||
TEST_ESP_OK(mcpwm_new_generator(oper, &generator_config, &gen_a));
|
TEST_ESP_OK(mcpwm_new_generator(oper, &generator_config, &gen_a));
|
||||||
generator_config.gen_gpio_num = gen_b_gpio;
|
generator_config.gen_gpio_num = gen_b_gpio;
|
||||||
TEST_ESP_OK(mcpwm_new_generator(oper, &generator_config, &gen_b));
|
TEST_ESP_OK(mcpwm_new_generator(oper, &generator_config, &gen_b));
|
||||||
@ -249,10 +260,23 @@ TEST_CASE("mcpwm_operator_brake_on_gpio_fault", "[mcpwm]")
|
|||||||
TEST_ESP_OK(mcpwm_del_generator(gen_b));
|
TEST_ESP_OK(mcpwm_del_generator(gen_b));
|
||||||
TEST_ESP_OK(mcpwm_del_operator(oper));
|
TEST_ESP_OK(mcpwm_del_operator(oper));
|
||||||
TEST_ESP_OK(mcpwm_del_timer(timer));
|
TEST_ESP_OK(mcpwm_del_timer(timer));
|
||||||
|
TEST_ESP_OK(gpio_reset_pin(cbc_fault_gpio));
|
||||||
|
TEST_ESP_OK(gpio_reset_pin(ost_fault_gpio));
|
||||||
|
TEST_ESP_OK(gpio_reset_pin(gen_a_gpio));
|
||||||
|
TEST_ESP_OK(gpio_reset_pin(gen_b_gpio));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("mcpwm_operator_brake_on_soft_fault", "[mcpwm]")
|
TEST_CASE("mcpwm_operator_brake_on_soft_fault", "[mcpwm]")
|
||||||
{
|
{
|
||||||
|
const int gen_a_gpio = TEST_PWMA_GPIO;
|
||||||
|
const int gen_b_gpio = TEST_PWMB_GPIO;
|
||||||
|
printf("init gpios to read generator output\r\n");
|
||||||
|
gpio_config_t gen_gpio_conf = {
|
||||||
|
.mode = GPIO_MODE_INPUT,
|
||||||
|
.pin_bit_mask = BIT(gen_a_gpio) | BIT(gen_b_gpio),
|
||||||
|
};
|
||||||
|
TEST_ESP_OK(gpio_config(&gen_gpio_conf));
|
||||||
|
|
||||||
printf("install timer\r\n");
|
printf("install timer\r\n");
|
||||||
mcpwm_timer_config_t timer_config = {
|
mcpwm_timer_config_t timer_config = {
|
||||||
.clk_src = MCPWM_TIMER_CLK_SRC_DEFAULT,
|
.clk_src = MCPWM_TIMER_CLK_SRC_DEFAULT,
|
||||||
@ -286,14 +310,11 @@ TEST_CASE("mcpwm_operator_brake_on_soft_fault", "[mcpwm]")
|
|||||||
TEST_ESP_OK(mcpwm_operator_set_brake_on_fault(oper, &brake_config));
|
TEST_ESP_OK(mcpwm_operator_set_brake_on_fault(oper, &brake_config));
|
||||||
|
|
||||||
printf("create generators\r\n");
|
printf("create generators\r\n");
|
||||||
const int gen_a_gpio = TEST_PWMA_GPIO;
|
|
||||||
const int gen_b_gpio = TEST_PWMB_GPIO;
|
|
||||||
mcpwm_gen_handle_t gen_a = NULL;
|
mcpwm_gen_handle_t gen_a = NULL;
|
||||||
mcpwm_gen_handle_t gen_b = NULL;
|
mcpwm_gen_handle_t gen_b = NULL;
|
||||||
mcpwm_generator_config_t generator_config = {
|
mcpwm_generator_config_t generator_config = {
|
||||||
.flags.io_loop_back = true,
|
.gen_gpio_num = gen_a_gpio,
|
||||||
};
|
};
|
||||||
generator_config.gen_gpio_num = gen_a_gpio;
|
|
||||||
TEST_ESP_OK(mcpwm_new_generator(oper, &generator_config, &gen_a));
|
TEST_ESP_OK(mcpwm_new_generator(oper, &generator_config, &gen_a));
|
||||||
generator_config.gen_gpio_num = gen_b_gpio;
|
generator_config.gen_gpio_num = gen_b_gpio;
|
||||||
TEST_ESP_OK(mcpwm_new_generator(oper, &generator_config, &gen_b));
|
TEST_ESP_OK(mcpwm_new_generator(oper, &generator_config, &gen_b));
|
||||||
@ -360,4 +381,6 @@ TEST_CASE("mcpwm_operator_brake_on_soft_fault", "[mcpwm]")
|
|||||||
TEST_ESP_OK(mcpwm_del_generator(gen_b));
|
TEST_ESP_OK(mcpwm_del_generator(gen_b));
|
||||||
TEST_ESP_OK(mcpwm_del_operator(oper));
|
TEST_ESP_OK(mcpwm_del_operator(oper));
|
||||||
TEST_ESP_OK(mcpwm_del_timer(timer));
|
TEST_ESP_OK(mcpwm_del_timer(timer));
|
||||||
|
TEST_ESP_OK(gpio_reset_pin(gen_a_gpio));
|
||||||
|
TEST_ESP_OK(gpio_reset_pin(gen_b_gpio));
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@ -106,6 +106,13 @@ TEST_CASE("mcpwm_gpio_sync_timer_phase_lock", "[mcpwm]")
|
|||||||
// |
|
// |
|
||||||
// v
|
// v
|
||||||
// timer0-->timer1-->timer2
|
// timer0-->timer1-->timer2
|
||||||
|
const int gpio_num = TEST_SYNC_GPIO;
|
||||||
|
gpio_config_t sync_gpio_conf = {
|
||||||
|
.mode = GPIO_MODE_OUTPUT,
|
||||||
|
.pin_bit_mask = BIT(gpio_num),
|
||||||
|
};
|
||||||
|
TEST_ESP_OK(gpio_config(&sync_gpio_conf));
|
||||||
|
|
||||||
mcpwm_timer_config_t timer_config = {
|
mcpwm_timer_config_t timer_config = {
|
||||||
.clk_src = MCPWM_TIMER_CLK_SRC_DEFAULT,
|
.clk_src = MCPWM_TIMER_CLK_SRC_DEFAULT,
|
||||||
.group_id = 0,
|
.group_id = 0,
|
||||||
@ -127,11 +134,9 @@ TEST_CASE("mcpwm_gpio_sync_timer_phase_lock", "[mcpwm]")
|
|||||||
.direction = MCPWM_TIMER_DIRECTION_UP,
|
.direction = MCPWM_TIMER_DIRECTION_UP,
|
||||||
};
|
};
|
||||||
mcpwm_sync_handle_t gpio_sync_src;
|
mcpwm_sync_handle_t gpio_sync_src;
|
||||||
const int gpio_num = TEST_SYNC_GPIO;
|
|
||||||
mcpwm_gpio_sync_src_config_t gpio_sync_config = {
|
mcpwm_gpio_sync_src_config_t gpio_sync_config = {
|
||||||
.group_id = 0,
|
.group_id = 0,
|
||||||
.gpio_num = gpio_num,
|
.gpio_num = gpio_num,
|
||||||
.flags.io_loop_back = true, // so that we can use gpio driver to simulate the sync signal
|
|
||||||
.flags.pull_down = true, // internally pull down
|
.flags.pull_down = true, // internally pull down
|
||||||
};
|
};
|
||||||
TEST_ESP_OK(mcpwm_new_gpio_sync_src(&gpio_sync_config, &gpio_sync_src));
|
TEST_ESP_OK(mcpwm_new_gpio_sync_src(&gpio_sync_config, &gpio_sync_src));
|
||||||
@ -154,6 +159,7 @@ TEST_CASE("mcpwm_gpio_sync_timer_phase_lock", "[mcpwm]")
|
|||||||
TEST_ESP_OK(mcpwm_del_sync_src(sync_srcs[i]));
|
TEST_ESP_OK(mcpwm_del_sync_src(sync_srcs[i]));
|
||||||
TEST_ESP_OK(mcpwm_del_timer(timers[i]));
|
TEST_ESP_OK(mcpwm_del_timer(timers[i]));
|
||||||
}
|
}
|
||||||
|
TEST_ESP_OK(gpio_reset_pin(gpio_num));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("mcpwm_timer_sync_timer_phase_lock", "[mcpwm]")
|
TEST_CASE("mcpwm_timer_sync_timer_phase_lock", "[mcpwm]")
|
||||||
|
@ -122,8 +122,6 @@ You can allocate a MCPWM generator object by calling the :cpp:func:`mcpwm_new_ge
|
|||||||
|
|
||||||
- :cpp:member:`mcpwm_generator_config_t::gen_gpio_num` sets the GPIO number used by the generator.
|
- :cpp:member:`mcpwm_generator_config_t::gen_gpio_num` sets the GPIO number used by the generator.
|
||||||
- :cpp:member:`mcpwm_generator_config_t::invert_pwm` sets whether to invert the PWM signal.
|
- :cpp:member:`mcpwm_generator_config_t::invert_pwm` sets whether to invert the PWM signal.
|
||||||
- :cpp:member:`mcpwm_generator_config_t::io_loop_back` sets whether to enable the Loop-back mode. It is for debugging purposes only. It enables both the GPIO's input and output ability through the GPIO matrix peripheral.
|
|
||||||
- :cpp:member:`mcpwm_generator_config_t::io_od_mode` configures the PWM GPIO as open-drain output.
|
|
||||||
- :cpp:member:`mcpwm_generator_config_t::pull_up` and :cpp:member:`mcpwm_generator_config_t::pull_down` controls whether to enable the internal pull-up and pull-down resistors accordingly.
|
- :cpp:member:`mcpwm_generator_config_t::pull_up` and :cpp:member:`mcpwm_generator_config_t::pull_down` controls whether to enable the internal pull-up and pull-down resistors accordingly.
|
||||||
|
|
||||||
The :cpp:func:`mcpwm_new_generator` will return a pointer to the allocated generator object if the allocation succeeds. Otherwise, it will return an error code. Specifically, when there are no more free generators in the MCPWM operator, this function will return the :c:macro:`ESP_ERR_NOT_FOUND` error. [1]_
|
The :cpp:func:`mcpwm_new_generator` will return a pointer to the allocated generator object if the allocation succeeds. Otherwise, it will return an error code. Specifically, when there are no more free generators in the MCPWM operator, this function will return the :c:macro:`ESP_ERR_NOT_FOUND` error. [1]_
|
||||||
@ -142,7 +140,6 @@ To allocate a GPIO fault object, you can call the :cpp:func:`mcpwm_new_gpio_faul
|
|||||||
- :cpp:member:`mcpwm_gpio_fault_config_t::gpio_num` sets the GPIO number used by the fault.
|
- :cpp:member:`mcpwm_gpio_fault_config_t::gpio_num` sets the GPIO number used by the fault.
|
||||||
- :cpp:member:`mcpwm_gpio_fault_config_t::active_level` sets the active level of the fault signal.
|
- :cpp:member:`mcpwm_gpio_fault_config_t::active_level` sets the active level of the fault signal.
|
||||||
- :cpp:member:`mcpwm_gpio_fault_config_t::pull_up` and :cpp:member:`mcpwm_gpio_fault_config_t::pull_down` set whether to pull up and/or pull down the GPIO internally.
|
- :cpp:member:`mcpwm_gpio_fault_config_t::pull_up` and :cpp:member:`mcpwm_gpio_fault_config_t::pull_down` set whether to pull up and/or pull down the GPIO internally.
|
||||||
- :cpp:member:`mcpwm_gpio_fault_config_t::io_loop_back` sets whether to enable the loopback mode. It is for debugging purposes only. It enables both the GPIO's input and output ability through the GPIO matrix peripheral.
|
|
||||||
|
|
||||||
The :cpp:func:`mcpwm_new_gpio_fault` will return a pointer to the allocated fault object if the allocation succeeds. Otherwise, it will return an error code. Specifically, when there are no more free GPIO faults in the MCPWM group, this function will return the :c:macro:`ESP_ERR_NOT_FOUND` error. [1]_
|
The :cpp:func:`mcpwm_new_gpio_fault` will return a pointer to the allocated fault object if the allocation succeeds. Otherwise, it will return an error code. Specifically, when there are no more free GPIO faults in the MCPWM group, this function will return the :c:macro:`ESP_ERR_NOT_FOUND` error. [1]_
|
||||||
|
|
||||||
@ -163,7 +160,6 @@ To allocate a GPIO sync source, you can call the :cpp:func:`mcpwm_new_gpio_sync_
|
|||||||
- :cpp:member:`mcpwm_gpio_sync_src_config_t::gpio_num` sets the GPIO number used by the sync source.
|
- :cpp:member:`mcpwm_gpio_sync_src_config_t::gpio_num` sets the GPIO number used by the sync source.
|
||||||
- :cpp:member:`mcpwm_gpio_sync_src_config_t::active_neg` sets whether the sync signal is active on falling edges.
|
- :cpp:member:`mcpwm_gpio_sync_src_config_t::active_neg` sets whether the sync signal is active on falling edges.
|
||||||
- :cpp:member:`mcpwm_gpio_sync_src_config_t::pull_up` and :cpp:member:`mcpwm_gpio_sync_src_config_t::pull_down` set whether to pull up and/or pull down the GPIO internally.
|
- :cpp:member:`mcpwm_gpio_sync_src_config_t::pull_up` and :cpp:member:`mcpwm_gpio_sync_src_config_t::pull_down` set whether to pull up and/or pull down the GPIO internally.
|
||||||
- :cpp:member:`mcpwm_gpio_sync_src_config_t::io_loop_back` sets whether to enable the Loop-back mode. It is for debugging purposes only. It enables both the GPIO's input and output ability through the GPIO matrix peripheral.
|
|
||||||
|
|
||||||
The :cpp:func:`mcpwm_new_gpio_sync_src` will return a pointer to the allocated sync source object if the allocation succeeds. Otherwise, it will return an error code. Specifically, when there are no more free GPIO sync sources in the MCPWM group, this function will return the :c:macro:`ESP_ERR_NOT_FOUND` error. [1]_
|
The :cpp:func:`mcpwm_new_gpio_sync_src` will return a pointer to the allocated sync source object if the allocation succeeds. Otherwise, it will return an error code. Specifically, when there are no more free GPIO sync sources in the MCPWM group, this function will return the :c:macro:`ESP_ERR_NOT_FOUND` error. [1]_
|
||||||
|
|
||||||
@ -207,8 +203,6 @@ Next, to allocate a capture channel, you can call the :cpp:func:`mcpwm_new_captu
|
|||||||
- :cpp:member:`mcpwm_capture_channel_config_t::extra_capture_channel_flags::pos_edge` and :cpp:member:`mcpwm_capture_channel_config_t::extra_capture_channel_flags::neg_edge` set whether to capture on the positive and/or falling edge of the input signal.
|
- :cpp:member:`mcpwm_capture_channel_config_t::extra_capture_channel_flags::pos_edge` and :cpp:member:`mcpwm_capture_channel_config_t::extra_capture_channel_flags::neg_edge` set whether to capture on the positive and/or falling edge of the input signal.
|
||||||
- :cpp:member:`mcpwm_capture_channel_config_t::extra_capture_channel_flags::pull_up` and :cpp:member:`mcpwm_capture_channel_config_t::extra_capture_channel_flags::pull_down` set whether to pull up and/or pull down the GPIO internally.
|
- :cpp:member:`mcpwm_capture_channel_config_t::extra_capture_channel_flags::pull_up` and :cpp:member:`mcpwm_capture_channel_config_t::extra_capture_channel_flags::pull_down` set whether to pull up and/or pull down the GPIO internally.
|
||||||
- :cpp:member:`mcpwm_capture_channel_config_t::extra_capture_channel_flags::invert_cap_signal` sets whether to invert the capture signal.
|
- :cpp:member:`mcpwm_capture_channel_config_t::extra_capture_channel_flags::invert_cap_signal` sets whether to invert the capture signal.
|
||||||
- :cpp:member:`mcpwm_capture_channel_config_t::extra_capture_channel_flags::io_loop_back` sets whether to enable the Loop-back mode. It is for debugging purposes only. It enables both the GPIO's input and output ability through the GPIO matrix peripheral.
|
|
||||||
- :cpp:member:`mcpwm_capture_channel_config_t::extra_capture_channel_flags::keep_io_conf_at_exit` sets whether to keep the GPIO configuration when the capture channel is deleted.
|
|
||||||
|
|
||||||
The :cpp:func:`mcpwm_new_capture_channel` will return a pointer to the allocated capture channel object if the allocation succeeds. Otherwise, it will return an error code. Specifically, when there is no free capture channel left in the capture timer, this function will return the :c:macro:`ESP_ERR_NOT_FOUND` error.
|
The :cpp:func:`mcpwm_new_capture_channel` will return a pointer to the allocated capture channel object if the allocation succeeds. Otherwise, it will return an error code. Specifically, when there is no free capture channel left in the capture timer, this function will return the :c:macro:`ESP_ERR_NOT_FOUND` error.
|
||||||
|
|
||||||
|
@ -122,8 +122,6 @@ MCPWM 生成器
|
|||||||
|
|
||||||
- :cpp:member:`mcpwm_generator_config_t::gen_gpio_num` 设置生成器使用的 GPIO 编号。
|
- :cpp:member:`mcpwm_generator_config_t::gen_gpio_num` 设置生成器使用的 GPIO 编号。
|
||||||
- :cpp:member:`mcpwm_generator_config_t::invert_pwm` 设置是否反相 PWM 信号。
|
- :cpp:member:`mcpwm_generator_config_t::invert_pwm` 设置是否反相 PWM 信号。
|
||||||
- :cpp:member:`mcpwm_generator_config_t::io_loop_back` 设置是否启用回环模式。该模式仅用于调试,使用 GPIO 交换矩阵外设同时启用 GPIO 输入和输出。
|
|
||||||
- :cpp:member:`mcpwm_generator_config_t::io_od_mode` 设置是否启用漏极开路输出。
|
|
||||||
- :cpp:member:`mcpwm_generator_config_t::pull_up` 和 :cpp:member:`mcpwm_generator_config_t::pull_down` 用来设置是否启用内部上下拉电阻。
|
- :cpp:member:`mcpwm_generator_config_t::pull_up` 和 :cpp:member:`mcpwm_generator_config_t::pull_down` 用来设置是否启用内部上下拉电阻。
|
||||||
|
|
||||||
分配成功后,:cpp:func:`mcpwm_new_generator` 将返回一个指向已分配生成器的指针。否则,函数将返回错误代码。具体来说,当 MCPWM 操作器中没有空闲生成器时,将返回 :c:macro:`ESP_ERR_NOT_FOUND` 错误。[1]_
|
分配成功后,:cpp:func:`mcpwm_new_generator` 将返回一个指向已分配生成器的指针。否则,函数将返回错误代码。具体来说,当 MCPWM 操作器中没有空闲生成器时,将返回 :c:macro:`ESP_ERR_NOT_FOUND` 错误。[1]_
|
||||||
@ -142,7 +140,6 @@ MCPWM 故障分为两种类型:来自 GPIO 的故障信号和软件故障。
|
|||||||
- :cpp:member:`mcpwm_gpio_fault_config_t::gpio_num` 设置故障所使用的 GPIO 编号。
|
- :cpp:member:`mcpwm_gpio_fault_config_t::gpio_num` 设置故障所使用的 GPIO 编号。
|
||||||
- :cpp:member:`mcpwm_gpio_fault_config_t::active_level` 设置故障信号的有效电平。
|
- :cpp:member:`mcpwm_gpio_fault_config_t::active_level` 设置故障信号的有效电平。
|
||||||
- :cpp:member:`mcpwm_gpio_fault_config_t::pull_up` 和 :cpp:member:`mcpwm_gpio_fault_config_t::pull_down` 设置是否在内部拉高和/或拉低 GPIO。
|
- :cpp:member:`mcpwm_gpio_fault_config_t::pull_up` 和 :cpp:member:`mcpwm_gpio_fault_config_t::pull_down` 设置是否在内部拉高和/或拉低 GPIO。
|
||||||
- :cpp:member:`mcpwm_gpio_fault_config_t::io_loop_back` 设置是否启用回环模式。该模式仅用于调试,使用 GPIO 交换矩阵外设同时启用 GPIO 输入和输出。
|
|
||||||
|
|
||||||
分配成功后,:cpp:func:`mcpwm_new_gpio_fault` 将返回一个指向已分配故障的指针。否则,函数将返回错误代码。具体来说,当指定 MCPWM 组中没有空闲 GPIO 故障时,将返回 :c:macro:`ESP_ERR_NOT_FOUND` 错误。[1]_
|
分配成功后,:cpp:func:`mcpwm_new_gpio_fault` 将返回一个指向已分配故障的指针。否则,函数将返回错误代码。具体来说,当指定 MCPWM 组中没有空闲 GPIO 故障时,将返回 :c:macro:`ESP_ERR_NOT_FOUND` 错误。[1]_
|
||||||
|
|
||||||
@ -163,7 +160,6 @@ MCPWM 同步源
|
|||||||
- :cpp:member:`mcpwm_gpio_sync_src_config_t::gpio_num` 设置同步源使用的 GPIO 编号。
|
- :cpp:member:`mcpwm_gpio_sync_src_config_t::gpio_num` 设置同步源使用的 GPIO 编号。
|
||||||
- :cpp:member:`mcpwm_gpio_sync_src_config_t::active_neg` 设置同步信号在下降沿是否有效。
|
- :cpp:member:`mcpwm_gpio_sync_src_config_t::active_neg` 设置同步信号在下降沿是否有效。
|
||||||
- :cpp:member:`mcpwm_gpio_sync_src_config_t::pull_up` 和 :cpp:member:`mcpwm_gpio_sync_src_config_t::pull_down` 设置是否在内部拉高和/或拉低 GPIO。
|
- :cpp:member:`mcpwm_gpio_sync_src_config_t::pull_up` 和 :cpp:member:`mcpwm_gpio_sync_src_config_t::pull_down` 设置是否在内部拉高和/或拉低 GPIO。
|
||||||
- :cpp:member:`mcpwm_gpio_sync_src_config_t::io_loop_back` 设置是否启用回环模式。该模式仅用于调试,使用 GPIO 交换矩阵外设同时启用 GPIO 输入和输出。
|
|
||||||
|
|
||||||
分配成功后,:cpp:func:`mcpwm_new_gpio_sync_src` 将返回一个指向已分配同步源的指针。否则,函数将返回错误代码。具体来说,当 MCPWM 组中没有空闲 GPIO 时钟源时,将返回 :c:macro:`ESP_ERR_NOT_FOUND` 错误。[1]_
|
分配成功后,:cpp:func:`mcpwm_new_gpio_sync_src` 将返回一个指向已分配同步源的指针。否则,函数将返回错误代码。具体来说,当 MCPWM 组中没有空闲 GPIO 时钟源时,将返回 :c:macro:`ESP_ERR_NOT_FOUND` 错误。[1]_
|
||||||
|
|
||||||
@ -207,8 +203,6 @@ MCPWM 组有一个专用定时器,用于捕获特定事件发生时的时间
|
|||||||
- :cpp:member:`mcpwm_capture_channel_config_t::extra_capture_channel_flags::pos_edge` 和 :cpp:member:`mcpwm_capture_channel_config_t::extra_capture_channel_flags::neg_edge` 设置是否在输入信号的上升沿和/或下降沿捕获时间戳。
|
- :cpp:member:`mcpwm_capture_channel_config_t::extra_capture_channel_flags::pos_edge` 和 :cpp:member:`mcpwm_capture_channel_config_t::extra_capture_channel_flags::neg_edge` 设置是否在输入信号的上升沿和/或下降沿捕获时间戳。
|
||||||
- :cpp:member:`mcpwm_capture_channel_config_t::extra_capture_channel_flags::pull_up` 和 :cpp:member:`mcpwm_capture_channel_config_t::extra_capture_channel_flags::pull_down` 设置是否在内部拉高和/或拉低 GPIO。
|
- :cpp:member:`mcpwm_capture_channel_config_t::extra_capture_channel_flags::pull_up` 和 :cpp:member:`mcpwm_capture_channel_config_t::extra_capture_channel_flags::pull_down` 设置是否在内部拉高和/或拉低 GPIO。
|
||||||
- :cpp:member:`mcpwm_capture_channel_config_t::extra_capture_channel_flags::invert_cap_signal` 设置是否取反捕获信号。
|
- :cpp:member:`mcpwm_capture_channel_config_t::extra_capture_channel_flags::invert_cap_signal` 设置是否取反捕获信号。
|
||||||
- :cpp:member:`mcpwm_capture_channel_config_t::extra_capture_channel_flags::io_loop_back` 设置是否启用回环模式。该模式仅用于调试,使用 GPIO 交换矩阵外设同时启用 GPIO 输入和输出。
|
|
||||||
- :cpp:member:`mcpwm_capture_channel_config_t::extra_capture_channel_flags::keep_io_conf_at_exit` 设置是否在删除通道时保留 GPIO 的相关配置。
|
|
||||||
|
|
||||||
分配成功后,:cpp:func:`mcpwm_new_capture_channel` 将返回一个指向已分配捕获通道的指针。否则,函数将返回错误代码。具体来说,当捕获定时器中没有空闲捕获通道时,将返回 :c:macro:`ESP_ERR_NOT_FOUND` 错误。
|
分配成功后,:cpp:func:`mcpwm_new_capture_channel` 将返回一个指向已分配捕获通道的指针。否则,函数将返回错误代码。具体来说,当捕获定时器中没有空闲捕获通道时,将返回 :c:macro:`ESP_ERR_NOT_FOUND` 错误。
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user