Fixed parameter group violations in `motorDevConfig_t`, incremented EEPROM config...
[betaflight.git] / src / main / drivers / pwm_output.h
blobd6d3cca14dc94c9d9a369228901e3ab496dc6342
1 /*
2 * This file is part of Cleanflight.
4 * Cleanflight is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * Cleanflight is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
18 #pragma once
20 #include "platform.h"
22 #include "drivers/io_types.h"
23 #include "drivers/pwm_output_counts.h"
24 #include "drivers/timer.h"
27 #define ALL_MOTORS 255
29 #define DSHOT_MAX_COMMAND 47
32 DshotSettingRequest (KISS24). Spin direction, 3d and save Settings reqire 10 requests.. and the TLM Byte must always be high if 1-47 are used to send settings
34 3D Mode:
35 0 = stop
36 48 (low) - 1047 (high) -> negative direction
37 1048 (low) - 2047 (high) -> positive direction
40 typedef enum {
41 DSHOT_CMD_MOTOR_STOP = 0,
42 DSHOT_CMD_BEACON1,
43 DSHOT_CMD_BEACON2,
44 DSHOT_CMD_BEACON3,
45 DSHOT_CMD_BEACON4,
46 DSHOT_CMD_BEACON5,
47 DSHOT_CMD_ESC_INFO, // V2 includes settings
48 DSHOT_CMD_SPIN_DIRECTION_1,
49 DSHOT_CMD_SPIN_DIRECTION_2,
50 DSHOT_CMD_3D_MODE_OFF,
51 DSHOT_CMD_3D_MODE_ON,
52 DSHOT_CMD_SETTINGS_REQUEST, // Currently not implemented
53 DSHOT_CMD_SAVE_SETTINGS,
54 DSHOT_CMD_SPIN_DIRECTION_NORMAL = 20,
55 DSHOT_CMD_SPIN_DIRECTION_REVERSED = 21,
56 DSHOT_CMD_LED0_ON, // BLHeli32 only
57 DSHOT_CMD_LED1_ON, // BLHeli32 only
58 DSHOT_CMD_LED2_ON, // BLHeli32 only
59 DSHOT_CMD_LED3_ON, // BLHeli32 only
60 DSHOT_CMD_LED0_OFF, // BLHeli32 only
61 DSHOT_CMD_LED1_OFF, // BLHeli32 only
62 DSHOT_CMD_LED2_OFF, // BLHeli32 only
63 DSHOT_CMD_LED3_OFF, // BLHeli32 only
64 DSHOT_CMD_AUDIO_STREAM_MODE_ON_OFF = 30, // KISS audio Stream mode on/Off
65 DSHOT_CMD_SILENT_MODE_ON_OFF = 31, // KISS silent Mode on/Off
66 DSHOT_CMD_MAX = 47
67 } dshotCommands_e;
70 typedef enum {
71 PWM_TYPE_STANDARD = 0,
72 PWM_TYPE_ONESHOT125,
73 PWM_TYPE_ONESHOT42,
74 PWM_TYPE_MULTISHOT,
75 PWM_TYPE_BRUSHED,
76 #ifdef USE_DSHOT
77 PWM_TYPE_DSHOT150,
78 PWM_TYPE_DSHOT300,
79 PWM_TYPE_DSHOT600,
80 PWM_TYPE_DSHOT1200,
81 PWM_TYPE_PROSHOT1000,
82 #endif
83 PWM_TYPE_MAX
84 } motorPwmProtocolTypes_e;
86 #define PWM_TIMER_1MHZ MHZ_TO_HZ(1)
88 #ifdef USE_DSHOT
89 #define MAX_DMA_TIMERS 8
91 #define MOTOR_DSHOT1200_HZ MHZ_TO_HZ(24)
92 #define MOTOR_DSHOT600_HZ MHZ_TO_HZ(12)
93 #define MOTOR_DSHOT300_HZ MHZ_TO_HZ(6)
94 #define MOTOR_DSHOT150_HZ MHZ_TO_HZ(3)
96 #define MOTOR_BIT_0 7
97 #define MOTOR_BIT_1 14
98 #define MOTOR_BITLENGTH 19
100 #define MOTOR_PROSHOT1000_HZ MHZ_TO_HZ(24)
101 #define PROSHOT_BASE_SYMBOL 24 // 1uS
102 #define PROSHOT_BIT_WIDTH 3
103 #define MOTOR_NIBBLE_LENGTH_PROSHOT 96 // 4uS
104 #endif
107 #define DSHOT_DMA_BUFFER_SIZE 18 /* resolution + frame reset (2us) */
108 #define PROSHOT_DMA_BUFFER_SIZE 6 /* resolution + frame reset (2us) */
110 typedef struct {
111 TIM_TypeDef *timer;
112 #if defined(USE_DSHOT) && defined(USE_DSHOT_DMAR)
113 #if !defined(USE_HAL_DRIVER)
114 #ifdef STM32F3
115 DMA_Channel_TypeDef *dmaBurstRef;
116 #else
117 DMA_Stream_TypeDef *dmaBurstRef;
118 #endif
119 uint16_t dmaBurstLength;
120 #endif
121 #endif
122 uint32_t dmaBurstBuffer[DSHOT_DMA_BUFFER_SIZE * 4];
123 uint16_t timerDmaSources;
124 } motorDmaTimer_t;
126 typedef struct {
127 ioTag_t ioTag;
128 const timerHardware_t *timerHardware;
129 uint16_t value;
130 #ifdef USE_DSHOT
131 uint16_t timerDmaSource;
132 bool configured;
133 #endif
134 motorDmaTimer_t *timer;
135 volatile bool requestTelemetry;
136 #if defined(STM32F3) || defined(STM32F4) || defined(STM32F7)
137 uint32_t dmaBuffer[DSHOT_DMA_BUFFER_SIZE];
138 #else
139 uint8_t dmaBuffer[DSHOT_DMA_BUFFER_SIZE];
140 #endif
141 #if defined(USE_HAL_DRIVER)
142 TIM_HandleTypeDef TimHandle;
143 DMA_HandleTypeDef hdma_tim;
144 uint16_t timerDmaIndex;
145 #endif
146 } motorDmaOutput_t;
148 motorDmaOutput_t *getMotorDmaOutput(uint8_t index);
150 struct timerHardware_s;
151 typedef void pwmWriteFn(uint8_t index, float value); // function pointer used to write motors
152 typedef void pwmCompleteWriteFn(uint8_t motorCount); // function pointer used after motors are written
154 typedef struct {
155 volatile timCCR_t *ccr;
156 TIM_TypeDef *tim;
157 } timerChannel_t;
159 typedef struct {
160 timerChannel_t channel;
161 float pulseScale;
162 float pulseOffset;
163 bool forceOverflow;
164 bool enabled;
165 IO_t io;
166 } pwmOutputPort_t;
168 //CAVEAT: This is used in the `motorConfig_t` parameter group, so the parameter group constraints apply
169 typedef struct motorDevConfig_s {
170 uint16_t motorPwmRate; // The update rate of motor outputs (50-498Hz)
171 uint8_t motorPwmProtocol; // Pwm Protocol
172 uint8_t motorPwmInversion; // Active-High vs Active-Low. Useful for brushed FCs converted for brushless operation
173 uint8_t useUnsyncedPwm;
174 uint8_t useBurstDshot;
175 ioTag_t ioTags[MAX_SUPPORTED_MOTORS];
176 } motorDevConfig_t;
178 extern bool useBurstDshot;
180 void motorDevInit(const motorDevConfig_t *motorDevConfig, uint16_t idlePulse, uint8_t motorCount);
182 typedef struct servoDevConfig_s {
183 // PWM values, in milliseconds, common range is 1000-2000 (1ms to 2ms)
184 uint16_t servoCenterPulse; // This is the value for servos when they should be in the middle. e.g. 1500.
185 uint16_t servoPwmRate; // The update rate of servo outputs (50-498Hz)
186 ioTag_t ioTags[MAX_SUPPORTED_SERVOS];
187 } servoDevConfig_t;
189 void servoDevInit(const servoDevConfig_t *servoDevConfig);
191 void pwmServoConfig(const struct timerHardware_s *timerHardware, uint8_t servoIndex, uint16_t servoPwmRate, uint16_t servoCenterPulse);
193 bool isMotorProtocolDshot(void);
195 #ifdef USE_DSHOT
196 typedef uint8_t loadDmaBufferFn(uint32_t *dmaBuffer, int stride, uint16_t packet); // function pointer used to encode a digital motor value into the DMA buffer representation
198 uint16_t prepareDshotPacket(motorDmaOutput_t *const motor, uint16_t value);
200 extern loadDmaBufferFn *loadDmaBuffer;
202 uint32_t getDshotHz(motorPwmProtocolTypes_e pwmProtocolType);
203 void pwmWriteDshotCommand(uint8_t index, uint8_t motorCount, uint8_t command);
204 void pwmWriteDshotInt(uint8_t index, uint16_t value);
205 void pwmDshotMotorHardwareConfig(const timerHardware_t *timerHardware, uint8_t motorIndex, motorPwmProtocolTypes_e pwmProtocolType, uint8_t output);
206 void pwmCompleteDshotMotorUpdate(uint8_t motorCount);
207 #endif
209 #ifdef BEEPER
210 void pwmWriteBeeper(bool onoffBeep);
211 void pwmToggleBeeper(void);
212 void beeperPwmInit(const ioTag_t tag, uint16_t frequency);
213 #endif
214 void pwmOutConfig(timerChannel_t *channel, const timerHardware_t *timerHardware, uint32_t hz, uint16_t period, uint16_t value, uint8_t inversion);
216 void pwmWriteMotor(uint8_t index, float value);
217 void pwmShutdownPulsesForAllMotors(uint8_t motorCount);
218 void pwmCompleteMotorUpdate(uint8_t motorCount);
220 void pwmWriteServo(uint8_t index, float value);
222 pwmOutputPort_t *pwmGetMotors(void);
223 bool pwmIsSynced(void);
224 void pwmDisableMotors(void);
225 void pwmEnableMotors(void);
226 bool pwmAreMotorsEnabled(void);