Browse Source

Restructured, implemented X52 vendor commands.

Thomas Buck 7 years ago
parent
commit
870044a8eb
9 changed files with 564 additions and 208 deletions
  1. 78
    23
      Saitek-X52-PPM.ino
  2. 111
    0
      hid_parser.cpp
  3. 39
    0
      hid_parser.h
  4. 0
    141
      hidjoystickrptparser.cpp
  5. 0
    44
      hidjoystickrptparser.h
  6. 56
    0
      joystick_events.cpp
  7. 31
    0
      joystick_events.h
  8. 163
    0
      x52.cpp
  9. 86
    0
      x52.h

+ 78
- 23
Saitek-X52-PPM.ino View File

@@ -1,38 +1,93 @@
1
+/*
2
+ * Saitek X52 Arduino USB Host Shield Library.
3
+ * Copyright 2016 by Thomas Buck <xythobuz@xythobuz.de>
4
+ * 
5
+ * Based on the USB Host Library HID Joystick example
6
+ * https://www.circuitsathome.com/mcu/hid-joystick-code-sample
7
+ * 
8
+ * This program is free software; you can redistribute it and/or
9
+ * modify it under the terms of the GNU General Public License as
10
+ * published by the Free Software Foundation, version 2.
11
+ */
12
+
1 13
 #include <hid.h>
2 14
 #include <hiduniversal.h>
3 15
 #include <usbhub.h>
4 16
 
5
-// Satisfy IDE, which only needs to see the include statment in the ino.
6
-#ifdef dobogusinclude
7
-#include <spi4teensy3.h>
8
-#include <SPI.h>
9
-#endif
10
-
11
-#include "hidjoystickrptparser.h"
17
+#include "hid_parser.h"
18
+#include "x52.h"
12 19
 
13
-USB Usb;
14
-USBHub Hub(&Usb);
15
-HIDUniversal Hid(&Usb);
16
-JoystickEvents JoyEvents;
17
-JoystickReportParser Joy(&JoyEvents);
20
+USB usb;
21
+USBHub hub(&usb);
22
+HIDUniversal hid(&usb);
23
+X52 x52(&usb, &hid);
24
+JoystickEvents joyevents;
25
+JoystickReportParser joy(&joyevents);
18 26
 
19 27
 void setup() {  
20
-        Serial.begin(115200);
21
-#if !defined(__MIPSEL__)
22
-        while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
23
-#endif
24
-        Serial.println("Start");
28
+    Serial.begin(115200);
29
+    Serial.println("Start");
25 30
 
26
-        if (Usb.Init() == -1)
27
-                Serial.println("OSC did not start.");
31
+    if (usb.Init() == -1) {
32
+        Serial.println("OSC did not start.");
33
+    }
28 34
 
29
-        delay(200);
35
+    delay(200);
30 36
 
31
-        if (!Hid.SetReportParser(0, &Joy))
32
-                ErrorMessage<uint8_t > (PSTR("SetReportParser"), 1);
37
+    if (!hid.SetReportParser(0, &joy)) {
38
+        ErrorMessage<uint8_t >(PSTR("SetReportParser"), 1);
39
+    }
33 40
 }
34 41
 
35 42
 void loop() {
36
-        Usb.Task();
43
+    usb.Task();
44
+
45
+    static unsigned long lastTime = 0;
46
+    static uint8_t d = 0;
47
+    if ((millis() - lastTime) >= 500) {
48
+        //x52.setDate(d, d, d);
49
+        d++;
50
+        lastTime = millis();
51
+
52
+        String tmp = String(d);
53
+        //x52.setMFDText(0, tmp.c_str());
54
+    }
55
+
56
+    if (Serial.available()) {
57
+        char c = Serial.read();
58
+        if (c == 't') {
59
+            x52.setMFDText(0, "Arduino");
60
+            x52.setMFDText(1, "Hello");
61
+            x52.setMFDText(2, "World");
62
+        } else if (c == '0') {
63
+            x52.setMFDBrightness(0);
64
+        } else if (c == '1') {
65
+            x52.setMFDBrightness(1);
66
+        } else if (c == '2') {
67
+            x52.setMFDBrightness(2);
68
+        } else if (c == '3') {
69
+            x52.setLEDBrightness(0);
70
+        } else if (c == '4') {
71
+            x52.setLEDBrightness(1);
72
+        } else if (c == '5') {
73
+            x52.setLEDBrightness(2);
74
+        } else if (c == 'q') {
75
+            x52.setShift(1);
76
+        } else if (c == 'w') {
77
+            x52.setShift(0);
78
+        } else if (c == 'a') {
79
+            x52.setBlink(1);
80
+        } else if (c == 's') {
81
+            x52.setBlink(0);
82
+        } else if (c == 'z') {
83
+            x52.setDate(1, 1, 1);
84
+        } else if (c == 'x') {
85
+            x52.setTime(12, 42);
86
+            x52.setTimeOffset(0, -120);
87
+            x52.setTimeOffset(0, 240);
88
+        } else {
89
+            Serial.println("Unknown command!");
90
+        }
91
+    }
37 92
 }
