├── debug-utils
└── MIDI LE for OSX
│ ├── MIDI LE for OSX.app
│ └── Contents
│ │ ├── PkgInfo
│ │ ├── MacOS
│ │ └── MIDI LE for OSX
│ │ ├── Resources
│ │ └── Base.lproj
│ │ │ └── MainMenu.nib
│ │ ├── Info.plist
│ │ └── _CodeSignature
│ │ └── CodeResources
│ ├── MIDI LE for OSX Binary.zip
│ ├── MIDI LE for OSX
│ ├── PGMidi
│ │ ├── worra.mp3
│ │ ├── PGMidiAllSources.h
│ │ ├── PGMidiFind.h
│ │ ├── PGArc.h
│ │ ├── PGMidiAllSources.mm
│ │ ├── iOSVersionDetection.h
│ │ ├── PGMidiFind.mm
│ │ └── PGMidi.h
│ ├── main.m
│ ├── NSData+hexConv.h
│ ├── Images.xcassets
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── Info.plist
│ ├── NSData+hexConv.m
│ └── AppDelegate.h
│ ├── MIDI LE for OSX.xcodeproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcuserdata
│ │ │ └── sierenmusic.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcuserdata
│ │ └── sierenmusic.xcuserdatad
│ │ ├── xcschemes
│ │ ├── xcschememanagement.plist
│ │ └── MIDI LE for OSX.xcscheme
│ │ └── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
│ ├── README.md
│ └── MIDI LE for OSXTests
│ ├── Info.plist
│ └── MIDI_LE_for_OSXTests.m
├── run_unit_tests.sh
├── .gitmodules
├── .travis.yml
├── LICENSE
├── Legacy Projects
└── nRF8001-BLE-Proto
│ ├── RBL_nRF8001
│ ├── examples
│ │ ├── BLE_RGB
│ │ │ ├── BLE_RGB.ino
│ │ │ └── Adafruit_NeoPixel.h
│ │ ├── SimpleChat
│ │ │ └── SimpleChat.ino
│ │ ├── HelloWorld
│ │ │ └── HelloWorld.ino
│ │ ├── SimpleControls
│ │ │ └── SimpleControls.ino
│ │ ├── BLEFirmataSketch
│ │ │ ├── BLEFirmata.h
│ │ │ ├── BLEFirmata.cpp
│ │ │ └── Boards.h
│ │ └── BLEControllerSketch
│ │ │ ├── BLEControllerSketch.ino
│ │ │ └── Boards.h
│ ├── RBL_nRF8001.h
│ ├── RBL_services_OLD.h
│ └── RBL_services.h
│ ├── README.md
│ ├── RBL_services.h
│ └── nRF8001-BLE-Proto.ino
├── nRF51822-BLEMIDI
├── README.md
├── projectconfig.h
├── nRF51822-BLEMIDI.ino
└── BLEParser.h
├── CMakeLists.txt
├── README.md
└── unit_tests
└── tst_BLEParser.cpp
/debug-utils/MIDI LE for OSX/MIDI LE for OSX.app/Contents/PkgInfo:
--------------------------------------------------------------------------------
1 | APPL????
--------------------------------------------------------------------------------
/run_unit_tests.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | mkdir build
4 | cd build
5 | cmake ./../
6 | make
7 | ./bletest
8 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "nRF51822-BLEMIDI/googletest"]
2 | path = nRF51822-BLEMIDI/googletest
3 | url = https://github.com/google/googletest.git
4 |
--------------------------------------------------------------------------------
/debug-utils/MIDI LE for OSX/MIDI LE for OSX Binary.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sieren/blidino/HEAD/debug-utils/MIDI LE for OSX/MIDI LE for OSX Binary.zip
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: cpp
2 | os:
3 | - osx
4 | env:
5 | - CONFIG=Release
6 | - CONFIG=Debug
7 | install:
8 | script:
9 | ./run_unit_tests.sh
10 |
--------------------------------------------------------------------------------
/debug-utils/MIDI LE for OSX/MIDI LE for OSX/PGMidi/worra.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sieren/blidino/HEAD/debug-utils/MIDI LE for OSX/MIDI LE for OSX/PGMidi/worra.mp3
--------------------------------------------------------------------------------
/debug-utils/MIDI LE for OSX/MIDI LE for OSX.app/Contents/MacOS/MIDI LE for OSX:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sieren/blidino/HEAD/debug-utils/MIDI LE for OSX/MIDI LE for OSX.app/Contents/MacOS/MIDI LE for OSX
--------------------------------------------------------------------------------
/debug-utils/MIDI LE for OSX/MIDI LE for OSX.app/Contents/Resources/Base.lproj/MainMenu.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sieren/blidino/HEAD/debug-utils/MIDI LE for OSX/MIDI LE for OSX.app/Contents/Resources/Base.lproj/MainMenu.nib
--------------------------------------------------------------------------------
/debug-utils/MIDI LE for OSX/MIDI LE for OSX.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/debug-utils/MIDI LE for OSX/MIDI LE for OSX.xcodeproj/project.xcworkspace/xcuserdata/sierenmusic.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sieren/blidino/HEAD/debug-utils/MIDI LE for OSX/MIDI LE for OSX.xcodeproj/project.xcworkspace/xcuserdata/sierenmusic.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/debug-utils/MIDI LE for OSX/MIDI LE for OSX/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // MIDI LE for OSX
4 | //
5 | // Created by Matthias Frick on 08.10.2014.
6 | // Copyright (c) 2014 Matthias Frick. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | int main(int argc, const char * argv[]) {
12 | return NSApplicationMain(argc, argv);
13 | }
14 |
--------------------------------------------------------------------------------
/debug-utils/MIDI LE for OSX/MIDI LE for OSX/NSData+hexConv.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSData+hexConv.h
3 | // MIDI LE for OSX
4 | //
5 | // Created by Matthias Frick on 08.10.2014.
6 | // Copyright (c) 2014 Matthias Frick. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface NSData (hexConv)
12 | -(NSString*)hexRepresentationWithSpaces_AS:(BOOL)spaces;
13 | @end
14 |
--------------------------------------------------------------------------------
/debug-utils/MIDI LE for OSX/README.md:
--------------------------------------------------------------------------------
1 | MIDI LE FOR OSX
2 | =======
3 |
4 | Based on Apple's Sample Code fora Bluetooth LE Heart Rate Monitor this utility connects to devices offering the MIDI-BLE UDID/Characeteristic introduced in OSX/iOS and prints out the received "MIDI"-Packets in HEX. I am using this tool to monitor and debug incoming raw packets. It's just a quick hack at this point and at some point might be extended to route incoming MIDI Data to the IAC Bus for backwards compatibility to OSX 10.7+.
5 |
6 |
--------------------------------------------------------------------------------
/debug-utils/MIDI LE for OSX/MIDI LE for OSX/PGMidi/PGMidiAllSources.h:
--------------------------------------------------------------------------------
1 | //
2 | // PGMidiAllSources.h
3 | // PGMidi
4 | //
5 |
6 | #import
7 |
8 | @class PGMidi;
9 | @protocol PGMidiSourceDelegate;
10 |
11 | @interface PGMidiAllSources : NSObject
12 | {
13 | PGMidi *midi;
14 | id delegate;
15 | }
16 |
17 | #if ! __has_feature(objc_arc)
18 |
19 | @property (nonatomic,assign) PGMidi *midi;
20 | @property (nonatomic,assign) id delegate;
21 |
22 | #else
23 |
24 | @property (nonatomic,strong) PGMidi *midi;
25 | @property (nonatomic,strong) id delegate;
26 |
27 | #endif
28 |
29 | @end
30 |
--------------------------------------------------------------------------------
/debug-utils/MIDI LE for OSX/MIDI LE for OSX/PGMidi/PGMidiFind.h:
--------------------------------------------------------------------------------
1 | //
2 | // PGMidiFind.h
3 | // PGMidi
4 | //
5 |
6 | #import "PGMidi.h"
7 |
8 | @interface PGMidi (FindingConnections)
9 |
10 | - (PGMidiSource*) findSourceCalled:(NSString*)name;
11 |
12 | - (PGMidiDestination*) findDestinationCalled:(NSString*)name;
13 |
14 | - (void) findMatchingSource:(PGMidiSource**)source
15 | andDestination:(PGMidiDestination**)destination;
16 |
17 | - (void) findMatchingSource:(PGMidiSource**)source
18 | andDestination:(PGMidiDestination**)destination
19 | avoidNames:(NSArray*)namesToAvoid;
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/debug-utils/MIDI LE for OSX/MIDI LE for OSX.xcodeproj/xcuserdata/sierenmusic.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | MIDI LE for OSX.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 693626B519E5AF620071E21C
16 |
17 | primary
18 |
19 |
20 | 693626C819E5AF620071E21C
21 |
22 | primary
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/debug-utils/MIDI LE for OSX/MIDI LE for OSXTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | com.matt.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/debug-utils/MIDI LE for OSX/MIDI LE for OSXTests/MIDI_LE_for_OSXTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // MIDI_LE_for_OSXTests.m
3 | // MIDI LE for OSXTests
4 | //
5 | // Created by Matthias Frick on 08.10.2014.
6 | // Copyright (c) 2014 Matthias Frick. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface MIDI_LE_for_OSXTests : XCTestCase
13 |
14 | @end
15 |
16 | @implementation MIDI_LE_for_OSXTests
17 |
18 | - (void)setUp {
19 | [super setUp];
20 | // Put setup code here. This method is called before the invocation of each test method in the class.
21 | }
22 |
23 | - (void)tearDown {
24 | // Put teardown code here. This method is called after the invocation of each test method in the class.
25 | [super tearDown];
26 | }
27 |
28 | - (void)testExample {
29 | // This is an example of a functional test case.
30 | XCTAssert(YES, @"Pass");
31 | }
32 |
33 | - (void)testPerformanceExample {
34 | // This is an example of a performance test case.
35 | [self measureBlock:^{
36 | // Put the code you want to measure the time of here.
37 | }];
38 | }
39 |
40 | @end
41 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Matt Sieren
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/debug-utils/MIDI LE for OSX/MIDI LE for OSX/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "mac",
5 | "size" : "16x16",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "mac",
10 | "size" : "16x16",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "mac",
15 | "size" : "32x32",
16 | "scale" : "1x"
17 | },
18 | {
19 | "idiom" : "mac",
20 | "size" : "32x32",
21 | "scale" : "2x"
22 | },
23 | {
24 | "idiom" : "mac",
25 | "size" : "128x128",
26 | "scale" : "1x"
27 | },
28 | {
29 | "idiom" : "mac",
30 | "size" : "128x128",
31 | "scale" : "2x"
32 | },
33 | {
34 | "idiom" : "mac",
35 | "size" : "256x256",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "mac",
40 | "size" : "256x256",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "mac",
45 | "size" : "512x512",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "mac",
50 | "size" : "512x512",
51 | "scale" : "2x"
52 | }
53 | ],
54 | "info" : {
55 | "version" : 1,
56 | "author" : "xcode"
57 | }
58 | }
--------------------------------------------------------------------------------
/debug-utils/MIDI LE for OSX/MIDI LE for OSX/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIconFile
10 |
11 | CFBundleIdentifier
12 | com.matt.$(PRODUCT_NAME:rfc1034identifier)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1
25 | LSMinimumSystemVersion
26 | $(MACOSX_DEPLOYMENT_TARGET)
27 | NSHumanReadableCopyright
28 | Copyright © 2014 Matthias Frick. All rights reserved.
29 | NSMainNibFile
30 | MainMenu
31 | NSPrincipalClass
32 | NSApplication
33 |
34 |
35 |
--------------------------------------------------------------------------------
/Legacy Projects/nRF8001-BLE-Proto/RBL_nRF8001/examples/BLE_RGB/BLE_RGB.ino:
--------------------------------------------------------------------------------
1 | #include "Adafruit_NeoPixel.h"
2 | #include
3 | #include
4 | #include
5 |
6 | // Parameter 1 = number of pixels in strip
7 | // Parameter 2 = pin number (most are valid)
8 | // Parameter 3 = pixel type flags, add together as needed:
9 | // NEO_RGB Pixels are wired for RGB bitstream
10 | // NEO_GRB Pixels are wired for GRB bitstream
11 | // NEO_KHZ400 400 KHz bitstream (e.g. FLORA pixels)
12 | // NEO_KHZ800 800 KHz bitstream (e.g. High Density LED strip)
13 | Adafruit_NeoPixel strip = Adafruit_NeoPixel(1, 7, NEO_GRB + NEO_KHZ800);
14 |
15 | int R = 0;
16 | int G = 0;
17 | int B = 0;
18 |
19 | void setup()
20 | {
21 | strip.begin();
22 | strip.show(); // Initialize all pixels to 'off'
23 | ble_begin();
24 | }
25 |
26 | void loop()
27 | {
28 | if(3 == ble_available())
29 | {
30 | R = ble_read();
31 | G = ble_read();
32 | B = ble_read();
33 | colorWipe( strip.Color(R, G, B) );
34 | }
35 | ble_do_events();
36 | }
37 |
38 | // Fill the dots one after the other with a color
39 | void colorWipe(uint32_t c)
40 | {
41 | for(uint16_t i=0; i= 3
20 | #define PGMIDI_ARC 1
21 | #else
22 | #define PGMIDI_ARC 0
23 | #endif
24 |
25 | //==============================================================================
26 | // arc_cast
27 |
28 | #ifdef __cplusplus
29 |
30 | #if PGMIDI_ARC
31 |
32 | template
33 | inline
34 | OBJC_TYPE *arc_cast(SOURCE_TYPE *source)
35 | {
36 | return (__bridge OBJC_TYPE*)source;
37 | }
38 |
39 | #define PG_RELEASE(a) a = nil;
40 |
41 | #else
42 |
43 | template
44 | inline
45 | OBJC_TYPE *arc_cast(SOURCE_TYPE *source)
46 | {
47 | return (OBJC_TYPE*)source;
48 | }
49 |
50 | #define PG_RELEASE(a) [a release]; a = nil;
51 |
52 | #endif
53 |
54 | #endif
55 |
--------------------------------------------------------------------------------
/debug-utils/MIDI LE for OSX/MIDI LE for OSX/PGMidi/PGMidiAllSources.mm:
--------------------------------------------------------------------------------
1 | //
2 | // PGMidiAllSources.mm
3 | // PGMidi
4 | //
5 |
6 | #import "PGMidiAllSources.h"
7 |
8 | #import "PGMidi.h"
9 | #import "PGArc.h"
10 |
11 | @interface PGMidiAllSources ()
12 | @end
13 |
14 | @implementation PGMidiAllSources
15 |
16 | - (void) dealloc
17 | {
18 | self.midi = nil;
19 | #if ! PGMIDI_ARC
20 | [super dealloc];
21 | #endif
22 | }
23 |
24 | @synthesize midi, delegate;
25 |
26 | - (void) setMidi:(PGMidi *)newMidi
27 | {
28 | midi.delegate = nil;
29 | for (PGMidiSource *source in midi.sources) [source removeDelegate:self];
30 |
31 | midi = newMidi;
32 |
33 | midi.delegate = self;
34 | for (PGMidiSource *source in midi.sources) [source addDelegate:self];
35 | }
36 |
37 | #pragma mark PGMidiDelegate
38 |
39 | - (void) midi:(PGMidi*)midi sourceAdded:(PGMidiSource *)source
40 | {
41 | [source addDelegate:self];
42 | }
43 |
44 | - (void) midi:(PGMidi*)midi sourceRemoved:(PGMidiSource *)source {}
45 | - (void) midi:(PGMidi*)midi destinationAdded:(PGMidiDestination *)destination {}
46 | - (void) midi:(PGMidi*)midi destinationRemoved:(PGMidiDestination *)destination {}
47 |
48 | #pragma mark PGMidiSourceDelegate
49 |
50 | - (void) midiSource:(PGMidiSource*)input midiReceived:(const MIDIPacketList *)packetList
51 | {
52 | [delegate midiSource:input midiReceived:packetList];
53 | }
54 |
55 | @end
56 |
--------------------------------------------------------------------------------
/debug-utils/MIDI LE for OSX/MIDI LE for OSX/PGMidi/iOSVersionDetection.h:
--------------------------------------------------------------------------------
1 | /*
2 | * iOSVersionDetection.h
3 | * PGMidi
4 | *
5 | */
6 |
7 | // Adapted from http://cocoawithlove.com/2010/07/tips-tricks-for-conditional-ios3-ios32.html
8 |
9 | #ifndef kCFCoreFoundationVersionNumber_iPhoneOS_4_0
10 | #define kCFCoreFoundationVersionNumber_iPhoneOS_4_0 550.32
11 | #endif
12 |
13 | #ifndef kCFCoreFoundationVersionNumber_iPhoneOS_4_1
14 | #define kCFCoreFoundationVersionNumber_iPhoneOS_4_1 550.38
15 | #endif
16 |
17 | #ifndef kCFCoreFoundationVersionNumber_iPhoneOS_4_2
18 | // NOTE: THIS IS NOT THE FINAL NUMBER
19 | // 4.2 is not out of beta yet, so took the beta 1 build number
20 | #define kCFCoreFoundationVersionNumber_iPhoneOS_4_2 550.47
21 | #endif
22 |
23 | #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 40000
24 | #define IF_IOS4_OR_GREATER(...) \
25 | if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iPhoneOS_4_0) \
26 | { \
27 | __VA_ARGS__ \
28 | }
29 | #else
30 | #define IF_IOS4_OR_GREATER(...) \
31 | if (false) \
32 | { \
33 | }
34 | #endif
35 |
36 | #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 40200
37 | #define IF_IOS4_2_OR_GREATER(...) \
38 | if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iPhoneOS_4_2) \
39 | { \
40 | __VA_ARGS__ \
41 | }
42 | #else
43 | #define IF_IOS4_2_OR_GREATER(...) \
44 | if (false) \
45 | { \
46 | }
47 | #endif
48 |
49 | #define IF_IOS_HAS_COREMIDI(...) IF_IOS4_2_OR_GREATER(__VA_ARGS__)
50 |
--------------------------------------------------------------------------------
/debug-utils/MIDI LE for OSX/MIDI LE for OSX/NSData+hexConv.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSData+hexConv.m
3 | // MIDI LE for OSX
4 | //
5 | // Created by Matthias Frick on 08.10.2014.
6 | // Copyright (c) 2014 Matthias Frick. All rights reserved.
7 | //
8 |
9 | #import "NSData+hexConv.h"
10 |
11 | @implementation NSData (hexConv)
12 |
13 | -(NSString*)hexRepresentationWithSpaces_AS:(BOOL)spaces
14 | {
15 | const unsigned char* bytes = (const unsigned char*)[self bytes];
16 | NSUInteger nbBytes = [self length];
17 | //If spaces is true, insert a space every this many input bytes (twice this many output characters).
18 | static const NSUInteger spaceEveryThisManyBytes = 4UL;
19 | //If spaces is true, insert a line-break instead of a space every this many spaces.
20 | static const NSUInteger lineBreakEveryThisManySpaces = 4UL;
21 | const NSUInteger lineBreakEveryThisManyBytes = spaceEveryThisManyBytes * lineBreakEveryThisManySpaces;
22 | NSUInteger strLen = 2*nbBytes + (spaces ? nbBytes/spaceEveryThisManyBytes : 0);
23 |
24 | NSMutableString* hex = [[NSMutableString alloc] initWithCapacity:strLen];
25 | for(NSUInteger i=0; i Show Package Contents and then navigate to Resources/Java).
20 | 3. Download and import the [USB Host Shield 2.0 Library](https://github.com/felis/USB_Host_Shield_2.0) and the [USBH_MIDI Library](https://github.com/YuuichiAkagawa/USBH_MIDI) into Arduino.
21 | 4. Compile and upload the sketch.
22 |
23 | Known Issues
24 | ============
25 |
26 | Please check the [README within the root directory](https://github.com/sieren/blidino) for known issues.
27 |
28 |
--------------------------------------------------------------------------------
/debug-utils/MIDI LE for OSX/MIDI LE for OSX.app/Contents/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BuildMachineOSBuild
6 | 14A386a
7 | CFBundleDevelopmentRegion
8 | en
9 | CFBundleExecutable
10 | MIDI LE for OSX
11 | CFBundleIdentifier
12 | com.matt.MIDI-LE-for-OSX
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | MIDI LE for OSX
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1
25 | DTCompiler
26 | com.apple.compilers.llvm.clang.1_0
27 | DTPlatformBuild
28 | 6A317
29 | DTPlatformVersion
30 | GM
31 | DTSDKBuild
32 | 13F26
33 | DTSDKName
34 | macosx10.9
35 | DTXcode
36 | 0600
37 | DTXcodeBuild
38 | 6A317
39 | LSMinimumSystemVersion
40 | 10.10
41 | NSHumanReadableCopyright
42 | Copyright © 2014 Matthias Frick. All rights reserved.
43 | NSMainNibFile
44 | MainMenu
45 | NSPrincipalClass
46 | NSApplication
47 |
48 |
49 |
--------------------------------------------------------------------------------
/Legacy Projects/nRF8001-BLE-Proto/README.md:
--------------------------------------------------------------------------------
1 | blidino (nRF51288)
2 | ==================
3 |
4 | This project was the first prototype in reverse-engineering MIDI over BLE.
5 | Unfortunately the nRF8001 is too slow for extensive tasks like turning knobs (capped at 0.6-0.9kb/s)
6 | but it will work fine for playing keys.
7 |
8 | Hardware
9 | ========
10 | 1. [USB Host Shield by Sparkfun](https://www.sparkfun.com/products/9947)
11 |
12 | 2. [RedBearLab Blend Micro](http://redbearlab.com/blendmicro/)
13 |
14 |
15 | Installation
16 | ============
17 | 1. Set up the board as instructed on the [RedBearLab Blend Micro](http://redbearlab.com/blendmicro/) page.
18 | 2. Replace the ***RBL_services.h, RBL_nRF8001.cpp and RBL_nRF8001.h*** in the */libraries/RBL_nRF8001* subfolder of your Arduino workspace.
19 | 3. Download and import the [USB Host Shield 2.0 Library](https://github.com/felis/USB_Host_Shield_2.0) and the [USBH_MIDI Library](https://github.com/YuuichiAkagawa/USBH_MIDI) into Arduino. You might need to check the pin assignments for SS,INT,MISO,MOSI and CLK within *USBCore.h* and *usbhost.h in the USB Host Shield Library.
20 | 4. Compile and upload the sketch to the device.
21 |
22 | Known Issues
23 | ============
24 |
25 | • Slow MIDI Output
26 |
27 | The nRF8001 chip is designed for low-performance bluetooth applications, rendering it suitable for low
28 | performance MIDI applications only. Exceeding the bandwidth will result in dropped packets or stuck notes.
29 |
30 |
31 |
32 | The [Wiki](https://github.com/sieren/blidino/wiki) will be updated frequently with information about the ongoing development and discoveries about the BLE-MIDI Specificiation.
33 |
34 | Click the link to see a demo.
35 |
36 |
--------------------------------------------------------------------------------
/debug-utils/MIDI LE for OSX/MIDI LE for OSX/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // MIDI LE for OSX
4 | //
5 | // Created by Matthias Frick on 08.10.2014.
6 | // Copyright (c) 2014 Matthias Frick. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 | #import "PGMidi.h"
12 | #import "NSData+hexConv.h"
13 |
14 | @interface AppDelegate : NSObject
15 | {
16 |
17 |
18 | NSTimer *pulseTimer;
19 | // NSArrayController *arrayController;
20 |
21 | CBCentralManager *manager;
22 | CBPeripheral *peripheral;
23 |
24 |
25 |
26 | NSString *manufacturer;
27 |
28 | uint16_t heartRate;
29 |
30 | IBOutlet NSButton* connectButton;
31 | BOOL autoConnect;
32 |
33 | // Progress Indicator
34 | IBOutlet NSButton * indicatorButton;
35 | IBOutlet NSProgressIndicator *progressIndicator;
36 | }
37 |
38 |
39 | @property (assign) IBOutlet NSWindow *window;
40 | @property (assign) IBOutlet NSWindow *scanSheet;
41 | @property (assign) IBOutlet NSView *bleView;
42 | @property (assign) IBOutlet NSArrayController *arrayController;
43 | @property (nonatomic, strong) IBOutlet NSTextView *debugView;
44 | @property (assign) uint16_t heartRate;
45 | @property (retain) NSTimer *pulseTimer;
46 | @property (nonatomic, strong) IBOutlet NSMutableArray *heartRateMonitors;
47 | @property (copy) NSString *manufacturer;
48 | @property (copy) NSString *connected;
49 |
50 | - (IBAction) openScanSheet:(id) sender;
51 | - (IBAction) closeScanSheet:(id)sender;
52 | - (IBAction) cancelScanSheet:(id)sender;
53 | - (IBAction) connectButtonPressed:(id)sender;
54 |
55 | - (void) startScan;
56 | - (void) stopScan;
57 | - (BOOL) isLECapableHardware;
58 |
59 | // - (void) pulse;
60 | - (void) updateWithHRMData:(NSData *)data;
61 |
62 |
63 |
64 |
65 |
66 | @end
67 |
68 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8)
2 |
3 | include(CheckCXXCompilerFlag)
4 | CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
5 |
6 | # Enable ExternalProject CMake module
7 | include(ExternalProject)
8 |
9 | # Download and install GoogleTest
10 | ExternalProject_Add(
11 | gtest
12 | GIT_REPOSITORY https://github.com/google/googletest.git
13 | PREFIX ${CMAKE_CURRENT_BINARY_DIR}/googletest
14 | # Disable install step
15 | INSTALL_COMMAND ""
16 | )
17 |
18 | # Create a libgtest target to be used as a dependency by test programs
19 | add_library(libgtest IMPORTED STATIC GLOBAL)
20 | add_dependencies(libgtest gtest)
21 |
22 | # Set gtest properties
23 | ExternalProject_Get_Property(gtest source_dir binary_dir)
24 | set_target_properties(libgtest PROPERTIES
25 | "IMPORTED_LOCATION" "${binary_dir}/libgtest.a"
26 | "IMPORTED_LINK_INTERFACE_LIBRARIES" "${CMAKE_THREAD_LIBS_INIT}"
27 | # "INTERFACE_INCLUDE_DIRECTORIES" "${source_dir}/include"
28 | )
29 | # I couldn't make it work with INTERFACE_INCLUDE_DIRECTORIES
30 | #include_directories("${source_dir}/include")
31 | include_directories(SYSTEM
32 | ${CMAKE_CURRENT_BINARY_DIR}/googletest/src/gtest/googletest/include)
33 | include_directories(SYSTEM
34 | ${CMAKE_CURRENT_BINARY_DIR}/googletest/src/gtest/googlemock/include)
35 | # Set gmock properties
36 | # I couldn't make it work with INTERFACE_INCLUDE_DIRECTORIES
37 | include_directories("${source_dir}/include")
38 | add_library(libgmock IMPORTED STATIC GLOBAL)
39 |
40 | file(GLOB SRCS *.cpp *.h)
41 | add_executable(bletest ${SRCS} unit_tests/tst_BLEParser.cpp)
42 | set_property(TARGET bletest PROPERTY CXX_STANDARD 11)
43 |
44 | set_target_properties(libgmock PROPERTIES IMPORTED_LOCATION
45 | ${CMAKE_CURRENT_BINARY_DIR}/googletest/src/gtest-build/googlemock/libgmock.a)
46 | set_target_properties(libgtest PROPERTIES IMPORTED_LOCATION
47 | ${CMAKE_CURRENT_BINARY_DIR}/googletest/src/gtest-build/googlemock/gtest/libgtest.a)
48 |
49 | target_link_libraries(bletest
50 | libgtest
51 | libgmock
52 | )
53 | IF(CMAKE_SYSTEM_NAME STREQUAL Linux)
54 | set_target_properties(bletest PROPERTIES COMPILE_FLAGS -pthread LINK_FLAGS -pthread)
55 | ENDIF(CMAKE_SYSTEM_NAME STREQUAL Linux)
56 | install(TARGETS bletest DESTINATION bin)
57 |
--------------------------------------------------------------------------------
/Legacy Projects/nRF8001-BLE-Proto/RBL_nRF8001/RBL_nRF8001.h:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright (c) 2012, 2013 RedBearLab
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6 |
7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
10 |
11 | */
12 |
13 | #ifndef _RBL_NRF8001_H
14 | #define _RBL_NRF8001_H
15 |
16 | #include
17 | #include
18 | #include
19 | #include
20 |
21 | #include
22 | #include
23 |
24 | /* Put the nRF8001 setup in the RAM of the nRF8001.*/
25 | #include "RBL_services.h"
26 | /* Include the services_lock.h to put the setup in the OTP memory of the nRF8001.
27 | This would mean that the setup cannot be changed once put in.
28 | However this removes the need to do the setup of the nRF8001 on every reset.*/
29 |
30 | #if defined(BLEND_MICRO)
31 | #define DEFAULT_REQN 6
32 | #define DEFAULT_RDYN 7
33 | #else
34 | #define DEFAULT_REQN 9
35 | #define DEFAULT_RDYN 8
36 | #endif
37 |
38 | void ble_begin();
39 | void ble_set_name(char *name);
40 | void ble_write(unsigned char data);
41 | void ble_write_bytes(unsigned char *data, unsigned char len);
42 | void ble_do_events();
43 | int ble_buff_len(); // Added, we need buffer length in sketch
44 | int ble_read();
45 | unsigned char ble_available();
46 | unsigned char ble_connected(void);
47 | void ble_set_pins(uint8_t reqn, uint8_t rdyn);
48 | unsigned char ble_busy();
49 |
50 | #endif
51 |
52 |
--------------------------------------------------------------------------------
/Legacy Projects/nRF8001-BLE-Proto/RBL_nRF8001/examples/SimpleChat/SimpleChat.ino:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright (c) 2012-2014 RedBearLab
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6 |
7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
10 |
11 | */
12 |
13 | /*
14 | * Chat
15 | *
16 | * Simple chat sketch, work with the Chat iOS/Android App.
17 | * Type something from the Arduino serial monitor to send
18 | * to the Chat App or vice verse.
19 | *
20 | */
21 |
22 | //"services.h/spi.h/boards.h" is needed in every new project
23 | #include
24 | #include
25 | #include
26 |
27 | void setup()
28 | {
29 | // Default pins set to 9 and 8 for REQN and RDYN
30 | // Set your REQN and RDYN here before ble_begin() if you need
31 | //ble_set_pins(3, 2);
32 |
33 | // Set your BLE Shield name here, max. length 10
34 | //ble_set_name("My Name");
35 |
36 | // Init. and start BLE library.
37 | ble_begin();
38 |
39 | // Enable serial debug
40 | Serial.begin(57600);
41 | }
42 |
43 | unsigned char buf[16] = {0};
44 | unsigned char len = 0;
45 |
46 | void loop()
47 | {
48 | if ( ble_available() )
49 | {
50 | while ( ble_available() )
51 | Serial.write(ble_read());
52 |
53 | Serial.println();
54 | }
55 |
56 | if ( Serial.available() )
57 | {
58 | delay(5);
59 |
60 | while ( Serial.available() )
61 | ble_write( Serial.read() );
62 | }
63 |
64 | ble_do_events();
65 | }
66 |
67 |
--------------------------------------------------------------------------------
/Legacy Projects/nRF8001-BLE-Proto/RBL_nRF8001/examples/BLE_RGB/Adafruit_NeoPixel.h:
--------------------------------------------------------------------------------
1 | /*--------------------------------------------------------------------
2 | This file is part of the Adafruit NeoPixel library.
3 |
4 | NeoPixel is free software: you can redistribute it and/or modify
5 | it under the terms of the GNU Lesser General Public License as
6 | published by the Free Software Foundation, either version 3 of
7 | the License, or (at your option) any later version.
8 |
9 | NeoPixel is distributed in the hope that it will be useful,
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | GNU Lesser General Public License for more details.
13 |
14 | You should have received a copy of the GNU Lesser General Public
15 | License along with NeoPixel. If not, see
16 | .
17 | --------------------------------------------------------------------*/
18 |
19 | #if (ARDUINO >= 100)
20 | #include
21 | #else
22 | #include
23 | #include
24 | #endif
25 |
26 | // 'type' flags for LED pixels (third parameter to constructor):
27 | #define NEO_RGB 0x00 // Wired for RGB data order
28 | #define NEO_GRB 0x01 // Wired for GRB data order
29 | #define NEO_COLMASK 0x01
30 | #define NEO_KHZ400 0x00 // 400 KHz datastream
31 | #define NEO_KHZ800 0x02 // 800 KHz datastream
32 | #define NEO_SPDMASK 0x02
33 |
34 | class Adafruit_NeoPixel {
35 |
36 | public:
37 |
38 | // Constructor: number of LEDs, pin number, LED type
39 | Adafruit_NeoPixel(uint16_t n, uint8_t p=6, uint8_t t=NEO_GRB + NEO_KHZ800);
40 |
41 | void
42 | begin(void),
43 | show(void),
44 | setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b),
45 | setPixelColor(uint16_t n, uint32_t c);
46 | uint16_t
47 | numPixels(void);
48 | uint32_t
49 | Color(uint8_t r, uint8_t g, uint8_t b),
50 | getPixelColor(uint16_t n);
51 |
52 | private:
53 |
54 | uint16_t
55 | numLEDs, // Number of RGB LEDs in strip
56 | numBytes; // Size of 'pixels' buffer below
57 | uint8_t
58 | *pixels, // Holds LED color values (3 bytes each)
59 | pin, // Output pin number
60 | pinMask, // Output PORT bitmask
61 | type; // Pixel flags (400 vs 800 KHz, RGB vs GRB color)
62 | volatile uint8_t
63 | *port; // Output PORT register
64 | uint32_t
65 | endTime; // Latch timing reference
66 |
67 | };
68 |
--------------------------------------------------------------------------------
/debug-utils/MIDI LE for OSX/MIDI LE for OSX.xcodeproj/xcuserdata/sierenmusic.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
8 |
20 |
21 |
22 |
24 |
36 |
37 |
38 |
40 |
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/Legacy Projects/nRF8001-BLE-Proto/RBL_nRF8001/examples/HelloWorld/HelloWorld.ino:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright (c) 2012-2014 RedBearLab
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6 |
7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
10 |
11 | */
12 |
13 | /*
14 | * HelloWorld
15 | *
16 | * HelloWorld sketch, work with the Chat iOS/Android App.
17 | * It will send "Hello World" string to the App every 1 sec.
18 | *
19 | */
20 |
21 | //"services.h/spi.h/boards.h" is needed in every new project
22 | #include
23 | #include
24 | #include
25 |
26 | void setup()
27 | {
28 | //
29 | // For BLE Shield and Blend:
30 | // Default pins set to 9 and 8 for REQN and RDYN
31 | // Set your REQN and RDYN here before ble_begin() if you need
32 | //
33 | // For Blend Micro:
34 | // Default pins set to 6 and 7 for REQN and RDYN
35 | // So, no need to set for Blend Micro.
36 | //
37 | //ble_set_pins(3, 2);
38 |
39 | // Set your BLE advertising name here, max. length 10
40 | //ble_set_name("My BLE");
41 |
42 | // Init. and start BLE library.
43 | ble_begin();
44 |
45 | // Enable serial debug
46 | Serial.begin(57600);
47 | }
48 |
49 | unsigned char buf[16] = {0};
50 | unsigned char len = 0;
51 |
52 | void loop()
53 | {
54 | if ( ble_connected() )
55 | {
56 | ble_write('H');
57 | ble_write('e');
58 | ble_write('l');
59 | ble_write('l');
60 | ble_write('o');
61 | ble_write(' ');
62 | ble_write('W');
63 | ble_write('o');
64 | ble_write('r');
65 | ble_write('l');
66 | ble_write('d');
67 | ble_write('!');
68 | }
69 |
70 | ble_do_events();
71 |
72 | if ( ble_available() )
73 | {
74 | while ( ble_available() )
75 | {
76 | Serial.write(ble_read());
77 | }
78 |
79 | Serial.println();
80 | }
81 |
82 | delay(1000);
83 | }
84 |
85 |
--------------------------------------------------------------------------------
/debug-utils/MIDI LE for OSX/MIDI LE for OSX.app/Contents/_CodeSignature/CodeResources:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | files
6 |
7 | Resources/Base.lproj/MainMenu.nib
8 |
9 | hash
10 |
11 | 66Vr7R2OyX8v5mwLrRCVrbJP3vE=
12 |
13 | optional
14 |
15 |
16 |
17 | files2
18 |
19 | Resources/Base.lproj/MainMenu.nib
20 |
21 | hash
22 |
23 | 66Vr7R2OyX8v5mwLrRCVrbJP3vE=
24 |
25 | optional
26 |
27 |
28 |
29 | rules
30 |
31 | ^Resources/
32 |
33 | ^Resources/.*\.lproj/
34 |
35 | optional
36 |
37 | weight
38 | 1000
39 |
40 | ^Resources/.*\.lproj/locversion.plist$
41 |
42 | omit
43 |
44 | weight
45 | 1100
46 |
47 | ^version.plist$
48 |
49 |
50 | rules2
51 |
52 | .*\.dSYM($|/)
53 |
54 | weight
55 | 11
56 |
57 | ^(.*/)?\.DS_Store$
58 |
59 | omit
60 |
61 | weight
62 | 2000
63 |
64 | ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/
65 |
66 | nested
67 |
68 | weight
69 | 10
70 |
71 | ^.*
72 |
73 | ^Info\.plist$
74 |
75 | omit
76 |
77 | weight
78 | 20
79 |
80 | ^PkgInfo$
81 |
82 | omit
83 |
84 | weight
85 | 20
86 |
87 | ^Resources/
88 |
89 | weight
90 | 20
91 |
92 | ^Resources/.*\.lproj/
93 |
94 | optional
95 |
96 | weight
97 | 1000
98 |
99 | ^Resources/.*\.lproj/locversion.plist$
100 |
101 | omit
102 |
103 | weight
104 | 1100
105 |
106 | ^[^/]+$
107 |
108 | nested
109 |
110 | weight
111 | 10
112 |
113 | ^embedded\.provisionprofile$
114 |
115 | weight
116 | 20
117 |
118 | ^version\.plist$
119 |
120 | weight
121 | 20
122 |
123 |
124 |
125 |
126 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://travis-ci.org/sieren/blidino)
3 |
4 | blidino
5 | =======
6 |
7 | Arduino USB-MIDI to MIDI over Bluetooth Project.
8 | This repo hosts sketches and instructions to wirelessly connect USB Class compliant MIDI Devices to iOS / OSX Devices based on the recently released MIDI over Bluetooth protocol by Apple.
9 |
10 | The [BLEParser.h](https://github.com/auxren/blidino/blob/master/nRF51822-BLEMIDI/BLEParser.h) is fully templatized and can be injected with any class that supports the modelled functions (it is based around USBH_MIDI).
11 |
12 | GoogleMock based Unit-Tests ensure its basic feature-functionality (Single MIDI Notes, Running MIDI Status, SysEx).
13 |
14 | Simply execute `./run_unit_tests.sh` and the corresponding CMAKE file should take care of the rest (including fetching GoogleMock and GoogleTest).
15 |
16 |
17 | Projects
18 | ========
19 |
20 |
21 | [nRF52188](https://github.com/sieren/blidino/tree/master/nRF51822-BLEMIDI)
22 |
23 | This project holds code specifically aimed at the *nRF51288* by RedBearLab. It is designed to work out of the box with the [Circuits@Home USB Host Shield 2.0](http://www.circuitsathome.com/products-page/arduino-shields/usb-host-shield-2-0-for-arduino). You can get both boards for a total of around 50$.
24 |
25 |
26 | Requirements
27 | ====================
28 |
29 | As of 02.2016 this sketch requires the recent RBL SDK (based on S130). To make sure you are using the right firmware,
30 | drop the [bootloader.hex](https://github.com/RedBearLab/nRF51822-Arduino/blob/S130/bootloader/bootloader.hex) to the mBED drive.
31 | Older RBL Boards sold in 2014/2015 may still be using S110, thus updating is recommended if not done already.
32 |
33 | FAQ
34 | ====================
35 |
36 | • Do I have to use the USB Shield to make this work?
37 |
38 | Certainly not, removing all the USB Routines from the Code and replacing them with other functions is quite easy.
39 | The BLEParser takes in a Receiver Type which can be anything. To see an example of a fake-receiver, see the unit-test code.
40 |
41 |
42 | • Does this work with other Bluetooth boards?
43 |
44 | I suppose, but not out of the box. You'd have to re-implement the nRF SDK specific bluetooth functions for your board.
45 | The only supported boards right now are the ones based on the nRF51288 (and marketed through RBL).
46 | Rewriting this code natively for the nRF SDK is quite easy though and proved an ideal reference in the past.
47 |
48 |
49 | Known Issues
50 | ====================
51 |
52 |
53 | • USB to BLE Parsing
54 |
55 | MIDI to BLE-MIDI Parsing needs to be rewritten and made testable. This will be added shortly.
56 |
57 | Specifications
58 | ==============
59 | [Apple MIDI over Bluetooth
60 | PDF](https://developer.apple.com/bluetooth/Apple-Bluetooth-Low-Energy-MIDI-Specification.pdf)
61 |
62 |
63 |
64 | Videos
65 | =======
66 |
67 |
70 |
71 |
72 |
75 |
--------------------------------------------------------------------------------
/Legacy Projects/nRF8001-BLE-Proto/RBL_nRF8001/examples/SimpleControls/SimpleControls.ino:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright (c) 2012, 2013 RedBearLab
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6 |
7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
10 |
11 | */
12 |
13 | //"services.h/spi.h/boards.h" is needed in every new project
14 | #include
15 | #include
16 | #include
17 | #include
18 |
19 | #define DIGITAL_OUT_PIN 2
20 | #define DIGITAL_IN_PIN A4
21 | #define PWM_PIN 3
22 | #define SERVO_PIN 5
23 | #define ANALOG_IN_PIN A5
24 |
25 | Servo myservo;
26 |
27 | void setup()
28 | {
29 | // Default pins set to 9 and 8 for REQN and RDYN
30 | // Set your REQN and RDYN here before ble_begin() if you need
31 | //ble_set_pins(3, 2);
32 |
33 | // Set your BLE Shield name here, max. length 10
34 | //ble_set_name("My Name");
35 |
36 | // Init. and start BLE library.
37 | ble_begin();
38 |
39 | // Enable serial debug
40 | Serial.begin(57600);
41 |
42 | pinMode(DIGITAL_OUT_PIN, OUTPUT);
43 | pinMode(DIGITAL_IN_PIN, INPUT);
44 |
45 | // Default to internally pull high, change it if you need
46 | digitalWrite(DIGITAL_IN_PIN, HIGH);
47 | //digitalWrite(DIGITAL_IN_PIN, LOW);
48 |
49 | myservo.attach(SERVO_PIN);
50 | }
51 |
52 | void loop()
53 | {
54 | static boolean analog_enabled = false;
55 | static byte old_state = LOW;
56 |
57 | // If data is ready
58 | while(ble_available())
59 | {
60 | // read out command and data
61 | byte data0 = ble_read();
62 | byte data1 = ble_read();
63 | byte data2 = ble_read();
64 |
65 | if (data0 == 0x01) // Command is to control digital out pin
66 | {
67 | if (data1 == 0x01)
68 | digitalWrite(DIGITAL_OUT_PIN, HIGH);
69 | else
70 | digitalWrite(DIGITAL_OUT_PIN, LOW);
71 | }
72 | else if (data0 == 0xA0) // Command is to enable analog in reading
73 | {
74 | if (data1 == 0x01)
75 | analog_enabled = true;
76 | else
77 | analog_enabled = false;
78 | }
79 | else if (data0 == 0x02) // Command is to control PWM pin
80 | {
81 | analogWrite(PWM_PIN, data1);
82 | }
83 | else if (data0 == 0x03) // Command is to control Servo pin
84 | {
85 | myservo.write(data1);
86 | }
87 | else if (data0 == 0x04)
88 | {
89 | analog_enabled = false;
90 | myservo.write(0);
91 | analogWrite(PWM_PIN, 0);
92 | digitalWrite(DIGITAL_OUT_PIN, LOW);
93 | }
94 | }
95 |
96 | if (analog_enabled) // if analog reading enabled
97 | {
98 | // Read and send out
99 | uint16_t value = analogRead(ANALOG_IN_PIN);
100 | ble_write(0x0B);
101 | ble_write(value >> 8);
102 | ble_write(value);
103 | }
104 |
105 | // If digital in changes, report the state
106 | if (digitalRead(DIGITAL_IN_PIN) != old_state)
107 | {
108 | old_state = digitalRead(DIGITAL_IN_PIN);
109 |
110 | if (digitalRead(DIGITAL_IN_PIN) == HIGH)
111 | {
112 | ble_write(0x0A);
113 | ble_write(0x01);
114 | ble_write(0x00);
115 | }
116 | else
117 | {
118 | ble_write(0x0A);
119 | ble_write(0x00);
120 | ble_write(0x00);
121 | }
122 | }
123 |
124 | if (!ble_connected())
125 | {
126 | analog_enabled = false;
127 | digitalWrite(DIGITAL_OUT_PIN, LOW);
128 | }
129 |
130 | // Allow BLE Shield to send/receive data
131 | ble_do_events();
132 | }
133 |
134 |
135 |
136 |
--------------------------------------------------------------------------------
/unit_tests/tst_BLEParser.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include "gtest/gtest.h"
4 | #include "gmock/gmock.h"
5 | #include "../nRF51822-BLEMIDI/BLEParser.h"
6 | #include
7 | #include
8 |
9 | typedef uint8_t byte;
10 |
11 | int main(int argc, char **argv)
12 | {
13 | ::testing::InitGoogleTest(&argc, argv);
14 | int ret = RUN_ALL_TESTS();
15 | return ret;
16 | }
17 |
18 | // Mocking used USBMidi_H Functions
19 | class USBMidiMock
20 | {
21 | public:
22 | USBMidiMock() = default;
23 | // Ommiting byte nCable=0 overload
24 | MOCK_METHOD3(SendSysEx, void(
25 | uint8_t *dataptr,
26 | unsigned int datasize,
27 | byte nCable));
28 |
29 | // everything GEQ 3 is ignored by USBH_MIDI
30 | MOCK_METHOD2(SendData, void(
31 | (const uint8_t (&dataptr)[3], byte nCable)));
32 | };
33 |
34 | struct Fixture
35 | {
36 | Fixture()
37 | {
38 | mParser.setUSBMidiHandle(&mUSBMock);
39 | }
40 |
41 | void parseDataArray(uint8_t *data, uint8_t length)
42 | {
43 | for (int i = 1; i < length; i++)
44 | {
45 | mParser.parseMidiEvent(data[0], data[i]);
46 | }
47 | }
48 |
49 | void parseMidiEvent(uint8_t header, uint8_t event)
50 | {
51 | mParser.parseMidiEvent(header, event);
52 | }
53 |
54 | USBMidiMock& getMock()
55 | {
56 | return mUSBMock;
57 | }
58 |
59 | mfk::midi::BLEMIDIParser<256, USBMidiMock> mParser;
60 | ::testing::NiceMock mUSBMock;
61 | };
62 |
63 |
64 | TEST(BLEReturnMIDIData, SingleNote)
65 | {
66 | using testing::ElementsAreArray;
67 | using testing::_;
68 | Fixture f;
69 | static uint8_t testdata[5] =
70 | { 0x80, 0x80, 0x90, 0x80, 0x45 };
71 | static uint8_t midiResult[3] =
72 | { 0x90, 0x80, 0x45 };
73 |
74 | EXPECT_CALL(f.getMock(), SendData(ElementsAreArray(midiResult),0));
75 | f.parseDataArray(testdata, 5);
76 | }
77 |
78 |
79 | TEST(BLEReturnRunningMIDIData, TwoNotes)
80 | {
81 | using testing::ElementsAreArray;
82 | using testing::_;
83 | Fixture f;
84 | static uint8_t testdata[8] =
85 | { 0x80, 0x80, 0x90, 0x45, 0x45, 0x80, 0x22, 0x45 };
86 | static uint8_t midiResult1[3] =
87 | { 0x90, 0x45, 0x45 };
88 | static uint8_t midiResult2[3] =
89 | { 0x90, 0x22, 0x45 };
90 |
91 |
92 |
93 | EXPECT_CALL(f.getMock(), SendData(ElementsAreArray(midiResult1),0));
94 | EXPECT_CALL(f.getMock(), SendData(ElementsAreArray(midiResult2),0));
95 | f.parseDataArray(testdata, 8);
96 | }
97 |
98 |
99 | TEST(BLEReturnSysExData, SingleData)
100 | {
101 | using testing::ElementsAreArray;
102 | using testing::_;
103 | using testing::Args;
104 | Fixture f;
105 | static uint8_t testdata[8] =
106 | { 0x80, 0x80, 0xf0, 0x90, 0x80, 0x45, 0x88, 0xf7};
107 | static uint8_t sysExResult[5] =
108 | { 0xf0, 0x90, 0x80, 0x45, 0xf7 };
109 |
110 | EXPECT_CALL(f.getMock(), SendSysEx(_,_,0)).With(Args<0,1>(ElementsAreArray(sysExResult)));
111 | f.parseDataArray(testdata, 8);
112 | }
113 |
114 |
115 | TEST(BLEReturnLongSysExData, MultipleData)
116 | {
117 | using testing::ElementsAreArray;
118 | using testing::_;
119 | using testing::Args;
120 | Fixture f;
121 | static uint8_t longSysEx1[9] =
122 | {
123 | 0x80, 0x80, 0xf0, 0x47, 0x7f, 0x15, 0x5c, 0x00, 0x01
124 | };
125 | static uint8_t longSysEx2[9] =
126 | {
127 | 0x80, 0x21, 0x46, 0x47, 0x7f, 0x15, 0x5c, 0x80, 0xf7
128 | };
129 |
130 | static uint8_t sysExResult[14] =
131 | { 0xf0, 0x47, 0x7f, 0x15, 0x5c, 0x00, 0x01, 0x21, 0x46,
132 | 0x47, 0x7f, 0x15, 0x5c, 0xf7
133 | };
134 |
135 | EXPECT_CALL(f.getMock(), SendSysEx(_,_,0)).With(Args<0,1>(ElementsAreArray(sysExResult)));
136 | f.parseDataArray(longSysEx1, 9);
137 | f.parseDataArray(longSysEx2, 9);
138 | }
139 |
140 | TEST(BLEReturnSysExRecoveryBuffer, ReturnTwice)
141 | {
142 | using testing::ElementsAreArray;
143 | using testing::_;
144 | using testing::Args;
145 | Fixture f;
146 | static uint8_t longSysEx1[9] =
147 | {
148 | 0x80, 0x80, 0xf0, 0x47, 0x7f, 0x15, 0x5c, 0x00, 0x01
149 | };
150 | static uint8_t longSysEx2[9] =
151 | {
152 | 0x80, 0x21, 0x46, 0x47, 0x7f, 0x15, 0x5c, 0xf7, 0xf7
153 | };
154 |
155 | static uint8_t sysExFalseResult[13] =
156 | { 0xf0, 0x47, 0x7f, 0x15, 0x5c, 0x00, 0x01, 0x21, 0x46,
157 | 0x47, 0x7f, 0x15, 0xf7
158 | };
159 |
160 | static uint8_t sysExRecoveryResult[14] =
161 | { 0xf0, 0x47, 0x7f, 0x15, 0x5c, 0x00, 0x01, 0x21, 0x46,
162 | 0x47, 0x7f, 0x15, 0x5c, 0xf7
163 | };
164 |
165 | EXPECT_CALL(f.getMock(), SendSysEx(_,_,0)).With(Args<0,1>(
166 | ElementsAreArray(sysExFalseResult))).Times(1);
167 | EXPECT_CALL(f.getMock(), SendSysEx(_,_,0)).With(Args<0,1>(
168 | ElementsAreArray(sysExRecoveryResult))).Times(1);
169 |
170 | f.parseDataArray(longSysEx1, 9);
171 | f.parseDataArray(longSysEx2, 9);
172 | }
173 |
174 |
--------------------------------------------------------------------------------
/debug-utils/MIDI LE for OSX/MIDI LE for OSX.xcodeproj/xcuserdata/sierenmusic.xcuserdatad/xcschemes/MIDI LE for OSX.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
38 |
39 |
44 |
45 |
47 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
65 |
66 |
75 |
76 |
82 |
83 |
84 |
85 |
86 |
87 |
93 |
94 |
100 |
101 |
102 |
103 |
105 |
106 |
109 |
110 |
111 |
--------------------------------------------------------------------------------
/debug-utils/MIDI LE for OSX/MIDI LE for OSX/PGMidi/PGMidi.h:
--------------------------------------------------------------------------------
1 | //
2 | // PGMidi.h
3 | // PGMidi
4 | //
5 |
6 |
7 | #import
8 | #import
9 | #import "PGArc.h"
10 |
11 | @class PGMidi;
12 | @class PGMidiSource;
13 |
14 | extern NSString * const PGMidiSourceAddedNotification;
15 | extern NSString * const PGMidiSourceRemovedNotification;
16 | extern NSString * const PGMidiDestinationAddedNotification;
17 | extern NSString * const PGMidiDestinationRemovedNotification;
18 |
19 | extern NSString * const PGMidiConnectionKey;
20 |
21 |
22 | /// Represents a source/destination for MIDI data
23 | ///
24 | /// @see PGMidiSource
25 | /// @see PGMidiDestination
26 | @interface PGMidiConnection : NSObject
27 | {
28 | PGMidi *midi;
29 | MIDIEndpointRef endpoint;
30 | NSString *name;
31 | BOOL isNetworkSession;
32 | }
33 | @property (nonatomic,readonly) PGMidi *midi;
34 | @property (nonatomic,readonly) MIDIEndpointRef endpoint;
35 | @property (nonatomic,readonly) NSString *name;
36 | @property (nonatomic,readonly) BOOL isNetworkSession;
37 | @end
38 |
39 |
40 | /// Delegate protocol for PGMidiSource class.
41 | /// Adopt this protocol in your object to receive MIDI events
42 | ///
43 | /// IMPORTANT NOTE:
44 | /// MIDI input is received from a high priority background thread
45 | ///
46 | /// @see PGMidiSource
47 | @protocol PGMidiSourceDelegate
48 |
49 | // Raised on main run loop
50 | /// NOTE: Raised on high-priority background thread.
51 | ///
52 | /// To do anything UI-ish, you must forward the event to the main runloop
53 | /// (e.g. use performSelectorOnMainThread:withObject:waitUntilDone:)
54 | ///
55 | /// Be careful about autoreleasing objects here - there is no NSAutoReleasePool.
56 | ///
57 | /// Handle the data like this:
58 | ///
59 | /// // for some function HandlePacketData(Byte *data, UInt16 length)
60 | /// const MIDIPacket *packet = &packetList->packet[0];
61 | /// for (int i = 0; i < packetList->numPackets; ++i)
62 | /// {
63 | /// HandlePacketData(packet->data, packet->length);
64 | /// packet = MIDIPacketNext(packet);
65 | /// }
66 | - (void) midiSource:(PGMidiSource*)input midiReceived:(const MIDIPacketList *)packetList;
67 |
68 | @end
69 |
70 | /// Represents a source of MIDI data identified by CoreMIDI
71 | ///
72 | /// @see PGMidiSourceDelegate
73 | @interface PGMidiSource : PGMidiConnection
74 | - (void)addDelegate:(id)delegate;
75 | - (void)removeDelegate:(id)delegate;
76 |
77 | @property (strong, nonatomic, readonly) NSArray *delegates;
78 | @end
79 |
80 | //==============================================================================
81 |
82 | /// Represents a destination for MIDI data identified by CoreMIDI
83 | @interface PGMidiDestination : PGMidiConnection
84 | {
85 | }
86 | - (void) flushOutput;
87 | - (void) sendBytes:(const UInt8*)bytes size:(UInt32)size;
88 | - (void) sendPacketList:(MIDIPacketList *)packetList;
89 | @end
90 |
91 | //==============================================================================
92 |
93 | /// Delegate protocol for PGMidi class.
94 | ///
95 | /// @see PGMidi
96 | @protocol PGMidiDelegate
97 | - (void) midi:(PGMidi*)midi sourceAdded:(PGMidiSource *)source;
98 | - (void) midi:(PGMidi*)midi sourceRemoved:(PGMidiSource *)source;
99 | - (void) midi:(PGMidi*)midi destinationAdded:(PGMidiDestination *)destination;
100 | - (void) midi:(PGMidi*)midi destinationRemoved:(PGMidiDestination *)destination;
101 | @end
102 |
103 | /// Class for receiving MIDI input from any MIDI device.
104 | ///
105 | /// If you intend your app to support iOS 3.x which does not have CoreMIDI
106 | /// support, weak link to the CoreMIDI framework, and only create a
107 | /// PGMidi object if you are running the right version of iOS.
108 | ///
109 | /// @see PGMidiDelegate
110 | @interface PGMidi : NSObject
111 | {
112 | MIDIClientRef client;
113 | MIDIPortRef outputPort;
114 | MIDIPortRef inputPort;
115 | NSString *virtualEndpointName;
116 | MIDIEndpointRef virtualSourceEndpoint;
117 | MIDIEndpointRef virtualDestinationEndpoint;
118 | PGMidiSource *virtualDestinationSource;
119 | PGMidiDestination *virtualSourceDestination;
120 | NSMutableArray *sources, *destinations;
121 | }
122 |
123 | + (BOOL)midiAvailable;
124 |
125 | @property (nonatomic,assign) id delegate;
126 | @property (nonatomic,readonly) NSUInteger numberOfConnections;
127 | @property (nonatomic,readonly) NSMutableArray *sources;
128 | @property (nonatomic,readonly) NSMutableArray *destinations;
129 | @property (nonatomic,readonly) PGMidiSource *virtualDestinationSource;
130 | @property (nonatomic,readonly) PGMidiDestination *virtualSourceDestination;
131 | @property (nonatomic,retain) NSString *virtualEndpointName;
132 | @property (nonatomic,assign) BOOL networkEnabled;
133 | @property (nonatomic,assign) BOOL virtualSourceEnabled;
134 | @property (nonatomic,assign) BOOL virtualDestinationEnabled;
135 |
136 | /// Send a MIDI byte stream to every connected MIDI port
137 | - (void) sendBytes:(const UInt8*)bytes size:(UInt32)size;
138 | - (void) sendPacketList:(const MIDIPacketList *)packetList;
139 |
140 | @end
141 |
--------------------------------------------------------------------------------
/Legacy Projects/nRF8001-BLE-Proto/RBL_nRF8001/RBL_services_OLD.h:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved.
2 | *
3 | * The information contained herein is property of Nordic Semiconductor ASA.
4 | * Terms and conditions of usage are described in detail in NORDIC
5 | * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
6 | *
7 | * Licensees are granted free, non-transferable use of the information. NO
8 | * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
9 | * the file.
10 | */
11 |
12 | /**
13 | * This file is autogenerated by nRFgo Studio 1.14.1.2369
14 | */
15 |
16 | #ifndef SETUP_MESSAGES_H__
17 | #define SETUP_MESSAGES_H__
18 |
19 | #include "hal_platform.h"
20 | #include "aci.h"
21 | #define PIPE_GAP_DEVICE_NAME_SET 1
22 | #define PIPE_UART_OVER_BTLE_UART_RX_RX 2
23 | #define PIPE_UART_OVER_BTLE_UART_TX_TX 3
24 | #define PIPE_DEVICE_INFORMATION_HARDWARE_REVISION_STRING_SET 4
25 |
26 | #define NUMBER_OF_PIPES 4
27 |
28 | #define SERVICES_PIPE_TYPE_MAPPING_CONTENT {\
29 | {ACI_STORE_LOCAL, ACI_SET}, \
30 | {ACI_STORE_LOCAL, ACI_RX}, \
31 | {ACI_STORE_LOCAL, ACI_TX}, \
32 | {ACI_STORE_LOCAL, ACI_SET}, \
33 | }
34 |
35 | #define GAP_PPCP_MAX_CONN_INT 0x12 /**< Maximum connection interval as a multiple of 1.25 msec , 0xFFFF means no specific value requested */
36 | #define GAP_PPCP_MIN_CONN_INT 0x6 /**< Minimum connection interval as a multiple of 1.25 msec , 0xFFFF means no specific maximum*/
37 | #define GAP_PPCP_SLAVE_LATENCY 0
38 | #define GAP_PPCP_CONN_TIMEOUT 0xa /** Connection Supervision timeout multiplier as a multiple of 10msec, 0xFFFF means no specific value requested */
39 |
40 | #define NB_SETUP_MESSAGES 21
41 | #define SETUP_MESSAGES_CONTENT {\
42 | {0x00,\
43 | {\
44 | 0x07,0x06,0x00,0x00,0x03,0x02,0x41,0xd7,\
45 | },\
46 | },\
47 | {0x00,\
48 | {\
49 | 0x1f,0x06,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x04,0x01,0x01,0x00,0x00,0x06,0x00,0x00,\
50 | 0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
51 | },\
52 | },\
53 | {0x00,\
54 | {\
55 | 0x1f,0x06,0x10,0x1c,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
56 | 0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x03,0x90,0x01,0xff,\
57 | },\
58 | },\
59 | {0x00,\
60 | {\
61 | 0x1f,0x06,0x10,0x38,0xff,0xff,0x02,0x58,0x00,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x00,0x00,\
62 | 0x00,0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,\
63 | },\
64 | },\
65 | {0x00,\
66 | {\
67 | 0x05,0x06,0x10,0x54,0x00,0x00,\
68 | },\
69 | },\
70 | {0x00,\
71 | {\
72 | 0x1f,0x06,0x20,0x00,0x04,0x04,0x02,0x02,0x00,0x01,0x28,0x00,0x01,0x00,0x18,0x04,0x04,0x05,0x05,0x00,\
73 | 0x02,0x28,0x03,0x01,0x0e,0x03,0x00,0x00,0x2a,0x04,0x14,0x0a,\
74 | },\
75 | },\
76 | {0x00,\
77 | {\
78 | 0x1f,0x06,0x20,0x1c,0x0a,0x00,0x03,0x2a,0x00,0x01,0x42,0x4c,0x45,0x20,0x53,0x68,0x69,0x65,0x6c,0x64,\
79 | 0x04,0x04,0x05,0x05,0x00,0x04,0x28,0x03,0x01,0x02,0x05,0x00,\
80 | },\
81 | },\
82 | {0x00,\
83 | {\
84 | 0x1f,0x06,0x20,0x38,0x01,0x2a,0x06,0x04,0x03,0x02,0x00,0x05,0x2a,0x01,0x01,0x00,0x00,0x04,0x04,0x05,\
85 | 0x05,0x00,0x06,0x28,0x03,0x01,0x02,0x07,0x00,0x04,0x2a,0x06,\
86 | },\
87 | },\
88 | {0x00,\
89 | {\
90 | 0x1f,0x06,0x20,0x54,0x04,0x09,0x08,0x00,0x07,0x2a,0x04,0x01,0x06,0x00,0x12,0x00,0x00,0x00,0x0a,0x00,\
91 | 0x04,0x04,0x02,0x02,0x00,0x08,0x28,0x00,0x01,0x01,0x18,0x04,\
92 | },\
93 | },\
94 | {0x00,\
95 | {\
96 | 0x1f,0x06,0x20,0x70,0x04,0x10,0x10,0x00,0x09,0x28,0x00,0x01,0x1e,0x94,0x8d,0xf1,0x48,0x31,0x94,0xba,\
97 | 0x75,0x4c,0x3e,0x50,0x00,0x00,0x3d,0x71,0x04,0x04,0x13,0x13,\
98 | },\
99 | },\
100 | {0x00,\
101 | {\
102 | 0x1f,0x06,0x20,0x8c,0x00,0x0a,0x28,0x03,0x01,0x04,0x0b,0x00,0x1e,0x94,0x8d,0xf1,0x48,0x31,0x94,0xba,\
103 | 0x75,0x4c,0x3e,0x50,0x03,0x00,0x3d,0x71,0x44,0x10,0x14,0x00,\
104 | },\
105 | },\
106 | {0x00,\
107 | {\
108 | 0x1f,0x06,0x20,0xa8,0x00,0x0b,0x00,0x03,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
109 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x04,0x13,\
110 | },\
111 | },\
112 | {0x00,\
113 | {\
114 | 0x1f,0x06,0x20,0xc4,0x13,0x00,0x0c,0x28,0x03,0x01,0x10,0x0d,0x00,0x1e,0x94,0x8d,0xf1,0x48,0x31,0x94,\
115 | 0xba,0x75,0x4c,0x3e,0x50,0x02,0x00,0x3d,0x71,0x14,0x00,0x14,\
116 | },\
117 | },\
118 | {0x00,\
119 | {\
120 | 0x1f,0x06,0x20,0xe0,0x00,0x00,0x0d,0x00,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
121 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x14,\
122 | },\
123 | },\
124 | {0x00,\
125 | {\
126 | 0x1f,0x06,0x20,0xfc,0x03,0x02,0x00,0x0e,0x29,0x02,0x01,0x00,0x00,0x04,0x04,0x02,0x02,0x00,0x0f,0x28,\
127 | 0x00,0x01,0x0a,0x18,0x04,0x04,0x05,0x05,0x00,0x10,0x28,0x03,\
128 | },\
129 | },\
130 | {0x00,\
131 | {\
132 | 0x1c,0x06,0x21,0x18,0x01,0x02,0x11,0x00,0x27,0x2a,0x04,0x04,0x09,0x01,0x00,0x11,0x2a,0x27,0x01,0x0a,\
133 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
134 | },\
135 | },\
136 | {0x00,\
137 | {\
138 | 0x1f,0x06,0x40,0x00,0x2a,0x00,0x01,0x00,0x80,0x04,0x00,0x03,0x00,0x00,0x00,0x03,0x02,0x00,0x08,0x04,\
139 | 0x00,0x0b,0x00,0x00,0x00,0x02,0x02,0x00,0x02,0x04,0x00,0x0d,\
140 | },\
141 | },\
142 | {0x00,\
143 | {\
144 | 0x0f,0x06,0x40,0x1c,0x00,0x0e,0x2a,0x27,0x01,0x00,0x80,0x04,0x00,0x11,0x00,0x00,\
145 | },\
146 | },\
147 | {0x00,\
148 | {\
149 | 0x13,0x06,0x50,0x00,0x1e,0x94,0x8d,0xf1,0x48,0x31,0x94,0xba,0x75,0x4c,0x3e,0x50,0x00,0x00,0x3d,0x71,\
150 | },\
151 | },\
152 | {0x00,\
153 | {\
154 | 0x0f,0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
155 | },\
156 | },\
157 | {0x00,\
158 | {\
159 | 0x06,0x06,0xf0,0x00,0x03,0x6a,0x44,\
160 | },\
161 | },\
162 | }
163 |
164 | #endif
165 |
--------------------------------------------------------------------------------
/Legacy Projects/nRF8001-BLE-Proto/RBL_nRF8001/RBL_services.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2013, Nordic Semiconductor ASA
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification,
6 | * are permitted provided that the following conditions are met:
7 | *
8 | * - Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | *
11 | * - Redistributions in binary form must reproduce the above copyright notice, this
12 | * list of conditions and the following disclaimer in the documentation and/or
13 | * other materials provided with the distribution.
14 | *
15 | * - The name of Nordic Semiconductor ASA may not be used to endorse or promote
16 | * products derived from this software without specific prior written permission.
17 | *
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
22 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 | */
29 |
30 | /**
31 | * This file is autogenerated by nRFgo Studio 1.16.1.3119
32 | */
33 |
34 | #ifndef SETUP_MESSAGES_H__
35 | #define SETUP_MESSAGES_H__
36 |
37 | #include
38 | #include
39 | #include
40 | #define PIPE_GAP_DEVICE_NAME_SET 3
41 | #define PIPE_UART_OVER_BTLE_UART_RX_RX 2
42 | #define PIPE_UART_OVER_BTLE_UART_TX_TX 1
43 | #define PIPE_DEVICE_INFORMATION_HARDWARE_REVISION_STRING_SET 4
44 |
45 |
46 |
47 | #define SETUP_ID 0
48 | #define SETUP_FORMAT 3 /** nRF8001 D */
49 | #define ACI_DYNAMIC_DATA_SIZE 135
50 |
51 | /* Service: BLIDino - Characteristic: MIDI Service - Pipe: TX */
52 | #define PIPE_BLIDINO_MIDI_SERVICE_TX 1
53 | #define PIPE_BLIDINO_MIDI_SERVICE_TX_MAX_SIZE 20
54 |
55 | /* Service: BLIDino - Characteristic: MIDI Service - Pipe: RX */
56 | #define PIPE_BLIDINO_MIDI_SERVICE_RX 2
57 | #define PIPE_BLIDINO_MIDI_SERVICE_RX_MAX_SIZE 20
58 |
59 | /* Service: BLIDino - Characteristic: MIDI Service - Pipe: SET */
60 | #define PIPE_BLIDINO_MIDI_SERVICE_SET 3
61 | #define PIPE_BLIDINO_MIDI_SERVICE_SET_MAX_SIZE 20
62 |
63 |
64 | #define NUMBER_OF_PIPES 3
65 |
66 | #define SERVICES_PIPE_TYPE_MAPPING_CONTENT {\
67 | {ACI_STORE_LOCAL, ACI_TX}, \
68 | {ACI_STORE_LOCAL, ACI_RX}, \
69 | {ACI_STORE_LOCAL, ACI_SET}, \
70 | }
71 |
72 | #define GAP_PPCP_MAX_CONN_INT 0xc /**< Maximum connection interval as a multiple of 1.25 msec , 0xFFFF means no specific value requested */
73 | #define GAP_PPCP_MIN_CONN_INT 0x6 /**< Minimum connection interval as a multiple of 1.25 msec , 0xFFFF means no specific value requested */
74 | #define GAP_PPCP_SLAVE_LATENCY 0
75 | #define GAP_PPCP_CONN_TIMEOUT 0xffff /** Connection Supervision timeout multiplier as a multiple of 10msec, 0xFFFF means no specific value requested */
76 |
77 | #define NB_SETUP_MESSAGES 18
78 | #define SETUP_MESSAGES_CONTENT {\
79 | {0x00,\
80 | {\
81 | 0x07,0x06,0x00,0x00,0x03,0x02,0x41,0xfe,\
82 | },\
83 | },\
84 | {0x00,\
85 | {\
86 | 0x1f,0x06,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x03,0x01,0x01,0x00,0x00,0x06,0x00,0x00,\
87 | 0xd0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0e,\
88 | },\
89 | },\
90 | {0x00,\
91 | {\
92 | 0x1f,0x06,0x10,0x1c,0x5a,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
93 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x03,0x90,0x02,0xff,\
94 | },\
95 | },\
96 | {0x00,\
97 | {\
98 | 0x1f,0x06,0x10,0x38,0xff,0xff,0x02,0x58,0x0a,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x00,0x00,\
99 | 0x00,0x14,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0x00,0x00,0x00,\
100 | },\
101 | },\
102 | {0x00,\
103 | {\
104 | 0x05,0x06,0x10,0x54,0x00,0x00,\
105 | },\
106 | },\
107 | {0x00,\
108 | {\
109 | 0x1f,0x06,0x20,0x00,0x04,0x04,0x02,0x02,0x00,0x01,0x28,0x00,0x01,0x00,0x18,0x04,0x04,0x05,0x05,0x00,\
110 | 0x02,0x28,0x03,0x01,0x02,0x03,0x00,0x00,0x2a,0x04,0x04,0x14,\
111 | },\
112 | },\
113 | {0x00,\
114 | {\
115 | 0x1f,0x06,0x20,0x1c,0x07,0x00,0x03,0x2a,0x00,0x01,0x42,0x4c,0x49,0x44,0x49,0x6e,0x6f,0x65,0x6d,0x69,\
116 | 0x2e,0x63,0x6f,0x6d,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x04,\
117 | },\
118 | },\
119 | {0x00,\
120 | {\
121 | 0x1f,0x06,0x20,0x38,0x05,0x05,0x00,0x04,0x28,0x03,0x01,0x02,0x05,0x00,0x01,0x2a,0x06,0x04,0x03,0x02,\
122 | 0x00,0x05,0x2a,0x01,0x01,0x00,0x00,0x04,0x04,0x05,0x05,0x00,\
123 | },\
124 | },\
125 | {0x00,\
126 | {\
127 | 0x1f,0x06,0x20,0x54,0x06,0x28,0x03,0x01,0x02,0x07,0x00,0x04,0x2a,0x06,0x04,0x09,0x08,0x00,0x07,0x2a,\
128 | 0x04,0x01,0x06,0x00,0x0c,0x00,0x00,0x00,0xff,0xff,0x04,0x04,\
129 | },\
130 | },\
131 | {0x00,\
132 | {\
133 | 0x1f,0x06,0x20,0x70,0x02,0x02,0x00,0x08,0x28,0x00,0x01,0x01,0x18,0x04,0x04,0x10,0x10,0x00,0x09,0x28,\
134 | 0x00,0x01,0x00,0xc7,0xc4,0x4e,0xe3,0x6c,0x51,0xa7,0x33,0x4b,\
135 | },\
136 | },\
137 | {0x00,\
138 | {\
139 | 0x1f,0x06,0x20,0x8c,0xe8,0xed,0x5a,0x0e,0xb8,0x03,0x04,0x04,0x13,0x13,0x00,0x0a,0x28,0x03,0x01,0x16,\
140 | 0x0b,0x00,0xf3,0x6b,0x10,0x9d,0x66,0xf2,0xa9,0xa1,0x12,0x41,\
141 | },\
142 | },\
143 | {0x00,\
144 | {\
145 | 0x1f,0x06,0x20,0xa8,0x68,0x38,0xdb,0xe5,0x72,0x77,0x54,0x14,0x14,0x00,0x00,0x0b,0xe5,0xdb,0x03,0x00,\
146 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
147 | },\
148 | },\
149 | {0x00,\
150 | {\
151 | 0x16,0x06,0x20,0xc4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x14,0x03,0x02,0x00,0x0c,0x29,0x02,0x01,\
152 | 0x00,0x00,0x00,\
153 | },\
154 | },\
155 | {0x00,\
156 | {\
157 | 0x0d,0x06,0x40,0x00,0xe5,0xdb,0x03,0x00,0x8a,0x04,0x00,0x0b,0x00,0x0c,\
158 | },\
159 | },\
160 | {0x00,\
161 | {\
162 | 0x1f,0x06,0x50,0x00,0x00,0xc7,0xc4,0x4e,0xe3,0x6c,0x51,0xa7,0x33,0x4b,0xe8,0xed,0x00,0x00,0xb8,0x03,\
163 | 0xf3,0x6b,0x10,0x9d,0x66,0xf2,0xa9,0xa1,0x12,0x41,0x68,0x38,\
164 | },\
165 | },\
166 | {0x00,\
167 | {\
168 | 0x07,0x06,0x50,0x1c,0x00,0x00,0x72,0x77,\
169 | },\
170 | },\
171 | {0x00,\
172 | {\
173 | 0x06,0x06,0x60,0x00,0x00,0x00,0x00,\
174 | },\
175 | },\
176 | {0x00,\
177 | {\
178 | 0x06,0x06,0xf0,0x00,0x03,0x84,0xcb,\
179 | },\
180 | },\
181 | }
182 |
183 | #endif
--------------------------------------------------------------------------------
/Legacy Projects/nRF8001-BLE-Proto/RBL_services.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2013, Nordic Semiconductor ASA
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification,
6 | * are permitted provided that the following conditions are met:
7 | *
8 | * - Redistributions of source code must retain the above copyright notice, this
9 | * list of conditions and the following disclaimer.
10 | *
11 | * - Redistributions in binary form must reproduce the above copyright notice, this
12 | * list of conditions and the following disclaimer in the documentation and/or
13 | * other materials provided with the distribution.
14 | *
15 | * - The name of Nordic Semiconductor ASA may not be used to endorse or promote
16 | * products derived from this software without specific prior written permission.
17 | *
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
22 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 | */
29 |
30 | /**
31 | * This file is autogenerated by nRFgo Studio 1.16.1.3119
32 | */
33 |
34 | #ifndef SETUP_MESSAGES_H__
35 | #define SETUP_MESSAGES_H__
36 |
37 | #include
38 | #include
39 | #include
40 | #define PIPE_GAP_DEVICE_NAME_SET 3
41 | #define PIPE_UART_OVER_BTLE_UART_RX_RX 2
42 | #define PIPE_UART_OVER_BTLE_UART_TX_TX 1
43 | #define PIPE_DEVICE_INFORMATION_HARDWARE_REVISION_STRING_SET 4
44 |
45 |
46 |
47 | #define SETUP_ID 0
48 | #define SETUP_FORMAT 3 /** nRF8001 D */
49 | #define ACI_DYNAMIC_DATA_SIZE 135
50 |
51 | /* Service: BLIDino - Characteristic: MIDI Service - Pipe: TX */
52 | #define PIPE_BLIDINO_MIDI_SERVICE_TX 1
53 | #define PIPE_BLIDINO_MIDI_SERVICE_TX_MAX_SIZE 20
54 |
55 | /* Service: BLIDino - Characteristic: MIDI Service - Pipe: RX */
56 | #define PIPE_BLIDINO_MIDI_SERVICE_RX 2
57 | #define PIPE_BLIDINO_MIDI_SERVICE_RX_MAX_SIZE 20
58 |
59 | /* Service: BLIDino - Characteristic: MIDI Service - Pipe: SET */
60 | #define PIPE_BLIDINO_MIDI_SERVICE_SET 3
61 | #define PIPE_BLIDINO_MIDI_SERVICE_SET_MAX_SIZE 20
62 |
63 |
64 | #define NUMBER_OF_PIPES 3
65 |
66 | #define SERVICES_PIPE_TYPE_MAPPING_CONTENT {\
67 | {ACI_STORE_LOCAL, ACI_TX}, \
68 | {ACI_STORE_LOCAL, ACI_RX}, \
69 | {ACI_STORE_LOCAL, ACI_SET}, \
70 | }
71 |
72 | #define GAP_PPCP_MAX_CONN_INT 0xc /**< Maximum connection interval as a multiple of 1.25 msec , 0xFFFF means no specific value requested */
73 | #define GAP_PPCP_MIN_CONN_INT 0x6 /**< Minimum connection interval as a multiple of 1.25 msec , 0xFFFF means no specific value requested */
74 | #define GAP_PPCP_SLAVE_LATENCY 0
75 | #define GAP_PPCP_CONN_TIMEOUT 0xffff /** Connection Supervision timeout multiplier as a multiple of 10msec, 0xFFFF means no specific value requested */
76 |
77 | #define NB_SETUP_MESSAGES 18
78 | #define SETUP_MESSAGES_CONTENT {\
79 | {0x00,\
80 | {\
81 | 0x07,0x06,0x00,0x00,0x03,0x02,0x41,0xfe,\
82 | },\
83 | },\
84 | {0x00,\
85 | {\
86 | 0x1f,0x06,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x03,0x01,0x01,0x00,0x00,0x06,0x00,0x00,\
87 | 0xd0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0e,\
88 | },\
89 | },\
90 | {0x00,\
91 | {\
92 | 0x1f,0x06,0x10,0x1c,0x5a,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
93 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x03,0x90,0x02,0xff,\
94 | },\
95 | },\
96 | {0x00,\
97 | {\
98 | 0x1f,0x06,0x10,0x38,0xff,0xff,0x02,0x58,0x0a,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x00,0x00,\
99 | 0x00,0x14,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0x00,0x00,0x00,\
100 | },\
101 | },\
102 | {0x00,\
103 | {\
104 | 0x05,0x06,0x10,0x54,0x00,0x00,\
105 | },\
106 | },\
107 | {0x00,\
108 | {\
109 | 0x1f,0x06,0x20,0x00,0x04,0x04,0x02,0x02,0x00,0x01,0x28,0x00,0x01,0x00,0x18,0x04,0x04,0x05,0x05,0x00,\
110 | 0x02,0x28,0x03,0x01,0x02,0x03,0x00,0x00,0x2a,0x04,0x04,0x14,\
111 | },\
112 | },\
113 | {0x00,\
114 | {\
115 | 0x1f,0x06,0x20,0x1c,0x07,0x00,0x03,0x2a,0x00,0x01,0x42,0x4c,0x49,0x44,0x49,0x6e,0x6f,0x65,0x6d,0x69,\
116 | 0x2e,0x63,0x6f,0x6d,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x04,\
117 | },\
118 | },\
119 | {0x00,\
120 | {\
121 | 0x1f,0x06,0x20,0x38,0x05,0x05,0x00,0x04,0x28,0x03,0x01,0x02,0x05,0x00,0x01,0x2a,0x06,0x04,0x03,0x02,\
122 | 0x00,0x05,0x2a,0x01,0x01,0x00,0x00,0x04,0x04,0x05,0x05,0x00,\
123 | },\
124 | },\
125 | {0x00,\
126 | {\
127 | 0x1f,0x06,0x20,0x54,0x06,0x28,0x03,0x01,0x02,0x07,0x00,0x04,0x2a,0x06,0x04,0x09,0x08,0x00,0x07,0x2a,\
128 | 0x04,0x01,0x06,0x00,0x0c,0x00,0x00,0x00,0xff,0xff,0x04,0x04,\
129 | },\
130 | },\
131 | {0x00,\
132 | {\
133 | 0x1f,0x06,0x20,0x70,0x02,0x02,0x00,0x08,0x28,0x00,0x01,0x01,0x18,0x04,0x04,0x10,0x10,0x00,0x09,0x28,\
134 | 0x00,0x01,0x00,0xc7,0xc4,0x4e,0xe3,0x6c,0x51,0xa7,0x33,0x4b,\
135 | },\
136 | },\
137 | {0x00,\
138 | {\
139 | 0x1f,0x06,0x20,0x8c,0xe8,0xed,0x5a,0x0e,0xb8,0x03,0x04,0x04,0x13,0x13,0x00,0x0a,0x28,0x03,0x01,0x16,\
140 | 0x0b,0x00,0xf3,0x6b,0x10,0x9d,0x66,0xf2,0xa9,0xa1,0x12,0x41,\
141 | },\
142 | },\
143 | {0x00,\
144 | {\
145 | 0x1f,0x06,0x20,0xa8,0x68,0x38,0xdb,0xe5,0x72,0x77,0x54,0x14,0x14,0x00,0x00,0x0b,0xe5,0xdb,0x03,0x00,\
146 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
147 | },\
148 | },\
149 | {0x00,\
150 | {\
151 | 0x16,0x06,0x20,0xc4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x14,0x03,0x02,0x00,0x0c,0x29,0x02,0x01,\
152 | 0x00,0x00,0x00,\
153 | },\
154 | },\
155 | {0x00,\
156 | {\
157 | 0x0d,0x06,0x40,0x00,0xe5,0xdb,0x03,0x00,0x8a,0x04,0x00,0x0b,0x00,0x0c,\
158 | },\
159 | },\
160 | {0x00,\
161 | {\
162 | 0x1f,0x06,0x50,0x00,0x00,0xc7,0xc4,0x4e,0xe3,0x6c,0x51,0xa7,0x33,0x4b,0xe8,0xed,0x00,0x00,0xb8,0x03,\
163 | 0xf3,0x6b,0x10,0x9d,0x66,0xf2,0xa9,0xa1,0x12,0x41,0x68,0x38,\
164 | },\
165 | },\
166 | {0x00,\
167 | {\
168 | 0x07,0x06,0x50,0x1c,0x00,0x00,0x72,0x77,\
169 | },\
170 | },\
171 | {0x00,\
172 | {\
173 | 0x06,0x06,0x60,0x00,0x00,0x00,0x00,\
174 | },\
175 | },\
176 | {0x00,\
177 | {\
178 | 0x06,0x06,0xf0,0x00,0x03,0x84,0xcb,\
179 | },\
180 | },\
181 | }
182 |
183 | #endif
184 |
--------------------------------------------------------------------------------
/Legacy Projects/nRF8001-BLE-Proto/RBL_nRF8001/examples/BLEFirmataSketch/BLEFirmata.h:
--------------------------------------------------------------------------------
1 | /*
2 | Firmata.h - Firmata library
3 | Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved.
4 |
5 | This library is free software; you can redistribute it and/or
6 | modify it under the terms of the GNU Lesser General Public
7 | License as published by the Free Software Foundation; either
8 | version 2.1 of the License, or (at your option) any later version.
9 |
10 | See file LICENSE.txt for further informations on licensing terms.
11 | */
12 |
13 | #ifndef BleFirmata_h
14 | #define BleFirmata_h
15 |
16 | #include "Boards.h" /* Hardware Abstraction Layer + Wiring/Arduino */
17 |
18 | /* Version numbers for the protocol. The protocol is still changing, so these
19 | * version numbers are important. This number can be queried so that host
20 | * software can test whether it will be compatible with the currently
21 | * installed firmware. */
22 | #define FIRMATA_MAJOR_VERSION 2 // for non-compatible changes
23 | #define FIRMATA_MINOR_VERSION 3 // for backwards compatible changes
24 | #define FIRMATA_BUGFIX_VERSION 1 // for bugfix releases
25 |
26 | #define MAX_DATA_BYTES 32 // max number of data bytes in non-Sysex messages
27 |
28 | // message command bytes (128-255/0x80-0xFF)
29 | #define DIGITAL_MESSAGE 0x90 // send data for a digital pin
30 | #define ANALOG_MESSAGE 0xE0 // send data for an analog pin (or PWM)
31 | #define REPORT_ANALOG 0xC0 // enable analog input by pin #
32 | #define REPORT_DIGITAL 0xD0 // enable digital input by port pair
33 | //
34 | #define SET_PIN_MODE 0xF4 // set a pin to INPUT/OUTPUT/PWM/etc
35 | //
36 | #define REPORT_VERSION 0xF9 // report protocol version
37 | #define SYSTEM_RESET 0xFF // reset from MIDI
38 | //
39 | #define START_SYSEX 0xF0 // start a MIDI Sysex message
40 | #define END_SYSEX 0xF7 // end a MIDI Sysex message
41 |
42 | // extended command set using sysex (0-127/0x00-0x7F)
43 | /* 0x00-0x0F reserved for user-defined commands */
44 | #define SERVO_CONFIG 0x70 // set max angle, minPulse, maxPulse, freq
45 | #define STRING_DATA 0x71 // a string message with 14-bits per char
46 | #define SHIFT_DATA 0x75 // a bitstream to/from a shift register
47 | #define I2C_REQUEST 0x76 // send an I2C read/write request
48 | #define I2C_REPLY 0x77 // a reply to an I2C read request
49 | #define I2C_CONFIG 0x78 // config I2C settings such as delay times and power pins
50 | #define EXTENDED_ANALOG 0x6F // analog write (PWM, Servo, etc) to any pin
51 | #define PIN_STATE_QUERY 0x6D // ask for a pin's current mode and value
52 | #define PIN_STATE_RESPONSE 0x6E // reply with pin's current mode and value
53 | #define CAPABILITY_QUERY 0x6B // ask for supported modes and resolution of all pins
54 | #define CAPABILITY_RESPONSE 0x6C // reply with supported modes and resolution
55 | #define ANALOG_MAPPING_QUERY 0x69 // ask for mapping of analog to pin numbers
56 | #define ANALOG_MAPPING_RESPONSE 0x6A // reply with mapping info
57 | #define REPORT_FIRMWARE 0x79 // report name and version of the firmware
58 | #define SAMPLING_INTERVAL 0x7A // set the poll rate of the main loop
59 | #define SYSEX_NON_REALTIME 0x7E // MIDI Reserved for non-realtime messages
60 | #define SYSEX_REALTIME 0x7F // MIDI Reserved for realtime messages
61 | // these are DEPRECATED to make the naming more consistent
62 | #define FIRMATA_STRING 0x71 // same as STRING_DATA
63 | #define SYSEX_I2C_REQUEST 0x76 // same as I2C_REQUEST
64 | #define SYSEX_I2C_REPLY 0x77 // same as I2C_REPLY
65 | #define SYSEX_SAMPLING_INTERVAL 0x7A // same as SAMPLING_INTERVAL
66 |
67 | // pin modes
68 | //#define INPUT 0x00 // defined in wiring.h
69 | //#define OUTPUT 0x01 // defined in wiring.h
70 | #define ANALOG 0x02 // analog pin in analogInput mode
71 | #define PWM 0x03 // digital pin in PWM output mode
72 | #define SERVO 0x04 // digital pin in Servo output mode
73 | #define SHIFT 0x05 // shiftIn/shiftOut mode
74 | #define I2C 0x06 // pin included in I2C setup
75 | #define TOTAL_PIN_MODES 7
76 |
77 | extern "C" {
78 | // callback function types
79 | typedef void (*callbackFunction)(byte, int);
80 | typedef void (*systemResetCallbackFunction)(void);
81 | typedef void (*stringCallbackFunction)(char*);
82 | typedef void (*sysexCallbackFunction)(byte command, byte argc, byte*argv);
83 | }
84 |
85 |
86 | // TODO make it a subclass of a generic Serial/Stream base class
87 | class BleFirmataClass
88 | {
89 | public:
90 | BleFirmataClass(Stream &s);
91 | /* Arduino constructors */
92 | void begin();
93 | void begin(long);
94 | void begin(Stream &s);
95 | /* querying functions */
96 | void printVersion(void);
97 | void blinkVersion(void);
98 | void printFirmwareVersion(void);
99 | //void setFirmwareVersion(byte major, byte minor); // see macro below
100 | void setFirmwareNameAndVersion(const char *name, byte major, byte minor);
101 | /* serial receive handling */
102 | int available(void);
103 | void processInput(void);
104 | /* serial send handling */
105 | void sendAnalog(byte pin, int value);
106 | void sendDigital(byte pin, int value); // TODO implement this
107 | void sendDigitalPort(byte portNumber, int portData);
108 | void sendString(const char* string);
109 | void sendString(byte command, const char* string);
110 | void sendSysex(byte command, byte bytec, byte* bytev);
111 | /* attach & detach callback functions to messages */
112 | void attach(byte command, callbackFunction newFunction);
113 | void attach(byte command, systemResetCallbackFunction newFunction);
114 | void attach(byte command, stringCallbackFunction newFunction);
115 | void attach(byte command, sysexCallbackFunction newFunction);
116 | void detach(byte command);
117 |
118 | private:
119 | Stream &BleFirmataSerial;
120 | /* firmware name and version */
121 | byte firmwareVersionCount;
122 | byte *firmwareVersionVector;
123 | /* input message handling */
124 | byte waitForData; // this flag says the next serial input will be data
125 | byte executeMultiByteCommand; // execute this after getting multi-byte data
126 | byte multiByteChannel; // channel data for multiByteCommands
127 | byte storedInputData[MAX_DATA_BYTES]; // multi-byte data
128 | /* sysex */
129 | boolean parsingSysex;
130 | int sysexBytesRead;
131 | /* callback functions */
132 | callbackFunction currentAnalogCallback;
133 | callbackFunction currentDigitalCallback;
134 | callbackFunction currentReportAnalogCallback;
135 | callbackFunction currentReportDigitalCallback;
136 | callbackFunction currentPinModeCallback;
137 | systemResetCallbackFunction currentSystemResetCallback;
138 | stringCallbackFunction currentStringCallback;
139 | sysexCallbackFunction currentSysexCallback;
140 |
141 | /* private methods ------------------------------ */
142 | void processSysexMessage(void);
143 | void systemReset(void);
144 | void pin13strobe(int count, int onInterval, int offInterval);
145 | void sendValueAsTwo7bitBytes(int value);
146 | void startSysex(void);
147 | void endSysex(void);
148 | };
149 |
150 | extern BleFirmataClass BleFirmata;
151 |
152 | /*==============================================================================
153 | * MACROS
154 | *============================================================================*/
155 |
156 | /* shortcut for setFirmwareNameAndVersion() that uses __FILE__ to set the
157 | * firmware name. It needs to be a macro so that __FILE__ is included in the
158 | * firmware source file rather than the library source file.
159 | */
160 | #define setFirmwareVersion(x, y) setFirmwareNameAndVersion(__FILE__, x, y)
161 |
162 | #endif /* Firmata_h */
163 |
164 |
--------------------------------------------------------------------------------
/nRF51822-BLEMIDI/projectconfig.h:
--------------------------------------------------------------------------------
1 | /* mbed Microcontroller Library
2 | * Copyright (c) 2006-2013 ARM Limited
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | #ifndef _PROJECTCONFIG_H_
18 | #define _PROJECTCONFIG_H_
19 |
20 | /*=========================================================================
21 | MCU & BOARD SELCTION
22 |
23 | CFG_BOARD is one of the value defined in board.h
24 | -----------------------------------------------------------------------*/
25 | #define CFG_BOARD BOARD_PCA10001
26 | #define CFG_MCU_STRING "nRF51822"
27 | /*=========================================================================*/
28 |
29 |
30 | /*=========================================================================
31 | CODE BASE VERSION SETTINGS
32 |
33 | Please do not modify this version number. To set a version number
34 | for your project or firmware, change the values in your 'boards/'
35 | config file.
36 | -----------------------------------------------------------------------*/
37 | #define CFG_CODEBASE_VERSION_MAJOR 0
38 | #define CFG_CODEBASE_VERSION_MINOR 1
39 | #define CFG_CODEBASE_VERSION_REVISION 0
40 | /*=========================================================================*/
41 |
42 |
43 | /*=========================================================================
44 | FIRMWARE VERSION SETTINGS
45 | -----------------------------------------------------------------------*/
46 | #define CFG_FIRMWARE_VERSION_MAJOR 0
47 | #define CFG_FIRMWARE_VERSION_MINOR 0
48 | #define CFG_FIRMWARE_VERSION_REVISION 0
49 | /*=========================================================================*/
50 |
51 |
52 | /*=========================================================================
53 | DEBUG LEVEL
54 | -----------------------------------------------------------------------
55 |
56 | CFG_DEBUG Level 3: Full debug output, any failed assert
57 | will produce a breakpoint for the
58 | debugger
59 | Level 2: ATTR_ALWAYS_INLINE is null, ASSERT
60 | has text
61 | Level 1: ATTR_ALWAYS_INLINE is an attribute,
62 | ASSERT has no text
63 | Level 0: No debug information generated
64 |
65 | -----------------------------------------------------------------------*/
66 | #define CFG_DEBUG (1)
67 |
68 | #if (CFG_DEBUG > 3) || (CFG_DEBUG < 0)
69 | #error "CFG_DEBUG must be a value between 0 (no debug) and 3"
70 | #endif
71 | /*=========================================================================*/
72 |
73 |
74 | /*=========================================================================
75 | GENERAL NRF51 PERIPHERAL SETTINGS
76 | -----------------------------------------------------------------------
77 |
78 | CFG_SCHEDULER_ENABLE Set this to 'true' or 'false' depending on
79 | if you use the event scheduler or not
80 |
81 | -----------------------------------------------------------------------*/
82 | #define CFG_SCHEDULER_ENABLE false
83 |
84 | /*------------------------------- GPIOTE ------------------------------*/
85 | #define CFG_GPIOTE_MAX_USERS 4 /**< Maximum number of users of the GPIOTE handler. */
86 |
87 | /*-------------------------------- TIMER ------------------------------*/
88 | #define CFG_TIMER_PRESCALER 0 /**< Value of the RTC1 PRESCALER register. freq = (32768/(PRESCALER+1)) */
89 | #define CFG_TIMER_MAX_INSTANCE 8 /**< Maximum number of simultaneously created timers. */
90 | #define CFG_TIMER_OPERATION_QUEUE_SIZE 5 /**< Size of timer operation queues. */
91 | /*=========================================================================*/
92 |
93 |
94 | /*=========================================================================
95 | BTLE SETTINGS
96 | -----------------------------------------------------------------------*/
97 |
98 | #define CFG_BLE_TX_POWER_LEVEL 4 /**< in dBm (Valid values are -40, -20, -16, -12, -8, -4, 0, 4) */
99 |
100 | /*---------------------------- BOND MANAGER ---------------------------*/
101 | #define CFG_BLE_BOND_FLASH_PAGE_BOND (BLE_FLASH_PAGE_END-1) /**< Flash page used for bond manager bonding information.*/
102 | #define CFG_BLE_BOND_FLASH_PAGE_SYS_ATTR (BLE_FLASH_PAGE_END-3) /**< Flash page used for bond manager system attribute information. TODO check if we can use BLE_FLASH_PAGE_END-2*/
103 | #define CFG_BLE_BOND_DELETE_BUTTON_NUM 0 /**< Button to press to delete bond details during init */
104 |
105 | /*------------------------------ SECURITY -----------------------------*/
106 | #define CFG_BLE_SEC_PARAM_MITM 0 /**< Man In The Middle protection not required. */
107 | #define CFG_BLE_SEC_PARAM_IO_CAPABILITIES BLE_GAP_IO_CAPS_NONE /**< No I/O capabilities. */
108 | #define CFG_BLE_SEC_PARAM_OOB 0 /**< Out Of Band data not available. */
109 | #define CFG_BLE_SEC_PARAM_MIN_KEY_SIZE 7 /**< Minimum encryption key size. */
110 | #define CFG_BLE_SEC_PARAM_MAX_KEY_SIZE 16
111 |
112 | /*--------------------------------- GAP -------------------------------*/
113 | #define CFG_GAP_APPEARANCE BLE_APPEARANCE_GENERIC_TAG
114 | #define CFG_GAP_LOCAL_NAME "nRF5x"
115 |
116 | #define CFG_GAP_CONNECTION_MIN_INTERVAL_MS 8 /**< Minimum acceptable connection interval */
117 | #define CFG_GAP_CONNECTION_MAX_INTERVAL_MS 15 /**< Maximum acceptable connection interval */
118 | #define CFG_GAP_CONNECTION_SUPERVISION_TIMEOUT_MS 2000 /**< Connection supervisory timeout */
119 | #define CFG_GAP_CONNECTION_SLAVE_LATENCY 0 /**< Slave Latency in number of connection events. */
120 |
121 | #define CFG_GAP_ADV_INTERVAL_MS 250 /**< The advertising interval in miliseconds, should be multiply of 0.625 */
122 | #define CFG_GAP_ADV_TIMEOUT_S 180 /**< The advertising timeout in units of seconds. */
123 | /*=========================================================================*/
124 |
125 |
126 | /*=========================================================================
127 | VALIDATION
128 | -----------------------------------------------------------------------*/
129 | #if CFG_BLE_TX_POWER_LEVEL != -40 && CFG_BLE_TX_POWER_LEVEL != -20 && CFG_BLE_TX_POWER_LEVEL != -16 && CFG_BLE_TX_POWER_LEVEL != -12 && CFG_BLE_TX_POWER_LEVEL != -8 && CFG_BLE_TX_POWER_LEVEL != -4 && CFG_BLE_TX_POWER_LEVEL != 0 && CFG_BLE_TX_POWER_LEVEL != 4
130 | #error "CFG_BLE_TX_POWER_LEVEL must be -40, -20, -16, -12, -8, -4, 0 or 4"
131 | #endif
132 | /*=========================================================================*/
133 |
134 | #endif /* _PROJECTCONFIG_H_ */
135 |
--------------------------------------------------------------------------------
/Legacy Projects/nRF8001-BLE-Proto/nRF8001-BLE-Proto.ino:
--------------------------------------------------------------------------------
1 | /*
2 | *******************************************************************************
3 | * USB-MIDI dump utility
4 | * Copyright 2013 Yuuichi Akagawa
5 | *
6 | * for use with USB Host Shield 2.0 from Circuitsathome.com
7 | * https://github.com/felis/USB_Host_Shield_2.0
8 | *
9 | * This is sample program. Do not expect perfect behavior.
10 | *******************************************************************************
11 | * This program is free software; you can redistribute it and/or modify
12 | * it under the terms of the GNU General Public License as published by
13 | * the Free Software Foundation; either version 2 of the License, or
14 | * (at your option) any later version.
15 | *
16 | * This program is distributed in the hope that it will be useful,
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | * GNU General Public License for more details.
20 | *
21 | * You should have received a copy of the GNU General Public License
22 | * along with this program. If not, see
23 | *******************************************************************************
24 | */
25 |
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include
32 |
33 | // Activate to debug
34 | // this increases delay significantly due to increased I/Os
35 | #define DEBUG 1
36 |
37 | #ifdef DEBUG
38 | #define DEBUG_PRINT(x) Serial.print (x)
39 | #define DEBUG_PRINTDEC(x) Serial.print (x, DEC)
40 | #define DEBUG_PRINTHEX(x) Serial.print (x, HEX)
41 | #define DEBUG_PRINTLN(x) Serial.println (x)
42 | #else
43 | #define DEBUG_PRINT(x)
44 | #define DEBUG_PRINTDEC(x)
45 | #define DEBUG_PRINTHEX(x)
46 | #define DEBUG_PRINTLN(x)
47 | #endif
48 |
49 |
50 | /*******************************************************************************
51 | * INITIALIZE USB MIDI Variables
52 | *******************************************************************************/
53 | USB Usb;
54 | USBH_MIDI Midi(&Usb);
55 | uint8_t usbstate;
56 | uint8_t laststate;
57 | uint8_t rcode;
58 | //uint8_t buf[sizeof(USB_DEVICE_DESCRIPTOR)];
59 | USB_DEVICE_DESCRIPTOR buf;
60 |
61 | void MIDI_poll();
62 | void doDelay(unsigned long t1, unsigned long t2, unsigned long delayTime);
63 |
64 | boolean bFirst;
65 | uint16_t pid, vid;
66 |
67 | /*******************************************************************************
68 | * INITIALIZE Internal BLE Buffer
69 | *******************************************************************************/
70 | #define MAX_TX_BUFF 64
71 | static uint8_t midiOut_buff[MAX_TX_BUFF];
72 | static uint8_t midiOut_buff_len = 0;
73 |
74 |
75 | /*******************************************************************************
76 | * Setup USB Shield and Bluetooth Chip (nRF8001)
77 | *******************************************************************************/
78 |
79 | void setup()
80 | {
81 |
82 |
83 | bFirst = true;
84 | vid = pid = 0;
85 | #ifdef DEBUG
86 | Serial.begin(115200);
87 | #endif
88 | // while (!Serial);
89 | //Workaround for non UHS2.0 Shield
90 | pinMode(10,OUTPUT);
91 | digitalWrite(10,HIGH);
92 |
93 | DEBUG_PRINTLN("BLE Arduino Slave");
94 | Usb.Init();
95 | delay( 200 );
96 |
97 | // if (Usb.Init() == -1) {
98 | // while(1); //halt
99 | // }//if (Usb.Init() == -1...
100 | SPI.begin();
101 | ble_begin();
102 | ble_do_events();
103 | }
104 |
105 | /*******************************************************************************
106 | * Main Runloop
107 | *
108 | * Polls MIDI and BLE Data when SPI bus available
109 | *******************************************************************************/
110 |
111 | void loop()
112 | {
113 | unsigned long t1;
114 |
115 | // BLE not on SPI, go ahead
116 | if (!ble_busy()) {
117 |
118 | Usb.Task();
119 | /* usbstate = Usb.getUsbTaskState();
120 |
121 | if (usbstate != laststate) {
122 | laststate = usbstate;
123 |
124 | switch (usbstate) {
125 | case( USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE):
126 | E_Notify(PSTR("\r\nWaiting for device..."), 0x80);
127 | break;
128 | case( USB_ATTACHED_SUBSTATE_RESET_DEVICE):
129 | E_Notify(PSTR("\r\nDevice connected. Resetting..."), 0x80);
130 | break;
131 | case( USB_ATTACHED_SUBSTATE_WAIT_SOF):
132 | E_Notify(PSTR("\r\nReset complete. Waiting for the first SOF..."), 0x80);
133 | break;
134 | case( USB_ATTACHED_SUBSTATE_GET_DEVICE_DESCRIPTOR_SIZE):
135 | E_Notify(PSTR("\r\nSOF generation started. Enumerating device..."), 0x80);
136 | break;
137 | case( USB_STATE_ADDRESSING):
138 | E_Notify(PSTR("\r\nSetting device address..."), 0x80);
139 | break;
140 | case( USB_STATE_RUNNING):
141 | E_Notify(PSTR("\r\nGetting device descriptor"), 0x80);
142 | rcode = Usb.getDevDescr(1, 0, sizeof (USB_DEVICE_DESCRIPTOR), (uint8_t*) & buf);
143 |
144 | if (rcode) {
145 | E_Notify(PSTR("\r\nError reading device descriptor. Error code "), 0x80);
146 | // print_hex(rcode, 8);
147 | }
148 | else {
149 |
150 | E_Notify(PSTR("\r\nDescriptor Length:\t"), 0x80);
151 | print_hex(buf.bLength, 8);
152 | E_Notify(PSTR("\r\nDescriptor type:\t"), 0x80);
153 | print_hex(buf.bDescriptorType, 8);
154 | E_Notify(PSTR("\r\nUSB version:\t\t"), 0x80);
155 | print_hex(buf.bcdUSB, 16);
156 | E_Notify(PSTR("\r\nDevice class:\t\t"), 0x80);
157 | print_hex(buf.bDeviceClass, 8);
158 | E_Notify(PSTR("\r\nDevice Subclass:\t"), 0x80);
159 | print_hex(buf.bDeviceSubClass, 8);
160 | E_Notify(PSTR("\r\nDevice Protocol:\t"), 0x80);
161 | print_hex(buf.bDeviceProtocol, 8);
162 | E_Notify(PSTR("\r\nMax.packet size:\t"), 0x80);
163 | print_hex(buf.bMaxPacketSize0, 8);
164 | E_Notify(PSTR("\r\nVendor ID:\t\t"), 0x80);
165 | print_hex(buf.idVendor, 16);
166 | E_Notify(PSTR("\r\nProduct ID:\t\t"), 0x80);
167 | print_hex(buf.idProduct, 16);
168 | E_Notify(PSTR("\r\nRevision ID:\t\t"), 0x80);
169 | print_hex(buf.bcdDevice, 16);
170 | E_Notify(PSTR("\r\nMfg.string index:\t"), 0x80);
171 | print_hex(buf.iManufacturer, 8);
172 | E_Notify(PSTR("\r\nProd.string index:\t"), 0x80);
173 | print_hex(buf.iProduct, 8);
174 | E_Notify(PSTR("\r\nSerial number index:\t"), 0x80);
175 | print_hex(buf.iSerialNumber, 8);
176 | E_Notify(PSTR("\r\nNumber of conf.:\t"), 0x80);
177 | print_hex(buf.bNumConfigurations, 8);
178 |
179 | }
180 | break;
181 | case( USB_STATE_ERROR):
182 | E_Notify(PSTR("\r\nUSB state machine reached error state"), 0x80);
183 | break;
184 |
185 | default:
186 | break;
187 | }//switch( usbstate...
188 | } */
189 |
190 | if( Usb.getUsbTaskState() == USB_STATE_RUNNING )
191 | {
192 | MIDI_poll();
193 |
194 | // TO DO
195 | // Send MIDI to USB Device
196 |
197 | /* if (MIDI.read()) {
198 | msg[0] = MIDI.getType();
199 | if( msg[0] == 0xf0 ) { //SysEX
200 | //TODO
201 | //SysEx implementation
202 | }else{
203 | msg[1] = MIDI.getData1();
204 | msg[2] = MIDI.getData2();
205 | Midi.SendData(msg, 0);
206 | }
207 | */
208 | }
209 |
210 |
211 | }
212 |
213 |
214 | //TO DO:
215 | // Omni-Directional MIDI
216 | /* while(ble_available()) {
217 | midiOut_buff[midiOut_buff_len] = ble_read();
218 | midiOut_buff_len++;
219 | } */
220 |
221 | // Send packets
222 |
223 |
224 | ble_do_events();
225 | }
226 |
227 |
228 |
229 | /*******************************************************************************
230 | * Poll MIDI DATA from USB Port
231 | *******************************************************************************/
232 | void MIDI_poll()
233 | {
234 |
235 | uint8_t bufMidi[64];
236 | uint16_t rcvd;
237 | uint8_t size;
238 | byte outBuf[ 3 ];
239 | char buf[20];
240 |
241 | if(Midi.vid != vid || Midi.pid != pid){
242 | vid = Midi.vid;
243 | pid = Midi.pid;
244 | }
245 |
246 | do {
247 | if( (size=Midi.RecvData(outBuf)) > 0 ){
248 | //MIDI Output
249 | //DEBUG_PRINT("MIDI SIZE: ");
250 | //DEBUG_PRINTLN(size);
251 | /* for(int i=0; i0);
258 |
259 | }
260 |
261 |
262 | /*******************************************************************************
263 | * Convert MIDI Data to MIDI-BLE Packets
264 | *
265 | * TO DO: Implement official specification once released
266 | * as this is based on reverse-engineering
267 | *
268 | *******************************************************************************/
269 | void parseMIDItoAppleBle(int size, byte outBuf[3]) {
270 | char time[2];
271 | char buf[20];
272 |
273 | unsigned long timer = 0;
274 | int lastPos;
275 | timer = millis();
276 |
277 | uint16_t blueMidiTime = 0;
278 | blueMidiTime = 32768 + (timer % 16383);
279 |
280 |
281 | // 0x80 0x80 Prefix Bytes for Apple Protocol
282 | // buffer empty, write apple time prefix
283 | // TO DO:
284 | // Implement correct Apple Time Coding
285 | // 2nd byte (0x80) is temp workaround
286 | if (ble_buff_len() == 0)
287 | {
288 | ble_write(blueMidiTime >> 8);
289 | ble_write(0x80);
290 | for (int i = 0; i < size; i++)
291 | {
292 | ble_write(outBuf[i]);
293 | }
294 |
295 | }
296 | // Buffer already filled, append Packet
297 | // To Do: replace "80" hex seperator with relative timing data?
298 | // or wait for official spec to be released
299 | else if(ble_buff_len() >= 2)
300 | {
301 | int buffL = ble_buff_len();
302 | ble_write(0x80);
303 | for (int i = 0; i < size; i++)
304 | {
305 | ble_write(outBuf[i]);
306 | }
307 |
308 | }
309 |
310 | //DEBUG_PRINT("MIDI SIZE: ");
311 | //DEBUG_PRINTLN(size);
312 | DEBUG_PRINTLN("---- MIDI ----");
313 | for(int i=0; i> (num_nibbles - 1) * 4)) & 0x0f;
342 | DEBUG_PRINTHEX(digit);
343 | }
344 | while (--num_nibbles);
345 | }
346 |
347 |
348 |
349 |
--------------------------------------------------------------------------------
/Legacy Projects/nRF8001-BLE-Proto/RBL_nRF8001/examples/BLEControllerSketch/BLEControllerSketch.ino:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright (c) 2012, 2013 RedBearLab
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6 |
7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
10 |
11 | */
12 |
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include "Boards.h"
18 |
19 | #define PROTOCOL_MAJOR_VERSION 0 //
20 | #define PROTOCOL_MINOR_VERSION 0 //
21 | #define PROTOCOL_BUGFIX_VERSION 2 // bugfix
22 |
23 | #define PIN_CAPABILITY_NONE 0x00
24 | #define PIN_CAPABILITY_DIGITAL 0x01
25 | #define PIN_CAPABILITY_ANALOG 0x02
26 | #define PIN_CAPABILITY_PWM 0x04
27 | #define PIN_CAPABILITY_SERVO 0x08
28 | #define PIN_CAPABILITY_I2C 0x10
29 |
30 | // pin modes
31 | //#define INPUT 0x00 // defined in wiring.h
32 | //#define OUTPUT 0x01 // defined in wiring.h
33 | #define ANALOG 0x02 // analog pin in analogInput mode
34 | #define PWM 0x03 // digital pin in PWM output mode
35 | #define SERVO 0x04 // digital pin in Servo output mode
36 |
37 | byte pin_mode[TOTAL_PINS];
38 | byte pin_state[TOTAL_PINS];
39 | byte pin_pwm[TOTAL_PINS];
40 | byte pin_servo[TOTAL_PINS];
41 |
42 | Servo servos[MAX_SERVOS];
43 |
44 | void setup()
45 | {
46 | Serial.begin(57600);
47 | Serial.println("BLE Arduino Slave");
48 |
49 | /* Default all to digital input */
50 | for (int pin = 0; pin < TOTAL_PINS; pin++)
51 | {
52 | // Set pin to input with internal pull up
53 | pinMode(pin, INPUT);
54 | digitalWrite(pin, HIGH);
55 |
56 | // Save pin mode and state
57 | pin_mode[pin] = INPUT;
58 | pin_state[pin] = LOW;
59 | }
60 |
61 | // Default pins set to 9 and 8 for REQN and RDYN
62 | // Set your REQN and RDYN here before ble_begin() if you need
63 | //ble_set_pins(3, 2);
64 |
65 | // Set your BLE Shield name here, max. length 10
66 | //ble_set_name("My Name");
67 |
68 | // Init. and start BLE library.
69 | ble_begin();
70 | }
71 |
72 | static byte buf_len = 0;
73 |
74 | void ble_write_string(byte *bytes, uint8_t len)
75 | {
76 | if (buf_len + len > 20)
77 | {
78 | for (int j = 0; j < 15000; j++)
79 | ble_do_events();
80 |
81 | buf_len = 0;
82 | }
83 |
84 | for (int j = 0; j < len; j++)
85 | {
86 | ble_write(bytes[j]);
87 | buf_len++;
88 | }
89 |
90 | if (buf_len == 20)
91 | {
92 | for (int j = 0; j < 15000; j++)
93 | ble_do_events();
94 |
95 | buf_len = 0;
96 | }
97 | }
98 |
99 | byte reportDigitalInput()
100 | {
101 | if (!ble_connected())
102 | return 0;
103 |
104 | static byte pin = 0;
105 | byte report = 0;
106 |
107 | if (!IS_PIN_DIGITAL(pin))
108 | {
109 | pin++;
110 | if (pin >= TOTAL_PINS)
111 | pin = 0;
112 | return 0;
113 | }
114 |
115 | if (pin_mode[pin] == INPUT)
116 | {
117 | byte current_state = digitalRead(pin);
118 |
119 | if (pin_state[pin] != current_state)
120 | {
121 | pin_state[pin] = current_state;
122 | byte buf[] = {'G', pin, INPUT, current_state};
123 | ble_write_string(buf, 4);
124 |
125 | report = 1;
126 | }
127 | }
128 |
129 | pin++;
130 | if (pin >= TOTAL_PINS)
131 | pin = 0;
132 |
133 | return report;
134 | }
135 |
136 | void reportPinCapability(byte pin)
137 | {
138 | byte buf[] = {'P', pin, 0x00};
139 | byte pin_cap = 0;
140 |
141 | if (IS_PIN_DIGITAL(pin))
142 | pin_cap |= PIN_CAPABILITY_DIGITAL;
143 |
144 | if (IS_PIN_ANALOG(pin))
145 | pin_cap |= PIN_CAPABILITY_ANALOG;
146 |
147 | if (IS_PIN_PWM(pin))
148 | pin_cap |= PIN_CAPABILITY_PWM;
149 |
150 | if (IS_PIN_SERVO(pin))
151 | pin_cap |= PIN_CAPABILITY_SERVO;
152 |
153 | buf[2] = pin_cap;
154 | ble_write_string(buf, 3);
155 | }
156 |
157 | void reportPinServoData(byte pin)
158 | {
159 | // if (IS_PIN_SERVO(pin))
160 | // servos[PIN_TO_SERVO(pin)].write(value);
161 | // pin_servo[pin] = value;
162 |
163 | byte value = pin_servo[pin];
164 | byte mode = pin_mode[pin];
165 | byte buf[] = {'G', pin, mode, value};
166 | ble_write_string(buf, 4);
167 | }
168 |
169 | byte reportPinAnalogData()
170 | {
171 | if (!ble_connected())
172 | return 0;
173 |
174 | static byte pin = 0;
175 | byte report = 0;
176 |
177 | if (!IS_PIN_DIGITAL(pin))
178 | {
179 | pin++;
180 | if (pin >= TOTAL_PINS)
181 | pin = 0;
182 | return 0;
183 | }
184 |
185 | if (pin_mode[pin] == ANALOG)
186 | {
187 | uint16_t value = analogRead(pin);
188 | byte value_lo = value;
189 | byte value_hi = value>>8;
190 |
191 | byte mode = pin_mode[pin];
192 | mode = (value_hi << 4) | mode;
193 |
194 | byte buf[] = {'G', pin, mode, value_lo};
195 | ble_write_string(buf, 4);
196 | }
197 |
198 | pin++;
199 | if (pin >= TOTAL_PINS)
200 | pin = 0;
201 |
202 | return report;
203 | }
204 |
205 | void reportPinDigitalData(byte pin)
206 | {
207 | byte state = digitalRead(pin);
208 | byte mode = pin_mode[pin];
209 | byte buf[] = {'G', pin, mode, state};
210 | ble_write_string(buf, 4);
211 | }
212 |
213 | void reportPinPWMData(byte pin)
214 | {
215 | byte value = pin_pwm[pin];
216 | byte mode = pin_mode[pin];
217 | byte buf[] = {'G', pin, mode, value};
218 | ble_write_string(buf, 4);
219 | }
220 |
221 | void sendCustomData(uint8_t *buf, uint8_t len)
222 | {
223 | uint8_t data[20] = "Z";
224 | memcpy(&data[1], buf, len);
225 | ble_write_string(data, len+1);
226 | }
227 |
228 | byte queryDone = false;
229 |
230 | void loop()
231 | {
232 | while(ble_available())
233 | {
234 | byte cmd;
235 | cmd = ble_read();
236 | Serial.write(cmd);
237 |
238 | // Parse data here
239 | switch (cmd)
240 | {
241 | case 'V': // query protocol version
242 | {
243 | byte buf[] = {'V', 0x00, 0x00, 0x01};
244 | ble_write_string(buf, 4);
245 | }
246 | break;
247 |
248 | case 'C': // query board total pin count
249 | {
250 | byte buf[2];
251 | buf[0] = 'C';
252 | buf[1] = TOTAL_PINS;
253 | ble_write_string(buf, 2);
254 | }
255 | break;
256 |
257 | case 'M': // query pin mode
258 | {
259 | byte pin = ble_read();
260 | byte buf[] = {'M', pin, pin_mode[pin]}; // report pin mode
261 | ble_write_string(buf, 3);
262 | }
263 | break;
264 |
265 | case 'S': // set pin mode
266 | {
267 | byte pin = ble_read();
268 | byte mode = ble_read();
269 |
270 | if (IS_PIN_SERVO(pin) && mode != SERVO && servos[PIN_TO_SERVO(pin)].attached())
271 | servos[PIN_TO_SERVO(pin)].detach();
272 |
273 | /* ToDo: check the mode is in its capability or not */
274 | /* assume always ok */
275 | if (mode != pin_mode[pin])
276 | {
277 | pinMode(pin, mode);
278 | pin_mode[pin] = mode;
279 |
280 | if (mode == OUTPUT)
281 | {
282 | digitalWrite(pin, LOW);
283 | pin_state[pin] = LOW;
284 | }
285 | else if (mode == INPUT)
286 | {
287 | digitalWrite(pin, HIGH);
288 | pin_state[pin] = HIGH;
289 | }
290 | else if (mode == ANALOG)
291 | {
292 | if (IS_PIN_ANALOG(pin)) {
293 | if (IS_PIN_DIGITAL(pin)) {
294 | pinMode(PIN_TO_DIGITAL(pin), LOW);
295 | }
296 | }
297 | }
298 | else if (mode == PWM)
299 | {
300 | if (IS_PIN_PWM(pin))
301 | {
302 | pinMode(PIN_TO_PWM(pin), OUTPUT);
303 | analogWrite(PIN_TO_PWM(pin), 0);
304 | pin_pwm[pin] = 0;
305 | pin_mode[pin] = PWM;
306 | }
307 | }
308 | else if (mode == SERVO)
309 | {
310 | if (IS_PIN_SERVO(pin))
311 | {
312 | pin_servo[pin] = 0;
313 | pin_mode[pin] = SERVO;
314 | if (!servos[PIN_TO_SERVO(pin)].attached())
315 | servos[PIN_TO_SERVO(pin)].attach(PIN_TO_DIGITAL(pin));
316 | }
317 | }
318 | }
319 |
320 | // if (mode == ANALOG)
321 | // reportPinAnalogData(pin);
322 | if ( (mode == INPUT) || (mode == OUTPUT) )
323 | reportPinDigitalData(pin);
324 | else if (mode == PWM)
325 | reportPinPWMData(pin);
326 | else if (mode == SERVO)
327 | reportPinServoData(pin);
328 | }
329 | break;
330 |
331 | case 'G': // query pin data
332 | {
333 | byte pin = ble_read();
334 | reportPinDigitalData(pin);
335 | }
336 | break;
337 |
338 | case 'T': // set pin digital state
339 | {
340 | byte pin = ble_read();
341 | byte state = ble_read();
342 |
343 | digitalWrite(pin, state);
344 | reportPinDigitalData(pin);
345 | }
346 | break;
347 |
348 | case 'N': // set PWM
349 | {
350 | byte pin = ble_read();
351 | byte value = ble_read();
352 |
353 | analogWrite(PIN_TO_PWM(pin), value);
354 | pin_pwm[pin] = value;
355 | reportPinPWMData(pin);
356 | }
357 | break;
358 |
359 | case 'O': // set Servo
360 | {
361 | byte pin = ble_read();
362 | byte value = ble_read();
363 |
364 | if (IS_PIN_SERVO(pin))
365 | servos[PIN_TO_SERVO(pin)].write(value);
366 | pin_servo[pin] = value;
367 | reportPinServoData(pin);
368 | }
369 | break;
370 |
371 | case 'A': // query all pin status
372 | for (int pin = 0; pin < TOTAL_PINS; pin++)
373 | {
374 | reportPinCapability(pin);
375 | if ( (pin_mode[pin] == INPUT) || (pin_mode[pin] == OUTPUT) )
376 | reportPinDigitalData(pin);
377 | else if (pin_mode[pin] == PWM)
378 | reportPinPWMData(pin);
379 | else if (pin_mode[pin] == SERVO)
380 | reportPinServoData(pin);
381 | }
382 |
383 | queryDone = true;
384 | {
385 | uint8_t str[] = "ABC";
386 | sendCustomData(str, 3);
387 | }
388 |
389 | break;
390 |
391 | case 'P': // query pin capability
392 | {
393 | byte pin = ble_read();
394 | reportPinCapability(pin);
395 | }
396 | break;
397 |
398 | case 'Z':
399 | {
400 | byte len = ble_read();
401 | byte buf[len];
402 | for (int i=0;i");
405 | Serial.print("Received: ");
406 | Serial.print(len);
407 | Serial.println(" byte(s)");
408 | Serial.print(" Hex: ");
409 | for (int i=0;i
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include "BLEParser.h"
29 |
30 |
31 | #define TXRX_BUF_LEN 20
32 | #define RX_BUF_LEN 20 /** Overwriting RX Buf Len since we handle fragmentation **/
33 |
34 | BLE ble;
35 | Ticker sendTicker;
36 | Ticker usbTicker;
37 | mfk::midi::BLEMIDIParser<256, USBH_MIDI> parser;
38 |
39 | static uint8_t rx_buf[RX_BUF_LEN];
40 | static int rx_buf_num, rx_state = 0;
41 | static uint8_t rx_temp_buf[20];
42 | uint8_t outBufMidi[128];
43 | int outBufMidiPtr;
44 |
45 | // MIDI BLE Service UUIDs
46 | static const uint8_t uart_base_uuid[] = {0x03, 0xB8, 0x0E, 0x5A, 0xED, 0xE8, 0x4B, 0x33, 0xA7, 0x51, 0x6C, 0xE3, 0x4E, 0xC4, 0xC7, 0};
47 | static const uint8_t uart_tx_uuid[] = {0x77, 0x72, 0xE5, 0xDB, 0x38, 0x68, 0x41, 0x12, 0xA1, 0xA9, 0xF2, 0x66, 0x9D, 0x10, 0x6B, 0xF3};
48 | static const uint8_t uart_rx_uuid[] = {0x77, 0x72, 0xE5, 0xDB, 0x38, 0x68, 0x41, 0x12, 0xA1, 0xA9, 0xF2, 0x66, 0x9D, 0x10, 0x6B, 0xF3};
49 | static const uint8_t uart_base_uuid_rev[] = {0, 0xC7, 0xC4, 0x4E, 0xE3, 0x6C, 0x51, 0xA7, 0x33, 0x4B, 0xE8, 0xED, 0x5A, 0x0E, 0xB8, 0x03};
50 |
51 |
52 |
53 | uint8_t txPayload[TXRX_BUF_LEN] = {0,};
54 | uint8_t rxPayload[TXRX_BUF_LEN] = {0,};
55 |
56 | GattCharacteristic txCharacteristic
57 | (uart_tx_uuid, txPayload, 1, 20,
58 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE |
59 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE |
60 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY |
61 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ);
62 |
63 | GattCharacteristic *uartChars[] = {&txCharacteristic};
64 | GattService uartService(uart_base_uuid, uartChars,
65 | sizeof(uartChars) / sizeof(GattCharacteristic *));
66 |
67 | /*******************************************************************************
68 | * INITIALIZE USB MIDI Variables
69 | *******************************************************************************/
70 | USB Usb;
71 | USBH_MIDI Midi(&Usb);
72 | uint8_t usbstate;
73 | uint8_t laststate;
74 | uint8_t rcode;
75 | USB_DEVICE_DESCRIPTOR buf;
76 |
77 | void MIDI_poll();
78 |
79 | boolean bFirst;
80 | boolean isConnected;
81 | boolean isSysex;
82 | uint16_t pid, vid;
83 | int bufferInUse=0;
84 |
85 | /*******************************************************************************
86 | * INITIALIZE Internal BLE Buffer
87 | *******************************************************************************/
88 | #define MAX_TX_BUFF 64
89 | static uint8_t midiOut_buff[MAX_TX_BUFF];
90 | static uint8_t midiOut_buff_len = 0;
91 |
92 |
93 |
94 | /*******************************************************************************
95 | * Send MIDI data to BLE Stack
96 | *******************************************************************************/
97 | void sendData(void)
98 | {
99 | if(rx_buf_num > 0 && isConnected)
100 | {
101 | int bufInc = 0;
102 | if (rx_buf_num < 17)
103 | {
104 | bufInc = rx_buf_num % 17; }
105 | else
106 | {
107 | bufInc = 17;
108 | }
109 | ble.updateCharacteristicValue(txCharacteristic.getValueAttribute().getHandle(), rx_buf, bufInc);
110 | memmove(rx_buf, rx_buf+bufInc, rx_buf_num-bufInc); // probably not best practice? needs to be fixed
111 | rx_buf_num -= bufInc;
112 | rx_state = 0;
113 | }
114 | }
115 |
116 |
117 | /*******************************************************************************
118 | * Initialize USB Communication
119 | *******************************************************************************/
120 | void m_status_check_handle(void)
121 | {
122 |
123 | Usb.Task();
124 | usbstate = Usb.getUsbTaskState();
125 |
126 | if (usbstate != laststate)
127 | {
128 | laststate = usbstate;
129 |
130 | switch (usbstate)
131 | {
132 | case ( USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE):
133 | E_Notify(PSTR("\r\nWaiting for device..."), 0x80);
134 | break;
135 | case ( USB_ATTACHED_SUBSTATE_RESET_DEVICE):
136 | E_Notify(PSTR("\r\nDevice connected. Resetting..."), 0x80);
137 | break;
138 | case ( USB_ATTACHED_SUBSTATE_WAIT_SOF):
139 | E_Notify(PSTR("\r\nReset complete. Waiting for the first SOF..."), 0x80);
140 | break;
141 | case ( USB_ATTACHED_SUBSTATE_GET_DEVICE_DESCRIPTOR_SIZE):
142 | E_Notify(PSTR("\r\nSOF generation started. Enumerating device..."), 0x80);
143 | break;
144 | case ( USB_STATE_ADDRESSING):
145 | E_Notify(PSTR("\r\nSetting device address..."), 0x80);
146 | break;
147 | case ( USB_STATE_RUNNING):
148 | E_Notify(PSTR("\r\nGetting device descriptor"), 0x80);
149 | rcode = Usb.getDevDescr(1, 0, sizeof (USB_DEVICE_DESCRIPTOR), (uint8_t*) & buf);
150 |
151 | if (rcode)
152 | {
153 | E_Notify(PSTR("\r\nError reading device descriptor. Error code "), 0x80);
154 | // print_hex(rcode, 8);
155 | }
156 | else
157 | {
158 | E_Notify(PSTR("\r\nDescriptor Length:\t"), 0x80);
159 | print_hex(buf.bLength, 8);
160 | E_Notify(PSTR("\r\nDescriptor type:\t"), 0x80);
161 | print_hex(buf.bDescriptorType, 8);
162 | E_Notify(PSTR("\r\nUSB version:\t\t"), 0x80);
163 | print_hex(buf.bcdUSB, 16);
164 | E_Notify(PSTR("\r\nDevice class:\t\t"), 0x80);
165 | print_hex(buf.bDeviceClass, 8);
166 | E_Notify(PSTR("\r\nDevice Subclass:\t"), 0x80);
167 | print_hex(buf.bDeviceSubClass, 8);
168 | E_Notify(PSTR("\r\nDevice Protocol:\t"), 0x80);
169 | print_hex(buf.bDeviceProtocol, 8);
170 | E_Notify(PSTR("\r\nMax.packet size:\t"), 0x80);
171 | print_hex(buf.bMaxPacketSize0, 8);
172 | E_Notify(PSTR("\r\nVendor ID:\t\t"), 0x80);
173 | print_hex(buf.idVendor, 16);
174 | E_Notify(PSTR("\r\nProduct ID:\t\t"), 0x80);
175 | print_hex(buf.idProduct, 16);
176 | E_Notify(PSTR("\r\nRevision ID:\t\t"), 0x80);
177 | print_hex(buf.bcdDevice, 16);
178 | E_Notify(PSTR("\r\nMfg.string index:\t"), 0x80);
179 | print_hex(buf.iManufacturer, 8);
180 | E_Notify(PSTR("\r\nProd.string index:\t"), 0x80);
181 | print_hex(buf.iProduct, 8);
182 | E_Notify(PSTR("\r\nSerial number index:\t"), 0x80);
183 | print_hex(buf.iSerialNumber, 8);
184 | E_Notify(PSTR("\r\nNumber of conf.:\t"), 0x80);
185 | print_hex(buf.bNumConfigurations, 8);
186 |
187 | }
188 | break;
189 | case ( USB_STATE_ERROR):
190 | E_Notify(PSTR("\r\nUSB state machine reached error state"), 0x80);
191 | break;
192 |
193 | default:
194 | break;
195 | }//switch( usbstate...
196 | }
197 |
198 | if (Usb.getUsbTaskState() == USB_STATE_RUNNING)
199 | {
200 | MIDI_poll();
201 | }
202 | }
203 |
204 |
205 | /*******************************************************************************
206 | * Callback for Bluetooth disconnection
207 | * Restart advertising and stop the timers.
208 | *******************************************************************************/
209 | void disconnectionCallback(const Gap::DisconnectionCallbackParams_t*)
210 | {
211 | Serial.println("Disconnected ");
212 | Serial.println("Restart advertising ");
213 | isConnected = false;
214 | ble.startAdvertising();
215 | }
216 |
217 |
218 | /*******************************************************************************
219 | * Callback for incoming connections
220 | * Start the timers.
221 | *******************************************************************************/
222 | void connectionCallback(const Gap::ConnectionCallbackParams_t* params)
223 | {
224 | isConnected = true;
225 | Serial.println("Connected");
226 | sendTicker.attach(sendData, 0.01);
227 | }
228 |
229 |
230 | /*******************************************************************************
231 | * Callback for INCOMING MIDI BLE Data
232 | *******************************************************************************/
233 | void onDataWritten(const GattWriteCallbackParams *Handler)
234 | {
235 | uint8_t buf[TXRX_BUF_LEN];
236 | uint16_t bytesRead;
237 | if (Handler->handle == txCharacteristic.getValueAttribute().getHandle())
238 | {
239 | ble.readCharacteristicValue(txCharacteristic.getValueAttribute().getHandle(),
240 | buf, &bytesRead);
241 | parseIncoming(buf, bytesRead);
242 | }
243 | }
244 |
245 |
246 | /*******************************************************************************
247 | * Setup
248 | * Initialize USB Port, set Characteristics and Callbacks for BLE Stack.
249 | *******************************************************************************/
250 | void setup(void)
251 | {
252 | bFirst = true;
253 | vid = pid = 0;
254 | isConnected = false;
255 |
256 | //Workaround for non UHS2.0 Shield
257 | pinMode(10, OUTPUT);
258 | digitalWrite(10, HIGH);
259 |
260 | Usb.Init();
261 | delay(500);
262 | Serial.begin(9600);
263 |
264 | parser.setUSBMidiHandle(&Midi);
265 |
266 | ble.init();
267 | ble.onDisconnection(disconnectionCallback);
268 | ble.onConnection(connectionCallback);
269 | ble.onDataWritten(onDataWritten);
270 |
271 | /* setup advertising */
272 | ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
273 | ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
274 | (const uint8_t *)"BLIDIno", sizeof("BLIDIno") - 1);
275 | ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
276 | (const uint8_t *)uart_base_uuid_rev, sizeof(uart_base_uuid_rev));
277 |
278 | ble.accumulateScanResponse(GapAdvertisingData::SHORTENED_LOCAL_NAME,
279 | (const uint8_t *)"BLIDIno", sizeof("BLIDIno") - 1);
280 | ble.accumulateScanResponse(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
281 | (const uint8_t *)uart_base_uuid_rev, sizeof(uart_base_uuid_rev));
282 | ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
283 |
284 | /* 100ms; in multiples of 0.625ms. */
285 | ble.setAdvertisingInterval(160);
286 |
287 | // set adv_timeout, in seconds
288 | ble.setAdvertisingTimeout(0);
289 | ble.addService(uartService);
290 |
291 | //Set Device Name
292 | ble.setDeviceName((const uint8_t *)"Blidino");
293 |
294 | ble.startAdvertising();
295 | usbTicker.attach(m_status_check_handle, 0.01);
296 | }
297 |
298 |
299 | /*******************************************************************************
300 | * BLE Loop
301 | *******************************************************************************/
302 | void loop(void)
303 | {
304 | ble.waitForEvent();
305 | }
306 |
307 |
308 | /*******************************************************************************
309 | * Poll MIDI DATA from USB Port
310 | *******************************************************************************/
311 | void MIDI_poll()
312 | {
313 | uint8_t bufMidi[64];
314 | uint16_t rcvd;
315 | uint8_t size;
316 | byte outBuf[ 3 ];
317 | char buf[20];
318 |
319 | if (Midi.vid != vid || Midi.pid != pid)
320 | {
321 | vid = Midi.vid;
322 | pid = Midi.pid;
323 | }
324 |
325 | do
326 | {
327 | if ((size = Midi.RecvData(outBuf)) > 0)
328 | {
329 | // Send data to parser
330 | parseMIDItoAppleBle(size, outBuf);
331 | }
332 | } while (size > 0);
333 | }
334 |
335 |
336 | /*******************************************************************************
337 | * Convert MIDI Data to MIDI-BLE Packets
338 | *******************************************************************************/
339 | void parseMIDItoAppleBle(int size, byte outBuf[3])
340 | {
341 | char time[2];
342 | char buf[20];
343 | unsigned long timer = 0;
344 | int lastPos;
345 | timer = millis();
346 | uint16_t blueMidiTime = 0;
347 | blueMidiTime = 32768 + (timer % 16383); // TODO Proper Bitshifting
348 |
349 | // TODO
350 | // This section is a total mess and is in urgent need of
351 | // a rewrite.
352 |
353 | if(rx_buf_num <= 100) // arbitrary high number
354 | {
355 | if (rx_buf_num % 17 == 0) // End of packet, start a new one
356 | {
357 | rx_buf[rx_buf_num] = blueMidiTime >> 8;
358 | rx_buf_num++;
359 | rx_buf[rx_buf_num] = 0x80;
360 | rx_buf_num++;
361 | }
362 | else
363 | {
364 | rx_buf[rx_buf_num] = 0x80;
365 | rx_buf_num++;
366 | }
367 | for (int i = 0; i < size; i++)
368 | {
369 | rx_buf[rx_buf_num] = outBuf[i];
370 | rx_buf_num++;
371 | }
372 | }
373 | }
374 |
375 |
376 | /*******************************************************************************
377 | * Convert MIDI BLE to MIDI USB
378 | *******************************************************************************/
379 | void parseIncoming(uint8_t *buffer, uint16_t bytesRead)
380 | {
381 | for (int i = 1; i < bytesRead; i++)
382 | {
383 | parser.parseMidiEvent(buffer[0], buffer[i]);
384 | }
385 | }
386 |
387 |
388 | /*******************************************************************************
389 | * Convert USB Host debug info to Hex
390 | *******************************************************************************/
391 | void print_hex(int v, int num_places)
392 | {
393 | int mask = 0, n, num_nibbles, digit;
394 | for (n = 1; n <= num_places; n++)
395 | {
396 | mask = (mask << 1) | 0x0001;
397 | }
398 | v = v & mask; // truncate v to specified number of places
399 |
400 | num_nibbles = num_places / 4;
401 | if ((num_places % 4) != 0)
402 | {
403 | ++num_nibbles;
404 | }
405 | do
406 | {
407 | digit = ((v >> (num_nibbles - 1) * 4)) & 0x0f;
408 | Serial.println(digit, HEX);
409 | }
410 | while (--num_nibbles);
411 | }
412 |
413 |
--------------------------------------------------------------------------------
/Legacy Projects/nRF8001-BLE-Proto/RBL_nRF8001/examples/BLEFirmataSketch/BLEFirmata.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | Firmata.cpp - Firmata library
3 | Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved.
4 |
5 | This library is free software; you can redistribute it and/or
6 | modify it under the terms of the GNU Lesser General Public
7 | License as published by the Free Software Foundation; either
8 | version 2.1 of the License, or (at your option) any later version.
9 |
10 | See file LICENSE.txt for further informations on licensing terms.
11 | */
12 |
13 | //******************************************************************************
14 | //* Includes
15 | //******************************************************************************
16 |
17 | #include "BLEFirmata.h"
18 | #include "HardwareSerial.h"
19 | #include "RBL_nRF8001.h"
20 |
21 | extern "C" {
22 | #include
23 | #include
24 | }
25 |
26 | //******************************************************************************
27 | //* Support Functions
28 | //******************************************************************************
29 |
30 | void BleFirmataClass::sendValueAsTwo7bitBytes(int value)
31 | {
32 | ble_write(value & B01111111); // LSB
33 | ble_write(value >> 7 & B01111111); // MSB
34 | }
35 |
36 | void BleFirmataClass::startSysex(void)
37 | {
38 | ble_write(START_SYSEX);
39 | }
40 |
41 | void BleFirmataClass::endSysex(void)
42 | {
43 | ble_write(END_SYSEX);
44 | }
45 |
46 | //******************************************************************************
47 | //* Constructors
48 | //******************************************************************************
49 |
50 | BleFirmataClass::BleFirmataClass(Stream &s) : BleFirmataSerial(s)
51 | {
52 | firmwareVersionCount = 0;
53 | systemReset();
54 | }
55 |
56 | //******************************************************************************
57 | //* Public Methods
58 | //******************************************************************************
59 |
60 | /* begin method for overriding default serial bitrate */
61 | void BleFirmataClass::begin(void)
62 | {
63 | begin(57600);
64 | }
65 |
66 | /* begin method for overriding default serial bitrate */
67 | void BleFirmataClass::begin(long speed)
68 | {
69 | // Serial.begin(speed);
70 | BleFirmataSerial = Serial;
71 | blinkVersion();
72 | printVersion();
73 | printFirmwareVersion();
74 | }
75 |
76 | void BleFirmataClass::begin(Stream &s)
77 | {
78 | BleFirmataSerial = s;
79 | systemReset();
80 | printVersion();
81 | printFirmwareVersion();
82 | }
83 |
84 | // output the protocol version message to the serial port
85 | void BleFirmataClass::printVersion(void) {
86 | ble_write(REPORT_VERSION);
87 | ble_write(FIRMATA_MAJOR_VERSION);
88 | ble_write(FIRMATA_MINOR_VERSION);
89 | }
90 |
91 | void BleFirmataClass::blinkVersion(void)
92 | {
93 | // flash the pin with the protocol version
94 | pinMode(VERSION_BLINK_PIN,OUTPUT);
95 | pin13strobe(FIRMATA_MAJOR_VERSION, 40, 210);
96 | delay(250);
97 | pin13strobe(FIRMATA_MINOR_VERSION, 40, 210);
98 | delay(125);
99 | }
100 |
101 | void BleFirmataClass::printFirmwareVersion(void)
102 | {
103 | byte i;
104 |
105 | if(firmwareVersionCount) { // make sure that the name has been set before reporting
106 | startSysex();
107 | ble_write(REPORT_FIRMWARE);
108 | ble_write(firmwareVersionVector[0]); // major version number
109 | ble_write(firmwareVersionVector[1]); // minor version number
110 | for(i=2; i 0) && (inputData < 128) ) {
198 | waitForData--;
199 | storedInputData[waitForData] = inputData;
200 | if( (waitForData==0) && executeMultiByteCommand ) { // got the whole message
201 | switch(executeMultiByteCommand) {
202 | case ANALOG_MESSAGE:
203 | if(currentAnalogCallback) {
204 | (*currentAnalogCallback)(multiByteChannel,
205 | (storedInputData[0] << 7)
206 | + storedInputData[1]);
207 | }
208 | break;
209 | case DIGITAL_MESSAGE:
210 | if(currentDigitalCallback) {
211 | (*currentDigitalCallback)(multiByteChannel,
212 | (storedInputData[0] << 7)
213 | + storedInputData[1]);
214 | }
215 | break;
216 | case SET_PIN_MODE:
217 | if(currentPinModeCallback)
218 | (*currentPinModeCallback)(storedInputData[1], storedInputData[0]);
219 | break;
220 | case REPORT_ANALOG:
221 | if(currentReportAnalogCallback)
222 | (*currentReportAnalogCallback)(multiByteChannel,storedInputData[0]);
223 | break;
224 | case REPORT_DIGITAL:
225 | if(currentReportDigitalCallback)
226 | (*currentReportDigitalCallback)(multiByteChannel,storedInputData[0]);
227 | break;
228 | }
229 | executeMultiByteCommand = 0;
230 | }
231 | } else {
232 | // remove channel info from command byte if less than 0xF0
233 | if(inputData < 0xF0) {
234 | command = inputData & 0xF0;
235 | multiByteChannel = inputData & 0x0F;
236 | } else {
237 | command = inputData;
238 | // commands in the 0xF* range don't use channel data
239 | }
240 | switch (command) {
241 | case ANALOG_MESSAGE:
242 | case DIGITAL_MESSAGE:
243 | case SET_PIN_MODE:
244 | waitForData = 2; // two data bytes needed
245 | executeMultiByteCommand = command;
246 | break;
247 | case REPORT_ANALOG:
248 | case REPORT_DIGITAL:
249 | waitForData = 1; // two data bytes needed
250 | executeMultiByteCommand = command;
251 | break;
252 | case START_SYSEX:
253 | parsingSysex = true;
254 | sysexBytesRead = 0;
255 | break;
256 | case SYSTEM_RESET:
257 | systemReset();
258 | break;
259 | case REPORT_VERSION:
260 | BleFirmata.printVersion();
261 | break;
262 | }
263 | }
264 | }
265 |
266 | //------------------------------------------------------------------------------
267 | // Serial Send Handling
268 |
269 | // send an analog message
270 | void BleFirmataClass::sendAnalog(byte pin, int value)
271 | {
272 | // pin can only be 0-15, so chop higher bits
273 | ble_write(ANALOG_MESSAGE | (pin & 0xF));
274 | sendValueAsTwo7bitBytes(value);
275 | }
276 |
277 | // send a single digital pin in a digital message
278 | void BleFirmataClass::sendDigital(byte pin, int value)
279 | {
280 | /* TODO add single pin digital messages to the protocol, this needs to
281 | * track the last digital data sent so that it can be sure to change just
282 | * one bit in the packet. This is complicated by the fact that the
283 | * numbering of the pins will probably differ on Arduino, Wiring, and
284 | * other boards. The DIGITAL_MESSAGE sends 14 bits at a time, but it is
285 | * probably easier to send 8 bit ports for any board with more than 14
286 | * digital pins.
287 | */
288 |
289 | // TODO: the digital message should not be sent on the serial port every
290 | // time sendDigital() is called. Instead, it should add it to an int
291 | // which will be sent on a schedule. If a pin changes more than once
292 | // before the digital message is sent on the serial port, it should send a
293 | // digital message for each change.
294 |
295 | // if(value == 0)
296 | // sendDigitalPortPair();
297 | }
298 |
299 |
300 | // send 14-bits in a single digital message (protocol v1)
301 | // send an 8-bit port in a single digital message (protocol v2)
302 | void BleFirmataClass::sendDigitalPort(byte portNumber, int portData)
303 | {
304 | ble_write(DIGITAL_MESSAGE | (portNumber & 0xF));
305 | ble_write((byte)portData % 128); // Tx bits 0-6
306 | ble_write(portData >> 7); // Tx bits 7-13
307 | }
308 |
309 |
310 | void BleFirmataClass::sendSysex(byte command, byte bytec, byte* bytev)
311 | {
312 | byte i;
313 | startSysex();
314 | ble_write(command);
315 | for(i=0; i
7 |
8 | #if defined(ARDUINO) && ARDUINO >= 100
9 | #include "Arduino.h" // for digitalRead, digitalWrite, etc
10 | #else
11 | #include "WProgram.h"
12 | #endif
13 |
14 | // Normally Servo.h must be included before Firmata.h (which then includes
15 | // this file). If Servo.h wasn't included, this allows the code to still
16 | // compile, but without support for any Servos. Hopefully that's what the
17 | // user intended by not including Servo.h
18 | #ifndef MAX_SERVOS
19 | #define MAX_SERVOS 0
20 | #endif
21 |
22 | /*
23 | Firmata Hardware Abstraction Layer
24 |
25 | Firmata is built on top of the hardware abstraction functions of Arduino,
26 | specifically digitalWrite, digitalRead, analogWrite, analogRead, and
27 | pinMode. While these functions offer simple integer pin numbers, Firmata
28 | needs more information than is provided by Arduino. This file provides
29 | all other hardware specific details. To make Firmata support a new board,
30 | only this file should require editing.
31 |
32 | The key concept is every "pin" implemented by Firmata may be mapped to
33 | any pin as implemented by Arduino. Usually a simple 1-to-1 mapping is
34 | best, but such mapping should not be assumed. This hardware abstraction
35 | layer allows Firmata to implement any number of pins which map onto the
36 | Arduino implemented pins in almost any arbitrary way.
37 |
38 |
39 | General Constants:
40 |
41 | These constants provide basic information Firmata requires.
42 |
43 | TOTAL_PINS: The total number of pins Firmata implemented by Firmata.
44 | Usually this will match the number of pins the Arduino functions
45 | implement, including any pins pins capable of analog or digital.
46 | However, Firmata may implement any number of pins. For example,
47 | on Arduino Mini with 8 analog inputs, 6 of these may be used
48 | for digital functions, and 2 are analog only. On such boards,
49 | Firmata can implement more pins than Arduino's pinMode()
50 | function, in order to accommodate those special pins. The
51 | Firmata protocol supports a maximum of 128 pins, so this
52 | constant must not exceed 128.
53 |
54 | TOTAL_ANALOG_PINS: The total number of analog input pins implemented.
55 | The Firmata protocol allows up to 16 analog inputs, accessed
56 | using offsets 0 to 15. Because Firmata presents the analog
57 | inputs using different offsets than the actual pin numbers
58 | (a legacy of Arduino's analogRead function, and the way the
59 | analog input capable pins are physically labeled on all
60 | Arduino boards), the total number of analog input signals
61 | must be specified. 16 is the maximum.
62 |
63 | VERSION_BLINK_PIN: When Firmata starts up, it will blink the version
64 | number. This constant is the Arduino pin number where a
65 | LED is connected.
66 |
67 |
68 | Pin Mapping Macros:
69 |
70 | These macros provide the mapping between pins as implemented by
71 | Firmata protocol and the actual pin numbers used by the Arduino
72 | functions. Even though such mappings are often simple, pin
73 | numbers received by Firmata protocol should always be used as
74 | input to these macros, and the result of the macro should be
75 | used with with any Arduino function.
76 |
77 | When Firmata is extended to support a new pin mode or feature,
78 | a pair of macros should be added and used for all hardware
79 | access. For simple 1:1 mapping, these macros add no actual
80 | overhead, yet their consistent use allows source code which
81 | uses them consistently to be easily adapted to all other boards
82 | with different requirements.
83 |
84 | IS_PIN_XXXX(pin): The IS_PIN macros resolve to true or non-zero
85 | if a pin as implemented by Firmata corresponds to a pin
86 | that actually implements the named feature.
87 |
88 | PIN_TO_XXXX(pin): The PIN_TO macros translate pin numbers as
89 | implemented by Firmata to the pin numbers needed as inputs
90 | to the Arduino functions. The corresponding IS_PIN macro
91 | should always be tested before using a PIN_TO macro, so
92 | these macros only need to handle valid Firmata pin
93 | numbers for the named feature.
94 |
95 |
96 | Port Access Inline Funtions:
97 |
98 | For efficiency, Firmata protocol provides access to digital
99 | input and output pins grouped by 8 bit ports. When these
100 | groups of 8 correspond to actual 8 bit ports as implemented
101 | by the hardware, these inline functions can provide high
102 | speed direct port access. Otherwise, a default implementation
103 | using 8 calls to digitalWrite or digitalRead is used.
104 |
105 | When porting Firmata to a new board, it is recommended to
106 | use the default functions first and focus only on the constants
107 | and macros above. When those are working, if optimized port
108 | access is desired, these inline functions may be extended.
109 | The recommended approach defines a symbol indicating which
110 | optimization to use, and then conditional complication is
111 | used within these functions.
112 |
113 | readPort(port, bitmask): Read an 8 bit port, returning the value.
114 | port: The port number, Firmata pins port*8 to port*8+7
115 | bitmask: The actual pins to read, indicated by 1 bits.
116 |
117 | writePort(port, value, bitmask): Write an 8 bit port.
118 | port: The port number, Firmata pins port*8 to port*8+7
119 | value: The 8 bit value to write
120 | bitmask: The actual pins to write, indicated by 1 bits.
121 | */
122 |
123 | /*==============================================================================
124 | * Board Specific Configuration
125 | *============================================================================*/
126 |
127 | #ifndef digitalPinHasPWM
128 | #define digitalPinHasPWM(p) IS_PIN_DIGITAL(p)
129 | #endif
130 |
131 | // Arduino Duemilanove, Diecimila, and NG
132 | #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__)
133 | #if defined(NUM_ANALOG_INPUTS) && NUM_ANALOG_INPUTS == 6
134 | #define TOTAL_ANALOG_PINS 6
135 | #define TOTAL_PINS 20 // 14 digital + 6 analog
136 | #else
137 | #define TOTAL_ANALOG_PINS 8
138 | #define TOTAL_PINS 22 // 14 digital + 8 analog
139 | #endif
140 | #define VERSION_BLINK_PIN 13
141 | #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) <= 19)
142 | #define IS_PIN_ANALOG(p) ((p) >= 14 && (p) < 14 + TOTAL_ANALOG_PINS)
143 | #define IS_PIN_PWM(p) digitalPinHasPWM(p)
144 | #define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) - 2 < MAX_SERVOS)
145 | #define IS_PIN_I2C(p) ((p) == 18 || (p) == 19)
146 | #define PIN_TO_DIGITAL(p) (p)
147 | #define PIN_TO_ANALOG(p) ((p) - 14)
148 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
149 | #define PIN_TO_SERVO(p) ((p) - 2)
150 | #define ARDUINO_PINOUT_OPTIMIZE 1
151 |
152 |
153 | // Wiring (and board)
154 | #elif defined(WIRING)
155 | #define VERSION_BLINK_PIN WLED
156 | #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS)
157 | #define IS_PIN_ANALOG(p) ((p) >= FIRST_ANALOG_PIN && (p) < (FIRST_ANALOG_PIN+TOTAL_ANALOG_PINS))
158 | #define IS_PIN_PWM(p) digitalPinHasPWM(p)
159 | #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
160 | #define IS_PIN_I2C(p) ((p) == SDA || (p) == SCL)
161 | #define PIN_TO_DIGITAL(p) (p)
162 | #define PIN_TO_ANALOG(p) ((p) - FIRST_ANALOG_PIN)
163 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
164 | #define PIN_TO_SERVO(p) (p)
165 |
166 |
167 | // old Arduinos
168 | #elif defined(__AVR_ATmega8__)
169 | #define TOTAL_ANALOG_PINS 6
170 | #define TOTAL_PINS 20 // 14 digital + 6 analog
171 | #define VERSION_BLINK_PIN 13
172 | #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) <= 19)
173 | #define IS_PIN_ANALOG(p) ((p) >= 14 && (p) <= 19)
174 | #define IS_PIN_PWM(p) digitalPinHasPWM(p)
175 | #define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) - 2 < MAX_SERVOS)
176 | #define IS_PIN_I2C(p) ((p) == 18 || (p) == 19)
177 | #define PIN_TO_DIGITAL(p) (p)
178 | #define PIN_TO_ANALOG(p) ((p) - 14)
179 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
180 | #define PIN_TO_SERVO(p) ((p) - 2)
181 | #define ARDUINO_PINOUT_OPTIMIZE 1
182 |
183 |
184 | // Arduino Mega
185 | #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
186 | #define TOTAL_ANALOG_PINS 16
187 | #define TOTAL_PINS 70 // 54 digital + 16 analog
188 | #define VERSION_BLINK_PIN 13
189 | #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS)
190 | #define IS_PIN_ANALOG(p) ((p) >= 54 && (p) < TOTAL_PINS)
191 | #define IS_PIN_PWM(p) digitalPinHasPWM(p)
192 | #define IS_PIN_SERVO(p) ((p) >= 2 && (p) - 2 < MAX_SERVOS)
193 | #define IS_PIN_I2C(p) ((p) == 20 || (p) == 21)
194 | #define PIN_TO_DIGITAL(p) (p)
195 | #define PIN_TO_ANALOG(p) ((p) - 54)
196 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
197 | #define PIN_TO_SERVO(p) ((p) - 2)
198 |
199 |
200 | // Teensy 1.0
201 | #elif defined(__AVR_AT90USB162__)
202 | #define TOTAL_ANALOG_PINS 0
203 | #define TOTAL_PINS 21 // 21 digital + no analog
204 | #define VERSION_BLINK_PIN 6
205 | #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS)
206 | #define IS_PIN_ANALOG(p) (0)
207 | #define IS_PIN_PWM(p) digitalPinHasPWM(p)
208 | #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
209 | #define IS_PIN_I2C(p) (0)
210 | #define PIN_TO_DIGITAL(p) (p)
211 | #define PIN_TO_ANALOG(p) (0)
212 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
213 | #define PIN_TO_SERVO(p) (p)
214 |
215 |
216 | // Teensy 2.0
217 | #elif defined(__AVR_ATmega32U4__)
218 | #define TOTAL_ANALOG_PINS 12
219 | #define TOTAL_PINS 25 // 11 digital + 12 analog
220 | #define VERSION_BLINK_PIN 11
221 | #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS)
222 | #define IS_PIN_ANALOG(p) ((p) >= 11 && (p) <= 22)
223 | #define IS_PIN_PWM(p) digitalPinHasPWM(p)
224 | #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
225 | #define IS_PIN_I2C(p) ((p) == 5 || (p) == 6)
226 | #define PIN_TO_DIGITAL(p) (p)
227 | #define PIN_TO_ANALOG(p) (((p)<22)?21-(p):11)
228 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
229 | #define PIN_TO_SERVO(p) (p)
230 |
231 |
232 | // Teensy++ 1.0 and 2.0
233 | #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
234 | #define TOTAL_ANALOG_PINS 8
235 | #define TOTAL_PINS 46 // 38 digital + 8 analog
236 | #define VERSION_BLINK_PIN 6
237 | #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS)
238 | #define IS_PIN_ANALOG(p) ((p) >= 38 && (p) < TOTAL_PINS)
239 | #define IS_PIN_PWM(p) digitalPinHasPWM(p)
240 | #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
241 | #define IS_PIN_I2C(p) ((p) == 0 || (p) == 1)
242 | #define PIN_TO_DIGITAL(p) (p)
243 | #define PIN_TO_ANALOG(p) ((p) - 38)
244 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
245 | #define PIN_TO_SERVO(p) (p)
246 |
247 |
248 | // Sanguino
249 | #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
250 | #define TOTAL_ANALOG_PINS 8
251 | #define TOTAL_PINS 32 // 24 digital + 8 analog
252 | #define VERSION_BLINK_PIN 0
253 | #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS)
254 | #define IS_PIN_ANALOG(p) ((p) >= 24 && (p) < TOTAL_PINS)
255 | #define IS_PIN_PWM(p) digitalPinHasPWM(p)
256 | #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
257 | #define IS_PIN_I2C(p) ((p) == 16 || (p) == 17)
258 | #define PIN_TO_DIGITAL(p) (p)
259 | #define PIN_TO_ANALOG(p) ((p) - 24)
260 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
261 | #define PIN_TO_SERVO(p) ((p) - 2)
262 |
263 |
264 | // Illuminato
265 | #elif defined(__AVR_ATmega645__)
266 | #define TOTAL_ANALOG_PINS 6
267 | #define TOTAL_PINS 42 // 36 digital + 6 analog
268 | #define VERSION_BLINK_PIN 13
269 | #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS)
270 | #define IS_PIN_ANALOG(p) ((p) >= 36 && (p) < TOTAL_PINS)
271 | #define IS_PIN_PWM(p) digitalPinHasPWM(p)
272 | #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
273 | #define IS_PIN_I2C(p) ((p) == 4 || (p) == 5)
274 | #define PIN_TO_DIGITAL(p) (p)
275 | #define PIN_TO_ANALOG(p) ((p) - 36)
276 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
277 | #define PIN_TO_SERVO(p) ((p) - 2)
278 |
279 |
280 | // Arduino DUE
281 | #elif defined(__SAM3X8E__)
282 | #define TOTAL_ANALOG_PINS 12
283 | #define TOTAL_PINS 66 // 54 digital + 12 analog
284 | #define VERSION_BLINK_PIN 13
285 | #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS)
286 | #define IS_PIN_ANALOG(p) ((p) >= 54 && (p) < TOTAL_PINS)
287 | #define IS_PIN_PWM(p) digitalPinHasPWM(p)
288 | #define IS_PIN_SERVO(p) ((p) >= 2 && (p) - 2 < MAX_SERVOS)
289 | #define IS_PIN_I2C(p) ((p) == 20 || (p) == 21) // 70 71
290 | #define PIN_TO_DIGITAL(p) (p)
291 | #define PIN_TO_ANALOG(p) ((p) - 54)
292 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
293 | #define PIN_TO_SERVO(p) ((p) - 2)
294 |
295 |
296 | // anything else
297 | #else
298 | #error "Please edit Boards.h with a hardware abstraction for this board"
299 | #endif
300 |
301 |
302 | /*==============================================================================
303 | * readPort() - Read an 8 bit port
304 | *============================================================================*/
305 |
306 | static inline unsigned char readPort(byte, byte) __attribute__((always_inline, unused));
307 | static inline unsigned char readPort(byte port, byte bitmask)
308 | {
309 | #if defined(ARDUINO_PINOUT_OPTIMIZE)
310 | if (port == 0) return (PIND & 0xFC) & bitmask; // ignore Rx/Tx 0/1
311 | if (port == 1) return ((PINB & 0x3F) | ((PINC & 0x03) << 6)) & bitmask;
312 | if (port == 2) return ((PINC & 0x3C) >> 2) & bitmask;
313 | return 0;
314 | #else
315 | unsigned char out=0, pin=port*8;
316 | if (IS_PIN_DIGITAL(pin+0) && (bitmask & 0x01) && digitalRead(PIN_TO_DIGITAL(pin+0))) out |= 0x01;
317 | if (IS_PIN_DIGITAL(pin+1) && (bitmask & 0x02) && digitalRead(PIN_TO_DIGITAL(pin+1))) out |= 0x02;
318 | if (IS_PIN_DIGITAL(pin+2) && (bitmask & 0x04) && digitalRead(PIN_TO_DIGITAL(pin+2))) out |= 0x04;
319 | if (IS_PIN_DIGITAL(pin+3) && (bitmask & 0x08) && digitalRead(PIN_TO_DIGITAL(pin+3))) out |= 0x08;
320 | if (IS_PIN_DIGITAL(pin+4) && (bitmask & 0x10) && digitalRead(PIN_TO_DIGITAL(pin+4))) out |= 0x10;
321 | if (IS_PIN_DIGITAL(pin+5) && (bitmask & 0x20) && digitalRead(PIN_TO_DIGITAL(pin+5))) out |= 0x20;
322 | if (IS_PIN_DIGITAL(pin+6) && (bitmask & 0x40) && digitalRead(PIN_TO_DIGITAL(pin+6))) out |= 0x40;
323 | if (IS_PIN_DIGITAL(pin+7) && (bitmask & 0x80) && digitalRead(PIN_TO_DIGITAL(pin+7))) out |= 0x80;
324 | return out;
325 | #endif
326 | }
327 |
328 | /*==============================================================================
329 | * writePort() - Write an 8 bit port, only touch pins specified by a bitmask
330 | *============================================================================*/
331 |
332 | static inline unsigned char writePort(byte, byte, byte) __attribute__((always_inline, unused));
333 | static inline unsigned char writePort(byte port, byte value, byte bitmask)
334 | {
335 | #if defined(ARDUINO_PINOUT_OPTIMIZE)
336 | if (port == 0) {
337 | bitmask = bitmask & 0xFC; // do not touch Tx & Rx pins
338 | byte valD = value & bitmask;
339 | byte maskD = ~bitmask;
340 | cli();
341 | PORTD = (PORTD & maskD) | valD;
342 | sei();
343 | } else if (port == 1) {
344 | byte valB = (value & bitmask) & 0x3F;
345 | byte valC = (value & bitmask) >> 6;
346 | byte maskB = ~(bitmask & 0x3F);
347 | byte maskC = ~((bitmask & 0xC0) >> 6);
348 | cli();
349 | PORTB = (PORTB & maskB) | valB;
350 | PORTC = (PORTC & maskC) | valC;
351 | sei();
352 | } else if (port == 2) {
353 | bitmask = bitmask & 0x0F;
354 | byte valC = (value & bitmask) << 2;
355 | byte maskC = ~(bitmask << 2);
356 | cli();
357 | PORTC = (PORTC & maskC) | valC;
358 | sei();
359 | }
360 | #else
361 | byte pin=port*8;
362 | if ((bitmask & 0x01)) digitalWrite(PIN_TO_DIGITAL(pin+0), (value & 0x01));
363 | if ((bitmask & 0x02)) digitalWrite(PIN_TO_DIGITAL(pin+1), (value & 0x02));
364 | if ((bitmask & 0x04)) digitalWrite(PIN_TO_DIGITAL(pin+2), (value & 0x04));
365 | if ((bitmask & 0x08)) digitalWrite(PIN_TO_DIGITAL(pin+3), (value & 0x08));
366 | if ((bitmask & 0x10)) digitalWrite(PIN_TO_DIGITAL(pin+4), (value & 0x10));
367 | if ((bitmask & 0x20)) digitalWrite(PIN_TO_DIGITAL(pin+5), (value & 0x20));
368 | if ((bitmask & 0x40)) digitalWrite(PIN_TO_DIGITAL(pin+6), (value & 0x40));
369 | if ((bitmask & 0x80)) digitalWrite(PIN_TO_DIGITAL(pin+7), (value & 0x80));
370 | #endif
371 | }
372 |
373 |
374 |
375 |
376 | #ifndef TOTAL_PORTS
377 | #define TOTAL_PORTS ((TOTAL_PINS + 7) / 8)
378 | #endif
379 |
380 |
381 | #endif /* Firmata_Boards_h */
382 |
383 |
--------------------------------------------------------------------------------
/Legacy Projects/nRF8001-BLE-Proto/RBL_nRF8001/examples/BLEControllerSketch/Boards.h:
--------------------------------------------------------------------------------
1 | /* Boards.h - Hardware Abstraction Layer for Firmata library */
2 |
3 | #ifndef Boards_h
4 | #define Boards_h
5 |
6 | #include
7 |
8 | #if defined(ARDUINO) && ARDUINO >= 100
9 | #include "Arduino.h" // for digitalRead, digitalWrite, etc
10 | #else
11 | #include "WProgram.h"
12 | #endif
13 |
14 | // Normally Servo.h must be included before Firmata.h (which then includes
15 | // this file). If Servo.h wasn't included, this allows the code to still
16 | // compile, but without support for any Servos. Hopefully that's what the
17 | // user intended by not including Servo.h
18 | #ifndef MAX_SERVOS
19 | #define MAX_SERVOS 0
20 | #endif
21 |
22 | /*
23 | Firmata Hardware Abstraction Layer
24 |
25 | Firmata is built on top of the hardware abstraction functions of Arduino,
26 | specifically digitalWrite, digitalRead, analogWrite, analogRead, and
27 | pinMode. While these functions offer simple integer pin numbers, Firmata
28 | needs more information than is provided by Arduino. This file provides
29 | all other hardware specific details. To make Firmata support a new board,
30 | only this file should require editing.
31 |
32 | The key concept is every "pin" implemented by Firmata may be mapped to
33 | any pin as implemented by Arduino. Usually a simple 1-to-1 mapping is
34 | best, but such mapping should not be assumed. This hardware abstraction
35 | layer allows Firmata to implement any number of pins which map onto the
36 | Arduino implemented pins in almost any arbitrary way.
37 |
38 |
39 | General Constants:
40 |
41 | These constants provide basic information Firmata requires.
42 |
43 | TOTAL_PINS: The total number of pins Firmata implemented by Firmata.
44 | Usually this will match the number of pins the Arduino functions
45 | implement, including any pins pins capable of analog or digital.
46 | However, Firmata may implement any number of pins. For example,
47 | on Arduino Mini with 8 analog inputs, 6 of these may be used
48 | for digital functions, and 2 are analog only. On such boards,
49 | Firmata can implement more pins than Arduino's pinMode()
50 | function, in order to accommodate those special pins. The
51 | Firmata protocol supports a maximum of 128 pins, so this
52 | constant must not exceed 128.
53 |
54 | TOTAL_ANALOG_PINS: The total number of analog input pins implemented.
55 | The Firmata protocol allows up to 16 analog inputs, accessed
56 | using offsets 0 to 15. Because Firmata presents the analog
57 | inputs using different offsets than the actual pin numbers
58 | (a legacy of Arduino's analogRead function, and the way the
59 | analog input capable pins are physically labeled on all
60 | Arduino boards), the total number of analog input signals
61 | must be specified. 16 is the maximum.
62 |
63 | VERSION_BLINK_PIN: When Firmata starts up, it will blink the version
64 | number. This constant is the Arduino pin number where a
65 | LED is connected.
66 |
67 |
68 | Pin Mapping Macros:
69 |
70 | These macros provide the mapping between pins as implemented by
71 | Firmata protocol and the actual pin numbers used by the Arduino
72 | functions. Even though such mappings are often simple, pin
73 | numbers received by Firmata protocol should always be used as
74 | input to these macros, and the result of the macro should be
75 | used with with any Arduino function.
76 |
77 | When Firmata is extended to support a new pin mode or feature,
78 | a pair of macros should be added and used for all hardware
79 | access. For simple 1:1 mapping, these macros add no actual
80 | overhead, yet their consistent use allows source code which
81 | uses them consistently to be easily adapted to all other boards
82 | with different requirements.
83 |
84 | IS_PIN_XXXX(pin): The IS_PIN macros resolve to true or non-zero
85 | if a pin as implemented by Firmata corresponds to a pin
86 | that actually implements the named feature.
87 |
88 | PIN_TO_XXXX(pin): The PIN_TO macros translate pin numbers as
89 | implemented by Firmata to the pin numbers needed as inputs
90 | to the Arduino functions. The corresponding IS_PIN macro
91 | should always be tested before using a PIN_TO macro, so
92 | these macros only need to handle valid Firmata pin
93 | numbers for the named feature.
94 |
95 |
96 | Port Access Inline Funtions:
97 |
98 | For efficiency, Firmata protocol provides access to digital
99 | input and output pins grouped by 8 bit ports. When these
100 | groups of 8 correspond to actual 8 bit ports as implemented
101 | by the hardware, these inline functions can provide high
102 | speed direct port access. Otherwise, a default implementation
103 | using 8 calls to digitalWrite or digitalRead is used.
104 |
105 | When porting Firmata to a new board, it is recommended to
106 | use the default functions first and focus only on the constants
107 | and macros above. When those are working, if optimized port
108 | access is desired, these inline functions may be extended.
109 | The recommended approach defines a symbol indicating which
110 | optimization to use, and then conditional complication is
111 | used within these functions.
112 |
113 | readPort(port, bitmask): Read an 8 bit port, returning the value.
114 | port: The port number, Firmata pins port*8 to port*8+7
115 | bitmask: The actual pins to read, indicated by 1 bits.
116 |
117 | writePort(port, value, bitmask): Write an 8 bit port.
118 | port: The port number, Firmata pins port*8 to port*8+7
119 | value: The 8 bit value to write
120 | bitmask: The actual pins to write, indicated by 1 bits.
121 | */
122 |
123 | /*==============================================================================
124 | * Board Specific Configuration
125 | *============================================================================*/
126 |
127 | #ifndef digitalPinHasPWM
128 | #define digitalPinHasPWM(p) IS_PIN_DIGITAL(p)
129 | #endif
130 |
131 | // Arduino Duemilanove, Diecimila, and NG
132 | #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__)
133 | #if defined(NUM_ANALOG_INPUTS) && NUM_ANALOG_INPUTS == 6
134 | #define TOTAL_ANALOG_PINS 6
135 | #define TOTAL_PINS 20 // 14 digital + 6 analog
136 | #else
137 | #define TOTAL_ANALOG_PINS 8
138 | #define TOTAL_PINS 22 // 14 digital + 8 analog
139 | #endif
140 | #define VERSION_BLINK_PIN 13
141 | #define IS_PIN_DIGITAL(p) (((p) >= 2 && (p) <= 19) && !((p) >= 8 && (p) <= 13))
142 | //#define IS_PIN_DIGITAL(p) ( ((p) >= 2 && (p) <= 7) || ((p) >= 13 && (p) <= 19) )
143 | #define IS_PIN_ANALOG(p) ((p) >= 14 && (p) < 14 + TOTAL_ANALOG_PINS)
144 | #define IS_PIN_PWM(p) (digitalPinHasPWM(p) && !((p) >= 8 && (p) <= 12))
145 | #define IS_PIN_SERVO(p) ( (p) >= 2 && (p) <= 7 )
146 | #define IS_PIN_I2C(p) ((p) == 18 || (p) == 19)
147 | #define PIN_TO_DIGITAL(p) (p)
148 | #define PIN_TO_ANALOG(p) ((p) - 14)
149 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
150 | #define PIN_TO_SERVO(p) ((p) - 2)
151 | #define ARDUINO_PINOUT_OPTIMIZE 1
152 |
153 |
154 | // Wiring (and board)
155 | #elif defined(WIRING)
156 | #define VERSION_BLINK_PIN WLED
157 | #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS)
158 | #define IS_PIN_ANALOG(p) ((p) >= FIRST_ANALOG_PIN && (p) < (FIRST_ANALOG_PIN+TOTAL_ANALOG_PINS))
159 | #define IS_PIN_PWM(p) digitalPinHasPWM(p)
160 | #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
161 | #define IS_PIN_I2C(p) ((p) == SDA || (p) == SCL)
162 | #define PIN_TO_DIGITAL(p) (p)
163 | #define PIN_TO_ANALOG(p) ((p) - FIRST_ANALOG_PIN)
164 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
165 | #define PIN_TO_SERVO(p) (p)
166 |
167 |
168 | // old Arduinos
169 | #elif defined(__AVR_ATmega8__)
170 | #define TOTAL_ANALOG_PINS 6
171 | #define TOTAL_PINS 20 // 14 digital + 6 analog
172 | #define VERSION_BLINK_PIN 13
173 | #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) <= 19)
174 | #define IS_PIN_ANALOG(p) ((p) >= 14 && (p) <= 19)
175 | #define IS_PIN_PWM(p) digitalPinHasPWM(p)
176 | #define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) - 2 < MAX_SERVOS)
177 | #define IS_PIN_I2C(p) ((p) == 18 || (p) == 19)
178 | #define PIN_TO_DIGITAL(p) (p)
179 | #define PIN_TO_ANALOG(p) ((p) - 14)
180 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
181 | #define PIN_TO_SERVO(p) ((p) - 2)
182 | #define ARDUINO_PINOUT_OPTIMIZE 1
183 |
184 |
185 | // Arduino Mega
186 | #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
187 | #define TOTAL_ANALOG_PINS 16
188 | #define TOTAL_PINS 70 // 54 digital + 16 analog
189 | #define VERSION_BLINK_PIN 13
190 | #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS)
191 | #define IS_PIN_ANALOG(p) ((p) >= 54 && (p) < TOTAL_PINS)
192 | #define IS_PIN_PWM(p) digitalPinHasPWM(p)
193 | #define IS_PIN_SERVO(p) ((p) >= 2 && (p) - 2 < MAX_SERVOS)
194 | #define IS_PIN_I2C(p) ((p) == 20 || (p) == 21)
195 | #define PIN_TO_DIGITAL(p) (p)
196 | #define PIN_TO_ANALOG(p) ((p) - 54)
197 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
198 | #define PIN_TO_SERVO(p) ((p) - 2)
199 |
200 |
201 | // Teensy 1.0
202 | #elif defined(__AVR_AT90USB162__)
203 | #define TOTAL_ANALOG_PINS 0
204 | #define TOTAL_PINS 21 // 21 digital + no analog
205 | #define VERSION_BLINK_PIN 6
206 | #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS)
207 | #define IS_PIN_ANALOG(p) (0)
208 | #define IS_PIN_PWM(p) digitalPinHasPWM(p)
209 | #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
210 | #define IS_PIN_I2C(p) (0)
211 | #define PIN_TO_DIGITAL(p) (p)
212 | #define PIN_TO_ANALOG(p) (0)
213 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
214 | #define PIN_TO_SERVO(p) (p)
215 |
216 |
217 | // Blend Micro
218 | #elif defined(BLEND_MICRO)
219 | #define TOTAL_ANALOG_PINS 6
220 | #define TOTAL_PINS 24 // 11 digital + 12 analog
221 | #define VERSION_BLINK_PIN 13
222 | #define IS_PIN_DIGITAL(p) ( (p) >= 0 && (p) < 24 && !((p) == 4) && !((p) >= 6 && (p) <= 7) && !((p) >=14 && (p) <= 17) )
223 | #define IS_PIN_ANALOG(p) ((p) >= 18 && (p) < 24)
224 | #define IS_PIN_PWM(p) ( (p) == 3 || (p) == 5 || (p) == 9 || (p) == 10 || (p) == 11 || (p) == 13 )
225 | #define IS_PIN_SERVO(p) ( (p) >= 0 && (p) < MAX_SERVOS && !((p) == 4) && !((p) >= 6 && (p) <= 7) )
226 | #define IS_PIN_I2C(p) ((p) == 5 || (p) == 6)
227 | #define PIN_TO_DIGITAL(p) (p)
228 | #define PIN_TO_ANALOG(p) ((p)-18)
229 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
230 | #define PIN_TO_SERVO(p) (p)
231 |
232 |
233 | // Teensy 2.0
234 | #elif defined(__AVR_ATmega32U4__)
235 | #define TOTAL_ANALOG_PINS 6
236 | #define TOTAL_PINS 24 // 11 digital + 12 analog
237 | #define VERSION_BLINK_PIN 13
238 | #define IS_PIN_DIGITAL(p) ( (p) >= 0 && (p) < 24 && !((p) >= 8 && (p) <= 9) && !((p) >=14 && (p) <= 17) )
239 | #define IS_PIN_ANALOG(p) ((p) >= 18 && (p) < 24)
240 | #define IS_PIN_PWM(p) ( (p) == 3 || (p) == 5 || (p) == 6 || (p) == 10 || (p) == 11 || (p) == 13 )
241 | #define IS_PIN_SERVO(p) ( (p) >= 0 && (p) < MAX_SERVOS && !((p) >= 8 && (p) <= 9) )
242 | #define IS_PIN_I2C(p) ((p) == 5 || (p) == 6)
243 | #define PIN_TO_DIGITAL(p) (p)
244 | #define PIN_TO_ANALOG(p) ((p)-18)
245 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
246 | #define PIN_TO_SERVO(p) (p)
247 |
248 |
249 | // Teensy++ 1.0 and 2.0
250 | #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
251 | #define TOTAL_ANALOG_PINS 8
252 | #define TOTAL_PINS 46 // 38 digital + 8 analog
253 | #define VERSION_BLINK_PIN 6
254 | #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS)
255 | #define IS_PIN_ANALOG(p) ((p) >= 38 && (p) < TOTAL_PINS)
256 | #define IS_PIN_PWM(p) digitalPinHasPWM(p)
257 | #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
258 | #define IS_PIN_I2C(p) ((p) == 0 || (p) == 1)
259 | #define PIN_TO_DIGITAL(p) (p)
260 | #define PIN_TO_ANALOG(p) ((p) - 38)
261 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
262 | #define PIN_TO_SERVO(p) (p)
263 |
264 |
265 | // Sanguino
266 | #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
267 | #define TOTAL_ANALOG_PINS 8
268 | #define TOTAL_PINS 32 // 24 digital + 8 analog
269 | #define VERSION_BLINK_PIN 0
270 | #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS)
271 | #define IS_PIN_ANALOG(p) ((p) >= 24 && (p) < TOTAL_PINS)
272 | #define IS_PIN_PWM(p) digitalPinHasPWM(p)
273 | #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
274 | #define IS_PIN_I2C(p) ((p) == 16 || (p) == 17)
275 | #define PIN_TO_DIGITAL(p) (p)
276 | #define PIN_TO_ANALOG(p) ((p) - 24)
277 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
278 | #define PIN_TO_SERVO(p) ((p) - 2)
279 |
280 |
281 | // Illuminato
282 | #elif defined(__AVR_ATmega645__)
283 | #define TOTAL_ANALOG_PINS 6
284 | #define TOTAL_PINS 42 // 36 digital + 6 analog
285 | #define VERSION_BLINK_PIN 13
286 | #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS)
287 | #define IS_PIN_ANALOG(p) ((p) >= 36 && (p) < TOTAL_PINS)
288 | #define IS_PIN_PWM(p) digitalPinHasPWM(p)
289 | #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
290 | #define IS_PIN_I2C(p) ((p) == 4 || (p) == 5)
291 | #define PIN_TO_DIGITAL(p) (p)
292 | #define PIN_TO_ANALOG(p) ((p) - 36)
293 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
294 | #define PIN_TO_SERVO(p) ((p) - 2)
295 |
296 |
297 | // Arduino DUE
298 | #elif defined(__SAM3X8E__)
299 | #define TOTAL_ANALOG_PINS 12
300 | #define TOTAL_PINS 66 // 54 digital + 12 analog
301 | #define VERSION_BLINK_PIN 13
302 | #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS)
303 | #define IS_PIN_ANALOG(p) ((p) >= 54 && (p) < TOTAL_PINS)
304 | #define IS_PIN_PWM(p) digitalPinHasPWM(p)
305 | #define IS_PIN_SERVO(p) ((p) >= 2 && (p) - 2 < MAX_SERVOS)
306 | #define IS_PIN_I2C(p) ((p) == 20 || (p) == 21) // 70 71
307 | #define PIN_TO_DIGITAL(p) (p)
308 | #define PIN_TO_ANALOG(p) ((p) - 54)
309 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
310 | #define PIN_TO_SERVO(p) ((p) - 2)
311 |
312 |
313 | // anything else
314 | #else
315 | #error "Please edit Boards.h with a hardware abstraction for this board"
316 | #endif
317 |
318 |
319 | /*==============================================================================
320 | * readPort() - Read an 8 bit port
321 | *============================================================================*/
322 |
323 | static inline unsigned char readPort(byte, byte) __attribute__((always_inline, unused));
324 | static inline unsigned char readPort(byte port, byte bitmask)
325 | {
326 | #if defined(ARDUINO_PINOUT_OPTIMIZE)
327 | if (port == 0) return (PIND & 0xFC) & bitmask; // ignore Rx/Tx 0/1
328 | if (port == 1) return ((PINB & 0x3F) | ((PINC & 0x03) << 6)) & bitmask;
329 | if (port == 2) return ((PINC & 0x3C) >> 2) & bitmask;
330 | return 0;
331 | #else
332 | unsigned char out=0, pin=port*8;
333 | if (IS_PIN_DIGITAL(pin+0) && (bitmask & 0x01) && digitalRead(PIN_TO_DIGITAL(pin+0))) out |= 0x01;
334 | if (IS_PIN_DIGITAL(pin+1) && (bitmask & 0x02) && digitalRead(PIN_TO_DIGITAL(pin+1))) out |= 0x02;
335 | if (IS_PIN_DIGITAL(pin+2) && (bitmask & 0x04) && digitalRead(PIN_TO_DIGITAL(pin+2))) out |= 0x04;
336 | if (IS_PIN_DIGITAL(pin+3) && (bitmask & 0x08) && digitalRead(PIN_TO_DIGITAL(pin+3))) out |= 0x08;
337 | if (IS_PIN_DIGITAL(pin+4) && (bitmask & 0x10) && digitalRead(PIN_TO_DIGITAL(pin+4))) out |= 0x10;
338 | if (IS_PIN_DIGITAL(pin+5) && (bitmask & 0x20) && digitalRead(PIN_TO_DIGITAL(pin+5))) out |= 0x20;
339 | if (IS_PIN_DIGITAL(pin+6) && (bitmask & 0x40) && digitalRead(PIN_TO_DIGITAL(pin+6))) out |= 0x40;
340 | if (IS_PIN_DIGITAL(pin+7) && (bitmask & 0x80) && digitalRead(PIN_TO_DIGITAL(pin+7))) out |= 0x80;
341 | return out;
342 | #endif
343 | }
344 |
345 | /*==============================================================================
346 | * writePort() - Write an 8 bit port, only touch pins specified by a bitmask
347 | *============================================================================*/
348 |
349 | static inline unsigned char writePort(byte, byte, byte) __attribute__((always_inline, unused));
350 | static inline unsigned char writePort(byte port, byte value, byte bitmask)
351 | {
352 | #if defined(ARDUINO_PINOUT_OPTIMIZE)
353 | if (port == 0) {
354 | bitmask = bitmask & 0xFC; // do not touch Tx & Rx pins
355 | byte valD = value & bitmask;
356 | byte maskD = ~bitmask;
357 | cli();
358 | PORTD = (PORTD & maskD) | valD;
359 | sei();
360 | } else if (port == 1) {
361 | byte valB = (value & bitmask) & 0x3F;
362 | byte valC = (value & bitmask) >> 6;
363 | byte maskB = ~(bitmask & 0x3F);
364 | byte maskC = ~((bitmask & 0xC0) >> 6);
365 | cli();
366 | PORTB = (PORTB & maskB) | valB;
367 | PORTC = (PORTC & maskC) | valC;
368 | sei();
369 | } else if (port == 2) {
370 | bitmask = bitmask & 0x0F;
371 | byte valC = (value & bitmask) << 2;
372 | byte maskC = ~(bitmask << 2);
373 | cli();
374 | PORTC = (PORTC & maskC) | valC;
375 | sei();
376 | }
377 | #else
378 | byte pin=port*8;
379 | if ((bitmask & 0x01)) digitalWrite(PIN_TO_DIGITAL(pin+0), (value & 0x01));
380 | if ((bitmask & 0x02)) digitalWrite(PIN_TO_DIGITAL(pin+1), (value & 0x02));
381 | if ((bitmask & 0x04)) digitalWrite(PIN_TO_DIGITAL(pin+2), (value & 0x04));
382 | if ((bitmask & 0x08)) digitalWrite(PIN_TO_DIGITAL(pin+3), (value & 0x08));
383 | if ((bitmask & 0x10)) digitalWrite(PIN_TO_DIGITAL(pin+4), (value & 0x10));
384 | if ((bitmask & 0x20)) digitalWrite(PIN_TO_DIGITAL(pin+5), (value & 0x20));
385 | if ((bitmask & 0x40)) digitalWrite(PIN_TO_DIGITAL(pin+6), (value & 0x40));
386 | if ((bitmask & 0x80)) digitalWrite(PIN_TO_DIGITAL(pin+7), (value & 0x80));
387 | #endif
388 | }
389 |
390 |
391 |
392 |
393 | #ifndef TOTAL_PORTS
394 | #define TOTAL_PORTS ((TOTAL_PINS + 7) / 8)
395 | #endif
396 |
397 |
398 | #endif /* Firmata_Boards_h */
399 |
--------------------------------------------------------------------------------
/nRF51822-BLEMIDI/BLEParser.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2014 Matthias Frick
3 | *
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy
5 | * of this software and associated documentation files (the "Software"), to deal
6 | * in the Software without restriction, including without limitation the rights
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | * copies of the Software, and to permit persons to whom the Software is
9 | * furnished to do so, subject to the following conditions:
10 | *
11 | * The above copyright notice and this permission notice shall be included in all
12 | * copies or substantial portions of the Software.
13 | *
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 | * SOFTWARE.
21 | */
22 |
23 | #ifndef ____BLEParser__
24 | #define ____BLEParser__
25 | #include
26 | #include
27 | #include
28 |
29 | namespace mfk
30 | {
31 | namespace midi
32 | {
33 | static int MIDI_STATE_TIMESTAMP = 0;
34 | static int MIDI_STATE_WAIT = 1;
35 | static int MIDI_STATE_SIGNAL_2BYTES_2 = 21;
36 | static int MIDI_STATE_SIGNAL_3BYTES_2 = 31;
37 | static int MIDI_STATE_SIGNAL_3BYTES_3 = 32;
38 | static int MIDI_STATE_SIGNAL_SYSEX = 41;
39 |
40 | // for Timestamp
41 | static int MAX_TIMESTAMP = 8192;
42 | static int BUFFER_LENGTH_MILLIS = 10;
43 |
44 |
45 | // for RPN/NRPN messages
46 | static int PARAMETER_MODE_NONE = 0;
47 | static int PARAMETER_MODE_RPN = 1;
48 | static int PARAMETER_MODE_NRPN = 2;
49 | int parameterMode = 0;
50 | int parameterNumber = 0x3fff;
51 | int parameterValue = 0x3fff;
52 |
53 | template
54 | class BLEMIDIParser
55 | {
56 | public:
57 |
58 | void parseMidiEvent(uint8_t header, const uint8_t event)
59 | {
60 | uint8_t midiEvent = event & 0xff;
61 | uint8_t timeToWait;
62 | // printf((char*)midiEvent);
63 | if (midiState == MIDI_STATE_TIMESTAMP)
64 | {
65 | // printf("Timestamp");
66 | if ((midiEvent & 0x80) == 0)
67 | {
68 | // running status
69 | midiState = MIDI_STATE_WAIT;
70 | }
71 |
72 | if (midiEvent == 0xf7)
73 | {
74 | // make sure this is the end of sysex
75 | // and send alternative recovery stream
76 | if (sysExRecBufferPtr > 0)
77 | {
78 | uint8_t removed = replaceLastByteInRecoveryBuffer(midiEvent);
79 | sendSysexRecovery();
80 | resetRecoveryBuffer();
81 | }
82 | midiState = MIDI_STATE_TIMESTAMP;
83 | return;
84 | }
85 | else
86 | {
87 | // reset alternative sysex stream
88 | resetRecoveryBuffer();
89 | }
90 | } // end of timestamp
91 |
92 | if (midiState == MIDI_STATE_TIMESTAMP)
93 | {
94 | timestamp = ((header & 0x3f) << 7) | (midiEvent & 0x7f);
95 | midiState = MIDI_STATE_WAIT;
96 | }
97 | else if (midiState == MIDI_STATE_WAIT)
98 | {
99 | switch (midiEvent & 0xf0) {
100 | case 0xf0: {
101 | switch (midiEvent) {
102 | case 0xf0:
103 | resetRecoveryBuffer();
104 | resetSysExBuffer();
105 | addByteToSysExBuffer(midiEvent);
106 | midiState = MIDI_STATE_SIGNAL_SYSEX;
107 | break;
108 | case 0xf1:
109 | case 0xf3:
110 | // 0xf1 MIDI Time Code Quarter Frame. : 2bytes
111 | // 0xf3 Song Select. : 2bytes
112 | midiEventKind = midiEvent;
113 | addByteToMidiBuffer(midiEvent);
114 | midiState = MIDI_STATE_SIGNAL_2BYTES_2;
115 | break;
116 | case 0xf2:
117 | // 0xf2 Song Position Pointer. : 3bytes
118 | midiEventKind = midiEvent;
119 | addByteToMidiBuffer(midiEvent);
120 | midiState = MIDI_STATE_SIGNAL_3BYTES_2;
121 | break;
122 | case 0xf6:
123 | // 0xf6 Tune Request : 1byte
124 | addByteToMidiBuffer(midiEvent);
125 | midiState = MIDI_STATE_TIMESTAMP;
126 | break;
127 | case 0xf8:
128 | // 0xf8 Timing Clock : 1byte
129 | #pragma mark send timeclock
130 | midiState = MIDI_STATE_TIMESTAMP;
131 | break;
132 | case 0xfa:
133 | // 0xfa Start : 1byte
134 | midiState = MIDI_STATE_TIMESTAMP;
135 | break;
136 | case 0xfb:
137 | // 0xfb Continue : 1byte
138 | midiState = MIDI_STATE_TIMESTAMP;
139 | break;
140 | case 0xfc:
141 | // 0xfc Stop : 1byte
142 | midiState = MIDI_STATE_TIMESTAMP;
143 | break;
144 | case 0xfe:
145 | // 0xfe Active Sensing : 1byte
146 | midiState = MIDI_STATE_TIMESTAMP;
147 | break;
148 | case 0xff:
149 | // 0xff Reset : 1byte
150 | midiState = MIDI_STATE_TIMESTAMP;
151 | break;
152 |
153 | default:
154 | break;
155 | }
156 | }
157 | break;
158 | case 0x80:
159 | case 0x90:
160 | case 0xa0:
161 | case 0xb0:
162 | case 0xe0:
163 | // 3bytes pattern
164 | midiEventKind = midiEvent;
165 | midiState = MIDI_STATE_SIGNAL_3BYTES_2;
166 | break;
167 | case 0xc0: // program change
168 | case 0xd0: // channel after-touch
169 | // 2bytes pattern
170 | midiEventKind = midiEvent;
171 | midiState = MIDI_STATE_SIGNAL_2BYTES_2;
172 | break;
173 | default:
174 | // 0x00 - 0x70: running status
175 | if ((midiEventKind & 0xf0) != 0xf0) {
176 | // previous event kind is multi-bytes pattern
177 | midiEventNote = midiEvent;
178 | midiState = MIDI_STATE_SIGNAL_3BYTES_3;
179 | }
180 | break;
181 | }
182 | }
183 | else if (midiState == MIDI_STATE_SIGNAL_2BYTES_2)
184 | {
185 | switch (midiEventKind & 0xf0)
186 | {
187 | // 2bytes pattern
188 | case 0xc0: // program change
189 | midiEventNote = midiEvent;
190 | midiState = MIDI_STATE_TIMESTAMP;
191 | break;
192 | case 0xd0: // channel after-touch
193 | midiEventNote = midiEvent;
194 | midiState = MIDI_STATE_TIMESTAMP;
195 | break;
196 | case 0xf0:
197 | {
198 | switch (midiEventKind)
199 | {
200 | case 0xf1:
201 | // 0xf1 MIDI Time Code Quarter Frame. : 2bytes
202 | midiEventNote = midiEvent;
203 | addByteToMidiBuffer(midiEventNote);
204 | sendMidi(2);
205 | resetMidiBuffer();
206 | midiState = MIDI_STATE_TIMESTAMP;
207 | break;
208 | case 0xf3:
209 | // 0xf3 Song Select. : 2bytes
210 | midiEventNote = midiEvent;
211 | addByteToMidiBuffer(midiEventNote);
212 | sendMidi(2);
213 | resetMidiBuffer();
214 | midiState = MIDI_STATE_TIMESTAMP;
215 | break;
216 | default:
217 | // illegal state
218 | midiState = MIDI_STATE_TIMESTAMP;
219 | break;
220 | }
221 | }
222 | break;
223 | default:
224 | // illegal state
225 | midiState = MIDI_STATE_TIMESTAMP;
226 | break;
227 | }
228 | }
229 | else if (midiState == MIDI_STATE_SIGNAL_3BYTES_2)
230 | {
231 | switch (midiEventKind & 0xf0)
232 | {
233 | case 0x80:
234 | case 0x90:
235 | case 0xa0:
236 | case 0xb0:
237 | case 0xe0:
238 | case 0xf0:
239 | // 3bytes pattern
240 | midiEventNote = midiEvent;
241 | midiState = MIDI_STATE_SIGNAL_3BYTES_3;
242 | break;
243 | default:
244 | // illegal state
245 | midiState = MIDI_STATE_TIMESTAMP;
246 | break;
247 | }
248 | }
249 | else if (midiState == MIDI_STATE_SIGNAL_3BYTES_3)
250 | {
251 | switch (midiEventKind & 0xf0)
252 | {
253 | // 3bytes pattern
254 | case 0x80: // note off
255 | midiEventVelocity = midiEvent;
256 | addByteToMidiBuffer(midiEventKind);
257 | addByteToMidiBuffer(midiEventNote);
258 | addByteToMidiBuffer(midiEventVelocity);
259 | sendMidi(3);
260 | resetMidiBuffer();
261 | midiState = MIDI_STATE_TIMESTAMP;
262 | break;
263 | case 0x90: // note on
264 | midiEventVelocity = midiEvent;
265 | //timeToWait = calculateTimeToWait(timestamp);
266 | addByteToMidiBuffer(midiEventKind);
267 | addByteToMidiBuffer(midiEventNote);
268 | addByteToMidiBuffer(midiEventVelocity);
269 | sendMidi(3);
270 | resetMidiBuffer();
271 | midiState = MIDI_STATE_TIMESTAMP;
272 | break;
273 | case 0xa0: // control polyphonic key pressure
274 | midiEventVelocity = midiEvent;
275 | addByteToMidiBuffer(midiEventKind);
276 | addByteToMidiBuffer(midiEventNote);
277 | addByteToMidiBuffer(midiEventVelocity);
278 | sendMidi(3);
279 | resetMidiBuffer();
280 | midiState = MIDI_STATE_TIMESTAMP;
281 | break;
282 | case 0xb0: // control change
283 | midiEventVelocity = midiEvent;
284 | switch (midiEventNote & 0x7f)
285 | {
286 | case 98:
287 | // NRPN LSB
288 | parameterNumber &= 0x3f80;
289 | parameterNumber |= midiEventVelocity & 0x7f;
290 | parameterMode = PARAMETER_MODE_NRPN;
291 | break;
292 | case 99:
293 | // NRPN MSB
294 | parameterNumber &= 0x007f;
295 | parameterNumber |= (midiEventVelocity & 0x7f) << 7;
296 | parameterMode = PARAMETER_MODE_NRPN;
297 | break;
298 | case 100:
299 | // RPN LSB
300 | parameterNumber &= 0x3f80;
301 | parameterNumber |= midiEventVelocity & 0x7f;
302 | parameterMode = PARAMETER_MODE_RPN;
303 | break;
304 | case 101:
305 | // RPN MSB
306 | parameterNumber &= 0x007f;
307 | parameterNumber |= (midiEventVelocity & 0x7f) << 7;
308 | parameterMode = PARAMETER_MODE_RPN;
309 | break;
310 | case 38:
311 | // data LSB
312 | parameterValue &= 0x3f80;
313 | parameterValue |= midiEventVelocity & 0x7f;
314 |
315 | if (parameterNumber != 0x3fff) {
316 | if (parameterMode == PARAMETER_MODE_RPN)
317 | {
318 | addByteToMidiBuffer(midiEventKind);
319 | addByteToMidiBuffer(parameterNumber);
320 | addByteToMidiBuffer(parameterValue);
321 | sendMidi(3);
322 | resetMidiBuffer();
323 | }
324 | else if (parameterMode == PARAMETER_MODE_NRPN)
325 | {
326 | addByteToMidiBuffer(midiEventKind);
327 | addByteToMidiBuffer(parameterNumber);
328 | addByteToMidiBuffer(parameterValue);
329 | sendMidi(3);
330 | resetMidiBuffer();
331 | }
332 | }
333 | break;
334 | case 6:
335 | // data MSB
336 | parameterValue &= 0x007f;
337 | parameterValue |= (midiEventVelocity & 0x7f) << 7;
338 |
339 | if (parameterNumber != 0x3fff)
340 | {
341 | if (parameterMode == PARAMETER_MODE_RPN)
342 | {
343 | addByteToMidiBuffer(midiEventKind);
344 | addByteToMidiBuffer(parameterNumber);
345 | addByteToMidiBuffer(parameterValue);
346 | sendMidi(3);
347 | resetMidiBuffer();
348 | }
349 | else if (parameterMode == PARAMETER_MODE_NRPN)
350 | {
351 | addByteToMidiBuffer(midiEventKind);
352 | addByteToMidiBuffer(parameterNumber);
353 | addByteToMidiBuffer(parameterValue);
354 | sendMidi(3);
355 | resetMidiBuffer();
356 | }
357 | }
358 | break;
359 | default:
360 | // do nothing
361 | break;
362 | }
363 | addByteToMidiBuffer(midiEventKind);
364 | addByteToMidiBuffer(midiEventNote);
365 | addByteToMidiBuffer(midiEventVelocity);
366 | sendMidi(3);
367 | resetMidiBuffer();
368 | midiState = MIDI_STATE_TIMESTAMP;
369 | break;
370 | case 0xe0: // pitch bend
371 | midiEventVelocity = midiEvent;
372 | addByteToMidiBuffer(midiEventKind);
373 | addByteToMidiBuffer(midiEventNote);
374 | addByteToMidiBuffer(midiEventVelocity);
375 | sendMidi(3);
376 | resetMidiBuffer();
377 | midiState = MIDI_STATE_TIMESTAMP;
378 | break;
379 | case 0xf0: // Song Position Pointer.
380 | midiEventVelocity = midiEvent;
381 | addByteToMidiBuffer(midiEventKind);
382 | addByteToMidiBuffer(midiEventNote);
383 | addByteToMidiBuffer(midiEventVelocity);
384 | sendMidi(3);
385 | resetMidiBuffer();
386 | midiState = MIDI_STATE_TIMESTAMP;
387 | break;
388 | default:
389 | // illegal state
390 | midiState = MIDI_STATE_TIMESTAMP;
391 | break;
392 | }
393 | }
394 | else if (midiState == MIDI_STATE_SIGNAL_SYSEX)
395 | {
396 | if (midiEvent == 0xf7)
397 | {
398 | uint8_t repEvt = replaceLastByteInSysExBuffer(midiEvent);
399 |
400 | resetRecoveryBuffer();
401 | createSysExRecovery();
402 | replaceLastByteInRecoveryBuffer(repEvt);
403 | addByteToRecoveryBuffer(midiEvent);
404 | sendSysex();
405 | resetSysExBuffer();
406 | midiState = MIDI_STATE_TIMESTAMP;
407 | }
408 | else
409 | {
410 | addByteToSysExBuffer(midiEvent);
411 | }
412 |
413 | }
414 | }
415 | void setUSBMidiHandle(Receiver *MidiHdl)
416 | {
417 | midiRecv = MidiHdl;
418 | }
419 |
420 | private:
421 |
422 | void addByteToMidiBuffer(uint8_t midiEvent)
423 | {
424 | midiBuffer[midiBufferPtr] = midiEvent;
425 | midiBufferPtr++;
426 | }
427 |
428 | void addByteToSysExBuffer(uint8_t midiEvent)
429 | {
430 | sysExBuffer[sysExBufferPtr] = midiEvent;
431 | sysExBufferPtr++;
432 | }
433 |
434 | uint8_t replaceLastByteInSysExBuffer(uint8_t midiEvent)
435 | {
436 | sysExBufferPtr--;
437 | uint8_t lastEvt = sysExBuffer[sysExBufferPtr];
438 | sysExBuffer[sysExBufferPtr] = midiEvent;
439 | sysExBufferPtr++;
440 | return lastEvt;
441 | }
442 |
443 | void sendSysex()
444 | {
445 | midiRecv->SendSysEx(sysExBuffer, sysExBufferPtr, 0);
446 | }
447 |
448 | void createSysExRecovery()
449 | {
450 | sysExRecBufferPtr = sysExBufferPtr;
451 | memcpy(alterSysExBuffer, sysExBuffer, sysExBufferPtr);
452 | }
453 |
454 | void sendSysexRecovery()
455 | {
456 | midiRecv->SendSysEx(alterSysExBuffer, sysExRecBufferPtr, 0);
457 | }
458 |
459 | uint8_t replaceLastByteInRecoveryBuffer(uint8_t midiEvent)
460 | {
461 | sysExRecBufferPtr--;
462 | uint8_t lastEvt = alterSysExBuffer[sysExRecBufferPtr];
463 | alterSysExBuffer[sysExRecBufferPtr] = midiEvent;
464 | sysExRecBufferPtr++;
465 | return lastEvt;
466 | }
467 |
468 | void addByteToRecoveryBuffer(uint8_t midiEvent)
469 | {
470 | alterSysExBuffer[sysExRecBufferPtr] = midiEvent;
471 | sysExRecBufferPtr++;
472 | }
473 |
474 | void resetMidiBuffer()
475 | {
476 | memset(&midiBuffer[0], 0, sizeof(midiBuffer));
477 | midiBufferPtr = 0;
478 | }
479 |
480 | void resetSysExBuffer()
481 | {
482 | memset(&sysExBuffer[0], 0, kMaxBufferSize);
483 | sysExBufferPtr = 0;
484 | }
485 |
486 | void resetRecoveryBuffer()
487 | {
488 | memset(&alterSysExBuffer[0], 0, sizeof(alterSysExBuffer));
489 | sysExRecBufferPtr = 0;
490 | }
491 |
492 | void sendMidi(uint8_t size)
493 | {
494 | midiRecv->SendData(midiBuffer, 0);
495 | }
496 |
497 | uint8_t midiBuffer[3];
498 | uint8_t sysExBuffer[kMaxBufferSize];
499 | uint8_t alterSysExBuffer[kMaxBufferSize];
500 | int midiBufferPtr = 0;
501 | int sysExRecBufferPtr = 0;
502 | int sysExBufferPtr = 0;
503 |
504 |
505 | // MIDI event messages, state & stamps
506 | int midiEventKind;
507 | int midiEventNote;
508 | int midiEventVelocity;
509 | int midiState = MIDI_STATE_TIMESTAMP;
510 | int timestamp;
511 |
512 |
513 | bool useTimestamp = true;
514 | int lastTimestamp;
515 | long lastTimestampRecorded = 0;
516 | int zeroTimestampCount = 0;
517 | Receiver *midiRecv;
518 | };
519 | }
520 | }
521 |
522 | #endif /* defined(____BLEParser__) */
523 |
--------------------------------------------------------------------------------