From 57f6b71321180a739227f73ccff7cb8592f04d70 Mon Sep 17 00:00:00 2001 From: Matthew Moore Date: Sun, 15 Apr 2018 12:52:37 -0700 Subject: [PATCH 1/8] Change encoder.calibrated to encoder.manually_calibrated --- Firmware/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Firmware/README.md b/Firmware/README.md index 214afe68..2acd6474 100644 --- a/Firmware/README.md +++ b/Firmware/README.md @@ -251,7 +251,7 @@ If you have an encoder with an index (Z) signal, you may avoid having to do the * Since you will only do this once, it is recommended that you mechanically disengage the motor from anything other than the encoder, so it can spin freely. * All the parameters we will be modifying are in the motor structs at the top of [MotorControl/low_level.c](MotorControl/low_level.c). -* Set `.encoder.use_index = true` and `.encoder.calibrated = false`. +* Set `.encoder.use_index = true` and `.encoder.manually_calibrated = false`. * Flash this configuration, and let the motor scan for the index pulse and then complete the encoder calibration. * Run `explore_odrive.py`, check [Communicating over USB or UART](#communicating-over-usb-or-uart) for instructions on how to do that. * Enter the following to print out the calibration parameters (substitute the motor number you are calibrating for ``): @@ -259,7 +259,7 @@ If you have an encoder with an index (Z) signal, you may avoid having to do the * `my_odrive.motor.encoder.motor_dir` - This should print 1 or -1. * Copy these numbers to the corresponding entries in low_level.c: `.encoder.encoder_offset` and `.encoder.motor_dir`. * _Warning_: Please be careful to enter the correct numbers, and not to confuse the motor channels. Incorrect values may cause the motor to spin out of control. -* Set `.encoder.calibrated = true`. +* Set `.encoder.manually_calibrated = true`. * Flash this configuration and check that the motor scans for the index pulse but skips the encoder calibration. * Congratulations, you are now done. You may now attach the motor to your mechanical load. * If you wish to scan for the index pulse in the other direction (if for example your axis usually starts close to a hard-stop), you can set a negative value in `.encoder.idx_search_speed`. From 87a04bd9f62850f69c76afef31383dde29e6179b Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Tue, 17 Apr 2018 18:01:41 -0700 Subject: [PATCH 2/8] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 16613f9a..32f3a08c 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ ODrive v3.3 and onward have 5V tolerant GPIO pins. To enable step/dir mode for the GPIO, please see [Setting the GPIO mode](Firmware/README.md#communication-configuration). There is also a new config variable called `counts_per_step`, which specifies how many encoder counts a "step" corresponds to. It can be any floating point value. -The maximum step rate is pending tests, but it should handle at least 16kHz. If you want's to test it, please be aware that the failure mode on too high step rates is expected to be that the motors shuts down and coasts. +The maximum step rate is pending tests, but it should handle at least 32kHz. If you want's to test it, please be aware that the failure mode on too high step rates is expected to be that the motors shuts down and coasts. Please be aware that there is no enable line right now, and the step/direction interface is enabled by default, and remains active as long as the ODrive is in position control mode. By default the ODrive starts in position control mode, so you don't need to send any commands over USB to get going. You can still send USB commands if you want to. From 64505c0428d21881861b6c7229e2b7970aba2c65 Mon Sep 17 00:00:00 2001 From: Samuel Sadok Date: Mon, 23 Apr 2018 22:39:46 -0700 Subject: [PATCH 3/8] [HOTFIX] add delay before entering DFU mode, may short the brake resistor FETs otherwise --- Firmware/Board/v3/Src/main.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Firmware/Board/v3/Src/main.c b/Firmware/Board/v3/Src/main.c index 644799de..20f4ba8a 100644 --- a/Firmware/Board/v3/Src/main.c +++ b/Firmware/Board/v3/Src/main.c @@ -100,6 +100,21 @@ int main(void) { /* USER CODE BEGIN 1 */ + /* + * This wait loop works around an obscure timing issue. + * When the transition NVIC_SystemReset() => STM bootloader happens quickly, + * there is a yet unexplained phenomenon where both the high side and low side + * brake resistor FETs would turn on simultaneously for about 2.5ms. + * This manifests in an audible click and may lead to failure of the FETs. + * When adding a delay before entering DFU mode the issue does not occur. + * + * This loop takes about 5 cycles per iteration, so the delay + * is about 1/168000kHz*5*1000000 = 30ms + */ + for (size_t i = 0; i < 1000000; ++i) { + __NOP(); + } + /* We could jump to the bootloader directly on demand without rebooting but that requires us to reset several peripherals and interrupts for it to function correctly. Therefore it's easier to just reset the entire chip. */ From 9b641e326e75cfd3561bc16dfa83c99904b6b4a1 Mon Sep 17 00:00:00 2001 From: Samuel Sadok Date: Tue, 24 Apr 2018 12:20:08 -0700 Subject: [PATCH 4/8] [firmware] disable DFU feature for board version <= 3.4 because it can break the board --- Firmware/Board/v3/Src/main.c | 33 ++++++++++++++++++------------ Firmware/MotorControl/commands.cpp | 15 ++++++++++++-- 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/Firmware/Board/v3/Src/main.c b/Firmware/Board/v3/Src/main.c index 20f4ba8a..7b9d2c6c 100644 --- a/Firmware/Board/v3/Src/main.c +++ b/Firmware/Board/v3/Src/main.c @@ -100,19 +100,26 @@ int main(void) { /* USER CODE BEGIN 1 */ - /* - * This wait loop works around an obscure timing issue. - * When the transition NVIC_SystemReset() => STM bootloader happens quickly, - * there is a yet unexplained phenomenon where both the high side and low side - * brake resistor FETs would turn on simultaneously for about 2.5ms. - * This manifests in an audible click and may lead to failure of the FETs. - * When adding a delay before entering DFU mode the issue does not occur. - * - * This loop takes about 5 cycles per iteration, so the delay - * is about 1/168000kHz*5*1000000 = 30ms - */ - for (size_t i = 0; i < 1000000; ++i) { - __NOP(); + if(*((unsigned long *)0x2001C000) == 0xDEADFE75) { + /* The STM DFU bootloader enables internal pull-up resistors on PB10 (AUX_H) + * and PB11 (AUX_L), thereby causing shoot-through on the brake resistor + * FETs and obliterating them unless external 3.3k pull-down resistors are + * present. Pull-downs are only present on ODrive 3.5 or newer. + * On older boards we disable DFU by default but if the user insists + * there's only one thing left that might save it: time. + * The brake resistor gate driver needs a certain 10V supply (GVDD) to + * make it work. This voltage is supplied by the motor gate drivers which get + * disabled at system reset. So over time GVDD voltage _should_ below + * dangerous levels. This is completely handwavy and should not be relied on + * so you are on your own on if you ignore this warning. + * + * This loop takes 5 cycles per iteration and at this point the system runs + * on the internal 16MHz RC oscillator so the delay is about 2 seconds. + */ + for (size_t i = 0; i < (16000000UL / 5UL * 2UL); ++i) { + __NOP(); + } + *((unsigned long *)0x2001C000) = 0xDEADBEEF; } /* We could jump to the bootloader directly on demand without rebooting diff --git a/Firmware/MotorControl/commands.cpp b/Firmware/MotorControl/commands.cpp index a163ae4c..ced0574d 100644 --- a/Firmware/MotorControl/commands.cpp +++ b/Firmware/MotorControl/commands.cpp @@ -109,8 +109,19 @@ void motors_run_anticogging_calibration_func() { } void enter_dfu_mode() { - *((unsigned long *)0x2001C000) = 0xDEADBEEF; - NVIC_SystemReset(); + if ((HW_VERSION_MAJOR == 3) && (HW_VERSION_MINOR >= 5)) { + *((unsigned long *)0x2001C000) = 0xDEADBEEF; + NVIC_SystemReset(); + } else { + /* + * DFU mode is only allowed on board version >= 3.5 because it can burn + * the brake resistor FETs on older boards. + * If you really want to use it on an older board, add 3.3k pull-down resistors + * to the AUX_L and AUX_H signals and _only then_ uncomment these lines. + */ + //*((unsigned long *)0x2001C000) = 0xDEADFE75; + //NVIC_SystemReset(); + } } // This table specifies which fields and functions are exposed on the USB and UART ports. From e46040a29b6b7bd0a3a1f59a949ad5cc7dc1298f Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Tue, 24 Apr 2018 12:54:03 -0700 Subject: [PATCH 5/8] DFU not available for v3.4 or earlier --- Firmware/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Firmware/README.md b/Firmware/README.md index 2acd6474..5306901b 100644 --- a/Firmware/README.md +++ b/Firmware/README.md @@ -49,7 +49,7 @@ __CONFIG_STEP_DIR__: Set to `y` to use the GPIO1 and GPIO2 for step/direction in

## Downloading and Installing Tools ### Getting a programmer -__Note:__ If you don't plan to make major firmware modifications you can use the built-in DFU feature. +__Note:__ If you have ODrive v3.5 and newer, and don't plan to make major firmware modifications you can use the built-in DFU feature. In this case you don't need an SWD programmer and you can skip OpenOCD related instructions. Get a programmer that supports SWD (Serial Wire Debugging) and is ST-link v2 compatible. You can get them really cheap on [eBay](http://www.ebay.co.uk/itm/ST-Link-V2-Emulator-Downloader-Programming-Mini-Unit-STM8-STM32-with-20CM-Line-/391173940927?hash=item5b13c8a6bf:g:3g8AAOSw~OdVf-Tu) or many other places. @@ -96,7 +96,7 @@ After installing all of the above, open a Git Bash shell. Continue at section [B * Run `make` in the `Firmware` directory. ### Flashing the firmware (standalone device) -Note: ODrive v3.4 and earlier require you to flash with the external programmer first (see below), before you can reflash in standalone mode. +Note: This method of updating the firmware is only supported on ODrive v3.5 and newer. If you have an older board you must instead use the method in the [next section](#flashing-the-firmware). * __Windows__: Use the [Zadig](http://zadig.akeo.ie/) utility to set ODrive (not STLink!) driver to libusb-win32. * If 'Odrive version 3.x' is not in the list of devices upon opening Zadig, check 'List All Devices' from the options menu. With the Odrive selected in the device list choose 'libusb-win32' from the target driver list and select the large 'install driver' button. * Run `make dfu` in the `Firmware` directory. From 70a86c7d5701e3cc6aebf5adec4602cf32a6e360 Mon Sep 17 00:00:00 2001 From: Samuel Sadok Date: Tue, 24 Apr 2018 13:16:38 -0700 Subject: [PATCH 6/8] disable dfu.py --- tools/dfu.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/dfu.py b/tools/dfu.py index 7ad27bf8..8a890507 100755 --- a/tools/dfu.py +++ b/tools/dfu.py @@ -14,6 +14,9 @@ import usb.core import usb.util import odrive.core +print("The DFU script had to be disabled because of it potentially breaking the board.") +sys.exit(1) + # We are interactively printing status messages, so flush by default import functools print = functools.partial(print, flush=True) From f5b4ab455503036e76f5b0c3f2050c2299499edd Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Tue, 24 Apr 2018 15:37:41 -0700 Subject: [PATCH 7/8] update mac run instructions --- Firmware/README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Firmware/README.md b/Firmware/README.md index 5306901b..8fef2b05 100644 --- a/Firmware/README.md +++ b/Firmware/README.md @@ -73,9 +73,10 @@ To compile the program, you first need to install the prerequisite tools: * No additional USB CDC driver should be required on Linux. #### Mac: -* `brew cask install gcc-arm-embedded`: GCC toolchain+debugger -* `brew cask install osxfuse; brew install tup`: Build tool -* `brew install openocd`: Programmer +First install [Homebrew](https://brew.sh/). Then you can run these commands in Terminal: +* `brew cask install gcc-arm-embedded`: to install GCC toolchain+debugger +* `brew cask install osxfuse; brew install tup`: to install the build tool +* `brew install openocd`: to install the programmer tool #### Windows: Install the following: @@ -165,7 +166,8 @@ pip install pyusb pyserial 5. __Windows__: Use the [Zadig](http://zadig.akeo.ie/) utility to set ODrive (not STLink!) driver to libusb-win32. * If 'Odrive version 3.x' is not in the list of devices upon opening Zadig, check 'List All Devices' from the options menu. With the Odrive selected in the device list choose 'libusb-win32' from the target driver list and select the large 'install driver' button. 6. Open the bash prompt in the `ODrive/tools/` folder. -7. Run `python3 demo.py` or `python3 explore_odrive.py`. +7. Run `python3 demo.py` or `python3 explore_odrive.py`. +- __Mac__: `python3 demo.py --discover serial` or `python3 explore_odrive.py --discover serial` - `demo.py` is a very simple script which will make motor 0 turn back and forth. Use this as an example if you want to control the ODrive yourself programatically. - `explore_odrive.py` drops you into an interactive python shell where you can explore and edit the parameters that are available on your device. For instance `my_odrive.motor0.pos_setpoint = 10000` makes motor0 move to position 10000. To connect over serial instead of USB run `./tools/explore_odrive.py --discover serial`. From 968131185232125ba64ee39512ab1e52c804b91c Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Tue, 24 Apr 2018 15:39:30 -0700 Subject: [PATCH 8/8] update mac run instructions --- Firmware/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/README.md b/Firmware/README.md index 8fef2b05..10a1051e 100644 --- a/Firmware/README.md +++ b/Firmware/README.md @@ -167,7 +167,7 @@ pip install pyusb pyserial * If 'Odrive version 3.x' is not in the list of devices upon opening Zadig, check 'List All Devices' from the options menu. With the Odrive selected in the device list choose 'libusb-win32' from the target driver list and select the large 'install driver' button. 6. Open the bash prompt in the `ODrive/tools/` folder. 7. Run `python3 demo.py` or `python3 explore_odrive.py`. -- __Mac__: `python3 demo.py --discover serial` or `python3 explore_odrive.py --discover serial` +- __Mac__: instead run: `python3 demo.py --discover serial` or `python3 explore_odrive.py --discover serial` - `demo.py` is a very simple script which will make motor 0 turn back and forth. Use this as an example if you want to control the ODrive yourself programatically. - `explore_odrive.py` drops you into an interactive python shell where you can explore and edit the parameters that are available on your device. For instance `my_odrive.motor0.pos_setpoint = 10000` makes motor0 move to position 10000. To connect over serial instead of USB run `./tools/explore_odrive.py --discover serial`.