Skip to content

Commit 296ce52

Browse files
Tails86hathach
authored andcommitted
Updated host hid_controller example to demo tuh_hid_send_report
1 parent f6774d5 commit 296ce52

File tree

3 files changed

+80
-11
lines changed

3 files changed

+80
-11
lines changed

examples/host/hid_controller/src/hid_app.c

Lines changed: 78 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,22 @@ 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+
if ( board_millis() - start_ms >= interval_ms)
171+
{
172+
start_ms += interval_ms;
173+
174+
sony_ds4_output_report_t output_report = {0};
175+
output_report.set_rumble = 1;
176+
output_report.motor_left = motor_left;
177+
output_report.motor_right = motor_right;
178+
tuh_hid_send_report(ds4_dev_addr, ds4_instance, 5, &output_report, sizeof(output_report));
179+
}
180+
}
128181
}
129182

130183
//--------------------------------------------------------------------+
@@ -149,6 +202,14 @@ void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_re
149202
// Sony DualShock 4 [CUH-ZCT2x]
150203
if ( is_sony_ds4(dev_addr) )
151204
{
205+
if (!ds4_mounted)
206+
{
207+
ds4_dev_addr = dev_addr;
208+
ds4_instance = instance;
209+
motor_left = 0;
210+
motor_right = 0;
211+
ds4_mounted = true;
212+
}
152213
// request to receive report
153214
// tuh_hid_report_received_cb() will be invoked when report is available
154215
if ( !tuh_hid_receive_report(dev_addr, instance) )
@@ -162,6 +223,10 @@ void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_re
162223
void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance)
163224
{
164225
printf("HID device address = %d, instance = %d is unmounted\r\n", dev_addr, instance);
226+
if (ds4_mounted && ds4_dev_addr == dev_addr && ds4_instance == instance)
227+
{
228+
ds4_mounted = false;
229+
}
165230
}
166231

167232
// check if different than 2
@@ -179,8 +244,8 @@ bool diff_report(sony_ds4_report_t const* rpt1, sony_ds4_report_t const* rpt2)
179244
result = diff_than_2(rpt1->x, rpt2->x) || diff_than_2(rpt1->y , rpt2->y ) ||
180245
diff_than_2(rpt1->z, rpt2->z) || diff_than_2(rpt1->rz, rpt2->rz);
181246

182-
// check the reset with mem compare
183-
result |= memcmp(&rpt1->rz + 1, &rpt2->rz + 1, sizeof(sony_ds4_report_t)-4);
247+
// check the rest with mem compare
248+
result |= memcmp(&rpt1->rz + 1, &rpt2->rz + 1, sizeof(sony_ds4_report_t)-6);
184249

185250
return result;
186251
}
@@ -234,6 +299,10 @@ void process_sony_ds4(uint8_t const* report, uint16_t len)
234299
printf("\r\n");
235300
}
236301

302+
// The left and right triggers control the intensity of the left and right rumble motors
303+
motor_left = ds4_report.l2_trigger;
304+
motor_right = ds4_report.r2_trigger;
305+
237306
prev_report = ds4_report;
238307
}
239308
}

src/class/hid/hid_host.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ 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-
bool 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)
278278
{
279279
TU_LOG2("HID Send Report %d\r\n", report_id);
280280

src/class/hid/hid_host.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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-
bool 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)