ALways output MIDI data through BLE

Dependencies:   microbit

Committer:
dw02136
Date:
Sun Oct 06 05:08:18 2019 +0000
Revision:
0:cf9bce1f2f5e
1st Issue

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dw02136 0:cf9bce1f2f5e 1 /*
dw02136 0:cf9bce1f2f5e 2 The MIT License (MIT)
dw02136 0:cf9bce1f2f5e 3
dw02136 0:cf9bce1f2f5e 4 Copyright (c) 2016 British Broadcasting Corporation.
dw02136 0:cf9bce1f2f5e 5 This software is provided by Lancaster University by arrangement with the BBC.
dw02136 0:cf9bce1f2f5e 6
dw02136 0:cf9bce1f2f5e 7 Permission is hereby granted, free of charge, to any person obtaining a
dw02136 0:cf9bce1f2f5e 8 copy of this software and associated documentation files (the "Software"),
dw02136 0:cf9bce1f2f5e 9 to deal in the Software without restriction, including without limitation
dw02136 0:cf9bce1f2f5e 10 the rights to use, copy, modify, merge, publish, distribute, sublicense,
dw02136 0:cf9bce1f2f5e 11 and/or sell copies of the Software, and to permit persons to whom the
dw02136 0:cf9bce1f2f5e 12 Software is furnished to do so, subject to the following conditions:
dw02136 0:cf9bce1f2f5e 13
dw02136 0:cf9bce1f2f5e 14 The above copyright notice and this permission notice shall be included in
dw02136 0:cf9bce1f2f5e 15 all copies or substantial portions of the Software.
dw02136 0:cf9bce1f2f5e 16
dw02136 0:cf9bce1f2f5e 17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
dw02136 0:cf9bce1f2f5e 18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
dw02136 0:cf9bce1f2f5e 19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
dw02136 0:cf9bce1f2f5e 20 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
dw02136 0:cf9bce1f2f5e 21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
dw02136 0:cf9bce1f2f5e 22 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
dw02136 0:cf9bce1f2f5e 23 DEALINGS IN THE SOFTWARE.
dw02136 0:cf9bce1f2f5e 24 */
dw02136 0:cf9bce1f2f5e 25
dw02136 0:cf9bce1f2f5e 26 #include "MicroBit.h"
dw02136 0:cf9bce1f2f5e 27
dw02136 0:cf9bce1f2f5e 28 const static char DEVICE_NAME[] = "MY_MICROBIT_BLE_MIDI";
dw02136 0:cf9bce1f2f5e 29 const uint8_t MIDI_SERVICE[16] = {
dw02136 0:cf9bce1f2f5e 30 0x03, 0xb8, 0x0e, 0x5a, 0xed, 0xe8, 0x4b, 0x33, 0xa7, 0x51, 0x6c, 0xe3, 0x4e, 0xc4, 0xc7, 0x00
dw02136 0:cf9bce1f2f5e 31 };
dw02136 0:cf9bce1f2f5e 32 const uint8_t MIDI_CHAR[16] = {
dw02136 0:cf9bce1f2f5e 33 0x77, 0x72, 0xe5, 0xdb, 0x38, 0x68, 0x41, 0x12, 0xa1, 0xa9, 0xf2, 0x66, 0x9d, 0x10, 0x6b, 0xf3
dw02136 0:cf9bce1f2f5e 34 };
dw02136 0:cf9bce1f2f5e 35
dw02136 0:cf9bce1f2f5e 36 MicroBit uBit;
dw02136 0:cf9bce1f2f5e 37 Serial pc(USBTX, USBRX);
dw02136 0:cf9bce1f2f5e 38
dw02136 0:cf9bce1f2f5e 39 bool isConnect = false;
dw02136 0:cf9bce1f2f5e 40
dw02136 0:cf9bce1f2f5e 41 //MIDI Charactarastics/Service
dw02136 0:cf9bce1f2f5e 42 uint8_t midiPayload[5] = { 0x80, 0x80, 0x00, 0x00, 0x00 };
dw02136 0:cf9bce1f2f5e 43
dw02136 0:cf9bce1f2f5e 44 GattCharacteristic midiChar (MIDI_CHAR,
dw02136 0:cf9bce1f2f5e 45 midiPayload, 5, 5,
dw02136 0:cf9bce1f2f5e 46 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ);
dw02136 0:cf9bce1f2f5e 47 GattCharacteristic *midiChars[] = {&midiChar, };
dw02136 0:cf9bce1f2f5e 48 GattService midiService(MIDI_SERVICE, midiChars,
dw02136 0:cf9bce1f2f5e 49 sizeof(midiChars) / sizeof(GattCharacteristic *));
dw02136 0:cf9bce1f2f5e 50
dw02136 0:cf9bce1f2f5e 51 static Gap::ConnectionParams_t connectionParams;
dw02136 0:cf9bce1f2f5e 52
dw02136 0:cf9bce1f2f5e 53 //NoteOn
dw02136 0:cf9bce1f2f5e 54 void notifyNote(uint8_t note, uint8_t velocity);
dw02136 0:cf9bce1f2f5e 55
dw02136 0:cf9bce1f2f5e 56 //BLE Connection Callback
dw02136 0:cf9bce1f2f5e 57 void onConnectionCallback(const Gap::ConnectionCallbackParams_t *params)
dw02136 0:cf9bce1f2f5e 58 {
dw02136 0:cf9bce1f2f5e 59 isConnect = true;
dw02136 0:cf9bce1f2f5e 60 pc.printf("connected. Got handle %u\r\n", params->handle);
dw02136 0:cf9bce1f2f5e 61 uBit.display.printChar('C');
dw02136 0:cf9bce1f2f5e 62
dw02136 0:cf9bce1f2f5e 63 connectionParams.slaveLatency = 1;
dw02136 0:cf9bce1f2f5e 64 if (uBit.ble->gap().updateConnectionParams(params->handle, &connectionParams) != BLE_ERROR_NONE) {
dw02136 0:cf9bce1f2f5e 65 pc.printf("failed to update connection paramter\r\n");
dw02136 0:cf9bce1f2f5e 66 }
dw02136 0:cf9bce1f2f5e 67 }
dw02136 0:cf9bce1f2f5e 68
dw02136 0:cf9bce1f2f5e 69 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
dw02136 0:cf9bce1f2f5e 70 {
dw02136 0:cf9bce1f2f5e 71 isConnect = false;
dw02136 0:cf9bce1f2f5e 72 pc.printf("Disconnected handle %u, reason %u\r\n", params->handle, params->reason);
dw02136 0:cf9bce1f2f5e 73 pc.printf("Restarting the advertising process\r\n");
dw02136 0:cf9bce1f2f5e 74 uBit.display.printChar('A');
dw02136 0:cf9bce1f2f5e 75
dw02136 0:cf9bce1f2f5e 76 pc.printf("Start Advertising\r\n");
dw02136 0:cf9bce1f2f5e 77 uBit.ble->gap().startAdvertising();
dw02136 0:cf9bce1f2f5e 78 }
dw02136 0:cf9bce1f2f5e 79
dw02136 0:cf9bce1f2f5e 80 int main()
dw02136 0:cf9bce1f2f5e 81 {
dw02136 0:cf9bce1f2f5e 82 // Initialise the micro:bit runtime.
dw02136 0:cf9bce1f2f5e 83 pc.printf("Initialising MicroBit\r\n");
dw02136 0:cf9bce1f2f5e 84 uBit.ble = new BLEDevice();
dw02136 0:cf9bce1f2f5e 85 uBit.init();
dw02136 0:cf9bce1f2f5e 86 uBit.ble->init();
dw02136 0:cf9bce1f2f5e 87 pc.printf("Init done\r\n");
dw02136 0:cf9bce1f2f5e 88
dw02136 0:cf9bce1f2f5e 89 //Add conection and disconnection callback
dw02136 0:cf9bce1f2f5e 90 uBit.ble->gap().onConnection(onConnectionCallback);
dw02136 0:cf9bce1f2f5e 91 uBit.ble->gap().onDisconnection(disconnectionCallback);
dw02136 0:cf9bce1f2f5e 92
dw02136 0:cf9bce1f2f5e 93 /* setup advertising */
dw02136 0:cf9bce1f2f5e 94 uBit.ble->gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
dw02136 0:cf9bce1f2f5e 95 //Reverse UUID for Adv
dw02136 0:cf9bce1f2f5e 96 uint8_t TMP_ADV_SERVICE[16];
dw02136 0:cf9bce1f2f5e 97 for(int i = 0; i < 16; i++)
dw02136 0:cf9bce1f2f5e 98 {
dw02136 0:cf9bce1f2f5e 99 TMP_ADV_SERVICE[i] = MIDI_SERVICE[15-i];
dw02136 0:cf9bce1f2f5e 100 }
dw02136 0:cf9bce1f2f5e 101 uBit.ble->gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, (uint8_t*)TMP_ADV_SERVICE, sizeof(TMP_ADV_SERVICE));
dw02136 0:cf9bce1f2f5e 102 uBit.ble->gap().accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_COMPUTER);
dw02136 0:cf9bce1f2f5e 103 uBit.ble->accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
dw02136 0:cf9bce1f2f5e 104 uBit.ble->gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
dw02136 0:cf9bce1f2f5e 105 uBit.ble->setAdvertisingInterval(160); /* 100ms; in multiples of 0.625ms. */
dw02136 0:cf9bce1f2f5e 106 uBit.ble->startAdvertising();
dw02136 0:cf9bce1f2f5e 107 pc.printf("Start Advertising\r\n");
dw02136 0:cf9bce1f2f5e 108 uBit.display.printChar('A');
dw02136 0:cf9bce1f2f5e 109
dw02136 0:cf9bce1f2f5e 110 uBit.ble->gattServer().addService(midiService);
dw02136 0:cf9bce1f2f5e 111
dw02136 0:cf9bce1f2f5e 112 // Insert your code here!
dw02136 0:cf9bce1f2f5e 113 while(1) {
dw02136 0:cf9bce1f2f5e 114 if(isConnect) {
dw02136 0:cf9bce1f2f5e 115 for (int note = 0x1E; note < 0x5A; note ++) {
dw02136 0:cf9bce1f2f5e 116 notifyNote(note, 0x45);
dw02136 0:cf9bce1f2f5e 117 wait_ms(100);
dw02136 0:cf9bce1f2f5e 118 notifyNote(note, 0x00);
dw02136 0:cf9bce1f2f5e 119 wait_ms(100);
dw02136 0:cf9bce1f2f5e 120 }
dw02136 0:cf9bce1f2f5e 121 }
dw02136 0:cf9bce1f2f5e 122 }
dw02136 0:cf9bce1f2f5e 123
dw02136 0:cf9bce1f2f5e 124 // If main exits, there may still be other fibers running or registered event handlers etc.
dw02136 0:cf9bce1f2f5e 125 // Simply release this fiber, which will mean we enter the scheduler. Worse case, we then
dw02136 0:cf9bce1f2f5e 126 // sit in the idle task forever, in a power efficient sleep.
dw02136 0:cf9bce1f2f5e 127 //release_fiber();
dw02136 0:cf9bce1f2f5e 128 }
dw02136 0:cf9bce1f2f5e 129
dw02136 0:cf9bce1f2f5e 130 //NotifyNote
dw02136 0:cf9bce1f2f5e 131 void notifyNote(uint8_t note, uint8_t velocity)
dw02136 0:cf9bce1f2f5e 132 {
dw02136 0:cf9bce1f2f5e 133 //Send Note
dw02136 0:cf9bce1f2f5e 134 midiPayload[2] = 0x90;
dw02136 0:cf9bce1f2f5e 135 midiPayload[3] = note;
dw02136 0:cf9bce1f2f5e 136 midiPayload[4] = velocity;
dw02136 0:cf9bce1f2f5e 137
dw02136 0:cf9bce1f2f5e 138 //Notify MIDI Data
dw02136 0:cf9bce1f2f5e 139 uBit.ble->gattServer().write(midiChar.getValueAttribute().getHandle(), midiPayload, sizeof(midiPayload));
dw02136 0:cf9bce1f2f5e 140 }