make step/dir pins configurable

This commit is contained in:
Oskar Weigl
2018-10-22 21:03:13 -07:00
parent 8aac095bfd
commit b09d1e9e25
5 changed files with 74 additions and 31 deletions
+3
View File
@@ -1,6 +1,9 @@
# Unreleased Features
Please add a note of your changes below this heading if you make a Pull Request.
## Added
* Make step dir gpio pins configurable.
## Fixed
* Would ERROR_CONTROL_DEADLINE_MISSED along with every ERROR_PHASE_RESISTANCE_OUT_OF_RANGE.
+25 -12
View File
@@ -26,6 +26,8 @@ Axis::Axis(const AxisHardwareConfig_t& hw_config,
controller_.axis_ = this;
motor_.axis_ = this;
trap_.axis_ = this;
decode_step_dir_pins();
}
static void step_cb_wrapper(void* ctx) {
@@ -67,24 +69,37 @@ bool Axis::wait_for_current_meas() {
// step/direction interface
void Axis::step_cb() {
if (step_dir_active_) {
GPIO_PinState dir_pin = HAL_GPIO_ReadPin(hw_config_.dir_port, hw_config_.dir_pin);
GPIO_PinState dir_pin = HAL_GPIO_ReadPin(dir_port_, dir_pin_);
float dir = (dir_pin == GPIO_PIN_SET) ? 1.0f : -1.0f;
controller_.pos_setpoint_ += dir * config_.counts_per_step;
}
};
// @brief Enables or disables step/dir input
void Axis::set_step_dir_enabled(bool enable) {
if (enable) {
void Axis::load_default_step_dir_pin_config(
const AxisHardwareConfig_t& hw_config, Config_t* config) {
config->step_gpio_pin = hw_config.step_gpio_pin;
config->dir_gpio_pin = hw_config.dir_gpio_pin;
}
void Axis::decode_step_dir_pins() {
step_port_ = get_gpio_port_by_pin(config_.step_gpio_pin);
step_pin_ = get_gpio_pin_by_pin(config_.step_gpio_pin);
dir_port_ = get_gpio_port_by_pin(config_.dir_gpio_pin);
dir_pin_ = get_gpio_pin_by_pin(config_.dir_gpio_pin);
}
// @brief (de)activates step/dir input
void Axis::set_step_dir_active(bool active) {
if (active) {
// Set up the direction GPIO as input
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Pin = hw_config_.dir_pin;
GPIO_InitStruct.Pin = dir_pin_;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(hw_config_.dir_port, &GPIO_InitStruct);
HAL_GPIO_Init(dir_port_, &GPIO_InitStruct);
// Subscribe to rising edges of the step GPIO
GPIO_subscribe(hw_config_.step_port, hw_config_.step_pin, GPIO_PULLDOWN,
GPIO_subscribe(step_port_, step_pin_, GPIO_PULLDOWN,
step_cb_wrapper, this);
step_dir_active_ = true;
@@ -92,7 +107,7 @@ void Axis::set_step_dir_enabled(bool enable) {
step_dir_active_ = false;
// Unsubscribe from step GPIO
GPIO_unsubscribe(hw_config_.step_port, hw_config_.step_pin);
GPIO_unsubscribe(step_port_, step_pin_);
}
}
@@ -167,7 +182,6 @@ bool Axis::run_sensorless_spin_up() {
// Note run_sensorless_control_loop and run_closed_loop_control_loop are very similar and differ only in where we get the estimate from.
bool Axis::run_sensorless_control_loop() {
set_step_dir_enabled(config_.enable_step_dir);
run_control_loop([this](){
if (controller_.config_.control_mode >= Controller::CTRL_MODE_POSITION_CONTROL)
return error_ |= ERROR_POS_CTRL_DURING_SENSORLESS, false;
@@ -180,12 +194,11 @@ bool Axis::run_sensorless_control_loop() {
return false; // set_error should update axis.error_
return true;
});
set_step_dir_enabled(false);
return check_for_errors();
}
bool Axis::run_closed_loop_control_loop() {
set_step_dir_enabled(config_.enable_step_dir);
set_step_dir_active(config_.enable_step_dir);
run_control_loop([this](){
// Note that all estimators are updated in the loop prefix in run_control_loop
float current_setpoint;
@@ -195,7 +208,7 @@ bool Axis::run_closed_loop_control_loop() {
return false; // set_error should update axis.error_
return true;
});
set_step_dir_enabled(false);
set_step_dir_active(false);
return check_for_errors();
}
+19 -2
View File
@@ -45,9 +45,12 @@ public:
bool startup_sensorless_control = false; //<! enable sensorless control after calibration/startup
bool enable_step_dir = false; //<! enable step/dir input after calibration
// For M0 this has no effect if enable_uart is true
float counts_per_step = 2.0f;
// Defaults loaded from hw_config in load_configuration in main.cpp
uint16_t step_gpio_pin = 0;
uint16_t dir_gpio_pin = 0;
// Spinup settings
float ramp_up_time = 0.4f; // [s]
float ramp_up_distance = 4 * M_PI; // [rad]
@@ -74,7 +77,10 @@ public:
bool wait_for_current_meas();
void step_cb();
void set_step_dir_enabled(bool enable);
void set_step_dir_active(bool enable);
void decode_step_dir_pins();
static void load_default_step_dir_pin_config(
const AxisHardwareConfig_t& hw_config, Config_t* config);
bool check_DRV_fault();
bool check_PSU_brownout();
@@ -168,6 +174,13 @@ public:
// variables exposed on protocol
Error_t error_ = ERROR_NONE;
bool step_dir_active_ = false; // auto enabled after calibration, based on config.enable_step_dir
// updated from config in constructor, and on protocol hook
GPIO_TypeDef* step_port_;
uint16_t step_pin_;
GPIO_TypeDef* dir_port_;
uint16_t dir_pin_;
State_t requested_state_ = AXIS_STATE_STARTUP_SEQUENCE;
State_t task_chain_[10] = { AXIS_STATE_UNDEFINED };
State_t& current_state_ = task_chain_[0];
@@ -189,6 +202,10 @@ public:
make_protocol_property("startup_sensorless_control", &config_.startup_sensorless_control),
make_protocol_property("enable_step_dir", &config_.enable_step_dir),
make_protocol_property("counts_per_step", &config_.counts_per_step),
make_protocol_property("step_gpio_pin", &config_.step_gpio_pin,
[](void* ctx) { static_cast<Axis*>(ctx)->decode_step_dir_pins(); }, this),
make_protocol_property("dir_gpio_pin", &config_.dir_gpio_pin,
[](void* ctx) { static_cast<Axis*>(ctx)->decode_step_dir_pins(); }, this),
make_protocol_property("ramp_up_time", &config_.ramp_up_time),
make_protocol_property("ramp_up_distance", &config_.ramp_up_distance),
make_protocol_property("spin_up_current", &config_.spin_up_current),
+24 -16
View File
@@ -21,10 +21,12 @@
typedef struct {
GPIO_TypeDef* step_port;
uint16_t step_pin;
GPIO_TypeDef* dir_port;
uint16_t dir_pin;
// GPIO_TypeDef* step_port;
// uint16_t step_pin;
// GPIO_TypeDef* dir_port;
// uint16_t dir_pin;
uint16_t step_gpio_pin;
uint16_t dir_gpio_pin;
size_t thermistor_adc_ch;
osPriority thread_priority;
} AxisHardwareConfig_t;
@@ -74,10 +76,12 @@ const size_t thermistor_num_coeffs = sizeof(thermistor_poly_coeffs)/sizeof(therm
const BoardHardwareConfig_t hw_configs[2] = { {
//M0
.axis_config = {
.step_port = GPIO_1_GPIO_Port,
.step_pin = GPIO_1_Pin,
.dir_port = GPIO_2_GPIO_Port,
.dir_pin = GPIO_2_Pin,
// .step_port = GPIO_1_GPIO_Port,
// .step_pin = GPIO_1_Pin,
// .dir_port = GPIO_2_GPIO_Port,
// .dir_pin = GPIO_2_Pin,
.step_gpio_pin = 1,
.dir_gpio_pin = 2,
.thermistor_adc_ch = 15,
.thread_priority = (osPriority)(osPriorityHigh + (osPriority)1),
},
@@ -111,15 +115,19 @@ const BoardHardwareConfig_t hw_configs[2] = { {
//M1
.axis_config = {
#if HW_VERSION_MAJOR == 3 && HW_VERSION_MINOR >= 5
.step_port = GPIO_7_GPIO_Port,
.step_pin = GPIO_7_Pin,
.dir_port = GPIO_8_GPIO_Port,
.dir_pin = GPIO_8_Pin,
// .step_port = GPIO_7_GPIO_Port,
// .step_pin = GPIO_7_Pin,
// .dir_port = GPIO_8_GPIO_Port,
// .dir_pin = GPIO_8_Pin,
.step_gpio_pin = 7,
.dir_gpio_pin = 8,
#else
.step_port = GPIO_3_GPIO_Port,
.step_pin = GPIO_3_Pin,
.dir_port = GPIO_4_GPIO_Port,
.dir_pin = GPIO_4_Pin,
// .step_port = GPIO_3_GPIO_Port,
// .step_pin = GPIO_3_Pin,
// .dir_port = GPIO_4_GPIO_Port,
// .dir_pin = GPIO_4_Pin,
.step_gpio_pin = 3,
.dir_gpio_pin = 4,
#endif
#if HW_VERSION_MAJOR == 3 && HW_VERSION_MINOR >= 3
.thermistor_adc_ch = 4,
+3 -1
View File
@@ -65,6 +65,8 @@ void load_configuration(void) {
motor_configs[i] = Motor::Config_t();
trap_configs[i] = TrapezoidalTrajectory::Config_t();
axis_configs[i] = Axis::Config_t();
// Default step/dir pins are different, so we need to explicitly load them
Axis::load_default_step_dir_pin_config(hw_configs[i].axis_config, &axis_configs[i]);
}
} else {
user_config_loaded_ = true;
@@ -179,7 +181,7 @@ int odrive_main(void) {
#if HW_VERSION_MAJOR == 3 && HW_VERSION_MINOR >= 3
if (board_config.enable_uart) {
axes[0]->config_.enable_step_dir = false;
axes[0]->set_step_dir_enabled(false);
axes[0]->set_step_dir_active(false);
SetGPIO12toUART();
}
#endif