38 93
 

+ 111
- 0
hid_parser.cpp View File

@@ -0,0 +1,111 @@
1
+/*
2
+ * Saitek X52 Arduino USB Host Shield Library.
3
+ * Copyright 2016 by Thomas Buck <xythobuz@xythobuz.de>
4
+ * 
5
+ * Based on the USB Host Library HID Joystick example
6
+ * https://www.circuitsathome.com/mcu/hid-joystick-code-sample
7
+ * 
8
+ * This program is free software; you can redistribute it and/or
9
+ * modify it under the terms of the GNU General Public License as
10
+ * published by the Free Software Foundation, version 2.
11
+ */
12
+
13
+#include "hid_parser.h"
14
+
15
+JoystickReportParser::JoystickReportParser(JoystickEvents* evt)
16
+        : joyEvents(evt), oldHat(0), oldButtons(0), oldMouse(0) {
17
+    for (uint8_t i = 0; i < RPT_GEMEPAD_LEN; i++) {
18
+        oldPad[i] = 0;
19
+    }
20
+}
21
+
22
+void JoystickReportParser::Parse(HID* hid, bool is_rpt_id, uint8_t len, uint8_t* bufPart) {
23
+    if (len == 8) {
24
+        // First part of buffer, store and do nothing
25
+        for (uint8_t i = 0; i < 8; i++) {
26
+            buf[i] = bufPart[i];
27
+        }
28
+        return;
29
+    } else {
30
+        // Append second part, then evaluate
31
+        for (uint8_t i = 0; i < len; i++) {
32
+            buf[i + 8] = bufPart[i];
33
+        }
34
+    }
35
+
36
+    /*
37
+    Serial.println("");
38
+    Serial.print("Packet: ");
39
+    for (uint8_t i = 0; i < (8 + len); i++) {
40
+        PrintHex<uint8_t >(buf[i], 0x80);
41
+        Serial.print(" ");
42
+    }
43
+    Serial.println("");
44
+    Serial.println("");
45
+    */
46
+
47
+    // Checking if there are changes in report since the method was last called
48
+    bool match = true;
49
+    for (uint8_t i = 0; i < RPT_GEMEPAD_LEN; i++) {
50
+        if (buf[i] != oldPad[i]) {
51
+            match = false;
52
+            break;
53
+        }
54
+    }
55
+
56
+    // Calling Game Pad event handler
57
+    if (!match && joyEvents) {
58
+        buffer.X = buf[0] | ((buf[1] & 0x07) << 8);
59
+        buffer.Y = ((buf[1] & 0xF8) >> 3) | ((buf[2] & 0x3F) << 5);
60
+        buffer.Rz = ((buf[2] & 0xC0) >> 6) | (buf[3] << 2);
61
+        buffer.Z = buf[4];
62
+        buffer.Rx = buf[5];
63
+        buffer.Ry = buf[6];
64
+        buffer.Slider = buf[7];
65
+
66
+        joyEvents->OnGamePadChanged((const GamePadEventData*)&buffer);
67
+
68
+        for (uint8_t i = 0; i < RPT_GEMEPAD_LEN; i++) {
69
+            oldPad[i] = buf[i];
70
+        }
71
+    }
72
+
73
+    // Calling Hat Switch event handler`
74
+    uint8_t hat = (buf[12] & 0xF0) >> 4;
75
+    if (hat != oldHat && joyEvents) {
76
+        joyEvents->OnHatSwitch(hat);
77
+        oldHat = hat;
78
+    }
79
+
80
+    uint64_t buttons = buf[12] & 0x03;
81
+    buttons <<= 8;
82
+    buttons |= buf[11];
83
+    buttons <<= 8;
84
+    buttons |= buf[10];
85
+    buttons <<= 8;
86
+    buttons |= buf[9];
87
+    buttons <<= 8;
88
+    buttons |= buf[8];
89
+
90
+    // Calling Button Event Handler for every button changed
91
+    uint64_t changes = (buttons ^ oldButtons);
92
+    if (changes) {
93
+        for (uint8_t i = 0; i < 34; i++) {
94
+            uint64_t mask = (1ull << i);
95
+            if ((mask & changes) && joyEvents) {
96
+                if (buttons & mask) {
97
+                    joyEvents->OnButtonDn(i);
98
+                } else {
99
+                    joyEvents->OnButtonUp(i);
100
+                }
101
+            }
102
+        }
103
+        oldButtons = buttons;
104
+    }
105
+
106
+    if (oldMouse != buf[13] && joyEvents) {
107
+        oldMouse = buf[13];
108
+        joyEvents->OnMouseMoved((buf[13] & 0xF0) >> 4, buf[13] & 0x0F);
109
+    }
110
+}
111
+

