From c43f7b5f5c72a0e35a45646cfd692ff93b81c064 Mon Sep 17 00:00:00 2001 From: Maxim Buzdalov Date: Tue, 14 May 2024 09:16:21 +1000 Subject: [PATCH 1/5] AP_ESC_Telem: add support for Extended DShot Telemetry v2 --- libraries/AP_ESC_Telem/AP_ESC_Telem.cpp | 115 +++++++++++++++++- libraries/AP_ESC_Telem/AP_ESC_Telem.h | 6 + libraries/AP_ESC_Telem/AP_ESC_Telem_Backend.h | 8 ++ libraries/AP_ESC_Telem/LogStructure.h | 36 +++++- 4 files changed, 160 insertions(+), 5 deletions(-) diff --git a/libraries/AP_ESC_Telem/AP_ESC_Telem.cpp b/libraries/AP_ESC_Telem/AP_ESC_Telem.cpp index e6f3bd523c392..9a3e34f84251e 100644 --- a/libraries/AP_ESC_Telem/AP_ESC_Telem.cpp +++ b/libraries/AP_ESC_Telem/AP_ESC_Telem.cpp @@ -468,6 +468,15 @@ void AP_ESC_Telem::update_telem_data(const uint8_t esc_index, const AP_ESC_Telem telemdata.usage_s = new_data.usage_s; } +#if AP_EXTENDED_DSHOT_TELEM_V2_ENABLED + if (data_mask & AP_ESC_Telem_Backend::TelemetryType::EDT2_STATUS) { + telemdata.edt2_status = merge_edt2_status(telemdata.edt2_status, new_data.edt2_status); + } + if (data_mask & AP_ESC_Telem_Backend::TelemetryType::EDT2_STRESS) { + telemdata.edt2_stress = merge_edt2_stress(telemdata.edt2_stress, new_data.edt2_stress); + } +#endif + telemdata.count++; telemdata.types |= data_mask; telemdata.last_update_ms = AP_HAL::millis(); @@ -499,6 +508,63 @@ void AP_ESC_Telem::update_rpm(const uint8_t esc_index, const float new_rpm, cons #endif } +#if AP_EXTENDED_DSHOT_TELEM_V2_ENABLED + +// The following is based on https://github.com/bird-sanctuary/extended-dshot-telemetry. +// For the following part we explain the bits of Extended DShot Telemetry v2 status telemetry: +// - bits 0-3: the "stress level" +// - bit 5: the "error" bit (e.g. the stall event in Bluejay) +// - bit 6: the "warning" bit (e.g. the desync event in Bluejay) +// - bit 7: the "alert" bit (e.g. the demag event in Bluejay) + +// Since logger can read out telemetry values less frequently than they are updated, +// it makes sense to aggregate these status bits, and to collect the maximum observed stress level. +// To reduce the logging rate of the EDT2 messages, we will try to log them only once a new frame comes. +// To track this, we are going to (ab)use bit 15 of the field: 1 means there is something to write. + +// EDTv2 also features separate "stress" messages. +// These come more frequently, and are scaled differently (the allowed range is from 0 to 255), +// so we have to log them separately. + +constexpr uint16_t EDT2_TELEM_UPDATED = 0x8000U; +constexpr uint16_t EDT2_STRESS_0F_MASK = 0xfU; +constexpr uint16_t EDT2_STRESS_FF_MASK = 0xffU; +constexpr uint16_t EDT2_ERROR_MASK = 0x20U; +constexpr uint16_t EDT2_WARNING_MASK = 0x40U; +constexpr uint16_t EDT2_ALERT_MASK = 0x80U; +constexpr uint16_t EDT2_ALL_BITS = EDT2_ERROR_MASK | EDT2_WARNING_MASK | EDT2_ALERT_MASK; + +#define EDT2_HAS_NEW_DATA(status) bool((status) & EDT2_TELEM_UPDATED) +#define EDT2_STRESS_FROM_STATUS(status) uint8_t((status) & EDT2_STRESS_0F_MASK) +#define EDT2_ERROR_BIT_FROM_STATUS(status) bool((status) & EDT2_ERROR_MASK) +#define EDT2_WARNING_BIT_FROM_STATUS(status) bool((status) & EDT2_WARNING_MASK) +#define EDT2_ALERT_BIT_FROM_STATUS(status) bool((status) & EDT2_ALERT_MASK) +#define EDT2_STRESS_FROM_STRESS(stress) uint8_t((stress) & EDT2_STRESS_FF_MASK) + +uint16_t AP_ESC_Telem::merge_edt2_status(uint16_t old_status, uint16_t new_status) +{ + if (EDT2_HAS_NEW_DATA(old_status)) { + new_status = uint16_t( + (old_status & ~EDT2_STRESS_0F_MASK) | // old status except for the stress is preserved + (new_status & EDT2_ALL_BITS) | // all new status bits are included + MAX(old_status & EDT2_STRESS_0F_MASK, new_status & EDT2_STRESS_0F_MASK) // the stress is maxed out + ); + } + return EDT2_TELEM_UPDATED | new_status; +} + +uint16_t AP_ESC_Telem::merge_edt2_stress(uint16_t old_stress, uint16_t new_stress) +{ + if (EDT2_HAS_NEW_DATA(old_stress)) { + new_stress = uint16_t( + MAX(old_stress & EDT2_STRESS_FF_MASK, new_stress & EDT2_STRESS_FF_MASK) // the stress is maxed out + ); + } + return EDT2_TELEM_UPDATED | new_stress; +} + +#endif // AP_EXTENDED_DSHOT_TELEM_V2_ENABLED + void AP_ESC_Telem::update() { #if HAL_LOGGING_ENABLED @@ -507,7 +573,7 @@ void AP_ESC_Telem::update() for (uint8_t i = 0; i < ESC_TELEM_MAX_ESCS; i++) { const volatile AP_ESC_Telem_Backend::RpmData &rpmdata = _rpm_data[i]; - const volatile AP_ESC_Telem_Backend::TelemetryData &telemdata = _telem_data[i]; + volatile AP_ESC_Telem_Backend::TelemetryData &telemdata = _telem_data[i]; // Push received telemetry data into the logging system if (logger && logger->logging_enabled()) { if (telemdata.last_update_ms != _last_telem_log_ms[i] @@ -544,6 +610,51 @@ void AP_ESC_Telem::update() _last_telem_log_ms[i] = telemdata.last_update_ms; _last_rpm_log_us[i] = rpmdata.last_update_us; } + +#if AP_EXTENDED_DSHOT_TELEM_V2_ENABLED + // Write an EDTv2 message, if there is any update + uint16_t edt2_status = telemdata.edt2_status; + uint16_t edt2_stress = telemdata.edt2_stress; + if (EDT2_HAS_NEW_DATA(edt2_status | edt2_stress)) { + // Could probably be faster/smaller with bitmasking, but not sure + uint8_t status = 0; + if (EDT2_HAS_NEW_DATA(edt2_stress)) { + status |= uint8_t(log_Edt2_Status::HAS_STRESS_DATA); + } + if (EDT2_HAS_NEW_DATA(edt2_status)) { + status |= uint8_t(log_Edt2_Status::HAS_STATUS_DATA); + } + if (EDT2_ALERT_BIT_FROM_STATUS(edt2_status)) { + status |= uint8_t(log_Edt2_Status::ALERT_BIT); + } + if (EDT2_WARNING_BIT_FROM_STATUS(edt2_status)) { + status |= uint8_t(log_Edt2_Status::WARNING_BIT); + } + if (EDT2_ERROR_BIT_FROM_STATUS(edt2_status)) { + status |= uint8_t(log_Edt2_Status::ERROR_BIT); + } + // An EDT2 status message is: + // id: starts from 0 + // stress: the current stress which comes from edt2_stress + // max_stress: the maximum stress which comes from edt2_status + // status: the status bits which come from both + const struct log_Edt2 pkt_edt2{ + LOG_PACKET_HEADER_INIT(uint8_t(LOG_EDT2_MSG)), + time_us : now_us64, + instance : i, + stress : EDT2_STRESS_FROM_STRESS(edt2_stress), + max_stress : EDT2_STRESS_FROM_STATUS(edt2_status), + status : status, + }; + if (AP::logger().WriteBlock_first_succeed(&pkt_edt2, sizeof(pkt_edt2))) { + // Only clean the telem_updated bits if the write succeeded. + // This is important because, if rate limiting is enabled, + // the log-on-change behavior may lose a lot of entries + telemdata.edt2_status &= ~EDT2_TELEM_UPDATED; + telemdata.edt2_stress &= ~EDT2_TELEM_UPDATED; + } + } +#endif // AP_EXTENDED_DSHOT_TELEM_V2_ENABLED } } #endif // HAL_LOGGING_ENABLED @@ -608,4 +719,4 @@ AP_ESC_Telem &esc_telem() }; -#endif +#endif // HAL_WITH_ESC_TELEM diff --git a/libraries/AP_ESC_Telem/AP_ESC_Telem.h b/libraries/AP_ESC_Telem/AP_ESC_Telem.h index ae40ede597079..4c5d0719915b8 100644 --- a/libraries/AP_ESC_Telem/AP_ESC_Telem.h +++ b/libraries/AP_ESC_Telem/AP_ESC_Telem.h @@ -118,6 +118,12 @@ class AP_ESC_Telem { static bool rpm_data_within_timeout (const volatile AP_ESC_Telem_Backend::RpmData &instance, const uint32_t now_us, const uint32_t timeout_us); static bool was_rpm_data_ever_reported (const volatile AP_ESC_Telem_Backend::RpmData &instance); +#if AP_EXTENDED_DSHOT_TELEM_V2_ENABLED + // helpers that aggregate data in EDTv2 messages + static uint16_t merge_edt2_status(uint16_t old_status, uint16_t new_status); + static uint16_t merge_edt2_stress(uint16_t old_stress, uint16_t new_stress); +#endif + // rpm data volatile AP_ESC_Telem_Backend::RpmData _rpm_data[ESC_TELEM_MAX_ESCS]; // telemetry data diff --git a/libraries/AP_ESC_Telem/AP_ESC_Telem_Backend.h b/libraries/AP_ESC_Telem/AP_ESC_Telem_Backend.h index b6d6725a55fa1..e46eb48ceb6b0 100644 --- a/libraries/AP_ESC_Telem/AP_ESC_Telem_Backend.h +++ b/libraries/AP_ESC_Telem/AP_ESC_Telem_Backend.h @@ -19,6 +19,10 @@ class AP_ESC_Telem_Backend { uint32_t last_update_ms; // last update time in milliseconds, determines whether active uint16_t types; // telemetry types present uint16_t count; // number of times updated +#if AP_EXTENDED_DSHOT_TELEM_V2_ENABLED + uint16_t edt2_status; // status reported by Extended DShot Telemetry v2 + uint16_t edt2_stress; // stress reported in dedicated messages by Extended DShot Telemetry v2 +#endif // return true if the data is stale bool stale(uint32_t now_ms=0) const volatile; @@ -42,6 +46,10 @@ class AP_ESC_Telem_Backend { USAGE = 1 << 5, TEMPERATURE_EXTERNAL = 1 << 6, MOTOR_TEMPERATURE_EXTERNAL = 1 << 7, +#if AP_EXTENDED_DSHOT_TELEM_V2_ENABLED + EDT2_STATUS = 1 << 8, + EDT2_STRESS = 1 << 9, +#endif }; diff --git a/libraries/AP_ESC_Telem/LogStructure.h b/libraries/AP_ESC_Telem/LogStructure.h index a3c0dc791cd3d..c50ac47b95e97 100644 --- a/libraries/AP_ESC_Telem/LogStructure.h +++ b/libraries/AP_ESC_Telem/LogStructure.h @@ -3,7 +3,8 @@ #include #define LOG_IDS_FROM_ESC_TELEM \ - LOG_ESC_MSG + LOG_ESC_MSG, \ + LOG_EDT2_MSG // @LoggerMessage: ESC // @Description: Feedback received from ESCs @@ -31,6 +32,35 @@ struct PACKED log_Esc { float error_rate; }; -#define LOG_STRUCTURE_FROM_ESC_TELEM \ +enum class log_Edt2_Status : uint8_t { + HAS_STRESS_DATA = 1U<<0, // true if the message contains up-to-date stress data + HAS_STATUS_DATA = 1U<<1, // true if the message contains up-to-date status data + ALERT_BIT = 1U<<2, // true if the last status had the "alert" bit (e.g. demag) + WARNING_BIT = 1U<<3, // true if the last status had the "warning" bit (e.g. desync) + ERROR_BIT = 1U<<4, // true if the last status had the "error" bit (e.g. stall) +}; + + +// @LoggerMessage: EDT2 +// @Description: Status received from ESCs via Extended DShot telemetry v2 +// @Field: TimeUS: microseconds since system startup +// @Field: Instance: ESC instance number +// @Field: Stress: current stress level (commutation effort), scaled to [0..255] +// @Field: MaxStress: maximum stress level (commutation effort) since arming, scaled to [0..15] +// @Field: Status: status bits +// @FieldBitmaskEnum: Status: log_Edt2_Status +struct PACKED log_Edt2 { + LOG_PACKET_HEADER; + uint64_t time_us; + uint8_t instance; + uint8_t stress; + uint8_t max_stress; + uint8_t status; +}; + +#define LOG_STRUCTURE_FROM_ESC_TELEM \ { LOG_ESC_MSG, sizeof(log_Esc), \ - "ESC", "QBffffcfcf", "TimeUS,Instance,RPM,RawRPM,Volt,Curr,Temp,CTot,MotTemp,Err", "s#qqvAOaO%", "F-00--BCB-" , true }, + "ESC", "QBffffcfcf", "TimeUS,Instance,RPM,RawRPM,Volt,Curr,Temp,CTot,MotTemp,Err", "s#qqvAOaO%", "F-00--BCB-" , true }, \ + { LOG_EDT2_MSG, sizeof(log_Edt2), \ + "EDT2", "QBBBB", "TimeUS,Instance,Stress,MaxStress,Status", "s#---", "F----" , true }, + From 2644ac53670bace7227418d0108fc0658b3113d4 Mon Sep 17 00:00:00 2001 From: Maxim Buzdalov Date: Tue, 14 May 2024 09:16:21 +1000 Subject: [PATCH 2/5] AP_HAL_ChibiOS: add support for Extended DShot Telemetry v2 --- libraries/AP_HAL_ChibiOS/RCOutput_bdshot.cpp | 24 +++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/libraries/AP_HAL_ChibiOS/RCOutput_bdshot.cpp b/libraries/AP_HAL_ChibiOS/RCOutput_bdshot.cpp index cb1c04e29d574..7b2e88089f851 100644 --- a/libraries/AP_HAL_ChibiOS/RCOutput_bdshot.cpp +++ b/libraries/AP_HAL_ChibiOS/RCOutput_bdshot.cpp @@ -755,12 +755,12 @@ bool RCOutput::bdshot_decode_telemetry_from_erpm(uint16_t encodederpm, uint8_t c uint16_t value = (encodederpm & 0x000001ffU); // 9bits #if HAL_WITH_ESC_TELEM uint8_t normalized_chan = chan; -#endif #if HAL_WITH_IO_MCU if (iomcu_enabled) { normalized_chan = chan + chan_offset; } #endif +#endif // HAL_WITH_ESC_TELEM: one can possibly imagine a FC with IOMCU but with ESC_TELEM compiled out... if (!(value & 0x100U) && (_dshot_esc_type == DSHOT_ESC_BLHELI_EDT || _dshot_esc_type == DSHOT_ESC_BLHELI_EDT_S)) { switch (expo) { @@ -796,10 +796,28 @@ bool RCOutput::bdshot_decode_telemetry_from_erpm(uint16_t encodederpm, uint8_t c break; case 0b100: // Debug 1 case 0b101: // Debug 2 - case 0b110: // Stress level - case 0b111: // Status return false; break; + case 0b110: { // Stress level + #if HAL_WITH_ESC_TELEM && AP_EXTENDED_DSHOT_TELEM_V2_ENABLED + TelemetryData t { + .edt2_stress = value + }; + update_telem_data(normalized_chan, t, AP_ESC_Telem_Backend::TelemetryType::EDT2_STRESS); + #endif + return false; + } + break; + case 0b111: { // Status + #if HAL_WITH_ESC_TELEM && AP_EXTENDED_DSHOT_TELEM_V2_ENABLED + TelemetryData t { + .edt2_status = value + }; + update_telem_data(normalized_chan, t, AP_ESC_Telem_Backend::TelemetryType::EDT2_STATUS); + #endif + return false; + } + break; default: // eRPM break; } From 3ea29365b2e1872496e2184e1ae21fa3309f42a6 Mon Sep 17 00:00:00 2001 From: Maxim Buzdalov Date: Tue, 14 May 2024 09:16:22 +1000 Subject: [PATCH 3/5] AP_HAL: add support for Extended DShot Telemetry v2 --- libraries/AP_HAL/AP_HAL_Boards.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/libraries/AP_HAL/AP_HAL_Boards.h b/libraries/AP_HAL/AP_HAL_Boards.h index b2f38945cc68e..24b6a66d3b5c6 100644 --- a/libraries/AP_HAL/AP_HAL_Boards.h +++ b/libraries/AP_HAL/AP_HAL_Boards.h @@ -175,6 +175,19 @@ #define HAL_WITH_IO_MCU_DSHOT HAL_WITH_IO_MCU_BIDIR_DSHOT #endif +#ifndef HAL_REQUIRES_BDSHOT_SUPPORT +#define HAL_REQUIRES_BDSHOT_SUPPORT (defined(HAL_WITH_BIDIR_DSHOT) || HAL_WITH_IO_MCU_BIDIR_DSHOT) +#endif + +// support for Extended DShot Telemetry v2 is enabled only if any kind of such telemetry +// can in principle arrive, either from servo outputs or from IOMCU + +// if not desired, set to 0 - and if IOMCU has bidirectional DShot enabled, recompile it too, +// otherwise the communication to IOMCU breaks! +#ifndef AP_EXTENDED_DSHOT_TELEM_V2_ENABLED +#define AP_EXTENDED_DSHOT_TELEM_V2_ENABLED HAL_REQUIRES_BDSHOT_SUPPORT +#endif + // this is used as a general mechanism to make a 'small' build by // dropping little used features. We use this to allow us to keep // FMUv2 going for as long as possible From 038c423a0a6e331f7fab431f67278b8ac884c850 Mon Sep 17 00:00:00 2001 From: Maxim Buzdalov Date: Tue, 14 May 2024 09:16:23 +1000 Subject: [PATCH 4/5] AP_IOMCU: add support for Extended DShot Telemetry v2 --- libraries/AP_IOMCU/AP_IOMCU.cpp | 6 ++++- libraries/AP_IOMCU/iofirmware/iofirmware.cpp | 25 +++++++++++++------- libraries/AP_IOMCU/iofirmware/ioprotocol.h | 5 ++++ 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/libraries/AP_IOMCU/AP_IOMCU.cpp b/libraries/AP_IOMCU/AP_IOMCU.cpp index 83ebd6e01a748..47b75e8d5e667 100644 --- a/libraries/AP_IOMCU/AP_IOMCU.cpp +++ b/libraries/AP_IOMCU/AP_IOMCU.cpp @@ -453,7 +453,11 @@ void AP_IOMCU::read_telem() TelemetryData t { .temperature_cdeg = int16_t(telem->temperature_cdeg[i]), .voltage = float(telem->voltage_cvolts[i]) * 0.01, - .current = float(telem->current_camps[i]) * 0.01 + .current = float(telem->current_camps[i]) * 0.01, +#if AP_EXTENDED_DSHOT_TELEM_V2_ENABLED + .edt2_status = telem->edt2_status[i], + .edt2_stress = telem->edt2_stress[i], +#endif }; update_telem_data(esc_group * 4 + i, t, telem->types[i]); } diff --git a/libraries/AP_IOMCU/iofirmware/iofirmware.cpp b/libraries/AP_IOMCU/iofirmware/iofirmware.cpp index bb24b0dcad4c0..37d991bd1c8de 100644 --- a/libraries/AP_IOMCU/iofirmware/iofirmware.cpp +++ b/libraries/AP_IOMCU/iofirmware/iofirmware.cpp @@ -635,25 +635,34 @@ void AP_IOMCU_FW::telem_update() uint32_t now_ms = AP_HAL::millis(); for (uint8_t i = 0; i < IOMCU_MAX_TELEM_CHANNELS/4; i++) { + struct page_dshot_telem &dshot_i = dshot_telem[i]; for (uint8_t j = 0; j < 4; j++) { const uint8_t esc_id = (i * 4 + j); if (esc_id >= IOMCU_MAX_TELEM_CHANNELS) { continue; } - dshot_telem[i].error_rate[j] = uint16_t(roundf(hal.rcout->get_erpm_error_rate(esc_id) * 100.0)); + dshot_i.error_rate[j] = uint16_t(roundf(hal.rcout->get_erpm_error_rate(esc_id) * 100.0)); #if HAL_WITH_ESC_TELEM const volatile AP_ESC_Telem_Backend::TelemetryData& telem = esc_telem.get_telem_data(esc_id); // if data is stale then set to zero to avoid phantom data appearing in mavlink if (now_ms - telem.last_update_ms > ESC_TELEM_DATA_TIMEOUT_MS) { - dshot_telem[i].voltage_cvolts[j] = 0; - dshot_telem[i].current_camps[j] = 0; - dshot_telem[i].temperature_cdeg[j] = 0; + dshot_i.voltage_cvolts[j] = 0; + dshot_i.current_camps[j] = 0; + dshot_i.temperature_cdeg[j] = 0; +#if AP_EXTENDED_DSHOT_TELEM_V2_ENABLED + dshot_i.edt2_status[j] = 0; + dshot_i.edt2_stress[j] = 0; +#endif continue; } - dshot_telem[i].voltage_cvolts[j] = uint16_t(roundf(telem.voltage * 100)); - dshot_telem[i].current_camps[j] = uint16_t(roundf(telem.current * 100)); - dshot_telem[i].temperature_cdeg[j] = telem.temperature_cdeg; - dshot_telem[i].types[j] = telem.types; + dshot_i.voltage_cvolts[j] = uint16_t(roundf(telem.voltage * 100)); + dshot_i.current_camps[j] = uint16_t(roundf(telem.current * 100)); + dshot_i.temperature_cdeg[j] = telem.temperature_cdeg; +#if AP_EXTENDED_DSHOT_TELEM_V2_ENABLED + dshot_i.edt2_status[j] = uint8_t(telem.edt2_status); + dshot_i.edt2_stress[j] = uint8_t(telem.edt2_stress); +#endif + dshot_i.types[j] = telem.types; #endif } } diff --git a/libraries/AP_IOMCU/iofirmware/ioprotocol.h b/libraries/AP_IOMCU/iofirmware/ioprotocol.h index be00d927593f7..c6a804ad45c3c 100644 --- a/libraries/AP_IOMCU/iofirmware/ioprotocol.h +++ b/libraries/AP_IOMCU/iofirmware/ioprotocol.h @@ -223,4 +223,9 @@ struct page_dshot_telem { uint16_t current_camps[4]; uint16_t temperature_cdeg[4]; uint16_t types[4]; +// if EDTv2 needs to be disabled, IOMCU firmware should be recompiled too, this is the reason +#if AP_EXTENDED_DSHOT_TELEM_V2_ENABLED + uint8_t edt2_status[4]; + uint8_t edt2_stress[4]; +#endif }; From 7c7f5d54ea7fdf2196c206b9472de05090162969 Mon Sep 17 00:00:00 2001 From: Maxim Buzdalov Date: Tue, 14 May 2024 09:16:23 +1000 Subject: [PATCH 5/5] Tools: rebuilt IO firmware --- .../IO_Firmware/iofirmware_dshot_highpolh.bin | Bin 47564 -> 47564 bytes .../IO_Firmware/iofirmware_dshot_lowpolh.bin | Bin 47564 -> 47564 bytes .../iofirmware_f103_8MHz_highpolh.bin | Bin 40704 -> 40704 bytes .../iofirmware_f103_8MHz_lowpolh.bin | Bin 40704 -> 40704 bytes .../iofirmware_f103_dshot_highpolh.bin | Bin 53100 -> 53348 bytes .../iofirmware_f103_dshot_lowpolh.bin | Bin 53100 -> 53348 bytes .../IO_Firmware/iofirmware_f103_highpolh.bin | Bin 40696 -> 40696 bytes Tools/IO_Firmware/iofirmware_f103_lowpolh.bin | Bin 40696 -> 40696 bytes Tools/IO_Firmware/iofirmware_highpolh.bin | Bin 40704 -> 40704 bytes Tools/IO_Firmware/iofirmware_lowpolh.bin | Bin 40704 -> 40704 bytes 10 files changed, 0 insertions(+), 0 deletions(-) diff --git a/Tools/IO_Firmware/iofirmware_dshot_highpolh.bin b/Tools/IO_Firmware/iofirmware_dshot_highpolh.bin index a986d7dfa7480982c4f33b48d717f484f1832f26..45354a76ef3569dd06491e28cf0ce3f3d499e072 100755 GIT binary patch delta 28 kcmX@}nd!`DrVUa?jG2?AjT#v%C(ku9Wn8!UveC~r0I<6ZK>z>% delta 28 kcmX@}nd!`DrVUa?j75{BjT#v{CeJl8Wjwt3veC~r0J4t^ZU6uP diff --git a/Tools/IO_Firmware/iofirmware_dshot_lowpolh.bin b/Tools/IO_Firmware/iofirmware_dshot_lowpolh.bin index 01e10a37e4e820c163bbeaf365a4db7994d89182..a7e29528d9ff544fdb5310521b84f9a9bfa06b27 100755 GIT binary patch delta 28 kcmX@}nd!`DrVUa?jG2?AjT#v%C(ku9Wn8!UveC~r0I<6ZK>z>% delta 28 kcmX@}nd!`DrVUa?j75{BjT#v{CeJl8Wjwt3veC~r0J4t^ZU6uP diff --git a/Tools/IO_Firmware/iofirmware_f103_8MHz_highpolh.bin b/Tools/IO_Firmware/iofirmware_f103_8MHz_highpolh.bin index 9d79171876dfd581bf81d249ef846f9cc6b4407b..62564b2c04a2402524ca8f6d431f6b5ec9b98c22 100755 GIT binary patch delta 28 kcmZqJ$JDToX~R8T#>~n0bsHHgCnxF^Gp^fwRZqJB0I$;v)c^nh delta 28 kcmZqJ$JDToX~R8T#-hphbsHHwCMW6@GalZ2RZqJB0I{bG0ssI2 diff --git a/Tools/IO_Firmware/iofirmware_f103_8MHz_lowpolh.bin b/Tools/IO_Firmware/iofirmware_f103_8MHz_lowpolh.bin index cba2c729d057ede40cd1a2e127c5fc2afdcd0bb7..be0a4ac44d01551e6b04758cb0eb52673051c480 100755 GIT binary patch delta 28 kcmZqJ$JDToX~R8T#>~n0bsHHgCnxF^Gp^fwRZqJB0I$;v)c^nh delta 28 kcmZqJ$JDToX~R8T#-hphbsHHwCMW6@GalZ2RZqJB0I{bG0ssI2 diff --git a/Tools/IO_Firmware/iofirmware_f103_dshot_highpolh.bin b/Tools/IO_Firmware/iofirmware_f103_dshot_highpolh.bin index e27740255e5a37cd5a453726e0582141cccacfc1..afdd37a688b32b699c14cf7701d9aceb0ea7a8db 100755 GIT binary patch delta 10307 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 ZnMO}qa=(0m(jP2mzJl0kiT^s4{vSuTD?k7M delta 10204 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 HCW-zpuEiUc diff --git a/Tools/IO_Firmware/iofirmware_f103_dshot_lowpolh.bin b/Tools/IO_Firmware/iofirmware_f103_dshot_lowpolh.bin index a3e33ac45ea889b6b9194defc592c0a0413f291d..67570053434086358da5cc1d5a1b73df78f13897 100755 GIT binary patch delta 10323 zcmaKx30zgx+W*(uXW*cW0y67497GV&gD8V!BIpJ@65^1WS>SlUA=J#F49p?SA#`b} zm}zM_7I36jR7Bsj(y}12M6$iKR6vN?!pEZ=D^i>>MmDi~RtZ_ln{Ez$g0DR~Sh9A}~3!sC8R+#>y+NMaKk)DgK4N{2;e>2ox~ zF^f~&@6hs8sI|y;k{8Wugd=Q5w^`lGv_v~Yhdu$sho%t^nikfL{n~9;a9B5@Eth_a z@~LT%Jd%|Bj@okRZ1)D~HrwtOZoHl7Q&%ayr5#x-7wJE8r9f$gTgD$N68s8$>e3z^ z8_*zK={`AxrT^m!6-ul}rMCE0x+RmfHID=RtSfqmFN%LeBPL^Fs_2>(T@tn8ah%GD43mQr?2BHF{Dql<1mp&>_v`BB=UgNU3*m0My{4#jyNhsKrVp{gT05AR?tE3r5|rp zRMy=V-bO~HNCmo=!ut()zHzTbZWJM3rTf${sA*!6!W24pTjre>Igh_eKHVbMM9%wBOUI62z7X!k zao8EI_I%o3w8WZ%khH?IEt5nSG&Z5{Szm3?&|ecLSH+r+N+#{ZqNCDuABAbM?4p+k zX^V6-ajYwLrjK0iC275(Bkm^RA_r{21X`&b6n{3cdqY{eXS3Yn8=Ue~;&gSli_M?sT=GokA+l|`(W98CGUj+KhL)6`VT#0 z3BN&wfymbct&sV>yCO>X4uZJCaij!{0$ z6cMcCTgQJ+y}hy8jkN7AMN14@BxUa%>Fy0AHK?BIwfrhcndA`LP_D-WDjagiTLARl z*WA=7|FG8QvYcu*TJ}|9lk`p09c-NHOFp`@(pS$a+iZjg{Vh#cQg=eWDv8xz!6u%b zX*?^1O$aH##+7s@WI(JQ8{2CG;1C-P&6apS#QbnsN!<5Ml7wVkVpFeZ&y30JVSrVqp#>CEREy8f)Bncx&JNS!(U;Ih3o#wk84CH<9o<0aYEHq#+q za?0b?4__G~1iMyC5E6G3{JAT!#J<)CkMU1hS1Wsd>X0krh01)2KF12e7)xnX*n`i> zS;KQJaz0g-R!FD#o4sR8(FhS1xyd`RnB^7LvD#Q-WIwg6`gCJOk

