BLE MIDI

Dependencies:   BLE_API mbed nRF51822

Committer:
niklasjakob
Date:
Mon Jun 12 17:12:31 2017 +0000
Revision:
0:7de36d52cfef
BLE MIDI BRIDGE TEST

Who changed what in which revision?

UserRevisionLine numberNew contents of line
niklasjakob 0:7de36d52cfef 1 /*
niklasjakob 0:7de36d52cfef 2 * Copyright (c) 2016 Samuele Cornell
niklasjakob 0:7de36d52cfef 3 *
niklasjakob 0:7de36d52cfef 4 * Permission is hereby granted, free of charge, to any person obtaining a copy
niklasjakob 0:7de36d52cfef 5 * of this software and associated documentation files (the "Software"), to deal
niklasjakob 0:7de36d52cfef 6 * in the Software without restriction, including without limitation the rights
niklasjakob 0:7de36d52cfef 7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
niklasjakob 0:7de36d52cfef 8 * copies of the Software, and to permit persons to whom the Software is
niklasjakob 0:7de36d52cfef 9 * furnished to do so, subject to the following conditions:
niklasjakob 0:7de36d52cfef 10 *
niklasjakob 0:7de36d52cfef 11 * The above copyright notice and this permission notice shall be included in all
niklasjakob 0:7de36d52cfef 12 * copies or substantial portions of the Software.
niklasjakob 0:7de36d52cfef 13 *
niklasjakob 0:7de36d52cfef 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
niklasjakob 0:7de36d52cfef 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
niklasjakob 0:7de36d52cfef 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
niklasjakob 0:7de36d52cfef 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
niklasjakob 0:7de36d52cfef 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
niklasjakob 0:7de36d52cfef 19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
niklasjakob 0:7de36d52cfef 20 * SOFTWARE.
niklasjakob 0:7de36d52cfef 21 *
niklasjakob 0:7de36d52cfef 22 */
niklasjakob 0:7de36d52cfef 23
niklasjakob 0:7de36d52cfef 24 /*
niklasjakob 0:7de36d52cfef 25 * Thanks to Matthias Frick and his project blidino https://github.com/sieren/blidino
niklasjakob 0:7de36d52cfef 26 * which also uses RedBearslab nRF51822 and implements a USB-MIDI to BLE-MIDI bridge.
niklasjakob 0:7de36d52cfef 27 * His work made this possible and served as the main inspiration for this project .
niklasjakob 0:7de36d52cfef 28 * The content of BLEMIDI_MIDI_Parser.h file is for the most part taken from his blidino project.
niklasjakob 0:7de36d52cfef 29 */
niklasjakob 0:7de36d52cfef 30
niklasjakob 0:7de36d52cfef 31 #include "mbed.h"
niklasjakob 0:7de36d52cfef 32
niklasjakob 0:7de36d52cfef 33 #include "ble/BLE.h"
niklasjakob 0:7de36d52cfef 34
niklasjakob 0:7de36d52cfef 35 #include "LEDService.h"
niklasjakob 0:7de36d52cfef 36
niklasjakob 0:7de36d52cfef 37 Serial UART(UART_TX_PIN,UART_RX_PIN) ; //UART_RX_PIN,BUFSERIAL_LENGHT
niklasjakob 0:7de36d52cfef 38
niklasjakob 0:7de36d52cfef 39 #if ONLY_MIDI_to_BLEMIDI==0
niklasjakob 0:7de36d52cfef 40
niklasjakob 0:7de36d52cfef 41 #include "BLEMIDI_MIDI_Parser.h"
niklasjakob 0:7de36d52cfef 42
niklasjakob 0:7de36d52cfef 43 #endif
niklasjakob 0:7de36d52cfef 44
niklasjakob 0:7de36d52cfef 45 #if ONLY_BLEMIDI_to_MIDI==0
niklasjakob 0:7de36d52cfef 46
niklasjakob 0:7de36d52cfef 47 #include "MIDI_BLEMIDI_Parser.h"
niklasjakob 0:7de36d52cfef 48
niklasjakob 0:7de36d52cfef 49 #endif
niklasjakob 0:7de36d52cfef 50
niklasjakob 0:7de36d52cfef 51
niklasjakob 0:7de36d52cfef 52
niklasjakob 0:7de36d52cfef 53 #define TXRX_BUF_LEN 20
niklasjakob 0:7de36d52cfef 54
niklasjakob 0:7de36d52cfef 55 #define RX_BUF_LEN 256
niklasjakob 0:7de36d52cfef 56
niklasjakob 0:7de36d52cfef 57
niklasjakob 0:7de36d52cfef 58 #if LIGHT_SHOW==1
niklasjakob 0:7de36d52cfef 59 DigitalOut redled(P0_20); // sets the two LEDS on the MIDI Shield as outputs, these will be used as a visual feedback for debug
niklasjakob 0:7de36d52cfef 60 DigitalOut greenled(P0_19); //
niklasjakob 0:7de36d52cfef 61 #endif
niklasjakob 0:7de36d52cfef 62
niklasjakob 0:7de36d52cfef 63
niklasjakob 0:7de36d52cfef 64 /******************************************************************************************************************************
niklasjakob 0:7de36d52cfef 65 *INITIALIZE VARIABLES, BUFFERS and BLE-MIDI Service and Characteristic
niklasjakob 0:7de36d52cfef 66 ******************************************************************************************************************************/
niklasjakob 0:7de36d52cfef 67
niklasjakob 0:7de36d52cfef 68 Ticker sendBLEMIDI_Ticker ;
niklasjakob 0:7de36d52cfef 69 Ticker sendData_Ticker ;
niklasjakob 0:7de36d52cfef 70
niklasjakob 0:7de36d52cfef 71 Timer t; // timer used for BLE-MIDI timestamps
niklasjakob 0:7de36d52cfef 72
niklasjakob 0:7de36d52cfef 73 bool isConnected;
niklasjakob 0:7de36d52cfef 74
niklasjakob 0:7de36d52cfef 75
niklasjakob 0:7de36d52cfef 76 ////////////////////////////////////////////
niklasjakob 0:7de36d52cfef 77 bool sendBLEMIDI_flag = false ;
niklasjakob 0:7de36d52cfef 78
niklasjakob 0:7de36d52cfef 79 ////////////
niklasjakob 0:7de36d52cfef 80
niklasjakob 0:7de36d52cfef 81
niklasjakob 0:7de36d52cfef 82 BLEDevice ble; // BLE_API
niklasjakob 0:7de36d52cfef 83
niklasjakob 0:7de36d52cfef 84 static Gap::ConnectionParams_t connectionParams;
niklasjakob 0:7de36d52cfef 85
niklasjakob 0:7de36d52cfef 86
niklasjakob 0:7de36d52cfef 87 // MIDI BLE Service and Characteristic UUID ( see Apple BLE-MIDI Spec. and Midi manufacter Association BLE-MIDI Spec.)
niklasjakob 0:7de36d52cfef 88
niklasjakob 0:7de36d52cfef 89 static const uint8_t service_uuid[] = {0x03, 0xB8, 0x0E, 0x5A, 0xED, 0xE8, 0x4B, 0x33, 0xA7, 0x51, 0x6C, 0xE3, 0x4E, 0xC4, 0xC7, 0};
niklasjakob 0:7de36d52cfef 90 static const uint8_t characteristic_uuid[] = {0x77, 0x72, 0xE5, 0xDB, 0x38, 0x68, 0x41, 0x12, 0xA1, 0xA9, 0xF2, 0x66, 0x9D, 0x10, 0x6B, 0xF3};
niklasjakob 0:7de36d52cfef 91
niklasjakob 0:7de36d52cfef 92 static const uint8_t service_uuid_rev[] = {0, 0xC7, 0xC4, 0x4E, 0xE3, 0x6C, 0x51, 0xA7, 0x33, 0x4B, 0xE8, 0xED, 0x5A, 0x0E, 0xB8, 0x03};
niklasjakob 0:7de36d52cfef 93
niklasjakob 0:7de36d52cfef 94 uint8_t txPayload[TXRX_BUF_LEN] = {0,};
niklasjakob 0:7de36d52cfef 95
niklasjakob 0:7de36d52cfef 96
niklasjakob 0:7de36d52cfef 97 GattCharacteristic midiCharacteristic(characteristic_uuid, txPayload, 0, 20,GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE |
niklasjakob 0:7de36d52cfef 98 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE |
niklasjakob 0:7de36d52cfef 99 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY |
niklasjakob 0:7de36d52cfef 100 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ);
niklasjakob 0:7de36d52cfef 101
niklasjakob 0:7de36d52cfef 102 GattCharacteristic *midiChars[] = {&midiCharacteristic};
niklasjakob 0:7de36d52cfef 103 GattService BLEMIDIService(service_uuid, midiChars,sizeof(midiChars) / sizeof(GattCharacteristic *));
niklasjakob 0:7de36d52cfef 104
niklasjakob 0:7de36d52cfef 105
niklasjakob 0:7de36d52cfef 106
niklasjakob 0:7de36d52cfef 107 /*********************************************************************************************************************
niklasjakob 0:7de36d52cfef 108 MIDI to BLE-MIDI
niklasjakob 0:7de36d52cfef 109 *********************************************************************************************************************/
niklasjakob 0:7de36d52cfef 110
niklasjakob 0:7de36d52cfef 111
niklasjakob 0:7de36d52cfef 112 #if ONLY_BLEMIDI_to_MIDI==0
niklasjakob 0:7de36d52cfef 113
niklasjakob 0:7de36d52cfef 114
niklasjakob 0:7de36d52cfef 115 void sendBLEMIDI_Callback (void)
niklasjakob 0:7de36d52cfef 116 {
niklasjakob 0:7de36d52cfef 117
niklasjakob 0:7de36d52cfef 118 sendBLEMIDI_flag = true ;
niklasjakob 0:7de36d52cfef 119
niklasjakob 0:7de36d52cfef 120 /**** This callback is called within an ISR with frequency set by the sendBLEMIDI_Ticker, because it is called in an Interrupt context it is preferably
niklasjakob 0:7de36d52cfef 121 doing the MIDI to BLEMIDI task in the main, the callback only set a flag which would be checked in the main loop.
niklasjakob 0:7de36d52cfef 122 This is because all the BLEMIDI to MIDI conversion is already performed within Interrupt context. ( thus as a consequence BLEMIDI to MIDI has higher priority )
niklasjakob 0:7de36d52cfef 123 *****/
niklasjakob 0:7de36d52cfef 124 }
niklasjakob 0:7de36d52cfef 125
niklasjakob 0:7de36d52cfef 126
niklasjakob 0:7de36d52cfef 127
niklasjakob 0:7de36d52cfef 128 void sendBLEMIDI(void)
niklasjakob 0:7de36d52cfef 129 {
niklasjakob 0:7de36d52cfef 130
niklasjakob 0:7de36d52cfef 131
niklasjakob 0:7de36d52cfef 132 // MIDI::MIDI_to_BLEMIDI_Parser() parses incoming MIDI events from the UART (see MIDI_BLEMIDI_Parser.h)
niklasjakob 0:7de36d52cfef 133 if(isConnected == true && MIDI::MIDI_to_BLEMIDI_Parser()==true) {
niklasjakob 0:7de36d52cfef 134
niklasjakob 0:7de36d52cfef 135 // a valid MIDI message has been parsed from the UART buffer
niklasjakob 0:7de36d52cfef 136
niklasjakob 0:7de36d52cfef 137 #if LIGHT_SHOW==1
niklasjakob 0:7de36d52cfef 138 greenled = !(greenled);
niklasjakob 0:7de36d52cfef 139 #endif
niklasjakob 0:7de36d52cfef 140
niklasjakob 0:7de36d52cfef 141 uint8_t BLEmidi_out[SysExMaxSize] ;
niklasjakob 0:7de36d52cfef 142 uint8_t SysEx_Array_lenght ;
niklasjakob 0:7de36d52cfef 143
niklasjakob 0:7de36d52cfef 144 uint16_t ticks = t.read_us() & 0x1fff; // read timer for timestamps
niklasjakob 0:7de36d52cfef 145
niklasjakob 0:7de36d52cfef 146 if(MIDI::mMessage.sysexArray[0] == MIDI::SystemExclusive) { // message is SysEx
niklasjakob 0:7de36d52cfef 147
niklasjakob 0:7de36d52cfef 148
niklasjakob 0:7de36d52cfef 149 SysEx_Array_lenght = MIDI::mMessage.getSysExSize() ; // get SysEx message lenght
niklasjakob 0:7de36d52cfef 150
niklasjakob 0:7de36d52cfef 151 uint8_t position = 0; // position for SysexArray
niklasjakob 0:7de36d52cfef 152
niklasjakob 0:7de36d52cfef 153 // header
niklasjakob 0:7de36d52cfef 154
niklasjakob 0:7de36d52cfef 155 BLEmidi_out[position++] = 0x80 | ((ticks >> 7) & 0x3f); // header & timestampHigh
niklasjakob 0:7de36d52cfef 156 BLEmidi_out[position++] = 0x80 | (ticks & 0x7f); // timestampLow
niklasjakob 0:7de36d52cfef 157
niklasjakob 0:7de36d52cfef 158 for (int i = 0; i < SysEx_Array_lenght; i++) {
niklasjakob 0:7de36d52cfef 159 if (i == SysEx_Array_lenght - 1) {
niklasjakob 0:7de36d52cfef 160 // modify last byte
niklasjakob 0:7de36d52cfef 161 BLEmidi_out[position++] = 0x80 | (ticks & 0x7f);
niklasjakob 0:7de36d52cfef 162
niklasjakob 0:7de36d52cfef 163 if (position == 20) {
niklasjakob 0:7de36d52cfef 164
niklasjakob 0:7de36d52cfef 165
niklasjakob 0:7de36d52cfef 166 ble.updateCharacteristicValue(midiCharacteristic.getValueAttribute().getHandle(), BLEmidi_out, 20);
niklasjakob 0:7de36d52cfef 167
niklasjakob 0:7de36d52cfef 168 position = 0;
niklasjakob 0:7de36d52cfef 169 // header
niklasjakob 0:7de36d52cfef 170 BLEmidi_out[position++] = 0x80 | (ticks >> 7) & 0x3f;
niklasjakob 0:7de36d52cfef 171 }
niklasjakob 0:7de36d52cfef 172 }
niklasjakob 0:7de36d52cfef 173 BLEmidi_out[position++] = MIDI::mMessage.sysexArray[i];
niklasjakob 0:7de36d52cfef 174 if (position == 20) {
niklasjakob 0:7de36d52cfef 175 ble.updateCharacteristicValue(midiCharacteristic.getValueAttribute().getHandle(), BLEmidi_out, 20);
niklasjakob 0:7de36d52cfef 176
niklasjakob 0:7de36d52cfef 177 position = 0;
niklasjakob 0:7de36d52cfef 178 // header
niklasjakob 0:7de36d52cfef 179 BLEmidi_out[position++] = 0x80 | (ticks >> 7) & 0x3f;
niklasjakob 0:7de36d52cfef 180 }
niklasjakob 0:7de36d52cfef 181
niklasjakob 0:7de36d52cfef 182 ticks = t.read_us() & 0x1fff;
niklasjakob 0:7de36d52cfef 183 }
niklasjakob 0:7de36d52cfef 184
niklasjakob 0:7de36d52cfef 185 if (position > 0) {
niklasjakob 0:7de36d52cfef 186 // send remains
niklasjakob 0:7de36d52cfef 187 ble.updateCharacteristicValue(midiCharacteristic.getValueAttribute().getHandle(), BLEmidi_out, position);
niklasjakob 0:7de36d52cfef 188
niklasjakob 0:7de36d52cfef 189 }
niklasjakob 0:7de36d52cfef 190
niklasjakob 0:7de36d52cfef 191
niklasjakob 0:7de36d52cfef 192 MIDI::mMessage.sysexArray[0]= 0 ; // reset
niklasjakob 0:7de36d52cfef 193
niklasjakob 0:7de36d52cfef 194 }
niklasjakob 0:7de36d52cfef 195
niklasjakob 0:7de36d52cfef 196
niklasjakob 0:7de36d52cfef 197 // message is not SysEx
niklasjakob 0:7de36d52cfef 198
niklasjakob 0:7de36d52cfef 199
niklasjakob 0:7de36d52cfef 200 else {
niklasjakob 0:7de36d52cfef 201
niklasjakob 0:7de36d52cfef 202
niklasjakob 0:7de36d52cfef 203 if(MIDI::mMessage.data1 == 0 ) { // no data1 only status
niklasjakob 0:7de36d52cfef 204
niklasjakob 0:7de36d52cfef 205 BLEmidi_out[0] = 0x80 | ((ticks >> 7) & 0x3f);
niklasjakob 0:7de36d52cfef 206 BLEmidi_out[1] = 0x80 | (ticks & 0x7f);
niklasjakob 0:7de36d52cfef 207 BLEmidi_out[2] = MIDI::mMessage.channel+MIDI::mMessage.type;
niklasjakob 0:7de36d52cfef 208
niklasjakob 0:7de36d52cfef 209 ble.updateCharacteristicValue(midiCharacteristic.getValueAttribute().getHandle(), BLEmidi_out , 3);
niklasjakob 0:7de36d52cfef 210
niklasjakob 0:7de36d52cfef 211 }
niklasjakob 0:7de36d52cfef 212
niklasjakob 0:7de36d52cfef 213 if(MIDI::mMessage.data2 == 0 ) { // no data2
niklasjakob 0:7de36d52cfef 214
niklasjakob 0:7de36d52cfef 215 BLEmidi_out[0] = 0x80 | ((ticks >> 7) & 0x3f);
niklasjakob 0:7de36d52cfef 216 BLEmidi_out[1] = 0x80 | (ticks & 0x7f);
niklasjakob 0:7de36d52cfef 217 BLEmidi_out[2] = MIDI::mMessage.channel+MIDI::mMessage.type;
niklasjakob 0:7de36d52cfef 218 BLEmidi_out[3] = MIDI::mMessage.data1 ;
niklasjakob 0:7de36d52cfef 219
niklasjakob 0:7de36d52cfef 220 ble.updateCharacteristicValue(midiCharacteristic.getValueAttribute().getHandle(), BLEmidi_out , 4);
niklasjakob 0:7de36d52cfef 221
niklasjakob 0:7de36d52cfef 222 }
niklasjakob 0:7de36d52cfef 223
niklasjakob 0:7de36d52cfef 224 if(MIDI::mMessage.data2 != 0 ) {
niklasjakob 0:7de36d52cfef 225
niklasjakob 0:7de36d52cfef 226 BLEmidi_out[0] = 0x80 | ((ticks >> 7) & 0x3f);
niklasjakob 0:7de36d52cfef 227 BLEmidi_out[1] = 0x80 | (ticks & 0x7f);
niklasjakob 0:7de36d52cfef 228 BLEmidi_out[2] = MIDI::mMessage.channel+MIDI::mMessage.type;
niklasjakob 0:7de36d52cfef 229 BLEmidi_out[3] = MIDI::mMessage.data1 ;
niklasjakob 0:7de36d52cfef 230 BLEmidi_out[4] = MIDI::mMessage.data2 ;
niklasjakob 0:7de36d52cfef 231
niklasjakob 0:7de36d52cfef 232 ble.updateCharacteristicValue(midiCharacteristic.getValueAttribute().getHandle(), BLEmidi_out , 5);
niklasjakob 0:7de36d52cfef 233
niklasjakob 0:7de36d52cfef 234 }
niklasjakob 0:7de36d52cfef 235
niklasjakob 0:7de36d52cfef 236 }// end else
niklasjakob 0:7de36d52cfef 237
niklasjakob 0:7de36d52cfef 238 }// outer if
niklasjakob 0:7de36d52cfef 239
niklasjakob 0:7de36d52cfef 240 // invalid message or not connected
niklasjakob 0:7de36d52cfef 241
niklasjakob 0:7de36d52cfef 242 }
niklasjakob 0:7de36d52cfef 243
niklasjakob 0:7de36d52cfef 244 #endif
niklasjakob 0:7de36d52cfef 245
niklasjakob 0:7de36d52cfef 246
niklasjakob 0:7de36d52cfef 247 /******************************************************************************************************************************
niklasjakob 0:7de36d52cfef 248 * BLE CALLBACKS
niklasjakob 0:7de36d52cfef 249 ******************************************************************************************************************************/
niklasjakob 0:7de36d52cfef 250
niklasjakob 0:7de36d52cfef 251
niklasjakob 0:7de36d52cfef 252 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
niklasjakob 0:7de36d52cfef 253 {
niklasjakob 0:7de36d52cfef 254 //device disconnected
niklasjakob 0:7de36d52cfef 255
niklasjakob 0:7de36d52cfef 256 isConnected = false ;
niklasjakob 0:7de36d52cfef 257
niklasjakob 0:7de36d52cfef 258 #if ONLY_BLEMIDI_to_MIDI==0
niklasjakob 0:7de36d52cfef 259 sendBLEMIDI_Ticker.detach() ; // stop Ticker to save energy
niklasjakob 0:7de36d52cfef 260 #endif
niklasjakob 0:7de36d52cfef 261
niklasjakob 0:7de36d52cfef 262 ble.startAdvertising(); // start advertising
niklasjakob 0:7de36d52cfef 263 }
niklasjakob 0:7de36d52cfef 264
niklasjakob 0:7de36d52cfef 265
niklasjakob 0:7de36d52cfef 266 void connectionCallback(const Gap::ConnectionCallbackParams_t* params) {
niklasjakob 0:7de36d52cfef 267
niklasjakob 0:7de36d52cfef 268
niklasjakob 0:7de36d52cfef 269 isConnected=true ;
niklasjakob 0:7de36d52cfef 270
niklasjakob 0:7de36d52cfef 271 // try update conn.parameters
niklasjakob 0:7de36d52cfef 272
niklasjakob 0:7de36d52cfef 273 connectionParams.minConnectionInterval = Config::minConnectionInterval;
niklasjakob 0:7de36d52cfef 274 connectionParams.maxConnectionInterval = Config::maxConnectionInterval;
niklasjakob 0:7de36d52cfef 275 connectionParams.slaveLatency = Config::slaveLatency;
niklasjakob 0:7de36d52cfef 276 connectionParams.connectionSupervisionTimeout = Config::supervisionTimeout;
niklasjakob 0:7de36d52cfef 277
niklasjakob 0:7de36d52cfef 278 ble.updateConnectionParams(params->handle ,&connectionParams);
niklasjakob 0:7de36d52cfef 279
niklasjakob 0:7de36d52cfef 280
niklasjakob 0:7de36d52cfef 281 //start timers here
niklasjakob 0:7de36d52cfef 282 #if ONLY_BLEMIDI_to_MIDI==0
niklasjakob 0:7de36d52cfef 283 sendBLEMIDI_Ticker.attach( sendBLEMIDI_Callback, SENDBLEMIDI_INTERVAL); // every SENDBLEMIDI_INTERVAL seconds calls sendBLEMIDI_Callback (ISR)
niklasjakob 0:7de36d52cfef 284
niklasjakob 0:7de36d52cfef 285 t.start(); // start the timer used for BLEMIDI timestamps
niklasjakob 0:7de36d52cfef 286
niklasjakob 0:7de36d52cfef 287 #endif
niklasjakob 0:7de36d52cfef 288
niklasjakob 0:7de36d52cfef 289 }
niklasjakob 0:7de36d52cfef 290
niklasjakob 0:7de36d52cfef 291
niklasjakob 0:7de36d52cfef 292 /****************************************************************************************************************************
niklasjakob 0:7de36d52cfef 293 BLE-MIDI to MIDI
niklasjakob 0:7de36d52cfef 294 ****************************************************************************************************************************/
niklasjakob 0:7de36d52cfef 295
niklasjakob 0:7de36d52cfef 296
niklasjakob 0:7de36d52cfef 297 #if ONLY_MIDI_to_BLEMIDI==0
niklasjakob 0:7de36d52cfef 298
niklasjakob 0:7de36d52cfef 299 void parseIncoming(uint8_t *buffer, uint16_t bytesRead) { // parse BLE-MIDI Events that have been written on the MIDI Characteristic
niklasjakob 0:7de36d52cfef 300 for (int i = 1; i < bytesRead; i++)
niklasjakob 0:7de36d52cfef 301 {
niklasjakob 0:7de36d52cfef 302 parseMidiEvent(buffer[0], buffer[i]); // parse and send through UART the MIDI Events received through BLE (see BLE_MIDI_Parser.h)
niklasjakob 0:7de36d52cfef 303 }
niklasjakob 0:7de36d52cfef 304 }
niklasjakob 0:7de36d52cfef 305
niklasjakob 0:7de36d52cfef 306
niklasjakob 0:7de36d52cfef 307
niklasjakob 0:7de36d52cfef 308 void onDataWritten(const GattWriteCallbackParams *Handler) // this functions is called within an ISR every time data has been written on nRF51822 GATT Server MIDI Characteristic
niklasjakob 0:7de36d52cfef 309 {
niklasjakob 0:7de36d52cfef 310
niklasjakob 0:7de36d52cfef 311 #if LIGHT_SHOW==1
niklasjakob 0:7de36d52cfef 312 redled = !(redled) ;
niklasjakob 0:7de36d52cfef 313 #endif
niklasjakob 0:7de36d52cfef 314
niklasjakob 0:7de36d52cfef 315 uint8_t buf[TXRX_BUF_LEN];
niklasjakob 0:7de36d52cfef 316 uint16_t bytesRead;
niklasjakob 0:7de36d52cfef 317 if (Handler->handle == midiCharacteristic.getValueAttribute().getHandle()) {
niklasjakob 0:7de36d52cfef 318 ble.readCharacteristicValue(midiCharacteristic.getValueAttribute().getHandle(),
niklasjakob 0:7de36d52cfef 319 buf, &bytesRead);
niklasjakob 0:7de36d52cfef 320 //parseIncoming(buf, bytesRead);
niklasjakob 0:7de36d52cfef 321
niklasjakob 0:7de36d52cfef 322 for (int i = 0; i < bytesRead; i++){
niklasjakob 0:7de36d52cfef 323 UART.putc(buf[i]);
niklasjakob 0:7de36d52cfef 324
niklasjakob 0:7de36d52cfef 325 }
niklasjakob 0:7de36d52cfef 326
niklasjakob 0:7de36d52cfef 327 }
niklasjakob 0:7de36d52cfef 328
niklasjakob 0:7de36d52cfef 329 }
niklasjakob 0:7de36d52cfef 330
niklasjakob 0:7de36d52cfef 331 #endif
niklasjakob 0:7de36d52cfef 332
niklasjakob 0:7de36d52cfef 333
niklasjakob 0:7de36d52cfef 334 /**************************************
niklasjakob 0:7de36d52cfef 335 MAIN
niklasjakob 0:7de36d52cfef 336 ***************************************/
niklasjakob 0:7de36d52cfef 337
niklasjakob 0:7de36d52cfef 338 int main(void)
niklasjakob 0:7de36d52cfef 339 {
niklasjakob 0:7de36d52cfef 340
niklasjakob 0:7de36d52cfef 341
niklasjakob 0:7de36d52cfef 342 #if LIGHT_SHOW==1
niklasjakob 0:7de36d52cfef 343 redled = 1;
niklasjakob 0:7de36d52cfef 344 greenled = 1;
niklasjakob 0:7de36d52cfef 345 #endif
niklasjakob 0:7de36d52cfef 346
niklasjakob 0:7de36d52cfef 347
niklasjakob 0:7de36d52cfef 348
niklasjakob 0:7de36d52cfef 349 UART.baud(31250) ; // set UART baud rate to 31250 (MIDI standard)
niklasjakob 0:7de36d52cfef 350
niklasjakob 0:7de36d52cfef 351 ble.init();
niklasjakob 0:7de36d52cfef 352 ble.onDisconnection(disconnectionCallback);
niklasjakob 0:7de36d52cfef 353 ble.onConnection(connectionCallback) ;
niklasjakob 0:7de36d52cfef 354
niklasjakob 0:7de36d52cfef 355 #if ONLY_MIDI_to_BLEMIDI==0
niklasjakob 0:7de36d52cfef 356 ble.onDataWritten(onDataWritten);
niklasjakob 0:7de36d52cfef 357 #endif
niklasjakob 0:7de36d52cfef 358
niklasjakob 0:7de36d52cfef 359 //conn. parameters ( rejected on iOS/OSX see Apple BLE peripheral design guidelines but can work on Android )
niklasjakob 0:7de36d52cfef 360
niklasjakob 0:7de36d52cfef 361 connectionParams.minConnectionInterval = Config::minConnectionInterval;
niklasjakob 0:7de36d52cfef 362 connectionParams.maxConnectionInterval = Config::maxConnectionInterval;
niklasjakob 0:7de36d52cfef 363 connectionParams.slaveLatency = Config::slaveLatency;
niklasjakob 0:7de36d52cfef 364 connectionParams.connectionSupervisionTimeout = Config::supervisionTimeout;
niklasjakob 0:7de36d52cfef 365 ble.setPreferredConnectionParams(&connectionParams);
niklasjakob 0:7de36d52cfef 366 ble.getPreferredConnectionParams(&connectionParams);
niklasjakob 0:7de36d52cfef 367
niklasjakob 0:7de36d52cfef 368
niklasjakob 0:7de36d52cfef 369 /* setup advertising */
niklasjakob 0:7de36d52cfef 370 ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
niklasjakob 0:7de36d52cfef 371 ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
niklasjakob 0:7de36d52cfef 372 (const uint8_t *)"LLFX", sizeof("LLFX") - 1);
niklasjakob 0:7de36d52cfef 373 ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
niklasjakob 0:7de36d52cfef 374 (const uint8_t *)service_uuid_rev, sizeof(service_uuid_rev));
niklasjakob 0:7de36d52cfef 375
niklasjakob 0:7de36d52cfef 376 ble.accumulateScanResponse(GapAdvertisingData::SHORTENED_LOCAL_NAME,
niklasjakob 0:7de36d52cfef 377 (const uint8_t *)"LLFX", sizeof("LLFX") - 1);
niklasjakob 0:7de36d52cfef 378 ble.accumulateScanResponse(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,(const uint8_t *)service_uuid_rev, sizeof(service_uuid_rev));
niklasjakob 0:7de36d52cfef 379 ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
niklasjakob 0:7de36d52cfef 380
niklasjakob 0:7de36d52cfef 381 /* 100ms; in multiples of 0.625ms. */
niklasjakob 0:7de36d52cfef 382 ble.setAdvertisingInterval(160);
niklasjakob 0:7de36d52cfef 383
niklasjakob 0:7de36d52cfef 384 // set adv_timeout, in seconds
niklasjakob 0:7de36d52cfef 385 ble.setAdvertisingTimeout(0);
niklasjakob 0:7de36d52cfef 386 ble.addService(BLEMIDIService);
niklasjakob 0:7de36d52cfef 387
niklasjakob 0:7de36d52cfef 388 //Set Device Name
niklasjakob 0:7de36d52cfef 389 ble.setDeviceName((const uint8_t *)"LLFX");
niklasjakob 0:7de36d52cfef 390
niklasjakob 0:7de36d52cfef 391 ble.startAdvertising();
niklasjakob 0:7de36d52cfef 392
niklasjakob 0:7de36d52cfef 393
niklasjakob 0:7de36d52cfef 394 while(1) { //main loop
niklasjakob 0:7de36d52cfef 395
niklasjakob 0:7de36d52cfef 396 #if ONLY_BLEMIDI_to_MIDI==0
niklasjakob 0:7de36d52cfef 397 if(sendBLEMIDI_flag == true ) { // check if the flag is set
niklasjakob 0:7de36d52cfef 398
niklasjakob 0:7de36d52cfef 399 sendBLEMIDI_flag=false ;
niklasjakob 0:7de36d52cfef 400 sendBLEMIDI() ; // parse MIDI Events from UART and send them over BLE
niklasjakob 0:7de36d52cfef 401
niklasjakob 0:7de36d52cfef 402 }
niklasjakob 0:7de36d52cfef 403 #endif
niklasjakob 0:7de36d52cfef 404
niklasjakob 0:7de36d52cfef 405 ble.waitForEvent(); // sleep
niklasjakob 0:7de36d52cfef 406
niklasjakob 0:7de36d52cfef 407 } // end main loop
niklasjakob 0:7de36d52cfef 408
niklasjakob 0:7de36d52cfef 409 } // end main