![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
A BLE HID controller implementation with communication over SPI
Dependencies: BLE_API BLE_HID mbed nRF51822
main.cpp
- Committer:
- mrhannah
- Date:
- 2017-12-13
- Revision:
- 0:f21dc3a04d62
File content as of revision 0:f21dc3a04d62:
/* 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 "ble/BLE.h" #include "ControllerService.h" #include "common.h" /** * This program implements a complete HID-over-Gatt Profile: * - HID is provided by ControllerServices * - Battery Service * - Device Information Service * */ DigitalOut waiting_led(LED1); DigitalOut connected_led(LED2); SPISlave arduino(p23, p22, p21, p24); // mosi, miso, sck, ssel DigitalOut arduino_int(p25); BLE ble; ControllerService *contServicePtr; static const char DEVICE_NAME[] = "puppeteerPro"; static const char SHORT_DEVICE_NAME[] = "pptPro"; static void onDisconnect(const Gap::DisconnectionCallbackParams_t *params) { HID_DEBUG("disconnected\r\n"); connected_led = 0; ble.gap().startAdvertising(); // restart advertising } static void onConnect(const Gap::ConnectionCallbackParams_t *params) { HID_DEBUG("connected\r\n"); waiting_led = false; } static void waiting() { if (!contServicePtr->isConnected()) { //connected_led = !connected_led; } else { //connected_led = 1; } } // Current system // arduino does slave select & interrupt // arduino transfers // ble hits isr & records current report void spi_receive() { static uint8_t byte_count = 0; static uint8_t current_report[6] = {0}; if(arduino.receive()) { waiting_led = !waiting_led; uint8_t resp = arduino.read(); if (resp == 0xFF) { byte_count = 0; memset(current_report, 0, sizeof(current_report)); } else { current_report[byte_count] = resp; byte_count++; if (byte_count == 6) { connected_led = !connected_led; contServicePtr->setReport(current_report); byte_count = 0; } } arduino.reply(0xAA); // finally trigger interrupt to signal receiving arduino_int = 0; wait_us(100); arduino_int = 1; wait_us(100); arduino_int = 0; } } int main() { Ticker heartbeat; HID_DEBUG("initialising ticker\r\n"); heartbeat.attach(waiting, 1); HID_DEBUG("initialising ble\r\n"); ble.init(); ble.gap().onDisconnection(onDisconnect); ble.gap().onConnection(onConnect); initializeSecurity(ble); HID_DEBUG("adding hid service\r\n"); ControllerService contService(ble); contServicePtr = &contService; HID_DEBUG("adding device info and battery service\r\n"); initializeHOGP(ble); HID_DEBUG("setting up gap\r\n"); ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::GAMEPAD); ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (const uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME, (const uint8_t *)SHORT_DEVICE_NAME, sizeof(SHORT_DEVICE_NAME)); ble.gap().setDeviceName((const uint8_t *)DEVICE_NAME); HID_DEBUG("advertising\r\n"); ble.gap().startAdvertising(); // Start interrupt sequence for SPI with Arduino Ticker spi_thread; connected_led = 1; arduino_int = 0; arduino.reply(0xAA); spi_thread.attach(spi_receive, 0.020); // 5ms ticker sequence while (true) { ble.waitForEvent(); } }