This program enables a RedBearlab nRF51822 to be used as a "bridge device" with full bi-directional communication between MIDI through standard MIDI cables and BLE-MIDI. MIDI cables are connected to the UART. This allows for example to send MIDI data to synthesizers directly from a computer or a tablet via BLE-MIDI and vice-versa, "wires-free" . The Midi Manufacturers Association BLE-MIDI Specification is used. This project is inspired by Matthias Frick's "blidino" project which implements a USB-MIDI to BLE-MIDI bridge with the nRF51822 and is available at https://github.com/sieren/blidino. I owe to him all the BLE-MIDI to MIDI parsing part.

Dependencies:   BLE_API BufferedSerial mbed nRF51822

/media/uploads/popcornell/wp_20160713_22_30_15_rich.jpg

Video

Committer:
popcornell
Date:
Tue Aug 09 12:57:23 2016 +0000
Revision:
0:244f1d0a3810
first

Who changed what in which revision?

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