drivers: stepper: DRV8424 Fault Event

Adds support for the fault event via the fault pin to the drv8424 driver.

Signed-off-by: Jan Behrens <jan.behrens@navimatix.de>
This commit is contained in:
Jan Behrens 2025-03-27 12:00:17 +01:00 committed by Benjamin Cabé
parent c8c79a9fc6
commit d486c7794a

View File

@ -14,6 +14,12 @@
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(drv8424, CONFIG_STEPPER_LOG_LEVEL);
/* Enable and wake up times of the drv84xx stepper controller family. Only after they have elapsed
* are controller output signals guaranteed to be valid.
*/
#define DRV84XX_ENABLE_TIME K_USEC(5)
#define DRV84XX_WAKE_UP_TIME K_USEC(1200)
/**
* @brief DRV8424 stepper driver configuration data.
*
@ -26,6 +32,7 @@ struct drv8424_config {
struct gpio_dt_spec en_pin;
struct gpio_dt_spec m0_pin;
struct gpio_dt_spec m1_pin;
struct gpio_dt_spec fault_pin;
};
/* Struct for storing the states of output pins. */
@ -37,15 +44,15 @@ struct drv8424_pin_states {
};
/**
* @brief DRV8424 stepper driver data.
*
* This structure contains mutable data used by a DRV8424 stepper driver.
* @brief DRV84XX stepper driver data.
*/
struct drv8424_data {
const struct step_dir_stepper_common_data common;
const struct device *dev;
bool enabled;
struct drv8424_pin_states pin_states;
enum stepper_micro_step_resolution ustep_res;
struct gpio_callback fault_cb_data;
};
STEP_DIR_STEPPER_STRUCT_CHECK(struct drv8424_config, struct drv8424_data);
@ -172,6 +179,10 @@ static int drv8424_enable(const struct device *dev)
{
const struct drv8424_config *config = dev->config;
struct drv8424_data *data = dev->data;
bool has_enable_pin = config->en_pin.port != NULL;
bool has_sleep_pin = config->sleep_pin.port != NULL;
bool has_fault_pin = config->fault_pin.port != NULL;
k_timeout_t enable_timeout;
int ret;
ret = drv8424_check_en_sleep_pin(config);
@ -189,6 +200,26 @@ static int drv8424_enable(const struct device *dev)
return ret;
}
if (has_enable_pin) {
enable_timeout = DRV84XX_ENABLE_TIME;
}
if (has_sleep_pin) {
enable_timeout = DRV84XX_WAKE_UP_TIME;
}
if (has_fault_pin) {
/* Wait after enable/wakeup until the fault pin is guaranteed to be in the
* proper state.
*/
k_sleep(enable_timeout);
ret = gpio_add_callback_dt(&config->fault_pin, &data->fault_cb_data);
if (ret != 0) {
LOG_ERR("%s: Failed to add fault callback (error: %d)", dev->name, ret);
return ret;
}
}
data->enabled = true;
return ret;
@ -198,6 +229,7 @@ static int drv8424_disable(const struct device *dev)
{
const struct drv8424_config *config = dev->config;
struct drv8424_data *data = dev->data;
bool has_fault_pin = config->fault_pin.port != NULL;
int ret;
ret = drv8424_check_en_sleep_pin(config);
@ -215,6 +247,14 @@ static int drv8424_disable(const struct device *dev)
return ret;
}
if (has_fault_pin) {
ret = gpio_remove_callback_dt(&config->fault_pin, &data->fault_cb_data);
if (ret != 0) {
LOG_ERR("%s: Failed to remove fault callback (error: %d)", dev->name, ret);
return ret;
}
}
config->common.timing_source->stop(dev);
data->enabled = false;
@ -339,6 +379,13 @@ static int drv8424_run(const struct device *dev, enum stepper_direction directio
return step_dir_stepper_common_run(dev, direction);
}
void fault_event(const struct device *dev, struct gpio_callback *cb, uint32_t pins)
{
struct drv8424_data *data = CONTAINER_OF(cb, struct drv8424_data, fault_cb_data);
stepper_trigger_callback(data->dev, STEPPER_EVENT_FAULT_DETECTED);
}
static int drv8424_init(const struct device *dev)
{
const struct drv8424_config *const config = dev->config;
@ -392,6 +439,25 @@ static int drv8424_init(const struct device *dev)
return ret;
}
/* Configure fault pin if it is available */
if (config->fault_pin.port != NULL) {
ret = gpio_pin_configure_dt(&config->fault_pin, GPIO_INPUT);
if (ret != 0) {
LOG_ERR("%s: Failed to configure fault_pin (error: %d)", dev->name, ret);
return ret;
}
ret = gpio_pin_interrupt_configure_dt(&config->fault_pin,
GPIO_INT_EDGE_TO_INACTIVE);
if (ret != 0) {
LOG_ERR("Error %d: failed to configure interrupt on %s pin %d", ret,
config->fault_pin.port->name, config->fault_pin.pin);
return ret;
}
gpio_init_callback(&data->fault_cb_data, fault_event, BIT(config->fault_pin.pin));
}
return 0;
}
@ -419,11 +485,13 @@ static DEVICE_API(stepper, drv8424_stepper_api) = {
.en_pin = GPIO_DT_SPEC_INST_GET_OR(inst, en_gpios, {0}), \
.m0_pin = GPIO_DT_SPEC_INST_GET(inst, m0_gpios), \
.m1_pin = GPIO_DT_SPEC_INST_GET(inst, m1_gpios), \
.fault_pin = GPIO_DT_SPEC_INST_GET_OR(inst, fault_gpios, {0}), \
}; \
\
static struct drv8424_data drv8424_data_##inst = { \
.common = STEP_DIR_STEPPER_DT_INST_COMMON_DATA_INIT(inst), \
.ustep_res = DT_INST_PROP(inst, micro_step_res), \
.dev = DEVICE_DT_GET(DT_INST(inst, DT_DRV_COMPAT)), \
}; \
\
DEVICE_DT_INST_DEFINE(inst, &drv8424_init, NULL, &drv8424_data_##inst, \