r;=R~H>?BChrRuyV;C`wrGb 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 l??R~hY$MSOY-CysuxP^e6L~Zy delta 10202 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 G`u_j~NEsvm diff --git a/Tools/IO_Firmware/iofirmware_f103_highpolh.bin b/Tools/IO_Firmware/iofirmware_f103_highpolh.bin index c3d67598c1b118c7c6b2968bceb6809640f9fa41..b14b7183293e1772d0638fb23d8f1a177379bed9 100755 GIT binary patch delta 28 kcmeydm+8k|rVaOW88au}*KK61oSdjv%(!mzRXybb0LW+zy8r+H delta 28 kcmeydm+8k|rVaOW8H*<0*KK6%n4G9r%y@Y7RXybb0LnZJ=l}o! diff --git a/Tools/IO_Firmware/iofirmware_f103_lowpolh.bin b/Tools/IO_Firmware/iofirmware_f103_lowpolh.bin index 3a43e19918a219d64dff8674e5010632e219eb7b..411152646d4e7f3eb9367ed9379b0a57e46509e7 100755 GIT binary patch delta 28 kcmeydm+8k|rVaOW88au}*KK61oSdjv%(!mzRXybb0LW+zy8r+H delta 28 kcmeydm+8k|rVaOW8H*<0*KK6%n4G9r%y@Y7RXybb0LnZJ=l}o! diff --git a/Tools/IO_Firmware/iofirmware_highpolh.bin b/Tools/IO_Firmware/iofirmware_highpolh.bin index f03fc5273eb090dac3b01e482236ec8e7d171a62..b094ccf1a9b35a38d0a5e2eaca77729d87f20386 100755 GIT binary patch delta 28 kcmZqJ$JDToX~Q*L#>~mrbsHHgCr9cPGp^fwR?oNq0Io|5y#N3J delta 28 kcmZqJ$JDToX~Q*L#-hpBbsHHwCP(TOGalZ2R?oNq0I(km>Hq)$ diff --git a/Tools/IO_Firmware/iofirmware_lowpolh.bin b/Tools/IO_Firmware/iofirmware_lowpolh.bin index 648e4f962403cffc86777f9c8edfd62ebd68efb6..6837e06288055f62f48d81e925b4818937dcab93 100755 GIT binary patch delta 28 kcmZqJ$JDToX~Q*L#>~mrbsHHgCr9cPGp^fwR?oNq0Io|5y#N3J delta 28 kcmZqJ$JDToX~Q*L#-hpBbsHHwCP(TOGalZ2R?oNq0I(km>Hq)$