hidbus_base.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #pragma once
  4. #include <array>
  5. #include <span>
  6. #include "common/typed_address.h"
  7. #include "core/hle/result.h"
  8. namespace Core {
  9. class System;
  10. }
  11. namespace Kernel {
  12. class KEvent;
  13. class KReadableEvent;
  14. } // namespace Kernel
  15. namespace Service::KernelHelpers {
  16. class ServiceContext;
  17. }
  18. namespace Service::HID {
  19. // This is nn::hidbus::JoyPollingMode
  20. enum class JoyPollingMode : u32 {
  21. SixAxisSensorDisable,
  22. SixAxisSensorEnable,
  23. ButtonOnly,
  24. };
  25. struct DataAccessorHeader {
  26. Result result{ResultUnknown};
  27. INSERT_PADDING_WORDS(0x1);
  28. std::array<u8, 0x18> unused{};
  29. u64 latest_entry{};
  30. u64 total_entries{};
  31. };
  32. static_assert(sizeof(DataAccessorHeader) == 0x30, "DataAccessorHeader is an invalid size");
  33. struct JoyDisableSixAxisPollingData {
  34. std::array<u8, 0x26> data;
  35. u8 out_size;
  36. INSERT_PADDING_BYTES(0x1);
  37. u64 sampling_number;
  38. };
  39. static_assert(sizeof(JoyDisableSixAxisPollingData) == 0x30,
  40. "JoyDisableSixAxisPollingData is an invalid size");
  41. struct JoyEnableSixAxisPollingData {
  42. std::array<u8, 0x8> data;
  43. u8 out_size;
  44. INSERT_PADDING_BYTES(0x7);
  45. u64 sampling_number;
  46. };
  47. static_assert(sizeof(JoyEnableSixAxisPollingData) == 0x18,
  48. "JoyEnableSixAxisPollingData is an invalid size");
  49. struct JoyButtonOnlyPollingData {
  50. std::array<u8, 0x2c> data;
  51. u8 out_size;
  52. INSERT_PADDING_BYTES(0x3);
  53. u64 sampling_number;
  54. };
  55. static_assert(sizeof(JoyButtonOnlyPollingData) == 0x38,
  56. "JoyButtonOnlyPollingData is an invalid size");
  57. struct JoyDisableSixAxisPollingEntry {
  58. u64 sampling_number;
  59. JoyDisableSixAxisPollingData polling_data;
  60. };
  61. static_assert(sizeof(JoyDisableSixAxisPollingEntry) == 0x38,
  62. "JoyDisableSixAxisPollingEntry is an invalid size");
  63. struct JoyEnableSixAxisPollingEntry {
  64. u64 sampling_number;
  65. JoyEnableSixAxisPollingData polling_data;
  66. };
  67. static_assert(sizeof(JoyEnableSixAxisPollingEntry) == 0x20,
  68. "JoyEnableSixAxisPollingEntry is an invalid size");
  69. struct JoyButtonOnlyPollingEntry {
  70. u64 sampling_number;
  71. JoyButtonOnlyPollingData polling_data;
  72. };
  73. static_assert(sizeof(JoyButtonOnlyPollingEntry) == 0x40,
  74. "JoyButtonOnlyPollingEntry is an invalid size");
  75. struct JoyDisableSixAxisDataAccessor {
  76. DataAccessorHeader header{};
  77. std::array<JoyDisableSixAxisPollingEntry, 0xb> entries{};
  78. };
  79. static_assert(sizeof(JoyDisableSixAxisDataAccessor) == 0x298,
  80. "JoyDisableSixAxisDataAccessor is an invalid size");
  81. struct JoyEnableSixAxisDataAccessor {
  82. DataAccessorHeader header{};
  83. std::array<JoyEnableSixAxisPollingEntry, 0xb> entries{};
  84. };
  85. static_assert(sizeof(JoyEnableSixAxisDataAccessor) == 0x190,
  86. "JoyEnableSixAxisDataAccessor is an invalid size");
  87. struct ButtonOnlyPollingDataAccessor {
  88. DataAccessorHeader header;
  89. std::array<JoyButtonOnlyPollingEntry, 0xb> entries;
  90. };
  91. static_assert(sizeof(ButtonOnlyPollingDataAccessor) == 0x2F0,
  92. "ButtonOnlyPollingDataAccessor is an invalid size");
  93. class HidbusBase {
  94. public:
  95. explicit HidbusBase(Core::System& system_, KernelHelpers::ServiceContext& service_context_);
  96. virtual ~HidbusBase();
  97. void ActivateDevice();
  98. void DeactivateDevice();
  99. bool IsDeviceActivated() const;
  100. // Enables/disables the device
  101. void Enable(bool enable);
  102. // returns true if device is enabled
  103. bool IsEnabled() const;
  104. // returns true if polling mode is enabled
  105. bool IsPollingMode() const;
  106. // returns polling mode
  107. JoyPollingMode GetPollingMode() const;
  108. // Sets and enables JoyPollingMode
  109. void SetPollingMode(JoyPollingMode mode);
  110. // Disables JoyPollingMode
  111. void DisablePollingMode();
  112. // Called on EnableJoyPollingReceiveMode
  113. void SetTransferMemoryAddress(Common::ProcessAddress t_mem);
  114. Kernel::KReadableEvent& GetSendCommandAsycEvent() const;
  115. virtual void OnInit() {}
  116. virtual void OnRelease() {}
  117. // Updates device transfer memory
  118. virtual void OnUpdate() {}
  119. // Returns the device ID of the joycon
  120. virtual u8 GetDeviceId() const {
  121. return {};
  122. }
  123. // Assigns a command from data
  124. virtual bool SetCommand(std::span<const u8> data) {
  125. return {};
  126. }
  127. // Returns a reply from a command
  128. virtual std::vector<u8> GetReply() const {
  129. return {};
  130. }
  131. protected:
  132. bool is_activated{};
  133. bool device_enabled{};
  134. bool polling_mode_enabled{};
  135. JoyPollingMode polling_mode = {};
  136. // TODO(German77): All data accessors need to be replaced with a ring lifo object
  137. JoyDisableSixAxisDataAccessor disable_sixaxis_data{};
  138. JoyEnableSixAxisDataAccessor enable_sixaxis_data{};
  139. ButtonOnlyPollingDataAccessor button_only_data{};
  140. Common::ProcessAddress transfer_memory{};
  141. Core::System& system;
  142. Kernel::KEvent* send_command_async_event;
  143. KernelHelpers::ServiceContext& service_context;
  144. };
  145. } // namespace Service::HID