From 89bf879ff97eae995aceae9effd263a9096cb927 Mon Sep 17 00:00:00 2001 From: Shaun Meehan Date: Thu, 27 Aug 2020 18:28:33 -0700 Subject: [PATCH] Added GPIO_MODE_MECH_BRAKE, removed pull-ups for outputs, updated docs, added check for GPIO_MODE_MECH_BRAKE to startup in main --- Firmware/MotorControl/main.cpp | 8 ++++- Firmware/MotorControl/mechanical_brake.cpp | 13 +++++--- Firmware/MotorControl/mechanical_brake.hpp | 5 +-- Firmware/odrive-interface.yaml | 9 ++++- docs/interfaces.md | 38 +++++++++++----------- docs/mechanical-brakes.md | 4 --- tools/odrive/enums.py | 2 ++ 7 files changed, 47 insertions(+), 32 deletions(-) diff --git a/Firmware/MotorControl/main.cpp b/Firmware/MotorControl/main.cpp index c1af09f4..225c01b1 100644 --- a/Firmware/MotorControl/main.cpp +++ b/Firmware/MotorControl/main.cpp @@ -411,7 +411,8 @@ extern "C" int main(void) { GPIO_InitStruct.Pin = get_gpio(i).pin_mask_; // Set Alternate Function setting for this GPIO mode - if (mode == ODriveIntf::GPIO_MODE_DIGITAL || mode == ODriveIntf::GPIO_MODE_ANALOG_IN) { + if (mode == ODriveIntf::GPIO_MODE_DIGITAL || mode == ODriveIntf::GPIO_MODE_ANALOG_IN + || mode == ODriveIntf::GPIO_MODE_MECH_BRAKE) { GPIO_InitStruct.Alternate = 0; } else { auto it = std::find_if( @@ -497,6 +498,11 @@ extern "C" int main(void) { GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; } break; + case ODriveIntf::GPIO_MODE_MECH_BRAKE: { + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + } break; default: { odrv.misconfigured_ = true; continue; diff --git a/Firmware/MotorControl/mechanical_brake.cpp b/Firmware/MotorControl/mechanical_brake.cpp index 591efc62..b70334ff 100644 --- a/Firmware/MotorControl/mechanical_brake.cpp +++ b/Firmware/MotorControl/mechanical_brake.cpp @@ -1,6 +1,7 @@ #include bool MechanicalBrake::apply_config() { + config_.parent = this; set_enabled(config_.enabled); return true; } @@ -14,10 +15,12 @@ void MechanicalBrake::release() { } void MechanicalBrake::set_enabled(bool enable) { - if (config_.gpio_num != 0) { - Stm32Gpio gpio = get_gpio(config_.gpio_num); - if (enable) { - gpio.config(GPIO_MODE_OUTPUT_PP, config_.pulldown ? GPIO_PULLDOWN : GPIO_PULLUP); - } + Stm32Gpio gpio = get_gpio(config_.gpio_num); + + // We need this flag to alert the system to the configuration on boot + odrv.config_.gpio_modes[config_.gpio_num] = ODriveIntf::GPIO_MODE_MECH_BRAKE; + + if (enable) { + gpio.config(GPIO_MODE_OUTPUT_PP, GPIO_NOPULL, GPIO_SPEED_FREQ_LOW); } } \ No newline at end of file diff --git a/Firmware/MotorControl/mechanical_brake.hpp b/Firmware/MotorControl/mechanical_brake.hpp index 240e7ed4..ae8373fd 100644 --- a/Firmware/MotorControl/mechanical_brake.hpp +++ b/Firmware/MotorControl/mechanical_brake.hpp @@ -1,13 +1,14 @@ #ifndef __MECHANICAL_BRAKE_HPP #define __MECHANICAL_BRAKE_HPP -class MechanicalBrake { +#include + +class MechanicalBrake : public ODriveIntf::MechanicalBrakeIntf { public: struct Config_t { uint16_t gpio_num = 0; bool enabled = false; bool is_active_low = true; - bool pulldown = true; // custom setters MechanicalBrake* parent = nullptr; diff --git a/Firmware/odrive-interface.yaml b/Firmware/odrive-interface.yaml index 26491c4d..39108079 100644 --- a/Firmware/odrive-interface.yaml +++ b/Firmware/odrive-interface.yaml @@ -925,7 +925,13 @@ interfaces: gpio_num: {type: uint16, c_setter: set_gpio_num} enabled: {type: bool, c_setter: set_enabled} is_active_low: bool - pulldown: bool + functions: + engage: + doc: | + This function engages the mechanical brake if one is present and enabled. + release: + doc: | + This function releases the mecahncal brake if one is present and enabled. valuetypes: ODrive.GpioMode: @@ -950,6 +956,7 @@ valuetypes: Enc0: {doc: The pin is used by quadrature encoder 0.} Enc1: {doc: The pin is used by quadrature encoder 1.} Enc2: {doc: This mode is not supported on ODrive v3.x.} + MechBrake: {doc: This is to support external mechanical brakes.} ODrive.Can.Protocol: values: {Simple: } diff --git a/docs/interfaces.md b/docs/interfaces.md index 93297657..090948f4 100644 --- a/docs/interfaces.md +++ b/docs/interfaces.md @@ -18,25 +18,25 @@ The ODrive can be controlled over various ports and protocols. If you're comfort ## Pinout -| # | Label | `GPIO_MODE_DIGITAL` | `GPIO_MODE_ANALOG_IN` | `GPIO_MODE_UART0` | `GPIO_MODE_PWM0` | `GPIO_MODE_CAN0` | `GPIO_MODE_I2C0` | `GPIO_MODE_ENC0` | `GPIO_MODE_ENC1` | -|----|---------------|------------------------|-----------------------|-------------------|------------------|------------------|------------------|------------------|------------------| -| 0 | _not a pin_ | | | | | | | | | -| 1 | GPIO1 (+) | general purpose | analog input | **UART0.TX** | PWM0.0 | | | | | -| 2 | GPIO2 (+) | general purpose | analog input | **UART0.RX** | PWM0.1 | | | | | -| 3 | GPIO3 | general purpose | **analog input** | | PWM0.2 | | | | | -| 4 | GPIO4 | general purpose | **analog input** | | PWM0.3 | | | | | -| 5 | GPIO5 | general purpose | **analog input** (*) | | | | | | | -| 6 | GPIO6 (*) (+) | **general purpose** | | | | | | | | -| 7 | GPIO7 (*) (+) | **general purpose** | | | | | | | | -| 8 | GPIO8 (*) (+) | **general purpose** | | | | | | | | -| 9 | M0.A | general purpose | | | | | | **ENC0.A** | | -| 10 | M0.B | general purpose | | | | | | **ENC0.B** | | -| 11 | M0.Z | **general purpose** | | | | | | | | -| 12 | M1.A | general purpose | | | | | I2C.SCL | | **ENC1.A** | -| 13 | M1.B | general purpose | | | | | I2C.SDA | | **ENC1.B** | -| 14 | M1.Z | **general purpose** | | | | | | | | -| 15 | _not exposed_ | general purpose | | | | **CAN0.RX** | I2C.SCL | | | -| 16 | _not exposed_ | general purpose | | | | **CAN0.TX** | I2C.SDA | | | +| # | Label | `GPIO_MODE_DIGITAL` | `GPIO_MODE_ANALOG_IN` | `GPIO_MODE_UART0` | `GPIO_MODE_PWM0` | `GPIO_MODE_CAN0` | `GPIO_MODE_I2C0` | `GPIO_MODE_ENC0` | `GPIO_MODE_ENC1` | `GPIO_MODE_MECH_BRAKE` | +|----|---------------|------------------------|-----------------------|-------------------|------------------|------------------|------------------|------------------|------------------|------------------------| +| 0 | _not a pin_ | | | | | | | | | | +| 1 | GPIO1 (+) | general purpose | analog input | **UART0.TX** | PWM0.0 | | | | | mechanical brake | +| 2 | GPIO2 (+) | general purpose | analog input | **UART0.RX** | PWM0.1 | | | | | mechanical brake | +| 3 | GPIO3 | general purpose | **analog input** | | PWM0.2 | | | | | mechanical brake | +| 4 | GPIO4 | general purpose | **analog input** | | PWM0.3 | | | | | mechanical brake | +| 5 | GPIO5 | general purpose | **analog input** (*) | | | | | | | mechanical brake | +| 6 | GPIO6 (*) (+) | **general purpose** | | | | | | | | mechanical brake | +| 7 | GPIO7 (*) (+) | **general purpose** | | | | | | | | mechanical brake | +| 8 | GPIO8 (*) (+) | **general purpose** | | | | | | | | mechanical brake | +| 9 | M0.A | general purpose | | | | | | **ENC0.A** | | | +| 10 | M0.B | general purpose | | | | | | **ENC0.B** | | | +| 11 | M0.Z | **general purpose** | | | | | | | | | +| 12 | M1.A | general purpose | | | | | I2C.SCL | | **ENC1.A** | | +| 13 | M1.B | general purpose | | | | | I2C.SDA | | **ENC1.B** | | +| 14 | M1.Z | **general purpose** | | | | | | | | | +| 15 | _not exposed_ | general purpose | | | | **CAN0.RX** | I2C.SCL | | | | +| 16 | _not exposed_ | general purpose | | | | **CAN0.TX** | I2C.SDA | | | | (*) ODrive v3.5 and later
diff --git a/docs/mechanical-brakes.md b/docs/mechanical-brakes.md index dc2cdaf6..ae3ce821 100644 --- a/docs/mechanical-brakes.md +++ b/docs/mechanical-brakes.md @@ -16,7 +16,6 @@ Name | Type | Default gpio_num | int | 0 enabled | boolean | false is_active_low | boolean | true -pulldown | boolean | true ### gpio_num The GPIO pin number, according to the silkscreen labels on ODrive. Set with these commands: @@ -33,9 +32,6 @@ Enables/disables the operation of the mechanical brake. ### is_active_low Most safety braking systems are active low, e.g. when the power is off, the brake is on. If the system uses brake drive electronics which use active high logic, flip this bit then reconsider the safety implications of your design... -### pulldown -If `true`, it enables the GPIO pulldown resistor. If `false`, it enables the GPIO pullup resistor. - ### Example Let's say we're hacking away on an old ABB robotic arm. We've wired a 24V brake drive circuit triggered by GPIO5. When GPIO5 is driven, it will release the brakes on the axis we're moving. diff --git a/tools/odrive/enums.py b/tools/odrive/enums.py index 17409599..8ca03c21 100644 --- a/tools/odrive/enums.py +++ b/tools/odrive/enums.py @@ -16,6 +16,7 @@ GPIO_MODE_PWM0 = 8 GPIO_MODE_ENC0 = 9 GPIO_MODE_ENC1 = 10 GPIO_MODE_ENC2 = 11 +GPIO_MODE_MECH_BRAKE = 12 # ODrive.Can.Protocol PROTOCOL_SIMPLE = 0 @@ -45,6 +46,7 @@ ENCODER_MODE_SINCOS = 2 ENCODER_MODE_SPI_ABS_CUI = 256 ENCODER_MODE_SPI_ABS_AMS = 257 ENCODER_MODE_SPI_ABS_AEAT = 258 +ENCODER_MODE_SPI_ABS_RLS = 259 # ODrive.Controller.ControlMode CONTROL_MODE_VOLTAGE_CONTROL = 0