يتيح بروتوكول جهاز الواجهة البشرية (HID) لتتبُّع حركة الرأس، والمتوفر للأجهزة التي تعمل بالإصدار 13 من نظام التشغيل Android والإصدارات الأحدث، توصيل جهاز تتبُّع حركة الرأس بجهاز Android عبر USB أو بلوتوث وعرضه على إطار عمل Android والتطبيقات من خلال إطار عمل الأجهزة الاستشعارية. يُستخدَم هذا البروتوكول للتحكّم في تأثير الصوت الافتراضي (الصوت الثلاثي الأبعاد). تستخدِم هذه الصفحة المصطلحين الجهاز و المضيف وفقًا لتعريفهما في البلوتوث، حيث يشير الجهاز إلى جهاز تتبُّع الرأس ويشير المضيف إلى مضيف Android.
على الشركات المصنّعة للأجهزة ضبط إعدادات أجهزة Android لتفعيل ميزة استخدام بروتوكول HID لجهاز تتبُّع الرأس. للحصول على معلومات أكثر تفصيلاً حول الإعداد، يُرجى الاطّلاع على ملف ملاحظات Dynamic Sensors README.
تفترض هذه الصفحة معرفة المَراجع التالية:
البنية على مستوى أعلى
يحدِّد إطار عمل Android جهاز تتبُّع الرأس كجهاز HID.
للحصول على مثال كامل لموصّف HID صالح، راجِع الملحق 1: مثال لموصّف HID.
في المستوى الأعلى، يمثّل جهاز تتبُّع الرأس مجموعة تطبيقات تتضمّن
صفحة Sensors
(0x20
) واستخدام Other: Custom
(0xE1
). تتضمّن هذه
المجموعة عدّة حقول بيانات (مدخلات) وسمات (ميزات).
المواقع وحقول البيانات
يصف هذا القسم السمات وحقول البيانات في مجموعة بيانات جهاز تتبُّع الرأس.
السمة: وصف أداة الاستشعار (0x0308
)
سمة "وصف أداة الاستشعار" (0x0308
) هي سمة سلسلة ASCII (بسعة 8 بت)
للقراءة فقط يجب أن تحتوي على القيم التالية:
إصدار أداة تتبُّع حركة الرأس 1.0:
#AndroidHeadTracker#1.0
الإصدار 2.0 من أداة تتبُّع حركة الرأس (متاحة في الإصدار 15 من Android أو إصدار أحدث)، والذي يتضمّن تقنية LE Audio:
#AndroidHeadTracker#2.0#x
x
هو عدد صحيح (1
أو 2
أو 3
) يشير إلى بروتوكول النقل المتوافق:
- 1: ACL
- 2: ISO
- 3: ACL + ISO
لا يُتوقّع وجود عنصر إنهاء فارغ، ما يعني أنّ الحجم الإجمالي لهذه السمة هو 23 حرفًا من 8 بت للإصدار 1.0.
تُستخدَم هذه السمة كعنصر تمييز لتجنُّب حدوث تداخل مع الأجهزة الاستشعارية المخصّصة الأخرى.
السمة: المعرّف الفريد الثابت (0x0302
)
سمة المعرّف الفريد الدائم (0x0302
) هي صفيف للقراءة فقط يتألف من 16
عنصرًا، بسعة 8 بت لكل عنصر (إجمالي 128 بت). لا يُتوقّع وجود عنصر إنهاء فارغ. هذا
السمة اختيارية.
تسمح هذه السمة لأجهزة تتبُّع حركة الرأس والمدمجة في أجهزة الصوت بالإشارة إلى جهاز الصوت المرتبط بها. المخطّطات التالية متاحة.
أداة تتبُّع الرأس المستقلة
إذا لم تكن سمة المعرّف الفريد الدائم (0x0302
) متوفّرة أو تم ضبطها على كل
الأرقام الصفرية، يعني ذلك أنّ جهاز تتبُّع الرأس غير مرتبط بشكل دائم بجهاز
صوت ويمكن استخدامه بشكل منفصل، على سبيل المثال، من خلال السماح للمستخدم
بربط جهاز تتبُّع الرأس يدويًا بجهاز صوت منفصل.
الإشارة إلى عنوان MAC الخاص بالبلوتوث
وحدة ثمانيّة البت | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
القيمة | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | B | T | عنوان MAC الخاص بالبلوتوث |
في هذا المخطط، يجب أن تكون الأوكتات الثمانية الأولى هي 0
، ويجب أن تحتوي الأوكتات 8 و9 على
قيم ASCII B
وT
على التوالي، ويتم تفسير الأوكتات الستة التالية
على أنّها عنوان MAC لتقنية Bluetooth، بافتراض أنّ جهاز تتبُّع حركة الرأس
ينطبق على أي جهاز صوتي يتضمّن عنوان MAC هذا. يجب أن يكون هذا العنوان هو عنوان
المعرّف، حتى إذا كان الجهاز يستخدم عنوان MAC عشوائيًا لإنشاء
عمليات الربط. يجب أن تعرض الأجهزة المزوّدة بوضعَين وتتم ربطها عبر البلوتوث الكلاسيكي
(بتنسيق HID 1.0) وBluetooth LE (بتنسيق HID 2.0) وصفَين HID
بعنوان الهوية نفسه. يجب أن تعرض الأجهزة المزودة بوضعَين والتي تتضمّن جهازَين منفصلَين، أحدهما على يمين الجهاز والآخر على يساره، واجهة HID لتقنية Bluetooth LE باستخدام الجهاز الأساسي المزوّد بوضعَين بدلاً من الجهاز الثانوي المزوّد بتقنية LE فقط.
الإشارة باستخدام المعرّف الفريد العالمي (UUID)
عند ضبط أهم وحدة بت (MSB) من الثمانيت 8 (≥0x80
)، يتم تفسير الحقل
على أنّه معرّف UUID، كما هو محدّد في
RFC-4122. يقدّم
جهاز الصوت المقابل المعرّف الفريد العالمي (UUID) نفسه، والذي تم تسجيله في
إطار عمل Android، من خلال آلية غير محدّدة خاصة
بنوع النقل المستخدَم.
السمة: حالة إعداد التقارير (0x0316
)
سمة حالة إعداد التقارير (0x0316
) هي سمة للقراءة/الكتابة تحتوي على
الدلالات العادية كما هو موضّح في مواصفات HID. يستخدم المضيف هذه
السمة للإشارة إلى الجهاز بالأحداث التي يجب الإبلاغ عنها. لا يتم استخدام سوى القيم "لا يوجد
أحداث" (0x0840
) و"كل الأحداث" (0x0841
).
يجب أن تكون القيمة الأولية لهذا الحقل "ما مِن أحداث"، ويجب ألا يغيّرها الجهاز أبدًا، بل المضيف فقط.
السمة: حالة الطاقة (0x0319
)
سمة حالة الطاقة (0x0319
) هي سمة للقراءة/الكتابة تحتوي على
الدلالات العادية كما هو محدّد في مواصفات HID. يستخدم المضيف هذه السمة
للإشارة إلى الجهاز بشأن حالة الطاقة التي يجب أن يكون عليها. لا يتم استخدام سوى
القيمتَين "تشغيل الطاقة الكاملة" (0x0851
) و"إيقاف الطاقة" (0x0855
).
يحدِّد الجهاز القيمة الأولية لهذا الحقل، ويجب ألا يغيّرها أبدًا، بل يجب أن يغيّرها المضيف فقط.
السمة: فاصل إعداد التقارير (0x030E
)
خاصية فاصل إعداد التقارير (0x030E
) هي خاصية للقراءة/الكتابة تحتوي على
الدلالات العادية كما هو محدّد في مواصفات HID. يستخدم المضيف هذه
السمة للإشارة إلى الجهاز بعدد المرات التي يجب فيها الإبلاغ عن قراءات البيانات.
يتم قياس الوحدات بالثواني. يحدِّد الجهاز النطاق الصالح لهذه القيمة ويصفّه باستخدام آلية الحد الأدنى/الحد الأقصى المادي. يجب أن يكون معدل الإبلاغ 50 هرتز
على الأقل، والحد الأقصى المُقترَح لمعدل الإبلاغ هو
100 هرتز. لذلك، يجب أن يكون الحد الأدنى لفاصل الإبلاغ أقل من أو يساوي
20 ملي ثانية، ويُنصح بأن يكون أكبر من أو يساوي 10 ملي ثانية.
السمة: نقل LE محجوز من المورّد (0xF410
)
سمة LE Transport (0xF410
) المحجوزة للمورّد هي سمة للقراءة/الكتابة
تتضمن الدلالات العادية كما هو محدّد في مواصفات HID. يستخدم المضيف
هذه السمة للإشارة إلى وسيط النقل المحدّد (ACL أو ISO). لا يتم استخدام سوى قيم ACL (0xF800
) وISO (0xF801
)، ويجب تضمين كليهما في المجموعة المنطقية.
يتم ضبط هذه السمة قبل حالات الطاقة أو إعداد التقارير.
حقل البيانات: القيمة المخصّصة 1 (0x0544
)
حقل "القيمة المخصّصة 1" (0x0544
) هو حقل إدخال يُستخدَم لتسجيل
معلومات تتبُّع الرأس الفعلية. وهي مصفوفة من 3 عناصر، ويتم تفسيرها وفقًا
لقواعد HID العادية للقيم المادية كما هو موضّح في القسم 6.2.2.7 من
مواصفات HID. النطاق الصالح لكل عنصر هو [-π, π] راديان. تكون الوحدات
دائمًا راديان.
يتم تفسير العناصر على النحو التالي: [rx, ry, rz]
، بحيث يكون [rx, ry, rz]
هو
ناقل دوران،
يمثّل عملية التحويل من الإطار المرجعي إلى إطار الرأس.
يجب أن يكون حجم الإشعاع ضمن النطاق [0..π].
الإطار المرجعي عشوائي، ولكنه ثابت بشكل عام ويجب أن يكون يمينيًا. يُسمح بانحراف بسيط. محاور الرأس هي:
- X من الأذن اليسرى إلى اليمنى
- نعم من مؤخرة الرأس إلى الأنف (من الخلف إلى الأمام)
- Z من الرقبة إلى أعلى الرأس
حقل البيانات: القيمة المخصّصة 2 (0x0545
)
حقل "القيمة المخصّصة 2" (0x0545
) هو حقل إدخال يُستخدَم لإعداد تقارير عن
معلومات تتبُّع الرأس الفعلية. وهي مصفوفة ذات نقطة ثابتة تتألف من 3 عناصر، ويتم تفسيرها وفقًا لقواعد HID العادية للقيم المادية.
تكون الوحدات دائمًا راديان/ثانية.
يتم تفسير العناصر على النحو التالي: [vx, vy, vz]
، بحيث يكون [vx, vy, vz]
هو
ناقل دوران،
يمثّل السرعة الزاويّة لإطار الرأس (بالنسبة إلى نفسه).
حقل البيانات: القيمة المخصّصة 3 (0x0546
)
حقل "القيمة المخصّصة 3" (0x0546
) هو حقل إدخال يُستخدَم لتتبُّع
الانقطاعات في الإطار المرجعي. وهو عدد صحيح قياسي بحجم 8 بت. ويجب أن يزيد الجهاز هذا العدد (مع إعادة اللف) في كل مرة يتم فيها
تغيير الإطار المرجعي، على سبيل المثال، إذا تم إعادة ضبط حالة خوارزمية فلتر الاتجاه
المستخدَمة لتحديد الاتجاه. يتمinterpreted تفسير هذه القيمة وفقًا لقواعد HID العادية للقيم المادية. ومع ذلك،
لا يهمّ القيمة المادية والوحدات. إنّ المعلومات الوحيدة ذات الصلة بالمضيف هي القيمة التي تم تغييرها. لتجنُّب المشاكل الرقمية المرتبطة بفقدان الدقة
أثناء التحويل من الوحدات المنطقية إلى الوحدات الفعلية، ننصحك بضبط
قيم الحد الأدنى الفعلي والحد الأقصى الفعلي ومعامل الوحدة على القيمة صفر لهذا الحقل.
بنية التقرير
إنّ تجميع المواقع في تقارير (من خلال منح معرّفات التقارير) هو عملية مرنة. لتحقيق الكفاءة، ننصحك بفصل المواقع التي تتيح القراءة فقط عن المواقع التي تتيح القراءة والكتابة.
بالنسبة إلى حقول البيانات، يجب أن تكون حقول "القيمة المخصّصة 1" و"القيمة المخصّصة 2" و"القيمة المخصّصة 3" في الجدول نفسه، ويجب أن تكون في تقرير واحد فقط لجهاز معيّن (مجموعة تطبيقات).
إرسال تقارير الإدخال
يجب أن يرسل الجهاز تقارير الإدخال بشكل دوري وغير متزامن (من خلال رسائل HID INPUT) عند استيفاء جميع هذه الشروط:
- تم ضبط سمة Power State (حالة الطاقة) على Full Power (طاقة كاملة).
- تم ضبط سمة حالة إعداد التقارير على "كل الأحداث".
- تكون قيمة سمة فاصل إعداد التقارير غير صفرية.
تحدِّد خاصيّة "معدّل تكرار إعداد التقارير" عدد مرّات إرسال التقارير. في حال عدم استيفاء أي من الشروط أعلاه، يجب ألا يرسل الجهاز أي تقارير.
التوافق مع الإصدارات السابقة واللاحقة
يستخدم بروتوكول HID لتتبُّع حركة الرأس مخطّط إصدارات يتيح التحديثات، مع السماح بإمكانية التشغيل التفاعلي بين مضيف وجهاز يستخدمان إصدارات مختلفة من البروتوكول. يتم تحديد إصدارات البروتوكول برقمين، رئيسي وثانوي، لهما دلالات مختلفة كما هو описан في الأقسام التالية.
يمكن تحديد الإصدارات المتوافقة مع الجهاز من خلال فحص
السمة Sensor Description (0x0308
) الخاصة به.
التوافق مع الإصدارات الثانوية
تكون التغييرات التي يتم إجراؤها على الإصدار الثانوي متوافقة مع الإصدارات الثانوية السابقة التي تستند إلى الإصدار الرئيسي نفسه. في التحديثات التي تطرأ على الإصدار الفرعي، يتجاهل المضيف حقول البيانات والسمات الإضافية. على سبيل المثال، الجهاز الذي يستخدم الإصدار 1.6 من البروتوكول متوافق مع مضيف يتوافق مع الإصدار 1.x من البروتوكول، بما في ذلك الإصدار 1.5.
التوافق مع الإصدارات الرئيسية
يُسمح بإجراء تغييرات غير متوافقة مع الإصدارات القديمة في الإصدارات الرئيسية. ولتمكّن الأجهزة من إتاحة إصدارات رئيسية متعددة للتوافق مع المضيفين القدامى والجدد، يمكن للأجهزة تحديد مجموعات تطبيقات متعددة في وصفي ملف التقارير. مثلاً:
const unsigned char ReportDescriptor[] = {
HID_USAGE_PAGE_SENSOR,
HID_USAGE_SENSOR_TYPE_OTHER_CUSTOM,
HID_COLLECTION(HID_APPLICATION),
// Feature report 2 (read-only).
HID_REPORT_ID(2),
// Magic value: "#AndroidHeadTracker#1.5"
HID_USAGE_SENSOR_PROPERTY_SENSOR_DESCRIPTION,
HID_LOGICAL_MIN_8(0),
HID_LOGICAL_MAX_8(0xFF),
HID_REPORT_SIZE(8),
HID_REPORT_COUNT(23),
HID_FEATURE(HID_CONST_VAR_ABS),
...
HID_END_COLLECTION,
HID_COLLECTION(HID_APPLICATION),
// Feature report 12 (read-only).
HID_REPORT_ID(12),
// Magic value: "#AndroidHeadTracker#2.4"
HID_USAGE_SENSOR_PROPERTY_SENSOR_DESCRIPTION,
HID_LOGICAL_MIN_8(0),
HID_LOGICAL_MAX_8(0xFF),
HID_REPORT_SIZE(8),
HID_REPORT_COUNT(23),
HID_FEATURE(HID_CONST_VAR_ABS),
...
HID_END_COLLECTION,
};
في هذه الحالة، يمكن للمضيف سرد جميع مجموعات التطبيقات المختلفة التي يُعلِن عنها الجهاز، وفحص سمة "وصف أداة الاستشعار" لتحديد إصدارات البروتوكول التي ينفِّذها كلّ منها، ثم اختيار أحدث إصدار من البروتوكول يتيح للمضيف استخدامه. عند اختياره، يعمل المضيف مع البروتوكول الوحيد الذي تم اختياره طوال فترة اتصال الجهاز.
الملحق: مثال على وصف HID
يوضّح المثال التالي وصفًا نموذجيًا صالحًا لجهاز HID. ويستخدم رمز برمجي مختصر شائعًا في لغة C، وهو متوفر في استخدامات أدوات استشعار HID (القسم 4.1).
const unsigned char ReportDescriptor[] = {
HID_USAGE_PAGE_SENSOR,
HID_USAGE_SENSOR_TYPE_OTHER_CUSTOM,
HID_COLLECTION(HID_APPLICATION),
// Feature report 2 (read-only).
HID_REPORT_ID(2),
// Magic value: "#AndroidHeadTracker#1.0"
HID_USAGE_SENSOR_PROPERTY_SENSOR_DESCRIPTION,
HID_LOGICAL_MIN_8(0),
HID_LOGICAL_MAX_8(0xFF),
HID_REPORT_SIZE(8),
HID_REPORT_COUNT(23),
HID_FEATURE(HID_CONST_VAR_ABS),
// UUID.
HID_USAGE_SENSOR_PROPERTY_PERSISTENT_UNIQUE_ID,
HID_LOGICAL_MIN_8(0),
HID_LOGICAL_MAX_8(0xFF),
HID_REPORT_SIZE(8),
HID_REPORT_COUNT(16),
HID_FEATURE(HID_CONST_VAR_ABS),
// Feature report 1 (read/write).
HID_REPORT_ID(1),
// 1-bit on/off reporting state.
HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE,
HID_LOGICAL_MIN_8(0),
HID_LOGICAL_MAX_8(1),
HID_REPORT_SIZE(1),
HID_REPORT_COUNT(1),
HID_COLLECTION(HID_LOGICAL),
HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS,
HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS,
HID_FEATURE(HID_DATA_ARR_ABS),
HID_END_COLLECTION,
// 1-bit on/off power state.
HID_USAGE_SENSOR_PROPERTY_POWER_STATE,
HID_LOGICAL_MIN_8(0),
HID_LOGICAL_MAX_8(1),
HID_REPORT_SIZE(1),
HID_REPORT_COUNT(1),
HID_COLLECTION(HID_LOGICAL),
HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D4_POWER_OFF,
HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D0_FULL_POWER,
HID_FEATURE(HID_DATA_ARR_ABS),
HID_END_COLLECTION,
// 6-bit reporting interval, with values [0x00..0x3F] corresponding to [10ms..100ms].
HID_USAGE_SENSOR_PROPERTY_REPORT_INTERVAL,
HID_LOGICAL_MIN_8(0x00),
HID_LOGICAL_MAX_8(0x3F),
HID_PHYSICAL_MIN_8(10),
HID_PHYSICAL_MAX_8(100),
HID_REPORT_SIZE(6),
HID_REPORT_COUNT(1),
HID_USAGE_SENSOR_UNITS_SECOND,
HID_UNIT_EXPONENT(0xD), // 10^-3
HID_FEATURE(HID_DATA_VAR_ABS),
// Input report 1
// Orientation as rotation vector (scaled to [-pi..pi] rad).
HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_1,
HID_LOGICAL_MIN_16(0x01, 0x80), // LOGICAL_MINIMUM (-32767)
HID_LOGICAL_MAX_16(0xFF, 0x7F), // LOGICAL_MAXIMUM (32767)
HID_PHYSICAL_MIN_32(0x60, 0x4F, 0x46, 0xED), // -314159265
HID_PHYSICAL_MAX_32(0xA1, 0xB0, 0xB9, 0x12), // 314159265
HID_UNIT_EXPONENT(0x08), // 10^-8
HID_REPORT_SIZE(16),
HID_REPORT_COUNT(3),
HID_INPUT(HID_DATA_VAR_ABS),
// Angular velocity as rotation vector (scaled to [-32..32] rad/sec).
HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_2,
HID_LOGICAL_MIN_16(0x01, 0x80), // LOGICAL_MINIMUM (-32767)
HID_LOGICAL_MAX_16(0xFF, 0x7F), // LOGICAL_MAXIMUM (32767)
HID_PHYSICAL_MIN_8(0xE0),
HID_PHYSICAL_MAX_8(0x20),
HID_UNIT_EXPONENT(0x00), // 10^0
HID_REPORT_SIZE(16),
HID_REPORT_COUNT(3),
HID_INPUT(HID_DATA_VAR_ABS),
// Reference frame reset counter.
HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_3,
HID_LOGICAL_MIN_16(0x00, 0x00), // LOGICAL_MINIMUM (0)
HID_LOGICAL_MAX_16(0xFF, 0x00), // LOGICAL_MAXIMUM (255)
HID_PHYSICAL_MIN_8(0x00),
HID_PHYSICAL_MAX_8(0x00),
HID_UNIT_EXPONENT(0x00), // 10^0
HID_REPORT_SIZE(8),
HID_REPORT_COUNT(1),
HID_INPUT(HID_DATA_VAR_ABS),
HID_END_COLLECTION,
};
الملحق 2: مثال على وصف HID بالإصدار 2.0
يوضّح المثال التالي وصف HID بالإصدار 2.0 لجهاز يتوافق مع نقل ACL في Bluetooth LE فقط.
const unsigned char ReportDescriptor[] = {
HID_USAGE_PAGE_SENSOR,
HID_USAGE_SENSOR_TYPE_OTHER_CUSTOM,
HID_COLLECTION(HID_APPLICATION),
// Feature report 2 (read-only).
HID_REPORT_ID(2),
// Magic value: "#AndroidHeadTracker#2.0#1"
HID_USAGE_SENSOR_PROPERTY_SENSOR_DESCRIPTION,
HID_LOGICAL_MIN_8(0),
HID_LOGICAL_MAX_8(0xFF),
HID_REPORT_SIZE(8),
HID_REPORT_COUNT(25),
HID_FEATURE(HID_CONST_VAR_ABS),
// UUID.
HID_USAGE_SENSOR_PROPERTY_PERSISTENT_UNIQUE_ID,
HID_LOGICAL_MIN_8(0),
HID_LOGICAL_MAX_8(0xFF),
HID_REPORT_SIZE(8),
HID_REPORT_COUNT(16),
HID_FEATURE(HID_CONST_VAR_ABS),
// Feature report 1 (read/write).
HID_REPORT_ID(1),
// 1-bit on/off reporting state.
HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE,
HID_LOGICAL_MIN_8(0),
HID_LOGICAL_MAX_8(1),
HID_REPORT_SIZE(1),
HID_REPORT_COUNT(1),
HID_COLLECTION(HID_LOGICAL),
HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS,
HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS,
HID_FEATURE(HID_DATA_ARR_ABS),
HID_END_COLLECTION,
// 1-bit on/off power state.
HID_USAGE_SENSOR_PROPERTY_POWER_STATE,
HID_LOGICAL_MIN_8(0),
HID_LOGICAL_MAX_8(1),
HID_REPORT_SIZE(1),
HID_REPORT_COUNT(1),
HID_COLLECTION(HID_LOGICAL),
HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D4_POWER_OFF,
HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D0_FULL_POWER,
HID_FEATURE(HID_DATA_ARR_ABS),
HID_END_COLLECTION,
// 6-bit reporting interval, with values [0x00..0x3F] corresponding to [10ms..100ms].
HID_USAGE_SENSOR_PROPERTY_REPORT_INTERVAL,
HID_LOGICAL_MIN_8(0x00),
HID_LOGICAL_MAX_8(0x3F),
HID_PHYSICAL_MIN_8(10),
HID_PHYSICAL_MAX_8(100),
HID_REPORT_SIZE(6),
HID_REPORT_COUNT(1),
HID_USAGE_SENSOR_UNITS_SECOND,
HID_UNIT_EXPONENT(0xD), // 10^-3
HID_FEATURE(HID_DATA_VAR_ABS),
// 1-bit transport selection
HID_USAGE_SENSOR_PROPERTY_VENDOR_LE_TRANSPORT,
HID_LOGICAL_MIN_8(0),
HID_LOGICAL_MAX_8(1),
HID_REPORT_SIZE(1),
HID_REPORT_COUNT(1),
HID_COLLECTION(HID_LOGICAL),
HID_USAGE_SENSOR_PROPERTY_VENDOR_LE_TRANSPORT_ACL,
HID_USAGE_SENSOR_PROPERTY_VENDOR_LE_TRANSPORT_ISO,
HID_FEATURE(HID_DATA_ARR_ABS),
HID_END_COLLECTION,
// Input report 1
// Orientation as rotation vector (scaled to [-pi..pi] rad).
HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_1,
HID_LOGICAL_MIN_16(0x01, 0x80), // LOGICAL_MINIMUM (-32767)
HID_LOGICAL_MAX_16(0xFF, 0x7F), // LOGICAL_MAXIMUM (32767)
HID_PHYSICAL_MIN_32(0x60, 0x4F, 0x46, 0xED), // -314159265
HID_PHYSICAL_MAX_32(0xA1, 0xB0, 0xB9, 0x12), // 314159265
HID_UNIT_EXPONENT(0x08), // 10^-8
HID_REPORT_SIZE(16),
HID_REPORT_COUNT(3),
HID_INPUT(HID_DATA_VAR_ABS),
// Angular velocity as rotation vector (scaled to [-32..32] rad/sec).
HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_2,
HID_LOGICAL_MIN_16(0x01, 0x80), // LOGICAL_MINIMUM (-32767)
HID_LOGICAL_MAX_16(0xFF, 0x7F), // LOGICAL_MAXIMUM (32767)
HID_PHYSICAL_MIN_8(0xE0),
HID_PHYSICAL_MAX_8(0x20),
HID_UNIT_EXPONENT(0x00), // 10^0
HID_REPORT_SIZE(16),
HID_REPORT_COUNT(3),
HID_INPUT(HID_DATA_VAR_ABS),
// Reference frame reset counter.
HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_3,
HID_LOGICAL_MIN_16(0x00, 0x00), // LOGICAL_MINIMUM (0)
HID_LOGICAL_MAX_16(0xFF, 0x00), // LOGICAL_MAXIMUM (255)
HID_PHYSICAL_MIN_8(0x00),
HID_PHYSICAL_MAX_8(0x00),
HID_UNIT_EXPONENT(0x00), // 10^0
HID_REPORT_SIZE(8),
HID_REPORT_COUNT(1),
HID_INPUT(HID_DATA_VAR_ABS),
HID_END_COLLECTION,
};