Browse Source

Use TimerOne library for CPPM output. Renamed files.

Thomas Buck 3 years ago
parent
commit
0a93918345
9 changed files with 144 additions and 100 deletions
  1. 4
    2
      Saitek-X52-PPM.ino
  2. 12
    62
      cppm.cpp
  3. 4
    19
      cppm.h
  4. 30
    0
      data.h
  5. 19
    11
      events.h
  6. 63
    0
      events_cppm.cpp
  7. 4
    1
      events_deadzone.cpp
  8. 2
    1
      parser.cpp
  9. 6
    4
      parser.h

+ 4
- 2
Saitek-X52-PPM.ino View File

@@ -14,7 +14,8 @@
14 14
 #include <hiduniversal.h>
15 15
 #include <usbhub.h>
16 16
 
17
-#include "hid_parser.h"
17
+#include "events.h"
18
+#include "parser.h"
18 19
 #include "x52.h"
19 20
 
20 21
 #define ENABLE_SERIAL_PORT
@@ -24,7 +25,8 @@ USB usb;
24 25
 USBHub hub(&usb);
25 26
 HIDUniversal hid(&usb);
26 27
 X52 x52(&usb, &hid);
27
-JoystickEventsDeadZone joyevents;
28
+JoystickEventsCPPM joyCPPM;
29
+JoystickEventsDeadZone joyevents((JoystickEvents*)&joyCPPM);
28 30
 JoystickReportParser joy(&joyevents);
29 31
 