+ 39
- 0
hid_parser.h View File

@@ -0,0 +1,39 @@
1
+/*
2
+ * Saitek X52 Arduino USB Host Shield Library.
3
+ * Copyright 2016 by Thomas Buck <xythobuz@xythobuz.de>
4
+ * 
5
+ * Based on the USB Host Library HID Joystick example
6
+ * https://www.circuitsathome.com/mcu/hid-joystick-code-sample
7
+ * 
8
+ * This program is free software; you can redistribute it and/or
9
+ * modify it under the terms of the GNU General Public License as
10
+ * published by the Free Software Foundation, version 2.
11
+ */
12
+
13
+#ifndef __HID_PARSER_H__
14
+#define __HID_PARSER_H__
15
+
16
+#include <hid.h>
17
+#include "joystick_events.h"
18
+
19
+#define RPT_GEMEPAD_LEN 8
20
+#define BUFFER_SIZE 16
21
+
22
+class JoystickReportParser : public HIDReportParser {
23
+    JoystickEvents* joyEvents;
24
+
25
+    uint8_t buf[BUFFER_SIZE];
26
+    uint8_t oldPad[RPT_GEMEPAD_LEN];
27
+    uint8_t oldHat;
28
+    uint64_t oldButtons;
29
+    uint8_t oldMouse;
30
+    GamePadEventData buffer;
31
+
32
+  public:
33
+    JoystickReportParser(JoystickEvents* evt);
34
+
35
+    virtual void Parse(HID* hid, bool is_rpt_id, uint8_t len, uint8_t* bufPart);
36
+};
37
+
38
+#endif // __HID_PARSER_H__
39
+

+ 0
- 141
hidjoystickrptparser.cpp View File

