Skip to content

Commit 6c68c26

Browse files
committed
Feat: Add battery status support for SteelSeries Arctis Nova 3P Wireless
1 parent b7077b1 commit 6c68c26

File tree

1 file changed

+55
-1
lines changed

1 file changed

+55
-1
lines changed

src/devices/steelseries_arctis_nova_3p_wireless.c

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,16 @@ enum { MSG_SIZE = 64 };
99

1010
enum { ID_ARCTIS_NOVA_3P_WIRELESS = 0x2269 };
1111

12+
enum {
13+
HEADSET_ONLINE = 0x03,
14+
HEADSET_OFFLINE = 0x02
15+
};
16+
17+
enum {
18+
BATTERY_MAX = 0x64,
19+
BATTERY_MIN = 0x00
20+
};
21+
1222
static struct device device_arctis;
1323

1424
static const uint16_t PRODUCT_IDS[] = { ID_ARCTIS_NOVA_3P_WIRELESS };
@@ -17,6 +27,7 @@ static const uint8_t SAVE_DATA[MSG_SIZE] = { 0x09 }; // Command to save settings
1727
static int arctis_nova_3p_wireless_send_sidetone(hid_device* device_handle, uint8_t num);
1828
static int arctis_nova_3p_wireless_send_microphone_volume(hid_device* device_handle, uint8_t num);
1929
static int arctis_nova_3p_wireless_send_inactive_time(hid_device* device_handle, uint8_t num);
30+
static BatteryInfo arctis_nova_3p_wireless_request_battery(hid_device* device_handle);
2031

2132
void arctis_nova_3p_wireless_init(struct device** device)
2233
{
@@ -26,10 +37,11 @@ void arctis_nova_3p_wireless_init(struct device** device)
2637

2738
strncpy(device_arctis.device_name, "SteelSeries Arctis Nova 3P Wireless", sizeof(device_arctis.device_name));
2839

29-
device_arctis.capabilities = B(CAP_SIDETONE) | B(CAP_INACTIVE_TIME) | B(CAP_MICROPHONE_VOLUME);
40+
device_arctis.capabilities = B(CAP_SIDETONE) | B(CAP_INACTIVE_TIME) | B(CAP_MICROPHONE_VOLUME) | B(CAP_BATTERY_STATUS);
3041
device_arctis.send_sidetone = &arctis_nova_3p_wireless_send_sidetone;
3142
device_arctis.send_inactive_time = &arctis_nova_3p_wireless_send_inactive_time;
3243
device_arctis.send_microphone_volume = &arctis_nova_3p_wireless_send_microphone_volume;
44+
device_arctis.request_battery = &arctis_nova_3p_wireless_request_battery;
3345

3446
*device = &device_arctis;
3547
}
@@ -85,3 +97,45 @@ static int arctis_nova_3p_wireless_send_inactive_time(hid_device* device_handle,
8597

8698
return hid_send_feature_report(device_handle, SAVE_DATA, MSG_SIZE);
8799
}
100+
101+
static BatteryInfo arctis_nova_3p_wireless_request_battery(hid_device* device_handle)
102+
{
103+
int r = 0;
104+
105+
BatteryInfo info = { .status = BATTERY_UNAVAILABLE, .level = -1 };
106+
107+
uint8_t data[MSG_SIZE] = { 0xb0 };
108+
r = hid_send_feature_report(device_handle, data, MSG_SIZE);
109+
110+
if (r < 0) {
111+
info.status = BATTERY_HIDERROR;
112+
return info;
113+
}
114+
115+
if (r == 0) {
116+
info.status = BATTERY_TIMEOUT;
117+
return info;
118+
}
119+
120+
r = hid_read_timeout(device_handle, data, 4, hsc_device_timeout);
121+
122+
if (r < 0) {
123+
info.status = BATTERY_HIDERROR;
124+
return info;
125+
}
126+
127+
if (r == 0) {
128+
info.status = BATTERY_TIMEOUT;
129+
return info;
130+
}
131+
132+
if (data[1] == HEADSET_OFFLINE) {
133+
info.status = BATTERY_UNAVAILABLE;
134+
return info;
135+
}
136+
137+
info.status = BATTERY_AVAILABLE;
138+
int bat = data[3];
139+
info.level = map(bat, BATTERY_MIN, BATTERY_MAX, 0, 100);
140+
return info;
141+
}

0 commit comments

Comments
 (0)