@@ -91,9 +91,8 @@ typedef struct TU_ATTR_PACKED
91
91
uint8_t counter : 6 ; // +1 each report
92
92
};
93
93
94
- // comment out since not used by this example
95
- // uint8_t l2_trigger; // 0 released, 0xff fully pressed
96
- // uint8_t r2_trigger; // as above
94
+ uint8_t l2_trigger ; // 0 released, 0xff fully pressed
95
+ uint8_t r2_trigger ; // as above
97
96
98
97
// uint16_t timestamp;
99
98
// uint8_t battery;
@@ -105,15 +104,54 @@ typedef struct TU_ATTR_PACKED
105
104
106
105
} sony_ds4_report_t ;
107
106
107
+ typedef struct TU_ATTR_PACKED {
108
+ // First 16 bits set what data is pertinent in this structure (1 = set; 0 = not set)
109
+ uint8_t set_rumble : 1 ;
110
+ uint8_t set_led : 1 ;
111
+ uint8_t set_led_blink : 1 ;
112
+ uint8_t set_ext_write : 1 ;
113
+ uint8_t set_left_volume : 1 ;
114
+ uint8_t set_right_volume : 1 ;
115
+ uint8_t set_mic_volume : 1 ;
116
+ uint8_t set_speaker_volume : 1 ;
117
+ uint8_t set_flags2 ;
118
+
119
+ uint8_t reserved ;
120
+
121
+ uint8_t motor_right ;
122
+ uint8_t motor_left ;
123
+
124
+ uint8_t lightbar_red ;
125
+ uint8_t lightbar_green ;
126
+ uint8_t lightbar_blue ;
127
+ uint8_t lightbar_blink_on ;
128
+ uint8_t lightbar_blink_off ;
129
+
130
+ uint8_t ext_data [8 ];
131
+
132
+ uint8_t volume_left ;
133
+ uint8_t volume_right ;
134
+ uint8_t volume_mic ;
135
+ uint8_t volume_speaker ;
136
+
137
+ uint8_t other [9 ];
138
+ } sony_ds4_output_report_t ;
139
+
140
+ static bool ds4_mounted = false;
141
+ static uint8_t ds4_dev_addr = 0 ;
142
+ static uint8_t ds4_instance = 0 ;
143
+ static uint8_t motor_left = 0 ;
144
+ static uint8_t motor_right = 0 ;
145
+
108
146
// check if device is Sony DualShock 4
109
147
static inline bool is_sony_ds4 (uint8_t dev_addr )
110
148
{
111
149
uint16_t vid , pid ;
112
150
tuh_vid_pid_get (dev_addr , & vid , & pid );
113
151
114
- return ( (vid == 0x054c && (pid == 0x09cc || pid == 0x05c4 )) // Sony DualShock4
115
- || (vid == 0x0f0d && pid == 0x005e ) // Hori FC4
116
- || (vid == 0x0f0d && pid == 0x00ee ) // Hori PS4 Mini (PS4-099U)
152
+ return ( (vid == 0x054c && (pid == 0x09cc || pid == 0x05c4 )) // Sony DualShock4
153
+ || (vid == 0x0f0d && pid == 0x005e ) // Hori FC4
154
+ || (vid == 0x0f0d && pid == 0x00ee ) // Hori PS4 Mini (PS4-099U)
117
155
|| (vid == 0x1f4f && pid == 0x1002 ) // ASW GG xrd controller
118
156
);
119
157
}
@@ -124,7 +162,23 @@ static inline bool is_sony_ds4(uint8_t dev_addr)
124
162
125
163
void hid_app_task (void )
126
164
{
127
- // nothing to do
165
+ if (ds4_mounted )
166
+ {
167
+ const uint32_t interval_ms = 200 ;
168
+ static uint32_t start_ms = 0 ;
169
+
170
+ uint32_t current_time_ms = board_millis ();
171
+ if ( current_time_ms - start_ms >= interval_ms )
172
+ {
173
+ start_ms = current_time_ms ;
174
+
175
+ sony_ds4_output_report_t output_report = {0 };
176
+ output_report .set_rumble = 1 ;
177
+ output_report .motor_left = motor_left ;
178
+ output_report .motor_right = motor_right ;
179
+ tuh_hid_send_report (ds4_dev_addr , ds4_instance , 5 , & output_report , sizeof (output_report ));
180
+ }
181
+ }
128
182
}
129
183
130
184
//--------------------------------------------------------------------+
@@ -149,6 +203,14 @@ void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_re
149
203
// Sony DualShock 4 [CUH-ZCT2x]
150
204
if ( is_sony_ds4 (dev_addr ) )
151
205
{
206
+ if (!ds4_mounted )
207
+ {
208
+ ds4_dev_addr = dev_addr ;
209
+ ds4_instance = instance ;
210
+ motor_left = 0 ;
211
+ motor_right = 0 ;
212
+ ds4_mounted = true;
213
+ }
152
214
// request to receive report
153
215
// tuh_hid_report_received_cb() will be invoked when report is available
154
216
if ( !tuh_hid_receive_report (dev_addr , instance ) )
@@ -162,6 +224,10 @@ void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_re
162
224
void tuh_hid_umount_cb (uint8_t dev_addr , uint8_t instance )
163
225
{
164
226
printf ("HID device address = %d, instance = %d is unmounted\r\n" , dev_addr , instance );
227
+ if (ds4_mounted && ds4_dev_addr == dev_addr && ds4_instance == instance )
228
+ {
229
+ ds4_mounted = false;
230
+ }
165
231
}
166
232
167
233
// check if different than 2
@@ -179,8 +245,8 @@ bool diff_report(sony_ds4_report_t const* rpt1, sony_ds4_report_t const* rpt2)
179
245
result = diff_than_2 (rpt1 -> x , rpt2 -> x ) || diff_than_2 (rpt1 -> y , rpt2 -> y ) ||
180
246
diff_than_2 (rpt1 -> z , rpt2 -> z ) || diff_than_2 (rpt1 -> rz , rpt2 -> rz );
181
247
182
- // check the reset with mem compare
183
- result |= memcmp (& rpt1 -> rz + 1 , & rpt2 -> rz + 1 , sizeof (sony_ds4_report_t )- 4 );
248
+ // check the rest with mem compare
249
+ result |= memcmp (& rpt1 -> rz + 1 , & rpt2 -> rz + 1 , sizeof (sony_ds4_report_t )- 6 );
184
250
185
251
return result ;
186
252
}
@@ -234,6 +300,10 @@ void process_sony_ds4(uint8_t const* report, uint16_t len)
234
300
printf ("\r\n" );
235
301
}
236
302
303
+ // The left and right triggers control the intensity of the left and right rumble motors
304
+ motor_left = ds4_report .l2_trigger ;
305
+ motor_right = ds4_report .r2_trigger ;
306
+
237
307
prev_report = ds4_report ;
238
308
}
239
309
}
0 commit comments