@@ -1,141 +0,0 @@
1
-#include "hidjoystickrptparser.h"
2
-
3
-/*
4
- * Adapted for the Saitek X52 flight controller
5
- */
6
-
7
-JoystickReportParser::JoystickReportParser(JoystickEvents *evt) :
8
-joyEvents(evt), oldHat(0), oldButtons(0), oldMouse(0) {
9
-        for (uint8_t i = 0; i < RPT_GEMEPAD_LEN; i++)
10
-                oldPad[i] = 0;
11
-}
12
-
13
-void JoystickReportParser::Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *bufPart) {
14
-        if (len == 8) {
15
-          // First part of buffer, store and do nothing
16
-          for (uint8_t i = 0; i < 8; i++) {
17
-            buf[i] = bufPart[i];
18
-          }
19
-          return;
20
-        } else {
21
-          // Append second part, then evaluate
22
-          for (uint8_t i = 0; i < len; i++) {
23
-            buf[i + 8] = bufPart[i];
24
-          }
25
-        }
26
-
27
-        /*
28
-        Serial.println("");
29
-        Serial.print("Packet: ");
30
-        for (uint8_t i = 0; i < (8 + len); i++) {
31
-          PrintHex<uint8_t >(buf[i], 0x80);
32
-          Serial.print(" ");
33
-        }
34
-        Serial.println("");
35
-        Serial.println("");
36
-        */
37
-
38
-        // Checking if there are changes in report since the method was last called
39
-        bool match = true;
40
-        for (uint8_t i = 0; i < RPT_GEMEPAD_LEN; i++)
41
-                if (buf[i] != oldPad[i]) {
42
-                        match = false;
43
-                        break;
44
-                }
45
-
46
-        // Calling Game Pad event handler
47
-        if (!match && joyEvents) {
48
-                buffer.X = buf[0] | ((buf[1] & 0x07) << 8);
49
-                buffer.Y = ((buf[1] & 0xF8) >> 3) | ((buf[2] & 0x3F) << 5);
50
-                buffer.Rz = ((buf[2] & 0xC0) >> 6) | (buf[3] << 2);
51
-                buffer.Z = buf[4];
52
-                buffer.Rx = buf[5];
53
-                buffer.Ry = buf[6];
54
-                buffer.Slider = buf[7];
55
-                
56
-                joyEvents->OnGamePadChanged((const GamePadEventData*)&buffer);
57
-
58
-                for (uint8_t i = 0; i < RPT_GEMEPAD_LEN; i++) oldPad[i] = buf[i];
59
-        }
60
-
61
-        // Calling Hat Switch event handler`
62
-        uint8_t hat = (buf[12] & 0xF0) >> 4;
63
-        if (hat != oldHat && joyEvents) {
64
-                joyEvents->OnHatSwitch(hat);
65
-                oldHat = hat;
66
-        }
67
-
68
-        uint64_t buttons = buf[12] & 0x03;
69
-        buttons <<= 8;
70
-        buttons |= buf[11];
71
-        buttons <<= 8;
72
-        buttons |= buf[10];
73
-        buttons <<= 8;
74
-        buttons |= buf[9];
75
-        buttons <<= 8;
76
-        buttons |= buf[8];
77
-
78
-        // Calling Button Event Handler for every button changed
79
-        uint64_t changes = (buttons ^ oldButtons);
80
-        if (changes) {
81
-                for (uint8_t i = 0; i < 34; i++) {
82
-                        uint64_t mask = (1ull << i);
83
-                        if ((mask & changes) && joyEvents) {
84
-                                if (buttons & mask) {
85
-                                        joyEvents->OnButtonDn(i);
86
-                                } else {
87
-                                        joyEvents->OnButtonUp(i);
88
-                                }
89
-                        }
90
-                }
91
-                oldButtons = buttons;
92
-        }
93
-
94
-        if (oldMouse != buf[13] && joyEvents) {
95
-          oldMouse = buf[13];
96
-          joyEvents->OnMouseMoved((buf[13] & 0xF0) >> 4, buf[13] & 0x0F);
97
-        }
98
-}
99
-
100
-void JoystickEvents::OnGamePadChanged(const GamePadEventData *evt) {
101
-        Serial.print("X: ");
102
-        PrintHex<uint16_t > (evt->X, 0x80);
103
-        Serial.print("\tY: ");
104
-        PrintHex<uint16_t > (evt->Y, 0x80);
105
-        Serial.print("\tZ: ");
106
-        PrintHex<uint8_t > (evt->Z, 0x80);
107
-        Serial.print("\tRx: ");
108
-        PrintHex<uint8_t > (evt->Rx, 0x80);
109
-        Serial.print("\tRy: ");
110
-        PrintHex<uint8_t > (evt->Ry, 0x80);
111
-        Serial.print("\tRz: ");
112
-        PrintHex<uint16_t > (evt->Rz, 0x80);
113
-        Serial.print("\tSlider: ");
114
-        PrintHex<uint8_t > (evt->Slider, 0x80);
115
-        Serial.println("");
116
-}
117
-
118
-void JoystickEvents::OnHatSwitch(uint8_t hat) {
119
-        Serial.print("Hat Switch: ");
120
-        PrintHex<uint8_t > (hat, 0x80);
121
-        Serial.println("");
122
-}
123
-
124
-void JoystickEvents::OnButtonUp(uint8_t but_id) {
125
-        Serial.print("Up: ");
126
-        Serial.println(but_id, DEC);
127
-}
128
-
129
-void JoystickEvents::OnButtonDn(uint8_t but_id) {
130
-        Serial.print("Dn: ");
131
-        Serial.println(but_id, DEC);
132
-}
133
-
134
-void JoystickEvents::OnMouseMoved(uint8_t x, uint8_t y) {
135
-        Serial.print("Mouse X: ");
136
-        PrintHex<uint8_t >(x, 0x80);
137
-        Serial.print("\tY: ");
138
-        PrintHex<uint8_t >(y, 0x80);
139
-        Serial.println("");
140
-}
141
-

