Dshot RPM Telemetry Refactoring (#13012)
[betaflight.git] / src / main / io / usb_cdc_hid.c
blob0af76b6b9fd88f3c6c9ff529c0cf4a69d21b5c75
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/>.
22 #include <stdbool.h>
24 #include "platform.h"
26 #ifdef USE_USB_CDC_HID
28 #include "common/maths.h"
29 #include "fc/rc_controls.h"
30 #include "rx/rx.h"
31 #include "pg/usb.h"
32 #include "sensors/battery.h"
33 #include "usb_cdc_hid.h"
35 #define USB_CDC_HID_NUM_AXES 8
36 #define USB_CDC_HID_NUM_BUTTONS 8
38 #define USB_CDC_HID_RANGE_MIN -127
39 #define USB_CDC_HID_RANGE_MAX 127
41 // In the windows joystick driver, the axes are defined as shown in the second column.
43 const uint8_t hidChannelMapping[] = {
44 ROLL, // X
45 PITCH, // Y
46 AUX3, // Z
47 YAW, // X Rotation
48 AUX1, // Z Rotation
49 THROTTLE, // Y Rotation
50 AUX4, // Slider
51 AUX2, // Dial
52 AUX5, // Button 1
53 AUX6, // Button 2
54 AUX7, // Button 3
55 AUX8, // Button 4
56 AUX9, // Button 5
57 AUX10, // Button 6
58 AUX11, // Button 7
59 AUX12 // Button 8
62 void sendRcDataToHid(void)
64 int8_t report[9];
65 // Axes
66 for (unsigned i = 0; i < USB_CDC_HID_NUM_AXES; i++) {
67 const uint8_t channel = hidChannelMapping[i];
68 report[i] = scaleRange(constrain(rcData[channel], PWM_RANGE_MIN, PWM_RANGE_MAX), PWM_RANGE_MIN, PWM_RANGE_MAX, USB_CDC_HID_RANGE_MIN, USB_CDC_HID_RANGE_MAX);
69 if (channel == PITCH) {
70 // PITCH is inverted in Windows
71 report[i] = -report[i];
75 // Buttons
76 // Each bit in one byte represents one button so we have 8 buttons in one-byte-data
77 report[8] = 0;
78 for (unsigned i = 0; i < USB_CDC_HID_NUM_BUTTONS; i++) {
79 const uint8_t channel = hidChannelMapping[i + USB_CDC_HID_NUM_AXES];
80 if (scaleRange(constrain(rcData[channel], PWM_RANGE_MIN, PWM_RANGE_MAX), PWM_RANGE_MIN, PWM_RANGE_MAX, USB_CDC_HID_RANGE_MIN, USB_CDC_HID_RANGE_MAX) > 0) {
81 report[8] |= (1 << i);
85 sendReport((uint8_t*)report, sizeof(report));
88 bool cdcDeviceIsMayBeActive(void)
90 return usbDevConfig()->type == COMPOSITE && usbIsConnected() && (getBatteryState() == BATTERY_NOT_PRESENT || batteryConfig()->voltageMeterSource == VOLTAGE_METER_NONE);
92 #endif