A BLE HID controller implementation with communication over SPI
Dependencies: BLE_API BLE_HID mbed nRF51822
main.cpp
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2015 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #include "mbed.h" 00018 00019 #include "ble/BLE.h" 00020 #include "ControllerService.h" 00021 #include "common.h" 00022 00023 /** 00024 * This program implements a complete HID-over-Gatt Profile: 00025 * - HID is provided by ControllerServices 00026 * - Battery Service 00027 * - Device Information Service 00028 * 00029 */ 00030 00031 DigitalOut waiting_led(LED1); 00032 DigitalOut connected_led(LED2); 00033 00034 00035 SPISlave arduino(p23, p22, p21, p24); // mosi, miso, sck, ssel 00036 DigitalOut arduino_int(p25); 00037 00038 BLE ble; 00039 ControllerService *contServicePtr; 00040 00041 static const char DEVICE_NAME[] = "puppeteerPro"; 00042 static const char SHORT_DEVICE_NAME[] = "pptPro"; 00043 00044 static void onDisconnect(const Gap::DisconnectionCallbackParams_t *params) 00045 { 00046 HID_DEBUG("disconnected\r\n"); 00047 connected_led = 0; 00048 00049 ble.gap().startAdvertising(); // restart advertising 00050 } 00051 00052 static void onConnect(const Gap::ConnectionCallbackParams_t *params) 00053 { 00054 HID_DEBUG("connected\r\n"); 00055 waiting_led = false; 00056 } 00057 00058 static void waiting() { 00059 if (!contServicePtr->isConnected()) { 00060 //connected_led = !connected_led; 00061 } 00062 else { 00063 //connected_led = 1; 00064 } 00065 } 00066 00067 // Current system 00068 // arduino does slave select & interrupt 00069 // arduino transfers 00070 // ble hits isr & records current report 00071 void spi_receive() { 00072 static uint8_t byte_count = 0; 00073 static uint8_t current_report[6] = {0}; 00074 00075 if(arduino.receive()) { 00076 waiting_led = !waiting_led; 00077 uint8_t resp = arduino.read(); 00078 00079 if (resp == 0xFF) { 00080 byte_count = 0; 00081 memset(current_report, 0, sizeof(current_report)); 00082 } else { 00083 current_report[byte_count] = resp; 00084 byte_count++; 00085 00086 if (byte_count == 6) { 00087 connected_led = !connected_led; 00088 contServicePtr->setReport(current_report); 00089 byte_count = 0; 00090 } 00091 } 00092 arduino.reply(0xAA); 00093 00094 // finally trigger interrupt to signal receiving 00095 arduino_int = 0; 00096 wait_us(100); 00097 arduino_int = 1; 00098 wait_us(100); 00099 arduino_int = 0; 00100 } 00101 } 00102 00103 int main() 00104 { 00105 Ticker heartbeat; 00106 00107 HID_DEBUG("initialising ticker\r\n"); 00108 00109 heartbeat.attach(waiting, 1); 00110 00111 HID_DEBUG("initialising ble\r\n"); 00112 ble.init(); 00113 00114 ble.gap().onDisconnection(onDisconnect); 00115 ble.gap().onConnection(onConnect); 00116 00117 initializeSecurity(ble); 00118 00119 HID_DEBUG("adding hid service\r\n"); 00120 ControllerService contService(ble); 00121 contServicePtr = &contService; 00122 00123 HID_DEBUG("adding device info and battery service\r\n"); 00124 initializeHOGP(ble); 00125 00126 HID_DEBUG("setting up gap\r\n"); 00127 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::GAMEPAD); 00128 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, 00129 (const uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); 00130 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME, 00131 (const uint8_t *)SHORT_DEVICE_NAME, sizeof(SHORT_DEVICE_NAME)); 00132 00133 ble.gap().setDeviceName((const uint8_t *)DEVICE_NAME); 00134 00135 HID_DEBUG("advertising\r\n"); 00136 ble.gap().startAdvertising(); 00137 00138 // Start interrupt sequence for SPI with Arduino 00139 Ticker spi_thread; 00140 connected_led = 1; 00141 arduino_int = 0; 00142 arduino.reply(0xAA); 00143 spi_thread.attach(spi_receive, 0.020); // 5ms ticker sequence 00144 00145 00146 while (true) { 00147 ble.waitForEvent(); 00148 } 00149 }
Generated on Tue Jul 26 2022 20:51:08 by 1.7.2