2 * This file is part of Cleanflight and Betaflight.
4 * Cleanflight and Betaflight are free software. You can redistribute
5 * this software and/or modify this software under the terms of the
6 * GNU General Public License as published by the Free Software
7 * Foundation, either version 3 of the License, or (at your option)
10 * Cleanflight and Betaflight are distributed in the hope that they
11 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this software.
18 * If not, see <http://www.gnu.org/licenses/>.
26 #include "common/time.h"
30 #define DSHOT_MIN_THROTTLE (48)
31 #define DSHOT_MAX_THROTTLE (2047)
32 #define DSHOT_3D_FORWARD_MIN_THROTTLE (1048)
33 #define DSHOT_RANGE (DSHOT_MAX_THROTTLE - DSHOT_MIN_THROTTLE)
35 #define DSHOT_TELEMETRY_NOEDGE (0xfffe)
36 #define DSHOT_TELEMETRY_INVALID (0xffff)
38 #define MIN_GCR_EDGES (7)
39 #define MAX_GCR_EDGES (22)
41 // comment out to see frame dump of corrupted frames in dshot_telemetry_info
42 //#define DEBUG_BBDECODE
44 #ifdef USE_DSHOT_TELEMETRY_STATS
45 #define DSHOT_TELEMETRY_QUALITY_WINDOW 1 // capture a rolling 1 second of packet stats
46 #define DSHOT_TELEMETRY_QUALITY_BUCKET_MS 100 // determines the granularity of the stats and the overall number of rolling buckets
47 #define DSHOT_TELEMETRY_QUALITY_BUCKET_COUNT (DSHOT_TELEMETRY_QUALITY_WINDOW * 1000 / DSHOT_TELEMETRY_QUALITY_BUCKET_MS)
49 typedef struct dshotTelemetryQuality_s
{
50 uint32_t packetCountSum
;
51 uint32_t invalidCountSum
;
52 uint32_t packetCountArray
[DSHOT_TELEMETRY_QUALITY_BUCKET_COUNT
];
53 uint32_t invalidCountArray
[DSHOT_TELEMETRY_QUALITY_BUCKET_COUNT
];
54 uint8_t lastBucketIndex
;
55 } dshotTelemetryQuality_t
;
57 extern dshotTelemetryQuality_t dshotTelemetryQuality
[MAX_SUPPORTED_MOTORS
];
58 #endif // USE_DSHOT_TELEMETRY_STATS
60 #define DSHOT_NORMAL_TELEMETRY_MASK (1 << DSHOT_TELEMETRY_TYPE_eRPM)
61 #define DSHOT_EXTENDED_TELEMETRY_MASK (~DSHOT_NORMAL_TELEMETRY_MASK)
63 typedef enum dshotTelemetryType_e
{
64 DSHOT_TELEMETRY_TYPE_eRPM
= 0,
65 DSHOT_TELEMETRY_TYPE_TEMPERATURE
= 1,
66 DSHOT_TELEMETRY_TYPE_VOLTAGE
= 2,
67 DSHOT_TELEMETRY_TYPE_CURRENT
= 3,
68 DSHOT_TELEMETRY_TYPE_DEBUG1
= 4,
69 DSHOT_TELEMETRY_TYPE_DEBUG2
= 5,
70 DSHOT_TELEMETRY_TYPE_DEBUG3
= 6,
71 DSHOT_TELEMETRY_TYPE_STATE_EVENTS
= 7,
72 DSHOT_TELEMETRY_TYPE_COUNT
73 } dshotTelemetryType_t
;
75 typedef enum dshotRawValueState_e
{
76 DSHOT_RAW_VALUE_STATE_INVALID
= 0,
77 DSHOT_RAW_VALUE_STATE_NOT_PROCESSED
= 1,
78 DSHOT_RAW_VALUE_STATE_PROCESSED
= 2,
79 DSHOT_RAW_VALUE_STATE_COUNT
80 } dshotRawValueState_t
;
82 typedef struct dshotProtocolControl_s
{
84 bool requestTelemetry
;
85 } dshotProtocolControl_t
;
87 void dshotInitEndpoints(const motorConfig_t
*motorConfig
, float outputLimit
, float *outputLow
, float *outputHigh
, float *disarm
, float *deadbandMotor3dHigh
, float *deadbandMotor3dLow
);
88 float dshotConvertFromExternal(uint16_t externalValue
);
89 uint16_t dshotConvertToExternal(float motorValue
);
91 uint16_t prepareDshotPacket(dshotProtocolControl_t
*pcb
);
93 #ifdef USE_DSHOT_TELEMETRY
94 extern bool useDshotTelemetry
;
96 typedef struct dshotTelemetryMotorState_s
{
98 uint16_t telemetryData
[DSHOT_TELEMETRY_TYPE_COUNT
];
99 uint8_t telemetryTypes
;
101 } dshotTelemetryMotorState_t
;
104 typedef struct dshotTelemetryState_s
{
105 bool useDshotTelemetry
;
106 uint32_t invalidPacketCount
;
108 dshotTelemetryMotorState_t motorState
[MAX_SUPPORTED_MOTORS
];
109 uint32_t inputBuffer
[MAX_GCR_EDGES
];
110 dshotRawValueState_t rawValueState
;
111 } dshotTelemetryState_t
;
113 extern dshotTelemetryState_t dshotTelemetryState
;
115 #ifdef USE_DSHOT_TELEMETRY_STATS
116 void updateDshotTelemetryQuality(dshotTelemetryQuality_t
*qualityStats
, bool packetValid
, timeMs_t currentTimeMs
);
118 #endif // USE_DSHOT_TELEMETRY
120 void initDshotTelemetry(const timeUs_t looptimeUs
);
121 void updateDshotTelemetry(void);
123 uint16_t getDshotErpm(uint8_t motorIndex
);
124 float getDshotRpm(uint8_t motorIndex
);
125 float getDshotRpmAverage(void);
126 float getMotorFrequencyHz(uint8_t motorIndex
);
127 float getMinMotorFrequencyHz(void);
129 bool isDshotMotorTelemetryActive(uint8_t motorIndex
);
130 bool isDshotTelemetryActive(void);
131 void dshotCleanTelemetryData(void);
133 float erpmToRpm(uint32_t erpm
);
135 int16_t getDshotTelemetryMotorInvalidPercent(uint8_t motorIndex
);
137 void validateAndfixMotorOutputReordering(uint8_t *array
, const unsigned size
);