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:
parent
c8c79a9fc6
commit
d486c7794a
@ -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, \
|
||||
|
||||
Loading…
Reference in New Issue
Block a user