Skip to content

Commit 7cf67b2

Browse files
authored
Merge pull request hathach#1889 from Tails86/master
Implemented tuh_hid_send_report
2 parents be21413 + 9247131 commit 7cf67b2

File tree

3 files changed

+126
-14
lines changed

3 files changed

+126
-14
lines changed

examples/host/hid_controller/src/hid_app.c

Lines changed: 79 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,8 @@ typedef struct TU_ATTR_PACKED
9191
uint8_t counter : 6; // +1 each report
9292
};
9393

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
9796

9897
// uint16_t timestamp;
9998
// uint8_t battery;
@@ -105,15 +104,54 @@ typedef struct TU_ATTR_PACKED
105104

106105
} sony_ds4_report_t;
107106

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+
108146
// check if device is Sony DualShock 4
109147
static inline bool is_sony_ds4(uint8_t dev_addr)
110148
{
111149
uint16_t vid, pid;
112150
tuh_vid_pid_get(dev_addr, &vid, &pid);
113151

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)
117155
|| (vid == 0x1f4f && pid == 0x1002) // ASW GG xrd controller
118156
);
119157
}
@@ -124,7 +162,23 @@ static inline bool is_sony_ds4(uint8_t dev_addr)
124162

125163
void hid_app_task(void)
126164
{
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+
}
128182
}
129183

130184
//--------------------------------------------------------------------+
@@ -149,6 +203,14 @@ void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_re
149203
// Sony DualShock 4 [CUH-ZCT2x]
150204
if ( is_sony_ds4(dev_addr) )
151205
{
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+
}
152214
// request to receive report
153215
// tuh_hid_report_received_cb() will be invoked when report is available
154216
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
162224
void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance)
163225
{
164226
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+
}
165231
}
166232

167233
// check if different than 2
@@ -179,8 +245,8 @@ bool diff_report(sony_ds4_report_t const* rpt1, sony_ds4_report_t const* rpt2)
179245
result = diff_than_2(rpt1->x, rpt2->x) || diff_than_2(rpt1->y , rpt2->y ) ||
180246
diff_than_2(rpt1->z, rpt2->z) || diff_than_2(rpt1->rz, rpt2->rz);
181247

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);
184250

185251
return result;
186252
}
@@ -234,6 +300,10 @@ void process_sony_ds4(uint8_t const* report, uint16_t len)
234300
printf("\r\n");
235301
}
236302

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+
237307
prev_report = ds4_report;
238308
}
239309
}

src/class/hid/hid_host.c

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*
1+
/*
22
* The MIT License (MIT)
33
*
44
* Copyright (c) 2019 Ha Thach (tinyusb.org)
@@ -274,7 +274,49 @@ bool tuh_hid_receive_report(uint8_t dev_addr, uint8_t instance)
274274
// return !usbh_edpt_busy(dev_addr, hid_itf->ep_in);
275275
//}
276276

277-
//void tuh_hid_send_report(uint8_t dev_addr, uint8_t instance, uint8_t report_id, uint8_t const* report, uint16_t len);
277+
bool tuh_hid_send_report(uint8_t dev_addr, uint8_t instance, uint8_t report_id, const void* report, uint16_t len)
278+
{
279+
TU_LOG2("HID Send Report %d\r\n", report_id);
280+
281+
hidh_interface_t* hid_itf = get_instance(dev_addr, instance);
282+
283+
if (hid_itf->ep_out == 0)
284+
{
285+
// This HID does not have an out endpoint (other than control)
286+
return false;
287+
}
288+
else if (len > CFG_TUH_HID_EPOUT_BUFSIZE
289+
|| (report_id != 0 && len > (CFG_TUH_HID_EPOUT_BUFSIZE - 1)))
290+
{
291+
// ep_out buffer is not large enough to hold contents
292+
return false;
293+
}
294+
295+
// claim endpoint
296+
TU_VERIFY( usbh_edpt_claim(dev_addr, hid_itf->ep_out) );
297+
298+
if (report_id == 0)
299+
{
300+
// No report ID in transmission
301+
memcpy(&hid_itf->epout_buf[0], report, len);
302+
}
303+
else
304+
{
305+
hid_itf->epout_buf[0] = report_id;
306+
memcpy(&hid_itf->epout_buf[1], report, len);
307+
++len; // 1 more byte for report_id
308+
}
309+
310+
TU_LOG3_MEM(hid_itf->epout_buf, len, 2);
311+
312+
if ( !usbh_edpt_xfer(dev_addr, hid_itf->ep_out, hid_itf->epout_buf, len) )
313+
{
314+
usbh_edpt_release(dev_addr, hid_itf->ep_out);
315+
return false;
316+
}
317+
318+
return true;
319+
}
278320

279321
//--------------------------------------------------------------------+
280322
// USBH API
@@ -349,7 +391,7 @@ bool hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *de
349391
hidh_device_t* hid_dev = get_dev(dev_addr);
350392
TU_ASSERT(hid_dev->inst_count < CFG_TUH_HID, 0);
351393

352-
hidh_interface_t* hid_itf = get_instance(dev_addr, hid_dev->inst_count);
394+
hidh_interface_t* hid_itf = get_instance(dev_addr, hid_dev->inst_count);
353395

354396
//------------- Endpoint Descriptors -------------//
355397
p_desc = tu_desc_next(p_desc);

src/class/hid/hid_host.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*
1+
/*
22
* The MIT License (MIT)
33
*
44
* Copyright (c) 2019 Ha Thach (tinyusb.org)
@@ -106,7 +106,7 @@ bool tuh_hid_receive_report(uint8_t dev_addr, uint8_t instance);
106106

107107
// Send report using interrupt endpoint
108108
// If report_id > 0 (composite), it will be sent as 1st byte, then report contents. Otherwise only report content is sent.
109-
//void tuh_hid_send_report(uint8_t dev_addr, uint8_t instance, uint8_t report_id, uint8_t const* report, uint16_t len);
109+
bool tuh_hid_send_report(uint8_t dev_addr, uint8_t instance, uint8_t report_id, const void* report, uint16_t len);
110110

111111
//--------------------------------------------------------------------+
112112
// Callbacks (Weak is optional)

0 commit comments

Comments
 (0)