A BLE HID controller implementation with communication over SPI

Dependencies:   BLE_API BLE_HID mbed nRF51822

Revision:
0:f21dc3a04d62
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ControllerService.h	Wed Dec 13 05:34:15 2017 +0000
@@ -0,0 +1,116 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mbed.h"
+
+#include "HIDServiceBase.h"
+
+/**
+ * Report descriptor for a standard 3 buttons + wheel mouse with relative X/Y
+ * moves
+ */
+report_map_t CONTROLLER_REPORT_MAP = {
+        USAGE_PAGE(1),      0x01,       // Genric Desktop
+        USAGE(1),           0x05,       // Gamepad
+        COLLECTION(1),      0x01,       // Application
+        COLLECTION(1),      0x00,       // Physical
+        
+        REPORT_ID(1),       0x03,       // Report ID 3
+        USAGE_PAGE(1),      0x09,       // Buttons
+        USAGE_MINIMUM(1),       0x01,   // Minimum of 1
+        USAGE_MAXIMUM(1),       0x10,   // Maximum of 16
+        LOGICAL_MINIMUM(1),     0x00,   // Logical Minimum of 0
+        LOGICAL_MAXIMUM(1),     0x01,   // Logical Maximum of 1
+        REPORT_SIZE(1),     0x01,       // Each report is 1 bit
+        REPORT_COUNT(1),    0x10,       // All in all 16 * 1 bit
+        INPUT(1),           0x02,       // Input (Data, Var, Abs)
+        
+        USAGE_PAGE(1),      0x01,       // Generic Desktop
+        USAGE(1),           0x30,       // Usage X
+        USAGE(1),           0x31,       // Usage Y
+        USAGE(1),           0x32,       // Usage Z
+        USAGE(1),           0x33,       // Usage Rx
+        LOGICAL_MINIMUM(1), 0x00,       // Logical Minimum: 0
+        LOGICAL_MAXIMUM(1), 0xFE,       // Logical maximum: 254
+        REPORT_SIZE(1),     0x08,       // Each report is 8 bits
+        REPORT_COUNT(1),    0x04,       // 4 reports * 8 bits
+        INPUT(1),           0x02,        // Input (Data, Var, Abs)
+        END_COLLECTION(0),
+        END_COLLECTION(0)
+};
+
+uint8_t report[7] = {0x03, 0, 0, 0, 0, 0, 0};
+
+//bool toggle = true;
+//uint8_t onReport[7] = {0x03, 0xFF, 0xFF, 0x80, 0x80, 0x80, 0x80};
+//uint8_t offReport[7] = {0x03, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20};
+
+class ControllerService: public HIDServiceBase
+{
+public:
+    ControllerService(BLE &_ble) :
+        HIDServiceBase(_ble,
+                       CONTROLLER_REPORT_MAP, sizeof(CONTROLLER_REPORT_MAP),
+                       inputReport          = report,
+                       outputReport         = NULL,
+                       featureReport        = NULL,
+                       inputReportLength    = 7,
+                       outputReportLength   = 0,
+                       featureReportLength  = 0,
+                       reportTickerDelay    = 250)
+    {
+        failedReports = 0;
+        startReportTicker();
+    }
+
+    virtual void onConnection(const Gap::ConnectionCallbackParams_t *params)
+    {
+        HIDServiceBase::onConnection(params);
+        startReportTicker();
+    }
+
+    virtual void onDisconnection(const Gap::DisconnectionCallbackParams_t *params)
+    {
+        stopReportTicker();
+        HIDServiceBase::onDisconnection(params);
+    }
+    
+    void setReport(uint8_t *r) {
+//        for (int i = 0; i < 6; i++) {
+//            report[i+1] = r[i];
+//        }
+        memcpy(&report[1], r, 6);
+    }
+
+    /**
+     * Called by the report ticker
+     */
+
+    virtual void sendCallback(void) {
+//        if (toggle) {
+//            send(onReport);
+//        } else {
+//            send(offReport);
+//        }
+//        toggle = !toggle;
+        
+        if (send(report)) {
+            failedReports++;
+        }   
+    }
+    
+    uint32_t failedReports;
+};