Dshot RPM Telemetry Refactoring (#13012)
[betaflight.git] / src / main / drivers / dshot.h
blob1d1e05742817b0988dae21a8582eba59a615dfef
1 /*
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)
8 * any later version.
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/>.
21 #pragma once
23 #include <stdbool.h>
24 #include <stdint.h>
26 #include "common/time.h"
28 #include "pg/motor.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 {
83 uint16_t value;
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 {
97 uint16_t rawValue;
98 uint16_t telemetryData[DSHOT_TELEMETRY_TYPE_COUNT];
99 uint8_t telemetryTypes;
100 uint8_t maxTemp;
101 } dshotTelemetryMotorState_t;
104 typedef struct dshotTelemetryState_s {
105 bool useDshotTelemetry;
106 uint32_t invalidPacketCount;
107 uint32_t readCount;
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);
117 #endif
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);