+ 0
- 44
hidjoystickrptparser.h View File

@@ -1,44 +0,0 @@
1
-#if !defined(__HIDJOYSTICKRPTPARSER_H__)
2
-#define __HIDJOYSTICKRPTPARSER_H__
3
-
4
-#include <hid.h>
5
-
6
-/*
7
- * Adapted for the Saitek X52 flight controller
8
- */
9
-
10
-struct GamePadEventData {
11
-        uint16_t X, Y, Rz; // 11bit, 11bit, 10bit
12
-        uint8_t Z, Rx, Ry, Slider;
13
-};
14
-
15
-class JoystickEvents {
16
-public:
17
-        virtual void OnGamePadChanged(const GamePadEventData *evt);
18
-        virtual void OnHatSwitch(uint8_t hat);
19
-        virtual void OnButtonUp(uint8_t but_id);
20
-        virtual void OnButtonDn(uint8_t but_id);
21
-        virtual void OnMouseMoved(uint8_t x, uint8_t y);
22
-};
23
-
24
-#define RPT_GEMEPAD_LEN 8
25
-#define BUFFER_SIZE 16
26
-
27
-class JoystickReportParser : public HIDReportParser {
28
-        JoystickEvents *joyEvents;
29
-
30
-        uint8_t buf[BUFFER_SIZE];
31
-        uint8_t oldPad[RPT_GEMEPAD_LEN];
32
-        uint8_t oldHat;
33
-        uint64_t oldButtons;
34
-        uint8_t oldMouse;
35
-        GamePadEventData buffer;
36
-
37
-public:
38
-        JoystickReportParser(JoystickEvents *evt);
39
-
40
-        virtual void Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *bufPart);
41
-};
42
-
43
-#endif // __HIDJOYSTICKRPTPARSER_H__
44
-

+ 56
- 0
joystick_events.cpp View File

@@ -0,0 +1,56 @@
1
+/*
2
+ * Saitek X52 Arduino USB Host Shield Library.
3
+ * Copyright 2016 by Thomas Buck <xythobuz@xythobuz.de>
4
+ * 
5
+ * Based on the USB Host Library HID Joystick example
6
+ * https://www.circuitsathome.com/mcu/hid-joystick-code-sample
7
+ * 
8
+ * This program is free software; you can redistribute it and/or
9
+ * modify it under the terms of the GNU General Public License as
10
+ * published by the Free Software Foundation, version 2.
11
+ */
12
+
13
+#include "hid_parser.h"
14
+
15
+void JoystickEvents::OnGamePadChanged(const GamePadEventData *evt) {
16
+    Serial.print("X: ");
17
+    PrintHex<uint16_t > (evt->X, 0x80);
18
+    Serial.print("\tY: ");
19
+    PrintHex<uint16_t > (evt->Y, 0x80);
20
+    Serial.print("\tZ: ");
21
+    PrintHex<uint8_t > (evt->Z, 0x80);
22
+    Serial.print("\tRx: ");
23
+    PrintHex<uint8_t > (evt->Rx, 0x80);
24
+    Serial.print("\tRy: ");
25
+    PrintHex<uint8_t > (evt->Ry, 0x80);
26
+    Serial.print("\tRz: ");
27
+    PrintHex<uint16_t > (evt->Rz, 0x80);
28
+    Serial.print("\tSlider: ");
29
+    PrintHex<uint8_t > (evt->Slider, 0x80);
30
+    Serial.println("");
31
+}
32
+
33
+void JoystickEvents::OnHatSwitch(uint8_t hat) {
34
+    Serial.print("Hat Switch: ");
35
+    PrintHex<uint8_t > (hat, 0x80);
36
+    Serial.println("");
37
+}
38
+
39
+void JoystickEvents::OnButtonUp(uint8_t but_id) {
40
+    Serial.print("Up: ");
41
+    Serial.println(but_id, DEC);
42
+}
43
+
44
+void JoystickEvents::OnButtonDn(uint8_t but_id) {
45
+    Serial.print("Dn: ");
46
+    Serial.println(but_id, DEC);
47
+}
48
+
49
+void JoystickEvents::OnMouseMoved(uint8_t x, uint8_t y) {
50
+    Serial.print("Mouse X: ");
51
+    PrintHex<uint8_t >(x, 0x80);
52
+    Serial.print("\tY: ");
53
+    PrintHex<uint8_t >(y, 0x80);
54
+    Serial.println("");
55
+}
56
+

