From 49dcf47b37ec4a644aff3ea343886a518a44009a Mon Sep 17 00:00:00 2001 From: Samuel Sadok Date: Tue, 24 Apr 2018 12:20:08 -0700 Subject: [PATCH] [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 | 21 ++++++++++++++----- 2 files changed, 36 insertions(+), 18 deletions(-) diff --git a/Firmware/Board/v3/Src/main.c b/Firmware/Board/v3/Src/main.c index 20f4ba8a..1691e4a6 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 4f8453d8..2ca2a066 100644 --- a/Firmware/MotorControl/commands.cpp +++ b/Firmware/MotorControl/commands.cpp @@ -109,11 +109,6 @@ void motors_run_anticogging_calibration_func() { } } -void enter_dfu_mode() { - *((unsigned long *)0x2001C000) = 0xDEADBEEF; - NVIC_SystemReset(); -} - #if HW_VERSION_MAJOR == 3 // Determine start address of the OTP struct: // The OTP is organized into 16-byte blocks. @@ -142,6 +137,22 @@ const uint8_t fw_version_minor = FW_VERSION_MINOR; const uint8_t fw_version_revision = FW_VERSION_REVISION; const uint8_t fw_version_unreleased = FW_VERSION_UNRELEASED; // 0 for official releases, 1 otherwise +void enter_dfu_mode() { + if ((board_version_major == 3) && (board_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. // TODO: Autogenerate this table. It will come up again very soon in the Arduino library. // clang-format off