libnx  v4.6.0
ringcon.h
Go to the documentation of this file.
1 /**
2  * @file ringcon.h
3  * @brief Wrapper for using the Ring-Con attached to a Joy-Con, with hidbus. See also: https://switchbrew.org/wiki/Ring-Con
4  * @author yellows8
5  * @copyright libnx Authors
6  */
7 #pragma once
8 #include "../types.h"
9 #include "../services/hidbus.h"
10 
11 #define RINGCON_CAL_MAGIC -0x3502 // 0xCAFE
12 
13 /// Whether the output data is valid.
14 typedef enum {
15  RingConDataValid_Ok = 0, ///< Valid.
16  RingConDataValid_CRC = 1, ///< Bad CRC.
17  RingConDataValid_Cal = 2, ///< Only used with \ref ringconReadUserCal. Calibration is needed via \ref ringconUpdateUserCal.
19 
20 typedef enum {
21  RingConErrorFlag_BadUserCalUpdate = 0, ///< The output from \ref ringconReadUserCal doesn't match the input used with \ref ringconWriteUserCal, or the \ref RingConDataValid is not ::RingConDataValid_Ok.
22  RingConErrorFlag_BadFlag = 4, ///< The output flag from \ref ringconCmdx00020105 when successful is invalid.
23  RingConErrorFlag_BadUserCal = 5, ///< BadUserCal
24  RingConErrorFlag_BadManuCal = 6, ///< BadManuCal
26 
27 /// Ring-Con firmware version.
28 typedef struct {
29  u8 fw_main_ver; ///< Main firmware version.
30  u8 fw_sub_ver; ///< Sub firmware version.
32 
33 /// Ring-Con manufacturer calibration.
34 typedef struct {
35  s16 os_max; ///< (manu_)os_max
36  s16 hk_max; ///< (manu_)hk_max
37  s16 zero_min; ///< (manu_)zero_min
38  s16 zero_max; ///< (manu_)zero_max
40 
41 /// Ring-Con user calibration.
42 typedef struct {
43  s16 os_max; ///< (user_)os_max
44  s16 hk_max; ///< (user_)hk_max
45  s16 zero; ///< (user_)zero
46  RingConDataValid data_valid; ///< \ref RingConDataValid
48 
49 /// Polling data extracted from \ref HidbusJoyPollingReceivedData.
50 typedef struct {
51  s16 data; ///< Sensor state data.
52  u64 sampling_number; ///< SamplingNumber
54 
55 /// Ring-Con state object.
56 typedef struct {
57  bool bus_initialized;
58  HidbusBusHandle handle;
59  void* workbuf;
60  size_t workbuf_size;
61  u64 polling_last_sampling_number;
62  u32 error_flags;
63 
64  u64 id_l, id_h;
65  RingConFwVersion fw_ver;
66  u32 flag;
67  s16 unk_cal;
68  s32 total_push_count;
69 
70  RingConManuCal manu_cal;
71  RingConUserCal user_cal;
72 } RingCon;
73 
74 /**
75  * @brief Creates a \ref RingCon object, and handles the various initialization for it.
76  * @param c \ref RingCon
77  * @param[in] id \ref HidNpadIdType. A Ring-Con must be attached to this controller.
78  */
80 
81 /**
82  * @brief Close a \ref RingCon.
83  * @param c \ref RingCon
84  */
86 
87 /**
88  * @brief Gets the error flags field.
89  * @param c \ref RingCon
90  */
92  return c->error_flags;
93 }
94 
95 /**
96  * @brief Gets the value of an error flag, set by \ref ringconSetErrorFlag.
97  * @param c \ref RingCon
98  * @param[in] flag \ref RingConErrorFlag
99  */
101  return (c->error_flags & BIT(flag)) != 0;
102 }
103 
104 /**
105  * @brief Gets the \ref RingConFwVersion previously loaded by \ref ringconCreate.
106  * @param c \ref RingCon
107  * @param[out] out \ref RingConFwVersion
108  */
110  return c->fw_ver;
111 }
112 
113 /**
114  * @brief Gets the Id previously loaded by \ref ringconCreate.
115  * @param c \ref RingCon
116  * @param[out] id_l Id low.
117  * @param[out] id_h Id high.
118  */
119 NX_CONSTEXPR void ringconGetId(RingCon *c, u64 *id_l, u64 *id_h) {
120  *id_l = c->id_l;
121  *id_h = c->id_h;
122 }
123 
124 /**
125  * @brief Gets the unk_cal previously loaded by \ref ringconCreate with \ref ringconReadUnkCal. Only valid when the output flag from \ref ringconCmdx00020105 is valid.
126  * @param c \ref RingCon
127  */
129  return c->unk_cal;
130 }
131 
132 /**
133  * @brief Gets the total-push-count previously loaded by \ref ringconCreate.
134  * @param c \ref RingCon
135  * @param[out] out total_push_count
136  */
138  return c->total_push_count;
139 }
140 
141 /**
142  * @brief Gets the \ref RingConManuCal previously loaded by \ref ringconCreate.
143  * @param c \ref RingCon
144  * @param[out] out \ref RingConManuCal
145  */
147  *out = c->manu_cal;
148 }
149 
150 /**
151  * @brief Gets the \ref RingConUserCal previously loaded by \ref ringconCreate.
152  * @note The Ring-Con UserCal doesn't seem to be calibrated normally?
153  * @param c \ref RingCon
154  * @param[out] out \ref RingConUserCal
155  */
157  *out = c->user_cal;
158 }
159 
160 /**
161  * @brief Updates the \ref RingConUserCal.
162  * @note The input \ref RingConUserCal is used with \ref ringconWriteUserCal, and the output from \ref ringconReadUserCal is verified with the input \ref RingConUserCal. This does not update the \ref RingConUserCal returned by \ref ringconGetUserCal.
163  * @note The Ring-Con UserCal doesn't seem to be calibrated normally?
164  * @param c \ref RingCon
165  * @param[in] cal \ref RingConUserCal
166  */
168 
169 /**
170  * @brief Reads the \ref RingConFwVersion.
171  * @note This is used internally by \ref ringconCreate. Normally you should use \ref ringconGetFwVersion instead.
172  * @param c \ref RingCon
173  * @param[out] out \ref RingConFwVersion
174  */
176 
177 /**
178  * @brief Reads the Id.
179  * @note This is used internally by \ref ringconCreate. Normally you should use \ref ringconGetId instead.
180  * @param c \ref RingCon
181  * @param[out] id_l Id low.
182  * @param[out] id_h Id high.
183  */
184 Result ringconReadId(RingCon *c, u64 *id_l, u64 *id_h);
185 
186 /**
187  * @brief Gets the \ref RingConPollingData. Only returns entries which are new since the last time this was called (or if not previously called, all available entries up to count).
188  * @param c \ref RingCon
189  * @param[out] out Output array of \ref RingConPollingData. Entry order is newest -> oldest.
190  * @param[in] count Total size of the out array in entries, max value is 0x9.
191  * @param[out] total_out Total output entries.
192  */
194 
195 /**
196  * @brief Uses cmd 0x00020105.
197  * @note Used internally by \ref ringconCreate.
198  * @param c \ref RingCon
199  * @param[out] out Output value.
200  */
202 
203 /**
204  * @brief Reads the \ref RingConManuCal.
205  * @note Used internally by \ref ringconCreate and \ref ringconReadUnkCal.
206  * @param c \ref RingCon
207  * @param[out] out \ref RingConManuCal
208  */
210 
211 /**
212  * @brief Gets the unknown value derived from the output of cmd 0x00020504 and \ref ringconReadManuCal.
213  * @note Used internally by \ref ringconCreate.
214  * @param c \ref RingCon
215  * @param[out] out Output value.
216  */
218 
219 /**
220  * @brief Reads the \ref RingConUserCal.
221  * @note Used internally by \ref ringconCreate and \ref ringconUpdateUserCal.
222  * @param c \ref RingCon
223  * @param[out] out \ref RingConUserCal
224  */
226 
227 /**
228  * @brief Reads the rep-count for Multitask Mode.
229  * @param c \ref RingCon
230  * @param[out] out Output value. Official sw using this clamps the output to range 0-500.
231  * @param[out] data_valid \ref RingConDataValid
232  */
234 
235 /**
236  * @brief Reads the total-push-count, for Multitask Mode.
237  * @note Used internally by \ref ringconCreate. Normally \ref ringconGetTotalPushCount should be used instead.
238  * @param c \ref RingCon
239  * @param[out] out Output value.
240  * @param[out] data_valid \ref RingConDataValid
241  */
243 
244 /**
245  * @brief This resets the value returned by \ref ringconReadRepCount to 0.
246  * @param c \ref RingCon
247  */
249 
250 /**
251  * @brief Writes the \ref RingConUserCal.
252  * @note Used internally by \ref ringconUpdateUserCal.
253  * @param c \ref RingCon
254  * @param[in] cal \ref RingConUserCal
255  */
257 
HidNpadIdType
HID controller IDs.
Definition: hid.h:214
Result ringconCreate(RingCon *c, HidNpadIdType id)
Creates a RingCon object, and handles the various initialization for it.
static RingConFwVersion ringconGetFwVersion(RingCon *c)
Gets the RingConFwVersion previously loaded by ringconCreate.
Definition: ringcon.h:109
Result ringconReadUserCal(RingCon *c, RingConUserCal *out)
Reads the RingConUserCal.
static void ringconGetId(RingCon *c, u64 *id_l, u64 *id_h)
Gets the Id previously loaded by ringconCreate.
Definition: ringcon.h:119
Result ringconReadId(RingCon *c, u64 *id_l, u64 *id_h)
Reads the Id.
Result ringconWriteUserCal(RingCon *c, RingConUserCal cal)
Writes the RingConUserCal.
static s16 ringconGetUnkCal(RingCon *c)
Gets the unk_cal previously loaded by ringconCreate with ringconReadUnkCal.
Definition: ringcon.h:128
Result ringconUpdateUserCal(RingCon *c, RingConUserCal cal)
Updates the RingConUserCal.
RingConErrorFlag
Definition: ringcon.h:20
@ RingConErrorFlag_BadUserCal
BadUserCal.
Definition: ringcon.h:23
@ RingConErrorFlag_BadFlag
The output flag from ringconCmdx00020105 when successful is invalid.
Definition: ringcon.h:22
@ RingConErrorFlag_BadManuCal
BadManuCal.
Definition: ringcon.h:24
@ RingConErrorFlag_BadUserCalUpdate
The output from ringconReadUserCal doesn't match the input used with ringconWriteUserCal,...
Definition: ringcon.h:21
static bool ringconGetErrorFlag(RingCon *c, RingConErrorFlag flag)
Gets the value of an error flag, set by ringconSetErrorFlag.
Definition: ringcon.h:100
Result ringconResetRepCount(RingCon *c)
This resets the value returned by ringconReadRepCount to 0.
void ringconClose(RingCon *c)
Close a RingCon.
Result ringconCmdx00020105(RingCon *c, u32 *out)
Uses cmd 0x00020105.
static s32 ringconGetTotalPushCount(RingCon *c)
Gets the total-push-count previously loaded by ringconCreate.
Definition: ringcon.h:137
static u32 ringconGetErrorFlags(RingCon *c)
Gets the error flags field.
Definition: ringcon.h:91
Result ringconReadRepCount(RingCon *c, s32 *out, RingConDataValid *data_valid)
Reads the rep-count for Multitask Mode.
RingConDataValid
Whether the output data is valid.
Definition: ringcon.h:14
@ RingConDataValid_Ok
Valid.
Definition: ringcon.h:15
@ RingConDataValid_Cal
Only used with ringconReadUserCal. Calibration is needed via ringconUpdateUserCal.
Definition: ringcon.h:17
@ RingConDataValid_CRC
Bad CRC.
Definition: ringcon.h:16
static void ringconGetManuCal(RingCon *c, RingConManuCal *out)
Gets the RingConManuCal previously loaded by ringconCreate.
Definition: ringcon.h:146
Result ringconReadUnkCal(RingCon *c, s16 *out)
Gets the unknown value derived from the output of cmd 0x00020504 and ringconReadManuCal.
Result ringconGetPollingData(RingCon *c, RingConPollingData *out, s32 count, s32 *total_out)
Gets the RingConPollingData.
Result ringconReadFwVersion(RingCon *c, RingConFwVersion *out)
Reads the RingConFwVersion.
Result ringconReadManuCal(RingCon *c, RingConManuCal *out)
Reads the RingConManuCal.
static void ringconGetUserCal(RingCon *c, RingConUserCal *out)
Gets the RingConUserCal previously loaded by ringconCreate.
Definition: ringcon.h:156
Result ringconReadTotalPushCount(RingCon *c, s32 *out, RingConDataValid *data_valid)
Reads the total-push-count, for Multitask Mode.
BusHandle.
Definition: hidbus.h:28
Ring-Con firmware version.
Definition: ringcon.h:28
u8 fw_main_ver
Main firmware version.
Definition: ringcon.h:29
u8 fw_sub_ver
Sub firmware version.
Definition: ringcon.h:30
Ring-Con manufacturer calibration.
Definition: ringcon.h:34
s16 zero_min
(manu_)zero_min
Definition: ringcon.h:37
s16 zero_max
(manu_)zero_max
Definition: ringcon.h:38
s16 os_max
(manu_)os_max
Definition: ringcon.h:35
s16 hk_max
(manu_)hk_max
Definition: ringcon.h:36
Polling data extracted from HidbusJoyPollingReceivedData.
Definition: ringcon.h:50
s16 data
Sensor state data.
Definition: ringcon.h:51
u64 sampling_number
SamplingNumber.
Definition: ringcon.h:52
Ring-Con user calibration.
Definition: ringcon.h:42
s16 hk_max
(user_)hk_max
Definition: ringcon.h:44
s16 os_max
(user_)os_max
Definition: ringcon.h:43
s16 zero
(user_)zero
Definition: ringcon.h:45
RingConDataValid data_valid
RingConDataValid
Definition: ringcon.h:46
Ring-Con state object.
Definition: ringcon.h:56
#define BIT(n)
Creates a bitmask from a bit number.
Definition: types.h:54
uint64_t u64
64-bit unsigned integer.
Definition: types.h:22
uint8_t u8
8-bit unsigned integer.
Definition: types.h:19
int16_t s16
16-bit signed integer.
Definition: types.h:26
u32 Result
Function error code result type.
Definition: types.h:44
#define NX_CONSTEXPR
Flags a function as constexpr in C++14 and above; or as (always) inline otherwise.
Definition: types.h:92
int32_t s32
32-bit signed integer.
Definition: types.h:27
uint32_t u32
32-bit unsigned integer.
Definition: types.h:21