+ 31
- 0
joystick_events.h View File

@@ -0,0 +1,31 @@
1
+/*
2
+ * Saitek X52 Arduino USB Host Shield Library.
3
+ * Copyright 2016 by Thomas Buck <xythobuz@xythobuz.de>
4
+ * 
5
+ * Based on the USB Host Library HID Joystick example
6
+ * https://www.circuitsathome.com/mcu/hid-joystick-code-sample
7
+ * 
8
+ * This program is free software; you can redistribute it and/or
9
+ * modify it under the terms of the GNU General Public License as
10
+ * published by the Free Software Foundation, version 2.
11
+ */
12
+
13
+#ifndef __JOYSTICK_EVENTS_H__
14
+#define __JOYSTICK_EVENTS_H__
15
+
16
+struct GamePadEventData {
17
+    uint16_t X, Y, Rz; // 11bit, 11bit, 10bit
18
+    uint8_t Z, Rx, Ry, Slider;
19
+};
20
+
21
+class JoystickEvents {
22
+  public:
23
+    virtual void OnGamePadChanged(const GamePadEventData *evt);
24
+    virtual void OnHatSwitch(uint8_t hat);
25
+    virtual void OnButtonUp(uint8_t but_id);
26
+    virtual void OnButtonDn(uint8_t but_id);
27
+    virtual void OnMouseMoved(uint8_t x, uint8_t y);
28
+};
29
+
30
+#endif // __JOYSTICK_EVENTS_H__
31
+

+ 163
- 0
x52.cpp View File

