libnx  v4.2.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  */
85 void ringconClose(RingCon *c);
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  */
193 Result ringconGetPollingData(RingCon *c, RingConPollingData *out, s32 count, s32 *total_out);
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  */
233 Result ringconReadRepCount(RingCon *c, s32 *out, RingConDataValid *data_valid);
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 
RingConErrorFlag_BadUserCalUpdate
@ RingConErrorFlag_BadUserCalUpdate
The output from ringconReadUserCal doesn't match the input used with ringconWriteUserCal,...
Definition: ringcon.h:21
ringconGetId
static void ringconGetId(RingCon *c, u64 *id_l, u64 *id_h)
Gets the Id previously loaded by ringconCreate.
Definition: ringcon.h:119
RingConErrorFlag
RingConErrorFlag
Definition: ringcon.h:20
RingConDataValid
RingConDataValid
Whether the output data is valid.
Definition: ringcon.h:14
ringconReadFwVersion
Result ringconReadFwVersion(RingCon *c, RingConFwVersion *out)
Reads the RingConFwVersion.
ringconGetErrorFlag
static bool ringconGetErrorFlag(RingCon *c, RingConErrorFlag flag)
Gets the value of an error flag, set by ringconSetErrorFlag.
Definition: ringcon.h:100
ringconReadRepCount
Result ringconReadRepCount(RingCon *c, s32 *out, RingConDataValid *data_valid)
Reads the rep-count for Multitask Mode.
RingConManuCal
Ring-Con manufacturer calibration.
Definition: ringcon.h:34
ringconGetManuCal
static void ringconGetManuCal(RingCon *c, RingConManuCal *out)
Gets the RingConManuCal previously loaded by ringconCreate.
Definition: ringcon.h:146
ringconGetUserCal
static void ringconGetUserCal(RingCon *c, RingConUserCal *out)
Gets the RingConUserCal previously loaded by ringconCreate.
Definition: ringcon.h:156
u8
uint8_t u8
8-bit unsigned integer.
Definition: types.h:19
ringconGetUnkCal
static s16 ringconGetUnkCal(RingCon *c)
Gets the unk_cal previously loaded by ringconCreate with ringconReadUnkCal.
Definition: ringcon.h:128
NX_CONSTEXPR
#define NX_CONSTEXPR
Flags a function as constexpr in C++14 and above; or as (always) inline otherwise.
Definition: types.h:88
s16
int16_t s16
16-bit signed integer.
Definition: types.h:26
RingConErrorFlag_BadFlag
@ RingConErrorFlag_BadFlag
The output flag from ringconCmdx00020105 when successful is invalid.
Definition: ringcon.h:22
ringconUpdateUserCal
Result ringconUpdateUserCal(RingCon *c, RingConUserCal cal)
Updates the RingConUserCal.
s32
int32_t s32
32-bit signed integer.
Definition: types.h:27
ringconResetRepCount
Result ringconResetRepCount(RingCon *c)
This resets the value returned by ringconReadRepCount to 0.
ringconReadUserCal
Result ringconReadUserCal(RingCon *c, RingConUserCal *out)
Reads the RingConUserCal.
HidbusBusHandle
BusHandle.
Definition: hidbus.h:28
RingConFwVersion::fw_main_ver
u8 fw_main_ver
Main firmware version.
Definition: ringcon.h:29
HidNpadIdType
HidNpadIdType
HID controller IDs.
Definition: hid.h:214
ringconGetPollingData
Result ringconGetPollingData(RingCon *c, RingConPollingData *out, s32 count, s32 *total_out)
Gets the RingConPollingData.
ringconGetFwVersion
static RingConFwVersion ringconGetFwVersion(RingCon *c)
Gets the RingConFwVersion previously loaded by ringconCreate.
Definition: ringcon.h:109
RingConDataValid_CRC
@ RingConDataValid_CRC
Bad CRC.
Definition: ringcon.h:16
ringconReadTotalPushCount
Result ringconReadTotalPushCount(RingCon *c, s32 *out, RingConDataValid *data_valid)
Reads the total-push-count, for Multitask Mode.
RingCon
Ring-Con state object.
Definition: ringcon.h:56
RingConUserCal::zero
s16 zero
(user_)zero
Definition: ringcon.h:45
ringconReadUnkCal
Result ringconReadUnkCal(RingCon *c, s16 *out)
Gets the unknown value derived from the output of cmd 0x00020504 and ringconReadManuCal.
u32
uint32_t u32
32-bit unsigned integer.
Definition: types.h:21
RingConUserCal::hk_max
s16 hk_max
(user_)hk_max
Definition: ringcon.h:44
ringconReadManuCal
Result ringconReadManuCal(RingCon *c, RingConManuCal *out)
Reads the RingConManuCal.
RingConManuCal::zero_min
s16 zero_min
(manu_)zero_min
Definition: ringcon.h:37
u64
uint64_t u64
64-bit unsigned integer.
Definition: types.h:22
Result
u32 Result
Function error code result type.
Definition: types.h:44
ringconGetErrorFlags
static u32 ringconGetErrorFlags(RingCon *c)
Gets the error flags field.
Definition: ringcon.h:91
RingConPollingData::data
s16 data
Sensor state data.
Definition: ringcon.h:51
RingConManuCal::os_max
s16 os_max
(manu_)os_max
Definition: ringcon.h:35
RingConErrorFlag_BadUserCal
@ RingConErrorFlag_BadUserCal
BadUserCal.
Definition: ringcon.h:23
ringconCreate
Result ringconCreate(RingCon *c, HidNpadIdType id)
Creates a RingCon object, and handles the various initialization for it.
RingConPollingData::sampling_number
u64 sampling_number
SamplingNumber.
Definition: ringcon.h:52
RingConManuCal::zero_max
s16 zero_max
(manu_)zero_max
Definition: ringcon.h:38
RingConUserCal::data_valid
RingConDataValid data_valid
RingConDataValid
Definition: ringcon.h:46
ringconReadId
Result ringconReadId(RingCon *c, u64 *id_l, u64 *id_h)
Reads the Id.
ringconCmdx00020105
Result ringconCmdx00020105(RingCon *c, u32 *out)
Uses cmd 0x00020105.
ringconWriteUserCal
Result ringconWriteUserCal(RingCon *c, RingConUserCal cal)
Writes the RingConUserCal.
RingConErrorFlag_BadManuCal
@ RingConErrorFlag_BadManuCal
BadManuCal.
Definition: ringcon.h:24
BIT
#define BIT(n)
Creates a bitmask from a bit number.
Definition: types.h:54
RingConDataValid_Cal
@ RingConDataValid_Cal
Only used with ringconReadUserCal. Calibration is needed via ringconUpdateUserCal.
Definition: ringcon.h:17
RingConFwVersion
Ring-Con firmware version.
Definition: ringcon.h:28
RingConFwVersion::fw_sub_ver
u8 fw_sub_ver
Sub firmware version.
Definition: ringcon.h:30
ringconClose
void ringconClose(RingCon *c)
Close a RingCon.
RingConManuCal::hk_max
s16 hk_max
(manu_)hk_max
Definition: ringcon.h:36
RingConPollingData
Polling data extracted from HidbusJoyPollingReceivedData.
Definition: ringcon.h:50
ringconGetTotalPushCount
static s32 ringconGetTotalPushCount(RingCon *c)
Gets the total-push-count previously loaded by ringconCreate.
Definition: ringcon.h:137
RingConUserCal
Ring-Con user calibration.
Definition: ringcon.h:42
RingConUserCal::os_max
s16 os_max
(user_)os_max
Definition: ringcon.h:43
RingConDataValid_Ok
@ RingConDataValid_Ok
Valid.
Definition: ringcon.h:15