30 32
 void setup() {

cppm.c → cppm.cpp View File

@@ -28,14 +28,11 @@
28 28
  * modify it under the terms of the GNU General Public License as
29 29
  * published by the Free Software Foundation, version 2.
30 30
  */
31
-
32
-#include <avr/io.h>
33
-#include <avr/interrupt.h>
34
-
31
+#include <TimerOne.h>
35 32
 #include "cppm.h"
36 33
 
37
-#define MAX_STATES 17
38 34
 #define CHANNELS 8
35
+#define MAX_STATES ((2 * CHANNELS) + 1)
39 36
 #define WHOLE_PULSE_WIDTH 20000
40 37
 #define PULSE_WIDTH 2000
41 38
 #define MAX_PULSE_WIDTH (CHANNELS * PULSE_WIDTH) // 16.000
@@ -48,32 +45,15 @@
48 45
 volatile uint16_t cppmData[CHANNELS] = { 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500 };
49 46
 volatile uint16_t delaySum = 0;
50 47
 volatile uint8_t state = 0;
51
-volatile uint16_t triggerTimeRemaining = 0;
52
-
53
-#define NONE 0
54
-#define COMPARE_MATCH 1
55
-#define OVERFLOW 2
56
-volatile uint8_t triggerState = NONE;
57 48
 
58 49
 static void triggerIn(uint16_t us);
59 50
 static void nextState(void);
60 51
 
61 52
 void cppmInit(void) {
62
-    // Set pin to output mode
63
-    CPPM_DDR |= (1 << CPPM_PIN);
64
-
65
-    // Start with a low pulse
66
-    CPPM_PORT &= ~(1 << CPPM_PIN);
67
-
68
-    TCCR0B |= (1 << CS01); // Prescaler: 8
69
-
70
-#ifdef DEBUG
71
-    TIMSK0 |= (1 << TOIE0) | (1 << OCIE0A); // Enable Overflow and Compare Match Interrupt
72
-#else
73
-    TIMSK |= (1 << TOIE0) | (1 << OCIE0A); // Enable Overflow and Compare Match Interrupt
74
-#endif
75
-    OCR0A = 0;
76
-
53
+    pinMode(CPPM_OUTPUT_PIN, OUTPUT);
54
+    digitalWrite(CPPM_OUTPUT_PIN, LOW);
55
+    Timer1.initialize();
56
+    Timer1.attachInterrupt(&nextState);
77 57
     state = 0;
78 58
     delaySum = MIN_WAIT;
79 59
     triggerIn(PULSE_LOW);
@@ -88,17 +68,13 @@ void cppmCopy(uint16_t *data) {
88 68
 }
89 69
 
90 70
 static void triggerIn(uint16_t us) {
91
-    TCNT0 = 0; // Reset Timer
92
-    if (us <= (TIME_AFTER_OVERFLOW - 1)) {
93
-        triggerState = COMPARE_MATCH;
94
-        OCR0A = us * TIME_MULTIPLIER;
95
-    } else {
96
-        triggerState = OVERFLOW;
97
-        triggerTimeRemaining = us - TIME_AFTER_OVERFLOW;
98
-    }
71
+    Timer1.setPeriod(us);
72
+    // TODO reset timer?
99 73
 }
100 74
 
101 75
 static void nextState(void) {
76
+    // TODO stop timer?
77
+    
102 78
     state++;
103 79
     if (state > MAX_STATES) {
104 80
         state = 0;
@@ -106,10 +82,10 @@ static void nextState(void) {
106 82
     }
107 83
     if ((state % 2) == 0) {
108 84
         // pulse pause
109
-        CPPM_PORT &= ~(1 << CPPM_PIN);
85
+        digitalWrite(CPPM_OUTPUT_PIN, LOW);
110 86
         triggerIn(PULSE_LOW);
111 87
     } else {
112
-        CPPM_PORT |= (1 << CPPM_PIN);
88
+        digitalWrite(CPPM_OUTPUT_PIN, HIGH);
113 89
         if (state <= 15) {
114 90
             // normal ppm pulse
115 91
             uint8_t index = state / 2;
@@ -122,29 +98,3 @@ static void nextState(void) {
122 98
     }
123 99
 }
124 100
 
125
-#ifdef DEBUG
126
-ISR(TIMER0_OVF_vect) {
127
-#else
128
-ISR(TIM0_OVF_vect) {
129
-#endif
130
-    if (triggerState == OVERFLOW) {
131
-        if (triggerTimeRemaining == 0) {
132
-            triggerState = NONE;
133
-            nextState();
134
-        } else {
135
-            triggerIn(triggerTimeRemaining);
136
-        }
137
-    }
138
-}
139
-
140
-#ifdef DEBUG
141
-ISR(TIMER0_COMPA_vect) {
142
-#else
143
-ISR(TIM0_COMPA_vect) {
144
-#endif
145
-    if (triggerState == COMPARE_MATCH) {
146
-        triggerState = NONE;
147
-        nextState();
148
-    }
149
-}
150
-

+ 4
- 19
cppm.h View File

@@ -7,30 +7,15 @@
7 7
  * published by the Free Software Foundation, version 2.
8 8
  */
9 9
 
10
-#ifndef _CPPM_H
11
-#define _CPPM_H
10
+#ifndef __CPPM_H__
11
+#define __CPPM_H__
12 12
 
13 13
 #include <stdint.h>
14 14
 
15
-#ifdef DEBUG
16
-
17
-// Arduino D10
18
-#define CPPM_PORT PORTB
19
-#define CPPM_DDR DDRB
20
-#define CPPM_PIN PB2
21
-
22
-#else
23
-
24
-#define CPPM_PORT PORTB
25
-#define CPPM_DDR DDRB
26
-#define CPPM_PIN PB5
27
-
28
-#endif
29
-
30
-extern volatile uint16_t cppmData[8];
15
+#define CPPM_OUTPUT_PIN 13
31 16
 
32 17
 void cppmInit(void);
33 18
 void cppmCopy(uint16_t *data);
34 19
 
35
-#endif
20
+#endif // __CPPM_H__
36 21
 

+ 30
- 0
data.h View File

@@ -0,0 +1,30 @@
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 __GAMEPAD_EVENT_DATA_H__
14
+#define __GAMEPAD_EVENT_DATA_H__
15
+
16
+#include <stdint.h>
17
+
18
+class GamePadEventData {
19
+  public:
20
+    GamePadEventData(uint16_t v) : X(v), Y(v), Z(v), Rx(v), Ry(v), Rz(v), Slider(v) { }
21
+    GamePadEventData(uint16_t x, uint16_t y, uint8_t z, uint8_t rx, uint8_t ry,
22
+            uint16_t rz, uint8_t slider)
23
+            : X(x), Y(y), Z(z), Rx(rx), Ry(ry), Rz(rz), Slider(slider) { }
24
+
25
+    uint16_t X, Y, Rz; // 11bit, 11bit, 10bit
26
+    uint8_t Z, Rx, Ry, Slider;
27
+};
28
+
29
+#endif // __GAMEPAD_EVENT_DATA_H__
30
+

joystick_events.h → events.h View File

@@ -13,20 +13,13 @@
13 13
 #ifndef __JOYSTICK_EVENTS_H__
14 14
 #define __JOYSTICK_EVENTS_H__
15 15
 
16
-class GamePadEventData {
17
-  public:
18
-    GamePadEventData(uint16_t v) : X(v), Y(v), Z(v), Rx(v), Ry(v), Rz(v), Slider(v) { }
19
-    GamePadEventData(uint16_t x, uint16_t y, uint8_t z, uint8_t rx, uint8_t ry,
20
-            uint16_t rz, uint8_t slider)
21
-            : X(x), Y(y), Z(z), Rx(rx), Ry(ry), Rz(rz), Slider(slider) { }
16
+#include <stdint.h>
22 17
 
23
-    uint16_t X, Y, Rz; // 11bit, 11bit, 10bit
24
-    uint8_t Z, Rx, Ry, Slider;
25
-};
18
+class GamePadEventData;
26 19
 
27 20
 class JoystickEvents {
28 21
   public:
29
-    JoystickEvents(JoystickEvents* _client = NULL) : client(_client) { }
22
+    JoystickEvents(JoystickEvents* _client = 0) : client(_client) { }
30 23
     virtual void OnGamePadChanged(const GamePadEventData& evt) = 0;
31 24
     virtual void OnHatSwitch(uint8_t hat) = 0;
32 25
     virtual void OnButtonUp(uint8_t but_id) = 0;
@@ -39,13 +32,14 @@ class JoystickEvents {
39 32
 
40 33
 class JoystickEventsDeadZone : public JoystickEvents {
41 34
   public:
35
+    JoystickEventsDeadZone(JoystickEvents* client = 0) : JoystickEvents(client) { }
42 36
     virtual void OnGamePadChanged(const GamePadEventData& evt);
43 37
     virtual void OnHatSwitch(uint8_t hat);
44 38
     virtual void OnButtonUp(uint8_t but_id);
45 39
     virtual void OnButtonDn(uint8_t but_id);
46 40
     virtual void OnMouseMoved(uint8_t x, uint8_t y);
47 41
 
48
-  protected:
42
+  private:
49 43
     const static GamePadEventData deadZone;
50 44
     const static uint8_t deadZoneMouseX, deadZoneMouseY;
51 45
 
@@ -53,5 +47,19 @@ class JoystickEventsDeadZone : public JoystickEvents {
53 47
     const static uint8_t centerMouseX, centerMouseY;
54 48
 };
55 49
 
50
+class JoystickEventsCPPM : public JoystickEvents {
51
+  public:
52
+    JoystickEventsCPPM(JoystickEvents* client = 0);
53
+    virtual void OnGamePadChanged(const GamePadEventData& evt);
54
+    virtual void OnHatSwitch(uint8_t hat);
55
+    virtual void OnButtonUp(uint8_t but_id);
56
+    virtual void OnButtonDn(uint8_t but_id);
57
+    virtual void OnMouseMoved(uint8_t x, uint8_t y);
58
+
59
+  private:
60
+    const static uint8_t channels = 8;
61
+    uint16_t values[channels];
62
+};
63
+
56 64
 #endif // __JOYSTICK_EVENTS_H__
57 65
 

+ 63
- 0
events_cppm.cpp View File

@@ -0,0 +1,63 @@
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 "data.h"
14
+#include "cppm.h"
15
+#include "events.h"
16
+
17
+//#define DEBUG_OUTPUT_RAW
18
+#define DEBUG_OUTPUT
19
+
20
+#define CHANNEL_THROTTLE 0
21
+#define CHANNEL_PITCH 2
22
+#define CHANNEL_ROLL 1
23
+#define CHANNEL_YAW 3
24
+#define CHANNEL_AUX1 4
25
+#define CHANNEL_AUX2 5
26
+
27
+JoystickEventsCPPM::JoystickEventsCPPM(JoystickEvents* client) : JoystickEvents(client) {
28
+    for (uint8_t i = 0; i < channels; i++) {
29
+        values[i] = 1500;
30
+    }
31
+
32
+    values[CHANNEL_AUX1] = 200;
33
+    values[CHANNEL_AUX2] = 200;
34
+    
35
+    cppmInit();
36
+    cppmCopy(values);
37
+}
38
+
39
+void JoystickEventsCPPM::OnGamePadChanged(const GamePadEventData& evt) {
40
+    values[CHANNEL_THROTTLE] = evt.Z;
41
+    values[CHANNEL_PITCH] = evt.Y;
42
+    values[CHANNEL_ROLL] = evt.X;
43
+    values[CHANNEL_YAW] = evt.Rz;
44
+
45
+    cppmCopy(values);
46
+}
47
+
48
+void JoystickEventsCPPM::OnHatSwitch(uint8_t hat) {
49
+
50
+}
51
+
52
+void JoystickEventsCPPM::OnButtonUp(uint8_t but_id) {
53
+
54
+}
55
+
56
+void JoystickEventsCPPM::OnButtonDn(uint8_t but_id) {
57
+
58
+}
59
+
60
+void JoystickEventsCPPM::OnMouseMoved(uint8_t x, uint8_t y) {
61
+
62
+}
63
+

joystick_events.cpp → events_deadzone.cpp View File

@@ -10,7 +10,10 @@
10 10
  * published by the Free Software Foundation, version 2.
11 11
  */
12 12
 
13
-#include "hid_parser.h"
13
+#include <usb.h>
14
+
15
+#include "data.h"
16
+#include "events.h"
14 17
 
15 18
 //#define DEBUG_OUTPUT_RAW
16 19
 #define DEBUG_OUTPUT

hid_parser.cpp → parser.cpp View File

@@ -10,7 +10,8 @@
10 10
  * published by the Free Software Foundation, version 2.
11 11
  */
12 12
 
13
-#include "hid_parser.h"
13
+#include "events.h"
14
+#include "parser.h"
14 15
 
15 16
 //#define DEBUG_OUTPUT
16 17
 

hid_parser.h → parser.h View File

@@ -10,15 +10,17 @@
10 10
  * published by the Free Software Foundation, version 2.
11 11
  */
12 12
 
13
-#ifndef __HID_PARSER_H__
14
-#define __HID_PARSER_H__
13
+#ifndef __PARSER_H__
14
+#define __PARSER_H__
15 15
 
16 16
 #include <hid.h>
17
-#include "joystick_events.h"
17
+#include "data.h"
18 18
 
19 19
 #define RPT_GEMEPAD_LEN 8
20 20
 #define BUFFER_SIZE 16
21 21
 
22
+class JoystickEvents;
23
+
22 24
 class JoystickReportParser : public HIDReportParser {
23 25
   public:
24 26
     JoystickReportParser(JoystickEvents* evt);
@@ -34,5 +36,5 @@ class JoystickReportParser : public HIDReportParser {
34 36
     JoystickEvents* joyEvents;
35 37
 };
36 38
 
37
-#endif // __HID_PARSER_H__
39
+#endif // __PARSER_H__
38 40
 

Loading…
Cancel
Save