@@ -0,0 +1,163 @@
1
+/*
2
+ * Saitek X52 Arduino USB Host Shield Library.
3
+ * Copyright 2016 by Thomas Buck <xythobuz@xythobuz.de>
4
+ * 
5
+ * Based on "x52pro-linux" by Nirenjan Krishnan
6
+ * https://github.com/nirenjan/x52pro-linux
7
+ * 
8
+ * This program is free software; you can redistribute it and/or
9
+ * modify it under the terms of the GNU General Public License as
10
+ * published by the Free Software Foundation, version 2.
11
+ */
12
+
13
+#include "x52.h"
14
+
15
+#define TIME_24H_FORMAT
16
+#define DEBUG_OUTPUT
17
+
18
+X52::X52(USB* u, HID* h) : usb(u), hid(h) { }
19
+
20
+void X52::setTime(uint8_t h, uint8_t m) {
21
+    uint8_t ret = sendCommand(X52_TIME_CLOCK1, m | ((h & 0x7F) << 8)
22
+#ifdef TIME_24H_FORMAT
23
+            | (1 << 15)
24
+#endif
25
+            );
26
+    if (ret) {
27
+#ifdef DEBUG_OUTPUT
28
+        Serial.print("Error setting time: ");
29
+        Serial.println(ret, DEC);
30
+#endif
31
+    }
32
+}
33
+
34
+void X52::setTimeOffset(uint8_t cl, int16_t offset) {
35
+    if (offset < -1023) {
36
+        offset = -1023;
37
+    }
38
+    
39
+    if (offset > 1023) {
40
+        offset = 1023;
41
+    }
42
+    
43
+    uint8_t negative = 0;
44
+    if (offset < 0) {
45
+        negative = 1;
46
+        offset = -offset;
47
+    }
48
+
49
+    uint8_t ret = sendCommand(cl ? X52_OFFS_CLOCK3 : X52_OFFS_CLOCK2,
50
+            (negative << 10) | (offset & 0x03FF)
51
+#ifdef TIME_24H_FORMAT
52
+            | (1 << 15)
53
+#endif
54
+            );
55
+    if (ret) {
56
+#ifdef DEBUG_OUTPUT
57
+        Serial.print("Error setting offset: ");
58
+        Serial.println(ret, DEC);
59
+#endif
60
+    }
61
+}
62
+
63
+void X52::setDate(uint8_t dd, uint8_t mm, uint8_t yy) {
64
+    uint8_t ret = sendCommand(X52_DATE_DDMM, dd | (mm << 8));
65
+    if (!ret) {
66
+        ret = sendCommand(X52_DATE_YEAR, yy);
67
+    }
68
+    if (ret) {
69
+#ifdef DEBUG_OUTPUT
70
+        Serial.print("Error setting date: ");
71
+        Serial.println(ret, DEC);
72
+#endif
73
+    }
74
+}
75
+
76
+void X52::setBlink(uint8_t state) {
77
+    uint8_t ret = sendCommand(X52_BLINK_INDICATOR, state ? X52_BLINK_ON : X52_BLINK_OFF);
78
+    if (ret != 0) {
79
+#ifdef DEBUG_OUTPUT
80
+        Serial.print("Error setting blink: ");
81
+        Serial.println(ret, DEC);
82
+#endif
83
+    }
84
+}
85
+
86
+void X52::setShift(uint8_t state) {
87
+    uint8_t ret = sendCommand(X52_SHIFT_INDICATOR, state ? X52_SHIFT_ON : X52_SHIFT_OFF);
88
+    if (ret != 0) {
89
+#ifdef DEBUG_OUTPUT
90
+        Serial.print("Error setting shift: ");
91
+        Serial.println(ret, DEC);
92
+#endif
93
+    }
94
+}
95
+
96
+void X52::setMFDText(uint8_t line, const char* text) {
97
+    const static uint16_t lines[3] = {
98
+        X52_MFD_LINE1,
99
+        X52_MFD_LINE2,
100
+        X52_MFD_LINE3
101
+    };
102
+
103
+    if (line >= 3) {
104
+        return;
105
+    }
106
+
107
+    uint8_t ret = sendCommand(X52_MFD_CLEAR_LINE | lines[line], 0);
108
+    if (ret) {
109
+#ifdef DEBUG_OUTPUT
110
+        Serial.print("Error clearing line: ");
111
+        Serial.println(ret, DEC);
112
+#endif
113
+        return;
114
+    }
115
+
116
+    for (uint8_t i = 0; i < 16; i += 2) {
117
+        if (text[i] == '\0') {
118
+            break;
119
+        }
120
+
121
+        uint16_t value = text[i];
122
+
123
+        if (text[i + 1] != '\0') {
124
+            value |= text[i + 1] << 8;
125
+        }
126
+
127
+        ret = sendCommand(X52_MFD_WRITE_LINE | lines[line], value);
128
+        if (ret) {
129
+#ifdef DEBUG_OUTPUT
130
+            Serial.print("Error writing to line: ");
131
+            Serial.println(ret, DEC);
132
+#endif
133
+            return;
134
+        }
135
+
136
+        if (text[i + 1] == '\0') {
137
+            break;
138
+        }
139
+    }
140
+}
141
+
142
+uint8_t X52::sendCommand(uint16_t command, uint16_t val) {
143
+    const uint8_t valLo = (val & 0x00FF);
144
+    const uint8_t valHi = (val & 0xFF00) >> 8;
145
+
146
+#ifdef DEBUG_OUTPUT
147
+    Serial.println("Sending X52 Ctrl-Req...");
148
+#endif
149
+
150
+    uint8_t ret = usb->ctrlReq(hid->GetAddress(), 0,
151
+                              USB_SETUP_TYPE_VENDOR | USB_SETUP_RECIPIENT_DEVICE,
152
+                              X52_VENDOR_REQUEST, valLo, valHi, command,
153
+                              0, 0, NULL, NULL);
154
+    if (ret != 0) {
155
+#ifdef DEBUG_OUTPUT
156
+        Serial.print("Ctrl-Req Error Code: ");
157
+        Serial.println(val, DEC);
158
+#endif
159
+    }
160
+
161
+    return ret;
162
+}
163
+

