forked from mirror/joycontrol
implemented 0x30 input report
This commit is contained in:
+139
-32
@@ -4,6 +4,7 @@ from asyncio import BaseTransport, BaseProtocol
|
||||
from typing import Optional, Union, Tuple, Text
|
||||
|
||||
from joycontrol.controller import Controller
|
||||
from joycontrol.controller_state import ControllerState
|
||||
from joycontrol.report import OutputReport, SubCommand, InputReport, OutputReportID
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -21,15 +22,27 @@ class ControllerProtocol(BaseProtocol):
|
||||
|
||||
self.transport = None
|
||||
|
||||
# This must always be an 0x21 input report to be compatible with button events
|
||||
self._button_input_report = InputReport()
|
||||
self._button_input_report.set_input_report_id(0x21)
|
||||
self._button_input_report.set_misc()
|
||||
|
||||
self._data_received = asyncio.Event()
|
||||
|
||||
def get_button_input_report(self):
|
||||
return self._button_input_report
|
||||
self._controller_state = ControllerState(self)
|
||||
|
||||
self._pending_write = None
|
||||
self._pending_input_report = None
|
||||
|
||||
self._0x30_input_report_sender = None
|
||||
|
||||
self.sig_wait_player_lights = asyncio.Event()
|
||||
|
||||
async def write(self, input_report: InputReport):
|
||||
# set button and TODO: stick date
|
||||
if self._controller_state.button_state is not None:
|
||||
input_report.set_button_status(self._controller_state.button_state)
|
||||
self._controller_state.sig_is_send.set()
|
||||
|
||||
await self.transport.write(input_report)
|
||||
|
||||
def get_controller_state(self):
|
||||
return self._controller_state
|
||||
|
||||
async def wait_for_output_report(self):
|
||||
self._data_received.clear()
|
||||
@@ -45,6 +58,27 @@ class ControllerProtocol(BaseProtocol):
|
||||
def error_received(self, exc: Exception) -> None:
|
||||
raise NotImplementedError()
|
||||
|
||||
async def send_0x30_input_reports(self):
|
||||
input_report = InputReport()
|
||||
input_report.set_input_report_id(0x30)
|
||||
input_report.set_misc()
|
||||
|
||||
while True:
|
||||
# TODO: set sensor data
|
||||
input_report.set_6axis_data()
|
||||
|
||||
await self.write(input_report)
|
||||
|
||||
"""
|
||||
if self.controller == Controller.PRO_CONTROLLER:
|
||||
# send state at 120Hz if Pro Controller
|
||||
await asyncio.sleep(1 / 120)
|
||||
else:
|
||||
# send state at 60Hz
|
||||
await asyncio.sleep(1 / 60)
|
||||
"""
|
||||
await asyncio.sleep(1 / 30)
|
||||
|
||||
async def report_received(self, data: Union[bytes, Text], addr: Tuple[str, int]) -> None:
|
||||
self._data_received.set()
|
||||
|
||||
@@ -87,6 +121,19 @@ class ControllerProtocol(BaseProtocol):
|
||||
|
||||
elif sub_command == SubCommand.TRIGGER_BUTTONS_ELAPSED_TIME:
|
||||
await self._command_trigger_buttons_elapsed_time(report)
|
||||
|
||||
elif sub_command == SubCommand.ENABLE_6AXIS_SENSOR:
|
||||
await self._command_enable_6axis_sensor(report)
|
||||
|
||||
elif sub_command == SubCommand.ENABLE_VIBRATION:
|
||||
await self._command_enable_vibration(report)
|
||||
|
||||
elif sub_command == SubCommand.SET_NFC_IR_MCU_CONFIG:
|
||||
await self._command_set_nfc_ir_mcu_config(report)
|
||||
|
||||
elif sub_command == SubCommand.SET_PLAYER_LIGHTS:
|
||||
await self._command_set_player_lights(report)
|
||||
|
||||
else:
|
||||
logger.warning(f'Sub command 0x{sub_command.value:02x} not implemented - ignoring')
|
||||
#elif output_report_id == OutputReportID.RUMBLE_ONLY:
|
||||
@@ -95,48 +142,108 @@ class ControllerProtocol(BaseProtocol):
|
||||
logger.warning(f'Output report {output_report_id} not implemented - ignoring')
|
||||
|
||||
async def _command_request_device_info(self, output_report):
|
||||
input_report = InputReport()
|
||||
input_report.set_input_report_id(0x21)
|
||||
input_report.set_misc()
|
||||
|
||||
address = self.transport.get_extra_info('sockname')
|
||||
assert address is not None
|
||||
bd_address = list(map(lambda x: int(x, 16), address[0].split(':')))
|
||||
|
||||
self._button_input_report.set_misc()
|
||||
self._button_input_report.set_ack(0x82)
|
||||
self._button_input_report.sub_0x02_device_info(bd_address, controller=self.controller)
|
||||
input_report.set_ack(0x82)
|
||||
input_report.sub_0x02_device_info(bd_address, controller=self.controller)
|
||||
|
||||
await self._button_input_report.write(self.transport)
|
||||
await self.write(input_report)
|
||||
|
||||
async def _command_set_shipment_state(self, output_report):
|
||||
self._button_input_report.set_misc()
|
||||
self._button_input_report.set_ack(0x80)
|
||||
self._button_input_report.sub_0x08_shipment()
|
||||
input_report = InputReport()
|
||||
input_report.set_input_report_id(0x21)
|
||||
input_report.set_misc()
|
||||
|
||||
await self._button_input_report.write(self.transport)
|
||||
input_report.set_ack(0x80)
|
||||
input_report.reply_to_subcommand_id(0x08)
|
||||
|
||||
await self.write(input_report)
|
||||
|
||||
async def _command_spi_flash_read(self, output_report):
|
||||
self._button_input_report.set_misc()
|
||||
self._button_input_report.set_ack(0x90)
|
||||
self._button_input_report.sub_0x10_spi_flash_read(output_report)
|
||||
input_report = InputReport()
|
||||
input_report.set_input_report_id(0x21)
|
||||
input_report.set_misc()
|
||||
|
||||
await self._button_input_report.write(self.transport)
|
||||
input_report.set_ack(0x90)
|
||||
input_report.sub_0x10_spi_flash_read(output_report)
|
||||
|
||||
await self.write(input_report)
|
||||
|
||||
async def _command_set_input_report_mode(self, output_report):
|
||||
self._button_input_report.set_misc()
|
||||
self._button_input_report.set_ack(0x80)
|
||||
self._button_input_report.sub_0x03_set_input_report_mode()
|
||||
if output_report.data[12] == 0x30:
|
||||
logger.info('Setting input report mode to 0x30...')
|
||||
# start sending 0x30 input reports
|
||||
assert self._0x30_input_report_sender is None
|
||||
self._0x30_input_report_sender = asyncio.ensure_future(self.send_0x30_input_reports())
|
||||
|
||||
await self._button_input_report.write(self.transport)
|
||||
input_report = InputReport()
|
||||
input_report.set_input_report_id(0x21)
|
||||
input_report.set_misc()
|
||||
|
||||
input_report.set_ack(0x80)
|
||||
input_report.reply_to_subcommand_id(0x03)
|
||||
|
||||
await self.write(input_report)
|
||||
else:
|
||||
logger.error(f'input report mode {output_report.data[12]} not implemented - ignoring request')
|
||||
|
||||
async def _command_trigger_buttons_elapsed_time(self, output_report):
|
||||
self._button_input_report.set_misc()
|
||||
self._button_input_report.set_ack(0x83)
|
||||
self._button_input_report.sub_0x04_trigger_buttons_elapsed_time()
|
||||
input_report = InputReport()
|
||||
input_report.set_input_report_id(0x21)
|
||||
input_report.set_misc()
|
||||
|
||||
await self._button_input_report.write(self.transport)
|
||||
input_report.set_ack(0x83)
|
||||
input_report.sub_0x04_trigger_buttons_elapsed_time()
|
||||
|
||||
async def _enable_6axis_sensor(self, output_report):
|
||||
self._button_input_report.set_misc()
|
||||
self._button_input_report.set_ack(0x80)
|
||||
await self.write(input_report)
|
||||
|
||||
self._button_input_report.reply_to_subcommand_id(0x40)
|
||||
async def _command_enable_6axis_sensor(self, output_report):
|
||||
input_report = InputReport()
|
||||
input_report.set_input_report_id(0x21)
|
||||
input_report.set_misc()
|
||||
|
||||
await self._button_input_report.write(self.transport)
|
||||
input_report.set_ack(0x80)
|
||||
input_report.reply_to_subcommand_id(0x40)
|
||||
|
||||
await self.write(input_report)
|
||||
|
||||
async def _command_enable_vibration(self, output_report):
|
||||
input_report = InputReport()
|
||||
input_report.set_input_report_id(0x21)
|
||||
input_report.set_misc()
|
||||
|
||||
input_report.set_ack(0x80)
|
||||
input_report.reply_to_subcommand_id(SubCommand.ENABLE_VIBRATION.value)
|
||||
|
||||
await self.write(input_report)
|
||||
|
||||
async def _command_set_nfc_ir_mcu_config(self, output_report):
|
||||
input_report = InputReport()
|
||||
input_report.set_input_report_id(0x21)
|
||||
input_report.set_misc()
|
||||
|
||||
input_report.set_ack(0xA0)
|
||||
input_report.reply_to_subcommand_id(SubCommand.SET_NFC_IR_MCU_CONFIG.value)
|
||||
|
||||
for i in range(16, 51):
|
||||
input_report.data[i] = 0xFF
|
||||
|
||||
await self.write(input_report)
|
||||
|
||||
async def _command_set_player_lights(self, output_report):
|
||||
input_report = InputReport()
|
||||
input_report.set_input_report_id(0x21)
|
||||
input_report.set_misc()
|
||||
|
||||
input_report.set_ack(0x80)
|
||||
input_report.reply_to_subcommand_id(SubCommand.SET_PLAYER_LIGHTS.value)
|
||||
|
||||
await self.write(input_report)
|
||||
|
||||
self.sig_wait_player_lights.set()
|
||||
|
||||
Reference in New Issue
Block a user