+ 86
- 0
x52.h View File

@@ -0,0 +1,86 @@
1
+/*
2
+ * Saitek X52 Arduino USB Host Shield Library.
3
+ * Copyright 2016 by Thomas Buck <xythobuz@xythobuz.de>
4
+ * 
5
+ * Based on "x52pro-linux" by Nirenjan Krishnan
6
+ * https://github.com/nirenjan/x52pro-linux
7
+ * 
8
+ * This program is free software; you can redistribute it and/or
9
+ * modify it under the terms of the GNU General Public License as
10
+ * published by the Free Software Foundation, version 2.
11
+ */
12
+
13
+#ifndef __X52_H__
14
+#define __X52_H__
15
+
16
+#include <hid.h>
17
+
18
+#define X52_VENDOR_REQUEST 0x91
19
+#define X52_MFD_BRIGHTNESS 0xB1
20
+#define X52_LED_BRIGHTNESS 0xB2
21
+#define X52_MFD_CLEAR_LINE 0x08
22
+#define X52_MFD_WRITE_LINE 0x00
23
+#define X52_MFD_LINE1 0xD1
24
+#define X52_MFD_LINE2 0xD2
25
+#define X52_MFD_LINE3 0xD4
26
+#define X52_SHIFT_INDICATOR 0xFD
27
+#define X52_SHIFT_ON 0x51
28
+#define X52_SHIFT_OFF 0x50
29
+#define X52_BLINK_INDICATOR 0xB4
30
+#define X52_BLINK_ON 0x51
31
+#define X52_BLINK_OFF 0x50
32
+#define X52_DATE_DDMM 0xC4
33
+#define X52_DATE_YEAR 0xC8
34
+#define X52_TIME_CLOCK1 0xC0
35
+#define X52_OFFS_CLOCK2 0xC1
36
+#define X52_OFFS_CLOCK3 0xC2
37
+
38
+class X52 {
39
+  public:
40
+    X52(USB* u, HID* h);
41
+
42
+    /*
43
+     * Set brightness of LEDs and MFD backlight.
44
+     * Three states, 0=off, 1=dim, 2=on.
45
+     */
46
+    void setLEDBrightness(uint16_t val) { sendCommand(X52_LED_BRIGHTNESS, val); }
47
+    void setMFDBrightness(uint16_t val) { sendCommand(X52_MFD_BRIGHTNESS, val); }
48
+    
49
+    /*
50
+     * Print text on the MFD lines (0 - 2).
51
+     * Maximum of 16 characters per line.
52
+     */
53
+    void setMFDText(uint8_t line, const char* text);
54
+
55
+    /*
56
+     * Enable (1) or Disable(0) the MFD shift indicator.
57
+     */
58
+    void setShift(uint8_t state);
59
+
60
+    /*
61
+     * Fast blinking of Info and Hat LEDs.
62
+     * State can be 0=off or 1=on.
63
+     */
64
+    void setBlink(uint8_t state);
65
+
66
+    /*
67
+     * Set date. The third digit seems to be broken in hardware?
68
+     */
69
+    void setDate(uint8_t dd, uint8_t mm, uint8_t yy);
70
+
71
+    /*
72
+     * Set time. There seems to be a problem with time offsets
73
+     * and the 12h/24h time format conflicting...?
74
+     */
75
+    void setTime(uint8_t h, uint8_t m);
76
+    void setTimeOffset(uint8_t cl, int16_t offset);
77
+
78
+  private:
79
+    uint8_t sendCommand(uint16_t command, uint16_t val);
80
+    
81
+    USB* usb;
82
+    HID* hid;
83
+};
84
+
85
+#endif // __X52_H__
86
+

Loading…
Cancel
Save